argsbarg 5.1.10 → 5.1.12

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
@@ -7,6 +7,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [5.1.12] - 2026-07-05
11
+
12
+ ### Changed
13
+
14
+ - **`scripts/dev-formula.ts`** — `install` stages a `file://` dev formula; `reset` restores the release formula. `just install-local` orchestrates stage → `brew install` → reset.
15
+
16
+ ## [5.1.11] - 2026-07-05
17
+
18
+
10
19
  ## [5.1.10] - 2026-07-05
11
20
 
12
21
  ### Added
@@ -656,7 +665,9 @@ const cli = { ... } satisfies CliProgram; // or : CliProgram
656
665
  - Migrate schemas: rename every `children` property to **`commands`**; move positional definitions to **`CliPositional`** objects on `positionals` and strip `positional` / `argMin` / `argMax` from flag definitions under `options` (flags only carry `name`, `description`, `kind`, and optional `shortName`).
657
666
  - Imports: use `CliPositional` where needed; replace `CliOptionDef` with `CliOption` or `CliPositional` as appropriate.
658
667
 
659
- [Unreleased]: https://github.com/bdombro/bun-argsbarg/compare/v5.1.10...HEAD
668
+ [Unreleased]: https://github.com/bdombro/bun-argsbarg/compare/v5.1.12...HEAD
669
+ [5.1.12]: https://github.com/bdombro/bun-argsbarg/releases/tag/v5.1.12
670
+ [5.1.11]: https://github.com/bdombro/bun-argsbarg/releases/tag/v5.1.11
660
671
  [5.1.10]: https://github.com/bdombro/bun-argsbarg/releases/tag/v5.1.10
661
672
  [5.1.9]: https://github.com/bdombro/bun-argsbarg/releases/tag/v5.1.9
662
673
  [5.1.8]: https://github.com/bdombro/bun-argsbarg/releases/tag/v5.1.8
package/README.md CHANGED
@@ -266,7 +266,7 @@ To refresh the Cursor rule in an existing consumer: `bun scripts/merge-cli-progr
266
266
  | Command layout | `src/commands/<name>/command.ts`; registration in `src/program.ts` |
267
267
  | MCP doc topics | `docs.topics` auto-exposed as `<key>://docs/<topic>` resources when docs + MCP enabled |
268
268
  | Package import | `from "argsbarg"` (not relative to argsbarg `src/`) |
269
- | Homebrew distribution | `scripts/formula-shared.ts`, `scripts/with-dev-formula.ts`, `Formula/`, `justfile` |
269
+ | Homebrew distribution | `scripts/formula-shared.ts`, `scripts/dev-formula.ts`, `Formula/`, `justfile` |
270
270
  | Dev tooling | Biome (`just format` / `just lint`), TypeScript, colocated tests |
271
271
  | Cursor rules | `.cursor/rules/cli-program.mdc`, `.cursor/rules/code.mdc` |
272
272
 
@@ -48,7 +48,15 @@ just reinstall-local # fast binary swap (`install -m 755` into Cellar; run ins
48
48
  just uninstall # undo formula + agent artifacts (app config removed by formula uninstall)
49
49
  ```
50
50
 
51
- Dev and release use the **same formula file** (`Formula/{key}.rb`, class name, install/post_install/test). `just install-local` temporarily overwrites it with a `file://` dev formula (staged under `Formula/.staging/`), runs `brew install`, then **restores** the release formula from backup. Release bumps rewrite the GitHub URL via `scripts/release.ts`.
51
+ Dev and release use the **same formula file** (`Formula/{key}.rb`). `just install-local` runs:
52
+
53
+ ```bash
54
+ bun scripts/dev-formula.ts install # back up release formula, write file:// dev formula
55
+ brew install --formula <tap>/{key} # install from the dev formula
56
+ bun scripts/dev-formula.ts reset # restore release formula
57
+ ```
58
+
59
+ If `brew install` fails, run `bun scripts/dev-formula.ts reset` manually to restore the release formula.
52
60
 
53
61
  ### Developer uninstall
54
62
 
@@ -45,12 +45,14 @@ install: install-local
45
45
  sync-artifacts:
46
46
  just run configure --sync --yes
47
47
 
48
- # Dev install: build, dev formula (restored after brew), symlink tap, brew install
48
+ # Dev install: build, stage dev formula, brew install, restore release formula
49
49
  install-local: build
50
50
  @brew untap {{tap}} 2>/dev/null || true
51
51
  mkdir -p {{tap_parent}}
