psyclaw 0.29.18 → 0.29.19

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,3 @@
1
+ # PsyClaw 使用白皮书
2
+
3
+ 当前使用说明、安装方式和命令接口请阅读 [PsyClaw使用白皮书_v0.29.15.md](PsyClaw使用白皮书_v0.29.15.md)。同步提供 Word 版:[PsyClaw使用白皮书_v0.29.15.docx](PsyClaw使用白皮书_v0.29.15.docx)。
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "psyclaw",
3
- "version": "0.29.18",
3
+ "version": "0.29.19",
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",
@@ -30,7 +30,9 @@
30
30
  "vendor/academic-paper-skills",
31
31
  "vendor/windows",
32
32
  "scripts/psyclaw.mjs",
33
- "scripts/rebrand-pi.mjs"
33
+ "scripts/rebrand-pi.mjs",
34
+ "docs/使用白皮书.md",
35
+ "docs/PsyClaw使用白皮书_v0.29.15.md"
34
36
  ],
35
37
  "engines": {
36
38
  "node": ">=22.19.0"
@@ -423,6 +423,74 @@ async function applySettingsPatches(settingsManagerPath) {
423
423
  return applied;
424
424
  }
425
425
 
426
+ export const FOOTER_PATCHES = [
427
+ {
428
+ old: ` else {
429
+ contextPercentStr = contextPercentDisplay;
430
+ }
431
+ statsParts.push(contextPercentStr);
432
+ if (areExperimentalFeaturesEnabled()) {`,
433
+ next: ` else {
434
+ contextPercentStr = contextPercentDisplay;
435
+ }
436
+ statsParts.push(contextPercentStr);
437
+ const modeStatus = this.footerData.getExtensionStatuses().get("mode");
438
+ if (modeStatus) {
439
+ statsParts.push(sanitizeStatusText(modeStatus));
440
+ }
441
+ if (areExperimentalFeaturesEnabled()) {`,
442
+ },
443
+ {
444
+ old: ` // Add extension statuses on a single line, sorted by key alphabetically
445
+ const extensionStatuses = this.footerData.getExtensionStatuses();
446
+ if (extensionStatuses.size > 0) {
447
+ const sortedStatuses = Array.from(extensionStatuses.entries())
448
+ .sort(([a], [b]) => a.localeCompare(b))
449
+ .map(([, text]) => sanitizeStatusText(text));
450
+ const statusLine = sortedStatuses.join(" ");
451
+ // Truncate to terminal width with dim ellipsis for consistency with footer style
452
+ lines.push(truncateToWidth(statusLine, width, theme.fg("dim", "...")));
453
+ }`,
454
+ next: ` // Add extension statuses on a single line, sorted by key alphabetically
455
+ const extensionStatuses = this.footerData.getExtensionStatuses();
456
+ if (extensionStatuses.size > 0) {
457
+ const sortedStatuses = Array.from(extensionStatuses.entries())
458
+ .filter(([key]) => key !== "mode")
459
+ .sort(([a], [b]) => a.localeCompare(b))
460
+ .map(([, text]) => sanitizeStatusText(text));
461
+ if (sortedStatuses.length > 0) {
462
+ const statusLine = sortedStatuses.join(" ");
463
+ // Truncate to terminal width with dim ellipsis for consistency with footer style
464
+ lines.push(truncateToWidth(statusLine, width, theme.fg("dim", "...")));
465
+ }
466
+ }`,
467
+ },
468
+ ];
469
+
470
+ export function applyFooterPatchesToContent(content) {
471
+ let patched = content;
472
+ let appliedCount = 0;
473
+ const isCrlf = content.includes("\r\n");
474
+ for (const { old, next } of FOOTER_PATCHES) {
475
+ const targetOld = isCrlf ? old.replace(/\r?\n/g, "\r\n") : old;
476
+ const targetNext = isCrlf ? next.replace(/\r?\n/g, "\r\n") : next;
477
+ if (patched.includes(targetOld)) {
478
+ patched = patched.replace(targetOld, targetNext);
479
+ appliedCount++;
480
+ }
481
+ }
482
+ return { content: patched, applied: appliedCount > 0, appliedCount };
483
+ }
484
+
485
+ async function applyFooterPatches(footerPath) {
486
+ const content = await readFile(footerPath, "utf8");
487
+ const result = applyFooterPatchesToContent(content);
488
+ if (result.applied) {
489
+ await atomicReplace(footerPath, result.content, true);
490
+ }
491
+ return result.appliedCount;
492
+ }
493
+
426
494
  const MANAGED_TOOL_DOWNLOAD_GUARD = ` // PsyClaw supplies Node-based find/grep fallbacks. Keep PATH tools when
427
495
  // present, but never fetch optional binaries from GitHub during startup.
428
496
  return undefined;`;
@@ -448,16 +516,18 @@ export async function rebrandPiRuntime(options = {}) {
448
516
  const settingsManagerPath = join(pkgDir, "dist", "core", "settings-manager.js");
449
517
  const slashCommandsPath = join(pkgDir, "dist", "core", "slash-commands.js");
450
518
  const toolsManagerPath = join(pkgDir, "dist", "utils", "tools-manager.js");
519
+ const footerPath = join(pkgDir, "dist", "modes", "interactive", "components", "footer.js");
451
520
 
452
521
  const pkgResult = await patchPackageJson(pkgPath);
453
522
  const applied = await applyModePatches(modePath);
454
523
  const settingsApplied = await applySettingsPatches(settingsManagerPath);
524
+ const footerApplied = await applyFooterPatches(footerPath);
455
525
  const commandApplied = await applySlashCommandPatches(slashCommandsPath);
456
526
  const managedToolsRestored = await restoreManagedToolManager(toolsManagerPath);
457
527
 
458
528
  if (!options.quiet) {
459
529
  process.stdout.write(
460
- `psyclaw rebrand: piConfig ${pkgResult.applied ? "applied" : "already set"} · ${applied.length > 0 ? `patched ${applied.length} display string(s)` : "display strings already patched"} · ${settingsApplied.length > 0 ? `patched ${settingsApplied.length} setting default(s)` : "settings already patched"} · ${commandApplied.length > 0 ? `hidden ${commandApplied.length} Pi command(s)` : "Pi commands already filtered"} · ${managedToolsRestored ? "restored managed-tool downloads" : "managed-tool downloads unchanged"} (${pkgDir})\n`,
530
+ `psyclaw rebrand: piConfig ${pkgResult.applied ? "applied" : "already set"} · ${applied.length > 0 ? `patched ${applied.length} display string(s)` : "display strings already patched"} · ${settingsApplied.length > 0 ? `patched ${settingsApplied.length} setting default(s)` : "settings already patched"} · ${footerApplied > 0 ? `patched ${footerApplied} footer component(s)` : "footer already patched"} · ${commandApplied.length > 0 ? `hidden ${commandApplied.length} Pi command(s)` : "Pi commands already filtered"} · ${managedToolsRestored ? "restored managed-tool downloads" : "managed-tool downloads unchanged"} (${pkgDir})\n`,
461
531
  );
462
532
  if (applied.length > 0) {
463
533
  for (const label of applied) {
@@ -469,6 +539,9 @@ export async function rebrandPiRuntime(options = {}) {
469
539
  process.stdout.write(` - ${label}…\n`);
470
540
  }
471
541
  }
542
+ if (footerApplied > 0) {
543
+ process.stdout.write(` - mode status inline with context auto indicator…\n`);
544
+ }
472
545
  if (commandApplied.length > 0) {
473
546
  for (const label of commandApplied) {
474
547
  process.stdout.write(` - ${label}…\n`);
@@ -103,8 +103,10 @@
103
103
  "name": "Journal Frontier Radar",
104
104
  "kind": "skill",
105
105
  "stage": "文献前沿",
106
- "description": "基于期刊文章清单开展可追溯的前沿追踪、主题映射、关键词分析和未解决问题发现。",
106
+ "description": "基于期刊文章清单开展可追溯的前沿追踪、主题映射、关键词分析和未解决问题发现。前置依赖:Kimi WebBridge(须先安装并 `kimi-webbridge status` 确认 extension_connected)。",
107
107
  "sourceRef": "https://github.com/kingfly51/journal-frontier-radar",
108
+ "prerequisites": ["kimi-webbridge"],
109
+ "requiresExternalTools": ["kimi-webbridge"],
108
110
  "installHint": "安装仓库中的 skills/journal-frontier-radar 完整目录,包含 SKILL.md 及其脚本。启用前须先安装推荐外部工具 Kimi WebBridge(官方 daemon + Chrome/Edge 扩展),并用 `kimi-webbridge status` 确认 extension_connected: true;不要把本机 Downloads 解压扩展当 PsyClaw Plugin 安装。"
109
111
  },
110
112
  {
@@ -204,7 +206,7 @@
204
206
  "kind": "external-tool",
205
207
  "installable": true,
206
208
  "stage": "浏览器桥接",
207
- "description": "月之暗面官方本机浏览器桥:daemon(127.0.0.1:10086)+ Chrome/Edge 扩展。让 Agent 操作用户真实浏览器与登录态,供 Journal Frontier Radar 等文献调研 Skill 联网检索;不是 PsyClaw Plugin,也不是可 clone 进 .psyclaw 的 Skill 包。",
209
+ "description": "月之暗面官方本机浏览器桥:daemon(127.0.0.1:10086)+ Chrome/Edge 扩展。让 Agent 操作用户真实浏览器与登录态;Journal Frontier Radar 的前置依赖。不是 PsyClaw Plugin,也不是可 clone 进 .psyclaw 的 Skill 包。",
208
210
  "sourceRef": "https://www.kimi.com/zh-cn/features/webbridge",
209
211
  "installHint": "按官网安装,不要把 Downloads 解压扩展当 PsyClaw Plugin。1) macOS/Linux 执行 `curl -fsSL https://cdn.kimi.com/webbridge/install.sh | bash`(Windows 按官网指引);2) 从 Chrome Web Store 或 Edge Add-ons 安装 Kimi WebBridge 扩展并保持浏览器运行;商店不可用时才从官网下载后手动「加载已解压的扩展程序」;3) 运行 `kimi-webbridge status`,确认 extension_connected: true;4) 安装脚本若写入宿主 Skill 目录(常见为 ~/.claude/skills/kimi-webbridge),保留即可,供 Agent 调用本机 daemon。完成后报告 daemon 路径、扩展连接状态与验证命令输出。"
210
212
  },