@wuyaos/pi-sync 1.1.0 → 1.2.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/PROMO.md CHANGED
@@ -1,95 +1,59 @@
1
1
  # pi-sync promotion drafts
2
2
 
3
- Repo: https://github.com/wuyaos/pi-packages
4
- Install: `pi install git:github.com/wuyaos/pi-packages`
5
- Release: https://github.com/wuyaos/pi-packages/releases/tag/v1.0.1
3
+ ## English
6
4
 
7
- ---
8
-
9
- ## English (short)
10
-
11
- **pi-sync** — WebDAV backup/restore for the [Pi coding agent](https://github.com/earendil-works/pi-coding-agent).
12
-
13
- Open `/sync`, then **Upload Backup** on one machine and **Download Backup** on another.
5
+ **pi-sync 1.2** — versioned WebDAV archives for the [Pi coding agent](https://github.com/earendil-works/pi-coding-agent).
14
6
 
15
7
  ```bash
16
- pi install git:github.com/wuyaos/pi-packages
17
- /sync # main machine → Upload Backup (Backup to cloud)
18
- /sync # new machine → Download Backup (Restore from cloud)
8
+ pi install npm:@wuyaos/pi-sync
9
+ /sync
19
10
  ```
20
11
 
21
- Works with any WebDAV (Nextcloud, 坚果云, TeraCLOUD, self-hosted). Restore keeps local `.bak` copies. MIT.
22
-
23
- 👉 https://github.com/wuyaos/pi-packages
24
-
25
- ---
26
-
27
- ## English (Discord / forum)
28
-
29
- Hey Pi users — I open-sourced **pi-sync**, a small package that syncs your Pi agent home over WebDAV.
30
-
31
- Problem: multi-machine setups mean re-copying `models.json`, skills, and extensions by hand.
32
- Solution: `/sync push` on the main box, `/sync pull` on the next one.
33
-
34
- - Install: `pi install git:github.com/wuyaos/pi-packages`
35
- - Interactive menu: Upload Backup · Download Backup · Configure Sync Settings
36
- - Optional Windows bootstrap script for brand-new machines
37
- - Backup zips tagged by platform (`windows11`, `macos`, …)
38
- - Restore confirms and keeps timestamped local backups
39
-
40
- Feedback / issues welcome: https://github.com/wuyaos/pi-packages
41
-
42
- ---
12
+ Highlights:
43
13
 
44
- ## 中文(短)
14
+ - Direct `~/.pi/agent` archive with configurable exclusions
15
+ - Independent shared-Skills and per-project session archives
16
+ - Automatic current-project archive when Pi exits
17
+ - Back Up All / Restore All (latest)
18
+ - English and Chinese menus
19
+ - Streamed WebDAV transfers and safe archive validation
20
+ - No live or per-turn synchronization
45
21
 
46
- **pi-sync**:给 [Pi coding agent](https://github.com/earendil-works/pi-coding-agent) 用的 WebDAV 配置同步插件。
22
+ WebDAV layout:
47
23
 
48
- 多机之间一键备份 / 恢复 models、settings、skills、extensions。
49
-
50
- ```bash
51
- pi install git:github.com/wuyaos/pi-packages
52
- /sync # 主力机 → Upload Backup (Backup to cloud)
53
- /sync # 新机器 → Download Backup (Restore from cloud)
24
+ ```text
25
+ backup/pi/
26
+ backup/skills/
27
+ backup/sessions/<project>/
54
28
  ```
55
29
 
56
- 支持任意 WebDAV(坚果云 / Nextcloud / 自建)。恢复前会做本地备份。MIT 开源。
57
-
58
- 👉 https://github.com/wuyaos/pi-packages
59
-
60
- ---
61
-
62
- ## 中文(朋友圈 / 社区)
63
-
64
- 换电脑重装 Pi 配置太烦?我做了个小工具 **pi-sync** 并开源了。
30
+ Repository: https://github.com/wuyaos/pi-packages/tree/master/pi-sync
65
31
 
66
- - 主力机 `/sync` → **Upload Backup** 把配置打成 zip 传到 WebDAV
67
- - 新机器 `/sync` → **Download Backup** 选择备份并还原
68
- - 覆盖 models / settings / skills / extensions
69
- - 恢复前自动留本地备份,密码建议用应用专用密码 + 环境变量
32
+ ## 简体中文
70
33
 
71
- 安装一行:
34
+ **pi-sync 1.2**:面向 [Pi coding agent](https://github.com/earendil-works/pi-coding-agent) 的 WebDAV 有版本归档备份。
72
35
 
73
36
  ```bash
74
- pi install git:github.com/wuyaos/pi-packages
37
+ pi install npm:@wuyaos/pi-sync
38
+ /sync
75
39
  ```
76
40
 
77
- 仓库:https://github.com/wuyaos/pi-packages
78
- Release:https://github.com/wuyaos/pi-packages/releases/tag/v1.0.1
41
+ 主要特性:
79
42
 
80
- 欢迎试用和提 issue。
43
+ - 直接归档 `~/.pi/agent`,支持黑名单排除
44
+ - 共享 Skills 与项目会话独立归档
45
+ - 退出 Pi 时自动归档当前项目会话
46
+ - 全部备份 / 全部恢复(最新)
47
+ - 中英文菜单切换
48
+ - WebDAV 流式传输与安全归档校验
49
+ - 不进行实时或每轮同步
81
50
 
82
- ---
51
+ WebDAV 目录:
83
52
 
84
- ## Tweet / X (EN)
85
-
86
- Multi-machine Pi setup? I open-sourced pi-sync:
87
-
88
- `/sync` → Upload Backup → WebDAV
89
- `/sync` → Download Backup → new machine
90
-
91
- models · settings · skills · extensions
92
-
93
- `pi install git:github.com/wuyaos/pi-packages`
53
+ ```text
54
+ backup/pi/
55
+ backup/skills/
56
+ backup/sessions/<project>/
57
+ ```
94
58
 
95
- https://github.com/wuyaos/pi-packages
59
+ 仓库:https://github.com/wuyaos/pi-packages/tree/master/pi-sync
package/README.md CHANGED
@@ -4,202 +4,211 @@
4
4
 
5
5
  [![pi package](https://img.shields.io/badge/pi-package-blue)](https://github.com/earendil-works/pi-coding-agent)
6
6
  [![license](https://img.shields.io/badge/license-MIT-green)](./LICENSE)
7
- [![release](https://img.shields.io/github/v/release/wuyaos/pi-packages?display_name=tag&sort=semver)](https://github.com/wuyaos/pi-packages/releases)
8
7
 
9
- WebDAV-based config sync for [Pi](https://github.com/earendil-works/pi-coding-agent) — backup and restore **models**, **settings**, **skills**, **extensions**, and **session projects** across machines.
8
+ WebDAV archive backup and restore for [Pi](https://github.com/earendil-works/pi-coding-agent).
10
9
 
11
- Run `/sync`, pick an action from the menu. One machine uploads; another downloads and restores.
10
+ `pi-sync` creates versioned `.tar.xz` archives for Pi agent data, shared skills, and project sessions. It is intentionally **archive-only**: there are no live uploads, per-turn hooks, interval synchronization, or multi-machine merge conflicts.
12
11
 
13
- <p align="center">
14
- <img src="docs/sync-menu.png" alt="Pi WebDAV Synchronization menu" width="720" />
15
- </p>
12
+ ## Features
16
13
 
17
- <p align="center"><sub><b>Pi WebDAV Synchronization</b> interactive menu after <code>/sync</code></sub></p>
18
-
19
- ## Why
20
-
21
- If you run Pi on multiple PCs / WSL / servers, reinstalling models, skills, and extensions by hand is painful. `pi-sync` packages your agent home into a timestamped zip, uploads it to any WebDAV folder, and restores it with local safety backups.
14
+ - Back up `~/.pi/agent` directly without a staging copy
15
+ - Exclude reinstallable or transient trees through a configurable blacklist
16
+ - Keep `~/.agents/skills` in an independent, optional archive
17
+ - Archive sessions separately per project
18
+ - Automatically archive the current project when Pi exits
19
+ - Back up or restore every enabled category in one action
20
+ - English and Simplified Chinese `/sync` menus
21
+ - Stream WebDAV uploads/downloads instead of buffering whole archives in memory
22
+ - Reject unsafe archive paths, symbolic links, special nodes, and unsafe restore destinations
22
23
 
23
24
  ## Install
24
25
 
25
- Requires [Pi coding agent](https://github.com/earendil-works/pi-coding-agent) and a WebDAV endpoint (TeraCLOUD, 坚果云 / Jianguoyun, Nextcloud, ownCloud, self-hosted, …).
26
-
27
- `pi-sync` is part of the [wuyaos/pi-packages](https://github.com/wuyaos/pi-packages) monorepo. Installing the whole repo loads every sub-package:
26
+ Install the package from npm:
28
27
 
29
28
  ```bash
30
- pi install git:github.com/wuyaos/pi-packages
29
+ pi install npm:@wuyaos/pi-sync
31
30
  ```
32
31
 
33
- To load **only** `pi-sync`, use the object form in `~/.pi/agent/settings.json`:
32
+ Or install the complete monorepo:
34
33
 
35
- ```json
36
- {
37
- "packages": [
38
- {
39
- "source": "git:github.com/wuyaos/pi-packages",
40
- "extensions": ["pi-sync/extensions/*.ts"],
41
- "themes": []
42
- }
43
- ]
44
- }
34
+ ```bash
35
+ pi install git:github.com/wuyaos/pi-packages
45
36
  ```
46
37
 
47
- Then restart Pi or run `/reload`.
38
+ Restart Pi or run `/reload` after installation.
48
39
 
49
40
  ## Usage
50
41
 
51
- Type **`/sync`** in Pi. There are no CLI subcommands — everything goes through the interactive menu:
42
+ Run `/sync`. The interactive menu contains:
52
43
 
53
- | Menu item | What it does |
54
- |-----------|----------------|
55
- | ☁️ **Upload Backup (Backup to cloud)** | Zip current config and upload to WebDAV |
56
- | 📥 **Download Backup (Restore from cloud)** | List remote backups, download one, restore with confirmation |
57
- | ⚙️ **Configure Sync Settings** | WebDAV URL / user / password, and what to include |
58
- | **Cancel** | Leave the menu |
44
+ - **Back Up All** / **Restore All (latest)**
45
+ - Upload or restore **Pi Backup**
46
+ - Upload or restore **Skills Backup**
47
+ - Upload or restore **Sessions Archive**
48
+ - Configure backup settings
49
+ - Switch the menu between English and Chinese
59
50
 
60
- Keyboard hints (as shown in the TUI): `↵` select · `↑↓` navigate · `Esc` cancel.
51
+ The first run opens a WebDAV setup wizard when the URL, username, or password is missing.
61
52
 
62
- ### First-time setup
53
+ ## Archive model
63
54
 
64
- ```bash
65
- # 1. Install
66
- pi install git:github.com/wuyaos/pi-packages
55
+ ### Pi backup
67
56
 
68
- # 2. Open the menu (first run starts the setup wizard if WebDAV is empty)
69
- /sync
57
+ The Pi archive packs `~/.pi/agent` directly. Its default blacklist is:
70
58
 
71
- # 3. If needed: Configure Sync Settings
72
- # enter URL / user / password
73
- # tip: set password to $PI_WEBDAV_PASS and export that env var
59
+ ```json
60
+ ["npm", "git", "sessions", "state", "tmp", "webui-rpc-supervisor", "vstack"]
61
+ ```
62
+
63
+ This keeps configuration and extension state while excluding installed package sources, temporary extension caches, sessions (archived separately), workspace history, background-task state, and Web UI RPC runtime sockets. `config/sync.json` is included unless explicitly blacklisted.
64
+
65
+ Archive name:
74
66
 
75
- # 4. On your main machine → Upload Backup (Backup to cloud)
76
- # 5. On a new machine (after install + configure) → Download Backup (Restore from cloud)
67
+ ```text
68
+ backup/pi/pi_agent_<platform>_<timestamp>.tar.xz
77
69
  ```
78
70
 
79
- ### What gets synced
71
+ ### Shared skills backup
80
72
 
81
- | Component | Default | Notes |
82
- |-----------|---------|-------|
83
- | Config | ON | `models.json`, `settings.json`, `auth.json` |
84
- | Skills | ON | entire `~/.pi/agent/skills` |
85
- | Extensions | ON | `~/.pi/agent/extensions` (the sync plugin itself is excluded from the zip) |
86
- | Sessions | OFF | per-project session history under `~/.pi/agent/sessions/`; pick which projects to include under **Configure Sync Settings → Session Projects** |
73
+ `~/.agents/skills` is stored in a separate archive and is disabled by default.
87
74
 
88
- Toggle any of these under **Configure Sync Settings**.
75
+ ```text
76
+ backup/skills/agent_skills_<timestamp>.tar.xz
77
+ ```
89
78
 
90
- ### Sessions (optional)
79
+ ### Session archives
91
80
 
92
- Session history is organized by project cwd under `~/.pi/agent/sessions/<projectDir>/`. The **Session Projects** submenu lists every project directory found on this machine and lets you check the ones you want to back up.
81
+ Sessions are archived by project. There is no live synchronization or `_latest.json` marker.
93
82
 
94
- - Turn on **Backup Sessions** in **Configure Sync Settings**.
95
- - Open **Session Projects** and toggle projects on/off (use **Select All** / **Reset list** for convenience).
96
- - List mode (toggleable):
97
- - **Whitelist**: only checked projects are backed up; an empty list backs up **nothing**.
98
- - **Blacklist**: checked projects are skipped; an empty list backs up **everything**.
99
- - On restore, session files are *merged* into the local `~/.pi/agent/sessions/` — session file names are unique (timestamp + uuid), so restoring never overwrites or deletes your local sessions.
83
+ ```text
84
+ backup/sessions/<projectDir>/sessions_<platform>_<timestamp>.tar.xz
85
+ ```
86
+
87
+ Project selection supports:
100
88
 
101
- > Note: project directory names encode the project path, so a backup made on one machine only restores into the same project path on another machine.
89
+ - **Whitelist**: only listed projects are archived; an empty list means none.
90
+ - **Blacklist**: listed projects are excluded; an empty list means all projects.
102
91
 
103
- ### Backup filename
92
+ When `backupOnExit` is enabled, Pi archives the current allowed project during `session_shutdown`. Manual session backup remains available from `/sync`.
104
93
 
105
- Archives look like:
94
+ ## WebDAV layout
106
95
 
107
96
  ```text
108
- pi_sync_backup_2026-7-14_20260714120000_windows11.zip
97
+ <webdavUrl>/
98
+ └── backup/
99
+ ├── pi/
100
+ │ └── pi_agent_<platform>_<timestamp>.tar.xz
101
+ ├── skills/
102
+ │ └── agent_skills_<timestamp>.tar.xz
103
+ └── sessions/
104
+ └── <projectDir>/
105
+ └── sessions_<platform>_<timestamp>.tar.xz
106
+ ```
107
+
108
+ `maxBackups` is enforced independently in each backup directory. `0` keeps every archive.
109
+
110
+ ## Configuration
111
+
112
+ Configuration is stored at `~/.pi/agent/config/sync.json`:
113
+
114
+ ```json
115
+ {
116
+ "webdavUrl": "https://example.com/dav/pi",
117
+ "webdavUser": "user",
118
+ "webdavPass": "$PI_WEBDAV_PASS",
119
+ "language": "en",
120
+ "backupProviders": true,
121
+ "backupSessions": true,
122
+ "backupAgentSkills": false,
123
+ "piExcludePaths": ["npm", "git", "sessions", "state", "tmp", "webui-rpc-supervisor", "vstack"],
124
+ "backupOnExit": true,
125
+ "sessionProjectMode": "blacklist",
126
+ "sessionProjects": [],
127
+ "maxBackups": 10
128
+ }
109
129
  ```
110
130
 
111
- The trailing platform tag (`windows11` / `windows10` / `macos` / `linux`) shows which host created the backup.
131
+ The password may reference an environment variable (`$PI_WEBDAV_PASS`). When `language` is absent, pi-sync uses `settings.json piSwitch.language` and falls back to English.
112
132
 
113
- ### Safety on restore
133
+ ## Restore behavior and safety
114
134
 
115
- - Existing config files get a timestamped `.bak` copy before overwrite
116
- - Existing skills / extensions folders are renamed to `*-backup-<timestamp>` before replace/merge
117
- - Restore shows a plan and asks for confirmation
118
- - After a successful restore you can reload the agent runtime to apply skills/extensions
135
+ - Every archive path is checked for absolute paths and traversal.
136
+ - Symlinks and non-regular filesystem nodes are rejected before extraction.
137
+ - Archives are extracted to a temporary directory before merging.
138
+ - Restore refuses symbolic links or type conflicts in destination paths.
139
+ - Pi restore only touches files present in the archive; excluded directories remain unchanged.
140
+ - Skills restore moves the existing `~/.agents/skills` to a timestamped backup first.
141
+ - Session restore merges files into `~/.pi/agent/sessions`.
142
+ - Pi restore shows a plan and offers `/reload` afterward.
119
143
 
120
- ## Bootstrap (new Windows machine, no Pi yet)
144
+ Treat archives as sensitive: Pi backups may contain WebDAV credentials, API keys, provider settings, and other secrets.
121
145
 
122
- If Pi is not installed yet, you can still pull the latest zip with the helper script:
146
+ ## New Windows machine
147
+
148
+ `pi-bootstrap.ps1` downloads the latest archive from `backup/pi/` and merges it into `%USERPROFILE%\.pi\agent`:
149
+
150
+ > **Trusted archives only:** this bootstrap helper does not perform pi-sync's TypeScript path and link validation. Use `/sync` restore for normal recovery, and use the script only with a trusted WebDAV endpoint and archive.
123
151
 
124
152
  ```powershell
125
- # Prefer env vars so secrets never land in shell history
126
- $env:PI_WEBDAV_URL = "https://your-webdav.example/dav/Pi"
127
- $env:PI_WEBDAV_USER = "your-user"
128
- $env:PI_WEBDAV_PASS = "your-app-password"
153
+ $env:PI_WEBDAV_URL = "https://example.com/dav/pi"
154
+ $env:PI_WEBDAV_USER = "user"
155
+ $env:PI_WEBDAV_PASS = "app-password"
129
156
  .\pi-bootstrap.ps1
130
157
  ```
131
158
 
132
- Or one-liner placeholders (replace before running):
159
+ The script is intended for trusted archives and new-machine bootstrap. Install/update packages afterward so excluded `npm/` and `git/` trees are rebuilt.
133
160
 
134
- ```powershell
135
- $url="https://your-webdav.example/dav/Pi"; $user="your-user"; $pass="your-app-password"
136
- $pair="$user`:$pass"; $auth=[Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes($pair))
137
- $resp=Invoke-RestMethod -Uri $url -Method PROPFIND -Headers @{Authorization="Basic $auth";Depth="1"} -ContentType "application/xml"
138
- $files=([regex]'<d:href>([^<]+)</d:href>').Matches($resp) | %{$_.Groups[1].Value} | ?{$_ -match "pi_sync_backup_.*\.zip$"} | Sort-Object -Descending
139
- $latest=$files[0]; $name=Split-Path $latest -Leaf
140
- Invoke-WebRequest -Uri "$url/$name" -Headers @{Authorization="Basic $auth"} -OutFile "$env:TEMP\$name"
141
- ```
161
+ ## Troubleshooting
142
162
 
143
- Then install Pi and use **Download Backup** from `/sync` for future updates.
163
+ | Symptom | Fix |
164
+ |---|---|
165
+ | HTTP 401 / 403 | Verify the WebDAV URL and use an app-specific password. |
166
+ | PROPFIND fails | Ensure the server supports WebDAV `PROPFIND` with `Depth: 1`. |
167
+ | tar errors | Install a `tar` implementation with xz support. |
168
+ | Exit backup is skipped | Check `backupOnExit`, `backupSessions`, project mode/list, and WebDAV credentials. |
169
+ | Packages missing after Pi restore | Re-run `pi update --extensions` or reinstall packages from `settings.json`. |
144
170
 
145
- ## Security
171
+ ## Development
146
172
 
147
- - WebDAV credentials are stored locally in `~/.pi/agent/sync_config.json`
148
- - Prefer **app-specific passwords** (not your main account password)
149
- - Prefer env-var references: set password to `$PI_WEBDAV_PASS` in the UI, then export that variable in your shell profile
150
- - Backups may include `auth.json` / API keys if those options are enabled — treat the WebDAV folder as sensitive
151
- - Never commit real WebDAV URLs with credentials into git
173
+ ```bash
174
+ cd /mnt/d/work/project/person/pi-packages
175
+ node --import tsx --test pi-sync/extensions/sync/*.test.ts
176
+ npm run typecheck
177
+ ```
152
178
 
153
- ## Troubleshooting
179
+ The monorepo typecheck may report unrelated errors from other packages; pi-sync-specific errors are identified by paths beginning with `pi-sync/`.
154
180
 
155
- | Symptom | Fix |
156
- |---------|-----|
157
- | HTTP 401 / 403 | Check user/password; use app password; confirm URL includes the correct DAV path |
158
- | PROPFIND fails / empty list | Server may block PROPFIND; try another WebDAV provider; ensure Depth:1 is allowed |
159
- | tar / zip errors | Need a working `tar` on PATH (Windows 10+ has one; Git Bash / WSL also fine) |
160
- | Restore overwrote something | Look for `*.bak-*` files and `skills-backup-*` / `extensions-backup-*` folders next to the agent dir |
161
- | Plugin missing after restore | Re-run `pi install git:github.com/wuyaos/pi-packages` — the sync package excludes itself from the archive |
181
+ ### WebDAV smoke test
162
182
 
163
- ## Structure
183
+ The committed smoke harness creates uniquely named temporary Pi and session archives, uploads/list/downloads/validates them, then deletes them. It never prints credentials. It is intentionally write-protected:
164
184
 
165
- ```text
166
- pi-sync/
167
- package.json
168
- LICENSE
169
- README.md
170
- README.zh-CN.md
171
- pi-bootstrap.ps1
172
- docs/
173
- sync-menu.png # /sync menu screenshot
174
- extensions/
175
- sync/
176
- index.ts # /sync command
177
- _shared/
178
- json-io.ts
179
- enhanced-select.ts
180
- spawn.ts
181
- fetch-utils.ts
182
- box-drawing.ts
185
+ ```bash
186
+ cd /mnt/d/work/project/person/pi-packages
187
+ PI_SYNC_SMOKE_WRITE=1 bash --noprofile --norc pi-sync/scripts/verify.sh
183
188
  ```
184
189
 
190
+ `verify.sh` also runs the unit tests, strict pi-sync typecheck, extension-load check, package whitelist check, and diff check. It uses `~/.pi/agent/config/sync.json`; optionally set `PI_SYNC_SMOKE_PROJECT` to a permitted local session directory name (such as `--home-user--`).
191
+
185
192
  ## Changelog
186
193
 
187
- ### v1.0.1
194
+ ### v1.2.0
195
+
196
+ - Replace live synchronization with versioned archive-only backup/restore
197
+ - Add direct Pi-home tar backup with blacklist exclusions
198
+ - Separate Pi, shared skills, and per-project session archives
199
+ - Add exit-time session archiving and manual all-category backup/restore
200
+ - Add English/Chinese menu switching
201
+ - Add streamed WebDAV transfer, config caching, and archive/restore safety checks
202
+ - Remove live sync, interval sync, custom-path, memory, and legacy monolithic code
203
+
204
+ ### v1.1.1
188
205
 
189
- - Tag backup zip names with host platform (`windows11` / `macos` / `linux` / …)
190
- - Remove example credentials from bootstrap script comments
191
- - Add MIT `LICENSE` and expand README (security, restore safety, troubleshooting, menu screenshot)
206
+ - Cache WebDAV directory creation and loaded configuration to reduce repeated I/O
192
207
 
193
208
  ### v1.0.0
194
209
 
195
- - Initial public release: interactive `/sync` menu over WebDAV
196
- - Upload Backup · Download Backup · Configure Sync Settings
197
- - Windows bootstrap helper script
210
+ - Initial WebDAV backup/restore release
198
211
 
199
212
  ## License
200
213
 
201
214
  MIT — see [LICENSE](./LICENSE).
202
-
203
- ## Acknowledgements
204
-
205
- This open-source project is linked and recognized by the [LINUX DO](https://linux.do) community.