btca-server 1.0.962 → 2.0.0

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.
Files changed (43) hide show
  1. package/package.json +3 -3
  2. package/src/agent/agent.test.ts +31 -24
  3. package/src/agent/index.ts +8 -2
  4. package/src/agent/loop.ts +303 -346
  5. package/src/agent/service.ts +252 -233
  6. package/src/agent/types.ts +2 -2
  7. package/src/collections/index.ts +2 -1
  8. package/src/collections/service.ts +352 -345
  9. package/src/config/config.test.ts +3 -1
  10. package/src/config/index.ts +615 -727
  11. package/src/config/remote.ts +214 -369
  12. package/src/context/index.ts +6 -12
  13. package/src/context/transaction.ts +23 -30
  14. package/src/effect/errors.ts +45 -0
  15. package/src/effect/layers.ts +26 -0
  16. package/src/effect/runtime.ts +19 -0
  17. package/src/effect/services.ts +154 -0
  18. package/src/index.ts +291 -369
  19. package/src/metrics/index.ts +46 -46
  20. package/src/pricing/models-dev.ts +104 -106
  21. package/src/providers/auth.ts +159 -200
  22. package/src/providers/index.ts +19 -2
  23. package/src/providers/model.ts +115 -135
  24. package/src/providers/openai.ts +3 -3
  25. package/src/resources/impls/git.ts +123 -146
  26. package/src/resources/impls/npm.test.ts +16 -5
  27. package/src/resources/impls/npm.ts +66 -75
  28. package/src/resources/index.ts +6 -1
  29. package/src/resources/schema.ts +7 -6
  30. package/src/resources/service.test.ts +13 -12
  31. package/src/resources/service.ts +153 -112
  32. package/src/stream/index.ts +1 -1
  33. package/src/stream/service.test.ts +5 -5
  34. package/src/stream/service.ts +282 -293
  35. package/src/tools/glob.ts +126 -141
  36. package/src/tools/grep.ts +205 -210
  37. package/src/tools/index.ts +8 -4
  38. package/src/tools/list.ts +118 -140
  39. package/src/tools/read.ts +209 -235
  40. package/src/tools/virtual-sandbox.ts +91 -83
  41. package/src/validation/index.ts +18 -22
  42. package/src/vfs/virtual-fs.test.ts +37 -25
  43. package/src/vfs/virtual-fs.ts +218 -216
package/src/tools/list.ts CHANGED
@@ -4,160 +4,138 @@
4
4
  */
5
5
  import * as path from 'node:path';
6
6
  import { z } from 'zod';
7
- import { Result } from 'better-result';
8
7
 
9
8
  import type { ToolContext } from './context.ts';
