psyclaw 0.30.8 → 0.30.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.
package/LICENSE CHANGED
@@ -1,21 +1,16 @@
1
- MIT License
1
+ Creative Commons Attribution-NonCommercial 4.0 International
2
2
 
3
- Copyright (c) 2026 Exekiel179 and PsyClaw contributors
3
+ Copyright (c) 2026 Exekiel179
4
4
 
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
5
+ PsyClaw is licensed under the Creative Commons Attribution-NonCommercial 4.0
6
+ International License (CC BY-NC 4.0).
11
7
 
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
8
+ You may share and adapt the material for non-commercial purposes, provided you
9
+ give appropriate credit and indicate if changes were made. Commercial use is not
10
+ permitted under this license.
14
11
 
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
12
+ Full legal code:
13
+ https://creativecommons.org/licenses/by-nc/4.0/legalcode
14
+
15
+ Human-readable summary:
16
+ https://creativecommons.org/licenses/by-nc/4.0/
package/README.md CHANGED
@@ -2,21 +2,20 @@
2
2
 
3
3
  面向社会科学研究的智能体工作台:把研究项目、证据账本、完整性门禁、可恢复工作流和本地面板接到内置运行时上。它不替代统计软件,也不会把未经核验的引用、结果或审稿意见写成事实。
4
4
 
5
- 当前版本:`0.30.8` · 命令与用户目录:`psyclaw` / `~/.psyclaw` · 许可证:MIT
6
- 内置 Academic Research Skills(`vendor/ars`)遵循上游 CC BY-NC 4.0,仅限非商业用途。
5
+ 许可证:CC BY-NC 4.0
7
6
 
8
7
  ## 安装
9
8
 
10
9
  需要 Node.js `>=22.19.0`。
11
10
 
12
11
  ```bash
13
- npm install -g psyclaw@0.30.8
12
+ npm install -g psyclaw@latest
14
13
  ```
15
14
 
16
15
  中国大陆可用镜像或安装脚本:
17
16
 
18
17
  ```bash
19
- npm install -g psyclaw@0.30.8 --registry=https://registry.npmmirror.com
18
+ npm install -g psyclaw@latest --registry=https://registry.npmmirror.com
20
19
  # 或
21
20
  PSYCLAW_CN=1 curl -fsSL https://exekiel179.github.io/psyclaw/install.sh | sh
22
21
  ```
@@ -79,13 +78,6 @@ psyclaw evidence add notes/source.md --level user
79
78
  - [技能与生态准入清单](docs/技能与生态准入清单.md) · [威胁模型](docs/威胁模型.md)
80
79
  - [AGENTS.md](AGENTS.md)
81
80
 
82
- ## 边界
83
-
84
- - 复用官方 Pi runtime,不维护 fork。
85
- - 统计计算委托 Python/R、SPSS/Stata/Mplus 或受信任 MCP;须保存脚本、输入指纹与环境信息。
86
- - Skill / Plugin / MCP 默认只发现、不执行;启用前核对来源与信任状态。
87
- - 无证据的事实性 Claim 须标为 `uncertain` 或阻断;无 receipt / 审批的副作用不算完成。
88
-
89
81
  ## 从源码开发
90
82
 
91
83
  ```bash
@@ -109,7 +101,7 @@ RELEASE_MESSAGE="release: describe the change" pnpm release:push
109
101
 
110
102
  ```bash
111
103
  npm uninstall -g psyclaw
