opencode-homebrew-agent 1.0.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.
Files changed (60) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +175 -0
  3. package/agents/brew.md +146 -0
  4. package/package.json +22 -0
  5. package/src/AGENTS.md +172 -0
  6. package/src/scripts/brew-analyze.sh +373 -0
  7. package/src/scripts/brew-deps.sh +140 -0
  8. package/src/scripts/brew-env.sh +288 -0
  9. package/src/scripts/brew-search.sh +150 -0
  10. package/src/scripts/brew-template.sh +263 -0
  11. package/src/scripts/package.json +21 -0
  12. package/src/skills/homebrew-agent/SKILL.md +203 -0
  13. package/src/skills/homebrew-tap/SKILL.md +97 -0
  14. package/src/templates/taps/01-full-ci/AGENTS.md +71 -0
  15. package/src/templates/taps/01-full-ci/tap-structure/.github/workflows/autobump.yml +24 -0
  16. package/src/templates/taps/01-full-ci/tap-structure/.github/workflows/publish.yml +33 -0
  17. package/src/templates/taps/01-full-ci/tap-structure/.github/workflows/tests.yml +33 -0
  18. package/src/templates/taps/01-full-ci/tap-structure/Formula/_formula.rb +31 -0
  19. package/src/templates/taps/01-full-ci/tap-structure/README.md +27 -0
  20. package/src/templates/taps/01-full-ci/tap-structure/cmd/.gitkeep +0 -0
  21. package/src/templates/taps/01-full-ci/tap-structure/formula_renames.json +1 -0
  22. package/src/templates/taps/01-full-ci/tap-structure/lib/.gitkeep +0 -0
  23. package/src/templates/taps/01-full-ci/tap-structure/require/.gitkeep +0 -0
  24. package/src/templates/taps/01-full-ci/tap-structure/tap_migrations.json +1 -0
  25. package/src/templates/taps/01-full-ci/template.md +45 -0
  26. package/src/templates/taps/02-root-level/AGENTS.md +72 -0
  27. package/src/templates/taps/02-root-level/tap-structure/README.md +27 -0
  28. package/src/templates/taps/02-root-level/tap-structure/_formula.rb +29 -0
  29. package/src/templates/taps/02-root-level/template.md +35 -0
  30. package/src/templates/taps/03-simple-script/AGENTS.md +71 -0
  31. package/src/templates/taps/03-simple-script/tap-structure/Formula/_formula.rb +27 -0
  32. package/src/templates/taps/03-simple-script/tap-structure/README.md +27 -0
  33. package/src/templates/taps/03-simple-script/tap-structure/scripts/release.rb +46 -0
  34. package/src/templates/taps/03-simple-script/template.md +41 -0
  35. package/src/templates/taps/04-python-venv/AGENTS.md +83 -0
  36. package/src/templates/taps/04-python-venv/tap-structure/Formula/_formula.rb +57 -0
  37. package/src/templates/taps/04-python-venv/tap-structure/README.md +27 -0
  38. package/src/templates/taps/04-python-venv/tap-structure/scripts/release.rb +44 -0
  39. package/src/templates/taps/04-python-venv/template.md +58 -0
  40. package/src/templates/taps/05-node-npm/AGENTS.md +90 -0
  41. package/src/templates/taps/05-node-npm/tap-structure/Formula/_formula.rb +46 -0
  42. package/src/templates/taps/05-node-npm/tap-structure/README.md +27 -0
  43. package/src/templates/taps/05-node-npm/tap-structure/scripts/release.rb +40 -0
  44. package/src/templates/taps/05-node-npm/template.md +74 -0
  45. package/src/templates/taps/06-keg-only/AGENTS.md +82 -0
  46. package/src/templates/taps/06-keg-only/tap-structure/Formula/_formula.rb +45 -0
  47. package/src/templates/taps/06-keg-only/tap-structure/README.md +27 -0
  48. package/src/templates/taps/06-keg-only/template.md +60 -0
  49. package/src/templates/taps/07-cask-only/AGENTS.md +97 -0
  50. package/src/templates/taps/07-cask-only/tap-structure/Casks/_app.rb +26 -0
  51. package/src/templates/taps/07-cask-only/tap-structure/README.md +27 -0
  52. package/src/templates/taps/07-cask-only/template.md +58 -0
  53. package/src/templates/taps/08-go-binary/AGENTS.md +86 -0
  54. package/src/templates/taps/08-go-binary/tap-structure/Formula/_formula.rb +40 -0
  55. package/src/templates/taps/08-go-binary/tap-structure/README.md +27 -0
  56. package/src/templates/taps/08-go-binary/tap-structure/scripts/release.rb +38 -0
  57. package/src/templates/taps/08-go-binary/template.md +60 -0
  58. package/src/workflows/analyze-source.sh +124 -0
  59. package/src/workflows/convert-npm-to-bun.sh +112 -0
  60. package/src/workflows/create-tap.sh +196 -0
