@thegitai/cli 1.0.0-beta.1

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 (101) hide show
  1. package/LICENSE +20 -0
  2. package/README.md +30 -0
  3. package/dist/bin/ai.js +438 -0
  4. package/dist/parsers/tree-sitter-c-sharp.wasm +0 -0
  5. package/dist/parsers/tree-sitter-c.wasm +0 -0
  6. package/dist/parsers/tree-sitter-cpp.wasm +0 -0
  7. package/dist/parsers/tree-sitter-css.wasm +0 -0
  8. package/dist/parsers/tree-sitter-go.wasm +0 -0
  9. package/dist/parsers/tree-sitter-html.wasm +0 -0
  10. package/dist/parsers/tree-sitter-java.wasm +0 -0
  11. package/dist/parsers/tree-sitter-javascript.wasm +0 -0
  12. package/dist/parsers/tree-sitter-objc.wasm +0 -0
  13. package/dist/parsers/tree-sitter-php.wasm +0 -0
  14. package/dist/parsers/tree-sitter-python.wasm +0 -0
  15. package/dist/parsers/tree-sitter-ruby.wasm +0 -0
  16. package/dist/parsers/tree-sitter-rust.wasm +0 -0
  17. package/dist/parsers/tree-sitter-tsx.wasm +0 -0
  18. package/dist/parsers/tree-sitter-typescript.wasm +0 -0
  19. package/dist/src/agent-mode.js +142 -0
  20. package/dist/src/api/auth.js +81 -0
  21. package/dist/src/api/browser-login.js +184 -0
  22. package/dist/src/api/chat.js +346 -0
  23. package/dist/src/api/contracts.js +1 -0
  24. package/dist/src/api/http.js +44 -0
  25. package/dist/src/api/index.js +11 -0
  26. package/dist/src/api/models.js +110 -0
  27. package/dist/src/api/sessions.js +72 -0
  28. package/dist/src/artifact-policy.js +207 -0
  29. package/dist/src/client-state.js +14 -0
  30. package/dist/src/core/clipboard.js +208 -0
  31. package/dist/src/core/open-url.js +32 -0
  32. package/dist/src/edit-journal.js +133 -0
  33. package/dist/src/executor.js +924 -0
  34. package/dist/src/extractors/cpp.js +18 -0
  35. package/dist/src/extractors/csharp.js +16 -0
  36. package/dist/src/extractors/css.js +12 -0
  37. package/dist/src/extractors/go.js +27 -0
  38. package/dist/src/extractors/index.js +52 -0
  39. package/dist/src/extractors/java.js +14 -0
  40. package/dist/src/extractors/javascript.js +33 -0
  41. package/dist/src/extractors/objc.js +14 -0
  42. package/dist/src/extractors/php.js +20 -0
  43. package/dist/src/extractors/python.js +11 -0
  44. package/dist/src/extractors/ruby.js +13 -0
  45. package/dist/src/extractors/rust.js +17 -0
  46. package/dist/src/extractors/utils.js +58 -0
  47. package/dist/src/help-text.js +125 -0
  48. package/dist/src/markdown-renderer.js +112 -0
  49. package/dist/src/patcher.js +279 -0
  50. package/dist/src/project-index.js +221 -0
  51. package/dist/src/repo-map-languages.js +100 -0
  52. package/dist/src/runtime-mode.js +35 -0
  53. package/dist/src/scanner.js +362 -0
  54. package/dist/src/secret-preview.js +137 -0
  55. package/dist/src/session-exit.js +17 -0
  56. package/dist/src/session-safety.js +1012 -0
  57. package/dist/src/session-store.js +266 -0
  58. package/dist/src/session.js +93 -0
  59. package/dist/src/tool-executor.js +188 -0
  60. package/dist/src/tools/code-intel.js +472 -0
  61. package/dist/src/tools/delete-file.js +27 -0
  62. package/dist/src/tools/exec-utils.js +17 -0
  63. package/dist/src/tools/find-symbol.js +70 -0
  64. package/dist/src/tools/get-diagnostics.js +22 -0
  65. package/dist/src/tools/grep-code.js +331 -0
  66. package/dist/src/tools/hover-symbol.js +95 -0
  67. package/dist/src/tools/index.js +73 -0
  68. package/dist/src/tools/list-checkpoints.js +11 -0
  69. package/dist/src/tools/list-directories.js +16 -0
  70. package/dist/src/tools/list-files.js +13 -0
  71. package/dist/src/tools/list-session-edits.js +9 -0
  72. package/dist/src/tools/list-symbols.js +55 -0
  73. package/dist/src/tools/patch-file.js +88 -0
  74. package/dist/src/tools/path-listing.js +83 -0
  75. package/dist/src/tools/read-document.js +111 -0
  76. package/dist/src/tools/read-file.js +109 -0
  77. package/dist/src/tools/restore-checkpoint.js +100 -0
  78. package/dist/src/tools/ripgrep.js +29 -0
  79. package/dist/src/tools/run-command.js +94 -0
  80. package/dist/src/tools/run-node-script.js +210 -0
  81. package/dist/src/tools/search-code.js +37 -0
  82. package/dist/src/tools/shell-diagnostics.js +707 -0
  83. package/dist/src/tools/signature-help.js +118 -0
  84. package/dist/src/tools/str-replace.js +193 -0
  85. package/dist/src/tools/types.js +1 -0
  86. package/dist/src/tools/undo-edit.js +202 -0
  87. package/dist/src/tools/write-file.js +59 -0
  88. package/dist/src/tree-sitter-runtime.js +135 -0
  89. package/dist/src/types.js +1 -0
  90. package/dist/src/ui/paste-collapse.js +22 -0
  91. package/dist/src/ui/prompt-history-store.js +96 -0
  92. package/dist/src/ui/repl.js +2238 -0
  93. package/dist/src/ui/tui/bridge.js +175 -0
  94. package/dist/src/ui/tui/build-frame.js +718 -0
  95. package/dist/src/ui/tui/markdown-render.js +455 -0
  96. package/dist/src/ui/tui/shell-input.js +488 -0
  97. package/dist/src/ui/tui/text.js +30 -0
  98. package/dist/src/ui/tui/types.js +1 -0
  99. package/dist/src/usage.js +47 -0
  100. package/dist/src/utils.js +38 -0
  101. package/package.json +38 -0
