codebuff 1.0.318 → 1.0.319
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.
- package/dist/__tests__/display.test.d.ts +1 -0
- package/dist/__tests__/display.test.js +174 -0
- package/dist/__tests__/display.test.js.map +1 -0
- package/dist/background-process-manager.d.ts +1 -1
- package/dist/background-process-manager.js +3 -3
- package/dist/browser-runner.d.ts +1 -1
- package/dist/browser-runner.js +4 -4
- package/dist/chat-storage.d.ts +1 -1
- package/dist/chat-storage.js +1 -1
- package/dist/checkpoints/checkpoint-manager.d.ts +1 -1
- package/dist/checkpoints/checkpoint-manager.js +1 -1
- package/dist/checkpoints/file-manager.js +1 -1
- package/dist/cli-handlers/api-key.d.ts +1 -1
- package/dist/cli-handlers/api-key.js +1 -1
- package/dist/cli-handlers/diff.d.ts +1 -1
- package/dist/cli-handlers/inititalization-flow.js +1 -1
- package/dist/cli.d.ts +1 -1
- package/dist/cli.js +4 -3
- package/dist/cli.js.map +1 -1
- package/dist/client.d.ts +6 -6
- package/dist/client.js +9 -9
- package/dist/code-map/tsconfig.tsbuildinfo +1 -1
- package/dist/common/actions.d.ts +5 -4
- package/dist/common/actions.d.ts.map +1 -0
- package/dist/common/analytics.d.ts +1 -0
- package/dist/common/analytics.d.ts.map +1 -0
- package/dist/common/analytics.js +5 -5
- package/dist/common/analytics.js.map +1 -1
- package/dist/common/api-keys/constants.d.ts +1 -0
- package/dist/common/api-keys/constants.d.ts.map +1 -0
- package/dist/common/api-keys/crypto.d.ts +1 -0
- package/dist/common/api-keys/crypto.d.ts.map +1 -0
- package/dist/common/api-keys/crypto.js +3 -3
- package/dist/common/api-keys/crypto.js.map +1 -1
- package/dist/common/browser-actions.d.ts +1 -0
- package/dist/common/browser-actions.d.ts.map +1 -0
- package/dist/common/constants/analytics-events.d.ts +2 -0
- package/dist/common/constants/analytics-events.d.ts.map +1 -0
- package/dist/common/constants/analytics-events.js +1 -0
- package/dist/common/constants/analytics-events.js.map +1 -1
- package/dist/common/constants/grant-priorities.d.ts +1 -0
- package/dist/common/constants/grant-priorities.d.ts.map +1 -0
- package/dist/common/constants/tools.d.ts +1 -0
- package/dist/common/constants/tools.d.ts.map +1 -0
- package/dist/common/constants/tools.js +1 -1
- package/dist/common/constants/tools.js.map +1 -1
- package/dist/common/constants.d.ts +13 -16
- package/dist/common/constants.d.ts.map +1 -0
- package/dist/common/constants.js +25 -22
- package/dist/common/constants.js.map +1 -1
- package/dist/common/db/drizzle.config.d.ts +1 -0
- package/dist/common/db/drizzle.config.d.ts.map +1 -0
- package/dist/common/db/drizzle.config.js +3 -3
- package/dist/common/db/drizzle.config.js.map +1 -1
- package/dist/common/db/index.d.ts +1 -0
- package/dist/common/db/index.d.ts.map +1 -0
- package/dist/common/db/index.js +2 -2
- package/dist/common/db/index.js.map +1 -1
- package/dist/common/db/schema.d.ts +2 -1
- package/dist/common/db/schema.d.ts.map +1 -0
- package/dist/common/db/transaction.d.ts +1 -0
- package/dist/common/db/transaction.d.ts.map +1 -0
- package/dist/common/json-config/__tests__/constants.test.d.ts +1 -0
- package/dist/common/json-config/__tests__/constants.test.d.ts.map +1 -0
- package/dist/common/json-config/__tests__/stringify-schema.test.d.ts +1 -0
- package/dist/common/json-config/__tests__/stringify-schema.test.d.ts.map +1 -0
- package/dist/common/json-config/constants.d.ts +1 -0
- package/dist/common/json-config/constants.d.ts.map +1 -0
- package/dist/common/json-config/stringify-schema.d.ts +1 -0
- package/dist/common/json-config/stringify-schema.d.ts.map +1 -0
- package/dist/common/project-file-tree.d.ts +1 -0
- package/dist/common/project-file-tree.d.ts.map +1 -0
- package/dist/common/project-file-tree.js +5 -5
- package/dist/common/project-file-tree.js.map +1 -1
- package/dist/common/types/agent-state.d.ts +1 -0
- package/dist/common/types/agent-state.d.ts.map +1 -0
- package/dist/common/types/grant.d.ts +1 -0
- package/dist/common/types/grant.d.ts.map +1 -0
- package/dist/common/types/message.d.ts +7 -6
- package/dist/common/types/message.d.ts.map +1 -0
- package/dist/common/types/organization.d.ts +1 -0
- package/dist/common/types/organization.d.ts.map +1 -0
- package/dist/common/types/referral.d.ts +1 -0
- package/dist/common/types/referral.d.ts.map +1 -0
- package/dist/common/types/tools.d.ts +1 -0
- package/dist/common/types/tools.d.ts.map +1 -0
- package/dist/common/types/usage.d.ts +1 -0
- package/dist/common/types/usage.d.ts.map +1 -0
- package/dist/common/util/__tests__/messages.test.d.ts +1 -0
- package/dist/common/util/__tests__/messages.test.d.ts.map +1 -0
- package/dist/common/util/__tests__/saxy.test.d.ts +1 -0
- package/dist/common/util/__tests__/saxy.test.d.ts.map +1 -0
- package/dist/common/util/__tests__/string.test.d.ts +1 -0
- package/dist/common/util/__tests__/string.test.d.ts.map +1 -0
- package/dist/common/util/array.d.ts +1 -0
- package/dist/common/util/array.d.ts.map +1 -0
- package/dist/common/util/changes.d.ts +1 -0
- package/dist/common/util/changes.d.ts.map +1 -0
- package/dist/common/util/credentials.d.ts +1 -0
- package/dist/common/util/credentials.d.ts.map +1 -0
- package/dist/common/util/currency.d.ts +1 -0
- package/dist/common/util/currency.d.ts.map +1 -0
- package/dist/common/util/dates.d.ts +1 -0
- package/dist/common/util/dates.d.ts.map +1 -0
- package/dist/common/util/file.d.ts +7 -1
- package/dist/common/util/file.d.ts.map +1 -0
- package/dist/common/util/file.js +32 -9
- package/dist/common/util/file.js.map +1 -1
- package/dist/common/util/git.d.ts +1 -0
- package/dist/common/util/git.d.ts.map +1 -0
- package/dist/common/util/logger.d.ts +1 -0
- package/dist/common/util/logger.d.ts.map +1 -0
- package/dist/common/util/logger.js +2 -2
- package/dist/common/util/logger.js.map +1 -1
- package/dist/common/util/lru-cache.d.ts +1 -0
- package/dist/common/util/lru-cache.d.ts.map +1 -0
- package/dist/common/util/messages.d.ts +1 -0
- package/dist/common/util/messages.d.ts.map +1 -0
- package/dist/common/util/min-heap.d.ts +1 -0
- package/dist/common/util/min-heap.d.ts.map +1 -0
- package/dist/common/util/object.d.ts +1 -0
- package/dist/common/util/object.d.ts.map +1 -0
- package/dist/common/util/patch.d.ts +1 -0
- package/dist/common/util/patch.d.ts.map +1 -0
- package/dist/common/util/promise.d.ts +1 -0
- package/dist/common/util/promise.d.ts.map +1 -0
- package/dist/common/util/random.d.ts +1 -0
- package/dist/common/util/random.d.ts.map +1 -0
- package/dist/common/util/referral.d.ts +1 -0
- package/dist/common/util/referral.d.ts.map +1 -0
- package/dist/common/util/saxy.d.ts +1 -0
- package/dist/common/util/saxy.d.ts.map +1 -0
- package/dist/common/util/string.d.ts +1 -0
- package/dist/common/util/string.d.ts.map +1 -0
- package/dist/common/util/stripe.d.ts +1 -0
- package/dist/common/util/stripe.d.ts.map +1 -0
- package/dist/common/util/stripe.js +2 -2
- package/dist/common/util/stripe.js.map +1 -1
- package/dist/common/util/sync-failure.d.ts +1 -0
- package/dist/common/util/sync-failure.d.ts.map +1 -0
- package/dist/common/websockets/websocket-client.d.ts +1 -0
- package/dist/common/websockets/websocket-client.d.ts.map +1 -0
- package/dist/common/websockets/websocket-schema.d.ts +17 -16
- package/dist/common/websockets/websocket-schema.d.ts.map +1 -0
- package/dist/config.js +1 -1
- package/dist/config.js.map +1 -1
- package/dist/credentials.d.ts +1 -1
- package/dist/credentials.js +3 -3
- package/dist/credentials.js.map +1 -1
- package/dist/dev-process-manager.d.ts +1 -1
- package/dist/dev-process-manager.js +2 -2
- package/dist/display.d.ts +5 -7
- package/dist/display.js +65 -13
- package/dist/display.js.map +1 -1
- package/dist/index.js +5 -75
- package/dist/json-config/hooks.d.ts +1 -1
- package/dist/json-config/hooks.js +1 -1
- package/dist/json-config/parser.d.ts +1 -1
- package/dist/json-config/parser.js +1 -1
- package/dist/menu.d.ts +1 -1
- package/dist/menu.js +3 -2
- package/dist/menu.js.map +1 -1
- package/dist/project-files.d.ts +4 -39
- package/dist/project-files.js +58 -98
- package/dist/project-files.js.map +1 -1
- package/dist/terminal/background.js +1 -1
- package/dist/terminal/base.js +5 -4
- package/dist/terminal/base.js.map +1 -1
- package/dist/tool-handlers.d.ts +2 -2
- package/dist/tool-handlers.js +4 -4
- package/dist/types.d.ts +1 -1
- package/dist/update-codebuff.js +1 -1
- package/dist/utils/__tests__/tool-renderers.test.js +2 -2
- package/dist/utils/__tests__/xml-stream-parser.test.js +1 -1
- package/dist/utils/analytics.d.ts +1 -1
- package/dist/utils/analytics.js +4 -4
- package/dist/utils/analytics.js.map +1 -1
- package/dist/utils/git.js +2 -1
- package/dist/utils/git.js.map +1 -1
- package/dist/utils/logger.js +3 -3
- package/dist/utils/logger.js.map +1 -1
- package/dist/utils/tool-renderers.d.ts +1 -1
- package/dist/utils/tool-renderers.js +10 -7
- package/dist/utils/tool-renderers.js.map +1 -1
- package/dist/utils/xml-stream-parser.d.ts +1 -1
- package/dist/utils/xml-stream-parser.js +2 -2
- package/dist/web-scraper.js +1 -1
- package/dist/workers/project-context.js +1 -1
- package/package.json +15 -18
- package/dist/code-map/test-langs/test.d.ts +0 -12
- package/dist/code-map/test-langs/test.d.ts.map +0 -1
- package/dist/code-map/test-langs/test.js +0 -23
- package/dist/code-map/test-langs/test.js.map +0 -1
- package/dist/common/db/env.d.mts +0 -1
- package/dist/common/db/env.mjs +0 -26
- package/dist/common/db/env.mjs.map +0 -1
- package/dist/common/env.d.mts +0 -1
- package/dist/common/env.mjs +0 -43
- package/dist/common/env.mjs.map +0 -1
- package/dist/utils/terminal.d.ts +0 -59
- package/dist/utils/terminal.js +0 -734
- package/dist/utils/terminal.js.map +0 -1
package/dist/utils/terminal.js
DELETED
|
@@ -1,734 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
-
if (mod && mod.__esModule) return mod;
|
|
20
|
-
var result = {};
|
|
21
|
-
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
-
__setModuleDefault(result, mod);
|
|
23
|
-
return result;
|
|
24
|
-
};
|
|
25
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
26
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
|
-
};
|
|
28
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
-
exports.readNewTerminalOutput = exports.runCommandPtyManager = exports.runCommandPty = exports.runTerminalCommand = exports.resetShell = exports.recreateShell = exports.isCommandRunning = exports.persistentProcess = void 0;
|
|
30
|
-
exports.runBackgroundCommand = runBackgroundCommand;
|
|
31
|
-
exports.killAndResetPersistentProcess = killAndResetPersistentProcess;
|
|
32
|
-
exports.clearScreen = clearScreen;
|
|
33
|
-
const assert_1 = __importDefault(require("assert"));
|
|
34
|
-
const child_process_1 = require("child_process");
|
|
35
|
-
const fs_1 = require("fs");
|
|
36
|
-
const os = __importStar(require("os"));
|
|
37
|
-
const path_1 = __importStar(require("path"));
|
|
38
|
-
const analytics_events_1 = require("../common/constants/analytics-events");
|
|
39
|
-
const array_1 = require("../common/util/array");
|
|
40
|
-
const string_1 = require("../common/util/string");
|
|
41
|
-
const picocolors_1 = require("picocolors");
|
|
42
|
-
const background_process_manager_1 = require("../background-process-manager");
|
|
43
|
-
const project_files_1 = require("../project-files");
|
|
44
|
-
const analytics_1 = require("./analytics");
|
|
45
|
-
const detect_shell_1 = require("./detect-shell");
|
|
46
|
-
let pty;
|
|
47
|
-
const tempConsoleError = console.error;
|
|
48
|
-
console.error = () => { };
|
|
49
|
-
try {
|
|
50
|
-
pty = require('@homebridge/node-pty-prebuilt-multiarch');
|
|
51
|
-
}
|
|
52
|
-
catch (error) {
|
|
53
|
-
}
|
|
54
|
-
finally {
|
|
55
|
-
console.error = tempConsoleError;
|
|
56
|
-
}
|
|
57
|
-
const COMMAND_OUTPUT_LIMIT = 10_000;
|
|
58
|
-
const promptIdentifier = '@36261@';
|
|
59
|
-
const createPersistantProcess = (dir, forceChildProcess = false) => {
|
|
60
|
-
if (pty && process.env.NODE_ENV !== 'test' && !forceChildProcess) {
|
|
61
|
-
const isWindows = os.platform() === 'win32';
|
|
62
|
-
const currShell = (0, detect_shell_1.detectShell)();
|
|
63
|
-
const shell = isWindows
|
|
64
|
-
? currShell === 'powershell'
|
|
65
|
-
? 'powershell.exe'
|
|
66
|
-
: 'cmd.exe'
|
|
67
|
-
: 'bash';
|
|
68
|
-
const shellWithoutExe = shell.split('.')[0];
|
|
69
|
-
// Prepare shell init commands
|
|
70
|
-
let shellInitCommands = '';
|
|
71
|
-
if (!isWindows) {
|
|
72
|
-
// Source all relevant config files based on shell type
|
|
73
|
-
if (currShell === 'zsh') {
|
|
74
|
-
shellInitCommands = `
|
|
75
|
-
source ~/.zshenv 2>/dev/null || true
|
|
76
|
-
source ~/.zprofile 2>/dev/null || true
|
|
77
|
-
source ~/.zshrc 2>/dev/null || true
|
|
78
|
-
source ~/.zlogin 2>/dev/null || true
|
|
79
|
-
`;
|
|
80
|
-
}
|
|
81
|
-
else if (currShell === 'fish') {
|
|
82
|
-
shellInitCommands = `
|
|
83
|
-
source ~/.config/fish/config.fish 2>/dev/null || true
|
|
84
|
-
`;
|
|
85
|
-
}
|
|
86
|
-
else {
|
|
87
|
-
// Bash - source both profile and rc files
|
|
88
|
-
shellInitCommands = `
|
|
89
|
-
source ~/.bash_profile 2>/dev/null || true
|
|
90
|
-
source ~/.profile 2>/dev/null || true
|
|
91
|
-
source ~/.bashrc 2>/dev/null || true
|
|
92
|
-
`;
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
else if (currShell === 'powershell') {
|
|
96
|
-
// Try to source all possible PowerShell profile locations
|
|
97
|
-
shellInitCommands = `
|
|
98
|
-
$profiles = @(
|
|
99
|
-
$PROFILE.AllUsersAllHosts,
|
|
100
|
-
$PROFILE.AllUsersCurrentHost,
|
|
101
|
-
$PROFILE.CurrentUserAllHosts,
|
|
102
|
-
$PROFILE.CurrentUserCurrentHost
|
|
103
|
-
)
|
|
104
|
-
foreach ($prof in $profiles) {
|
|
105
|
-
if (Test-Path $prof) { . $prof }
|
|
106
|
-
}
|
|
107
|
-
`;
|
|
108
|
-
}
|
|
109
|
-
const persistentPty = pty.spawn(shell, isWindows ? [] : ['--login'], {
|
|
110
|
-
name: 'xterm-256color',
|
|
111
|
-
cols: process.stdout.columns || 80,
|
|
112
|
-
rows: process.stdout.rows || 24,
|
|
113
|
-
cwd: dir,
|
|
114
|
-
env: {
|
|
115
|
-
...process.env,
|
|
116
|
-
PAGER: 'cat',
|
|
117
|
-
GIT_PAGER: 'cat',
|
|
118
|
-
GIT_TERMINAL_PROMPT: '0',
|
|
119
|
-
...(isWindows
|
|
120
|
-
? {
|
|
121
|
-
TERM: 'cygwin',
|
|
122
|
-
ANSICON: '1',
|
|
123
|
-
PROMPT: promptIdentifier,
|
|
124
|
-
}
|
|
125
|
-
: {
|
|
126
|
-
TERM: 'xterm-256color',
|
|
127
|
-
// Preserve important environment variables
|
|
128
|
-
PATH: process.env.PATH,
|
|
129
|
-
HOME: process.env.HOME,
|
|
130
|
-
USER: process.env.USER,
|
|
131
|
-
SHELL: shellWithoutExe,
|
|
132
|
-
}),
|
|
133
|
-
LESS: '-FRX',
|
|
134
|
-
TERM_PROGRAM: 'mintty',
|
|
135
|
-
FORCE_COLOR: '1',
|
|
136
|
-
// Locale settings for consistent output
|
|
137
|
-
LANG: 'en_US.UTF-8',
|
|
138
|
-
LC_ALL: 'en_US.UTF-8',
|
|
139
|
-
},
|
|
140
|
-
});
|
|
141
|
-
// Source the shell config files
|
|
142
|
-
if (shellInitCommands) {
|
|
143
|
-
persistentPty.write(shellInitCommands);
|
|
144
|
-
}
|
|
145
|
-
// Set prompt for Unix shells after sourcing config
|
|
146
|
-
if (!isWindows) {
|
|
147
|
-
persistentPty.write(`PS1=${promptIdentifier} && PS2=${promptIdentifier}\n`);
|
|
148
|
-
}
|
|
149
|
-
const persistentProcessInfo = {
|
|
150
|
-
type: 'pty',
|
|
151
|
-
shell: 'pty',
|
|
152
|
-
pty: persistentPty,
|
|
153
|
-
timerId: null,
|
|
154
|
-
globalOutputBuffer: '',
|
|
155
|
-
globalOutputLastReadLength: 0,
|
|
156
|
-
};
|
|
157
|
-
// Add a persistent listener to capture all output for manager mode
|
|
158
|
-
persistentPty.onData((data) => {
|
|
159
|
-
if (persistentProcessInfo.type === 'pty') {
|
|
160
|
-
persistentProcessInfo.globalOutputBuffer += data.toString(); // Should we use stripColors(...)?
|
|
161
|
-
}
|
|
162
|
-
});
|
|
163
|
-
return persistentProcessInfo;
|
|
164
|
-
}
|
|
165
|
-
else {
|
|
166
|
-
// Fallback to child_process
|
|
167
|
-
const isWindows = os.platform() === 'win32';
|
|
168
|
-
const currShell = (0, detect_shell_1.detectShell)();
|
|
169
|
-
const shell = isWindows
|
|
170
|
-
? currShell === 'powershell'
|
|
171
|
-
? 'powershell.exe'
|
|
172
|
-
: 'cmd.exe'
|
|
173
|
-
: 'bash';
|
|
174
|
-
const childProcess = null;
|
|
175
|
-
return {
|
|
176
|
-
type: 'process',
|
|
177
|
-
shell,
|
|
178
|
-
childProcess,
|
|
179
|
-
timerId: null,
|
|
180
|
-
globalOutputBuffer: '',
|
|
181
|
-
globalOutputLastReadLength: 0,
|
|
182
|
-
};
|
|
183
|
-
}
|
|
184
|
-
};
|
|
185
|
-
exports.persistentProcess = null;
|
|
186
|
-
process.stdout.on('resize', () => {
|
|
187
|
-
if (!exports.persistentProcess)
|
|
188
|
-
return;
|
|
189
|
-
if (exports.persistentProcess.type === 'pty') {
|
|
190
|
-
exports.persistentProcess.pty.resize(process.stdout.columns, process.stdout.rows);
|
|
191
|
-
}
|
|
192
|
-
});
|
|
193
|
-
let commandIsRunning = false;
|
|
194
|
-
const isCommandRunning = () => {
|
|
195
|
-
return commandIsRunning;
|
|
196
|
-
};
|
|
197
|
-
exports.isCommandRunning = isCommandRunning;
|
|
198
|
-
const recreateShell = (cwd, forceChildProcess = false) => {
|
|
199
|
-
exports.persistentProcess = createPersistantProcess(cwd, forceChildProcess);
|
|
200
|
-
};
|
|
201
|
-
exports.recreateShell = recreateShell;
|
|
202
|
-
const resetShell = (cwd) => {
|
|
203
|
-
commandIsRunning = false;
|
|
204
|
-
if (exports.persistentProcess) {
|
|
205
|
-
if (exports.persistentProcess.timerId) {
|
|
206
|
-
clearTimeout(exports.persistentProcess.timerId);
|
|
207
|
-
exports.persistentProcess.timerId = null;
|
|
208
|
-
}
|
|
209
|
-
if (exports.persistentProcess.type === 'pty') {
|
|
210
|
-
exports.persistentProcess.pty.kill();
|
|
211
|
-
(0, exports.recreateShell)(cwd);
|
|
212
|
-
}
|
|
213
|
-
else {
|
|
214
|
-
exports.persistentProcess.childProcess?.kill();
|
|
215
|
-
exports.persistentProcess = {
|
|
216
|
-
...exports.persistentProcess,
|
|
217
|
-
childProcess: null,
|
|
218
|
-
};
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
};
|
|
222
|
-
exports.resetShell = resetShell;
|
|
223
|
-
function formatResult(command, stdout, status) {
|
|
224
|
-
return (0, array_1.buildArray)(`<command>${command}</command>`, '<terminal_command_result>', stdout &&
|
|
225
|
-
`<output>${(0, string_1.truncateStringWithMessage)({ str: (0, string_1.stripColors)(stdout), maxLength: COMMAND_OUTPUT_LIMIT, remove: 'MIDDLE' })}</output>`, `<status>${status}</status>`, '</terminal_command_result>').join('\n');
|
|
226
|
-
}
|
|
227
|
-
const MAX_EXECUTION_TIME = 30_000;
|
|
228
|
-
function runBackgroundCommand(options, resolveCommand) {
|
|
229
|
-
const { toolCallId, command, mode, cwd, stdoutFile, stderrFile } = options;
|
|
230
|
-
const isWindows = os.platform() === 'win32';
|
|
231
|
-
const shell = isWindows ? 'cmd.exe' : 'bash';
|
|
232
|
-
const shellArgs = isWindows ? ['/c'] : ['-c'];
|
|
233
|
-
if (mode === 'assistant') {
|
|
234
|
-
console.log((0, picocolors_1.green)(`Running background process...\n> ${command}`));
|
|
235
|
-
}
|
|
236
|
-
const initialStdout = '';
|
|
237
|
-
const initialStderr = '';
|
|
238
|
-
try {
|
|
239
|
-
const childProcess = (0, background_process_manager_1.spawnAndTrack)(shell, [...shellArgs, command], {
|
|
240
|
-
cwd,
|
|
241
|
-
env: { ...process.env, FORCE_COLOR: '1' },
|
|
242
|
-
// Ensure detached is always false to link child lifetime to parent
|
|
243
|
-
detached: false,
|
|
244
|
-
stdio: 'pipe',
|
|
245
|
-
});
|
|
246
|
-
// An error should have been thrown when we called `spawn`
|
|
247
|
-
(0, assert_1.default)(childProcess.pid !== undefined, 'Failed to spawn process: no PID assigned.');
|
|
248
|
-
const processId = childProcess.pid;
|
|
249
|
-
const processInfo = {
|
|
250
|
-
pid: processId,
|
|
251
|
-
toolCallId,
|
|
252
|
-
command,
|
|
253
|
-
process: childProcess,
|
|
254
|
-
stdoutBuffer: [],
|
|
255
|
-
stderrBuffer: [],
|
|
256
|
-
status: 'running',
|
|
257
|
-
startTime: Date.now(),
|
|
258
|
-
endTime: null,
|
|
259
|
-
lastReportedStdoutLength: 0,
|
|
260
|
-
lastReportedStderrLength: 0,
|
|
261
|
-
lastReportedStatus: null,
|
|
262
|
-
stdoutFile,
|
|
263
|
-
stderrFile,
|
|
264
|
-
};
|
|
265
|
-
background_process_manager_1.backgroundProcesses.set(processId, processInfo);
|
|
266
|
-
// Set up file streams if paths are provided
|
|
267
|
-
let stdoutStream;
|
|
268
|
-
let stderrStream;
|
|
269
|
-
if (stdoutFile) {
|
|
270
|
-
const stdoutAbs = path_1.default.isAbsolute(stdoutFile)
|
|
271
|
-
? stdoutFile
|
|
272
|
-
: path_1.default.join(cwd, stdoutFile);
|
|
273
|
-
(0, fs_1.mkdirSync)((0, path_1.dirname)(stdoutAbs), { recursive: true });
|
|
274
|
-
stdoutStream = (0, fs_1.createWriteStream)(stdoutAbs);
|
|
275
|
-
}
|
|
276
|
-
const realStderrFile = stderrFile || stdoutFile;
|
|
277
|
-
if (realStderrFile) {
|
|
278
|
-
const stderrAbs = path_1.default.isAbsolute(realStderrFile)
|
|
279
|
-
? realStderrFile
|
|
280
|
-
: path_1.default.join(cwd, realStderrFile);
|
|
281
|
-
(0, fs_1.mkdirSync)((0, path_1.dirname)(stderrAbs), { recursive: true });
|
|
282
|
-
stderrStream = (0, fs_1.createWriteStream)(stderrAbs);
|
|
283
|
-
}
|
|
284
|
-
childProcess.stdout.on('data', (data) => {
|
|
285
|
-
const output = (0, string_1.stripColors)(data.toString());
|
|
286
|
-
processInfo.stdoutBuffer.push(output);
|
|
287
|
-
// Write to file if stream exists
|
|
288
|
-
if (stdoutStream) {
|
|
289
|
-
stdoutStream.write(output);
|
|
290
|
-
}
|
|
291
|
-
});
|
|
292
|
-
childProcess.stderr.on('data', (data) => {
|
|
293
|
-
const output = (0, string_1.stripColors)(data.toString());
|
|
294
|
-
processInfo.stderrBuffer.push(output);
|
|
295
|
-
// Write to file if stream exists
|
|
296
|
-
if (stderrStream) {
|
|
297
|
-
stderrStream.write(output);
|
|
298
|
-
}
|
|
299
|
-
});
|
|
300
|
-
childProcess.on('error', (error) => {
|
|
301
|
-
processInfo.status = 'error';
|
|
302
|
-
processInfo.stderrBuffer.push(`\nError spawning command: ${error.message}`);
|
|
303
|
-
processInfo.endTime = Date.now();
|
|
304
|
-
// Close file streams
|
|
305
|
-
stdoutStream?.end();
|
|
306
|
-
stderrStream?.end();
|
|
307
|
-
});
|
|
308
|
-
let exitCode = null;
|
|
309
|
-
childProcess.on('close', (code) => {
|
|
310
|
-
exitCode = code;
|
|
311
|
-
processInfo.status = code === 0 ? 'completed' : 'error';
|
|
312
|
-
processInfo.endTime = Date.now();
|
|
313
|
-
// Close file streams
|
|
314
|
-
stdoutStream?.end();
|
|
315
|
-
stderrStream?.end();
|
|
316
|
-
});
|
|
317
|
-
// Unreference the process so the parent can exit independently IF the child is the only thing keeping it alive.
|
|
318
|
-
childProcess.unref();
|
|
319
|
-
const resultMessage = `<background_process>
|
|
320
|
-
<process_id>${processId}</process_id>
|
|
321
|
-
<command>${command}</command>
|
|
322
|
-
<status>${processInfo.status}</status>
|
|
323
|
-
</background_process>`;
|
|
324
|
-
resolveCommand({
|
|
325
|
-
result: resultMessage,
|
|
326
|
-
stdout: initialStdout + initialStderr,
|
|
327
|
-
exitCode,
|
|
328
|
-
});
|
|
329
|
-
}
|
|
330
|
-
catch (error) {
|
|
331
|
-
const errorMessage = `<background_process>\n<command>${command}</command>\n<error>${error.message}</error>\n</background_process>`;
|
|
332
|
-
resolveCommand({
|
|
333
|
-
result: errorMessage,
|
|
334
|
-
stdout: error.message,
|
|
335
|
-
exitCode: null,
|
|
336
|
-
});
|
|
337
|
-
}
|
|
338
|
-
}
|
|
339
|
-
const runTerminalCommand = async (toolCallId, command, mode, processType, timeoutSeconds, cwd, stdoutFile, stderrFile) => {
|
|
340
|
-
const maybeTimeoutSeconds = timeoutSeconds < 0 ? null : timeoutSeconds;
|
|
341
|
-
cwd = cwd || (mode === 'assistant' ? (0, project_files_1.getProjectRoot)() : (0, project_files_1.getWorkingDirectory)());
|
|
342
|
-
return new Promise((resolve) => {
|
|
343
|
-
if (!exports.persistentProcess) {
|
|
344
|
-
throw new Error('Shell not initialized');
|
|
345
|
-
}
|
|
346
|
-
if (commandIsRunning) {
|
|
347
|
-
(0, exports.resetShell)(cwd);
|
|
348
|
-
}
|
|
349
|
-
commandIsRunning = true;
|
|
350
|
-
// Add special case for git log to limit output
|
|
351
|
-
const modifiedCommand = command.trim() === 'git log' ? 'git log -n 5' : command;
|
|
352
|
-
const resolveCommand = (value) => {
|
|
353
|
-
commandIsRunning = false;
|
|
354
|
-
(0, analytics_1.trackEvent)(analytics_events_1.AnalyticsEvent.TERMINAL_COMMAND_COMPLETED, {
|
|
355
|
-
command,
|
|
356
|
-
result: value.result,
|
|
357
|
-
stdout: value.stdout,
|
|
358
|
-
exitCode: value.exitCode,
|
|
359
|
-
mode,
|
|
360
|
-
processType,
|
|
361
|
-
});
|
|
362
|
-
resolve(value);
|
|
363
|
-
};
|
|
364
|
-
if (processType === 'BACKGROUND') {
|
|
365
|
-
runBackgroundCommand({
|
|
366
|
-
toolCallId,
|
|
367
|
-
command: modifiedCommand,
|
|
368
|
-
mode,
|
|
369
|
-
cwd,
|
|
370
|
-
stdoutFile,
|
|
371
|
-
stderrFile,
|
|
372
|
-
}, resolveCommand);
|
|
373
|
-
}
|
|
374
|
-
else if (exports.persistentProcess.type === 'pty') {
|
|
375
|
-
if (mode === 'manager') {
|
|
376
|
-
(0, exports.runCommandPtyManager)(exports.persistentProcess, modifiedCommand, cwd, maybeTimeoutSeconds, resolveCommand);
|
|
377
|
-
}
|
|
378
|
-
else {
|
|
379
|
-
(0, exports.runCommandPty)(exports.persistentProcess, modifiedCommand, mode, cwd, maybeTimeoutSeconds, resolveCommand);
|
|
380
|
-
}
|
|
381
|
-
}
|
|
382
|
-
else {
|
|
383
|
-
// Fallback to child_process implementation
|
|
384
|
-
runCommandChildProcess(exports.persistentProcess, modifiedCommand, mode, cwd, maybeTimeoutSeconds, resolveCommand);
|
|
385
|
-
}
|
|
386
|
-
});
|
|
387
|
-
};
|
|
388
|
-
exports.runTerminalCommand = runTerminalCommand;
|
|
389
|
-
const echoLinePattern = new RegExp(`${promptIdentifier}[^\n]*\n`, 'g');
|
|
390
|
-
const commandDonePattern = new RegExp(`^${promptIdentifier}(.*)${promptIdentifier}[\\s\\S]*${promptIdentifier}`);
|
|
391
|
-
const runCommandPty = (persistentProcess, command, mode, cwd, maybeTimeoutSeconds, resolve) => {
|
|
392
|
-
const ptyProcess = persistentProcess.pty;
|
|
393
|
-
if (command.trim() === 'clear') {
|
|
394
|
-
// `clear` needs access to the main process stdout. This is a workaround.
|
|
395
|
-
(0, child_process_1.execSync)('clear', { stdio: 'inherit' });
|
|
396
|
-
resolve({
|
|
397
|
-
result: formatResult(command, '', `Complete`),
|
|
398
|
-
stdout: '',
|
|
399
|
-
exitCode: 0,
|
|
400
|
-
});
|
|
401
|
-
return;
|
|
402
|
-
}
|
|
403
|
-
const projectRoot = (0, project_files_1.getProjectRoot)();
|
|
404
|
-
const isWindows = os.platform() === 'win32';
|
|
405
|
-
if (mode === 'assistant') {
|
|
406
|
-
const displayDirectory = path_1.default.join(path_1.default.parse(projectRoot).base, path_1.default.relative(projectRoot, path_1.default.resolve(projectRoot, cwd)));
|
|
407
|
-
console.log((0, picocolors_1.green)(`${displayDirectory} > ${command}`));
|
|
408
|
-
}
|
|
409
|
-
let commandOutput = '';
|
|
410
|
-
let buffer = promptIdentifier;
|
|
411
|
-
let echoLinesRemaining = isWindows ? 1 : command.split('\n').length;
|
|
412
|
-
let timer = null;
|
|
413
|
-
if (maybeTimeoutSeconds !== null) {
|
|
414
|
-
timer = setTimeout(() => {
|
|
415
|
-
if (mode === 'assistant') {
|
|
416
|
-
// Kill and recreate PTY
|
|
417
|
-
(0, exports.resetShell)(cwd);
|
|
418
|
-
resolve({
|
|
419
|
-
result: formatResult(command, commandOutput, `Command timed out after ${maybeTimeoutSeconds} seconds and was terminated. Shell has been restarted.`),
|
|
420
|
-
stdout: commandOutput,
|
|
421
|
-
exitCode: 124,
|
|
422
|
-
});
|
|
423
|
-
}
|
|
424
|
-
}, maybeTimeoutSeconds * 1000);
|
|
425
|
-
}
|
|
426
|
-
persistentProcess.timerId = timer;
|
|
427
|
-
const longestSuffixThatsPrefixOf = (str, target) => {
|
|
428
|
-
for (let len = target.length; len > 0; len--) {
|
|
429
|
-
const prefix = target.slice(0, len);
|
|
430
|
-
if (str.endsWith(prefix)) {
|
|
431
|
-
return prefix;
|
|
432
|
-
}
|
|
433
|
-
}
|
|
434
|
-
return '';
|
|
435
|
-
};
|
|
436
|
-
const asdf = (0, string_1.generateCompactId)('asdf');
|
|
437
|
-
const dataDisposable = ptyProcess.onData((data) => {
|
|
438
|
-
console.log({ data, asdf });
|
|
439
|
-
buffer += data;
|
|
440
|
-
const suffix = longestSuffixThatsPrefixOf(buffer, promptIdentifier);
|
|
441
|
-
let toProcess = buffer.slice(0, buffer.length - suffix.length);
|
|
442
|
-
buffer = suffix;
|
|
443
|
-
const matches = toProcess.match(echoLinePattern);
|
|
444
|
-
if (matches) {
|
|
445
|
-
for (let i = 0; i < matches.length && echoLinesRemaining > 0; i++) {
|
|
446
|
-
echoLinesRemaining = Math.max(echoLinesRemaining - 1, 0);
|
|
447
|
-
// Process normal output line
|
|
448
|
-
toProcess = toProcess.replace(echoLinePattern, '');
|
|
449
|
-
}
|
|
450
|
-
}
|
|
451
|
-
const indexOfPromptIdentifier = toProcess.indexOf(promptIdentifier);
|
|
452
|
-
if (indexOfPromptIdentifier !== -1) {
|
|
453
|
-
buffer = toProcess.slice(indexOfPromptIdentifier) + buffer;
|
|
454
|
-
toProcess = toProcess.slice(0, indexOfPromptIdentifier);
|
|
455
|
-
}
|
|
456
|
-
process.stdout.write(toProcess);
|
|
457
|
-
commandOutput += toProcess;
|
|
458
|
-
const commandDone = buffer.match(commandDonePattern);
|
|
459
|
-
if (commandDone && echoLinesRemaining === 0) {
|
|
460
|
-
// Command is done
|
|
461
|
-
if (timer) {
|
|
462
|
-
clearTimeout(timer);
|
|
463
|
-
}
|
|
464
|
-
dataDisposable.dispose();
|
|
465
|
-
const exitCode = buffer.includes('Command completed')
|
|
466
|
-
? 0
|
|
467
|
-
: (() => {
|
|
468
|
-
const match = buffer.match(/Command failed with exit code (\d+)\./);
|
|
469
|
-
return match ? parseInt(match[1]) : null;
|
|
470
|
-
})();
|
|
471
|
-
const statusMessage = buffer.includes('Command completed')
|
|
472
|
-
? 'Complete'
|
|
473
|
-
: `Failed with exit code: ${exitCode}`;
|
|
474
|
-
const newWorkingDirectory = commandDone[1];
|
|
475
|
-
if (mode === 'assistant') {
|
|
476
|
-
ptyProcess.write(`cd ${(0, project_files_1.getWorkingDirectory)()}\r\n`);
|
|
477
|
-
resolve({
|
|
478
|
-
result: formatResult(command, commandOutput, `cwd: ${path_1.default.resolve(projectRoot, cwd)}\n\n${statusMessage}`),
|
|
479
|
-
stdout: commandOutput,
|
|
480
|
-
exitCode,
|
|
481
|
-
});
|
|
482
|
-
return;
|
|
483
|
-
}
|
|
484
|
-
let outsideProject = false;
|
|
485
|
-
const currentWorkingDirectory = (0, project_files_1.getWorkingDirectory)();
|
|
486
|
-
let finalCwd = currentWorkingDirectory;
|
|
487
|
-
if (newWorkingDirectory !== currentWorkingDirectory) {
|
|
488
|
-
(0, analytics_1.trackEvent)(analytics_events_1.AnalyticsEvent.CHANGE_DIRECTORY, {
|
|
489
|
-
from: currentWorkingDirectory,
|
|
490
|
-
to: newWorkingDirectory,
|
|
491
|
-
isSubdir: (0, project_files_1.isSubdir)(currentWorkingDirectory, newWorkingDirectory),
|
|
492
|
-
});
|
|
493
|
-
if (path_1.default.relative(projectRoot, newWorkingDirectory).startsWith('..')) {
|
|
494
|
-
outsideProject = true;
|
|
495
|
-
console.log(`
|
|
496
|
-
Unable to cd outside of the project root (${projectRoot})
|
|
497
|
-
|
|
498
|
-
If you want to change the project root:
|
|
499
|
-
1. Exit Codebuff (type "exit")
|
|
500
|
-
2. Navigate into the target directory (type "cd ${newWorkingDirectory}")
|
|
501
|
-
3. Restart Codebuff`);
|
|
502
|
-
ptyProcess.write(`cd ${currentWorkingDirectory}\r\n`);
|
|
503
|
-
}
|
|
504
|
-
else {
|
|
505
|
-
(0, project_files_1.setWorkingDirectory)(newWorkingDirectory);
|
|
506
|
-
finalCwd = newWorkingDirectory;
|
|
507
|
-
}
|
|
508
|
-
}
|
|
509
|
-
resolve({
|
|
510
|
-
result: formatResult(command, commandOutput, (0, array_1.buildArray)([
|
|
511
|
-
`cwd: ${currentWorkingDirectory}`,
|
|
512
|
-
`${statusMessage}\n`,
|
|
513
|
-
outsideProject &&
|
|
514
|
-
`Detected final cwd outside project root. Reset cwd to ${currentWorkingDirectory}`,
|
|
515
|
-
`Final **user** cwd: ${finalCwd} (Assistant's cwd is still project root)`,
|
|
516
|
-
]).join('\n')),
|
|
517
|
-
stdout: commandOutput,
|
|
518
|
-
exitCode,
|
|
519
|
-
});
|
|
520
|
-
return;
|
|
521
|
-
}
|
|
522
|
-
});
|
|
523
|
-
// Write the command
|
|
524
|
-
const cdCommand = `cd ${path_1.default.resolve(projectRoot, cwd)}`;
|
|
525
|
-
const commandWithCheck = isWindows
|
|
526
|
-
? `${cdCommand} & ${command} & echo ${promptIdentifier}%cd%${promptIdentifier}`
|
|
527
|
-
: `${cdCommand}; ${command}; ec=$?; printf "${promptIdentifier}$(pwd)${promptIdentifier}"; if [ $ec -eq 0 ]; then printf "Command completed."; else printf "Command failed with exit code $ec."; fi`;
|
|
528
|
-
ptyProcess.write(`${commandWithCheck}\r`);
|
|
529
|
-
};
|
|
530
|
-
exports.runCommandPty = runCommandPty;
|
|
531
|
-
const runCommandChildProcess = (persistentProcess, command, mode, cwd, maybeTimeoutSeconds, resolve) => {
|
|
532
|
-
const isWindows = os.platform() === 'win32';
|
|
533
|
-
let commandOutput = '';
|
|
534
|
-
if (mode === 'assistant') {
|
|
535
|
-
console.log((0, picocolors_1.green)(`> ${command}`));
|
|
536
|
-
}
|
|
537
|
-
const childProcess = (0, child_process_1.spawn)(persistentProcess.shell, [isWindows ? '/c' : '-c', command], {
|
|
538
|
-
cwd,
|
|
539
|
-
env: {
|
|
540
|
-
...process.env,
|
|
541
|
-
PAGER: 'cat',
|
|
542
|
-
GIT_PAGER: 'cat',
|
|
543
|
-
GIT_TERMINAL_PROMPT: '0',
|
|
544
|
-
LESS: '-FRX',
|
|
545
|
-
},
|
|
546
|
-
});
|
|
547
|
-
persistentProcess = {
|
|
548
|
-
...persistentProcess,
|
|
549
|
-
childProcess,
|
|
550
|
-
};
|
|
551
|
-
let timer = null;
|
|
552
|
-
if (maybeTimeoutSeconds !== null) {
|
|
553
|
-
timer = setTimeout(() => {
|
|
554
|
-
(0, exports.resetShell)(cwd);
|
|
555
|
-
if (mode === 'assistant') {
|
|
556
|
-
resolve({
|
|
557
|
-
result: formatResult(command, commandOutput, `Command timed out after ${maybeTimeoutSeconds} seconds and was terminated.`),
|
|
558
|
-
stdout: commandOutput,
|
|
559
|
-
exitCode: 124,
|
|
560
|
-
});
|
|
561
|
-
}
|
|
562
|
-
}, maybeTimeoutSeconds * 1000);
|
|
563
|
-
}
|
|
564
|
-
persistentProcess.timerId = timer;
|
|
565
|
-
childProcess.stdout.on('data', (data) => {
|
|
566
|
-
const output = data.toString();
|
|
567
|
-
process.stdout.write(output);
|
|
568
|
-
commandOutput += output;
|
|
569
|
-
});
|
|
570
|
-
childProcess.stderr.on('data', (data) => {
|
|
571
|
-
const output = data.toString();
|
|
572
|
-
process.stdout.write(output);
|
|
573
|
-
commandOutput += output;
|
|
574
|
-
});
|
|
575
|
-
childProcess.on('close', (code) => {
|
|
576
|
-
if (timer) {
|
|
577
|
-
clearTimeout(timer);
|
|
578
|
-
}
|
|
579
|
-
if (command.startsWith('cd ') && mode === 'user') {
|
|
580
|
-
const newWorkingDirectory = command.split(' ')[1];
|
|
581
|
-
cwd = (0, project_files_1.setWorkingDirectory)(path_1.default.join(cwd, newWorkingDirectory));
|
|
582
|
-
}
|
|
583
|
-
if (mode === 'assistant') {
|
|
584
|
-
console.log((0, picocolors_1.green)(`Command completed`));
|
|
585
|
-
}
|
|
586
|
-
resolve({
|
|
587
|
-
result: formatResult(command, commandOutput, `complete`),
|
|
588
|
-
stdout: commandOutput,
|
|
589
|
-
exitCode: childProcess.exitCode,
|
|
590
|
-
});
|
|
591
|
-
});
|
|
592
|
-
};
|
|
593
|
-
function killAndResetPersistentProcess() {
|
|
594
|
-
if (exports.persistentProcess?.type === 'pty') {
|
|
595
|
-
exports.persistentProcess.pty.kill();
|
|
596
|
-
exports.persistentProcess = null;
|
|
597
|
-
}
|
|
598
|
-
}
|
|
599
|
-
function clearScreen() {
|
|
600
|
-
process.stdout.write('\u001b[2J\u001b[0;0H');
|
|
601
|
-
}
|
|
602
|
-
// New function specifically for manager mode with settling behavior
|
|
603
|
-
const runCommandPtyManager = (persistentProcess, command, cwd, maybeTimeoutSeconds, resolve) => {
|
|
604
|
-
const ptyProcess = persistentProcess.pty;
|
|
605
|
-
if (command.trim() === 'clear') {
|
|
606
|
-
// `clear` needs access to the main process stdout. This is a workaround.
|
|
607
|
-
(0, child_process_1.execSync)('clear', { stdio: 'inherit' });
|
|
608
|
-
resolve({
|
|
609
|
-
result: formatResult(command, '', `Complete`),
|
|
610
|
-
stdout: '',
|
|
611
|
-
exitCode: 0,
|
|
612
|
-
});
|
|
613
|
-
return;
|
|
614
|
-
}
|
|
615
|
-
const projectRoot = (0, project_files_1.getProjectRoot)();
|
|
616
|
-
const isWindows = os.platform() === 'win32';
|
|
617
|
-
console.log((0, picocolors_1.green)(`${cwd} > ${command}`));
|
|
618
|
-
let commandOutput = '';
|
|
619
|
-
let buffer = promptIdentifier;
|
|
620
|
-
let echoLinesRemaining = isWindows ? 1 : command.split('\n').length;
|
|
621
|
-
let timer = null;
|
|
622
|
-
let settleTimer = null;
|
|
623
|
-
// Use the provided timeout or default to 30 seconds for manager mode
|
|
624
|
-
const managerTimeoutMs = maybeTimeoutSeconds !== null ? maybeTimeoutSeconds * 1000 : 30000;
|
|
625
|
-
if (maybeTimeoutSeconds !== null) {
|
|
626
|
-
timer = setTimeout(() => {
|
|
627
|
-
// In manager mode, don't kill the terminal - just report what we have
|
|
628
|
-
if (timer) {
|
|
629
|
-
clearTimeout(timer);
|
|
630
|
-
}
|
|
631
|
-
if (settleTimer) {
|
|
632
|
-
clearTimeout(settleTimer);
|
|
633
|
-
}
|
|
634
|
-
dataDisposable.dispose();
|
|
635
|
-
resolve({
|
|
636
|
-
result: formatResult(command, commandOutput, `Command timed out after ${managerTimeoutMs / 1000} seconds. Output captured so far. Terminal is still running.`),
|
|
637
|
-
stdout: commandOutput,
|
|
638
|
-
exitCode: null, // null indicates timeout, not failure
|
|
639
|
-
});
|
|
640
|
-
}, managerTimeoutMs);
|
|
641
|
-
}
|
|
642
|
-
persistentProcess.timerId = timer;
|
|
643
|
-
const longestSuffixThatsPrefixOf = (str, target) => {
|
|
644
|
-
for (let len = target.length; len > 0; len--) {
|
|
645
|
-
const prefix = target.slice(0, len);
|
|
646
|
-
if (str.endsWith(prefix)) {
|
|
647
|
-
return prefix;
|
|
648
|
-
}
|
|
649
|
-
}
|
|
650
|
-
return '';
|
|
651
|
-
};
|
|
652
|
-
const finishCommand = (exitCode = null) => {
|
|
653
|
-
if (timer) {
|
|
654
|
-
clearTimeout(timer);
|
|
655
|
-
}
|
|
656
|
-
if (settleTimer) {
|
|
657
|
-
clearTimeout(settleTimer);
|
|
658
|
-
}
|
|
659
|
-
dataDisposable.dispose();
|
|
660
|
-
const statusMessage = exitCode === 0
|
|
661
|
-
? 'Complete'
|
|
662
|
-
: exitCode === null
|
|
663
|
-
? 'Comand started'
|
|
664
|
-
: `Failed with exit code: ${exitCode}`;
|
|
665
|
-
resolve({
|
|
666
|
-
result: formatResult(command, undefined, `cwd: ${path_1.default.resolve(projectRoot, cwd)}\n\n${statusMessage}`),
|
|
667
|
-
stdout: commandOutput,
|
|
668
|
-
exitCode,
|
|
669
|
-
});
|
|
670
|
-
};
|
|
671
|
-
const dataDisposable = ptyProcess.onData((data) => {
|
|
672
|
-
buffer += data;
|
|
673
|
-
const suffix = longestSuffixThatsPrefixOf(buffer, promptIdentifier);
|
|
674
|
-
let toProcess = buffer.slice(0, buffer.length - suffix.length);
|
|
675
|
-
buffer = suffix;
|
|
676
|
-
const matches = toProcess.match(echoLinePattern);
|
|
677
|
-
if (matches) {
|
|
678
|
-
for (let i = 0; i < matches.length && echoLinesRemaining > 0; i++) {
|
|
679
|
-
echoLinesRemaining = Math.max(echoLinesRemaining - 1, 0);
|
|
680
|
-
// Process normal output line
|
|
681
|
-
toProcess = toProcess.replace(echoLinePattern, '');
|
|
682
|
-
}
|
|
683
|
-
}
|
|
684
|
-
const indexOfPromptIdentifier = toProcess.indexOf(promptIdentifier);
|
|
685
|
-
if (indexOfPromptIdentifier !== -1) {
|
|
686
|
-
buffer = toProcess.slice(indexOfPromptIdentifier) + buffer;
|
|
687
|
-
toProcess = toProcess.slice(0, indexOfPromptIdentifier);
|
|
688
|
-
}
|
|
689
|
-
process.stdout.write(toProcess);
|
|
690
|
-
commandOutput += toProcess;
|
|
691
|
-
// Reset settle timer whenever we get new output
|
|
692
|
-
if (settleTimer) {
|
|
693
|
-
clearTimeout(settleTimer);
|
|
694
|
-
}
|
|
695
|
-
// Set settle timer for 3000ms - if no new output comes, finish the command
|
|
696
|
-
settleTimer = setTimeout(() => {
|
|
697
|
-
finishCommand();
|
|
698
|
-
}, 3000);
|
|
699
|
-
const commandDone = buffer.match(commandDonePattern);
|
|
700
|
-
if (commandDone && echoLinesRemaining === 0) {
|
|
701
|
-
// Command is done
|
|
702
|
-
const exitCode = buffer.includes('Command completed')
|
|
703
|
-
? 0
|
|
704
|
-
: (() => {
|
|
705
|
-
const match = buffer.match(/Command failed with exit code (\d+)\./);
|
|
706
|
-
return match ? parseInt(match[1]) : null;
|
|
707
|
-
})();
|
|
708
|
-
finishCommand(exitCode);
|
|
709
|
-
return;
|
|
710
|
-
}
|
|
711
|
-
});
|
|
712
|
-
ptyProcess.write(`${command}`);
|
|
713
|
-
setTimeout(() => {
|
|
714
|
-
ptyProcess.write('\r');
|
|
715
|
-
}, 50);
|
|
716
|
-
};
|
|
717
|
-
exports.runCommandPtyManager = runCommandPtyManager;
|
|
718
|
-
// Add a function to get new terminal output since last read
|
|
719
|
-
const readNewTerminalOutput = (options = { maxLength: COMMAND_OUTPUT_LIMIT }) => {
|
|
720
|
-
if (!exports.persistentProcess) {
|
|
721
|
-
return '';
|
|
722
|
-
}
|
|
723
|
-
const currentLength = exports.persistentProcess.globalOutputBuffer.length;
|
|
724
|
-
const newOutput = exports.persistentProcess.globalOutputBuffer.slice(exports.persistentProcess.globalOutputLastReadLength);
|
|
725
|
-
// Update the last read position
|
|
726
|
-
exports.persistentProcess.globalOutputLastReadLength = currentLength;
|
|
727
|
-
return (0, string_1.truncateStringWithMessage)({
|
|
728
|
-
str: newOutput,
|
|
729
|
-
maxLength: options.maxLength,
|
|
730
|
-
remove: 'MIDDLE',
|
|
731
|
-
});
|
|
732
|
-
};
|
|
733
|
-
exports.readNewTerminalOutput = readNewTerminalOutput;
|
|
734
|
-
//# sourceMappingURL=terminal.js.map
|