Communitygithub.com

Aquarius-mu/skillManager

個人スキルライブラリ:AIエージェントスキルの収集、整理、バージョン管理

skillManager とは?

スキル「Aquarius-mu/skillManager」は、Feishuカード(スキーマ2.0)を活用して、AIエージェント(例:Claude Code、Cursor、Codex)がFeishuメッセージを対話的に送信・更新するための、詳細なリファレンスと実装ガイドを提供します。このドキュメントでは、JSON 2.0ボタンの設定、元メッセージの更新、カード内のメンション構文、使用可能なEmojiキーの厳格なルールなど、スキーマ2.0の重要なルールを体系的に網羅しています。Python heredocを使用してカードJSONを安全に構築する方法や、lark-cliコマンドでのメッセージ送信・更新方法についても具体的な手順を示しており、開発者はこのガイドを基に、Feishuボットと効果的に連携するエージェントスキルを実装できます。このスキルは、Feishu上のワークフロー自動化や、エージェントによる動的な情報配信・更新を実現したい開発者に特に有用です。

対応✓Claude Code~Codex CLI~Cursor
npx skills add Aquarius-mu/skillManager

お気に入りのAIに質問する

このエージェントスキルを事前に読み込んだ状態で新しいチャットを開きます。

プレビュー

スキル README より

ホバーテキスト

ドキュメント

feishu-card(スキーマ 2.0)

重要なルール

  • すべてのカードは スキーマ 2.0 を使用し、要素は body.elements[] に配置すること(トップレベルの elements[] ではない)
  • カード送信時は --as bot、--msg-type interactive、--content に JSON 文字列を渡すこと
  • カード内での @メンションは <at id="ou_xxx">名前</at> を使用すること(<at user_id> ではない)
  • JSON 2.0 では action コンテナは不要。button は body.elements に直接配置し、インタラクションには behaviors 配列を使用する
  • まず「思考中」カードを送信して message_id を取得し、Claude が回答したら PATCH でその場で更新し、画面のスクロールを防ぐ
  • スキーマ 2.0 では note タグはサポートされていない(エラー 200861)。注釈は div + lark_md(<font color=grey>注釈テキスト</font>)を使用すること
  • カード JSON の作成は Python heredoc またはファイル書き込みで行うこと。$(python3 -c "...") は禁止 — 内容にバッククォートや特殊文字が含まれる場合、bash が構文エラーになる

トップレベル構造の完全フィールド

{
  "schema": "2.0",
  "config": {
    "streaming_mode": false,
    "enable_forward": true,
    "update_multi": true,
    "width_mode": "default"
  },
  "card_link": {
    "url": "https://...",
    "pc_url": "https://...",
    "ios_url": "https://...",
    "android_url": "https://..."
  },
  "header": { "...": "..." },
  "body": {
    "direction": "vertical",
    "padding": "0px",
    "elements": []
  }
}

config フィールド

フィールドタイプデフォルト説明
streaming_modeboolfalseストリーミング更新状態(思考中プレースホルダー用)
enable_forwardbooltrueカードの転送を許可
update_multiboolfalseJSON 2.0 共有カードモード(複数人で同期更新する場合は true に設定)
width_modestringdefault(600px)compact(400px)/ fill(全幅レスポンシブ)/ default

Header フィールド

{
  "header": {
    "title":    {"tag": "plain_text", "content": "タイトル"},
    "subtitle": {"tag": "plain_text", "content": "サブタイトル(オプション)"},
    "template": "blue",
    "icon": {
      "tag": "standard_icon",
      "token": "robot-outlined",
      "color": "blue"
    },
    "text_tag_list": [
      {"tag": "text_tag", "text": {"tag": "plain_text", "content": "New"}, "color": "blue"}
    ]
  }
}

template 色:blue / wathet / turquoise / green / yellow / orange / red / carmine / violet / purple / indigo / grey


Feishu 色の列挙型クイックリファレンス

