work-with-adf

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Work with ADF (Atlassian Document Format)

操作ADF(Atlassian文档格式)

Purpose

用途

This skill helps you work with Atlassian Document Format (ADF), the JSON-based format used for rich text content in Jira. Whether you're creating documents programmatically, understanding the structure, validating content, or debugging Jira API errors, this skill provides clear guidance and patterns.
本技能可帮助你操作Atlassian文档格式(ADF)——Jira中用于富文本内容的JSON格式。无论你是要以编程方式构建文档、理解ADF结构、验证内容,还是调试Jira API错误,本技能都能提供清晰的指导和实现模式。

Quick Start

快速入门

Create a simple ADF paragraph:
python
from jira_tool.formatter import JiraDocumentBuilder

doc = JiraDocumentBuilder()
doc.add_paragraph(doc.add_text("Hello, Jira!"))
adf = doc.build()
print(adf)
Output:
json
{
  "version": 1,
  "type": "doc",
  "content": [
    {
      "type": "paragraph",
      "content": [{"type": "text", "text": "Hello, Jira!"}]
    }
  ]
}
创建一个简单的ADF段落:
python
from jira_tool.formatter import JiraDocumentBuilder

doc = JiraDocumentBuilder()
doc.add_paragraph(doc.add_text("Hello, Jira!"))
adf = doc.build()
print(adf)
输出:
json
{
  "version": 1,
  "type": "doc",
  "content": [
    {
      "type": "paragraph",
      "content": [{"type": "text", "text": "Hello, Jira!"}]
    }
  ]
}

Instructions

操作步骤

Step 1: Understand ADF Structure

步骤1:理解ADF结构

ADF documents follow a strict hierarchical structure:
  1. Root Node (
    doc
    )
    : Every document must have
    version
    ,
    type: "doc"
    , and
    content
    array
  2. Block Nodes: Top-level structure (headings, paragraphs, lists, panels, code blocks, tables)
  3. Inline Nodes: Content within blocks (text, emoji, links, mentions)
  4. Marks: Formatting applied to text (bold, italic, code, strikethrough, links)
