@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.cjs CHANGED
@@ -45,6 +45,8 @@ var DEFAULT_QUEUE_POLL_INTERVAL_MS = 500;
45
45
  var DEFAULT_HASH_BATCH_SIZE = 32;
46
46
  var DEFAULT_MAX_SNAPSHOT_ATTEMPTS = 5;
47
47
  var DEFAULT_HTTP_TIMEOUT_MS = 12e4;
48
+ var DEFAULT_UPLOAD_CHUNK_SIZE = 1;
49
+ var DEFAULT_MAX_QUERY_WAIT_MS = 5e4;
48
50
 
49
51
  // src/config/Configurator.ts
50
52
  var DEFAULT_RETRIEVAL_FORMATTER = "standard";
@@ -72,6 +74,14 @@ function parseInteger(value, fallback) {
72
74
  }
73
75
  return parsed;
74
76
  }
77
+ function parseSecondsToMs(value, fallbackMs) {
78
+ if (!value) return fallbackMs;
79
+ const seconds = Number.parseInt(value, 10);
80
+ if (Number.isNaN(seconds) || seconds <= 0) {
81
+ throw new Error(`Invalid seconds value: ${value}`);
82
+ }
83
+ return seconds * 1e3;
84
+ }
75
85
  function parseFormatter(value) {
76
86
  if (!value) return DEFAULT_RETRIEVAL_FORMATTER;
77
87
  const normalized = value.toLowerCase();
@@ -118,7 +128,9 @@ async function resolveConfig({
118
128
  maxSnapshotAttempts: DEFAULTS.maxSnapshotAttempts,
119
129
  retrievalFormatter: parseFormatter(
120
130
  process.env.CODERULE_RETRIEVAL_FORMATTER
121
- )
131
+ ),
132
+ uploadChunkSize: DEFAULT_UPLOAD_CHUNK_SIZE,
133
+ maxQueryWaitMs: DEFAULT_MAX_QUERY_WAIT_MS
122
134
  };
123
135
  if (process.env.CODERULE_SNAPSHOT_DEBOUNCE_MS) {
124
136
  baseConfig.snapshotDebounceMs = parseInteger(
@@ -160,6 +172,16 @@ async function resolveConfig({
160
172
  process.env.CODERULE_HTTP_TIMEOUT,
161
173
  DEFAULT_HTTP_TIMEOUT_MS
162
174
  );
175
+ if (process.env.CODERULE_UPLOAD_CHUNK_SIZE) {
176
+ baseConfig.uploadChunkSize = parseInteger(
177
+ process.env.CODERULE_UPLOAD_CHUNK_SIZE,
178
+ baseConfig.uploadChunkSize
179
+ );
180
+ }
181
+ baseConfig.maxQueryWaitMs = parseSecondsToMs(
182
+ process.env.CODERULE_MAX_WAIT_TIME,
183
+ baseConfig.maxQueryWaitMs
184
+ );
163
185
  logger.debug(
164
186
  {
165
187
  rootPath,
@@ -1093,7 +1115,7 @@ async function withRetries(op, logger2, context, maxAttempts) {
1093
1115
  }
1094
1116
  }
1095
1117
  }
1096
- async function uploadMissing(rootPath, missing, syncClient, logger2, maxAttempts, chunkSize = 64) {
1118
+ async function uploadMissing(rootPath, missing, syncClient, logger2, maxAttempts, chunkSize = 1) {
1097
1119
  if (!missing || missing.length === 0) return;
1098
1120
  const total = missing.length;
1099
1121
  const chunks = [];
@@ -1135,7 +1157,7 @@ async function uploadMissing(rootPath, missing, syncClient, logger2, maxAttempts
1135
1157
  async function ensureSnapshotCreated(rootPath, computation, syncClient, logger2, options) {
1136
1158
  const { snapshotHash, files } = computation;
1137
1159
  const maxAttempts = options?.maxAttempts ?? 5;
1138
- const uploadChunkSize = options?.uploadChunkSize ?? 64;
1160
+ const uploadChunkSize = options?.uploadChunkSize ?? 1;
1139
1161
  let status = await withRetries(
1140
1162
  () => syncClient.checkSnapshotStatus(snapshotHash),
1141
1163
  logger2,
@@ -1217,7 +1239,7 @@ async function publishSnapshot(rootPath, filesRepo, snapshotsRepo, syncClient, l
1217
1239
  }
1218
1240
 
1219
1241
  // src/service/InitialSync.ts
1220
- async function runInitialSyncPipeline(runtime) {
1242
+ async function runInitialSyncPipeline(runtime, options) {
1221
1243
  const inventoryLogger = runtime.logger.child({ scope: "inventory" });
1222
1244
  await runInventory({
1223
1245
  rootPath: runtime.config.rootPath,
@@ -1233,16 +1255,37 @@ async function runInitialSyncPipeline(runtime) {
1233
1255
  hashLogger.debug("Hasher processed batch");
1234
1256
  }
1235
1257
  }
1236
- const syncLogger = runtime.logger.child({ scope: "snapshot" });
1237
- const result = await publishSnapshot(
1238
- runtime.config.rootPath,
1239
- runtime.filesRepo,
1240
- runtime.snapshotsRepo,
1241
- runtime.clients.sync,
1242
- syncLogger,
1243
- { maxAttempts: runtime.config.maxSnapshotAttempts }
1258
+ if (options?.blockUntilReady !== false) {
1259
+ const syncLogger = runtime.logger.child({ scope: "snapshot" });
1260
+ const result = await publishSnapshot(
1261
+ runtime.config.rootPath,
1262
+ runtime.filesRepo,
1263
+ runtime.snapshotsRepo,
1264
+ runtime.clients.sync,
1265
+ syncLogger,
1266
+ {
1267
+ maxAttempts: runtime.config.maxSnapshotAttempts,
1268
+ uploadChunkSize: runtime.config.uploadChunkSize
1269
+ }
1270
+ );
1271
+ return result;
1272
+ }
1273
+ const computation = computeSnapshot(runtime.filesRepo);
1274
+ const createdAt = Date.now();
1275
+ runtime.snapshotsRepo.insert(
1276
+ computation.snapshotHash,
1277
+ computation.filesCount,
1278
+ computation.totalSize,
1279
+ createdAt
1244
1280
  );
1245
- return result;
1281
+ runtime.outbox.enqueueSnapshot(runtime.config.rootId, 0);
1282
+ return {
1283
+ snapshotHash: computation.snapshotHash,
1284
+ filesCount: computation.filesCount,
1285
+ totalSize: computation.totalSize,
1286
+ status: "READY",
1287
+ createdAt
1288
+ };
1246
1289
  }
1247
1290
  async function createChokidarWatcher(options, usePolling) {
1248
1291
  const log = options.logger.child({
@@ -1644,7 +1687,10 @@ var ServiceRunner = class {
1644
1687
  this.runtime.snapshotsRepo,
1645
1688
  this.runtime.clients.sync,
1646
1689
  log,
1647
- { maxAttempts: this.runtime.config.maxSnapshotAttempts }
1690
+ {
1691
+ maxAttempts: this.runtime.config.maxSnapshotAttempts,
1692
+ uploadChunkSize: this.runtime.config.uploadChunkSize
1693
+ }
1648
1694
  );
1649
1695
  this.runtime.outbox.ack(job.id, this.fsControlLeaseOwner);
1650
1696
  this.state.updateSnapshotReady(result.createdAt);
@@ -1703,7 +1749,9 @@ function awaitShutdownSignals() {
1703
1749
  async function runInitialSync(params) {
1704
1750
  const runtime = await bootstrap(params);
1705
1751
  try {
1706
- const result = await runInitialSyncPipeline(runtime);
1752
+ const result = await runInitialSyncPipeline(runtime, {
1753
+ blockUntilReady: true
1754
+ });
1707
1755
  runtime.logger.info(
1708
1756
  {
1709
1757
  snapshotHash: result.snapshotHash,
@@ -1727,7 +1775,9 @@ async function runService(params) {
1727
1775
  await runner.prepareWatcher(true);
1728
1776
  let initialCreatedAt;
1729
1777
  try {
1730
- const initial = await runInitialSyncPipeline(runtime);
1778
+ const initial = await runInitialSyncPipeline(runtime, {
1779
+ blockUntilReady: false
1780
+ });
1731
1781
  runtime.logger.info(
1732
1782
  {
1733
1783
  snapshotHash: initial.snapshotHash,
@@ -1771,7 +1821,9 @@ var ENV_FLAG_MAP = {
1771
1821
  "queue-poll": "CODERULE_QUEUE_POLL_INTERVAL_MS",
1772
1822
  "hash-batch": "CODERULE_HASH_BATCH_SIZE",
1773
1823
  "hash-lease": "CODERULE_HASH_LEASE_MS",
1774
- "max-snapshot-attempts": "CODERULE_MAX_SNAPSHOT_ATTEMPTS"
1824
+ "max-snapshot-attempts": "CODERULE_MAX_SNAPSHOT_ATTEMPTS",
1825
+ "upload-chunk-size": "CODERULE_UPLOAD_CHUNK_SIZE",
1826
+ "max-wait-time": "CODERULE_MAX_WAIT_TIME"
1775
1827
  };
1776
1828
  function printUsage() {
1777
1829
  console.log(`Usage: coderule-scanner [token] [options]
@@ -1795,6 +1847,8 @@ Options:
1795
1847
  --hash-batch <n> Override CODERULE_HASH_BATCH_SIZE
1796
1848
  --hash-lease <ms> Override CODERULE_HASH_LEASE_MS
1797
1849
  --max-snapshot-attempts <n> Override CODERULE_MAX_SNAPSHOT_ATTEMPTS
1850
+ --upload-chunk-size <n> Override CODERULE_UPLOAD_CHUNK_SIZE (default 1)
1851
+ --max-wait-time <sec> Override CODERULE_MAX_WAIT_TIME (default 50s)
1798
1852
  KEY=value Set arbitrary environment variable
1799
1853
  --help Show this message
1800
1854
  `);