@telorun/analyzer 0.10.1 → 0.12.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 (92) hide show
  1. package/LICENSE +2 -2
  2. package/README.md +3 -3
  3. package/dist/adapters/http-adapter.d.ts +10 -0
  4. package/dist/adapters/http-adapter.d.ts.map +1 -0
  5. package/dist/adapters/http-adapter.js +18 -0
  6. package/dist/adapters/node-adapter.d.ts +17 -0
  7. package/dist/adapters/node-adapter.d.ts.map +1 -0
  8. package/dist/adapters/node-adapter.js +71 -0
  9. package/dist/adapters/registry-adapter.d.ts +15 -0
  10. package/dist/adapters/registry-adapter.d.ts.map +1 -0
  11. package/dist/adapters/registry-adapter.js +53 -0
  12. package/dist/analysis-registry.d.ts +7 -0
  13. package/dist/analysis-registry.d.ts.map +1 -1
  14. package/dist/analysis-registry.js +38 -0
  15. package/dist/analyzer.d.ts +15 -0
  16. package/dist/analyzer.d.ts.map +1 -1
  17. package/dist/analyzer.js +268 -7
  18. package/dist/builtins.d.ts.map +1 -1
  19. package/dist/builtins.js +172 -1
  20. package/dist/definition-registry.d.ts.map +1 -1
  21. package/dist/definition-registry.js +16 -0
  22. package/dist/dependency-graph.d.ts.map +1 -1
  23. package/dist/dependency-graph.js +27 -13
  24. package/dist/index.d.ts +2 -0
  25. package/dist/index.d.ts.map +1 -1
  26. package/dist/index.js +2 -0
  27. package/dist/kernel-globals.d.ts.map +1 -1
  28. package/dist/kernel-globals.js +9 -11
  29. package/dist/manifest-loader.d.ts +23 -1
  30. package/dist/manifest-loader.d.ts.map +1 -1
  31. package/dist/manifest-loader.js +66 -3
  32. package/dist/normalize-inline-resources.d.ts.map +1 -1
  33. package/dist/normalize-inline-resources.js +26 -14
  34. package/dist/position-metadata.d.ts +11 -2
  35. package/dist/position-metadata.d.ts.map +1 -1
  36. package/dist/position-metadata.js +18 -3
  37. package/dist/precompile.d.ts.map +1 -1
  38. package/dist/precompile.js +9 -1
  39. package/dist/reference-field-map.d.ts +21 -4
  40. package/dist/reference-field-map.d.ts.map +1 -1
  41. package/dist/reference-field-map.js +93 -25
  42. package/dist/residual-schema.d.ts +23 -0
  43. package/dist/residual-schema.d.ts.map +1 -0
  44. package/dist/residual-schema.js +45 -0
  45. package/dist/resolve-ref-sentinels.d.ts +27 -0
  46. package/dist/resolve-ref-sentinels.d.ts.map +1 -0
  47. package/dist/resolve-ref-sentinels.js +114 -0
  48. package/dist/rewrite-synthetic-origins.d.ts +10 -0
  49. package/dist/rewrite-synthetic-origins.d.ts.map +1 -0
  50. package/dist/rewrite-synthetic-origins.js +55 -0
  51. package/dist/schema-compat.d.ts +7 -1
  52. package/dist/schema-compat.d.ts.map +1 -1
  53. package/dist/schema-compat.js +19 -2
  54. package/dist/system-kinds.d.ts +25 -0
  55. package/dist/system-kinds.d.ts.map +1 -0
  56. package/dist/system-kinds.js +34 -0
  57. package/dist/types.d.ts +12 -0
  58. package/dist/types.d.ts.map +1 -1
  59. package/dist/validate-cel-context.d.ts +61 -7
  60. package/dist/validate-cel-context.d.ts.map +1 -1
  61. package/dist/validate-cel-context.js +90 -8
  62. package/dist/validate-provider-coherence.d.ts +23 -0
  63. package/dist/validate-provider-coherence.d.ts.map +1 -0
  64. package/dist/validate-provider-coherence.js +148 -0
  65. package/dist/validate-references.d.ts.map +1 -1
  66. package/dist/validate-references.js +141 -36
  67. package/dist/with-synthetic-positions.d.ts +28 -0
  68. package/dist/with-synthetic-positions.d.ts.map +1 -0
  69. package/dist/with-synthetic-positions.js +45 -0
  70. package/package.json +7 -4
  71. package/src/analysis-registry.ts +37 -0
  72. package/src/analyzer.ts +313 -9
  73. package/src/builtins.ts +172 -1
  74. package/src/definition-registry.ts +15 -0
  75. package/src/dependency-graph.ts +27 -14
  76. package/src/index.ts +2 -0
  77. package/src/kernel-globals.ts +9 -11
  78. package/src/manifest-loader.ts +69 -4
  79. package/src/normalize-inline-resources.ts +48 -13
  80. package/src/position-metadata.ts +18 -3
  81. package/src/precompile.ts +8 -1
  82. package/src/reference-field-map.ts +129 -24
  83. package/src/residual-schema.ts +49 -0
  84. package/src/resolve-ref-sentinels.ts +127 -0
  85. package/src/rewrite-synthetic-origins.ts +75 -0
  86. package/src/schema-compat.ts +19 -2
  87. package/src/system-kinds.ts +37 -0
  88. package/src/types.ts +12 -0
  89. package/src/validate-cel-context.ts +111 -8
  90. package/src/validate-provider-coherence.ts +166 -0
  91. package/src/validate-references.ts +138 -35
  92. package/src/with-synthetic-positions.ts +48 -0
