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.
- package/README.md +4 -4
- package/dist/apps/panel/index.html +849 -337
- package/dist/src/adapters/pi/extension.js +87 -15
- package/dist/src/adapters/pi/extension.js.map +1 -1
- package/dist/src/adapters/pi/rpc.js +1 -1
- package/dist/src/adapters/pi/rpc.js.map +1 -1
- package/dist/src/analysis/stats-router.js +1 -1
- package/dist/src/analysis/stats-router.js.map +1 -1
- package/dist/src/ars/mode-editor.d.ts +1 -5
- package/dist/src/ars/mode-editor.js +1 -9
- package/dist/src/ars/mode-editor.js.map +1 -1
- package/dist/src/branding.d.ts +4 -3
- package/dist/src/branding.js +10 -9
- package/dist/src/branding.js.map +1 -1
- package/dist/src/chat.d.ts +7 -0
- package/dist/src/chat.js +19 -1
- package/dist/src/chat.js.map +1 -1
- package/dist/src/cli-args.d.ts +1 -0
- package/dist/src/cli-args.js +1 -0
- package/dist/src/cli-args.js.map +1 -1
- package/dist/src/cli.js +39 -7
- package/dist/src/cli.js.map +1 -1
- package/dist/src/index.d.ts +2 -0
- package/dist/src/index.js +2 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/literature/knowledge-map.d.ts +4 -0
- package/dist/src/literature/knowledge-map.js +4 -0
- package/dist/src/literature/knowledge-map.js.map +1 -1
- package/dist/src/panel/server.js +9 -109
- package/dist/src/panel/server.js.map +1 -1
- package/dist/src/project/bootstrap.js +0 -2
- package/dist/src/project/bootstrap.js.map +1 -1
- package/dist/src/project/workspace.js +3 -3
- package/dist/src/project/workspace.js.map +1 -1
- package/dist/src/research/choice.d.ts +16 -0
- package/dist/src/research/choice.js +25 -0
- package/dist/src/research/choice.js.map +1 -0
- package/dist/src/session/continuously-work.d.ts +16 -0
- package/dist/src/session/continuously-work.js +44 -0
- package/dist/src/session/continuously-work.js.map +1 -0
- package/dist/src/session/help.d.ts +3 -0
- package/dist/src/session/help.js +68 -26
- package/dist/src/session/help.js.map +1 -1
- package/dist/src/session/modes.js +7 -7
- package/dist/src/session/modes.js.map +1 -1
- package/dist/src/style/cli-ui.d.ts +1 -0
- package/dist/src/style/cli-ui.js +26 -14
- package/dist/src/style/cli-ui.js.map +1 -1
- package/dist/src/updates/update.d.ts +8 -1
- package/dist/src/updates/update.js +68 -2
- package/dist/src/updates/update.js.map +1 -1
- package/dist/src/verify/checklist.d.ts +46 -5
- package/dist/src/verify/checklist.js +139 -24
- package/dist/src/verify/checklist.js.map +1 -1
- package/dist/src/wake-options/runtime.d.ts +1 -0
- package/dist/src/wake-options/runtime.js +12 -2
- package/dist/src/wake-options/runtime.js.map +1 -1
- package/package.json +1 -1
- package/skills/recommended/catalog.json +24 -154
- 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"}
|
package/dist/src/panel/server.js
CHANGED
|
@@ -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,
|
|
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"
|
|
1089
|
-
|
|
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
|
-
|
|
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" });
|