112
- npm install -g psyclaw@0.30.8
104
+ npm install -g psyclaw@latest
113
105
  ```
114
106
 
115
107
  仅卸载程序:`npm uninstall -g psyclaw`
@@ -15,6 +15,7 @@ import { PROVIDER_PRESETS, providerCredentialSource, saveProviderConfig } from "
15
15
  import { dirname } from "node:path";
16
16
  import { fileURLToPath } from "node:url";
17
17
  import { coreSkillNames, enabledRecommendedSkillPaths, normalizeRecommendedSkillId, readRecommendationState, readRecommendedCatalog, recommendedSkillTarget, saveRecommendationState, validateModelInstalledRecommendedSkill, } from "../../skills/recommended.js";
18
+ import { buildRecommendedSkillInstallTask } from "../../skills/install-guidance.js";
18
19
  import { SkillManagerComponent } from "../../tui/skill-manager.js";
19
20
  import { BiosignalWizardComponent } from "../../tui/biosignal-wizard.js";
20
21
  import { readBiosignalPackCatalog, resolveBiosignalInstallPlan, } from "../../skills/biosignal-pack.js";
@@ -726,12 +727,20 @@ function modelMcpInstallTask(root, row, plan) {
726
727
  "成功后确保 .psyclaw/recommendations.json 的 mcp 列表包含该 id(安装时已默认写入启用),说明写入了哪些配置,并提醒用户执行 /reload。若安装命令本身失败,直接诊断并修复;只有遇到必须由用户提供的凭据或外部软件许可证时才向用户说明。",
727
728
  ].join("\n");
728
729
  }
730
+ /** Queue an install/setup prompt for the model without rendering the long text as a user bubble. */
731
+ function queueHiddenInstallTask(pi, ctx, task) {
732
+ if (typeof pi.sendMessage === "function") {
733
+ pi.sendMessage({ customType: "psyclaw-install-task", content: task, display: false }, ctx.isIdle() ? { triggerTurn: true } : { deliverAs: "followUp" });
734
+ return;
735
+ }
736
+ pi.sendUserMessage(task, ctx.isIdle() ? {} : { deliverAs: "followUp" });
737
+ }
729
738
  async function queueModelMcpInstall(pi, ctx, row, plan) {
730
739
  if (!row.sourceRef)
731
740
  throw new Error(`推荐 MCP 没有来源网址: ${row.id}`);
732
741
  await setRecommendedMcpEnabled(ctx.cwd, row.id, true);
733
- pi.sendUserMessage(modelMcpInstallTask(ctx.cwd, row, plan), ctx.isIdle() ? {} : { deliverAs: "followUp" });
734
- ctx.ui.notify(`已将 ${row.name} 的下载、安装和配置任务交给当前模型(默认启用)。完成后请执行 /reload。`, "info");
742
+ queueHiddenInstallTask(pi, ctx, modelMcpInstallTask(ctx.cwd, row, plan));
743
+ ctx.ui.notify(`已将 ${row.name} 的安装任务交给当前模型(指令不展示在对话中;默认启用)。完成后请执行 /reload。`, "info");
735
744
  }
736
745
  async function showMcpManager(pi, ctx, runtime) {
737
746
  const catalog = await recommendedItems("mcp");
@@ -776,20 +785,15 @@ async function showMcpManager(pi, ctx, runtime) {
776
785
  }
777
786
  }
778
787
  function modelSkillInstallTask(root, row, scope) {
779
- const target = recommendedSkillTarget(root, row.id, scope);
780
- return [
781
- `安装推荐 Skill:${row.name} (${row.id})。`,
782
- `来源网址:${row.sourceRef}`,
783
- ...(row.installHint ? [`仓库入口提示:${row.installHint}`] : []),
784
- `安装位置:${skillScopeLabel(scope)}。`,
785
- `唯一允许的最终目标目录:${target}`,
786
- "用户已通过 Skill 管理页授权本次安装。请使用当前会话的联网、文件和命令工具读取来源仓库,并直接下载、安装所需依赖和完成 Skill 安装;不要再次要求安装权限。不要写入其他 Skill 目录,不要修改 .psyclaw/data/raw、data/raw、.git 或研究产物。",
787
- row.collection
788
- ? "这是多 Skill 套件:目标目录自身无需 SKILL.md,但其子目录必须包含一个或多个有效 SKILL.md。保留套件内共享目录和相对路径,不得包含 .git、符号链接或凭据。"
789
- : "目标目录最终必须直接包含有效 SKILL.md(YAML frontmatter 至少包含 name 和 description),不得包含 .git、符号链接、凭据或二进制大文件。",
790
- "如果仓库包含多个 Skill,只安装与此推荐项相符的部分;如果它不是 Skill 或无法合理适配,停止并说明原因,不要伪造 SKILL.md。",
791
- "安装完成后检查目标目录结构。该项已在推荐状态中默认启用;完成后执行 /reload 即可加载,无需再手动启用。",
792
- ].join("\n");
788
+ return buildRecommendedSkillInstallTask({
789
+ name: row.name,
790
+ id: row.id,
791
+ sourceRef: row.sourceRef ?? "",
792
+ target: recommendedSkillTarget(root, row.id, scope),
793
+ scopeLabel: skillScopeLabel(scope),
794
+ ...(row.installHint ? { installHint: row.installHint } : {}),
795
+ collection: Boolean(row.collection),
796
+ });
793
797
  }
794
798
  async function chooseSkillScope(ctx) {
795
799
  const projectLabel = skillScopeLabel("project");
@@ -829,8 +833,8 @@ async function queueModelSkillInstall(pi, ctx, row) {
829
833
  return;
830
834
  }
831
835
  void trackSkillInstall("queued", { skill_id: row.id, scope, status: "queued" });
832
- pi.sendUserMessage(modelSkillInstallTask(ctx.cwd, row, scope), ctx.isIdle() ? {} : { deliverAs: "followUp" });
833
- ctx.ui.notify(`已将 ${row.name} 的安装任务交给当前模型(默认启用),目标为${skillScopeLabel(scope)}。完成后请执行 /reload。`, "info");
836
+ queueHiddenInstallTask(pi, ctx, modelSkillInstallTask(ctx.cwd, row, scope));
837
+ ctx.ui.notify(`已将 ${row.name} 的安装任务交给当前模型(指令不展示在对话中;默认启用),目标为${skillScopeLabel(scope)}。完成后请执行 /reload。`, "info");
834
838
  });
835
839
  }
836
840
  function modelBiosignalPackInstallTask(root, plan, skillRows, mcpRows, mcpPlans, skillScope) {
@@ -943,8 +947,8 @@ async function queueBiosignalPackInstall(pi, ctx, plan, runtime) {
943
947
  if (!approved)
944
948
  return;
945
949
  await markBiosignalPackDesired(ctx.cwd, plan, scope);
946
- pi.sendUserMessage(modelBiosignalPackInstallTask(ctx.cwd, plan, skillRows, selectedMcp, mcpCatalog.installPrep, scope), ctx.isIdle() ? {} : { deliverAs: "followUp" });
947
- ctx.ui.notify("已将生理信号能力包安装任务交给当前模型。完成后请执行 /reload,并 Shift+Tab 切到 analysis 使用。", "info");
950
+ queueHiddenInstallTask(pi, ctx, modelBiosignalPackInstallTask(ctx.cwd, plan, skillRows, selectedMcp, mcpCatalog.installPrep, scope));
951
+ ctx.ui.notify("已将生理信号能力包安装任务交给当前模型(指令不展示在对话中)。完成后请执行 /reload,并 Shift+Tab 切到 analysis 使用。", "info");
948
952
  }
949
953
  async function showBiosignalPack(pi, ctx, runtime) {
950
954
  const catalog = await readBiosignalPackCatalog();
@@ -1315,6 +1319,7 @@ export default function psyclawExtension(pi) {
1315
1319
  isProjectTrusted: () => ctx.isProjectTrusted(),
1316
1320
  isIdle: () => ctx.isIdle(),
1317
1321
  sendUserMessage: (message, options) => pi.sendUserMessage(message, options ?? {}),
1322
+ sendHiddenInstallTask: (task) => queueHiddenInstallTask(pi, ctx, task),
1318
1323
  }, { view: "help" });
1319
1324
  ctx.ui.notify(formatSessionHelpBrief(url) + (opened ? "" : "\n(未能自动打开浏览器时请手动访问)"), opened ? "info" : "warning");
1320
1325
  }
@@ -1597,6 +1602,7 @@ export default function psyclawExtension(pi) {
1597
1602
  isProjectTrusted: () => ctx.isProjectTrusted(),
1598
1603
  isIdle: () => ctx.isIdle(),
1599
1604
  sendUserMessage: (message, options) => pi.sendUserMessage(message, options ?? {}),
1605
+ sendHiddenInstallTask: (task) => queueHiddenInstallTask(pi, ctx, task),
1600
1606
  }, { view: "help" });
1601
1607
  ctx.ui.notify(formatSessionHelpBrief(url) + (opened ? "" : "\n(未能自动打开浏览器时请手动访问)"), opened ? "info" : "warning");
1602
1608
  }