psyclaw 0.25.2 → 0.26.0
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 +111 -60
- package/{apps → dist/apps}/panel/index.html +50 -28
- package/dist/src/adapters/pi/extension.d.ts +19 -0
- package/dist/src/adapters/pi/extension.js +735 -0
- package/dist/src/adapters/pi/extension.js.map +1 -0
- package/dist/src/adapters/pi/model.d.ts +72 -0
- package/dist/src/adapters/pi/model.js +152 -0
- package/dist/src/adapters/pi/model.js.map +1 -0
- package/dist/src/adapters/pi/resources.d.ts +23 -0
- package/dist/src/adapters/pi/resources.js +54 -0
- package/dist/src/adapters/pi/resources.js.map +1 -0
- package/dist/src/adapters/pi/rpc.d.ts +58 -0
- package/dist/src/adapters/pi/rpc.js +253 -0
- package/dist/src/adapters/pi/rpc.js.map +1 -0
- package/dist/src/adapters/pi/session.d.ts +30 -0
- package/dist/src/adapters/pi/session.js +64 -0
- package/dist/src/adapters/pi/session.js.map +1 -0
- package/dist/src/agents/catalog.d.ts +30 -0
- package/dist/src/agents/catalog.js +118 -0
- package/dist/src/agents/catalog.js.map +1 -0
- package/dist/src/agents/discover.d.ts +28 -0
- package/dist/src/agents/discover.js +127 -0
- package/dist/src/agents/discover.js.map +1 -0
- package/dist/src/agents/import.d.ts +67 -0
- package/dist/src/agents/import.js +789 -0
- package/dist/src/agents/import.js.map +1 -0
- package/dist/src/analysis/hooks.d.ts +81 -0
- package/dist/src/analysis/hooks.js +139 -0
- package/dist/src/analysis/hooks.js.map +1 -0
- package/dist/src/analysis/pre-registration.d.ts +18 -0
- package/dist/src/analysis/pre-registration.js +86 -0
- package/dist/src/analysis/pre-registration.js.map +1 -0
- package/dist/src/branding.d.ts +44 -0
- package/dist/src/branding.js +128 -0
- package/dist/src/branding.js.map +1 -0
- package/dist/src/chat.d.ts +16 -0
- package/dist/src/chat.js +95 -0
- package/dist/src/chat.js.map +1 -0
- package/dist/src/cli.d.ts +2 -0
- package/dist/src/cli.js +316 -0
- package/dist/src/cli.js.map +1 -0
- package/dist/src/core/citations.d.ts +44 -0
- package/dist/src/core/citations.js +48 -0
- package/dist/src/core/citations.js.map +1 -0
- package/dist/src/core/contracts.d.ts +119 -0
- package/dist/src/core/contracts.js +2 -0
- package/dist/src/core/contracts.js.map +1 -0
- package/dist/src/core/docx.d.ts +11 -0
- package/dist/src/core/docx.js +46 -0
- package/dist/src/core/docx.js.map +1 -0
- package/dist/src/core/doi.d.ts +41 -0
- package/dist/src/core/doi.js +82 -0
- package/dist/src/core/doi.js.map +1 -0
- package/dist/src/core/evidence-policy.d.ts +24 -0
- package/dist/src/core/evidence-policy.js +308 -0
- package/dist/src/core/evidence-policy.js.map +1 -0
- package/dist/src/core/filekind.d.ts +15 -0
- package/dist/src/core/filekind.js +82 -0
- package/dist/src/core/filekind.js.map +1 -0
- package/dist/src/core/hash.d.ts +2 -0
- package/dist/src/core/hash.js +17 -0
- package/dist/src/core/hash.js.map +1 -0
- package/dist/src/core/pricing.d.ts +38 -0
- package/dist/src/core/pricing.js +110 -0
- package/dist/src/core/pricing.js.map +1 -0
- package/dist/src/core/redact.d.ts +12 -0
- package/dist/src/core/redact.js +48 -0
- package/dist/src/core/redact.js.map +1 -0
- package/dist/src/core/references.d.ts +55 -0
- package/dist/src/core/references.js +102 -0
- package/dist/src/core/references.js.map +1 -0
- package/dist/src/core/schemas.d.ts +162 -0
- package/dist/src/core/schemas.js +160 -0
- package/dist/src/core/schemas.js.map +1 -0
- package/dist/src/extension.d.ts +1 -0
- package/dist/src/extension.js +2 -0
- package/dist/src/extension.js.map +1 -0
- package/dist/src/index.d.ts +72 -0
- package/dist/src/index.js +73 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/install/installer.d.ts +147 -0
- package/dist/src/install/installer.js +721 -0
- package/dist/src/install/installer.js.map +1 -0
- package/dist/src/integrations/contracts.d.ts +35 -0
- package/dist/src/integrations/contracts.js +27 -0
- package/dist/src/integrations/contracts.js.map +1 -0
- package/dist/src/integrations/mcp.d.ts +155 -0
- package/dist/src/integrations/mcp.js +826 -0
- package/dist/src/integrations/mcp.js.map +1 -0
- package/dist/src/knowledge-map/contracts.d.ts +20 -0
- package/dist/src/knowledge-map/contracts.js +2 -0
- package/dist/src/knowledge-map/contracts.js.map +1 -0
- package/dist/src/knowledge-map/index.d.ts +4 -0
- package/dist/src/knowledge-map/index.js +39 -0
- package/dist/src/knowledge-map/index.js.map +1 -0
- package/dist/src/literature/contracts.d.ts +106 -0
- package/dist/src/literature/contracts.js +2 -0
- package/dist/src/literature/contracts.js.map +1 -0
- package/dist/src/literature/fulltext.d.ts +7 -0
- package/dist/src/literature/fulltext.js +24 -0
- package/dist/src/literature/fulltext.js.map +1 -0
- package/dist/src/literature/knowledge-map.d.ts +2 -0
- package/dist/src/literature/knowledge-map.js +20 -0
- package/dist/src/literature/knowledge-map.js.map +1 -0
- package/dist/src/literature/ledger.d.ts +3 -0
- package/dist/src/literature/ledger.js +17 -0
- package/dist/src/literature/ledger.js.map +1 -0
- package/dist/src/literature/metadata.d.ts +6 -0
- package/dist/src/literature/metadata.js +32 -0
- package/dist/src/literature/metadata.js.map +1 -0
- package/dist/src/memory/store.d.ts +22 -0
- package/dist/src/memory/store.js +73 -0
- package/dist/src/memory/store.js.map +1 -0
- package/dist/src/orchestration/contracts.d.ts +61 -0
- package/dist/src/orchestration/contracts.js +2 -0
- package/dist/src/orchestration/contracts.js.map +1 -0
- package/dist/src/orchestration/pi-executor.d.ts +28 -0
- package/dist/src/orchestration/pi-executor.js +169 -0
- package/dist/src/orchestration/pi-executor.js.map +1 -0
- package/dist/src/orchestration/runner.d.ts +196 -0
- package/dist/src/orchestration/runner.js +991 -0
- package/dist/src/orchestration/runner.js.map +1 -0
- package/dist/src/orchestration/scheduler.d.ts +8 -0
- package/dist/src/orchestration/scheduler.js +335 -0
- package/dist/src/orchestration/scheduler.js.map +1 -0
- package/dist/src/panel/events.d.ts +20 -0
- package/dist/src/panel/events.js +93 -0
- package/dist/src/panel/events.js.map +1 -0
- package/dist/src/panel/extension.d.ts +8 -0
- package/dist/src/panel/extension.js +115 -0
- package/dist/src/panel/extension.js.map +1 -0
- package/dist/src/panel/literature-map.d.ts +26 -0
- package/dist/src/panel/literature-map.js +34 -0
- package/dist/src/panel/literature-map.js.map +1 -0
- package/dist/src/panel/projection.d.ts +51 -0
- package/dist/src/panel/projection.js +288 -0
- package/dist/src/panel/projection.js.map +1 -0
- package/dist/src/panel/server.d.ts +46 -0
- package/dist/src/panel/server.js +1610 -0
- package/dist/src/panel/server.js.map +1 -0
- package/dist/src/panel/usage.d.ts +53 -0
- package/dist/src/panel/usage.js +150 -0
- package/dist/src/panel/usage.js.map +1 -0
- package/dist/src/project/bootstrap.d.ts +10 -0
- package/dist/src/project/bootstrap.js +83 -0
- package/dist/src/project/bootstrap.js.map +1 -0
- package/dist/src/project/hitl.d.ts +12 -0
- package/dist/src/project/hitl.js +43 -0
- package/dist/src/project/hitl.js.map +1 -0
- package/dist/src/project/jsonl.d.ts +16 -0
- package/dist/src/project/jsonl.js +93 -0
- package/dist/src/project/jsonl.js.map +1 -0
- package/dist/src/project/manuscript.d.ts +21 -0
- package/dist/src/project/manuscript.js +74 -0
- package/dist/src/project/manuscript.js.map +1 -0
- package/dist/src/project/paths.d.ts +38 -0
- package/dist/src/project/paths.js +166 -0
- package/dist/src/project/paths.js.map +1 -0
- package/dist/src/project/versions.d.ts +10 -0
- package/dist/src/project/versions.js +14 -0
- package/dist/src/project/versions.js.map +1 -0
- package/dist/src/psyclaw-theme.d.ts +88 -0
- package/dist/src/psyclaw-theme.js +89 -0
- package/dist/src/psyclaw-theme.js.map +1 -0
- package/dist/src/research/brief.d.ts +11 -0
- package/dist/src/research/brief.js +81 -0
- package/dist/src/research/brief.js.map +1 -0
- package/dist/src/research/ledger.d.ts +12 -0
- package/dist/src/research/ledger.js +43 -0
- package/dist/src/research/ledger.js.map +1 -0
- package/dist/src/run.d.ts +20 -0
- package/dist/src/run.js +34 -0
- package/dist/src/run.js.map +1 -0
- package/dist/src/setup.d.ts +54 -0
- package/dist/src/setup.js +221 -0
- package/dist/src/setup.js.map +1 -0
- package/dist/src/skills/contracts.d.ts +105 -0
- package/dist/src/skills/contracts.js +3 -0
- package/dist/src/skills/contracts.js.map +1 -0
- package/dist/src/skills/preflight.d.ts +10 -0
- package/dist/src/skills/preflight.js +39 -0
- package/dist/src/skills/preflight.js.map +1 -0
- package/dist/src/skills/registry.d.ts +28 -0
- package/dist/src/skills/registry.js +540 -0
- package/dist/src/skills/registry.js.map +1 -0
- package/dist/src/style/artifact.d.ts +6 -0
- package/dist/src/style/artifact.js +61 -0
- package/dist/src/style/artifact.js.map +1 -0
- package/dist/src/style/cli-ui.d.ts +41 -0
- package/dist/src/style/cli-ui.js +119 -0
- package/dist/src/style/cli-ui.js.map +1 -0
- package/dist/src/style/contracts.d.ts +34 -0
- package/dist/src/style/contracts.js +2 -0
- package/dist/src/style/contracts.js.map +1 -0
- package/dist/src/style/registry.d.ts +16 -0
- package/dist/src/style/registry.js +50 -0
- package/dist/src/style/registry.js.map +1 -0
- package/dist/src/trust/manifest.d.ts +42 -0
- package/dist/src/trust/manifest.js +53 -0
- package/dist/src/trust/manifest.js.map +1 -0
- package/dist/src/trust/sbom.d.ts +54 -0
- package/dist/src/trust/sbom.js +77 -0
- package/dist/src/trust/sbom.js.map +1 -0
- package/dist/src/tui/app.d.ts +3 -0
- package/dist/src/tui/app.js +103 -0
- package/dist/src/tui/app.js.map +1 -0
- package/dist/src/tui/model.d.ts +13 -0
- package/dist/src/tui/model.js +25 -0
- package/dist/src/tui/model.js.map +1 -0
- package/dist/src/updates/check.d.ts +43 -0
- package/dist/src/updates/check.js +68 -0
- package/dist/src/updates/check.js.map +1 -0
- package/dist/src/updates/manifest.d.ts +19 -0
- package/dist/src/updates/manifest.js +58 -0
- package/dist/src/updates/manifest.js.map +1 -0
- package/dist/src/updates/registry.d.ts +21 -0
- package/dist/src/updates/registry.js +82 -0
- package/dist/src/updates/registry.js.map +1 -0
- package/dist/src/updates/skills.d.ts +15 -0
- package/dist/src/updates/skills.js +39 -0
- package/dist/src/updates/skills.js.map +1 -0
- package/dist/src/updates/status.d.ts +7 -0
- package/dist/src/updates/status.js +37 -0
- package/dist/src/updates/status.js.map +1 -0
- package/dist/src/updates/update.d.ts +43 -0
- package/dist/src/updates/update.js +128 -0
- package/dist/src/updates/update.js.map +1 -0
- package/dist/src/wizard.d.ts +7 -0
- package/dist/src/wizard.js +90 -0
- package/dist/src/wizard.js.map +1 -0
- package/dist/src/workflows/analysis-delegation.d.ts +3 -0
- package/dist/src/workflows/analysis-delegation.js +96 -0
- package/dist/src/workflows/analysis-delegation.js.map +1 -0
- package/dist/src/workflows/expert-review-runner.d.ts +29 -0
- package/dist/src/workflows/expert-review-runner.js +35 -0
- package/dist/src/workflows/expert-review-runner.js.map +1 -0
- package/dist/src/workflows/expert-review.d.ts +140 -0
- package/dist/src/workflows/expert-review.js +111 -0
- package/dist/src/workflows/expert-review.js.map +1 -0
- package/dist/src/workflows/institutional-fulltext.d.ts +16 -0
- package/dist/src/workflows/institutional-fulltext.js +110 -0
- package/dist/src/workflows/institutional-fulltext.js.map +1 -0
- package/dist/src/workflows/literature-review.d.ts +3 -0
- package/dist/src/workflows/literature-review.js +76 -0
- package/dist/src/workflows/literature-review.js.map +1 -0
- package/dist/src/workflows/meta-analysis.d.ts +38 -0
- package/dist/src/workflows/meta-analysis.js +185 -0
- package/dist/src/workflows/meta-analysis.js.map +1 -0
- package/dist/src/workflows/publish.d.ts +51 -0
- package/dist/src/workflows/publish.js +153 -0
- package/dist/src/workflows/publish.js.map +1 -0
- package/dist/src/workflows/spec.d.ts +51 -0
- package/dist/src/workflows/spec.js +157 -0
- package/dist/src/workflows/spec.js.map +1 -0
- package/dist/src/workflows/style-contract.d.ts +24 -0
- package/dist/src/workflows/style-contract.js +23 -0
- package/dist/src/workflows/style-contract.js.map +1 -0
- package/dist/src/workflows/writing-review.d.ts +15 -0
- package/dist/src/workflows/writing-review.js +82 -0
- package/dist/src/workflows/writing-review.js.map +1 -0
- package/package.json +20 -8
- package/scripts/rebrand-pi.mjs +3 -3
- 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 +0 -729
- package/scripts/build_preprint_figures.py +0 -238
- package/scripts/build_three_line_table_fixture.py +0 -56
- package/scripts/build_whitepaper_docx.py +0 -768
- package/scripts/check-branding.mjs +0 -159
- package/scripts/copy-panel.mjs +0 -11
- package/scripts/verify_docx.py +0 -41
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { appendFile, mkdir, readFile, rename, rm, writeFile } from "node:fs/promises";
|
|
2
|
+
import { basename, dirname, join } from "node:path";
|
|
3
|
+
import { randomUUID } from "node:crypto";
|
|
4
|
+
const writeQueues = new Map();
|
|
5
|
+
/**
|
|
6
|
+
* Serialize all mutations for one JSONL path in this process. A rejected
|
|
7
|
+
* operation must not poison later writes, so the next operation starts after
|
|
8
|
+
* the previous one settles.
|
|
9
|
+
*/
|
|
10
|
+
function enqueue(path, operation) {
|
|
11
|
+
const previous = writeQueues.get(path) ?? Promise.resolve();
|
|
12
|
+
const next = previous.catch(() => undefined).then(operation);
|
|
13
|
+
writeQueues.set(path, next);
|
|
14
|
+
void next.finally(() => {
|
|
15
|
+
if (writeQueues.get(path) === next)
|
|
16
|
+
writeQueues.delete(path);
|
|
17
|
+
}).catch(() => undefined);
|
|
18
|
+
return next;
|
|
19
|
+
}
|
|
20
|
+
export async function appendJsonl(path, value) {
|
|
21
|
+
await enqueue(path, async () => {
|
|
22
|
+
await mkdir(dirname(path), { recursive: true });
|
|
23
|
+
await appendFile(path, `${JSON.stringify(value)}\n`, "utf8");
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Check for an existing logical record and append only when its key is new.
|
|
28
|
+
* The read and append happen inside the same per-path queue, making this
|
|
29
|
+
* operation safe for concurrent callers in the current process.
|
|
30
|
+
*/
|
|
31
|
+
export async function appendJsonlIfMissing(path, value, key) {
|
|
32
|
+
return enqueue(path, async () => {
|
|
33
|
+
const existing = await readJsonl(path);
|
|
34
|
+
const wanted = key(value);
|
|
35
|
+
if (existing.some((item) => key(item) === wanted))
|
|
36
|
+
return { appended: false };
|
|
37
|
+
await mkdir(dirname(path), { recursive: true });
|
|
38
|
+
await appendFile(path, `${JSON.stringify(value)}\n`, "utf8");
|
|
39
|
+
return { appended: true };
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Replace a file through a same-directory temporary file and rename. Keeping
|
|
44
|
+
* the temporary file beside the destination preserves rename atomicity on
|
|
45
|
+
* filesystems that support it and avoids partially written JSON/Markdown.
|
|
46
|
+
*/
|
|
47
|
+
export async function atomicWriteFile(path, contents) {
|
|
48
|
+
const directory = dirname(path);
|
|
49
|
+
await mkdir(directory, { recursive: true });
|
|
50
|
+
const temporary = join(directory, `.${basename(path)}.${randomUUID()}.tmp`);
|
|
51
|
+
try {
|
|
52
|
+
await writeFile(temporary, contents, { encoding: "utf8", flag: "wx" });
|
|
53
|
+
try {
|
|
54
|
+
await rename(temporary, path);
|
|
55
|
+
}
|
|
56
|
+
catch (error) {
|
|
57
|
+
// Windows may reject replacing an existing file with rename. Remove
|
|
58
|
+
// only the exact destination, then complete the same-directory move.
|
|
59
|
+
const code = error.code;
|
|
60
|
+
if (code !== "EEXIST" && code !== "EPERM" && code !== "EACCES")
|
|
61
|
+
throw error;
|
|
62
|
+
await rm(path, { force: true });
|
|
63
|
+
await rename(temporary, path);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
finally {
|
|
67
|
+
await rm(temporary, { force: true }).catch(() => undefined);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
export async function readJsonl(path) {
|
|
71
|
+
let text;
|
|
72
|
+
try {
|
|
73
|
+
text = await readFile(path, "utf8");
|
|
74
|
+
}
|
|
75
|
+
catch (error) {
|
|
76
|
+
if (error.code === "ENOENT")
|
|
77
|
+
return [];
|
|
78
|
+
throw error;
|
|
79
|
+
}
|
|
80
|
+
const rows = [];
|
|
81
|
+
for (const [index, line] of text.split(/\r?\n/).entries()) {
|
|
82
|
+
if (!line.trim())
|
|
83
|
+
continue;
|
|
84
|
+
try {
|
|
85
|
+
rows.push(JSON.parse(line));
|
|
86
|
+
}
|
|
87
|
+
catch {
|
|
88
|
+
throw new Error(`Invalid JSONL at ${path}:${index + 1}`);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return rows;
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=jsonl.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jsonl.js","sourceRoot":"","sources":["../../../src/project/jsonl.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared manuscript discovery (convention: docs/文档规范.md).
|
|
3
|
+
*
|
|
4
|
+
* The panel, the publish workflow, and the agent tools all resolve "the
|
|
5
|
+
* manuscript" the same way so a document generated by any of them is
|
|
6
|
+
* immediately recognized by the others:
|
|
7
|
+
* 1. notes/manuscript.md (panel-managed)
|
|
8
|
+
* 2. paper/ or docs/ *.md (prefer names like 手稿/论文/初稿/draft/manuscript)
|
|
9
|
+
* 3. report fallbacks (meta-analysis / literature review / HANDOFF)
|
|
10
|
+
*/
|
|
11
|
+
export declare const MANUSCRIPT_NAME_PATTERN: RegExp;
|
|
12
|
+
export interface Manuscript {
|
|
13
|
+
exists: boolean;
|
|
14
|
+
path: string | null;
|
|
15
|
+
markdown: string;
|
|
16
|
+
}
|
|
17
|
+
export declare function findMarkdownManuscript(root: string): Promise<{
|
|
18
|
+
path: string;
|
|
19
|
+
markdown: string;
|
|
20
|
+
} | null>;
|
|
21
|
+
export declare function readManuscript(root: string): Promise<Manuscript>;
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { lstat, readFile, readdir } from "node:fs/promises";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { assertSafeProjectPath } from "./paths.js";
|
|
4
|
+
/**
|
|
5
|
+
* Shared manuscript discovery (convention: docs/文档规范.md).
|
|
6
|
+
*
|
|
7
|
+
* The panel, the publish workflow, and the agent tools all resolve "the
|
|
8
|
+
* manuscript" the same way so a document generated by any of them is
|
|
9
|
+
* immediately recognized by the others:
|
|
10
|
+
* 1. notes/manuscript.md (panel-managed)
|
|
11
|
+
* 2. paper/ or docs/ *.md (prefer names like 手稿/论文/初稿/draft/manuscript)
|
|
12
|
+
* 3. report fallbacks (meta-analysis / literature review / HANDOFF)
|
|
13
|
+
*/
|
|
14
|
+
export const MANUSCRIPT_NAME_PATTERN = /(手稿|论文|初稿|draft|manuscript|Draft|Manuscript)/i;
|
|
15
|
+
export async function findMarkdownManuscript(root) {
|
|
16
|
+
for (const dir of ["paper", "docs"]) {
|
|
17
|
+
let entries = [];
|
|
18
|
+
try {
|
|
19
|
+
entries = await readdir(join(root, dir), { withFileTypes: true });
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
continue;
|
|
23
|
+
}
|
|
24
|
+
const candidates = [];
|
|
25
|
+
for (const entry of entries) {
|
|
26
|
+
if (!entry.isFile() || !/\.(md|markdown)$/i.test(entry.name))
|
|
27
|
+
continue;
|
|
28
|
+
const stat = await lstat(join(root, dir, entry.name)).catch(() => undefined);
|
|
29
|
+
if (stat?.isFile())
|
|
30
|
+
candidates.push({ name: entry.name, mtimeMs: stat.mtimeMs });
|
|
31
|
+
}
|
|
32
|
+
const preferred = candidates.filter((candidate) => MANUSCRIPT_NAME_PATTERN.test(candidate.name));
|
|
33
|
+
const pool = preferred.length > 0 ? preferred : candidates;
|
|
34
|
+
pool.sort((left, right) => right.mtimeMs - left.mtimeMs);
|
|
35
|
+
const picked = pool[0];
|
|
36
|
+
if (!picked)
|
|
37
|
+
continue;
|
|
38
|
+
const path = `${dir}/${picked.name}`;
|
|
39
|
+
try {
|
|
40
|
+
return { path, markdown: await readFile(await assertSafeProjectPath(root, path), "utf8") };
|
|
41
|
+
}
|
|
42
|
+
catch { /* try next candidate */ }
|
|
43
|
+
}
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
export async function readManuscript(root) {
|
|
47
|
+
// 1. The panel-managed working copy wins when present.
|
|
48
|
+
try {
|
|
49
|
+
const target = await assertSafeProjectPath(root, "notes/manuscript.md");
|
|
50
|
+
const markdown = await readFile(target, "utf8");
|
|
51
|
+
return { exists: true, path: "notes/manuscript.md", markdown };
|
|
52
|
+
}
|
|
53
|
+
catch { /* fall through */ }
|
|
54
|
+
// 2. A real manuscript under paper/ or docs/ is the next best source.
|
|
55
|
+
const found = await findMarkdownManuscript(root);
|
|
56
|
+
if (found)
|
|
57
|
+
return { exists: true, path: found.path, markdown: found.markdown };
|
|
58
|
+
// 3. Report fallbacks only when no manuscript exists at all.
|
|
59
|
+
const candidates = [
|
|
60
|
+
"analysis/outputs/meta-analysis.md",
|
|
61
|
+
"outputs/literature-review.md",
|
|
62
|
+
"notes/HANDOFF.md",
|
|
63
|
+
];
|
|
64
|
+
for (const relative of candidates) {
|
|
65
|
+
try {
|
|
66
|
+
const target = await assertSafeProjectPath(root, relative);
|
|
67
|
+
const markdown = await readFile(target, "utf8");
|
|
68
|
+
return { exists: true, path: relative, markdown };
|
|
69
|
+
}
|
|
70
|
+
catch { /* try next candidate */ }
|
|
71
|
+
}
|
|
72
|
+
return { exists: false, path: null, markdown: "" };
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=manuscript.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manuscript.js","sourceRoot":"","sources":["../../../src/project/manuscript.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
export declare const PSYCLAW_DIR: ".psyclaw";
|
|
2
|
+
export declare function projectPaths(root: string): {
|
|
3
|
+
root: string;
|
|
4
|
+
project: string;
|
|
5
|
+
evidence: string;
|
|
6
|
+
claims: string;
|
|
7
|
+
audit: string;
|
|
8
|
+
versions: string;
|
|
9
|
+
analysisHooks: string;
|
|
10
|
+
trust: string;
|
|
11
|
+
runs: string;
|
|
12
|
+
plans: string;
|
|
13
|
+
memory: string;
|
|
14
|
+
manifests: string;
|
|
15
|
+
raw: string;
|
|
16
|
+
clean: string;
|
|
17
|
+
analysis: string;
|
|
18
|
+
analysisScripts: string;
|
|
19
|
+
analysisConfigs: string;
|
|
20
|
+
analysisResults: string;
|
|
21
|
+
artifacts: string;
|
|
22
|
+
figures: string;
|
|
23
|
+
tables: string;
|
|
24
|
+
reports: string;
|
|
25
|
+
artifactData: string;
|
|
26
|
+
artifactCode: string;
|
|
27
|
+
notes: string;
|
|
28
|
+
outputs: string;
|
|
29
|
+
logs: string;
|
|
30
|
+
handoffMarkdown: string;
|
|
31
|
+
handoffJson: string;
|
|
32
|
+
};
|
|
33
|
+
export declare function ensureProjectDirectories(root: string): Promise<void>;
|
|
34
|
+
/**
|
|
35
|
+
* Verify a write target stays inside an approved project directory and is not
|
|
36
|
+
* an existing symlink. This is an application boundary, not an OS sandbox.
|
|
37
|
+
*/
|
|
38
|
+
export declare function assertSafeProjectPath(root: string, target: string): Promise<string>;
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import { lstat, mkdir, realpath } from "node:fs/promises";
|
|
2
|
+
import { isAbsolute, relative, resolve } from "node:path";
|
|
3
|
+
export const PSYCLAW_DIR = ".psyclaw";
|
|
4
|
+
export function projectPaths(root) {
|
|
5
|
+
const base = resolve(root);
|
|
6
|
+
return {
|
|
7
|
+
root: base,
|
|
8
|
+
project: resolve(base, PSYCLAW_DIR, "project.json"),
|
|
9
|
+
evidence: resolve(base, PSYCLAW_DIR, "evidence.jsonl"),
|
|
10
|
+
claims: resolve(base, PSYCLAW_DIR, "claims.jsonl"),
|
|
11
|
+
audit: resolve(base, PSYCLAW_DIR, "audit.jsonl"),
|
|
12
|
+
versions: resolve(base, PSYCLAW_DIR, "versions.jsonl"),
|
|
13
|
+
analysisHooks: resolve(base, PSYCLAW_DIR, "analysis-hooks.json"),
|
|
14
|
+
trust: resolve(base, PSYCLAW_DIR, "trust.json"),
|
|
15
|
+
runs: resolve(base, PSYCLAW_DIR, "runs"),
|
|
16
|
+
plans: resolve(base, PSYCLAW_DIR, "plans"),
|
|
17
|
+
memory: resolve(base, PSYCLAW_DIR, "memory"),
|
|
18
|
+
manifests: resolve(base, PSYCLAW_DIR, "manifests"),
|
|
19
|
+
raw: resolve(base, "data", "raw"),
|
|
20
|
+
clean: resolve(base, "data", "clean"),
|
|
21
|
+
analysis: resolve(base, "analysis"),
|
|
22
|
+
analysisScripts: resolve(base, "analysis", "scripts"),
|
|
23
|
+
analysisConfigs: resolve(base, "analysis", "configs"),
|
|
24
|
+
analysisResults: resolve(base, "analysis", "results"),
|
|
25
|
+
artifacts: resolve(base, "artifacts"),
|
|
26
|
+
figures: resolve(base, "artifacts", "figures"),
|
|
27
|
+
tables: resolve(base, "artifacts", "tables"),
|
|
28
|
+
reports: resolve(base, "artifacts", "reports"),
|
|
29
|
+
artifactData: resolve(base, "artifacts", "data"),
|
|
30
|
+
artifactCode: resolve(base, "artifacts", "code"),
|
|
31
|
+
notes: resolve(base, "notes"),
|
|
32
|
+
outputs: resolve(base, "outputs"),
|
|
33
|
+
logs: resolve(base, "logs"),
|
|
34
|
+
handoffMarkdown: resolve(base, "notes", "HANDOFF.md"),
|
|
35
|
+
handoffJson: resolve(base, "notes", "handoff.json"),
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
export async function ensureProjectDirectories(root) {
|
|
39
|
+
const paths = projectPaths(root);
|
|
40
|
+
const rootStat = await lstat(paths.root);
|
|
41
|
+
if (rootStat.isSymbolicLink())
|
|
42
|
+
throw new Error(`Project root symlink is not allowed: ${paths.root}`);
|
|
43
|
+
const directoryTargets = [
|
|
44
|
+
PSYCLAW_DIR,
|
|
45
|
+
`${PSYCLAW_DIR}/runs`,
|
|
46
|
+
`${PSYCLAW_DIR}/plans`,
|
|
47
|
+
`${PSYCLAW_DIR}/memory`,
|
|
48
|
+
`${PSYCLAW_DIR}/manifests`,
|
|
49
|
+
"data",
|
|
50
|
+
"data/raw",
|
|
51
|
+
"data/clean",
|
|
52
|
+
"analysis",
|
|
53
|
+
"analysis/scripts",
|
|
54
|
+
"analysis/configs",
|
|
55
|
+
"analysis/results",
|
|
56
|
+
"artifacts",
|
|
57
|
+
"artifacts/figures",
|
|
58
|
+
"artifacts/tables",
|
|
59
|
+
"artifacts/reports",
|
|
60
|
+
"artifacts/data",
|
|
61
|
+
"artifacts/code",
|
|
62
|
+
"notes",
|
|
63
|
+
"outputs",
|
|
64
|
+
"logs",
|
|
65
|
+
];
|
|
66
|
+
for (const target of directoryTargets) {
|
|
67
|
+
const candidate = resolve(paths.root, target);
|
|
68
|
+
try {
|
|
69
|
+
const stat = await lstat(candidate);
|
|
70
|
+
if (stat.isSymbolicLink())
|
|
71
|
+
throw new Error(`Protected directory symlink: ${target}`);
|
|
72
|
+
if (!stat.isDirectory())
|
|
73
|
+
throw new Error(`Expected directory: ${target}`);
|
|
74
|
+
}
|
|
75
|
+
catch (error) {
|
|
76
|
+
if (error.code !== "ENOENT")
|
|
77
|
+
throw error;
|
|
78
|
+
await mkdir(candidate, { recursive: false });
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Verify a write target stays inside an approved project directory and is not
|
|
84
|
+
* an existing symlink. This is an application boundary, not an OS sandbox.
|
|
85
|
+
*/
|
|
86
|
+
export async function assertSafeProjectPath(root, target) {
|
|
87
|
+
const base = resolve(root);
|
|
88
|
+
// `path.resolve` is platform-specific. Normalize separators and reject all
|
|
89
|
+
// absolute/drive-prefixed inputs before resolving so a project created on
|
|
90
|
+
// one platform cannot be escaped by a path form from another platform.
|
|
91
|
+
const rawTarget = target.trim();
|
|
92
|
+
const normalizedTarget = rawTarget.replaceAll("\\", "/");
|
|
93
|
+
const isCrossPlatformAbsolute = normalizedTarget.startsWith("/") ||
|
|
94
|
+
/^\\\\/.test(rawTarget) ||
|
|
95
|
+
/^[A-Za-z]:/.test(rawTarget);
|
|
96
|
+
if (isCrossPlatformAbsolute) {
|
|
97
|
+
throw new Error(`Path escapes project root: ${target}`);
|
|
98
|
+
}
|
|
99
|
+
const candidate = resolve(base, normalizedTarget);
|
|
100
|
+
const rel = relative(base, candidate);
|
|
101
|
+
const normalizedRel = rel.replaceAll("\\", "/");
|
|
102
|
+
if (normalizedRel === "" ||
|
|
103
|
+
normalizedRel === ".." ||
|
|
104
|
+
normalizedRel.startsWith("../") ||
|
|
105
|
+
isAbsolute(rel) ||
|
|
106
|
+
normalizedRel.startsWith("/")) {
|
|
107
|
+
throw new Error(`Path escapes project root: ${target}`);
|
|
108
|
+
}
|
|
109
|
+
const protectedRel = normalizedRel.toLowerCase();
|
|
110
|
+
if (protectedRel === ".git" ||
|
|
111
|
+
protectedRel.startsWith(".git/") ||
|
|
112
|
+
protectedRel === "data/raw" ||
|
|
113
|
+
protectedRel.startsWith("data/raw/") ||
|
|
114
|
+
protectedRel.includes("credential") ||
|
|
115
|
+
protectedRel.includes("secret")) {
|
|
116
|
+
throw new Error(`Protected project path is not writable: ${target}`);
|
|
117
|
+
}
|
|
118
|
+
try {
|
|
119
|
+
const stat = await lstat(candidate);
|
|
120
|
+
if (stat.isSymbolicLink())
|
|
121
|
+
throw new Error(`Symlink target is not writable: ${target}`);
|
|
122
|
+
const resolvedCandidate = await realpath(candidate);
|
|
123
|
+
const resolvedBase = await realpath(base);
|
|
124
|
+
const resolvedRel = relative(resolvedBase, resolvedCandidate);
|
|
125
|
+
const normalizedResolvedRel = resolvedRel.replaceAll("\\", "/");
|
|
126
|
+
if (normalizedResolvedRel === ".." ||
|
|
127
|
+
normalizedResolvedRel.startsWith("../") ||
|
|
128
|
+
isAbsolute(resolvedRel) ||
|
|
129
|
+
normalizedResolvedRel.startsWith("/")) {
|
|
130
|
+
throw new Error(`Resolved path escapes project root: ${target}`);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
catch (error) {
|
|
134
|
+
if (error.code === "ENOENT") {
|
|
135
|
+
// Resolve the nearest existing ancestor so a symlinked parent cannot
|
|
136
|
+
// redirect a future write outside the project root.
|
|
137
|
+
let ancestor = candidate;
|
|
138
|
+
while (true) {
|
|
139
|
+
try {
|
|
140
|
+
const resolvedAncestor = await realpath(ancestor);
|
|
141
|
+
const resolvedBase = await realpath(base);
|
|
142
|
+
const ancestorRel = relative(resolvedBase, resolvedAncestor);
|
|
143
|
+
const normalizedAncestorRel = ancestorRel.replaceAll("\\", "/");
|
|
144
|
+
if (normalizedAncestorRel === ".." ||
|
|
145
|
+
normalizedAncestorRel.startsWith("../") ||
|
|
146
|
+
isAbsolute(ancestorRel) ||
|
|
147
|
+
normalizedAncestorRel.startsWith("/")) {
|
|
148
|
+
throw new Error(`Resolved path escapes project root: ${target}`);
|
|
149
|
+
}
|
|
150
|
+
return candidate;
|
|
151
|
+
}
|
|
152
|
+
catch (ancestorError) {
|
|
153
|
+
if (ancestorError.code !== "ENOENT")
|
|
154
|
+
throw ancestorError;
|
|
155
|
+
const parent = resolve(ancestor, "..");
|
|
156
|
+
if (parent === ancestor)
|
|
157
|
+
throw ancestorError;
|
|
158
|
+
ancestor = parent;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
throw error;
|
|
163
|
+
}
|
|
164
|
+
return candidate;
|
|
165
|
+
}
|
|
166
|
+
//# sourceMappingURL=paths.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.js","sourceRoot":"","sources":["../../../src/project/paths.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export type VersionedArtifactKind = "analysis-plan" | "manuscript-revision" | "figure" | "table" | "manuscript";
|
|
2
|
+
export interface VersionRecord {
|
|
3
|
+
schemaVersion: "psyclaw/version-record/v1";
|
|
4
|
+
kind: VersionedArtifactKind;
|
|
5
|
+
version: number;
|
|
6
|
+
runId: string;
|
|
7
|
+
createdAt: string;
|
|
8
|
+
}
|
|
9
|
+
/** Allocate monotonically within a project and persist the allocation. */
|
|
10
|
+
export declare function allocateProjectVersion(root: string, kind: VersionedArtifactKind, runId: string, now?: string): Promise<string>;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { readJsonl, appendJsonl } from "./jsonl.js";
|
|
2
|
+
import { projectPaths } from "./paths.js";
|
|
3
|
+
/** Allocate monotonically within a project and persist the allocation. */
|
|
4
|
+
export async function allocateProjectVersion(root, kind, runId, now = new Date().toISOString()) {
|
|
5
|
+
const path = projectPaths(root).versions;
|
|
6
|
+
const records = await readJsonl(path);
|
|
7
|
+
const max = records
|
|
8
|
+
.filter((record) => record.kind === kind && Number.isInteger(record.version) && (record.version ?? 0) > 0)
|
|
9
|
+
.reduce((highest, record) => Math.max(highest, record.version ?? 0), 0);
|
|
10
|
+
const version = max + 1;
|
|
11
|
+
await appendJsonl(path, { schemaVersion: "psyclaw/version-record/v1", kind, version, runId, createdAt: now });
|
|
12
|
+
return `v${version}`;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=versions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"versions.js","sourceRoot":"","sources":["../../../src/project/versions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAY1C,0EAA0E;AAC1E,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAAC,IAAY,EAAE,IAA2B,EAAE,KAAa,EAAE,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;IACnI,MAAM,IAAI,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC;IACzC,MAAM,OAAO,GAAG,MAAM,SAAS,CAAyB,IAAI,CAAC,CAAC;IAC9D,MAAM,GAAG,GAAG,OAAO;SAChB,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,IAAI,IAAI,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;SACzG,MAAM,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC,OAAO,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAC1E,MAAM,OAAO,GAAG,GAAG,GAAG,CAAC,CAAC;IACxB,MAAM,WAAW,CAAgB,IAAI,EAAE,EAAE,aAAa,EAAE,2BAA2B,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC,CAAC;IAC7H,OAAO,IAAI,OAAO,EAAE,CAAC;AACvB,CAAC"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The psyclaw color theme for the bundled Pi TUI. It is a teal-dark variant of
|
|
3
|
+
* Pi's built-in dark theme: the accent is a calm teal, headings/borders shift
|
|
4
|
+
* cooler, and backgrounds get a faint teal tint. Every required color token is
|
|
5
|
+
* present so the theme passes Pi's theme JSON schema.
|
|
6
|
+
*/
|
|
7
|
+
export declare const PSYCLAW_THEME_NAME = "psyclaw";
|
|
8
|
+
export declare const PSYCLAW_THEME: {
|
|
9
|
+
name: string;
|
|
10
|
+
vars: {
|
|
11
|
+
cyan: string;
|
|
12
|
+
blue: string;
|
|
13
|
+
green: string;
|
|
14
|
+
red: string;
|
|
15
|
+
yellow: string;
|
|
16
|
+
text: string;
|
|
17
|
+
gray: string;
|
|
18
|
+
dimGray: string;
|
|
19
|
+
darkGray: string;
|
|
20
|
+
accent: string;
|
|
21
|
+
selectedBg: string;
|
|
22
|
+
userMsgBg: string;
|
|
23
|
+
toolPendingBg: string;
|
|
24
|
+
toolSuccessBg: string;
|
|
25
|
+
toolErrorBg: string;
|
|
26
|
+
customMsgBg: string;
|
|
27
|
+
};
|
|
28
|
+
colors: {
|
|
29
|
+
accent: string;
|
|
30
|
+
border: string;
|
|
31
|
+
borderAccent: string;
|
|
32
|
+
borderMuted: string;
|
|
33
|
+
success: string;
|
|
34
|
+
error: string;
|
|
35
|
+
warning: string;
|
|
36
|
+
muted: string;
|
|
37
|
+
dim: string;
|
|
38
|
+
text: string;
|
|
39
|
+
thinkingText: string;
|
|
40
|
+
selectedBg: string;
|
|
41
|
+
scrollbarThumb: string;
|
|
42
|
+
userMessageBg: string;
|
|
43
|
+
userMessageText: string;
|
|
44
|
+
customMessageBg: string;
|
|
45
|
+
customMessageText: string;
|
|
46
|
+
customMessageLabel: string;
|
|
47
|
+
toolPendingBg: string;
|
|
48
|
+
toolSuccessBg: string;
|
|
49
|
+
toolErrorBg: string;
|
|
50
|
+
toolTitle: string;
|
|
51
|
+
toolOutput: string;
|
|
52
|
+
mdHeading: string;
|
|
53
|
+
mdLink: string;
|
|
54
|
+
mdLinkUrl: string;
|
|
55
|
+
mdCode: string;
|
|
56
|
+
mdCodeBlock: string;
|
|
57
|
+
mdCodeBlockBorder: string;
|
|
58
|
+
mdQuote: string;
|
|
59
|
+
mdQuoteBorder: string;
|
|
60
|
+
mdHr: string;
|
|
61
|
+
mdListBullet: string;
|
|
62
|
+
toolDiffAdded: string;
|
|
63
|
+
toolDiffRemoved: string;
|
|
64
|
+
toolDiffContext: string;
|
|
65
|
+
syntaxComment: string;
|
|
66
|
+
syntaxKeyword: string;
|
|
67
|
+
syntaxFunction: string;
|
|
68
|
+
syntaxVariable: string;
|
|
69
|
+
syntaxString: string;
|
|
70
|
+
syntaxNumber: string;
|
|
71
|
+
syntaxType: string;
|
|
72
|
+
syntaxOperator: string;
|
|
73
|
+
syntaxPunctuation: string;
|
|
74
|
+
thinkingOff: string;
|
|
75
|
+
thinkingMinimal: string;
|
|
76
|
+
thinkingLow: string;
|
|
77
|
+
thinkingMedium: string;
|
|
78
|
+
thinkingHigh: string;
|
|
79
|
+
thinkingXhigh: string;
|
|
80
|
+
thinkingMax: string;
|
|
81
|
+
bashMode: string;
|
|
82
|
+
};
|
|
83
|
+
export: {
|
|
84
|
+
pageBg: string;
|
|
85
|
+
cardBg: string;
|
|
86
|
+
infoBg: string;
|
|
87
|
+
};
|
|
88
|
+
};
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The psyclaw color theme for the bundled Pi TUI. It is a teal-dark variant of
|
|
3
|
+
* Pi's built-in dark theme: the accent is a calm teal, headings/borders shift
|
|
4
|
+
* cooler, and backgrounds get a faint teal tint. Every required color token is
|
|
5
|
+
* present so the theme passes Pi's theme JSON schema.
|
|
6
|
+
*/
|
|
7
|
+
export const PSYCLAW_THEME_NAME = "psyclaw";
|
|
8
|
+
export const PSYCLAW_THEME = {
|
|
9
|
+
name: PSYCLAW_THEME_NAME,
|
|
10
|
+
vars: {
|
|
11
|
+
cyan: "#2ec4b6",
|
|
12
|
+
blue: "#4a90d9",
|
|
13
|
+
green: "#7ec699",
|
|
14
|
+
red: "#e06c75",
|
|
15
|
+
yellow: "#e5c07b",
|
|
16
|
+
text: "#d8dee9",
|
|
17
|
+
gray: "#8b98a5",
|
|
18
|
+
dimGray: "#5b6672",
|
|
19
|
+
darkGray: "#3b4252",
|
|
20
|
+
accent: "#2ec4b6",
|
|
21
|
+
selectedBg: "#1f3a3d",
|
|
22
|
+
userMsgBg: "#2a2f3a",
|
|
23
|
+
toolPendingBg: "#2b303b",
|
|
24
|
+
toolSuccessBg: "#1f3d34",
|
|
25
|
+
toolErrorBg: "#3d2b2b",
|
|
26
|
+
customMsgBg: "#27333b",
|
|
27
|
+
},
|
|
28
|
+
colors: {
|
|
29
|
+
accent: "accent",
|
|
30
|
+
border: "blue",
|
|
31
|
+
borderAccent: "cyan",
|
|
32
|
+
borderMuted: "darkGray",
|
|
33
|
+
success: "green",
|
|
34
|
+
error: "red",
|
|
35
|
+
warning: "yellow",
|
|
36
|
+
muted: "gray",
|
|
37
|
+
dim: "dimGray",
|
|
38
|
+
text: "text",
|
|
39
|
+
thinkingText: "gray",
|
|
40
|
+
selectedBg: "selectedBg",
|
|
41
|
+
scrollbarThumb: "selectedBg",
|
|
42
|
+
userMessageBg: "userMsgBg",
|
|
43
|
+
userMessageText: "text",
|
|
44
|
+
customMessageBg: "customMsgBg",
|
|
45
|
+
customMessageText: "text",
|
|
46
|
+
customMessageLabel: "#2ec4b6",
|
|
47
|
+
toolPendingBg: "toolPendingBg",
|
|
48
|
+
toolSuccessBg: "toolSuccessBg",
|
|
49
|
+
toolErrorBg: "toolErrorBg",
|
|
50
|
+
toolTitle: "text",
|
|
51
|
+
toolOutput: "gray",
|
|
52
|
+
mdHeading: "#e5c07b",
|
|
53
|
+
mdLink: "#4fc3b8",
|
|
54
|
+
mdLinkUrl: "dimGray",
|
|
55
|
+
mdCode: "accent",
|
|
56
|
+
mdCodeBlock: "green",
|
|
57
|
+
mdCodeBlockBorder: "gray",
|
|
58
|
+
mdQuote: "gray",
|
|
59
|
+
mdQuoteBorder: "gray",
|
|
60
|
+
mdHr: "gray",
|
|
61
|
+
mdListBullet: "accent",
|
|
62
|
+
toolDiffAdded: "green",
|
|
63
|
+
toolDiffRemoved: "red",
|
|
64
|
+
toolDiffContext: "gray",
|
|
65
|
+
syntaxComment: "#7f9b7f",
|
|
66
|
+
syntaxKeyword: "#61afef",
|
|
67
|
+
syntaxFunction: "#98c379",
|
|
68
|
+
syntaxVariable: "#d19a66",
|
|
69
|
+
syntaxString: "#98c379",
|
|
70
|
+
syntaxNumber: "#d19a66",
|
|
71
|
+
syntaxType: "#2ec4b6",
|
|
72
|
+
syntaxOperator: "#d8dee9",
|
|
73
|
+
syntaxPunctuation: "#d8dee9",
|
|
74
|
+
thinkingOff: "darkGray",
|
|
75
|
+
thinkingMinimal: "#6e7b8a",
|
|
76
|
+
thinkingLow: "#5f87af",
|
|
77
|
+
thinkingMedium: "#6fb3b8",
|
|
78
|
+
thinkingHigh: "#7ec4c8",
|
|
79
|
+
thinkingXhigh: "#2ec4b6",
|
|
80
|
+
thinkingMax: "#4dd0c9",
|
|
81
|
+
bashMode: "green",
|
|
82
|
+
},
|
|
83
|
+
export: {
|
|
84
|
+
pageBg: "#16181d",
|
|
85
|
+
cardBg: "#1e222a",
|
|
86
|
+
infoBg: "#202a2e",
|
|
87
|
+
},
|
|
88
|
+
};
|
|
89
|
+
//# sourceMappingURL=psyclaw-theme.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"psyclaw-theme.js","sourceRoot":"","sources":["../../src/psyclaw-theme.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,SAAS,CAAC;AAE5C,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B,IAAI,EAAE,kBAAkB;IACxB,IAAI,EAAE;QACJ,IAAI,EAAE,SAAS;QACf,IAAI,EAAE,SAAS;QACf,KAAK,EAAE,SAAS;QAChB,GAAG,EAAE,SAAS;QACd,MAAM,EAAE,SAAS;QACjB,IAAI,EAAE,SAAS;QACf,IAAI,EAAE,SAAS;QACf,OAAO,EAAE,SAAS;QAClB,QAAQ,EAAE,SAAS;QACnB,MAAM,EAAE,SAAS;QACjB,UAAU,EAAE,SAAS;QACrB,SAAS,EAAE,SAAS;QACpB,aAAa,EAAE,SAAS;QACxB,aAAa,EAAE,SAAS;QACxB,WAAW,EAAE,SAAS;QACtB,WAAW,EAAE,SAAS;KACvB;IACD,MAAM,EAAE;QACN,MAAM,EAAE,QAAQ;QAChB,MAAM,EAAE,MAAM;QACd,YAAY,EAAE,MAAM;QACpB,WAAW,EAAE,UAAU;QACvB,OAAO,EAAE,OAAO;QAChB,KAAK,EAAE,KAAK;QACZ,OAAO,EAAE,QAAQ;QACjB,KAAK,EAAE,MAAM;QACb,GAAG,EAAE,SAAS;QACd,IAAI,EAAE,MAAM;QACZ,YAAY,EAAE,MAAM;QAEpB,UAAU,EAAE,YAAY;QACxB,cAAc,EAAE,YAAY;QAC5B,aAAa,EAAE,WAAW;QAC1B,eAAe,EAAE,MAAM;QACvB,eAAe,EAAE,aAAa;QAC9B,iBAAiB,EAAE,MAAM;QACzB,kBAAkB,EAAE,SAAS;QAC7B,aAAa,EAAE,eAAe;QAC9B,aAAa,EAAE,eAAe;QAC9B,WAAW,EAAE,aAAa;QAC1B,SAAS,EAAE,MAAM;QACjB,UAAU,EAAE,MAAM;QAElB,SAAS,EAAE,SAAS;QACpB,MAAM,EAAE,SAAS;QACjB,SAAS,EAAE,SAAS;QACpB,MAAM,EAAE,QAAQ;QAChB,WAAW,EAAE,OAAO;QACpB,iBAAiB,EAAE,MAAM;QACzB,OAAO,EAAE,MAAM;QACf,aAAa,EAAE,MAAM;QACrB,IAAI,EAAE,MAAM;QACZ,YAAY,EAAE,QAAQ;QAEtB,aAAa,EAAE,OAAO;QACtB,eAAe,EAAE,KAAK;QACtB,eAAe,EAAE,MAAM;QAEvB,aAAa,EAAE,SAAS;QACxB,aAAa,EAAE,SAAS;QACxB,cAAc,EAAE,SAAS;QACzB,cAAc,EAAE,SAAS;QACzB,YAAY,EAAE,SAAS;QACvB,YAAY,EAAE,SAAS;QACvB,UAAU,EAAE,SAAS;QACrB,cAAc,EAAE,SAAS;QACzB,iBAAiB,EAAE,SAAS;QAE5B,WAAW,EAAE,UAAU;QACvB,eAAe,EAAE,SAAS;QAC1B,WAAW,EAAE,SAAS;QACtB,cAAc,EAAE,SAAS;QACzB,YAAY,EAAE,SAAS;QACvB,aAAa,EAAE,SAAS;QACxB,WAAW,EAAE,SAAS;QAEtB,QAAQ,EAAE,OAAO;KAClB;IACD,MAAM,EAAE;QACN,MAAM,EAAE,SAAS;QACjB,MAAM,EAAE,SAAS;QACjB,MAAM,EAAE,SAAS;KAClB;CACF,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { GateResult, Handoff } from "../core/contracts.js";
|
|
2
|
+
export interface BriefResult {
|
|
3
|
+
runId: string;
|
|
4
|
+
verdict: "pass" | "blocked";
|
|
5
|
+
gates: GateResult[];
|
|
6
|
+
briefPath?: string;
|
|
7
|
+
manifestPath: string;
|
|
8
|
+
verdictPath: string;
|
|
9
|
+
handoff: Handoff;
|
|
10
|
+
}
|
|
11
|
+
export declare function runOfflineBrief(root: string): Promise<BriefResult>;
|