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,81 @@
1
+ import { mkdir } from "node:fs/promises";
2
+ import { join } from "node:path";
3
+ import { randomUUID } from "node:crypto";
4
+ import { checkEvidenceSufficiency } from "../core/evidence-policy.js";
5
+ import { projectPaths } from "../project/paths.js";
6
+ import { loadLedger, readProject } from "./ledger.js";
7
+ import { writeHandoff } from "../project/bootstrap.js";
8
+ import { atomicWriteFile } from "../project/jsonl.js";
9
+ import { RunEventLog } from "../panel/events.js";
10
+ export async function runOfflineBrief(root) {
11
+ const paths = projectPaths(root);
12
+ const runId = `run_${randomUUID().replaceAll("-", "")}`;
13
+ const project = await readProject(root);
14
+ const ledger = await loadLedger(root);
15
+ const gates = checkEvidenceSufficiency({ ...ledger, paradigm: project.paradigm });
16
+ const blocked = gates.filter((gate) => !gate.ok);
17
+ const eventLog = new RunEventLog(root, runId);
18
+ const eventAt = new Date().toISOString();
19
+ await eventLog.append({ type: "planned", at: eventAt });
20
+ for (const gate of gates)
21
+ await eventLog.append({ type: "gate", at: eventAt, message: gate.reason });
22
+ await eventLog.append({
23
+ type: blocked.length === 0 ? "completed" : "blocked",
24
+ at: eventAt,
25
+ message: blocked.length === 0 ? "all evidence gates passed" : "evidence gates blocked",
26
+ });
27
+ const manifest = {
28
+ schemaVersion: "psyclaw/brief-manifest/v1",
29
+ runId,
30
+ inputs: ledger.evidence.map((item) => ({ id: item.id, sha256: item.sha256, locator: item.source.locator })),
31
+ claims: ledger.claims.map((claim) => ({ id: claim.id, status: claim.status, evidenceIds: claim.evidenceIds })),
32
+ gates,
33
+ generatedAt: new Date().toISOString(),
34
+ };
35
+ await mkdir(paths.manifests, { recursive: true });
36
+ const manifestPath = join(paths.manifests, `${runId}.json`);
37
+ await atomicWriteFile(manifestPath, `${JSON.stringify(manifest, null, 2)}\n`);
38
+ let briefPath;
39
+ if (blocked.length === 0) {
40
+ const goal = project.goal;
41
+ const lines = [
42
+ "# Research Brief",
43
+ "",
44
+ `Research goal: ${goal}`,
45
+ "",
46
+ "## Audited Claims",
47
+ "",
48
+ ...ledger.claims.map((claim) => `- ${claim.text} [${claim.status}]`),
49
+ "",
50
+ "Evidence and limitations are recorded in the manifest and ledger.",
51
+ "",
52
+ ];
53
+ briefPath = join(paths.outputs, "brief.md");
54
+ await atomicWriteFile(briefPath, lines.join("\n"));
55
+ }
56
+ const verdictPath = join(paths.manifests, `${runId}.verdict.json`);
57
+ const verdict = {
58
+ schemaVersion: "psyclaw/verdict/v1",
59
+ runId,
60
+ verdict: blocked.length === 0 ? "pass" : "blocked",
61
+ manifestPath,
62
+ ...(briefPath ? { briefPath } : {}),
63
+ gateCount: gates.length,
64
+ blockedGateCount: blocked.length,
65
+ generatedAt: new Date().toISOString(),
66
+ };
67
+ await atomicWriteFile(verdictPath, `${JSON.stringify(verdict, null, 2)}\n`);
68
+ const handoff = await writeHandoff(root, {
69
+ projectId: project.id,
70
+ runId,
71
+ goal: project.goal,
72
+ completed: ["evidence ledger loaded", "evidence sufficiency gates evaluated"],
73
+ verified: blocked.length === 0 ? ["brief.md", "manifest", "verdict"] : ["manifest", "verdict"],
74
+ blocked: blocked.map((gate) => gate.reason),
75
+ nextSteps: blocked.length === 0 ? ["human review before external use"] : ["resolve blocked evidence gates"],
76
+ verificationCommands: ["pnpm typecheck", "pnpm test"],
77
+ generatedAt: new Date().toISOString(),
78
+ });
79
+ return { runId, verdict: blocked.length === 0 ? "pass" : "blocked", gates, ...(briefPath ? { briefPath } : {}), manifestPath, verdictPath, handoff };
80
+ }
81
+ //# sourceMappingURL=brief.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"brief.js","sourceRoot":"","sources":["../../../src/research/brief.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import type { Claim, ClaimEvidenceLink, Evidence } from "../core/contracts.js";
2
+ export interface LedgerSnapshot {
3
+ evidence: Evidence[];
4
+ claims: Claim[];
5
+ links: ClaimEvidenceLink[];
6
+ }
7
+ export declare function loadLedger(root: string): Promise<LedgerSnapshot>;
8
+ export declare function appendEvidence(root: string, evidence: Evidence): Promise<void>;
9
+ export declare function appendClaim(root: string, claim: Claim): Promise<void>;
10
+ export declare function appendClaimEvidenceLink(root: string, link: ClaimEvidenceLink): Promise<void>;
11
+ export declare function readProjectGoal(root: string): Promise<string>;
12
+ export declare function readProject(root: string): Promise<import("../core/contracts.js").ResearchProject>;
@@ -0,0 +1,43 @@
1
+ import { readFile } from "node:fs/promises";
2
+ import { appendJsonl, readJsonl } from "../project/jsonl.js";
3
+ import { projectPaths } from "../project/paths.js";
4
+ import { asClaim, asClaimEvidenceLink, asEvidence, asProject } from "../core/schemas.js";
5
+ export async function loadLedger(root) {
6
+ const paths = projectPaths(root);
7
+ const evidence = (await readJsonl(paths.evidence)).map((value) => asEvidence(value));
8
+ const claims = [];
9
+ const links = [];
10
+ for (const value of await readJsonl(paths.claims)) {
11
+ if (typeof value !== "object" || value === null)
12
+ throw new Error("Invalid claims record");
13
+ if ("relation" in value && "claimId" in value && "evidenceId" in value) {
14
+ links.push(asClaimEvidenceLink(value));
15
+ }
16
+ else {
17
+ claims.push(asClaim(value));
18
+ }
19
+ }
20
+ return {
21
+ evidence,
22
+ claims,
23
+ links,
24
+ };
25
+ }
26
+ export async function appendEvidence(root, evidence) {
27
+ asEvidence(evidence);
28
+ await appendJsonl(projectPaths(root).evidence, evidence);
29
+ }
30
+ export async function appendClaim(root, claim) {
31
+ await appendJsonl(projectPaths(root).claims, asClaim({ ...claim, recordType: "claim" }));
32
+ }
33
+ export async function appendClaimEvidenceLink(root, link) {
34
+ await appendJsonl(projectPaths(root).claims, asClaimEvidenceLink({ ...link, recordType: "claim-evidence-link" }));
35
+ }
36
+ export async function readProjectGoal(root) {
37
+ const project = asProject(JSON.parse(await readFile(projectPaths(root).project, "utf8")));
38
+ return project.goal;
39
+ }
40
+ export async function readProject(root) {
41
+ return asProject(JSON.parse(await readFile(projectPaths(root).project, "utf8")));
42
+ }
43
+ //# sourceMappingURL=ledger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ledger.js","sourceRoot":"","sources":["../../../src/research/ledger.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,mBAAmB,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AASzF,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,IAAY;IAC3C,MAAM,KAAK,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;IACjC,MAAM,QAAQ,GAAG,CAAC,MAAM,SAAS,CAAU,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC;IAC9F,MAAM,MAAM,GAAY,EAAE,CAAC;IAC3B,MAAM,KAAK,GAAwB,EAAE,CAAC;IACtC,KAAK,MAAM,KAAK,IAAI,MAAM,SAAS,CAAU,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC;QAC3D,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI;YAAE,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;QAC1F,IAAI,UAAU,IAAI,KAAK,IAAI,SAAS,IAAI,KAAK,IAAI,YAAY,IAAI,KAAK,EAAE,CAAC;YACvE,KAAK,CAAC,IAAI,CAAC,mBAAmB,CAAC,KAAK,CAAC,CAAC,CAAC;QACzC,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;QAC9B,CAAC;IACH,CAAC;IACD,OAAO;QACL,QAAQ;QACR,MAAM;QACN,KAAK;KACN,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,IAAY,EAAE,QAAkB;IACnE,UAAU,CAAC,QAAQ,CAAC,CAAC;IACrB,MAAM,WAAW,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;AAC3D,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,IAAY,EAAE,KAAY;IAC1D,MAAM,WAAW,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC;AAC3F,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAAC,IAAY,EAAE,IAAuB;IACjF,MAAM,WAAW,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,mBAAmB,CAAC,EAAE,GAAG,IAAI,EAAE,UAAU,EAAE,qBAAqB,EAAE,CAAC,CAAC,CAAC;AACpH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,IAAY;IAChD,MAAM,OAAO,GAAG,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,QAAQ,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;IAC1F,OAAO,OAAO,CAAC,IAAI,CAAC;AACtB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,IAAY;IAC5C,OAAO,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,QAAQ,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;AACnF,CAAC"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Staged progress output for psyclaw workflows: prints `[stage] label…` lines
3
+ * the way a research pipeline reads. The stage tag is rendered in the psyclaw
4
+ * accent color; notes are dimmed. Used by the `psyclaw_workflow` tool (captured
5
+ * into the tool result) and by TTY sessions. Pure line formatting is exported
6
+ * for tests.
7
+ */
8
+ export declare function formatStageLine(tag: string, label: string, color?: boolean): string;
9
+ export declare function formatNoteLine(note: string, color?: boolean): string;
10
+ export interface StageRunnerOptions {
11
+ /** Override stdout (tests). */
12
+ write?: (line: string) => void;
13
+ color?: boolean;
14
+ }
15
+ export interface StageRunner {
16
+ /** Print `[tag] label…`, run `fn`, then print an optional completion note. */
17
+ stage<T>(tag: string, label: string, fn: () => Promise<T>, onDone?: (result: T) => string): Promise<T>;
18
+ note(message: string): void;
19
+ }
20
+ export declare function createStageRunner(options?: StageRunnerOptions): StageRunner;
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Staged progress output for psyclaw workflows: prints `[stage] label…` lines
3
+ * the way a research pipeline reads. The stage tag is rendered in the psyclaw
4
+ * accent color; notes are dimmed. Used by the `psyclaw_workflow` tool (captured
5
+ * into the tool result) and by TTY sessions. Pure line formatting is exported
6
+ * for tests.
7
+ */
8
+ const ACCENT = "\x1b[36m"; // teal
9
+ const DIM = "\x1b[2m";
10
+ const RESET = "\x1b[0m";
11
+ export function formatStageLine(tag, label, color = true) {
12
+ const tagPart = color ? `${ACCENT}[${tag}]${RESET}` : `[${tag}]`;
13
+ return `${tagPart} ${label}`;
14
+ }
15
+ export function formatNoteLine(note, color = true) {
16
+ return color ? ` ${DIM}${note}${RESET}` : ` ${note}`;
17
+ }
18
+ export function createStageRunner(options = {}) {
19
+ const write = options.write ?? ((line) => process.stdout.write(`${line}\n`));
20
+ const color = options.color ?? process.stdout.isTTY;
21
+ return {
22
+ note(message) {
23
+ write(formatNoteLine(message, color));
24
+ },
25
+ async stage(tag, label, fn, onDone) {
26
+ write(formatStageLine(tag, `${label}…`, color));
27
+ const result = await fn();
28
+ if (onDone !== undefined)
29
+ write(formatNoteLine(onDone(result), color));
30
+ return result;
31
+ },
32
+ };
33
+ }
34
+ //# sourceMappingURL=run.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run.js","sourceRoot":"","sources":["../../src/run.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,MAAM,GAAG,UAAU,CAAC,CAAC,OAAO;AAClC,MAAM,GAAG,GAAG,SAAS,CAAC;AACtB,MAAM,KAAK,GAAG,SAAS,CAAC;AAExB,MAAM,UAAU,eAAe,CAAC,GAAW,EAAE,KAAa,EAAE,KAAK,GAAG,IAAI;IACtE,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI,GAAG,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,GAAG,GAAG,CAAC;IACjE,OAAO,GAAG,OAAO,IAAI,KAAK,EAAE,CAAC;AAC/B,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,IAAY,EAAE,KAAK,GAAG,IAAI;IACvD,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,GAAG,GAAG,IAAI,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;AACzD,CAAC;AAcD,MAAM,UAAU,iBAAiB,CAAC,UAA8B,EAAE;IAChE,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC;IAC7E,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC;IACpD,OAAO;QACL,IAAI,CAAC,OAAe;YAClB,KAAK,CAAC,cAAc,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC;QACxC,CAAC;QACD,KAAK,CAAC,KAAK,CAAI,GAAW,EAAE,KAAa,EAAE,EAAoB,EAAE,MAA8B;YAC7F,KAAK,CAAC,eAAe,CAAC,GAAG,EAAE,GAAG,KAAK,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC;YAChD,MAAM,MAAM,GAAG,MAAM,EAAE,EAAE,CAAC;YAC1B,IAAI,MAAM,KAAK,SAAS;gBAAE,KAAK,CAAC,cAAc,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC;YACvE,OAAO,MAAM,CAAC;QAChB,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,54 @@
1
+ export interface ProviderPreset {
2
+ id: string;
3
+ name: string;
4
+ baseUrl: string;
5
+ api: "openai-completions" | "anthropic-messages";
6
+ apiKeyEnv: string;
7
+ models: readonly {
8
+ id: string;
9
+ name: string;
10
+ reasoning?: boolean;
11
+ }[];
12
+ }
13
+ /**
14
+ * Generic, provider-neutral presets. None of these embed a literal API key:
15
+ * the `apiKey` is written as an environment-variable reference (`$ENV`), so
16
+ * the user supplies the secret in their shell environment, never on disk.
17
+ */
18
+ export declare const PROVIDER_PRESETS: readonly ProviderPreset[];
19
+ export interface SetupOptions {
20
+ agentDir?: string;
21
+ /** Provider ids to write; defaults to all presets (the generic guide). */
22
+ providers?: readonly string[];
23
+ }
24
+ export interface SetupResult {
25
+ path: string;
26
+ providers: string[];
27
+ }
28
+ export interface ProviderConfigInput {
29
+ id: string;
30
+ name: string;
31
+ baseUrl: string;
32
+ api: "openai-completions" | "anthropic-messages";
33
+ apiKeyEnv: string;
34
+ models: readonly {
35
+ id: string;
36
+ name?: string;
37
+ reasoning?: boolean;
38
+ }[];
39
+ apiKey?: string;
40
+ }
41
+ /** Persist provider metadata and, when supplied, the key in Pi's auth store. */
42
+ export declare function saveProviderConfig(input: ProviderConfigInput, options?: {
43
+ agentDir?: string;
44
+ }): Promise<SetupResult>;
45
+ /**
46
+ * Write Pi's `models.json` with the selected provider presets, merging into
47
+ * any existing providers rather than clobbering them. No API key literal is
48
+ * ever written — only `$ENV_VAR` references.
49
+ */
50
+ export declare function setupProviders(options?: SetupOptions): Promise<SetupResult>;
51
+ /** Whether any provider has been written to `models.json` yet. */
52
+ export declare function hasConfiguredProvider(options?: {
53
+ agentDir?: string;
54
+ }): Promise<boolean>;
@@ -0,0 +1,221 @@
1
+ import { getAgentDir } from "@earendil-works/pi-coding-agent";
2
+ import { mkdir, readFile, writeFile } from "node:fs/promises";
3
+ import { join } from "node:path";
4
+ import { dirname } from "node:path";
5
+ import { fileURLToPath, pathToFileURL } from "node:url";
6
+ import { DEFAULT_PRICING, PROVIDER_PRICING } from "./core/pricing.js";
7
+ /**
8
+ * Generic, provider-neutral presets. None of these embed a literal API key:
9
+ * the `apiKey` is written as an environment-variable reference (`$ENV`), so
10
+ * the user supplies the secret in their shell environment, never on disk.
11
+ */
12
+ export const PROVIDER_PRESETS = [
13
+ {
14
+ id: "deepseek",
15
+ name: "DeepSeek",
16
+ baseUrl: "https://api.deepseek.com",
17
+ api: "openai-completions",
18
+ apiKeyEnv: "DEEPSEEK_API_KEY",
19
+ models: [
20
+ { id: "deepseek-v4-flash", name: "DeepSeek V4 Flash" },
21
+ { id: "deepseek-v4-pro", name: "DeepSeek V4 Pro", reasoning: true },
22
+ ],
23
+ },
24
+ {
25
+ id: "openai",
26
+ name: "OpenAI",
27
+ baseUrl: "https://api.openai.com/v1",
28
+ api: "openai-completions",
29
+ apiKeyEnv: "OPENAI_API_KEY",
30
+ models: [
31
+ { id: "gpt-5.5", name: "GPT-5.5" },
32
+ { id: "gpt-5.5-pro", name: "GPT-5.5 Pro", reasoning: true },
33
+ ],
34
+ },
35
+ {
36
+ id: "anthropic",
37
+ name: "Anthropic",
38
+ baseUrl: "https://api.anthropic.com",
39
+ api: "anthropic-messages",
40
+ apiKeyEnv: "ANTHROPIC_API_KEY",
41
+ models: [
42
+ { id: "claude-sonnet-4-6", name: "Claude Sonnet 4.6" },
43
+ { id: "claude-opus-4-8", name: "Claude Opus 4.8", reasoning: true },
44
+ ],
45
+ },
46
+ {
47
+ id: "qwen",
48
+ name: "通义千问",
49
+ baseUrl: "https://dashscope.aliyuncs.com/compatible-mode",
50
+ api: "openai-completions",
51
+ apiKeyEnv: "DASHSCOPE_API_KEY",
52
+ models: [
53
+ { id: "qwen3.6-plus", name: "Qwen 3.6 Plus" },
54
+ { id: "qwen3.7-max", name: "Qwen 3.7 Max", reasoning: true },
55
+ { id: "qwen3.6-flash", name: "Qwen 3.6 Flash" },
56
+ ],
57
+ },
58
+ {
59
+ id: "zhipu",
60
+ name: "智谱 GLM",
61
+ baseUrl: "https://open.bigmodel.cn/api/paas/v4",
62
+ api: "openai-completions",
63
+ apiKeyEnv: "ZHIPU_API_KEY",
64
+ models: [
65
+ { id: "glm-5", name: "GLM-5", reasoning: true },
66
+ { id: "glm-5.1", name: "GLM-5.1", reasoning: true },
67
+ { id: "glm-5-turbo", name: "GLM-5 Turbo" },
68
+ ],
69
+ },
70
+ {
71
+ id: "moonshot",
72
+ name: "月之暗面 Kimi",
73
+ baseUrl: "https://api.moonshot.cn/v1",
74
+ api: "openai-completions",
75
+ apiKeyEnv: "MOONSHOT_API_KEY",
76
+ models: [
77
+ { id: "kimi-k2.6", name: "Kimi K2.6", reasoning: true },
78
+ { id: "kimi-k2.5", name: "Kimi K2.5" },
79
+ ],
80
+ },
81
+ {
82
+ id: "ollama",
83
+ name: "Ollama(本地)",
84
+ baseUrl: "http://localhost:11434/v1",
85
+ api: "openai-completions",
86
+ apiKeyEnv: "OLLAMA_API_KEY",
87
+ models: [
88
+ { id: "qwen3:8b", name: "Qwen3 8B" },
89
+ { id: "qwen3:14b", name: "Qwen3 14B" },
90
+ { id: "deepseek-r1:8b", name: "DeepSeek R1 8B", reasoning: true },
91
+ ],
92
+ },
93
+ {
94
+ id: "custom",
95
+ name: "自定义 OpenAI 兼容接口",
96
+ baseUrl: "",
97
+ api: "openai-completions",
98
+ apiKeyEnv: "PSYCLAW_CUSTOM_API_KEY",
99
+ models: [],
100
+ },
101
+ ];
102
+ function providerToJson(preset) {
103
+ const pricing = PROVIDER_PRICING[preset.id] ?? DEFAULT_PRICING;
104
+ return {
105
+ baseUrl: preset.baseUrl,
106
+ api: preset.api,
107
+ apiKey: `$${preset.apiKeyEnv}`,
108
+ models: preset.models.map((model) => ({
109
+ id: model.id,
110
+ name: model.name,
111
+ ...(model.reasoning === undefined ? {} : { reasoning: model.reasoning }),
112
+ cost: { ...pricing },
113
+ })),
114
+ };
115
+ }
116
+ function providerConfig(input) {
117
+ if (!/^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/.test(input.id))
118
+ throw new Error("Invalid provider id");
119
+ if (!/^[A-Z][A-Z0-9_]{0,127}$/.test(input.apiKeyEnv))
120
+ throw new Error("Invalid API key environment name");
121
+ if (input.baseUrl) {
122
+ const url = new URL(input.baseUrl);
123
+ if (url.protocol !== "http:" && url.protocol !== "https:")
124
+ throw new Error("Provider endpoint must use http or https");
125
+ if (url.username || url.password || url.hash)
126
+ throw new Error("Provider endpoint must not contain credentials or fragments");
127
+ }
128
+ if (input.models.length === 0)
129
+ throw new Error("At least one model is required");
130
+ const pricing = PROVIDER_PRICING[input.id] ?? DEFAULT_PRICING;
131
+ return {
132
+ baseUrl: input.baseUrl,
133
+ api: input.api,
134
+ apiKey: `$${input.apiKeyEnv}`,
135
+ models: input.models.map((model) => ({
136
+ id: model.id,
137
+ name: model.name ?? model.id,
138
+ ...(model.reasoning === undefined ? {} : { reasoning: model.reasoning }),
139
+ cost: { ...pricing },
140
+ })),
141
+ };
142
+ }
143
+ /** Persist provider metadata and, when supplied, the key in Pi's auth store. */
144
+ export async function saveProviderConfig(input, options = {}) {
145
+ const agentDir = options.agentDir ?? getAgentDir();
146
+ const modelsPath = join(agentDir, "models.json");
147
+ let existing = {};
148
+ try {
149
+ const parsed = JSON.parse(await readFile(modelsPath, "utf8"));
150
+ if (parsed.providers && typeof parsed.providers === "object" && !Array.isArray(parsed.providers)) {
151
+ existing.providers = parsed.providers;
152
+ }
153
+ }
154
+ catch { /* start with a new catalog */ }
155
+ await mkdir(agentDir, { recursive: true });
156
+ await writeFile(modelsPath, `${JSON.stringify({ providers: { ...existing.providers, [input.id]: providerConfig(input) } }, null, 2)}\n`, "utf8");
157
+ if (input.apiKey?.trim()) {
158
+ // AuthStorage is intentionally not part of Pi's public root export. Resolve
159
+ // the locked runtime's implementation without reading or logging secrets.
160
+ const entry = fileURLToPath(import.meta.resolve("@earendil-works/pi-coding-agent"));
161
+ const { AuthStorage } = await import(pathToFileURL(join(dirname(entry), "core", "auth-storage.js")).href);
162
+ const auth = AuthStorage.create(join(agentDir, "auth.json"));
163
+ await auth.modify(input.id, async () => ({ type: "api_key", key: input.apiKey.trim() }));
164
+ }
165
+ return { path: modelsPath, providers: [input.id] };
166
+ }
167
+ /**
168
+ * Write Pi's `models.json` with the selected provider presets, merging into
169
+ * any existing providers rather than clobbering them. No API key literal is
170
+ * ever written — only `$ENV_VAR` references.
171
+ */
172
+ export async function setupProviders(options = {}) {
173
+ const agentDir = options.agentDir ?? getAgentDir();
174
+ const modelsPath = join(agentDir, "models.json");
175
+ const selected = options.providers && options.providers.length > 0
176
+ ? options.providers
177
+ : PROVIDER_PRESETS.map((preset) => preset.id);
178
+ const providers = {};
179
+ for (const id of selected) {
180
+ const preset = PROVIDER_PRESETS.find((candidate) => candidate.id === id);
181
+ if (!preset)
182
+ throw new Error(`Unknown provider: ${id}`);
183
+ providers[id] = providerToJson(preset);
184
+ }
185
+ let existing = {};
186
+ try {
187
+ const parsed = JSON.parse(await readFile(modelsPath, "utf8"));
188
+ if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
189
+ const candidate = parsed.providers;
190
+ if (candidate && typeof candidate === "object" && !Array.isArray(candidate)) {
191
+ existing = { providers: candidate };
192
+ }
193
+ }
194
+ }
195
+ catch {
196
+ // Missing or malformed file: start from the presets.
197
+ }
198
+ await mkdir(agentDir, { recursive: true });
199
+ const merged = { ...existing.providers, ...providers };
200
+ await writeFile(modelsPath, `${JSON.stringify({ providers: merged }, null, 2)}\n`, "utf8");
201
+ return { path: modelsPath, providers: Object.keys(providers) };
202
+ }
203
+ /** Whether any provider has been written to `models.json` yet. */
204
+ export async function hasConfiguredProvider(options = {}) {
205
+ const agentDir = options.agentDir ?? getAgentDir();
206
+ const modelsPath = join(agentDir, "models.json");
207
+ try {
208
+ const parsed = JSON.parse(await readFile(modelsPath, "utf8"));
209
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed))
210
+ return false;
211
+ const providers = parsed.providers;
212
+ return providers !== undefined &&
213
+ typeof providers === "object" &&
214
+ !Array.isArray(providers) &&
215
+ Object.keys(providers).length > 0;
216
+ }
217
+ catch {
218
+ return false;
219
+ }
220
+ }
221
+ //# sourceMappingURL=setup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup.js","sourceRoot":"","sources":["../../src/setup.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAC9D,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC9D,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACxD,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAWtE;;;;GAIG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAA8B;IACzD;QACE,EAAE,EAAE,UAAU;QACd,IAAI,EAAE,UAAU;QAChB,OAAO,EAAE,0BAA0B;QACnC,GAAG,EAAE,oBAAoB;QACzB,SAAS,EAAE,kBAAkB;QAC7B,MAAM,EAAE;YACN,EAAE,EAAE,EAAE,mBAAmB,EAAE,IAAI,EAAE,mBAAmB,EAAE;YACtD,EAAE,EAAE,EAAE,iBAAiB,EAAE,IAAI,EAAE,iBAAiB,EAAE,SAAS,EAAE,IAAI,EAAE;SACpE;KACF;IACD;QACE,EAAE,EAAE,QAAQ;QACZ,IAAI,EAAE,QAAQ;QACd,OAAO,EAAE,2BAA2B;QACpC,GAAG,EAAE,oBAAoB;QACzB,SAAS,EAAE,gBAAgB;QAC3B,MAAM,EAAE;YACN,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE;YAClC,EAAE,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,aAAa,EAAE,SAAS,EAAE,IAAI,EAAE;SAC5D;KACF;IACD;QACE,EAAE,EAAE,WAAW;QACf,IAAI,EAAE,WAAW;QACjB,OAAO,EAAE,2BAA2B;QACpC,GAAG,EAAE,oBAAoB;QACzB,SAAS,EAAE,mBAAmB;QAC9B,MAAM,EAAE;YACN,EAAE,EAAE,EAAE,mBAAmB,EAAE,IAAI,EAAE,mBAAmB,EAAE;YACtD,EAAE,EAAE,EAAE,iBAAiB,EAAE,IAAI,EAAE,iBAAiB,EAAE,SAAS,EAAE,IAAI,EAAE;SACpE;KACF;IACD;QACE,EAAE,EAAE,MAAM;QACV,IAAI,EAAE,MAAM;QACZ,OAAO,EAAE,gDAAgD;QACzD,GAAG,EAAE,oBAAoB;QACzB,SAAS,EAAE,mBAAmB;QAC9B,MAAM,EAAE;YACN,EAAE,EAAE,EAAE,cAAc,EAAE,IAAI,EAAE,eAAe,EAAE;YAC7C,EAAE,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,cAAc,EAAE,SAAS,EAAE,IAAI,EAAE;YAC5D,EAAE,EAAE,EAAE,eAAe,EAAE,IAAI,EAAE,gBAAgB,EAAE;SAChD;KACF;IACD;QACE,EAAE,EAAE,OAAO;QACX,IAAI,EAAE,QAAQ;QACd,OAAO,EAAE,sCAAsC;QAC/C,GAAG,EAAE,oBAAoB;QACzB,SAAS,EAAE,eAAe;QAC1B,MAAM,EAAE;YACN,EAAE,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE;YAC/C,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,IAAI,EAAE;YACnD,EAAE,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,aAAa,EAAE;SAC3C;KACF;IACD;QACE,EAAE,EAAE,UAAU;QACd,IAAI,EAAE,WAAW;QACjB,OAAO,EAAE,4BAA4B;QACrC,GAAG,EAAE,oBAAoB;QACzB,SAAS,EAAE,kBAAkB;QAC7B,MAAM,EAAE;YACN,EAAE,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,WAAW,EAAE,SAAS,EAAE,IAAI,EAAE;YACvD,EAAE,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,WAAW,EAAE;SACvC;KACF;IACD;QACE,EAAE,EAAE,QAAQ;QACZ,IAAI,EAAE,YAAY;QAClB,OAAO,EAAE,2BAA2B;QACpC,GAAG,EAAE,oBAAoB;QACzB,SAAS,EAAE,gBAAgB;QAC3B,MAAM,EAAE;YACN,EAAE,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE;YACpC,EAAE,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,WAAW,EAAE;YACtC,EAAE,EAAE,EAAE,gBAAgB,EAAE,IAAI,EAAE,gBAAgB,EAAE,SAAS,EAAE,IAAI,EAAE;SAClE;KACF;IACD;QACE,EAAE,EAAE,QAAQ;QACZ,IAAI,EAAE,iBAAiB;QACvB,OAAO,EAAE,EAAE;QACX,GAAG,EAAE,oBAAoB;QACzB,SAAS,EAAE,wBAAwB;QACnC,MAAM,EAAE,EAAE;KACX;CACF,CAAC;AAEF,SAAS,cAAc,CAAC,MAAsB;IAC5C,MAAM,OAAO,GAAG,gBAAgB,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,eAAe,CAAC;IAC/D,OAAO;QACL,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,GAAG,EAAE,MAAM,CAAC,GAAG;QACf,MAAM,EAAE,IAAI,MAAM,CAAC,SAAS,EAAE;QAC9B,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;YACpC,EAAE,EAAE,KAAK,CAAC,EAAE;YACZ,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,GAAG,CAAC,KAAK,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,CAAC;YACxE,IAAI,EAAE,EAAE,GAAG,OAAO,EAAE;SACrB,CAAC,CAAC;KACJ,CAAC;AACJ,CAAC;AAuBD,SAAS,cAAc,CAAC,KAA0B;IAChD,IAAI,CAAC,qCAAqC,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAC;IAClG,IAAI,CAAC,yBAAyB,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC;IAC1G,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;QAClB,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACnC,IAAI,GAAG,CAAC,QAAQ,KAAK,OAAO,IAAI,GAAG,CAAC,QAAQ,KAAK,QAAQ;YAAE,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC;QACvH,IAAI,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,IAAI;YAAE,MAAM,IAAI,KAAK,CAAC,6DAA6D,CAAC,CAAC;IAC/H,CAAC;IACD,IAAI,KAAK,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC;IACjF,MAAM,OAAO,GAAG,gBAAgB,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,eAAe,CAAC;IAC9D,OAAO;QACL,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,GAAG,EAAE,KAAK,CAAC,GAAG;QACd,MAAM,EAAE,IAAI,KAAK,CAAC,SAAS,EAAE;QAC7B,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;YACnC,EAAE,EAAE,KAAK,CAAC,EAAE;YACZ,IAAI,EAAE,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,EAAE;YAC5B,GAAG,CAAC,KAAK,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,CAAC;YACxE,IAAI,EAAE,EAAE,GAAG,OAAO,EAAE;SACrB,CAAC,CAAC;KACJ,CAAC;AACJ,CAAC;AAED,gFAAgF;AAChF,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,KAA0B,EAAE,UAAiC,EAAE;IACtG,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,WAAW,EAAE,CAAC;IACnD,MAAM,UAAU,GAAG,IAAI,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC;IACjD,IAAI,QAAQ,GAA4C,EAAE,CAAC;IAC3D,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC,CAA4B,CAAC;QACzF,IAAI,MAAM,CAAC,SAAS,IAAI,OAAO,MAAM,CAAC,SAAS,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC;YACjG,QAAQ,CAAC,SAAS,GAAG,MAAM,CAAC,SAAoC,CAAC;QACnE,CAAC;IACH,CAAC;IAAC,MAAM,CAAC,CAAC,8BAA8B,CAAC,CAAC;IAC1C,MAAM,KAAK,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC3C,MAAM,SAAS,CAAC,UAAU,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,SAAS,EAAE,EAAE,GAAG,QAAQ,CAAC,SAAS,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,cAAc,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACjJ,IAAI,KAAK,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE,CAAC;QACzB,4EAA4E;QAC5E,0EAA0E;QAC1E,MAAM,KAAK,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,iCAAiC,CAAC,CAAC,CAAC;QACpF,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,iBAAiB,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAC1G,MAAM,IAAI,GAAG,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC,CAAC;QAC7D,MAAM,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,EAAE,KAAK,CAAC,MAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC;IAC5F,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,SAAS,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC;AACrD,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,UAAwB,EAAE;IAC7D,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,WAAW,EAAE,CAAC;IACnD,MAAM,UAAU,GAAG,IAAI,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC;IACjD,MAAM,QAAQ,GAAG,OAAO,CAAC,SAAS,IAAI,OAAO,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC;QAChE,CAAC,CAAC,OAAO,CAAC,SAAS;QACnB,CAAC,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IAEhD,MAAM,SAAS,GAA4B,EAAE,CAAC;IAC9C,KAAK,MAAM,EAAE,IAAI,QAAQ,EAAE,CAAC;QAC1B,MAAM,MAAM,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;QACzE,IAAI,CAAC,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,qBAAqB,EAAE,EAAE,CAAC,CAAC;QACxD,SAAS,CAAC,EAAE,CAAC,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC;IACzC,CAAC;IAED,IAAI,QAAQ,GAA4C,EAAE,CAAC;IAC3D,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC,CAAY,CAAC;QACzE,IAAI,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YACnE,MAAM,SAAS,GAAI,MAAkC,CAAC,SAAS,CAAC;YAChE,IAAI,SAAS,IAAI,OAAO,SAAS,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC;gBAC5E,QAAQ,GAAG,EAAE,SAAS,EAAE,SAAoC,EAAE,CAAC;YACjE,CAAC;QACH,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,qDAAqD;IACvD,CAAC;IAED,MAAM,KAAK,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC3C,MAAM,MAAM,GAAG,EAAE,GAAG,QAAQ,CAAC,SAAS,EAAE,GAAG,SAAS,EAAE,CAAC;IACvD,MAAM,SAAS,CAAC,UAAU,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAC3F,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;AACjE,CAAC;AAED,kEAAkE;AAClE,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,UAAiC,EAAE;IAC7E,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,WAAW,EAAE,CAAC;IACnD,MAAM,UAAU,GAAG,IAAI,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC;IACjD,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC,CAAY,CAAC;QACzE,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;YAAE,OAAO,KAAK,CAAC;QACjF,MAAM,SAAS,GAAI,MAAkC,CAAC,SAAS,CAAC;QAChE,OAAO,SAAS,KAAK,SAAS;YAC5B,OAAO,SAAS,KAAK,QAAQ;YAC7B,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC;YACzB,MAAM,CAAC,IAAI,CAAC,SAAmB,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;IAChD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}
@@ -0,0 +1,105 @@
1
+ /** The descriptor is the only object needed by a router during discovery. */
2
+ export declare const SKILL_DESCRIPTOR_VERSION: "psyclaw/skill-descriptor/v1";
3
+ export type SkillLicenseStatus = "verified" | "declared" | "missing" | "invalid" | "unknown";
4
+ export type SkillDependencyStatus = "ready" | "declared" | "missing" | "blocked" | "unknown";
5
+ export type SkillTrustStatus = "trusted" | "untrusted" | "blocked" | "unknown";
6
+ export type SkillRiskLevel = "low" | "medium" | "high" | "critical" | "unknown";
7
+ /**
8
+ * Host-side approval is deliberately separate from descriptor metadata.
9
+ * A skill may describe itself as `trusted`, but only an approval supplied by
10
+ * the host can move it out of discover-only mode.
11
+ */
12
+ export type SkillApprovalStatus = "discover-only" | "approved" | "blocked" | "stale";
13
+ /**
14
+ * Host-generated supply-chain evidence. These fields deliberately live
15
+ * outside SKILL.md frontmatter: a skill cannot certify its own license,
16
+ * dependency audit, or SBOM.
17
+ */
18
+ export interface SkillAdmissionEvidence {
19
+ schemaVersion: "psyclaw/skill-admission/v1";
20
+ contentSha256: string;
21
+ licenseSpdx: string;
22
+ licenseEvidenceRef: string;
23
+ dependencyEvidenceRef: string;
24
+ sbomSha256: string;
25
+ }
26
+ export interface SkillApproval {
27
+ /** `false` is an explicit deny and takes precedence over every other field. */
28
+ approved: boolean;
29
+ /** Optional content pin. When present, it must match the discovered SHA. */
30
+ sha256?: string;
31
+ /** Optional logical path pin, resolved relative to the process cwd. */
32
+ sourcePath?: string;
33
+ /** Optional canonical path pin. Useful for lock/manifest based approvals. */
34
+ resolvedPath?: string;
35
+ /** Required host-side manifest/SBOM attestation for execution. */
36
+ admission?: SkillAdmissionEvidence;
37
+ }
38
+ export type SkillApprovalEntry = boolean | SkillApproval;
39
+ export type SkillApprovalMap = Readonly<Record<string, SkillApprovalEntry>> | ReadonlyMap<string, SkillApprovalEntry>;
40
+ export interface SkillDescriptor {
41
+ schemaVersion: typeof SKILL_DESCRIPTOR_VERSION;
42
+ /** Stable id used by routing and explicit load/enable operations. */
43
+ id: string;
44
+ name: string;
45
+ description: string;
46
+ /** Absolute path as discovered from the caller-provided root. */
47
+ sourcePath: string;
48
+ /** Canonical path used for reads; never a symlink. */
49
+ resolvedPath: string;
50
+ /** Canonical root under which the skill was discovered. */
51
+ rootPath: string;
52
+ /** SHA-256 of the complete SKILL.md file, including frontmatter. */
53
+ sha256: string;
54
+ licenseStatus: SkillLicenseStatus;
55
+ dependencyStatus: SkillDependencyStatus;
56
+ /** Metadata-derived trust; never sufficient for execution by itself. */
57
+ trust: SkillTrustStatus;
58
+ risk: SkillRiskLevel;
59
+ /** Host approval state. `discover-only` is the secure default. */
60
+ approvalStatus: SkillApprovalStatus;
61
+ /** Runtime routing toggle; always false after discovery until explicitly enabled. */
62
+ enabled: boolean;
63
+ /** Duplicate ids are retained and marked instead of being overwritten. */
64
+ conflicted: boolean;
65
+ /** YAML frontmatter only. It never contains the Markdown body. */
66
+ metadata: Readonly<Record<string, unknown>>;
67
+ }
68
+ export interface LoadedSkill extends SkillDescriptor {
69
+ /** Markdown after the YAML frontmatter delimiter. */
70
+ body: string;
71
+ }
72
+ export type SkillDiagnosticSeverity = "warning" | "error";
73
+ export type SkillDiagnosticCode = "root-not-found" | "root-not-directory" | "root-symlink" | "path-traversal" | "symlink-path" | "invalid-frontmatter" | "invalid-metadata" | "read-error" | "hash-error" | "duplicate-id" | "not-found" | "ambiguous-id" | "blocked-skill" | "suspicious-body";
74
+ export interface SkillDiagnostic {
75
+ code: SkillDiagnosticCode;
76
+ severity: SkillDiagnosticSeverity;
77
+ message: string;
78
+ path?: string;
79
+ skillId?: string;
80
+ relatedPaths?: string[];
81
+ }
82
+ export interface SkillDiscoveryReport {
83
+ skills: SkillDescriptor[];
84
+ diagnostics: SkillDiagnostic[];
85
+ }
86
+ export interface SkillRegistryOptions {
87
+ roots?: string[];
88
+ /** Explicit id allowlist. This is shorthand for `{ [id]: true }`. */
89
+ approvedIds?: readonly string[];
90
+ /** Explicit host approvals, optionally pinned to content and paths. */
91
+ approvals?: SkillApprovalMap;
92
+ /** Descriptive alias for `approvals` when loading a trust manifest. */
93
+ approvalMap?: SkillApprovalMap;
94
+ /** Backwards-compatible singular alias for `approvals`. */
95
+ approval?: SkillApprovalMap;
96
+ /**
97
+ * Deprecated compatibility option. Frontmatter `enabledByDefault` never
98
+ * grants host approval and this option is intentionally ignored.
99
+ */
100
+ enableByDefault?: boolean;
101
+ }
102
+ export interface SkillSearchOptions {
103
+ enabledOnly?: boolean;
104
+ limit?: number;
105
+ }
@@ -0,0 +1,3 @@
1
+ /** The descriptor is the only object needed by a router during discovery. */
2
+ export const SKILL_DESCRIPTOR_VERSION = "psyclaw/skill-descriptor/v1";
3
+ //# sourceMappingURL=contracts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contracts.js","sourceRoot":"","sources":["../../../src/skills/contracts.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,MAAM,CAAC,MAAM,wBAAwB,GAAG,6BAAsC,CAAC"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Content preflight for skill bodies. This is a heuristic tripwire, not an OS
3
+ * boundary: a body that instructs the agent to bypass gates or move data out
4
+ * of the project is marked suspicious and the skill is never executable.
5
+ */
6
+ export interface PreflightResult {
7
+ suspicious: boolean;
8
+ findings: string[];
9
+ }
10
+ export declare function preflightSkillBody(body: string): PreflightResult;