← 一覧に戻る

ダッシュボード改修 完了サマリ (j-20260503-003)

2026年5月3日 15:32 更新
MD から自動変換されたページです。内容について質問があれば右下の ? ボタンからどうぞ。

起源: msg 5312-5327 健人指示「ダッシュボード改修+plan-viewer統合+3行+URLのみ+気をつけるじゃなく仕組み化」 実施日: 2026-05-03 指針: 既存 mini-apps-ui (DISPATCH CONSOLE) を 4 ラベル UI に再構築し、Telegram 上の判断系 reply を「3 行 + ダッシュボード URL」に強制テンプレ化する。気をつけるのではなく hook で仕組み化する。

4 ラベル定義

ラベル 含まれるもの 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/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 本文には載せない。

propose / question

report-propose-v2.sh / report-question-v2.sh も同方式。 inline_keyboard (承認/却下/選択肢) は仕組み上必要なので継続。

長文 reply のガード

PreToolUse hook (secretary-reply-length-guard.sh) が mcp__plugin_telegram_telegram__reply / send_messagetext 長を監視し、200 字超で deny を返す。例外は tool_input.allow_long=true

ログ: ~/.claude/logs/secretary-reply-guard.log

既知の制約・残課題

  1. 本番デプロイは未実施: 現状 Tailscale Funnel は mbp.tail863a2a.ts.net → 127.0.0.1:8765 (plan-viewer Python) を向いている。mini-apps-api は 127.0.0.1:3721 で別ポート稼働中。Telegram WebView から DISPATCH CONSOLE を開けるようにするには、以下のいずれかが必要 (健人判断):
    • A: Funnel を 8765 → 3721 (mini-apps-api) に切替、plan-viewer は別経路 / 別ポート (8766 等) に逃す
    • B: Caddy / nginx で /app/* → 3721, それ以外 → 8765 に振る reverse proxy
    • C: Cloudflare Pages にビルド成果物だけ別ドメインで公開
    • 推奨: A が最小工数。plan-viewer は単純な静的配信なので別ポートで python3 -m http.server を 8766 等に起動し、ブックマークの URL だけ更新すれば済む。
  2. mini-apps-api のリロードが必要: launchd 経由で bun run src/index.ts (非 watch) なので、変更を反映するには launchctl kickstart -k gui/$(id -u)/com.aiharataketo.secretary で再起動。再起動中の数秒間 Telegram からの API 呼び出しは失敗する。
  3. read_at の書き込み権限: mini-apps-api は jobs.db を読み取り専用 (db.ts) と書き込み (db-rw.ts) の 2 接続で運用。read_at 以外を書ける経路は db-rw.ts に追加しない限り存在しないので、サーフェスは最小限。
  4. 既存 report-*.sh の互換: v1 は当面残置 (削除はせず未使用にする)。完全廃止は別タスクで段階的に。
  5. PreToolUse hook の例外: チバ回答転送など長文を素のまま渡す reply は tool_input.allow_long=true を秘書側で明示的に付与する必要がある。秘書プロンプト側でそのケースを書き足すかどうかは運用しながら判断。
  6. MenuButton 設定: 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

完了条件 (done_when) チェック

条件 結果 根拠
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 を安易に増やせない構造を担保した。

なぜ buckets.ts を SQL CASE + TS 関数の二重定義にしたか

SQL 側は /api/buckets で全件分類してレスポンスに含めるため (1 fetch / 4 セクション)、 TS 側は SSE 等で個別ジョブが届いた時にクライアントで再分類するため。 両者が乖離しないよう、定義を 1 ファイル buckets.ts に集約した。

なぜ INBOX に DONE+未読を入れるか

完了報告を出した瞬間に「健人が見るべきもの」になるから。Telegram には 3 行しか送らない仕組みに切り替えると、DONE の中身は必ずダッシュボードで読まれる必要がある。read_at で「読んだか」を実観測することで、未読 DONE が ARCHIVE に紛れて見落とされるのを防ぐ。

なぜ PreToolUse hook を allow_long で例外許容にしたか

チバ回答 (恋愛コーチからの長文) や、過去履歴のサマリなど、ダッシュボードを通さず直接 Telegram で読みたい例外がある。完全 deny にすると秘書が回避策で 200 字を頻繁に超えるようになり、結局形骸化する。例外を明示的なオプトインにしておくことで、運用上の柔軟性と仕組み強制を両立した。

📝 質問モード — テキストを選択してね
✓ 質問を送信しました