@companion-ai/feynman 0.5.4 → 0.5.5

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/.nvmrc CHANGED
@@ -1 +1 @@
1
- 24.20.0
1
+ 24.21.0
package/README.md CHANGED
@@ -27,7 +27,7 @@ irm https://feynman.is/install.ps1 | iex
27
27
 
28
28
  The one-line installer fetches the latest tagged release as a standalone bundle with its own Node.js runtime and verifies its SHA-256 before installing. To pin a version, pass it explicitly, for example `curl -fsSL https://feynman.is/install | bash -s -- 0.5.3`. Rerun the installer to upgrade; `feynman update` only updates optional Pi packages you installed.
29
29
 
30
- **npm alternative** (uses your local Node.js `>=22.22.0 <26`):
30
+ **npm alternative** (uses your local Node.js `>=22.22.0`):
31
31
 
32
32
  ```bash
33
33
  npm install -g @companion-ai/feynman
package/RELEASES.md CHANGED
@@ -6,6 +6,24 @@ GitHub release notes are generated from the matching `## vX.Y.Z` section in this
6
6
 
7
7
  ## Unreleased
8
8
 
9
+ ## v0.5.5 - 2026-09-24
10
+
11
+ ### Node.js 26
12
+
13
+ - Feynman now runs on Node.js 26, the current release. The upper version limit is gone: Feynman needs Node.js 22.22.0 or newer, like Pi itself. Tests run on Node 22, 24, and 26.
14
+ - The standalone installers bundle Node.js 24.21.0, the latest LTS release.
15
+
16
+ ### alphaXiv
17
+
18
+ - When an alphaXiv call fails, the tool error now points the agent to `feynman_science_database_search` (arXiv or Semantic Scholar) or `fetch_content`, so a research run continues on another source instead of retrying a broken tool. A "not logged in" error names `feynman alpha login`.
19
+ - The alphaXiv docs explain signing in from a machine without a browser (SSH, Docker, WSL): open the printed URL anywhere and paste the final `127.0.0.1:9876/callback` URL back into the terminal.
20
+
21
+ ### Other
22
+
23
+ - The setup docs explain the most common reason local models write no files: a small context window. They show how to raise Ollama's context and set `contextWindow` and `maxTokens` in `models.json`.
24
+ - feynman.is/privacy and feynman.is/telemetry go to the telemetry section, which lists what is collected and how to opt out.
25
+ - Updated dependencies: pi-btw 0.6.1, posthog-node 5.53, @clack/prompts 1.8.1, and the website toolchain (Astro 7.3, @astrojs/react 7). CI uses actions/checkout and actions/setup-node v7 and wrangler 4.139.
26
+
9
27
  ## v0.5.4 - 2026-09-24
10
28
 
11
29
  ### Use Feynman from ACP editors
package/bin/feynman.js CHANGED
@@ -3,7 +3,6 @@ import { resolve } from "node:path";
3
3
  import { pathToFileURL } from "node:url";
4
4
 
5
5
  const MIN_NODE_VERSION = "22.22.0";
6
- const MAX_NODE_MAJOR = 25;
7
6
  const PREFERRED_NODE_MAJOR = 24;
8
7
 
