@wuyaos/pi-sync 1.1.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 BevalZ
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:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
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.
package/PROMO.md ADDED
@@ -0,0 +1,95 @@
1
+ # pi-sync promotion drafts
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
6
+
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.
14
+
15
+ ```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)
19
+ ```
20
+
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
+ ---
43
+
44
+ ## 中文(短)
45
+
46
+ **pi-sync**:给 [Pi coding agent](https://github.com/earendil-works/pi-coding-agent) 用的 WebDAV 配置同步插件。
47
+
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)
54
+ ```
55
+
56
+ 支持任意 WebDAV(坚果云 / Nextcloud / 自建)。恢复前会做本地备份。MIT 开源。
57
+
58
+ 👉 https://github.com/wuyaos/pi-packages
59
+
60
+ ---
61
+
62
+ ## 中文(朋友圈 / 社区)
63
+
64
+ 换电脑重装 Pi 配置太烦?我做了个小工具 **pi-sync** 并开源了。
65
+
66
+ - 主力机 `/sync` → **Upload Backup** 把配置打成 zip 传到 WebDAV
67
+ - 新机器 `/sync` → **Download Backup** 选择备份并还原
68
+ - 覆盖 models / settings / skills / extensions
69
+ - 恢复前自动留本地备份,密码建议用应用专用密码 + 环境变量
70
+
71
+ 安装一行:
72
+
73
+ ```bash
74
+ pi install git:github.com/wuyaos/pi-packages
75
+ ```
76
+
77
+ 仓库:https://github.com/wuyaos/pi-packages
78
+ Release:https://github.com/wuyaos/pi-packages/releases/tag/v1.0.1
79
+
80
+ 欢迎试用和提 issue。
81
+
82
+ ---
83
+
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`
94
+
95
+ https://github.com/wuyaos/pi-packages
package/README.md ADDED
@@ -0,0 +1,205 @@
1
+ # pi-sync
2
+
3
+ **English** | [简体中文](./README.zh-CN.md)
4
+
5
+ [![pi package](https://img.shields.io/badge/pi-package-blue)](https://github.com/earendil-works/pi-coding-agent)
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
+
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.
10
+
11
+ Run `/sync`, pick an action from the menu. One machine uploads; another downloads and restores.
12
+
13
+ <p align="center">
14
+ <img src="docs/sync-menu.png" alt="Pi WebDAV Synchronization menu" width="720" />
15
+ </p>
16
+
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.
22
+
23
+ ## Install
24
+
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:
28
+
29
+ ```bash
30
+ pi install git:github.com/wuyaos/pi-packages
31
+ ```
32
+
33
+ To load **only** `pi-sync`, use the object form in `~/.pi/agent/settings.json`:
34
+
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
+ }
45
+ ```
46
+
47
+ Then restart Pi or run `/reload`.
48
+
49
+ ## Usage
50
+
51
+ Type **`/sync`** in Pi. There are no CLI subcommands — everything goes through the interactive menu:
52
+
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 |
59
+
60
+ Keyboard hints (as shown in the TUI): `↵` select · `↑↓` navigate · `Esc` cancel.
61
+
62
+ ### First-time setup
63
+
64
+ ```bash
65
+ # 1. Install
66
+ pi install git:github.com/wuyaos/pi-packages
67
+
68
+ # 2. Open the menu (first run starts the setup wizard if WebDAV is empty)
69
+ /sync
70
+
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
74
+
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)
77
+ ```
78
+
79
+ ### What gets synced
80
+
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** |
87
+
88
+ Toggle any of these under **Configure Sync Settings**.
89
+
90
+ ### Sessions (optional)
91
+
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.
93
+
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.
100
+
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.
102
+
103
+ ### Backup filename
104
+
105
+ Archives look like:
106
+
107
+ ```text
108
+ pi_sync_backup_2026-7-14_20260714120000_windows11.zip
109
+ ```
110
+
111
+ The trailing platform tag (`windows11` / `windows10` / `macos` / `linux`) shows which host created the backup.
112
+
113
+ ### Safety on restore
114
+
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
119
+
120
+ ## Bootstrap (new Windows machine, no Pi yet)
121
+
122
+ If Pi is not installed yet, you can still pull the latest zip with the helper script:
123
+
124
+ ```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"
129
+ .\pi-bootstrap.ps1
130
+ ```
131
+
132
+ Or one-liner placeholders (replace before running):
133
+
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
+ ```
142
+
143
+ Then install Pi and use **Download Backup** from `/sync` for future updates.
144
+
145
+ ## Security
146
+
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
152
+
153
+ ## Troubleshooting
154
+
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 |
162
+
163
+ ## Structure
164
+
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
183
+ ```
184
+
185
+ ## Changelog
186
+
187
+ ### v1.0.1
188
+
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)
192
+
193
+ ### v1.0.0
194
+
195
+ - Initial public release: interactive `/sync` menu over WebDAV
196
+ - Upload Backup · Download Backup · Configure Sync Settings
197
+ - Windows bootstrap helper script
198
+
199
+ ## License
200
+
201
+ 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.
@@ -0,0 +1,205 @@
1
+ # pi-sync
2
+
3
+ [English](./README.md) | **简体中文**
4
+
5
+ [![pi package](https://img.shields.io/badge/pi-package-blue)](https://github.com/earendil-works/pi-coding-agent)
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
+
9
+ 面向 [Pi](https://github.com/earendil-works/pi-coding-agent) 的 WebDAV 配置同步工具 —— 跨机器备份与恢复 **models**、**settings**、**skills**、**extensions** 以及选定的 **session 项目**。
10
+
11
+ 在 Pi 里输入 `/sync`,从菜单选择操作。一台机器上传,另一台下载并恢复。
12
+
13
+ <p align="center">
14
+ <img src="docs/sync-menu.png" alt="Pi WebDAV Synchronization 菜单" width="720" />
15
+ </p>
16
+
17
+ <p align="center"><sub><b>Pi WebDAV Synchronization</b> —— 输入 <code>/sync</code> 后的交互菜单</sub></p>
18
+
19
+ ## 为什么需要它
20
+
21
+ 如果你在多台 PC / WSL / 服务器上使用 Pi,手工重装 models、skills、extensions 很痛苦。`pi-sync` 会把 agent 主目录打包成带时间戳的 zip,上传到任意 WebDAV 目录,并在恢复时保留本地安全备份。
22
+
23
+ ## 安装
24
+
25
+ 需要 [Pi coding agent](https://github.com/earendil-works/pi-coding-agent),以及可用的 WebDAV(TeraCLOUD、坚果云、Nextcloud、ownCloud、自建等)。
26
+
27
+ `pi-sync` 是 [wuyaos/pi-packages](https://github.com/wuyaos/pi-packages) monorepo 的子包。直接安装整个仓库会加载所有子包:
28
+
29
+ ```bash
30
+ pi install git:github.com/wuyaos/pi-packages
31
+ ```
32
+
33
+ 只想加载 **pi-sync** 时,在 `~/.pi/agent/settings.json` 用 object 形式筛选:
34
+
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
+ }
45
+ ```
46
+
47
+ 然后重启 Pi,或执行 `/reload`。
48
+
49
+ ## 用法
50
+
51
+ 在 Pi 中输入 **`/sync`**。没有命令行子命令 —— 全部通过交互菜单完成:
52
+
53
+ | 菜单项 | 作用 |
54
+ |--------|------|
55
+ | ☁️ **Upload Backup (Backup to cloud)** | 打包当前配置并上传到 WebDAV |
56
+ | 📥 **Download Backup (Restore from cloud)** | 列出云端备份,下载并在确认后恢复 |
57
+ | ⚙️ **Configure Sync Settings** | 配置 WebDAV 地址 / 用户 / 密码,以及同步范围 |
58
+ | ❌ **Cancel** | 退出菜单 |
59
+
60
+ TUI 提示:`↵` 选择 · `↑↓` 导航 · `Esc` 取消。
61
+
62
+ ### 首次配置
63
+
64
+ ```bash
65
+ # 1. 安装
66
+ pi install git:github.com/wuyaos/pi-packages
67
+
68
+ # 2. 打开菜单(若尚未配置 WebDAV,会先进入设置向导)
69
+ /sync
70
+
71
+ # 3. 如需修改:Configure Sync Settings
72
+ # 填写 URL / 用户名 / 密码
73
+ # 建议:密码填 $PI_WEBDAV_PASS,并在 shell 中 export 该环境变量
74
+
75
+ # 4. 主力机 → Upload Backup (Backup to cloud)
76
+ # 5. 新机器(安装并配置后)→ Download Backup (Restore from cloud)
77
+ ```
78
+
79
+ ### 会同步哪些内容
80
+
81
+ | 组件 | 默认 | 说明 |
82
+ |------|------|------|
83
+ | Config | 开 | `models.json`、`settings.json`、`auth.json` |
84
+ | Skills | 开 | 整个 `~/.pi/agent/skills` |
85
+ | Extensions | 开 | `~/.pi/agent/extensions`(zip 中会排除 sync 插件自身) |
86
+ | Sessions | 关 | `~/.pi/agent/sessions/` 下按项目分目录的会话历史;在 **Configure Sync Settings → Session Projects** 中勾选要同步的项目 |
87
+
88
+ 可在 **Configure Sync Settings** 中分别开关。
89
+
90
+ ### Sessions(可选)
91
+
92
+ 会话历史按项目 cwd 存放在 `~/.pi/agent/sessions/<projectDir>/`。**Session Projects** 子菜单会列出本机所有项目目录,勾选你想备份的那些。
93
+
94
+ - 在 **Configure Sync Settings** 中打开 **Backup Sessions**。
95
+ - 打开 **Session Projects** 逐个勾选项目(可用 **Select All** / **Reset list** 快捷全选/清空)。
96
+ - 列表模式(可切换):
97
+ - **白名单模式**:只备份勾选的项目,空列表 = 全部不备份。
98
+ - **黑名单模式**:跳过勾选的项目,空列表 = 全部备份。
99
+ - 恢复时会以 *合并* 方式写入本地 `~/.pi/agent/sessions/`——会话文件名为唯一的时间戳+uuid,不会覆盖或删除本地已有会话。
100
+
101
+ > 注意:项目目录名由项目路径编码而来,备份在 A 机器上制作,恢复到 B 机器时只会落到相同项目路径对应的项目目录中。
102
+
103
+ ### 备份文件名
104
+
105
+ 归档文件形如:
106
+
107
+ ```text
108
+ pi_sync_backup_2026-7-14_20260714120000_windows11.zip
109
+ ```
110
+
111
+ 末尾的平台标签(`windows11` / `windows10` / `macos` / `linux`)标明该备份由哪类主机生成。
112
+
113
+ ### 恢复时的安全机制
114
+
115
+ - 覆盖前,已有配置文件会生成带时间戳的 `.bak` 副本
116
+ - 已有 skills / extensions 目录会先改名为 `*-backup-<timestamp>`,再替换/合并
117
+ - 恢复前会展示计划,并要求确认
118
+ - 恢复成功后可选择 reload agent runtime,以应用 skills / extensions
119
+
120
+ ## 新机引导(Windows,尚未安装 Pi)
121
+
122
+ 若还没装 Pi,也可先用辅助脚本拉取最新 zip:
123
+
124
+ ```powershell
125
+ # 优先用环境变量,避免密钥进入 shell 历史
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"
129
+ .\pi-bootstrap.ps1
130
+ ```
131
+
132
+ 或使用占位符一行命令(运行前请替换):
133
+
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
+ ```
142
+
143
+ 之后安装 Pi,后续更新用 `/sync` → **Download Backup** 即可。
144
+
145
+ ## 安全建议
146
+
147
+ - WebDAV 凭证保存在本机 `~/.pi/agent/sync_config.json`
148
+ - 优先使用**应用专用密码**(不要用主账号密码)
149
+ - 更推荐环境变量引用:界面里密码填 `$PI_WEBDAV_PASS`,再在 shell profile 中 export
150
+ - 若开启相关选项,备份可能包含 `auth.json` / API key —— 请把 WebDAV 目录当敏感数据对待
151
+ - 切勿把真实 WebDAV 地址与凭证提交进 git
152
+
153
+ ## 故障排查
154
+
155
+ | 现象 | 处理 |
156
+ |------|------|
157
+ | HTTP 401 / 403 | 检查用户名密码;改用应用专用密码;确认 URL 含正确 DAV 路径 |
158
+ | PROPFIND 失败 / 列表为空 | 服务端可能禁用 PROPFIND;换 WebDAV 提供商;确认允许 Depth:1 |
159
+ | tar / zip 报错 | PATH 中需要可用的 `tar`(Windows 10+ 自带;Git Bash / WSL 亦可) |
160
+ | 恢复覆盖了本地内容 | 在 agent 目录旁查找 `*.bak-*` 与 `skills-backup-*` / `extensions-backup-*` |
161
+ | 恢复后插件不见了 | 重新执行 `pi install git:github.com/wuyaos/pi-packages` —— 归档会排除 sync 包自身 |
162
+
163
+ ## 目录结构
164
+
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 菜单截图
174
+ extensions/
175
+ sync/
176
+ index.ts # /sync 命令
177
+ _shared/
178
+ json-io.ts
179
+ enhanced-select.ts
180
+ spawn.ts
181
+ fetch-utils.ts
182
+ box-drawing.ts
183
+ ```
184
+
185
+ ## 更新日志
186
+
187
+ ### v1.0.1
188
+
189
+ - 备份 zip 文件名增加主机平台标签(`windows11` / `macos` / `linux` 等)
190
+ - 从 bootstrap 脚本示例中移除真实凭证
191
+ - 增加 MIT `LICENSE`,扩充 README(安全、恢复保护、故障排查、菜单截图)
192
+
193
+ ### v1.0.0
194
+
195
+ - 首次公开发布:基于 WebDAV 的交互式 `/sync` 菜单
196
+ - Upload Backup · Download Backup · Configure Sync Settings
197
+ - Windows 新机引导脚本
198
+
199
+ ## 许可证
200
+
201
+ MIT — 见 [LICENSE](./LICENSE)。
202
+
203
+ ## 致谢
204
+
205
+ 本开源项目已链接并获 [LINUX DO](https://linux.do) 社区认可。
Binary file
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Shared box-drawing utilities for TUI dashboards.
3
+ *
4
+ * Reusable across extensions (cost-tracker, session-manager, etc.).
5
+ * Import: import { … } from "../_shared/box-drawing"
6
+ */
7
+
8
+ import { truncateToWidth, visibleWidth } from "@earendil-works/pi-tui";
9
+
10
+ // ── Unicode box-drawing characters ─────────────────────────────────────
11
+
12
+ export const H = "─";
13
+ export const V = "│";
14
+ export const TL = "╭";
15
+ export const TR = "╮";
16
+ export const BL = "╰";
17
+ export const BR = "╯";
18
+ export const LT = "├";
19
+ export const RT = "┤";
20
+
21
+ // ── Border helpers ─────────────────────────────────────────────────────
22
+
23
+ /** Top border with optional title (title rendered by caller, not inserted here). */
24
+ export function topBorder(w: number, title: string, th: any): string {
25
+ const titleVis = visibleWidth(title);
26
+ const left = 2;
27
+ const right = w - 2 - left - titleVis;
28
+ return th.fg("accent", TL + H.repeat(left)) + title + th.fg("accent", H.repeat(Math.max(0, right)) + TR);
29
+ }
30
+
31
+ /** Simple top border without title. */
32
+ export function topBorderPlain(w: number, th: any): string {
33
+ return th.fg("accent", TL + H.repeat(w - 2) + TR);
34
+ }
35
+
36
+ /** Bottom border. */
37
+ export function bottomBorder(w: number, th: any): string {
38
+ return th.fg("borderMuted", BL + H.repeat(w - 2) + BR);
39
+ }
40
+
41
+ /** Mid horizontal divider. */
42
+ export function midBorder(w: number, th: any): string {
43
+ return th.fg("borderMuted", LT + H.repeat(w - 2) + RT);
44
+ }
45
+
46
+ /** Pad text to a fixed visible width, truncating if too long. */
47
+ export function sidePad(text: string, width: number): string {
48
+ const vis = visibleWidth(text);
49
+ if (vis >= width) return truncateToWidth(text, width);
50
+ return text + " ".repeat(width - vis);
51
+ }
52
+
53
+ /** Render a single content line inside a box: `│ content │`. */
54
+ export function lineInBox(content: string, boxWidth: number, th: any): string {
55
+ const contentW = boxWidth - 4;
56
+ if (contentW <= 0) return th.fg("borderMuted", V) + V;
57
+ return th.fg("borderMuted", V) + " " + sidePad(content, contentW) + " " + th.fg("borderMuted", V);
58
+ }