aisnitch 0.2.18 → 0.2.20
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/cli/index.cjs +398 -14
- package/dist/cli/index.cjs.map +1 -1
- package/dist/cli/index.js +398 -14
- package/dist/cli/index.js.map +1 -1
- package/dist/index.cjs +1002 -24
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1336 -1
- package/dist/index.d.ts +1336 -1
- package/dist/index.js +947 -23
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/cli/index.cjs
CHANGED
|
@@ -41,7 +41,7 @@ var import_commander = require("commander");
|
|
|
41
41
|
|
|
42
42
|
// src/package-info.ts
|
|
43
43
|
var AISNITCH_PACKAGE_NAME = "aisnitch";
|
|
44
|
-
var AISNITCH_VERSION = "0.2.
|
|
44
|
+
var AISNITCH_VERSION = "0.2.20";
|
|
45
45
|
var AISNITCH_DESCRIPTION = "Universal bridge for AI coding tool activity \u2014 capture, normalize, stream.";
|
|
46
46
|
|
|
47
47
|
// src/core/events/schema.ts
|
|
@@ -123,8 +123,8 @@ function createUuidV7() {
|
|
|
123
123
|
return (0, import_uuid.v7)();
|
|
124
124
|
}
|
|
125
125
|
var ToolInputSchema = import_zod.z.strictObject({
|
|
126
|
-
filePath: import_zod.z.string().min(1).optional(),
|
|
127
|
-
command: import_zod.z.string().min(1).optional()
|
|
126
|
+
filePath: import_zod.z.string().min(1).max(4096).optional(),
|
|
127
|
+
command: import_zod.z.string().min(1).max(1e4).optional()
|
|
128
128
|
}).refine(
|
|
129
129
|
(value) => value.filePath !== void 0 || value.command !== void 0,
|
|
130
130
|
"toolInput must include filePath or command"
|
|
@@ -135,35 +135,35 @@ var ErrorTypeSchema = import_zod.z.enum(ERROR_TYPES);
|
|
|
135
135
|
var CESPCategorySchema = import_zod.z.enum(CESP_CATEGORIES);
|
|
136
136
|
var EventDataSchema = import_zod.z.strictObject({
|
|
137
137
|
state: AISnitchEventTypeSchema,
|
|
138
|
-
project: import_zod.z.string().min(1).optional(),
|
|
139
|
-
projectPath: import_zod.z.string().min(1).optional(),
|
|
138
|
+
project: import_zod.z.string().min(1).max(255).optional(),
|
|
139
|
+
projectPath: import_zod.z.string().min(1).max(4096).optional(),
|
|
140
140
|
duration: import_zod.z.number().int().min(0).optional(),
|
|
141
|
-
toolName: import_zod.z.string().min(1).optional(),
|
|
141
|
+
toolName: import_zod.z.string().min(1).max(100).optional(),
|
|
142
142
|
toolInput: ToolInputSchema.optional(),
|
|
143
|
-
activeFile: import_zod.z.string().min(1).optional(),
|
|
144
|
-
model: import_zod.z.string().min(1).optional(),
|
|
143
|
+
activeFile: import_zod.z.string().min(1).max(4096).optional(),
|
|
144
|
+
model: import_zod.z.string().min(1).max(200).optional(),
|
|
145
145
|
tokensUsed: import_zod.z.number().int().min(0).optional(),
|
|
146
|
-
errorMessage: import_zod.z.string().min(1).optional(),
|
|
146
|
+
errorMessage: import_zod.z.string().min(1).max(1e4).optional(),
|
|
147
147
|
errorType: ErrorTypeSchema.optional(),
|
|
148
148
|
raw: import_zod.z.record(import_zod.z.string(), import_zod.z.unknown()).optional(),
|
|
149
|
-
terminal: import_zod.z.string().min(1).optional(),
|
|
150
|
-
cwd: import_zod.z.string().min(1).optional(),
|
|
149
|
+
terminal: import_zod.z.string().min(1).max(100).optional(),
|
|
150
|
+
cwd: import_zod.z.string().min(1).max(4096).optional(),
|
|
151
151
|
pid: import_zod.z.number().int().positive().optional(),
|
|
152
|
-
instanceId: import_zod.z.string().min(1).optional(),
|
|
152
|
+
instanceId: import_zod.z.string().min(1).max(255).optional(),
|
|
153
153
|
instanceIndex: import_zod.z.number().int().min(1).optional(),
|
|
154
154
|
instanceTotal: import_zod.z.number().int().min(1).optional()
|
|
155
155
|
});
|
|
156
156
|
var AISnitchEventSchema = import_zod.z.strictObject({
|
|
157
157
|
specversion: import_zod.z.literal("1.0"),
|
|
158
158
|
id: import_zod.z.string().refine(isUuidV7, "id must be a valid UUIDv7 string"),
|
|
159
|
-
source: import_zod.z.string().refine(
|
|
159
|
+
source: import_zod.z.string().max(2e3).refine(
|
|
160
160
|
isValidUriReference,
|
|
161
161
|
"source must be a valid non-empty CloudEvents URI-reference"
|
|
162
162
|
),
|
|
163
163
|
type: AISnitchEventTypeSchema,
|
|
164
164
|
time: ISO_TIMESTAMP_SCHEMA,
|
|
165
165
|
"aisnitch.tool": ToolNameSchema,
|
|
166
|
-
"aisnitch.sessionid": import_zod.z.string().min(1),
|
|
166
|
+
"aisnitch.sessionid": import_zod.z.string().min(1).max(500),
|
|
167
167
|
"aisnitch.seqnum": import_zod.z.number().int().min(1),
|
|
168
168
|
data: EventDataSchema
|
|
169
169
|
});
|
|
@@ -3351,6 +3351,346 @@ function isPidRunning(pid) {
|
|
|
3351
3351
|
}
|
|
3352
3352
|
}
|
|
3353
3353
|
|
|
3354
|
+
// src/core/errors.ts
|
|
3355
|
+
var AISnitchError = class _AISnitchError extends Error {
|
|
3356
|
+
/**
|
|
3357
|
+
* Machine-readable error code for programmatic handling.
|
|
3358
|
+
* Format: `SUBCATEGORY_SPECIFIC_DETAIL` (uppercase with underscores).
|
|
3359
|
+
*/
|
|
3360
|
+
code;
|
|
3361
|
+
/**
|
|
3362
|
+
* Arbitrary context bag forwarded to the logger for structured debugging.
|
|
3363
|
+
*/
|
|
3364
|
+
context;
|
|
3365
|
+
constructor(message, code, context) {
|
|
3366
|
+
super(message);
|
|
3367
|
+
this.name = "AISnitchError";
|
|
3368
|
+
this.code = code;
|
|
3369
|
+
this.context = context;
|
|
3370
|
+
if (Error.captureStackTrace) {
|
|
3371
|
+
Error.captureStackTrace(this, _AISnitchError);
|
|
3372
|
+
}
|
|
3373
|
+
}
|
|
3374
|
+
/**
|
|
3375
|
+
* Full error chain for logging: `[name] code — message`.
|
|
3376
|
+
*/
|
|
3377
|
+
toString() {
|
|
3378
|
+
return `${this.name} [${this.code}] \u2014 ${this.message}`;
|
|
3379
|
+
}
|
|
3380
|
+
/**
|
|
3381
|
+
* JSON serialization friendly to pino serializers.
|
|
3382
|
+
*/
|
|
3383
|
+
toJSON() {
|
|
3384
|
+
return {
|
|
3385
|
+
name: this.name,
|
|
3386
|
+
code: this.code,
|
|
3387
|
+
message: this.message,
|
|
3388
|
+
context: this.context,
|
|
3389
|
+
stack: this.stack
|
|
3390
|
+
};
|
|
3391
|
+
}
|
|
3392
|
+
};
|
|
3393
|
+
function isAISnitchError(error) {
|
|
3394
|
+
return error instanceof AISnitchError;
|
|
3395
|
+
}
|
|
3396
|
+
function isRetryableError(error) {
|
|
3397
|
+
if (!isAISnitchError(error)) {
|
|
3398
|
+
if (error instanceof Error) {
|
|
3399
|
+
const code = error.code;
|
|
3400
|
+
const retryableCodes = /* @__PURE__ */ new Set([
|
|
3401
|
+
"ECONNREFUSED",
|
|
3402
|
+
"ECONNRESET",
|
|
3403
|
+
"ETIMEDOUT",
|
|
3404
|
+
"ENOTFOUND",
|
|
3405
|
+
"EHOSTUNREACH",
|
|
3406
|
+
"EPIPE",
|
|
3407
|
+
"EPERM"
|
|
3408
|
+
// sometimes transient on macOS file locks
|
|
3409
|
+
]);
|
|
3410
|
+
if (typeof code === "string" && retryableCodes.has(code)) {
|
|
3411
|
+
return true;
|
|
3412
|
+
}
|
|
3413
|
+
}
|
|
3414
|
+
return false;
|
|
3415
|
+
}
|
|
3416
|
+
const retryableCategories = /* @__PURE__ */ new Set(["TIMEOUT", "NETWORK"]);
|
|
3417
|
+
for (const category of retryableCategories) {
|
|
3418
|
+
if (error.code.startsWith(category)) {
|
|
3419
|
+
return true;
|
|
3420
|
+
}
|
|
3421
|
+
}
|
|
3422
|
+
const retryablePatterns = [
|
|
3423
|
+
/^ADAPTER_.*_(FILE_IO|NETWORK|PROCESS_DETECT)_ERROR$/,
|
|
3424
|
+
/^PIPELINE_.*_(RETRY|RECONNECT)_ERROR$/
|
|
3425
|
+
];
|
|
3426
|
+
for (const pattern of retryablePatterns) {
|
|
3427
|
+
if (pattern.test(error.code)) {
|
|
3428
|
+
return true;
|
|
3429
|
+
}
|
|
3430
|
+
}
|
|
3431
|
+
return false;
|
|
3432
|
+
}
|
|
3433
|
+
|
|
3434
|
+
// src/core/circuit-breaker.ts
|
|
3435
|
+
var CircuitOpenError = class _CircuitOpenError extends AISnitchError {
|
|
3436
|
+
constructor(circuitId, state) {
|
|
3437
|
+
super(
|
|
3438
|
+
`Circuit "${circuitId}" is OPEN \u2014 operation rejected`,
|
|
3439
|
+
"CIRCUIT_OPEN",
|
|
3440
|
+
{ circuitId, failures: state.failures, lastFailureAt: state.lastFailureAt }
|
|
3441
|
+
);
|
|
3442
|
+
this.circuitId = circuitId;
|
|
3443
|
+
this.state = state;
|
|
3444
|
+
this.name = "CircuitOpenError";
|
|
3445
|
+
if (Error.captureStackTrace) {
|
|
3446
|
+
Error.captureStackTrace(this, _CircuitOpenError);
|
|
3447
|
+
}
|
|
3448
|
+
}
|
|
3449
|
+
toString() {
|
|
3450
|
+
return `${this.name} [${this.code}] "${this.circuitId}" \u2014 failures=${this.state.failures}`;
|
|
3451
|
+
}
|
|
3452
|
+
};
|
|
3453
|
+
var DEFAULT_OPTIONS = {
|
|
3454
|
+
failureThreshold: 5,
|
|
3455
|
+
halfOpenAfterMs: 3e4,
|
|
3456
|
+
id: "unnamed",
|
|
3457
|
+
resetOnSuccess: true,
|
|
3458
|
+
shouldCountAsFailure: isRetryableError,
|
|
3459
|
+
windowMs: 6e4
|
|
3460
|
+
};
|
|
3461
|
+
var CircuitBreaker = class {
|
|
3462
|
+
failures = 0;
|
|
3463
|
+
lastFailureAt = null;
|
|
3464
|
+
state = "closed";
|
|
3465
|
+
halfOpenTestStartedAt = null;
|
|
3466
|
+
options;
|
|
3467
|
+
constructor(options = {}) {
|
|
3468
|
+
this.options = {
|
|
3469
|
+
...DEFAULT_OPTIONS,
|
|
3470
|
+
...options,
|
|
3471
|
+
// Re-spread to ensure all fields have defaults
|
|
3472
|
+
failureThreshold: options.failureThreshold ?? DEFAULT_OPTIONS.failureThreshold,
|
|
3473
|
+
halfOpenAfterMs: options.halfOpenAfterMs ?? DEFAULT_OPTIONS.halfOpenAfterMs,
|
|
3474
|
+
id: options.id ?? DEFAULT_OPTIONS.id,
|
|
3475
|
+
resetOnSuccess: options.resetOnSuccess ?? DEFAULT_OPTIONS.resetOnSuccess,
|
|
3476
|
+
shouldCountAsFailure: options.shouldCountAsFailure ?? DEFAULT_OPTIONS.shouldCountAsFailure,
|
|
3477
|
+
windowMs: options.windowMs ?? DEFAULT_OPTIONS.windowMs
|
|
3478
|
+
};
|
|
3479
|
+
}
|
|
3480
|
+
/**
|
|
3481
|
+
* Executes an async operation through the circuit breaker.
|
|
3482
|
+
*
|
|
3483
|
+
* - If the circuit is CLOSED → runs `fn` and updates state based on result
|
|
3484
|
+
* - If the circuit is HALF-OPEN → runs `fn` once to test recovery
|
|
3485
|
+
* - If the circuit is OPEN → throws `CircuitOpenError` immediately (no call)
|
|
3486
|
+
*
|
|
3487
|
+
* @param fn - The async operation to protect
|
|
3488
|
+
* @returns The result of `fn` if successful
|
|
3489
|
+
* @throws CircuitOpenError if the circuit is OPEN
|
|
3490
|
+
* @throws The error from `fn` if it throws (and `shouldCountAsFailure` returns true)
|
|
3491
|
+
*/
|
|
3492
|
+
async execute(fn) {
|
|
3493
|
+
switch (this.state) {
|
|
3494
|
+
case "closed":
|
|
3495
|
+
return this.executeClosed(fn);
|
|
3496
|
+
case "half-open":
|
|
3497
|
+
return this.executeHalfOpen(fn);
|
|
3498
|
+
case "open":
|
|
3499
|
+
if (this.shouldTransitionToHalfOpen()) {
|
|
3500
|
+
this.transitionToHalfOpen();
|
|
3501
|
+
return this.executeHalfOpen(fn);
|
|
3502
|
+
}
|
|
3503
|
+
throw new CircuitOpenError(this.options.id, this.getState());
|
|
3504
|
+
}
|
|
3505
|
+
}
|
|
3506
|
+
/**
|
|
3507
|
+
* Returns the current observable circuit state.
|
|
3508
|
+
*/
|
|
3509
|
+
getState() {
|
|
3510
|
+
return {
|
|
3511
|
+
failures: this.failures,
|
|
3512
|
+
lastFailureAt: this.lastFailureAt,
|
|
3513
|
+
state: this.state
|
|
3514
|
+
};
|
|
3515
|
+
}
|
|
3516
|
+
/**
|
|
3517
|
+
* Forces the circuit to CLOSED (resets failure count and state).
|
|
3518
|
+
* Useful for manual recovery after a known-fix or after a maintenance window.
|
|
3519
|
+
*/
|
|
3520
|
+
reset() {
|
|
3521
|
+
this.failures = 0;
|
|
3522
|
+
this.lastFailureAt = null;
|
|
3523
|
+
this.state = "closed";
|
|
3524
|
+
this.halfOpenTestStartedAt = null;
|
|
3525
|
+
logger.debug({ circuitId: this.options.id }, "Circuit breaker manually reset");
|
|
3526
|
+
}
|
|
3527
|
+
/**
|
|
3528
|
+
* Pre-warms the circuit by performing one test call in HALF-OPEN state.
|
|
3529
|
+
* If the circuit is already HALF-OPEN, this does nothing.
|
|
3530
|
+
* If the circuit is CLOSED, this does nothing.
|
|
3531
|
+
*/
|
|
3532
|
+
async preWarm(fn) {
|
|
3533
|
+
if (this.state !== "open") {
|
|
3534
|
+
return;
|
|
3535
|
+
}
|
|
3536
|
+
this.transitionToHalfOpen();
|
|
3537
|
+
try {
|
|
3538
|
+
await fn();
|
|
3539
|
+
this.transitionToClosed();
|
|
3540
|
+
} catch {
|
|
3541
|
+
this.transitionToOpen();
|
|
3542
|
+
}
|
|
3543
|
+
}
|
|
3544
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
3545
|
+
// Private methods
|
|
3546
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
3547
|
+
async executeClosed(fn) {
|
|
3548
|
+
try {
|
|
3549
|
+
const result = await fn();
|
|
3550
|
+
this.onSuccess();
|
|
3551
|
+
return result;
|
|
3552
|
+
} catch (error) {
|
|
3553
|
+
this.onFailure(error);
|
|
3554
|
+
throw error;
|
|
3555
|
+
}
|
|
3556
|
+
}
|
|
3557
|
+
async executeHalfOpen(fn) {
|
|
3558
|
+
this.halfOpenTestStartedAt = Date.now();
|
|
3559
|
+
try {
|
|
3560
|
+
const result = await fn();
|
|
3561
|
+
this.transitionToClosed();
|
|
3562
|
+
return result;
|
|
3563
|
+
} catch (error) {
|
|
3564
|
+
this.transitionToOpen();
|
|
3565
|
+
throw error;
|
|
3566
|
+
}
|
|
3567
|
+
}
|
|
3568
|
+
onSuccess() {
|
|
3569
|
+
if (this.options.resetOnSuccess) {
|
|
3570
|
+
this.failures = 0;
|
|
3571
|
+
this.lastFailureAt = null;
|
|
3572
|
+
} else {
|
|
3573
|
+
this.failures = Math.max(0, this.failures - 1);
|
|
3574
|
+
if (this.failures === 0) {
|
|
3575
|
+
this.lastFailureAt = null;
|
|
3576
|
+
}
|
|
3577
|
+
}
|
|
3578
|
+
logger.debug(
|
|
3579
|
+
{
|
|
3580
|
+
circuitId: this.options.id,
|
|
3581
|
+
failures: this.failures
|
|
3582
|
+
},
|
|
3583
|
+
"Circuit breaker operation succeeded"
|
|
3584
|
+
);
|
|
3585
|
+
}
|
|
3586
|
+
onFailure(error) {
|
|
3587
|
+
if (!this.options.shouldCountAsFailure(error)) {
|
|
3588
|
+
logger.debug(
|
|
3589
|
+
{ circuitId: this.options.id, error },
|
|
3590
|
+
"Circuit breaker operation failed but error is not counted as failure"
|
|
3591
|
+
);
|
|
3592
|
+
return;
|
|
3593
|
+
}
|
|
3594
|
+
this.failures += 1;
|
|
3595
|
+
this.lastFailureAt = Date.now();
|
|
3596
|
+
if (this.failures >= this.options.failureThreshold) {
|
|
3597
|
+
this.transitionToOpen();
|
|
3598
|
+
} else {
|
|
3599
|
+
logger.debug(
|
|
3600
|
+
{
|
|
3601
|
+
circuitId: this.options.id,
|
|
3602
|
+
failures: this.failures,
|
|
3603
|
+
threshold: this.options.failureThreshold
|
|
3604
|
+
},
|
|
3605
|
+
"Circuit breaker recorded failure"
|
|
3606
|
+
);
|
|
3607
|
+
}
|
|
3608
|
+
}
|
|
3609
|
+
transitionToOpen() {
|
|
3610
|
+
if (this.state === "open") {
|
|
3611
|
+
return;
|
|
3612
|
+
}
|
|
3613
|
+
this.state = "open";
|
|
3614
|
+
this.halfOpenTestStartedAt = null;
|
|
3615
|
+
logger.warn(
|
|
3616
|
+
{
|
|
3617
|
+
circuitId: this.options.id,
|
|
3618
|
+
failures: this.failures,
|
|
3619
|
+
windowMs: this.options.windowMs
|
|
3620
|
+
},
|
|
3621
|
+
"\u{1F534} Circuit breaker OPEN \u2014 blocking operations"
|
|
3622
|
+
);
|
|
3623
|
+
}
|
|
3624
|
+
transitionToHalfOpen() {
|
|
3625
|
+
this.state = "half-open";
|
|
3626
|
+
this.halfOpenTestStartedAt = Date.now();
|
|
3627
|
+
logger.info(
|
|
3628
|
+
{ circuitId: this.options.id },
|
|
3629
|
+
"\u{1F7E1} Circuit breaker HALF-OPEN \u2014 testing recovery"
|
|
3630
|
+
);
|
|
3631
|
+
}
|
|
3632
|
+
transitionToClosed() {
|
|
3633
|
+
this.state = "closed";
|
|
3634
|
+
this.failures = 0;
|
|
3635
|
+
this.lastFailureAt = null;
|
|
3636
|
+
this.halfOpenTestStartedAt = null;
|
|
3637
|
+
logger.info(
|
|
3638
|
+
{ circuitId: this.options.id },
|
|
3639
|
+
"\u{1F7E2} Circuit breaker CLOSED \u2014 recovery successful"
|
|
3640
|
+
);
|
|
3641
|
+
}
|
|
3642
|
+
shouldTransitionToHalfOpen() {
|
|
3643
|
+
if (this.lastFailureAt === null) {
|
|
3644
|
+
return true;
|
|
3645
|
+
}
|
|
3646
|
+
const elapsed = Date.now() - this.lastFailureAt;
|
|
3647
|
+
return elapsed >= this.options.halfOpenAfterMs;
|
|
3648
|
+
}
|
|
3649
|
+
};
|
|
3650
|
+
var SHARED_BREAKERS = Object.freeze({
|
|
3651
|
+
/**
|
|
3652
|
+
* Breaker for adapter event emission.
|
|
3653
|
+
* Threshold: 5 failures in 60s → open for 30s → half-open test.
|
|
3654
|
+
*/
|
|
3655
|
+
adapterEmit: new CircuitBreaker({
|
|
3656
|
+
id: "adapter.emit",
|
|
3657
|
+
failureThreshold: 5,
|
|
3658
|
+
halfOpenAfterMs: 3e4,
|
|
3659
|
+
shouldCountAsFailure: isRetryableError,
|
|
3660
|
+
windowMs: 6e4
|
|
3661
|
+
}),
|
|
3662
|
+
/**
|
|
3663
|
+
* Breaker for file system operations (transcript reading, config loading).
|
|
3664
|
+
* More tolerant: 10 failures in 60s → open for 30s.
|
|
3665
|
+
*/
|
|
3666
|
+
fileSystem: new CircuitBreaker({
|
|
3667
|
+
id: "filesystem",
|
|
3668
|
+
failureThreshold: 10,
|
|
3669
|
+
halfOpenAfterMs: 3e4,
|
|
3670
|
+
windowMs: 6e4
|
|
3671
|
+
}),
|
|
3672
|
+
/**
|
|
3673
|
+
* Breaker for HTTP/HTTPS requests.
|
|
3674
|
+
* Stricter: 3 failures in 30s → open for 15s.
|
|
3675
|
+
*/
|
|
3676
|
+
httpRequest: new CircuitBreaker({
|
|
3677
|
+
id: "http-request",
|
|
3678
|
+
failureThreshold: 3,
|
|
3679
|
+
halfOpenAfterMs: 15e3,
|
|
3680
|
+
windowMs: 3e4
|
|
3681
|
+
}),
|
|
3682
|
+
/**
|
|
3683
|
+
* Breaker for process detection operations.
|
|
3684
|
+
* Most tolerant: 20 failures in 60s → open for 10s.
|
|
3685
|
+
*/
|
|
3686
|
+
processDetection: new CircuitBreaker({
|
|
3687
|
+
id: "process-detection",
|
|
3688
|
+
failureThreshold: 20,
|
|
3689
|
+
halfOpenAfterMs: 1e4,
|
|
3690
|
+
windowMs: 6e4
|
|
3691
|
+
})
|
|
3692
|
+
});
|
|
3693
|
+
|
|
3354
3694
|
// src/core/engine/event-bus.ts
|
|
3355
3695
|
var import_eventemitter3 = require("eventemitter3");
|
|
3356
3696
|
var EventBus = class {
|
|
@@ -11116,6 +11456,50 @@ var Pipeline = class {
|
|
|
11116
11456
|
}
|
|
11117
11457
|
};
|
|
11118
11458
|
|
|
11459
|
+
// src/core/timeout.ts
|
|
11460
|
+
var DEFAULT_TIMEOUTS = Object.freeze({
|
|
11461
|
+
/**
|
|
11462
|
+
* File read/write operations (JSONL transcripts, config files).
|
|
11463
|
+
* Default: 5 seconds
|
|
11464
|
+
*/
|
|
11465
|
+
fileOperation: 5e3,
|
|
11466
|
+
/**
|
|
11467
|
+
* HTTP requests to health endpoint or external APIs.
|
|
11468
|
+
* Default: 30 seconds
|
|
11469
|
+
*/
|
|
11470
|
+
httpRequest: 3e4,
|
|
11471
|
+
/**
|
|
11472
|
+
* Process detection commands (`pgrep`, `ps aux`).
|
|
11473
|
+
* Default: 3 seconds
|
|
11474
|
+
*/
|
|
11475
|
+
processDetection: 3e3,
|
|
11476
|
+
/**
|
|
11477
|
+
* Adapter startup (file watchers, hook bridges, pollers).
|
|
11478
|
+
* Default: 10 seconds
|
|
11479
|
+
*/
|
|
11480
|
+
adapterStartup: 1e4,
|
|
11481
|
+
/**
|
|
11482
|
+
* Adapter shutdown (graceful cleanup, watcher close).
|
|
11483
|
+
* Default: 5 seconds — after this, resources are force-closed
|
|
11484
|
+
*/
|
|
11485
|
+
adapterShutdown: 5e3,
|
|
11486
|
+
/**
|
|
11487
|
+
* Daemon graceful shutdown (stop all components in order).
|
|
11488
|
+
* Default: 30 seconds
|
|
11489
|
+
*/
|
|
11490
|
+
daemonShutdown: 3e4,
|
|
11491
|
+
/**
|
|
11492
|
+
* WebSocket connection establishment.
|
|
11493
|
+
* Default: 10 seconds
|
|
11494
|
+
*/
|
|
11495
|
+
wsConnection: 1e4,
|
|
11496
|
+
/**
|
|
11497
|
+
* Overall pipeline start (all components).
|
|
11498
|
+
* Default: 15 seconds
|
|
11499
|
+
*/
|
|
11500
|
+
pipelineStartup: 15e3
|
|
11501
|
+
});
|
|
11502
|
+
|
|
11119
11503
|
// src/tui/index.tsx
|
|
11120
11504
|
var import_ink13 = require("ink");
|
|
11121
11505
|
var import_fullscreen_ink = require("fullscreen-ink");
|