@ornexus/neocortex 3.8.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.
- package/LICENSE +56 -0
- package/README.md +661 -0
- package/install.js +453 -0
- package/install.ps1 +1478 -0
- package/install.sh +1409 -0
- package/package.json +93 -0
- package/packages/client/dist/adapters/adapter-registry.d.ts +62 -0
- package/packages/client/dist/adapters/adapter-registry.d.ts.map +1 -0
- package/packages/client/dist/adapters/adapter-registry.js +107 -0
- package/packages/client/dist/adapters/adapter-registry.js.map +1 -0
- package/packages/client/dist/adapters/antigravity-adapter.d.ts +19 -0
- package/packages/client/dist/adapters/antigravity-adapter.d.ts.map +1 -0
- package/packages/client/dist/adapters/antigravity-adapter.js +78 -0
- package/packages/client/dist/adapters/antigravity-adapter.js.map +1 -0
- package/packages/client/dist/adapters/claude-code-adapter.d.ts +20 -0
- package/packages/client/dist/adapters/claude-code-adapter.d.ts.map +1 -0
- package/packages/client/dist/adapters/claude-code-adapter.js +80 -0
- package/packages/client/dist/adapters/claude-code-adapter.js.map +1 -0
- package/packages/client/dist/adapters/codex-adapter.d.ts +20 -0
- package/packages/client/dist/adapters/codex-adapter.d.ts.map +1 -0
- package/packages/client/dist/adapters/codex-adapter.js +81 -0
- package/packages/client/dist/adapters/codex-adapter.js.map +1 -0
- package/packages/client/dist/adapters/cursor-adapter.d.ts +20 -0
- package/packages/client/dist/adapters/cursor-adapter.d.ts.map +1 -0
- package/packages/client/dist/adapters/cursor-adapter.js +116 -0
- package/packages/client/dist/adapters/cursor-adapter.js.map +1 -0
- package/packages/client/dist/adapters/gemini-adapter.d.ts +19 -0
- package/packages/client/dist/adapters/gemini-adapter.d.ts.map +1 -0
- package/packages/client/dist/adapters/gemini-adapter.js +72 -0
- package/packages/client/dist/adapters/gemini-adapter.js.map +1 -0
- package/packages/client/dist/adapters/index.d.ts +20 -0
- package/packages/client/dist/adapters/index.d.ts.map +1 -0
- package/packages/client/dist/adapters/index.js +22 -0
- package/packages/client/dist/adapters/index.js.map +1 -0
- package/packages/client/dist/adapters/platform-detector.d.ts +47 -0
- package/packages/client/dist/adapters/platform-detector.d.ts.map +1 -0
- package/packages/client/dist/adapters/platform-detector.js +107 -0
- package/packages/client/dist/adapters/platform-detector.js.map +1 -0
- package/packages/client/dist/adapters/target-adapter.d.ts +71 -0
- package/packages/client/dist/adapters/target-adapter.d.ts.map +1 -0
- package/packages/client/dist/adapters/target-adapter.js +13 -0
- package/packages/client/dist/adapters/target-adapter.js.map +1 -0
- package/packages/client/dist/adapters/vscode-adapter.d.ts +20 -0
- package/packages/client/dist/adapters/vscode-adapter.d.ts.map +1 -0
- package/packages/client/dist/adapters/vscode-adapter.js +73 -0
- package/packages/client/dist/adapters/vscode-adapter.js.map +1 -0
- package/packages/client/dist/cache/crypto-utils.d.ts +31 -0
- package/packages/client/dist/cache/crypto-utils.d.ts.map +1 -0
- package/packages/client/dist/cache/crypto-utils.js +77 -0
- package/packages/client/dist/cache/crypto-utils.js.map +1 -0
- package/packages/client/dist/cache/encrypted-cache.d.ts +31 -0
- package/packages/client/dist/cache/encrypted-cache.d.ts.map +1 -0
- package/packages/client/dist/cache/encrypted-cache.js +92 -0
- package/packages/client/dist/cache/encrypted-cache.js.map +1 -0
- package/packages/client/dist/cache/index.d.ts +14 -0
- package/packages/client/dist/cache/index.d.ts.map +1 -0
- package/packages/client/dist/cache/index.js +14 -0
- package/packages/client/dist/cache/index.js.map +1 -0
- package/packages/client/dist/cli.d.ts +15 -0
- package/packages/client/dist/cli.d.ts.map +1 -0
- package/packages/client/dist/cli.js +182 -0
- package/packages/client/dist/cli.js.map +1 -0
- package/packages/client/dist/commands/activate.d.ts +48 -0
- package/packages/client/dist/commands/activate.d.ts.map +1 -0
- package/packages/client/dist/commands/activate.js +186 -0
- package/packages/client/dist/commands/activate.js.map +1 -0
- package/packages/client/dist/commands/cache-status.d.ts +40 -0
- package/packages/client/dist/commands/cache-status.d.ts.map +1 -0
- package/packages/client/dist/commands/cache-status.js +113 -0
- package/packages/client/dist/commands/cache-status.js.map +1 -0
- package/packages/client/dist/commands/invoke.d.ts +71 -0
- package/packages/client/dist/commands/invoke.d.ts.map +1 -0
- package/packages/client/dist/commands/invoke.js +345 -0
- package/packages/client/dist/commands/invoke.js.map +1 -0
- package/packages/client/dist/config/resolver-selection.d.ts +41 -0
- package/packages/client/dist/config/resolver-selection.d.ts.map +1 -0
- package/packages/client/dist/config/resolver-selection.js +278 -0
- package/packages/client/dist/config/resolver-selection.js.map +1 -0
- package/packages/client/dist/context/context-collector.d.ts +29 -0
- package/packages/client/dist/context/context-collector.d.ts.map +1 -0
- package/packages/client/dist/context/context-collector.js +223 -0
- package/packages/client/dist/context/context-collector.js.map +1 -0
- package/packages/client/dist/context/context-sanitizer.d.ts +29 -0
- package/packages/client/dist/context/context-sanitizer.d.ts.map +1 -0
- package/packages/client/dist/context/context-sanitizer.js +146 -0
- package/packages/client/dist/context/context-sanitizer.js.map +1 -0
- package/packages/client/dist/index.d.ts +55 -0
- package/packages/client/dist/index.d.ts.map +1 -0
- package/packages/client/dist/index.js +37 -0
- package/packages/client/dist/index.js.map +1 -0
- package/packages/client/dist/license/index.d.ts +6 -0
- package/packages/client/dist/license/index.d.ts.map +1 -0
- package/packages/client/dist/license/index.js +6 -0
- package/packages/client/dist/license/index.js.map +1 -0
- package/packages/client/dist/license/license-client.d.ts +53 -0
- package/packages/client/dist/license/license-client.d.ts.map +1 -0
- package/packages/client/dist/license/license-client.js +164 -0
- package/packages/client/dist/license/license-client.js.map +1 -0
- package/packages/client/dist/machine/fingerprint.d.ts +24 -0
- package/packages/client/dist/machine/fingerprint.d.ts.map +1 -0
- package/packages/client/dist/machine/fingerprint.js +61 -0
- package/packages/client/dist/machine/fingerprint.js.map +1 -0
- package/packages/client/dist/machine/index.d.ts +6 -0
- package/packages/client/dist/machine/index.d.ts.map +1 -0
- package/packages/client/dist/machine/index.js +6 -0
- package/packages/client/dist/machine/index.js.map +1 -0
- package/packages/client/dist/resilience/circuit-breaker.d.ts +71 -0
- package/packages/client/dist/resilience/circuit-breaker.d.ts.map +1 -0
- package/packages/client/dist/resilience/circuit-breaker.js +171 -0
- package/packages/client/dist/resilience/circuit-breaker.js.map +1 -0
- package/packages/client/dist/resilience/degradation-manager.d.ts +68 -0
- package/packages/client/dist/resilience/degradation-manager.d.ts.map +1 -0
- package/packages/client/dist/resilience/degradation-manager.js +165 -0
- package/packages/client/dist/resilience/degradation-manager.js.map +1 -0
- package/packages/client/dist/resilience/freshness-indicator.d.ts +60 -0
- package/packages/client/dist/resilience/freshness-indicator.d.ts.map +1 -0
- package/packages/client/dist/resilience/freshness-indicator.js +101 -0
- package/packages/client/dist/resilience/freshness-indicator.js.map +1 -0
- package/packages/client/dist/resilience/index.d.ts +9 -0
- package/packages/client/dist/resilience/index.d.ts.map +1 -0
- package/packages/client/dist/resilience/index.js +9 -0
- package/packages/client/dist/resilience/index.js.map +1 -0
- package/packages/client/dist/resilience/recovery-detector.d.ts +60 -0
- package/packages/client/dist/resilience/recovery-detector.d.ts.map +1 -0
- package/packages/client/dist/resilience/recovery-detector.js +75 -0
- package/packages/client/dist/resilience/recovery-detector.js.map +1 -0
- package/packages/client/dist/resolvers/asset-resolver.d.ts +80 -0
- package/packages/client/dist/resolvers/asset-resolver.d.ts.map +1 -0
- package/packages/client/dist/resolvers/asset-resolver.js +14 -0
- package/packages/client/dist/resolvers/asset-resolver.js.map +1 -0
- package/packages/client/dist/resolvers/local-resolver.d.ts +27 -0
- package/packages/client/dist/resolvers/local-resolver.d.ts.map +1 -0
- package/packages/client/dist/resolvers/local-resolver.js +219 -0
- package/packages/client/dist/resolvers/local-resolver.js.map +1 -0
- package/packages/client/dist/resolvers/remote-resolver.d.ts +63 -0
- package/packages/client/dist/resolvers/remote-resolver.d.ts.map +1 -0
- package/packages/client/dist/resolvers/remote-resolver.js +207 -0
- package/packages/client/dist/resolvers/remote-resolver.js.map +1 -0
- package/packages/client/dist/telemetry/index.d.ts +6 -0
- package/packages/client/dist/telemetry/index.d.ts.map +1 -0
- package/packages/client/dist/telemetry/index.js +6 -0
- package/packages/client/dist/telemetry/index.js.map +1 -0
- package/packages/client/dist/telemetry/offline-queue.d.ts +58 -0
- package/packages/client/dist/telemetry/offline-queue.d.ts.map +1 -0
- package/packages/client/dist/telemetry/offline-queue.js +132 -0
- package/packages/client/dist/telemetry/offline-queue.js.map +1 -0
- package/packages/client/dist/types/index.d.ts +141 -0
- package/packages/client/dist/types/index.d.ts.map +1 -0
- package/packages/client/dist/types/index.js +39 -0
- package/packages/client/dist/types/index.js.map +1 -0
- package/targets-stubs/antigravity/README.md +20 -0
- package/targets-stubs/claude-code/README.md +20 -0
- package/targets-stubs/codex/README.md +20 -0
- package/targets-stubs/cursor/README.md +20 -0
- package/targets-stubs/gemini-cli/README.md +20 -0
- package/targets-stubs/vscode/README.md +20 -0
package/install.sh
ADDED
|
@@ -0,0 +1,1409 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# Neocortex - Instalador Unix
|
|
4
|
+
# Epic & Story Development Orchestrator
|
|
5
|
+
|
|
6
|
+
# Versao do instalador
|
|
7
|
+
VERSION="3.8.0"
|
|
8
|
+
|
|
9
|
+
# Flags
|
|
10
|
+
MIGRATION_DETECTED=false
|
|
11
|
+
MIGRATION_SOURCES=""
|
|
12
|
+
CODERABBIT_INSTALLED=false
|
|
13
|
+
LEGACY_ITEMS=""
|
|
14
|
+
LEGACY_WARNINGS=0
|
|
15
|
+
SELECTED_TARGETS=""
|
|
16
|
+
VALID_TARGETS="claude-code cursor vscode gemini-cli codex antigravity"
|
|
17
|
+
LOCAL_MODE=false
|
|
18
|
+
NEOCORTEX_SERVER_URL="https://api.neocortex.ornexus.com"
|
|
19
|
+
|
|
20
|
+
# =============================================================================
|
|
21
|
+
# DETECCAO DE AMBIENTE
|
|
22
|
+
# =============================================================================
|
|
23
|
+
|
|
24
|
+
is_interactive() { [ -t 0 ] && [ -t 1 ]; }
|
|
25
|
+
|
|
26
|
+
supports_colors() { [ -t 1 ] && [ "$(tput colors 2>/dev/null || echo 0)" -ge 8 ]; }
|
|
27
|
+
|
|
28
|
+
supports_unicode() {
|
|
29
|
+
case "${LANG:-}${LC_ALL:-}${LC_CTYPE:-}" in
|
|
30
|
+
*UTF-8*|*utf-8*|*utf8*) return 0 ;;
|
|
31
|
+
*) return 1 ;;
|
|
32
|
+
esac
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
if [ -z "$HOME" ]; then
|
|
36
|
+
HOME=$(getent passwd "$(whoami)" | cut -d: -f6 2>/dev/null || echo "/root")
|
|
37
|
+
export HOME
|
|
38
|
+
fi
|
|
39
|
+
|
|
40
|
+
# =============================================================================
|
|
41
|
+
# PARSING DE ARGUMENTOS
|
|
42
|
+
# =============================================================================
|
|
43
|
+
|
|
44
|
+
AUTO_YES=false
|
|
45
|
+
DEBUG_MODE=false
|
|
46
|
+
SKIP_PROJECT_DIRS=false
|
|
47
|
+
CREATE_PROJECT=false
|
|
48
|
+
QUIET_MODE=false
|
|
49
|
+
NO_BANNER=false
|
|
50
|
+
CLEANUP_LEGACY=false
|
|
51
|
+
|
|
52
|
+
while [[ $# -gt 0 ]]; do
|
|
53
|
+
case $1 in
|
|
54
|
+
-y|--yes) AUTO_YES=true; shift ;;
|
|
55
|
+
-d|--debug) DEBUG_MODE=true; shift ;;
|
|
56
|
+
-s|--skip-project) SKIP_PROJECT_DIRS=true; shift ;;
|
|
57
|
+
-q|--quiet) QUIET_MODE=true; shift ;;
|
|
58
|
+
--no-banner) NO_BANNER=true; shift ;;
|
|
59
|
+
--cleanup-legacy) CLEANUP_LEGACY=true; shift ;;
|
|
60
|
+
--targets=*) SELECTED_TARGETS="${1#--targets=}"; shift ;;
|
|
61
|
+
--create-project) CREATE_PROJECT=true; shift ;;
|
|
62
|
+
--local) LOCAL_MODE=true; shift ;;
|
|
63
|
+
--server-url=*) NEOCORTEX_SERVER_URL="${1#--server-url=}"; shift ;;
|
|
64
|
+
-h|--help)
|
|
65
|
+
echo ""
|
|
66
|
+
echo " Neocortex Installer v${VERSION}"
|
|
67
|
+
echo " Epic & Story Development Orchestrator"
|
|
68
|
+
echo ""
|
|
69
|
+
echo " Uso: npx @ornexus/neocortex [opcoes]"
|
|
70
|
+
echo ""
|
|
71
|
+
echo " Opcoes:"
|
|
72
|
+
echo " -y, --yes Modo automatico (Claude Code only)"
|
|
73
|
+
echo " --targets=<lista> Plataformas separadas por virgula"
|
|
74
|
+
echo " --create-project Instalar estrutura no projeto"
|
|
75
|
+
echo " -s, --skip-project Nao perguntar sobre projeto"
|
|
76
|
+
echo " -q, --quiet Modo silencioso"
|
|
77
|
+
echo " --cleanup-legacy Remover artefatos legados de ~/.claude/"
|
|
78
|
+
echo " --local Modo local (copia IP para desenvolvimento)"
|
|
79
|
+
echo " --server-url=<url> URL do server Neocortex (padrao: api.neocortex.ornexus.com)"
|
|
80
|
+
echo " -d, --debug Modo debug"
|
|
81
|
+
echo " -h, --help Mostra esta ajuda"
|
|
82
|
+
echo ""
|
|
83
|
+
echo " Plataformas: claude-code, cursor, vscode, gemini-cli, codex, antigravity"
|
|
84
|
+
exit 0
|
|
85
|
+
;;
|
|
86
|
+
*) shift ;;
|
|
87
|
+
esac
|
|
88
|
+
done
|
|
89
|
+
|
|
90
|
+
if ! is_interactive; then
|
|
91
|
+
AUTO_YES=true
|
|
92
|
+
fi
|
|
93
|
+
|
|
94
|
+
# =============================================================================
|
|
95
|
+
# CORES E SIMBOLOS
|
|
96
|
+
# =============================================================================
|
|
97
|
+
|
|
98
|
+
if supports_colors && [ "$QUIET_MODE" = false ]; then
|
|
99
|
+
RED='\033[0;31m'
|
|
100
|
+
GREEN='\033[0;32m'
|
|
101
|
+
YELLOW='\033[1;33m'
|
|
102
|
+
BLUE='\033[0;34m'
|
|
103
|
+
MAGENTA='\033[0;35m'
|
|
104
|
+
CYAN='\033[0;36m'
|
|
105
|
+
WHITE='\033[1;37m'
|
|
106
|
+
GRAY='\033[0;90m'
|
|
107
|
+
BOLD='\033[1m'
|
|
108
|
+
DIM='\033[2m'
|
|
109
|
+
NC='\033[0m'
|
|
110
|
+
else
|
|
111
|
+
RED='' GREEN='' YELLOW='' BLUE='' MAGENTA='' CYAN=''
|
|
112
|
+
WHITE='' GRAY='' BOLD='' DIM='' NC=''
|
|
113
|
+
fi
|
|
114
|
+
|
|
115
|
+
if supports_unicode; then
|
|
116
|
+
SYM_OK="✓"
|
|
117
|
+
SYM_FAIL="✗"
|
|
118
|
+
SYM_WARN="!"
|
|
119
|
+
SYM_ARROW="→"
|
|
120
|
+
SYM_DOT="·"
|
|
121
|
+
SYM_SPINNER_FRAMES=('⠋' '⠙' '⠹' '⠸' '⠼' '⠴' '⠦' '⠧' '⠇' '⠏')
|
|
122
|
+
else
|
|
123
|
+
SYM_OK="ok"
|
|
124
|
+
SYM_FAIL="x"
|
|
125
|
+
SYM_WARN="!"
|
|
126
|
+
SYM_ARROW="->"
|
|
127
|
+
SYM_DOT="."
|
|
128
|
+
SYM_SPINNER_FRAMES=('|' '/' '-' '\')
|
|
129
|
+
fi
|
|
130
|
+
|
|
131
|
+
# =============================================================================
|
|
132
|
+
# FUNCOES DE LOG
|
|
133
|
+
# =============================================================================
|
|
134
|
+
|
|
135
|
+
# Step header: [1/5] Installing core...
|
|
136
|
+
step() {
|
|
137
|
+
local num=$1 total=$2 msg=$3
|
|
138
|
+
echo ""
|
|
139
|
+
echo -e " ${BOLD}${CYAN}[$num/$total]${NC} ${BOLD}$msg${NC}"
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
# Success line
|
|
143
|
+
ok() { echo -e " ${GREEN}${SYM_OK}${NC} $1"; }
|
|
144
|
+
|
|
145
|
+
# Warning line
|
|
146
|
+
warn() { echo -e " ${YELLOW}${SYM_WARN}${NC} $1"; }
|
|
147
|
+
|
|
148
|
+
# Error line
|
|
149
|
+
fail() { echo -e " ${RED}${SYM_FAIL}${NC} $1"; }
|
|
150
|
+
|
|
151
|
+
# Info line
|
|
152
|
+
info() { echo -e " ${DIM}${SYM_ARROW} $1${NC}"; }
|
|
153
|
+
|
|
154
|
+
# Debug line
|
|
155
|
+
debug() { [ "$DEBUG_MODE" = true ] && echo -e " ${GRAY}[debug] $1${NC}"; }
|
|
156
|
+
|
|
157
|
+
# Spinner for background tasks
|
|
158
|
+
run_with_spinner() {
|
|
159
|
+
local msg="$1"
|
|
160
|
+
shift
|
|
161
|
+
"$@" &
|
|
162
|
+
local pid=$!
|
|
163
|
+
local i=0
|
|
164
|
+
local len=${#SYM_SPINNER_FRAMES[@]}
|
|
165
|
+
|
|
166
|
+
while kill -0 "$pid" 2>/dev/null; do
|
|
167
|
+
printf "\r ${CYAN}%s${NC} %s" "${SYM_SPINNER_FRAMES[$((i % len))]}" "$msg"
|
|
168
|
+
i=$((i + 1))
|
|
169
|
+
sleep 0.08
|
|
170
|
+
done
|
|
171
|
+
|
|
172
|
+
wait "$pid"
|
|
173
|
+
local exit_code=$?
|
|
174
|
+
|
|
175
|
+
if [ $exit_code -eq 0 ]; then
|
|
176
|
+
printf "\r ${GREEN}${SYM_OK}${NC} %s\n" "$msg"
|
|
177
|
+
else
|
|
178
|
+
printf "\r ${RED}${SYM_FAIL}${NC} %s\n" "$msg"
|
|
179
|
+
fi
|
|
180
|
+
|
|
181
|
+
return $exit_code
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
# =============================================================================
|
|
185
|
+
# FUNCOES DE COPIA (silenciosas - sem log individual)
|
|
186
|
+
# =============================================================================
|
|
187
|
+
|
|
188
|
+
copy_file() {
|
|
189
|
+
local src="$1" dest="$2"
|
|
190
|
+
debug "Copiando: $src -> $dest"
|
|
191
|
+
[ -f "$src" ] && cp "$src" "$dest" 2>/dev/null
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
copy_dir() {
|
|
195
|
+
local src="$1" dest="$2"
|
|
196
|
+
debug "Copiando dir: $src -> $dest"
|
|
197
|
+
[ -d "$src" ] && cp -r "$src" "$dest" 2>/dev/null
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
# =============================================================================
|
|
201
|
+
# DETECCAO DE VERSAO ANTIGA
|
|
202
|
+
# =============================================================================
|
|
203
|
+
|
|
204
|
+
detect_old_installation() {
|
|
205
|
+
debug "Verificando instalacoes antigas..."
|
|
206
|
+
|
|
207
|
+
local dest_dir="${HOME}/.claude/agents/neocortex"
|
|
208
|
+
|
|
209
|
+
if [ -f "$dest_dir/.version" ]; then
|
|
210
|
+
INSTALLED_VERSION=$(cat "$dest_dir/.version" 2>/dev/null)
|
|
211
|
+
local new_version=""
|
|
212
|
+
if [ -f "$SOURCE_DIR/package.json" ]; then
|
|
213
|
+
new_version=$(grep '"version"' "$SOURCE_DIR/package.json" 2>/dev/null | head -1 | sed 's/.*"version"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/')
|
|
214
|
+
fi
|
|
215
|
+
if [ -n "$INSTALLED_VERSION" ] && [ -n "$new_version" ]; then
|
|
216
|
+
if [ "$INSTALLED_VERSION" = "$new_version" ]; then
|
|
217
|
+
info "Reinstalando v$new_version"
|
|
218
|
+
else
|
|
219
|
+
info "Atualizando v$INSTALLED_VERSION ${SYM_ARROW} v$new_version"
|
|
220
|
+
fi
|
|
221
|
+
fi
|
|
222
|
+
fi
|
|
223
|
+
|
|
224
|
+
# Check for old files
|
|
225
|
+
local old_files=()
|
|
226
|
+
if [ -f "$dest_dir/step-registry.json" ]; then
|
|
227
|
+
if ! grep -q "state.json" "$dest_dir/workflow.md" 2>/dev/null; then
|
|
228
|
+
old_files+=("workflow antigo")
|
|
229
|
+
fi
|
|
230
|
+
fi
|
|
231
|
+
|
|
232
|
+
if grep -r "orchestrator.db" "$dest_dir" 2>/dev/null | grep -v "backup" | grep -v "migrated" > /dev/null; then
|
|
233
|
+
old_files+=("referencias SQLite")
|
|
234
|
+
fi
|
|
235
|
+
|
|
236
|
+
if [ ${#old_files[@]} -gt 0 ]; then
|
|
237
|
+
MIGRATION_DETECTED=true
|
|
238
|
+
MIGRATION_SOURCES="${old_files[*]}"
|
|
239
|
+
debug "Detectado: $MIGRATION_SOURCES"
|
|
240
|
+
fi
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
detect_legacy_artifacts() {
|
|
244
|
+
local warnings=0
|
|
245
|
+
local legacy_items=""
|
|
246
|
+
local claude_dir="$HOME/.claude"
|
|
247
|
+
|
|
248
|
+
debug "Verificando artefatos legados em ~/.claude/..."
|
|
249
|
+
|
|
250
|
+
# Check 1: .git inside agents/ (leftover from contains-studio/agents repo)
|
|
251
|
+
if [ -d "$claude_dir/agents/.git" ]; then
|
|
252
|
+
warn "Repositorio .git detectado em ~/.claude/agents/"
|
|
253
|
+
info "Pode conflitar com instalacoes do Neocortex"
|
|
254
|
+
info "Execute com --cleanup-legacy para remover"
|
|
255
|
+
legacy_items="${legacy_items}${claude_dir}/agents/.git
|
|
256
|
+
"
|
|
257
|
+
warnings=$((warnings + 1))
|
|
258
|
+
fi
|
|
259
|
+
|
|
260
|
+
# Check 2: Nested .claude/.claude/ (BMAD installation error)
|
|
261
|
+
if [ -d "$claude_dir/.claude" ]; then
|
|
262
|
+
warn "Diretorio aninhado detectado: ~/.claude/.claude/"
|
|
263
|
+
info "Possivelmente erro de instalacao anterior (BMAD)"
|
|
264
|
+
info "Execute com --cleanup-legacy para remover"
|
|
265
|
+
legacy_items="${legacy_items}${claude_dir}/.claude
|
|
266
|
+
"
|
|
267
|
+
warnings=$((warnings + 1))
|
|
268
|
+
fi
|
|
269
|
+
|
|
270
|
+
# Check 3: Loose agents without namespace (files directly in agents/, not in subdirs)
|
|
271
|
+
local loose_count=0
|
|
272
|
+
if [ -d "$claude_dir/agents" ]; then
|
|
273
|
+
for f in "$claude_dir/agents"/*.md; do
|
|
274
|
+
[ -f "$f" ] || continue
|
|
275
|
+
loose_count=$((loose_count + 1))
|
|
276
|
+
debug " Solto: $(basename "$f")"
|
|
277
|
+
done
|
|
278
|
+
fi
|
|
279
|
+
if [ $loose_count -gt 0 ]; then
|
|
280
|
+
info "$loose_count arquivo(s) .md solto(s) em ~/.claude/agents/"
|
|
281
|
+
info "Considere organizar em namespaces (ex: agents/neocortex/)"
|
|
282
|
+
warnings=$((warnings + 1))
|
|
283
|
+
fi
|
|
284
|
+
|
|
285
|
+
# Check 4: Legacy agents-ldtn/ directory
|
|
286
|
+
if [ -d "$claude_dir/agents-ldtn" ]; then
|
|
287
|
+
warn "Diretorio legado detectado: ~/.claude/agents-ldtn/"
|
|
288
|
+
info "Execute com --cleanup-legacy para remover"
|
|
289
|
+
legacy_items="${legacy_items}${claude_dir}/agents-ldtn
|
|
290
|
+
"
|
|
291
|
+
warnings=$((warnings + 1))
|
|
292
|
+
fi
|
|
293
|
+
|
|
294
|
+
# Check 5: .superclaude-metadata.json
|
|
295
|
+
if [ -f "$claude_dir/.superclaude-metadata.json" ]; then
|
|
296
|
+
warn "Metadata legado detectado: ~/.claude/.superclaude-metadata.json"
|
|
297
|
+
info "Execute com --cleanup-legacy para remover"
|
|
298
|
+
legacy_items="${legacy_items}${claude_dir}/.superclaude-metadata.json
|
|
299
|
+
"
|
|
300
|
+
warnings=$((warnings + 1))
|
|
301
|
+
fi
|
|
302
|
+
|
|
303
|
+
# Check 6: superclaude_backup_*.tar.gz in backups/
|
|
304
|
+
local backup_count=0
|
|
305
|
+
if [ -d "$claude_dir/backups" ]; then
|
|
306
|
+
for f in "$claude_dir/backups"/superclaude_backup_*.tar.gz; do
|
|
307
|
+
[ -f "$f" ] || continue
|
|
308
|
+
backup_count=$((backup_count + 1))
|
|
309
|
+
done
|
|
310
|
+
fi
|
|
311
|
+
if [ $backup_count -gt 0 ]; then
|
|
312
|
+
info "$backup_count backup(s) SuperClaude antigo(s) em ~/.claude/backups/"
|
|
313
|
+
warnings=$((warnings + 1))
|
|
314
|
+
fi
|
|
315
|
+
|
|
316
|
+
if [ $warnings -gt 0 ]; then
|
|
317
|
+
warn "$warnings artefato(s) legado(s) detectado(s)"
|
|
318
|
+
fi
|
|
319
|
+
|
|
320
|
+
# Export for cleanup (newline-separated for paths with spaces)
|
|
321
|
+
LEGACY_ITEMS="$legacy_items"
|
|
322
|
+
LEGACY_WARNINGS=$warnings
|
|
323
|
+
|
|
324
|
+
return 0 # Never block installation
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
cleanup_legacy_artifacts() {
|
|
328
|
+
# Only run if --cleanup-legacy was passed
|
|
329
|
+
if [ "$CLEANUP_LEGACY" != true ]; then
|
|
330
|
+
return 0
|
|
331
|
+
fi
|
|
332
|
+
|
|
333
|
+
# Check if there are items to clean
|
|
334
|
+
if [ $LEGACY_WARNINGS -eq 0 ] || [ -z "$LEGACY_ITEMS" ]; then
|
|
335
|
+
info "Nenhum artefato legado encontrado para limpeza"
|
|
336
|
+
return 0
|
|
337
|
+
fi
|
|
338
|
+
|
|
339
|
+
# Safety: refuse cleanup in --yes mode (protect against automated deletion)
|
|
340
|
+
if [ "$AUTO_YES" = true ]; then
|
|
341
|
+
warn "Cleanup requer confirmacao interativa (--yes ignorado para seguranca)"
|
|
342
|
+
return 0
|
|
343
|
+
fi
|
|
344
|
+
|
|
345
|
+
# Show what will be removed
|
|
346
|
+
echo ""
|
|
347
|
+
warn "Os seguintes artefatos serao removidos:"
|
|
348
|
+
local item_count=0
|
|
349
|
+
while IFS= read -r item; do
|
|
350
|
+
[ -z "$item" ] && continue
|
|
351
|
+
local display_item="${item/#$HOME/~}"
|
|
352
|
+
if [ -d "$item" ]; then
|
|
353
|
+
info " - ${display_item}/ (diretorio)"
|
|
354
|
+
else
|
|
355
|
+
info " - ${display_item} (arquivo)"
|
|
356
|
+
fi
|
|
357
|
+
item_count=$((item_count + 1))
|
|
358
|
+
done <<EOF
|
|
359
|
+
$LEGACY_ITEMS
|
|
360
|
+
EOF
|
|
361
|
+
|
|
362
|
+
echo -ne " Confirmar remocao? ${BOLD}[s/N]:${NC} "
|
|
363
|
+
|
|
364
|
+
local response=""
|
|
365
|
+
if read -r -t 30 response 2>/dev/null; then
|
|
366
|
+
: # response received
|
|
367
|
+
else
|
|
368
|
+
echo ""
|
|
369
|
+
info "Timeout - cleanup cancelado"
|
|
370
|
+
return 0
|
|
371
|
+
fi
|
|
372
|
+
|
|
373
|
+
if [[ ! "$response" =~ ^([sS][iI]?[mM]?|[yY][eE]?[sS]?)$ ]]; then
|
|
374
|
+
info "Cleanup cancelado"
|
|
375
|
+
return 0
|
|
376
|
+
fi
|
|
377
|
+
|
|
378
|
+
# Execute cleanup
|
|
379
|
+
local removed=0
|
|
380
|
+
local failed=0
|
|
381
|
+
while IFS= read -r item; do
|
|
382
|
+
[ -z "$item" ] && continue
|
|
383
|
+
local display_item="${item/#$HOME/~}"
|
|
384
|
+
if rm -rf "$item" 2>/dev/null; then
|
|
385
|
+
ok "Removido: $display_item"
|
|
386
|
+
removed=$((removed + 1))
|
|
387
|
+
else
|
|
388
|
+
fail "Falha ao remover: $display_item"
|
|
389
|
+
failed=$((failed + 1))
|
|
390
|
+
fi
|
|
391
|
+
done <<EOF
|
|
392
|
+
$LEGACY_ITEMS
|
|
393
|
+
EOF
|
|
394
|
+
|
|
395
|
+
if [ $failed -eq 0 ]; then
|
|
396
|
+
ok "$removed artefato(s) removido(s) com sucesso"
|
|
397
|
+
else
|
|
398
|
+
warn "$removed removido(s), $failed falha(s)"
|
|
399
|
+
fi
|
|
400
|
+
|
|
401
|
+
return 0
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
detect_project_migration_needs() {
|
|
405
|
+
local migration_needed=false
|
|
406
|
+
local sources=()
|
|
407
|
+
|
|
408
|
+
[ -f ".neocortex/orchestrator.db" ] && { migration_needed=true; sources+=("orchestrator.db"); }
|
|
409
|
+
for yaml_path in "bmad-output/sprint-status.yaml" ".neocortex/sprint-status.yaml" "docs/sprint-status.yaml"; do
|
|
410
|
+
[ -f "$yaml_path" ] && { migration_needed=true; sources+=("$yaml_path"); }
|
|
411
|
+
done
|
|
412
|
+
|
|
413
|
+
if [ "$migration_needed" = true ]; then
|
|
414
|
+
echo "${sources[*]}"
|
|
415
|
+
return 0
|
|
416
|
+
fi
|
|
417
|
+
return 1
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
# =============================================================================
|
|
421
|
+
# BANNER
|
|
422
|
+
# =============================================================================
|
|
423
|
+
|
|
424
|
+
show_banner() {
|
|
425
|
+
[ "$QUIET_MODE" = true ] && return
|
|
426
|
+
[ "$NO_BANNER" = true ] && return
|
|
427
|
+
|
|
428
|
+
# True color blue gradient (#00B4FF → #7DD3FC → #0070A8) matching neocortex-cli theme
|
|
429
|
+
local g1="\033[38;2;0;180;255m" # #00B4FF bright blue
|
|
430
|
+
local g2="\033[38;2;48;191;254m" # #30BFFE
|
|
431
|
+
local g3="\033[38;2;95;204;253m" # #5FCCFD light blue
|
|
432
|
+
local g4="\033[38;2;102;192;236m" # #66C0EC
|
|
433
|
+
local g5="\033[38;2;56;154;204m" # #389ACC
|
|
434
|
+
local g6="\033[38;2;0;112;168m" # #0070A8 deep blue
|
|
435
|
+
local gd="\033[38;5;236m"
|
|
436
|
+
local gt="\033[38;5;243m"
|
|
437
|
+
local rst="\033[0m"
|
|
438
|
+
|
|
439
|
+
local lines=(
|
|
440
|
+
"${g1} ███╗ ██╗███████╗ ██████╗ ██████╗ ██████╗ ██████╗ ████████╗███████╗██╗ ██╗${rst}"
|
|
441
|
+
"${g2} ████╗ ██║██╔════╝██╔═══██╗██╔════╝██╔═══██╗██╔══██╗╚══██╔══╝██╔════╝╚██╗██╔╝${rst}"
|
|
442
|
+
"${g3} ██╔██╗ ██║█████╗ ██║ ██║██║ ██║ ██║██████╔╝ ██║ █████╗ ╚███╔╝${rst}"
|
|
443
|
+
"${g4} ██║╚██╗██║██╔══╝ ██║ ██║██║ ██║ ██║██╔══██╗ ██║ ██╔══╝ ██╔██╗${rst}"
|
|
444
|
+
"${g5} ██║ ╚████║███████╗╚██████╔╝╚██████╗╚██████╔╝██║ ██║ ██║ ███████╗██╔╝ ██╗${rst}"
|
|
445
|
+
"${g6} ╚═╝ ╚═══╝╚══════╝ ╚═════╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚══════╝╚═╝ ╚═╝${rst}"
|
|
446
|
+
""
|
|
447
|
+
"${gd} ──────────────────────────────────────────────────────────────────────────────────${rst}"
|
|
448
|
+
"${gt} Development Orchestrator | OrNexus Team v${VERSION}${rst}"
|
|
449
|
+
)
|
|
450
|
+
|
|
451
|
+
echo ""
|
|
452
|
+
for line in "${lines[@]}"; do
|
|
453
|
+
echo -e "$line"
|
|
454
|
+
sleep 0.02
|
|
455
|
+
done
|
|
456
|
+
echo ""
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
# =============================================================================
|
|
460
|
+
# DETECCAO DO DIRETORIO FONTE
|
|
461
|
+
# =============================================================================
|
|
462
|
+
|
|
463
|
+
detect_source_dir() {
|
|
464
|
+
if [ -n "${BASH_SOURCE[0]}" ]; then
|
|
465
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" 2>/dev/null && pwd)"
|
|
466
|
+
elif [ -n "$0" ]; then
|
|
467
|
+
SCRIPT_DIR="$(cd "$(dirname "$0")" 2>/dev/null && pwd)"
|
|
468
|
+
else
|
|
469
|
+
SCRIPT_DIR="$PWD"
|
|
470
|
+
fi
|
|
471
|
+
|
|
472
|
+
if [ ! -f "$SCRIPT_DIR/targets/claude-code/neocortex.md" ]; then
|
|
473
|
+
if [ ! -f "$SCRIPT_DIR/neocortex.md" ]; then
|
|
474
|
+
for possible_dir in \
|
|
475
|
+
"$SCRIPT_DIR" \
|
|
476
|
+
"$(npm root -g 2>/dev/null)/neocortex" \
|
|
477
|
+
"$(dirname "$0")" \
|
|
478
|
+
"$PWD/node_modules/neocortex" \
|
|
479
|
+
"$HOME/.npm/_npx/"*"/node_modules/neocortex"; do
|
|
480
|
+
if [ -f "$possible_dir/targets/claude-code/neocortex.md" ] 2>/dev/null || \
|
|
481
|
+
[ -f "$possible_dir/neocortex.md" ] 2>/dev/null; then
|
|
482
|
+
SCRIPT_DIR="$possible_dir"
|
|
483
|
+
break
|
|
484
|
+
fi
|
|
485
|
+
done
|
|
486
|
+
fi
|
|
487
|
+
fi
|
|
488
|
+
|
|
489
|
+
SOURCE_DIR="$SCRIPT_DIR"
|
|
490
|
+
debug "Source: $SOURCE_DIR"
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
# =============================================================================
|
|
494
|
+
# TIER 3: CLEANUP DE IP LEGADA E CONFIG DO THIN CLIENT
|
|
495
|
+
# =============================================================================
|
|
496
|
+
|
|
497
|
+
cleanup_legacy_ip() {
|
|
498
|
+
local neocortex_dir="${HOME}/.claude/agents/neocortex"
|
|
499
|
+
local skills_dir="${HOME}/.claude/skills/neocortex"
|
|
500
|
+
local cleaned=false
|
|
501
|
+
|
|
502
|
+
# Remover core/ e seus subdiretorios
|
|
503
|
+
if [ -d "$neocortex_dir/core" ]; then
|
|
504
|
+
rm -rf "$neocortex_dir/core"
|
|
505
|
+
cleaned=true
|
|
506
|
+
fi
|
|
507
|
+
|
|
508
|
+
# Remover step folders (steps-c, steps-e, steps-p, steps-r, steps-u)
|
|
509
|
+
for folder in steps-c steps-e steps-p steps-r steps-u; do
|
|
510
|
+
if [ -d "$neocortex_dir/$folder" ]; then
|
|
511
|
+
rm -rf "$neocortex_dir/$folder"
|
|
512
|
+
cleaned=true
|
|
513
|
+
fi
|
|
514
|
+
done
|
|
515
|
+
|
|
516
|
+
# Remover skills
|
|
517
|
+
if [ -d "$skills_dir" ]; then
|
|
518
|
+
rm -rf "$skills_dir"
|
|
519
|
+
cleaned=true
|
|
520
|
+
fi
|
|
521
|
+
|
|
522
|
+
# Remover arquivos desnecessarios
|
|
523
|
+
for file in package.json README.md; do
|
|
524
|
+
if [ -f "$neocortex_dir/$file" ]; then
|
|
525
|
+
rm -f "$neocortex_dir/$file"
|
|
526
|
+
cleaned=true
|
|
527
|
+
fi
|
|
528
|
+
done
|
|
529
|
+
|
|
530
|
+
if [ "$cleaned" = true ]; then
|
|
531
|
+
info "IP proprietaria removida de versao anterior (agora servida via server remoto)"
|
|
532
|
+
fi
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
setup_thin_client_config() {
|
|
536
|
+
local config_dir="${HOME}/.neocortex"
|
|
537
|
+
local config_file="${config_dir}/config.json"
|
|
538
|
+
|
|
539
|
+
mkdir -p "$config_dir" 2>/dev/null
|
|
540
|
+
mkdir -p "$config_dir/cache" 2>/dev/null
|
|
541
|
+
|
|
542
|
+
if [ -f "$config_file" ]; then
|
|
543
|
+
# Preservar config existente, atualizar apenas serverUrl se necessario
|
|
544
|
+
local existing_mode
|
|
545
|
+
existing_mode=$(grep '"mode"' "$config_file" 2>/dev/null | head -1 | sed 's/.*"mode"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/')
|
|
546
|
+
|
|
547
|
+
if [ "$existing_mode" = "active" ] || [ "$existing_mode" = "local" ]; then
|
|
548
|
+
debug "Config existente preservada (mode=$existing_mode)"
|
|
549
|
+
return 0
|
|
550
|
+
fi
|
|
551
|
+
fi
|
|
552
|
+
|
|
553
|
+
# Criar config base para thin client
|
|
554
|
+
cat > "$config_file" << EOFCONFIG
|
|
555
|
+
{
|
|
556
|
+
"version": "${VERSION}",
|
|
557
|
+
"mode": "pending-activation",
|
|
558
|
+
"serverUrl": "${NEOCORTEX_SERVER_URL}",
|
|
559
|
+
"tier": 3,
|
|
560
|
+
"cache": {
|
|
561
|
+
"enabled": true,
|
|
562
|
+
"directory": "${config_dir}/cache",
|
|
563
|
+
"encryption": "AES-256-GCM"
|
|
564
|
+
},
|
|
565
|
+
"resilience": {
|
|
566
|
+
"circuitBreaker": true,
|
|
567
|
+
"maxRetries": 3,
|
|
568
|
+
"timeoutMs": 5000
|
|
569
|
+
},
|
|
570
|
+
"installedAt": "$(date -Iseconds 2>/dev/null || date '+%Y-%m-%dT%H:%M:%S')",
|
|
571
|
+
"installerVersion": "${VERSION}"
|
|
572
|
+
}
|
|
573
|
+
EOFCONFIG
|
|
574
|
+
|
|
575
|
+
debug "Thin client config criada: $config_file"
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
cleanup_legacy_ip_project() {
|
|
579
|
+
local project_dir="$1"
|
|
580
|
+
local neocortex_dir="$project_dir/.claude/agents/neocortex"
|
|
581
|
+
local skills_dir="$project_dir/.claude/skills/neocortex"
|
|
582
|
+
local cleaned=false
|
|
583
|
+
|
|
584
|
+
# Remover core/ e seus subdiretorios
|
|
585
|
+
if [ -d "$neocortex_dir/core" ]; then
|
|
586
|
+
rm -rf "$neocortex_dir/core"
|
|
587
|
+
cleaned=true
|
|
588
|
+
fi
|
|
589
|
+
|
|
590
|
+
# Remover step folders
|
|
591
|
+
for folder in steps-c steps-e steps-p steps-r steps-u; do
|
|
592
|
+
if [ -d "$neocortex_dir/$folder" ]; then
|
|
593
|
+
rm -rf "$neocortex_dir/$folder"
|
|
594
|
+
cleaned=true
|
|
595
|
+
fi
|
|
596
|
+
done
|
|
597
|
+
|
|
598
|
+
# Remover skills
|
|
599
|
+
if [ -d "$skills_dir" ]; then
|
|
600
|
+
rm -rf "$skills_dir"
|
|
601
|
+
cleaned=true
|
|
602
|
+
fi
|
|
603
|
+
|
|
604
|
+
# Remover arquivos desnecessarios
|
|
605
|
+
for file in package.json README.md; do
|
|
606
|
+
if [ -f "$neocortex_dir/$file" ]; then
|
|
607
|
+
rm -f "$neocortex_dir/$file"
|
|
608
|
+
cleaned=true
|
|
609
|
+
fi
|
|
610
|
+
done
|
|
611
|
+
|
|
612
|
+
if [ "$cleaned" = true ]; then
|
|
613
|
+
info "IP proprietaria removida do projeto (agora servida via server remoto)"
|
|
614
|
+
fi
|
|
615
|
+
}
|
|
616
|
+
|
|
617
|
+
# =============================================================================
|
|
618
|
+
# INSTALACAO CORE
|
|
619
|
+
# =============================================================================
|
|
620
|
+
|
|
621
|
+
install_core() {
|
|
622
|
+
local errors=0
|
|
623
|
+
|
|
624
|
+
CLAUDE_DIR="${HOME}/.claude"
|
|
625
|
+
AGENTS_DIR="${CLAUDE_DIR}/agents"
|
|
626
|
+
DEST_DIR="${AGENTS_DIR}/neocortex"
|
|
627
|
+
|
|
628
|
+
debug "HOME=$HOME | DEST=$DEST_DIR | LOCAL_MODE=$LOCAL_MODE"
|
|
629
|
+
|
|
630
|
+
# Create directories
|
|
631
|
+
if [ ! -d "$CLAUDE_DIR" ]; then
|
|
632
|
+
mkdir -p "$CLAUDE_DIR" 2>/dev/null || { fail "Falha ao criar $CLAUDE_DIR"; return 1; }
|
|
633
|
+
fi
|
|
634
|
+
mkdir -p "$AGENTS_DIR" 2>/dev/null || { fail "Falha ao criar $AGENTS_DIR"; return 1; }
|
|
635
|
+
|
|
636
|
+
# Clean previous installation
|
|
637
|
+
if [ -d "$DEST_DIR" ]; then
|
|
638
|
+
rm -rf "$DEST_DIR" 2>/dev/null
|
|
639
|
+
debug "Instalacao anterior removida"
|
|
640
|
+
fi
|
|
641
|
+
mkdir -p "$DEST_DIR" 2>/dev/null || { fail "Falha ao criar $DEST_DIR"; return 1; }
|
|
642
|
+
|
|
643
|
+
if [ "$LOCAL_MODE" = true ]; then
|
|
644
|
+
# Mode local: copiar IP completa (comportamento legado para devs)
|
|
645
|
+
copy_dir "$SOURCE_DIR/core" "$DEST_DIR/" || ((errors++))
|
|
646
|
+
copy_file "$SOURCE_DIR/package.json" "$DEST_DIR/" || ((errors++))
|
|
647
|
+
copy_file "$SOURCE_DIR/README.md" "$DEST_DIR/" || ((errors++))
|
|
648
|
+
else
|
|
649
|
+
# Tier 3 Remote Mode: NÃO copiar IP
|
|
650
|
+
# Apenas setup do thin client - steps/skills/standards vem do server
|
|
651
|
+
cleanup_legacy_ip
|
|
652
|
+
setup_thin_client_config
|
|
653
|
+
fi
|
|
654
|
+
|
|
655
|
+
# Write version file
|
|
656
|
+
local pkg_version=""
|
|
657
|
+
if [ -f "$SOURCE_DIR/package.json" ]; then
|
|
658
|
+
pkg_version=$(grep '"version"' "$SOURCE_DIR/package.json" 2>/dev/null | head -1 | sed 's/.*"version"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/')
|
|
659
|
+
fi
|
|
660
|
+
[ -n "$pkg_version" ] && echo "$pkg_version" > "$DEST_DIR/.version"
|
|
661
|
+
|
|
662
|
+
if [ $errors -eq 0 ]; then
|
|
663
|
+
if [ "$LOCAL_MODE" = true ]; then
|
|
664
|
+
ok "Core instalado ${DIM}(standards, templates, scripts) [modo local]${NC}"
|
|
665
|
+
else
|
|
666
|
+
ok "Core instalado ${DIM}(thin client configurado) [modo remoto]${NC}"
|
|
667
|
+
fi
|
|
668
|
+
else
|
|
669
|
+
fail "Core instalado com erros"
|
|
670
|
+
fi
|
|
671
|
+
|
|
672
|
+
return $errors
|
|
673
|
+
}
|
|
674
|
+
|
|
675
|
+
# =============================================================================
|
|
676
|
+
# INSTALACAO DE SKILLS
|
|
677
|
+
# =============================================================================
|
|
678
|
+
|
|
679
|
+
install_skills() {
|
|
680
|
+
local errors=0
|
|
681
|
+
|
|
682
|
+
SKILLS_DIR="${CLAUDE_DIR}/skills"
|
|
683
|
+
SKILLS_DEST="${SKILLS_DIR}/neocortex"
|
|
684
|
+
SKILLS_SOURCE="${SOURCE_DIR}/core/skills"
|
|
685
|
+
|
|
686
|
+
# Tier 3 Remote Mode: skills vem do server, nao copiar
|
|
687
|
+
if [ "$LOCAL_MODE" != true ]; then
|
|
688
|
+
ok "Skills ${DIM}(servidas via server remoto) [modo remoto]${NC}"
|
|
689
|
+
return 0
|
|
690
|
+
fi
|
|
691
|
+
|
|
692
|
+
if [ ! -d "$SKILLS_SOURCE" ]; then
|
|
693
|
+
debug "Skills nao encontradas no pacote"
|
|
694
|
+
return 0
|
|
695
|
+
fi
|
|
696
|
+
|
|
697
|
+
mkdir -p "$SKILLS_DIR" 2>/dev/null || { fail "Falha ao criar $SKILLS_DIR"; return 1; }
|
|
698
|
+
|
|
699
|
+
# Clean previous
|
|
700
|
+
[ -d "$SKILLS_DEST" ] && rm -rf "$SKILLS_DEST" 2>/dev/null
|
|
701
|
+
|
|
702
|
+
if cp -r "$SKILLS_SOURCE" "$SKILLS_DEST" 2>/dev/null; then
|
|
703
|
+
# Count skills
|
|
704
|
+
local skill_count=0
|
|
705
|
+
for skill_file in "$SKILLS_DEST"/step-skills/*/*.md "$SKILLS_DEST"/domain-skills/*/*.md; do
|
|
706
|
+
if [ -f "$skill_file" ] && [[ "$(basename "$skill_file")" != "_template.md" ]]; then
|
|
707
|
+
((skill_count++))
|
|
708
|
+
fi
|
|
709
|
+
done
|
|
710
|
+
ok "Skills instaladas ${DIM}($skill_count skills) [modo local]${NC}"
|
|
711
|
+
else
|
|
712
|
+
fail "Falha ao copiar skills"
|
|
713
|
+
((errors++))
|
|
714
|
+
fi
|
|
715
|
+
|
|
716
|
+
return $errors
|
|
717
|
+
}
|
|
718
|
+
|
|
719
|
+
# =============================================================================
|
|
720
|
+
# INSTALACAO DE AGENT (Claude Code)
|
|
721
|
+
# =============================================================================
|
|
722
|
+
|
|
723
|
+
install_agent() {
|
|
724
|
+
local errors=0
|
|
725
|
+
|
|
726
|
+
CLAUDE_TARGET_DIR="$SOURCE_DIR/targets/claude-code"
|
|
727
|
+
[ ! -d "$CLAUDE_TARGET_DIR" ] && CLAUDE_TARGET_DIR="$SOURCE_DIR"
|
|
728
|
+
|
|
729
|
+
# Tier 3 Stub-Only: copiar apenas 2 arquivos de interface (stubs minimos)
|
|
730
|
+
copy_file "$CLAUDE_TARGET_DIR/neocortex.md" "$DEST_DIR/"
|
|
731
|
+
copy_file "$CLAUDE_TARGET_DIR/neocortex.agent.yaml" "$DEST_DIR/"
|
|
732
|
+
|
|
733
|
+
# Cleanup: remover workflow.md de instalacoes anteriores (v3.8 -> v3.9)
|
|
734
|
+
if [ -f "$DEST_DIR/workflow.md" ]; then
|
|
735
|
+
rm -f "$DEST_DIR/workflow.md"
|
|
736
|
+
[ "$QUIET_MODE" = false ] && echo " Removed workflow.md (content now server-side)"
|
|
737
|
+
fi
|
|
738
|
+
|
|
739
|
+
if [ "$LOCAL_MODE" = true ]; then
|
|
740
|
+
# Modo local: copiar IP completa (comportamento legado para devs)
|
|
741
|
+
copy_file "$SOURCE_DIR/package.json" "$DEST_DIR/"
|
|
742
|
+
copy_file "$SOURCE_DIR/README.md" "$DEST_DIR/"
|
|
743
|
+
copy_dir "$SOURCE_DIR/core" "$DEST_DIR/"
|
|
744
|
+
|
|
745
|
+
for folder in steps-c steps-e steps-p steps-r steps-u; do
|
|
746
|
+
copy_dir "$SOURCE_DIR/core/steps/$folder" "$DEST_DIR/"
|
|
747
|
+
done
|
|
748
|
+
fi
|
|
749
|
+
# Tier 3 Remote Mode: apenas 2 stub files + server-side orchestration
|
|
750
|
+
|
|
751
|
+
return $errors
|
|
752
|
+
}
|
|
753
|
+
|
|
754
|
+
# =============================================================================
|
|
755
|
+
# INSTALACAO DE TARGETS
|
|
756
|
+
# =============================================================================
|
|
757
|
+
|
|
758
|
+
install_targets() {
|
|
759
|
+
local targets="$1"
|
|
760
|
+
local target_errors=0
|
|
761
|
+
local target_count=0
|
|
762
|
+
local target_results=()
|
|
763
|
+
|
|
764
|
+
targets=$(echo "$targets" | tr ',' ' ')
|
|
765
|
+
|
|
766
|
+
for target in $targets; do
|
|
767
|
+
local adapter_script="$SOURCE_DIR/targets/$target/install-${target}.sh"
|
|
768
|
+
local func_name="install_$(echo "$target" | tr '-' '_')"
|
|
769
|
+
|
|
770
|
+
if [ ! -f "$adapter_script" ]; then
|
|
771
|
+
if [ "$target" = "claude-code" ]; then
|
|
772
|
+
install_agent
|
|
773
|
+
local result=$?
|
|
774
|
+
if [ $result -eq 0 ]; then
|
|
775
|
+
target_results+=("$target:OK")
|
|
776
|
+
((target_count++))
|
|
777
|
+
ok "${BOLD}claude-code${NC} ${DIM}(agent, steps, core)${NC}"
|
|
778
|
+
else
|
|
779
|
+
target_results+=("$target:FAIL")
|
|
780
|
+
((target_errors++))
|
|
781
|
+
fail "claude-code"
|
|
782
|
+
fi
|
|
783
|
+
continue
|
|
784
|
+
fi
|
|
785
|
+
|
|
786
|
+
warn "$target ${DIM}(adapter nao encontrado)${NC}"
|
|
787
|
+
target_results+=("$target:SKIP")
|
|
788
|
+
((target_errors++))
|
|
789
|
+
continue
|
|
790
|
+
fi
|
|
791
|
+
|
|
792
|
+
. "$adapter_script"
|
|
793
|
+
|
|
794
|
+
if type "$func_name" >/dev/null 2>&1; then
|
|
795
|
+
"$func_name" "$SOURCE_DIR" "$HOME"
|
|
796
|
+
local result=$?
|
|
797
|
+
if [ $result -eq 0 ]; then
|
|
798
|
+
target_results+=("$target:OK")
|
|
799
|
+
((target_count++))
|
|
800
|
+
ok "${BOLD}$target${NC}"
|
|
801
|
+
else
|
|
802
|
+
target_results+=("$target:WARN")
|
|
803
|
+
warn "$target ${DIM}(instalado com avisos)${NC}"
|
|
804
|
+
((target_count++))
|
|
805
|
+
fi
|
|
806
|
+
else
|
|
807
|
+
fail "$target ${DIM}(funcao $func_name nao encontrada)${NC}"
|
|
808
|
+
target_results+=("$target:FAIL")
|
|
809
|
+
((target_errors++))
|
|
810
|
+
fi
|
|
811
|
+
done
|
|
812
|
+
|
|
813
|
+
TARGET_RESULTS=("${target_results[@]}")
|
|
814
|
+
TARGET_COUNT=$target_count
|
|
815
|
+
|
|
816
|
+
return $target_errors
|
|
817
|
+
}
|
|
818
|
+
|
|
819
|
+
# =============================================================================
|
|
820
|
+
# CARREGAMENTO DE .ENV
|
|
821
|
+
# =============================================================================
|
|
822
|
+
|
|
823
|
+
load_env_file() {
|
|
824
|
+
local env_file=""
|
|
825
|
+
for possible_env in "./.env" "$SOURCE_DIR/.env"; do
|
|
826
|
+
[ -f "$possible_env" ] && { env_file="$possible_env"; break; }
|
|
827
|
+
done
|
|
828
|
+
|
|
829
|
+
if [ -n "$env_file" ] && [ -f "$env_file" ]; then
|
|
830
|
+
local loaded=0
|
|
831
|
+
while IFS='=' read -r key value || [ -n "$key" ]; do
|
|
832
|
+
[[ -z "$key" || "$key" =~ ^[[:space:]]*# ]] && continue
|
|
833
|
+
key=$(echo "$key" | xargs)
|
|
834
|
+
value=$(echo "$value" | xargs)
|
|
835
|
+
value="${value%\"}"; value="${value#\"}"
|
|
836
|
+
value="${value%\'}"; value="${value#\'}"
|
|
837
|
+
if [ -n "$value" ] && [ -z "${!key}" ]; then
|
|
838
|
+
export "$key=$value"
|
|
839
|
+
((loaded++))
|
|
840
|
+
fi
|
|
841
|
+
done < "$env_file"
|
|
842
|
+
[ $loaded -gt 0 ] && info "$loaded variavel(eis) carregada(s) do .env"
|
|
843
|
+
return 0
|
|
844
|
+
fi
|
|
845
|
+
return 1
|
|
846
|
+
}
|
|
847
|
+
|
|
848
|
+
# =============================================================================
|
|
849
|
+
# CONFIGURACAO DE TOKENS
|
|
850
|
+
# =============================================================================
|
|
851
|
+
|
|
852
|
+
prompt_tokens() {
|
|
853
|
+
[ "$QUIET_MODE" = true ] && return
|
|
854
|
+
[ -n "$CONTEXT7_API_KEY" ] && return
|
|
855
|
+
|
|
856
|
+
if [ "$AUTO_YES" = true ]; then
|
|
857
|
+
return
|
|
858
|
+
fi
|
|
859
|
+
|
|
860
|
+
echo ""
|
|
861
|
+
info "MCP Context7 nao configurado ${DIM}(opcional)${NC}"
|
|
862
|
+
echo -ne " Configurar agora? ${BOLD}[s/N]:${NC} "
|
|
863
|
+
|
|
864
|
+
local response=""
|
|
865
|
+
if read -r -t 15 response 2>/dev/null; then
|
|
866
|
+
: # resposta recebida
|
|
867
|
+
else
|
|
868
|
+
echo ""
|
|
869
|
+
return
|
|
870
|
+
fi
|
|
871
|
+
|
|
872
|
+
if [[ "$response" =~ ^([sS][iI]?[mM]?|[yY][eE]?[sS]?)$ ]]; then
|
|
873
|
+
echo ""
|
|
874
|
+
info "Obtenha sua API Key em: ${WHITE}https://context7.com${NC}"
|
|
875
|
+
echo -ne " Cole sua ${BOLD}CONTEXT7_API_KEY${NC}: "
|
|
876
|
+
|
|
877
|
+
local api_key=""
|
|
878
|
+
if read -r -t 60 api_key 2>/dev/null; then
|
|
879
|
+
if [[ "$api_key" =~ ^ctx7sk- ]]; then
|
|
880
|
+
export CONTEXT7_API_KEY="$api_key"
|
|
881
|
+
ok "CONTEXT7_API_KEY configurada"
|
|
882
|
+
echo ""
|
|
883
|
+
info "Para persistir: ${DIM}echo 'export CONTEXT7_API_KEY=\"$api_key\"' >> ~/.bashrc${NC}"
|
|
884
|
+
elif [ -n "$api_key" ]; then
|
|
885
|
+
warn "Formato invalido (esperado: ctx7sk-...)"
|
|
886
|
+
fi
|
|
887
|
+
fi
|
|
888
|
+
fi
|
|
889
|
+
}
|
|
890
|
+
|
|
891
|
+
# =============================================================================
|
|
892
|
+
# INSTALACAO DE MCP SERVERS
|
|
893
|
+
# =============================================================================
|
|
894
|
+
|
|
895
|
+
install_mcps() {
|
|
896
|
+
if ! command -v claude >/dev/null 2>&1; then
|
|
897
|
+
info "Claude CLI nao encontrado ${DIM}(MCPs serao instalados depois)${NC}"
|
|
898
|
+
return 0
|
|
899
|
+
fi
|
|
900
|
+
|
|
901
|
+
local mcp_results=""
|
|
902
|
+
|
|
903
|
+
if claude mcp list 2>/dev/null | grep -q "^playwright"; then
|
|
904
|
+
mcp_results="${mcp_results}playwright:OK "
|
|
905
|
+
else
|
|
906
|
+
if claude mcp add playwright npx @playwright/mcp@latest 2>/dev/null; then
|
|
907
|
+
mcp_results="${mcp_results}playwright:OK "
|
|
908
|
+
else
|
|
909
|
+
mcp_results="${mcp_results}playwright:FAIL "
|
|
910
|
+
fi
|
|
911
|
+
fi
|
|
912
|
+
|
|
913
|
+
if claude mcp list 2>/dev/null | grep -q "^context7"; then
|
|
914
|
+
mcp_results="${mcp_results}context7:OK "
|
|
915
|
+
elif [ -n "$CONTEXT7_API_KEY" ]; then
|
|
916
|
+
if claude mcp add --transport http context7 https://mcp.context7.com/mcp --header "CONTEXT7_API_KEY: $CONTEXT7_API_KEY" 2>/dev/null; then
|
|
917
|
+
mcp_results="${mcp_results}context7:OK "
|
|
918
|
+
else
|
|
919
|
+
mcp_results="${mcp_results}context7:FAIL "
|
|
920
|
+
fi
|
|
921
|
+
else
|
|
922
|
+
mcp_results="${mcp_results}context7:SKIP "
|
|
923
|
+
fi
|
|
924
|
+
|
|
925
|
+
# Show compact MCP results
|
|
926
|
+
local mcp_ok="" mcp_skip=""
|
|
927
|
+
for entry in $mcp_results; do
|
|
928
|
+
local name="${entry%%:*}"
|
|
929
|
+
local status="${entry##*:}"
|
|
930
|
+
case "$status" in
|
|
931
|
+
OK) mcp_ok="${mcp_ok}${name}, " ;;
|
|
932
|
+
SKIP) mcp_skip="${mcp_skip}${name}, " ;;
|
|
933
|
+
esac
|
|
934
|
+
done
|
|
935
|
+
|
|
936
|
+
[ -n "$mcp_ok" ] && ok "MCPs: ${DIM}${mcp_ok%, }${NC}"
|
|
937
|
+
[ -n "$mcp_skip" ] && info "MCPs pendentes: ${DIM}${mcp_skip%, }${NC}"
|
|
938
|
+
|
|
939
|
+
return 0
|
|
940
|
+
}
|
|
941
|
+
|
|
942
|
+
# =============================================================================
|
|
943
|
+
# INSTALACAO DO CODERABBIT CLI
|
|
944
|
+
# =============================================================================
|
|
945
|
+
|
|
946
|
+
install_coderabbit() {
|
|
947
|
+
if command -v coderabbit >/dev/null 2>&1; then
|
|
948
|
+
ok "CodeRabbit CLI"
|
|
949
|
+
CODERABBIT_INSTALLED=true
|
|
950
|
+
return 0
|
|
951
|
+
fi
|
|
952
|
+
|
|
953
|
+
if command -v curl >/dev/null 2>&1 && curl -fsSL https://cli.coderabbit.ai/install.sh | sh 2>/dev/null; then
|
|
954
|
+
ok "CodeRabbit CLI ${DIM}(instalado)${NC}"
|
|
955
|
+
CODERABBIT_INSTALLED=true
|
|
956
|
+
elif command -v npm >/dev/null 2>&1 && npm install -g coderabbit 2>/dev/null; then
|
|
957
|
+
ok "CodeRabbit CLI ${DIM}(via npm)${NC}"
|
|
958
|
+
CODERABBIT_INSTALLED=true
|
|
959
|
+
else
|
|
960
|
+
info "CodeRabbit CLI ${DIM}(instale depois: curl -fsSL https://cli.coderabbit.ai/install.sh | sh)${NC}"
|
|
961
|
+
CODERABBIT_INSTALLED=false
|
|
962
|
+
fi
|
|
963
|
+
|
|
964
|
+
return 0
|
|
965
|
+
}
|
|
966
|
+
|
|
967
|
+
# =============================================================================
|
|
968
|
+
# VERIFICACAO POS-INSTALACAO
|
|
969
|
+
# =============================================================================
|
|
970
|
+
|
|
971
|
+
verify_installation() {
|
|
972
|
+
local fails=0
|
|
973
|
+
local warns=0
|
|
974
|
+
local report=""
|
|
975
|
+
|
|
976
|
+
if ! echo "$SELECTED_TARGETS" | grep -q "claude-code"; then
|
|
977
|
+
return 0
|
|
978
|
+
fi
|
|
979
|
+
|
|
980
|
+
# ─── Layer 1: File existence + minimum size ─────────────────────────
|
|
981
|
+
local check_fname check_min check_fpath check_size check_ext check_first_line check_display
|
|
982
|
+
for check_fname in neocortex.md neocortex.agent.yaml; do
|
|
983
|
+
case "$check_fname" in
|
|
984
|
+
neocortex.md) check_min=512 ;;
|
|
985
|
+
neocortex.agent.yaml) check_min=128 ;;
|
|
986
|
+
esac
|
|
987
|
+
check_fpath="${DEST_DIR}/${check_fname}"
|
|
988
|
+
|
|
989
|
+
if [ ! -f "$check_fpath" ]; then
|
|
990
|
+
report="${report}FAIL ${check_fname} (nao encontrado)\n"
|
|
991
|
+
fails=$((fails + 1))
|
|
992
|
+
else
|
|
993
|
+
check_size=$(wc -c < "$check_fpath" 2>/dev/null | tr -d ' ')
|
|
994
|
+
if [ "$check_size" -lt "$check_min" ] 2>/dev/null; then
|
|
995
|
+
report="${report}FAIL ${check_fname} (${check_size} bytes - possivelmente corrompido, minimo ${check_min})\n"
|
|
996
|
+
fails=$((fails + 1))
|
|
997
|
+
else
|
|
998
|
+
# ─── Layer 2: Content marker (frontmatter) ──────────────
|
|
999
|
+
check_ext="${check_fname##*.}"
|
|
1000
|
+
if [ "$check_ext" = "md" ]; then
|
|
1001
|
+
check_first_line=$(head -1 "$check_fpath" 2>/dev/null)
|
|
1002
|
+
if [ "$check_first_line" != "---" ]; then
|
|
1003
|
+
report="${report}WARN ${check_fname} (formato invalido - sem frontmatter)\n"
|
|
1004
|
+
warns=$((warns + 1))
|
|
1005
|
+
else
|
|
1006
|
+
if [ "$check_size" -ge 1024 ]; then check_display="$((check_size / 1024))KB"; else check_display="${check_size}B"; fi
|
|
1007
|
+
report="${report}OK ${check_fname} (${check_display})\n"
|
|
1008
|
+
fi
|
|
1009
|
+
else
|
|
1010
|
+
if [ "$check_size" -ge 1024 ]; then check_display="$((check_size / 1024))KB"; else check_display="${check_size}B"; fi
|
|
1011
|
+
report="${report}OK ${check_fname} (${check_display})\n"
|
|
1012
|
+
fi
|
|
1013
|
+
fi
|
|
1014
|
+
fi
|
|
1015
|
+
done
|
|
1016
|
+
|
|
1017
|
+
if [ "$LOCAL_MODE" = true ]; then
|
|
1018
|
+
# ─── Layer 3: Step directories (local mode only) ─────────────────
|
|
1019
|
+
for dir in steps-c steps-e steps-p steps-r steps-u; do
|
|
1020
|
+
local dir_path="$DEST_DIR/$dir"
|
|
1021
|
+
if [ ! -d "$dir_path" ]; then
|
|
1022
|
+
report="${report}FAIL ${dir}/ (diretorio nao encontrado)\n"
|
|
1023
|
+
fails=$((fails + 1))
|
|
1024
|
+
else
|
|
1025
|
+
local md_count=0
|
|
1026
|
+
for f in "$dir_path"/*.md; do
|
|
1027
|
+
[ -f "$f" ] && md_count=$((md_count + 1))
|
|
1028
|
+
done
|
|
1029
|
+
if [ $md_count -eq 0 ]; then
|
|
1030
|
+
report="${report}WARN ${dir}/ (vazio - nenhum arquivo .md)\n"
|
|
1031
|
+
warns=$((warns + 1))
|
|
1032
|
+
else
|
|
1033
|
+
report="${report}OK ${dir}/ (${md_count} arquivos)\n"
|
|
1034
|
+
fi
|
|
1035
|
+
fi
|
|
1036
|
+
done
|
|
1037
|
+
|
|
1038
|
+
# ─── Layer 3b: Core directory (local mode only) ──────────────────
|
|
1039
|
+
if [ ! -d "$DEST_DIR/core" ]; then
|
|
1040
|
+
report="${report}FAIL core/ (diretorio nao encontrado)\n"
|
|
1041
|
+
fails=$((fails + 1))
|
|
1042
|
+
else
|
|
1043
|
+
report="${report}OK core/\n"
|
|
1044
|
+
fi
|
|
1045
|
+
else
|
|
1046
|
+
# ─── Layer 3: Thin client config (remote mode) ───────────────────
|
|
1047
|
+
local config_file="${HOME}/.neocortex/config.json"
|
|
1048
|
+
if [ -f "$config_file" ]; then
|
|
1049
|
+
report="${report}OK ~/.neocortex/config.json (thin client configurado)\n"
|
|
1050
|
+
else
|
|
1051
|
+
report="${report}WARN ~/.neocortex/config.json (nao encontrado)\n"
|
|
1052
|
+
warns=$((warns + 1))
|
|
1053
|
+
fi
|
|
1054
|
+
|
|
1055
|
+
# Verify NO IP directories exist
|
|
1056
|
+
local ip_found=false
|
|
1057
|
+
for dir in core steps-c steps-e steps-p steps-r steps-u; do
|
|
1058
|
+
if [ -d "$DEST_DIR/$dir" ]; then
|
|
1059
|
+
report="${report}WARN ${dir}/ ainda existe (deveria ter sido removido)\n"
|
|
1060
|
+
warns=$((warns + 1))
|
|
1061
|
+
ip_found=true
|
|
1062
|
+
fi
|
|
1063
|
+
done
|
|
1064
|
+
if [ "$ip_found" = false ]; then
|
|
1065
|
+
report="${report}OK Zero IP no filesystem (modo remoto)\n"
|
|
1066
|
+
fi
|
|
1067
|
+
fi
|
|
1068
|
+
|
|
1069
|
+
# ─── Display report ─────────────────────────────────────────────────
|
|
1070
|
+
if [ $fails -eq 0 ] && [ $warns -eq 0 ]; then
|
|
1071
|
+
# All good - compact output
|
|
1072
|
+
if [ "$QUIET_MODE" != true ]; then
|
|
1073
|
+
ok "Instalacao verificada"
|
|
1074
|
+
fi
|
|
1075
|
+
return 0
|
|
1076
|
+
fi
|
|
1077
|
+
|
|
1078
|
+
# Show detailed report when issues found
|
|
1079
|
+
if [ "$QUIET_MODE" = true ] && [ $fails -eq 0 ]; then
|
|
1080
|
+
return 0 # In quiet mode, skip warnings-only report
|
|
1081
|
+
fi
|
|
1082
|
+
|
|
1083
|
+
echo ""
|
|
1084
|
+
info "Verificacao pos-instalacao:"
|
|
1085
|
+
echo -e "$report" | while IFS= read -r line; do
|
|
1086
|
+
[ -z "$line" ] && continue
|
|
1087
|
+
local status="${line%% *}"
|
|
1088
|
+
local detail="${line#* }"
|
|
1089
|
+
case "$status" in
|
|
1090
|
+
OK) echo -e " ${GREEN}${SYM_OK}${NC} $detail" ;;
|
|
1091
|
+
WARN) echo -e " ${YELLOW}${SYM_WARN}${NC} $detail" ;;
|
|
1092
|
+
FAIL) echo -e " ${RED}${SYM_FAIL}${NC} $detail" ;;
|
|
1093
|
+
esac
|
|
1094
|
+
done
|
|
1095
|
+
|
|
1096
|
+
[ $fails -gt 0 ] && return 1
|
|
1097
|
+
return 0
|
|
1098
|
+
}
|
|
1099
|
+
|
|
1100
|
+
# =============================================================================
|
|
1101
|
+
# RESULTADO
|
|
1102
|
+
# =============================================================================
|
|
1103
|
+
|
|
1104
|
+
show_result() {
|
|
1105
|
+
local install_status=$1
|
|
1106
|
+
[ "$QUIET_MODE" = true ] && return
|
|
1107
|
+
|
|
1108
|
+
echo ""
|
|
1109
|
+
echo -e " ${DIM}────────────────────────────────────────${NC}"
|
|
1110
|
+
|
|
1111
|
+
if [ $install_status -eq 0 ] && verify_installation; then
|
|
1112
|
+
echo ""
|
|
1113
|
+
echo -e " ${GREEN}${BOLD}Instalacao concluida!${NC}"
|
|
1114
|
+
echo ""
|
|
1115
|
+
if [ "$LOCAL_MODE" = true ]; then
|
|
1116
|
+
echo -e " ${DIM}Modo:${NC} Local (IP completa copiada)"
|
|
1117
|
+
echo -e " ${DIM}Locais:${NC}"
|
|
1118
|
+
echo -e " ${DIM}Agente:${NC} ~/.claude/agents/neocortex/"
|
|
1119
|
+
echo -e " ${DIM}Skills:${NC} ~/.claude/skills/neocortex/"
|
|
1120
|
+
else
|
|
1121
|
+
echo -e " ${DIM}Modo:${NC} Remoto (Tier 3 - thin client)"
|
|
1122
|
+
echo -e " ${DIM}Locais:${NC}"
|
|
1123
|
+
echo -e " ${DIM}Agente:${NC} ~/.claude/agents/neocortex/ ${DIM}(3 arquivos)${NC}"
|
|
1124
|
+
echo -e " ${DIM}Config:${NC} ~/.neocortex/config.json"
|
|
1125
|
+
echo ""
|
|
1126
|
+
echo -e " ${DIM}Ative sua licenca:${NC}"
|
|
1127
|
+
echo -e " ${CYAN}npx @ornexus/neocortex-client activate NX-PRO-xxx${NC}"
|
|
1128
|
+
fi
|
|
1129
|
+
echo ""
|
|
1130
|
+
echo -e " ${DIM}Proximo passo:${NC}"
|
|
1131
|
+
echo -e " ${CYAN}@neocortex *init @docs/epics.md${NC}"
|
|
1132
|
+
echo ""
|
|
1133
|
+
else
|
|
1134
|
+
echo ""
|
|
1135
|
+
echo -e " ${RED}${BOLD}Instalacao com problemas${NC}"
|
|
1136
|
+
echo ""
|
|
1137
|
+
echo -e " Execute novamente com ${BOLD}--debug${NC} para detalhes:"
|
|
1138
|
+
echo -e " ${YELLOW}npx @ornexus/neocortex --debug${NC}"
|
|
1139
|
+
echo ""
|
|
1140
|
+
return 1
|
|
1141
|
+
fi
|
|
1142
|
+
}
|
|
1143
|
+
|
|
1144
|
+
# =============================================================================
|
|
1145
|
+
# CRIACAO DE DIRETORIOS DO PROJETO
|
|
1146
|
+
# =============================================================================
|
|
1147
|
+
|
|
1148
|
+
create_project_dirs() {
|
|
1149
|
+
[ "$QUIET_MODE" = true ] && return
|
|
1150
|
+
[ "$SKIP_PROJECT_DIRS" = true ] && return
|
|
1151
|
+
|
|
1152
|
+
local should_create=false
|
|
1153
|
+
|
|
1154
|
+
if [ "$CREATE_PROJECT" = true ] || [ "$AUTO_YES" = true ]; then
|
|
1155
|
+
should_create=true
|
|
1156
|
+
else
|
|
1157
|
+
echo -ne " Instalar estrutura no projeto atual? ${BOLD}[s/N]:${NC} "
|
|
1158
|
+
|
|
1159
|
+
local response="n"
|
|
1160
|
+
if read -r -t 30 response </dev/tty 2>/dev/null; then
|
|
1161
|
+
:
|
|
1162
|
+
else
|
|
1163
|
+
echo ""
|
|
1164
|
+
response="n"
|
|
1165
|
+
fi
|
|
1166
|
+
|
|
1167
|
+
[[ "$response" =~ ^([sS][iI]?[mM]?|[yY][eE]?[sS]?)$ ]] && should_create=true
|
|
1168
|
+
fi
|
|
1169
|
+
|
|
1170
|
+
if [ "$should_create" = true ]; then
|
|
1171
|
+
local project_dir="$PWD"
|
|
1172
|
+
|
|
1173
|
+
# Clean previous project files
|
|
1174
|
+
rm -rf "$project_dir/targets/claude-code" 2>/dev/null
|
|
1175
|
+
rm -f "$project_dir/.cursor/agents/neocortex.md" 2>/dev/null
|
|
1176
|
+
rm -rf "$project_dir/.cursor/skills" 2>/dev/null
|
|
1177
|
+
rm -f "$project_dir/.github/agents/neocortex.md" 2>/dev/null
|
|
1178
|
+
rm -rf "$project_dir/.github/skills" 2>/dev/null
|
|
1179
|
+
rm -f "$project_dir/.github/copilot-instructions.md" 2>/dev/null
|
|
1180
|
+
rm -rf "$project_dir/.agent/skills/neocortex" 2>/dev/null
|
|
1181
|
+
rm -f "$project_dir/AGENTS.md" 2>/dev/null
|
|
1182
|
+
rm -rf "$project_dir/.agents/skills" 2>/dev/null
|
|
1183
|
+
rm -f "$project_dir/GEMINI.md" 2>/dev/null
|
|
1184
|
+
rm -rf "$project_dir/.claude/agents/neocortex" 2>/dev/null
|
|
1185
|
+
rm -rf "$project_dir/.claude/skills/neocortex" 2>/dev/null
|
|
1186
|
+
|
|
1187
|
+
if [ "$LOCAL_MODE" = true ]; then
|
|
1188
|
+
# Modo local: limpar e reconstruir core/
|
|
1189
|
+
rm -rf "$project_dir/core" 2>/dev/null
|
|
1190
|
+
fi
|
|
1191
|
+
|
|
1192
|
+
# Create base directories
|
|
1193
|
+
mkdir -p "$project_dir/.neocortex/specs" \
|
|
1194
|
+
"$project_dir/.neocortex/planning" \
|
|
1195
|
+
"$project_dir/docs/stories" \
|
|
1196
|
+
"$project_dir/docs/epics" \
|
|
1197
|
+
"$project_dir/docs/proposals" 2>/dev/null
|
|
1198
|
+
|
|
1199
|
+
# Copy state template if needed
|
|
1200
|
+
if [ ! -f "$project_dir/.neocortex/state.json" ]; then
|
|
1201
|
+
[ -f "$SOURCE_DIR/core/data/state-template.json" ] && \
|
|
1202
|
+
cp "$SOURCE_DIR/core/data/state-template.json" "$project_dir/.neocortex/state.json"
|
|
1203
|
+
fi
|
|
1204
|
+
|
|
1205
|
+
# Copy core (ONLY in local mode)
|
|
1206
|
+
if [ "$LOCAL_MODE" = true ] && [ -d "$SOURCE_DIR/core" ]; then
|
|
1207
|
+
mkdir -p "$project_dir/core"
|
|
1208
|
+
cp -r "$SOURCE_DIR/core"/* "$project_dir/core/" 2>/dev/null
|
|
1209
|
+
fi
|
|
1210
|
+
|
|
1211
|
+
# Install target-specific files
|
|
1212
|
+
local targets_list
|
|
1213
|
+
targets_list=$(echo "$SELECTED_TARGETS" | tr ',' ' ')
|
|
1214
|
+
local target_summary=""
|
|
1215
|
+
|
|
1216
|
+
for target in $targets_list; do
|
|
1217
|
+
case "$target" in
|
|
1218
|
+
claude-code)
|
|
1219
|
+
local claude_target_dir="$SOURCE_DIR/targets/claude-code"
|
|
1220
|
+
if [ -d "$claude_target_dir" ]; then
|
|
1221
|
+
mkdir -p "$project_dir/.claude/agents/neocortex"
|
|
1222
|
+
|
|
1223
|
+
# Tier 3: copiar apenas 2 stub files
|
|
1224
|
+
cp "$claude_target_dir/neocortex.md" "$project_dir/.claude/agents/neocortex/" 2>/dev/null
|
|
1225
|
+
cp "$claude_target_dir/neocortex.agent.yaml" "$project_dir/.claude/agents/neocortex/" 2>/dev/null
|
|
1226
|
+
# Cleanup workflow.md from previous versions
|
|
1227
|
+
rm -f "$project_dir/.claude/agents/neocortex/workflow.md" 2>/dev/null
|
|
1228
|
+
|
|
1229
|
+
if [ "$LOCAL_MODE" = true ]; then
|
|
1230
|
+
# Modo local: copiar IP completa (comportamento legado)
|
|
1231
|
+
cp "$SOURCE_DIR/package.json" "$project_dir/.claude/agents/neocortex/" 2>/dev/null
|
|
1232
|
+
cp "$SOURCE_DIR/README.md" "$project_dir/.claude/agents/neocortex/" 2>/dev/null
|
|
1233
|
+
mkdir -p "$project_dir/.claude/agents/neocortex/core"
|
|
1234
|
+
cp -r "$SOURCE_DIR/core"/* "$project_dir/.claude/agents/neocortex/core/" 2>/dev/null
|
|
1235
|
+
for folder in steps-c steps-e steps-p steps-r steps-u; do
|
|
1236
|
+
if [ -d "$SOURCE_DIR/core/steps/$folder" ]; then
|
|
1237
|
+
mkdir -p "$project_dir/.claude/agents/neocortex/$folder"
|
|
1238
|
+
cp -r "$SOURCE_DIR/core/steps/$folder"/* "$project_dir/.claude/agents/neocortex/$folder/" 2>/dev/null
|
|
1239
|
+
fi
|
|
1240
|
+
done
|
|
1241
|
+
if [ -d "$SOURCE_DIR/core/skills" ]; then
|
|
1242
|
+
mkdir -p "$project_dir/.claude/skills/neocortex"
|
|
1243
|
+
cp -r "$SOURCE_DIR/core/skills"/* "$project_dir/.claude/skills/neocortex/" 2>/dev/null
|
|
1244
|
+
fi
|
|
1245
|
+
else
|
|
1246
|
+
# Tier 3 Remote Mode: limpar IP de versoes anteriores no projeto
|
|
1247
|
+
cleanup_legacy_ip_project "$project_dir"
|
|
1248
|
+
fi
|
|
1249
|
+
target_summary="${target_summary}claude-code, "
|
|
1250
|
+
fi
|
|
1251
|
+
;;
|
|
1252
|
+
cursor)
|
|
1253
|
+
local adapter_script="$SOURCE_DIR/targets/cursor/install-cursor.sh"
|
|
1254
|
+
if [ -f "$adapter_script" ]; then
|
|
1255
|
+
. "$adapter_script"
|
|
1256
|
+
install_cursor "$SOURCE_DIR" "$project_dir"
|
|
1257
|
+
target_summary="${target_summary}cursor, "
|
|
1258
|
+
fi
|
|
1259
|
+
;;
|
|
1260
|
+
vscode)
|
|
1261
|
+
local adapter_script="$SOURCE_DIR/targets/vscode/install-vscode.sh"
|
|
1262
|
+
if [ -f "$adapter_script" ]; then
|
|
1263
|
+
. "$adapter_script"
|
|
1264
|
+
install_vscode "$SOURCE_DIR" "$project_dir"
|
|
1265
|
+
target_summary="${target_summary}vscode, "
|
|
1266
|
+
fi
|
|
1267
|
+
;;
|
|
1268
|
+
gemini-cli)
|
|
1269
|
+
local gemini_target="$SOURCE_DIR/targets/gemini-cli"
|
|
1270
|
+
if [ -d "$gemini_target" ]; then
|
|
1271
|
+
[ -f "$gemini_target/gemini.md" ] && cp "$gemini_target/gemini.md" "$project_dir/GEMINI.md"
|
|
1272
|
+
if [ -d "$gemini_target/commands" ]; then
|
|
1273
|
+
mkdir -p "$project_dir/.gemini/commands"
|
|
1274
|
+
cp "$gemini_target/commands"/*.toml "$project_dir/.gemini/commands/" 2>/dev/null
|
|
1275
|
+
fi
|
|
1276
|
+
if [ -f "$gemini_target/agent.md" ]; then
|
|
1277
|
+
mkdir -p "$project_dir/.gemini/agents"
|
|
1278
|
+
cp "$gemini_target/agent.md" "$project_dir/.gemini/agents/neocortex.md"
|
|
1279
|
+
fi
|
|
1280
|
+
[ -f "$gemini_target/settings-mcp.json" ] && cp "$gemini_target/settings-mcp.json" "$project_dir/.gemini/settings-mcp.json"
|
|
1281
|
+
target_summary="${target_summary}gemini-cli, "
|
|
1282
|
+
fi
|
|
1283
|
+
;;
|
|
1284
|
+
codex)
|
|
1285
|
+
local adapter_script="$SOURCE_DIR/targets/codex/install-codex.sh"
|
|
1286
|
+
if [ -f "$adapter_script" ]; then
|
|
1287
|
+
. "$adapter_script"
|
|
1288
|
+
install_codex "$SOURCE_DIR" "$project_dir"
|
|
1289
|
+
target_summary="${target_summary}codex, "
|
|
1290
|
+
fi
|
|
1291
|
+
;;
|
|
1292
|
+
antigravity)
|
|
1293
|
+
local adapter_script="$SOURCE_DIR/targets/antigravity/install-antigravity.sh"
|
|
1294
|
+
if [ -f "$adapter_script" ]; then
|
|
1295
|
+
. "$adapter_script"
|
|
1296
|
+
install_antigravity "$SOURCE_DIR" "$project_dir"
|
|
1297
|
+
target_summary="${target_summary}antigravity, "
|
|
1298
|
+
fi
|
|
1299
|
+
;;
|
|
1300
|
+
esac
|
|
1301
|
+
done
|
|
1302
|
+
|
|
1303
|
+
echo ""
|
|
1304
|
+
ok "Estrutura do projeto instalada ${DIM}(${target_summary%, })${NC}"
|
|
1305
|
+
echo ""
|
|
1306
|
+
info "Proximo passo: ${CYAN}@neocortex *init @docs/epics.md${NC}"
|
|
1307
|
+
fi
|
|
1308
|
+
}
|
|
1309
|
+
|
|
1310
|
+
# =============================================================================
|
|
1311
|
+
# MIGRACAO
|
|
1312
|
+
# =============================================================================
|
|
1313
|
+
|
|
1314
|
+
show_migration_info() {
|
|
1315
|
+
[ "$QUIET_MODE" = true ] && return
|
|
1316
|
+
|
|
1317
|
+
local project_sources
|
|
1318
|
+
if project_sources=$(detect_project_migration_needs); then
|
|
1319
|
+
echo ""
|
|
1320
|
+
warn "${BOLD}Migracao detectada${NC}"
|
|
1321
|
+
for src in $project_sources; do
|
|
1322
|
+
info "Arquivo antigo: $src"
|
|
1323
|
+
done
|
|
1324
|
+
info "Execute: ${CYAN}@neocortex *init @docs/epics.md${NC} para migrar"
|
|
1325
|
+
fi
|
|
1326
|
+
}
|
|
1327
|
+
|
|
1328
|
+
# =============================================================================
|
|
1329
|
+
# MAIN
|
|
1330
|
+
# =============================================================================
|
|
1331
|
+
|
|
1332
|
+
TOTAL_STEPS=3
|
|
1333
|
+
|
|
1334
|
+
main() {
|
|
1335
|
+
show_banner
|
|
1336
|
+
detect_source_dir
|
|
1337
|
+
detect_old_installation
|
|
1338
|
+
detect_legacy_artifacts
|
|
1339
|
+
cleanup_legacy_artifacts
|
|
1340
|
+
|
|
1341
|
+
# Determine targets
|
|
1342
|
+
if [ -z "$SELECTED_TARGETS" ]; then
|
|
1343
|
+
SELECTED_TARGETS="claude-code"
|
|
1344
|
+
fi
|
|
1345
|
+
|
|
1346
|
+
debug "Targets: $SELECTED_TARGETS"
|
|
1347
|
+
|
|
1348
|
+
# Validate targets
|
|
1349
|
+
local invalid_targets=""
|
|
1350
|
+
for target in $(echo "$SELECTED_TARGETS" | tr ',' ' '); do
|
|
1351
|
+
echo "$VALID_TARGETS" | grep -wq "$target" || invalid_targets="$invalid_targets $target"
|
|
1352
|
+
done
|
|
1353
|
+
|
|
1354
|
+
if [ -n "$invalid_targets" ]; then
|
|
1355
|
+
fail "Plataformas invalidas:$invalid_targets"
|
|
1356
|
+
fail "Validas: $VALID_TARGETS"
|
|
1357
|
+
exit 1
|
|
1358
|
+
fi
|
|
1359
|
+
|
|
1360
|
+
# Count targets for step total
|
|
1361
|
+
local target_count=$(echo "$SELECTED_TARGETS" | tr ',' ' ' | wc -w | tr -d ' ')
|
|
1362
|
+
if echo "$SELECTED_TARGETS" | grep -q "claude-code"; then
|
|
1363
|
+
TOTAL_STEPS=5 # core + skills + targets + mcps + tools
|
|
1364
|
+
fi
|
|
1365
|
+
|
|
1366
|
+
# Step 1: Core
|
|
1367
|
+
step 1 $TOTAL_STEPS "Instalando core"
|
|
1368
|
+
install_core
|
|
1369
|
+
local core_result=$?
|
|
1370
|
+
if [ $core_result -ne 0 ]; then
|
|
1371
|
+
fail "Falha na instalacao do core"
|
|
1372
|
+
exit 1
|
|
1373
|
+
fi
|
|
1374
|
+
|
|
1375
|
+
# Step 2: Skills
|
|
1376
|
+
step 2 $TOTAL_STEPS "Instalando skills"
|
|
1377
|
+
install_skills
|
|
1378
|
+
|
|
1379
|
+
# Step 3: Targets
|
|
1380
|
+
step 3 $TOTAL_STEPS "Instalando ${BOLD}$target_count${NC} plataforma(s)"
|
|
1381
|
+
install_targets "$SELECTED_TARGETS"
|
|
1382
|
+
|
|
1383
|
+
# Step 4-5: Claude Code extras
|
|
1384
|
+
if echo "$SELECTED_TARGETS" | grep -q "claude-code"; then
|
|
1385
|
+
load_env_file
|
|
1386
|
+
prompt_tokens
|
|
1387
|
+
|
|
1388
|
+
step 4 $TOTAL_STEPS "Configurando MCPs"
|
|
1389
|
+
install_mcps
|
|
1390
|
+
|
|
1391
|
+
step 5 $TOTAL_STEPS "Verificando ferramentas"
|
|
1392
|
+
install_coderabbit
|
|
1393
|
+
fi
|
|
1394
|
+
|
|
1395
|
+
# Result
|
|
1396
|
+
show_result $core_result
|
|
1397
|
+
local result_code=$?
|
|
1398
|
+
|
|
1399
|
+
if [ $result_code -eq 0 ]; then
|
|
1400
|
+
show_migration_info
|
|
1401
|
+
create_project_dirs
|
|
1402
|
+
echo -e " ${DIM}Desenvolvido por OrNexus Team${NC}"
|
|
1403
|
+
echo ""
|
|
1404
|
+
fi
|
|
1405
|
+
|
|
1406
|
+
exit $result_code
|
|
1407
|
+
}
|
|
1408
|
+
|
|
1409
|
+
main
|