@silkweave/cli 1.3.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/.turbo/turbo-build.log +18 -0
- package/.turbo/turbo-check.log +13 -0
- package/.turbo/turbo-lint.log +5 -0
- package/.turbo/turbo-prepack.log +26 -0
- package/README.md +67 -0
- package/build/index.d.ts +5 -0
- package/build/index.js +85 -0
- package/build/index.js.map +1 -0
- package/package.json +39 -0
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
> @silkweave/cli@1.3.0 build /Users/atomic/projects/ai/silkweave/packages/cli
|
|
4
|
+
> tsup
|
|
5
|
+
|
|
6
|
+
[34mCLI[39m Building entry: src/index.ts
|
|
7
|
+
[34mCLI[39m Using tsconfig: tsconfig.json
|
|
8
|
+
[34mCLI[39m tsup v8.5.1
|
|
9
|
+
[34mCLI[39m Using tsup config: /Users/atomic/projects/ai/silkweave/packages/cli/tsup.config.ts
|
|
10
|
+
[34mCLI[39m Target: es2022
|
|
11
|
+
[34mCLI[39m Cleaning output folder
|
|
12
|
+
[34mESM[39m Build start
|
|
13
|
+
[32mESM[39m [1mbuild/index.js [22m[32m3.19 KB[39m
|
|
14
|
+
[32mESM[39m [1mbuild/index.js.map [22m[32m5.64 KB[39m
|
|
15
|
+
[32mESM[39m ⚡️ Build success in 9ms
|
|
16
|
+
DTS Build start
|
|
17
|
+
DTS ⚡️ Build success in 565ms
|
|
18
|
+
DTS build/index.d.ts 103.00 B
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
> @silkweave/cli@1.3.0 check /Users/atomic/projects/ai/silkweave/packages/cli
|
|
4
|
+
> pnpm lint && pnpm typecheck
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
> @silkweave/cli@1.3.0 lint /Users/atomic/projects/ai/silkweave/packages/cli
|
|
8
|
+
> eslint
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
> @silkweave/cli@1.3.0 typecheck /Users/atomic/projects/ai/silkweave/packages/cli
|
|
12
|
+
> tsc --noEmit
|
|
13
|
+
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
> @silkweave/cli@1.3.0 prepack /Users/atomic/projects/ai/mcphero/packages/cli
|
|
4
|
+
> pnpm clean && pnpm build
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
> @silkweave/cli@1.3.0 clean /Users/atomic/projects/ai/mcphero/packages/cli
|
|
8
|
+
> rimraf build
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
> @silkweave/cli@1.3.0 build /Users/atomic/projects/ai/mcphero/packages/cli
|
|
12
|
+
> tsup
|
|
13
|
+
|
|
14
|
+
[34mCLI[39m Building entry: src/index.ts
|
|
15
|
+
[34mCLI[39m Using tsconfig: tsconfig.json
|
|
16
|
+
[34mCLI[39m tsup v8.5.1
|
|
17
|
+
[34mCLI[39m Using tsup config: /Users/atomic/projects/ai/mcphero/packages/cli/tsup.config.ts
|
|
18
|
+
[34mCLI[39m Target: es2022
|
|
19
|
+
[34mCLI[39m Cleaning output folder
|
|
20
|
+
[34mESM[39m Build start
|
|
21
|
+
[32mESM[39m [1mbuild/index.js [22m[32m3.19 KB[39m
|
|
22
|
+
[32mESM[39m [1mbuild/index.js.map [22m[32m5.64 KB[39m
|
|
23
|
+
[32mESM[39m ⚡️ Build success in 9ms
|
|
24
|
+
DTS Build start
|
|
25
|
+
DTS ⚡️ Build success in 613ms
|
|
26
|
+
DTS build/index.d.ts 103.00 B
|
package/README.md
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# @silkweave/cli
|
|
2
|
+
|
|
3
|
+
CLI adapter for [Silkweave](https://github.com/atomicbi/silkweave) — turn your actions into a complete command-line application with help text, option parsing, and styled terminal output via clack.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pnpm add @silkweave/core @silkweave/cli
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
```typescript
|
|
14
|
+
import { silkweave } from '@silkweave/core'
|
|
15
|
+
import { cli } from '@silkweave/cli'
|
|
16
|
+
import { GreetAction } from './actions/greet.js'
|
|
17
|
+
|
|
18
|
+
await silkweave({ name: 'mytool', description: 'My CLI Tool', version: '1.0.0' })
|
|
19
|
+
.adapter(cli())
|
|
20
|
+
.action(GreetAction)
|
|
21
|
+
.start()
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
$ mytool greet --name "World" --enthusiastic
|
|
26
|
+
◇ mytool - greet
|
|
27
|
+
ℹ HELLO, WORLD!!!
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## How Zod Types Map to CLI Options
|
|
31
|
+
|
|
32
|
+
| Zod Type | CLI Representation |
|
|
33
|
+
|----------|-------------------|
|
|
34
|
+
| `z.string()` | `--option-name <string>` |
|
|
35
|
+
| `z.number()` | `--option-name <number>` |
|
|
36
|
+
| `z.boolean()` | `--option-name` / `--no-option-name` |
|
|
37
|
+
| `z.enum([...])` | `--option-name <choice>` with choices validation |
|
|
38
|
+
| `z.record()` | `--option-name <json>` |
|
|
39
|
+
| `.default(value)` | Sets the default in help text |
|
|
40
|
+
| `.describe('...')` | Sets the option description |
|
|
41
|
+
|
|
42
|
+
Field names are automatically converted to `kebab-case`. Action names become subcommands.
|
|
43
|
+
|
|
44
|
+
## Positional Arguments
|
|
45
|
+
|
|
46
|
+
Use the `args` property on an action to promote fields to positional arguments:
|
|
47
|
+
|
|
48
|
+
```typescript
|
|
49
|
+
const DeployAction = createAction({
|
|
50
|
+
name: 'deploy',
|
|
51
|
+
input: z.object({
|
|
52
|
+
environment: z.string(),
|
|
53
|
+
dryRun: z.boolean().default(false)
|
|
54
|
+
}),
|
|
55
|
+
args: ['environment'],
|
|
56
|
+
// ...
|
|
57
|
+
})
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
```
|
|
61
|
+
$ mytool deploy production --dry-run
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## See Also
|
|
65
|
+
|
|
66
|
+
- [Silkweave README](https://github.com/atomicbi/silkweave) — Full documentation
|
|
67
|
+
- [`@silkweave/core`](https://www.npmjs.com/package/@silkweave/core) — Core library
|
package/build/index.d.ts
ADDED
package/build/index.js
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
// src/adapter/cli.ts
|
|
2
|
+
import { intro, log } from "@clack/prompts";
|
|
3
|
+
import { unwrap } from "@silkweave/core";
|
|
4
|
+
import { createCLILogger } from "@silkweave/logger";
|
|
5
|
+
import { camelCase, kebabCase } from "change-case";
|
|
6
|
+
import { Command } from "commander";
|
|
7
|
+
import z from "zod";
|
|
8
|
+
function handleCLIError(error) {
|
|
9
|
+
if (error instanceof z.ZodError) {
|
|
10
|
+
log.error("Validation Error", { withGuide: false });
|
|
11
|
+
for (const issue of error.issues) {
|
|
12
|
+
log.error(`${issue.path}: ${issue.message}`);
|
|
13
|
+
}
|
|
14
|
+
} else if (error instanceof Error) {
|
|
15
|
+
log.error(error.message);
|
|
16
|
+
} else if (typeof error === "string") {
|
|
17
|
+
log.error(error);
|
|
18
|
+
} else {
|
|
19
|
+
log.error(JSON.stringify(error));
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
function parseCLIInput(action, args) {
|
|
23
|
+
const tmpArgs = args.slice(0, -1);
|
|
24
|
+
const rawInput = tmpArgs.pop();
|
|
25
|
+
action.args?.forEach((k, index) => {
|
|
26
|
+
rawInput[k] = args[index];
|
|
27
|
+
});
|
|
28
|
+
const { error, data } = action.input.safeParse(rawInput);
|
|
29
|
+
if (error || !data) {
|
|
30
|
+
handleCLIError(error);
|
|
31
|
+
process.exit();
|
|
32
|
+
}
|
|
33
|
+
return data;
|
|
34
|
+
}
|
|
35
|
+
var cli = () => {
|
|
36
|
+
return (options, baseContext) => {
|
|
37
|
+
const context = baseContext.fork({ adapter: "cli" });
|
|
38
|
+
const program = new Command().name(options.name).description(options.description).version(options.version);
|
|
39
|
+
return {
|
|
40
|
+
context,
|
|
41
|
+
start: async (actions) => {
|
|
42
|
+
for (const action of actions) {
|
|
43
|
+
const name = kebabCase(action.name);
|
|
44
|
+
const command = program.command(name).description(action.description);
|
|
45
|
+
const shape = action.input.shape;
|
|
46
|
+
const keys = Object.keys(shape);
|
|
47
|
+
for (const key of keys) {
|
|
48
|
+
const [type, { defaultValue }] = unwrap(shape[key]);
|
|
49
|
+
const description = type.description;
|
|
50
|
+
const isArgument = action.args?.includes(key);
|
|
51
|
+
if (isArgument) {
|
|
52
|
+
command.argument(`[${camelCase(key)}]`, description, defaultValue);
|
|
53
|
+
} else if (type instanceof z.ZodBoolean) {
|
|
54
|
+
command.option(`--${kebabCase(key)}`, description, defaultValue);
|
|
55
|
+
command.option(`--no-${kebabCase(key)}`);
|
|
56
|
+
} else if (type instanceof z.ZodNumber) {
|
|
57
|
+
command.option(`--${kebabCase(key)} <number>`, description, defaultValue);
|
|
58
|
+
} else if (type instanceof z.ZodString || type instanceof z.ZodEnum) {
|
|
59
|
+
command.option(`--${kebabCase(key)} <string>`, description, defaultValue);
|
|
60
|
+
} else if (type instanceof z.ZodObject || type instanceof z.ZodRecord || type instanceof z.ZodArray) {
|
|
61
|
+
command.option(`--${kebabCase(key)} <json>`, description ?? "", JSON.parse, defaultValue);
|
|
62
|
+
} else {
|
|
63
|
+
throw new Error(`Invalid zod type: ${type.def.type}`);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
command.action((...args) => {
|
|
67
|
+
const logger = createCLILogger();
|
|
68
|
+
const input = parseCLIInput(action, args);
|
|
69
|
+
intro(`${options.name} - ${action.name}`);
|
|
70
|
+
action.run(input, context.fork({ logger, command })).then((result) => {
|
|
71
|
+
logger.info(JSON.stringify(result, null, 2));
|
|
72
|
+
}).catch(handleCLIError);
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
program.parse();
|
|
76
|
+
},
|
|
77
|
+
stop: async () => {
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
};
|
|
81
|
+
};
|
|
82
|
+
export {
|
|
83
|
+
cli
|
|
84
|
+
};
|
|
85
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/adapter/cli.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { intro, log } from '@clack/prompts'\nimport { Action, AdapterFactory, unwrap } from '@silkweave/core'\nimport { createCLILogger } from '@silkweave/logger'\nimport { camelCase, kebabCase } from 'change-case'\nimport { Command } from 'commander'\nimport z from 'zod'\n\nfunction handleCLIError(error: unknown) {\n if (error instanceof z.ZodError) {\n log.error('Validation Error', { withGuide: false })\n for (const issue of error.issues) {\n log.error(`${issue.path}: ${issue.message}`)\n }\n } else if (error instanceof Error) {\n log.error(error.message)\n } else if (typeof error === 'string') {\n log.error(error)\n } else {\n log.error(JSON.stringify(error))\n }\n}\n\nfunction parseCLIInput(action: Action, args: any[]) {\n const tmpArgs = args.slice(0, -1)\n const rawInput = tmpArgs.pop()\n action.args?.forEach((k, index) => { rawInput[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\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 const name = kebabCase(action.name)\n const command = program.command(name).description(action.description)\n const shape = action.input.shape\n const keys = Object.keys(shape)\n for (const key of keys) {\n const [type, { defaultValue }] = unwrap(shape[key])\n const description = type.description\n const isArgument = action.args?.includes(key)\n if (isArgument) {\n command.argument(`[${camelCase(key)}]`, description, defaultValue)\n } else if (type instanceof z.ZodBoolean) {\n command.option(`--${kebabCase(key)}`, description, defaultValue)\n command.option(`--no-${kebabCase(key)}`)\n } else if (type instanceof z.ZodNumber) {\n command.option(`--${kebabCase(key)} <number>`, description, defaultValue)\n } else if (type instanceof z.ZodString || type instanceof z.ZodEnum) {\n command.option(`--${kebabCase(key)} <string>`, description, defaultValue)\n } else if (type instanceof z.ZodObject || type instanceof z.ZodRecord || type instanceof z.ZodArray) {\n command.option(`--${kebabCase(key)} <json>`, description ?? '', JSON.parse, defaultValue)\n } else {\n throw new Error(`Invalid zod type: ${type.def.type}`)\n }\n }\n command.action((...args) => {\n const logger = createCLILogger()\n const input = parseCLIInput(action, args)\n intro(`${options.name} - ${action.name}`)\n action.run(input, context.fork({ logger, command })).then((result) => {\n logger.info(JSON.stringify(result, null, 2))\n }).catch(handleCLIError)\n })\n }\n program.parse()\n },\n stop: async () => { }\n }\n }\n}\n"],"mappings":"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","names":[]}
|
package/package.json
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@silkweave/cli",
|
|
3
|
+
"version": "1.3.0",
|
|
4
|
+
"description": "Silkweave CLI Adapter",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "git+ssh://git@github.com/atomicbi/silkweave.git",
|
|
8
|
+
"directory": "packages/cli"
|
|
9
|
+
},
|
|
10
|
+
"type": "module",
|
|
11
|
+
"main": "build/index.js",
|
|
12
|
+
"types": "build/index.d.ts",
|
|
13
|
+
"dependencies": {
|
|
14
|
+
"@clack/prompts": "^1.0.1",
|
|
15
|
+
"change-case": "^5.4.4",
|
|
16
|
+
"commander": "^13.1.0",
|
|
17
|
+
"zod": "^4.3.6",
|
|
18
|
+
"@silkweave/core": "1.3.0",
|
|
19
|
+
"@silkweave/logger": "1.3.0"
|
|
20
|
+
},
|
|
21
|
+
"devDependencies": {
|
|
22
|
+
"@eslint/js": "^10.0.1",
|
|
23
|
+
"@stylistic/eslint-plugin": "^5.10.0",
|
|
24
|
+
"@types/node": "^22.0.0",
|
|
25
|
+
"rimraf": "^6.1.3",
|
|
26
|
+
"tsup": "^8.5.1",
|
|
27
|
+
"tsx": "^4.21.0",
|
|
28
|
+
"typescript": "^5.9.3",
|
|
29
|
+
"typescript-eslint": "^8.56.1"
|
|
30
|
+
},
|
|
31
|
+
"scripts": {
|
|
32
|
+
"clean": "rimraf build",
|
|
33
|
+
"build": "tsup",
|
|
34
|
+
"watch": "tsup --watch",
|
|
35
|
+
"typecheck": "tsc --noEmit",
|
|
36
|
+
"lint": "eslint",
|
|
37
|
+
"check": "pnpm lint && pnpm typecheck"
|
|
38
|
+
}
|
|
39
|
+
}
|