@companion-ai/feynman 0.2.1 → 0.2.3
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
|
@@ -27,53 +27,7 @@ const settingsPath = resolve(appRoot, ".feynman", "settings.json");
|
|
|
27
27
|
const workspaceDir = resolve(appRoot, ".feynman", "npm");
|
|
28
28
|
const workspacePackageJsonPath = resolve(workspaceDir, "package.json");
|
|
29
29
|
|
|
30
|
-
|
|
31
|
-
if (!existsSync(settingsPath)) {
|
|
32
|
-
return;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
const settings = JSON.parse(readFileSync(settingsPath, "utf8"));
|
|
36
|
-
const packageSpecs = Array.isArray(settings.packages)
|
|
37
|
-
? settings.packages
|
|
38
|
-
.filter((value) => typeof value === "string" && value.startsWith("npm:"))
|
|
39
|
-
.map((value) => value.slice(4))
|
|
40
|
-
: [];
|
|
41
|
-
|
|
42
|
-
if (packageSpecs.length === 0) {
|
|
43
|
-
return;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
mkdirSync(workspaceDir, { recursive: true });
|
|
47
|
-
|
|
48
|
-
writeFileSync(
|
|
49
|
-
workspacePackageJsonPath,
|
|
50
|
-
JSON.stringify(
|
|
51
|
-
{
|
|
52
|
-
name: "pi-extensions",
|
|
53
|
-
private: true,
|
|
54
|
-
dependencies: Object.fromEntries(packageSpecs.map((spec) => [spec, "latest"])),
|
|
55
|
-
},
|
|
56
|
-
null,
|
|
57
|
-
2,
|
|
58
|
-
) + "\n",
|
|
59
|
-
"utf8",
|
|
60
|
-
);
|
|
61
|
-
|
|
62
|
-
const npmExec = process.env.npm_execpath;
|
|
63
|
-
const install = npmExec
|
|
64
|
-
? spawnSync(process.execPath, [npmExec, "install", "--prefix", workspaceDir, ...packageSpecs], {
|
|
65
|
-
stdio: "inherit",
|
|
66
|
-
})
|
|
67
|
-
: spawnSync("npm", ["install", "--prefix", workspaceDir, ...packageSpecs], {
|
|
68
|
-
stdio: "inherit",
|
|
69
|
-
});
|
|
70
|
-
|
|
71
|
-
if (install.status !== 0) {
|
|
72
|
-
console.warn("[feynman] warning: failed to preinstall default Pi packages into .feynman/npm");
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
ensurePackageWorkspace();
|
|
30
|
+
// Pi handles package installation from .feynman/settings.json at runtime — no manual install needed
|
|
77
31
|
|
|
78
32
|
if (existsSync(packageJsonPath)) {
|
|
79
33
|
const pkg = JSON.parse(readFileSync(packageJsonPath, "utf8"));
|
|
@@ -296,6 +250,18 @@ if (existsSync(sessionSearchIndexerPath)) {
|
|
|
296
250
|
}
|
|
297
251
|
}
|
|
298
252
|
|
|
253
|
+
const oauthPagePath = resolve(appRoot, "node_modules", "@mariozechner", "pi-ai", "dist", "utils", "oauth", "oauth-page.js");
|
|
254
|
+
|
|
255
|
+
if (existsSync(oauthPagePath)) {
|
|
256
|
+
let source = readFileSync(oauthPagePath, "utf8");
|
|
257
|
+
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>`;';
|
|
258
|
+
if (source.includes(piLogo)) {
|
|
259
|
+
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>`;';
|
|
260
|
+
source = source.replace(piLogo, feynmanLogo);
|
|
261
|
+
writeFileSync(oauthPagePath, source, "utf8");
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
|
|
299
265
|
if (existsSync(piMemoryPath)) {
|
|
300
266
|
let source = readFileSync(piMemoryPath, "utf8");
|
|
301
267
|
const memoryOriginal = 'const MEMORY_DIR = join(homedir(), ".pi", "memory");';
|