Minimal Valid Document:
json
{
  "version": 1,
  "type": "doc",
  "content": []
}
Key Principle: ADF uses a single sequential path - traversing nodes linearly produces correct reading order.
ADF文档遵循严格的层级结构:
  1. 根节点(
    doc
    :每个文档必须包含
    version
    type: "doc"
    content
    数组
  2. 块节点:顶层结构(标题、段落、列表、面板、代码块、表格)
  3. 行内节点:块内容中的元素(文本、表情符号、链接、提及)
  4. 标记:应用于文本的格式(粗体、斜体、代码、删除线、链接)
最小有效文档
json
{
  "version": 1,
  "type": "doc",
  "content": []
}
核心原则:ADF采用单一顺序路径——线性遍历节点即可得到正确的阅读顺序。

Step 2: Choose Your Approach

步骤2:选择实现方式

Pick the right tool for your use case:
Option A: Use
JiraDocumentBuilder
(Recommended)
  • Built-in Python class in
    src/jira_tool/formatter.py
  • Fluent API with method chaining
  • Handles correct nesting automatically
  • Best for: Most common tasks
Option B: Use Specialized Builders
  • EpicBuilder
    : Pre-formatted template for epics
  • IssueBuilder
    : Pre-formatted template for issues
  • Best for: Creating standardized documents
Option C: Build Raw ADF (Advanced)
  • Direct JSON dictionaries
  • Full control over structure
  • Best for: Complex or non-standard layouts
根据你的使用场景选择合适的工具:
选项A:使用
JiraDocumentBuilder
(推荐)
  • src/jira_tool/formatter.py
    中内置的Python类
  • 支持链式调用的流畅API
  • 自动处理正确的嵌套结构
  • 最适合:大多数常规任务
选项B:使用专用构建器
  • EpicBuilder
    :预格式化的史诗模板
  • IssueBuilder
    :预格式化的问题模板
  • 最适合:创建标准化文档
选项C:构建原始ADF(高级)
  • 直接使用JSON字典
  • 完全控制文档结构
  • 最适合:复杂或非标准布局

Step 3: Build Your Document

步骤3:构建你的文档

Basic Elements

基础元素

Add a heading:
python
doc.add_heading("My Epic", level=1)
doc.add_heading("Problem Statement", level=2)
Add a paragraph with formatting:
python
doc.add_paragraph(
    doc.bold("Priority: "),
    doc.add_text("P0")
)
Add lists:
python
doc.add_bullet_list(["Item 1", "Item 2", "Item 3"])
doc.add_ordered_list(["First step", "Second step"], start=1)
Add code blocks:
python
doc.add_code_block(
    'def hello():\n    print("world")',
    language="python"
)
Add panels (info, note, warning, success, error):
python
doc.add_panel("warning",
    {"type": "paragraph", "content": [doc.add_text("Important!")]}
)
Add visual elements:
python
doc.add_rule()  # Horizontal rule
emoji = doc.add_emoji(":rocket:", "🚀")
添加标题
python
doc.add_heading("My Epic", level=1)
doc.add_heading("Problem Statement", level=2)
添加带格式的段落
python
doc.add_paragraph(
    doc.bold("Priority: "),
    doc.add_text("P0")
)
添加列表
python
doc.add_bullet_list(["Item 1", "Item 2", "Item 3"])
doc.add_ordered_list(["First step", "Second step"], start=1)
添加代码块
python
doc.add_code_block(
    'def hello():\n    print("world")',
    language="python"
)
添加面板(信息、备注、警告、成功、错误):
python
doc.add_panel("warning",
    {"type": "paragraph", "content": [doc.add_text("Important!")]}
)
添加可视化元素
python
doc.add_rule()  # 水平分隔线
emoji = doc.add_emoji(":rocket:", "🚀")

Formatting Options

格式选项

Text formatting (use in text nodes):
python
doc.bold("Bold text")
doc.italic("Italic text")
doc.code("inline_code")
doc.strikethrough("Strikethrough")
doc.link("Click here", "https://example.com")
Combine formatting:
python
doc.add_paragraph(
    doc.bold("Status: "),
    doc.add_text("In Progress")
)
文本格式(用于文本节点):
python
doc.bold("Bold text")
doc.italic("Italic text")
doc.code("inline_code")
doc.strikethrough("Strikethrough")
doc.link("Click here", "https://example.com")
组合格式
python
doc.add_paragraph(
    doc.bold("Status: "),
    doc.add_text("In Progress")
)

Step 4: Build and Export

步骤4:构建并导出

Get the final ADF:
python
adf_dict = doc.build()
Use with Jira API:
python
from jira_tool.client import JiraClient

client = JiraClient()
client.create_issue(
    project="PROJ",
    issue_type="Epic",
    summary="My Epic",
    description=adf_dict  # Pass ADF directly
)
获取最终ADF
python
adf_dict = doc.build()
与Jira API配合使用
python
from jira_tool.client import JiraClient

client = JiraClient()
client.create_issue(
    project="PROJ",
    issue_type="Epic",
    summary="My Epic",
    description=adf_dict  # 直接传入ADF
)

Examples

示例

Example 1: Create a Simple Epic

示例1:创建简单史诗

python
from jira_tool.formatter import EpicBuilder

epic = EpicBuilder(
    title="User Authentication System",
    priority="P0",
    dependencies="OAuth 2.0 library",
    services="Auth Service, API Gateway"
)

epic.add_problem_statement(
    "Current authentication is insecure and lacks OAuth support"
)

epic.add_description(
    "Implement OAuth 2.0 integration with support for multiple providers"
)

epic.add_technical_details(
    requirements=[
        "Implement OAuth 2.0 flow",
        "Support Google and GitHub providers",
        "Add token refresh mechanism"
    ],
    code_example="oauth = OAuth2Handler(provider='google')",
    code_language="python"
)

epic.add_acceptance_criteria([
    "Users can log in with Google",
    "Users can log in with GitHub",
    "Tokens refresh automatically"
])

epic.add_edge_cases([
    "Handle provider outages gracefully",
    "Support token expiration",
    "Manage scope conflicts"
])

epic.add_testing_considerations([
    "Mock OAuth provider responses",
    "Test token refresh edge cases",
    "Verify scope permissions"
])

adf = epic.build()
python
from jira_tool.formatter import EpicBuilder

epic = EpicBuilder(
    title="User Authentication System",
    priority="P0",
    dependencies="OAuth 2.0 library",
    services="Auth Service, API Gateway"
)

epic.add_problem_statement(
    "Current authentication is insecure and lacks OAuth support"
)

epic.add_description(
    "Implement OAuth 2.0 integration with support for multiple providers"
)

epic.add_technical_details(
    requirements=[
        "Implement OAuth 2.0 flow",
        "Support Google and GitHub providers",
        "Add token refresh mechanism"
    ],
    code_example="oauth = OAuth2Handler(provider='google')",
    code_language="python"
)

epic.add_acceptance_criteria([
    "Users can log in with Google",
    "Users can log in with GitHub",
    "Tokens refresh automatically"
])

epic.add_edge_cases([
    "Handle provider outages gracefully",
    "Support token expiration",
    "Manage scope conflicts"
])

epic.add_testing_considerations([
    "Mock OAuth provider responses",
    "Test token refresh edge cases",
    "Verify scope permissions"
])

adf = epic.build()

Example 2: Create an Issue with Mixed Content

示例2:创建包含混合内容的问题

python
from jira_tool.formatter import IssueBuilder

issue = IssueBuilder(
    title="Implement OAuth Google Provider",
    component="Auth Service",
    story_points=13,
    epic_key="PROJ-100"
)

issue.add_description(
    "Add Google OAuth 2.0 provider support to the authentication system"
)

issue.add_implementation_details([
    "Register application with Google Cloud Console",
    "Implement OAuth callback endpoint",
    "Add token validation and refresh logic",
    "Update user profile with Google user ID"
])

issue.add_acceptance_criteria([
    "Users can authenticate with Google account",
    "Tokens are validated on each request",
    "Token refresh works correctly",
    "Tests pass with >90% coverage"
])

adf = issue.build()
python
from jira_tool.formatter import IssueBuilder

issue = IssueBuilder(
    title="Implement OAuth Google Provider",
    component="Auth Service",
    story_points=13,
    epic_key="PROJ-100"
)

issue.add_description(
    "Add Google OAuth 2.0 provider support to the authentication system"
)

issue.add_implementation_details([
    "Register application with Google Cloud Console",
    "Implement OAuth callback endpoint",
    "Add token validation and refresh logic",
    "Update user profile with Google user ID"
])

issue.add_acceptance_criteria([
    "Users can authenticate with Google account",
    "Tokens are validated on each request",
    "Token refresh works correctly",
    "Tests pass with >90% coverage"
])

adf = issue.build()

Example 3: Create Raw ADF with Full Control

示例3:创建完全可控的原始ADF

For cases where builders don't provide enough flexibility:
python
adf_document = {
    "version": 1,
    "type": "doc",
    "content": [
        {
            "type": "heading",
            "attrs": {"level": 1},
            "content": [{"type": "text", "text": "Custom Report"}]
        },
        {
            "type": "paragraph",
            "content": [
                {"type": "text", "text": "Data as of: "},
                {"type": "text", "text": "2025-11-03", "marks": [{"type": "code"}]}
            ]
        },
        {
            "type": "table",
            "attrs": {"isNumberColumnEnabled": False, "layout": "default"},
            "content": [
                {
                    "type": "tableRow",
                    "content": [
                        {
                            "type": "tableHeader",
                            "content": [
                                {"type": "paragraph", "content": [{"type": "text", "text": "Metric"}]}
                            ]
                        },
                        {
                            "type": "tableHeader",
                            "content": [
                                {"type": "paragraph", "content": [{"type": "text", "text": "Value"}]}
                            ]
                        }
                    ]
                }
            ]
        }
    ]
}
适用于构建器无法满足需求的场景:
python
adf_document = {
    "version": 1,
    "type": "doc",
    "content": [
        {
            "type": "heading",
            "attrs": {"level": 1},
            "content": [{"type": "text", "text": "Custom Report"}]
        },
        {
            "type": "paragraph",
            "content": [
                {"type": "text", "text": "Data as of: "},
                {"type": "text", "text": "2025-11-03", "marks": [{"type": "code"}]}
            ]
        },
        {
            "type": "table",
            "attrs": {"isNumberColumnEnabled": False, "layout": "default"},
            "content": [
                {
                    "type": "tableRow",
                    "content": [
                        {
                            "type": "tableHeader",
                            "content": [
                                {"type": "paragraph", "content": [{"type": "text", "text": "Metric"}]}
                            ]
                        },
                        {
                            "type": "tableHeader",
                            "content": [
                                {"type": "paragraph", "content": [{"type": "text", "text": "Value"}]}
                            ]
                        }
                    ]
                }
            ]
        }
    ]
}

Example 4: Add Emoji to Documents

示例4:为文档添加表情符号

python
from jira_tool.formatter import JiraDocumentBuilder

doc = JiraDocumentBuilder()
python
from jira_tool.formatter import JiraDocumentBuilder

doc = JiraDocumentBuilder()

Emoji in paragraph

段落中的表情符号

doc.add_paragraph( doc.add_emoji(":rocket:", "🚀"), doc.add_text(" "), doc.bold("Important Update") )
doc.add_paragraph( doc.add_emoji(":rocket:", "🚀"), doc.add_text(" "), doc.bold("Important Update") )

Emoji in heading

标题中的表情符号

doc.add_heading(doc.add_emoji(":warning:", "⚠️") + " Critical Issue", 1)
adf = doc.build()
undefined
doc.add_heading(doc.add_emoji(":warning:", "⚠️") + " Critical Issue", 1)
adf = doc.build()
undefined

Validation

验证

Validate ADF Structure

验证ADF结构

Using the Official JSON Schema:
Atlassian provides an official JSON Schema for ADF validation:
Using the Built-in Validator:
bash
undefined
使用官方JSON Schema:
Atlassian提供了用于ADF验证的官方JSON Schema:
使用内置验证器:
bash
undefined

Validate using the skill's validation script

使用本技能的验证脚本进行验证

python .claude/skills/work-with-adf/scripts/validate_adf.py your-adf.json

This validator checks:
- Root document structure (version, type, content)
- Required properties for all node types
- Valid parent-child relationships
- Attribute constraints (heading levels, panel types, etc.)
- Text mark validity
python .claude/skills/work-with-adf/scripts/validate_adf.py your-adf.json

该验证器会检查:
- 根文档结构(版本、类型、内容)
- 所有节点类型的必填属性
- 有效的父子节点关系
- 属性约束(标题级别、面板类型等)
- 文本标记的有效性

Common Validation Errors

常见验证错误

Error:
"content is required for block nodes"
  • Cause: Block node (paragraph, heading, list) missing
    content
    array
  • Fix: Add
    "content": []
    even if empty, or add child nodes
Error:
"version is required"
  • Cause: Document missing version field at root
  • Fix: Ensure
    "version": 1
    at document root
Error:
"Node type X is not allowed as child of Y"
  • Cause: Invalid nesting (e.g., heading inside paragraph)
  • Fix: Review node hierarchy - ensure block nodes only contain valid children
Error:
"attrs is required for node type X"
  • Cause: Node requires attributes but they're missing
  • Fix: Add
    attrs
    object with required properties
错误
"content is required for block nodes"
  • 原因:块节点(段落、标题、列表)缺少
    content
    数组
  • 修复:即使为空也要添加
    "content": []
    ,或者添加子节点
错误
"version is required"
  • 原因:文档根节点缺少version字段
  • 修复:确保文档根节点包含
    "version": 1
错误
"Node type X is not allowed as child of Y"
  • 原因:无效的嵌套(例如,标题嵌套在段落中)
  • 修复:检查节点层级结构——确保块节点仅包含有效的子节点
错误
"attrs is required for node type X"
  • 原因:节点需要属性但未提供
  • 修复:添加包含必填属性的
    attrs
    对象

Debug Validation Errors

调试验证错误

When Jira API returns validation errors:
  1. Print the ADF:
    import json; print(json.dumps(adf, indent=2))
  2. Check nesting: Block nodes at top level, inline nodes in blocks
  3. Validate attributes: Use
    .build()
    output as reference
  4. Test incrementally: Build document piece by piece
当Jira API返回验证错误时:
  1. 打印ADF
    import json; print(json.dumps(adf, indent=2))
  2. 检查嵌套:块节点位于顶层,行内节点位于块节点内
  3. 验证属性:以
    .build()
    的输出作为参考
  4. 增量测试:逐步构建文档

Advanced Patterns

高级模式

Pattern 1: Conditional Content

模式1:条件内容

Add content based on conditions:
python
doc = JiraDocumentBuilder()
doc.add_heading("Report", 1)

if has_dependencies:
    doc.add_heading("Dependencies", 2)
    doc.add_bullet_list(dependencies)

if has_code_example:
    doc.add_code_block(code, language)

adf = doc.build()
根据条件添加内容:
python
doc = JiraDocumentBuilder()
doc.add_heading("Report", 1)

if has_dependencies:
    doc.add_heading("Dependencies", 2)
    doc.add_bullet_list(dependencies)

if has_code_example:
    doc.add_code_block(code, language)

adf = doc.build()

Pattern 2: Reusable Templates

模式2:可复用模板

Create functions for common patterns:
python
def create_info_section(title: str, content: str) -> dict:
    """Create a titled info panel."""
    from jira_tool.formatter import JiraDocumentBuilder
    doc = JiraDocumentBuilder()
    doc.add_heading(title, 2)
    doc.add_panel("info",
        {"type": "paragraph", "content": [doc.add_text(content)]}
    )
    return doc.content[0]  # Return just the heading
    return doc.content[1]  # Return just the panel
为常见模式创建函数:
python
def create_info_section(title: str, content: str) -> dict:
    """Create a titled info panel."""
    from jira_tool.formatter import JiraDocumentBuilder
    doc = JiraDocumentBuilder()
    doc.add_heading(title, 2)
    doc.add_panel("info",
        {"type": "paragraph", "content": [doc.add_text(content)]}
    )
    return doc.content[0]  # 仅返回标题
    return doc.content[1]  # 仅返回面板

Use in larger document

在更大的文档中使用

epic = EpicBuilder("My Epic", "P0") epic.content.extend(create_info_section("Background", "...").values())
undefined
epic = EpicBuilder("My Epic", "P0") epic.content.extend(create_info_section("Background", "...").values())
undefined

Pattern 3: Multi-line Code Blocks

模式3:多行代码块

Preserve formatting in code:
python
code = """
def calculate(a, b):
    result = a + b
    return result
"""

doc.add_code_block(code.strip(), language="python")
保留代码的格式:
python
code = """
def calculate(a, b):
    result = a + b
    return result
"""

doc.add_code_block(code.strip(), language="python")

Requirements

要求

  • Python 3.8+
  • jira-tool
    package (from this repository)
  • Knowledge of JSON structure
  • Jira instance with Cloud API access
  • Python 3.8+
  • jira-tool
    包(来自本仓库)
  • JSON结构相关知识
  • 具备Cloud API访问权限的Jira实例

See Also

另请参阅

  • docs/reference/adf_reference_guide.md
    - Complete ADF node reference
  • src/jira_tool/formatter.py
    - JiraDocumentBuilder source code
  • docs/guides/jira_formatting_guide.md
    - Jira formatting best practices
  • Atlassian ADF Specification - Official documentation
  • Official ADF JSON Schema - Schema definition
  • examples/examples.md
    - Real-world use cases and patterns
  • references/reference.md
    - Complete node type reference
  • scripts/validate_adf.py
    - Validation utility
  • docs/reference/adf_reference_guide.md
    - 完整的ADF节点参考
  • src/jira_tool/formatter.py
    - JiraDocumentBuilder源代码
  • docs/guides/jira_formatting_guide.md
    - Jira格式化最佳实践
  • Atlassian ADF Specification - 官方文档
  • Official ADF JSON Schema - Schema定义
  • examples/examples.md
    - 真实场景的使用案例和模式
  • references/reference.md
    - 完整的节点类型参考
  • scripts/validate_adf.py
    - 验证工具