wangchuan 1.0.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.
Files changed (73) hide show
  1. package/.wangchuan/config.example.json +43 -0
  2. package/README.md +210 -0
  3. package/dist/bin/wangchuan.d.ts +9 -0
  4. package/dist/bin/wangchuan.d.ts.map +1 -0
  5. package/dist/bin/wangchuan.js +93 -0
  6. package/dist/bin/wangchuan.js.map +1 -0
  7. package/dist/src/commands/diff.d.ts +9 -0
  8. package/dist/src/commands/diff.d.ts.map +1 -0
  9. package/dist/src/commands/diff.js +96 -0
  10. package/dist/src/commands/diff.js.map +1 -0
  11. package/dist/src/commands/init.d.ts +6 -0
  12. package/dist/src/commands/init.d.ts.map +1 -0
  13. package/dist/src/commands/init.js +49 -0
  14. package/dist/src/commands/init.js.map +1 -0
  15. package/dist/src/commands/list.d.ts +9 -0
  16. package/dist/src/commands/list.d.ts.map +1 -0
  17. package/dist/src/commands/list.js +45 -0
  18. package/dist/src/commands/list.js.map +1 -0
  19. package/dist/src/commands/pull.d.ts +6 -0
  20. package/dist/src/commands/pull.d.ts.map +1 -0
  21. package/dist/src/commands/pull.js +53 -0
  22. package/dist/src/commands/pull.js.map +1 -0
  23. package/dist/src/commands/push.d.ts +9 -0
  24. package/dist/src/commands/push.d.ts.map +1 -0
  25. package/dist/src/commands/push.js +72 -0
  26. package/dist/src/commands/push.js.map +1 -0
  27. package/dist/src/commands/status.d.ts +6 -0
  28. package/dist/src/commands/status.d.ts.map +1 -0
  29. package/dist/src/commands/status.js +86 -0
  30. package/dist/src/commands/status.js.map +1 -0
  31. package/dist/src/core/config.d.ts +27 -0
  32. package/dist/src/core/config.d.ts.map +1 -0
  33. package/dist/src/core/config.js +110 -0
  34. package/dist/src/core/config.js.map +1 -0
  35. package/dist/src/core/crypto.d.ts +24 -0
  36. package/dist/src/core/crypto.d.ts.map +1 -0
  37. package/dist/src/core/crypto.js +89 -0
  38. package/dist/src/core/crypto.js.map +1 -0
  39. package/dist/src/core/git.d.ts +18 -0
  40. package/dist/src/core/git.d.ts.map +1 -0
  41. package/dist/src/core/git.js +79 -0
  42. package/dist/src/core/git.js.map +1 -0
  43. package/dist/src/core/sync.d.ts +27 -0
  44. package/dist/src/core/sync.d.ts.map +1 -0
  45. package/dist/src/core/sync.js +253 -0
  46. package/dist/src/core/sync.js.map +1 -0
  47. package/dist/src/types.d.ts +95 -0
  48. package/dist/src/types.d.ts.map +1 -0
  49. package/dist/src/types.js +5 -0
  50. package/dist/src/types.js.map +1 -0
  51. package/dist/src/utils/linediff.d.ts +22 -0
  52. package/dist/src/utils/linediff.d.ts.map +1 -0
  53. package/dist/src/utils/linediff.js +80 -0
  54. package/dist/src/utils/linediff.js.map +1 -0
  55. package/dist/src/utils/logger.d.ts +13 -0
  56. package/dist/src/utils/logger.d.ts.map +1 -0
  57. package/dist/src/utils/logger.js +34 -0
  58. package/dist/src/utils/logger.js.map +1 -0
  59. package/dist/src/utils/prompt.d.ts +14 -0
  60. package/dist/src/utils/prompt.d.ts.map +1 -0
  61. package/dist/src/utils/prompt.js +37 -0
  62. package/dist/src/utils/prompt.js.map +1 -0
  63. package/dist/src/utils/validator.d.ts +17 -0
  64. package/dist/src/utils/validator.d.ts.map +1 -0
  65. package/dist/src/utils/validator.js +33 -0
  66. package/dist/src/utils/validator.js.map +1 -0
  67. package/dist/test/crypto.test.d.ts +5 -0
  68. package/dist/test/crypto.test.d.ts.map +1 -0
  69. package/dist/test/crypto.test.js +93 -0
  70. package/dist/test/crypto.test.js.map +1 -0
  71. package/package.json +56 -0
  72. package/skill/SKILL.md +67 -0
  73. package/skill/wangchuan-skill.sh +54 -0