9
8
  function parseNodeVersion(version) {
@@ -21,15 +20,12 @@ function compareNodeVersions(left, right) {
21
20
  return left.patch - right.patch;
22
21
  }
23
22
 
24
- const parsedNodeVersion = parseNodeVersion(process.versions.node);
25
- if (compareNodeVersions(parsedNodeVersion, parseNodeVersion(MIN_NODE_VERSION)) < 0 || parsedNodeVersion.major > MAX_NODE_MAJOR) {
23
+ if (compareNodeVersions(parseNodeVersion(process.versions.node), parseNodeVersion(MIN_NODE_VERSION)) < 0) {
26
24
  const isWindows = process.platform === "win32";
27
- console.error(`feynman supports Node.js ${MIN_NODE_VERSION} through ${MAX_NODE_MAJOR}.x (detected ${process.versions.node}).`);
28
- console.error(parsedNodeVersion.major > MAX_NODE_MAJOR
29
- ? "This newer Node release is not supported yet."
30
- : isWindows
31
- ? "Install a supported Node.js release from https://nodejs.org, or use the standalone installer:"
32
- : `Switch to a supported Node release with \`nvm install ${PREFERRED_NODE_MAJOR} && nvm use ${PREFERRED_NODE_MAJOR}\`, or use the standalone installer:`);
25
+ console.error(`feynman requires Node.js ${MIN_NODE_VERSION} or newer (detected ${process.versions.node}).`);
26
+ console.error(isWindows
27
+ ? "Install a supported Node.js release from https://nodejs.org, or use the standalone installer:"
28
+ : `Switch to a supported Node release with \`nvm install ${PREFERRED_NODE_MAJOR} && nvm use ${PREFERRED_NODE_MAJOR}\`, or use the standalone installer:`);
33
29
  console.error(isWindows
34
30
  ? "irm https://feynman.is/install.ps1 | iex"
35
31
  : "curl -fsSL https://feynman.is/install | bash");
@@ -1,5 +1,4 @@
1
1
  export const MIN_NODE_VERSION = "22.22.0";
2
- export const MAX_NODE_MAJOR = 25;
3
2
  export const PREFERRED_NODE_MAJOR = 24;
4
3
  function parseNodeVersion(version) {
5
4
  const [major = "0", minor = "0", patch = "0"] = version.replace(/^v/, "").split(".");
@@ -17,20 +16,15 @@ function compareNodeVersions(left, right) {
17
16
  return left.patch - right.patch;
18
17
  }
19
18
  export function isSupportedNodeVersion(version = process.versions.node) {
20
- const parsed = parseNodeVersion(version);
21
- return compareNodeVersions(parsed, parseNodeVersion(MIN_NODE_VERSION)) >= 0 && parsed.major <= MAX_NODE_MAJOR;
19
+ return compareNodeVersions(parseNodeVersion(version), parseNodeVersion(MIN_NODE_VERSION)) >= 0;
22
20
  }
23
21
  export function getUnsupportedNodeVersionLines(version = process.versions.node) {
24
22
  const isWindows = process.platform === "win32";
25
- const parsed = parseNodeVersion(version);
26
- const rangeText = `Node.js ${MIN_NODE_VERSION} through ${MAX_NODE_MAJOR}.x`;
27
23
  return [
28
- `feynman supports ${rangeText} (detected ${version}).`,
29
- parsed.major > MAX_NODE_MAJOR
30
- ? "This newer Node release is not supported yet."
31
- : isWindows
32
- ? "Install a supported Node.js release from https://nodejs.org, or use the standalone installer:"
33
- : `Switch to a supported Node release with \`nvm install ${PREFERRED_NODE_MAJOR} && nvm use ${PREFERRED_NODE_MAJOR}\`, or use the standalone installer:`,
24
+ `feynman requires Node.js ${MIN_NODE_VERSION} or newer (detected ${version}).`,
25
+ isWindows
26
+ ? "Install a supported Node.js release from https://nodejs.org, or use the standalone installer:"
27
+ : `Switch to a supported Node release with \`nvm install ${PREFERRED_NODE_MAJOR} && nvm use ${PREFERRED_NODE_MAJOR}\`, or use the standalone installer:`,
34
28
  isWindows
35
29
  ? "irm https://feynman.is/install.ps1 | iex"
36
30
  : "curl -fsSL https://feynman.is/install | bash",
@@ -18,6 +18,19 @@ function formatText(value: unknown): string {
18
18
  return JSON.stringify(value, null, 2);
19
19
  }
20
20
 
21
+ // alphaXiv's API has changed without notice before; when a call fails, point
22
+ // the model at the other paper sources instead of leaving it on a broken tool.
23
+ async function withPaperFallback<T>(run: () => Promise<T>): Promise<T> {
24
+ try {
25
+ return await run();
26
+ } catch (error) {
27
+ const message = (error instanceof Error ? error.message : String(error)).replace("`alpha login`", "`feynman alpha login`");
28
+ throw new Error(
29
+ `${message}\nalphaXiv did not answer this call. Use feynman_science_database_search (source "arxiv" or "semanticscholar") or fetch_content on https://arxiv.org/abs/<id> instead.`,
30
+ );
31
+ }
32
+ }
33
+
21
34
  // Pi converts Type.Array inputs before validating them, which would turn null into ["null"].
22
35
  // Preserve the JSON Schema array contract without the Type.Array conversion marker.
23
36
  const paperSectionsSchema = Type.Unsafe<string[]>({
@@ -47,7 +60,7 @@ export function registerAlphaTools(pi: ExtensionAPI): void {
47
60
  ),
48
61
  }),
49
62
  async execute(_toolCallId, params) {
50
- const result = await searchPapers(params.query, params.mode?.trim() || "semantic");
63
+ const result = await withPaperFallback(() => searchPapers(params.query, params.mode?.trim() || "semantic"));
51
64
  return { content: [{ type: "text", text: formatText(result) }], details: result };
52
65
  },
53
66
  });
@@ -69,7 +82,7 @@ export function registerAlphaTools(pi: ExtensionAPI): void {
69
82
  sections: Type.Optional(paperSectionsSchema),
70
83
  }),
71
84
  async execute(_toolCallId, params) {
72
- const result = await getPaper(params.paper, { fullText: params.fullText });
85
+ const result = await withPaperFallback(() => getPaper(params.paper, { fullText: params.fullText }));
73
86
  const extracted = extractPaperSections(result.content, params.section, params.sections);
74
87
  const filteredResult = extracted.requested.length
75
88
  ? {
@@ -92,7 +105,7 @@ export function registerAlphaTools(pi: ExtensionAPI): void {
92
105
  question: Type.String({ description: "Question about the paper." }),
93
106
  }),
94
107
  async execute(_toolCallId, params) {
95
- const result = await askPaper(params.paper, params.question);
108
+ const result = await withPaperFallback(() => askPaper(params.paper, params.question));
96
109
  return { content: [{ type: "text", text: formatText(result) }], details: result };
97
110
  },
98
111
  });
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "@companion-ai/feynman",
3
- "version": "0.5.4",
3
+ "version": "0.5.5",
4
4
  "description": "Research-first CLI agent built on Pi and alphaXiv",
5
5
  "license": "MIT",
6
6
  "type": "module",
7
7
  "engines": {
8
- "node": ">=22.22.0 <26"
8
+ "node": ">=22.22.0"
9
9
  },
10
10
  "bin": {
11
11
  "feynman": "bin/feynman.js"
@@ -77,16 +77,16 @@
77
77
  }
78
78
  },
79
79
  "dependencies": {
80
- "@clack/prompts": "^1.7.0",
80
+ "@clack/prompts": "^1.8.1",
81
81
  "@companion-ai/alpha-hub": "0.1.6",
82
82
  "@earendil-works/pi-ai": "*",
83
83
  "@earendil-works/pi-coding-agent": "*",
84
84
  "fast-xml-parser": "5.11.1",
85
- "pi-btw": "0.6.0",
85
+ "pi-btw": "0.6.1",
86
86
  "pi-docparser": "4.0.0",
87
87
  "pi-subagents": "0.71.0",
88
88
  "pi-web-access": "0.31.0",
89
- "posthog-node": "^5.51.6"
89
+ "posthog-node": "^5.53.0"
90
90
  },
91
91
  "peerDependencies": {
92
92
  "@earendil-works/pi-ai": "*",
@@ -95,10 +95,10 @@
95
95
  "typebox": "*"
96
96
  },
97
97
  "devDependencies": {
98
- "@types/node": "^26.4.1",
99
- "tsx": "^4.23.13",
98
+ "@types/node": "^26.6.2",
99
+ "tsx": "^4.23.15",
100
100
  "typescript": "^7.0.2",
101
- "yaml": "2.9.0"
101
+ "yaml": "2.9.1"
102
102
  },
103
103
  "repository": {
104
104
  "type": "git",
@@ -1,5 +1,4 @@
1
1
  const MIN_NODE_VERSION = "22.22.0";
2
- const MAX_NODE_MAJOR = 25;
3
2
  const PREFERRED_NODE_MAJOR = 24;
4
3
 
5
4
  function parseNodeVersion(version) {
@@ -18,20 +17,16 @@ function compareNodeVersions(left, right) {
18
17
  }
19
18
 
20
19
  function isSupportedNodeVersion(version = process.versions.node) {
21
- const parsed = parseNodeVersion(version);
22
- return compareNodeVersions(parsed, parseNodeVersion(MIN_NODE_VERSION)) >= 0 && parsed.major <= MAX_NODE_MAJOR;
20
+ return compareNodeVersions(parseNodeVersion(version), parseNodeVersion(MIN_NODE_VERSION)) >= 0;
23
21
  }
24
22
 
25
23
  function getUnsupportedNodeVersionLines(version = process.versions.node) {
26
24
  const isWindows = process.platform === "win32";
27
- const parsed = parseNodeVersion(version);
28
25
  return [
29
- `feynman supports Node.js ${MIN_NODE_VERSION} through ${MAX_NODE_MAJOR}.x (detected ${version}).`,
30
- parsed.major > MAX_NODE_MAJOR
31
- ? "This newer Node release is not supported yet."
32
- : isWindows
33
- ? "Install a supported Node.js release from https://nodejs.org, or use the standalone installer:"
34
- : `Switch to a supported Node release with \`nvm install ${PREFERRED_NODE_MAJOR} && nvm use ${PREFERRED_NODE_MAJOR}\`, or use the standalone installer:`,
26
+ `feynman requires Node.js ${MIN_NODE_VERSION} or newer (detected ${version}).`,
27
+ isWindows
28
+ ? "Install a supported Node.js release from https://nodejs.org, or use the standalone installer:"
29
+ : `Switch to a supported Node release with \`nvm install ${PREFERRED_NODE_MAJOR} && nvm use ${PREFERRED_NODE_MAJOR}\`, or use the standalone installer:`,
35
30
  isWindows
36
31
  ? "irm https://feynman.is/install.ps1 | iex"
37
32
  : "curl -fsSL https://feynman.is/install | bash",
@@ -42,11 +37,5 @@ if (!isSupportedNodeVersion()) {
42
37
  for (const line of getUnsupportedNodeVersionLines()) {
43
38
  console.error(line);
44
39
  }
45
- // Too-new Node must not abort the install: failing preinstall makes npm roll
46
- // back to the previously installed version, which pins users to a release that
47
- // predates the fix they are trying to get (issue #177). The launcher in
48
- // bin/feynman.js enforces the supported range at runtime with the same message.
49
- if (parseNodeVersion(process.versions.node).major <= MAX_NODE_MAJOR) {
50
- process.exit(1);
51
- }
40
+ process.exit(1);
52
41
  }