pi-harness-runtime 1.1.423 → 1.1.424

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 (124) hide show
  1. package/README.md +1 -1
  2. package/harness/skills-plan/2026-07-12-herdr-moo-skills-adaptation-plan.md +9 -6
  3. package/package.json +2 -6
  4. package/packages/a2a-adapter/package.json +1 -1
  5. package/packages/agent-policy/package.json +1 -1
  6. package/packages/architecture-generator/package.json +1 -1
  7. package/packages/auth/package.json +1 -1
  8. package/packages/autonomous-refactor/package.json +1 -1
  9. package/packages/autonomous-runtime/package.json +1 -1
  10. package/packages/cache-strategy/package.json +1 -1
  11. package/packages/capability-registry/package.json +1 -1
  12. package/packages/checkpoint/package.json +1 -1
  13. package/packages/cli-plugin-sdk/package.json +1 -1
  14. package/packages/clipboard/package.json +1 -1
  15. package/packages/clipboard-plugin/package.json +1 -1
  16. package/packages/code-generation/package.json +1 -1
  17. package/packages/code-review/package.json +1 -1
  18. package/packages/codex-adapter/package.json +1 -1
  19. package/packages/codex-watcher/package.json +1 -1
  20. package/packages/config-capture/package.json +1 -1
  21. package/packages/connection-runtime/package.json +1 -1
  22. package/packages/context-compiler/package.json +1 -1
  23. package/packages/context-discovery/package.json +1 -1
  24. package/packages/context-manager/package.json +1 -1
  25. package/packages/contracts/package.json +1 -1
  26. package/packages/cookie-sanitizer/package.json +1 -1
  27. package/packages/cost-optimizer/package.json +1 -1
  28. package/packages/dependency-analyzer/package.json +1 -1
  29. package/packages/django-plugin/package.json +1 -1
  30. package/packages/doc-generator/package.json +1 -1
  31. package/packages/durable-review/package.json +1 -1
  32. package/packages/e2e-tester/package.json +1 -1
  33. package/packages/evaluation-engine/package.json +1 -1
  34. package/packages/evaluation-runner/package.json +1 -1
  35. package/packages/event-bus/package.json +1 -1
  36. package/packages/event-sink/package.json +1 -1
  37. package/packages/event-store/package.json +1 -1
  38. package/packages/experience-replay/package.json +1 -1
  39. package/packages/feedback-collector/package.json +1 -1
  40. package/packages/file-copy-helper/package.json +1 -1
  41. package/packages/framework-detector/package.json +1 -1
  42. package/packages/framework-plugin-sdk/package.json +1 -1
  43. package/packages/frappe-plugin/package.json +1 -1
  44. package/packages/generic-web-plugin/package.json +1 -1
  45. package/packages/health-monitor/package.json +1 -1
  46. package/packages/intent-analyzer/package.json +1 -1
  47. package/packages/jev-judge/package.json +1 -1
  48. package/packages/knowledge-graph/package.json +1 -1
  49. package/packages/knowledge-retrieval/package.json +1 -1
  50. package/packages/laravel-plugin/package.json +1 -1
  51. package/packages/learning-engine/package.json +1 -1
  52. package/packages/logging/package.json +1 -1
  53. package/packages/mcp-adapter/package.json +1 -1
  54. package/packages/memory-engine/package.json +1 -1
  55. package/packages/milestone-manager/package.json +1 -1
  56. package/packages/model-registry/package.json +1 -1
  57. package/packages/nextjs-plugin/package.json +1 -1
  58. package/packages/notification/package.json +1 -1
  59. package/packages/observability/package.json +1 -1
  60. package/packages/okf-indexer/package.json +1 -1
  61. package/packages/paperclip-integration/package.json +1 -1
  62. package/packages/performance-optimizer/package.json +1 -1
  63. package/packages/permission-mode/package.json +1 -1
  64. package/packages/privilege-broker/package.json +1 -1
  65. package/packages/project-analyzer/package.json +1 -1
  66. package/packages/project-bootstrap/package.json +1 -1
  67. package/packages/projection-engine/package.json +1 -1
  68. package/packages/prompt-compiler/package.json +1 -1
  69. package/packages/prompt-versioning/package.json +1 -1
  70. package/packages/provider-adapter-sdk/package.json +1 -1
  71. package/packages/provider-router/package.json +1 -1
  72. package/packages/provider-selector/package.json +1 -1
  73. package/packages/providers/package.json +1 -1
  74. package/packages/qdrant-skills/package.json +1 -1
  75. package/packages/quota-manager/package.json +1 -1
  76. package/packages/rate-limiter/package.json +1 -1
  77. package/packages/react-vite-plugin/package.json +1 -1
  78. package/packages/relay/package.json +1 -1
  79. package/packages/release-manager/package.json +1 -1
  80. package/packages/requirement-compiler/package.json +1 -1
  81. package/packages/runtime/package.json +1 -1
  82. package/packages/scheduler/package.json +1 -1
  83. package/packages/scheduler-adapter/package.json +1 -1
  84. package/packages/session/package.json +1 -1
  85. package/packages/session-api/package.json +1 -1
  86. package/packages/session-export/package.json +1 -1
  87. package/packages/shared-context/package.json +1 -1
  88. package/packages/skill-mcp-client/package.json +1 -1
  89. package/packages/skill-registry/package.json +1 -1
  90. package/packages/skills/dist/sanitize-rules.d.ts.map +1 -1
  91. package/packages/skills/dist/sanitize-rules.js +4 -3
  92. package/packages/skills/dist/sanitize-rules.js.map +1 -1
  93. package/packages/skills/package.json +1 -1
  94. package/packages/skills/src/sanitize-rules.ts +4 -3
  95. package/packages/sprint-planner/package.json +1 -1
  96. package/packages/subscription-engine/package.json +1 -1
  97. package/packages/task-compiler/package.json +1 -1
  98. package/packages/telegram/package.json +1 -1
  99. package/packages/tencentdb-memory/package.json +1 -1
  100. package/packages/tencentdb-sync/package.json +1 -1
  101. package/packages/test-data-generator/package.json +1 -1
  102. package/packages/test-generator/package.json +1 -1
  103. package/packages/todo-bd-sync/package.json +1 -1
  104. package/packages/token-estimation/package.json +1 -1
  105. package/packages/token-optimizer/package.json +1 -1
  106. package/packages/tooling-preference/package.json +1 -1
  107. package/packages/trajectory/package.json +1 -1
  108. package/packages/tui/package.json +1 -1
  109. package/packages/two-phase-review/package.json +1 -1
  110. package/packages/types/package.json +1 -1
  111. package/packages/voice-api/package.json +1 -1
  112. package/packages/webmcp-tester/package.json +1 -1
  113. package/packages/wiki/package.json +1 -1
  114. package/packages/workflow-events/package.json +1 -1
  115. package/packages/workspace-scanner/package.json +1 -1
  116. package/packages/worktree/package.json +1 -1
  117. package/packages/write-review/package.json +1 -1
  118. package/plugins/herdr-clipboard/paste.sh +28 -0
  119. package/scripts/copy-plugins.js +9 -5
  120. package/scripts/verify-package-contents.ts +124 -1
  121. package/skills/harness-runtime/SKILL.md +0 -300
  122. /package/{.pi/plugins → plugins}/herdr-clipboard/herdr-plugin.toml +0 -0
  123. /package/{.pi/plugins → plugins}/herdr-clipboard/start-bridge.sh +0 -0
  124. /package/{.pi/plugins → plugins}/herdr-clipboard/tmux-watch.sh +0 -0
