@ottocode/sdk 0.1.199 → 0.1.201

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.
@@ -1,134 +0,0 @@
1
- import { tool, type Tool } from 'ai';
2
- import { z } from 'zod/v3';
3
- import { spawn } from 'node:child_process';
4
- import { join } from 'node:path';
5
- import DESCRIPTION from './grep.txt' with { type: 'text' };
6
- import { defaultIgnoreGlobs } from './ignore.ts';
7
- import { createToolError, type ToolResponse } from '../error.ts';
8
- import { resolveBinary } from '../bin-manager.ts';
9
-
10
- function expandTilde(p: string) {
11
- const home = process.env.HOME || process.env.USERPROFILE || '';
12
- if (!home) return p;
13
- if (p === '~') return home;
14
- if (p.startsWith('~/')) return `${home}/${p.slice(2)}`;
15
- return p;
16
- }
17
-
18
- export function buildGrepTool(projectRoot: string): {
19
- name: string;
20
- tool: Tool;
21
- } {
22
- const grep = tool({
23
- description: DESCRIPTION,
24
- inputSchema: z.object({
25
- pattern: z
26
- .string()
27
- .describe('Regex pattern to search for in file contents'),
28
- path: z
29
- .string()
30
- .optional()
31
- .describe('Directory to search in (default: project root).'),
32
- include: z
33
- .string()
34
- .optional()
35
- .describe('File glob to include (e.g., "*.js", "*.{ts,tsx}")'),
36
- ignore: z
37
- .array(z.string())
38
- .optional()
39
- .describe('Glob patterns to exclude from search'),
40
- }),
41
- async execute(params: {
42
- pattern: string;
43
- path?: string;
44
- include?: string;
45
- ignore?: string[];
46
- }): Promise<
47
- ToolResponse<{
48
- count: number;
49
- matches: Array<{ file: string; line: number; text: string }>;
50
- }>
51
- > {
52
- const pattern = String(params.pattern || '');
53
- if (!pattern) {
54
- return createToolError('pattern is required', 'validation', {
55
- parameter: 'pattern',
56
- suggestion: 'Provide a regex pattern to search for',
57
- });
58
- }
59
-
60
- const p = expandTilde(String(params.path || '')).trim();
61
- const isAbs = p.startsWith('/') || /^[A-Za-z]:[\\/]/.test(p);
62
- const searchPath = p ? (isAbs ? p : join(projectRoot, p)) : projectRoot;
63
-
64
- const rgBin = await resolveBinary('rg');
65
- const args: string[] = ['-n', '--color', 'never'];
66
- for (const g of defaultIgnoreGlobs(params.ignore)) {
67
- args.push('--glob', g);
68
- }
69
- if (params.include) {
70
- args.push('--glob', params.include);
71
- }
72
- args.push(pattern, searchPath);
73
-
74
- let output = '';
75
- try {
76
- output = await new Promise<string>((resolve, reject) => {
77
- const proc = spawn(rgBin, args, { cwd: projectRoot });
78
- let stdout = '';
79
- let stderr = '';
80
- proc.stdout.on('data', (d) => {
81
- stdout += d.toString();
82
- });
83
- proc.stderr.on('data', (d) => {
84
- stderr += d.toString();
85
- });
86
- proc.on('close', (code) => {
87
- if (code === 1) resolve('');
88
- else if (code !== 0)
89
- reject(new Error(stderr.trim() || 'ripgrep failed'));
90
- else resolve(stdout);
91
- });
92
- proc.on('error', reject);
93
- });
94
- } catch (error: unknown) {
95
- const err2 = error as { message?: string };
96
- return createToolError(`ripgrep failed: ${err2.message}`, 'execution', {
97
- parameter: 'pattern',
98
- value: pattern,
99
- suggestion:
100
- 'Check if ripgrep (rg) is installed and the pattern is valid',
101
- });
102
- }
103
-
104
- const lines = output.trim().split('\n');
105
- const matches: Array<{
106
- file: string;
107
- line: number;
108
- text: string;
109
- }> = [];
110
-
111
- for (const line of lines) {
112
- if (!line) continue;
113
- const m = line.match(/^(.+?):(\d+):(.*)$/s);
114
- if (!m) continue;
115
- const filePath = m[1];
116
- const lineNum = parseInt(m[2], 10);
117
- const lineText = m[3];
118
- if (!filePath || !Number.isFinite(lineNum)) continue;
119
- matches.push({ file: filePath, line: lineNum, text: lineText });
120
- }
121
-
122
- const limit = 500;
123
- const truncated = matches.length > limit;
124
- const finalMatches = truncated ? matches.slice(0, limit) : matches;
125
-
126
- return {
127
- ok: true,
128
- count: finalMatches.length,
129
- matches: finalMatches,
130
- };
131
- },
132
- });
133
- return { name: 'grep', tool: grep };
134
- }
@@ -1,9 +0,0 @@
1
- - Fast content search tool powered by ripgrep (rg)
2
- - Supports full regex syntax (e.g., "log.*Error", "function\\s+\\w+")
3
- - Optional include glob to filter files (e.g., "*.js", "*.{ts,tsx}")
4
- - Returns files with at least one match and line previews, sorted by modification time
5
- - Skips common build and cache folders by default; add 'ignore' patterns to refine
6
-
7
- Usage tips:
8
- - For counting matches, use the Bash tool with rg directly (do not use grep)
9
- - Batch multiple searches when exploring a codebase broadly