toolcraft 0.0.66 → 0.0.68
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.compile-check.js +5 -0
- package/dist/cli.d.ts +4 -1
- package/dist/cli.js +72 -10
- package/dist/human-in-loop/runner.js +29 -26
- package/dist/index.d.ts +6 -0
- package/dist/index.js +2 -2
- package/dist/mcp.d.ts +3 -1
- package/dist/mcp.js +10 -3
- package/dist/runtime-logging.d.ts +19 -0
- package/dist/runtime-logging.js +42 -0
- package/dist/sdk.d.ts +3 -1
- package/dist/sdk.js +10 -3
- package/package.json +2 -2
|
@@ -18,10 +18,15 @@ const ignoredOptions = {
|
|
|
18
18
|
fetch: globalThis.fetch,
|
|
19
19
|
controls: {
|
|
20
20
|
debug: true,
|
|
21
|
+
logLevel: true,
|
|
21
22
|
output: true,
|
|
22
23
|
verbose: true,
|
|
23
24
|
yes: true,
|
|
24
25
|
},
|
|
26
|
+
logLevel: "warn",
|
|
27
|
+
logger: (event) => {
|
|
28
|
+
event.level;
|
|
29
|
+
},
|
|
25
30
|
humanInLoop: {},
|
|
26
31
|
version: "1.0.0",
|
|
27
32
|
};
|
package/dist/cli.d.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { configureTheme } from "toolcraft-design";
|
|
2
|
-
import type { Group } from "./index.js";
|
|
2
|
+
import type { Group, LogLevel, RuntimeLoggerInput } from "./index.js";
|
|
3
3
|
import { type ErrorReportsOption } from "./error-report.js";
|
|
4
4
|
import type { HumanInLoopRuntimeOptions } from "./human-in-loop/index.js";
|
|
5
5
|
export { configureTheme };
|
|
6
6
|
type Casing = "kebab" | "snake";
|
|
7
7
|
export interface CLIControls {
|
|
8
8
|
debug?: boolean;
|
|
9
|
+
logLevel?: boolean;
|
|
9
10
|
output?: boolean;
|
|
10
11
|
verbose?: boolean;
|
|
11
12
|
yes?: boolean;
|
|
@@ -18,6 +19,8 @@ export interface RunCLIOptions<TServices extends object = Record<string, unknown
|
|
|
18
19
|
controls?: CLIControls;
|
|
19
20
|
fetch?: typeof globalThis.fetch;
|
|
20
21
|
humanInLoop?: HumanInLoopRuntimeOptions;
|
|
22
|
+
logLevel?: LogLevel;
|
|
23
|
+
logger?: RuntimeLoggerInput;
|
|
21
24
|
projectRoot?: string;
|
|
22
25
|
rootDisplayName?: string;
|
|
23
26
|
rootUsageName?: string;
|
package/dist/cli.js
CHANGED
|
@@ -4,7 +4,6 @@ import { Command as CommanderCommand, CommanderError, InvalidArgumentError, Opti
|
|
|
4
4
|
import { cancel, configureTheme, confirm, createLogger, formatCommandList, formatOptionList, getTheme, helpFormatterPlain, isCancel, note, promptText, renderTable, resetOutputFormatCache, select, text } from "toolcraft-design";
|
|
5
5
|
import { ApprovalDeclinedError, UserError, assertCommandRequirements, getCommandSourcePath, resolveCommandSecrets } from "./index.js";
|
|
6
6
|
import { hasOwnErrorCode } from "./error-codes.js";
|
|
7
|
-
import { summarizeHttpError } from "./api-error-summary.js";
|
|
8
7
|
import { mergeApprovalsGroup } from "./human-in-loop/approvals-commands.js";
|
|
9
8
|
import { writeErrorReport } from "./error-report.js";
|
|
10
9
|
import { invokeWithHumanInLoop } from "./human-in-loop/index.js";
|
|
@@ -12,6 +11,8 @@ import { resolveMcpProxies } from "./mcp-proxy.js";
|
|
|
12
11
|
import { getExpectedNumberDescription, isValidNumberSchemaValue } from "./number-schema.js";
|
|
13
12
|
import { findEntrypointPackageMetadata } from "./package-metadata.js";
|
|
14
13
|
import { redactHttpBody, redactHttpHeaderValue } from "./redaction.js";
|
|
14
|
+
import { createRuntimeLogger, isLogLevel, LOG_LEVELS } from "./runtime-logging.js";
|
|
15
|
+
import { summarizeHttpError } from "./api-error-summary.js";
|
|
15
16
|
import { renderResult } from "./renderer.js";
|
|
16
17
|
import { renderSourceSnippet } from "./source-snippet.js";
|
|
17
18
|
import { enableSourceMaps, formatDebugStack } from "./stack-trim.js";
|
|
@@ -25,11 +26,12 @@ const RESERVED_SERVICE_NAMES = new Set([
|
|
|
25
26
|
"fetch",
|
|
26
27
|
"fs",
|
|
27
28
|
"env",
|
|
29
|
+
"diagnostics",
|
|
28
30
|
"progress",
|
|
29
31
|
"runtimeOptions",
|
|
30
32
|
"root"
|
|
31
33
|
]);
|
|
32
|
-
const RESERVED_SERVICE_NAMES_MESSAGE = "Available reserved names: params, secrets, fetch, fs, env, progress, runtimeOptions, root.";
|
|
34
|
+
const RESERVED_SERVICE_NAMES_MESSAGE = "Available reserved names: params, secrets, fetch, fs, env, diagnostics, progress, runtimeOptions, root.";
|
|
33
35
|
const NULL_OPTION_VALUE = Symbol("toolcraft.cli.null");
|
|
34
36
|
function inferProgramName(argv) {
|
|
35
37
|
const entrypoint = argv[1];
|
|
@@ -641,6 +643,7 @@ function createOption(field, globalLongOptionFlags) {
|
|
|
641
643
|
function resolveCLIControls(controls) {
|
|
642
644
|
return {
|
|
643
645
|
debug: controls?.debug === true,
|
|
646
|
+
logLevel: controls?.logLevel === true,
|
|
644
647
|
output: controls?.output === true,
|
|
645
648
|
verbose: controls?.verbose === true,
|
|
646
649
|
yes: controls?.yes === true
|
|
@@ -660,6 +663,9 @@ function getGlobalLongOptionFlags(presetsEnabled, versionEnabled, controls) {
|
|
|
660
663
|
if (controls.debug) {
|
|
661
664
|
flags.push("--debug");
|
|
662
665
|
}
|
|
666
|
+
if (controls.logLevel) {
|
|
667
|
+
flags.push("--log-level");
|
|
668
|
+
}
|
|
663
669
|
if (controls.verbose) {
|
|
664
670
|
flags.push("--verbose");
|
|
665
671
|
}
|
|
@@ -699,6 +705,9 @@ function createCommanderOption(flags, description, field) {
|
|
|
699
705
|
function hasHelpFlag(argv) {
|
|
700
706
|
return argv.some((token) => HELP_FLAGS.has(token));
|
|
701
707
|
}
|
|
708
|
+
function normalizeVerboseAlias(argv) {
|
|
709
|
+
return argv.map((token) => (token === "-v" ? "--verbose" : token));
|
|
710
|
+
}
|
|
702
711
|
function resolveHelpOutput(argv) {
|
|
703
712
|
for (let index = 0; index < argv.length; index += 1) {
|
|
704
713
|
const token = argv[index] ?? "";
|
|
@@ -1095,11 +1104,17 @@ function formatGlobalOptionsLine(ctx) {
|
|
|
1095
1104
|
if (ctx.controls.output) {
|
|
1096
1105
|
flags.push("--output <format>");
|
|
1097
1106
|
}
|
|
1107
|
+
if (ctx.controls.verbose) {
|
|
1108
|
+
flags.push("-v, --verbose");
|
|
1109
|
+
}
|
|
1098
1110
|
if (ctx.showVersion) {
|
|
1099
1111
|
flags.push("--version");
|
|
1100
1112
|
}
|
|
1101
1113
|
return flags.length > 0 ? `${text.section("Options:")} ${flags.join(" ")}` : "";
|
|
1102
1114
|
}
|
|
1115
|
+
function formatLeafGlobalOptionsLine(ctx) {
|
|
1116
|
+
return ctx.controls.verbose ? `${text.section("Options:")} -v, --verbose` : "";
|
|
1117
|
+
}
|
|
1103
1118
|
function collectSchemaGlobalFieldRows(group, scope, casing, globalLongOptionFlags) {
|
|
1104
1119
|
const seen = new Map();
|
|
1105
1120
|
const visit = (node) => {
|
|
@@ -1200,6 +1215,10 @@ function renderLeafHelp(command, breadcrumb, casing, globalOptions, rootUsageNam
|
|
|
1200
1215
|
if (optionRows.length > 0) {
|
|
1201
1216
|
sections.push(`${text.sectionHeader("Options")}\n${formatHelpOptionList(optionRows)}`);
|
|
1202
1217
|
}
|
|
1218
|
+
const builtInLine = formatLeafGlobalOptionsLine(globalOptions);
|
|
1219
|
+
if (builtInLine.length > 0) {
|
|
1220
|
+
sections.push(builtInLine);
|
|
1221
|
+
}
|
|
1203
1222
|
const secretRows = formatSecretRows(command.secrets);
|
|
1204
1223
|
if (secretRows.length > 0) {
|
|
1205
1224
|
sections.push(`${text.sectionHeader("Secrets (environment)")}\n${formatHelpOptionList(secretRows)}`);
|
|
@@ -1444,7 +1463,9 @@ function isToolcraftHiddenCommander(command) {
|
|
|
1444
1463
|
}
|
|
1445
1464
|
function getToolcraftHiddenDefaultNames(command) {
|
|
1446
1465
|
const value = Reflect.get(command, "_toolcraftHiddenDefaultNames");
|
|
1447
|
-
return Array.isArray(value)
|
|
1466
|
+
return Array.isArray(value)
|
|
1467
|
+
? value.filter((item) => typeof item === "string")
|
|
1468
|
+
: [];
|
|
1448
1469
|
}
|
|
1449
1470
|
function getToolcraftReservedChildNames(command) {
|
|
1450
1471
|
const value = Reflect.get(command, "_toolcraftReservedChildNames");
|
|
@@ -1482,6 +1503,9 @@ function addGlobalOptions(command, presetsEnabled, controls) {
|
|
|
1482
1503
|
.preset("trim")
|
|
1483
1504
|
.argParser(parseDebugStackMode));
|
|
1484
1505
|
}
|
|
1506
|
+
if (controls.logLevel) {
|
|
1507
|
+
options.push(new Option("--log-level <level>", "Set runtime diagnostic log level.").argParser(parseLogLevel));
|
|
1508
|
+
}
|
|
1485
1509
|
if (controls.verbose) {
|
|
1486
1510
|
options.push(new Option("--verbose", "Print detailed runtime diagnostics."));
|
|
1487
1511
|
}
|
|
@@ -1499,6 +1523,26 @@ function parseDebugStackMode(value) {
|
|
|
1499
1523
|
}
|
|
1500
1524
|
throw new InvalidArgumentError(formatInvalidEnumMessage("--debug", String(value), ["raw"], { candidates: ["raw"] }));
|
|
1501
1525
|
}
|
|
1526
|
+
function parseLogLevel(value) {
|
|
1527
|
+
if (isLogLevel(value)) {
|
|
1528
|
+
return value;
|
|
1529
|
+
}
|
|
1530
|
+
throw new InvalidArgumentError(formatInvalidEnumMessage("--log-level", value, [...LOG_LEVELS], {
|
|
1531
|
+
candidates: ["warn", "debug", "trace"],
|
|
1532
|
+
threshold: 3
|
|
1533
|
+
}));
|
|
1534
|
+
}
|
|
1535
|
+
function writeCLIDiagnosticEvent(event) {
|
|
1536
|
+
const transcript = event.data?.transcript;
|
|
1537
|
+
if (typeof transcript === "string") {
|
|
1538
|
+
process.stderr.write(transcript);
|
|
1539
|
+
return;
|
|
1540
|
+
}
|
|
1541
|
+
if (event.category === "progress" || event.level === "trace") {
|
|
1542
|
+
return;
|
|
1543
|
+
}
|
|
1544
|
+
process.stderr.write(`${event.message}\n`);
|
|
1545
|
+
}
|
|
1502
1546
|
function setNestedValue(target, path, value) {
|
|
1503
1547
|
let cursor = target;
|
|
1504
1548
|
for (let index = 0; index < path.length - 1; index += 1) {
|
|
@@ -2763,7 +2807,7 @@ function getResolvedFlags(command) {
|
|
|
2763
2807
|
const flags = command.optsWithGlobals();
|
|
2764
2808
|
return flags;
|
|
2765
2809
|
}
|
|
2766
|
-
async function executeCommand(state, services, requirementOptions, runtimeFetch, runtimeOptions, onErrorReportContext) {
|
|
2810
|
+
async function executeCommand(state, services, requirementOptions, runtimeFetch, runtimeOptions, diagnosticsOptions, onErrorReportContext) {
|
|
2767
2811
|
const logger = createLogger();
|
|
2768
2812
|
const primitives = {
|
|
2769
2813
|
logger,
|
|
@@ -2774,6 +2818,13 @@ async function executeCommand(state, services, requirementOptions, runtimeFetch,
|
|
|
2774
2818
|
const optionValues = state.actionCommand.optsWithGlobals();
|
|
2775
2819
|
const resolvedFlags = optionValues;
|
|
2776
2820
|
const output = resolveOutput(resolvedFlags);
|
|
2821
|
+
const diagnostics = createRuntimeLogger({
|
|
2822
|
+
level: resolvedFlags.logLevel ??
|
|
2823
|
+
(diagnosticsOptions.verboseControlEnabled && resolvedFlags.verbose
|
|
2824
|
+
? "trace"
|
|
2825
|
+
: diagnosticsOptions.logLevel),
|
|
2826
|
+
logger: diagnosticsOptions.logger ?? writeCLIDiagnosticEvent
|
|
2827
|
+
});
|
|
2777
2828
|
const shouldPrompt = !resolvedFlags.yes && Boolean(process.stdin.isTTY);
|
|
2778
2829
|
const runtime = await resolveFixtureRuntime(state.command, services, requirementOptions, runtimeFetch);
|
|
2779
2830
|
const preflightContext = {
|
|
@@ -2782,7 +2833,9 @@ async function executeCommand(state, services, requirementOptions, runtimeFetch,
|
|
|
2782
2833
|
fetch: runtime.fetch,
|
|
2783
2834
|
fs: runtime.fs,
|
|
2784
2835
|
env: runtime.env,
|
|
2836
|
+
diagnostics,
|
|
2785
2837
|
progress(message) {
|
|
2838
|
+
diagnostics.emit({ level: "info", message, category: "progress" });
|
|
2786
2839
|
logger.info(message);
|
|
2787
2840
|
}
|
|
2788
2841
|
};
|
|
@@ -3311,7 +3364,10 @@ function configureCommanderSuggestionOutput(command) {
|
|
|
3311
3364
|
}
|
|
3312
3365
|
export async function runCLI(roots, options = {}) {
|
|
3313
3366
|
enableSourceMaps();
|
|
3314
|
-
const
|
|
3367
|
+
const controls = resolveCLIControls(options.controls);
|
|
3368
|
+
const argv = controls.verbose
|
|
3369
|
+
? normalizeVerboseAlias([...(options.argv ?? process.argv)])
|
|
3370
|
+
: [...(options.argv ?? process.argv)];
|
|
3315
3371
|
const rootUsageName = options.rootUsageName ?? inferProgramName(argv);
|
|
3316
3372
|
let lastActionCommand;
|
|
3317
3373
|
let resolvedCommandPath = "";
|
|
@@ -3328,7 +3384,6 @@ export async function runCLI(roots, options = {}) {
|
|
|
3328
3384
|
const runtimeOptions = options.humanInLoop ?? {};
|
|
3329
3385
|
const runtimeFetch = options.fetch ?? globalThis.fetch;
|
|
3330
3386
|
version = options.version ?? findEntrypointPackageMetadata(argv[1])?.version;
|
|
3331
|
-
const controls = resolveCLIControls(options.controls);
|
|
3332
3387
|
const servicesWithBuiltIns = {
|
|
3333
3388
|
...services,
|
|
3334
3389
|
runtimeOptions,
|
|
@@ -3343,6 +3398,11 @@ export async function runCLI(roots, options = {}) {
|
|
|
3343
3398
|
await renderGeneratedHelp(root, argv, { ...options, version });
|
|
3344
3399
|
return;
|
|
3345
3400
|
}
|
|
3401
|
+
if (argv.length <= 2 && root.default?.scope.includes("cli") !== true) {
|
|
3402
|
+
userErrorPattern = "usage";
|
|
3403
|
+
await renderGeneratedHelp(root, argv, { ...options, version });
|
|
3404
|
+
return;
|
|
3405
|
+
}
|
|
3346
3406
|
program = new CommanderCommand();
|
|
3347
3407
|
program.name(root.name);
|
|
3348
3408
|
program.exitOverride();
|
|
@@ -3360,7 +3420,11 @@ export async function runCLI(roots, options = {}) {
|
|
|
3360
3420
|
const execute = async (state) => {
|
|
3361
3421
|
lastActionCommand = state.actionCommand;
|
|
3362
3422
|
resolvedCommandPath = formatCliCommandPath(state.commandPath);
|
|
3363
|
-
await executeCommand(state, servicesWithBuiltIns, requirementOptions, runtimeFetch, runtimeOptions,
|
|
3423
|
+
await executeCommand(state, servicesWithBuiltIns, requirementOptions, runtimeFetch, runtimeOptions, {
|
|
3424
|
+
logLevel: options.logLevel,
|
|
3425
|
+
logger: options.logger,
|
|
3426
|
+
verboseControlEnabled: controls.verbose
|
|
3427
|
+
}, (context) => {
|
|
3364
3428
|
errorReportContext = context;
|
|
3365
3429
|
});
|
|
3366
3430
|
};
|
|
@@ -3415,9 +3479,7 @@ export async function runCLI(roots, options = {}) {
|
|
|
3415
3479
|
debugStackMode: resolvedFlags !== undefined
|
|
3416
3480
|
? resolveDebugStackMode(resolvedFlags.debug)
|
|
3417
3481
|
: getDebugStackModeFromArgv(argv),
|
|
3418
|
-
output: resolvedFlags !== undefined
|
|
3419
|
-
? resolveOutput(resolvedFlags)
|
|
3420
|
-
: resolveOutputFromArgv(argv),
|
|
3482
|
+
output: resolvedFlags !== undefined ? resolveOutput(resolvedFlags) : resolveOutputFromArgv(argv),
|
|
3421
3483
|
verbose: resolvedFlags ? Boolean(resolvedFlags.verbose) : argv.includes("--verbose"),
|
|
3422
3484
|
program,
|
|
3423
3485
|
argv,
|
|
@@ -3,6 +3,7 @@ import { InvalidTransitionError } from "@poe-code/task-list";
|
|
|
3
3
|
import { UserError, resolveCommandSecrets } from "../index.js";
|
|
4
4
|
import { ensureApprovalList } from "./approval-tasks.js";
|
|
5
5
|
import { resolveProvider } from "./gate.js";
|
|
6
|
+
import { createRuntimeLogger } from "../runtime-logging.js";
|
|
6
7
|
const MAX_AVAILABLE_COMMAND_PATHS = 20;
|
|
7
8
|
export async function runApproval(approvalId, runtimeOptions, root) {
|
|
8
9
|
const { tasks } = await ensureApprovalList(runtimeOptions);
|
|
@@ -15,8 +16,8 @@ export async function runApproval(approvalId, runtimeOptions, root) {
|
|
|
15
16
|
try {
|
|
16
17
|
await tasks.fire(approvalId, "claim", {
|
|
17
18
|
metadataPatch: {
|
|
18
|
-
pid: process.pid
|
|
19
|
-
}
|
|
19
|
+
pid: process.pid
|
|
20
|
+
}
|
|
20
21
|
});
|
|
21
22
|
}
|
|
22
23
|
catch (error) {
|
|
@@ -28,15 +29,15 @@ export async function runApproval(approvalId, runtimeOptions, root) {
|
|
|
28
29
|
try {
|
|
29
30
|
const approvalResult = await provider.requestApproval({
|
|
30
31
|
message: approval.message,
|
|
31
|
-
declineInputPrompt: approval.declineInputPrompt ?? undefined
|
|
32
|
+
declineInputPrompt: approval.declineInputPrompt ?? undefined
|
|
32
33
|
});
|
|
33
34
|
if (approvalResult.outcome === "declined") {
|
|
34
35
|
await tasks.fire(approvalId, "decline", {
|
|
35
36
|
metadataPatch: {
|
|
36
37
|
error: {
|
|
37
|
-
reason: approvalResult.reason
|
|
38
|
-
}
|
|
39
|
-
}
|
|
38
|
+
reason: approvalResult.reason
|
|
39
|
+
}
|
|
40
|
+
}
|
|
40
41
|
});
|
|
41
42
|
return;
|
|
42
43
|
}
|
|
@@ -44,8 +45,8 @@ export async function runApproval(approvalId, runtimeOptions, root) {
|
|
|
44
45
|
catch (error) {
|
|
45
46
|
await tasks.fire(approvalId, "fail", {
|
|
46
47
|
metadataPatch: {
|
|
47
|
-
error: errorMetadataFromUnknown(error)
|
|
48
|
-
}
|
|
48
|
+
error: errorMetadataFromUnknown(error)
|
|
49
|
+
}
|
|
49
50
|
});
|
|
50
51
|
return;
|
|
51
52
|
}
|
|
@@ -59,23 +60,23 @@ export async function runApproval(approvalId, runtimeOptions, root) {
|
|
|
59
60
|
await tasks.fire(approvalId, "fail", {
|
|
60
61
|
metadataPatch: {
|
|
61
62
|
error: {
|
|
62
|
-
message: "result not JSON-serializable"
|
|
63
|
-
}
|
|
64
|
-
}
|
|
63
|
+
message: "result not JSON-serializable"
|
|
64
|
+
}
|
|
65
|
+
}
|
|
65
66
|
});
|
|
66
67
|
return;
|
|
67
68
|
}
|
|
68
69
|
await tasks.fire(approvalId, "succeed", {
|
|
69
70
|
metadataPatch: {
|
|
70
|
-
result: serializedResult.value
|
|
71
|
-
}
|
|
71
|
+
result: serializedResult.value
|
|
72
|
+
}
|
|
72
73
|
});
|
|
73
74
|
}
|
|
74
75
|
catch (error) {
|
|
75
76
|
await tasks.fire(approvalId, "fail", {
|
|
76
77
|
metadataPatch: {
|
|
77
|
-
error: errorMetadataFromUnknown(error)
|
|
78
|
-
}
|
|
78
|
+
error: errorMetadataFromUnknown(error)
|
|
79
|
+
}
|
|
79
80
|
});
|
|
80
81
|
}
|
|
81
82
|
}
|
|
@@ -105,7 +106,7 @@ function readApprovalPayload(task) {
|
|
|
105
106
|
enqueuedAt: typeof metadata.enqueuedAt === "string" ? metadata.enqueuedAt : undefined,
|
|
106
107
|
pid: typeof metadata.pid === "number" || metadata.pid === null ? metadata.pid : undefined,
|
|
107
108
|
result: metadata.result,
|
|
108
|
-
error: metadata.error
|
|
109
|
+
error: metadata.error
|
|
109
110
|
};
|
|
110
111
|
}
|
|
111
112
|
function findCommand(root, commandPath) {
|
|
@@ -170,15 +171,17 @@ function getVisibleCliChildren(root) {
|
|
|
170
171
|
return root.kind === "group" ? root.children.filter(isNodeVisibleInCli) : [];
|
|
171
172
|
}
|
|
172
173
|
function createHandlerContext(command, params) {
|
|
174
|
+
const diagnostics = createRuntimeLogger();
|
|
173
175
|
return {
|
|
174
176
|
params,
|
|
175
177
|
secrets: resolveCommandSecrets(command),
|
|
176
178
|
fetch: globalThis.fetch,
|
|
177
179
|
fs: createFs(),
|
|
178
180
|
env: createEnv(),
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
181
|
+
diagnostics,
|
|
182
|
+
progress(message) {
|
|
183
|
+
diagnostics.emit({ level: "info", message, category: "progress" });
|
|
184
|
+
}
|
|
182
185
|
};
|
|
183
186
|
}
|
|
184
187
|
function createFs() {
|
|
@@ -198,14 +201,14 @@ function createFs() {
|
|
|
198
201
|
},
|
|
199
202
|
lstat: async (path) => lstat(path),
|
|
200
203
|
rename: async (fromPath, toPath) => rename(fromPath, toPath),
|
|
201
|
-
unlink: async (path) => unlink(path)
|
|
204
|
+
unlink: async (path) => unlink(path)
|
|
202
205
|
};
|
|
203
206
|
}
|
|
204
207
|
function createEnv(values = process.env) {
|
|
205
208
|
return {
|
|
206
209
|
get(key) {
|
|
207
210
|
return values[key];
|
|
208
|
-
}
|
|
211
|
+
}
|
|
209
212
|
};
|
|
210
213
|
}
|
|
211
214
|
function serializeJsonResult(value) {
|
|
@@ -213,17 +216,17 @@ function serializeJsonResult(value) {
|
|
|
213
216
|
const serialized = JSON.stringify(value);
|
|
214
217
|
if (serialized === undefined) {
|
|
215
218
|
return {
|
|
216
|
-
ok: false
|
|
219
|
+
ok: false
|
|
217
220
|
};
|
|
218
221
|
}
|
|
219
222
|
return {
|
|
220
223
|
ok: true,
|
|
221
|
-
value: JSON.parse(serialized)
|
|
224
|
+
value: JSON.parse(serialized)
|
|
222
225
|
};
|
|
223
226
|
}
|
|
224
227
|
catch {
|
|
225
228
|
return {
|
|
226
|
-
ok: false
|
|
229
|
+
ok: false
|
|
227
230
|
};
|
|
228
231
|
}
|
|
229
232
|
}
|
|
@@ -232,11 +235,11 @@ function errorMetadataFromUnknown(error) {
|
|
|
232
235
|
return {
|
|
233
236
|
name: error.name,
|
|
234
237
|
message: error.message,
|
|
235
|
-
stack: error.stack
|
|
238
|
+
stack: error.stack
|
|
236
239
|
};
|
|
237
240
|
}
|
|
238
241
|
return {
|
|
239
242
|
name: "Error",
|
|
240
|
-
message: String(error)
|
|
243
|
+
message: String(error)
|
|
241
244
|
};
|
|
242
245
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ import type { LoggerOutput, RenderTableOptions, ThemePalette } from "toolcraft-d
|
|
|
4
4
|
import { ApprovalDeclinedError } from "./human-in-loop/types.js";
|
|
5
5
|
import type { HumanInLoopConfig, HumanInLoopPending, HumanInLoopRuntimeOptions } from "./human-in-loop/types.js";
|
|
6
6
|
import { ToolcraftBugError, UserError } from "./user-error.js";
|
|
7
|
+
import type { RuntimeLogger } from "./runtime-logging.js";
|
|
7
8
|
type ScopeValue = "cli" | "mcp" | "sdk";
|
|
8
9
|
type AnyObjectSchema = ObjectSchema<Record<string, never>>;
|
|
9
10
|
type EmptyServices = Record<string, never>;
|
|
@@ -68,6 +69,7 @@ export type GroupCheckContext<TServices extends object = EmptyServices> = TServi
|
|
|
68
69
|
fetch: typeof globalThis.fetch;
|
|
69
70
|
fs: HandlerFs;
|
|
70
71
|
env: HandlerEnv;
|
|
72
|
+
diagnostics: RuntimeLogger;
|
|
71
73
|
progress(message: string): void;
|
|
72
74
|
};
|
|
73
75
|
export type CommandCheckContext<TParamsSchema extends ObjectSchema<any> = AnyObjectSchema, TSecrets extends SecretDeclarations | undefined = undefined, TServices extends object = EmptyServices> = TServices & {
|
|
@@ -76,6 +78,7 @@ export type CommandCheckContext<TParamsSchema extends ObjectSchema<any> = AnyObj
|
|
|
76
78
|
fetch: typeof globalThis.fetch;
|
|
77
79
|
fs: HandlerFs;
|
|
78
80
|
env: HandlerEnv;
|
|
81
|
+
diagnostics: RuntimeLogger;
|
|
79
82
|
progress(message: string): void;
|
|
80
83
|
};
|
|
81
84
|
export interface Requires<TContext = unknown> {
|
|
@@ -94,6 +97,7 @@ export type HandlerContext<TParamsSchema extends ObjectSchema<any> = AnyObjectSc
|
|
|
94
97
|
fetch: typeof globalThis.fetch;
|
|
95
98
|
fs: HandlerFs;
|
|
96
99
|
env: HandlerEnv;
|
|
100
|
+
diagnostics: RuntimeLogger;
|
|
97
101
|
progress(message: string): void;
|
|
98
102
|
};
|
|
99
103
|
export interface CommandConfig<TServices extends object, TParamsSchema extends ObjectSchema<any>, TSecrets extends SecretDeclarations | undefined, TResult> {
|
|
@@ -200,7 +204,9 @@ export { S, toJsonSchema } from "toolcraft-schema";
|
|
|
200
204
|
export { AuthenticationError, BadRequestError, ClientError, ConflictError, HttpError, InternalServerError, NotFoundError, PermissionDeniedError, RateLimitError, ServerError, ServiceUnavailableError, UnprocessableEntityError, createHttpError } from "./http-errors.js";
|
|
201
205
|
export type { HttpErrorRequest, HttpErrorResponse } from "./http-errors.js";
|
|
202
206
|
export { ApprovalDeclinedError, ToolcraftBugError, UserError };
|
|
207
|
+
export { createRuntimeLogger, isLogLevel, shouldEmitDiagnostic } from "./runtime-logging.js";
|
|
203
208
|
export { findPackageMetadata, packageMetadata } from "./package-metadata.js";
|
|
204
209
|
export type { PackageMetadata } from "./package-metadata.js";
|
|
210
|
+
export type { DiagnosticLogEvent, LogLevel, RuntimeLogger, RuntimeLoggerInput } from "./runtime-logging.js";
|
|
205
211
|
export type { AnySchema, ArraySchema, BooleanSchema, EnumSchema, JsonSchema, NumberSchema, ObjectSchema, OptionalSchema, Static, StringSchema } from "toolcraft-schema";
|
|
206
212
|
export type { HumanInLoopConfig, HumanInLoopPending, HumanInLoopRuntimeOptions };
|
package/dist/index.js
CHANGED
|
@@ -236,8 +236,7 @@ function suggestSecretEnv(input, candidates) {
|
|
|
236
236
|
const lastPart = inputParts[inputParts.length - 1];
|
|
237
237
|
const relatedCandidates = candidates.filter((candidate) => {
|
|
238
238
|
const candidateParts = candidate.split("_");
|
|
239
|
-
return (candidateParts[0] === firstPart &&
|
|
240
|
-
candidateParts[candidateParts.length - 1] === lastPart);
|
|
239
|
+
return (candidateParts[0] === firstPart && candidateParts[candidateParts.length - 1] === lastPart);
|
|
241
240
|
});
|
|
242
241
|
const expandedSuggestions = suggest(input, relatedCandidates, {
|
|
243
242
|
threshold: Math.max(4, Math.floor(input.length / 4))
|
|
@@ -473,4 +472,5 @@ export function getCommandSourcePath(command) {
|
|
|
473
472
|
export { S, toJsonSchema } from "toolcraft-schema";
|
|
474
473
|
export { AuthenticationError, BadRequestError, ClientError, ConflictError, HttpError, InternalServerError, NotFoundError, PermissionDeniedError, RateLimitError, ServerError, ServiceUnavailableError, UnprocessableEntityError, createHttpError } from "./http-errors.js";
|
|
475
474
|
export { ApprovalDeclinedError, ToolcraftBugError, UserError };
|
|
475
|
+
export { createRuntimeLogger, isLogLevel, shouldEmitDiagnostic } from "./runtime-logging.js";
|
|
476
476
|
export { findPackageMetadata, packageMetadata } from "./package-metadata.js";
|
package/dist/mcp.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type SDKTransport, type Server as TinyServer } from "tiny-stdio-mcp-server";
|
|
2
|
-
import type { Group } from "./index.js";
|
|
2
|
+
import type { Group, LogLevel, RuntimeLoggerInput } from "./index.js";
|
|
3
3
|
import { type ErrorReportsOption } from "./error-report.js";
|
|
4
4
|
import { type HumanInLoopRuntimeOptions } from "./human-in-loop/index.js";
|
|
5
5
|
type Casing = "snake" | "camel";
|
|
@@ -13,6 +13,8 @@ export interface RunMCPOptions<TServices extends object = Record<string, unknown
|
|
|
13
13
|
version?: string;
|
|
14
14
|
humanInLoop?: HumanInLoopRuntimeOptions;
|
|
15
15
|
projectRoot?: string;
|
|
16
|
+
logLevel?: LogLevel;
|
|
17
|
+
logger?: RuntimeLoggerInput;
|
|
16
18
|
/**
|
|
17
19
|
* Optional allowlist of MCP tool names or group prefixes.
|
|
18
20
|
*
|
package/dist/mcp.js
CHANGED
|
@@ -13,17 +13,19 @@ import { filterSchemaForScope } from "./schema-scope.js";
|
|
|
13
13
|
import { enableSourceMaps } from "./stack-trim.js";
|
|
14
14
|
import { suggest } from "./suggest.js";
|
|
15
15
|
import { throwValidationErrors } from "./validation-errors.js";
|
|
16
|
+
import { createRuntimeLogger } from "./runtime-logging.js";
|
|
16
17
|
const RESERVED_SERVICE_NAMES = new Set([
|
|
17
18
|
"params",
|
|
18
19
|
"secrets",
|
|
19
20
|
"fetch",
|
|
20
21
|
"fs",
|
|
21
22
|
"env",
|
|
23
|
+
"diagnostics",
|
|
22
24
|
"progress",
|
|
23
25
|
"runtimeOptions",
|
|
24
26
|
"root"
|
|
25
27
|
]);
|
|
26
|
-
const RESERVED_SERVICE_NAMES_MESSAGE = "Available reserved names: params, secrets, fetch, fs, env, progress, runtimeOptions, root.";
|
|
28
|
+
const RESERVED_SERVICE_NAMES_MESSAGE = "Available reserved names: params, secrets, fetch, fs, env, diagnostics, progress, runtimeOptions, root.";
|
|
27
29
|
function normalizeRoots(roots) {
|
|
28
30
|
if (!Array.isArray(roots)) {
|
|
29
31
|
return roots;
|
|
@@ -755,6 +757,10 @@ function createResolvedMCPServer(root, options) {
|
|
|
755
757
|
const services = (options.services ?? {});
|
|
756
758
|
const runtimeOptions = options.humanInLoop ?? {};
|
|
757
759
|
const runtimeFetch = options.fetch ?? globalThis.fetch;
|
|
760
|
+
const diagnostics = createRuntimeLogger({
|
|
761
|
+
level: options.logLevel,
|
|
762
|
+
logger: options.logger
|
|
763
|
+
});
|
|
758
764
|
const servicesWithBuiltIns = {
|
|
759
765
|
...services,
|
|
760
766
|
runtimeOptions,
|
|
@@ -780,8 +786,9 @@ function createResolvedMCPServer(root, options) {
|
|
|
780
786
|
fetch: runtimeFetch,
|
|
781
787
|
fs: createFs(),
|
|
782
788
|
env: createEnv(),
|
|
783
|
-
|
|
784
|
-
|
|
789
|
+
diagnostics,
|
|
790
|
+
progress(message) {
|
|
791
|
+
diagnostics.emit({ level: "info", message, category: "progress" });
|
|
785
792
|
}
|
|
786
793
|
};
|
|
787
794
|
await assertCommandRequirements(tool.command, { ...baseContext, params: undefined });
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export type LogLevel = "silent" | "error" | "warn" | "info" | "debug" | "trace";
|
|
2
|
+
export interface DiagnosticLogEvent {
|
|
3
|
+
level: Exclude<LogLevel, "silent">;
|
|
4
|
+
message: string;
|
|
5
|
+
category?: "runtime" | "http" | "auth" | "retry" | "progress";
|
|
6
|
+
data?: Record<string, unknown>;
|
|
7
|
+
}
|
|
8
|
+
export interface RuntimeLogger {
|
|
9
|
+
level: LogLevel;
|
|
10
|
+
emit(event: DiagnosticLogEvent): void;
|
|
11
|
+
}
|
|
12
|
+
export type RuntimeLoggerInput = RuntimeLogger | ((event: DiagnosticLogEvent) => void);
|
|
13
|
+
export declare const LOG_LEVELS: readonly ["silent", "error", "warn", "info", "debug", "trace"];
|
|
14
|
+
export declare function isLogLevel(value: string): value is LogLevel;
|
|
15
|
+
export declare function shouldEmitDiagnostic(eventLevel: LogLevel, configuredLevel: LogLevel): boolean;
|
|
16
|
+
export declare function createRuntimeLogger(options?: {
|
|
17
|
+
level?: LogLevel;
|
|
18
|
+
logger?: RuntimeLoggerInput;
|
|
19
|
+
}): RuntimeLogger;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
const LOG_LEVEL_RANK = {
|
|
2
|
+
silent: 0,
|
|
3
|
+
error: 1,
|
|
4
|
+
warn: 2,
|
|
5
|
+
info: 3,
|
|
6
|
+
debug: 4,
|
|
7
|
+
trace: 5
|
|
8
|
+
};
|
|
9
|
+
export const LOG_LEVELS = Object.freeze([
|
|
10
|
+
"silent",
|
|
11
|
+
"error",
|
|
12
|
+
"warn",
|
|
13
|
+
"info",
|
|
14
|
+
"debug",
|
|
15
|
+
"trace"
|
|
16
|
+
]);
|
|
17
|
+
export function isLogLevel(value) {
|
|
18
|
+
return LOG_LEVELS.includes(value);
|
|
19
|
+
}
|
|
20
|
+
export function shouldEmitDiagnostic(eventLevel, configuredLevel) {
|
|
21
|
+
if (eventLevel === "silent" || configuredLevel === "silent") {
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
return LOG_LEVEL_RANK[eventLevel] <= LOG_LEVEL_RANK[configuredLevel];
|
|
25
|
+
}
|
|
26
|
+
export function createRuntimeLogger(options = {}) {
|
|
27
|
+
const level = options.level ?? "warn";
|
|
28
|
+
const sink = options.logger;
|
|
29
|
+
return {
|
|
30
|
+
level,
|
|
31
|
+
emit(event) {
|
|
32
|
+
if (!shouldEmitDiagnostic(event.level, level)) {
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
if (typeof sink === "function") {
|
|
36
|
+
sink(event);
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
sink?.emit(event);
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
}
|
package/dist/sdk.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ObjectSchema, Static } from "toolcraft-schema";
|
|
2
|
-
import type { Group, Scope } from "./index.js";
|
|
2
|
+
import type { Group, LogLevel, RuntimeLoggerInput, Scope } from "./index.js";
|
|
3
3
|
import { type ErrorReportsOption } from "./error-report.js";
|
|
4
4
|
import type { HumanInLoopPending, HumanInLoopRuntimeOptions } from "./human-in-loop/index.js";
|
|
5
5
|
type ScopeInput = readonly Scope[] | undefined;
|
|
@@ -69,6 +69,8 @@ export interface CreateSDKOptions<TServices extends object = Record<string, unkn
|
|
|
69
69
|
apiVersion?: string;
|
|
70
70
|
projectRoot?: string;
|
|
71
71
|
errorReports?: ErrorReportsOption;
|
|
72
|
+
logLevel?: LogLevel;
|
|
73
|
+
logger?: RuntimeLoggerInput;
|
|
72
74
|
}
|
|
73
75
|
export declare function createSDK<TRootInfo, TServices extends object = Record<string, unknown>>(root: Group<any> & {
|
|
74
76
|
readonly __agentKitGroupTypeInfo: TRootInfo;
|
package/dist/sdk.js
CHANGED
|
@@ -9,17 +9,19 @@ import { filterSchemaForScope } from "./schema-scope.js";
|
|
|
9
9
|
import { enableSourceMaps } from "./stack-trim.js";
|
|
10
10
|
import { suggest } from "./suggest.js";
|
|
11
11
|
import { throwValidationErrors } from "./validation-errors.js";
|
|
12
|
+
import { createRuntimeLogger } from "./runtime-logging.js";
|
|
12
13
|
const RESERVED_SERVICE_NAMES = new Set([
|
|
13
14
|
"params",
|
|
14
15
|
"secrets",
|
|
15
16
|
"fetch",
|
|
16
17
|
"fs",
|
|
17
18
|
"env",
|
|
19
|
+
"diagnostics",
|
|
18
20
|
"progress",
|
|
19
21
|
"runtimeOptions",
|
|
20
22
|
"root"
|
|
21
23
|
]);
|
|
22
|
-
const RESERVED_SERVICE_NAMES_MESSAGE = "Available reserved names: params, secrets, fetch, fs, env, progress, runtimeOptions, root.";
|
|
24
|
+
const RESERVED_SERVICE_NAMES_MESSAGE = "Available reserved names: params, secrets, fetch, fs, env, diagnostics, progress, runtimeOptions, root.";
|
|
23
25
|
function splitWords(value) {
|
|
24
26
|
const words = [];
|
|
25
27
|
let current = "";
|
|
@@ -362,6 +364,10 @@ function createResolvedSDK(root, options = {}) {
|
|
|
362
364
|
const services = options.services ?? {};
|
|
363
365
|
const runtimeOptions = options.humanInLoop ?? {};
|
|
364
366
|
const runtimeFetch = options.fetch ?? globalThis.fetch;
|
|
367
|
+
const diagnostics = createRuntimeLogger({
|
|
368
|
+
level: options.logLevel,
|
|
369
|
+
logger: options.logger
|
|
370
|
+
});
|
|
365
371
|
void options.casing;
|
|
366
372
|
validateServices(services);
|
|
367
373
|
function build(node, path) {
|
|
@@ -384,8 +390,9 @@ function createResolvedSDK(root, options = {}) {
|
|
|
384
390
|
fetch: runtimeFetch,
|
|
385
391
|
fs: createFs(),
|
|
386
392
|
env: createEnv(),
|
|
387
|
-
|
|
388
|
-
|
|
393
|
+
diagnostics,
|
|
394
|
+
progress(message) {
|
|
395
|
+
diagnostics.emit({ level: "info", message, category: "progress" });
|
|
389
396
|
}
|
|
390
397
|
};
|
|
391
398
|
await assertCommandRequirements(node, { ...baseContext, params: undefined }, {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "toolcraft",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.68",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
"postpack": "node ../../scripts/manage-bundled-workspace-deps.mjs cleanup . toolcraft-design @poe-code/frontmatter @poe-code/agent-mcp-config @poe-code/agent-human-in-loop @poe-code/task-list @poe-code/agent-defs @poe-code/config-mutations @poe-code/process-runner tiny-mcp-client mcp-oauth auth-store"
|
|
48
48
|
},
|
|
49
49
|
"dependencies": {
|
|
50
|
-
"toolcraft-schema": "0.0.
|
|
50
|
+
"toolcraft-schema": "0.0.68",
|
|
51
51
|
"commander": "^14.0.3",
|
|
52
52
|
"fast-string-width": "^3.0.2",
|
|
53
53
|
"fast-wrap-ansi": "^0.2.0",
|