psyclaw 0.29.3 → 0.29.5
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 +20 -5
- package/dist/apps/panel/index.html +262 -2
- package/dist/src/adapters/pi/extension.js +151 -26
- package/dist/src/adapters/pi/extension.js.map +1 -1
- package/dist/src/analysis/plan.d.ts +23 -0
- package/dist/src/analysis/plan.js +39 -2
- package/dist/src/analysis/plan.js.map +1 -1
- package/dist/src/analysis/stats-router.js +3 -2
- package/dist/src/analysis/stats-router.js.map +1 -1
- package/dist/src/ars/keybindings.d.ts +10 -5
- package/dist/src/ars/keybindings.js +20 -10
- package/dist/src/ars/keybindings.js.map +1 -1
- package/dist/src/branding.js +3 -1
- package/dist/src/branding.js.map +1 -1
- package/dist/src/cli.js +12 -2
- package/dist/src/cli.js.map +1 -1
- package/dist/src/index.d.ts +1 -0
- package/dist/src/index.js +1 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/network-routing.d.ts +10 -0
- package/dist/src/network-routing.js +46 -4
- package/dist/src/network-routing.js.map +1 -1
- package/dist/src/panel/extension.d.ts +2 -5
- package/dist/src/panel/extension.js +15 -91
- package/dist/src/panel/extension.js.map +1 -1
- package/dist/src/panel/server.js +37 -1
- package/dist/src/panel/server.js.map +1 -1
- package/dist/src/panel/workbench.d.ts +16 -0
- package/dist/src/panel/workbench.js +78 -0
- package/dist/src/panel/workbench.js.map +1 -0
- package/dist/src/session/help.d.ts +24 -0
- package/dist/src/session/help.js +64 -0
- package/dist/src/session/help.js.map +1 -0
- package/dist/src/session/modes.js +3 -2
- package/dist/src/session/modes.js.map +1 -1
- package/dist/src/skills/recommended.js +3 -1
- package/dist/src/skills/recommended.js.map +1 -1
- package/dist/src/style/cli-ui.js +7 -6
- package/dist/src/style/cli-ui.js.map +1 -1
- package/dist/src/updates/registry.d.ts +12 -1
- package/dist/src/updates/registry.js +12 -4
- package/dist/src/updates/registry.js.map +1 -1
- package/dist/src/updates/update.d.ts +2 -0
- package/dist/src/updates/update.js +11 -8
- package/dist/src/updates/update.js.map +1 -1
- package/dist/src/verify/checklist.d.ts +9 -2
- package/dist/src/verify/checklist.js +70 -15
- package/dist/src/verify/checklist.js.map +1 -1
- package/package.json +4 -1
- package/skills/core/analysis-plan/SKILL.md +21 -11
- package/skills/recommended/catalog.json +84 -2
- package/skills/scholars/README.md +20 -0
- package/skills/scholars/freud-perspective/SKILL.md +70 -0
- package/skills/scholars/gelman-perspective/SKILL.md +66 -0
- package/skills/scholars/kahneman-perspective/SKILL.md +71 -0
- package/vendor/nuwa-skill/LICENSE +21 -0
- package/vendor/nuwa-skill/NOTICE.md +9 -0
- package/vendor/nuwa-skill/PROVENANCE.json +1 -0
- package/vendor/nuwa-skill/README.md +378 -0
- package/vendor/nuwa-skill/README_EN.md +290 -0
- package/vendor/nuwa-skill/SKILL.md +709 -0
- package/vendor/nuwa-skill/references/extraction-framework.md +151 -0
- package/vendor/nuwa-skill/references/fidelity-scorecard.md +63 -0
- package/vendor/nuwa-skill/references/skill-template.md +117 -0
- package/vendor/nuwa-skill/scripts/merge_research.py +150 -0
- package/vendor/nuwa-skill/scripts/quality_check.py +152 -0
|
@@ -1,110 +1,34 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { DefaultPackageManager, getAgentDir, SettingsManager } from "@earendil-works/pi-coding-agent";
|
|
3
|
-
import { createPanelServer } from "./server.js";
|
|
4
|
-
async function listen(server, port) {
|
|
5
|
-
await new Promise((resolve, reject) => {
|
|
6
|
-
server.once("error", reject);
|
|
7
|
-
server.listen(port, "127.0.0.1", () => resolve());
|
|
8
|
-
});
|
|
9
|
-
const address = server.address();
|
|
10
|
-
return typeof address === "object" && address !== null ? address.port : port;
|
|
11
|
-
}
|
|
12
|
-
function openWorkbench(url) {
|
|
13
|
-
return new Promise((resolve) => {
|
|
14
|
-
const command = process.platform === "win32" ? "cmd" : process.platform === "darwin" ? "open" : "xdg-open";
|
|
15
|
-
const args = process.platform === "win32" ? ["/c", "start", "", url] : [url];
|
|
16
|
-
let child;
|
|
17
|
-
try {
|
|
18
|
-
child = spawn(command, args, { detached: true, stdio: "ignore", windowsHide: true });
|
|
19
|
-
}
|
|
20
|
-
catch {
|
|
21
|
-
resolve(false);
|
|
22
|
-
return;
|
|
23
|
-
}
|
|
24
|
-
child.once("error", () => resolve(false));
|
|
25
|
-
child.once("spawn", () => resolve(true));
|
|
26
|
-
child.unref();
|
|
27
|
-
});
|
|
28
|
-
}
|
|
1
|
+
import { closeResearchWorkbench, openResearchWorkbench } from "./workbench.js";
|
|
29
2
|
/**
|
|
30
|
-
* Optional Pi extension for the local
|
|
31
|
-
* psyclaw package does not load this extension by default; `/agents` remains a
|
|
32
|
-
* native core command. Binding is always loopback and the panel has no write
|
|
33
|
-
* endpoint.
|
|
3
|
+
* Optional Pi extension for the local web projection. Binding is always loopback.
|
|
34
4
|
*/
|
|
35
5
|
export default function psyclawPanelExtension(pi) {
|
|
36
|
-
let server;
|
|
37
|
-
let workbenchUrl;
|
|
38
|
-
const close = async () => {
|
|
39
|
-
const current = server;
|
|
40
|
-
server = undefined;
|
|
41
|
-
workbenchUrl = undefined;
|
|
42
|
-
if (!current)
|
|
43
|
-
return;
|
|
44
|
-
await new Promise((resolve) => current.close(() => resolve()));
|
|
45
|
-
};
|
|
46
6
|
pi.registerCommand("panel", {
|
|
47
|
-
description: "
|
|
7
|
+
description: "打开科研工作台(浏览器)",
|
|
48
8
|
handler: async (args, ctx) => {
|
|
49
|
-
|
|
50
|
-
|
|
9
|
+
const trimmed = args.trim().toLowerCase();
|
|
10
|
+
if (trimmed && trimmed !== "help" && !trimmed.startsWith("view=")) {
|
|
11
|
+
ctx.ui.notify("用法:/panel 或 /panel help", "info");
|
|
51
12
|
return;
|
|
52
13
|
}
|
|
14
|
+
const view = trimmed === "help" || trimmed === "view=help" ? "help" : undefined;
|
|
53
15
|
try {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
assistant: async (message) => {
|
|
62
|
-
pi.sendUserMessage(message, ctx.isIdle() ? {} : { deliverAs: "followUp" });
|
|
63
|
-
return { text: "✓ 指令/提问已转入当前 PsyClaw 智能体并在终端会话中执行。" };
|
|
64
|
-
},
|
|
65
|
-
installSkill: async (task) => {
|
|
66
|
-
pi.sendUserMessage(task, ctx.isIdle() ? {} : { deliverAs: "followUp" });
|
|
67
|
-
},
|
|
68
|
-
installExternalTool: async (task) => {
|
|
69
|
-
pi.sendUserMessage(task, ctx.isIdle() ? {} : { deliverAs: "followUp" });
|
|
70
|
-
},
|
|
71
|
-
installPlugin: async (source, scope) => {
|
|
72
|
-
await packageManager().installAndPersist(source, { local: scope === "project" });
|
|
73
|
-
},
|
|
74
|
-
listPlugins: () => packageManager().listConfiguredPackages().map(({ source, scope, filtered, installedPath }) => ({
|
|
75
|
-
source,
|
|
76
|
-
scope,
|
|
77
|
-
filtered,
|
|
78
|
-
installed: installedPath !== undefined,
|
|
79
|
-
})),
|
|
80
|
-
});
|
|
81
|
-
const actualPort = await listen(next, 0);
|
|
82
|
-
server = next;
|
|
83
|
-
workbenchUrl = `http://127.0.0.1:${actualPort}`;
|
|
84
|
-
}
|
|
85
|
-
openWorkbench(workbenchUrl).then((opened) => {
|
|
86
|
-
if (opened) {
|
|
87
|
-
ctx.ui.notify(`科研工作台已在浏览器中打开:${workbenchUrl}`, "info");
|
|
88
|
-
}
|
|
89
|
-
else {
|
|
90
|
-
// The local server is up regardless; give the user a reachable
|
|
91
|
-
// fallback instead of leaving them with a dead-end error.
|
|
92
|
-
ctx.ui.notify(`科研工作台已启动,但未能自动打开浏览器。请手动访问:${workbenchUrl}`, "warning");
|
|
93
|
-
}
|
|
94
|
-
}).catch((error) => {
|
|
95
|
-
ctx.ui.notify(`科研工作台已启动,但自动打开失败:${error instanceof Error ? error.message : String(error)}。请手动访问:${workbenchUrl}`, "warning");
|
|
96
|
-
});
|
|
16
|
+
const { url, opened } = await openResearchWorkbench({
|
|
17
|
+
cwd: ctx.cwd,
|
|
18
|
+
isProjectTrusted: () => ctx.isProjectTrusted(),
|
|
19
|
+
isIdle: () => ctx.isIdle(),
|
|
20
|
+
sendUserMessage: (message, options) => pi.sendUserMessage(message, options ?? {}),
|
|
21
|
+
}, view ? { view } : {});
|
|
22
|
+
ctx.ui.notify(opened ? `科研工作台已打开:${url}` : `工作台已启动,请手动访问:${url}`, opened ? "info" : "warning");
|
|
97
23
|
}
|
|
98
24
|
catch (error) {
|
|
99
|
-
server = undefined;
|
|
100
|
-
workbenchUrl = undefined;
|
|
101
25
|
const detail = error instanceof Error ? error.message : String(error);
|
|
102
26
|
ctx.ui.notify(`科研工作台启动失败:${detail}`, "error");
|
|
103
27
|
}
|
|
104
28
|
},
|
|
105
29
|
});
|
|
106
30
|
pi.on("session_shutdown", async () => {
|
|
107
|
-
await
|
|
31
|
+
await closeResearchWorkbench();
|
|
108
32
|
});
|
|
109
33
|
}
|
|
110
34
|
//# sourceMappingURL=extension.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extension.js","sourceRoot":"","sources":["../../../src/panel/extension.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"extension.js","sourceRoot":"","sources":["../../../src/panel/extension.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AAE/E;;GAEG;AACH,MAAM,CAAC,OAAO,UAAU,qBAAqB,CAAC,EAAgB;IAC5D,EAAE,CAAC,eAAe,CAAC,OAAO,EAAE;QAC1B,WAAW,EAAE,cAAc;QAC3B,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE;YAC3B,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;YAC1C,IAAI,OAAO,IAAI,OAAO,KAAK,MAAM,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;gBAClE,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,yBAAyB,EAAE,MAAM,CAAC,CAAC;gBACjD,OAAO;YACT,CAAC;YACD,MAAM,IAAI,GAAG,OAAO,KAAK,MAAM,IAAI,OAAO,KAAK,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC;YAChF,IAAI,CAAC;gBACH,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,MAAM,qBAAqB,CAAC;oBAClD,GAAG,EAAE,GAAG,CAAC,GAAG;oBACZ,gBAAgB,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,gBAAgB,EAAE;oBAC9C,MAAM,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,MAAM,EAAE;oBAC1B,eAAe,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,CAAC,EAAE,CAAC,eAAe,CAAC,OAAO,EAAE,OAAO,IAAI,EAAE,CAAC;iBAClF,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;gBACzB,GAAG,CAAC,EAAE,CAAC,MAAM,CACX,MAAM,CAAC,CAAC,CAAC,YAAY,GAAG,EAAE,CAAC,CAAC,CAAC,gBAAgB,GAAG,EAAE,EAClD,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAC5B,CAAC;YACJ,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,MAAM,MAAM,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;gBACtE,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,aAAa,MAAM,EAAE,EAAE,OAAO,CAAC,CAAC;YAChD,CAAC;QACH,CAAC;KACF,CAAC,CAAC;IAEH,EAAE,CAAC,EAAE,CAAC,kBAAkB,EAAE,KAAK,IAAI,EAAE;QACnC,MAAM,sBAAsB,EAAE,CAAC;IACjC,CAAC,CAAC,CAAC;AACL,CAAC"}
|
package/dist/src/panel/server.js
CHANGED
|
@@ -30,9 +30,10 @@ export { verifyDoi } from "../core/doi.js";
|
|
|
30
30
|
import { resumePlanWithPi } from "../orchestration/pi-executor.js";
|
|
31
31
|
import { RunEventLog } from "./events.js";
|
|
32
32
|
import { PSYCLAW_IDENTITY_PROMPT } from "../branding.js";
|
|
33
|
+
import { sessionHelpDocument } from "../session/help.js";
|
|
33
34
|
import { recommendedSkillTarget } from "../skills/recommended.js";
|
|
34
35
|
import { readUserSkillState, scanLocalSkills, setLocalSkillEnabled, userSkillId, } from "../skills/user-skills.js";
|
|
35
|
-
import { loadVerifyChecklist } from "../verify/checklist.js";
|
|
36
|
+
import { loadVerifyChecklist, markVerifyItem, skipUnverifiedItems } from "../verify/checklist.js";
|
|
36
37
|
import { readActiveAnalysisPlan } from "../analysis/plan.js";
|
|
37
38
|
const activePanelRuns = new Set();
|
|
38
39
|
async function readRecommendationState(root) {
|
|
@@ -864,6 +865,11 @@ export function createPanelServer(root, options = {}) {
|
|
|
864
865
|
response.end(JSON.stringify(await panelStats(root)));
|
|
865
866
|
return;
|
|
866
867
|
}
|
|
868
|
+
if (url.pathname === "/api/help") {
|
|
869
|
+
response.writeHead(200, { "content-type": "application/json" });
|
|
870
|
+
response.end(JSON.stringify({ schemaVersion: "psyclaw/panel-help/v1", ...sessionHelpDocument() }));
|
|
871
|
+
return;
|
|
872
|
+
}
|
|
867
873
|
if (url.pathname === "/api/files") {
|
|
868
874
|
response.writeHead(200, { "content-type": "application/json" });
|
|
869
875
|
response.end(JSON.stringify({ schemaVersion: "psyclaw/panel-files/v1", files: await listProjectFiles(root) }));
|
|
@@ -983,6 +989,36 @@ export function createPanelServer(root, options = {}) {
|
|
|
983
989
|
}));
|
|
984
990
|
return;
|
|
985
991
|
}
|
|
992
|
+
if (url.pathname === "/api/crosscheck") {
|
|
993
|
+
if (request.method === "GET") {
|
|
994
|
+
const checklist = await loadVerifyChecklist(root);
|
|
995
|
+
response.writeHead(200, { "content-type": "application/json" });
|
|
996
|
+
response.end(JSON.stringify({ schemaVersion: "psyclaw/crosscheck/v1", checklist }));
|
|
997
|
+
return;
|
|
998
|
+
}
|
|
999
|
+
if (request.method !== "POST")
|
|
1000
|
+
throw new Error("method not allowed");
|
|
1001
|
+
const body = await readJsonBody(request);
|
|
1002
|
+
if (body.action === "skip") {
|
|
1003
|
+
const checklist = await skipUnverifiedItems(root, typeof body.reason === "string" ? body.reason : undefined);
|
|
1004
|
+
response.writeHead(200, { "content-type": "application/json" });
|
|
1005
|
+
response.end(JSON.stringify({ schemaVersion: "psyclaw/crosscheck/v1", checklist }));
|
|
1006
|
+
return;
|
|
1007
|
+
}
|
|
1008
|
+
const id = String(body.id ?? "").trim();
|
|
1009
|
+
const status = String(body.status ?? "verified");
|
|
1010
|
+
if (!id)
|
|
1011
|
+
throw new Error("id is required");
|
|
1012
|
+
if (status !== "verified" && status !== "unverified" && status !== "flagged" && status !== "skipped") {
|
|
1013
|
+
throw new Error("status must be verified|unverified|flagged|skipped");
|
|
1014
|
+
}
|
|
1015
|
+
const kind = typeof body.kind === "string" ? body.kind : undefined;
|
|
1016
|
+
const notes = typeof body.notes === "string" ? body.notes : undefined;
|
|
1017
|
+
const checklist = await markVerifyItem(root, id, status, notes, kind);
|
|
1018
|
+
response.writeHead(200, { "content-type": "application/json" });
|
|
1019
|
+
response.end(JSON.stringify({ schemaVersion: "psyclaw/crosscheck/v1", checklist }));
|
|
1020
|
+
return;
|
|
1021
|
+
}
|
|
986
1022
|
if (url.pathname === "/api/active-provider") {
|
|
987
1023
|
if (request.method === "GET") {
|
|
988
1024
|
const settings = await readAgentSettings();
|