@dbx-tools/cli 0.1.103 → 0.1.105

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 CHANGED
@@ -1,4 +1,4 @@
1
- # @dbx-tools/dbxtools
1
+ # @dbx-tools/cli
2
2
 
3
3
  Scaffold, formatting, codegen, verification, build, and release helpers for Bun +
4
4
  workspaces monorepos. It wraps the shared `tsdown` config for building and a
@@ -8,7 +8,7 @@ orthogonal to writing package code.
8
8
  ## Installation
9
9
 
10
10
  ```bash
11
- bun add -d @dbx-tools/dbxtools
11
+ bun add -d @dbx-tools/cli
12
12
  ```
13
13
 
14
14
  Then point your root `package.json` scripts at the `dbxtools` bin for the helper
@@ -35,7 +35,7 @@ commands you want:
35
35
  | `dbxtools format` | `syncpack format`, regroup lifecycle hooks, then `prettier --write`. |
36
36
  | `dbxtools build` | Compile every publishable package with the shared `tsdown` config. |
37
37
  | `dbxtools codegen` | Regenerate each package's `generated/` zod tree from the `.d.ts` inputs its `package.json` declares. |
38
- | `dbxtools verify` | Fail on imports of sibling packages not declared as dependencies. |
38
+ | `dbxtools verify [--workspace-deps]` | Workspace verify pass; `--workspace-deps` fails on undeclared sibling imports. |
39
39
  | `dbxtools create [--plugin\|--shared] <slug>` | Scaffold a new package under `packages/<slug>/`. |
40
40
  | `dbxtools release [--dry-run]` | Build, then publish each package with a stamped (complete) manifest. |
41
41
  | `dbxtools tag [patch\|minor\|major]` | Version bump, commit, tag, push, and create a GitHub Release. `--notes-since v0.1.75` widens the notes baseline; default is the previous tag. `--no-ai-notes` skips Codex release notes. |
@@ -69,7 +69,7 @@ The same commands are exported as functions for projects that want to compose
69
69
  their own automation:
70
70
 
