@ultrst-armada/krnl 1.0.17 → 1.0.19

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.
@@ -62,8 +62,60 @@ var LifecycleManager = class {
62
62
  }
63
63
  };
64
64
 
65
- // src/telemetry/TelemetryController.ts
65
+ // src/telemetry/TelemetryInternals.ts
66
66
  import { randomUUID } from "crypto";
67
+ var createTelemetryId = (prefix) => `${prefix}_${randomUUID()}`;
68
+
69
+ // src/telemetry/TelemetrySnapshotBuilder.ts
70
+ function percentiles(values) {
71
+ if (!values.length) return { min: 0, mean: 0, p50: 0, p90: 0, p95: 0, p99: 0, max: 0 };
72
+ const sorted = [...values].sort((a, b) => a - b);
73
+ const pick = (p) => sorted[Math.min(sorted.length - 1, Math.floor((sorted.length - 1) * p))];
74
+ return {
75
+ min: sorted[0],
76
+ mean: sorted.reduce((sum, value) => sum + value, 0) / sorted.length,
77
+ p50: pick(0.5),
78
+ p90: pick(0.9),
79
+ p95: pick(0.95),
80
+ p99: pick(0.99),
81
+ max: sorted[sorted.length - 1]
82
+ };
83
+ }
84
+ function buildTelemetrySnapshot(input) {
85
+ const invocations = input.invocations.slice();
86
+ const durations = invocations.map((item) => item.durationMs);
87
+ const targetMap = /* @__PURE__ */ new Map();
88
+ for (const invocation of invocations) {
89
+ const key = `${invocation.kind}:${invocation.target}`;
90
+ const group = targetMap.get(key) ?? [];
91
+ group.push(invocation);
92
+ targetMap.set(key, group);
93
+ }
94
+ const targets = [...targetMap.values()].map((group) => ({
95
+ target: group[0].target,
96
+ kind: group[0].kind,
97
+ count: group.length,
98
+ successCount: group.filter((item) => item.status === "completed").length,
99
+ errorCount: group.filter((item) => item.status === "failed").length,
100
+ durationMs: percentiles(group.map((item) => item.durationMs)),
101
+ lastInvocationAt: group[group.length - 1]?.completedAt
102
+ }));
103
+ return {
104
+ serviceId: input.serviceId,
105
+ mode: input.mode,
106
+ capturedAt: Date.now(),
107
+ status: input.status,
108
+ totals: {
109
+ invocationCount: input.totalInvocationCount,
110
+ successCount: input.totalSuccessCount,
111
+ errorCount: input.totalErrorCount,
112
+ durationMs: percentiles(durations)
113
+ },
114
+ targets,
115
+ activeInvocations: input.activeInvocations,
116
+ recentInvocations: invocations.slice(-input.maxRecentInvocations)
117
+ };
118
+ }
67
119
 
68
120
  // src/telemetry/TelemetryResources.ts
69
121
  var runtimeProcess = typeof globalThis !== "undefined" ? globalThis.process : void 0;
@@ -103,21 +155,6 @@ function deltaResources(start, end) {
103
155
  }
104
156
 
105
157
  // src/telemetry/TelemetryController.ts
