psyclaw 0.29.11 → 0.29.13

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 (60) hide show
  1. package/README.md +4 -4
  2. package/dist/apps/panel/index.html +849 -337
  3. package/dist/src/adapters/pi/extension.js +87 -15
  4. package/dist/src/adapters/pi/extension.js.map +1 -1
  5. package/dist/src/adapters/pi/rpc.js +1 -1
  6. package/dist/src/adapters/pi/rpc.js.map +1 -1
  7. package/dist/src/analysis/stats-router.js +1 -1
  8. package/dist/src/analysis/stats-router.js.map +1 -1
  9. package/dist/src/ars/mode-editor.d.ts +1 -5
  10. package/dist/src/ars/mode-editor.js +1 -9
  11. package/dist/src/ars/mode-editor.js.map +1 -1
  12. package/dist/src/branding.d.ts +4 -3
  13. package/dist/src/branding.js +10 -9
  14. package/dist/src/branding.js.map +1 -1
  15. package/dist/src/chat.d.ts +7 -0
  16. package/dist/src/chat.js +19 -1
  17. package/dist/src/chat.js.map +1 -1
  18. package/dist/src/cli-args.d.ts +1 -0
  19. package/dist/src/cli-args.js +1 -0
  20. package/dist/src/cli-args.js.map +1 -1
  21. package/dist/src/cli.js +39 -7
  22. package/dist/src/cli.js.map +1 -1
  23. package/dist/src/index.d.ts +2 -0
  24. package/dist/src/index.js +2 -0
  25. package/dist/src/index.js.map +1 -1
  26. package/dist/src/literature/knowledge-map.d.ts +4 -0
  27. package/dist/src/literature/knowledge-map.js +4 -0
  28. package/dist/src/literature/knowledge-map.js.map +1 -1
  29. package/dist/src/panel/server.js +9 -109
  30. package/dist/src/panel/server.js.map +1 -1
  31. package/dist/src/project/bootstrap.js +0 -2
  32. package/dist/src/project/bootstrap.js.map +1 -1
  33. package/dist/src/project/workspace.js +3 -3
  34. package/dist/src/project/workspace.js.map +1 -1
  35. package/dist/src/research/choice.d.ts +16 -0
  36. package/dist/src/research/choice.js +25 -0
  37. package/dist/src/research/choice.js.map +1 -0
  38. package/dist/src/session/continuously-work.d.ts +16 -0
  39. package/dist/src/session/continuously-work.js +44 -0
  40. package/dist/src/session/continuously-work.js.map +1 -0
  41. package/dist/src/session/help.d.ts +3 -0
  42. package/dist/src/session/help.js +68 -26
  43. package/dist/src/session/help.js.map +1 -1
  44. package/dist/src/session/modes.js +7 -7
  45. package/dist/src/session/modes.js.map +1 -1
  46. package/dist/src/style/cli-ui.d.ts +1 -0
  47. package/dist/src/style/cli-ui.js +26 -14
  48. package/dist/src/style/cli-ui.js.map +1 -1
  49. package/dist/src/updates/update.d.ts +8 -1
  50. package/dist/src/updates/update.js +68 -2
  51. package/dist/src/updates/update.js.map +1 -1
  52. package/dist/src/verify/checklist.d.ts +46 -5
  53. package/dist/src/verify/checklist.js +139 -24
  54. package/dist/src/verify/checklist.js.map +1 -1
  55. package/dist/src/wake-options/runtime.d.ts +1 -0
  56. package/dist/src/wake-options/runtime.js +12 -2
  57. package/dist/src/wake-options/runtime.js.map +1 -1
  58. package/package.json +1 -1
  59. package/skills/recommended/catalog.json +24 -154
  60. package/skills/recommended/mcp-catalog.json +16 -4
@@ -1,4 +1,8 @@
1
1
  import { createHash } from "node:crypto";
