@travisennis/acai 0.0.10 → 0.0.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -4
- package/dist/agent/index.d.ts.map +1 -1
- package/dist/agent/index.js +29 -27
- package/dist/cli/stdin.d.ts +2 -1
- package/dist/cli/stdin.d.ts.map +1 -1
- package/dist/commands/generate-rules/service.d.ts +3 -2
- package/dist/commands/generate-rules/service.d.ts.map +1 -1
- package/dist/commands/health/utils.d.ts +3 -2
- package/dist/commands/health/utils.d.ts.map +1 -1
- package/dist/commands/init-project/utils.d.ts +2 -1
- package/dist/commands/init-project/utils.d.ts.map +1 -1
- package/dist/commands/init-project/utils.js +0 -11
- package/dist/commands/manager.d.ts.map +1 -1
- package/dist/commands/manager.js +6 -1
- package/dist/commands/resources/index.d.ts.map +1 -1
- package/dist/commands/resources/index.js +4 -1
- package/dist/commands/review/utils.d.ts +6 -1
- package/dist/commands/review/utils.d.ts.map +1 -1
- package/dist/commands/session/index.d.ts.map +1 -1
- package/dist/commands/session/index.js +6 -0
- package/dist/commands/session/types.d.ts +1 -0
- package/dist/commands/session/types.d.ts.map +1 -1
- package/dist/commands/tools/index.d.ts +3 -0
- package/dist/commands/tools/index.d.ts.map +1 -0
- package/dist/commands/tools/index.js +190 -0
- package/dist/commands/tools/templates.d.ts +6 -0
- package/dist/commands/tools/templates.d.ts.map +1 -0
- package/dist/commands/tools/templates.js +97 -0
- package/dist/config/index.d.ts +5 -0
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +41 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +15 -3
- package/dist/models/anthropic-provider.d.ts +1 -1
- package/dist/models/deepseek-provider.d.ts +3 -3
- package/dist/models/deepseek-provider.js +17 -17
- package/dist/models/google-provider.d.ts +2 -4
- package/dist/models/google-provider.d.ts.map +1 -1
- package/dist/models/google-provider.js +2 -17
- package/dist/models/groq-provider.d.ts +2 -4
- package/dist/models/groq-provider.d.ts.map +1 -1
- package/dist/models/groq-provider.js +3 -21
- package/dist/models/opencode-go-provider.d.ts +35 -0
- package/dist/models/opencode-go-provider.d.ts.map +1 -0
- package/dist/models/opencode-go-provider.js +214 -0
- package/dist/models/opencode-zen-provider.d.ts +5 -5
- package/dist/models/opencode-zen-provider.d.ts.map +1 -1
- package/dist/models/opencode-zen-provider.js +41 -47
- package/dist/models/openrouter-provider.d.ts +5 -13
- package/dist/models/openrouter-provider.d.ts.map +1 -1
- package/dist/models/openrouter-provider.js +34 -138
- package/dist/models/providers.d.ts +3 -3
- package/dist/models/providers.d.ts.map +1 -1
- package/dist/models/providers.js +6 -0
- package/dist/models/xai-provider.d.ts +1 -2
- package/dist/models/xai-provider.d.ts.map +1 -1
- package/dist/models/xai-provider.js +0 -13
- package/dist/prompts/manager.d.ts.map +1 -1
- package/dist/prompts/manager.js +5 -1
- package/dist/prompts/mentions.d.ts.map +1 -1
- package/dist/prompts/mentions.js +35 -6
- package/dist/prompts/system-prompt.d.ts +1 -0
- package/dist/prompts/system-prompt.d.ts.map +1 -1
- package/dist/prompts/system-prompt.js +20 -5
- package/dist/repl/index.d.ts +1 -2
- package/dist/repl/index.d.ts.map +1 -1
- package/dist/repl/index.js +14 -53
- package/dist/sessions/manager.d.ts +3 -3
- package/dist/sessions/manager.d.ts.map +1 -1
- package/dist/sessions/manager.js +1 -1
- package/dist/skills/activated-tracker.d.ts +11 -0
- package/dist/skills/activated-tracker.d.ts.map +1 -0
- package/dist/skills/activated-tracker.js +16 -0
- package/dist/skills/index.d.ts +3 -2
- package/dist/skills/index.d.ts.map +1 -1
- package/dist/skills/index.js +7 -1
- package/dist/subagents/index.d.ts +2 -1
- package/dist/subagents/index.d.ts.map +1 -1
- package/dist/terminal/table/utils.d.ts +1 -1
- package/dist/terminal/table/utils.d.ts.map +1 -1
- package/dist/terminal/wrap-ansi.js +2 -2
- package/dist/tools/agent.js +1 -1
- package/dist/tools/apply-patch.d.ts +62 -0
- package/dist/tools/apply-patch.d.ts.map +1 -0
- package/dist/tools/apply-patch.js +377 -0
- package/dist/tools/bash.d.ts +4 -4
- package/dist/tools/bash.d.ts.map +1 -1
- package/dist/tools/bash.js +40 -8
- package/dist/tools/directory-tree.d.ts +4 -4
- package/dist/tools/directory-tree.d.ts.map +1 -1
- package/dist/tools/directory-tree.js +3 -1
- package/dist/tools/dynamic-tool-loader.d.ts +12 -3
- package/dist/tools/dynamic-tool-loader.d.ts.map +1 -1
- package/dist/tools/dynamic-tool-loader.js +299 -39
- package/dist/tools/edit-file.d.ts +2 -2
- package/dist/tools/edit-file.d.ts.map +1 -1
- package/dist/tools/edit-file.js +188 -79
- package/dist/tools/glob.d.ts +16 -16
- package/dist/tools/glob.d.ts.map +1 -1
- package/dist/tools/glob.js +30 -15
- package/dist/tools/grep.d.ts +14 -14
- package/dist/tools/grep.d.ts.map +1 -1
- package/dist/tools/grep.js +50 -29
- package/dist/tools/index.d.ts +57 -84
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +20 -5
- package/dist/tools/ls.d.ts +2 -2
- package/dist/tools/ls.d.ts.map +1 -1
- package/dist/tools/ls.js +2 -1
- package/dist/tools/read-file.d.ts +9 -11
- package/dist/tools/read-file.d.ts.map +1 -1
- package/dist/tools/read-file.js +21 -16
- package/dist/tools/save-file.d.ts +4 -4
- package/dist/tools/save-file.d.ts.map +1 -1
- package/dist/tools/save-file.js +26 -21
- package/dist/tools/skill.d.ts +2 -1
- package/dist/tools/skill.d.ts.map +1 -1
- package/dist/tools/skill.js +55 -12
- package/dist/tools/types.d.ts +8 -2
- package/dist/tools/types.d.ts.map +1 -1
- package/dist/tools/web-fetch.d.ts +6 -18
- package/dist/tools/web-fetch.d.ts.map +1 -1
- package/dist/tools/web-fetch.js +45 -9
- package/dist/tools/web-search.d.ts +4 -22
- package/dist/tools/web-search.d.ts.map +1 -1
- package/dist/tools/web-search.js +1 -1
- package/dist/tui/autocomplete/file-search-provider.js +1 -1
- package/dist/tui/autocomplete/utils.d.ts +2 -1
- package/dist/tui/autocomplete/utils.d.ts.map +1 -1
- package/dist/tui/autocomplete/utils.js +25 -23
- package/dist/tui/components/editor.d.ts +2 -1
- package/dist/tui/components/editor.d.ts.map +1 -1
- package/dist/tui/components/editor.js +1 -1
- package/dist/tui/components/footer.d.ts +0 -2
- package/dist/tui/components/footer.d.ts.map +1 -1
- package/dist/tui/components/footer.js +1 -17
- package/dist/tui/components/markdown.d.ts +2 -2
- package/dist/tui/components/markdown.d.ts.map +1 -1
- package/dist/tui/components/welcome.d.ts +2 -1
- package/dist/tui/components/welcome.d.ts.map +1 -1
- package/dist/tui/editor-launcher.d.ts +3 -2
- package/dist/tui/editor-launcher.d.ts.map +1 -1
- package/dist/tui/index.d.ts +0 -1
- package/dist/tui/index.d.ts.map +1 -1
- package/dist/tui/tui.d.ts +1 -0
- package/dist/tui/tui.d.ts.map +1 -1
- package/dist/tui/tui.js +9 -0
- package/dist/tui/utils.d.ts +1 -5
- package/dist/tui/utils.d.ts.map +1 -1
- package/dist/tui/utils.js +271 -44
- package/dist/utils/binary-output.d.ts +32 -0
- package/dist/utils/binary-output.d.ts.map +1 -0
- package/dist/utils/binary-output.js +127 -0
- package/dist/utils/command-protection.d.ts.map +1 -1
- package/dist/utils/command-protection.js +92 -9
- package/dist/utils/parsing.d.ts +1 -1
- package/dist/utils/parsing.d.ts.map +1 -1
- package/package.json +28 -26
- package/dist/commands/add-directory/types.d.ts +0 -6
- package/dist/commands/add-directory/types.d.ts.map +0 -1
- package/dist/commands/add-directory/types.js +0 -1
- package/dist/commands/copy/types.d.ts +0 -3
- package/dist/commands/copy/types.d.ts.map +0 -1
- package/dist/commands/copy/types.js +0 -1
- package/dist/commands/review/types.d.ts +0 -12
- package/dist/commands/review/types.d.ts.map +0 -1
- package/dist/commands/review/types.js +0 -1
- package/dist/modes/manager.d.ts +0 -23
- package/dist/modes/manager.d.ts.map +0 -1
- package/dist/modes/manager.js +0 -77
- package/dist/modes/prompts.d.ts +0 -2
- package/dist/modes/prompts.d.ts.map +0 -1
- package/dist/modes/prompts.js +0 -143
- package/dist/tools/code-search.d.ts +0 -41
- package/dist/tools/code-search.d.ts.map +0 -1
- package/dist/tools/code-search.js +0 -195
- package/dist/utils/iterables.d.ts +0 -2
- package/dist/utils/iterables.d.ts.map +0 -1
- package/dist/utils/iterables.js +0 -6
package/dist/tools/save-file.js
CHANGED
|
@@ -17,6 +17,30 @@ const inputSchema = z.object({
|
|
|
17
17
|
.describe('Encoding format for saving the file. Use "utf-8" as default for text files')
|
|
18
18
|
.default("utf-8"),
|
|
19
19
|
});
|
|
20
|
+
async function checkFileNotReadOnly(filePath, projectConfig, primaryDir) {
|
|
21
|
+
try {
|
|
22
|
+
await fs.stat(filePath);
|
|
23
|
+
validateFileNotReadOnly(filePath, projectConfig, primaryDir);
|
|
24
|
+
}
|
|
25
|
+
catch (error) {
|
|
26
|
+
if (error.code !== "ENOENT") {
|
|
27
|
+
throw error;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
async function ensurePathIsFile(filePath) {
|
|
32
|
+
try {
|
|
33
|
+
const stat = await fs.stat(filePath);
|
|
34
|
+
if (stat.isDirectory()) {
|
|
35
|
+
throw new Error(`Cannot save file - path is a directory: ${filePath}`);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
catch (error) {
|
|
39
|
+
if (error.code !== "ENOENT") {
|
|
40
|
+
throw error;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
20
44
|
export const createSaveFileTool = async (options) => {
|
|
21
45
|
const { primaryDir, allowedDirs } = options.workspace;
|
|
22
46
|
const allowedDirectory = allowedDirs ?? [primaryDir];
|
|
@@ -35,27 +59,8 @@ export const createSaveFileTool = async (options) => {
|
|
|
35
59
|
throw new Error("File saving aborted");
|
|
36
60
|
}
|
|
37
61
|
const filePath = await validatePath(joinWorkingDir(userPath, primaryDir), allowedDirectory, { requireExistence: false, abortSignal });
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
validateFileNotReadOnly(filePath, projectConfig, primaryDir);
|
|
41
|
-
}
|
|
42
|
-
catch (error) {
|
|
43
|
-
if (error.code !== "ENOENT") {
|
|
44
|
-
throw error;
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
try {
|
|
48
|
-
const stat = await fs.stat(filePath);
|
|
49
|
-
if (stat.isDirectory()) {
|
|
50
|
-
throw new Error(`Cannot save file - path is a directory: ${filePath}`);
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
catch (error) {
|
|
54
|
-
if (error instanceof Error &&
|
|
55
|
-
error.message.includes("is a directory")) {
|
|
56
|
-
throw error;
|
|
57
|
-
}
|
|
58
|
-
}
|
|
62
|
+
await checkFileNotReadOnly(filePath, projectConfig, primaryDir);
|
|
63
|
+
await ensurePathIsFile(filePath);
|
|
59
64
|
if (abortSignal?.aborted) {
|
|
60
65
|
throw new Error("File saving aborted before writing");
|
|
61
66
|
}
|
package/dist/tools/skill.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
+
import type { ActivatedSkillsTracker } from "../skills/activated-tracker.ts";
|
|
2
3
|
import type { ToolExecutionOptions } from "./types.ts";
|
|
3
4
|
export declare const SkillTool: {
|
|
4
5
|
name: "Skill";
|
|
@@ -8,7 +9,7 @@ declare const inputSchema: z.ZodObject<{
|
|
|
8
9
|
args: z.ZodOptional<z.ZodString>;
|
|
9
10
|
}, z.core.$strip>;
|
|
10
11
|
type SkillInputSchema = z.infer<typeof inputSchema>;
|
|
11
|
-
export declare function createSkillTool(): Promise<{
|
|
12
|
+
export declare function createSkillTool(activatedSkillsTracker: ActivatedSkillsTracker): Promise<{
|
|
12
13
|
toolDef: {
|
|
13
14
|
description: string;
|
|
14
15
|
inputSchema: z.ZodObject<{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"skill.d.ts","sourceRoot":"","sources":["../../source/tools/skill.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"skill.d.ts","sourceRoot":"","sources":["../../source/tools/skill.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAC;AAI7E,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAEvD,eAAO,MAAM,SAAS;;CAErB,CAAC;AAEF,QAAA,MAAM,WAAW;;;iBAKf,CAAC;AAEH,KAAK,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,CAAC;AA+BpD,wBAAsB,eAAe,CACnC,sBAAsB,EAAE,sBAAsB;;;;;;;;kCAcd,gBAAgB,GAAG,MAAM;wCAIzB,gBAAgB,mBAC3B,oBAAoB,GACpC,OAAO,CAAC,MAAM,CAAC;GA8DrB"}
|
package/dist/tools/skill.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { readFile } from "node:fs/promises";
|
|
2
|
-
import { dirname } from "node:path";
|
|
1
|
+
import { readdir, readFile } from "node:fs/promises";
|
|
3
2
|
import { z } from "zod";
|
|
3
|
+
import { config, parseSkillsPath } from "../config/index.js";
|
|
4
4
|
import { loadSkills } from "../skills/index.js";
|
|
5
5
|
import style from "../terminal/style.js";
|
|
6
6
|
import { replaceArgumentPlaceholders } from "../utils/templates.js";
|
|
@@ -13,8 +13,37 @@ const inputSchema = z.object({
|
|
|
13
13
|
.describe('The skill name. E.g., "commit", "review-pr", or "pdf"'),
|
|
14
14
|
args: z.string().optional().describe("Optional arguments for the skill"),
|
|
15
15
|
});
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
/**
|
|
17
|
+
* List resources (files and directories) in a skill directory.
|
|
18
|
+
* Returns relative paths, excluding SKILL.md and hidden files.
|
|
19
|
+
*/
|
|
20
|
+
async function listSkillResources(baseDir) {
|
|
21
|
+
try {
|
|
22
|
+
const entries = await readdir(baseDir, { withFileTypes: true });
|
|
23
|
+
const resources = [];
|
|
24
|
+
for (const entry of entries) {
|
|
25
|
+
// Skip SKILL.md (already included in body)
|
|
26
|
+
if (entry.name === "SKILL.md")
|
|
27
|
+
continue;
|
|
28
|
+
// Skip hidden files
|
|
29
|
+
if (entry.name.startsWith("."))
|
|
30
|
+
continue;
|
|
31
|
+
resources.push(entry.name);
|
|
32
|
+
}
|
|
33
|
+
// Sort for consistent output
|
|
34
|
+
resources.sort();
|
|
35
|
+
// Cap at 50 files to avoid overwhelming output
|
|
36
|
+
return resources.slice(0, 50);
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
// Directory read failed, return empty
|
|
40
|
+
return [];
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
export async function createSkillTool(activatedSkillsTracker) {
|
|
44
|
+
const appConfig = await config.getConfig();
|
|
45
|
+
const skillPaths = parseSkillsPath(appConfig.skills.path);
|
|
46
|
+
const skills = await loadSkills(skillPaths);
|
|
18
47
|
const modelInvocableSkills = skills.getModelInvocable();
|
|
19
48
|
const description = "Run a skill (e.g., commit, review-pr).";
|
|
20
49
|
return {
|
|
@@ -30,35 +59,49 @@ export async function createSkillTool() {
|
|
|
30
59
|
if (abortSignal?.aborted) {
|
|
31
60
|
throw new Error("Skill execution aborted");
|
|
32
61
|
}
|
|
62
|
+
// Check for deduplication
|
|
63
|
+
if (activatedSkillsTracker.has(skillName)) {
|
|
64
|
+
return `Skill "${skillName}" is already loaded in this session. Its instructions are available in the conversation context.`;
|
|
65
|
+
}
|
|
33
66
|
// Find the skill
|
|
34
67
|
const skill = modelInvocableSkills.find((s) => s.name === skillName);
|
|
35
68
|
if (!skill) {
|
|
36
69
|
const availableSkillNames = modelInvocableSkills
|
|
37
70
|
.map((s) => s.name)
|
|
38
71
|
.join(", ");
|
|
39
|
-
|
|
40
|
-
return errorMsg;
|
|
72
|
+
return `Skill "${skillName}" not found. Available skills: ${availableSkillNames}`;
|
|
41
73
|
}
|
|
42
74
|
if (skill.disableModelInvocation) {
|
|
43
75
|
return `Skill "${skillName}" is not available for model invocation.`;
|
|
44
76
|
}
|
|
45
77
|
// Read the skill file
|
|
46
78
|
const content = await readFile(skill.filePath, "utf8");
|
|
47
|
-
let result = `# Skill Name: ${skill.name}`;
|
|
48
|
-
result += `\n**Base directory**: ${dirname(skill.filePath)}\n\n`;
|
|
49
|
-
result +=
|
|
50
|
-
"Relative paths in this skill (e.g., scripts/, reference/) are relative to this base directory.\n";
|
|
51
79
|
// Parse frontmatter and body
|
|
52
80
|
const yamlStart = content.indexOf("---");
|
|
53
81
|
const yamlEnd = content.indexOf("---", yamlStart + 3);
|
|
54
82
|
const body = yamlEnd !== -1 ? content.slice(yamlEnd + 3).trim() : content;
|
|
83
|
+
// List resources in skill directory
|
|
84
|
+
const resources = await listSkillResources(skill.baseDir);
|
|
85
|
+
// Build result
|
|
86
|
+
let result = `# Skill: ${skill.name}\n\n`;
|
|
87
|
+
result += `**Base directory**: ${skill.baseDir}\n\n`;
|
|
88
|
+
if (resources.length > 0) {
|
|
89
|
+
result += "<skill_resources>\n";
|
|
90
|
+
for (const resource of resources) {
|
|
91
|
+
result += `${resource}\n`;
|
|
92
|
+
}
|
|
93
|
+
result += "</skill_resources>\n\n";
|
|
94
|
+
result +=
|
|
95
|
+
"Relative paths in this skill are relative to the base directory.\n\n";
|
|
96
|
+
}
|
|
55
97
|
const argsArray = args ? args.split(/\s+/).filter(Boolean) : [];
|
|
56
98
|
result += replaceArgumentPlaceholders(body, argsArray);
|
|
99
|
+
// Mark as activated
|
|
100
|
+
activatedSkillsTracker.add(skillName);
|
|
57
101
|
return result;
|
|
58
102
|
}
|
|
59
103
|
catch (error) {
|
|
60
|
-
|
|
61
|
-
return errorMsg;
|
|
104
|
+
return error.message;
|
|
62
105
|
}
|
|
63
106
|
},
|
|
64
107
|
};
|
package/dist/tools/types.d.ts
CHANGED
|
@@ -1,20 +1,26 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
export declare const fileEncodingSchema: z.ZodEnum<{
|
|
3
|
+
base64: "base64";
|
|
4
|
+
base64url: "base64url";
|
|
3
5
|
utf8: "utf8";
|
|
4
6
|
ascii: "ascii";
|
|
5
7
|
"utf-8": "utf-8";
|
|
6
8
|
utf16le: "utf16le";
|
|
7
9
|
ucs2: "ucs2";
|
|
8
10
|
"ucs-2": "ucs-2";
|
|
9
|
-
base64: "base64";
|
|
10
|
-
base64url: "base64url";
|
|
11
11
|
latin1: "latin1";
|
|
12
12
|
binary: "binary";
|
|
13
13
|
hex: "hex";
|
|
14
14
|
}>;
|
|
15
|
+
export type SessionContext = {
|
|
16
|
+
sessionId: string;
|
|
17
|
+
projectDir: string;
|
|
18
|
+
agentName: string;
|
|
19
|
+
};
|
|
15
20
|
export type ToolExecutionOptions = {
|
|
16
21
|
toolCallId: string;
|
|
17
22
|
messages?: any[];
|
|
18
23
|
abortSignal?: AbortSignal;
|
|
24
|
+
sessionContext?: SessionContext;
|
|
19
25
|
};
|
|
20
26
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../source/tools/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,kBAAkB;;;;;;;;;;;;EAY7B,CAAC;AAEH,MAAM,MAAM,oBAAoB,GAAG;IACjC,UAAU,EAAE,MAAM,CAAC;IAEnB,QAAQ,CAAC,EAAE,GAAG,EAAE,CAAC;IACjB,WAAW,CAAC,EAAE,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../source/tools/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,kBAAkB;;;;;;;;;;;;EAY7B,CAAC;AAEH,MAAM,MAAM,cAAc,GAAG;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IACjC,UAAU,EAAE,MAAM,CAAC;IAEnB,QAAQ,CAAC,EAAE,GAAG,EAAE,CAAC;IACjB,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,cAAc,CAAC,EAAE,cAAc,CAAC;CACjC,CAAC"}
|
|
@@ -14,23 +14,11 @@ declare const inputSchema: z.ZodObject<{
|
|
|
14
14
|
html: "html";
|
|
15
15
|
json: "json";
|
|
16
16
|
}>>;
|
|
17
|
-
jina: z.ZodOptional<z.
|
|
18
|
-
timeout: z.ZodOptional<z.
|
|
19
|
-
headers: z.ZodOptional<z.
|
|
17
|
+
jina: z.ZodOptional<z.ZodPreprocess<z.ZodNullable<z.ZodCoercedBoolean<unknown>>>>;
|
|
18
|
+
timeout: z.ZodOptional<z.ZodPreprocess<z.ZodNullable<z.ZodCoercedNumber<unknown>>>>;
|
|
19
|
+
headers: z.ZodOptional<z.ZodPreprocess<z.ZodNullable<z.ZodCoercedBoolean<unknown>>>>;
|
|
20
20
|
}, z.core.$strip>;
|
|
21
21
|
type WebFetchInputSchema = z.infer<typeof inputSchema>;
|
|
22
|
-
/**
|
|
23
|
-
* Fetch result interface
|
|
24
|
-
*/
|
|
25
|
-
export interface FetchResult {
|
|
26
|
-
content: string;
|
|
27
|
-
contentType: string;
|
|
28
|
-
sourceUrl: string;
|
|
29
|
-
tokenCount: number;
|
|
30
|
-
success: boolean;
|
|
31
|
-
provider: "jina" | "local" | "direct";
|
|
32
|
-
headers?: Record<string, string>;
|
|
33
|
-
}
|
|
34
22
|
/**
|
|
35
23
|
* Execute web fetch
|
|
36
24
|
*/
|
|
@@ -49,9 +37,9 @@ export declare const createWebFetchTool: () => Promise<{
|
|
|
49
37
|
html: "html";
|
|
50
38
|
json: "json";
|
|
51
39
|
}>>;
|
|
52
|
-
jina: z.ZodOptional<z.
|
|
53
|
-
timeout: z.ZodOptional<z.
|
|
54
|
-
headers: z.ZodOptional<z.
|
|
40
|
+
jina: z.ZodOptional<z.ZodPreprocess<z.ZodNullable<z.ZodCoercedBoolean<unknown>>>>;
|
|
41
|
+
timeout: z.ZodOptional<z.ZodPreprocess<z.ZodNullable<z.ZodCoercedNumber<unknown>>>>;
|
|
42
|
+
headers: z.ZodOptional<z.ZodPreprocess<z.ZodNullable<z.ZodCoercedBoolean<unknown>>>>;
|
|
55
43
|
}, z.core.$strip>;
|
|
56
44
|
};
|
|
57
45
|
display({ url }: WebFetchInputSchema): string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"web-fetch.d.ts","sourceRoot":"","sources":["../../source/tools/web-fetch.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"web-fetch.d.ts","sourceRoot":"","sources":["../../source/tools/web-fetch.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAEvD,eAAO,MAAM,YAAY;;CAExB,CAAC;AASF;;GAEG;AACH,QAAA,MAAM,WAAW;;;;;;;;;;;iBAkBf,CAAC;AAEH,KAAK,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,CAAC;AA6bvD;;GAEG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,mBAAmB,EAC5B,gBAAgB,EAAE,oBAAoB,GACrC,OAAO,CAAC,MAAM,CAAC,CAwFjB;AAED;;GAEG;AACH,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;qBAQV,mBAAmB;qBAIzB,mBAAmB,oBACV,oBAAoB,GACrC,OAAO,CAAC,MAAM,CAAC;EAIrB,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG,OAAO,CAAC,UAAU,CAAC,OAAO,kBAAkB,CAAC,CAAC,CAAC"}
|
package/dist/tools/web-fetch.js
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import { writeFileSync } from "node:fs";
|
|
2
|
+
import { tmpdir } from "node:os";
|
|
3
|
+
import { join } from "node:path";
|
|
1
4
|
import { load } from "cheerio";
|
|
2
5
|
import { z } from "zod";
|
|
3
6
|
import style from "../terminal/style.js";
|
|
@@ -9,6 +12,7 @@ const DEFAULT_TIMEOUT = 30000; // 30 seconds
|
|
|
9
12
|
const MAX_REDIRECTS = 5;
|
|
10
13
|
const MAX_URL_LENGTH = 2048;
|
|
11
14
|
const JINA_API_BASE = "https://r.jina.ai";
|
|
15
|
+
const MAX_INLINE_SIZE = 50_000; // bytes; content exceeding this is written to a temp file
|
|
12
16
|
/**
|
|
13
17
|
* Input schema for the web fetch tool
|
|
14
18
|
*/
|
|
@@ -304,12 +308,29 @@ async function fetchUrl(url, options) {
|
|
|
304
308
|
const { useJina = false, timeout = DEFAULT_TIMEOUT, verbose = false, headers: includeHeaders = false, abortSignal, } = options;
|
|
305
309
|
let redirectCount = 0;
|
|
306
310
|
let currentUrl = url;
|
|
307
|
-
while (redirectCount
|
|
311
|
+
while (redirectCount < MAX_REDIRECTS) {
|
|
308
312
|
const { signal, cleanup } = createTimeoutSignal(timeout, abortSignal);
|
|
309
313
|
try {
|
|
314
|
+
// Standard browser headers to avoid 403 errors on bot-protected sites
|
|
315
|
+
const requestHeaders = {
|
|
316
|
+
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
|
|
317
|
+
// biome-ignore lint/style/useNamingConvention: HTTP header name must match specification
|
|
318
|
+
Accept: "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8",
|
|
319
|
+
"Accept-Language": "en-US,en;q=0.9",
|
|
320
|
+
"Accept-Encoding": "gzip, deflate, br",
|
|
321
|
+
// biome-ignore lint/style/useNamingConvention: HTTP header name must match specification
|
|
322
|
+
Connection: "keep-alive",
|
|
323
|
+
"Upgrade-Insecure-Requests": "1",
|
|
324
|
+
"Sec-Fetch-Dest": "document",
|
|
325
|
+
"Sec-Fetch-Mode": "navigate",
|
|
326
|
+
"Sec-Fetch-Site": "none",
|
|
327
|
+
"Sec-Fetch-User": "?1",
|
|
328
|
+
"Cache-Control": "max-age=0",
|
|
329
|
+
};
|
|
310
330
|
const response = await fetch(currentUrl, {
|
|
311
331
|
signal,
|
|
312
332
|
redirect: "manual",
|
|
333
|
+
headers: requestHeaders,
|
|
313
334
|
});
|
|
314
335
|
// Handle redirects
|
|
315
336
|
if (response.status >= 300 && response.status < 400) {
|
|
@@ -383,6 +404,7 @@ export async function executeWebFetch(options, executionOptions) {
|
|
|
383
404
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
384
405
|
throw new Error(`Web fetch failed: ${errorMessage}`);
|
|
385
406
|
}
|
|
407
|
+
let content;
|
|
386
408
|
switch (output) {
|
|
387
409
|
case "json": {
|
|
388
410
|
const jsonOutput = {
|
|
@@ -396,18 +418,32 @@ export async function executeWebFetch(options, executionOptions) {
|
|
|
396
418
|
if (headers && result.headers) {
|
|
397
419
|
jsonOutput["headers"] = result["headers"];
|
|
398
420
|
}
|
|
399
|
-
|
|
421
|
+
content = JSON.stringify(jsonOutput, null, 2);
|
|
422
|
+
break;
|
|
400
423
|
}
|
|
401
424
|
case "html":
|
|
402
|
-
|
|
425
|
+
content = result.content;
|
|
426
|
+
break;
|
|
403
427
|
case "markdown":
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
428
|
+
content = result.contentType.includes("text/html")
|
|
429
|
+
? htmlToMarkdown(result.content)
|
|
430
|
+
: result.content;
|
|
431
|
+
break;
|
|
408
432
|
default:
|
|
409
|
-
|
|
433
|
+
content = result.content;
|
|
434
|
+
break;
|
|
435
|
+
}
|
|
436
|
+
const contentSize = Buffer.byteLength(content, "utf-8");
|
|
437
|
+
if (contentSize > MAX_INLINE_SIZE) {
|
|
438
|
+
const tmpFile = join(tmpdir(), `acai-webfetch-${Date.now()}-${Math.random().toString(36).slice(2, 8)}.txt`);
|
|
439
|
+
writeFileSync(tmpFile, content, "utf-8");
|
|
440
|
+
return [
|
|
441
|
+
`The fetched content from ${url} is ${contentSize} bytes which exceeds the ${MAX_INLINE_SIZE} byte inline limit.`,
|
|
442
|
+
`The full content has been saved to: ${tmpFile}`,
|
|
443
|
+
"To use this content, read the file in parts using the Read tool or search it with the Grep tool.",
|
|
444
|
+
].join("\n");
|
|
410
445
|
}
|
|
446
|
+
return content;
|
|
411
447
|
}
|
|
412
448
|
/**
|
|
413
449
|
* Create the web fetch tool
|
|
@@ -420,7 +456,7 @@ export const createWebFetchTool = async () => {
|
|
|
420
456
|
inputSchema,
|
|
421
457
|
},
|
|
422
458
|
display({ url }) {
|
|
423
|
-
return
|
|
459
|
+
return `${style.cyan(url)}`;
|
|
424
460
|
},
|
|
425
461
|
async execute(options, executionOptions) {
|
|
426
462
|
return executeWebFetch(options, executionOptions);
|
|
@@ -8,32 +8,14 @@ export declare const WebSearchTool: {
|
|
|
8
8
|
*/
|
|
9
9
|
declare const inputSchema: z.ZodObject<{
|
|
10
10
|
query: z.ZodString;
|
|
11
|
-
numResults: z.ZodOptional<z.
|
|
12
|
-
timeout: z.ZodOptional<z.
|
|
11
|
+
numResults: z.ZodOptional<z.ZodPreprocess<z.ZodNullable<z.ZodCoercedNumber<unknown>>>>;
|
|
12
|
+
timeout: z.ZodOptional<z.ZodPreprocess<z.ZodNullable<z.ZodCoercedNumber<unknown>>>>;
|
|
13
13
|
provider: z.ZodOptional<z.ZodEnum<{
|
|
14
14
|
exa: "exa";
|
|
15
15
|
duckduckgo: "duckduckgo";
|
|
16
16
|
}>>;
|
|
17
17
|
}, z.core.$strip>;
|
|
18
18
|
type WebSearchInputSchema = z.infer<typeof inputSchema>;
|
|
19
|
-
/**
|
|
20
|
-
* Search result interface
|
|
21
|
-
*/
|
|
22
|
-
export interface SearchResult {
|
|
23
|
-
title: string;
|
|
24
|
-
url: string;
|
|
25
|
-
snippet: string;
|
|
26
|
-
publishedDate?: string;
|
|
27
|
-
}
|
|
28
|
-
/**
|
|
29
|
-
* Search response interface
|
|
30
|
-
*/
|
|
31
|
-
export interface SearchResponse {
|
|
32
|
-
results: SearchResult[];
|
|
33
|
-
provider: string;
|
|
34
|
-
query: string;
|
|
35
|
-
totalResults?: number;
|
|
36
|
-
}
|
|
37
19
|
/**
|
|
38
20
|
* Execute web search
|
|
39
21
|
*/
|
|
@@ -46,8 +28,8 @@ export declare const createWebSearchTool: () => Promise<{
|
|
|
46
28
|
description: string;
|
|
47
29
|
inputSchema: z.ZodObject<{
|
|
48
30
|
query: z.ZodString;
|
|
49
|
-
numResults: z.ZodOptional<z.
|
|
50
|
-
timeout: z.ZodOptional<z.
|
|
31
|
+
numResults: z.ZodOptional<z.ZodPreprocess<z.ZodNullable<z.ZodCoercedNumber<unknown>>>>;
|
|
32
|
+
timeout: z.ZodOptional<z.ZodPreprocess<z.ZodNullable<z.ZodCoercedNumber<unknown>>>>;
|
|
51
33
|
provider: z.ZodOptional<z.ZodEnum<{
|
|
52
34
|
exa: "exa";
|
|
53
35
|
duckduckgo: "duckduckgo";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"web-search.d.ts","sourceRoot":"","sources":["../../source/tools/web-search.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAEvD,eAAO,MAAM,aAAa;;CAEzB,CAAC;AAQF;;GAEG;AACH,QAAA,MAAM,WAAW;;;;;;;;iBAkBf,CAAC;AAEH,KAAK,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"web-search.d.ts","sourceRoot":"","sources":["../../source/tools/web-search.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAEvD,eAAO,MAAM,aAAa;;CAEzB,CAAC;AAQF;;GAEG;AACH,QAAA,MAAM,WAAW;;;;;;;;iBAkBf,CAAC;AAEH,KAAK,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,CAAC;AA+MxD;;GAEG;AACH,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,oBAAoB,EAC7B,gBAAgB,EAAE,oBAAoB,GACrC,OAAO,CAAC,MAAM,CAAC,CAwEjB;AAED;;GAEG;AACH,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;uBAQT,oBAAoB;qBAI5B,oBAAoB,oBACX,oBAAoB,GACrC,OAAO,CAAC,MAAM,CAAC;EAIrB,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG,OAAO,CAAC,UAAU,CAAC,OAAO,mBAAmB,CAAC,CAAC,CAAC"}
|
package/dist/tools/web-search.js
CHANGED
|
@@ -217,7 +217,7 @@ export const createWebSearchTool = async () => {
|
|
|
217
217
|
inputSchema,
|
|
218
218
|
},
|
|
219
219
|
display({ query }) {
|
|
220
|
-
return
|
|
220
|
+
return `${style.cyan(query)}`;
|
|
221
221
|
},
|
|
222
222
|
async execute(options, executionOptions) {
|
|
223
223
|
return executeWebSearch(options, executionOptions);
|
|
@@ -7,10 +7,11 @@ export declare class DirectoryCache {
|
|
|
7
7
|
clear(): void;
|
|
8
8
|
}
|
|
9
9
|
export declare const directoryCache: DirectoryCache;
|
|
10
|
-
|
|
10
|
+
interface DirentWithPath extends Dirent {
|
|
11
11
|
parentPath: string;
|
|
12
12
|
}
|
|
13
13
|
export declare function getDirectoryEntries(dirs: string[]): Promise<DirentWithPath[]>;
|
|
14
14
|
export declare function isPathWithinAllowedDirs(requestedPath: string, allowedDirs: string[]): Promise<boolean>;
|
|
15
15
|
export declare function extractPathPrefix(text: string, forceExtract?: boolean): string | null;
|
|
16
|
+
export {};
|
|
16
17
|
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../source/tui/autocomplete/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAKtC,qBAAa,cAAc;IACzB,OAAO,CAAC,KAAK,CAA+D;IAC5E,OAAO,CAAC,GAAG,CAAQ;IAEb,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC;IAQhD,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI;IAIzC,KAAK,IAAI,IAAI;CAGd;AAED,eAAO,MAAM,cAAc,gBAAuB,CAAC;AAGnD,
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../source/tui/autocomplete/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAKtC,qBAAa,cAAc;IACzB,OAAO,CAAC,KAAK,CAA+D;IAC5E,OAAO,CAAC,GAAG,CAAQ;IAEb,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC;IAQhD,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI;IAIzC,KAAK,IAAI,IAAI;CAGd;AAED,eAAO,MAAM,cAAc,gBAAuB,CAAC;AAGnD,UAAU,cAAe,SAAQ,MAAM;IACrC,UAAU,EAAE,MAAM,CAAC;CACpB;AAGD,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,MAAM,EAAE,GACb,OAAO,CAAC,cAAc,EAAE,CAAC,CA4B3B;AA8BD,wBAAsB,uBAAuB,CAC3C,aAAa,EAAE,MAAM,EACrB,WAAW,EAAE,MAAM,EAAE,GACpB,OAAO,CAAC,OAAO,CAAC,CAWlB;AAmCD,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,MAAM,EACZ,YAAY,UAAQ,GACnB,MAAM,GAAG,IAAI,CAuCf"}
|
|
@@ -83,6 +83,27 @@ export async function isPathWithinAllowedDirs(requestedPath, allowedDirs) {
|
|
|
83
83
|
}
|
|
84
84
|
return false;
|
|
85
85
|
}
|
|
86
|
+
function hasPathIndicator(pathPrefix) {
|
|
87
|
+
return (pathPrefix.includes("/") ||
|
|
88
|
+
pathPrefix.endsWith("/") ||
|
|
89
|
+
pathPrefix.startsWith(".") ||
|
|
90
|
+
pathPrefix.startsWith("~/"));
|
|
91
|
+
}
|
|
92
|
+
function isPartialPath(pathPrefix) {
|
|
93
|
+
return (!pathPrefix.includes("/") &&
|
|
94
|
+
!pathPrefix.includes(".") &&
|
|
95
|
+
!pathPrefix.startsWith("./") &&
|
|
96
|
+
!pathPrefix.startsWith("../") &&
|
|
97
|
+
!pathPrefix.startsWith("~/") &&
|
|
98
|
+
pathPrefix.length > 3);
|
|
99
|
+
}
|
|
100
|
+
function shouldReturnEmptyForForceExtract(pathPrefix, text) {
|
|
101
|
+
return (!pathPrefix.includes("/") &&
|
|
102
|
+
!pathPrefix.endsWith("/") &&
|
|
103
|
+
!pathPrefix.startsWith(".") &&
|
|
104
|
+
!pathPrefix.startsWith("~/") &&
|
|
105
|
+
(text === "" || text.endsWith(" ")));
|
|
106
|
+
}
|
|
86
107
|
export function extractPathPrefix(text, forceExtract = false) {
|
|
87
108
|
// Match paths - more conservative approach to avoid matching already completed paths
|
|
88
109
|
// This regex captures:
|
|
@@ -97,40 +118,21 @@ export function extractPathPrefix(text, forceExtract = false) {
|
|
|
97
118
|
const pathPrefix = matches[1] || "";
|
|
98
119
|
// For forced extraction (Tab key), always return something
|
|
99
120
|
if (forceExtract) {
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
if (!pathPrefix.includes("/") &&
|
|
103
|
-
!pathPrefix.endsWith("/") &&
|
|
104
|
-
!pathPrefix.startsWith(".") &&
|
|
105
|
-
!pathPrefix.startsWith("~/")) {
|
|
106
|
-
// Only return empty string if we're at the beginning or after space
|
|
107
|
-
// This prevents completing "source" as empty string
|
|
108
|
-
if (text === "" || text.endsWith(" ")) {
|
|
109
|
-
return "";
|
|
110
|
-
}
|
|
121
|
+
if (shouldReturnEmptyForForceExtract(pathPrefix, text)) {
|
|
122
|
+
return "";
|
|
111
123
|
}
|
|
112
124
|
return pathPrefix;
|
|
113
125
|
}
|
|
114
126
|
// For natural triggers, be more conservative:
|
|
115
127
|
// Only trigger if we have a clear path indicator
|
|
116
|
-
|
|
117
|
-
pathPrefix.endsWith("/") ||
|
|
118
|
-
pathPrefix.startsWith(".") ||
|
|
119
|
-
pathPrefix.startsWith("~/");
|
|
120
|
-
if (!hasPathIndicator) {
|
|
128
|
+
if (!hasPathIndicator(pathPrefix)) {
|
|
121
129
|
return null;
|
|
122
130
|
}
|
|
123
131
|
// Additional check: don't trigger if the path looks like it's already completed
|
|
124
132
|
// (i.e., doesn't end with a partial filename)
|
|
125
133
|
// Only apply this check for paths that don't have clear path indicators
|
|
126
134
|
// and look like single directory names (no path separators)
|
|
127
|
-
if (
|
|
128
|
-
!pathPrefix.includes(".") &&
|
|
129
|
-
!pathPrefix.startsWith("./") &&
|
|
130
|
-
!pathPrefix.startsWith("../") &&
|
|
131
|
-
!pathPrefix.startsWith("~/") &&
|
|
132
|
-
pathPrefix.length > 3) {
|
|
133
|
-
// This might be a completed directory name, not a partial path
|
|
135
|
+
if (isPartialPath(pathPrefix)) {
|
|
134
136
|
return null;
|
|
135
137
|
}
|
|
136
138
|
return pathPrefix;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { AutocompleteProvider } from "../autocomplete.ts";
|
|
2
2
|
import type { Component } from "../tui.ts";
|
|
3
3
|
import type { SelectListTheme } from "./select-list.ts";
|
|
4
|
-
|
|
4
|
+
interface EditorTheme {
|
|
5
5
|
borderColor: (str: string) => string;
|
|
6
6
|
selectList?: SelectListTheme;
|
|
7
7
|
}
|
|
@@ -121,4 +121,5 @@ export declare class Editor implements Component {
|
|
|
121
121
|
private isModifiedEnter;
|
|
122
122
|
getCursorPosition(): [number, number] | null;
|
|
123
123
|
}
|
|
124
|
+
export {};
|
|
124
125
|
//# sourceMappingURL=editor.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"editor.d.ts","sourceRoot":"","sources":["../../../source/tui/components/editor.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC/D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAuK3C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAExD,
|
|
1
|
+
{"version":3,"file":"editor.d.ts","sourceRoot":"","sources":["../../../source/tui/components/editor.ts"],"names":[],"mappings":"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"}
|
|
@@ -8,7 +8,6 @@ type State = {
|
|
|
8
8
|
currentContextWindow: number;
|
|
9
9
|
contextWindow: number;
|
|
10
10
|
agentState?: AgentState;
|
|
11
|
-
currentMode?: string;
|
|
12
11
|
};
|
|
13
12
|
export declare class FooterComponent implements Component {
|
|
14
13
|
private modelManager;
|
|
@@ -16,7 +15,6 @@ export declare class FooterComponent implements Component {
|
|
|
16
15
|
private state;
|
|
17
16
|
private progressBar;
|
|
18
17
|
private agentState?;
|
|
19
|
-
private currentMode;
|
|
20
18
|
constructor(modelManager: ModelManager, tokenTracker: TokenTracker | undefined, state: State);
|
|
21
19
|
setState(state: State): void;
|
|
22
20
|
resetState(): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"footer.d.ts","sourceRoot":"","sources":["../../../source/tui/components/footer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AAGtE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAE5D,OAAO,EAAE,KAAK,SAAS,EAAgB,MAAM,WAAW,CAAC;AAGzD,KAAK,KAAK,GAAG;IACX,aAAa,EAAE,iBAAiB,CAAC;IACjC,oBAAoB,EAAE,MAAM,CAAC;IAC7B,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"footer.d.ts","sourceRoot":"","sources":["../../../source/tui/components/footer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AAGtE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAE5D,OAAO,EAAE,KAAK,SAAS,EAAgB,MAAM,WAAW,CAAC;AAGzD,KAAK,KAAK,GAAG;IACX,aAAa,EAAE,iBAAiB,CAAC;IACjC,oBAAoB,EAAE,MAAM,CAAC;IAC7B,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,UAAU,CAAC;CACzB,CAAC;AA2CF,qBAAa,eAAgB,YAAW,SAAS;IAC/C,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,YAAY,CAAC,CAAe;IACpC,OAAO,CAAC,KAAK,CAAQ;IACrB,OAAO,CAAC,WAAW,CAAuB;IAC1C,OAAO,CAAC,UAAU,CAAC,CAAa;gBAE9B,YAAY,EAAE,YAAY,EAC1B,YAAY,EAAE,YAAY,GAAG,SAAS,EACtC,KAAK,EAAE,KAAK;IAad,QAAQ,CAAC,KAAK,EAAE,KAAK;IASrB,UAAU;IAIV,gBAAgB,IAAI,iBAAiB;IAIrC,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE;CAkEhC"}
|
|
@@ -41,7 +41,6 @@ export class FooterComponent {
|
|
|
41
41
|
state;
|
|
42
42
|
progressBar;
|
|
43
43
|
agentState;
|
|
44
|
-
currentMode = "Normal";
|
|
45
44
|
constructor(modelManager, tokenTracker, state) {
|
|
46
45
|
this.modelManager = modelManager;
|
|
47
46
|
this.tokenTracker = tokenTracker;
|
|
@@ -53,9 +52,6 @@ export class FooterComponent {
|
|
|
53
52
|
if (state.agentState) {
|
|
54
53
|
this.agentState = state.agentState;
|
|
55
54
|
}
|
|
56
|
-
if (state.currentMode !== undefined) {
|
|
57
|
-
this.currentMode = state.currentMode;
|
|
58
|
-
}
|
|
59
55
|
this.state = state;
|
|
60
56
|
this.progressBar.setCurrent(state.currentContextWindow);
|
|
61
57
|
this.progressBar.setTotal(state.contextWindow);
|
|
@@ -72,20 +68,8 @@ export class FooterComponent {
|
|
|
72
68
|
const [pathLine, gitLine] = formatProjectStatus(this.state.projectStatus);
|
|
73
69
|
const padding = Math.max(0, width - visibleWidth(pathLine) - modelInfo.length);
|
|
74
70
|
results.push(pathLine + " ".repeat(padding) + style.dim(modelInfo));
|
|
75
|
-
const modeDisplay = this.currentMode !== "Normal"
|
|
76
|
-
? style.magenta(`[${this.currentMode}]`)
|
|
77
|
-
: "";
|
|
78
71
|
if (gitLine) {
|
|
79
|
-
|
|
80
|
-
const gitPadding = Math.max(0, width - visibleWidth(gitLine) - visibleWidth(modeDisplay));
|
|
81
|
-
results.push(`${gitLine}${" ".repeat(gitPadding)}${modeDisplay}`);
|
|
82
|
-
}
|
|
83
|
-
else {
|
|
84
|
-
results.push(gitLine);
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
else if (modeDisplay) {
|
|
88
|
-
results.push(modeDisplay);
|
|
72
|
+
results.push(gitLine);
|
|
89
73
|
}
|
|
90
74
|
// Line 3: Total session usage from token tracker (accumulated across all turns)
|
|
91
75
|
if (this.tokenTracker) {
|