funcoding-cli 0.2.0 → 0.3.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/README.md CHANGED
@@ -13,41 +13,58 @@
13
13
 
14
14
  把这句话发给你的智能体:
15
15
 
16
- > 运行 `npx --yes funcoding-cli@latest setup`,然后帮我找一个处理 PDF 的 Skill 并安装。
16
+ > 运行 `npx --yes funcoding-cli@latest init`,然后帮我找一个处理 PDF 的 Skill 并安装。
17
17
 
18
- `setup` 会给当前智能体装上 funcoding Skill([skill/funcoding/SKILL.md](skill/funcoding/SKILL.md))。Skill 里写明了:
18
+ `init` 做两件事:
19
19
 
20
- - 什么时候用哪条命令
21
- - 安装前先用 `info` 检查内容,并征得用户同意
22
- - 缺少 MCP 密钥时向用户索取,不要编造
20
+ 1. 没有全局安装时,用 npm 全局安装本工具,之后终端里可以直接用 `funcoding`,或者简写 `fun`。加 `--no-global` 跳过这一步。
21
+ 2. 给当前智能体装上 funcoding Skill([skill/funcoding/SKILL.md](skill/funcoding/SKILL.md))。Skill 里写明了:
22
+ - 什么时候用哪条命令
23
+ - 安装前先用 `skills info` 检查内容,并征得用户同意
24
+ - 缺少 MCP 密钥时向用户索取,不要编造
23
25
 
24
- 也可以全局安装,之后的命令是 `funcoding`:
26
+ 也可以自己全局安装:
25
27
 
26
28
  ```bash
27
29
  npm i -g funcoding-cli
28
- funcoding --help
30
+ fun --help
29
31
  ```
30
32
 
33
+ 没有用简写 `fc`:它是 zsh 和 bash 的内建命令(编辑历史命令用),shell 会优先执行内建命令。
34
+
31
35
  ## 命令
32
36
 