色の列挙型をサポートするすべてのフィールド(background_color、text_color、icon color など)は以下の形式を使用します。基本色名だけを使用することはできません(例:あるコンポーネントで "blue" を単独で使用するとエラーになる場合があります)。階層サフィックスを付ける必要があります。

色系薄色(背景推奨)中間色濃色(テキスト推奨)
青 blueblue-50 blue-100 blue-200blue-300~blue-500blue-600~blue-900
水色 wathetwathet-50 wathet-100 wathet-200wathet-300~wathet-500wathet-600~wathet-900
青緑 turquoiseturquoise-50 turquoise-100turquoise-300~turquoise-500turquoise-600~turquoise-900
緑 greengreen-50 green-100 green-200green-300~green-500green-600~green-900
黄緑 limelime-50 lime-100lime-300~lime-500lime-600~lime-900
黄 yellowyellow-50 yellow-100yellow-300~yellow-500yellow-600~yellow-900
橙 orangeorange-50 orange-100orange-300~orange-500orange-600~orange-900
赤 redred-50 red-100red-300~red-500red-600~red-900
ピンク carminecarmine-50 carmine-100carmine-300~carmine-500carmine-600~carmine-900
紫 purplepurple-50 purple-100purple-300~purple-500purple-600~purple-900
青紫 violetviolet-50 violet-100violet-300~violet-500violet-600~violet-900
藍 indigoindigo-50 indigo-100indigo-300~indigo-500indigo-600~indigo-900
灰 greygrey-00 grey-50 grey-100grey-300~grey-500grey-600~grey-1000
白white bg-white——

よく使う薄色背景のおすすめ(collapsible_panel、column 背景など):

blue-100    wathet-100    green-100    yellow-100
orange-100  red-100       purple-100   carmine-100
turquoise-100    violet-100    indigo-100    lime-100

コンポーネントクイックリファレンス

tagタイプ説明
divコンテンツテキストブロック(plain_text / lark_md)、アイコン接頭辞サポート
markdownコンテンツプレーン Markdown テキスト(@は非対応。@は div+lark_md を使用)
imgコンテンツ画像
tableコンテンツデータテーブル(カードあたり最大5個、ネスト不可)
hrレイアウト区切り線
noteレイアウト❌ スキーマ2.0では廃止。div + lark_md + <font color=grey> を使用
column_setコンテナ複数列レイアウト
collapsible_panelコンテナ折りたたみパネル
buttonインタラクションボタン(JSON 2.0では elements に直接配置、action コンテナは不要)
inputインタラクションテキスト入力(form 内で使用する必要あり)
select_staticインタラクション静的ドロップダウンセレクター

div(テキストブロック)

{
  "tag": "div",
  "text": {
    "tag": "lark_md",
    "content": "**太字** _斜体_ `コード`",
    "text_size": "normal",
    "text_color": "default",
    "text_align": "left",
    "lines": 3
  },
  "icon": {"tag": "standard_icon", "token": "robot-outlined", "color": "blue"}
}

text.tag:plain_text(プレーンテキスト)または lark_md(Markdown + @) text_size:heading-0 / heading / normal(デフォルト)/ notation / x-small text_align:left / center / right


img(画像)

{
  "tag": "img",
  "img_key": "img_xxx",
  "alt": {"tag": "plain_text", "content": "ホバー説明"},
  "title": {"tag": "plain_text", "content": "画像タイトル"},
  "scale_type": "crop_center",
  "size": "medium",
  "corner_radius": "4px",
  "preview": true
}

scale_type:crop_center / crop_top / fit_horizontal size:stretch(全幅)/ large / medium / small / tiny / "300px 200px"(カスタム)

JSON 2.0 では stretch_without_padding はサポートされていません。全幅効果は負のマージンを使用してください


column_set(複数列レイアウト)

