@companion-ai/feynman 0.5.60 → 0.5.62

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/README.md CHANGED
@@ -59,7 +59,7 @@ Results are saved to `outputs/` (drafts to `papers/`). `/lit`, `/deepresearch`,
59
59
 
60
60
  ## Sources
61
61
 
62
- Feynman searches alphaXiv, Semantic Scholar, OpenAlex, arXiv, PubMed, Europe PMC, bioRxiv, medRxiv, Crossref, the web, and Hugging Face, and reads local PDFs and documents. Free `OPENALEX_API_KEY` and `SEMANTIC_SCHOLAR_API_KEY` keys avoid the shared rate limits. It runs on stock [Pi](https://github.com/earendil-works/pi) with four research agents: researcher, verifier, reviewer, and writer.
62
+ Feynman searches alphaXiv, Semantic Scholar, OpenAlex, arXiv, PubMed, Europe PMC, bioRxiv, medRxiv, Crossref, the web, and Hugging Face, and reads local PDFs and documents. Free `OPENALEX_API_KEY` and `SEMANTIC_SCHOLAR_API_KEY` keys avoid the shared rate limits. It runs on stock [Pi](https://github.com/earendil-works/pi) with four research agents: researcher, verifier, reviewer, and writer. Add your own tools, such as a Zotero library, with `feynman mcp add`.
63
63
 
64
64
  ## Telemetry
65
65
 
package/RELEASES.md CHANGED
@@ -6,6 +6,22 @@ GitHub release notes are generated from the matching `## vX.Y.Z` section in this
6
6
 
7
7
  ## Unreleased
8
8
 
9
+ ## v0.5.62 - 2026-11-03
10
+
11
+ - Parallel researcher subagents in `/deepresearch`, `/lit` and `/summarize` no longer fail with `args.tasks[0] contains unsupported fields: output`. The workflow examples in the prompts and docs no longer put an `output` field on each item; each task names its output path instead.
12
+ - **Pi 1.5.0.**
13
+ - Security: Pi now ships `undici` 8.12.3 and `minimatch` 11.0.3, so the `undici` advisories on Pi 1.4.0's pinned 8.10.2 copy and the `minimatch` advisory ([GHSA-g3hv-75wg-m249](https://github.com/advisories/GHSA-g3hv-75wg-m249)) on its 10.2.6 copy are gone. Feynman's release audit has no exceptions again.
14
+ - Long streamed tool calls and code-heavy answers use much less CPU: arguments are parsed once per delta, and highlighting and rendered Markdown are reused instead of redone on every update.
15
+ - Tool arguments are validated with Pi's new schema library. A single value where a list is expected (for example one paper section) is now wrapped into a list instead of being rejected, and validation errors read `- paper: missing`.
16
+ - Claude sessions no longer fail with `role 'system' must precede an 'assistant' message` after an empty or reasoning-only reply.
17
+ - Failed session writes no longer leave resumed sessions missing earlier history.
18
+ - `pi.exec()` no longer crashes on very large command output or hangs on commands that ignore SIGTERM.
19
+ - GPT-6.1 Terra is available through OpenAI, Azure OpenAI and OpenAI Codex; with only an OpenAI key, Feynman now recommends `openai/gpt-6.1-terra`.
20
+
21
+ ## v0.5.61 - 2026-10-30
22
+
23
+ - **`feynman mcp` adds MCP servers.** Pi has built-in MCP support, but its docs say `pi mcp add`, and `feynman mcp list` used to be sent to the model as a chat question. `feynman mcp add|list|remove` now runs Pi's own command with Feynman's settings, saves servers in `~/.feynman/agent/mcp.json`, and every session loads them. For example, to use your Zotero library with [zotero-mcp](https://github.com/54yyyu/zotero-mcp): `feynman mcp add zotero --env ZOTERO_LOCAL=true -- zotero-mcp`. Pi's own output and help still say `pi mcp`; use `feynman mcp` instead.
24
+
9
25
  ## v0.5.60 - 2026-10-29
10
26
 
11
27
  - **pi-subagents 0.84.0.**
package/dist/cli.js CHANGED
@@ -461,6 +461,19 @@ async function runMain(input) {
461
461
  await runBundledAlphaCli(appRoot, alphaPassthrough.args, { cwd: alphaPassthrough.cwd });
462
462
  return;
463
463
  }
464
+ // Pi owns MCP server management; its flags (--env, --url, ...) would fail Feynman's own parser.
465
+ // Servers land in this Feynman home's agent directory, which every Feynman session loads.
466
+ if (rawArgs[0] === "mcp") {
467
+ const piOptions = {
468
+ appRoot,
469
+ workingDir: process.cwd(),
470
+ sessionDir: getDefaultSessionDir(feynmanHome),
471
+ feynmanAgentDir,
472
+ feynmanVersion,
473
+ };
474
+ process.exitCode = await runPi(piOptions, rawArgs, buildPiEnv(piOptions));
475
+ return;
476
+ }
464
477
  const parseCliArgs = () => parseArgs({
465
478
  args: process.argv.slice(2),
466
479
  allowPositionals: true,
@@ -138,6 +138,7 @@ export const cliCommandSections = [
138
138
  { usage: "feynman packages list", description: "Show core and optional Pi package presets." },
139
139
  { usage: "feynman packages install <preset>", description: "Install optional package presets on demand." },
140
140
  { usage: "feynman packages remove <preset>", description: "Remove an installed optional package preset." },
141
+ { usage: "feynman mcp <add|list|remove|...>", description: "Add and manage MCP servers, such as a Zotero library. Same as Pi's `mcp` command; servers are stored in ~/.feynman/agent/mcp.json." },
141
142
  { usage: "feynman search status", description: "Show Pi web-access status and config path." },
142
143
  { usage: "feynman search set <provider> [api-key]", description: "Set the web search provider and optionally save its API key." },
143
144
  { usage: "feynman search clear", description: "Reset web search provider to auto while preserving API keys." },
@@ -169,7 +170,7 @@ export const legacyFlags = [
169
170
  { usage: "--setup-preview", description: "Alias for `feynman setup preview`." },
170
171
  ];
171
172
 
172
- export const topLevelCommandNames = ["alpha", "chat", "doctor", "help", "model", "packages", "search", "setup", "status", "update"];
173
+ export const topLevelCommandNames = ["alpha", "chat", "doctor", "help", "mcp", "model", "packages", "search", "setup", "status", "update"];
173
174
 
174
175
  export function formatSlashUsage(command) {
175
176
  return `/${command.name}${command.args ? ` ${command.args}` : ""}`;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@companion-ai/feynman",
3
- "version": "0.5.60",
3
+ "version": "0.5.62",
4
4
  "description": "The open source AI research agent.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -79,9 +79,9 @@
79
79
  "dependencies": {
80
80
  "@clack/prompts": "^1.8.1",
81
81
  "@companion-ai/alpha-hub": "0.1.7",
82
- "@earendil-works/pi-codemode": "1.4.0",
83
- "@earendil-works/pi-mcp": "1.4.0",
84
- "@earendil-works/pi-telemetry": "1.4.0",
82
+ "@earendil-works/pi-codemode": "1.5.0",
83
+ "@earendil-works/pi-mcp": "1.5.0",
84
+ "@earendil-works/pi-telemetry": "1.5.0",
85
85
  "fast-xml-parser": "5.11.2",
86
86
  "pi-btw": "0.8.0",
87
87
  "pi-docparser": "4.0.0",
@@ -91,9 +91,9 @@
91
91
  "undici": "^8.12.3"
92
92
  },
93
93
  "peerDependencies": {
94
- "@earendil-works/pi-agent-core": "1.4.0",
95
- "@earendil-works/pi-ai": "1.4.0",
96
- "@earendil-works/pi-coding-agent": "1.4.0",
94
+ "@earendil-works/pi-agent-core": "1.5.0",
95
+ "@earendil-works/pi-ai": "1.5.0",
96
+ "@earendil-works/pi-coding-agent": "1.5.0",
97
97
  "@earendil-works/pi-tui": "*",
98
98
  "typebox": "*"
99
99
  },
@@ -64,7 +64,7 @@ If subagents were chosen:
64
64
  - Keep `subagent` tool-call JSON small and valid.
65
65
  - Do not place multi-paragraph instructions inside the `subagent` JSON.
66
66
  - Use only supported `subagent` keys. Do not add extra keys such as `artifacts` unless the tool schema explicitly exposes them.
67
- - For parallel evidence gathering, write a workflow script that returns `await runs.all(...)` to `outputs/.plans/<slug>-workflow.js` with the write tool. After the write succeeds, in a later tool call (not in parallel with the write), call `subagent` with `workflow: "./outputs/.plans/<slug>-workflow.js"`, `async: true`, and `globalConcurrencyLimit: 4`. Each item needs a unique stable `key`, plus its agent, short task, and output path. Do not pass the script text inside the tool call.
67
+ - For parallel evidence gathering, write a workflow script that returns `await runs.all(...)` to `outputs/.plans/<slug>-workflow.js` with the write tool. After the write succeeds, in a later tool call (not in parallel with the write), call `subagent` with `workflow: "./outputs/.plans/<slug>-workflow.js"`, `async: true`, and `globalConcurrencyLimit: 4`. Each item needs a unique stable `key`, plus its `agent` and a short `task` that names the output path; items take no `output` field. Do not pass the script text inside the tool call.
68
68
  - Read the ordered result array and record each child's `ok`, error, and returned output/artifact paths. Ordinary child failures are collected by `runs.all`; validation or infrastructure failure can still fail the workflow. Do not assume every output exists.
69
69
  - Prefer broad guidance such as "use paper search and web search"; if a PDF parser or paper fetch fails, the researcher must continue from metadata, abstracts, and web sources and mark PDF parsing as blocked.
70
70
 
@@ -72,8 +72,8 @@ Example shape: `outputs/.plans/<slug>-workflow.js` contains
72
72
 
73
73
  ```js
74
74
  return await runs.all([
75
- { key: "web", agent: "researcher", task: "Read outputs/.plans/<slug>-T1.md and write outputs/.drafts/<slug>-research-web.md.", output: "outputs/.drafts/<slug>-research-web.md" },
76
- { key: "papers", agent: "researcher", task: "Read outputs/.plans/<slug>-T2.md and write outputs/.drafts/<slug>-research-papers.md.", output: "outputs/.drafts/<slug>-research-papers.md" },
75
+ { key: "web", agent: "researcher", task: "Read outputs/.plans/<slug>-T1.md and write outputs/.drafts/<slug>-research-web.md." },
76
+ { key: "papers", agent: "researcher", task: "Read outputs/.plans/<slug>-T2.md and write outputs/.drafts/<slug>-research-papers.md." },
77
77
  ]);
78
78
  ```
79
79
 
@@ -83,7 +83,7 @@ and the `subagent` call is:
83
83
  { "workflow": "./outputs/.plans/<slug>-workflow.js", "async": true, "globalConcurrencyLimit": 4 }
84
84
  ```
85
85
 
86
- Continue independent work after launch, then consume completion results before synthesis. Relative output paths resolve against the workspace, so each child writes its declared path; verify each file on disk, and use the returned output reference for any that is missing. After evidence gathering, update the plan ledger and verification log. If research failed, record exactly what failed and proceed with a blocked or partial draft.
86
+ Continue independent work after launch, then consume completion results before synthesis. Relative output paths resolve against the workspace, so each child writes the path named in its task; verify each file on disk, and use the returned output reference for any that is missing. After evidence gathering, update the plan ledger and verification log. If research failed, record exactly what failed and proceed with a blocked or partial draft.
87
87
 
88
88
  ## Step 4: Draft
89
89
 
@@ -116,11 +116,11 @@ Briefly summarize: "Source is ~<chars> chars -> <N> chunks -> <N> researcher sub
116
116
 
117
117
  ### 3c. Dispatch researcher subagents
118
118
 
119
- Use one async workflow with a stable key for each chunk and a concurrency limit of four: write the script to `outputs/.plans/<slug>-workflow.js` with the write tool, then, after the write succeeds, in a later tool call, call `subagent` with `{ "workflow": "./outputs/.plans/<slug>-workflow.js", "async": true, "globalConcurrencyLimit": 4 }`. Expand the example item below for the actual chunk inventory; retain the single-source restriction and explicit output declaration for every child.
119
+ Use one async workflow with a stable key for each chunk and a concurrency limit of four: write the script to `outputs/.plans/<slug>-workflow.js` with the write tool, then, after the write succeeds, in a later tool call, call `subagent` with `{ "workflow": "./outputs/.plans/<slug>-workflow.js", "async": true, "globalConcurrencyLimit": 4 }`. Expand the example item below for the actual chunk inventory; retain the single-source restriction and name the output path inside every child's task; items take no `output` field.
120
120
 
121
121
  ```js
122
122
  return await runs.all([
123
- { key: "chunk-NNN", agent: "researcher", task: "Read ONLY outputs/.notes/<slug>-chunk-NNN.txt. Extract: (1) key claims, (2) methodology or technical approach, (3) cited evidence. Do NOT use web_search or fetch external URLs — this is single-source summarization. If a claim appears to start or end mid-sentence at the file boundary, mark it BOUNDARY PARTIAL. Write to outputs/.notes/<slug>-summary-chunk-NNN.md.", output: "outputs/.notes/<slug>-summary-chunk-NNN.md" },
123
+ { key: "chunk-NNN", agent: "researcher", task: "Read ONLY outputs/.notes/<slug>-chunk-NNN.txt. Extract: (1) key claims, (2) methodology or technical approach, (3) cited evidence. Do NOT use web_search or fetch external URLs — this is single-source summarization. If a claim appears to start or end mid-sentence at the file boundary, mark it BOUNDARY PARTIAL. Write to outputs/.notes/<slug>-summary-chunk-NNN.md." },
124
124
  ]);
125
125
  ```
126
126