@tuel/code-oz 0.20.0-alpha.0 → 0.20.3-alpha.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.
- package/README.md +190 -14
- package/npm-wrapper/index.cjs +71 -10
- package/package.json +14 -12
package/README.md
CHANGED
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
# code-oz
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
**CI-style gates for AI coding agents.**
|
|
4
|
+
|
|
5
|
+
`code-oz` runs coding agents through a repo-local delivery loop:
|
|
6
|
+
|
|
7
|
+
**DEFINE → PLAN → BUILD → VERIFY → REVIEW → SHIP**
|
|
8
|
+
|
|
9
|
+
Use it when direct AI coding is too unconstrained and you want every change to pass through inspectable artifacts, approval gates, verification evidence, and independent review before it ships.
|
|
10
|
+
|
|
11
|
+
AI agents are fast. `code-oz` makes their work auditable. It is for risky repos, not fastest-loop coding.
|
|
4
12
|
|
|
5
13
|
[](https://github.com/omerakben/code-oz/actions/workflows/test.yml)
|
|
6
14
|
[](https://github.com/omerakben/code-oz/actions/workflows/release.yml)
|
|
@@ -8,18 +16,28 @@ Repo-native agentic SDLC runtime that makes AI code pass through debate, evidenc
|
|
|
8
16
|
[](https://github.com/omerakben/homebrew-code-oz)
|
|
9
17
|
[](LICENSE)
|
|
10
18
|
[](https://github.com/omerakben/code-oz/releases)
|
|
11
|
-
[](https://github.com/omerakben/code-oz/actions/workflows/test.yml)
|
|
12
20
|
|
|
13
21
|
> **macOS note:** code-oz binaries are not yet Apple-Developer-signed (signing + notarization deferred to v0.x stable). Gatekeeper may prompt on first launch; the install script applies `xattr -d com.apple.quarantine` as a workaround, and `brew install` handles this automatically.
|
|
14
22
|
|
|
23
|
+
## What you get
|
|
24
|
+
|
|
25
|
+
- file-based phase gates you can inspect in the repo
|
|
26
|
+
- approvals bound to exact artifact SHA-256s
|
|
27
|
+
- isolated worktrees for agent changes
|
|
28
|
+
- an `events.jsonl` ledger for reconstructing what happened
|
|
29
|
+
- cross-family review so the builder and reviewer are not the same model family
|
|
30
|
+
|
|
31
|
+
Status: public alpha. The deterministic demo uses `FakeProvider` so you can inspect the lifecycle without spending tokens. FakeProvider proves lifecycle gates and ledger determinism, not model quality.
|
|
32
|
+
|
|
15
33
|
## Install
|
|
16
34
|
|
|
17
35
|
Three channels deliver the same single binary, verified against the same `checksums.txt`.
|
|
18
36
|
|
|
19
37
|
```sh
|
|
20
38
|
# curl | sh
|
|
21
|
-
curl -fsSL https://github.com/omerakben/code-oz/releases/download/v0.20.
|
|
22
|
-
| sh -s -- --version v0.20.
|
|
39
|
+
curl -fsSL https://github.com/omerakben/code-oz/releases/download/v0.20.1-alpha.0/install.sh \
|
|
40
|
+
| sh -s -- --version v0.20.1-alpha.0
|
|
23
41
|
|
|
24
42
|
# npm (scoped under the TUEL AI publisher; binary still runs as `code-oz`)
|
|
25
43
|
npm install -g @tuel/code-oz
|
|
@@ -29,24 +47,154 @@ brew tap omerakben/code-oz
|
|
|
29
47
|
brew install omerakben/code-oz/code-oz
|
|
30
48
|
```
|
|
31
49
|
|
|
32
|
-
Platform support: macOS arm64, macOS x64, Linux x64, Linux arm64. Windows
|
|
50
|
+
Platform support: macOS arm64, macOS x64, Linux x64, Linux arm64. Windows and Scoop are deferred to a future distribution milestone.
|
|
51
|
+
|
|
52
|
+
If `npm install -g @tuel/code-oz` fails with a 404 or authentication error, your `~/.npmrc` is likely overriding the `@tuel` scope — see [`docs/TRUST.md` § Install gotchas](docs/TRUST.md#install-gotchas-npm-scope-routing-for-tuelcode-oz) for the fix.
|
|
53
|
+
|
|
54
|
+
## Why not just Claude Code or Codex?
|
|
55
|
+
|
|
56
|
+
Use Claude Code, Codex, Cursor, Gemini CLI, OpenCode, Roo Code, or Aider directly when you want the fastest possible agent loop.
|
|
57
|
+
|
|
58
|
+
Use `code-oz` when you want a governed loop.
|
|
59
|
+
|
|
60
|
+
Direct-agent workflow:
|
|
61
|
+
|
|
62
|
+
1. Ask an agent to make a change.
|
|
63
|
+
2. Inspect the result.
|
|
64
|
+
3. Hope the prompt, tests, and review were enough.
|
|
65
|
+
|
|
66
|
+
`code-oz` workflow:
|
|
67
|
+
|
|
68
|
+
1. Define the task as an artifact.
|
|
69
|
+
2. Approve the artifact by SHA-256.
|
|
70
|
+
3. Build in an isolated worktree.
|
|
71
|
+
4. Verify evidence before review.
|
|
72
|
+
5. Require independent review.
|
|
73
|
+
6. Write a ledger of what happened.
|
|
33
74
|
|
|
34
|
-
|
|
75
|
+
`code-oz` is not trying to be a smarter coding model. It is the control layer around coding models.
|
|
35
76
|
|
|
36
|
-
|
|
77
|
+
## What is real today?
|
|
37
78
|
|
|
38
|
-
|
|
79
|
+
| Area | Status |
|
|
80
|
+
| ---------------- | -------------------------------------------------------------------- |
|
|
81
|
+
| CLI commands | `init`, `run`, `approve`, `doctor` |
|
|
82
|
+
| Lifecycle | `DEFINE → PLAN → BUILD → VERIFY → REVIEW → SHIP` for greenfield runs |
|
|
83
|
+
| Gates | File-based gates with schema validation |
|
|
84
|
+
| Approvals | SHA-256-bound approval artifacts |
|
|
85
|
+
| Isolation | Worktree-per-run isolation |
|
|
86
|
+
| Ledger | `events.jsonl` audit trail |
|
|
87
|
+
| Demo provider | Deterministic `FakeProvider` |
|
|
88
|
+
| Live providers | Claude CLI, Codex CLI, and xAI HTTP adapter |
|
|
89
|
+
| xAI auth | `XAI_API_KEY` env var |
|
|
90
|
+
| Install channels | curl script, npm package, Homebrew tap |
|
|
91
|
+
| Platforms | macOS arm64, macOS x64, Linux arm64, Linux x64 |
|
|
92
|
+
| Tests | 3395 offline tests in CI |
|
|
39
93
|
|
|
40
|
-
|
|
94
|
+
The provider contract is intentionally narrow. The alpha is about proving governed delivery, not supporting every agent on day one.
|
|
41
95
|
|
|
42
|
-
|
|
96
|
+
## What is simulated or not ready yet?
|
|
97
|
+
|
|
98
|
+
| Area | Current state |
|
|
99
|
+
| ------------------------------ | ----------------------------------------------------------- |
|
|
100
|
+
| FakeProvider demo | Simulated model responses, real gates/artifacts/ledger |
|
|
101
|
+
| Gemini | Stub provider in v0.1; not a working invocation adapter |
|
|
102
|
+
| OpenCode / Roo Code | Future adapter candidates, not v0.1 providers |
|
|
103
|
+
| Brownfield AUDIT runtime | Detection works; AUDIT phase runtime lands in M17/v0.21 |
|
|
104
|
+
| Windows / Scoop | Deferred |
|
|
105
|
+
| Apple signing / notarization | Deferred to v0.x stable; macOS may show Gatekeeper prompts |
|
|
106
|
+
| GPG/Sigstore-signed checksums | Deferred to v0.x stable |
|
|
107
|
+
| Full benchmark proof | Protocol shipped; measured rows land in v0.21 with runner |
|
|
108
|
+
| Broad multi-agent consultation | Deferred |
|
|
109
|
+
| Cloud IAM adapters | Deferred |
|
|
110
|
+
|
|
111
|
+
Do not use the alpha as proof that one model writes better code than another. Use it to inspect whether the governed lifecycle works.
|
|
112
|
+
|
|
113
|
+
## How is this different?
|
|
114
|
+
|
|
115
|
+
| Tool | Best for | What `code-oz` adds |
|
|
116
|
+
| -------------------------- | ------------------------------------------ | --------------------------------------------------------------------------- |
|
|
117
|
+
| Claude Code | Fast terminal coding with Claude | Repo-local gates, approvals, worktree isolation, ledger, independent review |
|
|
118
|
+
| Codex CLI | Fast terminal coding with OpenAI models | Same governed lifecycle around Codex output |
|
|
119
|
+
| Cursor | AI-native IDE workflow | External lifecycle governance outside the editor |
|
|
120
|
+
| Aider | Terminal-native git-integrated pair coding | Multi-phase artifacts and cross-family review |
|
|
121
|
+
| Gemini CLI / OpenCode / Roo Code | Direct AI coding loop | Future adapter candidates; not supported in v0.1 |
|
|
122
|
+
| Qodo / Sonar | PR/code quality review | Earlier lifecycle gates before the PR review stage |
|
|
123
|
+
| HivePipe / Devin / Factory | Managed agentic SDLC or agent workforce | Local-first, source-visible CLI runtime for owned repos |
|
|
124
|
+
|
|
125
|
+
Full footnote-sourced comparison: [`docs/comparisons/ai-coding-agents.md`](docs/comparisons/ai-coding-agents.md). Benchmark protocol: [`docs/benchmarks/agent-gate-bench.md`](docs/benchmarks/agent-gate-bench.md) (measured rows land in v0.21 with the runner).
|
|
126
|
+
|
|
127
|
+
`code-oz` is not a replacement for coding agents. It is a governed delivery loop around them.
|
|
128
|
+
|
|
129
|
+
## Quick demo
|
|
43
130
|
|
|
44
131
|
```sh
|
|
132
|
+
git clone https://github.com/omerakben/code-oz.git
|
|
133
|
+
cd code-oz
|
|
134
|
+
bun install
|
|
45
135
|
bun run demo:todo-cli # default (balanced)
|
|
46
136
|
bun run demo:todo-cli --effort lite # multiplier 0.4
|
|
47
|
-
bun run demo:todo-cli --effort beast # multiplier 6.0
|
|
48
137
|
```
|
|
49
138
|
|
|
139
|
+
The demo runs one full lifecycle:
|
|
140
|
+
|
|
141
|
+
```txt
|
|
142
|
+
DEFINE → PLAN → BUILD → VERIFY → REVIEW → SHIP
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
Then inspect:
|
|
146
|
+
|
|
147
|
+
```sh
|
|
148
|
+
ls docs/demo/01-todo-cli/output/
|
|
149
|
+
cat docs/demo/01-todo-cli/output/balanced/events.jsonl | tail
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
The demo uses `FakeProvider`, so it is deterministic and token-free. The value is not that the fake model is smart. The value is that the same gates, approvals, worktree flow, and ledger mechanics are exercised every time.
|
|
153
|
+
|
|
154
|
+
## Failure demo
|
|
155
|
+
|
|
156
|
+
Governance only matters if bad runs get blocked. The failure-gates demo runs five deterministic scenarios:
|
|
157
|
+
|
|
158
|
+
```sh
|
|
159
|
+
bun run demo:failure-gates
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
| Failure | Expected result |
|
|
163
|
+
| ------------------------------------------------ | ------------------------------------------------ |
|
|
164
|
+
| Tampered approved artifact | Gate refuses because SHA-256 no longer matches |
|
|
165
|
+
| BUILD output changes files outside allowed scope | Mutation gate blocks the run |
|
|
166
|
+
| VERIFY evidence fails | Run restarts or writes `NEEDS_INTERVENTION.json` |
|
|
167
|
+
| REVIEW uses same provider family as BUILD | Cross-family review check refuses it |
|
|
168
|
+
| Reviewer finds risky change | Run routes back to revision instead of SHIP |
|
|
169
|
+
|
|
170
|
+
Walkthrough: [`docs/demo/02-failure-gates/`](docs/demo/02-failure-gates/README.md).
|
|
171
|
+
|
|
172
|
+
This is the demo to watch before trusting the tool.
|
|
173
|
+
|
|
174
|
+
## Who is this for?
|
|
175
|
+
|
|
176
|
+
Use `code-oz` if:
|
|
177
|
+
|
|
178
|
+
- you already use AI coding agents
|
|
179
|
+
- you work in repos where mistakes matter
|
|
180
|
+
- you want approval artifacts instead of chat transcripts
|
|
181
|
+
- you want to compare builder and reviewer model families
|
|
182
|
+
- you want a reproducible audit trail for AI-generated changes
|
|
183
|
+
|
|
184
|
+
Do not use `code-oz` yet if:
|
|
185
|
+
|
|
186
|
+
- you want the fastest possible one-shot code generation
|
|
187
|
+
- you need Windows support today
|
|
188
|
+
- you need a polished enterprise SaaS dashboard
|
|
189
|
+
- you need every provider family supported today
|
|
190
|
+
- you are not willing to run an alpha
|
|
191
|
+
|
|
192
|
+
## Provider setup
|
|
193
|
+
|
|
194
|
+
First-run CLI defaults to `FakeProvider` when no live provider is configured, so `code-oz init && code-oz run` can complete without spending provider tokens. Live Claude and Codex use their upstream CLI login sessions; xAI uses `XAI_API_KEY`. The separate `code-oz-gui` helper uses `GEMINI_API_KEY` for an in-app AI assistant; that key is not used by the CLI.
|
|
195
|
+
|
|
196
|
+
See [`docs/PROVIDER_SETUP.md`](docs/PROVIDER_SETUP.md) for the single provider setup table and [`docs/contracts/PROVIDERS.md`](docs/contracts/PROVIDERS.md) for the live / stub / future-candidate matrix.
|
|
197
|
+
|
|
50
198
|
## Try it from source
|
|
51
199
|
|
|
52
200
|
```sh
|
|
@@ -59,11 +207,39 @@ mkdir /tmp/code-oz-smoke && cd /tmp/code-oz-smoke
|
|
|
59
207
|
~/Projects/code-oz/dist/code-oz doctor tools
|
|
60
208
|
```
|
|
61
209
|
|
|
62
|
-
##
|
|
210
|
+
## Trust and security
|
|
211
|
+
|
|
212
|
+
- Vulnerability reporting and artifact trust posture: [`SECURITY.md`](SECURITY.md)
|
|
213
|
+
- Data boundaries, install trust, and what is and is not logged: [`docs/TRUST.md`](docs/TRUST.md)
|
|
214
|
+
|
|
215
|
+
## Contributing
|
|
216
|
+
|
|
217
|
+
- Setup, tests, commit conventions, PR expectations: [`CONTRIBUTING.md`](CONTRIBUTING.md)
|
|
218
|
+
- Community standards: [`CODE_OF_CONDUCT.md`](CODE_OF_CONDUCT.md)
|
|
219
|
+
|
|
220
|
+
## Roadmap
|
|
221
|
+
|
|
222
|
+
Public summary at [`docs/design/ROADMAP.md#now-next-later`](docs/design/ROADMAP.md#now-next-later). The detailed milestone inventory follows in the same file.
|
|
223
|
+
|
|
224
|
+
- **Now (v0.20.1-alpha.0)**: first-run polish, truth-corrected provider claims, failure demo, security and community files, agent-gate benchmark protocol.
|
|
225
|
+
- **Next (v0.21.0-alpha.0)**: M17 AUDIT runtime for brownfield repos.
|
|
226
|
+
- **Later**: signed checksums, broader provider adapters, Windows/Scoop, hosted launch artifacts.
|
|
227
|
+
|
|
228
|
+
## Architecture and historical context
|
|
229
|
+
|
|
230
|
+
For the dense architecture (hybrid phase-graph, agentic sub-orchestration spine, 23 non-negotiable rules), product thesis, influence library, and the project's historical "AI software company" framing: [`docs/ABOUT.md`](docs/ABOUT.md).
|
|
231
|
+
|
|
232
|
+
## Star this repo if...
|
|
233
|
+
|
|
234
|
+
Star `code-oz` if you think AI coding agents need more than clever prompts:
|
|
63
235
|
|
|
64
|
-
|
|
236
|
+
- inspectable specs and plans
|
|
237
|
+
- test evidence before review
|
|
238
|
+
- independent model-family review
|
|
239
|
+
- tamper-evident approvals
|
|
240
|
+
- a ledger of what the agent did
|
|
65
241
|
|
|
66
|
-
|
|
242
|
+
Direct agents are fast. Governed agents are auditable.
|
|
67
243
|
|
|
68
244
|
## License
|
|
69
245
|
|
package/npm-wrapper/index.cjs
CHANGED
|
@@ -20,12 +20,14 @@ const { createHash } = require('node:crypto')
|
|
|
20
20
|
const { spawn, spawnSync } = require('node:child_process')
|
|
21
21
|
const { Readable } = require('node:stream')
|
|
22
22
|
const { pipeline } = require('node:stream/promises')
|
|
23
|
+
const { fileURLToPath } = require('node:url')
|
|
23
24
|
|
|
24
25
|
const GH_OWNER = 'omerakben'
|
|
25
26
|
const GH_REPO = 'code-oz'
|
|
26
27
|
|
|
27
|
-
function die(message) {
|
|
28
|
+
function die(message, hint) {
|
|
28
29
|
process.stderr.write(`code-oz launcher: ${message}\n`)
|
|
30
|
+
if (hint) process.stderr.write(`hint: ${hint}\n`)
|
|
29
31
|
process.exit(1)
|
|
30
32
|
}
|
|
31
33
|
|
|
@@ -53,7 +55,7 @@ function detectPlatform() {
|
|
|
53
55
|
if (process.platform !== 'darwin' && process.platform !== 'linux') {
|
|
54
56
|
die(
|
|
55
57
|
`unsupported platform: ${process.platform}. Supported: darwin, linux. ` +
|
|
56
|
-
'Windows is deferred to v0.
|
|
58
|
+
'Windows is deferred to a future distribution milestone (v0.21+).',
|
|
57
59
|
)
|
|
58
60
|
}
|
|
59
61
|
if (process.arch !== 'arm64' && process.arch !== 'x64') {
|
|
@@ -62,27 +64,46 @@ function detectPlatform() {
|
|
|
62
64
|
return { os: process.platform, arch: process.arch }
|
|
63
65
|
}
|
|
64
66
|
|
|
67
|
+
function parseDownloadUrl(raw) {
|
|
68
|
+
let parsed
|
|
69
|
+
try {
|
|
70
|
+
parsed = new URL(raw)
|
|
71
|
+
} catch (err) {
|
|
72
|
+
throw new Error(`invalid download URL ${JSON.stringify(raw)}: ${err.message}`)
|
|
73
|
+
}
|
|
74
|
+
if (parsed.protocol === 'file:') return parsed
|
|
75
|
+
if (parsed.protocol !== 'https:') {
|
|
76
|
+
throw new Error(`download URL must use https: ${raw}`)
|
|
77
|
+
}
|
|
78
|
+
return parsed
|
|
79
|
+
}
|
|
80
|
+
|
|
65
81
|
async function download(url, destination) {
|
|
66
|
-
|
|
67
|
-
|
|
82
|
+
const parsed = parseDownloadUrl(url)
|
|
83
|
+
if (parsed.protocol === 'file:') {
|
|
84
|
+
const sourcePath = fileURLToPath(parsed)
|
|
68
85
|
if (!fs.existsSync(sourcePath)) {
|
|
69
86
|
throw new Error(`source file does not exist: ${sourcePath}`)
|
|
70
87
|
}
|
|
71
88
|
await fs.promises.copyFile(sourcePath, destination)
|
|
72
89
|
return
|
|
73
90
|
}
|
|
74
|
-
const protocol = url.startsWith('https://') ? require('node:https') : require('node:http')
|
|
75
91
|
await new Promise((resolve, reject) => {
|
|
76
|
-
const request =
|
|
92
|
+
const request = require('node:https').get(parsed, (response) => {
|
|
77
93
|
const status = response.statusCode ?? 0
|
|
78
94
|
if (status >= 300 && status < 400 && response.headers.location) {
|
|
79
95
|
response.resume()
|
|
80
|
-
|
|
96
|
+
const redirected = new URL(response.headers.location, parsed)
|
|
97
|
+
if (redirected.protocol !== 'https:') {
|
|
98
|
+
reject(new Error(`redirect must stay on https: ${redirected.href}`))
|
|
99
|
+
return
|
|
100
|
+
}
|
|
101
|
+
download(redirected.href, destination).then(resolve, reject)
|
|
81
102
|
return
|
|
82
103
|
}
|
|
83
104
|
if (status < 200 || status >= 300) {
|
|
84
105
|
response.resume()
|
|
85
|
-
reject(new Error(`HTTP ${status} for ${
|
|
106
|
+
reject(new Error(`HTTP ${status} for ${parsed.href}`))
|
|
86
107
|
return
|
|
87
108
|
}
|
|
88
109
|
const fileStream = fs.createWriteStream(destination)
|
|
@@ -101,6 +122,31 @@ function sha256File(filePath) {
|
|
|
101
122
|
return hash.digest('hex')
|
|
102
123
|
}
|
|
103
124
|
|
|
125
|
+
function readCachedSha(sidecarPath) {
|
|
126
|
+
try {
|
|
127
|
+
const raw = fs.readFileSync(sidecarPath, 'utf8').trim()
|
|
128
|
+
return /^[0-9a-f]{64}$/i.test(raw) ? raw.toLowerCase() : null
|
|
129
|
+
} catch {
|
|
130
|
+
return null
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
function verifyCachedBinary(binaryPath, sidecarPath) {
|
|
135
|
+
if (!fs.existsSync(binaryPath)) return { ok: false, reason: 'cached binary missing' }
|
|
136
|
+
const expectedSha = readCachedSha(sidecarPath)
|
|
137
|
+
if (expectedSha === null) {
|
|
138
|
+
return { ok: false, reason: 'cache checksum metadata missing' }
|
|
139
|
+
}
|
|
140
|
+
const actualSha = sha256File(binaryPath)
|
|
141
|
+
if (actualSha !== expectedSha) {
|
|
142
|
+
return {
|
|
143
|
+
ok: false,
|
|
144
|
+
reason: `cache checksum mismatch: expected ${expectedSha}, got ${actualSha}`,
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
return { ok: true }
|
|
148
|
+
}
|
|
149
|
+
|
|
104
150
|
function findChecksumEntry(text, assetName) {
|
|
105
151
|
const lines = text.split(/\r?\n/)
|
|
106
152
|
for (const line of lines) {
|
|
@@ -125,7 +171,18 @@ function extractTarball(tarballPath, destinationDir) {
|
|
|
125
171
|
async function ensureBinary({ version, host, cacheRoot, baseUrl }) {
|
|
126
172
|
const cacheDir = path.join(cacheRoot, version)
|
|
127
173
|
const cachedBinary = path.join(cacheDir, 'code-oz')
|
|
128
|
-
|
|
174
|
+
const cachedShaPath = path.join(cacheDir, 'code-oz.sha256')
|
|
175
|
+
if (fs.existsSync(cachedBinary)) {
|
|
176
|
+
const cached = verifyCachedBinary(cachedBinary, cachedShaPath)
|
|
177
|
+
if (cached.ok) return cachedBinary
|
|
178
|
+
await fs.promises.rm(cachedBinary, { force: true })
|
|
179
|
+
await fs.promises.rm(cachedShaPath, { force: true })
|
|
180
|
+
if (baseUrl.startsWith('file://')) {
|
|
181
|
+
throw new Error(
|
|
182
|
+
`${cached.reason}; removed corrupted cache entry but cannot redownload from ${baseUrl}`,
|
|
183
|
+
)
|
|
184
|
+
}
|
|
185
|
+
}
|
|
129
186
|
|
|
130
187
|
await fs.promises.mkdir(cacheDir, { recursive: true })
|
|
131
188
|
const stageName = `code-oz-v${version}-${host.os}-${host.arch}`
|
|
@@ -162,6 +219,7 @@ async function ensureBinary({ version, host, cacheRoot, baseUrl }) {
|
|
|
162
219
|
|
|
163
220
|
await fs.promises.copyFile(stagedBinary, cachedBinary)
|
|
164
221
|
await fs.promises.chmod(cachedBinary, 0o755)
|
|
222
|
+
await fs.promises.writeFile(cachedShaPath, `${sha256File(cachedBinary)}\n`, 'utf8')
|
|
165
223
|
await fs.promises.rm(path.join(cacheDir, stageName), { recursive: true, force: true })
|
|
166
224
|
await fs.promises.rm(tarballPath, { force: true })
|
|
167
225
|
await fs.promises.rm(checksumsPath, { force: true })
|
|
@@ -180,7 +238,10 @@ async function main() {
|
|
|
180
238
|
try {
|
|
181
239
|
binary = await ensureBinary({ version, host, cacheRoot, baseUrl })
|
|
182
240
|
} catch (err) {
|
|
183
|
-
die(
|
|
241
|
+
die(
|
|
242
|
+
err.message,
|
|
243
|
+
`retry, or remove ${path.join(cacheRoot, version)} and run code-oz again. Use only HTTPS release URLs outside local tests.`,
|
|
244
|
+
)
|
|
184
245
|
}
|
|
185
246
|
|
|
186
247
|
const child = spawn(binary, process.argv.slice(2), { stdio: 'inherit' })
|
package/package.json
CHANGED
|
@@ -1,21 +1,22 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tuel/code-oz",
|
|
3
|
-
"version": "0.20.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.20.3-alpha.0",
|
|
4
|
+
"description": "CI-style gates for AI coding agents — local-first governed delivery loop",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
7
|
"code-oz": "npm-wrapper/index.cjs"
|
|
8
8
|
},
|
|
9
9
|
"scripts": {
|
|
10
|
-
"test": "bun test",
|
|
11
|
-
"test:watch": "bun test --watch",
|
|
10
|
+
"test": "bun test ./tests",
|
|
11
|
+
"test:watch": "bun test ./tests --watch",
|
|
12
12
|
"dev": "bun run src/cli.ts",
|
|
13
13
|
"build:binary": "bun build --compile --target=bun src/cli.ts --outfile dist/code-oz",
|
|
14
14
|
"build:binaries": "bun run scripts/build-binaries.ts",
|
|
15
15
|
"smoke": "bun run scripts/smoke-test.ts",
|
|
16
16
|
"typecheck": "tsc --noEmit",
|
|
17
17
|
"eval:repo_context": "bun run scripts/eval-repo-context.ts",
|
|
18
|
-
"demo:todo-cli": "bun run scripts/demo/01-todo-cli/run-demo.ts"
|
|
18
|
+
"demo:todo-cli": "bun run scripts/demo/01-todo-cli/run-demo.ts",
|
|
19
|
+
"demo:failure-gates": "bun run scripts/demo/02-failure-gates/run-demo.ts"
|
|
19
20
|
},
|
|
20
21
|
"engines": {
|
|
21
22
|
"node": ">=18",
|
|
@@ -31,14 +32,15 @@
|
|
|
31
32
|
"bugs": "https://github.com/omerakben/code-oz/issues",
|
|
32
33
|
"keywords": [
|
|
33
34
|
"ai",
|
|
34
|
-
"
|
|
35
|
-
"
|
|
36
|
-
"codex",
|
|
37
|
-
"gemini",
|
|
35
|
+
"coding-agent",
|
|
36
|
+
"cli",
|
|
38
37
|
"sdlc",
|
|
39
|
-
"
|
|
40
|
-
"
|
|
41
|
-
"
|
|
38
|
+
"devtools",
|
|
39
|
+
"agentic-ai",
|
|
40
|
+
"claude-code",
|
|
41
|
+
"codex",
|
|
42
|
+
"typescript",
|
|
43
|
+
"open-source"
|
|
42
44
|
],
|
|
43
45
|
"files": [
|
|
44
46
|
"npm-wrapper/",
|