pi-harness-runtime 1.1.366 → 1.1.367
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.
- package/index.ts +12 -0
- package/package.json +1 -1
- package/packages/a2a-adapter/package.json +1 -1
- package/packages/agent-policy/package.json +1 -1
- package/packages/architecture-generator/package.json +1 -1
- package/packages/auth/package.json +1 -1
- package/packages/autonomous-refactor/package.json +1 -1
- package/packages/autonomous-runtime/package.json +1 -1
- package/packages/cache-strategy/package.json +1 -1
- package/packages/capability-registry/package.json +1 -1
- package/packages/checkpoint/package.json +1 -1
- package/packages/cli-plugin-sdk/package.json +1 -1
- package/packages/clipboard/package.json +1 -1
- package/packages/clipboard-plugin/package.json +1 -1
- package/packages/code-generation/package.json +1 -1
- package/packages/code-review/package.json +1 -1
- package/packages/codex-adapter/package.json +1 -1
- package/packages/codex-watcher/package.json +1 -1
- package/packages/config-capture/package.json +1 -1
- package/packages/connection-runtime/package.json +1 -1
- package/packages/context-compiler/package.json +1 -1
- package/packages/context-discovery/package.json +1 -1
- package/packages/context-manager/package.json +1 -1
- package/packages/contracts/dist/workspace-env.d.ts +46 -0
- package/packages/contracts/dist/workspace-env.js +231 -0
- package/packages/contracts/package.json +1 -1
- package/packages/contracts/src/workspace-env.ts +278 -0
- package/packages/cookie-sanitizer/package.json +1 -1
- package/packages/cost-optimizer/package.json +1 -1
- package/packages/dependency-analyzer/package.json +1 -1
- package/packages/django-plugin/package.json +1 -1
- package/packages/doc-generator/package.json +1 -1
- package/packages/durable-review/package.json +1 -1
- package/packages/e2e-tester/package.json +1 -1
- package/packages/evaluation-engine/package.json +1 -1
- package/packages/evaluation-runner/package.json +1 -1
- package/packages/event-bus/package.json +1 -1
- package/packages/event-sink/package.json +1 -1
- package/packages/event-store/package.json +1 -1
- package/packages/experience-replay/package.json +1 -1
- package/packages/feedback-collector/package.json +1 -1
- package/packages/file-copy-helper/package.json +1 -1
- package/packages/framework-detector/package.json +1 -1
- package/packages/framework-plugin-sdk/package.json +1 -1
- package/packages/frappe-plugin/package.json +1 -1
- package/packages/generic-web-plugin/package.json +1 -1
- package/packages/health-monitor/package.json +1 -1
- package/packages/intent-analyzer/package.json +1 -1
- package/packages/jev-judge/package.json +1 -1
- package/packages/knowledge-graph/package.json +1 -1
- package/packages/knowledge-retrieval/package.json +1 -1
- package/packages/laravel-plugin/package.json +1 -1
- package/packages/learning-engine/package.json +1 -1
- package/packages/mcp-adapter/package.json +1 -1
- package/packages/memory-engine/package.json +1 -1
- package/packages/milestone-manager/package.json +1 -1
- package/packages/model-registry/package.json +1 -1
- package/packages/nextjs-plugin/package.json +1 -1
- package/packages/notification/package.json +1 -1
- package/packages/observability/package.json +1 -1
- package/packages/okf-indexer/package.json +1 -1
- package/packages/paperclip-integration/package.json +1 -1
- package/packages/performance-optimizer/package.json +1 -1
- package/packages/permission-mode/package.json +1 -1
- package/packages/privilege-broker/package.json +1 -1
- package/packages/project-analyzer/package.json +1 -1
- package/packages/project-bootstrap/package.json +1 -1
- package/packages/projection-engine/package.json +1 -1
- package/packages/prompt-compiler/package.json +1 -1
- package/packages/prompt-versioning/package.json +1 -1
- package/packages/provider-adapter-sdk/package.json +1 -1
- package/packages/provider-router/package.json +1 -1
- package/packages/provider-selector/package.json +1 -1
- package/packages/providers/package.json +1 -1
- package/packages/qdrant-skills/package.json +1 -1
- package/packages/quota-manager/package.json +1 -1
- package/packages/rate-limiter/package.json +1 -1
- package/packages/react-vite-plugin/package.json +1 -1
- package/packages/relay/package.json +1 -1
- package/packages/release-manager/package.json +1 -1
- package/packages/requirement-compiler/package.json +1 -1
- package/packages/runtime/package.json +1 -1
- package/packages/scheduler/package.json +1 -1
- package/packages/scheduler-adapter/package.json +1 -1
- package/packages/session/package.json +1 -1
- package/packages/session-api/package.json +1 -1
- package/packages/session-export/package.json +1 -1
- package/packages/shared-context/package.json +1 -1
- package/packages/skill-mcp-client/package.json +1 -1
- package/packages/skill-registry/package.json +1 -1
- package/packages/skills/package.json +1 -1
- package/packages/sprint-planner/package.json +1 -1
- package/packages/subscription-engine/package.json +1 -1
- package/packages/task-compiler/package.json +1 -1
- package/packages/telegram/package.json +1 -1
- package/packages/tencentdb-memory/package.json +1 -1
- package/packages/tencentdb-sync/package.json +1 -1
- package/packages/test-data-generator/package.json +1 -1
- package/packages/test-generator/package.json +1 -1
- package/packages/todo-bd-sync/package.json +1 -1
- package/packages/token-estimation/package.json +1 -1
- package/packages/token-optimizer/package.json +1 -1
- package/packages/trajectory/package.json +1 -1
- package/packages/tui/package.json +1 -1
- package/packages/types/package.json +1 -1
- package/packages/voice-api/package.json +1 -1
- package/packages/webmcp-tester/package.json +1 -1
- package/packages/wiki/package.json +1 -1
- package/packages/workflow-events/package.json +1 -1
- package/packages/workspace-scanner/package.json +1 -1
- package/packages/worktree/package.json +1 -1
- package/packages/write-review/package.json +1 -1
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Workspace Environment Detector
|
|
3
|
+
*
|
|
4
|
+
* Detects if the workspace is a development environment by checking:
|
|
5
|
+
* 1. .env file existence and NODE_ENV value
|
|
6
|
+
* 2. package.json "dev" script presence
|
|
7
|
+
* 3. .env.development or .env.local files
|
|
8
|
+
*
|
|
9
|
+
* Stores detected environment in SQLite for agent reference.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { DatabaseSync } from "node:sqlite";
|
|
13
|
+
import { existsSync, readFileSync } from "fs";
|
|
14
|
+
import { join, dirname } from "path";
|
|
15
|
+
import { fileURLToPath } from "url";
|
|
16
|
+
|
|
17
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
18
|
+
const STORE_DIR = join(process.env.HOME || "/home/frappe", ".pi-harness-runtime");
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Ensure store directory exists
|
|
22
|
+
*/
|
|
23
|
+
function ensureStoreDir(): void {
|
|
24
|
+
if (!existsSync(STORE_DIR)) {
|
|
25
|
+
// mkdirSync is not available in all contexts, use fs promises or exec
|
|
26
|
+
import("fs").then((fs) => fs.mkdirSync(STORE_DIR, { recursive: true }));
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Get workspace database path
|
|
32
|
+
*/
|
|
33
|
+
function getDbPath(): string {
|
|
34
|
+
ensureStoreDir();
|
|
35
|
+
return join(STORE_DIR, "workspace-env.sqlite");
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Initialize workspace environment database
|
|
40
|
+
*/
|
|
41
|
+
function initDatabase(): DatabaseSync {
|
|
42
|
+
const db = new DatabaseSync(getDbPath());
|
|
43
|
+
db.exec(`
|
|
44
|
+
CREATE TABLE IF NOT EXISTS workspace_env (
|
|
45
|
+
workspace_path TEXT PRIMARY KEY,
|
|
46
|
+
is_dev_env INTEGER NOT NULL DEFAULT 0,
|
|
47
|
+
has_dev_script INTEGER NOT NULL DEFAULT 0,
|
|
48
|
+
node_env TEXT,
|
|
49
|
+
has_env_file INTEGER NOT NULL DEFAULT 0,
|
|
50
|
+
ram_gb REAL,
|
|
51
|
+
detected_at INTEGER NOT NULL,
|
|
52
|
+
updated_at INTEGER NOT NULL
|
|
53
|
+
)
|
|
54
|
+
`);
|
|
55
|
+
return db;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Detect RAM in GB
|
|
60
|
+
*/
|
|
61
|
+
function detectRamGb(): number | null {
|
|
62
|
+
try {
|
|
63
|
+
if (process.platform === "linux") {
|
|
64
|
+
const meminfo = readFileSync("/proc/meminfo", "utf8");
|
|
65
|
+
const match = meminfo.match(/MemTotal:\\s+(\\d+)\\s+kB/);
|
|
66
|
+
if (match) {
|
|
67
|
+
return Math.round((parseInt(match[1], 10) / 1024 / 1024) * 10) / 10;
|
|
68
|
+
}
|
|
69
|
+
} else if (process.platform === "darwin") {
|
|
70
|
+
const out = require("child_process").execSync("sysctl hw.memsize", { encoding: "utf8" });
|
|
71
|
+
const match = out.match(/hw\\.memsize:\\s+(\\d+)/);
|
|
72
|
+
if (match) {
|
|
73
|
+
return Math.round((parseInt(match[1], 10) / 1024 / 1024 / 1024) * 10) / 10;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
} catch {
|
|
77
|
+
// Fallback: return null
|
|
78
|
+
}
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Detect if workspace is a dev environment
|
|
84
|
+
*/
|
|
85
|
+
export interface WorkspaceEnvResult {
|
|
86
|
+
workspacePath: string;
|
|
87
|
+
isDevEnv: boolean;
|
|
88
|
+
hasDevScript: boolean;
|
|
89
|
+
nodeEnv: string | null;
|
|
90
|
+
hasEnvFile: boolean;
|
|
91
|
+
ramGb: number | null;
|
|
92
|
+
detectedAt: number;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Detect and store workspace environment
|
|
97
|
+
*/
|
|
98
|
+
export function detectWorkspaceEnv(workspacePath: string): WorkspaceEnvResult {
|
|
99
|
+
const now = Date.now();
|
|
100
|
+
const ramGb = detectRamGb();
|
|
101
|
+
|
|
102
|
+
// Check for .env files
|
|
103
|
+
const hasEnvFile = existsSync(join(workspacePath, ".env")) ||
|
|
104
|
+
existsSync(join(workspacePath, ".env.development")) ||
|
|
105
|
+
existsSync(join(workspacePath, ".env.local")) ||
|
|
106
|
+
existsSync(join(workspacePath, ".env.dev"));
|
|
107
|
+
|
|
108
|
+
// Read NODE_ENV from .env file if present
|
|
109
|
+
let nodeEnv: string | null = null;
|
|
110
|
+
const envFile = join(workspacePath, ".env");
|
|
111
|
+
if (existsSync(envFile)) {
|
|
112
|
+
try {
|
|
113
|
+
const envContent = readFileSync(envFile, "utf8");
|
|
114
|
+
const match = envContent.match(/NODE_ENV=(.+)/);
|
|
115
|
+
if (match) {
|
|
116
|
+
nodeEnv = match[1].trim().replace(/['"]/g, "");
|
|
117
|
+
}
|
|
118
|
+
} catch {
|
|
119
|
+
// Ignore read errors
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// Check for dev script in package.json
|
|
124
|
+
let hasDevScript = false;
|
|
125
|
+
const pkgJsonPath = join(workspacePath, "package.json");
|
|
126
|
+
if (existsSync(pkgJsonPath)) {
|
|
127
|
+
try {
|
|
128
|
+
const pkg = JSON.parse(readFileSync(pkgJsonPath, "utf8"));
|
|
129
|
+
hasDevScript = !!(pkg.scripts && (pkg.scripts.dev || pkg.scripts.development));
|
|
130
|
+
} catch {
|
|
131
|
+
// Ignore parse errors
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// Determine if this is a dev environment
|
|
136
|
+
// Dev env if: has .env file OR has dev script OR NODE_ENV=development
|
|
137
|
+
const isDevEnv = hasEnvFile || hasDevScript || nodeEnv === "development" || nodeEnv === "dev";
|
|
138
|
+
|
|
139
|
+
// Store in SQLite
|
|
140
|
+
const db = initDatabase();
|
|
141
|
+
db.prepare(`
|
|
142
|
+
INSERT OR REPLACE INTO workspace_env
|
|
143
|
+
(workspace_path, is_dev_env, has_dev_script, node_env, has_env_file, ram_gb, detected_at, updated_at)
|
|
144
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
145
|
+
`).run(workspacePath, isDevEnv ? 1 : 0, hasDevScript ? 1 : 0, nodeEnv, hasEnvFile ? 1 : 0, ramGb, now, now);
|
|
146
|
+
|
|
147
|
+
db.close();
|
|
148
|
+
|
|
149
|
+
return {
|
|
150
|
+
workspacePath,
|
|
151
|
+
isDevEnv,
|
|
152
|
+
hasDevScript,
|
|
153
|
+
nodeEnv,
|
|
154
|
+
hasEnvFile,
|
|
155
|
+
ramGb,
|
|
156
|
+
detectedAt: now,
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Load cached workspace environment
|
|
162
|
+
*/
|
|
163
|
+
export function loadWorkspaceEnv(workspacePath: string): WorkspaceEnvResult | null {
|
|
164
|
+
const db = initDatabase();
|
|
165
|
+
const row = db.prepare("SELECT * FROM workspace_env WHERE workspace_path = ?").get(workspacePath) as {
|
|
166
|
+
workspace_path: string;
|
|
167
|
+
is_dev_env: number;
|
|
168
|
+
has_dev_script: number;
|
|
169
|
+
node_env: string | null;
|
|
170
|
+
has_env_file: number;
|
|
171
|
+
ram_gb: number | null;
|
|
172
|
+
detected_at: number;
|
|
173
|
+
} | undefined;
|
|
174
|
+
db.close();
|
|
175
|
+
|
|
176
|
+
if (!row) return null;
|
|
177
|
+
|
|
178
|
+
return {
|
|
179
|
+
workspacePath: row.workspace_path,
|
|
180
|
+
isDevEnv: row.is_dev_env === 1,
|
|
181
|
+
hasDevScript: row.has_dev_script === 1,
|
|
182
|
+
nodeEnv: row.node_env,
|
|
183
|
+
hasEnvFile: row.has_env_file === 1,
|
|
184
|
+
ramGb: row.ram_gb,
|
|
185
|
+
detectedAt: row.detected_at,
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Get or detect workspace environment
|
|
191
|
+
*/
|
|
192
|
+
export function getWorkspaceEnv(workspacePath: string): WorkspaceEnvResult {
|
|
193
|
+
// Try to load cached result first
|
|
194
|
+
const cached = loadWorkspaceEnv(workspacePath);
|
|
195
|
+
if (cached) {
|
|
196
|
+
// Check if cache is recent (within 1 hour)
|
|
197
|
+
const ageMs = Date.now() - cached.detectedAt;
|
|
198
|
+
if (ageMs < 60 * 60 * 1000) {
|
|
199
|
+
return cached;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
// Detect fresh
|
|
203
|
+
return detectWorkspaceEnv(workspacePath);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* Check if agent should prefer dev mode (no build)
|
|
208
|
+
*/
|
|
209
|
+
export function shouldUseDevMode(workspacePath: string): {
|
|
210
|
+
preferDev: boolean;
|
|
211
|
+
reason: string;
|
|
212
|
+
ramGb: number | null;
|
|
213
|
+
} {
|
|
214
|
+
const env = getWorkspaceEnv(workspacePath);
|
|
215
|
+
|
|
216
|
+
// Low RAM threshold
|
|
217
|
+
const LOW_RAM_GB = 16;
|
|
218
|
+
|
|
219
|
+
if (!env.isDevEnv) {
|
|
220
|
+
return {
|
|
221
|
+
preferDev: false,
|
|
222
|
+
reason: "Not detected as dev environment",
|
|
223
|
+
ramGb: env.ramGb,
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
if (env.ramGb !== null && env.ramGb < LOW_RAM_GB) {
|
|
228
|
+
return {
|
|
229
|
+
preferDev: true,
|
|
230
|
+
reason: `Low RAM (${env.ramGb}GB < ${LOW_RAM_GB}GB) - avoid parallel build + dev`,
|
|
231
|
+
ramGb: env.ramGb,
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
if (env.hasDevScript) {
|
|
236
|
+
return {
|
|
237
|
+
preferDev: true,
|
|
238
|
+
reason: `Dev script detected - hot reload available`,
|
|
239
|
+
ramGb: env.ramGb,
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
return {
|
|
244
|
+
preferDev: false,
|
|
245
|
+
reason: "Dev environment but no dev script found",
|
|
246
|
+
ramGb: env.ramGb,
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* Format workspace env as agent-readable message
|
|
252
|
+
*/
|
|
253
|
+
export function formatEnvForAgent(workspacePath: string): string {
|
|
254
|
+
const env = shouldUseDevMode(workspacePath);
|
|
255
|
+
const details = getWorkspaceEnv(workspacePath);
|
|
256
|
+
|
|
257
|
+
let message = `[Workspace Environment]\n`;
|
|
258
|
+
message += `- Path: ${workspacePath}\n`;
|
|
259
|
+
message += `- Detected: ${details.isDevEnv ? "Development" : "Production/Unknown"}\n`;
|
|
260
|
+
message += `- Has dev script: ${details.hasDevScript ? "Yes" : "No"}\n`;
|
|
261
|
+
message += `- NODE_ENV: ${details.nodeEnv || "not set"}\n`;
|
|
262
|
+
message += `- Has .env file: ${details.hasEnvFile ? "Yes" : "No"}\n`;
|
|
263
|
+
message += `- RAM: ${details.ramGb ? `${details.ramGb}GB` : "unknown"}\n`;
|
|
264
|
+
message += `\n`;
|
|
265
|
+
|
|
266
|
+
if (env.preferDev) {
|
|
267
|
+
message += `RECOMMENDATION: Use \`dev\` mode (no build needed)\n`;
|
|
268
|
+
message += `Reason: ${env.reason}\n`;
|
|
269
|
+
message += `→ Run: \`bun run dev\` (or \`npm run dev\`)\n`;
|
|
270
|
+
message += `→ DON'T: Run \`build\` unless explicitly requested\n`;
|
|
271
|
+
} else {
|
|
272
|
+
message += `RECOMMENDATION: Build may be needed\n`;
|
|
273
|
+
message += `Reason: ${env.reason}\n`;
|
|
274
|
+
message += `→ Use: \`bun run build\` before running\n`;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
return message;
|
|
278
|
+
}
|