Claude Mods の全体像 .
Claude Code の Mods(function hooks)で何ができて、どう書き、どう始めるのかを 1 ページにまとめました。ハッカソンの補足資料として使えます。
Mods とは.
Claude Code の振る舞いと見た目を、TypeScript / JavaScript の関数で書き換えるプラグインです。
土台は function hook という仕組みです。イベントごとに async 関数を登録し、Express や Koa のミドルウェアのように重ねて合成します。mod は「hooks/hooks.json がこのモジュールを 1 つ指しているプラグイン」で、配布もインストールも普通のプラグインと同じです。
止める・書き換える
ツール実行、プロンプト送信、設定変更などを実行前に受け取り、拒否したり中身を書き換えたりできます。
tool.call · prompt.submit · config.set
描く
サイドパネル、プロンプト欄の上の帯、ツール結果の表示などを自分の UI に差し替えられます。
ui.render · $.ui.open · $.ui.toast
足す
スラッシュコマンド、モデルが呼べるツール、サブエージェントの型を追加できます。
$.command · $.tool · $.agent
従来の hooks との違い
| 従来の hooks(settings) | Mods(function hooks) | |
|---|---|---|
| 動く場所 | 外部のシェルプロセス | Claude Code のプロセス内の関数 |
| やりとり | JSON / テキストと allow・deny | 値をそのまま書き換え、UI も返せる |
| タイミング | 決まった時点で 1 回 | next() の前後どちらでも介入できる |
| UI・状態 | 持てない | パネル描画、状態保持、タイマー |
| 複数の組み合わせ | 順番の制御が難しい | 登録順のチェーンで自然に合成 |
- ・ターミナルは v2.1.287 以降、デスクトップアプリは v2.1.286 以降で既定でオン(フラグ不要)
-
・従来の settings の hooks はそのまま動きます。mod からは
classic.PreToolUseなどとしてフックできます
基本形.
モジュールは register(on, options) を export し、その中で on(イベント名, マッチャー?, フック)
を呼びます。フックはすべて ($, e, next) の形です。
export function register(on) {
on("tool.call", { tool: "Bash" }, async ($, e, next) => {
if (e.command.includes("git push --force")) {
return { deny: "force push は使わないでください" } // 本体の代わりに答える
}
const r = await next(e) // 後ろのフックと本体を実行
$.ui.toast("Bash ran") // 結果を見てから反応する
return r
}).catch(($, e, next) =>
next.called ? next(e) : { deny: "ガードが失敗したので止めました" })
} $
外の世界への唯一の窓口
画面、モデル、ファイル、ストア、タイマー、HTTP など。mod は Node も DOM もない環境で動くので、外に触れるのは必ず $ 経由です。$.ui.toast(…) のように省略せず書きます(読み込み時に静的に棚卸しされるため)。
e
イベントの入力
深く freeze されたプレーンなデータ。直接は書き換えられません。変えたいときは next({ ...e, command }) のようにコピーを渡します。
next
チェーンの残り
next(e) で後ろのフックと Claude Code 本体を実行し、その結果を受け取ります。呼ばずに return すれば、本体の代わりに答えたことになります。
next の 4 つの使い方
-
return next(e)そのまま通す -
return next({ ...e, text })入力を書き換えて通す -
return { deny: "…" }本体を動かさずに答える(拒否など) -
const r = await next(e); …結果を見てから反応する・結果を書き換える
チェーン.
同じイベントにフックした mod は 5 つの tier
に並び、外側から順に呼ばれます。下りで各 mod が e
を書き換え、最後に Claude Code 本体(core)が既定の答えを出し、上りで各 mod
が結果を書き換えます。外側にいるほど権限が強い
と覚えておけば十分です。
- prepend 組織ポリシー prependPlugins
- user あなたが入れた mod ハッカソンで作るのはここ
- append 組織ポリシー appendPlugins
- builtin バイナリ同梱の mod sec-default, diff など
- core Claude Code 本体 既定の答えを出す
組織は prepend と append の両端を持てます。個人の端末で作る mod は user tier に入ります。
イベント.
on("イベント名", マッチャー?, フック)
で受け取ります。各イベントについて「いつ発火するか」と「フックで何を返せるか」をまとめました。マッチャーで対象を絞れます(例: on("tool.call", { tool: "Bash" }, …))。
1 ターンの流れ
- session.start 起動
- prompt.submit 送信
- turn.start ターン開始
- turn.step モデルに問い合わせ
- tool.call ツール実行前
- tool.check 許可判定
- ui.render 画面に描く
- turn.complete ターン終了
- session.end 終了
ツール
tool.call よく使う next({ ...e, command }) で入力を書き換え · { deny } で拒否 · { result } で結果を差し替え · await next(e) の後で結果を加工 tool.check { decision: "allow" | "ask" | "deny" } tool.describe { description, isDeferred } で説明を書き換え プロンプト
prompt.submit よく使う next({ ...e, text }) で書き換え · context でモデルだけが読む文脈を追加 · { drop } で破棄 prompt.edit prompt.fill { isFilled: false } で入れない prompt.suggest next({ ...e, text }) で書き換え · { isShown: false } で出さない prompt.autocomplete { suggestions: [{ text }] } で候補を追加 prompt.mention context を追加 · 別の path を読ませる · { deny } prompt.compose { sections } の追加・置き換え・並べ替え・削除 prompt.section { text } で差し替え · { text: null } で削除 prompt.context { blocks } を追加・削除・書き換え prompt.attachment { text } で差し替え · { text: null } で外す skill.prompt { text } で差し替え attribution.text { text } で差し替え コマンドと設定
command.run よく使う { text } で答える(自作コマンドの応答はここ)· next({ ...e, args }) で引数を書き換え command.describe { description, argumentHint, isHidden } config.set { deny } で変更させない · next({ ...e, value }) で値を補正 config.describe { label, description, isHidden } ターン
turn.start e.agentId なし) turn.step model / effort を差し替え · 応答ストリームを加工(async generator で書く) turn.complete よく使う { text } で回答の下に一行表示(記録は変わらない) セッション
session.start よく使う session.end e.reason) session.compact { skip } で圧縮しない session.append next({ ...e, message }) で内容を書き換え(マスキングなど) session.send { isDelivered: false } で送らない session.receive next({ ...e, text }) で書き換え · { consumed } で受け取って捨てる session.attach · detach session.measure $.session.usage() の値が届く) サブエージェント
agent.offer { isOffered: false } で隠す agent.spawn next({ ...e, model }) でモデルを変える · { deny } 画面
ui.render よく使う await next(e) の描画を包む · props を書き換え · next(e) で何もしない ui.press next(e) で onPress を実行 · 横取りして別の動作 ui.input · ui.select ui.focus · ui.scroll { deny } で動かさない ui.close e.origin.kind: plugin · person · unload) ui.message surface.post(data) したとき { props } で再描画なしに渡し返す ui.fault ui.resolve メタ
plugin.register { refuse } で読み込ませない(組織の審査用) engine.create telemetry.log · mark { deny }。マッチャーで { to: "collector" } を指定 classic.<Event> <noun>.<method> fs.read) { deny } · { value } で代わりに答える * "tool.*" のような glob も使える $ API.
$ はフックの第 1 引数で、mod が外の世界に触れる唯一の手段です。$.名詞.動詞(…)
の形で、省略せずに書きます。呼び出しそれぞれもイベントなので、他の mod から横取りできます(on("fs.read", …) など)。
画面に出す
$.ui
-
.toast(text) - 画面下の通知バーに数秒表示
-
.status(text) - ステータス行に表示(
undefinedで消す) -
.log(text) - トランスクリプトに一行足す
-
.notify(text, { title }) - OS のネイティブ通知
-
.notice(text) - ダイアログの下に一行
-
.ask(…) - AskUserQuestion のダイアログで質問する
-
.open({ id, title }) · close({ id }) · panes() - ペインを開く・閉じる・一覧
-
.focus(…) · scroll(…) - フォーカス・スクロール位置を動かす
-
.copy({ text }) - クリップボードにコピー
-
.selection() - マウスで最後に選択したテキスト
-
.invalidate("ui.render") - 再描画を依頼($.state なら不要)
-
.resolve(e) - その画面の要素(Box, Text …)を得る
-
.blit(…) - 再描画なしで Raster / Image を差し替え
モデルとプロンプト
$.model
-
.complete({ model, prompt }) - 履歴なしの単発補完。結果は
{ isAnswered, text } -
.fork({ prompt }) - この会話の続きとして、ツールなしで 1 回質問
-
.classify(text, labels) - ラベルを 1 つ選ばせる
$.prompt
-
.submit(…) - プロンプトを送る(暇になったら新しいターンを始める)
-
.read() - 入力欄の中身を読む
-
.fill({ text, mode }) - 入力欄に書く(replace · append · insert)
-
.suggest(…) - 入力欄に薄字で提案
-
.compose() - システムプロンプトを組み立てて得る
-
.media({ id }) - 添付画像・文書の中身(managed の mod のみ)
機能を足す
$.command
-
.register({ name, description }) - /コマンドを追加。応答は
command.runで返す -
.run(…) - コマンドを入力したように実行
-
.list() - コマンドの一覧
$.tool
-
.register({ name, description, inputSchema }) - モデルが呼べるツールを追加(
mcp__<plugin>__<name>)。応答はtool.callで返す -
.call(…) - フックと権限を通してツールを実行
-
.check(…) - 許可判定だけを得る
-
.list() - 今あるツールの一覧
$.agent
-
.register(…) - サブエージェントの型を追加(
<plugin>:<name>) -
.spawn({ subagentType, … }) - サブエージェントを起動し、終わるまで待つ
-
.list() - 動いているエージェントの一覧
セッションを知る・操作する
$.session
-
.id() · cwd() · root() · repo() - セッションの識別子と場所
-
.model() · version() · turns() - モデル · Claude Code のバージョン · ターン数
-
.messages() - 会話(1 メッセージ 1 項目の
{ role, text, toolUses }) -
.usage() - コンテキスト使用率 · レート制限 · コスト
-
.compact() · append({ message }) · send(…) - 今すぐ圧縮 · 会話に行を足す · 他セッションへ送る
-
.surfaces() - 接続中の画面(ターミナル · デスクトップ · スマホ)
-
.authorize() - Anthropic 認証のハンドル(
$.http.fetchの auth 用。秘密は渡らない) -
.identity() - サインイン情報(managed の mod のみ)
$.turn
-
.abort() - 実行中のターンを止める
データを持つ
$.state
-
.get(ref) · set(ref, value) - セッション中の値。リロードしても残り、描画中に get すると set で自動再描画
-
.atom · read · update · derive "claude-code"から import する補助関数
$.store
-
.get(key) · set(key, value) · delete(key) · keys() - マシン上の全セッションで共有する KV(JSON、合計 4 MiB)
$.fs
-
.read(path) · write(path, text) · list(path) - ファイルの読み書き(write は非アトミック)
-
.exists(path) · stat(path) · ancestors(…) - 存在確認 · 種類やサイズ · 上位フォルダの指示ファイル
外とつながる
$.http
-
.fetch(url, init) - ホスト経由の HTTP リクエスト
$.process
-
.run({ argv }) · spawn({ argv }) - コマンドを実行(シェルなし)· 出力をストリームで受ける
$.mcp
-
.call(…) · connect(…) - 接続済み MCP サーバーのツールを呼ぶ · 接続する
その他
$.clock
-
.now() · sleep(ms) · after(…) · every(…) - 時刻とキャンセルできるタイマー
$.audio
-
.play({ asset }) · speak(text) - mod 内の音声ファイルを再生 · 読み上げ
$.settings · $.config · $.env
-
.read() · list() / set() · get() / set() - 設定の読み出し · /config の行 · 環境変数
$.telemetry · $.plugin
-
.log() · mark() · name · root - テレメトリ記録 · 自分のプラグイン名とフォルダ
$.state と $.store の使い分け
| $.state | $.store | |
|---|---|---|
| 寿命 | セッションの間(/clear などで初期値) | セッションをまたいで残る |
| ホットリロード | 残る | 残る |
| 再描画 | 描画中の get が購読し、set で自動再描画 | しない |
| 型の宣言 | types/index.d.ts の PluginState に必要 | 不要 |
| 向いている値 | 画面に出す値 | 次回の起動でも使う値 |
引数と戻り値の正確な形は、mod を読み込むと .claude-plugin/types/claude-code/index.d.ts に書き出される型定義が正です。
描画.
on("ui.render", { component: "描画箇所" }, …)
で、Claude Code の画面の決まった場所を自分の UI にできます。まず「どこに描けるか」を画面の図で見てから、使える要素と書き方を確認します。
よく使う 4 つの表示
> ログイン画面のバグを直して
● Read(src/login.ts)
● Bash(npm test)
C ステータスライン ⎇ main · ツール 12 回 · ✓ テスト成功
Tool calls
done Read
done Bash
done Grep
runs Edit
- A ペイン
$.ui.open({ id, title }) + ui.render { component: "Pane" }全画面表示では横にドック、それ以外はプロンプト欄の上に開く。タブで複数持てる - B 帯
ui.render { component: "AbovePrompt" }プロンプト欄の真上の一帯。Button や Input も置ける。全 mod で共有 - C ステータスライン
$.ui.status(text)画面下の行に短い文字列を出す。undefinedで消す。どのフックからでも呼べる - D トースト
$.ui.toast(text)通知バーに数秒だけ出す。どのフックからでも呼べる
どこに描けるか
Tool callsPane
done Read
done Bash
runs Edit
$.ui.open で開く。全画面では横にドック、それ以外はプロンプト欄の上
青枠はハッカソンで特に使いやすい 2 か所(AbovePrompt と Pane)です。図はイメージです。
| component | 画面のどこ | 対応 |
|---|---|---|
InfoNotice | ロゴの下の薄い案内行 | ターミナル |
UserMessage | あなたのプロンプト(> …)、タスク通知、他エージェントからのメッセージ | 両方 |
AssistantMessage | Claude の回答テキスト | 両方 |
ToolUse | ツール呼び出しの行(Bash(ls -la)) | 両方 |
ToolResult | ツール行の下に出る結果 | 両方 |
ToolGroup | まとめられた行(Read 3 files) | 両方 |
ToolProgress | 実行中ツールの進捗行 | ターミナル |
CommandOutput | スラッシュコマンドの出力(自作コマンドの { text } も) | 両方 |
AskUserQuestion | 質問ダイアログ | 両方 |
Spinner | ターン中に動く行(Sautéing… 12s) | 両方 |
TurnDuration | ターンの終わりの行(Baked for 3s) | ターミナル |
AbovePrompt | プロンプト欄の真上の帯。全 mod で共有 | 両方 |
PromptHint | プロンプト欄の下のヒント行(? for shortcuts) | 両方 |
SessionMode | プロンプト欄の下、右端のモード表示 | 両方 |
Pane | $.ui.open で開くパネル。全画面では横にドック | 両方 |
使える要素
const { Box, Text, Button } = $.ui.resolve(e)
で取り出します。画面(e.surface)ごとに使える要素が違います。
| 要素 | 用途 | 主な props | 対応 |
|---|---|---|---|
Box | 並べる・囲む(flexbox) | flexDirection · gap · padding · borderStyle · backgroundColor · hover | 両方 |
Text | 文字 | color · dimColor · weight · size · mono · italic · wrap | 両方 |
Button | 押せるボタン | label · hotkey · onPress · variant · plain | 両方 |
Link | リンク | href · label | 両方 |
Code | シンタックスハイライト付きコード / diff | source · language · path · format: 'diff' | 両方 |
Markdown | 回答と同じ見た目の Markdown | text · onLinkPress | 両方 |
Input | テキスト入力欄 | label · placeholder · value · onInput · onSubmit | 両方 |
Select | 選択肢 | label · options · value · onSelect | 両方 |
Client | 別スレッドで動く描画モジュール(ゲームなど) | module · props · width · height | 両方 |
Raster | 色付きセルのグリッド(グラフ・ヒートマップ) | columns · rows · cells | ターミナル |
Image | 画像(kitty / Ghostty で表示) | source · columns · rows · alt | ターミナル |
Svg | SVG | source · alt · width · height | デスクトップ |
書き方は 4 通り
- 包む
const drawn = await next(e)を自分の Box の子に入れて、前後に足す - 置き換える
nextを呼ばずに自分のツリーを返す - props を変える
next({ ...e, props: { ...e.props, … } })で本体の描画に渡す値だけ変える - 何もしない 描くものがないときは
return next(e)
例: ツール結果の下に一行とボタンを足す(包む)
on("ui.render", { component: "ToolResult" }, async ($, e, next) => {
const { Box, Text, Button } = $.ui.resolve(e)
const drawn = await next(e) // 本体(と内側の mod)が描いたもの
return Box({ flexDirection: "column", children: [
drawn,
Text({ dimColor: true, children: "↳ reviewed" }),
Button({ label: "copy", hotkey: "c", onPress: () => $.ui.toast("copied") }),
] })
}) ペインを作る(公式サンプル)
コマンド登録 → ペインを開く → 値を書く → 描く、の 4 ステップです。ツール呼び出しを記録してサイドパネルに一覧します。
import { atom, read, update } from "claude-code"
import type { Register } from "claude-code"
import type { ToolCall } from "../types"
const PANE = "tool-calls"
const calls = atom({ plugin: "tool-calls", key: "calls" } as const, [])
export const register: Register = on => {
// 1. コマンドを登録し、ペインを開く
on("session.start", async ($, e, next) => {
await $.command.register({ name: "tool-calls", description: "Show tool calls" })
void $.ui.open({ id: PANE, title: "Tool calls" })
return next(e)
})
// 2. 自作コマンドに答える
on("command.run", { command: "tool-calls" }, async $ => {
await $.ui.open({ id: PANE, title: "Tool calls" })
return { text: "Tool calls pane opened." }
})
// 3. 値を $.state に書く(読んでいる描画が自動で描き直される)
on("tool.call", async ($, e, next) => {
await update($, calls, list => [...list, { id: e.tool_use_id, tool: e.tool }].slice(-200))
return next(e)
})
// 4. ペインの中身を描く
on("ui.render", { component: "Pane", requestId: PANE }, async ($, e) => {
const { Box, Text } = $.ui.resolve(e)
const list = await read($, calls)
return (
<Box flexDirection="column">
{list.length === 0 && <Text dimColor>No tool calls yet.</Text>}
{list.map(call => <Text>{call.tool}</Text>)}
</Box>
)
})
} // types/index.d.ts(plugin.json の "types" で指す)
export type ToolCall = { id: string; tool: string }
declare module "claude-code" {
interface PluginState {
"tool-calls": { calls: ToolCall[] }
}
} 描画のルール
- ・要素は
$.ui.resolve(e)から取り出す(グローバルにはない)。.tsxなら JSX でも書ける - ・Pane と AbovePrompt は
e.props.bodyColumnsの幅に合わせて描く - ・描画中に
$.state.getした値は、$.state.setされると自動で描き直される。手動なら$.ui.invalidate("ui.render") - ・描画中に
$.state.setは呼べない。ボタンのonPressや別のイベントから書く - ・検証に通らないツリー(その画面にない要素など)は描かれず、本体の描画に戻る。理由はトランスクリプトに薄字で出る
- ・描画が出るのはターミナルとデスクトップアプリ(Code タブ)。
e.surfaceで出し分けられる
3 つの型.
作りたいもののほとんどは、次の 3 つのどれか、または組み合わせです。
1. ガード tool.call + { deny }
危険なコマンドや本番への操作を止める。失敗時に素通りしないよう .catch を付けるのが定石です。
export function register(on) {
on("tool.call", { tool: "Bash" }, async ($, e, next) => {
if (e.command.includes("git push --force")) {
return { deny: "force push は使わないでください" } // 本体の代わりに答える
}
const r = await next(e) // 後ろのフックと本体を実行
$.ui.toast("Bash ran") // 結果を見てから反応する
return r
}).catch(($, e, next) =>
next.called ? next(e) : { deny: "ガードが失敗したので止めました" })
} 2. 常駐 UI ui.render + $.state
プロンプト欄の上やサイドパネルに情報を出し続ける。値は $.state に置けば、書き換えるだけで再描画されます。($.state を使う mod は types/index.d.ts で値の型を宣言します)
const turns = { plugin: "turn-counter", key: "turns" }
export function register(on) {
on("turn.complete", async ($, e, next) => {
const r = await next(e)
if (!e.agentId) {
const { value = 0 } = await $.state.get(turns)
await $.state.set(turns, value + 1)
}
return r
})
on("ui.render", { component: "AbovePrompt" }, async ($, e, next) => {
const { value = 0 } = await $.state.get(turns) // 描画中の get が購読になる
if (value === 0) return next(e)
const { Text } = $.ui.resolve(e)
return Text({ dimColor: true, children: `このセッション ${value} ターン目` })
})
} 3. 記憶 prompt.submit + $.store
セッションをまたいで覚えておきたいことを、毎回のプロンプトに文脈として添える。
export function register(on) {
on("prompt.submit", async ($, e, next) => {
const notes = await $.store.get("notes").catch(() => undefined)
if (typeof notes !== "string") return next(e)
// モデルだけが読む文脈を足す(画面には出ない)
return next({ ...e, context: [...(e.context ?? []), notes] })
})
} はじめかた.
A. Claude に書いてもらう(最短)
-
Claude Code で
/plugin-authoringを実行し、「こういう mod を作って」と頼む - 「Enable hot reloading for this session?」と聞かれたら Enable for this session を選ぶ
- ターンが終わると読み込まれる。以降は修正を頼むたびにホットリロード
/pluginで読み込まれているか確認
B. 自分で書く
my-mod/
├── .claude-plugin/
│ └── plugin.json { "name": "my-mod", "version": "0.1.0", "description": "…" }
├── hooks/
│ ├── hooks.json { "modules": ["./register.ts"] }
│ └── register.ts export function register(on, options) { … }
├── types/index.d.ts $.state を使うときだけ(plugin.json の "types" で指す)
└── tests/*.test.ts claude plugin test で実行 -
claude --plugin-dir ./my-modその 1 セッションだけ読み込む。保存するとホットリロード -
claude plugin validate ./my-modフックしたイベント、呼んでいる $、拒否される箇所を一覧(--strict --json) -
claude plugin test ./my-mod*.test.ts を本物のランタイムで実行 -
tsc -p ./my-mod読み込み後に .claude-plugin/types/ に型が出るので型チェックできる -
/plugin · /reload-plugins読み込み中の mod を確認 · 再読み込み
C. 配る
mod のリポジトリに marketplace.json を置けば、そのまま配布できます。
// .claude-plugin/marketplace.json(mod のリポジトリ直下)
{
"name": "my-mods",
"owner": { "name": "you" },
"plugins": [{ "name": "my-mod", "source": "./" }]
} 使う側はターミナルの Claude Code で:
/plugin install my-mod --marketplace <owner>/<repo> ハマりどころ.
- 読み込まれない 信頼していないフォルダでは、エラーも出さずに読み込まれません。/plugin で「1 mod active」と出るか確認します。
- $ は省略せず書く $.ui.toast(…) のように名詞と動詞をそのまま書きます。const ui = $.ui のような書き方や import() は読み込みで拒否されます。
- 状態の置き場所 保存のたびに register が再実行され、モジュール変数は消えます。画面に出す値は $.state、次回の起動でも使う値は $.store に置きます。
- 描画中は書けない ui.render の中で $.state.set は使えません。ボタンの onPress や別のイベントから書きます。
- 時間の上限 フック自身の実行は 1 イベント 10 秒まで(next や $ を待つ時間は数えない)。.catch は 1 秒です。
- ガードには .catch .catch がないと、フックが例外を投げたときに止めたかった操作がそのまま通ります。
- 変数名 h JSX はタグを h(…) の呼び出しに変換します。.tsx でローカル変数に h という名前を付けると描画が壊れます。
- $ の reject await した $ 呼び出しの reject を放置すると mod 全体が外れます。.catch で受けておきます。
- 名前 plugin.json の name を claude- で始めると validate で弾かれます。
- 描画が出る場所 描画が出るのはターミナルとデスクトップアプリ(Code タブ)。VS Code のチャットや claude -p ではフックだけが動きます。
- 組織の端末 Team / Enterprise や管理端末では sec-default が外側に入り、個人の mod が触れない箇所があります。v2.1.299 から /plugin と validate がスキップされたフックを表示します。
アイデア.
何を作るか迷ったときのたたき台です。右側は使う API の目安です。
安全
-
force push・rm -rf・本番 DB 接続を止める
tool.call + { deny }
-
コミット前に秘密情報をスキャン
tool.call + 正規表現
-
本番デプロイだけ 2 段階承認
tool.call + $.ui.ask
開発体験
-
コミット前に lint / test を自動で通す
tool.call + $.process.run
-
/pr で差分から PR 説明を生成
$.command.register + $.model.complete
-
編集したファイルの影響範囲をパネルに出す
tool.call + ui.render(Pane)
見える化
-
コスト・コンテキスト残量の HUD
session.measure + $.ui.status
-
サブエージェントの進捗ダッシュボード
$.agent.list + ui.render(Pane)
-
CI の状態を常時表示
$.http.fetch + $.clock.every
体験・遊び
-
長いタスクの終了を読み上げ / 通知
turn.complete + $.audio.speak / $.ui.notify
-
待ち時間のミニゲーム
ui.render(AbovePrompt)+ Client
-
ツール結果に「セカンドオピニオン」ボタン
ui.render + Button + $.model.fork
記憶・連携
-
過去の失敗パターンを毎回の文脈に添える
prompt.submit + $.store
-
社内 API をモデルが呼べるツールにする
$.tool.register + $.http.fetch
-
/ticket で Linear / Jira に起票
$.command.register + $.http.fetch
最近の変更.
v2.1.296〜v2.1.299 で入った主な変更です。
- v2.1.299 $.prompt.media(添付画像・文書の中身を読む)と $.session.identity() を追加。どちらも managed settings で入れた mod だけが使えます。
- v2.1.299 Text に size · weight · mono · tabular を追加(bold は weight に置き換え予定)。Box の余白に xs〜xl の段階指定。
- v2.1.299 turn.start がサブエージェントとチームメイトのターンでも発火(メインでは e.agentId なし)。agent.spawn が終了したサブエージェントの再開でも発火(e.resume)。
- v2.1.299 skill.prompt の e にフロントマター・ソース・ファイルパス。session.append に queue の経路。
- v2.1.299 止められる操作は、フックに渡せないとき通さずに拒否する(fail-closed)。組織管理でスキップされたフックを /plugin と validate が表示。
- v2.1.296 $.http.fetch の 4 MiB 上限が HEAD を拒否しなくなった(2.1.299 で 204 · 205 · 304 も対象外に)。
API は early access で、リリースごとに変わることがあります。