@travisennis/acai 0.0.11 → 0.0.13
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 +5 -5
- package/dist/agent/index.d.ts.map +1 -1
- package/dist/agent/index.js +2 -5
- package/dist/commands/history/types.d.ts +3 -2
- package/dist/commands/history/types.d.ts.map +1 -1
- package/dist/commands/init-project/utils.d.ts +0 -1
- package/dist/commands/init-project/utils.d.ts.map +1 -1
- package/dist/commands/init-project/utils.js +1 -12
- package/dist/commands/manager.d.ts.map +1 -1
- package/dist/commands/manager.js +6 -19
- 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/share/html-renderer.d.ts.map +1 -1
- package/dist/commands/share/html-renderer.js +54 -48
- 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 +191 -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 -2
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +42 -6
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +98 -68
- 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/manager.d.ts +1 -10
- package/dist/models/manager.d.ts.map +1 -1
- package/dist/models/manager.js +2 -2
- 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 +130 -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 -2
- package/dist/prompts/system-prompt.d.ts.map +1 -1
- package/dist/prompts/system-prompt.js +26 -15
- package/dist/repl/index.d.ts +28 -13
- package/dist/repl/index.d.ts.map +1 -1
- package/dist/repl/index.js +242 -305
- 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 +12 -2
- package/dist/skills/index.d.ts.map +1 -1
- package/dist/skills/index.js +127 -71
- package/dist/terminal/control.d.ts +1 -21
- package/dist/terminal/control.d.ts.map +1 -1
- package/dist/terminal/control.js +1 -32
- package/dist/terminal/formatting.d.ts +0 -33
- package/dist/terminal/formatting.d.ts.map +1 -1
- package/dist/terminal/formatting.js +0 -91
- package/dist/terminal/highlight/theme.d.ts +0 -37
- package/dist/terminal/highlight/theme.d.ts.map +1 -1
- package/dist/terminal/highlight/theme.js +1 -79
- package/dist/terminal/keys.d.ts +0 -97
- package/dist/terminal/keys.d.ts.map +1 -1
- package/dist/terminal/keys.js +0 -194
- package/dist/terminal/select-prompt.d.ts.map +1 -1
- package/dist/terminal/select-prompt.js +65 -51
- package/dist/terminal/style.d.ts +1 -1
- package/dist/terminal/style.d.ts.map +1 -1
- package/dist/terminal/supports-color.d.ts.map +1 -1
- package/dist/terminal/supports-color.js +38 -20
- package/dist/terminal/supports-hyperlinks.d.ts +3 -0
- package/dist/terminal/supports-hyperlinks.d.ts.map +1 -1
- package/dist/terminal/supports-hyperlinks.js +72 -31
- package/dist/terminal/table/layout-manager.d.ts +0 -20
- package/dist/terminal/table/layout-manager.d.ts.map +1 -1
- package/dist/terminal/table/layout-manager.js +68 -44
- package/dist/terminal/table/utils.d.ts +0 -1
- package/dist/terminal/table/utils.d.ts.map +1 -1
- package/dist/terminal/table/utils.js +2 -4
- package/dist/tools/apply-patch.d.ts +5 -3
- package/dist/tools/apply-patch.d.ts.map +1 -1
- package/dist/tools/apply-patch.js +154 -123
- package/dist/tools/bash.d.ts +4 -4
- package/dist/tools/bash.d.ts.map +1 -1
- package/dist/tools/bash.js +27 -13
- package/dist/tools/dynamic-tool-loader.d.ts +17 -3
- package/dist/tools/dynamic-tool-loader.d.ts.map +1 -1
- package/dist/tools/dynamic-tool-loader.js +360 -81
- package/dist/tools/edit-file.d.ts +2 -2
- package/dist/tools/index.d.ts +27 -151
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +16 -21
- package/dist/tools/read-file.d.ts +8 -8
- package/dist/tools/read-file.d.ts.map +1 -1
- package/dist/tools/read-file.js +32 -13
- 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 +64 -14
- package/dist/tools/types.d.ts +8 -2
- package/dist/tools/types.d.ts.map +1 -1
- package/dist/tools/web-fetch.d.ts +8 -12
- package/dist/tools/web-fetch.d.ts.map +1 -1
- package/dist/tools/web-fetch.js +86 -44
- package/dist/tools/web-search.d.ts +4 -8
- package/dist/tools/web-search.d.ts.map +1 -1
- package/dist/tools/web-search.js +41 -33
- package/dist/tui/autocomplete/utils.d.ts +0 -15
- package/dist/tui/autocomplete/utils.d.ts.map +1 -1
- package/dist/tui/autocomplete/utils.js +0 -85
- package/dist/tui/autocomplete.d.ts +1 -1
- package/dist/tui/autocomplete.d.ts.map +1 -1
- package/dist/tui/autocomplete.js +1 -1
- package/dist/tui/components/editor.d.ts +12 -0
- package/dist/tui/components/editor.d.ts.map +1 -1
- package/dist/tui/components/editor.js +181 -195
- 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/input.d.ts +4 -0
- package/dist/tui/components/input.d.ts.map +1 -1
- package/dist/tui/components/input.js +33 -31
- package/dist/tui/components/markdown.d.ts +30 -0
- package/dist/tui/components/markdown.d.ts.map +1 -1
- package/dist/tui/components/markdown.js +274 -242
- package/dist/tui/components/modal.d.ts.map +1 -1
- package/dist/tui/components/modal.js +11 -11
- package/dist/tui/components/select-list.d.ts +5 -0
- package/dist/tui/components/select-list.d.ts.map +1 -1
- package/dist/tui/components/select-list.js +69 -98
- package/dist/tui/components/table.d.ts +6 -0
- package/dist/tui/components/table.d.ts.map +1 -1
- package/dist/tui/components/table.js +61 -52
- package/dist/tui/index.d.ts +1 -8
- package/dist/tui/index.d.ts.map +1 -1
- package/dist/tui/index.js +0 -8
- package/dist/tui/tui.d.ts +9 -0
- package/dist/tui/tui.d.ts.map +1 -1
- package/dist/tui/tui.js +78 -48
- package/dist/tui/utils.d.ts +7 -0
- package/dist/tui/utils.d.ts.map +1 -1
- package/dist/tui/utils.js +117 -53
- package/dist/utils/bash.d.ts.map +1 -1
- package/dist/utils/bash.js +121 -104
- 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 +3 -2
- package/dist/utils/command-protection.d.ts.map +1 -1
- package/dist/utils/command-protection.js +121 -29
- package/dist/utils/filesystem/operations.d.ts +0 -15
- package/dist/utils/filesystem/operations.d.ts.map +1 -1
- package/dist/utils/filesystem/operations.js +1 -38
- package/dist/utils/filesystem/security.d.ts.map +1 -1
- package/dist/utils/filesystem/security.js +22 -15
- package/dist/utils/filetype-detection.d.ts +0 -1
- package/dist/utils/filetype-detection.d.ts.map +1 -1
- package/dist/utils/filetype-detection.js +0 -12
- package/dist/utils/formatting.d.ts +0 -30
- package/dist/utils/formatting.d.ts.map +1 -1
- package/dist/utils/formatting.js +0 -44
- package/dist/utils/git.d.ts +4 -6
- package/dist/utils/git.d.ts.map +1 -1
- package/dist/utils/git.js +36 -46
- package/dist/utils/ignore.d.ts +1 -1
- package/dist/utils/ignore.d.ts.map +1 -1
- package/dist/utils/ignore.js +1 -1
- package/dist/utils/parsing.d.ts +1 -1
- package/dist/utils/parsing.d.ts.map +1 -1
- package/dist/utils/process.d.ts.map +1 -1
- package/dist/utils/process.js +77 -79
- package/dist/utils/yaml.d.ts +0 -1
- package/dist/utils/yaml.d.ts.map +1 -1
- package/dist/utils/yaml.js +80 -89
- package/dist/utils/zod.d.ts +0 -3
- package/dist/utils/zod.d.ts.map +1 -1
- package/dist/utils/zod.js +0 -7
- package/package.json +32 -29
- package/dist/agent/sub-agent.d.ts +0 -23
- package/dist/agent/sub-agent.d.ts.map +0 -1
- package/dist/agent/sub-agent.js +0 -109
- package/dist/commands/add-directory/index.d.ts +0 -3
- package/dist/commands/add-directory/index.d.ts.map +0 -1
- package/dist/commands/add-directory/index.js +0 -50
- package/dist/commands/add-directory/utils.d.ts +0 -3
- package/dist/commands/add-directory/utils.d.ts.map +0 -1
- package/dist/commands/add-directory/utils.js +0 -15
- package/dist/commands/clear/index.d.ts +0 -3
- package/dist/commands/clear/index.d.ts.map +0 -1
- package/dist/commands/clear/index.js +0 -13
- package/dist/commands/generate-rules/index.d.ts +0 -3
- package/dist/commands/generate-rules/index.d.ts.map +0 -1
- package/dist/commands/generate-rules/index.js +0 -206
- package/dist/commands/generate-rules/service.d.ts +0 -22
- package/dist/commands/generate-rules/service.d.ts.map +0 -1
- package/dist/commands/generate-rules/service.js +0 -103
- package/dist/commands/generate-rules/utils.d.ts +0 -5
- package/dist/commands/generate-rules/utils.d.ts.map +0 -1
- package/dist/commands/generate-rules/utils.js +0 -25
- package/dist/commands/handoff/index.d.ts +0 -3
- package/dist/commands/handoff/index.d.ts.map +0 -1
- package/dist/commands/handoff/index.js +0 -97
- package/dist/commands/handoff/utils.d.ts +0 -4
- package/dist/commands/handoff/utils.d.ts.map +0 -1
- package/dist/commands/handoff/utils.js +0 -123
- package/dist/commands/list-directories/index.d.ts +0 -3
- package/dist/commands/list-directories/index.d.ts.map +0 -1
- package/dist/commands/list-directories/index.js +0 -35
- package/dist/commands/pickup/index.d.ts +0 -3
- package/dist/commands/pickup/index.d.ts.map +0 -1
- package/dist/commands/pickup/index.js +0 -141
- package/dist/commands/pickup/types.d.ts +0 -6
- package/dist/commands/pickup/types.d.ts.map +0 -1
- package/dist/commands/pickup/types.js +0 -1
- package/dist/commands/pickup/utils.d.ts +0 -7
- package/dist/commands/pickup/utils.d.ts.map +0 -1
- package/dist/commands/pickup/utils.js +0 -56
- package/dist/commands/remove-directory/index.d.ts +0 -3
- package/dist/commands/remove-directory/index.d.ts.map +0 -1
- package/dist/commands/remove-directory/index.js +0 -55
- package/dist/commands/review/index.d.ts +0 -3
- package/dist/commands/review/index.d.ts.map +0 -1
- package/dist/commands/review/index.js +0 -12
- package/dist/commands/review/review-panel.d.ts +0 -3
- package/dist/commands/review/review-panel.d.ts.map +0 -1
- package/dist/commands/review/review-panel.js +0 -186
- package/dist/commands/review/utils.d.ts +0 -18
- package/dist/commands/review/utils.d.ts.map +0 -1
- package/dist/commands/review/utils.js +0 -146
- package/dist/commands/shell/index.d.ts +0 -3
- package/dist/commands/shell/index.d.ts.map +0 -1
- package/dist/commands/shell/index.js +0 -96
- 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/dist/subagents/index.d.ts +0 -16
- package/dist/subagents/index.d.ts.map +0 -1
- package/dist/subagents/index.js +0 -231
- package/dist/terminal/index.d.ts +0 -9
- package/dist/terminal/index.d.ts.map +0 -1
- package/dist/terminal/index.js +0 -8
- package/dist/tools/agent.d.ts +0 -27
- package/dist/tools/agent.d.ts.map +0 -1
- package/dist/tools/agent.js +0 -81
- package/dist/tools/directory-tree.d.ts +0 -28
- package/dist/tools/directory-tree.d.ts.map +0 -1
- package/dist/tools/directory-tree.js +0 -152
- package/dist/tools/glob.d.ts +0 -35
- package/dist/tools/glob.d.ts.map +0 -1
- package/dist/tools/glob.js +0 -159
- package/dist/tools/grep.d.ts +0 -100
- package/dist/tools/grep.d.ts.map +0 -1
- package/dist/tools/grep.js +0 -601
- package/dist/tools/ls.d.ts +0 -26
- package/dist/tools/ls.d.ts.map +0 -1
- package/dist/tools/ls.js +0 -82
- package/dist/tui/components/header.d.ts +0 -21
- package/dist/tui/components/header.d.ts.map +0 -1
- package/dist/tui/components/header.js +0 -63
- package/dist/utils/bash/parse.d.ts +0 -19
- package/dist/utils/bash/parse.d.ts.map +0 -1
- package/dist/utils/bash/parse.js +0 -223
- package/dist/utils/bash/quote.d.ts +0 -6
- package/dist/utils/bash/quote.d.ts.map +0 -1
- package/dist/utils/bash/quote.js +0 -23
- package/dist/utils/generators.d.ts +0 -3
- package/dist/utils/generators.d.ts.map +0 -1
- package/dist/utils/generators.js +0 -25
- package/dist/utils/glob.d.ts +0 -52
- package/dist/utils/glob.d.ts.map +0 -1
- package/dist/utils/glob.js +0 -376
|
@@ -38,47 +38,53 @@ function parsePatchHeader(lines, startIdx) {
|
|
|
38
38
|
}
|
|
39
39
|
return null;
|
|
40
40
|
}
|
|
41
|
+
function parseOneChunk(lines, startIdx) {
|
|
42
|
+
const contextLine = lines[startIdx].substring(2).trim();
|
|
43
|
+
let i = startIdx + 1;
|
|
44
|
+
const oldLines = [];
|
|
45
|
+
const newLines = [];
|
|
46
|
+
let isEndOfFile = false;
|
|
47
|
+
while (i < lines.length && !lines[i].startsWith("@@")) {
|
|
48
|
+
const changeLine = lines[i];
|
|
49
|
+
if (changeLine === "*** End of File") {
|
|
50
|
+
isEndOfFile = true;
|
|
51
|
+
i++;
|
|
52
|
+
break;
|
|
53
|
+
}
|
|
54
|
+
if (changeLine.startsWith("***")) {
|
|
55
|
+
break;
|
|
56
|
+
}
|
|
57
|
+
if (changeLine.startsWith(" ")) {
|
|
58
|
+
const content = changeLine.substring(1);
|
|
59
|
+
oldLines.push(content);
|
|
60
|
+
newLines.push(content);
|
|
61
|
+
}
|
|
62
|
+
else if (changeLine.startsWith("-")) {
|
|
63
|
+
oldLines.push(changeLine.substring(1));
|
|
64
|
+
}
|
|
65
|
+
else if (changeLine.startsWith("+")) {
|
|
66
|
+
newLines.push(changeLine.substring(1));
|
|
67
|
+
}
|
|
68
|
+
i++;
|
|
69
|
+
}
|
|
70
|
+
return {
|
|
71
|
+
chunk: {
|
|
72
|
+
oldLines,
|
|
73
|
+
newLines,
|
|
74
|
+
changeContext: contextLine || undefined,
|
|
75
|
+
isEndOfFile: isEndOfFile || undefined,
|
|
76
|
+
},
|
|
77
|
+
nextIdx: i,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
41
80
|
function parseUpdateFileChunks(lines, startIdx) {
|
|
42
81
|
const chunks = [];
|
|
43
82
|
let i = startIdx;
|
|
44
83
|
while (i < lines.length && !lines[i].startsWith("***")) {
|
|
45
84
|
if (lines[i].startsWith("@@")) {
|
|
46
|
-
const
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
const newLines = [];
|
|
50
|
-
let isEndOfFile = false;
|
|
51
|
-
while (i < lines.length && !lines[i].startsWith("@@")) {
|
|
52
|
-
const changeLine = lines[i];
|
|
53
|
-
// Check for end of file marker first (before general *** check)
|
|
54
|
-
if (changeLine === "*** End of File") {
|
|
55
|
-
isEndOfFile = true;
|
|
56
|
-
i++;
|
|
57
|
-
break;
|
|
58
|
-
}
|
|
59
|
-
// Check for other *** markers (new file operations)
|
|
60
|
-
if (changeLine.startsWith("***")) {
|
|
61
|
-
break;
|
|
62
|
-
}
|
|
63
|
-
if (changeLine.startsWith(" ")) {
|
|
64
|
-
const content = changeLine.substring(1);
|
|
65
|
-
oldLines.push(content);
|
|
66
|
-
newLines.push(content);
|
|
67
|
-
}
|
|
68
|
-
else if (changeLine.startsWith("-")) {
|
|
69
|
-
oldLines.push(changeLine.substring(1));
|
|
70
|
-
}
|
|
71
|
-
else if (changeLine.startsWith("+")) {
|
|
72
|
-
newLines.push(changeLine.substring(1));
|
|
73
|
-
}
|
|
74
|
-
i++;
|
|
75
|
-
}
|
|
76
|
-
chunks.push({
|
|
77
|
-
oldLines,
|
|
78
|
-
newLines,
|
|
79
|
-
changeContext: contextLine || undefined,
|
|
80
|
-
isEndOfFile: isEndOfFile || undefined,
|
|
81
|
-
});
|
|
85
|
+
const { chunk, nextIdx } = parseOneChunk(lines, i);
|
|
86
|
+
chunks.push(chunk);
|
|
87
|
+
i = nextIdx;
|
|
82
88
|
}
|
|
83
89
|
else {
|
|
84
90
|
i++;
|
|
@@ -175,36 +181,50 @@ function applyReplacements(lines, replacements) {
|
|
|
175
181
|
}
|
|
176
182
|
return result;
|
|
177
183
|
}
|
|
178
|
-
function
|
|
184
|
+
function findContextLine(originalLines, changeContext, lineIndex, filePath) {
|
|
185
|
+
const contextIdx = seekSequence(originalLines, [changeContext], lineIndex);
|
|
186
|
+
if (contextIdx === -1) {
|
|
187
|
+
throw new Error(`Failed to find context '${changeContext}' in ${filePath}`);
|
|
188
|
+
}
|
|
189
|
+
return contextIdx + 1;
|
|
190
|
+
}
|
|
191
|
+
function computeInsertionIndex(originalLines) {
|
|
192
|
+
return originalLines.length > 0 &&
|
|
193
|
+
originalLines[originalLines.length - 1] === ""
|
|
194
|
+
? originalLines.length - 1
|
|
195
|
+
: originalLines.length;
|
|
196
|
+
}
|
|
197
|
+
function findPatternWithFallback(originalLines, oldLines, newLines, lineIndex) {
|
|
198
|
+
let pattern = oldLines;
|
|
199
|
+
let newSlice = newLines;
|
|
200
|
+
let found = seekSequence(originalLines, pattern, lineIndex);
|
|
201
|
+
if (found === -1 &&
|
|
202
|
+
pattern.length > 0 &&
|
|
203
|
+
pattern[pattern.length - 1] === "") {
|
|
204
|
+
pattern = pattern.slice(0, -1);
|
|
205
|
+
if (newSlice.length > 0 && newSlice[newSlice.length - 1] === "") {
|
|
206
|
+
newSlice = newSlice.slice(0, -1);
|
|
207
|
+
}
|
|
208
|
+
found = seekSequence(originalLines, pattern, lineIndex);
|
|
209
|
+
}
|
|
210
|
+
return { pattern, newSlice, found };
|
|
211
|
+
}
|
|
212
|
+
export function computeReplacements(originalLines, filePath, chunks) {
|
|
179
213
|
const replacements = [];
|
|
180
214
|
let lineIndex = 0;
|
|
181
215
|
for (const chunk of chunks) {
|
|
182
216
|
if (chunk.changeContext) {
|
|
183
|
-
|
|
184
|
-
if (contextIdx === -1) {
|
|
185
|
-
throw new Error(`Failed to find context '${chunk.changeContext}' in ${filePath}`);
|
|
186
|
-
}
|
|
187
|
-
lineIndex = contextIdx + 1;
|
|
217
|
+
lineIndex = findContextLine(originalLines, chunk.changeContext, lineIndex, filePath);
|
|
188
218
|
}
|
|
189
219
|
if (chunk.oldLines.length === 0) {
|
|
190
|
-
|
|
191
|
-
originalLines
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
220
|
+
replacements.push([
|
|
221
|
+
computeInsertionIndex(originalLines),
|
|
222
|
+
0,
|
|
223
|
+
chunk.newLines,
|
|
224
|
+
]);
|
|
195
225
|
continue;
|
|
196
226
|
}
|
|
197
|
-
|
|
198
|
-
let newSlice = chunk.newLines;
|
|
199
|
-
let found = seekSequence(originalLines, pattern, lineIndex);
|
|
200
|
-
if (found === -1 &&
|
|
201
|
-
pattern.length > 0 &&
|
|
202
|
-
pattern[pattern.length - 1] === "") {
|
|
203
|
-
pattern = pattern.slice(0, -1);
|
|
204
|
-
if (newSlice.length > 0 && newSlice[newSlice.length - 1] === "")
|
|
205
|
-
newSlice = newSlice.slice(0, -1);
|
|
206
|
-
found = seekSequence(originalLines, pattern, lineIndex);
|
|
207
|
-
}
|
|
227
|
+
const { pattern, newSlice, found } = findPatternWithFallback(originalLines, chunk.oldLines, chunk.newLines, lineIndex);
|
|
208
228
|
if (found !== -1) {
|
|
209
229
|
replacements.push([found, pattern.length, newSlice]);
|
|
210
230
|
lineIndex = found + pattern.length;
|
|
@@ -242,39 +262,91 @@ function deriveNewContentsFromChunks(fileAbsPath, chunks) {
|
|
|
242
262
|
content: newContent,
|
|
243
263
|
};
|
|
244
264
|
}
|
|
245
|
-
async function
|
|
265
|
+
async function applyAddChange(change, changed) {
|
|
266
|
+
const dir = path.dirname(change.path);
|
|
267
|
+
if (dir !== "." && dir !== "/")
|
|
268
|
+
await fsp.mkdir(dir, { recursive: true });
|
|
269
|
+
await fsp.writeFile(change.path, change.content, "utf-8");
|
|
270
|
+
changed.push(change.path);
|
|
271
|
+
}
|
|
272
|
+
async function applyDeleteChange(change, changed) {
|
|
273
|
+
await fsp.unlink(change.path).catch(() => { });
|
|
274
|
+
changed.push(change.path);
|
|
275
|
+
}
|
|
276
|
+
async function applyUpdateChange(change, changed) {
|
|
277
|
+
if (change.movePath) {
|
|
278
|
+
const dir = path.dirname(change.movePath);
|
|
279
|
+
if (dir !== "." && dir !== "/")
|
|
280
|
+
await fsp.mkdir(dir, { recursive: true });
|
|
281
|
+
await fsp.writeFile(change.movePath, change.newContent, "utf-8");
|
|
282
|
+
await fsp.unlink(change.path).catch(() => { });
|
|
283
|
+
changed.push(change.movePath);
|
|
284
|
+
return;
|
|
285
|
+
}
|
|
286
|
+
await fsp.writeFile(change.path, change.newContent, "utf-8");
|
|
287
|
+
changed.push(change.path);
|
|
288
|
+
}
|
|
289
|
+
export async function applyChanges(changes, signal) {
|
|
246
290
|
const changed = [];
|
|
247
291
|
for (const change of changes) {
|
|
248
292
|
if (signal?.aborted)
|
|
249
293
|
throw new Error("Cancelled");
|
|
250
294
|
if (change.type === "add") {
|
|
251
|
-
|
|
252
|
-
if (dir !== "." && dir !== "/")
|
|
253
|
-
await fsp.mkdir(dir, { recursive: true });
|
|
254
|
-
await fsp.writeFile(change.path, change.content, "utf-8");
|
|
255
|
-
changed.push(change.path);
|
|
295
|
+
await applyAddChange(change, changed);
|
|
256
296
|
continue;
|
|
257
297
|
}
|
|
258
298
|
if (change.type === "delete") {
|
|
259
|
-
await
|
|
260
|
-
changed.push(change.path);
|
|
261
|
-
continue;
|
|
262
|
-
}
|
|
263
|
-
// update
|
|
264
|
-
if (change.movePath) {
|
|
265
|
-
const dir = path.dirname(change.movePath);
|
|
266
|
-
if (dir !== "." && dir !== "/")
|
|
267
|
-
await fsp.mkdir(dir, { recursive: true });
|
|
268
|
-
await fsp.writeFile(change.movePath, change.newContent, "utf-8");
|
|
269
|
-
await fsp.unlink(change.path).catch(() => { });
|
|
270
|
-
changed.push(change.movePath);
|
|
299
|
+
await applyDeleteChange(change, changed);
|
|
271
300
|
continue;
|
|
272
301
|
}
|
|
273
|
-
await
|
|
274
|
-
changed.push(change.path);
|
|
302
|
+
await applyUpdateChange(change, changed);
|
|
275
303
|
}
|
|
276
304
|
return changed;
|
|
277
305
|
}
|
|
306
|
+
async function processHunk(hunk, root, allowedDirectories, projectConfig, primaryDir, abortSignal) {
|
|
307
|
+
if (abortSignal?.aborted) {
|
|
308
|
+
throw new Error("Cancelled");
|
|
309
|
+
}
|
|
310
|
+
const p = resolvePathInRoot(root, hunk.path);
|
|
311
|
+
const validPath = await validatePath(p.abs, allowedDirectories, {
|
|
312
|
+
requireExistence: hunk.type !== "add",
|
|
313
|
+
abortSignal,
|
|
314
|
+
});
|
|
315
|
+
if (hunk.type === "add") {
|
|
316
|
+
return {
|
|
317
|
+
change: { type: "add", path: validPath, content: hunk.contents },
|
|
318
|
+
};
|
|
319
|
+
}
|
|
320
|
+
if (hunk.type === "delete") {
|
|
321
|
+
validateFileNotReadOnly(validPath, projectConfig, primaryDir);
|
|
322
|
+
return { change: { type: "delete", path: validPath } };
|
|
323
|
+
}
|
|
324
|
+
// update
|
|
325
|
+
validateFileNotReadOnly(validPath, projectConfig, primaryDir);
|
|
326
|
+
let moveAbs;
|
|
327
|
+
if (hunk.movePath) {
|
|
328
|
+
const moveP = resolvePathInRoot(root, hunk.movePath);
|
|
329
|
+
moveAbs = await validatePath(moveP.abs, allowedDirectories, {
|
|
330
|
+
requireExistence: false,
|
|
331
|
+
abortSignal,
|
|
332
|
+
});
|
|
333
|
+
}
|
|
334
|
+
const upd = deriveNewContentsFromChunks(validPath, hunk.chunks);
|
|
335
|
+
const change = {
|
|
336
|
+
type: "update",
|
|
337
|
+
path: validPath,
|
|
338
|
+
movePath: moveAbs,
|
|
339
|
+
newContent: upd.content,
|
|
340
|
+
unifiedDiff: upd.unifiedDiff,
|
|
341
|
+
};
|
|
342
|
+
if (upd.unifiedDiff) {
|
|
343
|
+
return {
|
|
344
|
+
change,
|
|
345
|
+
diffLine: `*** Update File: ${path.relative(root, moveAbs ?? validPath)}\n${upd.unifiedDiff}\n`,
|
|
346
|
+
};
|
|
347
|
+
}
|
|
348
|
+
return { change };
|
|
349
|
+
}
|
|
278
350
|
export const createApplyPatchTool = async (options) => {
|
|
279
351
|
const { primaryDir, allowedDirs } = options.workspace;
|
|
280
352
|
const allowedDirectories = allowedDirs ?? [primaryDir];
|
|
@@ -316,56 +388,15 @@ export const createApplyPatchTool = async (options) => {
|
|
|
316
388
|
if (hunks.length === 0) {
|
|
317
389
|
return "No changes found in patch.";
|
|
318
390
|
}
|
|
319
|
-
// Build a list of resolved file changes (absolute paths), and a diff preview.
|
|
320
391
|
const changes = [];
|
|
321
392
|
let diffOutput = "";
|
|
322
393
|
for (const hunk of hunks) {
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
const validPath = await validatePath(p.abs, allowedDirectories, {
|
|
328
|
-
requireExistence: hunk.type !== "add",
|
|
329
|
-
abortSignal,
|
|
330
|
-
});
|
|
331
|
-
if (hunk.type === "add") {
|
|
332
|
-
changes.push({
|
|
333
|
-
type: "add",
|
|
334
|
-
path: validPath,
|
|
335
|
-
content: hunk.contents,
|
|
336
|
-
});
|
|
337
|
-
continue;
|
|
338
|
-
}
|
|
339
|
-
if (hunk.type === "delete") {
|
|
340
|
-
// Validate file is not read-only before deletion
|
|
341
|
-
validateFileNotReadOnly(validPath, projectConfig, primaryDir);
|
|
342
|
-
changes.push({ type: "delete", path: validPath });
|
|
343
|
-
continue;
|
|
344
|
-
}
|
|
345
|
-
// update - validate file is not read-only
|
|
346
|
-
validateFileNotReadOnly(validPath, projectConfig, primaryDir);
|
|
347
|
-
let moveAbs;
|
|
348
|
-
if (hunk.movePath) {
|
|
349
|
-
const moveP = resolvePathInRoot(root, hunk.movePath);
|
|
350
|
-
moveAbs = await validatePath(moveP.abs, allowedDirectories, {
|
|
351
|
-
requireExistence: false,
|
|
352
|
-
abortSignal,
|
|
353
|
-
});
|
|
354
|
-
}
|
|
355
|
-
const upd = deriveNewContentsFromChunks(validPath, hunk.chunks);
|
|
356
|
-
changes.push({
|
|
357
|
-
type: "update",
|
|
358
|
-
path: validPath,
|
|
359
|
-
movePath: moveAbs,
|
|
360
|
-
newContent: upd.content,
|
|
361
|
-
unifiedDiff: upd.unifiedDiff,
|
|
362
|
-
});
|
|
363
|
-
if (upd.unifiedDiff) {
|
|
364
|
-
diffOutput += `*** Update File: ${path.relative(root, moveAbs ?? validPath)}\n`;
|
|
365
|
-
diffOutput += `${upd.unifiedDiff}\n`;
|
|
394
|
+
const { change, diffLine } = await processHunk(hunk, root, allowedDirectories, projectConfig, primaryDir, abortSignal);
|
|
395
|
+
changes.push(change);
|
|
396
|
+
if (diffLine) {
|
|
397
|
+
diffOutput += diffLine;
|
|
366
398
|
}
|
|
367
399
|
}
|
|
368
|
-
// Apply changes
|
|
369
400
|
const changedAbs = await applyChanges(changes, abortSignal);
|
|
370
401
|
const changedRel = changedAbs.map((p) => path.relative(root, p));
|
|
371
402
|
clearProjectStatusCache();
|
package/dist/tools/bash.d.ts
CHANGED
|
@@ -6,8 +6,8 @@ export declare const BashTool: {
|
|
|
6
6
|
};
|
|
7
7
|
declare const inputSchema: z.ZodObject<{
|
|
8
8
|
command: z.ZodString;
|
|
9
|
-
cwd: z.
|
|
10
|
-
timeout: z.
|
|
9
|
+
cwd: z.ZodPreprocess<z.ZodNullable<z.ZodString>>;
|
|
10
|
+
timeout: z.ZodPreprocess<z.ZodNullable<z.ZodCoercedNumber<unknown>>>;
|
|
11
11
|
background: z.ZodOptional<z.ZodBoolean>;
|
|
12
12
|
}, z.core.$strip>;
|
|
13
13
|
type BashInputSchema = z.infer<typeof inputSchema>;
|
|
@@ -19,8 +19,8 @@ export declare const createBashTool: (options: {
|
|
|
19
19
|
description: string;
|
|
20
20
|
inputSchema: z.ZodObject<{
|
|
21
21
|
command: z.ZodString;
|
|
22
|
-
cwd: z.
|
|
23
|
-
timeout: z.
|
|
22
|
+
cwd: z.ZodPreprocess<z.ZodNullable<z.ZodString>>;
|
|
23
|
+
timeout: z.ZodPreprocess<z.ZodNullable<z.ZodCoercedNumber<unknown>>>;
|
|
24
24
|
background: z.ZodOptional<z.ZodBoolean>;
|
|
25
25
|
}, z.core.$strip>;
|
|
26
26
|
};
|
package/dist/tools/bash.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bash.d.ts","sourceRoot":"","sources":["../../source/tools/bash.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"bash.d.ts","sourceRoot":"","sources":["../../source/tools/bash.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAepD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AA0CvD,eAAO,MAAM,QAAQ;;CAEpB,CAAC;AAkNF,QAAA,MAAM,WAAW;;;;;iBAkBf,CAAC;AAEH,KAAK,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,CAAC;AAEnD,eAAO,MAAM,cAAc,GAAU,SAAS;IAC5C,SAAS,EAAE,gBAAgB,CAAC;IAC5B,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC9B;;;;;;;;;;yBA8GwB,eAAe;mDAIK,eAAe,mBACrC,oBAAoB,GACpC,OAAO,CAAC,MAAM,CAAC;EA6BrB,CAAC"}
|
package/dist/tools/bash.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
// import { execSync } from "node:child_process";
|
|
2
1
|
import { randomBytes } from "node:crypto";
|
|
3
2
|
import { mkdirSync, writeFileSync } from "node:fs";
|
|
4
3
|
import { dirname } from "node:path";
|
|
@@ -6,6 +5,7 @@ import { z } from "zod";
|
|
|
6
5
|
import { initExecutionEnvironment } from "../execution/index.js";
|
|
7
6
|
import style from "../terminal/style.js";
|
|
8
7
|
import { resolveCwd, validatePaths } from "../utils/bash.js";
|
|
8
|
+
import { formatBinaryMessage, isBinaryOutput, saveBinaryOutput, } from "../utils/binary-output.js";
|
|
9
9
|
import { detectDestructiveCommand, formatBlockedCommandMessage, } from "../utils/command-protection.js";
|
|
10
10
|
import { expandEnvVars } from "../utils/env-expand.js";
|
|
11
11
|
import { logger } from "../utils/logger.js";
|
|
@@ -206,7 +206,7 @@ export const BashTool = {
|
|
|
206
206
|
// }
|
|
207
207
|
// Tools available:
|
|
208
208
|
// ${installedTools}`;
|
|
209
|
-
const simpleDescription = "Run terminal commands.";
|
|
209
|
+
const simpleDescription = "Run terminal commands. When you need to run multiple independent commands (e.g. `git status`, `git diff`, `git log`; or several `rg`/`grep` searches with different patterns), ALWAYS issue multiple Bash tool calls in the same assistant message rather than running one, waiting for the result, then running the next. The runtime executes parallel tool calls concurrently, so batching independent commands is several times faster than serial calls. Only sequence commands when one truly depends on the output of another.";
|
|
210
210
|
// Command execution timeout in milliseconds
|
|
211
211
|
const DEFAULT_TIMEOUT = 1.5 * 60 * 1000; // 1.5 minutes
|
|
212
212
|
// Maximum output size in bytes (50KB) to prevent context window exhaustion
|
|
@@ -214,15 +214,19 @@ const MAX_OUTPUT_SIZE = 50 * 1024;
|
|
|
214
214
|
/**
|
|
215
215
|
* Truncates output if it exceeds MAX_OUTPUT_SIZE and adds a clear message.
|
|
216
216
|
* This prevents extremely large outputs from exhausting the context window.
|
|
217
|
+
* The footer is always appended at the end, even when output is truncated.
|
|
217
218
|
*/
|
|
218
|
-
function truncateOutput(output) {
|
|
219
|
+
function truncateOutput(output, footer) {
|
|
220
|
+
if (output.length === 0) {
|
|
221
|
+
return footer;
|
|
222
|
+
}
|
|
219
223
|
if (output.length <= MAX_OUTPUT_SIZE) {
|
|
220
|
-
return output
|
|
224
|
+
return `${output}\n${footer}`;
|
|
221
225
|
}
|
|
222
226
|
const truncatedLength = MAX_OUTPUT_SIZE;
|
|
223
227
|
const originalLength = output.length;
|
|
224
228
|
const truncated = output.slice(0, truncatedLength);
|
|
225
|
-
return `${truncated}\n\n[OUTPUT TRUNCATED: ${originalLength.toLocaleString()} characters total, showing first ${truncatedLength.toLocaleString()} characters. The output was too large and was truncated to prevent context window exhaustion. Consider using commands that produce smaller output (e.g., head, tail with line limits, or redirecting to a file).]`;
|
|
229
|
+
return `${truncated}\n\n[OUTPUT TRUNCATED: ${originalLength.toLocaleString()} characters total, showing first ${truncatedLength.toLocaleString()} characters. The output was too large and was truncated to prevent context window exhaustion. Consider using commands that produce smaller output (e.g., head, tail with line limits, or redirecting to a file).]\n${footer}`;
|
|
226
230
|
}
|
|
227
231
|
const inputSchema = z.object({
|
|
228
232
|
command: z.string().describe("Full CLI command to execute."),
|
|
@@ -283,6 +287,7 @@ export const createBashTool = async (options) => {
|
|
|
283
287
|
return `Background process started with PID: ${proc.pid}`;
|
|
284
288
|
}
|
|
285
289
|
async function executeSync(cmd, cwd, timeout, signal) {
|
|
290
|
+
const startTime = Date.now();
|
|
286
291
|
const { output, exitCode, error } = await execEnv.executeCommand(cmd, {
|
|
287
292
|
cwd,
|
|
288
293
|
timeout,
|
|
@@ -291,16 +296,25 @@ export const createBashTool = async (options) => {
|
|
|
291
296
|
captureStderr: true,
|
|
292
297
|
throwOnError: false,
|
|
293
298
|
});
|
|
299
|
+
const elapsedMs = Date.now() - startTime;
|
|
300
|
+
const timeStr = elapsedMs < 1000 ? `${elapsedMs}ms` : `${(elapsedMs / 1000).toFixed(1)}s`;
|
|
301
|
+
const metadataFooter = `[exit:${exitCode} | ${timeStr}]`;
|
|
294
302
|
if (exitCode !== 0) {
|
|
295
|
-
const
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
303
|
+
const execError = error;
|
|
304
|
+
const wasKilled = execError?.killed === true || execError?.signal != null;
|
|
305
|
+
if (wasKilled) {
|
|
306
|
+
const timeoutOutput = output || `Command timed out after ${timeout.toLocaleString()}ms`;
|
|
307
|
+
return truncateOutput(timeoutOutput, metadataFooter);
|
|
308
|
+
}
|
|
309
|
+
return truncateOutput(output, metadataFooter);
|
|
310
|
+
}
|
|
311
|
+
// Check for binary output and handle specially
|
|
312
|
+
if (isBinaryOutput(output)) {
|
|
313
|
+
const saveResult = saveBinaryOutput(output);
|
|
314
|
+
const binaryMessage = formatBinaryMessage(saveResult);
|
|
315
|
+
return `${binaryMessage}\n${metadataFooter}`;
|
|
302
316
|
}
|
|
303
|
-
return truncateOutput(output);
|
|
317
|
+
return truncateOutput(output, metadataFooter);
|
|
304
318
|
}
|
|
305
319
|
return {
|
|
306
320
|
toolDef: {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
import type { ToolExecutionOptions } from "./types.ts";
|
|
2
|
+
import type { SessionContext, ToolExecutionOptions } from "./types.ts";
|
|
3
3
|
declare const toolMetadataSchema: z.ZodObject<{
|
|
4
4
|
name: z.ZodString;
|
|
5
5
|
description: z.ZodString;
|
|
@@ -17,7 +17,20 @@ declare const toolMetadataSchema: z.ZodObject<{
|
|
|
17
17
|
needsApproval: z.ZodDefault<z.ZodBoolean>;
|
|
18
18
|
}, z.core.$strip>;
|
|
19
19
|
type ToolMetadata = z.infer<typeof toolMetadataSchema>;
|
|
20
|
-
|
|
20
|
+
interface InterpreterResult {
|
|
21
|
+
command: string;
|
|
22
|
+
args: string[];
|
|
23
|
+
}
|
|
24
|
+
export declare function getShebang(scriptPath: string): string | null;
|
|
25
|
+
export declare function parseShebang(shebang: string, scriptPath: string): InterpreterResult;
|
|
26
|
+
export declare function resolveToolInterpreter(scriptPath: string): InterpreterResult | null;
|
|
27
|
+
export declare function parseTextSchema(content: string): ToolMetadata | null;
|
|
28
|
+
/**
|
|
29
|
+
* Processes child process stdout/stderr into a result string.
|
|
30
|
+
* Trims, truncates oversized output, falls back to stderr or a placeholder,
|
|
31
|
+
* and attempts JSON parsing for structured output.
|
|
32
|
+
*/
|
|
33
|
+
export declare function processChildOutput(stdout: string, stderr: string): string;
|
|
21
34
|
interface DynamicToolObject {
|
|
22
35
|
toolDef: {
|
|
23
36
|
description: string;
|
|
@@ -25,9 +38,10 @@ interface DynamicToolObject {
|
|
|
25
38
|
};
|
|
26
39
|
execute: (input: Record<string, unknown>, options: ToolExecutionOptions) => Promise<string>;
|
|
27
40
|
}
|
|
28
|
-
export declare function loadDynamicTools({ baseDir, existingToolNames, }: {
|
|
41
|
+
export declare function loadDynamicTools({ baseDir, existingToolNames, sessionContext, }: {
|
|
29
42
|
baseDir: string;
|
|
30
43
|
existingToolNames?: string[];
|
|
44
|
+
sessionContext?: SessionContext;
|
|
31
45
|
}): Promise<Record<string, DynamicToolObject>>;
|
|
32
46
|
export {};
|
|
33
47
|
//# sourceMappingURL=dynamic-tool-loader.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dynamic-tool-loader.d.ts","sourceRoot":"","sources":["../../source/tools/dynamic-tool-loader.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"dynamic-tool-loader.d.ts","sourceRoot":"","sources":["../../source/tools/dynamic-tool-loader.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,KAAK,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAGvE,QAAA,MAAM,kBAAkB;;;;;;;;;;;;;;;iBAatB,CAAC;AAEH,KAAK,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAMvD,UAAU,iBAAiB;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB;AAyBD,wBAAgB,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAc5D;AAED,wBAAgB,YAAY,CAC1B,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,GACjB,iBAAiB,CAUnB;AAED,wBAAgB,sBAAsB,CACpC,UAAU,EAAE,MAAM,GACjB,iBAAiB,GAAG,IAAI,CA0B1B;AAED,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI,CA4CpE;AA4LD;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CA4BzE;AAoFD,UAAU,iBAAiB;IACzB,OAAO,EAAE;QACP,WAAW,EAAE,MAAM,CAAC;QAEpB,WAAW,EAAE,GAAG,CAAC;KAClB,CAAC;IACF,OAAO,EAAE,CACP,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,OAAO,EAAE,oBAAoB,KAC1B,OAAO,CAAC,MAAM,CAAC,CAAC;CACtB;AAwED,wBAAsB,gBAAgB,CAAC,EACrC,OAAO,EACP,iBAAsB,EACtB,cAAc,GACf,EAAE;IACD,OAAO,EAAE,MAAM,CAAC;IAChB,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC7B,cAAc,CAAC,EAAE,cAAc,CAAC;CACjC,8CAiKA"}
|