@cloudglab/confluence-cli 0.0.4 → 0.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +34 -0
- package/README.md +11 -3
- package/dist/cli.js +12 -1
- package/dist/core/cli-output.js +8 -3
- package/dist/core/command-groups.generated.js +5 -1
- package/dist/install.js +25 -11
- package/dist/manifest.json +9 -3
- package/dist/tools/spaces.js +6 -3
- package/dist/tools/transfer.js +11 -10
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +2 -2
- package/skills/confluence-cli/SKILL.md +63 -0
- package/skills/confluence-cli/reference/cli.md +36 -0
- package/skills/confluence-cli/reference/commands.md +41 -0
- package/skills/confluence-cli/reference/content.md +23 -0
- package/skills/confluence-cli/reference/overview.md +23 -0
- package/skills/confluence-cli/reference/rest.md +19 -0
- package/skills/confluence-cli/reference/transfer.md +27 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,40 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## Unreleased
|
|
6
|
+
|
|
7
|
+
## 0.0.6 - 2026-06-17
|
|
8
|
+
|
|
9
|
+
### 变更
|
|
10
|
+
|
|
11
|
+
- Mermaid 图片渲染从 `mmd-cli` 切换为 `beautiful-mermaid-cli` 的 `bm render`,默认 PNG/SVG 渲染不再依赖本机 Chrome、Chromium、Puppeteer 或原生编译工具链。
|
|
12
|
+
- `install` / `update` 改为通过 `npm install -g beautiful-mermaid-cli@latest` 安装 Mermaid 渲染器,不再执行 `raw.githubusercontent.com` 上的 `curl | sh` 安装脚本。
|
|
13
|
+
- 项目运行要求从 Node.js 18+ 提升到 Node.js 20+,与 `beautiful-mermaid-cli` 的运行时要求保持一致。
|
|
14
|
+
- 对齐 `zentao-cli` 的通用账号命令,新增 `whoami`、`who-am-i`,并支持 `confluence who am i` 口语化输入,均复用 `getCurrentUser` 查询当前 Confluence 账号。
|
|
15
|
+
|
|
16
|
+
### 测试
|
|
17
|
+
|
|
18
|
+
- `tests/install.test.ts` 同步断言新的 `beautiful-mermaid-cli` 安装链路,并保留安装失败不阻断主流程的回归覆盖。
|
|
19
|
+
- `tests/tools/transfer.test.ts` 同步校验 `bm render <file> -o <png> --json --scale 3` 调用参数。
|
|
20
|
+
- `tests/cli.test.ts` 和 `tests/tools/spaces.test.ts` 覆盖 `whoami` / `who-am-i` 注册、命令列表展示和 `who am i` 归一化。
|
|
21
|
+
|
|
22
|
+
## 0.0.5 - 2026-06-17
|
|
23
|
+
|
|
24
|
+
### 修复
|
|
25
|
+
|
|
26
|
+
- `install` / `update` 链路:把仓库内 `skills/confluence-cli` 从指向 `.agents/skills/confluence-cli` 的符号链接替换为真实目录副本,避免 npm tarball 中 `skills/confluence-cli` 路径在用户机器上不可用导致“未找到已安装包内的 Confluence skill”错误。
|
|
27
|
+
- `install` / `update` 链路:`installMmdCli` 不再因 `curl -fsSL ... | sh` 网络失败而中断整个安装,改为捕获异常并输出 `已跳过 mmd-cli 安装:<原因>` 与后续 `--mermaid none` 退路提示。
|
|
28
|
+
- `install` / `update` 链路:`installSkillFromInstalledPackage` 在 `access` 失败时不再直接抛错,自动回退到 `installSkillFromNpmPackage`(`npm pack` + `tar -xzf` + `npx -y skills add`),覆盖包内 skill 缺失场景。
|
|
29
|
+
|
|
30
|
+
### 测试
|
|
31
|
+
|
|
32
|
+
- `tests/install.test.ts` 新增回归用例 `本地 skill 缺失时自动回退到 npm 包解压安装,mmd-cli 失败不阻断安装`:mock `curl` 退出码 35、stderr 含 `curl: (35) LibreSSL SSL_connect...`,断言安装链路按 `npm install -g` → 跳过 `mmd-cli` → `npm pack` → `tar` → `npx -y skills add` 顺序完成,并校验 stdout 中包含“已跳过 mmd-cli 安装”与“正在自动回退到 npm 包解压安装”两行提示。
|
|
33
|
+
|
|
34
|
+
### 说明
|
|
35
|
+
|
|
36
|
+
- 本次热修不改变 `mmd-cli` 运行时仍需系统 Chrome/Chromium 的前提;网络环境下无法自动安装 `mmd-cli` 时,建议用户改用 `--mermaid none` 保留代码块。
|
|
37
|
+
- 验证结果:`pnpm test -- tests/install.test.ts tests/skill.test.ts tests/tools/transfer.test.ts` 全部通过(3 个文件、10 个测试)。
|
|
38
|
+
|
|
5
39
|
## 0.0.4 - 2026-06-17
|
|
6
40
|
|
|
7
41
|
### 修复
|
package/README.md
CHANGED
|
@@ -21,9 +21,16 @@ pnpm test
|
|
|
21
21
|
pnpm release:smoke-query --dry-run
|
|
22
22
|
```
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
Mermaid 渲染默认使用 `beautiful-mermaid-cli` 的 `bm` 命令。它通过纯 JS + WASM 渲染 SVG/PNG,不依赖 Chrome、Chromium、Puppeteer 或原生编译工具链;安装/更新时会自动执行 `npm install -g beautiful-mermaid-cli@latest`。
|
|
25
25
|
|
|
26
|
-
`
|
|
26
|
+
由于 `beautiful-mermaid-cli` 要求 Node.js 20+,本项目运行要求也同步提升到 Node.js 20+。如果自动安装失败,上传时仍可传 `--mermaid none` 保留 Mermaid 代码块。
|
|
27
|
+
|
|
28
|
+
当前版本还补齐了 `zentao-cli` 风格的账号快捷命令:`confluence whoami`、`confluence who-am-i`,以及口语化输入 `confluence who am i`。
|
|
29
|
+
|
|
30
|
+
`install` / `update` 在以下情况会**继续完成安装**而不是中断:
|
|
31
|
+
|
|
32
|
+
- `beautiful-mermaid-cli` 安装失败时,会打印 `已跳过 beautiful-mermaid-cli 安装:<原因>` 与 `后续如需 Mermaid 图片渲染,可稍后重试安装,或在上传时传 --mermaid none 保留代码块。`。
|
|
33
|
+
- 全局包内 `skills/confluence-cli` 缺失时,会打印 `未找到已安装包内的 Confluence skill:<path>,正在自动回退到 npm 包解压安装...` 并自动用 `npm pack` + `tar` + `npx -y skills add` 完成 skill 安装,无需手动切换 `--skill-source npm`。
|
|
27
34
|
|
|
28
35
|
安装/更新入口:
|
|
29
36
|
|
|
@@ -66,6 +73,7 @@ CLI 会按顺序查找:显式 `envFile`、环境变量、当前/父目录 `.en
|
|
|
66
73
|
|
|
67
74
|
```bash
|
|
68
75
|
confluence list
|
|
76
|
+
confluence whoami
|
|
69
77
|
confluence searchContent --cql 'space = "DEV" AND text ~ "API"'
|
|
70
78
|
confluence getContent --id 123456
|
|
71
79
|
confluence listRestApis --group content
|
|
@@ -136,7 +144,7 @@ CONFLUENCE_SKIP_UPDATE_CHECK=true
|
|
|
136
144
|
- Confluence 7.13.7 全量 REST API 端点注册与通用调用
|
|
137
145
|
- MCP 页面/子页/评论/标签能力的语义化 CLI 命令
|
|
138
146
|
- Markdown 转 Confluence Wiki Markup
|
|
139
|
-
- Markdown/HTML 上传时默认用 `
|
|
147
|
+
- Markdown/HTML 上传时默认用 `beautiful-mermaid-cli` 将 Mermaid 渲染为 PNG 附件并以内置图片宏展示,必要时可用 `--mermaid none` 保留原代码块
|
|
140
148
|
- mark 风格 metadata 生成
|
|
141
149
|
- Markdown 上传预览、确认写入和附件上传
|
|
142
150
|
- 页面下载为带 frontmatter 的 Markdown,并可下载附件和一层子页
|
package/dist/cli.js
CHANGED
|
@@ -149,6 +149,17 @@ function parseCli(argv) {
|
|
|
149
149
|
role = value;
|
|
150
150
|
args.splice(roleIndex, 2);
|
|
151
151
|
}
|
|
152
|
-
|
|
152
|
+
const normalized = normalizeCommandAlias(args[0], args.slice(1));
|
|
153
|
+
return {
|
|
154
|
+
command: normalized.command,
|
|
155
|
+
commandArgs: args.slice(1 + normalized.consumedArgs),
|
|
156
|
+
role,
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
function normalizeCommandAlias(command, args) {
|
|
160
|
+
if (command === "who" && args[0] === "am" && args[1] === "i") {
|
|
161
|
+
return { command: "whoami", consumedArgs: 2 };
|
|
162
|
+
}
|
|
163
|
+
return { command, consumedArgs: 0 };
|
|
153
164
|
}
|
|
154
165
|
//# sourceMappingURL=cli.js.map
|
package/dist/core/cli-output.js
CHANGED
|
@@ -23,6 +23,9 @@ const COMMAND_DESCRIPTIONS = {
|
|
|
23
23
|
searchSpace: "搜索 Confluence 空间",
|
|
24
24
|
listSpaces: "列出 Confluence 空间",
|
|
25
25
|
getSpace: "获取空间详情",
|
|
26
|
+
getCurrentUser: "输出当前账号原始资料",
|
|
27
|
+
whoami: "查看当前 Confluence 账号",
|
|
28
|
+
"who-am-i": "whoami 的别名",
|
|
26
29
|
searchContent: "使用 CQL 搜索内容",
|
|
27
30
|
getContent: "获取页面或博客内容",
|
|
28
31
|
createContent: "创建 Confluence 内容",
|
|
@@ -46,7 +49,7 @@ export function printHelp(role, commandNames) {
|
|
|
46
49
|
"",
|
|
47
50
|
`当前 role: ${role}`,
|
|
48
51
|
"适配版本:Confluence Data Center / Server REST API。",
|
|
49
|
-
"运行要求:Node.js >=
|
|
52
|
+
"运行要求:Node.js >= 20",
|
|
50
53
|
"",
|
|
51
54
|
"用法:",
|
|
52
55
|
" confluence [--role full|reader|writer] <command> [--key value]",
|
|
@@ -56,6 +59,7 @@ export function printHelp(role, commandNames) {
|
|
|
56
59
|
"快速开始:",
|
|
57
60
|
" confluence list 查看全部可用命令(推荐)",
|
|
58
61
|
" confluence help <command> 查看命令参数",
|
|
62
|
+
" confluence whoami 校验当前账号",
|
|
59
63
|
" confluence initConfluence 初始化或校验连接配置",
|
|
60
64
|
" confluence version 查看版本",
|
|
61
65
|
" confluence changelog 查看最近更新",
|
|
@@ -99,7 +103,7 @@ export function printCommandList(role, commandNames, builtinCommandNames = BUILT
|
|
|
99
103
|
}
|
|
100
104
|
lines.push("");
|
|
101
105
|
}
|
|
102
|
-
lines.push("下一步:", " - 查看参数:confluence help <command>,例如 confluence help searchContent", " - 初始化配置:confluence initConfluence", " - 查看脚本友好命令名:confluence list --raw", " - 切换角色命令集:confluence --role reader list 或 confluence --role writer list", "");
|
|
106
|
+
lines.push("下一步:", " - 查看参数:confluence help <command>,例如 confluence help searchContent", " - 快速校验账号:confluence whoami", " - 初始化配置:confluence initConfluence", " - 查看脚本友好命令名:confluence list --raw", " - 切换角色命令集:confluence --role reader list 或 confluence --role writer list", "");
|
|
103
107
|
process.stdout.write(lines.join("\n"));
|
|
104
108
|
}
|
|
105
109
|
export function getBuiltinCommandHelp(commandName) {
|
|
@@ -210,7 +214,7 @@ export function renderCommandHelp(registry, name) {
|
|
|
210
214
|
}
|
|
211
215
|
function buildCommandGroups(commandNames) {
|
|
212
216
|
const groups = [
|
|
213
|
-
{ title: "开始使用", match: (name) => ["changelog", "help", "list", "version", "install", "update", "upgrade", "uninstall", "remove", "initConfluence"].includes(name), commands: [] },
|
|
217
|
+
{ title: "开始使用", match: (name) => ["changelog", "help", "list", "version", "install", "update", "upgrade", "uninstall", "remove", "initConfluence", "whoami", "who-am-i", "getCurrentUser"].includes(name), commands: [] },
|
|
214
218
|
{ title: "内容检索 / 页面", match: (name) => /Content|Page|searchContent|getContent/.test(name), commands: [] },
|
|
215
219
|
{ title: "上传 / 下载 / 附件", match: (name) => /Upload|Download|Attachment|upload|download/.test(name), commands: [] },
|
|
216
220
|
{ title: "空间 / 标签", match: (name) => /Space|Label/.test(name), commands: [] },
|
|
@@ -226,6 +230,7 @@ function buildCommandGroups(commandNames) {
|
|
|
226
230
|
}
|
|
227
231
|
function getRecommendedCommands(commandNames) {
|
|
228
232
|
const candidates = [
|
|
233
|
+
{ name: "whoami", description: "校验当前账号" },
|
|
229
234
|
{ name: "initConfluence", description: "初始化或校验连接配置" },
|
|
230
235
|
{ name: "searchContent", description: "使用 CQL 搜索页面/博客" },
|
|
231
236
|
{ name: "getContent", description: "读取 Confluence 内容" },
|
|
@@ -14,6 +14,8 @@ export const commandToGroup = {
|
|
|
14
14
|
"getCurrentUser": "space",
|
|
15
15
|
"getSpace": "space",
|
|
16
16
|
"listSpaces": "space",
|
|
17
|
+
"who-am-i": "space",
|
|
18
|
+
"whoami": "space",
|
|
17
19
|
"addComment": "content",
|
|
18
20
|
"deleteContent": "content",
|
|
19
21
|
"findContent": "content",
|
|
@@ -57,7 +59,9 @@ export const groupCommands = {
|
|
|
57
59
|
"convertContentBody",
|
|
58
60
|
"getCurrentUser",
|
|
59
61
|
"getSpace",
|
|
60
|
-
"listSpaces"
|
|
62
|
+
"listSpaces",
|
|
63
|
+
"who-am-i",
|
|
64
|
+
"whoami"
|
|
61
65
|
],
|
|
62
66
|
"content": [
|
|
63
67
|
"addComment",
|
package/dist/install.js
CHANGED
|
@@ -7,7 +7,7 @@ import { loadConfluenceConfig, normalizeConfig, saveConfig } from "./core/config
|
|
|
7
7
|
import { writeUpdateCacheAfterInstall } from "./update-probe.js";
|
|
8
8
|
const PACKAGE_NAME = "@cloudglab/confluence-cli";
|
|
9
9
|
const GIT_SKILL_SOURCE = "cloudglab/confluence-cli";
|
|
10
|
-
const
|
|
10
|
+
const MERMAID_RENDERER_PACKAGE = "beautiful-mermaid-cli";
|
|
11
11
|
export async function runInstallCommand(args = []) {
|
|
12
12
|
const options = parseInstallOptions(args);
|
|
13
13
|
await installPackageAndSkill("安装", options);
|
|
@@ -57,7 +57,7 @@ function printSuccessGuide(action, status) {
|
|
|
57
57
|
confluence update 更新 CLI 和 Skill
|
|
58
58
|
confluence install --skip-config-check 仅安装,跳过配置校验
|
|
59
59
|
confluence install --skill-global 把 skill 装到 user-level 全局目录
|
|
60
|
-
|
|
60
|
+
bm doctor --json 检查 Mermaid 渲染器
|
|
61
61
|
CONFLUENCE_DISABLE_WRITE=true 禁用真实写操作
|
|
62
62
|
|
|
63
63
|
写操作提示:真实写入仍需显式传 confirm=true。
|
|
@@ -160,7 +160,7 @@ function parseUninstallOptions(args) {
|
|
|
160
160
|
function printUninstallPreview(options) {
|
|
161
161
|
const steps = [
|
|
162
162
|
...(!options.cliOnly ? ["卸载 confluence skill(项目级和全局级)"] : []),
|
|
163
|
-
...(!options.skillOnly ? ["卸载全局 CLI 包、清理 npm
|
|
163
|
+
...(!options.skillOnly ? ["卸载全局 CLI 包、清理 npm 残留目录,并卸载 Mermaid 渲染器"] : []),
|
|
164
164
|
...(shouldRemoveConfig(options) ? ["删除 ~/.confluence/config.json"] : ["保留 ~/.confluence/config.json"]),
|
|
165
165
|
];
|
|
166
166
|
process.stdout.write(`卸载预览:\n${steps.map((step) => ` - ${step}`).join("\n")}\n\n真实执行请运行:\n confluence uninstall --confirm true\n npx -y ${PACKAGE_NAME}@latest uninstall --confirm true\n\n可选参数:\n --keep-config true 保留 Confluence 配置\n --cli-only true 只卸载 CLI\n --skill-only true 只卸载 skill\n`);
|
|
@@ -224,7 +224,7 @@ async function installPackageAndSkill(action, options) {
|
|
|
224
224
|
if (!options.skillOnly) {
|
|
225
225
|
await cleanupGlobalPackageResidues();
|
|
226
226
|
await installGlobalCli(action);
|
|
227
|
-
await
|
|
227
|
+
await installMermaidRenderer(action);
|
|
228
228
|
}
|
|
229
229
|
if (!options.cliOnly) {
|
|
230
230
|
await installSkill(action, options);
|
|
@@ -245,8 +245,15 @@ async function installGlobalCli(action) {
|
|
|
245
245
|
await runStep(`${action} Confluence CLI`, "npm", args);
|
|
246
246
|
}
|
|
247
247
|
}
|
|
248
|
-
async function
|
|
249
|
-
|
|
248
|
+
async function installMermaidRenderer(action) {
|
|
249
|
+
try {
|
|
250
|
+
await runStep(`${action} Mermaid 免浏览器渲染器 beautiful-mermaid-cli`, "npm", ["install", "-g", `${MERMAID_RENDERER_PACKAGE}@latest`]);
|
|
251
|
+
}
|
|
252
|
+
catch (error) {
|
|
253
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
254
|
+
process.stdout.write(`已跳过 beautiful-mermaid-cli 安装:${message}\n`);
|
|
255
|
+
process.stdout.write("后续如需 Mermaid 图片渲染,可稍后重试安装,或在上传时传 --mermaid none 保留代码块。\n");
|
|
256
|
+
}
|
|
250
257
|
}
|
|
251
258
|
function isNpmDirectoryNotEmptyError(error) {
|
|
252
259
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -286,7 +293,9 @@ async function installSkillFromInstalledPackage(action, skillGlobal) {
|
|
|
286
293
|
await access(skillPath);
|
|
287
294
|
}
|
|
288
295
|
catch {
|
|
289
|
-
|
|
296
|
+
process.stdout.write(`未找到已安装包内的 Confluence skill:${skillPath},正在自动回退到 npm 包解压安装...\n`);
|
|
297
|
+
await installSkillFromNpmPackage(action, skillGlobal);
|
|
298
|
+
return;
|
|
290
299
|
}
|
|
291
300
|
await runNpxStepWithRetry(`${action} Confluence skill`, createSkillAddArgs(skillPath, skillGlobal));
|
|
292
301
|
}
|
|
@@ -317,11 +326,16 @@ async function uninstallSkill() {
|
|
|
317
326
|
async function uninstallPackage() {
|
|
318
327
|
await runStep("卸载 Confluence CLI", "npm", ["uninstall", "-g", PACKAGE_NAME]);
|
|
319
328
|
await cleanupGlobalPackageResidues();
|
|
320
|
-
await
|
|
329
|
+
await uninstallMermaidRenderer();
|
|
321
330
|
}
|
|
322
|
-
async function
|
|
323
|
-
|
|
324
|
-
|
|
331
|
+
async function uninstallMermaidRenderer() {
|
|
332
|
+
try {
|
|
333
|
+
await runStep("卸载 Mermaid 免浏览器渲染器 beautiful-mermaid-cli", "npm", ["uninstall", "-g", MERMAID_RENDERER_PACKAGE]);
|
|
334
|
+
}
|
|
335
|
+
catch (error) {
|
|
336
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
337
|
+
process.stdout.write(`已跳过 beautiful-mermaid-cli 卸载:${message}\n`);
|
|
338
|
+
}
|
|
325
339
|
}
|
|
326
340
|
async function cleanupGlobalPackageResidues() {
|
|
327
341
|
const globalNodeModules = (await runCommandOutput("npm", ["root", "-g"])).trim();
|
package/dist/manifest.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "0.0.
|
|
2
|
+
"version": "0.0.6",
|
|
3
3
|
"commands": [
|
|
4
4
|
"addComment",
|
|
5
5
|
"addLabels",
|
|
@@ -31,7 +31,9 @@
|
|
|
31
31
|
"updateAttachment",
|
|
32
32
|
"uploadAttachment",
|
|
33
33
|
"uploadHtml",
|
|
34
|
-
"uploadMarkdown"
|
|
34
|
+
"uploadMarkdown",
|
|
35
|
+
"who-am-i",
|
|
36
|
+
"whoami"
|
|
35
37
|
],
|
|
36
38
|
"groups": {
|
|
37
39
|
"init": [
|
|
@@ -58,7 +60,9 @@
|
|
|
58
60
|
"convertContentBody",
|
|
59
61
|
"getCurrentUser",
|
|
60
62
|
"getSpace",
|
|
61
|
-
"listSpaces"
|
|
63
|
+
"listSpaces",
|
|
64
|
+
"who-am-i",
|
|
65
|
+
"whoami"
|
|
62
66
|
],
|
|
63
67
|
"content": [
|
|
64
68
|
"addComment",
|
|
@@ -101,6 +105,8 @@
|
|
|
101
105
|
"getCurrentUser": "space",
|
|
102
106
|
"getSpace": "space",
|
|
103
107
|
"listSpaces": "space",
|
|
108
|
+
"who-am-i": "space",
|
|
109
|
+
"whoami": "space",
|
|
104
110
|
"addComment": "content",
|
|
105
111
|
"deleteContent": "content",
|
|
106
112
|
"findContent": "content",
|
package/dist/tools/spaces.js
CHANGED
|
@@ -2,15 +2,18 @@ import { z } from "zod";
|
|
|
2
2
|
import { getApi } from "../core/api-provider.js";
|
|
3
3
|
import { jsonResult } from "../utils/result.js";
|
|
4
4
|
export function registerSpaceTools(registry) {
|
|
5
|
+
const getCurrentUser = async () => {
|
|
6
|
+
return jsonResult(await getApi().getCurrentUser());
|
|
7
|
+
};
|
|
5
8
|
registry.tool("listSpaces", z.object({ limit: z.number().int().positive().max(100).default(25) }), async ({ limit }) => {
|
|
6
9
|
return jsonResult(await getApi().listSpaces(limit));
|
|
7
10
|
}, "List Confluence spaces");
|
|
8
11
|
registry.tool("getSpace", z.object({ spaceKey: z.string() }), async ({ spaceKey }) => {
|
|
9
12
|
return jsonResult(await getApi().getSpace(spaceKey));
|
|
10
13
|
}, "Get one Confluence space by key");
|
|
11
|
-
registry.tool("getCurrentUser", z.object({}),
|
|
12
|
-
|
|
13
|
-
}, "
|
|
14
|
+
registry.tool("getCurrentUser", z.object({}), getCurrentUser, "Get current authenticated Confluence user");
|
|
15
|
+
registry.tool("whoami", z.object({}), getCurrentUser, "Show current authenticated Confluence user");
|
|
16
|
+
registry.tool("who-am-i", z.object({}), getCurrentUser, "Alias of whoami");
|
|
14
17
|
registry.tool("convertContentBody", z.object({ to: z.enum(["storage", "view", "export_view", "styled_view"]), value: z.string(), representation: z.enum(["wiki", "storage", "view"]).default("wiki") }), async ({ to, value, representation }) => {
|
|
15
18
|
return jsonResult(await getApi().convertBody(to, { value, representation: representation ?? "wiki" }));
|
|
16
19
|
}, "Convert Confluence content body representation");
|
package/dist/tools/transfer.js
CHANGED
|
@@ -382,29 +382,30 @@ function createMermaidFile(mermaidSource, pageTitle, sourceFile, idx, renderKind
|
|
|
382
382
|
function renderMermaidFile(mermaidSource, outputFile, renderKind) {
|
|
383
383
|
const inputFile = join(dirname(outputFile), `${basename(outputFile, extname(outputFile))}.mmd`);
|
|
384
384
|
writeFileSync(inputFile, mermaidSource, "utf8");
|
|
385
|
-
const
|
|
386
|
-
const args = ["
|
|
385
|
+
const renderer = resolveBeautifulMermaidBin();
|
|
386
|
+
const args = ["render", inputFile, "-o", outputFile, "--json"];
|
|
387
387
|
if (renderKind === "png") {
|
|
388
|
-
args.push("
|
|
388
|
+
args.push("--scale", "3");
|
|
389
389
|
}
|
|
390
390
|
try {
|
|
391
|
-
execFileSync(
|
|
391
|
+
execFileSync(renderer, args, { stdio: "pipe" });
|
|
392
392
|
}
|
|
393
393
|
catch (error) {
|
|
394
394
|
const message = error instanceof Error ? error.message : String(error);
|
|
395
|
-
throw new Error(`Failed to render Mermaid as ${renderKind} with
|
|
395
|
+
throw new Error(`Failed to render Mermaid as ${renderKind} with beautiful-mermaid-cli: ${message}`);
|
|
396
396
|
}
|
|
397
397
|
}
|
|
398
|
-
function
|
|
399
|
-
const extension = process.platform === "win32" ? ".
|
|
398
|
+
function resolveBeautifulMermaidBin() {
|
|
399
|
+
const extension = process.platform === "win32" ? ".cmd" : "";
|
|
400
400
|
const candidates = [
|
|
401
|
-
join(process.env.HOME ?? "", ".
|
|
402
|
-
"
|
|
401
|
+
join(process.env.HOME ?? "", ".npm-global", "bin", `bm${extension}`),
|
|
402
|
+
join(process.env.HOME ?? "", ".local", "bin", `bm${extension}`),
|
|
403
|
+
`/usr/local/bin/bm${extension}`,
|
|
403
404
|
];
|
|
404
405
|
const found = candidates.find((candidate) => existsSync(candidate));
|
|
405
406
|
if (found)
|
|
406
407
|
return found;
|
|
407
|
-
return `
|
|
408
|
+
return `bm${extension}`;
|
|
408
409
|
}
|
|
409
410
|
function safeFileName(value) {
|
|
410
411
|
return value.replace(/[\\/:*?"<>|]/g, "_");
|
package/dist/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const VERSION = "0.0.
|
|
1
|
+
export declare const VERSION = "0.0.6";
|
package/dist/version.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export const VERSION = "0.0.
|
|
1
|
+
export const VERSION = "0.0.6";
|
|
2
2
|
//# sourceMappingURL=version.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cloudglab/confluence-cli",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.6",
|
|
4
4
|
"description": "Confluence REST CLI for agents and local automation",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
"vitest": "^4.1.8"
|
|
54
54
|
},
|
|
55
55
|
"engines": {
|
|
56
|
-
"node": ">=
|
|
56
|
+
"node": ">=20"
|
|
57
57
|
},
|
|
58
58
|
"publishConfig": {
|
|
59
59
|
"access": "public"
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: confluence-cli
|
|
3
|
+
description: Use this CLI for Confluence REST operations from a terminal or agent workflow. Triggers on Confluence page search, read, upload (Markdown/HTML with Mermaid + TOC), download, labels, attachments, comments, and Confluence 7.13.7 REST pass-through.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Confluence CLI Skill
|
|
7
|
+
|
|
8
|
+
Use this CLI when a task needs Confluence REST operations from a terminal or agent workflow.
|
|
9
|
+
|
|
10
|
+
Start with these references when you need details:
|
|
11
|
+
|
|
12
|
+
- `reference/overview.md`:整体工作流与安全原则
|
|
13
|
+
- `reference/commands.md`:命令速查
|
|
14
|
+
- `reference/cli.md`:安装、更新、角色入口和环境变量
|
|
15
|
+
- `reference/content.md`:页面查询、读取、子页、评论、标签
|
|
16
|
+
- `reference/transfer.md`:Markdown/HTML 发布、下载、附件、Mermaid/TOC
|
|
17
|
+
- `reference/rest.md`:Confluence 7.13.7 REST 端点透传
|
|
18
|
+
- `../../docs/release.md`:发布前检查与 npm 发布流程
|
|
19
|
+
|
|
20
|
+
## Decision Matrix
|
|
21
|
+
|
|
22
|
+
- Read/search small content: `confluence searchContent` or `confluence getContent`.
|
|
23
|
+
- Convert Markdown locally: `confluence convertMarkdownToWiki`.
|
|
24
|
+
- Generate mark metadata: `confluence generateMarkMetadata`.
|
|
25
|
+
- Upload large Markdown through REST: `confluence uploadMarkdown --toc --confirm true`.
|
|
26
|
+
- Upload raw HTML through REST: `confluence uploadHtml --toc --confirm true`.
|
|
27
|
+
- For full page publishes or republish flows, include `--toc` by default; only omit it when the user explicitly says no TOC.
|
|
28
|
+
- Upload Markdown with attachments: `confluence uploadMarkdown --attachments '["a.png"]' --toc --confirm true`.
|
|
29
|
+
- Dry-run uploads first: omit `--confirm true`.
|
|
30
|
+
- Render Mermaid on the fly: any ```mermaid fence in Markdown/HTML auto-generates PNG attachments by default.
|
|
31
|
+
- Download editable backup: `confluence downloadPage`.
|
|
32
|
+
- Download page with attachments/children: `confluence downloadPage --downloadAttachments true --downloadChildren true`.
|
|
33
|
+
- Use MCP-style page tools: `getPageChildren`, `getComments`, `addComment`, `getLabels`, `addLabels`.
|
|
34
|
+
- Use attachment tools: `listAttachments`, `uploadAttachment`, `updateAttachment`, `downloadAttachment`.
|
|
35
|
+
- Check PAT identity: `confluence getCurrentUser`.
|
|
36
|
+
|
|
37
|
+
## Safety
|
|
38
|
+
|
|
39
|
+
All writes must pass `--confirm true`. Without confirmation, upload, delete, label, comment and attachment write commands return a dry-run preview.
|
|
40
|
+
|
|
41
|
+
## CQL Examples
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
confluence searchContent --cql 'space = "DEV" AND text ~ "API"'
|
|
45
|
+
confluence searchContent --cql 'type = page AND title ~ "Runbook"'
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Upload Patterns
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
# Markdown → Confluence,自动 Mermaid → PNG 附件图片,默认注入双 TOC 宏
|
|
52
|
+
confluence uploadMarkdown --file doc.md --id 142552620 --toc --tocMaxLevel 3 --confirm true
|
|
53
|
+
|
|
54
|
+
# 保持原代码块不渲染
|
|
55
|
+
confluence uploadMarkdown --file doc.md --id 142552620 --mermaid none --toc --confirm true
|
|
56
|
+
|
|
57
|
+
# HTML → Confluence,同样支持Mermaid和TOC
|
|
58
|
+
confluence uploadHtml --file page.html --space DEV --toc --confirm true
|
|
59
|
+
|
|
60
|
+
# 只预览(dry-run)
|
|
61
|
+
confluence uploadMarkdown --file doc.md --id 142552620 --toc
|
|
62
|
+
confluence uploadHtml --file page.html --space DEV --toc
|
|
63
|
+
```
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# CLI
|
|
2
|
+
|
|
3
|
+
## 安装与更新
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
confluence install --skip-config-check true
|
|
7
|
+
confluence update --skip-config-check true
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
可选参数:
|
|
11
|
+
|
|
12
|
+
- `--skill-source local|git|npm`
|
|
13
|
+
- `--skill-local-path <dir>`
|
|
14
|
+
- `--cli-only true|false`
|
|
15
|
+
- `--skill-only true|false`
|
|
16
|
+
- `--skip-config-check true|false`
|
|
17
|
+
|
|
18
|
+
## 角色入口
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
confluence list
|
|
22
|
+
confluence-reader list
|
|
23
|
+
confluence-writer list
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
- `confluence`:完整入口。
|
|
27
|
+
- `confluence-reader`:不注册发布上传类 transfer 命令。
|
|
28
|
+
- `confluence-writer`:注册写入和发布命令,但仍需要 `--confirm true`。
|
|
29
|
+
|
|
30
|
+
## 环境变量
|
|
31
|
+
|
|
32
|
+
- `CONFLUENCE_URL`
|
|
33
|
+
- `CONFLUENCE_PAT` 或 `CONFLUENCE_PERSONAL_TOKEN`
|
|
34
|
+
- `CONFLUENCE_USERNAME` + `CONFLUENCE_PASSWORD`
|
|
35
|
+
- `CONFLUENCE_DISABLE_WRITE=true`
|
|
36
|
+
- `CONFLUENCE_SKIP_UPDATE_CHECK=true`
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# 命令速查
|
|
2
|
+
|
|
3
|
+
## 基础
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
confluence help
|
|
7
|
+
confluence list
|
|
8
|
+
confluence version
|
|
9
|
+
confluence help searchContent
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## 配置
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
confluence initConfluence --url https://confluence.example.com --pat TOKEN --save true
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## 查询
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
confluence searchContent --cql 'space = "DEV" AND text ~ "API"'
|
|
22
|
+
confluence getContent --id 123456
|
|
23
|
+
confluence findContent --space DEV --title "API Guide"
|
|
24
|
+
confluence getPageChildren --id 123456 --type page
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## 发布与下载
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
confluence uploadMarkdown --file docs/page.md --space DEV --toc --confirm false
|
|
31
|
+
confluence uploadMarkdown --file docs/page.md --id 123456 --attachments '["docs/a.png"]' --toc --confirm true
|
|
32
|
+
confluence uploadHtml --file docs/page.html --space DEV --toc --confirm true
|
|
33
|
+
confluence downloadPage --id 123456 --outputDir exports --downloadAttachments true --downloadChildren true
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## REST 透传
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
confluence listRestApis --group content --limit 20
|
|
40
|
+
confluence callRestApi --method GET --path '/content/{id}' --pathParams '{"id":"123456"}' --query '{"expand":"body.storage,version"}'
|
|
41
|
+
```
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# 内容操作
|
|
2
|
+
|
|
3
|
+
## 查询页面
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
confluence searchContent --cql 'type = page AND title ~ "Runbook"'
|
|
7
|
+
confluence findContent --space DEV --title "Runbook"
|
|
8
|
+
confluence getContent --id 123456
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## 子页、评论、标签
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
confluence getPageChildren --id 123456 --type page
|
|
15
|
+
confluence getComments --id 123456
|
|
16
|
+
confluence addComment --id 123456 --text "LGTM" --confirm true
|
|
17
|
+
confluence getLabels --id 123456
|
|
18
|
+
confluence addLabels --id 123456 --labels '["api","docs"]' --confirm true
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## 安全原则
|
|
22
|
+
|
|
23
|
+
所有删除、评论、标签等写命令都必须显式 `--confirm true`;不传确认时只返回 preview。
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# 总览
|
|
2
|
+
|
|
3
|
+
## 这个 skill 做什么
|
|
4
|
+
|
|
5
|
+
- 用命令行方式操作 Confluence Server/Data Center REST API。
|
|
6
|
+
- 默认写操作只 preview,真实写入必须显式 `--confirm true`。
|
|
7
|
+
- 支持页面搜索、读取、评论、标签、附件、Markdown/HTML 发布、页面下载和 REST 端点透传。
|
|
8
|
+
|
|
9
|
+
## 推荐工作流
|
|
10
|
+
|
|
11
|
+
1. 先确认本机是否安装 `confluence`。
|
|
12
|
+
2. 如果没有,优先运行 `confluence install --skip-config-check true`。
|
|
13
|
+
3. 对命令参数不确定时,先运行 `confluence help <command>` 校对。
|
|
14
|
+
4. 查询类任务优先用 `searchContent`、`getContent`、`findContent`。
|
|
15
|
+
5. 发布类任务优先 dry-run,再加 `--confirm true`。
|
|
16
|
+
6. Markdown/HTML 全量发布默认加 `--toc`,除非用户明确不要目录。
|
|
17
|
+
7. 自动化环境可设置 `CONFLUENCE_DISABLE_WRITE=true` 彻底禁用真实写入。
|
|
18
|
+
|
|
19
|
+
## 适合谁
|
|
20
|
+
|
|
21
|
+
- 需要命令行操作 Confluence 的人。
|
|
22
|
+
- 需要把 Confluence 接入智能体的人。
|
|
23
|
+
- 需要在 Confluence 7.13.7 环境下稳定自动化的人。
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# REST 透传
|
|
2
|
+
|
|
3
|
+
`listRestApis` 和 `callRestApi` 用于覆盖 Confluence 7.13.7 官方 REST 端点。
|
|
4
|
+
|
|
5
|
+
## 查看端点
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
confluence listRestApis --limit 20
|
|
9
|
+
confluence listRestApis --group content --limit 20
|
|
10
|
+
confluence listRestApis --method GET --write false --limit 20
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## 调用端点
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
confluence callRestApi --method GET --path '/content/{id}' --pathParams '{"id":"123456"}' --query '{"expand":"body.storage,version"}'
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
写 REST 端点仍受 `--confirm true` 和 `CONFLUENCE_DISABLE_WRITE=true` 保护。
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# 发布与下载
|
|
2
|
+
|
|
3
|
+
## Markdown 发布
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
confluence uploadMarkdown --file docs/page.md --space DEV --toc --confirm false
|
|
7
|
+
confluence uploadMarkdown --file docs/page.md --id 123456 --toc --confirm true
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
## HTML 发布
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
confluence uploadHtml --file docs/page.html --space DEV --toc --confirm false
|
|
14
|
+
confluence uploadHtml --file docs/page.html --id 123456 --toc --confirm true
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Mermaid 与附件
|
|
18
|
+
|
|
19
|
+
- 默认将 Markdown/HTML 中的 Mermaid 渲染为 PNG 附件并插入图片宏。
|
|
20
|
+
- 如需保留原代码块,使用 `--mermaid none`。
|
|
21
|
+
- 附件用 JSON 数组传入:`--attachments '["docs/a.png"]'`。
|
|
22
|
+
|
|
23
|
+
## 下载
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
confluence downloadPage --id 123456 --outputDir exports --downloadAttachments true --downloadChildren true
|
|
27
|
+
```
|