@vetta-org/plugin-cli 0.1.5 → 0.1.7

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/CHANGELOG.md CHANGED
@@ -2,6 +2,39 @@
2
2
 
3
3
  All notable changes to `@vetta-org/plugin-cli` are documented in this file.
4
4
 
5
+ ## Unreleased
6
+
7
+ ### Changed
8
+
9
+ - `add` and `add .` now use the dedicated `.vettapkg` plugin package format. Existing `.zip` files remain accepted as a compatibility import path.
10
+
11
+ - `add` now identifies itself to Desktop so ability lifecycle logs distinguish CLI installs from manual package imports and marketplace installs.
12
+
13
+ - `sync --check` accepts schema v3 plugin releases without local `dist/` and validates release metadata for independently listed and bundle-only plugins. The marketplace publication gate separately verifies the referenced App releases and artifact digests.
14
+
15
+ ## [0.1.6] — 2026-09-14
16
+
17
+ ### Fixed
18
+
19
+ - **`init --refresh-guide` 不再覆盖手写的 `AGENTS.md`**。此前它无条件重写,而 `docs` 又把「没有
20
+ 版本戳」判成过期并给出这条命令——两者合起来是在引导用户删掉自己的文件。已知造成一个能力市场
21
+ 仓库根部 443 行手写市场规范被整份替换。
22
+
23
+ 没有 `vetta-guide-revision` 标记的文件现在一律拒绝覆盖(退出码 7),要覆盖得显式 `--force`;
24
+ 新增 `--dry-run` 把新模板打到 stdout 供人工合并。`docs` 对无标记文件改口为「看起来是手写的,
25
+ 请手动合并」,只有**带标记且落后**的才会被称作 stale 并给出刷新命令。
26
+
27
+ - 说明书标题不再印出未解析的本地化占位符。`plugin.json` 的 `name` 写成 `%plugin.name%` 时,按
28
+ `defaultLocale` 从 `locales/` 解析;解析不到退回插件 id。
29
+
30
+ - 说明书的命令清单改为读 `package.json` 的 `scripts`,只列真实存在的。老工程和自定义工程未必有
31
+ `dev` / `install:vetta`,照着跑只会得到一句 "Missing script";没有 `install:vetta` 时改列
32
+ `vetta-plugin-cli add .`。
33
+
34
+ - 更正 hub `AGENTS.md` 对 `sync` 的两处描述:`marketplaceVersion` 只在 semver 或纯整数时才推得动
35
+ (`YYYY.MM.DD-NN` 这类会报出来要手改),`config.api_version` / `permissions` / `commands`
36
+ **不回填**——宿主用 `plugin.json` 整个重算 `config`,`sync` 只在副本与真源不符时提醒删掉。
37
+
5
38
  ## [0.1.5] — 2026-09-14
6
39
 
7
40
  ### Changed
package/README.md CHANGED
@@ -28,6 +28,11 @@ is purely derived and holds no user content — leaving source, manifest and con
28
28
  the id and display name from the `plugin.json` already on disk. At a marketplace root it rewrites the
29
29
  hub brief instead.
30
30
 
31
+ It refuses to overwrite a brief that carries no `vetta-guide-revision` marker — that file is
32
+ indistinguishable from a hand-written one, and a marketplace root often holds a hand-written spec.
33
+ Use `--dry-run` to print the current template for manual merging, or `--force` to replace the file
34
+ outright.
35
+
31
36
  You will rarely have to remember this: the brief carries a revision stamp, and `docs` compares it on
32
37
  every run and says outright when it is behind. The brief itself holds no rules — those live in the
33
38
  manual, which travels with the SDK — so it changes seldom, and a project that refreshes once keeps
@@ -64,6 +69,13 @@ remotely: the host refuses to sync an entry whose version differs from the packa
64
69
  install a plugin whose built entry is missing from the published directory, and clients silently
65
70
  skip an update when `marketplaceVersion` did not change. `sync` reconciles all three.
66
71
 
