@supaku/agentfactory-cli 0.3.0 → 0.4.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.
Files changed (34) hide show
  1. package/dist/src/analyze-logs.d.ts +2 -2
  2. package/dist/src/analyze-logs.js +23 -194
  3. package/dist/src/cleanup.d.ts +2 -6
  4. package/dist/src/cleanup.d.ts.map +1 -1
  5. package/dist/src/cleanup.js +24 -225
  6. package/dist/src/lib/analyze-logs-runner.d.ts +47 -0
  7. package/dist/src/lib/analyze-logs-runner.d.ts.map +1 -0
  8. package/dist/src/lib/analyze-logs-runner.js +216 -0
  9. package/dist/src/lib/cleanup-runner.d.ts +28 -0
  10. package/dist/src/lib/cleanup-runner.d.ts.map +1 -0
  11. package/dist/src/lib/cleanup-runner.js +224 -0
  12. package/dist/src/lib/orchestrator-runner.d.ts +45 -0
  13. package/dist/src/lib/orchestrator-runner.d.ts.map +1 -0
  14. package/dist/src/lib/orchestrator-runner.js +144 -0
  15. package/dist/src/lib/queue-admin-runner.d.ts +30 -0
  16. package/dist/src/lib/queue-admin-runner.d.ts.map +1 -0
  17. package/dist/src/lib/queue-admin-runner.js +378 -0
  18. package/dist/src/lib/worker-fleet-runner.d.ts +28 -0
  19. package/dist/src/lib/worker-fleet-runner.d.ts.map +1 -0
  20. package/dist/src/lib/worker-fleet-runner.js +224 -0
  21. package/dist/src/lib/worker-runner.d.ts +31 -0
  22. package/dist/src/lib/worker-runner.d.ts.map +1 -0
  23. package/dist/src/lib/worker-runner.js +735 -0
  24. package/dist/src/orchestrator.d.ts +1 -1
  25. package/dist/src/orchestrator.js +42 -106
  26. package/dist/src/queue-admin.d.ts +3 -2
  27. package/dist/src/queue-admin.d.ts.map +1 -1
  28. package/dist/src/queue-admin.js +38 -360
  29. package/dist/src/worker-fleet.d.ts +1 -1
  30. package/dist/src/worker-fleet.js +23 -162
  31. package/dist/src/worker.d.ts +1 -0
  32. package/dist/src/worker.d.ts.map +1 -1
  33. package/dist/src/worker.js +33 -702
  34. package/package.json +28 -4
@@ -2,8 +2,8 @@
2
2
  /**
3
3
  * AgentFactory Log Analyzer CLI
4
4
  *
5
- * Analyzes agent session logs for errors and improvement opportunities.
6
- * Can automatically create deduplicated Linear issues in the backlog.
5
+ * Thin wrapper around the analyze-logs runner. Handles dotenv, arg parsing,
6
+ * SIGINT, and process.exit so the runner stays process-agnostic.
7
7
  *
8
8
  * Usage:
9
9
  * af-analyze-logs [options]
@@ -2,8 +2,8 @@
2
2
  /**
3
3
  * AgentFactory Log Analyzer CLI
4
4
  *
5
- * Analyzes agent session logs for errors and improvement opportunities.
6
- * Can automatically create deduplicated Linear issues in the backlog.
5
+ * Thin wrapper around the analyze-logs runner. Handles dotenv, arg parsing,
6
+ * SIGINT, and process.exit so the runner stays process-agnostic.
7
7
  *
8
8
  * Usage:
9
9
  * af-analyze-logs [options]
@@ -23,25 +23,10 @@
23
23
  * AGENT_LOGS_DIR Base directory for logs (default: .agent-logs)
24
24
  */
25
25
  import path from 'path';
26
- import { execSync } from 'child_process';
27
26
  import { config } from 'dotenv';
28
27
  // Load environment variables from .env.local in CWD
29
28
  config({ path: path.resolve(process.cwd(), '.env.local') });
