pi-harness-runtime 1.1.423 → 1.1.425

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 (123) hide show
  1. package/README.md +1 -1
  2. package/harness/skills-plan/2026-07-12-herdr-moo-skills-adaptation-plan.md +8 -4
  3. package/package.json +6 -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 +180 -1
  121. /package/{.pi/plugins → plugins}/herdr-clipboard/herdr-plugin.toml +0 -0
  122. /package/{.pi/plugins → plugins}/herdr-clipboard/start-bridge.sh +0 -0
  123. /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,63 @@ 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
+ ".agents/skills/",
78
+ ".claude/skills/",
79
+ ];
80
+
81
+ /**
82
+ * The one skill directory the package owns and publishes.
83
+ *
84
+ * `skills/harness-runtime/` is the skill of the package itself: it tells an
85
+ * installed agent what the harness is. It is public content, written for
86
+ * every user of the package, so it ships.
87
+ *
88
+ * Every other directory under `skills/` belongs to a user. Such a skill
89
+ * lives in that user's own Qdrant collection and in their installation-local
90
+ * skill store, and it must never reach the published tarball.
91
+ */
92
+ const PACKAGE_SKILL_DIR = "skills/harness-runtime/";
93
+
94
+ /** The files the published skill directory must contain. */
95
+ const REQUIRED_SKILL_FILES = ["skills/harness-runtime/SKILL.md"];
96
+
97
+ /**
98
+ * Whether a path is a skill payload that the package must not publish.
99
+ *
100
+ * A path under `skills/` is forbidden unless it belongs to the package's
101
+ * own skill directory.
102
+ */
103
+ function isForbiddenSkillPath(path: string): boolean {
104
+ if (!path.startsWith("skills/")) return false;
105
+ return !path.startsWith(PACKAGE_SKILL_DIR);
106
+ }
107
+
108
+ /** The plugin directory that ships with the package. */
109
+ const PLUGIN_DIR = "plugins";
110
+
111
+ /** The files a shipped herdr plugin must contain. */
112
+ const REQUIRED_PLUGIN_FILES = [
113
+ "plugins/herdr-clipboard/herdr-plugin.toml",
114
+ "plugins/herdr-clipboard/paste.sh",
115
+ "plugins/herdr-clipboard/start-bridge.sh",
116
+ "plugins/herdr-clipboard/tmux-watch.sh",
117
+ ];
118
+
56
119
  function listFiles(dir: string, filter: (file: string) => boolean): string[] {
57
120
  if (!existsSync(dir)) return [];
58
121
  const out: string[] = [];
@@ -98,6 +161,83 @@ const STATIC_IMPORT = /import\s+(type\s+)?[^;]*?from\s*["']([^"']+)["']/g;
98
161
  const DYNAMIC_IMPORT = /import\s*\(\s*["']([^"']+)["']\s*\)/g;
99
162
  const SIDE_EFFECT_IMPORT = /(?:^|\n)\s*import\s*["']([^"']+)["']/g;
100
163
 
164
+ /**
165
+ * The published package must not carry a skill payload or a local state
166
+ * directory, and it must carry the plugin that the postinstall copies.
167
+ *
168
+ * The check runs on the git index, because that is what the release commits
169
+ * and what npm packs from.
170
+ */
171
+ function checkPackageLayout(): void {
172
+ const tracked = spawnSync("git", ["ls-files"], {
173
+ cwd: ROOT,
174
+ encoding: "utf8",
175
+ });
176
+ const files =
177
+ tracked.status === 0 ? tracked.stdout.split("\n").filter(Boolean) : [];
178
+
179
+ for (const file of files) {
180
+ const posix = file.split("\\").join("/");
181
+ for (const prefix of FORBIDDEN_PACKAGE_PREFIXES) {
182
+ if (posix.startsWith(prefix)) {
183
+ problems.push({
184
+ kind: "forbidden-path",
185
+ detail: `${posix} is tracked - ${prefix} must not be committed`,
186
+ });
187
+ break;
188
+ }
189
+ }
190
+ if (isForbiddenSkillPath(posix)) {
191
+ problems.push({
192
+ kind: "forbidden-path",
193
+ detail: `${posix} is tracked - only ${PACKAGE_SKILL_DIR} may be committed`,
194
+ });
195
+ }
196
+ }
197
+
198
+ for (const required of REQUIRED_PLUGIN_FILES) {
199
+ if (!files.includes(required)) {
200
+ problems.push({
201
+ kind: "missing-plugin",
202
+ detail: `${required} is not tracked - the plugin would not ship`,
203
+ });
204
+ }
205
+ }
206
+
207
+ for (const required of REQUIRED_SKILL_FILES) {
208
+ if (!files.includes(required)) {
209
+ problems.push({
210
+ kind: "missing-plugin",
211
+ detail: `${required} is not tracked - the package would ship no skill`,
212
+ });
213
+ }
214
+ }
215
+ }
216
+
217
+ /**
218
+ * The postinstall copies the plugin from the package root.
219
+ *
220
+ * When the source directory moved to `plugins/` the copy script kept its
221
+ * old path, and the plugin silently stopped being installed.
222
+ */
223
+ function checkPluginCopySource(): void {
224
+ const script = join(ROOT, "scripts", "copy-plugins.js");
225
+ if (!existsSync(script)) {
226
+ problems.push({
227
+ kind: "missing-plugin",
228
+ detail: "scripts/copy-plugins.js is missing - the plugin would not be installed",
229
+ });
230
+ return;
231
+ }
232
+ const source = readFileSync(script, "utf8");
233
+ if (!source.includes(`"${PLUGIN_DIR}"`)) {
234
+ problems.push({
235
+ kind: "missing-plugin",
236
+ detail: `scripts/copy-plugins.js does not read from the ${PLUGIN_DIR}/ directory`,
237
+ });
238
+ }
239
+ }
240
+
101
241
  function checkImports(): void {
102
242
  for (const file of shippedSourceFiles()) {
103
243
  const content = readFileSync(file, "utf8");
@@ -306,6 +446,43 @@ async function inspectTarball(): Promise<void> {
306
446
  return;
307
447
  }
308
448
 
449
+ for (const file of files) {
450
+ const posix = file.split("\\").join("/");
451
+ for (const prefix of FORBIDDEN_PACKAGE_PREFIXES) {
452
+ if (posix.startsWith(prefix)) {
453
+ problems.push({
454
+ kind: "forbidden-path",
455
+ detail: `${posix} is in the tarball - ${prefix} must not be published`,
456
+ });
457
+ break;
458
+ }
459
+ }
460
+ if (isForbiddenSkillPath(posix)) {
461
+ problems.push({
462
+ kind: "forbidden-path",
463
+ detail: `${posix} is in the tarball - only ${PACKAGE_SKILL_DIR} may be published`,
464
+ });
465
+ }
466
+ }
467
+
468
+ for (const required of REQUIRED_PLUGIN_FILES) {
469
+ if (!files.includes(required)) {
470
+ problems.push({
471
+ kind: "missing-plugin",
472
+ detail: `${required} is not in the tarball`,
473
+ });
474
+ }
475
+ }
476
+
477
+ for (const required of REQUIRED_SKILL_FILES) {
478
+ if (!files.includes(required)) {
479
+ problems.push({
480
+ kind: "missing-plugin",
481
+ detail: `${required} is not in the tarball`,
482
+ });
483
+ }
484
+ }
485
+
309
486
  const inTarball = new Set(files);
310
487
  for (const { file, specifier, target } of runtimeImports.values()) {
311
488
  const relativeTarget = relative(ROOT, target).split("\\").join("/");
@@ -321,6 +498,8 @@ async function inspectTarball(): Promise<void> {
321
498
  }
322
499
  }
323
500
 
501
+ checkPackageLayout();
502
+ checkPluginCopySource();
324
503
  checkImports();
325
504
  checkPackageEntries();
326
505
  checkStaleOutputs();