@travisennis/acai 0.0.11 → 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 +2 -3
- 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/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 +11 -1
- package/dist/models/opencode-go-provider.d.ts.map +1 -1
- package/dist/models/opencode-go-provider.js +136 -0
- package/dist/models/opencode-zen-provider.d.ts +3 -3
- package/dist/models/opencode-zen-provider.d.ts.map +1 -1
- package/dist/models/opencode-zen-provider.js +26 -32
- package/dist/models/openrouter-provider.d.ts +4 -15
- package/dist/models/openrouter-provider.d.ts.map +1 -1
- package/dist/models/openrouter-provider.js +26 -169
- package/dist/models/providers.d.ts +1 -1
- package/dist/models/providers.d.ts.map +1 -1
- 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/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 +5 -52
- 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 +1 -1
- package/dist/skills/index.d.ts.map +1 -1
- package/dist/skills/index.js +7 -1
- package/dist/tools/bash.d.ts +4 -4
- package/dist/tools/bash.d.ts.map +1 -1
- package/dist/tools/bash.js +17 -6
- 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 +2 -0
- package/dist/tools/dynamic-tool-loader.d.ts +11 -2
- 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/glob.d.ts +16 -16
- package/dist/tools/glob.d.ts.map +1 -1
- package/dist/tools/glob.js +9 -1
- package/dist/tools/grep.d.ts +14 -14
- package/dist/tools/grep.d.ts.map +1 -1
- package/dist/tools/grep.js +7 -0
- package/dist/tools/index.d.ts +42 -36
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +16 -1
- package/dist/tools/ls.d.ts +2 -2
- package/dist/tools/ls.d.ts.map +1 -1
- package/dist/tools/ls.js +1 -0
- package/dist/tools/read-file.d.ts +8 -8
- package/dist/tools/save-file.d.ts +4 -4
- 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 -6
- package/dist/tools/web-fetch.d.ts.map +1 -1
- package/dist/tools/web-fetch.js +27 -8
- package/dist/tools/web-search.d.ts +4 -4
- package/dist/tools/web-search.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/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 +27 -25
- package/dist/modes/manager.d.ts +0 -24
- 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 -142
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#
|
|
1
|
+
# acai
|
|
2
2
|
|
|
3
3
|

|
|
4
4
|

