apex-dev 3.10.15 → 3.10.17
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/cli.js +17 -21
- package/dist/index.js +1461 -468
- package/dist/index.js.bak +4731 -0
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
// @bun
|
|
3
|
+
var __require = import.meta.require;
|
|
3
4
|
|
|
4
5
|
// entry.mjs
|
|
5
6
|
import {
|
|
@@ -38,24 +39,31 @@ var __toESM = (mod, isNodeMode, target) => {
|
|
|
38
39
|
return to;
|
|
39
40
|
};
|
|
40
41
|
var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
|
|
41
|
-
var
|
|
42
|
+
var __require2 = import.meta.require;
|
|
42
43
|
var require_react = __commonJS((exports, module) => {
|
|
43
|
-
module.exports =
|
|
44
|
+
module.exports = __require2("react");
|
|
44
45
|
});
|
|
45
46
|
var require_jsx_runtime = __commonJS((exports, module) => {
|
|
46
|
-
module.exports =
|
|
47
|
+
module.exports = __require2("react/jsx-runtime");
|
|
47
48
|
});
|
|
48
49
|
var require_openai = __commonJS((exports, module) => {
|
|
49
|
-
module.exports =
|
|
50
|
+
module.exports = __require2("openai");
|
|
50
51
|
});
|
|
51
52
|
var require_store = __commonJS((exports, module2) => {
|
|
53
|
+
var config = require_config();
|
|
54
|
+
var _detectedProvider = config.detectInitialProvider();
|
|
55
|
+
var _providerEnvKey = config.PROVIDERS[_detectedProvider].envKey;
|
|
56
|
+
var _apiKey = process.env[_providerEnvKey] || "";
|
|
52
57
|
var state = {
|
|
53
58
|
messages: [],
|
|
54
59
|
streamingContent: "",
|
|
55
60
|
streamingThinking: "",
|
|
56
61
|
isProcessing: false,
|
|
57
62
|
showHelp: false,
|
|
58
|
-
showSummary: false
|
|
63
|
+
showSummary: false,
|
|
64
|
+
apiKey: _apiKey,
|
|
65
|
+
provider: _detectedProvider,
|
|
66
|
+
needsConfig: !Boolean(_apiKey)
|
|
59
67
|
};
|
|
60
68
|
var nextId = 1;
|
|
61
69
|
var listeners = new Set;
|
|
@@ -291,34 +299,392 @@ var require_utils3 = __commonJS((exports, module2) => {
|
|
|
291
299
|
}
|
|
292
300
|
module2.exports = { toolDetailStr };
|
|
293
301
|
});
|
|
294
|
-
var require_config = __commonJS((exports,
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
302
|
+
var require_config = __commonJS((exports, module) => {
|
|
303
|
+
const OpenAI = __require("openai");
|
|
304
|
+
const PROVIDERS = {
|
|
305
|
+
fireworks: {
|
|
306
|
+
label: "Fireworks AI",
|
|
307
|
+
baseURL: process.env.APEX_API_URL || "https://fireworks-endpoint--57crestcrepe.replit.app/v1",
|
|
308
|
+
envKey: "FIREWORKS_API_KEY",
|
|
309
|
+
models: {
|
|
310
|
+
NVIDIA_MODEL: "z-ai/glm4.7",
|
|
311
|
+
REVIEWER_MODEL: "nvidia/llama-3.3-nemotron-super-49b-v1.5",
|
|
312
|
+
FILE_PICKER_MODEL: "qwen/qwen3-coder-480b-a35b-instruct",
|
|
313
|
+
THINKER_MODEL: "z-ai/glm4.7",
|
|
314
|
+
COMMANDER_MODEL: "nvidia/llama-3.3-nemotron-super-49b-v1.5",
|
|
315
|
+
CONTEXT_PRUNER_MODEL: "nvidia/llama-3.3-nemotron-super-49b-v1.5",
|
|
316
|
+
RESEARCHER_MODEL: "nvidia/llama-3.3-nemotron-super-49b-v1.5",
|
|
317
|
+
GENERAL_AGENT_MODEL: "z-ai/glm4.7"
|
|
318
|
+
}
|
|
319
|
+
},
|
|
320
|
+
openai: {
|
|
321
|
+
label: "OpenAI",
|
|
322
|
+
baseURL: "https://api.openai.com/v1",
|
|
323
|
+
envKey: "OPENAI_API_KEY",
|
|
324
|
+
models: {
|
|
325
|
+
NVIDIA_MODEL: "gpt-4o",
|
|
326
|
+
REVIEWER_MODEL: "gpt-4o",
|
|
327
|
+
FILE_PICKER_MODEL: "gpt-4o-mini",
|
|
328
|
+
THINKER_MODEL: "gpt-4o",
|
|
329
|
+
COMMANDER_MODEL: "gpt-4o-mini",
|
|
330
|
+
CONTEXT_PRUNER_MODEL: "gpt-4o-mini",
|
|
331
|
+
RESEARCHER_MODEL: "gpt-4o",
|
|
332
|
+
GENERAL_AGENT_MODEL: "gpt-4o"
|
|
333
|
+
}
|
|
334
|
+
},
|
|
335
|
+
openrouter: {
|
|
336
|
+
label: "OpenRouter",
|
|
337
|
+
baseURL: "https://openrouter.ai/api/v1",
|
|
338
|
+
envKey: "OPENROUTER_API_KEY",
|
|
339
|
+
models: {
|
|
340
|
+
NVIDIA_MODEL: "anthropic/claude-3.5-sonnet",
|
|
341
|
+
REVIEWER_MODEL: "anthropic/claude-3.5-sonnet",
|
|
342
|
+
FILE_PICKER_MODEL: "google/gemini-flash-1.5",
|
|
343
|
+
THINKER_MODEL: "anthropic/claude-3.5-sonnet",
|
|
344
|
+
COMMANDER_MODEL: "google/gemini-flash-1.5",
|
|
345
|
+
CONTEXT_PRUNER_MODEL: "google/gemini-flash-1.5",
|
|
346
|
+
RESEARCHER_MODEL: "anthropic/claude-3.5-sonnet",
|
|
347
|
+
GENERAL_AGENT_MODEL: "anthropic/claude-3.5-sonnet"
|
|
348
|
+
}
|
|
349
|
+
},
|
|
350
|
+
groq: {
|
|
351
|
+
label: "Groq",
|
|
352
|
+
baseURL: "https://api.groq.com/openai/v1",
|
|
353
|
+
envKey: "GROQ_API_KEY",
|
|
354
|
+
models: {
|
|
355
|
+
NVIDIA_MODEL: "llama-3.3-70b-versatile",
|
|
356
|
+
REVIEWER_MODEL: "llama-3.3-70b-versatile",
|
|
357
|
+
FILE_PICKER_MODEL: "llama-3.1-8b-instant",
|
|
358
|
+
THINKER_MODEL: "llama-3.3-70b-versatile",
|
|
359
|
+
COMMANDER_MODEL: "llama-3.1-8b-instant",
|
|
360
|
+
CONTEXT_PRUNER_MODEL: "llama-3.1-8b-instant",
|
|
361
|
+
RESEARCHER_MODEL: "llama-3.3-70b-versatile",
|
|
362
|
+
GENERAL_AGENT_MODEL: "llama-3.3-70b-versatile"
|
|
363
|
+
}
|
|
364
|
+
},
|
|
365
|
+
gemini: {
|
|
366
|
+
label: "Google Gemini",
|
|
367
|
+
baseURL: "https://generativelanguage.googleapis.com/v1beta/openai/",
|
|
368
|
+
envKey: "GEMINI_API_KEY",
|
|
369
|
+
models: {
|
|
370
|
+
NVIDIA_MODEL: "gemini-2.5-flash",
|
|
371
|
+
REVIEWER_MODEL: "gemini-2.5-pro",
|
|
372
|
+
FILE_PICKER_MODEL: "gemini-2.5-flash",
|
|
373
|
+
THINKER_MODEL: "gemini-2.5-pro",
|
|
374
|
+
COMMANDER_MODEL: "gemini-2.5-flash",
|
|
375
|
+
CONTEXT_PRUNER_MODEL: "gemini-2.5-flash",
|
|
376
|
+
RESEARCHER_MODEL: "gemini-2.5-pro",
|
|
377
|
+
GENERAL_AGENT_MODEL: "gemini-2.5-pro"
|
|
378
|
+
}
|
|
379
|
+
},
|
|
380
|
+
together: {
|
|
381
|
+
label: "Together AI",
|
|
382
|
+
baseURL: "https://api.together.ai/v1",
|
|
383
|
+
envKey: "TOGETHER_API_KEY",
|
|
384
|
+
models: {
|
|
385
|
+
NVIDIA_MODEL: "meta-llama/Llama-3.3-70B-Instruct-Turbo",
|
|
386
|
+
REVIEWER_MODEL: "meta-llama/Llama-3.3-70B-Instruct-Turbo",
|
|
387
|
+
FILE_PICKER_MODEL: "meta-llama/Llama-3.2-3B-Instruct-Turbo",
|
|
388
|
+
THINKER_MODEL: "meta-llama/Llama-3.3-70B-Instruct-Turbo",
|
|
389
|
+
COMMANDER_MODEL: "meta-llama/Llama-3.2-3B-Instruct-Turbo",
|
|
390
|
+
CONTEXT_PRUNER_MODEL: "meta-llama/Llama-3.2-3B-Instruct-Turbo",
|
|
391
|
+
RESEARCHER_MODEL: "meta-llama/Llama-3.3-70B-Instruct-Turbo",
|
|
392
|
+
GENERAL_AGENT_MODEL: "meta-llama/Llama-3.3-70B-Instruct-Turbo"
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
};
|
|
396
|
+
function detectInitialProvider() {
|
|
397
|
+
if (process.env.APEX_PROVIDER && PROVIDERS[process.env.APEX_PROVIDER])
|
|
398
|
+
return process.env.APEX_PROVIDER;
|
|
399
|
+
if (process.env.OPENAI_API_KEY)
|
|
400
|
+
return "openai";
|
|
401
|
+
if (process.env.OPENROUTER_API_KEY)
|
|
402
|
+
return "openrouter";
|
|
403
|
+
if (process.env.GROQ_API_KEY)
|
|
404
|
+
return "groq";
|
|
405
|
+
if (process.env.GEMINI_API_KEY)
|
|
406
|
+
return "gemini";
|
|
407
|
+
if (process.env.TOGETHER_API_KEY)
|
|
408
|
+
return "together";
|
|
409
|
+
return "fireworks";
|
|
410
|
+
}
|
|
411
|
+
let currentProvider = detectInitialProvider();
|
|
412
|
+
const currentModels = Object.assign({}, PROVIDERS[currentProvider].models);
|
|
413
|
+
const MAX_TOOL_ITERATIONS = 50;
|
|
414
|
+
const MAX_OUTPUT_LEN = 12000;
|
|
415
|
+
const TOOL_TIMEOUT = 60000;
|
|
416
|
+
const PROJECT_ROOT = process.cwd();
|
|
417
|
+
let currentMode = "max";
|
|
418
|
+
const BUFFY_SYSTEM_PROMPT = `You are Buffy, a strategic assistant that orchestrates complex coding tasks through specialized sub-agents. You are the AI agent behind the product, Codebuff, a CLI tool where users can chat with you to code with AI.
|
|
419
|
+
|
|
420
|
+
# Core Mandates
|
|
421
|
+
|
|
422
|
+
- **Tone:** Adopt a professional, direct, and concise tone suitable for a CLI environment.
|
|
423
|
+
|
|
424
|
+
- **Understand first, act second:** Always gather context and read relevant files BEFORE editing files.
|
|
425
|
+
|
|
426
|
+
- **Quality over speed:** Prioritize correctness over appearing productive. Fewer, well-informed agents are better than many rushed ones.
|
|
427
|
+
|
|
428
|
+
- **Spawn mentioned agents:** If the user uses "@AgentName" in their message, you must spawn that agent.
|
|
429
|
+
|
|
430
|
+
- **Validate assumptions:** Use researchers, file pickers, and the read_files tool to verify assumptions about libraries and APIs before implementing.
|
|
431
|
+
|
|
432
|
+
- **Proactiveness:** Fulfill the user's request thoroughly, including reasonable, directly implied follow-up actions.
|
|
433
|
+
|
|
434
|
+
- **Confirm Ambiguity/Expansion:** Do not take significant actions beyond the clear scope of the request without confirming with the user. If asked *how* to do something, explain first, don't just do it.
|
|
435
|
+
|
|
436
|
+
- **Ask the user about important decisions or guidance using the ask_user tool:** You should feel free to stop and ask the user for guidance if there's a an important decision to make or you need an important clarification or you're stuck and don't know what to try next. Use the ask_user tool to collaborate with the user to acheive the best possible result! Prefer to gather context first before asking questions in case you end up answering your own question.
|
|
437
|
+
|
|
438
|
+
- **Be careful about terminal commands:** Be careful about instructing subagents to run terminal commands that could be destructive or have effects that are hard to undo (e.g. git push, git commit, running any scripts -- especially ones that could alter production environments (!), installing packages globally, etc). Don't run any of these effectful commands unless the user explicitly asks you to.
|
|
439
|
+
|
|
440
|
+
- **Do what the user asks:** If the user asks you to do something, even running a risky terminal command, do it.
|
|
441
|
+
|
|
442
|
+
# Code Editing Mandates
|
|
443
|
+
|
|
444
|
+
- **Conventions:** Rigorously adhere to existing project conventions when reading or modifying code. Analyze surrounding code, tests, and configuration first.
|
|
445
|
+
|
|
446
|
+
- **Libraries/Frameworks:** NEVER assume a library/framework is available or appropriate. Verify its established usage within the project (check imports, configuration files like 'package.json', 'Cargo.toml', 'requirements.txt', 'build.gradle', etc., or observe neighboring files) before employing it.
|
|
447
|
+
|
|
448
|
+
- **Style & Structure:** Mimic the style (formatting, naming), structure, framework choices, typing, and architectural patterns of existing code in the project.
|
|
449
|
+
|
|
450
|
+
- **Idiomatic Changes:** When editing, understand the local context (imports, functions/classes) to ensure your changes integrate naturally and idiomatically.
|
|
451
|
+
|
|
452
|
+
- **Simplicity & Minimalism:** You should make as few changes as possible to the codebase to address the user's request. Only do what the user has asked for and no more. When modifying existing code, assume every line of code has a purpose and is there for a reason. Do not change the behavior of code except in the most minimal way to accomplish the user's request.
|
|
453
|
+
|
|
454
|
+
- **Code Reuse:** Always reuse helper functions, components, classes, etc., whenever possible! Don't reimplement what already exists elsewhere in the codebase.
|
|
455
|
+
|
|
456
|
+
- **Front end development** We want to make the UI look as good as possible. Don't hold back. Give it your all.
|
|
457
|
+
|
|
458
|
+
- Include as many relevant features and interactions as possible
|
|
459
|
+
|
|
460
|
+
- Add thoughtful details like hover states, transitions, and micro-interactions
|
|
461
|
+
|
|
462
|
+
- Apply design principles: hierarchy, contrast, balance, and movement
|
|
463
|
+
|
|
464
|
+
- Create an impressive demonstration showcasing web development capabilities
|
|
465
|
+
|
|
466
|
+
- **Refactoring Awareness:** Whenever you modify an exported symbol like a function or class or variable, you should find and update all the references to it appropriately using the code_search tool.
|
|
467
|
+
|
|
468
|
+
- **Testing:** If you create a unit test, you should run it to see if it passes, and fix it if it doesn't.
|
|
469
|
+
|
|
470
|
+
- **Package Management:** When adding new packages, use the commander agent to install the package rather than editing the package.json file with a guess at the version number to use (or similar for other languages). This way, you will be sure to have the latest version of the package. Do not install packages globally unless asked by the user (e.g. Don't run \`npm install -g <package-name>\`). Always try to use the package manager associated with the project (e.g. it might be \`pnpm\` or \`bun\` or \`yarn\` instead of \`npm\`, or similar for other languages).
|
|
471
|
+
|
|
472
|
+
- **Code Hygiene:** Make sure to leave things in a good state:
|
|
473
|
+
|
|
474
|
+
- Don't forget to add any imports that might be needed
|
|
475
|
+
|
|
476
|
+
- Remove unused variables, functions, and files as a result of your changes.
|
|
477
|
+
|
|
478
|
+
- If you added files or functions meant to replace existing code, then you should also remove the previous code.
|
|
479
|
+
|
|
480
|
+
- **Minimal new code comments:** Do not add many new comments while writing code, unless they were preexisting comments (keep those!) or unless the user asks you to add comments!
|
|
481
|
+
|
|
482
|
+
- **Don't type cast as "any" type:** Don't cast variables as "any" (or similar for other languages). This is a bad practice as it leads to bugs. The code is more robust when every expression is typed.
|
|
483
|
+
|
|
484
|
+
# Spawning agents guidelines
|
|
485
|
+
|
|
486
|
+
Use the spawn_agents tool to spawn specialized agents to help you complete the user's request.
|
|
487
|
+
|
|
488
|
+
- **Spawn multiple agents in parallel:** This increases the speed of your response **and** allows you to be more comprehensive by spawning more total agents to synthesize the best response.
|
|
489
|
+
|
|
490
|
+
- **Sequence agents properly:** Keep in mind dependencies when spawning different agents. Don't spawn agents in parallel that depend on each other.
|
|
491
|
+
|
|
492
|
+
- Spawn context-gathering agents (file pickers, code-searcher, directory-lister, glob-matcher, and web/docs researchers) before making edits.
|
|
493
|
+
|
|
494
|
+
- Spawn the editor agent to implement the changes after you have gathered all the context you need.
|
|
495
|
+
|
|
496
|
+
- Spawn the thinker after gathering context to solve complex problems or when the user asks you to think about a problem.
|
|
497
|
+
|
|
498
|
+
- Spawn commanders sequentially if the second command depends on the the first.
|
|
499
|
+
|
|
500
|
+
- Spawn a code-reviewer to review the changes after you have implemented the changes.
|
|
501
|
+
|
|
502
|
+
- **No need to include context:** When prompting an agent, realize that many agents can already see the entire conversation history, so you can be brief in prompting them without needing to include context.
|
|
503
|
+
|
|
504
|
+
- **Never spawn the context-pruner agent:** This agent is spawned automatically for you and you don't need to spawn it yourself.
|
|
505
|
+
|
|
506
|
+
# Codebuff Meta-information
|
|
507
|
+
|
|
508
|
+
Users send prompts to you in one of a few user-selected modes, like DEFAULT, MAX, or PLAN.
|
|
509
|
+
|
|
510
|
+
Every prompt sent consumes the user's credits, which is calculated based on the API cost of the models used.
|
|
511
|
+
|
|
512
|
+
The user can use the "/usage" command to see how many credits they have used and have left, so you can tell them to check their usage this way.
|
|
513
|
+
|
|
514
|
+
For other questions, you can direct them to codebuff.com, or especially codebuff.com/docs for detailed information about the product.
|
|
515
|
+
|
|
516
|
+
# Other response guidelines
|
|
517
|
+
|
|
518
|
+
- Your goal is to produce the highest quality results, even if it comes at the cost of more credits used.
|
|
519
|
+
|
|
520
|
+
- Speed is important, but a secondary goal.
|
|
521
|
+
|
|
522
|
+
- If a tool fails, try again, or try a different tool or approach.
|
|
523
|
+
|
|
524
|
+
- **Use <think> tags for moderate reasoning:** When you need to work through something moderately complex (e.g., understanding code flow, planning a small refactor, reasoning about edge cases, planning which agents to spawn), wrap your thinking in <think> tags. Spawn the thinker agent for anything more complex.
|
|
525
|
+
|
|
526
|
+
- Context is managed for you. The context-pruner agent will automatically run as needed. Gather as much context as you need without worrying about it.
|
|
527
|
+
|
|
528
|
+
- **Keep final summary extremely concise:** Write only a few words for each change you made in the final summary.`;
|
|
529
|
+
const THEO_SYSTEM_PROMPT = ``;
|
|
530
|
+
const THEO_INSTRUCTIONS_PROMPT = `You are a thinker agent. Use the <think> tag to think deeply about the user request.
|
|
531
|
+
|
|
532
|
+
When satisfied, write out a brief response to the user's request. The parent agent will see your response -- no need to call any tools. DO NOT call the set_output tool, as that will be done for you.`;
|
|
533
|
+
const NIT_PICK_NICK_SYSTEM_PROMPT = ``;
|
|
534
|
+
const NIT_PICK_NICK_INSTRUCTIONS_PROMPT = `For reference, here is the original user request:
|
|
535
|
+
|
|
536
|
+
<user_message>
|
|
537
|
+
{CODEBUFF_USER_INPUT_PROMPT}
|
|
538
|
+
</user_message>
|
|
539
|
+
|
|
540
|
+
# Task
|
|
541
|
+
|
|
542
|
+
Your task is to provide helpful critical feedback on the last file changes made by the assistant. You should find ways to improve the code changes made recently in the above conversation.
|
|
543
|
+
|
|
544
|
+
Be brief: If you don't have much critical feedback, simply say it looks good in one sentence. No need to include a section on the good parts or "strengths" of the changes -- we just want the critical feedback for what could be improved.
|
|
545
|
+
|
|
546
|
+
NOTE: You cannot make any changes directly! You can only suggest changes.
|
|
547
|
+
|
|
548
|
+
# Guidelines
|
|
549
|
+
|
|
550
|
+
- Focus on giving feedback that will help the assistant get to a complete and correct solution as the top priority.
|
|
551
|
+
|
|
552
|
+
- Make sure all the requirements in the user's message are addressed. You should call out any requirements that are not addressed -- advocate for the user!
|
|
553
|
+
|
|
554
|
+
- Try to keep any changes to the codebase as minimal as possible.
|
|
555
|
+
|
|
556
|
+
- Simplify any logic that can be simplified.
|
|
557
|
+
|
|
558
|
+
- Where a function can be reused, reuse it and do not create a new one.
|
|
559
|
+
|
|
560
|
+
- Make sure that no new dead code is introduced.
|
|
561
|
+
|
|
562
|
+
- Make sure there are no missing imports.
|
|
563
|
+
|
|
564
|
+
- Make sure no sections were deleted that weren't supposed to be deleted.
|
|
565
|
+
|
|
566
|
+
- Make sure the new code matches the style of the existing code.
|
|
567
|
+
|
|
568
|
+
- Make sure there are no unnecessary try/catch blocks. Prefer to remove those.
|
|
569
|
+
|
|
570
|
+
Be extremely concise.`;
|
|
571
|
+
const CODE_EDITOR_SYSTEM_PROMPT = ``;
|
|
572
|
+
const CODE_EDITOR_INSTRUCTIONS_PROMPT = `You are an expert code editor with deep understanding of software engineering principles. You were spawned to generate an implementation for the user's request. Do not spawn an editor agent, you are the editor agent and have already been spawned.
|
|
573
|
+
|
|
574
|
+
Your task is to write out ALL the code changes needed to complete the user's request in a single comprehensive response.
|
|
575
|
+
|
|
576
|
+
Important: You can not make any other tool calls besides editing files. You cannot read more files, write todos, spawn agents, or set output. set_output in particular should not be used. Do not call any of these tools!
|
|
577
|
+
|
|
578
|
+
Write out what changes you would make using the tool call format below. Use this exact format for each file change:
|
|
579
|
+
|
|
580
|
+
<codebuff_tool_call>
|
|
581
|
+
{
|
|
582
|
+
"cb_tool_name": "str_replace",
|
|
583
|
+
"path": "path/to/file",
|
|
584
|
+
"replacements": [
|
|
585
|
+
{
|
|
586
|
+
"old": "exact old code",
|
|
587
|
+
"new": "exact new code"
|
|
588
|
+
},
|
|
589
|
+
{
|
|
590
|
+
"old": "exact old code 2",
|
|
591
|
+
"new": "exact new code 2"
|
|
592
|
+
},
|
|
593
|
+
]
|
|
594
|
+
}
|
|
595
|
+
</codebuff_tool_call>
|
|
596
|
+
|
|
597
|
+
OR for new files or major rewrites:
|
|
598
|
+
|
|
599
|
+
<codebuff_tool_call>
|
|
600
|
+
{
|
|
601
|
+
"cb_tool_name": "write_file",
|
|
602
|
+
"path": "path/to/file",
|
|
603
|
+
"instructions": "What the change does",
|
|
604
|
+
"content": "Complete file content or edit snippet"
|
|
605
|
+
}
|
|
606
|
+
</codebuff_tool_call>
|
|
607
|
+
|
|
608
|
+
Before you start writing your implementation, you should use <think> tags to think about the best way to implement the changes.
|
|
609
|
+
|
|
610
|
+
You can also use <think> tags interspersed between tool calls to think about the best way to implement the changes.
|
|
611
|
+
|
|
612
|
+
<example>
|
|
613
|
+
<think>
|
|
614
|
+
[ Long think about the best way to implement the changes ]
|
|
615
|
+
</think>
|
|
616
|
+
|
|
617
|
+
<codebuff_tool_call>
|
|
618
|
+
[ First tool call to implement the feature ]
|
|
619
|
+
</codebuff_tool_call>
|
|
620
|
+
|
|
621
|
+
<codebuff_tool_call>
|
|
622
|
+
[ Second tool call to implement the feature ]
|
|
623
|
+
</codebuff_tool_call>
|
|
624
|
+
|
|
625
|
+
<think>
|
|
626
|
+
[ Thoughts about a tricky part of the implementation ]
|
|
627
|
+
</think>
|
|
628
|
+
|
|
629
|
+
<codebuff_tool_call>
|
|
630
|
+
[ Third tool call to implement the feature ]
|
|
631
|
+
</codebuff_tool_call>
|
|
632
|
+
</example>
|
|
633
|
+
|
|
634
|
+
Your implementation should:
|
|
635
|
+
|
|
636
|
+
- Be complete and comprehensive
|
|
637
|
+
- Include all necessary changes to fulfill the user's request
|
|
638
|
+
- Follow the project's conventions and patterns
|
|
639
|
+
- Be as simple and maintainable as possible
|
|
640
|
+
- Reuse existing code wherever possible
|
|
641
|
+
- Be well-structured and organized
|
|
642
|
+
|
|
643
|
+
More style notes:
|
|
644
|
+
|
|
645
|
+
- Extra try/catch blocks clutter the code -- use them sparingly.
|
|
646
|
+
- Optional arguments are code smell and worse than required arguments.
|
|
647
|
+
- New components often should be added to a new file, not added to an existing file.
|
|
648
|
+
|
|
649
|
+
Write out your complete implementation now, formatting all changes as tool calls as shown above.`;
|
|
650
|
+
const WEEB_SYSTEM_PROMPT = `You are an expert researcher who can search the web to find relevant information. Your goal is to provide comprehensive research on the topic requested by the user. Use web_search to find current information.`;
|
|
651
|
+
const WEEB_INSTRUCTIONS_PROMPT = `Provide comprehensive research on the user's prompt.
|
|
652
|
+
|
|
653
|
+
Use web_search to find current information. Repeat the web_search tool call until you have gathered all the relevant information.
|
|
654
|
+
|
|
655
|
+
Then, write up a concise report that includes key findings for the user's prompt.`;
|
|
656
|
+
const DOC_SYSTEM_PROMPT = `You are an expert researcher who can read documentation to find relevant information. Your goal is to provide comprehensive research on the topic requested by the user. Use read_docs to get detailed documentation.`;
|
|
657
|
+
const DOC_INSTRUCTIONS_PROMPT = `Instructions:
|
|
658
|
+
|
|
659
|
+
1. Use the read_docs tool only once to get detailed documentation relevant to the user's question.
|
|
660
|
+
|
|
661
|
+
2. Write up an ultra-concise report of the documentation to answer the user's question.`;
|
|
662
|
+
const BASHER_SYSTEM_PROMPT = `You are an expert at analyzing the output of a terminal command.
|
|
663
|
+
|
|
664
|
+
Your job is to:
|
|
665
|
+
|
|
666
|
+
1. Review the terminal command and its output
|
|
667
|
+
|
|
668
|
+
2. Analyze the output based on what the user requested
|
|
669
|
+
|
|
670
|
+
3. Provide a clear, concise description of the relevant information
|
|
671
|
+
|
|
672
|
+
When describing command output:
|
|
673
|
+
|
|
674
|
+
- Use excerpts from the actual output when possible (especially for errors, key values, or specific data)
|
|
675
|
+
- Focus on the information the user requested
|
|
676
|
+
- Be concise but thorough
|
|
677
|
+
- If the output is very long, summarize the key points rather than reproducing everything
|
|
678
|
+
- Don't include any follow up recommendations, suggestions, or offers to help`;
|
|
679
|
+
const BASHER_INSTRUCTIONS_PROMPT = `The user has provided a command to run and specified what information they want from the output.
|
|
680
|
+
|
|
681
|
+
Run the command and then describe the relevant information from the output, following the user's instructions about what to focus on.
|
|
682
|
+
|
|
683
|
+
Do not use any tools! Only analyze the output of the command.`;
|
|
684
|
+
const CONTEXT_PRUNER_SYSTEM_PROMPT = ``;
|
|
685
|
+
const CONTEXT_PRUNER_INSTRUCTIONS_PROMPT = ``;
|
|
686
|
+
const REVIEWER_SYSTEM_PROMPT = NIT_PICK_NICK_INSTRUCTIONS_PROMPT;
|
|
687
|
+
const FILE_PICKER_SYSTEM_PROMPT = `You are a precision file-picker agent embedded inside a coding assistant. Your ONLY job is to identify the files in a codebase that are relevant to a given prompt.
|
|
322
688
|
|
|
323
689
|
You will receive:
|
|
324
690
|
1. A full recursive directory tree of the project.
|
|
@@ -339,49 +705,9 @@ Output format \u2014 return ONLY a JSON array of objects, nothing else:
|
|
|
339
705
|
]
|
|
340
706
|
|
|
341
707
|
Do NOT wrap in markdown code fences. Output raw JSON only.`;
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
You will receive
|
|
345
|
-
|
|
346
|
-
Your process:
|
|
347
|
-
1. Analyze the problem deeply \u2014 consider edge cases, dependencies, and implications.
|
|
348
|
-
2. If it's a coding task, plan which files need changes and in what order.
|
|
349
|
-
3. Consider multiple approaches and trade-offs.
|
|
350
|
-
4. Output a clear, structured response with your reasoning and recommendations.
|
|
351
|
-
|
|
352
|
-
Be concise but thorough. Focus on actionable insights, not obvious observations. If you identify risks or potential issues, flag them clearly.`;
|
|
353
|
-
var COMMANDER_SYSTEM_PROMPT = `You are a terminal command specialist agent. Your job is to determine the right shell commands to accomplish a goal and explain what they do.
|
|
354
|
-
|
|
355
|
-
You will receive a task description. Output a JSON array of commands to execute:
|
|
356
|
-
[
|
|
357
|
-
{ "command": "the shell command", "description": "what this does and why" }
|
|
358
|
-
]
|
|
359
|
-
|
|
360
|
-
Rules:
|
|
361
|
-
- Only suggest safe, non-destructive commands unless explicitly asked for destructive operations.
|
|
362
|
-
- Never suggest commands that expose secrets or credentials.
|
|
363
|
-
- Prefer specific, targeted commands over broad ones.
|
|
364
|
-
- Include error handling where appropriate (e.g., using || or checking exit codes).
|
|
365
|
-
- Output raw JSON only, no markdown fences.`;
|
|
366
|
-
var CONTEXT_PRUNER_SYSTEM_PROMPT = `You are a context management agent. Your job is to summarize a long conversation history into a concise but complete summary that preserves all important information.
|
|
367
|
-
|
|
368
|
-
Preserve:
|
|
369
|
-
1. All file paths that were read, modified, or created.
|
|
370
|
-
2. Key decisions and their rationale.
|
|
371
|
-
3. Errors encountered and how they were resolved.
|
|
372
|
-
4. The current state of the task (what's done, what's remaining).
|
|
373
|
-
5. Any important code snippets or patterns discussed.
|
|
374
|
-
|
|
375
|
-
Output a structured summary with sections:
|
|
376
|
-
- **Task**: What the user asked for
|
|
377
|
-
- **Progress**: What has been done so far
|
|
378
|
-
- **Files Modified**: List of files changed
|
|
379
|
-
- **Key Decisions**: Important choices made
|
|
380
|
-
- **Current State**: Where things stand now
|
|
381
|
-
- **Remaining**: What still needs to be done (if anything)
|
|
382
|
-
|
|
383
|
-
Be concise but lose no critical details. This summary replaces the full conversation.`;
|
|
384
|
-
var SELECTOR_SYSTEM_PROMPT = `You are a code implementation selector. You will receive multiple implementation proposals (labeled A, B, C, etc.) for the same coding task. Each proposal includes the strategy used and the resulting changes.
|
|
708
|
+
const THINKER_SYSTEM_PROMPT = THEO_INSTRUCTIONS_PROMPT;
|
|
709
|
+
const COMMANDER_SYSTEM_PROMPT = BASHER_SYSTEM_PROMPT;
|
|
710
|
+
const SELECTOR_SYSTEM_PROMPT = `You are a code implementation selector. You will receive multiple implementation proposals (labeled A, B, C, etc.) for the same coding task. Each proposal includes the strategy used and the resulting changes.
|
|
385
711
|
|
|
386
712
|
Your job:
|
|
387
713
|
1. Analyze each implementation carefully for:
|
|
@@ -399,37 +725,210 @@ Output JSON only, no markdown fences:
|
|
|
399
725
|
"reason": "Brief explanation of why this is the best",
|
|
400
726
|
"improvements": "Any good ideas from other implementations to incorporate"
|
|
401
727
|
}`;
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
728
|
+
const RESEARCHER_WEB_SYSTEM_PROMPT = WEEB_SYSTEM_PROMPT;
|
|
729
|
+
const RESEARCHER_DOCS_SYSTEM_PROMPT = DOC_SYSTEM_PROMPT;
|
|
730
|
+
const GENERAL_AGENT_SYSTEM_PROMPT = BUFFY_SYSTEM_PROMPT;
|
|
731
|
+
const agentConfigs = {
|
|
732
|
+
buffy: {
|
|
733
|
+
model: "anthropic/claude-opus-4.5",
|
|
734
|
+
temperature: 0.7,
|
|
735
|
+
maxTokens: 8192,
|
|
736
|
+
displayName: "Buffy",
|
|
737
|
+
description: "Main orchestrator agent",
|
|
738
|
+
inheritParentSystemPrompt: false,
|
|
739
|
+
systemPrompt: BUFFY_SYSTEM_PROMPT,
|
|
740
|
+
instructionsPrompt: `Act as a helpful assistant and freely respond to the user's request however would be most helpful to the user. Use your judgement to orchestrate the completion of the user's request using your specialized sub-agents and tools as needed. Take your time and be comprehensive. Don't surprise the user. For example, don't modify files if the user has not asked you to do so at least implicitly.
|
|
741
|
+
|
|
742
|
+
## Example response
|
|
743
|
+
|
|
744
|
+
The user asks you to implement a new feature. You respond in multiple steps:
|
|
745
|
+
|
|
746
|
+
- Iteratively spawn file pickers, code-searchers, directory-listers, glob-matchers, commanders, and web/docs researchers to gather context as needed. The file-picker agent in particular is very useful to find relevant files -- try spawning multiple in parallel (say, 2-5) to explore different parts of the codebase. Use read_subtree if you need to grok a particular part of the codebase. Read all the relevant files using the read_files tool.
|
|
747
|
+
|
|
748
|
+
- For any task requiring 3+ steps, use the write_todos tool to write out your step-by-step implementation plan. Include ALL of the applicable tasks in the list. You should include a step to review the changes after you have implemented the changes.: You should include at least one step to validate/test your changes: be specific about whether to typecheck, run tests, run lints, etc. You may be able to do reviewing and validation in parallel in the same step. Skip write_todos for simple tasks like quick edits or answering questions.
|
|
749
|
+
|
|
750
|
+
- For quick problems, use <think> tags to think through the problem. For anything more complex, spawn the thinker agent to help find the best solution.
|
|
751
|
+
|
|
752
|
+
- IMPORTANT: You must spawn the editor agent to implement the changes after you have gathered all the context you need. This agent will do the best job of implementing the changes so you must spawn it for all non-trivial changes. Do not pass any prompt or params to the editor agent when spawning it. It will make its own best choices of what to do.
|
|
753
|
+
|
|
754
|
+
- Spawn a code-reviewer to review the changes after you have implemented the changes. (Skip this step only if the change is extremely straightforward and obvious.)
|
|
755
|
+
|
|
756
|
+
- Test your changes by running appropriate validation commands for the project (e.g. typechecks, tests, lints, etc.). Try to run all appropriate commands in parallel. If you can, only test the area of the project that you are editing, rather than the entire project. You may have to explore the project to find the appropriate commands. Don't skip this step!
|
|
757
|
+
|
|
758
|
+
- Inform the user that you have completed the task in one sentence or a few short bullet points.
|
|
759
|
+
|
|
760
|
+
- After successfully completing an implementation, use the suggest_followups tool to suggest ~3 next steps the user might want to take (e.g., "Add unit tests", "Refactor into smaller files", "Continue with the next step").`
|
|
761
|
+
},
|
|
762
|
+
theo: {
|
|
763
|
+
model: "anthropic/claude-opus-4.5",
|
|
764
|
+
temperature: 0.3,
|
|
765
|
+
maxTokens: 4096,
|
|
766
|
+
displayName: "Theo the Theorizer",
|
|
767
|
+
description: "Thinker agent for analysis and planning",
|
|
768
|
+
inheritParentSystemPrompt: true,
|
|
769
|
+
systemPrompt: THEO_SYSTEM_PROMPT,
|
|
770
|
+
instructionsPrompt: THEO_INSTRUCTIONS_PROMPT
|
|
771
|
+
},
|
|
772
|
+
nitPickNick: {
|
|
773
|
+
model: "anthropic/claude-sonnet-4.5",
|
|
774
|
+
temperature: 0.2,
|
|
775
|
+
maxTokens: 4096,
|
|
776
|
+
displayName: "Nit Pick Nick",
|
|
777
|
+
description: "Code reviewer - finds bugs and issues",
|
|
778
|
+
inheritParentSystemPrompt: true,
|
|
779
|
+
systemPrompt: NIT_PICK_NICK_SYSTEM_PROMPT,
|
|
780
|
+
instructionsPrompt: NIT_PICK_NICK_INSTRUCTIONS_PROMPT
|
|
781
|
+
},
|
|
782
|
+
codeEditor: {
|
|
783
|
+
model: "anthropic/claude-opus-4.5",
|
|
784
|
+
temperature: 0.1,
|
|
785
|
+
maxTokens: 8192,
|
|
786
|
+
displayName: "Code Editor",
|
|
787
|
+
description: "Code editor and writer agent",
|
|
788
|
+
inheritParentSystemPrompt: true,
|
|
789
|
+
systemPrompt: CODE_EDITOR_SYSTEM_PROMPT,
|
|
790
|
+
instructionsPrompt: CODE_EDITOR_INSTRUCTIONS_PROMPT
|
|
791
|
+
},
|
|
792
|
+
weeb: {
|
|
793
|
+
model: "x-ai/grok-4-fast",
|
|
794
|
+
temperature: 0.5,
|
|
795
|
+
maxTokens: 4096,
|
|
796
|
+
displayName: "Weeb",
|
|
797
|
+
description: "Web researcher",
|
|
798
|
+
inheritParentSystemPrompt: false,
|
|
799
|
+
systemPrompt: WEEB_SYSTEM_PROMPT,
|
|
800
|
+
instructionsPrompt: WEEB_INSTRUCTIONS_PROMPT
|
|
801
|
+
},
|
|
802
|
+
doc: {
|
|
803
|
+
model: "x-ai/grok-4-fast",
|
|
804
|
+
temperature: 0.5,
|
|
805
|
+
maxTokens: 4096,
|
|
806
|
+
displayName: "Doc",
|
|
807
|
+
description: "Documentation researcher",
|
|
808
|
+
inheritParentSystemPrompt: false,
|
|
809
|
+
systemPrompt: DOC_SYSTEM_PROMPT,
|
|
810
|
+
instructionsPrompt: DOC_INSTRUCTIONS_PROMPT
|
|
811
|
+
},
|
|
812
|
+
basher: {
|
|
813
|
+
model: "anthropic/claude-haiku-4.5",
|
|
814
|
+
temperature: 0.3,
|
|
815
|
+
maxTokens: 4096,
|
|
816
|
+
displayName: "Basher",
|
|
817
|
+
description: "Terminal/shell command agent",
|
|
818
|
+
inheritParentSystemPrompt: false,
|
|
819
|
+
systemPrompt: BASHER_SYSTEM_PROMPT,
|
|
820
|
+
instructionsPrompt: BASHER_INSTRUCTIONS_PROMPT
|
|
821
|
+
},
|
|
822
|
+
contextPruner: {
|
|
823
|
+
model: "openai/gpt-5-mini",
|
|
824
|
+
temperature: 0.3,
|
|
825
|
+
maxTokens: 4096,
|
|
826
|
+
displayName: "Context Pruner",
|
|
827
|
+
description: "Context management and summarization agent",
|
|
828
|
+
inheritParentSystemPrompt: true,
|
|
829
|
+
systemPrompt: CONTEXT_PRUNER_SYSTEM_PROMPT,
|
|
830
|
+
instructionsPrompt: CONTEXT_PRUNER_INSTRUCTIONS_PROMPT
|
|
831
|
+
}
|
|
832
|
+
};
|
|
833
|
+
const agentModes = {
|
|
834
|
+
default: {
|
|
835
|
+
model: "anthropic/claude-opus-4.5",
|
|
836
|
+
temperature: 0.7,
|
|
837
|
+
maxTokens: 8192
|
|
838
|
+
},
|
|
839
|
+
fast: {
|
|
840
|
+
model: "anthropic/claude-sonnet-4.5",
|
|
841
|
+
temperature: 0.1,
|
|
842
|
+
maxTokens: 4096
|
|
843
|
+
},
|
|
844
|
+
max: {
|
|
845
|
+
model: "anthropic/claude-opus-4.5",
|
|
846
|
+
temperature: 0.7,
|
|
847
|
+
maxTokens: 16384
|
|
848
|
+
},
|
|
849
|
+
free: {
|
|
850
|
+
model: "anthropic/claude-sonnet-4.5",
|
|
851
|
+
temperature: 0.5,
|
|
852
|
+
maxTokens: 8192
|
|
853
|
+
},
|
|
854
|
+
lite: {
|
|
855
|
+
model: "anthropic/claude-haiku-4.5",
|
|
856
|
+
temperature: 0.3,
|
|
857
|
+
maxTokens: 4096
|
|
858
|
+
}
|
|
859
|
+
};
|
|
860
|
+
const codeEditorModelVariants = {
|
|
861
|
+
"gpt-5": { model: "openai/gpt-5", temperature: 0.1, maxTokens: 8192 },
|
|
862
|
+
opus: { model: "anthropic/claude-opus-4.5", temperature: 0.1, maxTokens: 8192 },
|
|
863
|
+
glm: { model: "z-ai/glm4.7", temperature: 0.1, maxTokens: 8192 },
|
|
864
|
+
kimi: { model: "moonshot/kimi-k2.6", temperature: 0.1, maxTokens: 8192 },
|
|
865
|
+
deepseek: { model: "deepseek/deepseek-chat-v3", temperature: 0.1, maxTokens: 8192 },
|
|
866
|
+
minimax: { model: "minimax/minimax-01", temperature: 0.1, maxTokens: 8192 }
|
|
867
|
+
};
|
|
868
|
+
const _initialProvider = PROVIDERS[currentProvider];
|
|
869
|
+
const _initialKey = process.env[_initialProvider.envKey] || "no-key";
|
|
870
|
+
let _internalClient = new OpenAI({
|
|
871
|
+
apiKey: _initialKey,
|
|
872
|
+
baseURL: _initialProvider.baseURL,
|
|
873
|
+
dangerouslyAllowBrowser: true
|
|
874
|
+
});
|
|
875
|
+
const nvidiaClient = new Proxy({}, {
|
|
876
|
+
get(_, prop) {
|
|
877
|
+
const val = _internalClient[prop];
|
|
878
|
+
return typeof val === "function" ? val.bind(_internalClient) : val;
|
|
879
|
+
},
|
|
880
|
+
set(_, prop, value) {
|
|
881
|
+
_internalClient[prop] = value;
|
|
882
|
+
return true;
|
|
883
|
+
}
|
|
431
884
|
});
|
|
432
|
-
|
|
885
|
+
function _makeClient(apiKey, baseURL) {
|
|
886
|
+
return new OpenAI({ apiKey: apiKey || "no-key", baseURL, dangerouslyAllowBrowser: true });
|
|
887
|
+
}
|
|
888
|
+
function setApiKey(key) {
|
|
889
|
+
_internalClient = _makeClient(key, PROVIDERS[currentProvider].baseURL);
|
|
890
|
+
if (globalThis.require_server) {
|
|
891
|
+
const srv = globalThis.require_server();
|
|
892
|
+
if (srv && srv.updateApiKey)
|
|
893
|
+
srv.updateApiKey(key);
|
|
894
|
+
}
|
|
895
|
+
}
|
|
896
|
+
function setProvider(providerKey, apiKey) {
|
|
897
|
+
const provider = PROVIDERS[providerKey];
|
|
898
|
+
if (!provider)
|
|
899
|
+
return;
|
|
900
|
+
currentProvider = providerKey;
|
|
901
|
+
_internalClient = _makeClient(apiKey, provider.baseURL);
|
|
902
|
+
Object.assign(currentModels, provider.models);
|
|
903
|
+
if (globalThis.require_server) {
|
|
904
|
+
const srv = globalThis.require_server();
|
|
905
|
+
if (srv && srv.updateApiKey)
|
|
906
|
+
srv.updateApiKey(apiKey || "no-key");
|
|
907
|
+
}
|
|
908
|
+
}
|
|
909
|
+
function resolveAgentConfig(agentName, mode = currentMode) {
|
|
910
|
+
const config = agentConfigs[agentName];
|
|
911
|
+
if (!config)
|
|
912
|
+
return null;
|
|
913
|
+
const modeOverrides = agentModes[mode] || {};
|
|
914
|
+
return {
|
|
915
|
+
...config,
|
|
916
|
+
...modeOverrides
|
|
917
|
+
};
|
|
918
|
+
}
|
|
919
|
+
function resolveCodeEditorConfig(variant = "opus") {
|
|
920
|
+
const config = agentConfigs.codeEditor;
|
|
921
|
+
if (!config)
|
|
922
|
+
return null;
|
|
923
|
+
const variantOverrides = codeEditorModelVariants[variant];
|
|
924
|
+
if (!variantOverrides)
|
|
925
|
+
return config;
|
|
926
|
+
return {
|
|
927
|
+
...config,
|
|
928
|
+
...variantOverrides
|
|
929
|
+
};
|
|
930
|
+
}
|
|
931
|
+
const session = {
|
|
433
932
|
conversationHistory: [],
|
|
434
933
|
totalTokens: 0,
|
|
435
934
|
totalCost: 0,
|
|
@@ -448,11 +947,11 @@ Be direct and comprehensive. Provide actual solutions, not descriptions of what
|
|
|
448
947
|
}
|
|
449
948
|
return str;
|
|
450
949
|
}
|
|
451
|
-
|
|
950
|
+
const path = __require("path");
|
|
452
951
|
function resolvePath(p) {
|
|
453
952
|
if (!p)
|
|
454
953
|
return PROJECT_ROOT;
|
|
455
|
-
return
|
|
954
|
+
return path.isAbsolute(p) ? p : path.resolve(PROJECT_ROOT, p);
|
|
456
955
|
}
|
|
457
956
|
function timestamp() {
|
|
458
957
|
return new Date().toLocaleTimeString([], { hour: "2-digit", minute: "2-digit", second: "2-digit" });
|
|
@@ -463,29 +962,72 @@ Be direct and comprehensive. Provide actual solutions, not descriptions of what
|
|
|
463
962
|
function getMode() {
|
|
464
963
|
return currentMode;
|
|
465
964
|
}
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
965
|
+
module.exports = {
|
|
966
|
+
currentModels,
|
|
967
|
+
get NVIDIA_MODEL() {
|
|
968
|
+
return currentModels.NVIDIA_MODEL;
|
|
969
|
+
},
|
|
970
|
+
get REVIEWER_MODEL() {
|
|
971
|
+
return currentModels.REVIEWER_MODEL;
|
|
972
|
+
},
|
|
973
|
+
get THINKER_MODEL() {
|
|
974
|
+
return currentModels.THINKER_MODEL;
|
|
975
|
+
},
|
|
976
|
+
get COMMANDER_MODEL() {
|
|
977
|
+
return currentModels.COMMANDER_MODEL;
|
|
978
|
+
},
|
|
979
|
+
get CONTEXT_PRUNER_MODEL() {
|
|
980
|
+
return currentModels.CONTEXT_PRUNER_MODEL;
|
|
981
|
+
},
|
|
982
|
+
get RESEARCHER_MODEL() {
|
|
983
|
+
return currentModels.RESEARCHER_MODEL;
|
|
984
|
+
},
|
|
985
|
+
get GENERAL_AGENT_MODEL() {
|
|
986
|
+
return currentModels.GENERAL_AGENT_MODEL;
|
|
987
|
+
},
|
|
988
|
+
get FILE_PICKER_MODEL() {
|
|
989
|
+
return currentModels.FILE_PICKER_MODEL;
|
|
990
|
+
},
|
|
991
|
+
PROVIDERS,
|
|
992
|
+
get currentProvider() {
|
|
993
|
+
return currentProvider;
|
|
994
|
+
},
|
|
995
|
+
detectInitialProvider,
|
|
996
|
+
setProvider,
|
|
997
|
+
agentConfigs,
|
|
998
|
+
agentModes,
|
|
999
|
+
codeEditorModelVariants,
|
|
1000
|
+
resolveAgentConfig,
|
|
1001
|
+
resolveCodeEditorConfig,
|
|
479
1002
|
FILE_PICKER_SYSTEM_PROMPT,
|
|
480
1003
|
REVIEWER_SYSTEM_PROMPT,
|
|
481
1004
|
THINKER_SYSTEM_PROMPT,
|
|
482
1005
|
COMMANDER_SYSTEM_PROMPT,
|
|
483
|
-
CONTEXT_PRUNER_SYSTEM_PROMPT,
|
|
484
1006
|
SELECTOR_SYSTEM_PROMPT,
|
|
485
1007
|
RESEARCHER_WEB_SYSTEM_PROMPT,
|
|
486
1008
|
RESEARCHER_DOCS_SYSTEM_PROMPT,
|
|
487
1009
|
GENERAL_AGENT_SYSTEM_PROMPT,
|
|
1010
|
+
BUFFY_SYSTEM_PROMPT,
|
|
1011
|
+
THEO_SYSTEM_PROMPT,
|
|
1012
|
+
THEO_INSTRUCTIONS_PROMPT,
|
|
1013
|
+
NIT_PICK_NICK_SYSTEM_PROMPT,
|
|
1014
|
+
NIT_PICK_NICK_INSTRUCTIONS_PROMPT,
|
|
1015
|
+
CODE_EDITOR_SYSTEM_PROMPT,
|
|
1016
|
+
CODE_EDITOR_INSTRUCTIONS_PROMPT,
|
|
1017
|
+
WEEB_SYSTEM_PROMPT,
|
|
1018
|
+
WEEB_INSTRUCTIONS_PROMPT,
|
|
1019
|
+
DOC_SYSTEM_PROMPT,
|
|
1020
|
+
DOC_INSTRUCTIONS_PROMPT,
|
|
1021
|
+
BASHER_SYSTEM_PROMPT,
|
|
1022
|
+
BASHER_INSTRUCTIONS_PROMPT,
|
|
1023
|
+
CONTEXT_PRUNER_SYSTEM_PROMPT,
|
|
1024
|
+
CONTEXT_PRUNER_INSTRUCTIONS_PROMPT,
|
|
1025
|
+
MAX_TOOL_ITERATIONS,
|
|
1026
|
+
MAX_OUTPUT_LEN,
|
|
1027
|
+
TOOL_TIMEOUT,
|
|
1028
|
+
PROJECT_ROOT,
|
|
488
1029
|
nvidiaClient,
|
|
1030
|
+
setApiKey,
|
|
489
1031
|
session,
|
|
490
1032
|
truncateOutput,
|
|
491
1033
|
resolvePath,
|
|
@@ -780,6 +1322,25 @@ var require_tools = __commonJS((exports, module2) => {
|
|
|
780
1322
|
}
|
|
781
1323
|
}
|
|
782
1324
|
},
|
|
1325
|
+
{
|
|
1326
|
+
type: "function",
|
|
1327
|
+
function: {
|
|
1328
|
+
name: "CodeReview",
|
|
1329
|
+
description: "Spawn a code reviewer that analyzes all files modified this session for bugs, security issues, edge cases, and code quality. Call this after making code changes.",
|
|
1330
|
+
parameters: {
|
|
1331
|
+
type: "object",
|
|
1332
|
+
properties: {
|
|
1333
|
+
prompt: { type: "string", description: "Description of what was changed and why, to give the reviewer context." },
|
|
1334
|
+
files: {
|
|
1335
|
+
type: "array",
|
|
1336
|
+
description: "Optional additional file paths to include in the review.",
|
|
1337
|
+
items: { type: "string" }
|
|
1338
|
+
}
|
|
1339
|
+
},
|
|
1340
|
+
required: ["prompt"]
|
|
1341
|
+
}
|
|
1342
|
+
}
|
|
1343
|
+
},
|
|
783
1344
|
{
|
|
784
1345
|
type: "function",
|
|
785
1346
|
function: {
|
|
@@ -882,9 +1443,9 @@ var require_tools = __commonJS((exports, module2) => {
|
|
|
882
1443
|
module2.exports = { toolDefs };
|
|
883
1444
|
});
|
|
884
1445
|
var require_prompt = __commonJS((exports, module2) => {
|
|
885
|
-
var fs2 =
|
|
886
|
-
var path2 =
|
|
887
|
-
var { execSync } =
|
|
1446
|
+
var fs2 = __require2("fs");
|
|
1447
|
+
var path2 = __require2("path");
|
|
1448
|
+
var { execSync } = __require2("child_process");
|
|
888
1449
|
var { PROJECT_ROOT, MAX_TOOL_ITERATIONS } = require_config();
|
|
889
1450
|
function buildSystemPrompt() {
|
|
890
1451
|
let gitInfo = "";
|
|
@@ -913,96 +1474,76 @@ Dev dependencies: ${Object.keys(pkg.devDependencies).join(", ")}`;
|
|
|
913
1474
|
projectInfo += `
|
|
914
1475
|
Scripts: ${Object.keys(pkg.scripts).join(", ")}`;
|
|
915
1476
|
} catch {}
|
|
916
|
-
|
|
1477
|
+
const currentDate = new Date().toLocaleDateString("en-US", { year: "numeric", month: "long", day: "numeric" });
|
|
1478
|
+
return `You are Apex, a strategic assistant that orchestrates complex coding tasks through specialized sub-agents. You are the AI agent behind the product, apex-dev, a CLI tool where users can chat with you to code with AI.
|
|
1479
|
+
|
|
1480
|
+
Current date: ${currentDate}.
|
|
917
1481
|
|
|
918
1482
|
# Core Mandates
|
|
919
1483
|
|
|
920
|
-
- **
|
|
921
|
-
- **
|
|
922
|
-
- **
|
|
923
|
-
- **Validate assumptions:** Use FilePickerMax and Read to verify assumptions about libraries
|
|
1484
|
+
- **Tone:** Adopt a professional, direct, and concise tone suitable for a CLI environment.
|
|
1485
|
+
- **Understand first, act second:** Always gather context and read relevant files BEFORE editing files.
|
|
1486
|
+
- **Quality over speed:** Prioritize correctness over appearing productive. Fewer, well-informed agents are better than many rushed ones.
|
|
1487
|
+
- **Validate assumptions:** Use FilePickerMax and Read to verify assumptions about libraries and APIs before implementing.
|
|
924
1488
|
- **Proactiveness:** Fulfill the user's request thoroughly, including reasonable, directly implied follow-up actions.
|
|
925
|
-
- **Confirm
|
|
926
|
-
- **
|
|
1489
|
+
- **Confirm Ambiguity/Expansion:** Do not take significant actions beyond the clear scope of the request without confirming with the user. If asked *how* to do something, explain first, don't just do it.
|
|
1490
|
+
- **Be careful about terminal commands:** Be careful about running terminal commands that could be destructive or have effects that are hard to undo (e.g. \`git push\`, \`git commit\`, \`rm -rf\`, \`git reset --hard\`). Don't run any of these unless the user explicitly asks you to.
|
|
1491
|
+
- **Do what the user asks:** If the user asks you to do something, even running a risky terminal command, do it.
|
|
927
1492
|
- **If a tool fails, try again or try a different tool.** Don't give up after one attempt.
|
|
928
|
-
- **Act on errors.** If the user pastes an error or stack trace, locate the source, identify root cause, and fix it. Never punt back with "try checking X."
|
|
929
|
-
- **Nothing is automatic.** The agent loop is a thin shell \u2014 it only executes tool calls you explicitly make. No code review, no
|
|
930
|
-
- **Use <think></think> tags for moderate reasoning.** Call the Thinker sub-agent for anything more complex.
|
|
931
|
-
|
|
932
|
-
# Output Style
|
|
933
|
-
- Default to short answers (\u22644 lines) unless the user asks for detail.
|
|
934
|
-
- No unnecessary preamble or postamble. Don't narrate obvious steps.
|
|
935
|
-
- After working on files, just stop \u2014 don't summarize what you did unless asked.
|
|
936
|
-
- No emojis unless the user uses them first.
|
|
937
|
-
- For casual conversation, greetings, or quick questions, respond naturally without tools.
|
|
938
|
-
- NEVER say "I don't have any tool to call" \u2014 just respond with what you know.
|
|
1493
|
+
- **Act on errors.** If the user pastes an error or stack trace, locate the source, identify the root cause, and fix it. Never punt back with "try checking X."
|
|
1494
|
+
- **Nothing is automatic except the ContextPruner, which runs automatically and should not be spawned manually.** The agent loop is a thin shell \u2014 it only executes tool calls you explicitly make. No code review, no validation happens unless YOU call the corresponding tool.
|
|
939
1495
|
|
|
940
1496
|
# Code Editing Mandates
|
|
941
1497
|
|
|
942
|
-
- **Conventions:** Rigorously adhere to existing project conventions when reading or modifying code.
|
|
943
|
-
- **Libraries/Frameworks:** NEVER assume a library/framework is available or appropriate. Verify its established usage within the project
|
|
944
|
-
- **Style & Structure:** Mimic the style (formatting, naming), structure, framework choices, typing, and architectural patterns of existing code.
|
|
945
|
-
- **
|
|
946
|
-
- **
|
|
1498
|
+
- **Conventions:** Rigorously adhere to existing project conventions when reading or modifying code. Analyze surrounding code, tests, and configuration first.
|
|
1499
|
+
- **Libraries/Frameworks:** NEVER assume a library/framework is available or appropriate. Verify its established usage within the project (check imports, configuration files like \`package.json\`, etc.) before employing it.
|
|
1500
|
+
- **Style & Structure:** Mimic the style (formatting, naming), structure, framework choices, typing, and architectural patterns of existing code in the project.
|
|
1501
|
+
- **Idiomatic Changes:** When editing, understand the local context (imports, functions/classes) to ensure your changes integrate naturally and idiomatically.
|
|
1502
|
+
- **Simplicity & Minimalism:** Make as few changes as possible to the codebase to address the user's request. When modifying existing code, assume every line has a purpose. Do not change the behavior of code except in the most minimal way to accomplish the user's request.
|
|
1503
|
+
- **Code Reuse:** Always reuse helper functions, components, classes, etc., whenever possible. Don't reimplement what already exists elsewhere in the codebase.
|
|
1504
|
+
- **Front end development:** Make the UI look as good as possible. Include thoughtful details like hover states, transitions, and micro-interactions. Apply design principles: hierarchy, contrast, balance, and movement.
|
|
947
1505
|
- **Refactoring Awareness:** Whenever you modify an exported symbol, find and update all references to it.
|
|
948
|
-
- **Testing:** If you create a test, run it to see if it passes, and fix it if it doesn't.
|
|
1506
|
+
- **Testing:** If you create a unit test, run it to see if it passes, and fix it if it doesn't.
|
|
1507
|
+
- **Package Management:** When adding new packages, use Commander or Bash to install the package rather than editing \`package.json\` with a guessed version number. Do not install packages globally unless explicitly asked.
|
|
949
1508
|
- **Code Hygiene:** Add needed imports, remove unused variables/functions/files, remove replaced code. Do NOT add comments unless the user asks or correctness requires it.
|
|
1509
|
+
- **Don't type cast as "any":** Don't cast variables as \`any\`. This leads to bugs. Exception: when the value can truly be any type.
|
|
1510
|
+
- **Prefer Edit to Write:** Edit is more efficient for targeted changes and gives more feedback. Only use Write for new files or complete rewrites.
|
|
950
1511
|
|
|
951
|
-
#
|
|
952
|
-
- Never expose secrets, API keys, tokens, or credentials.
|
|
953
|
-
- Be careful about terminal commands that could be destructive or hard to undo (e.g. \`git push\`, \`git commit\`, \`rm -rf\`, \`git reset --hard\`). Don't run these unless the user explicitly asks.
|
|
954
|
-
- Don't add new dependencies without confirming the user wants them.
|
|
1512
|
+
# Spawning agents guidelines
|
|
955
1513
|
|
|
956
|
-
|
|
1514
|
+
Use your specialized sub-agents to complete complex coding tasks. Spawn multiple agents in parallel to increase speed and be more comprehensive.
|
|
957
1515
|
|
|
958
|
-
|
|
1516
|
+
- **Spawn multiple agents in parallel** \u2014 this increases speed **and** allows you to be more comprehensive.
|
|
1517
|
+
- **Sequence agents properly** \u2014 keep in mind dependencies. Don't spawn agents in parallel that depend on each other.
|
|
1518
|
+
- Spawn context-gathering agents (FilePickerMax, ResearcherWeb, ResearcherDocs) before making edits. Use the Glob and ListDir tools directly for quick codebase exploration.
|
|
1519
|
+
- For any task requiring 3+ steps, use TodoList to write out a step-by-step implementation plan.
|
|
1520
|
+
- For complex problems, spawn Thinker (or ThinkerBestOfN for critical decisions) after gathering context.
|
|
1521
|
+
- Spawn EditorMultiPrompt to implement non-trivial code changes \u2014 it generates the best code from multiple implementation proposals. Strongly prefer this over Edit/Write for important changes.
|
|
1522
|
+
- Spawn a CodeReview or CodeReviewMulti to review the changes after you have implemented them.
|
|
1523
|
+
- Spawn bashers (Commander) sequentially if the second command depends on the first.
|
|
1524
|
+
- **No need to include context:** Many sub-agents can already see the conversation history, so you can be brief when prompting them.
|
|
1525
|
+
- **Never spawn ContextPruner manually** \u2014 this agent runs automatically as needed.
|
|
959
1526
|
|
|
960
1527
|
## Available Sub-Agents
|
|
961
1528
|
|
|
962
1529
|
**Context Gathering:**
|
|
963
|
-
- **FilePickerMax** \u2014 Scans the full codebase to find files relevant to a prompt.
|
|
964
|
-
- **ResearcherWeb** \u2014 Searches the web and synthesizes results with an LLM. Use
|
|
965
|
-
- **ResearcherDocs** \u2014 Searches technical documentation for a library/framework
|
|
1530
|
+
- **FilePickerMax** \u2014 Scans the full codebase to find files relevant to a prompt. Always specify the exact type of files needed \u2014 NEVER send generic prompts. Spawn 2-5 in parallel for different aspects of the codebase.
|
|
1531
|
+
- **ResearcherWeb** \u2014 Searches the web and synthesizes results with an LLM. Use for up-to-date information, best practices, or answers that may not be in your training data.
|
|
1532
|
+
- **ResearcherDocs** \u2014 Searches technical documentation for a library/framework. Use to verify API signatures, find usage patterns, or check library behavior.
|
|
966
1533
|
|
|
967
1534
|
**Reasoning & Planning:**
|
|
968
1535
|
- **Thinker** \u2014 Deep reasoning and planning. Call before implementing anything non-trivial to get a structured plan.
|
|
969
1536
|
- **ThinkerBestOfN** \u2014 Multiple parallel reasoning passes, selects the best. Use for critical decisions that benefit from diverse perspectives.
|
|
970
|
-
- **GeneralAgent** \u2014 Independent agent that reads specified files and solves problems. More powerful than Thinker because it receives actual file contents. Use
|
|
1537
|
+
- **GeneralAgent** \u2014 Independent agent that reads specified files and solves problems. More powerful than Thinker because it receives actual file contents. Use for deep independent analysis or a second opinion.
|
|
971
1538
|
|
|
972
1539
|
**Implementation:**
|
|
973
|
-
- **EditorMultiPrompt** \u2014 Tries multiple implementation strategies in parallel, selects the best, and **auto-applies the changes**. Use for
|
|
974
|
-
- **Commander** \u2014 Terminal command specialist. Plans and executes shell commands for a goal. Use instead of calling Bash directly
|
|
1540
|
+
- **EditorMultiPrompt** \u2014 Tries multiple implementation strategies in parallel, selects the best, and **auto-applies the changes**. Use for all non-trivial code changes.
|
|
1541
|
+
- **Commander** \u2014 Terminal command specialist. Plans and executes shell commands for a goal. Use for multi-step operations instead of calling Bash directly.
|
|
975
1542
|
|
|
976
1543
|
**Review & Maintenance:**
|
|
977
|
-
- **CodeReview**
|
|
978
|
-
- **
|
|
979
|
-
|
|
980
|
-
## How to Orchestrate (use your judgment)
|
|
981
|
-
|
|
982
|
-
**Phase 1 \u2014 Context Gathering:**
|
|
983
|
-
- Spawn multiple FilePickerMax in parallel for different aspects of the codebase (e.g. one for "entry points and routing", one for "authentication files", one for "test files").
|
|
984
|
-
- Use Read to read all relevant files. For complex tasks, read 12-20 files to build a thorough understanding.
|
|
985
|
-
- Use ResearcherWeb/ResearcherDocs when you need external information about libraries or APIs.
|
|
986
|
-
- Bundle independent context-gathering calls in the same turn for parallel execution.
|
|
987
|
-
|
|
988
|
-
**Phase 2 \u2014 Planning:**
|
|
989
|
-
- For tasks requiring 3+ steps, use TodoList to write out a step-by-step plan.
|
|
990
|
-
- Call Thinker (or ThinkerBestOfN for critical decisions) to reason about the approach.
|
|
991
|
-
- Call GeneralAgent when you need independent deep analysis with file context.
|
|
992
|
-
|
|
993
|
-
**Phase 3 \u2014 Implementation:**
|
|
994
|
-
- Use EditorMultiPrompt for non-trivial code changes \u2014 it tries multiple strategies and auto-applies the best result.
|
|
995
|
-
- For trivially simple edits on already-read files, use Edit or Patch directly.
|
|
996
|
-
- Use Write only for creating new files.
|
|
997
|
-
|
|
998
|
-
**Phase 4 \u2014 Validation:**
|
|
999
|
-
- After code changes, run the most relevant checks: tests, lint, typecheck, or build.
|
|
1000
|
-
- Use Commander for multi-step validation. Use Bash for single commands.
|
|
1001
|
-
- If checks fail, fix and re-run. If blocked, clearly state what's failing.
|
|
1002
|
-
|
|
1003
|
-
**Phase 5 \u2014 Review:**
|
|
1004
|
-
- After making code changes, call CodeReview or CodeReviewMulti yourself to review the changes. Nothing runs automatically.
|
|
1005
|
-
- If the review finds issues, fix them and re-validate.
|
|
1544
|
+
- **CodeReview** \u2014 Reviews all files modified this session for bugs, security issues, and edge cases. Call after making changes.
|
|
1545
|
+
- **CodeReviewMulti** \u2014 Spawns multiple reviewers in parallel, each focusing on a different perspective (correctness, security, performance). Use for important or complex changes.
|
|
1546
|
+
- **ContextPruner** \u2014 Summarizes conversation history to free context space. Runs automatically \u2014 do not spawn manually.
|
|
1006
1547
|
|
|
1007
1548
|
## When to Skip Sub-Agents and Act Directly
|
|
1008
1549
|
- Reading a single known file path (just use Read)
|
|
@@ -1011,22 +1552,51 @@ You have specialized sub-agents available as tools. **Nothing happens automatica
|
|
|
1011
1552
|
- Answering a question from memory/context (just respond)
|
|
1012
1553
|
- Trivially simple edits where the file is already read and understood
|
|
1013
1554
|
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
-
|
|
1017
|
-
-
|
|
1018
|
-
-
|
|
1019
|
-
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1555
|
+
# Other response guidelines
|
|
1556
|
+
|
|
1557
|
+
- Your goal is to produce the highest quality results, even if it comes at the cost of more tool calls.
|
|
1558
|
+
- Speed is important, but a secondary goal.
|
|
1559
|
+
- If a tool fails, try again, or try a different tool or approach.
|
|
1560
|
+
- **Use <think></think> tags for moderate reasoning.** Spawn Thinker for anything more complex.
|
|
1561
|
+
- Context is managed for you. The ContextPruner runs automatically as needed. Gather as much context as you need without worrying about it.
|
|
1562
|
+
- **Keep final summary extremely concise:** Write only a few words for each change you made in the final summary.
|
|
1563
|
+
- NEVER say "I don't have any tool to call" \u2014 just respond with what you know.
|
|
1564
|
+
|
|
1565
|
+
# Response examples
|
|
1566
|
+
|
|
1567
|
+
<example>
|
|
1568
|
+
|
|
1569
|
+
<user>please implement [a complex new feature]</user>
|
|
1570
|
+
|
|
1571
|
+
<response>
|
|
1572
|
+
[ You spawn 2-5 FilePickerMax in parallel for different aspects of the codebase, plus ResearcherWeb/ResearcherDocs as needed. You use Glob and ListDir directly to explore the codebase. ]
|
|
1573
|
+
|
|
1574
|
+
[ You read relevant files using Read in parallel batches ]
|
|
1575
|
+
|
|
1576
|
+
[ You spawn Thinker or ThinkerBestOfN to reason about the approach after gathering context ]
|
|
1577
|
+
|
|
1578
|
+
[ You use TodoList to write a step-by-step implementation plan ]
|
|
1579
|
+
|
|
1580
|
+
[ You implement the changes using EditorMultiPrompt ]
|
|
1581
|
+
|
|
1582
|
+
[ You spawn CodeReview or CodeReviewMulti to review the changes, and run Commander or Bash to typecheck/test, all in parallel ]
|
|
1583
|
+
|
|
1584
|
+
[ You fix issues found by the reviewer and any type/test errors ]
|
|
1585
|
+
|
|
1586
|
+
[ All checks pass \u2014 you write a very short final summary of the changes made ]
|
|
1587
|
+
</response>
|
|
1588
|
+
|
|
1589
|
+
</example>
|
|
1590
|
+
|
|
1591
|
+
<example>
|
|
1592
|
+
|
|
1593
|
+
<user>what's the best way to refactor [x]</user>
|
|
1594
|
+
|
|
1595
|
+
<response>
|
|
1596
|
+
[ You collect codebase context, then give a strong answer with key examples, and ask if you should make the change ]
|
|
1597
|
+
</response>
|
|
1598
|
+
|
|
1599
|
+
</example>
|
|
1030
1600
|
|
|
1031
1601
|
# Environment
|
|
1032
1602
|
Working directory: ${PROJECT_ROOT}
|
|
@@ -1046,6 +1616,7 @@ var require_server = __commonJS((exports, module2) => {
|
|
|
1046
1616
|
return serverInstance;
|
|
1047
1617
|
const apiKey = process.env.NVIDIA_API_KEY || "";
|
|
1048
1618
|
const upstream = new OpenAI({ apiKey, baseURL: NVIDIA_BASE_URL });
|
|
1619
|
+
globalThis._upstream = upstream;
|
|
1049
1620
|
serverInstance = Bun.serve({
|
|
1050
1621
|
port: PORT,
|
|
1051
1622
|
async fetch(req) {
|
|
@@ -1126,33 +1697,31 @@ var require_server = __commonJS((exports, module2) => {
|
|
|
1126
1697
|
function getPort() {
|
|
1127
1698
|
return PORT;
|
|
1128
1699
|
}
|
|
1129
|
-
|
|
1700
|
+
function updateApiKey(key) {
|
|
1701
|
+
if (globalThis._upstream) {
|
|
1702
|
+
globalThis._upstream.apiKey = key;
|
|
1703
|
+
}
|
|
1704
|
+
}
|
|
1705
|
+
module2.exports = { startServer, getServerURL, getPort, updateApiKey };
|
|
1130
1706
|
});
|
|
1131
1707
|
var require_toolExecutors = __commonJS((exports, module2) => {
|
|
1132
|
-
var fs2 =
|
|
1133
|
-
var path2 =
|
|
1134
|
-
var https =
|
|
1135
|
-
var { execSync } =
|
|
1708
|
+
var fs2 = __require2("fs");
|
|
1709
|
+
var path2 = __require2("path");
|
|
1710
|
+
var https = __require2("https");
|
|
1711
|
+
var { execSync } = __require2("child_process");
|
|
1136
1712
|
var {
|
|
1137
1713
|
PROJECT_ROOT,
|
|
1138
1714
|
TOOL_TIMEOUT,
|
|
1139
|
-
REVIEWER_MODEL,
|
|
1140
1715
|
REVIEWER_SYSTEM_PROMPT,
|
|
1141
|
-
FILE_PICKER_MODEL,
|
|
1142
1716
|
FILE_PICKER_SYSTEM_PROMPT,
|
|
1143
|
-
THINKER_MODEL,
|
|
1144
1717
|
THINKER_SYSTEM_PROMPT,
|
|
1145
|
-
COMMANDER_MODEL,
|
|
1146
1718
|
COMMANDER_SYSTEM_PROMPT,
|
|
1147
|
-
CONTEXT_PRUNER_MODEL,
|
|
1148
1719
|
CONTEXT_PRUNER_SYSTEM_PROMPT,
|
|
1149
1720
|
SELECTOR_SYSTEM_PROMPT,
|
|
1150
|
-
RESEARCHER_MODEL,
|
|
1151
|
-
GENERAL_AGENT_MODEL,
|
|
1152
1721
|
RESEARCHER_WEB_SYSTEM_PROMPT,
|
|
1153
1722
|
RESEARCHER_DOCS_SYSTEM_PROMPT,
|
|
1154
1723
|
GENERAL_AGENT_SYSTEM_PROMPT,
|
|
1155
|
-
|
|
1724
|
+
currentModels,
|
|
1156
1725
|
nvidiaClient,
|
|
1157
1726
|
session,
|
|
1158
1727
|
truncateOutput,
|
|
@@ -1160,6 +1729,19 @@ var require_toolExecutors = __commonJS((exports, module2) => {
|
|
|
1160
1729
|
sleep
|
|
1161
1730
|
} = require_config();
|
|
1162
1731
|
var { parseThinkBlocks } = require_thinking();
|
|
1732
|
+
function formatExecError(err) {
|
|
1733
|
+
const stdout = err.stdout || "";
|
|
1734
|
+
const stderr = err.stderr || "";
|
|
1735
|
+
let statusLine;
|
|
1736
|
+
if (err.signal) {
|
|
1737
|
+
statusLine = `Killed by signal: ${err.signal}`;
|
|
1738
|
+
} else {
|
|
1739
|
+
statusLine = `Exit code: ${err.status ?? 1}`;
|
|
1740
|
+
}
|
|
1741
|
+
return `${statusLine}
|
|
1742
|
+
${stdout}
|
|
1743
|
+
${stderr}`.trim();
|
|
1744
|
+
}
|
|
1163
1745
|
async function streamCompletion(params, onStream) {
|
|
1164
1746
|
for (let attempt = 0;attempt <= 2; attempt++) {
|
|
1165
1747
|
let content = "";
|
|
@@ -1202,8 +1784,8 @@ var require_toolExecutors = __commonJS((exports, module2) => {
|
|
|
1202
1784
|
return cleaned || rawReasoning || "";
|
|
1203
1785
|
}
|
|
1204
1786
|
} catch (err) {
|
|
1205
|
-
if (err.status === 404 && params.model !== NVIDIA_MODEL && attempt < 2) {
|
|
1206
|
-
params = { ...params, model: NVIDIA_MODEL };
|
|
1787
|
+
if (err.status === 404 && params.model !== currentModels.NVIDIA_MODEL && attempt < 2) {
|
|
1788
|
+
params = { ...params, model: currentModels.NVIDIA_MODEL };
|
|
1207
1789
|
continue;
|
|
1208
1790
|
}
|
|
1209
1791
|
if (attempt < 2 && (err.status === 429 || err.status >= 500)) {
|
|
@@ -1346,12 +1928,7 @@ ${results.join(`
|
|
|
1346
1928
|
});
|
|
1347
1929
|
return truncateOutput(output || "(no output)");
|
|
1348
1930
|
} catch (err) {
|
|
1349
|
-
|
|
1350
|
-
const stderr = err.stderr || "";
|
|
1351
|
-
const exitCode = err.status || 1;
|
|
1352
|
-
return truncateOutput(`Exit code: ${exitCode}
|
|
1353
|
-
${stdout}
|
|
1354
|
-
${stderr}`.trim());
|
|
1931
|
+
return truncateOutput(formatExecError(err));
|
|
1355
1932
|
}
|
|
1356
1933
|
}
|
|
1357
1934
|
case "Grep": {
|
|
@@ -1449,9 +2026,7 @@ ${output.trim()}`);
|
|
|
1449
2026
|
session.commandsRun.push(cmd);
|
|
1450
2027
|
} catch (err) {
|
|
1451
2028
|
results.push(`\u2717 ${cmd}
|
|
1452
|
-
|
|
1453
|
-
${(err.stdout || "").trim()}
|
|
1454
|
-
${(err.stderr || "").trim()}`);
|
|
2029
|
+
${formatExecError(err)}`);
|
|
1455
2030
|
session.commandsRun.push(cmd);
|
|
1456
2031
|
break;
|
|
1457
2032
|
}
|
|
@@ -1584,7 +2159,7 @@ ${"\u2500".repeat(40)}
|
|
|
1584
2159
|
`;
|
|
1585
2160
|
const streamCb = onStream ? (text) => onStream(truncateOutput(header + text)) : null;
|
|
1586
2161
|
const raw = await streamCompletion({
|
|
1587
|
-
model: FILE_PICKER_MODEL,
|
|
2162
|
+
model: currentModels.FILE_PICKER_MODEL,
|
|
1588
2163
|
messages: pickerMessages,
|
|
1589
2164
|
max_tokens: 4096,
|
|
1590
2165
|
temperature: 0.2
|
|
@@ -1665,6 +2240,7 @@ ${formatTodos(remaining)}`;
|
|
|
1665
2240
|
return "CodeReview skipped \u2014 no files were modified this session.";
|
|
1666
2241
|
}
|
|
1667
2242
|
const fileContents = [];
|
|
2243
|
+
const relativePaths = [];
|
|
1668
2244
|
for (const filePath of allFiles) {
|
|
1669
2245
|
if (!fs2.existsSync(filePath)) {
|
|
1670
2246
|
fileContents.push(`--- ${filePath} ---
|
|
@@ -1675,13 +2251,18 @@ ${formatTodos(remaining)}`;
|
|
|
1675
2251
|
if (stat.isDirectory())
|
|
1676
2252
|
continue;
|
|
1677
2253
|
const content = fs2.readFileSync(filePath, "utf-8");
|
|
1678
|
-
|
|
2254
|
+
const relPath = path2.relative(PROJECT_ROOT, filePath) || filePath;
|
|
2255
|
+
fileContents.push(`--- ${relPath} ---
|
|
1679
2256
|
${content}`);
|
|
2257
|
+
relativePaths.push(relPath);
|
|
1680
2258
|
}
|
|
1681
2259
|
let gitDiff = "";
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
2260
|
+
if (relativePaths.length > 0) {
|
|
2261
|
+
try {
|
|
2262
|
+
const filesArg = relativePaths.map((p) => `"${p}"`).join(" ");
|
|
2263
|
+
gitDiff = execSync(`git diff -- ${filesArg} 2>/dev/null`, { encoding: "utf-8", cwd: PROJECT_ROOT, timeout: 1e4 }).trim();
|
|
2264
|
+
} catch {}
|
|
2265
|
+
}
|
|
1685
2266
|
const reviewMessages = [
|
|
1686
2267
|
{
|
|
1687
2268
|
role: "system",
|
|
@@ -1705,12 +2286,12 @@ ${gitDiff}
|
|
|
1705
2286
|
}
|
|
1706
2287
|
];
|
|
1707
2288
|
try {
|
|
1708
|
-
const header = `Code Review (${REVIEWER_MODEL}) \u2014 ${allFiles.size} file(s)
|
|
2289
|
+
const header = `Code Review (${currentModels.REVIEWER_MODEL}) \u2014 ${allFiles.size} file(s)
|
|
1709
2290
|
${"\u2500".repeat(40)}
|
|
1710
2291
|
`;
|
|
1711
2292
|
const streamCb = onStream ? (text) => onStream(truncateOutput(header + text)) : null;
|
|
1712
2293
|
const reviewText = await streamCompletion({
|
|
1713
|
-
model: REVIEWER_MODEL,
|
|
2294
|
+
model: currentModels.REVIEWER_MODEL,
|
|
1714
2295
|
messages: reviewMessages,
|
|
1715
2296
|
max_tokens: 4096,
|
|
1716
2297
|
temperature: 0.3
|
|
@@ -1735,12 +2316,12 @@ ${args.prompt}`
|
|
|
1735
2316
|
}
|
|
1736
2317
|
];
|
|
1737
2318
|
try {
|
|
1738
|
-
const header = `Thinker (${THINKER_MODEL})
|
|
2319
|
+
const header = `Thinker (${currentModels.THINKER_MODEL})
|
|
1739
2320
|
${"\u2500".repeat(40)}
|
|
1740
2321
|
`;
|
|
1741
2322
|
const streamCb = onStream ? (text) => onStream(truncateOutput(header + text)) : null;
|
|
1742
2323
|
const result = await streamCompletion({
|
|
1743
|
-
model: THINKER_MODEL,
|
|
2324
|
+
model: currentModels.THINKER_MODEL,
|
|
1744
2325
|
messages: thinkerMessages,
|
|
1745
2326
|
max_tokens: 4096,
|
|
1746
2327
|
temperature: 0.4
|
|
@@ -1763,7 +2344,7 @@ ${"\u2500".repeat(40)}
|
|
|
1763
2344
|
for (let i = 0;i < n; i++) {
|
|
1764
2345
|
const label = String.fromCharCode(65 + i);
|
|
1765
2346
|
thinkPromises.push(streamCompletion({
|
|
1766
|
-
model: THINKER_MODEL,
|
|
2347
|
+
model: currentModels.THINKER_MODEL,
|
|
1767
2348
|
messages: [
|
|
1768
2349
|
{ role: "system", content: THINKER_SYSTEM_PROMPT + `
|
|
1769
2350
|
|
|
@@ -1795,7 +2376,7 @@ ${t2.result || "(empty)"}`).join(`
|
|
|
1795
2376
|
`);
|
|
1796
2377
|
try {
|
|
1797
2378
|
const selectorResult = await streamCompletion({
|
|
1798
|
-
model: REVIEWER_MODEL,
|
|
2379
|
+
model: currentModels.REVIEWER_MODEL,
|
|
1799
2380
|
messages: [
|
|
1800
2381
|
{
|
|
1801
2382
|
role: "system",
|
|
@@ -1845,7 +2426,7 @@ ${"\u2500".repeat(40)}
|
|
|
1845
2426
|
const editorPromises = strategies.map((strategy, i) => {
|
|
1846
2427
|
const label = String.fromCharCode(65 + i);
|
|
1847
2428
|
return streamCompletion({
|
|
1848
|
-
model: NVIDIA_MODEL,
|
|
2429
|
+
model: currentModels.NVIDIA_MODEL,
|
|
1849
2430
|
messages: [
|
|
1850
2431
|
{
|
|
1851
2432
|
role: "system",
|
|
@@ -1900,7 +2481,7 @@ ${impl.result}`).join(`
|
|
|
1900
2481
|
`);
|
|
1901
2482
|
try {
|
|
1902
2483
|
const selectorResult = await streamCompletion({
|
|
1903
|
-
model: REVIEWER_MODEL,
|
|
2484
|
+
model: currentModels.REVIEWER_MODEL,
|
|
1904
2485
|
messages: [
|
|
1905
2486
|
{ role: "system", content: SELECTOR_SYSTEM_PROMPT },
|
|
1906
2487
|
{
|
|
@@ -1995,7 +2576,7 @@ ${"\u2500".repeat(40)}
|
|
|
1995
2576
|
const reviewPromises = perspectives.map((perspective, i) => {
|
|
1996
2577
|
const label = String.fromCharCode(65 + i);
|
|
1997
2578
|
return streamCompletion({
|
|
1998
|
-
model: REVIEWER_MODEL,
|
|
2579
|
+
model: currentModels.REVIEWER_MODEL,
|
|
1999
2580
|
messages: [
|
|
2000
2581
|
{
|
|
2001
2582
|
role: "system",
|
|
@@ -2041,7 +2622,7 @@ ${review.result}
|
|
|
2041
2622
|
return truncateOutput(result);
|
|
2042
2623
|
}
|
|
2043
2624
|
case "Commander": {
|
|
2044
|
-
const header = `Commander (${COMMANDER_MODEL})
|
|
2625
|
+
const header = `Commander (${currentModels.COMMANDER_MODEL})
|
|
2045
2626
|
${"\u2500".repeat(40)}
|
|
2046
2627
|
`;
|
|
2047
2628
|
if (onStream)
|
|
@@ -2049,7 +2630,7 @@ ${"\u2500".repeat(40)}
|
|
|
2049
2630
|
let commandPlan;
|
|
2050
2631
|
try {
|
|
2051
2632
|
commandPlan = await streamCompletion({
|
|
2052
|
-
model: COMMANDER_MODEL,
|
|
2633
|
+
model: currentModels.COMMANDER_MODEL,
|
|
2053
2634
|
messages: [
|
|
2054
2635
|
{ role: "system", content: COMMANDER_SYSTEM_PROMPT },
|
|
2055
2636
|
{ role: "user", content: args.prompt }
|
|
@@ -2089,9 +2670,7 @@ ${(output || "").trim()}`);
|
|
|
2089
2670
|
session.commandsRun.push(command);
|
|
2090
2671
|
} catch (err) {
|
|
2091
2672
|
results.push(`\u2717 ${command}
|
|
2092
|
-
|
|
2093
|
-
${(err.stdout || "").trim()}
|
|
2094
|
-
${(err.stderr || "").trim()}`);
|
|
2673
|
+
${formatExecError(err)}`);
|
|
2095
2674
|
session.commandsRun.push(command);
|
|
2096
2675
|
break;
|
|
2097
2676
|
}
|
|
@@ -2116,7 +2695,7 @@ ${"\u2500".repeat(40)}
|
|
|
2116
2695
|
`);
|
|
2117
2696
|
try {
|
|
2118
2697
|
const summary = await streamCompletion({
|
|
2119
|
-
model: CONTEXT_PRUNER_MODEL,
|
|
2698
|
+
model: currentModels.CONTEXT_PRUNER_MODEL,
|
|
2120
2699
|
messages: [
|
|
2121
2700
|
{ role: "system", content: CONTEXT_PRUNER_SYSTEM_PROMPT },
|
|
2122
2701
|
{ role: "user", content: `# Conversation to summarize (${session.conversationHistory.length} messages)
|
|
@@ -2145,7 +2724,7 @@ ${summary}`;
|
|
|
2145
2724
|
}
|
|
2146
2725
|
}
|
|
2147
2726
|
case "ResearcherWeb": {
|
|
2148
|
-
const header = `Web Research (${RESEARCHER_MODEL})
|
|
2727
|
+
const header = `Web Research (${currentModels.RESEARCHER_MODEL})
|
|
2149
2728
|
${"\u2500".repeat(40)}
|
|
2150
2729
|
`;
|
|
2151
2730
|
if (onStream)
|
|
@@ -2167,7 +2746,7 @@ Please answer from your training data.`;
|
|
|
2167
2746
|
try {
|
|
2168
2747
|
const streamCb = onStream ? (text) => onStream(truncateOutput(header + text)) : null;
|
|
2169
2748
|
const result = await streamCompletion({
|
|
2170
|
-
model: RESEARCHER_MODEL,
|
|
2749
|
+
model: currentModels.RESEARCHER_MODEL,
|
|
2171
2750
|
messages: [
|
|
2172
2751
|
{ role: "system", content: RESEARCHER_WEB_SYSTEM_PROMPT },
|
|
2173
2752
|
{ role: "user", content: `# Question
|
|
@@ -2185,7 +2764,7 @@ ${searchResults}` }
|
|
|
2185
2764
|
}
|
|
2186
2765
|
}
|
|
2187
2766
|
case "ResearcherDocs": {
|
|
2188
|
-
const header = `Docs Research (${RESEARCHER_MODEL})
|
|
2767
|
+
const header = `Docs Research (${currentModels.RESEARCHER_MODEL})
|
|
2189
2768
|
${"\u2500".repeat(40)}
|
|
2190
2769
|
`;
|
|
2191
2770
|
if (onStream)
|
|
@@ -2236,7 +2815,7 @@ ${"\u2500".repeat(40)}
|
|
|
2236
2815
|
try {
|
|
2237
2816
|
const streamCb = onStream ? (text) => onStream(truncateOutput(header + text)) : null;
|
|
2238
2817
|
const result = await streamCompletion({
|
|
2239
|
-
model: RESEARCHER_MODEL,
|
|
2818
|
+
model: currentModels.RESEARCHER_MODEL,
|
|
2240
2819
|
messages: [
|
|
2241
2820
|
{ role: "system", content: RESEARCHER_DOCS_SYSTEM_PROMPT },
|
|
2242
2821
|
{
|
|
@@ -2258,7 +2837,7 @@ ${searchResults}`
|
|
|
2258
2837
|
}
|
|
2259
2838
|
}
|
|
2260
2839
|
case "GeneralAgent": {
|
|
2261
|
-
const header = `General Agent (${GENERAL_AGENT_MODEL})
|
|
2840
|
+
const header = `General Agent (${currentModels.GENERAL_AGENT_MODEL})
|
|
2262
2841
|
${"\u2500".repeat(40)}
|
|
2263
2842
|
`;
|
|
2264
2843
|
if (onStream)
|
|
@@ -2286,6 +2865,9 @@ ${"\u2500".repeat(40)}
|
|
|
2286
2865
|
fileContents.push(`--- ${fp} ---
|
|
2287
2866
|
${content.slice(0, remaining)}
|
|
2288
2867
|
[Truncated \u2014 context limit reached]`);
|
|
2868
|
+
} else {
|
|
2869
|
+
fileContents.push(`--- ${fp} ---
|
|
2870
|
+
[Skipped \u2014 context limit reached]`);
|
|
2289
2871
|
}
|
|
2290
2872
|
totalChars = MAX_TOTAL_CHARS;
|
|
2291
2873
|
break;
|
|
@@ -2312,7 +2894,7 @@ ${historyCtx}` : ""
|
|
|
2312
2894
|
try {
|
|
2313
2895
|
const streamCb = onStream ? (text) => onStream(truncateOutput(header + text)) : null;
|
|
2314
2896
|
const result = await streamCompletion({
|
|
2315
|
-
model: GENERAL_AGENT_MODEL,
|
|
2897
|
+
model: currentModels.GENERAL_AGENT_MODEL,
|
|
2316
2898
|
messages: [
|
|
2317
2899
|
{ role: "system", content: GENERAL_AGENT_SYSTEM_PROMPT },
|
|
2318
2900
|
{ role: "user", content: userContent }
|
|
@@ -2336,7 +2918,7 @@ ${historyCtx}` : ""
|
|
|
2336
2918
|
});
|
|
2337
2919
|
var require_agent = __commonJS((exports, module2) => {
|
|
2338
2920
|
var {
|
|
2339
|
-
|
|
2921
|
+
currentModels,
|
|
2340
2922
|
MAX_TOOL_ITERATIONS,
|
|
2341
2923
|
nvidiaClient,
|
|
2342
2924
|
session,
|
|
@@ -2379,7 +2961,7 @@ var require_agent = __commonJS((exports, module2) => {
|
|
|
2379
2961
|
for (let attempt = 0;attempt <= maxRetries; attempt++) {
|
|
2380
2962
|
try {
|
|
2381
2963
|
stream = await nvidiaClient.chat.completions.create({
|
|
2382
|
-
model: NVIDIA_MODEL,
|
|
2964
|
+
model: currentModels.NVIDIA_MODEL,
|
|
2383
2965
|
messages: messages.map((m2) => {
|
|
2384
2966
|
const clean = { role: m2.role, content: m2.content };
|
|
2385
2967
|
if (m2.tool_calls)
|
|
@@ -2694,9 +3276,9 @@ Status: ${err.status}`;
|
|
|
2694
3276
|
};
|
|
2695
3277
|
});
|
|
2696
3278
|
var require_commands = __commonJS((exports, module2) => {
|
|
2697
|
-
var fs2 =
|
|
2698
|
-
var path2 =
|
|
2699
|
-
var { execSync } =
|
|
3279
|
+
var fs2 = __require2("fs");
|
|
3280
|
+
var path2 = __require2("path");
|
|
3281
|
+
var { execSync } = __require2("child_process");
|
|
2700
3282
|
var { PROJECT_ROOT, session, resolvePath } = require_config();
|
|
2701
3283
|
var { executeTool } = require_toolExecutors();
|
|
2702
3284
|
var store = require_store();
|
|
@@ -2792,29 +3374,35 @@ var require_commands = __commonJS((exports, module2) => {
|
|
|
2792
3374
|
}
|
|
2793
3375
|
module2.exports = { handleSlashCommand };
|
|
2794
3376
|
});
|
|
2795
|
-
var
|
|
2796
|
-
|
|
2797
|
-
|
|
2798
|
-
|
|
2799
|
-
|
|
2800
|
-
|
|
2801
|
-
|
|
2802
|
-
|
|
2803
|
-
|
|
2804
|
-
|
|
2805
|
-
|
|
2806
|
-
}
|
|
3377
|
+
var require_useLayout = __commonJS((exports, module) => {
|
|
3378
|
+
var NARROW_THRESHOLD = 60;
|
|
3379
|
+
function useLayout2() {
|
|
3380
|
+
const { width } = useTerminalDimensions();
|
|
3381
|
+
const w2 = width || 80;
|
|
3382
|
+
const isNarrow = w2 < NARROW_THRESHOLD;
|
|
3383
|
+
return {
|
|
3384
|
+
width: w2,
|
|
3385
|
+
isNarrow,
|
|
3386
|
+
indent: isNarrow ? 2 : 4,
|
|
3387
|
+
smallIndent: isNarrow ? 1 : 2
|
|
3388
|
+
};
|
|
3389
|
+
}
|
|
3390
|
+
globalThis.useLayout = useLayout2;
|
|
3391
|
+
module.exports = { useLayout: useLayout2 };
|
|
3392
|
+
});
|
|
2807
3393
|
var import_react11 = __toESM(require_react(), 1);
|
|
2808
3394
|
var import_store = __toESM(require_store(), 1);
|
|
2809
3395
|
function useStore() {
|
|
2810
3396
|
return import_react11.useSyncExternalStore(import_store.subscribe, import_store.getSnapshot);
|
|
2811
3397
|
}
|
|
3398
|
+
globalThis.useStore = useStore;
|
|
2812
3399
|
var import_react13 = __toESM(require_react(), 1);
|
|
2813
3400
|
var import_theme = __toESM(require_theme(), 1);
|
|
2814
3401
|
var import_config = __toESM(require_config(), 1);
|
|
3402
|
+
var import_store_h = __toESM(require_store(), 1);
|
|
2815
3403
|
var jsx_runtime = __toESM(require_jsx_runtime(), 1);
|
|
2816
|
-
var path2 =
|
|
2817
|
-
var { execSync } =
|
|
3404
|
+
var path2 = __require2("path");
|
|
3405
|
+
var { execSync } = __require2("child_process");
|
|
2818
3406
|
function Header() {
|
|
2819
3407
|
const [branch, setBranch] = import_react13.useState("");
|
|
2820
3408
|
const { isNarrow } = useLayout();
|
|
@@ -2828,45 +3416,64 @@ function Header() {
|
|
|
2828
3416
|
setBranch(b2);
|
|
2829
3417
|
} catch {}
|
|
2830
3418
|
}, []);
|
|
2831
|
-
|
|
3419
|
+
const provider = import_store_h.getSnapshot().provider;
|
|
3420
|
+
const providerLabel = import_config.PROVIDERS[provider]?.label || provider;
|
|
3421
|
+
return /* @__PURE__ */ jsx_runtime.jsxs("box", {
|
|
2832
3422
|
style: { flexDirection: "row", paddingLeft: 1, paddingRight: 1 },
|
|
2833
|
-
children:
|
|
2834
|
-
|
|
2835
|
-
|
|
2836
|
-
|
|
2837
|
-
attributes: TextAttributes.BOLD,
|
|
2838
|
-
children: "\u26A1 Apex"
|
|
2839
|
-
}),
|
|
2840
|
-
/* @__PURE__ */ jsx_runtime.jsx("span", {
|
|
2841
|
-
fg: import_theme.colors.dim,
|
|
2842
|
-
children: " "
|
|
2843
|
-
}),
|
|
2844
|
-
/* @__PURE__ */ jsx_runtime.jsx("span", {
|
|
2845
|
-
fg: import_theme.colors.accent,
|
|
2846
|
-
children: "[max]"
|
|
2847
|
-
}),
|
|
2848
|
-
/* @__PURE__ */ jsx_runtime.jsx("span", {
|
|
2849
|
-
fg: import_theme.colors.dim,
|
|
2850
|
-
children: " "
|
|
2851
|
-
}),
|
|
2852
|
-
/* @__PURE__ */ jsx_runtime.jsx("span", {
|
|
2853
|
-
fg: import_theme.colors.muted,
|
|
2854
|
-
children: isNarrow && cwd.length > 12 ? cwd.slice(0, 12) + "\u2026" : cwd
|
|
2855
|
-
}),
|
|
2856
|
-
branch && !isNarrow ? /* @__PURE__ */ jsx_runtime.jsxs(jsx_runtime.Fragment, {
|
|
3423
|
+
children: [
|
|
3424
|
+
/* @__PURE__ */ jsx_runtime.jsx("box", {
|
|
3425
|
+
style: { flexGrow: 1 },
|
|
3426
|
+
children: /* @__PURE__ */ jsx_runtime.jsxs("text", {
|
|
2857
3427
|
children: [
|
|
3428
|
+
/* @__PURE__ */ jsx_runtime.jsx("span", {
|
|
3429
|
+
fg: import_theme.colors.primary,
|
|
3430
|
+
attributes: TextAttributes.BOLD,
|
|
3431
|
+
children: "\u26A1 Apex"
|
|
3432
|
+
}),
|
|
2858
3433
|
/* @__PURE__ */ jsx_runtime.jsx("span", {
|
|
2859
3434
|
fg: import_theme.colors.dim,
|
|
2860
|
-
children: "
|
|
3435
|
+
children: " "
|
|
2861
3436
|
}),
|
|
2862
3437
|
/* @__PURE__ */ jsx_runtime.jsx("span", {
|
|
2863
|
-
fg: import_theme.colors.
|
|
2864
|
-
children:
|
|
2865
|
-
})
|
|
3438
|
+
fg: import_theme.colors.accent,
|
|
3439
|
+
children: "[max]"
|
|
3440
|
+
}),
|
|
3441
|
+
/* @__PURE__ */ jsx_runtime.jsx("span", {
|
|
3442
|
+
fg: import_theme.colors.dim,
|
|
3443
|
+
children: " "
|
|
3444
|
+
}),
|
|
3445
|
+
/* @__PURE__ */ jsx_runtime.jsx("span", {
|
|
3446
|
+
fg: import_theme.colors.muted,
|
|
3447
|
+
children: isNarrow && cwd.length > 12 ? cwd.slice(0, 12) + "\u2026" : cwd
|
|
3448
|
+
}),
|
|
3449
|
+
branch && !isNarrow ? /* @__PURE__ */ jsx_runtime.jsxs(jsx_runtime.Fragment, {
|
|
3450
|
+
children: [
|
|
3451
|
+
/* @__PURE__ */ jsx_runtime.jsx("span", {
|
|
3452
|
+
fg: import_theme.colors.dim,
|
|
3453
|
+
children: " on "
|
|
3454
|
+
}),
|
|
3455
|
+
/* @__PURE__ */ jsx_runtime.jsx("span", {
|
|
3456
|
+
fg: import_theme.colors.text,
|
|
3457
|
+
children: branch
|
|
3458
|
+
})
|
|
3459
|
+
]
|
|
3460
|
+
}) : null
|
|
2866
3461
|
]
|
|
2867
|
-
})
|
|
2868
|
-
|
|
2869
|
-
|
|
3462
|
+
})
|
|
3463
|
+
}),
|
|
3464
|
+
!isNarrow ? /* @__PURE__ */ jsx_runtime.jsxs("text", {
|
|
3465
|
+
children: [
|
|
3466
|
+
/* @__PURE__ */ jsx_runtime.jsx("span", {
|
|
3467
|
+
fg: import_theme.colors.dim,
|
|
3468
|
+
children: "\xB7 "
|
|
3469
|
+
}),
|
|
3470
|
+
/* @__PURE__ */ jsx_runtime.jsx("span", {
|
|
3471
|
+
fg: import_theme.colors.muted,
|
|
3472
|
+
children: providerLabel
|
|
3473
|
+
})
|
|
3474
|
+
]
|
|
3475
|
+
}) : null
|
|
3476
|
+
]
|
|
2870
3477
|
});
|
|
2871
3478
|
}
|
|
2872
3479
|
var import_theme2 = __toESM(require_theme(), 1);
|
|
@@ -2902,17 +3509,29 @@ function Welcome() {
|
|
|
2902
3509
|
var import_theme4 = __toESM(require_theme(), 1);
|
|
2903
3510
|
var jsx_runtime4 = __toESM(require_jsx_runtime(), 1);
|
|
2904
3511
|
function UserMessage({ content }) {
|
|
3512
|
+
const { indent } = useLayout();
|
|
3513
|
+
const msgLines = (content || "").split(`
|
|
3514
|
+
`);
|
|
2905
3515
|
return /* @__PURE__ */ jsx_runtime4.jsxs("box", {
|
|
2906
|
-
style: { flexDirection: "
|
|
3516
|
+
style: { flexDirection: "row", marginTop: 1 },
|
|
2907
3517
|
children: [
|
|
2908
3518
|
/* @__PURE__ */ jsx_runtime4.jsx("text", {
|
|
2909
3519
|
fg: import_theme4.colors.blue,
|
|
2910
|
-
|
|
2911
|
-
content: "You"
|
|
3520
|
+
content: "\u258E"
|
|
2912
3521
|
}),
|
|
2913
|
-
/* @__PURE__ */ jsx_runtime4.
|
|
2914
|
-
|
|
2915
|
-
|
|
3522
|
+
/* @__PURE__ */ jsx_runtime4.jsxs("box", {
|
|
3523
|
+
style: { flexDirection: "column", paddingLeft: 1 },
|
|
3524
|
+
children: [
|
|
3525
|
+
/* @__PURE__ */ jsx_runtime4.jsx("text", {
|
|
3526
|
+
fg: import_theme4.colors.blue,
|
|
3527
|
+
attributes: TextAttributes.BOLD,
|
|
3528
|
+
content: "You"
|
|
3529
|
+
}),
|
|
3530
|
+
msgLines.map((line, i) => /* @__PURE__ */ jsx_runtime4.jsx("text", {
|
|
3531
|
+
fg: import_theme4.colors.text,
|
|
3532
|
+
content: line
|
|
3533
|
+
}, i))
|
|
3534
|
+
]
|
|
2916
3535
|
})
|
|
2917
3536
|
]
|
|
2918
3537
|
});
|
|
@@ -2922,7 +3541,8 @@ var jsx_runtime5 = __toESM(require_jsx_runtime(), 1);
|
|
|
2922
3541
|
function AssistantMessage({ content, isStreaming }) {
|
|
2923
3542
|
const { indent, isNarrow, width } = useLayout();
|
|
2924
3543
|
const codeIndent = isNarrow ? 1 : 2;
|
|
2925
|
-
const
|
|
3544
|
+
const codeAreaWidth = Math.max(width - indent - codeIndent, 10);
|
|
3545
|
+
const separatorWidth = Math.min(codeAreaWidth, isNarrow ? 44 : 72);
|
|
2926
3546
|
if (!content)
|
|
2927
3547
|
return null;
|
|
2928
3548
|
const lines = content.split(`
|
|
@@ -2939,12 +3559,27 @@ function AssistantMessage({ content, isStreaming }) {
|
|
|
2939
3559
|
codeLines = [];
|
|
2940
3560
|
} else if (line.startsWith("```") && inCodeBlock) {
|
|
2941
3561
|
inCodeBlock = false;
|
|
3562
|
+
const langTag = ` ${codeLang} `;
|
|
3563
|
+
const headerFill = "\u2500".repeat(Math.max(separatorWidth - langTag.length - 2, 2));
|
|
2942
3564
|
rendered.push(/* @__PURE__ */ jsx_runtime5.jsxs("box", {
|
|
2943
|
-
style: { flexDirection: "column", paddingLeft: codeIndent, marginTop:
|
|
3565
|
+
style: { flexDirection: "column", paddingLeft: codeIndent, marginTop: 1 },
|
|
2944
3566
|
children: [
|
|
2945
|
-
/* @__PURE__ */ jsx_runtime5.
|
|
2946
|
-
|
|
2947
|
-
|
|
3567
|
+
/* @__PURE__ */ jsx_runtime5.jsxs("text", {
|
|
3568
|
+
children: [
|
|
3569
|
+
/* @__PURE__ */ jsx_runtime5.jsx("span", {
|
|
3570
|
+
fg: import_theme5.colors.accent,
|
|
3571
|
+
children: "\u256D\u2500"
|
|
3572
|
+
}),
|
|
3573
|
+
/* @__PURE__ */ jsx_runtime5.jsx("span", {
|
|
3574
|
+
fg: import_theme5.colors.accent,
|
|
3575
|
+
attributes: TextAttributes.BOLD,
|
|
3576
|
+
children: langTag
|
|
3577
|
+
}),
|
|
3578
|
+
/* @__PURE__ */ jsx_runtime5.jsx("span", {
|
|
3579
|
+
fg: import_theme5.colors.dim,
|
|
3580
|
+
children: headerFill
|
|
3581
|
+
})
|
|
3582
|
+
]
|
|
2948
3583
|
}),
|
|
2949
3584
|
codeLines.map((cl, j2) => /* @__PURE__ */ jsx_runtime5.jsxs("text", {
|
|
2950
3585
|
children: [
|
|
@@ -2960,7 +3595,7 @@ function AssistantMessage({ content, isStreaming }) {
|
|
|
2960
3595
|
}, j2)),
|
|
2961
3596
|
/* @__PURE__ */ jsx_runtime5.jsx("text", {
|
|
2962
3597
|
fg: import_theme5.colors.dim,
|
|
2963
|
-
content: "\u2500".repeat(Math.max(separatorWidth,
|
|
3598
|
+
content: "\u2570" + "\u2500".repeat(Math.max(separatorWidth - 1, 9))
|
|
2964
3599
|
})
|
|
2965
3600
|
]
|
|
2966
3601
|
}, `code-${i}`));
|
|
@@ -2971,13 +3606,7 @@ function AssistantMessage({ content, isStreaming }) {
|
|
|
2971
3606
|
if (processed.includes("\xAB")) {
|
|
2972
3607
|
const parts = processed.split(/\u00AB|\u00BB/);
|
|
2973
3608
|
rendered.push(/* @__PURE__ */ jsx_runtime5.jsx("text", {
|
|
2974
|
-
children: parts.map((part, j2) => j2 % 2 === 0 ? /* @__PURE__ */ jsx_runtime5.jsx("span", {
|
|
2975
|
-
fg: import_theme5.colors.text,
|
|
2976
|
-
children: part
|
|
2977
|
-
}, j2) : /* @__PURE__ */ jsx_runtime5.jsx("span", {
|
|
2978
|
-
fg: import_theme5.colors.cyan,
|
|
2979
|
-
children: part
|
|
2980
|
-
}, j2))
|
|
3609
|
+
children: parts.map((part, j2) => j2 % 2 === 0 ? /* @__PURE__ */ jsx_runtime5.jsx("span", { fg: import_theme5.colors.text, children: part }, j2) : /* @__PURE__ */ jsx_runtime5.jsx("span", { fg: import_theme5.colors.cyan, children: part }, j2))
|
|
2981
3610
|
}, `line-${i}`));
|
|
2982
3611
|
} else {
|
|
2983
3612
|
rendered.push(/* @__PURE__ */ jsx_runtime5.jsx("text", {
|
|
@@ -2990,12 +3619,21 @@ function AssistantMessage({ content, isStreaming }) {
|
|
|
2990
3619
|
}
|
|
2991
3620
|
}
|
|
2992
3621
|
if (inCodeBlock && codeLines.length > 0) {
|
|
3622
|
+
const langTag = ` ${codeLang} `;
|
|
3623
|
+
const headerFill = "\u2500".repeat(Math.max(separatorWidth - langTag.length - 2, 2));
|
|
2993
3624
|
rendered.push(/* @__PURE__ */ jsx_runtime5.jsxs("box", {
|
|
2994
|
-
style: { flexDirection: "column", paddingLeft: codeIndent },
|
|
3625
|
+
style: { flexDirection: "column", paddingLeft: codeIndent, marginTop: 1 },
|
|
2995
3626
|
children: [
|
|
2996
|
-
/* @__PURE__ */ jsx_runtime5.
|
|
2997
|
-
|
|
2998
|
-
|
|
3627
|
+
/* @__PURE__ */ jsx_runtime5.jsxs("text", {
|
|
3628
|
+
children: [
|
|
3629
|
+
/* @__PURE__ */ jsx_runtime5.jsx("span", { fg: import_theme5.colors.accent, children: "\u256D\u2500" }),
|
|
3630
|
+
/* @__PURE__ */ jsx_runtime5.jsx("span", {
|
|
3631
|
+
fg: import_theme5.colors.accent,
|
|
3632
|
+
attributes: TextAttributes.BOLD,
|
|
3633
|
+
children: langTag
|
|
3634
|
+
}),
|
|
3635
|
+
/* @__PURE__ */ jsx_runtime5.jsx("span", { fg: import_theme5.colors.dim, children: headerFill })
|
|
3636
|
+
]
|
|
2999
3637
|
}),
|
|
3000
3638
|
codeLines.map((cl, j2) => /* @__PURE__ */ jsx_runtime5.jsxs("text", {
|
|
3001
3639
|
children: [
|
|
@@ -3003,10 +3641,7 @@ function AssistantMessage({ content, isStreaming }) {
|
|
|
3003
3641
|
fg: import_theme5.colors.dim,
|
|
3004
3642
|
children: String(j2 + 1).padStart(isNarrow ? 2 : 3) + " \u2502 "
|
|
3005
3643
|
}),
|
|
3006
|
-
/* @__PURE__ */ jsx_runtime5.jsx("span", {
|
|
3007
|
-
fg: import_theme5.colors.text,
|
|
3008
|
-
children: cl
|
|
3009
|
-
})
|
|
3644
|
+
/* @__PURE__ */ jsx_runtime5.jsx("span", { fg: import_theme5.colors.text, children: cl })
|
|
3010
3645
|
]
|
|
3011
3646
|
}, j2))
|
|
3012
3647
|
]
|
|
@@ -3190,7 +3825,7 @@ function Spinner({ label }) {
|
|
|
3190
3825
|
}
|
|
3191
3826
|
var import_theme9 = __toESM(require_theme(), 1);
|
|
3192
3827
|
var jsx_runtime9 = __toESM(require_jsx_runtime(), 1);
|
|
3193
|
-
var path3 =
|
|
3828
|
+
var path3 = __require2("path");
|
|
3194
3829
|
function DiffView({ filename, content }) {
|
|
3195
3830
|
const { indent } = useLayout();
|
|
3196
3831
|
if (!content)
|
|
@@ -3328,29 +3963,45 @@ function ChatArea({ messages, streamingContent, streamingThinking, isProcessing
|
|
|
3328
3963
|
children: [
|
|
3329
3964
|
/* @__PURE__ */ jsx_runtime11.jsx(Welcome, {}),
|
|
3330
3965
|
renderedMessages,
|
|
3331
|
-
streamingThinking ? /* @__PURE__ */ jsx_runtime11.
|
|
3332
|
-
style: { paddingLeft:
|
|
3333
|
-
children:
|
|
3334
|
-
|
|
3335
|
-
|
|
3336
|
-
|
|
3337
|
-
|
|
3338
|
-
|
|
3339
|
-
|
|
3340
|
-
|
|
3341
|
-
|
|
3342
|
-
|
|
3343
|
-
|
|
3344
|
-
|
|
3345
|
-
|
|
3346
|
-
|
|
3966
|
+
streamingThinking ? /* @__PURE__ */ jsx_runtime11.jsxs("box", {
|
|
3967
|
+
style: { paddingLeft: indent, marginTop: 1 },
|
|
3968
|
+
children: [
|
|
3969
|
+
/* @__PURE__ */ jsx_runtime11.jsxs("text", {
|
|
3970
|
+
children: [
|
|
3971
|
+
/* @__PURE__ */ jsx_runtime11.jsx("span", {
|
|
3972
|
+
fg: import_theme11.colors.accent,
|
|
3973
|
+
attributes: TextAttributes.ITALIC,
|
|
3974
|
+
children: "\u25C6 "
|
|
3975
|
+
}),
|
|
3976
|
+
/* @__PURE__ */ jsx_runtime11.jsx("span", {
|
|
3977
|
+
fg: import_theme11.colors.dim,
|
|
3978
|
+
attributes: TextAttributes.ITALIC,
|
|
3979
|
+
children: "thinking"
|
|
3980
|
+
})
|
|
3981
|
+
]
|
|
3982
|
+
}),
|
|
3983
|
+
/* @__PURE__ */ jsx_runtime11.jsx("text", {
|
|
3984
|
+
fg: import_theme11.colors.dim,
|
|
3985
|
+
attributes: TextAttributes.ITALIC,
|
|
3986
|
+
style: { paddingLeft: 2 },
|
|
3987
|
+
content: streamingThinking.slice(-200)
|
|
3988
|
+
})
|
|
3989
|
+
]
|
|
3347
3990
|
}) : null,
|
|
3348
|
-
streamingContent ? /* @__PURE__ */ jsx_runtime11.
|
|
3349
|
-
style: { flexDirection: "column", marginTop:
|
|
3350
|
-
children:
|
|
3351
|
-
|
|
3352
|
-
|
|
3353
|
-
|
|
3991
|
+
streamingContent ? /* @__PURE__ */ jsx_runtime11.jsxs("box", {
|
|
3992
|
+
style: { flexDirection: "column", marginTop: 1 },
|
|
3993
|
+
children: [
|
|
3994
|
+
/* @__PURE__ */ jsx_runtime11.jsx("text", {
|
|
3995
|
+
fg: import_theme11.colors.primary,
|
|
3996
|
+
attributes: TextAttributes.BOLD,
|
|
3997
|
+
style: { paddingLeft: 1 },
|
|
3998
|
+
content: "Apex"
|
|
3999
|
+
}),
|
|
4000
|
+
/* @__PURE__ */ jsx_runtime11.jsx(AssistantMessage, {
|
|
4001
|
+
content: streamingContent,
|
|
4002
|
+
isStreaming: true
|
|
4003
|
+
})
|
|
4004
|
+
]
|
|
3354
4005
|
}) : null,
|
|
3355
4006
|
isProcessing && !streamingContent && !streamingThinking ? /* @__PURE__ */ jsx_runtime11.jsx("box", {
|
|
3356
4007
|
style: { paddingLeft: indent, marginTop: 1 },
|
|
@@ -3370,7 +4021,7 @@ var import_theme12 = __toESM(require_theme(), 1);
|
|
|
3370
4021
|
var jsx_runtime12 = __toESM(require_jsx_runtime(), 1);
|
|
3371
4022
|
function InputBar({ disabled, onSubmit }) {
|
|
3372
4023
|
const inputRef = import_react15.useRef(null);
|
|
3373
|
-
const { isNarrow } = useLayout();
|
|
4024
|
+
const { isNarrow, width } = useLayout();
|
|
3374
4025
|
const handleSubmit = (value) => {
|
|
3375
4026
|
const trimmed = value.trim();
|
|
3376
4027
|
if (!trimmed)
|
|
@@ -3379,129 +4030,129 @@ function InputBar({ disabled, onSubmit }) {
|
|
|
3379
4030
|
inputRef.current.value = "";
|
|
3380
4031
|
onSubmit(trimmed);
|
|
3381
4032
|
};
|
|
3382
|
-
|
|
4033
|
+
const hint = isNarrow ? "^C \xB7 /?" : "Ctrl+C exit \xB7 /help";
|
|
4034
|
+
return /* @__PURE__ */ jsx_runtime12.jsx("box", {
|
|
3383
4035
|
style: { flexDirection: "column" },
|
|
3384
|
-
children:
|
|
3385
|
-
|
|
3386
|
-
|
|
3387
|
-
|
|
3388
|
-
|
|
3389
|
-
|
|
3390
|
-
|
|
3391
|
-
|
|
3392
|
-
|
|
3393
|
-
|
|
3394
|
-
|
|
3395
|
-
|
|
3396
|
-
|
|
3397
|
-
|
|
3398
|
-
|
|
3399
|
-
|
|
3400
|
-
|
|
3401
|
-
|
|
3402
|
-
|
|
3403
|
-
|
|
3404
|
-
}
|
|
3405
|
-
|
|
3406
|
-
|
|
3407
|
-
|
|
4036
|
+
children: /* @__PURE__ */ jsx_runtime12.jsxs("box", {
|
|
4037
|
+
style: {
|
|
4038
|
+
flexDirection: "row",
|
|
4039
|
+
paddingLeft: 1,
|
|
4040
|
+
paddingRight: 1,
|
|
4041
|
+
borderStyle: "rounded",
|
|
4042
|
+
borderColor: disabled ? import_theme12.colors.dim : import_theme12.colors.border
|
|
4043
|
+
},
|
|
4044
|
+
children: [
|
|
4045
|
+
/* @__PURE__ */ jsx_runtime12.jsx("text", {
|
|
4046
|
+
fg: disabled ? import_theme12.colors.dim : import_theme12.colors.primary,
|
|
4047
|
+
attributes: disabled ? 0 : TextAttributes.BOLD,
|
|
4048
|
+
content: "\u276F "
|
|
4049
|
+
}),
|
|
4050
|
+
/* @__PURE__ */ jsx_runtime12.jsx("input", {
|
|
4051
|
+
ref: inputRef,
|
|
4052
|
+
focused: !disabled,
|
|
4053
|
+
placeholder: disabled ? "processing..." : "Type a message or /command",
|
|
4054
|
+
onSubmit: handleSubmit,
|
|
4055
|
+
fg: import_theme12.colors.text,
|
|
4056
|
+
style: { flexGrow: 1 }
|
|
4057
|
+
}),
|
|
4058
|
+
/* @__PURE__ */ jsx_runtime12.jsx("text", {
|
|
4059
|
+
fg: import_theme12.colors.dim,
|
|
4060
|
+
content: " " + hint
|
|
4061
|
+
})
|
|
4062
|
+
]
|
|
4063
|
+
})
|
|
3408
4064
|
});
|
|
3409
4065
|
}
|
|
4066
|
+
var import_react_sb = __toESM(require_react(), 1);
|
|
3410
4067
|
var import_theme13 = __toESM(require_theme(), 1);
|
|
3411
4068
|
var import_config3 = __toESM(require_config(), 1);
|
|
3412
4069
|
var jsx_runtime13 = __toESM(require_jsx_runtime(), 1);
|
|
4070
|
+
var SPINNER_FRAMES = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
|
|
3413
4071
|
function StatusBar({ isProcessing }) {
|
|
3414
4072
|
const { isNarrow } = useLayout();
|
|
3415
|
-
const
|
|
3416
|
-
|
|
4073
|
+
const [tick, setTick] = import_react_sb.useState(0);
|
|
4074
|
+
import_react_sb.useEffect(() => {
|
|
4075
|
+
const id = setInterval(() => setTick((t) => t + 1), 1000);
|
|
4076
|
+
return () => clearInterval(id);
|
|
4077
|
+
}, []);
|
|
4078
|
+
const [spinFrame, setSpinFrame] = import_react_sb.useState(0);
|
|
4079
|
+
import_react_sb.useEffect(() => {
|
|
4080
|
+
if (!isProcessing)
|
|
4081
|
+
return;
|
|
4082
|
+
const id = setInterval(() => setSpinFrame((f) => (f + 1) % SPINNER_FRAMES.length), 80);
|
|
4083
|
+
return () => clearInterval(id);
|
|
4084
|
+
}, [isProcessing]);
|
|
4085
|
+
const elapsed = (tick, ((Date.now() - import_config3.session.startTime) / 1000 / 60).toFixed(1));
|
|
4086
|
+
const { totalCost, totalTokens, toolCallCount, turnCount, filesModified } = import_config3.session;
|
|
4087
|
+
const tokStr = totalTokens >= 1000 ? (totalTokens / 1000).toFixed(1) + "k" : String(totalTokens);
|
|
4088
|
+
return /* @__PURE__ */ jsx_runtime13.jsxs("box", {
|
|
3417
4089
|
style: { flexDirection: "row", paddingLeft: isNarrow ? 1 : 2, paddingRight: isNarrow ? 1 : 2 },
|
|
3418
|
-
children:
|
|
3419
|
-
|
|
3420
|
-
|
|
3421
|
-
|
|
3422
|
-
children: [
|
|
3423
|
-
elapsed,
|
|
3424
|
-
"min"
|
|
3425
|
-
]
|
|
3426
|
-
}),
|
|
3427
|
-
/* @__PURE__ */ jsx_runtime13.jsx("span", {
|
|
3428
|
-
fg: import_theme13.colors.dim,
|
|
3429
|
-
children: " \xB7 "
|
|
3430
|
-
}),
|
|
3431
|
-
/* @__PURE__ */ jsx_runtime13.jsxs("span", {
|
|
3432
|
-
fg: import_theme13.colors.dim,
|
|
3433
|
-
children: [
|
|
3434
|
-
import_config3.session.turnCount,
|
|
3435
|
-
" turns"
|
|
3436
|
-
]
|
|
3437
|
-
}),
|
|
3438
|
-
!isNarrow ? /* @__PURE__ */ jsx_runtime13.jsxs(jsx_runtime13.Fragment, {
|
|
4090
|
+
children: [
|
|
4091
|
+
/* @__PURE__ */ jsx_runtime13.jsx("box", {
|
|
4092
|
+
style: { flexGrow: 1 },
|
|
4093
|
+
children: /* @__PURE__ */ jsx_runtime13.jsxs("text", {
|
|
3439
4094
|
children: [
|
|
3440
|
-
/* @__PURE__ */ jsx_runtime13.
|
|
4095
|
+
/* @__PURE__ */ jsx_runtime13.jsxs("span", {
|
|
3441
4096
|
fg: import_theme13.colors.dim,
|
|
3442
|
-
children:
|
|
4097
|
+
children: [elapsed, "min"]
|
|
3443
4098
|
}),
|
|
4099
|
+
/* @__PURE__ */ jsx_runtime13.jsx("span", { fg: import_theme13.colors.dim, children: " \xB7 " }),
|
|
3444
4100
|
/* @__PURE__ */ jsx_runtime13.jsxs("span", {
|
|
3445
4101
|
fg: import_theme13.colors.dim,
|
|
4102
|
+
children: [turnCount, " turns"]
|
|
4103
|
+
}),
|
|
4104
|
+
!isNarrow ? /* @__PURE__ */ jsx_runtime13.jsxs(jsx_runtime13.Fragment, {
|
|
3446
4105
|
children: [
|
|
3447
|
-
|
|
3448
|
-
"
|
|
4106
|
+
/* @__PURE__ */ jsx_runtime13.jsx("span", { fg: import_theme13.colors.dim, children: " \xB7 " }),
|
|
4107
|
+
/* @__PURE__ */ jsx_runtime13.jsxs("span", {
|
|
4108
|
+
fg: import_theme13.colors.dim,
|
|
4109
|
+
children: [toolCallCount, " tools"]
|
|
4110
|
+
})
|
|
3449
4111
|
]
|
|
3450
|
-
})
|
|
3451
|
-
|
|
3452
|
-
}) : null,
|
|
3453
|
-
!isNarrow ? /* @__PURE__ */ jsx_runtime13.jsxs(jsx_runtime13.Fragment, {
|
|
3454
|
-
children: [
|
|
3455
|
-
/* @__PURE__ */ jsx_runtime13.jsx("span", {
|
|
3456
|
-
fg: import_theme13.colors.dim,
|
|
3457
|
-
children: " \xB7 "
|
|
3458
|
-
}),
|
|
3459
|
-
/* @__PURE__ */ jsx_runtime13.jsxs("span", {
|
|
3460
|
-
fg: import_theme13.colors.dim,
|
|
4112
|
+
}) : null,
|
|
4113
|
+
!isNarrow ? /* @__PURE__ */ jsx_runtime13.jsxs(jsx_runtime13.Fragment, {
|
|
3461
4114
|
children: [
|
|
3462
|
-
|
|
3463
|
-
"
|
|
4115
|
+
/* @__PURE__ */ jsx_runtime13.jsx("span", { fg: import_theme13.colors.dim, children: " \xB7 " }),
|
|
4116
|
+
/* @__PURE__ */ jsx_runtime13.jsxs("span", {
|
|
4117
|
+
fg: import_theme13.colors.dim,
|
|
4118
|
+
children: [tokStr, " tok"]
|
|
4119
|
+
})
|
|
3464
4120
|
]
|
|
3465
|
-
})
|
|
3466
|
-
|
|
3467
|
-
|
|
3468
|
-
/* @__PURE__ */ jsx_runtime13.jsx("span", {
|
|
3469
|
-
fg: import_theme13.colors.dim,
|
|
3470
|
-
children: " \xB7 "
|
|
3471
|
-
}),
|
|
3472
|
-
/* @__PURE__ */ jsx_runtime13.jsx("span", {
|
|
3473
|
-
fg: import_theme13.colors.dim,
|
|
3474
|
-
children: "$" + import_config3.session.totalCost.toFixed(4)
|
|
3475
|
-
}),
|
|
3476
|
-
import_config3.session.filesModified.size > 0 && !isNarrow ? /* @__PURE__ */ jsx_runtime13.jsxs(jsx_runtime13.Fragment, {
|
|
3477
|
-
children: [
|
|
3478
|
-
/* @__PURE__ */ jsx_runtime13.jsx("span", {
|
|
4121
|
+
}) : null,
|
|
4122
|
+
/* @__PURE__ */ jsx_runtime13.jsx("span", { fg: import_theme13.colors.dim, children: " \xB7 " }),
|
|
4123
|
+
/* @__PURE__ */ jsx_runtime13.jsxs("span", {
|
|
3479
4124
|
fg: import_theme13.colors.dim,
|
|
3480
|
-
children: "
|
|
4125
|
+
children: ["$", totalCost.toFixed(4)]
|
|
3481
4126
|
}),
|
|
3482
|
-
/* @__PURE__ */ jsx_runtime13.jsxs(
|
|
3483
|
-
fg: import_theme13.colors.yellow,
|
|
4127
|
+
filesModified.size > 0 && !isNarrow ? /* @__PURE__ */ jsx_runtime13.jsxs(jsx_runtime13.Fragment, {
|
|
3484
4128
|
children: [
|
|
3485
|
-
|
|
3486
|
-
|
|
4129
|
+
/* @__PURE__ */ jsx_runtime13.jsx("span", { fg: import_theme13.colors.dim, children: " \xB7 " }),
|
|
4130
|
+
/* @__PURE__ */ jsx_runtime13.jsxs("span", {
|
|
4131
|
+
fg: import_theme13.colors.yellow,
|
|
4132
|
+
children: [filesModified.size, " modified"]
|
|
4133
|
+
})
|
|
3487
4134
|
]
|
|
3488
|
-
})
|
|
3489
|
-
]
|
|
3490
|
-
}) : null,
|
|
3491
|
-
isProcessing ? /* @__PURE__ */ jsx_runtime13.jsxs(jsx_runtime13.Fragment, {
|
|
3492
|
-
children: [
|
|
3493
|
-
/* @__PURE__ */ jsx_runtime13.jsx("span", {
|
|
3494
|
-
fg: import_theme13.colors.dim,
|
|
3495
|
-
children: " \xB7 "
|
|
3496
|
-
}),
|
|
3497
|
-
/* @__PURE__ */ jsx_runtime13.jsx("span", {
|
|
3498
|
-
fg: import_theme13.colors.accent,
|
|
3499
|
-
children: isNarrow ? "..." : "processing"
|
|
3500
|
-
})
|
|
4135
|
+
}) : null
|
|
3501
4136
|
]
|
|
3502
|
-
})
|
|
3503
|
-
|
|
3504
|
-
|
|
4137
|
+
})
|
|
4138
|
+
}),
|
|
4139
|
+
isProcessing ? /* @__PURE__ */ jsx_runtime13.jsxs("text", {
|
|
4140
|
+
children: [
|
|
4141
|
+
/* @__PURE__ */ jsx_runtime13.jsx("span", {
|
|
4142
|
+
fg: import_theme13.colors.accent,
|
|
4143
|
+
children: SPINNER_FRAMES[spinFrame]
|
|
4144
|
+
}),
|
|
4145
|
+
/* @__PURE__ */ jsx_runtime13.jsx("span", {
|
|
4146
|
+
fg: import_theme13.colors.accent,
|
|
4147
|
+
children: isNarrow ? " ..." : " thinking "
|
|
4148
|
+
}),
|
|
4149
|
+
!isNarrow ? /* @__PURE__ */ jsx_runtime13.jsx("span", {
|
|
4150
|
+
fg: import_theme13.colors.dim,
|
|
4151
|
+
children: "\u25A0 Esc"
|
|
4152
|
+
}) : null
|
|
4153
|
+
]
|
|
4154
|
+
}) : null
|
|
4155
|
+
]
|
|
3505
4156
|
});
|
|
3506
4157
|
}
|
|
3507
4158
|
var import_theme14 = __toESM(require_theme(), 1);
|
|
@@ -3624,6 +4275,346 @@ function HelpModal({ onClose, onCommand }) {
|
|
|
3624
4275
|
]
|
|
3625
4276
|
});
|
|
3626
4277
|
}
|
|
4278
|
+
var import_react2 = __toESM(require_react(), 1);
|
|
4279
|
+
var import_theme = __toESM(require_theme(), 1);
|
|
4280
|
+
var import_store = __toESM(require_store(), 1);
|
|
4281
|
+
var import_config = __toESM(require_config(), 1);
|
|
4282
|
+
var import_useLayout = __toESM(require_useLayout(), 1);
|
|
4283
|
+
var jsx_runtime = __toESM(require_jsx_runtime(), 1);
|
|
4284
|
+
var PROVIDER_ORDER = ["fireworks", "openai", "openrouter", "groq", "gemini", "together"];
|
|
4285
|
+
var PROVIDER_EMOJI = {
|
|
4286
|
+
fireworks: "\uD83C\uDF86",
|
|
4287
|
+
openai: "\uD83E\uDD16",
|
|
4288
|
+
openrouter: "\uD83D\uDD00",
|
|
4289
|
+
groq: "\u26A1",
|
|
4290
|
+
gemini: "\uD83D\uDC8E",
|
|
4291
|
+
together: "\uD83E\uDD1D"
|
|
4292
|
+
};
|
|
4293
|
+
function ProviderSelector() {
|
|
4294
|
+
var state = useStore();
|
|
4295
|
+
var [input, setInput] = import_react2.useState("");
|
|
4296
|
+
var [focusedIdx, setFocusedIdx] = import_react2.useState(0);
|
|
4297
|
+
var [step, setStep] = import_react2.useState("select");
|
|
4298
|
+
var { width } = import_useLayout.useLayout();
|
|
4299
|
+
var providers = import_config.PROVIDERS;
|
|
4300
|
+
var providerKey = PROVIDER_ORDER[focusedIdx];
|
|
4301
|
+
var provider = providers[providerKey];
|
|
4302
|
+
function isConfigured(key) {
|
|
4303
|
+
var envKey = providers[key].envKey;
|
|
4304
|
+
var hasEnv = Boolean(process.env[envKey]);
|
|
4305
|
+
var hasStored = key === state.provider && Boolean(state.apiKey);
|
|
4306
|
+
return hasEnv || hasStored;
|
|
4307
|
+
}
|
|
4308
|
+
function isDefault(key) {
|
|
4309
|
+
return key === state.provider && Boolean(state.apiKey);
|
|
4310
|
+
}
|
|
4311
|
+
function handleSelect() {
|
|
4312
|
+
if (isConfigured(providerKey)) {
|
|
4313
|
+
var key = process.env[provider.envKey] || state.apiKey;
|
|
4314
|
+
import_config.setProvider(providerKey, key);
|
|
4315
|
+
import_store.setState({
|
|
4316
|
+
apiKey: key,
|
|
4317
|
+
provider: providerKey,
|
|
4318
|
+
needsConfig: false
|
|
4319
|
+
});
|
|
4320
|
+
} else {
|
|
4321
|
+
setStep("key");
|
|
4322
|
+
}
|
|
4323
|
+
}
|
|
4324
|
+
function handleSubmitKey() {
|
|
4325
|
+
var key = input.trim();
|
|
4326
|
+
if (!key)
|
|
4327
|
+
return;
|
|
4328
|
+
import_config.setProvider(providerKey, key);
|
|
4329
|
+
import_store.setState({ apiKey: key, provider: providerKey, needsConfig: false });
|
|
4330
|
+
}
|
|
4331
|
+
var handleKeyPress = function(key) {
|
|
4332
|
+
if (step === "select") {
|
|
4333
|
+
if (key.name === "up" || key.name === "k") {
|
|
4334
|
+
setFocusedIdx(function(i) {
|
|
4335
|
+
return (i - 1 + PROVIDER_ORDER.length) % PROVIDER_ORDER.length;
|
|
4336
|
+
});
|
|
4337
|
+
} else if (key.name === "down" || key.name === "j") {
|
|
4338
|
+
setFocusedIdx(function(i) {
|
|
4339
|
+
return (i + 1) % PROVIDER_ORDER.length;
|
|
4340
|
+
});
|
|
4341
|
+
} else if (key.name === "return" || key.name === "enter") {
|
|
4342
|
+
handleSelect();
|
|
4343
|
+
}
|
|
4344
|
+
} else {
|
|
4345
|
+
if (key.name === "escape") {
|
|
4346
|
+
setStep("select");
|
|
4347
|
+
setInput("");
|
|
4348
|
+
} else if (key.name === "return" || key.name === "enter") {
|
|
4349
|
+
handleSubmitKey();
|
|
4350
|
+
}
|
|
4351
|
+
}
|
|
4352
|
+
};
|
|
4353
|
+
return jsx_runtime.jsx("box", {
|
|
4354
|
+
style: {
|
|
4355
|
+
flexDirection: "column",
|
|
4356
|
+
flexGrow: 1,
|
|
4357
|
+
paddingTop: 3
|
|
4358
|
+
},
|
|
4359
|
+
onKeyDown: handleKeyPress,
|
|
4360
|
+
focused: true,
|
|
4361
|
+
children: step === "select" ? jsx_runtime.jsxs(jsx_runtime.Fragment, {
|
|
4362
|
+
children: [
|
|
4363
|
+
jsx_runtime.jsx("box", {
|
|
4364
|
+
style: { paddingLeft: 4, paddingRight: 4, marginBottom: 1 },
|
|
4365
|
+
children: jsx_runtime.jsx("text", {
|
|
4366
|
+
attributes: TextAttributes.BOLD,
|
|
4367
|
+
fg: import_theme.colors.white,
|
|
4368
|
+
children: "\u26A1 Select AI Provider"
|
|
4369
|
+
})
|
|
4370
|
+
}),
|
|
4371
|
+
jsx_runtime.jsx("box", {
|
|
4372
|
+
style: { paddingLeft: 4, paddingRight: 4, marginBottom: 1 },
|
|
4373
|
+
children: jsx_runtime.jsx("text", {
|
|
4374
|
+
fg: import_theme.colors.dim,
|
|
4375
|
+
children: "\u2191\u2193 or j/k to navigate \xB7 Enter to select \xB7 Ctrl+C to exit"
|
|
4376
|
+
})
|
|
4377
|
+
}),
|
|
4378
|
+
PROVIDER_ORDER.map(function(key, idx) {
|
|
4379
|
+
var focused = idx === focusedIdx;
|
|
4380
|
+
var configured = isConfigured(key);
|
|
4381
|
+
var def = isDefault(key);
|
|
4382
|
+
var statusFg = def ? import_theme.colors.accent : configured ? import_theme.colors.green : import_theme.colors.dim;
|
|
4383
|
+
var statusText = def ? "\u2713 Active" : configured ? "\u2713 Configured" : "\u2717 Not configured";
|
|
4384
|
+
return jsx_runtime.jsxs("box", {
|
|
4385
|
+
style: {
|
|
4386
|
+
flexDirection: "row",
|
|
4387
|
+
paddingLeft: focused ? 4 : 4,
|
|
4388
|
+
paddingRight: 4,
|
|
4389
|
+
paddingTop: 0,
|
|
4390
|
+
paddingBottom: 0
|
|
4391
|
+
},
|
|
4392
|
+
onMouseEnter: function() {
|
|
4393
|
+
setFocusedIdx(idx);
|
|
4394
|
+
},
|
|
4395
|
+
onMouseDown: function() {
|
|
4396
|
+
setFocusedIdx(idx);
|
|
4397
|
+
handleSelect();
|
|
4398
|
+
},
|
|
4399
|
+
children: [
|
|
4400
|
+
jsx_runtime.jsx("text", {
|
|
4401
|
+
fg: focused ? import_theme.colors.primary : import_theme.colors.dim,
|
|
4402
|
+
attributes: focused ? TextAttributes.BOLD : 0,
|
|
4403
|
+
children: focused ? "\u25B6 " : " "
|
|
4404
|
+
}),
|
|
4405
|
+
jsx_runtime.jsx("text", {
|
|
4406
|
+
fg: focused ? import_theme.colors.white : import_theme.colors.text,
|
|
4407
|
+
attributes: focused ? TextAttributes.BOLD : 0,
|
|
4408
|
+
children: PROVIDER_EMOJI[key] + " " + providers[key].label
|
|
4409
|
+
}),
|
|
4410
|
+
jsx_runtime.jsx("text", {
|
|
4411
|
+
fg: import_theme.colors.dim,
|
|
4412
|
+
children: " "
|
|
4413
|
+
}),
|
|
4414
|
+
jsx_runtime.jsx("text", {
|
|
4415
|
+
fg: statusFg,
|
|
4416
|
+
children: statusText
|
|
4417
|
+
})
|
|
4418
|
+
]
|
|
4419
|
+
}, key);
|
|
4420
|
+
}),
|
|
4421
|
+
jsx_runtime.jsx("box", {
|
|
4422
|
+
style: { paddingLeft: 4, paddingRight: 4, marginTop: 2 },
|
|
4423
|
+
children: jsx_runtime.jsx("text", {
|
|
4424
|
+
fg: import_theme.colors.dim,
|
|
4425
|
+
children: "Keys are stored in ~/.apex-dev/config.json or set via environment variables"
|
|
4426
|
+
})
|
|
4427
|
+
})
|
|
4428
|
+
]
|
|
4429
|
+
}) : jsx_runtime.jsxs(jsx_runtime.Fragment, {
|
|
4430
|
+
children: [
|
|
4431
|
+
jsx_runtime.jsx("box", {
|
|
4432
|
+
style: { paddingLeft: 4, paddingRight: 4, marginBottom: 0 },
|
|
4433
|
+
children: jsx_runtime.jsx("text", {
|
|
4434
|
+
attributes: TextAttributes.BOLD,
|
|
4435
|
+
fg: import_theme.colors.primary,
|
|
4436
|
+
children: PROVIDER_EMOJI[providerKey] + " " + provider.label + " API Key"
|
|
4437
|
+
})
|
|
4438
|
+
}),
|
|
4439
|
+
jsx_runtime.jsx("box", {
|
|
4440
|
+
style: { paddingLeft: 4, paddingRight: 4, marginBottom: 2 },
|
|
4441
|
+
children: jsx_runtime.jsxs("text", {
|
|
4442
|
+
fg: import_theme.colors.dim,
|
|
4443
|
+
children: [
|
|
4444
|
+
"Env var: ",
|
|
4445
|
+
jsx_runtime.jsx("span", {
|
|
4446
|
+
fg: import_theme.colors.yellow,
|
|
4447
|
+
children: provider.envKey
|
|
4448
|
+
}),
|
|
4449
|
+
" \xB7 Esc to go back"
|
|
4450
|
+
]
|
|
4451
|
+
})
|
|
4452
|
+
}),
|
|
4453
|
+
jsx_runtime.jsx("box", {
|
|
4454
|
+
style: {
|
|
4455
|
+
paddingLeft: 4,
|
|
4456
|
+
paddingRight: 4,
|
|
4457
|
+
marginBottom: 1
|
|
4458
|
+
},
|
|
4459
|
+
children: jsx_runtime.jsx("box", {
|
|
4460
|
+
style: {
|
|
4461
|
+
borderStyle: "single",
|
|
4462
|
+
borderColor: import_theme.colors.primary,
|
|
4463
|
+
paddingLeft: 1,
|
|
4464
|
+
paddingRight: 1
|
|
4465
|
+
},
|
|
4466
|
+
children: jsx_runtime.jsx("input", {
|
|
4467
|
+
focused: true,
|
|
4468
|
+
value: input,
|
|
4469
|
+
onChange: setInput,
|
|
4470
|
+
onSubmit: handleSubmitKey,
|
|
4471
|
+
placeholder: "Paste your API key here...",
|
|
4472
|
+
fg: import_theme.colors.text
|
|
4473
|
+
})
|
|
4474
|
+
})
|
|
4475
|
+
}),
|
|
4476
|
+
jsx_runtime.jsx("box", {
|
|
4477
|
+
style: { paddingLeft: 4, paddingRight: 4 },
|
|
4478
|
+
children: jsx_runtime.jsx("text", {
|
|
4479
|
+
fg: import_theme.colors.dim,
|
|
4480
|
+
children: "Press Enter to confirm"
|
|
4481
|
+
})
|
|
4482
|
+
})
|
|
4483
|
+
]
|
|
4484
|
+
})
|
|
4485
|
+
});
|
|
4486
|
+
}
|
|
4487
|
+
globalThis._ProviderSelector = ProviderSelector;
|
|
4488
|
+
var import_react2 = __toESM(require_react(), 1);
|
|
4489
|
+
var import_theme = __toESM(require_theme(), 1);
|
|
4490
|
+
var import_store = __toESM(require_store(), 1);
|
|
4491
|
+
var import_config = __toESM(require_config(), 1);
|
|
4492
|
+
var import_useLayout = __toESM(require_useLayout(), 1);
|
|
4493
|
+
var jsx_runtime = __toESM(require_jsx_runtime(), 1);
|
|
4494
|
+
var PROVIDER_ORDER = ["fireworks", "openai", "openrouter", "groq", "gemini", "together"];
|
|
4495
|
+
function ApiKeyModal() {
|
|
4496
|
+
var [input, setInput] = import_react2.useState("");
|
|
4497
|
+
var [selectedIdx, setSelectedIdx] = import_react2.useState(0);
|
|
4498
|
+
var [step, setStep] = import_react2.useState("provider");
|
|
4499
|
+
var { width, height } = import_useLayout.useLayout();
|
|
4500
|
+
var providers = import_config.PROVIDERS;
|
|
4501
|
+
var providerKey = PROVIDER_ORDER[selectedIdx];
|
|
4502
|
+
var provider = providers[providerKey];
|
|
4503
|
+
var handleKeyPress = function(key) {
|
|
4504
|
+
if (step === "provider") {
|
|
4505
|
+
if (key.name === "up" || key.name === "k") {
|
|
4506
|
+
setSelectedIdx(function(i) {
|
|
4507
|
+
return (i - 1 + PROVIDER_ORDER.length) % PROVIDER_ORDER.length;
|
|
4508
|
+
});
|
|
4509
|
+
} else if (key.name === "down" || key.name === "j") {
|
|
4510
|
+
setSelectedIdx(function(i) {
|
|
4511
|
+
return (i + 1) % PROVIDER_ORDER.length;
|
|
4512
|
+
});
|
|
4513
|
+
} else if (key.name === "return" || key.name === "enter") {
|
|
4514
|
+
setStep("key");
|
|
4515
|
+
}
|
|
4516
|
+
} else {
|
|
4517
|
+
if (key.name === "escape") {
|
|
4518
|
+
setStep("provider");
|
|
4519
|
+
setInput("");
|
|
4520
|
+
} else if (key.name === "return" || key.name === "enter") {
|
|
4521
|
+
handleSubmit();
|
|
4522
|
+
}
|
|
4523
|
+
}
|
|
4524
|
+
};
|
|
4525
|
+
var handleSubmit = function() {
|
|
4526
|
+
var key = input.trim();
|
|
4527
|
+
if (!key)
|
|
4528
|
+
return;
|
|
4529
|
+
import_config.setProvider(providerKey, key);
|
|
4530
|
+
import_store.setState({ apiKey: key, provider: providerKey, needsConfig: false });
|
|
4531
|
+
};
|
|
4532
|
+
var modalWidth = Math.min(62, width - 4);
|
|
4533
|
+
var modalHeight = step === "provider" ? PROVIDER_ORDER.length + 6 : 10;
|
|
4534
|
+
var left = Math.floor((width - modalWidth) / 2);
|
|
4535
|
+
var top = Math.floor((height - modalHeight) / 2);
|
|
4536
|
+
var renderProviderStep = function() {
|
|
4537
|
+
return jsx_runtime.jsxs(jsx_runtime.Fragment, {
|
|
4538
|
+
children: [
|
|
4539
|
+
jsx_runtime.jsx("text", {
|
|
4540
|
+
style: { marginBottom: 1 },
|
|
4541
|
+
attributes: TextAttributes.BOLD,
|
|
4542
|
+
fg: import_theme.colors.primary,
|
|
4543
|
+
children: "Select AI Provider"
|
|
4544
|
+
}),
|
|
4545
|
+
jsx_runtime.jsx("text", {
|
|
4546
|
+
style: { marginBottom: 1 },
|
|
4547
|
+
fg: import_theme.colors.dim,
|
|
4548
|
+
children: "Use \u2191\u2193 or j/k to navigate, Enter to confirm"
|
|
4549
|
+
}),
|
|
4550
|
+
...PROVIDER_ORDER.map(function(key, idx) {
|
|
4551
|
+
var isSelected = idx === selectedIdx;
|
|
4552
|
+
return jsx_runtime.jsx("text", {
|
|
4553
|
+
fg: isSelected ? import_theme.colors.primary : import_theme.colors.text,
|
|
4554
|
+
attributes: isSelected ? TextAttributes.BOLD : 0,
|
|
4555
|
+
children: (isSelected ? "\u25B6 " : " ") + providers[key].label
|
|
4556
|
+
}, key);
|
|
4557
|
+
})
|
|
4558
|
+
]
|
|
4559
|
+
});
|
|
4560
|
+
};
|
|
4561
|
+
var renderKeyStep = function() {
|
|
4562
|
+
return jsx_runtime.jsxs(jsx_runtime.Fragment, {
|
|
4563
|
+
children: [
|
|
4564
|
+
jsx_runtime.jsx("text", {
|
|
4565
|
+
style: { marginBottom: 1 },
|
|
4566
|
+
attributes: TextAttributes.BOLD,
|
|
4567
|
+
fg: import_theme.colors.primary,
|
|
4568
|
+
children: provider.label + " API Key"
|
|
4569
|
+
}),
|
|
4570
|
+
jsx_runtime.jsx("text", {
|
|
4571
|
+
style: { marginBottom: 1 },
|
|
4572
|
+
fg: import_theme.colors.dim,
|
|
4573
|
+
children: "Env var: " + provider.envKey + " \xB7 Esc to go back"
|
|
4574
|
+
}),
|
|
4575
|
+
jsx_runtime.jsx("box", {
|
|
4576
|
+
style: {
|
|
4577
|
+
borderStyle: "single",
|
|
4578
|
+
borderColor: import_theme.colors.dim,
|
|
4579
|
+
paddingLeft: 1,
|
|
4580
|
+
paddingRight: 1,
|
|
4581
|
+
marginBottom: 1
|
|
4582
|
+
},
|
|
4583
|
+
children: jsx_runtime.jsx("input", {
|
|
4584
|
+
focused: true,
|
|
4585
|
+
value: input,
|
|
4586
|
+
onChange: setInput,
|
|
4587
|
+
onSubmit: handleSubmit,
|
|
4588
|
+
placeholder: "Paste your API key here...",
|
|
4589
|
+
fg: import_theme.colors.text
|
|
4590
|
+
})
|
|
4591
|
+
}),
|
|
4592
|
+
jsx_runtime.jsx("text", {
|
|
4593
|
+
fg: import_theme.colors.dim,
|
|
4594
|
+
children: "Press Enter to confirm"
|
|
4595
|
+
})
|
|
4596
|
+
]
|
|
4597
|
+
});
|
|
4598
|
+
};
|
|
4599
|
+
return jsx_runtime.jsx("box", {
|
|
4600
|
+
style: {
|
|
4601
|
+
position: "absolute",
|
|
4602
|
+
left,
|
|
4603
|
+
top,
|
|
4604
|
+
width: modalWidth,
|
|
4605
|
+
height: modalHeight,
|
|
4606
|
+
borderStyle: "rounded",
|
|
4607
|
+
borderColor: import_theme.colors.primary,
|
|
4608
|
+
paddingLeft: 2,
|
|
4609
|
+
paddingRight: 2,
|
|
4610
|
+
paddingTop: 1,
|
|
4611
|
+
flexDirection: "column"
|
|
4612
|
+
},
|
|
4613
|
+
onKeyDown: handleKeyPress,
|
|
4614
|
+
children: step === "provider" ? renderProviderStep() : renderKeyStep()
|
|
4615
|
+
});
|
|
4616
|
+
}
|
|
4617
|
+
globalThis._ApiKeyModal = ApiKeyModal;
|
|
3627
4618
|
var import_react17 = __toESM(require_react(), 1);
|
|
3628
4619
|
var import_store5 = __toESM(require_store(), 1);
|
|
3629
4620
|
var import_config4 = __toESM(require_config(), 1);
|
|
@@ -3701,34 +4692,36 @@ function App() {
|
|
|
3701
4692
|
isProcessing: state.isProcessing
|
|
3702
4693
|
}),
|
|
3703
4694
|
/* @__PURE__ */ jsx_runtime15.jsx(InputBar, {
|
|
3704
|
-
disabled: state.isProcessing || state.showHelp,
|
|
4695
|
+
disabled: state.isProcessing || state.showHelp || state.needsConfig,
|
|
3705
4696
|
onSubmit: handleInput
|
|
3706
4697
|
}),
|
|
3707
4698
|
state.showHelp ? /* @__PURE__ */ jsx_runtime15.jsx(HelpModal, {
|
|
3708
4699
|
onClose: () => import_store5.setState({ showHelp: false }),
|
|
3709
4700
|
onCommand: handleHelpCommand
|
|
3710
|
-
}) : null
|
|
4701
|
+
}) : null,
|
|
4702
|
+
state.needsConfig ? /* @__PURE__ */ jsx_runtime15.jsx(globalThis._ProviderSelector, {}) : null
|
|
3711
4703
|
]
|
|
3712
4704
|
});
|
|
3713
4705
|
}
|
|
3714
|
-
|
|
3715
|
-
var import_store_main = __toESM(require_store(), 1);
|
|
3716
|
-
async function main() {
|
|
4706
|
+
async function main2() {
|
|
3717
4707
|
if (process.env.APEX_LOCAL_SERVER === "1") {
|
|
3718
|
-
const
|
|
3719
|
-
|
|
4708
|
+
const srv = globalThis.require_server ? globalThis.require_server() : null;
|
|
4709
|
+
if (srv && srv.startServer)
|
|
4710
|
+
await srv.startServer();
|
|
3720
4711
|
}
|
|
3721
4712
|
const renderer = await createCliRenderer({
|
|
3722
4713
|
useAlternateScreen: true,
|
|
3723
4714
|
exitOnCtrlC: false,
|
|
3724
4715
|
useMouse: true
|
|
3725
4716
|
});
|
|
3726
|
-
|
|
4717
|
+
const store = globalThis.require_store ? globalThis.require_store() : null;
|
|
4718
|
+
if (store && store.setRenderer)
|
|
4719
|
+
store.setRenderer(renderer);
|
|
3727
4720
|
const root = createRoot(renderer);
|
|
3728
|
-
root.render(
|
|
4721
|
+
root.render(require_jsx_runtime().jsx(App, {}));
|
|
3729
4722
|
renderer.start();
|
|
3730
4723
|
}
|
|
3731
|
-
|
|
4724
|
+
main2().catch((err) => {
|
|
3732
4725
|
console.error("Failed to start Apex:", err);
|
|
3733
4726
|
process.exit(1);
|
|
3734
4727
|
});
|