psyclaw 0.24.0 → 0.25.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.
- package/README.md +46 -53
- package/{dist/apps → apps}/panel/index.html +28 -50
- package/package.json +10 -20
- package/scripts/__pycache__/build_dist.cpython-314.pyc +0 -0
- package/scripts/__pycache__/build_whitepaper_docx.cpython-314.pyc +0 -0
- package/scripts/build_preprint_docx.py +729 -0
- package/scripts/build_preprint_figures.py +238 -0
- package/scripts/build_three_line_table_fixture.py +56 -0
- package/scripts/build_whitepaper_docx.py +768 -0
- package/scripts/check-branding.mjs +159 -0
- package/scripts/copy-panel.mjs +11 -0
- package/scripts/rebrand-pi.mjs +291 -0
- package/scripts/verify_docx.py +41 -0
- package/skills/core/citation-audit/SKILL.md +9 -9
- package/skills/core/evidence-capture/SKILL.md +9 -9
- package/skills/core/manifest.json +15 -15
- package/skills/core/research-brief/SKILL.md +8 -8
- package/skills/core/research-intake/SKILL.md +9 -9
- package/dist/src/adapters/pi/extension.d.ts +0 -19
- package/dist/src/adapters/pi/extension.js +0 -735
- package/dist/src/adapters/pi/extension.js.map +0 -1
- package/dist/src/adapters/pi/model.d.ts +0 -72
- package/dist/src/adapters/pi/model.js +0 -152
- package/dist/src/adapters/pi/model.js.map +0 -1
- package/dist/src/adapters/pi/resources.d.ts +0 -23
- package/dist/src/adapters/pi/resources.js +0 -54
- package/dist/src/adapters/pi/resources.js.map +0 -1
- package/dist/src/adapters/pi/rpc.d.ts +0 -56
- package/dist/src/adapters/pi/rpc.js +0 -248
- package/dist/src/adapters/pi/rpc.js.map +0 -1
- package/dist/src/adapters/pi/session.d.ts +0 -30
- package/dist/src/adapters/pi/session.js +0 -64
- package/dist/src/adapters/pi/session.js.map +0 -1
- package/dist/src/agents/catalog.d.ts +0 -30
- package/dist/src/agents/catalog.js +0 -118
- package/dist/src/agents/catalog.js.map +0 -1
- package/dist/src/agents/discover.d.ts +0 -28
- package/dist/src/agents/discover.js +0 -127
- package/dist/src/agents/discover.js.map +0 -1
- package/dist/src/agents/import.d.ts +0 -67
- package/dist/src/agents/import.js +0 -801
- package/dist/src/agents/import.js.map +0 -1
- package/dist/src/analysis/hooks.d.ts +0 -81
- package/dist/src/analysis/hooks.js +0 -139
- package/dist/src/analysis/hooks.js.map +0 -1
- package/dist/src/analysis/pre-registration.d.ts +0 -18
- package/dist/src/analysis/pre-registration.js +0 -86
- package/dist/src/analysis/pre-registration.js.map +0 -1
- package/dist/src/branding.d.ts +0 -43
- package/dist/src/branding.js +0 -127
- package/dist/src/branding.js.map +0 -1
- package/dist/src/chat.d.ts +0 -16
- package/dist/src/chat.js +0 -67
- package/dist/src/chat.js.map +0 -1
- package/dist/src/cli.d.ts +0 -2
- package/dist/src/cli.js +0 -316
- package/dist/src/cli.js.map +0 -1
- package/dist/src/core/citations.d.ts +0 -44
- package/dist/src/core/citations.js +0 -48
- package/dist/src/core/citations.js.map +0 -1
- package/dist/src/core/contracts.d.ts +0 -119
- package/dist/src/core/contracts.js +0 -2
- package/dist/src/core/contracts.js.map +0 -1
- package/dist/src/core/docx.d.ts +0 -11
- package/dist/src/core/docx.js +0 -46
- package/dist/src/core/docx.js.map +0 -1
- package/dist/src/core/doi.d.ts +0 -41
- package/dist/src/core/doi.js +0 -82
- package/dist/src/core/doi.js.map +0 -1
- package/dist/src/core/evidence-policy.d.ts +0 -24
- package/dist/src/core/evidence-policy.js +0 -308
- package/dist/src/core/evidence-policy.js.map +0 -1
- package/dist/src/core/filekind.d.ts +0 -15
- package/dist/src/core/filekind.js +0 -82
- package/dist/src/core/filekind.js.map +0 -1
- package/dist/src/core/hash.d.ts +0 -2
- package/dist/src/core/hash.js +0 -17
- package/dist/src/core/hash.js.map +0 -1
- package/dist/src/core/pricing.d.ts +0 -38
- package/dist/src/core/pricing.js +0 -110
- package/dist/src/core/pricing.js.map +0 -1
- package/dist/src/core/redact.d.ts +0 -12
- package/dist/src/core/redact.js +0 -48
- package/dist/src/core/redact.js.map +0 -1
- package/dist/src/core/references.d.ts +0 -55
- package/dist/src/core/references.js +0 -102
- package/dist/src/core/references.js.map +0 -1
- package/dist/src/core/schemas.d.ts +0 -162
- package/dist/src/core/schemas.js +0 -160
- package/dist/src/core/schemas.js.map +0 -1
- package/dist/src/extension.d.ts +0 -1
- package/dist/src/extension.js +0 -2
- package/dist/src/extension.js.map +0 -1
- package/dist/src/index.d.ts +0 -72
- package/dist/src/index.js +0 -73
- package/dist/src/index.js.map +0 -1
- package/dist/src/install/installer.d.ts +0 -147
- package/dist/src/install/installer.js +0 -743
- package/dist/src/install/installer.js.map +0 -1
- package/dist/src/integrations/contracts.d.ts +0 -35
- package/dist/src/integrations/contracts.js +0 -27
- package/dist/src/integrations/contracts.js.map +0 -1
- package/dist/src/integrations/mcp.d.ts +0 -155
- package/dist/src/integrations/mcp.js +0 -826
- package/dist/src/integrations/mcp.js.map +0 -1
- package/dist/src/knowledge-map/contracts.d.ts +0 -20
- package/dist/src/knowledge-map/contracts.js +0 -2
- package/dist/src/knowledge-map/contracts.js.map +0 -1
- package/dist/src/knowledge-map/index.d.ts +0 -4
- package/dist/src/knowledge-map/index.js +0 -39
- package/dist/src/knowledge-map/index.js.map +0 -1
- package/dist/src/literature/contracts.d.ts +0 -106
- package/dist/src/literature/contracts.js +0 -2
- package/dist/src/literature/contracts.js.map +0 -1
- package/dist/src/literature/fulltext.d.ts +0 -7
- package/dist/src/literature/fulltext.js +0 -24
- package/dist/src/literature/fulltext.js.map +0 -1
- package/dist/src/literature/knowledge-map.d.ts +0 -2
- package/dist/src/literature/knowledge-map.js +0 -20
- package/dist/src/literature/knowledge-map.js.map +0 -1
- package/dist/src/literature/ledger.d.ts +0 -3
- package/dist/src/literature/ledger.js +0 -17
- package/dist/src/literature/ledger.js.map +0 -1
- package/dist/src/literature/metadata.d.ts +0 -6
- package/dist/src/literature/metadata.js +0 -32
- package/dist/src/literature/metadata.js.map +0 -1
- package/dist/src/memory/store.d.ts +0 -22
- package/dist/src/memory/store.js +0 -73
- package/dist/src/memory/store.js.map +0 -1
- package/dist/src/orchestration/contracts.d.ts +0 -61
- package/dist/src/orchestration/contracts.js +0 -2
- package/dist/src/orchestration/contracts.js.map +0 -1
- package/dist/src/orchestration/pi-executor.d.ts +0 -28
- package/dist/src/orchestration/pi-executor.js +0 -169
- package/dist/src/orchestration/pi-executor.js.map +0 -1
- package/dist/src/orchestration/runner.d.ts +0 -196
- package/dist/src/orchestration/runner.js +0 -991
- package/dist/src/orchestration/runner.js.map +0 -1
- package/dist/src/orchestration/scheduler.d.ts +0 -8
- package/dist/src/orchestration/scheduler.js +0 -335
- package/dist/src/orchestration/scheduler.js.map +0 -1
- package/dist/src/panel/events.d.ts +0 -20
- package/dist/src/panel/events.js +0 -93
- package/dist/src/panel/events.js.map +0 -1
- package/dist/src/panel/extension.d.ts +0 -8
- package/dist/src/panel/extension.js +0 -114
- package/dist/src/panel/extension.js.map +0 -1
- package/dist/src/panel/literature-map.d.ts +0 -26
- package/dist/src/panel/literature-map.js +0 -34
- package/dist/src/panel/literature-map.js.map +0 -1
- package/dist/src/panel/projection.d.ts +0 -51
- package/dist/src/panel/projection.js +0 -288
- package/dist/src/panel/projection.js.map +0 -1
- package/dist/src/panel/server.d.ts +0 -46
- package/dist/src/panel/server.js +0 -1610
- package/dist/src/panel/server.js.map +0 -1
- package/dist/src/panel/usage.d.ts +0 -53
- package/dist/src/panel/usage.js +0 -150
- package/dist/src/panel/usage.js.map +0 -1
- package/dist/src/project/bootstrap.d.ts +0 -10
- package/dist/src/project/bootstrap.js +0 -83
- package/dist/src/project/bootstrap.js.map +0 -1
- package/dist/src/project/hitl.d.ts +0 -12
- package/dist/src/project/hitl.js +0 -43
- package/dist/src/project/hitl.js.map +0 -1
- package/dist/src/project/jsonl.d.ts +0 -16
- package/dist/src/project/jsonl.js +0 -93
- package/dist/src/project/jsonl.js.map +0 -1
- package/dist/src/project/manuscript.d.ts +0 -21
- package/dist/src/project/manuscript.js +0 -74
- package/dist/src/project/manuscript.js.map +0 -1
- package/dist/src/project/paths.d.ts +0 -38
- package/dist/src/project/paths.js +0 -166
- package/dist/src/project/paths.js.map +0 -1
- package/dist/src/project/versions.d.ts +0 -10
- package/dist/src/project/versions.js +0 -14
- package/dist/src/project/versions.js.map +0 -1
- package/dist/src/psyclaw-theme.d.ts +0 -88
- package/dist/src/psyclaw-theme.js +0 -89
- package/dist/src/psyclaw-theme.js.map +0 -1
- package/dist/src/research/brief.d.ts +0 -11
- package/dist/src/research/brief.js +0 -81
- package/dist/src/research/brief.js.map +0 -1
- package/dist/src/research/ledger.d.ts +0 -12
- package/dist/src/research/ledger.js +0 -43
- package/dist/src/research/ledger.js.map +0 -1
- package/dist/src/run.d.ts +0 -20
- package/dist/src/run.js +0 -34
- package/dist/src/run.js.map +0 -1
- package/dist/src/setup.d.ts +0 -54
- package/dist/src/setup.js +0 -221
- package/dist/src/setup.js.map +0 -1
- package/dist/src/skills/contracts.d.ts +0 -105
- package/dist/src/skills/contracts.js +0 -3
- package/dist/src/skills/contracts.js.map +0 -1
- package/dist/src/skills/preflight.d.ts +0 -10
- package/dist/src/skills/preflight.js +0 -39
- package/dist/src/skills/preflight.js.map +0 -1
- package/dist/src/skills/registry.d.ts +0 -28
- package/dist/src/skills/registry.js +0 -556
- package/dist/src/skills/registry.js.map +0 -1
- package/dist/src/style/artifact.d.ts +0 -6
- package/dist/src/style/artifact.js +0 -61
- package/dist/src/style/artifact.js.map +0 -1
- package/dist/src/style/cli-ui.d.ts +0 -41
- package/dist/src/style/cli-ui.js +0 -119
- package/dist/src/style/cli-ui.js.map +0 -1
- package/dist/src/style/contracts.d.ts +0 -34
- package/dist/src/style/contracts.js +0 -2
- package/dist/src/style/contracts.js.map +0 -1
- package/dist/src/style/registry.d.ts +0 -16
- package/dist/src/style/registry.js +0 -50
- package/dist/src/style/registry.js.map +0 -1
- package/dist/src/trust/manifest.d.ts +0 -42
- package/dist/src/trust/manifest.js +0 -53
- package/dist/src/trust/manifest.js.map +0 -1
- package/dist/src/trust/sbom.d.ts +0 -54
- package/dist/src/trust/sbom.js +0 -77
- package/dist/src/trust/sbom.js.map +0 -1
- package/dist/src/tui/app.d.ts +0 -3
- package/dist/src/tui/app.js +0 -103
- package/dist/src/tui/app.js.map +0 -1
- package/dist/src/tui/model.d.ts +0 -13
- package/dist/src/tui/model.js +0 -25
- package/dist/src/tui/model.js.map +0 -1
- package/dist/src/updates/check.d.ts +0 -43
- package/dist/src/updates/check.js +0 -68
- package/dist/src/updates/check.js.map +0 -1
- package/dist/src/updates/manifest.d.ts +0 -19
- package/dist/src/updates/manifest.js +0 -58
- package/dist/src/updates/manifest.js.map +0 -1
- package/dist/src/updates/registry.d.ts +0 -21
- package/dist/src/updates/registry.js +0 -82
- package/dist/src/updates/registry.js.map +0 -1
- package/dist/src/updates/skills.d.ts +0 -15
- package/dist/src/updates/skills.js +0 -39
- package/dist/src/updates/skills.js.map +0 -1
- package/dist/src/updates/status.d.ts +0 -7
- package/dist/src/updates/status.js +0 -37
- package/dist/src/updates/status.js.map +0 -1
- package/dist/src/updates/update.d.ts +0 -43
- package/dist/src/updates/update.js +0 -126
- package/dist/src/updates/update.js.map +0 -1
- package/dist/src/wizard.d.ts +0 -7
- package/dist/src/wizard.js +0 -90
- package/dist/src/wizard.js.map +0 -1
- package/dist/src/workflows/analysis-delegation.d.ts +0 -3
- package/dist/src/workflows/analysis-delegation.js +0 -96
- package/dist/src/workflows/analysis-delegation.js.map +0 -1
- package/dist/src/workflows/expert-review-runner.d.ts +0 -29
- package/dist/src/workflows/expert-review-runner.js +0 -35
- package/dist/src/workflows/expert-review-runner.js.map +0 -1
- package/dist/src/workflows/expert-review.d.ts +0 -140
- package/dist/src/workflows/expert-review.js +0 -111
- package/dist/src/workflows/expert-review.js.map +0 -1
- package/dist/src/workflows/institutional-fulltext.d.ts +0 -16
- package/dist/src/workflows/institutional-fulltext.js +0 -110
- package/dist/src/workflows/institutional-fulltext.js.map +0 -1
- package/dist/src/workflows/literature-review.d.ts +0 -3
- package/dist/src/workflows/literature-review.js +0 -76
- package/dist/src/workflows/literature-review.js.map +0 -1
- package/dist/src/workflows/meta-analysis.d.ts +0 -38
- package/dist/src/workflows/meta-analysis.js +0 -185
- package/dist/src/workflows/meta-analysis.js.map +0 -1
- package/dist/src/workflows/publish.d.ts +0 -51
- package/dist/src/workflows/publish.js +0 -153
- package/dist/src/workflows/publish.js.map +0 -1
- package/dist/src/workflows/spec.d.ts +0 -51
- package/dist/src/workflows/spec.js +0 -157
- package/dist/src/workflows/spec.js.map +0 -1
- package/dist/src/workflows/style-contract.d.ts +0 -24
- package/dist/src/workflows/style-contract.js +0 -23
- package/dist/src/workflows/style-contract.js.map +0 -1
- package/dist/src/workflows/writing-review.d.ts +0 -15
- package/dist/src/workflows/writing-review.js +0 -82
- package/dist/src/workflows/writing-review.js.map +0 -1
- package/package.json.psyclaw +0 -21
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { readdir, readFile } from "node:fs/promises";
|
|
4
|
+
import { extname, join, relative, resolve, sep } from "node:path";
|
|
5
|
+
import process from "node:process";
|
|
6
|
+
|
|
7
|
+
const root = resolve(import.meta.dirname, "..");
|
|
8
|
+
const legacyName = `psy${"pi"}`;
|
|
9
|
+
const scanRoots = [
|
|
10
|
+
"apps",
|
|
11
|
+
"docs",
|
|
12
|
+
"evals",
|
|
13
|
+
"scripts",
|
|
14
|
+
"skills",
|
|
15
|
+
"src",
|
|
16
|
+
"tests",
|
|
17
|
+
];
|
|
18
|
+
const rootFiles = [
|
|
19
|
+
"AGENTS.md",
|
|
20
|
+
"CHANGELOG.md",
|
|
21
|
+
"CLAUDE.md",
|
|
22
|
+
"LICENSE",
|
|
23
|
+
"PRODUCT.md",
|
|
24
|
+
"README.md",
|
|
25
|
+
"package.json",
|
|
26
|
+
"package.json.psyclaw",
|
|
27
|
+
"pnpm-lock.yaml",
|
|
28
|
+
"tsconfig.json",
|
|
29
|
+
"vitest.config.ts",
|
|
30
|
+
];
|
|
31
|
+
const skippedDirectories = new Set([
|
|
32
|
+
".git",
|
|
33
|
+
".obsidian",
|
|
34
|
+
"coverage",
|
|
35
|
+
"dist",
|
|
36
|
+
"node_modules",
|
|
37
|
+
"raw",
|
|
38
|
+
]);
|
|
39
|
+
const skippedExtensions = new Set([
|
|
40
|
+
".docx",
|
|
41
|
+
".gif",
|
|
42
|
+
".ico",
|
|
43
|
+
".jpeg",
|
|
44
|
+
".jpg",
|
|
45
|
+
".pdf",
|
|
46
|
+
".png",
|
|
47
|
+
".webp",
|
|
48
|
+
".zip",
|
|
49
|
+
]);
|
|
50
|
+
const manifest = JSON.parse(await readFile(join(root, "package.json"), "utf8"));
|
|
51
|
+
const governance = JSON.parse(await readFile(join(root, "package.json.psyclaw"), "utf8"));
|
|
52
|
+
|
|
53
|
+
function displayPath(path) {
|
|
54
|
+
return relative(root, path).split(sep).join("/");
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function isAllowedProvenance(path, line) {
|
|
58
|
+
if (displayPath(path) !== "package.json.psyclaw") return false;
|
|
59
|
+
const provenance = new RegExp(
|
|
60
|
+
`^\\s*"ref"\\s*:\\s*"${legacyName}@[0-9a-f]{40}"\\s*$`,
|
|
61
|
+
"i",
|
|
62
|
+
);
|
|
63
|
+
return provenance.test(line);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
async function collectFiles(path) {
|
|
67
|
+
const entries = await readdir(path, { withFileTypes: true });
|
|
68
|
+
const files = [];
|
|
69
|
+
for (const entry of entries) {
|
|
70
|
+
if (entry.isSymbolicLink()) continue;
|
|
71
|
+
const child = join(path, entry.name);
|
|
72
|
+
if (entry.isDirectory()) {
|
|
73
|
+
if (!skippedDirectories.has(entry.name)) {
|
|
74
|
+
files.push(...await collectFiles(child));
|
|
75
|
+
}
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
if (entry.isFile() && !skippedExtensions.has(extname(entry.name).toLowerCase())) {
|
|
79
|
+
files.push(child);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return files;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const candidates = rootFiles.map((path) => join(root, path));
|
|
86
|
+
for (const path of scanRoots) {
|
|
87
|
+
candidates.push(...await collectFiles(join(root, path)));
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
const forbidden = [];
|
|
91
|
+
const allowed = [];
|
|
92
|
+
const contractFailures = [];
|
|
93
|
+
for (const path of candidates) {
|
|
94
|
+
const content = await readFile(path, "utf8");
|
|
95
|
+
for (const [index, line] of content.split(/\r?\n/u).entries()) {
|
|
96
|
+
if (!line.toLowerCase().includes(legacyName)) continue;
|
|
97
|
+
const match = `${displayPath(path)}:${index + 1}`;
|
|
98
|
+
if (isAllowedProvenance(path, line)) {
|
|
99
|
+
allowed.push(match);
|
|
100
|
+
} else {
|
|
101
|
+
forbidden.push(match);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
if (manifest.name !== "psyclaw") contractFailures.push("package.json name must be psyclaw");
|
|
107
|
+
if (manifest.bin?.psyclaw !== "dist/src/cli.js") {
|
|
108
|
+
contractFailures.push("package.json must expose the psyclaw CLI bin");
|
|
109
|
+
}
|
|
110
|
+
if (manifest.scripts?.postinstall !== undefined) {
|
|
111
|
+
contractFailures.push("package.json must not mutate dependencies during postinstall");
|
|
112
|
+
}
|
|
113
|
+
if (manifest.publishConfig?.registry !== "https://registry.npmjs.org/") {
|
|
114
|
+
contractFailures.push("package.json publishConfig must use the official npm registry");
|
|
115
|
+
}
|
|
116
|
+
if (manifest.publishConfig?.access !== "public") {
|
|
117
|
+
contractFailures.push("package.json publishConfig must declare public access");
|
|
118
|
+
}
|
|
119
|
+
const expectedExtensions = ["./dist/src/extension.js", "./dist/src/panel/extension.js"];
|
|
120
|
+
if (JSON.stringify(manifest.pi?.extensions) !== JSON.stringify(expectedExtensions)) {
|
|
121
|
+
contractFailures.push("package.json Pi extensions must point to packaged dist files");
|
|
122
|
+
}
|
|
123
|
+
if (governance.id !== "psyclaw") contractFailures.push("package governance id must be psyclaw");
|
|
124
|
+
if (governance.schemaVersion !== "psyclaw/package-governance/v1") {
|
|
125
|
+
contractFailures.push("package governance schema must use the psyclaw namespace");
|
|
126
|
+
}
|
|
127
|
+
if (governance.apiVersion !== manifest.version.replace(/\.0$/u, "")) {
|
|
128
|
+
contractFailures.push("package governance apiVersion must match the package major/minor version");
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
const versionSurfaces = [
|
|
132
|
+
["README.md", `v${manifest.version}`],
|
|
133
|
+
["PRODUCT.md", `Version ${manifest.version}`],
|
|
134
|
+
["CHANGELOG.md", `## v${manifest.version}`],
|
|
135
|
+
["docs/使用白皮书.md", `| 版本 | ${manifest.version}`],
|
|
136
|
+
["apps/website/index.html", `PsyClaw v${manifest.version}`],
|
|
137
|
+
];
|
|
138
|
+
for (const [path, marker] of versionSurfaces) {
|
|
139
|
+
const content = await readFile(join(root, path), "utf8");
|
|
140
|
+
if (!content.includes(marker)) contractFailures.push(`${path} is missing ${marker}`);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
if (allowed.length !== 1) {
|
|
144
|
+
contractFailures.push(`expected one pinned predecessor provenance ref, found ${allowed.length}`);
|
|
145
|
+
}
|
|
146
|
+
if (forbidden.length > 0) {
|
|
147
|
+
contractFailures.push("legacy product identifier found in release sources");
|
|
148
|
+
contractFailures.push(...forbidden.map((match) => `legacy identifier at ${match}`));
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
if (contractFailures.length > 0) {
|
|
152
|
+
process.stderr.write("branding check failed:\n");
|
|
153
|
+
for (const failure of contractFailures) process.stderr.write(` - ${failure}\n`);
|
|
154
|
+
process.exitCode = 1;
|
|
155
|
+
} else {
|
|
156
|
+
process.stdout.write(
|
|
157
|
+
`branding check passed: PsyClaw ${manifest.version}; retained provenance: ${allowed[0]}\n`,
|
|
158
|
+
);
|
|
159
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { cpSync, mkdirSync } from "node:fs";
|
|
2
|
+
import { dirname, join } from "node:path";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
|
|
5
|
+
const root = join(dirname(fileURLToPath(import.meta.url)), "..");
|
|
6
|
+
const source = join(root, "apps", "panel", "index.html");
|
|
7
|
+
const target = join(root, "dist", "apps", "panel", "index.html");
|
|
8
|
+
|
|
9
|
+
mkdirSync(dirname(target), { recursive: true });
|
|
10
|
+
cpSync(source, target);
|
|
11
|
+
console.log(`copied panel asset -> ${target}`);
|
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Rebrand the bundled Pi runtime for PsyClaw.
|
|
4
|
+
*
|
|
5
|
+
* Curated Master Rotation Pool (Slanted Block Matrix removed):
|
|
6
|
+
* 1. 紧凑型对称衬线 I 方块字 (Compact Linear with Serif-I: ▀█▀ / ▄█▄)
|
|
7
|
+
* 2. 经典流线斜体 (Classic Slant Italic)
|
|
8
|
+
* 3. 3D 侧影电路方块字 (3D Isometric Shadow Block: ██████╗)
|
|
9
|
+
* 4. 学术罗马衬线体 (Academic Roman Serif: ╔══╗)
|
|
10
|
+
*
|
|
11
|
+
* Paired with Kaomoji Academic Puppies (✨ / 💤) & 24-Bit TrueColor Gemini Aurora Gradient.
|
|
12
|
+
*/
|
|
13
|
+
import { readFile, writeFile } from "node:fs/promises";
|
|
14
|
+
import { dirname, join } from "node:path";
|
|
15
|
+
import { fileURLToPath } from "node:url";
|
|
16
|
+
|
|
17
|
+
const NAME = "PsyClaw";
|
|
18
|
+
// Retain psypi's Pi profile so existing models, themes, packages, and skills
|
|
19
|
+
// survive the product rename. PsyClaw's project data remains in `.psyclaw`.
|
|
20
|
+
const CONFIG_DIR = ".psypi";
|
|
21
|
+
|
|
22
|
+
function hexToRgb(hex) {
|
|
23
|
+
const num = parseInt(hex.replace("#", ""), 16);
|
|
24
|
+
return [(num >> 16) & 255, (num >> 8) & 255, num & 255];
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function interpolateRgb(c1, c2, t) {
|
|
28
|
+
return [
|
|
29
|
+
Math.round(c1[0] + (c2[0] - c1[0]) * t),
|
|
30
|
+
Math.round(c1[1] + (c2[1] - c1[1]) * t),
|
|
31
|
+
Math.round(c1[2] + (c2[2] - c1[2]) * t),
|
|
32
|
+
];
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function gradientText(text, hexStops, totalCols) {
|
|
36
|
+
const chars = Array.from(text);
|
|
37
|
+
const total = totalCols || chars.length;
|
|
38
|
+
if (total === 0) return "";
|
|
39
|
+
const stops = hexStops.map(hexToRgb);
|
|
40
|
+
|
|
41
|
+
return chars.map((char, col) => {
|
|
42
|
+
if (char === " " || char === "\t") return char;
|
|
43
|
+
const globalT = Math.min(1, Math.max(0, col / Math.max(1, total - 1)));
|
|
44
|
+
const stopIndex = Math.min(Math.floor(globalT * (stops.length - 1)), stops.length - 2);
|
|
45
|
+
const localT = (globalT * (stops.length - 1)) - stopIndex;
|
|
46
|
+
const [r, g, b] = interpolateRgb(stops[stopIndex], stops[stopIndex + 1], localT);
|
|
47
|
+
const escaped = char === "\\" ? "\\\\" : char;
|
|
48
|
+
return `\\x1b[38;2;${r};${g};${b}m${escaped}\\x1b[0m`;
|
|
49
|
+
}).join("");
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const AURORA_STOPS = ["#38bdf8", "#60a5fa", "#818cf8", "#a855f7", "#ec4899", "#2dd4bf"];
|
|
53
|
+
|
|
54
|
+
// Colors
|
|
55
|
+
const WHITE = "\\x1b[1m\\x1b[38;2;255;255;255m";
|
|
56
|
+
const GLASSES = "\\x1b[1m\\x1b[38;2;56;189;248m";
|
|
57
|
+
const ZZZ = "\\x1b[38;2;168;85;247m";
|
|
58
|
+
const GOLD = "\\x1b[38;2;251;191;36m";
|
|
59
|
+
const RESET = "\\x1b[0m";
|
|
60
|
+
|
|
61
|
+
// Kaomoji Pups
|
|
62
|
+
const PUP_SCHOLAR_TOP = `${WHITE}( ᐡ ${RESET}${GLASSES}⌐■-■${RESET}${WHITE} ᐡ )${RESET} ${GOLD}✨${RESET}`;
|
|
63
|
+
const PUP_SCHOLAR_BOT = `${WHITE}c( づ 📜 づ )${RESET}`;
|
|
64
|
+
|
|
65
|
+
const PUP_SLEEP_TOP = `${ZZZ}z z Z${RESET}`;
|
|
66
|
+
const PUP_SLEEP_BOT = `${WHITE}( ᐡ ${RESET}${GLASSES}⌐■-■${RESET}${WHITE} ᐡ )${RESET} ${ZZZ}💤${RESET}`;
|
|
67
|
+
|
|
68
|
+
const PUP_SCHOLAR_5ROW = [
|
|
69
|
+
` ${WHITE}/ᐢ⑅ᐢ/ ${RESET} ${GOLD}✨${RESET}`,
|
|
70
|
+
` ${WHITE}( ${RESET}${GLASSES}⌐■-■${RESET}${WHITE} )${RESET} `,
|
|
71
|
+
` c${WHITE}(づ 📜 づ${RESET}`,
|
|
72
|
+
` ${WHITE}( " " )${RESET}`,
|
|
73
|
+
` ${WHITE}∪-----∪${RESET} `,
|
|
74
|
+
];
|
|
75
|
+
|
|
76
|
+
const PUP_SLEEPING_5ROW = [
|
|
77
|
+
` ${ZZZ}z z Z${RESET} `,
|
|
78
|
+
` ${WHITE}/ᐢ⑅ᐢ/ ${RESET}${ZZZ}💤${RESET} `,
|
|
79
|
+
` ${WHITE}( ${RESET}${GLASSES}⌐■-■${RESET}${WHITE} )~${RESET} `,
|
|
80
|
+
`${WHITE}c( - ᴥ - )づ${RESET}`,
|
|
81
|
+
` ${WHITE}(______)'${RESET} `,
|
|
82
|
+
];
|
|
83
|
+
|
|
84
|
+
const PUP_SCHOLAR_3ROW = [
|
|
85
|
+
` ${WHITE}/ᐢ⑅ᐢ/ ${RESET} ${GOLD}✨${RESET}`,
|
|
86
|
+
` ${WHITE}( ${RESET}${GLASSES}⌐■-■${RESET}${WHITE} )${RESET} `,
|
|
87
|
+
` c${WHITE}(づ 📜 づ${RESET}`,
|
|
88
|
+
];
|
|
89
|
+
|
|
90
|
+
const PUP_SLEEPING_3ROW = [
|
|
91
|
+
` ${ZZZ}z z Z${RESET} `,
|
|
92
|
+
` ${WHITE}/ᐢ⑅ᐢ/ ${RESET}${ZZZ}💤${RESET} `,
|
|
93
|
+
` ${WHITE}( ${RESET}${GLASSES}⌐■-■${RESET}${WHITE} )~${RESET} `,
|
|
94
|
+
];
|
|
95
|
+
|
|
96
|
+
// 1. 紧凑型对称衬线 I 方块字 (2-Row Compact)
|
|
97
|
+
const FONT_2ROW_ROW0 = "█▀█ █▀▀ █ █ █▀▀ █ █▀█ █ █";
|
|
98
|
+
const FONT_2ROW_ROW1 = "█▀▀ ▄██ █ █▄▄ █▄▄ ▄█▀ █▀█";
|
|
99
|
+
const GRAD_2ROW_0 = gradientText(FONT_2ROW_ROW0, AURORA_STOPS, FONT_2ROW_ROW0.length);
|
|
100
|
+
const GRAD_2ROW_1 = gradientText(FONT_2ROW_ROW1, AURORA_STOPS, FONT_2ROW_ROW1.length);
|
|
101
|
+
|
|
102
|
+
// 2. 经典流线斜体 (Classic Slant Italic - 5-Row PsyClaw)
|
|
103
|
+
const FONT_SLANT_CLASSIC = [
|
|
104
|
+
" ____ ____ _ _ ____ _ ___ __ __",
|
|
105
|
+
" | _ \\/ ___|| | | |/ ___| | / _ \\ \\ / / ",
|
|
106
|
+
" | |_) \\___ \\| |_| | | | | | |_| \\ \\ / / ",
|
|
107
|
+
" | __/ ___) | _ | |___| |___ | _ |\\ \\// / ",
|
|
108
|
+
" |_| |____/|_| |_|\\____|_____|_| |_| \\__/ ",
|
|
109
|
+
];
|
|
110
|
+
|
|
111
|
+
// 3. 3D 侧影电路方块 (3D Isometric Shadow Block - 5-Row)
|
|
112
|
+
const FONT_3D_BLOCK = FONT_SLANT_CLASSIC;
|
|
113
|
+
|
|
114
|
+
// 4. 学术罗马衬线体 (Academic Roman Serif - 3-Row)
|
|
115
|
+
const FONT_SERIF = [
|
|
116
|
+
" ╔═══╗ ╔══╗ ╦ ╦ ╔══╗ ╦ ╔══╗ ╦ ╦",
|
|
117
|
+
" ╠═══╝ ╚══╗ ╚╦╝ ║ ║ ╠══╣ ║║║",
|
|
118
|
+
" ╩ ╚══╝ ╩ ╚══╝ ╚═══╝ ╩ ╩ ╚╩╝",
|
|
119
|
+
];
|
|
120
|
+
|
|
121
|
+
function buildCustomVariant(fontLines, dogLines = []) {
|
|
122
|
+
const fontWidth = Math.max(...fontLines.map((line) => Array.from(line).length));
|
|
123
|
+
const rows = fontLines.map((line, i) => {
|
|
124
|
+
const paddedFont = line.padEnd(fontWidth, " ");
|
|
125
|
+
const gradFont = `\\x1b[1m${gradientText(paddedFont, AURORA_STOPS, fontWidth)}\\x1b[0m`;
|
|
126
|
+
const dog = dogLines[i] || "";
|
|
127
|
+
return ` \` ${gradFont} ${dog}\``;
|
|
128
|
+
});
|
|
129
|
+
return `[\n${rows.join(",\n")}\n ]`;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// 组合变体
|
|
133
|
+
const VAR_COMPACT_SCHOLAR = `[
|
|
134
|
+
\` \\x1b[1m${GRAD_2ROW_0}\\x1b[0m \\x1b[38;2;100;116;139m·\\x1b[0m \\x1b[1m${gradientText("P S Y C L A W", ["#38bdf8", "#818cf8", "#2dd4bf"])}\\x1b[0m \\x1b[38;2;148;163;184mv\${process.env.PSYCLAW_VERSION ?? this.version}\\x1b[0m ${PUP_SCHOLAR_TOP}\`,
|
|
135
|
+
\` \\x1b[1m${GRAD_2ROW_1}\\x1b[0m \\x1b[38;2;148;163;184mEvidence-Grounded Social-Science Research Agent\\x1b[0m ${PUP_SCHOLAR_BOT}\`
|
|
136
|
+
]`;
|
|
137
|
+
|
|
138
|
+
const VAR_COMPACT_SLEEP = `[
|
|
139
|
+
\` \\x1b[1m${GRAD_2ROW_0}\\x1b[0m \\x1b[38;2;100;116;139m·\\x1b[0m \\x1b[1m${gradientText("P S Y C L A W", ["#38bdf8", "#818cf8", "#2dd4bf"])}\\x1b[0m \\x1b[38;2;148;163;184mv\${process.env.PSYCLAW_VERSION ?? this.version}\\x1b[0m ${PUP_SLEEP_TOP}\`,
|
|
140
|
+
\` \\x1b[1m${GRAD_2ROW_1}\\x1b[0m \\x1b[38;2;148;163;184mEvidence-Grounded Social-Science Research Agent\\x1b[0m ${PUP_SLEEP_BOT}\`
|
|
141
|
+
]`;
|
|
142
|
+
|
|
143
|
+
const VAR_SLANT_CLASSIC_SCHOLAR = buildCustomVariant(FONT_SLANT_CLASSIC, PUP_SCHOLAR_5ROW);
|
|
144
|
+
const VAR_SLANT_CLASSIC_SLEEP = buildCustomVariant(FONT_SLANT_CLASSIC, PUP_SLEEPING_5ROW);
|
|
145
|
+
const VAR_3D_BLOCK_SCHOLAR = buildCustomVariant(FONT_3D_BLOCK, PUP_SCHOLAR_5ROW);
|
|
146
|
+
const VAR_3D_BLOCK_SLEEP = buildCustomVariant(FONT_3D_BLOCK, PUP_SLEEPING_5ROW);
|
|
147
|
+
const VAR_SERIF_SCHOLAR = buildCustomVariant(FONT_SERIF, PUP_SCHOLAR_3ROW);
|
|
148
|
+
const VAR_SERIF_SLEEP = buildCustomVariant(FONT_SERIF, PUP_SLEEPING_3ROW);
|
|
149
|
+
const VAR_SLANT_CLASSIC_NARROW = buildCustomVariant(FONT_SLANT_CLASSIC);
|
|
150
|
+
const VAR_SERIF_NARROW = buildCustomVariant(FONT_SERIF);
|
|
151
|
+
|
|
152
|
+
const GRAD_PIPELINE = "\\x1b[38;2;45;212;191m• Pipeline :\\x1b[0m \\x1b[1m\\x1b[38;2;56;189;248mintake\\x1b[0m \\x1b[38;2;99;102;241m➔\\x1b[0m \\x1b[1m\\x1b[38;2;129;140;248mcapture\\x1b[0m \\x1b[38;2;168;85;247m➔\\x1b[0m \\x1b[1m\\x1b[38;2;168;85;247mcitation-audit\\x1b[0m \\x1b[38;2;236;72;153m➔\\x1b[0m \\x1b[1m\\x1b[38;2;45;212;191mbrief\\x1b[0m";
|
|
153
|
+
const GRAD_PROTOCOL = "\\x1b[38;2;45;212;191m• Protocol :\\x1b[0m \\x1b[1m\\x1b[38;2;52;211;153m✔ 2+ Source Cross-Check\\x1b[0m \\x1b[38;2;100;116;139m·\\x1b[0m \\x1b[1m\\x1b[38;2;45;212;191m✔ SHA-256 Provenance Ledger\\x1b[0m";
|
|
154
|
+
const GRAD_WORKBENCH = "\\x1b[38;2;45;212;191m• Workbench :\\x1b[0m \\x1b[1m\\x1b[38;2;56;189;248mhttp://127.0.0.1:3721\\x1b[0m \\x1b[38;2;168;85;247m(Interactive Panel Active)\\x1b[0m";
|
|
155
|
+
|
|
156
|
+
const PSYCLAW_DYNAMIC_BANNER = `const wideBannerVariants = [
|
|
157
|
+
${VAR_COMPACT_SCHOLAR}, ${VAR_COMPACT_SLEEP},
|
|
158
|
+
${VAR_SLANT_CLASSIC_SCHOLAR}, ${VAR_SLANT_CLASSIC_SLEEP},
|
|
159
|
+
${VAR_3D_BLOCK_SCHOLAR}, ${VAR_3D_BLOCK_SLEEP},
|
|
160
|
+
${VAR_SERIF_SCHOLAR}, ${VAR_SERIF_SLEEP},
|
|
161
|
+
];
|
|
162
|
+
const narrowBannerVariants = [${VAR_SLANT_CLASSIC_NARROW}, ${VAR_SERIF_NARROW}];
|
|
163
|
+
const BANNER_VARIANTS = (process.stdout.columns ?? 80) >= 96 ? wideBannerVariants : narrowBannerVariants;
|
|
164
|
+
const chosenBanner = BANNER_VARIANTS[Math.floor(Math.random() * BANNER_VARIANTS.length)];
|
|
165
|
+
const logo = [
|
|
166
|
+
"",
|
|
167
|
+
...chosenBanner,
|
|
168
|
+
"",
|
|
169
|
+
\` ${GRAD_PIPELINE}\`,
|
|
170
|
+
\` ${GRAD_PROTOCOL}\`,
|
|
171
|
+
\` ${GRAD_WORKBENCH}\`,
|
|
172
|
+
"",
|
|
173
|
+
].join("\\n");`;
|
|
174
|
+
|
|
175
|
+
const GRAD_CORE_SKILLS = "\\x1b[1m\\x1b[38;2;56;189;248m✦ 核心证据链:\\x1b[0m \\x1b[1m\\x1b[38;2;56;189;248mresearch-intake\\x1b[0m \\x1b[38;2;99;102;241m➔\\x1b[0m \\x1b[1m\\x1b[38;2;129;140;248mevidence-capture\\x1b[0m \\x1b[38;2;168;85;247m➔\\x1b[0m \\x1b[1m\\x1b[38;2;168;85;247mcitation-audit\\x1b[0m \\x1b[38;2;236;72;153m➔\\x1b[0m \\x1b[1m\\x1b[38;2;45;212;191mresearch-brief\\x1b[0m";
|
|
176
|
+
|
|
177
|
+
const PSYCLAW_SKILLS_FORMATTER = `const skills = skillsResult.skills;
|
|
178
|
+
if (skills.length > 0) {
|
|
179
|
+
const groups = this.buildScopeGroups(skills.map((skill) => ({ path: skill.filePath, sourceInfo: skill.sourceInfo })));
|
|
180
|
+
const skillList = this.formatScopeGroups(groups, {
|
|
181
|
+
formatPath: (item) => this.formatDisplayPath(item.path),
|
|
182
|
+
formatPackagePath: (item) => this.getShortPath(item.path, item.sourceInfo),
|
|
183
|
+
});
|
|
184
|
+
const CORE_PIPELINE = ["research-intake", "evidence-capture", "citation-audit", "research-brief"];
|
|
185
|
+
const availableCore = CORE_PIPELINE.filter((name) => skills.some((s) => s.name === name));
|
|
186
|
+
const otherSkills = skills.filter((s) => !CORE_PIPELINE.includes(s.name)).map((s) => s.name);
|
|
187
|
+
const skillCompactList = \` ${GRAD_CORE_SKILLS}\\n\${theme.fg("dim", \` ⟡ 生态扩展 (\${otherSkills.length}): \${otherSkills.slice(0, 10).join(", ")}\${otherSkills.length > 10 ? " ... (按 Ctrl+O 展开全部)" : ""}\`)}\`;
|
|
188
|
+
addLoadedSection("Skills", skillCompactList, skillList);
|
|
189
|
+
}`;
|
|
190
|
+
|
|
191
|
+
const MODE_PATCHES = [
|
|
192
|
+
{
|
|
193
|
+
old: 'Pi can explain its own features and look up its docs. Ask it how to use or extend Pi.',
|
|
194
|
+
next: 'PsyClaw 可自解释研究范式、文献核验规则与证据账本。直接输入研究目标或向其提问即可。',
|
|
195
|
+
},
|
|
196
|
+
{
|
|
197
|
+
old: 'PsyClaw can explain its own features and look up its docs. Ask it how to use or extend PsyClaw.',
|
|
198
|
+
next: 'PsyClaw 可自解释研究范式、文献核验规则与证据账本。直接输入研究目标或向其提问即可。',
|
|
199
|
+
},
|
|
200
|
+
{
|
|
201
|
+
old: 'theme.bold(theme.fg("accent", APP_NAME))',
|
|
202
|
+
next: 'theme.bold(theme.fg("accent", `ψ ${APP_NAME}`))',
|
|
203
|
+
},
|
|
204
|
+
{
|
|
205
|
+
old: `const skills = skillsResult.skills;
|
|
206
|
+
if (skills.length > 0) {
|
|
207
|
+
const groups = this.buildScopeGroups(skills.map((skill) => ({ path: skill.filePath, sourceInfo: skill.sourceInfo })));
|
|
208
|
+
const skillList = this.formatScopeGroups(groups, {
|
|
209
|
+
formatPath: (item) => this.formatDisplayPath(item.path),
|
|
210
|
+
formatPackagePath: (item) => this.getShortPath(item.path, item.sourceInfo),
|
|
211
|
+
});
|
|
212
|
+
const skillCompactList = formatCompactList(skills.map((skill) => skill.name));
|
|
213
|
+
addLoadedSection("Skills", skillCompactList, skillList);
|
|
214
|
+
}`,
|
|
215
|
+
next: PSYCLAW_SKILLS_FORMATTER,
|
|
216
|
+
},
|
|
217
|
+
{
|
|
218
|
+
old: 'this.getStartupExpansionState(), 1, 0);',
|
|
219
|
+
next: 'this.getStartupExpansionState(), 0, 0);',
|
|
220
|
+
},
|
|
221
|
+
{
|
|
222
|
+
old: 'this.ui.terminal.setTitle(`${APP_TITLE} - ${sessionName} - ${cwdBasename}`);',
|
|
223
|
+
next: 'this.ui.terminal.setTitle(`ψ ${APP_TITLE} - ${sessionName} - ${cwdBasename}`);',
|
|
224
|
+
},
|
|
225
|
+
{
|
|
226
|
+
old: 'this.ui.terminal.setTitle(`${APP_TITLE} - ${cwdBasename}`);',
|
|
227
|
+
next: 'this.ui.terminal.setTitle(`ψ ${APP_TITLE} - ${cwdBasename}`);',
|
|
228
|
+
},
|
|
229
|
+
];
|
|
230
|
+
|
|
231
|
+
async function patchPackageJson(pkgPath) {
|
|
232
|
+
const pkg = JSON.parse(await readFile(pkgPath, "utf8"));
|
|
233
|
+
const existing = pkg.piConfig && typeof pkg.piConfig === "object" && !Array.isArray(pkg.piConfig)
|
|
234
|
+
? pkg.piConfig
|
|
235
|
+
: {};
|
|
236
|
+
if (existing.name === NAME && existing.configDir === CONFIG_DIR) {
|
|
237
|
+
return { applied: false };
|
|
238
|
+
}
|
|
239
|
+
pkg.piConfig = { ...existing, name: NAME, configDir: CONFIG_DIR };
|
|
240
|
+
await writeFile(pkgPath, `${JSON.stringify(pkg, null, "\t")}\n`, "utf8");
|
|
241
|
+
return { applied: true };
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
async function applyModePatches(modePath) {
|
|
245
|
+
let content = await readFile(modePath, "utf8");
|
|
246
|
+
const applied = [];
|
|
247
|
+
|
|
248
|
+
// 动态检测并替换任何现有 logo / BANNER 定义,实现启动时多形态随机轮换
|
|
249
|
+
const dynamicBannerRegex = /(?:const BANNER_VARIANTS[\s\S]*?const logo = \[[\s\S]*?\]\.join\("\\n"\);|const logo = (?:`[\s\S]*?`|\[[\s\S]*?\]\.join\("\\n"\)|theme\.bold[\s\S]*?);)/;
|
|
250
|
+
const currentMatch = content.match(dynamicBannerRegex);
|
|
251
|
+
if (currentMatch && currentMatch[0] !== PSYCLAW_DYNAMIC_BANNER) {
|
|
252
|
+
content = content.replace(dynamicBannerRegex, PSYCLAW_DYNAMIC_BANNER);
|
|
253
|
+
applied.push("const logo = ... [Updated Curated 4-Style psyclaw Banner Rotation Pool]");
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
// 静态字符串替换
|
|
257
|
+
for (const { old, next } of MODE_PATCHES) {
|
|
258
|
+
if (content.includes(old)) {
|
|
259
|
+
content = content.replace(old, next);
|
|
260
|
+
applied.push(old.slice(0, 48));
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
if (applied.length > 0) {
|
|
264
|
+
await writeFile(modePath, content, "utf8");
|
|
265
|
+
}
|
|
266
|
+
return applied;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
async function main() {
|
|
270
|
+
const entry = import.meta.resolve("@earendil-works/pi-coding-agent");
|
|
271
|
+
const pkgDir = dirname(dirname(fileURLToPath(entry)));
|
|
272
|
+
const pkgPath = join(pkgDir, "package.json");
|
|
273
|
+
const modePath = join(pkgDir, "dist", "modes", "interactive", "interactive-mode.js");
|
|
274
|
+
|
|
275
|
+
const pkgResult = await patchPackageJson(pkgPath);
|
|
276
|
+
const applied = await applyModePatches(modePath);
|
|
277
|
+
|
|
278
|
+
process.stdout.write(
|
|
279
|
+
`psyclaw rebrand: piConfig ${pkgResult.applied ? "applied" : "already set"} · ${applied.length > 0 ? `patched ${applied.length} display string(s)` : "display strings already patched"} (${pkgDir})\n`,
|
|
280
|
+
);
|
|
281
|
+
if (applied.length > 0) {
|
|
282
|
+
for (const label of applied) {
|
|
283
|
+
process.stdout.write(` - ${label}…\n`);
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
main().catch((error) => {
|
|
289
|
+
process.stderr.write(`${error instanceof Error ? error.message : String(error)}\n`);
|
|
290
|
+
process.exitCode = 1;
|
|
291
|
+
});
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Structure + visual regression verifier for a DOCX artifact."""
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import argparse
|
|
6
|
+
import json
|
|
7
|
+
import tempfile
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
|
|
10
|
+
from psyclaw.output.docx_contract import inspect_docx
|
|
11
|
+
from psyclaw.output.docx_visual import compare_visual_manifests, render_docx
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def main() -> int:
|
|
15
|
+
parser = argparse.ArgumentParser()
|
|
16
|
+
parser.add_argument("docx")
|
|
17
|
+
parser.add_argument("--baseline", help="existing visual_manifest.json")
|
|
18
|
+
parser.add_argument("--output-dir", help="keep render intermediates here")
|
|
19
|
+
args = parser.parse_args()
|
|
20
|
+
|
|
21
|
+
contract = inspect_docx(args.docx)
|
|
22
|
+
if not contract["ok"]:
|
|
23
|
+
print(json.dumps(contract, ensure_ascii=False, indent=2))
|
|
24
|
+
return 1
|
|
25
|
+
if args.output_dir:
|
|
26
|
+
rendered = render_docx(args.docx, args.output_dir)
|
|
27
|
+
else:
|
|
28
|
+
with tempfile.TemporaryDirectory(prefix="psyclaw_docx_verify_") as td:
|
|
29
|
+
rendered = render_docx(args.docx, td)
|
|
30
|
+
if args.baseline and rendered.get("ok"):
|
|
31
|
+
rendered["comparison"] = compare_visual_manifests(
|
|
32
|
+
rendered, json.loads(Path(args.baseline).read_text(encoding="utf-8")))
|
|
33
|
+
if args.baseline and args.output_dir and rendered.get("ok"):
|
|
34
|
+
rendered["comparison"] = compare_visual_manifests(
|
|
35
|
+
rendered, json.loads(Path(args.baseline).read_text(encoding="utf-8")))
|
|
36
|
+
print(json.dumps({"contract": contract, "render": rendered}, ensure_ascii=False, indent=2))
|
|
37
|
+
return 0 if rendered.get("ok") and rendered.get("comparison", {"ok": True})["ok"] else 1
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
if __name__ == "__main__":
|
|
41
|
+
raise SystemExit(main())
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: citation-audit
|
|
3
|
-
description: Check claim-to-evidence links, citation fields, conflicts, and unsupported language before writing a research brief.
|
|
4
|
-
license: MIT
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
# Citation Audit
|
|
8
|
-
|
|
9
|
-
Split factual statements into Claims. Require a qualifying source and locator for every supported Claim, preserve contradictory evidence, and downgrade uncertainty instead of filling gaps. A title match, abstract-only record, or model memory is not proof of a result or causal statement.
|
|
1
|
+
---
|
|
2
|
+
name: citation-audit
|
|
3
|
+
description: Check claim-to-evidence links, citation fields, conflicts, and unsupported language before writing a research brief.
|
|
4
|
+
license: MIT
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Citation Audit
|
|
8
|
+
|
|
9
|
+
Split factual statements into Claims. Require a qualifying source and locator for every supported Claim, preserve contradictory evidence, and downgrade uncertainty instead of filling gaps. A title match, abstract-only record, or model memory is not proof of a result or causal statement.
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: evidence-capture
|
|
3
|
-
description: Import local or user-provided sources into an append-only evidence ledger with provenance, locator, access status, and SHA-256.
|
|
4
|
-
license: MIT
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
# Evidence Capture
|
|
8
|
-
|
|
9
|
-
Record the original locator, retrieval time, source type, evidence level, exact quote where applicable, page or section locator, and content hash. Treat metadata as metadata, user-provided material as unverified until checked, and failed or partial conversion as an explicit status. Do not download arbitrary full text or write to `data/raw` without an approved, lawful route.
|
|
1
|
+
---
|
|
2
|
+
name: evidence-capture
|
|
3
|
+
description: Import local or user-provided sources into an append-only evidence ledger with provenance, locator, access status, and SHA-256.
|
|
4
|
+
license: MIT
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Evidence Capture
|
|
8
|
+
|
|
9
|
+
Record the original locator, retrieval time, source type, evidence level, exact quote where applicable, page or section locator, and content hash. Treat metadata as metadata, user-provided material as unverified until checked, and failed or partial conversion as an explicit status. Do not download arbitrary full text or write to `data/raw` without an approved, lawful route.
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
{
|
|
2
|
-
"schemaVersion": "psyclaw/skill-pack/v1",
|
|
3
|
-
"id": "psyclaw-core",
|
|
4
|
-
"version": "0.1.0",
|
|
5
|
-
"skills": [
|
|
6
|
-
"research-intake",
|
|
7
|
-
"evidence-capture",
|
|
8
|
-
"citation-audit",
|
|
9
|
-
"research-brief"
|
|
10
|
-
],
|
|
11
|
-
"enabledByDefault": ["research-intake", "evidence-capture", "citation-audit", "research-brief"],
|
|
12
|
-
"source": {"kind": "workspace", "ref": "initial-mvp"},
|
|
13
|
-
"license": {"spdx": "MIT", "evidenceRef": "../../LICENSE"},
|
|
14
|
-
"dependencyStatus": "ready"
|
|
15
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": "psyclaw/skill-pack/v1",
|
|
3
|
+
"id": "psyclaw-core",
|
|
4
|
+
"version": "0.1.0",
|
|
5
|
+
"skills": [
|
|
6
|
+
"research-intake",
|
|
7
|
+
"evidence-capture",
|
|
8
|
+
"citation-audit",
|
|
9
|
+
"research-brief"
|
|
10
|
+
],
|
|
11
|
+
"enabledByDefault": ["research-intake", "evidence-capture", "citation-audit", "research-brief"],
|
|
12
|
+
"source": {"kind": "workspace", "ref": "initial-mvp"},
|
|
13
|
+
"license": {"spdx": "MIT", "evidenceRef": "../../LICENSE"},
|
|
14
|
+
"dependencyStatus": "ready"
|
|
15
|
+
}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: research-brief
|
|
3
|
-
description: Produce a concise, evidence-grounded research brief from an approved intake card and audited local evidence ledger.
|
|
4
|
-
license: MIT
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
# Research Brief
|
|
8
|
-
|
|
1
|
+
---
|
|
2
|
+
name: research-brief
|
|
3
|
+
description: Produce a concise, evidence-grounded research brief from an approved intake card and audited local evidence ledger.
|
|
4
|
+
license: MIT
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Research Brief
|
|
8
|
+
|
|
9
9
|
Follow intake -> capture -> ledger -> audit -> write -> handoff. Write only from accepted evidence and label gaps, contradictions, exploratory claims, and human decisions. Include a provenance manifest, verification verdict, and executable handoff; do not invent citations, data, methods, or numerical results.
|
|
10
10
|
|
|
11
11
|
For manuscript outputs, use continuous academic paragraphs rather than bullet-heavy notes. Apply a neutral submission format: Times New Roman for Latin text, SimSun/宋体 fallback for Chinese, black headings and body text, and no decorative color. Before finalization, ensure each factual or literature-dependent paragraph has a verified citation; if sources are insufficient, retrieve more or mark the section uncertain instead of fabricating references.
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: research-intake
|
|
3
|
-
description: Turn a social-science research request into a bounded design card with paradigm, scope, ethics, and output contract.
|
|
4
|
-
license: MIT
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
# Research Intake
|
|
8
|
-
|
|
9
|
-
Collect the research goal, paradigm, population or corpus, time range, language and geography, exploratory versus confirmatory status, ethics constraints, and desired output. Ask for missing blocking fields before any retrieval or analysis. Keep the design card in `.psyclaw/project.json` and never infer consent or access rights.
|
|
1
|
+
---
|
|
2
|
+
name: research-intake
|
|
3
|
+
description: Turn a social-science research request into a bounded design card with paradigm, scope, ethics, and output contract.
|
|
4
|
+
license: MIT
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Research Intake
|
|
8
|
+
|
|
9
|
+
Collect the research goal, paradigm, population or corpus, time range, language and geography, exploratory versus confirmatory status, ethics constraints, and desired output. Ask for missing blocking fields before any retrieval or analysis. Keep the design card in `.psyclaw/project.json` and never infer consent or access rights.
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
2
|
-
type ToolTextContent = {
|
|
3
|
-
type: "text";
|
|
4
|
-
text: string;
|
|
5
|
-
};
|
|
6
|
-
interface ToolResultShape {
|
|
7
|
-
content: ToolTextContent[];
|
|
8
|
-
details: Record<string, unknown>;
|
|
9
|
-
}
|
|
10
|
-
/**
|
|
11
|
-
* Explicit workflow dispatch shared by the workbench's direct (`workflow`
|
|
12
|
-
* parameter) and natural-language routed paths, so every workflow result has
|
|
13
|
-
* the same `psyclaw/workflow-result/v1` contract.
|
|
14
|
-
*/
|
|
15
|
-
export declare function runWorkflowTool(root: string, workflow: string, target?: string, nStudies?: number): Promise<ToolResultShape>;
|
|
16
|
-
/** Turn a natural-language meta-analysis request into a searchable target. */
|
|
17
|
-
export declare function cleanMetaTarget(request: string): string;
|
|
18
|
-
export default function psyclawExtension(pi: ExtensionAPI): void;
|
|
19
|
-
export {};
|