pi-harness-runtime 1.1.422 → 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 (143) 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/index.ts +32 -1
  4. package/package.json +2 -6
  5. package/packages/a2a-adapter/package.json +1 -1
  6. package/packages/agent-policy/package.json +1 -1
  7. package/packages/architecture-generator/package.json +1 -1
  8. package/packages/auth/package.json +1 -1
  9. package/packages/autonomous-refactor/package.json +1 -1
  10. package/packages/autonomous-runtime/package.json +1 -1
  11. package/packages/cache-strategy/package.json +1 -1
  12. package/packages/capability-registry/package.json +1 -1
  13. package/packages/checkpoint/package.json +1 -1
  14. package/packages/cli-plugin-sdk/package.json +1 -1
  15. package/packages/clipboard/package.json +1 -1
  16. package/packages/clipboard-plugin/package.json +1 -1
  17. package/packages/code-generation/package.json +1 -1
  18. package/packages/code-review/package.json +1 -1
  19. package/packages/codex-adapter/package.json +1 -1
  20. package/packages/codex-watcher/package.json +1 -1
  21. package/packages/config-capture/package.json +1 -1
  22. package/packages/connection-runtime/package.json +1 -1
  23. package/packages/context-compiler/package.json +1 -1
  24. package/packages/context-discovery/package.json +1 -1
  25. package/packages/context-manager/package.json +1 -1
  26. package/packages/contracts/package.json +1 -1
  27. package/packages/cookie-sanitizer/package.json +1 -1
  28. package/packages/cost-optimizer/package.json +1 -1
  29. package/packages/dependency-analyzer/package.json +1 -1
  30. package/packages/django-plugin/package.json +1 -1
  31. package/packages/doc-generator/package.json +1 -1
  32. package/packages/durable-review/package.json +1 -1
  33. package/packages/e2e-tester/package.json +1 -1
  34. package/packages/evaluation-engine/package.json +1 -1
  35. package/packages/evaluation-runner/package.json +1 -1
  36. package/packages/event-bus/package.json +1 -1
  37. package/packages/event-sink/package.json +1 -1
  38. package/packages/event-store/package.json +1 -1
  39. package/packages/experience-replay/package.json +1 -1
  40. package/packages/feedback-collector/package.json +1 -1
  41. package/packages/file-copy-helper/package.json +1 -1
  42. package/packages/framework-detector/package.json +1 -1
  43. package/packages/framework-plugin-sdk/package.json +1 -1
  44. package/packages/frappe-plugin/package.json +1 -1
  45. package/packages/generic-web-plugin/package.json +1 -1
  46. package/packages/health-monitor/package.json +1 -1
  47. package/packages/intent-analyzer/package.json +1 -1
  48. package/packages/jev-judge/package.json +1 -1
  49. package/packages/knowledge-graph/package.json +1 -1
  50. package/packages/knowledge-retrieval/package.json +1 -1
  51. package/packages/laravel-plugin/package.json +1 -1
  52. package/packages/learning-engine/package.json +1 -1
  53. package/packages/logging/package.json +1 -1
  54. package/packages/mcp-adapter/package.json +1 -1
  55. package/packages/memory-engine/package.json +1 -1
  56. package/packages/milestone-manager/package.json +1 -1
  57. package/packages/model-registry/package.json +1 -1
  58. package/packages/nextjs-plugin/package.json +1 -1
  59. package/packages/notification/package.json +1 -1
  60. package/packages/observability/package.json +1 -1
  61. package/packages/okf-indexer/package.json +1 -1
  62. package/packages/paperclip-integration/package.json +1 -1
  63. package/packages/performance-optimizer/package.json +1 -1
  64. package/packages/permission-mode/package.json +1 -1
  65. package/packages/privilege-broker/package.json +1 -1
  66. package/packages/project-analyzer/package.json +1 -1
  67. package/packages/project-bootstrap/package.json +1 -1
  68. package/packages/projection-engine/package.json +1 -1
  69. package/packages/prompt-compiler/package.json +1 -1
  70. package/packages/prompt-versioning/package.json +1 -1
  71. package/packages/provider-adapter-sdk/package.json +1 -1
  72. package/packages/provider-router/package.json +1 -1
  73. package/packages/provider-selector/package.json +1 -1
  74. package/packages/providers/package.json +1 -1
  75. package/packages/qdrant-skills/package.json +1 -1
  76. package/packages/quota-manager/package.json +1 -1
  77. package/packages/rate-limiter/package.json +1 -1
  78. package/packages/react-vite-plugin/package.json +1 -1
  79. package/packages/relay/package.json +1 -1
  80. package/packages/release-manager/package.json +1 -1
  81. package/packages/requirement-compiler/package.json +1 -1
  82. package/packages/runtime/package.json +1 -1
  83. package/packages/scheduler/package.json +1 -1
  84. package/packages/scheduler-adapter/package.json +1 -1
  85. package/packages/session/package.json +1 -1
  86. package/packages/session-api/package.json +1 -1
  87. package/packages/session-export/package.json +1 -1
  88. package/packages/shared-context/package.json +1 -1
  89. package/packages/skill-mcp-client/package.json +1 -1
  90. package/packages/skill-registry/package.json +1 -1
  91. package/packages/skills/dist/index.d.ts.map +1 -1
  92. package/packages/skills/dist/index.js +12 -4
  93. package/packages/skills/dist/index.js.map +1 -1
  94. package/packages/skills/dist/sanitize-rules.d.ts +93 -0
  95. package/packages/skills/dist/sanitize-rules.d.ts.map +1 -0
  96. package/packages/skills/dist/sanitize-rules.js +174 -0
  97. package/packages/skills/dist/sanitize-rules.js.map +1 -0
  98. package/packages/skills/dist/sanitize.d.ts +13 -2
  99. package/packages/skills/dist/sanitize.d.ts.map +1 -1
  100. package/packages/skills/dist/sanitize.js +14 -48
  101. package/packages/skills/dist/sanitize.js.map +1 -1
  102. package/packages/skills/dist/vector-schema.d.ts +7 -1
  103. package/packages/skills/dist/vector-schema.d.ts.map +1 -1
  104. package/packages/skills/dist/vector-schema.js +10 -5
  105. package/packages/skills/dist/vector-schema.js.map +1 -1
  106. package/packages/skills/package.json +1 -1
  107. package/packages/skills/src/index.ts +12 -5
  108. package/packages/skills/src/sanitize-rules.ts +219 -0
  109. package/packages/skills/src/sanitize.ts +26 -56
  110. package/packages/skills/src/vector-schema.ts +22 -14
  111. package/packages/skills/test/remote-skills.test.ts +33 -6
  112. package/packages/skills/test/sanitize.test.ts +163 -44
  113. package/packages/sprint-planner/package.json +1 -1
  114. package/packages/subscription-engine/package.json +1 -1
  115. package/packages/task-compiler/package.json +1 -1
  116. package/packages/telegram/package.json +1 -1
  117. package/packages/tencentdb-memory/package.json +1 -1
  118. package/packages/tencentdb-sync/package.json +1 -1
  119. package/packages/test-data-generator/package.json +1 -1
  120. package/packages/test-generator/package.json +1 -1
  121. package/packages/todo-bd-sync/package.json +1 -1
  122. package/packages/token-estimation/package.json +1 -1
  123. package/packages/token-optimizer/package.json +1 -1
  124. package/packages/tooling-preference/package.json +1 -1
  125. package/packages/trajectory/package.json +1 -1
  126. package/packages/tui/package.json +1 -1
  127. package/packages/two-phase-review/package.json +1 -1
  128. package/packages/types/package.json +1 -1
  129. package/packages/voice-api/package.json +1 -1
  130. package/packages/webmcp-tester/package.json +1 -1
  131. package/packages/wiki/package.json +1 -1
  132. package/packages/workflow-events/package.json +1 -1
  133. package/packages/workspace-scanner/package.json +1 -1
  134. package/packages/worktree/package.json +1 -1
  135. package/packages/write-review/package.json +1 -1
  136. package/plugins/herdr-clipboard/paste.sh +28 -0
  137. package/scripts/copy-plugins.js +9 -5
  138. package/scripts/sync-to-qdrant.ts +5 -9
  139. package/scripts/verify-package-contents.ts +124 -1
  140. package/skills/harness-runtime/SKILL.md +0 -300
  141. /package/{.pi/plugins → plugins}/herdr-clipboard/herdr-plugin.toml +0 -0
  142. /package/{.pi/plugins → plugins}/herdr-clipboard/start-bridge.sh +0 -0
  143. /package/{.pi/plugins → plugins}/herdr-clipboard/tmux-watch.sh +0 -0
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/observability",
3
- "version": "1.1.422",
3
+ "version": "1.1.424",
4
4
  "description": "Comprehensive observability system with structured logging, tracing, metrics, and alerting",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/okf-indexer",
