@cloudglab/confluence-cli 0.0.1
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/AGENTS.md +34 -0
- package/CHANGELOG.md +26 -0
- package/README.md +147 -0
- package/assets/readme/confluence-cli-hero.png +0 -0
- package/assets/readme/confluence-cli-hero.svg +7 -0
- package/assets/readme/prompts/01-cover-confluence-cli.md +61 -0
- package/dist/api/endpoints.d.ts +404 -0
- package/dist/api/endpoints.js +85 -0
- package/dist/api/index.d.ts +148 -0
- package/dist/api/index.js +143 -0
- package/dist/bin/confluence-reader.d.ts +2 -0
- package/dist/bin/confluence-reader.js +8 -0
- package/dist/bin/confluence-writer.d.ts +2 -0
- package/dist/bin/confluence-writer.js +8 -0
- package/dist/bin/confluence.d.ts +2 -0
- package/dist/bin/confluence.js +11 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +154 -0
- package/dist/core/api-provider.d.ts +3 -0
- package/dist/core/api-provider.js +13 -0
- package/dist/core/changelog.d.ts +7 -0
- package/dist/core/changelog.js +42 -0
- package/dist/core/cli-output.d.ts +16 -0
- package/dist/core/cli-output.js +318 -0
- package/dist/core/cli-registry.d.ts +20 -0
- package/dist/core/cli-registry.js +148 -0
- package/dist/core/command-groups.generated.d.ts +2 -0
- package/dist/core/command-groups.generated.js +88 -0
- package/dist/core/config.d.ts +5 -0
- package/dist/core/config.js +108 -0
- package/dist/core/http-error.d.ts +2 -0
- package/dist/core/http-error.js +4 -0
- package/dist/core/http.d.ts +28 -0
- package/dist/core/http.js +124 -0
- package/dist/core/inline-comment.d.ts +23 -0
- package/dist/core/inline-comment.js +27 -0
- package/dist/core/list-result.d.ts +14 -0
- package/dist/core/list-result.js +81 -0
- package/dist/core/manifest.d.ts +11 -0
- package/dist/core/manifest.js +42 -0
- package/dist/core/pagination.d.ts +26 -0
- package/dist/core/pagination.js +45 -0
- package/dist/core/roles.d.ts +4 -0
- package/dist/core/roles.js +12 -0
- package/dist/core/tool-registry.d.ts +9 -0
- package/dist/core/tool-registry.js +60 -0
- package/dist/core/validation.d.ts +2 -0
- package/dist/core/validation.js +10 -0
- package/dist/core/value.d.ts +2 -0
- package/dist/core/value.js +19 -0
- package/dist/core/write-guard.d.ts +25 -0
- package/dist/core/write-guard.js +49 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +3 -0
- package/dist/install.d.ts +3 -0
- package/dist/install.js +407 -0
- package/dist/manifest.json +122 -0
- package/dist/tools/attachments.d.ts +2 -0
- package/dist/tools/attachments.js +46 -0
- package/dist/tools/content.d.ts +2 -0
- package/dist/tools/content.js +45 -0
- package/dist/tools/convert.d.ts +2 -0
- package/dist/tools/convert.js +63 -0
- package/dist/tools/init.d.ts +2 -0
- package/dist/tools/init.js +24 -0
- package/dist/tools/install.d.ts +2 -0
- package/dist/tools/install.js +52 -0
- package/dist/tools/labels.d.ts +2 -0
- package/dist/tools/labels.js +22 -0
- package/dist/tools/metadata.d.ts +2 -0
- package/dist/tools/metadata.js +26 -0
- package/dist/tools/rest.d.ts +2 -0
- package/dist/tools/rest.js +52 -0
- package/dist/tools/spaces.d.ts +2 -0
- package/dist/tools/spaces.js +18 -0
- package/dist/tools/transfer.d.ts +2 -0
- package/dist/tools/transfer.js +407 -0
- package/dist/types/common.d.ts +17 -0
- package/dist/types/common.js +2 -0
- package/dist/update-probe.d.ts +2 -0
- package/dist/update-probe.js +142 -0
- package/dist/utils/mark-metadata.d.ts +9 -0
- package/dist/utils/mark-metadata.js +16 -0
- package/dist/utils/markdown.d.ts +9 -0
- package/dist/utils/markdown.js +220 -0
- package/dist/utils/result.d.ts +3 -0
- package/dist/utils/result.js +7 -0
- package/dist/version.d.ts +1 -0
- package/dist/version.js +2 -0
- package/docs/confluence-7.13.7-api.md +183 -0
- package/docs/index.html +608 -0
- package/docs/release.md +41 -0
- package/package.json +63 -0
- 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
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
import { marked } from "marked";
|
|
2
|
+
export function parseMarkdown(content, fallbackTitle) {
|
|
3
|
+
const frontmatter = {};
|
|
4
|
+
let body = content;
|
|
5
|
+
if (content.startsWith("---\n")) {
|
|
6
|
+
const end = content.indexOf("\n---", 4);
|
|
7
|
+
if (end > 0) {
|
|
8
|
+
Object.assign(frontmatter, parseSimpleYaml(content.slice(4, end)));
|
|
9
|
+
body = content.slice(end + 4).replace(/^\r?\n/, "");
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
return { frontmatter, body, title: readTitle(frontmatter, body, fallbackTitle) };
|
|
13
|
+
}
|
|
14
|
+
export function markdownToWiki(markdown) {
|
|
15
|
+
const lines = markdown.split(/\r?\n/);
|
|
16
|
+
const output = [];
|
|
17
|
+
let inCode = false;
|
|
18
|
+
let codeLang = "";
|
|
19
|
+
for (const line of lines) {
|
|
20
|
+
const fence = line.match(/^```\s*([\w-]+)?\s*$/);
|
|
21
|
+
if (fence) {
|
|
22
|
+
if (!inCode) {
|
|
23
|
+
codeLang = fence[1] ?? "";
|
|
24
|
+
output.push(codeLang ? `{code:language=${codeLang}}` : "{code}");
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
output.push("{code}");
|
|
28
|
+
codeLang = "";
|
|
29
|
+
}
|
|
30
|
+
inCode = !inCode;
|
|
31
|
+
continue;
|
|
32
|
+
}
|
|
33
|
+
if (inCode) {
|
|
34
|
+
output.push(line);
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
37
|
+
output.push(convertLine(line));
|
|
38
|
+
}
|
|
39
|
+
if (inCode)
|
|
40
|
+
output.push("{code}");
|
|
41
|
+
return output.join("\n");
|
|
42
|
+
}
|
|
43
|
+
export function markdownToStorage(markdown) {
|
|
44
|
+
const html = marked.parse(markdown, { gfm: true, breaks: false });
|
|
45
|
+
return postProcessStorageHtml(html);
|
|
46
|
+
}
|
|
47
|
+
function convertLine(line) {
|
|
48
|
+
const heading = line.match(/^(#{1,6})\s+(.+?)\s*#*\s*$/);
|
|
49
|
+
if (heading) {
|
|
50
|
+
const text = heading[2].replace(/\s*\{#[^}]+\}\s*$/, "");
|
|
51
|
+
return `h${heading[1].length}. ${convertInline(text)}`;
|
|
52
|
+
}
|
|
53
|
+
if (/^\s*[-*_]{3,}\s*$/.test(line))
|
|
54
|
+
return "----";
|
|
55
|
+
const task = line.match(/^(\s*)[-*]\s+\[([ xX])]\s+(.+)$/);
|
|
56
|
+
if (task) {
|
|
57
|
+
const level = Math.floor(task[1].length / 2) + 1;
|
|
58
|
+
return `${"*".repeat(level)} [${task[2].trim().toLowerCase() === "x" ? "x" : ""}] ${convertInline(task[3])}`;
|
|
59
|
+
}
|
|
60
|
+
const unordered = line.match(/^(\s*)[-*+]\s+(.+)$/);
|
|
61
|
+
if (unordered) {
|
|
62
|
+
const level = Math.floor(unordered[1].length / 2) + 1;
|
|
63
|
+
return `${"*".repeat(level)} ${convertInline(unordered[2])}`;
|
|
64
|
+
}
|
|
65
|
+
const ordered = line.match(/^(\s*)\d+\.\s+(.+)$/);
|
|
66
|
+
if (ordered) {
|
|
67
|
+
const level = Math.floor(ordered[1].length / 2) + 1;
|
|
68
|
+
return `${"#".repeat(level)} ${convertInline(ordered[2])}`;
|
|
69
|
+
}
|
|
70
|
+
const macroQuote = line.match(/^>\s*\*\*(info|tip|note|warning):\*\*\s*(.+)$/i);
|
|
71
|
+
if (macroQuote)
|
|
72
|
+
return `{${macroQuote[1].toLowerCase()}}\n${convertInline(macroQuote[2])}\n{${macroQuote[1].toLowerCase()}}`;
|
|
73
|
+
const quote = line.match(/^>\s*(.+)$/);
|
|
74
|
+
if (quote)
|
|
75
|
+
return `bq. ${convertInline(quote[1])}`;
|
|
76
|
+
if (isMarkdownTableSeparator(line))
|
|
77
|
+
return "";
|
|
78
|
+
if (line.trim().startsWith("|") && line.trim().endsWith("|")) {
|
|
79
|
+
return line.split("|").slice(1, -1).map((cell) => convertInline(cell.trim())).join(" | ");
|
|
80
|
+
}
|
|
81
|
+
return convertInline(line);
|
|
82
|
+
}
|
|
83
|
+
function convertInline(text) {
|
|
84
|
+
return text
|
|
85
|
+
.replace(/!\[([^\]]*)]\(([^)]+)\)/g, (_match, alt, url) => `!${url}|alt=${alt}!`)
|
|
86
|
+
.replace(/\[([^\]]+)]\(([^)]+)\)/g, "[$1|$2]")
|
|
87
|
+
.replace(/`([^`]+)`/g, "{{$1}}")
|
|
88
|
+
.replace(/\*\*([^*]+)\*\*/g, "*$1*")
|
|
89
|
+
.replace(/__([^_]+)__/g, "*$1*")
|
|
90
|
+
.replace(/~~([^~]+)~~/g, "-$1-")
|
|
91
|
+
.replace(/(^|\s)\*([^*\s][^*]*?)\*(?=\s|$)/g, "$1_$2_");
|
|
92
|
+
}
|
|
93
|
+
function parseSimpleYaml(yaml) {
|
|
94
|
+
const result = {};
|
|
95
|
+
for (const line of yaml.split(/\r?\n/)) {
|
|
96
|
+
const match = line.match(/^([A-Za-z0-9_.-]+):\s*(.*)$/);
|
|
97
|
+
if (!match)
|
|
98
|
+
continue;
|
|
99
|
+
const value = match[2].trim().replace(/^['"]|['"]$/g, "");
|
|
100
|
+
result[match[1]] = value;
|
|
101
|
+
}
|
|
102
|
+
return result;
|
|
103
|
+
}
|
|
104
|
+
function readTitle(frontmatter, body, fallbackTitle) {
|
|
105
|
+
if (typeof frontmatter.title === "string" && frontmatter.title.trim())
|
|
106
|
+
return frontmatter.title.trim();
|
|
107
|
+
const h1 = body.match(/^#\s+(.+)$/m);
|
|
108
|
+
if (h1)
|
|
109
|
+
return h1[1].trim();
|
|
110
|
+
return fallbackTitle;
|
|
111
|
+
}
|
|
112
|
+
function isMarkdownTableSeparator(line) {
|
|
113
|
+
return /^\s*\|?\s*:?-{3,}:?\s*(\|\s*:?-{3,}:?\s*)+\|?\s*$/.test(line);
|
|
114
|
+
}
|
|
115
|
+
function escapeHtml(value) {
|
|
116
|
+
return value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
117
|
+
}
|
|
118
|
+
export function postProcessStorageHtml(html) {
|
|
119
|
+
return html
|
|
120
|
+
.replace(/<pre><code(?: class="language-([^"]+)")?>([\s\S]*?)<\/code><\/pre>/g, (_match, language, code) => buildCodeMacro(language, decodeHtml(code)))
|
|
121
|
+
.replace(/<ul>\s*((?:<li><input(?: checked="")? disabled="" type="checkbox">\s*[\s\S]*?<\/li>\s*)+)\s*<\/ul>/g, (_match, items) => buildTaskList(items))
|
|
122
|
+
.replace(/<img\s+([^>]*?)\s*\/?>(?!<\/img>)/g, (_match, attrs) => buildImageMacro(attrs))
|
|
123
|
+
.replace(/<hr>/g, "<hr />")
|
|
124
|
+
.replace(/<p>\s*<\/p>/g, "")
|
|
125
|
+
.replace(/<p>(MERMAID_DRAWIO_PLACEHOLDER_\d+)<\/p>/g, "<p>$1</p>");
|
|
126
|
+
}
|
|
127
|
+
function buildCodeMacro(language, code) {
|
|
128
|
+
const lang = normalizeCodeMacroLanguage(language);
|
|
129
|
+
const params = ["<ac:structured-macro ac:name=\"code\" ac:schema-version=\"1\" data-layout=\"default\">"];
|
|
130
|
+
if (lang)
|
|
131
|
+
params.push(`<ac:parameter ac:name=\"language\">${escapeXml(lang)}</ac:parameter>`);
|
|
132
|
+
params.push(`<ac:plain-text-body><![CDATA[${code}]]></ac:plain-text-body>`);
|
|
133
|
+
params.push("</ac:structured-macro>");
|
|
134
|
+
return params.join("");
|
|
135
|
+
}
|
|
136
|
+
function normalizeCodeMacroLanguage(language) {
|
|
137
|
+
const value = language?.trim().toLowerCase();
|
|
138
|
+
if (!value)
|
|
139
|
+
return undefined;
|
|
140
|
+
const aliases = {
|
|
141
|
+
js: "js",
|
|
142
|
+
jsx: "js",
|
|
143
|
+
ts: "js",
|
|
144
|
+
tsx: "js",
|
|
145
|
+
shell: "bash",
|
|
146
|
+
sh: "bash",
|
|
147
|
+
zsh: "bash",
|
|
148
|
+
yml: "yml",
|
|
149
|
+
yaml: "yml",
|
|
150
|
+
xml: "xml",
|
|
151
|
+
html: "xml",
|
|
152
|
+
md: "text",
|
|
153
|
+
markdown: "text",
|
|
154
|
+
json: "text",
|
|
155
|
+
jsonc: "text",
|
|
156
|
+
csharp: "c#",
|
|
157
|
+
python: "py",
|
|
158
|
+
};
|
|
159
|
+
const normalized = aliases[value] ?? value;
|
|
160
|
+
const supported = new Set([
|
|
161
|
+
"actionscript3",
|
|
162
|
+
"applescript",
|
|
163
|
+
"bash",
|
|
164
|
+
"c",
|
|
165
|
+
"c#",
|
|
166
|
+
"coldfusion",
|
|
167
|
+
"cpp",
|
|
168
|
+
"css",
|
|
169
|
+
"delphi",
|
|
170
|
+
"diff",
|
|
171
|
+
"erl",
|
|
172
|
+
"groovy",
|
|
173
|
+
"java",
|
|
174
|
+
"jfx",
|
|
175
|
+
"js",
|
|
176
|
+
"perl",
|
|
177
|
+
"php",
|
|
178
|
+
"powershell",
|
|
179
|
+
"py",
|
|
180
|
+
"ruby",
|
|
181
|
+
"sass",
|
|
182
|
+
"scala",
|
|
183
|
+
"sql",
|
|
184
|
+
"text",
|
|
185
|
+
"vb",
|
|
186
|
+
"xml",
|
|
187
|
+
"yml",
|
|
188
|
+
]);
|
|
189
|
+
return supported.has(normalized) ? normalized : undefined;
|
|
190
|
+
}
|
|
191
|
+
function buildTaskList(items) {
|
|
192
|
+
const taskItems = [];
|
|
193
|
+
const itemRegex = /<li><input(?: checked="")? disabled="" type="checkbox">\s*([\s\S]*?)<\/li>/g;
|
|
194
|
+
let match = itemRegex.exec(items);
|
|
195
|
+
while (match) {
|
|
196
|
+
const complete = /checked=""/i.test(match[0]);
|
|
197
|
+
taskItems.push(`<ac:task><ac:task-status>${complete ? "complete" : "incomplete"}</ac:task-status><ac:task-body>${match[1]}</ac:task-body></ac:task>`);
|
|
198
|
+
match = itemRegex.exec(items);
|
|
199
|
+
}
|
|
200
|
+
return taskItems.length > 0 ? `<ac:task-list>${taskItems.join("")}</ac:task-list>` : `<ul>${items}</ul>`;
|
|
201
|
+
}
|
|
202
|
+
function buildImageMacro(attrs) {
|
|
203
|
+
const src = attrs.match(/src="([^"]+)"/i)?.[1];
|
|
204
|
+
const alt = attrs.match(/alt="([^"]*)"/i)?.[1] ?? "";
|
|
205
|
+
if (!src)
|
|
206
|
+
return `<img ${attrs} />`;
|
|
207
|
+
return `<ac:image>${src.startsWith("http") ? `<ri:url ri:value="${escapeXml(src)}" />` : `<ri:attachment ri:filename="${escapeXml(src)}" />`}${alt ? `<ac:parameter ac:name="alt">${escapeXml(alt)}</ac:parameter>` : ""}</ac:image>`;
|
|
208
|
+
}
|
|
209
|
+
function decodeHtml(value) {
|
|
210
|
+
return value
|
|
211
|
+
.replace(/</g, "<")
|
|
212
|
+
.replace(/>/g, ">")
|
|
213
|
+
.replace(/&/g, "&")
|
|
214
|
+
.replace(/"/g, '"')
|
|
215
|
+
.replace(/'/g, "'");
|
|
216
|
+
}
|
|
217
|
+
function escapeXml(value) {
|
|
218
|
+
return value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/\"/g, """).replace(/'/g, "'");
|
|
219
|
+
}
|
|
220
|
+
//# sourceMappingURL=markdown.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const VERSION = "0.0.1";
|
package/dist/version.js
ADDED
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
# Confluence 7.13.7 REST API 与 PAT 稳定基线
|
|
2
|
+
|
|
3
|
+
本项目优先面向 Atlassian Confluence Server/Data Center 7.13.7。REST API 清单从官方文档提取:`https://docs.atlassian.com/ConfluenceServer/rest/7.13.7/`。
|
|
4
|
+
|
|
5
|
+
## Personal Access Token
|
|
6
|
+
|
|
7
|
+
Confluence 7.13.7 支持 Personal Access Token(PAT)。调用 REST API 时使用 Bearer 认证:
|
|
8
|
+
|
|
9
|
+
```http
|
|
10
|
+
Authorization: Bearer <personal-access-token>
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
CLI 优先读取:
|
|
14
|
+
|
|
15
|
+
- `CONFLUENCE_PAT`
|
|
16
|
+
- `CONFLUENCE_PERSONAL_TOKEN`
|
|
17
|
+
|
|
18
|
+
Basic Auth 仅作为兼容模式:
|
|
19
|
+
|
|
20
|
+
- `CONFLUENCE_USERNAME`
|
|
21
|
+
- `CONFLUENCE_PASSWORD` 或 `CONFLUENCE_API_TOKEN`
|
|
22
|
+
|
|
23
|
+
这些 REST API 都可以用 PAT Bearer 调用;实际是否成功取决于 PAT 所属用户权限、空间权限、全局权限和实例配置。
|
|
24
|
+
|
|
25
|
+
## 文档更新稳定链路
|
|
26
|
+
|
|
27
|
+
稳定更新页面不要直接盲写,必须走三步:
|
|
28
|
+
|
|
29
|
+
1. `GET /rest/api/content/{id}?expand=body.storage,version,space,ancestors` 读取当前版本。
|
|
30
|
+
2. 生成 Confluence `storage` 或 `wiki` body。
|
|
31
|
+
3. `PUT /rest/api/content/{contentId}` 写入,`version.number` 必须递增。
|
|
32
|
+
|
|
33
|
+
建议默认写 `body.storage`,`wiki` 仅作为兼容输入格式保留。
|
|
34
|
+
|
|
35
|
+
## 7.13.7 官方 REST API 全量端点
|
|
36
|
+
|
|
37
|
+
以下端点从官方 7.13.7 页面解析得到;页面中的示例路径 `PUT /rest/api/content/456` 已排除,保留模板端点 `PUT /rest/api/content/{contentId}`。
|
|
38
|
+
|
|
39
|
+
| 方法 | 端点 |
|
|
40
|
+
| --- | --- |
|
|
41
|
+
| `GET` | `/rest/api/accessmode` |
|
|
42
|
+
| `GET` | `/rest/api/audit` |
|
|
43
|
+
| `POST` | `/rest/api/audit` |
|
|
44
|
+
| `GET` | `/rest/api/audit/export` |
|
|
45
|
+
| `GET` | `/rest/api/audit/retention` |
|
|
46
|
+
| `PUT` | `/rest/api/audit/retention` |
|
|
47
|
+
| `GET` | `/rest/api/audit/since` |
|
|
48
|
+
| `GET` | `/rest/api/content` |
|
|
49
|
+
| `POST` | `/rest/api/content` |
|
|
50
|
+
| `GET` | `/rest/api/content/search` |
|
|
51
|
+
| `POST` | `/rest/api/content/blueprint/instance/{draftId}` |
|
|
52
|
+
| `PUT` | `/rest/api/content/blueprint/instance/{draftId}` |
|
|
53
|
+
| `PUT` | `/rest/api/content/{contentId}` |
|
|
54
|
+
| `GET` | `/rest/api/content/{id}` |
|
|
55
|
+
| `DELETE` | `/rest/api/content/{id}` |
|
|
56
|
+
| `GET` | `/rest/api/content/{id}/child` |
|
|
57
|
+
| `GET` | `/rest/api/content/{id}/child/attachment` |
|
|
58
|
+
| `POST` | `/rest/api/content/{id}/child/attachment` |
|
|
59
|
+
| `PUT` | `/rest/api/content/{id}/child/attachment/{attachmentId}` |
|
|
60
|
+
| `POST` | `/rest/api/content/{id}/child/attachment/{attachmentId}/data` |
|
|
61
|
+
| `GET` | `/rest/api/content/{id}/child/comment` |
|
|
62
|
+
| `GET` | `/rest/api/content/{id}/child/{type}` |
|
|
63
|
+
| `GET` | `/rest/api/content/{id}/descendant` |
|
|
64
|
+
| `GET` | `/rest/api/content/{id}/descendant/{type}` |
|
|
65
|
+
| `GET` | `/rest/api/content/{id}/history` |
|
|
66
|
+
| `GET` | `/rest/api/content/{id}/history/{version}/macro/hash/{hash}` |
|
|
67
|
+
| `GET` | `/rest/api/content/{id}/history/{version}/macro/id/{macroId}` |
|
|
68
|
+
| `GET` | `/rest/api/content/{id}/label` |
|
|
69
|
+
| `POST` | `/rest/api/content/{id}/label` |
|
|
70
|
+
| `DELETE` | `/rest/api/content/{id}/label` |
|
|
71
|
+
| `DELETE` | `/rest/api/content/{id}/label/{label}` |
|
|
72
|
+
| `GET` | `/rest/api/content/{id}/property` |
|
|
73
|
+
| `POST` | `/rest/api/content/{id}/property` |
|
|
74
|
+
| `POST` | `/rest/api/content/{id}/property/{key}` |
|
|
75
|
+
| `GET` | `/rest/api/content/{id}/property/{key}` |
|
|
76
|
+
| `PUT` | `/rest/api/content/{id}/property/{key}` |
|
|
77
|
+
| `DELETE` | `/rest/api/content/{id}/property/{key}` |
|
|
78
|
+
| `GET` | `/rest/api/content/{id}/restriction/byOperation` |
|
|
79
|
+
| `GET` | `/rest/api/content/{id}/restriction/byOperation/{operationKey}` |
|
|
80
|
+
| `POST` | `/rest/api/contentbody/convert/{to}` |
|
|
81
|
+
| `GET` | `/rest/api/group` |
|
|
82
|
+
| `GET` | `/rest/api/group/{groupName}` |
|
|
83
|
+
| `GET` | `/rest/api/group/{groupName}/member` |
|
|
84
|
+
| `GET` | `/rest/api/longtask` |
|
|
85
|
+
| `GET` | `/rest/api/longtask/{id}` |
|
|
86
|
+
| `GET` | `/rest/api/search` |
|
|
87
|
+
| `GET` | `/rest/api/space` |
|
|
88
|
+
| `POST` | `/rest/api/space` |
|
|
89
|
+
| `POST` | `/rest/api/space/_private` |
|
|
90
|
+
| `GET` | `/rest/api/space/{spaceKey}` |
|
|
91
|
+
| `PUT` | `/rest/api/space/{spaceKey}` |
|
|
92
|
+
| `DELETE` | `/rest/api/space/{spaceKey}` |
|
|
93
|
+
| `GET` | `/rest/api/space/{spaceKey}/content` |
|
|
94
|
+
| `GET` | `/rest/api/space/{spaceKey}/content/{type}` |
|
|
95
|
+
| `GET` | `/rest/api/space/{spaceKey}/property` |
|
|
96
|
+
| `POST` | `/rest/api/space/{spaceKey}/property` |
|
|
97
|
+
| `POST` | `/rest/api/space/{spaceKey}/property/{key}` |
|
|
98
|
+
| `GET` | `/rest/api/space/{spaceKey}/property/{key}` |
|
|
99
|
+
| `PUT` | `/rest/api/space/{spaceKey}/property/{key}` |
|
|
100
|
+
| `DELETE` | `/rest/api/space/{spaceKey}/property/{key}` |
|
|
101
|
+
| `GET` | `/rest/api/user` |
|
|
102
|
+
| `GET` | `/rest/api/user/anonymous` |
|
|
103
|
+
| `GET` | `/rest/api/user/current` |
|
|
104
|
+
| `GET` | `/rest/api/user/memberof` |
|
|
105
|
+
| `POST` | `/rest/api/user/watch/content/{contentId}` |
|
|
106
|
+
| `GET` | `/rest/api/user/watch/content/{contentId}` |
|
|
107
|
+
| `DELETE` | `/rest/api/user/watch/content/{contentId}` |
|
|
108
|
+
| `POST` | `/rest/api/user/watch/space/{spaceKey}` |
|
|
109
|
+
| `GET` | `/rest/api/user/watch/space/{spaceKey}` |
|
|
110
|
+
| `DELETE` | `/rest/api/user/watch/space/{spaceKey}` |
|
|
111
|
+
| `GET` | `/rest/api/webhooks` |
|
|
112
|
+
| `POST` | `/rest/api/webhooks` |
|
|
113
|
+
| `GET` | `/rest/api/webhooks/{webhookId}` |
|
|
114
|
+
| `PUT` | `/rest/api/webhooks/{webhookId}` |
|
|
115
|
+
| `DELETE` | `/rest/api/webhooks/{webhookId}` |
|
|
116
|
+
| `GET` | `/rest/api/webhooks/{webhookId}/latest` |
|
|
117
|
+
| `GET` | `/rest/api/webhooks/{webhookId}/statistics` |
|
|
118
|
+
| `GET` | `/rest/api/webhooks/{webhookId}/statistics/summary` |
|
|
119
|
+
| `POST` | `/rest/api/webhooks/test` |
|
|
120
|
+
|
|
121
|
+
## 稳定 CLI 优先实现范围
|
|
122
|
+
|
|
123
|
+
第一阶段只实现与文档维护直接相关的接口:
|
|
124
|
+
|
|
125
|
+
- 内容读取、搜索、创建、更新、删除。
|
|
126
|
+
- 子页面、附件、标签、内容属性。
|
|
127
|
+
- 空间读取与空间内容查询。
|
|
128
|
+
- `GET /rest/api/user/current` 用于 token 校验。
|
|
129
|
+
- `POST /rest/api/contentbody/convert/{to}` 用于服务端 body 转换。
|
|
130
|
+
|
|
131
|
+
审计、用户 watch、webhooks、longtask、group 等接口先作为已知开放能力记录,不默认纳入文档上传主链路。
|
|
132
|
+
|
|
133
|
+
## 与 confluence-skill 能力对应关系
|
|
134
|
+
|
|
135
|
+
以下只列 `confluence-skill` 中已有明确能力能对应上的 REST API:
|
|
136
|
+
|
|
137
|
+
| confluence-skill 能力 | 对应 REST API |
|
|
138
|
+
| --- | --- |
|
|
139
|
+
| `confluence_search` / CQL 搜索 | `GET /rest/api/content/search`, `GET /rest/api/search` |
|
|
140
|
+
| `confluence_get_page` | `GET /rest/api/content/{id}`, `GET /rest/api/content` |
|
|
141
|
+
| `confluence_create_page` | `POST /rest/api/content` |
|
|
142
|
+
| `confluence_update_page` | `PUT /rest/api/content/{contentId}` |
|
|
143
|
+
| `confluence_delete_page` | `DELETE /rest/api/content/{id}` |
|
|
144
|
+
| `confluence_get_page_children` | `GET /rest/api/content/{id}/child`, `GET /rest/api/content/{id}/child/{type}` |
|
|
145
|
+
| `confluence_get_comments` | `GET /rest/api/content/{id}/child/comment` |
|
|
146
|
+
| `confluence_add_comment` | `POST /rest/api/content` |
|
|
147
|
+
| `confluence_get_labels` | `GET /rest/api/content/{id}/label` |
|
|
148
|
+
| `confluence_add_label` | `POST /rest/api/content/{id}/label` |
|
|
149
|
+
| 页面图片和附件处理 | `GET /rest/api/content/{id}/child/attachment`, `POST /rest/api/content/{id}/child/attachment`, `PUT /rest/api/content/{id}/child/attachment/{attachmentId}`, `POST /rest/api/content/{id}/child/attachment/{attachmentId}/data` |
|
|
150
|
+
| Markdown 上传页面 | `POST /rest/api/content`, `PUT /rest/api/content/{contentId}`, `POST /rest/api/content/{id}/child/attachment` |
|
|
151
|
+
| 下载页面到 Markdown | `GET /rest/api/content/{id}`, `GET /rest/api/content/{id}/child/attachment`, `GET /rest/api/content/{id}/child/{type}` |
|
|
152
|
+
| mark metadata 中的空间和标签 | `GET /rest/api/space`, `GET /rest/api/space/{spaceKey}`, `GET /rest/api/content/{id}/label`, `POST /rest/api/content/{id}/label` |
|
|
153
|
+
|
|
154
|
+
## 已转换为 TS CLI 的语义化命令
|
|
155
|
+
|
|
156
|
+
当前 CLI 不只保留 `callRestApi` 通用调用,也把 MCP/Python 常用能力转换成稳定命令:
|
|
157
|
+
|
|
158
|
+
| 能力 | TS CLI 命令 |
|
|
159
|
+
| --- | --- |
|
|
160
|
+
| 搜索内容 | `searchContent` |
|
|
161
|
+
| 读取内容 | `getContent`, `findContent` |
|
|
162
|
+
| 创建/更新 Markdown 页面 | `uploadMarkdown` |
|
|
163
|
+
| 删除内容 | `deleteContent` |
|
|
164
|
+
| 读取子页 | `getPageChildren` |
|
|
165
|
+
| 评论 | `getComments`, `addComment` |
|
|
166
|
+
| 标签 | `getLabels`, `addLabels`, `deleteLabel` |
|
|
167
|
+
| 附件 | `listAttachments`, `uploadAttachment`, `updateAttachment`, `downloadAttachment` |
|
|
168
|
+
| 下载页面 | `downloadPage`,支持 `downloadAttachments` 和 `downloadChildren` |
|
|
169
|
+
| 空间与用户校验 | `listSpaces`, `getSpace`, `getCurrentUser` |
|
|
170
|
+
| body 转换 | `convertContentBody` |
|
|
171
|
+
| mark metadata | `generateMarkMetadata` |
|
|
172
|
+
|
|
173
|
+
## 当前 skill 常见问题与 CLI 约束
|
|
174
|
+
|
|
175
|
+
通用 Confluence skill 经常更新失败,通常不是搜索问题,而是写入链路不稳定:
|
|
176
|
+
|
|
177
|
+
- Cloud 与 Server/Data Center 认证混用:7.13.7 PAT 应使用 Bearer,不是 Cloud Basic API Token。
|
|
178
|
+
- 未先读取当前 `version.number`,直接 PUT 导致版本冲突。
|
|
179
|
+
- Markdown 直接转 HTML 不等于 Confluence storage,复杂宏、附件、图片容易丢。
|
|
180
|
+
- 未明确 parent/ancestor,更新时可能移动页面或创建到错误位置。
|
|
181
|
+
- 未区分正文、附件、标签、属性,导致“一次上传”行为不可预测。
|
|
182
|
+
|
|
183
|
+
CLI 稳定版应坚持:认证固定、端点固定、写入前读取、写入需要确认、复杂能力分阶段实现。
|