ai/ai
1
0

add session claude

This commit is contained in:
2025-06-07 03:54:04 +09:00
parent 36522e3646
commit e34e579656
11 changed files with 1553 additions and 43 deletions

View File

@@ -7,7 +7,16 @@
"Bash(sed:*)", "Bash(sed:*)",
"Bash(ls:*)", "Bash(ls:*)",
"Bash(grep:*)", "Bash(grep:*)",
"Bash(git submodule:*)" "Bash(git submodule:*)",
"Bash(./claude/scripts/update-submodules.sh:*)",
"Bash(git fetch:*)",
"Bash(git reset:*)",
"Bash(git add:*)",
"Bash(git commit:*)",
"Bash(zsh:*)",
"Bash(git pull:*)",
"Bash(jq:*)",
"Bash(chmod:*)"
], ],
"deny": [] "deny": []
} }

4
.gitmodules vendored
View File

@@ -1,9 +1,9 @@
[submodule "moji"] [submodule "moji"]
path = moji path = moji
url = git@git.syui.ai:ai/moji.git url = git@git.syui.ai:ai/moji
[submodule "os"] [submodule "os"]
path = os path = os
url = git@git.syui.ai:ai/os.git url = git@git.syui.ai:ai/os
[submodule "verse"] [submodule "verse"]
path = verse path = verse
url = git@git.syui.ai:ai/verse url = git@git.syui.ai:ai/verse

View File

@@ -6,3 +6,50 @@
[2025-06-07 02:59:35] [INFO] Submodule update completed: 0/1 updated [2025-06-07 02:59:35] [INFO] Submodule update completed: 0/1 updated
[2025-06-07 03:00:30] [INFO] Starting submodule update (all=true, module=, auto=true, dry-run=false) [2025-06-07 03:00:30] [INFO] Starting submodule update (all=true, module=, auto=true, dry-run=false)
[2025-06-07 03:00:32] [INFO] Submodule update completed: 0/1 updated [2025-06-07 03:00:32] [INFO] Submodule update completed: 0/1 updated
[2025-06-07 03:08:58] [INFO] Starting submodule update (all=false, module=verse, auto=false, dry-run=false)
[2025-06-07 03:09:38] [INFO] Starting submodule update (all=true, module=, auto=false, dry-run=false)
[2025-06-07 03:09:39] [INFO] Submodule update completed: 0/1 updated
[2025-06-07 03:12:48] [INFO] Starting submodule update (all=false, module=verse, auto=false, dry-run=true)
[2025-06-07 03:12:55] [INFO] Starting submodule update (all=true, module=, auto=false, dry-run=true)
[2025-06-07 03:16:24] [INFO] Starting submodule update (all=false, module=verse, auto=false, dry-run=false)
[2025-06-07 03:16:24] [INFO] Found 8 submodules: card bot moji game os gpt shell verse
[2025-06-07 03:16:25] [INFO] Submodule update completed: 0/1 updated
[2025-06-07 03:16:31] [INFO] Starting submodule update (all=true, module=, auto=false, dry-run=true)
[2025-06-07 03:16:31] [INFO] Found 8 submodules: card bot moji game os gpt shell verse
[2025-06-07 03:21:50] [INFO] Starting submodule update (all=true, module=, auto=false, dry-run=true)
[2025-06-07 03:21:50] [INFO] Found 8 submodules: card bot moji game os gpt shell verse
[2025-06-07 03:22:03] [INFO] Starting submodule update (all=true, module=, auto=true, dry-run=false)
[2025-06-07 03:22:03] [INFO] Found 8 submodules: card bot moji game os gpt shell verse
[2025-06-07 03:22:04] [INFO] Updated card on branch claude: 725783bbca98a0dc88be1925d3208f941bcd7bdc -> 13723cf3d74e3d22c514b60413f790ef28ccf2aa
[2025-06-07 03:22:05] [INFO] Updated bot on branch claude: 998777d46a0dbe679eaf7a7bf7f5ed89ea99c652 -> a17d2c9d66f791ae2e2dc9567905f82de0e10a2a
[2025-06-07 03:22:06] [INFO] Updated moji on branch main: dcbebe6576647f4e5cdf32118f4c4b4b34e9c06a -> 81d36c3096ffbe50cd644ee4f6da267cc1a31eae
[2025-06-07 03:22:07] [INFO] Updated os on branch main: 591c34b61b379271f9264281c76632ec64a0f673 -> 21cd1ef16e9c736a4ea342716bc3857fe2864f82
[2025-06-07 03:22:09] [INFO] Auto-committed 4 submodule updates
[2025-06-07 03:22:09] [INFO] Submodule update completed: 4/8 updated
[2025-06-07 03:28:10] [INFO] Starting submodule update (all=false, module=, auto=false, dry-run=false)
[2025-06-07 03:28:10] [INFO] Found 8 submodules: card bot moji game os gpt shell verse
[2025-06-07 03:28:10] [INFO] URL validation passed: all URLs consistent
[2025-06-07 03:28:19] [INFO] Starting submodule update (all=true, module=, auto=false, dry-run=true)
[2025-06-07 03:28:19] [INFO] Found 8 submodules: card bot moji game os gpt shell verse
[2025-06-07 03:30:47] [INFO] Starting submodule update (all=false, module=, auto=false, dry-run=false)
[2025-06-07 03:30:47] [INFO] Using git base URL:
[2025-06-07 03:30:47] [INFO] Found 8 submodules: card bot moji game os gpt shell verse
[2025-06-07 03:30:47] [INFO] URL validation passed: all URLs consistent
[2025-06-07 03:31:09] [INFO] Starting submodule update (all=false, module=, auto=false, dry-run=false)
[2025-06-07 03:31:09] [INFO] Using git base URL: git@git.syui.ai:ai
[2025-06-07 03:31:09] [INFO] Found 8 submodules: card bot moji game os gpt shell verse
[2025-06-07 03:31:09] [INFO] URL validation passed: all URLs consistent
[2025-06-07 03:34:38] [INFO] Starting submodule update (all=false, module=, auto=false, dry-run=false)
[2025-06-07 03:34:39] [INFO] Using git base URL: git@git.syui.ai:ai
[2025-06-07 03:34:39] [INFO] Found 8 submodules: card bot moji game os gpt shell verse
[2025-06-07 03:34:39] [INFO] URL validation passed: all URLs consistent
[2025-06-07 03:37:58] [INFO] Starting submodule update (all=false, module=, auto=false, dry-run=false)
[2025-06-07 03:37:58] [INFO] Git host: git.syui.ai, protocol: ssh
[2025-06-07 03:37:58] [INFO] Found 8 submodules: card bot moji game os gpt shell verse
[2025-06-07 03:37:58] [INFO] URL validation passed: all URLs consistent
[2025-06-07 03:53:08] [INFO] Starting submodule update (all=true, module=, auto=true, dry-run=false)
[2025-06-07 03:53:08] [INFO] Git host: git.syui.ai, protocol: ssh
[2025-06-07 03:53:08] [INFO] Found 8 submodules: card bot moji game os gpt shell verse
[2025-06-07 03:53:11] [INFO] Updated os on branch main: 21cd1ef16e9c736a4ea342716bc3857fe2864f82 -> 55436e61ee85821fd8a799888205e301d17254ae
[2025-06-07 03:53:13] [INFO] Auto-committed 1 submodule updates
[2025-06-07 03:53:13] [INFO] Submodule update completed: 1/8 updated

50
ai.json
View File

