pi-harness-runtime 1.1.415 → 1.1.416

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 (119) hide show
  1. package/package.json +1 -1
  2. package/packages/a2a-adapter/package.json +1 -1
  3. package/packages/agent-policy/package.json +1 -1
  4. package/packages/architecture-generator/package.json +1 -1
  5. package/packages/auth/package.json +1 -1
  6. package/packages/autonomous-refactor/package.json +1 -1
  7. package/packages/autonomous-runtime/package.json +1 -1
  8. package/packages/cache-strategy/package.json +1 -1
  9. package/packages/capability-registry/package.json +1 -1
  10. package/packages/checkpoint/package.json +1 -1
  11. package/packages/cli-plugin-sdk/package.json +1 -1
  12. package/packages/clipboard/package.json +1 -1
  13. package/packages/clipboard-plugin/package.json +1 -1
  14. package/packages/code-generation/package.json +1 -1
  15. package/packages/code-review/package.json +1 -1
  16. package/packages/codex-adapter/package.json +1 -1
  17. package/packages/codex-watcher/package.json +1 -1
  18. package/packages/config-capture/package.json +1 -1
  19. package/packages/connection-runtime/package.json +1 -1
  20. package/packages/context-compiler/package.json +1 -1
  21. package/packages/context-discovery/package.json +1 -1
  22. package/packages/context-manager/package.json +1 -1
  23. package/packages/contracts/package.json +1 -1
  24. package/packages/cookie-sanitizer/package.json +1 -1
  25. package/packages/cost-optimizer/package.json +1 -1
  26. package/packages/dependency-analyzer/package.json +1 -1
  27. package/packages/django-plugin/package.json +1 -1
  28. package/packages/doc-generator/package.json +1 -1
  29. package/packages/durable-review/package.json +1 -1
  30. package/packages/e2e-tester/package.json +1 -1
  31. package/packages/evaluation-engine/package.json +1 -1
  32. package/packages/evaluation-runner/package.json +1 -1
  33. package/packages/event-bus/package.json +1 -1
  34. package/packages/event-sink/package.json +1 -1
  35. package/packages/event-store/package.json +1 -1
  36. package/packages/experience-replay/package.json +1 -1
  37. package/packages/feedback-collector/package.json +1 -1
  38. package/packages/file-copy-helper/package.json +1 -1
  39. package/packages/framework-detector/package.json +1 -1
  40. package/packages/framework-plugin-sdk/package.json +1 -1
  41. package/packages/frappe-plugin/package.json +1 -1
  42. package/packages/generic-web-plugin/package.json +1 -1
  43. package/packages/health-monitor/package.json +1 -1
  44. package/packages/intent-analyzer/package.json +1 -1
  45. package/packages/jev-judge/package.json +1 -1
  46. package/packages/knowledge-graph/package.json +1 -1
  47. package/packages/knowledge-retrieval/package.json +1 -1
  48. package/packages/laravel-plugin/package.json +1 -1
  49. package/packages/learning-engine/package.json +1 -1
  50. package/packages/logging/package.json +1 -1
  51. package/packages/mcp-adapter/package.json +1 -1
  52. package/packages/memory-engine/package.json +1 -1
  53. package/packages/milestone-manager/package.json +1 -1
  54. package/packages/model-registry/package.json +1 -1
  55. package/packages/nextjs-plugin/package.json +1 -1
  56. package/packages/notification/package.json +1 -1
  57. package/packages/observability/package.json +1 -1
  58. package/packages/okf-indexer/package.json +1 -1
  59. package/packages/paperclip-integration/package.json +1 -1
  60. package/packages/performance-optimizer/package.json +1 -1
  61. package/packages/permission-mode/package.json +1 -1
  62. package/packages/privilege-broker/package.json +1 -1
  63. package/packages/project-analyzer/package.json +1 -1
  64. package/packages/project-bootstrap/package.json +1 -1
  65. package/packages/projection-engine/package.json +1 -1
  66. package/packages/prompt-compiler/package.json +1 -1
  67. package/packages/prompt-versioning/package.json +1 -1
  68. package/packages/provider-adapter-sdk/package.json +1 -1
  69. package/packages/provider-router/package.json +1 -1
  70. package/packages/provider-selector/package.json +1 -1
  71. package/packages/providers/package.json +1 -1
  72. package/packages/qdrant-skills/package.json +1 -1
  73. package/packages/quota-manager/package.json +1 -1
  74. package/packages/rate-limiter/package.json +1 -1
  75. package/packages/react-vite-plugin/package.json +1 -1
  76. package/packages/relay/package.json +1 -1
  77. package/packages/release-manager/package.json +1 -1
  78. package/packages/requirement-compiler/package.json +1 -1
  79. package/packages/runtime/package.json +1 -1
  80. package/packages/scheduler/package.json +1 -1
  81. package/packages/scheduler-adapter/package.json +1 -1
  82. package/packages/session/package.json +1 -1
  83. package/packages/session-api/package.json +1 -1
  84. package/packages/session-export/package.json +1 -1
  85. package/packages/shared-context/package.json +1 -1
  86. package/packages/skill-mcp-client/package.json +1 -1
  87. package/packages/skill-registry/package.json +1 -1
  88. package/packages/skills/dist/sanitize.d.ts +5 -0
  89. package/packages/skills/dist/sanitize.d.ts.map +1 -1
  90. package/packages/skills/dist/sanitize.js +37 -12
  91. package/packages/skills/dist/sanitize.js.map +1 -1
  92. package/packages/skills/package.json +1 -1
  93. package/packages/skills/src/sanitize.ts +37 -12
  94. package/packages/skills/test/sanitize.test.ts +43 -0
  95. package/packages/skills/test/vector-schema.test.ts +15 -2
  96. package/packages/sprint-planner/package.json +1 -1
  97. package/packages/subscription-engine/package.json +1 -1
  98. package/packages/task-compiler/package.json +1 -1
  99. package/packages/telegram/package.json +1 -1
  100. package/packages/tencentdb-memory/package.json +1 -1
  101. package/packages/tencentdb-sync/package.json +1 -1
  102. package/packages/test-data-generator/package.json +1 -1
  103. package/packages/test-generator/package.json +1 -1
  104. package/packages/todo-bd-sync/package.json +1 -1
  105. package/packages/token-estimation/package.json +1 -1
  106. package/packages/token-optimizer/package.json +1 -1
  107. package/packages/tooling-preference/package.json +1 -1
  108. package/packages/trajectory/package.json +1 -1
  109. package/packages/tui/package.json +1 -1
  110. package/packages/two-phase-review/package.json +1 -1
  111. package/packages/types/package.json +1 -1
  112. package/packages/voice-api/package.json +1 -1
  113. package/packages/webmcp-tester/package.json +1 -1
  114. package/packages/wiki/package.json +1 -1
  115. package/packages/workflow-events/package.json +1 -1
  116. package/packages/workspace-scanner/package.json +1 -1
  117. package/packages/worktree/package.json +1 -1
  118. package/packages/write-review/package.json +1 -1
  119. package/scripts/sync-to-qdrant.ts +18 -37
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/provider-adapter-sdk",
3
- "version": "1.1.415",
3
+ "version": "1.1.416",
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.415",
3
+ "version": "1.1.416",
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.415",
3
+ "version": "1.1.416",
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.415",
3
+ "version": "1.1.416",
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.415",
3
+ "version": "1.1.416",
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.415",
3
+ "version": "1.1.416",
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.415",
3
+ "version": "1.1.416",
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.415",
3
+ "version": "1.1.416",
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.415",
3
+ "version": "1.1.416",
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.415",
3
+ "version": "1.1.416",
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.415",
3
+ "version": "1.1.416",
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.415",
3
+ "version": "1.1.416",
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.415",
3
+ "version": "1.1.416",
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.415",
3
+ "version": "1.1.416",
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.415",
3
+ "version": "1.1.416",
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.415",
3
+ "version": "1.1.416",
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.415",
3
+ "version": "1.1.416",
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.415",
3
+ "version": "1.1.416",
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.415",
3
+ "version": "1.1.416",
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.415",
3
+ "version": "1.1.416",
4
4
  "description": "Skill Registry for pi-harness-runtime — dynamic skill discovery and invocation",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -22,6 +22,11 @@ export declare function sanitizeText(text: string): string;