52
52
  ln -sfn '{{justfile_directory()}}' {{tap_path}}
53
- bun scripts/with-dev-formula.ts -- brew install --formula {{tap}}/{{cli_key}}
53
+ bun scripts/dev-formula.ts install
54
+ brew install --formula {{tap}}/{{cli_key}}
55
+ bun scripts/dev-formula.ts reset
54
56
  @echo ""
55
57
  @echo "Next: {{cli_key}} configure"
56
58
 
@@ -0,0 +1,97 @@
1
+ #!/usr/bin/env bun
2
+ /**
3
+ * Stage or restore the dev Homebrew formula for `just install-local`.
4
+ * `install` — back up release `Formula/{key}.rb` and write a `file://` dev formula.
5
+ * `reset` — restore the release formula from backup.
6
+ */
7
+
8
+ import { createHash } from "node:crypto";
9
+ import { chmodSync, copyFileSync, existsSync, mkdirSync, readFileSync, unlinkSync, writeFileSync } from "node:fs";
10
+ import { join } from "node:path";
11
+ import { createIdentity } from "./create-identity.ts";
12
+ import { renderDevFormula } from "./formula-shared.ts";
13
+
14
+ const { key } = createIdentity;
15
+ const root = join(import.meta.dir, "..");
16
+ const stagingDir = join(root, "Formula", ".staging");
17
+ const stagingPath = join(stagingDir, key);
18
+ const formulaPath = join(root, "Formula", `${key}.rb`);
19
+ const backupPath = join(stagingDir, `${key}.rb.bak`);
20
+ const programPath = join(root, "src/program.ts");
21
+
22
+ type Command = "install" | "reset";
23
+
24
+ function usage(): never {
25
+ process.stderr.write("Usage: bun scripts/dev-formula.ts <install|reset>\n");
26
+ process.exit(1);
27
+ }
28
+
29
+ function parseCommand(argv: string[]): Command {
30
+ const cmd = argv[2];
31
+ if (cmd === "install" || cmd === "reset") {
32
+ return cmd;
33
+ }
34
+ usage();
35
+ }
36
+
37
+ function backupReleaseFormula(): void {
38
+ if (!existsSync(formulaPath)) {
39
+ return;
40
+ }
41
+ mkdirSync(stagingDir, { recursive: true });
42
+ copyFileSync(formulaPath, backupPath);
43
+ }
44
+
45
+ function restoreReleaseFormula(): void {
46
+ if (!existsSync(backupPath)) {
47
+ return;
48
+ }
49
+ copyFileSync(backupPath, formulaPath);
50
+ unlinkSync(backupPath);
51
+ }
52
+
53
+ function readVersion(): string {
54
+ const content = readFileSync(programPath, "utf8");
55
+ const match = /version:\s*"([^"]+)"/.exec(content);
56
+ if (!match?.[1]) {
57
+ process.stderr.write(`Could not read version from ${programPath}\n`);
58
+ process.exit(1);
59
+ }
60
+ return match[1];
61
+ }
62
+
63
+ function stageDevFormula(): void {
64
+ const distPath = join(root, "dist", key);
65
+ if (!existsSync(distPath)) {
66
+ process.stderr.write(`Missing binary: ${distPath} (run just build first)\n`);
67
+ process.exit(1);
68
+ }
69
+ mkdirSync(stagingDir, { recursive: true });
70
+ copyFileSync(distPath, stagingPath);
71
+ chmodSync(stagingPath, 0o755);
72
+
73
+ const sha256 = createHash("sha256").update(readFileSync(stagingPath)).digest("hex");
74
+ writeFileSync(formulaPath, renderDevFormula(stagingPath, readVersion(), sha256), "utf8");
75
+ }
76
+
77
+ function install(): void {
78
+ backupReleaseFormula();
79
+ stageDevFormula();
80
+ console.log(`Wrote dev formula: ${formulaPath}`);
81
+ }
82
+
83
+ function reset(): void {
84
+ if (!existsSync(backupPath)) {
85
+ console.log("No dev formula backup to restore.");
86
+ return;
87
+ }
88
+ restoreReleaseFormula();
89
+ console.log(`Restored ${formulaPath}`);
90
+ }
91
+
92
+ const command = parseCommand(process.argv);
93
+ if (command === "install") {
94
+ install();
95
+ } else {
96
+ reset();
97
+ }
@@ -29,15 +29,19 @@ function generateJson(root: SchemaRoot): Record<string, unknown> {
29
29
  }
30
30
 
