deepseek-coder-agent-cli 1.0.30 → 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/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/package.json +1 -1
|
@@ -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
|
}
|