@nodeskai/genehub 2026.3.2-8 → 2026.3.3
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 +21 -0
- package/README.md +96 -0
- package/dist/index.js +158 -27
- package/dist/index.js.map +1 -1
- package/package.json +12 -13
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 NoDeskAI
|
|
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,96 @@
|
|
|
1
|
+
# @nodeskai/genehub - GeneHub CLI
|
|
2
|
+
|
|
3
|
+
AI 员工基因管理命令行工具,用于搜索、安装、发布基因到 GeneHub Registry。
|
|
4
|
+
|
|
5
|
+
## 安装
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install -g @nodeskai/genehub
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## 配置
|
|
12
|
+
|
|
13
|
+
### 配置文件
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
genehub config set registry https://genehub.nodeskai.com
|
|
17
|
+
genehub config set token <your-token>
|
|
18
|
+
genehub config get
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
配置文件存储在 `~/.genehub/config.json`。
|
|
22
|
+
|
|
23
|
+
### 环境变量
|
|
24
|
+
|
|
25
|
+
环境变量优先级高于配置文件:
|
|
26
|
+
|
|
27
|
+
| 环境变量 | 说明 | 对应配置项 |
|
|
28
|
+
|---|---|---|
|
|
29
|
+
| `GENEHUB_REGISTRY_URL` | Registry 地址 | `registry` |
|
|
30
|
+
| `GENEHUB_REGISTRY` | Registry 地址(别名) | `registry` |
|
|
31
|
+
| `GENEHUB_TOKEN` | 认证 Token | `token` |
|
|
32
|
+
|
|
33
|
+
本地开发示例:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
GENEHUB_REGISTRY_URL=http://localhost:3000 GENEHUB_TOKEN=dev genehub publish ./my-gene
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## 认证
|
|
40
|
+
|
|
41
|
+
使用 GitHub OAuth 登录,自动创建 API Key:
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
genehub auth login # 打开浏览器完成 GitHub 登录,自动保存 token
|
|
45
|
+
genehub auth status # 查看当前登录状态
|
|
46
|
+
genehub auth logout # 退出登录(清除本地 token)
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## 命令
|
|
50
|
+
|
|
51
|
+
| 命令 | 说明 |
|
|
52
|
+
|---|---|
|
|
53
|
+
| `genehub auth login` | GitHub OAuth 登录 |
|
|
54
|
+
| `genehub auth status` | 查看登录状态 |
|
|
55
|
+
| `genehub auth logout` | 退出登录 |
|
|
56
|
+
| `genehub search [keyword]` | 搜索基因库 |
|
|
57
|
+
| `genehub install <slug>` | 安装基因到当前 Agent 环境 |
|
|
58
|
+
| `genehub uninstall <slug>` | 卸载基因 |
|
|
59
|
+
| `genehub publish <path>` | 发布基因到 Registry |
|
|
60
|
+
| `genehub list` | 列出已安装的基因 |
|
|
61
|
+
| `genehub learn <slug>` | 触发基因深度学习(L2) |
|
|
62
|
+
| `genehub init` | 初始化基因项目 |
|
|
63
|
+
| `genehub config` | 管理配置 |
|
|
64
|
+
|
|
65
|
+
## 目录结构
|
|
66
|
+
|
|
67
|
+
```
|
|
68
|
+
packages/cli/
|
|
69
|
+
├── src/
|
|
70
|
+
│ ├── index.ts # 入口,注册所有命令
|
|
71
|
+
│ ├── config.ts # 配置管理(文件 + 环境变量)
|
|
72
|
+
│ ├── output.ts # 格式化输出工具
|
|
73
|
+
│ └── commands/
|
|
74
|
+
│ ├── auth.ts # GitHub OAuth 登录
|
|
75
|
+
│ ├── config.ts # config set / get
|
|
76
|
+
│ ├── init.ts # 初始化基因项目
|
|
77
|
+
│ ├── install.ts # 安装基因
|
|
78
|
+
│ ├── learn.ts # 深度学习
|
|
79
|
+
│ ├── list.ts # 列出已安装基因
|
|
80
|
+
│ ├── publish.ts # 发布基因
|
|
81
|
+
│ ├── search.ts # 搜索基因
|
|
82
|
+
│ └── uninstall.ts # 卸载基因
|
|
83
|
+
├── dist/ # 构建产物
|
|
84
|
+
├── package.json
|
|
85
|
+
└── tsup.config.ts
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## 开发
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
cd packages/cli
|
|
92
|
+
pnpm install
|
|
93
|
+
pnpm build # 构建
|
|
94
|
+
pnpm dev # 开发模式
|
|
95
|
+
pnpm test # 测试
|
|
96
|
+
```
|
package/dist/index.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
// src/index.ts
|
|
4
|
-
import { Command as
|
|
4
|
+
import { Command as Command10 } from "commander";
|
|
5
5
|
|
|
6
|
-
// src/commands/
|
|
6
|
+
// src/commands/auth.ts
|
|
7
|
+
import { createServer } from "http";
|
|
7
8
|
import { Command } from "commander";
|
|
8
9
|
|
|
9
10
|
// src/config.ts
|
|
@@ -16,12 +17,31 @@ var DEFAULT_CONFIG = {
|
|
|
16
17
|
registryUrl: "https://genehub.nodeskai.com"
|
|
17
18
|
};
|
|
18
19
|
async function loadConfig() {
|
|
20
|
+
let fileConfig = {};
|
|
19
21
|
try {
|
|
20
22
|
const raw = await readFile(CONFIG_PATH, "utf-8");
|
|
21
|
-
|
|
23
|
+
fileConfig = JSON.parse(raw);
|
|
22
24
|
} catch {
|
|
23
|
-
return DEFAULT_CONFIG;
|
|
24
25
|
}
|
|
26
|
+
const merged = { ...DEFAULT_CONFIG, ...fileConfig };
|
|
27
|
+
const envUrl = process.env.GENEHUB_REGISTRY_URL ?? process.env.GENEHUB_REGISTRY;
|
|
28
|
+
if (envUrl) {
|
|
29
|
+
merged.registryUrl = envUrl;
|
|
30
|
+
}
|
|
31
|
+
const envToken = process.env.GENEHUB_TOKEN;
|
|
32
|
+
if (envToken) {
|
|
33
|
+
merged.token = envToken;
|
|
34
|
+
}
|
|
35
|
+
return merged;
|
|
36
|
+
}
|
|
37
|
+
function getConfigSource(key) {
|
|
38
|
+
if (key === "registry") {
|
|
39
|
+
if (process.env.GENEHUB_REGISTRY_URL || process.env.GENEHUB_REGISTRY) return "env";
|
|
40
|
+
}
|
|
41
|
+
if (key === "token") {
|
|
42
|
+
if (process.env.GENEHUB_TOKEN) return "env";
|
|
43
|
+
}
|
|
44
|
+
return "file";
|
|
25
45
|
}
|
|
26
46
|
async function saveConfig(config) {
|
|
27
47
|
const current = await loadConfig();
|
|
@@ -56,8 +76,102 @@ function table(headers, rows) {
|
|
|
56
76
|
console.log(t.toString());
|
|
57
77
|
}
|
|
58
78
|
|
|
79
|
+
// src/commands/auth.ts
|
|
80
|
+
var authCommand = new Command("auth").description("\u8BA4\u8BC1\u7BA1\u7406");
|
|
81
|
+
authCommand.command("login").description("\u901A\u8FC7 GitHub OAuth \u767B\u5F55\u5E76\u81EA\u52A8\u521B\u5EFA API Key").action(async () => {
|
|
82
|
+
const config = await loadConfig();
|
|
83
|
+
const registryUrl = config.registryUrl.replace(/\/$/, "");
|
|
84
|
+
const port = await findAvailablePort(9876);
|
|
85
|
+
const callbackUrl = `http://localhost:${port}/callback`;
|
|
86
|
+
const tokenPromise = waitForCallback(port);
|
|
87
|
+
const authUrl = `${registryUrl}/auth/github?cli_callback=${encodeURIComponent(callbackUrl)}`;
|
|
88
|
+
info(`Opening browser for GitHub login...`);
|
|
89
|
+
info(` ${authUrl}`);
|
|
90
|
+
const open = await import("open").catch(() => null);
|
|
91
|
+
if (open) {
|
|
92
|
+
await open.default(authUrl);
|
|
93
|
+
} else {
|
|
94
|
+
warn("Cannot open browser automatically. Please open the URL above manually.");
|
|
95
|
+
}
|
|
96
|
+
try {
|
|
97
|
+
const { token, login } = await tokenPromise;
|
|
98
|
+
await saveConfig({ token });
|
|
99
|
+
ok(`Logged in as @${login}`);
|
|
100
|
+
ok(`Token saved to config (${token.slice(0, 12)}****)`);
|
|
101
|
+
} catch (err) {
|
|
102
|
+
fail(err instanceof Error ? err.message : "Login failed");
|
|
103
|
+
process.exit(1);
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
authCommand.command("status").description("\u67E5\u770B\u5F53\u524D\u767B\u5F55\u72B6\u6001").action(async () => {
|
|
107
|
+
const config = await loadConfig();
|
|
108
|
+
if (!config.token) {
|
|
109
|
+
info("Not logged in");
|
|
110
|
+
info(" Run: genehub auth login");
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
ok(`Token: ${config.token.slice(0, 12)}****`);
|
|
114
|
+
info(`Registry: ${config.registryUrl}`);
|
|
115
|
+
});
|
|
116
|
+
authCommand.command("logout").description("\u9000\u51FA\u767B\u5F55\uFF08\u6E05\u9664\u672C\u5730 token\uFF09").action(async () => {
|
|
117
|
+
await saveConfig({ token: void 0 });
|
|
118
|
+
ok("Logged out. Token removed.");
|
|
119
|
+
});
|
|
120
|
+
function findAvailablePort(preferred) {
|
|
121
|
+
return new Promise((resolve3, reject) => {
|
|
122
|
+
const server = createServer();
|
|
123
|
+
server.listen(preferred, () => {
|
|
124
|
+
server.close(() => resolve3(preferred));
|
|
125
|
+
});
|
|
126
|
+
server.on("error", () => {
|
|
127
|
+
const fallback = createServer();
|
|
128
|
+
fallback.listen(0, () => {
|
|
129
|
+
const addr = fallback.address();
|
|
130
|
+
const port = typeof addr === "object" && addr ? addr.port : 0;
|
|
131
|
+
fallback.close(() => resolve3(port));
|
|
132
|
+
});
|
|
133
|
+
fallback.on("error", reject);
|
|
134
|
+
});
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
function waitForCallback(port) {
|
|
138
|
+
return new Promise((resolve3, reject) => {
|
|
139
|
+
const timeout = setTimeout(() => {
|
|
140
|
+
server.close();
|
|
141
|
+
reject(new Error("Login timeout (60s)"));
|
|
142
|
+
}, 6e4);
|
|
143
|
+
const server = createServer((req, res) => {
|
|
144
|
+
if (!req.url?.startsWith("/callback")) {
|
|
145
|
+
res.writeHead(404);
|
|
146
|
+
res.end();
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
const url = new URL(req.url, `http://localhost:${port}`);
|
|
150
|
+
const token = url.searchParams.get("token");
|
|
151
|
+
const login = url.searchParams.get("login");
|
|
152
|
+
if (!token) {
|
|
153
|
+
res.writeHead(400, { "Content-Type": "text/html; charset=utf-8" });
|
|
154
|
+
res.end("<h2>Login failed</h2><p>No token received.</p>");
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
|
|
158
|
+
res.end(`<h2>Login successful</h2><p>@${login ?? "unknown"} - you can close this tab.</p>`);
|
|
159
|
+
clearTimeout(timeout);
|
|
160
|
+
server.close();
|
|
161
|
+
resolve3({ token, login: login ?? "" });
|
|
162
|
+
});
|
|
163
|
+
server.listen(port);
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
|
|
59
167
|
// src/commands/config.ts
|
|
60
|
-
|
|
168
|
+
import { Command as Command2 } from "commander";
|
|
169
|
+
var configCommand = new Command2("config").description("\u7BA1\u7406 GeneHub CLI \u914D\u7F6E");
|
|
170
|
+
function sourceLabel(source) {
|
|
171
|
+
if (source === "env") return " [env]";
|
|
172
|
+
if (source === "default") return " [default]";
|
|
173
|
+
return "";
|
|
174
|
+
}
|
|
61
175
|
configCommand.command("set <key> <value>").description("\u8BBE\u7F6E\u914D\u7F6E\u9879\uFF08registry / token\uFF09").action(async (key, value) => {
|
|
62
176
|
const validKeys = ["registry", "token"];
|
|
63
177
|
if (!validKeys.includes(key)) {
|
|
@@ -71,24 +185,29 @@ configCommand.command("set <key> <value>").description("\u8BBE\u7F6E\u914D\u7F6E
|
|
|
71
185
|
}
|
|
72
186
|
ok(`${key} = ${key === "token" ? `${value.slice(0, 8)}***` : value}`);
|
|
73
187
|
});
|
|
74
|
-
configCommand.command("get [key]").description("\u67E5\u770B\u914D\u7F6E").action(async (key) => {
|
|
188
|
+
configCommand.command("get [key]").description("\u67E5\u770B\u914D\u7F6E\uFF08\u652F\u6301 GENEHUB_REGISTRY_URL / GENEHUB_TOKEN \u73AF\u5883\u53D8\u91CF\u8986\u76D6\uFF09").action(async (key) => {
|
|
75
189
|
const config = await loadConfig();
|
|
76
190
|
if (key) {
|
|
77
191
|
const map = {
|
|
78
192
|
registry: config.registryUrl,
|
|
79
193
|
token: config.token ? `${config.token.slice(0, 8)}***` : void 0
|
|
80
194
|
};
|
|
81
|
-
|
|
195
|
+
const src = sourceLabel(getConfigSource(key));
|
|
196
|
+
info(`${key} = ${map[key] ?? "(\u672A\u8BBE\u7F6E)"}${src}`);
|
|
82
197
|
} else {
|
|
83
|
-
|
|
84
|
-
|
|
198
|
+
const regSrc = sourceLabel(getConfigSource("registry"));
|
|
199
|
+
const tokSrc = sourceLabel(getConfigSource("token"));
|
|
200
|
+
info(`registry = ${config.registryUrl}${regSrc}`);
|
|
201
|
+
info(
|
|
202
|
+
`token = ${config.token ? `${config.token.slice(0, 8)}***` : "(\u672A\u8BBE\u7F6E)"}${tokSrc}`
|
|
203
|
+
);
|
|
85
204
|
}
|
|
86
205
|
});
|
|
87
206
|
|
|
88
207
|
// src/commands/init.ts
|
|
89
208
|
import { mkdir as mkdir2, writeFile as writeFile2 } from "fs/promises";
|
|
90
209
|
import { join as join2, resolve } from "path";
|
|
91
|
-
import { Command as
|
|
210
|
+
import { Command as Command3 } from "commander";
|
|
92
211
|
import { stringify } from "yaml";
|
|
93
212
|
var TEMPLATE = {
|
|
94
213
|
slug: "my-gene",
|
|
@@ -131,7 +250,7 @@ metadata:
|
|
|
131
250
|
|
|
132
251
|
\u5728\u6B64\u7F16\u5199\u57FA\u56E0\u7684\u6280\u80FD\u63CF\u8FF0...
|
|
133
252
|
`;
|
|
134
|
-
var initCommand = new
|
|
253
|
+
var initCommand = new Command3("init").description("\u521D\u59CB\u5316\u57FA\u56E0\u6A21\u677F").argument("[path]", "\u76EE\u6807\u76EE\u5F55", ".").action(async (dirPath) => {
|
|
135
254
|
const absPath = resolve(dirPath);
|
|
136
255
|
try {
|
|
137
256
|
await mkdir2(absPath, { recursive: true });
|
|
@@ -153,7 +272,7 @@ var initCommand = new Command2("init").description("\u521D\u59CB\u5316\u57FA\u56
|
|
|
153
272
|
import { homedir as homedir2 } from "os";
|
|
154
273
|
import { join as join3 } from "path";
|
|
155
274
|
import { detectAdapter, GeneHubClient, getAdapter, LearningEngine } from "@nodeskai/genehub-sdk";
|
|
156
|
-
import { Command as
|
|
275
|
+
import { Command as Command4 } from "commander";
|
|
157
276
|
import ora from "ora";
|
|
158
277
|
function parseSlugVersion(input) {
|
|
159
278
|
const atIdx = input.lastIndexOf("@");
|
|
@@ -162,7 +281,7 @@ function parseSlugVersion(input) {
|
|
|
162
281
|
}
|
|
163
282
|
return { slug: input };
|
|
164
283
|
}
|
|
165
|
-
var installCommand = new
|
|
284
|
+
var installCommand = new Command4("install").description("\u5B89\u88C5\u57FA\u56E0\u5230\u5F53\u524D Agent \u73AF\u5883").argument("<slug>", "\u57FA\u56E0\u6807\u8BC6\u7B26\uFF08\u652F\u6301 slug@version \u683C\u5F0F\uFF09").option("-p, --product <product>", "\u6307\u5B9A\u76EE\u6807\u4EA7\u54C1\uFF08openclaw / nanobot / generic\uFF09").option("-f, --force", "\u5F3A\u5236\u8986\u76D6\u5DF2\u5B89\u88C5\u7248\u672C", false).option("--target <path>", "\u6307\u5B9A\u5B89\u88C5\u76EE\u6807\u8DEF\u5F84").option("--learn", "\u5B89\u88C5\u540E\u81EA\u52A8\u89E6\u53D1\u6DF1\u5EA6\u5B66\u4E60", false).action(async (rawSlug, opts) => {
|
|
166
285
|
const config = await loadConfig();
|
|
167
286
|
const client = new GeneHubClient({ registryUrl: config.registryUrl, token: config.token });
|
|
168
287
|
const { slug, version } = parseSlugVersion(rawSlug);
|
|
@@ -213,7 +332,7 @@ var installCommand = new Command3("install").description("\u5B89\u88C5\u57FA\u56
|
|
|
213
332
|
import { homedir as homedir3 } from "os";
|
|
214
333
|
import { join as join4 } from "path";
|
|
215
334
|
import { detectAdapter as detectAdapter2, GeneHubClient as GeneHubClient2, getAdapter as getAdapter2, LearningEngine as LearningEngine2 } from "@nodeskai/genehub-sdk";
|
|
216
|
-
import { Command as
|
|
335
|
+
import { Command as Command5 } from "commander";
|
|
217
336
|
import ora2 from "ora";
|
|
218
337
|
function getWorkspaceDir(product) {
|
|
219
338
|
switch (product) {
|
|
@@ -225,7 +344,7 @@ function getWorkspaceDir(product) {
|
|
|
225
344
|
return join4(process.cwd(), ".genehub");
|
|
226
345
|
}
|
|
227
346
|
}
|
|
228
|
-
var learnCommand = new
|
|
347
|
+
var learnCommand = new Command5("learn").description("\u89E6\u53D1\u57FA\u56E0\u6DF1\u5EA6\u5B66\u4E60\uFF08L2\uFF09").argument("<slug>", "\u57FA\u56E0\u6807\u8BC6\u7B26").option("-p, --product <product>", "\u6307\u5B9A\u76EE\u6807\u4EA7\u54C1").option("--check", "\u68C0\u67E5\u5B66\u4E60\u7ED3\u679C\u5E76\u5E94\u7528").action(async (slug, opts) => {
|
|
229
348
|
const config = await loadConfig();
|
|
230
349
|
const client = new GeneHubClient2({ registryUrl: config.registryUrl, token: config.token });
|
|
231
350
|
const adapter = opts.product ? getAdapter2(opts.product) : await detectAdapter2();
|
|
@@ -284,8 +403,8 @@ var learnCommand = new Command4("learn").description("\u89E6\u53D1\u57FA\u56E0\u
|
|
|
284
403
|
|
|
285
404
|
// src/commands/list.ts
|
|
286
405
|
import { detectAdapter as detectAdapter3, getAdapter as getAdapter3 } from "@nodeskai/genehub-sdk";
|
|
287
|
-
import { Command as
|
|
288
|
-
var listCommand = new
|
|
406
|
+
import { Command as Command6 } from "commander";
|
|
407
|
+
var listCommand = new Command6("list").description("\u5217\u51FA\u5F53\u524D\u73AF\u5883\u5DF2\u5B89\u88C5\u7684\u57FA\u56E0").option("-p, --product <product>", "\u6307\u5B9A\u76EE\u6807\u4EA7\u54C1").option("--json", "JSON \u683C\u5F0F\u8F93\u51FA", false).action(async (opts) => {
|
|
289
408
|
try {
|
|
290
409
|
const adapter = opts.product ? getAdapter3(opts.product) : await detectAdapter3();
|
|
291
410
|
const genes = await adapter.list();
|
|
@@ -314,13 +433,15 @@ import { readFile as readFile2 } from "fs/promises";
|
|
|
314
433
|
import { join as join5, resolve as resolve2 } from "path";
|
|
315
434
|
import { GeneHubClient as GeneHubClient3 } from "@nodeskai/genehub-sdk";
|
|
316
435
|
import { GeneManifestSchema } from "@nodeskai/genehub-types";
|
|
317
|
-
import { Command as
|
|
436
|
+
import { Command as Command7 } from "commander";
|
|
318
437
|
import ora3 from "ora";
|
|
319
438
|
import { parse } from "yaml";
|
|
320
|
-
var publishCommand = new
|
|
439
|
+
var publishCommand = new Command7("publish").description("\u53D1\u5E03\u57FA\u56E0\u5230 GeneHub Registry").argument("<path>", "\u57FA\u56E0\u76EE\u5F55\u8DEF\u5F84\uFF08\u5305\u542B gene.yaml\uFF09").action(async (dirPath) => {
|
|
321
440
|
const config = await loadConfig();
|
|
322
441
|
if (!config.token) {
|
|
323
|
-
fail("\u672A\u914D\u7F6E\u8BA4\u8BC1 token
|
|
442
|
+
fail("\u672A\u914D\u7F6E\u8BA4\u8BC1 token");
|
|
443
|
+
info(" \u65B9\u5F0F 1: genehub config set token <token>");
|
|
444
|
+
info(" \u65B9\u5F0F 2: export GENEHUB_TOKEN=<token>");
|
|
324
445
|
process.exit(1);
|
|
325
446
|
}
|
|
326
447
|
const client = new GeneHubClient3({ registryUrl: config.registryUrl, token: config.token });
|
|
@@ -345,8 +466,17 @@ var publishCommand = new Command6("publish").description("\u53D1\u5E03\u57FA\u56
|
|
|
345
466
|
}
|
|
346
467
|
process.exit(1);
|
|
347
468
|
}
|
|
348
|
-
const
|
|
349
|
-
const
|
|
469
|
+
const { slug, version } = validation.data;
|
|
470
|
+
const spinner = ora3(`\u53D1\u5E03 ${slug}@${version}...`).start();
|
|
471
|
+
let gene;
|
|
472
|
+
try {
|
|
473
|
+
gene = await client.publishGene(validation.data);
|
|
474
|
+
} catch (err) {
|
|
475
|
+
const isSlugExists = err instanceof Error && err.message.includes("gene_slug_exists");
|
|
476
|
+
if (!isSlugExists) throw err;
|
|
477
|
+
spinner.text = `\u57FA\u56E0 ${slug} \u5DF2\u5B58\u5728\uFF0C\u53D1\u5E03\u65B0\u7248\u672C ${version}...`;
|
|
478
|
+
gene = await client.publishVersion(slug, validation.data);
|
|
479
|
+
}
|
|
350
480
|
spinner.succeed("\u53D1\u5E03\u6210\u529F");
|
|
351
481
|
ok(`${gene.slug}@${gene.version} \u5DF2\u53D1\u5E03\u5230 GeneHub Registry`);
|
|
352
482
|
} catch (err) {
|
|
@@ -357,8 +487,8 @@ var publishCommand = new Command6("publish").description("\u53D1\u5E03\u57FA\u56
|
|
|
357
487
|
|
|
358
488
|
// src/commands/search.ts
|
|
359
489
|
import { GeneHubClient as GeneHubClient4 } from "@nodeskai/genehub-sdk";
|
|
360
|
-
import { Command as
|
|
361
|
-
var searchCommand = new
|
|
490
|
+
import { Command as Command8 } from "commander";
|
|
491
|
+
var searchCommand = new Command8("search").description("\u641C\u7D22\u57FA\u56E0\u5E93").argument("[keyword]", "\u641C\u7D22\u5173\u952E\u8BCD").option("-c, --category <category>", "\u6309\u5206\u7C7B\u8FC7\u6EE4").option("-t, --tags <tags>", "\u6309\u6807\u7B7E\u8FC7\u6EE4\uFF08\u9017\u53F7\u5206\u9694\uFF09").option("--compat <product>", "\u6309\u517C\u5BB9\u4EA7\u54C1\u8FC7\u6EE4").option("-s, --sort <sort>", "\u6392\u5E8F\u65B9\u5F0F\uFF08newest / popular / rating\uFF09", "newest").option("--page <page>", "\u9875\u7801", "1").option("--json", "JSON \u683C\u5F0F\u8F93\u51FA", false).action(async (keyword, opts) => {
|
|
362
492
|
const config = await loadConfig();
|
|
363
493
|
const client = new GeneHubClient4({ registryUrl: config.registryUrl, token: config.token });
|
|
364
494
|
try {
|
|
@@ -398,9 +528,9 @@ var searchCommand = new Command7("search").description("\u641C\u7D22\u57FA\u56E0
|
|
|
398
528
|
|
|
399
529
|
// src/commands/uninstall.ts
|
|
400
530
|
import { detectAdapter as detectAdapter4, getAdapter as getAdapter4 } from "@nodeskai/genehub-sdk";
|
|
401
|
-
import { Command as
|
|
531
|
+
import { Command as Command9 } from "commander";
|
|
402
532
|
import ora4 from "ora";
|
|
403
|
-
var uninstallCommand = new
|
|
533
|
+
var uninstallCommand = new Command9("uninstall").description("\u4ECE\u5F53\u524D Agent \u73AF\u5883\u5378\u8F7D\u57FA\u56E0").argument("<slug>", "\u57FA\u56E0\u6807\u8BC6\u7B26").option("-p, --product <product>", "\u6307\u5B9A\u76EE\u6807\u4EA7\u54C1\uFF08openclaw / nanobot / generic\uFF09").action(async (slug, opts) => {
|
|
404
534
|
const adapter = opts.product ? getAdapter4(opts.product) : await detectAdapter4();
|
|
405
535
|
info(`\u76EE\u6807\u4EA7\u54C1: ${adapter.product}`);
|
|
406
536
|
if (!await adapter.isInstalled(slug)) {
|
|
@@ -424,8 +554,9 @@ var uninstallCommand = new Command8("uninstall").description("\u4ECE\u5F53\u524D
|
|
|
424
554
|
});
|
|
425
555
|
|
|
426
556
|
// src/index.ts
|
|
427
|
-
var program = new
|
|
557
|
+
var program = new Command10();
|
|
428
558
|
program.name("genehub").description("GeneHub CLI - AI \u5458\u5DE5\u57FA\u56E0\u7BA1\u7406\u5DE5\u5177").version("0.1.0");
|
|
559
|
+
program.addCommand(authCommand);
|
|
429
560
|
program.addCommand(installCommand);
|
|
430
561
|
program.addCommand(uninstallCommand);
|
|
431
562
|
program.addCommand(searchCommand);
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/commands/config.ts","../src/config.ts","../src/output.ts","../src/commands/init.ts","../src/commands/install.ts","../src/commands/learn.ts","../src/commands/list.ts","../src/commands/publish.ts","../src/commands/search.ts","../src/commands/uninstall.ts"],"sourcesContent":["import { Command } from 'commander';\nimport { configCommand } from './commands/config.js';\nimport { initCommand } from './commands/init.js';\nimport { installCommand } from './commands/install.js';\nimport { learnCommand } from './commands/learn.js';\nimport { listCommand } from './commands/list.js';\nimport { publishCommand } from './commands/publish.js';\nimport { searchCommand } from './commands/search.js';\nimport { uninstallCommand } from './commands/uninstall.js';\n\nconst program = new Command();\n\nprogram.name('genehub').description('GeneHub CLI - AI 员工基因管理工具').version('0.1.0');\n\nprogram.addCommand(installCommand);\nprogram.addCommand(uninstallCommand);\nprogram.addCommand(searchCommand);\nprogram.addCommand(listCommand);\nprogram.addCommand(publishCommand);\nprogram.addCommand(initCommand);\nprogram.addCommand(configCommand);\nprogram.addCommand(learnCommand);\n\nprogram.parse();\n","import { Command } from 'commander';\nimport { loadConfig, saveConfig } from '../config.js';\nimport * as output from '../output.js';\n\nexport const configCommand = new Command('config').description('管理 GeneHub CLI 配置');\n\nconfigCommand\n .command('set <key> <value>')\n .description('设置配置项(registry / token)')\n .action(async (key: string, value: string) => {\n const validKeys = ['registry', 'token'] as const;\n if (!validKeys.includes(key as (typeof validKeys)[number])) {\n output.fail(`无效的配置项: ${key},可选: ${validKeys.join(', ')}`);\n return;\n }\n\n if (key === 'registry') {\n await saveConfig({ registryUrl: value });\n } else if (key === 'token') {\n await saveConfig({ token: value });\n }\n\n output.ok(`${key} = ${key === 'token' ? `${value.slice(0, 8)}***` : value}`);\n });\n\nconfigCommand\n .command('get [key]')\n .description('查看配置')\n .action(async (key?: string) => {\n const config = await loadConfig();\n\n if (key) {\n const map: Record<string, string | undefined> = {\n registry: config.registryUrl,\n token: config.token ? `${config.token.slice(0, 8)}***` : undefined,\n };\n output.info(`${key} = ${map[key] ?? '(未设置)'}`);\n } else {\n output.info(`registry = ${config.registryUrl}`);\n output.info(`token = ${config.token ? `${config.token.slice(0, 8)}***` : '(未设置)'}`);\n }\n });\n","import { mkdir, readFile, writeFile } from 'node:fs/promises';\nimport { homedir } from 'node:os';\nimport { join } from 'node:path';\n\nconst CONFIG_DIR = join(homedir(), '.genehub');\nconst CONFIG_PATH = join(CONFIG_DIR, 'config.json');\n\nexport type CliConfig = {\n registryUrl: string;\n token?: string;\n};\n\nconst DEFAULT_CONFIG: CliConfig = {\n registryUrl: 'https://genehub.nodeskai.com',\n};\n\nexport async function loadConfig(): Promise<CliConfig> {\n try {\n const raw = await readFile(CONFIG_PATH, 'utf-8');\n return { ...DEFAULT_CONFIG, ...JSON.parse(raw) };\n } catch {\n return DEFAULT_CONFIG;\n }\n}\n\nexport async function saveConfig(config: Partial<CliConfig>): Promise<void> {\n const current = await loadConfig();\n const merged = { ...current, ...config };\n await mkdir(CONFIG_DIR, { recursive: true });\n await writeFile(CONFIG_PATH, JSON.stringify(merged, null, 2), 'utf-8');\n}\n","import chalk from 'chalk';\nimport Table from 'cli-table3';\n\nexport function info(msg: string) {\n console.log(chalk.blue('i'), msg);\n}\n\nexport function ok(msg: string) {\n console.log(chalk.green('+'), msg);\n}\n\nexport function warn(msg: string) {\n console.log(chalk.yellow('!'), msg);\n}\n\nexport function fail(msg: string) {\n console.error(chalk.red('x'), msg);\n}\n\nexport function table(headers: string[], rows: string[][]) {\n const t = new Table({\n head: headers.map((h) => chalk.cyan(h)),\n style: { head: [], border: [] },\n });\n for (const row of rows) {\n t.push(row);\n }\n console.log(t.toString());\n}\n","import { mkdir, writeFile } from 'node:fs/promises';\nimport { join, resolve } from 'node:path';\nimport { Command } from 'commander';\nimport { stringify } from 'yaml';\nimport * as output from '../output.js';\n\nconst TEMPLATE = {\n slug: 'my-gene',\n name: '我的基因',\n version: '1.0.0',\n description: '基因功能描述',\n short_description: '一句话描述',\n category: 'development',\n tags: ['ability'],\n author: { type: 'human', name: '' },\n compatibility: [\n { product: 'openclaw', min_version: '0.5.0' },\n { product: 'nanobot', min_version: '0.1.0' },\n ],\n dependencies: [],\n synergies: [],\n skill: {\n name: 'my-gene',\n always: false,\n file: 'SKILL.md',\n },\n rules: [],\n config: {},\n mcp_servers: [],\n learning: {\n force_deep_learn: false,\n objectives: [],\n scenarios: [],\n },\n};\n\nconst SKILL_TEMPLATE = `---\nname: my-gene\ndescription: 一句话描述\nmetadata:\n openclaw:\n always: false\n nanobot:\n always: false\n---\n\n在此编写基因的技能描述...\n`;\n\nexport const initCommand = new Command('init')\n .description('初始化基因模板')\n .argument('[path]', '目标目录', '.')\n .action(async (dirPath: string) => {\n const absPath = resolve(dirPath);\n\n try {\n await mkdir(absPath, { recursive: true });\n\n const yamlPath = join(absPath, 'gene.yaml');\n await writeFile(yamlPath, stringify(TEMPLATE), 'utf-8');\n\n const skillPath = join(absPath, 'SKILL.md');\n await writeFile(skillPath, SKILL_TEMPLATE, 'utf-8');\n\n output.ok(`基因模板已创建:`);\n output.info(` ${yamlPath}`);\n output.info(` ${skillPath}`);\n output.info('编辑这两个文件后,使用 genehub publish 发布');\n } catch (err) {\n output.fail(err instanceof Error ? err.message : String(err));\n process.exit(1);\n }\n });\n","import { homedir } from 'node:os';\nimport { join } from 'node:path';\nimport { detectAdapter, GeneHubClient, getAdapter, LearningEngine } from '@nodeskai/genehub-sdk';\nimport { Command } from 'commander';\nimport ora from 'ora';\nimport { loadConfig } from '../config.js';\nimport * as output from '../output.js';\n\nfunction parseSlugVersion(input: string): { slug: string; version?: string } {\n const atIdx = input.lastIndexOf('@');\n if (atIdx > 0) {\n return { slug: input.slice(0, atIdx), version: input.slice(atIdx + 1) };\n }\n return { slug: input };\n}\n\nexport const installCommand = new Command('install')\n .description('安装基因到当前 Agent 环境')\n .argument('<slug>', '基因标识符(支持 slug@version 格式)')\n .option('-p, --product <product>', '指定目标产品(openclaw / nanobot / generic)')\n .option('-f, --force', '强制覆盖已安装版本', false)\n .option('--target <path>', '指定安装目标路径')\n .option('--learn', '安装后自动触发深度学习', false)\n .action(async (rawSlug: string, opts) => {\n const config = await loadConfig();\n const client = new GeneHubClient({ registryUrl: config.registryUrl, token: config.token });\n\n const { slug, version } = parseSlugVersion(rawSlug);\n const spinner = ora(`获取基因 ${slug}${version ? `@${version}` : ''} 的 manifest...`).start();\n\n try {\n const manifest = await client.getManifest(slug, version);\n spinner.succeed(`获取 ${manifest.name} v${manifest.version}`);\n\n const adapter = opts.product ? getAdapter(opts.product) : await detectAdapter();\n\n output.info(`目标产品: ${adapter.product}`);\n\n if (!opts.force && (await adapter.isInstalled(slug))) {\n const installedVer = await adapter.getInstalledVersion(slug);\n output.warn(`${slug}${installedVer ? ` v${installedVer}` : ''} 已安装,使用 --force 覆盖`);\n return;\n }\n\n const installSpinner = ora('安装中...').start();\n const result = await adapter.install(manifest, {\n force: opts.force,\n targetPath: opts.target,\n });\n installSpinner.succeed('安装完成');\n\n output.ok(`${result.slug}@${result.version} 安装成功`);\n output.info(`文件: ${result.files.join(', ')}`);\n\n if (result.needsRestart) {\n output.warn('需要重启 Agent Host 使基因生效');\n }\n\n if (result.dependencies.length > 0) {\n output.info(`依赖基因: ${result.dependencies.join(', ')}`);\n }\n\n try {\n await client.reportInstall(slug);\n } catch {\n // non-critical\n }\n\n if (opts.learn) {\n const workspaceDir =\n adapter.product === 'openclaw'\n ? join(homedir(), '.openclaw', 'workspace')\n : adapter.product === 'nanobot'\n ? join(homedir(), '.nanobot', 'workspace')\n : join(process.cwd(), '.genehub');\n\n const engine = new LearningEngine({ workspaceDir, adapter });\n const learnSpinner = ora('生成学习任务...').start();\n await engine.createLearningTask(manifest);\n learnSpinner.succeed('学习任务已创建,Agent 将在下次对话中处理');\n }\n } catch (err) {\n spinner.fail('安装失败');\n output.fail(err instanceof Error ? err.message : String(err));\n process.exit(1);\n }\n });\n","import { homedir } from 'node:os';\nimport { join } from 'node:path';\nimport { detectAdapter, GeneHubClient, getAdapter, LearningEngine } from '@nodeskai/genehub-sdk';\nimport { Command } from 'commander';\nimport ora from 'ora';\nimport { loadConfig } from '../config.js';\nimport * as output from '../output.js';\n\nfunction getWorkspaceDir(product: string): string {\n switch (product) {\n case 'openclaw':\n return join(homedir(), '.openclaw', 'workspace');\n case 'nanobot':\n return join(homedir(), '.nanobot', 'workspace');\n default:\n return join(process.cwd(), '.genehub');\n }\n}\n\nexport const learnCommand = new Command('learn')\n .description('触发基因深度学习(L2)')\n .argument('<slug>', '基因标识符')\n .option('-p, --product <product>', '指定目标产品')\n .option('--check', '检查学习结果并应用')\n .action(async (slug: string, opts) => {\n const config = await loadConfig();\n const client = new GeneHubClient({ registryUrl: config.registryUrl, token: config.token });\n\n const adapter = opts.product ? getAdapter(opts.product) : await detectAdapter();\n\n const workspaceDir = getWorkspaceDir(adapter.product);\n const engine = new LearningEngine({ workspaceDir, adapter });\n\n if (opts.check) {\n const spinner = ora('检查学习结果...').start();\n const result = await engine.checkResult(slug);\n\n if (!result) {\n spinner.fail('未找到学习结果');\n output.info('Agent 还未完成该基因的学习任务');\n\n const pending = await engine.listPendingTasks();\n if (pending.length > 0) {\n output.info(`待完成的学习任务: ${pending.join(', ')}`);\n }\n return;\n }\n\n spinner.succeed(`学习结果: ${result.decision}`);\n\n if (result.self_eval !== undefined) {\n output.info(`自评分: ${result.self_eval}`);\n }\n if (result.reason) {\n output.info(`理由: ${result.reason}`);\n }\n\n if (result.decision === 'learned' && result.content) {\n const skillsDir = join(workspaceDir, 'skills');\n const applied = await engine.applyResult(slug, skillsDir);\n if (applied) {\n output.ok('已将个性化版本应用到技能目录');\n }\n }\n\n return;\n }\n\n const spinner = ora(`获取 ${slug} 的 manifest...`).start();\n\n try {\n const manifest = await client.getManifest(slug);\n spinner.succeed(`获取 ${manifest.name} v${manifest.version}`);\n\n if (!manifest.learning?.objectives?.length && !manifest.learning?.scenarios?.length) {\n output.warn('该基因没有定义学习目标或练习场景,将创建基础学习任务');\n }\n\n const learnSpinner = ora('生成学习任务...').start();\n const task = await engine.createLearningTask(manifest);\n learnSpinner.succeed('学习任务已创建');\n\n output.ok(`任务文件: ${join(workspaceDir, 'learning-tasks', `${slug}.md`)}`);\n output.info(`结果路径: ${task.callback_path}`);\n output.info('');\n output.info('下一步:');\n output.info(' 1. Agent 在下次对话中会自动发现并处理学习任务');\n output.info(` 2. 学习完成后运行: genehub learn --check ${slug}`);\n } catch (err) {\n spinner.fail('学习任务创建失败');\n output.fail(err instanceof Error ? err.message : String(err));\n process.exit(1);\n }\n });\n","import { detectAdapter, getAdapter } from '@nodeskai/genehub-sdk';\nimport { Command } from 'commander';\nimport * as output from '../output.js';\n\nexport const listCommand = new Command('list')\n .description('列出当前环境已安装的基因')\n .option('-p, --product <product>', '指定目标产品')\n .option('--json', 'JSON 格式输出', false)\n .action(async (opts) => {\n try {\n const adapter = opts.product ? getAdapter(opts.product) : await detectAdapter();\n\n const genes = await adapter.list();\n\n if (opts.json) {\n console.log(JSON.stringify(genes, null, 2));\n return;\n }\n\n if (genes.length === 0) {\n output.info(`[${adapter.product}] 没有已安装的基因`);\n return;\n }\n\n output.info(`[${adapter.product}] 已安装 ${genes.length} 个基因:\\n`);\n\n for (const gene of genes) {\n const date = new Date(gene.installedAt).toLocaleDateString('zh-CN');\n console.log(` ${gene.slug.padEnd(24)} v${gene.version.padEnd(10)} ${date}`);\n }\n } catch (err) {\n output.fail(err instanceof Error ? err.message : String(err));\n process.exit(1);\n }\n });\n","import { readFile } from 'node:fs/promises';\nimport { join, resolve } from 'node:path';\nimport { GeneHubClient } from '@nodeskai/genehub-sdk';\nimport { GeneManifestSchema } from '@nodeskai/genehub-types';\nimport { Command } from 'commander';\nimport ora from 'ora';\nimport { parse } from 'yaml';\nimport { loadConfig } from '../config.js';\nimport * as output from '../output.js';\n\nexport const publishCommand = new Command('publish')\n .description('发布基因到 GeneHub Registry')\n .argument('<path>', '基因目录路径(包含 gene.yaml)')\n .action(async (dirPath: string) => {\n const config = await loadConfig();\n\n if (!config.token) {\n output.fail('未配置认证 token,请先运行 genehub config --token <token>');\n process.exit(1);\n }\n\n const client = new GeneHubClient({ registryUrl: config.registryUrl, token: config.token });\n const absPath = resolve(dirPath);\n\n try {\n const yamlPath = join(absPath, 'gene.yaml');\n const raw = await readFile(yamlPath, 'utf-8');\n const parsed = parse(raw);\n\n const skillMdPath = join(absPath, 'SKILL.md');\n if (parsed.skill?.file && !parsed.skill.content) {\n try {\n parsed.skill.content = await readFile(join(absPath, parsed.skill.file), 'utf-8');\n } catch {\n parsed.skill.content = await readFile(skillMdPath, 'utf-8');\n }\n }\n\n const validation = GeneManifestSchema.safeParse(parsed);\n if (!validation.success) {\n output.fail('Manifest 校验失败:');\n for (const issue of validation.error.issues) {\n output.fail(` ${issue.path.join('.')}: ${issue.message}`);\n }\n process.exit(1);\n }\n\n const spinner = ora(`发布 ${validation.data.slug}@${validation.data.version}...`).start();\n const gene = await client.publishGene(validation.data);\n spinner.succeed('发布成功');\n\n output.ok(`${gene.slug}@${gene.version} 已发布到 GeneHub Registry`);\n } catch (err) {\n output.fail(err instanceof Error ? err.message : String(err));\n process.exit(1);\n }\n });\n","import { GeneHubClient } from '@nodeskai/genehub-sdk';\nimport { Command } from 'commander';\nimport { loadConfig } from '../config.js';\nimport * as output from '../output.js';\n\nexport const searchCommand = new Command('search')\n .description('搜索基因库')\n .argument('[keyword]', '搜索关键词')\n .option('-c, --category <category>', '按分类过滤')\n .option('-t, --tags <tags>', '按标签过滤(逗号分隔)')\n .option('--compat <product>', '按兼容产品过滤')\n .option('-s, --sort <sort>', '排序方式(newest / popular / rating)', 'newest')\n .option('--page <page>', '页码', '1')\n .option('--json', 'JSON 格式输出', false)\n .action(async (keyword: string | undefined, opts) => {\n const config = await loadConfig();\n const client = new GeneHubClient({ registryUrl: config.registryUrl, token: config.token });\n\n try {\n const result = await client.searchGenes({\n q: keyword,\n category: opts.category,\n tags: opts.tags?.split(','),\n compatibility: opts.compat,\n sort: opts.sort,\n page: Number(opts.page),\n });\n\n if (opts.json) {\n console.log(JSON.stringify(result, null, 2));\n return;\n }\n\n if (result.items.length === 0) {\n output.info('未找到匹配的基因');\n return;\n }\n\n output.table(\n ['slug', '名称', '版本', '分类', '兼容', '安装数'],\n result.items.map((g) => [\n g.slug,\n g.name,\n g.version,\n g.category,\n (g.compatibility as string[]).join(', '),\n String(g.install_count),\n ]),\n );\n\n output.info(`共 ${result.total} 条结果,第 ${result.page}/${result.total_pages} 页`);\n } catch (err) {\n output.fail(err instanceof Error ? err.message : String(err));\n process.exit(1);\n }\n });\n","import { detectAdapter, getAdapter } from '@nodeskai/genehub-sdk';\nimport { Command } from 'commander';\nimport ora from 'ora';\nimport * as output from '../output.js';\n\nexport const uninstallCommand = new Command('uninstall')\n .description('从当前 Agent 环境卸载基因')\n .argument('<slug>', '基因标识符')\n .option('-p, --product <product>', '指定目标产品(openclaw / nanobot / generic)')\n .action(async (slug: string, opts) => {\n const adapter = opts.product ? getAdapter(opts.product) : await detectAdapter();\n\n output.info(`目标产品: ${adapter.product}`);\n\n if (!(await adapter.isInstalled(slug))) {\n output.warn(`${slug} 未安装`);\n return;\n }\n\n const spinner = ora('卸载中...').start();\n\n try {\n const result = await adapter.uninstall(slug);\n spinner.succeed('卸载完成');\n\n output.ok(`${result.slug} 已卸载`);\n output.info(`清理文件: ${result.files.join(', ')}`);\n\n if (result.needsRestart) {\n output.warn('需要重启 Agent Host 使变更生效');\n }\n } catch (err) {\n spinner.fail('卸载失败');\n output.fail(err instanceof Error ? err.message : String(err));\n process.exit(1);\n }\n });\n"],"mappings":"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","names":["Command","mkdir","writeFile","join","Command","Command","mkdir","join","writeFile","homedir","join","Command","Command","join","homedir","homedir","join","detectAdapter","GeneHubClient","getAdapter","LearningEngine","Command","ora","join","homedir","Command","GeneHubClient","getAdapter","detectAdapter","LearningEngine","spinner","ora","detectAdapter","getAdapter","Command","Command","getAdapter","detectAdapter","readFile","join","resolve","GeneHubClient","Command","ora","Command","GeneHubClient","resolve","join","readFile","ora","GeneHubClient","Command","Command","GeneHubClient","detectAdapter","getAdapter","Command","ora","Command","getAdapter","detectAdapter","ora","Command"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/commands/auth.ts","../src/config.ts","../src/output.ts","../src/commands/config.ts","../src/commands/init.ts","../src/commands/install.ts","../src/commands/learn.ts","../src/commands/list.ts","../src/commands/publish.ts","../src/commands/search.ts","../src/commands/uninstall.ts"],"sourcesContent":["import { Command } from 'commander';\nimport { authCommand } from './commands/auth.js';\nimport { configCommand } from './commands/config.js';\nimport { initCommand } from './commands/init.js';\nimport { installCommand } from './commands/install.js';\nimport { learnCommand } from './commands/learn.js';\nimport { listCommand } from './commands/list.js';\nimport { publishCommand } from './commands/publish.js';\nimport { searchCommand } from './commands/search.js';\nimport { uninstallCommand } from './commands/uninstall.js';\n\nconst program = new Command();\n\nprogram.name('genehub').description('GeneHub CLI - AI 员工基因管理工具').version('0.1.0');\n\nprogram.addCommand(authCommand);\nprogram.addCommand(installCommand);\nprogram.addCommand(uninstallCommand);\nprogram.addCommand(searchCommand);\nprogram.addCommand(listCommand);\nprogram.addCommand(publishCommand);\nprogram.addCommand(initCommand);\nprogram.addCommand(configCommand);\nprogram.addCommand(learnCommand);\n\nprogram.parse();\n","import { createServer } from 'node:http';\nimport { Command } from 'commander';\nimport { loadConfig, saveConfig } from '../config.js';\nimport * as output from '../output.js';\n\nexport const authCommand = new Command('auth').description('认证管理');\n\nauthCommand\n .command('login')\n .description('通过 GitHub OAuth 登录并自动创建 API Key')\n .action(async () => {\n const config = await loadConfig();\n const registryUrl = config.registryUrl.replace(/\\/$/, '');\n\n const port = await findAvailablePort(9876);\n const callbackUrl = `http://localhost:${port}/callback`;\n\n const tokenPromise = waitForCallback(port);\n\n const authUrl = `${registryUrl}/auth/github?cli_callback=${encodeURIComponent(callbackUrl)}`;\n output.info(`Opening browser for GitHub login...`);\n output.info(` ${authUrl}`);\n\n const open = await import('open').catch(() => null);\n if (open) {\n await open.default(authUrl);\n } else {\n output.warn('Cannot open browser automatically. Please open the URL above manually.');\n }\n\n try {\n const { token, login } = await tokenPromise;\n await saveConfig({ token });\n output.ok(`Logged in as @${login}`);\n output.ok(`Token saved to config (${token.slice(0, 12)}****)`);\n } catch (err) {\n output.fail(err instanceof Error ? err.message : 'Login failed');\n process.exit(1);\n }\n });\n\nauthCommand\n .command('status')\n .description('查看当前登录状态')\n .action(async () => {\n const config = await loadConfig();\n\n if (!config.token) {\n output.info('Not logged in');\n output.info(' Run: genehub auth login');\n return;\n }\n\n output.ok(`Token: ${config.token.slice(0, 12)}****`);\n output.info(`Registry: ${config.registryUrl}`);\n });\n\nauthCommand\n .command('logout')\n .description('退出登录(清除本地 token)')\n .action(async () => {\n await saveConfig({ token: undefined });\n output.ok('Logged out. Token removed.');\n });\n\nfunction findAvailablePort(preferred: number): Promise<number> {\n return new Promise((resolve, reject) => {\n const server = createServer();\n server.listen(preferred, () => {\n server.close(() => resolve(preferred));\n });\n server.on('error', () => {\n const fallback = createServer();\n fallback.listen(0, () => {\n const addr = fallback.address();\n const port = typeof addr === 'object' && addr ? addr.port : 0;\n fallback.close(() => resolve(port));\n });\n fallback.on('error', reject);\n });\n });\n}\n\nfunction waitForCallback(port: number): Promise<{ token: string; login: string }> {\n return new Promise((resolve, reject) => {\n const timeout = setTimeout(() => {\n server.close();\n reject(new Error('Login timeout (60s)'));\n }, 60_000);\n\n const server = createServer((req, res) => {\n if (!req.url?.startsWith('/callback')) {\n res.writeHead(404);\n res.end();\n return;\n }\n\n const url = new URL(req.url, `http://localhost:${port}`);\n const token = url.searchParams.get('token');\n const login = url.searchParams.get('login');\n\n if (!token) {\n res.writeHead(400, { 'Content-Type': 'text/html; charset=utf-8' });\n res.end('<h2>Login failed</h2><p>No token received.</p>');\n return;\n }\n\n res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });\n res.end(`<h2>Login successful</h2><p>@${login ?? 'unknown'} - you can close this tab.</p>`);\n\n clearTimeout(timeout);\n server.close();\n resolve({ token, login: login ?? '' });\n });\n\n server.listen(port);\n });\n}\n","import { mkdir, readFile, writeFile } from 'node:fs/promises';\nimport { homedir } from 'node:os';\nimport { join } from 'node:path';\n\nconst CONFIG_DIR = join(homedir(), '.genehub');\nconst CONFIG_PATH = join(CONFIG_DIR, 'config.json');\n\nexport type CliConfig = {\n registryUrl: string;\n token?: string;\n};\n\nconst DEFAULT_CONFIG: CliConfig = {\n registryUrl: 'https://genehub.nodeskai.com',\n};\n\n/**\n * Priority: env vars > config file > defaults\n *\n * - GENEHUB_REGISTRY_URL / GENEHUB_REGISTRY\n * - GENEHUB_TOKEN\n */\nexport async function loadConfig(): Promise<CliConfig> {\n let fileConfig: Partial<CliConfig> = {};\n try {\n const raw = await readFile(CONFIG_PATH, 'utf-8');\n fileConfig = JSON.parse(raw);\n } catch {\n // no config file, use defaults\n }\n\n const merged = { ...DEFAULT_CONFIG, ...fileConfig };\n\n const envUrl = process.env.GENEHUB_REGISTRY_URL ?? process.env.GENEHUB_REGISTRY;\n if (envUrl) {\n merged.registryUrl = envUrl;\n }\n\n const envToken = process.env.GENEHUB_TOKEN;\n if (envToken) {\n merged.token = envToken;\n }\n\n return merged;\n}\n\nexport function getConfigSource(key: 'registry' | 'token'): 'env' | 'file' | 'default' {\n if (key === 'registry') {\n if (process.env.GENEHUB_REGISTRY_URL || process.env.GENEHUB_REGISTRY) return 'env';\n }\n if (key === 'token') {\n if (process.env.GENEHUB_TOKEN) return 'env';\n }\n return 'file';\n}\n\nexport async function saveConfig(config: Partial<CliConfig>): Promise<void> {\n const current = await loadConfig();\n const merged = { ...current, ...config };\n await mkdir(CONFIG_DIR, { recursive: true });\n await writeFile(CONFIG_PATH, JSON.stringify(merged, null, 2), 'utf-8');\n}\n","import chalk from 'chalk';\nimport Table from 'cli-table3';\n\nexport function info(msg: string) {\n console.log(chalk.blue('i'), msg);\n}\n\nexport function ok(msg: string) {\n console.log(chalk.green('+'), msg);\n}\n\nexport function warn(msg: string) {\n console.log(chalk.yellow('!'), msg);\n}\n\nexport function fail(msg: string) {\n console.error(chalk.red('x'), msg);\n}\n\nexport function table(headers: string[], rows: string[][]) {\n const t = new Table({\n head: headers.map((h) => chalk.cyan(h)),\n style: { head: [], border: [] },\n });\n for (const row of rows) {\n t.push(row);\n }\n console.log(t.toString());\n}\n","import { Command } from 'commander';\nimport { getConfigSource, loadConfig, saveConfig } from '../config.js';\nimport * as output from '../output.js';\n\nexport const configCommand = new Command('config').description('管理 GeneHub CLI 配置');\n\nfunction sourceLabel(source: 'env' | 'file' | 'default'): string {\n if (source === 'env') return ' [env]';\n if (source === 'default') return ' [default]';\n return '';\n}\n\nconfigCommand\n .command('set <key> <value>')\n .description('设置配置项(registry / token)')\n .action(async (key: string, value: string) => {\n const validKeys = ['registry', 'token'] as const;\n if (!validKeys.includes(key as (typeof validKeys)[number])) {\n output.fail(`无效的配置项: ${key},可选: ${validKeys.join(', ')}`);\n return;\n }\n\n if (key === 'registry') {\n await saveConfig({ registryUrl: value });\n } else if (key === 'token') {\n await saveConfig({ token: value });\n }\n\n output.ok(`${key} = ${key === 'token' ? `${value.slice(0, 8)}***` : value}`);\n });\n\nconfigCommand\n .command('get [key]')\n .description('查看配置(支持 GENEHUB_REGISTRY_URL / GENEHUB_TOKEN 环境变量覆盖)')\n .action(async (key?: string) => {\n const config = await loadConfig();\n\n if (key) {\n const map: Record<string, string | undefined> = {\n registry: config.registryUrl,\n token: config.token ? `${config.token.slice(0, 8)}***` : undefined,\n };\n const src = sourceLabel(getConfigSource(key as 'registry' | 'token'));\n output.info(`${key} = ${map[key] ?? '(未设置)'}${src}`);\n } else {\n const regSrc = sourceLabel(getConfigSource('registry'));\n const tokSrc = sourceLabel(getConfigSource('token'));\n output.info(`registry = ${config.registryUrl}${regSrc}`);\n output.info(\n `token = ${config.token ? `${config.token.slice(0, 8)}***` : '(未设置)'}${tokSrc}`,\n );\n }\n });\n","import { mkdir, writeFile } from 'node:fs/promises';\nimport { join, resolve } from 'node:path';\nimport { Command } from 'commander';\nimport { stringify } from 'yaml';\nimport * as output from '../output.js';\n\nconst TEMPLATE = {\n slug: 'my-gene',\n name: '我的基因',\n version: '1.0.0',\n description: '基因功能描述',\n short_description: '一句话描述',\n category: 'development',\n tags: ['ability'],\n author: { type: 'human', name: '' },\n compatibility: [\n { product: 'openclaw', min_version: '0.5.0' },\n { product: 'nanobot', min_version: '0.1.0' },\n ],\n dependencies: [],\n synergies: [],\n skill: {\n name: 'my-gene',\n always: false,\n file: 'SKILL.md',\n },\n rules: [],\n config: {},\n mcp_servers: [],\n learning: {\n force_deep_learn: false,\n objectives: [],\n scenarios: [],\n },\n};\n\nconst SKILL_TEMPLATE = `---\nname: my-gene\ndescription: 一句话描述\nmetadata:\n openclaw:\n always: false\n nanobot:\n always: false\n---\n\n在此编写基因的技能描述...\n`;\n\nexport const initCommand = new Command('init')\n .description('初始化基因模板')\n .argument('[path]', '目标目录', '.')\n .action(async (dirPath: string) => {\n const absPath = resolve(dirPath);\n\n try {\n await mkdir(absPath, { recursive: true });\n\n const yamlPath = join(absPath, 'gene.yaml');\n await writeFile(yamlPath, stringify(TEMPLATE), 'utf-8');\n\n const skillPath = join(absPath, 'SKILL.md');\n await writeFile(skillPath, SKILL_TEMPLATE, 'utf-8');\n\n output.ok(`基因模板已创建:`);\n output.info(` ${yamlPath}`);\n output.info(` ${skillPath}`);\n output.info('编辑这两个文件后,使用 genehub publish 发布');\n } catch (err) {\n output.fail(err instanceof Error ? err.message : String(err));\n process.exit(1);\n }\n });\n","import { homedir } from 'node:os';\nimport { join } from 'node:path';\nimport { detectAdapter, GeneHubClient, getAdapter, LearningEngine } from '@nodeskai/genehub-sdk';\nimport { Command } from 'commander';\nimport ora from 'ora';\nimport { loadConfig } from '../config.js';\nimport * as output from '../output.js';\n\nfunction parseSlugVersion(input: string): { slug: string; version?: string } {\n const atIdx = input.lastIndexOf('@');\n if (atIdx > 0) {\n return { slug: input.slice(0, atIdx), version: input.slice(atIdx + 1) };\n }\n return { slug: input };\n}\n\nexport const installCommand = new Command('install')\n .description('安装基因到当前 Agent 环境')\n .argument('<slug>', '基因标识符(支持 slug@version 格式)')\n .option('-p, --product <product>', '指定目标产品(openclaw / nanobot / generic)')\n .option('-f, --force', '强制覆盖已安装版本', false)\n .option('--target <path>', '指定安装目标路径')\n .option('--learn', '安装后自动触发深度学习', false)\n .action(async (rawSlug: string, opts) => {\n const config = await loadConfig();\n const client = new GeneHubClient({ registryUrl: config.registryUrl, token: config.token });\n\n const { slug, version } = parseSlugVersion(rawSlug);\n const spinner = ora(`获取基因 ${slug}${version ? `@${version}` : ''} 的 manifest...`).start();\n\n try {\n const manifest = await client.getManifest(slug, version);\n spinner.succeed(`获取 ${manifest.name} v${manifest.version}`);\n\n const adapter = opts.product ? getAdapter(opts.product) : await detectAdapter();\n\n output.info(`目标产品: ${adapter.product}`);\n\n if (!opts.force && (await adapter.isInstalled(slug))) {\n const installedVer = await adapter.getInstalledVersion(slug);\n output.warn(`${slug}${installedVer ? ` v${installedVer}` : ''} 已安装,使用 --force 覆盖`);\n return;\n }\n\n const installSpinner = ora('安装中...').start();\n const result = await adapter.install(manifest, {\n force: opts.force,\n targetPath: opts.target,\n });\n installSpinner.succeed('安装完成');\n\n output.ok(`${result.slug}@${result.version} 安装成功`);\n output.info(`文件: ${result.files.join(', ')}`);\n\n if (result.needsRestart) {\n output.warn('需要重启 Agent Host 使基因生效');\n }\n\n if (result.dependencies.length > 0) {\n output.info(`依赖基因: ${result.dependencies.join(', ')}`);\n }\n\n try {\n await client.reportInstall(slug);\n } catch {\n // non-critical\n }\n\n if (opts.learn) {\n const workspaceDir =\n adapter.product === 'openclaw'\n ? join(homedir(), '.openclaw', 'workspace')\n : adapter.product === 'nanobot'\n ? join(homedir(), '.nanobot', 'workspace')\n : join(process.cwd(), '.genehub');\n\n const engine = new LearningEngine({ workspaceDir, adapter });\n const learnSpinner = ora('生成学习任务...').start();\n await engine.createLearningTask(manifest);\n learnSpinner.succeed('学习任务已创建,Agent 将在下次对话中处理');\n }\n } catch (err) {\n spinner.fail('安装失败');\n output.fail(err instanceof Error ? err.message : String(err));\n process.exit(1);\n }\n });\n","import { homedir } from 'node:os';\nimport { join } from 'node:path';\nimport { detectAdapter, GeneHubClient, getAdapter, LearningEngine } from '@nodeskai/genehub-sdk';\nimport { Command } from 'commander';\nimport ora from 'ora';\nimport { loadConfig } from '../config.js';\nimport * as output from '../output.js';\n\nfunction getWorkspaceDir(product: string): string {\n switch (product) {\n case 'openclaw':\n return join(homedir(), '.openclaw', 'workspace');\n case 'nanobot':\n return join(homedir(), '.nanobot', 'workspace');\n default:\n return join(process.cwd(), '.genehub');\n }\n}\n\nexport const learnCommand = new Command('learn')\n .description('触发基因深度学习(L2)')\n .argument('<slug>', '基因标识符')\n .option('-p, --product <product>', '指定目标产品')\n .option('--check', '检查学习结果并应用')\n .action(async (slug: string, opts) => {\n const config = await loadConfig();\n const client = new GeneHubClient({ registryUrl: config.registryUrl, token: config.token });\n\n const adapter = opts.product ? getAdapter(opts.product) : await detectAdapter();\n\n const workspaceDir = getWorkspaceDir(adapter.product);\n const engine = new LearningEngine({ workspaceDir, adapter });\n\n if (opts.check) {\n const spinner = ora('检查学习结果...').start();\n const result = await engine.checkResult(slug);\n\n if (!result) {\n spinner.fail('未找到学习结果');\n output.info('Agent 还未完成该基因的学习任务');\n\n const pending = await engine.listPendingTasks();\n if (pending.length > 0) {\n output.info(`待完成的学习任务: ${pending.join(', ')}`);\n }\n return;\n }\n\n spinner.succeed(`学习结果: ${result.decision}`);\n\n if (result.self_eval !== undefined) {\n output.info(`自评分: ${result.self_eval}`);\n }\n if (result.reason) {\n output.info(`理由: ${result.reason}`);\n }\n\n if (result.decision === 'learned' && result.content) {\n const skillsDir = join(workspaceDir, 'skills');\n const applied = await engine.applyResult(slug, skillsDir);\n if (applied) {\n output.ok('已将个性化版本应用到技能目录');\n }\n }\n\n return;\n }\n\n const spinner = ora(`获取 ${slug} 的 manifest...`).start();\n\n try {\n const manifest = await client.getManifest(slug);\n spinner.succeed(`获取 ${manifest.name} v${manifest.version}`);\n\n if (!manifest.learning?.objectives?.length && !manifest.learning?.scenarios?.length) {\n output.warn('该基因没有定义学习目标或练习场景,将创建基础学习任务');\n }\n\n const learnSpinner = ora('生成学习任务...').start();\n const task = await engine.createLearningTask(manifest);\n learnSpinner.succeed('学习任务已创建');\n\n output.ok(`任务文件: ${join(workspaceDir, 'learning-tasks', `${slug}.md`)}`);\n output.info(`结果路径: ${task.callback_path}`);\n output.info('');\n output.info('下一步:');\n output.info(' 1. Agent 在下次对话中会自动发现并处理学习任务');\n output.info(` 2. 学习完成后运行: genehub learn --check ${slug}`);\n } catch (err) {\n spinner.fail('学习任务创建失败');\n output.fail(err instanceof Error ? err.message : String(err));\n process.exit(1);\n }\n });\n","import { detectAdapter, getAdapter } from '@nodeskai/genehub-sdk';\nimport { Command } from 'commander';\nimport * as output from '../output.js';\n\nexport const listCommand = new Command('list')\n .description('列出当前环境已安装的基因')\n .option('-p, --product <product>', '指定目标产品')\n .option('--json', 'JSON 格式输出', false)\n .action(async (opts) => {\n try {\n const adapter = opts.product ? getAdapter(opts.product) : await detectAdapter();\n\n const genes = await adapter.list();\n\n if (opts.json) {\n console.log(JSON.stringify(genes, null, 2));\n return;\n }\n\n if (genes.length === 0) {\n output.info(`[${adapter.product}] 没有已安装的基因`);\n return;\n }\n\n output.info(`[${adapter.product}] 已安装 ${genes.length} 个基因:\\n`);\n\n for (const gene of genes) {\n const date = new Date(gene.installedAt).toLocaleDateString('zh-CN');\n console.log(` ${gene.slug.padEnd(24)} v${gene.version.padEnd(10)} ${date}`);\n }\n } catch (err) {\n output.fail(err instanceof Error ? err.message : String(err));\n process.exit(1);\n }\n });\n","import { readFile } from 'node:fs/promises';\nimport { join, resolve } from 'node:path';\nimport { GeneHubClient } from '@nodeskai/genehub-sdk';\nimport type { Gene } from '@nodeskai/genehub-types';\nimport { GeneManifestSchema } from '@nodeskai/genehub-types';\nimport { Command } from 'commander';\nimport ora from 'ora';\nimport { parse } from 'yaml';\nimport { loadConfig } from '../config.js';\nimport * as output from '../output.js';\n\nexport const publishCommand = new Command('publish')\n .description('发布基因到 GeneHub Registry')\n .argument('<path>', '基因目录路径(包含 gene.yaml)')\n .action(async (dirPath: string) => {\n const config = await loadConfig();\n\n if (!config.token) {\n output.fail('未配置认证 token');\n output.info(' 方式 1: genehub config set token <token>');\n output.info(' 方式 2: export GENEHUB_TOKEN=<token>');\n process.exit(1);\n }\n\n const client = new GeneHubClient({ registryUrl: config.registryUrl, token: config.token });\n const absPath = resolve(dirPath);\n\n try {\n const yamlPath = join(absPath, 'gene.yaml');\n const raw = await readFile(yamlPath, 'utf-8');\n const parsed = parse(raw);\n\n const skillMdPath = join(absPath, 'SKILL.md');\n if (parsed.skill?.file && !parsed.skill.content) {\n try {\n parsed.skill.content = await readFile(join(absPath, parsed.skill.file), 'utf-8');\n } catch {\n parsed.skill.content = await readFile(skillMdPath, 'utf-8');\n }\n }\n\n const validation = GeneManifestSchema.safeParse(parsed);\n if (!validation.success) {\n output.fail('Manifest 校验失败:');\n for (const issue of validation.error.issues) {\n output.fail(` ${issue.path.join('.')}: ${issue.message}`);\n }\n process.exit(1);\n }\n\n const { slug, version } = validation.data;\n const spinner = ora(`发布 ${slug}@${version}...`).start();\n\n let gene: Gene;\n try {\n gene = await client.publishGene(validation.data);\n } catch (err) {\n const isSlugExists = err instanceof Error && err.message.includes('gene_slug_exists');\n if (!isSlugExists) throw err;\n\n spinner.text = `基因 ${slug} 已存在,发布新版本 ${version}...`;\n gene = await client.publishVersion(slug, validation.data);\n }\n\n spinner.succeed('发布成功');\n output.ok(`${gene.slug}@${gene.version} 已发布到 GeneHub Registry`);\n } catch (err) {\n output.fail(err instanceof Error ? err.message : String(err));\n process.exit(1);\n }\n });\n","import { GeneHubClient } from '@nodeskai/genehub-sdk';\nimport { Command } from 'commander';\nimport { loadConfig } from '../config.js';\nimport * as output from '../output.js';\n\nexport const searchCommand = new Command('search')\n .description('搜索基因库')\n .argument('[keyword]', '搜索关键词')\n .option('-c, --category <category>', '按分类过滤')\n .option('-t, --tags <tags>', '按标签过滤(逗号分隔)')\n .option('--compat <product>', '按兼容产品过滤')\n .option('-s, --sort <sort>', '排序方式(newest / popular / rating)', 'newest')\n .option('--page <page>', '页码', '1')\n .option('--json', 'JSON 格式输出', false)\n .action(async (keyword: string | undefined, opts) => {\n const config = await loadConfig();\n const client = new GeneHubClient({ registryUrl: config.registryUrl, token: config.token });\n\n try {\n const result = await client.searchGenes({\n q: keyword,\n category: opts.category,\n tags: opts.tags?.split(','),\n compatibility: opts.compat,\n sort: opts.sort,\n page: Number(opts.page),\n });\n\n if (opts.json) {\n console.log(JSON.stringify(result, null, 2));\n return;\n }\n\n if (result.items.length === 0) {\n output.info('未找到匹配的基因');\n return;\n }\n\n output.table(\n ['slug', '名称', '版本', '分类', '兼容', '安装数'],\n result.items.map((g) => [\n g.slug,\n g.name,\n g.version,\n g.category,\n (g.compatibility as string[]).join(', '),\n String(g.install_count),\n ]),\n );\n\n output.info(`共 ${result.total} 条结果,第 ${result.page}/${result.total_pages} 页`);\n } catch (err) {\n output.fail(err instanceof Error ? err.message : String(err));\n process.exit(1);\n }\n });\n","import { detectAdapter, getAdapter } from '@nodeskai/genehub-sdk';\nimport { Command } from 'commander';\nimport ora from 'ora';\nimport * as output from '../output.js';\n\nexport const uninstallCommand = new Command('uninstall')\n .description('从当前 Agent 环境卸载基因')\n .argument('<slug>', '基因标识符')\n .option('-p, --product <product>', '指定目标产品(openclaw / nanobot / generic)')\n .action(async (slug: string, opts) => {\n const adapter = opts.product ? getAdapter(opts.product) : await detectAdapter();\n\n output.info(`目标产品: ${adapter.product}`);\n\n if (!(await adapter.isInstalled(slug))) {\n output.warn(`${slug} 未安装`);\n return;\n }\n\n const spinner = ora('卸载中...').start();\n\n try {\n const result = await adapter.uninstall(slug);\n spinner.succeed('卸载完成');\n\n output.ok(`${result.slug} 已卸载`);\n output.info(`清理文件: ${result.files.join(', ')}`);\n\n if (result.needsRestart) {\n output.warn('需要重启 Agent Host 使变更生效');\n }\n } catch (err) {\n spinner.fail('卸载失败');\n output.fail(err instanceof Error ? err.message : String(err));\n process.exit(1);\n }\n });\n"],"mappings":"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","names":["Command","resolve","Command","Command","mkdir","writeFile","join","Command","Command","mkdir","join","writeFile","homedir","join","Command","Command","join","homedir","homedir","join","detectAdapter","GeneHubClient","getAdapter","LearningEngine","Command","ora","join","homedir","Command","GeneHubClient","getAdapter","detectAdapter","LearningEngine","spinner","ora","detectAdapter","getAdapter","Command","Command","getAdapter","detectAdapter","readFile","join","resolve","GeneHubClient","Command","ora","Command","GeneHubClient","resolve","join","readFile","ora","GeneHubClient","Command","Command","GeneHubClient","detectAdapter","getAdapter","Command","ora","Command","getAdapter","detectAdapter","ora","Command"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nodeskai/genehub",
|
|
3
|
-
"version": "2026.3.
|
|
3
|
+
"version": "2026.3.3",
|
|
4
4
|
"description": "GeneHub CLI - AI 员工基因管理命令行工具",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -9,21 +9,14 @@
|
|
|
9
9
|
"files": [
|
|
10
10
|
"dist"
|
|
11
11
|
],
|
|
12
|
-
"scripts": {
|
|
13
|
-
"dev": "tsx src/index.ts",
|
|
14
|
-
"build": "tsup",
|
|
15
|
-
"prepublishOnly": "pnpm build",
|
|
16
|
-
"test": "vitest run",
|
|
17
|
-
"test:watch": "vitest"
|
|
18
|
-
},
|
|
19
12
|
"dependencies": {
|
|
20
|
-
"@nodeskai/genehub-types": "workspace:*",
|
|
21
|
-
"@nodeskai/genehub-sdk": "workspace:*",
|
|
22
13
|
"commander": "^13.1",
|
|
23
14
|
"chalk": "^5.4",
|
|
24
15
|
"cli-table3": "^0.6",
|
|
25
16
|
"ora": "^8.1",
|
|
26
|
-
"yaml": "^2.7"
|
|
17
|
+
"yaml": "^2.7",
|
|
18
|
+
"@nodeskai/genehub-sdk": "2026.3.3",
|
|
19
|
+
"@nodeskai/genehub-types": "2026.3.3"
|
|
27
20
|
},
|
|
28
21
|
"devDependencies": {
|
|
29
22
|
"tsup": "^8.3",
|
|
@@ -46,5 +39,11 @@
|
|
|
46
39
|
"skill",
|
|
47
40
|
"cli"
|
|
48
41
|
],
|
|
49
|
-
"license": "MIT"
|
|
50
|
-
|
|
42
|
+
"license": "MIT",
|
|
43
|
+
"scripts": {
|
|
44
|
+
"dev": "tsx src/index.ts",
|
|
45
|
+
"build": "tsup",
|
|
46
|
+
"test": "vitest run",
|
|
47
|
+
"test:watch": "vitest"
|
|
48
|
+
}
|
|
49
|
+
}
|