Issue Triage (Linear / Jira)
Composio CLI を使って、Linear または Jira でトリアージセッションとバグスイープを実行します。バックログを取得し、重複をクラスタリングし、ラベルを適用し、クリーンなリストをチームに引き渡します。
使用するタイミング
- 週次トリアージ: 「未アサイン、長期放置、優先度未設定の課題は?」
- リリース後のバグスイープ: 「すべての P1/P2 バグをクラスタリングし、重複排除し、担当者を割り当てる。」
- クロスツール同期: Sentry → Linear、PagerDuty → Jira
前提条件
curl -fsSL https://composio.dev/install | bash
composio login
composio link linear # または: composio link jira
ツールの確認
composio search "list issues" --toolkits linear
composio search "search issues" --toolkits jira
composio tools list linear
composio tools list jira
よく使うスラッグ(--get-schema で確認してください):
Linear
LINEAR_LIST_ISSUESLINEAR_CREATE_ISSUELINEAR_UPDATE_ISSUELINEAR_CREATE_COMMENT
Jira
JIRA_SEARCH_FOR_ISSUES_USING_JQLJIRA_CREATE_ISSUEJIRA_EDIT_ISSUEJIRA_ADD_COMMENTJIRA_ASSIGN_ISSUE
トリアージのワークフロー
- バックログの一部を取得:
# Linear composio execute LINEAR_LIST_ISSUES -d '{ "filter": { "state": { "type": { "eq": "unstarted" } }, "assignee": { "null": true } }, "first": 100 }' # Jira composio execute JIRA_SEARCH_FOR_ISSUES_USING_JQL -d '{ "jql": "project = APP AND statusCategory != Done AND assignee is EMPTY ORDER BY updated DESC", "maxResults": 100, "fields": ["summary","priority","labels","updated","reporter"] }' - クラスタリング: タイトルの類似性とラベルに基づいて、エージェントがローカルで重複をグループ化します。
- 更新を一括適用(ラベル、優先度、担当者):
composio execute LINEAR_UPDATE_ISSUE -d '{ "id":"abc-123","priority":2,"labelIds":["label-bug","label-p1"],"assigneeId":"user-42" }' composio execute JIRA_EDIT_ISSUE -d '{ "issueIdOrKey":"APP-482", "fields":{"priority":{"name":"High"},"labels":["bug","p1"]} }' - 重複をリンク: 正規の課題を参照するコメントを追加します。
- 変更内容のダイジェストを Slack に投稿: チームがスイープ結果を確認できるようにします。
バグスイープ(リリース後)
# Jira: 過去7日間に作成されたすべてのバグを重要度順に並べる
composio execute JIRA_SEARCH_FOR_ISSUES_USING_JQL -d '{
"jql":"type = Bug AND created >= -7d ORDER BY priority DESC, created ASC",
"fields":["summary","priority","labels","reporter","components"]
}' | jq -r '.issues[] | "\(.fields.priority.name)\t\(.key)\t\(.fields.summary)"'
ワークフローファイル
scripts/triage-linear.ts を作成し、composio run --file scripts/triage-linear.ts で実行します:
const { nodes: issues } = await execute("LINEAR_LIST_ISSUES", {
filter: { state: { type: { eq: "unstarted" } }, assignee: { null: true } },
first: 100
});
const stale = issues.filter(i => {
const age = (Date.now() - new Date(i.updatedAt).getTime()) / 86400000;
return age > 14;
});
for (const i of stale) {
await execute("LINEAR_CREATE_COMMENT", {
issueId: i.id,
body: "Auto-triage: stale for 14+ days. Please assign or close."
});
}
await execute("SLACK_SEND_MESSAGE", {
channel: "triage",
text: `Weekly triage: pinged ${stale.length} stale issues.`
});
クロスツール: Sentry → Linear
composio run '
const hot = await execute("SENTRY_LIST_A_PROJECTS_ISSUES", {
organization_slug:"acme", project_slug:"api",
query:"is:unresolved", sort:"freq", limit:5
});
for (const s of hot) {
await execute("LINEAR_CREATE_ISSUE", {
teamId: "TEAM_ID",
title: `[Sentry] ${s.title}`,
description: `${s.permalink}\nCount: ${s.count}`,
labelIds: ["label-bug","label-from-sentry"]
});
}
'
トラブルシューティング
- フィールド名が不明な場合 →
composio execute <SLUG> --get-schemaで正確なフィルター構造を確認します(Linear はネストされたオブジェクト、Jira は JQL 文字列を使用)。 - Linear で 403 エラー → 正しいワークスペースで
composio link linearを再実行します。 - Jira のカスタムフィールドが見つからない場合 →
fields配列に明示的に指定します。 - 一括編集でレート制限にかかった場合 →
composio runのループ内に 250ms のスリープを挿入し、--parallelは使用しないでください。
完全な CLI リファレンス: docs.composio.dev/docs/cli