3
- "version": "1.1.422",
3
+ "version": "1.1.424",
4
4
  "description": "OKF document indexer for SKILL.md files (RFC-0106)",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/paperclip-integration",
3
- "version": "1.1.422",
3
+ "version": "1.1.424",
4
4
  "description": "Paperclip API integration: poll agent inbox, route tasks to pi.dev, Telegram alerts",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/performance-optimizer",
3
- "version": "1.1.422",
3
+ "version": "1.1.424",
4
4
  "description": "Performance optimization analyzer for pi-harness runtime (RFC-0056)",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/permission-mode",
3
- "version": "1.1.422",
3
+ "version": "1.1.424",
4
4
  "type": "module",
5
5
  "description": "Runtime permission modes for pi-harness - Supervised/Auto/Full-access",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/privilege-broker",
3
- "version": "1.1.422",
3
+ "version": "1.1.424",
4
4
  "description": "Privilege Broker — capability registry and command executor for autonomous runtime (RFC-0101 §7)",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/project-analyzer",
3
- "version": "1.1.422",
3
+ "version": "1.1.424",
4
4
  "description": "Project analysis system for pi-harness-runtime - detects frameworks, rules, and project structure",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/project-bootstrap",
3
- "version": "1.1.422",
3
+ "version": "1.1.424",
4
4
  "description": "Project scaffolding from typed ProjectSpec",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/projection-engine",
