@brutalist/mcp 0.6.12 → 0.6.13
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/README.md +122 -154
- package/dist/brutalist-server.js +43 -43
- package/dist/brutalist-server.js.map +1 -1
- package/dist/cli-agents.d.ts.map +1 -1
- package/dist/cli-agents.js +12 -2
- package/dist/cli-agents.js.map +1 -1
- package/dist/types/tool-config.d.ts +1 -1
- package/dist/types/tool-config.js +1 -1
- package/dist/types/tool-config.js.map +1 -1
- package/dist/utils/response-cache.d.ts +13 -13
- package/dist/utils/response-cache.d.ts.map +1 -1
- package/dist/utils/response-cache.js +43 -43
- package/dist/utils/response-cache.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,59 +1,48 @@
|
|
|
1
|
-
# Brutalist MCP
|
|
1
|
+
# Brutalist MCP
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Multi-perspective code analysis using Claude Code, Codex, and Gemini CLI agents.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Get direct, honest technical feedback on your code, architecture, and ideas before they reach production.
|
|
6
6
|
|
|
7
|
-
##
|
|
7
|
+
## What It Does
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
The Brutalist MCP connects your AI coding assistant to three different CLI agents (Claude, Codex, Gemini), each providing independent analysis. This gives you multiple perspectives on:
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
- Code quality and security vulnerabilities
|
|
12
|
+
- Architecture decisions and scalability
|
|
13
|
+
- Product ideas and technical feasibility
|
|
14
|
+
- Research methodology and design flaws
|
|
12
15
|
|
|
13
|
-
|
|
16
|
+
Real file-system access. Straightforward analysis. No sugar-coating.
|
|
14
17
|
|
|
15
|
-
|
|
18
|
+
## Quick Start
|
|
16
19
|
|
|
17
|
-
|
|
20
|
+
### Step 1: Install a CLI Agent
|
|
18
21
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
Install at least one CLI agent:
|
|
22
|
-
- **Claude Code**: `npm install -g claude` (or via Claude desktop app)
|
|
23
|
-
- **Codex**: Install from [OpenAI Codex](https://github.com/openai/codex-cli)
|
|
24
|
-
- **Gemini**: `npm install -g @google/gemini-cli` or authenticate via `gemini auth`
|
|
25
|
-
|
|
26
|
-
### Installation
|
|
27
|
-
|
|
28
|
-
<details>
|
|
29
|
-
<summary><strong>Claude Code</strong> — One-liner</summary>
|
|
22
|
+
You need at least one of these installed:
|
|
30
23
|
|
|
31
24
|
```bash
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
</details>
|
|
25
|
+
# Option 1: Claude Code (recommended)
|
|
26
|
+
npm install -g claude
|
|
35
27
|
|
|
36
|
-
|
|
37
|
-
|
|
28
|
+
# Option 2: Codex
|
|
29
|
+
# Install from https://github.com/openai/codex-cli
|
|
38
30
|
|
|
39
|
-
|
|
40
|
-
|
|
31
|
+
# Option 3: Gemini
|
|
32
|
+
npm install -g @google/gemini-cli
|
|
41
33
|
```
|
|
42
|
-
</details>
|
|
43
34
|
|
|
44
|
-
|
|
45
|
-
<summary><strong>Gemini CLI</strong> — One-liner</summary>
|
|
35
|
+
### Step 2: Install the MCP Server
|
|
46
36
|
|
|
37
|
+
Choose your IDE:
|
|
38
|
+
|
|
39
|
+
**Claude Code:**
|
|
47
40
|
```bash
|
|
48
|
-
|
|
41
|
+
claude mcp add brutalist --scope user -- npx -y @brutalist/mcp
|
|
49
42
|
```
|
|
50
|
-
</details>
|
|
51
|
-
|
|
52
|
-
<details>
|
|
53
|
-
<summary><strong>Cursor</strong> — Manual config</summary>
|
|
54
|
-
|
|
55
|
-
Add to `~/.cursor/mcp.json` or use **Settings → MCP & Integrations**
|
|
56
43
|
|
|
44
|
+
**Cursor:**
|
|
45
|
+
Add to `~/.cursor/mcp.json`:
|
|
57
46
|
```json
|
|
58
47
|
{
|
|
59
48
|
"brutalist": {
|
|
@@ -62,13 +51,14 @@ Add to `~/.cursor/mcp.json` or use **Settings → MCP & Integrations**
|
|
|
62
51
|
}
|
|
63
52
|
}
|
|
64
53
|
```
|
|
65
|
-
</details>
|
|
66
|
-
|
|
67
|
-
<details>
|
|
68
|
-
<summary><strong>Windsurf</strong> — Manual config</summary>
|
|
69
54
|
|
|
70
|
-
|
|
55
|
+
**VS Code / Cline:**
|
|
56
|
+
```bash
|
|
57
|
+
code --add-mcp '{"name":"brutalist","command":"npx","args":["-y","@brutalist/mcp"]}'
|
|
58
|
+
```
|
|
71
59
|
|
|
60
|
+
**Windsurf:**
|
|
61
|
+
Add to `~/.codeium/windsurf/mcp_config.json`:
|
|
72
62
|
```json
|
|
73
63
|
{
|
|
74
64
|
"brutalist": {
|
|
@@ -77,187 +67,165 @@ Add to `~/.codeium/windsurf/mcp_config.json` or use **Plugin Store**
|
|
|
77
67
|
}
|
|
78
68
|
}
|
|
79
69
|
```
|
|
80
|
-
</details>
|
|
81
70
|
|
|
82
|
-
|
|
71
|
+
### Step 3: Verify Installation
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
# Check which CLI agents are available
|
|
75
|
+
cli_agent_roster()
|
|
76
|
+
```
|
|
83
77
|
|
|
84
|
-
|
|
78
|
+
## Usage Examples
|
|
85
79
|
|
|
86
|
-
|
|
80
|
+
### Analyze Your Codebase
|
|
87
81
|
|
|
88
82
|
```bash
|
|
89
|
-
#
|
|
83
|
+
# Analyze entire project
|
|
90
84
|
roast_codebase "/path/to/your/project"
|
|
91
85
|
|
|
92
|
-
#
|
|
93
|
-
roast_codebase "/src/auth"
|
|
94
|
-
roast_codebase "/src/api/handlers"
|
|
95
|
-
roast_codebase "/components" # React component chaos
|
|
86
|
+
# Analyze specific modules
|
|
87
|
+
roast_codebase "/src/auth"
|
|
88
|
+
roast_codebase "/src/api/handlers"
|
|
96
89
|
```
|
|
97
90
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
### 💡 **Idea Obliteration**
|
|
101
|
-
|
|
102
|
-
> Reality-check your startup dreams, product concepts, and technical decisions.
|
|
91
|
+
### Validate Ideas
|
|
103
92
|
|
|
104
93
|
```bash
|
|
105
|
-
#
|
|
94
|
+
# Evaluate a product concept
|
|
106
95
|
roast_idea "A social network for developers to share code snippets"
|
|
107
96
|
|
|
108
|
-
#
|
|
97
|
+
# Review technical decisions
|
|
109
98
|
roast_idea "Migrating our monolith to microservices with Kubernetes"
|
|
110
|
-
|
|
111
|
-
# Product feature validation
|
|
112
|
-
roast_idea "Adding AI-powered code suggestions to our IDE"
|
|
113
99
|
```
|
|
114
100
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
### 🏗️ **Architecture Annihilation**
|
|
118
|
-
|
|
119
|
-
> Find every scaling bottleneck, cost explosion, and operational nightmare in your system design.
|
|
101
|
+
### Review Architecture
|
|
120
102
|
|
|
121
103
|
```bash
|
|
122
|
-
# System architecture
|
|
104
|
+
# System architecture analysis
|
|
123
105
|
roast_architecture "Microservices with event sourcing and CQRS"
|
|
124
106
|
|
|
125
|
-
# Infrastructure design
|
|
107
|
+
# Infrastructure design review
|
|
126
108
|
roast_architecture """
|
|
127
109
|
API Gateway → Load Balancer → 3 Node.js services → PostgreSQL
|
|
128
110
|
Redis for caching, Docker containers on AWS ECS
|
|
129
111
|
"""
|
|
130
112
|
```
|
|
131
113
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
### 🔒 **Security Demolition**
|
|
135
|
-
|
|
136
|
-
> Expose authentication bypasses, injection vulnerabilities, and data leak opportunities.
|
|
114
|
+
### Security Analysis
|
|
137
115
|
|
|
138
116
|
```bash
|
|
139
|
-
# Authentication
|
|
117
|
+
# Authentication review
|
|
140
118
|
roast_security "JWT tokens with user roles in localStorage"
|
|
141
119
|
|
|
142
|
-
# API security
|
|
120
|
+
# API security check
|
|
143
121
|
roast_security "GraphQL API with dynamic queries and no rate limiting"
|
|
144
122
|
```
|
|
145
123
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
### 🤺 **Multi-Agent Warfare**
|
|
149
|
-
|
|
150
|
-
> Deploy multiple CLI agents in adversarial combat for maximum destruction.
|
|
124
|
+
### Compare Perspectives
|
|
151
125
|
|
|
152
126
|
```bash
|
|
153
|
-
#
|
|
127
|
+
# Get multiple viewpoints on technical decisions
|
|
154
128
|
roast_cli_debate "Should we use TypeScript or Go for this API?"
|
|
155
129
|
|
|
156
|
-
#
|
|
130
|
+
# Compare architecture approaches
|
|
157
131
|
roast_cli_debate "Microservices vs Monolith for our e-commerce platform"
|
|
158
132
|
```
|
|
159
133
|
|
|
160
|
-
---
|
|
161
|
-
|
|
162
|
-
### 🛠️ **Meta Commands**
|
|
163
|
-
|
|
164
|
-
```bash
|
|
165
|
-
# Check which CLI agents are available
|
|
166
|
-
cli_agent_roster()
|
|
167
|
-
```
|
|
168
|
-
|
|
169
134
|
## How It Works
|
|
170
135
|
|
|
171
|
-
This MCP server
|
|
172
|
-
- **Claude Code CLI** -
|
|
173
|
-
- **Codex CLI** -
|
|
174
|
-
- **Gemini CLI** -
|
|
136
|
+
This MCP server coordinates analysis from locally installed CLI agents:
|
|
137
|
+
- **Claude Code CLI** - Code review and architectural analysis
|
|
138
|
+
- **Codex CLI** - Security and technical implementation review
|
|
139
|
+
- **Gemini CLI** - System design and scalability analysis
|
|
175
140
|
|
|
176
|
-
Each agent runs locally
|
|
141
|
+
Each agent runs locally with direct file-system access, providing independent perspectives on your code and design decisions.
|
|
177
142
|
|
|
178
|
-
|
|
143
|
+
**Analysis time:** Up to 25 minutes for complex projects. Thorough analysis requires time to examine code patterns, dependencies, and architectural decisions.
|
|
179
144
|
|
|
180
|
-
##
|
|
145
|
+
## Pagination for Large Results
|
|
181
146
|
|
|
182
|
-
|
|
147
|
+
For analyses that exceed your IDE's token limit:
|
|
183
148
|
|
|
184
149
|
```bash
|
|
185
|
-
#
|
|
150
|
+
# Set chunk size for large codebases
|
|
186
151
|
roast_codebase({targetPath: "/monorepo", limit: 20000})
|
|
187
152
|
|
|
188
|
-
# Continue
|
|
153
|
+
# Continue from where you left off
|
|
189
154
|
roast_codebase({targetPath: "/monorepo", offset: 20000, limit: 20000})
|
|
190
155
|
|
|
191
|
-
#
|
|
156
|
+
# Use cursor-based navigation
|
|
192
157
|
roast_codebase({targetPath: "/complex-system", cursor: "offset:25000"})
|
|
193
158
|
```
|
|
194
159
|
|
|
195
|
-
|
|
196
|
-
-
|
|
197
|
-
-
|
|
198
|
-
-
|
|
199
|
-
-
|
|
160
|
+
Features:
|
|
161
|
+
- Smart boundary detection (preserves paragraphs and sentences)
|
|
162
|
+
- Token estimation (~4 chars = 1 token)
|
|
163
|
+
- Progress indicators
|
|
164
|
+
- Configurable chunk size (1K to 100K characters)
|
|
200
165
|
|
|
201
166
|
## Tools
|
|
202
167
|
|
|
203
|
-
### Code & Architecture
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
| `
|
|
208
|
-
| `
|
|
209
|
-
| `
|
|
210
|
-
| `
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
|
216
|
-
|
|
217
|
-
| `
|
|
218
|
-
| `
|
|
219
|
-
| `
|
|
220
|
-
| `
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
168
|
+
### Code & Architecture
|
|
169
|
+
|
|
170
|
+
| Tool | Analyzes |
|
|
171
|
+
|------|----------|
|
|
172
|
+
| `roast_codebase` | Security vulnerabilities, performance issues, code quality |
|
|
173
|
+
| `roast_file_structure` | Directory organization, naming conventions, structure |
|
|
174
|
+
| `roast_dependencies` | Version conflicts, security vulnerabilities, compatibility |
|
|
175
|
+
| `roast_git_history` | Commit quality, branching strategy, collaboration patterns |
|
|
176
|
+
| `roast_test_coverage` | Test coverage, quality gaps, testing strategy |
|
|
177
|
+
|
|
178
|
+
### Design & Planning
|
|
179
|
+
|
|
180
|
+
| Tool | Analyzes |
|
|
181
|
+
|------|----------|
|
|
182
|
+
| `roast_idea` | Feasibility, market fit, implementation challenges |
|
|
183
|
+
| `roast_architecture` | Scalability, cost, operational complexity |
|
|
184
|
+
| `roast_research` | Methodology, reproducibility, statistical validity |
|
|
185
|
+
| `roast_security` | Attack vectors, authentication, authorization |
|
|
186
|
+
| `roast_product` | UX, adoption barriers, user needs |
|
|
187
|
+
| `roast_infrastructure` | Reliability, scaling, operational overhead |
|
|
188
|
+
|
|
189
|
+
### Utilities
|
|
190
|
+
|
|
191
|
+
| Tool | Purpose |
|
|
192
|
+
|------|---------|
|
|
193
|
+
| `roast_cli_debate` | Multi-agent discussion from different perspectives |
|
|
194
|
+
| `cli_agent_roster` | Show available CLI agents on your system |
|
|
195
|
+
|
|
196
|
+
## Advanced Usage
|
|
197
|
+
|
|
198
|
+
### Choose Specific CLI Agents
|
|
231
199
|
|
|
232
200
|
```bash
|
|
233
|
-
# Use specific
|
|
201
|
+
# Use a specific agent
|
|
234
202
|
roast_codebase(targetPath="/src", preferredCLI="claude")
|
|
235
203
|
|
|
236
|
-
#
|
|
237
|
-
roast_security "/auth/module" #
|
|
204
|
+
# System automatically selects best agent for task
|
|
205
|
+
roast_security "/auth/module" # Typically uses Codex
|
|
238
206
|
|
|
239
|
-
#
|
|
240
|
-
roast_idea "..." # All available agents
|
|
207
|
+
# Multi-agent analysis (default)
|
|
208
|
+
roast_idea "..." # All available agents provide perspectives
|
|
241
209
|
```
|
|
242
210
|
|
|
243
|
-
###
|
|
244
|
-
|
|
245
|
-
Different CLI agents excel at different analysis types:
|
|
246
|
-
- **Code review**: Claude > Codex > Gemini
|
|
247
|
-
- **Architecture**: Gemini > Claude > Codex
|
|
248
|
-
- **Security**: Codex > Claude > Gemini
|
|
249
|
-
- **Research**: Claude > Gemini > Codex
|
|
211
|
+
### Agent Strengths
|
|
250
212
|
|
|
251
|
-
|
|
213
|
+
Different agents have different strengths:
|
|
214
|
+
- **Code review**: Claude, Codex, Gemini
|
|
215
|
+
- **Architecture**: Gemini, Claude, Codex
|
|
216
|
+
- **Security**: Codex, Claude, Gemini
|
|
217
|
+
- **Research**: Claude, Gemini, Codex
|
|
252
218
|
|
|
253
|
-
|
|
254
|
-
**Solution:** Deploy multiple local CLI agents with adversarial perspectives.
|
|
255
|
-
**Result:** Brutal honesty through systematic destruction before expensive failures.
|
|
219
|
+
## Why Multiple Perspectives
|
|
256
220
|
|
|
257
|
-
|
|
221
|
+
Each CLI agent brings a different approach to analysis:
|
|
222
|
+
- Different training data and focus areas
|
|
223
|
+
- Independent evaluation of the same code
|
|
224
|
+
- Varied perspectives on technical tradeoffs
|
|
258
225
|
|
|
259
|
-
|
|
226
|
+
Getting multiple viewpoints helps identify issues that a single perspective might miss.
|
|
260
227
|
|
|
261
228
|
---
|
|
262
229
|
|
|
263
|
-
|
|
230
|
+
**License:** MIT
|
|
231
|
+
**Issues:** https://github.com/ejmockler/brutalist-mcp/issues
|
package/dist/brutalist-server.js
CHANGED
|
@@ -12,7 +12,7 @@ import { TOOL_CONFIGS } from './tool-definitions.js';
|
|
|
12
12
|
import { extractPaginationParams, parseCursor, PAGINATION_DEFAULTS, ResponseChunker, createPaginationMetadata, formatPaginationStatus, estimateTokenCount } from './utils/pagination.js';
|
|
13
13
|
import { ResponseCache } from './utils/response-cache.js';
|
|
14
14
|
// Use environment variable or fallback to manual version
|
|
15
|
-
const PACKAGE_VERSION = process.env.npm_package_version || "0.
|
|
15
|
+
const PACKAGE_VERSION = process.env.npm_package_version || "0.6.12";
|
|
16
16
|
export class BrutalistServer {
|
|
17
17
|
server;
|
|
18
18
|
config;
|
|
@@ -373,9 +373,9 @@ export class BrutalistServer {
|
|
|
373
373
|
roster += "## Pagination Support (NEW in v0.5.2)\n";
|
|
374
374
|
roster += "**All tools now support intelligent pagination:**\n";
|
|
375
375
|
roster += "- Analysis results are cached with 2-hour TTL\n";
|
|
376
|
-
roster += "- Use `
|
|
376
|
+
roster += "- Use `context_id` from response to resume conversation\n";
|
|
377
377
|
roster += "- Smart text chunking preserves readability\n";
|
|
378
|
-
roster += "- Example: `roast_codebase(
|
|
378
|
+
roster += "- Example: `roast_codebase(context_id: 'a3f5c2d8', offset: 25000)`\n\n";
|
|
379
379
|
roster += "## Brutalist Philosophy\n";
|
|
380
380
|
roster += "*All tools use CLI agents with brutal system prompts for maximum reality-based criticism.*\n";
|
|
381
381
|
return {
|
|
@@ -445,13 +445,13 @@ export class BrutalistServer {
|
|
|
445
445
|
const explicitPaginationRequested = args.offset !== undefined ||
|
|
446
446
|
args.limit !== undefined ||
|
|
447
447
|
args.cursor !== undefined ||
|
|
448
|
-
args.
|
|
449
|
-
logger.info(`🔧 DEBUG: explicitPaginationRequested=${explicitPaginationRequested}, offset=${args.offset}, limit=${args.limit}, cursor=${args.cursor},
|
|
450
|
-
// Check cache if
|
|
451
|
-
if (args.
|
|
452
|
-
const cachedContent = await this.responseCache.get(args.
|
|
448
|
+
args.context_id !== undefined;
|
|
449
|
+
logger.info(`🔧 DEBUG: explicitPaginationRequested=${explicitPaginationRequested}, offset=${args.offset}, limit=${args.limit}, cursor=${args.cursor}, context_id=${args.context_id}`);
|
|
450
|
+
// Check cache if context_id provided
|
|
451
|
+
if (args.context_id && !args.force_refresh) {
|
|
452
|
+
const cachedContent = await this.responseCache.get(args.context_id, sessionId);
|
|
453
453
|
if (cachedContent) {
|
|
454
|
-
logger.info(`🎯 Cache HIT for
|
|
454
|
+
logger.info(`🎯 Cache HIT for context_id: ${args.context_id}`);
|
|
455
455
|
const cachedResult = {
|
|
456
456
|
success: true,
|
|
457
457
|
responses: [{
|
|
@@ -461,14 +461,14 @@ export class BrutalistServer {
|
|
|
461
461
|
executionTime: 0
|
|
462
462
|
}]
|
|
463
463
|
};
|
|
464
|
-
return this.formatToolResponse(cachedResult, args.verbose, paginationParams, args.
|
|
464
|
+
return this.formatToolResponse(cachedResult, args.verbose, paginationParams, args.context_id, explicitPaginationRequested);
|
|
465
465
|
}
|
|
466
466
|
else {
|
|
467
|
-
logger.warn(`❌ Cache MISS for
|
|
468
|
-
// Don't silently re-run -
|
|
469
|
-
throw new Error(`
|
|
467
|
+
logger.warn(`❌ Cache MISS for context_id: ${args.context_id}, session: ${sessionId}`);
|
|
468
|
+
// Don't silently re-run - context_id should always hit cache or error
|
|
469
|
+
throw new Error(`Context ID "${args.context_id}" not found in cache. ` +
|
|
470
470
|
`It may have expired (2 hour TTL) or belong to a different session. ` +
|
|
471
|
-
`Remove
|
|
471
|
+
`Remove context_id parameter to run a new analysis.`);
|
|
472
472
|
}
|
|
473
473
|
}
|
|
474
474
|
// Generate cache key for this request
|
|
@@ -482,12 +482,12 @@ export class BrutalistServer {
|
|
|
482
482
|
if (!args.force_refresh) {
|
|
483
483
|
const cachedContent = await this.responseCache.get(cacheKey, sessionId);
|
|
484
484
|
if (cachedContent) {
|
|
485
|
-
// Get existing
|
|
486
|
-
const
|
|
487
|
-
const
|
|
488
|
-
? this.responseCache.createAlias(
|
|
489
|
-
: this.responseCache.
|
|
490
|
-
logger.info(`🎯 Cache hit for new request, using
|
|
485
|
+
// Get existing context_id or create new alias
|
|
486
|
+
const existingContextId = this.responseCache.findContextIdForKey(cacheKey);
|
|
487
|
+
const contextId = existingContextId
|
|
488
|
+
? this.responseCache.createAlias(existingContextId, cacheKey)
|
|
489
|
+
: this.responseCache.generateContextId(cacheKey);
|
|
490
|
+
logger.info(`🎯 Cache hit for new request, using context_id: ${contextId}`);
|
|
491
491
|
const cachedResult = {
|
|
492
492
|
success: true,
|
|
493
493
|
responses: [{
|
|
@@ -497,7 +497,7 @@ export class BrutalistServer {
|
|
|
497
497
|
executionTime: 0
|
|
498
498
|
}]
|
|
499
499
|
};
|
|
500
|
-
return this.formatToolResponse(cachedResult, args.verbose, paginationParams,
|
|
500
|
+
return this.formatToolResponse(cachedResult, args.verbose, paginationParams, contextId, explicitPaginationRequested);
|
|
501
501
|
}
|
|
502
502
|
}
|
|
503
503
|
// Build context with custom builder if available
|
|
@@ -509,7 +509,7 @@ export class BrutalistServer {
|
|
|
509
509
|
// Run the analysis
|
|
510
510
|
const result = await this.executeBrutalistAnalysis(config.analysisType, primaryArg, config.systemPrompt, context, args.workingDirectory, args.preferredCLI, args.verbose, args.models, progressToken, sessionId, requestId);
|
|
511
511
|
// Cache the result if successful
|
|
512
|
-
let
|
|
512
|
+
let contextId;
|
|
513
513
|
if (result.success && result.responses.length > 0) {
|
|
514
514
|
const fullContent = this.extractFullContent(result);
|
|
515
515
|
if (fullContent) {
|
|
@@ -519,14 +519,14 @@ export class BrutalistServer {
|
|
|
519
519
|
acc[field] = args[field];
|
|
520
520
|
return acc;
|
|
521
521
|
}, {});
|
|
522
|
-
const {
|
|
523
|
-
requestId //
|
|
522
|
+
const { contextId: newId } = await this.responseCache.set(cacheData, fullContent, cacheKey, sessionId, // Bind to session
|
|
523
|
+
requestId // Track request
|
|
524
524
|
);
|
|
525
|
-
|
|
526
|
-
logger.info(`✅ Cached analysis result with ID: ${
|
|
525
|
+
contextId = newId;
|
|
526
|
+
logger.info(`✅ Cached analysis result with context ID: ${contextId} for session: ${sessionId?.substring(0, 8)}`);
|
|
527
527
|
}
|
|
528
528
|
}
|
|
529
|
-
return this.formatToolResponse(result, args.verbose, paginationParams,
|
|
529
|
+
return this.formatToolResponse(result, args.verbose, paginationParams, contextId, explicitPaginationRequested);
|
|
530
530
|
}
|
|
531
531
|
catch (error) {
|
|
532
532
|
return this.formatErrorResponse(error);
|
|
@@ -814,7 +814,7 @@ Remember: You are ${currentAgent.toUpperCase()}, passionate advocate for ${assig
|
|
|
814
814
|
}
|
|
815
815
|
return null;
|
|
816
816
|
}
|
|
817
|
-
formatToolResponse(result, verbose = false, paginationParams,
|
|
817
|
+
formatToolResponse(result, verbose = false, paginationParams, contextId, explicitPaginationRequested = false) {
|
|
818
818
|
logger.info(`🔧 DEBUG: formatToolResponse called with synthesis length: ${result.synthesis?.length || 0}`);
|
|
819
819
|
logger.info(`🔧 DEBUG: result.success=${result.success}, responses.length=${result.responses?.length || 0}`);
|
|
820
820
|
logger.info(`🔧 DEBUG: pagination params:`, paginationParams);
|
|
@@ -846,21 +846,21 @@ Remember: You are ${currentAgent.toUpperCase()}, passionate advocate for ${assig
|
|
|
846
846
|
offset: 0,
|
|
847
847
|
limit: PAGINATION_DEFAULTS.DEFAULT_LIMIT_TOKENS // Use token-based limit
|
|
848
848
|
};
|
|
849
|
-
return this.formatPaginatedResponse(primaryContent, forcedParams, result, verbose,
|
|
849
|
+
return this.formatPaginatedResponse(primaryContent, forcedParams, result, verbose, contextId);
|
|
850
850
|
}
|
|
851
851
|
else if (paginationParams) {
|
|
852
852
|
logger.info(`🔧 DEBUG: Applying pagination (explicitly requested)`);
|
|
853
|
-
return this.formatPaginatedResponse(primaryContent, paginationParams, result, verbose,
|
|
853
|
+
return this.formatPaginatedResponse(primaryContent, paginationParams, result, verbose, contextId);
|
|
854
854
|
}
|
|
855
855
|
}
|
|
856
856
|
// Non-paginated response (only for content that fits within token limit)
|
|
857
857
|
if (primaryContent) {
|
|
858
858
|
logger.info(`🔧 DEBUG: Returning full response (${estimatedTokens} tokens < ${maxTokensWithoutPagination} limit)`);
|
|
859
|
-
// Include
|
|
859
|
+
// Include context_id even for non-paginated responses (for future pagination/caching)
|
|
860
860
|
let responseText = '';
|
|
861
|
-
if (
|
|
861
|
+
if (contextId) {
|
|
862
862
|
responseText += `# Brutalist Analysis Results\n\n`;
|
|
863
|
-
responseText += `**🔑
|
|
863
|
+
responseText += `**🔑 Context ID:** ${contextId}\n\n`;
|
|
864
864
|
responseText += `---\n\n`;
|
|
865
865
|
responseText += primaryContent;
|
|
866
866
|
}
|
|
@@ -896,7 +896,7 @@ Remember: You are ${currentAgent.toUpperCase()}, passionate advocate for ${assig
|
|
|
896
896
|
}]
|
|
897
897
|
};
|
|
898
898
|
}
|
|
899
|
-
formatPaginatedResponse(content, paginationParams, result, verbose,
|
|
899
|
+
formatPaginatedResponse(content, paginationParams, result, verbose, contextId) {
|
|
900
900
|
// Using imported pagination utilities
|
|
901
901
|
const offset = paginationParams.offset || 0;
|
|
902
902
|
// Convert character-based limit to token-based limit (1 token ≈ 4 chars)
|
|
@@ -935,20 +935,20 @@ Remember: You are ${currentAgent.toUpperCase()}, passionate advocate for ${assig
|
|
|
935
935
|
// Show pagination metadata
|
|
936
936
|
const needsPagination = pagination.totalChunks > 1 || pagination.hasMore;
|
|
937
937
|
const isFirstRequest = offset === 0;
|
|
938
|
-
// Always show
|
|
939
|
-
if (isFirstRequest &&
|
|
940
|
-
paginatedText += `**🔑
|
|
938
|
+
// Always show context_id on first request for future pagination
|
|
939
|
+
if (isFirstRequest && contextId) {
|
|
940
|
+
paginatedText += `**🔑 Context ID:** ${contextId}\n`;
|
|
941
941
|
paginatedText += `**🔢 Token Estimate:** ~${totalTokens.toLocaleString()} tokens (total)\n\n`;
|
|
942
942
|
}
|
|
943
943
|
if (needsPagination) {
|
|
944
944
|
paginatedText += `**📊 Pagination Status:** ${statusLine}\n`;
|
|
945
|
-
if (!isFirstRequest &&
|
|
946
|
-
paginatedText += `**🔑
|
|
945
|
+
if (!isFirstRequest && contextId) {
|
|
946
|
+
paginatedText += `**🔑 Context ID:** ${contextId}\n`;
|
|
947
947
|
}
|
|
948
948
|
paginatedText += `**🔢 Token Estimate:** ~${chunkTokens.toLocaleString()} tokens (chunk) / ~${totalTokens.toLocaleString()} tokens (total)\n\n`;
|
|
949
949
|
if (pagination.hasMore) {
|
|
950
|
-
if (
|
|
951
|
-
paginatedText += `**⏭️ Continue Reading:** Use \`
|
|
950
|
+
if (contextId) {
|
|
951
|
+
paginatedText += `**⏭️ Continue Reading:** Use \`context_id: "${contextId}", offset: ${endOffset}\`\n\n`;
|
|
952
952
|
}
|
|
953
953
|
else {
|
|
954
954
|
paginatedText += `**⏭️ Continue Reading:** Use \`offset: ${endOffset}\` for next chunk\n\n`;
|
|
@@ -963,8 +963,8 @@ Remember: You are ${currentAgent.toUpperCase()}, passionate advocate for ${assig
|
|
|
963
963
|
paginatedText += `\n\n---\n\n`;
|
|
964
964
|
if (pagination.hasMore) {
|
|
965
965
|
paginatedText += `📖 **End of chunk ${pagination.chunkIndex}/${pagination.totalChunks}**\n`;
|
|
966
|
-
if (
|
|
967
|
-
paginatedText += `🔄 To continue: Include \`
|
|
966
|
+
if (contextId) {
|
|
967
|
+
paginatedText += `🔄 To continue: Include \`context_id: "${contextId}"\` with \`offset: ${endOffset}\` in next request`;
|
|
968
968
|
}
|
|
969
969
|
else {
|
|
970
970
|
paginatedText += `🔄 To continue: Use same tool with \`offset: ${endOffset}\``;
|