@@ -35,7 +35,13 @@ const ROOT = resolve(dirname(fileURLToPath(import.meta.url)), "..");
35
35
  const verifyTarball = process.argv.includes("--pack");
36
36
 
37
37
  interface Problem {
38
- kind: "missing-dist" | "missing-import" | "missing-tarball" | "missing-package";
38
+ kind:
39
+ | "missing-dist"
40
+ | "missing-import"
41
+ | "missing-tarball"
42
+ | "missing-package"
43
+ | "forbidden-path"
44
+ | "missing-plugin";
39
45
  detail: string;
40
46
  }
41
47
 
@@ -53,6 +59,37 @@ const SHIPPED_ROOT_FILES = [
53
59
  "windows.ts",
54
60
  ];
55
61
 
62
+ /**
63
+ * Paths that must never reach the published package.
64
+ *
65
+ * `.pi/` holds per-machine extension state and the user's private skills.
66
+ * `.pi-lens/` holds a local tool policy directory. The skill payload
67
+ * directories hold skill content: skills live in the user's own Qdrant
68
+ * collection and in the installation-local skill store, never in the
69
+ * published repository.
70
+ *
71
+ * `packages/skills/` is NOT in this list: that package is the runtime
72
+ * implementation that loads, queries and indexes skills.
73
+ */
74
+ const FORBIDDEN_PACKAGE_PREFIXES = [
75
+ ".pi/",
76
+ ".pi-lens/",
77
+ "skills/",
78
+ ".agents/skills/",
79
+ ".claude/skills/",
80
+ ];
81
+
82
+ /** The plugin directory that ships with the package. */
83
+ const PLUGIN_DIR = "plugins";
84
+
85
+ /** The files a shipped herdr plugin must contain. */
86
+ const REQUIRED_PLUGIN_FILES = [
87
+ "plugins/herdr-clipboard/herdr-plugin.toml",
88
+ "plugins/herdr-clipboard/paste.sh",
89
+ "plugins/herdr-clipboard/start-bridge.sh",
90
+ "plugins/herdr-clipboard/tmux-watch.sh",
91
+ ];
92
+
56
93
  function listFiles(dir: string, filter: (file: string) => boolean): string[] {
57
94
  if (!existsSync(dir)) return [];
58
95
  const out: string[] = [];
@@ -98,6 +135,68 @@ const STATIC_IMPORT = /import\s+(type\s+)?[^;]*?from\s*["']([^"']+)["']/g;
98
135
  const DYNAMIC_IMPORT = /import\s*\(\s*["']([^"']+)["']\s*\)/g;
99
136
  const SIDE_EFFECT_IMPORT = /(?:^|\n)\s*import\s*["']([^"']+)["']/g;
100
137
 
138
+ /**
139
+ * The published package must not carry a skill payload or a local state
140
+ * directory, and it must carry the plugin that the postinstall copies.
141
+ *
142
+ * The check runs on the git index, because that is what the release commits
143
+ * and what npm packs from.
144
+ */
145
+ function checkPackageLayout(): void {
146
+ const tracked = spawnSync("git", ["ls-files"], {
147
+ cwd: ROOT,
148
+ encoding: "utf8",
149
+ });
150
+ const files =
151
+ tracked.status === 0 ? tracked.stdout.split("\n").filter(Boolean) : [];
152
+
153
+ for (const file of files) {
154
+ const posix = file.split("\\").join("/");
155
+ for (const prefix of FORBIDDEN_PACKAGE_PREFIXES) {
156
+ if (posix.startsWith(prefix)) {
157
+ problems.push({
158
+ kind: "forbidden-path",
159
+ detail: `${posix} is tracked - ${prefix} must not be committed`,
160
+ });
161
+ break;
162
+ }
163
+ }
164
+ }
165
+
166
+ for (const required of REQUIRED_PLUGIN_FILES) {
167
+ if (!files.includes(required)) {
168
+ problems.push({
169
+ kind: "missing-plugin",
170
+ detail: `${required} is not tracked - the plugin would not ship`,
171
+ });
172
+ }
173
+ }
174
+ }
175
+
176
+ /**
177
+ * The postinstall copies the plugin from the package root.
178
+ *
179
+ * When the source directory moved to `plugins/` the copy script kept its
180
+ * old path, and the plugin silently stopped being installed.
181
+ */
182
+ function checkPluginCopySource(): void {
183
+ const script = join(ROOT, "scripts", "copy-plugins.js");
184
+ if (!existsSync(script)) {
185
+ problems.push({
186
+ kind: "missing-plugin",
187
+ detail: "scripts/copy-plugins.js is missing - the plugin would not be installed",
188
+ });
189
+ return;
190
+ }
191
+ const source = readFileSync(script, "utf8");
192
+ if (!source.includes(`"${PLUGIN_DIR}"`)) {
193
+ problems.push({
194
+ kind: "missing-plugin",
195
+ detail: `scripts/copy-plugins.js does not read from the ${PLUGIN_DIR}/ directory`,
196
+ });
197
+ }
198
+ }
199
+
101
200
  function checkImports(): void {
102
201
  for (const file of shippedSourceFiles()) {
103
202
  const content = readFileSync(file, "utf8");
@@ -306,6 +405,28 @@ async function inspectTarball(): Promise<void> {
306
405
  return;
307
406
  }
308
407
 
408
+ for (const file of files) {
409
+ const posix = file.split("\\").join("/");
410
+ for (const prefix of FORBIDDEN_PACKAGE_PREFIXES) {
411
+ if (posix.startsWith(prefix)) {
412
+ problems.push({
413
+ kind: "forbidden-path",
414
+ detail: `${posix} is in the tarball - ${prefix} must not be published`,
415
+ });
416
+ break;
417
+ }
418
+ }
419
+ }
420
+
421
+ for (const required of REQUIRED_PLUGIN_FILES) {
422
+ if (!files.includes(required)) {
423
+ problems.push({
424
+ kind: "missing-plugin",
425
+ detail: `${required} is not in the tarball`,
426
+ });
427
+ }
428
+ }
429
+
309
430
  const inTarball = new Set(files);
310
431
  for (const { file, specifier, target } of runtimeImports.values()) {
311
432
  const relativeTarget = relative(ROOT, target).split("\\").join("/");
@@ -321,6 +442,8 @@ async function inspectTarball(): Promise<void> {
321
442
  }
322
443
  }
323
444
 
445
+ checkPackageLayout();
446
+ checkPluginCopySource();
324
447
  checkImports();
325
448
  checkPackageEntries();
326
449
  checkStaleOutputs();
@@ -1,300 +0,0 @@
1
- ---
2
- description: Local-first, provider-agnostic AI coding harness runtime for pi.dev with quota management and multi-model coordination
3
- ---
4
-
5
- # Harness Runtime — pi Extension
6
-
7
- ## CRITICAL: Todo List Rule
8
-
9
- **When you identify 2+ tasks, issues, or jobs — add ALL of them to the Todo list immediately.**
10
-
11
- Do NOT just list them in text. Use the `todo` tool to create tracked tasks:
12
-
13
- ```bash
14
- # Creating multiple tasks at once
15
- bd create "Fix initialRemotionData not defined" -p 2
16
- bd create "Fix dictionary.title undefined" -p 2
17
- bd create "Replace Film icon with themed icon" -p 2
18
- ```
19
-
20
- **Rule**: If you write something like:
21
-
22
- - "There are 3 issues: ..."
23
- - "I found several problems: ..."
24
- - "Let me fix these: 1) X 2) Y 3) Z"
25
- - "Here are the tasks to do: ..."
26
-
27
- **Then you MUST create Todo items for each one.** Single-issue fixes don't need tracking.
28
-
29
- **Why**: Agents often identify issues verbally but forget to track them. This rule ensures nothing slips through.
30
-
31
- ## Remote Server Commands (SSH)
32
-
33
- **ALWAYS use detached SSH pattern to prevent long hangs.**
34
-
35
- ### Anti-Pattern (blocks SSH, hangs indefinitely)
36
-
37
- ```bash
38
- # WRONG - SSH blocks waiting for background process
39
- ssh user@host "kill old; sleep 2; uvicorn ... &"
40
- # SSH never returns because it waits for uvicorn
41
- ```
42
-
43
- ### Correct Pattern (fast exit, process stays on server)
44
-
45
- ```bash
46
- # CORRECT - SSH exits fast, process continues on server
47
- ssh -o BatchMode=yes user@host \
48
- "kill -9 OLD_PID 2>/dev/null; sleep 1; \
49
- cd /path/to/service && \
50
- nohup .venv/bin/uvicorn amos_api.main:app --host 0.0.0.0 --port 8100 \
51
- > /tmp/uvicorn.log 2>&1 & \
52
- echo 'UVICORN_STARTED'"
53
- ```
54
-
55
- **Key changes:**
56
-
57
- - `nohup ... &` — detaches from SSH session
58
- - `> /tmp/uvicorn.log 2>&1` — captures output to file
59
- - `echo 'UVICORN_STARTED'` — SSH exits fast with confirmation
60
- - `-o BatchMode=yes` — non-interactive, fails fast on auth issues
61
-
62
- **Why this matters**: A bare `&` in SSH keeps the shell open. `nohup` + redirect + `echo` ensures SSH exits immediately while the process runs on the server.
63
-
64
- **For long-running commands**, add a timeout guard:
65
-
66
- ```bash
67
- timeout 60s ssh -o BatchMode=yes user@host "long-command; echo DONE"
68
- ```
69
-
70
- **Status:** v0.3.0 | **RFCs:** 18 defined | **Implementation:** Phase 1-6
71
-
72
- ## Overview
73
-
74
- pi-harness-runtime is a local-first, provider-agnostic AI coding harness runtime for pi.dev. It coordinates multiple AI models to complete software engineering tasks with minimal human intervention.
75
-
76
- ## Core Architecture
77
-
78
- ```
79
- Human Requirement
80
- -> /harness start <requirement>
81
- -> Master Planner (creates task graph)
82
- -> Loop Runtime (executes tasks)
83
- -> Provider Router (selects best model)
84
- -> BlackBoard (coordination)
85
- -> Checkpoint Manager (resumability)
86
- -> Quota Manager (avoid exhaustion)
87
- -> Scheduler (pause/resume)
88
- -> Repair Engine (auto-fix failures)
89
- -> /harness status (report)
90
- ```
91
-
92
- ## Commands
93
-
94
- ### Usage Commands
95
-
96
- | Command | Description |
97
- | --------- | ------------- |
98
- | `/usage` | Show full status (local tracking + provider mirror) |
99
- | `/usage refresh` | Force refresh quota from MiniMax console |
100
- | `/usage today` | Today's usage + 5h window |
101
- | `/usage week` | This week's usage + lifetime |
102
- | `/usage reset` | Clear provider mirror |
103
-
104
- ### Harness Commands
105
-
106
- | Command | Description |
107
- | --------- | ------------- |
108
- | `/harness start <requirement>` | Start a new harness job |
109
- | `/harness status` | Show current job status |
110
- | `/harness tasks` | List all tasks |
111
- | `/harness pause` | Pause the current job |
112
- | `/harness resume` | Resume a paused job |
113
- | `/harness cancel` | Cancel the current job |
114
-
115
- ### Authentication Commands
116
-
117
- | Command | Description |
118
- | --------- | ------------- |
119
- | `/harness auth minimax` | Authenticate with MiniMax (opens browser) |
120
- | `/harness auth check` | Check MiniMax auth status |
121
- | `/harness auth scrape` | Scrape MiniMax usage (silent, uses saved profile) |
122
-
123
- **First-time setup:**
124
-
125
- ```bash
126
- harness-auth auth
127
- # -> Opens Chrome browser, login once, profile auto-saves
128
- # Or: bun packages/auth/src/run-minimax-auth.ts auth
129
- ```
130
-
131
- **Subsequent usage:**
132
-
133
- ```bash
134
- harness-auth scrape
135
- # -> Silent scraping with saved profile
136
- # Or: bun packages/auth/src/run-minimax-auth.ts scrape
137
- ```
138
-
139
- ## Job State Machine
140
-
141
- ```
142
- created -> planning -> queued -> running -> testing -> reviewing
143
- v v v v v
144
- cancelled blocked waiting_human repairing ready_for_client
145
- v v
146
- paused_quota archived
147
- ```
148
-
149
- ### State Transitions
150
-
151
- | From | Valid Transitions |
152
- | ------ | ----------------- |
153
- | created | planning |
154
- | planning | queued, cancelled |
155
- | queued | running, cancelled, waiting_human |
156
- | running | testing, reviewing, repairing, paused_quota, blocked, waiting_human, cancelled |
157
- | testing | reviewing, running, repairing, paused_quota, waiting_human, cancelled |
158
- | reviewing | repairing, running, ready_for_client, paused_quota, waiting_human, cancelled |
159
- | repairing | running, testing, reviewing, paused_quota, waiting_human, cancelled |
160
- | paused_quota | running, waiting_human, cancelled |
161
-
162
- ## Task Graph
163
-
164
- Tasks are organized as a DAG (Directed Acyclic Graph):
165
-
166
- - Tasks with dependencies are marked `pending` until all dependencies are `done`
167
- - Tasks without dependencies start as `ready`
168
- - Only `ready` tasks are picked for execution
169
-
170
- ## Key Components
171
-
172
- ### JobStateMachine (`harness/job-state-machine.ts`)
173
-
174
- - Manages job lifecycle states
175
- - Emits events on every transition
176
- - Auto-checkpoints to disk
177
-
178
- ### TaskGraphManager (`harness/task-graph.ts`)
179
-
180
- - DAG-based task representation
181
- - Tracks task status and dependencies
182
- - Computes topological execution order
183
-
184
- ### MasterPlanner (`harness/master-planner.ts`)
185
-
186
- - Converts requirements to task graphs
187
- - Heuristic planner (no LLM needed)
188
- - LLM-based planner (with provider config)
189
-
190
- ### RepairEngine (`harness/repair-engine.ts`)
191
-
192
- - Converts failures to repair tasks
193
- - Retry policy with exponential backoff
194
- - Auto-escalation after max retries
195
-
196
- ### SharedBlackboard (`harness/blackboard.ts`)
197
-
198
- - File-based agent coordination
199
- - Next-action queue
200
- - Agent registry and locks
201
-
202
- ### LoopRuntime (`harness/loop-runtime.ts`)
203
-
204
- - Core execution loop
205
- - Picks ready tasks, executes, tests, reviews
206
- - Handles failures and quota exhaustion
207
-
208
- ### ContextWindowManager (`harness/context-window-manager.ts`)
209
-
210
- - Tracks context usage per provider
211
- - Warning at 80%, critical at 95%
212
- - Truncation strategy
213
-
214
- ### AgentHandoffProtocol (`harness/agent-handoff.ts`)
215
-
216
- - Clean agent transitions
217
- - Context transfer
218
- - Handoff validation
219
-
220
- ### E2ETestEngine (`harness/e2e/test-engine.ts`)
221
-
222
- - Scenario-based E2E testing
223
- - Screenshot/video on failure
224
- - Playwright runner integration
225
-
226
- ### ProjectDetector (`harness/project-detector/detector.ts`)
227
-
228
- - Auto-detect: Frappe, Next.js, React, Django, Laravel
229
- - Seed strategy recommendation
230
- - E2E strategy recommendation
231
-
232
- ## Providers
233
-
234
- ### Provider Adapter (`packages/providers/adapters.ts`)
235
-
236
- - MiniMax, OpenAI adapters
237
- - Unified error parsing
238
- - Quota signal extraction
239
-
240
- ### Quota Manager (`packages/quota-manager/quota-manager.ts`)
241
-
242
- - Collects signals from API, Playwright, local estimates
243
- - Tracks 5h, daily, weekly, monthly windows
244
- - Selects best available provider
245
-
246
- ### Worktree Manager (`packages/worktree/worktree.ts`)
247
-
248
- - Git worktree per task
249
- - Isolated workspaces
250
- - Diff tracking
251
-
252
- ## Usage Example
253
-
254
- ```typescript
255
- // Start a new job
256
- /harness start Build a REST API with authentication
257
-
258
- // Monitor progress
259
- /harness status
260
- /harness tasks
261
-
262
- // Pause when quota is low
263
- /harness pause
264
-
265
- // Resume when quota resets
266
- /harness resume
267
-
268
- // Cancel if needed
269
- /harness cancel
270
- ```
271
-
272
- ## Data Directory
273
-
274
- All harness data is stored in `~/.pi/harness/`:
275
-
276
- ```
277
- ~/.pi/harness/
278
- jobs/
279
- <job-id>/
280
- checkpoint.json
281
- events.jsonl
282
- task-graph.json
283
- blackboard/
284
- repair-tasks.jsonl
285
- handoffs/
286
- ```
287
-
288
- ## Testing
289
-
290
- Run tests with:
291
-
292
- ```bash
293
- pi-harness-runtime@latest
294
- ```
295
-
296
- ## Related Skills
297
-
298
- - `form-state-persistence-fix` — Step data persistence patterns
299
- - `frappe-gl-preview` — GL entry preview pattern
300
- - `frappe-workflow` — Workflow debugging patterns