pi-harness-runtime 1.1.18 → 1.1.26

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 (101) hide show
  1. package/harness/e2e/auto-test-loop.ts +94 -29
  2. package/harness/e2e/tools-detector.ts +20 -17
  3. package/harness/index.ts +20 -3
  4. package/harness/loop-runtime.ts +49 -13
  5. package/harness/skill-sync.test.ts +57 -0
  6. package/harness/skill-sync.ts +247 -0
  7. package/harness/ssh-hang-recovery.ts +280 -0
  8. package/package.json +1 -1
  9. package/packages/a2a-adapter/package.json +1 -1
  10. package/packages/architecture-generator/package.json +1 -1
  11. package/packages/auth/package.json +1 -1
  12. package/packages/autonomous-refactor/package.json +1 -1
  13. package/packages/autonomous-runtime/package.json +1 -1
  14. package/packages/cache-strategy/package.json +1 -1
  15. package/packages/capability-registry/package.json +1 -1
  16. package/packages/checkpoint/package.json +1 -1
  17. package/packages/cli-plugin-sdk/package.json +1 -1
  18. package/packages/clipboard/package.json +1 -1
  19. package/packages/clipboard-plugin/package.json +1 -1
  20. package/packages/code-generation/package.json +1 -1
  21. package/packages/code-review/package.json +1 -1
  22. package/packages/codex-adapter/package.json +1 -1
  23. package/packages/config-capture/package.json +1 -1
  24. package/packages/context-compiler/package.json +1 -1
  25. package/packages/context-discovery/package.json +1 -1
  26. package/packages/context-manager/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/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-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/knowledge-graph/package.json +1 -1
  46. package/packages/knowledge-retrieval/package.json +1 -1
  47. package/packages/laravel-plugin/package.json +1 -1
  48. package/packages/learning-engine/package.json +1 -1
  49. package/packages/mcp-adapter/package.json +1 -1
  50. package/packages/memory-engine/package.json +1 -1
  51. package/packages/milestone-manager/package.json +1 -1
  52. package/packages/model-registry/package.json +1 -1
  53. package/packages/nextjs-plugin/package.json +1 -1
  54. package/packages/notification/package.json +1 -1
  55. package/packages/observability/package.json +1 -1
  56. package/packages/okf-indexer/package.json +1 -1
  57. package/packages/performance-optimizer/package.json +1 -1
  58. package/packages/privilege-broker/package.json +1 -1
  59. package/packages/project-analyzer/package.json +1 -1
  60. package/packages/project-bootstrap/package.json +1 -1
  61. package/packages/projection-engine/package.json +1 -1
  62. package/packages/prompt-compiler/package.json +1 -1
  63. package/packages/prompt-versioning/package.json +1 -1
  64. package/packages/provider-adapter-sdk/package.json +1 -1
  65. package/packages/provider-router/package.json +1 -1
  66. package/packages/provider-selector/package.json +1 -1
  67. package/packages/providers/package.json +1 -1
  68. package/packages/quota-manager/package.json +1 -1
  69. package/packages/rate-limiter/package.json +1 -1
  70. package/packages/react-vite-plugin/package.json +1 -1
  71. package/packages/release-manager/package.json +1 -1
  72. package/packages/requirement-compiler/package.json +1 -1
  73. package/packages/runtime/package.json +1 -1
  74. package/packages/scheduler/package.json +1 -1
  75. package/packages/scheduler-adapter/package.json +1 -1
  76. package/packages/session/package.json +1 -1
  77. package/packages/session-api/package.json +1 -1
  78. package/packages/session-export/package.json +1 -1
  79. package/packages/shared-context/package.json +1 -1
  80. package/packages/skill-mcp-client/package.json +28 -0
  81. package/packages/skill-mcp-client/src/client.ts +171 -0
  82. package/packages/skill-mcp-client/src/errors.ts +75 -0
  83. package/packages/skill-mcp-client/src/index.ts +13 -0
  84. package/packages/skill-mcp-client/src/types.ts +123 -0
  85. package/packages/skill-registry/package.json +1 -1
  86. package/packages/sprint-planner/package.json +1 -1
  87. package/packages/subscription-engine/package.json +1 -1
  88. package/packages/task-compiler/package.json +1 -1
  89. package/packages/tencentdb-memory/package.json +1 -1
  90. package/packages/tencentdb-sync/package.json +1 -1
  91. package/packages/test-data-generator/package.json +1 -1
  92. package/packages/test-generator/package.json +1 -1
  93. package/packages/todo-bd-sync/package.json +1 -1
  94. package/packages/token-estimation/package.json +1 -1
  95. package/packages/token-optimizer/package.json +1 -1
  96. package/packages/tui/package.json +1 -1
  97. package/packages/types/package.json +1 -1
  98. package/packages/workflow-events/package.json +1 -1
  99. package/packages/workspace-scanner/package.json +1 -1
  100. package/packages/worktree/package.json +1 -1
  101. package/packages/write-review/package.json +1 -1