106
- var id = (prefix) => `${prefix}_${randomUUID()}`;
107
- function percentiles(values) {
108
- if (!values.length) return { min: 0, mean: 0, p50: 0, p90: 0, p95: 0, p99: 0, max: 0 };
109
- const sorted = [...values].sort((a, b) => a - b);
110
- const pick = (p) => sorted[Math.min(sorted.length - 1, Math.floor((sorted.length - 1) * p))];
111
- return {
112
- min: sorted[0],
113
- mean: sorted.reduce((sum, value) => sum + value, 0) / sorted.length,
114
- p50: pick(0.5),
115
- p90: pick(0.9),
116
- p95: pick(0.95),
117
- p99: pick(0.99),
118
- max: sorted[sorted.length - 1]
119
- };
120
- }
121
158
  var TelemetryController = class {
122
159
  constructor(serviceId, options = {}) {
123
160
  this.serviceId = serviceId;
@@ -169,9 +206,9 @@ var TelemetryController = class {
169
206
  end: () => void 0
170
207
  };
171
208
  }
172
- const invocationId = id("inv");
173
- const spanId = id("span");
174
- const traceId = parentSpanId ? this.findTraceId(parentSpanId) ?? id("trace") : id("trace");
209
+ const invocationId = createTelemetryId("inv");
210
+ const spanId = createTelemetryId("span");
211
+ const traceId = parentSpanId ? this.findTraceId(parentSpanId) ?? createTelemetryId("trace") : createTelemetryId("trace");
175
212
  const active = {
176
213
  invocationId,
177
214
  traceId,
@@ -202,39 +239,17 @@ var TelemetryController = class {
202
239
  this.lastInvocationAt = void 0;
203
240
  }
204
241
  snapshot() {
205
- const invocations = this.samples.slice();
206
- const durations = invocations.map((item) => item.durationMs);
207
- const targetMap = /* @__PURE__ */ new Map();
208
- for (const invocation of invocations) {
209
- const key = `${invocation.kind}:${invocation.target}`;
210
- const group = targetMap.get(key) ?? [];
211
- group.push(invocation);
212
- targetMap.set(key, group);
213
- }
214
- const targets = [...targetMap.values()].map((group) => ({
215
- target: group[0].target,
216
- kind: group[0].kind,
217
- count: group.length,
218
- successCount: group.filter((item) => item.status === "completed").length,
219
- errorCount: group.filter((item) => item.status === "failed").length,
220
- durationMs: percentiles(group.map((item) => item.durationMs)),
221
- lastInvocationAt: group[group.length - 1]?.completedAt
222
- }));
223
- return {
242
+ return buildTelemetrySnapshot({
224
243
  serviceId: this.serviceId,
225
244
  mode: this.mode,
226
- capturedAt: Date.now(),
245
+ invocations: this.samples,
227
246
  status: this.status(),
228
- totals: {
229
- invocationCount: this.totalInvocationCount,
230
- successCount: this.totalSuccessCount,
231
- errorCount: this.totalErrorCount,
232
- durationMs: percentiles(durations)
233
- },
234
- targets,
247
+ totalInvocationCount: this.totalInvocationCount,
248
+ totalSuccessCount: this.totalSuccessCount,
249
+ totalErrorCount: this.totalErrorCount,
235
250
  activeInvocations: this.active.size,
236
- recentInvocations: invocations.slice(-this.maxRecentInvocations)
237
- };
251
+ maxRecentInvocations: this.maxRecentInvocations
252
+ });
238
253
  }
239
254
  functionality(name) {
240
255
  return this.snapshot().targets.find((target) => target.kind === "functionality" && target.target === name);
@@ -638,22 +653,22 @@ var FunctionalityFacade = class {
638
653
  definition;
639
654
  eventBus;
640
655
  events;
641
- constructor(id2, definition, options = {}) {
642
- if (!id2 || typeof id2 !== "string") {
656
+ constructor(id, definition, options = {}) {
657
+ if (!id || typeof id !== "string") {
643
658
  throw new Error("[FunctionalityFacade] Functionality id must be a non-empty string.");
644
659
  }
645
660
  if (!definition || typeof definition.execute !== "function") {
646
- throw new Error(`[FunctionalityFacade:${id2}] Functionality must define execute().`);
661
+ throw new Error(`[FunctionalityFacade:${id}] Functionality must define execute().`);
647
662
  }
648
- this.id = id2;
649
- this.name = definition.name || id2;
663
+ this.id = id;
664
+ this.name = definition.name || id;
650
665
  this.description = definition.description || "";
651
666
  this.bubbleEvents = options.bubbleEvents ?? definition.bubbleEvents ?? true;
652
667
  this.definition = definition;
653
668
  this.eventBus = new EventBus();
654
669
  for (const reserved of ["triggered", "completed", "failed"]) {
655
670
  if (definition.events && reserved in definition.events) {
656
- throw new Error(`[FunctionalityFacade:${id2}] Event '${reserved}' is reserved for functionality lifecycle.`);
671
+ throw new Error(`[FunctionalityFacade:${id}] Event '${reserved}' is reserved for functionality lifecycle.`);
657
672
  }
658
673
  }
659
674
  const eventNames = [
@@ -767,11 +782,11 @@ var PriorityQueue = class {
767
782
  return item.run;
768
783
  }
769
784
  enqueue(run, options) {
770
- const { priority = 0, id: id2 } = options ?? {};
785
+ const { priority = 0, id } = options ?? {};
771
786
  const { size } = this;
772
787
  const element = {
773
788
  priority,
774
- id: id2,
789
+ id,
775
790
  run
776
791
  };
777
792
  if (size === 0) {
@@ -788,16 +803,16 @@ var PriorityQueue = class {
788
803
  const index = lowerBound(this.#queue, element, (a, b) => a.priority === b.priority ? 0 : b.priority - a.priority);
789
804
  this.#queue.splice(index, 0, element);
790
805
  }
791
- setPriority(id2, priority) {
792
- const index = this.#findIndex((element) => element.id === id2);
806
+ setPriority(id, priority) {
807
+ const index = this.#findIndex((element) => element.id === id);
793
808
  if (index === -1) {
794
- throw new ReferenceError(`No promise function with the id "${id2}" exists in the queue.`);
809
+ throw new ReferenceError(`No promise function with the id "${id}" exists in the queue.`);
795
810
  }
796
811
  if (this.#queue[index].priority === priority) {
797
812
  return;
798
813
  }
799
814
  const [item] = this.#queue.splice(index, 1);
800
- this.enqueue(item.run, { priority, id: id2 });
815
+ this.enqueue(item.run, { priority, id });
801
816
  }
802
817
  remove(idOrRun) {
803
818
  const index = this.#findIndex((element) => (typeof idOrRun === "string" ? element.id : element.run) === idOrRun);
@@ -1213,17 +1228,17 @@ var PQueue = class extends EventTarget {
1213
1228
  }
1214
1229
  }
1215
1230
  async #add(function_, options, waitingTask) {
1216
- const id2 = options.id ?? (this.#idAssigner++).toString();
1231
+ const id = options.id ?? (this.#idAssigner++).toString();
1217
1232
  options = {
1218
1233
  timeout: this.#timeout,
1219
1234
  ...options,
1220
- id: id2
1235
+ id
1221
1236
  };
1222
1237
  validateTimeout(options.timeout);
1223
1238
  if (options.priority !== void 0 && (typeof options.priority !== "number" || Number.isNaN(options.priority))) {
1224
1239
  throw new TypeError(`Expected \`priority\` to be a number, got \`${String(options.priority)}\` (${typeof options.priority})`);
1225
1240
  }
1226
- waitingTask.id = id2;
1241
+ waitingTask.id = id;
1227
1242
  waitingTask.priority = options.priority ?? 0;
1228
1243
  return new Promise((resolve, reject) => {
1229
1244
  if (options.signal?.aborted) {
@@ -1240,7 +1255,7 @@ var PQueue = class extends EventTarget {
1240
1255
  }
1241
1256
  this.#pending++;
1242
1257
  const runningTask = {
1243
- id: id2,
1258
+ id,
1244
1259
  priority: waitingTask.priority,
1245
1260
  startTime: Date.now(),
1246
1261
  timeout: options.timeout
@@ -1307,7 +1322,7 @@ var PQueue = class extends EventTarget {
1307
1322
  if (this.#queue instanceof PriorityQueue) {
1308
1323
  this.#queue.remove(run);
1309
1324
  } else {
1310
- this.#queue.remove(id2);
1325
+ this.#queue.remove(id);
1311
1326
  }
1312
1327
  reject(signal.reason);
1313
1328
  this.#processQueue();
@@ -1383,18 +1398,18 @@ var PQueue = class extends EventTarget {
1383
1398
  // '🦀' runs last
1384
1399
  ```
1385
1400
  */
1386
- setPriority(id2, priority) {
1401
+ setPriority(id, priority) {
1387
1402
  if (typeof priority !== "number" || !Number.isFinite(priority)) {
1388
1403
  throw new TypeError(`Expected \`priority\` to be a finite number, got \`${priority}\` (${typeof priority})`);
1389
1404
  }
1390
1405
  for (const waitingTask of this.#waitingTasks) {
1391
- if (waitingTask.id === id2) {
1392
- this.#queue.setPriority(id2, priority);
1406
+ if (waitingTask.id === id) {
1407
+ this.#queue.setPriority(id, priority);
1393
1408
  waitingTask.priority = priority;
1394
1409
  return;
1395
1410
  }
1396
1411
  }
1397
- throw new ReferenceError(`No promise function with the id "${id2}" exists in the queue.`);
1412
+ throw new ReferenceError(`No promise function with the id "${id}" exists in the queue.`);
1398
1413
  }
1399
1414
  /**
1400
1415
  Adds a sync or async task to the queue.
@@ -1739,7 +1754,7 @@ var TimeoutError = class extends DOMException {
1739
1754
  // src/orchestration/canonical/KrnlQ.ts
1740
1755
  import { randomUUID as randomUUID2 } from "crypto";
1741
1756
 
1742
- // src/orchestration/canonical/model.ts
1757
+ // src/orchestration/canonical/dagValidation.ts
1743
1758
  function validateOrchestrationDAG(steps) {
1744
1759
  const errors = [];
1745
1760
  const stepMap = /* @__PURE__ */ new Map();
@@ -1804,8 +1819,8 @@ function validateOrchestrationDAG(steps) {
1804
1819
  }
1805
1820
  }
1806
1821
  const queue = [];
1807
- for (const [id2, deg] of inDegree.entries()) {
1808
- if (deg === 0) queue.push(id2);
1822
+ for (const [id, deg] of inDegree.entries()) {
1823
+ if (deg === 0) queue.push(id);
1809
1824
  }
1810
1825
  const order = [];
1811
1826
  while (queue.length > 0) {
@@ -2009,9 +2024,9 @@ var KrnlQueue = class {
2009
2024
  if (this.jobs.size <= this.maxRetainedJobs) return;
2010
2025
  const excess = this.jobs.size - this.maxRetainedJobs;
2011
2026
  let pruned = 0;
2012
- for (const [id2, record] of this.jobs.entries()) {
2027
+ for (const [id, record] of this.jobs.entries()) {
2013
2028
  if (record.status === "completed" || record.status === "failed" || record.status === "cancelled") {
2014
- this.jobs.delete(id2);
2029
+ this.jobs.delete(id);
2015
2030
  pruned++;
2016
2031
  if (pruned >= excess) break;
2017
2032
  }
@@ -3576,9 +3591,9 @@ var ServiceRuntime = class {
3576
3591
  // src/discovery/ServiceDiscovery.ts
3577
3592
  var ServiceDiscovery = class {
3578
3593
  peers = /* @__PURE__ */ new Map();
3579
- registerPeer(id2, name, endpoints) {
3580
- this.peers.set(id2, {
3581
- id: id2,
3594
+ registerPeer(id, name, endpoints) {
3595
+ this.peers.set(id, {
3596
+ id,
3582
3597
  name,
3583
3598
  endpoints,
3584
3599
  lastSeen: Date.now()
@@ -3587,8 +3602,8 @@ var ServiceDiscovery = class {
3587
3602
  getPeers() {
3588
3603
  return Array.from(this.peers.values());
3589
3604
  }
3590
- findPeer(id2) {
3591
- return this.peers.get(id2);
3605
+ findPeer(id) {
3606
+ return this.peers.get(id);
3592
3607
  }
3593
3608
  };
3594
3609
 
@@ -36,8 +36,8 @@ module.exports = __toCommonJS(index_exports);
36
36
 
37
37
  // src/KrnlValidatorEngine.ts
38
38
  var fs2 = __toESM(require("fs"), 1);
39
- var path3 = __toESM(require("path"), 1);
40
- var import_ts_morph5 = require("ts-morph");
39
+ var path4 = __toESM(require("path"), 1);
40
+ var import_ts_morph6 = require("ts-morph");
41
41
 
42
42
  // src/rules/fileLimits.ts
43
43
  function checkFileLimits(sf, options) {
@@ -312,6 +312,9 @@ function checkOrchestrationRules(sf) {
312
312
 
313
313
  // src/rules/workspaceRules.ts
314
314
  var fs = __toESM(require("fs"), 1);
315
+ var path3 = __toESM(require("path"), 1);
316
+
317
+ // src/rules/topLevelPurityRules.ts
315
318
  var path2 = __toESM(require("path"), 1);
316
319
  var import_ts_morph3 = require("ts-morph");
317
320
  function checkTopLevelPurity(sf) {
@@ -377,25 +380,27 @@ function checkTopLevelPurity(sf) {
377
380
  }
378
381
  return { errors, warnings };
379
382
  }
383
+
384
+ // src/rules/workspaceRules.ts
380
385
  function checkWorkspaceLayout(projectRoot, errors) {
381
- const krnlDir = path2.join(projectRoot, "krnl");
382
- const srcDir = path2.join(projectRoot, "src");
386
+ const krnlDir = path3.join(projectRoot, "krnl");
387
+ const srcDir = path3.join(projectRoot, "src");
383
388
  const targetDir = fs.existsSync(krnlDir) ? krnlDir : fs.existsSync(srcDir) ? srcDir : null;
384
389
  if (!targetDir) return;
385
- const backendDir = path2.join(targetDir, "backend");
386
- const frontendDir = path2.join(targetDir, "frontend");
390
+ const backendDir = path3.join(targetDir, "backend");
391
+ const frontendDir = path3.join(targetDir, "frontend");
387
392
  if (fs.existsSync(backendDir)) {
388
- const bServices = path2.join(backendDir, "services");
393
+ const bServices = path3.join(backendDir, "services");
389
394
  if (fs.existsSync(bServices)) {
390
395
  for (const sEntry of fs.readdirSync(bServices, { withFileTypes: true })) {
391
396
  if (!sEntry.isDirectory()) continue;
392
- const sDir = path2.join(bServices, sEntry.name);
393
- const sLibs = path2.join(sDir, "libraries");
397
+ const sDir = path3.join(bServices, sEntry.name);
398
+ const sLibs = path3.join(sDir, "libraries");
394
399
  if (fs.existsSync(sLibs)) {
395
400
  for (const entry of fs.readdirSync(sLibs, { withFileTypes: true })) {
396
401
  if (!entry.isDirectory()) continue;
397
- const libPath = path2.join(sLibs, entry.name);
398
- if (!fs.existsSync(path2.join(libPath, "manifest.json"))) {
402
+ const libPath = path3.join(sLibs, entry.name);
403
+ if (!fs.existsSync(path3.join(libPath, "manifest.json"))) {
399
404
  errors.push({
400
405
  ruleId: "krnl/concept-manifest-required",
401
406
  filePath: libPath,
@@ -405,12 +410,12 @@ function checkWorkspaceLayout(projectRoot, errors) {
405
410
  }
406
411
  }
407
412
  }
408
- const sFuncs = path2.join(sDir, "functionalities");
413
+ const sFuncs = path3.join(sDir, "functionalities");
409
414
  if (fs.existsSync(sFuncs)) {
410
415
  for (const entry of fs.readdirSync(sFuncs, { withFileTypes: true })) {
411
416
  if (!entry.isDirectory()) continue;
412
- const funcPath = path2.join(sFuncs, entry.name);
413
- if (!fs.existsSync(path2.join(funcPath, "manifest.json"))) {
417
+ const funcPath = path3.join(sFuncs, entry.name);
418
+ if (!fs.existsSync(path3.join(funcPath, "manifest.json"))) {
414
419
  errors.push({
415
420
  ruleId: "krnl/functionality-manifest-required",
416
421
  filePath: funcPath,
@@ -422,12 +427,12 @@ function checkWorkspaceLayout(projectRoot, errors) {
422
427
  }
423
428
  }
424
429
  }
425
- const bLibs = path2.join(backendDir, "libraries");
430
+ const bLibs = path3.join(backendDir, "libraries");
426
431
  if (fs.existsSync(bLibs)) {
427
432
  for (const entry of fs.readdirSync(bLibs, { withFileTypes: true })) {
428
433
  if (!entry.isDirectory()) continue;
429
- const libPath = path2.join(bLibs, entry.name);
430
- if (!fs.existsSync(path2.join(libPath, "manifest.json"))) {
434
+ const libPath = path3.join(bLibs, entry.name);
435
+ if (!fs.existsSync(path3.join(libPath, "manifest.json"))) {
431
436
  errors.push({
432
437
  ruleId: "krnl/concept-manifest-required",
433
438
  filePath: libPath,
@@ -437,12 +442,12 @@ function checkWorkspaceLayout(projectRoot, errors) {
437
442
  }
438
443
  }
439
444
  }
440
- const bFuncs = path2.join(backendDir, "functionalities");
445
+ const bFuncs = path3.join(backendDir, "functionalities");
441
446
  if (fs.existsSync(bFuncs)) {
442
447
  for (const entry of fs.readdirSync(bFuncs, { withFileTypes: true })) {
443
448
  if (!entry.isDirectory()) continue;
444
- const funcPath = path2.join(bFuncs, entry.name);
445
- if (!fs.existsSync(path2.join(funcPath, "manifest.json"))) {
449
+ const funcPath = path3.join(bFuncs, entry.name);
450
+ if (!fs.existsSync(path3.join(funcPath, "manifest.json"))) {
446
451
  errors.push({
447
452
  ruleId: "krnl/functionality-manifest-required",
448
453
  filePath: funcPath,
@@ -454,12 +459,12 @@ function checkWorkspaceLayout(projectRoot, errors) {
454
459
  }
455
460
  }
456
461
  if (fs.existsSync(frontendDir)) {
457
- const fLibs = path2.join(frontendDir, "libraries");
462
+ const fLibs = path3.join(frontendDir, "libraries");
458
463
  if (fs.existsSync(fLibs)) {
459
464
  for (const entry of fs.readdirSync(fLibs, { withFileTypes: true })) {
460
465
  if (!entry.isDirectory()) continue;
461
- const libPath = path2.join(fLibs, entry.name);
462
- if (!fs.existsSync(path2.join(libPath, "manifest.json"))) {
466
+ const libPath = path3.join(fLibs, entry.name);
467
+ if (!fs.existsSync(path3.join(libPath, "manifest.json"))) {
463
468
  errors.push({
464
469
  ruleId: "krnl/frontend-concept-manifest-required",
465
470
  filePath: libPath,
@@ -469,12 +474,12 @@ function checkWorkspaceLayout(projectRoot, errors) {
469
474
  }
470
475
  }
471
476
  }
472
- const fFuncs = path2.join(frontendDir, "functionalities");
477
+ const fFuncs = path3.join(frontendDir, "functionalities");
473
478
  if (fs.existsSync(fFuncs)) {
474
479
  for (const entry of fs.readdirSync(fFuncs, { withFileTypes: true })) {
475
480
  if (!entry.isDirectory()) continue;
476
- const funcPath = path2.join(fFuncs, entry.name);
477
- if (!fs.existsSync(path2.join(funcPath, "manifest.json"))) {
481
+ const funcPath = path3.join(fFuncs, entry.name);
482
+ if (!fs.existsSync(path3.join(funcPath, "manifest.json"))) {
478
483
  errors.push({
479
484
  ruleId: "krnl/frontend-functionality-manifest-required",
480
485
  filePath: funcPath,
@@ -518,6 +523,9 @@ function checkServiceBoundaries(sf) {
518
523
  }
519
524
 
520
525
  // src/rules/scopedLibraryRules.ts
526
+ var import_ts_morph5 = require("ts-morph");
527
+
528
+ // src/rules/scopedLibraryTypeHelpers.ts
521
529
  var import_ts_morph4 = require("ts-morph");
522
530
  var PRIMITIVE_AND_BUILTIN_TYPES = /* @__PURE__ */ new Set([
523
531
  "string",
@@ -570,14 +578,6 @@ var PRIMITIVE_AND_BUILTIN_TYPES = /* @__PURE__ */ new Set([
570
578
  "ReturnType",
571
579
  "InstanceType"
572
580
  ]);
573
- function detectServiceContext(filePath) {
574
- const normalized = filePath.replace(/\\/g, "/");
575
- const match = normalized.match(/(?:^|\/)services\/([^/]+)\/libraries\/([^/]+)/);
576
- if (match) {
577
- return { serviceName: match[1], libraryName: match[2] };
578
- }
579
- return null;
580
- }
581
581
  function containsIdentifier(name, target) {
582
582
  return name.toLowerCase().includes(target.toLowerCase());
583
583
  }
@@ -598,6 +598,16 @@ function hasContextualTypeReference(node, serviceName, localTypes) {
598
598
  }
599
599
  return false;
600
600
  }
601
+
602
+ // src/rules/scopedLibraryRules.ts
603
+ function detectServiceContext(filePath) {
604
+ const normalized = filePath.replace(/\\/g, "/");
605
+ const match = normalized.match(/(?:^|\/)services\/([^/]+)\/libraries\/([^/]+)/);
606
+ if (match) {
607
+ return { serviceName: match[1], libraryName: match[2] };
608
+ }
609
+ return null;
610
+ }
601
611
  function checkScopedLibraryRules(sf) {
602
612
  const errors = [];
603
613
  const warnings = [];
@@ -647,7 +657,7 @@ function checkScopedLibraryRules(sf) {
647
657
  for (const decl of stmt.getDeclarations()) {
648
658
  const varName = decl.getName();
649
659
  const init = decl.getInitializer();
650
- const isFunction = init && (init.getKind() === import_ts_morph4.SyntaxKind.ArrowFunction || init.getKind() === import_ts_morph4.SyntaxKind.FunctionExpression);
660
+ const isFunction = init && (init.getKind() === import_ts_morph5.SyntaxKind.ArrowFunction || init.getKind() === import_ts_morph5.SyntaxKind.FunctionExpression);
651
661
  if (isFunction) {
652
662
  const isContextual = hasContextualTypeReference(decl, serviceName, localTypes);
653
663
  const hasServiceName = containsIdentifier(varName, serviceName);
@@ -738,17 +748,17 @@ var KrnlValidatorEngine = class {
738
748
  limitOptions;
739
749
  constructor(optionsOrRoot) {
740
750
  const options = typeof optionsOrRoot === "string" ? { projectRoot: optionsOrRoot } : optionsOrRoot;
741
- this.projectRoot = path3.resolve(options.projectRoot || process.cwd());
751
+ this.projectRoot = path4.resolve(options.projectRoot || process.cwd());
742
752
  this.limitOptions = {
743
753
  maxFileLineLimit: options.maxFileLineLimit ?? 200,
744
754
  maxMainLogicLimit: options.maxMainLogicLimit ?? 20,
745
755
  maxHelperLineLimit: options.maxHelperLineLimit ?? 30
746
756
  };
747
- const tsConfigPath = path3.join(this.projectRoot, "tsconfig.json");
757
+ const tsConfigPath = path4.join(this.projectRoot, "tsconfig.json");
748
758
  if (fs2.existsSync(tsConfigPath)) {
749
- this.project = new import_ts_morph5.Project({ tsConfigFilePath: tsConfigPath, skipAddingFilesFromTsConfig: true });
759
+ this.project = new import_ts_morph6.Project({ tsConfigFilePath: tsConfigPath, skipAddingFilesFromTsConfig: true });
750
760
  } else {
751
- this.project = new import_ts_morph5.Project({ compilerOptions: {
761
+ this.project = new import_ts_morph6.Project({ compilerOptions: {
752
762
  target: 99
753
763
  /* ESNext */
754
764
  } });
@@ -779,7 +789,7 @@ var KrnlValidatorEngine = class {
779
789
  }
780
790
  validateSourceFile(sf) {
781
791
  const filePath = sf.getFilePath();
782
- const baseName = path3.basename(filePath);
792
+ const baseName = path4.basename(filePath);
783
793
  if (baseName.includes("_pb.") || baseName.endsWith(".d.ts")) {
784
794
  return { errors: [], warnings: [], promotableAssets: [] };
785
795
  }
@@ -814,7 +824,7 @@ var KrnlValidatorEngine = class {
814
824
  const entries = fs2.readdirSync(dir, { withFileTypes: true });
815
825
  for (const entry of entries) {
816
826
  if (entry.name === "node_modules" || entry.name === "dist" || entry.name === ".git") continue;
817
- const full = path3.join(dir, entry.name);
827
+ const full = path4.join(dir, entry.name);
818
828
  if (entry.isDirectory()) {
819
829
  this.collectSourceFiles(full, collected);
820
830
  } else if (entry.isFile() && (entry.name.endsWith(".ts") || entry.name.endsWith(".js") || entry.name.endsWith(".tsx") || entry.name.endsWith(".jsx"))) {