3
- "version": "1.1.422",
3
+ "version": "1.1.424",
4
4
  "type": "module",
5
5
  "main": "src/index.ts",
6
6
  "exports": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/prompt-compiler",
3
- "version": "1.1.422",
3
+ "version": "1.1.424",
4
4
  "description": "Deterministic prompt compiler for pi-harness-runtime",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/prompt-versioning",
3
- "version": "1.1.422",
3
+ "version": "1.1.424",
4
4
  "type": "module",
5
5
  "description": "Version control for prompts with rollback support (RFC-0019)",
6
6
  "main": "dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/provider-adapter-sdk",
3
- "version": "1.1.422",
3
+ "version": "1.1.424",
4
4
  "description": "SDK for building, testing, and registering AI provider adapters",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/provider-router",
3
- "version": "1.1.422",
3
+ "version": "1.1.424",
4
4
  "description": "Enhanced Provider Router for pi-harness-runtime — intelligent routing with capabilities, costs, and quotas",
5
5
  "type": "module",
6
6
  "main": "./dist/provider-router.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/provider-selector",
3
- "version": "1.1.422",
3
+ "version": "1.1.424",
4
4
  "description": "Multi-Provider Selector — route requests by cost, quality, and latency (RFC-0012)",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/providers",
3
- "version": "1.1.422",
3
+ "version": "1.1.424",
4
4
  "description": "pi-harness-runtime — providers",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/qdrant-skills",
3
- "version": "1.1.422",
3
+ "version": "1.1.424",
4
4
  "description": "Qdrant vector search integration for Hermes-style skill system",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/quota-manager",
3
- "version": "1.1.422",
3
+ "version": "1.1.424",
4
4
  "description": "pi-harness-runtime — quota-manager",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/rate-limiter",
3
- "version": "1.1.422",
3
+ "version": "1.1.424",
4
4
  "type": "module",
5
5
  "description": "Rate limiting with token bucket algorithm (RFC-0023)",
6
6
  "main": "dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/react-vite-plugin",
3
- "version": "1.1.422",
3
+ "version": "1.1.424",
4
4
  "description": "React/Vite framework analysis — components, config, TypeScript setup",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/relay",
3
- "version": "1.1.422",
3
+ "version": "1.1.424",
4
4
  "type": "module",
5
5
  "description": "Cloud relay for remote access - T3 Connect style for pi-harness",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/release-manager",
3
- "version": "1.1.422",
3
+ "version": "1.1.424",
4
4
  "type": "module",
5
5
  "description": "Release management for pi-harness",
6
6
  "main": "dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/requirement-compiler",
3
- "version": "1.1.422",
3
+ "version": "1.1.424",
4
4
  "description": "Compiles raw requirements into validated CompiledRequirement with ambiguity detection and risk tagging",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/runtime",
3
- "version": "1.1.422",
3
+ "version": "1.1.424",
4
4
  "description": "pi-harness-runtime — runtime",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/scheduler",
3
- "version": "1.1.422",
3
+ "version": "1.1.424",
4
4
  "description": "pi-harness-runtime — scheduler",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/scheduler-adapter",
