@karmaniverous/jeeves-watcher 0.18.9 → 0.18.10
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
CHANGED
|
@@ -29,7 +29,7 @@ Add a `vcs` block to your config:
|
|
|
29
29
|
{
|
|
30
30
|
"vcs": {
|
|
31
31
|
"enabled": true,
|
|
32
|
-
"
|
|
32
|
+
"commitThrottleMs": 30000,
|
|
33
33
|
"maxBatchSize": 1000,
|
|
34
34
|
"commitMessage": {
|
|
35
35
|
"enabled": true,
|
|
@@ -50,7 +50,7 @@ Add a `vcs` block to your config:
|
|
|
50
50
|
| Property | Default | Description |
|
|
51
51
|
|----------|---------|-------------|
|
|
52
52
|
| `vcs.enabled` | `false` | Enable git-backed version control globally |
|
|
53
|
-
| `vcs.
|
|
53
|
+
| `vcs.commitThrottleMs` | `30000` | Throttle interval (ms) for batching file changes into commits. Min: 1000 |
|
|
54
54
|
| `vcs.maxBatchSize` | `1000` | Maximum files per commit batch. Flushes immediately when exceeded. Min: 1 |
|
|
55
55
|
| `vcs.commitMessage.enabled` | `true` | Enable AI-generated commit messages |
|
|
56
56
|
| `vcs.commitMessage.provider` | `"anthropic"` | AI provider (currently only `"anthropic"` supported) |
|
package/config.schema.json
CHANGED
|
@@ -338,7 +338,7 @@
|
|
|
338
338
|
}
|
|
339
339
|
]
|
|
340
340
|
},
|
|
341
|
-
"
|
|
341
|
+
"commitThrottleMs": {
|
|
342
342
|
"allOf": [
|
|
343
343
|
{
|
|
344
344
|
"$ref": "#/definitions/__schema14"
|
|
@@ -458,7 +458,7 @@
|
|
|
458
458
|
},
|
|
459
459
|
"__schema14": {
|
|
460
460
|
"default": 30000,
|
|
461
|
-
"description": "
|
|
461
|
+
"description": "Throttle interval in milliseconds for batching commits. Default: 30000.",
|
|
462
462
|
"allOf": [
|
|
463
463
|
{
|
|
464
464
|
"$ref": "#/definitions/__schema15"
|
|
@@ -1487,7 +1487,7 @@
|
|
|
1487
1487
|
"author": {
|
|
1488
1488
|
"$ref": "#/definitions/__schema10"
|
|
1489
1489
|
},
|
|
1490
|
-
"
|
|
1490
|
+
"commitThrottleMs": {
|
|
1491
1491
|
"$ref": "#/definitions/__schema14"
|
|
1492
1492
|
},
|
|
1493
1493
|
"maxBatchSize": {
|
|
@@ -10,7 +10,7 @@ import Ajv from 'ajv';
|
|
|
10
10
|
import addFormats from 'ajv-formats';
|
|
11
11
|
import picomatch from 'picomatch';
|
|
12
12
|
import { deserialize, serialize } from 'node:v8';
|
|
13
|
-
import { normalizeWatchPaths, vcsRetentionConfigSchema, extractWatchPathStrings, vcsAuthorConfigSchema, inferenceRuleSchema, jeevesWatcherConfigSchema } from '@karmaniverous/jeeves-watcher-core';
|
|
13
|
+
import { normalizeWatchPaths, vcsRetentionConfigSchema, extractWatchPathStrings, vcsAuthorConfigSchema, inferenceRuleSchema, jeevesWatcherConfigSchema, getEndpoint } from '@karmaniverous/jeeves-watcher-core';
|
|
14
14
|
import { homedir } from 'node:os';
|
|
15
15
|
import { access, rm, stat, readFile, writeFile, appendFile, mkdir } from 'node:fs/promises';
|
|
16
16
|
import { pathToFileURL, fileURLToPath } from 'node:url';
|
|
@@ -1389,7 +1389,7 @@ async function pushToRemote(rootPath, remoteUrl, accessToken, pushErrors, logger
|
|
|
1389
1389
|
* Per-root VCS manager for git-backed content versioning.
|
|
1390
1390
|
*
|
|
1391
1391
|
* Each VCS-enabled watch root gets its own VcsManager instance, which owns
|
|
1392
|
-
* a
|
|
1392
|
+
* a throttled commit pipeline: file changes are batched, staged, committed
|
|
1393
1393
|
* (with optional AI-generated messages), and optionally pushed to a remote.
|
|
1394
1394
|
*
|
|
1395
1395
|
* Concurrency: only one commit is in-flight at a time per root. Index.lock
|
|
@@ -1406,7 +1406,7 @@ class VcsManager {
|
|
|
1406
1406
|
pendingReversions = [];
|
|
1407
1407
|
_pushErrors = [];
|
|
1408
1408
|
squashManager;
|
|
1409
|
-
|
|
1409
|
+
throttleTimer;
|
|
1410
1410
|
commitInFlight = Promise.resolve();
|
|
1411
1411
|
consecutiveCommitFailures = 0;
|
|
1412
1412
|
started = false;
|
|
@@ -1449,7 +1449,7 @@ class VcsManager {
|
|
|
1449
1449
|
this.isBaseline = false;
|
|
1450
1450
|
}
|
|
1451
1451
|
/**
|
|
1452
|
-
* Add a file to the pending set and
|
|
1452
|
+
* Add a file to the pending set and start the throttle timer.
|
|
1453
1453
|
* If the pending set exceeds maxBatchSize, flush immediately.
|
|
1454
1454
|
*
|
|
1455
1455
|
* @param filePath - Absolute path of the changed file.
|
|
@@ -1464,15 +1464,15 @@ class VcsManager {
|
|
|
1464
1464
|
}
|
|
1465
1465
|
this.pending.add(filePath);
|
|
1466
1466
|
if (this.pending.size >= this.config.maxBatchSize) {
|
|
1467
|
-
this.
|
|
1467
|
+
this.clearThrottle();
|
|
1468
1468
|
const batch = this.takeBatch(this.config.maxBatchSize);
|
|
1469
1469
|
this.commitInFlight = this.commitInFlight.then(() => this.commitBatch(batch));
|
|
1470
1470
|
if (this.pending.size > 0) {
|
|
1471
|
-
this.
|
|
1471
|
+
this.resetThrottle();
|
|
1472
1472
|
}
|
|
1473
1473
|
return;
|
|
1474
1474
|
}
|
|
1475
|
-
this.
|
|
1475
|
+
this.resetThrottle();
|
|
1476
1476
|
}
|
|
1477
1477
|
/**
|
|
1478
1478
|
* Record reversion metadata so the next commit uses a revert-prefixed message.
|
|
@@ -1497,7 +1497,7 @@ class VcsManager {
|
|
|
1497
1497
|
* Flush all pending files immediately.
|
|
1498
1498
|
*/
|
|
1499
1499
|
async flush() {
|
|
1500
|
-
this.
|
|
1500
|
+
this.clearThrottle();
|
|
1501
1501
|
if (this.pending.size > 0) {
|
|
1502
1502
|
const batch = [...this.pending];
|
|
1503
1503
|
this.pending.clear();
|
|
@@ -1530,23 +1530,25 @@ class VcsManager {
|
|
|
1530
1530
|
return batch;
|
|
1531
1531
|
}
|
|
1532
1532
|
/**
|
|
1533
|
-
* Clear the
|
|
1533
|
+
* Clear the throttle timer.
|
|
1534
1534
|
*/
|
|
1535
|
-
|
|
1536
|
-
if (this.
|
|
1537
|
-
clearTimeout(this.
|
|
1538
|
-
this.
|
|
1535
|
+
clearThrottle() {
|
|
1536
|
+
if (this.throttleTimer !== undefined) {
|
|
1537
|
+
clearTimeout(this.throttleTimer);
|
|
1538
|
+
this.throttleTimer = undefined;
|
|
1539
1539
|
}
|
|
1540
1540
|
}
|
|
1541
1541
|
/**
|
|
1542
|
-
*
|
|
1542
|
+
* Start the throttle timer to fire flush() after commitThrottleMs.
|
|
1543
|
+
* If a timer is already running, do not reset it — this is throttle, not debounce.
|
|
1543
1544
|
*/
|
|
1544
|
-
|
|
1545
|
-
this.
|
|
1546
|
-
|
|
1547
|
-
|
|
1545
|
+
resetThrottle() {
|
|
1546
|
+
if (this.throttleTimer !== undefined)
|
|
1547
|
+
return;
|
|
1548
|
+
this.throttleTimer = setTimeout(() => {
|
|
1549
|
+
this.throttleTimer = undefined;
|
|
1548
1550
|
void this.flush();
|
|
1549
|
-
}, this.config.
|
|
1551
|
+
}, this.config.commitThrottleMs);
|
|
1550
1552
|
}
|
|
1551
1553
|
/**
|
|
1552
1554
|
* Check for and remove stale index.lock files before retrying.
|
|
@@ -1717,8 +1719,8 @@ class VcsCoordinator {
|
|
|
1717
1719
|
/**
|
|
1718
1720
|
* Signal that the initial filesystem scan is complete.
|
|
1719
1721
|
*
|
|
1720
|
-
* Flushes each manager's
|
|
1721
|
-
* any files still pending in the VCS
|
|
1722
|
+
* Flushes each manager's throttle buffer before ending baseline mode, ensuring
|
|
1723
|
+
* any files still pending in the VCS throttle are committed with a
|
|
1722
1724
|
* `"baseline:"` prefix rather than `"watcher:"`. AI generation is not enabled
|
|
1723
1725
|
* until all managers have completed their flush.
|
|
1724
1726
|
*/
|
|
@@ -5412,36 +5414,36 @@ function createApiServer(options) {
|
|
|
5412
5414
|
};
|
|
5413
5415
|
},
|
|
5414
5416
|
});
|
|
5415
|
-
app.get('
|
|
5417
|
+
app.get(getEndpoint('status').path, withCache(cacheTtlMs, async () => {
|
|
5416
5418
|
const result = await coreStatusHandler();
|
|
5417
5419
|
return result.body;
|
|
5418
5420
|
}));
|
|
5419
|
-
app.post('
|
|
5421
|
+
app.post(getEndpoint('metadata').path, createMetadataHandler({
|
|
5420
5422
|
processor,
|
|
5421
5423
|
getConfig,
|
|
5422
5424
|
logger,
|
|
5423
5425
|
configDir: dirname(configPath),
|
|
5424
5426
|
}));
|
|
5425
|
-
app.post('
|
|
5427
|
+
app.post(getEndpoint('render').path, withCache(cacheTtlMs, createRenderHandler({
|
|
5426
5428
|
processor,
|
|
5427
5429
|
getWatch: () => getConfig().watch,
|
|
5428
5430
|
logger,
|
|
5429
5431
|
})));
|
|
5430
|
-
app.get('
|
|
5432
|
+
app.get(getEndpoint('searchFacets').path, createFacetsHandler({
|
|
5431
5433
|
getConfig,
|
|
5432
5434
|
valuesManager,
|
|
5433
5435
|
configDir: dirname(configPath),
|
|
5434
5436
|
}));
|
|
5435
|
-
app.post('
|
|
5437
|
+
app.post(getEndpoint('scan').path, createScanHandler({
|
|
5436
5438
|
vectorStore,
|
|
5437
5439
|
logger,
|
|
5438
5440
|
}));
|
|
5439
|
-
app.post('
|
|
5441
|
+
app.post(getEndpoint('walk').path, createWalkHandler({
|
|
5440
5442
|
getWatchPaths: () => extractWatchPathStrings(getConfig().watch.paths),
|
|
5441
5443
|
getFileSystemWatcher,
|
|
5442
5444
|
logger,
|
|
5443
5445
|
}));
|
|
5444
|
-
app.post('
|
|
5446
|
+
app.post(getEndpoint('search').path, createSearchHandler({
|
|
5445
5447
|
embeddingProvider,
|
|
5446
5448
|
vectorStore,
|
|
5447
5449
|
logger,
|
|
@@ -5452,12 +5454,12 @@ function createApiServer(options) {
|
|
|
5452
5454
|
: undefined;
|
|
5453
5455
|
},
|
|
5454
5456
|
}));
|
|
5455
|
-
app.post('
|
|
5457
|
+
app.post(getEndpoint('rebuildMetadata').path, createRebuildMetadataHandler({
|
|
5456
5458
|
enrichmentStore: options.enrichmentStore,
|
|
5457
5459
|
vectorStore,
|
|
5458
5460
|
logger,
|
|
5459
5461
|
}));
|
|
5460
|
-
app.post('
|
|
5462
|
+
app.post(getEndpoint('reindex').path, createConfigReindexHandler({
|
|
5461
5463
|
getConfig,
|
|
5462
5464
|
processor,
|
|
5463
5465
|
logger,
|
|
@@ -5468,10 +5470,10 @@ function createApiServer(options) {
|
|
|
5468
5470
|
vectorStore,
|
|
5469
5471
|
queue,
|
|
5470
5472
|
}));
|
|
5471
|
-
app.get('
|
|
5472
|
-
app.get('
|
|
5473
|
-
app.post('
|
|
5474
|
-
app.get('
|
|
5473
|
+
app.get(getEndpoint('issues').path, withCache(cacheTtlMs, createIssuesHandler({ issuesManager })));
|
|
5474
|
+
app.get(getEndpoint('configSchema').path, withCache(cacheTtlMs, createConfigSchemaHandler()));
|
|
5475
|
+
app.post(getEndpoint('configMatch').path, createConfigMatchHandler({ getConfig, logger }));
|
|
5476
|
+
app.get(getEndpoint('config').path, withCache(cacheTtlMs, createConfigQueryHandler({
|
|
5475
5477
|
getConfig,
|
|
5476
5478
|
valuesManager,
|
|
5477
5479
|
issuesManager,
|
|
@@ -5481,7 +5483,7 @@ function createApiServer(options) {
|
|
|
5481
5483
|
? () => virtualRuleStore.getAll()
|
|
5482
5484
|
: undefined,
|
|
5483
5485
|
})));
|
|
5484
|
-
app.post('
|
|
5486
|
+
app.post(getEndpoint('configValidate').path, createConfigValidateHandler({
|
|
5485
5487
|
getConfig,
|
|
5486
5488
|
logger,
|
|
5487
5489
|
configDir: dirname(configPath),
|
|
@@ -5495,7 +5497,7 @@ function createApiServer(options) {
|
|
|
5495
5497
|
return Promise.resolve();
|
|
5496
5498
|
},
|
|
5497
5499
|
});
|
|
5498
|
-
app.post('
|
|
5500
|
+
app.post(getEndpoint('configApply').path, async (request, reply) => {
|
|
5499
5501
|
const { patch, replace } = request.body;
|
|
5500
5502
|
const result = await coreConfigApplyHandler({ patch, replace });
|
|
5501
5503
|
return reply.status(result.status).send(result.body);
|
|
@@ -5514,34 +5516,34 @@ function createApiServer(options) {
|
|
|
5514
5516
|
gitignoreFilter,
|
|
5515
5517
|
vectorStore,
|
|
5516
5518
|
});
|
|
5517
|
-
app.post('
|
|
5519
|
+
app.post(getEndpoint('rulesRegister').path, createRulesRegisterHandler({
|
|
5518
5520
|
virtualRuleStore,
|
|
5519
5521
|
logger,
|
|
5520
5522
|
onRulesChanged,
|
|
5521
5523
|
}));
|
|
5522
|
-
app.delete('
|
|
5524
|
+
app.delete(getEndpoint('rulesUnregister').path, createRulesUnregisterHandler({
|
|
5523
5525
|
virtualRuleStore,
|
|
5524
5526
|
logger,
|
|
5525
5527
|
onRulesChanged,
|
|
5526
5528
|
}));
|
|
5527
|
-
app.delete('
|
|
5529
|
+
app.delete(getEndpoint('rulesUnregisterBySource').path, createRulesUnregisterParamHandler({
|
|
5528
5530
|
virtualRuleStore,
|
|
5529
5531
|
logger,
|
|
5530
5532
|
onRulesChanged,
|
|
5531
5533
|
}));
|
|
5532
|
-
app.post('
|
|
5533
|
-
app.post('
|
|
5534
|
+
app.post(getEndpoint('pointsDelete').path, createPointsDeleteHandler({ vectorStore, logger }));
|
|
5535
|
+
app.post(getEndpoint('rulesReapply').path, createRulesReapplyHandler({ processor, vectorStore, logger }));
|
|
5534
5536
|
}
|
|
5535
5537
|
// VCS routes — only registered when a VcsCoordinator is provided
|
|
5536
5538
|
if (options.vcsCoordinator) {
|
|
5537
5539
|
const coordinator = options.vcsCoordinator;
|
|
5538
|
-
app.get('
|
|
5539
|
-
app.get('
|
|
5540
|
-
app.get('
|
|
5541
|
-
app.get('
|
|
5542
|
-
app.get('
|
|
5543
|
-
app.post('
|
|
5544
|
-
app.post('
|
|
5540
|
+
app.get(getEndpoint('vcsStatus').path, createVcsStatusHandler({ coordinator, logger }));
|
|
5541
|
+
app.get(getEndpoint('vcsHistory').path, createVcsHistoryHandler({ coordinator, logger }));
|
|
5542
|
+
app.get(getEndpoint('vcsShow').path, createVcsShowHandler({ coordinator, logger }));
|
|
5543
|
+
app.get(getEndpoint('vcsDiff').path, createVcsDiffHandler({ coordinator, logger }));
|
|
5544
|
+
app.get(getEndpoint('vcsCheckExclusion').path, createVcsCheckExclusionHandler({ coordinator, logger }));
|
|
5545
|
+
app.post(getEndpoint('vcsRevert').path, createVcsRevertHandler({ coordinator, logger }));
|
|
5546
|
+
app.post(getEndpoint('vcsExclude').path, createVcsExcludeHandler({ coordinator, logger }));
|
|
5545
5547
|
}
|
|
5546
5548
|
return app;
|
|
5547
5549
|
}
|
|
@@ -226,7 +226,7 @@ async function startFromConfig(configPath, descriptor) {
|
|
|
226
226
|
const config = await loadConfig(resolvedPath);
|
|
227
227
|
// Dynamic import breaks the circular dependency between this module
|
|
228
228
|
// and app/index.ts (which defines JeevesWatcher and re-exports startFromConfig).
|
|
229
|
-
const { JeevesWatcher } = await import('./index-
|
|
229
|
+
const { JeevesWatcher } = await import('./index-B_g6RfR8.js');
|
|
230
230
|
const app = new JeevesWatcher(config, resolvedPath, descriptor);
|
|
231
231
|
installShutdownHandlers(() => app.stop());
|
|
232
232
|
await app.start();
|
package/dist/index.d.ts
CHANGED
|
@@ -1276,7 +1276,7 @@ interface PushError {
|
|
|
1276
1276
|
* Per-root VCS manager for git-backed content versioning.
|
|
1277
1277
|
*
|
|
1278
1278
|
* Each VCS-enabled watch root gets its own VcsManager instance, which owns
|
|
1279
|
-
* a
|
|
1279
|
+
* a throttled commit pipeline: file changes are batched, staged, committed
|
|
1280
1280
|
* (with optional AI-generated messages), and optionally pushed to a remote.
|
|
1281
1281
|
*
|
|
1282
1282
|
* Concurrency: only one commit is in-flight at a time per root. Index.lock
|
|
@@ -1293,7 +1293,7 @@ declare class VcsManager {
|
|
|
1293
1293
|
private readonly pendingReversions;
|
|
1294
1294
|
private readonly _pushErrors;
|
|
1295
1295
|
private readonly squashManager;
|
|
1296
|
-
private
|
|
1296
|
+
private throttleTimer;
|
|
1297
1297
|
private commitInFlight;
|
|
1298
1298
|
private consecutiveCommitFailures;
|
|
1299
1299
|
private started;
|
|
@@ -1316,7 +1316,7 @@ declare class VcsManager {
|
|
|
1316
1316
|
*/
|
|
1317
1317
|
endBaseline(): void;
|
|
1318
1318
|
/**
|
|
1319
|
-
* Add a file to the pending set and
|
|
1319
|
+
* Add a file to the pending set and start the throttle timer.
|
|
1320
1320
|
* If the pending set exceeds maxBatchSize, flush immediately.
|
|
1321
1321
|
*
|
|
1322
1322
|
* @param filePath - Absolute path of the changed file.
|
|
@@ -1348,13 +1348,14 @@ declare class VcsManager {
|
|
|
1348
1348
|
*/
|
|
1349
1349
|
private takeBatch;
|
|
1350
1350
|
/**
|
|
1351
|
-
* Clear the
|
|
1351
|
+
* Clear the throttle timer.
|
|
1352
1352
|
*/
|
|
1353
|
-
private
|
|
1353
|
+
private clearThrottle;
|
|
1354
1354
|
/**
|
|
1355
|
-
*
|
|
1355
|
+
* Start the throttle timer to fire flush() after commitThrottleMs.
|
|
1356
|
+
* If a timer is already running, do not reset it — this is throttle, not debounce.
|
|
1356
1357
|
*/
|
|
1357
|
-
private
|
|
1358
|
+
private resetThrottle;
|
|
1358
1359
|
/**
|
|
1359
1360
|
* Check for and remove stale index.lock files before retrying.
|
|
1360
1361
|
*/
|
|
@@ -1394,8 +1395,8 @@ declare class VcsCoordinator {
|
|
|
1394
1395
|
/**
|
|
1395
1396
|
* Signal that the initial filesystem scan is complete.
|
|
1396
1397
|
*
|
|
1397
|
-
* Flushes each manager's
|
|
1398
|
-
* any files still pending in the VCS
|
|
1398
|
+
* Flushes each manager's throttle buffer before ending baseline mode, ensuring
|
|
1399
|
+
* any files still pending in the VCS throttle are committed with a
|
|
1399
1400
|
* `"baseline:"` prefix rather than `"watcher:"`. AI generation is not enabled
|
|
1400
1401
|
* until all managers have completed their flush.
|
|
1401
1402
|
*/
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { join, dirname, resolve, relative, extname, basename, isAbsolute, sep } from 'node:path';
|
|
2
2
|
import { createConfigQueryHandler as createConfigQueryHandler$1, createStatusHandler, createConfigApplyHandler, substituteEnvVars, DEFAULT_PORTS, getBindAddress, postJson, fetchJson, getPackageVersion } from '@karmaniverous/jeeves';
|
|
3
|
-
import { extractWatchPathStrings, inferenceRuleSchema, jeevesWatcherConfigSchema, normalizeWatchPaths, vcsRetentionConfigSchema, vcsAuthorConfigSchema, LOGGING_DEFAULTS, API_DEFAULTS, EMBEDDING_DEFAULTS, CONFIG_WATCH_DEFAULTS, WATCH_DEFAULTS, ROOT_DEFAULTS, INIT_CONFIG_TEMPLATE, DEFAULT_PORT as DEFAULT_PORT$1, PLUGIN_PACKAGE, SERVICE_PACKAGE, COMPONENT_NAME } from '@karmaniverous/jeeves-watcher-core';
|
|
3
|
+
import { extractWatchPathStrings, inferenceRuleSchema, jeevesWatcherConfigSchema, normalizeWatchPaths, vcsRetentionConfigSchema, vcsAuthorConfigSchema, getEndpoint, LOGGING_DEFAULTS, API_DEFAULTS, EMBEDDING_DEFAULTS, CONFIG_WATCH_DEFAULTS, WATCH_DEFAULTS, ROOT_DEFAULTS, INIT_CONFIG_TEMPLATE, DEFAULT_PORT as DEFAULT_PORT$1, PLUGIN_PACKAGE, SERVICE_PACKAGE, COMPONENT_NAME } from '@karmaniverous/jeeves-watcher-core';
|
|
4
4
|
export { apiConfigSchema, configWatchConfigSchema, embeddingConfigSchema, inferenceRuleSchema, jeevesWatcherConfigSchema, loggingConfigSchema, vectorStoreConfigSchema, watchConfigSchema } from '@karmaniverous/jeeves-watcher-core';
|
|
5
5
|
import Fastify from 'fastify';
|
|
6
6
|
import { readdir, stat, access, readFile, writeFile, mkdir, appendFile, rm } from 'node:fs/promises';
|
|
@@ -5008,7 +5008,7 @@ async function pushToRemote(rootPath, remoteUrl, accessToken, pushErrors, logger
|
|
|
5008
5008
|
* Per-root VCS manager for git-backed content versioning.
|
|
5009
5009
|
*
|
|
5010
5010
|
* Each VCS-enabled watch root gets its own VcsManager instance, which owns
|
|
5011
|
-
* a
|
|
5011
|
+
* a throttled commit pipeline: file changes are batched, staged, committed
|
|
5012
5012
|
* (with optional AI-generated messages), and optionally pushed to a remote.
|
|
5013
5013
|
*
|
|
5014
5014
|
* Concurrency: only one commit is in-flight at a time per root. Index.lock
|
|
@@ -5025,7 +5025,7 @@ class VcsManager {
|
|
|
5025
5025
|
pendingReversions = [];
|
|
5026
5026
|
_pushErrors = [];
|
|
5027
5027
|
squashManager;
|
|
5028
|
-
|
|
5028
|
+
throttleTimer;
|
|
5029
5029
|
commitInFlight = Promise.resolve();
|
|
5030
5030
|
consecutiveCommitFailures = 0;
|
|
5031
5031
|
started = false;
|
|
@@ -5068,7 +5068,7 @@ class VcsManager {
|
|
|
5068
5068
|
this.isBaseline = false;
|
|
5069
5069
|
}
|
|
5070
5070
|
/**
|
|
5071
|
-
* Add a file to the pending set and
|
|
5071
|
+
* Add a file to the pending set and start the throttle timer.
|
|
5072
5072
|
* If the pending set exceeds maxBatchSize, flush immediately.
|
|
5073
5073
|
*
|
|
5074
5074
|
* @param filePath - Absolute path of the changed file.
|
|
@@ -5083,15 +5083,15 @@ class VcsManager {
|
|
|
5083
5083
|
}
|
|
5084
5084
|
this.pending.add(filePath);
|
|
5085
5085
|
if (this.pending.size >= this.config.maxBatchSize) {
|
|
5086
|
-
this.
|
|
5086
|
+
this.clearThrottle();
|
|
5087
5087
|
const batch = this.takeBatch(this.config.maxBatchSize);
|
|
5088
5088
|
this.commitInFlight = this.commitInFlight.then(() => this.commitBatch(batch));
|
|
5089
5089
|
if (this.pending.size > 0) {
|
|
5090
|
-
this.
|
|
5090
|
+
this.resetThrottle();
|
|
5091
5091
|
}
|
|
5092
5092
|
return;
|
|
5093
5093
|
}
|
|
5094
|
-
this.
|
|
5094
|
+
this.resetThrottle();
|
|
5095
5095
|
}
|
|
5096
5096
|
/**
|
|
5097
5097
|
* Record reversion metadata so the next commit uses a revert-prefixed message.
|
|
@@ -5116,7 +5116,7 @@ class VcsManager {
|
|
|
5116
5116
|
* Flush all pending files immediately.
|
|
5117
5117
|
*/
|
|
5118
5118
|
async flush() {
|
|
5119
|
-
this.
|
|
5119
|
+
this.clearThrottle();
|
|
5120
5120
|
if (this.pending.size > 0) {
|
|
5121
5121
|
const batch = [...this.pending];
|
|
5122
5122
|
this.pending.clear();
|
|
@@ -5149,23 +5149,25 @@ class VcsManager {
|
|
|
5149
5149
|
return batch;
|
|
5150
5150
|
}
|
|
5151
5151
|
/**
|
|
5152
|
-
* Clear the
|
|
5152
|
+
* Clear the throttle timer.
|
|
5153
5153
|
*/
|
|
5154
|
-
|
|
5155
|
-
if (this.
|
|
5156
|
-
clearTimeout(this.
|
|
5157
|
-
this.
|
|
5154
|
+
clearThrottle() {
|
|
5155
|
+
if (this.throttleTimer !== undefined) {
|
|
5156
|
+
clearTimeout(this.throttleTimer);
|
|
5157
|
+
this.throttleTimer = undefined;
|
|
5158
5158
|
}
|
|
5159
5159
|
}
|
|
5160
5160
|
/**
|
|
5161
|
-
*
|
|
5161
|
+
* Start the throttle timer to fire flush() after commitThrottleMs.
|
|
5162
|
+
* If a timer is already running, do not reset it — this is throttle, not debounce.
|
|
5162
5163
|
*/
|
|
5163
|
-
|
|
5164
|
-
this.
|
|
5165
|
-
|
|
5166
|
-
|
|
5164
|
+
resetThrottle() {
|
|
5165
|
+
if (this.throttleTimer !== undefined)
|
|
5166
|
+
return;
|
|
5167
|
+
this.throttleTimer = setTimeout(() => {
|
|
5168
|
+
this.throttleTimer = undefined;
|
|
5167
5169
|
void this.flush();
|
|
5168
|
-
}, this.config.
|
|
5170
|
+
}, this.config.commitThrottleMs);
|
|
5169
5171
|
}
|
|
5170
5172
|
/**
|
|
5171
5173
|
* Check for and remove stale index.lock files before retrying.
|
|
@@ -5336,8 +5338,8 @@ class VcsCoordinator {
|
|
|
5336
5338
|
/**
|
|
5337
5339
|
* Signal that the initial filesystem scan is complete.
|
|
5338
5340
|
*
|
|
5339
|
-
* Flushes each manager's
|
|
5340
|
-
* any files still pending in the VCS
|
|
5341
|
+
* Flushes each manager's throttle buffer before ending baseline mode, ensuring
|
|
5342
|
+
* any files still pending in the VCS throttle are committed with a
|
|
5341
5343
|
* `"baseline:"` prefix rather than `"watcher:"`. AI generation is not enabled
|
|
5342
5344
|
* until all managers have completed their flush.
|
|
5343
5345
|
*/
|
|
@@ -5901,36 +5903,36 @@ function createApiServer(options) {
|
|
|
5901
5903
|
};
|
|
5902
5904
|
},
|
|
5903
5905
|
});
|
|
5904
|
-
app.get('
|
|
5906
|
+
app.get(getEndpoint('status').path, withCache(cacheTtlMs, async () => {
|
|
5905
5907
|
const result = await coreStatusHandler();
|
|
5906
5908
|
return result.body;
|
|
5907
5909
|
}));
|
|
5908
|
-
app.post('
|
|
5910
|
+
app.post(getEndpoint('metadata').path, createMetadataHandler({
|
|
5909
5911
|
processor,
|
|
5910
5912
|
getConfig,
|
|
5911
5913
|
logger,
|
|
5912
5914
|
configDir: dirname(configPath),
|
|
5913
5915
|
}));
|
|
5914
|
-
app.post('
|
|
5916
|
+
app.post(getEndpoint('render').path, withCache(cacheTtlMs, createRenderHandler({
|
|
5915
5917
|
processor,
|
|
5916
5918
|
getWatch: () => getConfig().watch,
|
|
5917
5919
|
logger,
|
|
5918
5920
|
})));
|
|
5919
|
-
app.get('
|
|
5921
|
+
app.get(getEndpoint('searchFacets').path, createFacetsHandler({
|
|
5920
5922
|
getConfig,
|
|
5921
5923
|
valuesManager,
|
|
5922
5924
|
configDir: dirname(configPath),
|
|
5923
5925
|
}));
|
|
5924
|
-
app.post('
|
|
5926
|
+
app.post(getEndpoint('scan').path, createScanHandler({
|
|
5925
5927
|
vectorStore,
|
|
5926
5928
|
logger,
|
|
5927
5929
|
}));
|
|
5928
|
-
app.post('
|
|
5930
|
+
app.post(getEndpoint('walk').path, createWalkHandler({
|
|
5929
5931
|
getWatchPaths: () => extractWatchPathStrings(getConfig().watch.paths),
|
|
5930
5932
|
getFileSystemWatcher,
|
|
5931
5933
|
logger,
|
|
5932
5934
|
}));
|
|
5933
|
-
app.post('
|
|
5935
|
+
app.post(getEndpoint('search').path, createSearchHandler({
|
|
5934
5936
|
embeddingProvider,
|
|
5935
5937
|
vectorStore,
|
|
5936
5938
|
logger,
|
|
@@ -5941,12 +5943,12 @@ function createApiServer(options) {
|
|
|
5941
5943
|
: undefined;
|
|
5942
5944
|
},
|
|
5943
5945
|
}));
|
|
5944
|
-
app.post('
|
|
5946
|
+
app.post(getEndpoint('rebuildMetadata').path, createRebuildMetadataHandler({
|
|
5945
5947
|
enrichmentStore: options.enrichmentStore,
|
|
5946
5948
|
vectorStore,
|
|
5947
5949
|
logger,
|
|
5948
5950
|
}));
|
|
5949
|
-
app.post('
|
|
5951
|
+
app.post(getEndpoint('reindex').path, createConfigReindexHandler({
|
|
5950
5952
|
getConfig,
|
|
5951
5953
|
processor,
|
|
5952
5954
|
logger,
|
|
@@ -5957,10 +5959,10 @@ function createApiServer(options) {
|
|
|
5957
5959
|
vectorStore,
|
|
5958
5960
|
queue,
|
|
5959
5961
|
}));
|
|
5960
|
-
app.get('
|
|
5961
|
-
app.get('
|
|
5962
|
-
app.post('
|
|
5963
|
-
app.get('
|
|
5962
|
+
app.get(getEndpoint('issues').path, withCache(cacheTtlMs, createIssuesHandler({ issuesManager })));
|
|
5963
|
+
app.get(getEndpoint('configSchema').path, withCache(cacheTtlMs, createConfigSchemaHandler()));
|
|
5964
|
+
app.post(getEndpoint('configMatch').path, createConfigMatchHandler({ getConfig, logger }));
|
|
5965
|
+
app.get(getEndpoint('config').path, withCache(cacheTtlMs, createConfigQueryHandler({
|
|
5964
5966
|
getConfig,
|
|
5965
5967
|
valuesManager,
|
|
5966
5968
|
issuesManager,
|
|
@@ -5970,7 +5972,7 @@ function createApiServer(options) {
|
|
|
5970
5972
|
? () => virtualRuleStore.getAll()
|
|
5971
5973
|
: undefined,
|
|
5972
5974
|
})));
|
|
5973
|
-
app.post('
|
|
5975
|
+
app.post(getEndpoint('configValidate').path, createConfigValidateHandler({
|
|
5974
5976
|
getConfig,
|
|
5975
5977
|
logger,
|
|
5976
5978
|
configDir: dirname(configPath),
|
|
@@ -5984,7 +5986,7 @@ function createApiServer(options) {
|
|
|
5984
5986
|
return Promise.resolve();
|
|
5985
5987
|
},
|
|
5986
5988
|
});
|
|
5987
|
-
app.post('
|
|
5989
|
+
app.post(getEndpoint('configApply').path, async (request, reply) => {
|
|
5988
5990
|
const { patch, replace } = request.body;
|
|
5989
5991
|
const result = await coreConfigApplyHandler({ patch, replace });
|
|
5990
5992
|
return reply.status(result.status).send(result.body);
|
|
@@ -6003,34 +6005,34 @@ function createApiServer(options) {
|
|
|
6003
6005
|
gitignoreFilter,
|
|
6004
6006
|
vectorStore,
|
|
6005
6007
|
});
|
|
6006
|
-
app.post('
|
|
6008
|
+
app.post(getEndpoint('rulesRegister').path, createRulesRegisterHandler({
|
|
6007
6009
|
virtualRuleStore,
|
|
6008
6010
|
logger,
|
|
6009
6011
|
onRulesChanged,
|
|
6010
6012
|
}));
|
|
6011
|
-
app.delete('
|
|
6013
|
+
app.delete(getEndpoint('rulesUnregister').path, createRulesUnregisterHandler({
|
|
6012
6014
|
virtualRuleStore,
|
|
6013
6015
|
logger,
|
|
6014
6016
|
onRulesChanged,
|
|
6015
6017
|
}));
|
|
6016
|
-
app.delete('
|
|
6018
|
+
app.delete(getEndpoint('rulesUnregisterBySource').path, createRulesUnregisterParamHandler({
|
|
6017
6019
|
virtualRuleStore,
|
|
6018
6020
|
logger,
|
|
6019
6021
|
onRulesChanged,
|
|
6020
6022
|
}));
|
|
6021
|
-
app.post('
|
|
6022
|
-
app.post('
|
|
6023
|
+
app.post(getEndpoint('pointsDelete').path, createPointsDeleteHandler({ vectorStore, logger }));
|
|
6024
|
+
app.post(getEndpoint('rulesReapply').path, createRulesReapplyHandler({ processor, vectorStore, logger }));
|
|
6023
6025
|
}
|
|
6024
6026
|
// VCS routes — only registered when a VcsCoordinator is provided
|
|
6025
6027
|
if (options.vcsCoordinator) {
|
|
6026
6028
|
const coordinator = options.vcsCoordinator;
|
|
6027
|
-
app.get('
|
|
6028
|
-
app.get('
|
|
6029
|
-
app.get('
|
|
6030
|
-
app.get('
|
|
6031
|
-
app.get('
|
|
6032
|
-
app.post('
|
|
6033
|
-
app.post('
|
|
6029
|
+
app.get(getEndpoint('vcsStatus').path, createVcsStatusHandler({ coordinator, logger }));
|
|
6030
|
+
app.get(getEndpoint('vcsHistory').path, createVcsHistoryHandler({ coordinator, logger }));
|
|
6031
|
+
app.get(getEndpoint('vcsShow').path, createVcsShowHandler({ coordinator, logger }));
|
|
6032
|
+
app.get(getEndpoint('vcsDiff').path, createVcsDiffHandler({ coordinator, logger }));
|
|
6033
|
+
app.get(getEndpoint('vcsCheckExclusion').path, createVcsCheckExclusionHandler({ coordinator, logger }));
|
|
6034
|
+
app.post(getEndpoint('vcsRevert').path, createVcsRevertHandler({ coordinator, logger }));
|
|
6035
|
+
app.post(getEndpoint('vcsExclude').path, createVcsExcludeHandler({ coordinator, logger }));
|
|
6034
6036
|
}
|
|
6035
6037
|
return app;
|
|
6036
6038
|
}
|
package/package.json
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
"dependencies": {
|
|
10
10
|
"@commander-js/extra-typings": "^14.0.0",
|
|
11
11
|
"@karmaniverous/jeeves": "^0.5.12",
|
|
12
|
-
"@karmaniverous/jeeves-watcher-core": "^0.2.
|
|
12
|
+
"@karmaniverous/jeeves-watcher-core": "^0.2.4",
|
|
13
13
|
"@karmaniverous/jsonmap": "^2.1.1",
|
|
14
14
|
"@langchain/textsplitters": "*",
|
|
15
15
|
"@qdrant/js-client-rest": "*",
|
|
@@ -149,5 +149,5 @@
|
|
|
149
149
|
},
|
|
150
150
|
"type": "module",
|
|
151
151
|
"types": "dist/index.d.ts",
|
|
152
|
-
"version": "0.18.
|
|
152
|
+
"version": "0.18.10"
|
|
153
153
|
}
|