incur 0.4.8 → 0.4.10
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.d.ts +69 -19
- package/dist/Cli.d.ts.map +1 -1
- package/dist/Cli.js +419 -73
- package/dist/Cli.js.map +1 -1
- package/dist/Completions.d.ts +2 -1
- package/dist/Completions.d.ts.map +1 -1
- package/dist/Completions.js +52 -13
- package/dist/Completions.js.map +1 -1
- package/dist/Formatter.d.ts.map +1 -1
- package/dist/Formatter.js +6 -5
- package/dist/Formatter.js.map +1 -1
- package/dist/Help.d.ts +5 -0
- package/dist/Help.d.ts.map +1 -1
- package/dist/Help.js +19 -5
- package/dist/Help.js.map +1 -1
- package/dist/Mcp.d.ts +21 -0
- package/dist/Mcp.d.ts.map +1 -1
- package/dist/Mcp.js +44 -13
- package/dist/Mcp.js.map +1 -1
- package/dist/Parser.d.ts +14 -0
- package/dist/Parser.d.ts.map +1 -1
- package/dist/Parser.js +127 -1
- package/dist/Parser.js.map +1 -1
- package/dist/Skill.d.ts.map +1 -1
- package/dist/Skill.js +5 -2
- package/dist/Skill.js.map +1 -1
- package/dist/Skillgen.d.ts.map +1 -1
- package/dist/Skillgen.js +4 -38
- package/dist/Skillgen.js.map +1 -1
- package/dist/SyncMcp.d.ts.map +1 -1
- package/dist/SyncMcp.js +75 -8
- package/dist/SyncMcp.js.map +1 -1
- package/dist/SyncSkills.d.ts +9 -0
- package/dist/SyncSkills.d.ts.map +1 -1
- package/dist/SyncSkills.js +13 -74
- package/dist/SyncSkills.js.map +1 -1
- package/dist/bin.d.ts +1 -1
- package/dist/bin.d.ts.map +1 -1
- package/dist/internal/command.d.ts +31 -19
- package/dist/internal/command.d.ts.map +1 -1
- package/dist/internal/command.js +10 -5
- package/dist/internal/command.js.map +1 -1
- package/dist/internal/cta.d.ts +22 -0
- package/dist/internal/cta.d.ts.map +1 -0
- package/dist/internal/cta.js +25 -0
- package/dist/internal/cta.js.map +1 -0
- package/dist/internal/json.d.ts +5 -0
- package/dist/internal/json.d.ts.map +1 -0
- package/dist/internal/json.js +13 -0
- package/dist/internal/json.js.map +1 -0
- package/dist/internal/yaml.d.ts +12 -0
- package/dist/internal/yaml.d.ts.map +1 -0
- package/dist/internal/yaml.js +20 -0
- package/dist/internal/yaml.js.map +1 -0
- package/dist/middleware.d.ts +8 -4
- package/dist/middleware.d.ts.map +1 -1
- package/dist/middleware.js +1 -1
- package/dist/middleware.js.map +1 -1
- package/package.json +1 -1
- package/src/Cli.test-d.ts +73 -0
- package/src/Cli.test.ts +1536 -48
- package/src/Cli.ts +606 -108
- package/src/Completions.test.ts +85 -0
- package/src/Completions.ts +48 -9
- package/src/Formatter.test.ts +17 -0
- package/src/Formatter.ts +7 -5
- package/src/Help.test.ts +32 -1
- package/src/Help.ts +42 -4
- package/src/Mcp.test.ts +289 -0
- package/src/Mcp.ts +68 -13
- package/src/Parser.test.ts +173 -0
- package/src/Parser.ts +132 -1
- package/src/Skill.test.ts +6 -0
- package/src/Skill.ts +8 -5
- package/src/Skillgen.test.ts +55 -6
- package/src/Skillgen.ts +9 -35
- package/src/SyncMcp.test.ts +89 -0
- package/src/SyncMcp.ts +72 -8
- package/src/SyncSkills.test.ts +78 -1
- package/src/SyncSkills.ts +20 -78
- package/src/bun-compile.test.ts +5 -0
- package/src/e2e.test.ts +166 -12
- package/src/internal/command.ts +12 -4
- package/src/internal/cta.ts +58 -0
- package/src/internal/json.ts +16 -0
- package/src/internal/yaml.ts +23 -0
- package/src/lazy-imports.test.ts +94 -0
- package/src/middleware.ts +12 -3
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { execFile } from 'node:child_process'
|
|
2
|
+
import { mkdtemp, rm, writeFile } from 'node:fs/promises'
|
|
3
|
+
import { tmpdir } from 'node:os'
|
|
4
|
+
import { join } from 'node:path'
|
|
5
|
+
|
|
6
|
+
function exec(cmd: string, args: string[]): Promise<{ stdout: string; stderr: string }> {
|
|
7
|
+
return new Promise((resolve, reject) => {
|
|
8
|
+
execFile(
|
|
9
|
+
cmd,
|
|
10
|
+
args,
|
|
11
|
+
{ cwd: join(import.meta.dirname, '..'), timeout: 30_000 },
|
|
12
|
+
(error, stdout, stderr) => {
|
|
13
|
+
if (error) reject(new Error(stderr?.trim() || stdout?.trim() || error.message))
|
|
14
|
+
else resolve({ stdout, stderr })
|
|
15
|
+
},
|
|
16
|
+
)
|
|
17
|
+
})
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
let dir: string
|
|
21
|
+
let src: string
|
|
22
|
+
|
|
23
|
+
describe('lazy imports', () => {
|
|
24
|
+
beforeAll(async () => {
|
|
25
|
+
dir = await mkdtemp(join(tmpdir(), 'incur-lazy-'))
|
|
26
|
+
src = join(dir, 'cli.mts')
|
|
27
|
+
|
|
28
|
+
// Records every module loaded during a CLI run, then prints the heavy ones.
|
|
29
|
+
await writeFile(
|
|
30
|
+
src,
|
|
31
|
+
`
|
|
32
|
+
import { registerHooks } from 'node:module'
|
|
33
|
+
|
|
34
|
+
const loaded: string[] = []
|
|
35
|
+
registerHooks({
|
|
36
|
+
resolve(specifier, context, next) {
|
|
37
|
+
const result = next(specifier, context)
|
|
38
|
+
loaded.push(result.url)
|
|
39
|
+
return result
|
|
40
|
+
},
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
const { Cli, z } = await import('${join(import.meta.dirname, 'index.ts')}')
|
|
44
|
+
|
|
45
|
+
const cli = Cli.create('lazy-cli', { version: '1.0.0' })
|
|
46
|
+
|
|
47
|
+
cli.command('ping', {
|
|
48
|
+
description: 'Health check',
|
|
49
|
+
options: z.object({ upper: z.boolean().default(false) }),
|
|
50
|
+
run() {
|
|
51
|
+
return { pong: true }
|
|
52
|
+
},
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
await cli.serve(process.argv.slice(2))
|
|
56
|
+
|
|
57
|
+
const heavy = loaded.filter(
|
|
58
|
+
(url) => url.includes('@modelcontextprotocol') || url.includes('node_modules/yaml'),
|
|
59
|
+
)
|
|
60
|
+
console.log(JSON.stringify({ heavy }))
|
|
61
|
+
`,
|
|
62
|
+
)
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
afterAll(async () => {
|
|
66
|
+
await rm(dir, { recursive: true, force: true })
|
|
67
|
+
})
|
|
68
|
+
|
|
69
|
+
function parseHeavy(stdout: string): string[] {
|
|
70
|
+
const line = stdout.trim().split('\n').at(-1)!
|
|
71
|
+
return (JSON.parse(line) as { heavy: string[] }).heavy
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
test('plain command run does not load yaml or the MCP SDK', async () => {
|
|
75
|
+
const { stdout } = await exec(process.execPath, ['--import', 'tsx', src, 'ping'])
|
|
76
|
+
expect(stdout).toContain('pong: true')
|
|
77
|
+
expect(parseHeavy(stdout)).toEqual([])
|
|
78
|
+
})
|
|
79
|
+
|
|
80
|
+
test('--format yaml loads yaml on demand, but not the MCP SDK', async () => {
|
|
81
|
+
const { stdout } = await exec(process.execPath, [
|
|
82
|
+
'--import',
|
|
83
|
+
'tsx',
|
|
84
|
+
src,
|
|
85
|
+
'ping',
|
|
86
|
+
'--format',
|
|
87
|
+
'yaml',
|
|
88
|
+
])
|
|
89
|
+
expect(stdout).toContain('pong: true')
|
|
90
|
+
const heavy = parseHeavy(stdout)
|
|
91
|
+
expect(heavy.some((url) => url.includes('node_modules/yaml'))).toBe(true)
|
|
92
|
+
expect(heavy.some((url) => url.includes('@modelcontextprotocol'))).toBe(false)
|
|
93
|
+
})
|
|
94
|
+
})
|
package/src/middleware.ts
CHANGED
|
@@ -10,11 +10,16 @@ type InferVars<vars extends z.ZodObject<any> | undefined> =
|
|
|
10
10
|
type InferEnv<env extends z.ZodObject<any> | undefined> =
|
|
11
11
|
env extends z.ZodObject<any> ? z.output<env> : {}
|
|
12
12
|
|
|
13
|
+
/** @internal Infers the output type of a globals schema, or `{}` if undefined. */
|
|
14
|
+
type InferGlobals<globals extends z.ZodObject<any> | undefined> =
|
|
15
|
+
globals extends z.ZodObject<any> ? z.output<globals> : {}
|
|
16
|
+
|
|
13
17
|
/** Middleware handler that runs before/after command execution. */
|
|
14
18
|
export type Handler<
|
|
15
19
|
vars extends z.ZodObject<any> | undefined = undefined,
|
|
16
20
|
env extends z.ZodObject<any> | undefined = undefined,
|
|
17
|
-
|
|
21
|
+
globals extends z.ZodObject<any> | undefined = undefined,
|
|
22
|
+
> = (context: Context<vars, env, globals>, next: () => Promise<void>) => Promise<void> | void
|
|
18
23
|
|
|
19
24
|
/** CTA block for middleware error/ok responses. */
|
|
20
25
|
type CtaBlock = {
|
|
@@ -28,6 +33,7 @@ type CtaBlock = {
|
|
|
28
33
|
export type Context<
|
|
29
34
|
vars extends z.ZodObject<any> | undefined = undefined,
|
|
30
35
|
env extends z.ZodObject<any> | undefined = undefined,
|
|
36
|
+
globals extends z.ZodObject<any> | undefined = undefined,
|
|
31
37
|
> = {
|
|
32
38
|
/** Whether the consumer is an agent (stdout is not a TTY). */
|
|
33
39
|
agent: boolean
|
|
@@ -49,6 +55,8 @@ export type Context<
|
|
|
49
55
|
format: Formatter.Format
|
|
50
56
|
/** Whether the user explicitly passed `--format` or `--json`. */
|
|
51
57
|
formatExplicit: boolean
|
|
58
|
+
/** Parsed global options from the CLI-level globals schema. */
|
|
59
|
+
globals: InferGlobals<globals>
|
|
52
60
|
/** The CLI name. */
|
|
53
61
|
name: string
|
|
54
62
|
/** Set a typed variable for downstream middleware and handlers. */
|
|
@@ -59,10 +67,11 @@ export type Context<
|
|
|
59
67
|
version: string | undefined
|
|
60
68
|
}
|
|
61
69
|
|
|
62
|
-
/** Creates a strictly typed middleware handler. Pass the vars schema as a generic for typed `c.set()` and `c.var`, and the
|
|
70
|
+
/** Creates a strictly typed middleware handler. Pass the vars schema as a generic for typed `c.set()` and `c.var`, the env schema for typed `c.env`, and the globals schema for typed `c.globals`. */
|
|
63
71
|
export default function middleware<
|
|
64
72
|
const vars extends z.ZodObject<any> | undefined = undefined,
|
|
65
73
|
const env extends z.ZodObject<any> | undefined = undefined,
|
|
66
|
-
|
|
74
|
+
const globals extends z.ZodObject<any> | undefined = undefined,
|
|
75
|
+
>(handler: Handler<vars, env, globals>): Handler<vars, env, globals> {
|
|
67
76
|
return handler
|
|
68
77
|
}
|