pi-harness-runtime 1.1.446 → 1.1.448
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/AGENTS.md +61 -9
- package/CHANGELOG.md +7 -0
- package/README.md +44 -0
- package/harness/loop-review-agent.ts +10 -7
- package/package.json +2 -1
- package/packages/agent-policy/package.json +1 -1
- package/packages/auth/package.json +1 -1
- package/packages/autonomous-runtime/package.json +1 -1
- package/packages/checkpoint/package.json +1 -1
- package/packages/clipboard/package.json +1 -1
- package/packages/codex-watcher/package.json +1 -1
- package/packages/config-capture/package.json +1 -1
- package/packages/contracts/package.json +1 -1
- package/packages/cookie-sanitizer/package.json +1 -1
- package/packages/evaluation-engine/package.json +1 -1
- package/packages/event-bus/package.json +1 -1
- package/packages/event-store/package.json +1 -1
- package/packages/experience-replay/package.json +1 -1
- package/packages/file-copy-helper/package.json +1 -1
- package/packages/intent-analyzer/package.json +1 -1
- package/packages/jev-judge/package.json +1 -1
- package/packages/knowledge-retrieval/package.json +1 -1
- package/packages/learning-engine/package.json +1 -1
- package/packages/logging/package.json +1 -1
- package/packages/memory-engine/package.json +1 -1
- package/packages/notification/package.json +1 -1
- package/packages/paperclip-integration/package.json +1 -1
- package/packages/performance-optimizer/package.json +1 -1
- package/packages/privilege-broker/package.json +1 -1
- package/packages/prompt-compiler/package.json +1 -1
- package/packages/providers/package.json +1 -1
- package/packages/qdrant-skills/package.json +1 -1
- package/packages/quota-manager/package.json +1 -1
- package/packages/relay/package.json +1 -1
- package/packages/skill-mcp-client/package.json +1 -1
- package/packages/skills/package.json +1 -1
- package/packages/todo-bd-sync/package.json +1 -1
- package/packages/token-estimation/package.json +1 -1
- package/packages/tooling-preference/package.json +1 -1
- package/packages/trajectory/package.json +1 -1
- package/packages/tui/package.json +1 -1
- package/packages/two-phase-review/package.json +1 -1
- package/packages/types/package.json +1 -1
- package/packages/webmcp-tester/package.json +1 -1
- package/packages/wiki/package.json +1 -1
- package/packages/write-review/package.json +1 -1
- package/scripts/copy-plugins.js +12 -2
- package/scripts/sync-skills.ts +19 -4
- package/scripts/sync-to-qdrant.ts +39 -23
package/AGENTS.md
CHANGED
|
@@ -88,7 +88,7 @@ A task with a cheap tier and an expensive tier MUST use the cheap tier while the
|
|
|
88
88
|
|
|
89
89
|
## Versioning Convention
|
|
90
90
|
|
|
91
|
-
**Only patch-level updates (`
|
|
91
|
+
**Only patch-level updates (`1.1.x`)** — no minor/major bumps until the app is fully functional.
|
|
92
92
|
|
|
93
93
|
When releasing:
|
|
94
94
|
|
|
@@ -98,25 +98,77 @@ bun scripts/release-all.ts --release-as minor # only if explicitly requested
|
|
|
98
98
|
bun scripts/release-all.ts --release-as major # only if explicitly requested
|
|
99
99
|
```
|
|
100
100
|
|
|
101
|
-
|
|
101
|
+
The version of a release follows the published history, not the manifest.
|
|
102
|
+
The script reads the last tag and bumps from there, so a release that
|
|
103
|
+
follows `v1.1.447` is `v1.1.448`.
|
|
102
104
|
|
|
103
|
-
|
|
105
|
+
## Release Path: develop -> main -> npm (CRITICAL)
|
|
104
106
|
|
|
105
|
-
|
|
107
|
+
`develop` is the branch the work is done on. `main` is the branch npm
|
|
108
|
+
publishes. A release is a **tag on `main`**, and only such a tag
|
|
109
|
+
publishes.
|
|
106
110
|
|
|
107
111
|
```bash
|
|
108
|
-
#
|
|
109
|
-
git
|
|
112
|
+
# 1. The work is committed to develop and pushed.
|
|
113
|
+
git push origin develop
|
|
110
114
|
|
|
111
|
-
#
|
|
115
|
+
# 2. The version is prepared on develop. The script bumps the manifest,
|
|
116
|
+
# syncs the workspace, commits, pushes develop, and opens the pull
|
|
117
|
+
# request into main.
|
|
112
118
|
bun scripts/release-all.ts --release-as patch
|
|
119
|
+
|
|
120
|
+
# 3. The auto merge workflow merges develop into main as soon as the
|
|
121
|
+
# gates are green: "No sensitive terms" and "Tests".
|
|
122
|
+
# A pull request that is not green waits for a human.
|
|
123
|
+
|
|
124
|
+
# 4. After the merge, the tag is created on the tip of main.
|
|
125
|
+
bun scripts/release-all.ts --tag
|
|
126
|
+
|
|
127
|
+
# 5. The tag triggers release.yml, which publishes to npm through OIDC
|
|
128
|
+
# and creates the GitHub release.
|
|
113
129
|
```
|
|
114
130
|
|
|
115
|
-
**
|
|
131
|
+
**Rules**:
|
|
132
|
+
|
|
133
|
+
- **Never publish from `develop`.** The release workflow refuses a tag
|
|
134
|
+
that is not reachable from `main`.
|
|
135
|
+
- **Never run a local `npm publish`.** The registry is published by the
|
|
136
|
+
release workflow, with the OIDC credential of the repository.
|
|
137
|
+
- **A tag is a release.** The tag names the version, and the version in
|
|
138
|
+
the manifest of `main` has to be the one the tag names.
|
|
139
|
+
- **The npm Trusted Publisher is bound to `release.yml` on `main`.** A
|
|
140
|
+
tag or a branch push cannot publish on its own.
|
|
141
|
+
|
|
142
|
+
## Local Hooks: Husky (CRITICAL)
|
|
143
|
+
|
|
144
|
+
The hooks of the repository live in `.husky/` and are managed by
|
|
145
|
+
[Husky](https://typicode.github.io/husky/). There is no second hook
|
|
146
|
+
mechanism: `core.hooksPath` is `.husky/_`.
|
|
147
|
+
|
|
148
|
+
```bash
|
|
149
|
+
bunx husky # install the hooks (also done by `bun install`)
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
- **`.husky/pre-commit`** scans the staged change for a client name and
|
|
153
|
+
runs `lint-staged` on the staged files.
|
|
154
|
+
- **`.husky/pre-push`** scans the whole pushed range.
|
|
155
|
+
- The terms live in `~/.pi-harness-runtime/sensitive-terms.txt` (mode
|
|
156
|
+
`600`), outside the repository. The list is never committed and never
|
|
157
|
+
printed.
|
|
158
|
+
- The hooks **fail closed**: a machine without the list stops the commit
|
|
159
|
+
and names the way out. `PI_SENSITIVE_TERMS_SKIP=1` is the documented
|
|
160
|
+
way out for a contributor without the private list — the check of the
|
|
161
|
+
repository does that work for them.
|
|
162
|
+
- `git commit --no-verify` and `git push --no-verify` skip the hooks.
|
|
163
|
+
They are an escape hatch for a broken checkout, not a way to work.
|
|
164
|
+
|
|
165
|
+
**The local hook is the primary protection.** This repository and
|
|
166
|
+
`develop` are public: a name that is pushed there is disclosed, and the
|
|
167
|
+
check of the repository can only keep it from being merged.
|
|
116
168
|
|
|
117
169
|
## npm Publish Authentication
|
|
118
170
|
|
|
119
|
-
- **Normal release path: do NOT run local `npm publish`.** Push the
|
|
171
|
+
- **Normal release path: do NOT run local `npm publish`.** Push the change to `develop`, merge it into `main`, and tag `main`; the release workflow publishes through OIDC.
|
|
120
172
|
- **GitHub Actions OIDC release path should not require `npm login`.**
|
|
121
173
|
- If a **local/manual npm publish fallback** is needed and `npm whoami` fails, ask the user to run:
|
|
122
174
|
|
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
|
4
4
|
|
|
5
|
+
### [1.1.448](https://github.com/ManotLuijiu/pi-harness-runtime/compare/v1.1.447...v1.1.448) (2026-10-26)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### Features
|
|
9
|
+
|
|
10
|
+
* **release:** publish from a tag on main and gate the merge on the checks ([d744098](https://github.com/ManotLuijiu/pi-harness-runtime/commit/d7440985974e5bc6613c4e6ee05fb79a00996a0c))
|
|
11
|
+
|
|
5
12
|
### [1.1.190](https://github.com/ManotLuijiu/pi-harness-runtime/compare/v1.1.403...v1.1.190) (2026-10-24)
|
|
6
13
|
|
|
7
14
|
|
package/README.md
CHANGED
|
@@ -1268,6 +1268,50 @@ callbacks are queued on disk instead.
|
|
|
1268
1268
|
> **Note:** the token value is never logged, only the name of the source it came
|
|
1269
1269
|
> from (`env RELAY_AUTH_TOKEN`, `keys/relay-auth-token.txt`, …).
|
|
1270
1270
|
|
|
1271
|
+
## Contributing
|
|
1272
|
+
|
|
1273
|
+
The repository is public, and it holds the guard that keeps a client name
|
|
1274
|
+
out of it. Three layers do that work:
|
|
1275
|
+
|
|
1276
|
+
| Layer | What it does |
|
|
1277
|
+
| ----- | ------------ |
|
|
1278
|
+
| `.husky/pre-commit` | Scans the staged change and the staged paths, and runs `lint-staged` on the staged files. |
|
|
1279
|
+
| `.husky/pre-push` | Scans the whole pushed range. |
|
|
1280
|
+
| `.github/workflows/sensitive-terms.yml` | Scans every push and every pull request. |
|
|
1281
|
+
|
|
1282
|
+
**Local setup**:
|
|
1283
|
+
|
|
1284
|
+
```bash
|
|
1285
|
+
bun install # installs the dependencies and the git hooks
|
|
1286
|
+
bunx husky # only when the hooks are not installed yet
|
|
1287
|
+
```
|
|
1288
|
+
|
|
1289
|
+
The terms live in a private file outside the repository:
|
|
1290
|
+
|
|
1291
|
+
```bash
|
|
1292
|
+
mkdir -p ~/.pi-harness-runtime
|
|
1293
|
+
chmod 700 ~/.pi-harness-runtime
|
|
1294
|
+
printf '%s\n' "the term" >> ~/.pi-harness-runtime/sensitive-terms.txt
|
|
1295
|
+
chmod 600 ~/.pi-harness-runtime/sensitive-terms.txt
|
|
1296
|
+
```
|
|
1297
|
+
|
|
1298
|
+
**Without a list the hooks stop the commit** and name the way out. The
|
|
1299
|
+
list is a private thing, so a contributor who does not have it sets
|
|
1300
|
+
`PI_SENSITIVE_TERMS_SKIP=1` and lets the check of the repository do that
|
|
1301
|
+
work. `git commit --no-verify` and `git push --no-verify` skip the hooks
|
|
1302
|
+
too — they are an escape hatch for a broken checkout, not a way to work.
|
|
1303
|
+
|
|
1304
|
+
**The release path**: the work is committed to `develop`, the version is
|
|
1305
|
+
prepared there, the pull request into `main` is merged by the auto merge
|
|
1306
|
+
workflow once `No sensitive terms` and `Tests` are green, and the tag on
|
|
1307
|
+
`main` publishes to npm through OIDC. A tag that is not on `main`
|
|
1308
|
+
publishes nothing.
|
|
1309
|
+
|
|
1310
|
+
```bash
|
|
1311
|
+
bun scripts/release-all.ts --release-as patch # prepare the version on develop
|
|
1312
|
+
bun scripts/release-all.ts --tag # tag the tip of main after the merge
|
|
1313
|
+
```
|
|
1314
|
+
|
|
1271
1315
|
## License
|
|
1272
1316
|
|
|
1273
1317
|
MIT © 2026 MooCoding
|
|
@@ -86,8 +86,9 @@ async function main(): Promise<void> {
|
|
|
86
86
|
agentId: AGENT_ID,
|
|
87
87
|
taskId: action.taskId,
|
|
88
88
|
status: "success",
|
|
89
|
-
|
|
90
|
-
|
|
89
|
+
summary: verdict,
|
|
90
|
+
createdAt: new Date().toISOString(),
|
|
91
|
+
});
|
|
91
92
|
blackboard.updateAgentStatus(AGENT_ID, "idle");
|
|
92
93
|
|
|
93
94
|
// Decide next action based on verdict
|
|
@@ -117,11 +118,13 @@ async function main(): Promise<void> {
|
|
|
117
118
|
);
|
|
118
119
|
console.log(`[${AGENT_ID}] CHANGES — nextAction: code ${nextWrite}`);
|
|
119
120
|
} else {
|
|
120
|
-
blackboard.setNextAction(
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
121
|
+
blackboard.setNextAction(
|
|
122
|
+
encodeNextAction({
|
|
123
|
+
taskId: "report",
|
|
124
|
+
agentType: "review",
|
|
125
|
+
iteration: 0,
|
|
126
|
+
}),
|
|
127
|
+
);
|
|
125
128
|
console.log(`[${AGENT_ID}] CHANGES — nextAction: report`);
|
|
126
129
|
}
|
|
127
130
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-harness-runtime",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.448",
|
|
4
4
|
"description": "[BETA] Codex-style /usage status + autonomous coding harness for pi. Not production ready — expect breaking changes.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
@@ -211,6 +211,7 @@
|
|
|
211
211
|
"bun-types": "^1.4.3",
|
|
212
212
|
"husky": "^9.1.7",
|
|
213
213
|
"jiti": "2.7.0",
|
|
214
|
+
"lint-staged": "^17.6.0",
|
|
214
215
|
"playwright": "^1.62.0",
|
|
215
216
|
"standard-version": "^9.5.0",
|
|
216
217
|
"typescript": "^7.0.2"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pi-harness/two-phase-review",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.448",
|
|
4
4
|
"description": "pi-harness-runtime — two-phase implementation and review workflow (queue review signals, gate the phase, scope the diff)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
package/scripts/copy-plugins.js
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
|
|
12
12
|
import { mkdirSync, existsSync, readdirSync, cpSync } from "node:fs";
|
|
13
13
|
import { join, dirname } from "node:path";
|
|
14
|
-
import { fileURLToPath } from "node:url";
|
|
14
|
+
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
15
15
|
|
|
16
16
|
const __filename = fileURLToPath(import.meta.url);
|
|
17
17
|
const __dirname = dirname(__filename);
|
|
@@ -57,4 +57,14 @@ function main() {
|
|
|
57
57
|
console.log("[copy-plugins] Done!");
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
-
|
|
60
|
+
/**
|
|
61
|
+
* The program runs only when the file is the entry point.
|
|
62
|
+
*
|
|
63
|
+
* The script is published in the npm package and is the postinstall hook,
|
|
64
|
+
* so a consumer may import it. An import must not copy files into the
|
|
65
|
+
* home directory of the machine that imported it.
|
|
66
|
+
*/
|
|
67
|
+
const entry = process.argv[1];
|
|
68
|
+
if (entry && pathToFileURL(entry).href === import.meta.url) {
|
|
69
|
+
main();
|
|
70
|
+
}
|
package/scripts/sync-skills.ts
CHANGED
|
@@ -11,8 +11,9 @@
|
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
13
|
import { existsSync, mkdirSync, readdirSync, statSync, copyFileSync, rmSync } from "node:fs";
|
|
14
|
-
import { join, basename
|
|
14
|
+
import { join, basename } from "node:path";
|
|
15
15
|
import { homedir } from "node:os";
|
|
16
|
+
import { pathToFileURL } from "node:url";
|
|
16
17
|
|
|
17
18
|
// Default paths
|
|
18
19
|
const DEFAULT_TARGET = join(homedir(), ".pi-harness-runtime", "skills");
|
|
@@ -270,6 +271,20 @@ function syncSkills(options: SyncOptions): void {
|
|
|
270
271
|
console.log(` 3. List skills: /skill list`);
|
|
271
272
|
}
|
|
272
273
|
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
274
|
+
/**
|
|
275
|
+
* The program runs only when the file is the entry point.
|
|
276
|
+
*
|
|
277
|
+
* The script is published in the npm package, so a consumer may import it.
|
|
278
|
+
* An import must not sync skills, and it must not end the importing
|
|
279
|
+
* process - the same rule the harness programs and the command modules
|
|
280
|
+
* follow.
|
|
281
|
+
*/
|
|
282
|
+
function main(): void {
|
|
283
|
+
const options = parseArgs();
|
|
284
|
+
syncSkills(options);
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
const entry = process.argv[1];
|
|
288
|
+
if (entry && pathToFileURL(entry).href === import.meta.url) {
|
|
289
|
+
main();
|
|
290
|
+
}
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
|
|
14
14
|
import { existsSync, readdirSync, readFileSync, statSync } from "node:fs";
|
|
15
15
|
import { join } from "node:path";
|
|
16
|
+
import { pathToFileURL } from "node:url";
|
|
16
17
|
import { QdrantClient } from "@qdrant/js-client-rest";
|
|
17
18
|
// The runtime and this script must write into the SAME collection with the
|
|
18
19
|
// SAME vectors: a collection holds vectors of exactly one size, and a vector
|
|
@@ -343,10 +344,19 @@ async function search(query: string): Promise<void> {
|
|
|
343
344
|
// Main
|
|
344
345
|
// =============================================================================
|
|
345
346
|
|
|
346
|
-
|
|
347
|
+
/**
|
|
348
|
+
* The program runs only when the file is the entry point.
|
|
349
|
+
*
|
|
350
|
+
* The script is published in the npm package, so a consumer may import it.
|
|
351
|
+
* An import must not talk to Qdrant, and it must not end the importing
|
|
352
|
+
* process - the same rule the harness programs and the command modules
|
|
353
|
+
* follow.
|
|
354
|
+
*/
|
|
355
|
+
async function main(): Promise<void> {
|
|
356
|
+
const args = process.argv.slice(2);
|
|
347
357
|
|
|
348
|
-
if (args.includes("--help")) {
|
|
349
|
-
|
|
358
|
+
if (args.includes("--help")) {
|
|
359
|
+
console.log(`
|
|
350
360
|
Sync Skills to Qdrant (Sanitized)
|
|
351
361
|
──────────────────────────────────
|
|
352
362
|
Upload skills to Qdrant for team sharing.
|
|
@@ -373,28 +383,34 @@ Environment:
|
|
|
373
383
|
Or create file:
|
|
374
384
|
~/.pi-harness-runtime/keys/qdrant-api-key.txt
|
|
375
385
|
`);
|
|
376
|
-
|
|
377
|
-
}
|
|
386
|
+
process.exit(0);
|
|
387
|
+
}
|
|
378
388
|
|
|
379
|
-
if (args.includes("--list")) {
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
}
|
|
389
|
+
if (args.includes("--list")) {
|
|
390
|
+
await listSkills();
|
|
391
|
+
process.exit(0);
|
|
392
|
+
}
|
|
383
393
|
|
|
384
|
-
const searchIdx = args.indexOf("--search");
|
|
385
|
-
if (searchIdx !== -1 && args[searchIdx + 1]) {
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
}
|
|
394
|
+
const searchIdx = args.indexOf("--search");
|
|
395
|
+
if (searchIdx !== -1 && args[searchIdx + 1]) {
|
|
396
|
+
await search(args[searchIdx + 1]);
|
|
397
|
+
process.exit(0);
|
|
398
|
+
}
|
|
389
399
|
|
|
390
|
-
const fromIdx = args.indexOf("--from");
|
|
391
|
-
if (fromIdx === -1 || !args[fromIdx + 1]) {
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
}
|
|
400
|
+
const fromIdx = args.indexOf("--from");
|
|
401
|
+
if (fromIdx === -1 || !args[fromIdx + 1]) {
|
|
402
|
+
console.error("Error: --from <directory> is required");
|
|
403
|
+
console.error("Use --help for usage information.");
|
|
404
|
+
process.exit(1);
|
|
405
|
+
}
|
|
396
406
|
|
|
397
|
-
const sourceDir = args[fromIdx + 1];
|
|
398
|
-
const clear = args.includes("--clear");
|
|
407
|
+
const sourceDir = args[fromIdx + 1];
|
|
408
|
+
const clear = args.includes("--clear");
|
|
399
409
|
|
|
400
|
-
await syncToQdrant(sourceDir, clear);
|
|
410
|
+
await syncToQdrant(sourceDir, clear);
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
const entry = process.argv[1];
|
|
414
|
+
if (entry && pathToFileURL(entry).href === import.meta.url) {
|
|
415
|
+
await main();
|
|
416
|
+
}
|