incur 0.0.0 → 0.0.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.
Files changed (120) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +141 -0
  3. package/SKILL.md +664 -0
  4. package/dist/Cli.d.ts +255 -0
  5. package/dist/Cli.d.ts.map +1 -0
  6. package/dist/Cli.js +900 -0
  7. package/dist/Cli.js.map +1 -0
  8. package/dist/Errors.d.ts +92 -0
  9. package/dist/Errors.d.ts.map +1 -0
  10. package/dist/Errors.js +75 -0
  11. package/dist/Errors.js.map +1 -0
  12. package/dist/Formatter.d.ts +5 -0
  13. package/dist/Formatter.d.ts.map +1 -0
  14. package/dist/Formatter.js +91 -0
  15. package/dist/Formatter.js.map +1 -0
  16. package/dist/Help.d.ts +53 -0
  17. package/dist/Help.d.ts.map +1 -0
  18. package/dist/Help.js +231 -0
  19. package/dist/Help.js.map +1 -0
  20. package/dist/Mcp.d.ts +13 -0
  21. package/dist/Mcp.d.ts.map +1 -0
  22. package/dist/Mcp.js +140 -0
  23. package/dist/Mcp.js.map +1 -0
  24. package/dist/Parser.d.ts +24 -0
  25. package/dist/Parser.d.ts.map +1 -0
  26. package/dist/Parser.js +215 -0
  27. package/dist/Parser.js.map +1 -0
  28. package/dist/Register.d.ts +19 -0
  29. package/dist/Register.d.ts.map +1 -0
  30. package/dist/Register.js +2 -0
  31. package/dist/Register.js.map +1 -0
  32. package/dist/Schema.d.ts +4 -0
  33. package/dist/Schema.d.ts.map +1 -0
  34. package/dist/Schema.js +8 -0
  35. package/dist/Schema.js.map +1 -0
  36. package/dist/Skill.d.ts +29 -0
  37. package/dist/Skill.d.ts.map +1 -0
  38. package/dist/Skill.js +196 -0
  39. package/dist/Skill.js.map +1 -0
  40. package/dist/Skillgen.d.ts +3 -0
  41. package/dist/Skillgen.d.ts.map +1 -0
  42. package/dist/Skillgen.js +67 -0
  43. package/dist/Skillgen.js.map +1 -0
  44. package/dist/SyncMcp.d.ts +23 -0
  45. package/dist/SyncMcp.d.ts.map +1 -0
  46. package/dist/SyncMcp.js +100 -0
  47. package/dist/SyncMcp.js.map +1 -0
  48. package/dist/SyncSkills.d.ts +38 -0
  49. package/dist/SyncSkills.d.ts.map +1 -0
  50. package/dist/SyncSkills.js +163 -0
  51. package/dist/SyncSkills.js.map +1 -0
  52. package/dist/Typegen.d.ts +6 -0
  53. package/dist/Typegen.d.ts.map +1 -0
  54. package/dist/Typegen.js +92 -0
  55. package/dist/Typegen.js.map +1 -0
  56. package/dist/bin.d.ts +14 -0
  57. package/dist/bin.d.ts.map +1 -0
  58. package/dist/bin.js +30 -0
  59. package/dist/bin.js.map +1 -0
  60. package/dist/index.d.ts +15 -0
  61. package/dist/index.d.ts.map +1 -0
  62. package/dist/index.js +14 -0
  63. package/dist/index.js.map +1 -0
  64. package/dist/internal/pm.d.ts +3 -0
  65. package/dist/internal/pm.d.ts.map +1 -0
  66. package/dist/internal/pm.js +11 -0
  67. package/dist/internal/pm.js.map +1 -0
  68. package/dist/internal/types.d.ts +11 -0
  69. package/dist/internal/types.d.ts.map +1 -0
  70. package/dist/internal/types.js +2 -0
  71. package/dist/internal/types.js.map +1 -0
  72. package/dist/internal/utils.d.ts +8 -0
  73. package/dist/internal/utils.d.ts.map +1 -0
  74. package/dist/internal/utils.js +51 -0
  75. package/dist/internal/utils.js.map +1 -0
  76. package/examples/npm/cli.ts +180 -0
  77. package/examples/npm/node_modules/.bin/incur.src +21 -0
  78. package/examples/npm/node_modules/.bin/tsx +21 -0
  79. package/examples/npm/package.json +14 -0
  80. package/examples/npm/tsconfig.json +9 -0
  81. package/examples/presto/cli.ts +246 -0
  82. package/examples/presto/node_modules/.bin/incur.src +21 -0
  83. package/examples/presto/node_modules/.bin/tsx +21 -0
  84. package/examples/presto/package.json +14 -0
  85. package/examples/presto/tsconfig.json +9 -0
  86. package/package.json +53 -2
  87. package/src/Cli.test-d.ts +135 -0
  88. package/src/Cli.test.ts +1373 -0
  89. package/src/Cli.ts +1470 -0
  90. package/src/Errors.test.ts +96 -0
  91. package/src/Errors.ts +139 -0
  92. package/src/Formatter.test.ts +245 -0
  93. package/src/Formatter.ts +106 -0
  94. package/src/Help.test.ts +124 -0
  95. package/src/Help.ts +302 -0
  96. package/src/Mcp.test.ts +254 -0
  97. package/src/Mcp.ts +195 -0
  98. package/src/Parser.test-d.ts +45 -0
  99. package/src/Parser.test.ts +118 -0
  100. package/src/Parser.ts +247 -0
  101. package/src/Register.ts +18 -0
  102. package/src/Schema.test.ts +125 -0
  103. package/src/Schema.ts +8 -0
  104. package/src/Skill.test.ts +293 -0
  105. package/src/Skill.ts +253 -0
  106. package/src/Skillgen.ts +66 -0
  107. package/src/SyncMcp.test.ts +75 -0
  108. package/src/SyncMcp.ts +132 -0
  109. package/src/SyncSkills.test.ts +92 -0
  110. package/src/SyncSkills.ts +205 -0
  111. package/src/Typegen.test.ts +150 -0
  112. package/src/Typegen.ts +107 -0
  113. package/src/bin.ts +33 -0
  114. package/src/e2e.test.ts +1710 -0
  115. package/src/index.ts +14 -0
  116. package/src/internal/pm.test.ts +38 -0
  117. package/src/internal/pm.ts +8 -0
  118. package/src/internal/types.ts +22 -0
  119. package/src/internal/utils.ts +50 -0
  120. package/src/tsconfig.json +8 -0