{
  "tag": "column_set",
  "flex_mode": "bisect",
  "horizontal_spacing": "medium",
  "background_style": "default",
  "columns": [
    {
      "tag": "column",
      "width": "weighted",
      "weight": 1,
      "vertical_align": "top",
      "elements": [{"tag": "div", "text": {"tag": "plain_text", "content": "左列"}}]
    },
    {
      "tag": "column",
      "width": "weighted",
      "weight": 1,
      "elements": [{"tag": "div", "text": {"tag": "plain_text", "content": "右列"}}]
    }
  ]
}

flex_mode:none(比率で圧縮)/ stretch(狭画面で縦並び)/ flow(自動折り返し)/ bisect(等幅2列)/ trisect(等幅3列) horizontal_spacing:small(4px) / medium(8px) / large(12px) / extra_large(16px) column.width:auto / weighted(weight 1-5と組み合わせて使用)/ "200px"

最大ネスト5層。列内には form コンテナと table は配置不可


collapsible_panel(折りたたみパネル)

{
  "tag": "collapsible_panel",
  "expanded": false,
  "background_color": "default",
  "header": {
    "title": {"tag": "plain_text", "content": "クリックして展開"},
    "background_color": "grey",
    "icon": {"tag": "standard_icon", "token": "arrow-down-outlined"},
    "icon_expanded_angle": -180
  },
  "elements": [
    {"tag": "div", "text": {"tag": "plain_text", "content": "折りたたみコンテンツ"}}
  ]
}

table(データテーブル)

{
  "tag": "table",
  "page_size": 5,
  "row_height": "low",
  "freeze_first_column": false,
  "header_style": {
    "text_align": "left",
    "text_size": "normal",
    "background_style": "grey",
    "bold": true
  },
  "columns": [
    {"name": "name", "display_name": "名前", "data_type": "text", "width": "auto"},
    {"name": "status", "display_name": "状態", "data_type": "options", "width": "120px"},
    {"name": "count", "display_name": "数量", "data_type": "number",
     "format": {"precision": 0, "separator": true}},
    {"name": "ts", "display_name": "時間", "data_type": "date",
     "format": "YYYY/MM/DD HH:mm"}
  ],
  "rows": [
    {"name": "山田太郎", "status": [{"name": "進行中", "color": "blue"}], "count": 42, "ts": 1700000000000}
  ]
}

data_type:text / lark_md / markdown / options / number / persons / date row_height:low / middle / high / auto / "48px"(32-124px)

カードあたり最大5つのテーブル。ネスト不可


button(JSON 2.0)

{
  "tag": "button",
  "text": {"tag": "plain_text", "content": "確認"},
  "type": "primary",
  "size": "medium",
  "width": "default",
  "disabled": false,
  "behaviors": [
    {
      "type": "callback",
      "value": {"action": "confirm", "data": "payload"}
    }
  ],
  "confirm": {
    "title": {"tag": "plain_text", "content": "再確認"},
    "text":  {"tag": "plain_text", "content": "この操作を実行してもよろしいですか?"}
  }
}

type:default(灰)/ primary(青)/ danger(赤)/ text / primary_text / danger_text / primary_filled / danger_filled / laser size:tiny / small / medium / large behaviors[].type:callback(イベントトリガー)/ open_url(リンク遷移)

JSON 2.0 の変更点:action コンテナは不要。button は直接 body.elements または column.elements に配置。インタラクションには従来の value の代わりに behaviors を使用する


input(テキスト入力)

{
  "tag": "input",
  "name": "field_name",
  "placeholder": {"tag": "plain_text", "content": "入力してください..."},
  "default_value": "",
  "input_type": "text",
  "max_length": 200,
  "required": false,
  "disabled": false,
  "label": {"tag": "plain_text", "content": "ラベル"},
  "label_position": "top",
  "width": "fill"
}

input_type:text / multiline_text / password ユーザーが送信すると card.action.trigger イベントがトリガーされ、イベントには input_value が含まれる


@メンション構文