|
|
@@ -87,7 +87,6 @@ Reference files directly with `@filename`, directories with `@dirname`, or run s
|
|
|
87
87
|
│ ├── execution/ # Command execution utilities
|
|
88
88
|
│ ├── middleware/ # AI request/response middleware
|
|
89
89
|
│ ├── models/ # AI model providers and management
|
|
90
|
-
│ ├── modes/ # Agent mode management
|
|
91
90
|
│ ├── prompts/ # Prompt generation and management
|
|
92
91
|
│ ├── repl/ # REPL utilities
|
|
93
92
|
│ ├── sessions/ # Session persistence and management
|
|
@@ -108,7 +107,7 @@ Reference files directly with `@filename`, directories with `@dirname`, or run s
|
|
|
108
107
|
- [Usage Guide](docs/usage.md) - Commands, keyboard shortcuts, piped input, and prompt syntax
|
|
109
108
|
- [Configuration](docs/configuration.md) - Environment variables, project and global settings
|
|
110
109
|
- [Skills System](docs/skills.md) - Creating and using specialized instruction files
|
|
111
|
-
- [Dynamic Tools](docs/dynamic-tools.md) - Creating custom tools to extend acai
|
|
110
|
+
- [Dynamic Tools](docs/dynamic-tools.md) - Creating custom tools to extend acai (supports bash, python, and other languages; Amp-compatible text schema format; `/tools make` scaffolding command)
|
|
112
111
|
- [Architecture](ARCHITECTURE.md) - Internal architecture and flow diagrams
|
|
113
112
|
- [Contributing](CONTRIBUTING.md) - Development setup, scripts, and code style
|
|
114
113
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../source/commands/init-project/utils.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,qBAAqB,sCAAsC,CAAC;AAEzE,UAAU,oBAAoB;IAC5B,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,wBAAgB,sBAAsB,CACpC,UAAU,EAAE,MAAM,GACjB,oBAAoB,
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../source/commands/init-project/utils.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,qBAAqB,sCAAsC,CAAC;AAEzE,UAAU,oBAAoB;IAC5B,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,wBAAgB,sBAAsB,CACpC,UAAU,EAAE,MAAM,GACjB,oBAAoB,CAwBtB;AAED,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,oBAAoB,CAazE;AAED,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAE3D"}
|
|
@@ -12,17 +12,6 @@ export function ensureProjectDirectory(projectDir) {
|
|
|
12
12
|
else {
|
|
13
13
|
existing.push(".acai/");
|
|
14
14
|
}
|
|
15
|
-
const subdirs = ["rules"];
|
|
16
|
-
for (const subdir of subdirs) {
|
|
17
|
-
const dirPath = path.join(projectDir, subdir);
|
|
18
|
-
if (!existsSync(dirPath)) {
|
|
19
|
-
mkdirSync(dirPath, { recursive: true });
|
|
20
|
-
created.push(`.acai/${subdir}/`);
|
|
21
|
-
}
|
|
22
|
-
else {
|
|
23
|
-
existing.push(`.acai/${subdir}/`);
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
15
|
const agentsSkillsDir = path.join(path.dirname(projectDir), ".agents", "skills");
|
|
27
16
|
if (!existsSync(agentsSkillsDir)) {
|
|
28
17
|
mkdirSync(agentsSkillsDir, { recursive: true });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../source/commands/manager.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../source/commands/manager.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAEV,SAAS,EACT,MAAM,EACN,YAAY,EACZ,GAAG,EACJ,MAAM,iBAAiB,CAAC;AA4BzB,OAAO,KAAK,EAAE,cAAc,EAAe,MAAM,YAAY,CAAC;AAE9D,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAA2B;IAC3C,OAAO,CAAC,aAAa,CAAmB;IACxC,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,cAAc,CAAiB;IACvC,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,aAAa,CAAW;IAChC,OAAO,CAAC,SAAS,CAAmB;IACpC,OAAO,CAAC,WAAW,CAAU;gBAEjB,EACV,aAAa,EACb,YAAY,EACZ,cAAc,EACd,YAAY,EACZ,MAAM,EACN,YAAY,EACZ,aAAa,EACb,SAAS,GACV,EAAE,cAAc;IAaX,mBAAmB;YA2DX,qBAAqB;IA4EnC,OAAO,CAAC,iBAAiB;IAQnB,cAAc,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;IAuB/C,WAAW;IAKL,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAKlD,MAAM,CACV,EAAE,SAAS,EAAE,EAAE;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,EACpC,OAAO,EAAE;QACP,GAAG,EAAE,GAAG,CAAC;QACT,SAAS,EAAE,SAAS,CAAC;QACrB,cAAc,EAAE,SAAS,CAAC;QAC1B,MAAM,EAAE,MAAM,CAAC;KAChB;;;CAsBJ"}
|
package/dist/commands/manager.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { readFile } from "node:fs/promises";
|
|
2
|
+
import { parseSkillsPath } from "../config/index.js";
|
|
2
3
|
import { processPrompt } from "../prompts/mentions.js";
|
|
3
4
|
import { loadSkills } from "../skills/index.js";
|
|
4
5
|
import style from "../terminal/style.js";
|
|
@@ -27,6 +28,7 @@ import { reviewCommand } from "./review/index.js";
|
|
|
27
28
|
import { sessionCommand } from "./session/index.js";
|
|
28
29
|
import { shareCommand } from "./share/index.js";
|
|
29
30
|
import { shellCommand } from "./shell/index.js";
|
|
31
|
+
import { toolsCommand } from "./tools/index.js";
|
|
30
32
|
export class CommandManager {
|
|
31
33
|
commands;
|
|
32
34
|
promptManager;
|
|
@@ -87,6 +89,7 @@ export class CommandManager {
|
|
|
87
89
|
resourcesCommand(options),
|
|
88
90
|
shareCommand(options),
|
|
89
91
|
shellCommand(options),
|
|
92
|
+
toolsCommand(options),
|
|
90
93
|
];
|
|
91
94
|
// Add help command with access to all commands
|
|
92
95
|
const helpCmd = helpCommand(options, this.commands);
|
|
@@ -103,7 +106,9 @@ export class CommandManager {
|
|
|
103
106
|
this.initialized = true;
|
|
104
107
|
}
|
|
105
108
|
async registerSkillCommands(options) {
|
|
106
|
-
const
|
|
109
|
+
const appConfig = await this.config.getConfig();
|
|
110
|
+
const skillPaths = parseSkillsPath(appConfig.skills.path);
|
|
111
|
+
const skills = await loadSkills(skillPaths);
|
|
107
112
|
const userInvocableSkills = skills.getUserInvocable();
|
|
108
113
|
for (const skill of userInvocableSkills) {
|
|
109
114
|
const commandName = `/${skill.name}`;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../source/commands/resources/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../source/commands/resources/index.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAkC/D,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,cAAc,GAAG,WAAW,CAqErE"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { parseSkillsPath } from "../../config/index.js";
|
|
1
2
|
import { loadSkills } from "../../skills/index.js";
|
|
2
3
|
import style from "../../terminal/style.js";
|
|
3
4
|
import { Modal, Container as ModalContainer, ModalText, } from "../../tui/index.js";
|
|
@@ -30,7 +31,9 @@ export function resourcesCommand(options) {
|
|
|
30
31
|
getSubCommands: async () => [],
|
|
31
32
|
async handle(_args, { tui, editor }) {
|
|
32
33
|
try {
|
|
33
|
-
const
|
|
34
|
+
const appConfig = await options.config.getConfig();
|
|
35
|
+
const skillPaths = parseSkillsPath(appConfig.skills.path);
|
|
36
|
+
const skills = await loadSkills(skillPaths);
|
|
34
37
|
const allSkills = skills.getAll();
|
|
35
38
|
const agentsFiles = await options.config.readAgentsFiles();
|
|
36
39
|
const projectSkills = allSkills.filter((s) => s.source === "project");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../source/commands/session/index.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../source/commands/session/index.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAyH/D,wBAAgB,cAAc,CAAC,EAC7B,MAAM,EACN,YAAY,EACZ,YAAY,EACZ,cAAc,EACd,SAAS,EACT,YAAY,GACb,EAAE,cAAc,GAAG,WAAW,CAiK9B"}
|
|
@@ -44,6 +44,11 @@ function buildContextTable(breakdown, window) {
|
|
|
44
44
|
formatNumber(breakdown.systemPromptBreakdown.userAgentsMd),
|
|
45
45
|
formatPercentage(breakdown.systemPromptBreakdown.userAgentsMd, window),
|
|
46
46
|
],
|
|
47
|
+
[
|
|
48
|
+
" ~/.config/AGENTS.md",
|
|
49
|
+
formatNumber(breakdown.systemPromptBreakdown.configAgentsMd),
|
|
50
|
+
formatPercentage(breakdown.systemPromptBreakdown.configAgentsMd, window),
|
|
51
|
+
],
|
|
47
52
|
[
|
|
48
53
|
" ./AGENTS.md",
|
|
49
54
|
formatNumber(breakdown.systemPromptBreakdown.cwdAgentsMd),
|
|
@@ -126,6 +131,7 @@ export function sessionCommand({ config, tokenCounter, modelManager, sessionMana
|
|
|
126
131
|
const systemPromptBreakdown = {
|
|
127
132
|
core: tokenCounter.count(sysResult.components.core),
|
|
128
133
|
userAgentsMd: tokenCounter.count(sysResult.components.userAgentsMd),
|
|
134
|
+
configAgentsMd: tokenCounter.count(sysResult.components.configAgentsMd),
|
|
129
135
|
cwdAgentsMd: tokenCounter.count(sysResult.components.cwdAgentsMd),
|
|
130
136
|
learnedRules: tokenCounter.count(sysResult.components.learnedRules),
|
|
131
137
|
skills: tokenCounter.count(sysResult.components.skills),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../source/commands/session/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AAEvC,MAAM,MAAM,SAAS,GAAG;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,qBAAqB,EAAE;QACrB,IAAI,EAAE,MAAM,CAAC;QACb,YAAY,EAAE,MAAM,CAAC;QACrB,WAAW,EAAE,MAAM,CAAC;QACpB,YAAY,EAAE,MAAM,CAAC;QACrB,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,YAAY,EAAE,EACxB,OAAO,EAAE;IAAE,KAAK,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,CAAA;CAAE,GACxC,MAAM,CAOR"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../source/commands/session/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AAEvC,MAAM,MAAM,SAAS,GAAG;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,qBAAqB,EAAE;QACrB,IAAI,EAAE,MAAM,CAAC;QACb,YAAY,EAAE,MAAM,CAAC;QACrB,cAAc,EAAE,MAAM,CAAC;QACvB,WAAW,EAAE,MAAM,CAAC;QACpB,YAAY,EAAE,MAAM,CAAC;QACrB,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,YAAY,EAAE,EACxB,OAAO,EAAE;IAAE,KAAK,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,CAAA;CAAE,GACxC,MAAM,CAOR"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../source/commands/tools/index.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAa/D,wBAAgB,YAAY,CAAC,OAAO,EAAE,cAAc,GAAG,WAAW,CA6CjE"}
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import style from "../../terminal/style.js";
|
|
4
|
+
import { Text } from "../../tui/index.js";
|
|
5
|
+
import { bashTemplate, nodeTemplate, textCompanionTemplate, textSchemaTemplate, zshTemplate, } from "./templates.js";
|
|
6
|
+
const TOOL_NAME_REGEX = /^[a-zA-Z_][a-zA-Z0-9_-]*$/;
|
|
7
|
+
export function toolsCommand(options) {
|
|
8
|
+
return {
|
|
9
|
+
command: "/tools",
|
|
10
|
+
description: "Manage dynamic tools (make, list)",
|
|
11
|
+
aliases: [],
|
|
12
|
+
getSubCommands: async () => ["make", "list"],
|
|
13
|
+
async handle(args, { tui, container, editor, }) {
|
|
14
|
+
const subCommand = args[0];
|
|
15
|
+
if (subCommand === "make") {
|
|
16
|
+
return handleToolMake(args.slice(1), options, container, editor, tui);
|
|
17
|
+
}
|
|
18
|
+
if (subCommand === "list") {
|
|
19
|
+
return handleToolList(options, container, editor, tui);
|
|
20
|
+
}
|
|
21
|
+
// Default: show help
|
|
22
|
+
container.addChild(new Text(style.dim("Usage: /tools make <name> [--bash|--zsh|--node|--text] [--description <desc>] [--dir <path>]"), 0, 1));
|
|
23
|
+
container.addChild(new Text(style.dim(" /tools list"), 0, 1));
|
|
24
|
+
return "continue";
|
|
25
|
+
},
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
function writeToolFile(filePath, content, makeExecutable) {
|
|
29
|
+
const files = [];
|
|
30
|
+
fs.writeFileSync(filePath, content, "utf8");
|
|
31
|
+
if (makeExecutable) {
|
|
32
|
+
fs.chmodSync(filePath, 0o755);
|
|
33
|
+
}
|
|
34
|
+
files.push(filePath);
|
|
35
|
+
return files;
|
|
36
|
+
}
|
|
37
|
+
function createToolFiles(toolName, description, toolType, outputDir) {
|
|
38
|
+
const files = [];
|
|
39
|
+
const typeConfig = {
|
|
40
|
+
node: {
|
|
41
|
+
ext: ".mjs",
|
|
42
|
+
template: () => nodeTemplate(toolName, description),
|
|
43
|
+
executable: true,
|
|
44
|
+
},
|
|
45
|
+
bash: {
|
|
46
|
+
ext: ".sh",
|
|
47
|
+
template: () => bashTemplate(toolName, description),
|
|
48
|
+
executable: true,
|
|
49
|
+
},
|
|
50
|
+
zsh: {
|
|
51
|
+
ext: ".zsh",
|
|
52
|
+
template: () => zshTemplate(toolName, description),
|
|
53
|
+
executable: true,
|
|
54
|
+
},
|
|
55
|
+
text: { ext: ".sh", template: () => "", executable: true }, // handled separately
|
|
56
|
+
};
|
|
57
|
+
if (toolType === "text") {
|
|
58
|
+
const toolFilePath = path.join(outputDir, `${toolName}.tool`);
|
|
59
|
+
const companionFilePath = path.join(outputDir, `${toolName}.sh`);
|
|
60
|
+
if (fs.existsSync(toolFilePath))
|
|
61
|
+
return toolFilePath;
|
|
62
|
+
if (fs.existsSync(companionFilePath))
|
|
63
|
+
return companionFilePath;
|
|
64
|
+
files.push(...writeToolFile(toolFilePath, textSchemaTemplate(toolName, description), false));
|
|
65
|
+
files.push(...writeToolFile(companionFilePath, textCompanionTemplate(toolName), true));
|
|
66
|
+
return files;
|
|
67
|
+
}
|
|
68
|
+
const config = typeConfig[toolType];
|
|
69
|
+
const filePath = path.join(outputDir, `${toolName}${config.ext}`);
|
|
70
|
+
if (fs.existsSync(filePath))
|
|
71
|
+
return filePath;
|
|
72
|
+
files.push(...writeToolFile(filePath, config.template(), config.executable));
|
|
73
|
+
return files;
|
|
74
|
+
}
|
|
75
|
+
function handleToolMake(args, options, container, editor, tui) {
|
|
76
|
+
// Parse arguments
|
|
77
|
+
let toolName = "";
|
|
78
|
+
let toolType = "bash";
|
|
79
|
+
let description = "";
|
|
80
|
+
let customDir = "";
|
|
81
|
+
for (let i = 0; i < args.length; i++) {
|
|
82
|
+
const arg = args[i];
|
|
83
|
+
if (arg === "--bash") {
|
|
84
|
+
toolType = "bash";
|
|
85
|
+
}
|
|
86
|
+
else if (arg === "--zsh") {
|
|
87
|
+
toolType = "zsh";
|
|
88
|
+
}
|
|
89
|
+
else if (arg === "--node") {
|
|
90
|
+
toolType = "node";
|
|
91
|
+
}
|
|
92
|
+
else if (arg === "--text") {
|
|
93
|
+
toolType = "text";
|
|
94
|
+
}
|
|
95
|
+
else if (arg === "--description" || arg === "-d") {
|
|
96
|
+
description = args[++i] || "";
|
|
97
|
+
}
|
|
98
|
+
else if (arg === "--dir") {
|
|
99
|
+
customDir = args[++i] || "";
|
|
100
|
+
}
|
|
101
|
+
else if (!arg.startsWith("-")) {
|
|
102
|
+
toolName = arg;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
if (!toolName) {
|
|
106
|
+
container.addChild(new Text(style.red("Error: Tool name is required"), 0, 1));
|
|
107
|
+
container.addChild(new Text(style.dim("Usage: /tools make <name> [--bash|--zsh|--node|--text] [--description <desc>] [--dir <path>]"), 0, 1));
|
|
108
|
+
tui.requestRender();
|
|
109
|
+
editor.setText("");
|
|
110
|
+
return "continue";
|
|
111
|
+
}
|
|
112
|
+
if (!TOOL_NAME_REGEX.test(toolName)) {
|
|
113
|
+
container.addChild(new Text(style.red(`Error: Tool name must match ${TOOL_NAME_REGEX.source}`), 0, 1));
|
|
114
|
+
tui.requestRender();
|
|
115
|
+
editor.setText("");
|
|
116
|
+
return "continue";
|
|
117
|
+
}
|
|
118
|
+
if (!description) {
|
|
119
|
+
description = `Dynamic tool: ${toolName}`;
|
|
120
|
+
}
|
|
121
|
+
// Determine output directory
|
|
122
|
+
const outputDir = customDir || path.join(options.workspace.primaryDir, ".acai", "tools");
|
|
123
|
+
// Create directory if it doesn't exist
|
|
124
|
+
if (!fs.existsSync(outputDir)) {
|
|
125
|
+
fs.mkdirSync(outputDir, { recursive: true });
|
|
126
|
+
}
|
|
127
|
+
try {
|
|
128
|
+
const result = createToolFiles(toolName, description, toolType, outputDir);
|
|
129
|
+
if (typeof result === "string") {
|
|
130
|
+
// A file already exists
|
|
131
|
+
container.addChild(new Text(style.red(`Error: File already exists: ${result}`), 0, 1));
|
|
132
|
+
tui.requestRender();
|
|
133
|
+
editor.setText("");
|
|
134
|
+
return "continue";
|
|
135
|
+
}
|
|
136
|
+
container.addChild(new Text(style.green(`Created tool: ${toolName}`), 0, 1));
|
|
137
|
+
for (const filePath of result) {
|
|
138
|
+
container.addChild(new Text(style.dim(` ${filePath}`), 0, 1));
|
|
139
|
+
}
|
|
140
|
+
container.addChild(new Text(style.dim("Restart acai or reload tools to use the new tool."), 0, 1));
|
|
141
|
+
}
|
|
142
|
+
catch (e) {
|
|
143
|
+
container.addChild(new Text(style.red(`Error creating tool: ${e.message}`), 0, 1));
|
|
144
|
+
}
|
|
145
|
+
tui.requestRender();
|
|
146
|
+
editor.setText("");
|
|
147
|
+
return "continue";
|
|
148
|
+
}
|
|
149
|
+
async function handleToolList(options, container, editor, tui) {
|
|
150
|
+
const projectDir = path.join(options.workspace.primaryDir, ".acai", "tools");
|
|
151
|
+
const userDir = path.join(process.env["HOME"] || process.env["USERPROFILE"] || "", ".acai", "tools");
|
|
152
|
+
const dirs = [
|
|
153
|
+
{ label: "User tools", dirPath: userDir },
|
|
154
|
+
{ label: "Project tools", dirPath: projectDir },
|
|
155
|
+
];
|
|
156
|
+
let foundAny = false;
|
|
157
|
+
for (const dir of dirs) {
|
|
158
|
+
if (!fs.existsSync(dir.dirPath)) {
|
|
159
|
+
container.addChild(new Text(style.dim(`${dir.label}: directory not found (${dir.dirPath})`), 0, 1));
|
|
160
|
+
continue;
|
|
161
|
+
}
|
|
162
|
+
const files = fs.readdirSync(dir.dirPath);
|
|
163
|
+
const toolFiles = files.filter((f) => f.endsWith(".js") ||
|
|
164
|
+
f.endsWith(".mjs") ||
|
|
165
|
+
f.endsWith(".cjs") ||
|
|
166
|
+
f.endsWith(".sh") ||
|
|
167
|
+
f.endsWith(".bash") ||
|
|
168
|
+
f.endsWith(".zsh") ||
|
|
169
|
+
f.endsWith(".py") ||
|
|
170
|
+
f.endsWith(".rb") ||
|
|
171
|
+
f.endsWith(".tool") ||
|
|
172
|
+
(!path.extname(f) &&
|
|
173
|
+
fs.statSync(path.join(dir.dirPath, f)).mode & 0o111));
|
|
174
|
+
if (toolFiles.length === 0) {
|
|
175
|
+
container.addChild(new Text(style.dim(`${dir.label}: no tools found`), 0, 1));
|
|
176
|
+
continue;
|
|
177
|
+
}
|
|
178
|
+
foundAny = true;
|
|
179
|
+
container.addChild(new Text(style.bold(dir.label), 0, 1));
|
|
180
|
+
for (const file of toolFiles) {
|
|
181
|
+
container.addChild(new Text(style.dim(` ${file}`), 0, 1));
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
if (!foundAny) {
|
|
185
|
+
container.addChild(new Text(style.dim("No dynamic tools found."), 0, 1));
|
|
186
|
+
}
|
|
187
|
+
tui.requestRender();
|
|
188
|
+
editor.setText("");
|
|
189
|
+
return "continue";
|
|
190
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export declare function nodeTemplate(name: string, description: string): string;
|
|
2
|
+
export declare function bashTemplate(name: string, description: string): string;
|
|
3
|
+
export declare function zshTemplate(name: string, description: string): string;
|
|
4
|
+
export declare function textSchemaTemplate(name: string, description: string): string;
|
|
5
|
+
export declare function textCompanionTemplate(name: string): string;
|
|
6
|
+
//# sourceMappingURL=templates.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"templates.d.ts","sourceRoot":"","sources":["../../../source/commands/tools/templates.ts"],"names":[],"mappings":"AAAA,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CA2BtE;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAuBtE;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAuBrE;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAI5E;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAe1D"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
export function nodeTemplate(name, description) {
|
|
2
|
+
return `#!/usr/bin/env node
|
|
3
|
+
|
|
4
|
+
const TOOL_ACTION = process.env.TOOL_ACTION;
|
|
5
|
+
|
|
6
|
+
if (TOOL_ACTION === 'describe') {
|
|
7
|
+
console.log(JSON.stringify({
|
|
8
|
+
name: '${name}',
|
|
9
|
+
description: '${description}',
|
|
10
|
+
parameters: [],
|
|
11
|
+
needsApproval: false,
|
|
12
|
+
}, null, 2));
|
|
13
|
+
process.exit(0);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
if (TOOL_ACTION === 'execute') {
|
|
17
|
+
let data = '';
|
|
18
|
+
process.stdin.setEncoding('utf8');
|
|
19
|
+
process.stdin.on('data', (chunk) => { data += chunk; });
|
|
20
|
+
process.stdin.on('end', () => {
|
|
21
|
+
const params = JSON.parse(data);
|
|
22
|
+
// Your tool logic here
|
|
23
|
+
console.log('Hello from ${name}');
|
|
24
|
+
process.exit(0);
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
`;
|
|
28
|
+
}
|
|
29
|
+
export function bashTemplate(name, description) {
|
|
30
|
+
return `#!/bin/bash
|
|
31
|
+
|
|
32
|
+
action="\${TOOL_ACTION}"
|
|
33
|
+
|
|
34
|
+
if [ "$action" = "describe" ]; then
|
|
35
|
+
cat << 'EOF'
|
|
36
|
+
name: ${name}
|
|
37
|
+
description: ${description}
|
|
38
|
+
EOF
|
|
39
|
+
exit 0
|
|
40
|
+
fi
|
|
41
|
+
|
|
42
|
+
if [ "$action" = "execute" ]; then
|
|
43
|
+
# Read key-value params from stdin
|
|
44
|
+
while IFS='=' read -r key value; do
|
|
45
|
+
declare "$key"="$value"
|
|
46
|
+
done
|
|
47
|
+
# Your tool logic here
|
|
48
|
+
echo "Hello from ${name}"
|
|
49
|
+
exit 0
|
|
50
|
+
fi
|
|
51
|
+
`;
|
|
52
|
+
}
|
|
53
|
+
export function zshTemplate(name, description) {
|
|
54
|
+
return `#!/bin/zsh
|
|
55
|
+
|
|
56
|
+
action="\${TOOL_ACTION}"
|
|
57
|
+
|
|
58
|
+
if [ "$action" = "describe" ]; then
|
|
59
|
+
cat << 'EOF'
|
|
60
|
+
name: ${name}
|
|
61
|
+
description: ${description}
|
|
62
|
+
EOF
|
|
63
|
+
exit 0
|
|
64
|
+
fi
|
|
65
|
+
|
|
66
|
+
if [ "$action" = "execute" ]; then
|
|
67
|
+
# Read key-value params from stdin
|
|
68
|
+
while IFS='=' read -r key value; do
|
|
69
|
+
declare "$key"="$value"
|
|
70
|
+
done
|
|
71
|
+
# Your tool logic here
|
|
72
|
+
echo "Hello from ${name}"
|
|
73
|
+
exit 0
|
|
74
|
+
fi
|
|
75
|
+
`;
|
|
76
|
+
}
|
|
77
|
+
export function textSchemaTemplate(name, description) {
|
|
78
|
+
return `name: ${name}
|
|
79
|
+
description: ${description}
|
|
80
|
+
`;
|
|
81
|
+
}
|
|
82
|
+
export function textCompanionTemplate(name) {
|
|
83
|
+
return `#!/bin/bash
|
|
84
|
+
# Companion script for ${name}.tool
|
|
85
|
+
# Modify this script to implement your tool logic
|
|
86
|
+
|
|
87
|
+
action="\${TOOL_ACTION}"
|
|
88
|
+
|
|
89
|
+
if [ "$action" = "execute" ]; then
|
|
90
|
+
while IFS='=' read -r key value; do
|
|
91
|
+
declare "$key"="$value"
|
|
92
|
+
done
|
|
93
|
+
echo "Hello from ${name}"
|
|
94
|
+
exit 0
|
|
95
|
+
fi
|
|
96
|
+
`;
|
|
97
|
+
}
|
package/dist/config/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
+
export declare function parseSkillsPath(skillsPath: string): string[];
|
|
2
3
|
export declare const defaultConfig: {
|
|
3
4
|
readonly loop: {
|
|
4
5
|
readonly maxIterations: 200;
|
|
@@ -16,11 +17,13 @@ export declare const defaultConfig: {
|
|
|
16
17
|
readonly readOnlyFiles: string[];
|
|
17
18
|
readonly skills: {
|
|
18
19
|
readonly enabled: true;
|
|
20
|
+
readonly path: "";
|
|
19
21
|
};
|
|
20
22
|
readonly devtools: {
|
|
21
23
|
readonly enabled: false;
|
|
22
24
|
};
|
|
23
25
|
readonly autoGenerateRules: false;
|
|
26
|
+
readonly allowedDirs: string[];
|
|
24
27
|
readonly env: Record<string, string>;
|
|
25
28
|
};
|
|
26
29
|
declare const ConfigSchema: z.ZodObject<{
|
|
@@ -43,8 +46,10 @@ declare const ConfigSchema: z.ZodObject<{
|
|
|
43
46
|
readOnlyFiles: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodString>>>;
|
|
44
47
|
skills: z.ZodDefault<z.ZodOptional<z.ZodObject<{
|
|
45
48
|
enabled: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
49
|
+
path: z.ZodDefault<z.ZodOptional<z.ZodString>>;
|
|
46
50
|
}, z.core.$strip>>>;
|
|
47
51
|
autoGenerateRules: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
52
|
+
allowedDirs: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodString>>>;
|
|
48
53
|
devtools: z.ZodDefault<z.ZodOptional<z.ZodObject<{
|
|
49
54
|
enabled: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
50
55
|
}, z.core.$strip>>>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../source/config/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../source/config/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,EAAE,CAa5D;AAED,eAAO,MAAM,aAAa;;;;;8BAKI,MAAM,EAAE,GAAG,SAAS;;;;;;;;;4BAS3B,MAAM,EAAE;;;;;;;;;0BASV,MAAM,EAAE;kBAChB,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB,CAAC;AAGX,QAAA,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA0DhB,CAAC;AAEH,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAC;AAElD,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,OAAO,CAAS;gBAEZ,OAAO,EAAE,MAAM;IAI3B,OAAO,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM;IAK1B,UAAU,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAOlD,cAAc,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM;IAOjC,MAAM,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAW/C,UAAU,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO;CAIrC;AAED,qBAAa,aAAa;IACxB,QAAQ,CAAC,OAAO,EAAE,iBAAiB,CAAC;IACpC,QAAQ,CAAC,GAAG,EAAE,iBAAiB,CAAC;IAChC,OAAO,CAAC,YAAY,CAAuB;IAC3C,OAAO,CAAC,eAAe,CAAK;IAC5B,OAAO,CAAC,cAAc,CAAS;;YAOjB,WAAW;IAanB,SAAS,IAAI,OAAO,CAAC,MAAM,CAAC;IA6C5B,gBAAgB,IAAI,OAAO,CAAC,OAAO,CAAC;IAKpC,gBAAgB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAsBjD,eAAe,IAAI,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAgC/D,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAY7C,oBAAoB,IAAI,OAAO,CAAC,MAAM,CAAC;IAYvC,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;YAc3C,cAAc;IActB,mBAAmB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAexD,cAAc,CAClB,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,MAAM,CAAC,WAAW,EAAE,OAAO,CAAC,GACjC,OAAO,CAAC,IAAI,CAAC;CAKjB;AAGD,eAAO,MAAM,MAAM,eAAsB,CAAC"}
|
package/dist/config/index.js
CHANGED
|
@@ -4,6 +4,22 @@ import { homedir } from "node:os";
|
|
|
4
4
|
import path from "node:path";
|
|
5
5
|
import { z } from "zod";
|
|
6
6
|
import { jsonParser } from "../utils/parsing.js";
|
|
7
|
+
const PATH_SEPARATOR = process.platform === "win32" ? ";" : ":";
|
|
8
|
+
export function parseSkillsPath(skillsPath) {
|
|
9
|
+
if (!skillsPath)
|
|
10
|
+
return [];
|
|
11
|
+
const paths = skillsPath
|
|
12
|
+
.split(PATH_SEPARATOR)
|
|
13
|
+
.map((p) => p.trim())
|
|
14
|
+
.filter((p) => p.length > 0)
|
|
15
|
+
.map((p) => {
|
|
16
|
+
if (p.startsWith("~")) {
|
|
17
|
+
return path.join(homedir(), p.slice(1));
|
|
18
|
+
}
|
|
19
|
+
return path.resolve(p);
|
|
20
|
+
});
|
|
21
|
+
return [...new Set(paths)];
|
|
22
|
+
}
|
|
7
23
|
export const defaultConfig = {
|
|
8
24
|
loop: {
|
|
9
25
|
maxIterations: 200,
|
|
@@ -21,11 +37,13 @@ export const defaultConfig = {
|
|
|
21
37
|
readOnlyFiles: [],
|
|
22
38
|
skills: {
|
|
23
39
|
enabled: true,
|
|
40
|
+
path: "",
|
|
24
41
|
},
|
|
25
42
|
devtools: {
|
|
26
43
|
enabled: false,
|
|
27
44
|
},
|
|
28
45
|
autoGenerateRules: false,
|
|
46
|
+
allowedDirs: [],
|
|
29
47
|
env: {},
|
|
30
48
|
};
|
|
31
49
|
// Type definitions
|
|
@@ -68,6 +86,7 @@ const ConfigSchema = z.object({
|
|
|
68
86
|
skills: z
|
|
69
87
|
.object({
|
|
70
88
|
enabled: z.boolean().optional().default(defaultConfig.skills.enabled),
|
|
89
|
+
path: z.string().optional().default(defaultConfig.skills.path),
|
|
71
90
|
})
|
|
72
91
|
.optional()
|
|
73
92
|
.default(defaultConfig.skills),
|
|
@@ -75,6 +94,10 @@ const ConfigSchema = z.object({
|
|
|
75
94
|
.boolean()
|
|
76
95
|
.optional()
|
|
77
96
|
.default(defaultConfig.autoGenerateRules),
|
|
97
|
+
allowedDirs: z
|
|
98
|
+
.array(z.string())
|
|
99
|
+
.optional()
|
|
100
|
+
.default(defaultConfig.allowedDirs),
|
|
78
101
|
devtools: z
|
|
79
102
|
.object({
|
|
80
103
|
enabled: z.boolean().optional().default(defaultConfig.devtools.enabled),
|
|
@@ -156,10 +179,23 @@ export class ConfigManager {
|
|
|
156
179
|
...appConfig.env,
|
|
157
180
|
...projectConfig.env,
|
|
158
181
|
};
|
|
182
|
+
const mergedAllowedDirs = [
|
|
183
|
+
...(appConfig.allowedDirs ?? []),
|
|
184
|
+
...(projectConfig.allowedDirs ?? []),
|
|
185
|
+
];
|
|
186
|
+
const mergedSkills = {
|
|
187
|
+
...appConfig.skills,
|
|
188
|
+
...projectConfig.skills,
|
|
189
|
+
path: [appConfig.skills?.path, projectConfig.skills?.path]
|
|
190
|
+
.filter((p) => !!p)
|
|
191
|
+
.join(PATH_SEPARATOR),
|
|
192
|
+
};
|
|
159
193
|
const mergedConfig = {
|
|
160
194
|
...appConfig,
|
|
161
195
|
...projectConfig,
|
|
162
196
|
env: mergedEnv,
|
|
197
|
+
allowedDirs: mergedAllowedDirs,
|
|
198
|
+
skills: mergedSkills,
|
|
163
199
|
};
|
|
164
200
|
const result = ConfigSchema.parse(mergedConfig);
|
|
165
201
|
this.cachedConfig = result;
|
|
@@ -184,7 +220,7 @@ export class ConfigManager {
|
|
|
184
220
|
}
|
|
185
221
|
}
|
|
186
222
|
if (!configData.skills) {
|
|
187
|
-
configData.skills = { enabled: true };
|
|
223
|
+
configData.skills = { enabled: true, path: "" };
|
|
188
224
|
}
|
|
189
225
|
configData.skills.enabled = enabled;
|
|
190
226
|
await this.app.ensurePath();
|
|
@@ -197,6 +233,10 @@ export class ConfigManager {
|
|
|
197
233
|
absolute: path.join(this.app.getPath(), "AGENTS.md"),
|
|
198
234
|
relative: "~/.acai/AGENTS.md",
|
|
199
235
|
},
|
|
236
|
+
{
|
|
237
|
+
absolute: path.join(homedir(), ".config", "AGENTS.md"),
|
|
238
|
+
relative: "~/.config/AGENTS.md",
|
|
239
|
+
},
|
|
200
240
|
{
|
|
201
241
|
absolute: path.join(process.cwd(), "AGENTS.md"),
|
|
202
242
|
relative: "./AGENTS.md",
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../source/index.ts"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../source/index.ts"],"names":[],"mappings":";AAiCA,MAAM,WAAW,gBAAgB;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB;AAGD,wBAAgB,sBAAsB,CACpC,UAAU,GAAE,MAAM,EAAO,GACxB,gBAAgB,CAsBlB;AAoDD,QAAA,MAAM,KAAK;;;;;;;;;;CAAyB,CAAC;AAMrC;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,CAE9C;AAED,MAAM,MAAM,KAAK,GAAG,OAAO,KAAK,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -22,7 +22,7 @@ import { setTerminalTitle } from "./terminal/control.js";
|
|
|
22
22
|
import { select } from "./terminal/select-prompt.js";
|
|
23
23
|
import { TokenCounter } from "./tokens/counter.js";
|
|
24
24
|
import { TokenTracker } from "./tokens/tracker.js";
|
|
25
|
-
import { initTools } from "./tools/index.js";
|
|
25
|
+
import { getActivatedSkillsTracker, initTools, } from "./tools/index.js";
|
|
26
26
|
import { logger } from "./utils/logger.js";
|
|
27
27
|
import { getPackageVersion } from "./utils/version.js";
|
|
28
28
|
// Create workspace context from CLI arguments
|
|
@@ -221,7 +221,7 @@ async function determineInitialPrompt() {
|
|
|
221
221
|
async function initializeModelManager(appDir) {
|
|
222
222
|
const chosenModel = isSupportedModel(flags.model)
|
|
223
223
|
? flags.model
|
|
224
|
-
: "opencode-go:
|
|
224
|
+
: "opencode-go:glm-5-1"; // DEFAULT MODEL
|
|
225
225
|
const projectConfig = await config.getConfig();
|
|
226
226
|
const devtoolsEnabled = projectConfig.devtools?.enabled ?? false;
|
|
227
227
|
const modelManager = new ModelManager({
|
|
@@ -232,7 +232,7 @@ async function initializeModelManager(appDir) {
|
|
|
232
232
|
modelManager.setModel("cli", chosenModel);
|
|
233
233
|
modelManager.setModel("title-conversation", chosenModel);
|
|
234
234
|
modelManager.setModel("conversation-summarizer", chosenModel);
|
|
235
|
-
modelManager.setModel("tool-repair", "openai:gpt-5.
|
|
235
|
+
modelManager.setModel("tool-repair", "openai:gpt-5.4-mini");
|
|
236
236
|
modelManager.setModel("conversation-analyzer", chosenModel);
|
|
237
237
|
modelManager.setModel("init-project", chosenModel);
|
|
238
238
|
modelManager.setModel("handoff-agent", chosenModel);
|
|
@@ -337,6 +337,7 @@ function setupReplEventHandlers(repl, agent, sessionManager, noSession) {
|
|
|
337
337
|
logger.info("Resetting agent state.");
|
|
338
338
|
agent.resetState();
|
|
339
339
|
agent.setConfig(await config.getConfig());
|
|
340
|
+
getActivatedSkillsTracker().reset();
|
|
340
341
|
void repl.rerender();
|
|
341
342
|
});
|
|
342
343
|
repl.setInterruptCallback(async () => {
|
|
@@ -462,6 +463,17 @@ async function main() {
|
|
|
462
463
|
const { initialPromptInput, stdinContent, hasContinueOrResume, resumeSessionId, } = await determineInitialPrompt();
|
|
463
464
|
// Initialize application state
|
|
464
465
|
const state = await initializeAppState(appConfig, initialPromptInput, stdinContent, hasContinueOrResume, resumeSessionId);
|
|
466
|
+
// Add config-sourced allowed directories
|
|
467
|
+
const configAllowedDirs = appConfig.allowedDirs ?? [];
|
|
468
|
+
for (const dir of configAllowedDirs) {
|
|
469
|
+
const expandedDir = dir.startsWith("~/") || dir === "~"
|
|
470
|
+
? path.join(os.homedir(), dir.slice(1))
|
|
471
|
+
: dir;
|
|
472
|
+
const resolvedDir = path.resolve(expandedDir);
|
|
473
|
+
if (!workspace.allowedDirs.includes(resolvedDir)) {
|
|
474
|
+
workspace.allowedDirs.push(resolvedDir);
|
|
475
|
+
}
|
|
476
|
+
}
|
|
465
477
|
// Add logs directory to allowed directories if configured
|
|
466
478
|
const logsPath = (await config.getConfig()).logs?.path;
|
|
467
479
|
if (logsPath) {
|