pi-harness-runtime 1.1.402 → 1.1.404

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 (122) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/package.json +1 -1
  3. package/packages/a2a-adapter/package.json +1 -1
  4. package/packages/agent-policy/package.json +1 -1
  5. package/packages/architecture-generator/package.json +1 -1
  6. package/packages/auth/package.json +1 -1
  7. package/packages/autonomous-refactor/package.json +1 -1
  8. package/packages/autonomous-runtime/package.json +1 -1
  9. package/packages/cache-strategy/package.json +1 -1
  10. package/packages/capability-registry/package.json +1 -1
  11. package/packages/checkpoint/package.json +1 -1
  12. package/packages/cli-plugin-sdk/package.json +1 -1
  13. package/packages/clipboard/package.json +1 -1
  14. package/packages/clipboard-plugin/package.json +1 -1
  15. package/packages/code-generation/package.json +1 -1
  16. package/packages/code-review/package.json +1 -1
  17. package/packages/codex-adapter/package.json +1 -1
  18. package/packages/codex-watcher/package.json +1 -1
  19. package/packages/config-capture/package.json +1 -1
  20. package/packages/connection-runtime/package.json +1 -1
  21. package/packages/context-compiler/package.json +1 -1
  22. package/packages/context-discovery/package.json +1 -1
  23. package/packages/context-manager/package.json +1 -1
  24. package/packages/contracts/package.json +1 -1
  25. package/packages/cookie-sanitizer/package.json +1 -1
  26. package/packages/cost-optimizer/package.json +1 -1
  27. package/packages/dependency-analyzer/package.json +1 -1
  28. package/packages/django-plugin/package.json +1 -1
  29. package/packages/doc-generator/package.json +1 -1
  30. package/packages/durable-review/package.json +1 -1
  31. package/packages/e2e-tester/package.json +1 -1
  32. package/packages/evaluation-engine/package.json +1 -1
  33. package/packages/evaluation-runner/package.json +1 -1
  34. package/packages/event-bus/package.json +1 -1
  35. package/packages/event-sink/package.json +1 -1
  36. package/packages/event-store/package.json +1 -1
  37. package/packages/experience-replay/package.json +1 -1
  38. package/packages/feedback-collector/package.json +1 -1
  39. package/packages/file-copy-helper/package.json +1 -1
  40. package/packages/framework-detector/package.json +1 -1
  41. package/packages/framework-plugin-sdk/package.json +1 -1
  42. package/packages/frappe-plugin/package.json +1 -1
  43. package/packages/generic-web-plugin/package.json +1 -1
  44. package/packages/health-monitor/package.json +1 -1
  45. package/packages/intent-analyzer/package.json +1 -1
  46. package/packages/jev-judge/dist/auto-continue.d.ts +6 -0
  47. package/packages/jev-judge/dist/auto-continue.d.ts.map +1 -1
  48. package/packages/jev-judge/dist/auto-continue.js +13 -3
  49. package/packages/jev-judge/dist/auto-continue.js.map +1 -1
  50. package/packages/jev-judge/dist/question-risk.d.ts +8 -5
  51. package/packages/jev-judge/dist/question-risk.d.ts.map +1 -1
  52. package/packages/jev-judge/dist/question-risk.js +12 -7
  53. package/packages/jev-judge/dist/question-risk.js.map +1 -1
  54. package/packages/jev-judge/package.json +1 -1
  55. package/packages/jev-judge/src/auto-continue.ts +17 -3
  56. package/packages/jev-judge/src/question-risk.ts +12 -8
  57. package/packages/jev-judge/tests/auto-continue-context.test.ts +59 -0
  58. package/packages/jev-judge/tests/question-risk.test.ts +15 -2
  59. package/packages/knowledge-graph/package.json +1 -1
  60. package/packages/knowledge-retrieval/package.json +1 -1
  61. package/packages/laravel-plugin/package.json +1 -1
  62. package/packages/learning-engine/package.json +1 -1
  63. package/packages/logging/package.json +1 -1
  64. package/packages/mcp-adapter/package.json +1 -1
  65. package/packages/memory-engine/package.json +1 -1
  66. package/packages/milestone-manager/package.json +1 -1
  67. package/packages/model-registry/package.json +1 -1
  68. package/packages/nextjs-plugin/package.json +1 -1
  69. package/packages/notification/package.json +1 -1
  70. package/packages/observability/package.json +1 -1
  71. package/packages/okf-indexer/package.json +1 -1
  72. package/packages/paperclip-integration/package.json +1 -1
  73. package/packages/performance-optimizer/package.json +1 -1
  74. package/packages/permission-mode/package.json +1 -1
  75. package/packages/privilege-broker/package.json +1 -1
  76. package/packages/project-analyzer/package.json +1 -1
  77. package/packages/project-bootstrap/package.json +1 -1
  78. package/packages/projection-engine/package.json +1 -1
  79. package/packages/prompt-compiler/package.json +1 -1
  80. package/packages/prompt-versioning/package.json +1 -1
  81. package/packages/provider-adapter-sdk/package.json +1 -1
  82. package/packages/provider-router/package.json +1 -1
  83. package/packages/provider-selector/package.json +1 -1
  84. package/packages/providers/package.json +1 -1
  85. package/packages/qdrant-skills/package.json +1 -1
  86. package/packages/quota-manager/package.json +1 -1
  87. package/packages/rate-limiter/package.json +1 -1
  88. package/packages/react-vite-plugin/package.json +1 -1
  89. package/packages/relay/package.json +1 -1
  90. package/packages/release-manager/package.json +1 -1
  91. package/packages/requirement-compiler/package.json +1 -1
  92. package/packages/runtime/package.json +1 -1
  93. package/packages/scheduler/package.json +1 -1
  94. package/packages/scheduler-adapter/package.json +1 -1
  95. package/packages/session/package.json +1 -1
  96. package/packages/session-api/package.json +1 -1
  97. package/packages/session-export/package.json +1 -1
  98. package/packages/shared-context/package.json +1 -1
  99. package/packages/skill-mcp-client/package.json +1 -1
  100. package/packages/skill-registry/package.json +1 -1
  101. package/packages/skills/package.json +1 -1
  102. package/packages/sprint-planner/package.json +1 -1
  103. package/packages/subscription-engine/package.json +1 -1
  104. package/packages/task-compiler/package.json +1 -1
  105. package/packages/telegram/package.json +1 -1
  106. package/packages/tencentdb-memory/package.json +1 -1
  107. package/packages/tencentdb-sync/package.json +1 -1
  108. package/packages/test-data-generator/package.json +1 -1
  109. package/packages/test-generator/package.json +1 -1
  110. package/packages/todo-bd-sync/package.json +1 -1
  111. package/packages/token-estimation/package.json +1 -1
  112. package/packages/token-optimizer/package.json +1 -1
  113. package/packages/trajectory/package.json +1 -1
  114. package/packages/tui/package.json +1 -1
  115. package/packages/types/package.json +1 -1
  116. package/packages/voice-api/package.json +1 -1
  117. package/packages/webmcp-tester/package.json +1 -1
  118. package/packages/wiki/package.json +1 -1
  119. package/packages/workflow-events/package.json +1 -1
  120. package/packages/workspace-scanner/package.json +1 -1
  121. package/packages/worktree/package.json +1 -1
  122. package/packages/write-review/package.json +1 -1