72
+ For marketplace schema v3, a plugin may instead list immutable `releases[]` with HTTPS `.vettapkg` URLs
73
+ and SHA-256 digests. Its `source.path` then contains presentation files only. `sync --check`
74
+ checks release metadata and reconciles the catalog version with the highest release; the
75
+ Desktop installation verifies the downloaded package. Before advancing a stable marketplace ref,
76
+ run the publication check from a fixed `open-vetta` checkout as described in
77
+ [`docs/open-marketplace.md`](../../../docs/open-marketplace.md).
78
+
67
79
  ## Find the manual
68
80
 
69
81
  ```bash
@@ -96,8 +108,8 @@ The npm package is fetched with lifecycle scripts disabled. The CLI extracts onl
96
108
  Local archives and HTTP(S) archives use the same command:
97
109
 
98
110
  ```bash
99
- npx @vetta-org/plugin-cli add ./release/demo-1.0.0.zip
100
- npx @vetta-org/plugin-cli add https://example.com/demo-1.0.0.zip
111
+ npx @vetta-org/plugin-cli add ./release/demo-1.0.0.vettapkg
112
+ npx @vetta-org/plugin-cli add https://example.com/demo-1.0.0.vettapkg
101
113
  ```
102
114
 
103
115
  When an update is installed as a pending version, apply it through the running Desktop host instead of
@@ -120,12 +132,12 @@ The published plugin package must include a standard Desktop plugin archive and
120
132
  {
121
133
  "name": "@example/vetta-plugin-demo",
122
134
  "version": "1.0.0",
123
- "files": ["release/vetta-plugin.zip"],
135
+ "files": ["release/vetta-plugin.vettapkg"],
124
136
  "vetta": {
125
137
  "schemaVersion": 1,
126
138
  "type": "desktop-plugin",
127
139
  "pluginId": "demo",
128
- "archive": "release/vetta-plugin.zip"
140
+ "archive": "release/vetta-plugin.vettapkg"
129
141
  }
130
142
  }
131
143
  ```
@@ -19,11 +19,13 @@
19
19
  * `docs` 读它来判断一份说明书是不是旧的——没有这个戳,「该不该刷新」就只能靠人记得,而这
20
20
  * 恰恰是它凝固的原因。**改动模板内容时必须一并推进它**,否则存量工程不会收到提示。
21
21
  */
22
- export declare const AGENTS_GUIDE_REVISION = 2;
22
+ export declare const AGENTS_GUIDE_REVISION = 3;
23
23
  /** 从一份 AGENTS.md 正文里读出版本戳;不是本模板生成的(或早于版本戳)时返回 undefined。 */
24
24
  export declare function readAgentsGuideRevision(content: string): number | undefined;
25
25
  export declare function renderAgentsGuide(input: {
26
26
  pluginId: string;
27
27
  displayName: string;
28
+ /** 工程 package.json 里实际存在的 script 名;缺省按脚手架的那套算。 */
29
+ scripts?: readonly string[];
28
30
  }): string;
