@coda-console/plugin-check 0.4.4 → 0.4.5

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 CHANGED
@@ -20,23 +20,19 @@ templates/panel/ 最小的面板插件:一张卡片、一条进度条
20
20
  bin/、check/ 契约检查(仓库根的 package.json 就是它,@coda-console/plugin-check)
21
21
  test/ 检查包的测试;test/plugins/ 是各插件的测试(插件目录里只放运行要用的文件)
22
22
  docs/agent-protocol.md Coda 接入协议正文的公开副本
23
- .coda/workflows/ 本仓库自己的流程:sync-coda 把内置插件的副本同步进 Coda
24
23
  ```
25
24
 
26
25
  ## Coda 自带的插件
27
26
 
28
27
  `codex`、`claude`、`kimi`、`grok`、`opencode`、`codex-accounts`、`review` 是 Coda 内置的插件,源码从此在这里维护。
29
- Coda 仓库里的 `backend/src/resources/plugins/<id>/` 是本仓库**某个提交的只读副本**:Coda 的同步脚本按它的锁文件
30
- (记着本仓库的提交与每个目录的树哈希)把那个提交里的 `plugins/<id>` 原样复制过去,新机器、离线首启都带着它们。
28
+ 合进 main 后它们发布为 npm 包 `@coda-console/<id>`([npm 发布](#npm-发布)),Coda 后端的 `package.json` 把它们写成钉住版本号的依赖,
29
+ 随后端的 `npm ci` 装好,新机器首次启动就带着它们。
31
30
 
32
- - **改它们先在这里提 PR、合并**,再在 Coda 里同步到那个提交;不要直接改 Coda 里的副本(Coda 的测试会核对副本与锁文件一致)。
33
- 同步由本仓库的部署流程 `sync-coda`(`.coda/workflows/sync-coda.bpmn`、`scripts/sync-coda.mjs`)做:合并时勾选「部署」,
34
- 它在合并提交上运行 Coda 的同步脚本,推到 Coda 的分支 `sync/coda-plugins` 并开 PR(开着的就只更新),PR 由开这边 PR 的会话负责、走 Coda 的 PR 流程;
35
- 副本没有变化就什么都不做。也可以单独发起,同步默认分支的最新提交。
31
+ - **改它们先在这里提 PR、合并**,等发布流程发出新版本,再在 Coda 里把依赖升到那个版本(Coda 的 docs/development.md「coda-plugins 维护的内置插件」)。
36
32
  - **改了哪个插件就升哪个插件的 `version`**(`plugins/<id>/` 下任何文件,含 `package-lock.json`;只改 `test/` 不用):Coda 的插件页与遥测按版本认插件。
37
33
  CI 在 PR 上运行 `node scripts/check-versions.mjs origin/<目标分支>` 核对;Dependabot 升 CLI、SDK 的 PR 也要补一个升版本的提交。
38
- - Coda 的「检查更新」可以从这里装同一插件的新提交,盖过内置副本;只有本仓库的 `plugins/<id>` 这个来源能用这些名字。
39
- - 测的是插件自己代码的用例在 `test/plugins/<id>/`;把 Coda 与入口合在一起测的(启动 Coda 后端、写进 Coda 的存储)留在 Coda,对副本跑。
34
+ - Coda 的「检查更新」可以从 npm 装同一个包的新版本,盖过 Coda 带的版本;只有 `@coda-console/<id>` 这个包能用这些名字。
35
+ - 测的是插件自己代码的用例在 `test/plugins/<id>/`;把 Coda 与入口合在一起测的(启动 Coda 后端、写进 Coda 的存储)留在 Coda,对它装的 npm 包跑。
40
36
  `review` 是一个流程,要 Coda 的流程引擎才跑得起来,它的用例都在 Coda。
41
37
 
42
38
  | 插件 | npm 依赖(与 Coda 后端同版本) | 运行机上另要 |
@@ -88,7 +84,7 @@ Codex 用普通 ACP 选择型配置项 `service-tier`(「速度」)报告速
88
84
 
89
85
  `codex-accounts` 2.0.0 自己管理账号,不需要预装账号管理器或 Python。安装时 Coda 安装它的 npm 依赖和
90
86
  `codex` 插件;本版接管额度、登录入口和续期通知的配套入口是 `codex` 1.1.0。已有安装升级时两个插件一起更新,
91
- Coda 内置副本同步时也一起带上这两个目录。
87
+ Coda 升级依赖时也一起升这两个包。
92
88
 
93
89
  - 首次使用会把运行机 `$CODEX_HOME/auth.json`(默认 `~/.codex/auth.json`)里的 ChatGPT 登录导入插件,作为第一个
94
90
  普通受控账号并默认选用。原文件保留;之后的凭据、续期与选择都由插件维护,原登录文件后续变化不会替换受控账号。
@@ -139,15 +135,15 @@ Coda 按这个通用类别显示「额度不足」,不触发服务故障重试
139
135
  Codex 会话、面板与登录用的 Codex CLI 就是 `codex` 插件依赖的 `@openai/codex`;Claude 的是 `claude` 插件依赖的
140
136
  `@anthropic-ai/claude-agent-sdk`。插件按包名从自己的依赖里找它们,Coda 不另给路径。升级就是改这两个版本:
141
137
  Dependabot(`.github/dependabot.yml`)每周为它们各开一个 PR,连同 `package-lock.json` 一起改;合并后在 Coda「设置 › 插件」
142
- 对该插件点「检查更新」,内置副本随 Coda 同步到新提交。升 `@openai/codex` 时 codex-acp 经 `overrides` 跟着用新版本,
143
- 合并前用真实会话跑一轮。
138
+ 对该插件点「检查更新」,Coda 随后把依赖升到发布的新版本。升 `@openai/codex` 时 codex-acp 经 `overrides` 跟着用新版本,
139
+ Coda 升 `@coda-console/codex` 时也要改它根上的同一条 overrides(npm 只认根的,Coda 的测试会核对);合并前用真实会话跑一轮。
144
140
 
145
141
  ## 在 Coda 里安装
146
142
 
147
143
  「设置 › 插件 › 从仓库添加…」:
148
144
 
149
145
  1. **仓库**填 `coda-console/coda-plugins`(或 `https://github.com/coda-console/coda-plugins`);**版本**留空是默认分支,也可以填分支、标签或完整的提交号。
