@companion-ai/feynman 0.2.2 → 0.2.4
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.
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { readdir } from "node:fs/promises";
|
|
2
|
-
import { cpus,
|
|
2
|
+
import { cpus, homedir, totalmem } from "node:os";
|
|
3
3
|
import { execSync } from "node:child_process";
|
|
4
4
|
import { resolve as resolvePath } from "node:path";
|
|
5
5
|
|
|
@@ -133,33 +133,30 @@ type SystemResources = {
|
|
|
133
133
|
docker: boolean;
|
|
134
134
|
};
|
|
135
135
|
|
|
136
|
+
let cachedResources: SystemResources | null = null;
|
|
137
|
+
|
|
136
138
|
function detectSystemResources(): SystemResources {
|
|
139
|
+
if (cachedResources) return cachedResources;
|
|
140
|
+
|
|
137
141
|
const cores = cpus().length;
|
|
138
|
-
const cpu = cpus()[0]?.model?.trim() ?? "unknown";
|
|
139
142
|
const totalBytes = totalmem();
|
|
140
|
-
const freeBytes = freemem();
|
|
141
143
|
const ramTotal = `${Math.round(totalBytes / (1024 ** 3))}GB`;
|
|
142
|
-
const ramFree = `${Math.round(freeBytes / (1024 ** 3))}GB`;
|
|
143
144
|
|
|
144
|
-
|
|
145
|
+
cachedResources = { cpu: "", cores, ramTotal, ramFree: "", gpu: null, docker: false };
|
|
146
|
+
|
|
145
147
|
try {
|
|
146
148
|
if (process.platform === "darwin") {
|
|
147
|
-
const out = execSync("
|
|
148
|
-
|
|
149
|
-
if (match) gpu = match[1]!.trim();
|
|
150
|
-
} else {
|
|
151
|
-
const out = execSync("nvidia-smi --query-gpu=name --format=csv,noheader 2>/dev/null", { encoding: "utf8", timeout: 3000 }).trim();
|
|
152
|
-
if (out) gpu = out.split("\n")[0]!.trim();
|
|
149
|
+
const out = execSync("sysctl -n machdep.cpu.brand_string 2>/dev/null", { encoding: "utf8", timeout: 1000 }).trim();
|
|
150
|
+
if (out) cachedResources.cpu = out;
|
|
153
151
|
}
|
|
154
152
|
} catch {}
|
|
155
153
|
|
|
156
|
-
let docker = false;
|
|
157
154
|
try {
|
|
158
|
-
execSync("docker
|
|
159
|
-
docker = true;
|
|
155
|
+
execSync("command -v docker >/dev/null 2>&1", { timeout: 500 });
|
|
156
|
+
cachedResources.docker = true;
|
|
160
157
|
} catch {}
|
|
161
158
|
|
|
162
|
-
return
|
|
159
|
+
return cachedResources;
|
|
163
160
|
}
|
|
164
161
|
|
|
165
162
|
type WorkflowInfo = { name: string; description: string };
|
|
@@ -268,10 +265,9 @@ export function installFeynmanHeader(
|
|
|
268
265
|
pushLabeled("directory", dirLabel, "text");
|
|
269
266
|
pushLabeled("session", sessionId, "dim");
|
|
270
267
|
leftLines.push("");
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
pushLabeled("docker", resources.docker ? "available" : "not found", "dim");
|
|
268
|
+
const sysParts = [`${resources.cores} cores`, resources.ramTotal];
|
|
269
|
+
if (resources.docker) sysParts.push("docker");
|
|
270
|
+
pushLabeled("system", sysParts.join(" · "), "dim");
|
|
275
271
|
leftLines.push("");
|
|
276
272
|
leftLines.push(theme.fg("dim", `${toolCount} tools · ${agentCount} agents`));
|
|
277
273
|
|
|
@@ -343,7 +339,7 @@ export function installFeynmanHeader(
|
|
|
343
339
|
push(row(`${theme.fg("dim", "model".padEnd(10))} ${theme.fg("text", truncateVisible(modelLabel, narrowValW))}`));
|
|
344
340
|
push(row(`${theme.fg("dim", "directory".padEnd(10))} ${theme.fg("text", truncateVisible(dirLabel, narrowValW))}`));
|
|
345
341
|
push(row(`${theme.fg("dim", "session".padEnd(10))} ${theme.fg("dim", truncateVisible(sessionId, narrowValW))}`));
|
|
346
|
-
const resourceLine = `${resources.cores} cores · ${resources.ramTotal}
|
|
342
|
+
const resourceLine = `${resources.cores} cores · ${resources.ramTotal}${resources.docker ? " · docker" : ""}`;
|
|
347
343
|
push(row(theme.fg("dim", truncateVisible(resourceLine, contentW))));
|
|
348
344
|
push(row(theme.fg("dim", truncateVisible(`${toolCount} tools · ${agentCount} agents · ${commandCount} commands`, contentW))));
|
|
349
345
|
push(emptyRow());
|
package/package.json
CHANGED
|
@@ -5,14 +5,40 @@ import { fileURLToPath } from "node:url";
|
|
|
5
5
|
|
|
6
6
|
const here = dirname(fileURLToPath(import.meta.url));
|
|
7
7
|
const appRoot = resolve(here, "..");
|
|
8
|
-
|
|
8
|
+
|
|
9
|
+
function findNodeModules() {
|
|
10
|
+
let dir = appRoot;
|
|
11
|
+
while (dir !== dirname(dir)) {
|
|
12
|
+
const nm = resolve(dir, "node_modules");
|
|
13
|
+
if (existsSync(nm)) return nm;
|
|
14
|
+
dir = dirname(dir);
|
|
15
|
+
}
|
|
16
|
+
return resolve(appRoot, "node_modules");
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const nodeModules = findNodeModules();
|
|
20
|
+
|
|
21
|
+
function findPackageRoot(packageName) {
|
|
22
|
+
const candidate = resolve(nodeModules, packageName);
|
|
23
|
+
if (existsSync(resolve(candidate, "package.json"))) return candidate;
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const piPackageRoot = findPackageRoot("@mariozechner/pi-coding-agent");
|
|
28
|
+
const piTuiRoot = findPackageRoot("@mariozechner/pi-tui");
|
|
29
|
+
const piAiRoot = findPackageRoot("@mariozechner/pi-ai");
|
|
30
|
+
|
|
31
|
+
if (!piPackageRoot) {
|
|
32
|
+
console.warn("[feynman] pi-coding-agent not found, skipping patches");
|
|
33
|
+
process.exit(0);
|
|
34
|
+
}
|
|
35
|
+
|
|
9
36
|
const packageJsonPath = resolve(piPackageRoot, "package.json");
|
|
10
37
|
const cliPath = resolve(piPackageRoot, "dist", "cli.js");
|
|
11
38
|
const bunCliPath = resolve(piPackageRoot, "dist", "bun", "cli.js");
|
|
12
39
|
const interactiveModePath = resolve(piPackageRoot, "dist", "modes", "interactive", "interactive-mode.js");
|
|
13
40
|
const interactiveThemePath = resolve(piPackageRoot, "dist", "modes", "interactive", "theme", "theme.js");
|
|
14
|
-
const
|
|
15
|
-
const editorPath = resolve(piTuiRoot, "dist", "components", "editor.js");
|
|
41
|
+
const editorPath = piTuiRoot ? resolve(piTuiRoot, "dist", "components", "editor.js") : null;
|
|
16
42
|
const workspaceRoot = resolve(appRoot, ".feynman", "npm", "node_modules");
|
|
17
43
|
const webAccessPath = resolve(workspaceRoot, "pi-web-access", "index.ts");
|
|
18
44
|
const sessionSearchIndexerPath = resolve(
|
|
@@ -85,7 +111,7 @@ if (existsSync(interactiveThemePath)) {
|
|
|
85
111
|
writeFileSync(interactiveThemePath, themeSource, "utf8");
|
|
86
112
|
}
|
|
87
113
|
|
|
88
|
-
if (existsSync(editorPath)) {
|
|
114
|
+
if (editorPath && existsSync(editorPath)) {
|
|
89
115
|
let editorSource = readFileSync(editorPath, "utf8");
|
|
90
116
|
const importOriginal =
|
|
91
117
|
'import { getSegmenter, isPunctuationChar, isWhitespaceChar, truncateToWidth, visibleWidth } from "../utils.js";';
|
|
@@ -250,6 +276,18 @@ if (existsSync(sessionSearchIndexerPath)) {
|
|
|
250
276
|
}
|
|
251
277
|
}
|
|
252
278
|
|
|
279
|
+
const oauthPagePath = piAiRoot ? resolve(piAiRoot, "dist", "utils", "oauth", "oauth-page.js") : null;
|
|
280
|
+
|
|
281
|
+
if (oauthPagePath && existsSync(oauthPagePath)) {
|
|
282
|
+
let source = readFileSync(oauthPagePath, "utf8");
|
|
283
|
+
const piLogo = 'const LOGO_SVG = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 800 800" aria-hidden="true"><path fill="#fff" fill-rule="evenodd" d="M165.29 165.29 H517.36 V400 H400 V517.36 H282.65 V634.72 H165.29 Z M282.65 282.65 V400 H400 V282.65 Z"/><path fill="#fff" d="M517.36 400 H634.72 V634.72 H517.36 Z"/></svg>`;';
|
|
284
|
+
if (source.includes(piLogo)) {
|
|
285
|
+
const feynmanLogo = 'const LOGO_SVG = `<span style="font-size:32px;font-weight:700;color:#10b981;font-family:system-ui,sans-serif;letter-spacing:-0.02em">feynman</span>`;';
|
|
286
|
+
source = source.replace(piLogo, feynmanLogo);
|
|
287
|
+
writeFileSync(oauthPagePath, source, "utf8");
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
|
|
253
291
|
if (existsSync(piMemoryPath)) {
|
|
254
292
|
let source = readFileSync(piMemoryPath, "utf8");
|
|
255
293
|
const memoryOriginal = 'const MEMORY_DIR = join(homedir(), ".pi", "memory");';
|