@silkweave/cli 3.2.1 → 4.0.1
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/build/index.d.mts.map +1 -1
- package/build/index.mjs +7 -2
- package/build/index.mjs.map +1 -1
- package/package.json +7 -5
package/build/index.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/adapter/cli.ts"],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/adapter/cli.ts"],"mappings":";;;cAqIa,GAAA,EAAK,cAAA"}
|
package/build/index.mjs
CHANGED
|
@@ -15,9 +15,14 @@ function handleCLIError(error) {
|
|
|
15
15
|
process.exitCode = 1;
|
|
16
16
|
}
|
|
17
17
|
function parseCLIInput(action, args) {
|
|
18
|
-
const
|
|
18
|
+
const opts = args.slice(0, -1).pop();
|
|
19
|
+
const rawInput = {};
|
|
20
|
+
for (const key of Object.keys(action.input.shape)) {
|
|
21
|
+
const value = opts[camelCase(key)];
|
|
22
|
+
if (value !== void 0) rawInput[key] = value;
|
|
23
|
+
}
|
|
19
24
|
action.args?.forEach((k, index) => {
|
|
20
|
-
rawInput[k] = args[index];
|
|
25
|
+
rawInput[String(k)] = args[index];
|
|
21
26
|
});
|
|
22
27
|
const { error, data } = action.input.safeParse(rawInput);
|
|
23
28
|
if (error || !data) {
|
package/build/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"sources":["../src/adapter/cli.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { Action, ActionRun, ActionStreamRun, AdapterFactory, createConsoleLogger, isStreamingAction, SilkweaveContext, SilkweaveError, SilkweaveOptions, unwrap } from '@silkweave/core'\nimport { camelCase, kebabCase } from 'change-case'\nimport { Command } from 'commander'\nimport { once } from 'events'\nimport z from 'zod/v4'\n\nfunction handleCLIError(error: unknown) {\n if (error instanceof SilkweaveError) {\n console.error(`[${error.code}] ${error.message}`)\n } else if (error instanceof z.ZodError) {\n console.error('Validation Error')\n for (const issue of error.issues) {\n console.error(`${issue.path}: ${issue.message}`)\n }\n } else if (error instanceof Error) {\n console.error(error.message)\n } else if (typeof error === 'string') {\n console.error(error)\n } else {\n console.error(JSON.stringify(error))\n }\n process.exitCode = 1\n}\n\nfunction parseCLIInput(action: Action, args: any[]) {\n const tmpArgs = args.slice(0, -1)\n const
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../src/adapter/cli.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { Action, ActionRun, ActionStreamRun, AdapterFactory, createConsoleLogger, isStreamingAction, SilkweaveContext, SilkweaveError, SilkweaveOptions, unwrap } from '@silkweave/core'\nimport { camelCase, kebabCase } from 'change-case'\nimport { Command } from 'commander'\nimport { once } from 'events'\nimport z from 'zod/v4'\n\nfunction handleCLIError(error: unknown) {\n if (error instanceof SilkweaveError) {\n console.error(`[${error.code}] ${error.message}`)\n } else if (error instanceof z.ZodError) {\n console.error('Validation Error')\n for (const issue of error.issues) {\n console.error(`${issue.path}: ${issue.message}`)\n }\n } else if (error instanceof Error) {\n console.error(error.message)\n } else if (typeof error === 'string') {\n console.error(error)\n } else {\n console.error(JSON.stringify(error))\n }\n process.exitCode = 1\n}\n\nfunction parseCLIInput(action: Action, args: any[]) {\n const tmpArgs = args.slice(0, -1)\n const opts = tmpArgs.pop()\n // Options register as kebab-case flags (--action-id) and Commander stores them\n // camelized (actionId) - read back via camelCase(key) so snake_case schema keys\n // (action_id) map too, not just single-word ones.\n const rawInput: Record<string, unknown> = {}\n for (const key of Object.keys(action.input.shape)) {\n const value = opts[camelCase(key)]\n if (value !== undefined) { rawInput[key] = value }\n }\n action.args?.forEach((k, index) => { rawInput[String(k)] = args[index] })\n const { error, data } = action.input.safeParse(rawInput)\n if (error || !data) {\n handleCLIError(error)\n process.exit()\n }\n\n return data\n}\n\n/**\n * Map a Zod option type to its commander placeholder and, when the value needs\n * coercing from commander's raw string, a `parseArg`. Numeric/bigint/json fields\n * MUST carry a parser - without it every z.number() field fails Zod with\n * `expected number, received string`.\n */\nfunction optionSpec(type: z.ZodType): { placeholder: string; parseArg?: (value: string) => unknown } {\n if (type instanceof z.ZodNumber) {\n return { placeholder: '<number>', parseArg: (value) => Number(value) }\n }\n if (type instanceof z.ZodBigInt) {\n return { placeholder: '<bigint>', parseArg: (value) => { try { return BigInt(value) } catch { return value } } }\n }\n if (type instanceof z.ZodString || type instanceof z.ZodEnum) {\n return { placeholder: '<string>' }\n }\n if (type instanceof z.ZodObject || type instanceof z.ZodRecord || type instanceof z.ZodArray) {\n return { placeholder: '<json>', parseArg: JSON.parse }\n }\n throw new Error(`Invalid zod type: ${type.def.type}`)\n}\n\nfunction addCliOption(command: Command, key: string, type: z.ZodType, defaultValue: any, isArgument: boolean) {\n const description = type.description\n if (isArgument) {\n command.argument(`[${camelCase(key)}]`, description, defaultValue)\n return\n }\n const flag = kebabCase(key)\n if (type instanceof z.ZodBoolean) {\n command.option(`--${flag}`, description, defaultValue)\n command.option(`--no-${flag}`)\n return\n }\n const { placeholder, parseArg } = optionSpec(type)\n if (parseArg) {\n command.option(`--${flag} ${placeholder}`, description ?? '', parseArg, defaultValue)\n } else {\n command.option(`--${flag} ${placeholder}`, description, defaultValue)\n }\n}\n\nasync function runStreamingCommand(action: Action, input: object, context: SilkweaveContext) {\n const streamRun = action.run as ActionStreamRun<object, unknown>\n const iter = streamRun(input, context)\n for await (const chunk of iter) {\n const line = JSON.stringify(chunk) + '\\n'\n if (!process.stdout.write(line)) {\n await once(process.stdout, 'drain')\n }\n }\n}\n\nfunction registerCommand(program: Command, action: Action, options: SilkweaveOptions, context: SilkweaveContext) {\n const command = program.command(kebabCase(action.name)).description(action.description)\n const shape = action.input.shape\n const argKeys = action.args ?? []\n const argSet = new Set(argKeys)\n // Options first (order irrelevant), then positional arguments in `action.args`\n // order - not input-shape key order - so commander's positional slots line up\n // with how parseCLIInput reads them back (else the values are cross-assigned).\n for (const key of Object.keys(shape)) {\n if (argSet.has(key)) { continue }\n const [type, { defaultValue }] = unwrap(shape[key])\n addCliOption(command, key, type, defaultValue, false)\n }\n for (const argKey of argKeys) {\n const key = String(argKey)\n const [type, { defaultValue }] = unwrap(shape[key])\n addCliOption(command, key, type, defaultValue, true)\n }\n command.action((...args) => {\n const logger = createConsoleLogger()\n const input = parseCLIInput(action, args)\n const actionContext = context.fork({ logger, command })\n if (isStreamingAction(action)) {\n runStreamingCommand(action, input, actionContext).catch(handleCLIError)\n return\n }\n console.info(`${options.name} - ${action.name}`)\n const runFn = action.run as ActionRun<object, object>\n runFn(input, actionContext).then((result) => {\n logger.info(JSON.stringify(result, null, 2))\n }).catch(handleCLIError)\n })\n}\n\nexport const cli: AdapterFactory = () => {\n return (options, baseContext) => {\n const context = baseContext.fork({ adapter: 'cli' })\n const program = new Command()\n .name(options.name)\n .description(options.description)\n .version(options.version)\n\n return {\n context,\n start: async (actions) => {\n for (const action of actions) {\n registerCommand(program, action, options, context)\n }\n program.parse()\n },\n stop: async () => { }\n }\n }\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@silkweave/cli",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.0.1",
|
|
4
4
|
"description": "Silkweave CLI Adapter",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"homepage": "https://www.silkweave.dev",
|
|
@@ -29,18 +29,19 @@
|
|
|
29
29
|
"change-case": "^5.4.4",
|
|
30
30
|
"commander": "^13.1.0",
|
|
31
31
|
"zod": "^3.25.0",
|
|
32
|
-
"@silkweave/core": "
|
|
32
|
+
"@silkweave/core": "4.0.1"
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
35
|
"@eslint/js": "^10.0.1",
|
|
36
36
|
"@stylistic/eslint-plugin": "^5.10.0",
|
|
37
|
-
"eslint": "^10.4.0",
|
|
38
37
|
"@types/node": "^22.0.0",
|
|
38
|
+
"eslint": "^10.4.0",
|
|
39
39
|
"rimraf": "^6.1.3",
|
|
40
40
|
"tsdown": "^0.21.8",
|
|
41
41
|
"tsx": "^4.21.0",
|
|
42
42
|
"typescript": "^5.9.3",
|
|
43
|
-
"typescript-eslint": "^8.56.1"
|
|
43
|
+
"typescript-eslint": "^8.56.1",
|
|
44
|
+
"vitest": "^4.1.9"
|
|
44
45
|
},
|
|
45
46
|
"scripts": {
|
|
46
47
|
"clean": "rimraf build",
|
|
@@ -48,6 +49,7 @@
|
|
|
48
49
|
"watch": "tsdown --watch",
|
|
49
50
|
"typecheck": "tsc --noEmit",
|
|
50
51
|
"lint": "eslint",
|
|
51
|
-
"check": "pnpm lint && pnpm typecheck"
|
|
52
|
+
"check": "pnpm lint && pnpm typecheck",
|
|
53
|
+
"test": "vitest run"
|
|
52
54
|
}
|
|
53
55
|
}
|