150
- 2. **读取**:Coda 拉取那个提交,把仓库根与两层以内 `package.json` 带 `contributes` 的目录各列成一个插件——这个仓库里是 `plugins/` 下的七个与两个模板。内置插件可以从自身来源单独更新;卸载后,也可以从其他来源安装同名替代插件。
146
+ 2. **读取**:Coda 拉取那个提交,把仓库根与两层以内 `package.json` 带 `contributes` 的目录各列成一个插件——这个仓库里是 `plugins/` 下的七个与两个模板。Coda 内置的那几个只能从 npm 上自己的包单独更新;在 Coda 里先卸载它,才能从这里装同名的。
151
147
  3. 选一个,确认里逐条列出它会运行的命令(Agent 的 `command`、面板的命令与动作),确认就是批准:这些命令以你的账户在空间里每台机器上运行,Coda 不做隔离,只装你信任的来源。
152
148
 
153
149
  **Coda 只认提交**:安装时钉在读取到的那个提交上,每台机器各自取同一个提交。「检查更新」用记下的仓库与版本再读一次,提交变了才有更新;
package/check/coda.mjs CHANGED
@@ -136,11 +136,11 @@ export const DEPTH = 2;
136
136
  // `npm ci` in the plugin's version directory.
137
137
  export const NPM = ['dependencies', 'optionalDependencies'];
138
138
  export const NPM_LOCK = 'package-lock.json';
139
- // Those whose copies in Coda are taken from `plugins/<id>` of this repository (backend/src/resources/plugins.lock.json): a
140
- // version from the same repository and directory may be installed over a copy. Other sources may use the same ID once
141
- // the built-in plugin is uninstalled; only the target backend can check its installed state (builtinProblem).
142
- export const BUILTIN_HERE = ['claude', 'codex', 'codex-accounts', 'grok', 'kimi', 'opencode'];
143
- export const BUILTIN_REPOSITORY = /(^|[/:])coda-console\/coda-plugins(\.git)?\/?$/i;
139
+ // Those kept in `plugins/<id>` here that Coda ships as npm dependencies, `@coda-console/<id>` (docs/plugins.md「内置插件的来源」):
140
+ // a version of the same package may be installed over Coda's. Other sources may use the same ID once the built-in plugin is
141
+ // uninstalled; only the target backend can check its installed state (builtinProblem).
142
+ export const BUILTIN_HERE = ['claude', 'codex', 'codex-accounts', 'grok', 'kimi', 'opencode', 'review'];
143
+ export const BUILTIN_SCOPE = '@coda-console/';
144
144
  // An agent, a concurrency group and a command are one plugin's (catalogProblem, claims). Those the built-in plugins declare, by
145
145
  // plugin; and `claude`, the agent ID sessions from before #1069 still store (docs/plugins.md「Agent」).
