research-copilot 0.2.9 → 0.2.10
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 +42 -34
- package/app/out/main/index.mjs +42 -7
- package/app/out/preload/index.js +3 -2
- package/app/out/renderer/assets/{MilkdownMarkdownEditor-CK0d0F6d.js → MilkdownMarkdownEditor-De2Q1dek.js} +50 -50
- package/app/out/renderer/assets/{arc-CgrgxBD6.js → arc-C6EUFV_N.js} +1 -1
- package/app/out/renderer/assets/{blockDiagram-c4efeb88-BqZGW4Le.js → blockDiagram-c4efeb88-DPxImKGD.js} +8 -8
- package/app/out/renderer/assets/{c4Diagram-c83219d4-gNbl9eSr.js → c4Diagram-c83219d4-VnazgZ1X.js} +3 -3
- package/app/out/renderer/assets/{channel-vUNI1iNi.js → channel-DC2lk7Hf.js} +1 -1
- package/app/out/renderer/assets/{classDiagram-beda092f-jMkGJ9Ey.js → classDiagram-beda092f-CH4Xea-4.js} +6 -6
- package/app/out/renderer/assets/{classDiagram-v2-2358418a-CNuFkLzW.js → classDiagram-v2-2358418a-DQAT-8KP.js} +10 -10
- package/app/out/renderer/assets/{clone-rSI1fs-P.js → clone-DmzuvEez.js} +1 -1
- package/app/out/renderer/assets/{createText-1719965b-BXIo6gGa.js → createText-1719965b-DipiQz-3.js} +2 -2
- package/app/out/renderer/assets/{edges-96097737-nhmklBMU.js → edges-96097737-DMCNYzh0.js} +3 -3
- package/app/out/renderer/assets/{erDiagram-0228fc6a-DAEu9LLq.js → erDiagram-0228fc6a-BCYmzg3a.js} +5 -5
- package/app/out/renderer/assets/{flowDb-c6c81e3f-BCxc52Bt.js → flowDb-c6c81e3f-Dd2eD_J_.js} +1 -1
- package/app/out/renderer/assets/{flowDiagram-50d868cf-DAeMm-oV.js → flowDiagram-50d868cf-Cm_pVS1l.js} +12 -12
- package/app/out/renderer/assets/{flowDiagram-v2-4f6560a1-B3DiSW7H.js → flowDiagram-v2-4f6560a1-DmnPUt4m.js} +12 -12
- package/app/out/renderer/assets/{flowchart-elk-definition-6af322e1-C3U45hIj.js → flowchart-elk-definition-6af322e1-CWmjyrNl.js} +6 -6
- package/app/out/renderer/assets/{ganttDiagram-a2739b55-DH_BJl1v.js → ganttDiagram-a2739b55-zezz97ZG.js} +3 -3
- package/app/out/renderer/assets/{gitGraphDiagram-82fe8481-BQYI6jwt.js → gitGraphDiagram-82fe8481-B8AuyyHK.js} +2 -2
- package/app/out/renderer/assets/{graph-Cbmv2S9S.js → graph-CeW0ZYF_.js} +1 -1
- package/app/out/renderer/assets/{index-5325376f-tk-JBjUy.js → index-5325376f-ytL7PjAX.js} +6 -6
- package/app/out/renderer/assets/{index-Dk6CqgIG.js → index-Ay1x5fGf.js} +5 -5
- package/app/out/renderer/assets/{index-DcOi0itd.js → index-B0IaCM06.js} +111 -27
- package/app/out/renderer/assets/{index-ByH1hCUC.js → index-B0uWkIRD.js} +4 -4
- package/app/out/renderer/assets/{index-BTNmK-qR.js → index-B75z0HLs.js} +3 -3
- package/app/out/renderer/assets/{index-BkmP_G4w.js → index-BKsFANZc.js} +3 -3
- package/app/out/renderer/assets/{index-C4WNjCL0.js → index-Bvn-V7yR.js} +6 -6
- package/app/out/renderer/assets/{index-B05MKQl-.js → index-BvnI1484.js} +3 -3
- package/app/out/renderer/assets/{index-Bg6-UTvh.js → index-C-qLsVVB.js} +3 -3
- package/app/out/renderer/assets/{index-HX-NQu3g.js → index-C6pCLMcd.js} +6 -6
- package/app/out/renderer/assets/{index-Do8kanBG.js → index-C776N_wX.js} +1 -1
- package/app/out/renderer/assets/{index-DK2BzNnx.js → index-C7QDCbIv.js} +3 -3
- package/app/out/renderer/assets/{index-CqAzD5Mv.js → index-C9i71nBq.js} +6 -6
- package/app/out/renderer/assets/{index-DbWCHQ2E.js → index-CH0Tw6y0.js} +3 -3
- package/app/out/renderer/assets/{index-CdhMP7aL.js → index-CtSJ0GcR.js} +3 -3
- package/app/out/renderer/assets/{index--rks7CK0.js → index-CwqgQS0P.js} +3 -3
- package/app/out/renderer/assets/{index-QjeQ3sgb.js → index-CxruKWgd.js} +3 -3
- package/app/out/renderer/assets/{index-LbAr_1fx.css → index-D4U0VRks.css} +20 -0
- package/app/out/renderer/assets/{index-BdSZkB2P.js → index-DCzv5EHR.js} +4 -4
- package/app/out/renderer/assets/{index-BaHR_2Nj.js → index-DO8xKLcA.js} +3 -3
- package/app/out/renderer/assets/{index-DU4yTtXH.js → index-DfC33JyY.js} +3 -3
- package/app/out/renderer/assets/{index-DCdUaSNI.js → index-Dqp-JFMN.js} +3 -3
- package/app/out/renderer/assets/{index-hDvDO954.js → index-ETc6uiKn.js} +6 -6
- package/app/out/renderer/assets/{index-xqpIz9Nc.js → index-qA_Cm2qi.js} +6 -6
- package/app/out/renderer/assets/{index-BgoqHomD.js → index-rCpjMSg4.js} +6 -6
- package/app/out/renderer/assets/{infoDiagram-8eee0895-B7stNUSw.js → infoDiagram-8eee0895-C7ulMekA.js} +2 -2
- package/app/out/renderer/assets/{journeyDiagram-c64418c1-BmjjCYfG.js → journeyDiagram-c64418c1-B6EiRrRb.js} +4 -4
- package/app/out/renderer/assets/{layout-BwUXWB3n.js → layout-BQe3Guvd.js} +2 -2
- package/app/out/renderer/assets/{line-DAwxPIOb.js → line-DKt3MOVb.js} +1 -1
- package/app/out/renderer/assets/{linear-DF3tF_pi.js → linear-BkgDruk7.js} +1 -1
- package/app/out/renderer/assets/{mindmap-definition-8da855dc-Dcm6UXzX.js → mindmap-definition-8da855dc-B_OxB2wg.js} +3 -3
- package/app/out/renderer/assets/{pieDiagram-a8764435-DkGcoK7i.js → pieDiagram-a8764435-Cs6G_wWV.js} +3 -3
- package/app/out/renderer/assets/{quadrantDiagram-1e28029f-C1Q8r814.js → quadrantDiagram-1e28029f-CBOijGWr.js} +3 -3
- package/app/out/renderer/assets/{requirementDiagram-08caed73-C83u7Zho.js → requirementDiagram-08caed73-BWmZFvbN.js} +5 -5
- package/app/out/renderer/assets/{sankeyDiagram-a04cb91d-CmjgGu4H.js → sankeyDiagram-a04cb91d-Dz86q9nr.js} +2 -2
- package/app/out/renderer/assets/{sequenceDiagram-c5b8d532-B0tN0kuE.js → sequenceDiagram-c5b8d532-rgC0xuyv.js} +3 -3
- package/app/out/renderer/assets/{stateDiagram-1ecb1508-CvChhiL2.js → stateDiagram-1ecb1508-CUEUbsGu.js} +6 -6
- package/app/out/renderer/assets/{stateDiagram-v2-c2b004d7-DuV4iLKk.js → stateDiagram-v2-c2b004d7-CnX14ipk.js} +10 -10
- package/app/out/renderer/assets/{styles-b4e223ce-CYC1lyng.js → styles-b4e223ce-DoXfPoT8.js} +1 -1
- package/app/out/renderer/assets/{styles-ca3715f6-wbpEm70M.js → styles-ca3715f6-C9YwWiKc.js} +1 -1
- package/app/out/renderer/assets/{styles-d45a18b0-dtPSe0gc.js → styles-d45a18b0-BnKt7kQ1.js} +4 -4
- package/app/out/renderer/assets/{svgDrawCommon-b86b1483-DeFjfiKP.js → svgDrawCommon-b86b1483-Bz6F-KWS.js} +1 -1
- package/app/out/renderer/assets/{timeline-definition-faaaa080-WkpCNoL6.js → timeline-definition-faaaa080-Dc1X0wkq.js} +3 -3
- package/app/out/renderer/assets/{xychartDiagram-f5964ef8-DhjmJVco.js → xychartDiagram-f5964ef8-DOBthtKy.js} +5 -5
- package/app/out/renderer/index.html +2 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Research Copilot
|
|
2
2
|
|
|
3
|
-
An AI-powered desktop research assistant for scientists and academics. Literature search, data analysis, academic writing, and project management — all in one
|
|
3
|
+
An AI-powered desktop research assistant for scientists and academics. Literature search, data analysis, academic writing, cross-project paper memory, and project management — powered by your **ChatGPT Pro / Claude Max subscription** (or an API key), all in one desktop app.
|
|
4
4
|
|
|
5
5
|
Built on [pi-mono](https://github.com/badlogic/pi-mono) (agent runtime) + Electron + React.
|
|
6
6
|
|
|
@@ -8,36 +8,42 @@ Built on [pi-mono](https://github.com/badlogic/pi-mono) (agent runtime) + Electr
|
|
|
8
8
|
|
|
9
9
|
---
|
|
10
10
|
|
|
11
|
-
##
|
|
11
|
+
## Signing in (READ THIS FIRST)
|
|
12
12
|
|
|
13
|
-
Research Copilot
|
|
13
|
+
Research Copilot supports three auth methods and automatically prefers the cheapest working one. When multiple are configured, priority is:
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
**ChatGPT subscription → Claude subscription → OpenAI API key → Anthropic API key**
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
# ===== REQUIRED (at least one) =====
|
|
19
|
-
export OPENAI_API_KEY="sk-..." # For OpenAI models (GPT-4o, GPT-5, o3, etc.)
|
|
20
|
-
export ANTHROPIC_API_KEY="sk-ant-..." # For Anthropic models (Claude Sonnet, Opus, etc.)
|
|
17
|
+
First-launch model selection follows this order; you can override it any time from the model selector.
|
|
21
18
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
19
|
+
### Option 1 — Sign in with a subscription (recommended)
|
|
20
|
+
|
|
21
|
+
The fastest and most cost-predictable path. No API key needed, no metered billing surprises.
|
|
22
|
+
|
|
23
|
+
- **ChatGPT Pro / Plus** — click the model selector, pick a `GPT-5.4 (sub)` entry, sign in via OAuth. Uses the official ChatGPT subscription endpoint.
|
|
24
|
+
- **Claude Pro / Max** — click the model selector, pick a `Claude … (sub)` entry, sign in via OAuth. Uses the official Anthropic subscription endpoint. *(Previously gated behind `ENABLE_CLAUDE_SUB=1`; enabled by default since `0235a3f`.)*
|
|
26
25
|
|
|
27
|
-
|
|
26
|
+
Credentials are stored in the OS keychain via pi-ai's OAuth helper and refreshed automatically.
|
|
28
27
|
|
|
29
|
-
###
|
|
28
|
+
### Option 2 — Bring an API key
|
|
29
|
+
|
|
30
|
+
Open the unified settings panel (**Cmd+.**) and paste a key, or set it in your shell profile:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
export OPENAI_API_KEY="sk-..." # GPT-5.4, GPT-4o, o-series
|
|
34
|
+
export ANTHROPIC_API_KEY="sk-ant-..." # Claude Opus / Sonnet / Haiku
|
|
35
|
+
```
|
|
30
36
|
|
|
31
|
-
|
|
32
|
-
|-----|-----------|---------------|------------|
|
|
33
|
-
| `OPENAI_API_KEY` | **Yes** (if using OpenAI models) | Core AI agent — all chat, coding, writing, analysis | App cannot start the agent. You'll see an error dialog on first message. |
|
|
34
|
-
| `ANTHROPIC_API_KEY` | **Yes** (if using Anthropic models) | Core AI agent (same as above, for Claude models) | Same — agent won't initialize for Claude models. |
|
|
35
|
-
| `BRAVE_API_KEY` | Recommended | `web_search` tool — general web search via Brave Search | **Graceful fallback**: web search automatically degrades to arXiv-only (academic papers). No general web results. |
|
|
36
|
-
| `OPENROUTER_API_KEY` | Optional | `scientific-schematics` skill — AI-generated diagrams, flowcharts, graphical abstracts | The schematics skill fails when invoked. All other skills (writing, visualization, data analysis) work fine. |
|
|
37
|
+
Keys entered in the UI are saved to `~/.research-copilot/config.json`.
|
|
37
38
|
|
|
38
|
-
|
|
39
|
+
### Optional supporting keys
|
|
39
40
|
|
|
40
|
-
|
|
41
|
+
| Key | Enhances | Without it |
|
|
42
|
+
|-----|----------|------------|
|
|
43
|
+
| `BRAVE_API_KEY` | `web_search` tool — general web search via Brave | Falls back gracefully to arXiv-only academic search |
|
|
44
|
+
| `OPENROUTER_API_KEY` | `scientific-schematics` skill — AI-generated diagrams | The schematics skill fails when invoked; all other skills still work |
|
|
45
|
+
|
|
46
|
+
> **Semantic Scholar, arXiv, OpenAlex, DBLP**: used for literature search and **do not require API keys**. They work out of the box.
|
|
41
47
|
|
|
42
48
|
---
|
|
43
49
|
|
|
@@ -55,8 +61,10 @@ Research Copilot is a **vertical tool built specifically for academic research**
|
|
|
55
61
|
| **Academic writing** | Generic document drafting | Venue-specific templates (NeurIPS, ICML, journals), IMRAD structure, LaTeX, citation verification (never hallucinated) |
|
|
56
62
|
| **Grant writing** | None | Agency-specific guidance (NSF, NIH, DOE, DARPA, NSTC) with compliance checklists |
|
|
57
63
|
| **Data analysis** | Extracts data from documents | LLM-generated Python scripts with statistical modeling, matplotlib/seaborn visualization, and output manifests |
|
|
58
|
-
| **Domain skills** | General capabilities |
|
|
64
|
+
| **Domain skills** | General capabilities | 14 pluggable research skills (scientific writing, visualization, scholar evaluation, paper revision, slides, etc.) — extensible via Markdown |
|
|
65
|
+
| **Cross-project memory** | Per-conversation only | Background **Paper Wiki** agent that indexes every paper you touch into a local, concept-organized knowledge base shared across all your projects |
|
|
59
66
|
| **Knowledge persistence** | Not specified | Artifact store, session summaries, cross-session memory, @-mention references |
|
|
67
|
+
| **Auth** | Claude subscription only | **ChatGPT Pro / Claude Max** via OAuth *or* OpenAI / Anthropic API keys — priority-ordered so subscriptions are preferred automatically |
|
|
60
68
|
| **Openness** | Closed-source commercial product | Open source (MIT) — fully customizable |
|
|
61
69
|
|
|
62
70
|
**In short**: Claude Cowork is like a smart office assistant. Research Copilot is like a lab partner who knows how to search literature, run stats, write papers, and apply for grants.
|
|
@@ -73,8 +81,13 @@ Search across **Semantic Scholar**, **arXiv**, **OpenAlex**, and **DBLP** simult
|
|
|
73
81
|
|
|
74
82
|

|
|
75
83
|
|
|
84
|
+
### Cross-Project Paper Wiki
|
|
85
|
+
A background agent that turns every paper you've ever opened into a **local, concept-organized knowledge base** shared across all your projects. Each paper gets a summarized wiki page; recurring concepts get their own pages with back-references to the papers that mention them. The wiki is searchable from any project via `wiki_search` / `wiki_get` / `wiki_coverage` tools, so the AI can recall and cite work from earlier projects without you re-feeding it context.
|
|
86
|
+
|
|
87
|
+
The wiki runs offline and **is disabled by default** — it consumes LLM tokens (roughly 8K–25K input / 2K–4K output per paper), so you opt in from the Settings panel and pick a model you're comfortable paying for. Subscription-backed models are recommended; an "Auto" option follows the system-wide priority (sub before API key). Identity drift across DOI/arXiv/title lookups is reconciled automatically so papers don't get reprocessed.
|
|
88
|
+
|
|
76
89
|
### Extensible Skills System
|
|
77
|
-
Skills are lazy-loaded knowledge modules that give the AI domain expertise. The app ships with
|
|
90
|
+
Skills are lazy-loaded knowledge modules that give the AI domain expertise. The app ships with **14 builtin skills** covering academic writing (paper-writing, paper-revision, research-grants, rewrite-humanize, scientific-writing, scholar-evaluation), visualization (matplotlib, seaborn, scientific-schematics, scientific-visualization, marp-slides), research ideation (brainstorming, creative-thinking), and general coding. You can also add your own project-specific skills as plain Markdown files.
|
|
78
91
|
|
|
79
92
|
### File Attachments in Chat
|
|
80
93
|
Attach files directly in the chat input via the paperclip button, drag & drop, or paste. Supported formats:
|
|
@@ -96,7 +109,8 @@ Attach files directly in the chat input via the paperclip button, drag & drop, o
|
|
|
96
109
|
- **@-mention system** — reference entities inline in chat
|
|
97
110
|
- **Session continuity** — automatic context compaction and session summaries
|
|
98
111
|
- **Integrated terminal** — run commands without leaving the app
|
|
99
|
-
- **LLM providers** — OpenAI and Anthropic
|
|
112
|
+
- **LLM providers** — OpenAI and Anthropic, via ChatGPT Pro / Claude Max subscription OAuth *or* API keys, with automatic priority selection
|
|
113
|
+
- **Unified settings panel** — `Cmd+.` opens a single pane for models, API keys, research presets, data-analysis timeouts, and the Paper Wiki agent
|
|
100
114
|
|
|
101
115
|
## Prerequisites
|
|
102
116
|
|
|
@@ -123,17 +137,11 @@ npm install
|
|
|
123
137
|
npm run dev
|
|
124
138
|
```
|
|
125
139
|
|
|
126
|
-
###
|
|
127
|
-
|
|
128
|
-
On first launch, the app will prompt you to enter your API keys directly in the UI. Keys are saved to `~/.research-copilot/config.json`.
|
|
140
|
+
### Authentication
|
|
129
141
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
```bash
|
|
133
|
-
export ANTHROPIC_API_KEY="sk-ant-..." # or OPENAI_API_KEY="sk-..."
|
|
134
|
-
```
|
|
142
|
+
On first launch, open the model selector (top of the chat pane) and either **sign in** with ChatGPT Pro / Claude Max via OAuth, or paste an `OPENAI_API_KEY` / `ANTHROPIC_API_KEY` into the unified settings panel (`Cmd+.`). Everything else is optional.
|
|
135
143
|
|
|
136
|
-
See [
|
|
144
|
+
See [Signing in](#signing-in-read-this-first) above for the full breakdown and optional supporting keys.
|
|
137
145
|
|
|
138
146
|
### Build for Production
|
|
139
147
|
|
package/app/out/main/index.mjs
CHANGED
|
@@ -222,6 +222,7 @@ function registerConfigHandlers(handleRaw) {
|
|
|
222
222
|
}
|
|
223
223
|
return result;
|
|
224
224
|
});
|
|
225
|
+
handleRaw("config:pick-preferred-model", () => pickPreferredModelId());
|
|
225
226
|
handleRaw("config:save-api-key", (keyName, value) => {
|
|
226
227
|
if (!API_KEY_NAMES.includes(keyName)) {
|
|
227
228
|
return { success: false, error: `Unknown key: ${keyName}` };
|
|
@@ -256,6 +257,13 @@ function hasLlmAuth() {
|
|
|
256
257
|
const hasAnthropicSub = !!loadAnthropicSubCredentials();
|
|
257
258
|
return hasAnthropicKey || hasOpenaiKey || hasCodex || hasAnthropicSub;
|
|
258
259
|
}
|
|
260
|
+
function pickPreferredModelId() {
|
|
261
|
+
if (loadCodexCredentials()) return "openai-codex:gpt-5.4";
|
|
262
|
+
if (loadAnthropicSubCredentials()) return "anthropic-sub:claude-opus-4-6";
|
|
263
|
+
if ((process.env.OPENAI_API_KEY || "").trim()) return "openai:gpt-5.4";
|
|
264
|
+
if ((process.env.ANTHROPIC_API_KEY || "").trim()) return "anthropic:claude-opus-4-6";
|
|
265
|
+
return null;
|
|
266
|
+
}
|
|
259
267
|
function registerSettingsHandlers(handleRaw) {
|
|
260
268
|
handleRaw("config:has-llm-auth", () => hasLlmAuth());
|
|
261
269
|
handleRaw("settings:load", () => loadSettingsFromConfig());
|
|
@@ -879,6 +887,22 @@ const PATHS = {
|
|
|
879
887
|
// Local compute runs
|
|
880
888
|
computeRuns: ".research-pilot/compute-runs"
|
|
881
889
|
};
|
|
890
|
+
const _warnedReaddirPaths = /* @__PURE__ */ new Set();
|
|
891
|
+
function safeReaddir(dir) {
|
|
892
|
+
try {
|
|
893
|
+
return readdirSync$1(dir);
|
|
894
|
+
} catch (err) {
|
|
895
|
+
const code = err?.code;
|
|
896
|
+
if (code === "EPERM" || code === "ENOENT" || code === "ENOTDIR" || code === "EACCES") {
|
|
897
|
+
if (!_warnedReaddirPaths.has(dir)) {
|
|
898
|
+
_warnedReaddirPaths.add(dir);
|
|
899
|
+
console.warn(`[memory-v2] cannot read artifact dir (${code}): ${dir}`);
|
|
900
|
+
}
|
|
901
|
+
return [];
|
|
902
|
+
}
|
|
903
|
+
throw err;
|
|
904
|
+
}
|
|
905
|
+
}
|
|
882
906
|
function nowIso() {
|
|
883
907
|
return (/* @__PURE__ */ new Date()).toISOString();
|
|
884
908
|
}
|
|
@@ -980,7 +1004,7 @@ function migrateLegacyArtifacts(projectPath) {
|
|
|
980
1004
|
let removedDataNameField = 0;
|
|
981
1005
|
for (const { dir } of dirs) {
|
|
982
1006
|
if (!existsSync(dir)) continue;
|
|
983
|
-
for (const file of
|
|
1007
|
+
for (const file of safeReaddir(dir)) {
|
|
984
1008
|
if (!file.endsWith(".json")) continue;
|
|
985
1009
|
const filePath = join(dir, file);
|
|
986
1010
|
let raw;
|
|
@@ -1100,7 +1124,7 @@ function listArtifacts(projectPath, types) {
|
|
|
1100
1124
|
for (const { type, dir } of dirs) {
|
|
1101
1125
|
if (typeSet && !typeSet.has(type)) continue;
|
|
1102
1126
|
if (!existsSync(dir)) continue;
|
|
1103
|
-
for (const file of
|
|
1127
|
+
for (const file of safeReaddir(dir)) {
|
|
1104
1128
|
if (!file.endsWith(".json")) continue;
|
|
1105
1129
|
const artifact = readArtifactFromFile(join(dir, file));
|
|
1106
1130
|
if (!artifact) continue;
|
|
@@ -1113,7 +1137,7 @@ function findArtifactById(projectPath, artifactId) {
|
|
|
1113
1137
|
const dirs = resolveArtifactDirs(projectPath);
|
|
1114
1138
|
for (const { dir } of dirs) {
|
|
1115
1139
|
if (!existsSync(dir)) continue;
|
|
1116
|
-
for (const file of
|
|
1140
|
+
for (const file of safeReaddir(dir)) {
|
|
1117
1141
|
if (!file.endsWith(".json")) continue;
|
|
1118
1142
|
const fullPath = join(dir, file);
|
|
1119
1143
|
const artifact = readArtifactFromFile(fullPath);
|
|
@@ -1222,7 +1246,7 @@ function writeSessionSummary(projectPath, summary) {
|
|
|
1222
1246
|
function readLatestSessionSummary(projectPath, sessionId) {
|
|
1223
1247
|
const dir = join(projectPath, PATHS.sessionSummaries, sessionId);
|
|
1224
1248
|
if (!existsSync(dir)) return null;
|
|
1225
|
-
const files =
|
|
1249
|
+
const files = safeReaddir(dir).filter((f) => f.endsWith(".json"));
|
|
1226
1250
|
if (files.length === 0) return null;
|
|
1227
1251
|
files.sort((a, b) => {
|
|
1228
1252
|
const na = parseInt(a, 10);
|
|
@@ -12838,11 +12862,22 @@ function registerIpcHandlers() {
|
|
|
12838
12862
|
registerFolderOpenHandler(sharedHandle, getCtx);
|
|
12839
12863
|
(async () => {
|
|
12840
12864
|
const wikiSettings = loadSettingsFromConfig().wikiAgent;
|
|
12841
|
-
|
|
12865
|
+
let wikiModel = wikiSettings?.model ?? "none";
|
|
12866
|
+
if (wikiModel === "auto") {
|
|
12867
|
+
const preferred = pickPreferredModelId();
|
|
12868
|
+
if (!preferred) {
|
|
12869
|
+
if (process.env.RESEARCH_COPILOT_DEBUG) {
|
|
12870
|
+
console.log("[wiki-agent] auto mode but no auth configured; skipping startup");
|
|
12871
|
+
}
|
|
12872
|
+
return;
|
|
12873
|
+
}
|
|
12874
|
+
wikiModel = preferred;
|
|
12875
|
+
}
|
|
12876
|
+
if (wikiSettings && wikiModel !== "none") {
|
|
12842
12877
|
try {
|
|
12843
12878
|
const { getModel: getPiModel, completeSimple: completeSimple2 } = await import("@mariozechner/pi-ai");
|
|
12844
|
-
const wikiAuth = resolveCoordinatorAuth(
|
|
12845
|
-
const [rawProvider, modelId] =
|
|
12879
|
+
const wikiAuth = resolveCoordinatorAuth(wikiModel);
|
|
12880
|
+
const [rawProvider, modelId] = wikiModel.split(":");
|
|
12846
12881
|
const piProvider = rawProvider === "anthropic-sub" ? "anthropic" : rawProvider;
|
|
12847
12882
|
const model = getPiModel(piProvider, modelId);
|
|
12848
12883
|
let resolveApiKey;
|
package/app/out/preload/index.js
CHANGED
|
@@ -28,11 +28,12 @@ const api = {
|
|
|
28
28
|
getOpenAICodexStatus: () => electron.ipcRenderer.invoke("auth:get-openai-codex-status"),
|
|
29
29
|
openaiCodexLogin: () => electron.ipcRenderer.invoke("auth:openai-codex-login"),
|
|
30
30
|
openaiCodexLogout: () => electron.ipcRenderer.invoke("auth:openai-codex-logout"),
|
|
31
|
-
// Anthropic Subscription (Claude Pro/Max) OAuth
|
|
32
|
-
isClaudeSubEnabled: () =>
|
|
31
|
+
// Anthropic Subscription (Claude Pro/Max) OAuth — enabled by default
|
|
32
|
+
isClaudeSubEnabled: () => true,
|
|
33
33
|
getAnthropicSubStatus: () => electron.ipcRenderer.invoke("auth:get-anthropic-sub-status"),
|
|
34
34
|
anthropicSubLogin: () => electron.ipcRenderer.invoke("auth:anthropic-sub-login"),
|
|
35
35
|
anthropicSubLogout: () => electron.ipcRenderer.invoke("auth:anthropic-sub-logout"),
|
|
36
|
+
pickPreferredModel: () => electron.ipcRenderer.invoke("config:pick-preferred-model"),
|
|
36
37
|
getApiKeyStatus: () => electron.ipcRenderer.invoke("config:get-api-key-status"),
|
|
37
38
|
saveApiKey: (keyName, value) => electron.ipcRenderer.invoke("config:save-api-key", keyName, value),
|
|
38
39
|
listNotes: () => electron.ipcRenderer.invoke("cmd:list-notes"),
|