@gagik.co/snippet-agent 0.1.0
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/.eslintrc.js +13 -0
- package/.prettierrc.json +1 -0
- package/README.md +23 -0
- package/dist/agent-class.d.ts +47 -0
- package/dist/agent-class.js +314 -0
- package/dist/agent.d.ts +1 -0
- package/dist/agent.js +392 -0
- package/dist/banner.d.ts +1 -0
- package/dist/banner.js +23 -0
- package/dist/confirmation-extension.d.ts +10 -0
- package/dist/confirmation-extension.js +213 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +141 -0
- package/dist/mongosh-interactive-mode.d.ts +33 -0
- package/dist/mongosh-interactive-mode.js +244 -0
- package/dist/project-agent.d.ts +1 -0
- package/dist/project-agent.js +36 -0
- package/dist/shell-context.d.ts +17 -0
- package/dist/shell-context.js +75 -0
- package/dist/skills-loader.d.ts +2 -0
- package/dist/skills-loader.js +69 -0
- package/dist/src/index.d.ts +1 -0
- package/dist/src/index.js +8 -0
- package/dist/src/project-agent.d.ts +1 -0
- package/dist/src/project-agent.js +36 -0
- package/dist/stdout-patcher.d.ts +5 -0
- package/dist/stdout-patcher.js +41 -0
- package/dist/tools/index.d.ts +4 -0
- package/dist/tools/index.js +7 -0
- package/dist/tools/mongosh-eval.d.ts +7 -0
- package/dist/tools/mongosh-eval.js +84 -0
- package/dist/tools/search-docs.d.ts +2 -0
- package/dist/tools/search-docs.js +106 -0
- package/dist/tools/types.d.ts +12 -0
- package/dist/tools/types.js +2 -0
- package/dist/tools.d.ts +7 -0
- package/dist/tools.js +189 -0
- package/dist/types.d.ts +21 -0
- package/dist/types.js +2 -0
- package/package.json +38 -0
- package/skills/mongodb-connection.md +208 -0
- package/skills/mongodb-natural-language-querying.md +202 -0
- package/skills/mongodb-query-optimizer.md +265 -0
- package/skills/mongodb-schema-design.md +455 -0
- package/skills/mongodb-search-and-ai.md +357 -0
- package/skills/mongosh-shell.md +227 -0
- package/src/agent-class.ts +393 -0
- package/src/banner.ts +36 -0
- package/src/confirmation-extension.ts +297 -0
- package/src/index.ts +137 -0
- package/src/mongosh-interactive-mode.ts +420 -0
- package/src/shell-context.ts +97 -0
- package/src/skills-loader.ts +37 -0
- package/src/stdout-patcher.ts +48 -0
- package/src/tools/index.ts +4 -0
- package/src/tools/mongosh-eval.ts +115 -0
- package/src/tools/search-docs.ts +115 -0
- package/src/tools/types.ts +15 -0
- package/src/types.ts +23 -0
- package/tsconfig-lint.json +4 -0
- package/tsconfig.json +20 -0
package/.eslintrc.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
|
|
2
|
+
module.exports = {
|
|
3
|
+
root: true,
|
|
4
|
+
extends: ['@mongodb-js/eslint-config-devtools'],
|
|
5
|
+
parserOptions: {
|
|
6
|
+
tsconfigRootDir: __dirname,
|
|
7
|
+
project: ['./tsconfig-lint.json'],
|
|
8
|
+
},
|
|
9
|
+
rules: {
|
|
10
|
+
'@typescript-eslint/consistent-type-imports': 'off',
|
|
11
|
+
'@typescript-eslint/no-var-requires': 'off',
|
|
12
|
+
},
|
|
13
|
+
};
|
package/.prettierrc.json
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"@mongodb-js/prettier-config-devtools"
|
package/README.md
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# Project Agent Snippet
|
|
2
|
+
|
|
3
|
+
Integrates Pi coding agent with mongosh for programmatic agent usage.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
```javascript
|
|
14
|
+
// Chat with the Pi agent
|
|
15
|
+
projectAgent.chat("Analyze this codebase")
|
|
16
|
+
|
|
17
|
+
// Show help
|
|
18
|
+
projectAgent.help()
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Configuration
|
|
22
|
+
|
|
23
|
+
The snippet uses the `@earendil-works/pi-coding-agent` package for programmatic agent integration with mongosh.
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { Tool } from './tools';
|
|
2
|
+
import type { Skill } from './types';
|
|
3
|
+
import type { StdoutPatcher } from './stdout-patcher';
|
|
4
|
+
import type { ShellContext } from './shell-context';
|
|
5
|
+
export type AgentServices = {
|
|
6
|
+
createAgentSessionRuntime: typeof import('@earendil-works/pi-coding-agent').createAgentSessionRuntime;
|
|
7
|
+
createAgentSessionServices: typeof import('@earendil-works/pi-coding-agent').createAgentSessionServices;
|
|
8
|
+
createAgentSessionFromServices: typeof import('@earendil-works/pi-coding-agent').createAgentSessionFromServices;
|
|
9
|
+
SessionManager: typeof import('@earendil-works/pi-coding-agent').SessionManager;
|
|
10
|
+
InteractiveMode: typeof import('@earendil-works/pi-coding-agent').InteractiveMode;
|
|
11
|
+
SettingsManager: typeof import('@earendil-works/pi-coding-agent').SettingsManager;
|
|
12
|
+
getAgentDir: typeof import('@earendil-works/pi-coding-agent').getAgentDir;
|
|
13
|
+
AuthStorage: typeof import('@earendil-works/pi-coding-agent').AuthStorage;
|
|
14
|
+
ModelRegistry: typeof import('@earendil-works/pi-coding-agent').ModelRegistry;
|
|
15
|
+
};
|
|
16
|
+
export type AgentOptions = {
|
|
17
|
+
services: AgentServices;
|
|
18
|
+
mongoshEvalTool: Tool;
|
|
19
|
+
searchDocsTool: Tool;
|
|
20
|
+
loadedSkills: Skill[];
|
|
21
|
+
skillsDir: string;
|
|
22
|
+
debugLogging: boolean;
|
|
23
|
+
stdoutPatcher: StdoutPatcher;
|
|
24
|
+
shellContext: ShellContext;
|
|
25
|
+
};
|
|
26
|
+
export declare class Agent {
|
|
27
|
+
private static isRunning;
|
|
28
|
+
private sessionManager;
|
|
29
|
+
private services;
|
|
30
|
+
private mongoshEvalTool;
|
|
31
|
+
private searchDocsTool;
|
|
32
|
+
private loadedSkills;
|
|
33
|
+
private skillsDir;
|
|
34
|
+
private debugLogging;
|
|
35
|
+
private stdoutPatcher;
|
|
36
|
+
private shellContext;
|
|
37
|
+
private sessionId;
|
|
38
|
+
private resumeSessionId;
|
|
39
|
+
constructor(options: AgentOptions);
|
|
40
|
+
static getIsRunning(): boolean;
|
|
41
|
+
getCurrentSessionId(): string | undefined;
|
|
42
|
+
setResumeSessionId(sessionId: string): void;
|
|
43
|
+
resume(sessionId: string): Promise<void>;
|
|
44
|
+
run(options?: {
|
|
45
|
+
resumeSessionId?: string;
|
|
46
|
+
}): Promise<void>;
|
|
47
|
+
}
|
|
@@ -0,0 +1,314 @@
|
|
|
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 () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.Agent = void 0;
|
|
40
|
+
const os = __importStar(require("os"));
|
|
41
|
+
const path = __importStar(require("path"));
|
|
42
|
+
const banner_1 = require("./banner");
|
|
43
|
+
const confirmation_extension_1 = __importDefault(require("./confirmation-extension"));
|
|
44
|
+
const mongosh_interactive_mode_1 = require("./mongosh-interactive-mode");
|
|
45
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
46
|
+
class Agent {
|
|
47
|
+
constructor(options) {
|
|
48
|
+
this.services = options.services;
|
|
49
|
+
this.mongoshEvalTool = options.mongoshEvalTool;
|
|
50
|
+
this.searchDocsTool = options.searchDocsTool;
|
|
51
|
+
this.loadedSkills = options.loadedSkills;
|
|
52
|
+
this.skillsDir = options.skillsDir;
|
|
53
|
+
this.debugLogging = options.debugLogging;
|
|
54
|
+
this.stdoutPatcher = options.stdoutPatcher;
|
|
55
|
+
this.shellContext = options.shellContext;
|
|
56
|
+
this.sessionManager = this.services.SessionManager.create(process.cwd());
|
|
57
|
+
}
|
|
58
|
+
static getIsRunning() {
|
|
59
|
+
return Agent.isRunning;
|
|
60
|
+
}
|
|
61
|
+
getCurrentSessionId() {
|
|
62
|
+
return this.sessionId;
|
|
63
|
+
}
|
|
64
|
+
setResumeSessionId(sessionId) {
|
|
65
|
+
this.resumeSessionId = sessionId;
|
|
66
|
+
}
|
|
67
|
+
async resume(sessionId) {
|
|
68
|
+
this.resumeSessionId = sessionId;
|
|
69
|
+
await this.run({ resumeSessionId: sessionId });
|
|
70
|
+
}
|
|
71
|
+
async run(options) {
|
|
72
|
+
if (Agent.isRunning) {
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
Agent.isRunning = true;
|
|
76
|
+
const resumeSessionId = options?.resumeSessionId ?? this.resumeSessionId;
|
|
77
|
+
// Save and remove mongosh's stdin listeners to prevent interference with TUI
|
|
78
|
+
// Note: We intentionally do NOT pause() stdin as the TUI needs it for input handling
|
|
79
|
+
const savedListeners = process.stdin.rawListeners('data');
|
|
80
|
+
process.stdin.removeAllListeners('data');
|
|
81
|
+
// Ensure stdin is in flowing mode for the TUI
|
|
82
|
+
if (process.stdin.isPaused()) {
|
|
83
|
+
process.stdin.resume();
|
|
84
|
+
}
|
|
85
|
+
// Save and set raw mode to enable capturing special keys (Ctrl+O, etc.)
|
|
86
|
+
const originalRawMode = process.stdin.isTTY &&
|
|
87
|
+
process.stdin.isRaw;
|
|
88
|
+
if (process.stdin.isTTY) {
|
|
89
|
+
process.stdin.setRawMode(true);
|
|
90
|
+
}
|
|
91
|
+
const originalExit = process.exit.bind(process);
|
|
92
|
+
try {
|
|
93
|
+
const createRuntime = async (runtimeOptions) => {
|
|
94
|
+
const { SettingsManager, createAgentSessionServices, createAgentSessionFromServices, AuthStorage, ModelRegistry, } = this.services;
|
|
95
|
+
const settingsManager = SettingsManager.inMemory({
|
|
96
|
+
quietStartup: true,
|
|
97
|
+
enableInstallTelemetry: false,
|
|
98
|
+
});
|
|
99
|
+
// Create auth storage and model registry with MongoDB provider pre-configured
|
|
100
|
+
const authStorage = AuthStorage.create();
|
|
101
|
+
const modelRegistry = ModelRegistry.create(authStorage);
|
|
102
|
+
// Register the MongoDB Docs provider (same as the ai snippet's mongodb provider)
|
|
103
|
+
// Note: The MongoDB Knowledge API doesn't require authentication, but Pi SDK requires apiKey field
|
|
104
|
+
modelRegistry.registerProvider('mongodb', {
|
|
105
|
+
name: 'MongoDB',
|
|
106
|
+
baseUrl: 'https://knowledge.mongodb.com/api/v1',
|
|
107
|
+
api: 'openai-responses',
|
|
108
|
+
apiKey: 'mongodb', // Dummy key - the actual API doesn't require authentication
|
|
109
|
+
authHeader: false, // Don't send Authorization header
|
|
110
|
+
headers: {
|
|
111
|
+
'X-Request-Origin': 'mongodb-mongosh',
|
|
112
|
+
'user-agent': 'mongodb-mongosh',
|
|
113
|
+
},
|
|
114
|
+
models: [
|
|
115
|
+
{
|
|
116
|
+
id: 'mongodb-chat-latest',
|
|
117
|
+
name: 'MongoDB Assistant',
|
|
118
|
+
reasoning: false,
|
|
119
|
+
input: ['text'],
|
|
120
|
+
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
|
|
121
|
+
contextWindow: 128000,
|
|
122
|
+
maxTokens: 4000, // MongoDB Knowledge API max allowed
|
|
123
|
+
},
|
|
124
|
+
],
|
|
125
|
+
});
|
|
126
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
127
|
+
const mongoshSkills = this.loadedSkills.map((skill) => ({
|
|
128
|
+
name: skill.name,
|
|
129
|
+
description: skill.description,
|
|
130
|
+
filePath: skill.source,
|
|
131
|
+
baseDir: this.skillsDir,
|
|
132
|
+
source: 'custom',
|
|
133
|
+
sourceInfo: {
|
|
134
|
+
source: 'custom',
|
|
135
|
+
path: skill.source,
|
|
136
|
+
},
|
|
137
|
+
disableModelInvocation: false,
|
|
138
|
+
}));
|
|
139
|
+
const sessionServices = await createAgentSessionServices({
|
|
140
|
+
cwd: runtimeOptions.cwd,
|
|
141
|
+
settingsManager,
|
|
142
|
+
authStorage,
|
|
143
|
+
modelRegistry,
|
|
144
|
+
resourceLoaderOptions: {
|
|
145
|
+
extensionFactories: [confirmation_extension_1.default],
|
|
146
|
+
skillsOverride: (base) => ({
|
|
147
|
+
skills: [...base.skills, ...mongoshSkills],
|
|
148
|
+
diagnostics: base.diagnostics,
|
|
149
|
+
}),
|
|
150
|
+
systemPromptOverride: () => {
|
|
151
|
+
const basePrompt = `You are a MongoDB assistant running inside mongosh.
|
|
152
|
+
|
|
153
|
+
You are connected to a live MongoDB instance and can execute queries and commands using the mongosh_eval tool.
|
|
154
|
+
|
|
155
|
+
Guidelines:
|
|
156
|
+
- Always explain what you're about to do before running queries
|
|
157
|
+
- Use mongosh_eval for queries, inspections, and admin commands
|
|
158
|
+
- For destructive operations (drop, delete, update, insert), ask for confirmation first
|
|
159
|
+
- Suggest optimizations when you see inefficient patterns
|
|
160
|
+
- Use aggregation pipelines for complex data analysis
|
|
161
|
+
- Check indexes before suggesting queries on large collections
|
|
162
|
+
|
|
163
|
+
Available skills:
|
|
164
|
+
${this.loadedSkills.map((s) => `- ${s.name}: ${s.description}`).join('\n')}
|
|
165
|
+
|
|
166
|
+
When responding:
|
|
167
|
+
1. For simple questions, answer directly
|
|
168
|
+
2. For database queries, use mongosh_eval to check and show results
|
|
169
|
+
3. For performance questions, use explain plans to verify
|
|
170
|
+
4. Always format JSON results for readability`;
|
|
171
|
+
return basePrompt;
|
|
172
|
+
},
|
|
173
|
+
},
|
|
174
|
+
});
|
|
175
|
+
// Determine if MongoDB should be the default model
|
|
176
|
+
// Only default to mongodb-chat-latest if it's the only available model
|
|
177
|
+
// Otherwise, require manual selection by the user
|
|
178
|
+
const availableModels = modelRegistry.getAvailable();
|
|
179
|
+
const mongodbModel = modelRegistry.find('mongodb', 'mongodb-chat-latest');
|
|
180
|
+
// Check if MongoDB is the only available model (no other providers configured)
|
|
181
|
+
const otherModelsExist = availableModels.some((m) => m.provider !== 'mongodb');
|
|
182
|
+
const shouldUseMongoDbAsDefault = mongodbModel && !otherModelsExist && availableModels.length > 0;
|
|
183
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
184
|
+
const sessionFromServicesOptions = {
|
|
185
|
+
services: sessionServices,
|
|
186
|
+
sessionManager: runtimeOptions.sessionManager,
|
|
187
|
+
sessionStartEvent: runtimeOptions.sessionStartEvent,
|
|
188
|
+
customTools: [this.mongoshEvalTool, this.searchDocsTool],
|
|
189
|
+
};
|
|
190
|
+
// Only set the model if MongoDB should be the default
|
|
191
|
+
if (shouldUseMongoDbAsDefault) {
|
|
192
|
+
sessionFromServicesOptions.model = mongodbModel;
|
|
193
|
+
}
|
|
194
|
+
return {
|
|
195
|
+
...(await createAgentSessionFromServices(sessionFromServicesOptions)),
|
|
196
|
+
services: sessionServices,
|
|
197
|
+
diagnostics: sessionServices.diagnostics,
|
|
198
|
+
};
|
|
199
|
+
};
|
|
200
|
+
const { createAgentSessionRuntime } = this.services;
|
|
201
|
+
// Use custom MongoDB agent directory
|
|
202
|
+
const agentDir = path.join(os.homedir(), '.mongodb', 'mongosh', 'agent');
|
|
203
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
204
|
+
const sessionStartEvent = resumeSessionId
|
|
205
|
+
? { type: 'session-resume', sessionId: resumeSessionId }
|
|
206
|
+
: undefined;
|
|
207
|
+
const runtime = await createAgentSessionRuntime(createRuntime, {
|
|
208
|
+
cwd: process.cwd(),
|
|
209
|
+
agentDir,
|
|
210
|
+
sessionManager: this.sessionManager,
|
|
211
|
+
...(sessionStartEvent && { sessionStartEvent }),
|
|
212
|
+
});
|
|
213
|
+
// Create mongosh eval function for the interactive mode
|
|
214
|
+
const mongoshEval = async (expression) => {
|
|
215
|
+
const { shellEvaluator, originalEval, formatResultValue, instanceState, capturedPrintOutput, } = this.shellContext;
|
|
216
|
+
// Clear captured output before execution
|
|
217
|
+
capturedPrintOutput.length = 0;
|
|
218
|
+
try {
|
|
219
|
+
let rawValue = await shellEvaluator.customEval(originalEval, expression, instanceState.context, 'mongosh_interactive');
|
|
220
|
+
// Auto-call functions that take no arguments (e.g., `history` -> `history()`)
|
|
221
|
+
// This provides shell-like behavior for zero-argument functions
|
|
222
|
+
if (typeof rawValue === 'function') {
|
|
223
|
+
try {
|
|
224
|
+
rawValue = await rawValue();
|
|
225
|
+
}
|
|
226
|
+
catch {
|
|
227
|
+
// If calling fails, keep the original function reference
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
const formatted = await formatResultValue(rawValue);
|
|
231
|
+
// Build output: captured print output takes priority, then add formatted result if present
|
|
232
|
+
let output;
|
|
233
|
+
if (capturedPrintOutput.length > 0) {
|
|
234
|
+
// Has captured print output - use it as primary output
|
|
235
|
+
output = capturedPrintOutput.join('\n');
|
|
236
|
+
// Also append formatted result if it's meaningful (not empty/undefined)
|
|
237
|
+
if (formatted) {
|
|
238
|
+
output += '\n' + formatted;
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
else if (formatted) {
|
|
242
|
+
// No captured output, but has formatted result
|
|
243
|
+
output = formatted;
|
|
244
|
+
}
|
|
245
|
+
else {
|
|
246
|
+
// Nothing to show
|
|
247
|
+
output = '(no output)';
|
|
248
|
+
}
|
|
249
|
+
return { output };
|
|
250
|
+
}
|
|
251
|
+
catch (err) {
|
|
252
|
+
const errorMsg = err instanceof Error ? `${err.name}: ${err.message}` : String(err);
|
|
253
|
+
return { output: '', error: errorMsg };
|
|
254
|
+
}
|
|
255
|
+
};
|
|
256
|
+
// Create our custom interactive mode with $ mongosh support
|
|
257
|
+
const mode = new mongosh_interactive_mode_1.MongoshInteractiveMode(runtime, {
|
|
258
|
+
migratedProviders: [],
|
|
259
|
+
initialImages: [],
|
|
260
|
+
initialMessages: [],
|
|
261
|
+
verbose: this.debugLogging,
|
|
262
|
+
shellContext: this.shellContext,
|
|
263
|
+
mongoshEval,
|
|
264
|
+
debugLogging: this.debugLogging,
|
|
265
|
+
InteractiveMode: this.services.InteractiveMode,
|
|
266
|
+
});
|
|
267
|
+
this.stdoutPatcher.enable();
|
|
268
|
+
await (0, banner_1.printBanner)();
|
|
269
|
+
// Capture session ID from sessionManager
|
|
270
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
271
|
+
this.sessionId = this.sessionManager.sessionId;
|
|
272
|
+
// Initialize the mode (sets up onSubmit handler)
|
|
273
|
+
await mode.init();
|
|
274
|
+
await new Promise((resolve) => {
|
|
275
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
276
|
+
process.exit = (() => {
|
|
277
|
+
resolve();
|
|
278
|
+
});
|
|
279
|
+
mode.run().catch(() => {
|
|
280
|
+
resolve();
|
|
281
|
+
});
|
|
282
|
+
});
|
|
283
|
+
this.stdoutPatcher.disable();
|
|
284
|
+
}
|
|
285
|
+
catch (err) {
|
|
286
|
+
if (this.debugLogging) {
|
|
287
|
+
process.stderr.write(`[agent] Error: ${String(err)}\n`);
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
finally {
|
|
291
|
+
Agent.isRunning = false;
|
|
292
|
+
process.exit = originalExit;
|
|
293
|
+
// Restore terminal state
|
|
294
|
+
if (process.stdin.isTTY) {
|
|
295
|
+
process.stdin.setRawMode(originalRawMode ?? false);
|
|
296
|
+
}
|
|
297
|
+
for (const listener of savedListeners) {
|
|
298
|
+
process.stdin.on('data', listener);
|
|
299
|
+
}
|
|
300
|
+
process.stdin.resume();
|
|
301
|
+
const sessionId = this.sessionId || this.resumeSessionId;
|
|
302
|
+
if (sessionId) {
|
|
303
|
+
process.stdout.write(`Exited agent mode, resume your session with:\n${chalk_1.default.green(`agent.resume ${sessionId}`)}`);
|
|
304
|
+
}
|
|
305
|
+
else {
|
|
306
|
+
process.stdout.write('\n[Exited agent mode]');
|
|
307
|
+
}
|
|
308
|
+
// Force prompt redraw - emit newline then move up to trigger readline refresh
|
|
309
|
+
process.stdin.emit('data', '\n');
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
exports.Agent = Agent;
|
|
314
|
+
Agent.isRunning = false;
|
package/dist/agent.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|