起源: msg 5312-5327 健人指示「ダッシュボード改修+plan-viewer統合+3行+URLのみ+気をつけるじゃなく仕組み化」 実施日: 2026-05-03 指針: 既存 mini-apps-ui (DISPATCH CONSOLE) を 4 ラベル UI に再構築し、Telegram 上の判断系 reply を「3 行 + ダッシュボード URL」に強制テンプレ化する。気をつけるのではなく hook で仕組み化する。
| ラベル | 含まれるもの | jobs.status / awaiting_reply_kind |
|---|---|---|
| IN PROGRESS | 進行中 | SENT / IN_PROGRESS / VERIFYING |
| INBOX | 健人が判断・確認するもの | WAIT / propose_approval / ask_user_question / DONE & 未読 |
| TASKS | 動いてないタスク | PENDING / BACKLOG / RETRY |
| ARCHIVE | 完了済 | DONE & read_at / FAILED / EXPIRED |
JobDetail を開くと read_at に時刻が入り、DONE の INBOX → ARCHIVE 遷移が自動で起きる。
~/secretary-state/migrations/2026-05-03_dashboard_revamp.sql — read_at / plan_viewer_url カラム追加~/secretary-state/report-done-v2.sh — 3 行 + URL の完了報告~/secretary-state/report-propose-v2.sh — 3 行 + URL + 承認ボタンの提案~/secretary-state/report-question-v2.sh — 3 行 + URL + 選択肢ボタンの質問~/.claude/scripts/secretary-reply-length-guard.sh — 200 字超 reply 強制ブロック PreToolUse hook~/secretary-state/mini-apps-api/src/lib/buckets.ts — 4 ラベル分類の単一定義 (SQL CASE + TS 関数)~/secretary-state/mini-apps-api/src/lib/db-rw.ts — read_at 更新限定の書き込み接続~/secretary-state/mini-apps-api/src/routes/buckets.ts — GET /api/buckets~/secretary-state/mini-apps-ui/src/components/BucketCard.tsx — plan-viewer 風カード~/secretary-state/mini-apps-ui/src/components/BucketTabs.tsx — 上部固定 4 タブ~/.claude/secretary/settings.json — PreToolUse hook 追加 (reply / send_message)~/.claude/secretary/prompt.md — v2 スクリプト誘導 + 4 ラベル統一節を追加~/secretary-state/mini-apps-api/src/index.ts — /api/buckets ルート追加~/secretary-state/mini-apps-api/src/routes/jobs.ts — read_at / plan_viewer_url を SELECT に追加、POST /api/jobs/:id/read / unread 追加~/secretary-state/mini-apps-ui/src/api/types.ts — Bucket / BucketsResponse / read_at / plan_viewer_url 追加~/secretary-state/mini-apps-ui/src/api/client.ts — fetchBuckets / markJobRead 追加~/secretary-state/mini-apps-ui/src/pages/Dashboard.tsx — 4 セクション + 上部タブにフルリプレース~/secretary-state/mini-apps-ui/src/pages/JobDetail.tsx — マウント時 read_at 自動更新、plan_viewer_url リンク追加~/secretary-state/mini-apps-ui/src/styles/global.css — bucket-tabs / bucket-card / bucket-section スタイル追加~/secretary-state/mini-apps-ui/README.md — 開発・本番ビルド・Tailscale Funnel・MenuButton 手順を記載~/secretary-state/jobs.db.bak-20260503-151314 — マイグレーション直前のスナップショット~/secretary-state/report-done-v2.sh JOB_ID CHAT_ID
→ Telegram には:
✅ j-20260503-XXX 完了
🎯 [intent 80字]
詳細をダッシュボードで開く ← MarkdownV2 リンク
詳細 (verification_summary / done_when 検証結果 / next_action / plan-viewer URL) は すべてダッシュボードに集約。Telegram 本文には載せない。
report-propose-v2.sh / report-question-v2.sh も同方式。
inline_keyboard (承認/却下/選択肢) は仕組み上必要なので継続。
PreToolUse hook (secretary-reply-length-guard.sh) が
mcp__plugin_telegram_telegram__reply / send_message の
text 長を監視し、200 字超で deny を返す。例外は tool_input.allow_long=true。
ログ: ~/.claude/logs/secretary-reply-guard.log
mbp.tail863a2a.ts.net → 127.0.0.1:8765 (plan-viewer Python) を向いている。mini-apps-api は 127.0.0.1:3721 で別ポート稼働中。Telegram WebView から DISPATCH CONSOLE を開けるようにするには、以下のいずれかが必要 (健人判断):8765 → 3721 (mini-apps-api) に切替、plan-viewer は別経路 / 別ポート (8766 等) に逃す/app/* → 3721, それ以外 → 8765 に振る reverse proxypython3 -m http.server を 8766 等に起動し、ブックマークの URL だけ更新すれば済む。bun run src/index.ts (非 watch) なので、変更を反映するには launchctl kickstart -k gui/$(id -u)/com.aiharataketo.secretary で再起動。再起動中の数秒間 Telegram からの API 呼び出しは失敗する。db.ts) と書き込み (db-rw.ts) の 2 接続で運用。read_at 以外を書ける経路は db-rw.ts に追加しない限り存在しないので、サーフェスは最小限。tool_input.allow_long=true を秘書側で明示的に付与する必要がある。秘書プロンプト側でそのケースを書き足すかどうかは運用しながら判断。mini-apps-api/scripts/set-menu.ts で BotFather API を叩く既存スクリプトあり。デプロイ確定後に 1 回実行すれば良い。# 1. API 再起動
launchctl kickstart -k gui/$(id -u)/com.aiharataketo.secretary
# 2. ローカル UI dev (任意)
cd ~/secretary-state/mini-apps-ui && bun run dev
# 3. 本番ビルド
cd ~/secretary-state/mini-apps-ui && bunx vite build
# 4. ダッシュボード URL で確認
open https://mbp.tail863a2a.ts.net/app/ # ※ 上記制約 1 を解消後
# 5. v2 スクリプト dry-run
REPORT_DONE_DRY_RUN=1 ~/secretary-state/report-done-v2.sh j-XXXXXX-NNN 8888
| 条件 | 結果 | 根拠 |
|---|---|---|
| Dashboard 4 セクション + 上部タブ | ✅ | Dashboard.tsx + BucketTabs.tsx + global.css |
| jobs.db 4 ステータス分類でカード表示 | ✅ | buckets.ts (CASE) + BucketCard.tsx |
| JobDetail で verification 統合表示 + 既読移行 | ✅ | JobDetail.tsx の useEffect で markJobRead |
| report-*-v2.sh 動作確認 | ✅ | dry-run で j-20260331-010 を整形済 (テストログ参照) |
| 長文 reply hook で 200 字超を block | ✅ | secretary-reply-length-guard.sh の3パターンテストで確認 |
| 秘書プロンプト 4 ラベル定義 | ✅ | prompt.md の「4ラベル統一」節 |
| 本番 URL アクセス + デプロイ手順 README | ⚠️ 部分 | README は記載、本番デプロイは制約 1 で健人判断待ち |
| 改修サマリ報告 | ✅ | 本ドキュメント |
db-rw.ts を別ファイルにしたかjobs.db の書き込みサーフェスを最小化するため。db.ts (readonly) と分離することで、
将来 read_at 以外の UPDATE を安易に増やせない構造を担保した。
SQL 側は /api/buckets で全件分類してレスポンスに含めるため (1 fetch / 4 セクション)、
TS 側は SSE 等で個別ジョブが届いた時にクライアントで再分類するため。
両者が乖離しないよう、定義を 1 ファイル buckets.ts に集約した。
完了報告を出した瞬間に「健人が見るべきもの」になるから。Telegram には 3 行しか送らない仕組みに切り替えると、DONE の中身は必ずダッシュボードで読まれる必要がある。read_at で「読んだか」を実観測することで、未読 DONE が ARCHIVE に紛れて見落とされるのを防ぐ。
チバ回答 (恋愛コーチからの長文) や、過去履歴のサマリなど、ダッシュボードを通さず直接 Telegram で読みたい例外がある。完全 deny にすると秘書が回避策で 200 字を頻繁に超えるようになり、結局形骸化する。例外を明示的なオプトインにしておくことで、運用上の柔軟性と仕組み強制を両立した。