@@ -0,0 +1,135 @@
1
+ import { Cli, z } from 'incur'
2
+ import { expectTypeOf, test } from 'vitest'
3
+
4
+ test('args in run() infers from args schema', () => {
5
+ const cli = Cli.create('test')
6
+ cli.command('greet', {
7
+ args: z.object({ name: z.string() }),
8
+ run({ args }) {
9
+ expectTypeOf(args).toEqualTypeOf<{ name: string }>()
10
+ return {}
11
+ },
12
+ })
13
+ })
14
+
15
+ test('options in run() infers from options schema', () => {
16
+ const cli = Cli.create('test')
17
+ cli.command('list', {
18
+ options: z.object({
19
+ state: z.enum(['open', 'closed']).default('open'),
20
+ limit: z.number().default(30),
21
+ }),
22
+ run({ options }) {
23
+ expectTypeOf(options).toEqualTypeOf<{ state: 'open' | 'closed'; limit: number }>()
24
+ return {}
25
+ },
26
+ })
27
+ })
28
+
29
+ test('without schemas, run receives empty objects', () => {
30
+ const cli = Cli.create('test')
31
+ cli.command('ping', {
32
+ run({ args, options }) {
33
+ expectTypeOf(args).toEqualTypeOf<{}>()
34
+ expectTypeOf(options).toEqualTypeOf<{}>()
35
+ return { pong: true }
36
+ },
37
+ })
38
+ })
39
+
40
+ test('output constrains run return type', () => {
41
+ const cli = Cli.create('test')
42
+ cli.command('greet', {
43
+ output: z.object({ message: z.string() }),
44
+ run() {
45
+ return { message: 'hello' }
46
+ },
47
+ })
48
+
49
+ cli.command('greet', {
50
+ output: z.object({ message: z.string() }),
51
+ // @ts-expect-error — return doesn't match output schema
52
+ run() {
53
+ return { wrong: 123 }
54
+ },
55
+ })
56
+ })
57
+
58
+ test('alias keys are constrained to option keys', () => {
59
+ const cli = Cli.create('test')
60
+ cli.command('list', {
61
+ options: z.object({ state: z.string(), limit: z.number() }),
62
+ alias: { state: 's', limit: 'l' },
63
+ run: () => ({}),
64
+ })
65
+
66
+ cli.command('list', {
67
+ options: z.object({ state: z.string() }),
68
+ // @ts-expect-error — 'foo' is not an option key
69
+ alias: { foo: 'f' },
70
+ run: () => ({}),
71
+ })
72
+ })
73
+
74
+ test('ok() data param is typed from output schema', () => {
75
+ const cli = Cli.create('test')
76
+ cli.command('list', {
77
+ output: z.object({ items: z.array(z.string()) }),
78
+ run({ ok }) {
79
+ return ok({ items: ['a', 'b'] })
80
+ },
81
+ })
82
+
83
+ cli.command('list2', {
84
+ output: z.object({ items: z.array(z.string()) }),
85
+ run({ ok }) {
86
+ // @ts-expect-error — data doesn't match output schema
87
+ return ok({ wrong: 123 })
88
+ },
89
+ })
90
+ })
91
+
92
+ test('Cta accepts string shorthand', () => {
93
+ expectTypeOf<'auth login'>().toMatchTypeOf<Cli.Cta>()
94
+ })
95
+
96
+ test('Cta accepts object form', () => {
97
+ expectTypeOf<{ command: 'auth login'; description: 'Log in' }>().toMatchTypeOf<Cli.Cta>()
98
+ })
99
+
100
+ test('Cta narrows strings and objects to registered commands', () => {
101
+ type Commands = {
102
+ get: { args: { id: number }; options: {} }
103
+ list: { args: {}; options: { limit: number } }
104
+ }
105
+ type Cta = Cli.Cta<Commands>
106
+
107
+ // string suggests registered command names but accepts any string
108
+ expectTypeOf<'get'>().toMatchTypeOf<Cta>()
109
+ expectTypeOf<'list'>().toMatchTypeOf<Cta>()
110
+ expectTypeOf<'anything else'>().toMatchTypeOf<Cta>()
111
+
112
+ // object form narrows args/options via discriminated union on command
113
+ expectTypeOf<{ command: 'get'; args: { id: 42 } }>().toMatchTypeOf<Cta>()
114
+ expectTypeOf<{ command: 'list'; options: { limit: 10 } }>().toMatchTypeOf<Cta>()
115
+ })
116
+
117
+ test('command() accumulates command types through chaining', () => {
118
+ const cli = Cli.create('test')
119
+ .command('get', {
120
+ args: z.object({ id: z.number() }),
121
+ options: z.object({ verbose: z.boolean().default(false) }),
122
+ run: ({ args }) => ({ id: args.id }),
123
+ })
124
+ .command('list', {
125
+ options: z.object({ limit: z.number().default(30) }),
126
+ run: () => ({ items: [] }),
127
+ })
128
+
129
+ type Commands = typeof cli extends Cli.Cli<infer C> ? C : never
130
+ expectTypeOf<Commands['get']>().toEqualTypeOf<{
131
+ args: { id: number }
132
+ options: { verbose: boolean }
133
+ }>()
134
+ expectTypeOf<Commands['list']>().toEqualTypeOf<{ args: {}; options: { limit: number } }>()
135
+ })