31
31
  function writeBridge(path: string, scriptName: string, roots: SchemaRoot[], banner: string): void {
32
+ /** Sort by import binding so Biome `organizeImports` does not reorder the bridge file. */
33
+ const sorted = [...roots].sort((left, right) =>
34
+ jsonImportVar(left.outfile).localeCompare(jsonImportVar(right.outfile)),
35
+ );
32
36
  const lines = [`// Auto-generated by scripts/${scriptName} — do not edit by hand.`, ""];
33
- for (const root of roots) {
37
+ for (const root of sorted) {
34
38
  const varName = jsonImportVar(root.outfile);
35
39
  lines.push(`import ${varName} from "./generated/${root.outfile}";`);
36
40
  }
37
- if (roots.length > 0) {
41
+ if (sorted.length > 0) {
38
42
  lines.push("");
39
43
  }
40
- for (const root of roots) {
44
+ for (const root of sorted) {
41
45
  const varName = jsonImportVar(root.outfile);
42
46
  lines.push(`/** ${banner} \`${root.typeName}\`. */`);
43
47
  lines.push(`export const ${root.exportName} = ${varName} as Record<string, unknown>;`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "argsbarg",
3
- "version": "5.1.10",
3
+ "version": "5.1.12",
4
4
  "type": "module",
5
5
  "engines": {
6
6
  "bun": ">=1.3"
@@ -1,79 +0,0 @@
1
- #!/usr/bin/env bun
2
-
3
- /** Back up release formula, write dev formula, run a command, then restore. Usage: bun scripts/with-dev-formula.ts -- brew install … */
4
-
5
- import { spawnSync } from "node:child_process";
6
- import { createHash } from "node:crypto";
7
- import { chmodSync, copyFileSync, existsSync, mkdirSync, readFileSync, unlinkSync, writeFileSync } from "node:fs";
8
- import { join } from "node:path";
9
- import { createIdentity } from "./create-identity.ts";
10
- import { renderDevFormula } from "./formula-shared.ts";
11
-
12
- const { key } = createIdentity;
13
- const root = join(import.meta.dir, "..");
14
- const stagingDir = join(root, "Formula", ".staging");
15
- const stagingPath = join(stagingDir, key);
16
- const formulaPath = join(root, "Formula", `${key}.rb`);
17
- const backupPath = join(stagingDir, `${key}.rb.bak`);
18
-
19
- function backupReleaseFormula(): void {
20
- if (!existsSync(formulaPath)) {
21
- return;
22
- }
23
- mkdirSync(stagingDir, { recursive: true });
24
- copyFileSync(formulaPath, backupPath);
25
- }
26
-
27
- function restoreReleaseFormula(): void {
28
- if (!existsSync(backupPath)) {
29
- return;
30
- }
31
- copyFileSync(backupPath, formulaPath);
32
- unlinkSync(backupPath);
33
- }
34
-
35
- function writeDevFormula(): void {
36
- const distPath = join(root, "dist", key);
37
- mkdirSync(stagingDir, { recursive: true });
38
- copyFileSync(distPath, stagingPath);
39
- chmodSync(stagingPath, 0o755);
40
-
41
- const sha256 = createHash("sha256").update(readFileSync(stagingPath)).digest("hex");
42
- const version = JSON.parse(readFileSync(join(root, "package.json"), "utf8")).version as string;
43
- writeFileSync(formulaPath, renderDevFormula(stagingPath, version, sha256), "utf8");
44
- }
45
-
46
- const sep = process.argv.indexOf("--");
47
- if (sep === -1 || sep === process.argv.length - 1) {
48
- process.stderr.write("Usage: bun scripts/with-dev-formula.ts -- <command...>\n");
49
- process.exit(1);
50
- }
51
-
52
- const cmd = process.argv.slice(sep + 1);
53
- const executable = cmd[0];
54
- if (!executable) {
55
- process.stderr.write("Usage: bun scripts/with-dev-formula.ts -- <command...>\n");
56
- process.exit(1);
57
- }
58
- let restored = false;
59
-
60
- function restore(): void {
61
- if (restored) {
62
- return;
63
- }
64
- restored = true;
65
- restoreReleaseFormula();
66
- }
67
-
68
- try {
69
- backupReleaseFormula();
70
- writeDevFormula();
71
- const result = spawnSync(executable, cmd.slice(1), { stdio: "inherit" });
72
- process.exitCode = result.status === null ? 1 : result.status;
73
- } finally {
74
- restore();
75
- }
76
-
77
- if (process.exitCode === 0) {
78
- console.log(`Restored ${formulaPath}`);
79
- }