30
- import { createLogAnalyzer } from '@supaku/agentfactory';
31
- /**
32
- * Get the git repository root directory
33
- */
34
- function getGitRoot() {
35
- try {
36
- return execSync('git rev-parse --show-toplevel', {
37
- encoding: 'utf-8',
38
- stdio: ['pipe', 'pipe', 'pipe'],
39
- }).trim();
40
- }
41
- catch {
42
- return process.cwd();
43
- }
44
- }
29
+ import { runLogAnalyzer, printSummary } from './lib/analyze-logs-runner.js';
45
30
  const DEFAULT_POLL_INTERVAL = 5000;
46
31
  function parseArgs() {
47
32
  const args = process.argv.slice(2);
@@ -127,189 +112,33 @@ Examples:
127
112
  af-analyze-logs --verbose
128
113
  `);
129
114
  }
130
- /**
131
- * Analyze a single session and print results
132
- */
133
- async function analyzeAndPrintSession(analyzer, sessionId, options, stats) {
134
- console.log(`\nAnalyzing session: ${sessionId}`);
135
- console.log('-'.repeat(50));
136
- const result = analyzer.analyzeSession(sessionId);
137
- if (!result) {
138
- console.log(' [SKIP] Session not found or incomplete');
139
- return false;
140
- }
141
- console.log(` Issue: ${result.metadata.issueIdentifier}`);
142
- console.log(` Work Type: ${result.metadata.workType}`);
143
- console.log(` Status: ${result.metadata.status}`);
144
- console.log(` Events: ${result.eventsAnalyzed}`);
145
- console.log(` Errors: ${result.errorsFound}`);
146
- console.log(` Patterns: ${result.patterns.length}`);
147
- stats.sessionsAnalyzed++;
148
- stats.totalErrors += result.errorsFound;
149
- stats.totalPatterns += result.patterns.length;
150
- if (options.verbose && result.patterns.length > 0) {
151
- console.log('\n Detected Patterns:');
152
- for (const pattern of result.patterns) {
153
- console.log(` - [${pattern.severity}] ${pattern.title}`);
154
- console.log(` Type: ${pattern.type}, Occurrences: ${pattern.occurrences}`);
155
- if (pattern.tool) {
156
- console.log(` Tool: ${pattern.tool}`);
157
- }
158
- }
159
- }
160
- if (result.suggestedIssues.length > 0) {
161
- console.log(`\n Suggested Issues: ${result.suggestedIssues.length}`);
162
- if (options.verbose) {
163
- for (const issue of result.suggestedIssues) {
164
- console.log(` - ${issue.title}`);
165
- console.log(` Signature: ${issue.signature}`);
166
- console.log(` Labels: ${issue.labels.join(', ')}`);
167
- }
168
- }
169
- try {
170
- const issueResults = await analyzer.createIssues(result.suggestedIssues, sessionId, options.dryRun);
171
- for (const issueResult of issueResults) {
172
- if (issueResult.created) {
173
- console.log(` [${options.dryRun ? 'WOULD CREATE' : 'CREATED'}] ${issueResult.identifier}`);
174
- stats.issuesCreated++;
175
- }
176
- else {
177
- console.log(` [${options.dryRun ? 'WOULD UPDATE' : 'UPDATED'}] ${issueResult.identifier}`);
178
- stats.issuesUpdated++;
179
- }
180
- }
181
- }
182
- catch (error) {
183
- console.log(` [ERROR] Failed to create issues: ${error instanceof Error ? error.message : String(error)}`);
184
- }
185
- }
186
- if (!options.dryRun) {
187
- analyzer.markProcessed(sessionId, result);
188
- console.log(' [PROCESSED]');
189
- }
190
- return true;
191
- }
192
- /**
193
- * Print summary statistics
194
- */
195
- function printSummary(stats, dryRun) {
196
- console.log('\n' + '='.repeat(50));
197
- console.log('=== Summary ===\n');
198
- console.log(` Sessions analyzed: ${stats.sessionsAnalyzed}`);
199
- console.log(` Total errors found: ${stats.totalErrors}`);
200
- console.log(` Total patterns detected: ${stats.totalPatterns}`);
201
- console.log(` Issues created: ${stats.issuesCreated}${dryRun ? ' (dry run)' : ''}`);
202
- console.log(` Issues updated: ${stats.issuesUpdated}${dryRun ? ' (dry run)' : ''}`);
203
- console.log('');
204
- }
205
- /**
206
- * Format time for display
207
- */
208
- function formatTime() {
209
- return new Date().toLocaleTimeString();
210
- }
211
- /**
212
- * Watch mode - continuously poll for new sessions
213
- */
214
- async function runFollowMode(analyzer, options) {
215
- const stats = {
216
- sessionsAnalyzed: 0,
217
- totalErrors: 0,
218
- totalPatterns: 0,
219
- issuesCreated: 0,
220
- issuesUpdated: 0,
221
- };
222
- const processedInSession = new Set();
223
- console.log(`[${formatTime()}] Watching for new sessions (poll interval: ${options.interval}ms)`);
224
- console.log(`[${formatTime()}] Press Ctrl+C to stop\n`);
225
- let running = true;
226
- const shutdown = () => {
227
- console.log(`\n[${formatTime()}] Stopping...`);
228
- running = false;
229
- printSummary(stats, options.dryRun);
230
- process.exit(0);
231
- };
232
- process.on('SIGINT', shutdown);
233
- process.on('SIGTERM', shutdown);
234
- // Initial check for existing unprocessed sessions
235
- const initialSessions = analyzer.getUnprocessedSessions();
236
- if (initialSessions.length > 0) {
237
- console.log(`[${formatTime()}] Found ${initialSessions.length} existing unprocessed session(s)`);
238
- for (const sid of initialSessions) {
239
- if (!running)
240
- break;
241
- await analyzeAndPrintSession(analyzer, sid, options, stats);
242
- processedInSession.add(sid);
243
- }
244
- }
245
- // Poll loop
246
- while (running) {
247
- await new Promise((resolve) => setTimeout(resolve, options.interval));
248
- if (!running)
249
- break;
250
- const sessions = analyzer.getUnprocessedSessions();
251
- const newSessions = sessions.filter((s) => !processedInSession.has(s));
252
- if (newSessions.length > 0) {
253
- console.log(`[${formatTime()}] Found ${newSessions.length} new session(s) ready for analysis`);
254
- for (const sid of newSessions) {
255
- if (!running)
256
- break;
257
- const analyzed = await analyzeAndPrintSession(analyzer, sid, options, stats);
258
- if (analyzed) {
259
- processedInSession.add(sid);
260
- }
261
- }
262
- }
263
- }
264
- }
115
+ // ---------------------------------------------------------------------------
116
+ // Main
117
+ // ---------------------------------------------------------------------------
265
118
  async function main() {
266
119
  const options = parseArgs();
267
120
  if (options.showHelp) {
268
121
  printHelp();
269
122
  process.exit(0);
270
123
  }
271
- const gitRoot = getGitRoot();
272
- const logsDir = process.env.AGENT_LOGS_DIR ?? `${gitRoot}/.agent-logs`;
273
- console.log('\n=== AgentFactory Log Analyzer ===\n');
274
- if (options.dryRun) {
275
- console.log('[DRY RUN MODE - No issues will be created]\n');
276
- }
277
- const analyzer = createLogAnalyzer({ logsDir });
278
- if (options.cleanup) {
279
- console.log('Cleaning up old logs...\n');
280
- const deleted = analyzer.cleanupOldLogs();
281
- console.log(`Deleted ${deleted} old log entries.\n`);
282
- return;
283
- }
124
+ // Create AbortController for SIGINT handling in follow mode
125
+ const controller = new AbortController();
284
126
  if (options.follow) {
285
- await runFollowMode(analyzer, options);
286
- return;
287
- }
288
- // Standard one-shot mode
289
- const stats = {
290
- sessionsAnalyzed: 0,
291
- totalErrors: 0,
292
- totalPatterns: 0,
293
- issuesCreated: 0,
294
- issuesUpdated: 0,
295
- };
296
- let sessionsToAnalyze;
297
- if (options.sessionId) {
298
- sessionsToAnalyze = [options.sessionId];
299
- console.log(`Analyzing session: ${options.sessionId}\n`);
300
- }
301
- else {
302
- sessionsToAnalyze = analyzer.getUnprocessedSessions();
303
- console.log(`Found ${sessionsToAnalyze.length} unprocessed session(s)\n`);
304
- }
305
- if (sessionsToAnalyze.length === 0) {
306
- console.log('No sessions to analyze.\n');
307
- return;
308
- }
309
- for (const sid of sessionsToAnalyze) {
310
- await analyzeAndPrintSession(analyzer, sid, options, stats);
311
- }
312
- printSummary(stats, options.dryRun);
127
+ const shutdown = () => {
128
+ controller.abort();
129
+ };
130
+ process.on('SIGINT', shutdown);
131
+ process.on('SIGTERM', shutdown);
132
+ }
133
+ const result = await runLogAnalyzer({
134
+ sessionId: options.sessionId,
135
+ follow: options.follow,
136
+ interval: options.interval,
137
+ dryRun: options.dryRun,
138
+ cleanup: options.cleanup,
139
+ verbose: options.verbose,
140
+ }, controller.signal);
141
+ printSummary(result, options.dryRun);
313
142
  }
314
143
  main().catch((error) => {
315
144
  console.error('Error:', error instanceof Error ? error.message : error);
@@ -1,12 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  /**
3
- * AgentFactory Worktree Cleanup
3
+ * AgentFactory Worktree Cleanup CLI
4
4
  *
5
- * Cleans up orphaned git worktrees in the .worktrees/ directory.
6
- * Run this script periodically to remove worktrees from:
7
- * - Crashed agent sessions
8
- * - Completed work where cleanup failed
9
- * - Stale branches that have been merged/deleted
5
+ * Thin wrapper around the cleanup runner.
10
6
  *
11
7
  * Usage:
12
8
  * af-cleanup [options]
@@ -1 +1 @@
1
- {"version":3,"file":"cleanup.d.ts","sourceRoot":"","sources":["../../src/cleanup.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;;;;GAiBG"}
1
+ {"version":3,"file":"cleanup.d.ts","sourceRoot":"","sources":["../../src/cleanup.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;GAaG"}
@@ -1,12 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  /**
3
- * AgentFactory Worktree Cleanup
3
+ * AgentFactory Worktree Cleanup CLI
4
4
  *
5
- * Cleans up orphaned git worktrees in the .worktrees/ directory.
6
- * Run this script periodically to remove worktrees from:
7
- * - Crashed agent sessions
8
- * - Completed work where cleanup failed
9
- * - Stale branches that have been merged/deleted
5
+ * Thin wrapper around the cleanup runner.
10
6
  *
11
7
  * Usage:
12
8
  * af-cleanup [options]
@@ -17,30 +13,14 @@
17
13
  * --path <dir> Custom worktrees directory (default: .worktrees)
18
14
  * --help, -h Show this help message
19
15
  */
20
- import { execSync } from 'child_process';
21
- import { existsSync, readdirSync, statSync } from 'fs';
22
- import { resolve, basename } from 'path';
23
- /**
24
- * Get the git repository root directory
25
- */
26
- function getGitRoot() {
27
- try {
28
- return execSync('git rev-parse --show-toplevel', {
29
- encoding: 'utf-8',
30
- stdio: ['pipe', 'pipe', 'pipe'],
31
- }).trim();
32
- }
33
- catch {
34
- return process.cwd();
35
- }
36
- }
16
+ import { basename } from 'path';
17
+ import { runCleanup, getGitRoot } from './lib/cleanup-runner.js';
37
18
  function parseArgs() {
38
19
  const args = process.argv.slice(2);
39
- const gitRoot = getGitRoot();
40
20
  const result = {
41
21
  dryRun: false,
42
22
  force: false,
43
- worktreePath: resolve(gitRoot, '.worktrees'),
23
+ worktreePath: undefined,
44
24
  };
45
25
  for (let i = 0; i < args.length; i++) {
46
26
  const arg = args[i];
@@ -91,206 +71,7 @@ Examples:
91
71
  af-cleanup --force
92
72
  `);
