psyclaw 0.24.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 (270) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +67 -0
  3. package/dist/apps/panel/index.html +3416 -0
  4. package/dist/src/adapters/pi/extension.d.ts +19 -0
  5. package/dist/src/adapters/pi/extension.js +735 -0
  6. package/dist/src/adapters/pi/extension.js.map +1 -0
  7. package/dist/src/adapters/pi/model.d.ts +72 -0
  8. package/dist/src/adapters/pi/model.js +152 -0
  9. package/dist/src/adapters/pi/model.js.map +1 -0
  10. package/dist/src/adapters/pi/resources.d.ts +23 -0
  11. package/dist/src/adapters/pi/resources.js +54 -0
  12. package/dist/src/adapters/pi/resources.js.map +1 -0
  13. package/dist/src/adapters/pi/rpc.d.ts +56 -0
  14. package/dist/src/adapters/pi/rpc.js +248 -0
  15. package/dist/src/adapters/pi/rpc.js.map +1 -0
  16. package/dist/src/adapters/pi/session.d.ts +30 -0
  17. package/dist/src/adapters/pi/session.js +64 -0
  18. package/dist/src/adapters/pi/session.js.map +1 -0
  19. package/dist/src/agents/catalog.d.ts +30 -0
  20. package/dist/src/agents/catalog.js +118 -0
  21. package/dist/src/agents/catalog.js.map +1 -0
  22. package/dist/src/agents/discover.d.ts +28 -0
  23. package/dist/src/agents/discover.js +127 -0
  24. package/dist/src/agents/discover.js.map +1 -0
  25. package/dist/src/agents/import.d.ts +67 -0
  26. package/dist/src/agents/import.js +801 -0
  27. package/dist/src/agents/import.js.map +1 -0
  28. package/dist/src/analysis/hooks.d.ts +81 -0
  29. package/dist/src/analysis/hooks.js +139 -0
  30. package/dist/src/analysis/hooks.js.map +1 -0
  31. package/dist/src/analysis/pre-registration.d.ts +18 -0
  32. package/dist/src/analysis/pre-registration.js +86 -0
  33. package/dist/src/analysis/pre-registration.js.map +1 -0
  34. package/dist/src/branding.d.ts +43 -0
  35. package/dist/src/branding.js +127 -0
  36. package/dist/src/branding.js.map +1 -0
  37. package/dist/src/chat.d.ts +16 -0
  38. package/dist/src/chat.js +67 -0
  39. package/dist/src/chat.js.map +1 -0
  40. package/dist/src/cli.d.ts +2 -0
  41. package/dist/src/cli.js +316 -0
  42. package/dist/src/cli.js.map +1 -0
  43. package/dist/src/core/citations.d.ts +44 -0
  44. package/dist/src/core/citations.js +48 -0
  45. package/dist/src/core/citations.js.map +1 -0
  46. package/dist/src/core/contracts.d.ts +119 -0
  47. package/dist/src/core/contracts.js +2 -0
  48. package/dist/src/core/contracts.js.map +1 -0
  49. package/dist/src/core/docx.d.ts +11 -0
  50. package/dist/src/core/docx.js +46 -0
  51. package/dist/src/core/docx.js.map +1 -0
  52. package/dist/src/core/doi.d.ts +41 -0
  53. package/dist/src/core/doi.js +82 -0
  54. package/dist/src/core/doi.js.map +1 -0
  55. package/dist/src/core/evidence-policy.d.ts +24 -0
  56. package/dist/src/core/evidence-policy.js +308 -0
  57. package/dist/src/core/evidence-policy.js.map +1 -0
  58. package/dist/src/core/filekind.d.ts +15 -0
  59. package/dist/src/core/filekind.js +82 -0
  60. package/dist/src/core/filekind.js.map +1 -0
  61. package/dist/src/core/hash.d.ts +2 -0
  62. package/dist/src/core/hash.js +17 -0
  63. package/dist/src/core/hash.js.map +1 -0
  64. package/dist/src/core/pricing.d.ts +38 -0
  65. package/dist/src/core/pricing.js +110 -0
  66. package/dist/src/core/pricing.js.map +1 -0
  67. package/dist/src/core/redact.d.ts +12 -0
  68. package/dist/src/core/redact.js +48 -0
  69. package/dist/src/core/redact.js.map +1 -0
  70. package/dist/src/core/references.d.ts +55 -0
  71. package/dist/src/core/references.js +102 -0
  72. package/dist/src/core/references.js.map +1 -0
  73. package/dist/src/core/schemas.d.ts +162 -0
  74. package/dist/src/core/schemas.js +160 -0
  75. package/dist/src/core/schemas.js.map +1 -0
  76. package/dist/src/extension.d.ts +1 -0
  77. package/dist/src/extension.js +2 -0
  78. package/dist/src/extension.js.map +1 -0
  79. package/dist/src/index.d.ts +72 -0
  80. package/dist/src/index.js +73 -0
  81. package/dist/src/index.js.map +1 -0
  82. package/dist/src/install/installer.d.ts +147 -0
  83. package/dist/src/install/installer.js +743 -0
  84. package/dist/src/install/installer.js.map +1 -0
  85. package/dist/src/integrations/contracts.d.ts +35 -0
  86. package/dist/src/integrations/contracts.js +27 -0
  87. package/dist/src/integrations/contracts.js.map +1 -0
  88. package/dist/src/integrations/mcp.d.ts +155 -0
  89. package/dist/src/integrations/mcp.js +826 -0
  90. package/dist/src/integrations/mcp.js.map +1 -0
  91. package/dist/src/knowledge-map/contracts.d.ts +20 -0
  92. package/dist/src/knowledge-map/contracts.js +2 -0
  93. package/dist/src/knowledge-map/contracts.js.map +1 -0
  94. package/dist/src/knowledge-map/index.d.ts +4 -0
  95. package/dist/src/knowledge-map/index.js +39 -0
  96. package/dist/src/knowledge-map/index.js.map +1 -0
  97. package/dist/src/literature/contracts.d.ts +106 -0
  98. package/dist/src/literature/contracts.js +2 -0
  99. package/dist/src/literature/contracts.js.map +1 -0
  100. package/dist/src/literature/fulltext.d.ts +7 -0
  101. package/dist/src/literature/fulltext.js +24 -0
  102. package/dist/src/literature/fulltext.js.map +1 -0
  103. package/dist/src/literature/knowledge-map.d.ts +2 -0
  104. package/dist/src/literature/knowledge-map.js +20 -0
  105. package/dist/src/literature/knowledge-map.js.map +1 -0
  106. package/dist/src/literature/ledger.d.ts +3 -0
  107. package/dist/src/literature/ledger.js +17 -0
  108. package/dist/src/literature/ledger.js.map +1 -0
  109. package/dist/src/literature/metadata.d.ts +6 -0
  110. package/dist/src/literature/metadata.js +32 -0
  111. package/dist/src/literature/metadata.js.map +1 -0
  112. package/dist/src/memory/store.d.ts +22 -0
  113. package/dist/src/memory/store.js +73 -0
  114. package/dist/src/memory/store.js.map +1 -0
  115. package/dist/src/orchestration/contracts.d.ts +61 -0
  116. package/dist/src/orchestration/contracts.js +2 -0
  117. package/dist/src/orchestration/contracts.js.map +1 -0
  118. package/dist/src/orchestration/pi-executor.d.ts +28 -0
  119. package/dist/src/orchestration/pi-executor.js +169 -0
  120. package/dist/src/orchestration/pi-executor.js.map +1 -0
  121. package/dist/src/orchestration/runner.d.ts +196 -0
  122. package/dist/src/orchestration/runner.js +991 -0
  123. package/dist/src/orchestration/runner.js.map +1 -0
  124. package/dist/src/orchestration/scheduler.d.ts +8 -0
  125. package/dist/src/orchestration/scheduler.js +335 -0
  126. package/dist/src/orchestration/scheduler.js.map +1 -0
  127. package/dist/src/panel/events.d.ts +20 -0
  128. package/dist/src/panel/events.js +93 -0
  129. package/dist/src/panel/events.js.map +1 -0
  130. package/dist/src/panel/extension.d.ts +8 -0
  131. package/dist/src/panel/extension.js +114 -0
  132. package/dist/src/panel/extension.js.map +1 -0
  133. package/dist/src/panel/literature-map.d.ts +26 -0
  134. package/dist/src/panel/literature-map.js +34 -0
  135. package/dist/src/panel/literature-map.js.map +1 -0
  136. package/dist/src/panel/projection.d.ts +51 -0
  137. package/dist/src/panel/projection.js +288 -0
  138. package/dist/src/panel/projection.js.map +1 -0
  139. package/dist/src/panel/server.d.ts +46 -0
  140. package/dist/src/panel/server.js +1610 -0
  141. package/dist/src/panel/server.js.map +1 -0
  142. package/dist/src/panel/usage.d.ts +53 -0
  143. package/dist/src/panel/usage.js +150 -0
  144. package/dist/src/panel/usage.js.map +1 -0
  145. package/dist/src/project/bootstrap.d.ts +10 -0
  146. package/dist/src/project/bootstrap.js +83 -0
  147. package/dist/src/project/bootstrap.js.map +1 -0
  148. package/dist/src/project/hitl.d.ts +12 -0
  149. package/dist/src/project/hitl.js +43 -0
  150. package/dist/src/project/hitl.js.map +1 -0
  151. package/dist/src/project/jsonl.d.ts +16 -0
  152. package/dist/src/project/jsonl.js +93 -0
  153. package/dist/src/project/jsonl.js.map +1 -0
  154. package/dist/src/project/manuscript.d.ts +21 -0
  155. package/dist/src/project/manuscript.js +74 -0
  156. package/dist/src/project/manuscript.js.map +1 -0
  157. package/dist/src/project/paths.d.ts +38 -0
  158. package/dist/src/project/paths.js +166 -0
  159. package/dist/src/project/paths.js.map +1 -0
  160. package/dist/src/project/versions.d.ts +10 -0
  161. package/dist/src/project/versions.js +14 -0
  162. package/dist/src/project/versions.js.map +1 -0
  163. package/dist/src/psyclaw-theme.d.ts +88 -0
  164. package/dist/src/psyclaw-theme.js +89 -0
  165. package/dist/src/psyclaw-theme.js.map +1 -0
  166. package/dist/src/research/brief.d.ts +11 -0
  167. package/dist/src/research/brief.js +81 -0
  168. package/dist/src/research/brief.js.map +1 -0
  169. package/dist/src/research/ledger.d.ts +12 -0
  170. package/dist/src/research/ledger.js +43 -0
  171. package/dist/src/research/ledger.js.map +1 -0
  172. package/dist/src/run.d.ts +20 -0
  173. package/dist/src/run.js +34 -0
  174. package/dist/src/run.js.map +1 -0
  175. package/dist/src/setup.d.ts +54 -0
  176. package/dist/src/setup.js +221 -0
  177. package/dist/src/setup.js.map +1 -0
  178. package/dist/src/skills/contracts.d.ts +105 -0
  179. package/dist/src/skills/contracts.js +3 -0
  180. package/dist/src/skills/contracts.js.map +1 -0
  181. package/dist/src/skills/preflight.d.ts +10 -0
  182. package/dist/src/skills/preflight.js +39 -0
  183. package/dist/src/skills/preflight.js.map +1 -0
  184. package/dist/src/skills/registry.d.ts +28 -0
  185. package/dist/src/skills/registry.js +556 -0
  186. package/dist/src/skills/registry.js.map +1 -0
  187. package/dist/src/style/artifact.d.ts +6 -0
  188. package/dist/src/style/artifact.js +61 -0
  189. package/dist/src/style/artifact.js.map +1 -0
  190. package/dist/src/style/cli-ui.d.ts +41 -0
  191. package/dist/src/style/cli-ui.js +119 -0
  192. package/dist/src/style/cli-ui.js.map +1 -0
  193. package/dist/src/style/contracts.d.ts +34 -0
  194. package/dist/src/style/contracts.js +2 -0
  195. package/dist/src/style/contracts.js.map +1 -0
  196. package/dist/src/style/registry.d.ts +16 -0
  197. package/dist/src/style/registry.js +50 -0
  198. package/dist/src/style/registry.js.map +1 -0
  199. package/dist/src/trust/manifest.d.ts +42 -0
  200. package/dist/src/trust/manifest.js +53 -0
  201. package/dist/src/trust/manifest.js.map +1 -0
  202. package/dist/src/trust/sbom.d.ts +54 -0
  203. package/dist/src/trust/sbom.js +77 -0
  204. package/dist/src/trust/sbom.js.map +1 -0
  205. package/dist/src/tui/app.d.ts +3 -0
  206. package/dist/src/tui/app.js +103 -0
  207. package/dist/src/tui/app.js.map +1 -0
  208. package/dist/src/tui/model.d.ts +13 -0
  209. package/dist/src/tui/model.js +25 -0
  210. package/dist/src/tui/model.js.map +1 -0
  211. package/dist/src/updates/check.d.ts +43 -0
  212. package/dist/src/updates/check.js +68 -0
  213. package/dist/src/updates/check.js.map +1 -0
  214. package/dist/src/updates/manifest.d.ts +19 -0
  215. package/dist/src/updates/manifest.js +58 -0
  216. package/dist/src/updates/manifest.js.map +1 -0
  217. package/dist/src/updates/registry.d.ts +21 -0
  218. package/dist/src/updates/registry.js +82 -0
  219. package/dist/src/updates/registry.js.map +1 -0
  220. package/dist/src/updates/skills.d.ts +15 -0
  221. package/dist/src/updates/skills.js +39 -0
  222. package/dist/src/updates/skills.js.map +1 -0
  223. package/dist/src/updates/status.d.ts +7 -0
  224. package/dist/src/updates/status.js +37 -0
  225. package/dist/src/updates/status.js.map +1 -0
  226. package/dist/src/updates/update.d.ts +43 -0
  227. package/dist/src/updates/update.js +126 -0
  228. package/dist/src/updates/update.js.map +1 -0
  229. package/dist/src/wizard.d.ts +7 -0
  230. package/dist/src/wizard.js +90 -0
  231. package/dist/src/wizard.js.map +1 -0
  232. package/dist/src/workflows/analysis-delegation.d.ts +3 -0
  233. package/dist/src/workflows/analysis-delegation.js +96 -0
  234. package/dist/src/workflows/analysis-delegation.js.map +1 -0
  235. package/dist/src/workflows/expert-review-runner.d.ts +29 -0
  236. package/dist/src/workflows/expert-review-runner.js +35 -0
  237. package/dist/src/workflows/expert-review-runner.js.map +1 -0
  238. package/dist/src/workflows/expert-review.d.ts +140 -0
  239. package/dist/src/workflows/expert-review.js +111 -0
  240. package/dist/src/workflows/expert-review.js.map +1 -0
  241. package/dist/src/workflows/institutional-fulltext.d.ts +16 -0
  242. package/dist/src/workflows/institutional-fulltext.js +110 -0
  243. package/dist/src/workflows/institutional-fulltext.js.map +1 -0
  244. package/dist/src/workflows/literature-review.d.ts +3 -0
  245. package/dist/src/workflows/literature-review.js +76 -0
  246. package/dist/src/workflows/literature-review.js.map +1 -0
  247. package/dist/src/workflows/meta-analysis.d.ts +38 -0
  248. package/dist/src/workflows/meta-analysis.js +185 -0
  249. package/dist/src/workflows/meta-analysis.js.map +1 -0
  250. package/dist/src/workflows/publish.d.ts +51 -0
  251. package/dist/src/workflows/publish.js +153 -0
  252. package/dist/src/workflows/publish.js.map +1 -0
  253. package/dist/src/workflows/spec.d.ts +51 -0
  254. package/dist/src/workflows/spec.js +157 -0
  255. package/dist/src/workflows/spec.js.map +1 -0
  256. package/dist/src/workflows/style-contract.d.ts +24 -0
  257. package/dist/src/workflows/style-contract.js +23 -0
  258. package/dist/src/workflows/style-contract.js.map +1 -0
  259. package/dist/src/workflows/writing-review.d.ts +15 -0
  260. package/dist/src/workflows/writing-review.js +82 -0
  261. package/dist/src/workflows/writing-review.js.map +1 -0
  262. package/package.json +73 -0
  263. package/package.json.psyclaw +21 -0
  264. package/skills/core/citation-audit/SKILL.md +9 -0
  265. package/skills/core/evidence-capture/SKILL.md +9 -0
  266. package/skills/core/manifest.json +15 -0
  267. package/skills/core/research-brief/SKILL.md +11 -0
  268. package/skills/core/research-intake/SKILL.md +9 -0
  269. package/skills/recommended/catalog.json +52 -0
  270. package/skills/recommended/mcp-catalog.json +118 -0