@@ -0,0 +1,27 @@
1
+ # <Tap Name>
2
+
3
+ Homebrew tap for <formula>.
4
+
5
+ ## Install
6
+
7
+ ```sh
8
+ brew tap <user>/<tapname>
9
+ brew install <formula>
10
+ ```
11
+
12
+ ## Upgrade
13
+
14
+ ```sh
15
+ brew upgrade <formula>
16
+ ```
17
+
18
+ ## Uninstall
19
+
20
+ ```sh
21
+ brew uninstall <formula>
22
+ brew untap <user>/<tapname>
23
+ ```
24
+
25
+ ## License
26
+
27
+ MIT
@@ -0,0 +1,29 @@
1
+
2
+ # Root-level formula — place this file at the repository root.
3
+ # Replace <formula>, <description>, <url>, <sha256> with real values.
4
+ # IMPORTANT: Rename class <Formula> to CamelCase matching the filename (e.g., MyTool for my-tool.rb).
5
+
6
+ class <Formula> < Formula
7
+ desc "<one-line description>"
8
+ homepage "https://github.com/<user>/<repo>"
9
+ url "https://github.com/<user>/<repo>/archive/refs/tags/v<version>.tar.gz"
10
+ sha256 "<sha256>"
11
+ version "<version>"
12
+ license "MIT"
13
+
14
+ livecheck do
15
+ url :stable
16
+ regex(/^v?(\d+(?:\.\d+)+)$/i)
17
+ end
18
+
19
+ depends_on "<dep>"
20
+
21
+ def install
22
+ system "<build-command>"
23
+ bin.install "<binary>"
24
+ end
25
+
26
+ test do
27
+ assert_match "<expected>", shell_output("#{bin}/<cli> --help")
28
+ end
29
+ end
@@ -0,0 +1,35 @@
1
+ # Template 02: Root-Level `.rb`
2
+
3
+ ## Pattern: `yakitrak/homebrew-yakitrak`
4
+
5
+ A minimal tap with formula files at the repository root. No `Formula/`
6
+ subdirectory, no CI, no scripts. Best for **1-2 formula taps** where
7
+ simplicity is king.
8
+
9
+ ### Structure
10
+
11
+ ```
12
+ homebrew-<tap>/
13
+ ├── <formula>.rb # Formula at root (no Formula/ dir)
14
+ ├── LICENSE
15
+ └── README.md
16
+ ```
17
+
18
+ ### When to Use
19
+
20
+ - You have 1-2 simple formulae
21
+ - You don't need CI in the tap
22
+ - You want the absolute minimum structure
23
+
24
+ ### When NOT to Use
25
+
26
+ - You need CI/bottle workflows (use template 01)
27
+ - You need script-driven releases (use template 03)
28
+ - You need Python virtualenv deps (use template 04)
29
+
30
+ ### Reference
31
+
32
+ - `brew install <user>/<tap>/<formula>` works regardless of file location
33
+ - Homebrew scans root, `Formula/`, and `HomebrewFormula/` for `.rb` files
34
+
35
+ - Start with `brew tap-new <user>/homebrew-<tapname>` to generate the CI skeleton (optional — manual structure works too)
@@ -0,0 +1,71 @@
1
+ ---
2
+ name: homebrew-tap-simple-script
3
+ description: Creates and maintains lean Homebrew taps with script-driven release automation (oven-sh/homebrew-bun pattern).
4
+ ---
5
+
6
+ # homebrew-tap-simple-script
7
+
8
+ Agent for working with Simple + Script tap templates.
9
+
10
+ ## Description
11
+ Helps create and maintain lean Homebrew taps with script-driven release automation and optional versioned formula aliases.
12
+
13
+ ## Stacks
14
+ - homebrew
15
+ - ruby
16
+ - scripts
17
+
18
+ ## Requires
19
+ - basic-homebrew-knowledge
20
+
21
+ ## Key Actions
22
+
23
+ ### Release Script Pattern
24
+ The `scripts/release.rb` takes a version tag, fetches release assets, computes SHA256s, and rewrites the formula. Modeled on `oven-sh/homebrew-bun/scripts/release.rb`.
25
+
26
+ ### Versioned Formulae
27
+ Optionally create `Formula/<formula>@X.Y.Z.rb` aliases by copying the main formula with a modified class name (e.g., `class BunAT1314` for version `1.3.14`).
28
+
29
+ ### Permissions
30
+ - Read/write to `Formula/` and `scripts/`
31
+ - Network access for downloading release assets
32
+
33
+ ### Common Pitfalls
34
+
35
+ - After running `release.rb`, always `git diff` to verify version/SHA substitution worked.
36
+ - The release script hardcodes `_formula.rb`. If you rename the file, update the `FORMULA_FILE` path.
37
+ - `class <Formula>` must be replaced with the actual formula class name (e.g., `class MyTool < Formula`).
38
+ - For pre-built binary formulae, use versioned aliases (`formula@X.Y.Z.rb`) for rollback support.
39
+ - `ruby release.rb` without arguments prints usage. Always pass a version tag (e.g., `ruby release.rb 1.2.3`).
40
+
41
+ ### LSP Validation
42
+
43
+ Before finishing any formula, validate with the Ruby LSP:
44
+
45
+ 1. Ensure LSP is available:
46
+ ```sh
47
+ ruby-lsp --version # Verify LSP is installed
48
+ ```
49
+ 2. Run syntax check:
50
+ ```sh
51
+ ruby -c Formula/<formula>.rb
52
+ ```
53
+ 3. Run Homebrew linting:
54
+ ```sh
55
+ brew style --tap <user>/<tapname> Formula/<formula>.rb
56
+ ```
57
+ 4. Run formula audit:
58
+ ```sh
59
+ brew audit --new-formula Formula/<formula>.rb
60
+ ```
61
+
62
+ Do NOT mark work as complete until all diagnostics pass.
63
+
64
+ ### Verification
65
+ ```sh
66
+ ruby -c scripts/release.rb
67
+ ruby -c Formula/<formula>.rb
68
+ # Dry-run release:
69
+ ruby scripts/release.rb <version>
70
+ git diff # Verify changes
71
+ ```
@@ -0,0 +1,27 @@
1
+
2
+ # Simple formula with script-driven release (oven-sh/homebrew-bun pattern).
3
+ # Replace <formula>, <description>, <url>, <sha256> with real values.
4
+ # IMPORTANT: Rename class <Formula> to CamelCase matching the filename (e.g., MyTool for my-tool.rb).
5
+
6
+ class <Formula> < Formula
7
+ desc "<one-line description>"
8
+ homepage "https://github.com/<user>/<repo>"
9
+ url "https://github.com/<user>/<repo>/archive/refs/tags/v<version>.tar.gz"
10
+ sha256 "<sha256>"
11
+ version "<version>"
12
+ license "MIT"
13
+
14
+ livecheck do
15
+ url :stable
16
+ regex(/^v?(\d+(?:\.\d+)+)$/i)
17
+ end
18
+
19
+ def install
20
+ system "<build-command>"
21
+ bin.install "<binary>"
22
+ end
23
+
24
+ test do
25
+ assert_match "<expected>", shell_output("#{bin}/<cli> --version")
26
+ end
27
+ end
@@ -0,0 +1,27 @@
1
+ # <Tap Name>
2
+
3
+ Homebrew tap for <formula>.
4
+
5
+ ## Install
6
+
7
+ ```sh
8
+ brew tap <user>/<tapname>
9
+ brew install <formula>
10
+ ```
11
+
12
+ ## Upgrade
13
+
14
+ ```sh
15
+ brew upgrade <formula>
16
+ ```
17
+
18
+ ## Uninstall
19
+
20
+ ```sh
21
+ brew uninstall <formula>
22
+ brew untap <user>/<tapname>
23
+ ```
24
+
25
+ ## License
26
+
27
+ MIT
@@ -0,0 +1,46 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ # Release script modeled on oven-sh/homebrew-bun/scripts/release.rb.
5
+ # Usage: ruby scripts/release.rb <version>
6
+ #
7
+ # Fetches the release tarball, computes SHA256, and rewrites Formula/<formula>.rb.
8
+
9
+ require "open-uri"
10
+ require "digest"
11
+
12
+ TAP_DIR = File.dirname(__dir__)
13
+ FORMULA_FILE = File.join(TAP_DIR, "Formula", "_formula.rb") # rename to your formula name
14
+
15
+ def usage
16
+ puts "Usage: ruby scripts/release.rb <version>"
17
+ puts " e.g., ruby scripts/release.rb 1.2.3"
18
+ exit 1
19
+ end
20
+
21
+ def fetch_sha256(url)
22
+ uri = URI.parse(url)
23
+ puts " Downloading #{url}..."
24
+ content = URI.open(uri).read
25
+ Digest::SHA256.hexdigest(content)
26
+ end
27
+
28
+ version = ARGV.first || usage()
29
+
30
+ tarball_url = "https://github.com/<user>/<repo>/archive/refs/tags/v#{version}.tar.gz"
31
+
32
+ puts "Updating Formula/<formula>.rb to version #{version}..."
33
+
34
+ sha = fetch_sha256(tarball_url)
35
+
36
+ formula_content = File.read(FORMULA_FILE)
37
+
38
+ # Replace version and sha256
39
+ formula_content.sub!(/version "\d+\.\d+\.\d+"/, "version \"#{version}\"")
40
+ formula_content.sub!(/sha256 "[0-9a-f]{64}"/, "sha256 \"#{sha}\"")
41
+
42
+ File.write(FORMULA_FILE, formula_content)
43
+
44
+ puts "Done. Formula updated to v#{version}."
45
+ puts
46
+ puts "Review changes with: git diff Formula/<formula>.rb"
@@ -0,0 +1,41 @@
1
+ # Template 03: Simple + Script
2
+
3
+ ## Pattern: `oven-sh/homebrew-bun`
4
+
5
+ A lean tap with a `Formula/` subdirectory and a `scripts/release.rb` for
6
+ version bumps. No CI in the tap — releases are script-driven. Best for
7
+ **single-formula taps** where releases are manual or triggered externally.
8
+
9
+ ### Structure
10
+
11
+ ```
12
+ homebrew-<tap>/
13
+ ├── Formula/
14
+ │ ├── <formula>.rb # Latest version (overwritten on release)
15
+ │ └── <formula>@X.Y.Z.rb # (optional) Versioned aliases for rollback
16
+ ├── scripts/
17
+ │ └── release.rb # Version bump script
18
+ ├── .gitignore
19
+ ├── LICENSE
20
+ └── README.md
21
+ ```
22
+
23
+ ### When to Use
24
+
25
+ - You have a single formula (binary or script)
26
+ - You want a simple, script-driven release process
27
+ - You don't need CI in the tap itself
28
+ - You want versioned formula aliases for rollback support
29
+
30
+ ### When NOT to Use
31
+
32
+ - You need CI/bottle workflows (use template 01)
33
+ - Your formula needs Python virtualenv (use template 04)
34
+
35
+ ### Reference
36
+
37
+ - `scripts/release.rb` takes version, fetches assets, rewrites formula
38
+ - Versioned aliases (`<formula>@X.Y.Z.rb`) enable `brew install <formula>@1.2.3`
39
+ - See `oven-sh/homebrew-bun/scripts/release.rb` for the reference implementation
40
+
41
+ - Start with `brew tap-new <user>/homebrew-<tapname>` to generate the CI skeleton (optional — manual structure works too)
@@ -0,0 +1,83 @@
1
+ ---
2
+ name: homebrew-tap-python-venv
3
+ description: Creates and maintains Homebrew taps for Python CLI tools with pip dependencies in a virtualenv (bendzgerona/homebrew-litellm pattern).
4
+ ---
5
+
6
+ # homebrew-tap-python-venv
7
+
8
+ Agent for working with Python Virtualenv tap templates.
9
+
10
+ ## Description
11
+ Helps create and maintain Homebrew taps for Python CLI tools with pip dependencies installed in a Homebrew-managed virtualenv.
12
+
13
+ ## Stacks
14
+ - homebrew
15
+ - python
16
+ - ruby
17
+
18
+ ## Requires
19
+ - basic-homebrew-knowledge
20
+
21
+ ## Key Actions
22
+
23
+ ### Formula Structure
24
+ ```ruby
25
+ include Language::Python::Virtualenv
26
+ depends_on "python@3.13" # Pin to avoid brew's default
27
+ depends_on "openssl@3"
28
+ depends_on "pkgconf" => :build
29
+ ```
30
+
31
+ ### Install Pattern
32
+ ```ruby
33
+ venv = virtualenv_create(libexec, "python3.13")
34
+ venv.pip_install buildpath # Install the package itself
35
+ system venv.root/"bin/pip", "install", "package[extras]==#{version}"
36
+ ```
37
+
38
+ ### Post-Install Notice
39
+ Use `def caveats` to instruct users about optional deps, service setup, and separate agent/config installation.
40
+
41
+ ### Permissions
42
+ - Read/write to `Formula/` and `scripts/`
43
+ - Network access for pip installs
44
+ - `python@3.X` must be declared as dep (auto-installed)
45
+
46
+ ### Common Pitfalls
47
+
48
+ - `python@3.13` must match what is available in homebrew-core. Pin to a version that actually exists.
49
+ - Brew's Python packages (uvicorn, fastapi, pydantic) all depend on brew's default python — incompatible with pinned venvs.
50
+ - `virtualenv_create` sets up a Homebrew-managed venv. Do NOT use `python3 -m venv` instead.
51
+ - `pip_install` may fail if wheels need compilation. Add `depends_on "pkgconf" => :build` and `depends_on "openssl@3"`.
52
+ - The `service` block runs `libexec/bin/<cli>` — ensure the symlink target is correct or the service will fail silently.
53
+
54
+ ### LSP Validation
55
+
56
+ Before finishing any formula, validate with the Ruby LSP:
57
+
58
+ 1. Ensure LSP is available:
59
+ ```sh
60
+ ruby-lsp --version # Verify LSP is installed
61
+ ```
62
+ 2. Run syntax check:
63
+ ```sh
64
+ ruby -c Formula/<formula>.rb
65
+ ```
66
+ 3. Run Homebrew linting:
67
+ ```sh
68
+ brew style --tap <user>/<tapname> Formula/<formula>.rb
69
+ ```
70
+ 4. Run formula audit:
71
+ ```sh
72
+ brew audit --new-formula Formula/<formula>.rb
73
+ ```
74
+
75
+ Do NOT mark work as complete until all diagnostics pass.
76
+
77
+ ### Verification
78
+ ```sh
79
+ brew sh --ruby
80
+ ruby -c Formula/<formula>.rb
81
+ brew style --tap <user>/<tapname> Formula/<formula>.rb
82
+ brew audit --new-formula Formula/<formula>.rb
83
+ ```
@@ -0,0 +1,57 @@
1
+
2
+ # Python virtualenv formula (bendzgerona/homebrew-litellm pattern).
3
+ # Replace <formula>, <description>, <url>, <sha256> with real values.
4
+ # IMPORTANT: Rename class <Formula> to CamelCase matching the filename (e.g., MyTool for my-tool.rb).
5
+
6
+ class <Formula> < Formula
7
+ include Language::Python::Virtualenv
8
+
9
+ desc "<one-line description>"
10
+ homepage "https://github.com/<user>/<repo>"
11
+ url "https://github.com/<user>/<repo>/archive/refs/tags/v<version>.tar.gz"
12
+ sha256 "<sha256>"
13
+ version "<version>"
14
+ license "MIT"
15
+
16
+ depends_on "python@3.13" # Pin to avoid brew's default 3.14
17
+ depends_on "openssl@3"
18
+ depends_on "pkgconf" => :build
19
+
20
+ livecheck do
21
+ url :stable
22
+ strategy :github_latest
23
+ regex(/^v?(\d+(?:\.\d+)+)$/i)
24
+ end
25
+
26
+ def install
27
+ venv = virtualenv_create(libexec, "python3.13")
28
+ venv.pip_install buildpath
29
+
30
+ # If the package has extras:
31
+ # system venv.root/"bin/pip", "install", "package[extras]==#{version}"
32
+
33
+ bin.install_symlink libexec/"bin/<cli>"
34
+ end
35
+
36
+ service do
37
+ run [libexec/"bin/<cli>", "--config", etc/"<tool>/config.yaml"]
38
+ keep_alive true
39
+ log_path var/"log/<tool>.log"
40
+ error_log_path var/"log/<tool>.log"
41
+ end
42
+
43
+ def caveats
44
+ <<~EOS
45
+ Configuration file: #{etc/"<tool>/config.yaml"}
46
+ Start the service: brew services start <user>/<tap>/<formula>
47
+
48
+ Optional dependencies:
49
+ postgresql — for usage tracking via SQLite → PostgreSQL
50
+ redis — for request caching and rate limiting
51
+ EOS
52
+ end
53
+
54
+ test do
55
+ assert_match version.to_s, shell_output("#{bin}/<cli> --version")
56
+ end
57
+ end
@@ -0,0 +1,27 @@
1
+ # <Tap Name>
2
+
3
+ Homebrew tap for <formula>.
4
+
5
+ ## Install
6
+
7
+ ```sh
8
+ brew tap <user>/<tapname>
9
+ brew install <formula>
10
+ ```
11
+
12
+ ## Upgrade
13
+
14
+ ```sh
15
+ brew upgrade <formula>
16
+ ```
17
+
18
+ ## Uninstall
19
+
20
+ ```sh
21
+ brew uninstall <formula>
22
+ brew untap <user>/<tapname>
23
+ ```
24
+
25
+ ## License
26
+
27
+ MIT
@@ -0,0 +1,44 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ # Version bump script for Python virtualenv formula.
5
+ # Usage: ruby scripts/update-formula.rb <version>
6
+
7
+ require "open-uri"
8
+ require "digest"
9
+
10
+ TAP_DIR = File.dirname(__dir__)
11
+ FORMULA_FILE = File.join(TAP_DIR, "Formula", "_formula.rb") # rename to your formula name
12
+
13
+ def usage
14
+ puts "Usage: ruby scripts/update-formula.rb <version>"
15
+ puts " e.g., ruby scripts/update-formula.rb 1.2.3"
16
+ exit 1
17
+ end
18
+
19
+ def fetch_sha256(url)
20
+ uri = URI.parse(url)
21
+ puts " Downloading #{url}..."
22
+ content = URI.open(uri).read
23
+ Digest::SHA256.hexdigest(content)
24
+ end
25
+
26
+ version = ARGV.first || usage()
27
+
28
+ tarball_url = "https://github.com/<user>/<repo>/archive/refs/tags/v#{version}.tar.gz"
29
+
30
+ puts "Updating Formula/<formula>.rb to version #{version}..."
31
+ sha = fetch_sha256(tarball_url)
32
+
33
+ formula_content = File.read(FORMULA_FILE)
34
+ formula_content.sub!(/version "\d+\.\d+\.\d+"/, "version \"#{version}\"")
35
+ formula_content.sub!(/sha256 "[0-9a-f]{64}"/, "sha256 \"#{sha}\"")
36
+
37
+ # Also update the pip install version pin if present:
38
+ formula_content.gsub!('package[extras]==#{version}', "package[extras]==#{version}")
39
+ formula_content.sub!(/(# system venv\.root\/"bin\/pip", "install", "package\[extras\]==)#{version}/, "\\1#{version}")
40
+
41
+ File.write(FORMULA_FILE, formula_content)
42
+
43
+ puts "Done. Formula updated to v#{version}."
44
+ puts "Review: git diff Formula/<formula>.rb"
@@ -0,0 +1,58 @@
1
+ # Template 04: Python Virtualenv
2
+
3
+ ## Pattern: `bendzgerona/homebrew-litellm`
4
+
5
+ A tap for Python CLI tools that install dependencies via `pip` inside a
6
+ Homebrew-managed virtualenv. Combines the lean script-driven release
7
+ pattern (template 03) with Python virtualenv formula conventions.
8
+
9
+ ### Structure
10
+
11
+ ```
12
+ homebrew-<tap>/
13
+ ├── Formula/
14
+ │ └── <formula>.rb # Formula with Language::Python::Virtualenv
15
+ ├── scripts/
16
+ │ └── release.rb # Version bump script (SHA256 + version)
17
+ ├── .gitignore
18
+ ├── LICENSE
19
+ └── README.md
20
+ ```
21
+
22
+ ### Key Formula Patterns
23
+
24
+ ```ruby
25
+ include Language::Python::Virtualenv
26
+
27
+ depends_on "python@3.13" # Pin Python version
28
+ depends_on "openssl@3" # For C-extension wheel compilation
29
+ depends_on "pkgconf" => :build
30
+
31
+ def install
32
+ venv = virtualenv_create(libexec, "python3.13")
33
+ venv.pip_install buildpath
34
+ system venv.root/"bin/pip", "install", "<package>[extras]==#{version}"
35
+ %w[cli-name another-cli].each do |cmd|
36
+ (bin/cmd).write_env_script(venv.root/"bin/#{cmd}", PATH: "#{venv.root}/bin:#{ENV["PATH"]}")
37
+ end
38
+ end
39
+ ```
40
+
41
+ ### When to Use
42
+
43
+ - Your formula installs a Python CLI tool with pip dependencies
44
+ - You need to pin a specific Python version (brew's default may conflict)
45
+ - You have exact pin constraints that differ from brew's versions
46
+
47
+ ### When NOT to Use
48
+
49
+ - Your formula is a pre-built binary (use template 03)
50
+ - You need CI/bottle workflows (use template 01)
51
+
52
+ ### Reference
53
+
54
+ - `bendzgerona/homebrew-litellm` — reference implementation
55
+ - Homebrew docs: `Python-for-Formula-Authors.md`, `Formula-Cookbook.md`
56
+ - Use `depends_on "python@3.X"` to pin; brew's default changes over time
57
+
58
+ - Start with `brew tap-new <user>/homebrew-<tapname>` to generate the CI skeleton (optional — manual structure works too)
@@ -0,0 +1,90 @@
1
+ ---
2
+ name: homebrew-tap-node-npm
3
+ description: Creates and maintains Homebrew taps for JavaScript/TypeScript CLI tools using npm or bun.
4
+ ---
5
+
6
+ # homebrew-tap-node-npm
7
+
8
+ Agent for working with Node.js / npm / bun tap templates.
9
+
10
+ ## Description
11
+ Helps create and maintain Homebrew taps for JavaScript/TypeScript CLI tools using either npm or bun as the package manager.
12
+
13
+ ## Stacks
14
+ - homebrew
15
+ - nodejs
16
+ - bun
17
+ - javascript
18
+ - typescript
19
+
20
+ ## Requires
21
+ - basic-homebrew-knowledge
22
+
23
+ ## Key Actions
24
+
25
+ ### npm Pattern
26
+ ```ruby
27
+ depends_on "node"
28
+ def install
29
+ system "npm", "install", *std_npm_args
30
+ bin.install_symlink Dir["#{libexec}/bin/*"]
31
+ end
32
+ ```
33
+
34
+ ### bun Pattern
35
+ ```ruby
36
+ depends_on "bun"
37
+ def install
38
+ system "bun", "install", "--production"
39
+ bin.install_symlink Dir["#{libexec}/bin/*"]
40
+ end
41
+ ```
42
+
43
+ ### Compiled bun binary pattern
44
+ ```ruby
45
+ depends_on "bun"
46
+ def install
47
+ system "bun", "install"
48
+ system "bun", "build", "--compile", "--outfile=#{bin}/<cli>", "./src/index.ts"
49
+ end
50
+ ```
51
+
52
+ ### Permissions
53
+ - Read/write to `Formula/` and `scripts/`
54
+ - Network access for npm/bun installs
55
+ - `depends_on "bun"` requires `oven-sh/homebrew-bun` to be tapped
56
+
57
+ ### Common Pitfalls
58
+
59
+ - `depends_on "bun"` requires `brew tap oven-sh/bun` first — the bun formula is not in homebrew-core.
60
+ - Uncomment exactly ONE of the three install patterns in `_formula.rb`. Multiple `def install` blocks cause a Ruby syntax error.
61
+ - `std_npm_args` is required for npm-based installs — it sets `--prefix`, `--global`, `--no-save`. Raw `npm install` will not place binaries in the correct libexec path.
62
+
63
+ ### LSP Validation
64
+
65
+ Before finishing any formula, validate with the Ruby LSP:
66
+
67
+ 1. Ensure LSP is available:
68
+ ```sh
69
+ ruby-lsp --version # Verify LSP is installed
70
+ ```
71
+ 2. Run syntax check:
72
+ ```sh
73
+ ruby -c Formula/<formula>.rb
74
+ ```
75
+ 3. Run Homebrew linting:
76
+ ```sh
77
+ brew style --tap <user>/<tapname> Formula/<formula>.rb
78
+ ```
79
+ 4. Run formula audit:
80
+ ```sh
81
+ brew audit --new-formula Formula/<formula>.rb
82
+ ```
83
+
84
+ Do NOT mark work as complete until all diagnostics pass.
85
+
86
+ ### Verification
87
+ ```sh
88
+ ruby -c Formula/<formula>.rb
89
+ brew style --tap <user>/<tapname> Formula/<formula>.rb
90
+ ```