93
73
  }
94
- /**
95
- * Get list of git worktrees from 'git worktree list'
96
- */
97
- function getGitWorktrees() {
98
- const worktrees = new Map();
99
- try {
100
- const output = execSync('git worktree list --porcelain', {
101
- encoding: 'utf-8',
102
- stdio: ['pipe', 'pipe', 'pipe'],
103
- });
104
- let currentPath = '';
105
- for (const line of output.split('\n')) {
106
- if (line.startsWith('worktree ')) {
107
- currentPath = line.substring(9);
108
- }
109
- else if (line.startsWith('branch ')) {
110
- const branch = line.substring(7).replace('refs/heads/', '');
111
- worktrees.set(currentPath, branch);
112
- }
113
- }
114
- }
115
- catch (error) {
116
- console.error('Failed to list git worktrees:', error);
117
- }
118
- return worktrees;
119
- }
120
- /**
121
- * Check if a git branch exists
122
- */
123
- function branchExists(branchName) {
124
- try {
125
- execSync(`git show-ref --verify --quiet refs/heads/${branchName}`, {
126
- stdio: ['pipe', 'pipe', 'pipe'],
127
- });
128
- return true;
129
- }
130
- catch {
131
- return false;
132
- }
133
- }
134
- /**
135
- * Scan the worktrees directory and identify orphaned worktrees
136
- */
137
- function scanWorktrees(options) {
138
- const worktreesDir = resolve(options.worktreePath);
139
- const result = [];
140
- if (!existsSync(worktreesDir)) {
141
- console.log(`Worktrees directory not found: ${worktreesDir}`);
142
- return result;
143
- }
144
- const gitWorktrees = getGitWorktrees();
145
- const entries = readdirSync(worktreesDir);
146
- for (const entry of entries) {
147
- const entryPath = resolve(worktreesDir, entry);
148
- try {
149
- if (!statSync(entryPath).isDirectory()) {
150
- continue;
151
- }
152
- }
153
- catch {
154
- continue;
155
- }
156
- const info = {
157
- path: entryPath,
158
- branch: entry,
159
- isOrphaned: false,
160
- };
161
- const isKnownWorktree = gitWorktrees.has(entryPath);
162
- const branchName = isKnownWorktree ? gitWorktrees.get(entryPath) : entry;
163
- if (options.force) {
164
- info.isOrphaned = true;
165
- info.reason = 'force cleanup requested';
166
- }
167
- else if (!isKnownWorktree) {
168
- info.isOrphaned = true;
169
- info.reason = 'not registered with git worktree';
170
- }
171
- else if (!branchExists(branchName)) {
172
- info.isOrphaned = true;
173
- info.reason = `branch '${branchName}' no longer exists`;
174
- }
175
- result.push(info);
176
- }
177
- return result;
178
- }
179
- /**
180
- * Remove a single worktree
181
- */
182
- function removeWorktree(worktreePath) {
183
- try {
184
- execSync(`git worktree remove "${worktreePath}" --force`, {
185
- encoding: 'utf-8',
186
- stdio: ['pipe', 'pipe', 'pipe'],
187
- });
188
- return { success: true };
189
- }
190
- catch {
191
- try {
192
- execSync(`rm -rf "${worktreePath}"`, {
193
- encoding: 'utf-8',
194
- stdio: ['pipe', 'pipe', 'pipe'],
195
- });
196
- execSync('git worktree prune', {
197
- encoding: 'utf-8',
198
- stdio: ['pipe', 'pipe', 'pipe'],
199
- });
200
- return { success: true };
201
- }
202
- catch (rmError) {
203
- return {
204
- success: false,
205
- error: rmError instanceof Error ? rmError.message : String(rmError),
206
- };
207
- }
208
- }
209
- }
210
- /**
211
- * Main cleanup function
212
- */
213
- function cleanup(options) {
214
- const result = {
215
- scanned: 0,
216
- orphaned: 0,
217
- cleaned: 0,
218
- errors: [],
219
- };
220
- console.log('Scanning worktrees...\n');
221
- try {
222
- execSync('git worktree prune', {
223
- encoding: 'utf-8',
224
- stdio: ['pipe', 'pipe', 'pipe'],
225
- });
226
- }
227
- catch {
228
- console.log('Note: Could not prune git worktree metadata');
229
- }
230
- const worktrees = scanWorktrees(options);
231
- result.scanned = worktrees.length;
232
- if (worktrees.length === 0) {
233
- console.log('No worktrees found.\n');
234
- return result;
235
- }
236
- console.log(`Found ${worktrees.length} worktree(s) in ${options.worktreePath}/\n`);
237
- for (const wt of worktrees) {
238
- const status = wt.isOrphaned ? ' orphaned' : ' active';
239
- const reason = wt.reason ? ` (${wt.reason})` : '';
240
- console.log(` ${status}: ${basename(wt.path)}${reason}`);
241
- }
242
- console.log('');
243
- const orphaned = worktrees.filter((wt) => wt.isOrphaned);
244
- result.orphaned = orphaned.length;
245
- if (orphaned.length === 0) {
246
- console.log('No orphaned worktrees to clean up.\n');
247
- return result;
248
- }
249
- if (options.dryRun) {
250
- console.log(`[DRY RUN] Would clean up ${orphaned.length} orphaned worktree(s):\n`);
251
- for (const wt of orphaned) {
252
- console.log(` Would remove: ${wt.path}`);
253
- }
254
- console.log('');
255
- return result;
256
- }
257
- console.log(`Cleaning up ${orphaned.length} orphaned worktree(s)...\n`);
258
- for (const wt of orphaned) {
259
- process.stdout.write(` Removing ${basename(wt.path)}... `);
260
- const removal = removeWorktree(wt.path);
261
- if (removal.success) {
262
- console.log('done');
263
- result.cleaned++;
264
- }
265
- else {
266
- console.log(`FAILED: ${removal.error}`);
267
- result.errors.push({ path: wt.path, error: removal.error || 'Unknown error' });
268
- }
269
- }
270
- console.log('');
271
- try {
272
- execSync('git worktree prune', {
273
- encoding: 'utf-8',
274
- stdio: ['pipe', 'pipe', 'pipe'],
275
- });
276
- console.log('Pruned git worktree metadata.\n');
277
- }
278
- catch {
279
- // Ignore prune errors
280
- }
281
- return result;
282
- }
283
- // Main execution
284
- function main() {
285
- const options = parseArgs();
286
- console.log('\n=== AgentFactory Worktree Cleanup ===\n');
287
- if (options.dryRun) {
288
- console.log('[DRY RUN MODE - No changes will be made]\n');
289
- }
290
- if (options.force) {
291
- console.log('[FORCE MODE - All worktrees will be removed]\n');
292
- }
293
- const result = cleanup(options);
74
+ function printSummary(result) {
294
75
  console.log('=== Summary ===\n');
295
76
  console.log(` Scanned: ${result.scanned} worktree(s)`);
296
77
  console.log(` Orphaned: ${result.orphaned}`);
@@ -302,6 +83,24 @@ function main() {
302
83
  }
303
84
  }
304
85
  console.log('');
86
+ }
87
+ // Main execution
88
+ function main() {
89
+ const args = parseArgs();
90
+ console.log('\n=== AgentFactory Worktree Cleanup ===\n');
91
+ if (args.dryRun) {
92
+ console.log('[DRY RUN MODE - No changes will be made]\n');
93
+ }
94
+ if (args.force) {
95
+ console.log('[FORCE MODE - All worktrees will be removed]\n');
96
+ }
97
+ const result = runCleanup({
98
+ dryRun: args.dryRun,
99
+ force: args.force,
100
+ worktreePath: args.worktreePath,
101
+ gitRoot: getGitRoot(),
102
+ });
103
+ printSummary(result);
305
104
  if (result.errors.length > 0) {
306
105
  process.exit(1);
307
106
  }
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Log Analyzer Runner -- Programmatic API for the log analyzer CLI.
3
+ *
4
+ * Extracts the core logic from the analyze-logs bin script so that it can be
5
+ * invoked programmatically (e.g. from a Next.js route handler or test) without
6
+ * process.exit / dotenv / argv coupling.
7
+ */
8
+ export interface AnalyzerRunnerConfig {
9
+ /** Analyze a specific session */
10
+ sessionId?: string;
11
+ /** Watch for new sessions and analyze as they complete */
12
+ follow?: boolean;
13
+ /** Poll interval in milliseconds (default: 5000) */
14
+ interval?: number;
15
+ /** Show what would be created without creating issues */
16
+ dryRun?: boolean;
17
+ /** Cleanup old logs based on retention policy */
18
+ cleanup?: boolean;
19
+ /** Show detailed analysis output */
20
+ verbose?: boolean;
21
+ /** Base directory for logs (default: {gitRoot}/.agent-logs or AGENT_LOGS_DIR env) */
22
+ logsDir?: string;
23
+ /** Git root for default paths (default: auto-detect) */
24
+ gitRoot?: string;
25
+ }
26
+ export interface AnalyzerResult {
27
+ sessionsAnalyzed: number;
28
+ totalErrors: number;
29
+ totalPatterns: number;
30
+ issuesCreated: number;
31
+ issuesUpdated: number;
32
+ }
33
+ /** Detect the git repository root. Falls back to cwd. */
34
+ export declare function getGitRoot(): string;
35
+ export declare function printSummary(stats: AnalyzerResult, dryRun: boolean): void;
36
+ /**
37
+ * Run the log analyzer programmatically.
38
+ *
39
+ * For one-shot mode (default) the returned promise resolves with the analysis
40
+ * result once all sessions have been processed.
41
+ *
42
+ * For follow mode (`config.follow = true`) the analyzer keeps running until
43
+ * the optional `signal` is aborted. When the signal fires the current poll
44
+ * cycle finishes and the accumulated stats are returned.
45
+ */
46
+ export declare function runLogAnalyzer(config?: AnalyzerRunnerConfig, signal?: AbortSignal): Promise<AnalyzerResult>;
47
+ //# sourceMappingURL=analyze-logs-runner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analyze-logs-runner.d.ts","sourceRoot":"","sources":["../../../src/lib/analyze-logs-runner.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AASH,MAAM,WAAW,oBAAoB;IACnC,iCAAiC;IACjC,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,0DAA0D;IAC1D,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,oDAAoD;IACpD,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,yDAAyD;IACzD,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,iDAAiD;IACjD,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,oCAAoC;IACpC,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,qFAAqF;IACrF,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,wDAAwD;IACxD,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAED,MAAM,WAAW,cAAc;IAC7B,gBAAgB,EAAE,MAAM,CAAA;IACxB,WAAW,EAAE,MAAM,CAAA;IACnB,aAAa,EAAE,MAAM,CAAA;IACrB,aAAa,EAAE,MAAM,CAAA;IACrB,aAAa,EAAE,MAAM,CAAA;CACtB;AAQD,yDAAyD;AACzD,wBAAgB,UAAU,IAAI,MAAM,CASnC;AA0GD,wBAAgB,YAAY,CAAC,KAAK,EAAE,cAAc,EAAE,MAAM,EAAE,OAAO,GAAG,IAAI,CASzE;AAqED;;;;;;;;;GASG;AACH,wBAAsB,cAAc,CAClC,MAAM,GAAE,oBAAyB,EACjC,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,cAAc,CAAC,CAkDzB"}