bravecode-cli 0.1.53 → 0.1.55
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/dist/cli-main.mjs +128 -65
- package/dist/cli-main.mjs.map +3 -3
- package/package.json +1 -1
package/dist/cli-main.mjs
CHANGED
|
@@ -16212,14 +16212,14 @@ async function delay(delayInMs, options2) {
|
|
|
16212
16212
|
return Promise.resolve();
|
|
16213
16213
|
}
|
|
16214
16214
|
const signal = options2 == null ? void 0 : options2.abortSignal;
|
|
16215
|
-
return new Promise((
|
|
16215
|
+
return new Promise((resolve22, reject) => {
|
|
16216
16216
|
if (signal == null ? void 0 : signal.aborted) {
|
|
16217
16217
|
reject(createAbortError());
|
|
16218
16218
|
return;
|
|
16219
16219
|
}
|
|
16220
16220
|
const timeoutId = setTimeout(() => {
|
|
16221
16221
|
cleanup();
|
|
16222
|
-
|
|
16222
|
+
resolve22();
|
|
16223
16223
|
}, delayInMs);
|
|
16224
16224
|
const cleanup = () => {
|
|
16225
16225
|
clearTimeout(timeoutId);
|
|
@@ -18526,13 +18526,13 @@ var init_dist4 = __esm({
|
|
|
18526
18526
|
if (this._promise) {
|
|
18527
18527
|
return this._promise;
|
|
18528
18528
|
}
|
|
18529
|
-
this._promise = new Promise((
|
|
18529
|
+
this._promise = new Promise((resolve22, reject) => {
|
|
18530
18530
|
if (this.status.type === "resolved") {
|
|
18531
|
-
|
|
18531
|
+
resolve22(this.status.value);
|
|
18532
18532
|
} else if (this.status.type === "rejected") {
|
|
18533
18533
|
reject(this.status.error);
|
|
18534
18534
|
}
|
|
18535
|
-
this._resolve =
|
|
18535
|
+
this._resolve = resolve22;
|
|
18536
18536
|
this._reject = reject;
|
|
18537
18537
|
});
|
|
18538
18538
|
return this._promise;
|
|
@@ -19795,19 +19795,19 @@ var require_token_io = __commonJS({
|
|
|
19795
19795
|
getUserDataDir: () => getUserDataDir
|
|
19796
19796
|
});
|
|
19797
19797
|
module.exports = __toCommonJS(token_io_exports);
|
|
19798
|
-
var
|
|
19798
|
+
var import_path9 = __toESM2(__require("path"));
|
|
19799
19799
|
var import_fs10 = __toESM2(__require("fs"));
|
|
19800
19800
|
var import_os4 = __toESM2(__require("os"));
|
|
19801
19801
|
var import_token_error = require_token_error();
|
|
19802
19802
|
function findRootDir() {
|
|
19803
19803
|
try {
|
|
19804
19804
|
let dir = process.cwd();
|
|
19805
|
-
while (dir !==
|
|
19806
|
-
const pkgPath =
|
|
19805
|
+
while (dir !== import_path9.default.dirname(dir)) {
|
|
19806
|
+
const pkgPath = import_path9.default.join(dir, ".vercel");
|
|
19807
19807
|
if (import_fs10.default.existsSync(pkgPath)) {
|
|
19808
19808
|
return dir;
|
|
19809
19809
|
}
|
|
19810
|
-
dir =
|
|
19810
|
+
dir = import_path9.default.dirname(dir);
|
|
19811
19811
|
}
|
|
19812
19812
|
} catch (e) {
|
|
19813
19813
|
throw new import_token_error.VercelOidcTokenError(
|
|
@@ -19822,9 +19822,9 @@ var require_token_io = __commonJS({
|
|
|
19822
19822
|
}
|
|
19823
19823
|
switch (import_os4.default.platform()) {
|
|
19824
19824
|
case "darwin":
|
|
19825
|
-
return
|
|
19825
|
+
return import_path9.default.join(import_os4.default.homedir(), "Library/Application Support");
|
|
19826
19826
|
case "linux":
|
|
19827
|
-
return
|
|
19827
|
+
return import_path9.default.join(import_os4.default.homedir(), ".local/share");
|
|
19828
19828
|
case "win32":
|
|
19829
19829
|
if (process.env.LOCALAPPDATA) {
|
|
19830
19830
|
return process.env.LOCALAPPDATA;
|
|
@@ -37678,7 +37678,7 @@ ${instructions}` : instructions;
|
|
|
37678
37678
|
lastError = error40;
|
|
37679
37679
|
logError(`BraveCode stream error (attempt ${attempt + 1}/${maxRetries + 1}):`, error40.message);
|
|
37680
37680
|
if (attempt < maxRetries) {
|
|
37681
|
-
await new Promise((
|
|
37681
|
+
await new Promise((resolve3) => setTimeout(resolve3, 1e3 * (attempt + 1)));
|
|
37682
37682
|
continue;
|
|
37683
37683
|
}
|
|
37684
37684
|
}
|
|
@@ -37760,28 +37760,30 @@ ${error40.stderr || ""}`;
|
|
|
37760
37760
|
});
|
|
37761
37761
|
|
|
37762
37762
|
// src/core/tool/file.ts
|
|
37763
|
-
import { readFileSync, writeFileSync, existsSync } from "fs";
|
|
37763
|
+
import { readFileSync, writeFileSync, existsSync, mkdirSync } from "fs";
|
|
37764
|
+
import { dirname, isAbsolute, resolve as resolve2 } from "path";
|
|
37764
37765
|
var readTool, writeTool, editTool;
|
|
37765
37766
|
var init_file = __esm({
|
|
37766
37767
|
"src/core/tool/file.ts"() {
|
|
37767
37768
|
"use strict";
|
|
37768
37769
|
readTool = {
|
|
37769
37770
|
name: "read",
|
|
37770
|
-
description: "Read a file from the local filesystem.",
|
|
37771
|
+
description: "Read a file from the local filesystem. Accepts absolute or relative paths (relative to the current working directory).",
|
|
37771
37772
|
parameters: {
|
|
37772
37773
|
type: "object",
|
|
37773
37774
|
properties: {
|
|
37774
|
-
filePath: { type: "string", description: "The
|
|
37775
|
+
filePath: { type: "string", description: "The path to the file (absolute or relative)" }
|
|
37775
37776
|
},
|
|
37776
37777
|
required: ["filePath"]
|
|
37777
37778
|
},
|
|
37778
37779
|
async execute(input) {
|
|
37779
37780
|
const { filePath } = input;
|
|
37780
|
-
|
|
37781
|
-
|
|
37781
|
+
const absPath = isAbsolute(filePath) ? filePath : resolve2(process.cwd(), filePath);
|
|
37782
|
+
if (!existsSync(absPath)) {
|
|
37783
|
+
return `Error: File not found: ${absPath}`;
|
|
37782
37784
|
}
|
|
37783
37785
|
try {
|
|
37784
|
-
const content = readFileSync(
|
|
37786
|
+
const content = readFileSync(absPath, "utf-8");
|
|
37785
37787
|
return content;
|
|
37786
37788
|
} catch (error40) {
|
|
37787
37789
|
return `Error reading file: ${error40.message}`;
|
|
@@ -37790,20 +37792,22 @@ var init_file = __esm({
|
|
|
37790
37792
|
};
|
|
37791
37793
|
writeTool = {
|
|
37792
37794
|
name: "write",
|
|
37793
|
-
description: "Write a file to the local filesystem.",
|
|
37795
|
+
description: "Write a file to the local filesystem. Accepts absolute or relative paths (relative to the current working directory). Creates parent directories automatically if they don't exist.",
|
|
37794
37796
|
parameters: {
|
|
37795
37797
|
type: "object",
|
|
37796
37798
|
properties: {
|
|
37797
|
-
filePath: { type: "string", description: "The absolute
|
|
37799
|
+
filePath: { type: "string", description: "The path to the file (absolute or relative to the current working directory)" },
|
|
37798
37800
|
content: { type: "string", description: "The content to write" }
|
|
37799
37801
|
},
|
|
37800
37802
|
required: ["filePath", "content"]
|
|
37801
37803
|
},
|
|
37802
37804
|
async execute(input) {
|
|
37803
37805
|
const { filePath, content } = input;
|
|
37806
|
+
const absPath = isAbsolute(filePath) ? filePath : resolve2(process.cwd(), filePath);
|
|
37804
37807
|
try {
|
|
37805
|
-
|
|
37806
|
-
|
|
37808
|
+
mkdirSync(dirname(absPath), { recursive: true });
|
|
37809
|
+
writeFileSync(absPath, content, "utf-8");
|
|
37810
|
+
return `File written successfully: ${absPath}`;
|
|
37807
37811
|
} catch (error40) {
|
|
37808
37812
|
return `Error writing file: ${error40.message}`;
|
|
37809
37813
|
}
|
|
@@ -37811,11 +37815,11 @@ var init_file = __esm({
|
|
|
37811
37815
|
};
|
|
37812
37816
|
editTool = {
|
|
37813
37817
|
name: "edit",
|
|
37814
|
-
description: "Perform exact string replacements in files.",
|
|
37818
|
+
description: "Perform exact string replacements in files. Accepts absolute or relative paths (relative to the current working directory).",
|
|
37815
37819
|
parameters: {
|
|
37816
37820
|
type: "object",
|
|
37817
37821
|
properties: {
|
|
37818
|
-
filePath: { type: "string", description: "The absolute
|
|
37822
|
+
filePath: { type: "string", description: "The path to the file (absolute or relative to the current working directory)" },
|
|
37819
37823
|
oldString: { type: "string", description: "Text to find" },
|
|
37820
37824
|
newString: { type: "string", description: "Replacement text" }
|
|
37821
37825
|
},
|
|
@@ -37823,16 +37827,18 @@ var init_file = __esm({
|
|
|
37823
37827
|
},
|
|
37824
37828
|
async execute(input) {
|
|
37825
37829
|
const { filePath, oldString, newString } = input;
|
|
37826
|
-
|
|
37827
|
-
|
|
37830
|
+
const absPath = isAbsolute(filePath) ? filePath : resolve2(process.cwd(), filePath);
|
|
37831
|
+
if (!existsSync(absPath)) {
|
|
37832
|
+
return `Error: File not found: ${absPath}`;
|
|
37828
37833
|
}
|
|
37829
37834
|
try {
|
|
37830
|
-
const content = readFileSync(
|
|
37835
|
+
const content = readFileSync(absPath, "utf-8");
|
|
37831
37836
|
if (!content.includes(oldString)) {
|
|
37832
37837
|
return "Error: oldString not found in file.";
|
|
37833
37838
|
}
|
|
37834
37839
|
const updated = content.replace(oldString, newString);
|
|
37835
|
-
|
|
37840
|
+
mkdirSync(dirname(absPath), { recursive: true });
|
|
37841
|
+
writeFileSync(absPath, updated, "utf-8");
|
|
37836
37842
|
return "Edit applied successfully.";
|
|
37837
37843
|
} catch (error40) {
|
|
37838
37844
|
return `Error editing file: ${error40.message}`;
|
|
@@ -38280,7 +38286,7 @@ var APP_VERSION, APP_NAME;
|
|
|
38280
38286
|
var init_version = __esm({
|
|
38281
38287
|
"src/version.ts"() {
|
|
38282
38288
|
"use strict";
|
|
38283
|
-
APP_VERSION = "0.1.
|
|
38289
|
+
APP_VERSION = "0.1.55";
|
|
38284
38290
|
APP_NAME = "BraveCode";
|
|
38285
38291
|
}
|
|
38286
38292
|
});
|
|
@@ -38375,13 +38381,13 @@ var init_mcp = __esm({
|
|
|
38375
38381
|
}
|
|
38376
38382
|
}
|
|
38377
38383
|
sendRequest(method, params) {
|
|
38378
|
-
return new Promise((
|
|
38384
|
+
return new Promise((resolve3, reject) => {
|
|
38379
38385
|
if (!this.process?.stdin) {
|
|
38380
38386
|
reject(new Error("MCP server not running"));
|
|
38381
38387
|
return;
|
|
38382
38388
|
}
|
|
38383
38389
|
const id = ++this.requestId;
|
|
38384
|
-
this.pendingRequests.set(id, { resolve:
|
|
38390
|
+
this.pendingRequests.set(id, { resolve: resolve3, reject });
|
|
38385
38391
|
const message = JSON.stringify({
|
|
38386
38392
|
jsonrpc: "2.0",
|
|
38387
38393
|
id,
|
|
@@ -38404,12 +38410,12 @@ var init_mcp = __esm({
|
|
|
38404
38410
|
try {
|
|
38405
38411
|
const message = JSON.parse(line);
|
|
38406
38412
|
if (message.id && this.pendingRequests.has(message.id)) {
|
|
38407
|
-
const { resolve:
|
|
38413
|
+
const { resolve: resolve3, reject } = this.pendingRequests.get(message.id);
|
|
38408
38414
|
this.pendingRequests.delete(message.id);
|
|
38409
38415
|
if (message.error) {
|
|
38410
38416
|
reject(new Error(message.error.message || "Unknown error"));
|
|
38411
38417
|
} else {
|
|
38412
|
-
|
|
38418
|
+
resolve3(message.result);
|
|
38413
38419
|
}
|
|
38414
38420
|
}
|
|
38415
38421
|
} catch {
|
|
@@ -40706,7 +40712,7 @@ var init_permission = __esm({
|
|
|
40706
40712
|
|
|
40707
40713
|
// src/core/snapshot/index.ts
|
|
40708
40714
|
import { execFileSync } from "child_process";
|
|
40709
|
-
import { existsSync as existsSync4, mkdirSync, writeFileSync as writeFileSync2, readFileSync as readFileSync4 } from "fs";
|
|
40715
|
+
import { existsSync as existsSync4, mkdirSync as mkdirSync2, writeFileSync as writeFileSync2, readFileSync as readFileSync4 } from "fs";
|
|
40710
40716
|
import { join as join3 } from "path";
|
|
40711
40717
|
function isRealCommitHash(hash) {
|
|
40712
40718
|
return hash !== "no-changes" && !hash.startsWith("fallback-");
|
|
@@ -40727,7 +40733,7 @@ var init_snapshot = __esm({
|
|
|
40727
40733
|
}
|
|
40728
40734
|
ensureSnapshotDir() {
|
|
40729
40735
|
if (!existsSync4(this.snapshotDir)) {
|
|
40730
|
-
|
|
40736
|
+
mkdirSync2(this.snapshotDir, { recursive: true });
|
|
40731
40737
|
}
|
|
40732
40738
|
}
|
|
40733
40739
|
loadSnapshots() {
|
|
@@ -41004,14 +41010,20 @@ var init_agent = __esm({
|
|
|
41004
41010
|
model: "codestral-latest",
|
|
41005
41011
|
systemPrompt: `You are BraveCode AI, an expert software engineer. You MUST use the provided tools to make file changes \u2014 do NOT narrate or describe actions in prose.
|
|
41006
41012
|
|
|
41007
|
-
When asked to
|
|
41008
|
-
1.
|
|
41009
|
-
2.
|
|
41010
|
-
3.
|
|
41013
|
+
When asked to build, scaffold, or modify a project:
|
|
41014
|
+
1. Create a dedicated project directory first (e.g. my-app/, snake-game/, website/). All files for the project go inside that directory.
|
|
41015
|
+
2. Organize the project with a proper structure (e.g. src/ for source, public/ for assets, components/ for UI components, styles/ for CSS, etc.).
|
|
41016
|
+
3. Use relative paths inside the project directory so the project is portable (e.g. my-app/src/index.tsx, not /full/system/path/my-app/src/index.tsx).
|
|
41017
|
+
4. Initialize the project with package.json, configuration files, and a README when appropriate.
|
|
41018
|
+
5. Install dependencies with a <run_command> block if needed.
|
|
41019
|
+
6. Verify the project structure with a <run_command>ls -la ...</run_command> at the end.
|
|
41011
41020
|
|
|
41012
|
-
|
|
41021
|
+
Tool call conventions \u2014 emit these blocks instead of writing code in prose:
|
|
41022
|
+
- <write_file path="relative/path">content</write_file> for creating files
|
|
41023
|
+
- <read_file path="relative/path"/> for reading files
|
|
41024
|
+
- <run_command>shell command</run_command> for executing commands
|
|
41013
41025
|
|
|
41014
|
-
|
|
41026
|
+
Every file MUST be created or modified via a tool call. Writing code blocks in your response without calling a tool does not create or modify any files.`,
|
|
41015
41027
|
temperature: 0.7,
|
|
41016
41028
|
maxIterations: 20
|
|
41017
41029
|
},
|
|
@@ -41253,12 +41265,14 @@ IMPORTANT: Only test APIs you have authorization to test. Never attempt to acces
|
|
|
41253
41265
|
* Last-resort extractor for tool calls that the provider's parser missed.
|
|
41254
41266
|
* Handles non-standard tag formats the model emits in plain text, e.g.
|
|
41255
41267
|
* <write_file path="...">...</write_file>, <read_file path="..."/>,
|
|
41256
|
-
* <run_command>cmd</run_command>, including
|
|
41268
|
+
* <run_command>cmd</run_command>, <todowrite>...</todowrite>, including
|
|
41269
|
+
* the HTML-entity-escaped form.
|
|
41257
41270
|
*/
|
|
41258
41271
|
extractNativeToolTags(text2) {
|
|
41259
41272
|
const decoded = text2.replace(/</g, "<").replace(/>/g, ">").replace(/&/g, "&").replace(/"/g, '"');
|
|
41260
41273
|
const calls = [];
|
|
41261
|
-
|
|
41274
|
+
let nextId2 = 0;
|
|
41275
|
+
const idSeq = () => `native_${Date.now().toString(36)}_${nextId2++}`;
|
|
41262
41276
|
const wfRe = /<write_file\s+path="([^"]+)">([\s\S]*?)<\/write_file>/g;
|
|
41263
41277
|
let m;
|
|
41264
41278
|
while ((m = wfRe.exec(decoded)) !== null) {
|
|
@@ -41272,7 +41286,20 @@ IMPORTANT: Only test APIs you have authorization to test. Never attempt to acces
|
|
|
41272
41286
|
while ((m = rcRe.exec(decoded)) !== null) {
|
|
41273
41287
|
calls.push({ id: idSeq(), name: "bash", arguments: { command: m[1].trim() } });
|
|
41274
41288
|
}
|
|
41275
|
-
|
|
41289
|
+
const todos = [];
|
|
41290
|
+
const todosBlock = decoded.match(/#\s*Todos\s*\n([\s\S]*?)(?:\n\s*\n|$)/i);
|
|
41291
|
+
if (todosBlock) {
|
|
41292
|
+
const todoRe = /^\s*\[([ xX•\u2022\u25CF\u25CB])\]\s+(.+)$/gm;
|
|
41293
|
+
let t;
|
|
41294
|
+
while ((t = todoRe.exec(todosBlock[1])) !== null) {
|
|
41295
|
+
const mark = t[1].toLowerCase();
|
|
41296
|
+
let status = "pending";
|
|
41297
|
+
if (mark === "x") status = "completed";
|
|
41298
|
+
else if (mark === "\u2022" || mark === "\u25C9" || mark === "o") status = "in_progress";
|
|
41299
|
+
todos.push({ id: idSeq(), content: t[2].trim(), status });
|
|
41300
|
+
}
|
|
41301
|
+
}
|
|
41302
|
+
return { toolCalls: calls, todos };
|
|
41276
41303
|
}
|
|
41277
41304
|
async run(userMessage, onChunk, signal, onToolCall) {
|
|
41278
41305
|
let message = userMessage;
|
|
@@ -41318,7 +41345,11 @@ IMPORTANT: Only test APIs you have authorization to test. Never attempt to acces
|
|
|
41318
41345
|
}
|
|
41319
41346
|
}
|
|
41320
41347
|
if (toolCalls.length === 0) {
|
|
41321
|
-
toolCalls = this.extractNativeToolTags(fullResponse);
|
|
41348
|
+
const { toolCalls: native, todos: nativeTodos } = this.extractNativeToolTags(fullResponse);
|
|
41349
|
+
toolCalls = native;
|
|
41350
|
+
if (nativeTodos.length > 0) {
|
|
41351
|
+
this._lastTodos = nativeTodos;
|
|
41352
|
+
}
|
|
41322
41353
|
}
|
|
41323
41354
|
} else {
|
|
41324
41355
|
const result = await this.provider.chat({
|
|
@@ -41413,7 +41444,7 @@ IMPORTANT: Only test APIs you have authorization to test. Never attempt to acces
|
|
|
41413
41444
|
});
|
|
41414
41445
|
|
|
41415
41446
|
// src/core/config/index.ts
|
|
41416
|
-
import { existsSync as existsSync5, readFileSync as readFileSync5, writeFileSync as writeFileSync3, mkdirSync as
|
|
41447
|
+
import { existsSync as existsSync5, readFileSync as readFileSync5, writeFileSync as writeFileSync3, mkdirSync as mkdirSync3 } from "fs";
|
|
41417
41448
|
import { join as join4 } from "path";
|
|
41418
41449
|
import { homedir } from "os";
|
|
41419
41450
|
function getConfig() {
|
|
@@ -41470,7 +41501,7 @@ var init_config = __esm({
|
|
|
41470
41501
|
}
|
|
41471
41502
|
loadConfig() {
|
|
41472
41503
|
if (!existsSync5(this.configDir)) {
|
|
41473
|
-
|
|
41504
|
+
mkdirSync3(this.configDir, { recursive: true });
|
|
41474
41505
|
}
|
|
41475
41506
|
if (existsSync5(this.configFile)) {
|
|
41476
41507
|
try {
|
|
@@ -41554,7 +41585,7 @@ var init_config = __esm({
|
|
|
41554
41585
|
});
|
|
41555
41586
|
|
|
41556
41587
|
// src/core/share/index.ts
|
|
41557
|
-
import { readFileSync as readFileSync6, writeFileSync as writeFileSync4, existsSync as existsSync6, mkdirSync as
|
|
41588
|
+
import { readFileSync as readFileSync6, writeFileSync as writeFileSync4, existsSync as existsSync6, mkdirSync as mkdirSync4, readdirSync as readdirSync3, unlinkSync } from "fs";
|
|
41558
41589
|
import { join as join5 } from "path";
|
|
41559
41590
|
import { homedir as homedir2 } from "os";
|
|
41560
41591
|
import { randomBytes } from "crypto";
|
|
@@ -41570,7 +41601,7 @@ var init_share = __esm({
|
|
|
41570
41601
|
}
|
|
41571
41602
|
ensureShareDir() {
|
|
41572
41603
|
if (!existsSync6(this.shareDir)) {
|
|
41573
|
-
|
|
41604
|
+
mkdirSync4(this.shareDir, { recursive: true });
|
|
41574
41605
|
}
|
|
41575
41606
|
}
|
|
41576
41607
|
createShare(title, messages, options2 = {}) {
|
|
@@ -41654,7 +41685,7 @@ var init_share = __esm({
|
|
|
41654
41685
|
|
|
41655
41686
|
// src/core/update/index.ts
|
|
41656
41687
|
import { execSync as execSync3 } from "child_process";
|
|
41657
|
-
import { readFileSync as readFileSync7, writeFileSync as writeFileSync5, existsSync as existsSync7, mkdirSync as
|
|
41688
|
+
import { readFileSync as readFileSync7, writeFileSync as writeFileSync5, existsSync as existsSync7, mkdirSync as mkdirSync5 } from "fs";
|
|
41658
41689
|
import { join as join6 } from "path";
|
|
41659
41690
|
import { homedir as homedir3 } from "os";
|
|
41660
41691
|
var PACKAGE_NAME, CURRENT_VERSION, UPDATE_CHECK_INTERVAL, UpdateChecker;
|
|
@@ -41675,7 +41706,7 @@ var init_update = __esm({
|
|
|
41675
41706
|
}
|
|
41676
41707
|
ensureConfigDir() {
|
|
41677
41708
|
if (!existsSync7(this.configDir)) {
|
|
41678
|
-
|
|
41709
|
+
mkdirSync5(this.configDir, { recursive: true });
|
|
41679
41710
|
}
|
|
41680
41711
|
}
|
|
41681
41712
|
getLastCheckTime() {
|
|
@@ -41921,7 +41952,17 @@ function useToast() {
|
|
|
41921
41952
|
if (!ctx) throw new Error("useToast must be inside ToastProvider");
|
|
41922
41953
|
return ctx;
|
|
41923
41954
|
}
|
|
41924
|
-
|
|
41955
|
+
function TodoProvider({ children }) {
|
|
41956
|
+
const [todos, setTodos] = React2.useState([]);
|
|
41957
|
+
const value = React2.useMemo(() => ({ todos, setTodos }), [todos]);
|
|
41958
|
+
return React2.createElement(TodoContext.Provider, { value }, children);
|
|
41959
|
+
}
|
|
41960
|
+
function useTodos() {
|
|
41961
|
+
const ctx = React2.useContext(TodoContext);
|
|
41962
|
+
if (!ctx) throw new Error("useTodos must be inside TodoProvider");
|
|
41963
|
+
return ctx;
|
|
41964
|
+
}
|
|
41965
|
+
var SessionContext, msgIdCounter, nextId, AgentContext, DialogContext, ToastContext, toastCounter, TodoContext;
|
|
41925
41966
|
var init_providers = __esm({
|
|
41926
41967
|
"src/core/tui/context/providers.tsx"() {
|
|
41927
41968
|
"use strict";
|
|
@@ -41933,6 +41974,7 @@ var init_providers = __esm({
|
|
|
41933
41974
|
DialogContext = React2.createContext(null);
|
|
41934
41975
|
ToastContext = React2.createContext(null);
|
|
41935
41976
|
toastCounter = 0;
|
|
41977
|
+
TodoContext = React2.createContext(null);
|
|
41936
41978
|
}
|
|
41937
41979
|
});
|
|
41938
41980
|
|
|
@@ -41942,9 +41984,11 @@ function useAgentRunner() {
|
|
|
41942
41984
|
const { addMessage, updateMessage, addToolCall, messages } = useSession();
|
|
41943
41985
|
const { currentAgent, currentModel, setRunning } = useAgent();
|
|
41944
41986
|
const toast = useToast();
|
|
41987
|
+
const { setTodos } = useTodos();
|
|
41945
41988
|
const agentRef = React3.useRef(null);
|
|
41946
41989
|
const abortRef = React3.useRef(null);
|
|
41947
41990
|
const sendMessage = React3.useCallback(async (content) => {
|
|
41991
|
+
setTodos([]);
|
|
41948
41992
|
const userMsg = addMessage({
|
|
41949
41993
|
role: "user",
|
|
41950
41994
|
content,
|
|
@@ -41998,6 +42042,10 @@ function useAgentRunner() {
|
|
|
41998
42042
|
}
|
|
41999
42043
|
);
|
|
42000
42044
|
updateMessage(assistantMsg.id, { content: fullContent });
|
|
42045
|
+
const extractedTodos = agentRef.current?._lastTodos;
|
|
42046
|
+
if (extractedTodos && extractedTodos.length > 0) {
|
|
42047
|
+
setTodos(extractedTodos);
|
|
42048
|
+
}
|
|
42001
42049
|
} catch (err) {
|
|
42002
42050
|
const e = err;
|
|
42003
42051
|
if (e?.name === "AbortError" || e?.message?.includes("abort")) {
|
|
@@ -42035,6 +42083,7 @@ var init_use_agent_runner = __esm({
|
|
|
42035
42083
|
init_providers();
|
|
42036
42084
|
init_providers();
|
|
42037
42085
|
init_providers();
|
|
42086
|
+
init_providers();
|
|
42038
42087
|
}
|
|
42039
42088
|
});
|
|
42040
42089
|
|
|
@@ -44309,8 +44358,16 @@ function PixelLogo() {
|
|
|
44309
44358
|
function Sidebar({ compact = false }) {
|
|
44310
44359
|
const { colors: colors2 } = useTheme();
|
|
44311
44360
|
const { currentAgent, currentModel } = useAgent();
|
|
44361
|
+
const { todos } = useTodos();
|
|
44312
44362
|
const cwd = process.cwd().replace(process.env.HOME ?? "", "~");
|
|
44313
44363
|
const sessionTime = (/* @__PURE__ */ new Date()).toISOString().replace(/\.\d+Z$/, "Z").replace("T", "").slice(0, 19) + "Z";
|
|
44364
|
+
const todoPanel = todos.length > 0 ? /* @__PURE__ */ jsxs("box", { style: { flexDirection: "column", marginTop: 1 }, children: [
|
|
44365
|
+
/* @__PURE__ */ jsx("text", { fg: colors2.text, children: /* @__PURE__ */ jsx("b", { children: "\u25BC Todo" }) }),
|
|
44366
|
+
/* @__PURE__ */ jsx("box", { style: { flexDirection: "column" }, children: todos.map((t) => /* @__PURE__ */ jsxs("box", { style: { flexDirection: "row" }, children: [
|
|
44367
|
+
/* @__PURE__ */ jsx("text", { fg: t.status === "completed" ? colors2.success : t.status === "in_progress" ? colors2.warning : colors2.textMuted, children: t.status === "completed" ? "[\u2713] " : t.status === "in_progress" ? "[\u2022] " : "[ ] " }),
|
|
44368
|
+
/* @__PURE__ */ jsx("text", { fg: t.status === "completed" ? colors2.textMuted : t.status === "in_progress" ? colors2.warning : colors2.text, children: s(t.content) })
|
|
44369
|
+
] }, t.id)) })
|
|
44370
|
+
] }) : null;
|
|
44314
44371
|
if (compact) {
|
|
44315
44372
|
return /* @__PURE__ */ jsxs(
|
|
44316
44373
|
"box",
|
|
@@ -44338,6 +44395,7 @@ function Sidebar({ compact = false }) {
|
|
|
44338
44395
|
/* @__PURE__ */ jsx("text", { fg: colors2.success, children: "\u25CF" }),
|
|
44339
44396
|
/* @__PURE__ */ jsx("text", { fg: colors2.textMuted, children: " mcp connected" })
|
|
44340
44397
|
] }),
|
|
44398
|
+
todoPanel,
|
|
44341
44399
|
/* @__PURE__ */ jsx("box", { style: { flexGrow: 1 } }),
|
|
44342
44400
|
/* @__PURE__ */ jsx("box", { style: { marginTop: 1 }, children: /* @__PURE__ */ jsx("text", { fg: colors2.textMuted, children: s(APP_VERSION) }) }),
|
|
44343
44401
|
/* @__PURE__ */ jsx("text", { fg: colors2.textMuted, children: "ctrl+b sidebar" })
|
|
@@ -44375,6 +44433,7 @@ function Sidebar({ compact = false }) {
|
|
|
44375
44433
|
] }),
|
|
44376
44434
|
/* @__PURE__ */ jsx("box", { style: { marginTop: 1 }, children: /* @__PURE__ */ jsx("text", { fg: colors2.text, children: /* @__PURE__ */ jsx("b", { children: "LSP" }) }) }),
|
|
44377
44435
|
/* @__PURE__ */ jsx("text", { fg: colors2.textMuted, children: "LSPs are disabled" }),
|
|
44436
|
+
todoPanel,
|
|
44378
44437
|
/* @__PURE__ */ jsx("box", { style: { flexGrow: 1 } }),
|
|
44379
44438
|
/* @__PURE__ */ jsx("box", { style: { marginTop: 1 }, children: /* @__PURE__ */ jsx("text", { fg: colors2.textMuted, children: s(cwd) }) }),
|
|
44380
44439
|
/* @__PURE__ */ jsxs("box", { children: [
|
|
@@ -45089,7 +45148,7 @@ import { createCliRenderer, setRenderLibPath } from "@opentui/core";
|
|
|
45089
45148
|
import { createRoot as createReactRoot } from "@opentui/react";
|
|
45090
45149
|
import { existsSync as existsSync8 } from "node:fs";
|
|
45091
45150
|
import { createRequire } from "node:module";
|
|
45092
|
-
import { dirname, join as join7 } from "node:path";
|
|
45151
|
+
import { dirname as dirname2, join as join7 } from "node:path";
|
|
45093
45152
|
import { fileURLToPath } from "node:url";
|
|
45094
45153
|
function getCurrentTarget() {
|
|
45095
45154
|
const p = process.platform;
|
|
@@ -45123,15 +45182,15 @@ function resolveNativeLibViaRequire(pkgName, libFile) {
|
|
|
45123
45182
|
let pkgDir = null;
|
|
45124
45183
|
try {
|
|
45125
45184
|
const resolved = req.resolve(pkgName);
|
|
45126
|
-
pkgDir =
|
|
45185
|
+
pkgDir = dirname2(resolved);
|
|
45127
45186
|
} catch {
|
|
45128
45187
|
try {
|
|
45129
45188
|
const url2 = import.meta.resolve(pkgName + "/index.js");
|
|
45130
|
-
pkgDir =
|
|
45189
|
+
pkgDir = dirname2(fileURLToPath(url2));
|
|
45131
45190
|
} catch {
|
|
45132
45191
|
try {
|
|
45133
45192
|
const url2 = import.meta.resolve(pkgName);
|
|
45134
|
-
pkgDir =
|
|
45193
|
+
pkgDir = dirname2(fileURLToPath(url2));
|
|
45135
45194
|
} catch {
|
|
45136
45195
|
}
|
|
45137
45196
|
}
|
|
@@ -45139,7 +45198,7 @@ function resolveNativeLibViaRequire(pkgName, libFile) {
|
|
|
45139
45198
|
if (pkgDir) {
|
|
45140
45199
|
const candidate = join7(pkgDir, libFile);
|
|
45141
45200
|
if (existsSync8(candidate)) return candidate;
|
|
45142
|
-
const parentCandidate = join7(
|
|
45201
|
+
const parentCandidate = join7(dirname2(pkgDir), libFile);
|
|
45143
45202
|
if (existsSync8(parentCandidate)) return parentCandidate;
|
|
45144
45203
|
}
|
|
45145
45204
|
return null;
|
|
@@ -45151,26 +45210,26 @@ function resolveNativeLibViaSearch(libFile) {
|
|
|
45151
45210
|
const searchBases = [];
|
|
45152
45211
|
try {
|
|
45153
45212
|
const req = createRequire(import.meta.url);
|
|
45154
|
-
searchBases.push(
|
|
45213
|
+
searchBases.push(dirname2(req.resolve("@opentui/core/package.json")));
|
|
45155
45214
|
} catch {
|
|
45156
45215
|
}
|
|
45157
45216
|
searchBases.push(join7(process.cwd(), "node_modules", "@opentui", "core"));
|
|
45158
45217
|
try {
|
|
45159
|
-
searchBases.push(
|
|
45218
|
+
searchBases.push(dirname2(fileURLToPath(import.meta.url)));
|
|
45160
45219
|
} catch {
|
|
45161
45220
|
}
|
|
45162
45221
|
const dedupedBases = [...new Set(searchBases.filter(Boolean))];
|
|
45163
45222
|
for (const coreBase of dedupedBases) {
|
|
45164
|
-
const nmDir = join7(
|
|
45223
|
+
const nmDir = join7(dirname2(coreBase), "..");
|
|
45165
45224
|
for (const target of buildSearchTargets()) {
|
|
45166
45225
|
const nmPath = join7(nmDir, makePackageName(target), libFile);
|
|
45167
45226
|
if (existsSync8(nmPath)) return nmPath;
|
|
45168
|
-
const siblingPath = join7(
|
|
45227
|
+
const siblingPath = join7(dirname2(coreBase), makePackageName(target), libFile);
|
|
45169
45228
|
if (existsSync8(siblingPath)) return siblingPath;
|
|
45170
45229
|
}
|
|
45171
45230
|
}
|
|
45172
45231
|
try {
|
|
45173
|
-
const execDir =
|
|
45232
|
+
const execDir = dirname2(process.execPath);
|
|
45174
45233
|
for (const target of buildSearchTargets()) {
|
|
45175
45234
|
const candidate = join7(execDir, "..", "lib", "node_modules", "bravecode-cli", "node_modules", makePackageName(target), libFile);
|
|
45176
45235
|
if (existsSync8(candidate)) return candidate;
|
|
@@ -45261,15 +45320,19 @@ var init_tui = __esm({
|
|
|
45261
45320
|
React5.createElement(
|
|
45262
45321
|
ToastProvider,
|
|
45263
45322
|
null,
|
|
45264
|
-
React5.createElement(
|
|
45323
|
+
React5.createElement(
|
|
45324
|
+
TodoProvider,
|
|
45325
|
+
null,
|
|
45326
|
+
React5.createElement(App, null)
|
|
45327
|
+
)
|
|
45265
45328
|
)
|
|
45266
45329
|
)
|
|
45267
45330
|
)
|
|
45268
45331
|
)
|
|
45269
45332
|
);
|
|
45270
45333
|
root.render(tree);
|
|
45271
|
-
shutdownPromise = new Promise((
|
|
45272
|
-
const tryResolve = () =>
|
|
45334
|
+
shutdownPromise = new Promise((resolve3) => {
|
|
45335
|
+
const tryResolve = () => resolve3();
|
|
45273
45336
|
process.once("SIGINT", tryResolve);
|
|
45274
45337
|
process.once("SIGTERM", tryResolve);
|
|
45275
45338
|
});
|