3
- "version": "1.1.422",
3
+ "version": "1.1.424",
4
4
  "description": "Scheduler Adapter — cron, systemd, launchd, internal adapters for autonomous runtime (RFC-0101 §6)",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/session",
3
- "version": "1.1.422",
3
+ "version": "1.1.424",
4
4
  "description": "Session management system for pi-harness-runtime",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/session-api",
3
- "version": "1.1.422",
3
+ "version": "1.1.424",
4
4
  "type": "module",
5
5
  "main": "src/index.ts",
6
6
  "exports": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/session-export",
3
- "version": "1.1.422",
3
+ "version": "1.1.424",
4
4
  "type": "module",
5
5
  "main": "src/index.ts",
6
6
  "exports": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/shared-context",
3
- "version": "1.1.422",
3
+ "version": "1.1.424",
4
4
  "description": "pi-harness-runtime — shared-context",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/skill-mcp-client",
3
- "version": "1.1.422",
3
+ "version": "1.1.424",
4
4
  "description": "MCP client for Skills SaaS backend",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/skill-registry",
3
- "version": "1.1.422",
3
+ "version": "1.1.424",
4
4
  "description": "Skill Registry for pi-harness-runtime — dynamic skill discovery and invocation",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,oBAAoB,CAAC;AACnC,cAAc,eAAe,CAAC;AAC9B,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,iBAAiB,CAAC;AAChC,cAAc,uBAAuB,CAAC;AACtC,cAAc,aAAa,CAAC;AAE5B,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAe,MAAM,YAAY,CAAC;AAExE,OAAO,EAA0B,KAAK,aAAa,EAAE,MAAM,aAAa,CAAC;AAEzE;;;;;;GAMG;AACH,MAAM,WAAW,gBAAiB,SAAQ,UAAU;IAClD,kDAAkD;IAClD,QAAQ,EAAE,aAAa,CAAC;CACzB;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CACxB,MAAM,CAAC,EAAE,OAAO,CACd,YAAY,GAAG;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,EAAE,aAAa,CAAC;CAC1B,CACF,GACA,gBAAgB,CAuBlB;AAkCD;;GAEG;AACH,wBAAgB,gBAAgB;;;;;;;;;EAyB/B;AAGD,eAAO,MAAM,oBAAoB,EAAE,YAYlC,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,oBAAoB,CAAC;AACnC,cAAc,eAAe,CAAC;AAC9B,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,iBAAiB,CAAC;AAChC,cAAc,uBAAuB,CAAC;AACtC,cAAc,aAAa,CAAC;AAE5B,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAe,MAAM,YAAY,CAAC;AAExE,OAAO,EAA0B,KAAK,aAAa,EAAE,MAAM,aAAa,CAAC;AAKzE;;;;;;GAMG;AACH,MAAM,WAAW,gBAAiB,SAAQ,UAAU;IAClD,kDAAkD;IAClD,QAAQ,EAAE,aAAa,CAAC;CACzB;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CACxB,MAAM,CAAC,EAAE,OAAO,CACd,YAAY,GAAG;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,EAAE,aAAa,CAAC;CAC1B,CACF,GACA,gBAAgB,CA+BlB;AA8BD;;GAEG;AACH,wBAAgB,gBAAgB;;;;;;;;;EAyB/B;AAGD,eAAO,MAAM,oBAAoB,EAAE,YAYlC,CAAC"}
@@ -21,6 +21,9 @@ export * from "./skill-versioning.js";
21
21
  export * from "./linter.js";
22
22
  import { scanForSkillsSync } from "./scanner.js";
23
23
  import { getGlobalSkillRegistry } from "./loader.js";
24
+ import { existsSync, readdirSync } from "node:fs";
25
+ import { homedir } from "node:os";
26
+ import { join } from "node:path";
24
27
  /**
25
28
  * Initialize skills system
26
29
  *
@@ -46,14 +49,19 @@ export function initSkills(config) {
46
49
  }
47
50
  // Hint: if ~/.pi-harness-runtime/skills/ is empty, suggest the sync script
48
51
  checkEmptySkillsDir();
49
- return { ...result, registry };
52
+ // The scan can find the same skill twice: a symlinked directory is
53
+ // scanned twice, because the scanner follows the path it is given. The
54
+ // registry keeps one entry per id, so the count of the local skills is
55
+ // the count of the DISTINCT skills - and not the count of the files
56
+ // that were read.
57
+ const distinct = new Map();
58
+ for (const skill of result.skills)
59
+ distinct.set(skill.id, skill);
60
+ return { ...result, skills: [...distinct.values()], registry };
50
61
  }
51
62
  /** Show sync hint if the harness skills dir is empty. */
