@hunt-labs/bytekit-cli 0.7.1 → 0.8.0

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/CHANGELOG.md CHANGED
@@ -10,6 +10,30 @@ today, see [README.md](./README.md), which remains the authoritative usage guide
10
10
 
11
11
  ## [Unreleased]
12
12
 
13
+ ## [0.8.0] - 2026-08-11
14
+
15
+ ### Added
16
+
17
+ - **Every outgoing request now carries `X-ByteKit-Client: cli/<version>`.** The CLI identifies
18
+ itself with the sanctioned `client_surface` marker (issue #2906, slice 3 of #2701), so `bytekit`
19
+ usage is distinguishable in ByteKit's own analytics from both raw API calls (`api_direct`) and
20
+ programmatic `@hunt-labs/bytekit-sdk` usage (`sdk_ts`) instead of being counted as one of them.
21
+ `cli` is a member of the closed `client_surface` vocabulary declared in issue #2904; the version
22
+ affix is this package's own version, resolved from `package.json` at runtime — the same value
23
+ `bytekit --version` prints.
24
+
25
+ Set at exactly ONE place — the header literal inside the private transport core all three CLI
26
+ transports funnel through — so it rides on every command, on the JSON path, on the raw
27
+ `/v1/fetch` path, and on the 429 retry attempt alike. **Nothing else about a request changed:**
28
+ same `Authorization` and `Content-Type`, same body bytes, same per-attempt abort budget, same
29
+ single-retry 429 behavior, same error taxonomy, same exit codes and output shapes. The marker
30
+ carries no user data and cannot be set, overridden or read from the command line — `--headers`
31
+ is a _scrape_ option that travels in the request body to the captured site, and never touches
32
+ the CLI's own request headers.
33
+
34
+ Minor rather than patch because the wire format of every request changes, even though no
35
+ documented command behavior does. A gateway that does not yet recognize the header ignores it.
36
+
13
37
  ## [0.7.1] - 2026-08-10
14
38
 
15
39
  ### Changed
package/dist/client.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import { ByteKit, ByteKitError, ByteKitConnectionError } from '@hunt-labs/bytekit-sdk';
2
+ import { PACKAGE_VERSION } from './package-version.js';
2
3
  /**
3
4
  * The API host the SDK itself defaults to. The SDK's copy is module-private, so the CLI declares
4
5
  * its own and always passes an explicit `baseUrl` to the constructor — that way the SDK client and
@@ -289,6 +290,26 @@ async function sendWithRetry(apiKey, baseUrl, timeoutMs, method, path, body, rea
289
290
  headers: {
290
291
  Authorization: `Bearer ${apiKey}`,
291
292
  'Content-Type': 'application/json',
293
+ // The `client_surface` marker (issue #2906, slice 3 of #2701). THE CLI'S ONLY EMIT SITE:
294
+ // all three CLI transports funnel through this function, and this literal is rebuilt
295
+ // inside the retry loop, so the 429 retry attempt carries it too (E4) without a second
296
+ // site to keep in sync.
297
+ //
298
+ // The header name below (`CLIENT_SURFACE_HEADER`) and the closed surface vocabulary
299
+ // (`CLIENT_SURFACES`) are declared in `@bytekit/analytics-contract` — deliberately spelled
300
+ // as literals here rather than imported, because that package must never become a runtime
301
+ // dependency of the published CLI (#2906 E6). `__tests__/client-surface-marker.test.ts`
302
+ // imports the contract as a TEST-ONLY devDependency and binds these literals to the
303
+ // registry, which is what keeps the two from drifting.
304
+ //
305
+ // Grep gate 1 (#2906) counts occurrences of the header name in `src/` outside tests and
306
+ // expects exactly ONE — so this comment names the CONSTANT rather than re-spelling the
307
+ // string, and the single occurrence below is the emit site itself.
308
+ //
309
+ // The version affix comes from the package manifest via the shared `PACKAGE_VERSION`
310
+ // helper — the same value commander reports for `--version` — never a second hardcoded
311
+ // version string.
312
+ 'X-ByteKit-Client': `cli/${PACKAGE_VERSION}`,
292
313
  },
293
314
  };
294
315
  if (body !== undefined) {
package/dist/index.js CHANGED
@@ -1,7 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import { Command } from 'commander';
3
3
  import { realpathSync } from 'node:fs';
4
- import { createRequire } from 'node:module';
5
4
  import { fileURLToPath } from 'node:url';
6
5
  import { makeScrapeCommand } from './commands/scrape.js';
7
6
  import { makeScreenshotsCommand } from './commands/screenshots.js';
@@ -13,12 +12,10 @@ import { makeSearchCommand } from './commands/search.js';
13
12
  import { makeAccountCommand } from './commands/account.js';
14
13
  import { makeUsageCommand } from './commands/usage.js';
15
14
  import { makeWebhookDeliveriesCommand } from './commands/webhook-deliveries.js';
16
- // Resolve version from package.json at runtime (supports compiled output).
17
- const require = createRequire(import.meta.url);
18
- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
19
- const pkg = require('../package.json');
20
- // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
21
- const version = typeof pkg.version === 'string' ? pkg.version : '0.1.0';
15
+ // Resolved from package.json at runtime (supports compiled output). Shared with `client.ts`'s
16
+ // `client_surface` marker (#2906) so `--version` and the emitted `cli/<version>` affix can never
17
+ // disagree.
18
+ import { PACKAGE_VERSION as version } from './package-version.js';
22
19
  /** Construct the root CLI program. Exported so tests can inspect identity/structure without parsing argv. */
23
20
  export function buildProgram() {
24
21
  const program = new Command();
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Fallback `'0.1.0'` is carried over verbatim from the pre-#2906 inline resolution in `index.ts`.
3
+ * It cannot be reached from a correctly packed tarball; it exists so a malformed manifest degrades
4
+ * to a parseable semver instead of `undefined` leaking into `--version` output or onto the wire.
5
+ */
6
+ export declare const PACKAGE_VERSION: string;
@@ -0,0 +1,31 @@
1
+ import { createRequire } from 'node:module';
2
+ /**
3
+ * This package's own version, resolved at runtime from `package.json`.
4
+ *
5
+ * Two consumers share it so the CLI can never report one version to `--version` and affix another
6
+ * to its outgoing `client_surface` marker: `index.ts` (commander's `.version()`) and `client.ts`
7
+ * (the `cli/<version>` marker header, issue #2906 — spelled once, at that emit site).
8
+ *
9
+ * THIS MODULE MUST STAY DIRECTLY UNDER `src/`. `tsconfig.json` sets `rootDir: ./src` and
10
+ * `outDir: ./dist`, so `src/package-version.ts` compiles to `dist/package-version.js` and the
11
+ * `../package.json` below resolves to the PACKAGE ROOT from both trees. A copy of this block under
12
+ * `src/lib/` would compile to `dist/lib/`, where `../package.json` resolves to `dist/package.json`
13
+ * — a path that does not exist in the published tarball (`files` ships `dist` + `CHANGELOG.md`,
14
+ * not the manifest at that depth). `__tests__/entrypoint.test.ts` spawns the BUILT `dist` entry
15
+ * with `--version` and asserts the output equals the manifest version, so that dist-depth
16
+ * resolution is proven by an existing live test rather than argued.
17
+ *
18
+ * `createRequire(import.meta.url)` rather than a JSON import: the package is `type: module` and
19
+ * import attributes are still not uniformly available across the `engines.node: >=18` floor.
20
+ */
21
+ const require = createRequire(import.meta.url);
22
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
23
+ const pkg = require('../package.json');
24
+ /**
25
+ * Fallback `'0.1.0'` is carried over verbatim from the pre-#2906 inline resolution in `index.ts`.
26
+ * It cannot be reached from a correctly packed tarball; it exists so a malformed manifest degrades
27
+ * to a parseable semver instead of `undefined` leaking into `--version` output or onto the wire.
28
+ */
29
+ export const PACKAGE_VERSION =
30
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
31
+ typeof pkg.version === 'string' ? pkg.version : '0.1.0';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hunt-labs/bytekit-cli",
3
- "version": "0.7.1",
3
+ "version": "0.8.0",
4
4
  "description": "ByteKit CLI — wraps @hunt-labs/bytekit-sdk as shell subcommands",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -41,7 +41,7 @@
41
41
  ],
42
42
  "dependencies": {
43
43
  "commander": "^12.0.0",
44
- "@hunt-labs/bytekit-sdk": "^0.6.1"
44
+ "@hunt-labs/bytekit-sdk": "^0.7.0"
45
45
  },
46
46
  "scripts": {
47
47
  "build": "rm -rf dist tsconfig.tsbuildinfo && tsc",