2
+ /**
3
+ * Build a verified literature knowledge graph from ledger entries.
4
+ * Currently exported for contracts/tests; primary UI graph uses `src/knowledge-map/`.
5
+ */
2
6
  export function buildVerifiedKnowledgeMap(entries, now = new Date().toISOString()) {
3
7
  const nodes = new Map();
4
8
  const edges = [];
@@ -1 +1 @@
1
- {"version":3,"file":"knowledge-map.js","sourceRoot":"","sources":["../../../src/literature/knowledge-map.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAGzC,MAAM,UAAU,yBAAyB,CAAC,OAAgC,EAAE,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;IACxG,MAAM,KAAK,GAAG,IAAI,GAAG,EAAyB,CAAC;IAC/C,MAAM,KAAK,GAAoB,EAAE,CAAC;IAClC,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,IAAI,KAAK,CAAC,YAAY,KAAK,UAAU;YAAE,SAAS;QAChD,MAAM,IAAI,GAAkB,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,EAAE,KAAK,CAAC,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC;QAC7J,IAAI,CAAC,SAAS,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;QACvF,KAAK,MAAM,MAAM,IAAI,KAAK,CAAC,OAAO,IAAI,EAAE,EAAE,CAAC;YACzC,MAAM,EAAE,GAAG,UAAU,MAAM,CAAC,WAAW,EAAE,EAAE,CAAC;YAC5C,KAAK,CAAC,GAAG,CAAC,EAAE,EAAE,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;YAC7G,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,GAAG,KAAK,CAAC,MAAM,gBAAgB,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,CAAC,MAAM,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,EAAE,EAAE,EAAE,SAAS,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;QAC9J,CAAC;IACH,CAAC;IACD,MAAM,gBAAgB,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAC5F,OAAO,EAAE,aAAa,EAAE,0BAA0B,EAAE,KAAK,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,GAAG,EAAE,gBAAgB,EAAE,CAAC;AAC9H,CAAC"}
1
+ {"version":3,"file":"knowledge-map.js","sourceRoot":"","sources":["../../../src/literature/knowledge-map.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAGzC;;;GAGG;AACH,MAAM,UAAU,yBAAyB,CAAC,OAAgC,EAAE,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;IACxG,MAAM,KAAK,GAAG,IAAI,GAAG,EAAyB,CAAC;IAC/C,MAAM,KAAK,GAAoB,EAAE,CAAC;IAClC,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,IAAI,KAAK,CAAC,YAAY,KAAK,UAAU;YAAE,SAAS;QAChD,MAAM,IAAI,GAAkB,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,EAAE,KAAK,CAAC,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC;QAC7J,IAAI,CAAC,SAAS,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;QACvF,KAAK,MAAM,MAAM,IAAI,KAAK,CAAC,OAAO,IAAI,EAAE,EAAE,CAAC;YACzC,MAAM,EAAE,GAAG,UAAU,MAAM,CAAC,WAAW,EAAE,EAAE,CAAC;YAC5C,KAAK,CAAC,GAAG,CAAC,EAAE,EAAE,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;YAC7G,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,GAAG,KAAK,CAAC,MAAM,gBAAgB,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,CAAC,MAAM,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,EAAE,EAAE,EAAE,SAAS,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;QAC9J,CAAC;IACH,CAAC;IACD,MAAM,gBAAgB,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAC5F,OAAO,EAAE,aAAa,EAAE,0BAA0B,EAAE,KAAK,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,GAAG,EAAE,gBAAgB,EAAE,CAAC;AAC9H,CAAC"}
@@ -1,7 +1,7 @@
1
1
  import { createServer } from "node:http";
2
2
  import { randomUUID } from "node:crypto";
3
3
  import { spawn } from "node:child_process";
4
- import { lstat, mkdir, readFile, readdir, unlink, writeFile } from "node:fs/promises";
4
+ import { lstat, mkdir, readFile, readdir, writeFile } from "node:fs/promises";
5
5
  import { dirname, join } from "node:path";
6
6
  import { fileURLToPath } from "node:url";
7
7
  import { getAgentDir } from "@earendil-works/pi-coding-agent";
@@ -28,15 +28,12 @@ import { listCitationUses, recordCitationUse } from "../core/citations.js";
28
28
  import { readPublishedVersions } from "../workflows/publish.js";
29
29
  // Backward-compatible re-export: existing tests import verifyDoi from the panel server.
30
30
  export { verifyDoi } from "../core/doi.js";
31
- import { resumePlanWithPi } from "../orchestration/pi-executor.js";
32
- import { RunEventLog } from "./events.js";
33
31
  import { PSYCLAW_IDENTITY_PROMPT } from "../branding.js";
34
32
  import { sessionHelpDocument } from "../session/help.js";
35
33
  import { recommendedSkillTarget } from "../skills/recommended.js";
36
34
  import { readUserSkillState, scanLocalSkills, setLocalSkillEnabled, userSkillId, } from "../skills/user-skills.js";
37
35
  import { loadVerifyChecklist, markVerifyItem, skipUnverifiedItems } from "../verify/checklist.js";
38
36
  import { readActiveAnalysisPlan } from "../analysis/plan.js";
39
- const activePanelRuns = new Set();
40
37
  async function readRecommendationState(root) {
41
38
  try {
42
39
  const value = JSON.parse(await readFile(join(root, ".psyclaw", "recommendations.json"), "utf8"));
@@ -797,9 +794,6 @@ export function createPanelServer(root, options = {}) {
797
794
  "/api/crosscheck",
798
795
  "/api/wake-options/respond",
799
796
  ];
800
- // Kept false for source compatibility with the legacy handler below; the
801
- // method gate above makes pause/resume unreachable from the panel API.
802
- const runAction = false;
803
797
  if (request.method !== "GET" && request.method !== "HEAD" && !(request.method === "POST" && panelWriteRoutes.includes(url.pathname))) {
804
798
  response.writeHead(405, { "content-type": "application/json", allow: "GET, HEAD" });
805
799
  response.end(JSON.stringify({ error: "method not allowed" }));
@@ -1085,12 +1079,17 @@ export function createPanelServer(root, options = {}) {
1085
1079
  const status = String(body.status ?? "verified");
1086
1080
  if (!id)
1087
1081
  throw new Error("id is required");
1088
- if (status !== "verified" && status !== "unverified" && status !== "flagged" && status !== "skipped") {
1089
- throw new Error("status must be verified|unverified|flagged|skipped");
1082
+ if (status !== "verified"
1083
+ && status !== "ai-checked"
1084
+ && status !== "unverified"
1085
+ && status !== "flagged"
1086
+ && status !== "skipped") {
1087
+ throw new Error("status must be verified|ai-checked|unverified|flagged|skipped");
1090
1088
  }
1091
1089
  const kind = typeof body.kind === "string" ? body.kind : undefined;
1092
1090
  const notes = typeof body.notes === "string" ? body.notes : undefined;
1093
- const checklist = await markVerifyItem(root, id, status, notes, kind);
1091
+ // Panel clicks are human approvals; AI marks go through /crosscheck in-session.
1092
+ const checklist = await markVerifyItem(root, id, status, notes, kind, { source: "human" });
1094
1093
  response.writeHead(200, { "content-type": "application/json" });
1095
1094
  response.end(JSON.stringify({ schemaVersion: "psyclaw/crosscheck/v1", checklist }));
1096
1095
  return;
@@ -1358,67 +1357,6 @@ export function createPanelServer(root, options = {}) {
1358
1357
  }
1359
1358
  return;
1360
1359
  }
1361
- if (runAction) {
1362
- const match = url.pathname.match(/^\/api\/runs\/([A-Za-z0-9][A-Za-z0-9._-]{0,127})\/(pause|resume)$/);
1363
- const runId = match?.[1] ?? "";
1364
- const action = match?.[2] ?? "";
1365
- const body = await readJsonBody(request);
1366
- const approved = body.approved === true;
1367
- const actor = String(body.actor ?? "").trim();
1368
- const reason = String(body.reason ?? "").trim();
1369
- if (!approved || !actor || reason.length < 3) {
1370
- response.writeHead(400, { "content-type": "application/json" });
1371
- response.end(JSON.stringify({ error: "approved=true, actor, and reason (3+ chars) are required" }));
1372
- return;
1373
- }
1374
- const pausePath = await assertSafeProjectPath(root, `.psyclaw/runs/${runId}.pause`);
1375
- const planPath = await assertSafeProjectPath(root, `.psyclaw/plans/${runId}.json`);
1376
- if (action === "pause") {
1377
- await atomicWriteFile(pausePath, `${JSON.stringify({ schemaVersion: "psyclaw/pause-request/v1", runId, actor, reason, requestedAt: new Date().toISOString() }, null, 2)}\n`);
1378
- response.writeHead(200, { "content-type": "application/json" });
1379
- response.end(JSON.stringify({ schemaVersion: "psyclaw/run-action-receipt/v1", action, runId, status: "pause-requested", actor }));
1380
- return;
1381
- }
1382
- if (activePanelRuns.has(runId)) {
1383
- response.writeHead(409, { "content-type": "application/json" });
1384
- response.end(JSON.stringify({ error: "run is already being resumed" }));
1385
- return;
1386
- }
1387
- let plan;
1388
- try {
1389
- plan = JSON.parse(await readFile(planPath, "utf8"));
1390
- }
1391
- catch {
1392
- response.writeHead(404, { "content-type": "application/json" });
1393
- response.end(JSON.stringify({ error: "run plan not found" }));
1394
- return;
1395
- }
1396
- await unlink(pausePath).catch(() => undefined);
1397
- activePanelRuns.add(runId);
1398
- try {
1399
- const eventLog = new RunEventLog(root, runId);
1400
- const result = await resumePlanWithPi(plan, {
1401
- cwd: root,
1402
- root,
1403
- pauseRequested: async () => {
1404
- try {
1405
- await lstat(pausePath);
1406
- return true;
1407
- }
1408
- catch {
1409
- return false;
1410
- }
1411
- },
1412
- onEvent: async (event) => { await eventLog.append(event); },
1413
- });
1414
- response.writeHead(200, { "content-type": "application/json" });
1415
- response.end(JSON.stringify({ schemaVersion: "psyclaw/run-action-receipt/v1", action, runId, status: result.status, diagnostics: result.diagnostics, actor }));
1416
- }
1417
- finally {
1418
- activePanelRuns.delete(runId);
1419
- }
1420
- return;
1421
- }
1422
1360
  if (url.pathname === "/api/artifacts") {
1423
1361
  const indexPath = projectPaths(root).outputs + "/index.json";
1424
1362
  let indexedArtifacts = [];
@@ -1479,44 +1417,6 @@ export function createPanelServer(root, options = {}) {
1479
1417
  response.end(body);
1480
1418
  return;
1481
1419
  }
1482
- if (url.pathname === "/api/artifact/save") {
1483
- if (request.method !== "POST") {
1484
- response.writeHead(405, { "content-type": "application/json", allow: "POST" });
1485
- response.end(JSON.stringify({ error: "method not allowed" }));
1486
- return;
1487
- }
1488
- const body = await readJsonBody(request);
1489
- const relative = String(body.path ?? "").trim();
1490
- const content = typeof body.content === "string" ? body.content : "";
1491
- if (!relative || !/\.svg$/i.test(relative))
1492
- throw new Error("only SVG artifacts can be edited");
1493
- const rel = relative.replaceAll("\\", "/");
1494
- if (rel.split("/").some((part) => part === ".." || part === ""))
1495
- throw new Error("a relative artifact path is required");
1496
- if (!rel.startsWith("outputs/") && !rel.startsWith("analysis/outputs/"))
1497
- throw new Error("artifact must be under outputs/ or analysis/outputs/");
1498
- const target = await assertSafeProjectPath(root, rel);
1499
- const stat = await lstat(target).catch(() => undefined);
1500
- if (stat !== undefined && (stat.isSymbolicLink() || !stat.isFile()))
1501
- throw new Error("artifact must be a regular file");
1502
- await atomicWriteFile(target, content.endsWith("\n") ? content : `${content}\n`);
1503
- const receipt = {
1504
- schemaVersion: "psyclaw/tool-receipt/v1",
1505
- runId: `panel_${randomUUID().replaceAll("-", "")}`,
1506
- taskId: "panel.artifact.save",
1507
- tool: "panel.artifact.save",
1508
- effect: "write",
1509
- approval: "approved",
1510
- idempotencyKey: `panel:artifact:${sha256Text(`${rel}\u0000${content}`).slice(0, 24)}`,
1511
- ok: true,
1512
- startedAt: new Date().toISOString(),
1513
- finishedAt: new Date().toISOString(),
1514
- };
1515
- await atomicWriteFile(await assertSafeProjectPath(root, `.psyclaw/manifests/${receipt.runId}.receipt.json`), `${JSON.stringify(receipt, null, 2)}\n`);
1516
- response.writeHead(200, { "content-type": "application/json" });
1517
- response.end(JSON.stringify({ schemaVersion: "psyclaw/artifact-save-receipt/v1", ok: true, path: rel, bytes: Buffer.byteLength(content, "utf8") }));
1518
- return;
1519
- }
1520
1420
  if (url.pathname === "/api/ledger") {
1521
1421
  const ledger = await loadLedger(root);
1522
1422
  response.writeHead(200, { "content-type": "application/json" });