10
- import { VirtualSandbox } from './virtual-sandbox.ts';
11
- import { VirtualFs } from '../vfs/virtual-fs.ts';
12
-
13
- export namespace ListTool {
14
- // Schema for tool parameters
15
- export const Parameters = z.object({
16
- path: z.string().describe('The directory path to list')
17
- });
18
-
19
- export type ParametersType = z.infer<typeof Parameters>;
20
-
21
- // Entry type
22
- export type Entry = {
23
- name: string;
24
- type: 'file' | 'directory' | 'other';
25
- size?: number;
9
+ import { resolveSandboxPath } from './virtual-sandbox.ts';
10
+ import { readdirVirtualFs, statVirtualFs } from '../vfs/virtual-fs.ts';
11
+
12
+ export const ListToolParameters = z.object({
13
+ path: z.string().describe('The directory path to list')
14
+ });
15
+
16
+ export type ListToolParametersType = z.infer<typeof ListToolParameters>;
17
+
18
+ export type ListToolEntry = {
19
+ name: string;
20
+ type: 'file' | 'directory' | 'other';
21
+ size?: number;
22
+ };
23
+
24
+ export type ListToolResult = {
25
+ title: string;
26
+ output: string;
27
+ metadata: {
28
+ entries: ListToolEntry[];
29
+ fileCount: number;
30
+ directoryCount: number;
26
31
  };
32
+ };
27
33
 
28
- // Result type
29
- export type Result = {
30
- title: string;
31
- output: string;
32
- metadata: {
33
- entries: Entry[];
34
- fileCount: number;
35
- directoryCount: number;
34
+ const safeStat = async (filePath: string, vfsId?: string) => {
35
+ try {
36
+ return await statVirtualFs(filePath, vfsId);
37
+ } catch {
38
+ return null;
39
+ }
40
+ };
41
+
42
+ export const executeListTool = async (
43
+ params: ListToolParametersType,
44
+ context: ToolContext
45
+ ): Promise<ListToolResult> => {
46
+ const { basePath, vfsId } = context;
47
+ const resolvedPath = resolveSandboxPath(basePath, params.path);
48
+ const stats = await safeStat(resolvedPath, vfsId);
49
+ if (!stats) {
50
+ return {
51
+ title: params.path,
52
+ output: `Directory not found: ${params.path}`,
53
+ metadata: {
54
+ entries: [],
55
+ fileCount: 0,
56
+ directoryCount: 0
57
+ }
36
58
  };
37
- };
38
-
39
- const safeStat = async (filePath: string, vfsId?: string) => {
40
- const result = await Result.tryPromise(() => VirtualFs.stat(filePath, vfsId));
41
- return result.match({
42
- ok: (value) => value,
43
- err: () => null
44
- });
45
- };
46
-
47
- /**
48
- * Execute the list tool
49
- */
50
- export async function execute(params: ParametersType, context: ToolContext): Promise<Result> {
51
- const { basePath, vfsId } = context;
52
-
53
- // Resolve path within sandbox
54
- const resolvedPath = VirtualSandbox.resolvePath(basePath, params.path);
55
-
56
- // Check if path exists
57
- const stats = await safeStat(resolvedPath, vfsId);
58
- if (!stats) {
59
- return {
60
- title: params.path,
61
- output: `Directory not found: ${params.path}`,
62
- metadata: {
63
- entries: [],
64
- fileCount: 0,
65
- directoryCount: 0
66
- }
67
- };
68
- }
69
- if (!stats.isDirectory) {
70
- return {
71
- title: params.path,
72
- output: `Path is not a directory: ${params.path}`,
73
- metadata: {
74
- entries: [],
75
- fileCount: 0,
76
- directoryCount: 0
77
- }
78
- };
79
- }
80
-
81
- // Read directory contents
82
- const entries: Entry[] = [];
83
-
84
- const dirents = await VirtualFs.readdir(resolvedPath, vfsId);
85
- for (const dirent of dirents) {
86
- let type: Entry['type'] = 'other';
87
- let size: number | undefined;
88
- if (dirent.isDirectory) {
89
- type = 'directory';
90
- } else if (dirent.isFile) {
91
- type = 'file';
92
- const stats = await safeStat(path.posix.join(resolvedPath, dirent.name), vfsId);
93
- size = stats?.size;
59
+ }
60
+ if (!stats.isDirectory) {
61
+ return {
62
+ title: params.path,
63
+ output: `Path is not a directory: ${params.path}`,
64
+ metadata: {
65
+ entries: [],
66
+ fileCount: 0,
67
+ directoryCount: 0
94
68
  }
95
- entries.push({
96
- name: dirent.name,
97
- type,
98
- size
99
- });
100
- }
69
+ };
70
+ }
101
71
 
102
- // Sort: directories first, then files, alphabetically within each group
103
- entries.sort((a, b) => {
104
- if (a.type === 'directory' && b.type !== 'directory') return -1;
105
- if (a.type !== 'directory' && b.type === 'directory') return 1;
106
- return a.name.localeCompare(b.name);
72
+ const entries: ListToolEntry[] = [];
73
+ const dirents = await readdirVirtualFs(resolvedPath, vfsId);
74
+ for (const dirent of dirents) {
75
+ let type: ListToolEntry['type'] = 'other';
76
+ let size: number | undefined;
77
+ if (dirent.isDirectory) {
78
+ type = 'directory';
79
+ } else if (dirent.isFile) {
80
+ type = 'file';
81
+ const stats = await safeStat(path.posix.join(resolvedPath, dirent.name), vfsId);
82
+ size = stats?.size;
83
+ }
84
+ entries.push({
85
+ name: dirent.name,
86
+ type,
87
+ size
107
88
  });
89
+ }
108
90
 
109
- // Count files and directories
110
- const fileCount = entries.filter((e) => e.type === 'file').length;
111
- const directoryCount = entries.filter((e) => e.type === 'directory').length;
112
-
113
- // Format output
114
- const outputLines: string[] = [];
91
+ entries.sort((a, b) => {
92
+ if (a.type === 'directory' && b.type !== 'directory') return -1;
93
+ if (a.type !== 'directory' && b.type === 'directory') return 1;
94
+ return a.name.localeCompare(b.name);
95
+ });
115
96
 
116
- for (const entry of entries) {
117
- let line: string;
97
+ const fileCount = entries.filter((e) => e.type === 'file').length;
98
+ const directoryCount = entries.filter((e) => e.type === 'directory').length;
99
+ const outputLines: string[] = [];
100
+
101
+ for (const entry of entries) {
102
+ let line: string;
103
+ if (entry.type === 'directory') {
104
+ line = `[DIR] ${entry.name}/`;
105
+ } else if (entry.type === 'file') {
106
+ const sizeStr = entry.size !== undefined ? formatSize(entry.size) : '';
107
+ line = `[FILE] ${entry.name}${sizeStr ? ` (${sizeStr})` : ''}`;
108
+ } else {
109
+ line = `[???] ${entry.name}`;
110
+ }
111
+ outputLines.push(line);
112
+ }
118
113
 
119
- if (entry.type === 'directory') {
120
- line = `[DIR] ${entry.name}/`;
121
- } else if (entry.type === 'file') {
122
- const sizeStr = entry.size !== undefined ? formatSize(entry.size) : '';
123
- line = `[FILE] ${entry.name}${sizeStr ? ` (${sizeStr})` : ''}`;
124
- } else {
125
- line = `[???] ${entry.name}`;
126
- }
114
+ outputLines.push('');
115
+ outputLines.push(
116
+ `Total: ${entries.length} items (${directoryCount} directories, ${fileCount} files)`
117
+ );
127
118
 
128
- outputLines.push(line);
119
+ return {
120
+ title: params.path,
121
+ output: outputLines.join('\n'),
122
+ metadata: {
123
+ entries,
124
+ fileCount,
125
+ directoryCount
129
126
  }
127
+ };
128
+ };
130
129
 
131
- // Add summary
132
- outputLines.push('');
133
- outputLines.push(
134
- `Total: ${entries.length} items (${directoryCount} directories, ${fileCount} files)`
135
- );
130
+ const formatSize = (bytes: number): string => {
131
+ const units = ['B', 'KB', 'MB', 'GB'];
132
+ let size = bytes;
133
+ let unitIndex = 0;
136
134
 
137
- return {
138
- title: params.path,
139
- output: outputLines.join('\n'),
140
- metadata: {
141
- entries,
142
- fileCount,
143
- directoryCount
144
- }
145
- };
135
+ while (size >= 1024 && unitIndex < units.length - 1) {
136
+ size /= 1024;
137
+ unitIndex++;
146
138
  }
147
139
 
148
- /**
149
- * Format file size in human-readable format
150
- */
151
- function formatSize(bytes: number): string {
152
- const units = ['B', 'KB', 'MB', 'GB'];
153
- let size = bytes;
154
- let unitIndex = 0;
155
-
156
- while (size >= 1024 && unitIndex < units.length - 1) {
157
- size /= 1024;
158
- unitIndex++;
159
- }
160
-
161
- return `${size.toFixed(unitIndex === 0 ? 0 : 1)} ${units[unitIndex]}`;
162
- }
163
- }
140
+ return `${size.toFixed(unitIndex === 0 ? 0 : 1)} ${units[unitIndex]}`;
141
+ };