29
31
  //# sourceMappingURL=agents-template.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"agents-template.d.ts","sourceRoot":"","sources":["../src/agents-template.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,IAAI,CAAC;AAEvC,4HAA4D;AAC5D,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAI3E;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAwD1F","sourcesContent":["/**\n * 随脚手架落地的 Agent 说明书。\n *\n * 它替代的是「把开发知识写死在工作台插件的 skill 里」那套做法:那份 skill 只有 Vetta\n * 自己的 Agent 读得到,而且每加一个能力就要改一次、还要等 App 发版才到用户手里。这里\n * 反过来——工程自带说明书,说明书只说「去哪读手册」,手册随 SDK 版本进 node_modules。\n * 因此任何 Agent(Claude Code、Cursor、Vetta 自己)在任何陌生目录都能自举,而且读到的\n * 永远是这个工程实际编译所针对的那份合同。\n *\n * **这里刻意只留指引,不留知识。** 写进这个文件的每一条规则都会在所有存量工程里就地凝固:\n * 它是 `init` 当天的快照,之后既不会自更新,用户也没有理由回来看它。规则属于手册——手册\n * 随 SDK 升级一起到位。这个文件越薄,需要回头迁移老仓库的理由就越少。\n *\n * 单位是插件目录本身:外面是能力市场仓库、是单插件仓库、还是一堆别的东西,都不影响这里。\n */\n\n/**\n * 说明书的版本戳。\n *\n * `docs` 读它来判断一份说明书是不是旧的——没有这个戳,「该不该刷新」就只能靠人记得,而这\n * 恰恰是它凝固的原因。**改动模板内容时必须一并推进它**,否则存量工程不会收到提示。\n */\nexport const AGENTS_GUIDE_REVISION = 2;\n\n/** 从一份 AGENTS.md 正文里读出版本戳;不是本模板生成的(或早于版本戳)时返回 undefined。 */\nexport function readAgentsGuideRevision(content: string): number | undefined {\n\tconst match = /<!--\\s*vetta-guide-revision:\\s*(\\d+)\\s*-->/.exec(content);\n\tif (!match) return undefined;\n\treturn Number(match[1]);\n}\n\nexport function renderAgentsGuide(input: { pluginId: string; displayName: string }): string {\n\treturn `<!-- vetta-guide-revision: ${AGENTS_GUIDE_REVISION} -->\n# ${input.displayName}\n\nVetta 桌面插件工程(插件 id:\\`${input.pluginId}\\`)。\n\n**本文件不讲规则,只告诉你去哪读。** 规则在手册里,手册随 SDK 升级;写在这里的任何一条都会\n停在这个工程创建那天。两者冲突时一律以手册为准。\n\n## 第一步:装依赖,找到手册\n\n\\`\\`\\`bash\nnpm install\nnpx vetta-plugin-cli docs --check-latest\n\\`\\`\\`\n\n\\`npm install\\` 必须先跑:\\`vetta-plugin-cli\\` 是 \\`@vetta-org/plugin-cli\\` 的命令名,装完才在\n\\`node_modules/.bin\\` 里。还没装就想跑,用全名 \\`npx @vetta-org/plugin-cli docs\\`。\n\n它打印手册目录的**绝对路径**、手册对应的 SDK 版本,以及本工程与所属 hub 的位置。\n**不要硬编码这个路径**:工作区可能把依赖提升到仓库根,一仓多插件时各插件还可能钉不同版本。\n\n输出里出现 \\`Manual is behind\\` 或 \\`This brief is stale\\` 就按它给的命令升级,再重跑一次。\n\n## 第二步:按顺序读手册\n\n| 顺序 | 文件 | 何时读 |\n| --- | --- | --- |\n| 1 | \\`README.md\\` | **总是先读**:能力矩阵、信任模型、**不可违反的红线**、导航 |\n| 2 | \\`getting-started.md\\` | 首次写代码、构建、安装调试 |\n| 3 | \\`manifest.md\\` | 写/改 \\`plugin.json\\`、贡献智能体与团队 |\n| 4 | \\`permissions.md\\` | 选定权限列表之前 |\n| 5 | 按扩展点选读 | \\`ui-slots.md\\` / \\`conversation-and-agent.md\\` / \\`message-cards.md\\` / \\`mcp.md\\` / \\`ai.md\\` / \\`browser.md\\` / \\`app-actions.md\\` / \\`styling-and-pitfalls.md\\` |\n\n实现任一扩展点**之前**再读对应那章,不要凭记忆写 SDK API——这套合同变化很快。\n\n## 常用命令\n\n\\`\\`\\`bash\nnpm run dev # Vite + Module Federation 开发服务器\nnpm run build # 产出 dist/\nnpm run install:vetta # 打包并装进正在运行的 Vetta(需要 Vetta 已启动)\n\nnpx vetta-plugin-cli watch # 热更新:宿主改从本工程目录加载,改完即生效\nnpx vetta-plugin-cli reload ${input.pluginId} # 装完提示有 pending 版本时用它\nnpx vetta-plugin-cli uninstall # 卸载(省略 id 即本工程对应的插件)\nnpx vetta-plugin-cli sync # 在 hub 仓库根上跑:把索引与各能力目录对账\n\\`\\`\\`\n\n细节都在 \\`getting-started.md\\`。\\`docs\\` 打印了 \\`Marketplace index:\\` 就说明这个目录之上有能力\n市场索引,改完 \\`version\\` / \\`permissions\\` / \\`pluginApiVersion\\` 后要回仓库根跑 \\`sync\\`。\n\n## 信息不足时\n\n插件 id、展示名、要用哪些权限、功能边界、是否立刻安装——**问用户**,不要自己假定。\n`;\n}\n"]}
