psyclaw 0.29.9 → 0.29.11

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.
@@ -0,0 +1,131 @@
1
+ import { matchesKey, truncateToWidth } from "@earendil-works/pi-tui";
2
+ const MAX_VISIBLE = 9;
3
+ /**
4
+ * CLI renderer for psyclaw_wake_options — choice (radio) or checklist (toggle).
5
+ */
6
+ export class WakeOptionsComponent {
7
+ title;
8
+ prompt;
9
+ mode;
10
+ items;
11
+ allowMultiple;
12
+ minSelections;
13
+ tui;
14
+ theme;
15
+ keybindings;
16
+ done;
17
+ focused = false;
18
+ selectedIndex = 0;
19
+ checked = new Set();
20
+ completed = false;
21
+ constructor(title, prompt, mode, items, allowMultiple, minSelections, tui, theme, keybindings, done) {
22
+ this.title = title;
23
+ this.prompt = prompt;
24
+ this.mode = mode;
25
+ this.items = items;
26
+ this.allowMultiple = allowMultiple;
27
+ this.minSelections = minSelections;
28
+ this.tui = tui;
29
+ this.theme = theme;
30
+ this.keybindings = keybindings;
31
+ this.done = done;
32
+ for (const item of items) {
33
+ if (item.checked)
34
+ this.checked.add(item.id);
35
+ }
36
+ if (mode === "choice" && this.checked.size === 0 && items[0]) {
37
+ this.checked.add(items[0].id);
38
+ }
39
+ }
40
+ invalidate() { }
41
+ render(width) {
42
+ const contentWidth = Math.max(28, width - 4);
43
+ const start = Math.min(Math.max(0, this.selectedIndex - Math.floor(MAX_VISIBLE / 2)), Math.max(0, this.items.length - MAX_VISIBLE));
44
+ const visible = this.items.slice(start, start + MAX_VISIBLE);
45
+ const lines = [
46
+ this.theme.fg("accent", this.theme.bold(`唤醒选项 · ${this.title}`)),
47
+ "",
48
+ ];
49
+ if (this.prompt) {
50
+ lines.push(truncateToWidth(this.prompt, contentWidth), "");
51
+ }
52
+ for (const [offset, item] of visible.entries()) {
53
+ const index = start + offset;
54
+ const focused = index === this.selectedIndex;
55
+ const on = this.checked.has(item.id);
56
+ const marker = this.mode === "checklist" || this.allowMultiple
57
+ ? (on ? "[x]" : "[ ]")
58
+ : (on ? "(•)" : "( )");
59
+ const pointer = focused ? this.theme.fg("accent", ">") : " ";
60
+ const label = `${pointer} ${marker} ${item.label}`;
61
+ lines.push(focused ? this.theme.bold(truncateToWidth(label, contentWidth)) : truncateToWidth(label, contentWidth));
62
+ if (item.description && focused) {
63
+ lines.push(this.theme.fg("dim", truncateToWidth(` ${item.description}`, contentWidth)));
64
+ }
65
+ }
66
+ if (this.items.length > MAX_VISIBLE) {
67
+ lines.push(this.theme.fg("dim", ` ${this.selectedIndex + 1}/${this.items.length}`));
68
+ }
69
+ const hint = this.mode === "checklist" || this.allowMultiple
70
+ ? "↑/↓ 移动 · Space 勾选 · Enter 提交 · Esc 取消"
71
+ : "↑/↓ 移动 · Enter 确认 · Esc 取消";
72
+ lines.push("", this.theme.fg("dim", hint));
73
+ return lines;
74
+ }
75
+ handleInput(data) {
76
+ if (this.completed)
77
+ return;
78
+ if (this.keybindings.matches(data, "tui.select.cancel")) {
79
+ this.completed = true;
80
+ this.done({ type: "cancel" });
81
+ return;
82
+ }
83
+ if (this.items.length === 0)
84
+ return;
85
+ if (this.keybindings.matches(data, "tui.select.up") || matchesKey(data, "k")) {
86
+ this.selectedIndex = (this.selectedIndex - 1 + this.items.length) % this.items.length;
87
+ this.tui.requestRender();
88
+ return;
89
+ }
90
+ if (this.keybindings.matches(data, "tui.select.down") || matchesKey(data, "j")) {
91
+ this.selectedIndex = (this.selectedIndex + 1) % this.items.length;
92
+ this.tui.requestRender();
93
+ return;
94
+ }
95
+ if (data === " " || matchesKey(data, "space")) {
96
+ this.toggleCurrent();
97
+ this.tui.requestRender();
98
+ return;
99
+ }
100
+ if (this.keybindings.matches(data, "tui.select.confirm")) {
101
+ if (this.mode === "choice" && !this.allowMultiple) {
102
+ const current = this.items[this.selectedIndex];
103
+ if (!current)
104
+ return;
105
+ this.completed = true;
106
+ this.done({ type: "submit", selectedIds: [current.id] });
107
+ return;
108
+ }
109
+ if (this.checked.size < this.minSelections) {
110
+ return;
111
+ }
112
+ this.completed = true;
113
+ this.done({ type: "submit", selectedIds: [...this.checked] });
114
+ }
115
+ }
116
+ toggleCurrent() {
117
+ const current = this.items[this.selectedIndex];
118
+ if (!current)
119
+ return;
120
+ if (this.mode === "choice" && !this.allowMultiple) {
121
+ this.checked.clear();
122
+ this.checked.add(current.id);
123
+ return;
124
+ }
125
+ if (this.checked.has(current.id))
126
+ this.checked.delete(current.id);
127
+ else
128
+ this.checked.add(current.id);
129
+ }
130
+ }
131
+ //# sourceMappingURL=wake-options.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wake-options.js","sourceRoot":"","sources":["../../../src/tui/wake-options.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ import { type WakeOptionItem, type WakeOptionsAnswer, type WakeOptionsMode, type WakeOptionsPrompt } from "../panel/hub.js";
2
+ export interface WakeOptionsRequest {
3
+ title: string;
4
+ prompt?: string;
5
+ mode: WakeOptionsMode;
6
+ options: WakeOptionItem[];
7
+ allowMultiple?: boolean;
8
+ minSelections?: number;
9
+ syncVerify?: boolean;
10
+ timeoutMs?: number;
11
+ }
12
+ export interface WakeOptionsResult {
13
+ status: "answered" | "cancelled" | "timeout";
14
+ source: WakeOptionsAnswer["source"];
15
+ selectedIds: string[];
16
+ selectedLabels: string[];
17
+ panelClients: number;
18
+ verifySynced?: boolean;
19
+ notes?: string;
20
+ }
21
+ export declare function buildWakePrompt(request: WakeOptionsRequest, now?: number): WakeOptionsPrompt;
22
+ export declare function applyWakeVerifySync(root: string, prompt: WakeOptionsPrompt, selectedIds: string[]): Promise<boolean>;
23
+ /**
24
+ * Publish a wake-options prompt to Panel (SSE) and wait for an answer.
25
+ * Caller may race this against a CLI UI promise.
26
+ */
27
+ export declare function waitForPanelWakeAnswer(prompt: WakeOptionsPrompt, timeoutMs: number): Promise<WakeOptionsAnswer>;
28
+ export declare function resolvePanelWakeAnswer(answer: WakeOptionsAnswer): boolean;
29
+ export declare function formatWakeResult(result: WakeOptionsResult): string;
30
+ export declare function labelsFor(prompt: WakeOptionsPrompt, ids: string[]): string[];
@@ -0,0 +1,70 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { markVerifyItem } from "../verify/checklist.js";
3
+ import { panelHub, } from "../panel/hub.js";
4
+ function normalizeOptions(options) {
5
+ const seen = new Set();
6
+ const out = [];
7
+ for (const option of options) {
8
+ const id = option.id.trim();
9
+ const label = option.label.trim();
10
+ if (!id || !label || seen.has(id))
11
+ continue;
12
+ seen.add(id);
13
+ out.push({
14
+ id,
15
+ label,
16
+ ...(option.description?.trim() ? { description: option.description.trim() } : {}),
17
+ ...(option.checked === true ? { checked: true } : {}),
18
+ });
19
+ }
20
+ return out;
21
+ }
22
+ export function buildWakePrompt(request, now = Date.now()) {
23
+ const options = normalizeOptions(request.options);
24
+ if (options.length < 1)
25
+ throw new Error("options must contain at least one item");
26
+ const mode = request.mode;
27
+ const allowMultiple = mode === "checklist" ? request.allowMultiple !== false : Boolean(request.allowMultiple);
28
+ const timeoutMs = Math.min(Math.max(request.timeoutMs ?? 180_000, 5_000), 900_000);
29
+ const id = `wake_${randomUUID().slice(0, 8)}`;
30
+ return {
31
+ id,
32
+ title: request.title.trim() || "请选择",
33
+ ...(request.prompt?.trim() ? { prompt: request.prompt.trim() } : {}),
34
+ mode,
35
+ options,
36
+ allowMultiple,
37
+ minSelections: request.minSelections ?? (mode === "choice" ? 1 : 0),
38
+ syncVerify: request.syncVerify ?? mode === "checklist",
39
+ createdAt: new Date(now).toISOString(),
40
+ expiresAt: new Date(now + timeoutMs).toISOString(),
41
+ };
42
+ }
43
+ export async function applyWakeVerifySync(root, prompt, selectedIds) {
44
+ if (!prompt.syncVerify)
45
+ return false;
46
+ const selected = new Set(selectedIds);
47
+ for (const option of prompt.options) {
48
+ const status = selected.has(option.id) ? "verified" : "unverified";
49
+ await markVerifyItem(root, option.id, status, `wake-options:${prompt.id}`, undefined);
50
+ }
51
+ return true;
52
+ }
53
+ /**
54
+ * Publish a wake-options prompt to Panel (SSE) and wait for an answer.
55
+ * Caller may race this against a CLI UI promise.
56
+ */
57
+ export function waitForPanelWakeAnswer(prompt, timeoutMs) {
58
+ return panelHub.publishWake(prompt, timeoutMs);
59
+ }
60
+ export function resolvePanelWakeAnswer(answer) {
61
+ return panelHub.resolveWake(answer);
62
+ }
63
+ export function formatWakeResult(result) {
64
+ return JSON.stringify({ schemaVersion: "psyclaw/wake-options-result/v1", ...result }, null, 2);
65
+ }
66
+ export function labelsFor(prompt, ids) {
67
+ const map = new Map(prompt.options.map((item) => [item.id, item.label]));
68
+ return ids.map((id) => map.get(id) ?? id);
69
+ }
70
+ //# sourceMappingURL=runtime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime.js","sourceRoot":"","sources":["../../../src/wake-options/runtime.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "psyclaw",
3
- "version": "0.29.9",
3
+ "version": "0.29.11",
4
4
  "description": "A standalone, evidence-grounded social-science research agent with research contracts, evidence gates, and recoverable workflows",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -1,7 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  import { homedir } from "node:os";
4
- import { join } from "node:path";
4
+ import { dirname, join } from "node:path";
5
+ import { fileURLToPath, pathToFileURL } from "node:url";
5
6
  import { rebrandPiRuntime } from "./rebrand-pi.mjs";
6
7
 
7
8
  try {
@@ -20,7 +21,10 @@ try {
20
21
  // first imported. Prepare the locked runtime before loading PsyClaw's CLI so
21
22
  // a clean first launch cannot create the legacy ~/.pi directory.
22
23
  await rebrandPiRuntime({ quiet: true });
23
- await import("../dist/src/cli.js");
24
+ // Use an explicit file:// URL so Windows absolute paths never reach the ESM
25
+ // loader as protocol `c:` (ERR_UNSUPPORTED_ESM_URL_SCHEME).
26
+ const cliUrl = pathToFileURL(join(dirname(fileURLToPath(import.meta.url)), "..", "dist", "src", "cli.js")).href;
27
+ await import(cliUrl);
24
28
  } catch (error) {
25
29
  process.stderr.write(`PsyClaw could not start: ${error instanceof Error ? error.message : String(error)}\n`);
26
30
  process.exitCode = 1;