@hecer/yoke 1.6.1 → 1.6.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/.claude-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +1 -1
- package/CHANGELOG.md +12 -2
- package/README.md +5 -5
- package/canon/manifest.yaml +1 -1
- package/dist/agents/process.js +2 -0
- package/dist/agents/providers.js +1 -1
- package/dist/loop/cleanup.js +3 -0
- package/dist/loop/reporter.js +4 -1
- package/dist/loop/watchdog.js +2 -0
- package/docs/PUBLISHING.md +25 -2
- package/gemini-extension.json +1 -1
- package/package.json +1 -1
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"$schema": "https://json.schemastore.org/claude-code-plugin-manifest.json",
|
|
3
3
|
"name": "yoke",
|
|
4
4
|
"displayName": "Yoke",
|
|
5
|
-
"version": "1.6.
|
|
5
|
+
"version": "1.6.2",
|
|
6
6
|
"description": "Cross-agent coding harness: one curated skill canon (TDD, brainstorming, plans, reviews, shipping, design verification) plus mechanical safety gates and an autonomous loop via the yoke CLI.",
|
|
7
7
|
"author": { "name": "HECer", "url": "https://github.com/HECer" },
|
|
8
8
|
"homepage": "https://github.com/HECer/yoke#readme",
|
package/CHANGELOG.md
CHANGED
|
@@ -2,11 +2,21 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
## 1.6.2 — 2026-09-02
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
- GitHub Releases can now publish `@hecer/yoke` through npm trusted publishing with short-lived OIDC credentials and automatic provenance, without a long-lived npm token.
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
- Codex safe-mode invocations now use the supported `workspace-write` sandbox with `--approve-for-me`; the removed `--full-auto` flag no longer blocks current Codex CLI releases.
|
|
12
|
+
- Windows provider cleanup rechecks termination after process close and accepts an already-absent process as successfully cleaned up, avoiding stale ownership records and unnecessary watchdog waits.
|
|
13
|
+
- Successful stale-loop cleanup removes obsolete runtime status, so `yoke loop status` no longer reports a dead run as `RUNNING`.
|
|
14
|
+
|
|
5
15
|
## 1.6.1 — 2026-08-21
|
|
6
16
|
|
|
7
17
|
### Fixed
|
|
8
|
-
- Release metadata
|
|
9
|
-
- Provider cleanup
|
|
18
|
+
- Release metadata counts platform-conditional tests consistently on Windows and Ubuntu.
|
|
19
|
+
- Provider cleanup confirms termination after child close, preventing stale ownership records when Windows reports process exit asynchronously.
|
|
10
20
|
|
|
11
21
|
## 1.6.0 — 2026-08-20
|
|
12
22
|
|
package/README.md
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
# 🐂 Yoke
|
|
4
4
|
|
|
5
|
-
<!-- yoke:version:start -->1.6.
|
|
6
|
-
<!-- yoke:tests:start -->
|
|
5
|
+
<!-- yoke:version:start -->1.6.2<!-- yoke:version:end -->
|
|
6
|
+
<!-- yoke:tests:start -->1021<!-- yoke:tests:end -->
|
|
7
7
|
<!-- yoke:skills:start -->34<!-- yoke:skills:end -->
|
|
8
8
|
<!-- yoke:agents:start -->Claude | Codex | Gemini<!-- yoke:agents:end -->
|
|
9
9
|
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
[](#-license)
|
|
18
18
|

|
|
19
19
|

|
|
20
|
-

|
|
21
21
|

|
|
22
22
|

|
|
23
23
|
|
|
@@ -81,7 +81,7 @@ $ ls reading-app/.yoke/proof/STORY-2/
|
|
|
81
81
|
home.png list.png # photographic evidence, labelled per story
|
|
82
82
|
```
|
|
83
83
|
|
|
84
|
-
Every claim in that transcript is enforced by code paths with tests behind them —
|
|
84
|
+
Every claim in that transcript is enforced by code paths with tests behind them — 1021 of them, and this repo was built by its own loop and gates ([how it was built](#-why--how-it-was-built)).
|
|
85
85
|
|
|
86
86
|
## 🚀 Quickstart
|
|
87
87
|
|
|
@@ -856,7 +856,7 @@ release provenance.
|
|
|
856
856
|
## 🧪 Development
|
|
857
857
|
|
|
858
858
|
```bash
|
|
859
|
-
npm test # vitest (
|
|
859
|
+
npm test # vitest (1021 tests)
|
|
860
860
|
npm run build # tsc, no emit errors
|
|
861
861
|
npm run yoke -- validate canon
|
|
862
862
|
```
|
package/canon/manifest.yaml
CHANGED
package/dist/agents/process.js
CHANGED
|
@@ -81,6 +81,8 @@ export function startProviderProcess(agent, invocation, options = {}) {
|
|
|
81
81
|
telemetry: telemetry.finish(),
|
|
82
82
|
});
|
|
83
83
|
const finalize = (exitCode) => {
|
|
84
|
+
// Windows can emit close before taskkill's process-tree state is observable.
|
|
85
|
+
// Reconfirm here so successful termination does not leave a stale ownership record.
|
|
84
86
|
if (termination && pid !== undefined && !terminationConfirmed) {
|
|
85
87
|
terminationConfirmed = terminateProcessTree(pid, true);
|
|
86
88
|
}
|
package/dist/agents/providers.js
CHANGED
|
@@ -13,7 +13,7 @@ const argsFor = (agent, permissions) => {
|
|
|
13
13
|
return ['exec', '--dangerously-bypass-approvals-and-sandbox', '--json'];
|
|
14
14
|
if (permissions === 'read-only')
|
|
15
15
|
return ['exec', '--sandbox', 'read-only', '--json'];
|
|
16
|
-
return ['exec', '--
|
|
16
|
+
return ['exec', '--sandbox', 'workspace-write', '--approve-for-me', '--json'];
|
|
17
17
|
}
|
|
18
18
|
if (permissions === 'unsafe')
|
|
19
19
|
return ['--yolo'];
|
package/dist/loop/cleanup.js
CHANGED
|
@@ -6,6 +6,7 @@ import { processIncarnation } from '../agents/process-incarnation.js';
|
|
|
6
6
|
import { acquireTakeoverLease, acquireTakeoverRecoveryLease, lockPath, takeoverLockPath, readLock, isPidAlive, releaseTakeoverLease, releaseTakeoverRecoveryLease, takeoverRecoveryPath, } from './lock.js';
|
|
7
7
|
import { killProcessForCleanup, killProcessTreeForCleanup } from './watchdog.js';
|
|
8
8
|
import { cleanupClaims } from './claims.js';
|
|
9
|
+
import { clearStatus } from './reporter.js';
|
|
9
10
|
// Reap orphaned runners PROJECT-SCOPED: kill only pids recorded in this project's
|
|
10
11
|
// .yoke/runner.pid files (main dir + each worktree). Never by process-name or
|
|
11
12
|
// command-line pattern — that takes down runners belonging to OTHER projects,
|
|
@@ -223,6 +224,8 @@ export function runLoopCleanup(targetDir, opts = {}) {
|
|
|
223
224
|
rmSync(lockFile, { force: true });
|
|
224
225
|
console.log('Removed stale loop lock.');
|
|
225
226
|
}
|
|
227
|
+
if (failed === 0)
|
|
228
|
+
clearStatus(targetDir);
|
|
226
229
|
console.log(removed === 0 && failed === 0 ? 'No destructive cleanup performed.' : `Removed ${removed} worktree(s)${failed > 0 ? `, ${failed} failed` : ''}.`);
|
|
227
230
|
return failed === 0 ? 0 : 1;
|
|
228
231
|
}
|
package/dist/loop/reporter.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { existsSync, readFileSync, writeFileSync, mkdirSync, renameSync, appendFileSync, statSync } from 'node:fs';
|
|
1
|
+
import { existsSync, readFileSync, writeFileSync, mkdirSync, renameSync, appendFileSync, statSync, rmSync } from 'node:fs';
|
|
2
2
|
import { join } from 'node:path';
|
|
3
3
|
export const LOG_CAP_BYTES = 256 * 1024;
|
|
4
4
|
// Append a line to .yoke/loop.log, keeping the file bounded: once it exceeds
|
|
@@ -77,6 +77,9 @@ export function readStatus(dir) {
|
|
|
77
77
|
return null;
|
|
78
78
|
}
|
|
79
79
|
}
|
|
80
|
+
export function clearStatus(dir) {
|
|
81
|
+
rmSync(statusPath(dir), { force: true });
|
|
82
|
+
}
|
|
80
83
|
export function makeReporter(dir, opts = {}, now = () => new Date()) {
|
|
81
84
|
const sink = opts.log ?? ((line) => process.stdout.write(line + '\n'));
|
|
82
85
|
const emitConsole = (line) => { if (!opts.quiet)
|
package/dist/loop/watchdog.js
CHANGED
|
@@ -62,6 +62,8 @@ export function killProcessTreeForCleanup(pid, platform = process.platform, runT
|
|
|
62
62
|
}
|
|
63
63
|
}) {
|
|
64
64
|
if (platform === 'win32') {
|
|
65
|
+
// taskkill reports a non-zero status when the process disappeared between
|
|
66
|
+
// observation and cleanup; that is already the desired terminal state.
|
|
65
67
|
if (runTaskkill('taskkill', ['/PID', String(pid), '/T', '/F']) !== 0)
|
|
66
68
|
return !isProcessAlive(pid);
|
|
67
69
|
return confirmProcessStopped(pid, isProcessAlive);
|
package/docs/PUBLISHING.md
CHANGED
|
@@ -6,7 +6,7 @@ Where Yoke is published, and how each channel gets updated. (Reviewed 2026-08-20
|
|
|
6
6
|
|
|
7
7
|
| Channel | How | Update path |
|
|
8
8
|
|---|---|---|
|
|
9
|
-
| **npm** — [`@hecer/yoke`](https://www.npmjs.com/package/@hecer/yoke) |
|
|
9
|
+
| **npm** — [`@hecer/yoke`](https://www.npmjs.com/package/@hecer/yoke) | GitHub OIDC trusted publishing | every release |
|
|
10
10
|
| **GitHub** — [HECer/yoke](https://github.com/HECer/yoke) | push + tag + GitHub Release | every release |
|
|
11
11
|
| **Claude Code plugin (self-marketplace)** | `.claude-plugin/plugin.json` + `marketplace.json` in this repo; users: `/plugin marketplace add HECer/yoke` → `/plugin install yoke@yoke` | bump `version` in `plugin.json` |
|
|
12
12
|
| **Gemini CLI extension** | `gemini-extension.json` + `GEMINI-EXTENSION.md` at repo root; users: `gemini extensions install https://github.com/HECer/yoke` | bump `version` in the manifest |
|
|
@@ -33,7 +33,7 @@ release object is created. Use this idempotent check after the version commit re
|
|
|
33
33
|
|
|
34
34
|
```bash
|
|
35
35
|
set -euo pipefail
|
|
36
|
-
VERSION=1.6.
|
|
36
|
+
VERSION=1.6.2
|
|
37
37
|
TARGET=$(git rev-parse HEAD)
|
|
38
38
|
git fetch --tags origin
|
|
39
39
|
|
|
@@ -62,6 +62,29 @@ gh release view "v$VERSION" >/dev/null 2>&1 || \
|
|
|
62
62
|
Verify both surfaces before publishing npm: `gh release view "v$VERSION"` and
|
|
63
63
|
`npm view @hecer/yoke version`.
|
|
64
64
|
|
|
65
|
+
## npm trusted publishing
|
|
66
|
+
|
|
67
|
+
The `publish-npm.yml` workflow publishes a stable package automatically when a GitHub Release is
|
|
68
|
+
published. It checks out that exact tag, requires the tag to match the version in `package.json`,
|
|
69
|
+
reruns `prepublishOnly` through `npm publish`, and skips a version that already exists. GitHub OIDC
|
|
70
|
+
provides a short-lived publishing identity; no `NPM_TOKEN` repository secret is used. npm adds
|
|
71
|
+
provenance automatically for this public repository.
|
|
72
|
+
|
|
73
|
+
One package-owner setup step is required on npmjs.com under the `@hecer/yoke` package settings:
|
|
74
|
+
|
|
75
|
+
- Publisher: GitHub Actions
|
|
76
|
+
- Organization or user: `HECer`
|
|
77
|
+
- Repository: `yoke`
|
|
78
|
+
- Workflow filename: `publish-npm.yml`
|
|
79
|
+
- Environment: leave empty
|
|
80
|
+
- Allowed action: `npm publish`
|
|
81
|
+
|
|
82
|
+
After the trusted publisher exists, the next GitHub Release publishes automatically. To publish an
|
|
83
|
+
already-created release such as `v1.6.1`, run the **Publish npm** workflow manually and provide that
|
|
84
|
+
existing tag. The workflow refuses tags without a published GitHub Release and refuses tag/version
|
|
85
|
+
mismatches. After the first successful OIDC publish, disable traditional token publishing and revoke
|
|
86
|
+
obsolete automation tokens in npm package settings.
|
|
87
|
+
|
|
65
88
|
## Submitted / pending
|
|
66
89
|
|
|
67
90
|
| Channel | How | Status |
|
package/gemini-extension.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "yoke",
|
|
3
|
-
"version": "1.6.
|
|
3
|
+
"version": "1.6.2",
|
|
4
4
|
"description": "Cross-agent coding harness: curated skill canon, mechanical safety gates, autonomous loop with proof artifacts. CLI: npm i -g @hecer/yoke",
|
|
5
5
|
"contextFileName": "GEMINI-EXTENSION.md"
|
|
6
6
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hecer/yoke",
|
|
3
|
-
"version": "1.6.
|
|
3
|
+
"version": "1.6.2",
|
|
4
4
|
"description": "One harness, three agents, zero trust in \"done\" — cross-agent coding harness for Claude Code, Codex CLI, and Gemini CLI: one skill canon, mechanical safety gates, an autonomous loop with screenshot/video proofs.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|