@birdie_moblie/plugin-marketplace-cli 1.0.0 → 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/CHANGELOG.md +28 -0
- package/README.md +78 -22
- package/dist/adapters/claude.d.ts +17 -1
- package/dist/adapters/claude.js +37 -1
- package/dist/adapters/claude.js.map +1 -1
- package/dist/adapters/openspec.d.ts +66 -0
- package/dist/adapters/openspec.js +232 -0
- package/dist/adapters/openspec.js.map +1 -0
- package/dist/cli.d.ts +1 -1
- package/dist/cli.js +49 -5
- package/dist/cli.js.map +1 -1
- package/dist/commands/build.js +2 -0
- package/dist/commands/build.js.map +1 -1
- package/dist/commands/index-gen.js +34 -3
- package/dist/commands/index-gen.js.map +1 -1
- package/dist/commands/init-repo.d.ts +1 -0
- package/dist/commands/init-repo.js +64 -28
- package/dist/commands/init-repo.js.map +1 -1
- package/dist/commands/init.d.ts +1 -1
- package/dist/commands/init.js +44 -4
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/release-local.js +25 -0
- package/dist/commands/release-local.js.map +1 -1
- package/dist/commands/validate.js +232 -3
- package/dist/commands/validate.js.map +1 -1
- package/dist/generated/skill-content.d.ts +1 -0
- package/dist/generated/skill-content.js +4 -0
- package/dist/generated/skill-content.js.map +1 -0
- package/dist/schema/plugin-yaml.d.ts +14 -0
- package/dist/schema/plugin-yaml.js +38 -0
- package/dist/schema/plugin-yaml.js.map +1 -1
- package/package.json +13 -5
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
本文件记录 `@birdie_moblie/plugin-marketplace-cli` 的对外变更。版本号遵循 semver,日期使用 ISO 8601。
|
|
4
|
+
|
|
5
|
+
## 1.1.0 - 2026-06-29
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
- 新增 `lsp` 组件类型:`plugin.yaml` 可声明 `components.lsp`,build 阶段派生 `.lsp.json`,Claude Code 直接消费原生 LSP 配置。
|
|
9
|
+
- `init --type lsp` 生成 LSP 插件骨架,并写入面向 agent 的语义检索边界 skill 模板。
|
|
10
|
+
- marketplace 索引(`.claude-plugin/marketplace.json`、根 `marketplace.json`、`CATALOG.md`)、`release-local` 打包以及 `validate` 全面纳入 LSP 组件;Codex 输出仍然保持隔离,不暴露 LSP 字段。
|
|
11
|
+
- 新增 OpenSpec source adapter sidecar 流水线:`plugin.yaml` 中的 `openspec` overlay 由 CLI 生成 `.openspec-plugin/plugin.json` 与根 `.openspec-plugin/source-adapters.json`,不污染 Claude Code / Codex 平台原生格式。
|
|
12
|
+
- Lark 源适配抽象为通用 sheet fetch 命名,保留必需参数,多 source adapter 共存。
|
|
13
|
+
|
|
14
|
+
### Fixed
|
|
15
|
+
- `validate` 在 LSP 组件下校验文件存在性、extension 形式、startupTimeout / maxRestarts 非负,并比对 `.lsp.json` 是否与 `plugin.yaml` 一致,杜绝手改派生产物。
|
|
16
|
+
- 修正 LSP 派生产物中布尔/数字 `null` 字段被序列化为 JSON `null` 的问题。
|
|
17
|
+
- 清理 LSP 插件被移除时残留的 `.lsp.json`。
|
|
18
|
+
|
|
19
|
+
### Notes
|
|
20
|
+
- `.claude-plugin/plugin.json`、`.codex-plugin/plugin.json`、`.lsp.json`、`.openspec-plugin/plugin.json` 等派生文件必须通过 CLI 生成,不要手动编辑;CI 会校验它们与 `plugin.yaml` 派生结果一致。
|
|
21
|
+
|
|
22
|
+
## 1.0.1
|
|
23
|
+
|
|
24
|
+
- 修复 `init-repo` 阶段未注入维护 skill 的问题。
|
|
25
|
+
|
|
26
|
+
## 1.0.0
|
|
27
|
+
|
|
28
|
+
- 首次公开发布:`init-repo` / `init` / `validate` / `build` / `index` / `release-local`。
|
package/README.md
CHANGED
|
@@ -1,33 +1,35 @@
|
|
|
1
1
|
# @birdie_moblie/plugin-marketplace-cli
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
这是用于维护 Claude Code / Codex plugin marketplace 仓库的 CLI。它负责创建插件骨架、验证 `plugin.yaml`、生成平台 manifest、更新 marketplace 索引,并打出本地发布包。OpenSpec source adapter metadata 通过插件内 overlay 生成 sidecar,作为兼容层存在,不改变 Claude Code / Codex 输出格式。
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## 使用公网 CLI
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
|
-
|
|
8
|
+
npx @birdie_moblie/plugin-marketplace-cli --help
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
-
##
|
|
11
|
+
## 常用命令
|
|
12
12
|
|
|
13
13
|
```bash
|
|
14
|
-
plugin-marketplace init-repo [name] --organization "
|
|
15
|
-
plugin-marketplace init <plugin-name> --type <skill|mcp|hook>
|
|
16
|
-
plugin-marketplace validate [plugin-name] --all
|
|
17
|
-
plugin-marketplace build [plugin-name] --all
|
|
18
|
-
plugin-marketplace index
|
|
19
|
-
plugin-marketplace release-local
|
|
14
|
+
npx @birdie_moblie/plugin-marketplace-cli init-repo [name] --organization "团队名" [--no-skill]
|
|
15
|
+
npx @birdie_moblie/plugin-marketplace-cli init <plugin-name> --type <skill|mcp|lsp|hook>
|
|
16
|
+
npx @birdie_moblie/plugin-marketplace-cli validate [plugin-name] --all
|
|
17
|
+
npx @birdie_moblie/plugin-marketplace-cli build [plugin-name] --all
|
|
18
|
+
npx @birdie_moblie/plugin-marketplace-cli index
|
|
19
|
+
npx @birdie_moblie/plugin-marketplace-cli release-local
|
|
20
20
|
```
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
从其他目录操作指定仓库时,使用 `--root <dir>`:
|
|
23
23
|
|
|
24
24
|
```bash
|
|
25
|
-
plugin-marketplace --root /path/to/repo validate --all
|
|
25
|
+
npx @birdie_moblie/plugin-marketplace-cli --root /path/to/repo validate --all
|
|
26
26
|
```
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
不传 `--root` 时,CLI 会从当前工作目录向上查找 `marketplace.yaml`。除 `init-repo` 外,找不到 `marketplace.yaml` 会直接报错并提示先初始化仓库。
|
|
29
|
+
|
|
30
|
+
如果已经本地或全局安装该 npm 包,也可以直接使用 `plugin-marketplace` bin 运行同一组命令。
|
|
29
31
|
|
|
30
|
-
##
|
|
32
|
+
## 插件仓库结构
|
|
31
33
|
|
|
32
34
|
```text
|
|
33
35
|
.
|
|
@@ -36,36 +38,90 @@ Without `--root`, the CLI searches upward from the current working directory for
|
|
|
36
38
|
│ └── my-plugin/
|
|
37
39
|
│ ├── plugin.yaml
|
|
38
40
|
│ └── skills/
|
|
41
|
+
├── .agents/skills/marketplace-maintainer/SKILL.md
|
|
42
|
+
├── .claude/skills/marketplace-maintainer/SKILL.md
|
|
39
43
|
├── .claude-plugin/marketplace.json
|
|
40
44
|
├── .agents/plugins/marketplace.json
|
|
41
45
|
└── marketplace.json
|
|
42
46
|
```
|
|
43
47
|
|
|
44
|
-
|
|
48
|
+
每个插件的 Claude Code / Codex 平台信息以 `plugin.yaml` 为唯一来源。插件也可以额外提供 `openspec-source-adapters.yaml` overlay,用于声明 OpenSpec source adapter metadata。
|
|
49
|
+
|
|
50
|
+
仓库本身要作为 marketplace 源使用时,以下生成物需要随源码一起提交:
|
|
45
51
|
|
|
46
52
|
- `.claude-plugin/marketplace.json`
|
|
47
53
|
- `.agents/plugins/marketplace.json`
|
|
54
|
+
- `.openspec-plugin/source-adapters.json`
|
|
48
55
|
- `plugins/**/.claude-plugin/plugin.json`
|
|
49
56
|
- `plugins/**/.codex-plugin/plugin.json`
|
|
57
|
+
- `plugins/**/.openspec-plugin/plugin.json`
|
|
50
58
|
- `plugins/**/.mcp.json`
|
|
59
|
+
- `plugins/**/.lsp.json`
|
|
51
60
|
- `plugins/**/hooks/hooks.json`
|
|
52
61
|
- `marketplace.json`
|
|
53
62
|
- `plugins/CATALOG.md`
|
|
54
63
|
|
|
55
|
-
|
|
64
|
+
LSP 插件在 `plugin.yaml` 的 `components.lsp` 声明 server metadata:
|
|
65
|
+
|
|
66
|
+
```yaml
|
|
67
|
+
components:
|
|
68
|
+
lsp:
|
|
69
|
+
- name: dart
|
|
70
|
+
command: dart
|
|
71
|
+
args: ["language-server", "--protocol=lsp"]
|
|
72
|
+
extensionToLanguage:
|
|
73
|
+
".dart": dart
|
|
74
|
+
startupTimeout: 30000
|
|
75
|
+
maxRestarts: 3
|
|
76
|
+
diagnostics: true
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
CLI 会由 `components.lsp` 生成插件根目录 `.lsp.json`,并只在 Claude Code marketplace 写入 `lspServers` 字段。Codex 当前没有原生 LSP manifest;语义能力必须通过 MCP server 暴露。
|
|
56
80
|
|
|
57
|
-
`
|
|
81
|
+
OpenSpec sidecar 输出只来自 `openspec-source-adapters.yaml` overlay:
|
|
82
|
+
|
|
83
|
+
- `plugins/<name>/.openspec-plugin/plugin.json`
|
|
84
|
+
- `.openspec-plugin/source-adapters.json`
|
|
85
|
+
|
|
86
|
+
不要把 OpenSpec-only 字段加入 `plugin.yaml`、`.claude-plugin/plugin.json`、`.codex-plugin/plugin.json`、`.claude-plugin/marketplace.json`、`.agents/plugins/marketplace.json` 或根 `marketplace.json`。
|
|
87
|
+
|
|
88
|
+
## 推荐脚本
|
|
89
|
+
|
|
90
|
+
`plugin-marketplace init-repo` 会给新仓库写入一组 npm scripts,并默认注入 `marketplace-maintainer`
|
|
91
|
+
SKILL 到 `.agents/skills/` 和 `.claude/skills/`,方便维护者继续创建、验证和发布插件。如需只生成基础仓库结构,可传 `--no-skill`。这些 scripts 默认调用公网 `npx`,不要求先执行 `npm install`:
|
|
58
92
|
|
|
59
93
|
```json
|
|
60
94
|
{
|
|
61
95
|
"scripts": {
|
|
62
|
-
"mp": "plugin-marketplace",
|
|
63
|
-
"validate:plugins": "plugin-marketplace validate --all",
|
|
64
|
-
"build:plugins": "plugin-marketplace build --all",
|
|
65
|
-
"build:index": "plugin-marketplace index",
|
|
96
|
+
"mp": "npx @birdie_moblie/plugin-marketplace-cli",
|
|
97
|
+
"validate:plugins": "npx @birdie_moblie/plugin-marketplace-cli validate --all",
|
|
98
|
+
"build:plugins": "npx @birdie_moblie/plugin-marketplace-cli build --all",
|
|
99
|
+
"build:index": "npx @birdie_moblie/plugin-marketplace-cli index",
|
|
66
100
|
"build:all": "npm run build:plugins && npm run build:index",
|
|
67
101
|
"ci:local": "npm run validate:plugins && npm run build:all",
|
|
68
|
-
"release:local": "npm run ci:local && plugin-marketplace release-local"
|
|
102
|
+
"release:local": "npm run ci:local && npx @birdie_moblie/plugin-marketplace-cli release-local"
|
|
69
103
|
}
|
|
70
104
|
}
|
|
71
105
|
```
|
|
106
|
+
|
|
107
|
+
如果某个仓库需要固定 CLI 版本,或希望离线维护插件目录,可以手动把 CLI 加为 devDependency:
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
npm install --save-dev @birdie_moblie/plugin-marketplace-cli
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## 维护 CLI 源码
|
|
114
|
+
|
|
115
|
+
只有需要修改、测试或重新发布 `@birdie_moblie/plugin-marketplace-cli` 时才进入 `tools/`:
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
cd tools
|
|
119
|
+
npm install
|
|
120
|
+
npm run build
|
|
121
|
+
npm run mp -- --root .. validate --all
|
|
122
|
+
npm run mp -- --root .. build --all
|
|
123
|
+
npm run mp -- --root .. index
|
|
124
|
+
npm pack --dry-run
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
仓库根目录使用的是已发布 CLI 包。根目录 scripts 用于维护当前插件目录,不用于验证 `tools/` 里尚未发布的源码改动。
|
|
@@ -8,8 +8,9 @@
|
|
|
8
8
|
* - skills/<name>/SKILL.md — skill 文件(已在源码中维护,无需生成)
|
|
9
9
|
* - hooks/hooks.json — hook 配置(如果有 hooks 组件)
|
|
10
10
|
* - .mcp.json — MCP server 配置(如果有 mcp 组件)
|
|
11
|
+
* - .lsp.json — LSP server 配置(如果有 lsp 组件)
|
|
11
12
|
*/
|
|
12
|
-
import type { PluginYaml } from '../schema/plugin-yaml.js';
|
|
13
|
+
import type { PluginLspTransport, PluginYaml } from '../schema/plugin-yaml.js';
|
|
13
14
|
export interface ClaudeManifest {
|
|
14
15
|
name: string;
|
|
15
16
|
version: string;
|
|
@@ -35,6 +36,21 @@ export interface ClaudeMcpConfig {
|
|
|
35
36
|
env?: Record<string, string>;
|
|
36
37
|
}>;
|
|
37
38
|
}
|
|
39
|
+
export type ClaudeLspConfig = Record<string, {
|
|
40
|
+
command: string;
|
|
41
|
+
args?: string[];
|
|
42
|
+
env?: Record<string, string>;
|
|
43
|
+
transport?: PluginLspTransport;
|
|
44
|
+
extensionToLanguage: Record<string, string>;
|
|
45
|
+
workspaceFolder?: string;
|
|
46
|
+
startupTimeout?: number;
|
|
47
|
+
maxRestarts?: number;
|
|
48
|
+
diagnostics?: boolean;
|
|
49
|
+
}>;
|
|
50
|
+
/**
|
|
51
|
+
* 生成 Claude Code 的 .lsp.json(如果有 lsp 组件)
|
|
52
|
+
*/
|
|
53
|
+
export declare function buildLspConfig(config: PluginYaml): ClaudeLspConfig | null;
|
|
38
54
|
/**
|
|
39
55
|
* 将 Claude Code 兼容的文件写入插件目录
|
|
40
56
|
*/
|
package/dist/adapters/claude.js
CHANGED
|
@@ -8,9 +8,13 @@
|
|
|
8
8
|
* - skills/<name>/SKILL.md — skill 文件(已在源码中维护,无需生成)
|
|
9
9
|
* - hooks/hooks.json — hook 配置(如果有 hooks 组件)
|
|
10
10
|
* - .mcp.json — MCP server 配置(如果有 mcp 组件)
|
|
11
|
+
* - .lsp.json — LSP server 配置(如果有 lsp 组件)
|
|
11
12
|
*/
|
|
12
|
-
import { mkdirSync, writeFileSync } from 'node:fs';
|
|
13
|
+
import { mkdirSync, rmSync, writeFileSync } from 'node:fs';
|
|
13
14
|
import { join } from 'node:path';
|
|
15
|
+
function isPresent(value) {
|
|
16
|
+
return value != null;
|
|
17
|
+
}
|
|
14
18
|
/**
|
|
15
19
|
* 生成 Claude Code 的 .claude-plugin/plugin.json
|
|
16
20
|
*/
|
|
@@ -65,6 +69,29 @@ function buildMcpConfig(config) {
|
|
|
65
69
|
}
|
|
66
70
|
return { mcpServers: servers };
|
|
67
71
|
}
|
|
72
|
+
/**
|
|
73
|
+
* 生成 Claude Code 的 .lsp.json(如果有 lsp 组件)
|
|
74
|
+
*/
|
|
75
|
+
export function buildLspConfig(config) {
|
|
76
|
+
const lsps = config.components.lsp;
|
|
77
|
+
if (!lsps || lsps.length === 0)
|
|
78
|
+
return null;
|
|
79
|
+
const servers = {};
|
|
80
|
+
for (const lsp of lsps) {
|
|
81
|
+
servers[lsp.name] = {
|
|
82
|
+
command: lsp.command,
|
|
83
|
+
...(isPresent(lsp.args) ? { args: lsp.args } : {}),
|
|
84
|
+
...(isPresent(lsp.env) ? { env: lsp.env } : {}),
|
|
85
|
+
...(isPresent(lsp.transport) ? { transport: lsp.transport } : {}),
|
|
86
|
+
extensionToLanguage: lsp.extensionToLanguage,
|
|
87
|
+
...(isPresent(lsp.workspaceFolder) ? { workspaceFolder: lsp.workspaceFolder } : {}),
|
|
88
|
+
...(isPresent(lsp.startupTimeout) ? { startupTimeout: lsp.startupTimeout } : {}),
|
|
89
|
+
...(isPresent(lsp.maxRestarts) ? { maxRestarts: lsp.maxRestarts } : {}),
|
|
90
|
+
...(isPresent(lsp.diagnostics) ? { diagnostics: lsp.diagnostics } : {}),
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
return servers;
|
|
94
|
+
}
|
|
68
95
|
/**
|
|
69
96
|
* 将 Claude Code 兼容的文件写入插件目录
|
|
70
97
|
*/
|
|
@@ -85,5 +112,14 @@ export function generateClaude(config, pluginDir) {
|
|
|
85
112
|
if (mcpConfig) {
|
|
86
113
|
writeFileSync(join(pluginDir, '.mcp.json'), JSON.stringify(mcpConfig, null, 2) + '\n');
|
|
87
114
|
}
|
|
115
|
+
// 4. .lsp.json
|
|
116
|
+
const lspConfig = buildLspConfig(config);
|
|
117
|
+
const lspPath = join(pluginDir, '.lsp.json');
|
|
118
|
+
if (lspConfig) {
|
|
119
|
+
writeFileSync(lspPath, JSON.stringify(lspConfig, null, 2) + '\n');
|
|
120
|
+
}
|
|
121
|
+
else {
|
|
122
|
+
rmSync(lspPath, { force: true });
|
|
123
|
+
}
|
|
88
124
|
}
|
|
89
125
|
//# sourceMappingURL=claude.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"claude.js","sourceRoot":"","sources":["../../src/adapters/claude.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"claude.js","sourceRoot":"","sources":["../../src/adapters/claude.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenSpec 适配器
|
|
3
|
+
*
|
|
4
|
+
* 从 OpenSpec 专属配置生成独立 sidecar。
|
|
5
|
+
* 该 sidecar 不属于 Claude/Codex 原生 manifest,避免污染平台 manifest。
|
|
6
|
+
*/
|
|
7
|
+
import type { PluginYaml } from '../schema/plugin-yaml.js';
|
|
8
|
+
export declare const OPENSPEC_SOURCE_ADAPTERS_FILE = "openspec-source-adapters.yaml";
|
|
9
|
+
export type OpenSpecAdapterKind = 'command' | 'skill' | 'deferred' | 'manual';
|
|
10
|
+
export declare const OPEN_SPEC_ADAPTER_KINDS: OpenSpecAdapterKind[];
|
|
11
|
+
export interface OpenSpecAdapterOperation {
|
|
12
|
+
command?: string;
|
|
13
|
+
args?: string[];
|
|
14
|
+
output?: 'json' | 'markdown' | 'text';
|
|
15
|
+
parser?: 'prd-markdown' | 'yapi-summary-json' | 'raw-json' | 'raw-text';
|
|
16
|
+
skill?: string;
|
|
17
|
+
execution?: 'agent-plan' | 'agent-mcp';
|
|
18
|
+
produces?: string;
|
|
19
|
+
}
|
|
20
|
+
export interface OpenSpecAdapterParam {
|
|
21
|
+
key: string;
|
|
22
|
+
scope?: 'capability' | 'adapter' | 'operation';
|
|
23
|
+
required?: boolean;
|
|
24
|
+
label?: string;
|
|
25
|
+
description?: string;
|
|
26
|
+
sensitive?: boolean;
|
|
27
|
+
}
|
|
28
|
+
export interface OpenSpecAdapter {
|
|
29
|
+
id: string;
|
|
30
|
+
capability: string;
|
|
31
|
+
kind: OpenSpecAdapterKind;
|
|
32
|
+
operations: Record<string, OpenSpecAdapterOperation>;
|
|
33
|
+
knownParams?: OpenSpecAdapterParam[];
|
|
34
|
+
requiredParams?: OpenSpecAdapterParam[];
|
|
35
|
+
}
|
|
36
|
+
export interface OpenSpecSourceAdaptersYaml {
|
|
37
|
+
schemaVersion?: 'openspec.source-adapters.v1';
|
|
38
|
+
adapters: OpenSpecAdapter[];
|
|
39
|
+
}
|
|
40
|
+
export interface OpenSpecPluginManifest {
|
|
41
|
+
name: string;
|
|
42
|
+
version: string;
|
|
43
|
+
description: string;
|
|
44
|
+
author: PluginYaml['author'];
|
|
45
|
+
openspec: {
|
|
46
|
+
adapters: OpenSpecAdapter[];
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
export interface OpenSpecSourceAdapterIndexEntry {
|
|
50
|
+
name: string;
|
|
51
|
+
source: string;
|
|
52
|
+
manifest: string;
|
|
53
|
+
adapters: Array<{
|
|
54
|
+
id: string;
|
|
55
|
+
capability: string;
|
|
56
|
+
kind: OpenSpecAdapter['kind'];
|
|
57
|
+
operations: string[];
|
|
58
|
+
}>;
|
|
59
|
+
}
|
|
60
|
+
export declare function isOpenSpecAdapterKind(value: unknown): value is OpenSpecAdapterKind;
|
|
61
|
+
export declare function findDuplicateOpenSpecAdapterOperations(entries: OpenSpecSourceAdapterIndexEntry[]): string[];
|
|
62
|
+
export declare function assertUniqueOpenSpecAdapterOperations(entries: OpenSpecSourceAdapterIndexEntry[]): void;
|
|
63
|
+
export declare function loadOpenSpecAdapters(pluginDir: string): OpenSpecAdapter[];
|
|
64
|
+
export declare function buildOpenSpecManifest(config: PluginYaml, pluginDir: string): OpenSpecPluginManifest | null;
|
|
65
|
+
export declare function generateOpenSpec(config: PluginYaml, pluginDir: string): boolean;
|
|
66
|
+
export declare function buildOpenSpecSourceAdapterIndexEntry(config: PluginYaml, pluginDir: string, relativePath: string): OpenSpecSourceAdapterIndexEntry | null;
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenSpec 适配器
|
|
3
|
+
*
|
|
4
|
+
* 从 OpenSpec 专属配置生成独立 sidecar。
|
|
5
|
+
* 该 sidecar 不属于 Claude/Codex 原生 manifest,避免污染平台 manifest。
|
|
6
|
+
*/
|
|
7
|
+
import { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from 'node:fs';
|
|
8
|
+
import { join } from 'node:path';
|
|
9
|
+
import Ajv from 'ajv';
|
|
10
|
+
import yaml from 'js-yaml';
|
|
11
|
+
export const OPENSPEC_SOURCE_ADAPTERS_FILE = 'openspec-source-adapters.yaml';
|
|
12
|
+
export const OPEN_SPEC_ADAPTER_KINDS = [
|
|
13
|
+
'command',
|
|
14
|
+
'skill',
|
|
15
|
+
'deferred',
|
|
16
|
+
'manual',
|
|
17
|
+
];
|
|
18
|
+
const paramSchema = {
|
|
19
|
+
type: 'object',
|
|
20
|
+
required: ['key'],
|
|
21
|
+
additionalProperties: false,
|
|
22
|
+
properties: {
|
|
23
|
+
key: { type: 'string' },
|
|
24
|
+
scope: {
|
|
25
|
+
type: 'string',
|
|
26
|
+
nullable: true,
|
|
27
|
+
enum: ['capability', 'adapter', 'operation', null],
|
|
28
|
+
},
|
|
29
|
+
required: { type: 'boolean', nullable: true },
|
|
30
|
+
label: { type: 'string', nullable: true },
|
|
31
|
+
description: { type: 'string', nullable: true },
|
|
32
|
+
sensitive: { type: 'boolean', nullable: true },
|
|
33
|
+
},
|
|
34
|
+
};
|
|
35
|
+
const openSpecSourceAdaptersSchema = {
|
|
36
|
+
type: 'object',
|
|
37
|
+
required: ['adapters'],
|
|
38
|
+
additionalProperties: false,
|
|
39
|
+
properties: {
|
|
40
|
+
schemaVersion: {
|
|
41
|
+
type: 'string',
|
|
42
|
+
nullable: true,
|
|
43
|
+
enum: ['openspec.source-adapters.v1', null],
|
|
44
|
+
},
|
|
45
|
+
adapters: {
|
|
46
|
+
type: 'array',
|
|
47
|
+
items: {
|
|
48
|
+
type: 'object',
|
|
49
|
+
required: ['id', 'capability', 'kind', 'operations'],
|
|
50
|
+
additionalProperties: false,
|
|
51
|
+
properties: {
|
|
52
|
+
id: { type: 'string' },
|
|
53
|
+
capability: { type: 'string' },
|
|
54
|
+
kind: {
|
|
55
|
+
type: 'string',
|
|
56
|
+
enum: ['command', 'skill', 'deferred', 'manual'],
|
|
57
|
+
},
|
|
58
|
+
operations: {
|
|
59
|
+
type: 'object',
|
|
60
|
+
required: [],
|
|
61
|
+
additionalProperties: {
|
|
62
|
+
type: 'object',
|
|
63
|
+
required: [],
|
|
64
|
+
additionalProperties: false,
|
|
65
|
+
properties: {
|
|
66
|
+
command: { type: 'string', nullable: true },
|
|
67
|
+
args: {
|
|
68
|
+
type: 'array',
|
|
69
|
+
nullable: true,
|
|
70
|
+
items: { type: 'string' },
|
|
71
|
+
},
|
|
72
|
+
output: {
|
|
73
|
+
type: 'string',
|
|
74
|
+
nullable: true,
|
|
75
|
+
enum: ['json', 'markdown', 'text', null],
|
|
76
|
+
},
|
|
77
|
+
parser: {
|
|
78
|
+
type: 'string',
|
|
79
|
+
nullable: true,
|
|
80
|
+
enum: ['prd-markdown', 'yapi-summary-json', 'raw-json', 'raw-text', null],
|
|
81
|
+
},
|
|
82
|
+
skill: { type: 'string', nullable: true },
|
|
83
|
+
execution: {
|
|
84
|
+
type: 'string',
|
|
85
|
+
nullable: true,
|
|
86
|
+
enum: ['agent-plan', 'agent-mcp', null],
|
|
87
|
+
},
|
|
88
|
+
produces: { type: 'string', nullable: true },
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
},
|
|
92
|
+
knownParams: {
|
|
93
|
+
type: 'array',
|
|
94
|
+
nullable: true,
|
|
95
|
+
items: paramSchema,
|
|
96
|
+
},
|
|
97
|
+
requiredParams: {
|
|
98
|
+
type: 'array',
|
|
99
|
+
nullable: true,
|
|
100
|
+
items: paramSchema,
|
|
101
|
+
},
|
|
102
|
+
},
|
|
103
|
+
},
|
|
104
|
+
},
|
|
105
|
+
},
|
|
106
|
+
};
|
|
107
|
+
// @ts-expect-error -- ajv v8 CJS/ESM interop: runtime can construct Ajv in this project setup.
|
|
108
|
+
const ajv = new Ajv({ allErrors: true });
|
|
109
|
+
const validateOpenSpecSourceAdapters = ajv.compile(openSpecSourceAdaptersSchema);
|
|
110
|
+
function formatAjvErrors(errors) {
|
|
111
|
+
return (errors
|
|
112
|
+
?.map((error) => ` - ${error.instancePath || '/'}: ${error.message}`)
|
|
113
|
+
.join('\n') || ' - unknown validation error');
|
|
114
|
+
}
|
|
115
|
+
function stripNullish(value) {
|
|
116
|
+
if (Array.isArray(value)) {
|
|
117
|
+
return value.map((item) => stripNullish(item));
|
|
118
|
+
}
|
|
119
|
+
if (value && typeof value === 'object') {
|
|
120
|
+
const result = {};
|
|
121
|
+
for (const [key, child] of Object.entries(value)) {
|
|
122
|
+
if (child === null || child === undefined)
|
|
123
|
+
continue;
|
|
124
|
+
result[key] = stripNullish(child);
|
|
125
|
+
}
|
|
126
|
+
return result;
|
|
127
|
+
}
|
|
128
|
+
return value;
|
|
129
|
+
}
|
|
130
|
+
function validateUniqueAdapterOperations(adapters) {
|
|
131
|
+
const seen = new Map();
|
|
132
|
+
for (const adapter of adapters) {
|
|
133
|
+
for (const operation of Object.keys(adapter.operations)) {
|
|
134
|
+
const key = `${adapter.id}:${adapter.capability}:${operation}`;
|
|
135
|
+
const existing = seen.get(key);
|
|
136
|
+
if (existing) {
|
|
137
|
+
throw new Error(`${OPENSPEC_SOURCE_ADAPTERS_FILE} declares duplicate adapter operation '${key}' in '${existing}' and '${adapter.id}'`);
|
|
138
|
+
}
|
|
139
|
+
seen.set(key, adapter.id);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
export function isOpenSpecAdapterKind(value) {
|
|
144
|
+
return typeof value === 'string' && OPEN_SPEC_ADAPTER_KINDS.includes(value);
|
|
145
|
+
}
|
|
146
|
+
export function findDuplicateOpenSpecAdapterOperations(entries) {
|
|
147
|
+
const seen = new Map();
|
|
148
|
+
const errors = [];
|
|
149
|
+
for (const entry of entries) {
|
|
150
|
+
for (const adapter of entry.adapters) {
|
|
151
|
+
for (const operation of adapter.operations) {
|
|
152
|
+
const key = `${adapter.id}:${adapter.capability}:${operation}`;
|
|
153
|
+
const existing = seen.get(key);
|
|
154
|
+
if (existing) {
|
|
155
|
+
errors.push(`OpenSpec source adapter duplicate operation '${key}': ` +
|
|
156
|
+
`${existing.plugin} (${existing.source}, adapter ${existing.adapterId}) conflicts with ` +
|
|
157
|
+
`${entry.name} (${entry.source}, adapter ${adapter.id})`);
|
|
158
|
+
continue;
|
|
159
|
+
}
|
|
160
|
+
seen.set(key, {
|
|
161
|
+
plugin: entry.name,
|
|
162
|
+
source: entry.source,
|
|
163
|
+
adapterId: adapter.id,
|
|
164
|
+
capability: adapter.capability,
|
|
165
|
+
operation,
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
return errors;
|
|
171
|
+
}
|
|
172
|
+
export function assertUniqueOpenSpecAdapterOperations(entries) {
|
|
173
|
+
const errors = findDuplicateOpenSpecAdapterOperations(entries);
|
|
174
|
+
if (errors.length > 0) {
|
|
175
|
+
throw new Error(`OpenSpec source adapter index validation failed:\n${errors.join('\n')}`);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
export function loadOpenSpecAdapters(pluginDir) {
|
|
179
|
+
const yamlPath = join(pluginDir, OPENSPEC_SOURCE_ADAPTERS_FILE);
|
|
180
|
+
if (!existsSync(yamlPath))
|
|
181
|
+
return [];
|
|
182
|
+
const raw = readFileSync(yamlPath, 'utf-8');
|
|
183
|
+
const data = yaml.load(raw);
|
|
184
|
+
if (!validateOpenSpecSourceAdapters(data)) {
|
|
185
|
+
throw new Error(`${OPENSPEC_SOURCE_ADAPTERS_FILE} validation failed:\n${formatAjvErrors(validateOpenSpecSourceAdapters.errors)}`);
|
|
186
|
+
}
|
|
187
|
+
const sourceAdapters = data;
|
|
188
|
+
validateUniqueAdapterOperations(sourceAdapters.adapters);
|
|
189
|
+
return stripNullish(sourceAdapters.adapters);
|
|
190
|
+
}
|
|
191
|
+
export function buildOpenSpecManifest(config, pluginDir) {
|
|
192
|
+
const adapters = loadOpenSpecAdapters(pluginDir);
|
|
193
|
+
if (!adapters || adapters.length === 0)
|
|
194
|
+
return null;
|
|
195
|
+
return {
|
|
196
|
+
name: config.name,
|
|
197
|
+
version: config.version,
|
|
198
|
+
description: config.description,
|
|
199
|
+
author: stripNullish(config.author),
|
|
200
|
+
openspec: {
|
|
201
|
+
adapters,
|
|
202
|
+
},
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
export function generateOpenSpec(config, pluginDir) {
|
|
206
|
+
const openSpecDir = join(pluginDir, '.openspec-plugin');
|
|
207
|
+
const manifest = buildOpenSpecManifest(config, pluginDir);
|
|
208
|
+
if (!manifest) {
|
|
209
|
+
rmSync(openSpecDir, { recursive: true, force: true });
|
|
210
|
+
return false;
|
|
211
|
+
}
|
|
212
|
+
mkdirSync(openSpecDir, { recursive: true });
|
|
213
|
+
writeFileSync(join(openSpecDir, 'plugin.json'), JSON.stringify(manifest, null, 2) + '\n');
|
|
214
|
+
return true;
|
|
215
|
+
}
|
|
216
|
+
export function buildOpenSpecSourceAdapterIndexEntry(config, pluginDir, relativePath) {
|
|
217
|
+
const manifest = buildOpenSpecManifest(config, pluginDir);
|
|
218
|
+
if (!manifest)
|
|
219
|
+
return null;
|
|
220
|
+
return {
|
|
221
|
+
name: config.name,
|
|
222
|
+
source: relativePath,
|
|
223
|
+
manifest: `${relativePath}/.openspec-plugin/plugin.json`,
|
|
224
|
+
adapters: manifest.openspec.adapters.map((adapter) => ({
|
|
225
|
+
id: adapter.id,
|
|
226
|
+
capability: adapter.capability,
|
|
227
|
+
kind: adapter.kind,
|
|
228
|
+
operations: Object.keys(adapter.operations),
|
|
229
|
+
})),
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
//# sourceMappingURL=openspec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openspec.js","sourceRoot":"","sources":["../../src/adapters/openspec.ts"],"names":[],"mappings":"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"}
|