メッセージタイプ@人構文@全体
カード interactive lark_md<at id="ou_xxx">名前</at><at id="all">全員</at>
テキスト text / post<at user_id="ou_xxx">名前</at><at user_id="all"></at>

カード内 @メンション で検証済みの要素構造(div + lark_md を使用。生の markdown タグは使わない):

{
  "tag": "div",
  "text": {
    "tag": "lark_md",
    "content": "<at id=\"ou_xxx\">名前</at> メッセージ内容"
  }
}

Markdown 構文クイックリファレンス(lark_md / markdown タグ内)

テキストスタイル

**太字**    *斜体*    ~~打ち消し線~~    `インラインコード`

色付きテキスト

<font color=red>赤色</font>
<font color=green>緑色</font>
<font color=grey>灰色</font>
<font color=blue>青色</font>
<font color=orange>橙色</font>
<font color=wathet>水色</font>
<font color=purple>紫色</font>

完全な色:red / green / grey / blue / orange / wathet / purple / yellow / turquoise / indigo / violet / lime

タグ / 数字バッジ

<text_tag color='red'>タグ</text_tag>
<number_tag>99</number_tag>

ローカライズ時間

<local_datetime millisecond='1700000000000' format_type='date_num'></local_datetime>

format_type:date_num(2023/11/15)/ date_full(2023年11月15日)/ datetime(時分秒含む)

見出し / リスト / 引用

# H1  ## H2  ### H3  #### H4  ##### H5  ###### H6

- 順序なし  1. 順序あり  > 引用

コードブロック

```python
print("hello")
```

画像(Markdown 内)

![ホバーテキスト](img_xxx)

テーブル(最大5行のデータ)

| 列1 | 列2 |
|-----|-----|
| A   | B   |

リンク

