@coderule/mcp 1.5.0 → 1.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -30,6 +30,8 @@ var DEFAULT_QUEUE_POLL_INTERVAL_MS = 500;
30
30
  var DEFAULT_HASH_BATCH_SIZE = 32;
31
31
  var DEFAULT_MAX_SNAPSHOT_ATTEMPTS = 5;
32
32
  var DEFAULT_HTTP_TIMEOUT_MS = 12e4;
33
+ var DEFAULT_UPLOAD_CHUNK_SIZE = 1;
34
+ var DEFAULT_MAX_QUERY_WAIT_MS = 5e4;
33
35
 
34
36
  // src/config/Configurator.ts
35
37
  var DEFAULT_RETRIEVAL_FORMATTER = "standard";
@@ -57,6 +59,14 @@ function parseInteger(value, fallback) {
57
59
  }
58
60
  return parsed;
59
61
  }
62
+ function parseSecondsToMs(value, fallbackMs) {
63
+ if (!value) return fallbackMs;
64
+ const seconds = Number.parseInt(value, 10);
65
+ if (Number.isNaN(seconds) || seconds <= 0) {
66
+ throw new Error(`Invalid seconds value: ${value}`);
67
+ }
68
+ return seconds * 1e3;
69
+ }
60
70
  function parseFormatter(value) {
61
71
  if (!value) return DEFAULT_RETRIEVAL_FORMATTER;
62
72
  const normalized = value.toLowerCase();
@@ -103,7 +113,9 @@ async function resolveConfig({
103
113
  maxSnapshotAttempts: DEFAULTS.maxSnapshotAttempts,
104
114
  retrievalFormatter: parseFormatter(
105
115
  process.env.CODERULE_RETRIEVAL_FORMATTER
106
- )
116
+ ),
117
+ uploadChunkSize: DEFAULT_UPLOAD_CHUNK_SIZE,
118
+ maxQueryWaitMs: DEFAULT_MAX_QUERY_WAIT_MS
107
119
  };
108
120
  if (process.env.CODERULE_SNAPSHOT_DEBOUNCE_MS) {
109
121
  baseConfig.snapshotDebounceMs = parseInteger(
@@ -145,6 +157,16 @@ async function resolveConfig({
145
157
  process.env.CODERULE_HTTP_TIMEOUT,
146
158
  DEFAULT_HTTP_TIMEOUT_MS
147
159
  );
160
+ if (process.env.CODERULE_UPLOAD_CHUNK_SIZE) {
161
+ baseConfig.uploadChunkSize = parseInteger(
162
+ process.env.CODERULE_UPLOAD_CHUNK_SIZE,
163
+ baseConfig.uploadChunkSize
164
+ );
165
+ }
166
+ baseConfig.maxQueryWaitMs = parseSecondsToMs(
167
+ process.env.CODERULE_MAX_WAIT_TIME,
168
+ baseConfig.maxQueryWaitMs
169
+ );
148
170
  logger.debug(
149
171
  {
150
172
  rootPath,
@@ -1078,7 +1100,7 @@ async function withRetries(op, logger2, context, maxAttempts) {
1078
1100
  }
1079
1101
  }
1080
1102
  }
1081
- async function uploadMissing(rootPath, missing, syncClient, logger2, maxAttempts, chunkSize = 64) {
1103
+ async function uploadMissing(rootPath, missing, syncClient, logger2, maxAttempts, chunkSize = 1) {
1082
1104
  if (!missing || missing.length === 0) return;
1083
1105
  const total = missing.length;
1084
1106
  const chunks = [];
@@ -1120,7 +1142,7 @@ async function uploadMissing(rootPath, missing, syncClient, logger2, maxAttempts
1120
1142
  async function ensureSnapshotCreated(rootPath, computation, syncClient, logger2, options) {
1121
1143
  const { snapshotHash, files } = computation;
1122
1144
  const maxAttempts = options?.maxAttempts ?? 5;
1123
- const uploadChunkSize = options?.uploadChunkSize ?? 64;
1145
+ const uploadChunkSize = options?.uploadChunkSize ?? 1;
1124
1146
  let status = await withRetries(
1125
1147
  () => syncClient.checkSnapshotStatus(snapshotHash),
1126
1148
  logger2,
@@ -1202,7 +1224,7 @@ async function publishSnapshot(rootPath, filesRepo, snapshotsRepo, syncClient, l
1202
1224
  }
1203
1225
 
1204
1226
  // src/service/InitialSync.ts
1205
- async function runInitialSyncPipeline(runtime) {
1227
+ async function runInitialSyncPipeline(runtime, options) {
1206
1228
  const inventoryLogger = runtime.logger.child({ scope: "inventory" });
1207
1229
  await runInventory({
1208
1230
  rootPath: runtime.config.rootPath,
@@ -1218,16 +1240,37 @@ async function runInitialSyncPipeline(runtime) {
1218
1240
  hashLogger.debug("Hasher processed batch");
1219
1241
  }
1220
1242
  }
1221
- const syncLogger = runtime.logger.child({ scope: "snapshot" });
1222
- const result = await publishSnapshot(
1223
- runtime.config.rootPath,
1224
- runtime.filesRepo,
1225
- runtime.snapshotsRepo,
1226
- runtime.clients.sync,
1227
- syncLogger,
1228
- { maxAttempts: runtime.config.maxSnapshotAttempts }
1243
+ if (options?.blockUntilReady !== false) {
1244
+ const syncLogger = runtime.logger.child({ scope: "snapshot" });
1245
+ const result = await publishSnapshot(
1246
+ runtime.config.rootPath,
1247
+ runtime.filesRepo,
1248
+ runtime.snapshotsRepo,
1249
+ runtime.clients.sync,
1250
+ syncLogger,
1251
+ {
1252
+ maxAttempts: runtime.config.maxSnapshotAttempts,
1253
+ uploadChunkSize: runtime.config.uploadChunkSize
1254
+ }
1255
+ );
1256
+ return result;
1257
+ }
1258
+ const computation = computeSnapshot(runtime.filesRepo);
1259
+ const createdAt = Date.now();
1260
+ runtime.snapshotsRepo.insert(
1261
+ computation.snapshotHash,
1262
+ computation.filesCount,
1263
+ computation.totalSize,
1264
+ createdAt
1229
1265
  );
1230
- return result;
1266
+ runtime.outbox.enqueueSnapshot(runtime.config.rootId, 0);
1267
+ return {
1268
+ snapshotHash: computation.snapshotHash,
1269
+ filesCount: computation.filesCount,
1270
+ totalSize: computation.totalSize,
1271
+ status: "READY",
1272
+ createdAt
1273
+ };
1231
1274
  }
1232
1275
  async function createChokidarWatcher(options, usePolling) {
1233
1276
  const log = options.logger.child({
@@ -1629,7 +1672,10 @@ var ServiceRunner = class {
1629
1672
  this.runtime.snapshotsRepo,
1630
1673
  this.runtime.clients.sync,
1631
1674
  log,
1632
- { maxAttempts: this.runtime.config.maxSnapshotAttempts }
1675
+ {
1676
+ maxAttempts: this.runtime.config.maxSnapshotAttempts,
1677
+ uploadChunkSize: this.runtime.config.uploadChunkSize
1678
+ }
1633
1679
  );
1634
1680
  this.runtime.outbox.ack(job.id, this.fsControlLeaseOwner);
1635
1681
  this.state.updateSnapshotReady(result.createdAt);
@@ -1688,7 +1734,9 @@ function awaitShutdownSignals() {
1688
1734
  async function runInitialSync(params) {
1689
1735
  const runtime = await bootstrap(params);
1690
1736
  try {
1691
- const result = await runInitialSyncPipeline(runtime);
1737
+ const result = await runInitialSyncPipeline(runtime, {
1738
+ blockUntilReady: true
1739
+ });
1692
1740
  runtime.logger.info(
1693
1741
  {
1694
1742
  snapshotHash: result.snapshotHash,
@@ -1712,7 +1760,9 @@ async function runService(params) {
1712
1760
  await runner.prepareWatcher(true);
1713
1761
  let initialCreatedAt;
1714
1762
  try {
1715
- const initial = await runInitialSyncPipeline(runtime);
1763
+ const initial = await runInitialSyncPipeline(runtime, {
1764
+ blockUntilReady: false
1765
+ });
1716
1766
  runtime.logger.info(
1717
1767
  {
1718
1768
  snapshotHash: initial.snapshotHash,
@@ -1756,7 +1806,9 @@ var ENV_FLAG_MAP = {
1756
1806
  "queue-poll": "CODERULE_QUEUE_POLL_INTERVAL_MS",
1757
1807
  "hash-batch": "CODERULE_HASH_BATCH_SIZE",
1758
1808
  "hash-lease": "CODERULE_HASH_LEASE_MS",
1759
- "max-snapshot-attempts": "CODERULE_MAX_SNAPSHOT_ATTEMPTS"
1809
+ "max-snapshot-attempts": "CODERULE_MAX_SNAPSHOT_ATTEMPTS",
1810
+ "upload-chunk-size": "CODERULE_UPLOAD_CHUNK_SIZE",
1811
+ "max-wait-time": "CODERULE_MAX_WAIT_TIME"
1760
1812
  };
1761
1813
  function printUsage() {
1762
1814
  console.log(`Usage: coderule-scanner [token] [options]
@@ -1780,6 +1832,8 @@ Options:
1780
1832
  --hash-batch <n> Override CODERULE_HASH_BATCH_SIZE
1781
1833
  --hash-lease <ms> Override CODERULE_HASH_LEASE_MS
1782
1834
  --max-snapshot-attempts <n> Override CODERULE_MAX_SNAPSHOT_ATTEMPTS
1835
+ --upload-chunk-size <n> Override CODERULE_UPLOAD_CHUNK_SIZE (default 1)
1836
+ --max-wait-time <sec> Override CODERULE_MAX_WAIT_TIME (default 50s)
1783
1837
  KEY=value Set arbitrary environment variable
1784
1838
  --help Show this message
1785
1839
  `);