@@ -0,0 +1,7 @@
1
+ export type UpdateStatus = "up-to-date" | "outdated" | "unpinned" | "unavailable" | "not-published" | "unknown";
2
+ /** A ref that cannot be compared to a registry version. */
3
+ export declare function isUnpinnedRef(ref: string | undefined): boolean;
4
+ /** Compare two versions; returns null when either side is not parseable semver. */
5
+ export declare function compareSemver(left: string, right: string): number | null;
6
+ /** Classify a pinned version against the latest available version. */
7
+ export declare function versionStatus(current: string | undefined, latest: string | undefined): UpdateStatus;
@@ -0,0 +1,37 @@
1
+ const UNPINNED_REFS = new Set(["", "unpinned", "latest", "head", "main", "master", "*", "unknown"]);
2
+ /** A ref that cannot be compared to a registry version. */
3
+ export function isUnpinnedRef(ref) {
4
+ return ref === undefined || UNPINNED_REFS.has(ref.trim().toLowerCase());
5
+ }
6
+ /** Compare two versions; returns null when either side is not parseable semver. */
7
+ export function compareSemver(left, right) {
8
+ const a = parseSemver(left);
9
+ const b = parseSemver(right);
10
+ if (a === null || b === null)
11
+ return null;
12
+ for (let index = 0; index < 3; index += 1) {
13
+ const x = a[index] ?? 0;
14
+ const y = b[index] ?? 0;
15
+ if (x !== y)
16
+ return x < y ? -1 : 1;
17
+ }
18
+ return 0;
19
+ }
20
+ function parseSemver(value) {
21
+ const match = value.trim().replace(/^v/i, "").match(/^(\d+)\.(\d+)\.(\d+)/);
22
+ if (!match)
23
+ return null;
24
+ return [Number(match[1]), Number(match[2]), Number(match[3])];
25
+ }
26
+ /** Classify a pinned version against the latest available version. */
27
+ export function versionStatus(current, latest) {
28
+ if (latest === undefined)
29
+ return "unavailable";
30
+ if (current === undefined)
31
+ return "unknown";
32
+ const comparison = compareSemver(current, latest);
33
+ if (comparison === null)
34
+ return "unknown";
35
+ return comparison < 0 ? "outdated" : "up-to-date";
36
+ }
37
+ //# sourceMappingURL=status.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.js","sourceRoot":"","sources":["../../../src/updates/status.ts"],"names":[],"mappings":"AAQA,MAAM,aAAa,GAAG,IAAI,GAAG,CAAC,CAAC,EAAE,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,EAAE,SAAS,CAAC,CAAC,CAAC;AAEpG,2DAA2D;AAC3D,MAAM,UAAU,aAAa,CAAC,GAAuB;IACnD,OAAO,GAAG,KAAK,SAAS,IAAI,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC;AAC1E,CAAC;AAED,mFAAmF;AACnF,MAAM,UAAU,aAAa,CAAC,IAAY,EAAE,KAAa;IACvD,MAAM,CAAC,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC;IAC5B,MAAM,CAAC,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC;IAC7B,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAC1C,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;QAC1C,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACxB,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACxB,IAAI,CAAC,KAAK,CAAC;YAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACrC,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC;AAED,SAAS,WAAW,CAAC,KAAa;IAChC,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAAC;IAC5E,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IACxB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAChE,CAAC;AAED,sEAAsE;AACtE,MAAM,UAAU,aAAa,CAAC,OAA2B,EAAE,MAA0B;IACnF,IAAI,MAAM,KAAK,SAAS;QAAE,OAAO,aAAa,CAAC;IAC/C,IAAI,OAAO,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IAC5C,MAAM,UAAU,GAAG,aAAa,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAClD,IAAI,UAAU,KAAK,IAAI;QAAE,OAAO,SAAS,CAAC;IAC1C,OAAO,UAAU,GAAG,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,YAAY,CAAC;AACpD,CAAC"}
@@ -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,126 @@
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
+ return undefined;
25
+ }
26
+ function buildCommand(manager, version) {
27
+ const spec = `${PI_AI}@${version} ${PI_CODING_AGENT}@${version}`;
28
+ return manager === "pnpm" ? `pnpm add --save-exact ${spec}` : `npm install --save-exact ${spec}`;
29
+ }
30
+ /**
31
+ * Update the bundled Pi runtime by re-pinning both `@earendil-works/pi-*`
32
+ * packages to the latest official release. This is the write-side counterpart
33
+ * to `checkUpdates`: it is `--yes`/executor-gated, refuses non-semver versions,
34
+ * and always returns a structured receipt. Without an executor it is a pure
35
+ * plan (no workspace mutation).
36
+ */
37
+ export async function updateBundledPi(options) {
38
+ const now = options.now ?? (() => new Date().toISOString());
39
+ const startedAt = now();
40
+ const finish = (receipt) => ({
41
+ schemaVersion: "psyclaw/pi-update/v1",
42
+ startedAt,
43
+ finishedAt: now(),
44
+ ...receipt,
45
+ });
46
+ const manifest = await resolvePsyClawManifest(options.packageRoot);
47
+ if (manifest === undefined) {
48
+ return finish({
49
+ ok: false,
50
+ executed: false,
51
+ reasonCode: "update-skipped",
52
+ reason: "psyclaw package.json not found",
53
+ packageName: PI_CODING_AGENT,
54
+ });
55
+ }
56
+ let latest;
57
+ try {
58
+ latest = await options.registry.latestPiRelease();
59
+ }
60
+ catch {
61
+ latest = undefined;
62
+ }
63
+ const before = manifest.piVersion;
64
+ const base = {
65
+ packageName: PI_CODING_AGENT,
66
+ ...(before === undefined ? {} : { before }),
67
+ };
68
+ if (latest === undefined) {
69
+ return finish({ ok: false, executed: false, reasonCode: "update-skipped", reason: "latest Pi release unavailable", ...base });
70
+ }
71
+ if (!isSafeVersion(latest.version)) {
72
+ return finish({
73
+ ok: false,
74
+ executed: false,
75
+ reasonCode: "update-skipped",
76
+ reason: `refusing unsafe Pi version: ${latest.version}`,
77
+ latest: latest.version,
78
+ ...base,
79
+ });
80
+ }
81
+ const latestVersion = latest.version;
82
+ const comparison = before === undefined ? null : compareSemver(before, latestVersion);
83
+ const needsUpdate = options.force === true || comparison === null || comparison < 0;
84
+ const withLatest = {
85
+ ...base,
86
+ latest: latestVersion,
87
+ ...(latest.note === undefined ? {} : { note: latest.note }),
88
+ };
89
+ if (!needsUpdate) {
90
+ return finish({ ok: true, executed: false, reasonCode: "already-up-to-date", after: latestVersion, ...withLatest });
91
+ }
92
+ const manager = await packageManagerAt(manifest.root);
93
+ if (manager === undefined) {
94
+ return finish({
95
+ ok: false,
96
+ executed: false,
97
+ reasonCode: "update-skipped",
98
+ reason: "no pnpm-lock.yaml or package-lock.json found in the psyclaw package root",
99
+ ...withLatest,
100
+ });
101
+ }
102
+ const command = buildCommand(manager, latestVersion);
103
+ if (options.executor === undefined) {
104
+ return finish({
105
+ ok: true,
106
+ executed: false,
107
+ reasonCode: "update-skipped",
108
+ reason: "dry run: re-run with --yes to apply",
109
+ command,
110
+ after: latestVersion,
111
+ ...withLatest,
112
+ });
113
+ }
114
+ const { exitCode } = await options.executor({ command, cwd: manifest.root });
115
+ const ok = Number.isInteger(exitCode) && exitCode === 0;
116
+ return finish({
117
+ ok,
118
+ executed: true,
119
+ reasonCode: ok ? "update-applied" : "update-failed",
120
+ command,
121
+ exitCode,
122
+ ...(ok ? { after: latestVersion } : {}),
123
+ ...withLatest,
124
+ });
125
+ }
126
+ //# 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 } 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" }), _jsx(Text, { color: "black", backgroundColor: PSYCLAW_ACCENT, bold: true, children: " v0.24.0 " }), _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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"}