@ornexus/neocortex 3.9.22 → 3.9.23

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/install.ps1 CHANGED
@@ -15,7 +15,7 @@ param(
15
15
  [string]$ServerUrl = "https://api.neocortex.ornexus.com"
16
16
  )
17
17
 
18
- $VERSION = "3.9.22"
18
+ $VERSION = "3.9.23"
19
19
 
20
20
  # =============================================================================
21
21
  # CONFIGURACOES
@@ -388,6 +388,20 @@ function Invoke-AutoCleanupLegacy {
388
388
  # --- Categoria 7: Antigravity ---
389
389
  # Configs legadas de Antigravity sao gerenciadas pelo adapter, sem path fixo global
390
390
 
391
+ # --- Categoria 8: Plaintext cache cleanup (Epic 62 - GAP 1) ---
392
+ $cacheDir = "$env:USERPROFILE\.neocortex\cache"
393
+ if (Test-Path $cacheDir -PathType Container) {
394
+ # Remove plaintext menu-cache.json
395
+ Remove-LegacyItem "$cacheDir\menu-cache.json" "cache plaintext (menu)"
396
+
397
+ # Remove any non-.enc files in cache dir (excluding directories)
398
+ Get-ChildItem -Path $cacheDir -File -ErrorAction SilentlyContinue | Where-Object {
399
+ $_.Extension -ne ".enc"
400
+ } | ForEach-Object {
401
+ Remove-LegacyItem $_.FullName "cache plaintext"
402
+ }
403
+ }
404
+
391
405
  # --- Resultado ---
392
406
  $removed = $script:autoRemoved
393
407
  if ($removed -gt 0) {
@@ -586,6 +600,25 @@ function Set-ThinClientConfig {
586
600
  try {
587
601
  $existingConfig = Get-Content $configFile -Raw | ConvertFrom-Json -ErrorAction SilentlyContinue
588
602
  if ($existingConfig.mode -eq "active" -or $existingConfig.mode -eq "local" -or $existingConfig.mode -eq "remote") {
603
+ # --- Config schema migration (Epic 62 - GAP 4) ---
604
+ if (-not $existingConfig.configVersion) {
605
+ Write-Dbg "Migrando schema do config.json (adicionando configVersion)"
606
+ try {
607
+ # Add configVersion
608
+ $existingConfig | Add-Member -NotePropertyName "configVersion" -NotePropertyValue 1 -Force
609
+ # Remove known obsolete fields
610
+ $existingConfig.PSObject.Properties.Remove("version")
611
+ $existingConfig.PSObject.Properties.Remove("cache")
612
+ # Clean obsolete tier:3 from old base template
613
+ if ($existingConfig.tier -eq 3 -and $existingConfig.mode -eq "pending-activation") {
614
+ $existingConfig.PSObject.Properties.Remove("tier")
615
+ }
616
+ $existingConfig | ConvertTo-Json -Depth 5 | Out-File -FilePath $configFile -Encoding utf8
617
+ Write-Dbg "Config migrada para configVersion 1"
618
+ } catch {
619
+ Write-Dbg "Falha na migracao do config: $_"
620
+ }
621
+ }
589
622
  Write-Dbg "Config existente preservada (mode=$($existingConfig.mode))"
590
623
  return
591
624
  }
@@ -593,15 +626,9 @@ function Set-ThinClientConfig {
593
626
  }
594
627
 
595
628
  $config = @{
596
- version = $VERSION
629
+ configVersion = 1
597
630
  mode = "pending-activation"
598
631
  serverUrl = $NEOCORTEX_SERVER_URL
599
- tier = 3
600
- cache = @{
601
- enabled = $true
602
- directory = "$configDir\cache"
603
- encryption = "AES-256-GCM"
604
- }
605
632
  resilience = @{
606
633
  circuitBreaker = $true
607
634
  maxRetries = 3
@@ -656,13 +683,42 @@ function Install-Core {
656
683
  Set-ThinClientConfig
657
684
  }
658
685
 
659
- # Write version file
686
+ # --- Version-aware cache purge on upgrade (Epic 62 - GAP 2+3) ---
660
687
  $pkgJsonPath = Join-Path $script:SourceDir "package.json"
688
+ $pkgVersion = $null
661
689
  if (Test-Path $pkgJsonPath) {
662
690
  $pkgJson = Get-Content $pkgJsonPath -Raw | ConvertFrom-Json -ErrorAction SilentlyContinue
663
- if ($pkgJson.version) {
664
- $pkgJson.version | Out-File -FilePath "$script:DestDir\.version" -Encoding utf8 -NoNewline
691
+ $pkgVersion = $pkgJson.version
692
+ }
693
+
694
+ if ($pkgVersion) {
695
+ $oldVersion = $null
696
+ # Read existing .version from either location
697
+ $versionPaths = @("$script:DestDir\.version", "$env:USERPROFILE\.neocortex\.version")
698
+ foreach ($vp in $versionPaths) {
699
+ if (Test-Path $vp -PathType Leaf) {
700
+ $oldVersion = (Get-Content $vp -Raw -ErrorAction SilentlyContinue).Trim()
701
+ if ($oldVersion) { break }
702
+ }
703
+ }
704
+
705
+ # If version changed, purge all cache files
706
+ if ($oldVersion -and $oldVersion -ne $pkgVersion) {
707
+ $cachePurgeDir = "$env:USERPROFILE\.neocortex\cache"
708
+ if (Test-Path $cachePurgeDir -PathType Container) {
709
+ $purged = 0
710
+ Get-ChildItem -Path $cachePurgeDir -File -ErrorAction SilentlyContinue | ForEach-Object {
711
+ Remove-Item $_.FullName -Force -ErrorAction SilentlyContinue
712
+ $purged++
713
+ }
714
+ if ($purged -gt 0) {
715
+ Write-Info "Cache purgado: versao alterada de $oldVersion para $pkgVersion ($purged arquivo(s))"
716
+ }
717
+ }
665
718
  }
719
+
720
+ # Write version file
721
+ $pkgVersion | Out-File -FilePath "$script:DestDir\.version" -Encoding utf8 -NoNewline
666
722
  }
667
723
 
668
724
  if ($LOCAL_MODE) {
package/install.sh CHANGED
@@ -4,7 +4,7 @@
4
4
  # Development Orchestrator
5
5
 
6
6
  # Versao do instalador
7
- VERSION="3.9.22"
7
+ VERSION="3.9.23"
8
8
 
9
9
  # Flags
10
10
  MIGRATION_DETECTED=false
@@ -415,6 +415,22 @@ auto_cleanup_legacy() {
415
415
  # ─── Categoria 7: Antigravity ─────────────────────────────────────────
416
416
  # Configs legadas de Antigravity sao gerenciadas pelo adapter, sem path fixo global
417
417
 
418
+ # ─── Categoria 8: Plaintext cache cleanup (Epic 62 - GAP 1) ─────────
419
+ local cache_dir="$HOME/.neocortex/cache"
420
+ if [ -d "$cache_dir" ]; then
421
+ # Remove plaintext menu-cache.json
422
+ _remove_legacy "$cache_dir/menu-cache.json" "cache plaintext (menu)"
423
+
424
+ # Remove any non-.enc files in cache dir (excluding directories)
425
+ for cache_file in "$cache_dir"/*; do
426
+ [ -f "$cache_file" ] || continue
427
+ case "$cache_file" in
428
+ *.enc) continue ;; # Keep encrypted cache files
429
+ *) _remove_legacy "$cache_file" "cache plaintext" ;;
430
+ esac
431
+ done
432
+ fi
433
+
418
434
  # ─── Resultado ────────────────────────────────────────────────────────
419
435
  if [ $removed -gt 0 ]; then
420
436
  ok "$removed artefato(s) legado(s) removido(s) automaticamente"
@@ -579,6 +595,33 @@ setup_thin_client_config() {
579
595
  existing_mode=$(grep '"mode"' "$config_file" 2>/dev/null | head -1 | sed 's/.*"mode"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/')
580
596
 
581
597
  if [ "$existing_mode" = "active" ] || [ "$existing_mode" = "local" ] || [ "$existing_mode" = "remote" ]; then
598
+ # ─── Config schema migration (Epic 62 - GAP 4) ────────────────
599
+ # Check if config needs schema migration
600
+ local has_config_version
601
+ has_config_version=$(grep '"configVersion"' "$config_file" 2>/dev/null)
602
+ if [ -z "$has_config_version" ]; then
603
+ debug "Migrando schema do config.json (adicionando configVersion)"
604
+ if command -v node >/dev/null 2>&1; then
605
+ node -e "
606
+ const fs = require('fs');
607
+ const path = '$config_file';
608
+ try {
609
+ const cfg = JSON.parse(fs.readFileSync(path, 'utf-8'));
610
+ // Add configVersion
611
+ cfg.configVersion = 1;
612
+ // Remove known obsolete fields from old base template
613
+ delete cfg.version;
614
+ delete cfg.cache;
615
+ // Clean obsolete tier:3 from old base template (preserve real tier values)
616
+ if (cfg.tier === 3 && cfg.mode === 'pending-activation') {
617
+ delete cfg.tier;
618
+ }
619
+ fs.writeFileSync(path, JSON.stringify(cfg, null, 2) + '\n');
620
+ }" 2>/dev/null
621
+ chmod 600 "$config_file" 2>/dev/null
622
+ debug "Config migrada para configVersion 1"
623
+ fi
624
+ fi
582
625
  # Story 61.4 - ensure permissions are always enforced even on existing configs
583
626
  chmod 600 "$config_file" 2>/dev/null
584
627
  debug "Config existente preservada (mode=$existing_mode)"
@@ -589,15 +632,9 @@ setup_thin_client_config() {
589
632
  # Criar config base para thin client
590
633
  cat > "$config_file" << EOFCONFIG
591
634
  {
592
- "version": "${VERSION}",
635
+ "configVersion": 1,
593
636
  "mode": "pending-activation",
594
637
  "serverUrl": "${NEOCORTEX_SERVER_URL}",
595
- "tier": 3,
596
- "cache": {
597
- "enabled": true,
598
- "directory": "${config_dir}/cache",
599
- "encryption": "AES-256-GCM"
600
- },
601
638
  "resilience": {
602
639
  "circuitBreaker": true,
603
640
  "maxRetries": 3,
@@ -646,12 +683,45 @@ install_core() {
646
683
  # Thin-client ONLY: zero IP on client, all content from server
647
684
  setup_thin_client_config
648
685
 
649
- # Write version file
686
+ # ─── Version-aware cache purge on upgrade (Epic 62 - GAP 2+3) ───────
650
687
  local pkg_version=""
651
688
  if [ -f "$SOURCE_DIR/package.json" ]; then
652
689
  pkg_version=$(grep '"version"' "$SOURCE_DIR/package.json" 2>/dev/null | head -1 | sed 's/.*"version"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/')
653
690
  fi
654
- [ -n "$pkg_version" ] && echo "$pkg_version" > "$DEST_DIR/.version"
691
+
692
+ if [ -n "$pkg_version" ]; then
693
+ local old_version=""
694
+ # Read existing .version from either location
695
+ if [ -f "$DEST_DIR/.version" ]; then
696
+ old_version=$(cat "$DEST_DIR/.version" 2>/dev/null | tr -d '[:space:]')
697
+ elif [ -f "$HOME/.neocortex/.version" ]; then
698
+ old_version=$(cat "$HOME/.neocortex/.version" 2>/dev/null | tr -d '[:space:]')
699
+ fi
700
+
701
+ # If version changed, purge all cache files
702
+ if [ -n "$old_version" ] && [ "$old_version" != "$pkg_version" ]; then
703
+ local cache_dir="$HOME/.neocortex/cache"
704
+ if [ -d "$cache_dir" ]; then
705
+ local purged=0
706
+ # Remove all .enc files
707
+ for enc_file in "$cache_dir"/*.enc; do
708
+ [ -f "$enc_file" ] || continue
709
+ rm -f "$enc_file" 2>/dev/null && purged=$((purged + 1))
710
+ done
711
+ # Remove menu-cache.json (redundancy with 62.1)
712
+ [ -f "$cache_dir/menu-cache.json" ] && rm -f "$cache_dir/menu-cache.json" 2>/dev/null && purged=$((purged + 1))
713
+ # Remove any other non-directory files
714
+ for cache_file in "$cache_dir"/*; do
715
+ [ -f "$cache_file" ] || continue
716
+ rm -f "$cache_file" 2>/dev/null && purged=$((purged + 1))
717
+ done
718
+ [ $purged -gt 0 ] && info "Cache purgado: versao alterada de $old_version para $pkg_version ($purged arquivo(s))"
719
+ fi
720
+ fi
721
+
722
+ # Write version file
723
+ echo "$pkg_version" > "$DEST_DIR/.version"
724
+ fi
655
725
 
656
726
  if [ $errors -eq 0 ]; then
657
727
  ok "Core instalado ${DIM}(thin client configurado) [modo remoto]${NC}"
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@ornexus/neocortex",
3
- "version": "3.9.22",
4
- "description": "Neocortex v3.9.22 - Orquestrador de Desenvolvimento de Epics & Stories para Claude Code",
3
+ "version": "3.9.23",
4
+ "description": "Neocortex v3.9.23 - Orquestrador de Desenvolvimento de Epics & Stories para Claude Code",
5
5
  "keywords": [
6
6
  "claude",
7
7
  "claude-code",
@@ -52,6 +52,7 @@
52
52
  "install.js",
53
53
  "install.sh",
54
54
  "install.ps1",
55
+ "postinstall.js",
55
56
  "packages/client/dist/",
56
57
  "!packages/client/dist/**/*.js.map",
57
58
  "!packages/client/dist/**/*.d.ts.map",
@@ -62,7 +63,7 @@
62
63
  "build:clean": "rm -rf packages/shared/dist packages/client/dist && npm run build",
63
64
  "build:client": "npm run build -w packages/client",
64
65
  "build:shared": "npm run build -w packages/shared",
65
- "postinstall": "node -e \"console.log('\\nNeocortex instalado!\\n\\nUso:\\n @neocortex @docs/stories/1.1.story.md\\n @neocortex @epic-1\\n @neocortex *status\\n')\"",
66
+ "postinstall": "node postinstall.js",
66
67
  "sync": "node sync-version.js",
67
68
  "validate": "bash scripts/validate-pre-publish.sh",
68
69
  "test:e2e": "bash scripts/e2e-smoke-test.sh",
@@ -39,6 +39,26 @@ const STUB_TARGETS = [
39
39
  sourceDir: 'gemini-cli',
40
40
  files: ['agent.md'],
41
41
  },
42
+ {
43
+ destDir: join(homedir(), '.cursor', 'agents'),
44
+ sourceDir: 'cursor',
45
+ files: ['agent.md'],
46
+ },
47
+ {
48
+ destDir: join(homedir(), '.codex'),
49
+ sourceDir: 'codex',
50
+ files: ['agents.md'],
51
+ },
52
+ {
53
+ destDir: join(homedir(), '.vscode'),
54
+ sourceDir: 'vscode',
55
+ files: ['agent.md'],
56
+ },
57
+ {
58
+ destDir: join(homedir(), '.agent', 'skills', 'neocortex'),
59
+ sourceDir: 'antigravity',
60
+ files: ['skill/SKILL.md'],
61
+ },
42
62
  ];
43
63
  // -- Package Root Resolution --------------------------------------------------
44
64
  /**
@@ -127,7 +147,8 @@ export function refreshStubs(cliVersion) {
127
147
  const src = join(sourceDir, file);
128
148
  const dest = join(target.destDir, file);
129
149
  if (existsSync(src)) {
130
- mkdirSync(target.destDir, { recursive: true });
150
+ // Ensure parent directory exists (handles nested paths like skill/SKILL.md)
151
+ mkdirSync(dirname(dest), { recursive: true });
131
152
  copyFileSync(src, dest);
132
153
  copiedAny = true;
133
154
  }
package/postinstall.js ADDED
@@ -0,0 +1,102 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Neocortex - Postinstall Hook
5
+ *
6
+ * For global installs: auto-runs the installer in quiet/auto mode.
7
+ * For local installs: prints usage message.
8
+ *
9
+ * NEVER fails npm install -- always exits 0.
10
+ *
11
+ * Epic 62 - GAP 6
12
+ */
13
+
14
+ const { spawn } = require('child_process');
15
+ const path = require('path');
16
+ const os = require('os');
17
+ const fs = require('fs');
18
+
19
+ function isGlobalInstall() {
20
+ // npm sets npm_config_global=true for global installs
21
+ if (process.env.npm_config_global === 'true') return true;
22
+ // Fallback: check if our location is in a global prefix
23
+ try {
24
+ const globalPrefix = process.env.npm_config_prefix || '';
25
+ if (globalPrefix && __dirname.startsWith(globalPrefix)) return true;
26
+ } catch { /* ignore */ }
27
+ return false;
28
+ }
29
+
30
+ function showUsageMessage() {
31
+ console.log('\nNeocortex instalado!\n');
32
+ console.log('Uso:');
33
+ console.log(' @neocortex @docs/stories/1.1.story.md');
34
+ console.log(' @neocortex @epic-1');
35
+ console.log(' @neocortex *status\n');
36
+ }
37
+
38
+ function runInstaller() {
39
+ const platform = os.platform();
40
+
41
+ if (platform === 'win32') {
42
+ // Windows: run install.ps1
43
+ const scriptPath = path.join(__dirname, 'install.ps1');
44
+ if (!fs.existsSync(scriptPath)) {
45
+ showUsageMessage();
46
+ return;
47
+ }
48
+
49
+ const shells = ['pwsh', 'powershell'];
50
+ function tryShell(index) {
51
+ if (index >= shells.length) {
52
+ showUsageMessage();
53
+ return;
54
+ }
55
+ const child = spawn(shells[index], [
56
+ '-NoProfile', '-ExecutionPolicy', 'Bypass', '-File', scriptPath,
57
+ '-Yes', '-Quiet', '-SkipProject'
58
+ ], { stdio: 'inherit', shell: false });
59
+
60
+ child.on('error', () => tryShell(index + 1));
61
+ child.on('exit', () => { /* always succeed */ });
62
+ }
63
+ tryShell(0);
64
+ } else {
65
+ // Unix: run install.sh
66
+ const scriptPath = path.join(__dirname, 'install.sh');
67
+ if (!fs.existsSync(scriptPath)) {
68
+ showUsageMessage();
69
+ return;
70
+ }
71
+
72
+ try { fs.chmodSync(scriptPath, '755'); } catch { /* ignore */ }
73
+
74
+ const child = spawn('bash', [
75
+ scriptPath, '--yes', '--quiet', '--skip-project'
76
+ ], { stdio: 'inherit', shell: false });
77
+
78
+ child.on('error', () => {
79
+ // Fallback to sh
80
+ const shChild = spawn('sh', [
81
+ scriptPath, '--yes', '--quiet', '--skip-project'
82
+ ], { stdio: 'inherit', shell: false });
83
+ shChild.on('error', () => showUsageMessage());
84
+ shChild.on('exit', () => { /* always succeed */ });
85
+ });
86
+ child.on('exit', () => { /* always succeed */ });
87
+ }
88
+ }
89
+
90
+ try {
91
+ if (isGlobalInstall()) {
92
+ runInstaller();
93
+ } else {
94
+ showUsageMessage();
95
+ }
96
+ } catch {
97
+ // NEVER fail npm install
98
+ showUsageMessage();
99
+ }
100
+
101
+ // Always exit 0
102
+ process.on('exit', () => { process.exitCode = 0; });
@@ -1,4 +1,4 @@
1
- # 🧠 Neocortex v3.9.22 (Free) | OrNexus Team
1
+ # 🧠 Neocortex v3.9.23 (Free) | OrNexus Team
2
2
 
3
3
  This project uses Neocortex, a Development Orchestrator (Free).
4
4
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: neocortex
3
- description: "🧠 Neocortex v3.9.22 (Free) | OrNexus Team"
3
+ description: "🧠 Neocortex v3.9.23 (Free) | OrNexus Team"
4
4
  ---
5
5
 
6
6
  # Neocortex - Thin Client Interface
@@ -4,7 +4,7 @@ agent:
4
4
  name: 'Neocortex'
5
5
  title: 'Development Orchestrator (Free)'
6
6
  icon: '>'
7
- version: '3.9.22'
7
+ version: '3.9.23'
8
8
  architecture: 'thin-client'
9
9
  module: stand-alone
10
10
  hasSidecar: false
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: neocortex
3
- description: "🧠 Neocortex v3.9.22 (Free) | OrNexus Team"
3
+ description: "🧠 Neocortex v3.9.23 (Free) | OrNexus Team"
4
4
  model: opus
5
5
  color: blue
6
6
  tools:
@@ -56,7 +56,7 @@ SEMPRE que este agente for invocado, imprima o banner abaixo como PRIMEIRO outpu
56
56
  ┌────────────────────────────────────────────────────────────┐
57
57
  │ │
58
58
  │ ####### N E O C O R T E X │
59
- │ ### ######## v3.9.22
59
+ │ ### ######## v3.9.23
60
60
  │ ######### ##### │
61
61
  │ ## ############## Development Orchestrator │
62
62
  │ ## ### ###### ## OrNexus Team (Free) │
@@ -1,4 +1,4 @@
1
- # 🧠 Neocortex v3.9.22 (Free) | OrNexus Team
1
+ # 🧠 Neocortex v3.9.23 (Free) | OrNexus Team
2
2
 
3
3
  You are a Development Orchestrator (Free). All orchestration logic is delivered by the remote Neocortex server.
4
4
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: neocortex
3
- description: "🧠 Neocortex v3.9.22 (Free) | OrNexus Team"
3
+ description: "🧠 Neocortex v3.9.23 (Free) | OrNexus Team"
4
4
  model: fast
5
5
  readonly: false
6
6
  is_background: false
@@ -18,7 +18,7 @@ SEMPRE que este agente for invocado, imprima o banner abaixo como PRIMEIRO outpu
18
18
  ┌────────────────────────────────────────────────────────────┐
19
19
  │ │
20
20
  │ ####### N E O C O R T E X │
21
- │ ### ######## v3.9.22
21
+ │ ### ######## v3.9.23
22
22
  │ ######### ##### │
23
23
  │ ## ############## Development Orchestrator │
24
24
  │ ## ### ###### ## OrNexus Team (Free) │
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: neocortex
3
- description: "🧠 Neocortex v3.9.22 (Free) | OrNexus Team"
3
+ description: "🧠 Neocortex v3.9.23 (Free) | OrNexus Team"
4
4
  kind: local
5
5
  tools:
6
6
  - read_file
@@ -25,7 +25,7 @@ SEMPRE que este agente for invocado, imprima o banner abaixo como PRIMEIRO outpu
25
25
  ┌────────────────────────────────────────────────────────────┐
26
26
  │ │
27
27
  │ ####### N E O C O R T E X │
28
- │ ### ######## v3.9.22
28
+ │ ### ######## v3.9.23
29
29
  │ ######### ##### │
30
30
  │ ## ############## Development Orchestrator │
31
31
  │ ## ### ###### ## OrNexus Team (Free) │
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: "neocortex"
3
- description: "🧠 Neocortex v3.9.22 (Free) | OrNexus Team"
3
+ description: "🧠 Neocortex v3.9.23 (Free) | OrNexus Team"
4
4
  tools:
5
5
  - readFile
6
6
  - editFiles
@@ -26,7 +26,7 @@ SEMPRE que este agente for invocado, imprima o banner abaixo como PRIMEIRO outpu
26
26
  ┌────────────────────────────────────────────────────────────┐
27
27
  │ │
28
28
  │ ####### N E O C O R T E X │
29
- │ ### ######## v3.9.22
29
+ │ ### ######## v3.9.23
30
30
  │ ######### ##### │
31
31
  │ ## ############## Development Orchestrator │
32
32
  │ ## ### ###### ## OrNexus Team (Free) │