psyclaw 0.25.2 → 0.26.1

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.
Files changed (271) hide show
  1. package/README.md +111 -60
  2. package/{apps → dist/apps}/panel/index.html +50 -28
  3. package/dist/src/adapters/pi/extension.d.ts +19 -0
  4. package/dist/src/adapters/pi/extension.js +735 -0
  5. package/dist/src/adapters/pi/extension.js.map +1 -0
  6. package/dist/src/adapters/pi/model.d.ts +72 -0
  7. package/dist/src/adapters/pi/model.js +152 -0
  8. package/dist/src/adapters/pi/model.js.map +1 -0
  9. package/dist/src/adapters/pi/resources.d.ts +23 -0
  10. package/dist/src/adapters/pi/resources.js +54 -0
  11. package/dist/src/adapters/pi/resources.js.map +1 -0
  12. package/dist/src/adapters/pi/rpc.d.ts +58 -0
  13. package/dist/src/adapters/pi/rpc.js +253 -0
  14. package/dist/src/adapters/pi/rpc.js.map +1 -0
  15. package/dist/src/adapters/pi/session.d.ts +30 -0
  16. package/dist/src/adapters/pi/session.js +64 -0
  17. package/dist/src/adapters/pi/session.js.map +1 -0
  18. package/dist/src/agents/catalog.d.ts +30 -0
  19. package/dist/src/agents/catalog.js +118 -0
  20. package/dist/src/agents/catalog.js.map +1 -0
  21. package/dist/src/agents/discover.d.ts +28 -0
  22. package/dist/src/agents/discover.js +127 -0
  23. package/dist/src/agents/discover.js.map +1 -0
  24. package/dist/src/agents/import.d.ts +67 -0
  25. package/dist/src/agents/import.js +789 -0
  26. package/dist/src/agents/import.js.map +1 -0
  27. package/dist/src/analysis/hooks.d.ts +81 -0
  28. package/dist/src/analysis/hooks.js +139 -0
  29. package/dist/src/analysis/hooks.js.map +1 -0
  30. package/dist/src/analysis/pre-registration.d.ts +18 -0
  31. package/dist/src/analysis/pre-registration.js +86 -0
  32. package/dist/src/analysis/pre-registration.js.map +1 -0
  33. package/dist/src/branding.d.ts +44 -0
  34. package/dist/src/branding.js +128 -0
  35. package/dist/src/branding.js.map +1 -0
  36. package/dist/src/chat.d.ts +16 -0
  37. package/dist/src/chat.js +95 -0
  38. package/dist/src/chat.js.map +1 -0
  39. package/dist/src/cli.d.ts +2 -0
  40. package/dist/src/cli.js +316 -0
  41. package/dist/src/cli.js.map +1 -0
  42. package/dist/src/core/citations.d.ts +44 -0
  43. package/dist/src/core/citations.js +48 -0
  44. package/dist/src/core/citations.js.map +1 -0
  45. package/dist/src/core/contracts.d.ts +119 -0
  46. package/dist/src/core/contracts.js +2 -0
  47. package/dist/src/core/contracts.js.map +1 -0
  48. package/dist/src/core/docx.d.ts +11 -0
  49. package/dist/src/core/docx.js +46 -0
  50. package/dist/src/core/docx.js.map +1 -0
  51. package/dist/src/core/doi.d.ts +41 -0
  52. package/dist/src/core/doi.js +82 -0
  53. package/dist/src/core/doi.js.map +1 -0
  54. package/dist/src/core/evidence-policy.d.ts +24 -0
  55. package/dist/src/core/evidence-policy.js +308 -0
  56. package/dist/src/core/evidence-policy.js.map +1 -0
  57. package/dist/src/core/filekind.d.ts +15 -0
  58. package/dist/src/core/filekind.js +82 -0
  59. package/dist/src/core/filekind.js.map +1 -0
  60. package/dist/src/core/hash.d.ts +2 -0
  61. package/dist/src/core/hash.js +17 -0
  62. package/dist/src/core/hash.js.map +1 -0
  63. package/dist/src/core/pricing.d.ts +38 -0
  64. package/dist/src/core/pricing.js +110 -0
  65. package/dist/src/core/pricing.js.map +1 -0
  66. package/dist/src/core/redact.d.ts +12 -0
  67. package/dist/src/core/redact.js +48 -0
  68. package/dist/src/core/redact.js.map +1 -0
  69. package/dist/src/core/references.d.ts +55 -0
  70. package/dist/src/core/references.js +102 -0
  71. package/dist/src/core/references.js.map +1 -0
  72. package/dist/src/core/schemas.d.ts +162 -0
  73. package/dist/src/core/schemas.js +160 -0
  74. package/dist/src/core/schemas.js.map +1 -0
  75. package/dist/src/extension.d.ts +1 -0
  76. package/dist/src/extension.js +2 -0
  77. package/dist/src/extension.js.map +1 -0
  78. package/dist/src/index.d.ts +72 -0
  79. package/dist/src/index.js +73 -0
  80. package/dist/src/index.js.map +1 -0
  81. package/dist/src/install/installer.d.ts +147 -0
  82. package/dist/src/install/installer.js +721 -0
  83. package/dist/src/install/installer.js.map +1 -0
  84. package/dist/src/integrations/contracts.d.ts +35 -0
  85. package/dist/src/integrations/contracts.js +27 -0
  86. package/dist/src/integrations/contracts.js.map +1 -0
  87. package/dist/src/integrations/mcp.d.ts +155 -0
  88. package/dist/src/integrations/mcp.js +826 -0
  89. package/dist/src/integrations/mcp.js.map +1 -0
  90. package/dist/src/knowledge-map/contracts.d.ts +20 -0
  91. package/dist/src/knowledge-map/contracts.js +2 -0
  92. package/dist/src/knowledge-map/contracts.js.map +1 -0
  93. package/dist/src/knowledge-map/index.d.ts +4 -0
  94. package/dist/src/knowledge-map/index.js +39 -0
  95. package/dist/src/knowledge-map/index.js.map +1 -0
  96. package/dist/src/literature/contracts.d.ts +106 -0
  97. package/dist/src/literature/contracts.js +2 -0
  98. package/dist/src/literature/contracts.js.map +1 -0
  99. package/dist/src/literature/fulltext.d.ts +7 -0
  100. package/dist/src/literature/fulltext.js +24 -0
  101. package/dist/src/literature/fulltext.js.map +1 -0
  102. package/dist/src/literature/knowledge-map.d.ts +2 -0
  103. package/dist/src/literature/knowledge-map.js +20 -0
  104. package/dist/src/literature/knowledge-map.js.map +1 -0
  105. package/dist/src/literature/ledger.d.ts +3 -0
  106. package/dist/src/literature/ledger.js +17 -0
  107. package/dist/src/literature/ledger.js.map +1 -0
  108. package/dist/src/literature/metadata.d.ts +6 -0
  109. package/dist/src/literature/metadata.js +32 -0
  110. package/dist/src/literature/metadata.js.map +1 -0
  111. package/dist/src/memory/store.d.ts +22 -0
  112. package/dist/src/memory/store.js +73 -0
  113. package/dist/src/memory/store.js.map +1 -0
  114. package/dist/src/orchestration/contracts.d.ts +61 -0
  115. package/dist/src/orchestration/contracts.js +2 -0
  116. package/dist/src/orchestration/contracts.js.map +1 -0
  117. package/dist/src/orchestration/pi-executor.d.ts +28 -0
  118. package/dist/src/orchestration/pi-executor.js +169 -0
  119. package/dist/src/orchestration/pi-executor.js.map +1 -0
  120. package/dist/src/orchestration/runner.d.ts +196 -0
  121. package/dist/src/orchestration/runner.js +991 -0
  122. package/dist/src/orchestration/runner.js.map +1 -0
  123. package/dist/src/orchestration/scheduler.d.ts +8 -0
  124. package/dist/src/orchestration/scheduler.js +335 -0
  125. package/dist/src/orchestration/scheduler.js.map +1 -0
  126. package/dist/src/panel/events.d.ts +20 -0
  127. package/dist/src/panel/events.js +93 -0
  128. package/dist/src/panel/events.js.map +1 -0
  129. package/dist/src/panel/extension.d.ts +8 -0
  130. package/dist/src/panel/extension.js +115 -0
  131. package/dist/src/panel/extension.js.map +1 -0
  132. package/dist/src/panel/literature-map.d.ts +26 -0
  133. package/dist/src/panel/literature-map.js +34 -0
  134. package/dist/src/panel/literature-map.js.map +1 -0
  135. package/dist/src/panel/projection.d.ts +51 -0
  136. package/dist/src/panel/projection.js +288 -0
  137. package/dist/src/panel/projection.js.map +1 -0
  138. package/dist/src/panel/server.d.ts +46 -0
  139. package/dist/src/panel/server.js +1610 -0
  140. package/dist/src/panel/server.js.map +1 -0
  141. package/dist/src/panel/usage.d.ts +53 -0
  142. package/dist/src/panel/usage.js +150 -0
  143. package/dist/src/panel/usage.js.map +1 -0
  144. package/dist/src/project/bootstrap.d.ts +10 -0
  145. package/dist/src/project/bootstrap.js +83 -0
  146. package/dist/src/project/bootstrap.js.map +1 -0
  147. package/dist/src/project/hitl.d.ts +12 -0
  148. package/dist/src/project/hitl.js +43 -0
  149. package/dist/src/project/hitl.js.map +1 -0
  150. package/dist/src/project/jsonl.d.ts +16 -0
  151. package/dist/src/project/jsonl.js +93 -0
  152. package/dist/src/project/jsonl.js.map +1 -0
  153. package/dist/src/project/manuscript.d.ts +21 -0
  154. package/dist/src/project/manuscript.js +74 -0
  155. package/dist/src/project/manuscript.js.map +1 -0
  156. package/dist/src/project/paths.d.ts +38 -0
  157. package/dist/src/project/paths.js +166 -0
  158. package/dist/src/project/paths.js.map +1 -0
  159. package/dist/src/project/versions.d.ts +10 -0
  160. package/dist/src/project/versions.js +14 -0
  161. package/dist/src/project/versions.js.map +1 -0
  162. package/dist/src/psyclaw-theme.d.ts +88 -0
  163. package/dist/src/psyclaw-theme.js +89 -0
  164. package/dist/src/psyclaw-theme.js.map +1 -0
  165. package/dist/src/research/brief.d.ts +11 -0
  166. package/dist/src/research/brief.js +81 -0
  167. package/dist/src/research/brief.js.map +1 -0
  168. package/dist/src/research/ledger.d.ts +12 -0
  169. package/dist/src/research/ledger.js +43 -0
  170. package/dist/src/research/ledger.js.map +1 -0
  171. package/dist/src/run.d.ts +20 -0
  172. package/dist/src/run.js +34 -0
  173. package/dist/src/run.js.map +1 -0
  174. package/dist/src/setup.d.ts +54 -0
  175. package/dist/src/setup.js +221 -0
  176. package/dist/src/setup.js.map +1 -0
  177. package/dist/src/skills/contracts.d.ts +105 -0
  178. package/dist/src/skills/contracts.js +3 -0
  179. package/dist/src/skills/contracts.js.map +1 -0
  180. package/dist/src/skills/preflight.d.ts +10 -0
  181. package/dist/src/skills/preflight.js +39 -0
  182. package/dist/src/skills/preflight.js.map +1 -0
  183. package/dist/src/skills/registry.d.ts +28 -0
  184. package/dist/src/skills/registry.js +540 -0
  185. package/dist/src/skills/registry.js.map +1 -0
  186. package/dist/src/style/artifact.d.ts +6 -0
  187. package/dist/src/style/artifact.js +61 -0
  188. package/dist/src/style/artifact.js.map +1 -0
  189. package/dist/src/style/cli-ui.d.ts +41 -0
  190. package/dist/src/style/cli-ui.js +119 -0
  191. package/dist/src/style/cli-ui.js.map +1 -0
  192. package/dist/src/style/contracts.d.ts +34 -0
  193. package/dist/src/style/contracts.js +2 -0
  194. package/dist/src/style/contracts.js.map +1 -0
  195. package/dist/src/style/registry.d.ts +16 -0
  196. package/dist/src/style/registry.js +50 -0
  197. package/dist/src/style/registry.js.map +1 -0
  198. package/dist/src/trust/manifest.d.ts +42 -0
  199. package/dist/src/trust/manifest.js +53 -0
  200. package/dist/src/trust/manifest.js.map +1 -0
  201. package/dist/src/trust/sbom.d.ts +54 -0
  202. package/dist/src/trust/sbom.js +77 -0
  203. package/dist/src/trust/sbom.js.map +1 -0
  204. package/dist/src/tui/app.d.ts +3 -0
  205. package/dist/src/tui/app.js +103 -0
  206. package/dist/src/tui/app.js.map +1 -0
  207. package/dist/src/tui/model.d.ts +13 -0
  208. package/dist/src/tui/model.js +25 -0
  209. package/dist/src/tui/model.js.map +1 -0
  210. package/dist/src/updates/check.d.ts +43 -0
  211. package/dist/src/updates/check.js +68 -0
  212. package/dist/src/updates/check.js.map +1 -0
  213. package/dist/src/updates/manifest.d.ts +19 -0
  214. package/dist/src/updates/manifest.js +58 -0
  215. package/dist/src/updates/manifest.js.map +1 -0
  216. package/dist/src/updates/registry.d.ts +21 -0
  217. package/dist/src/updates/registry.js +82 -0
  218. package/dist/src/updates/registry.js.map +1 -0
  219. package/dist/src/updates/skills.d.ts +15 -0
  220. package/dist/src/updates/skills.js +39 -0
  221. package/dist/src/updates/skills.js.map +1 -0
  222. package/dist/src/updates/status.d.ts +7 -0
  223. package/dist/src/updates/status.js +37 -0
  224. package/dist/src/updates/status.js.map +1 -0
  225. package/dist/src/updates/update.d.ts +43 -0
  226. package/dist/src/updates/update.js +128 -0
  227. package/dist/src/updates/update.js.map +1 -0
  228. package/dist/src/wizard.d.ts +7 -0
  229. package/dist/src/wizard.js +90 -0
  230. package/dist/src/wizard.js.map +1 -0
  231. package/dist/src/workflows/analysis-delegation.d.ts +3 -0
  232. package/dist/src/workflows/analysis-delegation.js +96 -0
  233. package/dist/src/workflows/analysis-delegation.js.map +1 -0
  234. package/dist/src/workflows/expert-review-runner.d.ts +29 -0
  235. package/dist/src/workflows/expert-review-runner.js +35 -0
  236. package/dist/src/workflows/expert-review-runner.js.map +1 -0
  237. package/dist/src/workflows/expert-review.d.ts +140 -0
  238. package/dist/src/workflows/expert-review.js +111 -0
  239. package/dist/src/workflows/expert-review.js.map +1 -0
  240. package/dist/src/workflows/institutional-fulltext.d.ts +16 -0
  241. package/dist/src/workflows/institutional-fulltext.js +110 -0
  242. package/dist/src/workflows/institutional-fulltext.js.map +1 -0
  243. package/dist/src/workflows/literature-review.d.ts +3 -0
  244. package/dist/src/workflows/literature-review.js +76 -0
  245. package/dist/src/workflows/literature-review.js.map +1 -0
  246. package/dist/src/workflows/meta-analysis.d.ts +38 -0
  247. package/dist/src/workflows/meta-analysis.js +185 -0
  248. package/dist/src/workflows/meta-analysis.js.map +1 -0
  249. package/dist/src/workflows/publish.d.ts +51 -0
  250. package/dist/src/workflows/publish.js +153 -0
  251. package/dist/src/workflows/publish.js.map +1 -0
  252. package/dist/src/workflows/spec.d.ts +51 -0
  253. package/dist/src/workflows/spec.js +157 -0
  254. package/dist/src/workflows/spec.js.map +1 -0
  255. package/dist/src/workflows/style-contract.d.ts +24 -0
  256. package/dist/src/workflows/style-contract.js +23 -0
  257. package/dist/src/workflows/style-contract.js.map +1 -0
  258. package/dist/src/workflows/writing-review.d.ts +15 -0
  259. package/dist/src/workflows/writing-review.js +82 -0
  260. package/dist/src/workflows/writing-review.js.map +1 -0
  261. package/package.json +20 -8
  262. package/scripts/rebrand-pi.mjs +3 -3
  263. package/scripts/__pycache__/build_dist.cpython-314.pyc +0 -0
  264. package/scripts/__pycache__/build_whitepaper_docx.cpython-314.pyc +0 -0
  265. package/scripts/build_preprint_docx.py +0 -729
  266. package/scripts/build_preprint_figures.py +0 -238
  267. package/scripts/build_three_line_table_fixture.py +0 -56
  268. package/scripts/build_whitepaper_docx.py +0 -768
  269. package/scripts/check-branding.mjs +0 -159
  270. package/scripts/copy-panel.mjs +0 -11
  271. package/scripts/verify_docx.py +0 -41