package/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  # SUSTAINABLE USE LICENSE (Fair-code)
2
2
 
3
- Copyright (c) 2026 DiglyAI
3
+ Copyright (c) 2026 CodeNet Sp. z o.o.
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to use, copy, modify, and distribute the Software for any purpose—including commercial purposes—subject to the following conditions:
6
6
 
@@ -14,4 +14,4 @@ Permission is hereby granted, free of charge, to any person obtaining a copy of
14
14
 
15
15
  5. DISCLAIMER: The Software is provided "as is", without warranty of any kind, express or implied, including but not limited to the warranties of merchantability, fitness for a particular purpose and noninfringement. In no event shall the authors or copyright holders be liable for any claim, damages or other liability, whether in an action of contract, tort or otherwise, arising from, out of or in connection with the Software or the use or other dealings in the Software.
16
16
 
17
- For commercial licensing, managed hosting exemptions, or enterprise inquiries, please contact DiglyAI.
17
+ For commercial licensing, managed hosting exemptions, or enterprise inquiries, please contact <contact@codenet.pl>.
package/README.md CHANGED
@@ -1,5 +1,5 @@
1
1
  <p align="center">
2
- <img src="./assets/telo.png" alt="Telo" width="200" />
2
+ <img src="https://raw.githubusercontent.com/telorun/telo/main/assets/telo.png" alt="Telo" width="200" />
3
3
  </p>
4
4
 
5
5
  <h1 align="center">Telo</h1>
@@ -61,12 +61,12 @@ targets:
61
61
  kind: Telo.Import
62
62
  metadata:
63
63
  name: Http
64
- source: ../modules/http-server
64
+ source: std/http-server@0.4.0
65
65
  ---
66
66
  kind: Telo.Import
67
67
  metadata:
68
68
  name: Sql
69
- source: ../modules/sql
69
+ source: std/sql@0.2.3
70
70
  ---
71
71
  # SQLite database — swap driver/host/database for PostgreSQL with zero YAML changes
72
72
  kind: Sql.Connection