22
22
  *
23
23
  * The name is the identity of the point, so it has to be the same for
24
24
  * every writer: the map first, then the pattern rules.
25
+ *
26
+ * The result is a skill name - lower case, words separated by a dash -
27
+ * because the name of a point is also the id of the skill that a search
28
+ * returns. The replacements of the rules carry a space and brackets,
29
+ * which no skill name may hold.
25
30
  */
26
31
  export declare function skillPointName(name: string): string;
27
32
  //# sourceMappingURL=sanitize.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"sanitize.d.ts","sourceRoot":"","sources":["../src/sanitize.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAoDH;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAMjD;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEnD"}
1
+ {"version":3,"file":"sanitize.d.ts","sourceRoot":"","sources":["../src/sanitize.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAwDH;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAMjD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAInD"}
@@ -15,21 +15,25 @@
15
15
  *
16
16
  * The list is about the names of the clients and the projects of the
17
17
  * users of the harness - not about the skills themselves.
18
+ *
19
+ * The patterns match a plain fragment, without a word boundary. A client
20
+ * name rarely stands alone: it appears inside a directory name
21
+ * (`th_digisoft_erp_chart.json`), inside a Python module (`inpac_pharma`)
22
+ * or in a sentence ("integrated with Paperclip"). A word boundary would
23
+ * miss all of them - and `_` is a word character, so a boundary never
24
+ * follows an underscore.
18
25
  */
19
26
  const SANITIZATION_RULES = [
20
27
  // Client company names (case-insensitive)
21
- { pattern: /\binpac\b/gi, replacement: "[Client A]" },
22
- { pattern: /\bm-capital\b/gi, replacement: "[Client A]" },
23
- { pattern: /\bmcapital\b/gi, replacement: "[Client A]" },
24
- { pattern: /\bdigisoft\b/gi, replacement: "[Client B]" },
28
+ { pattern: /inpac/gi, replacement: "[Client A]" },
29
+ { pattern: /m-capital/gi, replacement: "[Client A]" },
30
+ { pattern: /mcapital/gi, replacement: "[Client A]" },
31
+ { pattern: /digisoft/gi, replacement: "[Client B]" },
25
32
  // Project/app specific names
26
- { pattern: /\bgse-insurance\b/gi, replacement: "[Insurance Project]" },
27
- { pattern: /\btbs-import\b/gi, replacement: "[Import Project]" },
28
- { pattern: /\bdigisoft_erp\b/gi, replacement: "[Client B Erp]" },
29
- { pattern: /\bm_capital\b/gi, replacement: "[Client A]" },
30
- { pattern: /\binpac_\b/gi, replacement: "[Client A]_" },
31
- { pattern: /\bpaperclip_\b/gi, replacement: "[Client D]_" },
32
- { pattern: /\bopenclaw_\b/gi, replacement: "[Client F]_" },
33
+ { pattern: /gse-insurance/gi, replacement: "[Insurance Project]" },
34
+ { pattern: /tbs-import/gi, replacement: "[Import Project]" },
35
+ { pattern: /paperclip/gi, replacement: "[Client D]" },
36
+ { pattern: /openclaw/gi, replacement: "[Client F]" },
33
37
  // Generic replacements
34
38
  { pattern: /Company Name/gi, replacement: "[Client Name]" },
35
39
  { pattern: /your company/gi, replacement: "[Client]" },
@@ -68,8 +72,29 @@ export function sanitizeText(text) {
68
72
  *
69
73
  * The name is the identity of the point, so it has to be the same for
70
74
  * every writer: the map first, then the pattern rules.
75
+ *
76
+ * The result is a skill name - lower case, words separated by a dash -
77
+ * because the name of a point is also the id of the skill that a search
78
+ * returns. The replacements of the rules carry a space and brackets,
79
+ * which no skill name may hold.
71
80
  */
72
81
  export function skillPointName(name) {
73
- return SKILL_NAME_MAP[name] || sanitizeText(name);
82
+ const mapped = SKILL_NAME_MAP[name];
83
+ if (mapped)
84
+ return mapped;
85
+ return kebabName(sanitizeText(name));
86
+ }
87
+ /**
88
+ * Bring a name into the shape of a skill name.
89
+ *
90
+ * The name of a skill is lower case and its words are separated by a
91
+ * dash: `^[a-z0-9]+(-[a-z0-9]+)*$`.
92
+ */
93
+ function kebabName(name) {
94
+ return name
95
+ .toLowerCase()
96
+ .replace(/[^a-z0-9]+/g, "-")
97
+ .replace(/-{2,}/g, "-")
98
+ .replace(/^-+|-+$/g, "");
74
99
  }
75
100
  //# sourceMappingURL=sanitize.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"sanitize.js","sourceRoot":"","sources":["../src/sanitize.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAQH;;;;;GAKG;AACH,MAAM,kBAAkB,GAAuB;IAC7C,0CAA0C;IAC1C,EAAE,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,YAAY,EAAE;IACrD,EAAE,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,YAAY,EAAE;IACzD,EAAE,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,YAAY,EAAE;IACxD,EAAE,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,YAAY,EAAE;IAExD,6BAA6B;IAC7B,EAAE,OAAO,EAAE,qBAAqB,EAAE,WAAW,EAAE,qBAAqB,EAAE;IACtE,EAAE,OAAO,EAAE,kBAAkB,EAAE,WAAW,EAAE,kBAAkB,EAAE;IAChE,EAAE,OAAO,EAAE,oBAAoB,EAAE,WAAW,EAAE,gBAAgB,EAAE;IAChE,EAAE,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,YAAY,EAAE;IACzD,EAAE,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,aAAa,EAAE;IACvD,EAAE,OAAO,EAAE,kBAAkB,EAAE,WAAW,EAAE,aAAa,EAAE;IAC3D,EAAE,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,aAAa,EAAE;IAE1D,uBAAuB;IACvB,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;;;;;GAKG;AACH,MAAM,cAAc,GAA2B;IAC9C,iCAAiC,EAAE,+BAA+B;IAClE,4BAA4B,EAAE,+BAA+B;IAC7D,4BAA4B,EAAE,+BAA+B;IAC7D,4BAA4B,EAAE,+BAA+B;IAC7D,0BAA0B,EAAE,0BAA0B;IACtD,WAAW,EAAE,cAAc;CAC3B,CAAC;AAEF;;;;;GAKG;AACH,MAAM,UAAU,YAAY,CAAC,IAAY;IACxC,IAAI,MAAM,GAAG,IAAI,CAAC;IAClB,KAAK,MAAM,IAAI,IAAI,kBAAkB,EAAE,CAAC;QACvC,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;IACzD,CAAC;IACD,OAAO,MAAM,CAAC;AACf,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAAC,IAAY;IAC1C,OAAO,cAAc,CAAC,IAAI,CAAC,IAAI,YAAY,CAAC,IAAI,CAAC,CAAC;AACnD,CAAC"}
1
+ {"version":3,"file":"sanitize.js","sourceRoot":"","sources":["../src/sanitize.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAQH;;;;;;;;;;;;GAYG;AACH,MAAM,kBAAkB,GAAuB;IAC7C,0CAA0C;IAC1C,EAAE,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,YAAY,EAAE;IACjD,EAAE,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,YAAY,EAAE;IACrD,EAAE,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,YAAY,EAAE;IACpD,EAAE,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,YAAY,EAAE;IAEpD,6BAA6B;IAC7B,EAAE,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,qBAAqB,EAAE;IAClE,EAAE,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,kBAAkB,EAAE;IAC5D,EAAE,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,YAAY,EAAE;IACrD,EAAE,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,YAAY,EAAE;IAEpD,uBAAuB;IACvB,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;;;;;GAKG;AACH,MAAM,cAAc,GAA2B;IAC9C,iCAAiC,EAAE,+BAA+B;IAClE,4BAA4B,EAAE,+BAA+B;IAC7D,4BAA4B,EAAE,+BAA+B;IAC7D,4BAA4B,EAAE,+BAA+B;IAC7D,0BAA0B,EAAE,0BAA0B;IACtD,WAAW,EAAE,cAAc;CAC3B,CAAC;AAEF;;;;;GAKG;AACH,MAAM,UAAU,YAAY,CAAC,IAAY;IACxC,IAAI,MAAM,GAAG,IAAI,CAAC;IAClB,KAAK,MAAM,IAAI,IAAI,kBAAkB,EAAE,CAAC;QACvC,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;IACzD,CAAC;IACD,OAAO,MAAM,CAAC;AACf,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,cAAc,CAAC,IAAY;IAC1C,MAAM,MAAM,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC;IACpC,IAAI,MAAM;QAAE,OAAO,MAAM,CAAC;IAC1B,OAAO,SAAS,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC;AACtC,CAAC;AAED;;;;;GAKG;AACH,SAAS,SAAS,CAAC,IAAY;IAC9B,OAAO,IAAI;SACT,WAAW,EAAE;SACb,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC;SAC3B,OAAO,CAAC,QAAQ,EAAE,GAAG,CAAC;SACtB,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;AAC3B,CAAC"}
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/skills",
3
- "version": "1.1.415",
3
+ "version": "1.1.416",
4
4
  "description": "File-based skill system with pi.dev compatibility and Hermes self-improvement",
5
5
  "type": "module",
6
6
  "main": "src/index.ts",
@@ -22,22 +22,26 @@ interface SanitizationRule {
22
22
  *
23
23
  * The list is about the names of the clients and the projects of the
24
24
  * users of the harness - not about the skills themselves.
25
+ *
26
+ * The patterns match a plain fragment, without a word boundary. A client
27
+ * name rarely stands alone: it appears inside a directory name
28
+ * (`th_digisoft_erp_chart.json`), inside a Python module (`inpac_pharma`)
29
+ * or in a sentence ("integrated with Paperclip"). A word boundary would
30
+ * miss all of them - and `_` is a word character, so a boundary never
31
+ * follows an underscore.
25
32
  */
26
33
  const SANITIZATION_RULES: SanitizationRule[] = [
27
34
  // Client company names (case-insensitive)
28
- { pattern: /\binpac\b/gi, replacement: "[Client A]" },
29
- { pattern: /\bm-capital\b/gi, replacement: "[Client A]" },
30
- { pattern: /\bmcapital\b/gi, replacement: "[Client A]" },
31
- { pattern: /\bdigisoft\b/gi, replacement: "[Client B]" },
35
+ { pattern: /inpac/gi, replacement: "[Client A]" },
36
+ { pattern: /m-capital/gi, replacement: "[Client A]" },
37
+ { pattern: /mcapital/gi, replacement: "[Client A]" },
38
+ { pattern: /digisoft/gi, replacement: "[Client B]" },
32
39
 
33
40
  // Project/app specific names
34
- { pattern: /\bgse-insurance\b/gi, replacement: "[Insurance Project]" },
35
- { pattern: /\btbs-import\b/gi, replacement: "[Import Project]" },
36
- { pattern: /\bdigisoft_erp\b/gi, replacement: "[Client B Erp]" },
37
- { pattern: /\bm_capital\b/gi, replacement: "[Client A]" },
38
- { pattern: /\binpac_\b/gi, replacement: "[Client A]_" },
39
- { pattern: /\bpaperclip_\b/gi, replacement: "[Client D]_" },
40
- { pattern: /\bopenclaw_\b/gi, replacement: "[Client F]_" },
41
+ { pattern: /gse-insurance/gi, replacement: "[Insurance Project]" },
42
+ { pattern: /tbs-import/gi, replacement: "[Import Project]" },
43
+ { pattern: /paperclip/gi, replacement: "[Client D]" },
44
+ { pattern: /openclaw/gi, replacement: "[Client F]" },
41
45
 
42
46
  // Generic replacements
43
47
  { pattern: /Company Name/gi, replacement: "[Client Name]" },
@@ -80,7 +84,28 @@ export function sanitizeText(text: string): string {
80
84
  *
81
85
  * The name is the identity of the point, so it has to be the same for
82
86
  * every writer: the map first, then the pattern rules.
87
+ *
88
+ * The result is a skill name - lower case, words separated by a dash -
89
+ * because the name of a point is also the id of the skill that a search
90
+ * returns. The replacements of the rules carry a space and brackets,
91
+ * which no skill name may hold.
83
92
  */
84
93
  export function skillPointName(name: string): string {
85
- return SKILL_NAME_MAP[name] || sanitizeText(name);
94
+ const mapped = SKILL_NAME_MAP[name];
95
+ if (mapped) return mapped;
96
+ return kebabName(sanitizeText(name));
97
+ }
98
+
99
+ /**
100
+ * Bring a name into the shape of a skill name.
101
+ *
102
+ * The name of a skill is lower case and its words are separated by a
103
+ * dash: `^[a-z0-9]+(-[a-z0-9]+)*$`.
104
+ */
105
+ function kebabName(name: string): string {
106
+ return name
107
+ .toLowerCase()
108
+ .replace(/[^a-z0-9]+/g, "-")
109
+ .replace(/-{2,}/g, "-")
110
+ .replace(/^-+|-+$/g, "");
86
111
  }
@@ -32,6 +32,26 @@ describe("the sanitization of a text", () => {
32
32
  expect(sanitizeText("your company")).toBe("[Client]");
33
33
  expect(sanitizeText("our client")).toBe("[Client]");
34
34
  });
35
+
36
+ test("a client name inside an identifier is replaced", () => {
37
+ // The name of a client rarely stands alone. A word boundary would
38
+ // miss every one of these - and an underscore is a word character,
39
+ // so a boundary never follows one.
40
+ expect(sanitizeText("inpac_pharma")).toBe("[Client A]_pharma");
41
+ expect(sanitizeText("th_digisoft_erp_chart.json")).toBe(
42
+ "th_[Client B]_erp_chart.json",
43
+ );
44
+ expect(sanitizeText("apps/inpac_pharma/setup")).toBe(
45
+ "apps/[Client A]_pharma/setup",
46
+ );
47
+ });
48
+
49
+ test("a client name in a sentence is replaced", () => {
50
+ expect(sanitizeText("integrated with Paperclip")).toBe(
51
+ "integrated with [Client D]",
52
+ );
53
+ expect(sanitizeText("OpenClaw secrets")).toBe("[Client F] secrets");
54
+ });
35
55
  });
36
56
 
37
57
  describe("the name of a skill in the shared collection", () => {
@@ -59,6 +79,29 @@ describe("the name of a skill in the shared collection", () => {
59
79
  expect(skillPointName(name)).not.toMatch(/inpac|gse-insurance|tbs-import/i);
60
80
  }
61
81
  });
82
+
83
+ test("the name is a valid skill name", () => {
84
+ // The name of a point is the id of the skill that a search returns,
85
+ // so it has to be a name that a skill may carry.
86
+ const NAME = /^[a-z0-9]+(-[a-z0-9]+)*$/;
87
+ for (const name of [
88
+ "inpac-pe-approval-workflow",
89
+ "openclaw-channel",
90
+ "gse-insurance-step5-slot-filter",
91
+ "tbs-import-clearance-lcv",
92
+ "whispertool",
93
+ "code-review",
94
+ ]) {
95
+ expect(skillPointName(name)).toMatch(NAME);
96
+ }
97
+ });
98
+
99
+ test("a name that needs no sanitization stays the same", () => {
100
+ expect(skillPointName("code-review")).toBe("code-review");
101
+ expect(skillPointName("frappe-doctype-field-order")).toBe(
102
+ "frappe-doctype-field-order",
103
+ );
104
+ });
62
105
  });
63
106
 
64
107
  describe("the payload of a point is sanitized", () => {
@@ -138,8 +138,21 @@ describe("the identity of a skill point", () => {
138
138
  body: "b",
139
139
  });
140
140
 
141
- expect(withTitle.text).toContain("A Human Title");
142
- expect(withoutTitle.text).not.toContain("A Human Title");
141
+ // The title is treated like the name: it is sanitized and it is
142
+ // brought into the shape of a skill name.
143
+ expect(withTitle.text).toContain("a-human-title");
144
+ expect(withoutTitle.text).not.toContain("a-human-title");
145
+ });
146
+
147
+ test("a title that is the name is not repeated in the text", () => {
148
+ const payload = skillPointPayload({
149
+ name: "a-skill",
150
+ title: "a-skill",
151
+ description: "d",
152
+ body: "b",
153
+ });
154
+
155
+ expect(payload.text.match(/a-skill/g)?.length).toBe(1);
143
156
  });
144
157
  });
145
158
 
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/sprint-planner",
3
- "version": "1.1.415",
3
+ "version": "1.1.416",
4
4
  "type": "module",
5
5
  "description": "Sprint planning engine for pi-harness",
6
6
  "main": "dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/subscription-engine",
3
- "version": "1.1.415",
3
+ "version": "1.1.416",
4
4
  "type": "module",
5
5
  "main": "src/index.ts",
6
6
  "exports": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/task-compiler",
3
- "version": "1.1.415",
3
+ "version": "1.1.416",
4
4
  "description": "Task Compiler for pi-harness-runtime — produces deterministic task DAG from CompiledRequirement",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/telegram",
3
- "version": "1.1.415",
3
+ "version": "1.1.416",
4
4
  "description": "pi-harness-runtime — Telegram inbound/outbound",
5
5
  "type": "module",
6
6
  "main": "./src/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@moocoding/tencentdb-memory",
3
- "version": "1.1.415",
3
+ "version": "1.1.416",
4
4
  "description": "TencentDB Agent Memory client - sync skills to centralized knowledge base",
5
5
  "type": "module",
6
6
  "main": "src/index.ts",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/tencentdb-sync",
3
- "version": "1.1.415",
3
+ "version": "1.1.416",
4
4
  "description": "Sync SKILL.md skills to TencentDB-Agent-Memory server (RFC-0105/0106)",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/test-data-generator",
3
- "version": "1.1.415",
3
+ "version": "1.1.416",
4
4
  "description": "Test data generation for pi-harness-runtime",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/test-generator",
3
- "version": "1.1.415",
3
+ "version": "1.1.416",
4
4
  "description": "Auto-Test Generator — generate unit and E2E tests from source code (RFC-0013)",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@moocoding/todo-bd-sync",
3
- "version": "1.1.415",
3
+ "version": "1.1.416",
4
4
  "description": "Two-way sync between rpiv-todo overlay and bd issue tracker",
5
5
  "type": "module",
6
6
  "main": "src/index.ts",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/token-estimation",
3
- "version": "1.1.415",
3
+ "version": "1.1.416",
4
4
  "description": "pi-harness-runtime — token-estimation",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/token-optimizer",
3
- "version": "1.1.415",
3
+ "version": "1.1.416",
4
4
  "description": "Token Budget Optimizer — maximize prompt value within token limits (RFC-0011)",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/tooling-preference",
3
- "version": "1.1.415",
3
+ "version": "1.1.416",
4
4
  "description": "pi-harness-runtime — JS/TS tooling preference (Biome vs ESLint/Prettier) proposal",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/trajectory",
3
- "version": "1.1.415",
3
+ "version": "1.1.416",
4
4
  "description": "Trajectory capture for the write-review loop — persists cycle records for learning",
5
5
  "type": "module",
6
6
  "main": "./dist/src/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/tui",
3
- "version": "1.1.415",
3
+ "version": "1.1.416",
4
4
  "description": "pi-harness-runtime — tui",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/two-phase-review",
3
- "version": "1.1.415",
3
+ "version": "1.1.416",
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",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/types",
3
- "version": "1.1.415",
3
+ "version": "1.1.416",
4
4
  "description": "Shared TypeScript types for pi-harness-runtime packages",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/voice-api",
3
- "version": "1.1.415",
3
+ "version": "1.1.416",
4
4
  "type": "module",
5
5
  "description": "Voice-to-text API using Whisper for Telegram and LINE integration",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/webmcp-tester",
3
- "version": "1.1.415",
3
+ "version": "1.1.416",
4
4
  "description": "WebMCP-powered E2E testing for pi-harness - natural language test scenarios",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/wiki",
3
- "version": "1.1.415",
3
+ "version": "1.1.416",
4
4
  "description": "LLM Wiki integration for pi-harness-runtime",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/workflow-events",
3
- "version": "1.1.415",
3
+ "version": "1.1.416",
4
4
  "type": "module",
5
5
  "main": "src/index.ts",
6
6
  "exports": {