Skip to content

feat: add inter-session communication inspired by Clawdbot - #15

Merged
Chachamaru127 merged 6 commits into
mainfrom
claude/study-competitor-repo-PBcJJ
Jan 24, 2026
Merged

Chachamaru127 merged 6 commits into
mainfrom
claude/study-competitor-repo-PBcJJ

Conversation

@Chachamaru127

@Chachamaru127 Chachamaru127 commented Jan 23, 2026 •

Copy link
Copy Markdown
Owner

Implemented features learned from Clawdbot competitor analysis:

Session Communication (Phase 1):

  • /session-broadcast: Send messages to all sessions
  • /session-inbox: Check received messages
  • /session-list: Show active sessions

Hooks Integration:

  • Auto inbox check before Write/Edit (5-min interval)
  • Auto broadcast on API/type file changes

External Automation (Phase 2):

  • /webhook-setup: GitHub Actions integration for auto-review

Future Design (Phase 4):

  • E2E verification design document (CDP/Playwright)

This maintains Harness's lightweight plugin philosophy while
adding real-time-ish session awareness capabilities.

https://claude.ai/code/session_01GgwkKJXFZpZWdh1etQbvaw

Summary by CodeRabbit

  • 新機能

    • セッション間ブロードキャスト、インボックス、アクティブセッション一覧と自動インボックス/自動ブロードキャストフックを追加
    • 軽量 MCP サーバーによるクロスクライアントツール群(セッション/ステータス/ワークフロー)を追加
  • ドキュメント

    • Webhook(GitHub Actions)セットアップ、E2E 検証設計、MCP README、関連ファイル検証ガイドなど多数を追加
  • 変更

    • リリースノート更新とバージョン上げ(2.9.24)

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai

coderabbitai Bot commented Jan 23, 2026 •

Copy link
Copy Markdown

Caution

Review failed

The pull request is closed.

Walkthrough

セッション間ブロードキャスト/受信トレイ機能のドキュメントと Bash ユーティリティ、Pre/Post フックの追加、MCP サーバー(session/status/workflow ツール群)実装、関連ファイル検証スキル設計、Webhook/GitHub Actions 設定ドキュメント、及びバージョン・CHANGELOG 更新を追加しました。(50語以内)

Changes

