@massa-ai/mcp-client 1.63.1 → 1.65.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.
Files changed (3) hide show
  1. package/dist/config-cli.js +410 -179
  2. package/dist/index.js +1105 -848
  3. package/package.json +3 -3
@@ -3540,22 +3540,15 @@ var BOOTSTRAP_RULE_IDS, RETIRED_RULE_IDS, BOOTSTRAP_RULES, RULES_BY_ID, Bootstra
3540
3540
  };
3541
3541
  var init_rules = __esm(() => {
3542
3542
  BOOTSTRAP_RULE_IDS = [
3543
- "caveman",
3544
3543
  "massa-ai-router",
3545
3544
  "dedupe-guardrails",
3546
- "plan-challenge",
3547
3545
  "conversation-feedback",
3548
3546
  "indexing-hygiene",
3549
3547
  "english-code",
3550
3548
  "code-comments"
3551
3549
  ];
3552
- RETIRED_RULE_IDS = ["persona-router"];
3550
+ RETIRED_RULE_IDS = ["persona-router", "caveman", "plan-challenge"];
3553
3551
  BOOTSTRAP_RULES = [
3554
- {
3555
- id: "caveman",
3556
- defaultEnabled: true,
3557
- description: "Keep communication compressed while preserving technical accuracy."
3558
- },
3559
3552
  {
3560
3553
  id: "massa-ai-router",
3561
3554
  defaultEnabled: true,
@@ -3566,11 +3559,6 @@ var init_rules = __esm(() => {
3566
3559
  defaultEnabled: true,
3567
3560
  description: "Reuse already-loaded massa-ai context instead of bulk-loading workflows or references."
3568
3561
  },
3569
- {
3570
- id: "plan-challenge",
3571
- defaultEnabled: true,
3572
- description: "Run The Fool as a post-plan challenge gate per the configured policy."
3573
- },
3574
3562
  {
3575
3563
  id: "conversation-feedback",
3576
3564
  defaultEnabled: true,
@@ -10202,7 +10190,8 @@ var init_ignore_patterns = __esm(() => {
10202
10190
  "**/pnpm-lock.yaml",
10203
10191
  "**/package-lock.json",
10204
10192
  "**/bun.lockb",
10205
- "**/yarn.lock"
10193
+ "**/yarn.lock",
10194
+ "**/Pods/**"
10206
10195
  ];
10207
10196
  });
10208
10197
 
@@ -117758,6 +117747,33 @@ class ManagedRunRepositoryPg {
117758
117747
  `;
117759
117748
  return rows[0] ? toActive(rows[0]) : null;
117760
117749
  }
117750
+ async getAnyActive() {
117751
+ const rows = await getPrismaClient2().$queryRaw`
117752
+ SELECT id, project_id, run_kind, event_id, content_hash, file_cursor,
117753
+ status, lease_token, lease_expires_at, heartbeat_at,
117754
+ created_at, completed_at
117755
+ FROM managed_runs
117756
+ WHERE status = 'active'
117757
+ AND lease_expires_at > clock_timestamp()
117758
+ ORDER BY lease_expires_at DESC
117759
+ LIMIT 1
117760
+ `;
117761
+ return rows[0] ? toActive(rows[0]) : null;
117762
+ }
117763
+ async release(lease) {
117764
+ const leaseToken = boundedText(lease.leaseToken, "leaseToken", MAX_LEASE_TOKEN);
117765
+ const deleted = await getPrismaClient2().$queryRaw`
117766
+ DELETE FROM managed_runs
117767
+ WHERE id = ${BigInt(lease.runId)}
117768
+ AND project_id = ${lease.projectId}
117769
+ AND run_kind = ${lease.runKind}
117770
+ AND lease_token = ${leaseToken}
117771
+ RETURNING id
117772
+ `;
117773
+ if (!deleted[0])
117774
+ return { status: "lease_lost" };
117775
+ return { status: "aborted", runId: deleted[0].id.toString() };
117776
+ }
117761
117777
  }
117762
117778
  var DEFAULT_LEASE_TTL_MS = 90000, MIN_LEASE_TTL_MS = 1000, MAX_LEASE_TTL_MS = 300000, HEARTBEAT_TTL_MS = 90000, MAX_PROJECT_ID = 512, MAX_EVENT_ID = 2000, MAX_CONTENT_HASH = 2000, MAX_LEASE_TOKEN = 512;
117763
117779
  var init_managed_run_repository_pg = __esm(() => {
@@ -117795,10 +117811,111 @@ var init_embedding_freshness = __esm(() => {
117795
117811
  };
117796
117812
  });
117797
117813
 
117814
+ // ../../packages/core/dist/services/jobs/heavy-work-lease.js
117815
+ import { randomUUID as randomUUID3 } from "crypto";
117816
+ import { setTimeout as delay2 } from "timers/promises";
117817
+ function repository() {
117818
+ return repositoryOverride ?? ManagedRunRepositoryPg.getInstance();
117819
+ }
117820
+ async function withHeavyWorkLease(kind, label, fn) {
117821
+ let repo;
117822
+ let lease;
117823
+ try {
117824
+ repo = repository();
117825
+ const outcome = await repo.begin({
117826
+ projectId: `heavy-work:${label}:${randomUUID3()}`,
117827
+ runKind: kind,
117828
+ eventId: `heavy-work:${label}`
117829
+ });
117830
+ if (outcome.status === "acquired")
117831
+ lease = outcome.lease;
117832
+ } catch (error51) {
117833
+ logger.warn("heavy-work lease unavailable; running without it", { label, error: error51 });
117834
+ }
117835
+ if (!repo || !lease)
117836
+ return fn();
117837
+ const heldRepo = repo;
117838
+ const heldLease = lease;
117839
+ const heartbeatController = new AbortController;
117840
+ (async () => {
117841
+ while (true) {
117842
+ try {
117843
+ await delay2(HEARTBEAT_MS, undefined, { signal: heartbeatController.signal });
117844
+ } catch {
117845
+ return;
117846
+ }
117847
+ try {
117848
+ await heldRepo.heartbeat(heldLease);
117849
+ } catch {}
117850
+ }
117851
+ })();
117852
+ try {
117853
+ return await fn();
117854
+ } finally {
117855
+ heartbeatController.abort();
117856
+ try {
117857
+ await heldRepo.release(heldLease);
117858
+ } catch (error51) {
117859
+ logger.warn("heavy-work lease release failed; it expires on its own", { label, error: error51 });
117860
+ }
117861
+ }
117862
+ }
117863
+ async function probeHeavyWork() {
117864
+ let timer;
117865
+ const timeout = new Promise((_, reject) => {
117866
+ timer = setTimeout(() => reject(new Error(`heavy-work probe timed out after ${PROBE_TIMEOUT_MS}ms`)), PROBE_TIMEOUT_MS);
117867
+ });
117868
+ try {
117869
+ const active = await Promise.race([repository().getAnyActive(), timeout]);
117870
+ if (!active)
117871
+ return { busy: false };
117872
+ return { busy: true, reason: `${active.runKind} run ${active.runId} (${active.projectId})` };
117873
+ } finally {
117874
+ clearTimeout(timer);
117875
+ }
117876
+ }
117877
+ var HEARTBEAT_MS = 30000, PROBE_TIMEOUT_MS = 5000, repositoryOverride = null;
117878
+ var init_heavy_work_lease = __esm(() => {
117879
+ init_dist();
117880
+ init_managed_run_repository_pg();
117881
+ });
117882
+
117883
+ // ../../packages/core/dist/services/search/incremental-reindex.js
117884
+ import path21 from "path";
117885
+ function runIncrementalReindex(deps, projectId, projectPath, filesToReindex) {
117886
+ return withHeavyWorkLease("reindex", `incremental-reindex:${projectId}`, async () => {
117887
+ const centralityMap = await deps.symbolRepo.getCentrality(await getProjectIdentityAliasResolver().resolve(projectId));
117888
+ let filesIndexed = 0;
117889
+ let chunksIndexed = 0;
117890
+ let errors4 = 0;
117891
+ for (const relativeFilePath of filesToReindex) {
117892
+ try {
117893
+ const fullPath = path21.join(projectPath, relativeFilePath);
117894
+ const result = await deps.indexFile(fullPath, projectId, projectPath, centralityMap);
117895
+ filesIndexed++;
117896
+ chunksIndexed += result.chunks;
117897
+ } catch (error51) {
117898
+ logger.error("Failed to reindex file", error51, {
117899
+ file: relativeFilePath
117900
+ });
117901
+ errors4++;
117902
+ }
117903
+ }
117904
+ await deps.indexManager.updateIndexMetadata(projectId, projectPath, filesToReindex);
117905
+ await deps.searchCache.invalidateProject(projectId);
117906
+ return { filesIndexed, chunksIndexed, errors: errors4 };
117907
+ });
117908
+ }
117909
+ var init_incremental_reindex = __esm(() => {
117910
+ init_dist();
117911
+ init_alias_resolver();
117912
+ init_heavy_work_lease();
117913
+ });
117914
+
117798
117915
  // ../../packages/core/dist/services/search/project-indexer.js
117799
117916
  import fs15 from "fs/promises";
117800
- import path21 from "path";
117801
- import { randomUUID as randomUUID3 } from "crypto";
117917
+ import path22 from "path";
117918
+ import { randomUUID as randomUUID4 } from "crypto";
117802
117919
  async function runWithIndexLock(lockMap, projectId, work) {
117803
117920
  const prevLock = lockMap.get(projectId);
117804
117921
  const isQueued = prevLock !== undefined;
@@ -117840,7 +117957,7 @@ async function indexProjectInternal(deps, projectPath, projectId, options = {})
117840
117957
  dot: false
117841
117958
  });
117842
117959
  const filteredFiles = files.filter((file2) => {
117843
- const relativePath = path21.relative(projectPath, file2);
117960
+ const relativePath = path22.relative(projectPath, file2);
117844
117961
  const shouldIgnore = ig.ignores(relativePath);
117845
117962
  if (shouldIgnore) {
117846
117963
  logger.debug("Ignoring file per .gitignore during indexing", {
@@ -117880,7 +117997,7 @@ async function indexProjectInternal(deps, projectPath, projectId, options = {})
117880
117997
  });
117881
117998
  }
117882
117999
  }
117883
- const indexedFilesList = filteredFiles.map((f) => path21.relative(projectPath, f));
118000
+ const indexedFilesList = filteredFiles.map((f) => path22.relative(projectPath, f));
117884
118001
  await deps.indexManager.updateIndexMetadata(projectId, projectPath, indexedFilesList);
117885
118002
  logger.info("Project indexing completed", {
117886
118003
  projectId,
@@ -117951,7 +118068,7 @@ async function ensureFreshIndex(deps, projectId, projectPath, options = {}) {
117951
118068
  if (needsFullReindex) {
117952
118069
  logger.info("Performing full reindex", { projectId });
117953
118070
  const managedRunRepo = ManagedRunRepositoryPg.getInstance();
117954
- const eventId = `reindex:${projectId}:${randomUUID3()}`;
118071
+ const eventId = `reindex:${projectId}:${randomUUID4()}`;
117955
118072
  const beginOutcome = await managedRunRepo.begin({
117956
118073
  projectId,
117957
118074
  runKind: "indexing",
@@ -118004,25 +118121,7 @@ async function ensureFreshIndex(deps, projectId, projectPath, options = {}) {
118004
118121
  projectId,
118005
118122
  fileCount: filesToReindex.length
118006
118123
  });
118007
- const centralityMap = await deps.symbolRepo.getCentrality(await getProjectIdentityAliasResolver().resolve(projectId));
118008
- let filesIndexed = 0;
118009
- let chunksIndexed = 0;
118010
- let errors4 = 0;
118011
- for (const relativeFilePath of filesToReindex) {
118012
- try {
118013
- const fullPath = path21.join(projectPath, relativeFilePath);
118014
- const result = await deps.indexFile(fullPath, projectId, projectPath, centralityMap);
118015
- filesIndexed++;
118016
- chunksIndexed += result.chunks;
118017
- } catch (error51) {
118018
- logger.error("Failed to reindex file", error51, {
118019
- file: relativeFilePath
118020
- });
118021
- errors4++;
118022
- }
118023
- }
118024
- await deps.indexManager.updateIndexMetadata(projectId, projectPath, filesToReindex);
118025
- await deps.searchCache.invalidateProject(projectId);
118124
+ const { filesIndexed, chunksIndexed, errors: errors4 } = await runIncrementalReindex(deps, projectId, projectPath, filesToReindex);
118026
118125
  logger.info("Incremental reindex completed", {
118027
118126
  projectId,
118028
118127
  filesIndexed,
@@ -118071,7 +118170,7 @@ async function checkSearchAdmission(deps, projectId, projectPath) {
118071
118170
  async function indexFile(deps, filePath, projectId, projectRoot, centralityMap) {
118072
118171
  projectId = await getProjectIdentityAliasResolver().resolve(projectId);
118073
118172
  const content = await fs15.readFile(filePath, "utf-8");
118074
- const relativePath = path21.relative(projectRoot, filePath);
118173
+ const relativePath = path22.relative(projectRoot, filePath);
118075
118174
  const maxFileSize = config.get("security").maxFileSize || 1024 * 1024;
118076
118175
  if (content.length > maxFileSize) {
118077
118176
  logger.warn("File too large, skipping", {
@@ -118091,7 +118190,7 @@ async function indexFile(deps, filePath, projectId, projectRoot, centralityMap)
118091
118190
  chunkIndex: i,
118092
118191
  totalChunks: chunks.length,
118093
118192
  type: chunk.type,
118094
- language: path21.extname(filePath).slice(1),
118193
+ language: path22.extname(filePath).slice(1),
118095
118194
  lineStart: chunk.lineStart,
118096
118195
  lineEnd: chunk.lineEnd,
118097
118196
  label: chunk.label,
@@ -118116,6 +118215,7 @@ var init_project_indexer = __esm(() => {
118116
118215
  init_managed_run_repository_pg();
118117
118216
  init_symbol_repo_workspace();
118118
118217
  init_embedding_freshness();
118218
+ init_incremental_reindex();
118119
118219
  globAsync2 = glob;
118120
118220
  });
118121
118221
 
@@ -120483,7 +120583,7 @@ __export(exports_memory_consolidation_job, {
120483
120583
  memoryConsolidationJob: () => memoryConsolidationJob,
120484
120584
  MemoryConsolidationJob: () => MemoryConsolidationJob
120485
120585
  });
120486
- import { randomUUID as randomUUID4 } from "crypto";
120586
+ import { randomUUID as randomUUID5 } from "crypto";
120487
120587
  async function addSupercedesEdge(store2, newId, sourceId, batchId) {
120488
120588
  const evidence = JSON.stringify({ batchId, consolidated: true });
120489
120589
  await store2.createEdge({
@@ -120627,11 +120727,11 @@ class MemoryConsolidationJob {
120627
120727
  });
120628
120728
  return { merged: 0, batchesCreated: 0 };
120629
120729
  }
120630
- const batch = await consolidateWindow(rowsToCandidates(candidates), this.llm, { idFactory: () => `batch-${now2}-${randomUUID4().slice(0, 8)}` }).catch(() => null);
120730
+ const batch = await consolidateWindow(rowsToCandidates(candidates), this.llm, { idFactory: () => `batch-${now2}-${randomUUID5().slice(0, 8)}` }).catch(() => null);
120631
120731
  if (!batch)
120632
120732
  return { merged: 0, batchesCreated: 0 };
120633
120733
  const sourceRows = candidates.filter((c) => batch.sourceIds.includes(c.id));
120634
- const newId = `mem-${now2}-${randomUUID4().slice(0, 8)}`;
120734
+ const newId = `mem-${now2}-${randomUUID5().slice(0, 8)}`;
120635
120735
  const importance = sourceRows.length ? Math.min(1, Math.max(...sourceRows.map((r) => r.importance))) : 0.7;
120636
120736
  const projectId = sourceRows.find((r) => r.project_id)?.project_id ?? null;
120637
120737
  try {
@@ -121828,8 +121928,8 @@ function toSymbolIdentityResolution(result) {
121828
121928
 
121829
121929
  class DefinitionLookupService {
121830
121930
  repository;
121831
- constructor(repository = getSymbolRepository) {
121832
- this.repository = repository;
121931
+ constructor(repository2 = getSymbolRepository) {
121932
+ this.repository = repository2;
121833
121933
  }
121834
121934
  async lookup(projectId, query) {
121835
121935
  const repo = this.repository();
@@ -121939,7 +122039,7 @@ class WorkspaceManager {
121939
122039
  return matches[0];
121940
122040
  }
121941
122041
  async removeWorkspace(projectId) {
121942
- await getSymbolRepository().clearProject(projectId);
122042
+ await withHeavyWorkLease("maintenance", `workspace-remove:${projectId}`, () => getSymbolRepository().clearProject(projectId));
121943
122043
  logger.info("WorkspaceManager: workspace removed", { projectId });
121944
122044
  }
121945
122045
  subscribeToEvents() {
@@ -121964,6 +122064,7 @@ var init_workspace_manager = __esm(() => {
121964
122064
  init_symbol_repository_factory();
121965
122065
  init_event_bus();
121966
122066
  init_symbol_graph_service();
122067
+ init_heavy_work_lease();
121967
122068
  workspaceManager = WorkspaceManager.getInstance();
121968
122069
  });
121969
122070
 
@@ -122649,16 +122750,16 @@ function detectRoutes(httpEdges, defs, opts = {}) {
122649
122750
  const seen = new Set;
122650
122751
  const out = [];
122651
122752
  for (const e of httpEdges) {
122652
- const path22 = e.route;
122653
- if (!path22)
122753
+ const path23 = e.route;
122754
+ if (!path23)
122654
122755
  continue;
122655
122756
  const method = (e.method ?? "ANY").toUpperCase();
122656
- const key = method + " " + path22;
122757
+ const key = method + " " + path23;
122657
122758
  if (seen.has(key))
122658
122759
  continue;
122659
122760
  seen.add(key);
122660
122761
  out.push({
122661
- path: path22,
122762
+ path: path23,
122662
122763
  method: e.method,
122663
122764
  file: e.fromFile,
122664
122765
  handler: e.targetFqn ?? e.symbolName
@@ -122669,12 +122770,12 @@ function detectRoutes(httpEdges, defs, opts = {}) {
122669
122770
  continue;
122670
122771
  const parsed = parseRouteName(d.name);
122671
122772
  const method = parsed?.method ?? "ANY";
122672
- const path22 = parsed?.path ?? d.name;
122673
- const key = method + " " + path22;
122773
+ const path23 = parsed?.path ?? d.name;
122774
+ const key = method + " " + path23;
122674
122775
  if (seen.has(key))
122675
122776
  continue;
122676
122777
  seen.add(key);
122677
- out.push({ path: path22, method: parsed?.method, file: d.filePath, handler: d.name });
122778
+ out.push({ path: path23, method: parsed?.method, file: d.filePath, handler: d.name });
122678
122779
  }
122679
122780
  for (const d of defs) {
122680
122781
  const parsed = parseRouteName(d.name);
@@ -122895,7 +122996,7 @@ __export(exports_symbol_graph_service, {
122895
122996
  symbolGraphService: () => symbolGraphService,
122896
122997
  SymbolGraphService: () => SymbolGraphService
122897
122998
  });
122898
- import path22 from "path";
122999
+ import path23 from "path";
122899
123000
  import fs16 from "fs/promises";
122900
123001
 
122901
123002
  class SymbolGraphService {
@@ -123249,7 +123350,7 @@ class SymbolGraphService {
123249
123350
  }
123250
123351
  async resolveToAbsolute(relativePath, projectId) {
123251
123352
  const root = await this.getProjectRoot(projectId);
123252
- return root ? path22.resolve(root, relativePath) : relativePath;
123353
+ return root ? path23.resolve(root, relativePath) : relativePath;
123253
123354
  }
123254
123355
  async getProjectRoot(projectId) {
123255
123356
  const cached2 = this.projectRootCache.get(projectId);
@@ -125032,31 +125133,31 @@ class TracePathService {
125032
125133
  const chains = [];
125033
125134
  const seen = new Set;
125034
125135
  let walks = 0;
125035
- const walk = (fqn, path23) => {
125136
+ const walk = (fqn, path24) => {
125036
125137
  if (chains.length >= CHAIN_CAP)
125037
125138
  return;
125038
125139
  if (walks >= MAX_WALKS)
125039
125140
  return;
125040
125141
  walks++;
125041
- const key = path23.join("\u2192");
125142
+ const key = path24.join("\u2192");
125042
125143
  if (seen.has(key))
125043
125144
  return;
125044
125145
  seen.add(key);
125045
125146
  const next = adj.get(fqn);
125046
125147
  if (!next || next.length === 0 || !whoHasChild.has(fqn)) {
125047
- if (path23.length > 1)
125048
- chains.push(path23.map((n) => this.fqnToName(n)).join(" \u2192 "));
125148
+ if (path24.length > 1)
125149
+ chains.push(path24.map((n) => this.fqnToName(n)).join(" \u2192 "));
125049
125150
  return;
125050
125151
  }
125051
125152
  for (const child of next) {
125052
125153
  if (chains.length >= CHAIN_CAP || walks >= MAX_WALKS)
125053
125154
  return;
125054
- if (path23.includes(child)) {
125055
- const cycled = [...path23, `${this.fqnToName(child)}\u21BA`];
125155
+ if (path24.includes(child)) {
125156
+ const cycled = [...path24, `${this.fqnToName(child)}\u21BA`];
125056
125157
  chains.push(cycled.map((n) => n).join(" \u2192 "));
125057
125158
  continue;
125058
125159
  }
125059
- walk(child, [...path23, child]);
125160
+ walk(child, [...path24, child]);
125060
125161
  }
125061
125162
  };
125062
125163
  for (const seed of seeds) {
@@ -126778,12 +126879,13 @@ function createProjectIdentityService(options = {}) {
126778
126879
  }
126779
126880
  },
126780
126881
  apply(input) {
126781
- return applyService.apply(input);
126882
+ return withHeavyWorkLease("maintenance", "project-identity", () => applyService.apply(input));
126782
126883
  }
126783
126884
  };
126784
126885
  }
126785
126886
  var init_service = __esm(() => {
126786
126887
  init_db_connection();
126888
+ init_heavy_work_lease();
126787
126889
  init_apply();
126788
126890
  init_errors4();
126789
126891
  init_planner();
@@ -127081,7 +127183,7 @@ var init_inference_probe = __esm(() => {
127081
127183
  // ../../packages/core/dist/services/health/local-health-checker.js
127082
127184
  import fs17 from "fs/promises";
127083
127185
  import { existsSync as existsSync3 } from "fs";
127084
- import path23 from "path";
127186
+ import path24 from "path";
127085
127187
 
127086
127188
  class LocalHealthChecker {
127087
127189
  dataDir = config.get("dataDir");
@@ -127160,7 +127262,7 @@ class LocalHealthChecker {
127160
127262
  try {
127161
127263
  if (!existsSync3(this.dataDir))
127162
127264
  await fs17.mkdir(this.dataDir, { recursive: true });
127163
- const probe = path23.join(this.dataDir, ".health-check-test");
127265
+ const probe = path24.join(this.dataDir, ".health-check-test");
127164
127266
  await fs17.writeFile(probe, "ok");
127165
127267
  await fs17.unlink(probe);
127166
127268
  return { available: true, latency: Date.now() - start, details: { path: this.dataDir, writable: true } };
@@ -127550,7 +127652,7 @@ var init_index_job_store = __esm(() => {
127550
127652
  });
127551
127653
 
127552
127654
  // ../../packages/core/dist/services/jobs/index-job-tracker.js
127553
- import { randomUUID as randomUUID5 } from "crypto";
127655
+ import { randomUUID as randomUUID6 } from "crypto";
127554
127656
 
127555
127657
  class IndexJobTracker {
127556
127658
  static instance;
@@ -127574,7 +127676,7 @@ class IndexJobTracker {
127574
127676
  return IndexJobTracker.instance;
127575
127677
  }
127576
127678
  createJob(projectId, projectPath) {
127577
- const jobId = randomUUID5();
127679
+ const jobId = randomUUID6();
127578
127680
  const job = {
127579
127681
  jobId,
127580
127682
  projectId,
@@ -127664,7 +127766,9 @@ class IndexJobTracker {
127664
127766
  const cutoff = now2 - staleMs;
127665
127767
  let reaped = 0;
127666
127768
  for (const job of running) {
127667
- const hbMs = job.heartbeatAt?.getTime();
127769
+ const live = this.jobs.get(job.jobId);
127770
+ const liveHb = live?.heartbeatAt?.getTime();
127771
+ const hbMs = liveHb ?? job.heartbeatAt?.getTime();
127668
127772
  const startedMs = job.startedAt?.getTime();
127669
127773
  const stale = hbMs != null && hbMs < cutoff || hbMs == null && startedMs != null && startedMs < cutoff;
127670
127774
  if (!stale)
@@ -128064,6 +128168,9 @@ class PgScheduledJobStore {
128064
128168
  }, "save");
128065
128169
  this.ensureHydrated();
128066
128170
  }
128171
+ async ready() {
128172
+ await this.ensureHydrated();
128173
+ }
128067
128174
  get(id) {
128068
128175
  this.ensureHydrated();
128069
128176
  return this.mirror.get(id) ?? null;
@@ -128140,10 +128247,18 @@ class Scheduler {
128140
128247
  handlers = new Map;
128141
128248
  cronCache = new Map;
128142
128249
  running = new Set;
128250
+ heavyWorkProbe;
128251
+ deferred = new Set;
128252
+ heavyWorkReason = null;
128253
+ lastProbeError = null;
128254
+ consecutiveProbeFailures = 0;
128255
+ evaluating = false;
128256
+ pendingTickAt = null;
128143
128257
  timer = null;
128144
128258
  started = false;
128145
128259
  constructor(opts = {}) {
128146
128260
  this.store = opts.store ?? getScheduledJobStore();
128261
+ this.heavyWorkProbe = opts.heavyWorkProbe ?? probeHeavyWork;
128147
128262
  const schedulerConfig = config.get("scheduler");
128148
128263
  this.tickIntervalMs = opts.tickIntervalMs ?? envPositiveInt(process.env.MASSA_AI_SCHEDULER_TICK_MS) ?? schedulerConfig?.tickMs ?? DEFAULTS.tickMs;
128149
128264
  this.maxConcurrent = opts.maxConcurrent ?? envPositiveInt(process.env.MASSA_AI_SCHEDULER_MAX_CONCURRENT) ?? schedulerConfig?.maxConcurrent ?? DEFAULTS.maxConcurrent;
@@ -128244,31 +128359,43 @@ class Scheduler {
128244
128359
  this.timer.unref?.();
128245
128360
  this.tick().catch(() => {});
128246
128361
  }
128247
- catchUpMissedJobs(now2 = Date.now()) {
128248
- if (!this.enabled)
128249
- return { caughtUp: 0, skipped: 0 };
128362
+ async catchUpMissedJobs(now2 = Date.now()) {
128363
+ if (!this.enabled || this.evaluating)
128364
+ return { caughtUp: 0, skipped: 0, deferred: 0 };
128365
+ this.evaluating = true;
128366
+ try {
128367
+ return await this.catchUpOnce(now2);
128368
+ } finally {
128369
+ this.evaluating = false;
128370
+ }
128371
+ }
128372
+ async catchUpOnce(now2) {
128250
128373
  const jobs = this.store.listEnabled();
128251
- let caughtUp = 0;
128252
128374
  let skipped = 0;
128375
+ const missed = [];
128253
128376
  for (const job of jobs) {
128254
128377
  if (this.running.has(job.jobKind)) {
128255
128378
  skipped++;
128256
128379
  continue;
128257
128380
  }
128258
- const overdueMs = now2 - job.nextRunAt;
128259
- if (overdueMs <= this.tickIntervalMs) {
128260
- continue;
128261
- }
128381
+ if (now2 - job.nextRunAt > this.tickIntervalMs)
128382
+ missed.push(job);
128383
+ }
128384
+ if (missed.length > 0 && await this.heavyWorkBusy()) {
128385
+ for (const job of missed)
128386
+ this.deferred.add(job.id);
128387
+ return { caughtUp: 0, skipped, deferred: missed.length };
128388
+ }
128389
+ for (const job of missed) {
128262
128390
  logger.info("Scheduler: catch-up tick for missed job", {
128263
128391
  id: job.id,
128264
128392
  name: job.name,
128265
128393
  jobKind: job.jobKind,
128266
- overdueMs
128394
+ overdueMs: now2 - job.nextRunAt
128267
128395
  });
128268
128396
  this.fireJob(job, now2);
128269
- caughtUp++;
128270
128397
  }
128271
- return { caughtUp, skipped };
128398
+ return { caughtUp: missed.length, skipped, deferred: 0 };
128272
128399
  }
128273
128400
  stop() {
128274
128401
  if (this.timer) {
@@ -128276,17 +128403,47 @@ class Scheduler {
128276
128403
  this.timer = null;
128277
128404
  }
128278
128405
  this.started = false;
128406
+ this.pendingTickAt = null;
128279
128407
  logger.info("Scheduler stopped");
128280
128408
  }
128281
128409
  isRunning() {
128282
128410
  return this.started && this.timer !== null;
128283
128411
  }
128284
128412
  async tick(now2 = Date.now()) {
128285
- const result = { evaluated: 0, fired: 0, skipped: 0, errors: 0 };
128413
+ const result = { evaluated: 0, fired: 0, skipped: 0, errors: 0, deferred: 0 };
128286
128414
  if (!this.enabled)
128287
128415
  return result;
128288
- const jobs = this.store.listEnabled();
128416
+ if (this.evaluating) {
128417
+ this.pendingTickAt = now2;
128418
+ return result;
128419
+ }
128420
+ this.evaluating = true;
128421
+ try {
128422
+ return await this.tickOnce(now2, result);
128423
+ } finally {
128424
+ this.evaluating = false;
128425
+ const pending = this.pendingTickAt;
128426
+ this.pendingTickAt = null;
128427
+ if (pending !== null) {
128428
+ this.tick(pending).catch((e) => {
128429
+ logger.warn("Scheduler tick failed (swallowed)", { error: e });
128430
+ });
128431
+ }
128432
+ }
128433
+ }
128434
+ async tickOnce(now2, result) {
128435
+ let jobs = this.store.listEnabled();
128289
128436
  result.evaluated = jobs.length;
128437
+ const due = jobs.filter((job) => !this.running.has(job.jobKind) && job.nextRunAt <= now2);
128438
+ if (due.length > 0) {
128439
+ if (await this.heavyWorkBusy()) {
128440
+ for (const job of due)
128441
+ this.deferred.add(job.id);
128442
+ result.deferred = due.length;
128443
+ return result;
128444
+ }
128445
+ jobs = this.store.listEnabled();
128446
+ }
128290
128447
  for (const job of jobs) {
128291
128448
  if (this.running.has(job.jobKind)) {
128292
128449
  result.skipped++;
@@ -128296,7 +128453,7 @@ class Scheduler {
128296
128453
  continue;
128297
128454
  }
128298
128455
  const overdueMs = now2 - job.nextRunAt;
128299
- const isMissed = overdueMs > this.tickIntervalMs;
128456
+ const isMissed = overdueMs > this.tickIntervalMs && !this.deferred.has(job.id);
128300
128457
  if (isMissed) {
128301
128458
  logger.warn("Scheduler: missed run (skipping, rescheduling)", {
128302
128459
  id: job.id,
@@ -128318,7 +128475,42 @@ class Scheduler {
128318
128475
  }
128319
128476
  return result;
128320
128477
  }
128478
+ async heavyWorkBusy() {
128479
+ let state;
128480
+ try {
128481
+ state = await this.heavyWorkProbe();
128482
+ } catch (e) {
128483
+ this.consecutiveProbeFailures++;
128484
+ this.lastProbeError = e.message;
128485
+ if (this.consecutiveProbeFailures === 1 || this.consecutiveProbeFailures % PROBE_FAILURE_WARN_EVERY === 0) {
128486
+ logger.warn("Scheduler: heavy-work probe failed; deferring due jobs", {
128487
+ consecutiveFailures: this.consecutiveProbeFailures,
128488
+ error: e
128489
+ });
128490
+ }
128491
+ return true;
128492
+ }
128493
+ this.consecutiveProbeFailures = 0;
128494
+ this.lastProbeError = null;
128495
+ if (state.busy) {
128496
+ if (this.heavyWorkReason === null) {
128497
+ logger.info("Scheduler: heavy database work in progress; deferring due jobs", {
128498
+ reason: state.reason ?? "unknown"
128499
+ });
128500
+ }
128501
+ this.heavyWorkReason = state.reason ?? "unknown";
128502
+ return true;
128503
+ }
128504
+ if (this.heavyWorkReason !== null) {
128505
+ logger.info("Scheduler: heavy database work finished; running deferred jobs", {
128506
+ deferred: this.deferred.size
128507
+ });
128508
+ this.heavyWorkReason = null;
128509
+ }
128510
+ return false;
128511
+ }
128321
128512
  fireJob(job, firedAt) {
128513
+ this.deferred.delete(job.id);
128322
128514
  const handler = this.handlers.get(job.jobKind);
128323
128515
  if (!handler) {
128324
128516
  logger.warn("Scheduler: no handler registered for jobKind", {
@@ -128378,6 +128570,9 @@ class Scheduler {
128378
128570
  }
128379
128571
  })();
128380
128572
  }
128573
+ async ready() {
128574
+ await this.store.ready?.();
128575
+ }
128381
128576
  status(now2 = Date.now()) {
128382
128577
  const jobs = this.store.listAll();
128383
128578
  return {
@@ -128392,10 +128587,17 @@ class Scheduler {
128392
128587
  nextRunAt: j.nextRunAt,
128393
128588
  lastRunAt: j.lastRunAt,
128394
128589
  lastSuccessAt: j.lastSuccessAt ?? null,
128590
+ lastFailureAt: j.lastFailureAt ?? null,
128395
128591
  consecutiveFailures: j.consecutiveFailures ?? 0,
128592
+ lastError: j.lastError ?? null,
128396
128593
  due: j.enabled && j.nextRunAt <= now2,
128397
- currentlyRunning: this.running.has(j.jobKind)
128398
- }))
128594
+ currentlyRunning: this.running.has(j.jobKind),
128595
+ deferred: this.deferred.has(j.id)
128596
+ })),
128597
+ heavyWork: {
128598
+ lastProbeError: this.lastProbeError,
128599
+ consecutiveProbeFailures: this.consecutiveProbeFailures
128600
+ }
128399
128601
  };
128400
128602
  }
128401
128603
  isJobRunning(jobKind) {
@@ -128414,12 +128616,13 @@ function resetScheduler() {
128414
128616
  }
128415
128617
  resetScheduledJobStore();
128416
128618
  }
128417
- var DEFAULTS, cachedScheduler = null;
128619
+ var DEFAULTS, PROBE_FAILURE_WARN_EVERY = 5, cachedScheduler = null;
128418
128620
  var init_scheduler = __esm(() => {
128419
128621
  init_dist();
128420
128622
  init_config();
128421
128623
  init_scheduler_cron();
128422
128624
  init_scheduler_store_factory();
128625
+ init_heavy_work_lease();
128423
128626
  DEFAULTS = {
128424
128627
  tickMs: 60000,
128425
128628
  maxConcurrent: 2
@@ -129328,7 +129531,7 @@ var init_auto_improve_llm = __esm(() => {
129328
129531
  });
129329
129532
 
129330
129533
  // ../../packages/core/dist/services/jobs/auto-improve-apply.js
129331
- import { randomUUID as randomUUID6 } from "crypto";
129534
+ import { randomUUID as randomUUID7 } from "crypto";
129332
129535
  function validateCreatePayload(p) {
129333
129536
  if ("type" in p && p.type !== undefined && p.type !== null) {
129334
129537
  if (typeof p.type !== "string" || !VALID_MEMORY_TYPES.has(p.type)) {
@@ -129369,7 +129572,7 @@ function buildUpdatePatch(p) {
129369
129572
  return patch;
129370
129573
  }
129371
129574
  async function applyProposal(job, record2) {
129372
- const memId = record2.targetMemoryId ?? `proposal-mem-${record2.id}-${randomUUID6().slice(0, 8)}`;
129575
+ const memId = record2.targetMemoryId ?? `proposal-mem-${record2.id}-${randomUUID7().slice(0, 8)}`;
129373
129576
  const p = record2.payload;
129374
129577
  if (record2.kind === "memory.create") {
129375
129578
  validateCreatePayload(p);
@@ -129636,8 +129839,8 @@ __export(exports_auto_improve_job, {
129636
129839
 
129637
129840
  class AutoImproveJob {
129638
129841
  llm;
129639
- observationStore;
129640
- proposalStore;
129842
+ injectedObservationStore;
129843
+ injectedProposalStore;
129641
129844
  memoryRepo;
129642
129845
  thresholds;
129643
129846
  minObservations;
@@ -129648,10 +129851,16 @@ class AutoImproveJob {
129648
129851
  lastRunAt = 0;
129649
129852
  newSinceRun = 0;
129650
129853
  runCalls = 0;
129854
+ get observationStore() {
129855
+ return this.injectedObservationStore ?? getObservationStore();
129856
+ }
129857
+ get proposalStore() {
129858
+ return this.injectedProposalStore ?? getProposalStore();
129859
+ }
129651
129860
  constructor(opts = {}) {
129652
129861
  this.llm = opts.llm ?? llm;
129653
- this.observationStore = opts.observationStore ?? getObservationStore();
129654
- this.proposalStore = opts.proposalStore ?? getProposalStore();
129862
+ this.injectedObservationStore = opts.observationStore;
129863
+ this.injectedProposalStore = opts.proposalStore;
129655
129864
  this.thresholds = { ...DEFAULT_THRESHOLDS, ...opts.thresholds };
129656
129865
  this.reviewGateOverride = opts.reviewGate;
129657
129866
  this.idFactory = opts.idFactory ?? (() => newProposalId());
@@ -129731,7 +129940,7 @@ __export(exports_observation_consolidation_job, {
129731
129940
  observationConsolidationJob: () => observationConsolidationJob,
129732
129941
  ObservationConsolidationJob: () => ObservationConsolidationJob
129733
129942
  });
129734
- import { randomUUID as randomUUID7 } from "crypto";
129943
+ import { randomUUID as randomUUID8 } from "crypto";
129735
129944
  function readBridgeConfig() {
129736
129945
  try {
129737
129946
  const c = config.get("hooks")?.bridge;
@@ -129749,7 +129958,7 @@ function readBridgeConfig() {
129749
129958
 
129750
129959
  class ObservationConsolidationJob {
129751
129960
  llm;
129752
- store;
129961
+ injectedStore;
129753
129962
  memoryRepo;
129754
129963
  minObservations;
129755
129964
  minIntervalMs;
@@ -129757,9 +129966,12 @@ class ObservationConsolidationJob {
129757
129966
  lastRunAt = 0;
129758
129967
  newSinceRun = 0;
129759
129968
  runCalls = 0;
129969
+ get store() {
129970
+ return this.injectedStore ?? getObservationStore();
129971
+ }
129760
129972
  constructor(opts = {}) {
129761
129973
  this.llm = opts.llm ?? llm;
129762
- this.store = opts.store ?? getObservationStore();
129974
+ this.injectedStore = opts.store;
129763
129975
  const injected = opts.memoryRepo;
129764
129976
  this.memoryRepo = injected ?? { insert: (i) => getMemoryRepository().insert(i) };
129765
129977
  const cfg = readBridgeConfig();
@@ -129821,7 +130033,7 @@ class ObservationConsolidationJob {
129821
130033
  if (observations.length < 2)
129822
130034
  return noop2;
129823
130035
  const window2 = observations.slice(0, this.maxWindow);
129824
- const batchId = `obs-batch-${Date.now()}-${randomUUID7().slice(0, 8)}`;
130036
+ const batchId = `obs-batch-${Date.now()}-${randomUUID8().slice(0, 8)}`;
129825
130037
  const prompt = buildObservationPrompt(window2);
129826
130038
  let batch;
129827
130039
  try {
@@ -129847,7 +130059,7 @@ class ObservationConsolidationJob {
129847
130059
  }
129848
130060
  if (!batch)
129849
130061
  return noop2;
129850
- const newId = `mem-${Date.now()}-${randomUUID7().slice(0, 8)}`;
130062
+ const newId = `mem-${Date.now()}-${randomUUID8().slice(0, 8)}`;
129851
130063
  const importance = 0.7;
129852
130064
  try {
129853
130065
  await Promise.resolve(this.memoryRepo.insert({
@@ -130465,7 +130677,7 @@ var init_scheduler2 = __esm(() => {
130465
130677
  // ../../packages/core/dist/services/pricing/models-dev-client.js
130466
130678
  import fs18 from "fs/promises";
130467
130679
  import { existsSync as existsSync4 } from "fs";
130468
- import path24 from "path";
130680
+ import path25 from "path";
130469
130681
  function getModelsDevClient() {
130470
130682
  if (!clientInstance) {
130471
130683
  clientInstance = new ModelsDevClient;
@@ -130485,7 +130697,7 @@ var init_models_dev_client = __esm(() => {
130485
130697
  memoryCacheTimestamp = 0;
130486
130698
  getLocalCachePath() {
130487
130699
  const dataDir = config.get("dataDir");
130488
- return path24.join(dataDir, ModelsDevClient.LOCAL_CACHE_FILE);
130700
+ return path25.join(dataDir, ModelsDevClient.LOCAL_CACHE_FILE);
130489
130701
  }
130490
130702
  async loadLocalCache() {
130491
130703
  const cachePath = this.getLocalCachePath();
@@ -130520,7 +130732,7 @@ var init_models_dev_client = __esm(() => {
130520
130732
  async saveLocalCache(models) {
130521
130733
  const cachePath = this.getLocalCachePath();
130522
130734
  try {
130523
- const dir = path24.dirname(cachePath);
130735
+ const dir = path25.dirname(cachePath);
130524
130736
  await fs18.mkdir(dir, { recursive: true });
130525
130737
  const data = {
130526
130738
  timestamp: Date.now(),
@@ -131462,7 +131674,7 @@ function stripNul(content) {
131462
131674
 
131463
131675
  // ../../packages/core/dist/services/etl/stages/discover.js
131464
131676
  import fs19 from "fs/promises";
131465
- import path25 from "path";
131677
+ import path26 from "path";
131466
131678
  import { createHash as createHash8 } from "crypto";
131467
131679
 
131468
131680
  class DiscoverStage {
@@ -131488,7 +131700,7 @@ class DiscoverStage {
131488
131700
  dot: false,
131489
131701
  absolute: false
131490
131702
  });
131491
- relPaths = found.map((p) => path25.isAbsolute(p) ? path25.relative(ctx.projectPath, p) : p).filter((p) => !ig.ignores(p) && applyPolicy(p, policy) !== "Drop");
131703
+ relPaths = found.map((p) => path26.isAbsolute(p) ? path26.relative(ctx.projectPath, p) : p).filter((p) => !ig.ignores(p) && applyPolicy(p, policy) !== "Drop");
131492
131704
  }
131493
131705
  if (ctx.resumeCursor?.path) {
131494
131706
  const cursorPath = ctx.resumeCursor.path;
@@ -131547,7 +131759,7 @@ class DiscoverStage {
131547
131759
  return discovered;
131548
131760
  }
131549
131761
  async processFile(ctx, relativePath, forceReindex) {
131550
- const absolutePath = path25.join(ctx.projectPath, relativePath);
131762
+ const absolutePath = path26.join(ctx.projectPath, relativePath);
131551
131763
  try {
131552
131764
  const stat = await fs19.stat(absolutePath);
131553
131765
  const content = stripNul(await fs19.readFile(absolutePath, "utf-8"));
@@ -131594,7 +131806,7 @@ class DiscoverStage {
131594
131806
  ig.add(pattern);
131595
131807
  }
131596
131808
  try {
131597
- const gitignorePath = path25.join(projectPath, ".gitignore");
131809
+ const gitignorePath = path26.join(projectPath, ".gitignore");
131598
131810
  const gitignoreContent = await fs19.readFile(gitignorePath, "utf8");
131599
131811
  const rules = gitignoreContent.split(`
131600
131812
  `).map((line) => line.trim()).filter((line) => line && !line.startsWith("#"));
@@ -132950,8 +133162,8 @@ function rustUseLeaves(node, source, prefix = []) {
132950
133162
  }
132951
133163
  if (node.type === "use_wildcard")
132952
133164
  return [{ path: [...prefix, "*"], glob: true }];
132953
- const path26 = rustPathSegments(node, source);
132954
- return path26.length ? [{ path: [...prefix, ...path26] }] : [];
133165
+ const path27 = rustPathSegments(node, source);
133166
+ return path27.length ? [{ path: [...prefix, ...path27] }] : [];
132955
133167
  }
132956
133168
  function functionalCaptures(captures, source, family) {
132957
133169
  if (family !== "clojure")
@@ -133923,7 +134135,7 @@ var init_structural_runtime = __esm(() => {
133923
134135
  });
133924
134136
 
133925
134137
  // ../../packages/core/dist/services/etl/stages/parse.js
133926
- import path26 from "path";
134138
+ import path27 from "path";
133927
134139
  import fs20 from "fs/promises";
133928
134140
  function resolveChunkerMaxChars() {
133929
134141
  const global2 = Number(process.env.EMBEDDING_MAX_CHARS);
@@ -133952,8 +134164,8 @@ class ParseStage {
133952
134164
  const results = new Map;
133953
134165
  let processed = 0;
133954
134166
  const phases = [
133955
- files.filter((file2) => path26.extname(file2.relativePath).toLowerCase() !== ".h"),
133956
- files.filter((file2) => path26.extname(file2.relativePath).toLowerCase() === ".h")
134167
+ files.filter((file2) => path27.extname(file2.relativePath).toLowerCase() !== ".h"),
134168
+ files.filter((file2) => path27.extname(file2.relativePath).toLowerCase() === ".h")
133957
134169
  ];
133958
134170
  const batches = phases.flatMap((phase) => Array.from({ length: Math.ceil(phase.length / BATCH_SIZE) }, (_, index) => phase.slice(index * BATCH_SIZE, (index + 1) * BATCH_SIZE)));
133959
134171
  for (const batch of batches) {
@@ -133991,19 +134203,19 @@ class ParseStage {
133991
134203
  return files.map((file2) => results.get(file2.relativePath));
133992
134204
  }
133993
134205
  recordHeaderImporterEvidence(ctx, files, parsedFiles) {
133994
- const knownHeaders = new Set(files.filter((file2) => path26.extname(file2.relativePath).toLowerCase() === ".h").map((file2) => path26.posix.normalize(file2.relativePath)));
134206
+ const knownHeaders = new Set(files.filter((file2) => path27.extname(file2.relativePath).toLowerCase() === ".h").map((file2) => path27.posix.normalize(file2.relativePath)));
133995
134207
  const mutable = {
133996
134208
  ...ctx.structuralHeaderEvidenceByFile
133997
134209
  };
133998
134210
  for (const parsed of parsedFiles) {
133999
- const extension = path26.extname(parsed.file.relativePath).toLowerCase();
134211
+ const extension = path27.extname(parsed.file.relativePath).toLowerCase();
134000
134212
  const key = extension === ".c" ? "cImporters" : [".cpp", ".hpp"].includes(extension) ? "cppImporters" : undefined;
134001
134213
  if (!key)
134002
134214
  continue;
134003
134215
  for (const imported of parsed.rawImports) {
134004
134216
  if (!["c_include", "cpp_include"].includes(imported.form) || imported.specifier.startsWith("<"))
134005
134217
  continue;
134006
- const header = path26.posix.normalize(path26.posix.join(path26.posix.dirname(parsed.file.relativePath), imported.specifier));
134218
+ const header = path27.posix.normalize(path27.posix.join(path27.posix.dirname(parsed.file.relativePath), imported.specifier));
134007
134219
  if (!knownHeaders.has(header))
134008
134220
  continue;
134009
134221
  const existing = mutable[header] ?? {};
@@ -134014,7 +134226,7 @@ class ParseStage {
134014
134226
  }
134015
134227
  async parseFile(ctx, file2) {
134016
134228
  if (!file2.needsReparse) {
134017
- const extension = path26.extname(file2.relativePath).toLowerCase();
134229
+ const extension = path27.extname(file2.relativePath).toLowerCase();
134018
134230
  if ([".c", ".cpp", ".hpp"].includes(extension)) {
134019
134231
  const content = file2.snapshotContent ?? await fs20.readFile(file2.absolutePath, "utf8");
134020
134232
  const outcome = await this.runtime.parse({ extension, source: Buffer.from(content) });
@@ -134029,7 +134241,7 @@ class ParseStage {
134029
134241
  }
134030
134242
  try {
134031
134243
  const content = file2.snapshotContent ?? await fs20.readFile(file2.absolutePath, "utf-8");
134032
- const ext2 = path26.extname(file2.relativePath).toLowerCase();
134244
+ const ext2 = path27.extname(file2.relativePath).toLowerCase();
134033
134245
  const chunkerMaxChars = resolveChunkerMaxChars();
134034
134246
  const chunks = smartChunk(content, file2.relativePath, chunkerMaxChars ? { maxChunkChars: chunkerMaxChars } : {});
134035
134247
  let symbols;
@@ -134584,7 +134796,7 @@ var init_resolver = __esm(() => {
134584
134796
  });
134585
134797
 
134586
134798
  // ../../packages/core/dist/services/structural/resolvers/typescript.js
134587
- import path27 from "path";
134799
+ import path28 from "path";
134588
134800
  function candidates(identities) {
134589
134801
  return Object.freeze(identities.map((identity) => Object.freeze({
134590
134802
  fqn: identity.fqn,
@@ -134679,7 +134891,7 @@ function probe(base, known, dialect = "typescript") {
134679
134891
  const bases = /\.[cm]?jsx?$/u.test(base) ? [base.replace(/\.[cm]?jsx?$/u, ".ts"), base.replace(/\.[cm]?jsx?$/u, ".tsx"), base] : [base];
134680
134892
  for (const candidateBase of bases)
134681
134893
  for (const suffix of DIALECT_PROBES[dialect] ?? [""]) {
134682
- const value = path27.posix.normalize(`${candidateBase}${suffix}`);
134894
+ const value = path28.posix.normalize(`${candidateBase}${suffix}`);
134683
134895
  if (!value.startsWith("../") && value !== ".." && known.has(value))
134684
134896
  return value;
134685
134897
  }
@@ -134688,7 +134900,7 @@ function probe(base, known, dialect = "typescript") {
134688
134900
  function resolveStructuralSpecifier(specifier, fromFile, build, dialect = "typescript") {
134689
134901
  const known = new Set(build.knownFiles.map(normalizeStructuralFile));
134690
134902
  if (specifier.startsWith("./") || specifier.startsWith("../")) {
134691
- return probe(path27.posix.join(path27.posix.dirname(fromFile), specifier), known, dialect);
134903
+ return probe(path28.posix.join(path28.posix.dirname(fromFile), specifier), known, dialect);
134692
134904
  }
134693
134905
  const aliases = build.pathAliasesByFile?.[normalizeStructuralFile(fromFile)] ?? build.pathAliases ?? [];
134694
134906
  for (const alias of aliases) {
@@ -134952,7 +135164,7 @@ var init_scripting2 = __esm(() => {
134952
135164
  });
134953
135165
 
134954
135166
  // ../../packages/core/dist/services/structural/resolvers/systems.js
134955
- import path28 from "path";
135167
+ import path29 from "path";
134956
135168
  var DIALECTS, SYSTEMS_LANGUAGE_RESOLVER;
134957
135169
  var init_systems2 = __esm(() => {
134958
135170
  init_typescript2();
@@ -134971,7 +135183,7 @@ var init_systems2 = __esm(() => {
134971
135183
  const bindings = item.bindings.map((binding) => binding.imported === "*" && binding.local === "*" && unresolvedTarget && !unresolvedTarget.qualifier ? { ...binding, imported: unresolvedTarget.name, local: unresolvedTarget.name } : binding);
134972
135184
  if (item.specifier === "crate" || item.specifier.startsWith("crate/")) {
134973
135185
  const crateRoot = file2.file.startsWith("src/") ? "src" : "";
134974
- return { ...item, bindings, specifier: `./${path28.posix.relative(path28.posix.dirname(file2.file), path28.posix.join(crateRoot, item.specifier.replace(/^crate\/?/u, "")))}` };
135186
+ return { ...item, bindings, specifier: `./${path29.posix.relative(path29.posix.dirname(file2.file), path29.posix.join(crateRoot, item.specifier.replace(/^crate\/?/u, "")))}` };
134975
135187
  }
134976
135188
  if (item.specifier === "self" || item.specifier.startsWith("self/"))
134977
135189
  return { ...item, bindings, specifier: `./${item.specifier.replace(/^self\/?/u, "")}` };
@@ -135069,7 +135281,7 @@ var init_data_document2 = __esm(() => {
135069
135281
  });
135070
135282
 
135071
135283
  // ../../packages/core/dist/services/etl/stages/resolve.js
135072
- import path29 from "path";
135284
+ import path30 from "path";
135073
135285
  import fs21 from "fs";
135074
135286
 
135075
135287
  class ResolveStage {
@@ -135094,7 +135306,7 @@ class ResolveStage {
135094
135306
  const structuralDocuments = files.flatMap((file2) => {
135095
135307
  if (!file2.structure)
135096
135308
  return [];
135097
- const language = resolveStructuralLanguage(path29.extname(file2.file.relativePath));
135309
+ const language = resolveStructuralLanguage(path30.extname(file2.file.relativePath));
135098
135310
  if (language.status !== "supported")
135099
135311
  throw new Error(`structural_manifest_missing:${file2.file.relativePath}`);
135100
135312
  return [{
@@ -135106,13 +135318,13 @@ class ResolveStage {
135106
135318
  }];
135107
135319
  });
135108
135320
  const currentStructuralFiles = new Set(structuralDocuments.map((document2) => document2.file));
135109
- const skippedStructuralFiles = new Set(files.filter((item) => !item.file.needsReparse && STRUCTURAL_SEED_EXTENSIONS.has(path29.extname(item.file.relativePath).toLowerCase())).map((item) => item.file.relativePath));
135321
+ const skippedStructuralFiles = new Set(files.filter((item) => !item.file.needsReparse && STRUCTURAL_SEED_EXTENSIONS.has(path30.extname(item.file.relativePath).toLowerCase())).map((item) => item.file.relativePath));
135110
135322
  const pathAliasesByFile = Object.fromEntries([...knownRelPaths].map((file2) => [
135111
135323
  file2,
135112
135324
  this.structuralAliasesFor(file2, rootAliases, monorepoPackages)
135113
135325
  ]));
135114
135326
  const buildMetadata = { knownFiles: [...knownRelPaths], pathAliasesByFile };
135115
- const seedRows = repositoryDefinitions.filter((definition) => STRUCTURAL_SEED_EXTENSIONS.has(path29.extname(definition.file_path).toLowerCase())).filter((definition) => knownRelPaths.has(definition.file_path) && skippedStructuralFiles.has(definition.file_path)).filter((definition) => !currentStructuralFiles.has(definition.file_path));
135327
+ const seedRows = repositoryDefinitions.filter((definition) => STRUCTURAL_SEED_EXTENSIONS.has(path30.extname(definition.file_path).toLowerCase())).filter((definition) => knownRelPaths.has(definition.file_path) && skippedStructuralFiles.has(definition.file_path)).filter((definition) => !currentStructuralFiles.has(definition.file_path));
135116
135328
  const seedIds = new Set;
135117
135329
  for (const definition of seedRows) {
135118
135330
  if (seedIds.has(definition.id))
@@ -135209,7 +135421,7 @@ class ResolveStage {
135209
135421
  if (parsed.file !== definition.file_path) {
135210
135422
  throw new Error(`structural_repository_seed_file_mismatch:${definition.id}`);
135211
135423
  }
135212
- const language = resolveStructuralLanguage(path29.extname(definition.file_path));
135424
+ const language = resolveStructuralLanguage(path30.extname(definition.file_path));
135213
135425
  if (language.status !== "supported")
135214
135426
  throw new Error(`structural_repository_seed_language:${definition.id}`);
135215
135427
  let identity;
@@ -135261,7 +135473,7 @@ class ResolveStage {
135261
135473
  });
135262
135474
  }
135263
135475
  resolveFile(parsed, projectPath, knownRelPaths, rootAliases, monorepoPackages, symbolIndex, knownFqns) {
135264
- const fromDir = path29.dirname(path29.join(projectPath, parsed.file.relativePath));
135476
+ const fromDir = path30.dirname(path30.join(projectPath, parsed.file.relativePath));
135265
135477
  const packageAliases = this.getPackageAliases(parsed.file.relativePath, monorepoPackages);
135266
135478
  const allAliases = [...packageAliases, ...rootAliases];
135267
135479
  const resolvedImports = parsed.rawImports.map((raw2) => {
@@ -135332,7 +135544,7 @@ class ResolveStage {
135332
135544
  index.set(def.name, `${def.file_path}#${def.name}`);
135333
135545
  }
135334
135546
  } catch (err) {
135335
- const skippedStructural = files.some((file2) => !file2.file.needsReparse && STRUCTURAL_SEED_EXTENSIONS.has(path29.extname(file2.file.relativePath).toLowerCase()));
135547
+ const skippedStructural = files.some((file2) => !file2.file.needsReparse && STRUCTURAL_SEED_EXTENSIONS.has(path30.extname(file2.file.relativePath).toLowerCase()));
135336
135548
  if (skippedStructural)
135337
135549
  throw new Error("structural_repository_seed_failed", { cause: err });
135338
135550
  logger.warn("buildSymbolIndex: repo seed failed, in-batch only", {
@@ -135356,7 +135568,7 @@ class ResolveStage {
135356
135568
  }
135357
135569
  resolveSpecifier(specifier, fromDir, projectPath, knownRelPaths, aliases) {
135358
135570
  if (specifier.startsWith("./") || specifier.startsWith("../")) {
135359
- const resolved = this.probeExtensions(path29.resolve(fromDir, specifier), projectPath, knownRelPaths);
135571
+ const resolved = this.probeExtensions(path30.resolve(fromDir, specifier), projectPath, knownRelPaths);
135360
135572
  return { resolvedPath: resolved, external: false };
135361
135573
  }
135362
135574
  for (const alias of aliases) {
@@ -135364,8 +135576,8 @@ class ResolveStage {
135364
135576
  const suffix = specifier.slice(alias.prefix.length);
135365
135577
  for (const target of alias.targets) {
135366
135578
  const cleanTarget = target.replace(/\/\*$/, "");
135367
- const basePath = alias.packagePath ? path29.join(projectPath, alias.packagePath) : projectPath;
135368
- const absPath = path29.join(basePath, cleanTarget + suffix);
135579
+ const basePath = alias.packagePath ? path30.join(projectPath, alias.packagePath) : projectPath;
135580
+ const absPath = path30.join(basePath, cleanTarget + suffix);
135369
135581
  const resolved = this.probeExtensions(absPath, projectPath, knownRelPaths);
135370
135582
  if (resolved)
135371
135583
  return { resolvedPath: resolved, external: false };
@@ -135381,7 +135593,7 @@ class ResolveStage {
135381
135593
  ...TS_EXTENSIONS.map((ext2) => absPath.replace(/\.[^.]+$/, ext2))
135382
135594
  ];
135383
135595
  for (const candidate2 of candidates2) {
135384
- const rel = path29.relative(projectPath, candidate2).replace(/\\/g, "/");
135596
+ const rel = path30.relative(projectPath, candidate2).replace(/\\/g, "/");
135385
135597
  if (knownRelPaths.has(rel))
135386
135598
  return rel;
135387
135599
  }
@@ -135389,7 +135601,7 @@ class ResolveStage {
135389
135601
  }
135390
135602
  loadTsConfigPaths(projectPath, packageBase) {
135391
135603
  const aliases = [];
135392
- const tsconfigPath = path29.join(projectPath, "tsconfig.json");
135604
+ const tsconfigPath = path30.join(projectPath, "tsconfig.json");
135393
135605
  try {
135394
135606
  const raw2 = fs21.readFileSync(tsconfigPath, "utf-8");
135395
135607
  const stripped = raw2.replace(/\/\/[^\n]*/g, "").replace(/\/\*[\s\S]*?\*\//g, "");
@@ -135420,7 +135632,7 @@ class ResolveStage {
135420
135632
  }
135421
135633
  }
135422
135634
  for (const packageRelPath of packagePaths) {
135423
- const absPackagePath = path29.join(projectPath, packageRelPath);
135635
+ const absPackagePath = path30.join(projectPath, packageRelPath);
135424
135636
  const aliases = this.loadTsConfigPaths(absPackagePath, packageRelPath);
135425
135637
  if (aliases.length > 0) {
135426
135638
  packages.push({
@@ -135450,7 +135662,7 @@ class ResolveStage {
135450
135662
  structuralAliasesFor(filePath, rootAliases, packages) {
135451
135663
  return [...this.getPackageAliases(filePath, packages), ...rootAliases].map((alias) => ({
135452
135664
  pattern: alias.prefix + (alias.targets.some((target) => target.includes("*")) ? "/*" : ""),
135453
- targets: alias.targets.map((target) => alias.packagePath ? path29.posix.join(alias.packagePath, target) : target)
135665
+ targets: alias.targets.map((target) => alias.packagePath ? path30.posix.join(alias.packagePath, target) : target)
135454
135666
  }));
135455
135667
  }
135456
135668
  }
@@ -135514,7 +135726,7 @@ var init_with_deadlock_retry = __esm(() => {
135514
135726
  });
135515
135727
 
135516
135728
  // ../../packages/core/dist/services/etl/stages/load.js
135517
- import path30 from "path";
135729
+ import path31 from "path";
135518
135730
  function formatDuration(ms) {
135519
135731
  const totalSec = Math.max(0, Math.round(ms / 1000));
135520
135732
  if (totalSec < 60)
@@ -135791,7 +136003,7 @@ class LoadStage {
135791
136003
  const filePath = file2.file.relativePath;
135792
136004
  const batch = buildSymbolPersistenceBatch(ctx.projectId, file2);
135793
136005
  if (ctx.graphGenerationLease) {
135794
- const manifest = getLanguageManifestEntry(path30.extname(filePath));
136006
+ const manifest = getLanguageManifestEntry(path31.extname(filePath));
135795
136007
  const diagnostics2 = (file2.structuralDiagnostics ?? []).slice(0, 10).map((diagnostic2) => ({
135796
136008
  code: diagnostic2.code,
135797
136009
  severity: diagnostic2.severity,
@@ -135843,7 +136055,7 @@ var init_load = __esm(() => {
135843
136055
  });
135844
136056
 
135845
136057
  // ../../packages/core/dist/data/graph-generation/graph-generation-repository-pg.js
135846
- import { randomUUID as randomUUID8 } from "crypto";
136058
+ import { randomUUID as randomUUID9 } from "crypto";
135847
136059
  function boundedText2(value, label, max = 512) {
135848
136060
  const normalized = value.normalize("NFC").trim();
135849
136061
  if (!normalized || normalized.length > max || normalized.includes("\x00")) {
@@ -135947,8 +136159,8 @@ class GraphGenerationRepositoryPg {
135947
136159
  }
135948
136160
  async begin(rawInput) {
135949
136161
  const input = validateBegin2(rawInput);
135950
- const generationId = randomUUID8();
135951
- const leaseToken = randomUUID8();
136162
+ const generationId = randomUUID9();
136163
+ const leaseToken = randomUUID9();
135952
136164
  return getPrismaClient2().$transaction(async (tx) => {
135953
136165
  const workspace = await lockWorkspace(tx, input.projectId);
135954
136166
  if (workspace.active_graph_generation_id !== input.expectedActiveGenerationId) {
@@ -136188,8 +136400,8 @@ function buildGraphInputSnapshotHash(files) {
136188
136400
 
136189
136401
  class GraphGenerationCoordinator {
136190
136402
  repository;
136191
- constructor(repository = getGraphGenerationRepository()) {
136192
- this.repository = repository;
136403
+ constructor(repository2 = getGraphGenerationRepository()) {
136404
+ this.repository = repository2;
136193
136405
  }
136194
136406
  async begin(input) {
136195
136407
  const deadline = Date.now() + GRAPH_GENERATION_LEASE_TTL_MS;
@@ -136247,10 +136459,10 @@ var init_graph_generation_coordinator = __esm(() => {
136247
136459
 
136248
136460
  // ../../packages/core/dist/services/etl/pipeline.js
136249
136461
  import { createHash as createHash10 } from "crypto";
136250
- import { setTimeout as delay2 } from "timers/promises";
136251
- import path31 from "path";
136462
+ import { setTimeout as delay3 } from "timers/promises";
136463
+ import path32 from "path";
136252
136464
  function buildHeaderLanguageEvidence(files) {
136253
- const headers = new Set(files.filter((file2) => path31.posix.extname(file2.relativePath).toLowerCase() === ".h").map((file2) => path31.posix.normalize(file2.relativePath)));
136465
+ const headers = new Set(files.filter((file2) => path32.posix.extname(file2.relativePath).toLowerCase() === ".h").map((file2) => path32.posix.normalize(file2.relativePath)));
136254
136466
  const mutable = new Map;
136255
136467
  const entry2 = (header) => {
136256
136468
  let value = mutable.get(header);
@@ -136261,7 +136473,7 @@ function buildHeaderLanguageEvidence(files) {
136261
136473
  return value;
136262
136474
  };
136263
136475
  for (const file2 of files) {
136264
- if (path31.posix.basename(file2.relativePath) !== "compile_commands.json" || file2.snapshotContent === undefined)
136476
+ if (path32.posix.basename(file2.relativePath) !== "compile_commands.json" || file2.snapshotContent === undefined)
136265
136477
  continue;
136266
136478
  let commands;
136267
136479
  try {
@@ -136277,11 +136489,11 @@ function buildHeaderLanguageEvidence(files) {
136277
136489
  const record2 = command;
136278
136490
  if (typeof record2.file !== "string")
136279
136491
  continue;
136280
- const projectRoot = path31.resolve(file2.absolutePath, ...file2.relativePath.split("/").map(() => ".."));
136281
- const commandDirectory = typeof record2.directory === "string" ? path31.resolve(projectRoot, record2.directory) : projectRoot;
136282
- const absoluteInput = path31.resolve(commandDirectory, record2.file);
136283
- const relative3 = path31.relative(projectRoot, absoluteInput);
136284
- const header = path31.posix.normalize(relative3.replaceAll(path31.sep, "/"));
136492
+ const projectRoot = path32.resolve(file2.absolutePath, ...file2.relativePath.split("/").map(() => ".."));
136493
+ const commandDirectory = typeof record2.directory === "string" ? path32.resolve(projectRoot, record2.directory) : projectRoot;
136494
+ const absoluteInput = path32.resolve(commandDirectory, record2.file);
136495
+ const relative3 = path32.relative(projectRoot, absoluteInput);
136496
+ const header = path32.posix.normalize(relative3.replaceAll(path32.sep, "/"));
136285
136497
  if (!headers.has(header))
136286
136498
  continue;
136287
136499
  const invocation = typeof record2.command === "string" ? record2.command : Array.isArray(record2.arguments) ? record2.arguments.join(" ") : "";
@@ -136331,6 +136543,7 @@ var init_pipeline = __esm(() => {
136331
136543
  init_language_manifest();
136332
136544
  init_graph_generation_coordinator();
136333
136545
  init_managed_run_repository_pg();
136546
+ init_workspace_manager();
136334
136547
  EtlPipeline = class EtlPipeline {
136335
136548
  static instance = null;
136336
136549
  static runTails = new Map;
@@ -136446,7 +136659,7 @@ var init_pipeline = __esm(() => {
136446
136659
  managedRunHeartbeat = (async () => {
136447
136660
  while (!stopManagedRunHeartbeat) {
136448
136661
  try {
136449
- await delay2(30000, undefined, { signal: managedRunTimerController.signal });
136662
+ await delay3(30000, undefined, { signal: managedRunTimerController.signal });
136450
136663
  } catch {
136451
136664
  return;
136452
136665
  }
@@ -136467,11 +136680,25 @@ var init_pipeline = __esm(() => {
136467
136680
  }
136468
136681
  })();
136469
136682
  }
136683
+ const jobHeartbeatController = new AbortController;
136684
+ (async () => {
136685
+ while (true) {
136686
+ try {
136687
+ await delay3(30000, undefined, { signal: jobHeartbeatController.signal });
136688
+ } catch {
136689
+ return;
136690
+ }
136691
+ try {
136692
+ indexJobTracker.heartbeat(jobId);
136693
+ } catch {}
136694
+ }
136695
+ })();
136470
136696
  try {
136471
136697
  const st1 = performance.now();
136472
136698
  const discoveredSnapshot = await this.discover.run(ctx, { forceReindex, includeTests: include_tests });
136473
136699
  ctx.structuralHeaderEvidenceByFile = buildHeaderLanguageEvidence(discoveredSnapshot);
136474
136700
  stageTimings.discover = Math.round(performance.now() - st1);
136701
+ await workspaceManager.markIndexing(projectId, projectPath);
136475
136702
  const activeGraph = await getSymbolRepository().getActiveGraphSnapshot(projectId);
136476
136703
  try {
136477
136704
  graphGenerationLease = await this.graphGenerations.begin({
@@ -136485,6 +136712,7 @@ var init_pipeline = __esm(() => {
136485
136712
  if (beginError.message.startsWith("graph_generation_stale_active:") && generationRetry < 3) {
136486
136713
  stopManagedRunHeartbeat = true;
136487
136714
  managedRunTimerController.abort();
136715
+ jobHeartbeatController.abort();
136488
136716
  if (managedRunHeartbeat)
136489
136717
  await managedRunHeartbeat;
136490
136718
  return this.runInternal(input, generationRetry + 1);
@@ -136496,7 +136724,7 @@ var init_pipeline = __esm(() => {
136496
136724
  graphHeartbeat = (async () => {
136497
136725
  while (!stopGraphHeartbeat) {
136498
136726
  try {
136499
- await delay2(30000, undefined, { signal: heartbeatTimerController.signal });
136727
+ await delay3(30000, undefined, { signal: heartbeatTimerController.signal });
136500
136728
  } catch {
136501
136729
  return;
136502
136730
  }
@@ -136668,6 +136896,7 @@ var init_pipeline = __esm(() => {
136668
136896
  activatedGraphGenerationId: result.activatedGraphGenerationId
136669
136897
  });
136670
136898
  await this.graphGenerations.cleanup(graphGenerationLease);
136899
+ jobHeartbeatController.abort();
136671
136900
  stopGraphHeartbeat = true;
136672
136901
  heartbeatTimerController.abort();
136673
136902
  await graphHeartbeat;
@@ -136694,6 +136923,7 @@ var init_pipeline = __esm(() => {
136694
136923
  logger.error("EtlPipeline: pending generation abort failed", abortError, { projectId, jobId });
136695
136924
  }
136696
136925
  }
136926
+ jobHeartbeatController.abort();
136697
136927
  stopGraphHeartbeat = true;
136698
136928
  heartbeatTimerController.abort();
136699
136929
  graphAbortController.abort();
@@ -142166,33 +142396,33 @@ var require_URL = __commonJS((exports, module) => {
142166
142396
  else
142167
142397
  return basepath.substring(0, lastslash + 1) + refpath;
142168
142398
  }
142169
- function remove_dot_segments(path32) {
142170
- if (!path32)
142171
- return path32;
142399
+ function remove_dot_segments(path33) {
142400
+ if (!path33)
142401
+ return path33;
142172
142402
  var output = "";
142173
- while (path32.length > 0) {
142174
- if (path32 === "." || path32 === "..") {
142175
- path32 = "";
142403
+ while (path33.length > 0) {
142404
+ if (path33 === "." || path33 === "..") {
142405
+ path33 = "";
142176
142406
  break;
142177
142407
  }
142178
- var twochars = path32.substring(0, 2);
142179
- var threechars = path32.substring(0, 3);
142180
- var fourchars = path32.substring(0, 4);
142408
+ var twochars = path33.substring(0, 2);
142409
+ var threechars = path33.substring(0, 3);
142410
+ var fourchars = path33.substring(0, 4);
142181
142411
  if (threechars === "../") {
142182
- path32 = path32.substring(3);
142412
+ path33 = path33.substring(3);
142183
142413
  } else if (twochars === "./") {
142184
- path32 = path32.substring(2);
142414
+ path33 = path33.substring(2);
142185
142415
  } else if (threechars === "/./") {
142186
- path32 = "/" + path32.substring(3);
142187
- } else if (twochars === "/." && path32.length === 2) {
142188
- path32 = "/";
142189
- } else if (fourchars === "/../" || threechars === "/.." && path32.length === 3) {
142190
- path32 = "/" + path32.substring(4);
142416
+ path33 = "/" + path33.substring(3);
142417
+ } else if (twochars === "/." && path33.length === 2) {
142418
+ path33 = "/";
142419
+ } else if (fourchars === "/../" || threechars === "/.." && path33.length === 3) {
142420
+ path33 = "/" + path33.substring(4);
142191
142421
  output = output.replace(/\/?[^\/]*$/, "");
142192
142422
  } else {
142193
- var segment = path32.match(/(\/?([^\/]*))/)[0];
142423
+ var segment = path33.match(/(\/?([^\/]*))/)[0];
142194
142424
  output += segment;
142195
- path32 = path32.substring(segment.length);
142425
+ path33 = path33.substring(segment.length);
142196
142426
  }
142197
142427
  }
142198
142428
  return output;
@@ -154262,21 +154492,21 @@ function jsonToKeyPathChunks(value, label = "$") {
154262
154492
  walk(value, label, out);
154263
154493
  return out;
154264
154494
  }
154265
- function walk(val, path32, out) {
154495
+ function walk(val, path33, out) {
154266
154496
  if (val === null || val === undefined)
154267
154497
  return;
154268
154498
  if (Array.isArray(val)) {
154269
154499
  if (val.length === 0) {
154270
- out.push({ path: path32, content: `**${path32}** = _[]_` });
154500
+ out.push({ path: path33, content: `**${path33}** = _[]_` });
154271
154501
  return;
154272
154502
  }
154273
154503
  if (val.every((v) => v !== null && typeof v === "object")) {
154274
- val.forEach((v, i) => walk(v, `${path32}[${i}]`, out));
154504
+ val.forEach((v, i) => walk(v, `${path33}[${i}]`, out));
154275
154505
  return;
154276
154506
  }
154277
154507
  const items = val.map((v) => `- \`${String(v)}\``).join(`
154278
154508
  `);
154279
- out.push({ path: path32, content: `**${path32}**
154509
+ out.push({ path: path33, content: `**${path33}**
154280
154510
 
154281
154511
  ${items}` });
154282
154512
  return;
@@ -154284,16 +154514,16 @@ ${items}` });
154284
154514
  if (typeof val === "object") {
154285
154515
  const entries = Object.entries(val);
154286
154516
  if (entries.length === 0) {
154287
- out.push({ path: path32, content: `**${path32}** = _{}_` });
154517
+ out.push({ path: path33, content: `**${path33}** = _{}_` });
154288
154518
  return;
154289
154519
  }
154290
154520
  for (const [k, v] of entries) {
154291
154521
  const safeKey = /^[A-Za-z_$][\w$]*$/.test(k) ? k : JSON.stringify(k);
154292
- walk(v, `${path32}.${safeKey}`, out);
154522
+ walk(v, `${path33}.${safeKey}`, out);
154293
154523
  }
154294
154524
  return;
154295
154525
  }
154296
- out.push({ path: path32, content: `**${path32}** = \`${String(val)}\`` });
154526
+ out.push({ path: path33, content: `**${path33}** = \`${String(val)}\`` });
154297
154527
  }
154298
154528
  var gfm, STRIP_SELECTORS, tdCache = null;
154299
154529
  var init_html_to_md = __esm(() => {
@@ -154633,6 +154863,7 @@ var init_services = __esm(() => {
154633
154863
  init_embeddings();
154634
154864
  init_local_health_checker();
154635
154865
  init_index_job_tracker();
154866
+ init_heavy_work_lease();
154636
154867
  init_scheduler2();
154637
154868
  init_models_dev_client();
154638
154869
  init_memory_graph_service();
@@ -154721,7 +154952,7 @@ init_config();
154721
154952
  init_dist();
154722
154953
  init_inference_providers();
154723
154954
  import os9 from "os";
154724
- import path32 from "path";
154955
+ import path33 from "path";
154725
154956
  var WRITABLE_PROVIDERS = ["ollama", "lmstudio", "mistral", "openai", "google", "cohere"];
154726
154957
  var GENERATOR_MARKER = "scripts/generate-subagent-artifacts.ts";
154727
154958
  var GENERATOR_MARKER_MAX_LEVELS = 6;
@@ -154792,7 +155023,7 @@ Examples:
154792
155023
  massa-ai-config doctor
154793
155024
  massa-ai-config doctor --fix
154794
155025
  massa-ai-config bootstrap list
154795
- massa-ai-config bootstrap disable caveman
155026
+ massa-ai-config bootstrap enable code-comments
154796
155027
  `);
154797
155028
  }
154798
155029
  function parseOptions(args) {
@@ -155150,7 +155381,7 @@ Using defaults:`);
155150
155381
  return 1;
155151
155382
  }
155152
155383
  const targetOpt = typeof options.target === "string" ? options.target : undefined;
155153
- const targetHome = targetOpt === undefined ? os9.homedir() : path32.resolve(targetOpt);
155384
+ const targetHome = targetOpt === undefined ? os9.homedir() : path33.resolve(targetOpt);
155154
155385
  if (targetHome !== os9.homedir() && options.yes !== true) {
155155
155386
  console.error(`Error: --target ${targetHome} is not your home (${os9.homedir()}) \u2014 pass --yes to confirm writing there`);
155156
155387
  return 1;
@@ -155170,7 +155401,7 @@ Using defaults:`);
155170
155401
  const report = applyBootstrapState({
155171
155402
  targetHome,
155172
155403
  dryRun,
155173
- sourcePath: repoRoot === null ? undefined : path32.join(repoRoot, "skills", "AGENTS.md")
155404
+ sourcePath: repoRoot === null ? undefined : path33.join(repoRoot, "skills", "AGENTS.md")
155174
155405
  });
155175
155406
  console.log(formatBootstrapReport(report));
155176
155407
  return bootstrapReportSucceeded(report) ? 0 : 1;