incur 0.3.2 → 0.3.4

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/src/Cli.ts CHANGED
@@ -1,18 +1,18 @@
1
+ import { estimateTokenCount, sliceByTokens } from 'tokenx'
1
2
  import type { z } from 'zod'
2
3
 
3
- import { estimateTokenCount, sliceByTokens } from 'tokenx'
4
4
  import * as Completions from './Completions.js'
5
- import * as Filter from './Filter.js'
6
5
  import type { FieldError } from './Errors.js'
7
6
  import { IncurError, ValidationError } from './Errors.js'
8
7
  import * as Fetch from './Fetch.js'
9
- import * as Openapi from './Openapi.js'
8
+ import * as Filter from './Filter.js'
10
9
  import * as Formatter from './Formatter.js'
11
10
  import * as Help from './Help.js'
12
11
  import { detectRunner } from './internal/pm.js'
13
12
  import type { OneOf } from './internal/types.js'
14
13
  import * as Mcp from './Mcp.js'
15
14
  import type { Context as MiddlewareContext, Handler as MiddlewareHandler } from './middleware.js'
15
+ import * as Openapi from './Openapi.js'
16
16
  export type { MiddlewareHandler }
17
17
  import * as Parser from './Parser.js'
18
18
  import type { Register } from './Register.js'
@@ -63,7 +63,13 @@ export type Cli<
63
63
  /** Mounts a fetch handler as a command, optionally with OpenAPI spec for typed subcommands. */
64
64
  <const name extends string>(
65
65
  name: name,
66
- definition: { basePath?: string | undefined; description?: string | undefined; fetch: FetchHandler; openapi?: Openapi.OpenAPISpec | undefined; outputPolicy?: OutputPolicy | undefined },
66
+ definition: {
67
+ basePath?: string | undefined
68
+ description?: string | undefined
69
+ fetch: FetchHandler
70
+ openapi?: Openapi.OpenAPISpec | undefined
71
+ outputPolicy?: OutputPolicy | undefined
72
+ },
67
73
  ): Cli<commands, vars, env>
68
74
  }
69
75
  /** A short description of the CLI. */