@@ -0,0 +1,247 @@
1
+ /**
2
+ * Skill Sync Service — RFC-0106
3
+ *
4
+ * Syncs skills from Skills SaaS backend and registers them with local registry.
5
+ * Falls back gracefully if backend is unavailable.
6
+ */
7
+
8
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
9
+ import { join } from "node:path";
10
+ import { homedir } from "node:os";
11
+ import type {
12
+ SkillInfo,
13
+ GetSkillResult,
14
+ } from "../packages/skill-mcp-client/src/types.js";
15
+ import { SkillAPIError } from "../packages/skill-mcp-client/src/errors.js";
16
+
17
+ type SkillMCPClient = InstanceType<
18
+ typeof import("../packages/skill-mcp-client/src/client.js").SkillMCPClient
19
+ >;
20
+
21
+ // Lazy import to avoid errors if package not built yet
22
+ let clientInstance: SkillMCPClient | null = null;
23
+
24
+ async function getClient(): Promise<SkillMCPClient | null> {
25
+ if (!process.env.SKILLS_SAAS_API_KEY) {
26
+ return null;
27
+ }
28
+
29
+ if (clientInstance) {
30
+ return clientInstance;
31
+ }
32
+
33
+ try {
34
+ const mod = await import("../packages/skill-mcp-client/src/client.js");
35
+ const SkillMCPClientClass = mod.SkillMCPClient;
36
+ const serverUrl =
37
+ process.env.SKILLS_SAAS_URL || "https://api.skills.bunchee.online";
38
+
39
+ clientInstance = new SkillMCPClientClass({
40
+ serverUrl,
41
+ apiKey: process.env.SKILLS_SAAS_API_KEY,
42
+ timeoutMs: 5000,
43
+ });
44
+ return clientInstance;
45
+ } catch {
46
+ console.warn("[skill-sync] Failed to import skill-mcp-client");
47
+ return null;
48
+ }
49
+ }
50
+
51
+ // Cache directory
52
+ const CACHE_DIR = join(homedir(), ".pi", "skills-cache");
53
+ const CACHE_FILE = join(CACHE_DIR, "skills-cache.json");
54
+ const CACHE_TTL_MS = 24 * 60 * 60 * 1000; // 24 hours
55
+
56
+ interface CacheData {
57
+ skills: SkillInfo[];
58
+ cachedAt: string;
59
+ version: string;
60
+ }
61
+
62
+ interface SkillSyncResult {
63
+ success: boolean;
64
+ skillCount: number;
65
+ source: "saas" | "cache" | "none";
66
+ error?: string;
67
+ }
68
+
69
+ /**
70
+ * Get cached skills from local disk
71
+ */
72
+ function getCachedSkills(): CacheData | null {
73
+ try {
74
+ if (!existsSync(CACHE_FILE)) {
75
+ return null;
76
+ }
77
+
78
+ const data = JSON.parse(readFileSync(CACHE_FILE, "utf-8")) as CacheData;
79
+ const age = Date.now() - new Date(data.cachedAt).getTime();
80
+
81
+ if (age > CACHE_TTL_MS) {
82
+ return null; // Cache expired
83
+ }
84
+
85
+ return data;
86
+ } catch {
87
+ return null;
88
+ }
89
+ }
90
+
91
+ /**
92
+ * Save skills to local cache
93
+ */
94
+ function saveCache(data: CacheData): void {
95
+ try {
96
+ if (!existsSync(CACHE_DIR)) {
97
+ mkdirSync(CACHE_DIR, { recursive: true });
98
+ }
99
+ writeFileSync(CACHE_FILE, JSON.stringify(data, null, 2));
100
+ } catch {
101
+ console.warn("[skill-sync] Failed to save cache");
102
+ }
103
+ }
104
+
105
+ /**
106
+ * Fetch and cache skills from SaaS backend
107
+ */
108
+ async function fetchFromSaaS(): Promise<CacheData | null> {
109
+ const client = await getClient();
110
+ if (!client) {
111
+ return null;
112
+ }
113
+
114
+ try {
115
+ const result = await client.listSkills({ limit: 100 });
116
+ const cacheData: CacheData = {
117
+ skills: result.skills,
118
+ cachedAt: new Date().toISOString(),
119
+ version: "1.0.0",
120
+ };
121
+ saveCache(cacheData);
122
+ return cacheData;
123
+ } catch (error) {
124
+ if (error instanceof SkillAPIError) {
125
+ console.warn(
126
+ `[skill-sync] API error: ${error.message} (code: ${error.code})`,
127
+ );
128
+ } else {
129
+ console.warn("[skill-sync] Failed to fetch from SaaS");
130
+ }
131
+ return null;
132
+ }
133
+ }
134
+
135
+ /**
136
+ * Sync skills from SaaS backend (RFC-0106)
137
+ *
138
+ * Flow:
139
+ * 1. Check cache first
140
+ * 2. If cache valid, return cached
141
+ * 3. If cache expired or missing, fetch from SaaS
142
+ * 4. If SaaS fails, return empty array (graceful degradation)
143
+ *
144
+ * @param options.forceRefresh - Force refresh from SaaS
145
+ * @returns Skills list (may be empty if backend unavailable)
146
+ */
147
+ export async function syncSkillsFromSaaS(
148
+ options: { forceRefresh?: boolean } = {},
149
+ ): Promise<SkillSyncResult> {
150
+ // Check if API key is configured
151
+ if (!process.env.SKILLS_SAAS_API_KEY) {
152
+ return {
153
+ success: true,
154
+ skillCount: 0,
155
+ source: "none",
156
+ error: "SKILLS_SAAS_API_KEY not configured",
157
+ };
158
+ }
159
+
160
+ // Check cache first (unless force refresh)
161
+ if (!options.forceRefresh) {
162
+ const cached = getCachedSkills();
163
+ if (cached) {
164
+ return {
165
+ success: true,
166
+ skillCount: cached.skills.length,
167
+ source: "cache",
168
+ };
169
+ }
170
+ }
171
+
172
+ // Fetch from SaaS
173
+ const data = await fetchFromSaaS();
174
+ if (data) {
175
+ return {
176
+ success: true,
177
+ skillCount: data.skills.length,
178
+ source: "saas",
179
+ };
180
+ }
181
+
182
+ // SaaS failed, try to use stale cache
183
+ const staleCache = getCachedSkills();
184
+ if (staleCache) {
185
+ return {
186
+ success: true,
187
+ skillCount: staleCache.skills.length,
188
+ source: "cache",
189
+ error: "Using stale cache (SaaS unavailable)",
190
+ };
191
+ }
192
+
193
+ // Everything failed, return empty
194
+ return {
195
+ success: true,
196
+ skillCount: 0,
197
+ source: "none",
198
+ error: "Could not reach Skills SaaS backend",
199
+ };
200
+ }
201
+
202
+ /**
203
+ * Get full skill prompt by slug or id
204
+ *
205
+ * Returns null if skill not found or backend unavailable
206
+ */
207
+ export async function getSkillFromSaaS(identifier: {
208
+ slug?: string;
209
+ id?: string;
210
+ }): Promise<GetSkillResult | null> {
211
+ const client = await getClient();
212
+ if (!client) {
213
+ return null;
214
+ }
215
+
216
+ try {
217
+ return await client.getSkill(identifier);
218
+ } catch (error) {
219
+ if (error instanceof SkillAPIError) {
220
+ console.warn(`[skill-sync] Failed to get skill: ${error.message}`);
221
+ }
222
+ return null;
223
+ }
224
+ }
225
+
226
+ /**
227
+ * Check if skill sync is configured
228
+ */
229
+ export function isSkillSyncConfigured(): boolean {
230
+ return !!process.env.SKILLS_SAAS_API_KEY;
231
+ }
232
+
233
+ /**
234
+ * Get sync status info
235
+ */
236
+ export function getSyncStatus(): {
237
+ configured: boolean;
238
+ cacheValid: boolean;
239
+ cachedSkills: number;
240
+ } {
241
+ const cache = getCachedSkills();
242
+ return {
243
+ configured: isSkillSyncConfigured(),
244
+ cacheValid: !!cache,
245
+ cachedSkills: cache?.skills.length ?? 0,
246
+ };
247
+ }
@@ -0,0 +1,280 @@
1
+ /**
2
+ * SSH Hang Recovery — Smart SSH wrapper that auto-recovers from hangs
3
+ *
4
+ * Problem: SSH commands can hang indefinitely (PM2 restart, sudo prompts, etc.)
5
+ * Solution: Timeout + process killing + retry + escalation
6
+ *
7
+ * Flow:
8
+ * Execute SSH command
9
+ * → Timeout reached? → Kill stuck processes → Retry
10
+ * → Retry failed? → Kill PM2 daemon processes → Retry
11
+ * → Still failing? → Escalate to human with diagnostic
12
+ */
13
+
14
+ import { execSync, exec } from "child_process";
15
+ import { setTimeout as setAsyncTimeout, clearTimeout } from "timers";
16
+
17
+ export interface SSHConfig {
18
+ host: string;
19
+ user?: string;
20
+ timeout?: number; // ms, default 120000 (2 min)
21
+ maxRetries?: number;
22
+ strictHostKeyChecking?: boolean;
23
+ }
24
+
25
+ export interface SSHResult {
26
+ success: boolean;
27
+ stdout: string;
28
+ stderr: string;
29
+ elapsedMs: number;
30
+ retries: number;
31
+ hungProcessesKilled: boolean;
32
+ error?: string;
33
+ }
34
+
35
+ const DEFAULT_TIMEOUT = 120_000; // 2 minutes
36
+ const HANG_THRESHOLD_MS = 60_000; // 1 minute = likely hang
37
+
38
+ /**
39
+ * Sanitize input for shell commands - prevent command injection
40
+ */
41
+
42
+ /**
43
+ * Execute SSH command with automatic hang recovery
44
+ */
45
+ export async function sshWithRecovery(
46
+ config: SSHConfig,
47
+ command: string,
48
+ ): Promise<SSHResult> {
49
+ const {
50
+ host,
51
+ user = "frappe",
52
+ timeout = DEFAULT_TIMEOUT,
53
+ maxRetries = 3,
54
+ strictHostKeyChecking = false,
55
+ } = config;
56
+
57
+ const sshBase = `ssh -o BatchMode=yes -o ConnectTimeout=30 -o StrictHostKeyChecking=${strictHostKeyChecking ? "yes" : "no"} ${user}@${host}`;
58
+
59
+ let retries = 0;
60
+ let hungProcessesKilled = false;
61
+
62
+ while (retries <= maxRetries) {
63
+ const startTime = Date.now();
64
+
65
+ try {
66
+ // Execute with timeout
67
+ const result = await execAsync(
68
+ `${sshBase} '${command.replace(/'/g, "'\\''")}'`,
69
+ timeout,
70
+ );
71
+
72
+ return {
73
+ success: result.exitCode === 0,
74
+ stdout: result.stdout,
75
+ stderr: result.stderr,
76
+ elapsedMs: Date.now() - startTime,
77
+ retries,
78
+ hungProcessesKilled,
79
+ error: result.exitCode === 0 ? undefined : `Exit code: ${result.exitCode}`,
80
+ };
81
+ } catch (error: any) {
82
+ const elapsed = Date.now() - startTime;
83
+ const isTimeout = elapsed >= timeout;
84
+
85
+ console.error(
86
+ `[ssh-recovery] Attempt ${retries + 1} failed: ${error.message} (${elapsed}ms)`,
87
+ );
88
+
89
+ if (isTimeout) {
90
+ hungProcessesKilled = true;
91
+
92
+ // Kill stuck processes on remote server
93
+ await killStuckProcesses(host, user);
94
+
95
+ // Also kill any local SSH processes stuck on this host
96
+ killLocalSSHProcesses(host);
97
+
98
+ retries++;
99
+ } else {
100
+ // Non-timeout error (permission denied, etc.)
101
+ return {
102
+ success: false,
103
+ stdout: "",
104
+ stderr: "",
105
+ elapsedMs: elapsed,
106
+ retries,
107
+ hungProcessesKilled: false,
108
+ error: error.message,
109
+ };
110
+ }
111
+ }
112
+ }
113
+
114
+ // All retries exhausted
115
+ return {
116
+ success: false,
117
+ stdout: "",
118
+ stderr: "",
119
+ elapsedMs: 0,
120
+ retries,
121
+ hungProcessesKilled,
122
+ error: `Command failed after ${maxRetries + 1} attempts`,
123
+ };
124
+ }
125
+
126
+ /**
127
+ * Kill stuck processes on remote server
128
+ */
129
+ async function killStuckProcesses(host: string, user: string): Promise<void> {
130
+ const killCommands = [
131
+ // Kill stuck SSH sessions
132
+ `pkill -f "ssh.*${host}" || true`,
133
+ // Kill stuck PM2 commands
134
+ `pkill -f "pm2.*amos-saas" || true`,
135
+ // Kill stuck sudo commands
136
+ `pkill -f "sudo.*pm2" || true`,
137
+ ];
138
+
139
+ for (const cmd of killCommands) {
140
+ try {
141
+ execSync(
142
+ `ssh -o BatchMode=yes -o ConnectTimeout=10 ${user}@${host} '${cmd}'`,
143
+ { timeout: 10_000, encoding: "utf-8" },
144
+ );
145
+ } catch {
146
+ // Ignore errors from kill commands
147
+ }
148
+ }
149
+ }
150
+
151
+ /**
152
+ * Kill local SSH processes stuck on this host
153
+ */
154
+ function killLocalSSHProcesses(host: string): void {
155
+ try {
156
+ // Kill any local SSH processes connecting to this host
157
+ execSync(`pkill -f "ssh.*${host}" || true`, { timeout: 5000 });
158
+ } catch {
159
+ // Ignore
160
+ }
161
+ }
162
+
163
+ /**
164
+ * Check if server is responsive
165
+ */
166
+ export async function pingServer(
167
+ host: string,
168
+ user: string = "frappe",
169
+ ): Promise<boolean> {
170
+ try {
171
+ execSync(
172
+ `ssh -o BatchMode=yes -o ConnectTimeout=5 ${user}@${host} 'echo ok'`,
173
+ { timeout: 10_000 },
174
+ );
175
+ return true;
176
+ } catch {
177
+ return false;
178
+ }
179
+ }
180
+
181
+ /**
182
+ * Get PM2 status with hang protection
183
+ */
184
+ export async function getPM2Status(
185
+ host: string,
186
+ pm2Path?: string,
187
+ ): Promise<SSHResult> {
188
+ const pm2Cmd = pm2Path || "pm2";
189
+ const command = `PM2_HOME=/home/frappe/.pm2 ${pm2Cmd} status`;
190
+
191
+ return sshWithRecovery(
192
+ {
193
+ host,
194
+ timeout: 30_000, // Status should be fast
195
+ maxRetries: 1,
196
+ },
197
+ command,
198
+ );
199
+ }
200
+
201
+ /**
202
+ * Restart PM2 process with hang protection
203
+ */
204
+ export async function pm2Restart(
205
+ host: string,
206
+ app: string,
207
+ ): Promise<SSHResult> {
208
+ const command = `PM2_HOME=/home/frappe/.pm2 pm2 restart ${app}`;
209
+
210
+ return sshWithRecovery(
211
+ {
212
+ host,
213
+ timeout: 180_000, // 3 min for restart
214
+ maxRetries: 2,
215
+ },
216
+ command,
217
+ );
218
+ }
219
+
220
+ /**
221
+ * Execute arbitrary command with hang protection
222
+ */
223
+ export async function safeSSHCommand(
224
+ host: string,
225
+ command: string,
226
+ options: { timeout?: number; maxRetries?: number } = {},
227
+ ): Promise<SSHResult> {
228
+ return sshWithRecovery(
229
+ {
230
+ host,
231
+ timeout: options.timeout ?? 120_000,
232
+ maxRetries: options.maxRetries ?? 2,
233
+ },
234
+ command,
235
+ );
236
+ }
237
+
238
+ // --- Helper for promise-based exec with timeout ---
239
+
240
+ interface ExecResult {
241
+ exitCode: number;
242
+ stdout: string;
243
+ stderr: string;
244
+ }
245
+
246
+ function execAsync(command: string, timeoutMs: number): Promise<ExecResult> {
247
+ return new Promise((resolve, reject) => {
248
+ const proc = exec(command, { encoding: "utf-8" }, (error, stdout, stderr) => {
249
+ if (error) {
250
+ reject(error);
251
+ } else {
252
+ resolve({ exitCode: 0, stdout, stderr });
253
+ }
254
+ });
255
+
256
+ const timer = setAsyncTimeout(() => {
257
+ // Kill the process tree
258
+ try {
259
+ proc.kill("SIGKILL");
260
+ } catch {
261
+ // Process already dead
262
+ }
263
+ reject(new Error(`Command timed out after ${timeoutMs}ms`));
264
+ }, timeoutMs);
265
+
266
+ proc.on("exit", (code) => {
267
+ clearTimeout(timer);
268
+ resolve({
269
+ exitCode: code ?? 0,
270
+ stdout: (proc.stdout || "").toString(),
271
+ stderr: (proc.stderr || "").toString(),
272
+ });
273
+ });
274
+
275
+ proc.on("error", (err) => {
276
+ clearTimeout(timer);
277
+ reject(err);
278
+ });
279
+ });
280
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-harness-runtime",
3
- "version": "1.1.18",
3
+ "version": "1.1.26",
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.18",
3
+ "version": "1.1.26",
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.18",
3
+ "version": "1.1.26",
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.18",
3
+ "version": "1.1.26",
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.18",
3
+ "version": "1.1.26",
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.18",
3
+ "version": "1.1.26",
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.18",
3
+ "version": "1.1.26",
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.18",
3
+ "version": "1.1.26",
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.18",
3
+ "version": "1.1.26",
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.18",
3
+ "version": "1.1.26",
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.18",
3
+ "version": "1.1.26",
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.18",
3
+ "version": "1.1.26",
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.18",
3
+ "version": "1.1.26",
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.18",
3
+ "version": "1.1.26",
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.18",
3
+ "version": "1.1.26",
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.18",
3
+ "version": "1.1.26",
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.18",
3
+ "version": "1.1.26",
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.18",
3
+ "version": "1.1.26",
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.18",
3
+ "version": "1.1.26",
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",