jira-agile
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseJira Agile Skill
Jira Agile Skill
Purpose
用途
Manage Jira Agile boards and sprints - list boards, manage sprints, move issues to sprints.
管理Jira Agile看板与Sprint——列出看板、管理Sprint、将问题移入/移出Sprint。
When to Use
使用场景
- Listing Scrum/Kanban boards
- Managing sprints (create, start, end)
- Moving issues to/from sprints
- Getting sprint issues
- 列出Scrum/Kanban看板
- 管理Sprint(创建、启动、结束)
- 将问题移入/移出Sprint
- 获取Sprint中的问题
Prerequisites
前提条件
- Authenticated JiraClient (see jira-auth skill)
- Board/sprint management permissions
- Note: Uses NOT
/rest/agile/1.0//rest/api/3/
- 已认证的JiraClient(详见jira-auth技能)
- 拥有看板/Sprint管理权限
- 注意:使用而非
/rest/agile/1.0//rest/api/3/
Implementation Pattern
实现模式
Step 1: Create Agile Client Extension
步骤1:创建Agile客户端扩展
typescript
class JiraAgileClient extends JiraClient {
async agileRequest<T>(path: string, options: RequestInit = {}): Promise<T> {
const url = `${this.baseUrl}/rest/agile/1.0${path}`;
const response = await fetch(url, {
...options,
headers: { ...this.headers, ...options.headers },
});
if (!response.ok) {
const error = await response.json().catch(() => ({}));
throw new Error(`Jira Agile API error: ${response.status} - ${JSON.stringify(error)}`);
}
return response.json();
}
}typescript
class JiraAgileClient extends JiraClient {
async agileRequest<T>(path: string, options: RequestInit = {}): Promise<T> {
const url = `${this.baseUrl}/rest/agile/1.0${path}`;
const response = await fetch(url, {
...options,
headers: { ...this.headers, ...options.headers },
});
if (!response.ok) {
const error = await response.json().catch(() => ({}));
throw new Error(`Jira Agile API error: ${response.status} - ${JSON.stringify(error)}`);
}
return response.json();
}
}Step 2: List Boards
步骤2:列出看板
typescript
interface Board {
id: number;
self: string;
name: string;
type: 'scrum' | 'kanban';
projectKey?: string;
}
interface BoardsResponse {
values: Board[];
startAt: number;
maxResults: number;
total: number;
isLast: boolean;
}
async function listBoards(
client: JiraAgileClient,
options: {
type?: 'scrum' | 'kanban';
projectKeyOrId?: string;
maxResults?: number;
} = {}
): Promise<Board[]> {
const params = new URLSearchParams();
if (options.type) params.set('type', options.type);
if (options.projectKeyOrId) params.set('projectKeyOrId', options.projectKeyOrId);
if (options.maxResults) params.set('maxResults', String(options.maxResults));
const response = await client.agileRequest<BoardsResponse>(
`/board?${params.toString()}`
);
return response.values;
}typescript
interface Board {
id: number;
self: string;
name: string;
type: 'scrum' | 'kanban';
projectKey?: string;
}
interface BoardsResponse {
values: Board[];
startAt: number;
maxResults: number;
total: number;
isLast: boolean;
}
async function listBoards(
client: JiraAgileClient,
options: {
type?: 'scrum' | 'kanban';
projectKeyOrId?: string;
maxResults?: number;
} = {}
): Promise<Board[]> {
const params = new URLSearchParams();
if (options.type) params.set('type', options.type);
if (options.projectKeyOrId) params.set('projectKeyOrId', options.projectKeyOrId);
if (options.maxResults) params.set('maxResults', String(options.maxResults));
const response = await client.agileRequest<BoardsResponse>(
`/board?${params.toString()}`
);
return response.values;
}Step 3: Get Board Sprints
步骤3:获取看板中的Sprint
typescript
interface Sprint {
id: number;
self: string;
state: 'future' | 'active' | 'closed';
name: string;
startDate?: string;
endDate?: string;
goal?: string;
}
async function getBoardSprints(
client: JiraAgileClient,
boardId: number,
state?: 'future' | 'active' | 'closed' | string
): Promise<Sprint[]> {
const params = state ? `?state=${state}` : '';
const response = await client.agileRequest<{ values: Sprint[] }>(
`/board/${boardId}/sprint${params}`
);
return response.values;
}typescript
interface Sprint {
id: number;
self: string;
state: 'future' | 'active' | 'closed';
name: string;
startDate?: string;
endDate?: string;
goal?: string;
}
async function getBoardSprints(
client: JiraAgileClient,
boardId: number,
state?: 'future' | 'active' | 'closed' | string
): Promise<Sprint[]> {
const params = state ? `?state=${state}` : '';
const response = await client.agileRequest<{ values: Sprint[] }>(
`/board/${boardId}/sprint${params}`
);
return response.values;
}Step 4: Get Sprint Issues
步骤4:获取Sprint中的问题
typescript
interface SprintIssue {
id: string;
key: string;
self: string;
fields: {
summary: string;
status: { name: string };
assignee?: { displayName: string };
};
}
async function getSprintIssues(
client: JiraAgileClient,
sprintId: number,
options: {
maxResults?: number;
startAt?: number;
} = {}
): Promise<SprintIssue[]> {
const params = new URLSearchParams();
if (options.maxResults) params.set('maxResults', String(options.maxResults));
if (options.startAt) params.set('startAt', String(options.startAt));
const response = await client.agileRequest<{ issues: SprintIssue[] }>(
`/sprint/${sprintId}/issue?${params.toString()}`
);
return response.issues;
}typescript
interface SprintIssue {
id: string;
key: string;
self: string;
fields: {
summary: string;
status: { name: string };
assignee?: { displayName: string };
};
}
async function getSprintIssues(
client: JiraAgileClient,
sprintId: number,
options: {
maxResults?: number;
startAt?: number;
} = {}
): Promise<SprintIssue[]> {
const params = new URLSearchParams();
if (options.maxResults) params.set('maxResults', String(options.maxResults));
if (options.startAt) params.set('startAt', String(options.startAt));
const response = await client.agileRequest<{ issues: SprintIssue[] }>(
`/sprint/${sprintId}/issue?${params.toString()}`
);
return response.issues;
}Step 5: Move Issues to Sprint
步骤5:将问题移入Sprint
typescript
async function moveIssuesToSprint(
client: JiraAgileClient,
sprintId: number,
issueKeys: string[],
options: {
rankBeforeIssue?: string;
rankAfterIssue?: string;
} = {}
): Promise<void> {
await client.agileRequest(`/sprint/${sprintId}/issue`, {
method: 'POST',
body: JSON.stringify({
issues: issueKeys,
...options,
}),
});
}typescript
async function moveIssuesToSprint(
client: JiraAgileClient,
sprintId: number,
issueKeys: string[],
options: {
rankBeforeIssue?: string;
rankAfterIssue?: string;
} = {}
): Promise<void> {
await client.agileRequest(`/sprint/${sprintId}/issue`, {
method: 'POST',
body: JSON.stringify({
issues: issueKeys,
...options,
}),
});
}Step 6: Create Sprint
步骤6:创建Sprint
typescript
interface CreateSprintInput {
name: string;
boardId: number;
startDate?: string;
endDate?: string;
goal?: string;
}
async function createSprint(
client: JiraAgileClient,
input: CreateSprintInput
): Promise<Sprint> {
return client.agileRequest<Sprint>('/sprint', {
method: 'POST',
body: JSON.stringify({
name: input.name,
originBoardId: input.boardId,
startDate: input.startDate,
endDate: input.endDate,
goal: input.goal,
}),
});
}typescript
interface CreateSprintInput {
name: string;
boardId: number;
startDate?: string;
endDate?: string;
goal?: string;
}
async function createSprint(
client: JiraAgileClient,
input: CreateSprintInput
): Promise<Sprint> {
return client.agileRequest<Sprint>('/sprint', {
method: 'POST',
body: JSON.stringify({
name: input.name,
originBoardId: input.boardId,
startDate: input.startDate,
endDate: input.endDate,
goal: input.goal,
}),
});
}Step 7: Start/End Sprint
步骤7:启动/结束Sprint
typescript
async function startSprint(
client: JiraAgileClient,
sprintId: number,
startDate: string,
endDate: string
): Promise<void> {
await client.agileRequest(`/sprint/${sprintId}`, {
method: 'POST',
body: JSON.stringify({
state: 'active',
startDate,
endDate,
}),
});
}
async function endSprint(
client: JiraAgileClient,
sprintId: number
): Promise<void> {
await client.agileRequest(`/sprint/${sprintId}`, {
method: 'POST',
body: JSON.stringify({
state: 'closed',
}),
});
}typescript
async function startSprint(
client: JiraAgileClient,
sprintId: number,
startDate: string,
endDate: string
): Promise<void> {
await client.agileRequest(`/sprint/${sprintId}`, {
method: 'POST',
body: JSON.stringify({
state: 'active',
startDate,
endDate,
}),
});
}
async function endSprint(
client: JiraAgileClient,
sprintId: number
): Promise<void> {
await client.agileRequest(`/sprint/${sprintId}`, {
method: 'POST',
body: JSON.stringify({
state: 'closed',
}),
});
}curl Examples
curl示例
List Boards
列出看板
bash
curl -X GET "https://mycompany.atlassian.net/rest/agile/1.0/board?type=scrum" \
-H "Authorization: Basic $(echo -n 'email:token' | base64)" \
-H "Accept: application/json"bash
curl -X GET "https://mycompany.atlassian.net/rest/agile/1.0/board?type=scrum" \
-H "Authorization: Basic $(echo -n 'email:token' | base64)" \
-H "Accept: application/json"Get Board Sprints
获取看板中的Sprint
bash
curl -X GET "https://mycompany.atlassian.net/rest/agile/1.0/board/1/sprint?state=active,future" \
-H "Authorization: Basic $(echo -n 'email:token' | base64)" \
-H "Accept: application/json"bash
curl -X GET "https://mycompany.atlassian.net/rest/agile/1.0/board/1/sprint?state=active,future" \
-H "Authorization: Basic $(echo -n 'email:token' | base64)" \
-H "Accept: application/json"Move Issues to Sprint
将问题移入Sprint
bash
curl -X POST "https://mycompany.atlassian.net/rest/agile/1.0/sprint/1/issue" \
-H "Authorization: Basic $(echo -n 'email:token' | base64)" \
-H "Content-Type: application/json" \
-d '{"issues": ["PROJ-123", "PROJ-124"]}'bash
curl -X POST "https://mycompany.atlassian.net/rest/agile/1.0/sprint/1/issue" \
-H "Authorization: Basic $(echo -n 'email:token' | base64)" \
-H "Content-Type: application/json" \
-d '{"issues": ["PROJ-123", "PROJ-124"]}'Create Sprint
创建Sprint
bash
curl -X POST "https://mycompany.atlassian.net/rest/agile/1.0/sprint" \
-H "Authorization: Basic $(echo -n 'email:token' | base64)" \
-H "Content-Type: application/json" \
-d '{"name": "Sprint 1", "originBoardId": 1, "goal": "Complete MVP"}'bash
curl -X POST "https://mycompany.atlassian.net/rest/agile/1.0/sprint" \
-H "Authorization: Basic $(echo -n 'email:token' | base64)" \
-H "Content-Type: application/json" \
-d '{"name": "Sprint 1", "originBoardId": 1, "goal": "Complete MVP"}'API Endpoints Summary
API端点汇总
| Operation | Method | Path |
|---|---|---|
| List boards | GET | |
| Get board | GET | |
| Get board sprints | GET | |
| Get sprint | GET | |
| Create sprint | POST | |
| Update sprint | PUT | |
| Delete sprint | DELETE | |
| Get sprint issues | GET | |
| Move issues to sprint | POST | |
| 操作 | 方法 | 路径 |
|---|---|---|
| 列出看板 | GET | |
| 获取看板 | GET | |
| 获取看板中的Sprint | GET | |
| 获取Sprint | GET | |
| 创建Sprint | POST | |
| 更新Sprint | PUT | |
| 删除Sprint | DELETE | |
| 获取Sprint中的问题 | GET | |
| 将问题移入Sprint | POST | |
Common Mistakes
常见错误
- Using instead of
/rest/api/3//rest/agile/1.0/ - Trying to add issues to closed sprints
- Kanban boards don't have sprints
- Sprint IDs are board-specific
- 使用而非
/rest/api/3//rest/agile/1.0/ - 尝试向已关闭的Sprint添加问题
- Kanban看板没有Sprint
- Sprint ID是看板专属的
References
参考资料
Version History
版本历史
- 2025-12-10: Created
- 2025-12-10:创建