@@ -0,0 +1,10 @@
1
+ import { type ManifestAdapter } from "../types.js";
2
+ export declare class HttpAdapter implements ManifestAdapter {
3
+ supports(url: string): boolean;
4
+ read(url: string): Promise<{
5
+ text: string;
6
+ source: string;
7
+ }>;
8
+ resolveRelative(base: string, relative: string): string;
9
+ }
10
+ //# sourceMappingURL=http-adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http-adapter.d.ts","sourceRoot":"","sources":["../../src/adapters/http-adapter.ts"],"names":[],"mappings":"AAAA,OAAO,EAA6B,KAAK,eAAe,EAAE,MAAM,aAAa,CAAC;AAE9E,qBAAa,WAAY,YAAW,eAAe;IACjD,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAIxB,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAWlE,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM;CAIxD"}
@@ -0,0 +1,18 @@
1
+ import { DEFAULT_MANIFEST_FILENAME } from "../types.js";
2
+ export class HttpAdapter {
3
+ supports(url) {
4
+ return url.startsWith("http://") || url.startsWith("https://");
5
+ }
6
+ async read(url) {
7
+ const fetchUrl = url.includes(".yaml") ? url : `${url}/${DEFAULT_MANIFEST_FILENAME}`;
8
+ const response = await fetch(fetchUrl);
9
+ if (!response.ok) {
10
+ throw new Error(`Failed to fetch manifest from ${fetchUrl}: ${response.status} ${response.statusText}`);
11
+ }
12
+ return { text: await response.text(), source: fetchUrl };
13
+ }
14
+ resolveRelative(base, relative) {
15
+ const baseDir = base.endsWith("/") ? base : base.slice(0, base.lastIndexOf("/") + 1);
16
+ return new URL(relative, baseDir).href;
17
+ }
18
+ }
@@ -0,0 +1,17 @@
1
+ import { type ManifestAdapter } from "../types.js";
2
+ /** Node.js fs-based ManifestAdapter for local files. Not browser-compatible. */
3
+ export declare class NodeAdapter implements ManifestAdapter {
4
+ private readonly cwd;
5
+ constructor(cwd?: string);
6
+ supports(url: string): boolean;
7
+ read(url: string): Promise<{
8
+ text: string;
9
+ source: string;
10
+ }>;
11
+ resolveRelative(base: string, relative: string): string;
12
+ expandGlob(base: string, patterns: string[]): Promise<string[]>;
13
+ resolveOwnerOf(fileUrl: string): Promise<string | null>;
14
+ }
15
+ /** @deprecated Use `new NodeAdapter(cwd)` instead */
16
+ export declare function createNodeAdapter(cwd?: string): ManifestAdapter;
17
+ //# sourceMappingURL=node-adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node-adapter.d.ts","sourceRoot":"","sources":["../../src/adapters/node-adapter.ts"],"names":[],"mappings":"AAIA,OAAO,EAA6B,KAAK,eAAe,EAAE,MAAM,aAAa,CAAC;AAM9E,gFAAgF;AAChF,qBAAa,WAAY,YAAW,eAAe;IACrC,OAAO,CAAC,QAAQ,CAAC,GAAG;gBAAH,GAAG,GAAE,MAAsB;IAExD,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAUxB,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IASlE,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM;IAKjD,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAc/D,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;CAoB9D;AAED,qDAAqD;AACrD,wBAAgB,iBAAiB,CAAC,GAAG,GAAE,MAAsB,GAAG,eAAe,CAE9E"}
@@ -0,0 +1,71 @@
1
+ import * as fs from "fs/promises";
2
+ import * as path from "path";
3
+ import { fileURLToPath } from "url";
4
+ import { minimatch } from "minimatch";
5
+ import { DEFAULT_MANIFEST_FILENAME } from "../types.js";
6
+ function toFilePath(url) {
7
+ return url.startsWith("file://") ? fileURLToPath(url) : url;
8
+ }
9
+ /** Node.js fs-based ManifestAdapter for local files. Not browser-compatible. */
10
+ export class NodeAdapter {
11
+ cwd;
12
+ constructor(cwd = process.cwd()) {
13
+ this.cwd = cwd;
14
+ }
15
+ supports(url) {
16
+ return (url.startsWith("file://") ||
17
+ url.startsWith("/") ||
18
+ url.startsWith("./") ||
19
+ url.startsWith("../") ||
20
+ (!url.includes("://") && !url.includes("@")));
21
+ }
22
+ async read(url) {
23
+ const filePath = toFilePath(url);
24
+ const stat = await fs.stat(filePath).catch(() => null);
25
+ const resolvedPath = stat?.isDirectory() ? path.join(filePath, DEFAULT_MANIFEST_FILENAME) : filePath;
26
+ const text = await fs.readFile(resolvedPath, "utf8");
27
+ return { text, source: resolvedPath };
28
+ }
29
+ resolveRelative(base, relative) {
30
+ const baseDir = path.dirname(path.resolve(this.cwd, toFilePath(base)));
31
+ return path.resolve(baseDir, relative);
32
+ }
33
+ async expandGlob(base, patterns) {
34
+ const baseDir = path.dirname(path.resolve(this.cwd, toFilePath(base)));
35
+ const entries = await fs.readdir(baseDir, { recursive: true, encoding: "utf8" });
36
+ const normalizedPatterns = patterns.map((p) => p.replace(/\\/g, "/").replace(/^\.\//, ""));
37
+ const matched = [];
38
+ for (const entry of entries) {
39
+ const normalized = entry.replace(/\\/g, "/");
40
+ if (normalizedPatterns.some((p) => minimatch(normalized, p))) {
41
+ matched.push(path.resolve(baseDir, entry));
42
+ }
43
+ }
44
+ return matched.sort();
45
+ }
46
+ async resolveOwnerOf(fileUrl) {
47
+ const resolved = path.resolve(this.cwd, toFilePath(fileUrl));
48
+ let dir = path.dirname(resolved);
49
+ while (true) {
50
+ const candidate = path.join(dir, DEFAULT_MANIFEST_FILENAME);
51
+ if (candidate !== resolved) {
52
+ try {
53
+ await fs.access(candidate);
54
+ return candidate;
55
+ }
56
+ catch {
57
+ // telo.yaml not found at this level
58
+ }
59
+ }
60
+ const parent = path.dirname(dir);
61
+ if (parent === dir)
62
+ break;
63
+ dir = parent;
64
+ }
65
+ return null;
66
+ }
67
+ }
68
+ /** @deprecated Use `new NodeAdapter(cwd)` instead */
69
+ export function createNodeAdapter(cwd = process.cwd()) {
70
+ return new NodeAdapter(cwd);
71
+ }
@@ -0,0 +1,15 @@
1
+ import { type ManifestAdapter } from "../types.js";
2
+ export declare class RegistryAdapter implements ManifestAdapter {
3
+ private registryUrl;
4
+ constructor(registryUrl?: string);
5
+ supports(url: string): boolean;
6
+ read(moduleRef: string): Promise<{
7
+ text: string;
8
+ source: string;
9
+ }>;
10
+ resolveRelative(base: string, relative: string): string;
11
+ private toRegistryModuleBase;
12
+ private toRegistryUrl;
13
+ private parseModuleRef;
14
+ }
15
+ //# sourceMappingURL=registry-adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry-adapter.d.ts","sourceRoot":"","sources":["../../src/adapters/registry-adapter.ts"],"names":[],"mappings":"AAAA,OAAO,EAA6B,KAAK,eAAe,EAAE,MAAM,aAAa,CAAC;AAI9E,qBAAa,eAAgB,YAAW,eAAe;IACzC,OAAO,CAAC,WAAW;gBAAX,WAAW,SAAuB;IAEtD,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAWxB,IAAI,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAWxE,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM;IAMvD,OAAO,CAAC,oBAAoB;IAM5B,OAAO,CAAC,aAAa;IAIrB,OAAO,CAAC,cAAc;CAmBvB"}
@@ -0,0 +1,53 @@
1
+ import { DEFAULT_MANIFEST_FILENAME } from "../types.js";
2
+ const DEFAULT_REGISTRY_URL = "https://registry.telo.run";
3
+ export class RegistryAdapter {
4
+ registryUrl;
5
+ constructor(registryUrl = DEFAULT_REGISTRY_URL) {
6
+ this.registryUrl = registryUrl;
7
+ }
8
+ supports(url) {
9
+ return (!url.startsWith("http://") &&
10
+ !url.startsWith("https://") &&
11
+ !url.startsWith("/") &&
12
+ !url.startsWith(".") &&
13
+ url.includes("@") &&
14
+ url.includes("/"));
15
+ }
16
+ async read(moduleRef) {
17
+ const fetchUrl = this.toRegistryUrl(moduleRef);
18
+ const response = await fetch(fetchUrl);
19
+ if (!response.ok) {
20
+ throw new Error(`Failed to fetch manifest ${moduleRef}: ${response.status} ${response.statusText}`);
21
+ }
22
+ return { text: await response.text(), source: fetchUrl };
23
+ }
24
+ resolveRelative(base, relative) {
25
+ const baseUrl = this.supports(base) ? this.toRegistryModuleBase(base) : base;
26
+ const baseWithSlash = baseUrl.endsWith("/") ? baseUrl : `${baseUrl}/`;
27
+ return new URL(relative, baseWithSlash).href;
28
+ }
29
+ toRegistryModuleBase(moduleRef) {
30
+ const parsed = this.parseModuleRef(moduleRef);
31
+ const normalizedBase = this.registryUrl.replace(/\/+$/, "");
32
+ return `${normalizedBase}/${parsed.modulePath}/${parsed.version}`;
33
+ }
34
+ toRegistryUrl(moduleRef) {
35
+ return `${this.toRegistryModuleBase(moduleRef)}/${DEFAULT_MANIFEST_FILENAME}`;
36
+ }
37
+ parseModuleRef(moduleRef) {
38
+ const atIdx = moduleRef.lastIndexOf("@");
39
+ if (atIdx <= 0 || atIdx === moduleRef.length - 1) {
40
+ throw new Error(`Invalid module reference '${moduleRef}', expected namespace/name@version`);
41
+ }
42
+ const modulePath = moduleRef.slice(0, atIdx);
43
+ if (!modulePath.includes("/")) {
44
+ throw new Error(`Invalid module reference '${moduleRef}', expected namespace/name@version`);
45
+ }
46
+ const rawVersion = moduleRef.slice(atIdx + 1);
47
+ const version = rawVersion.startsWith("v") ? rawVersion.substring(1) : rawVersion;
48
+ if (!version) {
49
+ throw new Error(`Invalid module reference '${moduleRef}', expected namespace/name@version`);
50
+ }
51
+ return { modulePath, version };
52
+ }
53
+ }
@@ -41,6 +41,13 @@ export declare class AnalysisRegistry {
41
41
  /** Returns the closest user-facing kind to `badKind`, or undefined when nothing
42
42
  * is close enough (or multiple candidates tie). Case-sensitive. */
43
43
  suggestKind(badKind: string): string | undefined;
44
+ /** Returns every user-facing (alias-form) kind that satisfies the given
45
+ * `x-telo-ref` constraint string (e.g. `"telo#Invocable"`, `"std/sql#Connection"`).
46
+ * Resolution mirrors `validateReferences.checkKind`: abstract targets expand to
47
+ * the set of definitions extending them; concrete targets yield just themselves.
48
+ * Returns `undefined` when the ref can't be resolved (e.g. unregistered identity),
49
+ * so callers can fall back to the unfiltered kind list. */
50
+ userFacingKindsForRef(xTeloRef: string): string[] | undefined;
44
51
  /** @internal Bridge for StaticAnalyzer — do not use outside the analyzer package. */
45
52
  _context(): AnalysisContext;
46
53
  }
@@ -1 +1 @@
1
- {"version":3,"file":"analysis-registry.d.ts","sourceRoot":"","sources":["../src/analysis-registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAMzE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElD;;;;GAIG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAC,IAAI,CAA4B;IACjD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAuB;IAC/C,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAoC;IAEpE,kBAAkB,CAAC,GAAG,EAAE,kBAAkB,GAAG,IAAI;IAIjD,sBAAsB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAIpE,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI;IAIpE,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAI7C;;;;;;;OAOG;IACH,mBAAmB,CACjB,QAAQ,EAAE,gBAAgB,EAC1B,KAAK,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,EAClC,OAAO,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,GACnC,IAAI;IAkBP;;;;OAIG;IACH,kBAAkB,IAAI,kBAAkB,EAAE;IAI1C,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,kBAAkB,GAAG,SAAS;IAM/D,QAAQ,IAAI,MAAM,EAAE;IAIpB;mEAC+D;IAC/D,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,EAAE;IAIxC;;;gCAG4B;IAC5B,oBAAoB,IAAI,MAAM,EAAE;IAIhC;wEACoE;IACpE,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAIhD,qFAAqF;IACrF,QAAQ,IAAI,eAAe;CAG5B"}
1
+ {"version":3,"file":"analysis-registry.d.ts","sourceRoot":"","sources":["../src/analysis-registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAMzE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElD;;;;GAIG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAC,IAAI,CAA4B;IACjD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAuB;IAC/C,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAoC;IAEpE,kBAAkB,CAAC,GAAG,EAAE,kBAAkB,GAAG,IAAI;IAIjD,sBAAsB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAIpE,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI;IAIpE,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAI7C;;;;;;;OAOG;IACH,mBAAmB,CACjB,QAAQ,EAAE,gBAAgB,EAC1B,KAAK,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,EAClC,OAAO,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,GACnC,IAAI;IAkBP;;;;OAIG;IACH,kBAAkB,IAAI,kBAAkB,EAAE;IAI1C,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,kBAAkB,GAAG,SAAS;IAM/D,QAAQ,IAAI,MAAM,EAAE;IAIpB;mEAC+D;IAC/D,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,EAAE;IAIxC;;;gCAG4B;IAC5B,oBAAoB,IAAI,MAAM,EAAE;IAIhC;wEACoE;IACpE,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAIhD;;;;;gEAK4D;IAC5D,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS;IA+B7D,qFAAqF;IACrF,QAAQ,IAAI,eAAe;CAG5B"}
@@ -79,6 +79,44 @@ export class AnalysisRegistry {
79
79
  suggestKind(badKind) {
80
80
  return computeSuggestKind(badKind, this.aliases, this.defs);
81
81
  }
82
+ /** Returns every user-facing (alias-form) kind that satisfies the given
83
+ * `x-telo-ref` constraint string (e.g. `"telo#Invocable"`, `"std/sql#Connection"`).
84
+ * Resolution mirrors `validateReferences.checkKind`: abstract targets expand to
85
+ * the set of definitions extending them; concrete targets yield just themselves.
86
+ * Returns `undefined` when the ref can't be resolved (e.g. unregistered identity),
87
+ * so callers can fall back to the unfiltered kind list. */
88
+ userFacingKindsForRef(xTeloRef) {
89
+ const targetKind = this.defs.resolveRef(xTeloRef);
90
+ if (!targetKind)
91
+ return undefined;
92
+ const targetDef = this.defs.resolve(targetKind);
93
+ if (!targetDef)
94
+ return undefined;
95
+ const canonicalKinds = [];
96
+ if (targetDef.kind === "Telo.Abstract") {
97
+ for (const def of this.defs.getByExtends(targetKind)) {
98
+ const module = def.metadata?.module;
99
+ if (module && def.metadata?.name) {
100
+ canonicalKinds.push(`${module}.${def.metadata.name}`);
101
+ }
102
+ }
103
+ }
104
+ else {
105
+ canonicalKinds.push(targetKind);
106
+ }
107
+ const out = new Set();
108
+ for (const kind of canonicalKinds) {
109
+ const dot = kind.indexOf(".");
110
+ if (dot === -1)
111
+ continue;
112
+ const moduleName = kind.slice(0, dot);
113
+ const typeName = kind.slice(dot + 1);
114
+ for (const alias of this.aliases.aliasesFor(moduleName)) {
115
+ out.add(`${alias}.${typeName}`);
116
+ }
117
+ }
118
+ return Array.from(out);
119
+ }
82
120
  /** @internal Bridge for StaticAnalyzer — do not use outside the analyzer package. */
83
121
  _context() {
84
122
  return { aliases: this.aliases, definitions: this.defs, aliasesByModule: this.aliasesByModule };
@@ -8,6 +8,21 @@ export interface StaticAnalyzerOptions {
8
8
  export declare class StaticAnalyzer {
9
9
  private readonly celEnv;
10
10
  constructor(options?: StaticAnalyzerOptions);
11
+ /**
12
+ * Run static analysis over a flattened manifest list.
13
+ *
14
+ * **Contract**: every non-system manifest (anything outside `Telo.Definition`,
15
+ * `Telo.Abstract`) must carry `metadata.source` (non-empty string) and
16
+ * `metadata.sourceLine` (number). The dedup that backs
17
+ * `DUPLICATE_RESOURCE_NAME` reads those fields to tell a pipeline echo
18
+ * apart from a genuine collision, and downstream diagnostic positioning
19
+ * depends on them too. Real callers stamp positions already (the `Loader`,
20
+ * `flattenForAnalyzer`, the telo-editor's `emitDocsFor`, the VSCode
21
+ * extension). Programmatic callers — tests, ad-hoc scripts — should pass
22
+ * their inputs through `withSyntheticPositions(...)` before calling
23
+ * `analyze()`. A missing position throws a clear error rather than
24
+ * silently producing wrong diagnostics.
25
+ */
11
26
  analyze(manifests: ResourceManifest[], options?: AnalysisOptions, registry?: AnalysisRegistry): AnalysisDiagnostic[];
12
27
  analyzeErrors(manifests: ResourceManifest[], options?: AnalysisOptions, registry?: AnalysisRegistry): AnalysisDiagnostic[];
13
28
  normalize(manifests: ResourceManifest[], registry: AnalysisRegistry): ResourceManifest[];
@@ -1 +1 @@
1
- {"version":3,"file":"analyzer.d.ts","sourceRoot":"","sources":["../src/analyzer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAsB,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAIzE,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAGL,KAAK,WAAW,EACjB,MAAM,sBAAsB,CAAC;AAa9B,OAAO,EAAsB,KAAK,kBAAkB,EAAE,KAAK,eAAe,EAAE,MAAM,YAAY,CAAC;AAgX/F,MAAM,WAAW,qBAAqB;IACpC,WAAW,CAAC,EAAE,WAAW,CAAC;CAC3B;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAc;gBAEzB,OAAO,GAAE,qBAA0B;IAI/C,OAAO,CACL,SAAS,EAAE,gBAAgB,EAAE,EAC7B,OAAO,CAAC,EAAE,eAAe,EACzB,QAAQ,CAAC,EAAE,gBAAgB,GAC1B,kBAAkB,EAAE;IAqUvB,aAAa,CACX,SAAS,EAAE,gBAAgB,EAAE,EAC7B,OAAO,CAAC,EAAE,eAAe,EACzB,QAAQ,CAAC,EAAE,gBAAgB,GAC1B,kBAAkB,EAAE;IAMvB,SAAS,CAAC,SAAS,EAAE,gBAAgB,EAAE,EAAE,QAAQ,EAAE,gBAAgB,GAAG,gBAAgB,EAAE;IAUxF,OAAO,CACL,SAAS,EAAE,gBAAgB,EAAE,EAC7B,QAAQ,EAAE,gBAAgB,GACzB;QAAE,WAAW,EAAE,kBAAkB,EAAE,CAAC;QAAC,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;QAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE;CAsB5F"}
1
+ {"version":3,"file":"analyzer.d.ts","sourceRoot":"","sources":["../src/analyzer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAsB,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAIzE,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAGL,KAAK,WAAW,EACjB,MAAM,sBAAsB,CAAC;AAgB9B,OAAO,EAAsB,KAAK,kBAAkB,EAAE,KAAK,eAAe,EAAE,MAAM,YAAY,CAAC;AAgf/F,MAAM,WAAW,qBAAqB;IACpC,WAAW,CAAC,EAAE,WAAW,CAAC;CAC3B;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAc;gBAEzB,OAAO,GAAE,qBAA0B;IAI/C;;;;;;;;;;;;;;OAcG;IACH,OAAO,CACL,SAAS,EAAE,gBAAgB,EAAE,EAC7B,OAAO,CAAC,EAAE,eAAe,EACzB,QAAQ,CAAC,EAAE,gBAAgB,GAC1B,kBAAkB,EAAE;IA8dvB,aAAa,CACX,SAAS,EAAE,gBAAgB,EAAE,EAC7B,OAAO,CAAC,EAAE,eAAe,EACzB,QAAQ,CAAC,EAAE,gBAAgB,GAC1B,kBAAkB,EAAE;IAMvB,SAAS,CAAC,SAAS,EAAE,gBAAgB,EAAE,EAAE,QAAQ,EAAE,gBAAgB,GAAG,gBAAgB,EAAE;IAexF,OAAO,CACL,SAAS,EAAE,gBAAgB,EAAE,EAC7B,QAAQ,EAAE,gBAAgB,GACzB;QAAE,WAAW,EAAE,kBAAkB,EAAE,CAAC;QAAC,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;QAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE;CAsB5F"}