@@ -0,0 +1,133 @@
1
+ import { execFileSync } from 'node:child_process';
2
+ import { createHash } from 'node:crypto';
3
+ import { existsSync, lstatSync, readFileSync } from 'node:fs';
4
+ import { resolveProjectPath } from './patcher.js';
5
+ export const MAX_EDIT_JOURNAL_RECORDS = 50;
6
+ const MAX_STORED_CONTENT_CHARS = 1_000_000;
7
+ export function hashContent(content) {
8
+ return `sha256:${createHash('sha256').update(content).digest('hex')}`;
9
+ }
10
+ export function readFileEditSnapshot(rootDir, filePath) {
11
+ try {
12
+ const absPath = resolveProjectPath(rootDir, filePath);
13
+ if (!existsSync(absPath)) {
14
+ return { exists: false, content: null, hash: null };
15
+ }
16
+ if (lstatSync(absPath).isSymbolicLink()) {
17
+ return {
18
+ exists: true,
19
+ content: null,
20
+ hash: null,
21
+ error: `Refusing to snapshot symbolic link: ${filePath}`,
22
+ };
23
+ }
24
+ const content = readFileSync(absPath, 'utf-8');
25
+ return { exists: true, content, hash: hashContent(content) };
26
+ }
27
+ catch (err) {
28
+ return {
29
+ exists: false,
30
+ content: null,
31
+ hash: null,
32
+ error: err?.message ? String(err.message) : String(err),
33
+ };
34
+ }
35
+ }
36
+ export function isGitWorkTree(rootDir) {
37
+ try {
38
+ const output = execFileSync('git', ['-C', rootDir, 'rev-parse', '--is-inside-work-tree'], { encoding: 'utf-8', stdio: ['ignore', 'pipe', 'ignore'] });
39
+ return output.trim() === 'true';
40
+ }
41
+ catch {
42
+ return false;
43
+ }
44
+ }
45
+ export function isEditToolName(toolName) {
46
+ return (toolName === 'write_file' ||
47
+ toolName === 'patch_file' ||
48
+ toolName === 'str_replace' ||
49
+ toolName === 'delete_file');
50
+ }
51
+ export function operationFromSnapshots(before, after) {
52
+ if (before.hash === after.hash)
53
+ return null;
54
+ if (!before.exists && after.exists)
55
+ return 'create';
56
+ if (before.exists && !after.exists)
57
+ return 'delete';
58
+ if (before.exists && after.exists)
59
+ return 'update';
60
+ return null;
61
+ }
62
+ export function canStoreEditSnapshot(snapshot) {
63
+ return (snapshot.error === undefined &&
64
+ (snapshot.content === null ||
65
+ snapshot.content.length <= MAX_STORED_CONTENT_CHARS));
66
+ }
67
+ export function normalizeAssistantEditJournal(value) {
68
+ if (!Array.isArray(value))
69
+ return [];
70
+ return value
71
+ .map((raw) => {
72
+ if (!raw || typeof raw !== 'object')
73
+ return null;
74
+ const entry = raw;
75
+ const toolName = String(entry.toolName ?? '');
76
+ const operation = String(entry.operation ?? '');
77
+ if (!isEditToolName(toolName))
78
+ return null;
79
+ if (operation !== 'create' &&
80
+ operation !== 'update' &&
81
+ operation !== 'delete') {
82
+ return null;
83
+ }
84
+ const id = String(entry.id ?? '').trim();
85
+ const filePath = String(entry.filePath ?? '').trim();
86
+ const toolCallId = String(entry.toolCallId ?? '').trim();
87
+ if (!id || !filePath || !toolCallId)
88
+ return null;
89
+ return {
90
+ id,
91
+ turnId: typeof entry.turnId === 'string' && entry.turnId.trim()
92
+ ? entry.turnId.trim()
93
+ : null,
94
+ toolCallId,
95
+ toolName,
96
+ filePath,
97
+ operation,
98
+ beforeHash: typeof entry.beforeHash === 'string' && entry.beforeHash
99
+ ? entry.beforeHash
100
+ : null,
101
+ afterHash: typeof entry.afterHash === 'string' && entry.afterHash
102
+ ? entry.afterHash
103
+ : null,
104
+ beforeContent: typeof entry.beforeContent === 'string' ? entry.beforeContent : null,
105
+ createdAt: typeof entry.createdAt === 'string' && entry.createdAt
106
+ ? entry.createdAt
107
+ : new Date().toISOString(),
108
+ revertedAt: typeof entry.revertedAt === 'string' && entry.revertedAt
109
+ ? entry.revertedAt
110
+ : null,
111
+ revertedByToolCallId: typeof entry.revertedByToolCallId === 'string' &&
112
+ entry.revertedByToolCallId
113
+ ? entry.revertedByToolCallId
114
+ : null,
115
+ gitWorkTree: entry.gitWorkTree === true,
116
+ };
117
+ })
118
+ .filter(Boolean)
119
+ .slice(-MAX_EDIT_JOURNAL_RECORDS);
120
+ }
121
+ export function formatRecentAssistantEdits(records, maxItems = 8) {
122
+ const active = records.filter((record) => !record.revertedAt);
123
+ if (!active.length)
124
+ return '';
125
+ return active
126
+ .slice(-maxItems)
127
+ .reverse()
128
+ .map((record) => {
129
+ const turn = record.turnId ? `, ${record.turnId}` : '';
130
+ return `- ${record.id}: ${record.operation} ${record.filePath} via ${record.toolName}${turn}`;
131
+ })
132
+ .join('\n');
133
+ }