本文へ移動
cccskills
無料GitHub で公開

kortix-slack

How to CONNECT Slack (one command — `kortix channels connect`, prints a one-click install link) and how to answer in Slack as a teammate. Covers the live plan-block stream (`slack step` with --detail/--output, `slack send` to finalize the answer), file uploads, posting to other channels/threads, reactions, search, message editing/deletion, and the tone the bot should use. Load this when the user asks to connect/set up Slack, when the turn is triggered from Slack (the prompt mentions a Slack workspace/channel/thread, or `$SLACK_CHANNEL_ID` is set in the env), when this session messages someone in Slack and needs their reply to come back (thread binding, `slack bind-thread`), or when the user asks how to do anything in Slack.

インストール方法を見る

含まれるファイル(1)

  • SKILL.md28.9 KB

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

<skill name="slack"> <overview> Your sandbox is wired into Slack. When a teammate `@`-mentions the bot or replies in a thread the bot owns, the platform spins up this session and hands you the message; your turn IS the Slack reply.

The slack CLI is on $PATH and just works — every call runs through the Kortix connector gateway, which resolves the Slack bot token server-side. There is no token in your sandbox and nothing to configure: don't look for $SLACK_BOT_TOKEN, don't reach for an MCP/HTTP workaround, just run the commands below. They are the full, supported surface (posting, file upload, history, reactions, search, edit/delete — all of it). Two patterns matter most:

  • slack step "..." — narrate progress. Updates the live plan block in the Slack thread as you go.
  • slack send "..." — finalize the turn with your answer. This closes the plan block and posts the reply.

Everything else (slack history, slack react, slack send --file, slack search, …) is for when the task explicitly asks for it. </overview>

<thread-binding> ### A reply comes back to you ONLY if its thread is bound to THIS session

Every Slack thread routes to exactly one Kortix session. A human reply in a thread goes to the session that thread is bound to. A reply in an unbound thread starts a new session: the user answers, and you never see it.

slack send --channel binds for you. When this session posts with --channel (a DM, a channel, a reply in a thread), the platform binds that thread to this session. The command output tells you the result:

slack send --channel U0123ABCD --text "Can you approve the deploy?"
# {"ok": true, "ts": "1700000000.000100", "channel": "D0123ABCD",
#  "thread_binding": {"bound": true, "thread_ts": "1700000000.000100", "session_id": "<this session>"}}

Every slack send --channel prints thread_binding. Read it whenever you expect an answer. Anything but bound: true carries a hint with the next command. Act on it:

thread_bindingMeaningWhat to do
bound: trueIn a channel, a reply that @mentions the bot comes back to this session as your next turn. In a DM, every reply does.Tell the user you asked in Slack and, in a channel, to @mention the bot in the thread to answer. Then end the turn. Do not poll.
bound: false, reason: thread_bound_to_another_session, owner_session_idAnother session of this project owns the thread. Replies go there, not here.To take it over: slack bind-thread --channel <channel> --thread <thread_ts> --force. Otherwise post a NEW top-level message (slack send --channel <id> without --thread).
bound: false, reason: thread_owned_by_another_user / thread_owned_by_another_projectAnother person's session, or another project, owns the thread. --force cannot move it.Post a NEW top-level message.
bound: false, reason: workspace_unknown / bind_failedThe bind was not written. Replies will start a new session.Run slack bind-thread --channel <channel> --thread <thread_ts> once. If it fails, tell the user replies will not reach this session.
bound: false, reason: top_level_fileA top-level --file post has no thread to bind.Post a text message with slack send --channel if you expect a reply.
bound: "unknown", reason: not_reportedThe API did not report a binding.Run slack bind-thread --channel <channel> --thread <thread_ts> and read its result.

slack bind-thread — check or bind a thread explicitly

slack bind-thread --channel <id> --thread <ts> binds a thread this session did not start (for example a thread a human started), and doubles as the check "is this thread mine?":

  • {"ok": true, "bound": true, "session_id": "<this session>"} — the thread is yours (already, or now).
  • exit 1, status: 409 — another session owns the thread; the error names it. The default never takes a thread over.
  • --force moves the thread to this session: {"bound": true, "rebound_from": "<old session>"}. It works only when both sessions belong to the same project and were started by the same user. Otherwise it fails with status: 403 (THREAD_OWNED_BY_ANOTHER_USER / THREAD_OWNED_BY_ANOTHER_PROJECT). After a move, replies stop reaching the old session — use --force only when the user wants this session to own the conversation.