@@ -204,14 +210,16 @@ export function create(
204
210
  // OpenAPI + fetch → generate typed command group (async, resolved before serve)
205
211
  if (def.openapi) {
206
212
  pending.push(
207
- Openapi.generateCommands(def.openapi, def.fetch, { basePath: def.basePath }).then((generated) => {
208
- commands.set(nameOrCli, {
209
- _group: true,
210
- description: def.description,
211
- commands: generated as Map<string, CommandEntry>,
212
- ...(def.outputPolicy ? { outputPolicy: def.outputPolicy } : undefined),
213
- } as InternalGroup)
214
- }),
213
+ Openapi.generateCommands(def.openapi, def.fetch, { basePath: def.basePath }).then(
214
+ (generated) => {
215
+ commands.set(nameOrCli, {
216
+ _group: true,
217
+ description: def.description,
218
+ commands: generated as Map<string, CommandEntry>,
219
+ ...(def.outputPolicy ? { outputPolicy: def.outputPolicy } : undefined),
220
+ } as InternalGroup)
221
+ },
222
+ ),
215
223
  )
216
224
  return cli
217
225
  }
@@ -594,7 +602,7 @@ async function serveImpl(
594
602
  if (help) {
595
603
  writeln(
596
604
  [
597
- `${name} skills add — Sync skill files to your agent`,
605
+ `${name} skills add — Sync skill files to agents`,
598
606
  '',
599
607
  `Usage: ${name} skills add [options]`,
600
608
  '',
@@ -670,7 +678,7 @@ async function serveImpl(
670
678
  if (help) {
671
679
  writeln(
672
680
  [
673
- `${name} mcp add — Register as an MCP server for your agent`,
681
+ `${name} mcp add — Register as MCP server for your agent`,
674
682
  '',
675
683
  `Usage: ${name} mcp add [options]`,
676
684
  '',
@@ -786,7 +794,16 @@ async function serveImpl(
786
794
  filtered.length === 0 && options.rootCommand
787
795
  ? { command: options.rootCommand, path: name, rest: [] as string[] }
788
796
  : filtered.length === 0 && options.rootFetch
789
- ? { fetchGateway: { _fetch: true as const, fetch: options.rootFetch, description: options.description }, middlewares: [] as MiddlewareHandler[], path: name, rest: [] as string[] }
797
+ ? {
798
+ fetchGateway: {
799
+ _fetch: true as const,
800
+ fetch: options.rootFetch,
801
+ description: options.description,
802
+ },
803
+ middlewares: [] as MiddlewareHandler[],
804
+ path: name,
805
+ rest: [] as string[],
806
+ }
790
807
  : resolveCommand(commands, filtered)
791
808
 
792
809
  // --help on a fetch gateway → show fetch-specific help
@@ -916,7 +933,16 @@ async function serveImpl(
916
933
  // Fall back to root fetch when no subcommand matches
917
934
  const effective =
918
935
  'error' in resolved && options.rootFetch && !resolved.path
919
- ? { fetchGateway: { _fetch: true as const, fetch: options.rootFetch, description: options.description }, middlewares: [] as MiddlewareHandler[], path: name, rest: filtered }
936
+ ? {
937
+ fetchGateway: {
938
+ _fetch: true as const,
939
+ fetch: options.rootFetch,
940
+ description: options.description,
941
+ },
942
+ middlewares: [] as MiddlewareHandler[],
943
+ path: name,
944
+ rest: filtered,
945
+ }
920
946
  : 'error' in resolved && options.rootCommand && !resolved.path
921
947
  ? { command: options.rootCommand, path: name, rest: filtered }
922
948
  : resolved
@@ -928,7 +954,11 @@ async function serveImpl(
928
954
 
929
955
  const filterPaths = filterOutput ? Filter.parse(filterOutput) : undefined
930
956
 
931
- function truncate(s: string): { text: string; truncated: boolean; nextOffset?: number | undefined } {
957
+ function truncate(s: string): {
958
+ text: string
959
+ truncated: boolean
960
+ nextOffset?: number | undefined
961
+ } {
932
962
  if (tokenLimit == null && tokenOffset == null) return { text: s, truncated: false }
933
963
  const total = estimateTokenCount(s)
934
964
  const offset = tokenOffset ?? 0
@@ -964,11 +994,12 @@ async function serveImpl(
964
994
  if (verbose) {
965
995
  if (tokenLimit != null || tokenOffset != null) {
966
996
  // Truncate data separately so meta (including nextOffset) is always visible
967
- const dataFormatted = output.ok && output.data != null
968
- ? Formatter.format(output.data, format)
969
- : !output.ok
970
- ? Formatter.format(output.error, format)
971
- : ''
997
+ const dataFormatted =
998
+ output.ok && output.data != null
999
+ ? Formatter.format(output.data, format)
1000
+ : !output.ok
1001
+ ? Formatter.format(output.error, format)
1002
+ : ''
972
1003
  const t = truncate(dataFormatted)
973
1004
  if (t.truncated) {
974
1005
  const envelope: Record<string, unknown> = output.ok
@@ -1070,9 +1101,12 @@ async function serveImpl(
1070
1101
  ok: false,
1071
1102
  error: {
1072
1103
  code: `HTTP_${output.status}`,
1073
- message: typeof output.data === 'object' && output.data !== null && 'message' in output.data
1074
- ? String((output.data as any).message)
1075
- : typeof output.data === 'string' ? output.data : `HTTP ${output.status}`,
1104
+ message:
1105
+ typeof output.data === 'object' && output.data !== null && 'message' in output.data
1106
+ ? String((output.data as any).message)
1107
+ : typeof output.data === 'string'
1108
+ ? output.data
1109
+ : `HTTP ${output.status}`,
1076
1110
  },
1077
1111
  meta: {
1078
1112
  command: path,
@@ -1084,11 +1118,18 @@ async function serveImpl(
1084
1118
  }
1085
1119
 
1086
1120
  try {
1087
- const cliEnv = options.envSchema ? Parser.parseEnv(options.envSchema, options.env ?? process.env) : {}
1121
+ const cliEnv = options.envSchema
1122
+ ? Parser.parseEnv(options.envSchema, options.env ?? process.env)
1123
+ : {}
1088
1124
  if (fetchMiddleware.length > 0) {
1089
1125
  const varsMap: Record<string, unknown> = options.vars ? options.vars.parse({}) : {}
1090
- const errorFn = (opts: { code: string; exitCode?: number | undefined; message: string; retryable?: boolean | undefined; cta?: CtaBlock | undefined }): never =>
1091
- ({ [sentinel]: 'error', ...opts }) as never
1126
+ const errorFn = (opts: {
1127
+ code: string
1128
+ exitCode?: number | undefined
1129
+ message: string
1130
+ retryable?: boolean | undefined
1131
+ cta?: CtaBlock | undefined
1132
+ }): never => ({ [sentinel]: 'error', ...opts }) as never
1092
1133
  const mwCtx: MiddlewareContext = {
1093
1134
  agent: !human,
1094
1135
  command: path,
@@ -1097,7 +1138,9 @@ async function serveImpl(
1097
1138
  format,
1098
1139
  formatExplicit,
1099
1140
  name,
1100
- set(key: string, value: unknown) { varsMap[key] = value },
1141
+ set(key: string, value: unknown) {
1142
+ varsMap[key] = value
1143
+ },
1101
1144
  var: varsMap,
1102
1145
  version: options.version,
1103
1146
  }
@@ -1107,13 +1150,23 @@ async function serveImpl(
1107
1150
  const cta = formatCtaBlock(name, err.cta)
1108
1151
  write({
1109
1152
  ok: false,
1110
- error: { code: err.code, message: err.message, ...(err.retryable !== undefined ? { retryable: err.retryable } : undefined) },
1111
- meta: { command: path, duration: `${Math.round(performance.now() - start)}ms`, ...(cta ? { cta } : undefined) },
1153
+ error: {
1154
+ code: err.code,
1155
+ message: err.message,
1156
+ ...(err.retryable !== undefined ? { retryable: err.retryable } : undefined),
1157
+ },
1158
+ meta: {
1159
+ command: path,
1160
+ duration: `${Math.round(performance.now() - start)}ms`,
1161
+ ...(cta ? { cta } : undefined),
1162
+ },
1112
1163
  })
1113
1164
  exit(err.exitCode ?? 1)
1114
1165
  }
1115
1166
  const composed = fetchMiddleware.reduceRight(
1116
- (next: () => Promise<void>, mw) => async () => { handleMwSentinel(await mw(mwCtx, next)) },
1167
+ (next: () => Promise<void>, mw) => async () => {
1168
+ handleMwSentinel(await mw(mwCtx, next))
1169
+ },
1117
1170
  runFetch,
1118
1171
  )
1119
1172
  await composed()
@@ -1344,7 +1397,9 @@ async function serveImpl(
1344
1397
  /** @internal Options for fetchImpl. */
1345
1398
  declare namespace fetchImpl {
1346
1399
  type Options = {
1347
- mcpHandler?: ((req: Request, commands: Map<string, CommandEntry>) => Promise<Response>) | undefined
1400
+ mcpHandler?:
1401
+ | ((req: Request, commands: Map<string, CommandEntry>) => Promise<Response>)
1402
+ | undefined
1348
1403
  middlewares?: MiddlewareHandler[] | undefined
1349
1404
  rootCommand?: CommandDefinition<any, any, any> | undefined
1350
1405
  vars?: z.ZodObject<any> | undefined
@@ -1358,9 +1413,8 @@ function createMcpHttpHandler(name: string, version: string) {
1358
1413
  return async (req: Request, commands: Map<string, CommandEntry>): Promise<Response> => {
1359
1414
  if (!transport) {
1360
1415
  const { McpServer } = await import('@modelcontextprotocol/sdk/server/mcp.js')
1361
- const { WebStandardStreamableHTTPServerTransport } = await import(
1362
- '@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js'
1363
- )
1416
+ const { WebStandardStreamableHTTPServerTransport } =
1417
+ await import('@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js')
1364
1418
 
1365
1419
  const server = new McpServer({ name, version })
1366
1420
 
@@ -1455,12 +1509,12 @@ async function fetchImpl(
1455
1509
 
1456
1510
  // Parse options from search params (GET) or body (non-GET)
1457
1511
  let inputOptions: Record<string, unknown> = {}
1458
- if (req.method === 'GET')
1459
- for (const [key, value] of url.searchParams) inputOptions[key] = value
1512
+ if (req.method === 'GET') for (const [key, value] of url.searchParams) inputOptions[key] = value
1460
1513
  else {
1461
1514
  try {
1462
1515
  const contentType = req.headers.get('content-type') ?? ''
1463
- if (contentType.includes('application/json')) inputOptions = (await req.json()) as Record<string, unknown>
1516
+ if (contentType.includes('application/json'))
1517
+ inputOptions = (await req.json()) as Record<string, unknown>
1464
1518
  } catch {}
1465
1519
  }
1466
1520
 
@@ -1477,7 +1531,11 @@ async function fetchImpl(
1477
1531
  if (options.rootCommand)
1478
1532
  return executeCommand(name, options.rootCommand, [], inputOptions, start, options)
1479
1533
  return jsonResponse(
1480
- { ok: false, error: { code: 'COMMAND_NOT_FOUND', message: 'No root command defined.' }, meta: { command: '/', duration: `${Math.round(performance.now() - start)}ms` } },
1534
+ {
1535
+ ok: false,
1536
+ error: { code: 'COMMAND_NOT_FOUND', message: 'No root command defined.' },
1537
+ meta: { command: '/', duration: `${Math.round(performance.now() - start)}ms` },
1538
+ },
1481
1539
  404,
1482
1540
  )
1483
1541
  }
@@ -1486,18 +1544,31 @@ async function fetchImpl(
1486
1544
 
1487
1545
  if ('error' in resolved)
1488
1546
  return jsonResponse(
1489
- { ok: false, error: { code: 'COMMAND_NOT_FOUND', message: `'${resolved.error}' is not a command for '${resolved.path ? `${name} ${resolved.path}` : name}'.` }, meta: { command: resolved.error, duration: `${Math.round(performance.now() - start)}ms` } },
1547
+ {
1548
+ ok: false,
1549
+ error: {
1550
+ code: 'COMMAND_NOT_FOUND',
1551
+ message: `'${resolved.error}' is not a command for '${resolved.path ? `${name} ${resolved.path}` : name}'.`,
1552
+ },
1553
+ meta: { command: resolved.error, duration: `${Math.round(performance.now() - start)}ms` },
1554
+ },
1490
1555
  404,
1491
1556
  )
1492
1557
 
1493
1558
  if ('help' in resolved)
1494
1559
  return jsonResponse(
1495
- { ok: false, error: { code: 'COMMAND_NOT_FOUND', message: `'${resolved.path}' is a command group. Specify a subcommand.` }, meta: { command: resolved.path, duration: `${Math.round(performance.now() - start)}ms` } },
1560
+ {
1561
+ ok: false,
1562
+ error: {
1563
+ code: 'COMMAND_NOT_FOUND',
1564
+ message: `'${resolved.path}' is a command group. Specify a subcommand.`,
1565
+ },
1566
+ meta: { command: resolved.path, duration: `${Math.round(performance.now() - start)}ms` },
1567
+ },
1496
1568
  404,
1497
1569
  )
1498
1570
 
1499
- if ('fetchGateway' in resolved)
1500
- return resolved.fetchGateway.fetch(req)
1571
+ if ('fetchGateway' in resolved) return resolved.fetchGateway.fetch(req)
1501
1572
 
1502
1573
  const { command, path, rest } = resolved
1503
1574
  return executeCommand(path, command, rest, inputOptions, start, options)
@@ -1528,8 +1599,11 @@ async function executeCommand(
1528
1599
  const parsedOptions = command.options ? command.options.parse(inputOptions) : {}
1529
1600
 
1530
1601
  const okFn = (data: unknown): never => ({ [sentinel_]: 'ok', data }) as never
1531
- const errorFn = (opts: { code: string; message: string; exitCode?: number | undefined }): never =>
1532
- ({ [sentinel_]: 'error', ...opts }) as never
1602
+ const errorFn = (opts: {
1603
+ code: string
1604
+ message: string
1605
+ exitCode?: number | undefined
1606
+ }): never => ({ [sentinel_]: 'error', ...opts }) as never
1533
1607
 
1534
1608
  const result = command.run({
1535
1609
  agent: true,
@@ -1560,26 +1634,60 @@ async function executeCommand(
1560
1634
  }
1561
1635
  if (isSentinel(value) && (value as any)[sentinel] === 'error') {
1562
1636
  const tagged = value as any
1563
- controller.enqueue(encoder.encode(JSON.stringify({ type: 'error', ok: false, error: { code: tagged.code, message: tagged.message } }) + '\n'))
1637
+ controller.enqueue(
1638
+ encoder.encode(
1639
+ JSON.stringify({
1640
+ type: 'error',
1641
+ ok: false,
1642
+ error: { code: tagged.code, message: tagged.message },
1643
+ }) + '\n',
1644
+ ),
1645
+ )
1564
1646
  controller.close()
1565
1647
  return
1566
1648
  }
1567
- controller.enqueue(encoder.encode(JSON.stringify({ type: 'chunk', data: value }) + '\n'))
1649
+ controller.enqueue(
1650
+ encoder.encode(JSON.stringify({ type: 'chunk', data: value }) + '\n'),
1651
+ )
1568
1652
  }
1569
1653
  const meta: Record<string, unknown> = { command: path }
1570
1654
  if (isSentinel(returnValue) && (returnValue as any)[sentinel] === 'error') {
1571
1655
  const tagged = returnValue as any
1572
- controller.enqueue(encoder.encode(JSON.stringify({ type: 'error', ok: false, error: { code: tagged.code, message: tagged.message } }) + '\n'))
1656
+ controller.enqueue(
1657
+ encoder.encode(
1658
+ JSON.stringify({
1659
+ type: 'error',
1660
+ ok: false,
1661
+ error: { code: tagged.code, message: tagged.message },
1662
+ }) + '\n',
1663
+ ),
1664
+ )
1573
1665
  } else {
1574
- controller.enqueue(encoder.encode(JSON.stringify({ type: 'done', ok: true, meta }) + '\n'))
1666
+ controller.enqueue(
1667
+ encoder.encode(JSON.stringify({ type: 'done', ok: true, meta }) + '\n'),
1668
+ )
1575
1669
  }
1576
1670
  } catch (error) {
1577
- controller.enqueue(encoder.encode(JSON.stringify({ type: 'error', ok: false, error: { code: 'UNKNOWN', message: error instanceof Error ? error.message : String(error) } }) + '\n'))
1671
+ controller.enqueue(
1672
+ encoder.encode(
1673
+ JSON.stringify({
1674
+ type: 'error',
1675
+ ok: false,
1676
+ error: {
1677
+ code: 'UNKNOWN',
1678
+ message: error instanceof Error ? error.message : String(error),
1679
+ },
1680
+ }) + '\n',
1681
+ ),
1682
+ )
1578
1683
  }
1579
1684
  controller.close()
1580
1685
  },
1581
1686
  })
1582
- response = new Response(stream, { status: 200, headers: { 'content-type': 'application/x-ndjson' } })
1687
+ response = new Response(stream, {
1688
+ status: 200,
1689
+ headers: { 'content-type': 'application/x-ndjson' },
1690
+ })
1583
1691
  return
1584
1692
  }
1585
1693
 
@@ -1590,7 +1698,11 @@ async function executeCommand(
1590
1698
  const tagged = awaited as any
1591
1699
  if (tagged[sentinel_] === 'error')
1592
1700
  response = jsonResponse(
1593
- { ok: false, error: { code: tagged.code, message: tagged.message }, meta: { command: path, duration } },
1701
+ {
1702
+ ok: false,
1703
+ error: { code: tagged.code, message: tagged.message },
1704
+ meta: { command: path, duration },
1705
+ },
1594
1706
  500,
1595
1707
  )
1596
1708
  else
@@ -1601,19 +1713,24 @@ async function executeCommand(
1601
1713
  return
1602
1714
  }
1603
1715
 
1604
- response = jsonResponse(
1605
- { ok: true, data: awaited, meta: { command: path, duration } },
1606
- 200,
1607
- )
1716
+ response = jsonResponse({ ok: true, data: awaited, meta: { command: path, duration } }, 200)
1608
1717
  }
1609
1718
 
1610
1719
  try {
1611
1720
  const allMiddleware = options.middlewares ?? []
1612
1721
  if (allMiddleware.length > 0) {
1613
- const errorFn = (opts: { code: string; message: string; exitCode?: number | undefined }): never => {
1722
+ const errorFn = (opts: {
1723
+ code: string
1724
+ message: string
1725
+ exitCode?: number | undefined
1726
+ }): never => {
1614
1727
  const duration = `${Math.round(performance.now() - start)}ms`
1615
1728
  response = jsonResponse(
1616
- { ok: false, error: { code: opts.code, message: opts.message }, meta: { command: path, duration } },
1729
+ {
1730
+ ok: false,
1731
+ error: { code: opts.code, message: opts.message },
1732
+ meta: { command: path, duration },
1733
+ },
1617
1734
  500,
1618
1735
  )
1619
1736
  return undefined as never
@@ -1626,12 +1743,16 @@ async function executeCommand(
1626
1743
  format: 'json',
1627
1744
  formatExplicit: true,
1628
1745
  name: path,
1629
- set(key: string, value: unknown) { varsMap[key] = value },
1746
+ set(key: string, value: unknown) {
1747
+ varsMap[key] = value
1748
+ },
1630
1749
  var: varsMap,
1631
1750
  version: undefined,
1632
1751
  }
1633
1752
  const composed = allMiddleware.reduceRight(
1634
- (next: () => Promise<void>, mw) => async () => { await mw(mwCtx, next) },
1753
+ (next: () => Promise<void>, mw) => async () => {
1754
+ await mw(mwCtx, next)
1755
+ },
1635
1756
  runCommand,
1636
1757
  )
1637
1758
  await composed()
@@ -1642,11 +1763,22 @@ async function executeCommand(
1642
1763
  const duration = `${Math.round(performance.now() - start)}ms`
1643
1764
  if (error instanceof ValidationError)
1644
1765
  return jsonResponse(
1645
- { ok: false, error: { code: 'VALIDATION_ERROR', message: error.message }, meta: { command: path, duration } },
1766
+ {
1767
+ ok: false,
1768
+ error: { code: 'VALIDATION_ERROR', message: error.message },
1769
+ meta: { command: path, duration },
1770
+ },
1646
1771
  400,
1647
1772
  )
1648
1773
  return jsonResponse(
1649
- { ok: false, error: { code: error instanceof IncurError ? error.code : 'UNKNOWN', message: error instanceof Error ? error.message : String(error) }, meta: { command: path, duration } },
1774
+ {
1775
+ ok: false,
1776
+ error: {
1777
+ code: error instanceof IncurError ? error.code : 'UNKNOWN',
1778
+ message: error instanceof Error ? error.message : String(error),
1779
+ },
1780
+ meta: { command: path, duration },
1781
+ },
1650
1782
  500,
1651
1783
  )
1652
1784
  }
@@ -1857,7 +1989,22 @@ function extractBuiltinFlags(argv: string[]) {
1857
1989
  else rest.push(token)
1858
1990
  }
1859
1991
 
1860
- return { verbose, format, formatExplicit, filterOutput, tokenLimit, tokenOffset, tokenCount, llms, llmsFull, mcp, help, version, schema, rest }
1992
+ return {
1993
+ verbose,
1994
+ format,
1995
+ formatExplicit,
1996
+ filterOutput,
1997
+ tokenLimit,
1998
+ tokenOffset,
1999
+ tokenCount,
2000
+ llms,
2001
+ llmsFull,
2002
+ mcp,
2003
+ help,
2004
+ version,
2005
+ schema,
2006
+ rest,
2007
+ }
1861
2008
  }
1862
2009
 
1863
2010
  /** @internal Collects immediate child commands/groups for help output. */
@@ -1991,8 +2138,9 @@ function formatHumanError(error: {
1991
2138
  /** @internal Formats a CTA block for human-readable TTY output. */
1992
2139
  function formatHumanCta(cta: FormattedCtaBlock): string {
1993
2140
  const lines: string[] = ['', cta.description]
2141
+ const maxLen = Math.max(...cta.commands.map((c) => c.command.length))
1994
2142
  for (const c of cta.commands) {
1995
- const desc = c.description ? ` # ${c.description}` : ''
2143
+ const desc = c.description ? ` ${''.padEnd(maxLen - c.command.length)}# ${c.description}` : ''
1996
2144
  lines.push(` ${c.command}${desc}`)
1997
2145
  }
1998
2146
  return lines.join('\n')
@@ -2073,7 +2221,8 @@ async function handleStreaming(
2073
2221
  }
2074
2222
  }
2075
2223
  if (useJsonl) ctx.writeln(JSON.stringify({ type: 'chunk', data: value }))
2076
- else if (ctx.renderOutput) ctx.writeln(ctx.truncate(Formatter.format(value, ctx.format)).text)
2224
+ else if (ctx.renderOutput)
2225
+ ctx.writeln(ctx.truncate(Formatter.format(value, ctx.format)).text)
2077
2226
  }
2078
2227
 
2079
2228
  // Handle return value — error() or ok() sentinel
package/src/Fetch.test.ts CHANGED
@@ -66,13 +66,7 @@ describe('parseArgv', () => {
66
66
  })
67
67
 
68
68
  test('multiple headers', () => {
69
- const input = Fetch.parseArgv([
70
- 'users',
71
- '-H',
72
- 'X-A: 1',
73
- '-H',
74
- 'X-B: 2',
75
- ])
69
+ const input = Fetch.parseArgv(['users', '-H', 'X-A: 1', '-H', 'X-B: 2'])
76
70
  expect(input.headers.get('X-A')).toBe('1')
77
71
  expect(input.headers.get('X-B')).toBe('2')
78
72
  })
@@ -123,16 +117,12 @@ describe('buildRequest', () => {
123
117
  })
124
118
 
125
119
  test('builds POST request with body', () => {
126
- const req = Fetch.buildRequest(
127
- Fetch.parseArgv(['users', '-X', 'POST', '-d', '{"name":"Bob"}']),
128
- )
120
+ const req = Fetch.buildRequest(Fetch.parseArgv(['users', '-X', 'POST', '-d', '{"name":"Bob"}']))
129
121
  expect(req.method).toBe('POST')
130
122
  })
131
123
 
132
124
  test('builds request with headers', () => {
133
- const req = Fetch.buildRequest(
134
- Fetch.parseArgv(['users', '-H', 'X-Api-Key: secret']),
135
- )
125
+ const req = Fetch.buildRequest(Fetch.parseArgv(['users', '-H', 'X-Api-Key: secret']))
136
126
  expect(req.headers.get('X-Api-Key')).toBe('secret')
137
127
  })
138
128
  })
package/src/Fetch.ts CHANGED
@@ -102,8 +102,7 @@ export function buildRequest(input: FetchInput): Request {
102
102
 
103
103
  if (input.body !== undefined) {
104
104
  init.body = input.body
105
- if (!input.headers.has('content-type'))
106
- input.headers.set('content-type', 'application/json')
105
+ if (!input.headers.has('content-type')) input.headers.set('content-type', 'application/json')
107
106
  }
108
107
 
109
108
  return new Request(url.toString(), init)
package/src/Filter.ts CHANGED
@@ -97,7 +97,12 @@ function resolve(data: unknown, segments: Segment[], index: number): unknown {
97
97
  return sliced.map((item) => resolve(item, segments, index + 1))
98
98
  }
99
99
 
100
- function merge(target: Record<string, unknown>, data: unknown, segments: Segment[], index: number): void {
100
+ function merge(
101
+ target: Record<string, unknown>,
102
+ data: unknown,
103
+ segments: Segment[],
104
+ index: number,
105
+ ): void {
101
106
  if (index >= segments.length || typeof data !== 'object' || data === null) return
102
107
  const segment = segments[index]!
103
108
 
@@ -129,8 +134,7 @@ function merge(target: Record<string, unknown>, data: unknown, segments: Segment
129
134
 
130
135
  // Next segment is a key — recurse into nested object
131
136
  if (typeof val !== 'object' || val === null) return
132
- if (!target[segment.key] || typeof target[segment.key] !== 'object')
133
- target[segment.key] = {}
137
+ if (!target[segment.key] || typeof target[segment.key] !== 'object') target[segment.key] = {}
134
138
  merge(target[segment.key] as Record<string, unknown>, val, segments, index + 1)
135
139
  return
136
140
  }
package/src/Help.test.ts CHANGED
@@ -29,7 +29,7 @@ describe('formatCommand', () => {
29
29
  --format <toon|json|yaml|md|jsonl> Output format
30
30
  --help Show help
31
31
  --llms, --llms-full Print LLM-readable manifest
32
- --schema Show JSON Schema for a command
32
+ --schema Show JSON Schema for command
33
33
  --token-count Print token count of output (instead of output)
34
34
  --token-limit <n> Limit output to n tokens
35
35
  --token-offset <n> Skip first n tokens of output
@@ -51,7 +51,7 @@ describe('formatCommand', () => {
51
51
  --format <toon|json|yaml|md|jsonl> Output format
52
52
  --help Show help
53
53
  --llms, --llms-full Print LLM-readable manifest
54
- --schema Show JSON Schema for a command
54
+ --schema Show JSON Schema for command
55
55
  --token-count Print token count of output (instead of output)
56
56
  --token-limit <n> Limit output to n tokens
57
57
  --token-offset <n> Skip first n tokens of output
@@ -80,7 +80,7 @@ describe('formatCommand', () => {
80
80
  --format <toon|json|yaml|md|jsonl> Output format
81
81
  --help Show help
82
82
  --llms, --llms-full Print LLM-readable manifest
83
- --schema Show JSON Schema for a command
83
+ --schema Show JSON Schema for command
84
84
  --token-count Print token count of output (instead of output)
85
85
  --token-limit <n> Limit output to n tokens
86
86
  --token-offset <n> Skip first n tokens of output
@@ -157,7 +157,7 @@ describe('formatRoot', () => {
157
157
  --format <toon|json|yaml|md|jsonl> Output format
158
158
  --help Show help
159
159
  --llms, --llms-full Print LLM-readable manifest
160
- --schema Show JSON Schema for a command
160
+ --schema Show JSON Schema for command
161
161
  --token-count Print token count of output (instead of output)
162
162
  --token-limit <n> Limit output to n tokens
163
163
  --token-offset <n> Skip first n tokens of output
@@ -182,7 +182,7 @@ describe('formatRoot', () => {
182
182
  --format <toon|json|yaml|md|jsonl> Output format
183
183
  --help Show help
184
184
  --llms, --llms-full Print LLM-readable manifest
185
- --schema Show JSON Schema for a command
185
+ --schema Show JSON Schema for command
186
186
  --token-count Print token count of output (instead of output)
187
187
  --token-limit <n> Limit output to n tokens
188
188
  --token-offset <n> Skip first n tokens of output
@@ -199,9 +199,9 @@ describe('formatRoot', () => {
199
199
  })
200
200
  expect(result).toMatchInlineSnapshot(`
201
201
  "my-tool@1.0.0 — A test CLI
202
- Aliases: mt, myt
203
202
 
204
203
  Usage: my-tool <command>
204
+ Aliases: mt, myt
205
205
 
206
206
  Commands:
207
207
  fetch Fetch a URL
@@ -211,7 +211,7 @@ describe('formatRoot', () => {
211
211
  --format <toon|json|yaml|md|jsonl> Output format
212
212
  --help Show help
213
213
  --llms, --llms-full Print LLM-readable manifest
214
- --schema Show JSON Schema for a command
214
+ --schema Show JSON Schema for command
215
215
  --token-count Print token count of output (instead of output)
216
216
  --token-limit <n> Limit output to n tokens
217
217
  --token-offset <n> Skip first n tokens of output
@@ -228,9 +228,9 @@ describe('formatRoot', () => {
228
228
  })
229
229
  expect(result).toMatchInlineSnapshot(`
230
230
  "my-tool@1.0.0 — A test CLI
231
- Aliases: mt, myt
232
231
 
233
232
  Usage: my-tool <url>
233
+ Aliases: mt, myt
234
234
 
235
235
  Arguments:
236
236
  url URL to fetch
@@ -240,7 +240,7 @@ describe('formatRoot', () => {
240
240
  --format <toon|json|yaml|md|jsonl> Output format
241
241
  --help Show help
242
242
  --llms, --llms-full Print LLM-readable manifest
243
- --schema Show JSON Schema for a command
243
+ --schema Show JSON Schema for command
244
244
  --token-count Print token count of output (instead of output)
245
245
  --token-limit <n> Limit output to n tokens
246
246
  --token-offset <n> Skip first n tokens of output