@nexus-cortex/server 4.31.0 → 4.33.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/docs/architecture.md +203 -0
- package/docs/assets/nexus-cortex-hero.svg +140 -0
- package/docs/authentication.md +95 -0
- package/docs/configuration.md +185 -0
- package/docs/user-guide.md +291 -0
- package/package.json +5 -4
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
# Nexus Cortex — Architecture
|
|
2
|
+
|
|
3
|
+
How the harness fits together: the monorepo layout, the orchestrator, the provider/tool/
|
|
4
|
+
middleware systems, and the other core subsystems. For usage see the [User Guide](user-guide.md).
|
|
5
|
+
|
|
6
|
+
## Monorepo structure
|
|
7
|
+
|
|
8
|
+
```
|
|
9
|
+
nexus-cortex/
|
|
10
|
+
├── packages/
|
|
11
|
+
│ ├── types/ # Shared TypeScript types (zero runtime deps)
|
|
12
|
+
│ ├── core/ # Core orchestration library
|
|
13
|
+
│ │ ├── orchestrator/ # CortexOrchestrator (main engine) + sub-agents
|
|
14
|
+
│ │ ├── adapters/ # Format adapters (Messages, ChatCompletions, …)
|
|
15
|
+
│ │ ├── models/ # Model registry (per-provider model cards)
|
|
16
|
+
│ │ ├── tools/ # Tool definitions & registries
|
|
17
|
+
│ │ ├── middleware/ # System-message, permissions, retry, mentorship, …
|
|
18
|
+
│ │ ├── training/ # Auto-research: experiments, router matrix, gate
|
|
19
|
+
│ │ ├── mcp/ # MCP client & server integration
|
|
20
|
+
│ │ ├── system-messages/# System message auto-loading
|
|
21
|
+
│ │ └── session/ # JSONL session storage
|
|
22
|
+
│ ├── executors/ # Tool execution implementations
|
|
23
|
+
│ ├── server/ # Express HTTP server (optional)
|
|
24
|
+
│ │ └── routes/ # REST API endpoints
|
|
25
|
+
│ └── cli/ # Headless cortex CLI
|
|
26
|
+
└── scripts/ # Build and maintenance scripts
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### Package build order
|
|
30
|
+
|
|
31
|
+
A strict order, because core and executors form a circular dependency broken by a two-pass
|
|
32
|
+
build (handled by `scripts/build.sh`):
|
|
33
|
+
|
|
34
|
+
1. **types** — shared types (zero deps)
|
|
35
|
+
2. **executors** — partial build (core imports fail; expected)
|
|
36
|
+
3. **core** — depends on types
|
|
37
|
+
4. **executors** — complete build (core now available)
|
|
38
|
+
5. **server** — depends on core
|
|
39
|
+
6. **cli** — headless `cortex` (depends on core)
|
|
40
|
+
7. **tui** — interactive React/Ink + Chalk UIs (Release 2 — not yet published)
|
|
41
|
+
|
|
42
|
+
Always build from the repo root: `npm run build`.
|
|
43
|
+
|
|
44
|
+
### Direct-wired vs server mode
|
|
45
|
+
|
|
46
|
+
**Direct mode (default)** — the core library is imported directly into the CLI process: zero
|
|
47
|
+
network overhead, immediate access to all orchestrator features, single-process debugging.
|
|
48
|
+
|
|
49
|
+
**Server mode (optional)** — an HTTP server exposes the REST API for web/mobile/remote clients
|
|
50
|
+
and multi-client use.
|
|
51
|
+
|
|
52
|
+
## Core systems
|
|
53
|
+
|
|
54
|
+
### Cortex Orchestrator
|
|
55
|
+
|
|
56
|
+
The orchestrator coordinates every AI interaction, tool execution, and session update. A
|
|
57
|
+
single `processMessage` turn handles periodic review, keyword detection, system-message
|
|
58
|
+
injection, context budgeting, model selection, the API call (with retry and context-rejection
|
|
59
|
+
compaction), the tool-calling loop (with loop detection and orphaned-tool recovery), cache-
|
|
60
|
+
metric extraction, and session persistence.
|
|
61
|
+
|
|
62
|
+
```typescript
|
|
63
|
+
import { CortexOrchestrator } from '@nexus-cortex/core';
|
|
64
|
+
|
|
65
|
+
const orchestrator = new CortexOrchestrator({
|
|
66
|
+
modelId: 'claude-sonnet-4-6',
|
|
67
|
+
projectPath: process.cwd(),
|
|
68
|
+
mcpAutoInject: true,
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
const response = await orchestrator.processMessage({ role: 'user', content: 'Analyze this codebase' });
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Multi-provider system
|
|
75
|
+
|
|
76
|
+
Providers are reached through a pluggable adapter layer (Messages, Chat Completions,
|
|
77
|
+
GenerateContent, GenAI, Responses). Each provider is enabled by its API key. The **five major
|
|
78
|
+
labs are proven end-to-end** (driven hard through the full tool loop, sub-agents, caching, and
|
|
79
|
+
the benchmark harness); the smaller labs (Cloudflare Workers AI, Zhipu/GLM, Qwen, Moonshot/Kimi,
|
|
80
|
+
MiniMax, Mercury) are incorporated through the same adapters but treated as preview.
|
|
81
|
+
|
|
82
|
+
**Run `cortex models list` for the live, exact set** — and `cortex models providers` for the
|
|
83
|
+
provider list with the API-key variable each needs.
|
|
84
|
+
|
|
85
|
+
### Tool system
|
|
86
|
+
|
|
87
|
+
A dual registry — immutable base tools + dynamic addon tools — plus any tools discovered from
|
|
88
|
+
connected MCP servers, all with read-before-edit safety. Categories: file & notebook, search,
|
|
89
|
+
shell (foreground + background), web & browser, sub-agents, git & PR, sandboxed artifacts with
|
|
90
|
+
React introspection, conversation history, MCP/tool discovery, planning & UI, code & monitoring,
|
|
91
|
+
auto-research, skills & commands, and an opt-in end-of-turn audit.
|
|
92
|
+
|
|
93
|
+
**Run `cortex tools list` for the live, authoritative set with descriptions.**
|
|
94
|
+
|
|
95
|
+
### System message management
|
|
96
|
+
|
|
97
|
+
System messages auto-load from `.cortex/CORTEX.md` (project context) and numbered files under
|
|
98
|
+
`.cortex/system-messages/`. `CORTEX.md` is generated on demand:
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
/init # in the CLI
|
|
102
|
+
# or programmatically:
|
|
103
|
+
import { InitCortexContext } from '@nexus-cortex/core';
|
|
104
|
+
await InitCortexContext.execute({ scope: 'auto', max_depth: 5 }, process.cwd());
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
It captures the project description, file tree, dependency analysis (npm/Python/Rust/Go),
|
|
108
|
+
available scripts, and monorepo package structure.
|
|
109
|
+
|
|
110
|
+
### MCP integration
|
|
111
|
+
|
|
112
|
+
Full Model Context Protocol support. Manage via `cortex mcp …` (or `/mcp` in the UI); configure
|
|
113
|
+
in `.cortex/mcp_config.json`:
|
|
114
|
+
|
|
115
|
+
```json
|
|
116
|
+
{
|
|
117
|
+
"mcpServers": {
|
|
118
|
+
"filesystem": {
|
|
119
|
+
"command": "npx",
|
|
120
|
+
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/allowed/path"]
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### Session management
|
|
127
|
+
|
|
128
|
+
JSONL-based persistence with full state recovery: append-only JSONL in `.cortex/sessions/`,
|
|
129
|
+
UUID message IDs (zero collision risk), content-addressable file checkpoints in
|
|
130
|
+
`.cortex/file-history/`, helper-model auto-compaction at a configurable token threshold, and
|
|
131
|
+
optional auto-resume on server start.
|
|
132
|
+
|
|
133
|
+
### Sandboxed artifacts & visual workspace
|
|
134
|
+
|
|
135
|
+
`CreateArtifactTool` spins up a runnable web/server app in a tmux-managed sandbox and the model
|
|
136
|
+
iterates against it with real feedback: snapshots (screenshot/DOM/console/network/accessibility),
|
|
137
|
+
interaction (click/type/navigate), hot-reload edits, and file transfer. React artifacts build
|
|
138
|
+
from a single component (CDN or esbuild-bundled), with React-aware introspection senses
|
|
139
|
+
(component tree, props, render-trace).
|
|
140
|
+
|
|
141
|
+
### Sub-agents (Task)
|
|
142
|
+
|
|
143
|
+
The `Task` tool dispatches work to isolated sub-agents that run in parallel, each with its own
|
|
144
|
+
permission scope. Sub-agents are profiles under `.cortex/agents/*.md` (YAML frontmatter +
|
|
145
|
+
instructions; project agents override personal `~/.cortex/agents/`). Set `AGENT_TMUX_MONITOR=true`
|
|
146
|
+
for a live tmux pane per agent.
|
|
147
|
+
|
|
148
|
+
### Auto-research (closed-loop improvement)
|
|
149
|
+
|
|
150
|
+
A closed-loop experiment runner that measures a change before keeping it: build a **baseline**
|
|
151
|
+
and a **candidate**, benchmark both on a graded task set, and gate a keep/discard verdict with
|
|
152
|
+
real statistics (Monte-Carlo: bootstrap CI + permutation + N-aware significance, plus a held-out
|
|
153
|
+
check). Inspired by [karpathy/autoresearch](https://github.com/karpathy/autoresearch). Driven by
|
|
154
|
+
`cortex autoresearch` (`bench` / `experiment` / `evaluate` / `fix` / `list`). Its first
|
|
155
|
+
application is the harness improving itself; the loop generalizes to other developmental-
|
|
156
|
+
improvement experiments.
|
|
157
|
+
|
|
158
|
+
### Permission system
|
|
159
|
+
|
|
160
|
+
Tool execution is gated by a policy engine with three environment profiles in `.cortex/`
|
|
161
|
+
(`permissions.dev.json` / `.test.json` / `.prod.json`) and four policy types — whitelist,
|
|
162
|
+
blacklist, file-operation, bash-command — with audit logging. `YOLO=true` bypasses all of it.
|
|
163
|
+
Manage at runtime via `cortex permissions …`.
|
|
164
|
+
|
|
165
|
+
### Model router & reactive mentorship
|
|
166
|
+
|
|
167
|
+
- **Model router** (opt-in, `MODEL_ROUTER_ENABLED`) routes `model="auto"` requests to the best
|
|
168
|
+
model for the task type using recorded benchmark history, with a multi-entry exclude list
|
|
169
|
+
(`MODEL_ROUTER_EXCLUDE`).
|
|
170
|
+
- **Reactive mentorship** (opt-in, `MENTORSHIP_ENABLED`) is an AI-to-AI self-improvement loop
|
|
171
|
+
that triggers helper-model review on errors, keywords (`@ultrathink` / `@analyze` / `@rethink`),
|
|
172
|
+
turn intervals, or repeated failure patterns.
|
|
173
|
+
|
|
174
|
+
## Power-user surfaces
|
|
175
|
+
|
|
176
|
+
Beyond the core loop, the harness ships surfaces you'd otherwise build yourself:
|
|
177
|
+
|
|
178
|
+
- **Visual agent monitoring (tmux).** Parallel sub-agents each in a live tmux pane
|
|
179
|
+
(`AGENT_TMUX_MONITOR`), plus an opt-in dashboard (`ENABLE_DASHBOARD=true`) to watch sandbox +
|
|
180
|
+
tmux sessions.
|
|
181
|
+
- **Git PR agent.** `PRAgent` runs review/create/list pipelines (and `/v1/pr/*` routes), shelling
|
|
182
|
+
out safely (`execFile`, no shell) behind an opt-in repo/action allow-list and an HMAC-verified
|
|
183
|
+
webhook.
|
|
184
|
+
- **Isolated git worktrees.** `WorkspaceManager` hands each agent a clean worktree (clone → branch
|
|
185
|
+
→ work → cleanup) so parallel agents never clobber each other.
|
|
186
|
+
- **Helper-model middleware.** A cheaper secondary model auto-compacts the conversation near the
|
|
187
|
+
context limit — *compaction first, windowing last*.
|
|
188
|
+
- **Session summarization + next-action prediction.** `TURN_SUMMARY_PREDICTION` emits a post-turn
|
|
189
|
+
summary and predicted next action — handy for agent-team handoffs and autonomy loops.
|
|
190
|
+
- **Deferred tool loading.** Expose only essential tools up front and let the model discover the
|
|
191
|
+
rest via `SearchTools` — a large first-turn input-token cut on big tool sets.
|
|
192
|
+
|
|
193
|
+
## Extending
|
|
194
|
+
|
|
195
|
+
**New tool** — define it in `packages/core/src/tools/`, add it to `BaseToolRegistry`, implement
|
|
196
|
+
the executor in `packages/executors/src/implementations/`, register it in `ExecutorRegistry`,
|
|
197
|
+
and rebuild.
|
|
198
|
+
|
|
199
|
+
**New provider** — implement a `FormatAdapter` in `packages/core/src/adapters/`, register it in
|
|
200
|
+
`AdapterRegistry`, add model cards under `packages/core/src/models/cards/`, and update the model
|
|
201
|
+
registry.
|
|
202
|
+
|
|
203
|
+
See `packages/*/CLAUDE.md` for per-package reading lists and the exact wiring.
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="688" height="543" viewBox="0 0 688 543" role="img" aria-label="Nexus Cortex">
|
|
2
|
+
<rect width="688" height="543" rx="12" fill="#070707"/>
|
|
3
|
+
<g transform="translate(27.7,0) scale(1.15,1)" font-family="ui-monospace,SFMono-Regular,Menlo,Consolas,monospace" font-size="16" xml:space="preserve">
|
|
4
|
+
<text x="106.2" y="37" textLength="9.65" lengthAdjust="spacingAndGlyphs" fill="#A6E22E">●</text>
|
|
5
|
+
<text x="212.3" y="37" textLength="9.65" lengthAdjust="spacingAndGlyphs" fill="#A6E22E">●</text>
|
|
6
|
+
<text x="270.2" y="37" textLength="9.65" lengthAdjust="spacingAndGlyphs" fill="#A6E22E">●</text>
|
|
7
|
+
<text x="328.1" y="37" textLength="9.65" lengthAdjust="spacingAndGlyphs" fill="#A6E22E">●</text>
|
|
8
|
+
<text x="434.2" y="37" textLength="9.65" lengthAdjust="spacingAndGlyphs" fill="#A6E22E">●</text>
|
|
9
|
+
<text x="106.2" y="56" textLength="9.65" lengthAdjust="spacingAndGlyphs" fill="#E6DB74">│</text>
|
|
10
|
+
<text x="212.3" y="56" textLength="38.60" lengthAdjust="spacingAndGlyphs" fill="#E6DB74">╰──╮</text>
|
|
11
|
+
<text x="270.2" y="56" textLength="9.65" lengthAdjust="spacingAndGlyphs" fill="#E6DB74">│</text>
|
|
12
|
+
<text x="299.2" y="56" textLength="38.60" lengthAdjust="spacingAndGlyphs" fill="#E6DB74">╭──╯</text>
|
|
13
|
+
<text x="434.2" y="56" textLength="9.65" lengthAdjust="spacingAndGlyphs" fill="#E6DB74">│</text>
|
|
14
|
+
<text x="67.5" y="75" textLength="9.65" lengthAdjust="spacingAndGlyphs" fill="#A6E22E">●</text>
|
|
15
|
+
<text x="77.2" y="75" textLength="38.60" lengthAdjust="spacingAndGlyphs" fill="#E6DB74">───╯</text>
|
|
16
|
+
<text x="135.1" y="75" textLength="9.65" lengthAdjust="spacingAndGlyphs" fill="#A6E22E">●</text>
|
|
17
|
+
<text x="144.8" y="75" textLength="28.95" lengthAdjust="spacingAndGlyphs" fill="#E6DB74">──╮</text>
|
|
18
|
+
<text x="241.2" y="75" textLength="9.65" lengthAdjust="spacingAndGlyphs" fill="#E6DB74">│</text>
|
|
19
|
+
<text x="270.2" y="75" textLength="9.65" lengthAdjust="spacingAndGlyphs" fill="#E6DB74">│</text>
|
|
20
|
+
<text x="299.2" y="75" textLength="9.65" lengthAdjust="spacingAndGlyphs" fill="#E6DB74">│</text>
|
|
21
|
+
<text x="376.4" y="75" textLength="28.95" lengthAdjust="spacingAndGlyphs" fill="#E6DB74">╭──</text>
|
|
22
|
+
<text x="405.3" y="75" textLength="9.65" lengthAdjust="spacingAndGlyphs" fill="#A6E22E">●</text>
|
|
23
|
+
<text x="434.2" y="75" textLength="38.60" lengthAdjust="spacingAndGlyphs" fill="#E6DB74">╰───</text>
|
|
24
|
+
<text x="472.9" y="75" textLength="9.65" lengthAdjust="spacingAndGlyphs" fill="#A6E22E">●</text>
|
|
25
|
+
<text x="164.1" y="94" textLength="28.95" lengthAdjust="spacingAndGlyphs" fill="#E6DB74">╰─╮</text>
|
|
26
|
+
<text x="241.2" y="94" textLength="9.65" lengthAdjust="spacingAndGlyphs" fill="#E6DB74">│</text>
|
|
27
|
+
<text x="270.2" y="94" textLength="9.65" lengthAdjust="spacingAndGlyphs" fill="#E6DB74">│</text>
|
|
28
|
+
<text x="299.2" y="94" textLength="9.65" lengthAdjust="spacingAndGlyphs" fill="#E6DB74">│</text>
|
|
29
|
+
<text x="357.1" y="94" textLength="28.95" lengthAdjust="spacingAndGlyphs" fill="#E6DB74">╭─╯</text>
|
|
30
|
+
<text x="106.2" y="113" textLength="337.75" lengthAdjust="spacingAndGlyphs" fill="#AE81FF">╭───────┴─────┴──┴──┴─────┴───────╮</text>
|
|
31
|
+
<text x="67.5" y="132" textLength="9.65" lengthAdjust="spacingAndGlyphs" fill="#A6E22E">●</text>
|
|
32
|
+
<text x="77.2" y="132" textLength="28.95" lengthAdjust="spacingAndGlyphs" fill="#E6DB74">───</text>
|
|
33
|
+
<text x="106.2" y="132" textLength="9.65" lengthAdjust="spacingAndGlyphs" fill="#AE81FF">┤</text>
|
|
34
|
+
<text x="115.8" y="132" textLength="9.65" lengthAdjust="spacingAndGlyphs" fill="#FD971F">■</text>
|
|
35
|
+
<text x="183.3" y="132" textLength="9.65" lengthAdjust="spacingAndGlyphs" fill="#FD971F">▀</text>
|
|
36
|
+
<text x="241.2" y="132" textLength="9.65" lengthAdjust="spacingAndGlyphs" fill="#FD971F">▀</text>
|
|
37
|
+
<text x="270.2" y="132" textLength="9.65" lengthAdjust="spacingAndGlyphs" fill="#FD971F">▀</text>
|
|
38
|
+
<text x="299.2" y="132" textLength="9.65" lengthAdjust="spacingAndGlyphs" fill="#FD971F">▀</text>
|
|
39
|
+
<text x="357.1" y="132" textLength="9.65" lengthAdjust="spacingAndGlyphs" fill="#FD971F">▀</text>
|
|
40
|
+
<text x="424.6" y="132" textLength="9.65" lengthAdjust="spacingAndGlyphs" fill="#FD971F">■</text>
|
|
41
|
+
<text x="434.2" y="132" textLength="9.65" lengthAdjust="spacingAndGlyphs" fill="#AE81FF">├</text>
|
|
42
|
+
<text x="443.9" y="132" textLength="28.95" lengthAdjust="spacingAndGlyphs" fill="#E6DB74">───</text>
|
|
43
|
+
<text x="472.9" y="132" textLength="9.65" lengthAdjust="spacingAndGlyphs" fill="#A6E22E">●</text>
|
|
44
|
+
<text x="106.2" y="151" textLength="9.65" lengthAdjust="spacingAndGlyphs" fill="#AE81FF">│</text>
|
|
45
|
+
<text x="144.8" y="151" textLength="260.55" lengthAdjust="spacingAndGlyphs" fill="#F8F8F2">╔═════════════════════════╗</text>
|
|
46
|
+
<text x="434.2" y="151" textLength="9.65" lengthAdjust="spacingAndGlyphs" fill="#AE81FF">│</text>
|
|
47
|
+
<text x="67.5" y="170" textLength="9.65" lengthAdjust="spacingAndGlyphs" fill="#A6E22E">●</text>
|
|
48
|
+
<text x="77.2" y="170" textLength="28.95" lengthAdjust="spacingAndGlyphs" fill="#E6DB74">───</text>
|
|
49
|
+
<text x="106.2" y="170" textLength="9.65" lengthAdjust="spacingAndGlyphs" fill="#AE81FF">┤</text>
|
|
50
|
+
<text x="115.8" y="170" textLength="9.65" lengthAdjust="spacingAndGlyphs" fill="#FD971F">■</text>
|
|
51
|
+
<text x="144.8" y="170" textLength="9.65" lengthAdjust="spacingAndGlyphs" fill="#F8F8F2">║</text>
|
|
52
|
+
<text x="395.7" y="170" textLength="9.65" lengthAdjust="spacingAndGlyphs" fill="#F8F8F2">║</text>
|
|
53
|
+
<text x="424.6" y="170" textLength="9.65" lengthAdjust="spacingAndGlyphs" fill="#FD971F">■</text>
|
|
54
|
+
<text x="434.2" y="170" textLength="9.65" lengthAdjust="spacingAndGlyphs" fill="#AE81FF">├</text>
|
|
55
|
+
<text x="443.9" y="170" textLength="28.95" lengthAdjust="spacingAndGlyphs" fill="#E6DB74">───</text>
|
|
56
|
+
<text x="472.9" y="170" textLength="9.65" lengthAdjust="spacingAndGlyphs" fill="#A6E22E">●</text>
|
|
57
|
+
<text x="106.2" y="189" textLength="9.65" lengthAdjust="spacingAndGlyphs" fill="#AE81FF">│</text>
|
|
58
|
+
<text x="144.8" y="189" textLength="9.65" lengthAdjust="spacingAndGlyphs" fill="#F8F8F2">║</text>
|
|
59
|
+
<text x="395.7" y="189" textLength="9.65" lengthAdjust="spacingAndGlyphs" fill="#F8F8F2">║</text>
|
|
60
|
+
<text x="434.2" y="189" textLength="9.65" lengthAdjust="spacingAndGlyphs" fill="#AE81FF">│</text>
|
|
61
|
+
<text x="67.5" y="208" textLength="9.65" lengthAdjust="spacingAndGlyphs" fill="#A6E22E">●</text>
|
|
62
|
+
<text x="77.2" y="208" textLength="28.95" lengthAdjust="spacingAndGlyphs" fill="#E6DB74">───</text>
|
|
63
|
+
<text x="106.2" y="208" textLength="9.65" lengthAdjust="spacingAndGlyphs" fill="#AE81FF">┤</text>
|
|
64
|
+
<text x="115.8" y="208" textLength="9.65" lengthAdjust="spacingAndGlyphs" fill="#FD971F">■</text>
|
|
65
|
+
<text x="144.8" y="208" textLength="9.65" lengthAdjust="spacingAndGlyphs" fill="#F8F8F2">║</text>
|
|
66
|
+
<text x="395.7" y="208" textLength="9.65" lengthAdjust="spacingAndGlyphs" fill="#F8F8F2">║</text>
|
|
67
|
+
<text x="424.6" y="208" textLength="9.65" lengthAdjust="spacingAndGlyphs" fill="#FD971F">■</text>
|
|
68
|
+
<text x="434.2" y="208" textLength="9.65" lengthAdjust="spacingAndGlyphs" fill="#AE81FF">├</text>
|
|
69
|
+
<text x="443.9" y="208" textLength="28.95" lengthAdjust="spacingAndGlyphs" fill="#E6DB74">───</text>
|
|
70
|
+
<text x="472.9" y="208" textLength="9.65" lengthAdjust="spacingAndGlyphs" fill="#A6E22E">●</text>
|
|
71
|
+
<text x="106.2" y="227" textLength="9.65" lengthAdjust="spacingAndGlyphs" fill="#AE81FF">│</text>
|
|
72
|
+
<text x="144.8" y="227" textLength="260.55" lengthAdjust="spacingAndGlyphs" fill="#F8F8F2">╚═════════════════════════╝</text>
|
|
73
|
+
<text x="434.2" y="227" textLength="9.65" lengthAdjust="spacingAndGlyphs" fill="#AE81FF">│</text>
|
|
74
|
+
<text x="67.5" y="246" textLength="9.65" lengthAdjust="spacingAndGlyphs" fill="#A6E22E">●</text>
|
|
75
|
+
<text x="77.2" y="246" textLength="28.95" lengthAdjust="spacingAndGlyphs" fill="#E6DB74">───</text>
|
|
76
|
+
<text x="106.2" y="246" textLength="9.65" lengthAdjust="spacingAndGlyphs" fill="#AE81FF">┤</text>
|
|
77
|
+
<text x="115.8" y="246" textLength="9.65" lengthAdjust="spacingAndGlyphs" fill="#FD971F">■</text>
|
|
78
|
+
<text x="183.3" y="246" textLength="9.65" lengthAdjust="spacingAndGlyphs" fill="#FD971F">▄</text>
|
|
79
|
+
<text x="241.2" y="246" textLength="9.65" lengthAdjust="spacingAndGlyphs" fill="#FD971F">▄</text>
|
|
80
|
+
<text x="270.2" y="246" textLength="9.65" lengthAdjust="spacingAndGlyphs" fill="#FD971F">▄</text>
|
|
81
|
+
<text x="299.2" y="246" textLength="9.65" lengthAdjust="spacingAndGlyphs" fill="#FD971F">▄</text>
|
|
82
|
+
<text x="357.1" y="246" textLength="9.65" lengthAdjust="spacingAndGlyphs" fill="#FD971F">▄</text>
|
|
83
|
+
<text x="424.6" y="246" textLength="9.65" lengthAdjust="spacingAndGlyphs" fill="#FD971F">■</text>
|
|
84
|
+
<text x="434.2" y="246" textLength="9.65" lengthAdjust="spacingAndGlyphs" fill="#AE81FF">├</text>
|
|
85
|
+
<text x="443.9" y="246" textLength="28.95" lengthAdjust="spacingAndGlyphs" fill="#E6DB74">───</text>
|
|
86
|
+
<text x="472.9" y="246" textLength="9.65" lengthAdjust="spacingAndGlyphs" fill="#A6E22E">●</text>
|
|
87
|
+
<text x="106.2" y="265" textLength="337.75" lengthAdjust="spacingAndGlyphs" fill="#AE81FF">╰───────┬─────┬──┬──┬─────┬───────╯</text>
|
|
88
|
+
<text x="164.1" y="284" textLength="28.95" lengthAdjust="spacingAndGlyphs" fill="#E6DB74">╭─╯</text>
|
|
89
|
+
<text x="241.2" y="284" textLength="9.65" lengthAdjust="spacingAndGlyphs" fill="#E6DB74">│</text>
|
|
90
|
+
<text x="270.2" y="284" textLength="9.65" lengthAdjust="spacingAndGlyphs" fill="#E6DB74">│</text>
|
|
91
|
+
<text x="299.2" y="284" textLength="9.65" lengthAdjust="spacingAndGlyphs" fill="#E6DB74">│</text>
|
|
92
|
+
<text x="357.1" y="284" textLength="28.95" lengthAdjust="spacingAndGlyphs" fill="#E6DB74">╰─╮</text>
|
|
93
|
+
<text x="67.5" y="303" textLength="9.65" lengthAdjust="spacingAndGlyphs" fill="#A6E22E">●</text>
|
|
94
|
+
<text x="77.2" y="303" textLength="38.60" lengthAdjust="spacingAndGlyphs" fill="#E6DB74">───╮</text>
|
|
95
|
+
<text x="135.1" y="303" textLength="9.65" lengthAdjust="spacingAndGlyphs" fill="#A6E22E">●</text>
|
|
96
|
+
<text x="144.8" y="303" textLength="28.95" lengthAdjust="spacingAndGlyphs" fill="#E6DB74">──╯</text>
|
|
97
|
+
<text x="241.2" y="303" textLength="9.65" lengthAdjust="spacingAndGlyphs" fill="#E6DB74">│</text>
|
|
98
|
+
<text x="270.2" y="303" textLength="9.65" lengthAdjust="spacingAndGlyphs" fill="#E6DB74">│</text>
|
|
99
|
+
<text x="299.2" y="303" textLength="9.65" lengthAdjust="spacingAndGlyphs" fill="#E6DB74">│</text>
|
|
100
|
+
<text x="376.4" y="303" textLength="28.95" lengthAdjust="spacingAndGlyphs" fill="#E6DB74">╰──</text>
|
|
101
|
+
<text x="405.3" y="303" textLength="9.65" lengthAdjust="spacingAndGlyphs" fill="#A6E22E">●</text>
|
|
102
|
+
<text x="434.2" y="303" textLength="38.60" lengthAdjust="spacingAndGlyphs" fill="#E6DB74">╭───</text>
|
|
103
|
+
<text x="472.9" y="303" textLength="9.65" lengthAdjust="spacingAndGlyphs" fill="#A6E22E">●</text>
|
|
104
|
+
<text x="106.2" y="322" textLength="9.65" lengthAdjust="spacingAndGlyphs" fill="#E6DB74">│</text>
|
|
105
|
+
<text x="212.3" y="322" textLength="38.60" lengthAdjust="spacingAndGlyphs" fill="#E6DB74">╭──╯</text>
|
|
106
|
+
<text x="270.2" y="322" textLength="9.65" lengthAdjust="spacingAndGlyphs" fill="#E6DB74">│</text>
|
|
107
|
+
<text x="299.2" y="322" textLength="38.60" lengthAdjust="spacingAndGlyphs" fill="#E6DB74">╰──╮</text>
|
|
108
|
+
<text x="434.2" y="322" textLength="9.65" lengthAdjust="spacingAndGlyphs" fill="#E6DB74">│</text>
|
|
109
|
+
<text x="106.2" y="341" textLength="9.65" lengthAdjust="spacingAndGlyphs" fill="#A6E22E">●</text>
|
|
110
|
+
<text x="212.3" y="341" textLength="9.65" lengthAdjust="spacingAndGlyphs" fill="#A6E22E">●</text>
|
|
111
|
+
<text x="270.2" y="341" textLength="9.65" lengthAdjust="spacingAndGlyphs" fill="#A6E22E">●</text>
|
|
112
|
+
<text x="328.1" y="341" textLength="9.65" lengthAdjust="spacingAndGlyphs" fill="#A6E22E">●</text>
|
|
113
|
+
<text x="434.2" y="341" textLength="9.65" lengthAdjust="spacingAndGlyphs" fill="#A6E22E">●</text>
|
|
114
|
+
</g>
|
|
115
|
+
<g transform="translate(225.4,201.7) scale(0.05244,-0.05244)" fill="#66D9EF">
|
|
116
|
+
<path transform="translate(0.0,0)" d="M56 0V720H216L619 240V720H776V0H616L211 482V0Z"/>
|
|
117
|
+
<path transform="translate(946.4,0)" d="M58 0V720H723V564H215V438H624V282H215V156H723V0Z"/>
|
|
118
|
+
<path transform="translate(1826.8,0)" d="M46 0V53L303 360L46 667V720H207L407 483L605 720H766V667L508 360L766 54V0H605L405 236L207 0Z"/>
|
|
119
|
+
<path transform="translate(2753.2,0)" d="M202 0Q161.5 0 127.75 20.0Q94 40 74.0 73.75Q54 107.5 54 148V720H209V156Q209 156 209.0 156.0Q209 156 209 156H617Q617 156 617.0 156.0Q617 156 617 156V720H774V148Q774 107.5 753.5 73.75Q733 40 699.5625 20.0Q666.125 0 626 0H202Z"/>
|
|
120
|
+
<path transform="translate(3695.7,0)" d="M202 0Q161.5 0 127.75 20.0Q94 40 74.0 73.75Q54 107.5 54 148V215H209V156Q209 156 209.0 156.0Q209 156 209 156H617Q617 156 617.0 156.0Q617 156 617 156V282Q617 282 617.0 282.0Q617 282 617 282H202Q161.5 282 127.75 302.0Q94 322 74.0 355.51724137931035Q54 389.0344827586207 54 430V572Q54 612.5 74.0 646.25Q94 680 127.75 700.0Q161.5 720 202 720H626Q666.125 720 699.5625 700.0Q733 680 753.5 646.25Q774 612.5 774 572V505H617V564Q617 564 617.0 564.0Q617 564 617 564H209Q209 564 209.0 564.0Q209 564 209 564V438Q209 438 209.0 438.0Q209 438 209 438H626Q666.125 438 699.5625 418.0Q733 398 753.5 364.48275862068965Q774 330.9655172413793 774 290V148Q774 107.5 753.5 73.75Q733 40 699.5625 20.0Q666.125 0 626 0Z"/>
|
|
121
|
+
</g>
|
|
122
|
+
<g transform="translate(70.0,460.8) scale(0.10911,-0.10911)" fill="#8F6A00">
|
|
123
|
+
<path transform="translate(0.0,0)" d="M204 0Q163 0 129.5 20.0Q96 40 76.0 73.5Q56 107 56 148V572Q56 613 76.0 646.5Q96 680 129.5 700.0Q163 720 204 720H774V564H244Q228 564 219.5 556.0Q211 548 211 531V189Q211 173 219.5 164.5Q228 156 244 156H774V0Z"/>
|
|
124
|
+
<path transform="translate(877.0,0)" d="M202 0Q161.5 0 127.75 20.0Q94 40 74.0 73.75Q54 107.5 54 148V572Q54 612.5 74.0 646.25Q94 680 127.75 700.0Q161.5 720 202 720H626Q666.125 720 699.5625 700.0Q733 680 753.5 646.25Q774 612.5 774 572V148Q774 107.5 753.5 73.75Q733 40 699.5625 20.0Q666.125 0 626 0ZM209 156H617Q617 156 617.0 156.0Q617 156 617 156V564Q617 564 617.0 564.0Q617 564 617 564H209Q209 564 209.0 564.0Q209 564 209 564V156Q209 156 209.0 156.0Q209 156 209 156Z"/>
|
|
125
|
+
<path transform="translate(1760.0,0)" d="M615 0 406 249H609L775 53V0ZM56 0V719H627Q667.5 719 701.25 699.0Q735 679 755.5 645.0Q776 611 776 571V385Q776 345 755.5 311.0Q735 277 701.25 257.0Q667.5 237 627 237L211 236V0ZM211 393H619Q619 393 619.0 393.0Q619 393 619 393V564Q619 564 619.0 564.0Q619 564 619 564H211Q211 564 211.0 564.0Q211 564 211 564V393Q211 393 211.0 393.0Q211 393 211 393Z"/>
|
|
126
|
+
<path transform="translate(2640.0,0)" d="M302 0V564H20V720H740V564H458V0Z"/>
|
|
127
|
+
<path transform="translate(3454.0,0)" d="M58 0V720H723V564H215V438H624V282H215V156H723V0Z"/>
|
|
128
|
+
<path transform="translate(4274.9,0)" d="M46 0V53L303 360L46 667V720H207L407 483L605 720H766V667L508 360L766 54V0H605L405 236L207 0Z"/>
|
|
129
|
+
</g>
|
|
130
|
+
<g transform="translate(66.5,457.3) scale(0.10911,-0.10911)" fill="#FFC600">
|
|
131
|
+
<path transform="translate(0.0,0)" d="M204 0Q163 0 129.5 20.0Q96 40 76.0 73.5Q56 107 56 148V572Q56 613 76.0 646.5Q96 680 129.5 700.0Q163 720 204 720H774V564H244Q228 564 219.5 556.0Q211 548 211 531V189Q211 173 219.5 164.5Q228 156 244 156H774V0Z"/>
|
|
132
|
+
<path transform="translate(877.0,0)" d="M202 0Q161.5 0 127.75 20.0Q94 40 74.0 73.75Q54 107.5 54 148V572Q54 612.5 74.0 646.25Q94 680 127.75 700.0Q161.5 720 202 720H626Q666.125 720 699.5625 700.0Q733 680 753.5 646.25Q774 612.5 774 572V148Q774 107.5 753.5 73.75Q733 40 699.5625 20.0Q666.125 0 626 0ZM209 156H617Q617 156 617.0 156.0Q617 156 617 156V564Q617 564 617.0 564.0Q617 564 617 564H209Q209 564 209.0 564.0Q209 564 209 564V156Q209 156 209.0 156.0Q209 156 209 156Z"/>
|
|
133
|
+
<path transform="translate(1760.0,0)" d="M615 0 406 249H609L775 53V0ZM56 0V719H627Q667.5 719 701.25 699.0Q735 679 755.5 645.0Q776 611 776 571V385Q776 345 755.5 311.0Q735 277 701.25 257.0Q667.5 237 627 237L211 236V0ZM211 393H619Q619 393 619.0 393.0Q619 393 619 393V564Q619 564 619.0 564.0Q619 564 619 564H211Q211 564 211.0 564.0Q211 564 211 564V393Q211 393 211.0 393.0Q211 393 211 393Z"/>
|
|
134
|
+
<path transform="translate(2640.0,0)" d="M302 0V564H20V720H740V564H458V0Z"/>
|
|
135
|
+
<path transform="translate(3454.0,0)" d="M58 0V720H723V564H215V438H624V282H215V156H723V0Z"/>
|
|
136
|
+
<path transform="translate(4274.9,0)" d="M46 0V53L303 360L46 667V720H207L407 483L605 720H766V667L508 360L766 54V0H605L405 236L207 0Z"/>
|
|
137
|
+
</g>
|
|
138
|
+
<text x="344.0" y="499" text-anchor="middle" font-family="ui-monospace,SFMono-Regular,Menlo,Consolas,monospace" font-size="13" letter-spacing="3" fill="#75715E">HEADLESS MULTI-PROVIDER AI AGENT HARNESS</text>
|
|
139
|
+
<text x="344.0" y="521" text-anchor="middle" font-family="ui-monospace,SFMono-Regular,Menlo,Consolas,monospace" font-size="12" fill="#75715E">Anthropic • OpenAI • Google • XAI • DeepSeek</text>
|
|
140
|
+
</svg>
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# Authentication & API Keys
|
|
2
|
+
|
|
3
|
+
The easiest way to add a key is the interactive setup — it runs automatically the first
|
|
4
|
+
time you start `cortex`, or any time on demand:
|
|
5
|
+
|
|
6
|
+
```bash
|
|
7
|
+
cortex config init
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
It asks which provider you use, takes your API key, and picks a default model — saving them
|
|
11
|
+
to `~/.cortex/.env` (a global config, so `cortex` works from any folder). The file is written
|
|
12
|
+
user-only (`chmod 600`) and is never committed.
|
|
13
|
+
|
|
14
|
+
### Where config is read from
|
|
15
|
+
|
|
16
|
+
Cortex loads, in priority order: a `.env` in your current folder → the package dir →
|
|
17
|
+
`~/.cortex/.env` (the global config) → plain environment variables. So you can also just
|
|
18
|
+
export a variable instead of using the wizard:
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
export ANTHROPIC_API_KEY=sk-ant-…
|
|
22
|
+
export DEFAULT_MODEL_ID=claude-sonnet-4-6
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
> **Set a `DEFAULT_MODEL_ID` that matches your key.** The built-in default is a Gemini model,
|
|
26
|
+
> so an Anthropic key alone won't be used until you also set the model (the wizard does this
|
|
27
|
+
> for you).
|
|
28
|
+
|
|
29
|
+
## Provider API keys
|
|
30
|
+
|
|
31
|
+
| Variable | Provider | Example default model |
|
|
32
|
+
|----------|----------|-----------------------|
|
|
33
|
+
| `ANTHROPIC_API_KEY` | Claude (Anthropic) | `claude-sonnet-4-6` |
|
|
34
|
+
| `OPENAI_API_KEY` | OpenAI (GPT / o-series) | `gpt-5-mini` |
|
|
35
|
+
| `GEMINI_API_KEY` (or `GOOGLE_API_KEY`) | Google Gemini | `gemini-2.5-flash` |
|
|
36
|
+
| `XAI_API_KEY` | xAI (Grok) | `grok-4.3` |
|
|
37
|
+
| `DEEPSEEK_API_KEY` | DeepSeek | `deepseek-v4-pro` |
|
|
38
|
+
|
|
39
|
+
Other providers (Cloudflare Workers AI, Zhipu/GLM, Qwen, Moonshot/Kimi, MiniMax, Mercury)
|
|
40
|
+
use the same pattern. Run `cortex models list` for the live set.
|
|
41
|
+
|
|
42
|
+
## Claude: API key *or* OAuth
|
|
43
|
+
|
|
44
|
+
Claude works two ways — pick one:
|
|
45
|
+
|
|
46
|
+
- **API key** — set `ANTHROPIC_API_KEY=sk-ant-…` in `.env`. Done.
|
|
47
|
+
- **OAuth** — use a Claude.ai Pro/Max subscription instead of a metered API key (below).
|
|
48
|
+
|
|
49
|
+
You can pin the method with `ANTHROPIC_AUTH_METHOD=auto|oauth|api-key` (default `auto`).
|
|
50
|
+
The resolution order under `auto` is:
|
|
51
|
+
|
|
52
|
+
```
|
|
53
|
+
~/.claude/.credentials.json → CLAUDE_CODE_OAUTH_TOKEN → ANTHROPIC_API_KEY
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### Claude OAuth setup
|
|
57
|
+
|
|
58
|
+
There are two ways to provide the OAuth token; the harness checks them in this order.
|
|
59
|
+
|
|
60
|
+
**1. `~/.claude/.credentials.json` (preferred)**
|
|
61
|
+
|
|
62
|
+
This file is created automatically when you sign in with the Claude Code CLI:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
claude login
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
If you've already done that, the harness reads it as-is — nothing else to do. It lives in
|
|
69
|
+
your home directory (not the project), is written owner-only (`chmod 600`), and includes a
|
|
70
|
+
refresh token so it renews itself.
|
|
71
|
+
|
|
72
|
+
To create it by hand instead:
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
mkdir -p ~/.claude && chmod 700 ~/.claude
|
|
76
|
+
cat > ~/.claude/.credentials.json <<'JSON'
|
|
77
|
+
{ "claudeAiOauth": {
|
|
78
|
+
"accessToken": "sk-ant-oat01-…",
|
|
79
|
+
"refreshToken": "sk-ant-ort01-…",
|
|
80
|
+
"expiresAt": 1765400000000,
|
|
81
|
+
"scopes": ["user:inference"] } }
|
|
82
|
+
JSON
|
|
83
|
+
chmod 600 ~/.claude/.credentials.json
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
**2. `CLAUDE_CODE_OAUTH_TOKEN` (headless / CI)**
|
|
87
|
+
|
|
88
|
+
Set a bare token in `.env` (or the environment) — handy where there's no `claude login`:
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
CLAUDE_CODE_OAUTH_TOKEN=sk-ant-oat01-…
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
The OAuth token is **never** written to any project file — keep it in the home-directory
|
|
95
|
+
credentials file or in `.env`, both of which stay outside version control.
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
# Configuration reference
|
|
2
|
+
|
|
3
|
+
Every Nexus Cortex setting is an environment variable, read from `.env` (or the process environment) at startup.
|
|
4
|
+
|
|
5
|
+
> **Canonical sources:** [`.env.example`](../.env.example) is the annotated template, and `packages/core/src/config/SettingsSchema.ts` is the schema (defaults + valid choices). This page mirrors them for browsing — if anything here disagrees, those win.
|
|
6
|
+
|
|
7
|
+
Per-launch overrides win — e.g. `DEFAULT_MODEL_ID=grok-4.3 PORT=4100 node packages/server/dist/index.js`. Booleans are the literal strings `true`/`false`. Only API keys are required; every other variable has a proven-optimal default.
|
|
8
|
+
|
|
9
|
+
#### API keys & authentication
|
|
10
|
+
|
|
11
|
+
Set the keys for the providers you use; leave the rest blank. A model is only available if its provider key is present.
|
|
12
|
+
|
|
13
|
+
| Variable | Default | What it does / how to use it |
|
|
14
|
+
|----------|---------|------------------------------|
|
|
15
|
+
| `ANTHROPIC_API_KEY` | — | Claude (Fable/Opus/Sonnet/Haiku) models. |
|
|
16
|
+
| `OPENAI_API_KEY` | — | GPT / o-series models. |
|
|
17
|
+
| `GOOGLE_API_KEY` | — | Gemini models (legacy key; `GEMINI_API_KEY` takes priority). |
|
|
18
|
+
| `GEMINI_API_KEY` | — | Preferred Gemini key; falls back to `GOOGLE_API_KEY`. |
|
|
19
|
+
| `XAI_API_KEY` | — | xAI Grok models. |
|
|
20
|
+
| `DEEPSEEK_API_KEY` | — | DeepSeek models (the default model's provider). |
|
|
21
|
+
| `NVIDIA_API_KEY` | — | Reserved for NVIDIA-hosted models (no standalone NVIDIA cards are registered yet; NVIDIA models are currently reached via Cloudflare). |
|
|
22
|
+
| `INCEPTION_API_KEY` | — | Inception Labs Mercury diffusion models (`mercury-2`). |
|
|
23
|
+
| `CLOUDFLARE_API_TOKEN` | — | Cloudflare Workers AI (`@cf/*` models). Requires `CLOUDFLARE_ACCOUNT_ID`. |
|
|
24
|
+
| `CLOUDFLARE_ACCOUNT_ID` | — | Cloudflare account ID (paired with the token above). |
|
|
25
|
+
| `DASHSCOPE_API_KEY` | — | Alibaba Qwen (DashScope) — `qwen-*` models. |
|
|
26
|
+
| `MINIMAX_API_KEY` | — | MiniMax — `minimax-*` models. |
|
|
27
|
+
| `MOONSHOT_API_KEY` | — | Moonshot AI (Kimi) — `moonshot-*` / `kimi-*` models. |
|
|
28
|
+
| `ZHIPU_API_KEY` | — | Zhipu AI (GLM) — `glm-*` models. |
|
|
29
|
+
| `HUGGINGFACE_API_KEY` | — | Reserved for Hugging Face Inference (`HUGGINGFACE_TOKEN` also accepted; cards exist but are not registered in the default build yet). |
|
|
30
|
+
| `ANTHROPIC_AUTH_METHOD` | `auto` | `auto` (oauth→key) \| `oauth` \| `api-key`. `.env.example` ships `api-key`; use `oauth` with a Claude.ai Max subscription. |
|
|
31
|
+
| `CLAUDE_CODE_OAUTH_TOKEN` | — | OAuth token override (alternative to `~/.claude/.credentials.json`). |
|
|
32
|
+
|
|
33
|
+
#### Model selection
|
|
34
|
+
|
|
35
|
+
| Variable | Default | What it does / how to use it |
|
|
36
|
+
|----------|---------|------------------------------|
|
|
37
|
+
| `DEFAULT_MODEL_ID` | `deepseek-v4-pro` | Primary model — any registry ID or alias (`cortex models list`). |
|
|
38
|
+
| `HELPER_MODEL_ID` | `deepseek-v4-flash` | Cheaper model for compaction & mentorship. |
|
|
39
|
+
| `WEB_TOOLS_MODEL` | `gemini-2.5-flash` | Model backing `WebSearch`/`WebFetch`; provider auto-detected from the ID prefix. |
|
|
40
|
+
|
|
41
|
+
#### System
|
|
42
|
+
|
|
43
|
+
| Variable | Default | What it does / how to use it |
|
|
44
|
+
|----------|---------|------------------------------|
|
|
45
|
+
| `DEBUG` | `false` | Verbose logging (system-message assembly, routes). Toggle at runtime via `/debug`. |
|
|
46
|
+
| `USE_EMOJI` | `false` | Allow emoji in CLI output. |
|
|
47
|
+
| `PROJECT_PATH` | cwd | Project root the tools operate on. |
|
|
48
|
+
| `PROJECT_ROOT` | `PROJECT_PATH`/cwd | Explicit override of the project root (set by the server at startup). |
|
|
49
|
+
|
|
50
|
+
#### Reactive mentorship (AI-to-AI self-improvement)
|
|
51
|
+
|
|
52
|
+
| Variable | Default | What it does / how to use it |
|
|
53
|
+
|----------|---------|------------------------------|
|
|
54
|
+
| `MENTORSHIP_ENABLED` | `false` | Master switch for the mentorship system. |
|
|
55
|
+
| `MENTORSHIP_TRIGGER_ON_ERROR` | `true` | Trigger helper-model review on tool errors (only applies when mentorship is enabled). |
|
|
56
|
+
| `MENTORSHIP_ERROR_THRESHOLD` | `medium` | Minimum severity to trigger: `low` \| `medium` \| `high`. |
|
|
57
|
+
| `MENTORSHIP_KEYWORDS_ENABLED` | `false` | React to `@ultrathink` / `@analyze` / `@rethink`. |
|
|
58
|
+
| `MENTORSHIP_CUSTOM_KEYWORDS` | — | Comma-separated extra trigger keywords. |
|
|
59
|
+
| `MENTORSHIP_HELPER_MODEL` | `deepseek-v4-flash` | Model used for mentorship, overriding `HELPER_MODEL_ID` (`.env.example` ships a Cloudflare Gemma override). |
|
|
60
|
+
| `MENTORSHIP_TURN_BASED_ENABLED` | `false` | Periodic review every N turns. |
|
|
61
|
+
| `MENTORSHIP_TURN_INTERVAL` | `10` | Turns between periodic reviews (1–50). |
|
|
62
|
+
| `MENTORSHIP_INTERLEAVED_THINKING` | `false` | Inject thinking for non-reasoning models. |
|
|
63
|
+
| `MENTORSHIP_PATTERN_DETECTION` | `false` | Detect repeated failure patterns. |
|
|
64
|
+
| `MENTORSHIP_PATTERN_THRESHOLD` | `3` | Similar errors needed to flag a pattern (2–10). |
|
|
65
|
+
| `MENTORSHIP_ACTIVE_DISCOVERY` | `false` | Proactive mentorship discovery (runtime flag). |
|
|
66
|
+
| `TURN_SUMMARY_PREDICTION` | `false` | Post-turn summary + next-action prediction via the helper model. |
|
|
67
|
+
|
|
68
|
+
#### Context management
|
|
69
|
+
|
|
70
|
+
| Variable | Default | What it does / how to use it |
|
|
71
|
+
|----------|---------|------------------------------|
|
|
72
|
+
| `ANTHROPIC_PROMPT_CACHING` | `true` | Enable Anthropic prompt caching (up to ~90% input-token savings). |
|
|
73
|
+
| `CONTEXT_BUDGET_STRATEGY` | `priority-based` | `priority-based` (keeps tool pairs) or `sliding-window` (dumb recency). |
|
|
74
|
+
|
|
75
|
+
#### Session
|
|
76
|
+
|
|
77
|
+
| Variable | Default | What it does / how to use it |
|
|
78
|
+
|----------|---------|------------------------------|
|
|
79
|
+
| `SESSION_STORAGE_DIR` | `.cortex/sessions` | Where JSONL session files are written. |
|
|
80
|
+
| `MCP_AUTO_INJECT` | `false` | Auto-inject connected MCP servers' tools into every turn. |
|
|
81
|
+
| `SYSTEM_MESSAGE_DOC_MAX_BYTES` | `0` | Per-doc byte cap for injected project docs (CORTEX.md, MEMORY.md). `0` = unlimited. |
|
|
82
|
+
|
|
83
|
+
#### Loop control
|
|
84
|
+
|
|
85
|
+
| Variable | Default | What it does / how to use it |
|
|
86
|
+
|----------|---------|------------------------------|
|
|
87
|
+
| `MAX_TOOL_ITERATIONS` | `50` | Max tool executions per turn. |
|
|
88
|
+
| `MAX_CONSECUTIVE_ERRORS` | `3` | Stop the turn after this many consecutive all-error iterations. |
|
|
89
|
+
| `TOOL_BUDGET_SOFT` | `15` | Soft per-turn tool-call budget (decisiveness brake). |
|
|
90
|
+
| `TOOL_TIMEOUT_MS` | `120000` | Per-tool execution timeout (ms). |
|
|
91
|
+
| `MAX_LOOP_REPETITIONS` | `5` | Identical tool calls before loop detection breaks the turn. |
|
|
92
|
+
|
|
93
|
+
#### Provider tooling
|
|
94
|
+
|
|
95
|
+
| Variable | Default | What it does / how to use it |
|
|
96
|
+
|----------|---------|------------------------------|
|
|
97
|
+
| `ENABLE_SERVER_SIDE_TOOLS` | `true` | xAI/OpenAI hosted server-side tools (hybrid is ~20–26% faster). |
|
|
98
|
+
| `XAI_API_MODE` | `messages` | xAI request surface: `messages` (CC-style) or `responses` (server-side tools). |
|
|
99
|
+
| `OPENAI_API_MODE` | `chat/completions` | OpenAI request surface: `chat/completions` or `responses` (opt into hosted server-side tools). |
|
|
100
|
+
| `ENABLE_DEFERRED_TOOL_LOADING` | `true` | Load only essential tools up front; discover the rest via `SearchTools` (~77% first-turn input-token cut). |
|
|
101
|
+
| `ENABLE_PTC` | `false` | Programmatic tool calling (compose tool calls in a script). |
|
|
102
|
+
| `ENABLE_LOCAL_CODE_EXECUTION` | `false` | Allow local code-execution tooling. |
|
|
103
|
+
|
|
104
|
+
#### Model router (auto model selection)
|
|
105
|
+
|
|
106
|
+
| Variable | Default | What it does / how to use it |
|
|
107
|
+
|----------|---------|------------------------------|
|
|
108
|
+
| `MODEL_ROUTER_ENABLED` | `false` | Auto-route `model="auto"` requests from benchmark history. |
|
|
109
|
+
| `MODEL_ROUTER_STRATEGY` | `auto` | `auto` (classify the prompt) or `matrix-only` (require an explicit task type). |
|
|
110
|
+
| `MODEL_ROUTER_RECORD` | `true` | Record turn metrics to `.cortex/router-matrix.jsonl` (independent of routing being on). |
|
|
111
|
+
| `MODEL_ROUTER_EXCLUDE` | `grok*` | Comma list of model IDs the router must never pick; trailing `*` = prefix wildcard. |
|
|
112
|
+
| `MODEL_ROUTER_EXPLORATION` | `false` | Posterior-sampling explore/exploit instead of a greedy pick. |
|
|
113
|
+
| `ROUTER_MIN_CONFIDENCE` | `0.3` | Min task-classification confidence (0–1) before `auto` routes; below it, inherit the parent model. |
|
|
114
|
+
| `ROUTER_MIN_SAMPLES` | `3` | Min benchmark samples a task type needs before `auto` trusts its recommendation. |
|
|
115
|
+
|
|
116
|
+
#### End-of-turn audit / training substrate (opt-in)
|
|
117
|
+
|
|
118
|
+
| Variable | Default | What it does / how to use it |
|
|
119
|
+
|----------|---------|------------------------------|
|
|
120
|
+
| `CORTEX_ENDTURN_GATE` | `false` | `true` = mandatory `EndTurn` self-audit + graded training records. Off = the tool is hidden. |
|
|
121
|
+
|
|
122
|
+
#### Decision store (prior recall)
|
|
123
|
+
|
|
124
|
+
| Variable | Default | What it does / how to use it |
|
|
125
|
+
|----------|---------|------------------------------|
|
|
126
|
+
| `CORTEX_RECORD_DECISIONS` | `true` | Append each tool decision to `.cortex/decisions.jsonl`. |
|
|
127
|
+
| `CORTEX_LOOKUP_PRIOR_DECISIONS` | `true` | Inject prior decisions as a `<system-reminder>` before tool use. |
|
|
128
|
+
| `CORTEX_DECISIONS_MAX_BYTES` | `2097152` | Rotation cap (bytes) for `decisions.jsonl` (default 2 MB). |
|
|
129
|
+
| `CORTEX_GIT_CONTEXT` | `true` | Per-turn "Repository State" note (branch/status/recent commits + cross-agent staleness warnings). |
|
|
130
|
+
|
|
131
|
+
#### Orchestrator mode
|
|
132
|
+
|
|
133
|
+
| Variable | Default | What it does / how to use it |
|
|
134
|
+
|----------|---------|------------------------------|
|
|
135
|
+
| `CORTEX_MODE` | `persistent` | `persistent` \| `stateless` (clean per request) \| `server` (HTTP client). |
|
|
136
|
+
| `CORTEX_SERVER_URL` | `http://localhost:4000` | Server endpoint when `CORTEX_MODE=server`. |
|
|
137
|
+
|
|
138
|
+
#### Agent workspace
|
|
139
|
+
|
|
140
|
+
| Variable | Default | What it does / how to use it |
|
|
141
|
+
|----------|---------|------------------------------|
|
|
142
|
+
| `AGENT_TMUX_MONITOR` | `false` | tmux visual monitoring for parallel agent teams (one live pane per agent). |
|
|
143
|
+
|
|
144
|
+
#### Git / PR access control
|
|
145
|
+
|
|
146
|
+
Governs the `PRAgent` & `WorkspaceManager` tools and the `/v1/pr/*` routes. Input-format validation (which blocks shell/argument injection) is **always** on; the allow-lists are opt-in defense-in-depth.
|
|
147
|
+
|
|
148
|
+
| Variable | Default | What it does / how to use it |
|
|
149
|
+
|----------|---------|------------------------------|
|
|
150
|
+
| `GIT_ALLOWED_REPOS` | — (all) | Comma list of `owner/repo` (supports `owner/*`, `*`). Unset = all repos allowed + a startup warning. Restrict for shared deployments, e.g. `me/app,me/*`. |
|
|
151
|
+
| `GIT_ALLOWED_ACTIONS` | — (all) | Comma list of allowed actions: `review,list,create,post-review,clone,worktree,diff,cleanup,status`. |
|
|
152
|
+
| `GIT_AUTH_TOKEN` | — | Token for gh/git. Injected into the subprocess env (`GH_TOKEN`/`GITHUB_TOKEN`) only — never on argv or in a URL. Unset = use `gh`'s own auth. |
|
|
153
|
+
| `GIT_HOST` | `github.com` | GitHub Enterprise host for the git/PR tools. |
|
|
154
|
+
| `GITHUB_WEBHOOK_SECRET` | — | HMAC secret for `/v1/pr/webhook` (`X-Hub-Signature-256`). Unset = the webhook is disabled (401). |
|
|
155
|
+
|
|
156
|
+
#### Server lifecycle
|
|
157
|
+
|
|
158
|
+
| Variable | Default | What it does / how to use it |
|
|
159
|
+
|----------|---------|------------------------------|
|
|
160
|
+
| `PORT` | `4000` | HTTP server port (falls back to the next free port if taken). |
|
|
161
|
+
| `AUTO_RESUME` | `false` | `true` = resume the most recent session on boot. |
|
|
162
|
+
| `RESUME_SESSION_ID` | — | Resume a specific session UUID (overrides `AUTO_RESUME`). |
|
|
163
|
+
| `SERVER_IDLE_TIMEOUT` | `0` | Seconds of inactivity before auto-shutdown. `0` = never (always-on daemon). |
|
|
164
|
+
| `SHUTDOWN_GRACE_MS` | `10000` | Max ms to drain in-flight connections on shutdown (`0` = wait indefinitely). |
|
|
165
|
+
| `ENABLE_DASHBOARD` | `false` | Eagerly start the sandbox+tmux dashboard (binds an extra port). Tools still start it lazily when needed. |
|
|
166
|
+
| `DASHBOARD_PORT` | `4001` | Dashboard port (whether started eagerly or lazily). |
|
|
167
|
+
|
|
168
|
+
#### Runtime flags & debug
|
|
169
|
+
|
|
170
|
+
| Variable | Default | What it does / how to use it |
|
|
171
|
+
|----------|---------|------------------------------|
|
|
172
|
+
| `YOLO` | `false` | Auto-approve **all** tool executions (bypasses the permission system). |
|
|
173
|
+
| `DEBUG_PAYLOAD` | `false` | Log raw API request/response payloads. |
|
|
174
|
+
| `DEBUG_SYSTEM_MESSAGES` | `false` | Verbose system-message assembly logging (also on with `DEBUG=true`). |
|
|
175
|
+
| `DEBUG_THINKING` | `false` | Show thinking/reasoning in the CLI. On Anthropic adaptive-thinking models, `true` requests summarized reasoning and **bills extra output tokens**; `false` keeps it omitted ($0). |
|
|
176
|
+
| `ENABLE_SMOKE_TESTS` | `false` | Run real-API smoke tests instead of mocked ones. |
|
|
177
|
+
|
|
178
|
+
#### Tool & path overrides
|
|
179
|
+
|
|
180
|
+
| Variable | Default | What it does / how to use it |
|
|
181
|
+
|----------|---------|------------------------------|
|
|
182
|
+
| `CHROMIUM_BIN` | auto | Override the Chromium binary for web/browse tools. |
|
|
183
|
+
| `PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH` | auto | Alternate Chromium path honored by Playwright. |
|
|
184
|
+
| `TMUX_BIN` | auto | Override the tmux binary for visual agent monitoring. |
|
|
185
|
+
| `GOOGLE_CLOUD_PROJECT` | — | Vertex AI project (only when using Vertex instead of the Gemini API). |
|
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
# Nexus Cortex — User Guide
|
|
2
|
+
|
|
3
|
+
The full headless workflow: the `cortex` CLI, the HTTP agent server, the REST API, sessions,
|
|
4
|
+
PR review, deployment, and troubleshooting. For setup see the [README](../README.md); for
|
|
5
|
+
internals see [Architecture](architecture.md).
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
The simplest install is the `nexus-cortex` meta-package — it pulls in the `cortex` CLI and the
|
|
10
|
+
HTTP server together:
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
npm install -g nexus-cortex
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
Prefer to install the components yourself? They're published individually:
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npm install -g @nexus-cortex/cli @nexus-cortex/server
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
From source (`npm run build` auto-links the global commands):
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
npm install && npm run build # multi-pass build, then links `cortex`
|
|
26
|
+
npm run link # re-link any time (self-healing)
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### Embed the library
|
|
30
|
+
|
|
31
|
+
To drive the orchestrator in your own code instead of through the CLI:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
npm install @nexus-cortex/core @nexus-cortex/executors
|
|
35
|
+
```
|
|
36
|
+
```typescript
|
|
37
|
+
import { CortexOrchestrator } from '@nexus-cortex/core';
|
|
38
|
+
|
|
39
|
+
const cortex = new CortexOrchestrator({
|
|
40
|
+
modelId: 'claude-sonnet-4-6',
|
|
41
|
+
projectPath: process.cwd(),
|
|
42
|
+
});
|
|
43
|
+
const res = await cortex.processMessage({ role: 'user', content: 'Analyze this codebase' });
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## The `cortex` CLI
|
|
47
|
+
|
|
48
|
+
`cortex` is a headless command — one-shot or multi-turn natural-language queries, plus a
|
|
49
|
+
full structured command set. The first query **auto-starts a local server**; it persists in
|
|
50
|
+
the background and subsequent calls share one stateful session.
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
# Simple query
|
|
54
|
+
cortex "What is this project?"
|
|
55
|
+
|
|
56
|
+
# Specific model
|
|
57
|
+
cortex --model deepseek-v4-flash "Explain TypeScript generics"
|
|
58
|
+
|
|
59
|
+
# Multi-turn (session persists automatically)
|
|
60
|
+
cortex "Remember the launch code is FALCON-42"
|
|
61
|
+
cortex "What was the launch code?"
|
|
62
|
+
|
|
63
|
+
# JSON output for scripting and agent workflows
|
|
64
|
+
cortex --json "List the npm scripts" | jq '.content[0].text'
|
|
65
|
+
|
|
66
|
+
# Session management
|
|
67
|
+
cortex --sessions # List all sessions
|
|
68
|
+
cortex --stats # Current session stats
|
|
69
|
+
cortex --new "Start a fresh conversation" # New session
|
|
70
|
+
cortex --resume SESSION_ID "Continue here" # Resume a specific session
|
|
71
|
+
cortex --quiet "Just the answer" # Response only, no metadata
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Autonomous agent (one-shot)
|
|
75
|
+
|
|
76
|
+
`cortex agent` (alias `cortex run`) runs one task to completion and exits — fresh session,
|
|
77
|
+
auto-approves tools (headless has no interactive approver), self-stops the server on idle.
|
|
78
|
+
Point it at a throwaway/worktree/sandbox dir on a real repo.
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
cortex agent "summarize the test gaps in this repo"
|
|
82
|
+
cortex agent --cwd ./feature-branch "add a --version flag and run the tests"
|
|
83
|
+
cortex run --json "fix the failing lint" | jq '.toolUses[].name'
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### Command groups
|
|
87
|
+
|
|
88
|
+
Run `cortex --help`, or `cortex <group> --help` for any group:
|
|
89
|
+
|
|
90
|
+
| Group | What it does |
|
|
91
|
+
|-------|--------------|
|
|
92
|
+
| `cortex "<prompt>"` | One-shot query (`-m/--model`, `--system`, `--max-tokens`, `--json`) |
|
|
93
|
+
| `cortex agent` / `run` | Autonomous one-shot agent (`--cwd`, `--json`) |
|
|
94
|
+
| `models` | `list` / `info` / `search` / `compare` / `cost` / `providers` / `switch` |
|
|
95
|
+
| `sessions` | `list` / `view` / `export` / `resume` / `checkpoints` / `stats` / `search` / `compact` |
|
|
96
|
+
| `config` | `get` / `set` / `categories` / `category` / `reset` |
|
|
97
|
+
| `mcp` | `list` / `status` / `tools` / `enable` / `disable` / `init` / `validate` / `edit` |
|
|
98
|
+
| `permissions` | `mode` / `set` / `grant` / `revoke` / `policies` / `tools` / `auto-approve` |
|
|
99
|
+
| `autoresearch` | `bench` / `experiment` / `evaluate` / `fix` / `list` |
|
|
100
|
+
| `context` | `status` / `compact` / `boundaries` / `strategy` / `savings` |
|
|
101
|
+
| `middleware` | `list` / `status` / `enable` / `disable` / `config` |
|
|
102
|
+
| `artifact` | `list` / `status` / `restart` / `stop` |
|
|
103
|
+
| `tmux` | `list` |
|
|
104
|
+
| `tools` | `list` / `info` |
|
|
105
|
+
| `cache` | `metrics` |
|
|
106
|
+
| `system-messages` | `list` / `view` / `reload` |
|
|
107
|
+
| `server` | `status` / `start` |
|
|
108
|
+
|
|
109
|
+
### Agent team usage
|
|
110
|
+
|
|
111
|
+
The session ID enables multi-turn agent workflows:
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
SESSION=$(cortex --quiet --json "Analyze test gaps" | jq -r '.sessionId')
|
|
115
|
+
cortex --resume $SESSION "Now fix the top priority gap"
|
|
116
|
+
cortex --resume $SESSION "Run the tests to verify"
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
> **Interactive terminal UIs — Release 2.** A React/Ink chat UI (`neoncortex`), a Chalk UI
|
|
120
|
+
> (`fuzzycortex`), the slash-command set, and a color-theme system ship in `@nexus-cortex/tui`
|
|
121
|
+
> in the next release. Release 1 is headless-only.
|
|
122
|
+
|
|
123
|
+
## Running the HTTP server
|
|
124
|
+
|
|
125
|
+
The server is a **stateful agent** — sequential requests share one persistent session with
|
|
126
|
+
full conversation history, tool execution, and context management. No terminal UI required.
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
# Production (uses DEFAULT_MODEL_ID from .env)
|
|
130
|
+
cortex-server &
|
|
131
|
+
# or, from source:
|
|
132
|
+
node packages/server/dist/index.js &
|
|
133
|
+
|
|
134
|
+
# Override model at launch
|
|
135
|
+
DEFAULT_MODEL_ID=grok-4-1-fast-reasoning cortex-server &
|
|
136
|
+
|
|
137
|
+
# Dev mode (auto-restart on code changes, auto-resumes session)
|
|
138
|
+
cd packages/server && npm run dev
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
Port 4000 = API server. The HTML dashboard (sandbox/tmux viewer, port 4001) is opt-in: set
|
|
142
|
+
`ENABLE_DASHBOARD=true` — a master switch, so when off no second port is ever bound.
|
|
143
|
+
|
|
144
|
+
### Direct HTTP (curl)
|
|
145
|
+
|
|
146
|
+
```bash
|
|
147
|
+
# Send a message
|
|
148
|
+
curl -s http://localhost:4000/v1/messages \
|
|
149
|
+
-H "Content-Type: application/json" \
|
|
150
|
+
-d '{"model":"grok-4-1-fast-reasoning","messages":[{"role":"user","content":"Read package.json and tell me the version"}]}'
|
|
151
|
+
|
|
152
|
+
# Multi-turn: the next request continues the same conversation
|
|
153
|
+
curl -s http://localhost:4000/v1/messages \
|
|
154
|
+
-H "Content-Type: application/json" \
|
|
155
|
+
-d '{"model":"grok-4-1-fast-reasoning","messages":[{"role":"user","content":"What dependencies does it have?"}]}'
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
### Response fields
|
|
159
|
+
|
|
160
|
+
| Field | Description |
|
|
161
|
+
|-------|-------------|
|
|
162
|
+
| `content[]` | Model text response |
|
|
163
|
+
| `toolUses[]` | Tools called (name, input, result) |
|
|
164
|
+
| `usage.inputTokens` | Total input tokens (reveals system message overhead) |
|
|
165
|
+
| `usage.outputTokens` | Response size |
|
|
166
|
+
| `usage.cache` | Cache hit rate and cost savings |
|
|
167
|
+
| `metadata.toolCallIterations` | Tool round-trips |
|
|
168
|
+
|
|
169
|
+
### Session management API
|
|
170
|
+
|
|
171
|
+
| Endpoint | Method | Description |
|
|
172
|
+
|----------|--------|-------------|
|
|
173
|
+
| `/sessions` | GET | List all sessions |
|
|
174
|
+
| `/sessions/new` | POST | Start fresh session (old one saved) |
|
|
175
|
+
| `/sessions/:id/stats` | GET | Token usage, turns, tool calls |
|
|
176
|
+
| `/sessions/:id/messages` | GET | Full message history |
|
|
177
|
+
| `/sessions/:id/model` | POST | Switch model mid-session |
|
|
178
|
+
| `/sessions/:id/compaction` | POST | Trigger context compaction |
|
|
179
|
+
| `/sessions/:id/cache/metrics` | GET | Cache hit rate and savings |
|
|
180
|
+
| `/health` | GET | Server status and available models |
|
|
181
|
+
|
|
182
|
+
Additional REST surfaces (run the server and `curl` them): `/tools`, `/permissions/*`,
|
|
183
|
+
`/middleware/*`, `/config/*`, `/mcp/*`, `/system-messages/*`, and `/v1/approval-mode`.
|
|
184
|
+
Session routes also include `export`, `DELETE`, `checkpoints`, `load`, `resume`, `context`,
|
|
185
|
+
and `compaction/boundaries`.
|
|
186
|
+
|
|
187
|
+
### PR review API
|
|
188
|
+
|
|
189
|
+
When the git/PR tools are configured (see [Architecture → Permission System](architecture.md)):
|
|
190
|
+
|
|
191
|
+
| Endpoint | Method | Description |
|
|
192
|
+
|----------|--------|-------------|
|
|
193
|
+
| `/v1/pr/review` | POST | Run a PR review pipeline (`{repo, prNumber, options?}`) |
|
|
194
|
+
| `/v1/pr/create` | POST | Drive PR creation in an isolated worktree (`{repo, branch?, description?}`) |
|
|
195
|
+
| `/v1/pr/list` | GET | List open PRs (`?repo=owner/repo`) |
|
|
196
|
+
| `/v1/pr/webhook` | POST | GitHub webhook — requires `GITHUB_WEBHOOK_SECRET` + a valid `X-Hub-Signature-256` (returns 401 if no secret is set) |
|
|
197
|
+
|
|
198
|
+
### Server lifecycle
|
|
199
|
+
|
|
200
|
+
The server does **not** auto-shutdown after responses (unless `--idle-timeout` is set). Stop it explicitly:
|
|
201
|
+
|
|
202
|
+
```bash
|
|
203
|
+
pkill -f "packages/server/dist/index.js" # or Ctrl+C if foreground
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
**Session resume**: by default the server starts a **fresh** session on boot. Opt into resuming:
|
|
207
|
+
|
|
208
|
+
| Variable | Default | Behavior |
|
|
209
|
+
|----------|---------|----------|
|
|
210
|
+
| `AUTO_RESUME` | `false` | `true` → resume the most recent session on startup |
|
|
211
|
+
| `RESUME_SESSION_ID` | — | Resume a specific session by UUID (overrides `AUTO_RESUME`) |
|
|
212
|
+
|
|
213
|
+
With `AUTO_RESUME=true`, `tsx watch` restarts (dev mode) seamlessly continue your conversation —
|
|
214
|
+
code changes take effect without losing session state. Pair it with `SERVER_IDLE_TIMEOUT` for a
|
|
215
|
+
"sleep when idle, resume on wake" daemon.
|
|
216
|
+
|
|
217
|
+
### Common launch variables
|
|
218
|
+
|
|
219
|
+
| Variable | Default | Description |
|
|
220
|
+
|----------|---------|-------------|
|
|
221
|
+
| `DEFAULT_MODEL_ID` | `deepseek-v4-pro` | Model to use (any registry ID or alias) |
|
|
222
|
+
| `PORT` | `4000` | Server port (falls back to the next free port if taken) |
|
|
223
|
+
| `DEBUG` | `false` | Verbose logging (system messages, routes) |
|
|
224
|
+
| `YOLO` | `false` | Auto-approve all tool executions (bypasses permissions) |
|
|
225
|
+
| `CORTEX_MODE` | `persistent` | `stateless` for clean per-request sessions; `server` for HTTP-client mode |
|
|
226
|
+
| `ENABLE_DASHBOARD` | `false` | Master switch for the sandbox/tmux web dashboard (binds `DASHBOARD_PORT`, default 4001) |
|
|
227
|
+
|
|
228
|
+
Every variable is documented in [Configuration](configuration.md) and in `.env.example`. Run
|
|
229
|
+
`cortex-server --help` for the server's own summary.
|
|
230
|
+
|
|
231
|
+
## Development
|
|
232
|
+
|
|
233
|
+
```bash
|
|
234
|
+
npm run clean # Clean build artifacts
|
|
235
|
+
npm run build # Build all packages (multi-pass; see Architecture)
|
|
236
|
+
npm run typecheck # Type checking
|
|
237
|
+
npm test # Run tests
|
|
238
|
+
npm run test:ci # Tests with coverage
|
|
239
|
+
npm run lint # Lint
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
### Dev workflow (stateful iteration)
|
|
243
|
+
|
|
244
|
+
The recommended loop uses the server in dev mode with auto-resume:
|
|
245
|
+
|
|
246
|
+
```bash
|
|
247
|
+
# Terminal 1: server with hot reload
|
|
248
|
+
cd packages/server && npm run dev
|
|
249
|
+
|
|
250
|
+
# Terminal 2: send messages (each builds on the last)
|
|
251
|
+
cortex "Read the orchestrator and explain the tool loop"
|
|
252
|
+
cortex "Now add logging before each tool call"
|
|
253
|
+
cortex "Run the tests to verify"
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
What survives restarts: **system-message edits** (read fresh each turn), **code changes**
|
|
257
|
+
(tsx watch restarts + auto-resumes from JSONL), and **session state** (history, cache metrics,
|
|
258
|
+
turn count restored from disk).
|
|
259
|
+
|
|
260
|
+
## Production deployment
|
|
261
|
+
|
|
262
|
+
```bash
|
|
263
|
+
# Production server
|
|
264
|
+
NODE_ENV=production PORT=4000 cortex-server
|
|
265
|
+
|
|
266
|
+
# With PM2
|
|
267
|
+
pm2 start packages/server/dist/index.js --name nexus-cortex
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
## Troubleshooting
|
|
271
|
+
|
|
272
|
+
**Build errors** — clean and rebuild:
|
|
273
|
+
```bash
|
|
274
|
+
npm run clean && npm run build
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
**TypeScript errors** — `npm run typecheck`; ensure array accesses guard for `undefined`.
|
|
278
|
+
|
|
279
|
+
**MCP server issues** — test the server manually and check config:
|
|
280
|
+
```bash
|
|
281
|
+
npx -y @modelcontextprotocol/server-filesystem /path/to/dir
|
|
282
|
+
cat .cortex/mcp_config.json
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
**Missing API keys** — confirm the keys for the providers you use are set:
|
|
286
|
+
```bash
|
|
287
|
+
echo $ANTHROPIC_API_KEY
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
> `CORTEX.md` (project context) is generated on demand in your own project — run `/init` or
|
|
291
|
+
> the `InitCortexContext` tool; it is not shipped with the package.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nexus-cortex/server",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.33.0",
|
|
4
4
|
"description": "Thin Express server wrapper for Nexus Cortex core library",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -20,8 +20,8 @@
|
|
|
20
20
|
"prepack": "node ../../scripts/copy-pkg-cortex-scaffold.mjs"
|
|
21
21
|
},
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"@nexus-cortex/core": "^4.
|
|
24
|
-
"@nexus-cortex/executors": "^4.
|
|
23
|
+
"@nexus-cortex/core": "^4.33.0",
|
|
24
|
+
"@nexus-cortex/executors": "^4.33.0",
|
|
25
25
|
"chalk": "^5.3.0",
|
|
26
26
|
"cors": "^2.8.5",
|
|
27
27
|
"dotenv": "^16.4.5",
|
|
@@ -48,7 +48,8 @@
|
|
|
48
48
|
"dist",
|
|
49
49
|
"README.md",
|
|
50
50
|
"LICENSE",
|
|
51
|
-
"NOTICE"
|
|
51
|
+
"NOTICE",
|
|
52
|
+
"docs"
|
|
52
53
|
],
|
|
53
54
|
"repository": {
|
|
54
55
|
"type": "git",
|