@ornexus/neocortex 4.0.1 → 4.0.2

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 (62) hide show
  1. package/install.ps1 +92 -33
  2. package/install.sh +15 -1
  3. package/package.json +3 -3
  4. package/packages/client/dist/adapters/adapter-registry.js +1 -106
  5. package/packages/client/dist/adapters/antigravity-adapter.js +2 -77
  6. package/packages/client/dist/adapters/claude-code-adapter.js +3 -79
  7. package/packages/client/dist/adapters/codex-adapter.js +2 -80
  8. package/packages/client/dist/adapters/cursor-adapter.js +4 -115
  9. package/packages/client/dist/adapters/gemini-adapter.js +2 -71
  10. package/packages/client/dist/adapters/index.js +1 -21
  11. package/packages/client/dist/adapters/platform-detector.js +1 -106
  12. package/packages/client/dist/adapters/target-adapter.js +0 -12
  13. package/packages/client/dist/adapters/vscode-adapter.js +2 -72
  14. package/packages/client/dist/agent/refresh-stubs.js +2 -234
  15. package/packages/client/dist/agent/update-agent-yaml.js +1 -102
  16. package/packages/client/dist/agent/update-description.js +1 -251
  17. package/packages/client/dist/cache/crypto-utils.js +1 -76
  18. package/packages/client/dist/cache/encrypted-cache.js +1 -94
  19. package/packages/client/dist/cache/in-memory-asset-cache.js +1 -70
  20. package/packages/client/dist/cache/index.js +1 -13
  21. package/packages/client/dist/cli.js +2 -163
  22. package/packages/client/dist/commands/activate.js +8 -390
  23. package/packages/client/dist/commands/cache-status.js +2 -112
  24. package/packages/client/dist/commands/invoke.js +28 -490
  25. package/packages/client/dist/config/resolver-selection.js +1 -278
  26. package/packages/client/dist/config/secure-config.js +12 -269
  27. package/packages/client/dist/constants.js +1 -25
  28. package/packages/client/dist/context/context-collector.js +2 -222
  29. package/packages/client/dist/context/context-sanitizer.js +1 -145
  30. package/packages/client/dist/index.js +1 -38
  31. package/packages/client/dist/license/index.js +1 -5
  32. package/packages/client/dist/license/license-client.js +1 -257
  33. package/packages/client/dist/machine/fingerprint.js +2 -160
  34. package/packages/client/dist/machine/index.js +1 -5
  35. package/packages/client/dist/resilience/circuit-breaker.js +1 -170
  36. package/packages/client/dist/resilience/degradation-manager.js +1 -164
  37. package/packages/client/dist/resilience/freshness-indicator.js +1 -100
  38. package/packages/client/dist/resilience/index.js +1 -8
  39. package/packages/client/dist/resilience/recovery-detector.js +1 -74
  40. package/packages/client/dist/resolvers/asset-resolver.js +0 -13
  41. package/packages/client/dist/resolvers/local-resolver.js +8 -218
  42. package/packages/client/dist/resolvers/remote-resolver.js +1 -282
  43. package/packages/client/dist/telemetry/index.js +1 -5
  44. package/packages/client/dist/telemetry/offline-queue.js +1 -131
  45. package/packages/client/dist/tier/index.js +1 -5
  46. package/packages/client/dist/tier/tier-aware-client.js +1 -260
  47. package/packages/client/dist/types/index.js +1 -38
  48. package/targets-stubs/antigravity/gemini.md +1 -1
  49. package/targets-stubs/antigravity/install-antigravity.sh +49 -3
  50. package/targets-stubs/antigravity/skill/SKILL.md +23 -4
  51. package/targets-stubs/claude-code/neocortex.agent.yaml +19 -1
  52. package/targets-stubs/claude-code/neocortex.md +64 -29
  53. package/targets-stubs/codex/agents.md +20 -3
  54. package/targets-stubs/codex/config-mcp.toml +5 -0
  55. package/targets-stubs/cursor/agent.md +23 -5
  56. package/targets-stubs/cursor/install-cursor.sh +51 -3
  57. package/targets-stubs/cursor/mcp.json +7 -0
  58. package/targets-stubs/gemini-cli/agent.md +37 -6
  59. package/targets-stubs/gemini-cli/install-gemini.sh +50 -17
  60. package/targets-stubs/vscode/agent.md +47 -10
  61. package/targets-stubs/vscode/install-vscode.sh +50 -3
  62. package/targets-stubs/vscode/mcp.json +8 -0
package/install.ps1 CHANGED
@@ -16,7 +16,7 @@ param(
16
16
  [string]$ServerUrl = "https://api.neocortex.sh"
17
17
  )
18
18
 
19
- $VERSION = "4.0.1"
19
+ $VERSION = "4.0.2"
20
20
 
21
21
  # =============================================================================
22
22
  # CONFIGURACOES
@@ -166,6 +166,69 @@ function Set-DirAcl {
166
166
  } catch { }
167
167
  }
168
168
 