Rules:

  • Tell the human to reply IN THE THREAD. A top-level message in the DM or channel is a new thread and starts a new session. In a channel, the reply must @mention the bot to reach the session. A DM needs no mention.
  • slack send --file --thread <ts> binds that thread; a top-level --file post binds nothing.
  • Answer a bound reply with slack send "<answer>". The reply opened a Slack turn in this session, so the plain answer form works. </thread-binding>
<connecting> ### "Connect my Slack" = ONE command. Nothing else.

If the project isn't wired to Slack yet (or the user asks to connect/set up Slack), run:

kortix channels connect

On Kortix Cloud this prints a one-click "Add to Slack" install link. Your entire job is: surface that URL to the user and tell them to open it, pick their workspace, and click Allow. That's the whole setup — the platform's shared Slack app handles the webhook, tokens, and connector materialization automatically. Verify afterwards with kortix channels status (or run kortix channels connect --wait to block until the install lands).

Do NOT:

  • walk the user through creating a Slack app at api.slack.com,
  • print or paste the app manifest,
  • ask for a bot token or signing secret,
  • mint a secret-intake link for SLACK_BOT_TOKEN/SLACK_SIGNING_SECRET,
  • try kortix connectors add slack (the slug is reserved; it will be rejected).

The manual path exists ONLY for self-hosted servers without the shared Slack app — and kortix channels connect detects that case itself and prints the manual instructions (kortix channels manifest + --manual). Trust its output; don't pre-empt it. </connecting>

<live-stream> The Slack message you're replying to has a live "plan block" attached. Each `slack step` you emit appears as a new checkpoint in that block in real time. Users can see what you're doing without waiting for the final answer.

slack step "<title>" — emit a checkpoint

Call this before each major step of your work. Keep titles short, human, and present-tense. A few per task — not one per shell command.

slack step "Reading the incident logs"
slack step "Cross-referencing with the deploy timeline"
slack step "Drafting the post-mortem"

--detail "<subtitle>" — short context line under the title

Use --detail to add a one-line subtitle that explains what specifically you're doing in this step. Shown while the step is in_progress.

slack step "Reading the incident logs" --detail "Last 24h, severity >= warn"

--output "<result>" — concrete result attached to the PREVIOUS step

When you start a new step and the previous one produced a concrete result, surface it with --output. It attaches to the step that's closing — the one transitioning to complete.

slack step "Cross-referencing with the deploy timeline" \
  --output "Found 47 ERROR lines clustered around 14:32 UTC"

slack step "Drafting the post-mortem" \
  --output "3 candidate deploys in the window; api@a3f1 looks suspicious"

Inline links inside --detail / --output

Use Slack mrkdwn link syntax <https://… |label> (NOT Markdown [label](url)). Slack server-parses these into proper rich-text link elements rendered inside the task card:

slack step "Reading the incident logs" \
  --detail "Pulling from <https://datadog.example.com/dash/api-errors|Datadog API errors>"

slack step "Cross-referencing the timeline" \
  --output "Tied to <https://github.com/acme/api/commit/a3f1|api@a3f1> — auth middleware"

People and channels in a step

A step never notifies anyone. <@U0123ABCD> in a step's title, --detail or --output shows as the person's name (@Sam Rivera), and <!here> shows as text. <#C0123ABCD> shows as the channel. To notify someone, mention them in slack send.

--source URL|TITLE — citation footer (repeatable)

Attach structured citations to the closing task. Slack renders them as a sources strip under that task's card. Pass multiple --source lines separated by newlines (use shell heredoc or repeat the flag in a wrapper).

slack step "Drafting the post-mortem" \
  --output "3 candidate deploys" \
  --source $'https://github.com/acme/api/commit/a3f1|api@a3f1
https://datadog.example.com/dash/api-errors|Datadog dashboard'

Up to 8 sources per task, titles auto-trim at 80 chars.