52
63
  function checkEmptySkillsDir() {
53
64
  try {
54
- const { readdirSync, existsSync } = require("node:fs");
55
- const { join } = require("node:path");
56
- const { homedir } = require("node:os");
57
65
  const harnessDir = join(homedir(), ".pi-harness-runtime", "skills");
58
66
  if (!existsSync(harnessDir))
59
67
  return;
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,93 @@
1
+ /**
2
+ * The rules that keep a client name out of the shared collection.
3
+ *
4
+ * The names of the clients of the users of the harness are **not** in this
5
+ * repository. The repository is public, and a list of client names in it
6
+ * is a list of client names in the world - the names of the projects and
7
+ * of the clients of every person who installs the package.
8
+ *
9
+ * The rules therefore live in a local file:
10
+ *
11
+ * ~/.pi-harness-runtime/skill-sanitization.json
12
+ *
13
+ * and this module is the mechanism that reads them and applies them. The
14
+ * file is per installation, so a machine holds the rules of its own
15
+ * clients and nobody else's.
16
+ *
17
+ * The file is optional. Without it only the generic rules apply, and the
18
+ * name of a client would travel into the collection of that installation.
19
+ * `sanitizationStatus()` tells the caller which of the two is the case,
20
+ * so a missing file is a visible state and not a silent one.
21
+ *
22
+ * The format of the file:
23
+ *
24
+ * ```json
25
+ * {
26
+ * "rules": [
27
+ * { "pattern": "acme", "replacement": "[Client A]", "flags": "gi" }
28
+ * ],
29
+ * "nameMap": {
30
+ * "acme-approval-workflow": "client-a-approval-workflow"
31
+ * }
32
+ * }
33
+ * ```
34
+ *
35
+ * The pattern is the source of a regular expression and the flags default
36
+ * to "gi". The rules match a plain fragment, without a word boundary: a
37
+ * client name rarely stands alone, it appears inside a directory name
38
+ * (`erp_report_2024.json`), inside a module name (`acme_pharma`) or in a
39
+ * sentence ("integrated with Acme"). A word boundary would miss all of
40
+ * them - and `_` is a word character, so a boundary never follows an
41
+ * underscore.
42
+ */
43
+ /** A rule as it is written in the local file. */
44
+ export interface SanitizationRuleSpec {
45
+ /** The source of a regular expression. */
46
+ pattern: string;
47
+ /** What a match becomes. */
48
+ replacement: string;
49
+ /** The flags of the regular expression. Defaults to "gi". */
50
+ flags?: string;
51
+ }
52
+ /** A compiled rule. */
53
+ export interface SanitizationRule {
54
+ pattern: RegExp;
55
+ replacement: string;
56
+ }
57
+ /** The whole rule set of one installation. */
58
+ export interface SanitizationRuleSet {
59
+ /** The rules, in the order they are applied. */
60
+ rules: SanitizationRule[];
61
+ /** The names that are renamed as a whole. */
62
+ nameMap: Record<string, string>;
63
+ /** Where the rules came from. */
64
+ source: "local-file" | "generic-only";
65
+ /** Why the local file did not contribute its rules. */
66
+ error?: string;
67
+ }
68
+ /** Where the rules of this installation live. */
69
+ export declare function sanitizationFilePath(): string;
70
+ /**
71
+ * The state of the rules of this installation.
72
+ *
73
+ * `configured` is false when the local file is missing or unreadable. The
74
+ * caller shows it, because a missing file is a weaker privacy guarantee
75
+ * and not a detail.
76
+ */
77
+ export declare function sanitizationStatus(): {
78
+ configured: boolean;
79
+ path: string;
80
+ ruleCount: number;
81
+ error?: string;
82
+ };
83
+ /**
84
+ * The rules of this installation.
85
+ *
86
+ * The file is read once per process: the rules do not change while the
87
+ * harness runs, and a skill that is indexed a hundred times must not read
88
+ * a file a hundred times.
89
+ */
90
+ export declare function loadSanitizationRules(path?: string): SanitizationRuleSet;
91
+ /** Forget the cached rules. A test needs it, a new file needs it. */
92
+ export declare function resetSanitizationRulesCache(): void;
93
+ //# sourceMappingURL=sanitize-rules.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sanitize-rules.d.ts","sourceRoot":"","sources":["../src/sanitize-rules.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AAMH,iDAAiD;AACjD,MAAM,WAAW,oBAAoB;IACnC,0CAA0C;IAC1C,OAAO,EAAE,MAAM,CAAC;IAChB,4BAA4B;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,6DAA6D;IAC7D,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,uBAAuB;AACvB,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,8CAA8C;AAC9C,MAAM,WAAW,mBAAmB;IAClC,gDAAgD;IAChD,KAAK,EAAE,gBAAgB,EAAE,CAAC;IAC1B,6CAA6C;IAC7C,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,iCAAiC;IACjC,MAAM,EAAE,YAAY,GAAG,cAAc,CAAC;IACtC,uDAAuD;IACvD,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AA2BD,iDAAiD;AACjD,wBAAgB,oBAAoB,IAAI,MAAM,CAK7C;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,IAAI;IACpC,UAAU,EAAE,OAAO,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CASA;AAID;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,SAAyB,GAAG,mBAAmB,CAMxF;AAED,qEAAqE;AACrE,wBAAgB,2BAA2B,IAAI,IAAI,CAElD"}
@@ -0,0 +1,174 @@
1
+ /**
2
+ * The rules that keep a client name out of the shared collection.
3
+ *
4
+ * The names of the clients of the users of the harness are **not** in this
5
+ * repository. The repository is public, and a list of client names in it
6
+ * is a list of client names in the world - the names of the projects and
7
+ * of the clients of every person who installs the package.
8
+ *
9
+ * The rules therefore live in a local file:
10
+ *
11
+ * ~/.pi-harness-runtime/skill-sanitization.json
12
+ *
13
+ * and this module is the mechanism that reads them and applies them. The
14
+ * file is per installation, so a machine holds the rules of its own
15
+ * clients and nobody else's.
16
+ *
17
+ * The file is optional. Without it only the generic rules apply, and the
18
+ * name of a client would travel into the collection of that installation.
19
+ * `sanitizationStatus()` tells the caller which of the two is the case,
20
+ * so a missing file is a visible state and not a silent one.
21
+ *
22
+ * The format of the file:
23
+ *
24
+ * ```json
25
+ * {
26
+ * "rules": [
27
+ * { "pattern": "acme", "replacement": "[Client A]", "flags": "gi" }
28
+ * ],
29
+ * "nameMap": {
30
+ * "acme-approval-workflow": "client-a-approval-workflow"
31
+ * }
32
+ * }
33
+ * ```
34
+ *
35
+ * The pattern is the source of a regular expression and the flags default
36
+ * to "gi". The rules match a plain fragment, without a word boundary: a
37
+ * client name rarely stands alone, it appears inside a directory name
38
+ * (`erp_report_2024.json`), inside a module name (`acme_pharma`) or in a
39
+ * sentence ("integrated with Acme"). A word boundary would miss all of
40
+ * them - and `_` is a word character, so a boundary never follows an
41
+ * underscore.
42
+ */
43
+ import { readFileSync } from "node:fs";
44
+ import { homedir } from "node:os";
45
+ import { join } from "node:path";
46
+ /**
47
+ * The rules that hold for every installation.
48
+ *
49
+ * They are about the way a text talks about a client, not about the name
50
+ * of a client: "Company Name" is a placeholder in a template, and it
51
+ * must not become a client name in the collection.
52
+ */
53
+ const GENERIC_RULES = [
54
+ { pattern: /Company Name/gi, replacement: "[Client Name]" },
55
+ { pattern: /your company/gi, replacement: "[Client]" },
56
+ { pattern: /our client/gi, replacement: "[Client]" },
57
+ { pattern: /client-specific/gi, replacement: "[Project-specific]" },
58
+ ];
59
+ /**
60
+ * The names that are renamed as a whole, for every installation.
61
+ *
62
+ * A name that would be unreadable after the pattern rules - a name that
63
+ * carries the client name in its middle - is renamed here.
64
+ *
65
+ * The map is empty: a name that belongs to a client is that client's, so it
66
+ * lives in the local file next to the other rules of the installation.
67
+ */
68
+ const GENERIC_NAME_MAP = {};
69
+ /** Where the rules of this installation live. */
70
+ export function sanitizationFilePath() {
71
+ const override = process.env.PI_SKILL_SANITIZATION_FILE;
72
+ if (override && override.trim())
73
+ return override.trim();
74
+ const home = process.env.HOME || process.env.USERPROFILE || homedir();
75
+ return join(home, ".pi-harness-runtime", "skill-sanitization.json");
76
+ }
77
+ /**
78
+ * The state of the rules of this installation.
79
+ *
80
+ * `configured` is false when the local file is missing or unreadable. The
81
+ * caller shows it, because a missing file is a weaker privacy guarantee
82
+ * and not a detail.
83
+ */
84
+ export function sanitizationStatus() {
85
+ const path = sanitizationFilePath();
86
+ const set = loadSanitizationRules(path);
87
+ return {
88
+ configured: set.source === "local-file",
89
+ path,
90
+ ruleCount: set.rules.length,
91
+ ...(set.error ? { error: set.error } : {}),
92
+ };
93
+ }
94
+ let cached;
95
+ /**
96
+ * The rules of this installation.
97
+ *
98
+ * The file is read once per process: the rules do not change while the
99
+ * harness runs, and a skill that is indexed a hundred times must not read
100
+ * a file a hundred times.
101
+ */
102
+ export function loadSanitizationRules(path = sanitizationFilePath()) {
103
+ if (cached && cached.path === path)
104
+ return cached.set;
105
+ const set = readSanitizationRules(path);
106
+ cached = { path, set };
107
+ return set;
108
+ }
109
+ /** Forget the cached rules. A test needs it, a new file needs it. */
110
+ export function resetSanitizationRulesCache() {
111
+ cached = undefined;
112
+ }
113
+ function readSanitizationRules(path) {
114
+ let raw;
115
+ try {
116
+ raw = readFileSync(path, "utf8");
117
+ }
118
+ catch (err) {
119
+ const code = err?.code;
120
+ if (code !== "ENOENT") {
121
+ return {
122
+ rules: [...GENERIC_RULES],
123
+ nameMap: { ...GENERIC_NAME_MAP },
124
+ source: "generic-only",
125
+ error: `The sanitization rules at ${path} could not be read: ${err instanceof Error ? err.message : String(err)}`,
126
+ };
127
+ }
128
+ return {
129
+ rules: [...GENERIC_RULES],
130
+ nameMap: { ...GENERIC_NAME_MAP },
131
+ source: "generic-only",
132
+ };
133
+ }
134
+ let parsed;
135
+ try {
136
+ parsed = JSON.parse(raw);
137
+ }
138
+ catch (err) {
139
+ return {
140
+ rules: [...GENERIC_RULES],
141
+ nameMap: { ...GENERIC_NAME_MAP },
142
+ source: "generic-only",
143
+ error: `The sanitization rules at ${path} are not valid JSON: ${err instanceof Error ? err.message : String(err)}`,
144
+ };
145
+ }
146
+ const rules = [...GENERIC_RULES];
147
+ const nameMap = { ...GENERIC_NAME_MAP };
148
+ const file = parsed;
149
+ for (const spec of file.rules ?? []) {
150
+ if (!spec || typeof spec.pattern !== "string" || typeof spec.replacement !== "string") {
151
+ continue;
152
+ }
153
+ try {
154
+ rules.push({
155
+ pattern: new RegExp(spec.pattern, spec.flags ?? "gi"),
156
+ replacement: spec.replacement,
157
+ });
158
+ }
159
+ catch {
160
+ // A broken pattern must not take the whole rule set down: the other
161
+ // rules still hold, and the broken one is reported below.
162
+ rules.push({
163
+ pattern: /$^/,
164
+ replacement: spec.replacement,
165
+ });
166
+ }
167
+ }
168
+ for (const [from, to] of Object.entries(file.nameMap ?? {})) {
169
+ if (typeof from === "string" && typeof to === "string")
170
+ nameMap[from] = to;
171
+ }
172
+ return { rules, nameMap, source: "local-file" };
173
+ }
174
+ //# sourceMappingURL=sanitize-rules.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sanitize-rules.js","sourceRoot":"","sources":["../src/sanitize-rules.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AA8BjC;;;;;;GAMG;AACH,MAAM,aAAa,GAAuB;IACxC,EAAE,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,eAAe,EAAE;IAC3D,EAAE,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,UAAU,EAAE;IACtD,EAAE,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,UAAU,EAAE;IACpD,EAAE,OAAO,EAAE,mBAAmB,EAAE,WAAW,EAAE,oBAAoB,EAAE;CACpE,CAAC;AAEF;;;;;;;;GAQG;AACH,MAAM,gBAAgB,GAA2B,EAAE,CAAC;AAEpD,iDAAiD;AACjD,MAAM,UAAU,oBAAoB;IAClC,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,0BAA0B,CAAC;IACxD,IAAI,QAAQ,IAAI,QAAQ,CAAC,IAAI,EAAE;QAAE,OAAO,QAAQ,CAAC,IAAI,EAAE,CAAC;IACxD,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,OAAO,EAAE,CAAC;IACtE,OAAO,IAAI,CAAC,IAAI,EAAE,qBAAqB,EAAE,yBAAyB,CAAC,CAAC;AACtE,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,kBAAkB;IAMhC,MAAM,IAAI,GAAG,oBAAoB,EAAE,CAAC;IACpC,MAAM,GAAG,GAAG,qBAAqB,CAAC,IAAI,CAAC,CAAC;IACxC,OAAO;QACL,UAAU,EAAE,GAAG,CAAC,MAAM,KAAK,YAAY;QACvC,IAAI;QACJ,SAAS,EAAE,GAAG,CAAC,KAAK,CAAC,MAAM;QAC3B,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC3C,CAAC;AACJ,CAAC;AAED,IAAI,MAA8D,CAAC;AAEnE;;;;;;GAMG;AACH,MAAM,UAAU,qBAAqB,CAAC,IAAI,GAAG,oBAAoB,EAAE;IACjE,IAAI,MAAM,IAAI,MAAM,CAAC,IAAI,KAAK,IAAI;QAAE,OAAO,MAAM,CAAC,GAAG,CAAC;IAEtD,MAAM,GAAG,GAAG,qBAAqB,CAAC,IAAI,CAAC,CAAC;IACxC,MAAM,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC;IACvB,OAAO,GAAG,CAAC;AACb,CAAC;AAED,qEAAqE;AACrE,MAAM,UAAU,2BAA2B;IACzC,MAAM,GAAG,SAAS,CAAC;AACrB,CAAC;AAED,SAAS,qBAAqB,CAAC,IAAY;IACzC,IAAI,GAAW,CAAC;IAChB,IAAI,CAAC;QACH,GAAG,GAAG,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACnC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,IAAI,GAAI,GAA6B,EAAE,IAAI,CAAC;QAClD,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;YACtB,OAAO;gBACL,KAAK,EAAE,CAAC,GAAG,aAAa,CAAC;gBACzB,OAAO,EAAE,EAAE,GAAG,gBAAgB,EAAE;gBAChC,MAAM,EAAE,cAAc;gBACtB,KAAK,EAAE,6BAA6B,IAAI,uBAAuB,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE;aAClH,CAAC;QACJ,CAAC;QACD,OAAO;YACL,KAAK,EAAE,CAAC,GAAG,aAAa,CAAC;YACzB,OAAO,EAAE,EAAE,GAAG,gBAAgB,EAAE;YAChC,MAAM,EAAE,cAAc;SACvB,CAAC;IACJ,CAAC;IAED,IAAI,MAAe,CAAC;IACpB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC3B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO;YACL,KAAK,EAAE,CAAC,GAAG,aAAa,CAAC;YACzB,OAAO,EAAE,EAAE,GAAG,gBAAgB,EAAE;YAChC,MAAM,EAAE,cAAc;YACtB,KAAK,EAAE,6BAA6B,IAAI,wBAAwB,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE;SACnH,CAAC;IACJ,CAAC;IAED,MAAM,KAAK,GAAuB,CAAC,GAAG,aAAa,CAAC,CAAC;IACrD,MAAM,OAAO,GAA2B,EAAE,GAAG,gBAAgB,EAAE,CAAC;IAEhE,MAAM,IAAI,GAAG,MAGZ,CAAC;IAEF,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,IAAI,EAAE,EAAE,CAAC;QACpC,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,CAAC,OAAO,KAAK,QAAQ,IAAI,OAAO,IAAI,CAAC,WAAW,KAAK,QAAQ,EAAE,CAAC;YACtF,SAAS;QACX,CAAC;QACD,IAAI,CAAC;YACH,KAAK,CAAC,IAAI,CAAC;gBACT,OAAO,EAAE,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC;gBACrD,WAAW,EAAE,IAAI,CAAC,WAAW;aAC9B,CAAC,CAAC;QACL,CAAC;QAAC,MAAM,CAAC;YACP,oEAAoE;YACpE,0DAA0D;YAC1D,KAAK,CAAC,IAAI,CAAC;gBACT,OAAO,EAAE,IAAI;gBACb,WAAW,EAAE,IAAI,CAAC,WAAW;aAC9B,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,KAAK,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC,EAAE,CAAC;QAC5D,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,OAAO,EAAE,KAAK,QAAQ;YAAE,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;IAC7E,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,CAAC;AAClD,CAAC"}