@dbx-tools/cli 0.1.112 → 0.3.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.
- package/.projen/deps.json +43 -0
- package/.projen/files.json +10 -0
- package/.projen/tasks.json +121 -0
- package/README.md +53 -67
- package/bin/dbxtools.ts +10 -0
- package/index.ts +8 -0
- package/package.json +41 -29
- package/src/bootstrap.ts +117 -0
- package/src/cli.ts +50 -0
- package/src/pnpm.ts +85 -0
- package/src/root.ts +80 -0
- package/test/tsconfig.json +14 -0
- package/tsconfig.json +43 -0
- package/dist/bin/dbxtools.d.ts +0 -1
- package/dist/bin/dbxtools.js +0 -55
- package/dist/index.d.ts +0 -289
- package/dist/index.js +0 -103
- package/dist/verify-ZnM5Gb2r.js +0 -1510
package/src/root.ts
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Workspace root detection for the `dbxtools` CLI.
|
|
3
|
+
*/
|
|
4
|
+
import { existsSync } from "node:fs";
|
|
5
|
+
import { basename, dirname, join, resolve } from "node:path";
|
|
6
|
+
import { exec } from "@dbx-tools/core";
|
|
7
|
+
import { functionModule } from "@dbx-tools/shared-core";
|
|
8
|
+
|
|
9
|
+
async function gitToplevel(): Promise<string | undefined> {
|
|
10
|
+
const { exitCode, stdout } = await exec.spawn("git", ["rev-parse", "--show-toplevel"], {
|
|
11
|
+
stdout: "capture",
|
|
12
|
+
stderr: "ignore",
|
|
13
|
+
stdin: "ignore",
|
|
14
|
+
});
|
|
15
|
+
if (exitCode !== 0) return undefined;
|
|
16
|
+
return stdout || undefined;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Walk upward from `startDir` for `.projenrc.ts`. If none is found, try git
|
|
21
|
+
* top-level only when that directory also contains `.projenrc.ts`; otherwise return
|
|
22
|
+
* `resolve(startDir)` (which may not be a workspace root).
|
|
23
|
+
*/
|
|
24
|
+
export async function findWorkspaceRoot(startDir: string = process.cwd()): Promise<string> {
|
|
25
|
+
let dir = resolve(startDir);
|
|
26
|
+
while (true) {
|
|
27
|
+
if (existsSync(join(dir, ".projenrc.ts"))) return dir;
|
|
28
|
+
const parent = dirname(dir);
|
|
29
|
+
if (parent === dir) break;
|
|
30
|
+
dir = parent;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const fromGit = await gitToplevel();
|
|
34
|
+
if (fromGit && existsSync(join(fromGit, ".projenrc.ts"))) return fromGit;
|
|
35
|
+
|
|
36
|
+
return resolve(startDir);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* True when the folder has no `.projenrc.ts` yet and needs full bootstrapping.
|
|
41
|
+
* Keying off `.projenrc.ts` (not `package.json`) avoids clobbering a cleaned
|
|
42
|
+
* workspace that still has a hand-authored projenrc.
|
|
43
|
+
*/
|
|
44
|
+
export function needsBootstrap(root: string): boolean {
|
|
45
|
+
return !existsSync(join(root, ".projenrc.ts"));
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/** True when `node_modules` or projen itself is missing under `root`. */
|
|
49
|
+
export function needsInstall(root: string): boolean {
|
|
50
|
+
if (!existsSync(join(root, "node_modules"))) return true;
|
|
51
|
+
if (existsSync(join(root, ".projenrc.ts")) && !existsSync(join(root, "node_modules", "projen"))) {
|
|
52
|
+
return true;
|
|
53
|
+
}
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* True when the synth TOOLCHAIN isn't installed yet: no `node_modules`, or the
|
|
59
|
+
* dbx-tools engine / `projen` aren't resolvable under it. Distinct from a full
|
|
60
|
+
* bootstrap (which keys off a MISSING `.projenrc.ts`): here the projenrc exists
|
|
61
|
+
* but its dependencies don't - e.g. a copied project whose generated manifests
|
|
62
|
+
* and `node_modules` are gitignored. Seeding the toolchain (not scaffolding)
|
|
63
|
+
* makes it synth-ready without touching the hand-authored `.projenrc.ts`.
|
|
64
|
+
*/
|
|
65
|
+
export function needsToolchain(root: string): boolean {
|
|
66
|
+
const modules = join(root, "node_modules");
|
|
67
|
+
if (!existsSync(modules)) return true;
|
|
68
|
+
return (
|
|
69
|
+
!existsSync(join(modules, "projen")) ||
|
|
70
|
+
!existsSync(join(modules, "@dbx-tools", "projen"))
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/** Async, memoized root lookup from the process cwd at first use. */
|
|
75
|
+
export const workspaceRoot = functionModule.memoize(() => findWorkspaceRoot());
|
|
76
|
+
|
|
77
|
+
/** Short label for log output (`basename` of the resolved root). */
|
|
78
|
+
export function rootLabel(root: string): string {
|
|
79
|
+
return basename(root) || root;
|
|
80
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
// ~~ Generated by projen. To modify, edit .projenrc.js and run "pnpm exec projen".
|
|
2
|
+
{
|
|
3
|
+
"extends": "../tsconfig.json",
|
|
4
|
+
"compilerOptions": {
|
|
5
|
+
"noEmit": true,
|
|
6
|
+
"rootDir": ".."
|
|
7
|
+
},
|
|
8
|
+
"include": [
|
|
9
|
+
"**/*.ts"
|
|
10
|
+
],
|
|
11
|
+
"exclude": [
|
|
12
|
+
"node_modules"
|
|
13
|
+
]
|
|
14
|
+
}
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
// ~~ Generated by projen. To modify, edit .projenrc.js and run "pnpm exec projen".
|
|
2
|
+
{
|
|
3
|
+
"compilerOptions": {
|
|
4
|
+
"rootDir": ".",
|
|
5
|
+
"outDir": "lib",
|
|
6
|
+
"alwaysStrict": true,
|
|
7
|
+
"declaration": true,
|
|
8
|
+
"esModuleInterop": true,
|
|
9
|
+
"experimentalDecorators": true,
|
|
10
|
+
"inlineSourceMap": true,
|
|
11
|
+
"inlineSources": true,
|
|
12
|
+
"lib": [
|
|
13
|
+
"ES2022"
|
|
14
|
+
],
|
|
15
|
+
"module": "ESNext",
|
|
16
|
+
"noEmitOnError": false,
|
|
17
|
+
"noFallthroughCasesInSwitch": true,
|
|
18
|
+
"noImplicitAny": true,
|
|
19
|
+
"noImplicitReturns": true,
|
|
20
|
+
"noImplicitThis": true,
|
|
21
|
+
"noUnusedLocals": true,
|
|
22
|
+
"noUnusedParameters": true,
|
|
23
|
+
"resolveJsonModule": true,
|
|
24
|
+
"strict": true,
|
|
25
|
+
"strictNullChecks": true,
|
|
26
|
+
"strictPropertyInitialization": true,
|
|
27
|
+
"stripInternal": true,
|
|
28
|
+
"target": "ES2022",
|
|
29
|
+
"types": [
|
|
30
|
+
"node"
|
|
31
|
+
],
|
|
32
|
+
"moduleResolution": "bundler",
|
|
33
|
+
"skipLibCheck": true
|
|
34
|
+
},
|
|
35
|
+
"include": [
|
|
36
|
+
"src/**/*.ts",
|
|
37
|
+
"index.ts",
|
|
38
|
+
"bin/**/*.ts"
|
|
39
|
+
],
|
|
40
|
+
"exclude": [
|
|
41
|
+
"node_modules"
|
|
42
|
+
]
|
|
43
|
+
}
|
package/dist/bin/dbxtools.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { };
|
package/dist/bin/dbxtools.js
DELETED
|
@@ -1,55 +0,0 @@
|
|
|
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-ZnM5Gb2r.js";
|
|
3
|
-
import { Command, InvalidArgumentError } from "commander";
|
|
4
|
-
|
|
5
|
-
//#region packages/cli/bin/dbxtools.ts
|
|
6
|
-
const program = new Command().name("dbxtools").description("Workspace build, scaffold, and release toolkit for Bun monorepos.");
|
|
7
|
-
program.command("format").description("syncpack format, regroup lifecycle hooks, then prettier --write.").action(format);
|
|
8
|
-
program.command("build").description("Compile every publishable package with the shared tsdown config.").action(build);
|
|
9
|
-
program.command("release").description("Build, then publish each package with a stamped (complete) manifest.").option("-n, --dry-run", "rehearse with `bun publish --dry-run`", false).action(async (opts) => {
|
|
10
|
-
await release({ dryRun: opts.dryRun });
|
|
11
|
-
});
|
|
12
|
-
program.command("codegen").description("Regenerate each package's `generated/` zod tree from its inputs.").action(codegen);
|
|
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
|
-
});
|
|
16
|
-
program.command("update").description("Pin root catalog entries to latest stable versions, then bun update at the repo root.").allowUnknownOption().action(async () => {
|
|
17
|
-
await update(forwardedUpdateArgs());
|
|
18
|
-
});
|
|
19
|
-
program.command("create").description("Scaffold a new workspace package under packages/<slug>/.").argument("<slug>", "kebab-case slug (lowercase, starts with a letter)", (value) => {
|
|
20
|
-
if (!/^[a-z][a-z0-9-]*$/.test(value)) throw new InvalidArgumentError(`invalid slug "${value}"`);
|
|
21
|
-
return value;
|
|
22
|
-
}).option("--plugin", "scaffold an AppKit plugin package").option("--shared", "scaffold a browser-safe shared package").action(async (slug, opts) => {
|
|
23
|
-
await create({
|
|
24
|
-
slug,
|
|
25
|
-
plugin: opts.plugin,
|
|
26
|
-
shared: opts.shared
|
|
27
|
-
});
|
|
28
|
-
});
|
|
29
|
-
program.command("agent").description("Run ucode codex exec with assistant output.").argument("[prompt...]", "prompt text (or pipe via stdin when omitted)").option("-t, --timeout <seconds>", "wall-clock budget in seconds (default 300)", (value) => {
|
|
30
|
-
const seconds = Number(value);
|
|
31
|
-
if (!Number.isFinite(seconds) || seconds <= 0) throw new InvalidArgumentError("timeout must be a positive number");
|
|
32
|
-
return Math.round(seconds * 1e3);
|
|
33
|
-
}).action(async (promptParts, opts) => {
|
|
34
|
-
const code = await agent({
|
|
35
|
-
prompt: await resolveAgentPrompt(promptParts),
|
|
36
|
-
timeoutMs: opts.timeout
|
|
37
|
-
});
|
|
38
|
-
if (code !== 0) process.exit(code);
|
|
39
|
-
});
|
|
40
|
-
program.command("tag").description("Bump every workspace, commit, tag HEAD, and push to origin.").argument("[bump]", "version bump (patch | minor | major)", (value) => {
|
|
41
|
-
if (value !== "patch" && value !== "minor" && value !== "major") throw new InvalidArgumentError("expected patch, minor, or major");
|
|
42
|
-
return value;
|
|
43
|
-
}, "patch").option("--no-publish", "skip publishing the tagged versions to the local registry").option("-n, --dry-run", "print the plan and release-notes preview; write nothing, push nothing", false).option("--notes-since <tag>", "widen release-notes baseline to this tag (e.g. v0.1.75); default is the previous tag on HEAD").option("--no-ai-notes", "skip ucode codex; use commit-grouped notes only").action(async (bump, opts) => {
|
|
44
|
-
await tag({
|
|
45
|
-
bump,
|
|
46
|
-
dryRun: opts.dryRun,
|
|
47
|
-
publish: opts.publish,
|
|
48
|
-
aiNotes: opts.aiNotes,
|
|
49
|
-
...notesSinceRequested(opts.notesSince) ? { notesSince: opts.notesSince } : {}
|
|
50
|
-
});
|
|
51
|
-
});
|
|
52
|
-
await program.parseAsync(process.argv);
|
|
53
|
-
|
|
54
|
-
//#endregion
|
|
55
|
-
export { };
|
package/dist/index.d.ts
DELETED
|
@@ -1,289 +0,0 @@
|
|
|
1
|
-
import { FileSystemProject, Workspace } from "pacwich";
|
|
2
|
-
|
|
3
|
-
//#region packages/cli/src/build.d.ts
|
|
4
|
-
/** Compile every publishable package with the shared tsdown config. */
|
|
5
|
-
declare function build(): Promise<void>;
|
|
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
|
|
40
|
-
//#region packages/cli/src/agent.d.ts
|
|
41
|
-
/**
|
|
42
|
-
* Run Codex headlessly via `ucode codex exec` for `dbxtools agent` and
|
|
43
|
-
* release tooling that drafts notes programmatically.
|
|
44
|
-
*/
|
|
45
|
-
/** Default wall-clock budget for a Codex invocation. */
|
|
46
|
-
declare const AGENT_DEFAULT_TIMEOUT_MS = 300000;
|
|
47
|
-
/** Options for {@link runAgent}. */
|
|
48
|
-
interface AgentOptions {
|
|
49
|
-
/** Wall-clock budget in milliseconds. */
|
|
50
|
-
timeoutMs?: number;
|
|
51
|
-
/** Working directory for the agent (defaults to `process.cwd()`). */
|
|
52
|
-
cwd?: string;
|
|
53
|
-
/**
|
|
54
|
-
* When `true` (default), capture stdout via `sh({ quiet: true })` for
|
|
55
|
-
* programmatic callers. When `false`, inherit stdio like
|
|
56
|
-
* `ucode codex exec …` in a shell.
|
|
57
|
-
*/
|
|
58
|
-
capture?: boolean;
|
|
59
|
-
/**
|
|
60
|
-
* When `true` (default) and `capture` is enabled, write the parsed
|
|
61
|
-
* assistant text to stdout. Set `false` when the caller will log the
|
|
62
|
-
* result itself (e.g. release-notes drafting).
|
|
63
|
-
*/
|
|
64
|
-
echo?: boolean;
|
|
65
|
-
}
|
|
66
|
-
/** Outcome of {@link runAgent}. */
|
|
67
|
-
interface AgentResult {
|
|
68
|
-
/** Trimmed assistant answer. */
|
|
69
|
-
text: string;
|
|
70
|
-
/** Subprocess exit code. */
|
|
71
|
-
exitCode: number;
|
|
72
|
-
/** Trimmed stderr. */
|
|
73
|
-
stderr: string;
|
|
74
|
-
}
|
|
75
|
-
/** Options for {@link agent}. */
|
|
76
|
-
interface AgentCommandOptions {
|
|
77
|
-
/** Prompt passed to `ucode codex exec`. */
|
|
78
|
-
prompt: string;
|
|
79
|
-
/** Wall-clock budget in milliseconds. */
|
|
80
|
-
timeoutMs?: number;
|
|
81
|
-
}
|
|
82
|
-
/** Whether `ucode codex --version` reports a usable Codex CLI. */
|
|
83
|
-
declare function agentAvailable(): Promise<boolean>;
|
|
84
|
-
/** Whether an exit code looks like the process was killed on a timeout. */
|
|
85
|
-
declare function agentTimedOut(exitCode: number): boolean;
|
|
86
|
-
/** Pull assistant prose out of `ucode codex exec` stdout. */
|
|
87
|
-
declare function parseCodexStdout(stdout: string): string;
|
|
88
|
-
/**
|
|
89
|
-
* Run `ucode codex exec` and return captured output. Throws when Codex
|
|
90
|
-
* is absent or the wall-clock budget is exceeded. On a non-zero exit
|
|
91
|
-
* the result is still returned so callers can use partial text.
|
|
92
|
-
*/
|
|
93
|
-
declare function runAgent(prompt: string, opts?: AgentOptions): Promise<AgentResult>;
|
|
94
|
-
/**
|
|
95
|
-
* `dbxtools agent` entry: run Codex and return a process exit code (0 on
|
|
96
|
-
* success, 1 on failure or timeout).
|
|
97
|
-
*/
|
|
98
|
-
declare function agent(opts: AgentCommandOptions): Promise<number>;
|
|
99
|
-
/** Join argv prompt parts, or read stdin when non-interactive and args are empty. */
|
|
100
|
-
declare function resolveAgentPrompt(promptParts: string[]): Promise<string>;
|
|
101
|
-
//#endregion
|
|
102
|
-
//#region packages/cli/src/codegen.d.ts
|
|
103
|
-
/** Regenerate the `generated/` tree for every package declaring a `codegen` field. */
|
|
104
|
-
declare function codegen(): Promise<void>;
|
|
105
|
-
//#endregion
|
|
106
|
-
//#region packages/cli/src/config.d.ts
|
|
107
|
-
/** Resolved toolkit configuration for the current repo. */
|
|
108
|
-
interface DbxtoolsConfig {
|
|
109
|
-
/** npm scope (e.g. `@acme`) used when scaffolding new packages. */
|
|
110
|
-
scope: string;
|
|
111
|
-
/** `owner/name` slug used for release links, or null when undiscoverable. */
|
|
112
|
-
repo: string | null;
|
|
113
|
-
/**
|
|
114
|
-
* Name of the shared-helpers package `create` wires as a dependency
|
|
115
|
-
* into new plugin / standard packages (when it exists in the
|
|
116
|
-
* workspace). Defaults to `<scope>/shared`, or null when no scope
|
|
117
|
-
* resolves.
|
|
118
|
-
*/
|
|
119
|
-
sharedPackage: string | null;
|
|
120
|
-
}
|
|
121
|
-
/**
|
|
122
|
-
* Resolve toolkit config for the current repo, memoized for the
|
|
123
|
-
* process. Overrides under the root `package.json` `dbxtools` key win
|
|
124
|
-
* over the auto-derived defaults.
|
|
125
|
-
*/
|
|
126
|
-
declare const getDbxtoolsConfig: () => Promise<DbxtoolsConfig>;
|
|
127
|
-
//#endregion
|
|
128
|
-
//#region packages/cli/src/create.d.ts
|
|
129
|
-
/** Options for {@link create}. */
|
|
130
|
-
interface CreateOptions {
|
|
131
|
-
/** kebab-case slug (lowercase, starts with a letter). */
|
|
132
|
-
slug: string;
|
|
133
|
-
/** Scaffold an AppKit plugin package. */
|
|
134
|
-
plugin?: boolean;
|
|
135
|
-
/** Scaffold a browser-safe shared package. */
|
|
136
|
-
shared?: boolean;
|
|
137
|
-
}
|
|
138
|
-
/** Scaffold a new workspace package under `packages/<slug>/`. */
|
|
139
|
-
declare function create(options: CreateOptions): Promise<void>;
|
|
140
|
-
//#endregion
|
|
141
|
-
//#region packages/cli/src/format.d.ts
|
|
142
|
-
/** syncpack + lifecycle-hook regroup + prettier across the workspace. */
|
|
143
|
-
declare function format(): Promise<void>;
|
|
144
|
-
//#endregion
|
|
145
|
-
//#region packages/cli/src/shell.d.ts
|
|
146
|
-
interface ShellResult {
|
|
147
|
-
exitCode: number;
|
|
148
|
-
stdout: string;
|
|
149
|
-
stderr: string;
|
|
150
|
-
}
|
|
151
|
-
interface ShellOptions {
|
|
152
|
-
/** Return the result on non-zero exit instead of throwing. */
|
|
153
|
-
nothrow?: boolean;
|
|
154
|
-
/** Working directory for the command. */
|
|
155
|
-
cwd?: string;
|
|
156
|
-
/** String piped to the command's stdin. */
|
|
157
|
-
input?: string;
|
|
158
|
-
/** Suppress the live echo. Output is still captured on the result. */
|
|
159
|
-
quiet?: boolean;
|
|
160
|
-
}
|
|
161
|
-
/**
|
|
162
|
-
* Run a command, streaming live unless `quiet`. Returns trimmed captured
|
|
163
|
-
* output regardless. Throws on non-zero unless `nothrow`.
|
|
164
|
-
*/
|
|
165
|
-
declare function sh(args: string[], opts?: ShellOptions): Promise<ShellResult>;
|
|
166
|
-
/** `bun x <args>` for one-off CLI tools (knip, syncpack, prettier, ...). */
|
|
167
|
-
declare function bunx(args: string[], opts?: ShellOptions): Promise<ShellResult>;
|
|
168
|
-
//#endregion
|
|
169
|
-
//#region packages/cli/src/git.d.ts
|
|
170
|
-
/**
|
|
171
|
-
* Run `git <args>`, returning trimmed output. Quiet by default since git is
|
|
172
|
-
* used mostly for its stdout (rev-parse, log, diff, ...); pass `quiet: false`
|
|
173
|
-
* to stream a mutating op live. Throws on non-zero unless `nothrow`.
|
|
174
|
-
*/
|
|
175
|
-
declare function git(args: string[], opts?: {
|
|
176
|
-
nothrow?: boolean;
|
|
177
|
-
quiet?: boolean;
|
|
178
|
-
cwd?: string;
|
|
179
|
-
}): Promise<ShellResult>;
|
|
180
|
-
//#endregion
|
|
181
|
-
//#region packages/cli/src/package.d.ts
|
|
182
|
-
/** Minimal package.json shape the commands care about. */
|
|
183
|
-
interface PackageJson {
|
|
184
|
-
name?: string;
|
|
185
|
-
version?: string;
|
|
186
|
-
private?: boolean;
|
|
187
|
-
workspaces?: string[];
|
|
188
|
-
[key: string]: unknown;
|
|
189
|
-
}
|
|
190
|
-
/** A workspace package: its parsed manifest, location, and dependency edges. */
|
|
191
|
-
declare class WorkspacePackage {
|
|
192
|
-
readonly meta: PackageJson;
|
|
193
|
-
readonly dir: string;
|
|
194
|
-
readonly slug: string;
|
|
195
|
-
readonly jsonPath: string;
|
|
196
|
-
private constructor();
|
|
197
|
-
/** Build from a pacwich {@link Workspace}, reading its manifest. */
|
|
198
|
-
static fromWorkspace(ws: Workspace): Promise<WorkspacePackage>;
|
|
199
|
-
}
|
|
200
|
-
/** Resolve `path` against the repo root. */
|
|
201
|
-
declare function toAbsolute(path: string): string;
|
|
202
|
-
/** Repo-relative form of `path`, or absolute when it sits outside the root. */
|
|
203
|
-
declare function toRelative(path: string): string;
|
|
204
|
-
/** Yield every workspace `package.json` path (`includeRoot` prepends the root manifest). */
|
|
205
|
-
declare function discoverPackageJsons(includeRoot?: boolean): AsyncIterableIterator<string>;
|
|
206
|
-
/** Workspace packages passing `filter` (default: non-private), sorted by slug. */
|
|
207
|
-
declare function discoverPackages(filter?: (pkg: WorkspacePackage) => boolean): Promise<WorkspacePackage[]>;
|
|
208
|
-
/** Write `value` as JSON, preserving the file's trailing newline to avoid format churn. */
|
|
209
|
-
declare function writeJson(path: string, value: unknown): Promise<void>;
|
|
210
|
-
//#endregion
|
|
211
|
-
//#region packages/cli/src/project.d.ts
|
|
212
|
-
declare const getProject: () => Promise<FileSystemProject>;
|
|
213
|
-
//#endregion
|
|
214
|
-
//#region packages/cli/src/release.d.ts
|
|
215
|
-
/** Options for {@link release}. */
|
|
216
|
-
interface ReleaseOptions {
|
|
217
|
-
/** Rehearse with `bun publish --dry-run` instead of publishing. */
|
|
218
|
-
dryRun?: boolean;
|
|
219
|
-
}
|
|
220
|
-
/**
|
|
221
|
-
* Build every publishable package, then publish each with a stamped
|
|
222
|
-
* (complete) `package.json`, restoring the slim source manifest after
|
|
223
|
-
* each publish whether it succeeds or fails.
|
|
224
|
-
*/
|
|
225
|
-
declare function release(opts?: ReleaseOptions): Promise<void>;
|
|
226
|
-
//#endregion
|
|
227
|
-
//#region packages/cli/src/script.d.ts
|
|
228
|
-
/** Log `message` and exit non-zero. */
|
|
229
|
-
declare function fail(message: string): never;
|
|
230
|
-
/** Narrow an unknown thrown value to its message string. */
|
|
231
|
-
declare function errorMessage(err: unknown): string;
|
|
232
|
-
/** Split text on newlines, trimming each line and dropping blanks. */
|
|
233
|
-
declare function nonEmptyLines(text: string): string[];
|
|
234
|
-
//#endregion
|
|
235
|
-
//#region packages/cli/src/tag.d.ts
|
|
236
|
-
type Bump = "major" | "minor" | "patch";
|
|
237
|
-
/** Options for {@link tag}. */
|
|
238
|
-
interface TagOptions {
|
|
239
|
-
/** Version bump (defaults to `patch`). */
|
|
240
|
-
bump?: Bump;
|
|
241
|
-
/** Print everything, write nothing. */
|
|
242
|
-
dryRun?: boolean;
|
|
243
|
-
/** Publish the tagged versions to the local registry (default true). */
|
|
244
|
-
publish?: boolean;
|
|
245
|
-
/**
|
|
246
|
-
* When set, widen the release-notes baseline to this tag instead of
|
|
247
|
-
* the latest tag on `HEAD` (e.g. `v0.1.75` when several recent tags
|
|
248
|
-
* failed to publish). Omit to use the previous tag only.
|
|
249
|
-
*/
|
|
250
|
-
notesSince?: string;
|
|
251
|
-
/** When false, skip Codex and use commit-grouped notes only. */
|
|
252
|
-
aiNotes?: boolean;
|
|
253
|
-
}
|
|
254
|
-
/**
|
|
255
|
-
* Version-bump every publishable workspace, commit, tag, push, create
|
|
256
|
-
* the GitHub Release (with generated notes), and publish to the local
|
|
257
|
-
* registry. See the file header for the full local-state policy.
|
|
258
|
-
*/
|
|
259
|
-
declare function tag(opts?: TagOptions): Promise<void>;
|
|
260
|
-
//#endregion
|
|
261
|
-
//#region packages/cli/src/update.d.ts
|
|
262
|
-
/** True when `version` is a release with no prerelease segment. */
|
|
263
|
-
declare function isStableVersion(version: string): boolean;
|
|
264
|
-
/** Highest stable version in `versions` that satisfies `range`. */
|
|
265
|
-
declare function latestStableInRange(versions: string[], range: string): string | null;
|
|
266
|
-
/** Rewrite a single range (or `latest`) to a caret pin on the latest stable match. */
|
|
267
|
-
declare function stableCaretRange(versions: string[], range: string): string;
|
|
268
|
-
/** Refresh every root `catalog` entry to the latest stable release in-range. */
|
|
269
|
-
declare function updateCatalog(): Promise<boolean>;
|
|
270
|
-
/** Run `bun update` with `forwardArgs` at the repo root. */
|
|
271
|
-
declare function runBunUpdate(forwardArgs: string[]): Promise<void>;
|
|
272
|
-
/** Refresh catalog pins, then `bun update` at the repo root. */
|
|
273
|
-
declare function update(forwardArgs?: string[]): Promise<void>;
|
|
274
|
-
/** Args after the `update` subcommand in `process.argv`. */
|
|
275
|
-
declare function forwardedUpdateArgs(argv?: string[]): string[];
|
|
276
|
-
//#endregion
|
|
277
|
-
//#region packages/cli/src/verify.d.ts
|
|
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>;
|
|
288
|
-
//#endregion
|
|
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
DELETED
|
@@ -1,103 +0,0 @@
|
|
|
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";
|
|
5
|
-
|
|
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 };
|