@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,175 @@
1
+ import { spawn } from 'node:child_process';
2
+ import { createInterface } from 'node:readline';
3
+ import { existsSync } from 'node:fs';
4
+ import { createRequire } from 'node:module';
5
+ import path from 'node:path';
6
+ import { fileURLToPath } from 'node:url';
7
+ const requireFromHere = createRequire(import.meta.url);
8
+ function normalizeChildMessage(raw) {
9
+ if (raw.op === 'ready') {
10
+ return {
11
+ op: 'ready',
12
+ cols: Number(raw.cols ?? 80),
13
+ rows: Number(raw.rows ?? 24),
14
+ };
15
+ }
16
+ if (raw.op === 'closed') {
17
+ return { op: 'closed' };
18
+ }
19
+ if (raw.op !== 'event') {
20
+ return null;
21
+ }
22
+ if (raw.kind === 'paste') {
23
+ return { op: 'event', kind: 'paste', text: String(raw.text ?? '') };
24
+ }
25
+ if (raw.kind === 'resize') {
26
+ return {
27
+ op: 'event',
28
+ kind: 'resize',
29
+ cols: Number(raw.cols ?? 80),
30
+ rows: Number(raw.rows ?? 24),
31
+ };
32
+ }
33
+ if (raw.kind === 'selectionCopy') {
34
+ return {
35
+ op: 'event',
36
+ kind: 'selectionCopy',
37
+ text: String(raw.text ?? ''),
38
+ };
39
+ }
40
+ if (raw.kind === 'linkCopy') {
41
+ return {
42
+ op: 'event',
43
+ kind: 'linkCopy',
44
+ url: String(raw.url ?? ''),
45
+ };
46
+ }
47
+ if (raw.kind === 'linkOpen') {
48
+ return {
49
+ op: 'event',
50
+ kind: 'linkOpen',
51
+ url: String(raw.url ?? ''),
52
+ };
53
+ }
54
+ if (raw.kind === 'contextMenu') {
55
+ return { op: 'event', kind: 'contextMenu' };
56
+ }
57
+ if (raw.kind === 'transcriptScroll') {
58
+ return {
59
+ op: 'event',
60
+ kind: 'transcriptScroll',
61
+ deltaLines: Number(raw.deltaLines ?? raw.delta_lines ?? 0),
62
+ };
63
+ }
64
+ if (raw.kind !== 'key') {
65
+ return null;
66
+ }
67
+ const bool = (value) => value === true;
68
+ return {
69
+ op: 'event',
70
+ kind: 'key',
71
+ input: String(raw.input ?? ''),
72
+ ctrl: bool(raw.ctrl),
73
+ meta: bool(raw.meta),
74
+ shift: bool(raw.shift),
75
+ escape: bool(raw.escape),
76
+ returnKey: bool(raw.returnKey ?? raw.return_key),
77
+ tab: bool(raw.tab),
78
+ backspace: bool(raw.backspace),
79
+ delete: bool(raw.delete),
80
+ upArrow: bool(raw.upArrow ?? raw.up_arrow),
81
+ downArrow: bool(raw.downArrow ?? raw.down_arrow),
82
+ leftArrow: bool(raw.leftArrow ?? raw.left_arrow),
83
+ rightArrow: bool(raw.rightArrow ?? raw.right_arrow),
84
+ home: bool(raw.home),
85
+ end: bool(raw.end),
86
+ paste: bool(raw.paste),
87
+ pageUp: bool(raw.pageUp ?? raw.page_up),
88
+ pageDown: bool(raw.pageDown ?? raw.page_down),
89
+ };
90
+ }
91
+ export function resolveTuiBinaryPath() {
92
+ const binaryName = process.platform === 'win32' ? 'thegitai-tui.exe' : 'thegitai-tui';
93
+ const platformPackage = `@thegitai/tui-${process.platform}-${process.arch}`;
94
+ // 1) Published per-platform optional dependency (the installed-from-npm path).
95
+ try {
96
+ return requireFromHere.resolve(`${platformPackage}/${binaryName}`);
97
+ }
98
+ catch {
99
+ // Not installed (unsupported platform yet, or local dev) — fall through.
100
+ }
101
+ // 2) Local dev build: `npm run build:tui` populates the workspace bin/.
102
+ const moduleDir = path.dirname(fileURLToPath(import.meta.url));
103
+ const devCandidates = [
104
+ path.join(moduleDir, '../../../bin', binaryName),
105
+ path.join(moduleDir, '../../../../bin', binaryName),
106
+ ];
107
+ const devBinary = devCandidates.find((candidate) => existsSync(candidate));
108
+ if (devBinary) {
109
+ return devBinary;
110
+ }
111
+ throw new Error(`Missing thegitai-tui binary. Expected the optional dependency "${platformPackage}" (your platform may not be supported yet), ` +
112
+ `or a local build at one of: ${devCandidates.join(', ')} (run "npm run build:tui").`);
113
+ }
114
+ export function spawnTuiProcess(options = {}) {
115
+ const binaryPath = resolveTuiBinaryPath();
116
+ return spawn(binaryPath, [], {
117
+ stdio: ['pipe', 'pipe', 'inherit'],
118
+ env: { ...process.env, ...options.env },
119
+ });
120
+ }
121
+ export function createRatatuiBridge() {
122
+ const child = spawnTuiProcess();
123
+ const rl = createInterface({ input: child.stdout });
124
+ let eventHandler = null;
125
+ let closed = false;
126
+ rl.on('line', (line) => {
127
+ const trimmed = line.trim();
128
+ if (!trimmed)
129
+ return;
130
+ try {
131
+ const message = normalizeChildMessage(JSON.parse(trimmed));
132
+ if (!message)
133
+ return;
134
+ eventHandler?.(message);
135
+ if (message.op === 'closed') {
136
+ closed = true;
137
+ }
138
+ }
139
+ catch {
140
+ // ignore malformed protocol lines
141
+ }
142
+ });
143
+ child.on('exit', () => {
144
+ closed = true;
145
+ eventHandler?.({ op: 'closed' });
146
+ });
147
+ const writeParent = (payload) => {
148
+ if (closed)
149
+ return;
150
+ child.stdin.write(`${JSON.stringify(payload)}\n`);
151
+ };
152
+ return {
153
+ onEvent(handler) {
154
+ eventHandler = handler;
155
+ },
156
+ render(frame) {
157
+ writeParent({ op: 'frame', ...frame });
158
+ },
159
+ clear() {
160
+ writeParent({ op: 'clear' });
161
+ },
162
+ async close() {
163
+ if (closed)
164
+ return;
165
+ writeParent({ op: 'quit' });
166
+ closed = true;
167
+ child.stdin.end();
168
+ await new Promise((resolve) => {
169
+ child.once('exit', () => resolve());
170
+ setTimeout(resolve, 500);
171
+ });
172
+ rl.close();
173
+ },
174
+ };
175
+ }