wangchuan 5.7.1 → 5.9.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 +83 -64
- package/README.zh-CN.md +82 -63
- package/dist/bin/wangchuan.js +1 -1
- package/dist/src/agents/claude.d.ts.map +1 -1
- package/dist/src/agents/claude.js +3 -0
- package/dist/src/agents/claude.js.map +1 -1
- package/dist/src/agents/codebuddy.d.ts.map +1 -1
- package/dist/src/agents/codebuddy.js +4 -0
- package/dist/src/agents/codebuddy.js.map +1 -1
- package/dist/src/agents/codex.d.ts.map +1 -1
- package/dist/src/agents/codex.js +3 -0
- package/dist/src/agents/codex.js.map +1 -1
- package/dist/src/agents/cursor.d.ts.map +1 -1
- package/dist/src/agents/cursor.js +4 -1
- package/dist/src/agents/cursor.js.map +1 -1
- package/dist/src/agents/gemini.js +1 -1
- package/dist/src/agents/gemini.js.map +1 -1
- package/dist/src/agents/openclaw.d.ts.map +1 -1
- package/dist/src/agents/openclaw.js +1 -0
- package/dist/src/agents/openclaw.js.map +1 -1
- package/dist/src/agents/workbuddy.d.ts.map +1 -1
- package/dist/src/agents/workbuddy.js +1 -0
- package/dist/src/agents/workbuddy.js.map +1 -1
- package/dist/src/commands/sync.d.ts.map +1 -1
- package/dist/src/commands/sync.js +16 -0
- package/dist/src/commands/sync.js.map +1 -1
- package/dist/src/commands/watch.d.ts +16 -4
- package/dist/src/commands/watch.d.ts.map +1 -1
- package/dist/src/commands/watch.js +85 -85
- package/dist/src/commands/watch.js.map +1 -1
- package/dist/src/core/sync.d.ts.map +1 -1
- package/dist/src/core/sync.js +13 -9
- package/dist/src/core/sync.js.map +1 -1
- package/dist/src/i18n.d.ts.map +1 -1
- package/dist/src/i18n.js +8 -10
- package/dist/src/i18n.js.map +1 -1
- package/package.json +1 -1
- package/skill/SKILL.md +84 -215
- package/skill/references/environment.md +198 -0
- package/skill/references/inspect-status.md +90 -0
- package/skill/references/install-setup.md +142 -0
- package/skill/references/resource-crud.md +153 -0
- package/skill/references/sync-conflict.md +69 -0
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
# Environment Management, Rollback, and Snapshots
|
|
2
|
+
|
|
3
|
+
## Environment basics
|
|
4
|
+
|
|
5
|
+
Environments map to git branches: `default` → `main`, `<name>` → `env/<name>`.
|
|
6
|
+
|
|
7
|
+
**Critical: isolation model.** Environments are **Git-branch-only isolation**. The local workspace (`~/.claude/`, `~/.cursor/`, etc.) is a **single shared copy** across all environments. Switching env = switch branch + overwrite local from new branch. But pull **never deletes** local files — files from the old env may remain as "leakage".
|
|
8
|
+
|
|
9
|
+
### Impact on all operations
|
|
10
|
+
|
|
11
|
+
| Operation | Environment behavior |
|
|
12
|
+
|-----------|---------------------|
|
|
13
|
+
| `sync` (push/pull) | Always targets current env's branch. Cannot push to or pull from another env. |
|
|
14
|
+
| `watch` | Pulls from current env only. After `env switch`, **must restart watch**. |
|
|
15
|
+
| Skill/agent/MCP CRUD | Changes apply to local workspace, pushed to current env's branch on sync. |
|
|
16
|
+
| `memory copy/broadcast` | Operates on local workspace files (shared). Pushed to current env on sync. |
|
|
17
|
+
| After `env switch` | Old env's local files may linger. Check `wangchuan status -v` for `localOnly` files before pushing — do NOT blindly push stale files to the new env. |
|
|
18
|
+
| Pull from another env | Must `env switch <target>` first. No `--from-env` flag exists. |
|
|
19
|
+
|
|
20
|
+
## Listing environments (指令 26)
|
|
21
|
+
|
|
22
|
+
When user says "查看忘川环境列表" / "list environments":
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
# List all environments
|
|
26
|
+
wangchuan env list
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
For per-environment health, iterate branches and check sync metadata:
|
|
30
|
+
```bash
|
|
31
|
+
# For each environment, check active machines and health
|
|
32
|
+
cd ~/.wangchuan/repo
|
|
33
|
+
for branch in $(git branch -r --list 'origin/env/*' | sed 's|origin/||'); do
|
|
34
|
+
env_name=$(echo "$branch" | sed 's|env/||')
|
|
35
|
+
echo "=== Environment: $env_name ==="
|
|
36
|
+
# Count active machines from recent commits on that branch
|
|
37
|
+
git log "origin/$branch" --oneline -20 --format="%s" | grep -oP '\[([^\]]+)\]$' | sort -u | wc -l | xargs -I{} echo " Active machines: {}"
|
|
38
|
+
# Check last sync time
|
|
39
|
+
git log "origin/$branch" --oneline -1 --format="%ci" | xargs -I{} echo " Last sync: {}"
|
|
40
|
+
done
|
|
41
|
+
# Also check default branch
|
|
42
|
+
echo "=== Environment: default ==="
|
|
43
|
+
git log origin/main --oneline -20 --format="%s" | grep -oP '\[([^\]]+)\]$' | sort -u | wc -l | xargs -I{} echo " Active machines: {}"
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
For detailed health of a specific environment, switch to it and run `wangchuan status -v` (see inspect-status.md).
|
|
47
|
+
|
|
48
|
+
## Current environment (指令 27)
|
|
49
|
+
|
|
50
|
+
When user says "看下忘川当前环境" / "which environment am I in":
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
wangchuan env current
|
|
54
|
+
wangchuan status -v
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Report: environment name, active machines count, health score, unsynced files, anomalies.
|
|
58
|
+
|
|
59
|
+
## Creating a new environment (指令 28)
|
|
60
|
+
|
|
61
|
+
When user says "新建忘川 xxx 环境" / "create xxx environment":
|
|
62
|
+
|
|
63
|
+
**Step 1: Check if environment already exists.**
|
|
64
|
+
```bash
|
|
65
|
+
wangchuan env list
|
|
66
|
+
```
|
|
67
|
+
If the name already exists, inform the user and ask: "Environment 'xxx' already exists. Switch to it instead?"
|
|
68
|
+
|
|
69
|
+
**Step 2: Ask about data initialization.**
|
|
70
|
+
Ask the user which option they prefer:
|
|
71
|
+
- **Fork current environment** (recommended for most cases) — the new env starts with a complete copy of the current env's memories, skills, MCP, agents, and configs. This is the default.
|
|
72
|
+
- **Start empty** — the new env starts with no data. Note: `env create` in non-TTY mode auto-forks; to create a truly empty env, the agent must create the branch manually and make an empty initial commit.
|
|
73
|
+
|
|
74
|
+
**Step 3: Create.**
|
|
75
|
+
```bash
|
|
76
|
+
# Fork current env (default, works in non-TTY):
|
|
77
|
+
wangchuan env create <name>
|
|
78
|
+
|
|
79
|
+
# To create from a specific existing env instead of current:
|
|
80
|
+
wangchuan env switch <source-env> # switch to source first
|
|
81
|
+
wangchuan env create <name> # fork from it
|
|
82
|
+
wangchuan env switch <name> # switch to the new env
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
**Step 4: Confirm and report.**
|
|
86
|
+
After creation, the user is still on the **original** environment. Ask if they want to switch to the new one:
|
|
87
|
+
```bash
|
|
88
|
+
wangchuan env switch <name>
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
`env create` in non-TTY mode auto-forks with memories (no interactive prompt needed). To create an empty environment, there is no flag — the fork behavior is the default. If user explicitly wants empty, agent would need to create the branch manually.
|
|
92
|
+
|
|
93
|
+
## Deleting an environment (指令 29)
|
|
94
|
+
|
|
95
|
+
When user says "删除忘川 xxx 环境" / "delete xxx environment":
|
|
96
|
+
|
|
97
|
+
**Step 1: Confirm with user.**
|
|
98
|
+
Ask: "Are you sure you want to delete environment 'xxx'? This removes the cloud branch and all its history."
|
|
99
|
+
|
|
100
|
+
**Step 2: Check constraints.**
|
|
101
|
+
- Cannot delete `default` environment
|
|
102
|
+
- Cannot delete the currently active environment (must switch first)
|
|
103
|
+
|
|
104
|
+
**Step 3: Execute.**
|
|
105
|
+
```bash
|
|
106
|
+
wangchuan env delete <name>
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
**Important**: `env delete` only removes the git branch. Local workspace files are NOT affected — they belong to whatever environment is currently active. Cloud data for that environment is permanently gone.
|
|
110
|
+
|
|
111
|
+
## Switching environments
|
|
112
|
+
|
|
113
|
+
When user says "切换到 xxx 环境" / "switch to work environment":
|
|
114
|
+
|
|
115
|
+
**Step 1: Check for unsynced local changes BEFORE switching.**
|
|
116
|
+
```bash
|
|
117
|
+
wangchuan status
|
|
118
|
+
```
|
|
119
|
+
- **Few changes (≤3 files)**: warn briefly, push first: `wangchuan sync -y`
|
|
120
|
+
- **Many changes or conflicts**: `wangchuan status -v` → show diff → ask "Push current changes first, or discard and switch?"
|
|
121
|
+
|
|
122
|
+
**Step 2: Switch.**
|
|
123
|
+
```bash
|
|
124
|
+
wangchuan env switch <name>
|
|
125
|
+
```
|
|
126
|
+
Auto-switches branch, updates config, runs sync to pull target env's data.
|
|
127
|
+
|
|
128
|
+
**Step 3: Post-switch checks.**
|
|
129
|
+
|
|
130
|
+
Check for conflict markers:
|
|
131
|
+
```bash
|
|
132
|
+
grep -rl '<<<<<<< LOCAL' ~/.claude/ ~/.openclaw/workspace/ ~/.codebuddy/ ~/.workbuddy/ ~/.codex/ 2>/dev/null
|
|
133
|
+
```
|
|
134
|
+
- No conflicts → success
|
|
135
|
+
- Conflicts → show to user, resolve
|
|
136
|
+
|
|
137
|
+
Check for stale files from previous env (workspace leakage):
|
|
138
|
+
```bash
|
|
139
|
+
wangchuan status -v # look for "localOnly" files — these are from the old env
|
|
140
|
+
```
|
|
141
|
+
Warn user: "These files exist locally but not in the new environment. Do NOT push them unless you intentionally want to bring them into this env."
|
|
142
|
+
|
|
143
|
+
**Step 4: Restart watch daemon** (watch only pulls from current env's branch):
|
|
144
|
+
```bash
|
|
145
|
+
pkill -f 'wangchuan.*watch' 2>/dev/null; nohup wangchuan watch >/dev/null 2>&1 &
|
|
146
|
+
```
|
|
147
|
+
Watch mode **only pulls** cloud changes — it does NOT push local changes. Users must run `wangchuan sync` manually to push. If watch encounters a conflict it cannot auto-merge, it records it to `~/.wangchuan/pending-conflicts.json` — the next `wangchuan sync` will display these conflicts for user resolution.
|
|
148
|
+
|
|
149
|
+
**Step 5: If user asked "pull memory from env X" without switching:**
|
|
150
|
+
Explain that cross-env pull is not supported — must switch first:
|
|
151
|
+
```bash
|
|
152
|
+
wangchuan env switch <target-env> # switch → auto-pulls target env's data
|
|
153
|
+
# After done, switch back:
|
|
154
|
+
wangchuan env switch <original-env>
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
## Rolling back (snapshots and git history)
|
|
158
|
+
|
|
159
|
+
When user says "回退记忆" / "rollback" / "restore a previous version":
|
|
160
|
+
|
|
161
|
+
**Step 1: Identify target.** Ask user's intent:
|
|
162
|
+
- **Undo last sync** → find auto-snapshot
|
|
163
|
+
- **Specific time** → `wangchuan snapshot list`
|
|
164
|
+
- **Recover deleted file** → `cd ~/.wangchuan/repo && git log --oneline --name-status -20`
|
|
165
|
+
- **Revert specific change** → `git log` + `git show <hash> --stat`
|
|
166
|
+
|
|
167
|
+
**Step 2: Find version.**
|
|
168
|
+
|
|
169
|
+
Option A — Snapshot:
|
|
170
|
+
```bash
|
|
171
|
+
wangchuan snapshot list
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
Option B — Git history:
|
|
175
|
+
```bash
|
|
176
|
+
cd ~/.wangchuan/repo && git log --oneline --name-status -20
|
|
177
|
+
cd ~/.wangchuan/repo && git show <hash> --stat
|
|
178
|
+
cd ~/.wangchuan/repo && git show <hash>:<file-path>
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
**Step 3: Execute.**
|
|
182
|
+
|
|
183
|
+
Snapshot restore (auto-pushes to cloud):
|
|
184
|
+
```bash
|
|
185
|
+
wangchuan snapshot restore <name>
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
Single file from git (needs sync after):
|
|
189
|
+
```bash
|
|
190
|
+
cd ~/.wangchuan/repo && git checkout <hash> -- <file-path>
|
|
191
|
+
wangchuan sync -y
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
Undo last sync:
|
|
195
|
+
```bash
|
|
196
|
+
wangchuan snapshot list # find pre-sync auto-snapshot (second most recent)
|
|
197
|
+
wangchuan snapshot restore <pre-sync-snapshot>
|
|
198
|
+
```
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# Inspecting Resources and Status
|
|
2
|
+
|
|
3
|
+
## Inspecting a skill
|
|
4
|
+
|
|
5
|
+
Report three things:
|
|
6
|
+
```bash
|
|
7
|
+
# 1. Which agents have it:
|
|
8
|
+
for entry in $(jq -r '.profiles.default | to_entries[] | select(.value.enabled) | "\(.key)=\(.value.workspacePath)"' ~/.wangchuan/config.json); do
|
|
9
|
+
agent="${entry%%=*}"; wspath="${entry#*=}"
|
|
10
|
+
expanded=$(echo "$wspath" | sed "s|^~|$HOME|")
|
|
11
|
+
[ -d "${expanded}/skills/xxx" ] && echo " ✓ $agent" || echo " ✗ $agent"
|
|
12
|
+
done
|
|
13
|
+
# 2. Shared or local:
|
|
14
|
+
cat ~/.wangchuan/shared-registry.json 2>/dev/null | grep -q '"name":"xxx".*"kind":"skill"' && echo "SHARED" || echo "LOCAL"
|
|
15
|
+
# 3. Cloud sync:
|
|
16
|
+
[ -d ~/.wangchuan/repo/shared/skills/xxx ] && echo "Synced to cloud" || echo "Not in cloud"
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Inspecting a custom agent
|
|
20
|
+
|
|
21
|
+
Same pattern, but only Claude, Cursor, CodeBuddy, WorkBuddy support custom agents.
|
|
22
|
+
```bash
|
|
23
|
+
for a in claude cursor codebuddy workbuddy; do
|
|
24
|
+
wspath=$(jq -r ".profiles.default.${a}.workspacePath" ~/.wangchuan/config.json)
|
|
25
|
+
expanded=$(echo "$wspath" | sed "s|^~|$HOME|")
|
|
26
|
+
[ -d "${expanded}/agents/xxx" ] && echo " ✓ $a" || echo " ✗ $a"
|
|
27
|
+
done
|
|
28
|
+
cat ~/.wangchuan/shared-registry.json 2>/dev/null | grep -q '"name":"xxx".*"kind":"agent"' && echo "SHARED" || echo "LOCAL"
|
|
29
|
+
[ -d ~/.wangchuan/repo/shared/agents/xxx ] && echo "Synced to cloud" || echo "Not in cloud"
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Inspecting MCP servers
|
|
33
|
+
|
|
34
|
+
MCP configs are JSON fields. Agents with MCP: Claude, OpenClaw, CodeBuddy, WorkBuddy, Cursor.
|
|
35
|
+
```bash
|
|
36
|
+
# List servers per agent:
|
|
37
|
+
jq -r '.mcpServers // {} | keys[]' ~/.claude/.claude.json 2>/dev/null | sed 's/^/ claude: /'
|
|
38
|
+
jq -r '.mcpServers // {} | keys[]' ~/.codebuddy/mcp.json 2>/dev/null | sed 's/^/ codebuddy: /'
|
|
39
|
+
# (repeat for workbuddy, cursor with mcp.json; openclaw with config/mcporter.json)
|
|
40
|
+
```
|
|
41
|
+
MCP has **no shared registry** — it uses a single merged file in the cloud (`shared/mcp/mcpServers.json.enc`). On each sync, all agents' MCP servers are merged into one superset and distributed to all agents locally. Report which agents have a given server, compare config values.
|
|
42
|
+
|
|
43
|
+
## Inspecting memory
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
# 1. List all agents' memory files:
|
|
47
|
+
wangchuan memory list
|
|
48
|
+
# 2. Show specific agent's memory:
|
|
49
|
+
wangchuan memory show <agent>
|
|
50
|
+
# 3. Shared memory status:
|
|
51
|
+
expanded=$(echo "~/.openclaw/workspace/memory/SHARED.md" | sed "s|^~|$HOME|")
|
|
52
|
+
[ -f "$expanded" ] && echo "✓ Shared memory exists" || echo "✗ No shared memory"
|
|
53
|
+
[ -f ~/.wangchuan/repo/shared/memory/SHARED.md.enc ] && echo "✓ Synced to cloud" || echo "✗ Not in cloud"
|
|
54
|
+
# 4. Per-agent cloud sync:
|
|
55
|
+
for a in openclaw codebuddy workbuddy codex; do
|
|
56
|
+
[ -f ~/.wangchuan/repo/agents/${a}/MEMORY.md.enc ] && echo " ✓ $a synced" || echo " ✗ $a not synced"
|
|
57
|
+
done
|
|
58
|
+
[ -f ~/.wangchuan/repo/agents/claude/CLAUDE.md ] && echo " ✓ claude synced" || echo " ✗ claude not synced"
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Status diagnostic (wangchuan status)
|
|
62
|
+
|
|
63
|
+
### Compact view: `wangchuan status`
|
|
64
|
+
- Health score (0–100), 4 dimensions: freshness / coverage / integrity / encryption
|
|
65
|
+
- Current environment and branch
|
|
66
|
+
- Changed files count (+added, ~modified, -missing)
|
|
67
|
+
- Last sync timestamp, pending actions
|
|
68
|
+
|
|
69
|
+
### Verbose view: `wangchuan status -v`
|
|
70
|
+
All of compact, plus:
|
|
71
|
+
- 4 health sub-scores with explanations
|
|
72
|
+
- File inventory per-agent (local ✔/✖, repo ✔/·, [enc], [field])
|
|
73
|
+
- Line-level diff per modified file
|
|
74
|
+
- Active machines (from git commit `[hostname]`)
|
|
75
|
+
- Recent 3 git commits
|
|
76
|
+
- Sync history (last 5 events)
|
|
77
|
+
- Conflict detection (local+remote both changed)
|
|
78
|
+
- Sync lock warnings
|
|
79
|
+
|
|
80
|
+
### Interpreting health issues
|
|
81
|
+
|
|
82
|
+
| Symptom | Meaning | Fix |
|
|
83
|
+
|---------|---------|-----|
|
|
84
|
+
| Freshness low | Haven't synced recently | `wangchuan sync -y` |
|
|
85
|
+
| Coverage low | Local files missing | `wangchuan sync -y` (pull restores) |
|
|
86
|
+
| Integrity low | Checksums mismatch | `wangchuan doctor` |
|
|
87
|
+
| Encryption low | Sensitive files unencrypted | Review config profiles |
|
|
88
|
+
| Conflict warning | Local+remote both changed | `wangchuan sync -y` → resolve markers |
|
|
89
|
+
| Stale sync lock | Previous sync crashed | `wangchuan doctor` |
|
|
90
|
+
| Pending distributions | Unprocessed sharing | `wangchuan sync -y` |
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
# Installation, Initialization, and Key Management
|
|
2
|
+
|
|
3
|
+
## Prerequisites
|
|
4
|
+
|
|
5
|
+
1. Node.js >= 18
|
|
6
|
+
2. Git installed and configured (SSH key or HTTPS credentials)
|
|
7
|
+
3. A **private** Git repo on any hosting platform
|
|
8
|
+
|
|
9
|
+
## Install CLI
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm install -g wangchuan
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Initialization (when `~/.wangchuan/config.json` does not exist)
|
|
16
|
+
|
|
17
|
+
**IMPORTANT: Interactive mode does NOT work in agent shell (non-TTY). Always pass flags explicitly.**
|
|
18
|
+
|
|
19
|
+
Ask user: brand new setup or restoring existing repo?
|
|
20
|
+
|
|
21
|
+
### Scenario A — Brand new setup
|
|
22
|
+
|
|
23
|
+
1. Guide user to create a **private** repo (or auto-create via `gh repo create wangchuan-sync --private`)
|
|
24
|
+
2. Run: `wangchuan init --repo <url>`
|
|
25
|
+
3. Auto: generates key → clones → detects agents → extracts shared resources → first sync
|
|
26
|
+
4. **Remind user to back up key**: `wangchuan doctor --key-export`
|
|
27
|
+
|
|
28
|
+
### Scenario B — Restore / new machine (may already have local agent data)
|
|
29
|
+
|
|
30
|
+
This is a multi-step flow with a **mandatory backup checkpoint**. If the user doesn't confirm backup, **stop and do not proceed** — next time the skill is triggered, start from Step 1 again.
|
|
31
|
+
|
|
32
|
+
**Step 1: Collect credentials.**
|
|
33
|
+
Ask for **repo SSH URL** and **master key** (`wangchuan_<hex>`).
|
|
34
|
+
|
|
35
|
+
**Step 2: Init (clone only, no sync yet).**
|
|
36
|
+
```bash
|
|
37
|
+
wangchuan init --repo <url> --key <key>
|
|
38
|
+
```
|
|
39
|
+
Init clones the repo and auto-runs a first sync. But BEFORE that happens, the agent must handle Steps 3-5 manually. Since init auto-syncs, the agent should instead do a **manual init sequence** to control the flow:
|
|
40
|
+
|
|
41
|
+
Actually, `wangchuan init` auto-syncs at the end and there's no flag to skip it. So the agent must do the backup warning BEFORE running init:
|
|
42
|
+
|
|
43
|
+
**Step 3: Check if local agent data exists and warn about shared resource overwrites.**
|
|
44
|
+
```bash
|
|
45
|
+
# Check if any agent workspace has data
|
|
46
|
+
for agent_dir in ~/.claude ~/.cursor ~/.openclaw/workspace ~/.codebuddy ~/.workbuddy ~/.codex ~/.gemini; do
|
|
47
|
+
[ -d "$agent_dir" ] && echo " ⚠️ Local data found: $agent_dir"
|
|
48
|
+
done
|
|
49
|
+
```
|
|
50
|
+
If local data exists, **inform the user**:
|
|
51
|
+
- "⚠️ **Shared skills and custom agents in the cloud will OVERWRITE your local versions** (no merge — direct copy)."
|
|
52
|
+
- "Your MCP servers will be safely merged (additive)."
|
|
53
|
+
- "Your memory files (CLAUDE.md, MEMORY.md) will be preserved (local wins on conflict)."
|
|
54
|
+
- "Your local-only files (skills, configs not in cloud) will be auto-pushed to cloud — please review after init."
|
|
55
|
+
|
|
56
|
+
**Ask user: "Have you backed up your important local skills/agents? Confirm to proceed, or cancel to back up first."**
|
|
57
|
+
|
|
58
|
+
If user says **cancel/not yet** → **STOP**. Do NOT run init. Tell user:
|
|
59
|
+
```
|
|
60
|
+
Please back up your local data first:
|
|
61
|
+
cp -r ~/.claude/skills/ ~/backup-claude-skills/
|
|
62
|
+
cp -r ~/.claude/agents/ ~/backup-claude-agents/
|
|
63
|
+
# (repeat for other agents as needed)
|
|
64
|
+
Then say "初始化忘川" again to resume.
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
If user says **confirmed** → proceed to Step 4.
|
|
68
|
+
|
|
69
|
+
**Step 4: Check cloud environments and let user choose.**
|
|
70
|
+
After init, check if cloud repo has multiple environments:
|
|
71
|
+
```bash
|
|
72
|
+
# Init first (this will clone + auto-sync to default branch)
|
|
73
|
+
wangchuan init --repo <url> --key <key>
|
|
74
|
+
# Then check for environments
|
|
75
|
+
wangchuan env list
|
|
76
|
+
```
|
|
77
|
+
If multiple environments exist (e.g. `default`, `work`, `personal`):
|
|
78
|
+
- List all environments to the user
|
|
79
|
+
- Ask: "Which environment do you want to sync with this machine?"
|
|
80
|
+
- If user picks non-default → `wangchuan env switch <chosen>` (auto-pulls that env's data)
|
|
81
|
+
|
|
82
|
+
If only `default` exists → no need to ask, already synced.
|
|
83
|
+
|
|
84
|
+
**Step 5: Post-init review.**
|
|
85
|
+
```bash
|
|
86
|
+
wangchuan status -v
|
|
87
|
+
```
|
|
88
|
+
Report what was synced: pulled files, pushed files, any conflicts detected. If shared skills were overwritten, inform user which ones.
|
|
89
|
+
|
|
90
|
+
**Complete flow summary:**
|
|
91
|
+
```
|
|
92
|
+
Ask credentials → Check local data exists?
|
|
93
|
+
→ Yes: warn overwrites → ask backup confirmed?
|
|
94
|
+
→ No: STOP (resume next time)
|
|
95
|
+
→ Yes: init → check envs → user picks env → status -v → ensure watch
|
|
96
|
+
→ No: init → check envs → user picks env → ensure watch
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
## Key management
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
# Export key (on source machine):
|
|
103
|
+
wangchuan doctor --key-export # prints wangchuan_<hex>
|
|
104
|
+
# Import key (on target machine):
|
|
105
|
+
wangchuan init --repo <url> --key wangchuan_<hex>
|
|
106
|
+
# Rotate key:
|
|
107
|
+
wangchuan doctor --key-rotate
|
|
108
|
+
# Generate setup one-liner for new machine:
|
|
109
|
+
wangchuan doctor --setup
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
**`master.key` is the ONLY thing that cannot be recovered.** Back it up securely.
|
|
113
|
+
|
|
114
|
+
## Key mismatch handling
|
|
115
|
+
|
|
116
|
+
If `Key mismatch!` appears during sync:
|
|
117
|
+
1. `wangchuan doctor --key-export` on the machine that last pushed
|
|
118
|
+
2. Copy key hex to current machine
|
|
119
|
+
3. `wangchuan init --key <hex>` or write to `~/.wangchuan/master.key`
|
|
120
|
+
|
|
121
|
+
## Installing the skill to agents
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
# Claude
|
|
125
|
+
cp -r wangchuan/ ~/.claude/skills/wangchuan/
|
|
126
|
+
# OpenClaw
|
|
127
|
+
cp -r wangchuan/ ~/.openclaw/workspace/skills/wangchuan/
|
|
128
|
+
# Codex
|
|
129
|
+
cp -r wangchuan/ ~/.codex/skills/wangchuan/
|
|
130
|
+
# Or let sync distribute automatically:
|
|
131
|
+
wangchuan sync
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
## Setting up Git repo
|
|
135
|
+
|
|
136
|
+
| Platform | How |
|
|
137
|
+
|----------|-----|
|
|
138
|
+
| GitHub | `wangchuan init` auto-creates via `gh` CLI |
|
|
139
|
+
| GitLab | gitlab.com → New project → Private |
|
|
140
|
+
| Gitee | gitee.com → New repo → Private |
|
|
141
|
+
| Bitbucket | bitbucket.org → Create repository → Private |
|
|
142
|
+
| Gitea | Your instance → New Repository → Private |
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
# Resource CRUD — Skills, Custom Agents, MCP, Memory
|
|
2
|
+
|
|
3
|
+
## Resource types and their mechanisms
|
|
4
|
+
|
|
5
|
+
| Resource | Local path | Sharing model | Registry | Applicable agents |
|
|
6
|
+
|----------|-----------|---------------|----------|-------------------|
|
|
7
|
+
| **Skills** | `<workspace>/skills/<name>/` | Directory copy, shared-registry | `kind:'skill'` | OpenClaw, Claude, CodeBuddy, WorkBuddy, Gemini (5) |
|
|
8
|
+
| **Custom agents** | `<workspace>/agents/<name>/` | Directory copy, shared-registry | `kind:'agent'` | Claude, Cursor, CodeBuddy, WorkBuddy (4) |
|
|
9
|
+
| **MCP servers** | JSON field `mcpServers` in config file | JSON key merge, single shared file in cloud | None (auto) | Claude (`.claude.json`), OpenClaw (`config/mcporter.json`), CodeBuddy/WorkBuddy/Cursor (`mcp.json`) (5) |
|
|
10
|
+
| **Memory** | `<workspace>/MEMORY.md` etc. | Per-agent file, manual copy/broadcast | None | OpenClaw/CodeBuddy/WorkBuddy/Codex (`MEMORY.md`); Claude (`CLAUDE.md`); shared (`SHARED.md`) |
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## Creating or modifying skills or custom agents
|
|
15
|
+
|
|
16
|
+
Skills and custom agents use the **same** flow — both are directories tracked by `shared-registry.json`.
|
|
17
|
+
|
|
18
|
+
**`shared-registry.json` schema** (at `~/.wangchuan/shared-registry.json`):
|
|
19
|
+
```json
|
|
20
|
+
{
|
|
21
|
+
"entries": [
|
|
22
|
+
{ "name": "wangchuan", "kind": "skill", "sourceAgent": "claude", "sharedAt": "2026-04-14T10:00:00Z" },
|
|
23
|
+
{ "name": "my-reviewer", "kind": "agent", "sourceAgent": "claude", "sharedAt": "2026-04-14T11:00:00Z" }
|
|
24
|
+
]
|
|
25
|
+
}
|
|
26
|
+
```
|
|
27
|
+
- `kind`: `"skill"` or `"agent"` — determines which resource type
|
|
28
|
+
- `name`: directory name (e.g. skill dir name or custom agent dir name)
|
|
29
|
+
- `sourceAgent`: which agent first shared it
|
|
30
|
+
- A resource is **shared** only if it has an entry here. Absent = local-only.
|
|
31
|
+
|
|
32
|
+
**Step 1: Determine if the resource is already shared.**
|
|
33
|
+
- **Newly created** → NOT shared (skip to Step 2b).
|
|
34
|
+
- **Existing** → check `~/.wangchuan/shared-registry.json` for the name with `kind:'skill'` or `kind:'agent'`.
|
|
35
|
+
|
|
36
|
+
**Step 2a: Already-shared** — distribute + sync automatically:
|
|
37
|
+
```bash
|
|
38
|
+
# Example: shared skill "foo" modified in claude, also used by cursor and codebuddy
|
|
39
|
+
cp -r ~/.claude/skills/foo/ ~/.cursor/skills/foo/
|
|
40
|
+
cp -r ~/.claude/skills/foo/ ~/.codebuddy/skills/foo/
|
|
41
|
+
# Example: shared custom agent "my-reviewer" modified in claude
|
|
42
|
+
cp -r ~/.claude/agents/my-reviewer/ ~/.cursor/agents/my-reviewer/
|
|
43
|
+
cp -r ~/.claude/agents/my-reviewer/ ~/.codebuddy/agents/my-reviewer/
|
|
44
|
+
wangchuan sync -y
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
**Step 2b: New / agent-local** — ask the user before distributing:
|
|
48
|
+
```bash
|
|
49
|
+
# List enabled agents for skills:
|
|
50
|
+
jq -r '.profiles.default | to_entries[] | select(.value.enabled) | "\(.key) → \(.value.workspacePath)/skills/"' ~/.wangchuan/config.json
|
|
51
|
+
# List enabled agents for custom agents (only 4 support them):
|
|
52
|
+
for a in claude cursor codebuddy workbuddy; do
|
|
53
|
+
jq -r --arg a "$a" '.profiles.default[$a] | select(.enabled) | "\($a) → \(.workspacePath)/agents/"' ~/.wangchuan/config.json
|
|
54
|
+
done
|
|
55
|
+
```
|
|
56
|
+
Present options:
|
|
57
|
+
- **All agents** — copy to every applicable agent's dir → `wangchuan sync -y` (registers as shared)
|
|
58
|
+
- **Specific agents** — copy only to selected → `wangchuan sync -y`
|
|
59
|
+
- **No distribution** — keep local only → `wangchuan sync -y`
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
## Deleting skills or custom agents
|
|
64
|
+
|
|
65
|
+
Deletion is destructive — **always ask the user** regardless of shared status.
|
|
66
|
+
|
|
67
|
+
**Step 1: Determine shared status and inform the user.**
|
|
68
|
+
```bash
|
|
69
|
+
# For skills:
|
|
70
|
+
cat ~/.wangchuan/shared-registry.json 2>/dev/null | grep -q '"name":"xxx".*"kind":"skill"' && echo "SHARED SKILL" || echo "LOCAL SKILL"
|
|
71
|
+
# For custom agents:
|
|
72
|
+
cat ~/.wangchuan/shared-registry.json 2>/dev/null | grep -q '"name":"xxx".*"kind":"agent"' && echo "SHARED AGENT" || echo "LOCAL AGENT"
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
**Step 2: List agents that have it and ask which to remove from.**
|
|
76
|
+
```bash
|
|
77
|
+
# For skills:
|
|
78
|
+
for entry in $(jq -r '.profiles.default | to_entries[] | select(.value.enabled) | "\(.key)=\(.value.workspacePath)"' ~/.wangchuan/config.json); do
|
|
79
|
+
agent="${entry%%=*}"; expanded=$(echo "${entry#*=}" | sed "s|^~|$HOME|")
|
|
80
|
+
[ -d "${expanded}/skills/xxx" ] && echo " ✓ $agent"
|
|
81
|
+
done
|
|
82
|
+
# For custom agents (only 4 agents support them):
|
|
83
|
+
for a in claude cursor codebuddy workbuddy; do
|
|
84
|
+
wspath=$(jq -r ".profiles.default.${a}.workspacePath" ~/.wangchuan/config.json)
|
|
85
|
+
expanded=$(echo "$wspath" | sed "s|^~|$HOME|")
|
|
86
|
+
[ -d "${expanded}/agents/xxx" ] && echo " ✓ $a"
|
|
87
|
+
done
|
|
88
|
+
```
|
|
89
|
+
Options: **All agents** / **[individual agents]** / **Cancel**
|
|
90
|
+
|
|
91
|
+
**Step 3: Execute.**
|
|
92
|
+
|
|
93
|
+
**All agents**: `rm -rf` from every agent → unregister from shared-registry.json → `wangchuan sync -y`.
|
|
94
|
+
```bash
|
|
95
|
+
rm -rf ~/.claude/skills/xxx/ ~/.cursor/skills/xxx/ ~/.codebuddy/skills/xxx/ # etc.
|
|
96
|
+
jq '.entries |= map(select(.name != "xxx" or .kind != "skill"))' ~/.wangchuan/shared-registry.json > /tmp/wc-sr.json && mv /tmp/wc-sr.json ~/.wangchuan/shared-registry.json
|
|
97
|
+
wangchuan sync -y
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
**Specific agents**: `rm -rf` from selected → unregister (demote) → `wangchuan sync -y`. Remaining agents keep local copies.
|
|
101
|
+
|
|
102
|
+
**Cancel**: no action.
|
|
103
|
+
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
## Creating, modifying, or deleting MCP servers
|
|
107
|
+
|
|
108
|
+
MCP servers are JSON fields (`mcpServers`). They have **no shared registry** — wangchuan auto-merges on sync. But agent should give user control.
|
|
109
|
+
|
|
110
|
+
**Creating or modifying:**
|
|
111
|
+
1. Edit the current agent's MCP config file:
|
|
112
|
+
- Claude: `~/.claude/.claude.json` → `mcpServers`
|
|
113
|
+
- CodeBuddy/WorkBuddy/Cursor: `~/<workspace>/mcp.json` → `mcpServers`
|
|
114
|
+
- OpenClaw: `~/.openclaw/workspace/config/mcporter.json` → `mcpServers`
|
|
115
|
+
2. Ask user: "Sync this MCP server to other agents?"
|
|
116
|
+
- **All**: write same entry to every MCP-enabled agent's config via jq
|
|
117
|
+
- **Specific**: write to selected only
|
|
118
|
+
- **No**: keep local
|
|
119
|
+
3. `wangchuan sync -y`
|
|
120
|
+
|
|
121
|
+
Example — add server to another agent:
|
|
122
|
+
```bash
|
|
123
|
+
SERVER_JSON=$(jq '.mcpServers["my-db"]' ~/.claude/.claude.json)
|
|
124
|
+
jq --argjson srv "$SERVER_JSON" '.mcpServers["my-db"] = $srv' ~/.codebuddy/mcp.json > /tmp/mcp.json && mv /tmp/mcp.json ~/.codebuddy/mcp.json
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
**Deleting:**
|
|
128
|
+
1. List which agents have it: `jq -e '.mcpServers["xxx"]' <file>` per agent
|
|
129
|
+
2. Ask user: All / Specific / Cancel
|
|
130
|
+
3. Remove via `jq 'del(.mcpServers["xxx"])'` from selected agents
|
|
131
|
+
4. `wangchuan sync -y`
|
|
132
|
+
|
|
133
|
+
**Note**: wangchuan's MCP auto-merge is **additive only** (never deletes keys). Agent-side `jq del()` is the only way to propagate removal.
|
|
134
|
+
|
|
135
|
+
---
|
|
136
|
+
|
|
137
|
+
## Creating, modifying, or deleting memory
|
|
138
|
+
|
|
139
|
+
Memory files are **per-agent** — no automatic cross-agent distribution.
|
|
140
|
+
|
|
141
|
+
**Creating or modifying:**
|
|
142
|
+
1. Write/update memory file (e.g. `~/.claude/CLAUDE.md`)
|
|
143
|
+
2. Ask user: "Sync to other agents?"
|
|
144
|
+
- **All**: `wangchuan memory broadcast <agent>` → `wangchuan sync -y`
|
|
145
|
+
- **Specific**: `wangchuan memory copy <source> <target>` → `wangchuan sync -y`
|
|
146
|
+
- **No**: `wangchuan sync -y`
|
|
147
|
+
|
|
148
|
+
**Deleting:**
|
|
149
|
+
1. `wangchuan memory list` to see who has what
|
|
150
|
+
2. Ask user: All / Specific / Cancel
|
|
151
|
+
3. `rm -f` selected agents' memory files → `wangchuan sync -y`
|
|
152
|
+
|
|
153
|
+
**Note**: Memory filenames differ per agent — Claude uses `CLAUDE.md`, OpenClaw/CodeBuddy/WorkBuddy/Codex use `MEMORY.md`.
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# Pushing, Pulling, and Conflict Resolution
|
|
2
|
+
|
|
3
|
+
## How sync works
|
|
4
|
+
|
|
5
|
+
`wangchuan sync` is **bidirectional**: pull first, then push. `wangchuan watch` is **pull-only** — it periodically pulls cloud changes but never pushes. Users must run `wangchuan sync` manually to push local changes.
|
|
6
|
+
|
|
7
|
+
Flow of `sync`: **auto-snapshot** → fetch remote → if remote ahead → git pull → three-way merge → then stage + push local changes.
|
|
8
|
+
Flow of `watch`: fetch remote → if remote ahead → git pull → restore to local → record unresolved conflicts.
|
|
9
|
+
|
|
10
|
+
**Note**: sync automatically creates a safety snapshot of the repo before every sync. This means you can always roll back to the pre-sync state via `wangchuan snapshot list` + `wangchuan snapshot restore`.
|
|
11
|
+
|
|
12
|
+
**Environment**: all sync/push/pull operations target the **current environment's branch only** (`cfg.environment`). After sync completes, always report the current environment name to the user (e.g. "Synced to cloud (environment: work)").
|
|
13
|
+
|
|
14
|
+
## Pushing memory to cloud
|
|
15
|
+
|
|
16
|
+
1. **Preview** (optional): `wangchuan status -v`
|
|
17
|
+
2. **Sync**: `wangchuan sync -y`
|
|
18
|
+
3. **Conflict resolution** (auto for `.md` files):
|
|
19
|
+
- Non-overlapping edits → auto-merged ✅
|
|
20
|
+
- Overlapping identical edits → deduplicated ✅
|
|
21
|
+
- Overlapping conflicting edits → conflict markers written:
|
|
22
|
+
```
|
|
23
|
+
<<<<<<< LOCAL
|
|
24
|
+
(your local changes)
|
|
25
|
+
=======
|
|
26
|
+
(cloud changes)
|
|
27
|
+
>>>>>>> REMOTE
|
|
28
|
+
```
|
|
29
|
+
4. **If conflict markers written** → read file, show conflicts to user, ask how to resolve, edit to remove markers, `wangchuan sync -y` again.
|
|
30
|
+
5. **If no conflicts** → done.
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
# Full push flow:
|
|
34
|
+
wangchuan sync -y
|
|
35
|
+
# Check for conflict markers:
|
|
36
|
+
grep -l '<<<<<<< LOCAL' ~/.claude/CLAUDE.md ~/.openclaw/workspace/MEMORY.md ~/.codebuddy/MEMORY.md ~/.workbuddy/MEMORY.md ~/.codex/MEMORY.md 2>/dev/null
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Pulling memory from cloud
|
|
40
|
+
|
|
41
|
+
Same command: `wangchuan sync -y`. Use `wangchuan sync -n` for dry-run preview first.
|
|
42
|
+
|
|
43
|
+
Conflict resolution is identical to pushing. Encrypted files are decrypted transparently during pull.
|
|
44
|
+
|
|
45
|
+
**Pulling from a specific environment**: push/pull always targets the **current** environment's branch. To pull from a different env:
|
|
46
|
+
```bash
|
|
47
|
+
wangchuan env switch <target-env> # switches branch + auto-syncs (pulls target env's data)
|
|
48
|
+
# When done, switch back:
|
|
49
|
+
wangchuan env switch <original-env>
|
|
50
|
+
```
|
|
51
|
+
There is no `--from-env` flag — must switch first.
|
|
52
|
+
|
|
53
|
+
## Syncing resources between agents
|
|
54
|
+
|
|
55
|
+
When user says "sync A's config to B", intent may be ambiguous.
|
|
56
|
+
|
|
57
|
+
**Step 1: Clarify** — ask which resources: Memory / Skills / MCP servers / Custom agents / All.
|
|
58
|
+
|
|
59
|
+
**Step 2: Execute per type:**
|
|
60
|
+
- **Memory**: `wangchuan memory copy <source> <target>` → `wangchuan sync -y`
|
|
61
|
+
- **Skills**: `cp -r "${SRC_WS}/skills/"* "${DST_WS}/skills/"` → `wangchuan sync -y`
|
|
62
|
+
- **MCP**: read mcpServers from source, jq merge into target → `wangchuan sync -y`
|
|
63
|
+
- **Custom agents**: `cp -r "${SRC_WS}/agents/"* "${DST_WS}/agents/"` → `wangchuan sync -y`
|
|
64
|
+
|
|
65
|
+
Get workspace paths:
|
|
66
|
+
```bash
|
|
67
|
+
SRC=$(jq -r '.profiles.default.<source>.workspacePath' ~/.wangchuan/config.json | sed "s|^~|$HOME|")
|
|
68
|
+
DST=$(jq -r '.profiles.default.<target>.workspacePath' ~/.wangchuan/config.json | sed "s|^~|$HOME|")
|
|
69
|
+
```
|