pi-harness-runtime 1.1.49 → 1.1.50

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 (97) hide show
  1. package/harness/langchain/agents.test.ts +0 -1
  2. package/harness/langchain/daemon.test.ts +60 -5
  3. package/harness/langchain/daemon.ts +1 -0
  4. package/harness/langchain/file-tools.ts +15 -5
  5. package/harness/langchain/graph.ts +35 -10
  6. package/harness/langchain/scoreboard.test.ts +5 -4
  7. package/package.json +1 -1
  8. package/packages/a2a-adapter/package.json +1 -1
  9. package/packages/architecture-generator/package.json +1 -1
  10. package/packages/auth/package.json +1 -1
  11. package/packages/autonomous-refactor/package.json +1 -1
  12. package/packages/autonomous-runtime/package.json +1 -1
  13. package/packages/cache-strategy/package.json +1 -1
  14. package/packages/capability-registry/package.json +1 -1
  15. package/packages/checkpoint/package.json +1 -1
  16. package/packages/cli-plugin-sdk/package.json +1 -1
  17. package/packages/clipboard/package.json +1 -1
  18. package/packages/clipboard-plugin/package.json +1 -1
  19. package/packages/code-generation/package.json +1 -1
  20. package/packages/code-review/package.json +1 -1
  21. package/packages/codex-adapter/package.json +1 -1
  22. package/packages/config-capture/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/cookie-sanitizer/package.json +1 -1
  27. package/packages/cost-optimizer/package.json +1 -1
  28. package/packages/dependency-analyzer/package.json +1 -1
  29. package/packages/django-plugin/package.json +1 -1
  30. package/packages/doc-generator/package.json +1 -1
  31. package/packages/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-store/package.json +1 -1
  35. package/packages/experience-replay/package.json +1 -1
  36. package/packages/feedback-collector/package.json +1 -1
  37. package/packages/file-copy-helper/package.json +1 -1
  38. package/packages/framework-detector/package.json +1 -1
  39. package/packages/framework-plugin-sdk/package.json +1 -1
  40. package/packages/frappe-plugin/package.json +1 -1
  41. package/packages/generic-web-plugin/package.json +1 -1
  42. package/packages/health-monitor/package.json +1 -1
  43. package/packages/intent-analyzer/package.json +1 -1
  44. package/packages/knowledge-graph/package.json +1 -1
  45. package/packages/knowledge-retrieval/package.json +1 -1
  46. package/packages/laravel-plugin/package.json +1 -1
  47. package/packages/learning-engine/package.json +1 -1
  48. package/packages/mcp-adapter/package.json +1 -1
  49. package/packages/memory-engine/package.json +1 -1
  50. package/packages/milestone-manager/package.json +1 -1
  51. package/packages/model-registry/package.json +1 -1
  52. package/packages/nextjs-plugin/package.json +1 -1
  53. package/packages/notification/package.json +1 -1
  54. package/packages/observability/package.json +1 -1
  55. package/packages/okf-indexer/package.json +1 -1
  56. package/packages/performance-optimizer/package.json +1 -1
  57. package/packages/privilege-broker/package.json +1 -1
  58. package/packages/project-analyzer/package.json +1 -1
  59. package/packages/project-bootstrap/package.json +1 -1
  60. package/packages/projection-engine/package.json +1 -1
  61. package/packages/prompt-compiler/package.json +1 -1
  62. package/packages/prompt-versioning/package.json +1 -1
  63. package/packages/provider-adapter-sdk/package.json +1 -1
  64. package/packages/provider-router/package.json +1 -1
  65. package/packages/provider-selector/package.json +1 -1
  66. package/packages/providers/package.json +1 -1
  67. package/packages/quota-manager/package.json +1 -1
  68. package/packages/rate-limiter/package.json +1 -1
  69. package/packages/react-vite-plugin/package.json +1 -1
  70. package/packages/release-manager/package.json +1 -1
  71. package/packages/requirement-compiler/package.json +1 -1
  72. package/packages/runtime/package.json +1 -1
  73. package/packages/scheduler/package.json +1 -1
  74. package/packages/scheduler-adapter/package.json +1 -1
  75. package/packages/session/package.json +1 -1
  76. package/packages/session-api/package.json +1 -1
  77. package/packages/session-export/package.json +1 -1
  78. package/packages/shared-context/package.json +1 -1
  79. package/packages/skill-mcp-client/package.json +1 -1
  80. package/packages/skill-registry/package.json +1 -1
  81. package/packages/sprint-planner/package.json +1 -1
  82. package/packages/subscription-engine/package.json +1 -1
  83. package/packages/task-compiler/package.json +1 -1
  84. package/packages/tencentdb-memory/package.json +1 -1
  85. package/packages/tencentdb-sync/package.json +1 -1
  86. package/packages/test-data-generator/package.json +1 -1
  87. package/packages/test-generator/package.json +1 -1
  88. package/packages/todo-bd-sync/package.json +1 -1
  89. package/packages/token-estimation/package.json +1 -1
  90. package/packages/token-optimizer/package.json +1 -1
  91. package/packages/tui/package.json +1 -1
  92. package/packages/types/package.json +1 -1
  93. package/packages/workflow-events/package.json +1 -1
  94. package/packages/workspace-scanner/package.json +1 -1
  95. package/packages/worktree/package.json +1 -1
  96. package/packages/write-review/package.json +1 -1
  97. package/packages/write-review/src/blackboard.ts +14 -4
