@qomicex/cli 0.1.1 → 0.1.2
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/dist/commands/bump.js +30 -0
- package/dist/index.js +13 -2
- package/dist/lib/permissions.js +1 -0
- package/dist/lib/signature.js +1 -1
- package/dist/lib/store.js +1 -1
- package/package.json +1 -1
- package/skills/qomicex-plugin/SKILL.md +65 -65
- package/skills/qomicex-plugin/debugging.md +55 -55
- package/skills/qomicex-plugin/manifest-schema.md +130 -130
- package/skills/qomicex-plugin/permissions.md +98 -98
- package/skills/qomicex-plugin/plugin-api.md +112 -112
- package/skills/qomicex-plugin/rules.md +45 -45
- package/skills/qomicex-plugin/signing.md +80 -80
- package/skills/qomicex-plugin/theme.md +58 -58
|
@@ -1,80 +1,80 @@
|
|
|
1
|
-
# Ed25519 签名流程
|
|
2
|
-
|
|
3
|
-
签名实现源:`packages/qomicex-cli/src/lib/signature.ts`。规范:**ADR-050 三级信任链**(商店根钥 → 开发者证书 → 包体签名)。与 store `src/lib/signature.ts`、launcher `plugin_signature.rs` 字节级一致。
|
|
4
|
-
|
|
5
|
-
## 签名载荷(规范化)
|
|
6
|
-
|
|
7
|
-
```
|
|
8
|
-
payload = canonicalJson({
|
|
9
|
-
manifest: sha256Hex(manifest.json 原始字节),
|
|
10
|
-
files: [{ path, sha256 }...] // 按 path 升序
|
|
11
|
-
})
|
|
12
|
-
signedHash = SHA-256(payload) // 文本 UTF-8
|
|
13
|
-
signature = Ed25519(私钥, payload 的 UTF-8 字节)
|
|
14
|
-
```
|
|
15
|
-
|
|
16
|
-
- `canonicalJson`:递归按键排序、无空白 JSON(键序对哈希无影响,保证确定性)。
|
|
17
|
-
- 包内 `signature.json` 与 `signature.cert.json` 本身不参与签名。
|
|
18
|
-
|
|
19
|
-
## 产物文件
|
|
20
|
-
|
|
21
|
-
| 文件 | 内容 |
|
|
22
|
-
|------|------|
|
|
23
|
-
| `signature.json` | `{ alg: "Ed25519", signedHash, signerKeyId, signature }` |
|
|
24
|
-
| `signature.cert.json` | 商店根钥签发的开发者证书:`{ alg, keyId, developerId, developerName, publicKey, issuedAt, signature }` |
|
|
25
|
-
|
|
26
|
-
验包要求:**两个文件都必须存在**,缺任一 → 未签名(`verify` 警告不拒绝);根钥验证书失败 / 包体验签失败 / 哈希不符 → 拒绝。
|
|
27
|
-
|
|
28
|
-
## 1. 生成密钥对
|
|
29
|
-
|
|
30
|
-
```bash
|
|
31
|
-
openssl genpkey -algorithm Ed25519 -out dev-key.pem
|
|
32
|
-
# 可选:提取 raw 32 字节 seed base64(publish 也接受 PEM,通常不必)
|
|
33
|
-
openssl pkey -in dev-key.pem -outform DER | tail -c 32 | base64
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
私钥支持三种格式:PKCS#8 PEM、PKCS#8 DER base64、raw 32 字节 seed base64。
|
|
37
|
-
|
|
38
|
-
> ⚠️ 私钥 = 开发者身份。**禁止**写入插件源码 / manifest / git 仓库 / 提交任何公开位置。使用环境变量 `QOMICEX_SIGN_KEY` 传入。
|
|
39
|
-
|
|
40
|
-
## 2. pack --key(本地签名,仅 signature.json)
|
|
41
|
-
|
|
42
|
-
```bash
|
|
43
|
-
qomicex pack --key ./dev-key.pem
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
- `keyId = ed25519:{公钥 base64 前 8 字符}`。
|
|
47
|
-
- 若项目根存在 `signature.cert.json` 会自动带上(发布过一次后即有)。
|
|
48
|
-
- 无证书时 CLI 会警告:商店上传仍需完整证书,建议走 publish。
|
|
49
|
-
|
|
50
|
-
## 3. publish(完整证书链)
|
|
51
|
-
|
|
52
|
-
```bash
|
|
53
|
-
export QOMICEX_SIGN_KEY=<私钥 base64/PEM> # 或 --key ./dev-key.pem
|
|
54
|
-
qomicex publish
|
|
55
|
-
qomicex publish --changelog "修复 X" --yes
|
|
56
|
-
qomicex publish --api http://127.0.0.1:8787/api/v1 # 本地商店(wrangler dev)调试
|
|
57
|
-
```
|
|
58
|
-
|
|
59
|
-
流程(RFC 8628 设备流):
|
|
60
|
-
1. `POST /api/v1/auth/device/code` → 打印授权码 + 验证 URL → 轮询 `device/token` 拿访问令牌。
|
|
61
|
-
2. `POST /api/v1/developer/keys` 上传 Ed25519 公钥 → 商店根钥签发开发者证书(返回 `keyId` + 证书内容)。
|
|
62
|
-
3. 用私钥对包体签名,写入 `signature.json`,与证书一起打进 `.qplugin`。
|
|
63
|
-
4. 查找/创建插件记录(`/plugins/mine` → 无则 `POST /plugins`),确认后 `POST /plugins/:id/versions` multipart 上传。
|
|
64
|
-
5. 成功后将签名包存为 `release/<id>-<version>.signed.qplugin` 供复验。
|
|
65
|
-
|
|
66
|
-
## 4. 验包
|
|
67
|
-
|
|
68
|
-
```bash
|
|
69
|
-
qomicex verify --package ./release/x.qplugin
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
- 用内置商店根公钥验签:`STORE_ROOT_PUBLIC_KEY_B64`(与 launcher `plugin_signature.rs` 的 `ROOT_PUBLIC_KEY_B64` 一致)。
|
|
73
|
-
- 未签名 → 提示"未签名"(警告,不拒绝);签名无效 → error 退出。
|
|
74
|
-
|
|
75
|
-
## 商店根公钥
|
|
76
|
-
|
|
77
|
-
```
|
|
78
|
-
|
|
79
|
-
```
|
|
80
|
-
(raw base64 Ed25519 公钥;开发 / 自建商店需替换为对应根钥)
|
|
1
|
+
# Ed25519 签名流程
|
|
2
|
+
|
|
3
|
+
签名实现源:`packages/qomicex-cli/src/lib/signature.ts`。规范:**ADR-050 三级信任链**(商店根钥 → 开发者证书 → 包体签名)。与 store `src/lib/signature.ts`、launcher `plugin_signature.rs` 字节级一致。
|
|
4
|
+
|
|
5
|
+
## 签名载荷(规范化)
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
payload = canonicalJson({
|
|
9
|
+
manifest: sha256Hex(manifest.json 原始字节),
|
|
10
|
+
files: [{ path, sha256 }...] // 按 path 升序
|
|
11
|
+
})
|
|
12
|
+
signedHash = SHA-256(payload) // 文本 UTF-8
|
|
13
|
+
signature = Ed25519(私钥, payload 的 UTF-8 字节)
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
- `canonicalJson`:递归按键排序、无空白 JSON(键序对哈希无影响,保证确定性)。
|
|
17
|
+
- 包内 `signature.json` 与 `signature.cert.json` 本身不参与签名。
|
|
18
|
+
|
|
19
|
+
## 产物文件
|
|
20
|
+
|
|
21
|
+
| 文件 | 内容 |
|
|
22
|
+
|------|------|
|
|
23
|
+
| `signature.json` | `{ alg: "Ed25519", signedHash, signerKeyId, signature }` |
|
|
24
|
+
| `signature.cert.json` | 商店根钥签发的开发者证书:`{ alg, keyId, developerId, developerName, publicKey, issuedAt, signature }` |
|
|
25
|
+
|
|
26
|
+
验包要求:**两个文件都必须存在**,缺任一 → 未签名(`verify` 警告不拒绝);根钥验证书失败 / 包体验签失败 / 哈希不符 → 拒绝。
|
|
27
|
+
|
|
28
|
+
## 1. 生成密钥对
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
openssl genpkey -algorithm Ed25519 -out dev-key.pem
|
|
32
|
+
# 可选:提取 raw 32 字节 seed base64(publish 也接受 PEM,通常不必)
|
|
33
|
+
openssl pkey -in dev-key.pem -outform DER | tail -c 32 | base64
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
私钥支持三种格式:PKCS#8 PEM、PKCS#8 DER base64、raw 32 字节 seed base64。
|
|
37
|
+
|
|
38
|
+
> ⚠️ 私钥 = 开发者身份。**禁止**写入插件源码 / manifest / git 仓库 / 提交任何公开位置。使用环境变量 `QOMICEX_SIGN_KEY` 传入。
|
|
39
|
+
|
|
40
|
+
## 2. pack --key(本地签名,仅 signature.json)
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
qomicex pack --key ./dev-key.pem
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
- `keyId = ed25519:{公钥 base64 前 8 字符}`。
|
|
47
|
+
- 若项目根存在 `signature.cert.json` 会自动带上(发布过一次后即有)。
|
|
48
|
+
- 无证书时 CLI 会警告:商店上传仍需完整证书,建议走 publish。
|
|
49
|
+
|
|
50
|
+
## 3. publish(完整证书链)
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
export QOMICEX_SIGN_KEY=<私钥 base64/PEM> # 或 --key ./dev-key.pem
|
|
54
|
+
qomicex publish
|
|
55
|
+
qomicex publish --changelog "修复 X" --yes
|
|
56
|
+
qomicex publish --api http://127.0.0.1:8787/api/v1 # 本地商店(wrangler dev)调试
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
流程(RFC 8628 设备流):
|
|
60
|
+
1. `POST /api/v1/auth/device/code` → 打印授权码 + 验证 URL → 轮询 `device/token` 拿访问令牌。
|
|
61
|
+
2. `POST /api/v1/developer/keys` 上传 Ed25519 公钥 → 商店根钥签发开发者证书(返回 `keyId` + 证书内容)。
|
|
62
|
+
3. 用私钥对包体签名,写入 `signature.json`,与证书一起打进 `.qplugin`。
|
|
63
|
+
4. 查找/创建插件记录(`/plugins/mine` → 无则 `POST /plugins`),确认后 `POST /plugins/:id/versions` multipart 上传。
|
|
64
|
+
5. 成功后将签名包存为 `release/<id>-<version>.signed.qplugin` 供复验。
|
|
65
|
+
|
|
66
|
+
## 4. 验包
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
qomicex verify --package ./release/x.qplugin
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
- 用内置商店根公钥验签:`STORE_ROOT_PUBLIC_KEY_B64`(与 launcher `plugin_signature.rs` 的 `ROOT_PUBLIC_KEY_B64` 一致)。
|
|
73
|
+
- 未签名 → 提示"未签名"(警告,不拒绝);签名无效 → error 退出。
|
|
74
|
+
|
|
75
|
+
## 商店根公钥
|
|
76
|
+
|
|
77
|
+
```
|
|
78
|
+
sPKcrc6QR5gcOnQMdq21Jo3yqxN7Mbm61OYxZnKuHE0=
|
|
79
|
+
```
|
|
80
|
+
(raw base64 Ed25519 公钥;开发 / 自建商店需替换为对应根钥)
|
|
@@ -1,58 +1,58 @@
|
|
|
1
|
-
# 主题语义 Token
|
|
2
|
-
|
|
3
|
-
规范源:`docs/junsi-dev-docs/2-架构设计/主题语义Token规范v1.md`(实现:`src/theme/`)。插件 UI 主题的**唯一正确做法**:全量经 `var(--*)` 消费语义 token,禁止内联色值。
|
|
4
|
-
|
|
5
|
-
## 三级语义模型
|
|
6
|
-
|
|
7
|
-
```
|
|
8
|
-
primitives(原始色板)→ semantic(语义角色)→ component(CSS 变量,唯一被 var() 读取)
|
|
9
|
-
```
|
|
10
|
-
|
|
11
|
-
v1 落点:`.qtheme` 主题直接表达 semantic/component 层(即 `--*` 平铺变量)。插件不写主题,只**消费**这些变量。token 点分命名,`.` 归一化为 `-`(`background.emphasis` → `--background-emphasis`)。
|
|
12
|
-
|
|
13
|
-
## 色板 token(plugin-ui 消费全集)
|
|
14
|
-
|
|
15
|
-
| token(theme.json 键) | CSS 变量 | 默认值(dark) | 语义 |
|
|
16
|
-
|---|---|---|---|
|
|
17
|
-
| background | `--background` | `230 20% 6%` | 页面底色 |
|
|
18
|
-
| foreground | `--foreground` | `220 20% 93%` | 主文字 |
|
|
19
|
-
| card / card-foreground | `--card` / `--card-foreground` | `228 18% 10%` / `220 20% 93%` | 卡片 |
|
|
20
|
-
| popover / popover-foreground | `--popover` / `--popover-foreground` | `228 18% 10%` / `220 20% 93%` | 浮层 |
|
|
21
|
-
| primary / primary-foreground | `--primary` / `--primary-foreground` | `142 71% 48%` / `230 20% 6%` | 主强调 |
|
|
22
|
-
| secondary / secondary-foreground | `--secondary` / `--secondary-foreground` | `228 18% 14%` / `220 20% 93%` | 次级 |
|
|
23
|
-
| muted / muted-foreground | `--muted` / `--muted-foreground` | `228 10% 18%` / `228 8% 55%` | 弱化 |
|
|
24
|
-
| accent / accent-foreground | `--accent` / `--accent-foreground` | `228 18% 14%` / `220 20% 93%` | 强调底 |
|
|
25
|
-
| destructive / destructive-foreground | `--destructive` / `--destructive-foreground` | `0 84% 60%` / `220 20% 93%` | 危险 |
|
|
26
|
-
| border | `--border` | `228 14% 21%` | 边框 |
|
|
27
|
-
| input | `--input` | `228 14% 21%` | 输入框 |
|
|
28
|
-
| ring | `--ring` | `142 71% 48%` | 焦点环 |
|
|
29
|
-
|
|
30
|
-
扩展语义(可选,emit 为 `--foreground-accent` 等):`foreground.accent`、`foreground.muted`、`foreground.destructive`、`background.elevated`、`background.emphasis`、`background.sunken`、`border.strong`、`border.accent`、`accent.hover`、`accent.active`、`status.success`、`status.warning`、`status.error`。
|
|
31
|
-
|
|
32
|
-
## 非色 token
|
|
33
|
-
|
|
34
|
-
| token | CSS 变量 | 默认值 | 说明 |
|
|
35
|
-
|---|---|---|---|
|
|
36
|
-
| radius | `--radius` | `0.625rem` | 圆角 |
|
|
37
|
-
| glass-blur | `--glass-blur` | `18px` | 毛玻璃模糊 |
|
|
38
|
-
|
|
39
|
-
## var() 消费约定
|
|
40
|
-
|
|
41
|
-
- **全部用 `var(--*)`,禁止内联色值**(`#hex` / `rgb()` / `hsl()` 字面量)。plugin-ui 组件已全量 var() 消费,换主题即时生效,无需重建 dist。
|
|
42
|
-
- 颜色值多为 HSL 三元组(如 `142 71% 48%`),组件库经 `hsl(var(--primary))` 解析。插件自定义 CSS 需要时同样写 `hsl(var(--primary) / <alpha>)` 形式。
|
|
43
|
-
- Tailwind 侧直接用语义类名:`bg-primary`、`text-foreground`、`bg-muted`、`text-muted-foreground`、`border-border` 等(`@qomicex/plugin-ui/tailwind-preset` 已映射)。
|
|
44
|
-
|
|
45
|
-
## 主题贡献(entry.theme)
|
|
46
|
-
|
|
47
|
-
- manifest `entry.theme` 指向 `dist/theme.css`,激活时注入 `<style data-plugin-theme>`。
|
|
48
|
-
- 主题 CSS 只能**覆盖/补充** token,仍须全部 `var()` 引用,禁止内联色值:
|
|
49
|
-
|
|
50
|
-
```css
|
|
51
|
-
:root[data-theme] {
|
|
52
|
-
/* 可选:覆盖默认 HSL token */
|
|
53
|
-
--primary: 142 71% 48%;
|
|
54
|
-
}
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
- `qomicex pack` 会自动把根目录的 `theme.css` 拷入 `dist/theme.css`(若 manifest 引用 `dist/theme.css`)。
|
|
58
|
-
- **不要在插件里定义与启动器冲突的平铺变量**;需要私有样式时走组件 class(Tailwind)或局部作用域。
|
|
1
|
+
# 主题语义 Token
|
|
2
|
+
|
|
3
|
+
规范源:`docs/junsi-dev-docs/2-架构设计/主题语义Token规范v1.md`(实现:`src/theme/`)。插件 UI 主题的**唯一正确做法**:全量经 `var(--*)` 消费语义 token,禁止内联色值。
|
|
4
|
+
|
|
5
|
+
## 三级语义模型
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
primitives(原始色板)→ semantic(语义角色)→ component(CSS 变量,唯一被 var() 读取)
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
v1 落点:`.qtheme` 主题直接表达 semantic/component 层(即 `--*` 平铺变量)。插件不写主题,只**消费**这些变量。token 点分命名,`.` 归一化为 `-`(`background.emphasis` → `--background-emphasis`)。
|
|
12
|
+
|
|
13
|
+
## 色板 token(plugin-ui 消费全集)
|
|
14
|
+
|
|
15
|
+
| token(theme.json 键) | CSS 变量 | 默认值(dark) | 语义 |
|
|
16
|
+
|---|---|---|---|
|
|
17
|
+
| background | `--background` | `230 20% 6%` | 页面底色 |
|
|
18
|
+
| foreground | `--foreground` | `220 20% 93%` | 主文字 |
|
|
19
|
+
| card / card-foreground | `--card` / `--card-foreground` | `228 18% 10%` / `220 20% 93%` | 卡片 |
|
|
20
|
+
| popover / popover-foreground | `--popover` / `--popover-foreground` | `228 18% 10%` / `220 20% 93%` | 浮层 |
|
|
21
|
+
| primary / primary-foreground | `--primary` / `--primary-foreground` | `142 71% 48%` / `230 20% 6%` | 主强调 |
|
|
22
|
+
| secondary / secondary-foreground | `--secondary` / `--secondary-foreground` | `228 18% 14%` / `220 20% 93%` | 次级 |
|
|
23
|
+
| muted / muted-foreground | `--muted` / `--muted-foreground` | `228 10% 18%` / `228 8% 55%` | 弱化 |
|
|
24
|
+
| accent / accent-foreground | `--accent` / `--accent-foreground` | `228 18% 14%` / `220 20% 93%` | 强调底 |
|
|
25
|
+
| destructive / destructive-foreground | `--destructive` / `--destructive-foreground` | `0 84% 60%` / `220 20% 93%` | 危险 |
|
|
26
|
+
| border | `--border` | `228 14% 21%` | 边框 |
|
|
27
|
+
| input | `--input` | `228 14% 21%` | 输入框 |
|
|
28
|
+
| ring | `--ring` | `142 71% 48%` | 焦点环 |
|
|
29
|
+
|
|
30
|
+
扩展语义(可选,emit 为 `--foreground-accent` 等):`foreground.accent`、`foreground.muted`、`foreground.destructive`、`background.elevated`、`background.emphasis`、`background.sunken`、`border.strong`、`border.accent`、`accent.hover`、`accent.active`、`status.success`、`status.warning`、`status.error`。
|
|
31
|
+
|
|
32
|
+
## 非色 token
|
|
33
|
+
|
|
34
|
+
| token | CSS 变量 | 默认值 | 说明 |
|
|
35
|
+
|---|---|---|---|
|
|
36
|
+
| radius | `--radius` | `0.625rem` | 圆角 |
|
|
37
|
+
| glass-blur | `--glass-blur` | `18px` | 毛玻璃模糊 |
|
|
38
|
+
|
|
39
|
+
## var() 消费约定
|
|
40
|
+
|
|
41
|
+
- **全部用 `var(--*)`,禁止内联色值**(`#hex` / `rgb()` / `hsl()` 字面量)。plugin-ui 组件已全量 var() 消费,换主题即时生效,无需重建 dist。
|
|
42
|
+
- 颜色值多为 HSL 三元组(如 `142 71% 48%`),组件库经 `hsl(var(--primary))` 解析。插件自定义 CSS 需要时同样写 `hsl(var(--primary) / <alpha>)` 形式。
|
|
43
|
+
- Tailwind 侧直接用语义类名:`bg-primary`、`text-foreground`、`bg-muted`、`text-muted-foreground`、`border-border` 等(`@qomicex/plugin-ui/tailwind-preset` 已映射)。
|
|
44
|
+
|
|
45
|
+
## 主题贡献(entry.theme)
|
|
46
|
+
|
|
47
|
+
- manifest `entry.theme` 指向 `dist/theme.css`,激活时注入 `<style data-plugin-theme>`。
|
|
48
|
+
- 主题 CSS 只能**覆盖/补充** token,仍须全部 `var()` 引用,禁止内联色值:
|
|
49
|
+
|
|
50
|
+
```css
|
|
51
|
+
:root[data-theme] {
|
|
52
|
+
/* 可选:覆盖默认 HSL token */
|
|
53
|
+
--primary: 142 71% 48%;
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
- `qomicex pack` 会自动把根目录的 `theme.css` 拷入 `dist/theme.css`(若 manifest 引用 `dist/theme.css`)。
|
|
58
|
+
- **不要在插件里定义与启动器冲突的平铺变量**;需要私有样式时走组件 class(Tailwind)或局部作用域。
|