@companion-ai/feynman 0.5.3 → 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/.feynman/themes/feynman.json +1 -1
- package/.nvmrc +1 -1
- package/README.md +19 -71
- package/RELEASES.md +36 -0
- package/bin/feynman.js +5 -9
- package/dist/cli.js +4 -7
- package/dist/pi/packages.js +1 -18
- package/dist/system/node-version.js +5 -11
- package/extensions/research-tools/alpha.ts +16 -3
- package/metadata/commands.mjs +3 -2
- package/package.json +8 -8
- package/scripts/check-node-version.mjs +6 -17
- package/scripts/check-pi-rpc.mjs +2 -1
- package/skills/alpha-research/SKILL.md +1 -1
- package/skills/autoresearch/SKILL.md +1 -1
- package/skills/preview/SKILL.md +7 -20
- package/skills/session-search/SKILL.md +5 -16
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"$schema": "https://raw.githubusercontent.com/
|
|
2
|
+
"$schema": "https://raw.githubusercontent.com/earendil-works/pi/main/packages/coding-agent/src/modes/interactive/theme/theme-schema.json",
|
|
3
3
|
"name": "feynman",
|
|
4
4
|
"vars": {
|
|
5
5
|
"ink": "#d3c6aa",
|
package/.nvmrc
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
24.
|
|
1
|
+
24.21.0
|
package/README.md
CHANGED
|
@@ -25,34 +25,22 @@ curl -fsSL https://feynman.is/install | bash
|
|
|
25
25
|
irm https://feynman.is/install.ps1 | iex
|
|
26
26
|
```
|
|
27
27
|
|
|
28
|
-
The one-line installer fetches the latest tagged release. To pin a version, pass it explicitly, for example `curl -fsSL https://feynman.is/install | bash -s -- 0.
|
|
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
|
-
|
|
31
|
-
|
|
32
|
-
To upgrade the standalone app later, rerun the installer. `feynman update` only refreshes optional Pi packages you installed; Pi and the core packages update with Feynman itself.
|
|
33
|
-
|
|
34
|
-
To uninstall the standalone app, remove the launcher and runtime bundle, then optionally remove `~/.feynman` if you also want to delete settings, sessions, and installed package state. If you also want to delete alphaXiv login state, remove `~/.ahub`. See the installation guide for platform-specific paths.
|
|
35
|
-
|
|
36
|
-
**npm alternative** (uses your local Node.js runtime):
|
|
30
|
+
**npm alternative** (uses your local Node.js `>=22.22.0`):
|
|
37
31
|
|
|
38
32
|
```bash
|
|
39
33
|
npm install -g @companion-ai/feynman
|
|
40
34
|
```
|
|
41
35
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
If you installed the interim `@advaitpaliwal/feynman` package (0.3.48), migrate once:
|
|
36
|
+
If you installed the interim `@advaitpaliwal/feynman` package, migrate once:
|
|
45
37
|
|
|
46
38
|
```bash
|
|
47
39
|
npm uninstall -g @advaitpaliwal/feynman
|
|
48
40
|
npm install -g @companion-ai/feynman
|
|
49
41
|
```
|
|
50
42
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
Local models are supported through the setup flow. For LM Studio, run `feynman setup`, choose `LM Studio`, and keep the default `http://localhost:1234/v1` unless you changed the server port. For LiteLLM, choose `LiteLLM Proxy` and keep the default `http://localhost:4000/v1`. For Ollama or vLLM, choose `Custom provider (baseUrl + API key)`, use `openai-completions`, and point it at the local `/v1` endpoint.
|
|
54
|
-
|
|
55
|
-
To authenticate another hosted provider, run `feynman model login <provider>`. GitHub Copilot sign-in retries model discovery once when GitHub rate-limits the request. OpenRouter login opens an OAuth page and listens for a local callback; over SSH or in another headless environment, paste the browser's final redirect URL or authorization code into Feynman's prompt, or set `OPENROUTER_API_KEY` before launch to use API-key authentication without OAuth.
|
|
43
|
+
Then run `feynman setup` to sign in to a model provider. To use Feynman in an ACP editor such as Zed, run it through [pi-acp](https://github.com/svkozak/pi-acp): `"agent_servers": { "Feynman": { "command": "npx", "args": ["-y", "pi-acp"], "env": { "PI_ACP_PI_COMMAND": "feynman" } } }`. See the [installation guide](https://feynman.is/docs/getting-started/installation) for uninstalling and the [setup guide](https://feynman.is/docs/getting-started/setup) for local models (LM Studio, LiteLLM, Ollama, vLLM) and Amazon Bedrock.
|
|
56
44
|
|
|
57
45
|
### Skills Only
|
|
58
46
|
|
|
@@ -70,52 +58,18 @@ curl -fsSL https://feynman.is/install-skills | bash
|
|
|
70
58
|
irm https://feynman.is/install-skills.ps1 | iex
|
|
71
59
|
```
|
|
72
60
|
|
|
73
|
-
That installs the skill library into `~/.codex/skills/feynman` for Codex.
|
|
74
|
-
|
|
75
|
-
**macOS / Linux:**
|
|
76
|
-
|
|
77
|
-
```bash
|
|
78
|
-
curl -fsSL https://feynman.is/install-skills | bash -s -- --codex
|
|
79
|
-
```
|
|
80
|
-
|
|
81
|
-
**Windows (PowerShell):**
|
|
82
|
-
|
|
83
|
-
```powershell
|
|
84
|
-
& ([scriptblock]::Create((irm https://feynman.is/install-skills.ps1))) -Scope Codex
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
For a repo-local Claude/agent install instead:
|
|
88
|
-
|
|
89
|
-
**macOS / Linux:**
|
|
90
|
-
|
|
91
|
-
```bash
|
|
92
|
-
curl -fsSL https://feynman.is/install-skills | bash -s -- --repo
|
|
93
|
-
```
|
|
94
|
-
|
|
95
|
-
**Windows (PowerShell):**
|
|
96
|
-
|
|
97
|
-
```powershell
|
|
98
|
-
& ([scriptblock]::Create((irm https://feynman.is/install-skills.ps1))) -Scope Repo
|
|
99
|
-
```
|
|
100
|
-
|
|
101
|
-
That installs into `.agents/skills/feynman` under the current repository.
|
|
102
|
-
|
|
103
|
-
For an OpenCode project-local install instead:
|
|
104
|
-
|
|
105
|
-
**macOS / Linux:**
|
|
61
|
+
That installs the skill library into `~/.codex/skills/feynman` for Codex. For other targets, pass a scope:
|
|
106
62
|
|
|
107
63
|
```bash
|
|
108
|
-
curl -fsSL https://feynman.is/install-skills | bash -s -- --
|
|
64
|
+
curl -fsSL https://feynman.is/install-skills | bash -s -- --codex # ~/.codex/skills/feynman (default)
|
|
65
|
+
curl -fsSL https://feynman.is/install-skills | bash -s -- --repo # .agents/skills/feynman in the current repo
|
|
66
|
+
curl -fsSL https://feynman.is/install-skills | bash -s -- --opencode # .opencode/skills/feynman in the current repo
|
|
109
67
|
```
|
|
110
68
|
|
|
111
|
-
**Windows (PowerShell):**
|
|
112
|
-
|
|
113
69
|
```powershell
|
|
114
|
-
& ([scriptblock]::Create((irm https://feynman.is/install-skills.ps1))) -Scope OpenCode
|
|
70
|
+
& ([scriptblock]::Create((irm https://feynman.is/install-skills.ps1))) -Scope Codex # or -Scope Repo, -Scope OpenCode
|
|
115
71
|
```
|
|
116
72
|
|
|
117
|
-
That installs into `.opencode/skills/feynman` under the current repository.
|
|
118
|
-
|
|
119
73
|
These installers download the bundled `skills/` and `prompts/` trees plus the repo guidance files referenced by those skills. They do not install the Feynman terminal, bundled Node runtime, auth storage, or Pi packages.
|
|
120
74
|
|
|
121
75
|
---
|
|
@@ -124,16 +78,10 @@ These installers download the bundled `skills/` and `prompts/` trees plus the re
|
|
|
124
78
|
|
|
125
79
|
```
|
|
126
80
|
$ feynman "what do we know about scaling laws"
|
|
127
|
-
→ Searches papers and web,
|
|
128
|
-
|
|
129
|
-
$ feynman -- "- summarize the strongest evidence first"
|
|
130
|
-
→ Preserves a research prompt that begins with a dash instead of parsing it as a CLI option
|
|
131
|
-
|
|
132
|
-
$ feynman --prompt="- summarize the strongest evidence first"
|
|
133
|
-
→ Runs a dash-leading research prompt once and exits
|
|
81
|
+
→ Searches papers and the web, answers with cited sources
|
|
134
82
|
|
|
135
83
|
$ feynman deepresearch "mechanistic interpretability"
|
|
136
|
-
→
|
|
84
|
+
→ Plan-first investigation with parallel researchers, synthesis, and citation verification
|
|
137
85
|
|
|
138
86
|
$ feynman lit "RLHF alternatives"
|
|
139
87
|
→ Literature review with consensus, disagreements, open questions, and lab/PI corpus mode when the input names a research group
|
|
@@ -165,6 +113,7 @@ Ask naturally or use slash commands as shortcuts.
|
|
|
165
113
|
| `/compare <topic>` | Source comparison matrix |
|
|
166
114
|
| `/draft <topic>` | Paper-style draft from research findings |
|
|
167
115
|
| `/autoresearch <idea>` | Bounded experiment loop with benchmark evidence |
|
|
116
|
+
| `/summarize <source>` | Summarize a paper, report, repo, or PDF without loading it raw into context |
|
|
168
117
|
| `/btw <question>` | Side conversation while the main research agent is busy, with optional handoff back into the main thread |
|
|
169
118
|
| `/outputs` | Browse all research artifacts |
|
|
170
119
|
|
|
@@ -183,19 +132,18 @@ Four bundled research agents, invoked by workflow prompts when decomposition hel
|
|
|
183
132
|
|
|
184
133
|
### Skills & Tools
|
|
185
134
|
|
|
186
|
-
- **[
|
|
187
|
-
- **Literature databases** — read-only Semantic Scholar
|
|
135
|
+
- **[alphaXiv](https://www.alphaxiv.org/)** — paper search, Q&A, code reading, and annotations (via Feynman's `alpha` tools and `feynman alpha` command)
|
|
136
|
+
- **Literature databases** — read-only Semantic Scholar, OpenAlex, arXiv ID lookup, PubMed, Europe PMC full text, bioRxiv/medRxiv, and Crossref, with stable identifiers. Set the free `OPENALEX_API_KEY` ([create one](https://openalex.org/settings/api)) and optionally `SEMANTIC_SCHOLAR_API_KEY` ([request one](https://www.semanticscholar.org/product/api#api-key-form)) to use your own rate limits
|
|
188
137
|
- **[Hugging Face Hub](https://huggingface.co/docs/hub/api)** — dataset metadata, split/schema inspection, and small file reads from model, dataset, and Space repos
|
|
189
|
-
- **Web research** —
|
|
190
|
-
- **
|
|
191
|
-
- **
|
|
192
|
-
- **Research execution options** — Docker, plus Modal or RunPod when their CLIs are installed, for explicitly chosen replication, benchmark, or dataset-heavy experiment runs; not service deployment or generic cloud administration
|
|
138
|
+
- **Web research** — search, page fetching, and PDF extraction through [pi-web-access](https://github.com/nicobailon/pi-web-access); Exa works without a key, and `feynman search set` configures Perplexity, Exa, or Gemini
|
|
139
|
+
- **Documents** — local PDF and office-document parsing through [pi-docparser](https://github.com/maxedapps/pi-docparser)
|
|
140
|
+
- **Compute** — Docker, plus Modal or RunPod when their CLIs are installed, for replication and experiment runs you explicitly approve
|
|
193
141
|
|
|
194
142
|
---
|
|
195
143
|
|
|
196
144
|
### How it works
|
|
197
145
|
|
|
198
|
-
|
|
146
|
+
Feynman runs on stock [Pi](https://github.com/earendil-works/pi) (`@earendil-works/pi-coding-agent`). Its prompts, skills, agents, and research tools load as a Pi [package](https://github.com/earendil-works/pi/blob/main/packages/coding-agent/docs/packages.md) alongside the bundled `pi-subagents`, `pi-web-access`, `pi-docparser`, and `pi-btw` packages. Paper search and analysis use [alphaXiv](https://www.alphaxiv.org/). Research claims link to papers, docs, or repos with direct URLs.
|
|
199
147
|
|
|
200
148
|
---
|
|
201
149
|
|
|
@@ -217,7 +165,7 @@ Feynman sends anonymous usage telemetry to PostHog by default and prints a one-t
|
|
|
217
165
|
|
|
218
166
|
---
|
|
219
167
|
|
|
220
|
-
The bundled
|
|
168
|
+
The bundled Pi packages are pinned and update with Feynman, not through `feynman update`. See the [package stack](https://feynman.is/docs/reference/package-stack) and [release notes](https://feynman.is/docs/reference/releases).
|
|
221
169
|
|
|
222
170
|
### Contributing
|
|
223
171
|
|
package/RELEASES.md
CHANGED
|
@@ -6,6 +6,42 @@ 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
|
+
|
|
27
|
+
## v0.5.4 - 2026-09-24
|
|
28
|
+
|
|
29
|
+
### Use Feynman from ACP editors
|
|
30
|
+
|
|
31
|
+
- `feynman --mode rpc` now accepts `--no-themes`, the Pi flag the [pi-acp](https://github.com/svkozak/pi-acp) adapter passes, so Feynman runs in ACP editors such as Zed. Point pi-acp at Feynman with `PI_ACP_PI_COMMAND=feynman`; the setup guide has the Zed settings.
|
|
32
|
+
|
|
33
|
+
### Removed what did not work
|
|
34
|
+
|
|
35
|
+
- The optional `session-search` package preset is gone. It indexes `~/.pi/agent/sessions` and never saw Feynman's sessions in `~/.feynman/sessions`, and its `/search` collided with pi-web-access's. Search past sessions with `grep` or `rg` over `~/.feynman/sessions`; the session-search skill now shows how.
|
|
36
|
+
- `/preview` is no longer listed in `/help`: no bundled or optional package provides it. `feynman setup preview` still installs pandoc, and the preview docs show how to render artifacts to HTML or PDF.
|
|
37
|
+
- `/help` lists pi-web-access's real `/websearch` and `/curator` commands instead of `/web-results`, which pi-web-access 0.31 no longer registers.
|
|
38
|
+
- The autoresearch and alpha skills no longer mention tools and patches that do not exist.
|
|
39
|
+
|
|
40
|
+
### Docs match the code
|
|
41
|
+
|
|
42
|
+
- Every docs page, the landing page, and the README were checked against the CLI, prompts, agents, and package code. Corrections include the setup flow (model access, optional packages, alphaXiv login, pandoc), where keys are stored (plain text in `~/.feynman/agent/auth.json` with user-only permissions, not encrypted), the verifier, reviewer, and writer roles and which workflows use them, workflow steps and output files, the web-search tools and commands, and dead Pi links (now `earendil-works/pi`).
|
|
43
|
+
- The landing page adds a PowerShell install command and drops cards for features that do not ship.
|
|
44
|
+
|
|
9
45
|
## v0.5.3 - 2026-09-24
|
|
10
46
|
|
|
11
47
|
### Leaner prompts, same research quality
|
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
|
-
|
|
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
|
|
28
|
-
console.error(
|
|
29
|
-
? "
|
|
30
|
-
:
|
|
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");
|
package/dist/cli.js
CHANGED
|
@@ -18,7 +18,7 @@ import { verifyAlphaAuthStatus } from "./alpha-auth-status.js";
|
|
|
18
18
|
import { ensureFeynmanAgentDir } from "./bootstrap/home.js";
|
|
19
19
|
import { ensureFeynmanHome, getDefaultSessionDir, getFeynmanAgentDir, getFeynmanHome } from "./config/paths.js";
|
|
20
20
|
import { launchPiChat, runPi } from "./pi/launch.js";
|
|
21
|
-
import { installPiPackage,
|
|
21
|
+
import { installPiPackage, listOptionalPackagePresets, normalizeOptionalPackagePresetName, resolvePackageSource, updatePiPackages, } from "./pi/packages.js";
|
|
22
22
|
import { canonicalizeModelSpec, ensureFeynmanSettings, normalizeThinkingLevel, readJson, } from "./pi/settings.js";
|
|
23
23
|
import { BUNDLED_PI_PACKAGES, buildPiEnv } from "./pi/runtime.js";
|
|
24
24
|
import { getConfiguredServiceTier, normalizeServiceTier, setConfiguredServiceTier } from "./model/service-tier.js";
|
|
@@ -266,11 +266,6 @@ async function handlePackagesCommand(subcommand, args, piOptions) {
|
|
|
266
266
|
if (!presetName) {
|
|
267
267
|
throw new Error(`Unknown package preset: ${target}`);
|
|
268
268
|
}
|
|
269
|
-
if (!isOptionalPackagePresetSupported(presetName)) {
|
|
270
|
-
console.log(`${presetName} is not available on this runtime.`);
|
|
271
|
-
console.log(`Its sqlite-backed dependency is only supported through Node ${MAX_NATIVE_PACKAGE_NODE_MAJOR}.x.`);
|
|
272
|
-
return;
|
|
273
|
-
}
|
|
274
269
|
const source = resolvePackageSource(presetName);
|
|
275
270
|
if (configuredSources.has(source)) {
|
|
276
271
|
console.log(`${source} already installed`);
|
|
@@ -448,6 +443,7 @@ async function runMain(input) {
|
|
|
448
443
|
model: { type: "string" },
|
|
449
444
|
"new-session": { type: "boolean" },
|
|
450
445
|
"no-session": { type: "boolean" },
|
|
446
|
+
"no-themes": { type: "boolean" },
|
|
451
447
|
prompt: { type: "string" },
|
|
452
448
|
resume: { type: "boolean", short: "r" },
|
|
453
449
|
"service-tier": { type: "string" },
|
|
@@ -668,7 +664,8 @@ async function runMain(input) {
|
|
|
668
664
|
thinkingLevel: launchThinkingLevel,
|
|
669
665
|
explicitModelSpec,
|
|
670
666
|
resumeRecentSession,
|
|
671
|
-
|
|
667
|
+
// ACP adapters such as pi-acp pass --no-themes with --mode rpc.
|
|
668
|
+
piArgs: values["no-themes"] ? [...piArgs, "--no-themes"] : piArgs,
|
|
672
669
|
preLaunchNotice,
|
|
673
670
|
...promptOptions,
|
|
674
671
|
});
|
package/dist/pi/packages.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { runPi } from "./launch.js";
|
|
2
2
|
import { buildPiEnv } from "./runtime.js";
|
|
3
|
-
export const MAX_NATIVE_PACKAGE_NODE_MAJOR = 22;
|
|
4
3
|
export const OPTIONAL_PACKAGE_PRESETS = {
|
|
5
4
|
memory: {
|
|
6
5
|
description: "Research-session preference and correction memory.",
|
|
@@ -10,29 +9,13 @@ export const OPTIONAL_PACKAGE_PRESETS = {
|
|
|
10
9
|
description: "Hindsight-backed research continuity memory.",
|
|
11
10
|
source: "npm:@luxusai/pi-hindsight",
|
|
12
11
|
},
|
|
13
|
-
"session-search": {
|
|
14
|
-
description: "Indexed recall for prior research session transcripts.",
|
|
15
|
-
source: "npm:@kaiserlich-dev/pi-session-search",
|
|
16
|
-
maxNodeMajor: MAX_NATIVE_PACKAGE_NODE_MAJOR,
|
|
17
|
-
},
|
|
18
12
|
};
|
|
19
|
-
function parseNodeMajor(version) {
|
|
20
|
-
return Number.parseInt(version.replace(/^v/, "").split(".")[0] ?? "0", 10) || 0;
|
|
21
|
-
}
|
|
22
|
-
export function supportsNativePackageSources(version = process.versions.node) {
|
|
23
|
-
return parseNodeMajor(version) <= MAX_NATIVE_PACKAGE_NODE_MAJOR;
|
|
24
|
-
}
|
|
25
13
|
export function normalizeOptionalPackagePresetName(name) {
|
|
26
14
|
const normalized = name.trim().toLowerCase();
|
|
27
15
|
return normalized in OPTIONAL_PACKAGE_PRESETS ? normalized : undefined;
|
|
28
16
|
}
|
|
29
|
-
export function
|
|
30
|
-
const preset = OPTIONAL_PACKAGE_PRESETS[name];
|
|
31
|
-
return !preset.maxNodeMajor || parseNodeMajor(version) <= preset.maxNodeMajor;
|
|
32
|
-
}
|
|
33
|
-
export function listOptionalPackagePresets(version = process.versions.node) {
|
|
17
|
+
export function listOptionalPackagePresets() {
|
|
34
18
|
return Object.keys(OPTIONAL_PACKAGE_PRESETS)
|
|
35
|
-
.filter((name) => isOptionalPackagePresetSupported(name, version))
|
|
36
19
|
.map((name) => ({ name, ...OPTIONAL_PACKAGE_PRESETS[name] }));
|
|
37
20
|
}
|
|
38
21
|
export function resolvePackageSource(name) {
|
|
@@ -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
|
-
|
|
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
|
|
29
|
-
|
|
30
|
-
? "
|
|
31
|
-
:
|
|
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/metadata/commands.mjs
CHANGED
|
@@ -54,8 +54,8 @@ export const livePackageCommandGroups = [
|
|
|
54
54
|
title: "Live Package Commands",
|
|
55
55
|
commands: [
|
|
56
56
|
{ name: "search", usage: "/search" },
|
|
57
|
-
{ name: "
|
|
58
|
-
{ name: "
|
|
57
|
+
{ name: "websearch", usage: "/websearch" },
|
|
58
|
+
{ name: "curator", usage: "/curator" },
|
|
59
59
|
{ name: "hotkeys", usage: "/hotkeys" },
|
|
60
60
|
{ name: "new", usage: "/new" },
|
|
61
61
|
{ name: "quit", usage: "/quit" },
|
|
@@ -161,6 +161,7 @@ export const legacyFlags = [
|
|
|
161
161
|
{ usage: "--session <path|id>", description: "Open a specific session." },
|
|
162
162
|
{ usage: "--fork <path|id>", description: "Fork a session into a new one." },
|
|
163
163
|
{ usage: "--no-session", description: "Use an in-memory session that is not persisted." },
|
|
164
|
+
{ usage: "--no-themes", description: "Skip theme loading (passed by ACP adapters such as pi-acp)." },
|
|
164
165
|
{ usage: "--export <session.jsonl> [out.html]", description: "Export a session file to HTML and exit." },
|
|
165
166
|
{ usage: "--doctor", description: "Alias for `feynman doctor`." },
|
|
166
167
|
{ usage: "--setup-preview", description: "Alias for `feynman setup preview`." },
|
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@companion-ai/feynman",
|
|
3
|
-
"version": "0.5.
|
|
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
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
99
|
-
"tsx": "^4.23.
|
|
98
|
+
"@types/node": "^26.6.2",
|
|
99
|
+
"tsx": "^4.23.15",
|
|
100
100
|
"typescript": "^7.0.2",
|
|
101
|
-
"yaml": "2.9.
|
|
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
|
-
|
|
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
|
|
30
|
-
|
|
31
|
-
? "
|
|
32
|
-
:
|
|
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
|
-
|
|
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
|
}
|
package/scripts/check-pi-rpc.mjs
CHANGED
|
@@ -12,7 +12,8 @@ const appRoot = realpathSync(resolve(feynmanBin, "..", ".."));
|
|
|
12
12
|
const home = mkdtempSync(join(tmpdir(), "feynman-rpc-"));
|
|
13
13
|
const env = { ...process.env, FEYNMAN_HOME: home, HOME: home, USERPROFILE: home, FEYNMAN_TELEMETRY: "0", PI_OFFLINE: "1" };
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
// --no-themes is what ACP adapters such as pi-acp pass; Feynman must accept it.
|
|
16
|
+
const child = spawn(process.execPath, [feynmanBin, "--mode", "rpc", "--no-session", "--no-themes"], { cwd: home, env });
|
|
16
17
|
let stdout = "";
|
|
17
18
|
let stderr = "";
|
|
18
19
|
child.stderr.on("data", (chunk) => { stderr += chunk; });
|
|
@@ -5,7 +5,7 @@ description: Search, read, and query research papers via Feynman's alphaXiv-back
|
|
|
5
5
|
|
|
6
6
|
# Alpha Research CLI
|
|
7
7
|
|
|
8
|
-
Use visible Feynman alpha tools when they are available. For shell commands, use `feynman alpha ...`; do not call the user's bare global `alpha` binary because it can be stale
|
|
8
|
+
Use visible Feynman alpha tools when they are available. For shell commands, use `feynman alpha ...`; do not call the user's bare global `alpha` binary because it can be stale.
|
|
9
9
|
|
|
10
10
|
## Commands
|
|
11
11
|
|
|
@@ -7,6 +7,6 @@ description: Bounded research experiment loop that tries hypotheses, measures be
|
|
|
7
7
|
|
|
8
8
|
Run the `/autoresearch` workflow. The slash command expands the full workflow instructions in the active session; do not try to read a relative prompt-template path from the installed skill directory.
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
Run the benchmark through the shell and record each result, its evidence, and the keep/revert decision in the session files.
|
|
11
11
|
|
|
12
12
|
Session files: `autoresearch.md`, `autoresearch.sh`, `autoresearch.jsonl`
|
package/skills/preview/SKILL.md
CHANGED
|
@@ -1,29 +1,16 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: preview
|
|
3
|
-
description:
|
|
3
|
+
description: Render Markdown or LaTeX research artifacts to HTML or PDF with pandoc. Use when the user wants to review a written artifact, export a report, or view a rendered document.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Preview
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
## Commands
|
|
11
|
-
|
|
12
|
-
| Command | Description |
|
|
13
|
-
|---------|-------------|
|
|
14
|
-
| `/preview` | Preview the most recent artifact in the browser, when available |
|
|
15
|
-
| `/preview --file <path>` | Preview a specific file, when available |
|
|
16
|
-
| `/preview-browser` | Force browser preview, when available |
|
|
17
|
-
| `/preview-pdf` | Export to PDF via pandoc + LaTeX, when available |
|
|
18
|
-
| `/preview-clear-cache` | Clear rendered preview cache, when available |
|
|
19
|
-
|
|
20
|
-
## Fallback
|
|
21
|
-
|
|
22
|
-
If the preview commands are not available, use bash:
|
|
8
|
+
Render Markdown or LaTeX artifacts with pandoc through the shell. `feynman setup preview` checks for pandoc, and `feynman doctor` reports whether it is available.
|
|
23
9
|
|
|
24
10
|
```bash
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
pandoc input.md -o output.pdf
|
|
11
|
+
pandoc outputs/<slug>.md -s -o outputs/<slug>.html # HTML
|
|
12
|
+
pandoc outputs/<slug>.md -o outputs/<slug>.pdf # PDF (needs a LaTeX engine)
|
|
13
|
+
open outputs/<slug>.html # macOS; xdg-open on Linux
|
|
29
14
|
```
|
|
15
|
+
|
|
16
|
+
Rendered HTML and PDF files are previews; the Markdown artifact stays canonical. If pandoc or a LaTeX engine is missing, say so and leave the Markdown artifact as the deliverable.
|
|
@@ -1,26 +1,15 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: session-search
|
|
3
|
-
description:
|
|
3
|
+
description: Search prior Feynman session transcripts on disk. Use when the user asks about earlier research sessions, past findings, or wants to resume a prior session.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Session Search
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
## Interactive search
|
|
11
|
-
|
|
12
|
-
```
|
|
13
|
-
/search <query>
|
|
14
|
-
```
|
|
15
|
-
|
|
16
|
-
Opens the session search UI when the optional package is loaded. Supports `resume <sessionPath>` to continue a found session.
|
|
17
|
-
|
|
18
|
-
## Direct file search
|
|
19
|
-
|
|
20
|
-
Session transcripts are stored as JSONL files in `~/.feynman/sessions/`. Each line is a JSON record with `type` (session, message, model_change) and `message.content` fields.
|
|
8
|
+
Feynman stores session transcripts as JSONL files under `~/.feynman/sessions/` (or `$FEYNMAN_HOME/.feynman/sessions/`). Each line is a JSON record with a `type` (session, message, model_change) and, for messages, `message.content`.
|
|
21
9
|
|
|
22
10
|
```bash
|
|
23
|
-
grep -ril "scaling laws" ~/.feynman/sessions/
|
|
11
|
+
grep -ril "scaling laws" ~/.feynman/sessions/ # sessions that mention a topic
|
|
12
|
+
grep -il "scaling laws" -r ~/.feynman/sessions/ | xargs ls -t # newest first
|
|
24
13
|
```
|
|
25
14
|
|
|
26
|
-
|
|
15
|
+
To continue a session you found, run `feynman --session <path>` or pick it with `feynman --resume`.
|