146
146
  export const BUILTIN_AGENTS = { 'claude-sdk': 'claude', codex: 'codex', grok: 'grok', kimi: 'kimi', opencode: 'opencode', claude: 'claude' };
@@ -7,7 +7,7 @@ import { execFileSync } from 'node:child_process';
7
7
  import { existsSync, lstatSync, readFileSync, readdirSync, realpathSync } from 'node:fs';
8
8
  import { basename, isAbsolute, join, normalize, relative, sep } from 'node:path';
9
9
  import { inflateSync } from 'node:zlib';
10
- import { AGENT_ID, AGENT_LIMITS, BUILTIN_AGENTS, BUILTIN_COMMANDS, BUILTIN_GROUPS, BUILTIN_HERE, BUILTIN_REPOSITORY, CAPABILITY,
10
+ import { AGENT_ID, AGENT_LIMITS, BUILTIN_AGENTS, BUILTIN_COMMANDS, BUILTIN_GROUPS, BUILTIN_HERE, BUILTIN_SCOPE, CAPABILITY,
11
11
  CODA_COMMANDS, CODA_EVENT_DOMAINS, COMMAND, COMMAND_LIMIT, BUILTIN_ONLY, CONTRIBUTES, EVENT, EVENT_LIMIT, DEPTH, ICON_LIMIT, INSTRUCTIONS_LIMIT, NPM, NPM_LOCK, PANEL_ID, PANEL_LIMITS, PLUGIN_ID, POINT,
12
12
  SEGMENT, SERVICE, SETTING_KEY, SETUP_KEYS, SIZE_LIMIT } from './coda.mjs';
13
13
 
@@ -227,11 +227,6 @@ function files(dir) {
227
227
  walk('');
228
228
  return { top: null, entries };
229
229
  }
230
- // The addresses the repository at `top` is fetched from.
231
- function remotes(top) {
232
- try { return execFileSync('git', ['-C', top, 'remote', '-v'], { encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] }).split('\n').map(l => l.split(/\s+/)[1]).filter(Boolean); }
233
- catch { return []; }
234
- }
235
230
  // Why npm could not install from the lock file next to the manifest (`npm ci` refuses a lock that does not match; Coda's
236
231
  // manifestProblem refuses it first), or null.
237
232
  function lockProblem(dir, manifest) {
@@ -266,13 +261,13 @@ export function checkManifest(dir, say) {
266
261
  const { top, entries } = files(dir);
267
262
  // Git names the top by its real path; so is the directory measured.
268
263
  const path = top ? relative(top, realpathSync(dir)).split(sep).filter(Boolean) : null;
269
- // A built-in plugin kept here, in its own place: Coda's copy of it comes from there, and so may a newer version.
264
+ // A built-in plugin as its package is named: Coda ships a version of that package, and a newer one may stand in for it.
270
265
  const declaredId = manifest.id !== undefined ? manifest.id : manifest.name;
271
- const own = BUILTIN_HERE.includes(declaredId) && path?.join('/') === `plugins/${declaredId}` && remotes(top).some(url => BUILTIN_REPOSITORY.test(url));
266
+ const own = BUILTIN_HERE.includes(declaredId) && manifest.name === `${BUILTIN_SCOPE}${declaredId}`;
272
267
  const id = part('manifest.name', () => {
273
268
  check(typeof declaredId === 'string' && PLUGIN_ID.test(declaredId), `package.json 的 ${manifest.id !== undefined ? 'id' : 'name'} 只能用小写字母、数字和「-」,以字母开头,至多 40 个字符`);
274
269
  return declaredId;
275
- }, name => `package.json 能读,插件 ID ${name}${own ? `(Coda 内置插件 ${name} 自己的来源:从这里装的新版本盖过 Coda 的内置副本)` : ''}`);
270
+ }, name => `package.json 能读,插件 ID ${name}${own ? `(Coda 内置插件 ${name}:Coda 带的是 npm 上 ${manifest.name} 的一个版本,这个包的新版本可以盖过它)` : ''}`);
276
271
  const contributes = part('manifest.contributes', () => {
277
272
  check(manifest.contributes && typeof manifest.contributes === 'object' && !Array.isArray(manifest.contributes),
278
273
  'contributes 须为对象(Coda 只把带 contributes 的目录当插件)');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coda-console/plugin-check",
3
- "version": "0.4.4",
3
+ "version": "0.4.5",
4
4
  "description": "Coda 插件的契约检查:扮演 Coda 读清单、启动 Agent 讲 ACP 与 _coda/wait、读面板。",
5
5
  "license": "MIT",
6
6
  "repository": {