37
+ 格式参照 [android CLI](https://github.com/android/skills/blob/main/devtools/android-cli/SKILL.md):
38
+
39
+ - 顶层是 `init`、`update`、`info`、`help` 这几条。
40
+ - 其余命令按「名词 动词」分组。
41
+ - 每条命令都可以加 `--help`,查看它的用法、选项和位置参数,比如 `funcoding skills add --help`。
42
+ - 选项可以写成 `--agent=codex`,也可以写成 `--agent codex`。
43
+
33
44
  | 命令 | 说明 |
34
45
  | --- | --- |
35
- | `search <关键词>` | 搜索 Skill 和 MCP Server |
36
- | `info <owner/repo/skill>` | 查看 Skill 的描述、文件清单和 SKILL.md 全文 |
37
- | `install <id…>` | 安装一个或多个 Skill,也可以粘贴网站上的详情页地址 |
38
- | `list` | 列出已安装的 Skill:默认列出全部智能体,包括用户目录和当前项目 |
39
- | `update [名称] [--check]` | 按原来源重新安装;`--check` 只比较远端的 SKILL.md,不安装 |
40
- | `remove <名称…>` | 删除通过 funcoding 安装的 Skill,删除前先备份;删除其他来源的 Skill 需要 `--force` |
41
- | `mcp info <owner/repo>` | 查看启动方式(远程地址、npm 或 PyPI 包),以及需要的环境变量或请求头 |
42
- | `mcp add <owner/repo>` | 写入智能体的 MCP 配置;必填项用 `--env KEY=VALUE` 或 `--header KEY=VALUE` 提供,`--via remote\|npm\|pypi` 指定启动方式 |
43
- | `mcp list` / `mcp remove <配置名…>` | 列出或删除 MCP 配置,修改前备份原文件 |
44
- | `login` / `logout` / `whoami` | 在浏览器中授权登录(设备码)、退出登录并使登录凭证失效、查看当前账号 |
45
- | `favorites` | 列出网站上收藏的 Skill 和 MCP Server |
46
- | `sync [--dry-run]` | 安装全部收藏,已安装的跳过;需要密钥的 MCP 会列出缺少哪些值 |
47
- | `news [--daily [YYYY-MM-DD]]` | 查看 AI 热榜,或某一天的 AI 日报 |
48
- | `docs search <关键词> [--agent <智能体>]` | 搜索中文文档 |
49
- | `docs read <智能体/路径>` | 读取文档的 Markdown 原文,开头附官方来源和核实日期 |
50
- | `setup` | 给智能体装上 funcoding Skill;`update` 时会一起更新到当前 CLI 版本 |
46
+ | `init` | 全局安装本工具,并给智能体装上 funcoding Skill |
47
+ | `update` | 把本工具更新到最新版本,并刷新已安装的 funcoding Skill |
48
+ | `info [<field>]` | 环境信息:版本、站点、是否全局安装、登录状态、本机的智能体和 Skill 目录、配置目录 |
49
+ | `help [<command>]` | 显示帮助 |
50
+ | `skills find <query>` | 查找 Skill |
51
+ | `skills info <id>` | 查看 Skill 的描述、文件清单和 SKILL.md 全文 |
52
+ | `skills add <id>...` | 安装一个或多个 Skill,也可以粘贴网站上的详情页地址 |
53
+ | `skills list` | 列出已安装的 Skill:默认列出全部智能体,包括用户目录和当前项目 |
54
+ | `skills update [<name>] [--check]` | 按原来源重新安装;`--check` 只比较远端的 SKILL.md,不安装 |
55
+ | `skills remove <name>...` | 删除通过 funcoding 安装的 Skill,删除前先备份;删除其他来源的 Skill 需要 `--force` |
56
+ | `mcp find <query>` | 查找 MCP Server |
57
+ | `mcp info <id>` | 查看启动方式(远程地址、npm 或 PyPI 包),以及需要的环境变量或请求头 |
58
+ | `mcp add <id>` | 写入智能体的 MCP 配置;必填项用 `--env=KEY=VALUE` 或 `--header=KEY=VALUE` 提供,`--via=remote\|npm\|pypi` 指定启动方式 |
59
+ | `mcp list` / `mcp remove <name>...` | 列出或删除 MCP 配置,修改前备份原文件 |
60
+ | `favorites list` | 列出网站上收藏的 Skill 和 MCP Server |
61
+ | `favorites sync [--dry-run]` | 安装全部收藏,已安装的跳过;需要密钥的 MCP 会列出缺少哪些值 |
62
+ | `lists info <link>` | 查看别人分享的清单(`https://funcoding.ai/share/<id>/`),不需要登录 |
63
+ | `lists add <link> [--dry-run]` | 安装清单里的全部 Skill 和 MCP Server,已安装的跳过 |
64
+ | `auth login` / `auth logout` / `auth status` | 在浏览器中授权登录(设备码)、退出登录并使登录凭证失效、查看当前账号 |
65
+ | `news list` / `news daily [<YYYY-MM-DD>]` | AI 热榜,或某一天的 AI 日报 |
66
+ | `docs search <query> [--agent=<slug>]` | 搜索中文文档 |
67
+ | `docs fetch <agent>/<path>` | 读取文档的 Markdown 原文,开头附官方来源和核实日期 |
51
68
 
52
69
  ## 给智能体的约定
53
70
 
@@ -55,9 +72,9 @@ funcoding --help
55
72
  - 成功时为 `{ "ok": true, ... }`
56
73
  - 失败时为 `{ "ok": false, "error": { "code", "message", "hint", ... } }`
57
74
  - 过程提示一律写到 stderr。
58
- - **不交互**:需要确认的操作通过参数表达,比如覆盖时加 `--force`,`sync` 可以先加 `--dry-run` 预览。
75
+ - **不交互**:需要确认的操作通过参数表达,比如覆盖时加 `--force`,`favorites sync`、`lists add` 可以先加 `--dry-run` 预览。
59
76
  - **`--agent`**:可选 `claude-code`、`codex`、`cursor`,多个用逗号分隔。`all` 表示本机检测到的全部智能体,检测方法是看用户目录下有没有对应的配置目录。不指定时,在 Claude Code 中运行(`CLAUDECODE=1`)默认装给 Claude Code,其他情况也默认 Claude Code。Codex 和 Cursor 没有文档化的环境变量,CLI 不去猜,需要显式指定。
60
- - **范围**:`--project` 装到当前项目,不加时装到用户目录。`list`、`update`、`remove`、`mcp list`、`mcp remove` 默认同时查看两处,可以用 `--project` 或 `--user` 缩小范围。
77
+ - **范围**:`--project` 装到当前项目,不加时装到用户目录。`skills list`、`skills update`、`skills remove`、`mcp list`、`mcp remove` 默认同时查看两处,可以用 `--project` 或 `--user` 缩小范围。
61
78
 
62
79
  | 退出码 | 含义 |
63
80
  | --- | --- |
package/dist/api.js CHANGED
@@ -11,7 +11,7 @@ export class ApiError extends CliError {
11
11
  status;
12
12
  body;
13
13
  constructor(message, status, body) {
14
- super(codeOf(status), message, status === 401 ? '运行 funcoding login 重新登录' : undefined);
14
+ super(codeOf(status), message, status === 401 ? '运行 funcoding auth login 重新登录' : undefined);
15
15
  this.status = status;
16
16
  this.body = body;
17
17
  }
package/dist/auth.js CHANGED
@@ -23,7 +23,7 @@ export async function login(opts) {
23
23
  if (existing) {
24
24
  const me = await fetchMe(existing.token).catch(() => null);
25
25
  if (me) {
26
- return done({ user: me.user, alreadyLoggedIn: true }, () => info(`已经登录:${bold(me.user.name)}${me.user.githubLogin ? dim(` (@${me.user.githubLogin})`) : ''}。要换账号先运行 ${cyan('funcoding logout')}。`));
26
+ return done({ user: me.user, alreadyLoggedIn: true }, () => info(`已经登录:${bold(me.user.name)}${me.user.githubLogin ? dim(` (@${me.user.githubLogin})`) : ''}。要换账号先运行 ${cyan('funcoding auth logout')}。`));
27
27
  }
28
28
  }
29
29
  const code = await api('/api/auth/device/code', { method: 'POST', body: JSON.stringify({ client_id: CLIENT_ID }) });
@@ -62,11 +62,11 @@ export async function login(opts) {
62
62
  if (e?.error === 'access_denied')
63
63
  fail('auth', '你在浏览器里拒绝了这次登录。');
64
64
  if (e?.error === 'expired_token')
65
- fail('auth', '验证码过期了。', '重新运行 funcoding login');
65
+ fail('auth', '验证码过期了。', '重新运行 funcoding auth login');
66
66
  throw err;
67
67
  }
68
68
  }
69
- fail('auth', '验证码过期了。', '重新运行 funcoding login');
69
+ fail('auth', '验证码过期了。', '重新运行 funcoding auth login');
70
70
  }
71
71
  export async function logout() {
72
72
  const c = await loadCredentials(SITE);
@@ -84,13 +84,13 @@ export async function fetchMe(token) {
84
84
  export async function requireToken() {
85
85
  const c = await loadCredentials(SITE);
86
86
  if (!c)
87
- return fail('auth', '还没有登录。', '运行 funcoding login');
87
+ return fail('auth', '还没有登录。', '运行 funcoding auth login');
88
88
  return c.token;
89
89
  }
90
- export async function whoami() {
90
+ export async function status() {
91
91
  const c = await loadCredentials(SITE);
92
92
  if (!c)
93
- return fail('auth', '未登录。', '运行 funcoding login');
93
+ return fail('auth', '未登录。', '运行 funcoding auth login');
94
94
  const me = await fetchMe(c.token);
95
95
  done({ user: me.user, favorites: { skills: me.favorites.skills.length, mcp: me.favorites.mcp.length }, site: SITE }, () => {
96
96
  info(`${bold(me.user.name)}${me.user.githubLogin ? dim(` (@${me.user.githubLogin})`) : ''}`);