@@ -1,4 +1,3 @@
1
-
2
1
  import { describe, it } from "node:test";
3
2
  import assert from "node:assert";
4
3
  import { isAutonomyRequest } from "./agents.js";
@@ -23,6 +23,7 @@ import { randomUUID } from "node:crypto";
23
23
 
24
24
  import { LoopDaemon, writeAck } from "./daemon.js";
25
25
  import type { DaemonConfig } from "./daemon.js";
26
+ import type { LoopDeps } from "./graph.js";
26
27
 
27
28
  // ─── Test fixtures ────────────────────────────────────────────────────────────
28
29
 
@@ -301,25 +302,79 @@ describe("T5 — single-writer (exactly one lease winner)", () => {
301
302
  describe("T6 — maxIterations cap", () => {
302
303
  it("with maxIterations=2, exactly 2 code.written events appear", async () => {
303
304
  cleanEvents();
305
+ // Mock reviewer: always changes_requested with a rotating file to avoid smart-stop.
306
+ // Use a mutable ref so review() sees the CURRENT writeCount (after increment).
307
+ const counter = { n: 0 };
308
+ const mockDeps: LoopDeps = {
309
+ maxIterations: 2,
310
+ onStep: undefined,
311
+ plan: async () => "# Stub plan\n1. Do thing",
312
+ write: async () => {
313
+ counter.n++;
314
+ return `// code pass ${counter.n}`;
315
+ },
316
+ review: async () => ({
317
+ verdict: "changes_requested" as const,
318
+ summary: "need changes",
319
+ comments: [{ file: `file${counter.n}.ts`, comment: "fix this", severity: "major" }],
320
+ }),
321
+ };
304
322
  const daemon = new LoopDaemon(
305
- testConfig({ sources: ["inbox"], maxIterations: 2 }),
323
+ testConfig({ sources: ["inbox"], maxIterations: 2, deps: mockDeps }),
306
324
  );
307
325
  daemon.start();
308
326
  try {
309
327
  const filename = `test-T6-${randomUUID().slice(0, 6)}.md`;
310
328
  writeFileSync(join(WORKSPACE, filename), "Test iteration cap", "utf8");
311
329
  await waitForEvent("loop.finished", 15_000);
312
- // Dry-run: writeCount=1 → changes_requested → writeCount=2 → approved
313
- // With maxIterations=2, loop exits after iteration 2
330
+ // Mock: writeCount=1 → review(changes, file1.ts) → writeCount=2 → review(changes, file2.ts)
331
+ // With maxIterations=2, the hard cap kicks in after iteration 2 → loop exits
332
+ // Smart-stop: different files (file1 vs file2) → no stuck-file trigger
314
333
  assert.strictEqual(
315
- countEvents("code.written"),
334
+ counter.n,
316
335
  2,
317
- `Expected exactly 2 code.written`,
336
+ `Expected exactly 2 writes (maxIterations=2, smart-stop overridden by different files)`,
318
337
  );
319
338
  } finally {
320
339
  daemon.stop();
321
340
  }
322
341
  });
342
+
343
+ it("smart-stop: converged (only minor comments) terminates early", async () => {
344
+ cleanEvents();
345
+ let writeCount = 0;
346
+ // Reviewer returns only minor comments → smart-stop should trigger at iteration 1
347
+ const mockDeps: LoopDeps = {
348
+ maxIterations: 5,
349
+ onStep: undefined,
350
+ plan: async () => "# Stub plan",
351
+ write: async () => {
352
+ writeCount++;
353
+ return `// code ${writeCount}`;
354
+ },
355
+ review: async () => ({
356
+ verdict: "changes_requested" as const,
357
+ summary: "minor",
358
+ comments: [
359
+ { file: "a.ts", comment: "nitpick", severity: "minor" },
360
+ { file: "b.ts", comment: "typo", severity: "minor" },
361
+ ],
362
+ }),
363
+ };
364
+ const daemon = new LoopDaemon(
365
+ testConfig({ sources: ["inbox"], maxIterations: 5, deps: mockDeps }),
366
+ );
367
+ daemon.start();
368
+ try {
369
+ const filename = `test-T6b-${randomUUID().slice(0, 6)}.md`;
370
+ writeFileSync(join(WORKSPACE, filename), "Test smart-stop", "utf8");
371
+ await waitForEvent("loop.finished", 15_000);
372
+ // Smart-stop: hasOnlyMinor=true (2 minor comments) → stop at iteration 1
373
+ assert.strictEqual(writeCount, 1, "converged: should stop after 1 write");
374
+ } finally {
375
+ daemon.stop();
376
+ }
377
+ });
323
378
  });
324
379
 
325
380
  // ─── T7: Crash resilience ───────────────────────────────────────────────────
@@ -824,6 +824,7 @@ export class LoopDaemon {
824
824
  notificationConfig: config.notificationConfig ?? undefined,
825
825
  tunnelCommand: config.tunnelCommand,
826
826
  widget: config.widget,
827
+ deps: config.deps,
827
828
  } as Required<DaemonConfig>;
828
829
 
829
830
  this.agentId = this.config.agentId;
@@ -46,7 +46,9 @@ export const readFile = tool(
46
46
  }
47
47
  const stats = statSync(resolved);
48
48
  if (stats.isDirectory()) {
49
- return JSON.stringify({ error: `Path is a directory, not a file: ${resolved}` });
49
+ return JSON.stringify({
50
+ error: `Path is a directory, not a file: ${resolved}`,
51
+ });
50
52
  }
51
53
  const content = readFileSync(resolved, encoding as BufferEncoding);
52
54
  return JSON.stringify({
@@ -70,7 +72,9 @@ export const readFile = tool(
70
72
  "Use this before editing a file so you know its current contents. " +
71
73
  "Returns JSON with path, size, lines, and content fields.",
72
74
  schema: z.object({
73
- path: z.string().describe("Absolute path or path relative to the repository root"),
75
+ path: z
76
+ .string()
77
+ .describe("Absolute path or path relative to the repository root"),
74
78
  encoding: z
75
79
  .enum(["utf-8", "utf-16", "ascii", "base64"])
76
80
  .optional()
@@ -126,12 +130,16 @@ export const writeFile = tool(
126
130
  "Set append=true to add to the end of an existing file. " +
127
131
  "Returns JSON with ok, path, size, and action fields.",
128
132
  schema: z.object({
129
- path: z.string().describe("Absolute path or path relative to the repository root"),
133
+ path: z
134
+ .string()
135
+ .describe("Absolute path or path relative to the repository root"),
130
136
  content: z.string().describe("File content. Use \\n for newlines."),
131
137
  append: z
132
138
  .boolean()
133
139
  .optional()
134
- .describe("Append to existing file instead of overwriting (default: false)"),
140
+ .describe(
141
+ "Append to existing file instead of overwriting (default: false)",
142
+ ),
135
143
  }),
136
144
  },
137
145
  );
@@ -169,7 +177,9 @@ export const listDir = tool(
169
177
  "List the contents of a directory (files and subdirectories, non-recursive). " +
170
178
  "Returns JSON with path and entries array (each entry has name, type, path).",
171
179
  schema: z.object({
172
- path: z.string().describe("Absolute path or path relative to the repository root"),
180
+ path: z
181
+ .string()
182
+ .describe("Absolute path or path relative to the repository root"),
173
183
  }),
174
184
  },
175
185
  );
@@ -20,8 +20,6 @@ import {
20
20
  StateGraph,
21
21
  } from "@langchain/langgraph";
22
22
  import {
23
- autonomyDirective,
24
- isAutonomyRequest,
25
23
  lastMessage,
26
24
  type ReviewVerdict,
27
25
  ReviewVerdictSchema,
@@ -51,6 +49,11 @@ const LoopState = Annotation.Root({
51
49
  reducer: (prev, next) => [...(prev ?? []), ...(next ?? [])],
52
50
  default: () => [],
53
51
  }),
52
+ /** File that received comments in the previous review. Used for smart-stop. */
53
+ lastCommentedFile: Annotation<string | undefined>({
54
+ reducer: (_prev, next) => next,
55
+ default: () => undefined,
56
+ }),
54
57
  });
55
58
 
56
59
  export type LoopState = typeof LoopState.State;
@@ -102,8 +105,11 @@ function reviewNode(deps: LoopDeps) {
102
105
  return async (state: LoopState): Promise<Partial<LoopState>> => {
103
106
  const review = await deps.review(state.plan, state.code);
104
107
  deps.onStep?.("review", state);
108
+ const commentedFile =
109
+ review.comments.length > 0 ? (review.comments[0].file ?? "") : undefined;
105
110
  return {
106
111
  review,
112
+ lastCommentedFile: commentedFile,
107
113
  log: [`[review:${state.iteration}] GPT verdict: ${review.verdict}`],
108
114
  };
109
115
  };
@@ -112,12 +118,23 @@ function reviewNode(deps: LoopDeps) {
112
118
  function finishNode() {
113
119
  return async (state: LoopState): Promise<Partial<LoopState>> => {
114
120
  const verdict = state.review?.verdict ?? "blocked";
115
- const reason =
116
- verdict === "approved"
117
- ? "reviewer approved"
118
- : verdict === "changes_requested"
119
- ? `max iterations (${state.iteration}) reached with changes still requested`
120
- : "reviewer blocked the task";
121
+ const comments = state.review?.comments ?? [];
122
+ let reason: string;
123
+ if (verdict === "approved") {
124
+ reason = "reviewer approved";
125
+ } else if (verdict === "blocked") {
126
+ reason = "reviewer blocked the task";
127
+ } else if (state.iteration >= 3) {
128
+ reason = `max iterations (${state.iteration}) reached with changes still requested`;
129
+ } else if (
130
+ comments.length > 0 &&
131
+ comments.every((c) => c.severity === "minor" || !c.severity)
132
+ ) {
133
+ reason = `converged: only minor comments (${state.iteration})`;
134
+ } else {
135
+ const file = state.lastCommentedFile ?? "unknown";
136
+ reason = `stuck: same file (${file}) flagged for ${comments.length} comment(s) across iterations`;
137
+ }
121
138
  return {
122
139
  log: [`[finish] ${state.iteration} iteration(s) — ${reason}`],
123
140
  };
@@ -126,13 +143,22 @@ function finishNode() {
126
143
 
127
144
  // ─── Routing ────────────────────────────────────────────────────────────────
128
145
 
146
+ /** Smart stop: loop terminates early when quality criteria are met. */
129
147
  function routeAfterReview(
130
148
  state: LoopState,
131
149
  maxIterations: number,
132
150
  ): "write" | "finish" {
133
151
  const verdict = state.review?.verdict;
152
+ const comments = state.review?.comments ?? [];
153
+ // 1. Always finish on approved or blocked
134
154
  if (verdict === "approved" || verdict === "blocked") return "finish";
155
+ // 2. Hard cap
135
156
  if (state.iteration >= maxIterations) return "finish";
157
+ // 3. SMART STOP: only minor comments (≤2) — converge fast
158
+ const hasOnlyMinor = comments.every(
159
+ (c) => c.severity === "minor" || !c.severity,
160
+ );
161
+ if (hasOnlyMinor && comments.length <= 2) return "finish";
136
162
  return "write";
137
163
  }
138
164
 
@@ -229,7 +255,6 @@ export async function buildRealLoopDeps(
229
255
  }
230
256
 
231
257
  // Autonomy mode: computed inside plan(), stored for write()/review()
232
- const _autonomous = false;
233
258
  const _directive = "";
234
259
 
235
260
  /** Inject scoreboard markdown into a user message. */
@@ -415,7 +440,7 @@ export function buildDryRunDeps(
415
440
  {
416
441
  file: "index.ts",
417
442
  comment: "dry-run: rename the exported constant",
418
- severity: "minor",
443
+ severity: "major",
419
444
  },
420
445
  ],
421
446
  };
@@ -19,7 +19,6 @@ import { buildDryRunDeps } from "./graph.js";
19
19
  import { createLoopCheckpointer } from "./checkpointer.js";
20
20
 
21
21
  describe("T15 — Scoreboard blackboard wiring", () => {
22
-
23
22
  const tmpDir = `/tmp/scoreboard-test-${Date.now()}`;
24
23
  const blackboardDir = join(tmpDir, ".write-review");
25
24
 
@@ -128,7 +127,7 @@ describe("T15 — Scoreboard blackboard wiring", () => {
128
127
  request: "test",
129
128
  plan: "# plan",
130
129
  iteration: 1,
131
- code: '```harness/langchain/surge.ts\nconst x = 1;\n```',
130
+ code: "```harness/langchain/surge.ts\nconst x = 1;\n```",
132
131
  review: null as any,
133
132
  log: [],
134
133
  });
@@ -153,7 +152,10 @@ describe("T15 — Scoreboard blackboard wiring", () => {
153
152
  );
154
153
  assert.equal(content.phase, "changes_requested");
155
154
  assert.equal(content.verdict, "changes_requested");
156
- assert.ok(content.changesRequested?.length > 0, "changesRequested should be set");
155
+ assert.ok(
156
+ content.changesRequested?.length > 0,
157
+ "changesRequested should be set",
158
+ );
157
159
  });
158
160
 
159
161
  it("dry-run plan prompt includes scoreboard markdown", async () => {
@@ -218,5 +220,4 @@ describe("T15 — Scoreboard blackboard wiring", () => {
218
220
  assert.equal(content.phase, "approved");
219
221
  assert.equal(content.iteration, 1);
220
222
  });
221
-
222
223
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-harness-runtime",
3
- "version": "1.1.49",
3
+ "version": "1.1.50",
4
4
  "description": "[BETA] Codex-style /usage status + autonomous coding harness for pi. Not production ready — expect breaking changes.",
5
5
  "type": "module",
6
6
  "scripts": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/a2a-adapter",
3
- "version": "1.1.49",
3
+ "version": "1.1.50",
4
4
  "type": "module",
5
5
  "description": "Google Agent-to-Agent (A2A) protocol adapter for pi-harness",
6
6
  "main": "dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/architecture-generator",
3
- "version": "1.1.49",
3
+ "version": "1.1.50",
4
4
  "description": "Generate ADR and Mermaid diagrams from project analysis",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/auth",
3
- "version": "1.1.49",
3
+ "version": "1.1.50",
4
4
  "description": "pi-harness-runtime — auth",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/autonomous-refactor",
3
- "version": "1.1.49",
3
+ "version": "1.1.50",
4
4
  "type": "module",
5
5
  "description": "Autonomous refactoring engine",
6
6
  "main": "dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/autonomous-runtime",
3
- "version": "1.1.49",
3
+ "version": "1.1.50",
4
4
  "description": "Autonomous Operations Runtime — task inbox, lease management, and worker lifecycle (RFC-0101)",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/cache-strategy",
3
- "version": "1.1.49",
3
+ "version": "1.1.50",
4
4
  "type": "module",
5
5
  "description": "Smart caching with TTL and invalidation strategies (RFC-0022)",
6
6
  "main": "dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/capability-registry",
3
- "version": "1.1.49",
3
+ "version": "1.1.50",
4
4
  "description": "Capability Registry for pi-harness-runtime — tracks model capabilities and enables capability-based routing",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/checkpoint",
3
- "version": "1.1.49",
3
+ "version": "1.1.50",
4
4
  "description": "Enhanced checkpoint system with incremental snapshots, diff-based storage, and recovery strategies",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/cli-plugin-sdk",
3
- "version": "1.1.49",
3
+ "version": "1.1.50",
4
4
  "type": "module",
5
5
  "description": "CLI Plugin SDK for pi-harness — install, list, remove, update, invoke plugins",
6
6
  "main": "dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/clipboard",
3
- "version": "1.1.49",
3
+ "version": "1.1.50",
4
4
  "type": "module",
5
5
  "main": "src/index.ts",
6
6
  "exports": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/clipboard-plugin",
3
- "version": "1.1.49",
3
+ "version": "1.1.50",
4
4
  "type": "module",
5
5
  "main": "src/index.ts",
6
6
  "exports": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/code-generation",
3
- "version": "1.1.49",
3
+ "version": "1.1.50",
4
4
  "description": "Code generation pipeline for pi-harness-runtime",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/code-review",
3
- "version": "1.1.49",
3
+ "version": "1.1.50",
4
4
  "description": "Automated code review engine for pi-harness-runtime",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/codex-adapter",
3
- "version": "1.1.49",
3
+ "version": "1.1.50",
4
4
  "type": "module",
5
5
  "description": "OpenAI Codex provider adapter for pi-harness",
6
6
  "main": "dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@moocoding/config-capture",
3
- "version": "1.1.49",
3
+ "version": "1.1.50",
4
4
  "description": "Auto-capture API-fetched configuration values to AGENTS.md",
5
5
  "type": "module",
6
6
  "main": "src/index.ts",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/context-compiler",
3
- "version": "1.1.49",
3
+ "version": "1.1.50",
4
4
  "description": "Bounded context selection engine for pi-harness-runtime",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/context-discovery",
3
- "version": "1.1.49",
3
+ "version": "1.1.50",
4
4
  "type": "module",
5
5
  "main": "src/index.ts",
6
6
  "exports": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/context-manager",
3
- "version": "1.1.49",
3
+ "version": "1.1.50",
4
4
  "description": "Context Window Manager — prevents model context overflow via compaction and resume prompts (RFC-0010)",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/cookie-sanitizer",
3
- "version": "1.1.49",
3
+ "version": "1.1.50",
4
4
  "description": "pi-harness-runtime — cookie sanitizer (provider-quota cookie file normaliser)",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/cost-optimizer",
3
- "version": "1.1.49",
3
+ "version": "1.1.50",
4
4
  "description": "Cost Optimizer for pi-harness-runtime — budget tracking, forecasting, and model selection optimization",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/dependency-analyzer",
3
- "version": "1.1.49",
3
+ "version": "1.1.50",
4
4
  "type": "module",
5
5
  "main": "src/index.ts",
6
6
  "exports": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/django-plugin",
3
- "version": "1.1.49",
3
+ "version": "1.1.50",
4
4
  "description": "Django framework analysis — models, management commands, settings",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/doc-generator",
3
- "version": "1.1.49",
3
+ "version": "1.1.50",
4
4
  "description": "Auto-Doc Generator — generate documentation from source code (RFC-0014)",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/evaluation-engine",
3
- "version": "1.1.49",
3
+ "version": "1.1.50",
4
4
  "description": "Evaluation engine for pi-harness runtime (RFC-0057)",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/evaluation-runner",
3
- "version": "1.1.49",
3
+ "version": "1.1.50",
4
4
  "type": "module",
5
5
  "description": "Framework-agnostic evaluation framework for AI outputs (RFC-0020)",
6
6
  "main": "dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/event-bus",
3
- "version": "1.1.49",
3
+ "version": "1.1.50",
4
4
  "type": "module",
5
5
  "main": "src/index.ts",
6
6
  "exports": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/event-store",
3
- "version": "1.1.49",
3
+ "version": "1.1.50",
4
4
  "type": "module",
5
5
  "main": "src/index.ts",
6
6
  "exports": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/experience-replay",
3
- "version": "1.1.49",
3
+ "version": "1.1.50",
4
4
  "description": "Experience replay for debugging and reproducibility (RFC-0059)",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/feedback-collector",
3
- "version": "1.1.49",
3
+ "version": "1.1.50",
4
4
  "type": "module",
5
5
  "description": "Collect and aggregate human/automated feedback (RFC-0021)",
6
6
  "main": "dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@moocoding/file-copy-helper",
3
- "version": "1.1.49",
3
+ "version": "1.1.50",
4
4
  "description": "Injects cp/sudo cp rule when user asks to mimic/copy files",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/framework-detector",
3
- "version": "1.1.49",
3
+ "version": "1.1.50",
4
4
  "description": "Framework detection 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/framework-plugin-sdk",
3
- "version": "1.1.49",
3
+ "version": "1.1.50",
4
4
  "description": "Framework plugin SDK for pi-harness-runtime",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/frappe-plugin",
3
- "version": "1.1.49",
3
+ "version": "1.1.50",
4
4
  "description": "Frappe/ERPNext framework analysis — DocTypes, hooks, bench sites, site config",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/generic-web-plugin",
3
- "version": "1.1.49",
3
+ "version": "1.1.50",
4
4
  "description": "Generic web framework analysis — REST/GraphQL endpoints, OpenAPI, auth",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/health-monitor",
3
- "version": "1.1.49",
3
+ "version": "1.1.50",
4
4
  "type": "module",
5
5
  "description": "Health monitoring and auto-healing",
6
6
  "main": "dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/intent-analyzer",
3
- "version": "1.1.49",
3
+ "version": "1.1.50",
4
4
  "type": "module",
5
5
  "main": "src/index.ts",
6
6
  "exports": {