@element47/ag 4.4.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 (158) hide show
  1. package/README.md +316 -0
  2. package/dist/cli/parser.d.ts +6 -0
  3. package/dist/cli/parser.d.ts.map +1 -0
  4. package/dist/cli/parser.js +62 -0
  5. package/dist/cli/parser.js.map +1 -0
  6. package/dist/cli/repl.d.ts +16 -0
  7. package/dist/cli/repl.d.ts.map +1 -0
  8. package/dist/cli/repl.js +599 -0
  9. package/dist/cli/repl.js.map +1 -0
  10. package/dist/cli.d.ts +3 -0
  11. package/dist/cli.d.ts.map +1 -0
  12. package/dist/cli.js +84 -0
  13. package/dist/cli.js.map +1 -0
  14. package/dist/core/__tests__/agent.test.d.ts +2 -0
  15. package/dist/core/__tests__/agent.test.d.ts.map +1 -0
  16. package/dist/core/__tests__/agent.test.js +53 -0
  17. package/dist/core/__tests__/agent.test.js.map +1 -0
  18. package/dist/core/__tests__/config.test.d.ts +2 -0
  19. package/dist/core/__tests__/config.test.d.ts.map +1 -0
  20. package/dist/core/__tests__/config.test.js +58 -0
  21. package/dist/core/__tests__/config.test.js.map +1 -0
  22. package/dist/core/__tests__/constants.test.d.ts +2 -0
  23. package/dist/core/__tests__/constants.test.d.ts.map +1 -0
  24. package/dist/core/__tests__/constants.test.js +40 -0
  25. package/dist/core/__tests__/constants.test.js.map +1 -0
  26. package/dist/core/__tests__/context.test.d.ts +2 -0
  27. package/dist/core/__tests__/context.test.d.ts.map +1 -0
  28. package/dist/core/__tests__/context.test.js +120 -0
  29. package/dist/core/__tests__/context.test.js.map +1 -0
  30. package/dist/core/__tests__/environment.test.d.ts +2 -0
  31. package/dist/core/__tests__/environment.test.d.ts.map +1 -0
  32. package/dist/core/__tests__/environment.test.js +94 -0
  33. package/dist/core/__tests__/environment.test.js.map +1 -0
  34. package/dist/core/__tests__/permissions.test.d.ts +2 -0
  35. package/dist/core/__tests__/permissions.test.d.ts.map +1 -0
  36. package/dist/core/__tests__/permissions.test.js +66 -0
  37. package/dist/core/__tests__/permissions.test.js.map +1 -0
  38. package/dist/core/__tests__/registry.test.d.ts +2 -0
  39. package/dist/core/__tests__/registry.test.d.ts.map +1 -0
  40. package/dist/core/__tests__/registry.test.js +152 -0
  41. package/dist/core/__tests__/registry.test.js.map +1 -0
  42. package/dist/core/__tests__/streaming.test.d.ts +2 -0
  43. package/dist/core/__tests__/streaming.test.d.ts.map +1 -0
  44. package/dist/core/__tests__/streaming.test.js +54 -0
  45. package/dist/core/__tests__/streaming.test.js.map +1 -0
  46. package/dist/core/agent.d.ts +87 -0
  47. package/dist/core/agent.d.ts.map +1 -0
  48. package/dist/core/agent.js +711 -0
  49. package/dist/core/agent.js.map +1 -0
  50. package/dist/core/colors.d.ts +12 -0
  51. package/dist/core/colors.d.ts.map +1 -0
  52. package/dist/core/colors.js +37 -0
  53. package/dist/core/colors.js.map +1 -0
  54. package/dist/core/config.d.ts +13 -0
  55. package/dist/core/config.d.ts.map +1 -0
  56. package/dist/core/config.js +30 -0
  57. package/dist/core/config.js.map +1 -0
  58. package/dist/core/constants.d.ts +5 -0
  59. package/dist/core/constants.d.ts.map +1 -0
  60. package/dist/core/constants.js +26 -0
  61. package/dist/core/constants.js.map +1 -0
  62. package/dist/core/context.d.ts +18 -0
  63. package/dist/core/context.d.ts.map +1 -0
  64. package/dist/core/context.js +99 -0
  65. package/dist/core/context.js.map +1 -0
  66. package/dist/core/loader.d.ts +3 -0
  67. package/dist/core/loader.d.ts.map +1 -0
  68. package/dist/core/loader.js +39 -0
  69. package/dist/core/loader.js.map +1 -0
  70. package/dist/core/registry.d.ts +11 -0
  71. package/dist/core/registry.d.ts.map +1 -0
  72. package/dist/core/registry.js +112 -0
  73. package/dist/core/registry.js.map +1 -0
  74. package/dist/core/skills.d.ts +14 -0
  75. package/dist/core/skills.d.ts.map +1 -0
  76. package/dist/core/skills.js +100 -0
  77. package/dist/core/skills.js.map +1 -0
  78. package/dist/core/types.d.ts +64 -0
  79. package/dist/core/types.d.ts.map +1 -0
  80. package/dist/core/types.js +2 -0
  81. package/dist/core/types.js.map +1 -0
  82. package/dist/core/version.d.ts +2 -0
  83. package/dist/core/version.d.ts.map +1 -0
  84. package/dist/core/version.js +7 -0
  85. package/dist/core/version.js.map +1 -0
  86. package/dist/memory/__tests__/memory.test.d.ts +2 -0
  87. package/dist/memory/__tests__/memory.test.d.ts.map +1 -0
  88. package/dist/memory/__tests__/memory.test.js +196 -0
  89. package/dist/memory/__tests__/memory.test.js.map +1 -0
  90. package/dist/memory/memory.d.ts +41 -0
  91. package/dist/memory/memory.d.ts.map +1 -0
  92. package/dist/memory/memory.js +206 -0
  93. package/dist/memory/memory.js.map +1 -0
  94. package/dist/tools/__tests__/bash.test.d.ts +2 -0
  95. package/dist/tools/__tests__/bash.test.d.ts.map +1 -0
  96. package/dist/tools/__tests__/bash.test.js +58 -0
  97. package/dist/tools/__tests__/bash.test.js.map +1 -0
  98. package/dist/tools/__tests__/file.test.d.ts +2 -0
  99. package/dist/tools/__tests__/file.test.d.ts.map +1 -0
  100. package/dist/tools/__tests__/file.test.js +115 -0
  101. package/dist/tools/__tests__/file.test.js.map +1 -0
  102. package/dist/tools/__tests__/git.test.d.ts +2 -0
  103. package/dist/tools/__tests__/git.test.d.ts.map +1 -0
  104. package/dist/tools/__tests__/git.test.js +19 -0
  105. package/dist/tools/__tests__/git.test.js.map +1 -0
  106. package/dist/tools/__tests__/grep.test.d.ts +2 -0
  107. package/dist/tools/__tests__/grep.test.d.ts.map +1 -0
  108. package/dist/tools/__tests__/grep.test.js +36 -0
  109. package/dist/tools/__tests__/grep.test.js.map +1 -0
  110. package/dist/tools/__tests__/memory-tool.test.d.ts +2 -0
  111. package/dist/tools/__tests__/memory-tool.test.d.ts.map +1 -0
  112. package/dist/tools/__tests__/memory-tool.test.js +39 -0
  113. package/dist/tools/__tests__/memory-tool.test.js.map +1 -0
  114. package/dist/tools/__tests__/plan.test.d.ts +2 -0
  115. package/dist/tools/__tests__/plan.test.d.ts.map +1 -0
  116. package/dist/tools/__tests__/plan.test.js +81 -0
  117. package/dist/tools/__tests__/plan.test.js.map +1 -0
  118. package/dist/tools/__tests__/schemas.test.d.ts +2 -0
  119. package/dist/tools/__tests__/schemas.test.d.ts.map +1 -0
  120. package/dist/tools/__tests__/schemas.test.js +40 -0
  121. package/dist/tools/__tests__/schemas.test.js.map +1 -0
  122. package/dist/tools/__tests__/web.test.d.ts +2 -0
  123. package/dist/tools/__tests__/web.test.d.ts.map +1 -0
  124. package/dist/tools/__tests__/web.test.js +51 -0
  125. package/dist/tools/__tests__/web.test.js.map +1 -0
  126. package/dist/tools/bash.d.ts +6 -0
  127. package/dist/tools/bash.d.ts.map +1 -0
  128. package/dist/tools/bash.js +89 -0
  129. package/dist/tools/bash.js.map +1 -0
  130. package/dist/tools/file.d.ts +7 -0
  131. package/dist/tools/file.d.ts.map +1 -0
  132. package/dist/tools/file.js +224 -0
  133. package/dist/tools/file.js.map +1 -0
  134. package/dist/tools/git.d.ts +3 -0
  135. package/dist/tools/git.d.ts.map +1 -0
  136. package/dist/tools/git.js +220 -0
  137. package/dist/tools/git.js.map +1 -0
  138. package/dist/tools/grep.d.ts +8 -0
  139. package/dist/tools/grep.d.ts.map +1 -0
  140. package/dist/tools/grep.js +265 -0
  141. package/dist/tools/grep.js.map +1 -0
  142. package/dist/tools/memory.d.ts +3 -0
  143. package/dist/tools/memory.d.ts.map +1 -0
  144. package/dist/tools/memory.js +33 -0
  145. package/dist/tools/memory.js.map +1 -0
  146. package/dist/tools/plan.d.ts +3 -0
  147. package/dist/tools/plan.d.ts.map +1 -0
  148. package/dist/tools/plan.js +60 -0
  149. package/dist/tools/plan.js.map +1 -0
  150. package/dist/tools/skill.d.ts +6 -0
  151. package/dist/tools/skill.d.ts.map +1 -0
  152. package/dist/tools/skill.js +20 -0
  153. package/dist/tools/skill.js.map +1 -0
  154. package/dist/tools/web.d.ts +3 -0
  155. package/dist/tools/web.d.ts.map +1 -0
  156. package/dist/tools/web.js +187 -0
  157. package/dist/tools/web.js.map +1 -0
  158. package/package.json +48 -0