Cohort / File(s) 変更概要
ドキュメント(セッション/Webhook/E2E/MCP等)
commands/optional/session-broadcast.md, commands/optional/session-inbox.md, commands/optional/session-list.md, commands/optional/webhook-setup.md, commands/optional/mcp-setup.md, docs/E2E_VERIFICATION_DESIGN.md, mcp-server/README.md, skills/verify/SKILL.md, skills/verify/references/verify-related-files.md, CHANGELOG.md, CHANGELOG_ja.md, README.md, README_ja.md
新規/更新ドキュメントを追加:セッションコマンド仕様、Webhook(GitHub Actions)セットアップ、E2E 検証設計、MCP サーバー導入手順、検証スキル参照、変更履歴と README の更新。
フック設定
hooks/hooks.json
PreToolUse と PostToolUse エントリ追加(pretooluse-inbox-check, session-auto-broadcast)。
Bash スクリプト(セッション管理・フック)
scripts/pretooluse-inbox-check.sh, scripts/session-auto-broadcast.sh, scripts/session-broadcast.sh, scripts/session-inbox-check.sh, scripts/session-list.sh, scripts/*
受信箱チェック(5分クールダウン)、自動ブロードキャストトリガ、ブロードキャスト書き出し(上限保持)、未読チェック/マーキング、アクティブセッション一覧などのユーティリティを追加。
MCP サーバー実装(TypeScript)
mcp-server/package.json, mcp-server/tsconfig.json, mcp-server/src/index.ts, mcp-server/src/tools/session.ts, mcp-server/src/tools/status.ts, mcp-server/src/tools/workflow.ts, mcp-server/src/utils.ts
新規パッケージとして stdio ベースの MCP サーバーを追加:ツール列挙・ディスパッチ、session/status/workflow ツール群、ファイルベース永続化ユーティリティを実装。
コアワークフロー更新
commands/core/work.md, skills/verify/*
実装後の「関連ファイル検証(Related-check)」をフェーズに挿入し、verify-related-files スキルをワークフローへ組み込み。
メタ情報更新
.claude-plugin/plugin.json, VERSION, CHANGELOG*, README*
プラグイン/バージョンバンプ(2.9.23 → 2.9.24)と関連 README/Changelog の更新。

Sequence Diagram(s)

sequenceDiagram
    participant User as ユーザー
    participant Tool as ツール
    participant PreHook as pretooluse-inbox-check
    participant Inbox as session-inbox-check
    participant Storage as .claude/sessions
    participant PostHook as session-auto-broadcast
    participant Broadcast as session-broadcast.sh

    User->>Tool: ツール起動
    Tool->>PreHook: PreToolUse フック呼び出し
    PreHook->>Storage: 最終チェック時刻確認 (.last_inbox_check)
    alt クールダウン内
        PreHook-->>Tool: 最小出力で戻る
    else
        PreHook->>Inbox: 未読数取得 (--count / --hook)
        Inbox->>Storage: broadcast.md と last-read を参照
        Inbox-->>PreHook: 未読数と要約を返す
        PreHook->>Tool: 未読通知(フック出力)
        PreHook->>Storage: .last_inbox_check 更新
    end

    Tool->>Tool: 本体処理(例:ファイル編集)
    Tool->>PostHook: PostToolUse フック呼び出し(file path を含む)
    PostHook->>Storage: auto-broadcast.json を読み込みパターン照合
    alt パターン一致
        PostHook->>Broadcast: `session-broadcast.sh --auto <file> <msg>` 実行
        Broadcast->>Storage: broadcast.md に追記(古い項目剪定)
        Broadcast-->>PostHook: フック用 JSON 出力
        PostHook-->>Tool: ブロードキャスト完了出力
    else
        PostHook-->>Tool: 空出力(何もしない)
    end

    Tool-->>User: 実行完了
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Poem

🐰 ぽん、と跳ねて告げます

ファイルに声を残し、受信箱が鳴り、
仲間の足跡が一覧に並び、
小さな橋(MCP)がクライアントを繋ぎ、
明日の検証が静かに始まる。

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 36.11% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed PRのタイトルは、セッション間通信機能の追加というメインの変更を的確に要約しており、Clawdbotの競合分析から着想を得たことを明確に示しています。

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Fix all issues with AI agents
In `@commands/optional/session-inbox.md`:
- Around line 34-36: MD040 is triggered because the fenced code blocks for the
snippets are missing a language tag; update the two fences containing the lines
`/session-inbox --mark` and `bash
"${CLAUDE_PLUGIN_ROOT}/scripts/session-inbox-check.sh"` to use a bash language
specifier (i.e., change the opening backticks to ```bash) so both code fences
are explicitly marked as bash.

In `@scripts/pretooluse-inbox-check.sh`:
- Around line 60-68: The script builds INBOX_SUMMARY and ESCAPED_SUMMARY but the
JSON emitted by the heredoc uses only ${UNREAD_COUNT}, so the unread-summary is
never included; update the emitted JSON (the heredoc that writes
hookSpecificOutput.additionalContext) to include ESCAPED_SUMMARY (or
INBOX_SUMMARY) in the additionalContext value (escaping as appropriate), or if
you decide not to include a summary remove the INBOX_SUMMARY/ESCAPED_SUMMARY
generation lines to avoid dead code; refer to the variables INBOX_SUMMARY and
ESCAPED_SUMMARY and the heredoc that currently prints hookSpecificOutput to
locate and fix the code.

In `@scripts/session-inbox-check.sh`:
- Around line 22-28: The get_session_id function falls back to "unknown" when jq
is missing, which differs from session-broadcast.sh's behavior of returning a
generated session name like session-$(date +%s); update get_session_id to match
by returning the same generated session string when jq isn't available or
SESSION_FILE doesn't exist, mirroring session-broadcast.sh logic so session
identifiers remain consistent across scripts (adjust the get_session_id function
to emit the session-$(date +%s) fallback instead of "unknown").
🧹 Nitpick comments (9)
commands/optional/webhook-setup.md (1)

209-209: 裸の URL をマークダウンリンクに変換することを検討してください。

URL をマークダウンリンク形式 [text](url) で囲むと、アクセシビリティと一貫性が向上します。

📝 修正案
-> 💡 API キーは https://console.anthropic.com で取得できます
+> 💡 API キーは [Anthropic Console](https://console.anthropic.com) で取得できます
scripts/session-list.sh (4)

12-12: 未使用の変数 SCRIPT_DIR があります。

この変数は定義されていますが、スクリプト内で使用されていません。削除するか、将来の使用予定があればコメントで説明を追加してください。

🧹 削除する場合の修正案
-SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"

81-83: 未使用の変数 active_count、stale_count、および tmp_file があります。

これらの変数は初期化されていますが、使用されていません。将来の機能(セッションのクリーンアップなど)のためのプレースホルダーであれば、TODO コメントを追加することを検討してください。

🧹 修正案
-  local active_count=0
-  local stale_count=0
-  local tmp_file=$(mktemp)
+  # TODO: セッションのクリーンアップ機能実装時に使用
+  # local active_count=0
+  # local stale_count=0

89-113: パイプ内の while ループはサブシェルで実行されるため、ループ内で更新された変数は外部に反映されません。

active_count や stale_count を使用する予定がある場合、プロセス置換 (< <(...)) を使用するか、一時ファイル経由で処理する必要があります。また、status 変数は抽出されていますが使用されていません。

♻️ プロセス置換を使用した修正案
-  jq -r 'to_entries[] | "\(.key)|\(.value.short_id)|\(.value.last_seen)|\(.value.status)"' "$ACTIVE_FILE" 2>/dev/null | while IFS='|' read -r full_id short_id last_seen status; do
+  while IFS='|' read -r full_id short_id last_seen _status; do
     local age=$((current_time - last_seen))
     # ... rest of the loop
-  done
+  done < <(jq -r 'to_entries[] | "\(.key)|\(.value.short_id)|\(.value.last_seen)|\(.value.status)"' "$ACTIVE_FILE" 2>/dev/null)

37-38: local 宣言と代入を分離して、コマンドの終了ステータスをマスクしないようにしてください。

local var=$(cmd) は常に成功を返すため、コマンドの失敗を検出できません。

📝 修正案
-  local current_session=$(get_current_session_id)
-  local current_time=$(get_current_timestamp)
+  local current_session
+  current_session=$(get_current_session_id)
+  local current_time
+  current_time=$(get_current_timestamp)
scripts/session-broadcast.sh (2)

13-13: 未使用の変数 SCRIPT_DIR があります。

他のスクリプト(session-list.sh など)と同様に、この変数は定義されていますが使用されていません。


79-80: local 宣言と代入を分離してください。

Shellcheck SC2155: コマンドの終了ステータスがマスクされる可能性があります。

📝 修正案
-  local session_id=$(get_session_id)
-  local timestamp=$(get_timestamp)
+  local session_id
+  session_id=$(get_session_id)
+  local timestamp
+  timestamp=$(get_timestamp)
scripts/session-inbox-check.sh (1)

148-156: JSON エスケープ処理が複雑で、特殊文字を含むメッセージで問題が発生する可能性があります。

現在の sed パイプラインは改行とクォートを処理していますが、バックスラッシュやその他の特殊文字(タブ、制御文字など)が含まれる場合に JSON が壊れる可能性があります。

♻️ jq を使用した安全なエスケープ案
     if [ "$unread_count" -gt 0 ]; then
-      local escaped_messages=$(echo -e "$unread_messages" | sed 's/\\/\\\\/g; s/"/\\"/g; s/$/\\n/' | tr -d '\n' | sed 's/\\n$//')
+      local escaped_messages
+      escaped_messages=$(echo -e "$unread_messages" | jq -Rs '.' | sed 's/^"//; s/"$//')
       cat <<EOF
scripts/session-auto-broadcast.sh (1)

75-85: カスタムパターンの読み取りロジックを改善できます。

jq の出力が空の場合、while read ループは1回実行されて空文字列を処理します。-n "$pattern" チェックで保護されていますが、より明示的なハンドリングが可能です。

📝 改善案
 if [ "$should_broadcast" = "false" ] && [ -f "$CONFIG_FILE" ] && command -v jq >/dev/null 2>&1; then
-  CUSTOM_PATTERNS=$(jq -r '.patterns // [] | .[]' "$CONFIG_FILE" 2>/dev/null)
+  CUSTOM_PATTERNS=$(jq -r '.patterns // [] | .[]' "$CONFIG_FILE" 2>/dev/null || true)
+  if [ -n "$CUSTOM_PATTERNS" ]; then
   while IFS= read -r pattern; do
     if [ -n "$pattern" ] && [[ "$FILE_PATH" == *"$pattern"* ]]; then
       should_broadcast="true"
       matched_pattern="$pattern"
       break
     fi
   done <<< "$CUSTOM_PATTERNS"
+  fi
 fi

Comment thread commands/optional/session-inbox.md
Comment on lines +60 to +68
# 未読メッセージの概要を取得
INBOX_SUMMARY=$(bash "$SCRIPT_DIR/session-inbox-check.sh" 2>/dev/null | head -5 || echo "")

# エスケープ処理
ESCAPED_SUMMARY=$(echo "$INBOX_SUMMARY" | sed 's/\\/\\\\/g; s/"/\\"/g; s/$/\\n/' | tr -d '\n' | sed 's/\\n$//')

cat <<EOF
{"hookSpecificOutput":{"hookEventName":"PreToolUse","additionalContext":"📨 他セッションからの未読メッセージが ${UNREAD_COUNT}件 あります。\\n/session-inbox で確認してください。"}}
EOF

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

未読概要が通知に反映されていません

Line 60-65 で概要を生成していますが、Line 66-68 の出力に使われていません。通知に要約を含めるか、不要なら生成処理を削除してください。

🛠️ 追加Contextに概要を含める例
-  cat <<EOF
-{"hookSpecificOutput":{"hookEventName":"PreToolUse","additionalContext":"📨 他セッションからの未読メッセージが ${UNREAD_COUNT}件 あります。\\n/session-inbox で確認してください。"}}
-EOF
+  cat <<EOF
+{"hookSpecificOutput":{"hookEventName":"PreToolUse","additionalContext":"📨 他セッションからの未読メッセージが ${UNREAD_COUNT}件 あります。\\n/session-inbox で確認してください。\\n${ESCAPED_SUMMARY}"}}
+EOF
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
# 未読メッセージの概要を取得
INBOX_SUMMARY=$(bash "$SCRIPT_DIR/session-inbox-check.sh" 2>/dev/null | head -5 || echo "")
# エスケープ処理
ESCAPED_SUMMARY=$(echo "$INBOX_SUMMARY" | sed 's/\\/\\\\/g; s/"/\\"/g; s/$/\\n/' | tr -d '\n' | sed 's/\\n$//')
cat <<EOF
{"hookSpecificOutput":{"hookEventName":"PreToolUse","additionalContext":"📨 他セッションからの未読メッセージが ${UNREAD_COUNT}件 あります。\\n/session-inbox で確認してください。"}}
EOF
# 未読メッセージの概要を取得
INBOX_SUMMARY=$(bash "$SCRIPT_DIR/session-inbox-check.sh" 2>/dev/null | head -5 || echo "")
# エスケープ処理
ESCAPED_SUMMARY=$(echo "$INBOX_SUMMARY" | sed 's/\\/\\\\/g; s/"/\\"/g; s/$/\\n/' | tr -d '\n' | sed 's/\\n$//')
cat <<EOF
{"hookSpecificOutput":{"hookEventName":"PreToolUse","additionalContext":"📨 他セッションからの未読メッセージが ${UNREAD_COUNT}件 あります。\\n/session-inbox で確認してください。\\n${ESCAPED_SUMMARY}"}}
EOF
🧰 Tools
🪛 Shellcheck (0.11.0)

[warning] 64-64: ESCAPED_SUMMARY appears unused. Verify use (or export if used externally).

(SC2034)

🤖 Prompt for AI Agents
In `@scripts/pretooluse-inbox-check.sh` around lines 60 - 68, The script builds
INBOX_SUMMARY and ESCAPED_SUMMARY but the JSON emitted by the heredoc uses only
${UNREAD_COUNT}, so the unread-summary is never included; update the emitted
JSON (the heredoc that writes hookSpecificOutput.additionalContext) to include
ESCAPED_SUMMARY (or INBOX_SUMMARY) in the additionalContext value (escaping as
appropriate), or if you decide not to include a summary remove the
INBOX_SUMMARY/ESCAPED_SUMMARY generation lines to avoid dead code; refer to the
variables INBOX_SUMMARY and ESCAPED_SUMMARY and the heredoc that currently
prints hookSpecificOutput to locate and fix the code.

Comment thread scripts/session-inbox-check.sh
Implemented features learned from Clawdbot competitor analysis:

Session Communication (Phase 1):
- /session-broadcast: Send messages to all sessions
- /session-inbox: Check received messages
- /session-list: Show active sessions

Hooks Integration:
- Auto inbox check before Write/Edit (5-min interval)
- Auto broadcast on API/type file changes

External Automation (Phase 2):
- /webhook-setup: GitHub Actions integration for auto-review

Future Design (Phase 4):
- E2E verification design document (CDP/Playwright)

This maintains Harness's lightweight plugin philosophy while
adding real-time-ish session awareness capabilities.

https://claude.ai/code/session_01GgwkKJXFZpZWdh1etQbvaw
Add a new verification step that automatically checks for missed file
updates after implementation:

- Detect function signature changes → warn about unchecked callers
- Detect interface/type changes → warn about implementation inconsistencies
- Detect export changes → warn about broken imports
- Detect config changes → warn about unsynchronized related configs

Integrated into /work flow:
- Phase 1: Related-check added to task-worker self-review loop
- Phase 3: Final related files verification before commit

Co-Authored-By: Claude <noreply@anthropic.com>
Enables Claude Code, Codex, and Cursor to share sessions via MCP protocol.

MCP Server (mcp-server/):
- Session tools: list, broadcast, inbox, register
- Workflow tools: plan, work, review
- Status tools: project status

New Commands:
- /mcp-setup: Configure MCP for different clients

This allows seamless collaboration between different AI clients
working on the same project, with real-time message passing.

https://claude.ai/code/session_01GgwkKJXFZpZWdh1etQbvaw
@Chachamaru127
Chachamaru127 force-pushed the claude/study-competitor-repo-PBcJJ branch from 3ddcdc2 to 7e17f40 Compare January 23, 2026 17:54
Merged features:
- Automatic detection of missed updates after implementation
- Function signature change detection
- Interface/type change warnings
- Export modification alerts
- Config change verification

Integrated into /work workflow (Phase 1 and Phase 3)

https://claude.ai/code/session_01GgwkKJXFZpZWdh1etQbvaw
Added documentation for:
- Inter-session communication (/session-broadcast, /session-inbox, /session-list)
- MCP Server for cross-client support (Claude Code, Codex, Cursor)
- Webhook automation (/webhook-setup)
- E2E verification design

Updated both English and Japanese versions.

https://claude.ai/code/session_01GgwkKJXFZpZWdh1etQbvaw

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 8

Note

Due to the large number of review comments, Critical, Major severity comments were prioritized as inline comments.

🤖 Fix all issues with AI agents
In `@mcp-server/src/tools/session.ts`:
- Around line 280-282: Assigning sessionId/client to process.env
(process.env.HARNESS_SESSION_ID, process.env.HARNESS_CLIENT) inside
handleRegister mutates global state for the entire MCP server; stop using
process.env for request-scoped session data and instead store the values on a
request-scoped context object or pass them through the call chain. Replace
writes to process.env in handleRegister with a per-request Context (e.g.,
sessionContext or a property on the incoming request object) and update any
consumers to read from that context (or accept sessionId/client as parameters)
so different requests/sessions don't clobber each other.
- Around line 103-118: The loadSessions/saveSessions pair has a race where
concurrent saveSessions() calls can overwrite each other; modify saveSessions to
perform an atomic write by writing JSON to a temporary file in the same
directory (e.g., ACTIVE_FILE + ".tmp" or using a unique suffix), fsync the temp
file (or file descriptor), then rename/replace the temp to ACTIVE_FILE
(fs.renameSync) to ensure atomic replace; keep loadSessions() unchanged but
ensure it reads ACTIVE_FILE only after rename so it never sees a
partially-written file; alternatively, if you prefer locking, add an exclusive
lock around loadSessions/saveSessions (e.g., using a simple advisory lock or a
small lockfile) to serialize access to ACTIVE_FILE.
- Around line 27-31: SESSIONS_DIR and derived constants (ACTIVE_FILE,
BROADCAST_FILE) use a raw relative path; replace them to resolve against the
project root using getProjectRoot() (as done in status.ts/workflow.ts) and
path.join so paths work regardless of process.cwd(); import getProjectRoot and
path, set SESSIONS_DIR = path.join(getProjectRoot(), ".claude", "sessions") and
build ACTIVE_FILE/BROADCAST_FILE from that SESSIONS_DIR.

In `@mcp-server/src/tools/status.ts`:
- Around line 31-45: getProjectRoot currently uses `while (current !== "/")`
which hangs on Windows because `path.dirname("C:\\") === "C:\\"`; change the
loop to detect root correctly (e.g., compute const root =
path.parse(current).root and stop when current === root or when
path.dirname(current) === current) and return the last checked directory if no
marker found; update references to the function (notably the duplicate in
workflow.ts) by extracting getProjectRoot into a shared utility module and
importing it from both places to remove duplication. Ensure you reference and
update the function named getProjectRoot and the duplicate implementation in
workflow.ts when making these changes.

In `@mcp-server/src/tools/workflow.ts`:
- Around line 86-101: getProjectRoot is duplicated in workflow.ts and status.ts
and uses a Unix-only loop termination (current !== "/"); extract a single
exported getProjectRoot into a common utility module, replace both local
definitions with imports, and remove the duplicates. Implement the termination
using path.parse(current).root (or comparing current === path.dirname(current))
so it works on Windows, keep the same marker list and fs.existsSync logic, and
update any references in workflow.ts and status.ts to call the shared
getProjectRoot.

In `@scripts/session-auto-broadcast.sh`:
- Around line 96-98: The hook JSON currently interpolates FILE_NAME directly
into a here-doc (cat <<EOF ...) which can break if FILE_NAME contains quotes or
backslashes; replace the heredoc JSON construction with a safe JSON generator
using jq -n --arg to pass FILE_NAME (e.g. use jq -n --arg fileName "$FILE_NAME"
'{hookSpecificOutput: {hookEventName:"AutoBroadcast", additionalContext: ("📢
自動ブロードキャスト: " + $fileName + " の変更を他セッションに通知しました")}}' ) and emit that output
instead of the raw heredoc so the FILE_NAME is properly escaped.

In `@scripts/session-broadcast.sh`:
- Around line 90-109: Wrap the append and pruning sequence that writes to
BROADCAST_FILE (the echo "## ${timestamp} ..." block, the msg_count grep, mktemp
creation, awk filtering and mv) inside a file lock; detect and prefer flock when
available (e.g. if command -v flock) and otherwise use an exclusive lock via a
dedicated lock fd (exec 200>"${BROADCAST_FILE}.lock"; flock 200 ...; exec
200>&-). Ensure mktemp and temp_file creation/cleanup and the mv into
BROADCAST_FILE happen while the lock is held, and release the lock after
completion; add a trap to remove temp_file on exit/error to avoid stale temp
files. This will protect BROADCAST_FILE and the MAX_MESSAGES pruning logic from
concurrent runs.
- Around line 116-119: The current here-doc emits unescaped JSON using the raw
${message:0:50}, breaking when message contains " or \; replace the heredoc
block that prints hookSpecificOutput with a jq-based generator (use jq -n --arg
truncated "$(echo "${message}" | cut -c1-50)" '{hookSpecificOutput:
{hookEventName:"Broadcast", additionalContext: ("📤 ブロードキャスト送信: " +
$truncated)}}') so jq handles proper JSON escaping; update the branch that
checks HOOK_OUTPUT to call jq (or fail/emit a safe fallback if jq is
unavailable) and reference the HOOK_OUTPUT check and the message variable in the
change.
♻️ Duplicate comments (2)
scripts/pretooluse-inbox-check.sh (1)

60-68: ESCAPED_SUMMARY が生成されているが出力に含まれていません

Line 64 で ESCAPED_SUMMARY を生成していますが、Line 66-68 の JSON 出力には使用されていません。概要を通知に含めるか、不要であれば生成処理を削除してください。

scripts/session-inbox-check.sh (1)

22-28: get_session_id のフォールバックが session-broadcast.sh と一貫性がありません

session-broadcast.sh では jq がない場合 session-$(date +%s) を返しますが、このスクリプトでは unknown を返しています。この不一致により、jq がインストールされていない環境でセッション追跡に問題が発生する可能性があります。

🔧 一貫性のある修正案
 get_session_id() {
   if [ -f "$SESSION_FILE" ] && command -v jq >/dev/null 2>&1; then
     jq -r '.session_id // "unknown"' "$SESSION_FILE" 2>/dev/null
   else
-    echo "unknown"
+    echo "session-$(date +%s)"
   fi
 }

関連コード: scripts/session-broadcast.sh の 21-27 行目を参照してください。

🟡 Minor comments (16)
commands/optional/webhook-setup.md-209-209 (1)

209-209: 裸URLをリンク表記にしてください

MD034 に抵触します。

🛠 変更案
-> 💡 API キーは https://console.anthropic.com で取得できます
+> 💡 API キーは <https://console.anthropic.com> で取得できます
docs/E2E_VERIFICATION_DESIGN.md-66-72 (1)

66-72: ベースURLは裸リンクではなくコード/リンク表記にしてください

MD034 に抵触します。

🛠 変更案
-| `--base-url` | 対象URL | http://localhost:3000 |
+| `--base-url` | 対象URL | `http://localhost:3000` |
mcp-server/README.md-93-115 (1)

93-115: フェンス付きブロックに言語指定を追加してください

図とツリーのフェンスが MD040 に抵触しています。

🛠 変更案
-```
+```text
[Claude Code]                         [Codex]
...

- +text
mcp-server/
├── src/
...
└── README.md

Also applies to: 135-146

commands/optional/mcp-setup.md-45-45 (1)

45-45: 強調ではなく見出しにしてください

見出し扱いの文が強調になっており、MD036 に抵触します。

🛠 変更案
-**ユーザーの回答を待つ**
+#### ユーザーの回答を待つ
commands/optional/webhook-setup.md-44-44 (1)

44-44: 強調ではなく見出しにしてください

MD036 に抵触します。

🛠 変更案
-**ユーザーの回答を待つ**
+#### ユーザーの回答を待つ
commands/optional/mcp-setup.md-134-153 (1)

134-153: コードブロックに言語指定を追加してください

フェンスに言語がなく MD040 に抵触します。

🛠 変更案
-```
+```text
[Claude Code]
You: harness_session_register を実行して、client: "claude-code"
...
You: OK、新しい API を使って実装を続けて
</details>

</blockquote></details>
<details>
<summary>docs/E2E_VERIFICATION_DESIGN.md-15-44 (1)</summary><blockquote>

`15-44`: **フェンス付きブロックに言語指定を追加してください**

MD040 に抵触しています。  


<details>
<summary>🛠 変更案</summary>

```diff
-```
+```text
┌─────────────────────────────────────────────────────────┐
...
└───────────┘

- +text
.claude/e2e/
├── baseline/
...
└── diff/


-```
+```text
/verify
├── build
...
└── e2e
</details>


Also applies to: 113-123, 143-149

</blockquote></details>
<details>
<summary>commands/optional/session-broadcast.md-34-52 (1)</summary><blockquote>

`34-52`: **フェンス付きブロックに言語指定を追加してください**

MD040 に抵触しています。  


<details>
<summary>🛠 変更案</summary>

```diff
-```
+```text
「他のセッションに、API変更したことを伝えて」
→ ブロードキャストメッセージを送信

- +text
{ユーザーのメッセージ}

CHANGELOG.md-46-51 (1)

46-51: CHANGELOG に今回の PR の主要機能(セッション間通信)が記載されていません。

追加された verify-related-files 機能は記載されていますが、PR の主題である以下の機能が CHANGELOG に含まれていません:

  • /session-broadcast, /session-inbox, /session-list コマンド
  • MCP サーバーによるセッション通信機能
  • Hooks 統合(PreToolUse inbox check, PostToolUse auto-broadcast)

マージ前に CHANGELOG を更新することを推奨します。

mcp-server/src/tools/status.ts-125-128 (1)

125-128: args が undefined の場合にデストラクチャリングエラーが発生します。

handleStatusTool から args が undefined で渡される可能性がありますが、handleStatus で直接デストラクチャリングするとエラーになります。

🐛 修正案
 function handleStatus(args: { verbose?: boolean }): {
   content: Array<{ type: string; text: string }>;
 } {
-  const { verbose = false } = args;
+  const { verbose = false } = args || {};
mcp-server/src/tools/workflow.ts-111-121 (1)

111-121: execSync は git がない環境や最初のコミット前に例外を投げます。

現在の catch ブロックは空配列を返しますが、エラーの種類(git 未インストール vs HEAD~1 不在 vs その他)を区別できません。HEAD~1 が存在しない場合は git diff --staged --name-only など代替手段を検討してください。

♻️ より堅牢な実装案
 function getRecentChanges(): string[] {
   try {
-    const output = execSync("git diff --name-only HEAD~1", {
+    // Try HEAD~1 first, fallback to staged changes
+    let output: string;
+    try {
+      output = execSync("git diff --name-only HEAD~1", {
+        encoding: "utf-8",
+        cwd: getProjectRoot(),
+        stdio: ['pipe', 'pipe', 'pipe'],
+      });
+    } catch {
+      output = execSync("git diff --staged --name-only", {
+        encoding: "utf-8",
+        cwd: getProjectRoot(),
+        stdio: ['pipe', 'pipe', 'pipe'],
+      });
+    }
-      encoding: "utf-8",
-      cwd: getProjectRoot(),
-    });
     return output.trim().split("\n").filter(Boolean);
   } catch {
     return [];
   }
 }
mcp-server/src/tools/status.ts-47-59 (1)

47-59: getPlansStatus() は PlansParser と異なるマーカー形式でカウントしており、状態計算に不整合があります。

getPlansStatus() は cc:TODO、cc:WIP、cc:DONE のテキスト出現回数をカウントしていますが、PlansParser はチェックボックス(- [ ], - [x])とバッククォート内のマーカー(`cc:TODO` など)を構文的に解析しています。

さらに、実際の Plans.md では cc:DONE は使用されておらず、代わりに cc:完了 またはチェックボックス [x] で完了を表現しているため、getPlansStatus() の "done" カウントは常にゼロになります。

例えば - [x] タスク cc:WIP という行では、PlansParser は "completed" と判定しますが、getPlansStatus() は "wip" とカウントするため、ユーザーに異なる進捗情報が表示される恐れがあります。

commands/core/work.md-516-523 (1)

516-523: 関連ファイル検証セクションのコードフェンスに言語指定を追加してください。

Line 516 と Line 525 のフェンスが未指定で MD040 に該当します。text などを指定してください。

🧩 修正案
-```
+```text
 Run related files verification:
 → Detect function signature changes → check callers
@@
 → Detect config changes → check related configs

@@
- +text
📋 Related Files Verification
@@
3. Show LSP find-references

Also applies to: 525-536

skills/verify/references/verify-related-files.md-105-113 (1)

105-113: 出力例フェンスの言語指定が不足しています。

Line 105 ほか複数のフェンスが MD040 に該当します。text 等の言語指定を全箇所に付与してください。

🧩 修正例(他の未指定フェンスにも同様に適用)
-```
+```text
 変更された関数/型を特定
     ↓
 LSP find-references を実行
     ↓
 全参照箇所をリスト化
     ↓
 未編集の参照箇所を警告

</details>


Also applies to: 139-146, 170-177, 194-200, 204-206, 213-220, 238-248, 252-274, 278-298

</blockquote></details>
<details>
<summary>skills/verify/SKILL.md-164-178 (1)</summary><blockquote>

`164-178`: **このコードフェンスにも言語指定を付けてください。**

Line 164 のフェンスが未指定で MD040 に該当します。`text` などを指定してください。  


<details>
<summary>🧩 修正案</summary>

```diff
-```
+```text
 編集ファイルを取得
     ↓
┌─────────────────────────────────────────┐
│           関連ファイル検証               │
@@
   修正漏れ候補を警告

</details>

</blockquote></details>
<details>
<summary>commands/optional/session-inbox.md-89-96 (1)</summary><blockquote>

`89-96`: **コードフェンスに言語指定を追加してください。**

Line 89 のフェンスが言語未指定で MD040 に該当します。`text` などを付与してください。  


<details>
<summary>🧩 修正案</summary>

```diff
-```
+```text
 You: このファイルを編集して
@@
 Claude: 承知しました。UserAPI の変更を考慮して編集します...

</details>

</blockquote></details>

</blockquote></details>

<details>
<summary>🧹 Nitpick comments (7)</summary><blockquote>

<details>
<summary>mcp-server/src/tools/session.ts (1)</summary><blockquote>

`240-244`: **`toLocaleTimeString()` はロケールに依存し、出力形式が非決定的です。**

サーバー環境やユーザーの設定によって時刻形式が変わるため、一貫性のある出力を得るには明示的なフォーマットを指定してください。


<details>
<summary>♻️ 修正案</summary>

```diff
   const formatted = unread
     .map((msg) => {
-      const time = new Date(msg.timestamp).toLocaleTimeString();
+      const date = new Date(msg.timestamp);
+      const time = date.toISOString().slice(11, 19); // HH:MM:SS
       return `[${time}] ${msg.client}: ${msg.message}`;
     })
     .join("\n");
mcp-server/src/index.ts (1)

52-62: ルーティングのプレフィックスパターンに一貫性がありません。

harness_session_* と harness_workflow_* はアンダースコア区切りですが、harness_status には後続のアンダースコアがありません。startsWith("harness_status") は harness_status_verbose のような将来のツールにもマッチしますが、harness_statusXYZ のような意図しないツール名にもマッチします。

一貫性のため harness_status_* パターンに統一するか、または完全一致と組み合わせることを検討してください。

♻️ より明確なルーティング
-    if (name.startsWith("harness_status")) {
+    if (name === "harness_status" || name.startsWith("harness_status_")) {
       return await handleStatusTool(name, args);
     }
scripts/pretooluse-inbox-check.sh (2)

18-18: 未使用の変数 SESSION_FILE を削除してください

SESSION_FILE は宣言されていますが、スクリプト内で使用されていません。不要なコードは混乱を招くため削除を推奨します。

🔧 修正案
 SESSIONS_DIR=".claude/sessions"
 BROADCAST_FILE="${SESSIONS_DIR}/broadcast.md"
-SESSION_FILE=".claude/state/session.json"
 CHECK_INTERVAL_FILE="${SESSIONS_DIR}/.last_inbox_check"

22-28: 未使用の変数 INPUT を削除してください

stdin から JSON を読み取っていますが、INPUT 変数はその後使用されていません。必要がなければ、このコードブロック全体を削除することを検討してください。

🔧 修正案
-# ===== stdin から JSON 入力を読み取り =====
-INPUT=""
-if [ -t 0 ]; then
-  : # stdin が TTY の場合は入力なし
-else
-  INPUT=$(cat 2>/dev/null || true)
-fi
-
 # ===== チェック間隔の確認 =====
scripts/session-list.sh (2)

12-12: 未使用の変数 SCRIPT_DIR を削除してください

SCRIPT_DIR は宣言されていますが、スクリプト内で使用されていません。

🔧 修正案
-SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
-
 # ===== 設定 =====

80-83: 未使用の変数と未実装のクリーンアップ処理

active_count、stale_count、tmp_file が宣言されていますが使用されていません。コメントには「古いセッションをクリーンアップ」と記載されていますが、実装されていません。不要であれば削除するか、TODO コメントを追加してください。

🔧 修正案(未使用変数の削除)
-  # 古いセッションをクリーンアップしながら表示
-  local active_count=0
-  local stale_count=0
-  local tmp_file=$(mktemp)
-
   echo "| セッションID | 最終アクティブ | 状態 |"
scripts/session-inbox-check.sh (1)

14-14: 未使用の変数 SCRIPT_DIR を削除してください

SCRIPT_DIR は宣言されていますが、スクリプト内で使用されていません。

🔧 修正案
-SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
-
 # ===== 設定 =====

Comment thread mcp-server/src/tools/session.ts Outdated
Comment on lines +103 to +118
function loadSessions(): Record<string, Session> {
ensureSessionsDir();
if (fs.existsSync(ACTIVE_FILE)) {
try {
return JSON.parse(fs.readFileSync(ACTIVE_FILE, "utf-8"));
} catch {
return {};
}
}
return {};
}

function saveSessions(sessions: Record<string, Session>): void {
ensureSessionsDir();
fs.writeFileSync(ACTIVE_FILE, JSON.stringify(sessions, null, 2));
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

ファイル読み書きに競合状態(Race Condition)のリスクがあります。

複数のセッションが同時に loadSessions() → saveSessions() を実行すると、後から書き込んだセッションが先のセッションの変更を上書きする可能性があります。

ファイルロックの導入、または atomic write パターン(一時ファイルに書き込んでからリネーム)の検討を推奨します。

🤖 Prompt for AI Agents
In `@mcp-server/src/tools/session.ts` around lines 103 - 118, The
loadSessions/saveSessions pair has a race where concurrent saveSessions() calls
can overwrite each other; modify saveSessions to perform an atomic write by
writing JSON to a temporary file in the same directory (e.g., ACTIVE_FILE +
".tmp" or using a unique suffix), fsync the temp file (or file descriptor), then
rename/replace the temp to ACTIVE_FILE (fs.renameSync) to ensure atomic replace;
keep loadSessions() unchanged but ensure it reads ACTIVE_FILE only after rename
so it never sees a partially-written file; alternatively, if you prefer locking,
add an exclusive lock around loadSessions/saveSessions (e.g., using a simple
advisory lock or a small lockfile) to serialize access to ACTIVE_FILE.

Comment thread mcp-server/src/tools/session.ts
Comment thread mcp-server/src/tools/status.ts Outdated
Comment thread mcp-server/src/tools/workflow.ts Outdated
Comment on lines +96 to +98
cat <<EOF
{"hookSpecificOutput":{"hookEventName":"AutoBroadcast","additionalContext":"📢 自動ブロードキャスト: ${FILE_NAME} の変更を他セッションに通知しました"}}
EOF

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Hook JSON の文字列をエスケープしてください。

FILE_NAME に ", \ などが含まれると JSON が壊れ、フック処理が失敗する可能性があります。jq -n --arg で JSON を生成する形にしてください。

🧩 修正案
-  # 通知メッセージを出力
-  cat <<EOF
-{"hookSpecificOutput":{"hookEventName":"AutoBroadcast","additionalContext":"📢 自動ブロードキャスト: ${FILE_NAME} の変更を他セッションに通知しました"}}
-EOF
+  # 通知メッセージを出力(JSON エスケープ)
+  msg="📢 自動ブロードキャスト: ${FILE_NAME} の変更を他セッションに通知しました"
+  jq -n --arg msg "$msg" \
+    '{"hookSpecificOutput":{"hookEventName":"AutoBroadcast","additionalContext":$msg}}'
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
cat <<EOF
{"hookSpecificOutput":{"hookEventName":"AutoBroadcast","additionalContext":"📢 自動ブロードキャスト: ${FILE_NAME} の変更を他セッションに通知しました"}}
EOF
# 通知メッセージを出力(JSON エスケープ)
msg="📢 自動ブロードキャスト: ${FILE_NAME} の変更を他セッションに通知しました"
jq -n --arg msg "$msg" \
'{"hookSpecificOutput":{"hookEventName":"AutoBroadcast","additionalContext":$msg}}'
🤖 Prompt for AI Agents
In `@scripts/session-auto-broadcast.sh` around lines 96 - 98, The hook JSON
currently interpolates FILE_NAME directly into a here-doc (cat <<EOF ...) which
can break if FILE_NAME contains quotes or backslashes; replace the heredoc JSON
construction with a safe JSON generator using jq -n --arg to pass FILE_NAME
(e.g. use jq -n --arg fileName "$FILE_NAME" '{hookSpecificOutput:
{hookEventName:"AutoBroadcast", additionalContext: ("📢 自動ブロードキャスト: " +
$fileName + " の変更を他セッションに通知しました")}}' ) and emit that output instead of the raw
heredoc so the FILE_NAME is properly escaped.

Comment on lines +90 to +109
# ブロードキャストファイルに追記
{
echo ""
echo "## ${timestamp} [${short_id}]"
echo "${prefix}${message}"
} >> "$BROADCAST_FILE"

# 古いメッセージを削除(MAX_MESSAGES を超えた場合)
if [ -f "$BROADCAST_FILE" ]; then
local msg_count=$(grep -c "^## " "$BROADCAST_FILE" 2>/dev/null || echo "0")
if [ "$msg_count" -gt "$MAX_MESSAGES" ]; then
# 最新の MAX_MESSAGES 件のみ保持
local temp_file=$(mktemp)
local skip_count=$((msg_count - MAX_MESSAGES))
awk -v skip="$skip_count" '
/^## / { count++ }
count > skip { print }
' "$BROADCAST_FILE" > "$temp_file"
mv "$temp_file" "$BROADCAST_FILE"
fi

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

broadcast.md の追記・剪定はロックで保護してください。

複数セッションの同時実行で追記や剪定が競合し、メッセージ欠落や破損が起き得ます。ファイルロックで保護してください。

🧩 修正案(flock がある場合のみロック)
+  if command -v flock >/dev/null 2>&1; then
+    exec 200>"${BROADCAST_FILE}.lock"
+    flock -x 200
+  fi
+
   # ブロードキャストファイルに追記
   {
     echo ""
     echo "## ${timestamp} [${short_id}]"
     echo "${prefix}${message}"
   } >> "$BROADCAST_FILE"
@@
   if [ -f "$BROADCAST_FILE" ]; then
     local msg_count=$(grep -c "^## " "$BROADCAST_FILE" 2>/dev/null || echo "0")
     if [ "$msg_count" -gt "$MAX_MESSAGES" ]; then
@@
       mv "$temp_file" "$BROADCAST_FILE"
     fi
   fi
+
+  if command -v flock >/dev/null 2>&1; then
+    flock -u 200
+    exec 200>&-
+  fi
🧰 Tools
🪛 Shellcheck (0.11.0)

[warning] 99-99: Declare and assign separately to avoid masking return values.

(SC2155)


[warning] 102-102: Declare and assign separately to avoid masking return values.

(SC2155)

🤖 Prompt for AI Agents
In `@scripts/session-broadcast.sh` around lines 90 - 109, Wrap the append and
pruning sequence that writes to BROADCAST_FILE (the echo "## ${timestamp} ..."
block, the msg_count grep, mktemp creation, awk filtering and mv) inside a file
lock; detect and prefer flock when available (e.g. if command -v flock) and
otherwise use an exclusive lock via a dedicated lock fd (exec
200>"${BROADCAST_FILE}.lock"; flock 200 ...; exec 200>&-). Ensure mktemp and
temp_file creation/cleanup and the mv into BROADCAST_FILE happen while the lock
is held, and release the lock after completion; add a trap to remove temp_file
on exit/error to avoid stale temp files. This will protect BROADCAST_FILE and
the MAX_MESSAGES pruning logic from concurrent runs.

Comment on lines +116 to +119
if [ "${HOOK_OUTPUT:-}" = "true" ]; then
cat <<EOF
{"hookSpecificOutput":{"hookEventName":"Broadcast","additionalContext":"📤 ブロードキャスト送信: ${message:0:50}..."}}
EOF

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Hook 用 JSON もエスケープ処理が必要です。

message に " や \ が含まれると JSON が壊れます。jq -n --arg などで生成してください。

🧩 修正案
   # JSON 出力(hooks 用)
   if [ "${HOOK_OUTPUT:-}" = "true" ]; then
-    cat <<EOF
-{"hookSpecificOutput":{"hookEventName":"Broadcast","additionalContext":"📤 ブロードキャスト送信: ${message:0:50}..."}}
-EOF
+    if command -v jq >/dev/null 2>&1; then
+      jq -n --arg msg "📤 ブロードキャスト送信: ${message:0:50}..." \
+        '{"hookSpecificOutput":{"hookEventName":"Broadcast","additionalContext":$msg}}'
+    else
+      local escaped
+      escaped=$(printf '%s' "📤 ブロードキャスト送信: ${message:0:50}..." | sed 's/\\/\\\\/g; s/"/\\"/g')
+      echo "{\"hookSpecificOutput\":{\"hookEventName\":\"Broadcast\",\"additionalContext\":\"$escaped\"}}"
+    fi
   fi
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if [ "${HOOK_OUTPUT:-}" = "true" ]; then
cat <<EOF
{"hookSpecificOutput":{"hookEventName":"Broadcast","additionalContext":"📤 ブロードキャスト送信: ${message:0:50}..."}}
EOF
if [ "${HOOK_OUTPUT:-}" = "true" ]; then
if command -v jq >/dev/null 2>&1; then
jq -n --arg msg "📤 ブロードキャスト送信: ${message:0:50}..." \
'{"hookSpecificOutput":{"hookEventName":"Broadcast","additionalContext":$msg}}'
else
local escaped
escaped=$(printf '%s' "📤 ブロードキャスト送信: ${message:0:50}..." | sed 's/\\/\\\\/g; s/"/\\"/g')
echo "{\"hookSpecificOutput\":{\"hookEventName\":\"Broadcast\",\"additionalContext\":\"$escaped\"}}"
fi
fi
🤖 Prompt for AI Agents
In `@scripts/session-broadcast.sh` around lines 116 - 119, The current here-doc
emits unescaped JSON using the raw ${message:0:50}, breaking when message
contains " or \; replace the heredoc block that prints hookSpecificOutput with a
jq-based generator (use jq -n --arg truncated "$(echo "${message}" | cut
-c1-50)" '{hookSpecificOutput: {hookEventName:"Broadcast", additionalContext:
("📤 ブロードキャスト送信: " + $truncated)}}') so jq handles proper JSON escaping; update
the branch that checks HOOK_OUTPUT to call jq (or fail/emit a safe fallback if
jq is unavailable) and reference the HOOK_OUTPUT check and the message variable
in the change.

Changes based on code review findings:

1. **Code Quality (P0)**:
   - Extract getProjectRoot() to shared utils.ts module
   - Change package name from @Anthropic-AI to @claude-code-harness
   - Add safeReadJSON/safeWriteJSON with error logging

2. **Performance**:
   - Convert execSync to async exec in getRecentChangesAsync()
   - Use shared constants for thresholds and limits

3. **Maintainability**:
   - Replace magic numbers with named constants
   - Add type definitions for session/message data
   - Extract plan template generation to separate function

4. **Shell Scripts**:
   - Add trap cleanup for temp files in session-broadcast.sh
   - Add trap cleanup for temp files in session-list.sh
   - Remove unused dead code (unused mktemp)

Co-Authored-By: Claude <noreply@anthropic.com>
@Chachamaru127
Chachamaru127 merged commit 8a35b4e into main Jan 24, 2026
1 of 2 checks passed
@Chachamaru127
Chachamaru127 deleted the claude/study-competitor-repo-PBcJJ branch February 11, 2026 06:04
kimseunghyun-kr added a commit to kimseunghyun-kr/claude_team_harness that referenced this pull request May 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants