aws-runtime-bridge 1.7.48 → 1.7.50
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/adapter/AcodeSdkAdapter.d.ts +77 -0
- package/dist/adapter/AcodeSdkAdapter.d.ts.map +1 -0
- package/dist/adapter/AcodeSdkAdapter.js +322 -0
- package/dist/adapter/AcodeSdkAdapter.test.d.ts +2 -0
- package/dist/adapter/AcodeSdkAdapter.test.d.ts.map +1 -0
- package/dist/adapter/AcodeSdkAdapter.test.js +273 -0
- package/dist/adapter/AdapterRegistry.d.ts +1 -1
- package/dist/adapter/AdapterRegistry.d.ts.map +1 -1
- package/dist/adapter/AdapterRegistry.js +2 -0
- package/dist/adapter/AdapterRegistry.test.js +10 -1
- package/dist/adapter/SdkProviderSpi.d.ts.map +1 -1
- package/dist/adapter/SdkProviderSpi.js +10 -1
- package/dist/adapter/index.d.ts +1 -0
- package/dist/adapter/index.d.ts.map +1 -1
- package/dist/adapter/index.js +1 -0
- package/dist/adapters/cc-switch/index.d.ts +2 -0
- package/dist/adapters/cc-switch/index.d.ts.map +1 -1
- package/dist/adapters/cc-switch/index.js +6 -0
- package/dist/adapters/cc-switch/mcp-acode.d.ts +17 -0
- package/dist/adapters/cc-switch/mcp-acode.d.ts.map +1 -0
- package/dist/adapters/cc-switch/mcp-acode.js +71 -0
- package/dist/adapters/cc-switch/mcp-acode.test.d.ts +2 -0
- package/dist/adapters/cc-switch/mcp-acode.test.d.ts.map +1 -0
- package/dist/adapters/cc-switch/mcp-acode.test.js +80 -0
- package/dist/adapters/cc-switch/mcp-claude.d.ts.map +1 -1
- package/dist/adapters/cc-switch/mcp-claude.js +1 -0
- package/dist/adapters/cc-switch/mcp-claudecode.d.ts.map +1 -1
- package/dist/adapters/cc-switch/mcp-claudecode.js +1 -0
- package/dist/adapters/cc-switch/mcp-claudecode.test.js +1 -0
- package/dist/adapters/cc-switch/mcp-codex.d.ts.map +1 -1
- package/dist/adapters/cc-switch/mcp-codex.js +1 -0
- package/dist/adapters/cc-switch/mcp-codex.test.js +1 -0
- package/dist/adapters/cc-switch/mcp-opencode.d.ts.map +1 -1
- package/dist/adapters/cc-switch/mcp-opencode.js +1 -0
- package/dist/adapters/cc-switch/mcp-opencode.test.js +1 -0
- package/dist/adapters/cc-switch/skill-acode.d.ts +11 -0
- package/dist/adapters/cc-switch/skill-acode.d.ts.map +1 -0
- package/dist/adapters/cc-switch/skill-acode.js +12 -0
- package/dist/adapters/cc-switch/skill-directory.test.js +1 -0
- package/dist/config.d.ts +4 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +10 -0
- package/dist/index.js +2 -0
- package/dist/routes/ai-sources.js +3 -2
- package/dist/routes/instance.js +1 -1
- package/dist/routes/instance.test.js +2 -1
- package/dist/routes/mcp.js +2 -2
- package/dist/routes/mcp.test.js +2 -1
- package/dist/routes/runtime-binding.d.ts +3 -2
- package/dist/routes/runtime-binding.d.ts.map +1 -1
- package/dist/routes/runtime-binding.js +9 -56
- package/dist/routes/runtime-binding.test.js +4 -80
- package/dist/routes/sessions.d.ts +5 -0
- package/dist/routes/sessions.d.ts.map +1 -1
- package/dist/routes/sessions.js +36 -16
- package/dist/routes/sessions.test.js +13 -0
- package/dist/routes/skills.js +2 -2
- package/dist/routes/skills.test.js +2 -1
- package/dist/routes/terminal.d.ts +24 -4
- package/dist/routes/terminal.d.ts.map +1 -1
- package/dist/routes/terminal.js +99 -10
- package/dist/routes/terminal.test.js +74 -8
- package/dist/services/acode-package.d.ts +8 -0
- package/dist/services/acode-package.d.ts.map +1 -0
- package/dist/services/acode-package.js +82 -0
- package/dist/services/ai-source-apply.d.ts +4 -0
- package/dist/services/ai-source-apply.d.ts.map +1 -1
- package/dist/services/ai-source-apply.js +38 -9
- package/dist/services/ai-source-apply.test.js +58 -1
- package/dist/services/cc-switch-sdk.d.ts.map +1 -1
- package/dist/services/cc-switch-sdk.js +9 -1
- package/dist/services/instance-init-service.d.ts.map +1 -1
- package/dist/services/instance-init-service.js +3 -2
- package/dist/services/instance-init-service.test.js +6 -5
- package/dist/services/instance-service.d.ts.map +1 -1
- package/dist/services/instance-service.js +1 -0
- package/dist/services/instance-state.js +1 -1
- package/dist/services/instance-state.test.js +4 -4
- package/dist/services/tool-installer.d.ts.map +1 -1
- package/dist/services/tool-installer.js +10 -0
- package/dist/types.d.ts +5 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/file-utils.d.ts.map +1 -1
- package/dist/utils/file-utils.js +1 -0
- package/dist/utils/mcp-utils.d.ts.map +1 -1
- package/dist/utils/mcp-utils.js +4 -1
- package/dist/utils/validation.js +1 -1
- package/node_modules/@cc-switch/sdk/dist/constants.d.ts.map +1 -1
- package/node_modules/@cc-switch/sdk/dist/constants.js +7 -0
- package/node_modules/@cc-switch/sdk/dist/schemas.d.ts.map +1 -1
- package/node_modules/@cc-switch/sdk/dist/schemas.js +1 -0
- package/node_modules/@cc-switch/sdk/dist/sdk.d.ts.map +1 -1
- package/node_modules/@cc-switch/sdk/dist/sdk.js +7 -3
- package/node_modules/@cc-switch/sdk/dist/services/ai-config-service.d.ts +7 -0
- package/node_modules/@cc-switch/sdk/dist/services/ai-config-service.d.ts.map +1 -1
- package/node_modules/@cc-switch/sdk/dist/services/ai-config-service.js +29 -2
- package/node_modules/@cc-switch/sdk/dist/types.d.ts +4 -1
- package/node_modules/@cc-switch/sdk/dist/types.d.ts.map +1 -1
- package/package/acode/README.md +88 -0
- package/package/acode/dist/built-in-file-tools.d.ts +16 -0
- package/package/acode/dist/built-in-file-tools.d.ts.map +1 -0
- package/package/acode/dist/built-in-file-tools.js +231 -0
- package/package/acode/dist/cli.d.ts +3 -0
- package/package/acode/dist/cli.d.ts.map +1 -0
- package/package/acode/dist/cli.js +37 -0
- package/package/acode/dist/commands/commandLoader.d.ts +7 -0
- package/package/acode/dist/commands/commandLoader.d.ts.map +1 -0
- package/package/acode/dist/commands/commandLoader.js +33 -0
- package/package/acode/dist/commands/commandParser.d.ts +7 -0
- package/package/acode/dist/commands/commandParser.d.ts.map +1 -0
- package/package/acode/dist/commands/commandParser.js +77 -0
- package/package/acode/dist/commands/commandRegistry.d.ts +13 -0
- package/package/acode/dist/commands/commandRegistry.d.ts.map +1 -0
- package/package/acode/dist/commands/commandRegistry.js +30 -0
- package/package/acode/dist/config.d.ts +4 -0
- package/package/acode/dist/config.d.ts.map +1 -0
- package/package/acode/dist/config.js +80 -0
- package/package/acode/dist/hooks/hookBus.d.ts +19 -0
- package/package/acode/dist/hooks/hookBus.d.ts.map +1 -0
- package/package/acode/dist/hooks/hookBus.js +40 -0
- package/package/acode/dist/index.d.ts +8 -0
- package/package/acode/dist/index.d.ts.map +1 -0
- package/package/acode/dist/index.js +7 -0
- package/package/acode/dist/runtime.d.ts +34 -0
- package/package/acode/dist/runtime.d.ts.map +1 -0
- package/package/acode/dist/runtime.js +571 -0
- package/package/acode/dist/types.d.ts +99 -0
- package/package/acode/dist/types.d.ts.map +1 -0
- package/package/acode/dist/types.js +1 -0
- package/package/acode/package.json +24 -0
- package/package/aws-client-agent-mcp/dist/agent-client.d.ts +4 -4
- package/package/aws-client-agent-mcp/dist/agent-client.d.ts.map +1 -1
- package/package/aws-client-agent-mcp/dist/agent-client.js +9 -6
- package/package/aws-client-agent-mcp/dist/agent-client.js.map +1 -1
- package/package/aws-client-agent-mcp/dist/agent-client.test.js +21 -0
- package/package/aws-client-agent-mcp/dist/agent-client.test.js.map +1 -1
- package/package/aws-client-agent-mcp/dist/http-client.d.ts +1 -17
- package/package/aws-client-agent-mcp/dist/http-client.d.ts.map +1 -1
- package/package/aws-client-agent-mcp/dist/http-client.js +7 -113
- package/package/aws-client-agent-mcp/dist/http-client.js.map +1 -1
- package/package/aws-client-agent-mcp/dist/http-client.test.js +22 -2
- package/package/aws-client-agent-mcp/dist/http-client.test.js.map +1 -1
- package/package/aws-client-agent-mcp/dist/mcp-server.d.ts +0 -5
- package/package/aws-client-agent-mcp/dist/mcp-server.d.ts.map +1 -1
- package/package/aws-client-agent-mcp/dist/mcp-server.js +1 -23
- package/package/aws-client-agent-mcp/dist/mcp-server.js.map +1 -1
- package/package/aws-client-agent-mcp/dist/mcp-server.test.js +89 -6
- package/package/aws-client-agent-mcp/dist/mcp-server.test.js.map +1 -1
- package/package/aws-client-agent-mcp/dist/types.d.ts +3 -0
- package/package/aws-client-agent-mcp/dist/types.d.ts.map +1 -1
- package/package/aws-client-agent-mcp/dist/websocket-client.d.ts +0 -13
- package/package/aws-client-agent-mcp/dist/websocket-client.d.ts.map +1 -1
- package/package/aws-client-agent-mcp/dist/websocket-client.js +3 -100
- package/package/aws-client-agent-mcp/dist/websocket-client.js.map +1 -1
- package/package/cc-switch-sdk/dist/constants.d.ts.map +1 -1
- package/package/cc-switch-sdk/dist/constants.js +7 -0
- package/package/cc-switch-sdk/dist/schemas.d.ts.map +1 -1
- package/package/cc-switch-sdk/dist/schemas.js +1 -0
- package/package/cc-switch-sdk/dist/sdk.d.ts.map +1 -1
- package/package/cc-switch-sdk/dist/sdk.js +7 -3
- package/package/cc-switch-sdk/dist/services/ai-config-service.d.ts +7 -0
- package/package/cc-switch-sdk/dist/services/ai-config-service.d.ts.map +1 -1
- package/package/cc-switch-sdk/dist/services/ai-config-service.js +29 -2
- package/package/cc-switch-sdk/dist/types.d.ts +4 -1
- package/package/cc-switch-sdk/dist/types.d.ts.map +1 -1
- package/package.json +8 -4
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
2
|
+
import { promises as fs } from 'node:fs';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
function toDisplayPath(targetPath) {
|
|
5
|
+
return targetPath.replace(/\\/g, '/');
|
|
6
|
+
}
|
|
7
|
+
async function pathExists(targetPath) {
|
|
8
|
+
try {
|
|
9
|
+
await fs.access(targetPath);
|
|
10
|
+
return true;
|
|
11
|
+
}
|
|
12
|
+
catch {
|
|
13
|
+
return false;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
function countOccurrences(content, search) {
|
|
17
|
+
if (!search) {
|
|
18
|
+
return 0;
|
|
19
|
+
}
|
|
20
|
+
let count = 0;
|
|
21
|
+
let index = content.indexOf(search);
|
|
22
|
+
while (index >= 0) {
|
|
23
|
+
count += 1;
|
|
24
|
+
index = content.indexOf(search, index + search.length);
|
|
25
|
+
}
|
|
26
|
+
return count;
|
|
27
|
+
}
|
|
28
|
+
function readStringArg(args, names, label) {
|
|
29
|
+
for (const name of names) {
|
|
30
|
+
const value = args[name];
|
|
31
|
+
if (typeof value === 'string') {
|
|
32
|
+
return value;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
throw new Error(`${label} is required`);
|
|
36
|
+
}
|
|
37
|
+
function ensureInsideWorkspace(workspaceRoot, targetPath) {
|
|
38
|
+
const resolvedTargetPath = path.resolve(targetPath);
|
|
39
|
+
const relativePath = path.relative(workspaceRoot, resolvedTargetPath);
|
|
40
|
+
if (relativePath.startsWith('..') || path.isAbsolute(relativePath)) {
|
|
41
|
+
throw new Error(`Target path is outside workspace: ${resolvedTargetPath}`);
|
|
42
|
+
}
|
|
43
|
+
return resolvedTargetPath;
|
|
44
|
+
}
|
|
45
|
+
async function ensureWritableTarget(workspaceRoot, targetPath) {
|
|
46
|
+
const realParentPath = await fs.realpath(path.dirname(targetPath));
|
|
47
|
+
ensureInsideWorkspace(workspaceRoot, realParentPath);
|
|
48
|
+
try {
|
|
49
|
+
const targetLinkStat = await fs.lstat(targetPath);
|
|
50
|
+
if (targetLinkStat.isSymbolicLink()) {
|
|
51
|
+
throw new Error(`Refusing to write through symbolic link: ${targetPath}`);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
catch (error) {
|
|
55
|
+
const errorCode = typeof error === 'object' && error !== null ? Reflect.get(error, 'code') : undefined;
|
|
56
|
+
if (errorCode !== 'ENOENT') {
|
|
57
|
+
throw error;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* 解析内置文件工具目标路径。
|
|
63
|
+
* 主流程:同时校验请求路径与 realpath 工作区边界,防止绝对路径、`..` 与符号链接目录穿透。
|
|
64
|
+
*/
|
|
65
|
+
async function resolveWorkspaceTarget(workingDirectory, rawFilePath) {
|
|
66
|
+
const requestedRoot = path.resolve(String(workingDirectory || '').trim());
|
|
67
|
+
const workspaceRoot = await fs.realpath(requestedRoot);
|
|
68
|
+
const workspaceStat = await fs.stat(workspaceRoot);
|
|
69
|
+
if (!workspaceStat.isDirectory()) {
|
|
70
|
+
throw new Error(`Workspace path is not a directory: ${requestedRoot}`);
|
|
71
|
+
}
|
|
72
|
+
const normalizedFilePath = rawFilePath.trim();
|
|
73
|
+
if (!normalizedFilePath) {
|
|
74
|
+
throw new Error('file_path is required');
|
|
75
|
+
}
|
|
76
|
+
const requestedPath = path.isAbsolute(normalizedFilePath)
|
|
77
|
+
? path.resolve(normalizedFilePath)
|
|
78
|
+
: path.resolve(requestedRoot, normalizedFilePath);
|
|
79
|
+
const requestedRelativePath = path.relative(requestedRoot, requestedPath);
|
|
80
|
+
if (requestedRelativePath.startsWith('..') || path.isAbsolute(requestedRelativePath)) {
|
|
81
|
+
throw new Error(`Target path is outside workspace: ${requestedPath}`);
|
|
82
|
+
}
|
|
83
|
+
return {
|
|
84
|
+
workspaceRoot,
|
|
85
|
+
requestedPath,
|
|
86
|
+
targetPath: ensureInsideWorkspace(workspaceRoot, path.join(workspaceRoot, requestedRelativePath)),
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* 原子写入完整文件内容。
|
|
91
|
+
* 主流程:创建父目录 -> 校验 realpath 边界和符号链接 -> 写同目录临时文件 -> rename 覆盖目标。
|
|
92
|
+
*/
|
|
93
|
+
async function writeFileAtomically(workingDirectory, filePath, content) {
|
|
94
|
+
const target = await resolveWorkspaceTarget(workingDirectory, filePath);
|
|
95
|
+
const parentPath = path.dirname(target.targetPath);
|
|
96
|
+
const createdParentDirectory = !(await pathExists(parentPath));
|
|
97
|
+
await fs.mkdir(parentPath, { recursive: true });
|
|
98
|
+
await ensureWritableTarget(target.workspaceRoot, target.targetPath);
|
|
99
|
+
const temporaryPath = path.join(parentPath, `.${path.basename(target.targetPath)}.${process.pid}.${randomUUID()}.tmp`);
|
|
100
|
+
try {
|
|
101
|
+
await fs.writeFile(temporaryPath, content, 'utf-8');
|
|
102
|
+
await fs.rename(temporaryPath, target.targetPath);
|
|
103
|
+
}
|
|
104
|
+
catch (error) {
|
|
105
|
+
await fs.rm(temporaryPath, { force: true });
|
|
106
|
+
throw error;
|
|
107
|
+
}
|
|
108
|
+
return {
|
|
109
|
+
workspaceRoot: target.workspaceRoot,
|
|
110
|
+
targetPath: target.targetPath,
|
|
111
|
+
bytes: Buffer.byteLength(content, 'utf-8'),
|
|
112
|
+
createdParentDirectory,
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
async function readFileInsideWorkspace(workingDirectory, filePath) {
|
|
116
|
+
const target = await resolveWorkspaceTarget(workingDirectory, filePath);
|
|
117
|
+
const realTargetPath = ensureInsideWorkspace(target.workspaceRoot, await fs.realpath(target.targetPath));
|
|
118
|
+
const stat = await fs.stat(realTargetPath);
|
|
119
|
+
if (!stat.isFile()) {
|
|
120
|
+
throw new Error(`Path is not a file: ${realTargetPath}`);
|
|
121
|
+
}
|
|
122
|
+
return {
|
|
123
|
+
workspaceRoot: target.workspaceRoot,
|
|
124
|
+
targetPath: realTargetPath,
|
|
125
|
+
content: await fs.readFile(realTargetPath, 'utf-8'),
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
function writeFileTool(workingDirectory) {
|
|
129
|
+
return {
|
|
130
|
+
kind: 'builtin',
|
|
131
|
+
toolName: 'write_file',
|
|
132
|
+
exposedName: 'write_file',
|
|
133
|
+
description: 'Create or overwrite a UTF-8 text file inside the current workspace. Parent directories are created automatically.',
|
|
134
|
+
inputSchema: {
|
|
135
|
+
type: 'object',
|
|
136
|
+
properties: {
|
|
137
|
+
file_path: { type: 'string', description: 'Workspace-relative file path to write.' },
|
|
138
|
+
content: { type: 'string', description: 'Complete UTF-8 file content.' },
|
|
139
|
+
},
|
|
140
|
+
required: ['file_path', 'content'],
|
|
141
|
+
additionalProperties: false,
|
|
142
|
+
},
|
|
143
|
+
async execute(args) {
|
|
144
|
+
const filePath = readStringArg(args, ['file_path', 'filePath'], 'file_path');
|
|
145
|
+
const content = readStringArg(args, ['content'], 'content');
|
|
146
|
+
const result = await writeFileAtomically(workingDirectory, filePath, content);
|
|
147
|
+
return {
|
|
148
|
+
ok: true,
|
|
149
|
+
tool: 'write_file',
|
|
150
|
+
workspacePath: toDisplayPath(result.workspaceRoot),
|
|
151
|
+
filePath: toDisplayPath(result.targetPath),
|
|
152
|
+
bytes: result.bytes,
|
|
153
|
+
createdParentDirectory: result.createdParentDirectory,
|
|
154
|
+
};
|
|
155
|
+
},
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
function editFileTool(workingDirectory) {
|
|
159
|
+
return {
|
|
160
|
+
kind: 'builtin',
|
|
161
|
+
toolName: 'edit_file',
|
|
162
|
+
exposedName: 'edit_file',
|
|
163
|
+
description: 'Replace exactly one occurrence of old_string with new_string in a UTF-8 workspace text file.',
|
|
164
|
+
inputSchema: {
|
|
165
|
+
type: 'object',
|
|
166
|
+
properties: {
|
|
167
|
+
file_path: { type: 'string', description: 'Workspace-relative file path to edit.' },
|
|
168
|
+
old_string: { type: 'string', description: 'Existing text to replace. Must occur exactly once.' },
|
|
169
|
+
new_string: { type: 'string', description: 'Replacement text.' },
|
|
170
|
+
},
|
|
171
|
+
required: ['file_path', 'old_string', 'new_string'],
|
|
172
|
+
additionalProperties: false,
|
|
173
|
+
},
|
|
174
|
+
async execute(args) {
|
|
175
|
+
const filePath = readStringArg(args, ['file_path', 'filePath'], 'file_path');
|
|
176
|
+
const oldString = readStringArg(args, ['old_string', 'oldString'], 'old_string');
|
|
177
|
+
const newString = readStringArg(args, ['new_string', 'newString'], 'new_string');
|
|
178
|
+
if (!oldString) {
|
|
179
|
+
throw new Error('old_string must not be empty');
|
|
180
|
+
}
|
|
181
|
+
const current = await readFileInsideWorkspace(workingDirectory, filePath);
|
|
182
|
+
const occurrences = countOccurrences(current.content, oldString);
|
|
183
|
+
if (occurrences === 0) {
|
|
184
|
+
throw new Error('old_string was not found in file');
|
|
185
|
+
}
|
|
186
|
+
if (occurrences > 1) {
|
|
187
|
+
throw new Error(`old_string occurs ${occurrences} times; provide a unique match`);
|
|
188
|
+
}
|
|
189
|
+
const updatedContent = current.content.replace(oldString, newString);
|
|
190
|
+
const result = await writeFileAtomically(workingDirectory, filePath, updatedContent);
|
|
191
|
+
return {
|
|
192
|
+
ok: true,
|
|
193
|
+
tool: 'edit_file',
|
|
194
|
+
workspacePath: toDisplayPath(result.workspaceRoot),
|
|
195
|
+
filePath: toDisplayPath(result.targetPath),
|
|
196
|
+
replacements: 1,
|
|
197
|
+
bytes: result.bytes,
|
|
198
|
+
};
|
|
199
|
+
},
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
function readFileTool(workingDirectory) {
|
|
203
|
+
return {
|
|
204
|
+
kind: 'builtin',
|
|
205
|
+
toolName: 'read_file',
|
|
206
|
+
exposedName: 'read_file',
|
|
207
|
+
description: 'Read a UTF-8 text file inside the current workspace.',
|
|
208
|
+
inputSchema: {
|
|
209
|
+
type: 'object',
|
|
210
|
+
properties: {
|
|
211
|
+
file_path: { type: 'string', description: 'Workspace-relative file path to read.' },
|
|
212
|
+
},
|
|
213
|
+
required: ['file_path'],
|
|
214
|
+
additionalProperties: false,
|
|
215
|
+
},
|
|
216
|
+
async execute(args) {
|
|
217
|
+
const filePath = readStringArg(args, ['file_path', 'filePath'], 'file_path');
|
|
218
|
+
const result = await readFileInsideWorkspace(workingDirectory, filePath);
|
|
219
|
+
return {
|
|
220
|
+
ok: true,
|
|
221
|
+
tool: 'read_file',
|
|
222
|
+
workspacePath: toDisplayPath(result.workspaceRoot),
|
|
223
|
+
filePath: toDisplayPath(result.targetPath),
|
|
224
|
+
content: result.content,
|
|
225
|
+
};
|
|
226
|
+
},
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
export function createBuiltInFileTools(workingDirectory) {
|
|
230
|
+
return [readFileTool(workingDirectory), writeFileTool(workingDirectory), editFileTool(workingDirectory)];
|
|
231
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { randomUUID } from 'node:crypto';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { ACodeRuntime } from './runtime.js';
|
|
5
|
+
function getFlagValue(args, name) {
|
|
6
|
+
const index = args.indexOf(name);
|
|
7
|
+
if (index >= 0) {
|
|
8
|
+
return args[index + 1];
|
|
9
|
+
}
|
|
10
|
+
const prefixed = args.find((arg) => arg.startsWith(`${name}=`));
|
|
11
|
+
return prefixed ? prefixed.slice(name.length + 1) : undefined;
|
|
12
|
+
}
|
|
13
|
+
async function main() {
|
|
14
|
+
const args = process.argv.slice(2);
|
|
15
|
+
const cwd = path.resolve(getFlagValue(args, '--cwd') || process.cwd());
|
|
16
|
+
const configPath = getFlagValue(args, '--config');
|
|
17
|
+
const skillsDir = getFlagValue(args, '--skills-dir');
|
|
18
|
+
const prompt = getFlagValue(args, '--prompt') || args.filter((arg) => !arg.startsWith('--')).join(' ');
|
|
19
|
+
const runtime = new ACodeRuntime({
|
|
20
|
+
sessionId: getFlagValue(args, '--session-id') || randomUUID(),
|
|
21
|
+
workingDirectory: cwd,
|
|
22
|
+
configPath,
|
|
23
|
+
skillsDir,
|
|
24
|
+
initialPrompt: prompt,
|
|
25
|
+
model: getFlagValue(args, '--model'),
|
|
26
|
+
});
|
|
27
|
+
runtime.on('event', (event) => {
|
|
28
|
+
process.stdout.write(`${JSON.stringify(event)}\n`);
|
|
29
|
+
});
|
|
30
|
+
await runtime.start();
|
|
31
|
+
await runtime.stop();
|
|
32
|
+
}
|
|
33
|
+
main().catch((error) => {
|
|
34
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
35
|
+
process.stderr.write(`[acode] ${message}\n`);
|
|
36
|
+
process.exitCode = 1;
|
|
37
|
+
});
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { ACodeCommandSpec } from '../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* 从命令目录加载 Markdown slash commands。
|
|
4
|
+
* 主流程:跳过不存在目录与隐藏文件 -> 解析 `.md` 文件 -> 按文件名稳定排序。
|
|
5
|
+
*/
|
|
6
|
+
export declare function loadAcodeCommands(commandDirs: readonly string[]): Promise<ACodeCommandSpec[]>;
|
|
7
|
+
//# sourceMappingURL=commandLoader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"commandLoader.d.ts","sourceRoot":"","sources":["../../src/commands/commandLoader.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAYpD;;;GAGG;AACH,wBAAsB,iBAAiB,CAAC,WAAW,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAgBnG"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import fs from 'node:fs/promises';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { parseAcodeCommandMarkdown } from './commandParser.js';
|
|
4
|
+
async function pathExists(targetPath) {
|
|
5
|
+
try {
|
|
6
|
+
await fs.access(targetPath);
|
|
7
|
+
return true;
|
|
8
|
+
}
|
|
9
|
+
catch {
|
|
10
|
+
return false;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* 从命令目录加载 Markdown slash commands。
|
|
15
|
+
* 主流程:跳过不存在目录与隐藏文件 -> 解析 `.md` 文件 -> 按文件名稳定排序。
|
|
16
|
+
*/
|
|
17
|
+
export async function loadAcodeCommands(commandDirs) {
|
|
18
|
+
const commands = [];
|
|
19
|
+
for (const commandDir of commandDirs) {
|
|
20
|
+
if (!(await pathExists(commandDir))) {
|
|
21
|
+
continue;
|
|
22
|
+
}
|
|
23
|
+
const entries = await fs.readdir(commandDir, { withFileTypes: true });
|
|
24
|
+
for (const entry of entries.sort((left, right) => left.name.localeCompare(right.name))) {
|
|
25
|
+
if (!entry.isFile() || entry.name.startsWith('.') || path.extname(entry.name).toLowerCase() !== '.md') {
|
|
26
|
+
continue;
|
|
27
|
+
}
|
|
28
|
+
const sourcePath = path.join(commandDir, entry.name);
|
|
29
|
+
commands.push(parseAcodeCommandMarkdown(sourcePath, await fs.readFile(sourcePath, 'utf-8')));
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return commands;
|
|
33
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { ACodeCommandSpec } from '../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* 解析 Markdown slash command。
|
|
4
|
+
* 主流程:读取可选 YAML frontmatter -> 使用正文作为 prompt 模板 -> 缺省命令名取文件名。
|
|
5
|
+
*/
|
|
6
|
+
export declare function parseAcodeCommandMarkdown(sourcePath: string, rawMarkdown: string): ACodeCommandSpec;
|
|
7
|
+
//# sourceMappingURL=commandParser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"commandParser.d.ts","sourceRoot":"","sources":["../../src/commands/commandParser.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AA6DpD;;;GAGG;AACH,wBAAgB,yBAAyB,CAAC,UAAU,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,gBAAgB,CAuBnG"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
function parseScalar(raw) {
|
|
3
|
+
const trimmed = raw.trim();
|
|
4
|
+
if (!trimmed) {
|
|
5
|
+
return undefined;
|
|
6
|
+
}
|
|
7
|
+
if ((trimmed.startsWith('"') && trimmed.endsWith('"')) || (trimmed.startsWith("'") && trimmed.endsWith("'"))) {
|
|
8
|
+
return trimmed.slice(1, -1).trim();
|
|
9
|
+
}
|
|
10
|
+
return trimmed;
|
|
11
|
+
}
|
|
12
|
+
function parseList(raw) {
|
|
13
|
+
const trimmed = raw.trim();
|
|
14
|
+
if (!trimmed) {
|
|
15
|
+
return [];
|
|
16
|
+
}
|
|
17
|
+
const withoutBrackets = trimmed.startsWith('[') && trimmed.endsWith(']') ? trimmed.slice(1, -1) : trimmed;
|
|
18
|
+
return withoutBrackets
|
|
19
|
+
.split(',')
|
|
20
|
+
.map((item) => parseScalar(item) ?? '')
|
|
21
|
+
.filter(Boolean);
|
|
22
|
+
}
|
|
23
|
+
function fallbackCommandName(sourcePath) {
|
|
24
|
+
return path.basename(sourcePath, path.extname(sourcePath)).trim();
|
|
25
|
+
}
|
|
26
|
+
function parseFrontmatter(rawFrontmatter) {
|
|
27
|
+
const parsed = {};
|
|
28
|
+
for (const line of rawFrontmatter.split(/\r?\n/)) {
|
|
29
|
+
const match = line.match(/^\s*([A-Za-z][A-Za-z0-9_-]*)\s*:\s*(.*)$/);
|
|
30
|
+
if (!match) {
|
|
31
|
+
continue;
|
|
32
|
+
}
|
|
33
|
+
const key = match[1];
|
|
34
|
+
const value = match[2] ?? '';
|
|
35
|
+
if (key === 'name') {
|
|
36
|
+
parsed.name = parseScalar(value);
|
|
37
|
+
}
|
|
38
|
+
if (key === 'description') {
|
|
39
|
+
parsed.description = parseScalar(value);
|
|
40
|
+
}
|
|
41
|
+
if (key === 'allowedTools' || key === 'allowed-tools') {
|
|
42
|
+
parsed.allowedTools = parseList(value);
|
|
43
|
+
}
|
|
44
|
+
if (key === 'argumentHint' || key === 'argument-hint') {
|
|
45
|
+
parsed.argumentHint = parseScalar(value);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return parsed;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* 解析 Markdown slash command。
|
|
52
|
+
* 主流程:读取可选 YAML frontmatter -> 使用正文作为 prompt 模板 -> 缺省命令名取文件名。
|
|
53
|
+
*/
|
|
54
|
+
export function parseAcodeCommandMarkdown(sourcePath, rawMarkdown) {
|
|
55
|
+
const normalized = rawMarkdown.replace(/^\uFEFF/, '');
|
|
56
|
+
let body = normalized;
|
|
57
|
+
let metadata = {};
|
|
58
|
+
if (normalized.startsWith('---')) {
|
|
59
|
+
const end = normalized.indexOf('\n---', 3);
|
|
60
|
+
if (end >= 0) {
|
|
61
|
+
metadata = parseFrontmatter(normalized.slice(3, end));
|
|
62
|
+
body = normalized.slice(end + '\n---'.length).replace(/^\r?\n/, '');
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
const name = (metadata.name || fallbackCommandName(sourcePath)).replace(/^\/+/, '').trim();
|
|
66
|
+
if (!name) {
|
|
67
|
+
throw new Error(`ACode command name is empty: ${sourcePath}`);
|
|
68
|
+
}
|
|
69
|
+
return {
|
|
70
|
+
name,
|
|
71
|
+
description: metadata.description,
|
|
72
|
+
allowedTools: metadata.allowedTools,
|
|
73
|
+
argumentHint: metadata.argumentHint,
|
|
74
|
+
body: body.trim(),
|
|
75
|
+
sourcePath,
|
|
76
|
+
};
|
|
77
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { ACodeCommandSpec } from '../types.js';
|
|
2
|
+
export interface ExpandedAcodeCommand {
|
|
3
|
+
command: ACodeCommandSpec;
|
|
4
|
+
prompt: string;
|
|
5
|
+
argumentsText: string;
|
|
6
|
+
}
|
|
7
|
+
export declare class ACodeCommandRegistry {
|
|
8
|
+
private readonly commands;
|
|
9
|
+
constructor(commands: readonly ACodeCommandSpec[]);
|
|
10
|
+
list(): ACodeCommandSpec[];
|
|
11
|
+
expand(input: string): ExpandedAcodeCommand | null;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=commandRegistry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"commandRegistry.d.ts","sourceRoot":"","sources":["../../src/commands/commandRegistry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAEpD,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,gBAAgB,CAAC;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,MAAM,CAAC;CACvB;AAMD,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAuC;gBAEpD,QAAQ,EAAE,SAAS,gBAAgB,EAAE;IAMjD,IAAI,IAAI,gBAAgB,EAAE;IAI1B,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,oBAAoB,GAAG,IAAI;CAgBnD"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
function normalizeCommandName(name) {
|
|
2
|
+
return name.replace(/^\/+/, '').trim().toLowerCase();
|
|
3
|
+
}
|
|
4
|
+
export class ACodeCommandRegistry {
|
|
5
|
+
constructor(commands) {
|
|
6
|
+
this.commands = new Map();
|
|
7
|
+
for (const command of commands) {
|
|
8
|
+
this.commands.set(normalizeCommandName(command.name), command);
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
list() {
|
|
12
|
+
return [...this.commands.values()];
|
|
13
|
+
}
|
|
14
|
+
expand(input) {
|
|
15
|
+
const match = input.trim().match(/^\/([^\s]+)(?:\s+(.*))?$/s);
|
|
16
|
+
if (!match) {
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
const command = this.commands.get(normalizeCommandName(match[1] ?? ''));
|
|
20
|
+
if (!command) {
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
const argumentsText = (match[2] ?? '').trim();
|
|
24
|
+
return {
|
|
25
|
+
command,
|
|
26
|
+
argumentsText,
|
|
27
|
+
prompt: command.body.replace(/\$ARGUMENTS/g, argumentsText),
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { ACodeConfigFile, ACodeSkillMetadata } from './types.js';
|
|
2
|
+
export declare function loadAcodeConfig(configPath: string | undefined): Promise<ACodeConfigFile>;
|
|
3
|
+
export declare function loadAcodeSkills(skillsDir: string | undefined): Promise<ACodeSkillMetadata[]>;
|
|
4
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAWtE,wBAAsB,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC,eAAe,CAAC,CAU9F;AA8CD,wBAAsB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAgBlG"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import fs from 'node:fs/promises';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
async function pathExists(target) {
|
|
4
|
+
try {
|
|
5
|
+
await fs.access(target);
|
|
6
|
+
return true;
|
|
7
|
+
}
|
|
8
|
+
catch {
|
|
9
|
+
return false;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
export async function loadAcodeConfig(configPath) {
|
|
13
|
+
if (!configPath || !(await pathExists(configPath))) {
|
|
14
|
+
return {};
|
|
15
|
+
}
|
|
16
|
+
const raw = await fs.readFile(configPath, 'utf-8');
|
|
17
|
+
const parsed = JSON.parse(raw);
|
|
18
|
+
if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
|
|
19
|
+
return {};
|
|
20
|
+
}
|
|
21
|
+
return parsed;
|
|
22
|
+
}
|
|
23
|
+
function parseYamlStringValue(raw) {
|
|
24
|
+
const trimmed = raw.trim();
|
|
25
|
+
if (!trimmed) {
|
|
26
|
+
return undefined;
|
|
27
|
+
}
|
|
28
|
+
if ((trimmed.startsWith('"') && trimmed.endsWith('"')) || (trimmed.startsWith("'") && trimmed.endsWith("'"))) {
|
|
29
|
+
return trimmed.slice(1, -1).trim();
|
|
30
|
+
}
|
|
31
|
+
return trimmed;
|
|
32
|
+
}
|
|
33
|
+
function fallbackNameFromDirectory(directory) {
|
|
34
|
+
return path.basename(directory).replace(/\.skill$/, '').replace(/[-_]/g, ' ');
|
|
35
|
+
}
|
|
36
|
+
async function readSkillMetadata(directory) {
|
|
37
|
+
const skillFile = path.join(directory, 'SKILL.md');
|
|
38
|
+
if (!(await pathExists(skillFile))) {
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
const raw = (await fs.readFile(skillFile, 'utf-8')).replace(/^\uFEFF/, '');
|
|
42
|
+
const metadata = {};
|
|
43
|
+
if (raw.startsWith('---')) {
|
|
44
|
+
const end = raw.indexOf('\n---', 3);
|
|
45
|
+
if (end >= 0) {
|
|
46
|
+
for (const line of raw.slice(3, end).split(/\r?\n/)) {
|
|
47
|
+
const match = line.match(/^\s*(name|description)\s*:\s*(.*)$/);
|
|
48
|
+
if (!match) {
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
const value = parseYamlStringValue(match[2] ?? '');
|
|
52
|
+
if (value) {
|
|
53
|
+
metadata[match[1]] = value;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return {
|
|
59
|
+
name: metadata.name || fallbackNameFromDirectory(directory),
|
|
60
|
+
description: metadata.description,
|
|
61
|
+
directory,
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
export async function loadAcodeSkills(skillsDir) {
|
|
65
|
+
if (!skillsDir || !(await pathExists(skillsDir))) {
|
|
66
|
+
return [];
|
|
67
|
+
}
|
|
68
|
+
const entries = await fs.readdir(skillsDir, { withFileTypes: true });
|
|
69
|
+
const skills = [];
|
|
70
|
+
for (const entry of entries) {
|
|
71
|
+
if (entry.name.startsWith('.') || (!entry.isDirectory() && !entry.isSymbolicLink())) {
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
74
|
+
const metadata = await readSkillMetadata(path.join(skillsDir, entry.name));
|
|
75
|
+
if (metadata) {
|
|
76
|
+
skills.push(metadata);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return skills;
|
|
80
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { ACodeHookEvent, ACodeHookEventName, ACodeHookHandler, ACodeHookResult } from '../types.js';
|
|
2
|
+
export interface ACodeHookBusOptions {
|
|
3
|
+
sessionId: string;
|
|
4
|
+
now?: () => string;
|
|
5
|
+
onError?: (event: ACodeHookEvent, error: unknown) => void;
|
|
6
|
+
}
|
|
7
|
+
export declare class ACodeHookBus {
|
|
8
|
+
private readonly options;
|
|
9
|
+
private readonly handlers;
|
|
10
|
+
constructor(options: ACodeHookBusOptions);
|
|
11
|
+
register(handler: ACodeHookHandler): void;
|
|
12
|
+
/**
|
|
13
|
+
* 分发 ACode 生命周期 Hook。
|
|
14
|
+
* 主流程:按注册顺序执行 handler -> fail-open 记录错误 -> 遇到 deny 立即返回。
|
|
15
|
+
*/
|
|
16
|
+
dispatch(name: ACodeHookEventName, data: Record<string, unknown>): Promise<ACodeHookResult[]>;
|
|
17
|
+
}
|
|
18
|
+
export declare function findDeniedHookResult(results: readonly ACodeHookResult[]): ACodeHookResult | undefined;
|
|
19
|
+
//# sourceMappingURL=hookBus.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hookBus.d.ts","sourceRoot":"","sources":["../../src/hooks/hookBus.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEzG,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;CAC3D;AAED,qBAAa,YAAY;IAGX,OAAO,CAAC,QAAQ,CAAC,OAAO;IAFpC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA0B;gBAEtB,OAAO,EAAE,mBAAmB;IAEzD,QAAQ,CAAC,OAAO,EAAE,gBAAgB,GAAG,IAAI;IAIzC;;;OAGG;IACG,QAAQ,CAAC,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC;CAuBpG;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,SAAS,eAAe,EAAE,GAAG,eAAe,GAAG,SAAS,CAErG"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
export class ACodeHookBus {
|
|
2
|
+
constructor(options) {
|
|
3
|
+
this.options = options;
|
|
4
|
+
this.handlers = [];
|
|
5
|
+
}
|
|
6
|
+
register(handler) {
|
|
7
|
+
this.handlers.push(handler);
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* 分发 ACode 生命周期 Hook。
|
|
11
|
+
* 主流程:按注册顺序执行 handler -> fail-open 记录错误 -> 遇到 deny 立即返回。
|
|
12
|
+
*/
|
|
13
|
+
async dispatch(name, data) {
|
|
14
|
+
const event = {
|
|
15
|
+
name,
|
|
16
|
+
sessionId: this.options.sessionId,
|
|
17
|
+
timestamp: this.options.now?.() ?? new Date().toISOString(),
|
|
18
|
+
data,
|
|
19
|
+
};
|
|
20
|
+
const results = [];
|
|
21
|
+
for (const handler of this.handlers) {
|
|
22
|
+
try {
|
|
23
|
+
const result = await handler(event);
|
|
24
|
+
if (result) {
|
|
25
|
+
results.push(result);
|
|
26
|
+
if (result.decision === 'deny') {
|
|
27
|
+
return results;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
catch (error) {
|
|
32
|
+
this.options.onError?.(event, error);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return results;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
export function findDeniedHookResult(results) {
|
|
39
|
+
return results.find((result) => result.decision === 'deny');
|
|
40
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export * from './commands/commandRegistry.js';
|
|
2
|
+
export * from './commands/commandLoader.js';
|
|
3
|
+
export * from './commands/commandParser.js';
|
|
4
|
+
export * from './config.js';
|
|
5
|
+
export * from './hooks/hookBus.js';
|
|
6
|
+
export * from './runtime.js';
|
|
7
|
+
export * from './types.js';
|
|
8
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,+BAA+B,CAAC;AAC9C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,aAAa,CAAC;AAC5B,cAAc,oBAAoB,CAAC;AACnC,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export * from './commands/commandRegistry.js';
|
|
2
|
+
export * from './commands/commandLoader.js';
|
|
3
|
+
export * from './commands/commandParser.js';
|
|
4
|
+
export * from './config.js';
|
|
5
|
+
export * from './hooks/hookBus.js';
|
|
6
|
+
export * from './runtime.js';
|
|
7
|
+
export * from './types.js';
|