oneskill 0.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/LICENSE +176 -0
- package/README.md +171 -0
- package/SKILL.md +59 -0
- package/dist/cli.js +411 -0
- package/dist/cli.js.map +1 -0
- package/package.json +45 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
Apache License
|
|
2
|
+
Version 2.0, January 2004
|
|
3
|
+
http://www.apache.org/licenses/
|
|
4
|
+
|
|
5
|
+
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
6
|
+
|
|
7
|
+
1. Definitions.
|
|
8
|
+
|
|
9
|
+
"License" shall mean the terms and conditions for use, reproduction,
|
|
10
|
+
and distribution as defined by Sections 1 through 9 of this document.
|
|
11
|
+
|
|
12
|
+
"Licensor" shall mean the copyright owner or entity authorized by
|
|
13
|
+
the copyright owner that is granting the License.
|
|
14
|
+
|
|
15
|
+
"Legal Entity" shall mean the union of the acting entity and all
|
|
16
|
+
other entities that control, are controlled by, or are under common
|
|
17
|
+
control with that entity. For the purposes of this definition,
|
|
18
|
+
"control" means (i) the power, direct or indirect, to cause the
|
|
19
|
+
direction or management of such entity, whether by contract or
|
|
20
|
+
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
|
21
|
+
outstanding shares, or (iii) beneficial ownership of such entity.
|
|
22
|
+
|
|
23
|
+
"You" (or "Your") shall mean an individual or Legal Entity
|
|
24
|
+
exercising permissions granted by this License.
|
|
25
|
+
|
|
26
|
+
"Source" form shall mean the preferred form for making modifications,
|
|
27
|
+
including but not limited to software source code, documentation
|
|
28
|
+
source, and configuration files.
|
|
29
|
+
|
|
30
|
+
"Object" form shall mean any form resulting from mechanical
|
|
31
|
+
transformation or translation of a Source form, including but
|
|
32
|
+
not limited to compiled object code, generated documentation,
|
|
33
|
+
and conversions to other media types.
|
|
34
|
+
|
|
35
|
+
"Work" shall mean the work of authorship, whether in Source or
|
|
36
|
+
Object form, made available under the License, as indicated by a
|
|
37
|
+
copyright notice that is included in or attached to the work
|
|
38
|
+
(an example is provided in the Appendix below).
|
|
39
|
+
|
|
40
|
+
"Derivative Works" shall mean any work, whether in Source or Object
|
|
41
|
+
form, that is based on (or derived from) the Work and for which the
|
|
42
|
+
editorial revisions, annotations, elaborations, or other modifications
|
|
43
|
+
represent, as a whole, an original work of authorship. For the purposes
|
|
44
|
+
of this License, Derivative Works shall not include works that remain
|
|
45
|
+
separable from, or merely link (or bind by name) to the interfaces of,
|
|
46
|
+
the Work and Derivative Works thereof.
|
|
47
|
+
|
|
48
|
+
"Contribution" shall mean any work of authorship, including
|
|
49
|
+
the original version of the Work and any modifications or additions
|
|
50
|
+
to that Work or Derivative Works thereof, that is intentionally
|
|
51
|
+
submitted to Licensor for inclusion in the Work by the copyright owner
|
|
52
|
+
or by an individual or Legal Entity authorized to submit on behalf of
|
|
53
|
+
the copyright owner. For the purposes of this definition, "submitted"
|
|
54
|
+
means any form of electronic, verbal, or written communication sent
|
|
55
|
+
to the Licensor or its representatives, including but not limited to
|
|
56
|
+
communication on electronic mailing lists, source code control systems,
|
|
57
|
+
and issue tracking systems that are managed by, or on behalf of, the
|
|
58
|
+
Licensor for the purpose of discussing and improving the Work, but
|
|
59
|
+
excluding communication that is conspicuously marked or otherwise
|
|
60
|
+
designated in writing by the copyright owner as "Not a Contribution."
|
|
61
|
+
|
|
62
|
+
"Contributor" shall mean Licensor and any individual or Legal Entity
|
|
63
|
+
on behalf of whom a Contribution has been received by Licensor and
|
|
64
|
+
subsequently incorporated within the Work.
|
|
65
|
+
|
|
66
|
+
2. Grant of Copyright License. Subject to the terms and conditions of
|
|
67
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
68
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
69
|
+
copyright license to reproduce, prepare Derivative Works of,
|
|
70
|
+
publicly display, publicly perform, sublicense, and distribute the
|
|
71
|
+
Work and such Derivative Works in Source or Object form.
|
|
72
|
+
|
|
73
|
+
3. Grant of Patent License. Subject to the terms and conditions of
|
|
74
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
75
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
76
|
+
(except as stated in this section) patent license to make, have made,
|
|
77
|
+
use, offer to sell, sell, import, and otherwise transfer the Work,
|
|
78
|
+
where such license applies only to those patent claims licensable
|
|
79
|
+
by such Contributor that are necessarily infringed by their
|
|
80
|
+
Contribution(s) alone or by combination of their Contribution(s)
|
|
81
|
+
with the Work to which such Contribution(s) was submitted. If You
|
|
82
|
+
institute patent litigation against any entity (including a
|
|
83
|
+
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
|
84
|
+
or a Contribution incorporated within the Work constitutes direct
|
|
85
|
+
or contributory patent infringement, then any patent licenses
|
|
86
|
+
granted to You under this License for that Work shall terminate
|
|
87
|
+
as of the date such litigation is filed.
|
|
88
|
+
|
|
89
|
+
4. Redistribution. You may reproduce and distribute copies of the
|
|
90
|
+
Work or Derivative Works thereof in any medium, with or without
|
|
91
|
+
modifications, and in Source or Object form, provided that You
|
|
92
|
+
meet the following conditions:
|
|
93
|
+
|
|
94
|
+
(a) You must give any other recipients of the Work or
|
|
95
|
+
Derivative Works a copy of this License; and
|
|
96
|
+
|
|
97
|
+
(b) You must cause any modified files to carry prominent notices
|
|
98
|
+
stating that You changed the files; and
|
|
99
|
+
|
|
100
|
+
(c) You must retain, in the Source form of any Derivative Works
|
|
101
|
+
that You distribute, all copyright, patent, trademark, and
|
|
102
|
+
attribution notices from the Source form of the Work,
|
|
103
|
+
excluding those notices that do not pertain to any part of
|
|
104
|
+
the Derivative Works; and
|
|
105
|
+
|
|
106
|
+
(d) If the Work includes a "NOTICE" text file as part of its
|
|
107
|
+
distribution, then any Derivative Works that You distribute must
|
|
108
|
+
include a readable copy of the attribution notices contained
|
|
109
|
+
within such NOTICE file, excluding those notices that do not
|
|
110
|
+
pertain to any part of the Derivative Works, in at least one
|
|
111
|
+
of the following places: within a NOTICE text file distributed
|
|
112
|
+
as part of the Derivative Works; within the Source form or
|
|
113
|
+
documentation, if provided along with the Derivative Works; or,
|
|
114
|
+
within a display generated by the Derivative Works, if and
|
|
115
|
+
wherever such third-party notices normally appear. The contents
|
|
116
|
+
of the NOTICE file are for informational purposes only and
|
|
117
|
+
do not modify the License. You may add Your own attribution
|
|
118
|
+
notices within Derivative Works that You distribute, alongside
|
|
119
|
+
or as an addendum to the NOTICE text from the Work, provided
|
|
120
|
+
that such additional attribution notices cannot be construed
|
|
121
|
+
as modifying the License.
|
|
122
|
+
|
|
123
|
+
You may add Your own copyright statement to Your modifications and
|
|
124
|
+
may provide additional or different license terms and conditions
|
|
125
|
+
for use, reproduction, or distribution of Your modifications, or
|
|
126
|
+
for any such Derivative Works as a whole, provided Your use,
|
|
127
|
+
reproduction, and distribution of the Work otherwise complies with
|
|
128
|
+
the conditions stated in this License.
|
|
129
|
+
|
|
130
|
+
5. Submission of Contributions. Unless You explicitly state otherwise,
|
|
131
|
+
any Contribution intentionally submitted for inclusion in the Work
|
|
132
|
+
by You to the Licensor shall be under the terms and conditions of
|
|
133
|
+
this License, without any additional terms or conditions.
|
|
134
|
+
Notwithstanding the above, nothing herein shall supersede or modify
|
|
135
|
+
the terms of any separate license agreement you may have executed
|
|
136
|
+
with Licensor regarding such Contributions.
|
|
137
|
+
|
|
138
|
+
6. Trademarks. This License does not grant permission to use the trade
|
|
139
|
+
names, trademarks, service marks, or product names of the Licensor,
|
|
140
|
+
except as required for reasonable and customary use in describing the
|
|
141
|
+
origin of the Work and reproducing the content of the NOTICE file.
|
|
142
|
+
|
|
143
|
+
7. Disclaimer of Warranty. Unless required by applicable law or
|
|
144
|
+
agreed to in writing, Licensor provides the Work (and each
|
|
145
|
+
Contributor provides its Contributions) on an "AS IS" BASIS,
|
|
146
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
147
|
+
implied, including, without limitation, any warranties or conditions
|
|
148
|
+
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
|
149
|
+
PARTICULAR PURPOSE. You are solely responsible for determining the
|
|
150
|
+
appropriateness of using or redistributing the Work and assume any
|
|
151
|
+
risks associated with Your exercise of permissions under this License.
|
|
152
|
+
|
|
153
|
+
8. Limitation of Liability. In no event and under no legal theory,
|
|
154
|
+
whether in tort (including negligence), contract, or otherwise,
|
|
155
|
+
unless required by applicable law (such as deliberate and grossly
|
|
156
|
+
negligent acts) or agreed to in writing, shall any Contributor be
|
|
157
|
+
liable to You for damages, including any direct, indirect, special,
|
|
158
|
+
incidental, or consequential damages of any character arising as a
|
|
159
|
+
result of this License or out of the use or inability to use the
|
|
160
|
+
Work (including but not limited to damages for loss of goodwill,
|
|
161
|
+
work stoppage, computer failure or malfunction, or any and all
|
|
162
|
+
other commercial damages or losses), even if such Contributor
|
|
163
|
+
has been advised of the possibility of such damages.
|
|
164
|
+
|
|
165
|
+
9. Accepting Warranty or Additional Liability. While redistributing
|
|
166
|
+
the Work or Derivative Works thereof, You may choose to offer,
|
|
167
|
+
and charge a fee for, acceptance of support, warranty, indemnity,
|
|
168
|
+
or other liability obligations and/or rights consistent with this
|
|
169
|
+
License. However, in accepting such obligations, You may act only
|
|
170
|
+
on Your own behalf and on Your sole responsibility, not on behalf
|
|
171
|
+
of any other Contributor, and only if You agree to indemnify,
|
|
172
|
+
defend, and hold each Contributor harmless for any liability
|
|
173
|
+
incurred by, or claims asserted against, such Contributor by reason
|
|
174
|
+
of Your accepting any such warranty or additional liability.
|
|
175
|
+
|
|
176
|
+
END OF TERMS AND CONDITIONS
|
package/README.md
ADDED
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
|
|
3
|
+
# OneSkill Meta-Manager
|
|
4
|
+
|
|
5
|
+
**The universal bridge for AI Agent Skills.**
|
|
6
|
+
Discover, install, and map capabilities from the OpenSkills registry to your environment.
|
|
7
|
+
|
|
8
|
+
[](https://www.npmjs.com/package/oneskill)
|
|
9
|
+
[](LICENSE)
|
|
10
|
+
|
|
11
|
+
[**🇺🇸 English**](#-english) | [**🇨🇳 中文指南**](#-中文指南)
|
|
12
|
+
|
|
13
|
+
</div>
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
<a name="-english"></a>
|
|
18
|
+
|
|
19
|
+
## ⚡️ What is OneSkill?
|
|
20
|
+
|
|
21
|
+
**OneSkill** is a meta-tool designed for AI Agents (and humans) to easily extend their capabilities. It serves as a search engine and workflow manager for the [OpenSkills](https://github.com/Starttoaster/openskills) ecosystem.
|
|
22
|
+
|
|
23
|
+
While `openskills` handles the raw installation of files, **OneSkill** provides:
|
|
24
|
+
1. **Intelligent Search**: Find the right tool for the job using natural language or keywords.
|
|
25
|
+
2. **Workflow Guidance**: A standardized process for Agents to acquire new skills safely.
|
|
26
|
+
3. **Environment Mapping**: Crucially, it bridges the gap between `openskills` (standard structure) and consumers like **Gemini CLI** (custom structure).
|
|
27
|
+
|
|
28
|
+
## 🚀 Quick Start
|
|
29
|
+
|
|
30
|
+
You don't need to install it permanently. Just run it with `npx`.
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
# Search for a skill (e.g., to browse the web)
|
|
34
|
+
npx oneskill search "puppeteer browser"
|
|
35
|
+
|
|
36
|
+
# Search for database tools sorted by popularity
|
|
37
|
+
npx oneskill search "database" --sort stars
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## 🛠 Workflow
|
|
41
|
+
|
|
42
|
+
The standard lifecycle for adding a new capability to your Agent:
|
|
43
|
+
|
|
44
|
+
1. **Search**: Find a skill.
|
|
45
|
+
```bash
|
|
46
|
+
npx oneskill search "github integration"
|
|
47
|
+
```
|
|
48
|
+
2. **Install**: Use the standard `openskills` installer.
|
|
49
|
+
```bash
|
|
50
|
+
npx openskills install anthropics/skills
|
|
51
|
+
```
|
|
52
|
+
3. **Map (Important for Gemini)**: If you are using **Gemini CLI**, you must map the installed skills to your configuration.
|
|
53
|
+
```bash
|
|
54
|
+
# Maps installed skills to Gemini's config
|
|
55
|
+
npx oneskill map --target gemini
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## 📖 Command Reference
|
|
59
|
+
|
|
60
|
+
### `search`
|
|
61
|
+
Search the global registry for skills.
|
|
62
|
+
```bash
|
|
63
|
+
npx oneskill search <query> [options]
|
|
64
|
+
|
|
65
|
+
# Options:
|
|
66
|
+
# --category <name> Filter by category
|
|
67
|
+
# --sort <field> Sort by 'stars', 'created', or 'updated'
|
|
68
|
+
# --limit <number> Limit results (default: 10)
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### `map`
|
|
72
|
+
Generates configuration for specific agent environments.
|
|
73
|
+
```bash
|
|
74
|
+
npx oneskill map --target <env>
|
|
75
|
+
|
|
76
|
+
# Targets:
|
|
77
|
+
# gemini Generate/Update Gemini CLI config
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### `list`
|
|
81
|
+
List locally mapped skills (wrapper around openskills list).
|
|
82
|
+
```bash
|
|
83
|
+
npx oneskill list
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
---
|
|
87
|
+
|
|
88
|
+
<br>
|
|
89
|
+
<br>
|
|
90
|
+
|
|
91
|
+
<a name="-中文指南"></a>
|
|
92
|
+
|
|
93
|
+
## 🇨🇳 中文指南
|
|
94
|
+
|
|
95
|
+
[**⬆️ Back to English**](#-english)
|
|
96
|
+
|
|
97
|
+
**OneSkill** 是一个为 AI Agent 设计的通用技能管理工具。它作为 [OpenSkills](https://github.com/Starttoaster/openskills) 生态系统的搜索引擎和工作流管理器,帮助你发现、安装并将能力映射到你的运行环境中。
|
|
98
|
+
|
|
99
|
+
### 核心功能
|
|
100
|
+
|
|
101
|
+
1. **智能搜索**: 支持通过自然语言或关键词搜索注册表中的 Skill。
|
|
102
|
+
2. **工作流引导**: 为 Agent 提供了一套标准的扩展能力流程(搜索 -> 确认 -> 安装)。
|
|
103
|
+
3. **环境映射**: 解决了安装路径与运行环境不一致的问题。特别是对于 **Gemini CLI** 用户,OneSkill 能自动将下载的 Skill 映射到 Gemini 的配置文件中。
|
|
104
|
+
|
|
105
|
+
### 🚀 快速开始
|
|
106
|
+
|
|
107
|
+
无需全局安装,直接使用 `npx` 运行即可:
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
# 搜索技能 (例如:想要网页浏览能力)
|
|
111
|
+
npx oneskill search "puppeteer browser"
|
|
112
|
+
|
|
113
|
+
# 搜索数据库相关技能,并按星级排序
|
|
114
|
+
npx oneskill search "database" --sort stars
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### 🛠 使用流程
|
|
118
|
+
|
|
119
|
+
为你的 Agent 添加新能力的推荐步骤:
|
|
120
|
+
|
|
121
|
+
1. **搜索 (Search)**: 查找你需要的技能。
|
|
122
|
+
```bash
|
|
123
|
+
npx oneskill search "github integration"
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
2. **安装 (Install)**: 使用 `openskills` 标准命令进行下载。
|
|
127
|
+
```bash
|
|
128
|
+
npx openskills install anthropics/skills
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
3. **映射 (Map)**: **(Gemini 用户必读)**
|
|
132
|
+
`openskills` 默认将文件下载到通用目录,Gemini CLI 无法直接读取。必须执行映射命令:
|
|
133
|
+
```bash
|
|
134
|
+
# 自动识别已安装的 Skill 并配置到 Gemini
|
|
135
|
+
npx oneskill map --target gemini
|
|
136
|
+
```
|
|
137
|
+
*如果你的 Skill 是全局安装的 (加了 --global),这里也需要加 --global。*
|
|
138
|
+
|
|
139
|
+
### 📖 命令参考
|
|
140
|
+
|
|
141
|
+
#### `search` (搜索)
|
|
142
|
+
在全局注册表中搜索技能。
|
|
143
|
+
```bash
|
|
144
|
+
npx oneskill search <查询词> [选项]
|
|
145
|
+
|
|
146
|
+
# 选项:
|
|
147
|
+
# --category <name> 按分类筛选
|
|
148
|
+
# --sort <field> 排序方式: 'stars' (星级), 'created' (创建时间), 'updated' (更新时间)
|
|
149
|
+
# --limit <number> 限制返回数量 (默认: 10)
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
#### `map` (映射)
|
|
153
|
+
为特定环境生成配置。
|
|
154
|
+
```bash
|
|
155
|
+
npx oneskill map --target <环境>
|
|
156
|
+
|
|
157
|
+
# 支持的目标:
|
|
158
|
+
# gemini 更新 Gemini CLI 的配置与路径映射
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
#### `list` (列表)
|
|
162
|
+
查看本地已安装的技能。
|
|
163
|
+
```bash
|
|
164
|
+
npx oneskill list
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
---
|
|
168
|
+
|
|
169
|
+
<div align="center">
|
|
170
|
+
<sub>Built with ❤️ by the OneSkill Community</sub>
|
|
171
|
+
</div>
|
package/SKILL.md
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: oneskill
|
|
3
|
+
description: Discover skills, iterate on queries, and automate skill installations for any environment.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# OneSkill Meta-Manager
|
|
7
|
+
|
|
8
|
+
Use this skill to discover new capabilities, refine search queries, and streamline skill setup using OpenSkills. This provides a unified way to expand your environment's features.
|
|
9
|
+
|
|
10
|
+
## When to Use
|
|
11
|
+
|
|
12
|
+
- When a user asks for capabilities you do not currently have.
|
|
13
|
+
- When a task is complex, domain-specific, or repeatedly blocked after 2 attempts.
|
|
14
|
+
- When a better skill likely exists (e.g., web browsing, GitHub integration, database management, cloud infrastructure).
|
|
15
|
+
|
|
16
|
+
## Workflow
|
|
17
|
+
|
|
18
|
+
1. Search the registry:
|
|
19
|
+
- Run: `npx oneskill search "<query>" [options]`
|
|
20
|
+
- Supported options: `--category`, `--limit`, `--offset`, `--sort`.
|
|
21
|
+
- Examples:
|
|
22
|
+
- `npx oneskill search "browser" --sort stars`
|
|
23
|
+
- `npx oneskill search "" --category database --limit 5`
|
|
24
|
+
2. Analyze results:
|
|
25
|
+
- Identify the best match or refine the query and search again.
|
|
26
|
+
3. Confirm with the user:
|
|
27
|
+
- Explain what the skill does and where it comes from.
|
|
28
|
+
4. Install after explicit approval (use openskills):
|
|
29
|
+
- Run: `npx openskills install <slug-or-repo>`
|
|
30
|
+
- Example: `npx openskills install anthropics/skills`
|
|
31
|
+
5. Handle environment-specific setup:
|
|
32
|
+
- **Gemini CLI Users:** `openskills` does not automatically configure Gemini. You MUST run the mapping command after installation:
|
|
33
|
+
- `npx oneskill map --target gemini` (add `--global` if installed globally)
|
|
34
|
+
6. Apply the new skill to finish the original request.
|
|
35
|
+
|
|
36
|
+
## OpenSkills Basics
|
|
37
|
+
|
|
38
|
+
- `npx openskills install <source> [options]` # Install from GitHub, local path, or private repo
|
|
39
|
+
- `npx openskills sync [-y] [-o <path>]` # Update AGENTS.md (or custom output)
|
|
40
|
+
- `npx openskills list` # Show installed skills
|
|
41
|
+
- `npx openskills read <name>` # Load skill (for agents)
|
|
42
|
+
- `npx openskills update [name...]` # Update installed skills (default: all)
|
|
43
|
+
- `npx openskills manage` # Remove skills (interactive)
|
|
44
|
+
- `npx openskills remove <name>` # Remove specific skill
|
|
45
|
+
|
|
46
|
+
Examples:
|
|
47
|
+
- `npx openskills install anthropics/skills`
|
|
48
|
+
- `npx openskills sync`
|
|
49
|
+
|
|
50
|
+
Defaults: Installs are project-local (`./.claude/skills`, or `./.agent/skills` with `--universal`). Use `--global` for `~/.claude/skills`.
|
|
51
|
+
|
|
52
|
+
## Safety Reminders
|
|
53
|
+
|
|
54
|
+
- Do not install without explicit user confirmation.
|
|
55
|
+
- Avoid `--force-map` unless the user agrees to overwrite an existing target.
|
|
56
|
+
- Use openskills for installation/updates; OneSkill only searches and maps for Gemini.
|
|
57
|
+
- For Gemini, run `npx oneskill map --target gemini` after installs.
|
|
58
|
+
- Default install/map is project-local, same as openskills; use `--global` for global installs.
|
|
59
|
+
- When installing OneSkill itself, recommend `--global` so it is available across projects.
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,411 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// src/cli.ts
|
|
4
|
+
import { Command } from "commander";
|
|
5
|
+
|
|
6
|
+
// src/core/registry.ts
|
|
7
|
+
var DEFAULT_REGISTRY_URL = "https://skillsdirectory.com/api/registry";
|
|
8
|
+
function getRegistryBase(override) {
|
|
9
|
+
return (override || process.env.ONESKILL_REGISTRY_URL || DEFAULT_REGISTRY_URL).replace(/\/$/, "");
|
|
10
|
+
}
|
|
11
|
+
async function fetchJson(url) {
|
|
12
|
+
const res = await fetch(url, { headers: { "accept": "application/json" } });
|
|
13
|
+
if (!res.ok) {
|
|
14
|
+
const text = await res.text();
|
|
15
|
+
throw new Error(`Registry request failed (${res.status}): ${text.slice(0, 200)}`);
|
|
16
|
+
}
|
|
17
|
+
return res.json();
|
|
18
|
+
}
|
|
19
|
+
function normalizeSkill(item) {
|
|
20
|
+
const slug = String(item.slug || item.id || item.name || "");
|
|
21
|
+
const name = String(item.name || item.title || slug || "");
|
|
22
|
+
const description = String(item.description || item.summary || "");
|
|
23
|
+
const repository = String(item.repository || item.repo || item.url || "");
|
|
24
|
+
const verified = typeof item.verified === "boolean" ? item.verified : void 0;
|
|
25
|
+
const stars = typeof item.stars === "number" ? item.stars : typeof item.github?.stars === "number" ? item.github.stars : void 0;
|
|
26
|
+
const tags = Array.isArray(item.tags) ? item.tags.map(String) : void 0;
|
|
27
|
+
const authorObj = item.author;
|
|
28
|
+
const authorName = typeof item.author === "string" ? String(item.author) : authorObj?.name ? String(authorObj.name) : void 0;
|
|
29
|
+
const author = authorName ? { name: authorName, url: authorObj?.url ? String(authorObj.url) : void 0 } : void 0;
|
|
30
|
+
const signals = {
|
|
31
|
+
lastUpdated: item.lastUpdated ? String(item.lastUpdated) : void 0,
|
|
32
|
+
license: item.license ? String(item.license) : typeof item.github?.license === "string" ? String(item.github.license) : void 0,
|
|
33
|
+
riskHints: Array.isArray(item.riskHints) ? item.riskHints.map(String) : void 0
|
|
34
|
+
};
|
|
35
|
+
return {
|
|
36
|
+
schemaVersion: "1",
|
|
37
|
+
slug,
|
|
38
|
+
name,
|
|
39
|
+
description,
|
|
40
|
+
repository,
|
|
41
|
+
verified,
|
|
42
|
+
stars,
|
|
43
|
+
tags,
|
|
44
|
+
author,
|
|
45
|
+
signals
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
function normalizeSearchPayload(payload) {
|
|
49
|
+
if (!payload || typeof payload !== "object") return [];
|
|
50
|
+
const data = payload;
|
|
51
|
+
const candidates = (Array.isArray(data.skills) ? data.skills : null) || (Array.isArray(data.items) ? data.items : null) || (Array.isArray(data.results) ? data.results : null) || (Array.isArray(data.data) ? data.data : null) || (Array.isArray(payload) ? payload : null);
|
|
52
|
+
if (!candidates) return [];
|
|
53
|
+
return candidates.filter((item) => item && typeof item === "object").map((item) => normalizeSkill(item));
|
|
54
|
+
}
|
|
55
|
+
async function searchRegistry(params, overrideUrl) {
|
|
56
|
+
const base = getRegistryBase(overrideUrl);
|
|
57
|
+
const url = new URL(base);
|
|
58
|
+
if (params.q) url.searchParams.set("q", params.q);
|
|
59
|
+
if (params.category) url.searchParams.set("category", params.category);
|
|
60
|
+
if (typeof params.limit === "number") url.searchParams.set("limit", String(params.limit));
|
|
61
|
+
if (typeof params.offset === "number") url.searchParams.set("offset", String(params.offset));
|
|
62
|
+
if (params.sort) url.searchParams.set("sort", params.sort);
|
|
63
|
+
const raw = await fetchJson(url.toString());
|
|
64
|
+
const items = normalizeSearchPayload(raw);
|
|
65
|
+
return { items, raw };
|
|
66
|
+
}
|
|
67
|
+
async function fetchRegistryInfo(slug, overrideUrl) {
|
|
68
|
+
const base = getRegistryBase(overrideUrl);
|
|
69
|
+
const url = `${base}/${encodeURIComponent(slug)}`;
|
|
70
|
+
const raw = await fetchJson(url);
|
|
71
|
+
if (raw && typeof raw === "object") {
|
|
72
|
+
const record = raw;
|
|
73
|
+
const candidate = record.skill || record.item || record;
|
|
74
|
+
if (candidate && typeof candidate === "object") {
|
|
75
|
+
return { item: normalizeSkill(candidate), raw };
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
throw new Error("Registry info failed");
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// src/utils/json.ts
|
|
82
|
+
function printJson(data) {
|
|
83
|
+
process.stdout.write(JSON.stringify(data, null, 2) + "\n");
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// src/commands/search.ts
|
|
87
|
+
async function runSearch(query, options) {
|
|
88
|
+
const result = await searchRegistry(
|
|
89
|
+
{
|
|
90
|
+
q: query,
|
|
91
|
+
category: options.category,
|
|
92
|
+
limit: options.limit,
|
|
93
|
+
offset: options.offset,
|
|
94
|
+
sort: options.sort
|
|
95
|
+
},
|
|
96
|
+
options.registry
|
|
97
|
+
);
|
|
98
|
+
const raw = result.raw;
|
|
99
|
+
printJson({
|
|
100
|
+
schemaVersion: "1",
|
|
101
|
+
query,
|
|
102
|
+
registry: raw?.registry,
|
|
103
|
+
version: raw?.version,
|
|
104
|
+
pagination: raw?.pagination,
|
|
105
|
+
items: result.items
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// src/commands/info.ts
|
|
110
|
+
async function runInfo(slug, options) {
|
|
111
|
+
const result = await fetchRegistryInfo(slug, options.registry);
|
|
112
|
+
printJson({ schemaVersion: "1", item: result.item });
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// src/commands/list.ts
|
|
116
|
+
import { spawnSync as spawnSync2 } from "child_process";
|
|
117
|
+
|
|
118
|
+
// src/core/openskills.ts
|
|
119
|
+
import { readFileSync, existsSync } from "fs";
|
|
120
|
+
import { dirname, resolve } from "path";
|
|
121
|
+
import { createRequire } from "module";
|
|
122
|
+
import { spawnSync } from "child_process";
|
|
123
|
+
var require2 = createRequire(import.meta.url);
|
|
124
|
+
function resolveOpenskillsCli() {
|
|
125
|
+
const pkgPath = require2.resolve("openskills/package.json");
|
|
126
|
+
const pkgDir = dirname(pkgPath);
|
|
127
|
+
const content = readFileSync(pkgPath, "utf-8");
|
|
128
|
+
const parsed = JSON.parse(content);
|
|
129
|
+
const bin = parsed.bin;
|
|
130
|
+
let candidate = null;
|
|
131
|
+
if (typeof bin === "string") {
|
|
132
|
+
candidate = resolve(pkgDir, bin);
|
|
133
|
+
} else if (bin && typeof bin === "object") {
|
|
134
|
+
const first = Object.values(bin)[0];
|
|
135
|
+
if (first) candidate = resolve(pkgDir, first);
|
|
136
|
+
} else if (parsed.main) {
|
|
137
|
+
candidate = resolve(pkgDir, parsed.main);
|
|
138
|
+
}
|
|
139
|
+
if (candidate && existsSync(candidate)) {
|
|
140
|
+
return candidate;
|
|
141
|
+
}
|
|
142
|
+
const result = spawnSync("npm", ["run", "build"], {
|
|
143
|
+
cwd: pkgDir,
|
|
144
|
+
stdio: "inherit"
|
|
145
|
+
});
|
|
146
|
+
if (result.status !== 0) {
|
|
147
|
+
throw new Error("Failed to build openskills");
|
|
148
|
+
}
|
|
149
|
+
if (candidate && existsSync(candidate)) {
|
|
150
|
+
return candidate;
|
|
151
|
+
}
|
|
152
|
+
throw new Error("Unable to resolve openskills CLI entry");
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// src/commands/list.ts
|
|
156
|
+
async function runList(_options) {
|
|
157
|
+
const cliPath = resolveOpenskillsCli();
|
|
158
|
+
const args = [cliPath, "list"];
|
|
159
|
+
const result = spawnSync2(process.execPath, args, {
|
|
160
|
+
cwd: process.cwd(),
|
|
161
|
+
stdio: "inherit"
|
|
162
|
+
});
|
|
163
|
+
if (result.status !== 0) {
|
|
164
|
+
throw new Error("openskills list failed");
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// src/core/root.ts
|
|
169
|
+
import { existsSync as existsSync2, readFileSync as readFileSync2 } from "fs";
|
|
170
|
+
import { dirname as dirname2, join, resolve as resolve2 } from "path";
|
|
171
|
+
var MARKER_DIRS = [".git", ".agent", ".claude", ".gemini", ".codex"];
|
|
172
|
+
function hasOneskillConfig(pkgPath) {
|
|
173
|
+
try {
|
|
174
|
+
const content = readFileSync2(pkgPath, "utf-8");
|
|
175
|
+
const parsed = JSON.parse(content);
|
|
176
|
+
return Boolean(parsed.oneskill);
|
|
177
|
+
} catch {
|
|
178
|
+
return false;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
function hasMarkers(dir) {
|
|
182
|
+
for (const marker of MARKER_DIRS) {
|
|
183
|
+
if (existsSync2(join(dir, marker))) return marker;
|
|
184
|
+
}
|
|
185
|
+
if (existsSync2(join(dir, "AGENTS.md"))) return "AGENTS.md";
|
|
186
|
+
const pkgPath = join(dir, "package.json");
|
|
187
|
+
if (existsSync2(pkgPath) && hasOneskillConfig(pkgPath)) return "package.json:oneskill";
|
|
188
|
+
return null;
|
|
189
|
+
}
|
|
190
|
+
function detectRoot(startDir) {
|
|
191
|
+
let current = resolve2(startDir);
|
|
192
|
+
while (true) {
|
|
193
|
+
const reason = hasMarkers(current);
|
|
194
|
+
if (reason) return { root: current, reason };
|
|
195
|
+
const parent = dirname2(current);
|
|
196
|
+
if (parent === current) {
|
|
197
|
+
return { root: resolve2(startDir), reason: "fallback:cwd" };
|
|
198
|
+
}
|
|
199
|
+
current = parent;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// src/commands/doctor.ts
|
|
204
|
+
async function runDoctor(options) {
|
|
205
|
+
const rootInfo = detectRoot(options.root || process.cwd());
|
|
206
|
+
const root = rootInfo.root;
|
|
207
|
+
const paths = {
|
|
208
|
+
agent: `${root}/.agent/skills`,
|
|
209
|
+
claude: `${root}/.claude/skills`,
|
|
210
|
+
gemini: `${root}/.gemini/skills`,
|
|
211
|
+
codex: `${root}/.codex/skills`,
|
|
212
|
+
oneskillLogs: `${root}/.oneskill/logs`
|
|
213
|
+
};
|
|
214
|
+
printJson({ schemaVersion: "1", root: rootInfo.root, reason: rootInfo.reason, paths });
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
// src/commands/sync.ts
|
|
218
|
+
import { spawnSync as spawnSync3 } from "child_process";
|
|
219
|
+
async function runSync(options) {
|
|
220
|
+
const cliPath = resolveOpenskillsCli();
|
|
221
|
+
const args = [cliPath, "sync"];
|
|
222
|
+
if (options.yes) {
|
|
223
|
+
args.push("--yes");
|
|
224
|
+
}
|
|
225
|
+
if (options.output) {
|
|
226
|
+
args.push("--output", options.output);
|
|
227
|
+
}
|
|
228
|
+
const result = spawnSync3(process.execPath, args, {
|
|
229
|
+
cwd: process.cwd(),
|
|
230
|
+
stdio: "inherit"
|
|
231
|
+
});
|
|
232
|
+
if (result.status !== 0) {
|
|
233
|
+
throw new Error("openskills sync failed");
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
// src/core/map.ts
|
|
238
|
+
import { existsSync as existsSync5, readdirSync } from "fs";
|
|
239
|
+
import { basename, join as join3 } from "path";
|
|
240
|
+
import { homedir } from "os";
|
|
241
|
+
|
|
242
|
+
// src/core/mapping.ts
|
|
243
|
+
import { existsSync as existsSync4, lstatSync, readlinkSync, rmSync, symlinkSync, cpSync, writeFileSync as writeFileSync2 } from "fs";
|
|
244
|
+
import { join as join2, resolve as resolve4 } from "path";
|
|
245
|
+
|
|
246
|
+
// src/core/fs.ts
|
|
247
|
+
import { mkdirSync, readFileSync as readFileSync3, writeFileSync, existsSync as existsSync3 } from "fs";
|
|
248
|
+
import { dirname as dirname3, resolve as resolve3, sep } from "path";
|
|
249
|
+
function ensureDir(path) {
|
|
250
|
+
mkdirSync(path, { recursive: true });
|
|
251
|
+
}
|
|
252
|
+
function isPathInside(targetPath, baseDir) {
|
|
253
|
+
const resolvedTarget = resolve3(targetPath);
|
|
254
|
+
const resolvedBase = resolve3(baseDir);
|
|
255
|
+
const baseWithSep = resolvedBase.endsWith(sep) ? resolvedBase : resolvedBase + sep;
|
|
256
|
+
return resolvedTarget === resolvedBase || resolvedTarget.startsWith(baseWithSep);
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
// src/core/mapping.ts
|
|
260
|
+
var TARGET_DIRS = {
|
|
261
|
+
codex: ".codex/skills",
|
|
262
|
+
gemini: ".gemini/skills",
|
|
263
|
+
claude: ".claude/skills",
|
|
264
|
+
agent: ".agent/skills"
|
|
265
|
+
};
|
|
266
|
+
function getTargetBase(root, target, options) {
|
|
267
|
+
if (target === "codex" && options?.codexHome) {
|
|
268
|
+
return resolve4(options.codexHome, "skills");
|
|
269
|
+
}
|
|
270
|
+
return join2(root, TARGET_DIRS[target]);
|
|
271
|
+
}
|
|
272
|
+
function readLinkTarget(path) {
|
|
273
|
+
try {
|
|
274
|
+
return readlinkSync(path);
|
|
275
|
+
} catch {
|
|
276
|
+
return null;
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
function mapSkill(root, target, skillName, storePath, options) {
|
|
280
|
+
const baseDir = getTargetBase(root, target, options);
|
|
281
|
+
const targetPath = join2(baseDir, skillName);
|
|
282
|
+
if (target !== "codex" && !isPathInside(targetPath, root)) {
|
|
283
|
+
throw new Error(`Target path escapes root: ${targetPath}`);
|
|
284
|
+
}
|
|
285
|
+
ensureDir(baseDir);
|
|
286
|
+
if (existsSync4(targetPath)) {
|
|
287
|
+
const stat = lstatSync(targetPath);
|
|
288
|
+
if (stat.isSymbolicLink()) {
|
|
289
|
+
const linkTarget = readLinkTarget(targetPath);
|
|
290
|
+
if (linkTarget && resolve4(linkTarget) === resolve4(storePath)) {
|
|
291
|
+
return { target, path: targetPath, mode: process.platform === "win32" ? "junction" : "symlink", updatedAt: (/* @__PURE__ */ new Date()).toISOString() };
|
|
292
|
+
}
|
|
293
|
+
if (!options?.forceMap) {
|
|
294
|
+
throw new Error(`Target already exists (symlink): ${targetPath}`);
|
|
295
|
+
}
|
|
296
|
+
} else {
|
|
297
|
+
if (!options?.forceMap) {
|
|
298
|
+
throw new Error(`Target already exists: ${targetPath}`);
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
rmSync(targetPath, { recursive: true, force: true });
|
|
302
|
+
}
|
|
303
|
+
const linkType = process.platform === "win32" ? "junction" : "dir";
|
|
304
|
+
try {
|
|
305
|
+
symlinkSync(storePath, targetPath, linkType);
|
|
306
|
+
return { target, path: targetPath, mode: process.platform === "win32" ? "junction" : "symlink", updatedAt: (/* @__PURE__ */ new Date()).toISOString() };
|
|
307
|
+
} catch (error) {
|
|
308
|
+
if (!options?.forceMap) {
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
cpSync(storePath, targetPath, { recursive: true, dereference: false });
|
|
312
|
+
writeFileSync2(
|
|
313
|
+
join2(targetPath, ".oneskill-meta.json"),
|
|
314
|
+
JSON.stringify({ source: storePath, mappedAt: (/* @__PURE__ */ new Date()).toISOString(), mode: "copy" }, null, 2) + "\n",
|
|
315
|
+
"utf-8"
|
|
316
|
+
);
|
|
317
|
+
return { target, path: targetPath, mode: "copy", updatedAt: (/* @__PURE__ */ new Date()).toISOString() };
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
// src/core/map.ts
|
|
321
|
+
function getSourceBase(root, options) {
|
|
322
|
+
const baseRoot = options.global ? homedir() : root;
|
|
323
|
+
const folder = options.universal ? ".agent/skills" : ".claude/skills";
|
|
324
|
+
return join3(baseRoot, folder);
|
|
325
|
+
}
|
|
326
|
+
function getTargetRoot(root, options) {
|
|
327
|
+
return options.global ? homedir() : root;
|
|
328
|
+
}
|
|
329
|
+
function mapInstalledSkills(options) {
|
|
330
|
+
if (options.target !== "gemini") {
|
|
331
|
+
throw new Error("map currently supports only --target gemini");
|
|
332
|
+
}
|
|
333
|
+
const rootInfo = detectRoot(process.cwd());
|
|
334
|
+
const sourceBase = getSourceBase(rootInfo.root, options);
|
|
335
|
+
const targetRoot = getTargetRoot(rootInfo.root, options);
|
|
336
|
+
if (!existsSync5(sourceBase)) {
|
|
337
|
+
return { mapped: 0, sourceBase, targetRoot };
|
|
338
|
+
}
|
|
339
|
+
const entries = readdirSync(sourceBase, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => join3(sourceBase, entry.name));
|
|
340
|
+
let mapped = 0;
|
|
341
|
+
for (const dir of entries) {
|
|
342
|
+
const name = basename(dir);
|
|
343
|
+
mapSkill(targetRoot, "gemini", name, dir, { forceMap: options.forceMap });
|
|
344
|
+
mapped += 1;
|
|
345
|
+
}
|
|
346
|
+
return { mapped, sourceBase, targetRoot };
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
// src/commands/map.ts
|
|
350
|
+
async function runMap(options) {
|
|
351
|
+
if (!options.target) {
|
|
352
|
+
throw new Error("map requires --target gemini");
|
|
353
|
+
}
|
|
354
|
+
const result = mapInstalledSkills({
|
|
355
|
+
target: options.target,
|
|
356
|
+
global: options.global,
|
|
357
|
+
universal: options.universal,
|
|
358
|
+
forceMap: options.forceMap
|
|
359
|
+
});
|
|
360
|
+
printJson({ schemaVersion: "1", ...result });
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
// src/core/versions.ts
|
|
364
|
+
import { readFileSync as readFileSync4 } from "fs";
|
|
365
|
+
import { dirname as dirname4, join as join4 } from "path";
|
|
366
|
+
import { fileURLToPath } from "url";
|
|
367
|
+
import { createRequire as createRequire2 } from "module";
|
|
368
|
+
var require3 = createRequire2(import.meta.url);
|
|
369
|
+
function getOneskillVersion() {
|
|
370
|
+
const __dirname = dirname4(fileURLToPath(import.meta.url));
|
|
371
|
+
const pkgPath = join4(__dirname, "../../package.json");
|
|
372
|
+
try {
|
|
373
|
+
const content = readFileSync4(pkgPath, "utf-8");
|
|
374
|
+
const parsed = JSON.parse(content);
|
|
375
|
+
return parsed.version || "0.0.0";
|
|
376
|
+
} catch {
|
|
377
|
+
return "0.0.0";
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
// src/cli.ts
|
|
382
|
+
var program = new Command();
|
|
383
|
+
program.name("oneskill").description("Meta-skill manager for AI coding agents").version(getOneskillVersion());
|
|
384
|
+
program.command("search <query>").description("Search the skill registry").option("--registry <url>", "Registry base URL override").option("--category <slug>", "Filter by category slug").option("--limit <n>", "Results per page (max 100)", (value) => Number.parseInt(value, 10)).option("--offset <n>", "Pagination offset", (value) => Number.parseInt(value, 10)).option("--sort <value>", "Sort by: votes, recent, stars").action(async (query, options) => {
|
|
385
|
+
await runSearch(query, options);
|
|
386
|
+
});
|
|
387
|
+
program.command("info <slug>").description("Fetch skill info from registry").option("--registry <url>", "Registry base URL override").action(async (slug, options) => {
|
|
388
|
+
await runInfo(slug, options);
|
|
389
|
+
});
|
|
390
|
+
program.command("sync").description("Forward to openskills sync").option("-y, --yes", "Skip interactive selection, sync all skills").option("-o, --output <path>", "Output file path (default: AGENTS.md)").action(async (options) => {
|
|
391
|
+
await runSync(options);
|
|
392
|
+
});
|
|
393
|
+
program.command("map").description("Map installed skills into Gemini directory").option("--target <target>", "Target environment (gemini only)").option("--global", "Map from global openskills install", false).option("--universal", "Map from universal (.agent/skills)", false).option("--force-map", "Overwrite target mapping if it exists", false).action(async (options) => {
|
|
394
|
+
await runMap({
|
|
395
|
+
target: options.target,
|
|
396
|
+
global: options.global,
|
|
397
|
+
universal: options.universal,
|
|
398
|
+
forceMap: options.forceMap
|
|
399
|
+
});
|
|
400
|
+
});
|
|
401
|
+
program.command("list").description("List managed skills").option("--root <path>", "Override workspace root").action(async (options) => {
|
|
402
|
+
await runList(options);
|
|
403
|
+
});
|
|
404
|
+
program.command("doctor").description("Diagnose OneSkill environment").option("--root <path>", "Override workspace root").action(async (options) => {
|
|
405
|
+
await runDoctor(options);
|
|
406
|
+
});
|
|
407
|
+
program.parseAsync(process.argv).catch((error) => {
|
|
408
|
+
console.error(error instanceof Error ? error.message : String(error));
|
|
409
|
+
process.exitCode = 1;
|
|
410
|
+
});
|
|
411
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/cli.ts","../src/core/registry.ts","../src/utils/json.ts","../src/commands/search.ts","../src/commands/info.ts","../src/commands/list.ts","../src/core/openskills.ts","../src/core/root.ts","../src/commands/doctor.ts","../src/commands/sync.ts","../src/core/map.ts","../src/core/mapping.ts","../src/core/fs.ts","../src/commands/map.ts","../src/core/versions.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { Command } from 'commander';\nimport { runSearch } from './commands/search.js';\nimport { runInfo } from './commands/info.js';\nimport { runList } from './commands/list.js';\nimport { runDoctor } from './commands/doctor.js';\nimport { runSync } from './commands/sync.js';\nimport { runMap } from './commands/map.js';\nimport { getOneskillVersion } from './core/versions.js';\n\nconst program = new Command();\n\nprogram\n .name('oneskill')\n .description('Meta-skill manager for AI coding agents')\n .version(getOneskillVersion());\n\nprogram\n .command('search <query>')\n .description('Search the skill registry')\n .option('--registry <url>', 'Registry base URL override')\n .option('--category <slug>', 'Filter by category slug')\n .option('--limit <n>', 'Results per page (max 100)', (value) => Number.parseInt(value, 10))\n .option('--offset <n>', 'Pagination offset', (value) => Number.parseInt(value, 10))\n .option('--sort <value>', 'Sort by: votes, recent, stars')\n .action(async (query: string, options: { registry?: string; category?: string; limit?: number; offset?: number; sort?: string }) => {\n await runSearch(query, options);\n });\n\nprogram\n .command('info <slug>')\n .description('Fetch skill info from registry')\n .option('--registry <url>', 'Registry base URL override')\n .action(async (slug: string, options: { registry?: string }) => {\n await runInfo(slug, options);\n });\n\nprogram\n .command('sync')\n .description('Forward to openskills sync')\n .option('-y, --yes', 'Skip interactive selection, sync all skills')\n .option('-o, --output <path>', 'Output file path (default: AGENTS.md)')\n .action(async (options: { yes?: boolean; output?: string }) => {\n await runSync(options);\n });\n\nprogram\n .command('map')\n .description('Map installed skills into Gemini directory')\n .option('--target <target>', 'Target environment (gemini only)')\n .option('--global', 'Map from global openskills install', false)\n .option('--universal', 'Map from universal (.agent/skills)', false)\n .option('--force-map', 'Overwrite target mapping if it exists', false)\n .action(async (options: { target?: string; global?: boolean; universal?: boolean; forceMap?: boolean }) => {\n await runMap({\n target: options.target as 'gemini' | undefined,\n global: options.global,\n universal: options.universal,\n forceMap: options.forceMap,\n });\n });\n\nprogram\n .command('list')\n .description('List managed skills')\n .option('--root <path>', 'Override workspace root')\n .action(async (options: { root?: string }) => {\n await runList(options);\n });\n\nprogram\n .command('doctor')\n .description('Diagnose OneSkill environment')\n .option('--root <path>', 'Override workspace root')\n .action(async (options: { root?: string }) => {\n await runDoctor(options);\n });\n\nprogram.parseAsync(process.argv).catch((error) => {\n console.error(error instanceof Error ? error.message : String(error));\n process.exitCode = 1;\n});\n","import type { RegistryInfoResponse, RegistrySearchResponse, SkillListItem } from './types.js';\n\nconst DEFAULT_REGISTRY_URL = 'https://skillsdirectory.com/api/registry';\n\nexport interface SearchParams {\n q?: string;\n category?: string;\n limit?: number;\n offset?: number;\n sort?: string;\n}\n\nfunction getRegistryBase(override?: string): string {\n return (override || process.env.ONESKILL_REGISTRY_URL || DEFAULT_REGISTRY_URL).replace(/\\/$/, '');\n}\n\nasync function fetchJson(url: string): Promise<unknown> {\n const res = await fetch(url, { headers: { 'accept': 'application/json' } });\n if (!res.ok) {\n const text = await res.text();\n throw new Error(`Registry request failed (${res.status}): ${text.slice(0, 200)}`);\n }\n return res.json();\n}\n\nfunction normalizeSkill(item: Record<string, unknown>): SkillListItem {\n const slug = String(item.slug || item.id || item.name || '');\n const name = String(item.name || item.title || slug || '');\n const description = String(item.description || item.summary || '');\n const repository = String(item.repository || item.repo || item.url || '');\n const verified = typeof item.verified === 'boolean' ? item.verified : undefined;\n const stars =\n typeof item.stars === 'number'\n ? item.stars\n : typeof (item.github as { stars?: unknown } | undefined)?.stars === 'number'\n ? (item.github as { stars: number }).stars\n : undefined;\n const tags = Array.isArray(item.tags) ? item.tags.map(String) : undefined;\n const authorObj = item.author as { name?: unknown; url?: unknown } | undefined;\n const authorName = typeof item.author === 'string' ? String(item.author) : authorObj?.name ? String(authorObj.name) : undefined;\n const author = authorName\n ? { name: authorName, url: authorObj?.url ? String(authorObj.url) : undefined }\n : undefined;\n\n const signals = {\n lastUpdated: item.lastUpdated ? String(item.lastUpdated) : undefined,\n license:\n item.license ? String(item.license)\n : typeof (item.github as { license?: unknown } | undefined)?.license === 'string'\n ? String((item.github as { license: string }).license)\n : undefined,\n riskHints: Array.isArray(item.riskHints) ? item.riskHints.map(String) : undefined,\n };\n\n return {\n schemaVersion: '1',\n slug,\n name,\n description,\n repository,\n verified,\n stars,\n tags,\n author,\n signals,\n };\n}\n\nfunction normalizeSearchPayload(payload: unknown): SkillListItem[] {\n if (!payload || typeof payload !== 'object') return [];\n const data = payload as Record<string, unknown>;\n const candidates =\n (Array.isArray(data.skills) ? data.skills : null) ||\n (Array.isArray(data.items) ? data.items : null) ||\n (Array.isArray(data.results) ? data.results : null) ||\n (Array.isArray(data.data) ? data.data : null) ||\n (Array.isArray(payload) ? (payload as unknown[]) : null);\n\n if (!candidates) return [];\n return candidates\n .filter((item) => item && typeof item === 'object')\n .map((item) => normalizeSkill(item as Record<string, unknown>));\n}\n\nexport async function searchRegistry(params: SearchParams, overrideUrl?: string): Promise<RegistrySearchResponse> {\n const base = getRegistryBase(overrideUrl);\n const url = new URL(base);\n if (params.q) url.searchParams.set('q', params.q);\n if (params.category) url.searchParams.set('category', params.category);\n if (typeof params.limit === 'number') url.searchParams.set('limit', String(params.limit));\n if (typeof params.offset === 'number') url.searchParams.set('offset', String(params.offset));\n if (params.sort) url.searchParams.set('sort', params.sort);\n const raw = await fetchJson(url.toString());\n const items = normalizeSearchPayload(raw);\n return { items, raw };\n}\n\nexport async function fetchRegistryInfo(slug: string, overrideUrl?: string): Promise<RegistryInfoResponse> {\n const base = getRegistryBase(overrideUrl);\n const url = `${base}/${encodeURIComponent(slug)}`;\n const raw = await fetchJson(url);\n if (raw && typeof raw === 'object') {\n const record = raw as Record<string, unknown>;\n const candidate = (record.skill as Record<string, unknown> | undefined) || (record.item as Record<string, unknown> | undefined) || record;\n if (candidate && typeof candidate === 'object') {\n return { item: normalizeSkill(candidate as Record<string, unknown>), raw };\n }\n }\n throw new Error('Registry info failed');\n}\n","export function printJson(data: unknown): void {\n process.stdout.write(JSON.stringify(data, null, 2) + '\\n');\n}\n","import { searchRegistry } from '../core/registry.js';\nimport { printJson } from '../utils/json.js';\n\nexport interface SearchCommandOptions {\n registry?: string;\n category?: string;\n limit?: number;\n offset?: number;\n sort?: string;\n}\n\nexport async function runSearch(query: string, options: SearchCommandOptions): Promise<void> {\n const result = await searchRegistry(\n {\n q: query,\n category: options.category,\n limit: options.limit,\n offset: options.offset,\n sort: options.sort,\n },\n options.registry\n );\n const raw = result.raw as { registry?: unknown; version?: unknown; pagination?: unknown } | undefined;\n printJson({\n schemaVersion: '1',\n query,\n registry: raw?.registry,\n version: raw?.version,\n pagination: raw?.pagination,\n items: result.items,\n });\n}\n","import { fetchRegistryInfo } from '../core/registry.js';\nimport { printJson } from '../utils/json.js';\n\nexport interface InfoCommandOptions {\n registry?: string;\n}\n\nexport async function runInfo(slug: string, options: InfoCommandOptions): Promise<void> {\n const result = await fetchRegistryInfo(slug, options.registry);\n printJson({ schemaVersion: '1', item: result.item });\n}\n","import { spawnSync } from 'child_process';\nimport { resolveOpenskillsCli } from '../core/openskills.js';\n\nexport interface ListCommandOptions {}\n\nexport async function runList(_options: ListCommandOptions): Promise<void> {\n const cliPath = resolveOpenskillsCli();\n const args = [cliPath, 'list'];\n const result = spawnSync(process.execPath, args, {\n cwd: process.cwd(),\n stdio: 'inherit',\n });\n if (result.status !== 0) {\n throw new Error('openskills list failed');\n }\n}\n","import { readFileSync, existsSync } from 'fs';\nimport { dirname, resolve } from 'path';\nimport { createRequire } from 'module';\nimport { spawnSync } from 'child_process';\n\nconst require = createRequire(import.meta.url);\n\nexport function resolveOpenskillsCli(): string {\n const pkgPath = require.resolve('openskills/package.json');\n const pkgDir = dirname(pkgPath);\n const content = readFileSync(pkgPath, 'utf-8');\n const parsed = JSON.parse(content) as { bin?: Record<string, string> | string; main?: string };\n const bin = parsed.bin;\n let candidate: string | null = null;\n if (typeof bin === 'string') {\n candidate = resolve(pkgDir, bin);\n } else if (bin && typeof bin === 'object') {\n const first = Object.values(bin)[0];\n if (first) candidate = resolve(pkgDir, first);\n } else if (parsed.main) {\n candidate = resolve(pkgDir, parsed.main);\n }\n\n if (candidate && existsSync(candidate)) {\n return candidate;\n }\n\n // Build openskills locally if the CLI entry is missing.\n const result = spawnSync('npm', ['run', 'build'], {\n cwd: pkgDir,\n stdio: 'inherit',\n });\n if (result.status !== 0) {\n throw new Error('Failed to build openskills');\n }\n\n if (candidate && existsSync(candidate)) {\n return candidate;\n }\n\n throw new Error('Unable to resolve openskills CLI entry');\n}\n","import { existsSync, readFileSync } from 'fs';\nimport { dirname, join, resolve } from 'path';\nimport type { RootDetection } from './types.js';\n\nconst MARKER_DIRS = ['.git', '.agent', '.claude', '.gemini', '.codex'];\n\nfunction hasOneskillConfig(pkgPath: string): boolean {\n try {\n const content = readFileSync(pkgPath, 'utf-8');\n const parsed = JSON.parse(content) as { oneskill?: unknown };\n return Boolean(parsed.oneskill);\n } catch {\n return false;\n }\n}\n\nfunction hasMarkers(dir: string): string | null {\n for (const marker of MARKER_DIRS) {\n if (existsSync(join(dir, marker))) return marker;\n }\n if (existsSync(join(dir, 'AGENTS.md'))) return 'AGENTS.md';\n const pkgPath = join(dir, 'package.json');\n if (existsSync(pkgPath) && hasOneskillConfig(pkgPath)) return 'package.json:oneskill';\n return null;\n}\n\nexport function detectRoot(startDir: string): RootDetection {\n let current = resolve(startDir);\n while (true) {\n const reason = hasMarkers(current);\n if (reason) return { root: current, reason };\n const parent = dirname(current);\n if (parent === current) {\n return { root: resolve(startDir), reason: 'fallback:cwd' };\n }\n current = parent;\n }\n}\n","import { detectRoot } from '../core/root.js';\nimport { printJson } from '../utils/json.js';\n\nexport interface DoctorCommandOptions {\n root?: string;\n}\n\nexport async function runDoctor(options: DoctorCommandOptions): Promise<void> {\n const rootInfo = detectRoot(options.root || process.cwd());\n const root = rootInfo.root;\n const paths = {\n agent: `${root}/.agent/skills`,\n claude: `${root}/.claude/skills`,\n gemini: `${root}/.gemini/skills`,\n codex: `${root}/.codex/skills`,\n oneskillLogs: `${root}/.oneskill/logs`,\n };\n printJson({ schemaVersion: '1', root: rootInfo.root, reason: rootInfo.reason, paths });\n}\n","import { spawnSync } from 'child_process';\nimport { resolveOpenskillsCli } from '../core/openskills.js';\n\nexport interface SyncCommandOptions {\n yes?: boolean;\n output?: string;\n}\n\nexport async function runSync(options: SyncCommandOptions): Promise<void> {\n const cliPath = resolveOpenskillsCli();\n const args = [cliPath, 'sync'];\n if (options.yes) {\n args.push('--yes');\n }\n if (options.output) {\n args.push('--output', options.output);\n }\n const result = spawnSync(process.execPath, args, {\n cwd: process.cwd(),\n stdio: 'inherit',\n });\n if (result.status !== 0) {\n throw new Error('openskills sync failed');\n }\n}\n","import { existsSync, readdirSync } from 'fs';\nimport { basename, join } from 'path';\nimport { homedir } from 'os';\nimport { mapSkill } from './mapping.js';\nimport { detectRoot } from './root.js';\nimport type { TargetEnvironment } from './types.js';\n\nexport interface MapOptions {\n target: TargetEnvironment;\n global?: boolean;\n universal?: boolean;\n forceMap?: boolean;\n}\n\nfunction getSourceBase(root: string, options: MapOptions): string {\n const baseRoot = options.global ? homedir() : root;\n const folder = options.universal ? '.agent/skills' : '.claude/skills';\n return join(baseRoot, folder);\n}\n\nfunction getTargetRoot(root: string, options: MapOptions): string {\n return options.global ? homedir() : root;\n}\n\nexport function mapInstalledSkills(options: MapOptions): { mapped: number; sourceBase: string; targetRoot: string } {\n if (options.target !== 'gemini') {\n throw new Error('map currently supports only --target gemini');\n }\n const rootInfo = detectRoot(process.cwd());\n const sourceBase = getSourceBase(rootInfo.root, options);\n const targetRoot = getTargetRoot(rootInfo.root, options);\n\n if (!existsSync(sourceBase)) {\n return { mapped: 0, sourceBase, targetRoot };\n }\n\n const entries = readdirSync(sourceBase, { withFileTypes: true })\n .filter((entry) => entry.isDirectory())\n .map((entry) => join(sourceBase, entry.name));\n\n let mapped = 0;\n for (const dir of entries) {\n const name = basename(dir);\n mapSkill(targetRoot, 'gemini', name, dir, { forceMap: options.forceMap });\n mapped += 1;\n }\n\n return { mapped, sourceBase, targetRoot };\n}\n","import { existsSync, lstatSync, readlinkSync, rmSync, symlinkSync, cpSync, writeFileSync } from 'fs';\nimport { join, resolve } from 'path';\nimport { ensureDir, isPathInside } from './fs.js';\nimport type { SkillMappingRecord, TargetEnvironment } from './types.js';\n\nconst TARGET_DIRS: Record<TargetEnvironment, string> = {\n codex: '.codex/skills',\n gemini: '.gemini/skills',\n claude: '.claude/skills',\n agent: '.agent/skills',\n};\n\nexport interface MapOptions {\n forceMap?: boolean;\n codexHome?: string;\n}\n\nfunction getTargetBase(root: string, target: TargetEnvironment, options?: MapOptions): string {\n if (target === 'codex' && options?.codexHome) {\n return resolve(options.codexHome, 'skills');\n }\n return join(root, TARGET_DIRS[target]);\n}\n\nfunction readLinkTarget(path: string): string | null {\n try {\n return readlinkSync(path);\n } catch {\n return null;\n }\n}\n\nexport function mapSkill(\n root: string,\n target: TargetEnvironment,\n skillName: string,\n storePath: string,\n options?: MapOptions\n): SkillMappingRecord {\n const baseDir = getTargetBase(root, target, options);\n const targetPath = join(baseDir, skillName);\n\n if (target !== 'codex' && !isPathInside(targetPath, root)) {\n throw new Error(`Target path escapes root: ${targetPath}`);\n }\n\n ensureDir(baseDir);\n\n if (existsSync(targetPath)) {\n const stat = lstatSync(targetPath);\n if (stat.isSymbolicLink()) {\n const linkTarget = readLinkTarget(targetPath);\n if (linkTarget && resolve(linkTarget) === resolve(storePath)) {\n return { target, path: targetPath, mode: process.platform === 'win32' ? 'junction' : 'symlink', updatedAt: new Date().toISOString() };\n }\n if (!options?.forceMap) {\n throw new Error(`Target already exists (symlink): ${targetPath}`);\n }\n } else {\n if (!options?.forceMap) {\n throw new Error(`Target already exists: ${targetPath}`);\n }\n }\n rmSync(targetPath, { recursive: true, force: true });\n }\n\n const linkType = process.platform === 'win32' ? 'junction' : 'dir';\n try {\n symlinkSync(storePath, targetPath, linkType);\n return { target, path: targetPath, mode: process.platform === 'win32' ? 'junction' : 'symlink', updatedAt: new Date().toISOString() };\n } catch (error) {\n if (!options?.forceMap) {\n // Fall through to copy on Windows permission errors or other failures.\n }\n }\n\n cpSync(storePath, targetPath, { recursive: true, dereference: false });\n writeFileSync(\n join(targetPath, '.oneskill-meta.json'),\n JSON.stringify({ source: storePath, mappedAt: new Date().toISOString(), mode: 'copy' }, null, 2) + '\\n',\n 'utf-8'\n );\n\n return { target, path: targetPath, mode: 'copy', updatedAt: new Date().toISOString() };\n}\n","import { mkdirSync, readFileSync, writeFileSync, existsSync } from 'fs';\nimport { dirname, resolve, sep } from 'path';\n\nexport function ensureDir(path: string): void {\n mkdirSync(path, { recursive: true });\n}\n\nexport function readJsonFile<T>(path: string): T | null {\n if (!existsSync(path)) return null;\n const content = readFileSync(path, 'utf-8');\n return JSON.parse(content) as T;\n}\n\nexport function writeJsonFile(path: string, data: unknown): void {\n ensureDir(dirname(path));\n writeFileSync(path, JSON.stringify(data, null, 2) + '\\n', 'utf-8');\n}\n\nexport function isPathInside(targetPath: string, baseDir: string): boolean {\n const resolvedTarget = resolve(targetPath);\n const resolvedBase = resolve(baseDir);\n const baseWithSep = resolvedBase.endsWith(sep) ? resolvedBase : resolvedBase + sep;\n return resolvedTarget === resolvedBase || resolvedTarget.startsWith(baseWithSep);\n}\n","import type { TargetEnvironment } from '../core/types.js';\nimport { mapInstalledSkills } from '../core/map.js';\nimport { printJson } from '../utils/json.js';\n\nexport interface MapCommandOptions {\n target?: TargetEnvironment;\n global?: boolean;\n universal?: boolean;\n forceMap?: boolean;\n}\n\nexport async function runMap(options: MapCommandOptions): Promise<void> {\n if (!options.target) {\n throw new Error('map requires --target gemini');\n }\n const result = mapInstalledSkills({\n target: options.target,\n global: options.global,\n universal: options.universal,\n forceMap: options.forceMap,\n });\n printJson({ schemaVersion: '1', ...result });\n}\n","import { readFileSync } from 'fs';\nimport { dirname, join } from 'path';\nimport { fileURLToPath } from 'url';\nimport { createRequire } from 'module';\n\nconst require = createRequire(import.meta.url);\n\nexport function getOneskillVersion(): string {\n const __dirname = dirname(fileURLToPath(import.meta.url));\n const pkgPath = join(__dirname, '../../package.json');\n try {\n const content = readFileSync(pkgPath, 'utf-8');\n const parsed = JSON.parse(content) as { version?: string };\n return parsed.version || '0.0.0';\n } catch {\n return '0.0.0';\n }\n}\n\nexport function getOpenskillsVersion(): string {\n try {\n const pkgPath = require.resolve('openskills/package.json');\n const content = readFileSync(pkgPath, 'utf-8');\n const parsed = JSON.parse(content) as { version?: string };\n return parsed.version || '0.0.0';\n } catch {\n return '0.0.0';\n }\n}\n"],"mappings":";;;AACA,SAAS,eAAe;;;ACCxB,IAAM,uBAAuB;AAU7B,SAAS,gBAAgB,UAA2B;AAClD,UAAQ,YAAY,QAAQ,IAAI,yBAAyB,sBAAsB,QAAQ,OAAO,EAAE;AAClG;AAEA,eAAe,UAAU,KAA+B;AACtD,QAAM,MAAM,MAAM,MAAM,KAAK,EAAE,SAAS,EAAE,UAAU,mBAAmB,EAAE,CAAC;AAC1E,MAAI,CAAC,IAAI,IAAI;AACX,UAAM,OAAO,MAAM,IAAI,KAAK;AAC5B,UAAM,IAAI,MAAM,4BAA4B,IAAI,MAAM,MAAM,KAAK,MAAM,GAAG,GAAG,CAAC,EAAE;AAAA,EAClF;AACA,SAAO,IAAI,KAAK;AAClB;AAEA,SAAS,eAAe,MAA8C;AACpE,QAAM,OAAO,OAAO,KAAK,QAAQ,KAAK,MAAM,KAAK,QAAQ,EAAE;AAC3D,QAAM,OAAO,OAAO,KAAK,QAAQ,KAAK,SAAS,QAAQ,EAAE;AACzD,QAAM,cAAc,OAAO,KAAK,eAAe,KAAK,WAAW,EAAE;AACjE,QAAM,aAAa,OAAO,KAAK,cAAc,KAAK,QAAQ,KAAK,OAAO,EAAE;AACxE,QAAM,WAAW,OAAO,KAAK,aAAa,YAAY,KAAK,WAAW;AACtE,QAAM,QACJ,OAAO,KAAK,UAAU,WAClB,KAAK,QACL,OAAQ,KAAK,QAA4C,UAAU,WAClE,KAAK,OAA6B,QACnC;AACN,QAAM,OAAO,MAAM,QAAQ,KAAK,IAAI,IAAI,KAAK,KAAK,IAAI,MAAM,IAAI;AAChE,QAAM,YAAY,KAAK;AACvB,QAAM,aAAa,OAAO,KAAK,WAAW,WAAW,OAAO,KAAK,MAAM,IAAI,WAAW,OAAO,OAAO,UAAU,IAAI,IAAI;AACtH,QAAM,SAAS,aACX,EAAE,MAAM,YAAY,KAAK,WAAW,MAAM,OAAO,UAAU,GAAG,IAAI,OAAU,IAC5E;AAEJ,QAAM,UAAU;AAAA,IACd,aAAa,KAAK,cAAc,OAAO,KAAK,WAAW,IAAI;AAAA,IAC3D,SACE,KAAK,UAAU,OAAO,KAAK,OAAO,IAChC,OAAQ,KAAK,QAA8C,YAAY,WACvE,OAAQ,KAAK,OAA+B,OAAO,IACnD;AAAA,IACJ,WAAW,MAAM,QAAQ,KAAK,SAAS,IAAI,KAAK,UAAU,IAAI,MAAM,IAAI;AAAA,EAC1E;AAEA,SAAO;AAAA,IACL,eAAe;AAAA,IACf;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAAS,uBAAuB,SAAmC;AACjE,MAAI,CAAC,WAAW,OAAO,YAAY,SAAU,QAAO,CAAC;AACrD,QAAM,OAAO;AACb,QAAM,cACH,MAAM,QAAQ,KAAK,MAAM,IAAI,KAAK,SAAS,UAC3C,MAAM,QAAQ,KAAK,KAAK,IAAI,KAAK,QAAQ,UACzC,MAAM,QAAQ,KAAK,OAAO,IAAI,KAAK,UAAU,UAC7C,MAAM,QAAQ,KAAK,IAAI,IAAI,KAAK,OAAO,UACvC,MAAM,QAAQ,OAAO,IAAK,UAAwB;AAErD,MAAI,CAAC,WAAY,QAAO,CAAC;AACzB,SAAO,WACJ,OAAO,CAAC,SAAS,QAAQ,OAAO,SAAS,QAAQ,EACjD,IAAI,CAAC,SAAS,eAAe,IAA+B,CAAC;AAClE;AAEA,eAAsB,eAAe,QAAsB,aAAuD;AAChH,QAAM,OAAO,gBAAgB,WAAW;AACxC,QAAM,MAAM,IAAI,IAAI,IAAI;AACxB,MAAI,OAAO,EAAG,KAAI,aAAa,IAAI,KAAK,OAAO,CAAC;AAChD,MAAI,OAAO,SAAU,KAAI,aAAa,IAAI,YAAY,OAAO,QAAQ;AACrE,MAAI,OAAO,OAAO,UAAU,SAAU,KAAI,aAAa,IAAI,SAAS,OAAO,OAAO,KAAK,CAAC;AACxF,MAAI,OAAO,OAAO,WAAW,SAAU,KAAI,aAAa,IAAI,UAAU,OAAO,OAAO,MAAM,CAAC;AAC3F,MAAI,OAAO,KAAM,KAAI,aAAa,IAAI,QAAQ,OAAO,IAAI;AACzD,QAAM,MAAM,MAAM,UAAU,IAAI,SAAS,CAAC;AAC1C,QAAM,QAAQ,uBAAuB,GAAG;AACxC,SAAO,EAAE,OAAO,IAAI;AACtB;AAEA,eAAsB,kBAAkB,MAAc,aAAqD;AACzG,QAAM,OAAO,gBAAgB,WAAW;AACxC,QAAM,MAAM,GAAG,IAAI,IAAI,mBAAmB,IAAI,CAAC;AAC/C,QAAM,MAAM,MAAM,UAAU,GAAG;AAC/B,MAAI,OAAO,OAAO,QAAQ,UAAU;AAClC,UAAM,SAAS;AACf,UAAM,YAAa,OAAO,SAAkD,OAAO,QAAgD;AACnI,QAAI,aAAa,OAAO,cAAc,UAAU;AAC9C,aAAO,EAAE,MAAM,eAAe,SAAoC,GAAG,IAAI;AAAA,IAC3E;AAAA,EACF;AACA,QAAM,IAAI,MAAM,sBAAsB;AACxC;;;AC7GO,SAAS,UAAU,MAAqB;AAC7C,UAAQ,OAAO,MAAM,KAAK,UAAU,MAAM,MAAM,CAAC,IAAI,IAAI;AAC3D;;;ACSA,eAAsB,UAAU,OAAe,SAA8C;AAC3F,QAAM,SAAS,MAAM;AAAA,IACnB;AAAA,MACE,GAAG;AAAA,MACH,UAAU,QAAQ;AAAA,MAClB,OAAO,QAAQ;AAAA,MACf,QAAQ,QAAQ;AAAA,MAChB,MAAM,QAAQ;AAAA,IAChB;AAAA,IACA,QAAQ;AAAA,EACV;AACA,QAAM,MAAM,OAAO;AACnB,YAAU;AAAA,IACR,eAAe;AAAA,IACf;AAAA,IACA,UAAU,KAAK;AAAA,IACf,SAAS,KAAK;AAAA,IACd,YAAY,KAAK;AAAA,IACjB,OAAO,OAAO;AAAA,EAChB,CAAC;AACH;;;ACxBA,eAAsB,QAAQ,MAAc,SAA4C;AACtF,QAAM,SAAS,MAAM,kBAAkB,MAAM,QAAQ,QAAQ;AAC7D,YAAU,EAAE,eAAe,KAAK,MAAM,OAAO,KAAK,CAAC;AACrD;;;ACVA,SAAS,aAAAA,kBAAiB;;;ACA1B,SAAS,cAAc,kBAAkB;AACzC,SAAS,SAAS,eAAe;AACjC,SAAS,qBAAqB;AAC9B,SAAS,iBAAiB;AAE1B,IAAMC,WAAU,cAAc,YAAY,GAAG;AAEtC,SAAS,uBAA+B;AAC7C,QAAM,UAAUA,SAAQ,QAAQ,yBAAyB;AACzD,QAAM,SAAS,QAAQ,OAAO;AAC9B,QAAM,UAAU,aAAa,SAAS,OAAO;AAC7C,QAAM,SAAS,KAAK,MAAM,OAAO;AACjC,QAAM,MAAM,OAAO;AACnB,MAAI,YAA2B;AAC/B,MAAI,OAAO,QAAQ,UAAU;AAC3B,gBAAY,QAAQ,QAAQ,GAAG;AAAA,EACjC,WAAW,OAAO,OAAO,QAAQ,UAAU;AACzC,UAAM,QAAQ,OAAO,OAAO,GAAG,EAAE,CAAC;AAClC,QAAI,MAAO,aAAY,QAAQ,QAAQ,KAAK;AAAA,EAC9C,WAAW,OAAO,MAAM;AACtB,gBAAY,QAAQ,QAAQ,OAAO,IAAI;AAAA,EACzC;AAEA,MAAI,aAAa,WAAW,SAAS,GAAG;AACtC,WAAO;AAAA,EACT;AAGA,QAAM,SAAS,UAAU,OAAO,CAAC,OAAO,OAAO,GAAG;AAAA,IAChD,KAAK;AAAA,IACL,OAAO;AAAA,EACT,CAAC;AACD,MAAI,OAAO,WAAW,GAAG;AACvB,UAAM,IAAI,MAAM,4BAA4B;AAAA,EAC9C;AAEA,MAAI,aAAa,WAAW,SAAS,GAAG;AACtC,WAAO;AAAA,EACT;AAEA,QAAM,IAAI,MAAM,wCAAwC;AAC1D;;;ADpCA,eAAsB,QAAQ,UAA6C;AACzE,QAAM,UAAU,qBAAqB;AACrC,QAAM,OAAO,CAAC,SAAS,MAAM;AAC7B,QAAM,SAASC,WAAU,QAAQ,UAAU,MAAM;AAAA,IAC/C,KAAK,QAAQ,IAAI;AAAA,IACjB,OAAO;AAAA,EACT,CAAC;AACD,MAAI,OAAO,WAAW,GAAG;AACvB,UAAM,IAAI,MAAM,wBAAwB;AAAA,EAC1C;AACF;;;AEfA,SAAS,cAAAC,aAAY,gBAAAC,qBAAoB;AACzC,SAAS,WAAAC,UAAS,MAAM,WAAAC,gBAAe;AAGvC,IAAM,cAAc,CAAC,QAAQ,UAAU,WAAW,WAAW,QAAQ;AAErE,SAAS,kBAAkB,SAA0B;AACnD,MAAI;AACF,UAAM,UAAUF,cAAa,SAAS,OAAO;AAC7C,UAAM,SAAS,KAAK,MAAM,OAAO;AACjC,WAAO,QAAQ,OAAO,QAAQ;AAAA,EAChC,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,SAAS,WAAW,KAA4B;AAC9C,aAAW,UAAU,aAAa;AAChC,QAAID,YAAW,KAAK,KAAK,MAAM,CAAC,EAAG,QAAO;AAAA,EAC5C;AACA,MAAIA,YAAW,KAAK,KAAK,WAAW,CAAC,EAAG,QAAO;AAC/C,QAAM,UAAU,KAAK,KAAK,cAAc;AACxC,MAAIA,YAAW,OAAO,KAAK,kBAAkB,OAAO,EAAG,QAAO;AAC9D,SAAO;AACT;AAEO,SAAS,WAAW,UAAiC;AAC1D,MAAI,UAAUG,SAAQ,QAAQ;AAC9B,SAAO,MAAM;AACX,UAAM,SAAS,WAAW,OAAO;AACjC,QAAI,OAAQ,QAAO,EAAE,MAAM,SAAS,OAAO;AAC3C,UAAM,SAASD,SAAQ,OAAO;AAC9B,QAAI,WAAW,SAAS;AACtB,aAAO,EAAE,MAAMC,SAAQ,QAAQ,GAAG,QAAQ,eAAe;AAAA,IAC3D;AACA,cAAU;AAAA,EACZ;AACF;;;AC9BA,eAAsB,UAAU,SAA8C;AAC5E,QAAM,WAAW,WAAW,QAAQ,QAAQ,QAAQ,IAAI,CAAC;AACzD,QAAM,OAAO,SAAS;AACtB,QAAM,QAAQ;AAAA,IACZ,OAAO,GAAG,IAAI;AAAA,IACd,QAAQ,GAAG,IAAI;AAAA,IACf,QAAQ,GAAG,IAAI;AAAA,IACf,OAAO,GAAG,IAAI;AAAA,IACd,cAAc,GAAG,IAAI;AAAA,EACvB;AACA,YAAU,EAAE,eAAe,KAAK,MAAM,SAAS,MAAM,QAAQ,SAAS,QAAQ,MAAM,CAAC;AACvF;;;AClBA,SAAS,aAAAC,kBAAiB;AAQ1B,eAAsB,QAAQ,SAA4C;AACxE,QAAM,UAAU,qBAAqB;AACrC,QAAM,OAAO,CAAC,SAAS,MAAM;AAC7B,MAAI,QAAQ,KAAK;AACf,SAAK,KAAK,OAAO;AAAA,EACnB;AACA,MAAI,QAAQ,QAAQ;AAClB,SAAK,KAAK,YAAY,QAAQ,MAAM;AAAA,EACtC;AACA,QAAM,SAASC,WAAU,QAAQ,UAAU,MAAM;AAAA,IAC/C,KAAK,QAAQ,IAAI;AAAA,IACjB,OAAO;AAAA,EACT,CAAC;AACD,MAAI,OAAO,WAAW,GAAG;AACvB,UAAM,IAAI,MAAM,wBAAwB;AAAA,EAC1C;AACF;;;ACxBA,SAAS,cAAAC,aAAY,mBAAmB;AACxC,SAAS,UAAU,QAAAC,aAAY;AAC/B,SAAS,eAAe;;;ACFxB,SAAS,cAAAC,aAAY,WAAW,cAAc,QAAQ,aAAa,QAAQ,iBAAAC,sBAAqB;AAChG,SAAS,QAAAC,OAAM,WAAAC,gBAAe;;;ACD9B,SAAS,WAAW,gBAAAC,eAAc,eAAe,cAAAC,mBAAkB;AACnE,SAAS,WAAAC,UAAS,WAAAC,UAAS,WAAW;AAE/B,SAAS,UAAU,MAAoB;AAC5C,YAAU,MAAM,EAAE,WAAW,KAAK,CAAC;AACrC;AAaO,SAAS,aAAa,YAAoB,SAA0B;AACzE,QAAM,iBAAiBC,SAAQ,UAAU;AACzC,QAAM,eAAeA,SAAQ,OAAO;AACpC,QAAM,cAAc,aAAa,SAAS,GAAG,IAAI,eAAe,eAAe;AAC/E,SAAO,mBAAmB,gBAAgB,eAAe,WAAW,WAAW;AACjF;;;ADlBA,IAAM,cAAiD;AAAA,EACrD,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,OAAO;AACT;AAOA,SAAS,cAAc,MAAc,QAA2B,SAA8B;AAC5F,MAAI,WAAW,WAAW,SAAS,WAAW;AAC5C,WAAOC,SAAQ,QAAQ,WAAW,QAAQ;AAAA,EAC5C;AACA,SAAOC,MAAK,MAAM,YAAY,MAAM,CAAC;AACvC;AAEA,SAAS,eAAe,MAA6B;AACnD,MAAI;AACF,WAAO,aAAa,IAAI;AAAA,EAC1B,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEO,SAAS,SACd,MACA,QACA,WACA,WACA,SACoB;AACpB,QAAM,UAAU,cAAc,MAAM,QAAQ,OAAO;AACnD,QAAM,aAAaA,MAAK,SAAS,SAAS;AAE1C,MAAI,WAAW,WAAW,CAAC,aAAa,YAAY,IAAI,GAAG;AACzD,UAAM,IAAI,MAAM,6BAA6B,UAAU,EAAE;AAAA,EAC3D;AAEA,YAAU,OAAO;AAEjB,MAAIC,YAAW,UAAU,GAAG;AAC1B,UAAM,OAAO,UAAU,UAAU;AACjC,QAAI,KAAK,eAAe,GAAG;AACzB,YAAM,aAAa,eAAe,UAAU;AAC5C,UAAI,cAAcF,SAAQ,UAAU,MAAMA,SAAQ,SAAS,GAAG;AAC5D,eAAO,EAAE,QAAQ,MAAM,YAAY,MAAM,QAAQ,aAAa,UAAU,aAAa,WAAW,YAAW,oBAAI,KAAK,GAAE,YAAY,EAAE;AAAA,MACtI;AACA,UAAI,CAAC,SAAS,UAAU;AACtB,cAAM,IAAI,MAAM,oCAAoC,UAAU,EAAE;AAAA,MAClE;AAAA,IACF,OAAO;AACL,UAAI,CAAC,SAAS,UAAU;AACtB,cAAM,IAAI,MAAM,0BAA0B,UAAU,EAAE;AAAA,MACxD;AAAA,IACF;AACA,WAAO,YAAY,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AAAA,EACrD;AAEA,QAAM,WAAW,QAAQ,aAAa,UAAU,aAAa;AAC7D,MAAI;AACF,gBAAY,WAAW,YAAY,QAAQ;AAC3C,WAAO,EAAE,QAAQ,MAAM,YAAY,MAAM,QAAQ,aAAa,UAAU,aAAa,WAAW,YAAW,oBAAI,KAAK,GAAE,YAAY,EAAE;AAAA,EACtI,SAAS,OAAO;AACd,QAAI,CAAC,SAAS,UAAU;AAAA,IAExB;AAAA,EACF;AAEA,SAAO,WAAW,YAAY,EAAE,WAAW,MAAM,aAAa,MAAM,CAAC;AACrE,EAAAG;AAAA,IACEF,MAAK,YAAY,qBAAqB;AAAA,IACtC,KAAK,UAAU,EAAE,QAAQ,WAAW,WAAU,oBAAI,KAAK,GAAE,YAAY,GAAG,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI;AAAA,IACnG;AAAA,EACF;AAEA,SAAO,EAAE,QAAQ,MAAM,YAAY,MAAM,QAAQ,YAAW,oBAAI,KAAK,GAAE,YAAY,EAAE;AACvF;;;ADtEA,SAAS,cAAc,MAAc,SAA6B;AAChE,QAAM,WAAW,QAAQ,SAAS,QAAQ,IAAI;AAC9C,QAAM,SAAS,QAAQ,YAAY,kBAAkB;AACrD,SAAOG,MAAK,UAAU,MAAM;AAC9B;AAEA,SAAS,cAAc,MAAc,SAA6B;AAChE,SAAO,QAAQ,SAAS,QAAQ,IAAI;AACtC;AAEO,SAAS,mBAAmB,SAAiF;AAClH,MAAI,QAAQ,WAAW,UAAU;AAC/B,UAAM,IAAI,MAAM,6CAA6C;AAAA,EAC/D;AACA,QAAM,WAAW,WAAW,QAAQ,IAAI,CAAC;AACzC,QAAM,aAAa,cAAc,SAAS,MAAM,OAAO;AACvD,QAAM,aAAa,cAAc,SAAS,MAAM,OAAO;AAEvD,MAAI,CAACC,YAAW,UAAU,GAAG;AAC3B,WAAO,EAAE,QAAQ,GAAG,YAAY,WAAW;AAAA,EAC7C;AAEA,QAAM,UAAU,YAAY,YAAY,EAAE,eAAe,KAAK,CAAC,EAC5D,OAAO,CAAC,UAAU,MAAM,YAAY,CAAC,EACrC,IAAI,CAAC,UAAUD,MAAK,YAAY,MAAM,IAAI,CAAC;AAE9C,MAAI,SAAS;AACb,aAAW,OAAO,SAAS;AACzB,UAAM,OAAO,SAAS,GAAG;AACzB,aAAS,YAAY,UAAU,MAAM,KAAK,EAAE,UAAU,QAAQ,SAAS,CAAC;AACxE,cAAU;AAAA,EACZ;AAEA,SAAO,EAAE,QAAQ,YAAY,WAAW;AAC1C;;;AGrCA,eAAsB,OAAO,SAA2C;AACtE,MAAI,CAAC,QAAQ,QAAQ;AACnB,UAAM,IAAI,MAAM,8BAA8B;AAAA,EAChD;AACA,QAAM,SAAS,mBAAmB;AAAA,IAChC,QAAQ,QAAQ;AAAA,IAChB,QAAQ,QAAQ;AAAA,IAChB,WAAW,QAAQ;AAAA,IACnB,UAAU,QAAQ;AAAA,EACpB,CAAC;AACD,YAAU,EAAE,eAAe,KAAK,GAAG,OAAO,CAAC;AAC7C;;;ACtBA,SAAS,gBAAAE,qBAAoB;AAC7B,SAAS,WAAAC,UAAS,QAAAC,aAAY;AAC9B,SAAS,qBAAqB;AAC9B,SAAS,iBAAAC,sBAAqB;AAE9B,IAAMC,WAAUD,eAAc,YAAY,GAAG;AAEtC,SAAS,qBAA6B;AAC3C,QAAM,YAAYF,SAAQ,cAAc,YAAY,GAAG,CAAC;AACxD,QAAM,UAAUC,MAAK,WAAW,oBAAoB;AACpD,MAAI;AACF,UAAM,UAAUF,cAAa,SAAS,OAAO;AAC7C,UAAM,SAAS,KAAK,MAAM,OAAO;AACjC,WAAO,OAAO,WAAW;AAAA,EAC3B,QAAQ;AACN,WAAO;AAAA,EACT;AACF;;;AdPA,IAAM,UAAU,IAAI,QAAQ;AAE5B,QACG,KAAK,UAAU,EACf,YAAY,yCAAyC,EACrD,QAAQ,mBAAmB,CAAC;AAE/B,QACG,QAAQ,gBAAgB,EACxB,YAAY,2BAA2B,EACvC,OAAO,oBAAoB,4BAA4B,EACvD,OAAO,qBAAqB,yBAAyB,EACrD,OAAO,eAAe,8BAA8B,CAAC,UAAU,OAAO,SAAS,OAAO,EAAE,CAAC,EACzF,OAAO,gBAAgB,qBAAqB,CAAC,UAAU,OAAO,SAAS,OAAO,EAAE,CAAC,EACjF,OAAO,kBAAkB,+BAA+B,EACxD,OAAO,OAAO,OAAe,YAAsG;AAClI,QAAM,UAAU,OAAO,OAAO;AAChC,CAAC;AAEH,QACG,QAAQ,aAAa,EACrB,YAAY,gCAAgC,EAC5C,OAAO,oBAAoB,4BAA4B,EACvD,OAAO,OAAO,MAAc,YAAmC;AAC9D,QAAM,QAAQ,MAAM,OAAO;AAC7B,CAAC;AAEH,QACG,QAAQ,MAAM,EACd,YAAY,4BAA4B,EACxC,OAAO,aAAa,6CAA6C,EACjE,OAAO,uBAAuB,uCAAuC,EACrE,OAAO,OAAO,YAAgD;AAC7D,QAAM,QAAQ,OAAO;AACvB,CAAC;AAEH,QACG,QAAQ,KAAK,EACb,YAAY,4CAA4C,EACxD,OAAO,qBAAqB,kCAAkC,EAC9D,OAAO,YAAY,sCAAsC,KAAK,EAC9D,OAAO,eAAe,sCAAsC,KAAK,EACjE,OAAO,eAAe,yCAAyC,KAAK,EACpE,OAAO,OAAO,YAA4F;AACzG,QAAM,OAAO;AAAA,IACX,QAAQ,QAAQ;AAAA,IAChB,QAAQ,QAAQ;AAAA,IAChB,WAAW,QAAQ;AAAA,IACnB,UAAU,QAAQ;AAAA,EACpB,CAAC;AACH,CAAC;AAEH,QACG,QAAQ,MAAM,EACd,YAAY,qBAAqB,EACjC,OAAO,iBAAiB,yBAAyB,EACjD,OAAO,OAAO,YAA+B;AAC5C,QAAM,QAAQ,OAAO;AACvB,CAAC;AAEH,QACG,QAAQ,QAAQ,EAChB,YAAY,+BAA+B,EAC3C,OAAO,iBAAiB,yBAAyB,EACjD,OAAO,OAAO,YAA+B;AAC5C,QAAM,UAAU,OAAO;AACzB,CAAC;AAEH,QAAQ,WAAW,QAAQ,IAAI,EAAE,MAAM,CAAC,UAAU;AAChD,UAAQ,MAAM,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AACpE,UAAQ,WAAW;AACrB,CAAC;","names":["spawnSync","require","spawnSync","existsSync","readFileSync","dirname","resolve","spawnSync","spawnSync","existsSync","join","existsSync","writeFileSync","join","resolve","readFileSync","existsSync","dirname","resolve","resolve","resolve","join","existsSync","writeFileSync","join","existsSync","readFileSync","dirname","join","createRequire","require"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "oneskill",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Meta-skill manager for AI coding agents",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/cli.js",
|
|
7
|
+
"bin": {
|
|
8
|
+
"oneskill": "dist/cli.js"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"dist",
|
|
12
|
+
"README.md",
|
|
13
|
+
"SKILL.md"
|
|
14
|
+
],
|
|
15
|
+
"scripts": {
|
|
16
|
+
"build": "tsup",
|
|
17
|
+
"dev": "tsup --watch",
|
|
18
|
+
"typecheck": "tsc --noEmit",
|
|
19
|
+
"test": "vitest run"
|
|
20
|
+
},
|
|
21
|
+
"keywords": [
|
|
22
|
+
"skills",
|
|
23
|
+
"ai",
|
|
24
|
+
"agents",
|
|
25
|
+
"meta-skill",
|
|
26
|
+
"codex",
|
|
27
|
+
"gemini",
|
|
28
|
+
"claude"
|
|
29
|
+
],
|
|
30
|
+
"author": "OneSkill Contributors",
|
|
31
|
+
"license": "Apache-2.0",
|
|
32
|
+
"engines": {
|
|
33
|
+
"node": ">=20.6.0"
|
|
34
|
+
},
|
|
35
|
+
"dependencies": {
|
|
36
|
+
"chalk": "^5.6.2",
|
|
37
|
+
"commander": "^12.1.0"
|
|
38
|
+
},
|
|
39
|
+
"devDependencies": {
|
|
40
|
+
"@types/node": "^24.9.1",
|
|
41
|
+
"tsup": "^8.5.0",
|
|
42
|
+
"typescript": "^5.9.3",
|
|
43
|
+
"vitest": "^4.0.3"
|
|
44
|
+
}
|
|
45
|
+
}
|