@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.
Files changed (156) hide show
  1. package/LICENSE +56 -0
  2. package/README.md +661 -0
  3. package/install.js +453 -0
  4. package/install.ps1 +1478 -0
  5. package/install.sh +1409 -0
  6. package/package.json +93 -0
  7. package/packages/client/dist/adapters/adapter-registry.d.ts +62 -0
  8. package/packages/client/dist/adapters/adapter-registry.d.ts.map +1 -0
  9. package/packages/client/dist/adapters/adapter-registry.js +107 -0
  10. package/packages/client/dist/adapters/adapter-registry.js.map +1 -0
  11. package/packages/client/dist/adapters/antigravity-adapter.d.ts +19 -0
  12. package/packages/client/dist/adapters/antigravity-adapter.d.ts.map +1 -0
  13. package/packages/client/dist/adapters/antigravity-adapter.js +78 -0
  14. package/packages/client/dist/adapters/antigravity-adapter.js.map +1 -0
  15. package/packages/client/dist/adapters/claude-code-adapter.d.ts +20 -0
  16. package/packages/client/dist/adapters/claude-code-adapter.d.ts.map +1 -0
  17. package/packages/client/dist/adapters/claude-code-adapter.js +80 -0
  18. package/packages/client/dist/adapters/claude-code-adapter.js.map +1 -0
  19. package/packages/client/dist/adapters/codex-adapter.d.ts +20 -0
  20. package/packages/client/dist/adapters/codex-adapter.d.ts.map +1 -0
  21. package/packages/client/dist/adapters/codex-adapter.js +81 -0
  22. package/packages/client/dist/adapters/codex-adapter.js.map +1 -0
  23. package/packages/client/dist/adapters/cursor-adapter.d.ts +20 -0
  24. package/packages/client/dist/adapters/cursor-adapter.d.ts.map +1 -0
  25. package/packages/client/dist/adapters/cursor-adapter.js +116 -0
  26. package/packages/client/dist/adapters/cursor-adapter.js.map +1 -0
  27. package/packages/client/dist/adapters/gemini-adapter.d.ts +19 -0
  28. package/packages/client/dist/adapters/gemini-adapter.d.ts.map +1 -0
  29. package/packages/client/dist/adapters/gemini-adapter.js +72 -0
  30. package/packages/client/dist/adapters/gemini-adapter.js.map +1 -0
  31. package/packages/client/dist/adapters/index.d.ts +20 -0
  32. package/packages/client/dist/adapters/index.d.ts.map +1 -0
  33. package/packages/client/dist/adapters/index.js +22 -0
  34. package/packages/client/dist/adapters/index.js.map +1 -0
  35. package/packages/client/dist/adapters/platform-detector.d.ts +47 -0
  36. package/packages/client/dist/adapters/platform-detector.d.ts.map +1 -0
  37. package/packages/client/dist/adapters/platform-detector.js +107 -0
  38. package/packages/client/dist/adapters/platform-detector.js.map +1 -0
  39. package/packages/client/dist/adapters/target-adapter.d.ts +71 -0
  40. package/packages/client/dist/adapters/target-adapter.d.ts.map +1 -0
  41. package/packages/client/dist/adapters/target-adapter.js +13 -0
  42. package/packages/client/dist/adapters/target-adapter.js.map +1 -0
  43. package/packages/client/dist/adapters/vscode-adapter.d.ts +20 -0
  44. package/packages/client/dist/adapters/vscode-adapter.d.ts.map +1 -0
  45. package/packages/client/dist/adapters/vscode-adapter.js +73 -0
  46. package/packages/client/dist/adapters/vscode-adapter.js.map +1 -0
  47. package/packages/client/dist/cache/crypto-utils.d.ts +31 -0
  48. package/packages/client/dist/cache/crypto-utils.d.ts.map +1 -0
  49. package/packages/client/dist/cache/crypto-utils.js +77 -0
  50. package/packages/client/dist/cache/crypto-utils.js.map +1 -0
  51. package/packages/client/dist/cache/encrypted-cache.d.ts +31 -0
  52. package/packages/client/dist/cache/encrypted-cache.d.ts.map +1 -0
  53. package/packages/client/dist/cache/encrypted-cache.js +92 -0
  54. package/packages/client/dist/cache/encrypted-cache.js.map +1 -0
  55. package/packages/client/dist/cache/index.d.ts +14 -0
  56. package/packages/client/dist/cache/index.d.ts.map +1 -0
  57. package/packages/client/dist/cache/index.js +14 -0
  58. package/packages/client/dist/cache/index.js.map +1 -0
  59. package/packages/client/dist/cli.d.ts +15 -0
  60. package/packages/client/dist/cli.d.ts.map +1 -0
  61. package/packages/client/dist/cli.js +182 -0
  62. package/packages/client/dist/cli.js.map +1 -0
  63. package/packages/client/dist/commands/activate.d.ts +48 -0
  64. package/packages/client/dist/commands/activate.d.ts.map +1 -0
  65. package/packages/client/dist/commands/activate.js +186 -0
  66. package/packages/client/dist/commands/activate.js.map +1 -0
  67. package/packages/client/dist/commands/cache-status.d.ts +40 -0
  68. package/packages/client/dist/commands/cache-status.d.ts.map +1 -0
  69. package/packages/client/dist/commands/cache-status.js +113 -0
  70. package/packages/client/dist/commands/cache-status.js.map +1 -0
  71. package/packages/client/dist/commands/invoke.d.ts +71 -0
  72. package/packages/client/dist/commands/invoke.d.ts.map +1 -0
  73. package/packages/client/dist/commands/invoke.js +345 -0
  74. package/packages/client/dist/commands/invoke.js.map +1 -0
  75. package/packages/client/dist/config/resolver-selection.d.ts +41 -0
  76. package/packages/client/dist/config/resolver-selection.d.ts.map +1 -0
  77. package/packages/client/dist/config/resolver-selection.js +278 -0
  78. package/packages/client/dist/config/resolver-selection.js.map +1 -0
  79. package/packages/client/dist/context/context-collector.d.ts +29 -0
  80. package/packages/client/dist/context/context-collector.d.ts.map +1 -0
  81. package/packages/client/dist/context/context-collector.js +223 -0
  82. package/packages/client/dist/context/context-collector.js.map +1 -0
  83. package/packages/client/dist/context/context-sanitizer.d.ts +29 -0
  84. package/packages/client/dist/context/context-sanitizer.d.ts.map +1 -0
  85. package/packages/client/dist/context/context-sanitizer.js +146 -0
  86. package/packages/client/dist/context/context-sanitizer.js.map +1 -0
  87. package/packages/client/dist/index.d.ts +55 -0
  88. package/packages/client/dist/index.d.ts.map +1 -0
  89. package/packages/client/dist/index.js +37 -0
  90. package/packages/client/dist/index.js.map +1 -0
  91. package/packages/client/dist/license/index.d.ts +6 -0
  92. package/packages/client/dist/license/index.d.ts.map +1 -0
  93. package/packages/client/dist/license/index.js +6 -0
  94. package/packages/client/dist/license/index.js.map +1 -0
  95. package/packages/client/dist/license/license-client.d.ts +53 -0
  96. package/packages/client/dist/license/license-client.d.ts.map +1 -0
  97. package/packages/client/dist/license/license-client.js +164 -0
  98. package/packages/client/dist/license/license-client.js.map +1 -0
  99. package/packages/client/dist/machine/fingerprint.d.ts +24 -0
  100. package/packages/client/dist/machine/fingerprint.d.ts.map +1 -0
  101. package/packages/client/dist/machine/fingerprint.js +61 -0
  102. package/packages/client/dist/machine/fingerprint.js.map +1 -0
  103. package/packages/client/dist/machine/index.d.ts +6 -0
  104. package/packages/client/dist/machine/index.d.ts.map +1 -0
  105. package/packages/client/dist/machine/index.js +6 -0
  106. package/packages/client/dist/machine/index.js.map +1 -0
  107. package/packages/client/dist/resilience/circuit-breaker.d.ts +71 -0
  108. package/packages/client/dist/resilience/circuit-breaker.d.ts.map +1 -0
  109. package/packages/client/dist/resilience/circuit-breaker.js +171 -0
  110. package/packages/client/dist/resilience/circuit-breaker.js.map +1 -0
  111. package/packages/client/dist/resilience/degradation-manager.d.ts +68 -0
  112. package/packages/client/dist/resilience/degradation-manager.d.ts.map +1 -0
  113. package/packages/client/dist/resilience/degradation-manager.js +165 -0
  114. package/packages/client/dist/resilience/degradation-manager.js.map +1 -0
  115. package/packages/client/dist/resilience/freshness-indicator.d.ts +60 -0
  116. package/packages/client/dist/resilience/freshness-indicator.d.ts.map +1 -0
  117. package/packages/client/dist/resilience/freshness-indicator.js +101 -0
  118. package/packages/client/dist/resilience/freshness-indicator.js.map +1 -0
  119. package/packages/client/dist/resilience/index.d.ts +9 -0
  120. package/packages/client/dist/resilience/index.d.ts.map +1 -0
  121. package/packages/client/dist/resilience/index.js +9 -0
  122. package/packages/client/dist/resilience/index.js.map +1 -0
  123. package/packages/client/dist/resilience/recovery-detector.d.ts +60 -0
  124. package/packages/client/dist/resilience/recovery-detector.d.ts.map +1 -0
  125. package/packages/client/dist/resilience/recovery-detector.js +75 -0
  126. package/packages/client/dist/resilience/recovery-detector.js.map +1 -0
  127. package/packages/client/dist/resolvers/asset-resolver.d.ts +80 -0
  128. package/packages/client/dist/resolvers/asset-resolver.d.ts.map +1 -0
  129. package/packages/client/dist/resolvers/asset-resolver.js +14 -0
  130. package/packages/client/dist/resolvers/asset-resolver.js.map +1 -0
  131. package/packages/client/dist/resolvers/local-resolver.d.ts +27 -0
  132. package/packages/client/dist/resolvers/local-resolver.d.ts.map +1 -0
  133. package/packages/client/dist/resolvers/local-resolver.js +219 -0
  134. package/packages/client/dist/resolvers/local-resolver.js.map +1 -0
  135. package/packages/client/dist/resolvers/remote-resolver.d.ts +63 -0
  136. package/packages/client/dist/resolvers/remote-resolver.d.ts.map +1 -0
  137. package/packages/client/dist/resolvers/remote-resolver.js +207 -0
  138. package/packages/client/dist/resolvers/remote-resolver.js.map +1 -0
  139. package/packages/client/dist/telemetry/index.d.ts +6 -0
  140. package/packages/client/dist/telemetry/index.d.ts.map +1 -0
  141. package/packages/client/dist/telemetry/index.js +6 -0
  142. package/packages/client/dist/telemetry/index.js.map +1 -0
  143. package/packages/client/dist/telemetry/offline-queue.d.ts +58 -0
  144. package/packages/client/dist/telemetry/offline-queue.d.ts.map +1 -0
  145. package/packages/client/dist/telemetry/offline-queue.js +132 -0
  146. package/packages/client/dist/telemetry/offline-queue.js.map +1 -0
  147. package/packages/client/dist/types/index.d.ts +141 -0
  148. package/packages/client/dist/types/index.d.ts.map +1 -0
  149. package/packages/client/dist/types/index.js +39 -0
  150. package/packages/client/dist/types/index.js.map +1 -0
  151. package/targets-stubs/antigravity/README.md +20 -0
  152. package/targets-stubs/claude-code/README.md +20 -0
  153. package/targets-stubs/codex/README.md +20 -0
  154. package/targets-stubs/cursor/README.md +20 -0
  155. package/targets-stubs/gemini-cli/README.md +20 -0
  156. package/targets-stubs/vscode/README.md +20 -0
