@stan-chen/simple-cli 0.2.3 → 0.2.4

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 (136) hide show
  1. package/README.md +62 -63
  2. package/dist/anyllm.py +62 -0
  3. package/dist/builtins.d.ts +726 -0
  4. package/dist/builtins.js +481 -0
  5. package/dist/cli.d.ts +0 -4
  6. package/dist/cli.js +34 -493
  7. package/dist/engine.d.ts +33 -0
  8. package/dist/engine.js +138 -0
  9. package/dist/learnings.d.ts +15 -0
  10. package/dist/learnings.js +54 -0
  11. package/dist/llm.d.ts +18 -0
  12. package/dist/llm.js +66 -0
  13. package/dist/mcp.d.ts +132 -0
  14. package/dist/mcp.js +43 -0
  15. package/dist/skills.d.ts +5 -16
  16. package/dist/skills.js +91 -253
  17. package/dist/tui.d.ts +1 -0
  18. package/dist/tui.js +10 -0
  19. package/package.json +10 -6
  20. package/dist/claw/jit.d.ts +0 -5
  21. package/dist/claw/jit.js +0 -138
  22. package/dist/claw/management.d.ts +0 -3
  23. package/dist/claw/management.js +0 -107
  24. package/dist/commands/add.d.ts +0 -9
  25. package/dist/commands/add.js +0 -50
  26. package/dist/commands/git/commit.d.ts +0 -12
  27. package/dist/commands/git/commit.js +0 -98
  28. package/dist/commands/git/status.d.ts +0 -6
  29. package/dist/commands/git/status.js +0 -42
  30. package/dist/commands/index.d.ts +0 -16
  31. package/dist/commands/index.js +0 -377
  32. package/dist/commands/mcp/status.d.ts +0 -6
  33. package/dist/commands/mcp/status.js +0 -31
  34. package/dist/commands/swarm.d.ts +0 -36
  35. package/dist/commands/swarm.js +0 -236
  36. package/dist/commands.d.ts +0 -32
  37. package/dist/commands.js +0 -427
  38. package/dist/context.d.ts +0 -116
  39. package/dist/context.js +0 -337
  40. package/dist/index.d.ts +0 -6
  41. package/dist/index.js +0 -109
  42. package/dist/lib/agent.d.ts +0 -99
  43. package/dist/lib/agent.js +0 -313
  44. package/dist/lib/editor.d.ts +0 -74
  45. package/dist/lib/editor.js +0 -441
  46. package/dist/lib/git.d.ts +0 -164
  47. package/dist/lib/git.js +0 -356
  48. package/dist/lib/shim.d.ts +0 -4
  49. package/dist/lib/shim.js +0 -30
  50. package/dist/lib/ui.d.ts +0 -159
  51. package/dist/lib/ui.js +0 -277
  52. package/dist/mcp/client.d.ts +0 -22
  53. package/dist/mcp/client.js +0 -81
  54. package/dist/mcp/manager.d.ts +0 -186
  55. package/dist/mcp/manager.js +0 -446
  56. package/dist/prompts/provider.d.ts +0 -22
  57. package/dist/prompts/provider.js +0 -79
  58. package/dist/providers/index.d.ts +0 -31
  59. package/dist/providers/index.js +0 -93
  60. package/dist/providers/multi.d.ts +0 -12
  61. package/dist/providers/multi.js +0 -28
  62. package/dist/registry.d.ts +0 -29
  63. package/dist/registry.js +0 -443
  64. package/dist/repoMap.d.ts +0 -5
  65. package/dist/repoMap.js +0 -79
  66. package/dist/router.d.ts +0 -41
  67. package/dist/router.js +0 -118
  68. package/dist/swarm/coordinator.d.ts +0 -86
  69. package/dist/swarm/coordinator.js +0 -257
  70. package/dist/swarm/index.d.ts +0 -28
  71. package/dist/swarm/index.js +0 -29
  72. package/dist/swarm/task.d.ts +0 -104
  73. package/dist/swarm/task.js +0 -221
  74. package/dist/swarm/types.d.ts +0 -132
  75. package/dist/swarm/types.js +0 -37
  76. package/dist/swarm/worker.d.ts +0 -109
  77. package/dist/swarm/worker.js +0 -369
  78. package/dist/tools/analyzeFile.d.ts +0 -16
  79. package/dist/tools/analyzeFile.js +0 -43
  80. package/dist/tools/analyze_file.d.ts +0 -16
  81. package/dist/tools/analyze_file.js +0 -43
  82. package/dist/tools/clawBrain.d.ts +0 -23
  83. package/dist/tools/clawBrain.js +0 -136
  84. package/dist/tools/claw_brain.d.ts +0 -23
  85. package/dist/tools/claw_brain.js +0 -139
  86. package/dist/tools/deleteFile.d.ts +0 -19
  87. package/dist/tools/deleteFile.js +0 -36
  88. package/dist/tools/delete_file.d.ts +0 -19
  89. package/dist/tools/delete_file.js +0 -36
  90. package/dist/tools/fileOps.d.ts +0 -22
  91. package/dist/tools/fileOps.js +0 -43
  92. package/dist/tools/file_ops.d.ts +0 -22
  93. package/dist/tools/file_ops.js +0 -43
  94. package/dist/tools/git.d.ts +0 -40
  95. package/dist/tools/git.js +0 -236
  96. package/dist/tools/glob.d.ts +0 -34
  97. package/dist/tools/glob.js +0 -165
  98. package/dist/tools/grep.d.ts +0 -53
  99. package/dist/tools/grep.js +0 -296
  100. package/dist/tools/linter.d.ts +0 -35
  101. package/dist/tools/linter.js +0 -407
  102. package/dist/tools/listDir.d.ts +0 -29
  103. package/dist/tools/listDir.js +0 -50
  104. package/dist/tools/list_dir.d.ts +0 -29
  105. package/dist/tools/list_dir.js +0 -50
  106. package/dist/tools/memory.d.ts +0 -34
  107. package/dist/tools/memory.js +0 -215
  108. package/dist/tools/organizer.d.ts +0 -1
  109. package/dist/tools/organizer.js +0 -65
  110. package/dist/tools/readFiles.d.ts +0 -25
  111. package/dist/tools/readFiles.js +0 -31
  112. package/dist/tools/read_files.d.ts +0 -25
  113. package/dist/tools/read_files.js +0 -31
  114. package/dist/tools/reloadTools.d.ts +0 -11
  115. package/dist/tools/reloadTools.js +0 -22
  116. package/dist/tools/reload_tools.d.ts +0 -11
  117. package/dist/tools/reload_tools.js +0 -22
  118. package/dist/tools/runCommand.d.ts +0 -32
  119. package/dist/tools/runCommand.js +0 -79
  120. package/dist/tools/run_command.d.ts +0 -32
  121. package/dist/tools/run_command.js +0 -103
  122. package/dist/tools/scheduler.d.ts +0 -25
  123. package/dist/tools/scheduler.js +0 -65
  124. package/dist/tools/scraper.d.ts +0 -31
  125. package/dist/tools/scraper.js +0 -211
  126. package/dist/tools/writeFiles.d.ts +0 -63
  127. package/dist/tools/writeFiles.js +0 -87
  128. package/dist/tools/write_files.d.ts +0 -84
  129. package/dist/tools/write_files.js +0 -91
  130. package/dist/tools/write_to_file.d.ts +0 -15
  131. package/dist/tools/write_to_file.js +0 -21
  132. package/dist/ui/server.d.ts +0 -5
  133. package/dist/ui/server.js +0 -74
  134. package/dist/watcher.d.ts +0 -35
  135. package/dist/watcher.js +0 -164
  136. /package/{docs/assets → assets}/logo.jpeg +0 -0
