@specforge/mcp 2.6.0 → 3.0.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/README.md +73 -0
- package/bin/{specforge-mcp → specforge} +0 -5
- package/dist/ai-provider/circuit-breaker.d.ts +63 -0
- package/dist/ai-provider/circuit-breaker.d.ts.map +1 -0
- package/dist/ai-provider/circuit-breaker.js +160 -0
- package/dist/ai-provider/circuit-breaker.js.map +1 -0
- package/dist/ai-provider/cli-version.d.ts +50 -0
- package/dist/ai-provider/cli-version.d.ts.map +1 -0
- package/dist/ai-provider/cli-version.js +141 -0
- package/dist/ai-provider/cli-version.js.map +1 -0
- package/dist/ai-provider/config-loader.d.ts +45 -0
- package/dist/ai-provider/config-loader.d.ts.map +1 -0
- package/dist/ai-provider/config-loader.js +106 -0
- package/dist/ai-provider/config-loader.js.map +1 -0
- package/dist/ai-provider/errors.d.ts +48 -0
- package/dist/ai-provider/errors.d.ts.map +1 -0
- package/dist/ai-provider/errors.js +102 -0
- package/dist/ai-provider/errors.js.map +1 -0
- package/dist/ai-provider/events.d.ts +73 -0
- package/dist/ai-provider/events.d.ts.map +1 -0
- package/dist/ai-provider/events.js +75 -0
- package/dist/ai-provider/events.js.map +1 -0
- package/dist/ai-provider/factory.d.ts +31 -0
- package/dist/ai-provider/factory.d.ts.map +1 -0
- package/dist/ai-provider/factory.js +100 -0
- package/dist/ai-provider/factory.js.map +1 -0
- package/dist/ai-provider/index.d.ts +24 -0
- package/dist/ai-provider/index.d.ts.map +1 -0
- package/dist/ai-provider/index.js +46 -0
- package/dist/ai-provider/index.js.map +1 -0
- package/dist/ai-provider/instance-coordinator.d.ts +54 -0
- package/dist/ai-provider/instance-coordinator.d.ts.map +1 -0
- package/dist/ai-provider/instance-coordinator.js +199 -0
- package/dist/ai-provider/instance-coordinator.js.map +1 -0
- package/dist/ai-provider/jsonl-parser.d.ts +43 -0
- package/dist/ai-provider/jsonl-parser.d.ts.map +1 -0
- package/dist/ai-provider/jsonl-parser.js +107 -0
- package/dist/ai-provider/jsonl-parser.js.map +1 -0
- package/dist/ai-provider/lifecycle.d.ts +50 -0
- package/dist/ai-provider/lifecycle.d.ts.map +1 -0
- package/dist/ai-provider/lifecycle.js +145 -0
- package/dist/ai-provider/lifecycle.js.map +1 -0
- package/dist/ai-provider/logger.d.ts +69 -0
- package/dist/ai-provider/logger.d.ts.map +1 -0
- package/dist/ai-provider/logger.js +161 -0
- package/dist/ai-provider/logger.js.map +1 -0
- package/dist/ai-provider/metrics.d.ts +91 -0
- package/dist/ai-provider/metrics.d.ts.map +1 -0
- package/dist/ai-provider/metrics.js +187 -0
- package/dist/ai-provider/metrics.js.map +1 -0
- package/dist/ai-provider/process-manager.d.ts +97 -0
- package/dist/ai-provider/process-manager.d.ts.map +1 -0
- package/dist/ai-provider/process-manager.js +477 -0
- package/dist/ai-provider/process-manager.js.map +1 -0
- package/dist/ai-provider/providers/claude-code.d.ts +64 -0
- package/dist/ai-provider/providers/claude-code.d.ts.map +1 -0
- package/dist/ai-provider/providers/claude-code.js +205 -0
- package/dist/ai-provider/providers/claude-code.js.map +1 -0
- package/dist/ai-provider/retry-executor.d.ts +52 -0
- package/dist/ai-provider/retry-executor.d.ts.map +1 -0
- package/dist/ai-provider/retry-executor.js +138 -0
- package/dist/ai-provider/retry-executor.js.map +1 -0
- package/dist/ai-provider/safe-args.d.ts +58 -0
- package/dist/ai-provider/safe-args.d.ts.map +1 -0
- package/dist/ai-provider/safe-args.js +176 -0
- package/dist/ai-provider/safe-args.js.map +1 -0
- package/dist/ai-provider/semaphore.d.ts +50 -0
- package/dist/ai-provider/semaphore.d.ts.map +1 -0
- package/dist/ai-provider/semaphore.js +97 -0
- package/dist/ai-provider/semaphore.js.map +1 -0
- package/dist/ai-provider/tracer.d.ts +67 -0
- package/dist/ai-provider/tracer.d.ts.map +1 -0
- package/dist/ai-provider/tracer.js +209 -0
- package/dist/ai-provider/tracer.js.map +1 -0
- package/dist/ai-provider/types.d.ts +181 -0
- package/dist/ai-provider/types.d.ts.map +1 -0
- package/dist/ai-provider/types.js +8 -0
- package/dist/ai-provider/types.js.map +1 -0
- package/dist/autopilot/agents/agent-runner.d.ts +109 -0
- package/dist/autopilot/agents/agent-runner.d.ts.map +1 -0
- package/dist/autopilot/agents/agent-runner.js +731 -0
- package/dist/autopilot/agents/agent-runner.js.map +1 -0
- package/dist/autopilot/agents/agent-selector.d.ts +59 -0
- package/dist/autopilot/agents/agent-selector.d.ts.map +1 -0
- package/dist/autopilot/agents/agent-selector.js +234 -0
- package/dist/autopilot/agents/agent-selector.js.map +1 -0
- package/dist/autopilot/agents/model-selector.d.ts +49 -0
- package/dist/autopilot/agents/model-selector.d.ts.map +1 -0
- package/dist/autopilot/agents/model-selector.js +62 -0
- package/dist/autopilot/agents/model-selector.js.map +1 -0
- package/dist/autopilot/agents/profiles/builtin.d.ts +55 -0
- package/dist/autopilot/agents/profiles/builtin.d.ts.map +1 -0
- package/dist/autopilot/agents/profiles/builtin.js +323 -0
- package/dist/autopilot/agents/profiles/builtin.js.map +1 -0
- package/dist/autopilot/agents/profiles/types.d.ts +98 -0
- package/dist/autopilot/agents/profiles/types.d.ts.map +1 -0
- package/dist/autopilot/agents/profiles/types.js +17 -0
- package/dist/autopilot/agents/profiles/types.js.map +1 -0
- package/dist/autopilot/api/autopilot-api-client.d.ts +217 -0
- package/dist/autopilot/api/autopilot-api-client.d.ts.map +1 -0
- package/dist/autopilot/api/autopilot-api-client.js +402 -0
- package/dist/autopilot/api/autopilot-api-client.js.map +1 -0
- package/dist/autopilot/cli/abort.d.ts +20 -0
- package/dist/autopilot/cli/abort.d.ts.map +1 -0
- package/dist/autopilot/cli/abort.js +201 -0
- package/dist/autopilot/cli/abort.js.map +1 -0
- package/dist/autopilot/cli/display.d.ts +63 -0
- package/dist/autopilot/cli/display.d.ts.map +1 -0
- package/dist/autopilot/cli/display.js +260 -0
- package/dist/autopilot/cli/display.js.map +1 -0
- package/dist/autopilot/cli/index.d.ts +24 -0
- package/dist/autopilot/cli/index.d.ts.map +1 -0
- package/dist/autopilot/cli/index.js +79 -0
- package/dist/autopilot/cli/index.js.map +1 -0
- package/dist/autopilot/cli/pause.d.ts +18 -0
- package/dist/autopilot/cli/pause.d.ts.map +1 -0
- package/dist/autopilot/cli/pause.js +110 -0
- package/dist/autopilot/cli/pause.js.map +1 -0
- package/dist/autopilot/cli/resume.d.ts +22 -0
- package/dist/autopilot/cli/resume.d.ts.map +1 -0
- package/dist/autopilot/cli/resume.js +172 -0
- package/dist/autopilot/cli/resume.js.map +1 -0
- package/dist/autopilot/cli/run.d.ts +25 -0
- package/dist/autopilot/cli/run.d.ts.map +1 -0
- package/dist/autopilot/cli/run.js +220 -0
- package/dist/autopilot/cli/run.js.map +1 -0
- package/dist/autopilot/cli/status.d.ts +20 -0
- package/dist/autopilot/cli/status.d.ts.map +1 -0
- package/dist/autopilot/cli/status.js +217 -0
- package/dist/autopilot/cli/status.js.map +1 -0
- package/dist/autopilot/config.d.ts +45 -0
- package/dist/autopilot/config.d.ts.map +1 -0
- package/dist/autopilot/config.js +269 -0
- package/dist/autopilot/config.js.map +1 -0
- package/dist/autopilot/core/dependency-resolver.d.ts +108 -0
- package/dist/autopilot/core/dependency-resolver.d.ts.map +1 -0
- package/dist/autopilot/core/dependency-resolver.js +394 -0
- package/dist/autopilot/core/dependency-resolver.js.map +1 -0
- package/dist/autopilot/core/dispatcher.d.ts +215 -0
- package/dist/autopilot/core/dispatcher.d.ts.map +1 -0
- package/dist/autopilot/core/dispatcher.js +594 -0
- package/dist/autopilot/core/dispatcher.js.map +1 -0
- package/dist/autopilot/core/failure-handler.d.ts +145 -0
- package/dist/autopilot/core/failure-handler.d.ts.map +1 -0
- package/dist/autopilot/core/failure-handler.js +308 -0
- package/dist/autopilot/core/failure-handler.js.map +1 -0
- package/dist/autopilot/core/rate-limit-handler.d.ts +108 -0
- package/dist/autopilot/core/rate-limit-handler.d.ts.map +1 -0
- package/dist/autopilot/core/rate-limit-handler.js +195 -0
- package/dist/autopilot/core/rate-limit-handler.js.map +1 -0
- package/dist/autopilot/core/state-manager.d.ts +160 -0
- package/dist/autopilot/core/state-manager.d.ts.map +1 -0
- package/dist/autopilot/core/state-manager.js +393 -0
- package/dist/autopilot/core/state-manager.js.map +1 -0
- package/dist/autopilot/core/timeout-manager.d.ts +95 -0
- package/dist/autopilot/core/timeout-manager.d.ts.map +1 -0
- package/dist/autopilot/core/timeout-manager.js +188 -0
- package/dist/autopilot/core/timeout-manager.js.map +1 -0
- package/dist/autopilot/git/branch-manager.d.ts +117 -0
- package/dist/autopilot/git/branch-manager.d.ts.map +1 -0
- package/dist/autopilot/git/branch-manager.js +238 -0
- package/dist/autopilot/git/branch-manager.js.map +1 -0
- package/dist/autopilot/git/index.d.ts +9 -0
- package/dist/autopilot/git/index.d.ts.map +1 -0
- package/dist/autopilot/git/index.js +9 -0
- package/dist/autopilot/git/index.js.map +1 -0
- package/dist/autopilot/git/merge-manager.d.ts +118 -0
- package/dist/autopilot/git/merge-manager.d.ts.map +1 -0
- package/dist/autopilot/git/merge-manager.js +304 -0
- package/dist/autopilot/git/merge-manager.js.map +1 -0
- package/dist/autopilot/git/worktree-manager.d.ts +128 -0
- package/dist/autopilot/git/worktree-manager.d.ts.map +1 -0
- package/dist/autopilot/git/worktree-manager.js +298 -0
- package/dist/autopilot/git/worktree-manager.js.map +1 -0
- package/dist/autopilot/index.d.ts +30 -0
- package/dist/autopilot/index.d.ts.map +1 -0
- package/dist/autopilot/index.js +55 -0
- package/dist/autopilot/index.js.map +1 -0
- package/dist/autopilot/sync/index.d.ts +7 -0
- package/dist/autopilot/sync/index.d.ts.map +1 -0
- package/dist/autopilot/sync/index.js +7 -0
- package/dist/autopilot/sync/index.js.map +1 -0
- package/dist/autopilot/sync/sync-manager.d.ts +168 -0
- package/dist/autopilot/sync/sync-manager.d.ts.map +1 -0
- package/dist/autopilot/sync/sync-manager.js +303 -0
- package/dist/autopilot/sync/sync-manager.js.map +1 -0
- package/dist/autopilot/types.d.ts +454 -0
- package/dist/autopilot/types.d.ts.map +1 -0
- package/dist/autopilot/types.js +26 -0
- package/dist/autopilot/types.js.map +1 -0
- package/dist/autopilot/utils/audit-logger.d.ts +176 -0
- package/dist/autopilot/utils/audit-logger.d.ts.map +1 -0
- package/dist/autopilot/utils/audit-logger.js +308 -0
- package/dist/autopilot/utils/audit-logger.js.map +1 -0
- package/dist/autopilot/utils/cost-tracker.d.ts +162 -0
- package/dist/autopilot/utils/cost-tracker.d.ts.map +1 -0
- package/dist/autopilot/utils/cost-tracker.js +269 -0
- package/dist/autopilot/utils/cost-tracker.js.map +1 -0
- package/dist/autopilot/utils/index.d.ts +9 -0
- package/dist/autopilot/utils/index.d.ts.map +1 -0
- package/dist/autopilot/utils/index.js +9 -0
- package/dist/autopilot/utils/index.js.map +1 -0
- package/dist/autopilot/utils/progress-reporter.d.ts +132 -0
- package/dist/autopilot/utils/progress-reporter.d.ts.map +1 -0
- package/dist/autopilot/utils/progress-reporter.js +290 -0
- package/dist/autopilot/utils/progress-reporter.js.map +1 -0
- package/dist/autopilot/worker/worker-pool.d.ts +179 -0
- package/dist/autopilot/worker/worker-pool.d.ts.map +1 -0
- package/dist/autopilot/worker/worker-pool.js +331 -0
- package/dist/autopilot/worker/worker-pool.js.map +1 -0
- package/dist/autopilot/worker/worker-session.d.ts +171 -0
- package/dist/autopilot/worker/worker-session.d.ts.map +1 -0
- package/dist/autopilot/worker/worker-session.js +295 -0
- package/dist/autopilot/worker/worker-session.js.map +1 -0
- package/dist/cli/index.d.ts +1 -1
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +4 -1
- package/dist/cli/index.js.map +1 -1
- package/dist/index.js +0 -1
- package/dist/index.js.map +1 -1
- package/dist/tools/core/epic.js +1 -1
- package/dist/tools/core/epic.js.map +1 -1
- package/dist/tools/core/lookup.d.ts.map +1 -1
- package/dist/tools/core/lookup.js +3 -2
- package/dist/tools/core/lookup.js.map +1 -1
- package/dist/tools/core/specification.js +1 -1
- package/dist/tools/core/specification.js.map +1 -1
- package/dist/tools/core/ticket.d.ts.map +1 -1
- package/dist/tools/core/ticket.js +4 -6
- package/dist/tools/core/ticket.js.map +1 -1
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +60 -0
- package/dist/tools/index.js.map +1 -1
- package/dist/validation/index.d.ts.map +1 -1
- package/dist/validation/index.js +4 -1
- package/dist/validation/index.js.map +1 -1
- package/package.json +8 -4
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AI Provider Logger
|
|
3
|
+
*
|
|
4
|
+
* Structured JSON logging with request ID support.
|
|
5
|
+
*/
|
|
6
|
+
import type { LogLevel } from './types.js';
|
|
7
|
+
export declare class Logger {
|
|
8
|
+
private component;
|
|
9
|
+
private static globalRequestId?;
|
|
10
|
+
private static logLevel;
|
|
11
|
+
constructor(component: string);
|
|
12
|
+
/**
|
|
13
|
+
* Set global request ID for correlation
|
|
14
|
+
*/
|
|
15
|
+
static setRequestId(requestId: string): void;
|
|
16
|
+
/**
|
|
17
|
+
* Clear global request ID
|
|
18
|
+
*/
|
|
19
|
+
static clearRequestId(): void;
|
|
20
|
+
/**
|
|
21
|
+
* Get current request ID
|
|
22
|
+
*/
|
|
23
|
+
static getRequestId(): string | undefined;
|
|
24
|
+
/**
|
|
25
|
+
* Set minimum log level
|
|
26
|
+
*/
|
|
27
|
+
static setLogLevel(level: LogLevel): void;
|
|
28
|
+
/**
|
|
29
|
+
* Check if a log level should be output
|
|
30
|
+
*/
|
|
31
|
+
private shouldLog;
|
|
32
|
+
/**
|
|
33
|
+
* Log debug message
|
|
34
|
+
*/
|
|
35
|
+
debug(message: string, context?: Record<string, unknown>): void;
|
|
36
|
+
/**
|
|
37
|
+
* Log info message
|
|
38
|
+
*/
|
|
39
|
+
info(message: string, context?: Record<string, unknown>): void;
|
|
40
|
+
/**
|
|
41
|
+
* Log warning message
|
|
42
|
+
*/
|
|
43
|
+
warn(message: string, context?: Record<string, unknown>): void;
|
|
44
|
+
/**
|
|
45
|
+
* Log error message
|
|
46
|
+
*/
|
|
47
|
+
error(message: string, context?: Record<string, unknown>): void;
|
|
48
|
+
/**
|
|
49
|
+
* Log error with Error object
|
|
50
|
+
*/
|
|
51
|
+
errorWithException(message: string, error: Error, context?: Record<string, unknown>): void;
|
|
52
|
+
/**
|
|
53
|
+
* Create a child logger with additional context
|
|
54
|
+
*/
|
|
55
|
+
child(subComponent: string): Logger;
|
|
56
|
+
/**
|
|
57
|
+
* Core logging method
|
|
58
|
+
*/
|
|
59
|
+
private log;
|
|
60
|
+
/**
|
|
61
|
+
* Sanitize context to prevent PII logging
|
|
62
|
+
*/
|
|
63
|
+
private sanitizeContext;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Create a logger for a specific component
|
|
67
|
+
*/
|
|
68
|
+
export declare function createLogger(component: string): Logger;
|
|
69
|
+
//# sourceMappingURL=logger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/ai-provider/logger.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAY,MAAM,YAAY,CAAC;AAMrD,qBAAa,MAAM;IAIL,OAAO,CAAC,SAAS;IAH7B,OAAO,CAAC,MAAM,CAAC,eAAe,CAAC,CAAS;IACxC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAoB;gBAEvB,SAAS,EAAE,MAAM;IAErC;;OAEG;IACH,MAAM,CAAC,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAI5C;;OAEG;IACH,MAAM,CAAC,cAAc,IAAI,IAAI;IAI7B;;OAEG;IACH,MAAM,CAAC,YAAY,IAAI,MAAM,GAAG,SAAS;IAIzC;;OAEG;IACH,MAAM,CAAC,WAAW,CAAC,KAAK,EAAE,QAAQ,GAAG,IAAI;IAIzC;;OAEG;IACH,OAAO,CAAC,SAAS;IAOjB;;OAEG;IACH,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAI/D;;OAEG;IACH,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAI9D;;OAEG;IACH,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAI9D;;OAEG;IACH,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAI/D;;OAEG;IACH,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAW1F;;OAEG;IACH,KAAK,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM;IAInC;;OAEG;IACH,OAAO,CAAC,GAAG;IAiCX;;OAEG;IACH,OAAO,CAAC,eAAe;CAyBxB;AAMD;;GAEG;AACH,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAEtD"}
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AI Provider Logger
|
|
3
|
+
*
|
|
4
|
+
* Structured JSON logging with request ID support.
|
|
5
|
+
*/
|
|
6
|
+
// ============================================================================
|
|
7
|
+
// Logger Class
|
|
8
|
+
// ============================================================================
|
|
9
|
+
export class Logger {
|
|
10
|
+
component;
|
|
11
|
+
static globalRequestId;
|
|
12
|
+
static logLevel = 'info';
|
|
13
|
+
constructor(component) {
|
|
14
|
+
this.component = component;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Set global request ID for correlation
|
|
18
|
+
*/
|
|
19
|
+
static setRequestId(requestId) {
|
|
20
|
+
Logger.globalRequestId = requestId;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Clear global request ID
|
|
24
|
+
*/
|
|
25
|
+
static clearRequestId() {
|
|
26
|
+
Logger.globalRequestId = undefined;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Get current request ID
|
|
30
|
+
*/
|
|
31
|
+
static getRequestId() {
|
|
32
|
+
return Logger.globalRequestId;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Set minimum log level
|
|
36
|
+
*/
|
|
37
|
+
static setLogLevel(level) {
|
|
38
|
+
Logger.logLevel = level;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Check if a log level should be output
|
|
42
|
+
*/
|
|
43
|
+
shouldLog(level) {
|
|
44
|
+
const levels = ['debug', 'info', 'warn', 'error'];
|
|
45
|
+
const currentIndex = levels.indexOf(Logger.logLevel);
|
|
46
|
+
const messageIndex = levels.indexOf(level);
|
|
47
|
+
return messageIndex >= currentIndex;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Log debug message
|
|
51
|
+
*/
|
|
52
|
+
debug(message, context) {
|
|
53
|
+
this.log('debug', message, context);
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Log info message
|
|
57
|
+
*/
|
|
58
|
+
info(message, context) {
|
|
59
|
+
this.log('info', message, context);
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Log warning message
|
|
63
|
+
*/
|
|
64
|
+
warn(message, context) {
|
|
65
|
+
this.log('warn', message, context);
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Log error message
|
|
69
|
+
*/
|
|
70
|
+
error(message, context) {
|
|
71
|
+
this.log('error', message, context);
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Log error with Error object
|
|
75
|
+
*/
|
|
76
|
+
errorWithException(message, error, context) {
|
|
77
|
+
this.log('error', message, {
|
|
78
|
+
...context,
|
|
79
|
+
error: {
|
|
80
|
+
name: error.name,
|
|
81
|
+
message: error.message,
|
|
82
|
+
stack: error.stack,
|
|
83
|
+
},
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Create a child logger with additional context
|
|
88
|
+
*/
|
|
89
|
+
child(subComponent) {
|
|
90
|
+
return new Logger(`${this.component}:${subComponent}`);
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Core logging method
|
|
94
|
+
*/
|
|
95
|
+
log(level, message, context) {
|
|
96
|
+
if (!this.shouldLog(level)) {
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
const entry = {
|
|
100
|
+
timestamp: new Date().toISOString(),
|
|
101
|
+
level,
|
|
102
|
+
component: this.component,
|
|
103
|
+
message,
|
|
104
|
+
context: this.sanitizeContext(context),
|
|
105
|
+
requestId: Logger.globalRequestId,
|
|
106
|
+
};
|
|
107
|
+
// Structured JSON logging
|
|
108
|
+
const output = JSON.stringify(entry);
|
|
109
|
+
switch (level) {
|
|
110
|
+
case 'debug':
|
|
111
|
+
console.debug(output);
|
|
112
|
+
break;
|
|
113
|
+
case 'info':
|
|
114
|
+
console.info(output);
|
|
115
|
+
break;
|
|
116
|
+
case 'warn':
|
|
117
|
+
console.warn(output);
|
|
118
|
+
break;
|
|
119
|
+
case 'error':
|
|
120
|
+
console.error(output);
|
|
121
|
+
break;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Sanitize context to prevent PII logging
|
|
126
|
+
*/
|
|
127
|
+
sanitizeContext(context) {
|
|
128
|
+
if (!context) {
|
|
129
|
+
return undefined;
|
|
130
|
+
}
|
|
131
|
+
const sanitized = {};
|
|
132
|
+
const sensitiveKeys = ['password', 'token', 'apiKey', 'secret', 'credential', 'auth'];
|
|
133
|
+
for (const [key, value] of Object.entries(context)) {
|
|
134
|
+
const lowerKey = key.toLowerCase();
|
|
135
|
+
const isSensitive = sensitiveKeys.some(sk => lowerKey.includes(sk));
|
|
136
|
+
if (isSensitive) {
|
|
137
|
+
sanitized[key] = '[REDACTED]';
|
|
138
|
+
}
|
|
139
|
+
else if (typeof value === 'string' && value.length > 1000) {
|
|
140
|
+
sanitized[key] = value.substring(0, 1000) + '...[TRUNCATED]';
|
|
141
|
+
}
|
|
142
|
+
else if (typeof value === 'object' && value !== null) {
|
|
143
|
+
sanitized[key] = this.sanitizeContext(value);
|
|
144
|
+
}
|
|
145
|
+
else {
|
|
146
|
+
sanitized[key] = value;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
return sanitized;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
// ============================================================================
|
|
153
|
+
// Factory Function
|
|
154
|
+
// ============================================================================
|
|
155
|
+
/**
|
|
156
|
+
* Create a logger for a specific component
|
|
157
|
+
*/
|
|
158
|
+
export function createLogger(component) {
|
|
159
|
+
return new Logger(component);
|
|
160
|
+
}
|
|
161
|
+
//# sourceMappingURL=logger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/ai-provider/logger.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Metrics Collection
|
|
3
|
+
*
|
|
4
|
+
* Counters and histograms for observability.
|
|
5
|
+
*/
|
|
6
|
+
import type { MetricStats } from './types.js';
|
|
7
|
+
export declare class Metrics {
|
|
8
|
+
private counters;
|
|
9
|
+
private histograms;
|
|
10
|
+
private gauges;
|
|
11
|
+
/**
|
|
12
|
+
* Increment a counter.
|
|
13
|
+
*/
|
|
14
|
+
increment(name: string, value?: number): void;
|
|
15
|
+
/**
|
|
16
|
+
* Decrement a counter.
|
|
17
|
+
*/
|
|
18
|
+
decrement(name: string, value?: number): void;
|
|
19
|
+
/**
|
|
20
|
+
* Record a value in a histogram.
|
|
21
|
+
*/
|
|
22
|
+
histogram(name: string, value: number): void;
|
|
23
|
+
/**
|
|
24
|
+
* Set a gauge value.
|
|
25
|
+
*/
|
|
26
|
+
gauge(name: string, value: number): void;
|
|
27
|
+
/**
|
|
28
|
+
* Get a counter value.
|
|
29
|
+
*/
|
|
30
|
+
getCounter(name: string): number;
|
|
31
|
+
/**
|
|
32
|
+
* Get a gauge value.
|
|
33
|
+
*/
|
|
34
|
+
getGauge(name: string): number;
|
|
35
|
+
/**
|
|
36
|
+
* Get histogram statistics.
|
|
37
|
+
*/
|
|
38
|
+
getHistogramStats(name: string): MetricStats | null;
|
|
39
|
+
/**
|
|
40
|
+
* Get all metrics.
|
|
41
|
+
*/
|
|
42
|
+
getAll(): {
|
|
43
|
+
counters: Record<string, number>;
|
|
44
|
+
gauges: Record<string, number>;
|
|
45
|
+
histograms: Record<string, MetricStats | null>;
|
|
46
|
+
};
|
|
47
|
+
/**
|
|
48
|
+
* Reset all metrics.
|
|
49
|
+
*/
|
|
50
|
+
reset(): void;
|
|
51
|
+
/**
|
|
52
|
+
* Reset a specific metric.
|
|
53
|
+
*/
|
|
54
|
+
resetMetric(name: string): void;
|
|
55
|
+
/**
|
|
56
|
+
* Export metrics as Prometheus-style text.
|
|
57
|
+
*/
|
|
58
|
+
toPrometheus(): string;
|
|
59
|
+
/**
|
|
60
|
+
* Calculate percentile from sorted array.
|
|
61
|
+
*/
|
|
62
|
+
private percentile;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Get or create global metrics instance.
|
|
66
|
+
*/
|
|
67
|
+
export declare function getMetrics(): Metrics;
|
|
68
|
+
/**
|
|
69
|
+
* Create a new metrics instance.
|
|
70
|
+
*/
|
|
71
|
+
export declare function createMetrics(): Metrics;
|
|
72
|
+
export declare const METRIC_NAMES: {
|
|
73
|
+
readonly REQUESTS_STARTED: "requests.started";
|
|
74
|
+
readonly REQUESTS_SUCCESS: "requests.success";
|
|
75
|
+
readonly REQUESTS_FAILURE: "requests.failure";
|
|
76
|
+
readonly REQUESTS_TIMEOUT: "requests.timeout";
|
|
77
|
+
readonly REQUESTS_CIRCUIT_BLOCKED: "requests.circuit_breaker_blocked";
|
|
78
|
+
readonly REQUEST_DURATION_MS: "requests.duration_ms";
|
|
79
|
+
readonly SPAWN_DURATION_MS: "spawn.duration_ms";
|
|
80
|
+
readonly PROCESSES_ACTIVE: "processes.active";
|
|
81
|
+
readonly PROCESSES_SPAWNED: "processes.spawned";
|
|
82
|
+
readonly PROCESSES_KILLED: "processes.killed";
|
|
83
|
+
readonly ERRORS_AUTH: "errors.auth";
|
|
84
|
+
readonly ERRORS_RATE_LIMIT: "errors.rate_limit";
|
|
85
|
+
readonly ERRORS_TIMEOUT: "errors.timeout";
|
|
86
|
+
readonly ERRORS_NETWORK: "errors.network";
|
|
87
|
+
readonly ERRORS_UNKNOWN: "errors.unknown";
|
|
88
|
+
readonly RETRIES_ATTEMPTED: "retries.attempted";
|
|
89
|
+
readonly RETRIES_SUCCESS: "retries.success";
|
|
90
|
+
};
|
|
91
|
+
//# sourceMappingURL=metrics.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metrics.d.ts","sourceRoot":"","sources":["../../src/ai-provider/metrics.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C,qBAAa,OAAO;IAClB,OAAO,CAAC,QAAQ,CAAkC;IAClD,OAAO,CAAC,UAAU,CAAoC;IACtD,OAAO,CAAC,MAAM,CAAkC;IAEhD;;OAEG;IACH,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,GAAE,MAAU,GAAG,IAAI;IAKhD;;OAEG;IACH,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,GAAE,MAAU,GAAG,IAAI;IAKhD;;OAEG;IACH,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAM5C;;OAEG;IACH,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAIxC;;OAEG;IACH,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAIhC;;OAEG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAI9B;;OAEG;IACH,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI;IAkBnD;;OAEG;IACH,MAAM,IAAI;QACR,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACjC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAC/B,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI,CAAC,CAAC;KAChD;IAaD;;OAEG;IACH,KAAK,IAAI,IAAI;IAMb;;OAEG;IACH,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAM/B;;OAEG;IACH,YAAY,IAAI,MAAM;IAsCtB;;OAEG;IACH,OAAO,CAAC,UAAU;CAInB;AAOD;;GAEG;AACH,wBAAgB,UAAU,IAAI,OAAO,CAKpC;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI,OAAO,CAEvC;AAGD,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;CA2Bf,CAAC"}
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Metrics Collection
|
|
3
|
+
*
|
|
4
|
+
* Counters and histograms for observability.
|
|
5
|
+
*/
|
|
6
|
+
export class Metrics {
|
|
7
|
+
counters = new Map();
|
|
8
|
+
histograms = new Map();
|
|
9
|
+
gauges = new Map();
|
|
10
|
+
/**
|
|
11
|
+
* Increment a counter.
|
|
12
|
+
*/
|
|
13
|
+
increment(name, value = 1) {
|
|
14
|
+
const current = this.counters.get(name) || 0;
|
|
15
|
+
this.counters.set(name, current + value);
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Decrement a counter.
|
|
19
|
+
*/
|
|
20
|
+
decrement(name, value = 1) {
|
|
21
|
+
const current = this.counters.get(name) || 0;
|
|
22
|
+
this.counters.set(name, Math.max(0, current - value));
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Record a value in a histogram.
|
|
26
|
+
*/
|
|
27
|
+
histogram(name, value) {
|
|
28
|
+
const values = this.histograms.get(name) || [];
|
|
29
|
+
values.push(value);
|
|
30
|
+
this.histograms.set(name, values);
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Set a gauge value.
|
|
34
|
+
*/
|
|
35
|
+
gauge(name, value) {
|
|
36
|
+
this.gauges.set(name, value);
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Get a counter value.
|
|
40
|
+
*/
|
|
41
|
+
getCounter(name) {
|
|
42
|
+
return this.counters.get(name) || 0;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Get a gauge value.
|
|
46
|
+
*/
|
|
47
|
+
getGauge(name) {
|
|
48
|
+
return this.gauges.get(name) || 0;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Get histogram statistics.
|
|
52
|
+
*/
|
|
53
|
+
getHistogramStats(name) {
|
|
54
|
+
const values = this.histograms.get(name);
|
|
55
|
+
if (!values || values.length === 0)
|
|
56
|
+
return null;
|
|
57
|
+
const sorted = [...values].sort((a, b) => a - b);
|
|
58
|
+
const count = sorted.length;
|
|
59
|
+
return {
|
|
60
|
+
count,
|
|
61
|
+
min: sorted[0],
|
|
62
|
+
max: sorted[count - 1],
|
|
63
|
+
avg: sorted.reduce((a, b) => a + b, 0) / count,
|
|
64
|
+
p50: this.percentile(sorted, 0.5),
|
|
65
|
+
p95: this.percentile(sorted, 0.95),
|
|
66
|
+
p99: this.percentile(sorted, 0.99),
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Get all metrics.
|
|
71
|
+
*/
|
|
72
|
+
getAll() {
|
|
73
|
+
const histograms = {};
|
|
74
|
+
for (const name of this.histograms.keys()) {
|
|
75
|
+
histograms[name] = this.getHistogramStats(name);
|
|
76
|
+
}
|
|
77
|
+
return {
|
|
78
|
+
counters: Object.fromEntries(this.counters),
|
|
79
|
+
gauges: Object.fromEntries(this.gauges),
|
|
80
|
+
histograms,
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Reset all metrics.
|
|
85
|
+
*/
|
|
86
|
+
reset() {
|
|
87
|
+
this.counters.clear();
|
|
88
|
+
this.histograms.clear();
|
|
89
|
+
this.gauges.clear();
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Reset a specific metric.
|
|
93
|
+
*/
|
|
94
|
+
resetMetric(name) {
|
|
95
|
+
this.counters.delete(name);
|
|
96
|
+
this.histograms.delete(name);
|
|
97
|
+
this.gauges.delete(name);
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Export metrics as Prometheus-style text.
|
|
101
|
+
*/
|
|
102
|
+
toPrometheus() {
|
|
103
|
+
const lines = [];
|
|
104
|
+
// Counters
|
|
105
|
+
for (const [name, value] of this.counters) {
|
|
106
|
+
const safeName = name.replace(/\./g, '_');
|
|
107
|
+
lines.push(`# TYPE ${safeName} counter`);
|
|
108
|
+
lines.push(`${safeName} ${value}`);
|
|
109
|
+
}
|
|
110
|
+
// Gauges
|
|
111
|
+
for (const [name, value] of this.gauges) {
|
|
112
|
+
const safeName = name.replace(/\./g, '_');
|
|
113
|
+
lines.push(`# TYPE ${safeName} gauge`);
|
|
114
|
+
lines.push(`${safeName} ${value}`);
|
|
115
|
+
}
|
|
116
|
+
// Histograms
|
|
117
|
+
for (const [name, values] of this.histograms) {
|
|
118
|
+
if (values.length === 0)
|
|
119
|
+
continue;
|
|
120
|
+
const safeName = name.replace(/\./g, '_');
|
|
121
|
+
const stats = this.getHistogramStats(name);
|
|
122
|
+
if (!stats)
|
|
123
|
+
continue;
|
|
124
|
+
lines.push(`# TYPE ${safeName} histogram`);
|
|
125
|
+
lines.push(`${safeName}_count ${stats.count}`);
|
|
126
|
+
lines.push(`${safeName}_sum ${values.reduce((a, b) => a + b, 0)}`);
|
|
127
|
+
lines.push(`${safeName}_min ${stats.min}`);
|
|
128
|
+
lines.push(`${safeName}_max ${stats.max}`);
|
|
129
|
+
lines.push(`${safeName}{quantile="0.5"} ${stats.p50}`);
|
|
130
|
+
lines.push(`${safeName}{quantile="0.95"} ${stats.p95}`);
|
|
131
|
+
lines.push(`${safeName}{quantile="0.99"} ${stats.p99}`);
|
|
132
|
+
}
|
|
133
|
+
return lines.join('\n');
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Calculate percentile from sorted array.
|
|
137
|
+
*/
|
|
138
|
+
percentile(sorted, p) {
|
|
139
|
+
const index = Math.ceil(sorted.length * p) - 1;
|
|
140
|
+
return sorted[Math.max(0, Math.min(index, sorted.length - 1))];
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Global metrics instance.
|
|
145
|
+
*/
|
|
146
|
+
let globalMetrics = null;
|
|
147
|
+
/**
|
|
148
|
+
* Get or create global metrics instance.
|
|
149
|
+
*/
|
|
150
|
+
export function getMetrics() {
|
|
151
|
+
if (!globalMetrics) {
|
|
152
|
+
globalMetrics = new Metrics();
|
|
153
|
+
}
|
|
154
|
+
return globalMetrics;
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Create a new metrics instance.
|
|
158
|
+
*/
|
|
159
|
+
export function createMetrics() {
|
|
160
|
+
return new Metrics();
|
|
161
|
+
}
|
|
162
|
+
// Metric name constants for consistency
|
|
163
|
+
export const METRIC_NAMES = {
|
|
164
|
+
// Request metrics
|
|
165
|
+
REQUESTS_STARTED: 'requests.started',
|
|
166
|
+
REQUESTS_SUCCESS: 'requests.success',
|
|
167
|
+
REQUESTS_FAILURE: 'requests.failure',
|
|
168
|
+
REQUESTS_TIMEOUT: 'requests.timeout',
|
|
169
|
+
REQUESTS_CIRCUIT_BLOCKED: 'requests.circuit_breaker_blocked',
|
|
170
|
+
// Duration metrics
|
|
171
|
+
REQUEST_DURATION_MS: 'requests.duration_ms',
|
|
172
|
+
SPAWN_DURATION_MS: 'spawn.duration_ms',
|
|
173
|
+
// Process metrics
|
|
174
|
+
PROCESSES_ACTIVE: 'processes.active',
|
|
175
|
+
PROCESSES_SPAWNED: 'processes.spawned',
|
|
176
|
+
PROCESSES_KILLED: 'processes.killed',
|
|
177
|
+
// Error metrics
|
|
178
|
+
ERRORS_AUTH: 'errors.auth',
|
|
179
|
+
ERRORS_RATE_LIMIT: 'errors.rate_limit',
|
|
180
|
+
ERRORS_TIMEOUT: 'errors.timeout',
|
|
181
|
+
ERRORS_NETWORK: 'errors.network',
|
|
182
|
+
ERRORS_UNKNOWN: 'errors.unknown',
|
|
183
|
+
// Retry metrics
|
|
184
|
+
RETRIES_ATTEMPTED: 'retries.attempted',
|
|
185
|
+
RETRIES_SUCCESS: 'retries.success',
|
|
186
|
+
};
|
|
187
|
+
//# sourceMappingURL=metrics.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metrics.js","sourceRoot":"","sources":["../../src/ai-provider/metrics.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Claude Code Process Manager
|
|
3
|
+
*
|
|
4
|
+
* Core module for spawning and managing Claude CLI processes.
|
|
5
|
+
*/
|
|
6
|
+
import type { ProcessManagerConfig, ProcessResult, ProcessStatus } from './types.js';
|
|
7
|
+
/**
|
|
8
|
+
* Claude CLI Process Manager.
|
|
9
|
+
*/
|
|
10
|
+
export declare class ClaudeCodeProcessManager {
|
|
11
|
+
private config;
|
|
12
|
+
private semaphore;
|
|
13
|
+
private circuitBreaker;
|
|
14
|
+
private retryExecutor;
|
|
15
|
+
private activeProcesses;
|
|
16
|
+
private isRateLimited;
|
|
17
|
+
private rateLimitMessage?;
|
|
18
|
+
private metrics;
|
|
19
|
+
private tracer;
|
|
20
|
+
private isShuttingDown;
|
|
21
|
+
constructor(config: ProcessManagerConfig);
|
|
22
|
+
/**
|
|
23
|
+
* Check if user is authenticated with Claude Code.
|
|
24
|
+
*/
|
|
25
|
+
checkAuth(): Promise<{
|
|
26
|
+
authenticated: boolean;
|
|
27
|
+
error?: string;
|
|
28
|
+
cliVersion?: string;
|
|
29
|
+
}>;
|
|
30
|
+
/**
|
|
31
|
+
* Run a prompt using Claude Code CLI.
|
|
32
|
+
*/
|
|
33
|
+
run(prompt: string, options?: {
|
|
34
|
+
workingDirectory?: string;
|
|
35
|
+
timeout?: number;
|
|
36
|
+
model?: 'sonnet' | 'opus';
|
|
37
|
+
sessionId?: string;
|
|
38
|
+
}): Promise<ProcessResult>;
|
|
39
|
+
/**
|
|
40
|
+
* Execute prompt with CLI.
|
|
41
|
+
*/
|
|
42
|
+
private executePrompt;
|
|
43
|
+
/**
|
|
44
|
+
* Spawn a Claude CLI process.
|
|
45
|
+
*/
|
|
46
|
+
private spawn;
|
|
47
|
+
/**
|
|
48
|
+
* Detect rate limit errors from CLI output.
|
|
49
|
+
*/
|
|
50
|
+
private isRateLimitError;
|
|
51
|
+
/**
|
|
52
|
+
* Detect auth errors from CLI output.
|
|
53
|
+
*/
|
|
54
|
+
private isAuthError;
|
|
55
|
+
/**
|
|
56
|
+
* Check if error is retryable.
|
|
57
|
+
*/
|
|
58
|
+
private isRetryable;
|
|
59
|
+
/**
|
|
60
|
+
* Categorize error type.
|
|
61
|
+
*/
|
|
62
|
+
private categorizeError;
|
|
63
|
+
/**
|
|
64
|
+
* Get current status.
|
|
65
|
+
*/
|
|
66
|
+
getStatus(): ProcessStatus;
|
|
67
|
+
/**
|
|
68
|
+
* Reset rate limit flag (after user switches accounts).
|
|
69
|
+
*/
|
|
70
|
+
resetRateLimitFlag(): void;
|
|
71
|
+
/**
|
|
72
|
+
* Get metrics.
|
|
73
|
+
*/
|
|
74
|
+
getMetrics(): {
|
|
75
|
+
counters: Record<string, number>;
|
|
76
|
+
gauges: Record<string, number>;
|
|
77
|
+
histograms: Record<string, import("./types.js").MetricStats | null>;
|
|
78
|
+
};
|
|
79
|
+
/**
|
|
80
|
+
* Graceful shutdown.
|
|
81
|
+
*/
|
|
82
|
+
shutdown(): Promise<void>;
|
|
83
|
+
/**
|
|
84
|
+
* Health check.
|
|
85
|
+
*/
|
|
86
|
+
healthCheck(): Promise<{
|
|
87
|
+
healthy: boolean;
|
|
88
|
+
details: Record<string, unknown>;
|
|
89
|
+
}>;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Create a process manager with configuration.
|
|
93
|
+
*/
|
|
94
|
+
export declare function createProcessManager(config: Partial<ProcessManagerConfig> & {
|
|
95
|
+
workingDirectory: string;
|
|
96
|
+
}): ClaudeCodeProcessManager;
|
|
97
|
+
//# sourceMappingURL=process-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"process-manager.d.ts","sourceRoot":"","sources":["../../src/ai-provider/process-manager.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EACV,oBAAoB,EACpB,aAAa,EACb,aAAa,EAEd,MAAM,YAAY,CAAC;AAoCpB;;GAEG;AACH,qBAAa,wBAAwB;IAWvB,OAAO,CAAC,MAAM;IAV1B,OAAO,CAAC,SAAS,CAAY;IAC7B,OAAO,CAAC,cAAc,CAAiB;IACvC,OAAO,CAAC,aAAa,CAAgB;IACrC,OAAO,CAAC,eAAe,CAAwC;IAC/D,OAAO,CAAC,aAAa,CAAkB;IACvC,OAAO,CAAC,gBAAgB,CAAC,CAAS;IAClC,OAAO,CAAC,OAAO,CAAmB;IAClC,OAAO,CAAC,MAAM,CAAkB;IAChC,OAAO,CAAC,cAAc,CAAkB;gBAEpB,MAAM,EAAE,oBAAoB;IAchD;;OAEG;IACG,SAAS,IAAI,OAAO,CAAC;QACzB,aAAa,EAAE,OAAO,CAAC;QACvB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,CAAC;IA0CF;;OAEG;IACG,GAAG,CACP,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE;QAAE,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,QAAQ,GAAG,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,GACvG,OAAO,CAAC,aAAa,CAAC;IAgFzB;;OAEG;YACW,aAAa;IAyE3B;;OAEG;YACW,KAAK;IA2HnB;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAKxB;;OAEG;IACH,OAAO,CAAC,WAAW;IAKnB;;OAEG;IACH,OAAO,CAAC,WAAW;IAMnB;;OAEG;IACH,OAAO,CAAC,eAAe;IAqBvB;;OAEG;IACH,SAAS,IAAI,aAAa;IAS1B;;OAEG;IACH,kBAAkB,IAAI,IAAI;IAM1B;;OAEG;IACH,UAAU;;;;;IAIV;;OAEG;IACG,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAyC/B;;OAEG;IACG,WAAW,IAAI,OAAO,CAAC;QAC3B,OAAO,EAAE,OAAO,CAAC;QACjB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;KAClC,CAAC;CAkBH;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,OAAO,CAAC,oBAAoB,CAAC,GAAG;IAAE,gBAAgB,EAAE,MAAM,CAAA;CAAE,GACnE,wBAAwB,CAS1B"}
|