@dmsdc-ai/aigentry-devkit 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,3 @@
1
+ # Global environment variables
2
+ # Loaded by direnv for all directories under ~/
3
+ dotenv_if_exists "$HOME/.env"
@@ -0,0 +1,12 @@
1
+ {
2
+ "permissions": {
3
+ "allow": [],
4
+ "deny": []
5
+ },
6
+ "env": {
7
+ "CLAUDE_CODE_ENABLE_STATUSLINE": "1",
8
+ "CLAUDE_CODE_STATUSLINE_COMMAND": "bash {{HOME}}/.claude/hud/simple-status.sh"
9
+ },
10
+ "plugins": [],
11
+ "skipDangerousModePermissionPrompt": false
12
+ }
@@ -0,0 +1,16 @@
1
+ {
2
+ "hooks": {
3
+ "SessionStart": [
4
+ {
5
+ "matcher": "startup|resume|clear|compact",
6
+ "hooks": [
7
+ {
8
+ "type": "command",
9
+ "command": "bash '${CLAUDE_PLUGIN_ROOT}/hooks/session-start'",
10
+ "async": false
11
+ }
12
+ ]
13
+ }
14
+ ]
15
+ }
16
+ }
@@ -0,0 +1,37 @@
1
+ #!/bin/bash
2
+ #
3
+ # Session start hook — load bootstrap context
4
+ #
5
+ # Injects the available skills list into the conversation context
6
+ # so the agent knows what capabilities are available.
7
+ #
8
+
9
+ PLUGIN_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
10
+ SKILLS_DIR="$PLUGIN_ROOT/skills"
11
+
12
+ # Build skills index
13
+ SKILLS_LIST=""
14
+ for skill_dir in "$SKILLS_DIR"/*/; do
15
+ [ -d "$skill_dir" ] || continue
16
+ skill_name=$(basename "$skill_dir")
17
+ skill_file="$skill_dir/SKILL.md"
18
+ if [ -f "$skill_file" ]; then
19
+ # Extract description from YAML frontmatter
20
+ desc=$(sed -n '/^---$/,/^---$/p' "$skill_file" | grep -E '^\s*description:' | head -1 | sed 's/.*description:\s*//' | head -c 100)
21
+ SKILLS_LIST="$SKILLS_LIST\n- **$skill_name**: $desc"
22
+ fi
23
+ done
24
+
25
+ if [ -z "$SKILLS_LIST" ]; then
26
+ exit 0
27
+ fi
28
+
29
+ CONTEXT="aigentry-devkit: Available skills:$SKILLS_LIST\n\nUse the Skill tool to invoke any skill by name."
30
+
31
+ # Output in Claude Code hook format
32
+ ESCAPED=$(echo -e "$CONTEXT" | node -e '
33
+ let d=""; process.stdin.on("data",c=>d+=c);
34
+ process.stdin.on("end",()=>console.log(JSON.stringify(d)));
35
+ ' 2>/dev/null)
36
+
37
+ echo "{\"hookSpecificOutput\":{\"additionalContext\":$ESCAPED}}"
@@ -0,0 +1,126 @@
1
+ #!/bin/bash
2
+ # Simple statusline: reads Claude Code stdin JSON for real-time token display
3
+ # Claude Code pipes JSON via stdin with model, context_window, cwd data.
4
+
5
+ # Read stdin JSON
6
+ STDIN=$(cat)
7
+
8
+ # Parse JSON fields with jq (fallback to defaults if missing)
9
+ CWD=$(echo "$STDIN" | jq -r '.cwd // empty' 2>/dev/null)
10
+ CWD="${CWD:-$PWD}"
11
+ CWD=$(basename "$CWD")
12
+
13
+ MODEL=$(echo "$STDIN" | jq -r '.model.display_name // .model.id // "Unknown"' 2>/dev/null)
14
+
15
+ # Context window data
16
+ WINDOW_SIZE=$(echo "$STDIN" | jq -r '.context_window.context_window_size // 0' 2>/dev/null)
17
+ MODEL_ID=$(echo "$STDIN" | jq -r '.model.id // ""' 2>/dev/null)
18
+
19
+ # Max plan: use reported context window (200K) as-is
20
+
21
+ USED_PCT=$(echo "$STDIN" | jq -r '.context_window.used_percentage // empty' 2>/dev/null)
22
+
23
+ # Token usage from current_usage
24
+ INPUT_TOKENS=$(echo "$STDIN" | jq -r '.context_window.current_usage.input_tokens // 0' 2>/dev/null)
25
+ CACHE_CREATE=$(echo "$STDIN" | jq -r '.context_window.current_usage.cache_creation_input_tokens // 0' 2>/dev/null)
26
+ CACHE_READ=$(echo "$STDIN" | jq -r '.context_window.current_usage.cache_read_input_tokens // 0' 2>/dev/null)
27
+
28
+ # Total used tokens
29
+ USED=$((INPUT_TOKENS + CACHE_CREATE + CACHE_READ))
30
+
31
+ # Calculate percentage
32
+ if [ -n "$USED_PCT" ] && [ "$USED_PCT" != "null" ]; then
33
+ PCT=$(printf '%.0f' "$USED_PCT" 2>/dev/null || echo 0)
34
+ elif [ "$WINDOW_SIZE" -gt 0 ] 2>/dev/null; then
35
+ PCT=$((USED * 100 / WINDOW_SIZE))
36
+ else
37
+ PCT=0
38
+ fi
39
+
40
+ # Clamp percentage
41
+ [ "$PCT" -gt 100 ] 2>/dev/null && PCT=100
42
+ [ "$PCT" -lt 0 ] 2>/dev/null && PCT=0
43
+
44
+ # Format token counts (e.g. 48000 -> 48.0K, 1500000 -> 1.50M)
45
+ format_tokens() {
46
+ local n=$1
47
+ if [ "$n" -ge 1000000 ] 2>/dev/null; then
48
+ local m=$((n / 10000))
49
+ echo "$((m / 100)).$((m % 100))M"
50
+ elif [ "$n" -ge 1000 ] 2>/dev/null; then
51
+ local k=$((n / 100))
52
+ echo "$((k / 10)).$((k % 10))K"
53
+ else
54
+ echo "${n}"
55
+ fi
56
+ }
57
+
58
+ USED_FMT=$(format_tokens "$USED")
59
+ WINDOW_FMT=$(format_tokens "$WINDOW_SIZE")
60
+
61
+ # Color codes
62
+ GREEN='\033[32m'
63
+ YELLOW='\033[33m'
64
+ RED='\033[31m'
65
+ DIM='\033[2m'
66
+ RESET='\033[0m'
67
+
68
+ # Select color based on percentage
69
+ if [ "$PCT" -ge 85 ]; then
70
+ COLOR="$RED"
71
+ elif [ "$PCT" -ge 70 ]; then
72
+ COLOR="$YELLOW"
73
+ else
74
+ COLOR="$GREEN"
75
+ fi
76
+
77
+ # Build progress bar (15 chars wide)
78
+ BAR_WIDTH=15
79
+ FILLED=$((PCT * BAR_WIDTH / 100))
80
+ [ "$FILLED" -lt 0 ] 2>/dev/null && FILLED=0
81
+ EMPTY=$((BAR_WIDTH - FILLED))
82
+
83
+ FILLED_BAR=""
84
+ EMPTY_BAR=""
85
+ if [ "$FILLED" -gt 0 ]; then
86
+ FILLED_BAR=$(printf '%0.s█' $(seq 1 "$FILLED"))
87
+ fi
88
+ if [ "$EMPTY" -gt 0 ]; then
89
+ EMPTY_BAR=$(printf '%0.s░' $(seq 1 "$EMPTY"))
90
+ fi
91
+
92
+ # PSM Session Detection
93
+ PSM_SESSION=""
94
+ PSM_NOTIFICATIONS=0
95
+ FULL_CWD=$(echo "$STDIN" | jq -r '.cwd // empty' 2>/dev/null)
96
+ FULL_CWD="${FULL_CWD:-$PWD}"
97
+
98
+ if [ -f "${FULL_CWD}/.psm-session.json" ]; then
99
+ PSM_SESSION=$(jq -r '.session_id // empty' "${FULL_CWD}/.psm-session.json" 2>/dev/null)
100
+ PSM_TYPE=$(jq -r '.type // empty' "${FULL_CWD}/.psm-session.json" 2>/dev/null)
101
+ PSM_BRANCH=$(jq -r '.branch // empty' "${FULL_CWD}/.psm-session.json" 2>/dev/null)
102
+
103
+ # Check for pending notifications
104
+ NOTIFY_FILE="${FULL_CWD}/.psm-notifications/pending.log"
105
+ if [ -f "$NOTIFY_FILE" ] && [ -s "$NOTIFY_FILE" ]; then
106
+ PSM_NOTIFICATIONS=$(wc -l < "$NOTIFY_FILE" | tr -d ' ')
107
+ fi
108
+ fi
109
+
110
+ # Build PSM suffix
111
+ PSM_SUFFIX=""
112
+ if [ -n "$PSM_SESSION" ]; then
113
+ CYAN='\033[36m'
114
+ if [ "$PSM_NOTIFICATIONS" -gt 0 ]; then
115
+ PSM_SUFFIX=$(printf ' | %bPSM:%s [%s] %b%d notif%b' "$CYAN" "$PSM_SESSION" "$PSM_BRANCH" "$YELLOW" "$PSM_NOTIFICATIONS" "$RESET")
116
+ else
117
+ PSM_SUFFIX=$(printf ' | %bPSM:%s [%s]%b' "$CYAN" "$PSM_SESSION" "$PSM_BRANCH" "$RESET")
118
+ fi
119
+ fi
120
+
121
+ # Output: cwd | model | [████░░░░░░] 5% 45.2K/1.0M | PSM:session [branch]
122
+ printf '%s | %s | [%b%s%b%s%b] %b%d%% %s/%s%b%b\n' \
123
+ "$CWD" "$MODEL" \
124
+ "$COLOR" "$FILLED_BAR" "$DIM" "$EMPTY_BAR" "$RESET" \
125
+ "$COLOR" "$PCT" "$USED_FMT" "$WINDOW_FMT" "$RESET" \
126
+ "$PSM_SUFFIX"
package/install.ps1 ADDED
@@ -0,0 +1,203 @@
1
+ param(
2
+ [switch]$Force
3
+ )
4
+
5
+ $ErrorActionPreference = "Stop"
6
+
7
+ $DevkitDir = Split-Path -Parent $MyInvocation.MyCommand.Path
8
+ $ClaudeDir = Join-Path $HOME ".claude"
9
+ $McpDest = Join-Path $HOME ".local\lib\mcp-deliberation"
10
+
11
+ function Write-Info([string]$Message) {
12
+ Write-Host "[+] $Message" -ForegroundColor Green
13
+ }
14
+
15
+ function Write-Warn([string]$Message) {
16
+ Write-Host "[!] $Message" -ForegroundColor Yellow
17
+ }
18
+
19
+ function Write-Header([string]$Message) {
20
+ Write-Host ""
21
+ Write-Host $Message -ForegroundColor Cyan
22
+ }
23
+
24
+ Write-Host ""
25
+ Write-Host " ===============================================" -ForegroundColor Cyan
26
+ Write-Host " aigentry-devkit installer (PowerShell)" -ForegroundColor Cyan
27
+ Write-Host " AI Development Environment Kit" -ForegroundColor Cyan
28
+ Write-Host " ===============================================" -ForegroundColor Cyan
29
+ Write-Host ""
30
+
31
+ Write-Header "1. Prerequisites"
32
+
33
+ $nodeCmd = Get-Command node -ErrorAction SilentlyContinue
34
+ if (-not $nodeCmd) {
35
+ Write-Warn "node not found. Install Node.js 18+ first."
36
+ exit 1
37
+ }
38
+ Write-Info "Node.js $(& node -v) found"
39
+
40
+ $npmCmd = Get-Command npm -ErrorAction SilentlyContinue
41
+ if (-not $npmCmd) {
42
+ Write-Warn "npm not found. Install Node.js (npm included)."
43
+ exit 1
44
+ }
45
+
46
+ if (Get-Command tmux -ErrorAction SilentlyContinue) {
47
+ Write-Info "tmux found (deliberation monitor can run in tmux)"
48
+ } else {
49
+ Write-Warn "tmux not found. Deliberation monitor auto-window is disabled."
50
+ }
51
+
52
+ if (Get-Command claude -ErrorAction SilentlyContinue) {
53
+ Write-Info "Claude Code CLI found"
54
+ } else {
55
+ Write-Warn "Claude Code CLI not found. Install with: npm install -g @anthropic-ai/claude-code"
56
+ }
57
+
58
+ Write-Header "2. Skills"
59
+
60
+ $skillsDest = Join-Path $ClaudeDir "skills"
61
+ New-Item -ItemType Directory -Path $skillsDest -Force | Out-Null
62
+
63
+ $skillDirs = Get-ChildItem (Join-Path $DevkitDir "skills") -Directory
64
+ foreach ($skillDir in $skillDirs) {
65
+ $skillName = $skillDir.Name
66
+ $target = Join-Path $skillsDest $skillName
67
+
68
+ if (Test-Path $target) {
69
+ if ($Force) {
70
+ Remove-Item -Recurse -Force $target
71
+ } else {
72
+ Write-Warn "$skillName already exists (skipping, use -Force to overwrite)"
73
+ continue
74
+ }
75
+ }
76
+
77
+ Copy-Item -Path $skillDir.FullName -Destination $target -Recurse
78
+ Write-Info "Installed skill: $skillName"
79
+ }
80
+
81
+ Write-Header "3. HUD Statusline"
82
+
83
+ $hudDest = Join-Path $ClaudeDir "hud"
84
+ New-Item -ItemType Directory -Path $hudDest -Force | Out-Null
85
+ $hudTarget = Join-Path $hudDest "simple-status.sh"
86
+ $hudSource = Join-Path $DevkitDir "hud\simple-status.sh"
87
+
88
+ if (-not (Test-Path $hudTarget) -or $Force) {
89
+ Copy-Item -Path $hudSource -Destination $hudTarget -Force
90
+ Write-Info "Installed HUD: simple-status.sh"
91
+ } else {
92
+ Write-Warn "HUD already exists (use -Force to overwrite)"
93
+ }
94
+
95
+ Write-Header "4. MCP Deliberation Server"
96
+
97
+ New-Item -ItemType Directory -Path $McpDest -Force | Out-Null
98
+ Copy-Item -Path (Join-Path $DevkitDir "mcp-servers\deliberation\index.js") -Destination (Join-Path $McpDest "index.js") -Force
99
+ Copy-Item -Path (Join-Path $DevkitDir "mcp-servers\deliberation\package.json") -Destination (Join-Path $McpDest "package.json") -Force
100
+ Copy-Item -Path (Join-Path $DevkitDir "mcp-servers\deliberation\session-monitor.sh") -Destination (Join-Path $McpDest "session-monitor.sh") -Force
101
+
102
+ Write-Info "Installing dependencies..."
103
+ Push-Location $McpDest
104
+ npm install --silent | Out-Null
105
+ Pop-Location
106
+ Write-Info "MCP deliberation server installed at $McpDest"
107
+
108
+ Write-Header "5. MCP Registration"
109
+
110
+ $mcpConfig = Join-Path $ClaudeDir ".mcp.json"
111
+ New-Item -ItemType Directory -Path $ClaudeDir -Force | Out-Null
112
+
113
+ if (Test-Path $mcpConfig) {
114
+ try {
115
+ $cfg = Get-Content $mcpConfig -Raw | ConvertFrom-Json
116
+ } catch {
117
+ $cfg = [pscustomobject]@{}
118
+ }
119
+ } else {
120
+ $cfg = [pscustomobject]@{}
121
+ }
122
+
123
+ if (-not $cfg.PSObject.Properties.Name.Contains("mcpServers")) {
124
+ $cfg | Add-Member -MemberType NoteProperty -Name mcpServers -Value ([pscustomobject]@{})
125
+ }
126
+
127
+ $cfg.mcpServers | Add-Member -MemberType NoteProperty -Name deliberation -Value ([pscustomobject]@{
128
+ command = "node"
129
+ args = @((Join-Path $McpDest "index.js"))
130
+ }) -Force
131
+
132
+ $cfg | ConvertTo-Json -Depth 8 | Set-Content -Path $mcpConfig -Encoding utf8
133
+ Write-Info "Registered deliberation MCP in $mcpConfig"
134
+
135
+ Write-Header "6. Config Templates"
136
+
137
+ $settingsDest = Join-Path $ClaudeDir "settings.json"
138
+ $settingsTemplate = Join-Path $DevkitDir "config\settings.json.template"
139
+ if (-not (Test-Path $settingsDest)) {
140
+ if (Test-Path $settingsTemplate) {
141
+ (Get-Content $settingsTemplate -Raw).Replace("{{HOME}}", $HOME) | Set-Content -Path $settingsDest -Encoding utf8
142
+ Write-Info "Created settings.json from template"
143
+ }
144
+ } else {
145
+ Write-Info "settings.json already exists (skipping)"
146
+ }
147
+
148
+ if (Get-Command direnv -ErrorAction SilentlyContinue) {
149
+ $globalEnvrc = Join-Path $HOME ".envrc"
150
+ if (-not (Test-Path $globalEnvrc)) {
151
+ Copy-Item -Path (Join-Path $DevkitDir "config\envrc\global.envrc") -Destination $globalEnvrc
152
+ Write-Info "Installed global .envrc"
153
+ } else {
154
+ Write-Info "Global .envrc already exists (skipping)"
155
+ }
156
+ } else {
157
+ Write-Warn "direnv not found. Skipping .envrc setup."
158
+ }
159
+
160
+ Write-Header "7. Codex Integration (optional)"
161
+
162
+ if (Get-Command codex -ErrorAction SilentlyContinue) {
163
+ try {
164
+ codex mcp add deliberation -- node (Join-Path $McpDest "index.js") | Out-Null
165
+ Write-Info "Registered deliberation MCP in Codex"
166
+ } catch {
167
+ Write-Warn "Codex MCP registration failed (may already exist)"
168
+ }
169
+
170
+ try {
171
+ $codexList = codex mcp list 2>$null
172
+ if ($codexList -match "deliberation") {
173
+ Write-Info "Codex MCP verification passed (deliberation found)"
174
+ } else {
175
+ Write-Warn "Codex MCP verification failed. Run manually: codex mcp add deliberation -- node $McpDest\index.js"
176
+ }
177
+ } catch {
178
+ Write-Warn "Codex MCP verification failed (codex mcp list unavailable)"
179
+ }
180
+ } else {
181
+ Write-Warn "Codex CLI not found. Skipping Codex integration."
182
+ }
183
+
184
+ Write-Header "8. Cross-platform Notes"
185
+ Write-Info "Codex is a deliberation participant CLI, not a separate MCP server."
186
+ Write-Info "Browser LLM tab detection uses macOS automation + CDP scan."
187
+ Write-Info "On Windows/Linux, start browser with --remote-debugging-port=9222 for automatic tab scan."
188
+ Write-Info "Fallback always works: prepare_turn -> paste to browser LLM -> submit_turn."
189
+
190
+ Write-Header "Installation Complete!"
191
+ Write-Host ""
192
+ Write-Host " Installed components:"
193
+ Write-Host " Skills: $((Get-ChildItem $skillsDest -Directory -ErrorAction SilentlyContinue | Measure-Object).Count) skills in $skillsDest"
194
+ Write-Host " HUD: $hudTarget"
195
+ Write-Host " MCP Server: $McpDest"
196
+ Write-Host " Config: $ClaudeDir"
197
+ Write-Host ""
198
+ Write-Host " Next steps:"
199
+ Write-Host " 1. Restart Claude/Codex processes to load new MCP settings"
200
+ Write-Host " 2. If browser tab scan is empty, enable browser remote debugging port"
201
+ Write-Host " 3. For updates, rerun install.ps1 -Force"
202
+ Write-Host ""
203
+ Write-Host " Enjoy your AI development environment!"
package/install.sh ADDED
@@ -0,0 +1,213 @@
1
+ #!/bin/bash
2
+ set -euo pipefail
3
+
4
+ #
5
+ # aigentry-devkit installer
6
+ #
7
+ # Usage:
8
+ # git clone https://github.com/dmsdc-ai/aigentry-devkit.git
9
+ # cd aigentry-devkit && bash install.sh
10
+ #
11
+
12
+ DEVKIT_DIR="$(cd "$(dirname "$0")" && pwd)"
13
+ CLAUDE_DIR="$HOME/.claude"
14
+ MCP_DEST="$HOME/.local/lib/mcp-deliberation"
15
+ PLATFORM="$(uname -s 2>/dev/null || echo unknown)"
16
+
17
+ # 색상
18
+ GREEN='\033[0;32m'
19
+ YELLOW='\033[1;33m'
20
+ CYAN='\033[0;36m'
21
+ BOLD='\033[1m'
22
+ NC='\033[0m'
23
+
24
+ info() { echo -e "${GREEN}[+]${NC} $1"; }
25
+ warn() { echo -e "${YELLOW}[!]${NC} $1"; }
26
+ header() { echo -e "\n${BOLD}${CYAN}$1${NC}"; }
27
+
28
+ echo -e "${BOLD}"
29
+ echo " ╔═══════════════════════════════════════╗"
30
+ echo " ║ aigentry-devkit installer ║"
31
+ echo " ║ AI Development Environment Kit ║"
32
+ echo " ╚═══════════════════════════════════════╝"
33
+ echo -e "${NC}"
34
+
35
+ # ── 사전 요구사항 확인 ──
36
+ header "1. Prerequisites"
37
+
38
+ command -v node >/dev/null 2>&1 || { warn "node not found. Install Node.js 18+"; exit 1; }
39
+ command -v npm >/dev/null 2>&1 || { warn "npm not found. Install Node.js 18+"; exit 1; }
40
+ info "Node.js $(node -v) found"
41
+ info "Platform: $PLATFORM"
42
+
43
+ case "$PLATFORM" in
44
+ MINGW*|MSYS*|CYGWIN*)
45
+ warn "Windows shell detected. Prefer PowerShell installer: powershell -ExecutionPolicy Bypass -File .\\install.ps1"
46
+ ;;
47
+ esac
48
+
49
+ if command -v tmux >/dev/null 2>&1; then
50
+ info "tmux found (deliberation monitor will use it)"
51
+ else
52
+ warn "tmux not found. Deliberation monitor terminals won't auto-open."
53
+ fi
54
+
55
+ if command -v claude >/dev/null 2>&1; then
56
+ info "Claude Code CLI found"
57
+ else
58
+ warn "Claude Code CLI not found. Install: npm install -g @anthropic-ai/claude-code"
59
+ fi
60
+
61
+ # ── Skills 설치 ──
62
+ header "2. Skills"
63
+
64
+ SKILLS_DEST="$CLAUDE_DIR/skills"
65
+ mkdir -p "$SKILLS_DEST"
66
+
67
+ for skill_dir in "$DEVKIT_DIR"/skills/*/; do
68
+ skill_name=$(basename "$skill_dir")
69
+ target="$SKILLS_DEST/$skill_name"
70
+
71
+ if [ -L "$target" ]; then
72
+ rm "$target"
73
+ fi
74
+
75
+ if [ -d "$target" ]; then
76
+ warn "$skill_name already exists (skipping, use --force to overwrite)"
77
+ continue
78
+ fi
79
+
80
+ ln -s "$skill_dir" "$target"
81
+ info "Linked skill: $skill_name"
82
+ done
83
+
84
+ # ── HUD / Statusline ──
85
+ header "3. HUD Statusline"
86
+
87
+ HUD_DEST="$CLAUDE_DIR/hud"
88
+ mkdir -p "$HUD_DEST"
89
+
90
+ if [ ! -f "$HUD_DEST/simple-status.sh" ] || [ "${1:-}" = "--force" ]; then
91
+ cp "$DEVKIT_DIR/hud/simple-status.sh" "$HUD_DEST/simple-status.sh"
92
+ chmod +x "$HUD_DEST/simple-status.sh"
93
+ info "Installed HUD: simple-status.sh"
94
+ else
95
+ warn "HUD already exists (use --force to overwrite)"
96
+ fi
97
+
98
+ # ── MCP Deliberation Server ──
99
+ header "4. MCP Deliberation Server"
100
+
101
+ mkdir -p "$MCP_DEST"
102
+ cp "$DEVKIT_DIR/mcp-servers/deliberation/index.js" "$MCP_DEST/"
103
+ cp "$DEVKIT_DIR/mcp-servers/deliberation/package.json" "$MCP_DEST/"
104
+ cp "$DEVKIT_DIR/mcp-servers/deliberation/session-monitor.sh" "$MCP_DEST/"
105
+ chmod +x "$MCP_DEST/session-monitor.sh"
106
+
107
+ info "Installing dependencies..."
108
+ (cd "$MCP_DEST" && npm install --silent 2>/dev/null)
109
+ info "MCP deliberation server installed at $MCP_DEST"
110
+
111
+ # ── MCP 등록 ──
112
+ header "5. MCP Registration"
113
+
114
+ MCP_CONFIG="$CLAUDE_DIR/.mcp.json"
115
+
116
+ if [ -f "$MCP_CONFIG" ]; then
117
+ # deliberation 서버가 이미 등록되어 있는지 확인
118
+ if node -e "const c=JSON.parse(require('fs').readFileSync('$MCP_CONFIG','utf-8'));process.exit(c.mcpServers?.deliberation?0:1)" 2>/dev/null; then
119
+ info "Deliberation MCP already registered"
120
+ else
121
+ # 기존 설정에 deliberation 추가
122
+ node -e "
123
+ const fs = require('fs');
124
+ const c = JSON.parse(fs.readFileSync('$MCP_CONFIG', 'utf-8'));
125
+ if (!c.mcpServers) c.mcpServers = {};
126
+ c.mcpServers.deliberation = {
127
+ command: 'node',
128
+ args: ['$MCP_DEST/index.js']
129
+ };
130
+ fs.writeFileSync('$MCP_CONFIG', JSON.stringify(c, null, 2));
131
+ "
132
+ info "Registered deliberation MCP in $MCP_CONFIG"
133
+ fi
134
+ else
135
+ # 새로 생성
136
+ cat > "$MCP_CONFIG" << MCPEOF
137
+ {
138
+ "mcpServers": {
139
+ "deliberation": {
140
+ "command": "node",
141
+ "args": ["$MCP_DEST/index.js"]
142
+ }
143
+ }
144
+ }
145
+ MCPEOF
146
+ info "Created $MCP_CONFIG with deliberation MCP"
147
+ fi
148
+
149
+ # ── Config 템플릿 ──
150
+ header "6. Config Templates"
151
+
152
+ # settings.json
153
+ SETTINGS_DEST="$CLAUDE_DIR/settings.json"
154
+ if [ ! -f "$SETTINGS_DEST" ]; then
155
+ SETTINGS_TEMPLATE="$DEVKIT_DIR/config/settings.json.template"
156
+ if [ -f "$SETTINGS_TEMPLATE" ]; then
157
+ sed "s|{{HOME}}|$HOME|g" "$SETTINGS_TEMPLATE" > "$SETTINGS_DEST"
158
+ info "Created settings.json from template"
159
+ fi
160
+ else
161
+ info "settings.json already exists (skipping)"
162
+ fi
163
+
164
+ # envrc
165
+ if command -v direnv >/dev/null 2>&1; then
166
+ if [ ! -f "$HOME/.envrc" ]; then
167
+ cp "$DEVKIT_DIR/config/envrc/global.envrc" "$HOME/.envrc"
168
+ info "Installed global .envrc"
169
+ else
170
+ info "Global .envrc already exists (skipping)"
171
+ fi
172
+ else
173
+ warn "direnv not found. Skipping .envrc setup."
174
+ fi
175
+
176
+ # ── Codex MCP 등록 (가능하면) ──
177
+ header "7. Codex Integration (optional)"
178
+
179
+ if command -v codex >/dev/null 2>&1; then
180
+ codex mcp add deliberation -- node "$MCP_DEST/index.js" 2>/dev/null && \
181
+ info "Registered deliberation MCP in Codex" || \
182
+ warn "Codex MCP registration failed (may already exist)"
183
+
184
+ if codex mcp list 2>/dev/null | grep -q "deliberation"; then
185
+ info "Codex MCP verification passed (deliberation found)"
186
+ else
187
+ warn "Codex MCP verification failed. Run manually: codex mcp add deliberation -- node $MCP_DEST/index.js"
188
+ fi
189
+ else
190
+ warn "Codex CLI not found. Skipping Codex integration."
191
+ fi
192
+
193
+ header "8. Cross-platform Notes"
194
+ info "Codex is a deliberation participant CLI, not a separate MCP server."
195
+ info "Browser LLM tab detection: macOS automation + CDP scan (Linux/Windows need browser remote-debugging port)."
196
+ info "If browser tab auto-scan is unavailable, use clipboard workflow: prepare_turn -> paste in browser -> submit_turn."
197
+
198
+ # ── 완료 ──
199
+ header "Installation Complete!"
200
+ echo ""
201
+ echo -e " ${BOLD}Installed components:${NC}"
202
+ echo -e " Skills: $(ls -d "$SKILLS_DEST"/*/ 2>/dev/null | wc -l | tr -d ' ') skills in $SKILLS_DEST"
203
+ echo -e " HUD: $HUD_DEST/simple-status.sh"
204
+ echo -e " MCP Server: $MCP_DEST"
205
+ echo -e " Config: $CLAUDE_DIR"
206
+ echo ""
207
+ echo -e " ${BOLD}Next steps:${NC}"
208
+ echo -e " 1. Restart Claude/Codex processes for MCP changes to take effect"
209
+ echo -e " 2. Add other MCP servers to $MCP_CONFIG as needed"
210
+ echo -e " 3. Configure your HUD in settings.json if not already done"
211
+ echo -e " 4. For Linux/Windows browser scan, launch browser with --remote-debugging-port=9222"
212
+ echo ""
213
+ echo -e " ${CYAN}Enjoy your AI development environment!${NC}"