@8gi-foundation/8gent-code 0.20.15 → 0.20.16
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/CHANGELOG.md +9 -0
- package/README.md +1 -1
- package/dist/cli.js +182 -109
- package/dist/node/cli.js +182 -109
- package/dist/node/tui.js +567 -452
- package/dist/tui.js +567 -452
- package/package.json +1 -1
package/dist/tui.js
CHANGED
|
@@ -18697,8 +18697,6 @@ var init_allowlist = __esm(() => {
|
|
|
18697
18697
|
"node",
|
|
18698
18698
|
"npm",
|
|
18699
18699
|
"npx",
|
|
18700
|
-
"pnpm",
|
|
18701
|
-
"yarn",
|
|
18702
18700
|
"deno",
|
|
18703
18701
|
"python",
|
|
18704
18702
|
"python3",
|
|
@@ -18706,9 +18704,6 @@ var init_allowlist = __esm(() => {
|
|
|
18706
18704
|
"pip3",
|
|
18707
18705
|
"uv",
|
|
18708
18706
|
"git",
|
|
18709
|
-
"go",
|
|
18710
|
-
"cargo",
|
|
18711
|
-
"rustc",
|
|
18712
18707
|
"tsc",
|
|
18713
18708
|
"gh",
|
|
18714
18709
|
"docker",
|
|
@@ -18733,20 +18728,18 @@ var init_allowlist = __esm(() => {
|
|
|
18733
18728
|
"biome",
|
|
18734
18729
|
"eslint",
|
|
18735
18730
|
"prettier",
|
|
18736
|
-
"vite"
|
|
18731
|
+
"vite",
|
|
18732
|
+
"8gent"
|
|
18737
18733
|
]);
|
|
18738
18734
|
SHORT_VERSION = {
|
|
18739
18735
|
node: "-v",
|
|
18740
18736
|
bun: "-v",
|
|
18741
18737
|
npm: "-v",
|
|
18742
|
-
pnpm: "-v",
|
|
18743
|
-
yarn: "-v",
|
|
18744
18738
|
deno: "-V",
|
|
18745
18739
|
python: "-V",
|
|
18746
18740
|
python3: "-V",
|
|
18747
18741
|
ffmpeg: "-version",
|
|
18748
|
-
ffprobe: "-version"
|
|
18749
|
-
go: "version"
|
|
18742
|
+
ffprobe: "-version"
|
|
18750
18743
|
};
|
|
18751
18744
|
SECRET_ARG = /(^|\/)\.env(\.[\w.-]+)?$|(^|\/)\.env\b|id_rsa|id_ed25519|id_ecdsa|(^|\/)\.ssh(\/|$)|\.aws\/|credentials|\.netrc|\.npmrc|\.git-credentials|keychain|\.pem$|\.key$|\.p12$/;
|
|
18752
18745
|
REDIR_RE2 = /(?<![<>&\d])(\d?|&)(>>?|<)(\|?)\s*(&\d+|[^\s;|&<>()]+)/g;
|
|
@@ -29981,7 +29974,7 @@ var init_permissions = __esm(() => {
|
|
|
29981
29974
|
var require_package = __commonJS(function(exports2, module2) {
|
|
29982
29975
|
module2.exports = {
|
|
29983
29976
|
name: "@8gi-foundation/8gent-code",
|
|
29984
|
-
version: "0.20.
|
|
29977
|
+
version: "0.20.16",
|
|
29985
29978
|
private: false,
|
|
29986
29979
|
engines: {
|
|
29987
29980
|
node: ">=22.5"
|
|
@@ -74427,8 +74420,31 @@ function emptyReplyStall(toolCalls) {
|
|
|
74427
74420
|
function isEmptyReplyStall(line) {
|
|
74428
74421
|
return line.startsWith(EMPTY_REPLY_STALL_PREFIX);
|
|
74429
74422
|
}
|
|
74430
|
-
function
|
|
74431
|
-
|
|
74423
|
+
function refusedCalls(log, max = 3) {
|
|
74424
|
+
const out = [];
|
|
74425
|
+
let total = 0;
|
|
74426
|
+
for (const e of log) {
|
|
74427
|
+
const m = /^\[[^\]]*\b(?:BLOCKED|DENIED)\b[^\]]*\]\s*([^\n]*)/.exec((e.result ?? "").trimStart());
|
|
74428
|
+
if (!m)
|
|
74429
|
+
continue;
|
|
74430
|
+
total++;
|
|
74431
|
+
if (out.length >= max)
|
|
74432
|
+
continue;
|
|
74433
|
+
const a = e.args;
|
|
74434
|
+
const first = typeof a?.command === "string" ? a.command.trim().split(/\s+/)[0] ?? "" : "";
|
|
74435
|
+
const bin = /^[A-Za-z][\w.+-]{0,40}$/.test(first) ? ` ${first}` : "";
|
|
74436
|
+
const why = /declin/i.test(m[1]) ? "declined" : "blocked by policy";
|
|
74437
|
+
out.push(`${e.name}${bin}: ${why}`);
|
|
74438
|
+
}
|
|
74439
|
+
return { total, shown: out };
|
|
74440
|
+
}
|
|
74441
|
+
function emptyReplyNote(toolCalls, log = []) {
|
|
74442
|
+
const base = `[harness] No reply: ${emptyReplyStall(toolCalls)}.`;
|
|
74443
|
+
const { total, shown } = refusedCalls(log);
|
|
74444
|
+
if (total === 0)
|
|
74445
|
+
return base;
|
|
74446
|
+
const more = total > shown.length ? ` (and ${total - shown.length} more)` : "";
|
|
74447
|
+
return `${base} ${total} of the calls were refused, so they did not run: ${shown.join("; ")}${more}.`;
|
|
74432
74448
|
}
|
|
74433
74449
|
function isEmptyReplyNote(reply) {
|
|
74434
74450
|
return reply.startsWith("[harness] No reply:");
|
|
@@ -74521,7 +74537,7 @@ ${summary}`;
|
|
|
74521
74537
|
if (unverified.length === 0)
|
|
74522
74538
|
return { content, rounds, toolLog, unverified: [] };
|
|
74523
74539
|
const notes = [
|
|
74524
|
-
empty ? emptyReplyNote(toolLog.length) : content.trimEnd(),
|
|
74540
|
+
empty ? emptyReplyNote(toolLog.length, toolLog) : content.trimEnd(),
|
|
74525
74541
|
unfulfilled.length > 0 ? formatHarnessNote(unfulfilled) : ""
|
|
74526
74542
|
].filter((n) => n.trim() !== "");
|
|
74527
74543
|
return { content: notes.join(`
|
|
@@ -557382,6 +557398,44 @@ var init_registry = __esm(() => {
|
|
|
557382
557398
|
];
|
|
557383
557399
|
});
|
|
557384
557400
|
|
|
557401
|
+
// packages/eight/small-talk.ts
|
|
557402
|
+
function isSmallTalk(text) {
|
|
557403
|
+
const flat = text.toLowerCase().replace(/^\[mode: [^\]]*\]\s*/, "").replace(/['\u2019]/g, "").replace(/[^a-z0-9 ]+/g, " ").replace(/\s+/g, " ").trim();
|
|
557404
|
+
return flat.length > 0 && flat.length <= 40 && GREETING.test(flat);
|
|
557405
|
+
}
|
|
557406
|
+
var CORE, GREETING, SMALL_TALK_NOTE = "[SMALL TALK] The person said hello and asked for nothing. Reply in one or two plain sentences and ask what they want to work on. No tools this turn: do not look around, list files or describe their folders.";
|
|
557407
|
+
var init_small_talk = __esm(() => {
|
|
557408
|
+
CORE = [
|
|
557409
|
+
"h+i+",
|
|
557410
|
+
"h+e+y+",
|
|
557411
|
+
"h+e+l+o+",
|
|
557412
|
+
"hiya",
|
|
557413
|
+
"howdy",
|
|
557414
|
+
"y+o+",
|
|
557415
|
+
"sup",
|
|
557416
|
+
"wa+s+s?u+p+",
|
|
557417
|
+
"w?h?a+t?s? ?u+p+",
|
|
557418
|
+
"good (?:morning|afternoon|evening|night)",
|
|
557419
|
+
"gm",
|
|
557420
|
+
"gn",
|
|
557421
|
+
"morning",
|
|
557422
|
+
"evening",
|
|
557423
|
+
"how are you(?: doing| today)?",
|
|
557424
|
+
"how are things",
|
|
557425
|
+
"hows it going",
|
|
557426
|
+
"how you doing",
|
|
557427
|
+
"you there",
|
|
557428
|
+
"anyone there",
|
|
557429
|
+
"ping",
|
|
557430
|
+
"thanks(?: a lot| so much)?",
|
|
557431
|
+
"thank you(?: so much)?",
|
|
557432
|
+
"thx",
|
|
557433
|
+
"ty",
|
|
557434
|
+
"cheers"
|
|
557435
|
+
].join("|");
|
|
557436
|
+
GREETING = new RegExp(`^(?:(?:hi+|hey+|hello+|yo+|hiya|howdy) )?(?:${CORE})(?: (?:there|again|everyone|all|team|mate|man|bro|friend|8gent|eight))?$`);
|
|
557437
|
+
});
|
|
557438
|
+
|
|
557385
557439
|
// packages/eight/verify-gate.ts
|
|
557386
557440
|
function isVerifyGateEnabled(env = process.env) {
|
|
557387
557441
|
const v = (env.EIGHT_VERIFY_GATE ?? "").trim().toLowerCase();
|
|
@@ -558312,8 +558366,8 @@ __export(exports_system_prompt, {
|
|
|
558312
558366
|
styleHasGuide: () => styleHasGuide,
|
|
558313
558367
|
workingProjectNote: () => workingProjectNote
|
|
558314
558368
|
});
|
|
558315
|
-
import { readFileSync as readFileSync96 } from "fs";
|
|
558316
|
-
import { basename as basename51, join as join154 } from "path";
|
|
558369
|
+
import { existsSync as existsSync105, readFileSync as readFileSync96 } from "fs";
|
|
558370
|
+
import { basename as basename51, join as join154, resolve as resolve73 } from "path";
|
|
558317
558371
|
function buildBoardContextSegment(path = BOARD_CONTEXT_PATH) {
|
|
558318
558372
|
let text;
|
|
558319
558373
|
try {
|
|
@@ -558344,8 +558398,20 @@ function communicationStyleLine(style) {
|
|
|
558344
558398
|
function styleHasGuide(style) {
|
|
558345
558399
|
return isCommunicationStyle(style) && STYLE_GUIDE[style] !== "";
|
|
558346
558400
|
}
|
|
558401
|
+
function isPlainHome(dir, home = resolveHome()) {
|
|
558402
|
+
try {
|
|
558403
|
+
return home !== "" && resolve73(dir) === resolve73(home) && !existsSync105(join154(dir, ".git"));
|
|
558404
|
+
} catch {
|
|
558405
|
+
return false;
|
|
558406
|
+
}
|
|
558407
|
+
}
|
|
558347
558408
|
function workingProjectNote(dir) {
|
|
558348
558409
|
const name = basename51(dir) || dir;
|
|
558410
|
+
if (isPlainHome(dir)) {
|
|
558411
|
+
return `
|
|
558412
|
+
|
|
558413
|
+
**Working folder: \`${dir}\` is the person's home folder, not a project. Do not list, search or summarise it unless they ask. Ask what they want to work on.**`;
|
|
558414
|
+
}
|
|
558349
558415
|
if (name === "8gent-code") {
|
|
558350
558416
|
return `
|
|
558351
558417
|
|
|
@@ -569507,14 +569573,15 @@ ${LOCAL_LOGIN_NOTE}`;
|
|
|
569507
569573
|
instructions,
|
|
569508
569574
|
localCoreTools,
|
|
569509
569575
|
chatStartTime,
|
|
569510
|
-
textForAgent
|
|
569576
|
+
textForAgent,
|
|
569577
|
+
smallTalk = false
|
|
569511
569578
|
} = opts;
|
|
569512
569579
|
const signal = this.armController().signal;
|
|
569513
569580
|
const allow = new Set(localCoreTools);
|
|
569514
569581
|
const specs = toolDefsToSpecs(this.executor.getToolDefinitions(), allow);
|
|
569515
569582
|
let stepNumber = 0;
|
|
569516
569583
|
let breakerStop = null;
|
|
569517
|
-
if (this.extensionToolsAllowed()) {
|
|
569584
|
+
if (this.extensionToolsAllowed() && !smallTalk) {
|
|
569518
569585
|
for (const t of this.extensionHost.listTools()) {
|
|
569519
569586
|
if (this.modeAllows(t.name)) {
|
|
569520
569587
|
specs.push({ name: t.name, description: t.description, parameters: t.parameters });
|
|
@@ -570092,6 +570159,10 @@ ${LOCAL_LOGIN_NOTE}`;
|
|
|
570092
570159
|
this.turnGitBaseline = asksForCommit(userMessage) ? gitSnapshot(this.config.workingDirectory || process.cwd()) : null;
|
|
570093
570160
|
this.executor.beginTurn(userMessage);
|
|
570094
570161
|
const textForAgent = userMessage.trim() || (imageBase64 ? "The user attached an image with no text. Describe what you see and help with anything relevant in the image." : userMessage);
|
|
570162
|
+
const smallTalkTurn = isSmallTalk(textForAgent) && !imageBase64 && this.config.agentScope !== "__table__";
|
|
570163
|
+
if (smallTalkTurn) {
|
|
570164
|
+
this.messageHistory.push({ role: "user", content: harnessNote(SMALL_TALK_NOTE) });
|
|
570165
|
+
}
|
|
570095
570166
|
let visionId = null;
|
|
570096
570167
|
let visionFailed = false;
|
|
570097
570168
|
if (imageBase64 && await this.promptImageSeen()) {
|
|
@@ -570162,7 +570233,7 @@ ${result.description.slice(0, 200)}${result.description.length > 200 ? "..." : "
|
|
|
570162
570233
|
}
|
|
570163
570234
|
}
|
|
570164
570235
|
const quickPrompt = quickLaneEnabled() && classifyPrompt(textForAgent) === "quick";
|
|
570165
|
-
if (needsClarification(textForAgent) && !imageBase64 && !quickPrompt && !isNoToolScope(this.config.agentScope)) {
|
|
570236
|
+
if (needsClarification(textForAgent) && !imageBase64 && !quickPrompt && !smallTalkTurn && !isNoToolScope(this.config.agentScope)) {
|
|
570166
570237
|
this.proactiveGatherer = createGatherer(textForAgent);
|
|
570167
570238
|
const question = this.proactiveGatherer.getCurrentQuestion();
|
|
570168
570239
|
if (question) {
|
|
@@ -570184,7 +570255,7 @@ Ask the user naturally; don't mention this instruction. After they answer, proce
|
|
|
570184
570255
|
this.kanban.moveTask(this.currentBmadTask.id, "ready");
|
|
570185
570256
|
this.kanban.moveTask(this.currentBmadTask.id, "in_progress");
|
|
570186
570257
|
}
|
|
570187
|
-
if (!this.proactiveGatherer && !quickPrompt) {
|
|
570258
|
+
if (!this.proactiveGatherer && !quickPrompt && !smallTalkTurn) {
|
|
570188
570259
|
await this.tryRunPreToolRouter(textForAgent);
|
|
570189
570260
|
}
|
|
570190
570261
|
const needsPlanningGate2 = !isVerbatimScope(this.config.agentScope) && needsPlanningGate(textForAgent);
|
|
@@ -570329,9 +570400,9 @@ Ask the user naturally; don't mention this instruction. After they answer, proce
|
|
|
570329
570400
|
"search_symbols",
|
|
570330
570401
|
"recall"
|
|
570331
570402
|
]);
|
|
570332
|
-
const scopedTools = isNoToolScope(this.config.agentScope) ? {} : this.config.agentScope === "__table__" ? Object.fromEntries(Object.entries(providerTools).filter(([k]) => TABLE_SESSION_TOOLS.has(k))) : providerTools;
|
|
570403
|
+
const scopedTools = isNoToolScope(this.config.agentScope) || smallTalkTurn ? {} : this.config.agentScope === "__table__" ? Object.fromEntries(Object.entries(providerTools).filter(([k]) => TABLE_SESSION_TOOLS.has(k))) : providerTools;
|
|
570333
570404
|
const withExtensions = { ...scopedTools };
|
|
570334
|
-
if (this.extensionToolsAllowed()) {
|
|
570405
|
+
if (this.extensionToolsAllowed() && !smallTalkTurn) {
|
|
570335
570406
|
for (const t of this.extensionHost.listTools()) {
|
|
570336
570407
|
if (t.name in withExtensions)
|
|
570337
570408
|
continue;
|
|
@@ -570343,7 +570414,7 @@ Ask the user naturally; don't mention this instruction. After they answer, proce
|
|
|
570343
570414
|
}
|
|
570344
570415
|
}
|
|
570345
570416
|
const effectiveTools = this.modeFilter(withExtensions);
|
|
570346
|
-
const textToolAllowlist = (isNoToolScope(this.config.agentScope) ? [] : this.config.agentScope === "__table__" ? [...TABLE_SESSION_TOOLS] : localCoreTools).filter((name) => getModeManager().isToolAllowed(name));
|
|
570417
|
+
const textToolAllowlist = (isNoToolScope(this.config.agentScope) || smallTalkTurn ? [] : this.config.agentScope === "__table__" ? [...TABLE_SESSION_TOOLS] : localCoreTools).filter((name) => getModeManager().isToolAllowed(name));
|
|
570347
570418
|
const harness = this.harnessProfileFor(providerConfig.model, isLocalProvider);
|
|
570348
570419
|
Object.assign(this.runtimeParams, {
|
|
570349
570420
|
voiceChatActive: getRuntimeParams().voiceChatActive,
|
|
@@ -570368,7 +570439,8 @@ Ask the user naturally; don't mention this instruction. After they answer, proce
|
|
|
570368
570439
|
`),
|
|
570369
570440
|
localCoreTools: textToolAllowlist,
|
|
570370
570441
|
chatStartTime,
|
|
570371
|
-
textForAgent
|
|
570442
|
+
textForAgent,
|
|
570443
|
+
smallTalk: smallTalkTurn
|
|
570372
570444
|
});
|
|
570373
570445
|
await this.readServerContextWindow();
|
|
570374
570446
|
await this.compactIfNeeded(providerConfig);
|
|
@@ -571053,7 +571125,7 @@ ${summary || " (no provider errors recorded)"}`);
|
|
|
571053
571125
|
};
|
|
571054
571126
|
}
|
|
571055
571127
|
const blankNative = gatedNative.content.trim() === "";
|
|
571056
|
-
const content = blankNative ? emptyReplyNote(this.turnToolLedger.length) : gatedNative.content;
|
|
571128
|
+
const content = blankNative ? emptyReplyNote(this.turnToolLedger.length, this.turnToolLedger) : gatedNative.content;
|
|
571057
571129
|
const flavor = voice.getFlavor("complete");
|
|
571058
571130
|
const flavoredContent = fixCompletedLine(gatedNative.violated || isVerbatimScope(this.config.agentScope) ? content : flavorResponse(content, flavor)).text;
|
|
571059
571131
|
this.messageHistory.push({ role: "assistant", content: flavoredContent });
|
|
@@ -571768,6 +571840,7 @@ var init_agent2 = __esm(() => {
|
|
|
571768
571840
|
init_modes();
|
|
571769
571841
|
init_planning_gate();
|
|
571770
571842
|
init_registry();
|
|
571843
|
+
init_small_talk();
|
|
571771
571844
|
init_verify_gate();
|
|
571772
571845
|
init_local_tool_scope();
|
|
571773
571846
|
init_local_turn_error();
|
|
@@ -572263,7 +572336,7 @@ var init_install = __esm(() => {
|
|
|
572263
572336
|
|
|
572264
572337
|
// packages/eight/source-update.ts
|
|
572265
572338
|
import { execFile as execFile7 } from "child_process";
|
|
572266
|
-
import { existsSync as
|
|
572339
|
+
import { existsSync as existsSync110, realpathSync as realpathSync36, statSync as statSync36 } from "fs";
|
|
572267
572340
|
import { homedir as homedir84 } from "os";
|
|
572268
572341
|
import * as nodePath from "path";
|
|
572269
572342
|
function scrubbedEnv(base) {
|
|
@@ -572362,7 +572435,7 @@ function modulePathToFs(modulePath) {
|
|
|
572362
572435
|
}
|
|
572363
572436
|
return s;
|
|
572364
572437
|
}
|
|
572365
|
-
function findCheckoutRoot(modulePath, platform, hasGit = (d) =>
|
|
572438
|
+
function findCheckoutRoot(modulePath, platform, hasGit = (d) => existsSync110(lib(platform).join(d, ".git"))) {
|
|
572366
572439
|
const p = lib(platform);
|
|
572367
572440
|
const fsPath = modulePathToFs(modulePath);
|
|
572368
572441
|
let dir = p.dirname(platform === "win32" ? fsPath.replace(/\//g, "\\") : fsPath);
|
|
@@ -572378,7 +572451,7 @@ function findCheckoutRoot(modulePath, platform, hasGit = (d) => existsSync109(li
|
|
|
572378
572451
|
}
|
|
572379
572452
|
function findBrowserCheckout(o) {
|
|
572380
572453
|
const p = lib(o.platform);
|
|
572381
|
-
const hasGit = o.hasGit ?? ((d) =>
|
|
572454
|
+
const hasGit = o.hasGit ?? ((d) => existsSync110(p.join(d, ".git")));
|
|
572382
572455
|
const looked = [];
|
|
572383
572456
|
let note;
|
|
572384
572457
|
const cands = [];
|
|
@@ -572704,7 +572777,7 @@ async function runSourceUpdate(deps, opts, report) {
|
|
|
572704
572777
|
git,
|
|
572705
572778
|
bun: bun ?? "bun",
|
|
572706
572779
|
platform,
|
|
572707
|
-
fileExists: deps.fileExists ?? ((f) =>
|
|
572780
|
+
fileExists: deps.fileExists ?? ((f) => existsSync110(f)),
|
|
572708
572781
|
now: deps.now ?? (() => new Date),
|
|
572709
572782
|
baseEnv: env,
|
|
572710
572783
|
forgeHost: env.EIGHT_FORGE_HOST,
|
|
@@ -573150,7 +573223,7 @@ var init_update_notice = __esm(() => {
|
|
|
573150
573223
|
});
|
|
573151
573224
|
|
|
573152
573225
|
// packages/voice/cloud-transcriber.ts
|
|
573153
|
-
import { existsSync as
|
|
573226
|
+
import { existsSync as existsSync111 } from "fs";
|
|
573154
573227
|
async function transcribeCloud(wavPath, options) {
|
|
573155
573228
|
const {
|
|
573156
573229
|
apiKey,
|
|
@@ -573162,7 +573235,7 @@ async function transcribeCloud(wavPath, options) {
|
|
|
573162
573235
|
if (!apiKey) {
|
|
573163
573236
|
throw new Error("OpenAI API key is required for cloud transcription. Set OPENAI_API_KEY environment variable.");
|
|
573164
573237
|
}
|
|
573165
|
-
if (!
|
|
573238
|
+
if (!existsSync111(wavPath)) {
|
|
573166
573239
|
throw new Error(`WAV file not found: ${wavPath}`);
|
|
573167
573240
|
}
|
|
573168
573241
|
const startTime = Date.now();
|
|
@@ -573266,11 +573339,11 @@ var init_types5 = __esm(() => {
|
|
|
573266
573339
|
|
|
573267
573340
|
// packages/voice/model-manager.ts
|
|
573268
573341
|
import { EventEmitter as EventEmitter15 } from "events";
|
|
573269
|
-
import { existsSync as
|
|
573342
|
+
import { existsSync as existsSync112, mkdirSync as mkdirSync80, realpathSync as realpathSync37, unlinkSync as unlinkSync3 } from "fs";
|
|
573270
573343
|
import { homedir as homedir85 } from "os";
|
|
573271
573344
|
import { join as join168, sep as sep30 } from "path";
|
|
573272
573345
|
function resolveWhisperModel(opts = {}) {
|
|
573273
|
-
const exists = opts.exists ??
|
|
573346
|
+
const exists = opts.exists ?? existsSync112;
|
|
573274
573347
|
const dirs = [
|
|
573275
573348
|
resolveModelsPath(opts.modelsDir ?? "~/.8gent/models/whisper"),
|
|
573276
573349
|
...opts.extraDirs ?? []
|
|
@@ -573331,7 +573404,7 @@ var init_model_manager = __esm(() => {
|
|
|
573331
573404
|
this.modelsDir = resolveModelsPath(modelsPath);
|
|
573332
573405
|
}
|
|
573333
573406
|
ensureModelsDir() {
|
|
573334
|
-
if (!
|
|
573407
|
+
if (!existsSync112(this.modelsDir)) {
|
|
573335
573408
|
mkdirSync80(this.modelsDir, { recursive: true });
|
|
573336
573409
|
}
|
|
573337
573410
|
}
|
|
@@ -573345,7 +573418,7 @@ var init_model_manager = __esm(() => {
|
|
|
573345
573418
|
return join168(this.modelsDir, WHISPER_MODELS[name].filename);
|
|
573346
573419
|
}
|
|
573347
573420
|
isModelDownloaded(name) {
|
|
573348
|
-
return
|
|
573421
|
+
return existsSync112(this.getModelPath(name));
|
|
573349
573422
|
}
|
|
573350
573423
|
listModels() {
|
|
573351
573424
|
return Object.keys(WHISPER_MODELS).map((name) => ({
|
|
@@ -573360,7 +573433,7 @@ var init_model_manager = __esm(() => {
|
|
|
573360
573433
|
async downloadModel(name) {
|
|
573361
573434
|
const info = WHISPER_MODELS[name];
|
|
573362
573435
|
const destPath = this.getModelPath(name);
|
|
573363
|
-
if (
|
|
573436
|
+
if (existsSync112(destPath)) {
|
|
573364
573437
|
return destPath;
|
|
573365
573438
|
}
|
|
573366
573439
|
this.ensureModelsDir();
|
|
@@ -573411,7 +573484,7 @@ var init_model_manager = __esm(() => {
|
|
|
573411
573484
|
this.emit("download-complete", { model: name, path: destPath });
|
|
573412
573485
|
return destPath;
|
|
573413
573486
|
} catch (err) {
|
|
573414
|
-
if (
|
|
573487
|
+
if (existsSync112(destPath)) {
|
|
573415
573488
|
try {
|
|
573416
573489
|
unlinkSync3(destPath);
|
|
573417
573490
|
} catch {}
|
|
@@ -573423,7 +573496,7 @@ var init_model_manager = __esm(() => {
|
|
|
573423
573496
|
}
|
|
573424
573497
|
deleteModel(name) {
|
|
573425
573498
|
const path = this.getModelPath(name);
|
|
573426
|
-
if (
|
|
573499
|
+
if (existsSync112(path)) {
|
|
573427
573500
|
unlinkSync3(path);
|
|
573428
573501
|
return true;
|
|
573429
573502
|
}
|
|
@@ -573434,7 +573507,7 @@ var init_model_manager = __esm(() => {
|
|
|
573434
573507
|
let totalBytes = 0;
|
|
573435
573508
|
for (const name of Object.keys(WHISPER_MODELS)) {
|
|
573436
573509
|
const path = this.getModelPath(name);
|
|
573437
|
-
if (
|
|
573510
|
+
if (existsSync112(path)) {
|
|
573438
573511
|
try {
|
|
573439
573512
|
const stat = Bun.file(path);
|
|
573440
573513
|
models[name] = stat.size;
|
|
@@ -573499,7 +573572,7 @@ var init_termux = __esm(() => {
|
|
|
573499
573572
|
|
|
573500
573573
|
// packages/voice/recorder.ts
|
|
573501
573574
|
import { EventEmitter as EventEmitter16 } from "events";
|
|
573502
|
-
import { closeSync as closeSync21, existsSync as
|
|
573575
|
+
import { closeSync as closeSync21, existsSync as existsSync113, openSync as openSync21, readSync as readSync13, statSync as statSync37, unlinkSync as unlinkSync4 } from "fs";
|
|
573503
573576
|
import { tmpdir as tmpdir20 } from "os";
|
|
573504
573577
|
import { join as join170 } from "path";
|
|
573505
573578
|
var {spawn: spawn26 } = globalThis.Bun;
|
|
@@ -573701,7 +573774,7 @@ var init_recorder = __esm(() => {
|
|
|
573701
573774
|
}
|
|
573702
573775
|
static cleanupFile(path) {
|
|
573703
573776
|
try {
|
|
573704
|
-
if (
|
|
573777
|
+
if (existsSync113(path)) {
|
|
573705
573778
|
unlinkSync4(path);
|
|
573706
573779
|
}
|
|
573707
573780
|
} catch {}
|
|
@@ -573721,7 +573794,7 @@ var init_recorder = __esm(() => {
|
|
|
573721
573794
|
});
|
|
573722
573795
|
|
|
573723
573796
|
// packages/voice/transcriber.ts
|
|
573724
|
-
import { existsSync as
|
|
573797
|
+
import { existsSync as existsSync114 } from "fs";
|
|
573725
573798
|
import { arch as arch2, homedir as homedir86, platform as platform9 } from "os";
|
|
573726
573799
|
import { join as join171 } from "path";
|
|
573727
573800
|
var {spawn: spawn27 } = globalThis.Bun;
|
|
@@ -573730,7 +573803,7 @@ function getWhisperBinaryPath() {
|
|
|
573730
573803
|
}
|
|
573731
573804
|
async function findWhisperBinary() {
|
|
573732
573805
|
const managedPath = getWhisperBinaryPath();
|
|
573733
|
-
if (
|
|
573806
|
+
if (existsSync114(managedPath)) {
|
|
573734
573807
|
return managedPath;
|
|
573735
573808
|
}
|
|
573736
573809
|
const names = ["whisper-cpp", "whisper-cli", "whisper", "main"];
|
|
@@ -573745,7 +573818,7 @@ async function findWhisperBinary() {
|
|
|
573745
573818
|
} catch {}
|
|
573746
573819
|
}
|
|
573747
573820
|
for (const brewName of ["/opt/homebrew/bin/whisper-cpp", "/opt/homebrew/bin/whisper-cli"]) {
|
|
573748
|
-
if (
|
|
573821
|
+
if (existsSync114(brewName)) {
|
|
573749
573822
|
return brewName;
|
|
573750
573823
|
}
|
|
573751
573824
|
}
|
|
@@ -573753,13 +573826,13 @@ async function findWhisperBinary() {
|
|
|
573753
573826
|
}
|
|
573754
573827
|
async function transcribeLocal(wavPath, options) {
|
|
573755
573828
|
const { binaryPath, modelPath, language = "en", timeoutMs = 30000, threads } = options;
|
|
573756
|
-
if (!
|
|
573829
|
+
if (!existsSync114(wavPath)) {
|
|
573757
573830
|
throw new Error(`WAV file not found: ${wavPath}`);
|
|
573758
573831
|
}
|
|
573759
|
-
if (!
|
|
573832
|
+
if (!existsSync114(binaryPath)) {
|
|
573760
573833
|
throw new Error(`Whisper binary not found: ${binaryPath}`);
|
|
573761
573834
|
}
|
|
573762
|
-
if (!
|
|
573835
|
+
if (!existsSync114(modelPath)) {
|
|
573763
573836
|
throw new Error(`Model file not found: ${modelPath}`);
|
|
573764
573837
|
}
|
|
573765
573838
|
const startTime = Date.now();
|
|
@@ -574035,7 +574108,7 @@ var init_neudecide = __esm(() => {
|
|
|
574035
574108
|
|
|
574036
574109
|
// packages/runtime/node-runtime.ts
|
|
574037
574110
|
import { execFile as execFile8 } from "child_process";
|
|
574038
|
-
import { existsSync as
|
|
574111
|
+
import { existsSync as existsSync119 } from "fs";
|
|
574039
574112
|
import { homedir as homedir88 } from "os";
|
|
574040
574113
|
import { join as join178 } from "path";
|
|
574041
574114
|
import { promisify as promisify6 } from "util";
|
|
@@ -574098,7 +574171,7 @@ async function isRuntimeReady(opts) {
|
|
|
574098
574171
|
version: opts.version,
|
|
574099
574172
|
platform
|
|
574100
574173
|
});
|
|
574101
|
-
if (!
|
|
574174
|
+
if (!existsSync119(bin))
|
|
574102
574175
|
return false;
|
|
574103
574176
|
const min = opts.minVersion ?? opts.version;
|
|
574104
574177
|
try {
|
|
@@ -574136,7 +574209,7 @@ var init_node_runtime = __esm(() => {
|
|
|
574136
574209
|
import { spawn as spawn29 } from "child_process";
|
|
574137
574210
|
import {
|
|
574138
574211
|
createWriteStream,
|
|
574139
|
-
existsSync as
|
|
574212
|
+
existsSync as existsSync120,
|
|
574140
574213
|
mkdirSync as mkdirSync83,
|
|
574141
574214
|
mkdtempSync as mkdtempSync12,
|
|
574142
574215
|
readdirSync as readdirSync27,
|
|
@@ -574197,7 +574270,7 @@ async function installRuntime(input) {
|
|
|
574197
574270
|
throw new Error(`could not find node-* dir inside ${extractRoot}`);
|
|
574198
574271
|
}
|
|
574199
574272
|
const extractedPath = join179(extractRoot, nodeDir);
|
|
574200
|
-
if (
|
|
574273
|
+
if (existsSync120(plan.runtimeDir)) {
|
|
574201
574274
|
rmSync17(plan.runtimeDir, { recursive: true, force: true });
|
|
574202
574275
|
}
|
|
574203
574276
|
renameSync17(extractedPath, plan.runtimeDir);
|
|
@@ -576179,7 +576252,7 @@ Nothing was changed. Type /update again to apply.`);
|
|
|
576179
576252
|
// apps/tui/src/lib/telegram-setup.ts
|
|
576180
576253
|
import {
|
|
576181
576254
|
chmodSync as chmodSync6,
|
|
576182
|
-
existsSync as
|
|
576255
|
+
existsSync as existsSync135,
|
|
576183
576256
|
lstatSync as lstatSync31,
|
|
576184
576257
|
mkdirSync as mkdirSync96,
|
|
576185
576258
|
readFileSync as readFileSync120,
|
|
@@ -576301,7 +576374,7 @@ async function getSeenChats(key) {
|
|
|
576301
576374
|
function mergeSettings(chatIds, envFile, tokenVar) {
|
|
576302
576375
|
const path = join200(homeDir4(), ".8gent", "settings.json");
|
|
576303
576376
|
let settings = {};
|
|
576304
|
-
if (
|
|
576377
|
+
if (existsSync135(path)) {
|
|
576305
576378
|
try {
|
|
576306
576379
|
const parsed = JSON.parse(readFileSync120(path, "utf8"));
|
|
576307
576380
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed))
|
|
@@ -576668,7 +576741,7 @@ Personal 8gent mini-app. Iteration is driven by \`SKILL.md\`. Run tests with \`b
|
|
|
576668
576741
|
}
|
|
576669
576742
|
|
|
576670
576743
|
// packages/app-creator/creator.ts
|
|
576671
|
-
import { existsSync as
|
|
576744
|
+
import { existsSync as existsSync136, mkdirSync as mkdirSync98, writeFileSync as writeFileSync78 } from "fs";
|
|
576672
576745
|
import { homedir as homedir96 } from "os";
|
|
576673
576746
|
import { dirname as dirname83, join as join202 } from "path";
|
|
576674
576747
|
function defaultAppsRoot() {
|
|
@@ -576726,7 +576799,7 @@ function createApp(input) {
|
|
|
576726
576799
|
return { ...draft, persisted: false, written: [] };
|
|
576727
576800
|
}
|
|
576728
576801
|
const dir = draft.dir;
|
|
576729
|
-
const targetExists =
|
|
576802
|
+
const targetExists = existsSync136(dir);
|
|
576730
576803
|
if (targetExists && !input.allowOverwrite) {
|
|
576731
576804
|
return {
|
|
576732
576805
|
...draft,
|
|
@@ -577573,7 +577646,7 @@ var init_producer = __esm(() => {
|
|
|
577573
577646
|
});
|
|
577574
577647
|
|
|
577575
577648
|
// packages/pet/companion.ts
|
|
577576
|
-
import { existsSync as
|
|
577649
|
+
import { existsSync as existsSync140, mkdirSync as mkdirSync104, readFileSync as readFileSync122, writeFileSync as writeFileSync80 } from "fs";
|
|
577577
577650
|
import { join as join204 } from "path";
|
|
577578
577651
|
function seedRng(seed) {
|
|
577579
577652
|
let h = 0;
|
|
@@ -577717,7 +577790,7 @@ function getDeckPath() {
|
|
|
577717
577790
|
function loadDeck() {
|
|
577718
577791
|
const deckPath = getDeckPath();
|
|
577719
577792
|
try {
|
|
577720
|
-
if (
|
|
577793
|
+
if (existsSync140(deckPath)) {
|
|
577721
577794
|
return JSON.parse(readFileSync122(deckPath, "utf-8"));
|
|
577722
577795
|
}
|
|
577723
577796
|
} catch {}
|
|
@@ -598971,234 +599044,6 @@ function useImageInput(options = {}) {
|
|
|
598971
599044
|
// apps/tui/src/components/message-list.tsx
|
|
598972
599045
|
var import_react63 = __toESM(require_react(), 1);
|
|
598973
599046
|
|
|
598974
|
-
// apps/tui/src/lib/chat-layout.ts
|
|
598975
|
-
var SHELL_CHROME = 4;
|
|
598976
|
-
var COLUMN_GAP = 1;
|
|
598977
|
-
var ACTIVITY_RAIL_WIDTH = 34;
|
|
598978
|
-
function chatColumnWidth(cols, shell, min = 24) {
|
|
598979
|
-
let width = cols - SHELL_CHROME;
|
|
598980
|
-
if (shell.planWidth && shell.planWidth > 0)
|
|
598981
|
-
width -= shell.planWidth + COLUMN_GAP;
|
|
598982
|
-
if (shell.activity)
|
|
598983
|
-
width -= ACTIVITY_RAIL_WIDTH + COLUMN_GAP;
|
|
598984
|
-
return Math.max(min, width);
|
|
598985
|
-
}
|
|
598986
|
-
var USER_BUBBLE_SHARE = 0.78;
|
|
598987
|
-
function bubbleWidths(contentWidth, role) {
|
|
598988
|
-
const inner = Math.max(16, contentWidth - 2);
|
|
598989
|
-
const bubble = role === "user" ? Math.max(16, Math.floor(inner * USER_BUBBLE_SHARE)) : inner;
|
|
598990
|
-
return { bubble, wrap: Math.max(8, bubble - 2) };
|
|
598991
|
-
}
|
|
598992
|
-
|
|
598993
|
-
// apps/tui/src/lib/tool-trail.ts
|
|
598994
|
-
var COLLAPSE_THRESHOLD = 8;
|
|
598995
|
-
var MAX_TRAIL_ROWS = 12;
|
|
598996
|
-
var PATH_KEYS = ["path", "file_path", "filePath", "file", "directory", "dir"];
|
|
598997
|
-
var COMMAND_KEYS = ["command", "cmd"];
|
|
598998
|
-
var QUERY_KEYS = ["query", "pattern", "q", "search", "url"];
|
|
598999
|
-
function oneLine(s) {
|
|
599000
|
-
return s.replace(/\s+/g, " ").trim().slice(0, 200);
|
|
599001
|
-
}
|
|
599002
|
-
function pick3(args, keys) {
|
|
599003
|
-
for (const k of keys) {
|
|
599004
|
-
const v = args[k];
|
|
599005
|
-
if (typeof v === "string" && v.trim())
|
|
599006
|
-
return oneLine(v);
|
|
599007
|
-
}
|
|
599008
|
-
return null;
|
|
599009
|
-
}
|
|
599010
|
-
function summarizeToolArgs(tool, args) {
|
|
599011
|
-
if (!args || typeof args !== "object")
|
|
599012
|
-
return "";
|
|
599013
|
-
const isCommand = /command|shell|exec|bash/.test(tool);
|
|
599014
|
-
const order = isCommand ? [COMMAND_KEYS, PATH_KEYS, QUERY_KEYS] : /search|grep|glob|find|fetch/.test(tool) ? [QUERY_KEYS, PATH_KEYS, COMMAND_KEYS] : [PATH_KEYS, COMMAND_KEYS, QUERY_KEYS];
|
|
599015
|
-
for (const keys of order) {
|
|
599016
|
-
const hit = pick3(args, keys);
|
|
599017
|
-
if (hit)
|
|
599018
|
-
return hit;
|
|
599019
|
-
}
|
|
599020
|
-
for (const v of Object.values(args)) {
|
|
599021
|
-
if (typeof v === "string" && v.trim())
|
|
599022
|
-
return oneLine(v);
|
|
599023
|
-
}
|
|
599024
|
-
return "";
|
|
599025
|
-
}
|
|
599026
|
-
var GATE_PREFIX = /^\s*\[([A-Z0-9_ -]*\b(?:BLOCKED|DENIED)\b[A-Z0-9_ -]*)\]/;
|
|
599027
|
-
var OTHER_BLOCK = /^\s*(?:Path blocked by path-guard|Path traversal blocked)|Hook blocked tool/;
|
|
599028
|
-
var RULE_NAME = /\[([a-z0-9]+(?:-[a-z0-9]+)+)\]/;
|
|
599029
|
-
function classifyToolResult(success, preview) {
|
|
599030
|
-
const text = preview ?? "";
|
|
599031
|
-
const gate = text.match(GATE_PREFIX);
|
|
599032
|
-
if (gate || OTHER_BLOCK.test(text)) {
|
|
599033
|
-
if (gate && /DENIED/.test(gate[1]))
|
|
599034
|
-
return { status: "blocked", reason: "denied" };
|
|
599035
|
-
const rule = text.match(RULE_NAME);
|
|
599036
|
-
return { status: "blocked", reason: rule ? `blocked: [${rule[1]}]` : "blocked" };
|
|
599037
|
-
}
|
|
599038
|
-
const exit = text.match(/^\s*Exit code (-?\d+)/);
|
|
599039
|
-
if (exit && exit[1] !== "0")
|
|
599040
|
-
return { status: "fail", reason: `exit ${exit[1]}` };
|
|
599041
|
-
if (!success || /^\s*(?:Error\b|Unknown tool:)/.test(text)) {
|
|
599042
|
-
const first = (text.split(`
|
|
599043
|
-
`).find((l) => l.trim()) ?? "").replace(/^\s*Error(?: running tool "[^"]*")?:?\s*/, "").trim();
|
|
599044
|
-
if (!first)
|
|
599045
|
-
return { status: "fail", reason: "error" };
|
|
599046
|
-
return { status: "fail", reason: first.length > 40 ? `${first.slice(0, 39)}\u2026` : first };
|
|
599047
|
-
}
|
|
599048
|
-
return { status: "ok" };
|
|
599049
|
-
}
|
|
599050
|
-
function toTrailEntry(event) {
|
|
599051
|
-
const { status, reason } = classifyToolResult(event.success !== false, event.resultPreview);
|
|
599052
|
-
const entry = {
|
|
599053
|
-
tool: event.toolName,
|
|
599054
|
-
summary: summarizeToolArgs(event.toolName, event.args),
|
|
599055
|
-
status
|
|
599056
|
-
};
|
|
599057
|
-
if (reason)
|
|
599058
|
-
entry.reason = reason;
|
|
599059
|
-
if (event.toolName === "update_plan") {
|
|
599060
|
-
const items = event.args?.plan;
|
|
599061
|
-
if (Array.isArray(items)) {
|
|
599062
|
-
const plan = items.map((i) => i && typeof i === "object" ? i : {}).filter((i) => typeof i.step === "string" && i.step.trim() !== "").map((i) => ({ step: i.step, status: typeof i.status === "string" ? i.status : "pending" }));
|
|
599063
|
-
if (plan.length > 0)
|
|
599064
|
-
entry.plan = plan;
|
|
599065
|
-
}
|
|
599066
|
-
}
|
|
599067
|
-
return entry;
|
|
599068
|
-
}
|
|
599069
|
-
function isReadTool(tool) {
|
|
599070
|
-
return /^(?:read_|list_|get_|search|grep|glob|find|view|web_search|web_fetch)/.test(tool);
|
|
599071
|
-
}
|
|
599072
|
-
function commonDir(paths) {
|
|
599073
|
-
const split = paths.map((p) => p.split("/").slice(0, -1));
|
|
599074
|
-
const first = split[0] ?? [];
|
|
599075
|
-
let n = 0;
|
|
599076
|
-
while (n < first.length && split.every((s) => s[n] === first[n]))
|
|
599077
|
-
n++;
|
|
599078
|
-
return n > 0 ? `${first.slice(0, n).join("/")}/` : "";
|
|
599079
|
-
}
|
|
599080
|
-
function collapseTrail(entries, maxRows = MAX_TRAIL_ROWS) {
|
|
599081
|
-
let rows = entries.map((e) => ({ ...e, count: 1 }));
|
|
599082
|
-
if (entries.length > COLLAPSE_THRESHOLD) {
|
|
599083
|
-
const out = [];
|
|
599084
|
-
for (let i = 0;i < entries.length; ) {
|
|
599085
|
-
const e = entries[i];
|
|
599086
|
-
let j = i + 1;
|
|
599087
|
-
if (e.status === "ok" && isReadTool(e.tool)) {
|
|
599088
|
-
while (j < entries.length && entries[j].tool === e.tool && entries[j].status === "ok")
|
|
599089
|
-
j++;
|
|
599090
|
-
}
|
|
599091
|
-
if (j - i > 1) {
|
|
599092
|
-
const run = entries.slice(i, j);
|
|
599093
|
-
out.push({
|
|
599094
|
-
tool: e.tool,
|
|
599095
|
-
status: "ok",
|
|
599096
|
-
count: run.length,
|
|
599097
|
-
summary: commonDir(run.map((r) => r.summary))
|
|
599098
|
-
});
|
|
599099
|
-
} else {
|
|
599100
|
-
out.push({ ...e, count: 1 });
|
|
599101
|
-
}
|
|
599102
|
-
i = j;
|
|
599103
|
-
}
|
|
599104
|
-
rows = out;
|
|
599105
|
-
}
|
|
599106
|
-
const cap = Math.max(1, Math.floor(maxRows));
|
|
599107
|
-
if (rows.length > cap) {
|
|
599108
|
-
let toFold = rows.length - cap + 1;
|
|
599109
|
-
const fold = new Set;
|
|
599110
|
-
for (const wantOk of [true, false]) {
|
|
599111
|
-
for (let i = 0;i < rows.length && toFold > 0; i++) {
|
|
599112
|
-
if (fold.has(i) || wantOk && rows[i].status !== "ok")
|
|
599113
|
-
continue;
|
|
599114
|
-
fold.add(i);
|
|
599115
|
-
toFold--;
|
|
599116
|
-
}
|
|
599117
|
-
}
|
|
599118
|
-
const folded = rows.filter((_, i) => fold.has(i));
|
|
599119
|
-
const count = (s) => folded.filter((r) => r.status === s).reduce((n, r) => n + r.count, 0);
|
|
599120
|
-
const failed = count("fail");
|
|
599121
|
-
const blocked = count("blocked");
|
|
599122
|
-
const summary = {
|
|
599123
|
-
tool: "",
|
|
599124
|
-
summary: "",
|
|
599125
|
-
status: failed > 0 ? "fail" : blocked > 0 ? "blocked" : "ok",
|
|
599126
|
-
count: folded.reduce((n, r) => n + r.count, 0),
|
|
599127
|
-
folded: true,
|
|
599128
|
-
all: fold.size === rows.length
|
|
599129
|
-
};
|
|
599130
|
-
if (failed > 0)
|
|
599131
|
-
summary.failed = failed;
|
|
599132
|
-
if (blocked > 0)
|
|
599133
|
-
summary.blocked = blocked;
|
|
599134
|
-
rows = [summary, ...rows.filter((_, i) => !fold.has(i))];
|
|
599135
|
-
}
|
|
599136
|
-
return rows;
|
|
599137
|
-
}
|
|
599138
|
-
var ICONS = { ok: "\u2713", fail: "\u2717", blocked: "\u2298" };
|
|
599139
|
-
function formatTrailRow(row, width) {
|
|
599140
|
-
const icon = ICONS[row.status];
|
|
599141
|
-
const budget = Math.max(1, width - icon.length - 1);
|
|
599142
|
-
if (row.folded) {
|
|
599143
|
-
const parts = [`${row.count} ${row.all ? "calls" : "earlier calls"}`];
|
|
599144
|
-
if (row.failed)
|
|
599145
|
-
parts.push(`${row.failed} failed`);
|
|
599146
|
-
if (row.blocked)
|
|
599147
|
-
parts.push(`${row.blocked} blocked`);
|
|
599148
|
-
return { icon, text: clip(parts.join(", "), budget) };
|
|
599149
|
-
}
|
|
599150
|
-
const head = row.count > 1 ? `${row.tool} \xD7${row.count}` : row.tool;
|
|
599151
|
-
const tail = row.reason ? ` (${row.reason})` : "";
|
|
599152
|
-
let summary = row.count > 1 ? row.summary ? `(${row.summary}\u2026)` : "" : row.summary;
|
|
599153
|
-
if (!summary)
|
|
599154
|
-
return { icon, text: clip(`${head}${tail}`, budget) };
|
|
599155
|
-
const room = budget - head.length - 1 - tail.length;
|
|
599156
|
-
if (room < 4)
|
|
599157
|
-
return { icon, text: clip(`${head}${tail}`, budget) };
|
|
599158
|
-
if (summary.length > room)
|
|
599159
|
-
summary = `${summary.slice(0, room - 1)}\u2026`;
|
|
599160
|
-
return { icon, text: `${head} ${summary}${tail}` };
|
|
599161
|
-
}
|
|
599162
|
-
function clip(s, width) {
|
|
599163
|
-
return s.length <= width ? s : `${s.slice(0, Math.max(0, width - 1))}\u2026`;
|
|
599164
|
-
}
|
|
599165
|
-
function buildChatItems(messages) {
|
|
599166
|
-
const items = [];
|
|
599167
|
-
let pending = [];
|
|
599168
|
-
let pendingFirst = null;
|
|
599169
|
-
const flush = () => {
|
|
599170
|
-
if (pending.length > 0 && pendingFirst) {
|
|
599171
|
-
items.push({
|
|
599172
|
-
message: { ...pendingFirst, id: `trail-${pendingFirst.id}`, role: "tool", content: "" },
|
|
599173
|
-
trail: pending
|
|
599174
|
-
});
|
|
599175
|
-
}
|
|
599176
|
-
pending = [];
|
|
599177
|
-
pendingFirst = null;
|
|
599178
|
-
};
|
|
599179
|
-
for (const m of messages) {
|
|
599180
|
-
if (m.role === "tool") {
|
|
599181
|
-
if (m.toolTrail) {
|
|
599182
|
-
if (!pendingFirst)
|
|
599183
|
-
pendingFirst = m;
|
|
599184
|
-
pending.push(m.toolTrail);
|
|
599185
|
-
}
|
|
599186
|
-
continue;
|
|
599187
|
-
}
|
|
599188
|
-
if (m.role === "assistant") {
|
|
599189
|
-
items.push({ message: m, trail: pending });
|
|
599190
|
-
pending = [];
|
|
599191
|
-
pendingFirst = null;
|
|
599192
|
-
continue;
|
|
599193
|
-
}
|
|
599194
|
-
if (m.role === "user")
|
|
599195
|
-
flush();
|
|
599196
|
-
items.push({ message: m, trail: [] });
|
|
599197
|
-
}
|
|
599198
|
-
flush();
|
|
599199
|
-
return items;
|
|
599200
|
-
}
|
|
599201
|
-
|
|
599202
599047
|
// apps/tui/src/hooks/useMouseScroll.ts
|
|
599203
599048
|
var import_react57 = __toESM(require_react(), 1);
|
|
599204
599049
|
function useMouseScroll({
|
|
@@ -599224,111 +599069,25 @@ function useMouseScroll({
|
|
|
599224
599069
|
}, [enabled, step]);
|
|
599225
599070
|
}
|
|
599226
599071
|
|
|
599227
|
-
// apps/tui/src/
|
|
599228
|
-
var
|
|
599229
|
-
var
|
|
599230
|
-
|
|
599231
|
-
|
|
599232
|
-
|
|
599233
|
-
|
|
599234
|
-
|
|
599235
|
-
|
|
599236
|
-
|
|
599237
|
-
|
|
599238
|
-
import_react58.useEffect(() => {
|
|
599239
|
-
if (!started)
|
|
599240
|
-
return;
|
|
599241
|
-
const timeout = setTimeout(() => {
|
|
599242
|
-
onComplete?.();
|
|
599243
|
-
}, duration);
|
|
599244
|
-
return () => clearTimeout(timeout);
|
|
599245
|
-
}, [started, duration, onComplete]);
|
|
599246
|
-
if (!started)
|
|
599247
|
-
return null;
|
|
599248
|
-
return /* @__PURE__ */ jsx_dev_runtime30.jsxDEV(Box_default, {
|
|
599249
|
-
children
|
|
599250
|
-
}, undefined, false, undefined, this);
|
|
599251
|
-
}
|
|
599252
|
-
|
|
599253
|
-
// apps/tui/src/components/ToolTrail.tsx
|
|
599254
|
-
var import_react59 = __toESM(require_react(), 1);
|
|
599255
|
-
var jsx_dev_runtime31 = __toESM(require_jsx_dev_runtime(), 1);
|
|
599256
|
-
function iconColor(status) {
|
|
599257
|
-
return status === "ok" ? t.green : status === "fail" ? t.red : t.orange;
|
|
599258
|
-
}
|
|
599259
|
-
function useLandingRows(total, animate) {
|
|
599260
|
-
const [shown, setShown] = import_react59.useState(total);
|
|
599261
|
-
const shownRef = import_react59.useRef(total);
|
|
599262
|
-
shownRef.current = shown;
|
|
599263
|
-
const landingRef = import_react59.useRef(null);
|
|
599264
|
-
import_react59.useEffect(() => {
|
|
599265
|
-
const from = shownRef.current;
|
|
599266
|
-
if (total <= from + 1 || !motionEnabled(animate)) {
|
|
599267
|
-
landingRef.current = null;
|
|
599268
|
-
setShown(total);
|
|
599269
|
-
return;
|
|
599270
|
-
}
|
|
599271
|
-
landingRef.current = total;
|
|
599272
|
-
const step = staggerFor(total - from);
|
|
599273
|
-
let n = from + 1;
|
|
599274
|
-
setShown(n);
|
|
599275
|
-
const id = setInterval(() => {
|
|
599276
|
-
n += 1;
|
|
599277
|
-
setShown(Math.min(total, n));
|
|
599278
|
-
if (n >= total) {
|
|
599279
|
-
landingRef.current = null;
|
|
599280
|
-
clearInterval(id);
|
|
599281
|
-
}
|
|
599282
|
-
}, step);
|
|
599283
|
-
return () => clearInterval(id);
|
|
599284
|
-
}, [total, animate]);
|
|
599285
|
-
if (landingRef.current === total)
|
|
599286
|
-
return Math.min(shown, total);
|
|
599287
|
-
if (total <= shown + 1)
|
|
599288
|
-
return total;
|
|
599289
|
-
return shown;
|
|
599290
|
-
}
|
|
599291
|
-
function ToolTrail({
|
|
599292
|
-
entries,
|
|
599293
|
-
width,
|
|
599294
|
-
maxRows,
|
|
599295
|
-
animate = true
|
|
599296
|
-
}) {
|
|
599297
|
-
const rows = collapseTrail(entries, maxRows);
|
|
599298
|
-
const visible = useLandingRows(rows.length, animate);
|
|
599299
|
-
if (rows.length === 0)
|
|
599300
|
-
return null;
|
|
599301
|
-
return /* @__PURE__ */ jsx_dev_runtime31.jsxDEV(Box_default, {
|
|
599302
|
-
flexDirection: "column",
|
|
599303
|
-
flexShrink: 0,
|
|
599304
|
-
children: rows.slice(0, visible).map((row, i) => {
|
|
599305
|
-
const { text } = formatTrailRow(row, width);
|
|
599306
|
-
const g = glyphs();
|
|
599307
|
-
const icon = row.status === "ok" ? g.ok : row.status === "fail" ? g.fail : g.blocked;
|
|
599308
|
-
return /* @__PURE__ */ jsx_dev_runtime31.jsxDEV(Box_default, {
|
|
599309
|
-
width,
|
|
599310
|
-
children: [
|
|
599311
|
-
/* @__PURE__ */ jsx_dev_runtime31.jsxDEV(Text, {
|
|
599312
|
-
color: iconColor(row.status),
|
|
599313
|
-
children: icon
|
|
599314
|
-
}, undefined, false, undefined, this),
|
|
599315
|
-
/* @__PURE__ */ jsx_dev_runtime31.jsxDEV(Text, {
|
|
599316
|
-
color: row.status === "ok" ? t.muted : t.textPrimary,
|
|
599317
|
-
wrap: "truncate-end",
|
|
599318
|
-
children: ` ${text}`
|
|
599319
|
-
}, undefined, false, undefined, this)
|
|
599320
|
-
]
|
|
599321
|
-
}, i, true, undefined, this);
|
|
599322
|
-
})
|
|
599323
|
-
}, undefined, false, undefined, this);
|
|
599072
|
+
// apps/tui/src/lib/chat-layout.ts
|
|
599073
|
+
var SHELL_CHROME = 4;
|
|
599074
|
+
var COLUMN_GAP = 1;
|
|
599075
|
+
var ACTIVITY_RAIL_WIDTH = 34;
|
|
599076
|
+
function chatColumnWidth(cols, shell, min = 24) {
|
|
599077
|
+
let width = cols - SHELL_CHROME;
|
|
599078
|
+
if (shell.planWidth && shell.planWidth > 0)
|
|
599079
|
+
width -= shell.planWidth + COLUMN_GAP;
|
|
599080
|
+
if (shell.activity)
|
|
599081
|
+
width -= ACTIVITY_RAIL_WIDTH + COLUMN_GAP;
|
|
599082
|
+
return Math.max(min, width);
|
|
599324
599083
|
}
|
|
599325
|
-
|
|
599326
|
-
|
|
599084
|
+
var USER_BUBBLE_SHARE = 0.78;
|
|
599085
|
+
function bubbleWidths(contentWidth, role) {
|
|
599086
|
+
const inner = Math.max(16, contentWidth - 2);
|
|
599087
|
+
const bubble = role === "user" ? Math.max(16, Math.floor(inner * USER_BUBBLE_SHARE)) : inner;
|
|
599088
|
+
return { bubble, wrap: Math.max(8, bubble - 2) };
|
|
599327
599089
|
}
|
|
599328
599090
|
|
|
599329
|
-
// apps/tui/src/components/TurnResults.tsx
|
|
599330
|
-
var import_react60 = __toESM(require_react(), 1);
|
|
599331
|
-
|
|
599332
599091
|
// apps/tui/src/lib/inline-markdown.ts
|
|
599333
599092
|
var MAX_DEPTH3 = 3;
|
|
599334
599093
|
var INDENT_STEP = 2;
|
|
@@ -599643,6 +599402,215 @@ function blockRows(block, width) {
|
|
|
599643
599402
|
}
|
|
599644
599403
|
}
|
|
599645
599404
|
|
|
599405
|
+
// apps/tui/src/lib/tool-trail.ts
|
|
599406
|
+
var COLLAPSE_THRESHOLD = 8;
|
|
599407
|
+
var MAX_TRAIL_ROWS = 12;
|
|
599408
|
+
var PATH_KEYS = ["path", "file_path", "filePath", "file", "directory", "dir"];
|
|
599409
|
+
var COMMAND_KEYS = ["command", "cmd"];
|
|
599410
|
+
var QUERY_KEYS = ["query", "pattern", "q", "search", "url"];
|
|
599411
|
+
function oneLine(s) {
|
|
599412
|
+
return s.replace(/\s+/g, " ").trim().slice(0, 200);
|
|
599413
|
+
}
|
|
599414
|
+
function pick3(args, keys) {
|
|
599415
|
+
for (const k of keys) {
|
|
599416
|
+
const v = args[k];
|
|
599417
|
+
if (typeof v === "string" && v.trim())
|
|
599418
|
+
return oneLine(v);
|
|
599419
|
+
}
|
|
599420
|
+
return null;
|
|
599421
|
+
}
|
|
599422
|
+
function summarizeToolArgs(tool, args) {
|
|
599423
|
+
if (!args || typeof args !== "object")
|
|
599424
|
+
return "";
|
|
599425
|
+
const isCommand = /command|shell|exec|bash/.test(tool);
|
|
599426
|
+
const order = isCommand ? [COMMAND_KEYS, PATH_KEYS, QUERY_KEYS] : /search|grep|glob|find|fetch/.test(tool) ? [QUERY_KEYS, PATH_KEYS, COMMAND_KEYS] : [PATH_KEYS, COMMAND_KEYS, QUERY_KEYS];
|
|
599427
|
+
for (const keys of order) {
|
|
599428
|
+
const hit = pick3(args, keys);
|
|
599429
|
+
if (hit)
|
|
599430
|
+
return hit;
|
|
599431
|
+
}
|
|
599432
|
+
for (const v of Object.values(args)) {
|
|
599433
|
+
if (typeof v === "string" && v.trim())
|
|
599434
|
+
return oneLine(v);
|
|
599435
|
+
}
|
|
599436
|
+
return "";
|
|
599437
|
+
}
|
|
599438
|
+
var GATE_PREFIX = /^\s*\[([A-Z0-9_ -]*\b(?:BLOCKED|DENIED)\b[A-Z0-9_ -]*)\]/;
|
|
599439
|
+
var OTHER_BLOCK = /^\s*(?:Path blocked by path-guard|Path traversal blocked)|Hook blocked tool/;
|
|
599440
|
+
var RULE_NAME = /\[([a-z0-9]+(?:-[a-z0-9]+)+)\]/;
|
|
599441
|
+
function classifyToolResult(success, preview) {
|
|
599442
|
+
const text = preview ?? "";
|
|
599443
|
+
const gate = text.match(GATE_PREFIX);
|
|
599444
|
+
if (gate || OTHER_BLOCK.test(text)) {
|
|
599445
|
+
if (gate && /DENIED/.test(gate[1]))
|
|
599446
|
+
return { status: "blocked", reason: "denied" };
|
|
599447
|
+
const rule = text.match(RULE_NAME);
|
|
599448
|
+
return { status: "blocked", reason: rule ? `blocked: [${rule[1]}]` : "blocked" };
|
|
599449
|
+
}
|
|
599450
|
+
const exit = text.match(/^\s*Exit code (-?\d+)/);
|
|
599451
|
+
if (exit && exit[1] !== "0")
|
|
599452
|
+
return { status: "fail", reason: `exit ${exit[1]}` };
|
|
599453
|
+
if (!success || /^\s*(?:Error\b|Unknown tool:)/.test(text)) {
|
|
599454
|
+
const first = (text.split(`
|
|
599455
|
+
`).find((l) => l.trim()) ?? "").replace(/^\s*Error(?: running tool "[^"]*")?:?\s*/, "").trim();
|
|
599456
|
+
if (!first)
|
|
599457
|
+
return { status: "fail", reason: "error" };
|
|
599458
|
+
return { status: "fail", reason: first.length > 40 ? `${first.slice(0, 39)}\u2026` : first };
|
|
599459
|
+
}
|
|
599460
|
+
return { status: "ok" };
|
|
599461
|
+
}
|
|
599462
|
+
function toTrailEntry(event) {
|
|
599463
|
+
const { status, reason } = classifyToolResult(event.success !== false, event.resultPreview);
|
|
599464
|
+
const entry = {
|
|
599465
|
+
tool: event.toolName,
|
|
599466
|
+
summary: summarizeToolArgs(event.toolName, event.args),
|
|
599467
|
+
status
|
|
599468
|
+
};
|
|
599469
|
+
if (reason)
|
|
599470
|
+
entry.reason = reason;
|
|
599471
|
+
if (event.toolName === "update_plan") {
|
|
599472
|
+
const items = event.args?.plan;
|
|
599473
|
+
if (Array.isArray(items)) {
|
|
599474
|
+
const plan = items.map((i) => i && typeof i === "object" ? i : {}).filter((i) => typeof i.step === "string" && i.step.trim() !== "").map((i) => ({ step: i.step, status: typeof i.status === "string" ? i.status : "pending" }));
|
|
599475
|
+
if (plan.length > 0)
|
|
599476
|
+
entry.plan = plan;
|
|
599477
|
+
}
|
|
599478
|
+
}
|
|
599479
|
+
return entry;
|
|
599480
|
+
}
|
|
599481
|
+
function isReadTool(tool) {
|
|
599482
|
+
return /^(?:read_|list_|get_|search|grep|glob|find|view|web_search|web_fetch)/.test(tool);
|
|
599483
|
+
}
|
|
599484
|
+
function commonDir(paths) {
|
|
599485
|
+
const split = paths.map((p) => p.split("/").slice(0, -1));
|
|
599486
|
+
const first = split[0] ?? [];
|
|
599487
|
+
let n = 0;
|
|
599488
|
+
while (n < first.length && split.every((s) => s[n] === first[n]))
|
|
599489
|
+
n++;
|
|
599490
|
+
return n > 0 ? `${first.slice(0, n).join("/")}/` : "";
|
|
599491
|
+
}
|
|
599492
|
+
function collapseTrail(entries, maxRows = MAX_TRAIL_ROWS) {
|
|
599493
|
+
let rows = entries.map((e) => ({ ...e, count: 1 }));
|
|
599494
|
+
if (entries.length > COLLAPSE_THRESHOLD) {
|
|
599495
|
+
const out = [];
|
|
599496
|
+
for (let i = 0;i < entries.length; ) {
|
|
599497
|
+
const e = entries[i];
|
|
599498
|
+
let j = i + 1;
|
|
599499
|
+
if (e.status === "ok" && isReadTool(e.tool)) {
|
|
599500
|
+
while (j < entries.length && entries[j].tool === e.tool && entries[j].status === "ok")
|
|
599501
|
+
j++;
|
|
599502
|
+
}
|
|
599503
|
+
if (j - i > 1) {
|
|
599504
|
+
const run = entries.slice(i, j);
|
|
599505
|
+
out.push({
|
|
599506
|
+
tool: e.tool,
|
|
599507
|
+
status: "ok",
|
|
599508
|
+
count: run.length,
|
|
599509
|
+
summary: commonDir(run.map((r) => r.summary))
|
|
599510
|
+
});
|
|
599511
|
+
} else {
|
|
599512
|
+
out.push({ ...e, count: 1 });
|
|
599513
|
+
}
|
|
599514
|
+
i = j;
|
|
599515
|
+
}
|
|
599516
|
+
rows = out;
|
|
599517
|
+
}
|
|
599518
|
+
const cap = Math.max(1, Math.floor(maxRows));
|
|
599519
|
+
if (rows.length > cap) {
|
|
599520
|
+
let toFold = rows.length - cap + 1;
|
|
599521
|
+
const fold = new Set;
|
|
599522
|
+
for (const wantOk of [true, false]) {
|
|
599523
|
+
for (let i = 0;i < rows.length && toFold > 0; i++) {
|
|
599524
|
+
if (fold.has(i) || wantOk && rows[i].status !== "ok")
|
|
599525
|
+
continue;
|
|
599526
|
+
fold.add(i);
|
|
599527
|
+
toFold--;
|
|
599528
|
+
}
|
|
599529
|
+
}
|
|
599530
|
+
const folded = rows.filter((_, i) => fold.has(i));
|
|
599531
|
+
const count = (s) => folded.filter((r) => r.status === s).reduce((n, r) => n + r.count, 0);
|
|
599532
|
+
const failed = count("fail");
|
|
599533
|
+
const blocked = count("blocked");
|
|
599534
|
+
const summary = {
|
|
599535
|
+
tool: "",
|
|
599536
|
+
summary: "",
|
|
599537
|
+
status: failed > 0 ? "fail" : blocked > 0 ? "blocked" : "ok",
|
|
599538
|
+
count: folded.reduce((n, r) => n + r.count, 0),
|
|
599539
|
+
folded: true,
|
|
599540
|
+
all: fold.size === rows.length
|
|
599541
|
+
};
|
|
599542
|
+
if (failed > 0)
|
|
599543
|
+
summary.failed = failed;
|
|
599544
|
+
if (blocked > 0)
|
|
599545
|
+
summary.blocked = blocked;
|
|
599546
|
+
rows = [summary, ...rows.filter((_, i) => !fold.has(i))];
|
|
599547
|
+
}
|
|
599548
|
+
return rows;
|
|
599549
|
+
}
|
|
599550
|
+
var ICONS = { ok: "\u2713", fail: "\u2717", blocked: "\u2298" };
|
|
599551
|
+
function formatTrailRow(row, width) {
|
|
599552
|
+
const icon = ICONS[row.status];
|
|
599553
|
+
const budget = Math.max(1, width - icon.length - 1);
|
|
599554
|
+
if (row.folded) {
|
|
599555
|
+
const parts = [`${row.count} ${row.all ? "calls" : "earlier calls"}`];
|
|
599556
|
+
if (row.failed)
|
|
599557
|
+
parts.push(`${row.failed} failed`);
|
|
599558
|
+
if (row.blocked)
|
|
599559
|
+
parts.push(`${row.blocked} blocked`);
|
|
599560
|
+
return { icon, text: clip(parts.join(", "), budget) };
|
|
599561
|
+
}
|
|
599562
|
+
const head = row.count > 1 ? `${row.tool} \xD7${row.count}` : row.tool;
|
|
599563
|
+
const tail = row.reason ? ` (${row.reason})` : "";
|
|
599564
|
+
let summary = row.count > 1 ? row.summary ? `(${row.summary}\u2026)` : "" : row.summary;
|
|
599565
|
+
if (!summary)
|
|
599566
|
+
return { icon, text: clip(`${head}${tail}`, budget) };
|
|
599567
|
+
const room = budget - head.length - 1 - tail.length;
|
|
599568
|
+
if (room < 4)
|
|
599569
|
+
return { icon, text: clip(`${head}${tail}`, budget) };
|
|
599570
|
+
if (summary.length > room)
|
|
599571
|
+
summary = `${summary.slice(0, room - 1)}\u2026`;
|
|
599572
|
+
return { icon, text: `${head} ${summary}${tail}` };
|
|
599573
|
+
}
|
|
599574
|
+
function clip(s, width) {
|
|
599575
|
+
return s.length <= width ? s : `${s.slice(0, Math.max(0, width - 1))}\u2026`;
|
|
599576
|
+
}
|
|
599577
|
+
function buildChatItems(messages) {
|
|
599578
|
+
const items = [];
|
|
599579
|
+
let pending = [];
|
|
599580
|
+
let pendingFirst = null;
|
|
599581
|
+
const flush = () => {
|
|
599582
|
+
if (pending.length > 0 && pendingFirst) {
|
|
599583
|
+
items.push({
|
|
599584
|
+
message: { ...pendingFirst, id: `trail-${pendingFirst.id}`, role: "tool", content: "" },
|
|
599585
|
+
trail: pending
|
|
599586
|
+
});
|
|
599587
|
+
}
|
|
599588
|
+
pending = [];
|
|
599589
|
+
pendingFirst = null;
|
|
599590
|
+
};
|
|
599591
|
+
for (const m of messages) {
|
|
599592
|
+
if (m.role === "tool") {
|
|
599593
|
+
if (m.toolTrail) {
|
|
599594
|
+
if (!pendingFirst)
|
|
599595
|
+
pendingFirst = m;
|
|
599596
|
+
pending.push(m.toolTrail);
|
|
599597
|
+
}
|
|
599598
|
+
continue;
|
|
599599
|
+
}
|
|
599600
|
+
if (m.role === "assistant") {
|
|
599601
|
+
items.push({ message: m, trail: pending });
|
|
599602
|
+
pending = [];
|
|
599603
|
+
pendingFirst = null;
|
|
599604
|
+
continue;
|
|
599605
|
+
}
|
|
599606
|
+
if (m.role === "user")
|
|
599607
|
+
flush();
|
|
599608
|
+
items.push({ message: m, trail: [] });
|
|
599609
|
+
}
|
|
599610
|
+
flush();
|
|
599611
|
+
return items;
|
|
599612
|
+
}
|
|
599613
|
+
|
|
599646
599614
|
// apps/tui/src/lib/activity-rail-derivation.ts
|
|
599647
599615
|
function deriveTools(messages, isProcessing, limit = 5) {
|
|
599648
599616
|
const ended = new Map;
|
|
@@ -600114,8 +600082,85 @@ function turnResultRows(trail, maxRows, plan) {
|
|
|
600114
600082
|
return buildTurnResults(trail, maxRows, plan).length;
|
|
600115
600083
|
}
|
|
600116
600084
|
|
|
600085
|
+
// apps/tui/src/components/ToolTrail.tsx
|
|
600086
|
+
var import_react58 = __toESM(require_react(), 1);
|
|
600087
|
+
var jsx_dev_runtime30 = __toESM(require_jsx_dev_runtime(), 1);
|
|
600088
|
+
function iconColor(status) {
|
|
600089
|
+
return status === "ok" ? t.green : status === "fail" ? t.red : t.orange;
|
|
600090
|
+
}
|
|
600091
|
+
function useLandingRows(total, animate) {
|
|
600092
|
+
const [shown, setShown] = import_react58.useState(total);
|
|
600093
|
+
const shownRef = import_react58.useRef(total);
|
|
600094
|
+
shownRef.current = shown;
|
|
600095
|
+
const landingRef = import_react58.useRef(null);
|
|
600096
|
+
import_react58.useEffect(() => {
|
|
600097
|
+
const from = shownRef.current;
|
|
600098
|
+
if (total <= from + 1 || !motionEnabled(animate)) {
|
|
600099
|
+
landingRef.current = null;
|
|
600100
|
+
setShown(total);
|
|
600101
|
+
return;
|
|
600102
|
+
}
|
|
600103
|
+
landingRef.current = total;
|
|
600104
|
+
const step = staggerFor(total - from);
|
|
600105
|
+
let n = from + 1;
|
|
600106
|
+
setShown(n);
|
|
600107
|
+
const id = setInterval(() => {
|
|
600108
|
+
n += 1;
|
|
600109
|
+
setShown(Math.min(total, n));
|
|
600110
|
+
if (n >= total) {
|
|
600111
|
+
landingRef.current = null;
|
|
600112
|
+
clearInterval(id);
|
|
600113
|
+
}
|
|
600114
|
+
}, step);
|
|
600115
|
+
return () => clearInterval(id);
|
|
600116
|
+
}, [total, animate]);
|
|
600117
|
+
if (landingRef.current === total)
|
|
600118
|
+
return Math.min(shown, total);
|
|
600119
|
+
if (total <= shown + 1)
|
|
600120
|
+
return total;
|
|
600121
|
+
return shown;
|
|
600122
|
+
}
|
|
600123
|
+
function ToolTrail({
|
|
600124
|
+
entries,
|
|
600125
|
+
width,
|
|
600126
|
+
maxRows,
|
|
600127
|
+
animate = true
|
|
600128
|
+
}) {
|
|
600129
|
+
const rows = collapseTrail(entries, maxRows);
|
|
600130
|
+
const visible = useLandingRows(rows.length, animate);
|
|
600131
|
+
if (rows.length === 0)
|
|
600132
|
+
return null;
|
|
600133
|
+
return /* @__PURE__ */ jsx_dev_runtime30.jsxDEV(Box_default, {
|
|
600134
|
+
flexDirection: "column",
|
|
600135
|
+
flexShrink: 0,
|
|
600136
|
+
children: rows.slice(0, visible).map((row, i) => {
|
|
600137
|
+
const { text } = formatTrailRow(row, width);
|
|
600138
|
+
const g = glyphs();
|
|
600139
|
+
const icon = row.status === "ok" ? g.ok : row.status === "fail" ? g.fail : g.blocked;
|
|
600140
|
+
return /* @__PURE__ */ jsx_dev_runtime30.jsxDEV(Box_default, {
|
|
600141
|
+
width,
|
|
600142
|
+
children: [
|
|
600143
|
+
/* @__PURE__ */ jsx_dev_runtime30.jsxDEV(Text, {
|
|
600144
|
+
color: iconColor(row.status),
|
|
600145
|
+
children: icon
|
|
600146
|
+
}, undefined, false, undefined, this),
|
|
600147
|
+
/* @__PURE__ */ jsx_dev_runtime30.jsxDEV(Text, {
|
|
600148
|
+
color: row.status === "ok" ? t.muted : t.textPrimary,
|
|
600149
|
+
wrap: "truncate-end",
|
|
600150
|
+
children: ` ${text}`
|
|
600151
|
+
}, undefined, false, undefined, this)
|
|
600152
|
+
]
|
|
600153
|
+
}, i, true, undefined, this);
|
|
600154
|
+
})
|
|
600155
|
+
}, undefined, false, undefined, this);
|
|
600156
|
+
}
|
|
600157
|
+
function toolTrailRows(entries, maxRows) {
|
|
600158
|
+
return entries.length === 0 ? 0 : collapseTrail(entries, maxRows).length;
|
|
600159
|
+
}
|
|
600160
|
+
|
|
600117
600161
|
// apps/tui/src/components/TurnResults.tsx
|
|
600118
|
-
var
|
|
600162
|
+
var import_react59 = __toESM(require_react(), 1);
|
|
600163
|
+
var jsx_dev_runtime31 = __toESM(require_jsx_dev_runtime(), 1);
|
|
600119
600164
|
function iconFor(status) {
|
|
600120
600165
|
const g = glyphs();
|
|
600121
600166
|
if (status === "ok")
|
|
@@ -600127,8 +600172,8 @@ function iconFor(status) {
|
|
|
600127
600172
|
return { icon: g.pending, color: t.muted };
|
|
600128
600173
|
}
|
|
600129
600174
|
function useResultLanding(total, land) {
|
|
600130
|
-
const [shown, setShown] =
|
|
600131
|
-
|
|
600175
|
+
const [shown, setShown] = import_react59.useState(land ? 0 : total);
|
|
600176
|
+
import_react59.useEffect(() => {
|
|
600132
600177
|
if (!land) {
|
|
600133
600178
|
setShown(total);
|
|
600134
600179
|
return;
|
|
@@ -600168,12 +600213,12 @@ function TurnResults({
|
|
|
600168
600213
|
const visible = useResultLanding(rows.length, land && motionEnabled(animate));
|
|
600169
600214
|
if (rows.length === 0)
|
|
600170
600215
|
return null;
|
|
600171
|
-
return /* @__PURE__ */
|
|
600216
|
+
return /* @__PURE__ */ jsx_dev_runtime31.jsxDEV(Box_default, {
|
|
600172
600217
|
flexDirection: "column",
|
|
600173
600218
|
flexShrink: 0,
|
|
600174
600219
|
children: rows.map((row, i) => {
|
|
600175
600220
|
if (i >= visible) {
|
|
600176
|
-
return /* @__PURE__ */
|
|
600221
|
+
return /* @__PURE__ */ jsx_dev_runtime31.jsxDEV(Box_default, {
|
|
600177
600222
|
height: 1,
|
|
600178
600223
|
width
|
|
600179
600224
|
}, i, false, undefined, this);
|
|
@@ -600181,55 +600226,55 @@ function TurnResults({
|
|
|
600181
600226
|
const { icon, color } = iconFor(row.status);
|
|
600182
600227
|
const fit = fitResultRow(row, width);
|
|
600183
600228
|
const quiet = row.status === "pending" || row.kind === "fold";
|
|
600184
|
-
return /* @__PURE__ */
|
|
600229
|
+
return /* @__PURE__ */ jsx_dev_runtime31.jsxDEV(Box_default, {
|
|
600185
600230
|
width,
|
|
600186
600231
|
height: 1,
|
|
600187
|
-
children: /* @__PURE__ */
|
|
600232
|
+
children: /* @__PURE__ */ jsx_dev_runtime31.jsxDEV(Text, {
|
|
600188
600233
|
wrap: "truncate-end",
|
|
600189
600234
|
children: [
|
|
600190
|
-
/* @__PURE__ */
|
|
600235
|
+
/* @__PURE__ */ jsx_dev_runtime31.jsxDEV(Text, {
|
|
600191
600236
|
color,
|
|
600192
600237
|
children: icon
|
|
600193
600238
|
}, undefined, false, undefined, this),
|
|
600194
|
-
/* @__PURE__ */
|
|
600239
|
+
/* @__PURE__ */ jsx_dev_runtime31.jsxDEV(Text, {
|
|
600195
600240
|
children: " "
|
|
600196
600241
|
}, undefined, false, undefined, this),
|
|
600197
|
-
/* @__PURE__ */
|
|
600242
|
+
/* @__PURE__ */ jsx_dev_runtime31.jsxDEV(Text, {
|
|
600198
600243
|
bold: !quiet,
|
|
600199
600244
|
color: quiet ? t.muted : t.textPrimary,
|
|
600200
600245
|
children: fit.verb
|
|
600201
600246
|
}, undefined, false, undefined, this),
|
|
600202
|
-
fit.spans ? /* @__PURE__ */
|
|
600247
|
+
fit.spans ? /* @__PURE__ */ jsx_dev_runtime31.jsxDEV(jsx_dev_runtime31.Fragment, {
|
|
600203
600248
|
children: [
|
|
600204
|
-
fit.verb ? /* @__PURE__ */
|
|
600249
|
+
fit.verb ? /* @__PURE__ */ jsx_dev_runtime31.jsxDEV(Text, {
|
|
600205
600250
|
children: " "
|
|
600206
600251
|
}, undefined, false, undefined, this) : null,
|
|
600207
|
-
fit.spans.map((s, j) => s.code ? /* @__PURE__ */
|
|
600252
|
+
fit.spans.map((s, j) => s.code ? /* @__PURE__ */ jsx_dev_runtime31.jsxDEV(Text, {
|
|
600208
600253
|
color: t.textPrimary,
|
|
600209
600254
|
backgroundColor: t.border,
|
|
600210
600255
|
children: s.text
|
|
600211
|
-
}, j, false, undefined, this) : /* @__PURE__ */
|
|
600256
|
+
}, j, false, undefined, this) : /* @__PURE__ */ jsx_dev_runtime31.jsxDEV(Text, {
|
|
600212
600257
|
color: quiet ? t.muted : t.textSecondary,
|
|
600213
600258
|
children: s.text
|
|
600214
600259
|
}, j, false, undefined, this))
|
|
600215
600260
|
]
|
|
600216
|
-
}, undefined, true, undefined, this) : fit.text ? /* @__PURE__ */
|
|
600261
|
+
}, undefined, true, undefined, this) : fit.text ? /* @__PURE__ */ jsx_dev_runtime31.jsxDEV(Text, {
|
|
600217
600262
|
color: quiet ? t.muted : t.textSecondary,
|
|
600218
600263
|
children: ` ${fit.text}`
|
|
600219
600264
|
}, undefined, false, undefined, this) : null,
|
|
600220
|
-
fit.chip ? /* @__PURE__ */
|
|
600265
|
+
fit.chip ? /* @__PURE__ */ jsx_dev_runtime31.jsxDEV(jsx_dev_runtime31.Fragment, {
|
|
600221
600266
|
children: [
|
|
600222
|
-
/* @__PURE__ */
|
|
600267
|
+
/* @__PURE__ */ jsx_dev_runtime31.jsxDEV(Text, {
|
|
600223
600268
|
children: " "
|
|
600224
600269
|
}, undefined, false, undefined, this),
|
|
600225
|
-
/* @__PURE__ */
|
|
600270
|
+
/* @__PURE__ */ jsx_dev_runtime31.jsxDEV(Text, {
|
|
600226
600271
|
color: t.textPrimary,
|
|
600227
600272
|
backgroundColor: t.border,
|
|
600228
600273
|
children: ` ${fit.chip} `
|
|
600229
600274
|
}, undefined, false, undefined, this)
|
|
600230
600275
|
]
|
|
600231
600276
|
}, undefined, true, undefined, this) : null,
|
|
600232
|
-
fit.note ? /* @__PURE__ */
|
|
600277
|
+
fit.note ? /* @__PURE__ */ jsx_dev_runtime31.jsxDEV(Text, {
|
|
600233
600278
|
color: row.status === "fail" ? t.red : t.muted,
|
|
600234
600279
|
children: `${" ".repeat(fit.noteGap ?? 2)}${fit.note}`
|
|
600235
600280
|
}, undefined, false, undefined, this) : null
|
|
@@ -600240,6 +600285,32 @@ function TurnResults({
|
|
|
600240
600285
|
}, undefined, false, undefined, this);
|
|
600241
600286
|
}
|
|
600242
600287
|
|
|
600288
|
+
// apps/tui/src/components/fade-transition.tsx
|
|
600289
|
+
var import_react60 = __toESM(require_react(), 1);
|
|
600290
|
+
var jsx_dev_runtime32 = __toESM(require_jsx_dev_runtime(), 1);
|
|
600291
|
+
function FadeIn({ children, duration = 300, delay = 0, onComplete }) {
|
|
600292
|
+
const [started, setStarted] = import_react60.useState(false);
|
|
600293
|
+
import_react60.useEffect(() => {
|
|
600294
|
+
const timeout = setTimeout(() => {
|
|
600295
|
+
setStarted(true);
|
|
600296
|
+
}, delay);
|
|
600297
|
+
return () => clearTimeout(timeout);
|
|
600298
|
+
}, [delay]);
|
|
600299
|
+
import_react60.useEffect(() => {
|
|
600300
|
+
if (!started)
|
|
600301
|
+
return;
|
|
600302
|
+
const timeout = setTimeout(() => {
|
|
600303
|
+
onComplete?.();
|
|
600304
|
+
}, duration);
|
|
600305
|
+
return () => clearTimeout(timeout);
|
|
600306
|
+
}, [started, duration, onComplete]);
|
|
600307
|
+
if (!started)
|
|
600308
|
+
return null;
|
|
600309
|
+
return /* @__PURE__ */ jsx_dev_runtime32.jsxDEV(Box_default, {
|
|
600310
|
+
children
|
|
600311
|
+
}, undefined, false, undefined, this);
|
|
600312
|
+
}
|
|
600313
|
+
|
|
600243
600314
|
// apps/tui/src/components/sound-effects.tsx
|
|
600244
600315
|
var import_react61 = __toESM(require_react(), 1);
|
|
600245
600316
|
var BELL = "\x07";
|
|
@@ -600652,6 +600723,7 @@ function MessageList({
|
|
|
600652
600723
|
showAnimations,
|
|
600653
600724
|
isLatestAssistant: message.id === lastAssistantId,
|
|
600654
600725
|
trail: trailById.get(message.id) ?? [],
|
|
600726
|
+
turnRunning,
|
|
600655
600727
|
trailMaxRows: trailCaps.get(message.id),
|
|
600656
600728
|
onAnimationStart: (id) => {
|
|
600657
600729
|
animatedIdsRef.current.add(id);
|
|
@@ -600683,6 +600755,7 @@ function MessageItem({
|
|
|
600683
600755
|
showAnimations,
|
|
600684
600756
|
isLatestAssistant = false,
|
|
600685
600757
|
trail = [],
|
|
600758
|
+
turnRunning = false,
|
|
600686
600759
|
trailMaxRows,
|
|
600687
600760
|
onAnimationStart
|
|
600688
600761
|
}) {
|
|
@@ -600868,7 +600941,7 @@ function MessageItem({
|
|
|
600868
600941
|
animate: showAnimations
|
|
600869
600942
|
}, undefined, false, undefined, this)
|
|
600870
600943
|
}, undefined, false, undefined, this),
|
|
600871
|
-
!isUser && !message.content.trim() && trail.length > 0 ? /* @__PURE__ */ jsx_dev_runtime34.jsxDEV(MutedText, {
|
|
600944
|
+
!isUser && !turnRunning && !message.content.trim() && trail.length > 0 ? /* @__PURE__ */ jsx_dev_runtime34.jsxDEV(MutedText, {
|
|
600872
600945
|
children: "No reply."
|
|
600873
600946
|
}, undefined, false, undefined, this) : null,
|
|
600874
600947
|
message.content.trim() || trail.length === 0 ? /* @__PURE__ */ jsx_dev_runtime34.jsxDEV(Box_default, {
|
|
@@ -601030,7 +601103,11 @@ function MarkdownBody({
|
|
|
601030
601103
|
})
|
|
601031
601104
|
}, undefined, false, undefined, this);
|
|
601032
601105
|
}
|
|
601033
|
-
function InlineSpans({
|
|
601106
|
+
function InlineSpans({
|
|
601107
|
+
spans,
|
|
601108
|
+
color,
|
|
601109
|
+
adhdMode
|
|
601110
|
+
}) {
|
|
601034
601111
|
return /* @__PURE__ */ jsx_dev_runtime34.jsxDEV(Text, {
|
|
601035
601112
|
color,
|
|
601036
601113
|
wrap: "wrap",
|
|
@@ -603441,7 +603518,7 @@ init_cloud_transcriber();
|
|
|
603441
603518
|
init_types5();
|
|
603442
603519
|
|
|
603443
603520
|
// packages/voice/voice-chat.ts
|
|
603444
|
-
import { existsSync as
|
|
603521
|
+
import { existsSync as existsSync115, unlinkSync as unlinkSync5 } from "fs";
|
|
603445
603522
|
import { tmpdir as tmpdir21 } from "os";
|
|
603446
603523
|
import { join as join172 } from "path";
|
|
603447
603524
|
|
|
@@ -603900,7 +603977,7 @@ class VoiceChatLoop {
|
|
|
603900
603977
|
cleanupFile(wavPath);
|
|
603901
603978
|
throw new VoiceChatFatalError(describeRecFailure(exitCode, why));
|
|
603902
603979
|
}
|
|
603903
|
-
if (!
|
|
603980
|
+
if (!existsSync115(wavPath)) {
|
|
603904
603981
|
this.reportError("No audio was recorded. Check that your microphone is the system input.");
|
|
603905
603982
|
return null;
|
|
603906
603983
|
}
|
|
@@ -604024,7 +604101,7 @@ function sleep2(ms) {
|
|
|
604024
604101
|
}
|
|
604025
604102
|
function cleanupFile(path) {
|
|
604026
604103
|
try {
|
|
604027
|
-
if (
|
|
604104
|
+
if (existsSync115(path))
|
|
604028
604105
|
unlinkSync5(path);
|
|
604029
604106
|
} catch {}
|
|
604030
604107
|
}
|
|
@@ -604084,7 +604161,7 @@ function splitIntoSentences(text) {
|
|
|
604084
604161
|
}
|
|
604085
604162
|
// packages/voice/full-duplex-provider.ts
|
|
604086
604163
|
import { execSync as execSync6 } from "child_process";
|
|
604087
|
-
import { existsSync as
|
|
604164
|
+
import { existsSync as existsSync116 } from "fs";
|
|
604088
604165
|
import { homedir as homedir87 } from "os";
|
|
604089
604166
|
import { join as join173 } from "path";
|
|
604090
604167
|
var MOSHI_HF_CACHE_PATH = join173(homedir87(), ".cache", "huggingface", "hub", "models--kyutai--moshiko-pytorch-bf16", "snapshots");
|
|
@@ -604102,7 +604179,7 @@ async function detectCapabilities() {
|
|
|
604102
604179
|
const hasAppleSilicon = platform === "darwin" && arch === "arm64";
|
|
604103
604180
|
const hasMLX = hasAppleSilicon && tryExec('python3 -c "import mlx"');
|
|
604104
604181
|
const hasMoshiInstalled = tryExec('python3 -c "import moshi"');
|
|
604105
|
-
const hasMoshiModel =
|
|
604182
|
+
const hasMoshiModel = existsSync116(MOSHI_HF_CACHE_PATH);
|
|
604106
604183
|
const hasCUDA = tryExec("nvidia-smi");
|
|
604107
604184
|
const hasNIMKey = !!process.env.NVIDIA_NIM_KEY;
|
|
604108
604185
|
return {
|
|
@@ -605133,7 +605210,7 @@ function useWorkspaceTabs() {
|
|
|
605133
605210
|
}
|
|
605134
605211
|
|
|
605135
605212
|
// apps/tui/src/lib/adhd-audio.ts
|
|
605136
|
-
import { existsSync as
|
|
605213
|
+
import { existsSync as existsSync118, mkdirSync as mkdirSync82 } from "fs";
|
|
605137
605214
|
import { join as join176 } from "path";
|
|
605138
605215
|
var {spawn: spawn28 } = globalThis.Bun;
|
|
605139
605216
|
var DEFAULT_CONFIG4 = {
|
|
@@ -605178,7 +605255,7 @@ var CACHE_DIR3 = join176(process.env.HOME || "~", ".8gent", "adhd-audio");
|
|
|
605178
605255
|
var CONFIG_PATH = join176(CACHE_DIR3, "config.json");
|
|
605179
605256
|
function loadConfig2() {
|
|
605180
605257
|
try {
|
|
605181
|
-
if (
|
|
605258
|
+
if (existsSync118(CONFIG_PATH)) {
|
|
605182
605259
|
const raw = JSON.parse(__require("fs").readFileSync(CONFIG_PATH, "utf-8"));
|
|
605183
605260
|
return { ...DEFAULT_CONFIG4, ...raw };
|
|
605184
605261
|
}
|
|
@@ -605187,7 +605264,7 @@ function loadConfig2() {
|
|
|
605187
605264
|
}
|
|
605188
605265
|
function saveConfig2(config) {
|
|
605189
605266
|
try {
|
|
605190
|
-
if (!
|
|
605267
|
+
if (!existsSync118(CACHE_DIR3))
|
|
605191
605268
|
mkdirSync82(CACHE_DIR3, { recursive: true });
|
|
605192
605269
|
__require("fs").writeFileSync(CONFIG_PATH, JSON.stringify(config, null, 2));
|
|
605193
605270
|
} catch {}
|
|
@@ -605199,7 +605276,7 @@ class ADHDAudio {
|
|
|
605199
605276
|
generating = false;
|
|
605200
605277
|
_config;
|
|
605201
605278
|
constructor() {
|
|
605202
|
-
if (!
|
|
605279
|
+
if (!existsSync118(CACHE_DIR3)) {
|
|
605203
605280
|
mkdirSync82(CACHE_DIR3, { recursive: true });
|
|
605204
605281
|
}
|
|
605205
605282
|
this._config = loadConfig2();
|
|
@@ -605226,7 +605303,7 @@ class ADHDAudio {
|
|
|
605226
605303
|
for (const soundscape of Object.keys(SOUNDSCAPES)) {
|
|
605227
605304
|
const path = this.getCachePath(soundscape);
|
|
605228
605305
|
try {
|
|
605229
|
-
if (
|
|
605306
|
+
if (existsSync118(path))
|
|
605230
605307
|
__require("fs").unlinkSync(path);
|
|
605231
605308
|
} catch {}
|
|
605232
605309
|
}
|
|
@@ -605245,7 +605322,7 @@ class ADHDAudio {
|
|
|
605245
605322
|
return join176(CACHE_DIR3, `${soundscape}.mp3`);
|
|
605246
605323
|
}
|
|
605247
605324
|
hasCached(soundscape) {
|
|
605248
|
-
return
|
|
605325
|
+
return existsSync118(this.getCachePath(soundscape));
|
|
605249
605326
|
}
|
|
605250
605327
|
async generate(soundscape) {
|
|
605251
605328
|
const preset = SOUNDSCAPES[soundscape];
|
|
@@ -610150,7 +610227,7 @@ function snapshot(manager) {
|
|
|
610150
610227
|
|
|
610151
610228
|
// apps/tui/src/hooks/useBodyParts.ts
|
|
610152
610229
|
var import_react83 = __toESM(require_react(), 1);
|
|
610153
|
-
import { existsSync as
|
|
610230
|
+
import { existsSync as existsSync123 } from "fs";
|
|
610154
610231
|
import { execSync as execSync8 } from "child_process";
|
|
610155
610232
|
import { homedir as homedir90 } from "os";
|
|
610156
610233
|
import { join as join187 } from "path";
|
|
@@ -610164,7 +610241,7 @@ function hasCliclick() {
|
|
|
610164
610241
|
}
|
|
610165
610242
|
}
|
|
610166
610243
|
function hasAxBridge() {
|
|
610167
|
-
return
|
|
610244
|
+
return existsSync123(join187(homedir90(), ".8gent", "bin", "8gent-ax-bridge"));
|
|
610168
610245
|
}
|
|
610169
610246
|
function detectDefaultBodyPartsState() {
|
|
610170
610247
|
const handsOk = hasCliclick();
|
|
@@ -611752,6 +611829,24 @@ ${r.message}`;
|
|
|
611752
611829
|
// apps/tui/src/app.tsx
|
|
611753
611830
|
init_slash_commands();
|
|
611754
611831
|
|
|
611832
|
+
// apps/tui/src/lib/term-intent.ts
|
|
611833
|
+
var VERBS2 = "run|open|start|launch|fire up|spin up|boot";
|
|
611834
|
+
var POLITE = "(?:please\\s+|can you\\s+|could you\\s+)?";
|
|
611835
|
+
var WHERE = "(?:\\s+in\\s+(?:a\\s+)?(?:new\\s+)?(?:tab|terminal(?:\\s+tab)?))?";
|
|
611836
|
+
var PRESET_INTENT = new RegExp(`^${POLITE}(?:${VERBS2})\\s+(?:up\\s+)?([a-z0-9][a-z0-9_-]*)(${WHERE})(?:\\s+please)?$`);
|
|
611837
|
+
function detectTermPresetIntent(input, presetIds) {
|
|
611838
|
+
const text = input.trim().toLowerCase().replace(/[.!?]+$/, "").replace(/\s+/g, " ");
|
|
611839
|
+
if (!text || text.length > 60)
|
|
611840
|
+
return null;
|
|
611841
|
+
const m = PRESET_INTENT.exec(text);
|
|
611842
|
+
if (!m)
|
|
611843
|
+
return null;
|
|
611844
|
+
const id = presetIds.find((p) => p.toLowerCase() === m[1]);
|
|
611845
|
+
if (!id)
|
|
611846
|
+
return null;
|
|
611847
|
+
return m[2] ? [id, "--in-tab"] : [id];
|
|
611848
|
+
}
|
|
611849
|
+
|
|
611755
611850
|
// apps/tui/src/lib/turn-outcome.ts
|
|
611756
611851
|
init_local_turn_error();
|
|
611757
611852
|
function turnEndedInError(messages) {
|
|
@@ -611769,7 +611864,7 @@ function turnEndedInError(messages) {
|
|
|
611769
611864
|
}
|
|
611770
611865
|
|
|
611771
611866
|
// apps/tui/src/screens/BTWView.tsx
|
|
611772
|
-
import { existsSync as
|
|
611867
|
+
import { existsSync as existsSync125, mkdirSync as mkdirSync89, readFileSync as readFileSync112, writeFileSync as writeFileSync69 } from "fs";
|
|
611773
611868
|
import { join as join189 } from "path";
|
|
611774
611869
|
var import_react85 = __toESM(require_react(), 1);
|
|
611775
611870
|
|
|
@@ -611785,10 +611880,10 @@ var jsx_dev_runtime50 = __toESM(require_jsx_dev_runtime(), 1);
|
|
|
611785
611880
|
var DATA_DIR5 = join189(process.env.HOME || "~", ".8gent", "tabs");
|
|
611786
611881
|
function loadBTW() {
|
|
611787
611882
|
try {
|
|
611788
|
-
if (!
|
|
611883
|
+
if (!existsSync125(DATA_DIR5))
|
|
611789
611884
|
mkdirSync89(DATA_DIR5, { recursive: true });
|
|
611790
611885
|
const filepath = join189(DATA_DIR5, "btw.json");
|
|
611791
|
-
if (
|
|
611886
|
+
if (existsSync125(filepath)) {
|
|
611792
611887
|
const raw = JSON.parse(readFileSync112(filepath, "utf-8"));
|
|
611793
611888
|
return raw.items || [];
|
|
611794
611889
|
}
|
|
@@ -611797,7 +611892,7 @@ function loadBTW() {
|
|
|
611797
611892
|
}
|
|
611798
611893
|
function saveBTW(items) {
|
|
611799
611894
|
try {
|
|
611800
|
-
if (!
|
|
611895
|
+
if (!existsSync125(DATA_DIR5))
|
|
611801
611896
|
mkdirSync89(DATA_DIR5, { recursive: true });
|
|
611802
611897
|
writeFileSync69(join189(DATA_DIR5, "btw.json"), JSON.stringify({ items }, null, 2));
|
|
611803
611898
|
} catch {}
|
|
@@ -612132,17 +612227,17 @@ function HistoryScreen({ conversations, onSelect, onBack }) {
|
|
|
612132
612227
|
}
|
|
612133
612228
|
|
|
612134
612229
|
// apps/tui/src/screens/IdeasView.tsx
|
|
612135
|
-
import { existsSync as
|
|
612230
|
+
import { existsSync as existsSync126, mkdirSync as mkdirSync90, readFileSync as readFileSync113, writeFileSync as writeFileSync70 } from "fs";
|
|
612136
612231
|
import { join as join190 } from "path";
|
|
612137
612232
|
var import_react87 = __toESM(require_react(), 1);
|
|
612138
612233
|
var jsx_dev_runtime52 = __toESM(require_jsx_dev_runtime(), 1);
|
|
612139
612234
|
var DATA_DIR6 = join190(process.env.HOME || "~", ".8gent", "tabs");
|
|
612140
612235
|
function loadIdeas() {
|
|
612141
612236
|
try {
|
|
612142
|
-
if (!
|
|
612237
|
+
if (!existsSync126(DATA_DIR6))
|
|
612143
612238
|
mkdirSync90(DATA_DIR6, { recursive: true });
|
|
612144
612239
|
const filepath = join190(DATA_DIR6, "ideas.json");
|
|
612145
|
-
if (
|
|
612240
|
+
if (existsSync126(filepath)) {
|
|
612146
612241
|
const raw = JSON.parse(readFileSync113(filepath, "utf-8"));
|
|
612147
612242
|
return raw.ideas || [];
|
|
612148
612243
|
}
|
|
@@ -612151,7 +612246,7 @@ function loadIdeas() {
|
|
|
612151
612246
|
}
|
|
612152
612247
|
function saveIdeas(ideas) {
|
|
612153
612248
|
try {
|
|
612154
|
-
if (!
|
|
612249
|
+
if (!existsSync126(DATA_DIR6))
|
|
612155
612250
|
mkdirSync90(DATA_DIR6, { recursive: true });
|
|
612156
612251
|
writeFileSync70(join190(DATA_DIR6, "ideas.json"), JSON.stringify({ ideas }, null, 2));
|
|
612157
612252
|
} catch {}
|
|
@@ -612614,7 +612709,7 @@ function KeyVaultScreen({
|
|
|
612614
612709
|
}
|
|
612615
612710
|
|
|
612616
612711
|
// apps/tui/src/screens/MusicPlayerView.tsx
|
|
612617
|
-
import { existsSync as
|
|
612712
|
+
import { existsSync as existsSync127, readdirSync as readdirSync28, statSync as statSync38 } from "fs";
|
|
612618
612713
|
import { basename as basename53, join as join191 } from "path";
|
|
612619
612714
|
var import_react89 = __toESM(require_react(), 1);
|
|
612620
612715
|
var jsx_dev_runtime54 = __toESM(require_jsx_dev_runtime(), 1);
|
|
@@ -612636,7 +612731,7 @@ function formatDate(date) {
|
|
|
612636
612731
|
}
|
|
612637
612732
|
function loadTracks(currentTrack) {
|
|
612638
612733
|
const tracks = [];
|
|
612639
|
-
if (!
|
|
612734
|
+
if (!existsSync127(CACHE_DIR4))
|
|
612640
612735
|
return tracks;
|
|
612641
612736
|
try {
|
|
612642
612737
|
const files = readdirSync28(CACHE_DIR4).filter((f) => f.endsWith(".mp3") || f.endsWith(".wav"));
|
|
@@ -613145,7 +613240,7 @@ function NarratorView({ tasks, narratorText, maxHeight }) {
|
|
|
613145
613240
|
}
|
|
613146
613241
|
|
|
613147
613242
|
// apps/tui/src/screens/NotesView.tsx
|
|
613148
|
-
import { existsSync as
|
|
613243
|
+
import { existsSync as existsSync128, mkdirSync as mkdirSync91, readFileSync as readFileSync114, writeFileSync as writeFileSync71 } from "fs";
|
|
613149
613244
|
import { join as join192 } from "path";
|
|
613150
613245
|
var import_react91 = __toESM(require_react(), 1);
|
|
613151
613246
|
var jsx_dev_runtime59 = __toESM(require_jsx_dev_runtime(), 1);
|
|
@@ -613153,10 +613248,10 @@ var DATA_DIR7 = join192(process.env.HOME || "~", ".8gent", "tabs");
|
|
|
613153
613248
|
var EMPTY_TAB_NAMES = [];
|
|
613154
613249
|
function loadNotes() {
|
|
613155
613250
|
try {
|
|
613156
|
-
if (!
|
|
613251
|
+
if (!existsSync128(DATA_DIR7))
|
|
613157
613252
|
mkdirSync91(DATA_DIR7, { recursive: true });
|
|
613158
613253
|
const filepath = join192(DATA_DIR7, "notes.json");
|
|
613159
|
-
if (
|
|
613254
|
+
if (existsSync128(filepath)) {
|
|
613160
613255
|
const raw = JSON.parse(readFileSync114(filepath, "utf-8"));
|
|
613161
613256
|
return raw.notes || [];
|
|
613162
613257
|
}
|
|
@@ -613165,7 +613260,7 @@ function loadNotes() {
|
|
|
613165
613260
|
}
|
|
613166
613261
|
function saveNotes(notes) {
|
|
613167
613262
|
try {
|
|
613168
|
-
if (!
|
|
613263
|
+
if (!existsSync128(DATA_DIR7))
|
|
613169
613264
|
mkdirSync91(DATA_DIR7, { recursive: true });
|
|
613170
613265
|
writeFileSync71(join192(DATA_DIR7, "notes.json"), JSON.stringify({ notes }, null, 2));
|
|
613171
613266
|
} catch {}
|
|
@@ -614360,7 +614455,7 @@ function OnboardingScreen({
|
|
|
614360
614455
|
|
|
614361
614456
|
// apps/tui/src/screens/ProjectsView.tsx
|
|
614362
614457
|
import { execSync as execSync9 } from "child_process";
|
|
614363
|
-
import { existsSync as
|
|
614458
|
+
import { existsSync as existsSync129, mkdirSync as mkdirSync92, readFileSync as readFileSync115, readdirSync as readdirSync29, statSync as statSync39, writeFileSync as writeFileSync72 } from "fs";
|
|
614364
614459
|
import { homedir as homedir91 } from "os";
|
|
614365
614460
|
import { basename as basename54, join as join193 } from "path";
|
|
614366
614461
|
var import_react96 = __toESM(require_react(), 1);
|
|
@@ -614375,7 +614470,7 @@ var SCAN_DIRS = [
|
|
|
614375
614470
|
var PROJECT_MARKERS = ["package.json", ".git", "CLAUDE.md", ".8gent"];
|
|
614376
614471
|
function isProjectDir(dirPath) {
|
|
614377
614472
|
try {
|
|
614378
|
-
return PROJECT_MARKERS.some((marker) =>
|
|
614473
|
+
return PROJECT_MARKERS.some((marker) => existsSync129(join193(dirPath, marker)));
|
|
614379
614474
|
} catch {
|
|
614380
614475
|
return false;
|
|
614381
614476
|
}
|
|
@@ -614383,7 +614478,7 @@ function isProjectDir(dirPath) {
|
|
|
614383
614478
|
function getProjectName(dirPath) {
|
|
614384
614479
|
try {
|
|
614385
614480
|
const pkgPath = join193(dirPath, "package.json");
|
|
614386
|
-
if (
|
|
614481
|
+
if (existsSync129(pkgPath)) {
|
|
614387
614482
|
const pkg = JSON.parse(readFileSync115(pkgPath, "utf8"));
|
|
614388
614483
|
if (pkg.name)
|
|
614389
614484
|
return pkg.name;
|
|
@@ -614393,7 +614488,7 @@ function getProjectName(dirPath) {
|
|
|
614393
614488
|
}
|
|
614394
614489
|
function getGitBranch2(dirPath) {
|
|
614395
614490
|
try {
|
|
614396
|
-
if (!
|
|
614491
|
+
if (!existsSync129(join193(dirPath, ".git")))
|
|
614397
614492
|
return;
|
|
614398
614493
|
const result = execSync9(`git -C "${dirPath}" branch --show-current 2>/dev/null`, {
|
|
614399
614494
|
encoding: "utf8",
|
|
@@ -614413,7 +614508,7 @@ function getLastModified(dirPath) {
|
|
|
614413
614508
|
}
|
|
614414
614509
|
}
|
|
614415
614510
|
function has8gent(dirPath) {
|
|
614416
|
-
return
|
|
614511
|
+
return existsSync129(join193(dirPath, ".8gent"));
|
|
614417
614512
|
}
|
|
614418
614513
|
function buildProjectEntry(dirPath) {
|
|
614419
614514
|
return {
|
|
@@ -614430,7 +614525,7 @@ function scanForProjects(currentPath) {
|
|
|
614430
614525
|
found.add(currentPath);
|
|
614431
614526
|
results.push(buildProjectEntry(currentPath));
|
|
614432
614527
|
for (const scanDir of SCAN_DIRS) {
|
|
614433
|
-
if (!
|
|
614528
|
+
if (!existsSync129(scanDir))
|
|
614434
614529
|
continue;
|
|
614435
614530
|
try {
|
|
614436
614531
|
const entries = readdirSync29(scanDir, { withFileTypes: true });
|
|
@@ -614462,7 +614557,7 @@ function scanForProjects(currentPath) {
|
|
|
614462
614557
|
}
|
|
614463
614558
|
function loadSavedProjects() {
|
|
614464
614559
|
try {
|
|
614465
|
-
if (!
|
|
614560
|
+
if (!existsSync129(SAVED_PROJECTS_PATH))
|
|
614466
614561
|
return [];
|
|
614467
614562
|
const raw = readFileSync115(SAVED_PROJECTS_PATH, "utf8");
|
|
614468
614563
|
const data = JSON.parse(raw);
|
|
@@ -614485,7 +614580,7 @@ function mergeProjects(scanned, saved) {
|
|
|
614485
614580
|
for (const s of saved) {
|
|
614486
614581
|
if (paths.has(s.path))
|
|
614487
614582
|
continue;
|
|
614488
|
-
if (!
|
|
614583
|
+
if (!existsSync129(s.path))
|
|
614489
614584
|
continue;
|
|
614490
614585
|
paths.add(s.path);
|
|
614491
614586
|
extra.push(buildProjectEntry(s.path));
|
|
@@ -614553,7 +614648,7 @@ function ProjectsView({
|
|
|
614553
614648
|
if (addMode) {
|
|
614554
614649
|
if (key.return) {
|
|
614555
614650
|
const trimmed = addInput.trim();
|
|
614556
|
-
if (trimmed &&
|
|
614651
|
+
if (trimmed && existsSync129(trimmed)) {
|
|
614557
614652
|
const newEntry = {
|
|
614558
614653
|
...buildProjectEntry(trimmed),
|
|
614559
614654
|
addedAt: new Date().toISOString()
|
|
@@ -614740,17 +614835,17 @@ function ProjectsView({
|
|
|
614740
614835
|
}
|
|
614741
614836
|
|
|
614742
614837
|
// apps/tui/src/screens/QuestionsView.tsx
|
|
614743
|
-
import { existsSync as
|
|
614838
|
+
import { existsSync as existsSync130, mkdirSync as mkdirSync93, readFileSync as readFileSync116, writeFileSync as writeFileSync73 } from "fs";
|
|
614744
614839
|
import { join as join194 } from "path";
|
|
614745
614840
|
var import_react97 = __toESM(require_react(), 1);
|
|
614746
614841
|
var jsx_dev_runtime62 = __toESM(require_jsx_dev_runtime(), 1);
|
|
614747
614842
|
var DATA_DIR8 = join194(process.env.HOME || "~", ".8gent", "tabs");
|
|
614748
614843
|
function loadQuestions() {
|
|
614749
614844
|
try {
|
|
614750
|
-
if (!
|
|
614845
|
+
if (!existsSync130(DATA_DIR8))
|
|
614751
614846
|
mkdirSync93(DATA_DIR8, { recursive: true });
|
|
614752
614847
|
const filepath = join194(DATA_DIR8, "questions.json");
|
|
614753
|
-
if (
|
|
614848
|
+
if (existsSync130(filepath)) {
|
|
614754
614849
|
const raw = JSON.parse(readFileSync116(filepath, "utf-8"));
|
|
614755
614850
|
return raw.questions || [];
|
|
614756
614851
|
}
|
|
@@ -614759,7 +614854,7 @@ function loadQuestions() {
|
|
|
614759
614854
|
}
|
|
614760
614855
|
function saveQuestions(questions) {
|
|
614761
614856
|
try {
|
|
614762
|
-
if (!
|
|
614857
|
+
if (!existsSync130(DATA_DIR8))
|
|
614763
614858
|
mkdirSync93(DATA_DIR8, { recursive: true });
|
|
614764
614859
|
writeFileSync73(join194(DATA_DIR8, "questions.json"), JSON.stringify({ questions }, null, 2));
|
|
614765
614860
|
} catch {}
|
|
@@ -616047,13 +616142,13 @@ import * as fs104 from "fs";
|
|
|
616047
616142
|
import * as pathMod from "path";
|
|
616048
616143
|
|
|
616049
616144
|
// apps/tui/src/lib/package-scripts.ts
|
|
616050
|
-
import { existsSync as
|
|
616051
|
-
import { join as join195, resolve as
|
|
616145
|
+
import { existsSync as existsSync131 } from "fs";
|
|
616146
|
+
import { join as join195, resolve as resolve74 } from "path";
|
|
616052
616147
|
var __dirname = (import.meta.dir + "/../apps/tui/src/lib");
|
|
616053
|
-
var PACKAGE_ROOT =
|
|
616148
|
+
var PACKAGE_ROOT = resolve74(__dirname, "../../../..");
|
|
616054
616149
|
function packageBinScript(name, root = PACKAGE_ROOT) {
|
|
616055
616150
|
const candidate = join195(root, "bin", name);
|
|
616056
|
-
return
|
|
616151
|
+
return existsSync131(candidate) ? candidate : null;
|
|
616057
616152
|
}
|
|
616058
616153
|
|
|
616059
616154
|
// apps/tui/src/app.tsx
|
|
@@ -620977,6 +621072,26 @@ ${found.slice(0, 40).map((k) => ` ${k.name} ${k.description}`).join(`
|
|
|
620977
621072
|
}
|
|
620978
621073
|
return;
|
|
620979
621074
|
}
|
|
621075
|
+
if (input && !attached) {
|
|
621076
|
+
const termArgs = detectTermPresetIntent(input, listPresetIds());
|
|
621077
|
+
if (termArgs) {
|
|
621078
|
+
appendToTab(tabId, {
|
|
621079
|
+
id: `user-${Date.now()}`,
|
|
621080
|
+
role: "user",
|
|
621081
|
+
content: bubbleContent,
|
|
621082
|
+
timestamp: new Date
|
|
621083
|
+
});
|
|
621084
|
+
setRecentCommands((prev) => [bubbleContent, ...prev].slice(0, 20));
|
|
621085
|
+
const refused = planModeRefusal2(permView(permHolderFor(tabId)).mode);
|
|
621086
|
+
if (refused) {
|
|
621087
|
+
addSystemMessage(refused);
|
|
621088
|
+
return;
|
|
621089
|
+
}
|
|
621090
|
+
addSystemMessage(`Opening ${termArgs[0]} (same as /term ${termArgs.join(" ")}).`);
|
|
621091
|
+
handleSlashCommand("term", termArgs);
|
|
621092
|
+
return;
|
|
621093
|
+
}
|
|
621094
|
+
}
|
|
620980
621095
|
if (input && !attached) {
|
|
620981
621096
|
const buildTask = detectBuildIntent(input);
|
|
620982
621097
|
if (buildTask) {
|