pi-harness-runtime 1.1.366 → 1.1.368
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/AGENTS.md +33 -0
- 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
package/AGENTS.md
CHANGED
|
@@ -490,3 +490,36 @@ bun run start # ✅ Correct - run compiled
|
|
|
490
490
|
bun run build && bun run test # CI pipeline
|
|
491
491
|
bun run build && bun run start # Server deployment
|
|
492
492
|
```
|
|
493
|
+
|
|
494
|
+
### 14. Workspace Environment Auto-Detection
|
|
495
|
+
|
|
496
|
+
**At session start, the harness auto-detects:**
|
|
497
|
+
- `.env` file presence → Dev environment
|
|
498
|
+
- `package.json` `dev` script → Hot reload available
|
|
499
|
+
- `NODE_ENV` value → development/production
|
|
500
|
+
- System RAM → Low RAM warning (<16GB)
|
|
501
|
+
|
|
502
|
+
**This info is stored in:**
|
|
503
|
+
```
|
|
504
|
+
~/.pi-harness-runtime/workspace-env.sqlite
|
|
505
|
+
```
|
|
506
|
+
|
|
507
|
+
**Agent should check workspace environment BEFORE running build commands:**
|
|
508
|
+
|
|
509
|
+
```
|
|
510
|
+
On Dev PC with hot reload:
|
|
511
|
+
→ DON'T: bun run build (unless explicitly asked)
|
|
512
|
+
→ DO: bun run dev (compiles on-demand, saves RAM)
|
|
513
|
+
|
|
514
|
+
On CI/Production:
|
|
515
|
+
→ DO: bun run build (always build first)
|
|
516
|
+
```
|
|
517
|
+
|
|
518
|
+
**Decision flow:**
|
|
519
|
+
```
|
|
520
|
+
Is this a dev workspace? (.env, dev script exists?)
|
|
521
|
+
└─ YES + Has dev script?
|
|
522
|
+
└─ YES → Use bun run dev (no build needed)
|
|
523
|
+
└─ NO → May need build
|
|
524
|
+
└─ NO → Build required (production/server)
|
|
525
|
+
```
|
package/index.ts
CHANGED
|
@@ -138,6 +138,8 @@ const sharedState = {
|
|
|
138
138
|
pqController: null as any,
|
|
139
139
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
140
140
|
delegationHarness: null as any,
|
|
141
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
142
|
+
workspaceEnvMessage: null as string | null,
|
|
141
143
|
};
|
|
142
144
|
|
|
143
145
|
async function initAutoContinue(pi: ExtensionAPI): Promise<void> {
|
|
@@ -386,6 +388,16 @@ async function initAutoContinue(pi: ExtensionAPI): Promise<void> {
|
|
|
386
388
|
_piSessionCwd = realpathSync(process.cwd());
|
|
387
389
|
logToFile("[codex-trigger]", "Pi session cwd captured:", _piSessionCwd);
|
|
388
390
|
|
|
391
|
+
// --- Detect workspace environment ---
|
|
392
|
+
try {
|
|
393
|
+
const { formatEnvForAgent } = await import("./packages/contracts/dist/workspace-env.js");
|
|
394
|
+
const envMessage = formatEnvForAgent(_piSessionCwd);
|
|
395
|
+
logToFile("[WorkspaceEnv]", envMessage);
|
|
396
|
+
sharedState.workspaceEnvMessage = envMessage;
|
|
397
|
+
} catch (e) {
|
|
398
|
+
logToFile("[WorkspaceEnv]", "Detection failed:", String(e));
|
|
399
|
+
}
|
|
400
|
+
|
|
389
401
|
// --- Drain pending greeting when Pi becomes active ---
|
|
390
402
|
if (codexSessionState.pendingGreeting) {
|
|
391
403
|
const pg = codexSessionState.pendingGreeting;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pi-harness/capability-registry",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.368",
|
|
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",
|
|
@@ -0,0 +1,46 @@
|
|
|
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
|
+
* Detect if workspace is a dev environment
|
|
13
|
+
*/
|
|
14
|
+
export interface WorkspaceEnvResult {
|
|
15
|
+
workspacePath: string;
|
|
16
|
+
isDevEnv: boolean;
|
|
17
|
+
hasDevScript: boolean;
|
|
18
|
+
nodeEnv: string | null;
|
|
19
|
+
hasEnvFile: boolean;
|
|
20
|
+
ramGb: number | null;
|
|
21
|
+
detectedAt: number;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Detect and store workspace environment
|
|
25
|
+
*/
|
|
26
|
+
export declare function detectWorkspaceEnv(workspacePath: string): WorkspaceEnvResult;
|
|
27
|
+
/**
|
|
28
|
+
* Load cached workspace environment
|
|
29
|
+
*/
|
|
30
|
+
export declare function loadWorkspaceEnv(workspacePath: string): WorkspaceEnvResult | null;
|
|
31
|
+
/**
|
|
32
|
+
* Get or detect workspace environment
|
|
33
|
+
*/
|
|
34
|
+
export declare function getWorkspaceEnv(workspacePath: string): WorkspaceEnvResult;
|
|
35
|
+
/**
|
|
36
|
+
* Check if agent should prefer dev mode (no build)
|
|
37
|
+
*/
|
|
38
|
+
export declare function shouldUseDevMode(workspacePath: string): {
|
|
39
|
+
preferDev: boolean;
|
|
40
|
+
reason: string;
|
|
41
|
+
ramGb: number | null;
|
|
42
|
+
};
|
|
43
|
+
/**
|
|
44
|
+
* Format workspace env as agent-readable message
|
|
45
|
+
*/
|
|
46
|
+
export declare function formatEnvForAgent(workspacePath: string): string;
|
|
@@ -0,0 +1,231 @@
|
|
|
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
|
+
import { DatabaseSync } from "node:sqlite";
|
|
12
|
+
import { existsSync, readFileSync } from "fs";
|
|
13
|
+
import { join, dirname } from "path";
|
|
14
|
+
import { fileURLToPath } from "url";
|
|
15
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
16
|
+
const STORE_DIR = join(process.env.HOME || "/home/frappe", ".pi-harness-runtime");
|
|
17
|
+
/**
|
|
18
|
+
* Ensure store directory exists
|
|
19
|
+
*/
|
|
20
|
+
function ensureStoreDir() {
|
|
21
|
+
if (!existsSync(STORE_DIR)) {
|
|
22
|
+
// mkdirSync is not available in all contexts, use fs promises or exec
|
|
23
|
+
import("fs").then((fs) => fs.mkdirSync(STORE_DIR, { recursive: true }));
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Get workspace database path
|
|
28
|
+
*/
|
|
29
|
+
function getDbPath() {
|
|
30
|
+
ensureStoreDir();
|
|
31
|
+
return join(STORE_DIR, "workspace-env.sqlite");
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Initialize workspace environment database
|
|
35
|
+
*/
|
|
36
|
+
function initDatabase() {
|
|
37
|
+
const db = new DatabaseSync(getDbPath());
|
|
38
|
+
db.exec(`
|
|
39
|
+
CREATE TABLE IF NOT EXISTS workspace_env (
|
|
40
|
+
workspace_path TEXT PRIMARY KEY,
|
|
41
|
+
is_dev_env INTEGER NOT NULL DEFAULT 0,
|
|
42
|
+
has_dev_script INTEGER NOT NULL DEFAULT 0,
|
|
43
|
+
node_env TEXT,
|
|
44
|
+
has_env_file INTEGER NOT NULL DEFAULT 0,
|
|
45
|
+
ram_gb REAL,
|
|
46
|
+
detected_at INTEGER NOT NULL,
|
|
47
|
+
updated_at INTEGER NOT NULL
|
|
48
|
+
)
|
|
49
|
+
`);
|
|
50
|
+
return db;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Detect RAM in GB
|
|
54
|
+
*/
|
|
55
|
+
function detectRamGb() {
|
|
56
|
+
try {
|
|
57
|
+
if (process.platform === "linux") {
|
|
58
|
+
const meminfo = readFileSync("/proc/meminfo", "utf8");
|
|
59
|
+
const match = meminfo.match(/MemTotal:\\s+(\\d+)\\s+kB/);
|
|
60
|
+
if (match) {
|
|
61
|
+
return Math.round((parseInt(match[1], 10) / 1024 / 1024) * 10) / 10;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
else if (process.platform === "darwin") {
|
|
65
|
+
const out = require("child_process").execSync("sysctl hw.memsize", { encoding: "utf8" });
|
|
66
|
+
const match = out.match(/hw\\.memsize:\\s+(\\d+)/);
|
|
67
|
+
if (match) {
|
|
68
|
+
return Math.round((parseInt(match[1], 10) / 1024 / 1024 / 1024) * 10) / 10;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
catch {
|
|
73
|
+
// Fallback: return null
|
|
74
|
+
}
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Detect and store workspace environment
|
|
79
|
+
*/
|
|
80
|
+
export function detectWorkspaceEnv(workspacePath) {
|
|
81
|
+
const now = Date.now();
|
|
82
|
+
const ramGb = detectRamGb();
|
|
83
|
+
// Check for .env files
|
|
84
|
+
const hasEnvFile = existsSync(join(workspacePath, ".env")) ||
|
|
85
|
+
existsSync(join(workspacePath, ".env.development")) ||
|
|
86
|
+
existsSync(join(workspacePath, ".env.local")) ||
|
|
87
|
+
existsSync(join(workspacePath, ".env.dev"));
|
|
88
|
+
// Read NODE_ENV from .env file if present
|
|
89
|
+
let nodeEnv = null;
|
|
90
|
+
const envFile = join(workspacePath, ".env");
|
|
91
|
+
if (existsSync(envFile)) {
|
|
92
|
+
try {
|
|
93
|
+
const envContent = readFileSync(envFile, "utf8");
|
|
94
|
+
const match = envContent.match(/NODE_ENV=(.+)/);
|
|
95
|
+
if (match) {
|
|
96
|
+
nodeEnv = match[1].trim().replace(/['"]/g, "");
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
catch {
|
|
100
|
+
// Ignore read errors
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
// Check for dev script in package.json
|
|
104
|
+
let hasDevScript = false;
|
|
105
|
+
const pkgJsonPath = join(workspacePath, "package.json");
|
|
106
|
+
if (existsSync(pkgJsonPath)) {
|
|
107
|
+
try {
|
|
108
|
+
const pkg = JSON.parse(readFileSync(pkgJsonPath, "utf8"));
|
|
109
|
+
hasDevScript = !!(pkg.scripts && (pkg.scripts.dev || pkg.scripts.development));
|
|
110
|
+
}
|
|
111
|
+
catch {
|
|
112
|
+
// Ignore parse errors
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
// Determine if this is a dev environment
|
|
116
|
+
// Dev env if: has .env file OR has dev script OR NODE_ENV=development
|
|
117
|
+
const isDevEnv = hasEnvFile || hasDevScript || nodeEnv === "development" || nodeEnv === "dev";
|
|
118
|
+
// Store in SQLite
|
|
119
|
+
const db = initDatabase();
|
|
120
|
+
db.prepare(`
|
|
121
|
+
INSERT OR REPLACE INTO workspace_env
|
|
122
|
+
(workspace_path, is_dev_env, has_dev_script, node_env, has_env_file, ram_gb, detected_at, updated_at)
|
|
123
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
124
|
+
`).run(workspacePath, isDevEnv ? 1 : 0, hasDevScript ? 1 : 0, nodeEnv, hasEnvFile ? 1 : 0, ramGb, now, now);
|
|
125
|
+
db.close();
|
|
126
|
+
return {
|
|
127
|
+
workspacePath,
|
|
128
|
+
isDevEnv,
|
|
129
|
+
hasDevScript,
|
|
130
|
+
nodeEnv,
|
|
131
|
+
hasEnvFile,
|
|
132
|
+
ramGb,
|
|
133
|
+
detectedAt: now,
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Load cached workspace environment
|
|
138
|
+
*/
|
|
139
|
+
export function loadWorkspaceEnv(workspacePath) {
|
|
140
|
+
const db = initDatabase();
|
|
141
|
+
const row = db.prepare("SELECT * FROM workspace_env WHERE workspace_path = ?").get(workspacePath);
|
|
142
|
+
db.close();
|
|
143
|
+
if (!row)
|
|
144
|
+
return null;
|
|
145
|
+
return {
|
|
146
|
+
workspacePath: row.workspace_path,
|
|
147
|
+
isDevEnv: row.is_dev_env === 1,
|
|
148
|
+
hasDevScript: row.has_dev_script === 1,
|
|
149
|
+
nodeEnv: row.node_env,
|
|
150
|
+
hasEnvFile: row.has_env_file === 1,
|
|
151
|
+
ramGb: row.ram_gb,
|
|
152
|
+
detectedAt: row.detected_at,
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Get or detect workspace environment
|
|
157
|
+
*/
|
|
158
|
+
export function getWorkspaceEnv(workspacePath) {
|
|
159
|
+
// Try to load cached result first
|
|
160
|
+
const cached = loadWorkspaceEnv(workspacePath);
|
|
161
|
+
if (cached) {
|
|
162
|
+
// Check if cache is recent (within 1 hour)
|
|
163
|
+
const ageMs = Date.now() - cached.detectedAt;
|
|
164
|
+
if (ageMs < 60 * 60 * 1000) {
|
|
165
|
+
return cached;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
// Detect fresh
|
|
169
|
+
return detectWorkspaceEnv(workspacePath);
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Check if agent should prefer dev mode (no build)
|
|
173
|
+
*/
|
|
174
|
+
export function shouldUseDevMode(workspacePath) {
|
|
175
|
+
const env = getWorkspaceEnv(workspacePath);
|
|
176
|
+
// Low RAM threshold
|
|
177
|
+
const LOW_RAM_GB = 16;
|
|
178
|
+
if (!env.isDevEnv) {
|
|
179
|
+
return {
|
|
180
|
+
preferDev: false,
|
|
181
|
+
reason: "Not detected as dev environment",
|
|
182
|
+
ramGb: env.ramGb,
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
if (env.ramGb !== null && env.ramGb < LOW_RAM_GB) {
|
|
186
|
+
return {
|
|
187
|
+
preferDev: true,
|
|
188
|
+
reason: `Low RAM (${env.ramGb}GB < ${LOW_RAM_GB}GB) - avoid parallel build + dev`,
|
|
189
|
+
ramGb: env.ramGb,
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
if (env.hasDevScript) {
|
|
193
|
+
return {
|
|
194
|
+
preferDev: true,
|
|
195
|
+
reason: `Dev script detected - hot reload available`,
|
|
196
|
+
ramGb: env.ramGb,
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
return {
|
|
200
|
+
preferDev: false,
|
|
201
|
+
reason: "Dev environment but no dev script found",
|
|
202
|
+
ramGb: env.ramGb,
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Format workspace env as agent-readable message
|
|
207
|
+
*/
|
|
208
|
+
export function formatEnvForAgent(workspacePath) {
|
|
209
|
+
const env = shouldUseDevMode(workspacePath);
|
|
210
|
+
const details = getWorkspaceEnv(workspacePath);
|
|
211
|
+
let message = `[Workspace Environment]\n`;
|
|
212
|
+
message += `- Path: ${workspacePath}\n`;
|
|
213
|
+
message += `- Detected: ${details.isDevEnv ? "Development" : "Production/Unknown"}\n`;
|
|
214
|
+
message += `- Has dev script: ${details.hasDevScript ? "Yes" : "No"}\n`;
|
|
215
|
+
message += `- NODE_ENV: ${details.nodeEnv || "not set"}\n`;
|
|
216
|
+
message += `- Has .env file: ${details.hasEnvFile ? "Yes" : "No"}\n`;
|
|
217
|
+
message += `- RAM: ${details.ramGb ? `${details.ramGb}GB` : "unknown"}\n`;
|
|
218
|
+
message += `\n`;
|
|
219
|
+
if (env.preferDev) {
|
|
220
|
+
message += `RECOMMENDATION: Use \`dev\` mode (no build needed)\n`;
|
|
221
|
+
message += `Reason: ${env.reason}\n`;
|
|
222
|
+
message += `→ Run: \`bun run dev\` (or \`npm run dev\`)\n`;
|
|
223
|
+
message += `→ DON'T: Run \`build\` unless explicitly requested\n`;
|
|
224
|
+
}
|
|
225
|
+
else {
|
|
226
|
+
message += `RECOMMENDATION: Build may be needed\n`;
|
|
227
|
+
message += `Reason: ${env.reason}\n`;
|
|
228
|
+
message += `→ Use: \`bun run build\` before running\n`;
|
|
229
|
+
}
|
|
230
|
+
return message;
|
|
231
|
+
}
|