@@ -3,11 +3,16 @@
"metadata": { "metadata": {
"last_updated": "2025-01-06", "last_updated": "2025-01-06",
"structure_version": "2.0", "structure_version": "2.0",
"git": {
"host": "git.syui.ai",
"protocol": "ssh"
},
"documentation": { "documentation": {
"core_docs": { "core_docs": {
"philosophy": "claude/core/philosophy.md", "philosophy": "claude/core/philosophy.md",
"naming": "claude/core/naming.md", "naming": "claude/core/naming.md",
"architecture": "claude/core/architecture.md" "architecture": "claude/core/architecture.md",
"git_architecture": "claude/core/git_architecture.md"
}, },
"project_docs": { "project_docs": {
"os": "claude/projects/os.md", "os": "claude/projects/os.md",
@@ -16,7 +21,12 @@
}, },
"scripts": { "scripts": {
"generate_docs": "claude/scripts/generate_claude.sh", "generate_docs": "claude/scripts/generate_claude.sh",
"sync_docs": "claude/scripts/sync_docs.sh" "sync_docs": "claude/scripts/sync_docs.sh",
"update_submodules": "claude/scripts/update-submodules.sh"
},
"docs": {
"submodule_management": "claude/docs/submodule_management.md",
"development_workflow": "claude/docs/development_workflow.md"
}, },
"templates": "claude/templates/", "templates": "claude/templates/",
"usage": { "usage": {
@@ -31,56 +41,72 @@
"type": "ai", "type": "ai",
"text": "個人特化型心理分析AI", "text": "個人特化型心理分析AI",
"status": "ai.gpt連携実装済み", "status": "ai.gpt連携実装済み",
"detailed_specs": "system_specs/ai_system.json" "detailed_specs": "system_specs/ai_system.json",
"branch": "main"
}, },
"gpt": { "gpt": {
"type": "gpt", "type": "gpt",
"text": "自律送信AI + 統合MCP基盤", "text": "自律送信AI + 統合MCP基盤",
"status": "23ツールMCPサーバー実装済み", "status": "23ツールMCPサーバー実装済み",
"detailed_specs": "system_specs/gpt_system.json" "detailed_specs": "system_specs/gpt_system.json",
"branch": "main"
}, },
"os": { "os": {
"type": "os", "type": "os",
"text": "AI統合OS基盤", "text": "AI統合OS基盤",
"status": "ArchLinux+Docker配布中" "status": "ArchLinux+Docker配布中",
"branch": "main"
}, },
"game": { "game": {
"type": "device", "type": "device",
"text": "携帯+ゲーム機融合デバイス", "text": "携帯+ゲーム機融合デバイス",
"status": "コンセプト段階" "status": "コンセプト段階",
"branch": "main"
}, },
"bot": { "bot": {
"type": "bot", "type": "bot",
"text": "atproto分散SNS連携bot", "text": "atproto分散SNS連携bot",
"status": "Rust実装済み" "status": "Rust実装済み",
"branch": "claude"
}, },
"moji": { "moji": {
"type": [ "font", "icon" ], "type": [ "font", "icon" ],
"text": "文字・フォント生成システム", "text": "文字・フォント生成システム",
"status": "基本実装済み" "status": "基本実装済み",
"branch": "main"
}, },
"card": { "card": {
"type": [ "card", "app", "web" ], "type": [ "card", "app", "web" ],
"text": "atproto基盤ユーザーデータ主権カードゲーム", "text": "atproto基盤ユーザーデータ主権カードゲーム",
"status": "ai.bot統合済み、iOS移植予定", "status": "ai.bot統合済み、iOS移植予定",
"data_reference": "data.card" "data_reference": "data.card",
"branch": "claude"
}, },
"api": { "api": {
"type": "api", "type": "api",
"text": "カード取得APIシステム", "text": "カード取得APIシステム",
"status": "golang ent実装、MCP移行予定" "status": "golang ent実装、MCP移行予定",
"branch": "main"
}, },
"log": { "log": {
"type": "blog", "type": "blog",
"text": "AI機能付き静的ブログジェネレーター", "text": "AI機能付き静的ブログジェネレーター",
"status": "hugo→rust移行、Claude Code開発予定", "status": "hugo→rust移行、Claude Code開発予定",
"features": "記事修正、情報追加、自動翻訳、AI一言コメント、atproto OAuth連携" "features": "記事修正、情報追加、自動翻訳、AI一言コメント、atproto OAuth連携",
"branch": "main"
}, },
"verse": { "verse": {
"type": "metaverse", "type": "metaverse",
"text": "現実とゲーム結合3D世界", "text": "現実とゲーム結合3D世界",
"status": "UE実装予定", "status": "UE実装予定",
"data_reference": "data.card, data.ability, data.system" "data_reference": "data.card, data.ability, data.system",
"branch": "main"
},
"shell": {
"type": "shell",
"text": "Claude Code類似AIシェル",
"status": "実装済み",
"branch": "main"
} }
}, },
"data": { "data": {

View File

@@ -344,7 +344,7 @@ atprotoはこの問題を解決しようとしているようです。
このドキュメントは動的生成されました。修正は元ファイルで行ってください。 このドキュメントは動的生成されました。修正は元ファイルで行ってください。
生成日時: 2025-06-07 03:00:32 生成日時: 2025-06-07 03:53:03
対象プロジェクト: ai 対象プロジェクト: ai
含有コンポーネント: core,specific 含有コンポーネント: core,specific
@@ -460,6 +460,18 @@ curl -sL https://git.syui.ai/ai/ai/raw/branch/main/ai.json | jq .ai.{project}
curl -sL https://git.syui.ai/ai/ai/raw/branch/main/ai.json | jq .ai.os curl -sL https://git.syui.ai/ai/ai/raw/branch/main/ai.json | jq .ai.os
# { "type": "os" } # { "type": "os" }
``` ```
## 日本語の注意点
日本語で文章を書く場合の注意です。
特殊文字列を日本語変換する際に、gitではこのような警告が出る場合があります。
- ` [U+FF1A] は : [U+003A] と混同するおそれがあります`
日本語でdocs, md, textを書く場合は特殊文字列を変換しないでください。できる限り英数文字をそのまま使うようにしてください。
# システム構成 # システム構成
## 全体アーキテクチャ ## 全体アーキテクチャ

View File

@@ -0,0 +1,196 @@
# Git アーキテクチャ設計
## 概要
ai.jsonの階層構造を利用した革新的なGit URL生成システム。
JSONの構造そのものがGitリポジトリの組織構造を表現する。
## 基本原理
### 構造ベースURL生成
```json
{
"metadata": {
"git": {
"host": "git.syui.ai",
"protocol": "ssh"
}
},
"ai": { // ← username (リポジトリ所有者)
"gpt": {}, // ← repo (リポジトリ名)
"bot": {},
"card": {}
}
}
```
### URL生成ロジック
```
JSONパス: ai.gpt
username = "ai" (第1レベルキー)
repo = "gpt" (第2レベルキー)
URL = git@git.syui.ai:ai/gpt
```
## 実装詳細
### 1. メタデータ構造
```json
{
"metadata": {
"git": {
"host": "git.syui.ai", // Gitサーバーホスト
"protocol": "ssh" // ssh | https
}
}
}
```
**host**: Gitサーバーのホスト名
**protocol**: アクセスプロトコル
### 2. プロジェクト階層
```json
{
"ai": {
"gpt": { "branch": "main" },
"bot": { "branch": "claude" },
"card": { "branch": "claude" }
}
}
```
**第1レベル**: username/organization
**第2レベル**: repository name
**branch**: 使用するブランチmainがデフォルト
### 3. URL生成アルゴリズム
```bash
function generate_git_url(username, repo) {
host = metadata.git.host || "git.syui.ai"
protocol = metadata.git.protocol || "ssh"
switch (protocol) {
case "ssh":
return "git@${host}:${username}/${repo}"
case "https":
return "https://${host}/${username}/${repo}"
}
}
```
## メリット
### 1. DRY原則の完全適用
- **Before**: 各プロジェクトでURL重複
- **After**: ホスト情報のみを一箇所で管理
### 2. 構造の意味性
JSONの階層 = Gitの名前空間という自然な対応
### 3. スケーラビリティ
```json
{
"ai": { // ai organization
"gpt": {},
"bot": {}
},
"syui": { // personal projects
"blog": {},
"cli": {}
},
"company": { // work projects
"app1": {},
"app2": {}
}
}
```
### 4. プロトコル柔軟性
```json
// SSH (デフォルト)
{ "protocol": "ssh" } // → git@host:user/repo
// HTTPS
{ "protocol": "https" } // → https://host/user/repo
```
## 使用例
### 基本的な使用
```json
{
"metadata": { "git": { "host": "git.syui.ai" } },
"ai": {
"gpt": { "branch": "main" } // → git@git.syui.ai:ai/gpt
}
}
```
### 複数組織
```json
{
"ai": {
"gpt": {} // → git@git.syui.ai:ai/gpt
},
"work": {
"project": {} // → git@git.syui.ai:work/project
}
}
```
### GitHub移行
```json
{
"metadata": {
"git": {
"host": "github.com",
"protocol": "https"
}
},
"myorg": {
"repo": {} // → https://github.com/myorg/repo
}
}
```
## カスタムURL
特別な要件がある場合は個別にURLを指定可能
```json
{
"ai": {
"special": {
"git_url": "git@special.host:custom/path",
"branch": "develop"
}
}
}
```
## 実装ファイル
- **設定**: `ai.json`
- **スクリプト**: `claude/scripts/update-submodules.sh`
- **関数**: `extract_git_info_from_path()`, `get_base_url_for_module()`
## 関連ドキュメント
- [命名規則](naming.md)
- [サブモジュール管理](../docs/submodule_management.md)
- [開発ワークフロー](../docs/development_workflow.md)

View File

@@ -0,0 +1,259 @@
# 最適化された開発ワークフロー
## 概要
プロジェクト間の齟齬を防止し、Claude Codeセッションの成果を確実に反映する最適化された開発ワークフロー。
## 基本原則
### 1. 一貫性の維持
- 全プロジェクトの状態同期
- 設定とコードの整合性
- ブランチ戦略の統一
### 2. セッション成果の記録
- Claude Codeセッションの完全記録
- 変更内容の構造化保存
- 反映状況の追跡
### 3. 自動化による品質保証
- 手動プロセスの最小化
- 自動検証とエラー検出
- 一貫したコミットメッセージ
## 推奨ワークフロー
### Phase 1: セッション開始前
#### 1. 全体状況確認
```bash
cd /Users/syui/ai/ai
# 一貫性チェック
./claude/scripts/update-submodules.sh --check-consistency
# URL検証
./claude/scripts/update-submodules.sh --validate
# 最新状態に更新
./claude/scripts/update-submodules.sh --all --dry-run
```
#### 2. 作業プロジェクト選択
```bash
# プロジェクトディレクトリに移動
cd gpt # 例: gpt プロジェクト
# ブランチ確認・切り替え
git status
git checkout claude # または適切なブランチ
```
### Phase 2: Claude Codeセッション
#### セッション中の注意点
- **専用ブランチ使用**: mainではなくclaudeブランチで作業
- **定期的なコミット**: 大きな変更は小分けにコミット
- **明確なコミットメッセージ**: 何を変更したかを明記
#### 推奨コミット戦略
```bash
# 機能追加の場合
git commit -m "Add: 新機能名 - 簡潔な説明"
# バグ修正の場合
git commit -m "Fix: 修正内容 - 問題の説明"
# 改善の場合
git commit -m "Improve: 改善内容 - before/afterの説明"
```
### Phase 3: セッション終了時(重要)
#### 自動セッション終了プロセス
```bash
# プロジェクトディレクトリで実行
./claude/scripts/session-end.sh --auto-sync
# または手動でサマリー指定
./claude/scripts/session-end.sh --summary="新しいMCP機能を実装。23ツールから25ツールに拡張。" --auto-sync
```
#### session-end.shの機能
1. **変更検出**: 未コミット変更の自動検出
2. **サマリー入力**: セッション成果の記録
3. **自動コミット**: 構造化されたコミットメッセージ
4. **親リポジトリ同期**: サブモジュール更新の自動反映
5. **セッション記録**: `.claude/sessions/`にMDファイル保存
6. **検証**: 一貫性チェックの自動実行
### Phase 4: 事後確認
#### 1. 結果確認
```bash
cd /Users/syui/ai/ai
# 更新が正しく反映されているか確認
git log --oneline -5
# 一貫性の最終確認
./claude/scripts/update-submodules.sh --check-consistency
```
#### 2. セッション記録確認
```bash
# 最新のセッション記録を確認
ls -la .claude/sessions/
cat .claude/sessions/gpt_2025-06-07_15-30-45.md
```
## 特殊ケースの対応
### 複数プロジェクト同時開発
#### 方法1: 順次処理(推奨)
```bash
# プロジェクト1完了
cd gpt
./claude/scripts/session-end.sh --auto-sync
# プロジェクト2開始
cd ../bot
# Claude Codeセッション...
./claude/scripts/session-end.sh --auto-sync
```
#### 方法2: 並行処理
```bash
# 各プロジェクトで作業(--auto-syncは使わない
cd gpt
./claude/scripts/session-end.sh --summary="GPT機能拡張"
cd ../bot
./claude/scripts/session-end.sh --summary="Bot統合改善"
# 最後に一括同期
cd ../
./claude/scripts/update-submodules.sh --all --auto
```
## 自動化ツール
### 利用可能なスクリプト
#### 1. session-end.sh
```bash
# 基本使用
./claude/scripts/session-end.sh --auto-sync
# サマリー指定
./claude/scripts/session-end.sh --summary="作業内容" --auto-sync
# プロジェクト指定
./claude/scripts/session-end.sh --project=gpt --auto-sync
```
#### 2. update-submodules.sh
```bash
# 一貫性チェック
./claude/scripts/update-submodules.sh --check-consistency
# 全体更新
./claude/scripts/update-submodules.sh --all --auto
# URL検証
./claude/scripts/update-submodules.sh --validate
```
### 推奨エイリアス設定
```bash
# ~/.zshrc
alias daily-check="cd /Users/syui/ai/ai && ./claude/scripts/update-submodules.sh --check-consistency"
alias sync-all="cd /Users/syui/ai/ai && ./claude/scripts/update-submodules.sh --all --auto"
alias session-end="../claude/scripts/session-end.sh --auto-sync"
```
## エラー対応
### よくある問題と解決策
#### 1. 未コミット変更の衝突
```
⚠️ gpt: Has uncommitted changes
```
**解決策:**
```bash
cd gpt
./claude/scripts/session-end.sh --summary="作業内容の説明" --auto-sync
```
#### 2. ブランチ不一致
```
⚠️ bot: Branch mismatch
Current: main
Expected: claude
```
**解決策:**
```bash
cd bot
git checkout claude
git merge main # 必要に応じて
```
#### 3. サブモジュールポインタ不一致
```
⚠️ card: Submodule pointer mismatch
```
**解決策:**
```bash
./claude/scripts/update-submodules.sh --module=card --auto
```
## セッション記録システム
### 自動生成される記録
- **場所**: `.claude/sessions/`
- **形式**: `{project}_{timestamp}.md`
- **内容**: セッション概要、変更詳細、コミット情報
### 記録例
```markdown
# Claude Code Session Report
**Project**: gpt
**Date**: 2025-06-07 15:30:45
**Summary**: MCP機能拡張。新しいツール追加とエラーハンドリング改善。
## Changes Made
src/mcp_client.rs | 45 +++++++++++++++++++++++++++++
src/commands.rs | 23 +++++++++++++--
2 files changed, 68 insertions(+), 2 deletions(-)
## Session End Status
- ✅ Changes committed
- ✅ Session logged
- ✅ Auto-sync completed
```
## ベストプラクティス
### 1. セッション設計
- **明確な目標**: 何を達成するかを最初に決める
- **適切な粒度**: 1セッション = 1つの機能や修正
- **定期的な保存**: 大きな変更は途中でコミット
### 2. 終了時のルーティン
```bash
# 必須: セッション終了スクリプト実行
./claude/scripts/session-end.sh --auto-sync
# 推奨: 最終確認
cd /Users/syui/ai/ai
./claude/scripts/update-submodules.sh --check-consistency
```
### 3. 定期メンテナンス
- **日次**: 作業開始前にconsistency check
- **週次**: 全体的な検証とクリーンアップ
このワークフローに従うことで、プロジェクト間の齟齬を防ぎ、Claude Codeセッションの成果を確実に蓄積できます。

View File

@@ -0,0 +1,223 @@
# サブモジュール管理システム
## 概要
ai.jsonの構造ベース設定を活用した高度なサブモジュール管理システム。
Git URLの自動生成、整合性チェック、一括管理機能を提供。
## スクリプト: update-submodules.sh
### 基本使用法
```bash
# 全サブモジュール更新
./claude/scripts/update-submodules.sh --all
# 特定サブモジュール更新
./claude/scripts/update-submodules.sh --module=gpt
# 自動コミット付き更新
./claude/scripts/update-submodules.sh --all --auto
```
## 主要機能
### 1. 更新機能
#### 全サブモジュール更新
```bash
./claude/scripts/update-submodules.sh --all [--auto] [--dry-run]
```
- ai.jsonで定義されたブランチで各サブモジュールを更新
- 構造ベースURL生成を使用
- オプションで自動コミット
#### 個別サブモジュール更新
```bash
./claude/scripts/update-submodules.sh --module=<name> [--auto]
```
- 指定されたサブモジュールのみ更新
- ai.jsonの設定を自動適用
### 2. 検証機能
#### URL整合性チェック
```bash
./claude/scripts/update-submodules.sh --validate
```
- .gitmodulesとai.jsonのURL一致確認
- 不整合があれば詳細レポート
- 構造ベース生成URLとの比較
**出力例:**
```
🔍 Validating URL consistency between ai.json and .gitmodules...
✅ gpt: URLs match
✅ bot: URLs match
❌ card: URL mismatch
.gitmodules: git@old.host:ai/card
ai.json: git@git.syui.ai:ai/card
```
### 3. 同期機能
#### .gitmodules同期
```bash
./claude/scripts/update-submodules.sh --sync [--auto]
```
- ai.jsonの設定を.gitmodulesに反映
- URL不整合の自動修正
- オプションで変更を自動コミット
### 4. サブモジュール管理
#### 新規追加
```bash
./claude/scripts/update-submodules.sh --add=<name> [--auto]
```
- ai.jsonの設定に基づき新しいサブモジュールを追加
- 構造ベースURLとブランチを自動適用
**前提条件:**
- ai.jsonに対象プロジェクトが定義済み
- リモートリポジトリが存在
#### 削除
```bash
./claude/scripts/update-submodules.sh --remove=<name> [--auto]
```
- サブモジュールを完全削除
- .gitmodules、.git/config、ディレクトリを清理
## オプション
### 共通オプション
| オプション | 説明 |
|-----------|------|
| `--auto` | 変更を自動コミット |
| `--dry-run` | 実行内容をプレビュー(変更なし) |
| `--help` | ヘルプ表示 |
### 操作オプション(排他)
| オプション | 説明 |
|-----------|------|
| `--all` | 全サブモジュール更新 |
| `--module=<name>` | 特定サブモジュール更新 |
| `--validate` | URL整合性チェック |
| `--sync` | .gitmodules同期 |
| `--add=<name>` | サブモジュール追加 |
| `--remove=<name>` | サブモジュール削除 |
## ai.json設定例
### 基本設定
```json
{
"metadata": {
"git": {
"host": "git.syui.ai",
"protocol": "ssh"
}
},
"ai": {
"gpt": {
"branch": "main",
"type": "gpt"
},
"bot": {
"branch": "claude",
"type": "bot"
}
}
}
```
### カスタムURL
```json
{
"ai": {
"special": {
"git_url": "git@special.host:custom/repo",
"branch": "develop"
}
}
}
```
## 実行フロー
### 1. 設定読み込み
- ai.jsonからgit設定とプロジェクト構造を読み込み
- .gitmodulesから既存サブモジュール情報を取得
### 2. URL生成
- 構造ベースロジックでGit URLを生成
- カスタムURLがあれば優先使用
### 3. 操作実行
- 指定された操作を実行
- ログ出力とエラーハンドリング
### 4. 結果報告
- 成功/失敗数の集計
- 詳細ログの出力
## トラブルシューティング
### よくある問題
#### 1. ブランチ不一致
```
❌ Failed to checkout branch claude
```
**解決方法:**
- リモートブランチの存在確認
- ai.jsonのブランチ設定確認
#### 2. URL不整合
```
❌ card: URL mismatch
```
**解決方法:**
```bash
./claude/scripts/update-submodules.sh --sync --auto
```
#### 3. 権限エラー
```
Permission denied (publickey)
```
**解決方法:**
- SSH鍵の設定確認
- リポジトリアクセス権限確認
## ログ
### ログファイル
```
.submodule-update.log
```
### ログレベル
- **INFO**: 正常操作
- **ERROR**: エラー状況
- **DEBUG**: 詳細情報(構造解析等)
## 関連ドキュメント
- [Git アーキテクチャ](../core/git_architecture.md)
- [命名規則](../core/naming.md)
- [開発ワークフロー](development_workflow.md)

227
claude/scripts/session-end.sh Executable file
View File

@@ -0,0 +1,227 @@
#!/bin/zsh
# Claude Code Session End Script
# セッション終了時の標準プロセス
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Configuration
SCRIPT_DIR="${0:a:h}"
REPO_ROOT="${SCRIPT_DIR:h:h}"
SESSION_LOG_DIR="$REPO_ROOT/.claude/sessions"
TIMESTAMP=$(date '+%Y-%m-%d_%H-%M-%S')
# Create session log directory if it doesn't exist
mkdir -p "$SESSION_LOG_DIR"
# Usage function
usage() {
echo "Usage: $0 [--project=<name>] [--summary=<text>] [--auto-sync] [--help]"
echo ""
echo "Claude Code Session End Manager"
echo ""
echo "Options:"
echo " --project=<name> Project name (auto-detected if not specified)"
echo " --summary=<text> Session summary (interactive prompt if not specified)"
echo " --auto-sync Automatically sync with parent repository"
echo " --help Show this help message"
echo ""
echo "This script should be run at the end of each Claude Code session to:"
echo " 1. Record session achievements"
echo " 2. Commit changes with proper messages"
echo " 3. Sync with parent repository"
echo " 4. Validate project consistency"
exit 1
}
# Logging function
log() {
local level="$1"
shift
local message="$*"
local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
echo "[$timestamp] [$level] $message" | tee -a "$SESSION_LOG_DIR/session-end.log"
}
# Parse arguments
PROJECT_NAME=""
SESSION_SUMMARY=""
AUTO_SYNC=false
for arg in "$@"; do
case $arg in
--project=*)
PROJECT_NAME="${arg#*=}"
;;
--summary=*)
SESSION_SUMMARY="${arg#*=}"
;;
--auto-sync)
AUTO_SYNC=true
;;
--help|-h)
usage
;;
*)
echo "Unknown argument: $arg"
usage
;;
esac
done
# Auto-detect project if not specified
if [[ -z "$PROJECT_NAME" ]]; then
# Check if we're in a submodule directory
if [[ -f ".git" && $(head -1 .git 2>/dev/null) =~ "gitdir:" ]]; then
PROJECT_NAME=$(basename "$PWD")
echo -e "${BLUE}📍 Auto-detected project: $PROJECT_NAME${NC}"
else
echo -e "${YELLOW}⚠️ Could not auto-detect project. Please specify --project=<name>${NC}"
echo "Available projects:"
cd "$REPO_ROOT"
for dir in */; do
if [[ -d "$dir/.git" || -f "$dir/.git" ]]; then
echo " - ${dir%/}"
fi
done
exit 1
fi
fi
# Validate project exists
if [[ ! -d "$REPO_ROOT/$PROJECT_NAME" ]]; then
echo -e "${RED}❌ Project '$PROJECT_NAME' not found${NC}"
exit 1
fi
cd "$REPO_ROOT/$PROJECT_NAME"
echo -e "${BLUE}🚀 Starting session end process for: $PROJECT_NAME${NC}"
log "INFO" "Starting session end process for project: $PROJECT_NAME"
# Check for uncommitted changes
if ! git diff --quiet || ! git diff --cached --quiet; then
echo -e "${YELLOW}📝 Uncommitted changes detected${NC}"
# Show status
echo -e "${BLUE}Current git status:${NC}"
git status --short
# Get session summary if not provided
if [[ -z "$SESSION_SUMMARY" ]]; then
echo ""
echo -e "${BLUE}📋 Please provide a session summary:${NC}"
echo "(Describe what was accomplished in this Claude Code session)"
read "SESSION_SUMMARY?> "
if [[ -z "$SESSION_SUMMARY" ]]; then
echo -e "${RED}❌ Session summary is required${NC}"
exit 1
fi
fi
# Stage all changes
git add .
# Create commit with session summary
COMMIT_MESSAGE="Claude Code Session: $SESSION_SUMMARY
📅 Session Date: $(date '+%Y-%m-%d %H:%M:%S')
🎯 Project: $PROJECT_NAME
📋 Summary: $SESSION_SUMMARY
🤖 Generated with Claude Code Session Manager
Co-Authored-By: Claude <noreply@anthropic.com>"
# Commit changes
if git commit -m "$COMMIT_MESSAGE"; then
echo -e "${GREEN}✅ Changes committed successfully${NC}"
log "INFO" "Session changes committed for $PROJECT_NAME"
# Save session record
SESSION_RECORD="$SESSION_LOG_DIR/${PROJECT_NAME}_${TIMESTAMP}.md"
cat > "$SESSION_RECORD" << EOF
# Claude Code Session Report
**Project**: $PROJECT_NAME
**Date**: $(date '+%Y-%m-%d %H:%M:%S')
**Summary**: $SESSION_SUMMARY
## Changes Made
\`\`\`
$(git show --stat HEAD)
\`\`\`
## Commit Details
\`\`\`
$(git show --oneline -s HEAD)
\`\`\`
## Session End Status
- ✅ Changes committed
- ✅ Session logged
$(if [[ "$AUTO_SYNC" == true ]]; then echo "- ✅ Auto-sync enabled"; else echo "- ⏸️ Manual sync required"; fi)
EOF
echo -e "${GREEN}📋 Session record saved: $SESSION_RECORD${NC}"
else
echo -e "${RED}❌ Failed to commit changes${NC}"
exit 1
fi
else
echo -e "${GREEN}✅ No uncommitted changes${NC}"
log "INFO" "No changes to commit in $PROJECT_NAME"
fi
# Sync with parent repository if requested
if [[ "$AUTO_SYNC" == true ]]; then
echo -e "${BLUE}🔄 Syncing with parent repository...${NC}"
cd "$REPO_ROOT"
# Update parent repository to reflect submodule changes
if "$REPO_ROOT/claude/scripts/update-submodules.sh" --module="$PROJECT_NAME" --auto; then
echo -e "${GREEN}✅ Parent repository synced successfully${NC}"
log "INFO" "Parent repository synced for $PROJECT_NAME"
else
echo -e "${YELLOW}⚠️ Parent repository sync failed. Manual sync may be required.${NC}"
log "WARNING" "Parent repository sync failed for $PROJECT_NAME"
fi
else
echo -e "${YELLOW}⏸️ Manual sync required. Run this command when ready:${NC}"
echo " cd $REPO_ROOT && ./claude/scripts/update-submodules.sh --module=$PROJECT_NAME --auto"
fi
# Validation check
echo -e "${BLUE}🔍 Running validation checks...${NC}"
cd "$REPO_ROOT"
if "$REPO_ROOT/claude/scripts/update-submodules.sh" --validate > /dev/null 2>&1; then
echo -e "${GREEN}✅ Project consistency validated${NC}"
log "INFO" "Validation passed for $PROJECT_NAME session end"
else
echo -e "${YELLOW}⚠️ Validation warnings detected. Run full validation:${NC}"
echo " ./claude/scripts/update-submodules.sh --validate"
fi
# Session summary
echo ""
echo -e "${GREEN}🎉 Session end process completed!${NC}"
echo ""
echo -e "${BLUE}📊 Summary:${NC}"
echo " 📦 Project: $PROJECT_NAME"
if [[ -n "$SESSION_SUMMARY" ]]; then
echo " 📋 Summary: $SESSION_SUMMARY"
fi
echo " 📅 Timestamp: $TIMESTAMP"
echo " 🔄 Sync: $(if [[ "$AUTO_SYNC" == true ]]; then echo "Completed"; else echo "Manual required"; fi)"
echo ""
echo -e "${BLUE}📁 Session records: $SESSION_LOG_DIR${NC}"
log "INFO" "Session end process completed successfully for $PROJECT_NAME"

View File

@@ -21,20 +21,26 @@ NC='\033[0m' # No Color
SCRIPT_DIR="${0:a:h}" SCRIPT_DIR="${0:a:h}"
REPO_ROOT="${SCRIPT_DIR:h:h}" REPO_ROOT="${SCRIPT_DIR:h:h}"
LOGFILE="$REPO_ROOT/.submodule-update.log" LOGFILE="$REPO_ROOT/.submodule-update.log"
AI_JSON="$REPO_ROOT/ai.json"
# Usage function # Usage function
usage() { usage() {
echo "Usage: $0 [--all] [--module=<name>] [--auto] [--dry-run] [--help]" echo "Usage: $0 [--all] [--module=<name>] [--auto] [--dry-run] [--validate] [--sync] [--add=<name>] [--remove=<name>] [--help]"
echo "" echo ""
echo "Options:" echo "Options:"
echo " --all Update all submodules" echo " --all Update all submodules"
echo " --module=<name> Update specific submodule (os, gpt, card, etc.)" echo " --module=<name> Update specific submodule (os, gpt, card, etc.)"
echo " --auto Auto-commit if changes detected" echo " --auto Auto-commit if changes detected"
echo " --dry-run Show what would be done without making changes" echo " --dry-run Show what would be done without making changes"
echo " --validate Validate URL consistency between ai.json and .gitmodules"
echo " --sync Sync .gitmodules from ai.json configuration"
echo " --add=<name> Add new submodule from ai.json configuration"
echo " --remove=<name> Remove submodule (both from .gitmodules and filesystem)"
echo " --help Show this help message" echo " --help Show this help message"
echo " --check-consistency Check for project inconsistencies and conflicts"
echo "" echo ""
echo "Available submodules:" echo "Available submodules:"
git submodule status | awk '{print " " $2}' git config --file .gitmodules --get-regexp path | awk '{print " " $2}'
exit 1 exit 1
} }
@@ -52,6 +58,11 @@ UPDATE_ALL=false
SPECIFIC_MODULE="" SPECIFIC_MODULE=""
AUTO_COMMIT=false AUTO_COMMIT=false
DRY_RUN=false DRY_RUN=false
VALIDATE_ONLY=false
SYNC_GITMODULES=false
ADD_MODULE=""
REMOVE_MODULE=""
CHECK_CONSISTENCY=false
for arg in "$@"; do for arg in "$@"; do
case $arg in case $arg in
@@ -67,6 +78,21 @@ for arg in "$@"; do
--dry-run) --dry-run)
DRY_RUN=true DRY_RUN=true
;; ;;
--validate)
VALIDATE_ONLY=true
;;
--sync)
SYNC_GITMODULES=true
;;
--add=*)
ADD_MODULE="${arg#*=}"
;;
--remove=*)
REMOVE_MODULE="${arg#*=}"
;;
--check-consistency)
CHECK_CONSISTENCY=true
;;
--help|-h) --help|-h)
usage usage
;; ;;
@@ -78,13 +104,22 @@ for arg in "$@"; do
done done
# Validate arguments # Validate arguments
if [[ "$UPDATE_ALL" == false && -z "$SPECIFIC_MODULE" ]]; then operations_count=0
echo "Error: Either --all or --module=<name> is required" [[ "$UPDATE_ALL" == true ]] && ((operations_count++))
[[ -n "$SPECIFIC_MODULE" ]] && ((operations_count++))
[[ "$VALIDATE_ONLY" == true ]] && ((operations_count++))
[[ "$SYNC_GITMODULES" == true ]] && ((operations_count++))
[[ -n "$ADD_MODULE" ]] && ((operations_count++))
[[ -n "$REMOVE_MODULE" ]] && ((operations_count++))
[[ "$CHECK_CONSISTENCY" == true ]] && ((operations_count++))
if [[ $operations_count -eq 0 ]]; then
echo "Error: At least one operation is required"
usage usage
fi fi
if [[ "$UPDATE_ALL" == true && -n "$SPECIFIC_MODULE" ]]; then if [[ $operations_count -gt 1 ]]; then
echo "Error: Cannot use both --all and --module" echo "Error: Only one operation can be specified at a time"
usage usage
fi fi
@@ -117,21 +152,20 @@ update_submodule() {
# Get current branch of the submodule # Get current branch of the submodule
cd "$module_path" || return 1 cd "$module_path" || return 1
local current_branch=$(git branch --show-current) local current_branch=$(git branch --show-current)
local target_branch="${branches[$module_name]:-main}"
if [[ -z "$current_branch" ]]; then if [[ -z "$current_branch" ]]; then
# If not on a branch (detached HEAD), try to determine the default branch # If not on a branch (detached HEAD), use target branch from ai.json
current_branch="main" current_branch="$target_branch"
if ! git rev-parse origin/main >/dev/null 2>&1; then
current_branch="master"
fi
fi fi
cd "$REPO_ROOT" cd "$REPO_ROOT"
if [[ "$DRY_RUN" == true ]]; then if [[ "$DRY_RUN" == true ]]; then
echo -e "${YELLOW}🔍 [DRY RUN] Would update $module_name (branch: $current_branch)${NC}" echo -e "${YELLOW}🔍 [DRY RUN] Would update $module_name (target branch: $target_branch)${NC}"
echo " Current: $current_commit" echo " Current: $current_commit"
cd "$module_path" || return 1 cd "$module_path" || return 1
git fetch origin >/dev/null 2>&1 git fetch origin >/dev/null 2>&1
local latest_commit=$(git rev-parse "origin/$current_branch" 2>/dev/null) local latest_commit=$(git rev-parse "origin/$target_branch" 2>/dev/null)
echo " Latest: $latest_commit" echo " Latest: $latest_commit"
cd "$REPO_ROOT" cd "$REPO_ROOT"
@@ -154,8 +188,8 @@ update_submodule() {
return 1 return 1
fi fi
# Use the current branch we detected earlier # Use the target branch from ai.json
local latest_commit=$(git rev-parse "origin/$current_branch" 2>/dev/null) local latest_commit=$(git rev-parse "origin/$target_branch" 2>/dev/null)
if [[ "$current_commit" == "$latest_commit" ]]; then if [[ "$current_commit" == "$latest_commit" ]]; then
echo -e "${GREEN}✅ Already up to date${NC}" echo -e "${GREEN}✅ Already up to date${NC}"
@@ -163,17 +197,17 @@ update_submodule() {
return 1 return 1
fi fi
echo "📝 Updating to latest commit on branch $current_branch..." echo "📝 Updating to latest commit on branch $target_branch (configured in ai.json)..."
# First ensure we're on the correct branch # First ensure we're on the correct branch
if ! git checkout "$current_branch"; then if ! git checkout "$target_branch"; then
echo -e "${RED}❌ Failed to checkout branch $current_branch${NC}" echo -e "${RED}❌ Failed to checkout branch $target_branch${NC}"
cd "$REPO_ROOT" cd "$REPO_ROOT"
return 1 return 1
fi fi
# Then pull the latest changes # Then pull the latest changes
if ! git pull origin "$current_branch"; then if ! git pull origin "$target_branch"; then
echo -e "${RED}❌ Failed to pull latest changes from $current_branch${NC}" echo -e "${RED}❌ Failed to pull latest changes from $target_branch${NC}"
cd "$REPO_ROOT" cd "$REPO_ROOT"
return 1 return 1
fi fi
@@ -186,24 +220,498 @@ update_submodule() {
# Stage the submodule update # Stage the submodule update
git add "$module_path" git add "$module_path"
echo -e "${GREEN}✅ Updated $module_name (branch: $current_branch)${NC}" echo -e "${GREEN}✅ Updated $module_name (branch: $target_branch)${NC}"
echo " From: $current_commit" echo " From: $current_commit"
echo " To: $new_commit" echo " To: $new_commit"
log "INFO" "Updated $module_name on branch $current_branch: $current_commit -> $new_commit" log "INFO" "Updated $module_name on branch $target_branch: $current_commit -> $new_commit"
return 0 return 0
} }
# Get list of submodules # Get list of submodules
declare -A submodules declare -A submodules
while IFS= read -r line; do while IFS= read -r line; do
if [[ $line =~ ^\[submodule\ \"([^\"]+)\"\] ]]; then if [[ $line =~ '^\[submodule "([^"]+)"\]' ]]; then
current_name="${match[1]}" current_name="${match[1]}"
elif [[ $line =~ ^[[:space:]]*path[[:space:]]*=[[:space:]]*(.+)$ ]]; then elif [[ $line =~ '^[[:space:]]*path[[:space:]]*=[[:space:]]*(.+)$' ]]; then
submodules[$current_name]="${match[1]}" submodules[$current_name]="${match[1]}"
fi fi
done < .gitmodules done < .gitmodules
# Get branch information from ai.json
declare -A branches
get_branch_for_module() {
local module="$1"
local branch="main" # default branch
if [[ -f "$AI_JSON" ]]; then
# Try to extract branch from ai.json using jq
if command -v jq >/dev/null 2>&1; then
local json_branch=$(jq -r ".ai.${module}.branch // \"main\"" "$AI_JSON" 2>/dev/null)
if [[ -n "$json_branch" && "$json_branch" != "null" ]]; then
branch="$json_branch"
fi
fi
fi
echo "$branch"
}
# Get URL and branch information from ai.json
declare -A urls
get_git_config() {
local config_key="$1"
local default_value="$2"
local value=""
if [[ -f "$AI_JSON" ]]; then
if command -v jq >/dev/null 2>&1; then
value=$(jq -r ".metadata.git.${config_key} // \"${default_value}\"" "$AI_JSON" 2>/dev/null)
fi
fi
# Fallback to default if not found
if [[ -z "$value" || "$value" == "null" ]]; then
value="$default_value"
fi
echo "$value"
}
# Extract username and repo from JSON path
# For ai.gpt -> username=ai, repo=gpt
extract_git_info_from_path() {
local module="$1"
local username=""
local repo=""
# Check if module exists in ai.json structure
if [[ -f "$AI_JSON" ]]; then
if command -v jq >/dev/null 2>&1; then
# Get all keys in the ai object
local ai_keys=$(jq -r '.ai | keys[]' "$AI_JSON" 2>/dev/null)
# Find the first level (username) that contains our module
while IFS= read -r key; do
if jq -e ".ai.${key}.${module}" "$AI_JSON" >/dev/null 2>&1; then
username="$key"
repo="$module"
break
fi
# Also check if the key itself is our module (direct under ai)
if [[ "$key" == "$module" ]]; then
username="ai" # Default namespace
repo="$module"
break
fi
done <<< "$ai_keys"
fi
fi
# Fallback: assume ai namespace
if [[ -z "$username" || -z "$repo" ]]; then
username="ai"
repo="$module"
fi
echo "${username}:${repo}"
}
get_base_url_for_module() {
local module="$1"
local host=$(get_git_config "host" "git.syui.ai")
local protocol=$(get_git_config "protocol" "ssh")
# Extract username and repo from JSON structure
local git_info=$(extract_git_info_from_path "$module")
local username="${git_info%%:*}"
local repo="${git_info##*:}"
local url=""
case "$protocol" in
"ssh")
url="git@${host}:${username}/${repo}"
;;
"https")
url="https://${host}/${username}/${repo}"
;;
*)
# Default to ssh
url="git@${host}:${username}/${repo}"
;;
esac
echo "$url"
}
get_url_for_module() {
local module="$1"
local url=$(get_base_url_for_module "$module")
# Check if there's a custom git_url override in ai.json
if [[ -f "$AI_JSON" ]]; then
if command -v jq >/dev/null 2>&1; then
local custom_url=$(jq -r ".ai.${module}.git_url // empty" "$AI_JSON" 2>/dev/null)
if [[ -n "$custom_url" && "$custom_url" != "null" ]]; then
url="$custom_url"
fi
fi
fi
echo "$url"
}
# Populate branches and URLs for all modules
for module in "${(k)submodules[@]}"; do
branches[$module]=$(get_branch_for_module "$module")
urls[$module]=$(get_url_for_module "$module")
done
# Log git configuration for debugging
log "INFO" "Git host: $(get_git_config 'host' 'git.syui.ai'), protocol: $(get_git_config 'protocol' 'ssh')"
# Debug: Log found submodules
log "INFO" "Found ${#submodules} submodules: ${(k)submodules[@]}"
# Validation function
validate_url_consistency() {
echo -e "${BLUE}🔍 Validating URL consistency between ai.json and .gitmodules...${NC}"
local inconsistencies=0
for module in "${(k)submodules[@]}"; do
local gitmodules_url=$(git config --file .gitmodules --get "submodule.${module}.url")
local ai_json_url="${urls[$module]}"
if [[ -n "$ai_json_url" ]]; then
if [[ "$gitmodules_url" != "$ai_json_url" ]]; then
echo -e "${RED}$module: URL mismatch${NC}"
echo " .gitmodules: $gitmodules_url"
echo " ai.json: $ai_json_url"
((inconsistencies++))
else
echo -e "${GREEN}$module: URLs match${NC}"
fi
else
echo -e "${YELLOW}⚠️ $module: No git_url in ai.json${NC}"
fi
done
echo ""
if [[ $inconsistencies -eq 0 ]]; then
echo -e "${GREEN}🎉 All URLs are consistent!${NC}"
log "INFO" "URL validation passed: all URLs consistent"
else
echo -e "${RED}❌ Found $inconsistencies URL inconsistencies${NC}"
echo "Run with --sync to fix inconsistencies"
log "ERROR" "URL validation failed: $inconsistencies inconsistencies"
return 1
fi
}
# Sync .gitmodules from ai.json
sync_gitmodules() {
echo -e "${BLUE}🔄 Syncing .gitmodules from ai.json...${NC}"
local changes=0
for module in "${(k)submodules[@]}"; do
local ai_json_url="${urls[$module]}"
local ai_json_branch="${branches[$module]}"
if [[ -n "$ai_json_url" ]]; then
local current_url=$(git config --file .gitmodules --get "submodule.${module}.url")
if [[ "$current_url" != "$ai_json_url" ]]; then
echo "📝 Updating $module URL: $current_url -> $ai_json_url"
git config --file .gitmodules "submodule.${module}.url" "$ai_json_url"
((changes++))
fi
fi
done
if [[ $changes -gt 0 ]]; then
echo -e "${GREEN}✅ Updated $changes URL(s) in .gitmodules${NC}"
log "INFO" "Synced .gitmodules: updated $changes URLs"
if [[ "$AUTO_COMMIT" == true ]]; then
git add .gitmodules
git commit -m "Sync .gitmodules URLs from ai.json
🔄 Updated $changes submodule URL(s)
🤖 Generated with submodule sync"
echo -e "${GREEN}✅ Changes committed to .gitmodules${NC}"
fi
else
echo -e "${GREEN}✅ .gitmodules is already in sync${NC}"
fi
}
# Add new submodule
add_submodule() {
local module="$1"
echo -e "${BLUE} Adding submodule: $module${NC}"
local ai_json_url=$(get_url_for_module "$module")
local ai_json_branch=$(get_branch_for_module "$module")
if [[ -z "$ai_json_url" ]]; then
echo -e "${RED}❌ No git_url found for '$module' in ai.json${NC}"
return 1
fi
if [[ -d "$module" ]]; then
echo -e "${RED}❌ Directory '$module' already exists${NC}"
return 1
fi
echo "📦 Adding submodule $module"
echo " URL: $ai_json_url"
echo " Branch: $ai_json_branch"
if [[ "$DRY_RUN" == true ]]; then
echo -e "${YELLOW}🔍 [DRY RUN] Would add submodule${NC}"
return 0
fi
if git submodule add -b "$ai_json_branch" "$ai_json_url" "$module"; then
echo -e "${GREEN}✅ Successfully added submodule $module${NC}"
log "INFO" "Added submodule $module from $ai_json_url (branch: $ai_json_branch)"
if [[ "$AUTO_COMMIT" == true ]]; then
git commit -m "Add submodule: $module
📦 Added from ai.json configuration
🌐 URL: $ai_json_url
🌿 Branch: $ai_json_branch
🤖 Generated with submodule manager"
echo -e "${GREEN}✅ Submodule addition committed${NC}"
fi
else
echo -e "${RED}❌ Failed to add submodule $module${NC}"
return 1
fi
}
# Remove submodule
remove_submodule() {
local module="$1"
echo -e "${BLUE} Removing submodule: $module${NC}"
if [[ ! -d "$module" ]]; then
echo -e "${RED}❌ Submodule '$module' does not exist${NC}"
return 1
fi
if [[ "$DRY_RUN" == true ]]; then
echo -e "${YELLOW}🔍 [DRY RUN] Would remove submodule${NC}"
return 0
fi
# Remove from .gitmodules
git config --file .gitmodules --remove-section "submodule.$module" 2>/dev/null || true
# Remove from .git/config
git config --remove-section "submodule.$module" 2>/dev/null || true
# Remove from git index
git rm --cached "$module" 2>/dev/null || true
# Remove directory
rm -rf "$module"
# Remove from .git/modules
rm -rf ".git/modules/$module"
echo -e "${GREEN}✅ Successfully removed submodule $module${NC}"
log "INFO" "Removed submodule $module"
if [[ "$AUTO_COMMIT" == true ]]; then
git add .gitmodules "$module" 2>/dev/null || true
git commit -m "Remove submodule: $module
🗑️ Completely removed submodule
🤖 Generated with submodule manager"
echo -e "${GREEN}✅ Submodule removal committed${NC}"
fi
}
# Consistency check function
check_project_consistency() {
echo -e "${BLUE}🔍 Checking project consistency...${NC}"
local issues=0
local warnings=0
# Check for uncommitted changes in submodules
echo -e "${BLUE}📝 Checking for uncommitted changes...${NC}"
for module in "${(k)submodules[@]}"; do
local module_path="${submodules[$module]}"
if [[ -d "$module_path" ]]; then
cd "$module_path"
if ! git diff --quiet || ! git diff --cached --quiet; then
echo -e "${YELLOW}⚠️ $module: Has uncommitted changes${NC}"
git status --short | sed 's/^/ /'
((warnings++))
else
echo -e "${GREEN}$module: Clean working directory${NC}"
fi
cd "$REPO_ROOT"
fi
done
# Check for branch inconsistencies
echo -e "${BLUE}🌿 Checking branch consistency...${NC}"
for module in "${(k)submodules[@]}"; do
local module_path="${submodules[$module]}"
local expected_branch="${branches[$module]}"
if [[ -d "$module_path" ]]; then
cd "$module_path"
local current_branch=$(git branch --show-current)
if [[ -z "$current_branch" ]]; then
current_branch="(detached HEAD)"
fi
if [[ "$current_branch" != "$expected_branch" ]]; then
echo -e "${YELLOW}⚠️ $module: Branch mismatch${NC}"
echo " Current: $current_branch"
echo " Expected: $expected_branch"
((warnings++))
else
echo -e "${GREEN}$module: Correct branch ($current_branch)${NC}"
fi
cd "$REPO_ROOT"
fi
done
# Check for remote synchronization
echo -e "${BLUE}🌐 Checking remote synchronization...${NC}"
for module in "${(k)submodules[@]}"; do
local module_path="${submodules[$module]}"
if [[ -d "$module_path" ]]; then
cd "$module_path"
git fetch --quiet 2>/dev/null || true
local ahead=$(git rev-list --count HEAD ^origin/HEAD 2>/dev/null || echo "0")
local behind=$(git rev-list --count origin/HEAD ^HEAD 2>/dev/null || echo "0")
if [[ "$ahead" -gt 0 || "$behind" -gt 0 ]]; then
echo -e "${YELLOW}⚠️ $module: Out of sync with remote${NC}"
if [[ "$ahead" -gt 0 ]]; then
echo " $ahead commits ahead"
fi
if [[ "$behind" -gt 0 ]]; then
echo " $behind commits behind"
fi
((warnings++))
else
echo -e "${GREEN}$module: Synchronized with remote${NC}"
fi
cd "$REPO_ROOT"
fi
done
# Check parent repository status
echo -e "${BLUE}🏠 Checking parent repository...${NC}"
if ! git diff --quiet || ! git diff --cached --quiet; then
echo -e "${YELLOW}⚠️ Parent repository has uncommitted changes${NC}"
git status --short | sed 's/^/ /'
((warnings++))
else
echo -e "${GREEN}✅ Parent repository is clean${NC}"
fi
# Check for submodule pointer mismatches
echo -e "${BLUE}🔗 Checking submodule pointers...${NC}"
for module in "${(k)submodules[@]}"; do
local module_path="${submodules[$module]}"
if [[ -d "$module_path" ]]; then
local submodule_commit=$(git ls-tree HEAD "$module_path" | awk '{print $3}')
local actual_commit=$(cd "$module_path" && git rev-parse HEAD)
if [[ "$submodule_commit" != "$actual_commit" ]]; then
echo -e "${YELLOW}⚠️ $module: Submodule pointer mismatch${NC}"
echo " Pointer: $submodule_commit"
echo " Actual: $actual_commit"
((warnings++))
else
echo -e "${GREEN}$module: Submodule pointer correct${NC}"
fi
fi
done
# Summary
echo ""
echo -e "${BLUE}📊 Consistency Check Summary:${NC}"
echo " 📦 Modules checked: ${#submodules}"
if [[ $issues -eq 0 && $warnings -eq 0 ]]; then
echo -e "${GREEN} ✅ No issues found${NC}"
echo -e "${GREEN}🎉 All projects are consistent!${NC}"
log "INFO" "Consistency check passed: no issues found"
return 0
else
if [[ $issues -gt 0 ]]; then
echo -e "${RED} ❌ Issues: $issues${NC}"
fi
if [[ $warnings -gt 0 ]]; then
echo -e "${YELLOW} ⚠️ Warnings: $warnings${NC}"
fi
echo ""
echo -e "${BLUE}💡 Recommended actions:${NC}"
echo " • Commit uncommitted changes in affected modules"
echo " • Switch to expected branches where needed"
echo " • Run: ./claude/scripts/update-submodules.sh --all --auto"
echo " • Use session-end.sh for proper session cleanup"
log "WARNING" "Consistency check found $issues issues and $warnings warnings"
return 1
fi
}
# Handle special operations
if [[ "$VALIDATE_ONLY" == true ]]; then
validate_url_consistency
exit $?
fi
if [[ "$SYNC_GITMODULES" == true ]]; then
sync_gitmodules
exit 0
fi
if [[ -n "$ADD_MODULE" ]]; then
add_submodule "$ADD_MODULE"
exit $?
fi
if [[ -n "$REMOVE_MODULE" ]]; then
remove_submodule "$REMOVE_MODULE"
exit $?
fi
if [[ "$CHECK_CONSISTENCY" == true ]]; then
check_project_consistency
exit $?
fi
# Main execution # Main execution
success_count=0 success_count=0
total_count=0 total_count=0
@@ -211,7 +719,7 @@ total_count=0
if [[ "$UPDATE_ALL" == true ]]; then if [[ "$UPDATE_ALL" == true ]]; then
echo -e "${BLUE}📚 Updating all submodules...${NC}" echo -e "${BLUE}📚 Updating all submodules...${NC}"
for module_name in "${(@k)submodules}"; do for module_name in "${(k)submodules[@]}"; do
module_path="${submodules[$module_name]}" module_path="${submodules[$module_name]}"
((total_count++)) ((total_count++))
@@ -224,7 +732,10 @@ else
if [[ -z "${submodules[$SPECIFIC_MODULE]}" ]]; then if [[ -z "${submodules[$SPECIFIC_MODULE]}" ]]; then
echo -e "${RED}❌ Submodule '$SPECIFIC_MODULE' not found${NC}" echo -e "${RED}❌ Submodule '$SPECIFIC_MODULE' not found${NC}"
echo "Available submodules: ${(@k)submodules}" echo "Available submodules:"
for name in "${(k)submodules[@]}"; do
echo " - $name (path: ${submodules[$name]})"
done
exit 1 exit 1
fi fi

2
gpt

Submodule gpt updated: 0de6017491...b410c83605