incur 0.3.4 → 0.3.6
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 +62 -1
- package/dist/Cli.d.ts +17 -7
- package/dist/Cli.d.ts.map +1 -1
- package/dist/Cli.js +435 -365
- package/dist/Cli.js.map +1 -1
- package/dist/Completions.d.ts +1 -2
- package/dist/Completions.d.ts.map +1 -1
- package/dist/Completions.js.map +1 -1
- package/dist/Filter.js +0 -18
- package/dist/Filter.js.map +1 -1
- package/dist/Help.d.ts +6 -0
- package/dist/Help.d.ts.map +1 -1
- package/dist/Help.js +35 -22
- package/dist/Help.js.map +1 -1
- package/dist/Mcp.d.ts +25 -5
- package/dist/Mcp.d.ts.map +1 -1
- package/dist/Mcp.js +61 -69
- package/dist/Mcp.js.map +1 -1
- package/dist/Parser.d.ts +2 -0
- package/dist/Parser.d.ts.map +1 -1
- package/dist/Parser.js +69 -37
- package/dist/Parser.js.map +1 -1
- package/dist/Skill.d.ts.map +1 -1
- package/dist/Skill.js +5 -1
- package/dist/Skill.js.map +1 -1
- package/dist/SyncSkills.d.ts.map +1 -1
- package/dist/SyncSkills.js +10 -1
- package/dist/SyncSkills.js.map +1 -1
- package/dist/bin.d.ts +1 -0
- package/dist/bin.d.ts.map +1 -1
- package/dist/bin.js +17 -2
- package/dist/bin.js.map +1 -1
- package/dist/internal/command.d.ts +118 -0
- package/dist/internal/command.d.ts.map +1 -0
- package/dist/internal/command.js +276 -0
- package/dist/internal/command.js.map +1 -0
- package/dist/internal/configSchema.d.ts +8 -0
- package/dist/internal/configSchema.d.ts.map +1 -0
- package/dist/internal/configSchema.js +57 -0
- package/dist/internal/configSchema.js.map +1 -0
- package/dist/internal/helpers.d.ts +5 -0
- package/dist/internal/helpers.d.ts.map +1 -0
- package/dist/internal/helpers.js +9 -0
- package/dist/internal/helpers.js.map +1 -0
- package/examples/npm/.npmrc.json +21 -0
- package/examples/npm/config.schema.json +137 -0
- package/package.json +1 -1
- package/src/Cli.test-d.ts +39 -0
- package/src/Cli.test.ts +704 -6
- package/src/Cli.ts +551 -448
- package/src/Completions.test.ts +35 -9
- package/src/Completions.ts +1 -2
- package/src/Filter.ts +0 -17
- package/src/Help.test.ts +77 -0
- package/src/Help.ts +39 -21
- package/src/Mcp.test.ts +143 -0
- package/src/Mcp.ts +92 -84
- package/src/Parser.test-d.ts +22 -0
- package/src/Parser.test.ts +89 -0
- package/src/Parser.ts +86 -35
- package/src/Skill.ts +5 -1
- package/src/SyncSkills.ts +11 -1
- package/src/bin.ts +21 -2
- package/src/e2e.test.ts +30 -17
- package/src/internal/command.ts +428 -0
- package/src/internal/configSchema.test.ts +193 -0
- package/src/internal/configSchema.ts +66 -0
- package/src/internal/helpers.ts +9 -0
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import fs from 'node:fs/promises'
|
|
2
|
+
import type { z } from 'zod'
|
|
3
|
+
|
|
4
|
+
import * as Cli from '../Cli.js'
|
|
5
|
+
import * as Schema from '../Schema.js'
|
|
6
|
+
import { importCli } from './utils.js'
|
|
7
|
+
|
|
8
|
+
/** Returns `true` if the CLI has `config` enabled on `Cli.create()`. */
|
|
9
|
+
export function hasConfig(cli: Cli.Cli): boolean {
|
|
10
|
+
return Cli.toConfigEnabled.get(cli) === true
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/** Imports a CLI from `input` (must `export default` a `Cli`), generates the JSON Schema, and writes it to `output`. */
|
|
14
|
+
export async function generate(input: string, output: string): Promise<void> {
|
|
15
|
+
const cli = await importCli(input)
|
|
16
|
+
await fs.writeFile(output, JSON.stringify(fromCli(cli), null, 2) + '\n')
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/** Generates a JSON Schema describing the config file structure for a CLI. */
|
|
20
|
+
export function fromCli(cli: Cli.Cli): Record<string, unknown> {
|
|
21
|
+
const commands = Cli.toCommands.get(cli)
|
|
22
|
+
if (!commands) return { type: 'object' }
|
|
23
|
+
|
|
24
|
+
const rootOptions = Cli.toRootOptions.get(cli)
|
|
25
|
+
const node = buildNode(commands, rootOptions)
|
|
26
|
+
const properties = (node.properties ?? {}) as Record<string, unknown>
|
|
27
|
+
properties.$schema = { type: 'string' }
|
|
28
|
+
node.properties = properties
|
|
29
|
+
return node
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/** Builds a JSON Schema node for a command level. */
|
|
33
|
+
function buildNode(
|
|
34
|
+
commands: Map<string, any>,
|
|
35
|
+
options?: z.ZodObject<any>,
|
|
36
|
+
): Record<string, unknown> {
|
|
37
|
+
const properties: Record<string, unknown> = {}
|
|
38
|
+
|
|
39
|
+
// Add `options` property from the options schema
|
|
40
|
+
if (options) {
|
|
41
|
+
const optSchema = Schema.toJsonSchema(options)
|
|
42
|
+
const props = optSchema.properties as Record<string, unknown> | undefined
|
|
43
|
+
if (props && Object.keys(props).length > 0)
|
|
44
|
+
properties.options = { type: 'object', additionalProperties: false, properties: props }
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Add `commands` property with subcommand namespaces
|
|
48
|
+
const commandProps: Record<string, unknown> = {}
|
|
49
|
+
for (const [name, entry] of commands) {
|
|
50
|
+
if ('_group' in entry && entry._group) {
|
|
51
|
+
commandProps[name] = buildNode(entry.commands, undefined)
|
|
52
|
+
} else if (!('_fetch' in entry)) {
|
|
53
|
+
const cmd = entry as { options?: z.ZodObject<any> }
|
|
54
|
+
commandProps[name] = buildNode(new Map(), cmd.options)
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
if (Object.keys(commandProps).length > 0)
|
|
58
|
+
properties.commands = { type: 'object', additionalProperties: false, properties: commandProps }
|
|
59
|
+
|
|
60
|
+
const node: Record<string, unknown> = {
|
|
61
|
+
type: 'object',
|
|
62
|
+
additionalProperties: false,
|
|
63
|
+
}
|
|
64
|
+
if (Object.keys(properties).length > 0) node.properties = properties
|
|
65
|
+
return node
|
|
66
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/** Checks whether a value is a plain object record. */
|
|
2
|
+
export function isRecord(value: unknown): value is Record<string, unknown> {
|
|
3
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value)
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
/** Converts a camelCase string to kebab-case. */
|
|
7
|
+
export function toKebab(value: string): string {
|
|
8
|
+
return value.replace(/[A-Z]/g, (c) => `-${c.toLowerCase()}`)
|
|
9
|
+
}
|