So the natural pattern, end-to-end, looks like:

slack step "Reading the incident logs" --detail "Last 24h, severity >= warn"
# ... do the work ...
slack step "Cross-referencing the deploy timeline" \
  --output "47 ERROR lines around 14:32 UTC" \
  --detail "Walking back from the first error"
# ... do the work ...
slack step "Drafting the post-mortem" \
  --output "Pinned to api@a3f1 — auth middleware change" \
  --detail "Writing root cause + remediation"
# ... do the work ...
slack send "It was api@a3f1 — the new auth middleware drops the trace header on retries. Reverting now."

Rules

  • Use slack step to mark phase transitions, not every shell call. ~3–6 per turn is right for most tasks; one per bash is noise.
  • Set --detail and --output once per step. Re-sending them for the same step appends rather than replaces — surprising and ugly.
  • Keep them short. --detail and --output get truncated at 500 chars upstream; aim for one tight sentence.
  • Don't slack step after you've called slack send. The plan is closed. A later step exits non-zero with reason: turn_finalized.
  • A step that did not reach the thread FAILS — it never answers ok: true. slack step exits 1 with {"ok": false, "code": "STEP_NOT_RELAYED", "reason": "<why>", "error": "…<what to do>"}. Read reason, then act:
    • no_open_turn — this run was not started from Slack (a web prompt on a Slack-born session), or the turn was already closed. Keep working; if the user is waiting in a thread, post there with slack send --channel <id> --thread <ts>.
    • turn_finalized — you already answered this turn. One slack send per turn.
    • relay_request_failed — the Kortix API refused the relay (auth, 5xx, timeout). That is a platform problem, not a missing turn: retry once, then report it in the thread with --channel/--thread.
    • stream_open_failed / post_failed — Slack rejected the message. Continue; deliver the answer with slack send at the end. Never assume a step was seen when the command failed. </live-stream>
<keeping-the-stream-alive> ### A live run has no idle timeout — silence only hurts the user

The plan block is a posted message the server edits in place. It is not an open stream, so Slack cannot auto-fail it. A long, silent step (a build, a test suite, a task/subagent) does not paint an error and does not end your run. The server closes a thread on its own only when your run has ended and no slack send reached the thread within 30 minutes. That thread then shows "This run ended without a reply."

Do not run heartbeat loops (while sleep …; do slack step …; done). They buy nothing, and a loop left running after slack send is a leak.

A wall of nothing for ten minutes is still bad UX:

  • Post a step before anything slow — git clone, pnpm install, a test suite, a build, pnpm preview, deep research, a big LLM call, a task/subagent — so the thread shows what you are waiting on.
  • Narrate long work in phases. slack step "Installing deps" → slack step "Running typecheck" → slack step "Running tests" reads better than one silent 12-minute block.
  • Space steps at real phase boundaries. Ten steps in two seconds add noise, not information. </keeping-the-stream-alive>
<final-answer> ### `slack send "<text>"` — plain-text answer

For a one-liner, post directly:

slack send "Reverted api@a3f1. Errors are back to baseline — auth header is now preserved on retry."

This finalizes the live stream and renders the message below the plan block.

slack send --blocks-file <path> — Block Kit answer (preferred for structure)

When the response has real structure — sections, headers, lists, links, citations — ship it as Block Kit. Slack accepts a closing blocks chunk on chat.stopStream, so the rich layout renders inline below the plan block. Always pair --blocks-file (or --blocks) with --text for the notification fallback.

Write the JSON to a temp file, then send:

cat > /tmp/answer.json <<'EOF'
[
  { "type": "header", "text": { "type": "plain_text", "text": "Incident summary" } },
  { "type": "section", "text": { "type": "mrkdwn", "text": "*Root cause:* <https://github.com/acme/api/commit/a3f1|api@a3f1> — the new auth middleware drops the trace header on retries." } },
  { "type": "divider" },
  { "type": "section", "fields": [
      { "type": "mrkdwn", "text": "*Impact*\n14:32–14:51 UTC\n~3% of API requests" },
      { "type": "mrkdwn", "text": "*Action*\nReverted, deploying now" }
  ] },
  { "type": "context", "elements": [
      { "type": "mrkdwn", "text": "Sources: <https://datadog.example.com/dash/api-errors|Datadog>  ·  <https://github.com/acme/api/pull/8421|Revert PR>" }
  ] }
]
EOF