@@ -0,0 +1,115 @@
1
+ import { spawn } from "node:child_process";
2
+ import { createPanelServer } from "./server.js";
3
+ import { PiRpcClient } from "../adapters/pi/rpc.js";
4
+ const BROWSER_ASSISTANT_PROMPT = [
5
+ "You are the PsyClaw browser research assistant.",
6
+ "Work in a read-only mode. You may inspect project files with read, grep, find, and ls only.",
7
+ "Do not claim a statistical result, citation, or completed action without evidence.",
8
+ "When the user asks for a change or side effect, explain the proposed plan and state that approval is required.",
9
+ ].join("\n");
10
+ function assistantEnv(provider) {
11
+ const envName = provider === "deepseek" ? "DEEPSEEK_API_KEY" : provider === "openai" ? "OPENAI_API_KEY" : provider === "anthropic" ? "ANTHROPIC_API_KEY" : provider === "google" ? "GEMINI_API_KEY" : undefined;
12
+ const value = envName === undefined ? undefined : process.env[envName];
13
+ return envName !== undefined && value !== undefined ? { [envName]: value } : {};
14
+ }
15
+ function assistantText(events) {
16
+ for (let index = events.length - 1; index >= 0; index -= 1) {
17
+ const event = events[index];
18
+ if (event?.type !== "message_end" || !event.message || typeof event.message !== "object")
19
+ continue;
20
+ const content = event.message.content;
21
+ if (!Array.isArray(content))
22
+ continue;
23
+ const text = content.filter((part) => Boolean(part && typeof part === "object" && part.type === "text" && typeof part.text === "string")).map((part) => part.text).join("");
24
+ if (text.trim())
25
+ return text.trim();
26
+ }
27
+ return "没有收到可显示的研究答复。";
28
+ }
29
+ async function listen(server, port) {
30
+ await new Promise((resolve, reject) => {
31
+ server.once("error", reject);
32
+ server.listen(port, "127.0.0.1", () => resolve());
33
+ });
34
+ const address = server.address();
35
+ return typeof address === "object" && address !== null ? address.port : port;
36
+ }
37
+ function openWorkbench(url) {
38
+ const command = process.platform === "win32" ? "cmd" : process.platform === "darwin" ? "open" : "xdg-open";
39
+ const args = process.platform === "win32" ? ["/c", "start", "", url] : [url];
40
+ const child = spawn(command, args, { detached: true, stdio: "ignore", windowsHide: true });
41
+ child.on("error", () => undefined);
42
+ child.unref();
43
+ }
44
+ /**
45
+ * Optional Pi extension for the local, read-only web projection. The core
46
+ * psyclaw package does not load this extension by default; `/agents` remains a
47
+ * native core command. Binding is always loopback and the panel has no write
48
+ * endpoint.
49
+ */
50
+ export default function psyclawPanelExtension(pi) {
51
+ let server;
52
+ let workbenchUrl;
53
+ let assistant;
54
+ const close = async () => {
55
+ const current = server;
56
+ server = undefined;
57
+ workbenchUrl = undefined;
58
+ const currentAssistant = assistant;
59
+ assistant = undefined;
60
+ await currentAssistant?.stop();
61
+ if (!current)
62
+ return;
63
+ await new Promise((resolve) => current.close(() => resolve()));
64
+ };
65
+ pi.registerCommand("panel", {
66
+ description: "Open the psyclaw research workbench in your browser",
67
+ handler: async (args, ctx) => {
68
+ if (args.trim() !== "") {
69
+ ctx.ui.notify("直接输入 /panel 即可打开科研工作台", "info");
70
+ return;
71
+ }
72
+ try {
73
+ if (server === undefined || workbenchUrl === undefined) {
74
+ const next = createPanelServer(ctx.cwd, { assistant: async (message) => {
75
+ if (!assistant) {
76
+ assistant = new PiRpcClient({
77
+ cwd: ctx.cwd,
78
+ ...(ctx.model?.provider === undefined ? {} : { provider: ctx.model.provider }),
79
+ ...(ctx.model?.id === undefined ? {} : { model: ctx.model.id }),
80
+ env: assistantEnv(ctx.model?.provider),
81
+ tools: ["read", "grep", "find", "ls"],
82
+ systemPrompt: BROWSER_ASSISTANT_PROMPT,
83
+ });
84
+ try {
85
+ await assistant.start();
86
+ }
87
+ catch (error) {
88
+ await assistant.stop().catch(() => undefined);
89
+ assistant = undefined;
90
+ throw error;
91
+ }
92
+ }
93
+ const current = assistant;
94
+ const events = await current.promptAndWait(message);
95
+ return { text: assistantText(events) };
96
+ } });
97
+ const actualPort = await listen(next, 0);
98
+ server = next;
99
+ workbenchUrl = `http://127.0.0.1:${actualPort}`;
100
+ }
101
+ openWorkbench(workbenchUrl);
102
+ ctx.ui.notify(`科研工作台已在浏览器中打开:${workbenchUrl}`, "info");
103
+ }
104
+ catch (error) {
105
+ server = undefined;
106
+ workbenchUrl = undefined;
107
+ ctx.ui.notify(error instanceof Error ? error.message : "科研工作台暂时无法打开", "error");
108
+ }
109
+ },
110
+ });
111
+ pi.on("session_shutdown", async () => {
112
+ await close();
113
+ });
114
+ }
115
+ //# sourceMappingURL=extension.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extension.js","sourceRoot":"","sources":["../../../src/panel/extension.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ import type { Claim, ClaimEvidenceLink, Evidence } from "../core/contracts.js";
2
+ /**
3
+ * Claim-centric literature context: for every claim, the sources that support,
4
+ * contradict, or contextualize it, with their evidence level and locator. This
5
+ * is the "文献脉络" view — where a claim came from and whether anything argues
6
+ * against it.
7
+ */
8
+ export interface ClaimLiteratureMap {
9
+ schemaVersion: "psyclaw/literature-map/v1";
10
+ generatedAt: string;
11
+ claims: Array<{
12
+ id: string;
13
+ text: string;
14
+ kind: Claim["kind"];
15
+ status: Claim["status"];
16
+ sources: Array<{
17
+ relation: "supports" | "contradicts" | "context";
18
+ evidenceId: string;
19
+ title: string;
20
+ locator?: string;
21
+ level: Evidence["level"];
22
+ sha256?: string;
23
+ }>;
24
+ }>;
25
+ }
26
+ export declare function buildClaimLiteratureMap(claims: readonly Claim[], evidence: readonly Evidence[], links: readonly ClaimEvidenceLink[], now?: string): ClaimLiteratureMap;
@@ -0,0 +1,34 @@
1
+ export function buildClaimLiteratureMap(claims, evidence, links, now = new Date().toISOString()) {
2
+ const evidenceById = new Map(evidence.map((item) => [item.id, item]));
3
+ return {
4
+ schemaVersion: "psyclaw/literature-map/v1",
5
+ generatedAt: now,
6
+ claims: claims.map((claim) => {
7
+ const sources = links
8
+ .filter((link) => link.claimId === claim.id)
9
+ .map((link) => {
10
+ const item = evidenceById.get(link.evidenceId);
11
+ return {
12
+ relation: link.relation,
13
+ evidenceId: link.evidenceId,
14
+ title: item?.source.title ?? item?.source.locator ?? link.evidenceId,
15
+ ...(item?.source.locator === undefined ? {} : { locator: item.source.locator }),
16
+ level: item?.level ?? "metadata",
17
+ ...(item?.sha256 === undefined ? {} : { sha256: item.sha256 }),
18
+ };
19
+ })
20
+ .sort((left, right) => {
21
+ const order = { contradicts: 0, supports: 1, context: 2 };
22
+ return order[left.relation] - order[right.relation];
23
+ });
24
+ return {
25
+ id: claim.id,
26
+ text: claim.text,
27
+ kind: claim.kind,
28
+ status: claim.status,
29
+ sources,
30
+ };
31
+ }),
32
+ };
33
+ }
34
+ //# sourceMappingURL=literature-map.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"literature-map.js","sourceRoot":"","sources":["../../../src/panel/literature-map.ts"],"names":[],"mappings":"AA2BA,MAAM,UAAU,uBAAuB,CACrC,MAAwB,EACxB,QAA6B,EAC7B,KAAmC,EACnC,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;IAE9B,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;IACtE,OAAO;QACL,aAAa,EAAE,2BAA2B;QAC1C,WAAW,EAAE,GAAG;QAChB,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;YAC3B,MAAM,OAAO,GAAG,KAAK;iBAClB,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,KAAK,KAAK,CAAC,EAAE,CAAC;iBAC3C,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;gBACZ,MAAM,IAAI,GAAG,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;gBAC/C,OAAO;oBACL,QAAQ,EAAE,IAAI,CAAC,QAAQ;oBACvB,UAAU,EAAE,IAAI,CAAC,UAAU;oBAC3B,KAAK,EAAE,IAAI,EAAE,MAAM,CAAC,KAAK,IAAI,IAAI,EAAE,MAAM,CAAC,OAAO,IAAI,IAAI,CAAC,UAAU;oBACpE,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;oBAC/E,KAAK,EAAE,IAAI,EAAE,KAAK,IAAK,UAAoB;oBAC3C,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC;iBAC/D,CAAC;YACJ,CAAC,CAAC;iBACD,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;gBACpB,MAAM,KAAK,GAAG,EAAE,WAAW,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAW,CAAC;gBACnE,OAAO,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;YACtD,CAAC,CAAC,CAAC;YACL,OAAO;gBACL,EAAE,EAAE,KAAK,CAAC,EAAE;gBACZ,IAAI,EAAE,KAAK,CAAC,IAAI;gBAChB,IAAI,EAAE,KAAK,CAAC,IAAI;gBAChB,MAAM,EAAE,KAAK,CAAC,MAAM;gBACpB,OAAO;aACR,CAAC;QACJ,CAAC,CAAC;KACH,CAAC;AACJ,CAAC"}
@@ -0,0 +1,51 @@
1
+ import { Type, type Static } from "typebox";
2
+ export declare const RunSnapshotSchema: Type.TObject<{
3
+ schemaVersion: Type.TLiteral<"psyclaw/run-snapshot/v1">;
4
+ runId: Type.TString;
5
+ projectId: Type.TString;
6
+ goal: Type.TString;
7
+ paradigm: Type.TString;
8
+ phase: Type.TUnion<[Type.TLiteral<"planned">, Type.TLiteral<"executing">, Type.TLiteral<"verifying">, Type.TLiteral<"completed">, Type.TLiteral<"paused">, Type.TLiteral<"blocked">, Type.TLiteral<"unknown">]>;
9
+ blocked: Type.TBoolean;
10
+ waitingOnHuman: Type.TArray<Type.TString>;
11
+ gates: Type.TArray<Type.TObject<{
12
+ gateId: Type.TString;
13
+ ok: Type.TBoolean;
14
+ severity: Type.TString;
15
+ reason: Type.TString;
16
+ }>>;
17
+ artifacts: Type.TArray<Type.TString>;
18
+ tasks: Type.TArray<Type.TObject<{
19
+ id: Type.TString;
20
+ status: Type.TUnion<[Type.TLiteral<"pending">, Type.TLiteral<"running">, Type.TLiteral<"succeeded">, Type.TLiteral<"failed">, Type.TLiteral<"blocked">]>;
21
+ attempt: Type.TInteger;
22
+ summary: Type.TString;
23
+ blockers: Type.TArray<Type.TString>;
24
+ artifacts: Type.TArray<Type.TString>;
25
+ receiptCount: Type.TInteger;
26
+ passedGates: Type.TArray<Type.TString>;
27
+ }>>;
28
+ evidenceCoverage: Type.TObject<{
29
+ totalClaims: Type.TInteger;
30
+ supportedClaims: Type.TInteger;
31
+ totalEvidence: Type.TInteger;
32
+ }>;
33
+ eventCount: Type.TInteger;
34
+ updatedAt: Type.TString;
35
+ nextStep: Type.TString;
36
+ }>;
37
+ export type RunSnapshot = Static<typeof RunSnapshotSchema>;
38
+ export declare function asRunSnapshot(value: unknown): RunSnapshot;
39
+ export interface RunListing {
40
+ runId: string;
41
+ phase: RunSnapshot["phase"];
42
+ eventCount: number;
43
+ }
44
+ /** List run ids discovered from the append-only run event log. */
45
+ export declare function listRuns(root: string): Promise<RunListing[]>;
46
+ /**
47
+ * Read-only projection of a run's facts. It derives a redacted snapshot from
48
+ * the JSONL event log, checkpoint, project, and evidence ledger. The panel
49
+ * consumes this and never mutates state or reaches the filesystem/MCP itself.
50
+ */
51
+ export declare function projectRunSnapshot(root: string, runId: string): Promise<RunSnapshot>;
@@ -0,0 +1,288 @@
1
+ import { lstat, readFile, readdir } from "node:fs/promises";
2
+ import { join } from "node:path";
3
+ import { Type } from "typebox";
4
+ import { Compile } from "typebox/compile";
5
+ import { checkEvidenceSufficiency } from "../core/evidence-policy.js";
6
+ import { redactSecrets } from "../core/redact.js";
7
+ import { readJsonl } from "../project/jsonl.js";
8
+ import { projectPaths } from "../project/paths.js";
9
+ import { assertSafeRunEventPath } from "./events.js";
10
+ import { loadLedger, readProject } from "../research/ledger.js";
11
+ export const RunSnapshotSchema = Type.Object({
12
+ schemaVersion: Type.Literal("psyclaw/run-snapshot/v1"),
13
+ runId: Type.String(),
14
+ projectId: Type.String(),
15
+ goal: Type.String(),
16
+ paradigm: Type.String(),
17
+ phase: Type.Union([
18
+ Type.Literal("planned"),
19
+ Type.Literal("executing"),
20
+ Type.Literal("verifying"),
21
+ Type.Literal("completed"),
22
+ Type.Literal("paused"),
23
+ Type.Literal("blocked"),
24
+ Type.Literal("unknown"),
25
+ ]),
26
+ blocked: Type.Boolean(),
27
+ waitingOnHuman: Type.Array(Type.String()),
28
+ gates: Type.Array(Type.Object({
29
+ gateId: Type.String(),
30
+ ok: Type.Boolean(),
31
+ severity: Type.String(),
32
+ reason: Type.String(),
33
+ })),
34
+ artifacts: Type.Array(Type.String()),
35
+ tasks: Type.Array(Type.Object({
36
+ id: Type.String(),
37
+ status: Type.Union([
38
+ Type.Literal("pending"),
39
+ Type.Literal("running"),
40
+ Type.Literal("succeeded"),
41
+ Type.Literal("failed"),
42
+ Type.Literal("blocked"),
43
+ ]),
44
+ attempt: Type.Integer({ minimum: 0 }),
45
+ summary: Type.String(),
46
+ blockers: Type.Array(Type.String()),
47
+ artifacts: Type.Array(Type.String()),
48
+ receiptCount: Type.Integer({ minimum: 0 }),
49
+ passedGates: Type.Array(Type.String()),
50
+ }, { additionalProperties: false })),
51
+ evidenceCoverage: Type.Object({
52
+ totalClaims: Type.Integer(),
53
+ supportedClaims: Type.Integer(),
54
+ totalEvidence: Type.Integer(),
55
+ }),
56
+ eventCount: Type.Integer(),
57
+ updatedAt: Type.String(),
58
+ nextStep: Type.String(),
59
+ }, { additionalProperties: false });
60
+ const compiled = Compile(RunSnapshotSchema);
61
+ export function asRunSnapshot(value) {
62
+ if (!compiled.Check(value)) {
63
+ const errors = [...compiled.Errors(value)].map((error) => {
64
+ const path = "path" in error && typeof error.path === "string" ? error.path : "/";
65
+ return `${path}: ${error.message}`;
66
+ });
67
+ throw new Error(`run snapshot schema invalid: ${errors.join("; ")}`);
68
+ }
69
+ return value;
70
+ }
71
+ function isRunEvent(value) {
72
+ if (typeof value !== "object" || value === null)
73
+ return false;
74
+ const event = value;
75
+ return event.schemaVersion === "psyclaw/run-event/v1" &&
76
+ typeof event.runId === "string" &&
77
+ typeof event.at === "string" &&
78
+ typeof event.type === "string";
79
+ }
80
+ function phaseFromEvents(events) {
81
+ const first = events[0];
82
+ const last = events.at(-1);
83
+ if (!last)
84
+ return "planned";
85
+ // A run must open with a `planned` event; a terminal or progress event
86
+ // without that opener is a forged or corrupt log, reported as unknown rather
87
+ // than trusted as a completed/blocked state.
88
+ if (first?.type !== "planned")
89
+ return "unknown";
90
+ switch (last.type) {
91
+ case "completed":
92
+ return "completed";
93
+ case "blocked":
94
+ return "blocked";
95
+ case "checkpoint":
96
+ return "paused";
97
+ case "gate":
98
+ return "verifying";
99
+ case "started":
100
+ case "receipt":
101
+ return "executing";
102
+ default:
103
+ return "planned";
104
+ }
105
+ }
106
+ /** One concrete next action for the researcher, derived from the run state. */
107
+ function nextStepFor(phase, blocked, waitingReasons, corrupt) {
108
+ if (corrupt)
109
+ return "运行事件或检查点不可用,先修复再继续";
110
+ const waiting = waitingReasons.filter((item) => !item.includes("corrupt"));
111
+ if (blocked || phase === "blocked") {
112
+ return waiting.length > 0 ? `有 ${waiting.length} 项门禁需要你确认后再继续` : "门禁未通过,检查证据与 Claim";
113
+ }
114
+ if (waiting.length > 0)
115
+ return `有 ${waiting.length} 项待你确认`;
116
+ switch (phase) {
117
+ case "paused": return "批准从 checkpoint 恢复运行";
118
+ case "completed": return "检查产物,按 APA7 导出 DOCX(图片已内嵌)";
119
+ case "executing": return "模型正在后台执行,无需操作";
120
+ case "verifying": return "模型正在核验门禁";
121
+ case "planned": return "导入证据并登记 Claim 后开始分析";
122
+ default: return "等待运行状态";
123
+ }
124
+ }
125
+ async function readEvents(root, runId) {
126
+ const path = await assertSafeRunEventPath(root, runId);
127
+ const stat = await lstat(path).catch((error) => {
128
+ if (error.code === "ENOENT")
129
+ return undefined;
130
+ throw error;
131
+ });
132
+ if (stat !== undefined && (stat.isSymbolicLink() || !stat.isFile())) {
133
+ throw new Error("Run event path must be a regular file");
134
+ }
135
+ const rows = await readJsonl(path);
136
+ return rows.map((row, index) => {
137
+ if (!isRunEvent(row) || row.runId !== runId) {
138
+ throw new Error(`Invalid run event at ${path}:${index + 1}`);
139
+ }
140
+ return row;
141
+ });
142
+ }
143
+ async function readCheckpoint(root, runId) {
144
+ const path = join(projectPaths(root).runs, `${runId}.checkpoint.json`);
145
+ try {
146
+ const stat = await lstat(path);
147
+ if (!stat.isFile() || stat.isSymbolicLink())
148
+ return { kind: "corrupt", artifacts: [], tasks: [] };
149
+ const text = await readFile(path, "utf8");
150
+ const value = JSON.parse(text);
151
+ if (value.schemaVersion !== "psyclaw/orchestrator-checkpoint/v1" || value.runId !== runId ||
152
+ value.tasks === null || typeof value.tasks !== "object" || Array.isArray(value.tasks)) {
153
+ return { kind: "corrupt", artifacts: [], tasks: [] };
154
+ }
155
+ const tasks = value.tasks;
156
+ const artifacts = [];
157
+ const taskProjections = [];
158
+ for (const [id, task] of Object.entries(tasks)) {
159
+ if (task === null || typeof task !== "object" || Array.isArray(task))
160
+ return { kind: "corrupt", artifacts: [], tasks: [] };
161
+ const item = task;
162
+ const taskArtifacts = item.artifacts;
163
+ const validStatus = item.status === "pending" || item.status === "running" || item.status === "succeeded" || item.status === "failed" || item.status === "blocked";
164
+ if (!validStatus || !Number.isInteger(item.attempt) || item.attempt < 0 ||
165
+ !Array.isArray(taskArtifacts) || !taskArtifacts.every((entry) => typeof entry === "string") ||
166
+ !Array.isArray(item.receipts) || !Array.isArray(item.passedGates) || !item.passedGates.every((entry) => typeof entry === "string")) {
167
+ return { kind: "corrupt", artifacts: [], tasks: [] };
168
+ }
169
+ artifacts.push(...taskArtifacts);
170
+ const report = item.report && typeof item.report === "object" && !Array.isArray(item.report)
171
+ ? item.report
172
+ : undefined;
173
+ if (report !== undefined && (typeof report.summary !== "string" || !Array.isArray(report.blockers) || !report.blockers.every((entry) => typeof entry === "string"))) {
174
+ return { kind: "corrupt", artifacts: [], tasks: [] };
175
+ }
176
+ const taskArtifactPaths = taskArtifacts;
177
+ const taskPassedGates = item.passedGates;
178
+ taskProjections.push({
179
+ id,
180
+ status: item.status,
181
+ attempt: item.attempt,
182
+ summary: redactSecrets(typeof report?.summary === "string" ? report.summary : ""),
183
+ blockers: (Array.isArray(report?.blockers) ? report.blockers : []).map((entry) => redactSecrets(entry)),
184
+ artifacts: taskArtifactPaths,
185
+ receiptCount: item.receipts.length,
186
+ passedGates: taskPassedGates,
187
+ });
188
+ }
189
+ return {
190
+ kind: "valid",
191
+ ...(typeof value.status === "string" ? { status: value.status } : {}),
192
+ artifacts,
193
+ tasks: taskProjections.sort((left, right) => left.id.localeCompare(right.id)),
194
+ };
195
+ }
196
+ catch (error) {
197
+ return error.code === "ENOENT"
198
+ ? { kind: "missing", artifacts: [], tasks: [] }
199
+ : { kind: "corrupt", artifacts: [], tasks: [] };
200
+ }
201
+ }
202
+ /** List run ids discovered from the append-only run event log. */
203
+ export async function listRuns(root) {
204
+ const runsDir = projectPaths(root).runs;
205
+ let entries;
206
+ try {
207
+ entries = await readdir(runsDir);
208
+ }
209
+ catch {
210
+ return [];
211
+ }
212
+ const listings = [];
213
+ for (const entry of entries) {
214
+ if (!entry.endsWith(".jsonl") || entry.endsWith(".checkpoint.json"))
215
+ continue;
216
+ const runId = entry.slice(0, -".jsonl".length);
217
+ try {
218
+ const events = await readEvents(root, runId);
219
+ listings.push({ runId, phase: phaseFromEvents(events), eventCount: events.length });
220
+ }
221
+ catch {
222
+ continue;
223
+ }
224
+ }
225
+ return listings.sort((left, right) => left.runId.localeCompare(right.runId));
226
+ }
227
+ /**
228
+ * Read-only projection of a run's facts. It derives a redacted snapshot from
229
+ * the JSONL event log, checkpoint, project, and evidence ledger. The panel
230
+ * consumes this and never mutates state or reaches the filesystem/MCP itself.
231
+ */
232
+ export async function projectRunSnapshot(root, runId) {
233
+ if (!/^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/.test(runId)) {
234
+ throw new Error("Run id contains unsupported path characters");
235
+ }
236
+ const project = await readProject(root);
237
+ const ledger = await loadLedger(root);
238
+ const gates = checkEvidenceSufficiency({ ...ledger, paradigm: project.paradigm });
239
+ const checkpoint = await readCheckpoint(root, runId);
240
+ let events = [];
241
+ let eventCorrupt = false;
242
+ try {
243
+ events = await readEvents(root, runId);
244
+ }
245
+ catch {
246
+ eventCorrupt = true;
247
+ }
248
+ const gateBlocked = gates.filter((gate) => !gate.ok);
249
+ const checkpointCorrupt = checkpoint.kind === "corrupt";
250
+ const phase = eventCorrupt || checkpointCorrupt
251
+ ? "unknown"
252
+ : checkpoint.kind === "valid" && checkpoint.status === "paused"
253
+ ? "paused"
254
+ : phaseFromEvents(events);
255
+ const snapshot = {
256
+ schemaVersion: "psyclaw/run-snapshot/v1",
257
+ runId,
258
+ projectId: project.id,
259
+ goal: redactSecrets(project.goal),
260
+ paradigm: project.paradigm,
261
+ phase,
262
+ blocked: gateBlocked.length > 0 || phase === "blocked",
263
+ waitingOnHuman: [
264
+ ...(eventCorrupt ? ["run event log is corrupt or unavailable"] : []),
265
+ ...(checkpointCorrupt ? ["run checkpoint is corrupt or unavailable"] : []),
266
+ ...gateBlocked.map((gate) => redactSecrets(gate.reason)),
267
+ ],
268
+ gates: gates.map((gate) => ({
269
+ gateId: gate.gateId,
270
+ ok: gate.ok,
271
+ severity: gate.severity,
272
+ reason: redactSecrets(gate.reason),
273
+ })),
274
+ artifacts: checkpoint.kind === "valid" ? checkpoint.artifacts : [],
275
+ tasks: checkpoint.kind === "valid" ? checkpoint.tasks : [],
276
+ evidenceCoverage: {
277
+ totalClaims: ledger.claims.length,
278
+ supportedClaims: ledger.claims.filter((claim) => claim.status === "supported").length,
279
+ totalEvidence: ledger.evidence.length,
280
+ },
281
+ eventCount: events.length,
282
+ updatedAt: new Date().toISOString(),
283
+ nextStep: nextStepFor(phase, gateBlocked.length > 0, gateBlocked.map((gate) => redactSecrets(gate.reason)), checkpointCorrupt || eventCorrupt),
284
+ };
285
+ asRunSnapshot(snapshot);
286
+ return snapshot;
287
+ }
288
+ //# sourceMappingURL=projection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"projection.js","sourceRoot":"","sources":["../../../src/panel/projection.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,46 @@
1
+ import { type Server } from "node:http";
2
+ export { verifyDoi } from "../core/doi.js";
3
+ export interface ProjectDocument {
4
+ path: string;
5
+ format: string;
6
+ kind: "manuscript" | "reference" | "data" | "report" | "document";
7
+ bytes: number;
8
+ sha256: string;
9
+ imported: boolean;
10
+ isManuscript: boolean;
11
+ }
12
+ /**
13
+ * Download the open-access PDF for a DOI into literature/<slug>.pdf. Only
14
+ * https/http URLs returned by OpenAlex are accepted; size is capped at 40 MB.
15
+ */
16
+ export declare function downloadReferencePdf(root: string, doi: string, fetchFn?: typeof fetch): Promise<{
17
+ ok: true;
18
+ path: string;
19
+ bytes: number;
20
+ oaUrl: string;
21
+ evidenceId: string;
22
+ } | {
23
+ ok: false;
24
+ reason: string;
25
+ doi: string;
26
+ }>;
27
+ export interface PanelServerOptions {
28
+ /** Absolute or cwd-relative path to the panel HTML file. */
29
+ panelHtmlPath?: string;
30
+ /** Optional browser assistant. The callback owns the Pi/model boundary. */
31
+ assistant?: (message: string) => Promise<{
32
+ text: string;
33
+ }>;
34
+ }
35
+ /**
36
+ * When the panel message references claims by id (e.g. the 追问此论断 flow),
37
+ * attach the real ledger context (.psyclaw) so the spawned read-only assistant
38
+ * answers grounded instead of fumbling for the claim.
39
+ */
40
+ export declare function enrichAssistantMessage(root: string, message: string): Promise<string>;
41
+ /**
42
+ * Narrow local panel server. Run facts and catalog endpoints are read-only;
43
+ * provider configuration is the one explicit POST action and delegates key
44
+ * persistence to Pi's auth storage.
45
+ */
46
+ export declare function createPanelServer(root: string, options?: PanelServerOptions): Server;