skills-console 0.4.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 +30 -0
- package/LICENSE +21 -0
- package/README.md +130 -0
- package/dist/adapters/filesystem/agent-registry.d.ts +5 -0
- package/dist/adapters/filesystem/agent-registry.js +236 -0
- package/dist/adapters/filesystem/agent-registry.js.map +1 -0
- package/dist/adapters/filesystem/frontmatter.d.ts +2 -0
- package/dist/adapters/filesystem/frontmatter.js +73 -0
- package/dist/adapters/filesystem/frontmatter.js.map +1 -0
- package/dist/adapters/filesystem/skill-scanner.d.ts +8 -0
- package/dist/adapters/filesystem/skill-scanner.js +157 -0
- package/dist/adapters/filesystem/skill-scanner.js.map +1 -0
- package/dist/adapters/filesystem/skills-lock.d.ts +2 -0
- package/dist/adapters/filesystem/skills-lock.js +44 -0
- package/dist/adapters/filesystem/skills-lock.js.map +1 -0
- package/dist/adapters/skills-cli/command-builder.d.ts +7 -0
- package/dist/adapters/skills-cli/command-builder.js +144 -0
- package/dist/adapters/skills-cli/command-builder.js.map +1 -0
- package/dist/adapters/skills-cli/executor.d.ts +20 -0
- package/dist/adapters/skills-cli/executor.js +51 -0
- package/dist/adapters/skills-cli/executor.js.map +1 -0
- package/dist/adapters/skills-cli/source-parser.d.ts +3 -0
- package/dist/adapters/skills-cli/source-parser.js +38 -0
- package/dist/adapters/skills-cli/source-parser.js.map +1 -0
- package/dist/adapters/skills-cli/types.d.ts +56 -0
- package/dist/adapters/skills-cli/types.js +2 -0
- package/dist/adapters/skills-cli/types.js.map +1 -0
- package/dist/application/backup-manager.d.ts +7 -0
- package/dist/application/backup-manager.js +164 -0
- package/dist/application/backup-manager.js.map +1 -0
- package/dist/application/build-inventory.d.ts +5 -0
- package/dist/application/build-inventory.js +103 -0
- package/dist/application/build-inventory.js.map +1 -0
- package/dist/application/doctor-fixes.d.ts +21 -0
- package/dist/application/doctor-fixes.js +103 -0
- package/dist/application/doctor-fixes.js.map +1 -0
- package/dist/application/history-store.d.ts +5 -0
- package/dist/application/history-store.js +42 -0
- package/dist/application/history-store.js.map +1 -0
- package/dist/application/profile-apply.d.ts +22 -0
- package/dist/application/profile-apply.js +69 -0
- package/dist/application/profile-apply.js.map +1 -0
- package/dist/application/profile-diff.d.ts +3 -0
- package/dist/application/profile-diff.js +105 -0
- package/dist/application/profile-diff.js.map +1 -0
- package/dist/application/profile-store.d.ts +9 -0
- package/dist/application/profile-store.js +109 -0
- package/dist/application/profile-store.js.map +1 -0
- package/dist/application/restore-operation.d.ts +8 -0
- package/dist/application/restore-operation.js +27 -0
- package/dist/application/restore-operation.js.map +1 -0
- package/dist/application/skill-operations.d.ts +32 -0
- package/dist/application/skill-operations.js +129 -0
- package/dist/application/skill-operations.js.map +1 -0
- package/dist/cli-commands.d.ts +8 -0
- package/dist/cli-commands.js +111 -0
- package/dist/cli-commands.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +15 -0
- package/dist/cli.js.map +1 -0
- package/dist/domain/operations.d.ts +50 -0
- package/dist/domain/operations.js +25 -0
- package/dist/domain/operations.js.map +1 -0
- package/dist/domain/profile.d.ts +43 -0
- package/dist/domain/profile.js +2 -0
- package/dist/domain/profile.js.map +1 -0
- package/dist/domain/types.d.ts +98 -0
- package/dist/domain/types.js +2 -0
- package/dist/domain/types.js.map +1 -0
- package/dist/platform/data-paths.d.ts +3 -0
- package/dist/platform/data-paths.js +17 -0
- package/dist/platform/data-paths.js.map +1 -0
- package/dist/platform/environment.d.ts +6 -0
- package/dist/platform/environment.js +71 -0
- package/dist/platform/environment.js.map +1 -0
- package/dist/platform/redaction.d.ts +1 -0
- package/dist/platform/redaction.js +7 -0
- package/dist/platform/redaction.js.map +1 -0
- package/dist/ui/App.d.ts +2 -0
- package/dist/ui/App.js +330 -0
- package/dist/ui/App.js.map +1 -0
- package/dist/ui/DoctorFixWizard.d.ts +12 -0
- package/dist/ui/DoctorFixWizard.js +58 -0
- package/dist/ui/DoctorFixWizard.js.map +1 -0
- package/dist/ui/OperationWizard.d.ts +19 -0
- package/dist/ui/OperationWizard.js +301 -0
- package/dist/ui/OperationWizard.js.map +1 -0
- package/dist/ui/ProfileWizard.d.ts +15 -0
- package/dist/ui/ProfileWizard.js +68 -0
- package/dist/ui/ProfileWizard.js.map +1 -0
- package/dist/ui/RestoreWizard.d.ts +12 -0
- package/dist/ui/RestoreWizard.js +42 -0
- package/dist/ui/RestoreWizard.js.map +1 -0
- package/dist/version.d.ts +1 -0
- package/dist/version.js +2 -0
- package/dist/version.js.map +1 -0
- package/docs/ARCHITECTURE.md +145 -0
- package/docs/OPERATIONS.md +200 -0
- package/docs/PROFILES.md +83 -0
- package/examples/skills-profile.json +21 -0
- package/package.json +71 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
本项目遵循 [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) 的结构。正式发布版本采用语义化版本号。
|
|
4
|
+
|
|
5
|
+
## [0.4.0] - 2026-07-17
|
|
6
|
+
|
|
7
|
+
首个正式交付版本。
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- 跨 Agent 本地 Skill 清单,覆盖用户、项目、共享、系统和 Codex 插件缓存根目录。
|
|
12
|
+
- Dashboard、Skills、Agents、Doctor、Profiles 和 History 六个 TUI 页面。
|
|
13
|
+
- 基于固定 `skills@1.5.17` 的来源预览、安装、更新和移除向导。
|
|
14
|
+
- 写前事务快照、脱敏操作历史、执行后重新扫描验证和恢复工作流。
|
|
15
|
+
- 目录名与 Skill 名不一致时的可逆 Doctor 修复。
|
|
16
|
+
- `skills-profile.json` 导出、校验、期望状态 diff 和受保护的顺序应用。
|
|
17
|
+
- 面向脚本的 inventory/profile CLI 与 JSON 输出。
|
|
18
|
+
- MIT License、公开 npm 发行元数据和开源贡献/安全策略。
|
|
19
|
+
- Node.js 22/24 CI 与基于 GitHub Actions OIDC 的 npm Trusted Publishing 工作流。
|
|
20
|
+
|
|
21
|
+
### Security
|
|
22
|
+
|
|
23
|
+
- 外部命令通过参数数组和 `shell: false` 执行。
|
|
24
|
+
- 增加凭据脱敏、受管根目录写保护、恢复路径边界校验和上游 no-op 检测。
|
|
25
|
+
- Codex 系统目录和插件缓存被标记为外部托管,只允许读取。
|
|
26
|
+
|
|
27
|
+
### Known limitations
|
|
28
|
+
|
|
29
|
+
- 更新后的验证只能确认安装仍存在,不能进行内容级版本证明。
|
|
30
|
+
- Windows 原生环境尚未进入正式支持矩阵。
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 CaoLiangqiang
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
# Skills Console
|
|
2
|
+
|
|
3
|
+
Skills Console 是一个本地优先的 Agent Skills 管理控制台。它用可视化 TUI 汇总当前用户和项目中的 Skills,通过固定版本的 [`skills`](https://github.com/vercel-labs/skills) CLI 执行安装、更新和移除,并为每次写操作保存可审计、可恢复的事务记录。
|
|
4
|
+
|
|
5
|
+
当前正式版本为 `0.4.0`,以 MIT License 开源,通过 GitHub 提供源码,并以公开 npm 包和可安装 tarball 交付。
|
|
6
|
+
|
|
7
|
+
## 产品形态
|
|
8
|
+
|
|
9
|
+
- 一个命令启动的六页 TUI:Dashboard、Skills、Agents、Doctor、Profiles、History。
|
|
10
|
+
- 一个面向自动化的只读 CLI:清单输出、Profile 导出、校验和 drift 检查。
|
|
11
|
+
- 一个本地事务层:写前快照、脱敏历史、执行后扫描验证和 History 恢复。
|
|
12
|
+
- 一个期望状态模型:用可版本控制的 `skills-profile.json` 描述项目需要的 Skills。
|
|
13
|
+
- 零产品遥测、无后台服务、无云端账号;本地文件系统是状态事实来源。
|
|
14
|
+
|
|
15
|
+
已内置识别 OpenAI Codex、Claude Code、Gemini CLI、Cursor、GitHub Copilot、OpenCode、Cline、Windsurf、Roo Code、Kiro CLI、Continue 和 Goose 的常见目录。只有已检测到的 Agent 目录会进入清单;Codex 系统 Skills 和插件缓存作为外部托管来源,只读展示。
|
|
16
|
+
|
|
17
|
+
## 环境要求
|
|
18
|
+
|
|
19
|
+
- Node.js `>=22`
|
|
20
|
+
- npm `>=10`
|
|
21
|
+
- 支持 Linux、macOS 和 WSL;Windows 原生环境尚未作为本版本发布平台验收
|
|
22
|
+
- 交互模式需要 TTY;非交互环境请使用 CLI 子命令
|
|
23
|
+
|
|
24
|
+
## 安装与运行
|
|
25
|
+
|
|
26
|
+
直接运行或全局安装公开 npm 包:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
npx skills-console
|
|
30
|
+
npm install --global skills-console
|
|
31
|
+
skills-console
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
从源码运行:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
npm ci
|
|
38
|
+
npm run dev
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
构建后运行:
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
npm run build
|
|
45
|
+
npm start
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
从发布 tarball 安装:
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
npm pack
|
|
52
|
+
npm install --global ./skills-console-0.4.0.tgz
|
|
53
|
+
skills-console
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
包名、源码仓库、问题反馈地址和许可证均记录在 `package.json`。首次占用包名由维护者在认证终端完成;后续发布由带 OIDC 短期凭据的 GitHub Actions Trusted Publishing 工作流执行,不在仓库保存长期 npm token。
|
|
57
|
+
|
|
58
|
+
## TUI 操作
|
|
59
|
+
|
|
60
|
+
| 按键 | 操作 |
|
|
61
|
+
| --- | --- |
|
|
62
|
+
| `←` / `→` 或 `h` / `l` | 切换页面 |
|
|
63
|
+
| `↑` / `↓` 或 `k` / `j` | 移动选择 |
|
|
64
|
+
| `/` | 搜索 Skill |
|
|
65
|
+
| `r` | 重新扫描 |
|
|
66
|
+
| `i` | 安装 Skill |
|
|
67
|
+
| `u` / `d` | 更新 / 移除当前 Skill |
|
|
68
|
+
| `f` | 执行当前 Doctor 可逆修复 |
|
|
69
|
+
| `p` | 导出或应用 Profile |
|
|
70
|
+
| `z` | 恢复当前 History 操作 |
|
|
71
|
+
| `q` | 退出或关闭当前向导 |
|
|
72
|
+
|
|
73
|
+
安装向导先以只读方式列出来源中的 Skills,再选择 Skill、Agent、项目或用户作用域,以及 symlink 或 copy 模式。写操作会显示与实际执行同源的脱敏命令预览;用户确认后才会运行。
|
|
74
|
+
|
|
75
|
+
## 非交互 CLI
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
# 文本清单摘要或完整 JSON 清单
|
|
79
|
+
skills-console inventory
|
|
80
|
+
skills-console inventory --json
|
|
81
|
+
skills-console --json
|
|
82
|
+
|
|
83
|
+
# 导出项目期望状态;默认写入 ./skills-profile.json
|
|
84
|
+
skills-console profile export [path] [--include-user] [--json]
|
|
85
|
+
|
|
86
|
+
# 校验与比较期望状态
|
|
87
|
+
skills-console profile validate [path]
|
|
88
|
+
skills-console profile diff [path] [--json]
|
|
89
|
+
|
|
90
|
+
skills-console --version
|
|
91
|
+
skills-console --help
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
通用退出码:`0` 表示成功或期望状态已满足,`1` 表示命令、配置或运行错误,`2` 仅用于 `profile diff` 表示存在可执行 drift。
|
|
95
|
+
|
|
96
|
+
Profile 默认只管理当前项目作用域,不删除未声明 Skill。详细 schema 和安全语义见 [Profile 协议](docs/PROFILES.md)。
|
|
97
|
+
|
|
98
|
+
## 安全与恢复
|
|
99
|
+
|
|
100
|
+
- `skills@1.5.17` 是直接依赖;运行时使用已安装的精确版本,不临时下载 latest。
|
|
101
|
+
- 子进程使用参数数组和 `shell: false`,预览文本与执行计划来自同一对象。
|
|
102
|
+
- 工具不会运行 Skill 仓库内的脚本;来源预览只读取上游 CLI 返回的清单。
|
|
103
|
+
- 写操作前备份所有匹配的可变安装,备份失败则不继续。
|
|
104
|
+
- 恢复前校验目标位于记录的 Skill 根目录内;软链接目标丢失时恢复为普通目录。
|
|
105
|
+
- 命令、日志和来源中的凭据会脱敏;History 最多保留每次执行的最后 200 行输出。
|
|
106
|
+
- Doctor 只自动处理目标明确且可逆的目录名不一致;其余诊断保持只读。
|
|
107
|
+
- 更新操作目前只能确认 Skill 仍然存在,不能证明内容版本确实变化,因此会标记为 `indeterminate`。
|
|
108
|
+
|
|
109
|
+
运行数据保存在:
|
|
110
|
+
|
|
111
|
+
```text
|
|
112
|
+
${XDG_DATA_HOME:-~/.local/share}/skills-console/history/
|
|
113
|
+
${XDG_DATA_HOME:-~/.local/share}/skills-console/backups/
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
完整实现边界见 [架构说明](docs/ARCHITECTURE.md),生产安装、验证、故障处理和发布步骤见 [运维与发布手册](docs/OPERATIONS.md)。
|
|
117
|
+
|
|
118
|
+
## 开发与验证
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
npm ci
|
|
122
|
+
npm run typecheck
|
|
123
|
+
npm test
|
|
124
|
+
npm run build
|
|
125
|
+
npm pack --dry-run
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
测试必须只使用临时 HOME/XDG 目录或 fixture,不得修改开发者真实的 Skills。版本变化记录见 [CHANGELOG](CHANGELOG.md)。
|
|
129
|
+
|
|
130
|
+
贡献流程见 [CONTRIBUTING](CONTRIBUTING.md),安全漏洞请按 [SECURITY](SECURITY.md) 私下报告。本项目依据 [MIT License](LICENSE) 发布。
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
import { access, stat } from 'node:fs/promises';
|
|
2
|
+
import { constants } from 'node:fs';
|
|
3
|
+
import { join, normalize } from 'node:path';
|
|
4
|
+
import { executableExists } from '../../platform/environment.js';
|
|
5
|
+
async function pathState(path) {
|
|
6
|
+
try {
|
|
7
|
+
await stat(path);
|
|
8
|
+
}
|
|
9
|
+
catch {
|
|
10
|
+
return { exists: false, readable: false, writable: false };
|
|
11
|
+
}
|
|
12
|
+
let readable = false;
|
|
13
|
+
let writable = false;
|
|
14
|
+
try {
|
|
15
|
+
await access(path, constants.R_OK);
|
|
16
|
+
readable = true;
|
|
17
|
+
}
|
|
18
|
+
catch {
|
|
19
|
+
// Represent access failures in the returned state.
|
|
20
|
+
}
|
|
21
|
+
try {
|
|
22
|
+
await access(path, constants.W_OK);
|
|
23
|
+
writable = true;
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
// Represent access failures in the returned state.
|
|
27
|
+
}
|
|
28
|
+
return { exists: true, readable, writable };
|
|
29
|
+
}
|
|
30
|
+
function definitions(environment) {
|
|
31
|
+
const home = environment.homeDir;
|
|
32
|
+
const project = environment.projectRoot;
|
|
33
|
+
const user = (path, options = {}) => ({
|
|
34
|
+
path: join(home, path),
|
|
35
|
+
...options,
|
|
36
|
+
});
|
|
37
|
+
const local = (path, options = {}) => ({
|
|
38
|
+
path: join(project, path),
|
|
39
|
+
...options,
|
|
40
|
+
});
|
|
41
|
+
return [
|
|
42
|
+
{
|
|
43
|
+
id: 'codex',
|
|
44
|
+
displayName: 'OpenAI Codex',
|
|
45
|
+
commands: ['codex'],
|
|
46
|
+
markerPaths: [join(home, '.codex')],
|
|
47
|
+
userRoots: [
|
|
48
|
+
user('.codex/skills', { excludedDirectoryNames: ['.system'] }),
|
|
49
|
+
user('.codex/skills/.system', {
|
|
50
|
+
kind: 'system',
|
|
51
|
+
mutable: false,
|
|
52
|
+
maxDepth: 3,
|
|
53
|
+
}),
|
|
54
|
+
user('.agents/skills', { kind: 'shared' }),
|
|
55
|
+
user('.codex/plugins/cache', {
|
|
56
|
+
kind: 'plugin-cache',
|
|
57
|
+
mutable: false,
|
|
58
|
+
maxDepth: 9,
|
|
59
|
+
}),
|
|
60
|
+
],
|
|
61
|
+
projectRoots: [local('.agents/skills', { kind: 'shared' }), local('.codex/skills')],
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
id: 'claude-code',
|
|
65
|
+
displayName: 'Claude Code',
|
|
66
|
+
commands: ['claude'],
|
|
67
|
+
markerPaths: [join(home, '.claude')],
|
|
68
|
+
userRoots: [user('.claude/skills')],
|
|
69
|
+
projectRoots: [local('.claude/skills')],
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
id: 'gemini-cli',
|
|
73
|
+
displayName: 'Gemini CLI',
|
|
74
|
+
commands: ['gemini'],
|
|
75
|
+
markerPaths: [join(home, '.gemini')],
|
|
76
|
+
userRoots: [user('.gemini/skills')],
|
|
77
|
+
projectRoots: [local('.agents/skills', { kind: 'shared' })],
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
id: 'cursor',
|
|
81
|
+
displayName: 'Cursor',
|
|
82
|
+
commands: ['cursor'],
|
|
83
|
+
markerPaths: [join(home, '.cursor')],
|
|
84
|
+
userRoots: [user('.cursor/skills')],
|
|
85
|
+
projectRoots: [local('.agents/skills', { kind: 'shared' })],
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
id: 'github-copilot',
|
|
89
|
+
displayName: 'GitHub Copilot',
|
|
90
|
+
commands: ['github-copilot'],
|
|
91
|
+
markerPaths: [join(home, '.copilot')],
|
|
92
|
+
userRoots: [user('.copilot/skills')],
|
|
93
|
+
projectRoots: [local('.agents/skills', { kind: 'shared' })],
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
id: 'opencode',
|
|
97
|
+
displayName: 'OpenCode',
|
|
98
|
+
commands: ['opencode'],
|
|
99
|
+
markerPaths: [join(home, '.config/opencode')],
|
|
100
|
+
userRoots: [user('.config/opencode/skills')],
|
|
101
|
+
projectRoots: [local('.agents/skills', { kind: 'shared' })],
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
id: 'cline',
|
|
105
|
+
displayName: 'Cline',
|
|
106
|
+
commands: [],
|
|
107
|
+
markerPaths: [join(home, '.cline')],
|
|
108
|
+
userRoots: [user('.agents/skills', { kind: 'shared' })],
|
|
109
|
+
projectRoots: [local('.agents/skills', { kind: 'shared' })],
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
id: 'windsurf',
|
|
113
|
+
displayName: 'Windsurf',
|
|
114
|
+
commands: ['windsurf'],
|
|
115
|
+
markerPaths: [join(home, '.codeium/windsurf')],
|
|
116
|
+
userRoots: [user('.codeium/windsurf/skills')],
|
|
117
|
+
projectRoots: [local('.windsurf/skills')],
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
id: 'roo',
|
|
121
|
+
displayName: 'Roo Code',
|
|
122
|
+
commands: [],
|
|
123
|
+
markerPaths: [join(home, '.roo')],
|
|
124
|
+
userRoots: [user('.roo/skills')],
|
|
125
|
+
projectRoots: [local('.roo/skills')],
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
id: 'kiro-cli',
|
|
129
|
+
displayName: 'Kiro CLI',
|
|
130
|
+
commands: ['kiro-cli', 'kiro'],
|
|
131
|
+
markerPaths: [join(home, '.kiro')],
|
|
132
|
+
userRoots: [user('.kiro/skills')],
|
|
133
|
+
projectRoots: [local('.kiro/skills')],
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
id: 'continue',
|
|
137
|
+
displayName: 'Continue',
|
|
138
|
+
commands: [],
|
|
139
|
+
markerPaths: [join(home, '.continue')],
|
|
140
|
+
userRoots: [user('.continue/skills')],
|
|
141
|
+
projectRoots: [local('.continue/skills')],
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
id: 'goose',
|
|
145
|
+
displayName: 'Goose',
|
|
146
|
+
commands: ['goose'],
|
|
147
|
+
markerPaths: [join(home, '.config/goose')],
|
|
148
|
+
userRoots: [user('.config/goose/skills')],
|
|
149
|
+
projectRoots: [local('.goose/skills')],
|
|
150
|
+
},
|
|
151
|
+
];
|
|
152
|
+
}
|
|
153
|
+
async function markerExists(paths) {
|
|
154
|
+
const matches = [];
|
|
155
|
+
for (const path of paths) {
|
|
156
|
+
if ((await pathState(path)).exists) {
|
|
157
|
+
matches.push(`config:${path}`);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
return matches;
|
|
161
|
+
}
|
|
162
|
+
async function commandMatches(commands) {
|
|
163
|
+
const matches = [];
|
|
164
|
+
for (const command of commands) {
|
|
165
|
+
if (await executableExists(command)) {
|
|
166
|
+
matches.push(`command:${command}`);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
return matches;
|
|
170
|
+
}
|
|
171
|
+
function rootKey(candidate) {
|
|
172
|
+
return `${candidate.scope}:${normalize(candidate.path)}`;
|
|
173
|
+
}
|
|
174
|
+
export async function resolveAgentRegistry(environment) {
|
|
175
|
+
const resolvedAgents = [];
|
|
176
|
+
for (const definition of definitions(environment)) {
|
|
177
|
+
const reasons = [
|
|
178
|
+
...(await markerExists(definition.markerPaths)),
|
|
179
|
+
...(await commandMatches(definition.commands)),
|
|
180
|
+
];
|
|
181
|
+
const ownRootExists = await Promise.all([...definition.userRoots, ...definition.projectRoots]
|
|
182
|
+
.filter((root) => root.kind !== 'shared')
|
|
183
|
+
.map(async (root) => (await pathState(root.path)).exists));
|
|
184
|
+
resolvedAgents.push({
|
|
185
|
+
definition,
|
|
186
|
+
detected: reasons.length > 0 || ownRootExists.some(Boolean),
|
|
187
|
+
reasons,
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
const candidates = [];
|
|
191
|
+
for (const agent of resolvedAgents.filter((item) => item.detected)) {
|
|
192
|
+
candidates.push(...agent.definition.userRoots.map((root) => ({
|
|
193
|
+
...root,
|
|
194
|
+
scope: 'user',
|
|
195
|
+
agentId: agent.definition.id,
|
|
196
|
+
})), ...agent.definition.projectRoots.map((root) => ({
|
|
197
|
+
...root,
|
|
198
|
+
scope: 'project',
|
|
199
|
+
agentId: agent.definition.id,
|
|
200
|
+
})));
|
|
201
|
+
}
|
|
202
|
+
const grouped = new Map();
|
|
203
|
+
for (const candidate of candidates) {
|
|
204
|
+
const key = rootKey(candidate);
|
|
205
|
+
grouped.set(key, [...(grouped.get(key) ?? []), candidate]);
|
|
206
|
+
}
|
|
207
|
+
const roots = [];
|
|
208
|
+
for (const [id, group] of grouped) {
|
|
209
|
+
const first = group[0];
|
|
210
|
+
if (!first) {
|
|
211
|
+
continue;
|
|
212
|
+
}
|
|
213
|
+
const state = await pathState(first.path);
|
|
214
|
+
roots.push({
|
|
215
|
+
id,
|
|
216
|
+
path: first.path,
|
|
217
|
+
scope: first.scope,
|
|
218
|
+
kind: first.kind ?? 'agent',
|
|
219
|
+
agentIds: [...new Set(group.map((item) => item.agentId))].sort(),
|
|
220
|
+
...state,
|
|
221
|
+
mutable: first.mutable ?? true,
|
|
222
|
+
maxDepth: first.maxDepth ?? 5,
|
|
223
|
+
excludedDirectoryNames: first.excludedDirectoryNames ?? [],
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
roots.sort((a, b) => a.path.localeCompare(b.path));
|
|
227
|
+
const agents = resolvedAgents.map(({ definition, detected, reasons }) => ({
|
|
228
|
+
id: definition.id,
|
|
229
|
+
displayName: definition.displayName,
|
|
230
|
+
detected,
|
|
231
|
+
detectionReasons: reasons,
|
|
232
|
+
roots: roots.filter((root) => root.agentIds.includes(definition.id)),
|
|
233
|
+
}));
|
|
234
|
+
return { agents, roots };
|
|
235
|
+
}
|
|
236
|
+
//# sourceMappingURL=agent-registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-registry.js","sourceRoot":"","sources":["../../../src/adapters/filesystem/agent-registry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { parseDocument } from 'yaml';
|
|
2
|
+
const NAME_PATTERN = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
|
3
|
+
function optionalString(value) {
|
|
4
|
+
return typeof value === 'string' && value.trim() ? value.trim() : undefined;
|
|
5
|
+
}
|
|
6
|
+
function sourceFromMetadata(metadata) {
|
|
7
|
+
const candidates = [
|
|
8
|
+
metadata.source,
|
|
9
|
+
metadata.repository,
|
|
10
|
+
metadata.sourceUrl,
|
|
11
|
+
metadata['source-url'],
|
|
12
|
+
];
|
|
13
|
+
return candidates.map(optionalString).find(Boolean);
|
|
14
|
+
}
|
|
15
|
+
export function parseSkillManifest(content) {
|
|
16
|
+
const empty = {
|
|
17
|
+
name: undefined,
|
|
18
|
+
description: undefined,
|
|
19
|
+
license: undefined,
|
|
20
|
+
compatibility: undefined,
|
|
21
|
+
allowedTools: undefined,
|
|
22
|
+
metadata: {},
|
|
23
|
+
source: undefined,
|
|
24
|
+
valid: false,
|
|
25
|
+
errors: [],
|
|
26
|
+
};
|
|
27
|
+
const match = /^---\r?\n([\s\S]*?)\r?\n---(?:\r?\n|$)/.exec(content);
|
|
28
|
+
if (!match?.[1]) {
|
|
29
|
+
return { ...empty, errors: ['Missing YAML frontmatter delimited by --- lines.'] };
|
|
30
|
+
}
|
|
31
|
+
const document = parseDocument(match[1], { logLevel: 'silent', prettyErrors: true });
|
|
32
|
+
const parseErrors = document.errors.map((error) => error.message);
|
|
33
|
+
const value = document.toJS();
|
|
34
|
+
if (!value || typeof value !== 'object' || Array.isArray(value)) {
|
|
35
|
+
return {
|
|
36
|
+
...empty,
|
|
37
|
+
errors: [...parseErrors, 'Frontmatter must be a YAML mapping.'],
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
const record = value;
|
|
41
|
+
const metadata = record.metadata && typeof record.metadata === 'object' && !Array.isArray(record.metadata)
|
|
42
|
+
? record.metadata
|
|
43
|
+
: {};
|
|
44
|
+
const name = optionalString(record.name);
|
|
45
|
+
const description = optionalString(record.description);
|
|
46
|
+
const errors = [...parseErrors];
|
|
47
|
+
if (!name) {
|
|
48
|
+
errors.push('Missing required name field.');
|
|
49
|
+
}
|
|
50
|
+
else if (!NAME_PATTERN.test(name) || name.length > 64) {
|
|
51
|
+
errors.push('Name must be 1-64 lowercase letters, numbers, or hyphen-separated words.');
|
|
52
|
+
}
|
|
53
|
+
if (!description) {
|
|
54
|
+
errors.push('Missing required description field.');
|
|
55
|
+
}
|
|
56
|
+
else if (description.length > 1024) {
|
|
57
|
+
errors.push('Description exceeds 1024 characters.');
|
|
58
|
+
}
|
|
59
|
+
return {
|
|
60
|
+
name,
|
|
61
|
+
description,
|
|
62
|
+
license: optionalString(record.license),
|
|
63
|
+
compatibility: optionalString(record.compatibility),
|
|
64
|
+
allowedTools: optionalString(record['allowed-tools']),
|
|
65
|
+
metadata,
|
|
66
|
+
source: optionalString(record.source) ??
|
|
67
|
+
optionalString(record.repository) ??
|
|
68
|
+
sourceFromMetadata(metadata),
|
|
69
|
+
valid: errors.length === 0,
|
|
70
|
+
errors,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=frontmatter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"frontmatter.js","sourceRoot":"","sources":["../../../src/adapters/filesystem/frontmatter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Diagnostic, SkillInstallation, SkillRoot } from '../../domain/types.js';
|
|
2
|
+
interface ScanResult {
|
|
3
|
+
installations: SkillInstallation[];
|
|
4
|
+
diagnostics: Diagnostic[];
|
|
5
|
+
}
|
|
6
|
+
export declare function scanSkillRoot(root: SkillRoot): Promise<ScanResult>;
|
|
7
|
+
export declare function scanSkillRoots(roots: SkillRoot[]): Promise<ScanResult>;
|
|
8
|
+
export {};
|