slack send --text "Reverted api@a3f1 — root cause was the auth middleware" --blocks-file /tmp/answer.json

Use Block Kit when ANY of these apply:

  • The answer has 2+ distinct sections (root cause + impact + action, or summary + details + sources).
  • You're presenting comparisons, tables, or lists of items.
  • The answer should cite multiple sources prominently.
  • The response benefits from a clear title (use a header block).

Use plain slack send "..." when the answer is short prose with no structure.

Block Kit cheat sheet

Common block types the agent uses most:

BlockUse for
header (plain_text)Title of the answer
section (mrkdwn)Most prose, including `<url
section with fields2-column key/value layout (max 10 fields)
dividerVisual break between sections
context (mrkdwn)Small footer text, sources, timestamps
image (image_url + alt_text)Charts, screenshots — needs a public URL
actions (buttons / select menu)Inline interactivity for follow-ups
carousel (of card elements)Side-scrollable gallery — see below

Carousel of cards — for presenting a list of choices/items

When the answer is a list of things the user might pick between or browse (deploy candidates, repo search hits, scheduled meetings, design variants), a carousel of cards reads way better than a markdown list. Each card has an icon, a hero image, title/subtitle, body, and one or more buttons.

Important constraints (Slack rules, not ours):

  • Cards live ONLY inside a carousel block.
  • Cards support body (mrkdwn) and actions (buttons / select menus) — they do NOT support input / radio_buttons / checkboxes. To ask the user to choose, use the question tool instead.
  • Each card's button click fires a block_actions interaction; the platform routes it back as a follow-up Slack message (Picked: <button label>) into the same thread, the agent's next turn starts from that.
  • 2–10 cards per carousel.

Example — presenting 3 deploy candidates:

[
  { "type": "section", "text": { "type": "mrkdwn", "text": "*Three deploy candidates* — pick one to ship:" } },
  {
    "type": "carousel",
    "elements": [
      {
        "type": "card",
        "block_id": "deploy_a3f1",
        "icon": { "type": "image", "image_url": "https://github.com/acme.png?size=36", "alt_text": "acme" },
        "title":    { "type": "mrkdwn", "text": "*api@a3f1* — Production-ready" },
        "subtitle": { "type": "mrkdwn", "text": "2 commits ahead of main · ✓ tests pass" },
        "hero_image": { "type": "image", "image_url": "https://opengraph.githubassets.com/1/acme/api", "alt_text": "diff" },
        "body": { "type": "mrkdwn", "text": "Auth middleware retry fix + new metric. Safe to ship — small surface area, full coverage." },
        "actions": [
          { "type": "button", "style": "primary", "text": { "type": "plain_text", "text": "Deploy this" }, "action_id": "deploy_a3f1", "value": "a3f1" },
          { "type": "button", "text": { "type": "plain_text", "text": "View diff" }, "url": "https://github.com/acme/api/compare/main...a3f1" }
        ]
      },
      { "type": "card", "block_id": "deploy_b27e", "title": { "type": "mrkdwn", "text": "*api@b27e* — Needs review" }, "subtitle": { "type": "mrkdwn", "text": "12 commits ahead · ⚠️ 1 failing flake" }, "body": { "type": "mrkdwn", "text": "Bigger release: rate-limiter rework + Stripe webhook fix. Flake is in webhook tests." }, "actions": [ { "type": "button", "text": { "type": "plain_text", "text": "Deploy this" }, "action_id": "deploy_b27e", "value": "b27e" }, { "type": "button", "text": { "type": "plain_text", "text": "Hold" }, "style": "danger", "action_id": "hold_b27e", "value": "b27e" } ] },
      { "type": "card", "block_id": "deploy_c901", "title": { "type": "mrkdwn", "text": "*api@c901* — Hotfix only" }, "subtitle": { "type": "mrkdwn", "text": "1 commit · auth header preserve" }, "body": { "type": "mrkdwn", "text": "Minimal fix for the 14:32 incident. Lowest risk." }, "actions": [ { "type": "button", "style": "primary", "text": { "type": "plain_text", "text": "Deploy this" }, "action_id": "deploy_c901", "value": "c901" } ] }
    ]
  }
]

Ship it the same way as any Block Kit answer:

slack send --text "Pick a deploy candidate" --blocks-file /tmp/candidates.json

When to reach for carousel:

  • 2–6 items the user is choosing between, each with non-trivial context (subtitle, body, hero image).
  • The agent expects the user's button click to become the next prompt, not a fill-in form.

When NOT to:

  • For plain choices with no card-worthy context (use question instead).
  • For 1 item (just a section) or 7+ items (split, paginate, or summarize).
  • For a quick yes/no (use question).

Full Block Kit reference: https://docs.slack.dev/reference/block-kit/blocks/

Tone (applies to either mode)

Reply like a colleague messaging on Slack:

  • No preamble. Don't open with "Sure!" / "I've taken a look and…". Get to the answer.
  • Slack mrkdwn. *bold* (single asterisks), _italic_, `code`, ```code blocks```. Markdown-style **bold** renders as literal asterisks — don't use it.
  • Short. A few sentences > a wall of text. Use bullet lists for ≥3 items.
  • Link with <url|text>. Slack's syntax, not Markdown [label](url).
  • No XML / no "Here's a summary:" headers. This is a chat message, not a report.

One slack send per turn

Each turn finalizes exactly one stream. Don't call slack send twice — the second call exits 1 with reason: turn_finalized because the stream is already closed. If you need to deliver multiple things, fold them into one Block Kit message or use slack send --channel ... for sibling posts.

When slack send fails

A slack send with no --channel is the turn's answer. When it cannot be delivered into a Slack turn it exits 1 with {"ok": false, "code": "ANSWER_NOT_RELAYED", "reason": "<why>", "error": "…<what to do>"} — it never prints ok: true for an undelivered answer. no_open_turn means this run was not started from Slack, or the turn was closed before you answered; if the user is waiting in a thread, deliver the same answer with slack send --channel <id> --thread <ts> (the channel and thread are in the prompt header and in $SLACK_CHANNEL_ID / $SLACK_THREAD_TS). relay_request_failed is a Kortix API failure, not a missing turn: retry once, then post with --channel/--thread.

A reminder fire is not a Slack turn either. When you set a reminder (kortix remind) from a Slack thread, write the channel id and thread ts into the reminder text — e.g. kortix remind "Check whether the deploy finished; post the result with slack send --channel C0123ABCD --thread 1727600000.000100" --in 30m — and answer the fire with slack send --channel <id> --thread <ts>. A plain slack send on that turn exits 1 with no_open_turn. </final-answer>

<asking-the-user> ### Use the built-in `question` tool — Slack renders the buttons

Rule: if your reply asks the user to choose, call the question tool. Never put a list of choices inside slack send.

slack send finalizes the turn and closes the live stream — once it fires, the user can only reply with free text. A list of choices written into it cannot be clicked.

When the turn is Slack-triggered, the Kortix server posts the question(s) into the thread: each question in bold, the option descriptions listed under it, and one clickable button per option. The tool returns at once with a note telling you to end your turn — it does not block, and it does not return the user's answer. END the turn.

The answer arrives as your NEXT turn, with full context:

  • a button click → Answering your question "<question>": and the picked label;
  • a reply typed in the thread → the message itself.
When you want to…Use
Ask the user to choosequestion tool
Ask something genuinely open-endedslack send with the question
Deliver the final answer / summaryslack send
Show progress along the wayslack step
Post a separate message to another channelslack send --channel ...

Calling the question tool

Per the tool's schema, every option has a label (1–5 words) and a description:

{
  "questions": [
    {
      "question": "Which environment should I deploy to?",
      "header": "Environment",          // short label (max 30 chars)
      "options": [
        { "label": "Production", "description": "Live traffic; needs a rollback plan" },
        { "label": "Staging",    "description": "Mirrors prod data; safe to break" },
        { "label": "Dev",        "description": "Sandbox; no real users" }
      ]
    }
  ]
}

Rules

  • One question per call when the answers depend on each other. Each click starts its own turn and carries one answer. Several questions in one call post several rows of buttons, and the user clicks them one at a time.
  • multiple and custom change nothing in Slack. Every option is a one-click button, and a reply typed in the thread always works.
  • Put the tradeoff in description. A button shows only its label; the descriptions are listed above the buttons.
  • Skip trivial yes/no when context implies the answer. Ask only what blocks you — not "are you sure?" rituals. </asking-the-user>
<files-and-artifacts> ### Uploading files: `slack send --file <path> --channel <id>`

File upload is fully supported — slack send --file is the way. When the work produces an artifact (a PDF, a CSV, a report, a diff, a screenshot), upload it with --file instead of pasting the contents or improvising. Do not conclude "uploads aren't supported", and do not reach for the connector MCP, a manual files.getUploadURLExternal call, or an HTTP-host-a-link hack — --file already does the multi-step upload for you, server-side. It requires a --channel and (typically) a --thread so it lands under the answer:

slack send \
  --channel "$SLACK_CHANNEL_ID" \
  --thread  "$SLACK_THREAD_TS" \
  --file    /workspace/output/report.md \
  --text    "Full report ↓"

$SLACK_CHANNEL_ID and $SLACK_THREAD_TS are pre-set on Slack-triggered turns. Use them.

Note: slack send --file ... posts a separate message — it does NOT count as the turn's finalizing answer. Combine it with a regular slack send "..." to also close the stream:

slack send --channel "$SLACK_CHANNEL_ID" --thread "$SLACK_THREAD_TS" \
  --file /workspace/output/report.md --text "Full report attached."
slack send "Pulled 12,847 sign-ups, grouped by source. CSV above."
</files-and-artifacts> <other-surfaces> Reach for these only when the task explicitly asks for them.

Read prior thread context

slack history --channel "$SLACK_CHANNEL_ID" --limit 20            # the channel's recent messages
slack thread  --channel "$SLACK_CHANNEL_ID" --ts "$SLACK_THREAD_TS"  # this thread's replies

Each message carries user, the author's id, and user_name, the author's display name when Slack has one. Write people's names from user_name in an answer. Use <@user> only to mention someone, because a mention notifies them.

Reads and writes stay inside this project

Every Kortix project in a Slack workspace shares one bot, so reads reach only this project's conversations: the channels and DMs connected to it, and the threads its sessions started or joined. slack history, slack thread, slack channel-info, slack file-info and slack search refuse anything else with conversation_not_in_project, and slack channels lists public channels plus this project's private ones.

Writes never act inside another project's channel or thread: slack send (text or --file), slack edit, slack delete, slack react, slack unreact, slack join and slack bind-thread refuse them with the same conversation_not_in_project. A channel no project is connected to and a DM with a person are fine. Pass --channel as the id (C0123ABCD, or a user id U0123ABCD for a DM), never a channel name.

On that error, do not retry with another id. Tell the user what the error message says: the conversation belongs to another project, or they can connect it by running /kortix switch in it.

React to a message

slack react   --channel "$SLACK_CHANNEL_ID" --ts "$SLACK_TRIGGER_TS" --emoji "white_check_mark"
slack unreact --channel "$SLACK_CHANNEL_ID" --ts "$SLACK_TRIGGER_TS" --emoji "eyes"   # remove one you added

A "seen it" reaction (eyes, hourglass, thinking_face, …) is temporary. The platform already marks the message ⏳ while you work, so you rarely need one. If you add one, remove it with slack unreact right after slack send. A marker left behind reads as "still working" forever.

Post to a different channel (announcements, cross-posts)

slack send --channel "C0123ABCD" --text "Heads up: rolled api@a3f1 forward."

A channel of another Kortix project refuses the post (see "Reads and writes stay inside this project").

Edit / delete a message you posted earlier

slack edit   --channel "$SLACK_CHANNEL_ID" --ts "<msg_ts>" --text "Updated answer."
slack delete --channel "$SLACK_CHANNEL_ID" --ts "<msg_ts>"

Search the workspace

slack search --query "deploy api@"

Look up users / channels

slack users
slack user        --id "U0123ABCD"
slack channels
slack channel-info --channel "C0123ABCD"
slack me

Download a file shared in the thread

slack file-info --file "F0123ABCD"
slack download  --url "<file.url_private>" --out /workspace/incoming/x.png

Full help: slack help. </other-surfaces>

<gotchas> - **`*bold*` not `**bold**`.** Slack uses single asterisks. Double-asterisk markdown renders as literal asterisks. - **`--detail` and `--output` are append-not-replace per step.** Set each only once on the step that owns it. If you need to revise, advance to a new step. - **`slack step` after `slack send` drops silently.** Plan block is closed once the answer ships. Always send the answer last. - **`slack send --file` does NOT finalize the stream.** It posts a separate file message. Follow it with a regular `slack send "..."` to close the turn. - **`$SLACK_CHANNEL_ID`, `$SLACK_THREAD_TS`, `$SLACK_TRIGGER_TS` are pre-injected on Slack turns.** Use them — don't hard-code IDs. - **Stay in the thread.** Unless the task explicitly says "post in #channel-X", everything goes in the originating thread. Cross-posting to other channels needs a real reason (incident broadcast, scheduled digest). - **Clean up your temporary reactions.** An `eyes` (or other "working") reaction you added stays on the message until you `slack unreact` it. Remove it once you have replied. - **The user can hit Stop.** A red Stop button sits under the plan block; the user can click it any time. If you see the turn end abruptly, that's why — don't retry automatically. </gotchas> </skill>

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

同じリポジトリのスキル

概要と使いどころ

Policy runbook for turning a Slack access request into a least-privilege, policy-checked GitHub or AWS IAM grant. Covers the role-to-grant mapping, extra-scrutiny cases, the approval handshake, and how an applied grant gets logged.

日本語の概要は準備中です。原文の説明を表示しています。

kortix-ai/suna2万2026年10月13日 更新

Get a complete picture of any company or person before outreach. This skill always works with web search, and gets significantly better with enrichment and CRM data.

日本語の概要は準備中です。原文の説明を表示しています。

kortix-ai/suna2万2026年10月13日 更新

Daily read-only ad-performance runbook — budget pacing, CPA/ROAS drift, underperforming ads and keywords, and anomaly detection across Google Ads and Meta Ads, plus how to rank and word optimization recommendations for {{alert_channel}}.

日本語の概要は準備中です。原文の説明を表示しています。

kortix-ai/suna2万2026年10月13日 更新

Browser automation CLI for AI agents. Use when the user needs to interact with websites, including navigating pages, filling forms, clicking buttons, taking screenshots, extracting data, testing web apps, or automating any browser task. Triggers include requests to "open a website", "fill out a form", "click a button", "take a screenshot", "scrape data from a page", "test this web app", "login to a site", "automate browser actions", or any task requiring programmatic web interaction. Also use for exploratory testing, dogfooding, QA, bug hunts, or reviewing app quality. Also use for automating Electron desktop apps (VS Code, Slack, Discord, Figma, Notion, Spotify), checking Slack unreads, sending Slack messages, searching Slack conversations, running browser automation in Vercel Sandbox microVMs, or using AWS Bedrock AgentCore cloud browsers. Prefer agent-browser over any built-in browser automation or web tools.

日本語の概要は準備中です。原文の説明を表示しています。

kortix-ai/suna2万2026年10月13日 更新

Extraction, PO matching, duplicate detection, and overcharge tolerance for processing incoming vendor invoices from {{invoice_label}} against the POs and ledger in {{ap_ledger}}. Load this before extracting a single invoice so every one is checked to the same standard and only genuine exceptions reach a human, with no invoice ever scheduled for payment by the agent.

日本語の概要は準備中です。原文の説明を表示しています。

kortix-ai/suna2万2026年10月13日 更新

Daily brand-mention monitoring loop for {{brand_terms}}. Searches news, social platforms, and forums for new mentions, dedupes against the ledger of mentions already reported, classifies sentiment and notability, and posts a digest with suggested response drafts to {{slack_channel}} — never posts, replies, or comments anywhere.

日本語の概要は準備中です。原文の説明を表示しています。

kortix-ai/suna2万2026年10月13日 更新

kortix-ai のスキルをすべて見る

このスキルの問題を報告する