169
+ # =============================================================================
170
+ # MCP JSON CONFIG MERGE HELPER (additive, preserves user-defined servers)
171
+ # Fail-open: on error, leaves existing file untouched.
172
+ # $RootKey: top-level key containing the servers map.
173
+ # - "mcpServers" for Cursor and Gemini CLI settings
174
+ # - "servers" for VS Code
175
+ # - "" for Antigravity (flat JSON: keys are server names)
176
+ # =============================================================================
177
+
178
+ function Merge-JsonMcpConfig {
179
+ param(
180
+ [string]$StubFile,
181
+ [string]$DestFile,
182
+ [string]$RootKey = "mcpServers"
183
+ )
184
+
185
+ if (-not (Test-Path $StubFile)) { return }
186
+
187
+ if (-not (Test-Path $DestFile)) {
188
+ $destDir = Split-Path -Parent $DestFile
189
+ if ($destDir -and -not (Test-Path $destDir)) {
190
+ New-Item -ItemType Directory -Path $destDir -Force -ErrorAction SilentlyContinue | Out-Null
191
+ }
192
+ try {
193
+ Copy-Item -Path $StubFile -Destination $DestFile -Force -ErrorAction Stop
194
+ } catch { }
195
+ return
196
+ }
197
+
198
+ try {
199
+ $existing = Get-Content $DestFile -Raw -ErrorAction Stop | ConvertFrom-Json
200
+ $stub = Get-Content $StubFile -Raw -ErrorAction Stop | ConvertFrom-Json
201
+
202
+ if ($RootKey -eq "") {
203
+ # Flat JSON: iterate over stub top-level properties
204
+ foreach ($prop in $stub.PSObject.Properties) {
205
+ if ($existing.PSObject.Properties.Name -contains $prop.Name) {
206
+ $existing.$($prop.Name) = $prop.Value
207
+ } else {
208
+ $existing | Add-Member -NotePropertyName $prop.Name -NotePropertyValue $prop.Value -Force
209
+ }
210
+ }
211
+ } else {
212
+ if (-not $stub.$RootKey) { return }
213
+ if (-not $existing.$RootKey) {
214
+ $existing | Add-Member -NotePropertyName $RootKey -NotePropertyValue $stub.$RootKey -Force
215
+ } else {
216
+ foreach ($prop in $stub.$RootKey.PSObject.Properties) {
217
+ if ($existing.$RootKey.PSObject.Properties.Name -contains $prop.Name) {
218
+ $existing.$RootKey.$($prop.Name) = $prop.Value
219
+ } else {
220
+ $existing.$RootKey | Add-Member -NotePropertyName $prop.Name -NotePropertyValue $prop.Value -Force
221
+ }
222
+ }
223
+ }
224
+ }
225
+
226
+ Write-Utf8NoBom -Path $DestFile -Content ($existing | ConvertTo-Json -Depth 20)
227
+ } catch {
228
+ # Fail-open: leave destination untouched
229
+ }
230
+ }
231
+
169
232
  function Read-HostWithTimeout {
170
233
  param([int]$TimeoutSeconds = 10, [string]$Default = "n")
171
234
  try {
@@ -1116,6 +1179,19 @@ function Install-MCPs {
1116
1179
  $mcpSkip += "context7"
1117
1180
  }
1118
1181
 
1182
+ # browser_use: optional (requires BROWSER_USE_API_KEY).
1183
+ # Get your API key at https://cloud.browser-use.com/billing
1184
+ if ($existingMcps -match "browser_use") {
1185
+ $mcpOk += "browser_use"
1186
+ } elseif ($env:BROWSER_USE_API_KEY) {
1187
+ try {
1188
+ & claude mcp add browser_use -e "BROWSER_USE_API_KEY=$env:BROWSER_USE_API_KEY" -- npx -y browser-use-mcp 2>$null
1189
+ if ($LASTEXITCODE -eq 0) { $mcpOk += "browser_use" }
1190
+ } catch {}
1191
+ } else {
1192
+ $mcpSkip += "browser_use"
1193
+ }
1194
+
1119
1195
  if ($mcpOk.Count -gt 0) { Write-Ok "MCPs: $($mcpOk -join ', ')" }
1120
1196
  if ($mcpSkip.Count -gt 0) { Write-Info "MCPs pendentes: $($mcpSkip -join ', ')" }
1121
1197
  }
@@ -1193,9 +1269,8 @@ function Install-Targets {
1193
1269
  "cursor" {
1194
1270
  $cursorTargetDir = Join-Path $script:SourceDir "targets\cursor"
1195
1271
  if (Test-Path $cursorTargetDir -PathType Container) {
1196
- # Clean previous
1272
+ # Clean previous (NOTE: mcp.json is NOT deleted -- it is merged additively below)
1197
1273
  Remove-Item -Path "$homeDir\.cursor\agents\neocortex.md" -Force -ErrorAction SilentlyContinue
1198
- Remove-Item -Path "$homeDir\.cursor\mcp.json" -Force -ErrorAction SilentlyContinue
1199
1274
  if (Test-Path "$homeDir\.cursor\skills") { Remove-Item -Path "$homeDir\.cursor\skills" -Recurse -Force -ErrorAction SilentlyContinue }
1200
1275
 
1201
1276
  # Agent
@@ -1213,9 +1288,9 @@ function Install-Targets {
1213
1288
  New-Item -ItemType Directory -Path "$homeDir\.cursor\commands" -Force | Out-Null
1214
1289
  Copy-Item -Path "$cursorTargetDir\commands\*.md" -Destination "$homeDir\.cursor\commands\" -Force -ErrorAction SilentlyContinue
1215
1290
  }
1216
- # MCP config
1291
+ # MCP config (additive merge -- preserves user-defined servers)
1217
1292
  if (Test-Path "$cursorTargetDir\mcp.json") {
1218
- Copy-Item -Path "$cursorTargetDir\mcp.json" -Destination "$homeDir\.cursor\mcp.json" -Force
1293
+ Merge-JsonMcpConfig -StubFile "$cursorTargetDir\mcp.json" -DestFile "$homeDir\.cursor\mcp.json" -RootKey "mcpServers"
1219
1294
  }
1220
1295
  # Skills
1221
1296
  $skillsSource = Join-Path $script:SourceDir "core\skills"
@@ -1254,7 +1329,8 @@ function Install-Targets {
1254
1329
  }
1255
1330
  if (Test-Path "$vscodeTargetDir\mcp.json") {
1256
1331
  New-Item -ItemType Directory -Path "$homeDir\.vscode" -Force | Out-Null
1257
- Copy-Item -Path "$vscodeTargetDir\mcp.json" -Destination "$homeDir\.vscode\mcp.json" -Force
1332
+ # Additive merge -- preserves user-defined servers (root key is "servers" in VS Code)
1333
+ Merge-JsonMcpConfig -StubFile "$vscodeTargetDir\mcp.json" -DestFile "$homeDir\.vscode\mcp.json" -RootKey "servers"
1258
1334
  }
1259
1335
  if (Test-Path "$vscodeTargetDir\copilot-instructions.md") {
1260
1336
  Copy-Item -Path "$vscodeTargetDir\copilot-instructions.md" -Destination "$homeDir\.github\copilot-instructions.md" -Force
@@ -1292,27 +1368,8 @@ function Install-Targets {
1292
1368
  Copy-Item -Path "$geminiTargetDir\commands\*.toml" -Destination "$geminiHome\commands\" -Force -ErrorAction SilentlyContinue
1293
1369
  }
1294
1370
  if (Test-Path "$geminiTargetDir\settings-mcp.json") {
1295
- $settingsFile = "$geminiHome\settings.json"
1296
- if (Test-Path $settingsFile) {
1297
- try {
1298
- $existingSettings = Get-Content $settingsFile -Raw | ConvertFrom-Json
1299
- $mcpFragment = Get-Content "$geminiTargetDir\settings-mcp.json" -Raw | ConvertFrom-Json
1300
- if ($mcpFragment.mcpServers) {
1301
- if (-not $existingSettings.mcpServers) {
1302
- $existingSettings | Add-Member -NotePropertyName "mcpServers" -NotePropertyValue $mcpFragment.mcpServers -Force
1303
- } else {
1304
- $mcpFragment.mcpServers.PSObject.Properties | ForEach-Object {
1305
- $existingSettings.mcpServers | Add-Member -NotePropertyName $_.Name -NotePropertyValue $_.Value -Force
1306
- }
1307
- }
1308
- }
1309
- Write-Utf8NoBom -Path $settingsFile -Content ($existingSettings | ConvertTo-Json -Depth 10)
1310
- } catch {
1311
- Copy-Item -Path "$geminiTargetDir\settings-mcp.json" -Destination "$geminiHome\settings-mcp.json" -Force
1312
- }
1313
- } else {
1314
- Copy-Item -Path "$geminiTargetDir\settings-mcp.json" -Destination $settingsFile -Force
1315
- }
1371
+ # Additive merge into ~/.gemini/settings.json (root key is "mcpServers")
1372
+ Merge-JsonMcpConfig -StubFile "$geminiTargetDir\settings-mcp.json" -DestFile "$geminiHome\settings.json" -RootKey "mcpServers"
1316
1373
  }
1317
1374
  $skillsSource = Join-Path $script:SourceDir "core\skills"
1318
1375
  if (Test-Path $skillsSource -PathType Container) {
@@ -1340,9 +1397,9 @@ function Install-Targets {
1340
1397
  }
1341
1398
  if (Test-Path "$codexTargetDir\config-mcp.toml") {
1342
1399
  $configFile = "$codexHome\config.toml"
1400
+ $mcpContent = Get-Content "$codexTargetDir\config-mcp.toml" -Raw
1343
1401
  if (Test-Path $configFile) {
1344
1402
  $configContent = Get-Content $configFile -Raw
1345
- $mcpContent = Get-Content "$codexTargetDir\config-mcp.toml" -Raw
1346
1403
  if ($configContent -match "# Neocortex MCP Servers") {
1347
1404
  $lines = Get-Content $configFile
1348
1405
  $markerIndex = ($lines | Select-String "# Neocortex MCP Servers" | Select-Object -First 1).LineNumber - 1
@@ -1353,6 +1410,7 @@ function Install-Targets {
1353
1410
  Write-Utf8NoBom -Path $configFile -Content "$existingContent`n# Neocortex MCP Servers`n$mcpContent"
1354
1411
  }
1355
1412
  } else {
1413
+ New-Item -ItemType Directory -Path $codexHome -Force -ErrorAction SilentlyContinue | Out-Null
1356
1414
  Write-Utf8NoBom -Path $configFile -Content "# Neocortex MCP Servers`n$mcpContent"
1357
1415
  }
1358
1416
  }
@@ -1369,8 +1427,7 @@ function Install-Targets {
1369
1427
  $antiTargetDir = Join-Path $script:SourceDir "targets\antigravity"
1370
1428
  $geminiHome = if ($env:GEMINI_HOME) { $env:GEMINI_HOME } else { "$homeDir\.gemini" }
1371
1429
  if (Test-Path $antiTargetDir -PathType Container) {
1372
- if (Test-Path "$geminiHome\antigravity") { Remove-Item -Path "$geminiHome\antigravity" -Recurse -Force -ErrorAction SilentlyContinue }
1373
-
1430
+ # NOTE: Do NOT recursively delete $geminiHome\antigravity -- merge mcp_config.json instead
1374
1431
  if (Test-Path "$antiTargetDir\skill\SKILL.md") {
1375
1432
  New-Item -ItemType Directory -Path "$homeDir\.agent\skills\neocortex" -Force | Out-Null
1376
1433
  Copy-Item -Path "$antiTargetDir\skill\SKILL.md" -Destination "$homeDir\.agent\skills\neocortex\SKILL.md" -Force
@@ -1385,7 +1442,8 @@ function Install-Targets {
1385
1442
  }
1386
1443
  if (Test-Path "$antiTargetDir\mcp-config.json") {
1387
1444
  New-Item -ItemType Directory -Path "$geminiHome\antigravity" -Force | Out-Null
1388
- Copy-Item -Path "$antiTargetDir\mcp-config.json" -Destination "$geminiHome\antigravity\mcp_config.json" -Force
1445
+ # Flat JSON (no root key); preserves user-defined servers
1446
+ Merge-JsonMcpConfig -StubFile "$antiTargetDir\mcp-config.json" -DestFile "$geminiHome\antigravity\mcp_config.json" -RootKey ""
1389
1447
  }
1390
1448
  if (Test-Path "$antiTargetDir\gemini.md") {
1391
1449
  Copy-Item -Path "$antiTargetDir\gemini.md" -Destination "$homeDir\GEMINI.md" -Force
@@ -1532,7 +1590,8 @@ function New-ProjectDirectories {
1532
1590
  Copy-Item -Path "$cursorTargetDir\commands\*.md" -Destination "$projectDir\.cursor\commands\" -Force -ErrorAction SilentlyContinue
1533
1591
  }
1534
1592
  if (Test-Path "$cursorTargetDir\mcp.json") {
1535
- Copy-Item -Path "$cursorTargetDir\mcp.json" -Destination "$projectDir\.cursor\mcp.json" -Force
1593
+ New-Item -ItemType Directory -Path "$projectDir\.cursor" -Force | Out-Null
1594
+ Merge-JsonMcpConfig -StubFile "$cursorTargetDir\mcp.json" -DestFile "$projectDir\.cursor\mcp.json" -RootKey "mcpServers"
1536
1595
  }
1537
1596
  $skillsSource = Join-Path $script:SourceDir "core\skills"
1538
1597
  if (Test-Path $skillsSource -PathType Container) {
@@ -1559,7 +1618,7 @@ function New-ProjectDirectories {
1559
1618
  }
1560
1619
  if (Test-Path "$vscodeTargetDir\mcp.json") {
1561
1620
  New-Item -ItemType Directory -Path "$projectDir\.vscode" -Force | Out-Null
1562
- Copy-Item -Path "$vscodeTargetDir\mcp.json" -Destination "$projectDir\.vscode\mcp.json" -Force
1621
+ Merge-JsonMcpConfig -StubFile "$vscodeTargetDir\mcp.json" -DestFile "$projectDir\.vscode\mcp.json" -RootKey "servers"
1563
1622
  }
1564
1623
  if (Test-Path "$vscodeTargetDir\copilot-instructions.md") {
1565
1624
  Copy-Item -Path "$vscodeTargetDir\copilot-instructions.md" -Destination "$projectDir\.github\copilot-instructions.md" -Force
package/install.sh CHANGED
@@ -4,7 +4,7 @@
4
4
  # Development Orchestrator
5
5
 
6
6
  # Versao do instalador
7
- VERSION="4.0.1"
7
+ VERSION="4.0.2"
8
8
 
9
9
  # Flags
10
10
  MIGRATION_DETECTED=false
@@ -1036,6 +1036,20 @@ install_mcps() {
1036
1036
  mcp_results="${mcp_results}context7:SKIP "
1037
1037
  fi
1038
1038
 
1039
+ # browser_use: optional (requires BROWSER_USE_API_KEY). Skipped if not set.
1040
+ # Get your API key at https://cloud.browser-use.com/billing
1041
+ if claude mcp list 2>/dev/null | grep -q "^browser_use"; then
1042
+ mcp_results="${mcp_results}browser_use:OK "
1043
+ elif [ -n "$BROWSER_USE_API_KEY" ]; then
1044
+ if claude mcp add browser_use -e "BROWSER_USE_API_KEY=$BROWSER_USE_API_KEY" -- npx -y browser-use-mcp 2>/dev/null; then
1045
+ mcp_results="${mcp_results}browser_use:OK "
1046
+ else
1047
+ mcp_results="${mcp_results}browser_use:FAIL "
1048
+ fi
1049
+ else
1050
+ mcp_results="${mcp_results}browser_use:SKIP "
1051
+ fi
1052
+
1039
1053
  # Show compact MCP results
1040
1054
  local mcp_ok="" mcp_skip=""
1041
1055
  for entry in $mcp_results; do
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@ornexus/neocortex",
3
- "version": "4.0.1",
4
- "description": "Neocortex v4.0.1 - Orquestrador de Desenvolvimento de Epics & Stories para Claude Code",
3
+ "version": "4.0.2",
4
+ "description": "Neocortex v4.0.2 - Orquestrador de Desenvolvimento de Epics & Stories para Claude Code",
5
5
  "keywords": [
6
6
  "claude",
7
7
  "claude-code",
@@ -59,7 +59,7 @@
59
59
  "targets-stubs/"
60
60
  ],
61
61
  "scripts": {
62
- "build": "npm run build -w packages/shared && npm run build -w packages/client && node scripts/strip-source-map-comments.js",
62
+ "build": "npm run build -w packages/shared && npm run build -w packages/client && node scripts/strip-source-map-comments.js && node scripts/minify-client-dist.mjs",
63
63
  "build:clean": "rm -rf packages/shared/dist packages/client/dist && npm run build",
64
64
  "build:client": "npm run build -w packages/client",
65
65
  "build:shared": "npm run build -w packages/shared",
@@ -1,106 +1 @@
1
- /**
2
- * @license FSL-1.1
3
- * Copyright (c) 2026 OrNexus AI
4
- *
5
- * Adapter Registry - Plugin-style registry for target adapters.
6
- *
7
- * Manages registration and lookup of TargetAdapter instances.
8
- * Supports dynamic registration for extensibility and provides
9
- * a factory function for the default set of 6 adapters.
10
- *
11
- * Story 42.8
12
- */
13
- import { ClaudeCodeAdapter } from './claude-code-adapter.js';
14
- import { CursorAdapter } from './cursor-adapter.js';
15
- import { VSCodeAdapter } from './vscode-adapter.js';
16
- import { GeminiAdapter } from './gemini-adapter.js';
17
- import { CodexAdapter } from './codex-adapter.js';
18
- import { AntigravityAdapter } from './antigravity-adapter.js';
19
- // ── Error Types ─────────────────────────────────────────────────────────────
20
- export class UnknownTargetError extends Error {
21
- targetId;
22
- constructor(targetId) {
23
- super(`Unknown target: "${targetId}". Available targets: ${[...DEFAULT_ADAPTERS.keys()].join(', ')}`);
24
- this.targetId = targetId;
25
- this.name = 'UnknownTargetError';
26
- }
27
- }
28
- // ── Default Adapters Map ────────────────────────────────────────────────────
29
- const DEFAULT_ADAPTERS = new Map([
30
- ['claude-code', () => new ClaudeCodeAdapter()],
31
- ['cursor', () => new CursorAdapter()],
32
- ['vscode', () => new VSCodeAdapter()],
33
- ['gemini-cli', () => new GeminiAdapter()],
34
- ['codex', () => new CodexAdapter()],
35
- ['antigravity', () => new AntigravityAdapter()],
36
- ]);
37
- // ── Registry Implementation ─────────────────────────────────────────────────
38
- export class AdapterRegistry {
39
- adapters = new Map();
40
- /**
41
- * Register a target adapter.
42
- *
43
- * @param adapter - The adapter instance to register
44
- * @throws Error if an adapter with the same target ID is already registered
45
- */
46
- register(adapter) {
47
- const id = adapter.getTargetId();
48
- if (this.adapters.has(id)) {
49
- throw new Error(`Adapter already registered for target: "${id}"`);
50
- }
51
- this.adapters.set(id, adapter);
52
- }
53
- /**
54
- * Get an adapter by target ID.
55
- *
56
- * @param targetId - The target platform identifier
57
- * @returns The adapter instance, or undefined if not found
58
- */
59
- get(targetId) {
60
- return this.adapters.get(targetId);
61
- }
62
- /**
63
- * Get an adapter by target ID, throwing if not found.
64
- *
65
- * @param targetId - The target platform identifier
66
- * @returns The adapter instance
67
- * @throws UnknownTargetError if no adapter is registered for the target
68
- */
69
- getOrThrow(targetId) {
70
- const adapter = this.adapters.get(targetId);
71
- if (!adapter) {
72
- throw new UnknownTargetError(targetId);
73
- }
74
- return adapter;
75
- }
76
- /**
77
- * Check if an adapter is registered for a target.
78
- *
79
- * @param targetId - The target platform identifier
80
- * @returns true if an adapter is registered
81
- */
82
- has(targetId) {
83
- return this.adapters.has(targetId);
84
- }
85
- /**
86
- * List all registered target IDs.
87
- *
88
- * @returns Array of registered target identifiers
89
- */
90
- listTargets() {
91
- return [...this.adapters.keys()];
92
- }
93
- }
94
- // ── Factory Function ────────────────────────────────────────────────────────
95
- /**
96
- * Create a registry pre-populated with all 6 default platform adapters.
97
- *
98
- * @returns AdapterRegistry with claude-code, cursor, vscode, gemini-cli, codex, antigravity
99
- */
100
- export function createDefaultRegistry() {
101
- const registry = new AdapterRegistry();
102
- for (const [, factory] of DEFAULT_ADAPTERS) {
103
- registry.register(factory());
104
- }
105
- return registry;
106
- }
1
+ import{ClaudeCodeAdapter as o}from"./claude-code-adapter.js";import{CursorAdapter as s}from"./cursor-adapter.js";import{VSCodeAdapter as n}from"./vscode-adapter.js";import{GeminiAdapter as i}from"./gemini-adapter.js";import{CodexAdapter as d}from"./codex-adapter.js";import{AntigravityAdapter as p}from"./antigravity-adapter.js";class g extends Error{targetId;constructor(r){super(`Unknown target: "${r}". Available targets: ${[...a.keys()].join(", ")}`),this.targetId=r,this.name="UnknownTargetError"}}const a=new Map([["claude-code",()=>new o],["cursor",()=>new s],["vscode",()=>new n],["gemini-cli",()=>new i],["codex",()=>new d],["antigravity",()=>new p]]);class c{adapters=new Map;register(r){const e=r.getTargetId();if(this.adapters.has(e))throw new Error(`Adapter already registered for target: "${e}"`);this.adapters.set(e,r)}get(r){return this.adapters.get(r)}getOrThrow(r){const e=this.adapters.get(r);if(!e)throw new g(r);return e}has(r){return this.adapters.has(r)}listTargets(){return[...this.adapters.keys()]}}function l(){const t=new c;for(const[,r]of a)t.register(r());return t}export{c as AdapterRegistry,g as UnknownTargetError,l as createDefaultRegistry};
@@ -1,77 +1,2 @@
1
- /**
2
- * @license FSL-1.1
3
- * Copyright (c) 2026 OrNexus AI
4
- *
5
- * Antigravity Adapter - Formats prompts for the Antigravity platform.
6
- *
7
- * Antigravity shares the GEMINI.md format with Gemini CLI but adds
8
- * platform-specific sections for workflows and rules.
9
- *
10
- * Story 42.8
11
- */
12
- // ── Constants ───────────────────────────────────────────────────────────────
13
- const TARGET_ID = 'antigravity';
14
- const MAX_CONTEXT_LENGTH = 1_000_000;
15
- const CAPABILITIES = {
16
- supportsMarkdown: true,
17
- supportsMultiFile: true,
18
- supportsMultiTurn: true,
19
- supportsTools: true,
20
- maxContextLength: MAX_CONTEXT_LENGTH,
21
- };
22
- // ── Implementation ──────────────────────────────────────────────────────────
23
- export class AntigravityAdapter {
24
- formatPrompt(assembledPrompt, platformInstructions, config) {
25
- const sections = [];
26
- // Main prompt content (shared Gemini format)
27
- sections.push(assembledPrompt);
28
- // @import directives for standards (shared with Gemini)
29
- if (platformInstructions.contextFiles && platformInstructions.contextFiles.length > 0) {
30
- sections.push('');
31
- sections.push('## Standards');
32
- sections.push('');
33
- for (const file of platformInstructions.contextFiles) {
34
- sections.push(`@import ${file}`);
35
- }
36
- }
37
- // Antigravity-specific: workflow support
38
- sections.push('');
39
- sections.push('## Antigravity-Specific');
40
- sections.push('');
41
- sections.push('This GEMINI.md is shared between Gemini CLI and Antigravity targets.');
42
- sections.push('For Antigravity-specific features:');
43
- // Tool definitions
44
- if (platformInstructions.tools && platformInstructions.tools.length > 0) {
45
- sections.push('');
46
- sections.push('### Tools');
47
- sections.push('');
48
- for (const tool of platformInstructions.tools) {
49
- sections.push(`- ${tool}`);
50
- }
51
- }
52
- // MCP configuration
53
- if (platformInstructions.mcpConfig && Object.keys(platformInstructions.mcpConfig).length > 0) {
54
- sections.push('');
55
- sections.push('### MCP Servers');
56
- sections.push('');
57
- sections.push('```json');
58
- sections.push(JSON.stringify(platformInstructions.mcpConfig, null, 2));
59
- sections.push('```');
60
- }
61
- let result = sections.join('\n');
62
- const maxLength = config.maxPromptLength ?? MAX_CONTEXT_LENGTH;
63
- if (result.length > maxLength) {
64
- result = result.slice(0, maxLength);
65
- }
66
- return result;
67
- }
68
- getTargetId() {
69
- return TARGET_ID;
70
- }
71
- getCapabilities() {
72
- return CAPABILITIES;
73
- }
74
- getInjectionMethod() {
75
- return 'file';
76
- }
77
- }
1
+ const u="antigravity",g=1e6,n={supportsMarkdown:!0,supportsMultiFile:!0,supportsMultiTurn:!0,supportsTools:!0,maxContextLength:1e6};class l{formatPrompt(h,t,o){const e=[];if(e.push(h),t.contextFiles&&t.contextFiles.length>0){e.push(""),e.push("## Standards"),e.push("");for(const i of t.contextFiles)e.push(`@import ${i}`)}if(e.push(""),e.push("## Antigravity-Specific"),e.push(""),e.push("This GEMINI.md is shared between Gemini CLI and Antigravity targets."),e.push("For Antigravity-specific features:"),t.tools&&t.tools.length>0){e.push(""),e.push("### Tools"),e.push("");for(const i of t.tools)e.push(`- ${i}`)}t.mcpConfig&&Object.keys(t.mcpConfig).length>0&&(e.push(""),e.push("### MCP Servers"),e.push(""),e.push("```json"),e.push(JSON.stringify(t.mcpConfig,null,2)),e.push("```"));let s=e.join(`
2
+ `);const p=o.maxPromptLength??1e6;return s.length>p&&(s=s.slice(0,p)),s}getTargetId(){return u}getCapabilities(){return n}getInjectionMethod(){return"file"}}export{l as AntigravityAdapter};
@@ -1,79 +1,3 @@
1
- /**
2
- * @license FSL-1.1
3
- * Copyright (c) 2026 OrNexus AI
4
- *
5
- * Claude Code Adapter - Formats prompts as CLAUDE.md content.
6
- *
7
- * Claude Code reads system prompts from CLAUDE.md and referenced .md files.
8
- * This adapter preserves full Markdown formatting, headers, sections,
9
- * code blocks, and injects platform-specific instructions.
10
- *
11
- * Story 42.8
12
- */
13
- // ── Constants ───────────────────────────────────────────────────────────────
14
- const TARGET_ID = 'claude-code';
15
- const MAX_CONTEXT_LENGTH = 200_000;
16
- const CAPABILITIES = {
17
- supportsMarkdown: true,
18
- supportsMultiFile: true,
19
- supportsMultiTurn: true,
20
- supportsTools: true,
21
- maxContextLength: MAX_CONTEXT_LENGTH,
22
- };
23
- // ── Implementation ──────────────────────────────────────────────────────────
24
- export class ClaudeCodeAdapter {
25
- formatPrompt(assembledPrompt, platformInstructions, config) {
26
- const sections = [];
27
- // Main prompt content (preserved as-is for Claude Code)
28
- sections.push(assembledPrompt);
29
- // Inject platform-specific instructions
30
- if (platformInstructions.tools && platformInstructions.tools.length > 0) {
31
- sections.push('');
32
- sections.push('## Available Tools');
33
- sections.push('');
34
- for (const tool of platformInstructions.tools) {
35
- sections.push(`- ${tool}`);
36
- }
37
- }
38
- if (platformInstructions.mcpConfig && Object.keys(platformInstructions.mcpConfig).length > 0) {
39
- sections.push('');
40
- sections.push('## MCP Configuration');
41
- sections.push('');
42
- sections.push('```json');
43
- sections.push(JSON.stringify(platformInstructions.mcpConfig, null, 2));
44
- sections.push('```');
45
- }
46
- if (platformInstructions.contextFiles && platformInstructions.contextFiles.length > 0) {
47
- sections.push('');
48
- sections.push('## Context Files');
49
- sections.push('');
50
- for (const file of platformInstructions.contextFiles) {
51
- sections.push(`@${file}`);
52
- }
53
- }
54
- // Apply custom headers
55
- if (config.customHeaders && Object.keys(config.customHeaders).length > 0) {
56
- const headerLines = [];
57
- for (const [key, value] of Object.entries(config.customHeaders)) {
58
- headerLines.push(`${key}: ${value}`);
59
- }
60
- sections.unshift(headerLines.join('\n'), '');
61
- }
62
- let result = sections.join('\n');
63
- // Enforce max length if configured
64
- const maxLength = config.maxPromptLength ?? MAX_CONTEXT_LENGTH;
65
- if (result.length > maxLength) {
66
- result = result.slice(0, maxLength);
67
- }
68
- return result;
69
- }
70
- getTargetId() {
71
- return TARGET_ID;
72
- }
73
- getCapabilities() {
74
- return CAPABILITIES;
75
- }
76
- getInjectionMethod() {
77
- return 'file';
78
- }
79
- }
1
+ const i="claude-code",T=2e5,r={supportsMarkdown:!0,supportsMultiFile:!0,supportsMultiTurn:!0,supportsTools:!0,maxContextLength:2e5};class g{formatPrompt(n,s,o){const e=[];if(e.push(n),s.tools&&s.tools.length>0){e.push(""),e.push("## Available Tools"),e.push("");for(const t of s.tools)e.push(`- ${t}`)}if(s.mcpConfig&&Object.keys(s.mcpConfig).length>0&&(e.push(""),e.push("## MCP Configuration"),e.push(""),e.push("```json"),e.push(JSON.stringify(s.mcpConfig,null,2)),e.push("```")),s.contextFiles&&s.contextFiles.length>0){e.push(""),e.push("## Context Files"),e.push("");for(const t of s.contextFiles)e.push(`@${t}`)}if(o.customHeaders&&Object.keys(o.customHeaders).length>0){const t=[];for(const[l,p]of Object.entries(o.customHeaders))t.push(`${l}: ${p}`);e.unshift(t.join(`
2
+ `),"")}let u=e.join(`
3
+ `);const h=o.maxPromptLength??2e5;return u.length>h&&(u=u.slice(0,h)),u}getTargetId(){return i}getCapabilities(){return r}getInjectionMethod(){return"file"}}export{g as ClaudeCodeAdapter};
@@ -1,80 +1,2 @@
1
- /**
2
- * @license FSL-1.1
3
- * Copyright (c) 2026 OrNexus AI
4
- *
5
- * Codex Adapter - Formats prompts as AGENTS.md content.
6
- *
7
- * Codex reads agent instructions from AGENTS.md files.
8
- * This adapter produces concise, agent-instruction style content
9
- * optimized for Codex's instruction format.
10
- *
11
- * Story 42.8
12
- */
13
- // ── Constants ───────────────────────────────────────────────────────────────
14
- const TARGET_ID = 'codex';
15
- const MAX_CONTEXT_LENGTH = 200_000;
16
- const CAPABILITIES = {
17
- supportsMarkdown: true,
18
- supportsMultiFile: false,
19
- supportsMultiTurn: true,
20
- supportsTools: true,
21
- maxContextLength: MAX_CONTEXT_LENGTH,
22
- };
23
- // ── Implementation ──────────────────────────────────────────────────────────
24
- export class CodexAdapter {
25
- formatPrompt(assembledPrompt, platformInstructions, config) {
26
- const sections = [];
27
- // Agent-style header
28
- sections.push(assembledPrompt);
29
- // Architecture section (concise)
30
- if (platformInstructions.tools && platformInstructions.tools.length > 0) {
31
- sections.push('');
32
- sections.push('## Tools');
33
- sections.push('');
34
- for (const tool of platformInstructions.tools) {
35
- sections.push(`- ${tool}`);
36
- }
37
- }
38
- // Context references
39
- if (platformInstructions.contextFiles && platformInstructions.contextFiles.length > 0) {
40
- sections.push('');
41
- sections.push('## Context Files');
42
- sections.push('');
43
- for (const file of platformInstructions.contextFiles) {
44
- sections.push(`- ${file}`);
45
- }
46
- }
47
- // MCP config (Codex supports MCP via config-mcp.toml)
48
- if (platformInstructions.mcpConfig && Object.keys(platformInstructions.mcpConfig).length > 0) {
49
- sections.push('');
50
- sections.push('## MCP Configuration');
51
- sections.push('');
52
- sections.push('```toml');
53
- // Convert to TOML-style representation
54
- for (const [key, value] of Object.entries(platformInstructions.mcpConfig)) {
55
- sections.push(`[${key}]`);
56
- if (typeof value === 'object' && value !== null) {
57
- for (const [subKey, subValue] of Object.entries(value)) {
58
- sections.push(`${subKey} = ${JSON.stringify(subValue)}`);
59
- }
60
- }
61
- }
62
- sections.push('```');
63
- }
64
- let result = sections.join('\n');
65
- const maxLength = config.maxPromptLength ?? MAX_CONTEXT_LENGTH;
66
- if (result.length > maxLength) {
67
- result = result.slice(0, maxLength);
68
- }
69
- return result;
70
- }
71
- getTargetId() {
72
- return TARGET_ID;
73
- }
74
- getCapabilities() {
75
- return CAPABILITIES;
76
- }
77
- getInjectionMethod() {
78
- return 'file';
79
- }
80
- }
1
+ const c="codex",T=2e5,g={supportsMarkdown:!0,supportsMultiFile:!1,supportsMultiTurn:!0,supportsTools:!0,maxContextLength:2e5};class f{formatPrompt(p,t,h){const e=[];if(e.push(p),t.tools&&t.tools.length>0){e.push(""),e.push("## Tools"),e.push("");for(const o of t.tools)e.push(`- ${o}`)}if(t.contextFiles&&t.contextFiles.length>0){e.push(""),e.push("## Context Files"),e.push("");for(const o of t.contextFiles)e.push(`- ${o}`)}if(t.mcpConfig&&Object.keys(t.mcpConfig).length>0){e.push(""),e.push("## MCP Configuration"),e.push(""),e.push("```toml");for(const[o,u]of Object.entries(t.mcpConfig))if(e.push(`[${o}]`),typeof u=="object"&&u!==null)for(const[i,l]of Object.entries(u))e.push(`${i} = ${JSON.stringify(l)}`);e.push("```")}let s=e.join(`
2
+ `);const n=h.maxPromptLength??2e5;return s.length>n&&(s=s.slice(0,n)),s}getTargetId(){return c}getCapabilities(){return g}getInjectionMethod(){return"file"}}export{f as CodexAdapter};