[テキスト](https://url)    [電話](tel://13800138000)

区切り線 / 改行

---   または   <hr>
<br/>  または  改行2回(段落改行)

Emoji

⚠️ 厳格なルール

  1. 公式リストのキーのみ使用可能。収録されていないキー(例::WAITING:、:PROCESSING:)はプレーンテキストとしてレンダリングされるため、使用禁止。
  2. キーの大文字小文字は公式と完全に一致させる必要がある(例:Fire は FIRE ではない、Trophy は TROPHY ではない、Shrug は SHRUG ではない)。
  3. <text_tag> 内では :KEY: はレンダリングされない。Unicode絵文字(例:✅)を使用する必要がある。
  4. :KEY: は lark_md の通常テキスト領域でのみ有効。

リリース通知でよく使う

:DONE:        :OK:           :THUMBSUP:     :APPLAUSE:
:PARTY:       :FIREWORKS:    :MUSCLE:       :THANKS:
:Trophy:      :Fire:         :Hundred:      :CheckMark:

作業 & 状態

:LGTM:        :OnIt:         :OneSecond:    :Get:
:ERROR:        :CrossMark:    :Pin:          :Alarm:
:Loudspeaker: :OKR:          :Yes:          :No:
:HEADSET:     :Typing:       :MeMeMe:       :Sigh:
:Lemon:       :AWESOMEN:     :VRHeadset:    :YouAreTheBest:
:SALUTE:      :HIGHFIVE:     :FISTBUMP:     :FINGERHEART:
:WAVE:        :ThumbsDown:

表情 - ポジティブ

:SMILE:       :LAUGH:        :LOL:          :LOVE:
:WINK:        :PROUD:        :WITTY:        :JOYFUL:
:WOW:         :BLUSH:        :HUG:          :BeamingFace:
:Delighted:   :ThanksFace:   :SaluteFace:   :PRAISE:
:CLAP:        :JIAYI:        :FACEPALM:     :YEAH:

表情 - ネガティブ / ふざけ

:CRY:         :SOB:          :ANGRY:        :SHOCKED:
:Shrug:       :THINKING:     :DIZZY:        :SLEEP:
:YAWN:        :SICK:         :SWEAT:        :EMBARRASSED:
:SKULL:       :RAINBOWPUKE:  :PUKE:         :ClownFace:
:ColdSweat:   :SMUG:         :SILENT:       :TERROR:
:PETRIFIED:   :BETRAYED:     :WRONGED:

お祝い & 祝日

:PARTY:       :FIREWORKS:    :REDPACKET:    :FORTUNE:
:FIRECRACKER: :XmasTree:     :XmasHat:      :Snowman:
:Pumpkin:     :Mooncake:     :MoonRabbit:   :Partying:
:StickyRiceBalls:            :JubilantRabbit:  :LUCK:
:FullMoonFace: :GoGoGo:      :HappyDragon:

アイテム & 食べ物

:ROSE:        :HEART:        :BEER:         :CAKE:
:GIFT:        :BOMB:         :Fire:         :Trophy:
:Coffee:      :BubbleTea:    :Drumstick:    :Pepper:
:CUCUMBER:    :CANDIEDHAWS:  :Soccer:       :Basketball:
:Music:       :CLEAVER:      :EatingFood:   :LIPS:

状態表示(頻繁に使わないでください。状態シーンのみ)

:GeneralDoNotDisturb:        :GeneralInMeetingBusy:
:StatusReading:              :GeneralWorkFromHome:
:GeneralBusinessTrip:        :StatusInFlight:
:GeneralSun:                 :GeneralMoonRest:
:StatusFlashOfInspiration:   :Status_PrivateMessage:
:GeneralTravellingCar:       :StatusBus:

Unicode Emoji(タイトル、text_tag 内、header subtitle で使用)

🎉 ✅ ❌ ⚠️ 🚀 📦 💬 ⏳ 🔔 📝 🛠️ 🔍 👋 🎯 💡 🌟
👥 📅 🤖 🏆 🔥 💯 📣 🎁 ☕ 🍺

推奨スタイル:タイトルには Unicode emoji を使用して視認性を高め、状態/フィードバックには Feishu の :DONE: :LGTM: などの専用構文を使用する


送信 / 返信 / 更新

グループに送信(新規メッセージ)

CARD=$(python3 -c "
import json
card = {
  'schema': '2.0',
  'header': {'title': {'tag': 'plain_text', 'content': 'タイトル'}, 'template': 'blue'},
  'body': {'elements': [{'tag': 'markdown', 'content': '内容'}]}
}
print(json.dumps(card))
")
lark-cli im +messages-send \
  --chat-id oc_xxx \
  --msg-type interactive \
  --content "$CARD" \
  --as bot

指定メッセージに返信(message_id を取得して後続の更新に使用)

MSG_ID=$(lark-cli im +messages-reply \
  --message-id om_xxx \
  --msg-type interactive \
  --content "$CARD" \
  --as bot \
  --jq '.data.message_id')

thread に返信(メインのチャットフローに表示しない)

lark-cli im +messages-reply \
  --message-id om_xxx \
  --msg-type interactive \
  --content "$CARD" \
  --reply-in-thread \
  --as bot

重複送信防止(1時間以内に同じ key では1回のみ送信)

lark-cli im +messages-send \
  --chat-id oc_xxx \
  --msg-type interactive \
  --content "$CARD" \
  --idempotency-key "deploy-654.0-notify" \
  --as bot

その場でカードを更新(PATCH)

PAYLOAD=$(jq -n --argjson card "$CARD" '{"msg_type":"interactive","content":($card|tojson)}')
lark-cli api PATCH "/open-apis/im/v1/messages/${MSG_ID}" \
  --data "$PAYLOAD" \
  --as bot

カードテンプレート

思考中(ストリーミング状態、先にプレースホルダーを送信)

make_thinking_card() {
  local name="$1" question="$2"
  jq -n --arg name "$name" --arg q "$question"

…

[翻訳のため省略]

関連スキル