@trydecember/cli 0.4.2 → 0.4.4
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/december.js +1621 -309
- package/package.json +1 -1
package/dist/december.js
CHANGED
|
@@ -65,7 +65,7 @@ var package_default;
|
|
|
65
65
|
var init_package = __esm(() => {
|
|
66
66
|
package_default = {
|
|
67
67
|
name: "@trydecember/cli",
|
|
68
|
-
version: "0.4.
|
|
68
|
+
version: "0.4.4",
|
|
69
69
|
description: "a coding agent for terminal and cloud.",
|
|
70
70
|
homepage: "https://trydecember.com",
|
|
71
71
|
repository: {
|
|
@@ -11072,10 +11072,13 @@ async function providerFetch(url, init) {
|
|
|
11072
11072
|
if (!res.ok) {
|
|
11073
11073
|
const text = await res.text();
|
|
11074
11074
|
const normalized = normalizeErrorResponse(text);
|
|
11075
|
+
const headers = new Headers(res.headers);
|
|
11076
|
+
headers.delete("retry-after");
|
|
11077
|
+
headers.delete("retry-after-ms");
|
|
11075
11078
|
return new Response(normalized, {
|
|
11076
11079
|
status: res.status,
|
|
11077
11080
|
statusText: res.statusText,
|
|
11078
|
-
headers
|
|
11081
|
+
headers
|
|
11079
11082
|
});
|
|
11080
11083
|
}
|
|
11081
11084
|
return res;
|
|
@@ -11085,7 +11088,8 @@ function openaiProvider(baseURL, apiKey, defaultHeaders, customClient) {
|
|
|
11085
11088
|
baseURL,
|
|
11086
11089
|
apiKey: apiKey || process.env.OPENAI_API_KEY || "dummy-key",
|
|
11087
11090
|
defaultHeaders,
|
|
11088
|
-
fetch: providerFetch
|
|
11091
|
+
fetch: providerFetch,
|
|
11092
|
+
maxRetries: 0
|
|
11089
11093
|
});
|
|
11090
11094
|
return createProvider({
|
|
11091
11095
|
id: "openai",
|
|
@@ -11184,6 +11188,11 @@ function openaiProvider(baseURL, apiKey, defaultHeaders, customClient) {
|
|
|
11184
11188
|
}
|
|
11185
11189
|
const activeToolCalls = new Map;
|
|
11186
11190
|
for await (const chunk of stream) {
|
|
11191
|
+
if (chunk.error) {
|
|
11192
|
+
const errObj = chunk.error;
|
|
11193
|
+
const msg = typeof errObj === "string" ? errObj : errObj.message || JSON.stringify(errObj);
|
|
11194
|
+
throw new Error(msg);
|
|
11195
|
+
}
|
|
11187
11196
|
if (chunk.usage) {
|
|
11188
11197
|
const cachedTokens = chunk.usage.prompt_tokens_details?.cached_tokens;
|
|
11189
11198
|
yield {
|
|
@@ -64374,6 +64383,7 @@ function parseIgnoreLines(content) {
|
|
|
64374
64383
|
const trimmed = line.trim();
|
|
64375
64384
|
if (!trimmed || trimmed.startsWith("#"))
|
|
64376
64385
|
continue;
|
|
64386
|
+
const isRootAnchored = trimmed.startsWith("/");
|
|
64377
64387
|
let clean = trimmed;
|
|
64378
64388
|
if (clean.startsWith("/")) {
|
|
64379
64389
|
clean = clean.slice(1);
|
|
@@ -64386,7 +64396,7 @@ function parseIgnoreLines(content) {
|
|
|
64386
64396
|
if (!clean.endsWith("/**")) {
|
|
64387
64397
|
patterns.push(`${clean}/**`);
|
|
64388
64398
|
}
|
|
64389
|
-
if (!clean.startsWith("**/")) {
|
|
64399
|
+
if (!isRootAnchored && !clean.startsWith("**/")) {
|
|
64390
64400
|
patterns.push(`**/${clean}`);
|
|
64391
64401
|
patterns.push(`**/${clean}/**`);
|
|
64392
64402
|
}
|
|
@@ -66471,15 +66481,23 @@ function anthropicProvider(baseURL, apiKey, customClientOrDefaultHeaders, custom
|
|
|
66471
66481
|
antMessages.push({ role: "assistant", content });
|
|
66472
66482
|
}
|
|
66473
66483
|
} else {
|
|
66474
|
-
antMessages.
|
|
66475
|
-
|
|
66476
|
-
content
|
|
66477
|
-
|
|
66478
|
-
|
|
66479
|
-
|
|
66480
|
-
|
|
66481
|
-
|
|
66482
|
-
|
|
66484
|
+
const prev = antMessages[antMessages.length - 1];
|
|
66485
|
+
if (prev && prev.role === "user" && Array.isArray(prev.content)) {
|
|
66486
|
+
prev.content.push({
|
|
66487
|
+
type: "text",
|
|
66488
|
+
text: msg.content
|
|
66489
|
+
});
|
|
66490
|
+
} else {
|
|
66491
|
+
antMessages.push({
|
|
66492
|
+
role: "user",
|
|
66493
|
+
content: [
|
|
66494
|
+
{
|
|
66495
|
+
type: "text",
|
|
66496
|
+
text: msg.content
|
|
66497
|
+
}
|
|
66498
|
+
]
|
|
66499
|
+
});
|
|
66500
|
+
}
|
|
66483
66501
|
}
|
|
66484
66502
|
}
|
|
66485
66503
|
if (antMessages.length >= 4) {
|
|
@@ -109443,6 +109461,14 @@ var LIVE_MODEL_CACHE_TTL_MS, liveModelCache, diskCacheLoaded = false, getCurated
|
|
|
109443
109461
|
case "aurikoai":
|
|
109444
109462
|
case "auriko-ai":
|
|
109445
109463
|
return [
|
|
109464
|
+
{
|
|
109465
|
+
label: "DeepSeek V4 Flash",
|
|
109466
|
+
value: "deepseek-v4-flash"
|
|
109467
|
+
},
|
|
109468
|
+
{
|
|
109469
|
+
label: "Gemini 2.5 Flash",
|
|
109470
|
+
value: "gemini-2.5-flash"
|
|
109471
|
+
},
|
|
109446
109472
|
{
|
|
109447
109473
|
label: "Claude Sonnet 4.6",
|
|
109448
109474
|
value: "claude-sonnet-4-6"
|
|
@@ -109455,18 +109481,10 @@ var LIVE_MODEL_CACHE_TTL_MS, liveModelCache, diskCacheLoaded = false, getCurated
|
|
|
109455
109481
|
label: "Claude Opus 4.7",
|
|
109456
109482
|
value: "claude-opus-4-7"
|
|
109457
109483
|
},
|
|
109458
|
-
{
|
|
109459
|
-
label: "DeepSeek V4 Flash",
|
|
109460
|
-
value: "deepseek-v4-flash"
|
|
109461
|
-
},
|
|
109462
109484
|
{
|
|
109463
109485
|
label: "DeepSeek V4 Pro",
|
|
109464
109486
|
value: "deepseek-v4-pro"
|
|
109465
109487
|
},
|
|
109466
|
-
{
|
|
109467
|
-
label: "Gemini 2.5 Flash",
|
|
109468
|
-
value: "gemini-2.5-flash"
|
|
109469
|
-
},
|
|
109470
109488
|
{
|
|
109471
109489
|
label: "Gemini 2.5 Pro",
|
|
109472
109490
|
value: "gemini-2.5-pro"
|
|
@@ -111283,9 +111301,15 @@ var LIVE_MODEL_CACHE_TTL_MS, liveModelCache, diskCacheLoaded = false, getCurated
|
|
|
111283
111301
|
if (normalized === "anyapi") {
|
|
111284
111302
|
return "anthropic/claude-sonnet-4-6";
|
|
111285
111303
|
}
|
|
111304
|
+
if (normalized === "auriko" || normalized === "aurikoai" || normalized === "auriko-ai") {
|
|
111305
|
+
return "deepseek-v4-flash";
|
|
111306
|
+
}
|
|
111286
111307
|
if (normalized === "bailing") {
|
|
111287
111308
|
return "Ling-1T";
|
|
111288
111309
|
}
|
|
111310
|
+
if (normalized === "baseten" || normalized === "basetenco" || normalized === "baseten-co") {
|
|
111311
|
+
return "deepseek-ai/DeepSeek-V4.1-Flash";
|
|
111312
|
+
}
|
|
111289
111313
|
if (normalized === "berget") {
|
|
111290
111314
|
return "mistralai/Mistral-Small-3.2-24B-Instruct-2506";
|
|
111291
111315
|
}
|
|
@@ -119420,6 +119444,190 @@ var init_browser = __esm(() => {
|
|
|
119420
119444
|
};
|
|
119421
119445
|
});
|
|
119422
119446
|
|
|
119447
|
+
// ../../packages/tools/src/code_intelligence.ts
|
|
119448
|
+
function formatDiagnostics(diags, path) {
|
|
119449
|
+
const target = path ? ` for ${path}` : "";
|
|
119450
|
+
if (!diags) {
|
|
119451
|
+
return `No diagnostic errors found${target}.`;
|
|
119452
|
+
}
|
|
119453
|
+
if (typeof diags === "string") {
|
|
119454
|
+
const trimmed = diags.trim();
|
|
119455
|
+
if (!trimmed) {
|
|
119456
|
+
return `No diagnostic errors found${target}.`;
|
|
119457
|
+
}
|
|
119458
|
+
return `Diagnostic errors found${target}:
|
|
119459
|
+
${trimmed}`;
|
|
119460
|
+
}
|
|
119461
|
+
if (Array.isArray(diags)) {
|
|
119462
|
+
if (diags.length === 0) {
|
|
119463
|
+
return `No diagnostic errors found${target}.`;
|
|
119464
|
+
}
|
|
119465
|
+
const formatted = diags.map((d) => {
|
|
119466
|
+
const loc = d.line ? `:${d.line}${d.column ? `:${d.column}` : ""}` : "";
|
|
119467
|
+
return `${d.filePath}${loc} - [${d.severity ?? "error"}] ${d.message}${d.source ? ` (${d.source})` : ""}`;
|
|
119468
|
+
}).join(`
|
|
119469
|
+
`);
|
|
119470
|
+
return `Diagnostic errors found${target}:
|
|
119471
|
+
${formatted}`;
|
|
119472
|
+
}
|
|
119473
|
+
return `No diagnostic errors found${target}.`;
|
|
119474
|
+
}
|
|
119475
|
+
var codeIntelligenceSchema, CodeIntelligenceTool;
|
|
119476
|
+
var init_code_intelligence = __esm(() => {
|
|
119477
|
+
init_esm2();
|
|
119478
|
+
codeIntelligenceSchema = Type2.Object({
|
|
119479
|
+
action: Type2.Union([
|
|
119480
|
+
Type2.Literal("diagnostics"),
|
|
119481
|
+
Type2.Literal("definition"),
|
|
119482
|
+
Type2.Literal("references"),
|
|
119483
|
+
Type2.Literal("outline")
|
|
119484
|
+
], {
|
|
119485
|
+
description: 'The code intelligence action to perform: "diagnostics", "definition", "references", or "outline".'
|
|
119486
|
+
}),
|
|
119487
|
+
path: Type2.Optional(Type2.String({
|
|
119488
|
+
description: 'Relative or absolute file path or directory to query. Required for "definition", "references", and "outline".'
|
|
119489
|
+
})),
|
|
119490
|
+
line: Type2.Optional(Type2.Integer({
|
|
119491
|
+
description: "1-indexed line number of the symbol for definition or references lookup."
|
|
119492
|
+
})),
|
|
119493
|
+
column: Type2.Optional(Type2.Integer({
|
|
119494
|
+
description: "1-indexed column number of the symbol for definition or references lookup."
|
|
119495
|
+
})),
|
|
119496
|
+
symbol: Type2.Optional(Type2.String({
|
|
119497
|
+
description: "Optional symbol name to search for in the file if line and column are not specified."
|
|
119498
|
+
}))
|
|
119499
|
+
});
|
|
119500
|
+
CodeIntelligenceTool = {
|
|
119501
|
+
name: "code_intelligence",
|
|
119502
|
+
description: "Query on-demand code intelligence, symbol definitions, call site references, document outline, and compiler diagnostics across the workspace or for a specific file.",
|
|
119503
|
+
inputSchema: codeIntelligenceSchema,
|
|
119504
|
+
execute: async ({ action, path, line, column, symbol }, context) => {
|
|
119505
|
+
if (action !== "diagnostics" && action !== "definition" && action !== "references" && action !== "outline") {
|
|
119506
|
+
return `Unsupported action: "${action}". Supported actions: "diagnostics", "definition", "references", "outline".`;
|
|
119507
|
+
}
|
|
119508
|
+
if (action === "diagnostics") {
|
|
119509
|
+
const diagFn = context.operations.diagnostics?.getDiagnostics || context.operations.lsp?.getDiagnostics;
|
|
119510
|
+
if (!diagFn) {
|
|
119511
|
+
return "Error: Diagnostics operations are not supported in the current environment.";
|
|
119512
|
+
}
|
|
119513
|
+
try {
|
|
119514
|
+
const diags = await diagFn(path ?? "");
|
|
119515
|
+
return formatDiagnostics(diags, path);
|
|
119516
|
+
} catch (err) {
|
|
119517
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
119518
|
+
return `Error retrieving diagnostics: ${message}`;
|
|
119519
|
+
}
|
|
119520
|
+
}
|
|
119521
|
+
if (action === "outline") {
|
|
119522
|
+
if (!path) {
|
|
119523
|
+
return 'Error: "path" parameter is required for "outline" action.';
|
|
119524
|
+
}
|
|
119525
|
+
if (!context.operations.lsp?.getOutline) {
|
|
119526
|
+
return "Error: LSP operations are not supported in the current environment.";
|
|
119527
|
+
}
|
|
119528
|
+
try {
|
|
119529
|
+
const symbols = await context.operations.lsp.getOutline(path);
|
|
119530
|
+
if (!symbols || symbols.length === 0) {
|
|
119531
|
+
return `No document symbols found for ${path}.`;
|
|
119532
|
+
}
|
|
119533
|
+
const lines = symbols.map((s) => `- [${s.kind}] ${s.name} (${path}:${s.line}:${s.column})${s.containerName ? ` (in ${s.containerName})` : ""}`);
|
|
119534
|
+
return `Document outline for ${path}:
|
|
119535
|
+
${lines.join(`
|
|
119536
|
+
`)}`;
|
|
119537
|
+
} catch (err) {
|
|
119538
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
119539
|
+
return `Error retrieving outline: ${message}`;
|
|
119540
|
+
}
|
|
119541
|
+
}
|
|
119542
|
+
if (!path) {
|
|
119543
|
+
return `Error: "path" parameter is required for "${action}" action.`;
|
|
119544
|
+
}
|
|
119545
|
+
let targetLine = line;
|
|
119546
|
+
let targetColumn = column;
|
|
119547
|
+
if ((targetLine === undefined || targetColumn === undefined) && symbol) {
|
|
119548
|
+
try {
|
|
119549
|
+
const content = await context.operations.fs.readFile(path);
|
|
119550
|
+
const fileLines = content.split(`
|
|
119551
|
+
`);
|
|
119552
|
+
let fallbackLine;
|
|
119553
|
+
let fallbackCol;
|
|
119554
|
+
for (let i = 0;i < fileLines.length; i++) {
|
|
119555
|
+
const lineStr = fileLines[i];
|
|
119556
|
+
const idx = lineStr.indexOf(symbol);
|
|
119557
|
+
if (idx !== -1) {
|
|
119558
|
+
if (/^\s*import\b/.test(lineStr)) {
|
|
119559
|
+
if (fallbackLine === undefined) {
|
|
119560
|
+
fallbackLine = i + 1;
|
|
119561
|
+
fallbackCol = idx + 1;
|
|
119562
|
+
}
|
|
119563
|
+
} else {
|
|
119564
|
+
targetLine = i + 1;
|
|
119565
|
+
targetColumn = idx + 1;
|
|
119566
|
+
break;
|
|
119567
|
+
}
|
|
119568
|
+
}
|
|
119569
|
+
}
|
|
119570
|
+
if (targetLine === undefined) {
|
|
119571
|
+
targetLine = fallbackLine;
|
|
119572
|
+
targetColumn = fallbackCol;
|
|
119573
|
+
}
|
|
119574
|
+
if (targetLine === undefined || targetColumn === undefined) {
|
|
119575
|
+
return `Symbol "${symbol}" not found in ${path}.`;
|
|
119576
|
+
}
|
|
119577
|
+
} catch (err) {
|
|
119578
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
119579
|
+
return `Error reading file ${path}: ${message}`;
|
|
119580
|
+
}
|
|
119581
|
+
}
|
|
119582
|
+
if (targetLine === undefined || targetColumn === undefined) {
|
|
119583
|
+
return `Error: "line" and "column" (or "symbol") are required for "${action}" action.`;
|
|
119584
|
+
}
|
|
119585
|
+
if (action === "definition") {
|
|
119586
|
+
if (!context.operations.lsp?.getDefinition) {
|
|
119587
|
+
return "Error: LSP operations are not supported in the current environment.";
|
|
119588
|
+
}
|
|
119589
|
+
try {
|
|
119590
|
+
const raw = await context.operations.lsp.getDefinition(path, targetLine, targetColumn);
|
|
119591
|
+
const locs = Array.isArray(raw) ? raw : raw ? [raw] : [];
|
|
119592
|
+
if (locs.length === 0) {
|
|
119593
|
+
return `No definition found for symbol at ${path}:${targetLine}:${targetColumn}.`;
|
|
119594
|
+
}
|
|
119595
|
+
if (locs.length === 1) {
|
|
119596
|
+
const loc = locs[0];
|
|
119597
|
+
return `Definition found at ${loc.filePath}:${loc.line}:${loc.column}`;
|
|
119598
|
+
}
|
|
119599
|
+
const list = locs.map((l) => `- ${l.filePath}:${l.line}:${l.column}`).join(`
|
|
119600
|
+
`);
|
|
119601
|
+
return `Definition(s) found:
|
|
119602
|
+
${list}`;
|
|
119603
|
+
} catch (err) {
|
|
119604
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
119605
|
+
return `Error retrieving definition: ${message}`;
|
|
119606
|
+
}
|
|
119607
|
+
}
|
|
119608
|
+
if (action === "references") {
|
|
119609
|
+
if (!context.operations.lsp?.getReferences) {
|
|
119610
|
+
return "Error: LSP operations are not supported in the current environment.";
|
|
119611
|
+
}
|
|
119612
|
+
try {
|
|
119613
|
+
const refs = await context.operations.lsp.getReferences(path, targetLine, targetColumn);
|
|
119614
|
+
if (!refs || refs.length === 0) {
|
|
119615
|
+
return `No references found for symbol at ${path}:${targetLine}:${targetColumn}.`;
|
|
119616
|
+
}
|
|
119617
|
+
const list = refs.map((r) => `- ${r.filePath}:${r.line}:${r.column}`).join(`
|
|
119618
|
+
`);
|
|
119619
|
+
return `Found ${refs.length} reference(s) for symbol at ${path}:${targetLine}:${targetColumn}:
|
|
119620
|
+
${list}`;
|
|
119621
|
+
} catch (err) {
|
|
119622
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
119623
|
+
return `Error retrieving references: ${message}`;
|
|
119624
|
+
}
|
|
119625
|
+
}
|
|
119626
|
+
return `Unsupported action: "${action}".`;
|
|
119627
|
+
}
|
|
119628
|
+
};
|
|
119629
|
+
});
|
|
119630
|
+
|
|
119423
119631
|
// ../../packages/tools/src/deferred-registry.ts
|
|
119424
119632
|
class DeferredToolRegistry {
|
|
119425
119633
|
tools = new Map;
|
|
@@ -121273,6 +121481,264 @@ var init_ls = __esm(() => {
|
|
|
121273
121481
|
};
|
|
121274
121482
|
});
|
|
121275
121483
|
|
|
121484
|
+
// ../../packages/tools/src/manage_memory.ts
|
|
121485
|
+
import path20 from "node:path";
|
|
121486
|
+
function resolveWriteTarget(cwd, target, category) {
|
|
121487
|
+
const isRules = target === "rules" || target === "RULES.md" || !target && category === "rules";
|
|
121488
|
+
if (isRules) {
|
|
121489
|
+
if (target === "RULES.md") {
|
|
121490
|
+
return { relativePath: "RULES.md", isRules: true };
|
|
121491
|
+
}
|
|
121492
|
+
return { relativePath: "RULES.md", isRules: true };
|
|
121493
|
+
}
|
|
121494
|
+
if (target === "MEMORY.md") {
|
|
121495
|
+
return { relativePath: "MEMORY.md", isRules: false };
|
|
121496
|
+
}
|
|
121497
|
+
return { relativePath: path20.join(".december", "memory.md"), isRules: false };
|
|
121498
|
+
}
|
|
121499
|
+
function resolveReadCandidates(target) {
|
|
121500
|
+
if (target === "rules" || target === "RULES.md") {
|
|
121501
|
+
return ["RULES.md", path20.join(".december", "rules.md"), path20.join(".december", "RULES.md")];
|
|
121502
|
+
}
|
|
121503
|
+
if (target === "memory" || target === "MEMORY.md") {
|
|
121504
|
+
return [
|
|
121505
|
+
path20.join(".december", "memory.md"),
|
|
121506
|
+
"MEMORY.md",
|
|
121507
|
+
path20.join(".december", "MEMORY.md")
|
|
121508
|
+
];
|
|
121509
|
+
}
|
|
121510
|
+
return [
|
|
121511
|
+
path20.join(".december", "memory.md"),
|
|
121512
|
+
"MEMORY.md",
|
|
121513
|
+
"RULES.md",
|
|
121514
|
+
path20.join(".december", "rules.md")
|
|
121515
|
+
];
|
|
121516
|
+
}
|
|
121517
|
+
function normalizeEntry(text) {
|
|
121518
|
+
return text.replace(/^[-*•]\s+/, "").trim();
|
|
121519
|
+
}
|
|
121520
|
+
var manageMemorySchema, ManageMemoryTool;
|
|
121521
|
+
var init_manage_memory = __esm(() => {
|
|
121522
|
+
init_esm2();
|
|
121523
|
+
manageMemorySchema = Type2.Object({
|
|
121524
|
+
action: Type2.Union([Type2.Literal("record"), Type2.Literal("read"), Type2.Literal("forget")], {
|
|
121525
|
+
description: 'The action to perform: "record" to store an entry, "read" to inspect entries, or "forget" to prune an entry.'
|
|
121526
|
+
}),
|
|
121527
|
+
entry: Type2.Optional(Type2.String({
|
|
121528
|
+
description: "The memory or rule entry text to record or forget."
|
|
121529
|
+
})),
|
|
121530
|
+
category: Type2.Optional(Type2.Union([
|
|
121531
|
+
Type2.Literal("build_and_test"),
|
|
121532
|
+
Type2.Literal("conventions"),
|
|
121533
|
+
Type2.Literal("architecture"),
|
|
121534
|
+
Type2.Literal("quirks"),
|
|
121535
|
+
Type2.Literal("rules"),
|
|
121536
|
+
Type2.Literal("general")
|
|
121537
|
+
], {
|
|
121538
|
+
description: "Category header: build_and_test, conventions, architecture, quirks, rules, or general."
|
|
121539
|
+
})),
|
|
121540
|
+
target: Type2.Optional(Type2.Union([
|
|
121541
|
+
Type2.Literal("memory"),
|
|
121542
|
+
Type2.Literal("rules"),
|
|
121543
|
+
Type2.Literal("MEMORY.md"),
|
|
121544
|
+
Type2.Literal("RULES.md")
|
|
121545
|
+
], {
|
|
121546
|
+
description: 'Target file: "memory" (.december/memory.md or MEMORY.md) or "rules" (RULES.md or .december/rules.md). Defaults to memory for general/memory entries, or rules if category is "rules".'
|
|
121547
|
+
})),
|
|
121548
|
+
query: Type2.Optional(Type2.String({
|
|
121549
|
+
description: "Optional query keyword to filter entries when reading."
|
|
121550
|
+
}))
|
|
121551
|
+
});
|
|
121552
|
+
ManageMemoryTool = {
|
|
121553
|
+
name: "manage_memory",
|
|
121554
|
+
description: "Use this tool to record, read, or forget persistent notes, conventions, build/test commands, quirks, and rules across sessions in workspace memory (.december/memory.md, MEMORY.md, RULES.md).",
|
|
121555
|
+
inputSchema: manageMemorySchema,
|
|
121556
|
+
execute: async ({ action, entry, category, target, query }, context) => {
|
|
121557
|
+
const cwd = context.operations.env.cwd();
|
|
121558
|
+
switch (action) {
|
|
121559
|
+
case "record": {
|
|
121560
|
+
if (!entry || !entry.trim()) {
|
|
121561
|
+
return 'Error: "entry" parameter is required for action "record".';
|
|
121562
|
+
}
|
|
121563
|
+
const cleanEntry = normalizeEntry(entry);
|
|
121564
|
+
if (!cleanEntry) {
|
|
121565
|
+
return 'Error: "entry" parameter cannot be empty.';
|
|
121566
|
+
}
|
|
121567
|
+
const { relativePath, isRules } = resolveWriteTarget(cwd, target, category);
|
|
121568
|
+
const fullPath = path20.isAbsolute(relativePath) ? relativePath : path20.join(cwd, relativePath);
|
|
121569
|
+
const cat = category || (isRules ? "rules" : "conventions");
|
|
121570
|
+
let existingContent = "";
|
|
121571
|
+
try {
|
|
121572
|
+
existingContent = await context.operations.fs.readFile(fullPath);
|
|
121573
|
+
} catch {}
|
|
121574
|
+
const lines = existingContent.split(`
|
|
121575
|
+
`);
|
|
121576
|
+
for (const line of lines) {
|
|
121577
|
+
const lineContent = normalizeEntry(line);
|
|
121578
|
+
if (lineContent && lineContent.toLowerCase() === cleanEntry.toLowerCase()) {
|
|
121579
|
+
return `Entry already exists in ${relativePath} under "${cat}". Skipped duplicate.`;
|
|
121580
|
+
}
|
|
121581
|
+
}
|
|
121582
|
+
const headerRegex = new RegExp(`^##\\s+${cat}\\b`, "im");
|
|
121583
|
+
const headerMatch = existingContent.match(headerRegex);
|
|
121584
|
+
let updatedContent = "";
|
|
121585
|
+
if (headerMatch && headerMatch.index !== undefined) {
|
|
121586
|
+
const headerIndex = headerMatch.index;
|
|
121587
|
+
const rest = existingContent.slice(headerIndex);
|
|
121588
|
+
const nextHeaderMatch = rest.slice(headerMatch[0].length).match(/\n##\s+/i);
|
|
121589
|
+
if (nextHeaderMatch && nextHeaderMatch.index !== undefined) {
|
|
121590
|
+
const insertPos = headerIndex + headerMatch[0].length + nextHeaderMatch.index;
|
|
121591
|
+
updatedContent = `${existingContent.slice(0, insertPos)}
|
|
121592
|
+
- ${cleanEntry}${existingContent.slice(insertPos)}`;
|
|
121593
|
+
} else {
|
|
121594
|
+
updatedContent = `${existingContent.trimEnd()}
|
|
121595
|
+
- ${cleanEntry}
|
|
121596
|
+
`;
|
|
121597
|
+
}
|
|
121598
|
+
} else {
|
|
121599
|
+
const prefix = existingContent.trim() ? `${existingContent.trimEnd()}
|
|
121600
|
+
|
|
121601
|
+
` : "";
|
|
121602
|
+
updatedContent = `${prefix}## ${cat}
|
|
121603
|
+
- ${cleanEntry}
|
|
121604
|
+
`;
|
|
121605
|
+
}
|
|
121606
|
+
try {
|
|
121607
|
+
await context.operations.fs.writeFile(fullPath, updatedContent);
|
|
121608
|
+
return `Recorded entry under "${cat}" in ${relativePath}.`;
|
|
121609
|
+
} catch (err) {
|
|
121610
|
+
return `Failed to write memory file: ${err.message}`;
|
|
121611
|
+
}
|
|
121612
|
+
}
|
|
121613
|
+
case "read": {
|
|
121614
|
+
const candidates = resolveReadCandidates(target);
|
|
121615
|
+
const contents = [];
|
|
121616
|
+
for (const candidate of candidates) {
|
|
121617
|
+
const fullPath = path20.isAbsolute(candidate) ? candidate : path20.join(cwd, candidate);
|
|
121618
|
+
try {
|
|
121619
|
+
const text = await context.operations.fs.readFile(fullPath);
|
|
121620
|
+
if (text && text.trim()) {
|
|
121621
|
+
contents.push({ file: candidate, text: text.trim() });
|
|
121622
|
+
}
|
|
121623
|
+
} catch {}
|
|
121624
|
+
}
|
|
121625
|
+
if (contents.length === 0) {
|
|
121626
|
+
return "No memory or rules entries found.";
|
|
121627
|
+
}
|
|
121628
|
+
if (category) {
|
|
121629
|
+
const matchedSections = [];
|
|
121630
|
+
const catLower = category.toLowerCase();
|
|
121631
|
+
for (const item of contents) {
|
|
121632
|
+
const lines = item.text.split(`
|
|
121633
|
+
`);
|
|
121634
|
+
let inCategory = false;
|
|
121635
|
+
const sectionLines = [];
|
|
121636
|
+
for (const line of lines) {
|
|
121637
|
+
if (line.startsWith("## ")) {
|
|
121638
|
+
const headerName = line.slice(3).trim().toLowerCase();
|
|
121639
|
+
if (headerName === catLower) {
|
|
121640
|
+
inCategory = true;
|
|
121641
|
+
sectionLines.push(line);
|
|
121642
|
+
} else {
|
|
121643
|
+
inCategory = false;
|
|
121644
|
+
}
|
|
121645
|
+
} else if (inCategory) {
|
|
121646
|
+
sectionLines.push(line);
|
|
121647
|
+
}
|
|
121648
|
+
}
|
|
121649
|
+
if (sectionLines.length > 0) {
|
|
121650
|
+
matchedSections.push(`### Source: ${item.file}
|
|
121651
|
+
${sectionLines.join(`
|
|
121652
|
+
`).trim()}`);
|
|
121653
|
+
}
|
|
121654
|
+
}
|
|
121655
|
+
if (matchedSections.length === 0) {
|
|
121656
|
+
return `No entries found under category "${category}".`;
|
|
121657
|
+
}
|
|
121658
|
+
return matchedSections.join(`
|
|
121659
|
+
|
|
121660
|
+
`);
|
|
121661
|
+
}
|
|
121662
|
+
if (query) {
|
|
121663
|
+
const queryLower = query.toLowerCase();
|
|
121664
|
+
const matchedLines = [];
|
|
121665
|
+
for (const item of contents) {
|
|
121666
|
+
const lines = item.text.split(`
|
|
121667
|
+
`);
|
|
121668
|
+
let currentHeader = "";
|
|
121669
|
+
const fileMatches = [];
|
|
121670
|
+
for (const line of lines) {
|
|
121671
|
+
if (line.startsWith("## ")) {
|
|
121672
|
+
currentHeader = line;
|
|
121673
|
+
} else if (line.toLowerCase().includes(queryLower)) {
|
|
121674
|
+
if (currentHeader && !fileMatches.includes(currentHeader)) {
|
|
121675
|
+
fileMatches.push(currentHeader);
|
|
121676
|
+
}
|
|
121677
|
+
fileMatches.push(line);
|
|
121678
|
+
}
|
|
121679
|
+
}
|
|
121680
|
+
if (fileMatches.length > 0) {
|
|
121681
|
+
matchedLines.push(`### Source: ${item.file}
|
|
121682
|
+
${fileMatches.join(`
|
|
121683
|
+
`)}`);
|
|
121684
|
+
}
|
|
121685
|
+
}
|
|
121686
|
+
if (matchedLines.length === 0) {
|
|
121687
|
+
return `No memory entries found matching "${query}".`;
|
|
121688
|
+
}
|
|
121689
|
+
return matchedLines.join(`
|
|
121690
|
+
|
|
121691
|
+
`);
|
|
121692
|
+
}
|
|
121693
|
+
return contents.map((c) => `### Source: ${c.file}
|
|
121694
|
+
${c.text}`).join(`
|
|
121695
|
+
|
|
121696
|
+
`);
|
|
121697
|
+
}
|
|
121698
|
+
case "forget": {
|
|
121699
|
+
if (!entry || !entry.trim()) {
|
|
121700
|
+
return 'Error: "entry" parameter is required for action "forget".';
|
|
121701
|
+
}
|
|
121702
|
+
const targetClean = normalizeEntry(entry).toLowerCase();
|
|
121703
|
+
const candidates = resolveReadCandidates(target);
|
|
121704
|
+
let removed = false;
|
|
121705
|
+
for (const candidate of candidates) {
|
|
121706
|
+
const fullPath = path20.isAbsolute(candidate) ? candidate : path20.join(cwd, candidate);
|
|
121707
|
+
try {
|
|
121708
|
+
const text = await context.operations.fs.readFile(fullPath);
|
|
121709
|
+
const lines = text.split(`
|
|
121710
|
+
`);
|
|
121711
|
+
const newLines = [];
|
|
121712
|
+
let fileModified = false;
|
|
121713
|
+
for (const line of lines) {
|
|
121714
|
+
const lineClean = normalizeEntry(line).toLowerCase();
|
|
121715
|
+
if (lineClean && (lineClean === targetClean || lineClean.includes(targetClean))) {
|
|
121716
|
+
fileModified = true;
|
|
121717
|
+
removed = true;
|
|
121718
|
+
continue;
|
|
121719
|
+
}
|
|
121720
|
+
newLines.push(line);
|
|
121721
|
+
}
|
|
121722
|
+
if (fileModified) {
|
|
121723
|
+
await context.operations.fs.writeFile(fullPath, newLines.join(`
|
|
121724
|
+
`).trimEnd() + `
|
|
121725
|
+
`);
|
|
121726
|
+
}
|
|
121727
|
+
} catch {}
|
|
121728
|
+
}
|
|
121729
|
+
if (removed) {
|
|
121730
|
+
return "Removed entry from memory.";
|
|
121731
|
+
}
|
|
121732
|
+
return "Entry not found in memory.";
|
|
121733
|
+
}
|
|
121734
|
+
default: {
|
|
121735
|
+
return "Invalid action. Supported actions: record, read, forget.";
|
|
121736
|
+
}
|
|
121737
|
+
}
|
|
121738
|
+
}
|
|
121739
|
+
};
|
|
121740
|
+
});
|
|
121741
|
+
|
|
121276
121742
|
// ../../packages/tools/src/manage_task.ts
|
|
121277
121743
|
var manageTaskSchema, ManageTaskTool;
|
|
121278
121744
|
var init_manage_task = __esm(() => {
|
|
@@ -162241,7 +162707,7 @@ ${formatted}`;
|
|
|
162241
162707
|
|
|
162242
162708
|
// ../../packages/tools/src/bash-operations.ts
|
|
162243
162709
|
import { spawn as spawn2 } from "node:child_process";
|
|
162244
|
-
import
|
|
162710
|
+
import path21 from "node:path";
|
|
162245
162711
|
function trackDetachedChildPid(pid) {
|
|
162246
162712
|
trackedDetachedChildPids.add(pid);
|
|
162247
162713
|
}
|
|
@@ -162251,7 +162717,7 @@ function untrackDetachedChildPid(pid) {
|
|
|
162251
162717
|
function killProcessGroup(pid) {
|
|
162252
162718
|
if (process.platform === "win32") {
|
|
162253
162719
|
try {
|
|
162254
|
-
const child = spawn2(
|
|
162720
|
+
const child = spawn2(path21.join(process.env.SystemRoot ?? "C:\\Windows", "System32", "taskkill.exe"), ["/F", "/T", "/PID", String(pid)], {
|
|
162255
162721
|
stdio: "ignore",
|
|
162256
162722
|
detached: true,
|
|
162257
162723
|
windowsHide: true
|
|
@@ -162369,12 +162835,14 @@ var init_src4 = __esm(() => {
|
|
|
162369
162835
|
init_ask_question();
|
|
162370
162836
|
init_bash();
|
|
162371
162837
|
init_browser();
|
|
162838
|
+
init_code_intelligence();
|
|
162372
162839
|
init_deferred_registry();
|
|
162373
162840
|
init_edit();
|
|
162374
162841
|
init_edit_diff();
|
|
162375
162842
|
init_find();
|
|
162376
162843
|
init_grep();
|
|
162377
162844
|
init_ls();
|
|
162845
|
+
init_manage_memory();
|
|
162378
162846
|
init_manage_task();
|
|
162379
162847
|
init_read();
|
|
162380
162848
|
init_search_tools();
|
|
@@ -162392,11 +162860,13 @@ var init_src4 = __esm(() => {
|
|
|
162392
162860
|
init_grep();
|
|
162393
162861
|
init_ask_question();
|
|
162394
162862
|
init_manage_task();
|
|
162863
|
+
init_manage_memory();
|
|
162395
162864
|
init_browser();
|
|
162396
162865
|
init_web_search();
|
|
162397
162866
|
init_diff_preview();
|
|
162398
162867
|
init_deferred_registry();
|
|
162399
162868
|
init_search_tools();
|
|
162869
|
+
init_code_intelligence();
|
|
162400
162870
|
CORE_TOOLS = [
|
|
162401
162871
|
BashTool,
|
|
162402
162872
|
ReadFileTool,
|
|
@@ -162407,7 +162877,9 @@ var init_src4 = __esm(() => {
|
|
|
162407
162877
|
FindFilesTool,
|
|
162408
162878
|
GrepSearchTool,
|
|
162409
162879
|
AskQuestionTool,
|
|
162410
|
-
SearchToolsTool
|
|
162880
|
+
SearchToolsTool,
|
|
162881
|
+
CodeIntelligenceTool,
|
|
162882
|
+
ManageMemoryTool
|
|
162411
162883
|
];
|
|
162412
162884
|
DEFERRED_TOOLS = [ManageTaskTool, BrowserTool, WebSearchTool];
|
|
162413
162885
|
defaultDeferredRegistry.register(BrowserTool, {
|
|
@@ -162422,6 +162894,10 @@ var init_src4 = __esm(() => {
|
|
|
162422
162894
|
category: "task",
|
|
162423
162895
|
keywords: ["task", "background", "kill", "status", "process", "pid", "manage_task"]
|
|
162424
162896
|
});
|
|
162897
|
+
defaultDeferredRegistry.register(ManageMemoryTool, {
|
|
162898
|
+
category: "memory",
|
|
162899
|
+
keywords: ["memory", "rules", "conventions", "quirks", "manage_memory", "remember", "forget"]
|
|
162900
|
+
});
|
|
162425
162901
|
});
|
|
162426
162902
|
|
|
162427
162903
|
// ../../node_modules/.bun/uuid@14.0.1/node_modules/uuid/dist-node/rng.js
|
|
@@ -162626,6 +163102,64 @@ function estimateTokens(messages) {
|
|
|
162626
163102
|
return acc + Math.ceil((text.length + toolInput.length) / 4);
|
|
162627
163103
|
}, 0);
|
|
162628
163104
|
}
|
|
163105
|
+
function isSafeCompactionBoundary(messages, splitIndex, startIndex = 0) {
|
|
163106
|
+
if (splitIndex <= startIndex || splitIndex >= messages.length) {
|
|
163107
|
+
return false;
|
|
163108
|
+
}
|
|
163109
|
+
if (messages[splitIndex]?.role === "tool") {
|
|
163110
|
+
return false;
|
|
163111
|
+
}
|
|
163112
|
+
const preCallIds = new Set;
|
|
163113
|
+
for (let i = startIndex;i < splitIndex; i++) {
|
|
163114
|
+
const msg = messages[i];
|
|
163115
|
+
if (msg?.toolCalls) {
|
|
163116
|
+
for (const tc of msg.toolCalls) {
|
|
163117
|
+
if (tc.id)
|
|
163118
|
+
preCallIds.add(tc.id);
|
|
163119
|
+
}
|
|
163120
|
+
}
|
|
163121
|
+
}
|
|
163122
|
+
for (let i = splitIndex;i < messages.length; i++) {
|
|
163123
|
+
const msg = messages[i];
|
|
163124
|
+
if (msg?.role === "tool" && msg.toolCallId && preCallIds.has(msg.toolCallId)) {
|
|
163125
|
+
return false;
|
|
163126
|
+
}
|
|
163127
|
+
}
|
|
163128
|
+
const postCallIds = new Set;
|
|
163129
|
+
for (let i = splitIndex;i < messages.length; i++) {
|
|
163130
|
+
const msg = messages[i];
|
|
163131
|
+
if (msg?.toolCalls) {
|
|
163132
|
+
for (const tc of msg.toolCalls) {
|
|
163133
|
+
if (tc.id)
|
|
163134
|
+
postCallIds.add(tc.id);
|
|
163135
|
+
}
|
|
163136
|
+
}
|
|
163137
|
+
}
|
|
163138
|
+
for (let i = startIndex;i < splitIndex; i++) {
|
|
163139
|
+
const msg = messages[i];
|
|
163140
|
+
if (msg?.role === "tool" && msg.toolCallId && postCallIds.has(msg.toolCallId)) {
|
|
163141
|
+
return false;
|
|
163142
|
+
}
|
|
163143
|
+
}
|
|
163144
|
+
return true;
|
|
163145
|
+
}
|
|
163146
|
+
function findSafeCompactionBoundary(messages, targetIndex, startIndex = 1) {
|
|
163147
|
+
if (isSafeCompactionBoundary(messages, targetIndex, startIndex)) {
|
|
163148
|
+
return targetIndex;
|
|
163149
|
+
}
|
|
163150
|
+
const maxDelta = messages.length;
|
|
163151
|
+
for (let delta = 1;delta < maxDelta; delta++) {
|
|
163152
|
+
const left = targetIndex - delta;
|
|
163153
|
+
if (left > startIndex && isSafeCompactionBoundary(messages, left, startIndex)) {
|
|
163154
|
+
return left;
|
|
163155
|
+
}
|
|
163156
|
+
const right = targetIndex + delta;
|
|
163157
|
+
if (right < messages.length && isSafeCompactionBoundary(messages, right, startIndex)) {
|
|
163158
|
+
return right;
|
|
163159
|
+
}
|
|
163160
|
+
}
|
|
163161
|
+
return targetIndex;
|
|
163162
|
+
}
|
|
162629
163163
|
async function compactContextIfNeeded(messages, llm, maxTokens, modelOptions, signal) {
|
|
162630
163164
|
let limit = maxTokens;
|
|
162631
163165
|
if (!limit) {
|
|
@@ -162644,10 +163178,17 @@ async function compactContextIfNeeded(messages, llm, maxTokens, modelOptions, si
|
|
|
162644
163178
|
if (messages.length <= PROTECTED_TAIL + 1) {
|
|
162645
163179
|
return messages;
|
|
162646
163180
|
}
|
|
162647
|
-
const
|
|
162648
|
-
const
|
|
162649
|
-
const
|
|
162650
|
-
const
|
|
163181
|
+
const hasSystemPrompt = messages[0]?.role === "system";
|
|
163182
|
+
const systemPrompt = hasSystemPrompt ? messages[0] : undefined;
|
|
163183
|
+
const historyStartIndex = hasSystemPrompt ? 1 : 0;
|
|
163184
|
+
const targetIndex = messages.length - PROTECTED_TAIL;
|
|
163185
|
+
const safeSplitIndex = findSafeCompactionBoundary(messages, targetIndex, historyStartIndex);
|
|
163186
|
+
if (safeSplitIndex <= historyStartIndex || safeSplitIndex >= messages.length) {
|
|
163187
|
+
return messages;
|
|
163188
|
+
}
|
|
163189
|
+
const middleHistory = messages.slice(historyStartIndex, safeSplitIndex);
|
|
163190
|
+
const recentHistory = messages.slice(safeSplitIndex);
|
|
163191
|
+
const hasPreviousSummary = middleHistory.length > 0 && (middleHistory[0].role === "system" || middleHistory[0].role === "user") && middleHistory[0].content.includes("[COMPACTED HISTORY SUMMARY]");
|
|
162651
163192
|
let previousSummaryText = "";
|
|
162652
163193
|
let messagesToSummarize = middleHistory;
|
|
162653
163194
|
if (hasPreviousSummary) {
|
|
@@ -162655,6 +163196,9 @@ async function compactContextIfNeeded(messages, llm, maxTokens, modelOptions, si
|
|
|
162655
163196
|
`, "");
|
|
162656
163197
|
messagesToSummarize = middleHistory.slice(1);
|
|
162657
163198
|
}
|
|
163199
|
+
if (messagesToSummarize.length === 0) {
|
|
163200
|
+
return messages;
|
|
163201
|
+
}
|
|
162658
163202
|
const fileManifests = extractFileManifests(messagesToSummarize, previousSummaryText);
|
|
162659
163203
|
const historyText = messagesToSummarize.map((m) => {
|
|
162660
163204
|
let txt = `[${m.role.toUpperCase()}]: ${m.content}`;
|
|
@@ -162792,7 +163336,7 @@ ${fileManifests.modifiedFiles.join(`
|
|
|
162792
163336
|
content: `[COMPACTED HISTORY SUMMARY]
|
|
162793
163337
|
${finalSummary}`
|
|
162794
163338
|
};
|
|
162795
|
-
return [systemPrompt, summaryMessage, ...recentHistory];
|
|
163339
|
+
return systemPrompt ? [systemPrompt, summaryMessage, ...recentHistory] : [summaryMessage, ...recentHistory];
|
|
162796
163340
|
}
|
|
162797
163341
|
var DEFAULT_MAX_TOKENS = 32000, PRUNE_PROTECT_TOKENS = 40000, PRUNE_MINIMUM_SAVINGS = 15000, PRUNE_PROTECT_STEPS = 3, PRUNE_PROTECTED_TOOLS;
|
|
162798
163342
|
var init_compaction = __esm(() => {
|
|
@@ -162801,10 +163345,144 @@ var init_compaction = __esm(() => {
|
|
|
162801
163345
|
});
|
|
162802
163346
|
|
|
162803
163347
|
// ../../packages/agent/src/conversation-manager.ts
|
|
163348
|
+
import fs19 from "node:fs";
|
|
163349
|
+
import path22 from "node:path";
|
|
163350
|
+
|
|
162804
163351
|
class ConversationManager {
|
|
162805
163352
|
_messages = [];
|
|
162806
|
-
|
|
163353
|
+
workspaceRoot;
|
|
163354
|
+
constructor(initialMessagesOrOptions, options) {
|
|
163355
|
+
let initialMessages = [];
|
|
163356
|
+
let opts;
|
|
163357
|
+
if (Array.isArray(initialMessagesOrOptions)) {
|
|
163358
|
+
initialMessages = initialMessagesOrOptions;
|
|
163359
|
+
opts = options;
|
|
163360
|
+
} else if (initialMessagesOrOptions && typeof initialMessagesOrOptions === "object") {
|
|
163361
|
+
opts = initialMessagesOrOptions;
|
|
163362
|
+
}
|
|
162807
163363
|
this._messages = initialMessages;
|
|
163364
|
+
if (opts?.workspaceRoot) {
|
|
163365
|
+
this.workspaceRoot = opts.workspaceRoot;
|
|
163366
|
+
this.initSession({
|
|
163367
|
+
workspaceRoot: opts.workspaceRoot,
|
|
163368
|
+
systemPrompt: opts.systemPrompt
|
|
163369
|
+
});
|
|
163370
|
+
}
|
|
163371
|
+
}
|
|
163372
|
+
initSession(optionsOrWorkspaceRoot, systemPromptArg) {
|
|
163373
|
+
let workspaceRoot;
|
|
163374
|
+
let systemPrompt;
|
|
163375
|
+
if (typeof optionsOrWorkspaceRoot === "string") {
|
|
163376
|
+
workspaceRoot = optionsOrWorkspaceRoot;
|
|
163377
|
+
systemPrompt = systemPromptArg;
|
|
163378
|
+
} else if (optionsOrWorkspaceRoot && typeof optionsOrWorkspaceRoot === "object") {
|
|
163379
|
+
workspaceRoot = optionsOrWorkspaceRoot.workspaceRoot;
|
|
163380
|
+
systemPrompt = optionsOrWorkspaceRoot.systemPrompt;
|
|
163381
|
+
} else {
|
|
163382
|
+
workspaceRoot = this.workspaceRoot;
|
|
163383
|
+
systemPrompt = systemPromptArg;
|
|
163384
|
+
}
|
|
163385
|
+
if (workspaceRoot) {
|
|
163386
|
+
this.workspaceRoot = workspaceRoot;
|
|
163387
|
+
}
|
|
163388
|
+
const existingSystemIndex = this._messages.findIndex((m) => m.role === "system");
|
|
163389
|
+
let prompt = systemPrompt;
|
|
163390
|
+
if (prompt === undefined) {
|
|
163391
|
+
if (existingSystemIndex !== -1) {
|
|
163392
|
+
prompt = this._messages[existingSystemIndex].content;
|
|
163393
|
+
} else {
|
|
163394
|
+
prompt = "";
|
|
163395
|
+
}
|
|
163396
|
+
}
|
|
163397
|
+
const memoryContent = this.readWorkspaceMemory(workspaceRoot);
|
|
163398
|
+
let finalPrompt = prompt;
|
|
163399
|
+
if (memoryContent) {
|
|
163400
|
+
finalPrompt = this.injectMemoryBlock(prompt, memoryContent);
|
|
163401
|
+
}
|
|
163402
|
+
if (existingSystemIndex !== -1) {
|
|
163403
|
+
this._messages[existingSystemIndex].content = finalPrompt;
|
|
163404
|
+
} else if (finalPrompt) {
|
|
163405
|
+
this._messages.unshift({
|
|
163406
|
+
role: "system",
|
|
163407
|
+
content: finalPrompt,
|
|
163408
|
+
id: v4_default2(),
|
|
163409
|
+
timestamp: Date.now()
|
|
163410
|
+
});
|
|
163411
|
+
}
|
|
163412
|
+
return finalPrompt;
|
|
163413
|
+
}
|
|
163414
|
+
readWorkspaceMemory(workspaceRoot) {
|
|
163415
|
+
if (!workspaceRoot)
|
|
163416
|
+
return "";
|
|
163417
|
+
const memoryCandidates = [
|
|
163418
|
+
path22.join(workspaceRoot, ".december", "memory.md"),
|
|
163419
|
+
path22.join(workspaceRoot, "MEMORY.md"),
|
|
163420
|
+
path22.join(workspaceRoot, ".december", "MEMORY.md"),
|
|
163421
|
+
path22.join(workspaceRoot, "memory.md")
|
|
163422
|
+
];
|
|
163423
|
+
const rulesCandidates = [
|
|
163424
|
+
path22.join(workspaceRoot, "RULES.md"),
|
|
163425
|
+
path22.join(workspaceRoot, ".december", "rules.md"),
|
|
163426
|
+
path22.join(workspaceRoot, ".december", "RULES.md"),
|
|
163427
|
+
path22.join(workspaceRoot, "rules.md")
|
|
163428
|
+
];
|
|
163429
|
+
let memoryText = "";
|
|
163430
|
+
for (const candidate of memoryCandidates) {
|
|
163431
|
+
try {
|
|
163432
|
+
if (fs19.existsSync(candidate) && fs19.statSync(candidate).isFile()) {
|
|
163433
|
+
const content = fs19.readFileSync(candidate, "utf8").trim();
|
|
163434
|
+
if (content) {
|
|
163435
|
+
memoryText = content;
|
|
163436
|
+
break;
|
|
163437
|
+
}
|
|
163438
|
+
}
|
|
163439
|
+
} catch {}
|
|
163440
|
+
}
|
|
163441
|
+
let rulesText = "";
|
|
163442
|
+
for (const candidate of rulesCandidates) {
|
|
163443
|
+
try {
|
|
163444
|
+
if (fs19.existsSync(candidate) && fs19.statSync(candidate).isFile()) {
|
|
163445
|
+
const content = fs19.readFileSync(candidate, "utf8").trim();
|
|
163446
|
+
if (content) {
|
|
163447
|
+
rulesText = content;
|
|
163448
|
+
break;
|
|
163449
|
+
}
|
|
163450
|
+
}
|
|
163451
|
+
} catch {}
|
|
163452
|
+
}
|
|
163453
|
+
const parts = [];
|
|
163454
|
+
if (memoryText)
|
|
163455
|
+
parts.push(memoryText);
|
|
163456
|
+
if (rulesText && rulesText !== memoryText)
|
|
163457
|
+
parts.push(rulesText);
|
|
163458
|
+
return parts.join(`
|
|
163459
|
+
|
|
163460
|
+
`).trim();
|
|
163461
|
+
}
|
|
163462
|
+
injectMemoryBlock(prompt, memoryContent) {
|
|
163463
|
+
if (!memoryContent.trim())
|
|
163464
|
+
return prompt;
|
|
163465
|
+
if (prompt.includes("<project_memory>"))
|
|
163466
|
+
return prompt;
|
|
163467
|
+
const block = `<project_memory>
|
|
163468
|
+
${memoryContent.trim()}
|
|
163469
|
+
</project_memory>`;
|
|
163470
|
+
if (!prompt)
|
|
163471
|
+
return block;
|
|
163472
|
+
if (prompt.includes(`
|
|
163473
|
+
|
|
163474
|
+
Current date:`)) {
|
|
163475
|
+
return prompt.replace(`
|
|
163476
|
+
|
|
163477
|
+
Current date:`, `
|
|
163478
|
+
|
|
163479
|
+
${block}
|
|
163480
|
+
|
|
163481
|
+
Current date:`);
|
|
163482
|
+
}
|
|
163483
|
+
return `${prompt}
|
|
163484
|
+
|
|
163485
|
+
${block}`;
|
|
162808
163486
|
}
|
|
162809
163487
|
get messages() {
|
|
162810
163488
|
return this._messages;
|
|
@@ -163559,10 +164237,10 @@ class LangfuseMedia {
|
|
|
163559
164237
|
this._contentType = contentType;
|
|
163560
164238
|
this._source = "bytes";
|
|
163561
164239
|
} else if (filePath && contentType) {
|
|
163562
|
-
if (!
|
|
164240
|
+
if (!fs20) {
|
|
163563
164241
|
throw new Error("File system support is not available in this environment");
|
|
163564
164242
|
}
|
|
163565
|
-
if (!
|
|
164243
|
+
if (!fs20.existsSync(filePath)) {
|
|
163566
164244
|
throw new Error(`File at path ${filePath} does not exist`);
|
|
163567
164245
|
}
|
|
163568
164246
|
this._contentBytes = this.readFile(filePath);
|
|
@@ -163574,10 +164252,10 @@ class LangfuseMedia {
|
|
|
163574
164252
|
}
|
|
163575
164253
|
readFile(filePath) {
|
|
163576
164254
|
try {
|
|
163577
|
-
if (!
|
|
164255
|
+
if (!fs20) {
|
|
163578
164256
|
throw new Error("File system support is not available in this environment");
|
|
163579
164257
|
}
|
|
163580
|
-
return
|
|
164258
|
+
return fs20.readFileSync(filePath);
|
|
163581
164259
|
} catch (error) {
|
|
163582
164260
|
console.error(`Error reading file at path ${filePath}`, error);
|
|
163583
164261
|
return;
|
|
@@ -164699,7 +165377,7 @@ var DEFAULT_PROMPT_CACHE_TTL_SECONDS = 60, LangfusePersistedProperty, ChatMessag
|
|
|
164699
165377
|
}
|
|
164700
165378
|
});
|
|
164701
165379
|
return queryParams.toString();
|
|
164702
|
-
}, utils, common_release_envs,
|
|
165380
|
+
}, utils, common_release_envs, fs20 = null, cryptoModule = null, dynamicImport = (module) => {
|
|
164703
165381
|
return import(module);
|
|
164704
165382
|
}, MAX_EVENT_SIZE_BYTES, MAX_BATCH_SIZE_BYTES, ENVIRONMENT_PATTERN, WHITELISTED_LANGFUSE_INTERNAL_ENVIRONMENTS, LangfuseFetchHttpError, LangfuseFetchNetworkError, SUPPORT_URL = "https://langfuse.com/support", API_DOCS_URL = "https://api.reference.langfuse.com", RBAC_DOCS_URL = "https://langfuse.com/docs/rbac", INSTALLATION_DOCS_URL = "https://langfuse.com/docs/sdk/typescript/guide", RATE_LIMITS_URL = "https://langfuse.com/faq/all/api-limits", NPM_PACKAGE_URL = "https://www.npmjs.com/package/langfuse", updatePromptResponse, defaultServerErrorPrompt, defaultErrorResponse, errorResponseByCode, LangfuseCore, LangfuseTraceClient, LangfuseObservationClient, LangfuseSpanClient, LangfuseGenerationClient, LangfuseEventClient;
|
|
164705
165383
|
var init_lib = __esm(() => {
|
|
@@ -164878,12 +165556,12 @@ var init_lib = __esm(() => {
|
|
|
164878
165556
|
];
|
|
164879
165557
|
if (typeof globalThis.Deno !== "undefined") {
|
|
164880
165558
|
Promise.all([dynamicImport("node:fs"), dynamicImport("node:crypto")]).then(([importedFs, importedCrypto]) => {
|
|
164881
|
-
|
|
165559
|
+
fs20 = importedFs;
|
|
164882
165560
|
cryptoModule = importedCrypto;
|
|
164883
165561
|
}).catch();
|
|
164884
165562
|
} else if (typeof process !== "undefined" && process.versions?.node) {
|
|
164885
165563
|
Promise.all([dynamicImport("fs"), dynamicImport("crypto")]).then(([importedFs, importedCrypto]) => {
|
|
164886
|
-
|
|
165564
|
+
fs20 = importedFs;
|
|
164887
165565
|
cryptoModule = importedCrypto;
|
|
164888
165566
|
}).catch();
|
|
164889
165567
|
} else if (typeof crypto !== "undefined") {
|
|
@@ -166386,29 +167064,73 @@ var init_tracer_factory = __esm(() => {
|
|
|
166386
167064
|
});
|
|
166387
167065
|
|
|
166388
167066
|
// ../../packages/agent/src/utils/evaporation.ts
|
|
166389
|
-
function
|
|
167067
|
+
function isErrorToolOutput(content) {
|
|
167068
|
+
const lower = content.toLowerCase();
|
|
167069
|
+
return content.includes("[Tool Error]") || lower.includes("error:") || lower.includes("command failed") || lower.includes("exit code 1") || lower.includes("exit code 2") || lower.includes("failed:") || lower.includes("traceback (most recent call last)") || lower.includes("exception:") || lower.includes("fatal:") || lower.includes("panic:") || lower.includes("syntaxerror");
|
|
167070
|
+
}
|
|
167071
|
+
function truncateLargeToolOutput(rawContent, maxBytes = 6 * 1024, headLines = 20, tailLines = 20) {
|
|
167072
|
+
const byteLength = Buffer.byteLength(rawContent, "utf8");
|
|
167073
|
+
if (byteLength <= maxBytes) {
|
|
167074
|
+
return rawContent;
|
|
167075
|
+
}
|
|
167076
|
+
if (isErrorToolOutput(rawContent)) {
|
|
167077
|
+
return rawContent;
|
|
167078
|
+
}
|
|
167079
|
+
const lines = rawContent.split(`
|
|
167080
|
+
`);
|
|
167081
|
+
if (lines.length <= headLines + tailLines) {
|
|
167082
|
+
return rawContent;
|
|
167083
|
+
}
|
|
167084
|
+
const head = lines.slice(0, headLines).join(`
|
|
167085
|
+
`);
|
|
167086
|
+
const tail = lines.slice(lines.length - tailLines).join(`
|
|
167087
|
+
`);
|
|
167088
|
+
const omittedLines = lines.length - headLines - tailLines;
|
|
167089
|
+
const omittedBytes = byteLength - Buffer.byteLength(head, "utf8") - Buffer.byteLength(tail, "utf8");
|
|
167090
|
+
const omittedKb = (omittedBytes / 1024).toFixed(1);
|
|
167091
|
+
const banner = `
|
|
167092
|
+
|
|
167093
|
+
[... ${omittedLines} lines truncated (${omittedKb} KB) ...]
|
|
167094
|
+
|
|
167095
|
+
`;
|
|
167096
|
+
return head + banner + tail;
|
|
167097
|
+
}
|
|
167098
|
+
function evaporateStaleToolOutputs(messages, preserveRecentTurnsOrOptions = 3, preserveRecentStepsArg) {
|
|
166390
167099
|
if (!messages || messages.length === 0)
|
|
166391
167100
|
return [];
|
|
167101
|
+
let preserveRecentTurns = 3;
|
|
167102
|
+
let preserveRecentSteps = 2;
|
|
167103
|
+
let maxOutputSize = 6 * 1024;
|
|
167104
|
+
let headLines = 20;
|
|
167105
|
+
let tailLines = 20;
|
|
167106
|
+
if (typeof preserveRecentTurnsOrOptions === "number") {
|
|
167107
|
+
preserveRecentTurns = preserveRecentTurnsOrOptions;
|
|
167108
|
+
if (preserveRecentStepsArg !== undefined) {
|
|
167109
|
+
preserveRecentSteps = preserveRecentStepsArg;
|
|
167110
|
+
}
|
|
167111
|
+
} else if (typeof preserveRecentTurnsOrOptions === "object") {
|
|
167112
|
+
preserveRecentTurns = preserveRecentTurnsOrOptions.preserveRecentTurns ?? 3;
|
|
167113
|
+
preserveRecentSteps = preserveRecentTurnsOrOptions.preserveRecentSteps ?? 2;
|
|
167114
|
+
maxOutputSize = preserveRecentTurnsOrOptions.maxOutputSize ?? 6 * 1024;
|
|
167115
|
+
headLines = preserveRecentTurnsOrOptions.headLines ?? 20;
|
|
167116
|
+
tailLines = preserveRecentTurnsOrOptions.tailLines ?? 20;
|
|
167117
|
+
}
|
|
166392
167118
|
let userTurnsSeen = 0;
|
|
166393
|
-
let
|
|
167119
|
+
let agentStepsSeen = 0;
|
|
167120
|
+
const isStale = new Array(messages.length).fill(false);
|
|
166394
167121
|
for (let i = messages.length - 1;i >= 0; i--) {
|
|
166395
167122
|
const msg = messages[i];
|
|
167123
|
+
if (!msg)
|
|
167124
|
+
continue;
|
|
166396
167125
|
if (msg.role === "user" && !msg.isUI) {
|
|
166397
167126
|
userTurnsSeen++;
|
|
166398
|
-
if (userTurnsSeen >= preserveRecentTurns) {
|
|
166399
|
-
cutoffIndex = i;
|
|
166400
|
-
break;
|
|
166401
|
-
}
|
|
166402
167127
|
}
|
|
166403
|
-
|
|
166404
|
-
|
|
166405
|
-
|
|
166406
|
-
|
|
166407
|
-
|
|
166408
|
-
|
|
166409
|
-
toolCalls: m.toolCalls,
|
|
166410
|
-
toolCallId: m.toolCallId
|
|
166411
|
-
}));
|
|
167128
|
+
if (msg.role === "assistant" && (msg.toolCalls?.length || 0) > 0) {
|
|
167129
|
+
agentStepsSeen++;
|
|
167130
|
+
}
|
|
167131
|
+
if (userTurnsSeen >= preserveRecentTurns || agentStepsSeen >= preserveRecentSteps) {
|
|
167132
|
+
isStale[i] = true;
|
|
167133
|
+
}
|
|
166412
167134
|
}
|
|
166413
167135
|
return messages.map((msg, idx) => {
|
|
166414
167136
|
const baseMsg = {
|
|
@@ -166418,27 +167140,37 @@ function evaporateStaleToolOutputs(messages, preserveRecentTurns = 3) {
|
|
|
166418
167140
|
toolCalls: msg.toolCalls,
|
|
166419
167141
|
toolCallId: msg.toolCallId
|
|
166420
167142
|
};
|
|
166421
|
-
if (
|
|
167143
|
+
if (msg.role !== "tool") {
|
|
166422
167144
|
return baseMsg;
|
|
166423
167145
|
}
|
|
166424
|
-
|
|
166425
|
-
|
|
166426
|
-
|
|
166427
|
-
|
|
166428
|
-
|
|
166429
|
-
|
|
166430
|
-
|
|
166431
|
-
|
|
167146
|
+
const rawContent = typeof msg.content === "string" ? msg.content : JSON.stringify(msg.content);
|
|
167147
|
+
if (rawContent.length < 200) {
|
|
167148
|
+
return baseMsg;
|
|
167149
|
+
}
|
|
167150
|
+
if (isErrorToolOutput(rawContent)) {
|
|
167151
|
+
return baseMsg;
|
|
167152
|
+
}
|
|
167153
|
+
if (rawContent.startsWith("[Tool Output Evaporated:") || rawContent.startsWith("[tool output microcompacted:") || rawContent.startsWith("[Old tool result content cleared]")) {
|
|
167154
|
+
return baseMsg;
|
|
167155
|
+
}
|
|
167156
|
+
if (isStale[idx]) {
|
|
166432
167157
|
const lines = rawContent.split(`
|
|
166433
167158
|
`);
|
|
166434
167159
|
const lineCount = lines.length;
|
|
166435
167160
|
const byteSize = (Buffer.byteLength(rawContent, "utf8") / 1024).toFixed(1);
|
|
166436
|
-
const tombstone = `[Tool Output Evaporated: ${lineCount} lines (${byteSize} KB). Content previously processed by assistant.]`;
|
|
167161
|
+
const tombstone = `[Tool Output Evaporated: ${lineCount} lines (${byteSize} KB). exit code 0. Content previously processed by assistant.]`;
|
|
166437
167162
|
return {
|
|
166438
167163
|
...baseMsg,
|
|
166439
167164
|
content: tombstone
|
|
166440
167165
|
};
|
|
166441
167166
|
}
|
|
167167
|
+
const truncated = truncateLargeToolOutput(rawContent, maxOutputSize, headLines, tailLines);
|
|
167168
|
+
if (truncated !== rawContent) {
|
|
167169
|
+
return {
|
|
167170
|
+
...baseMsg,
|
|
167171
|
+
content: truncated
|
|
167172
|
+
};
|
|
167173
|
+
}
|
|
166442
167174
|
return baseMsg;
|
|
166443
167175
|
});
|
|
166444
167176
|
}
|
|
@@ -166503,8 +167235,14 @@ class Agent2 {
|
|
|
166503
167235
|
this.convertToLlm = config.convertToLlm || this.defaultConvertToLlm;
|
|
166504
167236
|
this.steeringQueue = new PendingMessageQueue(config.steeringMode || "all");
|
|
166505
167237
|
this.followUpQueue = new PendingMessageQueue(config.followUpMode || "all");
|
|
166506
|
-
this.conversation = new ConversationManager;
|
|
166507
167238
|
this.workspaceDir = config.workspaceDir;
|
|
167239
|
+
this.conversation = new ConversationManager([], {
|
|
167240
|
+
workspaceRoot: config.workspaceDir
|
|
167241
|
+
});
|
|
167242
|
+
this.systemPrompt = this.conversation.initSession({
|
|
167243
|
+
workspaceRoot: config.workspaceDir,
|
|
167244
|
+
systemPrompt: this.systemPrompt
|
|
167245
|
+
});
|
|
166508
167246
|
this.logsDir = config.logsDir;
|
|
166509
167247
|
this.disableLogging = config.disableLogging || false;
|
|
166510
167248
|
this.deferredRegistry = config.deferredRegistry || new DeferredToolRegistry;
|
|
@@ -166522,10 +167260,12 @@ class Agent2 {
|
|
|
166522
167260
|
this.deferredRegistry.register(tool);
|
|
166523
167261
|
}
|
|
166524
167262
|
}
|
|
166525
|
-
this.conversation.
|
|
166526
|
-
|
|
166527
|
-
|
|
166528
|
-
|
|
167263
|
+
if (this.conversation.messages.length === 0) {
|
|
167264
|
+
this.conversation.addMessage({
|
|
167265
|
+
role: "system",
|
|
167266
|
+
content: this.systemPrompt
|
|
167267
|
+
});
|
|
167268
|
+
}
|
|
166529
167269
|
}
|
|
166530
167270
|
get messages() {
|
|
166531
167271
|
return this.conversation.messages;
|
|
@@ -166535,16 +167275,26 @@ class Agent2 {
|
|
|
166535
167275
|
}
|
|
166536
167276
|
defaultConvertToLlm(messages) {
|
|
166537
167277
|
const filtered = messages.filter((m) => !m.isUI);
|
|
166538
|
-
const evaporated = evaporateStaleToolOutputs(filtered,
|
|
167278
|
+
const evaporated = evaporateStaleToolOutputs(filtered, {
|
|
167279
|
+
preserveRecentTurns: 3,
|
|
167280
|
+
preserveRecentSteps: 2,
|
|
167281
|
+
maxOutputSize: 6 * 1024
|
|
167282
|
+
});
|
|
166539
167283
|
const merged = [];
|
|
166540
|
-
for (
|
|
167284
|
+
for (let i = 0;i < evaporated.length; i++) {
|
|
167285
|
+
const msg = evaporated[i];
|
|
167286
|
+
let role = msg.role;
|
|
167287
|
+
const content = msg.content;
|
|
167288
|
+
if (role === "system" && i > 0 && content.includes("[COMPACTED HISTORY SUMMARY]")) {
|
|
167289
|
+
role = "user";
|
|
167290
|
+
}
|
|
166541
167291
|
const prev = merged[merged.length - 1];
|
|
166542
|
-
if (prev && prev.role === "user" &&
|
|
167292
|
+
if (prev && prev.role === "user" && role === "user" && !prev.toolCalls && !msg.toolCalls) {
|
|
166543
167293
|
prev.content = `${prev.content}
|
|
166544
167294
|
|
|
166545
|
-
${
|
|
167295
|
+
${content}`;
|
|
166546
167296
|
} else {
|
|
166547
|
-
merged.push({ ...msg });
|
|
167297
|
+
merged.push({ ...msg, role, content });
|
|
166548
167298
|
}
|
|
166549
167299
|
}
|
|
166550
167300
|
return merged;
|
|
@@ -166858,9 +167608,9 @@ var init_p_retry = __esm(() => {
|
|
|
166858
167608
|
});
|
|
166859
167609
|
|
|
166860
167610
|
// ../../packages/agent/src/utils/request-logger.ts
|
|
166861
|
-
import
|
|
167611
|
+
import fs21 from "node:fs";
|
|
166862
167612
|
import os11 from "node:os";
|
|
166863
|
-
import
|
|
167613
|
+
import path23 from "node:path";
|
|
166864
167614
|
function createRequestLogEntry(params) {
|
|
166865
167615
|
const {
|
|
166866
167616
|
turn,
|
|
@@ -166913,11 +167663,11 @@ function getGlobalConfigDir() {
|
|
|
166913
167663
|
const home = process.env.HOME || os11.homedir();
|
|
166914
167664
|
const isTestEnv = !!process.env.VITEST;
|
|
166915
167665
|
if (isTestEnv && home === os11.homedir()) {
|
|
166916
|
-
return
|
|
167666
|
+
return path23.join(os11.tmpdir(), "december-test-config", ".december");
|
|
166917
167667
|
}
|
|
166918
|
-
const canonicalDir =
|
|
166919
|
-
const legacyDir =
|
|
166920
|
-
if (
|
|
167668
|
+
const canonicalDir = path23.join(home, ".december");
|
|
167669
|
+
const legacyDir = path23.join(home, ".config", "december");
|
|
167670
|
+
if (fs21.existsSync(canonicalDir) || !fs21.existsSync(legacyDir)) {
|
|
166921
167671
|
return canonicalDir;
|
|
166922
167672
|
}
|
|
166923
167673
|
return legacyDir;
|
|
@@ -166927,7 +167677,7 @@ function getLogsDir(customDir) {
|
|
|
166927
167677
|
return customDir;
|
|
166928
167678
|
if (process.env.DECEMBER_LOGS_DIR)
|
|
166929
167679
|
return process.env.DECEMBER_LOGS_DIR;
|
|
166930
|
-
return
|
|
167680
|
+
return path23.join(getGlobalConfigDir(), "logs");
|
|
166931
167681
|
}
|
|
166932
167682
|
function getSessionLogPath(sessionIdOrLogsDir, logsDirOrSessionId) {
|
|
166933
167683
|
if (!sessionIdOrLogsDir && !logsDirOrSessionId)
|
|
@@ -166935,7 +167685,7 @@ function getSessionLogPath(sessionIdOrLogsDir, logsDirOrSessionId) {
|
|
|
166935
167685
|
let sessionId;
|
|
166936
167686
|
let customDir;
|
|
166937
167687
|
if (logsDirOrSessionId) {
|
|
166938
|
-
if (sessionIdOrLogsDir.startsWith("session-") || !sessionIdOrLogsDir.includes(
|
|
167688
|
+
if (sessionIdOrLogsDir.startsWith("session-") || !sessionIdOrLogsDir.includes(path23.sep) && logsDirOrSessionId.includes(path23.sep)) {
|
|
166939
167689
|
sessionId = sessionIdOrLogsDir;
|
|
166940
167690
|
customDir = logsDirOrSessionId;
|
|
166941
167691
|
} else {
|
|
@@ -166946,7 +167696,7 @@ function getSessionLogPath(sessionIdOrLogsDir, logsDirOrSessionId) {
|
|
|
166946
167696
|
sessionId = sessionIdOrLogsDir;
|
|
166947
167697
|
}
|
|
166948
167698
|
const cleanSessionId = sessionId.startsWith("session-") ? sessionId : `session-${sessionId}`;
|
|
166949
|
-
return
|
|
167699
|
+
return path23.join(getLogsDir(customDir), `${cleanSessionId}.jsonl`);
|
|
166950
167700
|
}
|
|
166951
167701
|
async function appendTurnLog(arg1, arg2, arg3) {
|
|
166952
167702
|
try {
|
|
@@ -166969,11 +167719,11 @@ async function appendTurnLog(arg1, arg2, arg3) {
|
|
|
166969
167719
|
const logFile = getSessionLogPath(sessionId, logsDir);
|
|
166970
167720
|
if (!logFile)
|
|
166971
167721
|
return;
|
|
166972
|
-
const dir =
|
|
166973
|
-
await
|
|
167722
|
+
const dir = path23.dirname(logFile);
|
|
167723
|
+
await fs21.promises.mkdir(dir, { recursive: true });
|
|
166974
167724
|
const line = JSON.stringify(entry) + `
|
|
166975
167725
|
`;
|
|
166976
|
-
await
|
|
167726
|
+
await fs21.promises.appendFile(logFile, line, "utf8");
|
|
166977
167727
|
} catch {}
|
|
166978
167728
|
}
|
|
166979
167729
|
var init_request_logger = __esm(() => {
|
|
@@ -167752,17 +168502,17 @@ var init_agent_loop = __esm(() => {
|
|
|
167752
168502
|
]);
|
|
167753
168503
|
});
|
|
167754
168504
|
// ../../packages/agent/src/skills/skill-subagent.ts
|
|
167755
|
-
import
|
|
168505
|
+
import fs22 from "node:fs";
|
|
167756
168506
|
async function executeSkillInSubagent(options) {
|
|
167757
168507
|
const { skill, args = [], task, parentAgent, signal, onEvent } = options;
|
|
167758
168508
|
let rawBody = skill.content || "";
|
|
167759
|
-
if (!rawBody && skill.entryFilePath &&
|
|
168509
|
+
if (!rawBody && skill.entryFilePath && fs22.existsSync(skill.entryFilePath)) {
|
|
167760
168510
|
try {
|
|
167761
168511
|
const parsed = parseSkillFile(skill.entryFilePath);
|
|
167762
168512
|
rawBody = parsed.body;
|
|
167763
168513
|
} catch {
|
|
167764
168514
|
try {
|
|
167765
|
-
rawBody =
|
|
168515
|
+
rawBody = fs22.readFileSync(skill.entryFilePath, "utf8");
|
|
167766
168516
|
} catch (err) {
|
|
167767
168517
|
return {
|
|
167768
168518
|
success: false,
|
|
@@ -167910,9 +168660,9 @@ var init_run_skill_tool = __esm(() => {
|
|
|
167910
168660
|
});
|
|
167911
168661
|
|
|
167912
168662
|
// ../../packages/agent/src/harness/agent-harness.ts
|
|
167913
|
-
import
|
|
168663
|
+
import fs23 from "node:fs";
|
|
167914
168664
|
import os12 from "node:os";
|
|
167915
|
-
import
|
|
168665
|
+
import path24 from "node:path";
|
|
167916
168666
|
function isReasoningModel(model, thinkingLevel) {
|
|
167917
168667
|
if (thinkingLevel === "off") {
|
|
167918
168668
|
return false;
|
|
@@ -167937,7 +168687,8 @@ function getModelFamilyPrompt(options) {
|
|
|
167937
168687
|
- Proactive Task Breakdown: Break down complex requests into orderly stages, verify each stage empirically, and maintain single-step transitions.`;
|
|
167938
168688
|
} else if (model.includes("gemini")) {
|
|
167939
168689
|
roleGuidelines = `### Model Specialization (Gemini)
|
|
167940
|
-
- Structured Execution: Follow clear operational phases: 1) Explore and gather context, 2) Formulate targeted edits, 3) Verify thoroughly.
|
|
168690
|
+
- Structured Execution: Follow clear operational phases: 1) Explore and gather context (inspect repo layout in monorepos before deep-diving), 2) Formulate targeted edits, 3) Verify thoroughly.
|
|
168691
|
+
- Efficient Verification: Run verification tests only after modifying files, not during early exploratory discovery. Once targeted tests pass and git diff is verified clean, complete your response immediately without repeating status, diff, or test commands.
|
|
167941
168692
|
- Absolute File Paths: STRICTLY specify absolute file paths when referencing, viewing, or editing files. NEVER output ambiguous relative paths.`;
|
|
167942
168693
|
}
|
|
167943
168694
|
return {
|
|
@@ -167973,22 +168724,22 @@ function discoverProjectRules(startDir, rootBoundary) {
|
|
|
167973
168724
|
"AGENTS.override.md",
|
|
167974
168725
|
"AGENTS.md",
|
|
167975
168726
|
"CLAUDE.md",
|
|
167976
|
-
|
|
167977
|
-
|
|
168727
|
+
path24.join(".december", "rules.md"),
|
|
168728
|
+
path24.join(".december", "AGENTS.md")
|
|
167978
168729
|
];
|
|
167979
168730
|
const seen = new Set;
|
|
167980
|
-
let current =
|
|
167981
|
-
const boundary = rootBoundary ?
|
|
168731
|
+
let current = path24.resolve(startDir);
|
|
168732
|
+
const boundary = rootBoundary ? path24.resolve(rootBoundary) : path24.parse(current).root;
|
|
167982
168733
|
const collectedFiles = [];
|
|
167983
168734
|
while (true) {
|
|
167984
168735
|
for (const name of candidateNames) {
|
|
167985
|
-
const candidatePath =
|
|
167986
|
-
if (
|
|
168736
|
+
const candidatePath = path24.join(current, name);
|
|
168737
|
+
if (fs23.existsSync(candidatePath)) {
|
|
167987
168738
|
try {
|
|
167988
|
-
if (
|
|
168739
|
+
if (fs23.statSync(candidatePath).isFile()) {
|
|
167989
168740
|
if (!seen.has(candidatePath)) {
|
|
167990
168741
|
seen.add(candidatePath);
|
|
167991
|
-
const content =
|
|
168742
|
+
const content = fs23.readFileSync(candidatePath, "utf8").trim();
|
|
167992
168743
|
if (content) {
|
|
167993
168744
|
collectedFiles.unshift({ path: candidatePath, content });
|
|
167994
168745
|
}
|
|
@@ -167999,7 +168750,7 @@ function discoverProjectRules(startDir, rootBoundary) {
|
|
|
167999
168750
|
}
|
|
168000
168751
|
if (current === boundary)
|
|
168001
168752
|
break;
|
|
168002
|
-
const parent =
|
|
168753
|
+
const parent = path24.dirname(current);
|
|
168003
168754
|
if (parent === current)
|
|
168004
168755
|
break;
|
|
168005
168756
|
current = parent;
|
|
@@ -168007,17 +168758,17 @@ function discoverProjectRules(startDir, rootBoundary) {
|
|
|
168007
168758
|
const home = process.env.HOME || process.env.USERPROFILE || os12.homedir();
|
|
168008
168759
|
const globalCandidateDirs = [
|
|
168009
168760
|
process.env.DECEMBER_CONFIG_DIR,
|
|
168010
|
-
|
|
168011
|
-
|
|
168761
|
+
path24.join(home, ".december"),
|
|
168762
|
+
path24.join(home, ".config", "december")
|
|
168012
168763
|
].filter((dir) => !!dir);
|
|
168013
168764
|
for (const globalDir of globalCandidateDirs) {
|
|
168014
168765
|
for (const candidate of ["rules.md", "AGENTS.md"]) {
|
|
168015
|
-
const globalPath =
|
|
168016
|
-
if (
|
|
168766
|
+
const globalPath = path24.join(globalDir, candidate);
|
|
168767
|
+
if (fs23.existsSync(globalPath) && !seen.has(globalPath)) {
|
|
168017
168768
|
try {
|
|
168018
|
-
if (
|
|
168769
|
+
if (fs23.statSync(globalPath).isFile()) {
|
|
168019
168770
|
seen.add(globalPath);
|
|
168020
|
-
const content =
|
|
168771
|
+
const content = fs23.readFileSync(globalPath, "utf8").trim();
|
|
168021
168772
|
if (content) {
|
|
168022
168773
|
collectedFiles.unshift({ path: globalPath, content });
|
|
168023
168774
|
}
|
|
@@ -168099,7 +168850,7 @@ You operate across two environments seamlessly: locally via a terminal CLI, and
|
|
|
168099
168850
|
`### Core Operating Principles & Guardrails
|
|
168100
168851
|
1. Inspect Logs & Stack Traces First: NEVER diagnose errors or failures without fetching and reading full un-truncated error logs. Base diagnoses strictly on empirical log evidence.
|
|
168101
168852
|
2. Root Cause Resolution: NEVER mask symptoms, swallow exceptions silently, use dummy fallbacks, or delete/comment out failing tests. Address the root cause directly.
|
|
168102
|
-
3. Execution & Verification: NEVER claim a task or fix is complete without running build, type-check, or test verification commands to empirically prove it works.
|
|
168853
|
+
3. Execution & Verification: NEVER claim a task or fix is complete without running build, type-check, or test verification commands to empirically prove it works. Do not run heavy build or test suites prematurely during early discovery before any code is modified. Target verification to the modified component rather than full monorepo rebuilds when possible. Once targeted verification succeeds and git diff confirms clean changes, conclude your turn promptly without redundant re-verification loops.
|
|
168103
168854
|
4. Preserving Integrity: Always preserve existing docstrings, comments, and public API signatures unless explicitly asked to modify them.
|
|
168104
168855
|
5. Absolute File Paths: ALWAYS specify absolute file paths when referencing, viewing, or editing files.
|
|
168105
168856
|
6. Strict Workspace Boundary: All operations (file reads, writes, searches, bash commands) must be strictly confined within the workspace directory (/workspace or current working directory). NEVER inspect, explore, or search system root paths or directories outside the workspace (such as /etc, /root, /bin, /var).
|
|
@@ -168273,6 +169024,12 @@ var init_agent_harness = __esm(() => {
|
|
|
168273
169024
|
guidelines: [
|
|
168274
169025
|
"Use 'run_skill' to delegate complex procedural workflows or specialized domain tasks to an isolated subagent, keeping the main conversation context clean."
|
|
168275
169026
|
]
|
|
169027
|
+
},
|
|
169028
|
+
manage_memory: {
|
|
169029
|
+
snippet: "Record, read, or prune persistent workspace rules and memories",
|
|
169030
|
+
guidelines: [
|
|
169031
|
+
"Use 'manage_memory' to record learned conventions, build/test commands, architecture notes, and quirks into persistent workspace memory."
|
|
169032
|
+
]
|
|
168276
169033
|
}
|
|
168277
169034
|
};
|
|
168278
169035
|
});
|
|
@@ -168287,10 +169044,383 @@ var init_telemetry = __esm(() => {
|
|
|
168287
169044
|
init_tracer_factory();
|
|
168288
169045
|
});
|
|
168289
169046
|
|
|
169047
|
+
// ../../packages/agent/src/lsp-client.ts
|
|
169048
|
+
import { spawn as spawn3 } from "node:child_process";
|
|
169049
|
+
import fs24 from "node:fs";
|
|
169050
|
+
import path25 from "node:path";
|
|
169051
|
+
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
169052
|
+
|
|
169053
|
+
class LspClient {
|
|
169054
|
+
workspaceRoot;
|
|
169055
|
+
binaryPath;
|
|
169056
|
+
requestTimeoutMs;
|
|
169057
|
+
child = null;
|
|
169058
|
+
nextId = 1;
|
|
169059
|
+
pendingRequests = new Map;
|
|
169060
|
+
buffer = Buffer.alloc(0);
|
|
169061
|
+
diagnosticsByUri = new Map;
|
|
169062
|
+
openedDocuments = new Set;
|
|
169063
|
+
initPromise = null;
|
|
169064
|
+
isShutdown = false;
|
|
169065
|
+
constructor(options) {
|
|
169066
|
+
this.workspaceRoot = path25.resolve(options.workspaceRoot);
|
|
169067
|
+
this.binaryPath = options.binaryPath;
|
|
169068
|
+
this.requestTimeoutMs = options.requestTimeoutMs ?? 15000;
|
|
169069
|
+
}
|
|
169070
|
+
async start() {
|
|
169071
|
+
if (this.initPromise) {
|
|
169072
|
+
return this.initPromise;
|
|
169073
|
+
}
|
|
169074
|
+
this.initPromise = this.initInternal();
|
|
169075
|
+
return this.initPromise;
|
|
169076
|
+
}
|
|
169077
|
+
findBinary() {
|
|
169078
|
+
if (this.binaryPath && fs24.existsSync(this.binaryPath)) {
|
|
169079
|
+
return this.binaryPath;
|
|
169080
|
+
}
|
|
169081
|
+
const candidatePaths = [
|
|
169082
|
+
path25.resolve(this.workspaceRoot, "node_modules/.bin/typescript-language-server"),
|
|
169083
|
+
path25.resolve(process.cwd(), "node_modules/.bin/typescript-language-server"),
|
|
169084
|
+
path25.resolve(process.cwd(), "node_modules/typescript-language-server/lib/cli.mjs")
|
|
169085
|
+
];
|
|
169086
|
+
for (const candidate of candidatePaths) {
|
|
169087
|
+
if (fs24.existsSync(candidate)) {
|
|
169088
|
+
return candidate;
|
|
169089
|
+
}
|
|
169090
|
+
}
|
|
169091
|
+
return "typescript-language-server";
|
|
169092
|
+
}
|
|
169093
|
+
async initInternal() {
|
|
169094
|
+
const bin = this.findBinary();
|
|
169095
|
+
this.child = spawn3(bin, ["--stdio"], {
|
|
169096
|
+
cwd: this.workspaceRoot,
|
|
169097
|
+
env: { ...process.env },
|
|
169098
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
169099
|
+
});
|
|
169100
|
+
this.child.stdout?.on("data", (chunk) => {
|
|
169101
|
+
this.handleStdout(chunk);
|
|
169102
|
+
});
|
|
169103
|
+
this.child.stderr?.on("data", (_chunk) => {});
|
|
169104
|
+
this.child.on("error", (err) => {
|
|
169105
|
+
this.rejectAllPending(new Error(`LSP process error: ${err.message}`));
|
|
169106
|
+
});
|
|
169107
|
+
this.child.on("exit", (code) => {
|
|
169108
|
+
this.rejectAllPending(new Error(`LSP process exited with code ${code}`));
|
|
169109
|
+
this.child = null;
|
|
169110
|
+
this.initPromise = null;
|
|
169111
|
+
});
|
|
169112
|
+
const rootUri = pathToFileURL(this.workspaceRoot).toString();
|
|
169113
|
+
await this.sendRequest("initialize", {
|
|
169114
|
+
processId: process.pid,
|
|
169115
|
+
rootUri,
|
|
169116
|
+
rootPath: this.workspaceRoot,
|
|
169117
|
+
capabilities: {
|
|
169118
|
+
textDocument: {
|
|
169119
|
+
definition: { dynamicRegistration: false, linkSupport: true },
|
|
169120
|
+
references: { dynamicRegistration: false },
|
|
169121
|
+
documentSymbol: {
|
|
169122
|
+
dynamicRegistration: false,
|
|
169123
|
+
hierarchicalDocumentSymbolSupport: true
|
|
169124
|
+
},
|
|
169125
|
+
synchronization: {
|
|
169126
|
+
dynamicRegistration: false,
|
|
169127
|
+
willSave: false,
|
|
169128
|
+
didSave: true
|
|
169129
|
+
}
|
|
169130
|
+
}
|
|
169131
|
+
}
|
|
169132
|
+
});
|
|
169133
|
+
this.sendNotification("initialized", {});
|
|
169134
|
+
}
|
|
169135
|
+
handleStdout(chunk) {
|
|
169136
|
+
this.buffer = Buffer.concat([this.buffer, chunk]);
|
|
169137
|
+
while (true) {
|
|
169138
|
+
const headerEnd = this.buffer.indexOf(`\r
|
|
169139
|
+
\r
|
|
169140
|
+
`);
|
|
169141
|
+
if (headerEnd === -1)
|
|
169142
|
+
break;
|
|
169143
|
+
const headerStr = this.buffer.subarray(0, headerEnd).toString("utf8");
|
|
169144
|
+
const match = headerStr.match(/Content-Length:\s*(\d+)/i);
|
|
169145
|
+
if (!match) {
|
|
169146
|
+
this.buffer = this.buffer.subarray(headerEnd + 4);
|
|
169147
|
+
continue;
|
|
169148
|
+
}
|
|
169149
|
+
const contentLength = parseInt(match[1], 10);
|
|
169150
|
+
const totalMsgLength = headerEnd + 4 + contentLength;
|
|
169151
|
+
if (this.buffer.length < totalMsgLength)
|
|
169152
|
+
break;
|
|
169153
|
+
const body = this.buffer.subarray(headerEnd + 4, totalMsgLength).toString("utf8");
|
|
169154
|
+
this.buffer = this.buffer.subarray(totalMsgLength);
|
|
169155
|
+
try {
|
|
169156
|
+
const msg = JSON.parse(body);
|
|
169157
|
+
if (msg.id !== undefined && this.pendingRequests.has(msg.id)) {
|
|
169158
|
+
const pending = this.pendingRequests.get(msg.id);
|
|
169159
|
+
clearTimeout(pending.timeout);
|
|
169160
|
+
this.pendingRequests.delete(msg.id);
|
|
169161
|
+
if (msg.error) {
|
|
169162
|
+
pending.reject(new Error(msg.error.message || "LSP error"));
|
|
169163
|
+
} else {
|
|
169164
|
+
pending.resolve(msg.result);
|
|
169165
|
+
}
|
|
169166
|
+
} else if (msg.method === "textDocument/publishDiagnostics") {
|
|
169167
|
+
this.handlePublishDiagnostics(msg.params);
|
|
169168
|
+
}
|
|
169169
|
+
} catch {}
|
|
169170
|
+
}
|
|
169171
|
+
}
|
|
169172
|
+
handlePublishDiagnostics(params) {
|
|
169173
|
+
if (!params || !params.uri || !Array.isArray(params.diagnostics))
|
|
169174
|
+
return;
|
|
169175
|
+
const uri = params.uri;
|
|
169176
|
+
const filePath = fileURLToPath(uri);
|
|
169177
|
+
const items = params.diagnostics.map((d) => {
|
|
169178
|
+
const sevNum = d.severity ?? 1;
|
|
169179
|
+
const severity = sevNum === 1 ? "error" : sevNum === 2 ? "warning" : "info";
|
|
169180
|
+
return {
|
|
169181
|
+
filePath,
|
|
169182
|
+
line: (d.range?.start?.line ?? 0) + 1,
|
|
169183
|
+
column: (d.range?.start?.character ?? 0) + 1,
|
|
169184
|
+
message: d.message || "",
|
|
169185
|
+
severity,
|
|
169186
|
+
source: d.source || "typescript"
|
|
169187
|
+
};
|
|
169188
|
+
});
|
|
169189
|
+
this.diagnosticsByUri.set(uri, items);
|
|
169190
|
+
}
|
|
169191
|
+
sendRequest(method, params) {
|
|
169192
|
+
if (!this.child || !this.child.stdin || this.isShutdown) {
|
|
169193
|
+
return Promise.reject(new Error("LSP client is not running"));
|
|
169194
|
+
}
|
|
169195
|
+
const id = this.nextId++;
|
|
169196
|
+
return new Promise((resolve, reject) => {
|
|
169197
|
+
const timeout = setTimeout(() => {
|
|
169198
|
+
this.pendingRequests.delete(id);
|
|
169199
|
+
reject(new Error(`LSP request "${method}" timed out after ${this.requestTimeoutMs}ms`));
|
|
169200
|
+
}, this.requestTimeoutMs);
|
|
169201
|
+
this.pendingRequests.set(id, { resolve, reject, timeout });
|
|
169202
|
+
const payload = JSON.stringify({ jsonrpc: "2.0", id, method, params });
|
|
169203
|
+
const header = `Content-Length: ${Buffer.byteLength(payload, "utf8")}\r
|
|
169204
|
+
\r
|
|
169205
|
+
`;
|
|
169206
|
+
this.child?.stdin?.write(header + payload);
|
|
169207
|
+
});
|
|
169208
|
+
}
|
|
169209
|
+
sendNotification(method, params) {
|
|
169210
|
+
if (!this.child || !this.child.stdin || this.isShutdown)
|
|
169211
|
+
return;
|
|
169212
|
+
const payload = JSON.stringify({ jsonrpc: "2.0", method, params });
|
|
169213
|
+
const header = `Content-Length: ${Buffer.byteLength(payload, "utf8")}\r
|
|
169214
|
+
\r
|
|
169215
|
+
`;
|
|
169216
|
+
this.child.stdin.write(header + payload);
|
|
169217
|
+
}
|
|
169218
|
+
async openDocument(filePath, content) {
|
|
169219
|
+
const absPath = path25.isAbsolute(filePath) ? filePath : path25.resolve(this.workspaceRoot, filePath);
|
|
169220
|
+
const uri = pathToFileURL(absPath).toString();
|
|
169221
|
+
if (this.openedDocuments.has(uri)) {
|
|
169222
|
+
return uri;
|
|
169223
|
+
}
|
|
169224
|
+
let fileContent = content;
|
|
169225
|
+
if (fileContent === undefined) {
|
|
169226
|
+
try {
|
|
169227
|
+
fileContent = fs24.readFileSync(absPath, "utf8");
|
|
169228
|
+
} catch {
|
|
169229
|
+
fileContent = "";
|
|
169230
|
+
}
|
|
169231
|
+
}
|
|
169232
|
+
this.sendNotification("textDocument/didOpen", {
|
|
169233
|
+
textDocument: {
|
|
169234
|
+
uri,
|
|
169235
|
+
languageId: "typescript",
|
|
169236
|
+
version: 1,
|
|
169237
|
+
text: fileContent
|
|
169238
|
+
}
|
|
169239
|
+
});
|
|
169240
|
+
this.openedDocuments.add(uri);
|
|
169241
|
+
return uri;
|
|
169242
|
+
}
|
|
169243
|
+
async getDefinition(filePath, line, column) {
|
|
169244
|
+
const queryRawDefinition = async (targetFile, targetLine, targetCol) => {
|
|
169245
|
+
await this.start();
|
|
169246
|
+
const uri = await this.openDocument(targetFile);
|
|
169247
|
+
const raw = await this.sendRequest("textDocument/definition", {
|
|
169248
|
+
textDocument: { uri },
|
|
169249
|
+
position: {
|
|
169250
|
+
line: Math.max(0, targetLine - 1),
|
|
169251
|
+
character: Math.max(0, targetCol - 1)
|
|
169252
|
+
}
|
|
169253
|
+
});
|
|
169254
|
+
if (!raw)
|
|
169255
|
+
return [];
|
|
169256
|
+
const array = Array.isArray(raw) ? raw : [raw];
|
|
169257
|
+
const locations = [];
|
|
169258
|
+
for (const loc of array) {
|
|
169259
|
+
const targetUri = loc.targetUri || loc.uri;
|
|
169260
|
+
if (!targetUri)
|
|
169261
|
+
continue;
|
|
169262
|
+
const targetRange = loc.targetSelectionRange || loc.targetRange || loc.range;
|
|
169263
|
+
const targetFilePath = fileURLToPath(targetUri);
|
|
169264
|
+
locations.push({
|
|
169265
|
+
filePath: targetFilePath,
|
|
169266
|
+
line: (targetRange?.start?.line ?? 0) + 1,
|
|
169267
|
+
column: (targetRange?.start?.character ?? 0) + 1
|
|
169268
|
+
});
|
|
169269
|
+
}
|
|
169270
|
+
return locations;
|
|
169271
|
+
};
|
|
169272
|
+
const initial = await queryRawDefinition(filePath, line, column);
|
|
169273
|
+
const resolved = [];
|
|
169274
|
+
for (const loc of initial) {
|
|
169275
|
+
try {
|
|
169276
|
+
const content = fs24.readFileSync(loc.filePath, "utf8");
|
|
169277
|
+
const lines = content.split(`
|
|
169278
|
+
`);
|
|
169279
|
+
const lineContent = lines[loc.line - 1] || "";
|
|
169280
|
+
if (/^\s*import\b/.test(lineContent)) {
|
|
169281
|
+
const secondHop = await queryRawDefinition(loc.filePath, loc.line, loc.column);
|
|
169282
|
+
if (secondHop.length > 0 && !(secondHop.length === 1 && secondHop[0].filePath === loc.filePath && secondHop[0].line === loc.line)) {
|
|
169283
|
+
resolved.push(...secondHop);
|
|
169284
|
+
continue;
|
|
169285
|
+
}
|
|
169286
|
+
}
|
|
169287
|
+
} catch {}
|
|
169288
|
+
resolved.push(loc);
|
|
169289
|
+
}
|
|
169290
|
+
return resolved;
|
|
169291
|
+
}
|
|
169292
|
+
async getReferences(filePath, line, column) {
|
|
169293
|
+
await this.start();
|
|
169294
|
+
const uri = await this.openDocument(filePath);
|
|
169295
|
+
const raw = await this.sendRequest("textDocument/references", {
|
|
169296
|
+
textDocument: { uri },
|
|
169297
|
+
position: {
|
|
169298
|
+
line: Math.max(0, line - 1),
|
|
169299
|
+
character: Math.max(0, column - 1)
|
|
169300
|
+
},
|
|
169301
|
+
context: { includeDeclaration: true }
|
|
169302
|
+
});
|
|
169303
|
+
if (!raw || !Array.isArray(raw))
|
|
169304
|
+
return [];
|
|
169305
|
+
const locations = [];
|
|
169306
|
+
for (const loc of raw) {
|
|
169307
|
+
if (!loc.uri)
|
|
169308
|
+
continue;
|
|
169309
|
+
const targetFilePath = fileURLToPath(loc.uri);
|
|
169310
|
+
locations.push({
|
|
169311
|
+
filePath: targetFilePath,
|
|
169312
|
+
line: (loc.range?.start?.line ?? 0) + 1,
|
|
169313
|
+
column: (loc.range?.start?.character ?? 0) + 1
|
|
169314
|
+
});
|
|
169315
|
+
}
|
|
169316
|
+
return locations;
|
|
169317
|
+
}
|
|
169318
|
+
async getOutline(filePath) {
|
|
169319
|
+
await this.start();
|
|
169320
|
+
const uri = await this.openDocument(filePath);
|
|
169321
|
+
const raw = await this.sendRequest("textDocument/documentSymbol", {
|
|
169322
|
+
textDocument: { uri }
|
|
169323
|
+
});
|
|
169324
|
+
if (!raw || !Array.isArray(raw))
|
|
169325
|
+
return [];
|
|
169326
|
+
const items = [];
|
|
169327
|
+
const extractSymbols = (symbols, containerName) => {
|
|
169328
|
+
for (const sym of symbols) {
|
|
169329
|
+
const kindStr = SYMBOL_KINDS[sym.kind] || "symbol";
|
|
169330
|
+
const range = sym.range || sym.location?.range;
|
|
169331
|
+
const line = (range?.start?.line ?? 0) + 1;
|
|
169332
|
+
const column = (range?.start?.character ?? 0) + 1;
|
|
169333
|
+
items.push({
|
|
169334
|
+
name: sym.name || "anonymous",
|
|
169335
|
+
kind: kindStr,
|
|
169336
|
+
line,
|
|
169337
|
+
column,
|
|
169338
|
+
containerName: sym.containerName || containerName
|
|
169339
|
+
});
|
|
169340
|
+
if (Array.isArray(sym.children) && sym.children.length > 0) {
|
|
169341
|
+
extractSymbols(sym.children, sym.name);
|
|
169342
|
+
}
|
|
169343
|
+
}
|
|
169344
|
+
};
|
|
169345
|
+
extractSymbols(raw);
|
|
169346
|
+
return items;
|
|
169347
|
+
}
|
|
169348
|
+
getDiagnostics(filePath) {
|
|
169349
|
+
if (filePath) {
|
|
169350
|
+
const absPath = path25.isAbsolute(filePath) ? filePath : path25.resolve(this.workspaceRoot, filePath);
|
|
169351
|
+
const uri = pathToFileURL(absPath).toString();
|
|
169352
|
+
return this.diagnosticsByUri.get(uri) || [];
|
|
169353
|
+
}
|
|
169354
|
+
const all = [];
|
|
169355
|
+
for (const items of this.diagnosticsByUri.values()) {
|
|
169356
|
+
all.push(...items);
|
|
169357
|
+
}
|
|
169358
|
+
return all;
|
|
169359
|
+
}
|
|
169360
|
+
async shutdown() {
|
|
169361
|
+
if (this.isShutdown)
|
|
169362
|
+
return;
|
|
169363
|
+
this.isShutdown = true;
|
|
169364
|
+
if (this.child) {
|
|
169365
|
+
try {
|
|
169366
|
+
await Promise.race([
|
|
169367
|
+
this.sendRequest("shutdown", {}),
|
|
169368
|
+
new Promise((r) => setTimeout(r, 500))
|
|
169369
|
+
]);
|
|
169370
|
+
this.sendNotification("exit", {});
|
|
169371
|
+
} catch {}
|
|
169372
|
+
try {
|
|
169373
|
+
this.child.kill("SIGTERM");
|
|
169374
|
+
} catch {}
|
|
169375
|
+
this.child = null;
|
|
169376
|
+
}
|
|
169377
|
+
this.rejectAllPending(new Error("LSP client shutdown"));
|
|
169378
|
+
}
|
|
169379
|
+
rejectAllPending(err) {
|
|
169380
|
+
for (const [id, pending] of this.pendingRequests.entries()) {
|
|
169381
|
+
clearTimeout(pending.timeout);
|
|
169382
|
+
pending.reject(err);
|
|
169383
|
+
this.pendingRequests.delete(id);
|
|
169384
|
+
}
|
|
169385
|
+
}
|
|
169386
|
+
}
|
|
169387
|
+
var SYMBOL_KINDS;
|
|
169388
|
+
var init_lsp_client = __esm(() => {
|
|
169389
|
+
SYMBOL_KINDS = {
|
|
169390
|
+
1: "file",
|
|
169391
|
+
2: "module",
|
|
169392
|
+
3: "namespace",
|
|
169393
|
+
4: "package",
|
|
169394
|
+
5: "class",
|
|
169395
|
+
6: "method",
|
|
169396
|
+
7: "property",
|
|
169397
|
+
8: "field",
|
|
169398
|
+
9: "constructor",
|
|
169399
|
+
10: "enum",
|
|
169400
|
+
11: "interface",
|
|
169401
|
+
12: "function",
|
|
169402
|
+
13: "variable",
|
|
169403
|
+
14: "constant",
|
|
169404
|
+
15: "string",
|
|
169405
|
+
16: "number",
|
|
169406
|
+
17: "boolean",
|
|
169407
|
+
18: "array",
|
|
169408
|
+
19: "object",
|
|
169409
|
+
20: "key",
|
|
169410
|
+
21: "null",
|
|
169411
|
+
22: "enumMember",
|
|
169412
|
+
23: "struct",
|
|
169413
|
+
24: "event",
|
|
169414
|
+
25: "operator",
|
|
169415
|
+
26: "typeParameter"
|
|
169416
|
+
};
|
|
169417
|
+
});
|
|
169418
|
+
|
|
168290
169419
|
// ../../packages/agent/src/index.ts
|
|
168291
169420
|
var exports_src3 = {};
|
|
168292
169421
|
__export(exports_src3, {
|
|
168293
169422
|
AgentHarness: () => AgentHarness,
|
|
169423
|
+
LspClient: () => LspClient,
|
|
168294
169424
|
runAgentLoop: () => runAgentLoop
|
|
168295
169425
|
});
|
|
168296
169426
|
var init_src5 = __esm(() => {
|
|
@@ -168303,6 +169433,7 @@ var init_src5 = __esm(() => {
|
|
|
168303
169433
|
init_telemetry();
|
|
168304
169434
|
init_skill_subagent();
|
|
168305
169435
|
init_run_skill_tool();
|
|
169436
|
+
init_lsp_client();
|
|
168306
169437
|
});
|
|
168307
169438
|
|
|
168308
169439
|
// src/headless-runner.ts
|
|
@@ -168580,8 +169711,8 @@ var exports_file_session_repository = {};
|
|
|
168580
169711
|
__export(exports_file_session_repository, {
|
|
168581
169712
|
FileSessionRepository: () => FileSessionRepository
|
|
168582
169713
|
});
|
|
168583
|
-
import
|
|
168584
|
-
import
|
|
169714
|
+
import fs25 from "node:fs/promises";
|
|
169715
|
+
import path26 from "node:path";
|
|
168585
169716
|
|
|
168586
169717
|
class FileSessionRepository {
|
|
168587
169718
|
sessionDir;
|
|
@@ -168591,22 +169722,22 @@ class FileSessionRepository {
|
|
|
168591
169722
|
if (sessionDir) {
|
|
168592
169723
|
this.sessionDir = sessionDir;
|
|
168593
169724
|
} else {
|
|
168594
|
-
this.sessionDir =
|
|
168595
|
-
const legacyDir =
|
|
169725
|
+
this.sessionDir = path26.join(getConfigDir(), "sessions");
|
|
169726
|
+
const legacyDir = path26.join(getLegacyConfigDir(), "sessions");
|
|
168596
169727
|
if (legacyDir !== this.sessionDir) {
|
|
168597
169728
|
this.legacySessionDir = legacyDir;
|
|
168598
169729
|
}
|
|
168599
169730
|
}
|
|
168600
169731
|
}
|
|
168601
169732
|
async saveContext(sessionId, messages) {
|
|
168602
|
-
await
|
|
168603
|
-
const historyPath =
|
|
169733
|
+
await fs25.mkdir(this.sessionDir, { recursive: true });
|
|
169734
|
+
const historyPath = path26.join(this.sessionDir, `${sessionId}.jsonl`);
|
|
168604
169735
|
let existing = this.sessionCache[sessionId];
|
|
168605
169736
|
if (!existing) {
|
|
168606
169737
|
existing = {};
|
|
168607
169738
|
this.sessionCache[sessionId] = existing;
|
|
168608
169739
|
try {
|
|
168609
|
-
const data = await
|
|
169740
|
+
const data = await fs25.readFile(historyPath, "utf-8");
|
|
168610
169741
|
const lines = data.split(`
|
|
168611
169742
|
`).filter((l) => l.trim().length > 0);
|
|
168612
169743
|
for (const l of lines) {
|
|
@@ -168630,19 +169761,19 @@ class FileSessionRepository {
|
|
|
168630
169761
|
}
|
|
168631
169762
|
}
|
|
168632
169763
|
if (appendContent) {
|
|
168633
|
-
await
|
|
169764
|
+
await fs25.appendFile(historyPath, appendContent, "utf-8");
|
|
168634
169765
|
}
|
|
168635
169766
|
}
|
|
168636
169767
|
async loadContext(sessionId) {
|
|
168637
|
-
let historyPath =
|
|
169768
|
+
let historyPath = path26.join(this.sessionDir, `${sessionId}.jsonl`);
|
|
168638
169769
|
try {
|
|
168639
169770
|
let data;
|
|
168640
169771
|
try {
|
|
168641
|
-
data = await
|
|
169772
|
+
data = await fs25.readFile(historyPath, "utf-8");
|
|
168642
169773
|
} catch (err) {
|
|
168643
169774
|
if (this.legacySessionDir) {
|
|
168644
|
-
const legacyPath =
|
|
168645
|
-
data = await
|
|
169775
|
+
const legacyPath = path26.join(this.legacySessionDir, `${sessionId}.jsonl`);
|
|
169776
|
+
data = await fs25.readFile(legacyPath, "utf-8");
|
|
168646
169777
|
historyPath = legacyPath;
|
|
168647
169778
|
} else {
|
|
168648
169779
|
throw err;
|
|
@@ -168683,7 +169814,7 @@ class FileSessionRepository {
|
|
|
168683
169814
|
if (msgs.length < lines.length) {
|
|
168684
169815
|
const compacted = msgs.map((m) => JSON.stringify(m)).join(`
|
|
168685
169816
|
`);
|
|
168686
|
-
await
|
|
169817
|
+
await fs25.writeFile(historyPath, compacted, "utf-8").catch(() => {});
|
|
168687
169818
|
}
|
|
168688
169819
|
const cacheObj = {};
|
|
168689
169820
|
for (const msg of msgs) {
|
|
@@ -168697,12 +169828,12 @@ class FileSessionRepository {
|
|
|
168697
169828
|
}
|
|
168698
169829
|
async listSessions() {
|
|
168699
169830
|
try {
|
|
168700
|
-
await
|
|
169831
|
+
await fs25.mkdir(this.sessionDir, { recursive: true });
|
|
168701
169832
|
const sessions = [];
|
|
168702
169833
|
const seenIds = new Set;
|
|
168703
169834
|
const processDirectory = async (dirPath) => {
|
|
168704
169835
|
try {
|
|
168705
|
-
const dirFiles = await
|
|
169836
|
+
const dirFiles = await fs25.readdir(dirPath);
|
|
168706
169837
|
for (const file of dirFiles) {
|
|
168707
169838
|
if (!file.endsWith(".jsonl"))
|
|
168708
169839
|
continue;
|
|
@@ -168710,10 +169841,10 @@ class FileSessionRepository {
|
|
|
168710
169841
|
if (seenIds.has(id))
|
|
168711
169842
|
continue;
|
|
168712
169843
|
seenIds.add(id);
|
|
168713
|
-
const filePath =
|
|
169844
|
+
const filePath = path26.join(dirPath, file);
|
|
168714
169845
|
try {
|
|
168715
|
-
const stat = await
|
|
168716
|
-
const data = await
|
|
169846
|
+
const stat = await fs25.stat(filePath);
|
|
169847
|
+
const data = await fs25.readFile(filePath, "utf-8");
|
|
168717
169848
|
const lines = data.split(`
|
|
168718
169849
|
`).filter((l) => l.trim().length > 0);
|
|
168719
169850
|
let preview = "";
|
|
@@ -168747,20 +169878,20 @@ class FileSessionRepository {
|
|
|
168747
169878
|
}
|
|
168748
169879
|
}
|
|
168749
169880
|
async deleteSession(sessionId) {
|
|
168750
|
-
const historyPath =
|
|
169881
|
+
const historyPath = path26.join(this.sessionDir, `${sessionId}.jsonl`);
|
|
168751
169882
|
try {
|
|
168752
|
-
await
|
|
169883
|
+
await fs25.unlink(historyPath);
|
|
168753
169884
|
} catch (e) {}
|
|
168754
169885
|
if (this.legacySessionDir) {
|
|
168755
169886
|
try {
|
|
168756
|
-
await
|
|
169887
|
+
await fs25.unlink(path26.join(this.legacySessionDir, `${sessionId}.jsonl`));
|
|
168757
169888
|
} catch {}
|
|
168758
169889
|
}
|
|
168759
169890
|
}
|
|
168760
169891
|
async renameSession(oldSessionId, newSessionId) {
|
|
168761
|
-
const oldPath =
|
|
168762
|
-
const newPath =
|
|
168763
|
-
await
|
|
169892
|
+
const oldPath = path26.join(this.sessionDir, `${oldSessionId}.jsonl`);
|
|
169893
|
+
const newPath = path26.join(this.sessionDir, `${newSessionId}.jsonl`);
|
|
169894
|
+
await fs25.rename(oldPath, newPath);
|
|
168764
169895
|
}
|
|
168765
169896
|
}
|
|
168766
169897
|
var init_file_session_repository = __esm(() => {
|
|
@@ -174394,21 +175525,53 @@ __export(exports_local_operations, {
|
|
|
174394
175525
|
localOperations: () => localOperations,
|
|
174395
175526
|
setActiveScopeDir: () => setActiveScopeDir
|
|
174396
175527
|
});
|
|
174397
|
-
import { exec as exec4, spawn as
|
|
174398
|
-
import
|
|
174399
|
-
import
|
|
175528
|
+
import { exec as exec4, spawn as spawn4 } from "node:child_process";
|
|
175529
|
+
import nodeFs from "node:fs";
|
|
175530
|
+
import fs26 from "node:fs/promises";
|
|
175531
|
+
import path27 from "node:path";
|
|
174400
175532
|
import { promisify as promisify4 } from "node:util";
|
|
174401
175533
|
function setActiveScopeDir(dir) {
|
|
174402
175534
|
activeScopeDir = dir;
|
|
174403
175535
|
}
|
|
174404
175536
|
function getScopedCwd() {
|
|
174405
175537
|
if (activeScopeDir) {
|
|
174406
|
-
return
|
|
175538
|
+
return path27.resolve(process.cwd(), activeScopeDir);
|
|
174407
175539
|
}
|
|
174408
175540
|
return process.cwd();
|
|
174409
175541
|
}
|
|
174410
|
-
|
|
175542
|
+
function isTypeScriptProject(workspaceDir) {
|
|
175543
|
+
return nodeFs.existsSync(path27.join(workspaceDir, "tsconfig.json")) || nodeFs.existsSync(path27.join(workspaceDir, "package.json"));
|
|
175544
|
+
}
|
|
175545
|
+
async function getOrLaunchLspClient(customWorkspaceDir) {
|
|
175546
|
+
const workspaceDir = customWorkspaceDir || getScopedCwd();
|
|
175547
|
+
if (activeLspClient && activeLspWorkspace === workspaceDir) {
|
|
175548
|
+
return activeLspClient;
|
|
175549
|
+
}
|
|
175550
|
+
if (!isTypeScriptProject(workspaceDir)) {
|
|
175551
|
+
return null;
|
|
175552
|
+
}
|
|
175553
|
+
if (activeLspClient) {
|
|
175554
|
+
try {
|
|
175555
|
+
await activeLspClient.shutdown();
|
|
175556
|
+
} catch {}
|
|
175557
|
+
activeLspClient = null;
|
|
175558
|
+
activeLspWorkspace = null;
|
|
175559
|
+
}
|
|
175560
|
+
const client = new LspClient({ workspaceRoot: workspaceDir });
|
|
175561
|
+
activeLspClient = client;
|
|
175562
|
+
activeLspWorkspace = workspaceDir;
|
|
175563
|
+
try {
|
|
175564
|
+
await client.start();
|
|
175565
|
+
} catch {
|
|
175566
|
+
activeLspClient = null;
|
|
175567
|
+
activeLspWorkspace = null;
|
|
175568
|
+
return null;
|
|
175569
|
+
}
|
|
175570
|
+
return activeLspClient;
|
|
175571
|
+
}
|
|
175572
|
+
var import_fast_glob, execAsync2, localBashOps, activeScopeDir, SERVER_READY_REGEX, DEFAULT_BG_TIMEOUT_MS = 20000, DEFAULT_SERVER_READY_DELAY_MS = 2500, localOperations, activeLspClient = null, activeLspWorkspace = null;
|
|
174411
175573
|
var init_local_operations = __esm(() => {
|
|
175574
|
+
init_src5();
|
|
174412
175575
|
init_src();
|
|
174413
175576
|
init_src4();
|
|
174414
175577
|
init_task_manager();
|
|
@@ -174424,7 +175587,7 @@ var init_local_operations = __esm(() => {
|
|
|
174424
175587
|
const fallbackTimeoutMs = actualOptions.waitMsBeforeAsync ?? DEFAULT_BG_TIMEOUT_MS;
|
|
174425
175588
|
const serverDelayMs = actualOptions.serverReadyDelayMs ?? DEFAULT_SERVER_READY_DELAY_MS;
|
|
174426
175589
|
return new Promise((resolve, reject) => {
|
|
174427
|
-
const child =
|
|
175590
|
+
const child = spawn4(command, {
|
|
174428
175591
|
cwd: targetCwd,
|
|
174429
175592
|
detached: process.platform !== "win32",
|
|
174430
175593
|
env: actualOptions.env ?? process.env,
|
|
@@ -174554,19 +175717,19 @@ Failed to start process: ${err?.message || err}
|
|
|
174554
175717
|
fs: {
|
|
174555
175718
|
readFile: async (filepath) => {
|
|
174556
175719
|
const root = getScopedCwd();
|
|
174557
|
-
const absolutePath =
|
|
174558
|
-
return
|
|
175720
|
+
const absolutePath = path27.isAbsolute(filepath) ? filepath : path27.resolve(root, filepath);
|
|
175721
|
+
return fs26.readFile(absolutePath, "utf8");
|
|
174559
175722
|
},
|
|
174560
175723
|
writeFile: async (filepath, content) => {
|
|
174561
175724
|
const root = getScopedCwd();
|
|
174562
|
-
const absolutePath =
|
|
174563
|
-
await
|
|
174564
|
-
await
|
|
175725
|
+
const absolutePath = path27.isAbsolute(filepath) ? filepath : path27.resolve(root, filepath);
|
|
175726
|
+
await fs26.mkdir(path27.dirname(absolutePath), { recursive: true });
|
|
175727
|
+
await fs26.writeFile(absolutePath, content, "utf8");
|
|
174565
175728
|
},
|
|
174566
175729
|
readdir: async (dirPath) => {
|
|
174567
175730
|
const root = getScopedCwd();
|
|
174568
|
-
const absolutePath =
|
|
174569
|
-
const entries = await
|
|
175731
|
+
const absolutePath = path27.isAbsolute(dirPath) ? dirPath : path27.resolve(root, dirPath);
|
|
175732
|
+
const entries = await fs26.readdir(absolutePath, { withFileTypes: true });
|
|
174570
175733
|
const ignores = getWorkspaceIgnores(root);
|
|
174571
175734
|
return entries.filter((entry) => !isPathIgnored(entry.name, ignores)).map((entry) => {
|
|
174572
175735
|
const type = entry.isDirectory() ? "DIR " : "FILE";
|
|
@@ -174575,14 +175738,14 @@ Failed to start process: ${err?.message || err}
|
|
|
174575
175738
|
},
|
|
174576
175739
|
mkdir: async (dirPath, options) => {
|
|
174577
175740
|
const root = getScopedCwd();
|
|
174578
|
-
const absolutePath =
|
|
174579
|
-
await
|
|
175741
|
+
const absolutePath = path27.isAbsolute(dirPath) ? dirPath : path27.resolve(root, dirPath);
|
|
175742
|
+
await fs26.mkdir(absolutePath, options);
|
|
174580
175743
|
},
|
|
174581
175744
|
exists: async (filepath) => {
|
|
174582
175745
|
const root = getScopedCwd();
|
|
174583
|
-
const absolutePath =
|
|
175746
|
+
const absolutePath = path27.isAbsolute(filepath) ? filepath : path27.resolve(root, filepath);
|
|
174584
175747
|
try {
|
|
174585
|
-
await
|
|
175748
|
+
await fs26.access(absolutePath);
|
|
174586
175749
|
return true;
|
|
174587
175750
|
} catch {
|
|
174588
175751
|
return false;
|
|
@@ -174592,7 +175755,7 @@ Failed to start process: ${err?.message || err}
|
|
|
174592
175755
|
search: {
|
|
174593
175756
|
find: async (dirPath, query) => {
|
|
174594
175757
|
const root = getScopedCwd();
|
|
174595
|
-
const targetDir =
|
|
175758
|
+
const targetDir = path27.isAbsolute(dirPath) ? dirPath : path27.resolve(root, dirPath);
|
|
174596
175759
|
const ignores = getWorkspaceIgnores(root);
|
|
174597
175760
|
const files = await import_fast_glob.default([query], {
|
|
174598
175761
|
cwd: targetDir,
|
|
@@ -174604,10 +175767,11 @@ Failed to start process: ${err?.message || err}
|
|
|
174604
175767
|
},
|
|
174605
175768
|
grep: async (dirPath, query) => {
|
|
174606
175769
|
const root = getScopedCwd();
|
|
174607
|
-
const targetDir =
|
|
175770
|
+
const targetDir = path27.isAbsolute(dirPath) ? dirPath : path27.resolve(root, dirPath);
|
|
174608
175771
|
const ignores = getWorkspaceIgnores(root);
|
|
174609
175772
|
try {
|
|
174610
|
-
const
|
|
175773
|
+
const escapedQuery = query.replace(/"/g, "\\\"");
|
|
175774
|
+
const cmd = `git grep -nI "${escapedQuery}" -- ${targetDir} || grep -rnI --exclude-dir=node_modules --exclude-dir=.git "${escapedQuery}" ${targetDir}`;
|
|
174611
175775
|
const { stdout } = await execAsync2(cmd);
|
|
174612
175776
|
if (!stdout)
|
|
174613
175777
|
return "";
|
|
@@ -174616,8 +175780,9 @@ Failed to start process: ${err?.message || err}
|
|
|
174616
175780
|
const filtered = lines.filter((line) => {
|
|
174617
175781
|
if (!line.trim())
|
|
174618
175782
|
return false;
|
|
174619
|
-
const
|
|
174620
|
-
|
|
175783
|
+
const rawPath = line.split(":")[0];
|
|
175784
|
+
const relPath = path27.isAbsolute(rawPath) ? path27.relative(root, rawPath) : rawPath;
|
|
175785
|
+
return !isPathIgnored(relPath, ignores);
|
|
174621
175786
|
});
|
|
174622
175787
|
return filtered.join(`
|
|
174623
175788
|
`);
|
|
@@ -174658,8 +175823,56 @@ Failed to start process: ${err?.message || err}
|
|
|
174658
175823
|
return { text: "", error: error.message };
|
|
174659
175824
|
}
|
|
174660
175825
|
}
|
|
175826
|
+
},
|
|
175827
|
+
diagnostics: {
|
|
175828
|
+
getDiagnostics: async (filePath) => {
|
|
175829
|
+
const client = await getOrLaunchLspClient();
|
|
175830
|
+
if (!client)
|
|
175831
|
+
return [];
|
|
175832
|
+
return client.getDiagnostics(filePath);
|
|
175833
|
+
}
|
|
175834
|
+
},
|
|
175835
|
+
lsp: {
|
|
175836
|
+
getDefinition: async (filePath, line, column) => {
|
|
175837
|
+
const client = await getOrLaunchLspClient();
|
|
175838
|
+
if (!client)
|
|
175839
|
+
return [];
|
|
175840
|
+
return client.getDefinition(filePath, line, column);
|
|
175841
|
+
},
|
|
175842
|
+
getReferences: async (filePath, line, column) => {
|
|
175843
|
+
const client = await getOrLaunchLspClient();
|
|
175844
|
+
if (!client)
|
|
175845
|
+
return [];
|
|
175846
|
+
return client.getReferences(filePath, line, column);
|
|
175847
|
+
},
|
|
175848
|
+
getOutline: async (filePath) => {
|
|
175849
|
+
const client = await getOrLaunchLspClient();
|
|
175850
|
+
if (!client)
|
|
175851
|
+
return [];
|
|
175852
|
+
return client.getOutline(filePath);
|
|
175853
|
+
},
|
|
175854
|
+
getDiagnostics: async (filePath) => {
|
|
175855
|
+
const client = await getOrLaunchLspClient();
|
|
175856
|
+
if (!client)
|
|
175857
|
+
return [];
|
|
175858
|
+
return client.getDiagnostics(filePath);
|
|
175859
|
+
},
|
|
175860
|
+
shutdown: async () => {
|
|
175861
|
+
if (activeLspClient) {
|
|
175862
|
+
await activeLspClient.shutdown();
|
|
175863
|
+
activeLspClient = null;
|
|
175864
|
+
activeLspWorkspace = null;
|
|
175865
|
+
}
|
|
175866
|
+
}
|
|
174661
175867
|
}
|
|
174662
175868
|
};
|
|
175869
|
+
process.on("exit", () => {
|
|
175870
|
+
if (activeLspClient) {
|
|
175871
|
+
try {
|
|
175872
|
+
activeLspClient.shutdown();
|
|
175873
|
+
} catch {}
|
|
175874
|
+
}
|
|
175875
|
+
});
|
|
174663
175876
|
});
|
|
174664
175877
|
|
|
174665
175878
|
// src/utils/provider-factory.ts
|
|
@@ -179011,7 +180224,7 @@ var init_wrap_ansi = __esm(() => {
|
|
|
179011
180224
|
// ../../node_modules/.bun/terminal-size@4.0.1/node_modules/terminal-size/index.js
|
|
179012
180225
|
import process3 from "node:process";
|
|
179013
180226
|
import { execFileSync } from "node:child_process";
|
|
179014
|
-
import
|
|
180227
|
+
import fs27 from "node:fs";
|
|
179015
180228
|
import tty from "node:tty";
|
|
179016
180229
|
function terminalSize() {
|
|
179017
180230
|
const { env, stdout, stderr } = process3;
|
|
@@ -179059,7 +180272,7 @@ var defaultColumns = 80, defaultRows = 24, exec6 = (command, arguments_, { shell
|
|
|
179059
180272
|
return true;
|
|
179060
180273
|
}
|
|
179061
180274
|
try {
|
|
179062
|
-
const statContents =
|
|
180275
|
+
const statContents = fs27.readFileSync("/proc/self/stat", "utf8");
|
|
179063
180276
|
const closingParenthesisIndex = statContents.lastIndexOf(") ");
|
|
179064
180277
|
if (closingParenthesisIndex === -1) {
|
|
179065
180278
|
return false;
|
|
@@ -179079,8 +180292,8 @@ var defaultColumns = 80, defaultRows = 24, exec6 = (command, arguments_, { shell
|
|
|
179079
180292
|
}
|
|
179080
180293
|
}, devTty = () => {
|
|
179081
180294
|
try {
|
|
179082
|
-
const flags = process3.platform === "darwin" ?
|
|
179083
|
-
const { columns, rows } = tty.WriteStream(
|
|
180295
|
+
const flags = process3.platform === "darwin" ? fs27.constants.O_EVTONLY | fs27.constants.O_NONBLOCK : fs27.constants.O_NONBLOCK;
|
|
180296
|
+
const { columns, rows } = tty.WriteStream(fs27.openSync("/dev/tty", flags));
|
|
179084
180297
|
return { columns, rows };
|
|
179085
180298
|
} catch {}
|
|
179086
180299
|
}, tput = () => {
|
|
@@ -211282,7 +212495,7 @@ var init_Text = __esm(() => {
|
|
|
211282
212495
|
});
|
|
211283
212496
|
|
|
211284
212497
|
// ../../node_modules/.bun/ink@7.1.0+90ffd46201e3176f/node_modules/ink/build/components/ErrorOverview.js
|
|
211285
|
-
import * as
|
|
212498
|
+
import * as fs28 from "node:fs";
|
|
211286
212499
|
import { cwd } from "node:process";
|
|
211287
212500
|
function ErrorOverview({ error }) {
|
|
211288
212501
|
const stack = error.stack ? error.stack.split(`
|
|
@@ -211292,8 +212505,8 @@ function ErrorOverview({ error }) {
|
|
|
211292
212505
|
let excerpt;
|
|
211293
212506
|
let lineWidth = 0;
|
|
211294
212507
|
const stackLineCounts = new Map;
|
|
211295
|
-
if (filePath && origin?.line &&
|
|
211296
|
-
const sourceCode =
|
|
212508
|
+
if (filePath && origin?.line && fs28.existsSync(filePath)) {
|
|
212509
|
+
const sourceCode = fs28.readFileSync(filePath, "utf8");
|
|
211297
212510
|
excerpt = dist_default4(sourceCode, origin.line);
|
|
211298
212511
|
if (excerpt) {
|
|
211299
212512
|
for (const { line } of excerpt) {
|
|
@@ -212724,7 +213937,7 @@ var init_render_to_string = __esm(async () => {
|
|
|
212724
213937
|
});
|
|
212725
213938
|
|
|
212726
213939
|
// ../../node_modules/.bun/ink@7.1.0+90ffd46201e3176f/node_modules/ink/build/components/Static.js
|
|
212727
|
-
function
|
|
213940
|
+
function Static15(props) {
|
|
212728
213941
|
const { items, children: render, style: customStyle } = props;
|
|
212729
213942
|
const [index, setIndex] = import_react17.useState(0);
|
|
212730
213943
|
const itemsToRender = import_react17.useMemo(() => {
|
|
@@ -213967,9 +215180,9 @@ var init_paste_manager = __esm(() => {
|
|
|
213967
215180
|
});
|
|
213968
215181
|
|
|
213969
215182
|
// ../../packages/tui/src/utils/prompt-history.ts
|
|
213970
|
-
import
|
|
215183
|
+
import fs29 from "node:fs";
|
|
213971
215184
|
import os15 from "node:os";
|
|
213972
|
-
import
|
|
215185
|
+
import path28 from "node:path";
|
|
213973
215186
|
|
|
213974
215187
|
class PromptHistory {
|
|
213975
215188
|
historyPath;
|
|
@@ -213981,16 +215194,16 @@ class PromptHistory {
|
|
|
213981
215194
|
this.historyPath = customPath;
|
|
213982
215195
|
} else {
|
|
213983
215196
|
const home = process.env.HOME || process.env.USERPROFILE || os15.homedir();
|
|
213984
|
-
const canonicalPath =
|
|
213985
|
-
const legacyPath =
|
|
213986
|
-
this.historyPath =
|
|
215197
|
+
const canonicalPath = path28.join(home, ".december", "history");
|
|
215198
|
+
const legacyPath = path28.join(home, ".config", "december", "history");
|
|
215199
|
+
this.historyPath = fs29.existsSync(canonicalPath) || !fs29.existsSync(legacyPath) ? canonicalPath : legacyPath;
|
|
213987
215200
|
}
|
|
213988
215201
|
this.load();
|
|
213989
215202
|
}
|
|
213990
215203
|
load() {
|
|
213991
215204
|
try {
|
|
213992
|
-
if (
|
|
213993
|
-
const raw =
|
|
215205
|
+
if (fs29.existsSync(this.historyPath)) {
|
|
215206
|
+
const raw = fs29.readFileSync(this.historyPath, "utf8");
|
|
213994
215207
|
this.entries = raw.split(/\r?\n/).map((l) => l.trim()).filter(Boolean);
|
|
213995
215208
|
}
|
|
213996
215209
|
} catch {
|
|
@@ -214006,11 +215219,11 @@ class PromptHistory {
|
|
|
214006
215219
|
this.cursor = this.entries.length;
|
|
214007
215220
|
this.currentDraft = "";
|
|
214008
215221
|
try {
|
|
214009
|
-
const dir =
|
|
214010
|
-
if (!
|
|
214011
|
-
|
|
215222
|
+
const dir = path28.dirname(this.historyPath);
|
|
215223
|
+
if (!fs29.existsSync(dir)) {
|
|
215224
|
+
fs29.mkdirSync(dir, { recursive: true });
|
|
214012
215225
|
}
|
|
214013
|
-
|
|
215226
|
+
fs29.appendFileSync(this.historyPath, trimmed + `
|
|
214014
215227
|
`, "utf8");
|
|
214015
215228
|
} catch {}
|
|
214016
215229
|
}
|
|
@@ -214074,16 +215287,16 @@ var init_clipboard = () => {};
|
|
|
214074
215287
|
|
|
214075
215288
|
// ../../packages/tui/src/utils/handoff.ts
|
|
214076
215289
|
import { exec as exec7 } from "node:child_process";
|
|
214077
|
-
import
|
|
214078
|
-
import
|
|
215290
|
+
import fs30 from "node:fs";
|
|
215291
|
+
import path29 from "node:path";
|
|
214079
215292
|
import { promisify as promisify5 } from "node:util";
|
|
214080
215293
|
function getHandoffExcludes(baseDir = process.cwd()) {
|
|
214081
215294
|
const excludes = [...MANDATORY_HANDOFF_EXCLUDES];
|
|
214082
215295
|
const readIgnoreFile = (fileName) => {
|
|
214083
|
-
const filePath =
|
|
215296
|
+
const filePath = path29.join(baseDir, fileName);
|
|
214084
215297
|
try {
|
|
214085
|
-
if (
|
|
214086
|
-
const lines =
|
|
215298
|
+
if (fs30.existsSync(filePath)) {
|
|
215299
|
+
const lines = fs30.readFileSync(filePath, "utf8").split(`
|
|
214087
215300
|
`);
|
|
214088
215301
|
for (const line of lines) {
|
|
214089
215302
|
const trimmed = line.trim();
|
|
@@ -214152,9 +215365,9 @@ var init_handoff = __esm(() => {
|
|
|
214152
215365
|
});
|
|
214153
215366
|
|
|
214154
215367
|
// ../../packages/tui/src/components/command-menu/commands.tsx
|
|
214155
|
-
import
|
|
215368
|
+
import fs31 from "node:fs";
|
|
214156
215369
|
import os17 from "node:os";
|
|
214157
|
-
import
|
|
215370
|
+
import path30 from "node:path";
|
|
214158
215371
|
var COMMANDS;
|
|
214159
215372
|
var init_commands2 = __esm(() => {
|
|
214160
215373
|
init_clipboard();
|
|
@@ -214258,13 +215471,13 @@ var init_commands2 = __esm(() => {
|
|
|
214258
215471
|
const archivePath = ".december-handoff.tar.gz";
|
|
214259
215472
|
try {
|
|
214260
215473
|
const home = process.env.HOME || process.env.USERPROFILE || os17.homedir();
|
|
214261
|
-
const canonicalConfigPath =
|
|
214262
|
-
const legacyConfigPath =
|
|
214263
|
-
const configPath =
|
|
215474
|
+
const canonicalConfigPath = path30.join(home, ".december", "config.json");
|
|
215475
|
+
const legacyConfigPath = path30.join(home, ".config", "december", "config.json");
|
|
215476
|
+
const configPath = fs31.existsSync(canonicalConfigPath) || !fs31.existsSync(legacyConfigPath) ? canonicalConfigPath : legacyConfigPath;
|
|
214264
215477
|
let config = {};
|
|
214265
215478
|
try {
|
|
214266
|
-
if (
|
|
214267
|
-
config = JSON.parse(
|
|
215479
|
+
if (fs31.existsSync(configPath)) {
|
|
215480
|
+
config = JSON.parse(fs31.readFileSync(configPath, "utf8"));
|
|
214268
215481
|
}
|
|
214269
215482
|
} catch {}
|
|
214270
215483
|
if (!config.decemberToken) {
|
|
@@ -214299,7 +215512,7 @@ var init_commands2 = __esm(() => {
|
|
|
214299
215512
|
headers: { Authorization: `Bearer ${config.decemberToken}` }
|
|
214300
215513
|
});
|
|
214301
215514
|
if (!urlRes.ok) {
|
|
214302
|
-
await
|
|
215515
|
+
await fs31.promises.unlink(archivePath).catch(() => {});
|
|
214303
215516
|
if (urlRes.status === 401) {
|
|
214304
215517
|
ctx.toast.show({
|
|
214305
215518
|
variant: "error",
|
|
@@ -214320,7 +215533,7 @@ var init_commands2 = __esm(() => {
|
|
|
214320
215533
|
const urlJson = await urlRes.json();
|
|
214321
215534
|
const { uploadUrl, objectKey } = urlJson.data || urlJson;
|
|
214322
215535
|
ctx.toast.show({ variant: "info", message: "Uploading to MinIO..." });
|
|
214323
|
-
const fileData = await
|
|
215536
|
+
const fileData = await fs31.promises.readFile(archivePath);
|
|
214324
215537
|
const uploadRes = await fetch(uploadUrl, {
|
|
214325
215538
|
method: "PUT",
|
|
214326
215539
|
body: fileData
|
|
@@ -214344,11 +215557,11 @@ var init_commands2 = __esm(() => {
|
|
|
214344
215557
|
const errJson = await sessionRes.json().catch(() => ({}));
|
|
214345
215558
|
throw new Error(errJson.message || await sessionRes.text());
|
|
214346
215559
|
}
|
|
214347
|
-
await
|
|
215560
|
+
await fs31.promises.unlink(archivePath).catch(() => {});
|
|
214348
215561
|
ctx.toast.show({ variant: "success", message: "Handoff complete! Exiting in 3s." });
|
|
214349
215562
|
setTimeout(() => ctx.exit(), 3000);
|
|
214350
215563
|
} catch (e) {
|
|
214351
|
-
await
|
|
215564
|
+
await fs31.promises.unlink(archivePath).catch(() => {});
|
|
214352
215565
|
ctx.toast.show({ variant: "error", message: `Handoff failed: ${e.message}` });
|
|
214353
215566
|
}
|
|
214354
215567
|
}
|
|
@@ -215746,6 +216959,8 @@ var init_input_bar = __esm(async () => {
|
|
|
215746
216959
|
showExitConfirm ? /* @__PURE__ */ jsx_runtime8.jsx(Box_default, {
|
|
215747
216960
|
width: "100%",
|
|
215748
216961
|
justifyContent: "space-between",
|
|
216962
|
+
height: 1,
|
|
216963
|
+
overflow: "hidden",
|
|
215749
216964
|
children: /* @__PURE__ */ jsx_runtime8.jsx(Box_default, {
|
|
215750
216965
|
gap: 2,
|
|
215751
216966
|
alignItems: "center",
|
|
@@ -215762,6 +216977,7 @@ var init_input_bar = __esm(async () => {
|
|
|
215762
216977
|
]
|
|
215763
216978
|
}) : /* @__PURE__ */ jsx_runtime8.jsx(Text3, {
|
|
215764
216979
|
color: THEME.colors.muted,
|
|
216980
|
+
wrap: "truncate",
|
|
215765
216981
|
children: "· Press Ctrl+C again to exit"
|
|
215766
216982
|
})
|
|
215767
216983
|
})
|
|
@@ -215769,6 +216985,8 @@ var init_input_bar = __esm(async () => {
|
|
|
215769
216985
|
}) : /* @__PURE__ */ jsx_runtime8.jsxs(Box_default, {
|
|
215770
216986
|
width: "100%",
|
|
215771
216987
|
justifyContent: "space-between",
|
|
216988
|
+
height: 1,
|
|
216989
|
+
overflow: "hidden",
|
|
215772
216990
|
children: [
|
|
215773
216991
|
/* @__PURE__ */ jsx_runtime8.jsx(Box_default, {
|
|
215774
216992
|
gap: 2,
|
|
@@ -215780,6 +216998,7 @@ var init_input_bar = __esm(async () => {
|
|
|
215780
216998
|
children: [
|
|
215781
216999
|
/* @__PURE__ */ jsx_runtime8.jsxs(Text3, {
|
|
215782
217000
|
color: THEME.colors.muted,
|
|
217001
|
+
wrap: "truncate",
|
|
215783
217002
|
children: [
|
|
215784
217003
|
activeModeTag ? /* @__PURE__ */ jsx_runtime8.jsxs(Text3, {
|
|
215785
217004
|
color: THEME.colors.brand,
|
|
@@ -215793,6 +217012,7 @@ var init_input_bar = __esm(async () => {
|
|
|
215793
217012
|
]
|
|
215794
217013
|
}),
|
|
215795
217014
|
totalTasksCount > 0 && /* @__PURE__ */ jsx_runtime8.jsxs(Text3, {
|
|
217015
|
+
wrap: "truncate",
|
|
215796
217016
|
color: runningTasksCount > 0 ? THEME.colors.warning : THEME.colors.muted,
|
|
215797
217017
|
children: [
|
|
215798
217018
|
"·",
|
|
@@ -215819,6 +217039,7 @@ var init_input_bar = __esm(async () => {
|
|
|
215819
217039
|
marginLeft: 2,
|
|
215820
217040
|
children: /* @__PURE__ */ jsx_runtime8.jsx(Text3, {
|
|
215821
217041
|
color: contextColor,
|
|
217042
|
+
wrap: "truncate",
|
|
215822
217043
|
children: contextLabel
|
|
215823
217044
|
})
|
|
215824
217045
|
})
|
|
@@ -215849,7 +217070,7 @@ var init_scroll_viewport = __esm(async () => {
|
|
|
215849
217070
|
}, ref) {
|
|
215850
217071
|
const viewportRef = import_react43.useRef(null);
|
|
215851
217072
|
const contentRef = import_react43.useRef(null);
|
|
215852
|
-
const defaultHeight = explicitHeight ?? (typeof process !== "undefined" && process.stdout?.rows ? Math.max(
|
|
217073
|
+
const defaultHeight = explicitHeight ?? (typeof process !== "undefined" && process.stdout?.rows ? Math.max(1, process.stdout.rows - 6) : 24);
|
|
215853
217074
|
const [viewportHeight, setViewportHeight] = import_react43.useState(defaultHeight);
|
|
215854
217075
|
const [contentHeight, setContentHeight] = import_react43.useState(0);
|
|
215855
217076
|
const [internalScrollTop, setInternalScrollTop] = import_react43.useState(0);
|
|
@@ -215923,6 +217144,8 @@ var init_scroll_viewport = __esm(async () => {
|
|
|
215923
217144
|
const newTop = Math.max(0, currentTop - delta);
|
|
215924
217145
|
setIsReadingMode(newTop < currentMax);
|
|
215925
217146
|
setInternalScrollTop(newTop);
|
|
217147
|
+
stateRef.current.isReadingMode = newTop < currentMax;
|
|
217148
|
+
stateRef.current.internalScrollTop = newTop;
|
|
215926
217149
|
notifyStateChange(newTop);
|
|
215927
217150
|
}, [notifyStateChange]);
|
|
215928
217151
|
const handleScrollDown = import_react43.useCallback((delta) => {
|
|
@@ -215932,9 +217155,12 @@ var init_scroll_viewport = __esm(async () => {
|
|
|
215932
217155
|
if (newTop >= currentMax) {
|
|
215933
217156
|
setIsReadingMode(false);
|
|
215934
217157
|
setInternalScrollTop(currentMax);
|
|
217158
|
+
stateRef.current.isReadingMode = false;
|
|
217159
|
+
stateRef.current.internalScrollTop = currentMax;
|
|
215935
217160
|
notifyStateChange(currentMax);
|
|
215936
217161
|
} else {
|
|
215937
217162
|
setInternalScrollTop(newTop);
|
|
217163
|
+
stateRef.current.internalScrollTop = newTop;
|
|
215938
217164
|
notifyStateChange(newTop);
|
|
215939
217165
|
}
|
|
215940
217166
|
}, [notifyStateChange]);
|
|
@@ -215942,12 +217168,16 @@ var init_scroll_viewport = __esm(async () => {
|
|
|
215942
217168
|
const currentMax = stateRef.current.maxScrollTop;
|
|
215943
217169
|
setIsReadingMode(currentMax > 0);
|
|
215944
217170
|
setInternalScrollTop(0);
|
|
217171
|
+
stateRef.current.isReadingMode = currentMax > 0;
|
|
217172
|
+
stateRef.current.internalScrollTop = 0;
|
|
215945
217173
|
notifyStateChange(0);
|
|
215946
217174
|
}, [notifyStateChange]);
|
|
215947
217175
|
const handleScrollToBottom = import_react43.useCallback(() => {
|
|
215948
217176
|
const currentMax = stateRef.current.maxScrollTop;
|
|
215949
217177
|
setIsReadingMode(false);
|
|
215950
217178
|
setInternalScrollTop(currentMax);
|
|
217179
|
+
stateRef.current.isReadingMode = false;
|
|
217180
|
+
stateRef.current.internalScrollTop = currentMax;
|
|
215951
217181
|
notifyStateChange(currentMax);
|
|
215952
217182
|
}, [notifyStateChange]);
|
|
215953
217183
|
import_react43.default.useImperativeHandle(ref, () => ({
|
|
@@ -216002,6 +217232,7 @@ var init_scroll_viewport = __esm(async () => {
|
|
|
216002
217232
|
height: explicitHeight,
|
|
216003
217233
|
flexGrow: 1,
|
|
216004
217234
|
flexShrink: 1,
|
|
217235
|
+
minHeight: 0,
|
|
216005
217236
|
overflowY: "hidden",
|
|
216006
217237
|
flexDirection: "column",
|
|
216007
217238
|
width: "100%",
|
|
@@ -216023,7 +217254,7 @@ var init_scroll_viewport = __esm(async () => {
|
|
|
216023
217254
|
});
|
|
216024
217255
|
|
|
216025
217256
|
// ../../packages/tui/src/utils/terminal-link.ts
|
|
216026
|
-
import
|
|
217257
|
+
import path31 from "node:path";
|
|
216027
217258
|
function terminalLink(text, uri) {
|
|
216028
217259
|
if (!uri)
|
|
216029
217260
|
return text;
|
|
@@ -216032,7 +217263,7 @@ function terminalLink(text, uri) {
|
|
|
216032
217263
|
function fileLink(displayPath, targetPath, line, col) {
|
|
216033
217264
|
if (!targetPath)
|
|
216034
217265
|
return displayPath;
|
|
216035
|
-
const absPath =
|
|
217266
|
+
const absPath = path31.isAbsolute(targetPath) ? targetPath : path31.resolve(process.cwd(), targetPath);
|
|
216036
217267
|
const lineFragment = line ? `#L${line}${col ? `:${col}` : ""}` : "";
|
|
216037
217268
|
const uri = `file://${absPath}${lineFragment}`;
|
|
216038
217269
|
return terminalLink(displayPath, uri);
|
|
@@ -216041,9 +217272,9 @@ function toRelativePath(filePath, cwd = process.cwd()) {
|
|
|
216041
217272
|
if (!filePath)
|
|
216042
217273
|
return "";
|
|
216043
217274
|
const trimmed = filePath.trim();
|
|
216044
|
-
if (!
|
|
217275
|
+
if (!path31.isAbsolute(trimmed))
|
|
216045
217276
|
return trimmed;
|
|
216046
|
-
const rel =
|
|
217277
|
+
const rel = path31.relative(cwd, trimmed);
|
|
216047
217278
|
if (!rel || rel.startsWith("..")) {
|
|
216048
217279
|
return trimmed;
|
|
216049
217280
|
}
|
|
@@ -216097,7 +217328,10 @@ var import_react44, jsx_runtime10, DiffGutterView;
|
|
|
216097
217328
|
var init_diff_gutter = __esm(async () => {
|
|
216098
217329
|
init_theme();
|
|
216099
217330
|
init_terminal_link();
|
|
216100
|
-
await
|
|
217331
|
+
await __promiseAll([
|
|
217332
|
+
init_build2(),
|
|
217333
|
+
init_use_terminal_columns()
|
|
217334
|
+
]);
|
|
216101
217335
|
import_react44 = __toESM(require_react(), 1);
|
|
216102
217336
|
jsx_runtime10 = __toESM(require_jsx_runtime(), 1);
|
|
216103
217337
|
DiffGutterView = import_react44.default.memo(function DiffGutterView({
|
|
@@ -216116,8 +217350,12 @@ var init_diff_gutter = __esm(async () => {
|
|
|
216116
217350
|
const isTruncated = isExpanded && parsedLines.length > maxVisibleLines;
|
|
216117
217351
|
const maxLineNum = Math.max(...parsedLines.map((l) => Math.max(l.oldLineNumber || 0, l.newLineNumber || 0)), 1);
|
|
216118
217352
|
const gutterWidth = Math.max(2, String(maxLineNum).length);
|
|
216119
|
-
const
|
|
216120
|
-
const
|
|
217353
|
+
const columns = useTerminalColumns();
|
|
217354
|
+
const maxPathLen = Math.max(30, columns - 45);
|
|
217355
|
+
const cleanPath = filePath ? filePath.replace(/^\.\//, "") : "";
|
|
217356
|
+
const displayPath = cleanPath ? toRelativePath(cleanPath) : "";
|
|
217357
|
+
const truncatedDisplay = displayPath.length > maxPathLen ? displayPath.substring(0, maxPathLen - 3) + "..." : displayPath;
|
|
217358
|
+
const linkedPath = displayPath ? fileLink(truncatedDisplay, filePath || displayPath, startLine) : "";
|
|
216121
217359
|
return /* @__PURE__ */ jsx_runtime10.jsxs(Box_default, {
|
|
216122
217360
|
flexDirection: "column",
|
|
216123
217361
|
marginY: 0,
|
|
@@ -216127,14 +217365,18 @@ var init_diff_gutter = __esm(async () => {
|
|
|
216127
217365
|
gap: 1,
|
|
216128
217366
|
alignItems: "center",
|
|
216129
217367
|
children: [
|
|
216130
|
-
/* @__PURE__ */ jsx_runtime10.
|
|
216131
|
-
|
|
216132
|
-
|
|
216133
|
-
|
|
216134
|
-
|
|
216135
|
-
|
|
216136
|
-
|
|
216137
|
-
|
|
217368
|
+
/* @__PURE__ */ jsx_runtime10.jsxs(Text3, {
|
|
217369
|
+
children: [
|
|
217370
|
+
/* @__PURE__ */ jsx_runtime10.jsx(Text3, {
|
|
217371
|
+
color: THEME.colors.warning,
|
|
217372
|
+
children: `${THEME.glyphs.status} `
|
|
217373
|
+
}),
|
|
217374
|
+
/* @__PURE__ */ jsx_runtime10.jsx(Text3, {
|
|
217375
|
+
color: THEME.colors.warning,
|
|
217376
|
+
bold: true,
|
|
217377
|
+
children: actionLabel
|
|
217378
|
+
})
|
|
217379
|
+
]
|
|
216138
217380
|
}),
|
|
216139
217381
|
displayPath && /* @__PURE__ */ jsx_runtime10.jsx(Text3, {
|
|
216140
217382
|
color: THEME.colors.text,
|
|
@@ -216161,6 +217403,7 @@ var init_diff_gutter = __esm(async () => {
|
|
|
216161
217403
|
}),
|
|
216162
217404
|
/* @__PURE__ */ jsx_runtime10.jsxs(Text3, {
|
|
216163
217405
|
color: THEME.colors.muted,
|
|
217406
|
+
wrap: "truncate",
|
|
216164
217407
|
children: [
|
|
216165
217408
|
"(",
|
|
216166
217409
|
isExpanded ? "ctrl+o to collapse" : "ctrl+o to view",
|
|
@@ -261585,17 +262828,19 @@ function CollapsibleThought({
|
|
|
261585
262828
|
});
|
|
261586
262829
|
}
|
|
261587
262830
|
function StyledCommand({ command, truncate = true }) {
|
|
262831
|
+
const columns = useTerminalColumns();
|
|
262832
|
+
const maxArgLength = Math.max(40, columns - 38);
|
|
261588
262833
|
const match = command.match(/^([A-Za-z_]+)\(([\s\S]*)\)$/);
|
|
261589
262834
|
if (match) {
|
|
261590
262835
|
const args = (match[2] || "").replace(/\r?\n/g, " ");
|
|
261591
262836
|
const toolName = match[1];
|
|
261592
262837
|
let displayArgs = args;
|
|
261593
|
-
if (truncate && displayArgs.length > 80) {
|
|
261594
|
-
displayArgs = displayArgs.substring(0, 80) + "...";
|
|
261595
|
-
}
|
|
261596
262838
|
if ((toolName === "read_file" || toolName === "view_file" || toolName === "Read") && args && !args.includes(" ")) {
|
|
261597
|
-
const rel = toRelativePath(
|
|
261598
|
-
|
|
262839
|
+
const rel = toRelativePath(args);
|
|
262840
|
+
const truncatedRel = truncate && rel.length > maxArgLength ? rel.substring(0, maxArgLength - 3) + "..." : rel;
|
|
262841
|
+
displayArgs = fileLink(truncatedRel, args);
|
|
262842
|
+
} else if (truncate && displayArgs.length > maxArgLength) {
|
|
262843
|
+
displayArgs = displayArgs.substring(0, maxArgLength - 3) + "...";
|
|
261599
262844
|
}
|
|
261600
262845
|
const cmdColor = THEME.colors.warning;
|
|
261601
262846
|
return /* @__PURE__ */ jsx_runtime17.jsxs(Text3, {
|
|
@@ -261621,8 +262866,8 @@ function StyledCommand({ command, truncate = true }) {
|
|
|
261621
262866
|
});
|
|
261622
262867
|
}
|
|
261623
262868
|
let displayCmd = command.replace(/\r?\n/g, " ");
|
|
261624
|
-
if (truncate && displayCmd.length >
|
|
261625
|
-
displayCmd = displayCmd.substring(0,
|
|
262869
|
+
if (truncate && displayCmd.length > maxArgLength) {
|
|
262870
|
+
displayCmd = displayCmd.substring(0, maxArgLength - 3) + "...";
|
|
261626
262871
|
}
|
|
261627
262872
|
return /* @__PURE__ */ jsx_runtime17.jsx(Text3, {
|
|
261628
262873
|
color: THEME.colors.text,
|
|
@@ -261633,17 +262878,19 @@ function StyledRunningCommand({
|
|
|
261633
262878
|
command,
|
|
261634
262879
|
truncate = true
|
|
261635
262880
|
}) {
|
|
262881
|
+
const columns = useTerminalColumns();
|
|
262882
|
+
const maxArgLength = Math.max(40, columns - 38);
|
|
261636
262883
|
const match = command.match(/^([A-Za-z_]+)\(([\s\S]*)\)$/);
|
|
261637
262884
|
if (match) {
|
|
261638
262885
|
const args = (match[2] || "").replace(/\r?\n/g, " ");
|
|
261639
262886
|
const toolName = match[1];
|
|
261640
262887
|
let displayArgs = args;
|
|
261641
|
-
if (truncate && displayArgs.length > 80) {
|
|
261642
|
-
displayArgs = displayArgs.substring(0, 80) + "...";
|
|
261643
|
-
}
|
|
261644
262888
|
if ((toolName === "read_file" || toolName === "view_file" || toolName === "Read") && args && !args.includes(" ")) {
|
|
261645
|
-
const rel = toRelativePath(
|
|
261646
|
-
|
|
262889
|
+
const rel = toRelativePath(args);
|
|
262890
|
+
const truncatedRel = truncate && rel.length > maxArgLength ? rel.substring(0, maxArgLength - 3) + "..." : rel;
|
|
262891
|
+
displayArgs = fileLink(truncatedRel, args);
|
|
262892
|
+
} else if (truncate && displayArgs.length > maxArgLength) {
|
|
262893
|
+
displayArgs = displayArgs.substring(0, maxArgLength - 3) + "...";
|
|
261647
262894
|
}
|
|
261648
262895
|
const cmdColor = THEME.colors.warning;
|
|
261649
262896
|
return /* @__PURE__ */ jsx_runtime17.jsxs(Text3, {
|
|
@@ -261665,8 +262912,8 @@ function StyledRunningCommand({
|
|
|
261665
262912
|
});
|
|
261666
262913
|
}
|
|
261667
262914
|
let displayCmd = command.replace(/\r?\n/g, " ");
|
|
261668
|
-
if (truncate && displayCmd.length >
|
|
261669
|
-
displayCmd = displayCmd.substring(0,
|
|
262915
|
+
if (truncate && displayCmd.length > maxArgLength) {
|
|
262916
|
+
displayCmd = displayCmd.substring(0, maxArgLength - 3) + "...";
|
|
261670
262917
|
}
|
|
261671
262918
|
return /* @__PURE__ */ jsx_runtime17.jsx(Text3, {
|
|
261672
262919
|
color: THEME.colors.text,
|
|
@@ -261696,6 +262943,7 @@ function CollapsibleCommandOutput({
|
|
|
261696
262943
|
}),
|
|
261697
262944
|
lines.length > 0 && /* @__PURE__ */ jsx_runtime17.jsxs(Text3, {
|
|
261698
262945
|
color: THEME.colors.muted,
|
|
262946
|
+
wrap: "truncate",
|
|
261699
262947
|
children: [
|
|
261700
262948
|
"(",
|
|
261701
262949
|
isExpanded ? "ctrl+o to collapse" : "ctrl+o to expand",
|
|
@@ -261762,22 +263010,56 @@ function getReadBlockPath(block) {
|
|
|
261762
263010
|
const rel = toRelativePath(rawPath);
|
|
261763
263011
|
return { display: rel || rawPath, target: rawPath };
|
|
261764
263012
|
}
|
|
263013
|
+
function formatConsolidatedReadArgs(paths, maxArgLength) {
|
|
263014
|
+
const count = paths.length;
|
|
263015
|
+
if (count === 0)
|
|
263016
|
+
return "";
|
|
263017
|
+
if (count === 1) {
|
|
263018
|
+
const p0 = paths[0];
|
|
263019
|
+
const label = p0.display.length > maxArgLength ? p0.display.substring(0, Math.max(10, maxArgLength - 3)) + "..." : p0.display;
|
|
263020
|
+
return fileLink(label, p0.target);
|
|
263021
|
+
}
|
|
263022
|
+
if (count === 2) {
|
|
263023
|
+
const p0 = paths[0];
|
|
263024
|
+
const p1 = paths[1];
|
|
263025
|
+
if (p0.display.length + 2 + p1.display.length <= maxArgLength) {
|
|
263026
|
+
return `${fileLink(p0.display, p0.target)}, ${fileLink(p1.display, p1.target)}`;
|
|
263027
|
+
}
|
|
263028
|
+
const remainingForP1 = maxArgLength - (p0.display.length + 2);
|
|
263029
|
+
if (remainingForP1 >= 8) {
|
|
263030
|
+
const truncatedP1 = p1.display.substring(0, remainingForP1 - 3) + "...";
|
|
263031
|
+
return `${fileLink(p0.display, p0.target)}, ${fileLink(truncatedP1, p1.target)}`;
|
|
263032
|
+
}
|
|
263033
|
+
const truncatedP0 = p0.display.length > maxArgLength - 6 ? p0.display.substring(0, Math.max(10, maxArgLength - 9)) + "..." : p0.display;
|
|
263034
|
+
return `${fileLink(truncatedP0, p0.target)}, ...`;
|
|
263035
|
+
}
|
|
263036
|
+
const p0 = paths[0];
|
|
263037
|
+
const p1 = paths[1];
|
|
263038
|
+
const suffixTwo = `, +${count - 2} more`;
|
|
263039
|
+
if (p0.display.length + 2 + p1.display.length + suffixTwo.length <= maxArgLength) {
|
|
263040
|
+
return `${fileLink(p0.display, p0.target)}, ${fileLink(p1.display, p1.target)}${suffixTwo}`;
|
|
263041
|
+
}
|
|
263042
|
+
const remainingForP1 = maxArgLength - (p0.display.length + 2 + suffixTwo.length);
|
|
263043
|
+
if (remainingForP1 >= 8) {
|
|
263044
|
+
const truncatedP1 = p1.display.substring(0, remainingForP1 - 3) + "...";
|
|
263045
|
+
return `${fileLink(p0.display, p0.target)}, ${fileLink(truncatedP1, p1.target)}${suffixTwo}`;
|
|
263046
|
+
}
|
|
263047
|
+
const suffixOne = `, +${count - 1} more`;
|
|
263048
|
+
const remainingForP0 = maxArgLength - suffixOne.length;
|
|
263049
|
+
const label0 = p0.display.length > remainingForP0 ? p0.display.substring(0, Math.max(10, remainingForP0 - 3)) + "..." : p0.display;
|
|
263050
|
+
return `${fileLink(label0, p0.target)}${suffixOne}`;
|
|
263051
|
+
}
|
|
261765
263052
|
function ConsolidatedReadsView({
|
|
261766
263053
|
blocks,
|
|
261767
263054
|
forceExpanded,
|
|
261768
263055
|
isLastBlock
|
|
261769
263056
|
}) {
|
|
261770
263057
|
const isExpanded = forceExpanded ?? false;
|
|
263058
|
+
const columns = useTerminalColumns();
|
|
263059
|
+
const maxArgLength = Math.max(40, columns - 38);
|
|
261771
263060
|
const paths = blocks.map(getReadBlockPath);
|
|
261772
263061
|
const count = paths.length;
|
|
261773
|
-
|
|
261774
|
-
if (count === 2) {
|
|
261775
|
-
inlineArgs = `${fileLink(paths[0].display, paths[0].target)}, ${fileLink(paths[1].display, paths[1].target)}`;
|
|
261776
|
-
} else if (count > 2) {
|
|
261777
|
-
inlineArgs = `${fileLink(paths[0].display, paths[0].target)}, ${fileLink(paths[1].display, paths[1].target)}, +${count - 2} more`;
|
|
261778
|
-
} else if (count === 1) {
|
|
261779
|
-
inlineArgs = fileLink(paths[0].display, paths[0].target);
|
|
261780
|
-
}
|
|
263062
|
+
const inlineArgs = formatConsolidatedReadArgs(paths, maxArgLength);
|
|
261781
263063
|
const cmdColor = THEME.colors.warning;
|
|
261782
263064
|
const isRunning = blocks.some((b) => b.status === "running");
|
|
261783
263065
|
if (isRunning) {
|
|
@@ -261822,11 +263104,19 @@ function ConsolidatedReadsView({
|
|
|
261822
263104
|
alignItems: "center",
|
|
261823
263105
|
gap: 1,
|
|
261824
263106
|
children: [
|
|
261825
|
-
fileRunning ? /* @__PURE__ */ jsx_runtime17.jsx(Spinner2, {}) : /* @__PURE__ */ jsx_runtime17.
|
|
261826
|
-
|
|
261827
|
-
|
|
263107
|
+
fileRunning ? /* @__PURE__ */ jsx_runtime17.jsx(Spinner2, {}) : /* @__PURE__ */ jsx_runtime17.jsxs(Text3, {
|
|
263108
|
+
children: [
|
|
263109
|
+
/* @__PURE__ */ jsx_runtime17.jsx(Text3, {
|
|
263110
|
+
color: cmdColor,
|
|
263111
|
+
children: `${THEME.glyphs.status} `
|
|
263112
|
+
}),
|
|
263113
|
+
/* @__PURE__ */ jsx_runtime17.jsx(Text3, {
|
|
263114
|
+
color: THEME.colors.muted,
|
|
263115
|
+
children: fileLink(p.display, p.target)
|
|
263116
|
+
})
|
|
263117
|
+
]
|
|
261828
263118
|
}),
|
|
261829
|
-
/* @__PURE__ */ jsx_runtime17.jsx(Text3, {
|
|
263119
|
+
fileRunning && /* @__PURE__ */ jsx_runtime17.jsx(Text3, {
|
|
261830
263120
|
color: THEME.colors.muted,
|
|
261831
263121
|
children: fileLink(p.display, p.target)
|
|
261832
263122
|
})
|
|
@@ -261868,6 +263158,7 @@ function ConsolidatedReadsView({
|
|
|
261868
263158
|
}),
|
|
261869
263159
|
/* @__PURE__ */ jsx_runtime17.jsxs(Text3, {
|
|
261870
263160
|
color: THEME.colors.muted,
|
|
263161
|
+
wrap: "truncate",
|
|
261871
263162
|
children: [
|
|
261872
263163
|
"(",
|
|
261873
263164
|
isExpanded ? "ctrl+o to collapse" : "ctrl+o to expand",
|
|
@@ -261951,6 +263242,7 @@ var init_bot_message = __esm(async () => {
|
|
|
261951
263242
|
init_terminal_link();
|
|
261952
263243
|
await __promiseAll([
|
|
261953
263244
|
init_build2(),
|
|
263245
|
+
init_use_terminal_columns(),
|
|
261954
263246
|
init_diff_gutter(),
|
|
261955
263247
|
init_inline_tip(),
|
|
261956
263248
|
init_spinner(),
|
|
@@ -262300,14 +263592,18 @@ ${r}`;
|
|
|
262300
263592
|
gap: 1,
|
|
262301
263593
|
alignItems: "center",
|
|
262302
263594
|
children: [
|
|
262303
|
-
/* @__PURE__ */ jsx_runtime17.
|
|
262304
|
-
|
|
262305
|
-
|
|
262306
|
-
|
|
262307
|
-
|
|
262308
|
-
|
|
262309
|
-
|
|
262310
|
-
|
|
263595
|
+
/* @__PURE__ */ jsx_runtime17.jsxs(Text3, {
|
|
263596
|
+
children: [
|
|
263597
|
+
/* @__PURE__ */ jsx_runtime17.jsx(Text3, {
|
|
263598
|
+
color: THEME.colors.warning,
|
|
263599
|
+
children: `${THEME.glyphs.status} `
|
|
263600
|
+
}),
|
|
263601
|
+
/* @__PURE__ */ jsx_runtime17.jsx(Text3, {
|
|
263602
|
+
color: THEME.colors.warning,
|
|
263603
|
+
bold: true,
|
|
263604
|
+
children: actionLabel
|
|
263605
|
+
})
|
|
263606
|
+
]
|
|
262311
263607
|
}),
|
|
262312
263608
|
/* @__PURE__ */ jsx_runtime17.jsx(Text3, {
|
|
262313
263609
|
color: THEME.colors.muted,
|
|
@@ -262346,27 +263642,27 @@ ${r}`;
|
|
|
262346
263642
|
});
|
|
262347
263643
|
|
|
262348
263644
|
// ../../packages/tui/src/components/header.tsx
|
|
262349
|
-
import
|
|
263645
|
+
import fs32 from "node:fs";
|
|
262350
263646
|
import { homedir } from "node:os";
|
|
262351
|
-
import
|
|
263647
|
+
import path32 from "node:path";
|
|
262352
263648
|
function getGitBranch(workspaceRoot = process.cwd()) {
|
|
262353
263649
|
if (cachedBranch !== undefined) {
|
|
262354
263650
|
return cachedBranch;
|
|
262355
263651
|
}
|
|
262356
263652
|
try {
|
|
262357
|
-
const gitPath =
|
|
262358
|
-
if (
|
|
262359
|
-
const stat =
|
|
262360
|
-
let headPath =
|
|
263653
|
+
const gitPath = path32.resolve(workspaceRoot, ".git");
|
|
263654
|
+
if (fs32.existsSync(gitPath)) {
|
|
263655
|
+
const stat = fs32.statSync(gitPath);
|
|
263656
|
+
let headPath = path32.resolve(gitPath, "HEAD");
|
|
262361
263657
|
if (stat.isFile()) {
|
|
262362
|
-
const content =
|
|
263658
|
+
const content = fs32.readFileSync(gitPath, "utf-8").trim();
|
|
262363
263659
|
if (content.startsWith("gitdir:")) {
|
|
262364
263660
|
const gitDir = content.slice(7).trim();
|
|
262365
|
-
headPath =
|
|
263661
|
+
headPath = path32.resolve(workspaceRoot, gitDir, "HEAD");
|
|
262366
263662
|
}
|
|
262367
263663
|
}
|
|
262368
|
-
if (
|
|
262369
|
-
const headContent =
|
|
263664
|
+
if (fs32.existsSync(headPath)) {
|
|
263665
|
+
const headContent = fs32.readFileSync(headPath, "utf-8").trim();
|
|
262370
263666
|
if (headContent.startsWith("ref: refs/heads/")) {
|
|
262371
263667
|
cachedBranch = headContent.replace("ref: refs/heads/", "").trim();
|
|
262372
263668
|
return cachedBranch;
|
|
@@ -262640,11 +263936,11 @@ var init_message_list = __esm(async () => {
|
|
|
262640
263936
|
flexDirection: "column",
|
|
262641
263937
|
width: "100%",
|
|
262642
263938
|
children: [
|
|
262643
|
-
staticMessages.length > 0 && /* @__PURE__ */ jsx_runtime20.jsx(
|
|
263939
|
+
staticMessages.length > 0 && /* @__PURE__ */ jsx_runtime20.jsx(Static15, {
|
|
262644
263940
|
items: staticMessages,
|
|
262645
263941
|
style: { width: "100%" },
|
|
262646
263942
|
children: (msg, index) => renderSingleMessage(msg, index, staticMessages, cliVersion, latestVersion, userEmail, expandCommands, announcement)
|
|
262647
|
-
},
|
|
263943
|
+
}, staticKey),
|
|
262648
263944
|
activeMessages.map((msg, index) => renderSingleMessage(msg, staticMessages.length + index, [...staticMessages, ...activeMessages], cliVersion, latestVersion, userEmail, expandCommands, announcement))
|
|
262649
263945
|
]
|
|
262650
263946
|
});
|
|
@@ -267729,17 +269025,17 @@ var init_global_shortcuts = __esm(async () => {
|
|
|
267729
269025
|
|
|
267730
269026
|
// ../../packages/tui/src/utils/pager.ts
|
|
267731
269027
|
import * as cp3 from "node:child_process";
|
|
267732
|
-
import
|
|
269028
|
+
import fs33 from "node:fs";
|
|
267733
269029
|
import os18 from "node:os";
|
|
267734
|
-
import
|
|
269030
|
+
import path33 from "node:path";
|
|
267735
269031
|
function openPlanInPager(planText, title = "december-plan") {
|
|
267736
269032
|
if (Boolean(process.env.BUN_TEST) || Boolean(process.env.VITEST)) {
|
|
267737
269033
|
return Promise.resolve();
|
|
267738
269034
|
}
|
|
267739
269035
|
return new Promise((resolve) => {
|
|
267740
269036
|
try {
|
|
267741
|
-
const tmpFile =
|
|
267742
|
-
|
|
269037
|
+
const tmpFile = path33.join(os18.tmpdir(), `${title}-${Date.now()}.md`);
|
|
269038
|
+
fs33.writeFileSync(tmpFile, planText, "utf8");
|
|
267743
269039
|
const pager = process.env.PAGER || process.env.EDITOR || (os18.platform() === "win32" ? "notepad" : "less -R");
|
|
267744
269040
|
const child = cp3.spawn(pager, [tmpFile], {
|
|
267745
269041
|
stdio: "inherit",
|
|
@@ -267747,7 +269043,7 @@ function openPlanInPager(planText, title = "december-plan") {
|
|
|
267747
269043
|
});
|
|
267748
269044
|
child.on("exit", () => {
|
|
267749
269045
|
try {
|
|
267750
|
-
|
|
269046
|
+
fs33.unlinkSync(tmpFile);
|
|
267751
269047
|
} catch {}
|
|
267752
269048
|
resolve();
|
|
267753
269049
|
});
|
|
@@ -267823,6 +269119,19 @@ function ChatApp({
|
|
|
267823
269119
|
}
|
|
267824
269120
|
};
|
|
267825
269121
|
}, []);
|
|
269122
|
+
import_react69.useEffect(() => {
|
|
269123
|
+
if (!process.stdout?.isTTY || isInline)
|
|
269124
|
+
return;
|
|
269125
|
+
const handleResize = () => {
|
|
269126
|
+
try {
|
|
269127
|
+
process.stdout.write("\x1B[2J\x1B[H");
|
|
269128
|
+
} catch {}
|
|
269129
|
+
};
|
|
269130
|
+
process.stdout.on("resize", handleResize);
|
|
269131
|
+
return () => {
|
|
269132
|
+
process.stdout.off("resize", handleResize);
|
|
269133
|
+
};
|
|
269134
|
+
}, [isInline]);
|
|
267826
269135
|
use_input_default((input, key) => {
|
|
267827
269136
|
if (key.ctrl && input === "c") {
|
|
267828
269137
|
handleInterrupt();
|
|
@@ -268304,8 +269613,8 @@ var init_store = __esm(() => {
|
|
|
268304
269613
|
|
|
268305
269614
|
// src/store/interceptors.ts
|
|
268306
269615
|
import { execSync as execSync2 } from "node:child_process";
|
|
268307
|
-
import
|
|
268308
|
-
import
|
|
269616
|
+
import fs34 from "node:fs/promises";
|
|
269617
|
+
import path34 from "node:path";
|
|
268309
269618
|
async function computeToolCallDiff(toolCall) {
|
|
268310
269619
|
if (toolCall.input?.diff) {
|
|
268311
269620
|
return toolCall.input.diff;
|
|
@@ -268314,11 +269623,11 @@ async function computeToolCallDiff(toolCall) {
|
|
|
268314
269623
|
if (!targetPath)
|
|
268315
269624
|
return;
|
|
268316
269625
|
const cwd = process.cwd();
|
|
268317
|
-
const resolved =
|
|
268318
|
-
const relative =
|
|
269626
|
+
const resolved = path34.resolve(cwd, targetPath);
|
|
269627
|
+
const relative = path34.relative(cwd, resolved);
|
|
268319
269628
|
let oldContent = "";
|
|
268320
269629
|
try {
|
|
268321
|
-
oldContent = await
|
|
269630
|
+
oldContent = await fs34.readFile(resolved, "utf-8");
|
|
268322
269631
|
} catch {}
|
|
268323
269632
|
if (toolCall.name === "write_to_file" || toolCall.name === "write") {
|
|
268324
269633
|
const newContent = toolCall.input?.CodeContent ?? toolCall.input?.content ?? "";
|
|
@@ -268382,9 +269691,9 @@ function setupAgentInterceptors(agent, storeState) {
|
|
|
268382
269691
|
];
|
|
268383
269692
|
if (fileTools.includes(toolCall.name)) {
|
|
268384
269693
|
const cwd = process.cwd();
|
|
268385
|
-
const resolved =
|
|
268386
|
-
const relative =
|
|
268387
|
-
const isOutside = relative.startsWith("..") ||
|
|
269694
|
+
const resolved = path34.resolve(cwd, targetPath);
|
|
269695
|
+
const relative = path34.relative(cwd, resolved);
|
|
269696
|
+
const isOutside = relative.startsWith("..") || path34.isAbsolute(relative);
|
|
268388
269697
|
if (!config.nonWorkspaceAccess && isOutside) {
|
|
268389
269698
|
return {
|
|
268390
269699
|
block: true,
|
|
@@ -268448,8 +269757,8 @@ function setupAgentInterceptors(agent, storeState) {
|
|
|
268448
269757
|
const targetPath = toolCall.input?.TargetFile || toolCall.input?.AbsolutePath || toolCall.input?.filePath || toolCall.input?.path;
|
|
268449
269758
|
if (targetPath) {
|
|
268450
269759
|
const cwd = process.cwd();
|
|
268451
|
-
const resolved =
|
|
268452
|
-
const relative =
|
|
269760
|
+
const resolved = path34.resolve(cwd, targetPath);
|
|
269761
|
+
const relative = path34.relative(cwd, resolved);
|
|
268453
269762
|
try {
|
|
268454
269763
|
execSync2(`git ls-files --error-unmatch "${relative}"`, {
|
|
268455
269764
|
cwd,
|
|
@@ -268476,7 +269785,7 @@ var init_interceptors = __esm(() => {
|
|
|
268476
269785
|
});
|
|
268477
269786
|
|
|
268478
269787
|
// src/utils/direct-shell.ts
|
|
268479
|
-
import { spawn as
|
|
269788
|
+
import { spawn as spawn6 } from "node:child_process";
|
|
268480
269789
|
function startDirectCommand(command, options = {}) {
|
|
268481
269790
|
const { timeoutMs = 20000, serverReadyDelayMs = 2500, onData, onBackground } = options;
|
|
268482
269791
|
let output = "";
|
|
@@ -268486,7 +269795,7 @@ function startDirectCommand(command, options = {}) {
|
|
|
268486
269795
|
const isWindows = process.platform === "win32";
|
|
268487
269796
|
const shellCmd = isWindows ? "cmd.exe" : "/bin/bash";
|
|
268488
269797
|
const shellArgs = isWindows ? ["/d", "/s", "/c", command] : ["-c", command];
|
|
268489
|
-
const child =
|
|
269798
|
+
const child = spawn6(shellCmd, shellArgs, {
|
|
268490
269799
|
cwd: process.cwd(),
|
|
268491
269800
|
env: process.env,
|
|
268492
269801
|
stdio: ["pipe", "pipe", "pipe"],
|
|
@@ -268638,15 +269947,15 @@ var init_direct_shell = __esm(() => {
|
|
|
268638
269947
|
});
|
|
268639
269948
|
|
|
268640
269949
|
// src/utils/usage-tracker.ts
|
|
268641
|
-
import
|
|
268642
|
-
import
|
|
269950
|
+
import fs35 from "node:fs/promises";
|
|
269951
|
+
import path35 from "node:path";
|
|
268643
269952
|
function getUsageFilePath() {
|
|
268644
|
-
return
|
|
269953
|
+
return path35.join(getConfigDir(), "usage.json");
|
|
268645
269954
|
}
|
|
268646
269955
|
async function loadUsageLedger() {
|
|
268647
269956
|
const filePath = getUsageFilePath();
|
|
268648
269957
|
try {
|
|
268649
|
-
const raw = await
|
|
269958
|
+
const raw = await fs35.readFile(filePath, "utf-8");
|
|
268650
269959
|
const parsed = JSON.parse(raw);
|
|
268651
269960
|
if (parsed && typeof parsed === "object" && parsed.version === 1 && parsed.days) {
|
|
268652
269961
|
return parsed;
|
|
@@ -268659,8 +269968,8 @@ async function loadUsageLedger() {
|
|
|
268659
269968
|
}
|
|
268660
269969
|
async function saveUsageLedger(ledger) {
|
|
268661
269970
|
const configDir = getConfigDir();
|
|
268662
|
-
const filePath =
|
|
268663
|
-
const tmpPath =
|
|
269971
|
+
const filePath = path35.join(configDir, "usage.json");
|
|
269972
|
+
const tmpPath = path35.join(configDir, `usage.json.tmp.${Date.now()}`);
|
|
268664
269973
|
const cutoffDate = new Date(Date.now() - 30 * 24 * 60 * 60 * 1000).toISOString().slice(0, 10);
|
|
268665
269974
|
const prunedDays = {};
|
|
268666
269975
|
for (const [dateKey, dayRecord] of Object.entries(ledger.days)) {
|
|
@@ -268670,12 +269979,12 @@ async function saveUsageLedger(ledger) {
|
|
|
268670
269979
|
}
|
|
268671
269980
|
ledger.days = prunedDays;
|
|
268672
269981
|
try {
|
|
268673
|
-
await
|
|
268674
|
-
await
|
|
268675
|
-
await
|
|
269982
|
+
await fs35.mkdir(configDir, { recursive: true });
|
|
269983
|
+
await fs35.writeFile(tmpPath, JSON.stringify(ledger, null, 2), "utf-8");
|
|
269984
|
+
await fs35.rename(tmpPath, filePath);
|
|
268676
269985
|
} catch {
|
|
268677
269986
|
try {
|
|
268678
|
-
await
|
|
269987
|
+
await fs35.unlink(tmpPath);
|
|
268679
269988
|
} catch {}
|
|
268680
269989
|
}
|
|
268681
269990
|
}
|
|
@@ -268873,7 +270182,7 @@ var init_usage_rates2 = __esm(() => {
|
|
|
268873
270182
|
// src/utils/error-parser.ts
|
|
268874
270183
|
import util5 from "util";
|
|
268875
270184
|
function isCreditOrBalanceError(combined) {
|
|
268876
|
-
return combined.includes("insufficient balance") || combined.includes("insufficient credits") || combined.includes("insufficient_balance") || combined.includes("insufficient_credits") || combined.includes("insufficient_quota") || combined.includes("balance is insufficient") || combined.includes("balance insufficient") || combined.includes("balance exhausted") || combined.includes("out of credits") || combined.includes("credit balance is too low") || combined.includes("credits exhausted") || combined.includes("requires more credits") || combined.includes("can only afford") || combined.includes("payment required") || combined.includes("quota exceeded") || combined.includes("quota_exhausted") || combined.includes("402") || combined.includes("1008") || combined.includes("20009") || (combined.includes("credits") || combined.includes("balance")) && (combined.includes("insufficient") || combined.includes("exhausted") || combined.includes("empty") || combined.includes("zero") || combined.includes("low") || combined.includes("top up") || combined.includes("recharge") || combined.includes("afford") || combined.includes("add credits"));
|
|
270185
|
+
return combined.includes("insufficient balance") || combined.includes("insufficient credits") || combined.includes("insufficient_balance") || combined.includes("insufficient_credits") || combined.includes("insufficient_quota") || combined.includes("balance is insufficient") || combined.includes("balance insufficient") || combined.includes("balance exhausted") || combined.includes("out of credits") || combined.includes("credit balance is too low") || combined.includes("credits exhausted") || combined.includes("requires more credits") || combined.includes("can only afford") || combined.includes("payment required") || combined.includes("quota exceeded") || combined.includes("quota_exhausted") || combined.includes("budget_exhausted") || combined.includes("budget exhausted") || combined.includes("budget exceeded") || combined.includes("budget_exceeded") || combined.includes("402") || combined.includes("1008") || combined.includes("20009") || (combined.includes("credits") || combined.includes("balance")) && (combined.includes("insufficient") || combined.includes("exhausted") || combined.includes("empty") || combined.includes("zero") || combined.includes("low") || combined.includes("top up") || combined.includes("recharge") || combined.includes("afford") || combined.includes("add credits"));
|
|
268877
270186
|
}
|
|
268878
270187
|
function normalizeProviderAlias(provider) {
|
|
268879
270188
|
if (!provider)
|
|
@@ -269257,7 +270566,8 @@ function parseErrorMessage(err, context) {
|
|
|
269257
270566
|
}
|
|
269258
270567
|
const contextStr = `${context?.provider || ""} ${context?.model || ""}`.toLowerCase().trim();
|
|
269259
270568
|
const lowerStr = (errMsg + " " + (finalResult || "") + (contextStr ? " " + contextStr : "")).toLowerCase();
|
|
269260
|
-
const
|
|
270569
|
+
const isBudgetExhausted = lowerStr.includes("budget_exhausted") || lowerStr.includes("budget exhausted") || lowerStr.includes("budget_exceeded") || lowerStr.includes("budget exceeded");
|
|
270570
|
+
const isRateLimit = !isBudgetExhausted && (lowerStr.includes("429") || lowerStr.includes("quota") || lowerStr.includes("rate limit") || lowerStr.includes("rate_limit") || lowerStr.includes("resource_exhausted") || lowerStr.includes("generativelanguage.googleapis.com"));
|
|
269261
270571
|
if (isRateLimit && !finalResult.includes("Rate limit or quota exhausted")) {
|
|
269262
270572
|
const rateDetails = resolveRateLimitDetails(lowerStr, context);
|
|
269263
270573
|
return rateDetails.notice + finalResult;
|
|
@@ -269298,7 +270608,8 @@ function parseError(err, context) {
|
|
|
269298
270608
|
const contextStr = `${context?.provider || ""} ${context?.model || ""}`.toLowerCase().trim();
|
|
269299
270609
|
const fullMessage = parseErrorMessage(err, context);
|
|
269300
270610
|
const combined = `${fullMessage} ${explicitCause || ""} ${contextStr ? " " + contextStr : ""}`.toLowerCase();
|
|
269301
|
-
const
|
|
270611
|
+
const isBudgetExhausted = combined.includes("budget_exhausted") || combined.includes("budget exhausted") || combined.includes("budget_exceeded") || combined.includes("budget exceeded");
|
|
270612
|
+
const isRateLimit = !isBudgetExhausted && (combined.includes("429") || combined.includes("quota") || combined.includes("rate limit") || combined.includes("rate_limit") || combined.includes("resource_exhausted") || combined.includes("generativelanguage.googleapis.com"));
|
|
269302
270613
|
if (isRateLimit) {
|
|
269303
270614
|
const parts = fullMessage.split(`
|
|
269304
270615
|
`);
|
|
@@ -269940,7 +271251,7 @@ var init_error_parser = __esm(() => {
|
|
|
269940
271251
|
{
|
|
269941
271252
|
id: "auriko",
|
|
269942
271253
|
name: "Auriko",
|
|
269943
|
-
match: (str) => (str.includes("auriko.ai") || str.includes("api.auriko.ai") || str.includes("auriko")) && (isCreditOrBalanceError(str) || str.includes("credits") || str.includes("402")),
|
|
271254
|
+
match: (str) => (str.includes("auriko.ai") || str.includes("api.auriko.ai") || str.includes("auriko")) && (isCreditOrBalanceError(str) || str.includes("credits") || str.includes("budget") || str.includes("402")),
|
|
269944
271255
|
notice: `Insufficient credits in your Auriko account. Please check your account at https://www.auriko.ai/dashboard
|
|
269945
271256
|
`,
|
|
269946
271257
|
message: "Insufficient credits in your Auriko account.",
|
|
@@ -270110,14 +271421,14 @@ function extractJsonArray(rawText) {
|
|
|
270110
271421
|
}
|
|
270111
271422
|
|
|
270112
271423
|
// src/utils/project-context.ts
|
|
270113
|
-
import
|
|
270114
|
-
import
|
|
271424
|
+
import fs36 from "node:fs";
|
|
271425
|
+
import path36 from "node:path";
|
|
270115
271426
|
function getProjectContext(workspaceDir = process.cwd()) {
|
|
270116
271427
|
const parts = [];
|
|
270117
271428
|
try {
|
|
270118
|
-
const pkgPath =
|
|
270119
|
-
if (
|
|
270120
|
-
const pkg = JSON.parse(
|
|
271429
|
+
const pkgPath = path36.join(workspaceDir, "package.json");
|
|
271430
|
+
if (fs36.existsSync(pkgPath)) {
|
|
271431
|
+
const pkg = JSON.parse(fs36.readFileSync(pkgPath, "utf8"));
|
|
270121
271432
|
const deps = Object.keys(pkg.dependencies || {}).slice(0, 15).join(", ");
|
|
270122
271433
|
const devDeps = Object.keys(pkg.devDependencies || {}).slice(0, 10).join(", ");
|
|
270123
271434
|
parts.push(`Project: ${pkg.name || "Unnamed"}`);
|
|
@@ -270126,13 +271437,13 @@ function getProjectContext(workspaceDir = process.cwd()) {
|
|
|
270126
271437
|
if (devDeps)
|
|
270127
271438
|
parts.push(`DevDependencies: ${devDeps}`);
|
|
270128
271439
|
}
|
|
270129
|
-
const agentsPath =
|
|
270130
|
-
if (
|
|
270131
|
-
const content =
|
|
271440
|
+
const agentsPath = path36.join(workspaceDir, "AGENTS.md");
|
|
271441
|
+
if (fs36.existsSync(agentsPath)) {
|
|
271442
|
+
const content = fs36.readFileSync(agentsPath, "utf8");
|
|
270132
271443
|
parts.push(`Guidelines (from AGENTS.md):
|
|
270133
271444
|
${content.slice(0, 500)}`);
|
|
270134
271445
|
}
|
|
270135
|
-
const entries =
|
|
271446
|
+
const entries = fs36.readdirSync(workspaceDir, { withFileTypes: true }).filter((e) => !e.name.startsWith(".") && e.name !== "node_modules").map((e) => e.isDirectory() ? `${e.name}/` : e.name).slice(0, 20);
|
|
270136
271447
|
if (entries.length > 0) {
|
|
270137
271448
|
parts.push(`Workspace layout: ${entries.join(", ")}`);
|
|
270138
271449
|
}
|
|
@@ -270287,14 +271598,14 @@ async function fetchProviderBalance(provider, apiKey, timeoutMs = 2000) {
|
|
|
270287
271598
|
}
|
|
270288
271599
|
|
|
270289
271600
|
// src/utils/formatters.ts
|
|
270290
|
-
import
|
|
271601
|
+
import path37 from "node:path";
|
|
270291
271602
|
function toRelativePath2(filePath, cwd = process.cwd()) {
|
|
270292
271603
|
if (!filePath)
|
|
270293
271604
|
return "";
|
|
270294
271605
|
const trimmed = filePath.trim();
|
|
270295
|
-
if (!
|
|
271606
|
+
if (!path37.isAbsolute(trimmed))
|
|
270296
271607
|
return trimmed;
|
|
270297
|
-
const rel =
|
|
271608
|
+
const rel = path37.relative(cwd, trimmed);
|
|
270298
271609
|
if (!rel || rel.startsWith("..")) {
|
|
270299
271610
|
return trimmed;
|
|
270300
271611
|
}
|
|
@@ -271034,7 +272345,7 @@ ${formatSubscriptionCard(bundle, targetModel)}`
|
|
|
271034
272345
|
const probeAbortController = new AbortController;
|
|
271035
272346
|
const probeTimeout = setTimeout(() => {
|
|
271036
272347
|
probeAbortController.abort(new Error("Connection timed out while verifying API key."));
|
|
271037
|
-
},
|
|
272348
|
+
}, 8000);
|
|
271038
272349
|
try {
|
|
271039
272350
|
const stream = testProvider.stream([{ role: "user", content: "Hi" }], undefined, undefined, {
|
|
271040
272351
|
model: testModel,
|
|
@@ -271051,15 +272362,19 @@ ${formatSubscriptionCard(bundle, targetModel)}`
|
|
|
271051
272362
|
}
|
|
271052
272363
|
} catch (probeErr) {
|
|
271053
272364
|
lastProbeErr = probeErr;
|
|
271054
|
-
const errText =
|
|
272365
|
+
const errText = `${probeErr?.message || ""} ${probeErr?.code || ""} ${probeErr?.error?.code || ""} ${String(probeErr)}`.toLowerCase();
|
|
271055
272366
|
if (errText.includes("401") || errText.includes("unauthorized") || errText.includes("invalid api key") || errText.includes("incorrect api key")) {
|
|
271056
272367
|
throw probeErr;
|
|
271057
272368
|
}
|
|
271058
|
-
if (errText.includes("402") || errText.includes("credits") || errText.includes("payment") || errText.includes("afford") || errText.includes("insufficient_quota")) {
|
|
272369
|
+
if (errText.includes("402") || errText.includes("credits") || errText.includes("payment") || errText.includes("afford") || errText.includes("budget") || errText.includes("balance") || errText.includes("insufficient_quota")) {
|
|
271059
272370
|
if (!lowCreditErr) {
|
|
271060
272371
|
lowCreditErr = probeErr;
|
|
271061
272372
|
lowCreditModel = testModel;
|
|
271062
272373
|
}
|
|
272374
|
+
break;
|
|
272375
|
+
}
|
|
272376
|
+
if (errText.includes("timed out") || errText.includes("timeout") || probeErr?.name === "AbortError") {
|
|
272377
|
+
break;
|
|
271063
272378
|
}
|
|
271064
272379
|
}
|
|
271065
272380
|
}
|
|
@@ -271099,10 +272414,10 @@ ${formatSubscriptionCard(bundle, targetModel)}`
|
|
|
271099
272414
|
setApiKey("");
|
|
271100
272415
|
addToast(MESSAGES.AUTH.API_KEY_SAVED(selectedProvider), "success");
|
|
271101
272416
|
} catch (err) {
|
|
271102
|
-
const errStr =
|
|
272417
|
+
const errStr = `${err?.message || ""} ${err?.code || ""} ${err?.error?.code || ""} ${String(err)}`.toLowerCase();
|
|
271103
272418
|
const isTimeout = err?.name === "AbortError" || errStr.includes("aborted") || errStr.includes("timed out") || errStr.includes("timeout");
|
|
271104
|
-
const isLowCredit = errStr.includes("402") || errStr.includes("credits") || errStr.includes("payment") || errStr.includes("afford");
|
|
271105
|
-
if (errStr.includes("429") || errStr.includes("quota") || errStr.includes("rate limit") || errStr.includes("404") || errStr.includes("not found") || errStr.includes("503") || errStr.includes("无可用渠道") || errStr.includes("no available channel") || isLowCredit) {
|
|
272419
|
+
const isLowCredit = errStr.includes("402") || errStr.includes("credits") || errStr.includes("payment") || errStr.includes("afford") || errStr.includes("budget") || errStr.includes("balance") || errStr.includes("insufficient_quota");
|
|
272420
|
+
if (errStr.includes("429") || errStr.includes("quota") || errStr.includes("rate limit") || errStr.includes("404") || errStr.includes("not found") || errStr.includes("503") || errStr.includes("无可用渠道") || errStr.includes("no available channel") || errStr.includes("platform_keys_unavailable") || errStr.includes("byok_keys_required") || errStr.includes("tier_opt_in_required") || errStr.includes("no_provider_available") || isLowCredit) {
|
|
271106
272421
|
await Promise.resolve().then(() => init_models5());
|
|
271107
272422
|
const finalModel = testModel || getDefaultModelForProvider(selectedProvider);
|
|
271108
272423
|
const config = await loadConfig();
|
|
@@ -271290,7 +272605,6 @@ ${formatSubscriptionCard(bundle, targetModel)}`
|
|
|
271290
272605
|
try {
|
|
271291
272606
|
await agent.loadContext(item.value);
|
|
271292
272607
|
const resumedMessages = convertAgentMessagesToTuiMessages(agent.messages);
|
|
271293
|
-
console.clear();
|
|
271294
272608
|
setStaticMessages([{ id: "header", role: "header" }, ...resumedMessages]);
|
|
271295
272609
|
setStaticKey((k) => k + 1);
|
|
271296
272610
|
setActiveMessages([]);
|
|
@@ -271683,7 +272997,6 @@ function useAgentSession({
|
|
|
271683
272997
|
} = state;
|
|
271684
272998
|
const [expandCommands, setExpandCommands] = import_react71.useState(false);
|
|
271685
272999
|
const toggleExpandCommands = import_react71.useCallback(() => {
|
|
271686
|
-
console.clear();
|
|
271687
273000
|
setExpandCommands((prev) => !prev);
|
|
271688
273001
|
}, []);
|
|
271689
273002
|
const [detectedSubscriptions, setDetectedSubscriptions] = import_react71.useState({});
|
|
@@ -271728,7 +273041,6 @@ function useAgentSession({
|
|
|
271728
273041
|
}
|
|
271729
273042
|
const resumed = convertAgentMessagesToTuiMessages(agent.messages);
|
|
271730
273043
|
if (resumed.length > 0) {
|
|
271731
|
-
console.clear();
|
|
271732
273044
|
setStaticMessages([{ id: "header", role: "header" }, ...resumed]);
|
|
271733
273045
|
setStaticKey((k) => k + 1);
|
|
271734
273046
|
}
|
|
@@ -273696,7 +275008,7 @@ var init_use_agent_session = __esm(async () => {
|
|
|
273696
275008
|
|
|
273697
275009
|
// src/index.ts
|
|
273698
275010
|
init_package();
|
|
273699
|
-
import
|
|
275011
|
+
import path38 from "node:path";
|
|
273700
275012
|
|
|
273701
275013
|
// src/args.ts
|
|
273702
275014
|
import { parseArgs } from "node:util";
|
|
@@ -273834,12 +275146,12 @@ Options:
|
|
|
273834
275146
|
}
|
|
273835
275147
|
// src/constants/release-highlights.json
|
|
273836
275148
|
var release_highlights_default = {
|
|
273837
|
-
version: "0.4.
|
|
273838
|
-
title: "What's New in v0.4.
|
|
275149
|
+
version: "0.4.4",
|
|
275150
|
+
title: "What's New in v0.4.4",
|
|
273839
275151
|
bullets: [
|
|
273840
|
-
"*(
|
|
273841
|
-
"*(
|
|
273842
|
-
"*(
|
|
275152
|
+
"*(agent)* Passive workspace memory ingestion and manage_memory tool",
|
|
275153
|
+
"*(agent)* Lsp client integration for definition and reference navigation",
|
|
275154
|
+
"*(tools)* Prefer non-import lines when resolving symbol definition in code_intelligence"
|
|
273843
275155
|
],
|
|
273844
275156
|
url: "https://trydecember.com/docs/changelog"
|
|
273845
275157
|
};
|
|
@@ -274040,7 +275352,7 @@ To define project-specific instructions, create an AGENTS.md file in your projec
|
|
|
274040
275352
|
sessionRepository,
|
|
274041
275353
|
sessionId,
|
|
274042
275354
|
runtime: "cli",
|
|
274043
|
-
workspaceDir: parsedArgs.scope ?
|
|
275355
|
+
workspaceDir: parsedArgs.scope ? path38.resolve(process.cwd(), parsedArgs.scope) : process.cwd(),
|
|
274044
275356
|
thinkingLevel: config.thinkingLevel || "auto",
|
|
274045
275357
|
steeringMode: config.steeringMode || "all",
|
|
274046
275358
|
followUpMode: config.followUpMode || "all"
|
|
@@ -274144,7 +275456,7 @@ Executing Headless Task: "${parsedArgs.prompt}"
|
|
|
274144
275456
|
sessionRepository,
|
|
274145
275457
|
sessionId,
|
|
274146
275458
|
runtime: "cli",
|
|
274147
|
-
workspaceDir: parsedArgs.scope ?
|
|
275459
|
+
workspaceDir: parsedArgs.scope ? path38.resolve(process.cwd(), parsedArgs.scope) : process.cwd(),
|
|
274148
275460
|
thinkingLevel: config.thinkingLevel || "auto",
|
|
274149
275461
|
steeringMode: config.steeringMode || "all",
|
|
274150
275462
|
followUpMode: config.followUpMode || "all"
|