71
71
  ```ts
72
- import { build, codegen, create, release, tag, verify } from "@dbx-tools/dbxtools";
72
+ import { build, codegen, create, release, tag, verify } from "@dbx-tools/cli";
73
73
 
74
74
  await build();
75
75
  await codegen();
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env bun
2
- import { C as codegen, S as build, b as resolveAgentPrompt, d as release, f as format, g as agent, l as notesSinceRequested, n as forwardedUpdateArgs, p as create, s as update, t as verify, u as tag } from "../verify-CTCK1U-t.js";
2
+ import { C as codegen, S as build, b as resolveAgentPrompt, d as release, f as format, g as agent, l as notesSinceRequested, n as forwardedUpdateArgs, p as create, s as update, t as verify, u as tag } from "../verify-ZnM5Gb2r.js";
3
3
  import { Command, InvalidArgumentError } from "commander";
4
4
 
5
5
  //#region packages/cli/bin/dbxtools.ts
@@ -10,7 +10,9 @@ program.command("release").description("Build, then publish each package with a
10
10
  await release({ dryRun: opts.dryRun });
11
11
  });
12
12
  program.command("codegen").description("Regenerate each package's `generated/` zod tree from its inputs.").action(codegen);
13
- program.command("verify").description("Fail on imports of sibling packages not declared as dependencies.").action(verify);
13
+ program.command("verify").description("Workspace verify pass (optional sibling dependency scan).").option("--workspace-deps", "fail on imports of sibling packages not declared as dependencies", false).action(async (opts) => {
14
+ await verify({ workspaceDeps: opts.workspaceDeps });
15
+ });
14
16
  program.command("update").description("Pin root catalog entries to latest stable versions, then bun update at the repo root.").allowUnknownOption().action(async () => {
15
17
  await update(forwardedUpdateArgs());
16
18
  });
package/dist/index.d.ts CHANGED
@@ -4,6 +4,39 @@ import { FileSystemProject, Workspace } from "pacwich";
4
4
  /** Compile every publishable package with the shared tsdown config. */
5
5
  declare function build(): Promise<void>;
6
6
  //#endregion
7
+ //#region packages/cli/src/exec.d.ts
8
+ /**
9
+ * Subprocess helper with optional per-line stdout/stderr callbacks.
10
+ *
11
+ * Defaults to `Bun.spawn` so line callbacks stream as output arrives. Set
12
+ * `shell: true` to use Bun's cross-platform `$` shell (PATH resolution,
13
+ * Windows `.cmd` handling) when you do not need streaming line handlers.
14
+ *
15
+ * For capture-and-throw semantics, prefer {@link sh} / {@link bunx}.
16
+ */
17
+ type BunSpawnOptions = NonNullable<Parameters<typeof Bun.spawn>[1]>;
18
+ type ExecOptions = Omit<BunSpawnOptions, "stdin" | "stdout" | "stderr" | "stdio"> & {
19
+ stdin?: BunSpawnOptions["stdin"];
20
+ stdout?: BunSpawnOptions["stdout"] | ((line: string) => void);
21
+ stderr?: BunSpawnOptions["stderr"] | ((line: string) => void);
22
+ /**
23
+ * Run through Bun's `$` shell instead of `Bun.spawn`. Cross-platform
24
+ * command resolution; stdout/stderr echo to the terminal by default.
25
+ * Line callbacks are satisfied from buffered output after exit (Bun
26
+ * shell does not stream `.lines()` while the process runs).
27
+ */
28
+ shell?: boolean; /** Shell only: suppress live stdout/stderr echo (output is still buffered). */
29
+ quiet?: boolean;
30
+ };
31
+ /**
32
+ * Spawn a subprocess and wait for exit.
33
+ *
34
+ * Unset stdio fds default to `"inherit"`. Pass a function as `stdout` or
35
+ * `stderr` to receive each line; with the default `Bun.spawn` path that fd
36
+ * is piped and lines stream as they arrive.
37
+ */
38
+ declare function exec(command: string, args: string[], options?: ExecOptions): Promise<number>;
39
+ //#endregion
7
40
  //#region packages/cli/src/agent.d.ts
8
41
  /**
9
42
  * Run Codex headlessly via `ucode codex exec` for `dbxtools agent` and
@@ -242,7 +275,15 @@ declare function update(forwardArgs?: string[]): Promise<void>;
242
275
  declare function forwardedUpdateArgs(argv?: string[]): string[];
243
276
  //#endregion
244
277
  //#region packages/cli/src/verify.d.ts
245
- /** Fail when any workspace imports a sibling it doesn't declare as a dependency. */
246
- declare function verify(): Promise<void>;
278
+ /** Options for {@link verify}. */
279
+ interface VerifyOptions {
280
+ /**
281
+ * When true, fail on imports of sibling workspace packages not declared
282
+ * as dependencies. Off by default.
283
+ */
284
+ workspaceDeps?: boolean;
285
+ }
286
+ /** Workspace verify pass (optional implicit-dependency scan). */
287
+ declare function verify(options?: VerifyOptions): Promise<void>;
247
288
  //#endregion
248
- export { AGENT_DEFAULT_TIMEOUT_MS, type AgentCommandOptions, type AgentOptions, type AgentResult, type Bump, type CreateOptions, type DbxtoolsConfig, type PackageJson, type ReleaseOptions, type ShellResult, type TagOptions, WorkspacePackage, agent, agentAvailable, agentTimedOut, build, bunx, codegen, create, discoverPackageJsons, discoverPackages, errorMessage, fail, format, forwardedUpdateArgs, getDbxtoolsConfig, getProject, git, isStableVersion, latestStableInRange, nonEmptyLines, parseCodexStdout, release, resolveAgentPrompt, runAgent, runBunUpdate, sh, stableCaretRange, tag, toAbsolute, toRelative, update, updateCatalog, verify, writeJson };
289
+ export { AGENT_DEFAULT_TIMEOUT_MS, type AgentCommandOptions, type AgentOptions, type AgentResult, type Bump, type CreateOptions, type DbxtoolsConfig, type ExecOptions, type PackageJson, type ReleaseOptions, type ShellResult, type TagOptions, type VerifyOptions, WorkspacePackage, agent, agentAvailable, agentTimedOut, build, bunx, codegen, create, discoverPackageJsons, discoverPackages, errorMessage, exec, fail, format, forwardedUpdateArgs, getDbxtoolsConfig, getProject, git, isStableVersion, latestStableInRange, nonEmptyLines, parseCodexStdout, release, resolveAgentPrompt, runAgent, runBunUpdate, sh, stableCaretRange, tag, toAbsolute, toRelative, update, updateCatalog, verify, writeJson };
package/dist/index.js CHANGED
@@ -1,3 +1,103 @@
1
- import { A as git, C as codegen, D as toAbsolute, E as discoverPackages, F as nonEmptyLines, I as getProject, M as sh, N as errorMessage, O as toRelative, P as fail, S as build, T as discoverPackageJsons, _ as agentAvailable, a as runBunUpdate, b as resolveAgentPrompt, c as updateCatalog, d as release, f as format, g as agent, h as AGENT_DEFAULT_TIMEOUT_MS, i as latestStableInRange, j as bunx, k as writeJson, m as getDbxtoolsConfig, n as forwardedUpdateArgs, o as stableCaretRange, p as create, r as isStableVersion, s as update, t as verify, u as tag, v as agentTimedOut, w as WorkspacePackage, x as runAgent, y as parseCodexStdout } from "./verify-CTCK1U-t.js";
1
+ import { A as git, C as codegen, D as toAbsolute, E as discoverPackages, F as nonEmptyLines, I as getProject, M as sh, N as errorMessage, O as toRelative, P as fail, S as build, T as discoverPackageJsons, _ as agentAvailable, a as runBunUpdate, b as resolveAgentPrompt, c as updateCatalog, d as release, f as format, g as agent, h as AGENT_DEFAULT_TIMEOUT_MS, i as latestStableInRange, j as bunx, k as writeJson, m as getDbxtoolsConfig, n as forwardedUpdateArgs, o as stableCaretRange, p as create, r as isStableVersion, s as update, t as verify, u as tag, v as agentTimedOut, w as WorkspacePackage, x as runAgent, y as parseCodexStdout } from "./verify-ZnM5Gb2r.js";
2
+ import { $ } from "bun";
3
+ import * as readline from "node:readline";
4
+ import { Readable } from "node:stream";
2
5
 
3
- export { AGENT_DEFAULT_TIMEOUT_MS, WorkspacePackage, agent, agentAvailable, agentTimedOut, build, bunx, codegen, create, discoverPackageJsons, discoverPackages, errorMessage, fail, format, forwardedUpdateArgs, getDbxtoolsConfig, getProject, git, isStableVersion, latestStableInRange, nonEmptyLines, parseCodexStdout, release, resolveAgentPrompt, runAgent, runBunUpdate, sh, stableCaretRange, tag, toAbsolute, toRelative, update, updateCatalog, verify, writeJson };
6
+ //#region packages/cli/src/exec.ts
7
+ /**
8
+ * Subprocess helper with optional per-line stdout/stderr callbacks.
9
+ *
10
+ * Defaults to `Bun.spawn` so line callbacks stream as output arrives. Set
11
+ * `shell: true` to use Bun's cross-platform `$` shell (PATH resolution,
12
+ * Windows `.cmd` handling) when you do not need streaming line handlers.
13
+ *
14
+ * For capture-and-throw semantics, prefer {@link sh} / {@link bunx}.
15
+ */
16
+ /**
17
+ * Spawn a subprocess and wait for exit.
18
+ *
19
+ * Unset stdio fds default to `"inherit"`. Pass a function as `stdout` or
20
+ * `stderr` to receive each line; with the default `Bun.spawn` path that fd
21
+ * is piped and lines stream as they arrive.
22
+ */
23
+ async function exec(command, args, options = {}) {
24
+ if (options.shell) return execShell(command, args, options);
25
+ return execSpawn(command, args, options);
26
+ }
27
+ async function execSpawn(command, args, options) {
28
+ const { stdin, stdout, stderr, shell: _shell, quiet: _quiet, ...spawnOpts } = options;
29
+ const onStdout = typeof stdout === "function" ? stdout : void 0;
30
+ const onStderr = typeof stderr === "function" ? stderr : void 0;
31
+ const stdoutMode = typeof stdout === "function" ? "pipe" : stdout ?? "inherit";
32
+ const stderrMode = typeof stderr === "function" ? "pipe" : stderr ?? "inherit";
33
+ const proc = Bun.spawn([command, ...args], {
34
+ ...spawnOpts,
35
+ stdin: stdin ?? "inherit",
36
+ stdout: stdoutMode,
37
+ stderr: stderrMode
38
+ });
39
+ const reads = [];
40
+ if (onStdout && isReadableStream(proc.stdout)) reads.push(readLines(proc.stdout, onStdout));
41
+ if (onStderr && isReadableStream(proc.stderr)) reads.push(readLines(proc.stderr, onStderr));
42
+ try {
43
+ const exitCode = await proc.exited;
44
+ await Promise.all(reads);
45
+ return exitCode;
46
+ } catch (err) {
47
+ await Promise.allSettled(reads);
48
+ throw err;
49
+ }
50
+ }
51
+ async function execShell(command, args, options) {
52
+ const { cwd, env, quiet, stdout, stderr, stdin, shell: _shell, ..._spawnOnly } = options;
53
+ const onStdout = typeof stdout === "function" ? stdout : void 0;
54
+ const onStderr = typeof stderr === "function" ? stderr : void 0;
55
+ const argv = [command, ...args];
56
+ let cmd = typeof stdin === "string" ? $`${argv} < ${new Response(stdin)}`.nothrow() : $`${argv}`.nothrow();
57
+ if (cwd) cmd = cmd.cwd(cwd);
58
+ if (env) cmd = cmd.env(env);
59
+ if (quiet) cmd = cmd.quiet();
60
+ if (onStdout) {
61
+ const [res] = await Promise.all([cmd, (async () => {
62
+ for await (const line of cmd.lines()) onStdout(line);
63
+ })()]);
64
+ if (onStderr) emitBufferedLines(res.stderr.toString(), onStderr);
65
+ return res.exitCode;
66
+ }
67
+ const res = await cmd;
68
+ if (onStderr) emitBufferedLines(res.stderr.toString(), onStderr);
69
+ return res.exitCode;
70
+ }
71
+ function isReadableStream(value) {
72
+ return typeof value === "object" && value !== null && "getReader" in value;
73
+ }
74
+ async function readLines(stream, onLine) {
75
+ const rl = readline.createInterface({
76
+ input: Readable.fromWeb(stream),
77
+ crlfDelay: Infinity
78
+ });
79
+ for await (const line of rl) onLine(line);
80
+ }
81
+ function emitBufferedLines(text, onLine) {
82
+ if (text.length === 0) return;
83
+ const body = text.endsWith("\n") ? text.slice(0, -1) : text;
84
+ for (const line of body.split("\n")) onLine(line.endsWith("\r") ? line.slice(0, -1) : line);
85
+ }
86
+ if (import.meta.main) {
87
+ const useShell = process.argv.includes("--shell");
88
+ const [command, ...args] = process.argv.slice(2).filter((arg) => arg !== "--shell");
89
+ if (!command) {
90
+ console.error("Usage: exec [--shell] <command> [args...]");
91
+ process.exit(1);
92
+ }
93
+ const exitCode = await exec(command, args, {
94
+ shell: useShell,
95
+ stdout: (line) => console.log(line),
96
+ stderr: (line) => console.error(line)
97
+ });
98
+ console.log(`Exit code: ${exitCode}`);
99
+ process.exit(exitCode);
100
+ }
101
+
102
+ //#endregion
103
+ export { AGENT_DEFAULT_TIMEOUT_MS, WorkspacePackage, agent, agentAvailable, agentTimedOut, build, bunx, codegen, create, discoverPackageJsons, discoverPackages, errorMessage, exec, fail, format, forwardedUpdateArgs, getDbxtoolsConfig, getProject, git, isStableVersion, latestStableInRange, nonEmptyLines, parseCodexStdout, release, resolveAgentPrompt, runAgent, runBunUpdate, sh, stableCaretRange, tag, toAbsolute, toRelative, update, updateCatalog, verify, writeJson };
@@ -902,6 +902,22 @@ function resolveWorkspaceDeps(deps, siblingVersions) {
902
902
  }
903
903
  return next;
904
904
  }
905
+ /** Rewrite dev `bin` pointers (`./bin/foo.ts`) to built `dist` targets. */
906
+ function stampBin(meta) {
907
+ const bin = meta.bin;
908
+ if (!bin) return meta;
909
+ const stampTarget = (target) => /^\.\/bin\/[^/]+\.[cm]?tsx?$/.test(target) ? target.replace(/^\.\/bin\/(.+)\.[cm]?tsx?$/, "./dist/bin/$1.js") : target;
910
+ if (typeof bin === "string") return {
911
+ ...meta,
912
+ bin: stampTarget(bin)
913
+ };
914
+ const next = {};
915
+ for (const [name, target] of Object.entries(bin)) next[name] = stampTarget(target);
916
+ return {
917
+ ...meta,
918
+ bin: next
919
+ };
920
+ }
905
921
  /**
906
922
  * Return a publishable copy of `meta`: resolve `workspace:` sibling
907
923
  * pins to concrete versions (via `siblingVersions`), expand any source
@@ -941,7 +957,7 @@ function stampManifest(meta, siblingVersions) {
941
957
  stamped.license ??= DEFAULT_LICENSE;
942
958
  stamped.type ??= "module";
943
959
  if (typeof stamped.name === "string" && stamped.name.startsWith("@") && !stamped.publishConfig) stamped.publishConfig = { access: "public" };
944
- return stamped;
960
+ return stampBin(stamped);
945
961
  }
946
962
  /**
947
963
  * Build every publishable package, then publish each with a stamped
@@ -1356,7 +1372,7 @@ async function tag(opts = {}) {
1356
1372
  consola.log("Refreshing bun.lock to the bumped versions before local publish...");
1357
1373
  if ((await sh(["bun", "install"], { nothrow: true })).exitCode !== 0) consola.warn("bun install failed; skipping local publish so stale sibling pins aren't shipped. CI will publish from the tag.");
1358
1374
  else {
1359
- consola.log("Publishing packages to the local registry (bun run release)...");
1375
+ consola.log("Publishing packages to the local registry (bun dbxtools release)...");
1360
1376
  await sh([
1361
1377
  "bun",
1362
1378
  "run",
@@ -1476,9 +1492,13 @@ function forwardedUpdateArgs(argv = process.argv) {
1476
1492
 
1477
1493
  //#endregion
1478
1494
  //#region packages/cli/src/verify.ts
1479
- /** Fail when any workspace imports a sibling it doesn't declare as a dependency. */
1480
- async function verify() {
1495
+ /** Workspace verify pass (optional implicit-dependency scan). */
1496
+ async function verify(options = {}) {
1481
1497
  const project = await getProject();
1498
+ if (!options.workspaceDeps) {
1499
+ consola.log(`verify: ${project.workspaces.length} workspace(s) OK (skipped workspace dependency scan; pass --workspace-deps to enable)`);
1500
+ return;
1501
+ }
1482
1502
  const result = await project.verify({ strict: true });
1483
1503
  for (const issue of [...result.errors, ...result.warnings]) if (issue.level === "error") consola.error(issue.message);
1484
1504
  else consola.warn(issue.message);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dbx-tools/cli",
3
- "version": "0.1.103",
3
+ "version": "0.1.105",
4
4
  "bin": {
5
5
  "dbxtools": "./dist/bin/dbxtools.js"
6
6
  },