@@ -1,441 +0,0 @@
1
- /**
2
- * Intelligent Code Editor using ts-morph and fuzzy matching
3
- * Provides Aider-style SEARCH/REPLACE with smart matching
4
- */
5
- import { Project, SyntaxKind } from 'ts-morph';
6
- import { readFile, writeFile, mkdir } from 'fs/promises';
7
- import { existsSync } from 'fs';
8
- import { dirname } from 'path';
9
- import * as diff from 'diff';
10
- import levenshtein from 'fast-levenshtein';
11
- /**
12
- * Calculate similarity ratio between two strings (0-1)
13
- */
14
- function similarity(a, b) {
15
- if (a === b)
16
- return 1;
17
- if (!a || !b)
18
- return 0;
19
- const distance = levenshtein.get(a, b);
20
- const maxLen = Math.max(a.length, b.length);
21
- return 1 - distance / maxLen;
22
- }
23
- /**
24
- * Find the most similar chunk in content
25
- */
26
- function findMostSimilarChunk(content, search, threshold = 0.6) {
27
- const contentLines = content.split('\n');
28
- const searchLines = search.split('\n');
29
- const searchLen = searchLines.length;
30
- let bestMatch = { start: -1, end: -1, similarity: 0, text: '' };
31
- // Sliding window search
32
- for (let i = 0; i <= contentLines.length - searchLen; i++) {
33
- const chunk = contentLines.slice(i, i + searchLen).join('\n');
34
- const sim = similarity(chunk, search);
35
- if (sim > bestMatch.similarity) {
36
- bestMatch = {
37
- start: i,
38
- end: i + searchLen,
39
- similarity: sim,
40
- text: chunk,
41
- };
42
- }
43
- }
44
- // Also try with flexible window sizes (+/- 2 lines)
45
- for (let delta = -2; delta <= 2; delta++) {
46
- if (delta === 0)
47
- continue;
48
- const adjustedLen = searchLen + delta;
49
- if (adjustedLen < 1)
50
- continue;
51
- for (let i = 0; i <= contentLines.length - adjustedLen; i++) {
52
- const chunk = contentLines.slice(i, i + adjustedLen).join('\n');
53
- const sim = similarity(chunk, search);
54
- if (sim > bestMatch.similarity) {
55
- bestMatch = {
56
- start: i,
57
- end: i + adjustedLen,
58
- similarity: sim,
59
- text: chunk,
60
- };
61
- }
62
- }
63
- }
64
- if (bestMatch.similarity >= threshold) {
65
- return bestMatch;
66
- }
67
- return null;
68
- }
69
- /**
70
- * Handle whitespace-flexible matching
71
- */
72
- function matchWithFlexibleWhitespace(contentLines, searchLines) {
73
- // Strip leading whitespace from search to compare content only
74
- const strippedSearch = searchLines.map(line => line.trimStart());
75
- const searchLen = searchLines.length;
76
- for (let i = 0; i <= contentLines.length - searchLen; i++) {
77
- const chunk = contentLines.slice(i, i + searchLen);
78
- const strippedChunk = chunk.map(line => line.trimStart());
79
- // Check if content matches when ignoring leading whitespace
80
- if (strippedChunk.every((line, idx) => line === strippedSearch[idx])) {
81
- // Calculate the indent difference
82
- const firstNonEmptyIdx = chunk.findIndex(line => line.trim());
83
- if (firstNonEmptyIdx >= 0) {
84
- const actualIndent = chunk[firstNonEmptyIdx].match(/^(\s*)/)?.[1] || '';
85
- const searchIndent = searchLines[firstNonEmptyIdx].match(/^(\s*)/)?.[1] || '';
86
- const indentDiff = actualIndent.slice(0, actualIndent.length - searchIndent.length);
87
- return {
88
- start: i,
89
- end: i + searchLen,
90
- indent: indentDiff,
91
- };
92
- }
93
- return { start: i, end: i + searchLen, indent: '' };
94
- }
95
- }
96
- return null;
97
- }
98
- /**
99
- * Apply indent adjustment to replacement text
100
- */
101
- function applyIndent(text, indent) {
102
- return text
103
- .split('\n')
104
- .map(line => (line.trim() ? indent + line : line))
105
- .join('\n');
106
- }
107
- /**
108
- * Handle ... (ellipsis) in search/replace blocks
109
- */
110
- function handleEllipsis(content, search, replace) {
111
- const dotsPattern = /^\s*\.\.\.\s*$/m;
112
- if (!dotsPattern.test(search)) {
113
- return null;
114
- }
115
- const searchParts = search.split(dotsPattern);
116
- const replaceParts = replace.split(dotsPattern);
117
- if (searchParts.length !== replaceParts.length) {
118
- return null;
119
- }
120
- let result = content;
121
- for (let i = 0; i < searchParts.length; i++) {
122
- const searchPart = searchParts[i].trim();
123
- const replacePart = replaceParts[i].trim();
124
- if (!searchPart && !replacePart)
125
- continue;
126
- if (!searchPart && replacePart) {
127
- // Append to end
128
- result = result.trimEnd() + '\n' + replacePart;
129
- continue;
130
- }
131
- if (!result.includes(searchPart)) {
132
- return null;
133
- }
134
- result = result.replace(searchPart, replacePart);
135
- }
136
- return result;
137
- }
138
- /**
139
- * Apply a single edit to content
140
- */
141
- export function applyEdit(content, search, replace) {
142
- // Normalize line endings
143
- content = content.replace(/\r\n/g, '\n');
144
- search = search.replace(/\r\n/g, '\n').trim();
145
- replace = replace.replace(/\r\n/g, '\n');
146
- // 1. Try exact match
147
- if (content.includes(search)) {
148
- return {
149
- success: true,
150
- content: content.replace(search, replace),
151
- method: 'exact',
152
- };
153
- }
154
- // 2. Try ellipsis handling
155
- const ellipsisResult = handleEllipsis(content, search, replace);
156
- if (ellipsisResult) {
157
- return {
158
- success: true,
159
- content: ellipsisResult,
160
- method: 'ellipsis',
161
- };
162
- }
163
- // 3. Try whitespace-flexible matching
164
- const contentLines = content.split('\n');
165
- const searchLines = search.split('\n');
166
- const wsMatch = matchWithFlexibleWhitespace(contentLines, searchLines);
167
- if (wsMatch) {
168
- const adjustedReplace = applyIndent(replace, wsMatch.indent);
169
- const newLines = [
170
- ...contentLines.slice(0, wsMatch.start),
171
- ...adjustedReplace.split('\n'),
172
- ...contentLines.slice(wsMatch.end),
173
- ];
174
- return {
175
- success: true,
176
- content: newLines.join('\n'),
177
- method: 'whitespace-flex',
178
- };
179
- }
180
- // 4. Try fuzzy matching
181
- const fuzzyMatch = findMostSimilarChunk(content, search, 0.7);
182
- if (fuzzyMatch) {
183
- const newLines = [
184
- ...contentLines.slice(0, fuzzyMatch.start),
185
- ...replace.split('\n'),
186
- ...contentLines.slice(fuzzyMatch.end),
187
- ];
188
- return {
189
- success: true,
190
- content: newLines.join('\n'),
191
- method: `fuzzy (${(fuzzyMatch.similarity * 100).toFixed(0)}% match)`,
192
- };
193
- }
194
- // 5. Failed - provide suggestion
195
- const similarChunk = findMostSimilarChunk(content, search, 0.4);
196
- let suggestion;
197
- if (similarChunk) {
198
- suggestion = `Did you mean to match these lines (${(similarChunk.similarity * 100).toFixed(0)}% similar)?
199
-
200
- \`\`\`
201
- ${similarChunk.text}
202
- \`\`\``;
203
- }
204
- return {
205
- success: false,
206
- content,
207
- method: 'none',
208
- suggestion,
209
- };
210
- }
211
- /**
212
- * Apply edits to a file
213
- */
214
- export async function applyFileEdits(edits) {
215
- const results = [];
216
- const fileContents = new Map();
217
- // Group edits by file
218
- const editsByFile = new Map();
219
- for (const edit of edits) {
220
- const existing = editsByFile.get(edit.file) || [];
221
- existing.push(edit);
222
- editsByFile.set(edit.file, existing);
223
- }
224
- for (const [file, fileEdits] of editsByFile) {
225
- // Load file content
226
- let content;
227
- try {
228
- if (existsSync(file)) {
229
- content = await readFile(file, 'utf-8');
230
- }
231
- else {
232
- // New file - ensure directory exists
233
- await mkdir(dirname(file), { recursive: true });
234
- content = '';
235
- }
236
- }
237
- catch (error) {
238
- for (const edit of fileEdits) {
239
- results.push({
240
- file,
241
- success: false,
242
- applied: false,
243
- error: `Failed to read file: ${error instanceof Error ? error.message : error}`,
244
- });
245
- }
246
- continue;
247
- }
248
- // Apply each edit
249
- let currentContent = content;
250
- let anyApplied = false;
251
- for (const edit of fileEdits) {
252
- // Handle empty search (new file or append)
253
- if (!edit.search.trim()) {
254
- currentContent = currentContent + edit.replace;
255
- results.push({
256
- file,
257
- success: true,
258
- applied: true,
259
- diff: `+++ ${file}\n+ ${edit.replace.split('\n').join('\n+ ')}`,
260
- });
261
- anyApplied = true;
262
- continue;
263
- }
264
- const result = applyEdit(currentContent, edit.search, edit.replace);
265
- if (result.success) {
266
- const diffText = diff.createPatch(file, currentContent, result.content);
267
- currentContent = result.content;
268
- results.push({
269
- file,
270
- success: true,
271
- applied: true,
272
- diff: diffText,
273
- });
274
- anyApplied = true;
275
- }
276
- else {
277
- results.push({
278
- file,
279
- success: false,
280
- applied: false,
281
- error: 'SEARCH block did not match any content in file',
282
- suggestion: result.suggestion,
283
- });
284
- }
285
- }
286
- // Write back if any edits were applied
287
- if (anyApplied) {
288
- try {
289
- await writeFile(file, currentContent);
290
- }
291
- catch (error) {
292
- results.push({
293
- file,
294
- success: false,
295
- applied: false,
296
- error: `Failed to write file: ${error instanceof Error ? error.message : error}`,
297
- });
298
- }
299
- }
300
- }
301
- return results;
302
- }
303
- /**
304
- * Parse SEARCH/REPLACE blocks from LLM response
305
- */
306
- export function parseEditBlocks(response, validFiles) {
307
- const blocks = [];
308
- const seen = new Set(); // Track unique blocks by content
309
- // Pattern for <<<<<<< SEARCH ... ======= ... >>>>>>> REPLACE inside code fence
310
- // Captures: filename on line before ```, then search, then replace
311
- const blockPattern = /([^\n]+)\n```[^\n]*\n<<<<<<< SEARCH\n([\s\S]*?)\n=======\n([\s\S]*?)\n>>>>>>> REPLACE\n```/g;
312
- // Also try without code fence (for plain text format)
313
- const altPattern = /([^\n]+)\n<<<<<<< SEARCH\n([\s\S]*?)\n=======\n([\s\S]*?)\n>>>>>>> REPLACE/g;
314
- const processMatch = (match) => {
315
- let file = match[1].trim();
316
- const search = match[2];
317
- const replace = match[3];
318
- // Create a unique key for deduplication
319
- const key = `${search}|||${replace}`;
320
- if (seen.has(key)) {
321
- return; // Skip duplicate
322
- }
323
- seen.add(key);
324
- // Clean up filename - strip markdown formatting
325
- file = file.replace(/^[#*]+\s*/, ''); // Remove leading # and *
326
- file = file.replace(/`/g, ''); // Remove all backticks
327
- file = file.replace(/\s*[#*]+$/, ''); // Remove trailing # and *
328
- file = file.replace(/^(File:\s*|Filename:\s*)/i, '');
329
- file = file.trim();
330
- // Skip if filename looks like a language hint (e.g., "typescript", "javascript")
331
- const languageHints = ['typescript', 'javascript', 'python', 'java', 'go', 'rust', 'tsx', 'jsx', 'ts', 'js', 'py', 'rb', 'cpp', 'c', 'cs', 'sh', 'bash', 'json', 'yaml', 'yml', 'md', 'html', 'css'];
332
- if (languageHints.includes(file.toLowerCase())) {
333
- return; // Skip - this is likely a language hint, not a filename
334
- }
335
- // Try to match against valid files
336
- if (validFiles && validFiles.length > 0) {
337
- const exactMatch = validFiles.find(f => f === file || f.endsWith('/' + file));
338
- if (exactMatch) {
339
- file = exactMatch;
340
- }
341
- }
342
- blocks.push({ file, search, replace });
343
- };
344
- // First try the fenced pattern (more specific)
345
- let match;
346
- while ((match = blockPattern.exec(response)) !== null) {
347
- processMatch(match);
348
- }
349
- // Then try the alt pattern for any remaining blocks
350
- while ((match = altPattern.exec(response)) !== null) {
351
- processMatch(match);
352
- }
353
- return blocks;
354
- }
355
- /**
356
- * TypeScript/JavaScript AST-aware editing using ts-morph
357
- */
358
- export class ASTEditor {
359
- project;
360
- constructor() {
361
- this.project = new Project({
362
- useInMemoryFileSystem: true,
363
- compilerOptions: {
364
- allowJs: true,
365
- checkJs: false,
366
- },
367
- });
368
- }
369
- /**
370
- * Add a file to the project
371
- */
372
- addFile(path, content) {
373
- return this.project.createSourceFile(path, content, { overwrite: true });
374
- }
375
- /**
376
- * Get or create a source file
377
- */
378
- getSourceFile(path, content) {
379
- let sourceFile = this.project.getSourceFile(path);
380
- if (!sourceFile && content) {
381
- sourceFile = this.addFile(path, content);
382
- }
383
- return sourceFile;
384
- }
385
- /**
386
- * Find a function by name
387
- */
388
- findFunction(sourceFile, name) {
389
- // Try function declarations
390
- const funcDecl = sourceFile.getFunction(name);
391
- if (funcDecl)
392
- return funcDecl;
393
- // Try variable declarations with arrow functions
394
- const varDecl = sourceFile.getVariableDeclaration(name);
395
- if (varDecl)
396
- return varDecl;
397
- // Try method declarations in classes
398
- for (const classDecl of sourceFile.getClasses()) {
399
- const method = classDecl.getMethod(name);
400
- if (method)
401
- return method;
402
- }
403
- return undefined;
404
- }
405
- /**
406
- * Find a class by name
407
- */
408
- findClass(sourceFile, name) {
409
- return sourceFile.getClass(name);
410
- }
411
- /**
412
- * Rename a symbol across the project
413
- */
414
- renameSymbol(sourceFile, oldName, newName) {
415
- const identifier = sourceFile.getDescendantsOfKind(SyntaxKind.Identifier)
416
- .find(id => id.getText() === oldName);
417
- if (identifier) {
418
- identifier.rename(newName);
419
- return true;
420
- }
421
- return false;
422
- }
423
- /**
424
- * Get the modified content of a file
425
- */
426
- getContent(path) {
427
- return this.project.getSourceFile(path)?.getFullText();
428
- }
429
- /**
430
- * Save all changes
431
- */
432
- async saveAll() {
433
- await this.project.save();
434
- }
435
- }
436
- /**
437
- * Create a code editor instance
438
- */
439
- export function createEditor() {
440
- return new ASTEditor();
441
- }
package/dist/lib/git.d.ts DELETED
@@ -1,164 +0,0 @@
1
- /**
2
- * Git Operations using simple-git
3
- * Reliable git operations leveraging the native Git binary
4
- */
5
- import { SimpleGit, StatusResult, LogResult, BranchSummary } from 'simple-git';
6
- export interface GitConfig {
7
- cwd?: string;
8
- timeout?: number;
9
- }
10
- export interface CommitOptions {
11
- message: string;
12
- files?: string[];
13
- amend?: boolean;
14
- noVerify?: boolean;
15
- author?: string;
16
- }
17
- export interface DiffOptions {
18
- staged?: boolean;
19
- file?: string;
20
- from?: string;
21
- to?: string;
22
- }
23
- /**
24
- * GitManager - Wrapper around simple-git for reliable git operations
25
- */
26
- export declare class GitManager {
27
- private git;
28
- private cwd;
29
- constructor(config?: GitConfig);
30
- /**
31
- * Check if current directory is a git repository
32
- */
33
- isRepo(): Promise<boolean>;
34
- /**
35
- * Initialize a new git repository
36
- */
37
- init(): Promise<void>;
38
- /**
39
- * Get repository status
40
- */
41
- status(): Promise<StatusResult>;
42
- /**
43
- * Get current branch name
44
- */
45
- currentBranch(): Promise<string | null>;
46
- /**
47
- * Get all branches
48
- */
49
- branches(): Promise<BranchSummary>;
50
- /**
51
- * Checkout a branch
52
- */
53
- checkout(branch: string, create?: boolean): Promise<void>;
54
- /**
55
- * Stage files
56
- */
57
- add(files: string | string[]): Promise<void>;
58
- /**
59
- * Stage all changes
60
- */
61
- addAll(): Promise<void>;
62
- /**
63
- * Commit changes
64
- */
65
- commit(options: CommitOptions): Promise<{
66
- hash: string;
67
- message: string;
68
- } | null>;
69
- /**
70
- * Get diff
71
- */
72
- diff(options?: DiffOptions): Promise<string>;
73
- /**
74
- * Get staged diff
75
- */
76
- stagedDiff(): Promise<string>;
77
- /**
78
- * Get commit log
79
- */
80
- log(maxCount?: number): Promise<LogResult>;
81
- /**
82
- * Get the last commit
83
- */
84
- lastCommit(): Promise<{
85
- hash: string;
86
- message: string;
87
- author: string;
88
- date: string;
89
- } | null>;
90
- /**
91
- * Undo the last commit (soft reset)
92
- */
93
- undoLastCommit(): Promise<boolean>;
94
- /**
95
- * Hard reset to a commit
96
- */
97
- hardReset(commit?: string): Promise<void>;
98
- /**
99
- * Stash changes
100
- */
101
- stash(message?: string): Promise<void>;
102
- /**
103
- * Pop stash
104
- */
105
- stashPop(): Promise<void>;
106
- /**
107
- * Get list of tracked files
108
- */
109
- trackedFiles(): Promise<string[]>;
110
- /**
111
- * Get list of changed files (staged + unstaged)
112
- */
113
- changedFiles(): Promise<string[]>;
114
- /**
115
- * Check if a file is ignored
116
- */
117
- isIgnored(file: string): Promise<boolean>;
118
- /**
119
- * Get blame for a file
120
- */
121
- blame(file: string): Promise<string>;
122
- /**
123
- * Show a specific commit
124
- */
125
- show(commit: string): Promise<string>;
126
- /**
127
- * Get the root directory of the repository
128
- */
129
- rootDir(): Promise<string | null>;
130
- /**
131
- * Pull changes from remote
132
- */
133
- pull(remote?: string, branch?: string): Promise<void>;
134
- /**
135
- * Push changes to remote
136
- */
137
- push(remote?: string, branch?: string, options?: {
138
- setUpstream?: boolean;
139
- }): Promise<void>;
140
- /**
141
- * Create a new branch from current HEAD
142
- */
143
- createBranch(name: string): Promise<void>;
144
- /**
145
- * Delete a branch
146
- */
147
- deleteBranch(name: string, force?: boolean): Promise<void>;
148
- /**
149
- * Merge a branch into current branch
150
- */
151
- merge(branch: string): Promise<void>;
152
- /**
153
- * Get the raw simple-git instance for advanced operations
154
- */
155
- raw(): SimpleGit;
156
- }
157
- /**
158
- * Get or create a GitManager instance
159
- */
160
- export declare function getGitManager(config?: GitConfig): GitManager;
161
- /**
162
- * Generate AI commit message from diff
163
- */
164
- export declare function generateCommitMessage(diff: string, generateFn: (prompt: string) => Promise<string>, context?: string): Promise<string>;