psyclaw 0.25.2 → 0.26.0

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,43 @@
1
+ import { type RegistryClient } from "./registry.js";
2
+ /** A single side-effecting step for the injected executor to run. */
3
+ export interface PiUpdateStep {
4
+ command: string;
5
+ cwd: string;
6
+ }
7
+ export type PiUpdateExecutor = (step: PiUpdateStep) => Promise<{
8
+ exitCode: number;
9
+ }>;
10
+ export type PiUpdateReason = "already-up-to-date" | "update-applied" | "update-failed" | "update-skipped";
11
+ export interface PiUpdateReceipt {
12
+ schemaVersion: "psyclaw/pi-update/v1";
13
+ ok: boolean;
14
+ executed: boolean;
15
+ reasonCode: PiUpdateReason;
16
+ reason?: string;
17
+ packageName: string;
18
+ before?: string;
19
+ after?: string;
20
+ latest?: string;
21
+ note?: string;
22
+ command?: string;
23
+ exitCode?: number;
24
+ startedAt: string;
25
+ finishedAt: string;
26
+ }
27
+ export interface UpdateBundledPiOptions {
28
+ registry: RegistryClient;
29
+ /** Explicit psyclaw package root (tests); defaults to walking up from here. */
30
+ packageRoot?: string;
31
+ force?: boolean;
32
+ now?: () => string;
33
+ /** When omitted, the call is a dry run and never mutates the workspace. */
34
+ executor?: PiUpdateExecutor;
35
+ }
36
+ /**
37
+ * Update the bundled Pi runtime by re-pinning both `@earendil-works/pi-*`
38
+ * packages to the latest official release. This is the write-side counterpart
39
+ * to `checkUpdates`: it is `--yes`/executor-gated, refuses non-semver versions,
40
+ * and always returns a structured receipt. Without an executor it is a pure
41
+ * plan (no workspace mutation).
42
+ */
43
+ export declare function updateBundledPi(options: UpdateBundledPiOptions): Promise<PiUpdateReceipt>;
@@ -0,0 +1,128 @@
1
+ import { access } from "node:fs/promises";
2
+ import { join } from "node:path";
3
+ import { PI_AI, PI_CODING_AGENT, resolvePsyClawManifest } from "./manifest.js";
4
+ import { compareSemver } from "./status.js";
5
+ /** Reject anything that is not a plain, installable semver (guards the spawn). */
6
+ const SEMVER_PATTERN = /^\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.-]+)?$/;
7
+ function isSafeVersion(version) {
8
+ return SEMVER_PATTERN.test(version);
9
+ }
10
+ async function packageManagerAt(root) {
11
+ const candidates = [
12
+ ["pnpm", "pnpm-lock.yaml"],
13
+ ["npm", "package-lock.json"],
14
+ ];
15
+ for (const [manager, file] of candidates) {
16
+ try {
17
+ await access(join(root, file));
18
+ return manager;
19
+ }
20
+ catch {
21
+ // keep looking
22
+ }
23
+ }
24
+ // A globally installed npm package is not shipped with its lockfile. npm is
25
+ // still able to update this package's pinned runtime dependencies in place.
26
+ return "npm";
27
+ }
28
+ function buildCommand(manager, version) {
29
+ const spec = `${PI_AI}@${version} ${PI_CODING_AGENT}@${version}`;
30
+ return manager === "pnpm" ? `pnpm add --save-exact ${spec}` : `npm install --save-exact ${spec}`;
31
+ }
32
+ /**
33
+ * Update the bundled Pi runtime by re-pinning both `@earendil-works/pi-*`
34
+ * packages to the latest official release. This is the write-side counterpart
35
+ * to `checkUpdates`: it is `--yes`/executor-gated, refuses non-semver versions,
36
+ * and always returns a structured receipt. Without an executor it is a pure
37
+ * plan (no workspace mutation).
38
+ */
39
+ export async function updateBundledPi(options) {
40
+ const now = options.now ?? (() => new Date().toISOString());
41
+ const startedAt = now();
42
+ const finish = (receipt) => ({
43
+ schemaVersion: "psyclaw/pi-update/v1",
44
+ startedAt,
45
+ finishedAt: now(),
46
+ ...receipt,
47
+ });
48
+ const manifest = await resolvePsyClawManifest(options.packageRoot);
49
+ if (manifest === undefined) {
50
+ return finish({
51
+ ok: false,
52
+ executed: false,
53
+ reasonCode: "update-skipped",
54
+ reason: "psyclaw package.json not found",
55
+ packageName: PI_CODING_AGENT,
56
+ });
57
+ }
58
+ let latest;
59
+ try {
60
+ latest = await options.registry.latestPiRelease();
61
+ }
62
+ catch {
63
+ latest = undefined;
64
+ }
65
+ const before = manifest.piVersion;
66
+ const base = {
67
+ packageName: PI_CODING_AGENT,
68
+ ...(before === undefined ? {} : { before }),
69
+ };
70
+ if (latest === undefined) {
71
+ return finish({ ok: false, executed: false, reasonCode: "update-skipped", reason: "latest Pi release unavailable", ...base });
72
+ }
73
+ if (!isSafeVersion(latest.version)) {
74
+ return finish({
75
+ ok: false,
76
+ executed: false,
77
+ reasonCode: "update-skipped",
78
+ reason: `refusing unsafe Pi version: ${latest.version}`,
79
+ latest: latest.version,
80
+ ...base,
81
+ });
82
+ }
83
+ const latestVersion = latest.version;
84
+ const comparison = before === undefined ? null : compareSemver(before, latestVersion);
85
+ const needsUpdate = options.force === true || comparison === null || comparison < 0;
86
+ const withLatest = {
87
+ ...base,
88
+ latest: latestVersion,
89
+ ...(latest.note === undefined ? {} : { note: latest.note }),
90
+ };
91
+ if (!needsUpdate) {
92
+ return finish({ ok: true, executed: false, reasonCode: "already-up-to-date", after: latestVersion, ...withLatest });
93
+ }
94
+ const manager = await packageManagerAt(manifest.root);
95
+ if (manager === undefined) {
96
+ return finish({
97
+ ok: false,
98
+ executed: false,
99
+ reasonCode: "update-skipped",
100
+ reason: "no pnpm-lock.yaml or package-lock.json found in the psyclaw package root",
101
+ ...withLatest,
102
+ });
103
+ }
104
+ const command = buildCommand(manager, latestVersion);
105
+ if (options.executor === undefined) {
106
+ return finish({
107
+ ok: true,
108
+ executed: false,
109
+ reasonCode: "update-skipped",
110
+ reason: "dry run: re-run with --yes to apply",
111
+ command,
112
+ after: latestVersion,
113
+ ...withLatest,
114
+ });
115
+ }
116
+ const { exitCode } = await options.executor({ command, cwd: manifest.root });
117
+ const ok = Number.isInteger(exitCode) && exitCode === 0;
118
+ return finish({
119
+ ok,
120
+ executed: true,
121
+ reasonCode: ok ? "update-applied" : "update-failed",
122
+ command,
123
+ exitCode,
124
+ ...(ok ? { after: latestVersion } : {}),
125
+ ...withLatest,
126
+ });
127
+ }
128
+ //# sourceMappingURL=update.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update.js","sourceRoot":"","sources":["../../../src/updates/update.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ export type WizardStep = "welcome" | "provider" | "model" | "confirm" | "done";
2
+ export interface WizardResult {
3
+ completed: boolean;
4
+ provider?: string;
5
+ modelId?: string;
6
+ }
7
+ export declare function runWizard(): Promise<WizardResult>;
@@ -0,0 +1,90 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useState } from "react";
3
+ import { Box, Text, render, useInput } from "ink";
4
+ import { PROVIDER_PRESETS, setupProviders } from "./setup.js";
5
+ import { PSYCLAW_ACCENT, PSYCLAW_ERROR, PSYCLAW_OK, PSYCLAW_VERSION } from "./branding.js";
6
+ function Banner() {
7
+ return (_jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [_jsxs(Box, { gap: 1, alignItems: "center", children: [_jsx(Text, { color: PSYCLAW_ACCENT, bold: true, children: "\u03C8 PsyClaw" }), _jsxs(Text, { color: "black", backgroundColor: PSYCLAW_ACCENT, bold: true, children: [" v", PSYCLAW_VERSION, " "] }), _jsx(Text, { dimColor: true, children: "\u793E\u79D1\u79D1\u7814\u667A\u80FD\u4F53 \u00B7 \u9996\u6B21\u914D\u7F6E\u5411\u5BFC" })] }), _jsx(Text, { dimColor: true, children: "\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500" })] }));
8
+ }
9
+ function Hint({ children }) {
10
+ return (_jsx(Box, { marginTop: 1, children: _jsxs(Text, { dimColor: true, children: ["\uD83D\uDCA1 ", children] }) }));
11
+ }
12
+ function Selectable({ lines, selected }) {
13
+ return (_jsx(Box, { flexDirection: "column", marginY: 1, children: lines.map((line, index) => {
14
+ const isSelected = index === selected;
15
+ return (_jsxs(Box, { gap: 1, children: [_jsx(Text, { color: isSelected ? PSYCLAW_ACCENT : "gray", bold: isSelected, children: isSelected ? "❯" : " " }), isSelected ? (_jsx(Text, { bold: true, color: PSYCLAW_ACCENT, children: line })) : (_jsx(Text, { children: line }))] }, line));
16
+ }) }));
17
+ }
18
+ function Wizard({ onDone }) {
19
+ const [step, setStep] = useState("welcome");
20
+ const [providerIndex, setProviderIndex] = useState(0);
21
+ const [modelIndex, setModelIndex] = useState(0);
22
+ const provider = PROVIDER_PRESETS[providerIndex];
23
+ const model = provider?.models[modelIndex];
24
+ const apiKeyEnv = provider?.apiKeyEnv ?? "";
25
+ const keyConfigured = process.env[apiKeyEnv] !== undefined && process.env[apiKeyEnv] !== "";
26
+ const writeConfig = async () => {
27
+ if (!provider)
28
+ return;
29
+ await setupProviders({ providers: [provider.id] });
30
+ setStep("done");
31
+ };
32
+ useInput((input, key) => {
33
+ if (input === "q" && step !== "done") {
34
+ onDone({ completed: false });
35
+ return;
36
+ }
37
+ switch (step) {
38
+ case "welcome":
39
+ if (key.return)
40
+ setStep("provider");
41
+ break;
42
+ case "provider":
43
+ if (key.upArrow)
44
+ setProviderIndex((value) => Math.max(0, value - 1));
45
+ if (key.downArrow)
46
+ setProviderIndex((value) => Math.min(PROVIDER_PRESETS.length - 1, value + 1));
47
+ if (key.return) {
48
+ setModelIndex(0);
49
+ setStep("model");
50
+ }
51
+ break;
52
+ case "model":
53
+ if (key.upArrow)
54
+ setModelIndex((value) => Math.max(0, value - 1));
55
+ if (key.downArrow)
56
+ setModelIndex((value) => Math.min((provider?.models.length ?? 1) - 1, value + 1));
57
+ if (key.return)
58
+ setStep("confirm");
59
+ break;
60
+ case "confirm":
61
+ if (key.return)
62
+ void writeConfig();
63
+ if (key.escape)
64
+ setStep("provider");
65
+ break;
66
+ case "done":
67
+ if (key.return || input === "q") {
68
+ onDone({
69
+ completed: true,
70
+ ...(provider?.id === undefined ? {} : { provider: provider.id }),
71
+ ...(model?.id === undefined ? {} : { modelId: model.id }),
72
+ });
73
+ }
74
+ break;
75
+ }
76
+ });
77
+ const providerLines = PROVIDER_PRESETS.map((preset) => `${preset.name.padEnd(20)} (环境变量: $${preset.apiKeyEnv})`);
78
+ const modelLines = provider ? provider.models.map((entry) => `${entry.name.padEnd(26)} [${entry.id}]`) : [];
79
+ return (_jsxs(Box, { borderStyle: "round", borderColor: PSYCLAW_ACCENT, paddingX: 2, paddingY: 1, flexDirection: "column", children: [_jsx(Banner, {}), step === "welcome" && (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { bold: true, children: "\u6B22\u8FCE\u4F7F\u7528 PsyClaw\uFF01" }), _jsx(Text, { dimColor: true, children: "\u9996\u6B21\u8FD0\u884C\u9700\u914D\u7F6E\u4E00\u4E2A\u6A21\u578B\u63D0\u4F9B\u5546\uFF08API Key \u7531\u672C\u5730\u73AF\u5883\u53D8\u91CF\u5B89\u5168\u7BA1\u7406\uFF0C\u7EDD\u4E0D\u4E0A\u62A5\uFF09\u3002" }), _jsx(Hint, { children: "[Enter] \u5F00\u59CB\u914D\u7F6E \u00B7 [Q] \u9000\u51FA" })] })), step === "provider" && (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { bold: true, color: PSYCLAW_ACCENT, children: "[1/3] \u9009\u62E9\u6A21\u578B\u63D0\u4F9B\u5546 (Provider)" }), _jsx(Selectable, { lines: providerLines, selected: providerIndex }), _jsx(Hint, { children: "[\u2191/\u2193] \u79FB\u52A8\u5149\u6807 \u00B7 [Enter] \u786E\u8BA4\u9009\u62E9 \u00B7 [Q] \u9000\u51FA" })] })), step === "model" && (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Text, { bold: true, color: PSYCLAW_ACCENT, children: ["[2/3] \u9009\u62E9\u9ED8\u8BA4\u6A21\u578B (", provider?.name, ")"] }), _jsx(Selectable, { lines: modelLines, selected: modelIndex }), _jsx(Hint, { children: "[\u2191/\u2193] \u79FB\u52A8\u5149\u6807 \u00B7 [Enter] \u786E\u8BA4\u9009\u62E9 \u00B7 [Q] \u9000\u51FA" })] })), step === "confirm" && (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { bold: true, color: PSYCLAW_ACCENT, children: "[3/3] \u786E\u8BA4\u914D\u7F6E\u5E76\u5199\u5165" }), _jsxs(Box, { flexDirection: "column", marginY: 1, children: [_jsxs(Text, { children: ["\u2022 \u63D0\u4F9B\u5546: ", _jsx(Text, { color: PSYCLAW_ACCENT, bold: true, children: provider?.name })] }), _jsxs(Text, { children: ["\u2022 \u6A21 \u578B: ", _jsx(Text, { color: PSYCLAW_ACCENT, bold: true, children: model?.name }), " ", _jsxs(Text, { dimColor: true, children: ["(", model?.id, ")"] })] }), _jsxs(Text, { color: keyConfigured ? PSYCLAW_OK : PSYCLAW_ERROR, bold: true, children: ["\u2022 API Key: ", keyConfigured ? `✔ 已就绪 ($${apiKeyEnv})` : `✗ 未检测到 $${apiKeyEnv}(请先在环境设置)`] })] }), _jsx(Hint, { children: "[Enter] \u4FDD\u5B58\u5E76\u542F\u52A8\u5BF9\u8BDD \u00B7 [Esc] \u8FD4\u56DE\u4E0A\u4E00\u6B65 \u00B7 [Q] \u9000\u51FA" })] })), step === "done" && (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { color: PSYCLAW_OK, bold: true, children: "\u2714 \u914D\u7F6E\u5DF2\u6210\u529F\u5199\u5165 models.json \u4E0E\u73AF\u5883\u7F13\u5B58\uFF01" }), _jsx(Text, { dimColor: true, children: "\u9A6C\u4E0A\u542F\u52A8 PsyClaw \u667A\u80FD\u7814\u7A76\u52A9\u624B\u2026" }), _jsx(Hint, { children: "[Enter] \u7ACB\u5373\u8FDB\u5165\u5BF9\u8BDD \u00B7 [Q] \u9000\u51FA" })] }))] }));
80
+ }
81
+ export function runWizard() {
82
+ return new Promise((resolve) => {
83
+ let instance;
84
+ instance = render(_jsx(Wizard, { onDone: (result) => {
85
+ instance.unmount();
86
+ resolve(result);
87
+ } }), { stdout: process.stdout, exitOnCtrlC: false });
88
+ });
89
+ }
90
+ //# sourceMappingURL=wizard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wizard.js","sourceRoot":"","sources":["../../src/wizard.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { type WorkflowResult, type WorkflowSpec } from "./spec.js";
2
+ export declare const analysisDelegationSpec: WorkflowSpec;
3
+ export declare function runAnalysisDelegation(root: string): Promise<WorkflowResult>;
@@ -0,0 +1,96 @@
1
+ import { checkEvidenceSufficiency } from "../core/evidence-policy.js";
2
+ import { loadLedger, readProject } from "../research/ledger.js";
3
+ import { allParadigms, finalizeWorkflow } from "./spec.js";
4
+ import { ANALYSIS_HOOKS_VERSION, analysisHookDigest, loadUserAnalysisHooks } from "../analysis/hooks.js";
5
+ import { checkPreRegistration, readPreRegistration } from "../analysis/pre-registration.js";
6
+ import { allocateProjectVersion } from "../project/versions.js";
7
+ export const analysisDelegationSpec = {
8
+ id: "analysis-delegation",
9
+ version: "1.0.0",
10
+ description: "Plan an external statistical analysis without computing anything in core.",
11
+ paradigms: allParadigms,
12
+ steps: [
13
+ { id: "select", role: "analyst", effect: "read", description: "select result claims to delegate" },
14
+ { id: "contract", role: "analyst", effect: "read", description: "write input/output/environment contract" },
15
+ { id: "write", role: "writer", effect: "write", description: "write the delegation plan" },
16
+ ],
17
+ requiredArtifacts: ["analysis-plan.md", "delegation.json"],
18
+ };
19
+ export async function runAnalysisDelegation(root) {
20
+ const project = await readProject(root);
21
+ const ledger = await loadLedger(root);
22
+ const gates = checkEvidenceSufficiency({ ...ledger, paradigm: project.paradigm });
23
+ // Confirmatory analysis is gated on a pre-registered plan.
24
+ gates.push(...checkPreRegistration(await readPreRegistration(root), project.paradigm));
25
+ const version = await allocateProjectVersion(root, "analysis-plan", `analysis-delegation:${Date.now()}`);
26
+ const userHooks = await loadUserAnalysisHooks(root);
27
+ const resultClaims = ledger.claims.filter((claim) => claim.kind === "result");
28
+ if (resultClaims.length === 0) {
29
+ gates.push({ gateId: "analysis:no-result-claims", ok: false, severity: "block", reason: "no result claims to delegate" });
30
+ }
31
+ const delegation = {
32
+ schemaVersion: "psyclaw/delegation/v1",
33
+ paradigm: project.paradigm,
34
+ version,
35
+ note: "psyclaw plans and verifies delegated analysis; it never computes statistics in core.",
36
+ safety: {
37
+ hooks: ANALYSIS_HOOKS_VERSION,
38
+ hookDigest: analysisHookDigest(),
39
+ userHooks: userHooks.map((hook) => ({ id: hook.id, event: hook.event, severity: hook.severity })),
40
+ immutableInputs: ["data/raw", "declared input paths"],
41
+ requiredChecks: ["beforeAnalysis", "validateAnalysisPlan", "beforeWrite", "afterAnalysis"],
42
+ policy: ["never overwrite or recode data/raw", "never report p-values without effect sizes and uncertainty intervals", "never turn correlation or significance into causality", "record script, environment, input hashes, missing-data and multiplicity handling"],
43
+ },
44
+ tasks: resultClaims.map((claim) => ({
45
+ claimId: claim.id,
46
+ claim: claim.text,
47
+ inputRefs: claim.evidenceIds,
48
+ contract: {
49
+ entrypoint: `analysis/scripts/run_${claim.id}.py`,
50
+ script: `analysis/scripts/run_${claim.id}.py`,
51
+ moduleLayout: {
52
+ load: `analysis/scripts/${claim.id}/01_load.py`,
53
+ prepare: `analysis/scripts/${claim.id}/02_prepare.py`,
54
+ analyze: `analysis/scripts/${claim.id}/03_analyze.py`,
55
+ validate: `analysis/scripts/${claim.id}/04_validate.py`,
56
+ export: `analysis/scripts/${claim.id}/05_export.py`,
57
+ reviewDocument: `analysis/scripts/${claim.id}/README.md`,
58
+ },
59
+ environment: { python: ">=3.12", execution: "external-and-approved" },
60
+ inputDigestRefs: claim.evidenceIds,
61
+ outputSchema: "psyclaw/analysis-result/v1",
62
+ requiredArtifact: `analysis/results/${claim.id}.result.json`,
63
+ moduleBoundary: "The entrypoint may orchestrate modules only; data loading, preparation, analysis, validation, and export stay separately reviewable.",
64
+ },
65
+ })),
66
+ };
67
+ const markdown = [
68
+ `# Analysis Delegation Plan ${version}`,
69
+ "",
70
+ `Paradigm: ${project.paradigm}`,
71
+ "",
72
+ ...delegation.tasks.map((task) => [
73
+ `## ${task.claimId}`,
74
+ "",
75
+ `Claim: ${task.claim}`,
76
+ "",
77
+ `- Entrypoint: \`${task.contract.entrypoint}\``,
78
+ `- Modules: load → prepare → analyze → validate → export`,
79
+ `- Review document: \`${task.contract.moduleLayout.reviewDocument}\``,
80
+ `- Environment: \`${task.contract.environment.python}\``,
81
+ `- Required artifact: \`${task.contract.requiredArtifact}\``,
82
+ "",
83
+ ]).flat(),
84
+ ].join("\n");
85
+ return finalizeWorkflow(root, analysisDelegationSpec, {
86
+ gates,
87
+ outputs: [
88
+ { path: "analysis-plan.md", contents: markdown },
89
+ { path: "delegation.json", contents: `${JSON.stringify(delegation, null, 2)}\n` },
90
+ { path: `analysis-plan-${version}.md`, contents: markdown },
91
+ { path: `delegation-${version}.json`, contents: `${JSON.stringify(delegation, null, 2)}\n` },
92
+ ],
93
+ completed: ["result claims selected", "delegation contracts written"],
94
+ });
95
+ }
96
+ //# sourceMappingURL=analysis-delegation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analysis-delegation.js","sourceRoot":"","sources":["../../../src/workflows/analysis-delegation.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ import { type WorkflowResult, type WorkflowSpec } from "./spec.js";
2
+ export declare const expertReviewWorkflowSpec: WorkflowSpec;
3
+ export declare const expertReviewSpec: WorkflowSpec;
4
+ export interface ReviewerRole {
5
+ id: "methodologist" | "evidence-auditor" | "integrity-ethicist" | "editor";
6
+ label: string;
7
+ remit: string;
8
+ }
9
+ export declare const DEFAULT_REVIEWER_ROLES: readonly ReviewerRole[];
10
+ export interface ReviewApproval {
11
+ approved: boolean;
12
+ actor: string;
13
+ reason: string;
14
+ at?: string;
15
+ }
16
+ export interface ExpertReviewOptions {
17
+ approval?: ReviewApproval;
18
+ roles?: readonly ReviewerRole[];
19
+ }
20
+ export interface ExpertReviewSuggestion {
21
+ id: string;
22
+ role: ReviewerRole["id"];
23
+ priority: "block" | "warn";
24
+ target?: string;
25
+ suggestion: string;
26
+ rationale: string;
27
+ status: "proposed";
28
+ }
29
+ export declare function runExpertReview(root: string, options?: ExpertReviewOptions): Promise<WorkflowResult>;
@@ -0,0 +1,35 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { appendJsonl } from "../project/jsonl.js";
3
+ import { projectPaths } from "../project/paths.js";
4
+ import { allocateProjectVersion } from "../project/versions.js";
5
+ import { checkEvidenceSufficiency } from "../core/evidence-policy.js";
6
+ import { loadLedger, readProject } from "../research/ledger.js";
7
+ import { allParadigms, finalizeWorkflow } from "./spec.js";
8
+ export const expertReviewWorkflowSpec = { id: "expert-review", version: "1.0.0", description: "Run four independent review roles and produce evidence-grounded recommendations for human approval.", paradigms: allParadigms, steps: [{ id: "evidence", role: "verifier", effect: "read", description: "load and check the evidence ledger" }, { id: "method", role: "analyst", effect: "read", description: "review methods and claims" }, { id: "ethics", role: "critic", effect: "read", description: "review integrity, uncertainty, and ethics" }, { id: "editorial", role: "writer", effect: "read", description: "propose clarity and reporting revisions" }], requiredArtifacts: ["expert-review.md", "review-result.json", "review-suggestions.json"] };
9
+ export const expertReviewSpec = expertReviewWorkflowSpec;
10
+ export const DEFAULT_REVIEWER_ROLES = [{ id: "methodologist", label: "Methodologist", remit: "methods, design, and conclusion boundaries" }, { id: "evidence-auditor", label: "Evidence auditor", remit: "claim, source, locator, and conflict coverage" }, { id: "integrity-ethicist", label: "Integrity and ethics reviewer", remit: "uncertainty, ethics, privacy, and reporting risks" }, { id: "editor", label: "Academic editor", remit: "clarity, structure, and transparent revision suggestions" }];
11
+ export async function runExpertReview(root, options = {}) {
12
+ const project = await readProject(root);
13
+ const ledger = await loadLedger(root);
14
+ const gates = checkEvidenceSufficiency({ ...ledger, paradigm: project.paradigm });
15
+ const version = await allocateProjectVersion(root, "manuscript-revision", `expert-review:${Date.now()}`);
16
+ const approval = options.approval;
17
+ if (!approval?.approved)
18
+ gates.push({ gateId: "expert-review:human-approval", ok: false, severity: "block", reason: "human approval is required before adopting review recommendations" });
19
+ const suggestions = [];
20
+ for (const claim of ledger.claims) {
21
+ const gate = gates.find((item) => item.claimIds?.includes(claim.id));
22
+ if (claim.status === "supported" && gate && !gate.ok)
23
+ suggestions.push({ id: `suggestion_${randomUUID().replaceAll("-", "")}`, role: "evidence-auditor", priority: "block", target: claim.id, suggestion: "downgrade or substantiate this claim", rationale: "the evidence gate does not pass", status: "proposed" });
24
+ if (claim.kind !== "result" && /\b(?:causes?|leads? to|proves?|established)\b/i.test(claim.text))
25
+ suggestions.push({ id: `suggestion_${randomUUID().replaceAll("-", "")}`, role: "methodologist", priority: "warn", target: claim.id, suggestion: "replace causal or confirmatory wording with evidence-qualified language", rationale: "the claim is not a verified result artifact", status: "proposed" });
26
+ }
27
+ if (suggestions.length === 0)
28
+ suggestions.push({ id: `suggestion_${randomUUID().replaceAll("-", "")}`, role: "editor", priority: "warn", suggestion: "retain the current text and document the human review decision", rationale: "no automatic revision is performed by this workflow", status: "proposed" });
29
+ const result = { schemaVersion: "psyclaw/expert-review/v1", version, workflowVersion: expertReviewWorkflowSpec.version, roles: options.roles ?? DEFAULT_REVIEWER_ROLES, approval: approval ? { ...approval, at: approval.at ?? new Date().toISOString() } : { status: "pending" }, suggestions, findingCount: suggestions.length };
30
+ const markdown = [`# Expert Review ${version}`, "", `Research goal: ${project.goal}`, "", "Recommendations are proposals only; this workflow never edits manuscript text.", "", "## Recommendations", "", ...suggestions.map((item) => `- [${item.priority}] ${item.role}: ${item.suggestion}${item.target ? ` (${item.target})` : ""}`), ""].join("\n");
31
+ const receipt = { schemaVersion: "psyclaw/review-receipt/v1", runId: `review:${version}`, workflow: expertReviewWorkflowSpec.id, version, approval: approval?.approved ? "approved" : "pending", actor: approval?.actor ?? null, idempotencyKey: `expert-review:${version}`, createdAt: new Date().toISOString() };
32
+ await appendJsonl(projectPaths(root).audit, { schemaVersion: "psyclaw/audit/v1", action: "expert-review", workflow: expertReviewWorkflowSpec.id, version, approval: receipt.approval, actor: receipt.actor, receipt: receipt.schemaVersion, at: receipt.createdAt });
33
+ return finalizeWorkflow(root, expertReviewWorkflowSpec, { gates, outputs: [{ path: "expert-review.md", contents: markdown }, { path: "review-result.json", contents: `${JSON.stringify(result, null, 2)}\n` }, { path: "review-suggestions.json", contents: `${JSON.stringify({ schemaVersion: "psyclaw/review-suggestions/v1", version, suggestions }, null, 2)}\n` }, { path: `expert-review-${version}.md`, contents: markdown }, { path: `review-receipt-${version}.json`, contents: `${JSON.stringify(receipt, null, 2)}\n` }], completed: ["four reviewer roles evaluated the ledger", "standardized review result produced", "revision suggestions recorded without editing source text"] });
34
+ }
35
+ //# sourceMappingURL=expert-review-runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"expert-review-runner.js","sourceRoot":"","sources":["../../../src/workflows/expert-review-runner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,140 @@
1
+ import { Type } from "typebox";
2
+ /** The smallest independent panel used for a bounded manuscript review. */
3
+ export type ExpertReviewRole = "methodologist" | "evidence-critic" | "writing-editor" | "devil-advocate" | "ethics-reviewer" | "reproducibility-reviewer";
4
+ export type ExpertReviewSeverity = "block" | "major" | "minor" | "note";
5
+ export type ExpertReviewDisposition = "accept" | "revise" | "reject" | "uncertain";
6
+ export interface ExpertReviewFinding {
7
+ id: string;
8
+ severity: ExpertReviewSeverity;
9
+ rule: string;
10
+ message: string;
11
+ /** A finding must point to an input, claim, or artifact when one exists. */
12
+ refs: string[];
13
+ disposition: ExpertReviewDisposition;
14
+ }
15
+ export interface ExpertReviewOpinion {
16
+ schemaVersion: "psyclaw/expert-review-opinion/v1";
17
+ runId: string;
18
+ taskId: string;
19
+ dispatchId: string;
20
+ expertId: string;
21
+ role: ExpertReviewRole;
22
+ outcome: "complete" | "blocked" | "uncertain";
23
+ summary: string;
24
+ findings: ExpertReviewFinding[];
25
+ /** Empty is valid only when the expert explicitly reports no findings. */
26
+ evidenceRefs: string[];
27
+ }
28
+ export interface ExpertReviewContract {
29
+ schemaVersion: "psyclaw/expert-review/v1";
30
+ runId: string;
31
+ subject: {
32
+ kind: "manuscript" | "artifact" | "workflow";
33
+ ref: string;
34
+ };
35
+ inputRefs: string[];
36
+ experts: {
37
+ expertId: string;
38
+ role: ExpertReviewRole;
39
+ taskId: string;
40
+ }[];
41
+ requiredRoles: ExpertReviewRole[];
42
+ minOpinions: number;
43
+ independent: true;
44
+ output: {
45
+ artifactPath: string;
46
+ verdictPath: string;
47
+ };
48
+ }
49
+ export interface ExpertReviewResult {
50
+ schemaVersion: "psyclaw/expert-review-result/v1";
51
+ runId: string;
52
+ verdict: "pass" | "blocked" | "uncertain";
53
+ opinions: ExpertReviewOpinion[];
54
+ findings: ExpertReviewFinding[];
55
+ unresolvedRoles: ExpertReviewRole[];
56
+ /** Aggregation is a report only; it never upgrades an unsupported finding. */
57
+ blockReasons: string[];
58
+ }
59
+ export declare const ExpertReviewOpinionSchema: Type.TObject<{
60
+ schemaVersion: Type.TLiteral<"psyclaw/expert-review-opinion/v1">;
61
+ runId: Type.TString;
62
+ taskId: Type.TString;
63
+ dispatchId: Type.TString;
64
+ expertId: Type.TString;
65
+ role: Type.TUnion<[Type.TLiteral<"methodologist">, Type.TLiteral<"evidence-critic">, Type.TLiteral<"writing-editor">, Type.TLiteral<"devil-advocate">, Type.TLiteral<"ethics-reviewer">, Type.TLiteral<"reproducibility-reviewer">]>;
66
+ outcome: Type.TUnion<[Type.TLiteral<"complete">, Type.TLiteral<"blocked">, Type.TLiteral<"uncertain">]>;
67
+ summary: Type.TString;
68
+ findings: Type.TArray<Type.TObject<{
69
+ id: Type.TString;
70
+ severity: Type.TUnion<[Type.TLiteral<"block">, Type.TLiteral<"major">, Type.TLiteral<"minor">, Type.TLiteral<"note">]>;
71
+ rule: Type.TString;
72
+ message: Type.TString;
73
+ refs: Type.TArray<Type.TString>;
74
+ disposition: Type.TUnion<[Type.TLiteral<"accept">, Type.TLiteral<"revise">, Type.TLiteral<"reject">, Type.TLiteral<"uncertain">]>;
75
+ }>>;
76
+ evidenceRefs: Type.TArray<Type.TString>;
77
+ }>;
78
+ export declare const ExpertReviewContractSchema: Type.TObject<{
79
+ schemaVersion: Type.TLiteral<"psyclaw/expert-review/v1">;
80
+ runId: Type.TString;
81
+ subject: Type.TObject<{
82
+ kind: Type.TUnion<[Type.TLiteral<"manuscript">, Type.TLiteral<"artifact">, Type.TLiteral<"workflow">]>;
83
+ ref: Type.TString;
84
+ }>;
85
+ inputRefs: Type.TArray<Type.TString>;
86
+ experts: Type.TArray<Type.TObject<{
87
+ expertId: Type.TString;
88
+ role: Type.TUnion<[Type.TLiteral<"methodologist">, Type.TLiteral<"evidence-critic">, Type.TLiteral<"writing-editor">, Type.TLiteral<"devil-advocate">, Type.TLiteral<"ethics-reviewer">, Type.TLiteral<"reproducibility-reviewer">]>;
89
+ taskId: Type.TString;
90
+ }>>;
91
+ requiredRoles: Type.TArray<Type.TUnion<[Type.TLiteral<"methodologist">, Type.TLiteral<"evidence-critic">, Type.TLiteral<"writing-editor">, Type.TLiteral<"devil-advocate">, Type.TLiteral<"ethics-reviewer">, Type.TLiteral<"reproducibility-reviewer">]>>;
92
+ minOpinions: Type.TInteger;
93
+ independent: Type.TLiteral<true>;
94
+ output: Type.TObject<{
95
+ artifactPath: Type.TString;
96
+ verdictPath: Type.TString;
97
+ }>;
98
+ }>;
99
+ export declare const ExpertReviewResultSchema: Type.TObject<{
100
+ schemaVersion: Type.TLiteral<"psyclaw/expert-review-result/v1">;
101
+ runId: Type.TString;
102
+ verdict: Type.TUnion<[Type.TLiteral<"pass">, Type.TLiteral<"blocked">, Type.TLiteral<"uncertain">]>;
103
+ opinions: Type.TArray<Type.TObject<{
104
+ schemaVersion: Type.TLiteral<"psyclaw/expert-review-opinion/v1">;
105
+ runId: Type.TString;
106
+ taskId: Type.TString;
107
+ dispatchId: Type.TString;
108
+ expertId: Type.TString;
109
+ role: Type.TUnion<[Type.TLiteral<"methodologist">, Type.TLiteral<"evidence-critic">, Type.TLiteral<"writing-editor">, Type.TLiteral<"devil-advocate">, Type.TLiteral<"ethics-reviewer">, Type.TLiteral<"reproducibility-reviewer">]>;
110
+ outcome: Type.TUnion<[Type.TLiteral<"complete">, Type.TLiteral<"blocked">, Type.TLiteral<"uncertain">]>;
111
+ summary: Type.TString;
112
+ findings: Type.TArray<Type.TObject<{
113
+ id: Type.TString;
114
+ severity: Type.TUnion<[Type.TLiteral<"block">, Type.TLiteral<"major">, Type.TLiteral<"minor">, Type.TLiteral<"note">]>;
115
+ rule: Type.TString;
116
+ message: Type.TString;
117
+ refs: Type.TArray<Type.TString>;
118
+ disposition: Type.TUnion<[Type.TLiteral<"accept">, Type.TLiteral<"revise">, Type.TLiteral<"reject">, Type.TLiteral<"uncertain">]>;
119
+ }>>;
120
+ evidenceRefs: Type.TArray<Type.TString>;
121
+ }>>;
122
+ findings: Type.TArray<Type.TObject<{
123
+ id: Type.TString;
124
+ severity: Type.TUnion<[Type.TLiteral<"block">, Type.TLiteral<"major">, Type.TLiteral<"minor">, Type.TLiteral<"note">]>;
125
+ rule: Type.TString;
126
+ message: Type.TString;
127
+ refs: Type.TArray<Type.TString>;
128
+ disposition: Type.TUnion<[Type.TLiteral<"accept">, Type.TLiteral<"revise">, Type.TLiteral<"reject">, Type.TLiteral<"uncertain">]>;
129
+ }>>;
130
+ unresolvedRoles: Type.TArray<Type.TUnion<[Type.TLiteral<"methodologist">, Type.TLiteral<"evidence-critic">, Type.TLiteral<"writing-editor">, Type.TLiteral<"devil-advocate">, Type.TLiteral<"ethics-reviewer">, Type.TLiteral<"reproducibility-reviewer">]>>;
131
+ blockReasons: Type.TArray<Type.TString>;
132
+ }>;
133
+ export declare function validateExpertReviewContract(value: unknown): ExpertReviewContract;
134
+ export declare function validateExpertReviewOpinion(value: unknown): ExpertReviewOpinion;
135
+ export declare function validateExpertReviewResult(value: unknown): ExpertReviewResult;
136
+ /**
137
+ * Deterministically combines independent opinions. It does not infer a
138
+ * finding from a vote and never upgrades an uncertain or blocked opinion.
139
+ */
140
+ export declare function aggregateExpertReview(contractValue: unknown, opinionValues: readonly unknown[]): ExpertReviewResult;