genbox-agent 0.0.2 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/configure-hooks.d.ts +17 -0
- package/dist/configure-hooks.d.ts.map +1 -0
- package/dist/configure-hooks.js +235 -0
- package/dist/configure-hooks.js.map +1 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +41 -1
- package/dist/index.js.map +1 -1
- package/dist/providers/base-provider.d.ts +125 -0
- package/dist/providers/base-provider.d.ts.map +1 -0
- package/dist/providers/base-provider.js +217 -0
- package/dist/providers/base-provider.js.map +1 -0
- package/dist/providers/claude-provider.d.ts +35 -0
- package/dist/providers/claude-provider.d.ts.map +1 -0
- package/dist/providers/claude-provider.js +298 -0
- package/dist/providers/claude-provider.js.map +1 -0
- package/dist/providers/codex-provider.d.ts +73 -0
- package/dist/providers/codex-provider.d.ts.map +1 -0
- package/dist/providers/codex-provider.js +426 -0
- package/dist/providers/codex-provider.js.map +1 -0
- package/dist/providers/gemini-provider.d.ts +37 -0
- package/dist/providers/gemini-provider.d.ts.map +1 -0
- package/dist/providers/gemini-provider.js +352 -0
- package/dist/providers/gemini-provider.js.map +1 -0
- package/dist/providers/index.d.ts +128 -0
- package/dist/providers/index.d.ts.map +1 -0
- package/dist/providers/index.js +293 -0
- package/dist/providers/index.js.map +1 -0
- package/dist/types/index.d.ts +123 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +9 -0
- package/dist/types/index.js.map +1 -0
- package/dist/unified-daemon.d.ts +18 -0
- package/dist/unified-daemon.d.ts.map +1 -0
- package/dist/unified-daemon.js +309 -0
- package/dist/unified-daemon.js.map +1 -0
- package/dist/unified-hook.d.ts +24 -0
- package/dist/unified-hook.d.ts.map +1 -0
- package/dist/unified-hook.js +173 -0
- package/dist/unified-hook.js.map +1 -0
- package/package.json +34 -8
- package/src/daemon.ts +0 -329
- package/src/hook.ts +0 -200
- package/src/index.ts +0 -1
- package/src/session-manager.ts +0 -270
- package/tsconfig.json +0 -19
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Hook Configuration Generator CLI
|
|
4
|
+
*
|
|
5
|
+
* Generates and installs hook configurations for all supported AI CLI tools.
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* genbox-configure-hooks [options]
|
|
9
|
+
*
|
|
10
|
+
* Options:
|
|
11
|
+
* --provider <name> Configure only specified provider (claude, gemini, codex)
|
|
12
|
+
* --dry-run Print configuration without installing
|
|
13
|
+
* --hook-path <path> Custom path to the hook script
|
|
14
|
+
* --help Show this help message
|
|
15
|
+
*/
|
|
16
|
+
export {};
|
|
17
|
+
//# sourceMappingURL=configure-hooks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"configure-hooks.d.ts","sourceRoot":"","sources":["../src/configure-hooks.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;GAaG"}
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
/**
|
|
4
|
+
* Hook Configuration Generator CLI
|
|
5
|
+
*
|
|
6
|
+
* Generates and installs hook configurations for all supported AI CLI tools.
|
|
7
|
+
*
|
|
8
|
+
* Usage:
|
|
9
|
+
* genbox-configure-hooks [options]
|
|
10
|
+
*
|
|
11
|
+
* Options:
|
|
12
|
+
* --provider <name> Configure only specified provider (claude, gemini, codex)
|
|
13
|
+
* --dry-run Print configuration without installing
|
|
14
|
+
* --hook-path <path> Custom path to the hook script
|
|
15
|
+
* --help Show this help message
|
|
16
|
+
*/
|
|
17
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
18
|
+
if (k2 === undefined) k2 = k;
|
|
19
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
20
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
21
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
22
|
+
}
|
|
23
|
+
Object.defineProperty(o, k2, desc);
|
|
24
|
+
}) : (function(o, m, k, k2) {
|
|
25
|
+
if (k2 === undefined) k2 = k;
|
|
26
|
+
o[k2] = m[k];
|
|
27
|
+
}));
|
|
28
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
29
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
30
|
+
}) : function(o, v) {
|
|
31
|
+
o["default"] = v;
|
|
32
|
+
});
|
|
33
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
34
|
+
var ownKeys = function(o) {
|
|
35
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
36
|
+
var ar = [];
|
|
37
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
38
|
+
return ar;
|
|
39
|
+
};
|
|
40
|
+
return ownKeys(o);
|
|
41
|
+
};
|
|
42
|
+
return function (mod) {
|
|
43
|
+
if (mod && mod.__esModule) return mod;
|
|
44
|
+
var result = {};
|
|
45
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
46
|
+
__setModuleDefault(result, mod);
|
|
47
|
+
return result;
|
|
48
|
+
};
|
|
49
|
+
})();
|
|
50
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
51
|
+
const fs = __importStar(require("fs"));
|
|
52
|
+
const path = __importStar(require("path"));
|
|
53
|
+
const providers_1 = require("./providers");
|
|
54
|
+
const HOME = process.env.HOME || '/home/dev';
|
|
55
|
+
const GENBOX_ID = process.env.GENBOX_ID || 'default';
|
|
56
|
+
function parseArgs() {
|
|
57
|
+
const args = process.argv.slice(2);
|
|
58
|
+
const options = {
|
|
59
|
+
dryRun: false,
|
|
60
|
+
help: false,
|
|
61
|
+
};
|
|
62
|
+
for (let i = 0; i < args.length; i++) {
|
|
63
|
+
switch (args[i]) {
|
|
64
|
+
case '--provider':
|
|
65
|
+
options.provider = args[++i];
|
|
66
|
+
break;
|
|
67
|
+
case '--dry-run':
|
|
68
|
+
options.dryRun = true;
|
|
69
|
+
break;
|
|
70
|
+
case '--hook-path':
|
|
71
|
+
options.hookPath = args[++i];
|
|
72
|
+
break;
|
|
73
|
+
case '--help':
|
|
74
|
+
case '-h':
|
|
75
|
+
options.help = true;
|
|
76
|
+
break;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return options;
|
|
80
|
+
}
|
|
81
|
+
function printHelp() {
|
|
82
|
+
console.log(`
|
|
83
|
+
Hook Configuration Generator for Genbox Agent
|
|
84
|
+
|
|
85
|
+
Usage:
|
|
86
|
+
genbox-configure-hooks [options]
|
|
87
|
+
|
|
88
|
+
Options:
|
|
89
|
+
--provider <name> Configure only specified provider (claude, gemini, codex)
|
|
90
|
+
--dry-run Print configuration without installing
|
|
91
|
+
--hook-path <path> Custom path to the hook script (default: auto-detected)
|
|
92
|
+
--help, -h Show this help message
|
|
93
|
+
|
|
94
|
+
Examples:
|
|
95
|
+
genbox-configure-hooks # Configure all detected providers
|
|
96
|
+
genbox-configure-hooks --provider claude # Configure only Claude Code
|
|
97
|
+
genbox-configure-hooks --dry-run # Preview configurations
|
|
98
|
+
|
|
99
|
+
Environment Variables:
|
|
100
|
+
GENBOX_ID Genbox identifier (used in configurations)
|
|
101
|
+
GENBOX_TOKEN Authentication token
|
|
102
|
+
MONITORING_API_URL Backend API URL
|
|
103
|
+
`);
|
|
104
|
+
}
|
|
105
|
+
function findHookScript() {
|
|
106
|
+
// Check common locations
|
|
107
|
+
const locations = [
|
|
108
|
+
path.join(__dirname, 'unified-hook.js'),
|
|
109
|
+
'/usr/local/bin/ai-hook',
|
|
110
|
+
path.join(HOME, '.local', 'bin', 'ai-hook'),
|
|
111
|
+
];
|
|
112
|
+
for (const loc of locations) {
|
|
113
|
+
if (fs.existsSync(loc)) {
|
|
114
|
+
return loc;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
// Default to assuming it's in PATH
|
|
118
|
+
return 'ai-hook';
|
|
119
|
+
}
|
|
120
|
+
function ensureDirectory(dirPath) {
|
|
121
|
+
if (!fs.existsSync(dirPath)) {
|
|
122
|
+
fs.mkdirSync(dirPath, { recursive: true });
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
function readJsonFile(filePath) {
|
|
126
|
+
try {
|
|
127
|
+
if (fs.existsSync(filePath)) {
|
|
128
|
+
return JSON.parse(fs.readFileSync(filePath, 'utf-8'));
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
catch {
|
|
132
|
+
// Ignore errors
|
|
133
|
+
}
|
|
134
|
+
return {};
|
|
135
|
+
}
|
|
136
|
+
function writeJsonFile(filePath, data) {
|
|
137
|
+
fs.writeFileSync(filePath, JSON.stringify(data, null, 2));
|
|
138
|
+
}
|
|
139
|
+
function mergeHookConfig(existing, newHooks) {
|
|
140
|
+
const result = { ...existing };
|
|
141
|
+
result.hooks = { ...existing.hooks, ...newHooks.hooks };
|
|
142
|
+
return result;
|
|
143
|
+
}
|
|
144
|
+
async function configureProvider(provider, hookPath, dryRun) {
|
|
145
|
+
const registry = providers_1.ProviderRegistry.getInstance();
|
|
146
|
+
const providerInstance = registry.getProvider(provider, GENBOX_ID);
|
|
147
|
+
if (!providerInstance) {
|
|
148
|
+
console.error(` Failed to get provider instance`);
|
|
149
|
+
return false;
|
|
150
|
+
}
|
|
151
|
+
const detection = providerInstance.detect();
|
|
152
|
+
if (!detection.detected) {
|
|
153
|
+
console.log(` Skipping ${provider} - not installed`);
|
|
154
|
+
return false;
|
|
155
|
+
}
|
|
156
|
+
console.log(` ${provider} detected (version: ${detection.version || 'unknown'})`);
|
|
157
|
+
const config = providerInstance.generateHookConfig(hookPath);
|
|
158
|
+
if (!config) {
|
|
159
|
+
console.error(` Failed to generate hook configuration`);
|
|
160
|
+
return false;
|
|
161
|
+
}
|
|
162
|
+
// Determine config file path
|
|
163
|
+
let configPath;
|
|
164
|
+
let configContent;
|
|
165
|
+
switch (provider) {
|
|
166
|
+
case 'claude':
|
|
167
|
+
configPath = path.join(HOME, '.claude', 'settings.json');
|
|
168
|
+
ensureDirectory(path.dirname(configPath));
|
|
169
|
+
const claudeExisting = readJsonFile(configPath);
|
|
170
|
+
const claudeMerged = mergeHookConfig(claudeExisting, config.settingsJson);
|
|
171
|
+
configContent = JSON.stringify(claudeMerged, null, 2);
|
|
172
|
+
break;
|
|
173
|
+
case 'gemini':
|
|
174
|
+
configPath = path.join(HOME, '.gemini', 'settings.json');
|
|
175
|
+
ensureDirectory(path.dirname(configPath));
|
|
176
|
+
const geminiExisting = readJsonFile(configPath);
|
|
177
|
+
const geminiMerged = mergeHookConfig(geminiExisting, config.settingsJson);
|
|
178
|
+
configContent = JSON.stringify(geminiMerged, null, 2);
|
|
179
|
+
break;
|
|
180
|
+
case 'codex':
|
|
181
|
+
configPath = path.join(HOME, '.codex', 'config.toml');
|
|
182
|
+
ensureDirectory(path.dirname(configPath));
|
|
183
|
+
// Codex uses TOML
|
|
184
|
+
const codexProvider = providerInstance;
|
|
185
|
+
configContent = codexProvider.generateTomlConfig(hookPath);
|
|
186
|
+
break;
|
|
187
|
+
default:
|
|
188
|
+
console.error(` Unknown provider: ${provider}`);
|
|
189
|
+
return false;
|
|
190
|
+
}
|
|
191
|
+
if (dryRun) {
|
|
192
|
+
console.log(`\n Would write to ${configPath}:`);
|
|
193
|
+
console.log(' ' + '-'.repeat(60));
|
|
194
|
+
configContent.split('\n').forEach(line => console.log(` ${line}`));
|
|
195
|
+
console.log(' ' + '-'.repeat(60));
|
|
196
|
+
}
|
|
197
|
+
else {
|
|
198
|
+
writeJsonFile(configPath, JSON.parse(configContent));
|
|
199
|
+
console.log(` Configuration written to ${configPath}`);
|
|
200
|
+
}
|
|
201
|
+
return true;
|
|
202
|
+
}
|
|
203
|
+
async function main() {
|
|
204
|
+
const options = parseArgs();
|
|
205
|
+
if (options.help) {
|
|
206
|
+
printHelp();
|
|
207
|
+
process.exit(0);
|
|
208
|
+
}
|
|
209
|
+
console.log('Genbox Agent Hook Configuration Generator\n');
|
|
210
|
+
const hookPath = options.hookPath || findHookScript();
|
|
211
|
+
console.log(`Using hook script: ${hookPath}`);
|
|
212
|
+
console.log(`Genbox ID: ${GENBOX_ID}`);
|
|
213
|
+
console.log(`Dry run: ${options.dryRun ? 'yes' : 'no'}\n`);
|
|
214
|
+
const providers = options.provider
|
|
215
|
+
? [options.provider]
|
|
216
|
+
: ['claude', 'gemini', 'codex'];
|
|
217
|
+
let configured = 0;
|
|
218
|
+
for (const provider of providers) {
|
|
219
|
+
console.log(`Configuring ${provider}...`);
|
|
220
|
+
const success = await configureProvider(provider, hookPath, options.dryRun);
|
|
221
|
+
if (success)
|
|
222
|
+
configured++;
|
|
223
|
+
console.log('');
|
|
224
|
+
}
|
|
225
|
+
console.log(`\nSummary: ${configured}/${providers.length} providers configured`);
|
|
226
|
+
if (!options.dryRun && configured > 0) {
|
|
227
|
+
console.log('\nHook configurations installed successfully!');
|
|
228
|
+
console.log('AI CLI tools will now report events to the monitoring service.');
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
main().catch((error) => {
|
|
232
|
+
console.error('Error:', error.message);
|
|
233
|
+
process.exit(1);
|
|
234
|
+
});
|
|
235
|
+
//# sourceMappingURL=configure-hooks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"configure-hooks.js","sourceRoot":"","sources":["../src/configure-hooks.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,2 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Genbox Agent
|
|
3
|
+
*
|
|
4
|
+
* Unified agent for monitoring and controlling AI CLI sessions across:
|
|
5
|
+
* - Claude Code (Anthropic)
|
|
6
|
+
* - Gemini CLI (Google)
|
|
7
|
+
* - Codex CLI (OpenAI)
|
|
8
|
+
*
|
|
9
|
+
* This package provides:
|
|
10
|
+
* - Session management for all AI CLIs via tmux
|
|
11
|
+
* - Hook event capture and forwarding
|
|
12
|
+
* - WebSocket daemon for remote control
|
|
13
|
+
* - Easy extensibility for new AI CLI tools
|
|
14
|
+
*/
|
|
15
|
+
export * from './types';
|
|
16
|
+
export { BaseProvider, IAIProvider, ClaudeProvider, GeminiProvider, CodexProvider, ProviderRegistry, UnifiedSessionManager, HookConfigGenerator, } from './providers';
|
|
1
17
|
export { SessionManager, ClaudeSession } from './session-manager';
|
|
2
18
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAGH,cAAc,SAAS,CAAC;AAGxB,OAAO,EACL,YAAY,EACZ,WAAW,EACX,cAAc,EACd,cAAc,EACd,aAAa,EACb,gBAAgB,EAChB,qBAAqB,EACrB,mBAAmB,GACpB,MAAM,aAAa,CAAC;AAGrB,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,46 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Genbox Agent
|
|
4
|
+
*
|
|
5
|
+
* Unified agent for monitoring and controlling AI CLI sessions across:
|
|
6
|
+
* - Claude Code (Anthropic)
|
|
7
|
+
* - Gemini CLI (Google)
|
|
8
|
+
* - Codex CLI (OpenAI)
|
|
9
|
+
*
|
|
10
|
+
* This package provides:
|
|
11
|
+
* - Session management for all AI CLIs via tmux
|
|
12
|
+
* - Hook event capture and forwarding
|
|
13
|
+
* - WebSocket daemon for remote control
|
|
14
|
+
* - Easy extensibility for new AI CLI tools
|
|
15
|
+
*/
|
|
16
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
17
|
+
if (k2 === undefined) k2 = k;
|
|
18
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
19
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
20
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
21
|
+
}
|
|
22
|
+
Object.defineProperty(o, k2, desc);
|
|
23
|
+
}) : (function(o, m, k, k2) {
|
|
24
|
+
if (k2 === undefined) k2 = k;
|
|
25
|
+
o[k2] = m[k];
|
|
26
|
+
}));
|
|
27
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
28
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
29
|
+
};
|
|
2
30
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.SessionManager = void 0;
|
|
31
|
+
exports.SessionManager = exports.HookConfigGenerator = exports.UnifiedSessionManager = exports.ProviderRegistry = exports.CodexProvider = exports.GeminiProvider = exports.ClaudeProvider = exports.BaseProvider = void 0;
|
|
32
|
+
// Types
|
|
33
|
+
__exportStar(require("./types"), exports);
|
|
34
|
+
// Providers
|
|
35
|
+
var providers_1 = require("./providers");
|
|
36
|
+
Object.defineProperty(exports, "BaseProvider", { enumerable: true, get: function () { return providers_1.BaseProvider; } });
|
|
37
|
+
Object.defineProperty(exports, "ClaudeProvider", { enumerable: true, get: function () { return providers_1.ClaudeProvider; } });
|
|
38
|
+
Object.defineProperty(exports, "GeminiProvider", { enumerable: true, get: function () { return providers_1.GeminiProvider; } });
|
|
39
|
+
Object.defineProperty(exports, "CodexProvider", { enumerable: true, get: function () { return providers_1.CodexProvider; } });
|
|
40
|
+
Object.defineProperty(exports, "ProviderRegistry", { enumerable: true, get: function () { return providers_1.ProviderRegistry; } });
|
|
41
|
+
Object.defineProperty(exports, "UnifiedSessionManager", { enumerable: true, get: function () { return providers_1.UnifiedSessionManager; } });
|
|
42
|
+
Object.defineProperty(exports, "HookConfigGenerator", { enumerable: true, get: function () { return providers_1.HookConfigGenerator; } });
|
|
43
|
+
// Legacy exports for backwards compatibility
|
|
4
44
|
var session_manager_1 = require("./session-manager");
|
|
5
45
|
Object.defineProperty(exports, "SessionManager", { enumerable: true, get: function () { return session_manager_1.SessionManager; } });
|
|
6
46
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;GAaG;;;;;;;;;;;;;;;;;AAEH,QAAQ;AACR,0CAAwB;AAExB,YAAY;AACZ,yCASqB;AARnB,yGAAA,YAAY,OAAA;AAEZ,2GAAA,cAAc,OAAA;AACd,2GAAA,cAAc,OAAA;AACd,0GAAA,aAAa,OAAA;AACb,6GAAA,gBAAgB,OAAA;AAChB,kHAAA,qBAAqB,OAAA;AACrB,gHAAA,mBAAmB,OAAA;AAGrB,6CAA6C;AAC7C,qDAAkE;AAAzD,iHAAA,cAAc,OAAA"}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base Provider Interface and Abstract Class
|
|
3
|
+
*
|
|
4
|
+
* Defines the contract that all AI CLI providers must implement
|
|
5
|
+
*/
|
|
6
|
+
import { AISession, ProviderConfig, ProviderDetectionResult, UnifiedEventType, UnifiedHookEvent, HookConfig } from '../types';
|
|
7
|
+
/**
|
|
8
|
+
* Interface that all AI CLI providers must implement
|
|
9
|
+
*/
|
|
10
|
+
export interface IAIProvider {
|
|
11
|
+
/**
|
|
12
|
+
* Provider configuration
|
|
13
|
+
*/
|
|
14
|
+
readonly config: ProviderConfig;
|
|
15
|
+
/**
|
|
16
|
+
* Detect if this provider's CLI is installed
|
|
17
|
+
*/
|
|
18
|
+
detect(): ProviderDetectionResult;
|
|
19
|
+
/**
|
|
20
|
+
* Create a new session running the AI CLI
|
|
21
|
+
*/
|
|
22
|
+
createSession(projectPath: string): AISession | null;
|
|
23
|
+
/**
|
|
24
|
+
* Send a prompt to an active session
|
|
25
|
+
*/
|
|
26
|
+
sendPrompt(sessionId: string, prompt: string): boolean;
|
|
27
|
+
/**
|
|
28
|
+
* Send a keystroke to an active session
|
|
29
|
+
*/
|
|
30
|
+
sendKeystroke(sessionId: string, key: string): boolean;
|
|
31
|
+
/**
|
|
32
|
+
* Get terminal output from a session
|
|
33
|
+
*/
|
|
34
|
+
getOutput(sessionId: string, lines?: number): string | null;
|
|
35
|
+
/**
|
|
36
|
+
* Get the status of a session
|
|
37
|
+
*/
|
|
38
|
+
getSessionStatus(sessionId: string): AISession['status'];
|
|
39
|
+
/**
|
|
40
|
+
* Kill a session
|
|
41
|
+
*/
|
|
42
|
+
killSession(sessionId: string): boolean;
|
|
43
|
+
/**
|
|
44
|
+
* List all active sessions for this provider
|
|
45
|
+
*/
|
|
46
|
+
listSessions(): AISession[];
|
|
47
|
+
/**
|
|
48
|
+
* Parse hook input from the CLI
|
|
49
|
+
*/
|
|
50
|
+
parseHookInput(eventType: string, rawInput: string): UnifiedHookEvent;
|
|
51
|
+
/**
|
|
52
|
+
* Generate hook configuration for this provider
|
|
53
|
+
*/
|
|
54
|
+
generateHookConfig(hookScriptPath: string): HookConfig;
|
|
55
|
+
/**
|
|
56
|
+
* Map provider-specific event type to unified event type
|
|
57
|
+
*/
|
|
58
|
+
mapEventType(providerEventType: string): UnifiedEventType;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Abstract base class with common functionality
|
|
62
|
+
*/
|
|
63
|
+
export declare abstract class BaseProvider implements IAIProvider {
|
|
64
|
+
protected readonly genboxId: string;
|
|
65
|
+
abstract readonly config: ProviderConfig;
|
|
66
|
+
/**
|
|
67
|
+
* Common key mapping for tmux send-keys
|
|
68
|
+
*/
|
|
69
|
+
protected readonly keyMap: Record<string, string>;
|
|
70
|
+
constructor(genboxId: string);
|
|
71
|
+
abstract detect(): ProviderDetectionResult;
|
|
72
|
+
abstract createSession(projectPath: string): AISession | null;
|
|
73
|
+
abstract parseHookInput(eventType: string, rawInput: string): UnifiedHookEvent;
|
|
74
|
+
abstract generateHookConfig(hookScriptPath: string): HookConfig;
|
|
75
|
+
/**
|
|
76
|
+
* Map provider event type to unified event type
|
|
77
|
+
*/
|
|
78
|
+
mapEventType(providerEventType: string): UnifiedEventType;
|
|
79
|
+
/**
|
|
80
|
+
* Execute a tmux command
|
|
81
|
+
*/
|
|
82
|
+
protected runTmux(args: string[], timeout?: number): {
|
|
83
|
+
stdout: string;
|
|
84
|
+
stderr: string;
|
|
85
|
+
success: boolean;
|
|
86
|
+
};
|
|
87
|
+
/**
|
|
88
|
+
* Get the tmux session name for a session ID
|
|
89
|
+
*/
|
|
90
|
+
protected getSessionName(sessionId: string): string;
|
|
91
|
+
/**
|
|
92
|
+
* Send a prompt to a session via tmux
|
|
93
|
+
*/
|
|
94
|
+
sendPrompt(sessionId: string, prompt: string): boolean;
|
|
95
|
+
/**
|
|
96
|
+
* Send a keystroke to a session via tmux
|
|
97
|
+
*/
|
|
98
|
+
sendKeystroke(sessionId: string, key: string): boolean;
|
|
99
|
+
/**
|
|
100
|
+
* Capture terminal output from a session
|
|
101
|
+
*/
|
|
102
|
+
getOutput(sessionId: string, lines?: number): string | null;
|
|
103
|
+
/**
|
|
104
|
+
* Get session status by analyzing terminal output
|
|
105
|
+
*/
|
|
106
|
+
getSessionStatus(sessionId: string): AISession['status'];
|
|
107
|
+
/**
|
|
108
|
+
* Analyze terminal output to determine status
|
|
109
|
+
* Subclasses can override for provider-specific logic
|
|
110
|
+
*/
|
|
111
|
+
protected analyzeOutputForStatus(output: string): AISession['status'];
|
|
112
|
+
/**
|
|
113
|
+
* Kill a session
|
|
114
|
+
*/
|
|
115
|
+
killSession(sessionId: string): boolean;
|
|
116
|
+
/**
|
|
117
|
+
* List all sessions for this provider
|
|
118
|
+
*/
|
|
119
|
+
listSessions(): AISession[];
|
|
120
|
+
/**
|
|
121
|
+
* Create base hook event with common fields
|
|
122
|
+
*/
|
|
123
|
+
protected createBaseHookEvent(eventType: string, sessionId: string): Partial<UnifiedHookEvent>;
|
|
124
|
+
}
|
|
125
|
+
//# sourceMappingURL=base-provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base-provider.d.ts","sourceRoot":"","sources":["../../src/providers/base-provider.ts"],"names":[],"mappings":"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"}
|