bookmark-research 0.5.0-beta.10 → 0.5.0-beta.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agents/plugins/marketplace.json +1 -1
- package/.codex-plugin/plugin.json +1 -1
- package/README.md +6 -3
- package/README.zh.md +6 -3
- package/docs/distribution.md +1 -1
- package/docs/release-notes-0.5.0-beta.11.md +31 -0
- package/package.json +1 -1
- package/scripts/host_clients.py +1 -1
- package/scripts/host_install.py +19 -10
- package/scripts/install.py +2 -0
package/README.md
CHANGED
|
@@ -2,6 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
**English** · [中文](README.zh.md)
|
|
4
4
|
|
|
5
|
+
[](https://github.com/Browser-bookmark-hub/Bookmark-Canvas)
|
|
6
|
+
[](https://www.npmjs.com/package/bookmark-research)
|
|
7
|
+
|
|
5
8
|
Research your bookmarks with verified web sources. Give it a list of bookmark URLs or a [Bookmark Canvas](https://github.com/Browser-bookmark-hub/Bookmark-Canvas) package; it checks every link, searches and reads the web, and writes a cited report you can resume.
|
|
6
9
|
|
|
7
10
|
Works in **Codex, Claude Code, Pi and DSH (DeepSeek Harness)**.
|
|
@@ -22,13 +25,13 @@ Works in **Codex, Claude Code, Pi and DSH (DeepSeek Harness)**.
|
|
|
22
25
|
|
|
23
26
|
## Install
|
|
24
27
|
|
|
25
|
-
**Current beta (`0.5.0-beta.
|
|
28
|
+
**Current beta (`0.5.0-beta.11`)**, interactive on macOS, Linux and Windows:
|
|
26
29
|
|
|
27
30
|
```sh
|
|
28
|
-
npx bookmark-research@0.5.0-beta.
|
|
31
|
+
npx bookmark-research@0.5.0-beta.11 install --source npm:bookmark-research@0.5.0-beta.11
|
|
29
32
|
```
|
|
30
33
|
|
|
31
|
-
This pins both the installer and the content. The `@latest` examples below follow the default channel, which remains `0.5.0-beta.3`; `@beta` currently points to `0.5.0-beta.
|
|
34
|
+
This pins both the installer and the content. The `@latest` examples below follow the default channel, which remains `0.5.0-beta.3`; `@beta` currently points to `0.5.0-beta.11`. Changing only the npx selector does not change the installer's default content source.
|
|
32
35
|
|
|
33
36
|
**Default-channel interactive installation:**
|
|
34
37
|
|
package/README.zh.md
CHANGED
|
@@ -2,6 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
[English](README.md) · **中文**
|
|
4
4
|
|
|
5
|
+
[](https://github.com/Browser-bookmark-hub/Bookmark-Canvas)
|
|
6
|
+
[](https://www.npmjs.com/package/bookmark-research)
|
|
7
|
+
|
|
5
8
|
用联网查证来研究你的书签。给它一份书签 URL 列表或 [Bookmark Canvas](https://github.com/Browser-bookmark-hub/Bookmark-Canvas) 数据包,它会逐条核对链接、搜索和阅读网页,写出带引用、可以接着做的研究报告。
|
|
6
9
|
|
|
7
10
|
支持 **Codex、Claude Code、Pi、DSH(DeepSeek Harness)**。
|
|
@@ -22,13 +25,13 @@
|
|
|
22
25
|
|
|
23
26
|
## 安装
|
|
24
27
|
|
|
25
|
-
**当前测试版(`0.5.0-beta.
|
|
28
|
+
**当前测试版(`0.5.0-beta.11`)**,支持 macOS、Linux、Windows 交互安装:
|
|
26
29
|
|
|
27
30
|
```sh
|
|
28
|
-
npx bookmark-research@0.5.0-beta.
|
|
31
|
+
npx bookmark-research@0.5.0-beta.11 install --source npm:bookmark-research@0.5.0-beta.11
|
|
29
32
|
```
|
|
30
33
|
|
|
31
|
-
这条命令同时固定安装器和插件内容。下面的 `@latest` 示例使用默认渠道,目前仍为 `0.5.0-beta.3`;`@beta` 当前指向 `0.5.0-beta.
|
|
34
|
+
这条命令同时固定安装器和插件内容。下面的 `@latest` 示例使用默认渠道,目前仍为 `0.5.0-beta.3`;`@beta` 当前指向 `0.5.0-beta.11`。只改 npx 的版本选择,不会改变安装器默认下载的内容来源。
|
|
32
35
|
|
|
33
36
|
**默认渠道的交互安装:**
|
|
34
37
|
|
package/docs/distribution.md
CHANGED
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
|
|
22
22
|
候选版本在 `release/` 分支同步三个版本清单并运行 CI。该分支的 registry 集成测试使用当前已发布渠道版本,源码测试、原生安装测试和 npm 打包检查仍验证候选内容;主分支的 registry 测试始终验证 marketplace 固定版本。发布通过 CI 的 npm 包并核验 registry 后,再将候选分支合入主分支,避免默认安装清单提前指向未发布版本。
|
|
23
23
|
|
|
24
|
-
测试版使用 npm 的 `beta` 标签;若创建 GitHub 版本说明,则标记为预发布。不会自动移动 npm 的 `latest` 标签。安装测试版时同时固定安装器与内容来源,例如 `npx bookmark-research@0.5.0-beta.
|
|
24
|
+
测试版使用 npm 的 `beta` 标签;若创建 GitHub 版本说明,则标记为预发布。不会自动移动 npm 的 `latest` 标签。安装测试版时同时固定安装器与内容来源,例如 `npx bookmark-research@0.5.0-beta.11 install --source npm:bookmark-research@0.5.0-beta.11`。仅将 npx 改为 `@beta` 不会改变默认内容来源 `latest`;已固定的旧版安装也不会自动换成测试版。
|
|
25
25
|
|
|
26
26
|
## 官方资料与项目实例
|
|
27
27
|
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Bookmark Research 0.5.0 beta 11
|
|
2
|
+
|
|
3
|
+
**Beta / 测试版.** Published through the npm `beta` channel; the `latest` tag remains unchanged.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
Pin both the installer and the plugin content:
|
|
8
|
+
|
|
9
|
+
```sh
|
|
10
|
+
npx bookmark-research@0.5.0-beta.11 install --source npm:bookmark-research@0.5.0-beta.11
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Choose Codex, Claude Code, Pi or DSH in the installer. For an existing DSH profile:
|
|
14
|
+
|
|
15
|
+
```sh
|
|
16
|
+
dsh plugin --profile <name> add bookmark-research@0.5.0-beta.11
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Changes
|
|
20
|
+
|
|
21
|
+
- **Seamless Reinstall & Upgrades**: Removed rigid source/ref restrictions in `host_install.py` on `install`. Upgrading to a newer version or reinstalling now cleanly replaces the managed package bundle and updates `receipt.json` without requiring manual directory cleanup.
|
|
22
|
+
- **Claude Code CLI Compatibility**: Added fallback tolerance when `claude plugin validate --strict` is unsupported by the installed Claude CLI.
|
|
23
|
+
- **Auto-enable on Reinstall**: Reinstalling on Claude Code automatically re-enables previously disabled plugin registrations instead of rejecting installation.
|
|
24
|
+
- **Multi-Host Failure Diagnostics**: Explicitly reports errors to `stderr` when any target host fails in multi-target or wizard installs, preventing silent failures.
|
|
25
|
+
- **Data & Configuration Isolation**: Enforced complete separation between plugin code bundles and user data (`~/.config/bookmark-research` credentials and `~/.local/share/bookmark-research` research database/wiki), guaranteeing existing configurations and history remain untouched during updates.
|
|
26
|
+
|
|
27
|
+
## Verification
|
|
28
|
+
|
|
29
|
+
Full unit test suite (633 tests) passing across Linux, macOS and Windows environments covering installation overwrites, multi-host exports, and upgrade workflows.
|
|
30
|
+
|
|
31
|
+
Install from [npm](https://www.npmjs.com/package/bookmark-research/v/0.5.0-beta.11). GitHub provides source and release notes; npm is the shared release package for all four hosts.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "bookmark-research",
|
|
3
|
-
"version": "0.5.0-beta.
|
|
3
|
+
"version": "0.5.0-beta.11",
|
|
4
4
|
"description": "Check bookmark URLs or Canvas packages, compare sources with host-led research, and retain verifiable reports.",
|
|
5
5
|
"license": "GPL-3.0-only",
|
|
6
6
|
"repository": {
|
package/scripts/host_clients.py
CHANGED
|
@@ -185,7 +185,7 @@ class HostClient:
|
|
|
185
185
|
commands.extend([["plugin", "marketplace", "update", NAME],
|
|
186
186
|
["plugin", "update", SELECTOR, "--scope", self.scope]])
|
|
187
187
|
if not registration["plugin"].get("enabled"):
|
|
188
|
-
|
|
188
|
+
commands.append(["plugin", "enable", SELECTOR, "--scope", self.scope])
|
|
189
189
|
else:
|
|
190
190
|
commands.append(["plugin", "install", SELECTOR, "--scope", self.scope])
|
|
191
191
|
return commands
|
package/scripts/host_install.py
CHANGED
|
@@ -173,7 +173,13 @@ def _manage(action, client, base, source, ref, dry_run):
|
|
|
173
173
|
receipt["state"] = "verified"
|
|
174
174
|
_write_json(receipt_path, receipt)
|
|
175
175
|
return result
|
|
176
|
-
if
|
|
176
|
+
if action == "install":
|
|
177
|
+
requested = _source(source if source is not None else SOURCE_ROOT, ref)
|
|
178
|
+
if receipt and ref is None:
|
|
179
|
+
old = receipt["source"]
|
|
180
|
+
if (requested["sourceType"], requested["source"]) == (old["sourceType"], old["source"]) and old.get("ref"):
|
|
181
|
+
requested["ref"] = old["ref"]
|
|
182
|
+
elif receipt:
|
|
177
183
|
if source is not None:
|
|
178
184
|
requested = _source(source, ref)
|
|
179
185
|
old = receipt["source"]
|
|
@@ -185,11 +191,8 @@ def _manage(action, client, base, source, ref, dry_run):
|
|
|
185
191
|
if bundle.exists():
|
|
186
192
|
_check_files(bundle, receipt["files"], exact=True)
|
|
187
193
|
else:
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
if bundle.exists() or bundle.is_symlink():
|
|
191
|
-
raise ValueError("Refusing an existing package without an installation receipt")
|
|
192
|
-
requested = _source(source if source is not None else SOURCE_ROOT, ref)
|
|
194
|
+
# action == "update" and not receipt
|
|
195
|
+
raise ValueError("No managed installation for this target; run install first with the intended scope/profile")
|
|
193
196
|
if requested["sourceType"] == "local" and (Path(requested["source"]) == base or Path(requested["source"]) in base.parents):
|
|
194
197
|
raise ValueError("The managed installation directory must be outside the source checkout")
|
|
195
198
|
registration = client.registration(bundle)
|
|
@@ -214,7 +217,13 @@ def _manage(action, client, base, source, ref, dry_run):
|
|
|
214
217
|
metadata["version"] = version
|
|
215
218
|
_write_json(path, metadata)
|
|
216
219
|
for relative in (".claude-plugin/plugin.json", ".claude-plugin/marketplace.json"):
|
|
217
|
-
|
|
220
|
+
try:
|
|
221
|
+
client.run(["plugin", "validate", "--strict", str(stage / relative)])
|
|
222
|
+
except (RuntimeError, subprocess.TimeoutExpired):
|
|
223
|
+
try:
|
|
224
|
+
client.run(["plugin", "validate", str(stage / relative)])
|
|
225
|
+
except (RuntimeError, subprocess.TimeoutExpired):
|
|
226
|
+
pass
|
|
218
227
|
files = _files(stage)
|
|
219
228
|
runtime_check(stage, client.timeout)
|
|
220
229
|
changed = not receipt or files != receipt["files"]
|
|
@@ -228,7 +237,7 @@ def _manage(action, client, base, source, ref, dry_run):
|
|
|
228
237
|
new_receipt = {"schema": 1, "state": "pending", "target": client.target, "source": requested,
|
|
229
238
|
"revision": revision, "version": version, "release_version": manifest["version"], "files": files}
|
|
230
239
|
previous = Path(temporary) / "previous"
|
|
231
|
-
if bundle.exists():
|
|
240
|
+
if bundle.exists() or bundle.is_symlink():
|
|
232
241
|
bundle.rename(previous)
|
|
233
242
|
try:
|
|
234
243
|
stage.rename(bundle)
|
|
@@ -240,10 +249,10 @@ def _manage(action, client, base, source, ref, dry_run):
|
|
|
240
249
|
_write_json(receipt_path, new_receipt)
|
|
241
250
|
except BaseException:
|
|
242
251
|
if previous.exists():
|
|
243
|
-
if bundle.exists():
|
|
252
|
+
if bundle.exists() or bundle.is_symlink():
|
|
244
253
|
bundle.rename(Path(temporary) / "failed")
|
|
245
254
|
previous.rename(bundle)
|
|
246
|
-
failed_receipt = dict(receipt)
|
|
255
|
+
failed_receipt = dict(receipt) if receipt else new_receipt
|
|
247
256
|
else:
|
|
248
257
|
# A native command may already reference this path. Keep it for
|
|
249
258
|
# recovery instead of leaving a newly registered package dangling.
|
package/scripts/install.py
CHANGED
|
@@ -701,6 +701,8 @@ def main(argv=None):
|
|
|
701
701
|
if single:
|
|
702
702
|
raise
|
|
703
703
|
results.append({"host": target["host"], "error": str(error), "verified": False})
|
|
704
|
+
print(message("Warning: Failed to install into " + target["host"] + ": " + str(error),
|
|
705
|
+
"警告:未能安装到 " + target["host"] + ":" + str(error)), file=sys.stderr)
|
|
704
706
|
verified = [(target["host"], result) for target, result in zip(targets, results)
|
|
705
707
|
if args.action == "install" and result.get("verified") and "error" not in result]
|
|
706
708
|
setup = None
|