harnessbrew 0.5.2 → 0.6.1
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 +31 -0
- package/README.md +157 -80
- package/README.zh-CN.md +373 -0
- package/dist/cli.d.ts +17 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +184 -26
- package/dist/cli.js.map +1 -1
- package/dist/core/adapter-plugins.d.ts +12 -0
- package/dist/core/adapter-plugins.d.ts.map +1 -0
- package/dist/core/adapter-plugins.js +151 -0
- package/dist/core/adapter-plugins.js.map +1 -0
- package/dist/core/bundle.d.ts +33 -5
- package/dist/core/bundle.d.ts.map +1 -1
- package/dist/core/bundle.js +329 -60
- package/dist/core/bundle.js.map +1 -1
- package/dist/core/doctor.d.ts +2 -2
- package/dist/core/doctor.d.ts.map +1 -1
- package/dist/core/doctor.js +2 -0
- package/dist/core/doctor.js.map +1 -1
- package/dist/core/git.d.ts +1 -0
- package/dist/core/git.d.ts.map +1 -1
- package/dist/core/git.js +17 -0
- package/dist/core/git.js.map +1 -1
- package/dist/core/installations.d.ts +1 -0
- package/dist/core/installations.d.ts.map +1 -1
- package/dist/core/installations.js +135 -14
- package/dist/core/installations.js.map +1 -1
- package/dist/core/journal.d.ts +26 -0
- package/dist/core/journal.d.ts.map +1 -0
- package/dist/core/journal.js +363 -0
- package/dist/core/journal.js.map +1 -0
- package/dist/core/locks.d.ts +10 -0
- package/dist/core/locks.d.ts.map +1 -0
- package/dist/core/locks.js +90 -0
- package/dist/core/locks.js.map +1 -0
- package/dist/core/paths.d.ts +1 -0
- package/dist/core/paths.d.ts.map +1 -1
- package/dist/core/paths.js +3 -0
- package/dist/core/paths.js.map +1 -1
- package/dist/core/state.d.ts +2 -0
- package/dist/core/state.d.ts.map +1 -1
- package/dist/core/state.js +21 -2
- package/dist/core/state.js.map +1 -1
- package/dist/core/taps.d.ts +7 -1
- package/dist/core/taps.d.ts.map +1 -1
- package/dist/core/taps.js +74 -16
- package/dist/core/taps.js.map +1 -1
- package/dist/core/targets/claude-code.d.ts.map +1 -1
- package/dist/core/targets/claude-code.js +11 -1
- package/dist/core/targets/claude-code.js.map +1 -1
- package/dist/core/targets/codex.d.ts.map +1 -1
- package/dist/core/targets/codex.js +11 -1
- package/dist/core/targets/codex.js.map +1 -1
- package/dist/core/targets/planner.d.ts +2 -3
- package/dist/core/targets/planner.d.ts.map +1 -1
- package/dist/core/targets/planner.js +43 -3
- package/dist/core/targets/planner.js.map +1 -1
- package/dist/core/targets/registry.d.ts +7 -3
- package/dist/core/targets/registry.d.ts.map +1 -1
- package/dist/core/targets/registry.js +55 -0
- package/dist/core/targets/registry.js.map +1 -1
- package/dist/core/targets/transaction.d.ts.map +1 -1
- package/dist/core/targets/transaction.js +46 -10
- package/dist/core/targets/transaction.js.map +1 -1
- package/dist/core/targets/types.d.ts +8 -4
- package/dist/core/targets/types.d.ts.map +1 -1
- package/dist/core/targets/types.js +1 -1
- package/dist/core/targets/types.js.map +1 -1
- package/dist/core/targets.d.ts +6 -7
- package/dist/core/targets.d.ts.map +1 -1
- package/dist/core/targets.js +33 -22
- package/dist/core/targets.js.map +1 -1
- package/dist/core/upgrades.d.ts.map +1 -1
- package/dist/core/upgrades.js +10 -1
- package/dist/core/upgrades.js.map +1 -1
- package/dist/index.d.ts +13 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -2
- package/dist/index.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,37 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## Unreleased
|
|
6
|
+
|
|
7
|
+
## 0.6.1 - 2026-08-13
|
|
8
|
+
|
|
9
|
+
### Changed
|
|
10
|
+
|
|
11
|
+
- upgrade GitHub CI and release workflows to `actions/checkout@v6` and `actions/setup-node@v6` while keeping HarnessBrew builds on Node.js 22
|
|
12
|
+
- require Node.js 22 or later consistently in package metadata, CI, and installation documentation
|
|
13
|
+
- make English the default README and architecture language while retaining complete Simplified Chinese editions
|
|
14
|
+
- move historical release notes under `docs/releases` and remove obsolete roadmap, task-breakdown, and legacy walkthrough documents
|
|
15
|
+
- add CI, npm version, Node.js support, and license badges to both README editions
|
|
16
|
+
|
|
17
|
+
## 0.6.0 - 2026-08-13
|
|
18
|
+
|
|
19
|
+
### Added
|
|
20
|
+
|
|
21
|
+
- add a versioned JSON CLI envelope with command-level results and structured errors
|
|
22
|
+
- add transactional `--dry-run` previews that report path fingerprints and roll back all managed changes
|
|
23
|
+
- add Target Adapter API v1 with validated registration, Cellar-bounded symlink plans, transaction-managed execution, and lockfile version fingerprints
|
|
24
|
+
- add explicit CLI management for trusted Adapter modules with persisted identity verification and transactional previews
|
|
25
|
+
|
|
26
|
+
### Security
|
|
27
|
+
|
|
28
|
+
- validate complete Receipt structures, canonical Cellar locations, operation metadata, owned keys, and all destructive paths before use
|
|
29
|
+
- detect added, removed, modified, unsupported, and permission-changed Cellar files through exact inventory comparison
|
|
30
|
+
- prevent forced cleanup from recursively deleting a real directory that replaced a managed directory symlink
|
|
31
|
+
- serialize CLI mutations per HarnessBrew home and protect shared Target configuration updates across processes
|
|
32
|
+
- recover interrupted mutations from durable write-ahead journals, including abandoned process locks and external Target files
|
|
33
|
+
- add Harnessfile and lockfile v2 with structured scopes, portable paths, content digests, explicit lock refresh, and Target convergence
|
|
34
|
+
- require explicit Tap trust before Target activation, enforce fast-forward updates by default, and roll back invalid Tap candidates
|
|
35
|
+
|
|
5
36
|
## 0.5.2 - 2026-08-13
|
|
6
37
|
|
|
7
38
|
### Fixed
|
package/README.md
CHANGED
|
@@ -1,50 +1,57 @@
|
|
|
1
1
|
# HarnessBrew
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
English | [简体中文](README.zh-CN.md)
|
|
4
4
|
|
|
5
|
-
HarnessBrew
|
|
5
|
+
[](https://github.com/anzihenry/HarnessBrew/actions/workflows/ci.yml)
|
|
6
|
+
[](https://www.npmjs.com/package/harnessbrew)
|
|
7
|
+
[](https://www.npmjs.com/package/harnessbrew)
|
|
8
|
+
[](https://github.com/anzihenry/HarnessBrew/blob/main/LICENSE)
|
|
6
9
|
|
|
7
|
-
|
|
10
|
+
HarnessBrew is a Git package manager for AI agent assets. Like Homebrew, it discovers assets through Git Taps, describes them with Formulae, and uses a Cellar and Receipts to install, upgrade, and safely uninstall them.
|
|
8
11
|
|
|
9
|
-
-
|
|
10
|
-
- 校验并搜索 skill、agent、workflow、instruction、prompt、MCP 和 adapter Formula
|
|
11
|
-
- 解析依赖、循环、缺失项与冲突
|
|
12
|
-
- 按 Git commit 将不可变内容安装到 Cellar
|
|
13
|
-
- 链接到 OpenAI Codex 和 Claude Code
|
|
14
|
-
- 以原生格式投递 Skill、Agent、Workflow、Prompt、Instruction 和 MCP
|
|
15
|
-
- 支持 user/project scope,以及同一 Target 的多实例
|
|
16
|
-
- 通过 Receipt 跟踪文件、配置键、受管区块所有权和 SHA-256 摘要
|
|
17
|
-
- 使用 `doctor` 诊断并通过 `relink` 修复 Target 漂移
|
|
18
|
-
- 检测可用升级,并在升级后保留 Agent target 链接
|
|
19
|
-
- 使用 `Harnessfile` 和 lockfile 在不同设备上复现环境
|
|
20
|
-
- 从 npm 安装并通过 GitHub Release 发布
|
|
12
|
+
HarnessBrew does not host assets. Personal, team, and third-party assets remain in their own Git repositories and use the same installation mechanism.
|
|
21
13
|
|
|
22
|
-
##
|
|
14
|
+
## Features
|
|
23
15
|
|
|
24
|
-
|
|
16
|
+
- Register, update, and remove Git Taps
|
|
17
|
+
- Validate and search skill, agent, workflow, instruction, prompt, MCP, and adapter Formulae
|
|
18
|
+
- Resolve dependencies, cycles, missing entries, and conflicts
|
|
19
|
+
- Install immutable content into the Cellar at a specific Git commit
|
|
20
|
+
- Link assets into OpenAI Codex and Claude Code
|
|
21
|
+
- Deliver Skills, Agents, Workflows, Prompts, Instructions, and MCP configuration in native formats
|
|
22
|
+
- Support user and project scopes, including multiple instances of one Target
|
|
23
|
+
- Track file, configuration-key, managed-block, and SHA-256 ownership in Receipts
|
|
24
|
+
- Diagnose Target drift with `doctor` and repair it with `relink`
|
|
25
|
+
- Detect upgrades while preserving Agent Target links
|
|
26
|
+
- Reproduce environments across machines with a `Harnessfile` and lockfile
|
|
27
|
+
- Install from npm and publish through GitHub Releases
|
|
28
|
+
|
|
29
|
+
## Installation
|
|
30
|
+
|
|
31
|
+
Requirements: Node.js 22 or later and Git available on the system.
|
|
25
32
|
|
|
26
33
|
```bash
|
|
27
34
|
npm install --global harnessbrew
|
|
28
35
|
harnessbrew --version
|
|
29
36
|
```
|
|
30
37
|
|
|
31
|
-
|
|
38
|
+
You can also run it directly:
|
|
32
39
|
|
|
33
40
|
```bash
|
|
34
41
|
npx harnessbrew help
|
|
35
42
|
```
|
|
36
43
|
|
|
37
|
-
HarnessBrew
|
|
44
|
+
HarnessBrew stores managed state in `~/.harnessbrew` by default. Set `HARNESSBREW_HOME` for tests or isolated environments.
|
|
38
45
|
|
|
39
|
-
##
|
|
46
|
+
## Quick start
|
|
40
47
|
|
|
41
|
-
|
|
48
|
+
Register an asset Tap:
|
|
42
49
|
|
|
43
50
|
```bash
|
|
44
|
-
harnessbrew tap add xiejinheng/agents git@github.com:xiejinheng/agent-assets.git
|
|
51
|
+
harnessbrew tap add xiejinheng/agents git@github.com:xiejinheng/agent-assets.git --trust
|
|
45
52
|
```
|
|
46
53
|
|
|
47
|
-
|
|
54
|
+
Search for and inspect Formulae:
|
|
48
55
|
|
|
49
56
|
```bash
|
|
50
57
|
harnessbrew search review
|
|
@@ -52,46 +59,46 @@ harnessbrew search --kind skill --target openai-codex
|
|
|
52
59
|
harnessbrew info xiejinheng/agents/code-review
|
|
53
60
|
```
|
|
54
61
|
|
|
55
|
-
|
|
62
|
+
Install into the Cellar and link into Codex:
|
|
56
63
|
|
|
57
64
|
```bash
|
|
58
65
|
harnessbrew install xiejinheng/agents/code-review \
|
|
59
66
|
--target openai-codex
|
|
60
67
|
```
|
|
61
68
|
|
|
62
|
-
|
|
69
|
+
Omit `--target` to keep the asset in the Cellar without modifying an Agent configuration directory.
|
|
63
70
|
|
|
64
|
-
|
|
71
|
+
Update and upgrade:
|
|
65
72
|
|
|
66
73
|
```bash
|
|
67
|
-
harnessbrew update
|
|
74
|
+
harnessbrew update [--allow-rewind]
|
|
68
75
|
harnessbrew outdated
|
|
69
76
|
harnessbrew upgrade code-review
|
|
70
77
|
```
|
|
71
78
|
|
|
72
|
-
|
|
79
|
+
Safely uninstall:
|
|
73
80
|
|
|
74
81
|
```bash
|
|
75
82
|
harnessbrew uninstall code-review
|
|
76
83
|
```
|
|
77
84
|
|
|
78
|
-
|
|
85
|
+
HarnessBrew stops if a managed file or link has changed. Pass `--force` explicitly when the modified target should still be removed.
|
|
79
86
|
|
|
80
|
-
## Homebrew
|
|
87
|
+
## Homebrew concepts
|
|
81
88
|
|
|
82
89
|
| Homebrew | HarnessBrew |
|
|
83
90
|
| --- | --- |
|
|
84
91
|
| `brew` | `harnessbrew` |
|
|
85
|
-
| Tap | Git
|
|
86
|
-
| Formula / Cask | Agent
|
|
87
|
-
| Cellar |
|
|
88
|
-
| Link |
|
|
92
|
+
| Tap | Git asset-source repository |
|
|
93
|
+
| Formula / Cask | Agent asset Formula |
|
|
94
|
+
| Cellar | Commit-isolated local installation area |
|
|
95
|
+
| Link | Link into Codex, Claude Code, or another Target |
|
|
89
96
|
| `Brewfile` | `Harnessfile` |
|
|
90
|
-
| Receipt |
|
|
97
|
+
| Receipt | Installation source, digest, and ownership record |
|
|
91
98
|
|
|
92
|
-
##
|
|
99
|
+
## Creating a Tap
|
|
93
100
|
|
|
94
|
-
Tap
|
|
101
|
+
A Tap is a regular Git repository. Prefer one repository per asset collection instead of one repository per Skill.
|
|
95
102
|
|
|
96
103
|
```text
|
|
97
104
|
my-agent-tap/
|
|
@@ -108,7 +115,7 @@ my-agent-tap/
|
|
|
108
115
|
└── adapters/
|
|
109
116
|
```
|
|
110
117
|
|
|
111
|
-
|
|
118
|
+
Minimal `tap.json`:
|
|
112
119
|
|
|
113
120
|
```json
|
|
114
121
|
{
|
|
@@ -116,7 +123,7 @@ my-agent-tap/
|
|
|
116
123
|
}
|
|
117
124
|
```
|
|
118
125
|
|
|
119
|
-
Formula
|
|
126
|
+
The Formula directory name must match `name`, and its parent directory must match `kind`:
|
|
120
127
|
|
|
121
128
|
```json
|
|
122
129
|
{
|
|
@@ -134,28 +141,32 @@ Formula 的目录名称必须与 `name` 一致,目录类型必须与 `kind`
|
|
|
134
141
|
}
|
|
135
142
|
```
|
|
136
143
|
|
|
137
|
-
|
|
144
|
+
The full coordinate is `<owner>/<tap>/<formula>`. Dependencies and conflicts must use full coordinates to avoid ambiguity across Taps.
|
|
138
145
|
|
|
139
|
-
Git commit
|
|
146
|
+
The Git commit is the single source of truth for an installed version. Formulae do not maintain duplicate `.snapshots` or `history` data.
|
|
140
147
|
|
|
141
|
-
MCP Formula
|
|
148
|
+
An MCP Formula uses a common JSON entry format. Stdio configuration uses `command`, optional `args`, and `envVars` containing environment-variable names only. HTTP configuration uses `transport: "http"`, `url`, optional `bearerTokenEnvVar`, and `headersFromEnv`. HarnessBrew rejects plaintext `env` secret values in entries.
|
|
142
149
|
|
|
143
|
-
`adapter` Formula
|
|
150
|
+
An `adapter` Formula is a Git/Cellar-managed extension asset, but it is never executed automatically. Target Adapter runtime modules use a separate trust mechanism: review and install an npm package, then authorize it explicitly with `harnessbrew adapter add <module>`. Taps therefore remain declarative while third-party Targets can use the versioned Adapter SDK.
|
|
144
151
|
|
|
145
|
-
##
|
|
152
|
+
## Targets
|
|
146
153
|
|
|
147
|
-
|
|
154
|
+
Built-in Targets:
|
|
148
155
|
|
|
149
156
|
- `openai-codex`
|
|
150
157
|
- `claude-code`
|
|
151
158
|
|
|
152
|
-
|
|
159
|
+
Select a Target during installation:
|
|
153
160
|
|
|
154
161
|
```bash
|
|
155
162
|
harnessbrew install code-review --target openai-codex
|
|
156
163
|
```
|
|
157
164
|
|
|
158
|
-
Codex
|
|
165
|
+
Codex Skills are installed in `~/.agents/skills` by default, while other Codex configuration uses `~/.codex`; Claude Code uses `~/.claude`. Skills are linked as complete directories, preserving relative resources such as `scripts/`, `references/`, and `assets/` alongside `SKILL.md`.
|
|
166
|
+
|
|
167
|
+
Workflows and Prompts are projected as Target Skills with standard frontmatter. Agents use portable Markdown source and are rendered deterministically to `.codex/agents/<name>.toml` for Codex or `.claude/agents/<name>.md` for Claude Code. Instructions use owned managed blocks in Codex `AGENTS.md` and links under `.claude/rules/<name>.md` in Claude Code. MCP configuration is merged as TOML blocks or JSON keys. Removing shared configuration never overwrites user-owned content.
|
|
168
|
+
|
|
169
|
+
Use an isolated Target root when needed:
|
|
159
170
|
|
|
160
171
|
```bash
|
|
161
172
|
harnessbrew install code-review \
|
|
@@ -163,7 +174,7 @@ harnessbrew install code-review \
|
|
|
163
174
|
--target-root /path/to/sandbox/.codex
|
|
164
175
|
```
|
|
165
176
|
|
|
166
|
-
|
|
177
|
+
Targets support user and project scopes. `--project` implicitly selects project scope. The same Formula can exist in both scopes, and its Receipt records operations by their actual destination:
|
|
167
178
|
|
|
168
179
|
```bash
|
|
169
180
|
harnessbrew link code-review --target openai-codex --scope user
|
|
@@ -171,11 +182,11 @@ harnessbrew link code-review --target openai-codex --scope project --project /pa
|
|
|
171
182
|
harnessbrew unlink code-review --target openai-codex --scope project --project /path/to/repo
|
|
172
183
|
```
|
|
173
184
|
|
|
174
|
-
|
|
185
|
+
Project-scoped Codex assets use `.agents/skills`, `.codex/agents`, the root `AGENTS.md`, and `.codex/config.toml`. Claude Code uses `.claude/skills`, `.claude/agents`, `.claude/rules`, and the root `.mcp.json`. When a Target has multiple instances, `unlink` requires an explicit scope.
|
|
175
186
|
|
|
176
|
-
`harnessbrew doctor [formula]`
|
|
187
|
+
`harnessbrew doctor [formula]` validates Cellar file digests and every Target operation, distinguishing missing targets from modified ones. If the Cellar is intact, `harnessbrew relink <formula>` forcibly reconstructs HarnessBrew-owned targets using the scope and root recorded in the Receipt. Use `--target`, `--scope`, and `--project` to repair one instance.
|
|
177
188
|
|
|
178
|
-
|
|
189
|
+
Links can also be managed separately:
|
|
179
190
|
|
|
180
191
|
```bash
|
|
181
192
|
harnessbrew link code-review --target openai-codex
|
|
@@ -184,37 +195,49 @@ harnessbrew unlink code-review --target openai-codex
|
|
|
184
195
|
|
|
185
196
|
## Harnessfile
|
|
186
197
|
|
|
187
|
-
`Harnessfile`
|
|
198
|
+
A `Harnessfile` can be committed to a dotfiles or project repository:
|
|
188
199
|
|
|
189
200
|
```yaml
|
|
190
|
-
schemaVersion:
|
|
201
|
+
schemaVersion: 2
|
|
191
202
|
taps:
|
|
192
203
|
- name: xiejinheng/agents
|
|
193
204
|
git: git@github.com:xiejinheng/agent-assets.git
|
|
194
205
|
ref: main
|
|
206
|
+
trust: true
|
|
195
207
|
|
|
196
208
|
assets:
|
|
197
209
|
- formula: xiejinheng/agents/code-review
|
|
198
|
-
targets:
|
|
210
|
+
targets:
|
|
211
|
+
- target: openai-codex
|
|
212
|
+
scope: user
|
|
213
|
+
- target: claude-code
|
|
214
|
+
scope: project
|
|
215
|
+
project: .
|
|
199
216
|
```
|
|
200
217
|
|
|
201
|
-
|
|
218
|
+
Target placements in v2 declare `user` or `project` scope and may use `project` and `root` paths relative to the `Harnessfile`. Schema v1 `targets: [openai-codex]` remains compatible and is interpreted as user scope.
|
|
219
|
+
|
|
220
|
+
Install and generate `Harnessfile.lock`:
|
|
202
221
|
|
|
203
222
|
```bash
|
|
204
223
|
harnessbrew bundle install
|
|
205
224
|
```
|
|
206
225
|
|
|
207
|
-
lockfile
|
|
226
|
+
The v2 lockfile records the manifest digest, HarnessBrew Adapter versions, exact commit for every Tap, Formula content digests, dependency closure, and full Target placements. Commit it together with the `Harnessfile`.
|
|
208
227
|
|
|
209
|
-
|
|
228
|
+
On another machine, the same command checks out commits pinned by the lockfile instead of silently using the latest Tap versions. After changing a v2 Harnessfile, update the lockfile explicitly:
|
|
210
229
|
|
|
211
|
-
|
|
230
|
+
```bash
|
|
231
|
+
harnessbrew bundle install --update-lock
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
Remove managed assets not present in the manifest:
|
|
212
235
|
|
|
213
236
|
```bash
|
|
214
237
|
harnessbrew bundle cleanup
|
|
215
238
|
```
|
|
216
239
|
|
|
217
|
-
|
|
240
|
+
Use a different manifest path:
|
|
218
241
|
|
|
219
242
|
```bash
|
|
220
243
|
harnessbrew bundle install --file ./config/Harnessfile
|
|
@@ -223,9 +246,11 @@ harnessbrew bundle install --file ./config/Harnessfile
|
|
|
223
246
|
## CLI
|
|
224
247
|
|
|
225
248
|
```text
|
|
226
|
-
harnessbrew tap add <owner/name> <git-url> [--ref <ref>]
|
|
249
|
+
harnessbrew tap add <owner/name> <git-url> [--ref <ref>] [--trust]
|
|
227
250
|
harnessbrew tap list
|
|
228
|
-
harnessbrew tap update [owner/name]
|
|
251
|
+
harnessbrew tap update [owner/name] [--allow-rewind]
|
|
252
|
+
harnessbrew tap trust <owner/name>
|
|
253
|
+
harnessbrew tap untrust <owner/name>
|
|
229
254
|
harnessbrew tap remove <owner/name>
|
|
230
255
|
harnessbrew untap <owner/name>
|
|
231
256
|
harnessbrew search [query] [--kind <kind>] [--target <target>]
|
|
@@ -240,34 +265,44 @@ harnessbrew update
|
|
|
240
265
|
harnessbrew outdated
|
|
241
266
|
harnessbrew upgrade [formula]
|
|
242
267
|
harnessbrew uninstall <formula> [--force]
|
|
243
|
-
harnessbrew bundle install [--file <path>]
|
|
268
|
+
harnessbrew bundle install [--file <path>] [--update-lock]
|
|
244
269
|
harnessbrew bundle cleanup [--file <path>]
|
|
245
270
|
```
|
|
246
271
|
|
|
247
|
-
|
|
272
|
+
Every command accepts `--json`. Standard output then contains one schema v1 JSON envelope: `result` is the command-specific structured result, `output` retains human-readable text, and failures include `error.code`, `error.message`, `diagnostics`, and a non-zero `exitCode`.
|
|
273
|
+
|
|
274
|
+
Mutating commands also accept `--dry-run`. Under the same Home write lock, HarnessBrew runs full validation and the installation transaction, collects before/after types and digests for each path, then rolls back the Cellar, Receipts, Tap checkouts, and Agent Targets. With `--json`, the preview appears in `changes`. A dry run can still perform read-only network operations such as Git fetch or clone.
|
|
275
|
+
|
|
276
|
+
```bash
|
|
277
|
+
harnessbrew install code-review --target openai-codex --dry-run --json
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
## Local directories
|
|
248
281
|
|
|
249
282
|
```text
|
|
250
283
|
~/.harnessbrew/
|
|
251
|
-
├── taps/ #
|
|
252
|
-
├── cellar/ #
|
|
253
|
-
├── receipts/ #
|
|
254
|
-
└── state.json # Tap
|
|
284
|
+
├── taps/ # Git worktrees managed by HarnessBrew
|
|
285
|
+
├── cellar/ # Immutable content isolated by Formula and commit
|
|
286
|
+
├── receipts/ # Installation, dependency, Target-link, and digest records
|
|
287
|
+
└── state.json # Tap registration state
|
|
255
288
|
```
|
|
256
289
|
|
|
257
|
-
Tap
|
|
290
|
+
HarnessBrew owns the Tap worktrees and Cellar contents; do not edit them directly. Change personal assets in the source Tap repository, commit and push, then install the changes with `update` and `upgrade`.
|
|
258
291
|
|
|
259
|
-
##
|
|
292
|
+
## Security boundaries
|
|
260
293
|
|
|
261
|
-
-
|
|
262
|
-
-
|
|
263
|
-
-
|
|
264
|
-
-
|
|
265
|
-
-
|
|
266
|
-
-
|
|
294
|
+
- Formulae are declarative JSON; HarnessBrew does not execute arbitrary Tap scripts.
|
|
295
|
+
- Newly registered Taps are untrusted by default. They can be searched and installed into the Cellar, but linking or rendering into an Agent Target requires `tap trust`, `tap add --trust`, or `trust: true` in Harnessfile v2. Legacy state records are treated as trusted for compatibility.
|
|
296
|
+
- Tap updates accept Git fast-forwards only by default. Rewritten history must be reviewed and accepted with `--allow-rewind`. A failed candidate-commit validation restores the original checkout and state.
|
|
297
|
+
- Formula entries cannot escape their containing directories.
|
|
298
|
+
- Dependencies, conflicts, and Target compatibility are checked before installation.
|
|
299
|
+
- HarnessBrew does not overwrite target files it does not own through a Receipt.
|
|
300
|
+
- Uninstallation validates Cellar digests and symlink destinations first.
|
|
301
|
+
- Credentials for private Taps are handled by the system Git/SSH credential mechanism.
|
|
267
302
|
|
|
268
|
-
##
|
|
303
|
+
## Development
|
|
269
304
|
|
|
270
|
-
|
|
305
|
+
The project uses TypeScript 7.0 with strict type checking.
|
|
271
306
|
|
|
272
307
|
```bash
|
|
273
308
|
npm ci
|
|
@@ -276,11 +311,53 @@ npm test
|
|
|
276
311
|
npm run check
|
|
277
312
|
```
|
|
278
313
|
|
|
279
|
-
`npm run check`
|
|
314
|
+
`npm run check` runs TypeScript compilation, all Node.js tests, a package smoke test, and `npm pack --dry-run`.
|
|
315
|
+
|
|
316
|
+
## Target Adapter SDK
|
|
317
|
+
|
|
318
|
+
Node.js and TypeScript hosts can register third-party Agent Targets through the public API. Adapter API v1 receives only a Receipt and Target Context and returns a declarative installation plan. Writes, conflict detection, Receipts, `doctor`, `relink`, upgrades, dry runs, and rollback remain the responsibility of the HarnessBrew transaction layer.
|
|
319
|
+
|
|
320
|
+
```ts
|
|
321
|
+
import { registerTargetAdapter, type TargetAdapter } from "harnessbrew";
|
|
322
|
+
|
|
323
|
+
const adapter: TargetAdapter = {
|
|
324
|
+
apiVersion: 1,
|
|
325
|
+
name: "cursor",
|
|
326
|
+
version: "1.0.0",
|
|
327
|
+
capabilities: {
|
|
328
|
+
skill: "symlink-directory",
|
|
329
|
+
agent: "symlink-file",
|
|
330
|
+
workflow: "symlink-file",
|
|
331
|
+
instruction: "symlink-file",
|
|
332
|
+
prompt: "symlink-file",
|
|
333
|
+
mcp: "unsupported",
|
|
334
|
+
adapter: "unsupported"
|
|
335
|
+
},
|
|
336
|
+
plan(receipt, context = {}) {
|
|
337
|
+
// Return one absolute destination and a source inside receipt.cellarPath.
|
|
338
|
+
return { target: "cursor", coordinate: receipt.coordinate, operations: [/* ... */] };
|
|
339
|
+
}
|
|
340
|
+
};
|
|
341
|
+
|
|
342
|
+
const unregister = registerTargetAdapter(adapter);
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
The SDK validates API version, name, version, the complete capability matrix, plan identity, absolute target paths, and Cellar source boundaries. Third-party Adapter plans in v1 may use only `symlink-file`, `symlink-directory`, and `unsupported`; they cannot write files directly or generate shared configuration. Registration is explicit and process-local. HarnessBrew never executes Adapter Formulae from a Tap automatically. A third-party Adapter has the host process's privileges and should be loaded only from a reviewed npm package.
|
|
346
|
+
|
|
347
|
+
The standalone CLI can persist trusted Adapter modules. The module must already be installed and resolvable by `harnessbrew`, or be supplied as an absolute path or `file://` URL. It must default-export an Adapter or provide a named `adapter` export:
|
|
348
|
+
|
|
349
|
+
```bash
|
|
350
|
+
harnessbrew adapter add @harnessbrew/adapter-cursor
|
|
351
|
+
harnessbrew adapter list
|
|
352
|
+
harnessbrew install review --target cursor
|
|
353
|
+
harnessbrew adapter remove cursor
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
`adapter add` explicitly authorizes code execution. HarnessBrew records the module specifier and reviewed name, version, and API version in `~/.harnessbrew/adapters.json`. It loads the module only when install, link, unlink, relink, upgrade, or bundle operations need that Target, and verifies its identity every time. If a package upgrade changes identity, the command fails closed until the module is removed, reviewed, and added again. `adapter list` and `adapter remove` do not execute plugins, and HarnessBrew never runs `npm install` automatically. CLI-loaded Targets are also included in the Harnessfile v2 Adapter signature.
|
|
280
357
|
|
|
281
|
-
##
|
|
358
|
+
## Architecture
|
|
282
359
|
|
|
283
|
-
|
|
360
|
+
See [docs/architecture.md](docs/architecture.md) for the full design.
|
|
284
361
|
|
|
285
362
|
## License
|
|
286
363
|
|