goke 6.6.0 → 6.6.2
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 +142 -2
- package/dist/coerce.d.ts +25 -3
- package/dist/coerce.d.ts.map +1 -1
- package/dist/coerce.js +24 -2
- package/package.json +1 -1
- package/src/coerce.ts +27 -3
package/README.md
CHANGED
|
@@ -654,6 +654,60 @@ When using brackets in option name, angled brackets indicate that a string / num
|
|
|
654
654
|
|
|
655
655
|
**Optionality is determined solely by bracket syntax, not by the schema.** `[square brackets]` makes an option optional regardless of whether the schema is `z.string()` or `z.string().optional()`. The schema's `.optional()` is never consulted for this — it only affects type coercion. This means `z.string()` with `[--name]` is treated as optional: if the flag is omitted, `options.name` is `undefined` even though the schema has no `.optional()`.
|
|
656
656
|
|
|
657
|
+
### Optional-value flags — `--flag` vs `--flag value` vs omitted
|
|
658
|
+
|
|
659
|
+
A flag declared with square brackets (`--host [host]`) has **three distinct runtime states**, not two. The user can:
|
|
660
|
+
|
|
661
|
+
1. **Omit the flag entirely** — no `--host` on the command line at all
|
|
662
|
+
2. **Pass the flag bare** — `--host` by itself, with no value following it
|
|
663
|
+
3. **Pass the flag with a value** — `--host example.com`
|
|
664
|
+
|
|
665
|
+
goke surfaces all three cases through a single `string | undefined` type. There is no `boolean` in the union — bare flags are normalized to the **empty string `''`** so callers only ever deal with strings:
|
|
666
|
+
|
|
667
|
+
```ts
|
|
668
|
+
cli
|
|
669
|
+
.command('serve', 'Start the server')
|
|
670
|
+
.option('--host [host]', 'Optional host override')
|
|
671
|
+
.action((options) => {
|
|
672
|
+
// options.host: string | undefined
|
|
673
|
+
// --host → '' (flag present, no value)
|
|
674
|
+
// --host example.com → 'example.com'
|
|
675
|
+
// (omitted) → undefined
|
|
676
|
+
})
|
|
677
|
+
```
|
|
678
|
+
|
|
679
|
+
**Detecting each case:**
|
|
680
|
+
|
|
681
|
+
```ts
|
|
682
|
+
.action((options) => {
|
|
683
|
+
if (options.host === undefined) {
|
|
684
|
+
// Flag was not passed at all — use a sensible default
|
|
685
|
+
console.log('using default host: localhost')
|
|
686
|
+
} else if (options.host === '') {
|
|
687
|
+
// Flag was passed bare: `--host` with no value following it
|
|
688
|
+
// Treat this as an explicit "opt in, but use the default/automatic value"
|
|
689
|
+
console.log('host flag passed with no value — enabling auto-discovery')
|
|
690
|
+
} else {
|
|
691
|
+
// Flag was passed with an explicit value
|
|
692
|
+
console.log(`host = ${options.host}`)
|
|
693
|
+
}
|
|
694
|
+
})
|
|
695
|
+
```
|
|
696
|
+
|
|
697
|
+
**In most cases you don't need the three-way distinction** — a plain truthy check collapses "omitted" and "bare flag" into the same "fall back to default" branch:
|
|
698
|
+
|
|
699
|
+
```ts
|
|
700
|
+
.action((options) => {
|
|
701
|
+
// `--host` bare AND omitted both fall through to the default
|
|
702
|
+
const host = options.host || 'localhost'
|
|
703
|
+
startServer({ host })
|
|
704
|
+
})
|
|
705
|
+
```
|
|
706
|
+
|
|
707
|
+
Reserve the `=== ''` check for cases where "opt in without a value" is a meaningful signal distinct from "flag omitted" — for example, `--direct` meaning "auto-discover a Chrome instance" vs `--direct ws://…` meaning "connect to this specific endpoint" vs no `--direct` meaning "don't use direct mode".
|
|
708
|
+
|
|
709
|
+
> **Breaking change note (goke 6.6.0):** prior versions surfaced bare flags as `boolean` `true` inside a `string | boolean | undefined` union, forcing every call site to write `typeof options.host === 'string' ? options.host : undefined`. Code that used `options.host === true` to detect the bare-flag case must be updated to `options.host === ''`. Schema-based optional flags with `.default(...)` are unaffected — the default still kicks in when the flag is passed bare.
|
|
710
|
+
|
|
657
711
|
### Negated Options
|
|
658
712
|
|
|
659
713
|
To allow an option whose value is `false`, you need to manually specify a negated option:
|
|
@@ -684,6 +738,8 @@ cli
|
|
|
684
738
|
|
|
685
739
|
The `--` token signals the end of options. Everything after `--` is available via `options['--']` as a separate array, not mixed into positional args. This lets you distinguish between your command's own arguments and passthrough args — the same pattern used by `doppler`, `npm`, `pnpm`, and `docker`.
|
|
686
740
|
|
|
741
|
+
`options['--']` is **always present** on the inferred options type as `string[]`. When no `--` token appears on the command line, it's the empty array — you never need to guard with `||` or `?.` or an `Array.isArray` cast.
|
|
742
|
+
|
|
687
743
|
```ts
|
|
688
744
|
import { goke } from 'goke'
|
|
689
745
|
import { z } from 'zod'
|
|
@@ -700,10 +756,10 @@ cli
|
|
|
700
756
|
// runner run --env staging server.js -- --port 3000 --verbose
|
|
701
757
|
// script = 'server.js' (positional arg)
|
|
702
758
|
// options.env = 'staging' (runner's own option)
|
|
703
|
-
// options['--'] = ['--port', '3000', '--verbose'] (passthrough)
|
|
759
|
+
// options['--'] = ['--port', '3000', '--verbose'] (passthrough, always string[])
|
|
704
760
|
|
|
705
761
|
const secrets = loadSecrets(options.env)
|
|
706
|
-
const extraArgs =
|
|
762
|
+
const extraArgs = options['--'].join(' ')
|
|
707
763
|
execSync(`node ${script} ${extraArgs}`, {
|
|
708
764
|
env: { ...process.env, ...secrets },
|
|
709
765
|
stdio: 'inherit',
|
|
@@ -915,6 +971,90 @@ Always run `acme --help` before using this CLI.
|
|
|
915
971
|
For subcommand details: `acme <command> --help`
|
|
916
972
|
````
|
|
917
973
|
|
|
974
|
+
## YAML Output for Agent-Friendly CLIs
|
|
975
|
+
|
|
976
|
+
When a command returns structured data, print it as YAML on stdout. YAML is the best middle ground between human-readable output and machine-processable output:
|
|
977
|
+
|
|
978
|
+
- Humans can read it at a glance — no surrounding quotes on keys, less punctuation noise than JSON.
|
|
979
|
+
- Agents can process it with [`yq`](https://github.com/mikefarah/yq), the YAML equivalent of `jq`, to extract specific fields or filter results.
|
|
980
|
+
- It is more context-efficient than verbose prose: a compact YAML block conveys the same information in fewer tokens.
|
|
981
|
+
|
|
982
|
+
```ts
|
|
983
|
+
import { goke } from 'goke'
|
|
984
|
+
import { stringify } from 'yaml'
|
|
985
|
+
|
|
986
|
+
const cli = goke('deploy')
|
|
987
|
+
|
|
988
|
+
cli
|
|
989
|
+
.command('status', 'Show deployment status')
|
|
990
|
+
.action(async (options, { console }) => {
|
|
991
|
+
const status = await fetchStatus()
|
|
992
|
+
// Output structured data as YAML on stdout
|
|
993
|
+
console.log(stringify(status))
|
|
994
|
+
})
|
|
995
|
+
```
|
|
996
|
+
|
|
997
|
+
Example output:
|
|
998
|
+
|
|
999
|
+
```yaml
|
|
1000
|
+
deployment: prod-v2
|
|
1001
|
+
status: running
|
|
1002
|
+
replicas: 3
|
|
1003
|
+
lastDeploy: "2026-01-15T10:30:00Z"
|
|
1004
|
+
health:
|
|
1005
|
+
cpu: 42%
|
|
1006
|
+
memory: 1.2GB
|
|
1007
|
+
```
|
|
1008
|
+
|
|
1009
|
+
### Processing YAML output with yq
|
|
1010
|
+
|
|
1011
|
+
Agents can pipe the output through `yq` to extract specific fields or filter results — the same way they would use `jq` with JSON, but with cleaner, more readable output:
|
|
1012
|
+
|
|
1013
|
+
```bash
|
|
1014
|
+
# Extract a single field
|
|
1015
|
+
deploy status | yq '.deployment'
|
|
1016
|
+
|
|
1017
|
+
# Access nested fields
|
|
1018
|
+
deploy status | yq '.health.cpu'
|
|
1019
|
+
|
|
1020
|
+
# Filter an array of results
|
|
1021
|
+
deploy list | yq '.[] | select(.status == "running")'
|
|
1022
|
+
|
|
1023
|
+
# Combine multiple fields
|
|
1024
|
+
deploy list | yq '.[] | {name: .name, status: .status}'
|
|
1025
|
+
|
|
1026
|
+
# Count items matching a condition
|
|
1027
|
+
deploy list | yq '[.[] | select(.status == "error")] | length'
|
|
1028
|
+
```
|
|
1029
|
+
|
|
1030
|
+
### Keep stdout clean — send non-YAML to stderr
|
|
1031
|
+
|
|
1032
|
+
If a command outputs YAML on stdout, all unrelated content must go to stderr: error messages, progress indicators, informational logs, warnings. This keeps stdout pipeable through `yq` without breaking the YAML parse.
|
|
1033
|
+
|
|
1034
|
+
```ts
|
|
1035
|
+
cli
|
|
1036
|
+
.command('deploy <env>', 'Deploy to environment')
|
|
1037
|
+
.action(async (env, options, { console }) => {
|
|
1038
|
+
// Progress and logs → stderr (won't pollute yq pipes)
|
|
1039
|
+
console.error(`Deploying to ${env}...`)
|
|
1040
|
+
console.error('Building artifacts...')
|
|
1041
|
+
|
|
1042
|
+
const result = await deploy(env)
|
|
1043
|
+
|
|
1044
|
+
// Structured result → stdout as YAML
|
|
1045
|
+
console.log(stringify(result))
|
|
1046
|
+
})
|
|
1047
|
+
```
|
|
1048
|
+
|
|
1049
|
+
Now agents can process the output cleanly:
|
|
1050
|
+
|
|
1051
|
+
```bash
|
|
1052
|
+
# Only the YAML result reaches yq — progress lines go to the terminal
|
|
1053
|
+
deploy deploy production | yq '.version'
|
|
1054
|
+
```
|
|
1055
|
+
|
|
1056
|
+
If an error occurs, throw or write to `console.error` / `process.stderr`, and exit with a non-zero code. Never mix error text into stdout when the command is expected to output YAML.
|
|
1057
|
+
|
|
918
1058
|
## Contributor Notes
|
|
919
1059
|
|
|
920
1060
|
### Rules
|
package/dist/coerce.d.ts
CHANGED
|
@@ -78,13 +78,35 @@ export declare namespace StandardJSONSchemaV1 {
|
|
|
78
78
|
/**
|
|
79
79
|
* Wraps a plain JSON Schema object into a StandardJSONSchemaV1-compatible object.
|
|
80
80
|
*
|
|
81
|
-
*
|
|
82
|
-
*
|
|
81
|
+
* Originally built for @goke/mcp to wrap MCP tool schemas, but also useful for
|
|
82
|
+
* any consumer that has a hand-written JSON Schema (e.g. an array of strings
|
|
83
|
+
* or a tagged union) and wants goke's `.action()` callback to infer the right
|
|
84
|
+
* option type without reaching for Zod. Pass an explicit `Output` type
|
|
85
|
+
* parameter to tell TypeScript what the coerced value will look like at
|
|
86
|
+
* runtime — goke does not validate the output shape, it just propagates it
|
|
87
|
+
* into the inferred options type for `.action()` callbacks.
|
|
88
|
+
*
|
|
89
|
+
* @example
|
|
90
|
+
* ```ts
|
|
91
|
+
* cli
|
|
92
|
+
* .command('diff', 'Show diff')
|
|
93
|
+
* .option(
|
|
94
|
+
* '--filter <glob>',
|
|
95
|
+
* wrapJsonSchema<string[]>({
|
|
96
|
+
* type: 'array',
|
|
97
|
+
* items: { type: 'string' },
|
|
98
|
+
* description: 'Glob pattern (repeatable)',
|
|
99
|
+
* }),
|
|
100
|
+
* )
|
|
101
|
+
* .action((options) => {
|
|
102
|
+
* // options.filter: string[] | undefined
|
|
103
|
+
* })
|
|
104
|
+
* ```
|
|
83
105
|
*
|
|
84
106
|
* @param jsonSchema - A plain JSON Schema object (e.g. `{ type: "number" }`)
|
|
85
107
|
* @returns A StandardJSONSchemaV1-compatible object that Goke can use for coercion
|
|
86
108
|
*/
|
|
87
|
-
export declare function wrapJsonSchema(jsonSchema: Record<string, unknown>): StandardJSONSchemaV1
|
|
109
|
+
export declare function wrapJsonSchema<Output = unknown>(jsonSchema: Record<string, unknown>): StandardJSONSchemaV1<unknown, Output>;
|
|
88
110
|
/** Minimal JSON Schema interface — only what we need for CLI coercion. */
|
|
89
111
|
export interface JsonSchema {
|
|
90
112
|
type?: string | string[];
|
package/dist/coerce.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"coerce.d.ts","sourceRoot":"","sources":["../src/coerce.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAIH;;;;GAIG;AACH,qBAAa,SAAU,SAAQ,KAAK;gBACtB,OAAO,EAAE,MAAM;CAS5B;AASD,uEAAuE;AACvE,MAAM,WAAW,eAAe,CAAC,KAAK,GAAG,OAAO,EAAE,MAAM,GAAG,KAAK;IAC9D,QAAQ,CAAC,WAAW,EAAE,eAAe,CAAC,KAAK,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;CAC5D;AAED,MAAM,CAAC,OAAO,WAAW,eAAe,CAAC;IACvC,UAAiB,KAAK,CAAC,KAAK,GAAG,OAAO,EAAE,MAAM,GAAG,KAAK;QACpD,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC;QACpB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;QACxB,QAAQ,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC,KAAK,EAAE,MAAM,CAAC,GAAG,SAAS,CAAC;KACnD;IAED,UAAiB,KAAK,CAAC,KAAK,GAAG,OAAO,EAAE,MAAM,GAAG,KAAK;QACpD,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;QACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;KACzB;IAED,KAAY,UAAU,CAAC,MAAM,SAAS,eAAe,IAAI,WAAW,CAClE,MAAM,CAAC,WAAW,CAAC,CAAC,OAAO,CAAC,CAC7B,CAAC,OAAO,CAAC,CAAC;IAEX,KAAY,WAAW,CAAC,MAAM,SAAS,eAAe,IAAI,WAAW,CACnE,MAAM,CAAC,WAAW,CAAC,CAAC,OAAO,CAAC,CAC7B,CAAC,QAAQ,CAAC,CAAC;CACb;AAED,0CAA0C;AAC1C,MAAM,WAAW,oBAAoB,CAAC,KAAK,GAAG,OAAO,EAAE,MAAM,GAAG,KAAK;IACnE,QAAQ,CAAC,WAAW,EAAE,oBAAoB,CAAC,KAAK,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;CACjE;AAED,MAAM,CAAC,OAAO,WAAW,oBAAoB,CAAC;IAC5C,UAAiB,KAAK,CAAC,KAAK,GAAG,OAAO,EAAE,MAAM,GAAG,KAAK,CACpD,SAAQ,eAAe,CAAC,KAAK,CAAC,KAAK,EAAE,MAAM,CAAC;QAC5C,QAAQ,CAAC,UAAU,EAAE,oBAAoB,CAAC,SAAS,CAAC;KACrD;IAED,UAAiB,SAAS;QACxB,QAAQ,CAAC,KAAK,EAAE,CACd,OAAO,EAAE,oBAAoB,CAAC,OAAO,KAClC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAC7B,QAAQ,CAAC,MAAM,EAAE,CACf,OAAO,EAAE,oBAAoB,CAAC,OAAO,KAClC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;KAC9B;IAED,KAAY,MAAM,GACd,eAAe,GACf,UAAU,GACV,aAAa,GACb,CAAC,EAAE,GAAG,MAAM,CAAC,CAAC;IAElB,UAAiB,OAAO;QACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;QACxB,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC;KAC/D;IAED,UAAiB,KAAK,CAAC,KAAK,GAAG,OAAO,EAAE,MAAM,GAAG,KAAK,CACpD,SAAQ,eAAe,CAAC,KAAK,CAAC,KAAK,EAAE,MAAM,CAAC;KAAG;IAEjD,KAAY,UAAU,CAAC,MAAM,SAAS,eAAe,IACnD,eAAe,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;IAErC,KAAY,WAAW,CAAC,MAAM,SAAS,eAAe,IACpD,eAAe,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;CACvC;AAID
|
|
1
|
+
{"version":3,"file":"coerce.d.ts","sourceRoot":"","sources":["../src/coerce.ts"],"names":[],"mappings":"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"}
|
package/dist/coerce.js
CHANGED
|
@@ -50,8 +50,30 @@ export class GokeError extends Error {
|
|
|
50
50
|
/**
|
|
51
51
|
* Wraps a plain JSON Schema object into a StandardJSONSchemaV1-compatible object.
|
|
52
52
|
*
|
|
53
|
-
*
|
|
54
|
-
*
|
|
53
|
+
* Originally built for @goke/mcp to wrap MCP tool schemas, but also useful for
|
|
54
|
+
* any consumer that has a hand-written JSON Schema (e.g. an array of strings
|
|
55
|
+
* or a tagged union) and wants goke's `.action()` callback to infer the right
|
|
56
|
+
* option type without reaching for Zod. Pass an explicit `Output` type
|
|
57
|
+
* parameter to tell TypeScript what the coerced value will look like at
|
|
58
|
+
* runtime — goke does not validate the output shape, it just propagates it
|
|
59
|
+
* into the inferred options type for `.action()` callbacks.
|
|
60
|
+
*
|
|
61
|
+
* @example
|
|
62
|
+
* ```ts
|
|
63
|
+
* cli
|
|
64
|
+
* .command('diff', 'Show diff')
|
|
65
|
+
* .option(
|
|
66
|
+
* '--filter <glob>',
|
|
67
|
+
* wrapJsonSchema<string[]>({
|
|
68
|
+
* type: 'array',
|
|
69
|
+
* items: { type: 'string' },
|
|
70
|
+
* description: 'Glob pattern (repeatable)',
|
|
71
|
+
* }),
|
|
72
|
+
* )
|
|
73
|
+
* .action((options) => {
|
|
74
|
+
* // options.filter: string[] | undefined
|
|
75
|
+
* })
|
|
76
|
+
* ```
|
|
55
77
|
*
|
|
56
78
|
* @param jsonSchema - A plain JSON Schema object (e.g. `{ type: "number" }`)
|
|
57
79
|
* @returns A StandardJSONSchemaV1-compatible object that Goke can use for coercion
|
package/package.json
CHANGED
package/src/coerce.ts
CHANGED
|
@@ -127,13 +127,37 @@ export declare namespace StandardJSONSchemaV1 {
|
|
|
127
127
|
/**
|
|
128
128
|
* Wraps a plain JSON Schema object into a StandardJSONSchemaV1-compatible object.
|
|
129
129
|
*
|
|
130
|
-
*
|
|
131
|
-
*
|
|
130
|
+
* Originally built for @goke/mcp to wrap MCP tool schemas, but also useful for
|
|
131
|
+
* any consumer that has a hand-written JSON Schema (e.g. an array of strings
|
|
132
|
+
* or a tagged union) and wants goke's `.action()` callback to infer the right
|
|
133
|
+
* option type without reaching for Zod. Pass an explicit `Output` type
|
|
134
|
+
* parameter to tell TypeScript what the coerced value will look like at
|
|
135
|
+
* runtime — goke does not validate the output shape, it just propagates it
|
|
136
|
+
* into the inferred options type for `.action()` callbacks.
|
|
137
|
+
*
|
|
138
|
+
* @example
|
|
139
|
+
* ```ts
|
|
140
|
+
* cli
|
|
141
|
+
* .command('diff', 'Show diff')
|
|
142
|
+
* .option(
|
|
143
|
+
* '--filter <glob>',
|
|
144
|
+
* wrapJsonSchema<string[]>({
|
|
145
|
+
* type: 'array',
|
|
146
|
+
* items: { type: 'string' },
|
|
147
|
+
* description: 'Glob pattern (repeatable)',
|
|
148
|
+
* }),
|
|
149
|
+
* )
|
|
150
|
+
* .action((options) => {
|
|
151
|
+
* // options.filter: string[] | undefined
|
|
152
|
+
* })
|
|
153
|
+
* ```
|
|
132
154
|
*
|
|
133
155
|
* @param jsonSchema - A plain JSON Schema object (e.g. `{ type: "number" }`)
|
|
134
156
|
* @returns A StandardJSONSchemaV1-compatible object that Goke can use for coercion
|
|
135
157
|
*/
|
|
136
|
-
export function wrapJsonSchema
|
|
158
|
+
export function wrapJsonSchema<Output = unknown>(
|
|
159
|
+
jsonSchema: Record<string, unknown>,
|
|
160
|
+
): StandardJSONSchemaV1<unknown, Output> {
|
|
137
161
|
return {
|
|
138
162
|
"~standard": {
|
|
139
163
|
version: 1,
|