@@ -0,0 +1,220 @@
1
+ import { execFile } from 'node:child_process';
2
+ import { promisify } from 'node:util';
3
+ import { existsSync } from 'node:fs';
4
+ import { join } from 'node:path';
5
+ const execFileAsync = promisify(execFile);
6
+ async function run(args, cwd) {
7
+ const { stdout } = await execFileAsync('git', args, { cwd, encoding: 'utf-8', timeout: 30_000 });
8
+ return stdout.trim();
9
+ }
10
+ async function tryRun(args, cwd) {
11
+ try {
12
+ return { ok: true, out: await run(args, cwd) };
13
+ }
14
+ catch (e) {
15
+ const err = e;
16
+ return { ok: false, out: ((err.stdout ?? '') + (err.stderr ?? '')).trim() };
17
+ }
18
+ }
19
+ function isRepo(cwd) {
20
+ return existsSync(join(cwd, '.git'));
21
+ }
22
+ async function defaultBranch(cwd) {
23
+ const ref = await tryRun(['symbolic-ref', 'refs/remotes/origin/HEAD'], cwd);
24
+ if (ref.ok)
25
+ return ref.out.replace('refs/remotes/origin/', '');
26
+ const branches = await tryRun(['branch', '-r'], cwd);
27
+ if (branches.ok) {
28
+ if (branches.out.includes('origin/main'))
29
+ return 'main';
30
+ if (branches.out.includes('origin/master'))
31
+ return 'master';
32
+ }
33
+ return 'main';
34
+ }
35
+ async function currentBranch(cwd) {
36
+ const result = await tryRun(['rev-parse', '--abbrev-ref', 'HEAD'], cwd);
37
+ if (result.ok)
38
+ return result.out;
39
+ const sym = await tryRun(['symbolic-ref', '--short', 'HEAD'], cwd);
40
+ return sym.ok ? `${sym.out} (no commits yet)` : '(no commits yet)';
41
+ }
42
+ async function remoteUrl(cwd) {
43
+ const r = await tryRun(['remote', 'get-url', 'origin'], cwd);
44
+ return r.ok ? r.out : '';
45
+ }
46
+ async function compareUrl(cwd, branch) {
47
+ const remote = await remoteUrl(cwd);
48
+ if (!remote)
49
+ return '';
50
+ const base = await defaultBranch(cwd);
51
+ const url = remote
52
+ .replace(/^git@([^:]+):/, 'https://$1/')
53
+ .replace(/\.git$/, '');
54
+ return `${url}/compare/${base}...${branch}`;
55
+ }
56
+ // ── Action handlers ────────────────────────────────────────────────────────
57
+ async function doStatus(cwd) {
58
+ if (!isRepo(cwd))
59
+ return 'Not a git repository. Use action=init first.';
60
+ const lines = [];
61
+ lines.push(`Branch: ${await currentBranch(cwd)}`);
62
+ const remote = await remoteUrl(cwd);
63
+ if (remote)
64
+ lines.push(`Remote: ${remote}`);
65
+ const status = await run(['status', '--porcelain'], cwd);
66
+ if (status) {
67
+ const files = status.split('\n');
68
+ const staged = files.filter(f => /^[MADRC]/.test(f)).length;
69
+ const unstaged = files.filter(f => /^.[MADRC]/.test(f)).length;
70
+ const untracked = files.filter(f => f.startsWith('??')).length;
71
+ lines.push(`Changes: ${staged} staged, ${unstaged} unstaged, ${untracked} untracked`);
72
+ }
73
+ else {
74
+ lines.push('Working tree clean.');
75
+ }
76
+ const ahead = await tryRun(['rev-list', '@{u}..HEAD', '--count'], cwd);
77
+ const behind = await tryRun(['rev-list', 'HEAD..@{u}', '--count'], cwd);
78
+ if (ahead.ok && behind.ok) {
79
+ lines.push(`Ahead: ${ahead.out}, Behind: ${behind.out}`);
80
+ }
81
+ const log = await tryRun(['log', '--oneline', '-5'], cwd);
82
+ if (log.ok && log.out)
83
+ lines.push(`\nRecent commits:\n${log.out}`);
84
+ return lines.join('\n');
85
+ }
86
+ async function doInit(cwd, remote) {
87
+ if (isRepo(cwd)) {
88
+ const branch = await currentBranch(cwd);
89
+ const existing = await remoteUrl(cwd);
90
+ let msg = `Already a git repo. Branch: ${branch}`;
91
+ if (existing)
92
+ msg += `, Remote: ${existing}`;
93
+ if (remote && remote !== existing) {
94
+ await tryRun(['remote', 'remove', 'origin'], cwd);
95
+ await run(['remote', 'add', 'origin', remote], cwd);
96
+ msg += `\nRemote updated to: ${remote}`;
97
+ }
98
+ return msg;
99
+ }
100
+ await run(['init'], cwd);
101
+ let msg = 'Initialized git repository.';
102
+ if (remote) {
103
+ await run(['remote', 'add', 'origin', remote], cwd);
104
+ msg += ` Remote set to: ${remote}`;
105
+ }
106
+ return msg;
107
+ }
108
+ async function doBranch(cwd, name) {
109
+ if (!isRepo(cwd))
110
+ return 'Not a git repository. Use action=init first.';
111
+ const lines = [];
112
+ const status = await run(['status', '--porcelain'], cwd);
113
+ if (status) {
114
+ return `Error: ${status.split('\n').length} uncommitted change(s) detected. Commit or stash your changes before creating a new branch.\n\nDirty files:\n${status}`;
115
+ }
116
+ const fetchResult = await tryRun(['fetch', 'origin'], cwd);
117
+ if (fetchResult.ok) {
118
+ lines.push('Fetched latest from origin.');
119
+ }
120
+ else {
121
+ lines.push('Warning: Could not fetch from origin (no remote or offline). Branching from local state.');
122
+ }
123
+ const base = await defaultBranch(cwd);
124
+ if (fetchResult.ok) {
125
+ await tryRun(['checkout', base], cwd);
126
+ await tryRun(['merge', '--ff-only', `origin/${base}`], cwd);
127
+ lines.push(`Updated local ${base} to origin/${base}.`);
128
+ }
129
+ const result = await tryRun(['checkout', '-b', name], cwd);
130
+ if (result.ok) {
131
+ lines.push(`Created and switched to branch: ${name}`);
132
+ }
133
+ else {
134
+ const sw = await tryRun(['checkout', name], cwd);
135
+ lines.push(sw.ok
136
+ ? `Branch ${name} already exists. Switched to it.`
137
+ : `Error creating branch: ${result.out}`);
138
+ }
139
+ return lines.join('\n');
140
+ }
141
+ async function doCommit(cwd, message, files) {
142
+ if (!isRepo(cwd))
143
+ return 'Not a git repository. Use action=init first.';
144
+ if (files && files.length > 0) {
145
+ await run(['add', ...files], cwd);
146
+ }
147
+ else {
148
+ await run(['add', '-A'], cwd);
149
+ }
150
+ const staged = await tryRun(['diff', '--cached', '--stat'], cwd);
151
+ if (!staged.out)
152
+ return 'Nothing to commit. Working tree clean.';
153
+ const result = await tryRun(['commit', '-m', message], cwd);
154
+ return result.ok ? `Committed: ${message}\n${result.out}` : `Commit failed: ${result.out}`;
155
+ }
156
+ async function doPush(cwd, force) {
157
+ if (!isRepo(cwd))
158
+ return 'Not a git repository. Use action=init first.';
159
+ const branch = await currentBranch(cwd);
160
+ const base = await defaultBranch(cwd);
161
+ if (branch === base) {
162
+ return `You're on ${base}. Create a feature branch first with action=branch.`;
163
+ }
164
+ const args = ['push', '-u', 'origin', branch];
165
+ if (force)
166
+ args.splice(1, 0, '--force-with-lease');
167
+ const result = await tryRun(args, cwd);
168
+ const lines = [];
169
+ if (result.ok || result.out.includes('->')) {
170
+ lines.push(`Pushed ${branch} to origin.`);
171
+ }
172
+ else {
173
+ return `Push failed: ${result.out}`;
174
+ }
175
+ const url = await compareUrl(cwd, branch);
176
+ if (url)
177
+ lines.push(`\nCreate PR: ${url}`);
178
+ return lines.join('\n');
179
+ }
180
+ // ── Exported tool ──────────────────────────────────────────────────────────
181
+ export function gitTool(cwd) {
182
+ return {
183
+ type: 'function',
184
+ function: {
185
+ name: 'git',
186
+ description: 'Git operations. Actions: status (branch, changes, recent commits), init (initialize repo), branch (create from latest main), commit (stage + commit), push (push + PR compare URL).',
187
+ parameters: {
188
+ type: 'object',
189
+ properties: {
190
+ action: { type: 'string', enum: ['status', 'init', 'branch', 'commit', 'push'], description: 'The git operation to perform.' },
191
+ name: { type: 'string', description: 'Branch name (for action=branch, e.g. "feature/add-auth").' },
192
+ message: { type: 'string', description: 'Commit message (for action=commit).' },
193
+ files: { type: 'array', items: { type: 'string' }, description: 'Specific files to stage (for action=commit). Omit to stage all.' },
194
+ remote: { type: 'string', description: 'Remote URL (for action=init, e.g. "git@github.com:user/repo.git").' },
195
+ force: { type: 'boolean', description: 'Force push with lease (for action=push). Default: false.' }
196
+ },
197
+ required: ['action']
198
+ }
199
+ },
200
+ execute: async ({ action, name, message, files, remote, force }) => {
201
+ switch (action) {
202
+ case 'status': return doStatus(cwd);
203
+ case 'init': return doInit(cwd, remote);
204
+ case 'branch': {
205
+ if (!name)
206
+ return 'Error: name is required for action=branch.';
207
+ return doBranch(cwd, name);
208
+ }
209
+ case 'commit': {
210
+ if (!message)
211
+ return 'Error: message is required for action=commit.';
212
+ return doCommit(cwd, message, files);
213
+ }
214
+ case 'push': return doPush(cwd, force);
215
+ default: return `Unknown action "${action}". Use: status, init, branch, commit, push.`;
216
+ }
217
+ }
218
+ };
219
+ }
220
+ //# sourceMappingURL=git.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git.js","sourceRoot":"","sources":["../../src/tools/git.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Grep tool — code search and file finding
3
+ * Primary: ripgrep (rg) via execFileSync
4
+ * Fallback: native Node.js when rg is not installed
5
+ */
6
+ import { Tool } from '../core/types.js';
7
+ export declare function grepTool(cwd: string): Tool;
8
+ //# sourceMappingURL=grep.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"grep.d.ts","sourceRoot":"","sources":["../../src/tools/grep.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAiNxC,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CA+B1C"}
@@ -0,0 +1,265 @@
1
+ /**
2
+ * Grep tool — code search and file finding
3
+ * Primary: ripgrep (rg) via execFileSync
4
+ * Fallback: native Node.js when rg is not installed
5
+ */
6
+ import { execFile } from 'node:child_process';
7
+ import { promisify } from 'node:util';
8
+ import { readdirSync, readFileSync, statSync } from 'node:fs';
9
+ import { join, resolve, relative } from 'node:path';
10
+ import { DEFAULT_IGNORE, isBinary } from '../core/constants.js';
11
+ const execFileAsync = promisify(execFile);
12
+ const MAX_SEARCH_LINES = 250;
13
+ const MAX_FIND_RESULTS = 100;
14
+ const MAX_FILE_SIZE = 1_048_576; // 1 MB
15
+ // ── Ripgrep helpers ──────────────────────────────────────────────────────
16
+ async function tryRg(args, cwd) {
17
+ try {
18
+ const { stdout } = await execFileAsync('rg', args, {
19
+ cwd, encoding: 'utf-8', timeout: 30_000, maxBuffer: 2 * 1024 * 1024,
20
+ });
21
+ return { ok: true, out: stdout.trim(), notFound: false };
22
+ }
23
+ catch (e) {
24
+ const err = e;
25
+ if (err.code === 'ENOENT')
26
+ return { ok: false, out: '', notFound: true };
27
+ // rg exits 1 for no matches, 2 for errors
28
+ const out = ((err.stdout ?? '') + (err.stderr ?? '')).trim();
29
+ if (err.code === 1 || err.status === 1)
30
+ return { ok: true, out: '', notFound: false }; // no matches
31
+ return { ok: false, out, notFound: false };
32
+ }
33
+ }
34
+ async function rgSearch(cwd, pattern, path, glob, caseInsensitive, context) {
35
+ const args = [pattern, '--line-number', '--no-heading', '--color', 'never', '--max-count', String(MAX_SEARCH_LINES)];
36
+ if (glob)
37
+ args.push('--glob', glob);
38
+ if (caseInsensitive)
39
+ args.push('--ignore-case');
40
+ if (context && context > 0)
41
+ args.push('--context', String(context));
42
+ if (path)
43
+ args.push(path);
44
+ const result = await tryRg(args, cwd);
45
+ if (result.notFound)
46
+ return ''; // signal to use fallback
47
+ if (!result.ok)
48
+ return `Error: ${result.out}`;
49
+ return result.out || 'No matches found.';
50
+ }
51
+ async function rgFind(cwd, pattern, path) {
52
+ const args = ['--files', '--glob', pattern];
53
+ if (path)
54
+ args.push(path);
55
+ const result = await tryRg(args, cwd);
56
+ if (result.notFound)
57
+ return ''; // signal to use fallback
58
+ if (!result.ok)
59
+ return `Error: ${result.out}`;
60
+ if (!result.out)
61
+ return 'No matches found.';
62
+ const lines = result.out.split('\n');
63
+ if (lines.length > MAX_FIND_RESULTS) {
64
+ return lines.slice(0, MAX_FIND_RESULTS).join('\n')
65
+ + `\n... (${MAX_FIND_RESULTS} of ${lines.length} files shown. Narrow with path.)`;
66
+ }
67
+ return result.out;
68
+ }
69
+ // ── Native fallback helpers ──────────────────────────────────────────────
70
+ function walkDir(root, maxDepth = 20) {
71
+ const files = [];
72
+ function walk(dir, depth) {
73
+ if (depth > maxDepth)
74
+ return;
75
+ let entries;
76
+ try {
77
+ entries = readdirSync(dir, { withFileTypes: true });
78
+ }
79
+ catch {
80
+ return;
81
+ }
82
+ for (const entry of entries) {
83
+ if (DEFAULT_IGNORE.has(entry.name))
84
+ continue;
85
+ if (entry.name.startsWith('.') && entry.name !== '.')
86
+ continue;
87
+ const full = join(dir, entry.name);
88
+ if (entry.isSymbolicLink())
89
+ continue;
90
+ if (entry.isDirectory()) {
91
+ walk(full, depth + 1);
92
+ continue;
93
+ }
94
+ if (entry.isFile())
95
+ files.push(full);
96
+ }
97
+ }
98
+ walk(root, 0);
99
+ return files;
100
+ }
101
+ const MAX_GLOB_LENGTH = 200;
102
+ function matchesGlob(filepath, glob) {
103
+ // Protect against ReDoS from excessively complex patterns
104
+ if (glob.length > MAX_GLOB_LENGTH)
105
+ return false;
106
+ // Convert glob to regex: * -> [^/]*, ** -> .*, ? -> ., {a,b} -> (a|b), escape dots
107
+ const re = glob
108
+ .replace(/\./g, '\\.')
109
+ .replace(/\*\*/g, '{{GLOBSTAR}}')
110
+ .replace(/\*/g, '[^/]*')
111
+ .replace(/\{\{GLOBSTAR\}\}/g, '.*')
112
+ .replace(/\?/g, '.')
113
+ .replace(/\{([^}]+)\}/g, (_m, group) => `(${group.replace(/,/g, '|')})`);
114
+ // If pattern has no path separators, match against basename only
115
+ if (!glob.includes('/')) {
116
+ const basename = filepath.split('/').pop() || filepath;
117
+ return new RegExp(`^${re}$`).test(basename);
118
+ }
119
+ return new RegExp(`^${re}$`).test(filepath) || new RegExp(`${re}$`).test(filepath);
120
+ }
121
+ function fallbackSearch(cwd, pattern, searchRoot, glob, caseInsensitive, context) {
122
+ let regex;
123
+ try {
124
+ regex = new RegExp(pattern, caseInsensitive ? 'i' : '');
125
+ }
126
+ catch (e) {
127
+ return `Error: invalid regex — ${e instanceof Error ? e.message : String(e)}`;
128
+ }
129
+ const ctx = context && context > 0 ? context : 0;
130
+ const files = walkDir(searchRoot);
131
+ const output = [];
132
+ let matchCount = 0;
133
+ let truncated = false;
134
+ for (const file of files) {
135
+ if (matchCount >= MAX_SEARCH_LINES) {
136
+ truncated = true;
137
+ break;
138
+ }
139
+ try {
140
+ const stat = statSync(file);
141
+ if (stat.size > MAX_FILE_SIZE)
142
+ continue;
143
+ }
144
+ catch {
145
+ continue;
146
+ }
147
+ if (isBinary(file))
148
+ continue;
149
+ if (glob && !matchesGlob(relative(cwd, file), glob))
150
+ continue;
151
+ let content;
152
+ try {
153
+ content = readFileSync(file, 'utf-8');
154
+ }
155
+ catch {
156
+ continue;
157
+ }
158
+ const lines = content.split('\n');
159
+ const relPath = relative(cwd, file);
160
+ const fileMatches = [];
161
+ for (let i = 0; i < lines.length; i++) {
162
+ if (regex.test(lines[i])) {
163
+ const start = Math.max(0, i - ctx);
164
+ const end = Math.min(lines.length - 1, i + ctx);
165
+ for (let j = start; j <= end; j++) {
166
+ fileMatches.push(`${relPath}:${j + 1}:${lines[j]}`);
167
+ matchCount++;
168
+ if (matchCount >= MAX_SEARCH_LINES) {
169
+ truncated = true;
170
+ break;
171
+ }
172
+ }
173
+ if (truncated)
174
+ break;
175
+ }
176
+ }
177
+ if (fileMatches.length > 0) {
178
+ if (output.length > 0)
179
+ output.push('');
180
+ output.push(...fileMatches);
181
+ }
182
+ if (truncated)
183
+ break;
184
+ }
185
+ if (output.length === 0)
186
+ return 'No matches found.';
187
+ let result = output.join('\n');
188
+ if (truncated)
189
+ result += `\n... (${MAX_SEARCH_LINES} lines shown. Narrow with path or glob.)`;
190
+ return result;
191
+ }
192
+ function fallbackFind(cwd, pattern, searchRoot) {
193
+ const files = walkDir(searchRoot);
194
+ const matches = [];
195
+ for (const file of files) {
196
+ const relPath = relative(cwd, file);
197
+ if (matchesGlob(relPath, pattern)) {
198
+ matches.push(relPath);
199
+ if (matches.length >= MAX_FIND_RESULTS)
200
+ break;
201
+ }
202
+ }
203
+ if (matches.length === 0)
204
+ return 'No matches found.';
205
+ let result = matches.join('\n');
206
+ if (matches.length >= MAX_FIND_RESULTS) {
207
+ result += `\n... (${MAX_FIND_RESULTS} files shown. Narrow with path.)`;
208
+ }
209
+ return result;
210
+ }
211
+ // ── Action handlers ──────────────────────────────────────────────────────
212
+ async function doSearch(cwd, pattern, path, glob, caseInsensitive, context) {
213
+ const searchRoot = path ? resolve(cwd, path) : cwd;
214
+ if (!searchRoot.startsWith(cwd))
215
+ return 'Error: path must be within the project directory.';
216
+ // Try ripgrep first
217
+ const rgResult = await rgSearch(cwd, pattern, path, glob, caseInsensitive, context);
218
+ if (rgResult !== '')
219
+ return rgResult; // '' means rg not found
220
+ // Fallback to native Node.js
221
+ return fallbackSearch(cwd, pattern, searchRoot, glob, caseInsensitive, context);
222
+ }
223
+ async function doFind(cwd, pattern, path) {
224
+ const searchRoot = path ? resolve(cwd, path) : cwd;
225
+ if (!searchRoot.startsWith(cwd))
226
+ return 'Error: path must be within the project directory.';
227
+ // Try ripgrep first
228
+ const rgResult = await rgFind(cwd, pattern, path);
229
+ if (rgResult !== '')
230
+ return rgResult; // '' means rg not found
231
+ // Fallback to native Node.js
232
+ return fallbackFind(cwd, pattern, searchRoot);
233
+ }
234
+ // ── Exported tool ────────────────────────────────────────────────────────
235
+ export function grepTool(cwd) {
236
+ return {
237
+ type: 'function',
238
+ function: {
239
+ name: 'grep',
240
+ description: 'Search code and find files. Prefer this over bash for ALL search operations. Actions: search (find pattern in file contents using regex — use this instead of bash grep/rg), find (locate files by name/glob pattern — use this instead of bash find/ls).',
241
+ parameters: {
242
+ type: 'object',
243
+ properties: {
244
+ action: { type: 'string', enum: ['search', 'find'], description: 'search = content regex, find = file name glob.' },
245
+ pattern: { type: 'string', description: 'Regex for search, glob for find (e.g. "*.ts", "TODO", "function\\s+\\w+").' },
246
+ path: { type: 'string', description: 'Subdirectory to scope (relative to project root). Omit to search everywhere.' },
247
+ glob: { type: 'string', description: 'File type filter for action=search (e.g. "*.ts", "*.py"). Not needed for find.' },
248
+ case_insensitive: { type: 'boolean', description: 'Case-insensitive matching (search only). Default: false.' },
249
+ context: { type: 'number', description: 'Lines of context before and after each match (search only). Default: 0.' }
250
+ },
251
+ required: ['action', 'pattern']
252
+ }
253
+ },
254
+ execute: async ({ action, pattern, path, glob, case_insensitive, context }) => {
255
+ if (!pattern)
256
+ return 'Error: pattern is required.';
257
+ switch (action) {
258
+ case 'search': return doSearch(cwd, pattern, path, glob, case_insensitive, context);
259
+ case 'find': return doFind(cwd, pattern, path);
260
+ default: return `Unknown action "${action}". Use: search, find.`;
261
+ }
262
+ }
263
+ };
264
+ }
265
+ //# sourceMappingURL=grep.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"grep.js","sourceRoot":"","sources":["../../src/tools/grep.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { Tool } from '../core/types.js';
2
+ export declare function memoryTool(cwd: string): Tool;
3
+ //# sourceMappingURL=memory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory.d.ts","sourceRoot":"","sources":["../../src/tools/memory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAGxC,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CA8B5C"}
@@ -0,0 +1,33 @@
1
+ import { appendGlobalMemory, appendProjectMemory } from '../memory/memory.js';
2
+ export function memoryTool(cwd) {
3
+ return {
4
+ type: 'function',
5
+ function: {
6
+ name: 'memory',
7
+ description: 'Memory operations. Actions: save (persist a fact, decision, or pattern for future sessions).',
8
+ parameters: {
9
+ type: 'object',
10
+ properties: {
11
+ action: { type: 'string', enum: ['save'], description: 'The memory operation to perform.' },
12
+ tier: { type: 'string', enum: ['global', 'project'], description: '"global" for preferences, coding style, patterns that apply everywhere. "project" for architecture decisions, current ticket, PR templates, gotchas specific to this codebase.' },
13
+ content: { type: 'string', description: 'The fact, decision, or pattern to remember.' }
14
+ },
15
+ required: ['action', 'tier', 'content']
16
+ }
17
+ },
18
+ execute: ({ action, tier, content }) => {
19
+ switch (action) {
20
+ case 'save': {
21
+ if (tier === 'global') {
22
+ appendGlobalMemory(content, cwd);
23
+ return 'Saved to global memory.';
24
+ }
25
+ appendProjectMemory(content, cwd);
26
+ return 'Saved to project memory.';
27
+ }
28
+ default: return `Unknown action "${action}". Use: save.`;
29
+ }
30
+ }
31
+ };
32
+ }
33
+ //# sourceMappingURL=memory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory.js","sourceRoot":"","sources":["../../src/tools/memory.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAE9E,MAAM,UAAU,UAAU,CAAC,GAAW;IACpC,OAAO;QACL,IAAI,EAAE,UAAU;QAChB,QAAQ,EAAE;YACR,IAAI,EAAE,QAAQ;YACd,WAAW,EAAE,8FAA8F;YAC3G,UAAU,EAAE;gBACV,IAAI,EAAE,QAAQ;gBACd,UAAU,EAAE;oBACV,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,kCAAkC,EAAE;oBAC3F,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,QAAQ,EAAE,SAAS,CAAC,EAAE,WAAW,EAAE,gLAAgL,EAAE;oBACpP,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,6CAA6C,EAAE;iBACxF;gBACD,QAAQ,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,CAAC;aACxC;SACF;QACD,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAqD,EAAU,EAAE;YAChG,QAAQ,MAAM,EAAE,CAAC;gBACf,KAAK,MAAM,CAAC,CAAC,CAAC;oBACZ,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;wBACtB,kBAAkB,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;wBACjC,OAAO,yBAAyB,CAAC;oBACnC,CAAC;oBACD,mBAAmB,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;oBAClC,OAAO,0BAA0B,CAAC;gBACpC,CAAC;gBACD,OAAO,CAAC,CAAC,OAAO,mBAAmB,MAAM,eAAe,CAAC;YAC3D,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { Tool } from '../core/types.js';
2
+ export declare function planTool(cwd: string): Tool;
3
+ //# sourceMappingURL=plan.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plan.d.ts","sourceRoot":"","sources":["../../src/tools/plan.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAGxC,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAmD1C"}
@@ -0,0 +1,60 @@
1
+ import { savePlan, listPlans, loadPlanByName, appendPlan, setActivePlan } from '../memory/memory.js';
2
+ export function planTool(cwd) {
3
+ return {
4
+ type: 'function',
5
+ function: {
6
+ name: 'plan',
7
+ description: 'Manage task plans. Save a new plan, append to the latest plan, switch the active plan, list all plans, or read a specific plan by name. Plans are timestamped and the latest is automatically loaded as context.',
8
+ parameters: {
9
+ type: 'object',
10
+ properties: {
11
+ action: { type: 'string', enum: ['save', 'list', 'read', 'append', 'switch'], description: '"save" to create a new plan, "append" to add content to the latest plan, "switch" to activate a different plan by name, "list" to see all plans, "read" to view a specific plan.' },
12
+ content: { type: 'string', description: 'Plan content (required for action=save).' },
13
+ name: { type: 'string', description: 'Plan name for save (e.g. "refactor-cli") or read (e.g. "2026-04-13T12-31-22-refactor-cli").' }
14
+ },
15
+ required: ['action']
16
+ }
17
+ },
18
+ execute: ({ action, content, name }) => {
19
+ switch (action) {
20
+ case 'save': {
21
+ if (!content)
22
+ return 'Error: content is required for action=save.';
23
+ const filePath = savePlan(content, name, cwd);
24
+ return `Plan saved: ${filePath}`;
25
+ }
26
+ case 'append': {
27
+ if (!content)
28
+ return 'Error: content is required for action=append.';
29
+ const filePath = appendPlan(content, cwd);
30
+ return `Appended to plan: ${filePath}`;
31
+ }
32
+ case 'switch': {
33
+ if (!name)
34
+ return 'Error: name is required for action=switch. Use action=list to see available plans.';
35
+ const plans = listPlans(cwd);
36
+ const match = plans.find(p => p.name.includes(name));
37
+ if (!match)
38
+ return `No plan matching "${name}". Use action=list to see available plans.`;
39
+ setActivePlan(match.name, cwd);
40
+ return `Switched to plan: ${match.name}`;
41
+ }
42
+ case 'list': {
43
+ const plans = listPlans(cwd);
44
+ if (plans.length === 0)
45
+ return 'No plans saved yet.';
46
+ return plans.map(p => `${p.name} ${p.path}`).join('\n');
47
+ }
48
+ case 'read': {
49
+ if (!name)
50
+ return 'Error: name is required for action=read. Use action=list to see available plans.';
51
+ const result = loadPlanByName(name, cwd);
52
+ return result || `No plan found with name "${name}".`;
53
+ }
54
+ default:
55
+ return `Unknown action "${action}". Use "save", "append", "switch", "list", or "read".`;
56
+ }
57
+ }
58
+ };
59
+ }
60
+ //# sourceMappingURL=plan.js.map