1
+ {"version":3,"file":"agents-template.d.ts","sourceRoot":"","sources":["../src/agents-template.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,IAAI,CAAC;AAEvC,4HAA4D;AAC5D,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAI3E;AA4BD,wBAAgB,iBAAiB,CAAC,KAAK,EAAE;IACxC,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,4FAAkD;IAClD,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC5B,GAAG,MAAM,CAiDT","sourcesContent":["/**\n * 随脚手架落地的 Agent 说明书。\n *\n * 它替代的是「把开发知识写死在工作台插件的 skill 里」那套做法:那份 skill 只有 Vetta\n * 自己的 Agent 读得到,而且每加一个能力就要改一次、还要等 App 发版才到用户手里。这里\n * 反过来——工程自带说明书,说明书只说「去哪读手册」,手册随 SDK 版本进 node_modules。\n * 因此任何 Agent(Claude Code、Cursor、Vetta 自己)在任何陌生目录都能自举,而且读到的\n * 永远是这个工程实际编译所针对的那份合同。\n *\n * **这里刻意只留指引,不留知识。** 写进这个文件的每一条规则都会在所有存量工程里就地凝固:\n * 它是 `init` 当天的快照,之后既不会自更新,用户也没有理由回来看它。规则属于手册——手册\n * 随 SDK 升级一起到位。这个文件越薄,需要回头迁移老仓库的理由就越少。\n *\n * 单位是插件目录本身:外面是能力市场仓库、是单插件仓库、还是一堆别的东西,都不影响这里。\n */\n\n/**\n * 说明书的版本戳。\n *\n * `docs` 读它来判断一份说明书是不是旧的——没有这个戳,「该不该刷新」就只能靠人记得,而这\n * 恰恰是它凝固的原因。**改动模板内容时必须一并推进它**,否则存量工程不会收到提示。\n */\nexport const AGENTS_GUIDE_REVISION = 3;\n\n/** 从一份 AGENTS.md 正文里读出版本戳;不是本模板生成的(或早于版本戳)时返回 undefined。 */\nexport function readAgentsGuideRevision(content: string): number | undefined {\n\tconst match = /<!--\\s*vetta-guide-revision:\\s*(\\d+)\\s*-->/.exec(content);\n\tif (!match) return undefined;\n\treturn Number(match[1]);\n}\n\n/**\n * 渲染常用命令块。\n *\n * 只列工程真有的 script:模板写死 `npm run dev` / `install:vetta`,老工程和自定义工程未必有,\n * 照着跑就是一句 \"Missing script\"。读不到 package.json 时退回 CLI 直连命令——它们不依赖工程脚本。\n */\nfunction renderCommands(pluginId: string, scripts: readonly string[]): string {\n\tconst known: readonly (readonly [string, string])[] = [\n\t\t[\"dev\", \"npm run dev # 开发服务器\"],\n\t\t[\"build\", \"npm run build # 产出 dist/\"],\n\t\t[\"install:vetta\", \"npm run install:vetta # 打包并装进正在运行的 Vetta(需要 Vetta 已启动)\"],\n\t];\n\tconst lines = known.filter(([name]) => scripts.includes(name)).map(([, line]) => line);\n\tif (!scripts.includes(\"install:vetta\")) {\n\t\tlines.push(\"npx vetta-plugin-cli add . # 打包并装进正在运行的 Vetta\");\n\t}\n\treturn [\n\t\t...lines,\n\t\t\"\",\n\t\t\"npx vetta-plugin-cli watch # 热更新:宿主改从本工程目录加载,改完即生效\",\n\t\t`npx vetta-plugin-cli reload ${pluginId} # 装完提示有 pending 版本时用它`,\n\t\t\"npx vetta-plugin-cli uninstall # 卸载(省略 id 即本工程对应的插件)\",\n\t\t\"npx vetta-plugin-cli sync # 在 hub 仓库根上跑:把索引与各能力目录对账\",\n\t].join(\"\\n\");\n}\n\nexport function renderAgentsGuide(input: {\n\tpluginId: string;\n\tdisplayName: string;\n\t/** 工程 package.json 里实际存在的 script 名;缺省按脚手架的那套算。 */\n\tscripts?: readonly string[];\n}): string {\n\treturn `<!-- vetta-guide-revision: ${AGENTS_GUIDE_REVISION} -->\n# ${input.displayName}\n\nVetta 桌面插件工程(插件 id:\\`${input.pluginId}\\`)。\n\n**本文件不讲规则,只告诉你去哪读。** 规则在手册里,手册随 SDK 升级;写在这里的任何一条都会\n停在这个工程创建那天。两者冲突时一律以手册为准。\n\n## 第一步:装依赖,找到手册\n\n\\`\\`\\`bash\nnpm install\nnpx vetta-plugin-cli docs --check-latest\n\\`\\`\\`\n\n\\`npm install\\` 必须先跑:\\`vetta-plugin-cli\\` 是 \\`@vetta-org/plugin-cli\\` 的命令名,装完才在\n\\`node_modules/.bin\\` 里。还没装就想跑,用全名 \\`npx @vetta-org/plugin-cli docs\\`。\n\n它打印手册目录的**绝对路径**、手册对应的 SDK 版本,以及本工程与所属 hub 的位置。\n**不要硬编码这个路径**:工作区可能把依赖提升到仓库根,一仓多插件时各插件还可能钉不同版本。\n\n输出里出现 \\`Manual is behind\\` 或 \\`This brief is stale\\` 就按它给的命令升级,再重跑一次。\n\n## 第二步:按顺序读手册\n\n| 顺序 | 文件 | 何时读 |\n| --- | --- | --- |\n| 1 | \\`README.md\\` | **总是先读**:能力矩阵、信任模型、**不可违反的红线**、导航 |\n| 2 | \\`getting-started.md\\` | 首次写代码、构建、安装调试 |\n| 3 | \\`manifest.md\\` | 写/改 \\`plugin.json\\`、贡献智能体与团队 |\n| 4 | \\`permissions.md\\` | 选定权限列表之前 |\n| 5 | 按扩展点选读 | \\`ui-slots.md\\` / \\`conversation-and-agent.md\\` / \\`message-cards.md\\` / \\`mcp.md\\` / \\`ai.md\\` / \\`browser.md\\` / \\`app-actions.md\\` / \\`styling-and-pitfalls.md\\` |\n\n实现任一扩展点**之前**再读对应那章,不要凭记忆写 SDK API——这套合同变化很快。\n\n## 常用命令\n\n\\`\\`\\`bash\n${renderCommands(input.pluginId, input.scripts ?? [\"dev\", \"build\", \"install:vetta\"])}\n\\`\\`\\`\n\n细节都在 \\`getting-started.md\\`。\\`docs\\` 打印了 \\`Marketplace index:\\` 就说明这个目录之上有能力\n市场索引,改完 \\`version\\` / \\`permissions\\` / \\`pluginApiVersion\\` 后要回仓库根跑 \\`sync\\`。\n\n## 信息不足时\n\n插件 id、展示名、要用哪些权限、功能边界、是否立刻安装——**问用户**,不要自己假定。\n`;\n}\n"]}