@untangle-code/context-artifacts 0.0.0-stage → 0.1.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 (109) hide show
  1. package/LICENSE +661 -0
  2. package/NOTICE +90 -0
  3. package/README.md +247 -2
  4. package/THIRD_PARTY_LICENSES.md +24 -0
  5. package/dist/adapters/asyncapi.d.ts +20 -0
  6. package/dist/adapters/asyncapi.d.ts.map +1 -0
  7. package/dist/adapters/asyncapi.js +95 -0
  8. package/dist/adapters/asyncapi.js.map +1 -0
  9. package/dist/adapters/docker.d.ts +43 -0
  10. package/dist/adapters/docker.d.ts.map +1 -0
  11. package/dist/adapters/docker.js +97 -0
  12. package/dist/adapters/docker.js.map +1 -0
  13. package/dist/adapters/kubernetes.d.ts +22 -0
  14. package/dist/adapters/kubernetes.d.ts.map +1 -0
  15. package/dist/adapters/kubernetes.js +56 -0
  16. package/dist/adapters/kubernetes.js.map +1 -0
  17. package/dist/adapters/markdown.d.ts +35 -0
  18. package/dist/adapters/markdown.d.ts.map +1 -0
  19. package/dist/adapters/markdown.js +36 -0
  20. package/dist/adapters/markdown.js.map +1 -0
  21. package/dist/adapters/openapi.d.ts +21 -0
  22. package/dist/adapters/openapi.d.ts.map +1 -0
  23. package/dist/adapters/openapi.js +101 -0
  24. package/dist/adapters/openapi.js.map +1 -0
  25. package/dist/adapters/protobuf.d.ts +34 -0
  26. package/dist/adapters/protobuf.d.ts.map +1 -0
  27. package/dist/adapters/protobuf.js +221 -0
  28. package/dist/adapters/protobuf.js.map +1 -0
  29. package/dist/adapters/shared.d.ts +65 -0
  30. package/dist/adapters/shared.d.ts.map +1 -0
  31. package/dist/adapters/shared.js +95 -0
  32. package/dist/adapters/shared.js.map +1 -0
  33. package/dist/adapters/sql.d.ts +104 -0
  34. package/dist/adapters/sql.d.ts.map +1 -0
  35. package/dist/adapters/sql.js +427 -0
  36. package/dist/adapters/sql.js.map +1 -0
  37. package/dist/adapters/terraform.d.ts +40 -0
  38. package/dist/adapters/terraform.d.ts.map +1 -0
  39. package/dist/adapters/terraform.js +186 -0
  40. package/dist/adapters/terraform.js.map +1 -0
  41. package/dist/adapters/text.d.ts +24 -0
  42. package/dist/adapters/text.d.ts.map +1 -0
  43. package/dist/adapters/text.js +31 -0
  44. package/dist/adapters/text.js.map +1 -0
  45. package/dist/config-validation.d.ts +18 -0
  46. package/dist/config-validation.d.ts.map +1 -0
  47. package/dist/config-validation.js +30 -0
  48. package/dist/config-validation.js.map +1 -0
  49. package/dist/coverage.d.ts +114 -0
  50. package/dist/coverage.d.ts.map +1 -0
  51. package/dist/coverage.js +0 -0
  52. package/dist/coverage.js.map +1 -0
  53. package/dist/ids.d.ts +12 -0
  54. package/dist/ids.d.ts.map +1 -0
  55. package/dist/ids.js +42 -0
  56. package/dist/ids.js.map +1 -0
  57. package/dist/index.d.ts +55 -0
  58. package/dist/index.d.ts.map +1 -0
  59. package/dist/index.js +18 -0
  60. package/dist/index.js.map +1 -0
  61. package/dist/registry.d.ts +51 -0
  62. package/dist/registry.d.ts.map +1 -0
  63. package/dist/registry.js +86 -0
  64. package/dist/registry.js.map +1 -0
  65. package/dist/staleness.d.ts +44 -0
  66. package/dist/staleness.d.ts.map +1 -0
  67. package/dist/staleness.js +35 -0
  68. package/dist/staleness.js.map +1 -0
  69. package/dist/text/delimiter-balance.d.ts +95 -0
  70. package/dist/text/delimiter-balance.d.ts.map +1 -0
  71. package/dist/text/delimiter-balance.js +209 -0
  72. package/dist/text/delimiter-balance.js.map +1 -0
  73. package/dist/text/line-index.d.ts +61 -0
  74. package/dist/text/line-index.d.ts.map +1 -0
  75. package/dist/text/line-index.js +75 -0
  76. package/dist/text/line-index.js.map +1 -0
  77. package/dist/text/yaml-lite.d.ts +73 -0
  78. package/dist/text/yaml-lite.d.ts.map +1 -0
  79. package/dist/text/yaml-lite.js +486 -0
  80. package/dist/text/yaml-lite.js.map +1 -0
  81. package/package.json +61 -3
  82. package/src/adapters/__golden__/adr-0001-sections.json +68 -0
  83. package/src/adapters/__golden__/app-compose-services.json +24 -0
  84. package/src/adapters/__golden__/app-image-stages.json +24 -0
  85. package/src/adapters/__golden__/infra-main-sections.json +46 -0
  86. package/src/adapters/__golden__/orders-events-operations.json +24 -0
  87. package/src/adapters/__golden__/orders-proto-sections.json +57 -0
  88. package/src/adapters/__golden__/orders-schema-statements.json +68 -0
  89. package/src/adapters/__golden__/users-api-operations.json +46 -0
  90. package/src/adapters/__golden__/web-manifests-resources.json +24 -0
  91. package/src/adapters/asyncapi.ts +147 -0
  92. package/src/adapters/docker.ts +170 -0
  93. package/src/adapters/kubernetes.ts +103 -0
  94. package/src/adapters/markdown.ts +88 -0
  95. package/src/adapters/openapi.ts +156 -0
  96. package/src/adapters/protobuf.ts +286 -0
  97. package/src/adapters/shared.ts +151 -0
  98. package/src/adapters/sql.ts +555 -0
  99. package/src/adapters/terraform.ts +261 -0
  100. package/src/adapters/text.ts +72 -0
  101. package/src/config-validation.ts +41 -0
  102. package/src/coverage.ts +336 -0
  103. package/src/ids.ts +57 -0
  104. package/src/index.ts +105 -0
  105. package/src/registry.ts +155 -0
  106. package/src/staleness.ts +69 -0
  107. package/src/text/delimiter-balance.ts +295 -0
  108. package/src/text/line-index.ts +108 -0
  109. package/src/text/yaml-lite.ts +565 -0
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Kubernetes YAML adapter (architecture.md §20: "je Dokument eine
3
+ * Ressource, apiVersion/kind/name erhalten").
4
+ *
5
+ * Each `---`-separated YAML document in the file becomes exactly one
6
+ * chunk, kind `"kubernetes_resource"`, spanning that document's full line
7
+ * range — Kubernetes manifests are not sectioned further, since a
8
+ * Deployment's `spec.template` is meaningless read apart from its
9
+ * `metadata`. A document whose YAML fails to parse still gets its full raw
10
+ * span turned into a chunk (kind `"kubernetes_resource_parse_error"`, title
11
+ * carries the reason) rather than aborting the whole file: one malformed
12
+ * manifest in a directory of many must not hide the rest (architecture.md
13
+ * §22.2's cross-repo-search principle, applied at document granularity).
14
+ */
15
+ import type { ArtifactAdapter } from "@untangle-code/domain";
16
+ import type { SkipLedgerReporter } from "./shared.js";
17
+ export interface KubernetesAdapterOptions {
18
+ /** Overrides how a real skip-ledger finding surfaces from `chunk()` (default: a stderr warning) — see `coverage.ts`'s `SkipLedgerReporter`. */
19
+ onSkipLedgerGap?: SkipLedgerReporter;
20
+ }
21
+ export declare function createKubernetesAdapter(options?: KubernetesAdapterOptions): ArtifactAdapter;
22
+ //# sourceMappingURL=kubernetes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kubernetes.d.ts","sourceRoot":"","sources":["../../src/adapters/kubernetes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,KAAK,EACV,eAAe,EAKhB,MAAM,uBAAuB,CAAC;AAW/B,OAAO,KAAK,EAAc,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAkClE,MAAM,WAAW,wBAAwB;IACvC,+IAA+I;IAC/I,eAAe,CAAC,EAAE,kBAAkB,CAAC;CACtC;AAED,wBAAgB,uBAAuB,CAAC,OAAO,GAAE,wBAA6B,GAAG,eAAe,CAgC/F"}
@@ -0,0 +1,56 @@
1
+ import { buildLineIndex } from "../text/line-index.js";
2
+ import { mapGet, parseYamlNode, scalarString, splitYamlDocuments, YamlParseError, } from "../text/yaml-lite.js";
3
+ import { buildChunksReportingSkips, buildDocuments } from "./shared.js";
4
+ const YAML_EXTENSION = /\.ya?ml$/i;
5
+ const COMPOSE_FILENAME = /(^|\/)(docker-)?compose\.ya?ml$/i;
6
+ function kubernetesDrafts(content) {
7
+ return splitYamlDocuments(content).map((span) => {
8
+ try {
9
+ const root = parseYamlNode(span.text);
10
+ const apiVersion = scalarString(mapGet(root, "apiVersion"));
11
+ const kind = scalarString(mapGet(root, "kind"));
12
+ const name = scalarString(mapGet(mapGet(root, "metadata"), "name"));
13
+ const title = [apiVersion, kind].filter((part) => part !== undefined).join("/") +
14
+ (name === undefined ? "" : ` ${name}`);
15
+ return {
16
+ kind: "kubernetes_resource",
17
+ startLine: span.startLine,
18
+ endLine: span.endLine,
19
+ ...(title.trim().length === 0 ? {} : { title: title.trim() }),
20
+ };
21
+ }
22
+ catch (error) {
23
+ const reason = error instanceof YamlParseError ? error.message : "unknown parse error";
24
+ return {
25
+ kind: "kubernetes_resource_parse_error",
26
+ startLine: span.startLine,
27
+ endLine: span.endLine,
28
+ title: `parse error: ${reason}`,
29
+ };
30
+ }
31
+ });
32
+ }
33
+ export function createKubernetesAdapter(options = {}) {
34
+ return {
35
+ supports(type, path) {
36
+ // "auto" detection only claims .yaml/.yml files that are not a
37
+ // Compose file (see docker.ts) — every other ambiguous case (a plain
38
+ // config .yaml, an OpenAPI/AsyncAPI file without a name hint) should
39
+ // be configured with an explicit `type`, since path alone cannot
40
+ // disambiguate them (spec.md §19.1's `supports` has no content
41
+ // access — see README "Entscheidungen").
42
+ return (type === "kubernetes" ||
43
+ (type === "auto" && YAML_EXTENSION.test(path) && !COMPOSE_FILENAME.test(path)));
44
+ },
45
+ async read(input) {
46
+ return buildDocuments(input, "kubernetes");
47
+ },
48
+ chunk(document) {
49
+ return buildChunksReportingSkips(document, buildLineIndex(document.content), kubernetesDrafts(document.content), options.onSkipLedgerGap);
50
+ },
51
+ links() {
52
+ return [];
53
+ },
54
+ };
55
+ }
56
+ //# sourceMappingURL=kubernetes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kubernetes.js","sourceRoot":"","sources":["../../src/adapters/kubernetes.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Markdown / ADR adapter (architecture.md §20, spec.md §19.2 "semantische
3
+ * Abschnitte statt fester Zeilenfenster").
4
+ *
5
+ * ADRs are not a separate `ContextArtifactType` (spec.md §19.1's type union
6
+ * has no "adr" literal — an Architecture Decision Record IS a Markdown
7
+ * document, conventionally with `## Status`/`## Context`/`## Decision`/
8
+ * `## Consequences` headings) — this one adapter's heading-based sectioning
9
+ * handles both.
10
+ *
11
+ * WP-110: the sectioning itself no longer lives here. It moved verbatim to
12
+ * `@untangle-code/domain`'s `outlineMarkdown()` so that the SAME partition
13
+ * also serves ordinary `.md` files through the parser-registry prose adapter
14
+ * and the prose metrics — before that move, a configured artifact got
15
+ * breadcrumbed sections while the identical file outside an artifact
16
+ * configuration got arbitrary line windows. Behaviour here is unchanged; the
17
+ * implementation is simply no longer duplicated.
18
+ *
19
+ * Sectioning (defined on `outlineMarkdown`): each ATX heading (`#` …
20
+ * `######`, ignored inside fenced code blocks) starts a new chunk that runs
21
+ * up to the START of the very next heading of ANY level (or EOF) — a flat
22
+ * partition of the file with no overlap. Each chunk's `title` carries the
23
+ * breadcrumb (ancestor headings joined by " › ") instead, so the hierarchy
24
+ * is still fully recoverable even though `content` stays the exact raw slice
25
+ * — the breadcrumb is never spliced into the preserved raw content
26
+ * (spec.md §19.2).
27
+ */
28
+ import type { ArtifactAdapter } from "@untangle-code/domain";
29
+ import type { SkipLedgerReporter } from "./shared.js";
30
+ export interface MarkdownAdapterOptions {
31
+ /** Overrides how a real skip-ledger finding surfaces from `chunk()` (default: a stderr warning) — see `coverage.ts`'s `SkipLedgerReporter`. */
32
+ onSkipLedgerGap?: SkipLedgerReporter;
33
+ }
34
+ export declare function createMarkdownAdapter(options?: MarkdownAdapterOptions): ArtifactAdapter;
35
+ //# sourceMappingURL=markdown.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markdown.d.ts","sourceRoot":"","sources":["../../src/adapters/markdown.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,OAAO,KAAK,EACV,eAAe,EAKhB,MAAM,uBAAuB,CAAC;AAK/B,OAAO,KAAK,EAAc,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAmBlE,MAAM,WAAW,sBAAsB;IACrC,+IAA+I;IAC/I,eAAe,CAAC,EAAE,kBAAkB,CAAC;CACtC;AAED,wBAAgB,qBAAqB,CAAC,OAAO,GAAE,sBAA2B,GAAG,eAAe,CAyB3F"}
@@ -0,0 +1,36 @@
1
+ import { outlineMarkdown } from "@untangle-code/domain";
2
+ import { buildLineIndex, splitLines } from "../text/line-index.js";
3
+ import { buildChunksReportingSkips, buildDocuments } from "./shared.js";
4
+ const MARKDOWN_EXTENSION = /\.(md|markdown|mdx)$/i;
5
+ function markdownDrafts(lines) {
6
+ return outlineMarkdown(lines).map((section) => {
7
+ const draft = {
8
+ kind: "markdown_section",
9
+ startLine: section.startLine,
10
+ endLine: section.endLine,
11
+ };
12
+ // Der Vorspann vor der ersten Ueberschrift hat keinen Breadcrumb; ein
13
+ // leerer `title` waere eine Behauptung ueber eine Ueberschrift, die es
14
+ // nicht gibt.
15
+ return section.breadcrumb === "" ? draft : { ...draft, title: section.breadcrumb };
16
+ });
17
+ }
18
+ export function createMarkdownAdapter(options = {}) {
19
+ return {
20
+ supports(type, path) {
21
+ return type === "markdown" || (type === "auto" && MARKDOWN_EXTENSION.test(path));
22
+ },
23
+ async read(input) {
24
+ return buildDocuments(input, "markdown");
25
+ },
26
+ chunk(document) {
27
+ const { lines } = splitLines(document.content);
28
+ const index = buildLineIndex(document.content);
29
+ return buildChunksReportingSkips(document, index, markdownDrafts(lines), options.onSkipLedgerGap);
30
+ },
31
+ links() {
32
+ return [];
33
+ },
34
+ };
35
+ }
36
+ //# sourceMappingURL=markdown.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markdown.js","sourceRoot":"","sources":["../../src/adapters/markdown.ts"],"names":[],"mappings":"AAkCA,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAExD,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAGnE,OAAO,EAAE,yBAAyB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAExE,MAAM,kBAAkB,GAAG,uBAAuB,CAAC;AAEnD,SAAS,cAAc,CAAC,KAAe;IACrC,OAAO,eAAe,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE;QAC5C,MAAM,KAAK,GAAe;YACxB,IAAI,EAAE,kBAAkB;YACxB,SAAS,EAAE,OAAO,CAAC,SAAS;YAC5B,OAAO,EAAE,OAAO,CAAC,OAAO;SACzB,CAAC;QACF,sEAAsE;QACtE,uEAAuE;QACvE,cAAc;QACd,OAAO,OAAO,CAAC,UAAU,KAAK,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,KAAK,EAAE,KAAK,EAAE,OAAO,CAAC,UAAU,EAAE,CAAC;IACrF,CAAC,CAAC,CAAC;AACL,CAAC;AAOD,MAAM,UAAU,qBAAqB,CAAC,UAAkC,EAAE;IACxE,OAAO;QACL,QAAQ,CAAC,IAAY,EAAE,IAAY;YACjC,OAAO,IAAI,KAAK,UAAU,IAAI,CAAC,IAAI,KAAK,MAAM,IAAI,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QACnF,CAAC;QAED,KAAK,CAAC,IAAI,CAAC,KAAoB;YAC7B,OAAO,cAAc,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;QAC3C,CAAC;QAED,KAAK,CAAC,QAA0B;YAC9B,MAAM,EAAE,KAAK,EAAE,GAAG,UAAU,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;YAC/C,MAAM,KAAK,GAAG,cAAc,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;YAC/C,OAAO,yBAAyB,CAC9B,QAAQ,EACR,KAAK,EACL,cAAc,CAAC,KAAK,CAAC,EACrB,OAAO,CAAC,eAAe,CACxB,CAAC;QACJ,CAAC;QAED,KAAK;YACH,OAAO,EAAE,CAAC;QACZ,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * OpenAPI adapter (architecture.md §20: "je Operation ein Abschnitt,
3
+ * Operation-IDs erhalten").
4
+ *
5
+ * Parses the document with the package's YAML subset parser
6
+ * (`text/yaml-lite.ts`) and emits one chunk per `paths.<path>.<method>`
7
+ * operation, titled with the HTTP method, path and (when present)
8
+ * `operationId` — never dropped even when absent from the title, since
9
+ * `content` is always the exact raw YAML block, `operationId` field
10
+ * included. A malformed document degrades to a single whole-document
11
+ * `"openapi_parse_error"` chunk (architecture.md §22.2) rather than
12
+ * throwing — the raw content is still fully preserved in that chunk.
13
+ */
14
+ import type { ArtifactAdapter } from "@untangle-code/domain";
15
+ import type { SkipLedgerReporter } from "./shared.js";
16
+ export interface OpenApiAdapterOptions {
17
+ /** Overrides how a real skip-ledger finding surfaces from `chunk()` (default: a stderr warning) — see `coverage.ts`'s `SkipLedgerReporter`. */
18
+ onSkipLedgerGap?: SkipLedgerReporter;
19
+ }
20
+ export declare function createOpenApiAdapter(options?: OpenApiAdapterOptions): ArtifactAdapter;
21
+ //# sourceMappingURL=openapi.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openapi.d.ts","sourceRoot":"","sources":["../../src/adapters/openapi.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,KAAK,EACV,eAAe,EAKhB,MAAM,uBAAuB,CAAC;AAW/B,OAAO,KAAK,EAAc,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAyElE,MAAM,WAAW,qBAAqB;IACpC,+IAA+I;IAC/I,eAAe,CAAC,EAAE,kBAAkB,CAAC;CACtC;AAED,wBAAgB,oBAAoB,CAAC,OAAO,GAAE,qBAA0B,GAAG,eAAe,CA+CzF"}
@@ -0,0 +1,101 @@
1
+ import { buildLineIndex } from "../text/line-index.js";
2
+ import { mapGet, parseYamlNode, scalarString, YamlParseError, } from "../text/yaml-lite.js";
3
+ import { buildChunks, buildChunksReportingSkips, buildDocuments, wholeDocumentDraft, } from "./shared.js";
4
+ const OPENAPI_NAME_HINT = /openapi/i;
5
+ const YAML_OR_JSON_EXTENSION = /\.(ya?ml|json)$/i;
6
+ const HTTP_METHODS = ["get", "put", "post", "delete", "options", "head", "patch", "trace"];
7
+ function openApiDrafts(root) {
8
+ if (root === null || root.kind !== "map")
9
+ return [];
10
+ const drafts = [];
11
+ const info = mapGet(root, "info");
12
+ if (info !== undefined) {
13
+ const title = scalarString(mapGet(info, "title"));
14
+ drafts.push({
15
+ kind: "openapi_info",
16
+ startLine: info.startLine,
17
+ endLine: info.endLine,
18
+ ...(title === undefined ? {} : { title: `info: ${title}` }),
19
+ });
20
+ }
21
+ const paths = mapGet(root, "paths");
22
+ if (paths !== undefined && paths.kind === "map") {
23
+ for (const pathEntry of paths.entries) {
24
+ if (pathEntry.value.kind !== "map")
25
+ continue;
26
+ for (const methodEntry of pathEntry.value.entries) {
27
+ const method = methodEntry.key.toLowerCase();
28
+ if (!HTTP_METHODS.includes(method))
29
+ continue;
30
+ const operationId = scalarString(mapGet(methodEntry.value, "operationId"));
31
+ const title = operationId === undefined
32
+ ? `${method.toUpperCase()} ${pathEntry.key}`
33
+ : `${method.toUpperCase()} ${pathEntry.key} (${operationId})`;
34
+ drafts.push({
35
+ kind: "openapi_operation",
36
+ startLine: methodEntry.value.startLine,
37
+ endLine: methodEntry.value.endLine,
38
+ title,
39
+ });
40
+ }
41
+ }
42
+ }
43
+ return drafts;
44
+ }
45
+ function operationIdOf(chunk) {
46
+ if (chunk.kind !== "openapi_operation" || chunk.title === undefined)
47
+ return undefined;
48
+ const match = /\(([^()]+)\)$/.exec(chunk.title);
49
+ return match?.[1];
50
+ }
51
+ function draftsFor(document) {
52
+ try {
53
+ return openApiDrafts(parseYamlNode(document.content));
54
+ }
55
+ catch (error) {
56
+ const reason = error instanceof YamlParseError ? error.message : "unknown parse error";
57
+ return [
58
+ wholeDocumentDraft("openapi_parse_error", buildLineIndex(document.content), `parse error: ${reason}`),
59
+ ];
60
+ }
61
+ }
62
+ export function createOpenApiAdapter(options = {}) {
63
+ return {
64
+ supports(type, path) {
65
+ return (type === "openapi" ||
66
+ (type === "auto" && OPENAPI_NAME_HINT.test(path) && YAML_OR_JSON_EXTENSION.test(path)));
67
+ },
68
+ async read(input) {
69
+ return buildDocuments(input, "openapi");
70
+ },
71
+ chunk(document) {
72
+ return buildChunksReportingSkips(document, buildLineIndex(document.content), draftsFor(document), options.onSkipLedgerGap);
73
+ },
74
+ /**
75
+ * Heuristic (architecture.md §20's canonical example): assumes the
76
+ * common REST-codegen convention that a controller method is named
77
+ * after the operation's `operationId`. No AST/symbol table is
78
+ * consulted here — `targetId` stays unset; a later graph-linking stage
79
+ * resolves `targetName` against real symbols, if any match.
80
+ */
81
+ links(document) {
82
+ const chunks = buildChunks(document, buildLineIndex(document.content), draftsFor(document));
83
+ const links = [];
84
+ for (const chunk of chunks) {
85
+ const operationId = operationIdOf(chunk);
86
+ if (operationId === undefined)
87
+ continue;
88
+ links.push({
89
+ fromChunkId: chunk.chunkId,
90
+ targetKind: "symbol",
91
+ targetName: operationId,
92
+ heuristic: true,
93
+ confidence: 0.5,
94
+ note: `naming-convention guess: OpenAPI operationId "${operationId}" → a controller method of the same name`,
95
+ });
96
+ }
97
+ return links;
98
+ },
99
+ };
100
+ }
101
+ //# sourceMappingURL=openapi.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openapi.js","sourceRoot":"","sources":["../../src/adapters/openapi.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Protobuf adapter (architecture.md §20: "Messages, Services, RPCs").
3
+ *
4
+ * Brace-depth line scanning (no full grammar needed): a top-level
5
+ * (depth-0) `message Foo {` or `service Foo {` opens a block that runs to
6
+ * its matching `}`. Nested `message`s inside another message are part of
7
+ * the parent's content (not chunked separately — a deliberate scope limit,
8
+ * see README "Entscheidungen"; their bytes are still fully present in the
9
+ * parent chunk's content, so nothing is silently dropped). Inside a
10
+ * `service` block, each `rpc Name(...) returns (...);` additionally gets
11
+ * its own finer-grained chunk — intentionally OVERLAPPING the enclosing
12
+ * service chunk's range, so a search hit on one RPC's name returns a tight
13
+ * chunk while a hit on shared service-level comments/options still returns
14
+ * full context.
15
+ *
16
+ * The brace counter is string/comment-aware (WP-81 review finding: a `{` or
17
+ * `}` inside a string default value, e.g. `[default = "{"]`, or inside a
18
+ * `//`/`/* *\/` comment, must never move the depth counter — a naive raw
19
+ * count desyncs PERMANENTLY on such a line, degrading "runs to EOF" and
20
+ * silently swallowing every following top-level block). `scanLine` below
21
+ * carries string/block-comment state across lines through ONE continuous
22
+ * scan (a single shared `ScanState`, not a fresh one per block) — depth is
23
+ * tracked exactly once per line, not once in this function and again in a
24
+ * separate look-ahead, so there is only one source of truth for "are we
25
+ * inside a string/comment right now" across the whole file.
26
+ */
27
+ import type { ArtifactAdapter } from "@untangle-code/domain";
28
+ import type { SkipLedgerReporter } from "./shared.js";
29
+ export interface ProtobufAdapterOptions {
30
+ /** Overrides how a real skip-ledger finding surfaces from `chunk()` (default: a stderr warning) — see `coverage.ts`'s `SkipLedgerReporter`. */
31
+ onSkipLedgerGap?: SkipLedgerReporter;
32
+ }
33
+ export declare function createProtobufAdapter(options?: ProtobufAdapterOptions): ArtifactAdapter;
34
+ //# sourceMappingURL=protobuf.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"protobuf.d.ts","sourceRoot":"","sources":["../../src/adapters/protobuf.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,OAAO,KAAK,EACV,eAAe,EAKhB,MAAM,uBAAuB,CAAC;AAM/B,OAAO,KAAK,EAAsC,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAgM1F,MAAM,WAAW,sBAAsB;IACrC,+IAA+I;IAC/I,eAAe,CAAC,EAAE,kBAAkB,CAAC;CACtC;AAED,wBAAgB,qBAAqB,CAAC,OAAO,GAAE,sBAA2B,GAAG,eAAe,CAkD3F"}
@@ -0,0 +1,221 @@
1
+ import { describeDelimiterImbalances, findDelimiterImbalances } from "../text/delimiter-balance.js";
2
+ import { buildLineIndex, splitLines } from "../text/line-index.js";
3
+ import { buildChunks, buildChunksReportingSkips, buildDocuments } from "./shared.js";
4
+ const PROTO_EXTENSION = /\.proto$/i;
5
+ const MESSAGE_RE = /^\s*message\s+([\w.]+)\s*\{/;
6
+ const SERVICE_RE = /^\s*service\s+([\w.]+)\s*\{/;
7
+ const RPC_RE = /^\s*rpc\s+(\w+)\s*\(/;
8
+ /**
9
+ * Net brace delta for one line, skipping `'...'`/`"..."` string literals
10
+ * (with `\`-escapes) and `//`/`/* *\/` comments, so a brace character
11
+ * inside either never affects depth. `state` is mutated in place for
12
+ * anything that spans past this line's end (an unterminated string or an
13
+ * open block comment) — the NEXT call for the following line continues
14
+ * from exactly that state, which is what makes the counter immune to
15
+ * per-line resets.
16
+ */
17
+ function scanLine(line, state) {
18
+ let delta = 0;
19
+ for (let i = 0; i < line.length; i += 1) {
20
+ const c = line[i];
21
+ const next = line[i + 1];
22
+ if (state.inBlockComment) {
23
+ if (c === "*" && next === "/") {
24
+ state.inBlockComment = false;
25
+ i += 1;
26
+ }
27
+ continue;
28
+ }
29
+ if (state.inSingle) {
30
+ if (c === "\\") {
31
+ i += 1;
32
+ }
33
+ else if (c === "'") {
34
+ state.inSingle = false;
35
+ }
36
+ continue;
37
+ }
38
+ if (state.inDouble) {
39
+ if (c === "\\") {
40
+ i += 1;
41
+ }
42
+ else if (c === '"') {
43
+ state.inDouble = false;
44
+ }
45
+ continue;
46
+ }
47
+ if (c === "/" && next === "/") {
48
+ break; // line comment: rest of the line is never code, and cannot itself open a block comment
49
+ }
50
+ if (c === "/" && next === "*") {
51
+ state.inBlockComment = true;
52
+ i += 1;
53
+ continue;
54
+ }
55
+ if (c === "'") {
56
+ state.inSingle = true;
57
+ continue;
58
+ }
59
+ if (c === '"') {
60
+ state.inDouble = true;
61
+ continue;
62
+ }
63
+ if (c === "{")
64
+ delta += 1;
65
+ else if (c === "}")
66
+ delta -= 1;
67
+ }
68
+ return delta;
69
+ }
70
+ /**
71
+ * Letzte Zeile einer `rpc`-Deklaration.
72
+ *
73
+ * Zwei Formen: die Kurzform endet an ihrem `;` (das bei mehrzeiliger
74
+ * Signatur erst auf einer späteren Zeile steht), die Langform an der
75
+ * schließenden `}` ihres Optionsrumpfs. WP-118: bisher wurde nur die erste
76
+ * Form erkannt, also endete `rpc A(X) returns (Y) {` schon an der ersten
77
+ * `;` IM RUMPF — mitten im Konstrukt, mit fehlender schließender Klammer,
78
+ * und ohne Ledger-Eintrag, weil die Range des Service-Chunks alles
79
+ * abdeckte. Der Klammerstand wird deshalb mitgezählt.
80
+ */
81
+ function findRpcEnd(lines, startIndex, hardLimit) {
82
+ const state = { inSingle: false, inDouble: false, inBlockComment: false };
83
+ let depth = 0;
84
+ for (let i = startIndex; i < hardLimit; i += 1) {
85
+ const line = lines[i] ?? "";
86
+ const depthBefore = depth;
87
+ depth += scanLine(line, state);
88
+ if (depthBefore > 0 && depth === 0)
89
+ return i + 1; // Optionsrumpf geschlossen
90
+ if (depthBefore === 0 && depth === 0 && (line.includes(";") || line.includes("}")))
91
+ return i + 1;
92
+ }
93
+ return hardLimit;
94
+ }
95
+ /** Pushes `pending`'s finished draft (and, for a service, its nested RPC drafts scanned from its now-final range) into `drafts`. */
96
+ function finalizePendingBlock(drafts, lines, pending, endLine) {
97
+ drafts.push({ kind: pending.kind, startLine: pending.startLine, endLine, title: pending.title });
98
+ if (pending.kind !== "protobuf_service")
99
+ return;
100
+ for (let j = pending.startLine - 1; j < endLine; j += 1) {
101
+ const rpc = RPC_RE.exec(lines[j] ?? "");
102
+ if (rpc) {
103
+ const rpcEnd = findRpcEnd(lines, j, endLine);
104
+ drafts.push({
105
+ kind: "protobuf_rpc",
106
+ startLine: j + 1,
107
+ endLine: rpcEnd,
108
+ title: `${pending.title}.${rpc[1]}`,
109
+ });
110
+ }
111
+ }
112
+ }
113
+ function protobufDrafts(lines) {
114
+ const drafts = [];
115
+ const state = { inSingle: false, inDouble: false, inBlockComment: false };
116
+ let depth = 0;
117
+ let pending;
118
+ for (let i = 0; i < lines.length; i += 1) {
119
+ const line = lines[i] ?? "";
120
+ if (depth === 0 && pending === undefined) {
121
+ const message = MESSAGE_RE.exec(line);
122
+ const service = SERVICE_RE.exec(line);
123
+ if (message) {
124
+ pending = { kind: "protobuf_message", title: message[1], startLine: i + 1 };
125
+ }
126
+ else if (service) {
127
+ pending = { kind: "protobuf_service", title: service[1], startLine: i + 1 };
128
+ }
129
+ }
130
+ depth += scanLine(line, state);
131
+ if (pending !== undefined && depth === 0) {
132
+ finalizePendingBlock(drafts, lines, pending, i + 1);
133
+ pending = undefined;
134
+ }
135
+ }
136
+ if (pending !== undefined) {
137
+ // Unterminated top-level block (malformed source, or a still-open
138
+ // string/comment at EOF): degrade to "runs to EOF" rather than
139
+ // dropping it — never silently, see the module doc.
140
+ finalizePendingBlock(drafts, lines, pending, Math.max(lines.length, pending.startLine));
141
+ }
142
+ return drafts;
143
+ }
144
+ /**
145
+ * Trennzeichen-Konventionen für die Plausibilitätsprüfung (WP-118).
146
+ * Zeichenketten dürfen keine Zeile überschreiten — ein Anführungszeichen,
147
+ * das bis zum Zeilenende offen bleibt, ist in Protobuf bereits ein Befund.
148
+ */
149
+ const PROTOBUF_SCAN_OPTIONS = {
150
+ quotes: [
151
+ { open: "'", close: "'", backslashEscapes: true, doubledEscapes: false, spansLines: false },
152
+ { open: '"', close: '"', backslashEscapes: true, doubledEscapes: false, spansLines: false },
153
+ ],
154
+ brackets: [
155
+ { open: "{", close: "}" },
156
+ { open: "(", close: ")" },
157
+ { open: "[", close: "]" },
158
+ ],
159
+ lineComments: ["//"],
160
+ blockComment: { open: "/*", close: "*/" },
161
+ };
162
+ /**
163
+ * WP-118 (dieselbe Blindstelle wie in `sql.ts`): der Blockzähler dieses
164
+ * Adapters degradiert einen unabgeschlossenen Top-Level-Block zu „läuft
165
+ * bis Dateiende". Die Byte-Abdeckung bleibt dabei lückenlos, der Chunk ist
166
+ * weder leer noch überlappend — der Ledger sah also NICHTS, obwohl der
167
+ * Blockzähler nachweislich aus dem Tritt geraten war. Ein Fragment mit
168
+ * offener Klammer, offener Zeichenkette oder offenem Kommentar ist jetzt
169
+ * ein Befund.
170
+ */
171
+ const checkProtobufPlausibility = (chunk) => {
172
+ const imbalances = findDelimiterImbalances(chunk.content, PROTOBUF_SCAN_OPTIONS);
173
+ return imbalances.length === 0 ? undefined : describeDelimiterImbalances(imbalances);
174
+ };
175
+ function messageName(chunk) {
176
+ return chunk.kind === "protobuf_service" ? chunk.title : undefined;
177
+ }
178
+ export function createProtobufAdapter(options = {}) {
179
+ return {
180
+ supports(type, path) {
181
+ return type === "protobuf" || (type === "auto" && PROTO_EXTENSION.test(path));
182
+ },
183
+ async read(input) {
184
+ return buildDocuments(input, "protobuf");
185
+ },
186
+ chunk(document) {
187
+ const { lines } = splitLines(document.content);
188
+ const index = buildLineIndex(document.content);
189
+ return buildChunksReportingSkips(document, index, protobufDrafts(lines), options.onSkipLedgerGap, checkProtobufPlausibility);
190
+ },
191
+ /**
192
+ * Heuristic (architecture.md §20): a gRPC service `FooService` often
193
+ * backs a generated/handwritten server symbol named `FooServiceServer`
194
+ * or `FooServiceImpl`. Both are offered as separate low-confidence
195
+ * hints — this is a naming guess, not a resolved reference.
196
+ */
197
+ links(document) {
198
+ const { lines } = splitLines(document.content);
199
+ const index = buildLineIndex(document.content);
200
+ const chunks = buildChunks(document, index, protobufDrafts(lines));
201
+ const links = [];
202
+ for (const chunk of chunks) {
203
+ const name = messageName(chunk);
204
+ if (name === undefined)
205
+ continue;
206
+ for (const suffix of ["Server", "Impl"]) {
207
+ links.push({
208
+ fromChunkId: chunk.chunkId,
209
+ targetKind: "symbol",
210
+ targetName: `${name}${suffix}`,
211
+ heuristic: true,
212
+ confidence: 0.3,
213
+ note: `naming-convention guess: gRPC service "${name}" → generated/handwritten server symbol`,
214
+ });
215
+ }
216
+ }
217
+ return links;
218
+ },
219
+ };
220
+ }
221
+ //# sourceMappingURL=protobuf.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"protobuf.js","sourceRoot":"","sources":["../../src/adapters/protobuf.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,65 @@
1
+ /**
2
+ * Helpers shared by every concrete format adapter in `src/adapters/`.
3
+ */
4
+ import type { ArtifactChunk, ArtifactDocument, ArtifactInput, ContextArtifactType } from "@untangle-code/domain";
5
+ import { type ChunkPlausibilityCheck, type SkipLedgerReporter } from "../coverage.js";
6
+ import type { LineIndex } from "../text/line-index.js";
7
+ export type { ChunkPlausibilityCheck, SkipLedgerReporter } from "../coverage.js";
8
+ /** Builds one `ArtifactDocument` per file in `input.files` (spec.md §19.2: files AND directories). */
9
+ export declare function buildDocuments(input: ArtifactInput, type: Exclude<ContextArtifactType, "auto">, language?: string): ArtifactDocument[];
10
+ export interface ChunkDraft {
11
+ kind: string;
12
+ startLine: number;
13
+ endLine: number;
14
+ title?: string;
15
+ /**
16
+ * Optional exact byte range, used instead of `rangeForLines(index,
17
+ * startLine, endLine)` when a draft's true boundary does not land on a
18
+ * whole-line boundary — e.g. two SQL statements sharing one physical
19
+ * line, each needing its own non-overlapping byte span within that one
20
+ * line. `startLine`/`endLine` are still required (and still used for the
21
+ * chunk's `range.startLine`/`endLine`) so every draft has a human-facing
22
+ * line reference even when its bytes are sub-line-precise. Omitted by
23
+ * every adapter that only ever splits on whole lines (the common case).
24
+ */
25
+ startByte?: number;
26
+ endByte?: number;
27
+ }
28
+ /**
29
+ * Turns line-range drafts into fully-formed `ArtifactChunk`s: computes
30
+ * `range` (via `index`, or the draft's own `startByte`/`endByte` when
31
+ * given), byte-exact `content` (a slice of the SAME buffer `index` was
32
+ * built from — never a re-encoded copy, so content is always byte-identical
33
+ * to the source, spec.md §19.2), `contentHash`, and a deterministic
34
+ * `chunkId` (ordinal = position in `drafts`).
35
+ */
36
+ export declare function buildChunks(document: ArtifactDocument, index: LineIndex, drafts: ChunkDraft[]): ArtifactChunk[];
37
+ /** A single chunk spanning the whole document, used for parse-error degrades and the text fallback's single-window case. */
38
+ export declare function wholeDocumentDraft(kind: string, index: LineIndex, title?: string): ChunkDraft;
39
+ /**
40
+ * `buildChunks`, plus BUILD_PLAN §12 E4: `buildArtifactSkipLedger()` must
41
+ * never be a "Bringschuld" (an obligation a caller has to remember) —
42
+ * every format adapter's `chunk()` calls this instead of `buildChunks`
43
+ * directly, so a loss becomes visible in the SAME call that produces
44
+ * chunks, with zero extra action from whoever calls `adapter.chunk()`.
45
+ *
46
+ * `checkPlausibility` (optional, WP-118) reicht die formatspezifische
47
+ * Plausibilitätsprüfung des Adapters an den Ledger durch: ein Fragment,
48
+ * das MITTEN DURCH ein Konstrukt geschnitten wurde, ist auch dann ein
49
+ * Befund, wenn die Byte-Abdeckung lückenlos ist. Siehe
50
+ * `coverage.ts::ChunkPlausibilityCheck` und `text/delimiter-balance.ts`.
51
+ *
52
+ * Only entries beyond plain `"whitespace_or_comment"` are reported —
53
+ * `"unclassified_content"` and `"semantic_loss"` are the two reasons that
54
+ * indicate a real problem (see coverage.ts's module doc); a benign gap
55
+ * between two well-formed sections is expected and stays silent here too,
56
+ * exactly as it does for a caller who inspects the ledger directly.
57
+ *
58
+ * `report` defaults to `defaultSkipLedgerReporter` (a single stderr line
59
+ * per finding) but every `create*Adapter()` factory accepts an
60
+ * `onSkipLedgerGap` override — inject a real structured logger, a test
61
+ * spy, or a no-op, without this package depending on any particular
62
+ * logging implementation.
63
+ */
64
+ export declare function buildChunksReportingSkips(document: ArtifactDocument, index: LineIndex, drafts: ChunkDraft[], report?: SkipLedgerReporter, checkPlausibility?: ChunkPlausibilityCheck): ArtifactChunk[];
65
+ //# sourceMappingURL=shared.d.ts.map