deepseek-coder-agent-cli 1.0.29 → 1.0.31
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/README.md +86 -66
- package/dist/core/sudoPasswordManager.d.ts +52 -0
- package/dist/core/sudoPasswordManager.d.ts.map +1 -0
- package/dist/core/sudoPasswordManager.js +115 -0
- package/dist/core/sudoPasswordManager.js.map +1 -0
- package/dist/headless/interactiveShell.d.ts.map +1 -1
- package/dist/headless/interactiveShell.js +48 -0
- package/dist/headless/interactiveShell.js.map +1 -1
- package/dist/tools/bashTools.d.ts.map +1 -1
- package/dist/tools/bashTools.js +183 -8
- package/dist/tools/bashTools.js.map +1 -1
- package/dist/ui/UnifiedUIRenderer.d.ts +1 -0
- package/dist/ui/UnifiedUIRenderer.d.ts.map +1 -1
- package/dist/ui/UnifiedUIRenderer.js +30 -3
- package/dist/ui/UnifiedUIRenderer.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,15 +1,6 @@
|
|
|
1
1
|
# DeepSeek Coder CLI
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
## Features
|
|
6
|
-
|
|
7
|
-
- **Interactive Shell** - Full-featured terminal interface with multi-line input support
|
|
8
|
-
- **Code Editing** - Read, write, and edit files with AI assistance
|
|
9
|
-
- **Bash Integration** - Execute shell commands with real-time status display
|
|
10
|
-
- **Multi-Provider Support** - Works with DeepSeek, OpenAI, Anthropic, Google, and xAI
|
|
11
|
-
- **Session Management** - Save and restore conversation sessions
|
|
12
|
-
- **File Change Tracking** - Revert all changes made during a session with `/revert`
|
|
3
|
+
A multi-provider AI coding agent for the terminal. Switch between DeepSeek, OpenAI, Anthropic, Google, and xAI models with a single command.
|
|
13
4
|
|
|
14
5
|
## Installation
|
|
15
6
|
|
|
@@ -17,77 +8,94 @@ An AI-powered coding assistant for the terminal. Built for developers who prefer
|
|
|
17
8
|
npm install -g deepseek-coder-agent-cli
|
|
18
9
|
```
|
|
19
10
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
Get your API key from [DeepSeek Platform](https://platform.deepseek.com/api_keys), then:
|
|
11
|
+
Requires Node.js 20+.
|
|
23
12
|
|
|
24
|
-
|
|
25
|
-
deepseek --key YOUR_API_KEY
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
Or set via environment variable:
|
|
13
|
+
## Quick Start
|
|
29
14
|
|
|
30
15
|
```bash
|
|
16
|
+
# Set your API key
|
|
31
17
|
export DEEPSEEK_API_KEY=your_key_here
|
|
32
|
-
```
|
|
33
18
|
|
|
34
|
-
## Usage
|
|
35
|
-
|
|
36
|
-
```bash
|
|
37
19
|
# Start interactive mode
|
|
38
20
|
deepseek
|
|
39
21
|
|
|
40
|
-
#
|
|
22
|
+
# Or start with a prompt
|
|
41
23
|
deepseek "explain this codebase"
|
|
42
24
|
|
|
43
|
-
# Quick mode (
|
|
44
|
-
deepseek -q "list all
|
|
25
|
+
# Quick mode (single response, then exit)
|
|
26
|
+
deepseek -q "list all files"
|
|
45
27
|
```
|
|
46
28
|
|
|
29
|
+
## Supported Providers
|
|
30
|
+
|
|
31
|
+
| Provider | Environment Variable | Models |
|
|
32
|
+
|----------|---------------------|--------|
|
|
33
|
+
| DeepSeek | `DEEPSEEK_API_KEY` | deepseek-reasoner, deepseek-chat |
|
|
34
|
+
| OpenAI | `OPENAI_API_KEY` | gpt-5.2-pro, gpt-5.2-codex, gpt-5.2-codex-mini |
|
|
35
|
+
| Anthropic | `ANTHROPIC_API_KEY` | claude-opus-4-5, claude-sonnet-4-5, claude-haiku-4-5 |
|
|
36
|
+
| Google | `GEMINI_API_KEY` | gemini-3.0-pro, gemini-2.5-flash |
|
|
37
|
+
| xAI | `XAI_API_KEY` | grok-4-1-fast-reasoning, grok-4 |
|
|
38
|
+
| Ollama | `OLLAMA_BASE_URL` | llama3.3:70b, llama3.2:3b (local) |
|
|
39
|
+
| Qwen | `DASHSCOPE_API_KEY` | qwen-max, qwen-turbo |
|
|
40
|
+
|
|
41
|
+
Use `/model` to switch providers and models interactively.
|
|
42
|
+
|
|
47
43
|
## Commands
|
|
48
44
|
|
|
49
45
|
| Command | Description |
|
|
50
46
|
|---------|-------------|
|
|
51
|
-
| `/
|
|
52
|
-
| `/
|
|
53
|
-
| `/
|
|
54
|
-
| `/
|
|
55
|
-
| `/
|
|
56
|
-
| `/
|
|
57
|
-
| `/
|
|
58
|
-
| `/
|
|
47
|
+
| `/model` | Switch model/provider |
|
|
48
|
+
| `/help` | Show all commands |
|
|
49
|
+
| `/exit` or `/quit` | Exit the CLI |
|
|
50
|
+
| `/clear` | Clear conversation history |
|
|
51
|
+
| `/compact` | Summarize conversation to save context |
|
|
52
|
+
| `/diff` | Show git diff of changes |
|
|
53
|
+
| `/undo` | Undo last turn |
|
|
54
|
+
| `/rewind` | Rewind to a checkpoint |
|
|
55
|
+
| `/sessions` | Manage saved sessions |
|
|
56
|
+
| `/resume` | Resume a previous session |
|
|
57
|
+
| `/export` | Export conversation to file |
|
|
58
|
+
| `/context` | Refresh workspace snapshot |
|
|
59
|
+
| `/status` | Show session config and token usage |
|
|
60
|
+
| `/cost` | Show API cost breakdown |
|
|
61
|
+
| `/tools` | Enable/disable tools |
|
|
62
|
+
| `/secrets` | Configure API keys |
|
|
63
|
+
| `/providers` | List configured providers |
|
|
64
|
+
| `/refresh-models` | Discover new models from APIs |
|
|
65
|
+
| `/doctor` | Check environment and tool readiness |
|
|
66
|
+
| `/thinking` | Toggle thinking mode (balanced/extended) |
|
|
67
|
+
| `/vim` | Toggle vim-style input editing |
|
|
59
68
|
|
|
60
69
|
## Keyboard Shortcuts
|
|
61
70
|
|
|
62
71
|
| Shortcut | Action |
|
|
63
72
|
|----------|--------|
|
|
64
|
-
| `Ctrl+C` |
|
|
73
|
+
| `Ctrl+C` | Interrupt / Double-press to exit |
|
|
74
|
+
| `Ctrl+D` | Exit (when input empty) |
|
|
65
75
|
| `Ctrl+U` | Clear input line |
|
|
76
|
+
| `Esc` | Interrupt AI response |
|
|
66
77
|
| `Option+A` | Toggle auto-approve mode |
|
|
67
78
|
| `Option+G` | Toggle agentic mode |
|
|
68
|
-
| `Option+T` |
|
|
79
|
+
| `Option+T` | Cycle thinking depth |
|
|
80
|
+
|
|
81
|
+
## Tools
|
|
69
82
|
|
|
70
|
-
|
|
83
|
+
The AI has access to these tools:
|
|
71
84
|
|
|
72
85
|
| Tool | Description |
|
|
73
86
|
|------|-------------|
|
|
74
|
-
| `
|
|
75
|
-
| `
|
|
76
|
-
| `
|
|
77
|
-
| `
|
|
78
|
-
| `
|
|
79
|
-
| `
|
|
80
|
-
| `
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
|
85
|
-
|
|
86
|
-
| DeepSeek | `DEEPSEEK_API_KEY` | DeepSeek V3, DeepSeek Coder |
|
|
87
|
-
| OpenAI | `OPENAI_API_KEY` | GPT-4, GPT-4o |
|
|
88
|
-
| Anthropic | `ANTHROPIC_API_KEY` | Claude 3.5 Sonnet, Claude 3 Opus |
|
|
89
|
-
| Google | `GOOGLE_API_KEY` | Gemini 2.0 |
|
|
90
|
-
| xAI | `XAI_API_KEY` | Grok |
|
|
87
|
+
| `Read` | Read file contents |
|
|
88
|
+
| `Write` | Create or overwrite files |
|
|
89
|
+
| `Edit` | Make precise edits to files |
|
|
90
|
+
| `Bash` | Execute shell commands |
|
|
91
|
+
| `Glob` | Find files by pattern |
|
|
92
|
+
| `Grep` | Search file contents |
|
|
93
|
+
| `WebSearch` | Search the web |
|
|
94
|
+
| `WebFetch` | Fetch and analyze URLs |
|
|
95
|
+
| `LSP` | Language server operations (go to definition, find references) |
|
|
96
|
+
| `Task` | Launch background agents |
|
|
97
|
+
| `TodoWrite` | Track task progress |
|
|
98
|
+
| `HITL_Decision` | Request human input for decisions |
|
|
91
99
|
|
|
92
100
|
## CLI Options
|
|
93
101
|
|
|
@@ -95,27 +103,39 @@ deepseek -q "list all TypeScript files"
|
|
|
95
103
|
deepseek [options] [prompt]
|
|
96
104
|
|
|
97
105
|
Options:
|
|
98
|
-
-v, --version
|
|
99
|
-
-h, --help
|
|
100
|
-
-q, --quick
|
|
101
|
-
--provider <id>
|
|
102
|
-
--model <name>
|
|
103
|
-
--
|
|
104
|
-
--debug
|
|
106
|
+
-v, --version Show version
|
|
107
|
+
-h, --help Show help
|
|
108
|
+
-q, --quick Quick mode (non-interactive)
|
|
109
|
+
--provider <id> Select provider (deepseek, openai, anthropic, google, xai)
|
|
110
|
+
--model <name> Select model
|
|
111
|
+
--profile <name> Use agent profile
|
|
112
|
+
--debug Enable debug logging
|
|
105
113
|
```
|
|
106
114
|
|
|
115
|
+
## Configuration
|
|
116
|
+
|
|
117
|
+
Settings are stored in `~/.agi/`:
|
|
118
|
+
- `settings.json` - Model preferences per profile
|
|
119
|
+
- `secrets.json` - Encrypted API keys
|
|
120
|
+
- `discovered-models.json` - Cached model discovery
|
|
121
|
+
|
|
122
|
+
## Features
|
|
123
|
+
|
|
124
|
+
- **Multi-provider**: Switch between 7 AI providers seamlessly
|
|
125
|
+
- **HITL (Human-in-the-Loop)**: AI requests approval for important decisions
|
|
126
|
+
- **Session persistence**: Save and resume conversations
|
|
127
|
+
- **Checkpoint/Rewind**: Undo changes and revert to previous states
|
|
128
|
+
- **Streaming**: Real-time response streaming with interrupt support
|
|
129
|
+
- **Context management**: Automatic summarization to stay within limits
|
|
130
|
+
- **Tool permissions**: Configure which tools require approval
|
|
131
|
+
|
|
107
132
|
## Development
|
|
108
133
|
|
|
109
134
|
```bash
|
|
110
|
-
|
|
111
|
-
git clone https://github.com/anthropics/deepseek-cli.git
|
|
135
|
+
git clone <repo-url>
|
|
112
136
|
cd deepseek-cli
|
|
113
137
|
npm install
|
|
114
|
-
|
|
115
|
-
# Build
|
|
116
138
|
npm run build
|
|
117
|
-
|
|
118
|
-
# Run locally
|
|
119
139
|
npm start
|
|
120
140
|
```
|
|
121
141
|
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sudo Password Manager - handles sudo password caching and prompting
|
|
3
|
+
*
|
|
4
|
+
* This module provides a singleton manager for sudo passwords, allowing
|
|
5
|
+
* bash commands to run with sudo privileges by prompting the user for
|
|
6
|
+
* their password when needed.
|
|
7
|
+
*/
|
|
8
|
+
import { EventEmitter } from 'node:events';
|
|
9
|
+
declare class SudoPasswordManager extends EventEmitter {
|
|
10
|
+
private cachedPassword;
|
|
11
|
+
private passwordValidUntil;
|
|
12
|
+
private readonly CACHE_DURATION_MS;
|
|
13
|
+
private pendingRequest;
|
|
14
|
+
/**
|
|
15
|
+
* Get the cached sudo password if still valid
|
|
16
|
+
*/
|
|
17
|
+
getCachedPassword(): string | null;
|
|
18
|
+
/**
|
|
19
|
+
* Cache a sudo password
|
|
20
|
+
*/
|
|
21
|
+
cachePassword(password: string): void;
|
|
22
|
+
/**
|
|
23
|
+
* Invalidate the cached password (e.g., if sudo fails)
|
|
24
|
+
*/
|
|
25
|
+
invalidatePassword(): void;
|
|
26
|
+
/**
|
|
27
|
+
* Request a sudo password - emits 'password-needed' event
|
|
28
|
+
* Returns the password or null if cancelled
|
|
29
|
+
*/
|
|
30
|
+
requestPassword(): Promise<string | null>;
|
|
31
|
+
/**
|
|
32
|
+
* Provide the password in response to a 'password-needed' event
|
|
33
|
+
*/
|
|
34
|
+
providePassword(password: string | null): void;
|
|
35
|
+
/**
|
|
36
|
+
* Cancel the pending password request
|
|
37
|
+
*/
|
|
38
|
+
cancelRequest(): void;
|
|
39
|
+
/**
|
|
40
|
+
* Check if there's a pending password request
|
|
41
|
+
*/
|
|
42
|
+
hasPendingRequest(): boolean;
|
|
43
|
+
}
|
|
44
|
+
export declare const sudoPasswordManager: SudoPasswordManager;
|
|
45
|
+
export declare function getSudoPassword(): Promise<string | null>;
|
|
46
|
+
export declare function setCachedSudoPassword(password: string): void;
|
|
47
|
+
export declare function invalidateSudoPassword(): void;
|
|
48
|
+
export declare function onSudoPasswordNeeded(callback: () => void): void;
|
|
49
|
+
export declare function offSudoPasswordNeeded(callback: () => void): void;
|
|
50
|
+
export declare function provideSudoPassword(password: string | null): void;
|
|
51
|
+
export {};
|
|
52
|
+
//# sourceMappingURL=sudoPasswordManager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sudoPasswordManager.d.ts","sourceRoot":"","sources":["../../src/core/sudoPasswordManager.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAO3C,cAAM,mBAAoB,SAAQ,YAAY;IAC5C,OAAO,CAAC,cAAc,CAAuB;IAC7C,OAAO,CAAC,kBAAkB,CAAa;IACvC,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAiB;IACnD,OAAO,CAAC,cAAc,CAAoC;IAE1D;;OAEG;IACH,iBAAiB,IAAI,MAAM,GAAG,IAAI;IAOlC;;OAEG;IACH,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAKrC;;OAEG;IACH,kBAAkB,IAAI,IAAI;IAK1B;;;OAGG;IACG,eAAe,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IA0B/C;;OAEG;IACH,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAY9C;;OAEG;IACH,aAAa,IAAI,IAAI;IAQrB;;OAEG;IACH,iBAAiB,IAAI,OAAO;CAG7B;AAGD,eAAO,MAAM,mBAAmB,qBAA4B,CAAC;AAG7D,wBAAgB,eAAe,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAExD;AAED,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAE5D;AAED,wBAAgB,sBAAsB,IAAI,IAAI,CAE7C;AAED,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,IAAI,CAE/D;AAED,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,IAAI,CAEhE;AAED,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAEjE"}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sudo Password Manager - handles sudo password caching and prompting
|
|
3
|
+
*
|
|
4
|
+
* This module provides a singleton manager for sudo passwords, allowing
|
|
5
|
+
* bash commands to run with sudo privileges by prompting the user for
|
|
6
|
+
* their password when needed.
|
|
7
|
+
*/
|
|
8
|
+
import { EventEmitter } from 'node:events';
|
|
9
|
+
class SudoPasswordManager extends EventEmitter {
|
|
10
|
+
cachedPassword = null;
|
|
11
|
+
passwordValidUntil = 0;
|
|
12
|
+
CACHE_DURATION_MS = 5 * 60 * 1000; // 5 minutes (matches typical sudo timeout)
|
|
13
|
+
pendingRequest = null;
|
|
14
|
+
/**
|
|
15
|
+
* Get the cached sudo password if still valid
|
|
16
|
+
*/
|
|
17
|
+
getCachedPassword() {
|
|
18
|
+
if (this.cachedPassword && Date.now() < this.passwordValidUntil) {
|
|
19
|
+
return this.cachedPassword;
|
|
20
|
+
}
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Cache a sudo password
|
|
25
|
+
*/
|
|
26
|
+
cachePassword(password) {
|
|
27
|
+
this.cachedPassword = password;
|
|
28
|
+
this.passwordValidUntil = Date.now() + this.CACHE_DURATION_MS;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Invalidate the cached password (e.g., if sudo fails)
|
|
32
|
+
*/
|
|
33
|
+
invalidatePassword() {
|
|
34
|
+
this.cachedPassword = null;
|
|
35
|
+
this.passwordValidUntil = 0;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Request a sudo password - emits 'password-needed' event
|
|
39
|
+
* Returns the password or null if cancelled
|
|
40
|
+
*/
|
|
41
|
+
async requestPassword() {
|
|
42
|
+
// Check cache first
|
|
43
|
+
const cached = this.getCachedPassword();
|
|
44
|
+
if (cached) {
|
|
45
|
+
return cached;
|
|
46
|
+
}
|
|
47
|
+
// If there's already a pending request, wait for it
|
|
48
|
+
if (this.pendingRequest) {
|
|
49
|
+
return new Promise((resolve, reject) => {
|
|
50
|
+
// Subscribe to the same request
|
|
51
|
+
const originalResolve = this.pendingRequest.resolve;
|
|
52
|
+
this.pendingRequest.resolve = (password) => {
|
|
53
|
+
originalResolve(password);
|
|
54
|
+
resolve(password);
|
|
55
|
+
};
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
// Create new request
|
|
59
|
+
return new Promise((resolve, reject) => {
|
|
60
|
+
this.pendingRequest = { resolve, reject };
|
|
61
|
+
this.emit('password-needed');
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Provide the password in response to a 'password-needed' event
|
|
66
|
+
*/
|
|
67
|
+
providePassword(password) {
|
|
68
|
+
if (this.pendingRequest) {
|
|
69
|
+
const request = this.pendingRequest;
|
|
70
|
+
this.pendingRequest = null;
|
|
71
|
+
if (password) {
|
|
72
|
+
this.cachePassword(password);
|
|
73
|
+
}
|
|
74
|
+
request.resolve(password);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Cancel the pending password request
|
|
79
|
+
*/
|
|
80
|
+
cancelRequest() {
|
|
81
|
+
if (this.pendingRequest) {
|
|
82
|
+
const request = this.pendingRequest;
|
|
83
|
+
this.pendingRequest = null;
|
|
84
|
+
request.resolve(null);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Check if there's a pending password request
|
|
89
|
+
*/
|
|
90
|
+
hasPendingRequest() {
|
|
91
|
+
return this.pendingRequest !== null;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
// Singleton instance
|
|
95
|
+
export const sudoPasswordManager = new SudoPasswordManager();
|
|
96
|
+
// Convenience exports
|
|
97
|
+
export function getSudoPassword() {
|
|
98
|
+
return sudoPasswordManager.requestPassword();
|
|
99
|
+
}
|
|
100
|
+
export function setCachedSudoPassword(password) {
|
|
101
|
+
sudoPasswordManager.cachePassword(password);
|
|
102
|
+
}
|
|
103
|
+
export function invalidateSudoPassword() {
|
|
104
|
+
sudoPasswordManager.invalidatePassword();
|
|
105
|
+
}
|
|
106
|
+
export function onSudoPasswordNeeded(callback) {
|
|
107
|
+
sudoPasswordManager.on('password-needed', callback);
|
|
108
|
+
}
|
|
109
|
+
export function offSudoPasswordNeeded(callback) {
|
|
110
|
+
sudoPasswordManager.off('password-needed', callback);
|
|
111
|
+
}
|
|
112
|
+
export function provideSudoPassword(password) {
|
|
113
|
+
sudoPasswordManager.providePassword(password);
|
|
114
|
+
}
|
|
115
|
+
//# sourceMappingURL=sudoPasswordManager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sudoPasswordManager.js","sourceRoot":"","sources":["../../src/core/sudoPasswordManager.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"interactiveShell.d.ts","sourceRoot":"","sources":["../../src/headless/interactiveShell.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;
|
|
1
|
+
{"version":3,"file":"interactiveShell.d.ts","sourceRoot":"","sources":["../../src/headless/interactiveShell.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAyJH,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB;AAOD;;GAEG;AACH,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,uBAAuB,GAAG,OAAO,CAAC,IAAI,CAAC,CAuDzF"}
|
|
@@ -49,6 +49,7 @@ import { getSelfUpgrade, SelfUpgrade, resumeAfterUpgrade } from '../core/selfUpg
|
|
|
49
49
|
import { getHotReload } from '../core/hotReload.js';
|
|
50
50
|
import { theme } from '../ui/theme.js';
|
|
51
51
|
import { startNewRun } from '../tools/fileChangeTracker.js';
|
|
52
|
+
import { onSudoPasswordNeeded, offSudoPasswordNeeded, provideSudoPassword } from '../core/sudoPasswordManager.js';
|
|
52
53
|
// Timeout constants for attack tournament - balanced for model response time
|
|
53
54
|
const ATTACK_AGENT_STEP_TIMEOUT_MS = 24 * 60 * 60 * 1000; // 24 hours per agent step - effectively infinite
|
|
54
55
|
const ATTACK_REASONING_TIMEOUT_MS = 24 * 60 * 60 * 1000; // 24 hours max for reasoning-only before forcing action
|
|
@@ -384,6 +385,8 @@ class InteractiveShell {
|
|
|
384
385
|
// Start the UI
|
|
385
386
|
this.promptController.start();
|
|
386
387
|
this.applyDebugState(this.debugEnabled);
|
|
388
|
+
// Set up sudo password prompt handler
|
|
389
|
+
this.setupSudoPasswordHandler();
|
|
387
390
|
// Set initial status
|
|
388
391
|
this.promptController.setChromeMeta({
|
|
389
392
|
profile: this.profile,
|
|
@@ -474,6 +477,50 @@ class InteractiveShell {
|
|
|
474
477
|
// Ignore errors clearing pinned prompt
|
|
475
478
|
}
|
|
476
479
|
}
|
|
480
|
+
/**
|
|
481
|
+
* Set up handler for sudo password prompts from bash tool execution.
|
|
482
|
+
* When a sudo command needs a password, this prompts the user securely.
|
|
483
|
+
*/
|
|
484
|
+
sudoPasswordHandler = null;
|
|
485
|
+
setupSudoPasswordHandler() {
|
|
486
|
+
this.sudoPasswordHandler = async () => {
|
|
487
|
+
const renderer = this.promptController?.getRenderer();
|
|
488
|
+
if (!renderer) {
|
|
489
|
+
provideSudoPassword(null);
|
|
490
|
+
return;
|
|
491
|
+
}
|
|
492
|
+
try {
|
|
493
|
+
// Show password prompt
|
|
494
|
+
renderer.addEvent('system', chalk.yellow('🔐 Sudo password required'));
|
|
495
|
+
renderer.setSecretMode(true);
|
|
496
|
+
renderer.clearBuffer();
|
|
497
|
+
// Capture password input
|
|
498
|
+
const password = await renderer.captureInput({ allowEmpty: false, trim: true, resetBuffer: true });
|
|
499
|
+
// Hide password mode
|
|
500
|
+
renderer.setSecretMode(false);
|
|
501
|
+
if (password) {
|
|
502
|
+
provideSudoPassword(password);
|
|
503
|
+
renderer.addEvent('system', chalk.green('✓ Password provided'));
|
|
504
|
+
}
|
|
505
|
+
else {
|
|
506
|
+
provideSudoPassword(null);
|
|
507
|
+
renderer.addEvent('system', chalk.yellow('Sudo cancelled'));
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
catch (error) {
|
|
511
|
+
renderer.setSecretMode(false);
|
|
512
|
+
provideSudoPassword(null);
|
|
513
|
+
renderer.addEvent('system', chalk.red('Password prompt cancelled'));
|
|
514
|
+
}
|
|
515
|
+
};
|
|
516
|
+
onSudoPasswordNeeded(this.sudoPasswordHandler);
|
|
517
|
+
}
|
|
518
|
+
cleanupSudoPasswordHandler() {
|
|
519
|
+
if (this.sudoPasswordHandler) {
|
|
520
|
+
offSudoPasswordNeeded(this.sudoPasswordHandler);
|
|
521
|
+
this.sudoPasswordHandler = null;
|
|
522
|
+
}
|
|
523
|
+
}
|
|
477
524
|
applyDebugState(enabled, statusMessage) {
|
|
478
525
|
this.debugEnabled = enabled;
|
|
479
526
|
setDebugMode(enabled);
|
|
@@ -3727,6 +3774,7 @@ Any text response is a failure. Only tool calls are accepted.`;
|
|
|
3727
3774
|
}
|
|
3728
3775
|
handleExit() {
|
|
3729
3776
|
this.shouldExit = true;
|
|
3777
|
+
this.cleanupSudoPasswordHandler();
|
|
3730
3778
|
this.promptController?.stop();
|
|
3731
3779
|
void authorizedShutdown(0);
|
|
3732
3780
|
}
|