@@ -55,15 +55,18 @@ function matchPatterns(text, patterns, signals) {
55
55
  *
56
56
  * The rules:
57
57
  *
58
- * - A question that asks for permission for a concrete action ("approval",
59
- * "explicit") needs the explicit authorization of a human. Jev never
60
- * approves it on its own.
58
+ * - A question of kind "explicit" asks for an explicit human authorization.
59
+ * Jev never approves it on its own.
60
+ * - A question of kind "approval" is the agent proposing work. It stays
61
+ * auto-approvable as long as nothing in it is risky - that is the whole
62
+ * point of the timeout: routine, reversible work continues when the user
63
+ * is away.
61
64
  * - A question that names a destructive action is destructive, and its
62
65
  * reversibility cannot be proven - so it waits.
66
+ * - A question that reaches the outside world or touches a secret needs a
67
+ * human as well.
63
68
  * - A question with an unknown kind or an empty text is uncertain, and an
64
69
  * uncertain case waits for the human.
65
- * - Only a routine question without a destructive or external signal is
66
- * harmless enough for an autonomous decision.
67
70
  */
68
71
  export function classifyQuestionRisk(input) {
69
72
  const text = (input.text ?? "").toLowerCase();
@@ -72,8 +75,10 @@ export function classifyQuestionRisk(input) {
72
75
  const destructive = matchPatterns(text, DESTRUCTIVE_PATTERNS, signals);
73
76
  const external = matchPatterns(text, EXTERNAL_PATTERNS, signals);
74
77
  const sensitive = matchPatterns(text, SENSITIVE_PATTERNS, signals);
75
- // The agent asked for permission for a concrete action.
76
- let requiresExplicitAuthorization = kind === "approval" || kind === "explicit";
78
+ // Only an explicitly demanded authorization blocks the autonomous
79
+ // decision. An "approval" question is the agent proposing work: it
80
+ // stays auto-approvable unless the wording names a risky action.
81
+ let requiresExplicitAuthorization = kind === "explicit";
77
82
  // A destructive action never gets an autonomous approval.
78
83
  if (destructive) {
79
84
  requiresExplicitAuthorization = true;
@@ -1 +1 @@
1
- {"version":3,"file":"question-risk.js","sourceRoot":"","sources":["../src/question-risk.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"question-risk.js","sourceRoot":"","sources":["../src/question-risk.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/jev-judge",
3
- "version": "1.1.402",
3
+ "version": "1.1.404",
4
4
  "description": "Jev Judge - Structured decision model for agent routing, E2E testing, and automated decisions",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -118,10 +118,17 @@ export interface DecisionPolicyResult {
118
118
  export interface DecisionPolicyOptions {
119
119
  /** The confidence an autonomous approval needs. */
120
120
  confidenceThreshold?: number;
121
+ /** The confidence a cautious approval needs (lower than the approval threshold). */
122
+ cautionThreshold?: number;
121
123
  /** The confidence of the proposed outcome. */
122
124
  confidence?: number;
123
125
  }
124
126
 
127
+ /** The confidence an autonomous approval needs by default. */
128
+ export const DEFAULT_PROCEED_THRESHOLD = 0.7;
129
+ /** The confidence a cautious approval needs by default. */
130
+ export const DEFAULT_CAUTION_THRESHOLD = 0.5;
131
+
125
132
  /**
126
133
  * Is the value a known outcome?
127
134
  *
@@ -226,7 +233,13 @@ export function applyDecisionPolicy(
226
233
  };
227
234
  }
228
235
 
229
- const threshold = options?.confidenceThreshold ?? 0.7;
236
+ // The threshold belongs to the outcome: a cautious approval needs the
237
+ // caution threshold, the higher approval threshold is reserved for a
238
+ // full approval. The configured caution range must really proceed.
239
+ const threshold =
240
+ proposed === "proceed_with_caution"
241
+ ? (options?.cautionThreshold ?? DEFAULT_CAUTION_THRESHOLD)
242
+ : (options?.confidenceThreshold ?? DEFAULT_PROCEED_THRESHOLD);
230
243
  const confidence = options?.confidence;
231
244
  if (typeof confidence === "number" && confidence < threshold) {
232
245
  return {
@@ -307,8 +320,8 @@ export interface AutoContinueConfig extends JevJudgeConfig {
307
320
  * Default configuration
308
321
  */
309
322
  const DEFAULT_CONFIG = {
310
- proceedThreshold: 0.7,
311
- cautionThreshold: 0.5,
323
+ proceedThreshold: DEFAULT_PROCEED_THRESHOLD,
324
+ cautionThreshold: DEFAULT_CAUTION_THRESHOLD,
312
325
  maxWaitMinutes: 30,
313
326
  fallbackAction: "wait" as const,
314
327
  };
@@ -435,6 +448,7 @@ export class AutoContinueJudge {
435
448
  ): AutoContinueDecision {
436
449
  const policy = applyDecisionPolicy(decision.outcome, taskState.context, {
437
450
  confidenceThreshold: this.config.proceedThreshold,
451
+ cautionThreshold: this.config.cautionThreshold,
438
452
  confidence: decision.probability,
439
453
  });
440
454
 
@@ -98,15 +98,18 @@ function matchPatterns(
98
98
  *
99
99
  * The rules:
100
100
  *
101
- * - A question that asks for permission for a concrete action ("approval",
102
- * "explicit") needs the explicit authorization of a human. Jev never
103
- * approves it on its own.
101
+ * - A question of kind "explicit" asks for an explicit human authorization.
102
+ * Jev never approves it on its own.
103
+ * - A question of kind "approval" is the agent proposing work. It stays
104
+ * auto-approvable as long as nothing in it is risky - that is the whole
105
+ * point of the timeout: routine, reversible work continues when the user
106
+ * is away.
104
107
  * - A question that names a destructive action is destructive, and its
105
108
  * reversibility cannot be proven - so it waits.
109
+ * - A question that reaches the outside world or touches a secret needs a
110
+ * human as well.
106
111
  * - A question with an unknown kind or an empty text is uncertain, and an
107
112
  * uncertain case waits for the human.
108
- * - Only a routine question without a destructive or external signal is
109
- * harmless enough for an autonomous decision.
110
113
  */
111
114
  export function classifyQuestionRisk(
112
115
  input: QuestionRiskInput,
@@ -119,9 +122,10 @@ export function classifyQuestionRisk(
119
122
  const external = matchPatterns(text, EXTERNAL_PATTERNS, signals);
120
123
  const sensitive = matchPatterns(text, SENSITIVE_PATTERNS, signals);
121
124
 
122
- // The agent asked for permission for a concrete action.
123
- let requiresExplicitAuthorization =
124
- kind === "approval" || kind === "explicit";
125
+ // Only an explicitly demanded authorization blocks the autonomous
126
+ // decision. An "approval" question is the agent proposing work: it
127
+ // stays auto-approvable unless the wording names a risky action.
128
+ let requiresExplicitAuthorization = kind === "explicit";
125
129
 
126
130
  // A destructive action never gets an autonomous approval.
127
131
  if (destructive) {
@@ -13,6 +13,8 @@ import {
13
13
  buildDecisionState,
14
14
  createTaskState,
15
15
  isEligibleForDecision,
16
+ DEFAULT_CAUTION_THRESHOLD,
17
+ DEFAULT_PROCEED_THRESHOLD,
16
18
  MAX_LISTED_TASKS,
17
19
  MAX_QUESTION_CHARS,
18
20
  type DecisionContext,
@@ -138,6 +140,28 @@ describe("decision policy", () => {
138
140
  expect(result.appliedRule).toBe("clarification-never-approved");
139
141
  });
140
142
 
143
+ it("approves a benign approval question so the timeout can work", () => {
144
+ // The timeout exists for routine, reversible work: an agent that
145
+ // proposes work is not a hard authorization block.
146
+ const result = applyDecisionPolicy(
147
+ "approve",
148
+ context({
149
+ question: {
150
+ requestId: "q-1",
151
+ text: "Want me to implement the toggle buttons now?",
152
+ kind: "approval",
153
+ requiresExplicitAuthorization: false,
154
+ destructive: false,
155
+ reversible: true,
156
+ },
157
+ }),
158
+ { confidence: 0.9 },
159
+ );
160
+
161
+ expect(result.outcome).toBe("approve");
162
+ expect(result.appliedRule).toBeUndefined();
163
+ });
164
+
141
165
  it("never approves an action that needs an explicit authorization", () => {
142
166
  const result = applyDecisionPolicy(
143
167
  "approve",
@@ -204,6 +228,41 @@ describe("decision policy", () => {
204
228
  expect(result.appliedRule).toBe("confidence-below-threshold");
205
229
  });
206
230
 
231
+ it("keeps the configured caution range out of the approval threshold", () => {
232
+ // A cautious approval needs the caution threshold, not the higher
233
+ // approval threshold: the configured range must really proceed.
234
+ const result = applyDecisionPolicy("proceed_with_caution", context(), {
235
+ confidence: 0.6,
236
+ confidenceThreshold: DEFAULT_PROCEED_THRESHOLD,
237
+ cautionThreshold: DEFAULT_CAUTION_THRESHOLD,
238
+ });
239
+
240
+ expect(result.outcome).toBe("proceed_with_caution");
241
+ expect(result.appliedRule).toBeUndefined();
242
+ });
243
+
244
+ it("waits for a cautious approval below the caution threshold", () => {
245
+ const result = applyDecisionPolicy("proceed_with_caution", context(), {
246
+ confidence: 0.4,
247
+ confidenceThreshold: DEFAULT_PROCEED_THRESHOLD,
248
+ cautionThreshold: DEFAULT_CAUTION_THRESHOLD,
249
+ });
250
+
251
+ expect(result.outcome).toBe("wait");
252
+ expect(result.appliedRule).toBe("confidence-below-threshold");
253
+ });
254
+
255
+ it("keeps the approval threshold for a full approval", () => {
256
+ const result = applyDecisionPolicy("approve", context(), {
257
+ confidence: 0.6,
258
+ confidenceThreshold: DEFAULT_PROCEED_THRESHOLD,
259
+ cautionThreshold: DEFAULT_CAUTION_THRESHOLD,
260
+ });
261
+
262
+ expect(result.outcome).toBe("wait");
263
+ expect(result.appliedRule).toBe("confidence-below-threshold");
264
+ });
265
+
207
266
  it("approves a low risk approval with a high confidence", () => {
208
267
  const result = applyDecisionPolicy("approve", context(), {
209
268
  confidence: 0.9,
@@ -25,14 +25,17 @@ describe("classifyQuestionRisk", () => {
25
25
  });
26
26
 
27
27
  describe("a question that asks for permission", () => {
28
- it("needs an explicit authorization for an approval question", () => {
28
+ it("keeps a benign approval question auto-approvable", () => {
29
29
  const risk = classifyQuestionRisk({
30
30
  kind: "approval",
31
31
  text: "Want me to implement the toggle buttons now?",
32
32
  });
33
33
 
34
- expect(risk.requiresExplicitAuthorization).toBe(true);
34
+ // The timeout exists for routine, reversible work: the agent
35
+ // proposing work is not a hard authorization block.
36
+ expect(risk.requiresExplicitAuthorization).toBe(false);
35
37
  expect(risk.destructive).toBe(false);
38
+ expect(risk.reversible).toBe(true);
36
39
  });
37
40
 
38
41
  it("needs an explicit authorization for an explicit question", () => {
@@ -43,6 +46,16 @@ describe("classifyQuestionRisk", () => {
43
46
 
44
47
  expect(risk.requiresExplicitAuthorization).toBe(true);
45
48
  });
49
+
50
+ it("needs an explicit authorization for a risky approval question", () => {
51
+ const risk = classifyQuestionRisk({
52
+ kind: "approval",
53
+ text: "Want me to remove the old config file now?",
54
+ });
55
+
56
+ expect(risk.requiresExplicitAuthorization).toBe(true);
57
+ expect(risk.destructive).toBe(true);
58
+ });
46
59
  });
47
60
 
48
61
  describe("a destructive action", () => {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/knowledge-graph",
3
- "version": "1.1.402",
3
+ "version": "1.1.404",
4
4
  "description": "Knowledge Graph extraction and provenance linking for SKILL.md files",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/knowledge-retrieval",
3
- "version": "1.1.402",
3
+ "version": "1.1.404",
4
4
  "description": "Knowledge retrieval via TencentDB-Agent-Memory MCP (RFC-0105)",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/laravel-plugin",
3
- "version": "1.1.402",
3
+ "version": "1.1.404",
4
4
  "description": "Laravel framework analysis — artisan commands, Eloquent models, Blade",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/learning-engine",
3
- "version": "1.1.402",
3
+ "version": "1.1.404",
4
4
  "description": "Learning engine for extracting lessons from runtime execution (RFC-0058)",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/logging",
3
- "version": "1.1.402",
3
+ "version": "1.1.404",
4
4
  "type": "module",
5
5
  "description": "Centralized structured application logging with buffered Cloudflare R2 and webhook transports",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/mcp-adapter",
3
- "version": "1.1.402",
3
+ "version": "1.1.404",
4
4
  "type": "module",
5
5
  "description": "MCP server adapter for pi-harness — exposes harness capabilities as MCP tools/resources/prompts (RFC-0068)",
6
6
  "main": "dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/memory-engine",
3
- "version": "1.1.402",
3
+ "version": "1.1.404",
4
4
  "description": "Memory engine with OKF integration for durable knowledge management (RFC-0060)",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/milestone-manager",
3
- "version": "1.1.402",
3
+ "version": "1.1.404",
4
4
  "description": "Track milestones and alerts when items are at risk",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/model-registry",
3
- "version": "1.1.402",
3
+ "version": "1.1.404",
4
4
  "description": "Model Registry for pi-harness-runtime — centralized model metadata with pricing",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/nextjs-plugin",
3
- "version": "1.1.402",
3
+ "version": "1.1.404",
4
4
  "description": "Next.js framework detection and analysis for pi-harness-runtime (RFC-0062)",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/notification",
3
- "version": "1.1.402",
3
+ "version": "1.1.404",
4
4
  "description": "pi-harness-runtime — notification",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/observability",
3
- "version": "1.1.402",
3
+ "version": "1.1.404",
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.402",
3
+ "version": "1.1.404",
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.402",
3
+ "version": "1.1.404",
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.402",
3
+ "version": "1.1.404",
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.402",
3
+ "version": "1.1.404",
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.402",
3
+ "version": "1.1.404",
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.402",
3
+ "version": "1.1.404",
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.402",
3
+ "version": "1.1.404",
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.402",
3
+ "version": "1.1.404",
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.402",
3
+ "version": "1.1.404",
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.402",
3
+ "version": "1.1.404",
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.402",
3
+ "version": "1.1.404",
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.402",
3
+ "version": "1.1.404",
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.402",
3
+ "version": "1.1.404",
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.402",
3
+ "version": "1.1.404",
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.402",
3
+ "version": "1.1.404",
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.402",
3
+ "version": "1.1.404",
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.402",
3
+ "version": "1.1.404",
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.402",
3
+ "version": "1.1.404",
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.402",
3
+ "version": "1.1.404",
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.402",
3
+ "version": "1.1.404",
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.402",
3
+ "version": "1.1.404",
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.402",
3
+ "version": "1.1.404",
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.402",
3
+ "version": "1.1.404",
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.402",
3
+ "version": "1.1.404",
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.402",
3
+ "version": "1.1.404",
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.402",
3
+ "version": "1.1.404",
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.402",
3
+ "version": "1.1.404",
4
4
  "type": "module",
5
5
  "main": "src/index.ts",
6
6
  "exports": {