package/install.ps1 ADDED
@@ -0,0 +1,1478 @@
1
+ # Neocortex - Instalador Windows
2
+ # Epic & Story Development Orchestrator
3
+
4
+ param(
5
+ [switch]$Yes,
6
+ [switch]$Debug,
7
+ [switch]$SkipProject,
8
+ [switch]$CreateProject,
9
+ [switch]$Quiet,
10
+ [switch]$NoBanner,
11
+ [switch]$CleanupLegacy,
12
+ [switch]$Local,
13
+ [switch]$Help,
14
+ [string]$Targets = "",
15
+ [string]$ServerUrl = "https://api.neocortex.ornexus.com"
16
+ )
17
+
18
+ $VERSION = "3.8.0"
19
+
20
+ # =============================================================================
21
+ # CONFIGURACOES
22
+ # =============================================================================
23
+
24
+ $ErrorActionPreference = "Continue"
25
+ $script:Errors = 0
26
+ $script:MigrationDetected = $false
27
+ $script:MigrationSources = @()
28
+ $script:LegacyItems = @()
29
+ $script:LegacyWarnings = 0
30
+
31
+ $AUTO_YES = $Yes
32
+ $DEBUG_MODE = $Debug
33
+ $SKIP_PROJECT_DIRS = $SkipProject
34
+ $QUIET_MODE = $Quiet
35
+ $NO_BANNER = $NoBanner
36
+ $LOCAL_MODE = $Local
37
+ $NEOCORTEX_SERVER_URL = $ServerUrl
38
+
39
+ function Test-Interactive {
40
+ try {
41
+ if (-not [Environment]::UserInteractive) { return $false }
42
+ if ($null -eq $Host.UI -or $null -eq $Host.UI.RawUI) { return $false }
43
+ return $true
44
+ } catch { return $false }
45
+ }
46
+
47
+ if (-not (Test-Interactive)) {
48
+ $AUTO_YES = $true
49
+ }
50
+
51
+ # =============================================================================
52
+ # AJUDA
53
+ # =============================================================================
54
+
55
+ if ($Help) {
56
+ Write-Host ""
57
+ Write-Host " Neocortex Installer v$VERSION" -ForegroundColor White
58
+ Write-Host " Epic & Story Development Orchestrator" -ForegroundColor DarkGray
59
+ Write-Host ""
60
+ Write-Host " Uso: npx @ornexus/neocortex [opcoes]"
61
+ Write-Host ""
62
+ Write-Host " Opcoes:" -ForegroundColor DarkGray
63
+ Write-Host " -Yes Modo automatico (Claude Code only)" -ForegroundColor Cyan
64
+ Write-Host " -Targets <lista> Plataformas separadas por virgula" -ForegroundColor Cyan
65
+ Write-Host " -CreateProject Instalar estrutura no projeto" -ForegroundColor Cyan
66
+ Write-Host " -SkipProject Nao perguntar sobre projeto" -ForegroundColor Cyan
67
+ Write-Host " -Quiet Modo silencioso" -ForegroundColor Cyan
68
+ Write-Host " -CleanupLegacy Remover artefatos legados de ~/.claude/" -ForegroundColor Cyan
69
+ Write-Host " -Local Modo local (copia IP para desenvolvimento)" -ForegroundColor Cyan
70
+ Write-Host " -ServerUrl <url> URL do server Neocortex" -ForegroundColor Cyan
71
+ Write-Host " -Debug Modo debug" -ForegroundColor Cyan
72
+ Write-Host " -Help Mostra esta ajuda" -ForegroundColor Cyan
73
+ Write-Host ""
74
+ Write-Host " Plataformas: claude-code, cursor, vscode, gemini-cli, codex, antigravity" -ForegroundColor DarkGray
75
+ exit 0
76
+ }
77
+
78
+ # =============================================================================
79
+ # FUNCOES DE LOG
80
+ # =============================================================================
81
+
82
+ function Write-Step {
83
+ param([int]$Num, [int]$Total, [string]$Message)
84
+ Write-Host ""
85
+ Write-Host " [$Num/$Total] " -ForegroundColor Cyan -NoNewline
86
+ Write-Host $Message -ForegroundColor White
87
+ }
88
+
89
+ function Write-Ok {
90
+ param([string]$Message)
91
+ if (-not $QUIET_MODE) {
92
+ Write-Host " " -NoNewline
93
+ Write-Host "[ok]" -ForegroundColor Green -NoNewline
94
+ Write-Host " $Message"
95
+ }
96
+ }
97
+
98
+ function Write-Warn {
99
+ param([string]$Message)
100
+ Write-Host " " -NoNewline
101
+ Write-Host "[!]" -ForegroundColor Yellow -NoNewline
102
+ Write-Host " $Message"
103
+ }
104
+
105
+ function Write-Fail {
106
+ param([string]$Message)
107
+ Write-Host " " -NoNewline
108
+ Write-Host "[x]" -ForegroundColor Red -NoNewline
109
+ Write-Host " $Message"
110
+ }
111
+
112
+ function Write-Info {
113
+ param([string]$Message)
114
+ if (-not $QUIET_MODE) {
115
+ Write-Host " -> " -ForegroundColor DarkGray -NoNewline
116
+ Write-Host $Message -ForegroundColor DarkGray
117
+ }
118
+ }
119
+
120
+ function Write-Dbg {
121
+ param([string]$Message)
122
+ if ($DEBUG_MODE) {
123
+ Write-Host " [debug] $Message" -ForegroundColor DarkGray
124
+ }
125
+ }
126
+
127
+ function Read-HostWithTimeout {
128
+ param([int]$TimeoutSeconds = 10, [string]$Default = "n")
129
+ try {
130
+ if (-not (Test-Interactive)) { return $Default }
131
+ $endTime = [DateTime]::Now.AddSeconds($TimeoutSeconds)
132
+ while (-not $Host.UI.RawUI.KeyAvailable) {
133
+ if ([DateTime]::Now -ge $endTime) {
134
+ Write-Host ""
135
+ return $Default
136
+ }
137
+ Start-Sleep -Milliseconds 100
138
+ }
139
+ return Read-Host
140
+ } catch { return $Default }
141
+ }
142
+
143
+ # =============================================================================
144
+ # BANNER
145
+ # =============================================================================
146
+
147
+ function Show-Banner {
148
+ if ($QUIET_MODE) { return }
149
+ if ($NO_BANNER) { return }
150
+
151
+ $esc = [char]27
152
+ # True color blue gradient matching neocortex-cli theme (#00B4FF → #7DD3FC → #0070A8)
153
+ $lines = @(
154
+ @{ Text = " ███╗ ██╗███████╗ ██████╗ ██████╗ ██████╗ ██████╗ ████████╗███████╗██╗ ██╗"; Color = "38;2;0;180;255" },
155
+ @{ Text = " ████╗ ██║██╔════╝██╔═══██╗██╔════╝██╔═══██╗██╔══██╗╚══██╔══╝██╔════╝╚██╗██╔╝"; Color = "38;2;48;191;254" },
156
+ @{ Text = " ██╔██╗ ██║█████╗ ██║ ██║██║ ██║ ██║██████╔╝ ██║ █████╗ ╚███╔╝"; Color = "38;2;95;204;253" },
157
+ @{ Text = " ██║╚██╗██║██╔══╝ ██║ ██║██║ ██║ ██║██╔══██╗ ██║ ██╔══╝ ██╔██╗"; Color = "38;2;102;192;236" },
158
+ @{ Text = " ██║ ╚████║███████╗╚██████╔╝╚██████╗╚██████╔╝██║ ██║ ██║ ███████╗██╔╝ ██╗"; Color = "38;2;56;154;204" },
159
+ @{ Text = " ╚═╝ ╚═══╝╚══════╝ ╚═════╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚══════╝╚═╝ ╚═╝"; Color = "38;2;0;112;168" },
160
+ @{ Text = ""; Color = "" },
161
+ @{ Text = " ──────────────────────────────────────────────────────────────────────────────────"; Color = "38;5;236" },
162
+ @{ Text = " Development Orchestrator | OrNexus Team v$VERSION"; Color = "38;5;243" }
163
+ )
164
+
165
+ Write-Host ""
166
+ foreach ($line in $lines) {
167
+ if ($line.Text -eq "") { Write-Host ""; continue }
168
+ Write-Host "$esc[$($line.Color)m$($line.Text)$esc[0m"
169
+ Start-Sleep -Milliseconds 20
170
+ }
171
+ Write-Host ""
172
+ }
173
+
174
+ # =============================================================================
175
+ # FUNCOES DE COPIA (silenciosas)
176
+ # =============================================================================
177
+
178
+ function Copy-Silent {
179
+ param([string]$Source, [string]$Destination)
180
+ Write-Dbg "Copiando: $Source -> $Destination"
181
+ if (Test-Path $Source -PathType Leaf) {
182
+ try { Copy-Item -Path $Source -Destination $Destination -Force; return $true }
183
+ catch { return $false }
184
+ }
185
+ return $false
186
+ }
187
+
188
+ function Copy-DirSilent {
189
+ param([string]$Source, [string]$Destination)
190
+ Write-Dbg "Copiando dir: $Source -> $Destination"
191
+ if (Test-Path $Source -PathType Container) {
192
+ try { Copy-Item -Path $Source -Destination $Destination -Recurse -Force; return $true }
193
+ catch { return $false }
194
+ }
195
+ return $false
196
+ }
197
+
198
+ # =============================================================================
199
+ # DETECCAO DO DIRETORIO FONTE
200
+ # =============================================================================
201
+
202
+ function Get-SourceDirectory {
203
+ if ($PSScriptRoot) {
204
+ $script:SourceDir = $PSScriptRoot
205
+ } else {
206
+ $script:SourceDir = Get-Location
207
+ }
208
+ Write-Dbg "Source: $script:SourceDir"
209
+
210
+ if (-not (Test-Path "$script:SourceDir\targets\claude-code\neocortex.md") -and
211
+ -not (Test-Path "$script:SourceDir\neocortex.md")) {
212
+ $possibleDirs = @(
213
+ $script:SourceDir,
214
+ "$env:APPDATA\npm\node_modules\neocortex",
215
+ "$env:LOCALAPPDATA\npm-cache\_npx\*\node_modules\neocortex",
216
+ ".\node_modules\neocortex"
217
+ )
218
+ foreach ($dir in $possibleDirs) {
219
+ $expandedDirs = Get-Item $dir -ErrorAction SilentlyContinue
220
+ foreach ($expanded in $expandedDirs) {
221
+ if (Test-Path "$($expanded.FullName)\targets\claude-code\neocortex.md" -or
222
+ Test-Path "$($expanded.FullName)\neocortex.md") {
223
+ $script:SourceDir = $expanded.FullName
224
+ break
225
+ }
226
+ }
227
+ }
228
+ }
229
+ }
230
+
231
+ # =============================================================================
232
+ # DETECCAO DE VERSAO ANTIGA
233
+ # =============================================================================
234
+
235
+ function Test-OldInstallation {
236
+ Write-Dbg "Verificando instalacoes antigas..."
237
+ $destDir = "$env:USERPROFILE\.claude\agents\neocortex"
238
+
239
+ $versionFile = "$destDir\.version"
240
+ if (Test-Path $versionFile) {
241
+ $installedVersion = (Get-Content $versionFile -Raw).Trim()
242
+ $pkgJsonPath = Join-Path $script:SourceDir "package.json"
243
+ if (Test-Path $pkgJsonPath) {
244
+ $pkgJson = Get-Content $pkgJsonPath -Raw | ConvertFrom-Json -ErrorAction SilentlyContinue
245
+ if ($pkgJson.version) {
246
+ if ($installedVersion -eq $pkgJson.version) {
247
+ Write-Info "Reinstalando v$($pkgJson.version)"
248
+ } else {
249
+ Write-Info "Atualizando v$installedVersion -> v$($pkgJson.version)"
250
+ }
251
+ }
252
+ }
253
+ }
254
+ }
255
+
256
+ function Test-ProjectMigrationNeeds {
257
+ $sources = @()
258
+ if (Test-Path ".neocortex\orchestrator.db") { $sources += "orchestrator.db" }
259
+ @("bmad-output\sprint-status.yaml", ".neocortex\sprint-status.yaml", "docs\sprint-status.yaml") | ForEach-Object {
260
+ if (Test-Path $_) { $sources += $_ }
261
+ }
262
+ if ($sources.Count -gt 0) { return $sources }
263
+ return $null
264
+ }
265
+
266
+ # =============================================================================
267
+ # DETECCAO DE ARTEFATOS LEGADOS
268
+ # =============================================================================
269
+
270
+ function Test-LegacyArtifacts {
271
+ $warnings = 0
272
+ $script:LegacyItems = @()
273
+
274
+ Write-Dbg "Verificando artefatos legados em ~/.claude/..."
275
+
276
+ $claudeDir = "$env:USERPROFILE\.claude"
277
+
278
+ # Check 1: .git inside agents/ (leftover from contains-studio/agents repo)
279
+ if (Test-Path "$claudeDir\agents\.git" -PathType Container) {
280
+ Write-Warn "Repositorio .git detectado em ~\.claude\agents\"
281
+ Write-Info "Pode conflitar com instalacoes do Neocortex"
282
+ Write-Info "Execute com -CleanupLegacy para remover"
283
+ $script:LegacyItems += "$claudeDir\agents\.git"
284
+ $warnings++
285
+ }
286
+
287
+ # Check 2: Nested .claude\.claude\ (BMAD installation error)
288
+ if (Test-Path "$claudeDir\.claude" -PathType Container) {
289
+ Write-Warn "Diretorio aninhado detectado: ~\.claude\.claude\"
290
+ Write-Info "Possivelmente erro de instalacao anterior (BMAD)"
291
+ Write-Info "Execute com -CleanupLegacy para remover"
292
+ $script:LegacyItems += "$claudeDir\.claude"
293
+ $warnings++
294
+ }
295
+
296
+ # Check 3: Loose agents without namespace (files directly in agents\, not in subdirs)
297
+ $looseFiles = @()
298
+ if (Test-Path "$claudeDir\agents" -PathType Container) {
299
+ $looseFiles = Get-ChildItem -Path "$claudeDir\agents" -Filter "*.md" -File -ErrorAction SilentlyContinue
300
+ }
301
+ if ($looseFiles.Count -gt 0) {
302
+ Write-Info "$($looseFiles.Count) arquivo(s) .md solto(s) em ~\.claude\agents\"
303
+ foreach ($f in $looseFiles) {
304
+ Write-Dbg " Solto: $($f.Name)"
305
+ }
306
+ Write-Info "Considere organizar em namespaces (ex: agents\neocortex\)"
307
+ $warnings++
308
+ }
309
+
310
+ # Check 4: Legacy agents-ldtn\ directory
311
+ if (Test-Path "$claudeDir\agents-ldtn" -PathType Container) {
312
+ Write-Warn "Diretorio legado detectado: ~\.claude\agents-ldtn\"
313
+ Write-Info "Execute com -CleanupLegacy para remover"
314
+ $script:LegacyItems += "$claudeDir\agents-ldtn"
315
+ $warnings++
316
+ }
317
+
318
+ # Check 5: .superclaude-metadata.json
319
+ if (Test-Path "$claudeDir\.superclaude-metadata.json" -PathType Leaf) {
320
+ Write-Warn "Metadata legado detectado: ~\.claude\.superclaude-metadata.json"
321
+ Write-Info "Execute com -CleanupLegacy para remover"
322
+ $script:LegacyItems += "$claudeDir\.superclaude-metadata.json"
323
+ $warnings++
324
+ }
325
+
326
+ # Check 6: superclaude_backup_*.tar.gz in backups\
327
+ $backupCount = 0
328
+ if (Test-Path "$claudeDir\backups" -PathType Container) {
329
+ $backupCount = (Get-ChildItem -Path "$claudeDir\backups" -Filter "superclaude_backup_*.tar.gz" -File -ErrorAction SilentlyContinue).Count
330
+ }
331
+ if ($backupCount -gt 0) {
332
+ Write-Info "$backupCount backup(s) SuperClaude antigo(s) em ~\.claude\backups\"
333
+ $warnings++
334
+ }
335
+
336
+ if ($warnings -gt 0) {
337
+ Write-Warn "$warnings artefato(s) legado(s) detectado(s)"
338
+ }
339
+
340
+ $script:LegacyWarnings = $warnings
341
+ return $warnings
342
+ }
343
+
344
+ function Invoke-CleanupLegacy {
345
+ if (-not $CleanupLegacy) { return }
346
+
347
+ if ($script:LegacyWarnings -eq 0 -or $script:LegacyItems.Count -eq 0) {
348
+ Write-Info "Nenhum artefato legado encontrado para limpeza"
349
+ return
350
+ }
351
+
352
+ # Safety: refuse cleanup in -Yes mode (protect against automated deletion)
353
+ if ($AUTO_YES) {
354
+ Write-Warn "Cleanup requer confirmacao interativa (-Yes ignorado para seguranca)"
355
+ return
356
+ }
357
+
358
+ # Show what will be removed
359
+ Write-Host ""
360
+ Write-Warn "Os seguintes artefatos serao removidos:"
361
+ foreach ($item in $script:LegacyItems) {
362
+ $displayItem = $item -replace [regex]::Escape($env:USERPROFILE), "~"
363
+ if (Test-Path $item -PathType Container) {
364
+ Write-Info " - $displayItem\ (diretorio)"
365
+ } else {
366
+ Write-Info " - $displayItem (arquivo)"
367
+ }
368
+ }
369
+
370
+ Write-Host " Confirmar remocao? [s/N]: " -NoNewline -ForegroundColor White
371
+ $response = Read-HostWithTimeout -TimeoutSeconds 30 -Default "n"
372
+
373
+ if ($response -notmatch "^[sS]([iI][mM]?)?$|^[yY]([eE][sS]?)?$") {
374
+ Write-Info "Cleanup cancelado"
375
+ return
376
+ }
377
+
378
+ # Execute cleanup
379
+ $removed = 0
380
+ $failed = 0
381
+ foreach ($item in $script:LegacyItems) {
382
+ $displayItem = $item -replace [regex]::Escape($env:USERPROFILE), "~"
383
+ try {
384
+ Remove-Item -Path $item -Recurse -Force -ErrorAction Stop
385
+ Write-Ok "Removido: $displayItem"
386
+ $removed++
387
+ } catch {
388
+ Write-Fail "Falha ao remover: $displayItem"
389
+ $failed++
390
+ }
391
+ }
392
+
393
+ if ($failed -eq 0) {
394
+ Write-Ok "$removed artefato(s) removido(s) com sucesso"
395
+ } else {
396
+ Write-Warn "$removed removido(s), $failed falha(s)"
397
+ }
398
+ }
399
+
400
+ # =============================================================================
401
+ # VERIFICACAO POS-INSTALACAO
402
+ # =============================================================================
403
+
404
+ function Verify-Installation {
405
+ $fails = 0
406
+ $warns = 0
407
+ $report = @()
408
+
409
+ if ($script:SelectedTargets -notcontains "claude-code") {
410
+ return $true
411
+ }
412
+
413
+ # --- Layer 1: File existence + minimum size ---
414
+ $criticalFiles = @(
415
+ @{ Name = "neocortex.md"; MinBytes = 512; Label = "Agent principal (stub)" },
416
+ @{ Name = "neocortex.agent.yaml"; MinBytes = 128; Label = "Agent config YAML (stub)" }
417
+ )
418
+
419
+ foreach ($entry in $criticalFiles) {
420
+ $fpath = Join-Path $script:DestDir $entry.Name
421
+ $fname = $entry.Name
422
+
423
+ if (-not (Test-Path $fpath -PathType Leaf)) {
424
+ $report += @{ Status = "FAIL"; Detail = "$fname (nao encontrado)" }
425
+ $fails++
426
+ } else {
427
+ $fileInfo = Get-Item $fpath
428
+ $size = $fileInfo.Length
429
+
430
+ if ($size -lt $entry.MinBytes) {
431
+ $report += @{ Status = "FAIL"; Detail = "$fname ($size bytes - possivelmente corrompido, minimo $($entry.MinBytes))" }
432
+ $fails++
433
+ } else {
434
+ # --- Layer 2: Content marker (frontmatter) ---
435
+ $ext = [System.IO.Path]::GetExtension($fname)
436
+ if ($ext -eq ".md") {
437
+ $firstLine = (Get-Content $fpath -TotalCount 1 -ErrorAction SilentlyContinue)
438
+ if ($firstLine -ne "---") {
439
+ $report += @{ Status = "WARN"; Detail = "$fname (formato invalido - sem frontmatter)" }
440
+ $warns++
441
+ } else {
442
+ $displaySize = if ($size -ge 1024) { "$([math]::Floor($size / 1024))KB" } else { "${size}B" }
443
+ $report += @{ Status = "OK"; Detail = "$fname ($displaySize)" }
444
+ }
445
+ } else {
446
+ $displaySize = if ($size -ge 1024) { "$([math]::Floor($size / 1024))KB" } else { "${size}B" }
447
+ $report += @{ Status = "OK"; Detail = "$fname ($displaySize)" }
448
+ }
449
+ }
450
+ }
451
+ }
452
+
453
+ # --- Layer 3: Step directories ---
454
+ foreach ($dir in @("steps-c", "steps-e", "steps-p", "steps-r", "steps-u")) {
455
+ $dirPath = Join-Path $script:DestDir $dir
456
+ if (-not (Test-Path $dirPath -PathType Container)) {
457
+ $report += @{ Status = "FAIL"; Detail = "$dir/ (diretorio nao encontrado)" }
458
+ $fails++
459
+ } else {
460
+ $mdCount = (Get-ChildItem -Path $dirPath -Filter "*.md" -File -ErrorAction SilentlyContinue).Count
461
+ if ($mdCount -eq 0) {
462
+ $report += @{ Status = "WARN"; Detail = "$dir/ (vazio - nenhum arquivo .md)" }
463
+ $warns++
464
+ } else {
465
+ $report += @{ Status = "OK"; Detail = "$dir/ ($mdCount arquivos)" }
466
+ }
467
+ }
468
+ }
469
+
470
+ # --- Layer 3b: Core directory ---
471
+ $corePath = Join-Path $script:DestDir "core"
472
+ if (-not (Test-Path $corePath -PathType Container)) {
473
+ $report += @{ Status = "FAIL"; Detail = "core/ (diretorio nao encontrado)" }
474
+ $fails++
475
+ } else {
476
+ $report += @{ Status = "OK"; Detail = "core/" }
477
+ }
478
+
479
+ # --- Display report ---
480
+ if ($fails -eq 0 -and $warns -eq 0) {
481
+ if (-not $QUIET_MODE) {
482
+ Write-Ok "Instalacao verificada"
483
+ }
484
+ return $true
485
+ }
486
+
487
+ if ($QUIET_MODE -and $fails -eq 0) {
488
+ return $true # In quiet mode, skip warnings-only report
489
+ }
490
+
491
+ Write-Host ""
492
+ Write-Info "Verificacao pos-instalacao:"
493
+ foreach ($entry in $report) {
494
+ switch ($entry.Status) {
495
+ "OK" { Write-Host " " -NoNewline; Write-Host "[ok]" -ForegroundColor Green -NoNewline; Write-Host " $($entry.Detail)" }
496
+ "WARN" { Write-Host " " -NoNewline; Write-Host "[!]" -ForegroundColor Yellow -NoNewline; Write-Host " $($entry.Detail)" }
497
+ "FAIL" { Write-Host " " -NoNewline; Write-Host "[x]" -ForegroundColor Red -NoNewline; Write-Host " $($entry.Detail)" }
498
+ }
499
+ }
500
+
501
+ if ($fails -gt 0) { return $false }
502
+ return $true
503
+ }
504
+
505
+ # =============================================================================
506
+ # TIER 3: CLEANUP DE IP LEGADA E CONFIG DO THIN CLIENT
507
+ # =============================================================================
508
+
509
+ function Remove-LegacyIP {
510
+ $neocortexDir = "$env:USERPROFILE\.claude\agents\neocortex"
511
+ $skillsDir = "$env:USERPROFILE\.claude\skills\neocortex"
512
+ $cleaned = $false
513
+
514
+ # Remover core/ e seus subdiretorios
515
+ if (Test-Path "$neocortexDir\core") {
516
+ Remove-Item -Path "$neocortexDir\core" -Recurse -Force -ErrorAction SilentlyContinue
517
+ $cleaned = $true
518
+ }
519
+
520
+ # Remover step folders
521
+ foreach ($folder in @("steps-c", "steps-e", "steps-p", "steps-r", "steps-u")) {
522
+ if (Test-Path "$neocortexDir\$folder") {
523
+ Remove-Item -Path "$neocortexDir\$folder" -Recurse -Force -ErrorAction SilentlyContinue
524
+ $cleaned = $true
525
+ }
526
+ }
527
+
528
+ # Remover skills
529
+ if (Test-Path $skillsDir) {
530
+ Remove-Item -Path $skillsDir -Recurse -Force -ErrorAction SilentlyContinue
531
+ $cleaned = $true
532
+ }
533
+
534
+ # Remover arquivos desnecessarios
535
+ foreach ($file in @("package.json", "README.md")) {
536
+ if (Test-Path "$neocortexDir\$file") {
537
+ Remove-Item -Path "$neocortexDir\$file" -Force -ErrorAction SilentlyContinue
538
+ $cleaned = $true
539
+ }
540
+ }
541
+
542
+ if ($cleaned) {
543
+ Write-Info "IP proprietaria removida de versao anterior (agora servida via server remoto)"
544
+ }
545
+ }
546
+
547
+ function Set-ThinClientConfig {
548
+ $configDir = "$env:USERPROFILE\.neocortex"
549
+ $configFile = "$configDir\config.json"
550
+
551
+ New-Item -ItemType Directory -Path $configDir -Force -ErrorAction SilentlyContinue | Out-Null
552
+ New-Item -ItemType Directory -Path "$configDir\cache" -Force -ErrorAction SilentlyContinue | Out-Null
553
+
554
+ if (Test-Path $configFile) {
555
+ try {
556
+ $existingConfig = Get-Content $configFile -Raw | ConvertFrom-Json -ErrorAction SilentlyContinue
557
+ if ($existingConfig.mode -eq "active" -or $existingConfig.mode -eq "local") {
558
+ Write-Dbg "Config existente preservada (mode=$($existingConfig.mode))"
559
+ return
560
+ }
561
+ } catch { }
562
+ }
563
+
564
+ $config = @{
565
+ version = $VERSION
566
+ mode = "pending-activation"
567
+ serverUrl = $NEOCORTEX_SERVER_URL
568
+ tier = 3
569
+ cache = @{
570
+ enabled = $true
571
+ directory = "$configDir\cache"
572
+ encryption = "AES-256-GCM"
573
+ }
574
+ resilience = @{
575
+ circuitBreaker = $true
576
+ maxRetries = 3
577
+ timeoutMs = 5000
578
+ }
579
+ installedAt = (Get-Date -Format "o")
580
+ installerVersion = $VERSION
581
+ }
582
+
583
+ $config | ConvertTo-Json -Depth 5 | Out-File -FilePath $configFile -Encoding utf8
584
+ Write-Dbg "Thin client config criada: $configFile"
585
+ }
586
+
587
+ function Remove-LegacyIPProject {
588
+ param([string]$ProjectDir)
589
+
590
+ $neocortexDir = "$ProjectDir\.claude\agents\neocortex"
591
+ $skillsDir = "$ProjectDir\.claude\skills\neocortex"
592
+ $cleaned = $false
593
+
594
+ if (Test-Path "$neocortexDir\core") {
595
+ Remove-Item -Path "$neocortexDir\core" -Recurse -Force -ErrorAction SilentlyContinue
596
+ $cleaned = $true
597
+ }
598
+
599
+ foreach ($folder in @("steps-c", "steps-e", "steps-p", "steps-r", "steps-u")) {
600
+ if (Test-Path "$neocortexDir\$folder") {
601
+ Remove-Item -Path "$neocortexDir\$folder" -Recurse -Force -ErrorAction SilentlyContinue
602
+ $cleaned = $true
603
+ }
604
+ }
605
+
606
+ if (Test-Path $skillsDir) {
607
+ Remove-Item -Path $skillsDir -Recurse -Force -ErrorAction SilentlyContinue
608
+ $cleaned = $true
609
+ }
610
+
611
+ foreach ($file in @("package.json", "README.md")) {
612
+ if (Test-Path "$neocortexDir\$file") {
613
+ Remove-Item -Path "$neocortexDir\$file" -Force -ErrorAction SilentlyContinue
614
+ $cleaned = $true
615
+ }
616
+ }
617
+
618
+ if ($cleaned) {
619
+ Write-Info "IP proprietaria removida do projeto (agora servida via server remoto)"
620
+ }
621
+ }
622
+
623
+ # =============================================================================
624
+ # INSTALACAO CORE
625
+ # =============================================================================
626
+
627
+ function Install-Core {
628
+ $script:ClaudeDir = "$env:USERPROFILE\.claude"
629
+ $script:AgentsDir = "$script:ClaudeDir\agents"
630
+ $script:DestDir = "$script:AgentsDir\neocortex"
631
+
632
+ Write-Dbg "DEST=$script:DestDir"
633
+
634
+ # Create directories
635
+ if (-not (Test-Path $script:ClaudeDir)) {
636
+ try { New-Item -ItemType Directory -Path $script:ClaudeDir -Force | Out-Null }
637
+ catch { Write-Fail "Falha ao criar $script:ClaudeDir"; return $false }
638
+ }
639
+ New-Item -ItemType Directory -Path $script:AgentsDir -Force | Out-Null
640
+
641
+ # Clean previous
642
+ if (Test-Path $script:DestDir) {
643
+ Remove-Item -Path $script:DestDir -Recurse -Force -ErrorAction SilentlyContinue
644
+ }
645
+ New-Item -ItemType Directory -Path $script:DestDir -Force | Out-Null
646
+
647
+ if ($LOCAL_MODE) {
648
+ # Modo local: copiar IP completa (comportamento legado para devs)
649
+ $coreSource = Join-Path $script:SourceDir "core"
650
+ if (Test-Path $coreSource -PathType Container) {
651
+ Copy-Item -Path $coreSource -Destination "$script:DestDir\" -Recurse -Force -ErrorAction SilentlyContinue
652
+ }
653
+ Copy-Silent "$($script:SourceDir)\package.json" "$script:DestDir\" | Out-Null
654
+ Copy-Silent "$($script:SourceDir)\README.md" "$script:DestDir\" | Out-Null
655
+ } else {
656
+ # Tier 3 Remote Mode: NAO copiar IP
657
+ Remove-LegacyIP
658
+ Set-ThinClientConfig
659
+ }
660
+
661
+ # Write version file
662
+ $pkgJsonPath = Join-Path $script:SourceDir "package.json"
663
+ if (Test-Path $pkgJsonPath) {
664
+ $pkgJson = Get-Content $pkgJsonPath -Raw | ConvertFrom-Json -ErrorAction SilentlyContinue
665
+ if ($pkgJson.version) {
666
+ $pkgJson.version | Out-File -FilePath "$script:DestDir\.version" -Encoding utf8 -NoNewline
667
+ }
668
+ }
669
+
670
+ if ($LOCAL_MODE) {
671
+ Write-Ok "Core instalado (standards, templates, scripts) [modo local]"
672
+ } else {
673
+ Write-Ok "Core instalado (thin client configurado) [modo remoto]"
674
+ }
675
+ return $true
676
+ }
677
+
678
+ # =============================================================================
679
+ # INSTALACAO DE SKILLS
680
+ # =============================================================================
681
+
682
+ function Install-Skills {
683
+ $script:SkillsDir = "$script:ClaudeDir\skills"
684
+ $script:SkillsDest = "$script:SkillsDir\neocortex"
685
+ $skillsSource = "$script:SourceDir\core\skills"
686
+
687
+ # Tier 3 Remote Mode: skills vem do server, nao copiar
688
+ if (-not $LOCAL_MODE) {
689
+ Write-Ok "Skills (servidas via server remoto) [modo remoto]"
690
+ return $true
691
+ }
692
+
693
+ if (-not (Test-Path $skillsSource -PathType Container)) { return $true }
694
+
695
+ New-Item -ItemType Directory -Path $script:SkillsDir -Force | Out-Null
696
+
697
+ if (Test-Path $script:SkillsDest) {
698
+ Remove-Item -Path $script:SkillsDest -Recurse -Force -ErrorAction SilentlyContinue
699
+ }
700
+
701
+ try {
702
+ Copy-Item -Path $skillsSource -Destination $script:SkillsDest -Recurse -Force
703
+
704
+ # Count skills
705
+ $skillCount = 0
706
+ Get-ChildItem "$script:SkillsDest\step-skills\*\*.md", "$script:SkillsDest\domain-skills\*\*.md" -File -ErrorAction SilentlyContinue |
707
+ Where-Object { $_.Name -ne "_template.md" } | ForEach-Object { $skillCount++ }
708
+
709
+ Write-Ok "Skills instaladas ($skillCount skills) [modo local]"
710
+ return $true
711
+ } catch {
712
+ Write-Fail "Falha ao copiar skills"
713
+ return $false
714
+ }
715
+ }
716
+
717
+ # =============================================================================
718
+ # INSTALACAO DE AGENT (Claude Code)
719
+ # =============================================================================
720
+
721
+ function Install-Agent {
722
+ $claudeTargetDir = Join-Path $script:SourceDir "targets\claude-code"
723
+ if (-not (Test-Path $claudeTargetDir)) { $claudeTargetDir = $script:SourceDir }
724
+
725
+ # SEMPRE copiar os 3 arquivos de interface
726
+ # Tier 3: Copy only 2 stub files
727
+ Copy-Silent "$claudeTargetDir\neocortex.md" "$script:DestDir\" | Out-Null
728
+ Copy-Silent "$claudeTargetDir\neocortex.agent.yaml" "$script:DestDir\" | Out-Null
729
+ # Cleanup workflow.md from previous versions
730
+ if (Test-Path "$script:DestDir\workflow.md") {
731
+ Remove-Item "$script:DestDir\workflow.md" -Force -ErrorAction SilentlyContinue
732
+ }
733
+
734
+ if ($LOCAL_MODE) {
735
+ # Modo local: copiar IP completa (comportamento legado para devs)
736
+ Copy-Silent "$($script:SourceDir)\package.json" "$script:DestDir\" | Out-Null
737
+ Copy-Silent "$($script:SourceDir)\README.md" "$script:DestDir\" | Out-Null
738
+
739
+ $coreSource = Join-Path $script:SourceDir "core"
740
+ if (Test-Path $coreSource -PathType Container) {
741
+ Copy-Item -Path $coreSource -Destination "$script:DestDir\" -Recurse -Force -ErrorAction SilentlyContinue
742
+ }
743
+
744
+ foreach ($folder in @("steps-c", "steps-e", "steps-p", "steps-r", "steps-u")) {
745
+ $stepSrc = "$($script:SourceDir)\core\steps\$folder"
746
+ if (Test-Path $stepSrc -PathType Container) {
747
+ Copy-Item -Path $stepSrc -Destination "$script:DestDir\" -Recurse -Force -ErrorAction SilentlyContinue
748
+ }
749
+ }
750
+ }
751
+ # Tier 3 Remote Mode: apenas 3 arquivos de interface
752
+
753
+ return ($script:Errors -eq 0)
754
+ }
755
+
756
+ # =============================================================================
757
+ # CARREGAMENTO DE .ENV
758
+ # =============================================================================
759
+
760
+ function Import-EnvFile {
761
+ $envFile = $null
762
+ @(".\.env", "$script:SourceDir\.env") | ForEach-Object {
763
+ if ((Test-Path $_ -PathType Leaf) -and -not $envFile) { $envFile = $_ }
764
+ }
765
+ if (-not $envFile) { return $false }
766
+
767
+ $loaded = 0
768
+ Get-Content $envFile | ForEach-Object {
769
+ $line = $_.Trim()
770
+ if (-not $line -or $line.StartsWith("#")) { return }
771
+ if ($line -match "^([^=]+)=(.*)$") {
772
+ $key = $matches[1].Trim()
773
+ $value = $matches[2].Trim() -replace '^["'']|["'']$', ''
774
+ if ($value -and -not [Environment]::GetEnvironmentVariable($key)) {
775
+ [Environment]::SetEnvironmentVariable($key, $value, "Process")
776
+ Set-Item -Path "env:$key" -Value $value -ErrorAction SilentlyContinue
777
+ $loaded++
778
+ }
779
+ }
780
+ }
781
+ if ($loaded -gt 0) { Write-Info "$loaded variavel(eis) carregada(s) do .env" }
782
+ return $true
783
+ }
784
+
785
+ # =============================================================================
786
+ # CONFIGURACAO DE TOKENS
787
+ # =============================================================================
788
+
789
+ function Request-Tokens {
790
+ if ($QUIET_MODE -or $AUTO_YES -or $env:CONTEXT7_API_KEY) { return }
791
+
792
+ Write-Host ""
793
+ Write-Info "MCP Context7 nao configurado (opcional)"
794
+ Write-Host " Configurar agora? [s/N]: " -NoNewline -ForegroundColor White
795
+ $response = Read-HostWithTimeout -TimeoutSeconds 15 -Default "n"
796
+
797
+ if ($response -match "^[sS]([iI][mM]?)?$|^[yY]([eE][sS]?)?$") {
798
+ Write-Host ""
799
+ Write-Info "Obtenha sua API Key em: https://context7.com"
800
+ Write-Host " Cole sua CONTEXT7_API_KEY: " -NoNewline -ForegroundColor White
801
+ try {
802
+ $apiKey = Read-Host
803
+ if ($apiKey -match "^ctx7sk-") {
804
+ $env:CONTEXT7_API_KEY = $apiKey
805
+ Write-Ok "CONTEXT7_API_KEY configurada"
806
+ Write-Info "Para persistir: `$env:CONTEXT7_API_KEY = `"$apiKey`" em `$PROFILE"
807
+ } elseif ($apiKey) {
808
+ Write-Warn "Formato invalido (esperado: ctx7sk-...)"
809
+ }
810
+ } catch {}
811
+ }
812
+ }
813
+
814
+ # =============================================================================
815
+ # INSTALACAO DE MCP SERVERS
816
+ # =============================================================================
817
+
818
+ function Install-MCPs {
819
+ $claudeCmd = Get-Command claude -ErrorAction SilentlyContinue
820
+ if (-not $claudeCmd) {
821
+ Write-Info "Claude CLI nao encontrado (MCPs serao instalados depois)"
822
+ return
823
+ }
824
+
825
+ $existingMcps = ""
826
+ try { $existingMcps = & claude mcp list 2>$null } catch {}
827
+
828
+ $mcpOk = @()
829
+ $mcpSkip = @()
830
+
831
+ # Playwright
832
+ if ($existingMcps -match "playwright") {
833
+ $mcpOk += "playwright"
834
+ } else {
835
+ try {
836
+ & claude mcp add playwright npx @playwright/mcp@latest 2>$null
837
+ if ($LASTEXITCODE -eq 0) { $mcpOk += "playwright" }
838
+ } catch {}
839
+ }
840
+
841
+ # Context7
842
+ if ($existingMcps -match "context7") {
843
+ $mcpOk += "context7"
844
+ } elseif ($env:CONTEXT7_API_KEY) {
845
+ try {
846
+ & claude mcp add --transport http context7 https://mcp.context7.com/mcp --header "CONTEXT7_API_KEY: $env:CONTEXT7_API_KEY" 2>$null
847
+ if ($LASTEXITCODE -eq 0) { $mcpOk += "context7" }
848
+ } catch {}
849
+ } else {
850
+ $mcpSkip += "context7"
851
+ }
852
+
853
+ if ($mcpOk.Count -gt 0) { Write-Ok "MCPs: $($mcpOk -join ', ')" }
854
+ if ($mcpSkip.Count -gt 0) { Write-Info "MCPs pendentes: $($mcpSkip -join ', ')" }
855
+ }
856
+
857
+ # =============================================================================
858
+ # INSTALACAO DO CODERABBIT CLI
859
+ # =============================================================================
860
+
861
+ function Install-CodeRabbit {
862
+ $coderabbitCmd = Get-Command coderabbit -ErrorAction SilentlyContinue
863
+ if ($coderabbitCmd) {
864
+ Write-Ok "CodeRabbit CLI"
865
+ $script:CodeRabbitInstalled = $true
866
+ return
867
+ }
868
+
869
+ # Try curl via sh
870
+ try {
871
+ $shCmd = Get-Command sh -ErrorAction SilentlyContinue
872
+ if ($shCmd) {
873
+ $installScript = Invoke-WebRequest -Uri "https://cli.coderabbit.ai/install.sh" -UseBasicParsing -TimeoutSec 30 -ErrorAction Stop
874
+ $installScript.Content | & sh 2>$null
875
+ if ($LASTEXITCODE -eq 0) {
876
+ Write-Ok "CodeRabbit CLI (instalado)"
877
+ $script:CodeRabbitInstalled = $true
878
+ return
879
+ }
880
+ }
881
+ } catch {}
882
+
883
+ # Try npm
884
+ $npmCmd = Get-Command npm -ErrorAction SilentlyContinue
885
+ if ($npmCmd) {
886
+ try {
887
+ & npm install -g coderabbit 2>$null
888
+ if ($LASTEXITCODE -eq 0) {
889
+ Write-Ok "CodeRabbit CLI (via npm)"
890
+ $script:CodeRabbitInstalled = $true
891
+ return
892
+ }
893
+ } catch {}
894
+ }
895
+
896
+ Write-Info "CodeRabbit CLI (instale depois: curl -fsSL https://cli.coderabbit.ai/install.sh | sh)"
897
+ $script:CodeRabbitInstalled = $false
898
+ }
899
+
900
+ # =============================================================================
901
+ # MULTI-TARGET SUPPORT
902
+ # =============================================================================
903
+
904
+ $script:ValidTargets = @("claude-code", "cursor", "vscode", "gemini-cli", "codex", "antigravity")
905
+ $script:SelectedTargets = @()
906
+ $script:TargetResults = @()
907
+ $script:TargetCount = 0
908
+
909
+ function Install-Targets {
910
+ param([string[]]$TargetList)
911
+
912
+ $homeDir = $env:USERPROFILE
913
+
914
+ foreach ($target in $TargetList) {
915
+ switch ($target) {
916
+ "claude-code" {
917
+ $success = Install-Agent
918
+ if ($success) {
919
+ $script:TargetResults += "$target`:OK"
920
+ $script:TargetCount++
921
+ Write-Ok "claude-code (agent, steps, core)"
922
+ } else {
923
+ $script:TargetResults += "$target`:FAIL"
924
+ Write-Fail "claude-code"
925
+ }
926
+ }
927
+ "cursor" {
928
+ $cursorTargetDir = Join-Path $script:SourceDir "targets\cursor"
929
+ if (Test-Path $cursorTargetDir -PathType Container) {
930
+ # Clean previous
931
+ Remove-Item -Path "$homeDir\.cursor\agents\neocortex.md" -Force -ErrorAction SilentlyContinue
932
+ Remove-Item -Path "$homeDir\.cursor\mcp.json" -Force -ErrorAction SilentlyContinue
933
+ if (Test-Path "$homeDir\.cursor\skills") { Remove-Item -Path "$homeDir\.cursor\skills" -Recurse -Force -ErrorAction SilentlyContinue }
934
+
935
+ # Agent
936
+ if (Test-Path "$cursorTargetDir\agent.md") {
937
+ New-Item -ItemType Directory -Path "$homeDir\.cursor\agents" -Force | Out-Null
938
+ Copy-Item -Path "$cursorTargetDir\agent.md" -Destination "$homeDir\.cursor\agents\neocortex.md" -Force
939
+ }
940
+ # Rules
941
+ if (Test-Path "$cursorTargetDir\rules" -PathType Container) {
942
+ New-Item -ItemType Directory -Path "$homeDir\.cursor\rules" -Force | Out-Null
943
+ Copy-Item -Path "$cursorTargetDir\rules\*.mdc" -Destination "$homeDir\.cursor\rules\" -Force -ErrorAction SilentlyContinue
944
+ }
945
+ # Commands
946
+ if (Test-Path "$cursorTargetDir\commands" -PathType Container) {
947
+ New-Item -ItemType Directory -Path "$homeDir\.cursor\commands" -Force | Out-Null
948
+ Copy-Item -Path "$cursorTargetDir\commands\*.md" -Destination "$homeDir\.cursor\commands\" -Force -ErrorAction SilentlyContinue
949
+ }
950
+ # MCP config
951
+ if (Test-Path "$cursorTargetDir\mcp.json") {
952
+ Copy-Item -Path "$cursorTargetDir\mcp.json" -Destination "$homeDir\.cursor\mcp.json" -Force
953
+ }
954
+ # Skills
955
+ $skillsSource = Join-Path $script:SourceDir "core\skills"
956
+ if (Test-Path $skillsSource -PathType Container) {
957
+ New-Item -ItemType Directory -Path "$homeDir\.cursor\skills" -Force | Out-Null
958
+ Copy-Item -Path "$skillsSource\*" -Destination "$homeDir\.cursor\skills\" -Recurse -Force -ErrorAction SilentlyContinue
959
+ }
960
+
961
+ Write-Ok "cursor"
962
+ $script:TargetResults += "$target`:OK"
963
+ $script:TargetCount++
964
+ } else {
965
+ Write-Warn "cursor (adapter nao encontrado)"
966
+ $script:TargetResults += "$target`:SKIP"
967
+ }
968
+ }
969
+ "vscode" {
970
+ $vscodeTargetDir = Join-Path $script:SourceDir "targets\vscode"
971
+ if (Test-Path $vscodeTargetDir -PathType Container) {
972
+ # Clean previous
973
+ Remove-Item -Path "$homeDir\.github\agents\neocortex.md" -Force -ErrorAction SilentlyContinue
974
+ Remove-Item -Path "$homeDir\.github\copilot-instructions.md" -Force -ErrorAction SilentlyContinue
975
+ if (Test-Path "$homeDir\.github\skills") { Remove-Item -Path "$homeDir\.github\skills" -Recurse -Force -ErrorAction SilentlyContinue }
976
+
977
+ if (Test-Path "$vscodeTargetDir\agent.md") {
978
+ New-Item -ItemType Directory -Path "$homeDir\.github\agents" -Force | Out-Null
979
+ Copy-Item -Path "$vscodeTargetDir\agent.md" -Destination "$homeDir\.github\agents\neocortex.md" -Force
980
+ }
981
+ if (Test-Path "$vscodeTargetDir\instructions" -PathType Container) {
982
+ New-Item -ItemType Directory -Path "$homeDir\.github\instructions" -Force | Out-Null
983
+ Copy-Item -Path "$vscodeTargetDir\instructions\*.instructions.md" -Destination "$homeDir\.github\instructions\" -Force -ErrorAction SilentlyContinue
984
+ }
985
+ if (Test-Path "$vscodeTargetDir\prompts" -PathType Container) {
986
+ New-Item -ItemType Directory -Path "$homeDir\.github\prompts" -Force | Out-Null
987
+ Copy-Item -Path "$vscodeTargetDir\prompts\*.prompt.md" -Destination "$homeDir\.github\prompts\" -Force -ErrorAction SilentlyContinue
988
+ }
989
+ if (Test-Path "$vscodeTargetDir\mcp.json") {
990
+ New-Item -ItemType Directory -Path "$homeDir\.vscode" -Force | Out-Null
991
+ Copy-Item -Path "$vscodeTargetDir\mcp.json" -Destination "$homeDir\.vscode\mcp.json" -Force
992
+ }
993
+ if (Test-Path "$vscodeTargetDir\copilot-instructions.md") {
994
+ Copy-Item -Path "$vscodeTargetDir\copilot-instructions.md" -Destination "$homeDir\.github\copilot-instructions.md" -Force
995
+ }
996
+ $skillsSource = Join-Path $script:SourceDir "core\skills"
997
+ if (Test-Path $skillsSource -PathType Container) {
998
+ New-Item -ItemType Directory -Path "$homeDir\.github\skills" -Force | Out-Null
999
+ Copy-Item -Path "$skillsSource\*" -Destination "$homeDir\.github\skills\" -Recurse -Force -ErrorAction SilentlyContinue
1000
+ }
1001
+
1002
+ Write-Ok "vscode"
1003
+ $script:TargetResults += "$target`:OK"
1004
+ $script:TargetCount++
1005
+ } else {
1006
+ Write-Warn "vscode (adapter nao encontrado)"
1007
+ $script:TargetResults += "$target`:SKIP"
1008
+ }
1009
+ }
1010
+ "gemini-cli" {
1011
+ $geminiTargetDir = Join-Path $script:SourceDir "targets\gemini-cli"
1012
+ $geminiHome = if ($env:GEMINI_HOME) { $env:GEMINI_HOME } else { "$homeDir\.gemini" }
1013
+ if (Test-Path $geminiTargetDir -PathType Container) {
1014
+ Remove-Item -Path "$geminiHome\agents\neocortex.md" -Force -ErrorAction SilentlyContinue
1015
+ if (Test-Path "$geminiHome\skills") { Remove-Item -Path "$geminiHome\skills" -Recurse -Force -ErrorAction SilentlyContinue }
1016
+
1017
+ if (Test-Path "$geminiTargetDir\agent.md") {
1018
+ New-Item -ItemType Directory -Path "$geminiHome\agents" -Force | Out-Null
1019
+ Copy-Item -Path "$geminiTargetDir\agent.md" -Destination "$geminiHome\agents\neocortex.md" -Force
1020
+ }
1021
+ if (Test-Path "$geminiTargetDir\gemini.md") {
1022
+ Copy-Item -Path "$geminiTargetDir\gemini.md" -Destination "$homeDir\GEMINI.md" -Force
1023
+ }
1024
+ if (Test-Path "$geminiTargetDir\commands" -PathType Container) {
1025
+ New-Item -ItemType Directory -Path "$geminiHome\commands" -Force | Out-Null
1026
+ Copy-Item -Path "$geminiTargetDir\commands\*.toml" -Destination "$geminiHome\commands\" -Force -ErrorAction SilentlyContinue
1027
+ }
1028
+ if (Test-Path "$geminiTargetDir\settings-mcp.json") {
1029
+ $settingsFile = "$geminiHome\settings.json"
1030
+ if (Test-Path $settingsFile) {
1031
+ try {
1032
+ $existingSettings = Get-Content $settingsFile -Raw | ConvertFrom-Json
1033
+ $mcpFragment = Get-Content "$geminiTargetDir\settings-mcp.json" -Raw | ConvertFrom-Json
1034
+ if ($mcpFragment.mcpServers) {
1035
+ if (-not $existingSettings.mcpServers) {
1036
+ $existingSettings | Add-Member -NotePropertyName "mcpServers" -NotePropertyValue $mcpFragment.mcpServers -Force
1037
+ } else {
1038
+ $mcpFragment.mcpServers.PSObject.Properties | ForEach-Object {
1039
+ $existingSettings.mcpServers | Add-Member -NotePropertyName $_.Name -NotePropertyValue $_.Value -Force
1040
+ }
1041
+ }
1042
+ }
1043
+ $existingSettings | ConvertTo-Json -Depth 10 | Set-Content $settingsFile -Encoding utf8
1044
+ } catch {
1045
+ Copy-Item -Path "$geminiTargetDir\settings-mcp.json" -Destination "$geminiHome\settings-mcp.json" -Force
1046
+ }
1047
+ } else {
1048
+ Copy-Item -Path "$geminiTargetDir\settings-mcp.json" -Destination $settingsFile -Force
1049
+ }
1050
+ }
1051
+ $skillsSource = Join-Path $script:SourceDir "core\skills"
1052
+ if (Test-Path $skillsSource -PathType Container) {
1053
+ New-Item -ItemType Directory -Path "$geminiHome\skills" -Force | Out-Null
1054
+ Copy-Item -Path "$skillsSource\*" -Destination "$geminiHome\skills\" -Recurse -Force -ErrorAction SilentlyContinue
1055
+ }
1056
+
1057
+ Write-Ok "gemini-cli"
1058
+ $script:TargetResults += "$target`:OK"
1059
+ $script:TargetCount++
1060
+ } else {
1061
+ Write-Warn "gemini-cli (adapter nao encontrado)"
1062
+ $script:TargetResults += "$target`:SKIP"
1063
+ }
1064
+ }
1065
+ "codex" {
1066
+ $codexTargetDir = Join-Path $script:SourceDir "targets\codex"
1067
+ $codexHome = if ($env:CODEX_HOME) { $env:CODEX_HOME } else { "$homeDir\.codex" }
1068
+ if (Test-Path $codexTargetDir -PathType Container) {
1069
+ Remove-Item -Path "$codexHome\AGENTS.md" -Force -ErrorAction SilentlyContinue
1070
+ New-Item -ItemType Directory -Path $codexHome -Force | Out-Null
1071
+
1072
+ if (Test-Path "$codexTargetDir\agents.md") {
1073
+ Copy-Item -Path "$codexTargetDir\agents.md" -Destination "$codexHome\AGENTS.md" -Force
1074
+ }
1075
+ if (Test-Path "$codexTargetDir\config-mcp.toml") {
1076
+ $configFile = "$codexHome\config.toml"
1077
+ if (Test-Path $configFile) {
1078
+ $configContent = Get-Content $configFile -Raw
1079
+ $mcpContent = Get-Content "$codexTargetDir\config-mcp.toml" -Raw
1080
+ if ($configContent -match "# Neocortex MCP Servers") {
1081
+ $lines = Get-Content $configFile
1082
+ $markerIndex = ($lines | Select-String "# Neocortex MCP Servers" | Select-Object -First 1).LineNumber - 1
1083
+ $beforeSection = $lines[0..($markerIndex - 1)] -join "`n"
1084
+ "$($beforeSection.TrimEnd())`n`n# Neocortex MCP Servers`n$mcpContent" | Set-Content $configFile -Encoding utf8
1085
+ } else {
1086
+ "`n# Neocortex MCP Servers`n$mcpContent" | Add-Content $configFile -Encoding utf8
1087
+ }
1088
+ } else {
1089
+ "# Neocortex MCP Servers`n$mcpContent" | Set-Content $configFile -Encoding utf8
1090
+ }
1091
+ }
1092
+
1093
+ Write-Ok "codex"
1094
+ $script:TargetResults += "$target`:OK"
1095
+ $script:TargetCount++
1096
+ } else {
1097
+ Write-Warn "codex (adapter nao encontrado)"
1098
+ $script:TargetResults += "$target`:SKIP"
1099
+ }
1100
+ }
1101
+ "antigravity" {
1102
+ $antiTargetDir = Join-Path $script:SourceDir "targets\antigravity"
1103
+ $geminiHome = if ($env:GEMINI_HOME) { $env:GEMINI_HOME } else { "$homeDir\.gemini" }
1104
+ if (Test-Path $antiTargetDir -PathType Container) {
1105
+ if (Test-Path "$geminiHome\antigravity") { Remove-Item -Path "$geminiHome\antigravity" -Recurse -Force -ErrorAction SilentlyContinue }
1106
+
1107
+ if (Test-Path "$antiTargetDir\skill\SKILL.md") {
1108
+ New-Item -ItemType Directory -Path "$homeDir\.agent\skills\neocortex" -Force | Out-Null
1109
+ Copy-Item -Path "$antiTargetDir\skill\SKILL.md" -Destination "$homeDir\.agent\skills\neocortex\SKILL.md" -Force
1110
+ }
1111
+ if (Test-Path "$antiTargetDir\rules" -PathType Container) {
1112
+ New-Item -ItemType Directory -Path "$homeDir\.agent\rules" -Force | Out-Null
1113
+ Copy-Item -Path "$antiTargetDir\rules\*.md" -Destination "$homeDir\.agent\rules\" -Force -ErrorAction SilentlyContinue
1114
+ }
1115
+ if (Test-Path "$antiTargetDir\workflows" -PathType Container) {
1116
+ New-Item -ItemType Directory -Path "$homeDir\.agent\workflows" -Force | Out-Null
1117
+ Copy-Item -Path "$antiTargetDir\workflows\*.md" -Destination "$homeDir\.agent\workflows\" -Force -ErrorAction SilentlyContinue
1118
+ }
1119
+ if (Test-Path "$antiTargetDir\mcp-config.json") {
1120
+ New-Item -ItemType Directory -Path "$geminiHome\antigravity" -Force | Out-Null
1121
+ Copy-Item -Path "$antiTargetDir\mcp-config.json" -Destination "$geminiHome\antigravity\mcp_config.json" -Force
1122
+ }
1123
+ if (Test-Path "$antiTargetDir\gemini.md") {
1124
+ Copy-Item -Path "$antiTargetDir\gemini.md" -Destination "$homeDir\GEMINI.md" -Force
1125
+ }
1126
+ $skillsSource = Join-Path $script:SourceDir "core\skills"
1127
+ if (Test-Path $skillsSource -PathType Container) {
1128
+ $skillsDest = "$homeDir\.agent\skills\neocortex\skills"
1129
+ New-Item -ItemType Directory -Path $skillsDest -Force | Out-Null
1130
+ Copy-Item -Path "$skillsSource\*" -Destination "$skillsDest\" -Recurse -Force -ErrorAction SilentlyContinue
1131
+ }
1132
+
1133
+ Write-Ok "antigravity"
1134
+ $script:TargetResults += "$target`:OK"
1135
+ $script:TargetCount++
1136
+ } else {
1137
+ Write-Warn "antigravity (adapter nao encontrado)"
1138
+ $script:TargetResults += "$target`:SKIP"
1139
+ }
1140
+ }
1141
+ default {
1142
+ Write-Warn "'$target' nao reconhecido"
1143
+ $script:TargetResults += "$target`:SKIP"
1144
+ }
1145
+ }
1146
+ }
1147
+ }
1148
+
1149
+ # =============================================================================
1150
+ # CRIACAO DE DIRETORIOS DO PROJETO
1151
+ # =============================================================================
1152
+
1153
+ function New-ProjectDirectories {
1154
+ if ($QUIET_MODE -or $SKIP_PROJECT_DIRS) { return }
1155
+
1156
+ $shouldCreate = $false
1157
+
1158
+ if ($CreateProject -or $AUTO_YES) {
1159
+ $shouldCreate = $true
1160
+ } else {
1161
+ Write-Host " Instalar estrutura no projeto atual? [s/N]: " -NoNewline -ForegroundColor White
1162
+ $response = Read-HostWithTimeout -TimeoutSeconds 30 -Default "n"
1163
+ if ($response -match "^[sS]([iI][mM]?)?$|^[yY]([eE][sS]?)?$") { $shouldCreate = $true }
1164
+ }
1165
+
1166
+ if (-not $shouldCreate) { return }
1167
+
1168
+ $projectDir = Get-Location
1169
+
1170
+ # Clean previous
1171
+ @("$projectDir\core", "$projectDir\targets\claude-code", "$projectDir\.cursor\skills",
1172
+ "$projectDir\.github\skills", "$projectDir\.agent\skills\neocortex",
1173
+ "$projectDir\.agents\skills", "$projectDir\.claude\agents\neocortex",
1174
+ "$projectDir\.claude\skills\neocortex") | ForEach-Object {
1175
+ if (Test-Path $_) { Remove-Item -Path $_ -Recurse -Force -ErrorAction SilentlyContinue }
1176
+ }
1177
+ @("$projectDir\.cursor\agents\neocortex.md", "$projectDir\.github\agents\neocortex.md",
1178
+ "$projectDir\.github\copilot-instructions.md", "$projectDir\AGENTS.md",
1179
+ "$projectDir\GEMINI.md") | ForEach-Object {
1180
+ if (Test-Path $_) { Remove-Item -Path $_ -Force -ErrorAction SilentlyContinue }
1181
+ }
1182
+
1183
+ # Create base dirs
1184
+ @("$projectDir\.neocortex\specs", "$projectDir\.neocortex\planning",
1185
+ "$projectDir\docs\stories", "$projectDir\docs\epics", "$projectDir\docs\proposals") | ForEach-Object {
1186
+ New-Item -ItemType Directory -Path $_ -Force | Out-Null
1187
+ }
1188
+
1189
+ # State template
1190
+ $stateTemplate = Join-Path $script:SourceDir "core\data\state-template.json"
1191
+ $stateTarget = "$projectDir\.neocortex\state.json"
1192
+ if (-not (Test-Path $stateTarget) -and (Test-Path $stateTemplate)) {
1193
+ Copy-Item -Path $stateTemplate -Destination $stateTarget -Force
1194
+ }
1195
+
1196
+ # Core (ONLY in local mode)
1197
+ $coreSource = Join-Path $script:SourceDir "core"
1198
+ if ($LOCAL_MODE -and (Test-Path $coreSource -PathType Container)) {
1199
+ New-Item -ItemType Directory -Path "$projectDir\core" -Force | Out-Null
1200
+ Copy-Item -Path "$coreSource\*" -Destination "$projectDir\core\" -Recurse -Force
1201
+ }
1202
+
1203
+ # Target-specific files
1204
+ $targetSummary = @()
1205
+ foreach ($target in $script:SelectedTargets) {
1206
+ switch ($target) {
1207
+ "claude-code" {
1208
+ $claudeTargetDir = Join-Path $script:SourceDir "targets\claude-code"
1209
+ if (Test-Path $claudeTargetDir -PathType Container) {
1210
+ $agentDest = "$projectDir\.claude\agents\neocortex"
1211
+ New-Item -ItemType Directory -Path $agentDest -Force | Out-Null
1212
+
1213
+ # SEMPRE copiar os 3 arquivos de interface
1214
+ # Tier 3: Copy only 2 stub files
1215
+ Copy-Silent "$claudeTargetDir\neocortex.md" "$agentDest\" | Out-Null
1216
+ Copy-Silent "$claudeTargetDir\neocortex.agent.yaml" "$agentDest\" | Out-Null
1217
+ # Cleanup workflow.md from previous versions
1218
+ if (Test-Path "$agentDest\workflow.md") {
1219
+ Remove-Item "$agentDest\workflow.md" -Force -ErrorAction SilentlyContinue
1220
+ }
1221
+
1222
+ if ($LOCAL_MODE) {
1223
+ # Modo local: copiar IP completa (comportamento legado)
1224
+ Copy-Silent "$($script:SourceDir)\package.json" "$agentDest\" | Out-Null
1225
+ Copy-Silent "$($script:SourceDir)\README.md" "$agentDest\" | Out-Null
1226
+ New-Item -ItemType Directory -Path "$agentDest\core" -Force | Out-Null
1227
+ Copy-Item -Path "$coreSource\*" -Destination "$agentDest\core\" -Recurse -Force -ErrorAction SilentlyContinue
1228
+ foreach ($folder in @("steps-c", "steps-e", "steps-p", "steps-r", "steps-u")) {
1229
+ $stepSrc = "$($script:SourceDir)\core\steps\$folder"
1230
+ if (Test-Path $stepSrc -PathType Container) {
1231
+ New-Item -ItemType Directory -Path "$agentDest\$folder" -Force | Out-Null
1232
+ Copy-Item -Path "$stepSrc\*" -Destination "$agentDest\$folder\" -Recurse -Force -ErrorAction SilentlyContinue
1233
+ }
1234
+ }
1235
+ $skillsSource = Join-Path $script:SourceDir "core\skills"
1236
+ if (Test-Path $skillsSource -PathType Container) {
1237
+ New-Item -ItemType Directory -Path "$projectDir\.claude\skills\neocortex" -Force | Out-Null
1238
+ Copy-Item -Path "$skillsSource\*" -Destination "$projectDir\.claude\skills\neocortex\" -Recurse -Force -ErrorAction SilentlyContinue
1239
+ }
1240
+ } else {
1241
+ # Tier 3 Remote Mode: limpar IP de versoes anteriores no projeto
1242
+ Remove-LegacyIPProject -ProjectDir $projectDir
1243
+ }
1244
+ $targetSummary += "claude-code"
1245
+ }
1246
+ }
1247
+ "cursor" {
1248
+ $cursorTargetDir = Join-Path $script:SourceDir "targets\cursor"
1249
+ if (Test-Path $cursorTargetDir -PathType Container) {
1250
+ if (Test-Path "$cursorTargetDir\agent.md") {
1251
+ New-Item -ItemType Directory -Path "$projectDir\.cursor\agents" -Force | Out-Null
1252
+ Copy-Item -Path "$cursorTargetDir\agent.md" -Destination "$projectDir\.cursor\agents\neocortex.md" -Force
1253
+ }
1254
+ if (Test-Path "$cursorTargetDir\rules" -PathType Container) {
1255
+ New-Item -ItemType Directory -Path "$projectDir\.cursor\rules" -Force | Out-Null
1256
+ Copy-Item -Path "$cursorTargetDir\rules\*.mdc" -Destination "$projectDir\.cursor\rules\" -Force -ErrorAction SilentlyContinue
1257
+ }
1258
+ if (Test-Path "$cursorTargetDir\commands" -PathType Container) {
1259
+ New-Item -ItemType Directory -Path "$projectDir\.cursor\commands" -Force | Out-Null
1260
+ Copy-Item -Path "$cursorTargetDir\commands\*.md" -Destination "$projectDir\.cursor\commands\" -Force -ErrorAction SilentlyContinue
1261
+ }
1262
+ if (Test-Path "$cursorTargetDir\mcp.json") {
1263
+ Copy-Item -Path "$cursorTargetDir\mcp.json" -Destination "$projectDir\.cursor\mcp.json" -Force
1264
+ }
1265
+ $skillsSource = Join-Path $script:SourceDir "core\skills"
1266
+ if (Test-Path $skillsSource -PathType Container) {
1267
+ New-Item -ItemType Directory -Path "$projectDir\.cursor\skills" -Force | Out-Null
1268
+ Copy-Item -Path "$skillsSource\*" -Destination "$projectDir\.cursor\skills\" -Recurse -Force -ErrorAction SilentlyContinue
1269
+ }
1270
+ $targetSummary += "cursor"
1271
+ }
1272
+ }
1273
+ "vscode" {
1274
+ $vscodeTargetDir = Join-Path $script:SourceDir "targets\vscode"
1275
+ if (Test-Path $vscodeTargetDir -PathType Container) {
1276
+ if (Test-Path "$vscodeTargetDir\agent.md") {
1277
+ New-Item -ItemType Directory -Path "$projectDir\.github\agents" -Force | Out-Null
1278
+ Copy-Item -Path "$vscodeTargetDir\agent.md" -Destination "$projectDir\.github\agents\neocortex.md" -Force
1279
+ }
1280
+ if (Test-Path "$vscodeTargetDir\instructions" -PathType Container) {
1281
+ New-Item -ItemType Directory -Path "$projectDir\.github\instructions" -Force | Out-Null
1282
+ Copy-Item -Path "$vscodeTargetDir\instructions\*.instructions.md" -Destination "$projectDir\.github\instructions\" -Force -ErrorAction SilentlyContinue
1283
+ }
1284
+ if (Test-Path "$vscodeTargetDir\prompts" -PathType Container) {
1285
+ New-Item -ItemType Directory -Path "$projectDir\.github\prompts" -Force | Out-Null
1286
+ Copy-Item -Path "$vscodeTargetDir\prompts\*.prompt.md" -Destination "$projectDir\.github\prompts\" -Force -ErrorAction SilentlyContinue
1287
+ }
1288
+ if (Test-Path "$vscodeTargetDir\mcp.json") {
1289
+ New-Item -ItemType Directory -Path "$projectDir\.vscode" -Force | Out-Null
1290
+ Copy-Item -Path "$vscodeTargetDir\mcp.json" -Destination "$projectDir\.vscode\mcp.json" -Force
1291
+ }
1292
+ if (Test-Path "$vscodeTargetDir\copilot-instructions.md") {
1293
+ Copy-Item -Path "$vscodeTargetDir\copilot-instructions.md" -Destination "$projectDir\.github\copilot-instructions.md" -Force
1294
+ }
1295
+ $skillsSource = Join-Path $script:SourceDir "core\skills"
1296
+ if (Test-Path $skillsSource -PathType Container) {
1297
+ New-Item -ItemType Directory -Path "$projectDir\.github\skills" -Force | Out-Null
1298
+ Copy-Item -Path "$skillsSource\*" -Destination "$projectDir\.github\skills\" -Recurse -Force -ErrorAction SilentlyContinue
1299
+ }
1300
+ $targetSummary += "vscode"
1301
+ }
1302
+ }
1303
+ "gemini-cli" {
1304
+ $geminiTargetDir = Join-Path $script:SourceDir "targets\gemini-cli"
1305
+ if (Test-Path $geminiTargetDir -PathType Container) {
1306
+ if (Test-Path "$geminiTargetDir\gemini.md") { Copy-Item -Path "$geminiTargetDir\gemini.md" -Destination "$projectDir\GEMINI.md" -Force }
1307
+ if (Test-Path "$geminiTargetDir\commands" -PathType Container) {
1308
+ New-Item -ItemType Directory -Path "$projectDir\.gemini\commands" -Force | Out-Null
1309
+ Copy-Item -Path "$geminiTargetDir\commands\*.toml" -Destination "$projectDir\.gemini\commands\" -Force -ErrorAction SilentlyContinue
1310
+ }
1311
+ if (Test-Path "$geminiTargetDir\agent.md") {
1312
+ New-Item -ItemType Directory -Path "$projectDir\.gemini\agents" -Force | Out-Null
1313
+ Copy-Item -Path "$geminiTargetDir\agent.md" -Destination "$projectDir\.gemini\agents\neocortex.md" -Force
1314
+ }
1315
+ if (Test-Path "$geminiTargetDir\settings-mcp.json") {
1316
+ Copy-Item -Path "$geminiTargetDir\settings-mcp.json" -Destination "$projectDir\.gemini\settings-mcp.json" -Force
1317
+ }
1318
+ $targetSummary += "gemini-cli"
1319
+ }
1320
+ }
1321
+ "codex" {
1322
+ $codexTargetDir = Join-Path $script:SourceDir "targets\codex"
1323
+ if (Test-Path $codexTargetDir -PathType Container) {
1324
+ if (Test-Path "$codexTargetDir\agents.md") { Copy-Item -Path "$codexTargetDir\agents.md" -Destination "$projectDir\AGENTS.md" -Force }
1325
+ $skillsSource = Join-Path $script:SourceDir "core\skills"
1326
+ if (Test-Path $skillsSource -PathType Container) {
1327
+ New-Item -ItemType Directory -Path "$projectDir\.agents\skills" -Force | Out-Null
1328
+ Copy-Item -Path "$skillsSource\*" -Destination "$projectDir\.agents\skills\" -Recurse -Force -ErrorAction SilentlyContinue
1329
+ }
1330
+ $targetSummary += "codex"
1331
+ }
1332
+ }
1333
+ "antigravity" {
1334
+ $antiTargetDir = Join-Path $script:SourceDir "targets\antigravity"
1335
+ if (Test-Path $antiTargetDir -PathType Container) {
1336
+ if (Test-Path "$antiTargetDir\skill\SKILL.md") {
1337
+ New-Item -ItemType Directory -Path "$projectDir\.agent\skills\neocortex" -Force | Out-Null
1338
+ Copy-Item -Path "$antiTargetDir\skill\SKILL.md" -Destination "$projectDir\.agent\skills\neocortex\SKILL.md" -Force
1339
+ }
1340
+ if (Test-Path "$antiTargetDir\rules" -PathType Container) {
1341
+ New-Item -ItemType Directory -Path "$projectDir\.agent\rules" -Force | Out-Null
1342
+ Copy-Item -Path "$antiTargetDir\rules\*.md" -Destination "$projectDir\.agent\rules\" -Force -ErrorAction SilentlyContinue
1343
+ }
1344
+ if (Test-Path "$antiTargetDir\workflows" -PathType Container) {
1345
+ New-Item -ItemType Directory -Path "$projectDir\.agent\workflows" -Force | Out-Null
1346
+ Copy-Item -Path "$antiTargetDir\workflows\*.md" -Destination "$projectDir\.agent\workflows\" -Force -ErrorAction SilentlyContinue
1347
+ }
1348
+ if (Test-Path "$antiTargetDir\gemini.md") { Copy-Item -Path "$antiTargetDir\gemini.md" -Destination "$projectDir\GEMINI.md" -Force }
1349
+ $skillsSource = Join-Path $script:SourceDir "core\skills"
1350
+ if (Test-Path $skillsSource -PathType Container) {
1351
+ $skillsDest = "$projectDir\.agent\skills\neocortex\skills"
1352
+ New-Item -ItemType Directory -Path $skillsDest -Force | Out-Null
1353
+ Copy-Item -Path "$skillsSource\*" -Destination "$skillsDest\" -Recurse -Force -ErrorAction SilentlyContinue
1354
+ }
1355
+ $targetSummary += "antigravity"
1356
+ }
1357
+ }
1358
+ }
1359
+ }
1360
+
1361
+ Write-Host ""
1362
+ Write-Ok "Estrutura do projeto instalada ($($targetSummary -join ', '))"
1363
+ Write-Host ""
1364
+ Write-Info "Proximo passo: @neocortex *init @docs/epics.md"
1365
+ }
1366
+
1367
+ # =============================================================================
1368
+ # RESULTADO
1369
+ # =============================================================================
1370
+
1371
+ function Show-Result {
1372
+ param([bool]$Success)
1373
+ if ($QUIET_MODE) { return $Success }
1374
+
1375
+ Write-Host ""
1376
+ Write-Host " ----------------------------------------" -ForegroundColor DarkGray
1377
+
1378
+ if ($Success) {
1379
+ Write-Host ""
1380
+ Write-Host " Instalacao concluida!" -ForegroundColor Green
1381
+ Write-Host ""
1382
+ Write-Host " Locais:" -ForegroundColor DarkGray
1383
+ Write-Host " Agente: ~\.claude\agents\neocortex\" -ForegroundColor DarkGray
1384
+ Write-Host " Skills: ~\.claude\skills\neocortex\" -ForegroundColor DarkGray
1385
+ Write-Host ""
1386
+ Write-Host " Proximo passo:" -ForegroundColor DarkGray
1387
+ Write-Host " @neocortex *init @docs/epics.md" -ForegroundColor Cyan
1388
+ Write-Host ""
1389
+ return $true
1390
+ } else {
1391
+ Write-Host ""
1392
+ Write-Host " Instalacao com problemas" -ForegroundColor Red
1393
+ Write-Host ""
1394
+ Write-Host " Execute novamente com " -NoNewline
1395
+ Write-Host "-Debug" -ForegroundColor White -NoNewline
1396
+ Write-Host " para detalhes:"
1397
+ Write-Host " npx @ornexus/neocortex -Debug" -ForegroundColor Yellow
1398
+ Write-Host ""
1399
+ return $false
1400
+ }
1401
+ }
1402
+
1403
+ # =============================================================================
1404
+ # MAIN
1405
+ # =============================================================================
1406
+
1407
+ Show-Banner
1408
+ Get-SourceDirectory
1409
+ Test-OldInstallation
1410
+ Test-LegacyArtifacts | Out-Null
1411
+ Invoke-CleanupLegacy
1412
+
1413
+ # Determine targets
1414
+ if ($Targets) {
1415
+ $script:SelectedTargets = $Targets -split ',' | ForEach-Object { $_.Trim() } | Where-Object { $_ }
1416
+ $invalid = $script:SelectedTargets | Where-Object { $_ -notin $script:ValidTargets }
1417
+ if ($invalid) {
1418
+ Write-Fail "Plataformas invalidas: $($invalid -join ', ')"
1419
+ Write-Host " Validas: $($script:ValidTargets -join ', ')"
1420
+ exit 1
1421
+ }
1422
+ } elseif ($Yes) {
1423
+ $script:SelectedTargets = @("claude-code")
1424
+ } else {
1425
+ $script:SelectedTargets = @("claude-code")
1426
+ }
1427
+
1428
+ Write-Dbg "Targets: $($script:SelectedTargets -join ', ')"
1429
+
1430
+ $totalSteps = 3
1431
+ if ($script:SelectedTargets -contains "claude-code") { $totalSteps = 5 }
1432
+
1433
+ # Step 1: Core
1434
+ Write-Step 1 $totalSteps "Instalando core"
1435
+ $coreSuccess = Install-Core
1436
+
1437
+ if (-not $coreSuccess) {
1438
+ Write-Fail "Falha na instalacao do core"
1439
+ exit 1
1440
+ }
1441
+
1442
+ # Step 2: Skills
1443
+ Write-Step 2 $totalSteps "Instalando skills"
1444
+ Install-Skills | Out-Null
1445
+
1446
+ # Step 3: Targets
1447
+ Write-Step 3 $totalSteps "Instalando $($script:SelectedTargets.Count) plataforma(s)"
1448
+ Install-Targets -TargetList $script:SelectedTargets
1449
+
1450
+ # Step 4-5: Claude Code extras
1451
+ if ($script:SelectedTargets -contains "claude-code") {
1452
+ Import-EnvFile | Out-Null
1453
+ Request-Tokens
1454
+
1455
+ Write-Step 4 $totalSteps "Configurando MCPs"
1456
+ Install-MCPs
1457
+
1458
+ Write-Step 5 $totalSteps "Verificando ferramentas"
1459
+ Install-CodeRabbit
1460
+ }
1461
+
1462
+ $installSuccess = ($script:TargetResults | Where-Object { $_ -match ":FAIL$" }).Count -eq 0
1463
+ $verifySuccess = Verify-Installation
1464
+ $installSuccess = $installSuccess -and $verifySuccess
1465
+
1466
+ if (Show-Result $installSuccess) {
1467
+ $projectSources = Test-ProjectMigrationNeeds
1468
+ if ($projectSources) {
1469
+ Write-Warn "Migracao detectada"
1470
+ Write-Info "Execute: @neocortex *init @docs/epics.md para migrar"
1471
+ }
1472
+ New-ProjectDirectories
1473
+ Write-Host " Desenvolvido por OrNexus Team" -ForegroundColor DarkGray
1474
+ Write-Host ""
1475
+ exit 0
1476
+ } else {
1477
+ exit 1
1478
+ }