@@ -0,0 +1,43 @@
1
+ {
2
+ "_comment": "忘川配置示例 — 复制为 ~/.wangchuan/config.json 并修改",
3
+ "repo": "git@github.com:SUpermin6u/wangchuan.git",
4
+ "branch": "main",
5
+ "localRepoPath": "~/.wangchuan/repo",
6
+ "keyPath": "~/.wangchuan/master.key",
7
+ "hostname": "",
8
+ "profiles": {
9
+ "default": {
10
+ "openclaw": {
11
+ "enabled": true,
12
+ "workspacePath": "~/.openclaw/workspace",
13
+ "syncFiles": [
14
+ { "src": "MEMORY.md", "encrypt": true },
15
+ { "src": "AGENTS.md", "encrypt": false },
16
+ { "src": "SOUL.md", "encrypt": false },
17
+ { "src": "USER.md", "encrypt": true },
18
+ { "src": "TOOLS.md", "encrypt": false },
19
+ { "src": "config/mcporter.json", "encrypt": true }
20
+ ],
21
+ "syncDirs": [
22
+ { "src": "skills/", "encrypt": false }
23
+ ]
24
+ },
25
+ "claude": {
26
+ "enabled": false,
27
+ "workspacePath": "~/.claude",
28
+ "syncFiles": [
29
+ { "src": ".claude.json", "encrypt": true }
30
+ ]
31
+ },
32
+ "gemini": {
33
+ "enabled": false,
34
+ "workspacePath": "~/.gemini",
35
+ "syncFiles": [
36
+ { "src": "settings.internal.json", "encrypt": true },
37
+ { "src": "projects.json", "encrypt": false },
38
+ { "src": "trustedFolders.json", "encrypt": false }
39
+ ]
40
+ }
41
+ }
42
+ }
43
+ }
package/README.md ADDED
@@ -0,0 +1,210 @@
1
+ # 忘川 · Wangchuan
2
+
3
+ > 忘川是中国神话中冥界的遗忘之河,亡魂渡河饮水即忘前世一切记忆。
4
+ > 而 **Wangchuan** 让你的 AI 配置在环境切换时永不遗失。
5
+
6
+ AI 记忆同步系统,支持 OpenClaw / Claude / Gemini 多种智能体记忆的加密备份与跨环境迁移。
7
+
8
+ ---
9
+
10
+ ## 功能特性
11
+
12
+ | 命令 | 描述 |
13
+ |------|------|
14
+ | `init` | 初始化系统、生成 AES-256-GCM 密钥、克隆私有仓库 |
15
+ | `pull` | 从私有仓库拉取并解密配置,还原到本地工作区(支持冲突交互) |
16
+ | `push` | 将本地配置加密推送到私有仓库 |
17
+ | `status` | 查看仓库状态、工作区差异与文件清单 |
18
+ | `diff` | 逐文件显示本地与仓库的行级差异(自动解密) |
19
+ | `list` | 列出所有托管文件,显示本地/仓库存在状态 |
20
+
21
+ - **AES-256-GCM** 加密:密钥本地存储,永不提交 Git
22
+ - 全局 `--agent` 过滤:只操作指定智能体(`openclaw` / `claude` / `gemini`)
23
+ - 推送前自动扫描明文 token/apiKey
24
+ - 拉取冲突时交互式选择:覆盖 / 跳过 / 全部覆盖 / 全部跳过
25
+ - 失败自动回滚,不污染仓库历史
26
+ - 支持 OpenClaw Skill 封装,对话直接调用
27
+
28
+ ---
29
+
30
+ ## 安装
31
+
32
+ ```bash
33
+ git clone https://github.com/SUpermin6u/wangchuan.git ~/wangchuan
34
+ cd ~/wangchuan
35
+ npm install
36
+ npm run build # 编译 TypeScript
37
+ npm link # 全局注册 wangchuan 命令(可选)
38
+ ```
39
+
40
+ ---
41
+
42
+ ## 快速开始
43
+
44
+ ### 1. 初始化
45
+
46
+ ```bash
47
+ wangchuan init --repo git@github.com:yourname/your-brain.git
48
+ ```
49
+
50
+ 执行后:
51
+ - 生成 `~/.wangchuan/config.json`(系统配置)
52
+ - 生成 `~/.wangchuan/master.key`(主密钥,**请妥善保管**)
53
+ - 克隆仓库到 `~/.wangchuan/repo`
54
+
55
+ ### 2. 推送本地配置
56
+
57
+ ```bash
58
+ wangchuan push --message "初始化配置"
59
+ ```
60
+
61
+ ### 3. 在新环境拉取配置
62
+
63
+ ```bash
64
+ # 先把 master.key 复制到新环境的 ~/.wangchuan/master.key
65
+ wangchuan init --repo git@github.com:yourname/your-brain.git
66
+ wangchuan pull
67
+ ```
68
+
69
+ ### 4. 查看同步状态
70
+
71
+ ```bash
72
+ wangchuan status
73
+ ```
74
+
75
+ ### 5. 只操作指定智能体
76
+
77
+ ```bash
78
+ wangchuan push --agent openclaw -m "更新 OpenClaw 记忆"
79
+ wangchuan pull --agent claude
80
+ wangchuan diff --agent gemini
81
+ ```
82
+
83
+ ---
84
+
85
+ ## 支持同步的配置
86
+
87
+ 每个智能体的 `workspacePath` 均可在 `~/.wangchuan/config.json` 中自定义。
88
+
89
+ ### OpenClaw(默认开启)
90
+
91
+ | 文件 | 加密 |
92
+ |------|------|
93
+ | `MEMORY.md` | ✔ 加密 |
94
+ | `AGENTS.md` | 明文 |
95
+ | `SOUL.md` | 明文 |
96
+ | `USER.md` | ✔ 加密 |
97
+ | `TOOLS.md` | 明文 |
98
+ | `config/mcporter.json` | ✔ 加密 |
99
+ | `skills/` (目录) | 明文 |
100
+
101
+ 默认路径:`~/.openclaw/workspace/`
102
+
103
+ ### Claude(可选,在配置中开启)
104
+
105
+ | 文件 | 加密 |
106
+ |------|------|
107
+ | `.claude.json` | ✔ 加密 |
108
+
109
+ 默认路径:`~/.claude/`
110
+
111
+ ### Gemini(可选,在配置中开启)
112
+
113
+ | 文件 | 加密 |
114
+ |------|------|
115
+ | `settings.internal.json` | ✔ 加密 |
116
+ | `projects.json` | 明文 |
117
+ | `trustedFolders.json` | 明文 |
118
+
119
+ 默认路径:`~/.gemini/`
120
+
121
+ ---
122
+
123
+ ## 配置文件
124
+
125
+ 配置位于 `~/.wangchuan/config.json`,示例见 [.wangchuan/config.example.json](.wangchuan/config.example.json)。
126
+
127
+ ```jsonc
128
+ {
129
+ "repo": "git@github.com:yourname/your-brain.git",
130
+ "branch": "main",
131
+ "localRepoPath": "~/.wangchuan/repo",
132
+ "keyPath": "~/.wangchuan/master.key",
133
+ "profiles": {
134
+ "default": {
135
+ "openclaw": { "enabled": true, "workspacePath": "~/.openclaw/workspace", ... },
136
+ "claude": { "enabled": false, "workspacePath": "~/.claude", ... },
137
+ "gemini": { "enabled": false, "workspacePath": "~/.gemini", ... }
138
+ }
139
+ }
140
+ }
141
+ ```
142
+
143
+ ---
144
+
145
+ ## 加密说明
146
+
147
+ - 算法:**AES-256-GCM**(认证加密,防篡改)
148
+ - 密钥:`~/.wangchuan/master.key`(32 字节,十六进制存储)
149
+ - 密文格式:`IV(12B) + AuthTag(16B) + CipherText`,Base64 编码后存储为 `.enc` 文件
150
+ - **⚠️ master.key 丢失将无法解密历史配置,请做好备份**
151
+
152
+ ---
153
+
154
+ ## OpenClaw Skill
155
+
156
+ 将 `skill/` 目录注册为 OpenClaw Skill 后,即可在对话中直接说:
157
+
158
+ > "帮我拉取最新的 AI 配置"
159
+ > "把修改推送一下,备注:更新项目记忆"
160
+ > "查看忘川状态"
161
+ > "列出所有托管文件"
162
+
163
+ ---
164
+
165
+ ## 安全规范
166
+
167
+ 1. `master.key` 已加入 `.gitignore`,不会意外提交
168
+ 2. 推送前自动扫描明文 token(`api_key`, `sk-xxx`, `password` 等)
169
+ 3. 若需迁移密钥,用加密方式传输(不要通过明文邮件/IM)
170
+
171
+ ---
172
+
173
+ ## 目录结构
174
+
175
+ ```
176
+ wangchuan/
177
+ ├── bin/wangchuan.ts CLI 入口
178
+ ├── src/
179
+ │ ├── core/
180
+ │ │ ├── sync.ts 同步引擎
181
+ │ │ ├── crypto.ts AES-256-GCM 加解密
182
+ │ │ ├── git.ts simple-git 封装
183
+ │ │ └── config.ts 配置管理
184
+ │ ├── commands/
185
+ │ │ ├── init.ts init 命令
186
+ │ │ ├── pull.ts pull 命令
187
+ │ │ ├── push.ts push 命令
188
+ │ │ ├── status.ts status 命令
189
+ │ │ ├── diff.ts diff 命令
190
+ │ │ └── list.ts list 命令
191
+ │ ├── utils/
192
+ │ │ ├── logger.ts 日志工具
193
+ │ │ ├── validator.ts 参数校验
194
+ │ │ ├── linediff.ts LCS 行级差异算法
195
+ │ │ └── prompt.ts 交互式冲突提示
196
+ │ └── types.ts 全局类型定义
197
+ ├── skill/
198
+ │ ├── SKILL.md OpenClaw Skill 说明
199
+ │ └── wangchuan-skill.sh Skill 脚本
200
+ ├── test/
201
+ │ └── crypto.test.ts 加密模块测试
202
+ └── .wangchuan/
203
+ └── config.example.json 配置示例
204
+ ```
205
+
206
+ ---
207
+
208
+ ## License
209
+
210
+ MIT
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * wangchuan.ts — CLI 入口
4
+ *
5
+ * 用法:
6
+ * wangchuan <command> [--agent openclaw|claude|gemini] [flags]
7
+ */
8
+ export {};
9
+ //# sourceMappingURL=wangchuan.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wangchuan.d.ts","sourceRoot":"","sources":["../../bin/wangchuan.ts"],"names":[],"mappings":";AACA;;;;;GAKG"}
@@ -0,0 +1,93 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * wangchuan.ts — CLI 入口
4
+ *
5
+ * 用法:
6
+ * wangchuan <command> [--agent openclaw|claude|gemini] [flags]
7
+ */
8
+ import { Command } from 'commander';
9
+ import { cmdInit } from '../src/commands/init.js';
10
+ import { cmdPull } from '../src/commands/pull.js';
11
+ import { cmdPush } from '../src/commands/push.js';
12
+ import { cmdStatus } from '../src/commands/status.js';
13
+ import { cmdDiff } from '../src/commands/diff.js';
14
+ import { cmdList } from '../src/commands/list.js';
15
+ import { logger } from '../src/utils/logger.js';
16
+ const AGENT_CHOICES = ['openclaw', 'claude', 'gemini'];
17
+ /** 校验 --agent 值合法性 */
18
+ function parseAgent(val) {
19
+ if (!AGENT_CHOICES.includes(val)) {
20
+ throw new Error(`--agent 必须是 openclaw | claude | gemini,收到: ${val}`);
21
+ }
22
+ return val;
23
+ }
24
+ const program = new Command();
25
+ program
26
+ .name('wangchuan')
27
+ .description('忘川 · AI 记忆同步系统')
28
+ .version('1.0.0');
29
+ // ── init ────────────────────────────────────────────────────────
30
+ program
31
+ .command('init')
32
+ .description('初始化忘川,配置仓库并生成密钥')
33
+ .requiredOption('-r, --repo <url>', 'Git 仓库地址 (SSH 或 HTTPS)')
34
+ .option('--force', '强制重新初始化(覆盖现有配置)', false)
35
+ .action(async (opts) => {
36
+ await run(() => cmdInit(opts));
37
+ });
38
+ // ── pull ────────────────────────────────────────────────────────
39
+ program
40
+ .command('pull')
41
+ .description('从远端仓库拉取并还原配置到本地工作区')
42
+ .option('-a, --agent <name>', '只操作指定智能体 (openclaw|claude|gemini)', parseAgent)
43
+ .action(async (opts) => {
44
+ await run(() => cmdPull(opts));
45
+ });
46
+ // ── push ────────────────────────────────────────────────────────
47
+ program
48
+ .command('push')
49
+ .description('将本地工作区配置加密后推送到远端仓库')
50
+ .option('-m, --message <msg>', '自定义提交信息')
51
+ .option('-a, --agent <name>', '只操作指定智能体 (openclaw|claude|gemini)', parseAgent)
52
+ .action(async (opts) => {
53
+ await run(() => cmdPush(opts));
54
+ });
55
+ // ── status ──────────────────────────────────────────────────────
56
+ program
57
+ .command('status')
58
+ .description('查看当前同步状态和工作区差异')
59
+ .option('-a, --agent <name>', '只操作指定智能体 (openclaw|claude|gemini)', parseAgent)
60
+ .action(async (opts) => {
61
+ await run(() => cmdStatus(opts));
62
+ });
63
+ // ── diff ────────────────────────────────────────────────────────
64
+ program
65
+ .command('diff')
66
+ .description('显示本地与仓库的行级文件差异')
67
+ .option('-a, --agent <name>', '只显示指定智能体 (openclaw|claude|gemini)', parseAgent)
68
+ .action(async (opts) => {
69
+ await run(() => cmdDiff(opts));
70
+ });
71
+ // ── list ────────────────────────────────────────────────────────
72
+ program
73
+ .command('list')
74
+ .description('列出所有受管配置项及其本地/仓库存在状态')
75
+ .option('-a, --agent <name>', '只列出指定智能体 (openclaw|claude|gemini)', parseAgent)
76
+ .action(async (opts) => {
77
+ await run(() => cmdList(opts));
78
+ });
79
+ // ── 错误兜底 ────────────────────────────────────────────────────
80
+ async function run(fn) {
81
+ try {
82
+ await fn();
83
+ }
84
+ catch (err) {
85
+ logger.error(err.message);
86
+ if (process.env['WANGCHUAN_LOG_LEVEL'] === 'debug') {
87
+ console.error(err.stack);
88
+ }
89
+ process.exit(1);
90
+ }
91
+ }
92
+ program.parse(process.argv);
93
+ //# sourceMappingURL=wangchuan.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wangchuan.js","sourceRoot":"","sources":["../../bin/wangchuan.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * diff.ts — wangchuan diff 命令
3
+ *
4
+ * 对每个有变化的文件展示行级 unified diff。
5
+ * 加密文件先解密后再比较内容,明文文件直接比较。
6
+ */
7
+ import type { DiffCommandOptions } from '../types.js';
8
+ export declare function cmdDiff({ agent }?: DiffCommandOptions): Promise<void>;
9
+ //# sourceMappingURL=diff.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diff.d.ts","sourceRoot":"","sources":["../../../src/commands/diff.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAUH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAGtD,wBAAsB,OAAO,CAAC,EAAE,KAAK,EAAE,GAAE,kBAAuB,GAAG,OAAO,CAAC,IAAI,CAAC,CAqF/E"}
@@ -0,0 +1,96 @@
1
+ /**
2
+ * diff.ts — wangchuan diff 命令
3
+ *
4
+ * 对每个有变化的文件展示行级 unified diff。
5
+ * 加密文件先解密后再比较内容,明文文件直接比较。
6
+ */
7
+ import fs from 'fs';
8
+ import path from 'path';
9
+ import { config } from '../core/config.js';
10
+ import { syncEngine } from '../core/sync.js';
11
+ import { cryptoEngine } from '../core/crypto.js';
12
+ import { validator } from '../utils/validator.js';
13
+ import { logger } from '../utils/logger.js';
14
+ import { diffText } from '../utils/linediff.js';
15
+ import chalk from 'chalk';
16
+ export async function cmdDiff({ agent } = {}) {
17
+ logger.banner('忘川 · 文件差异');
18
+ const cfg = config.load();
19
+ validator.requireInit(cfg);
20
+ const repoPath = syncEngine.expandHome(cfg.localRepoPath);
21
+ const keyPath = syncEngine.expandHome(cfg.keyPath);
22
+ const entries = syncEngine.buildFileEntries(cfg, undefined, agent);
23
+ if (agent)
24
+ logger.info(`过滤智能体: ${chalk.cyan(agent)}\n`);
25
+ let totalChanged = 0;
26
+ for (const entry of entries) {
27
+ const srcExists = fs.existsSync(entry.srcAbs);
28
+ const repoAbs = path.join(repoPath, entry.repoRel);
29
+ const repoExists = fs.existsSync(repoAbs);
30
+ // ── 仅一侧存在 ──────────────────────────────────────────
31
+ if (srcExists && !repoExists) {
32
+ console.log(chalk.bold.green(`+++ ${entry.repoRel}`) + chalk.gray(' (新增,仓库中不存在)'));
33
+ const lines = fs.readFileSync(entry.srcAbs, 'utf-8').split('\n');
34
+ lines.forEach(l => console.log(chalk.green(`+ ${l}`)));
35
+ console.log();
36
+ totalChanged++;
37
+ continue;
38
+ }
39
+ if (!srcExists && repoExists) {
40
+ console.log(chalk.bold.red(`--- ${entry.repoRel}`) + chalk.gray(' (本地缺失)'));
41
+ console.log();
42
+ totalChanged++;
43
+ continue;
44
+ }
45
+ if (!srcExists && !repoExists)
46
+ continue;
47
+ // ── 两侧均存在,读取内容 ──────────────────────────────────
48
+ const localText = fs.readFileSync(entry.srcAbs, 'utf-8');
49
+ let repoText;
50
+ if (entry.encrypt) {
51
+ try {
52
+ repoText = cryptoEngine.decryptString(fs.readFileSync(repoAbs, 'utf-8').trim(), keyPath);
53
+ }
54
+ catch {
55
+ console.log(chalk.yellow(`~ ${entry.repoRel}`) + chalk.gray(' [加密文件,无法解密比较]'));
56
+ console.log();
57
+ totalChanged++;
58
+ continue;
59
+ }
60
+ }
61
+ else {
62
+ repoText = fs.readFileSync(repoAbs, 'utf-8');
63
+ }
64
+ const diffLines = diffText(repoText, localText);
65
+ if (diffLines.length === 0)
66
+ continue; // 内容相同,跳过
67
+ const encLabel = entry.encrypt ? chalk.gray(' [enc]') : '';
68
+ console.log(chalk.bold(`~~~ ${entry.repoRel}`) + encLabel);
69
+ console.log(chalk.gray(' --- 仓库版本'));
70
+ console.log(chalk.gray(' +++ 本地版本'));
71
+ console.log();
72
+ for (const line of diffLines) {
73
+ if (line.content === '...') {
74
+ console.log(chalk.gray(' ...'));
75
+ }
76
+ else if (line.type === 'added') {
77
+ console.log(chalk.green(`+ ${line.content}`));
78
+ }
79
+ else if (line.type === 'removed') {
80
+ console.log(chalk.red(`- ${line.content}`));
81
+ }
82
+ else {
83
+ console.log(chalk.gray(` ${line.content}`));
84
+ }
85
+ }
86
+ console.log();
87
+ totalChanged++;
88
+ }
89
+ if (totalChanged === 0) {
90
+ logger.ok('所有文件与仓库一致,无差异');
91
+ }
92
+ else {
93
+ logger.info(`共 ${totalChanged} 个文件有差异`);
94
+ }
95
+ }
96
+ //# sourceMappingURL=diff.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diff.js","sourceRoot":"","sources":["../../../src/commands/diff.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * init.ts — wangchuan init 命令
3
+ */
4
+ import type { InitOptions, WangchuanConfig } from '../types.js';
5
+ export declare function cmdInit({ repo, force }: InitOptions): Promise<WangchuanConfig>;
6
+ //# sourceMappingURL=init.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../../src/commands/init.ts"],"names":[],"mappings":"AAAA;;GAEG;AAOH,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAGhE,wBAAsB,OAAO,CAAC,EAAE,IAAI,EAAE,KAAa,EAAE,EAAE,WAAW,GAAG,OAAO,CAAC,eAAe,CAAC,CA2C5F"}
@@ -0,0 +1,49 @@
1
+ /**
2
+ * init.ts — wangchuan init 命令
3
+ */
4
+ import { config } from '../core/config.js';
5
+ import { cryptoEngine } from '../core/crypto.js';
6
+ import { gitEngine } from '../core/git.js';
7
+ import { validator } from '../utils/validator.js';
8
+ import { logger } from '../utils/logger.js';
9
+ import ora from 'ora';
10
+ export async function cmdInit({ repo, force = false }) {
11
+ logger.banner('忘川初始化');
12
+ if (!validator.isGitUrl(repo)) {
13
+ throw new Error(`无效的 Git 地址: ${repo}`);
14
+ }
15
+ const existing = config.load();
16
+ if (existing !== null && !force) {
17
+ logger.warn(`忘川已初始化 (仓库: ${existing.repo})`);
18
+ logger.info('如需重新初始化,请使用 --force 参数');
19
+ return existing;
20
+ }
21
+ // ── 写配置 ──────────────────────────────────────────────────
22
+ let spinner = ora('写入配置 …').start();
23
+ const cfg = await config.initialize(repo);
24
+ spinner.succeed(`配置已写入: ${config.paths.config}`);
25
+ // ── 生成密钥 ────────────────────────────────────────────────
26
+ if (!cryptoEngine.hasKey(cfg.keyPath)) {
27
+ spinner = ora('生成 AES-256-GCM 主密钥 …').start();
28
+ cryptoEngine.generateKey(cfg.keyPath);
29
+ spinner.succeed(`主密钥已生成: ${cfg.keyPath}`);
30
+ }
31
+ else {
32
+ logger.info(`主密钥已存在,跳过生成: ${cfg.keyPath}`);
33
+ }
34
+ // ── 克隆/拉取仓库 ────────────────────────────────────────────
35
+ spinner = ora(`克隆仓库: ${repo} …`).start();
36
+ try {
37
+ await gitEngine.cloneOrFetch(repo, cfg.localRepoPath, cfg.branch);
38
+ spinner.succeed(`仓库已就绪: ${cfg.localRepoPath}`);
39
+ }
40
+ catch (err) {
41
+ spinner.fail('克隆仓库失败');
42
+ throw new Error(`Git 操作失败: ${err.message}`);
43
+ }
44
+ logger.ok('\n忘川初始化完成!');
45
+ logger.step('下一步: wangchuan pull (同步远端配置到本地)');
46
+ logger.step(' wangchuan push (推送本地配置到远端)');
47
+ return cfg;
48
+ }
49
+ //# sourceMappingURL=init.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../../../src/commands/init.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAY,mBAAmB,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,SAAS,EAAE,MAAS,gBAAgB,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAS,uBAAuB,CAAC;AACrD,OAAO,EAAE,MAAM,EAAE,MAAY,oBAAoB,CAAC;AAElD,OAAO,GAAG,MAAM,KAAK,CAAC;AAEtB,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,EAAE,IAAI,EAAE,KAAK,GAAG,KAAK,EAAe;IAChE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAEvB,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QAC9B,MAAM,IAAI,KAAK,CAAC,eAAe,IAAI,EAAE,CAAC,CAAC;IACzC,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC;IAC/B,IAAI,QAAQ,KAAK,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;QAChC,MAAM,CAAC,IAAI,CAAC,eAAe,QAAQ,CAAC,IAAI,GAAG,CAAC,CAAC;QAC7C,MAAM,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC;QACtC,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,4DAA4D;IAC5D,IAAI,OAAO,GAAG,GAAG,CAAC,QAAQ,CAAC,CAAC,KAAK,EAAE,CAAC;IACpC,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;IAC1C,OAAO,CAAC,OAAO,CAAC,UAAU,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;IAEjD,2DAA2D;IAC3D,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;QACtC,OAAO,GAAG,GAAG,CAAC,sBAAsB,CAAC,CAAC,KAAK,EAAE,CAAC;QAC9C,YAAY,CAAC,WAAW,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACtC,OAAO,CAAC,OAAO,CAAC,WAAW,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;IAC5C,CAAC;SAAM,CAAC;QACN,MAAM,CAAC,IAAI,CAAC,gBAAgB,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;IAC7C,CAAC;IAED,0DAA0D;IAC1D,OAAO,GAAG,GAAG,CAAC,SAAS,IAAI,IAAI,CAAC,CAAC,KAAK,EAAE,CAAC;IACzC,IAAI,CAAC;QACH,MAAM,SAAS,CAAC,YAAY,CAAC,IAAI,EAAE,GAAG,CAAC,aAAa,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;QAClE,OAAO,CAAC,OAAO,CAAC,UAAU,GAAG,CAAC,aAAa,EAAE,CAAC,CAAC;IACjD,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACvB,MAAM,IAAI,KAAK,CAAC,aAAc,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;IACzD,CAAC;IAED,MAAM,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC;IACxB,MAAM,CAAC,IAAI,CAAC,kCAAkC,CAAC,CAAC;IAChD,MAAM,CAAC,IAAI,CAAC,qCAAqC,CAAC,CAAC;IAEnD,OAAO,GAAG,CAAC;AACb,CAAC"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * list.ts — wangchuan list 命令
3
+ *
4
+ * 瞬间列出所有受管配置文件,不做任何 git/IO 操作。
5
+ * 支持 --agent 过滤,按智能体分组展示。
6
+ */
7
+ import type { ListOptions } from '../types.js';
8
+ export declare function cmdList({ agent }?: ListOptions): Promise<void>;
9
+ //# sourceMappingURL=list.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../../src/commands/list.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAOH,OAAO,KAAK,EAAE,WAAW,EAAa,MAAM,aAAa,CAAC;AAS1D,wBAAsB,OAAO,CAAC,EAAE,KAAK,EAAE,GAAE,WAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAoCxE"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * list.ts — wangchuan list 命令
3
+ *
4
+ * 瞬间列出所有受管配置文件,不做任何 git/IO 操作。
5
+ * 支持 --agent 过滤,按智能体分组展示。
6
+ */
7
+ import fs from 'fs';
8
+ import { config } from '../core/config.js';
9
+ import { syncEngine } from '../core/sync.js';
10
+ import { validator } from '../utils/validator.js';
11
+ import { logger } from '../utils/logger.js';
12
+ import chalk from 'chalk';
13
+ const AGENT_LABELS = {
14
+ openclaw: 'OpenClaw',
15
+ claude: 'Claude',
16
+ gemini: 'Gemini',
17
+ };
18
+ export async function cmdList({ agent } = {}) {
19
+ logger.banner('忘川 · 配置清单');
20
+ const cfg = config.load();
21
+ validator.requireInit(cfg);
22
+ const repoPath = syncEngine.expandHome(cfg.localRepoPath);
23
+ const allAgents = agent ? [agent] : ['openclaw', 'claude', 'gemini'];
24
+ let totalFiles = 0;
25
+ for (const ag of allAgents) {
26
+ const entries = syncEngine.buildFileEntries(cfg, undefined, ag);
27
+ if (entries.length === 0)
28
+ continue;
29
+ console.log(chalk.bold.cyan(` ▸ ${AGENT_LABELS[ag]}`));
30
+ for (const e of entries) {
31
+ const localExists = fs.existsSync(e.srcAbs);
32
+ const repoExists = fs.existsSync(`${repoPath}/${e.repoRel}`);
33
+ const localMark = localExists ? chalk.green('✔') : chalk.red('✖');
34
+ const repoMark = repoExists ? chalk.green('✔') : chalk.gray('·');
35
+ const encLabel = e.encrypt ? chalk.magenta('[enc]') : ' ';
36
+ console.log(` ${localMark} 本地 ${repoMark} 仓库 ${encLabel} ${chalk.white(e.repoRel)}`);
37
+ console.log(chalk.gray(` └─ ${e.srcAbs}`));
38
+ }
39
+ console.log();
40
+ totalFiles += entries.length;
41
+ }
42
+ console.log(chalk.gray(` 共 ${totalFiles} 个配置文件`));
43
+ console.log(chalk.gray(` ✔ = 存在 · = 仓库中尚无(未推送) [enc] = 加密存储`));
44
+ }
45
+ //# sourceMappingURL=list.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list.js","sourceRoot":"","sources":["../../../src/commands/list.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,EAAE,MAAM,EAAE,MAAU,mBAAmB,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,SAAS,EAAE,MAAO,uBAAuB,CAAC;AACnD,OAAO,EAAE,MAAM,EAAE,MAAU,oBAAoB,CAAC;AAEhD,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,MAAM,YAAY,GAA8B;IAC9C,QAAQ,EAAE,UAAU;IACpB,MAAM,EAAI,QAAQ;IAClB,MAAM,EAAI,QAAQ;CACnB,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,EAAE,KAAK,KAAkB,EAAE;IACvD,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;IAE3B,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC;IAC1B,SAAS,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IAE3B,MAAM,QAAQ,GAAG,UAAU,CAAC,UAAU,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;IAC1D,MAAM,SAAS,GAAgB,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;IAElF,IAAI,UAAU,GAAG,CAAC,CAAC;IAEnB,KAAK,MAAM,EAAE,IAAI,SAAS,EAAE,CAAC;QAC3B,MAAM,OAAO,GAAG,UAAU,CAAC,gBAAgB,CAAC,GAAG,EAAE,SAAS,EAAE,EAAE,CAAC,CAAC;QAChE,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;YAAE,SAAS;QAEnC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,YAAY,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QAExD,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;YACxB,MAAM,WAAW,GAAG,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;YAC5C,MAAM,UAAU,GAAI,EAAE,CAAC,UAAU,CAAC,GAAG,QAAQ,IAAI,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;YAE9D,MAAM,SAAS,GAAG,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YAClE,MAAM,QAAQ,GAAI,UAAU,CAAE,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACnE,MAAM,QAAQ,GAAI,CAAC,CAAC,OAAO,CAAG,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;YAEjE,OAAO,CAAC,GAAG,CACT,OAAO,SAAS,QAAQ,QAAQ,QAAQ,QAAQ,KAAK,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAC9E,CAAC;YACF,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QAC1D,CAAC;QACD,OAAO,CAAC,GAAG,EAAE,CAAC;QACd,UAAU,IAAI,OAAO,CAAC,MAAM,CAAC;IAC/B,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,UAAU,QAAQ,CAAC,CAAC,CAAC;IACnD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,wCAAwC,CAAC,CAAC,CAAC;AACpE,CAAC"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * pull.ts — wangchuan pull 命令
3
+ */
4
+ import type { PullOptions, RestoreResult } from '../types.js';
5
+ export declare function cmdPull({ agent }?: PullOptions): Promise<RestoreResult>;
6
+ //# sourceMappingURL=pull.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pull.d.ts","sourceRoot":"","sources":["../../../src/commands/pull.ts"],"names":[],"mappings":"AAAA;;GAEG;AAOH,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAI9D,wBAAsB,OAAO,CAAC,EAAE,KAAK,EAAE,GAAE,WAAgB,GAAG,OAAO,CAAC,aAAa,CAAC,CA8CjF"}