doc-detective 4.29.0 → 4.30.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 (87) hide show
  1. package/bin/doc-detective-lsp.js +6 -0
  2. package/dist/cli.js +58 -35
  3. package/dist/cli.js.map +1 -1
  4. package/dist/common/src/schemas/schemas.json +56 -56
  5. package/dist/common/src/validate.d.ts +16 -1
  6. package/dist/common/src/validate.d.ts.map +1 -1
  7. package/dist/common/src/validate.js +113 -13
  8. package/dist/common/src/validate.js.map +1 -1
  9. package/dist/core/config.d.ts +66 -1
  10. package/dist/core/config.d.ts.map +1 -1
  11. package/dist/core/config.js +121 -68
  12. package/dist/core/config.js.map +1 -1
  13. package/dist/core/detectTests.d.ts.map +1 -1
  14. package/dist/core/detectTests.js +105 -23
  15. package/dist/core/detectTests.js.map +1 -1
  16. package/dist/core/index.d.ts.map +1 -1
  17. package/dist/core/index.js +53 -14
  18. package/dist/core/index.js.map +1 -1
  19. package/dist/core/openapi.d.ts.map +1 -1
  20. package/dist/core/openapi.js +22 -5
  21. package/dist/core/openapi.js.map +1 -1
  22. package/dist/core/resolveTests.d.ts.map +1 -1
  23. package/dist/core/resolveTests.js +33 -2
  24. package/dist/core/resolveTests.js.map +1 -1
  25. package/dist/core/tests/findStrategies.d.ts.map +1 -1
  26. package/dist/core/tests/findStrategies.js +83 -10
  27. package/dist/core/tests/findStrategies.js.map +1 -1
  28. package/dist/core/tests/saveScreenshot.d.ts.map +1 -1
  29. package/dist/core/tests/saveScreenshot.js +101 -59
  30. package/dist/core/tests/saveScreenshot.js.map +1 -1
  31. package/dist/core/utils.d.ts.map +1 -1
  32. package/dist/core/utils.js +13 -4
  33. package/dist/core/utils.js.map +1 -1
  34. package/dist/index.cjs +356 -196
  35. package/dist/lsp/command.d.ts +12 -0
  36. package/dist/lsp/command.d.ts.map +1 -0
  37. package/dist/lsp/command.js +24 -0
  38. package/dist/lsp/command.js.map +1 -0
  39. package/dist/lsp/completion.d.ts +27 -0
  40. package/dist/lsp/completion.d.ts.map +1 -0
  41. package/dist/lsp/completion.js +114 -0
  42. package/dist/lsp/completion.js.map +1 -0
  43. package/dist/lsp/diagnostics.d.ts +21 -0
  44. package/dist/lsp/diagnostics.d.ts.map +1 -0
  45. package/dist/lsp/diagnostics.js +137 -0
  46. package/dist/lsp/diagnostics.js.map +1 -0
  47. package/dist/lsp/gate.d.ts +30 -0
  48. package/dist/lsp/gate.d.ts.map +1 -0
  49. package/dist/lsp/gate.js +80 -0
  50. package/dist/lsp/gate.js.map +1 -0
  51. package/dist/lsp/hover.d.ts +9 -0
  52. package/dist/lsp/hover.d.ts.map +1 -0
  53. package/dist/lsp/hover.js +56 -0
  54. package/dist/lsp/hover.js.map +1 -0
  55. package/dist/lsp/inline.d.ts +25 -0
  56. package/dist/lsp/inline.d.ts.map +1 -0
  57. package/dist/lsp/inline.js +208 -0
  58. package/dist/lsp/inline.js.map +1 -0
  59. package/dist/lsp/json/positions.d.ts +51 -0
  60. package/dist/lsp/json/positions.d.ts.map +1 -0
  61. package/dist/lsp/json/positions.js +101 -0
  62. package/dist/lsp/json/positions.js.map +1 -0
  63. package/dist/lsp/messages.d.ts +27 -0
  64. package/dist/lsp/messages.d.ts.map +1 -0
  65. package/dist/lsp/messages.js +33 -0
  66. package/dist/lsp/messages.js.map +1 -0
  67. package/dist/lsp/model.d.ts +27 -0
  68. package/dist/lsp/model.d.ts.map +1 -0
  69. package/dist/lsp/model.js +49 -0
  70. package/dist/lsp/model.js.map +1 -0
  71. package/dist/lsp/registry.d.ts +61 -0
  72. package/dist/lsp/registry.d.ts.map +1 -0
  73. package/dist/lsp/registry.js +124 -0
  74. package/dist/lsp/registry.js.map +1 -0
  75. package/dist/lsp/server.d.ts +40 -0
  76. package/dist/lsp/server.d.ts.map +1 -0
  77. package/dist/lsp/server.js +64 -0
  78. package/dist/lsp/server.js.map +1 -0
  79. package/dist/lsp/yaml/positions.d.ts +32 -0
  80. package/dist/lsp/yaml/positions.d.ts.map +1 -0
  81. package/dist/lsp/yaml/positions.js +92 -0
  82. package/dist/lsp/yaml/positions.js.map +1 -0
  83. package/dist/utils.d.ts.map +1 -1
  84. package/dist/utils.js +30 -5
  85. package/dist/utils.js.map +1 -1
  86. package/package.json +6 -2
  87. package/scripts/postinstall.js +144 -1
@@ -0,0 +1,208 @@
1
+ import { DiagnosticSeverity, } from "vscode-languageserver";
2
+ import { validate } from "../common/src/validate.js";
3
+ import { parseObject } from "../common/src/detectTests.js";
4
+ import { defaultFileTypes } from "../common/src/fileTypes.js";
5
+ import { basenameFromUri } from "./gate.js";
6
+ import { getRegistry } from "./registry.js";
7
+ import { pointerFromPath } from "./json/positions.js";
8
+ import { DIAGNOSTIC_SOURCE, ACTION_KEYED_MESSAGE, V2_DEPRECATION_MESSAGE, schemaMessage, } from "./messages.js";
9
+ /**
10
+ * The fileTypes whose inline test statements we understand, keyed for lookup by
11
+ * extension. Derived from the runner's own `defaultFileTypes` so the detection
12
+ * patterns can never drift from what the runner parses.
13
+ */
14
+ const MARKUP_FILE_TYPES = [
15
+ defaultFileTypes.markdown,
16
+ defaultFileTypes.asciidoc,
17
+ defaultFileTypes.html,
18
+ defaultFileTypes.dita,
19
+ ].filter(Boolean);
20
+ /** Find the fileType whose extensions match this URI, or null. */
21
+ export function fileTypeForUri(uri) {
22
+ const name = basenameFromUri(uri);
23
+ for (const fileType of MARKUP_FILE_TYPES) {
24
+ /* c8 ignore next - every default fileType has extensions; `|| []` guards custom ones */
25
+ for (const ext of fileType.extensions || []) {
26
+ if (name.endsWith(`.${ext.toLowerCase()}`))
27
+ return fileType;
28
+ }
29
+ }
30
+ return null;
31
+ }
32
+ /** Compile a pattern with the global + hasIndices flags, or null if invalid. */
33
+ /* c8 ignore start - the runner's own patterns always compile; the catch guards malformed custom fileType patterns */
34
+ function compilePattern(pattern) {
35
+ try {
36
+ return new RegExp(pattern, "gd");
37
+ }
38
+ catch {
39
+ return null;
40
+ }
41
+ }
42
+ /* c8 ignore stop */
43
+ /** Offset spans of `ignoreStart`…`ignoreEnd` regions, to skip statements in. */
44
+ function ignoreRanges(text, fileType) {
45
+ const starts = collectMatchOffsets(text, fileType.inlineStatements?.ignoreStart);
46
+ const ends = collectMatchOffsets(text, fileType.inlineStatements?.ignoreEnd);
47
+ const ranges = [];
48
+ for (const start of starts) {
49
+ // Pair each ignoreStart with the next ignoreEnd after it; if none, ignore to
50
+ // end of document.
51
+ const end = ends.find((e) => e >= start);
52
+ ranges.push({ start, end: end ?? text.length });
53
+ }
54
+ return ranges;
55
+ }
56
+ export function collectMatchOffsets(text, patterns) {
57
+ const offsets = [];
58
+ for (const pattern of patterns || []) {
59
+ const re = compilePattern(pattern);
60
+ /* c8 ignore next - compilePattern only returns null for an invalid custom pattern */
61
+ if (!re)
62
+ continue;
63
+ let m;
64
+ while ((m = re.exec(text))) {
65
+ offsets.push(m.index);
66
+ // A zero-width match doesn't advance lastIndex; nudge it so a degenerate
67
+ // (empty-matching) custom pattern can't spin forever and hang the server.
68
+ if (m[0].length === 0)
69
+ re.lastIndex++;
70
+ }
71
+ }
72
+ return offsets.sort((a, b) => a - b);
73
+ }
74
+ /** Extract statements of one kind (testStart / step) with payloads + spans. */
75
+ export function extractStatements(text, patterns, ignore) {
76
+ const out = [];
77
+ for (const pattern of patterns || []) {
78
+ const re = compilePattern(pattern);
79
+ /* c8 ignore next - compilePattern only returns null for an invalid custom pattern */
80
+ if (!re)
81
+ continue;
82
+ let m;
83
+ while ((m = re.exec(text))) {
84
+ // A zero-width match doesn't advance lastIndex; nudge it so a degenerate
85
+ // (empty-matching) custom pattern can't spin forever and hang the server.
86
+ if (m[0].length === 0)
87
+ re.lastIndex++;
88
+ if (ignore.some((r) => m.index >= r.start && m.index < r.end))
89
+ continue;
90
+ const group = m.indices?.[1];
91
+ const range = group
92
+ ? { start: group[0], end: group[1] }
93
+ : /* c8 ignore next - hasIndices is always present under the 'd' flag */
94
+ { start: m.index, end: m.index + m[0].length };
95
+ /* c8 ignore next - capture group 1 is always present in the statement patterns */
96
+ const raw = m[1] ?? "";
97
+ const payload = parseObject({ stringifiedObject: raw });
98
+ out.push({ payload, parsed: payload !== null && typeof payload === "object", range });
99
+ }
100
+ }
101
+ return out;
102
+ }
103
+ /** Drop the "must have steps or contexts" errors so an open statement (which
104
+ * legitimately carries neither — later statements supply the steps) isn't
105
+ * falsely flagged. Everything else in the open statement is still validated. */
106
+ function isStepsOrContextsRequirement(error) {
107
+ if (error.instancePath)
108
+ return false; // only the top-level requirement
109
+ if (error.keyword === "anyOf")
110
+ return true;
111
+ if (error.keyword === "required" &&
112
+ ["steps", "contexts"].includes(error.params?.missingProperty)) {
113
+ return true;
114
+ }
115
+ return false;
116
+ }
117
+ function toLspRange(doc, range) {
118
+ return { start: doc.positionAt(range.start), end: doc.positionAt(range.end) };
119
+ }
120
+ /** Validate a `step` fragment and produce its diagnostics. */
121
+ function diagnoseStep(doc, stmt) {
122
+ if (!stmt.parsed)
123
+ return [];
124
+ const payload = stmt.payload;
125
+ const range = toLspRange(doc, stmt.range);
126
+ const isActionKeyed = "action" in payload;
127
+ const result = validate({
128
+ schemaKey: "step_v3",
129
+ object: payload,
130
+ addDefaults: false,
131
+ structuredErrors: true,
132
+ });
133
+ if (result.valid) {
134
+ // A valid v2 (action-keyed) step: deprecation warning, mirroring specs.
135
+ if (isActionKeyed)
136
+ return [warn(range, V2_DEPRECATION_MESSAGE, "legacy-v2-step")];
137
+ return [];
138
+ }
139
+ if (isActionKeyed) {
140
+ return [error(range, ACTION_KEYED_MESSAGE, "action-keyed-step")];
141
+ }
142
+ // A single invalid step matches no `anyOf` branch, so AJV reports a failure
143
+ // for EVERY action — dozens of "must have required property …". Collapse that
144
+ // wall: if the author clearly intended one action (a top-level key that is a
145
+ // known action), show only that action's own value errors; otherwise a single
146
+ // "not a recognized step" message.
147
+ const registry = getRegistry();
148
+ const actionKey = Object.keys(payload).find((k) => registry.byKey.has(k));
149
+ if (!actionKey) {
150
+ return [
151
+ error(range, 'Not a recognized Doc Detective step (expected `{"<action>": …}`).'),
152
+ ];
153
+ }
154
+ const prefix = pointerFromPath([actionKey]);
155
+ /* c8 ignore next - errorObjects is always set here (structuredErrors: true) */
156
+ const relevant = (result.errorObjects || []).filter((e) => (e.instancePath || "").startsWith(prefix));
157
+ // One concise diagnostic per step — the action's value can fail several
158
+ // internal branches (e.g. goTo accepts a URL string OR an object), and
159
+ // surfacing all of them is noise. Show the first, most specific message.
160
+ if (relevant.length === 0) {
161
+ return [error(range, `Invalid "${actionKey}" step.`)];
162
+ }
163
+ return [error(range, `${actionKey}: ${schemaMessage(relevant[0])}`)];
164
+ }
165
+ /** Validate a `test` open fragment (relaxed: steps/contexts not required). */
166
+ function diagnoseTestOpen(doc, stmt) {
167
+ if (!stmt.parsed)
168
+ return [];
169
+ const result = validate({
170
+ schemaKey: "test_v3",
171
+ object: stmt.payload,
172
+ addDefaults: false,
173
+ structuredErrors: true,
174
+ });
175
+ if (result.valid)
176
+ return [];
177
+ const range = toLspRange(doc, stmt.range);
178
+ /* c8 ignore next - errorObjects is always set here (structuredErrors: true) */
179
+ return (result.errorObjects || [])
180
+ .filter((e) => !isStepsOrContextsRequirement(e))
181
+ .map((e) => error(range, schemaMessage(e)));
182
+ }
183
+ function error(range, message, code) {
184
+ return { severity: DiagnosticSeverity.Error, range, message, source: DIAGNOSTIC_SOURCE, code };
185
+ }
186
+ function warn(range, message, code) {
187
+ return { severity: DiagnosticSeverity.Warning, range, message, source: DIAGNOSTIC_SOURCE, code };
188
+ }
189
+ /**
190
+ * Compute diagnostics for inline Doc Detective test statements embedded in a
191
+ * markup document (markdown/asciidoc/html/dita, or a config fileType). Only the
192
+ * `test` open and `step` statement regions the runner recognizes get language
193
+ * features — the rest of the prose is left alone.
194
+ */
195
+ export function computeInlineDiagnostics(doc, fileType) {
196
+ const text = doc.getText();
197
+ const ignore = ignoreRanges(text, fileType);
198
+ const statements = fileType.inlineStatements || {};
199
+ const diagnostics = [];
200
+ for (const stmt of extractStatements(text, statements.testStart, ignore)) {
201
+ diagnostics.push(...diagnoseTestOpen(doc, stmt));
202
+ }
203
+ for (const stmt of extractStatements(text, statements.step, ignore)) {
204
+ diagnostics.push(...diagnoseStep(doc, stmt));
205
+ }
206
+ return diagnostics;
207
+ }
208
+ //# sourceMappingURL=inline.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inline.js","sourceRoot":"","sources":["../../src/lsp/inline.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,51 @@
1
+ import { Node, ParseError } from "jsonc-parser";
2
+ /** A character-offset span into the source text (end-exclusive). */
3
+ export interface OffsetRange {
4
+ start: number;
5
+ end: number;
6
+ }
7
+ /** Result of parsing: the CST root (if any) plus lenient syntax errors. */
8
+ export interface JsonParse {
9
+ root: Node | undefined;
10
+ errors: ParseError[];
11
+ }
12
+ /**
13
+ * Parse JSON(-with-comments) into a position-preserving CST. jsonc-parser is
14
+ * tolerant of the half-typed, comma-trailing states an editor streams, and
15
+ * collects syntax errors rather than throwing.
16
+ */
17
+ export declare function parseJsonTree(text: string): JsonParse;
18
+ /**
19
+ * Turn an AJV `instancePath` (`/tests/0/steps/1/goTo`) into path segments,
20
+ * decoding the JSON-Pointer escapes (`~1`→`/`, `~0`→`~`) and numeric indices.
21
+ */
22
+ export declare function instancePathToSegments(instancePath: string): Array<string | number>;
23
+ /**
24
+ * Resolve the source span for an AJV `instancePath`. When the exact node is
25
+ * absent (e.g. a `required` error names an object whose child doesn't exist),
26
+ * walks up to the nearest present ancestor so the diagnostic still anchors
27
+ * somewhere sensible instead of vanishing. Returns `null` only when even the
28
+ * root can't be located (unparseable input).
29
+ */
30
+ export declare function rangeForInstancePath(root: Node, instancePath: string): OffsetRange | null;
31
+ /** A step whose author used the `action`-as-value antipattern. */
32
+ export interface ActionKeyedStep {
33
+ /** Span of the offending `"action"` key, for the squiggle. */
34
+ keyRange: OffsetRange;
35
+ /** JSON-Pointer to the step object, used to suppress its `anyOf` noise. */
36
+ pointer: string;
37
+ }
38
+ /**
39
+ * Build a JSON-Pointer from path segments, escaping `~`→`~0` and `/`→`~1` per
40
+ * RFC 6901. Shared by the JSON and YAML action-keyed detectors.
41
+ */
42
+ export declare function pointerFromPath(segments: Array<string | number>): string;
43
+ /**
44
+ * Find every step written as an object carrying an `action` property inside a
45
+ * `steps` array — the classic Doc Detective mistake (action name as a *value*
46
+ * under `action`, instead of the compact action-as-key form). Returns the
47
+ * `"action"` key span (to squiggle) and the step's JSON-Pointer (to suppress
48
+ * the otherwise-overwhelming `anyOf` schema failures for that same step).
49
+ */
50
+ export declare function findActionKeyedSteps(root: Node): ActionKeyedStep[];
51
+ //# sourceMappingURL=positions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"positions.d.ts","sourceRoot":"","sources":["../../../src/lsp/json/positions.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,IAAI,EACJ,UAAU,EACX,MAAM,cAAc,CAAC;AAEtB,oEAAoE;AACpE,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;CACb;AAED,2EAA2E;AAC3E,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,IAAI,GAAG,SAAS,CAAC;IACvB,MAAM,EAAE,UAAU,EAAE,CAAC;CACtB;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAOrD;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,YAAY,EAAE,MAAM,GAAG,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,CASnF;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,IAAI,EACV,YAAY,EAAE,MAAM,GACnB,WAAW,GAAG,IAAI,CAWpB;AAED,kEAAkE;AAClE,MAAM,WAAW,eAAe;IAC9B,8DAA8D;IAC9D,QAAQ,EAAE,WAAW,CAAC;IACtB,2EAA2E;IAC3E,OAAO,EAAE,MAAM,CAAC;CACjB;AASD;;;GAGG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,GAAG,MAAM,CASxE;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,IAAI,GAAG,eAAe,EAAE,CA2BlE"}
@@ -0,0 +1,101 @@
1
+ import { parseTree, findNodeAtLocation, getNodePath, } from "jsonc-parser";
2
+ /**
3
+ * Parse JSON(-with-comments) into a position-preserving CST. jsonc-parser is
4
+ * tolerant of the half-typed, comma-trailing states an editor streams, and
5
+ * collects syntax errors rather than throwing.
6
+ */
7
+ export function parseJsonTree(text) {
8
+ const errors = [];
9
+ const root = parseTree(text, errors, {
10
+ allowTrailingComma: true,
11
+ disallowComments: false,
12
+ });
13
+ return { root, errors };
14
+ }
15
+ /**
16
+ * Turn an AJV `instancePath` (`/tests/0/steps/1/goTo`) into path segments,
17
+ * decoding the JSON-Pointer escapes (`~1`→`/`, `~0`→`~`) and numeric indices.
18
+ */
19
+ export function instancePathToSegments(instancePath) {
20
+ if (!instancePath)
21
+ return [];
22
+ return instancePath
23
+ .split("/")
24
+ .slice(1)
25
+ .map((seg) => {
26
+ const unescaped = seg.replace(/~1/g, "/").replace(/~0/g, "~");
27
+ return /^\d+$/.test(unescaped) ? Number(unescaped) : unescaped;
28
+ });
29
+ }
30
+ /**
31
+ * Resolve the source span for an AJV `instancePath`. When the exact node is
32
+ * absent (e.g. a `required` error names an object whose child doesn't exist),
33
+ * walks up to the nearest present ancestor so the diagnostic still anchors
34
+ * somewhere sensible instead of vanishing. Returns `null` only when even the
35
+ * root can't be located (unparseable input).
36
+ */
37
+ export function rangeForInstancePath(root, instancePath) {
38
+ const segments = instancePathToSegments(instancePath);
39
+ for (let end = segments.length; end >= 0; end--) {
40
+ const node = end === 0 ? root : findNodeAtLocation(root, segments.slice(0, end));
41
+ if (node) {
42
+ return { start: node.offset, end: node.offset + node.length };
43
+ }
44
+ }
45
+ /* c8 ignore next 2 - root is always locatable when this is called with a real tree */
46
+ return null;
47
+ }
48
+ function visit(node, cb) {
49
+ cb(node);
50
+ if (node.children) {
51
+ for (const child of node.children)
52
+ visit(child, cb);
53
+ }
54
+ }
55
+ /**
56
+ * Build a JSON-Pointer from path segments, escaping `~`→`~0` and `/`→`~1` per
57
+ * RFC 6901. Shared by the JSON and YAML action-keyed detectors.
58
+ */
59
+ export function pointerFromPath(segments) {
60
+ /* c8 ignore next - defensive: callers pass a nested node's path, never the empty root path */
61
+ if (segments.length === 0)
62
+ return "";
63
+ return ("/" +
64
+ segments
65
+ .map((s) => String(s).replace(/~/g, "~0").replace(/\//g, "~1"))
66
+ .join("/"));
67
+ }
68
+ /**
69
+ * Find every step written as an object carrying an `action` property inside a
70
+ * `steps` array — the classic Doc Detective mistake (action name as a *value*
71
+ * under `action`, instead of the compact action-as-key form). Returns the
72
+ * `"action"` key span (to squiggle) and the step's JSON-Pointer (to suppress
73
+ * the otherwise-overwhelming `anyOf` schema failures for that same step).
74
+ */
75
+ export function findActionKeyedSteps(root) {
76
+ const found = [];
77
+ visit(root, (node) => {
78
+ if (node.type !== "property" ||
79
+ !node.children ||
80
+ node.children[0]?.value !== "steps") {
81
+ return;
82
+ }
83
+ const arr = node.children[1];
84
+ if (arr?.type !== "array" || !arr.children)
85
+ return;
86
+ for (const el of arr.children) {
87
+ if (el.type !== "object" || !el.children)
88
+ continue;
89
+ const actionProp = el.children.find((p) => p.type === "property" && p.children?.[0]?.value === "action");
90
+ if (actionProp && actionProp.children) {
91
+ const keyNode = actionProp.children[0];
92
+ found.push({
93
+ keyRange: { start: keyNode.offset, end: keyNode.offset + keyNode.length },
94
+ pointer: pointerFromPath(getNodePath(el)),
95
+ });
96
+ }
97
+ }
98
+ });
99
+ return found;
100
+ }
101
+ //# sourceMappingURL=positions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"positions.js","sourceRoot":"","sources":["../../../src/lsp/json/positions.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Shared diagnostic strings and the AJV-error→message formatter. Kept in its own
3
+ * module so both the spec pipeline (diagnostics.ts) and the inline pipeline
4
+ * (inline.ts) can use them without a circular import.
5
+ */
6
+ /** Diagnostic `source` label shown in the editor gutter/problems panel. */
7
+ export declare const DIAGNOSTIC_SOURCE = "doc-detective";
8
+ /**
9
+ * The flagship message: the single most common Doc Detective authoring mistake
10
+ * gets one clear diagnostic instead of the wall of `anyOf` failures the raw
11
+ * schema produces. Mirrors the plugin's write-blocking hook. Fires only on an
12
+ * INVALID document/step — a valid legacy v2 form gets the softer deprecation
13
+ * warning instead.
14
+ */
15
+ export declare const ACTION_KEYED_MESSAGE: string;
16
+ /**
17
+ * The version-mixing nudge: a document/step that is *valid* but uses the legacy
18
+ * v2 `action`-keyed form gets a non-blocking warning steering it to compact v3.
19
+ */
20
+ export declare const V2_DEPRECATION_MESSAGE = "Legacy v2 step form. Prefer the compact v3 form \u2014 the action name is the key, e.g. `{\"goTo\": \u2026}`.";
21
+ /** Format a single AJV error into a concise human message. */
22
+ export declare function schemaMessage(error: {
23
+ message?: string;
24
+ keyword?: string;
25
+ params?: Record<string, any>;
26
+ }): string;
27
+ //# sourceMappingURL=messages.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../../src/lsp/messages.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,2EAA2E;AAC3E,eAAO,MAAM,iBAAiB,kBAAkB,CAAC;AAEjD;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB,QAEQ,CAAC;AAE1C;;;GAGG;AACH,eAAO,MAAM,sBAAsB,kHACkE,CAAC;AAEtG,8DAA8D;AAC9D,wBAAgB,aAAa,CAAC,KAAK,EAAE;IACnC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAC9B,GAAG,MAAM,CAST"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Shared diagnostic strings and the AJV-error→message formatter. Kept in its own
3
+ * module so both the spec pipeline (diagnostics.ts) and the inline pipeline
4
+ * (inline.ts) can use them without a circular import.
5
+ */
6
+ /** Diagnostic `source` label shown in the editor gutter/problems panel. */
7
+ export const DIAGNOSTIC_SOURCE = "doc-detective";
8
+ /**
9
+ * The flagship message: the single most common Doc Detective authoring mistake
10
+ * gets one clear diagnostic instead of the wall of `anyOf` failures the raw
11
+ * schema produces. Mirrors the plugin's write-blocking hook. Fires only on an
12
+ * INVALID document/step — a valid legacy v2 form gets the softer deprecation
13
+ * warning instead.
14
+ */
15
+ export const ACTION_KEYED_MESSAGE = 'The action name is the key: write `{"goTo": …}`, not an object with an "action" property. ' +
16
+ 'Each step is `{"<action>": <value>}`.';
17
+ /**
18
+ * The version-mixing nudge: a document/step that is *valid* but uses the legacy
19
+ * v2 `action`-keyed form gets a non-blocking warning steering it to compact v3.
20
+ */
21
+ export const V2_DEPRECATION_MESSAGE = 'Legacy v2 step form. Prefer the compact v3 form — the action name is the key, e.g. `{"goTo": …}`.';
22
+ /** Format a single AJV error into a concise human message. */
23
+ export function schemaMessage(error) {
24
+ const base = error.message || "does not match the schema";
25
+ const params = error.params || {};
26
+ if (error.keyword === "additionalProperties" && params.additionalProperty) {
27
+ return `${base}: "${params.additionalProperty}"`;
28
+ }
29
+ // AJV's `required` message already names the missing property, so `base`
30
+ // needs no augmentation — it falls through to the return below.
31
+ return base;
32
+ }
33
+ //# sourceMappingURL=messages.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"messages.js","sourceRoot":"","sources":["../../src/lsp/messages.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,2EAA2E;AAC3E,MAAM,CAAC,MAAM,iBAAiB,GAAG,eAAe,CAAC;AAEjD;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAC/B,4FAA4F;IAC5F,uCAAuC,CAAC;AAE1C;;;GAGG;AACH,MAAM,CAAC,MAAM,sBAAsB,GACjC,mGAAmG,CAAC;AAEtG,8DAA8D;AAC9D,MAAM,UAAU,aAAa,CAAC,KAI7B;IACC,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,IAAI,2BAA2B,CAAC;IAC1D,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,IAAI,EAAE,CAAC;IAClC,IAAI,KAAK,CAAC,OAAO,KAAK,sBAAsB,IAAI,MAAM,CAAC,kBAAkB,EAAE,CAAC;QAC1E,OAAO,GAAG,IAAI,MAAM,MAAM,CAAC,kBAAkB,GAAG,CAAC;IACnD,CAAC;IACD,yEAAyE;IACzE,gEAAgE;IAChE,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -0,0 +1,27 @@
1
+ import { OffsetRange, ActionKeyedStep } from "./json/positions.js";
2
+ /** A syntax error reduced to an offset span + message, format-agnostic. */
3
+ export interface SyntaxErrorSpan {
4
+ range: OffsetRange;
5
+ message: string;
6
+ }
7
+ /**
8
+ * A format-agnostic view of a parsed spec/config buffer. JSON and YAML each
9
+ * provide one; the diagnostics (and, later, inline) pipeline works against this
10
+ * interface so the schema/action logic is written once.
11
+ */
12
+ export interface SpecModel {
13
+ /** The plain JS value (undefined for empty/unparseable buffers). */
14
+ value: any;
15
+ /** Syntax-error spans + messages (empty when the buffer parses cleanly). */
16
+ syntaxErrors: SyntaxErrorSpan[];
17
+ /** Source span for an AJV instancePath, or null if unlocatable. */
18
+ rangeForPath(instancePath: string): OffsetRange | null;
19
+ /** Steps written in the legacy `action`-keyed form. */
20
+ actionKeyedSteps(): ActionKeyedStep[];
21
+ }
22
+ /**
23
+ * Build the right model for a buffer by extension, or null for an unsupported
24
+ * one. Callers gate on the classifier separately (spec vs config).
25
+ */
26
+ export declare function buildModel(uri: string, text: string): SpecModel | null;
27
+ //# sourceMappingURL=model.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../../src/lsp/model.ts"],"names":[],"mappings":"AAEA,OAAO,EAIL,WAAW,EACX,eAAe,EAChB,MAAM,qBAAqB,CAAC;AAQ7B,2EAA2E;AAC3E,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,WAAW,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;GAIG;AACH,MAAM,WAAW,SAAS;IACxB,oEAAoE;IACpE,KAAK,EAAE,GAAG,CAAC;IACX,4EAA4E;IAC5E,YAAY,EAAE,eAAe,EAAE,CAAC;IAChC,mEAAmE;IACnE,YAAY,CAAC,YAAY,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI,CAAC;IACvD,uDAAuD;IACvD,gBAAgB,IAAI,eAAe,EAAE,CAAC;CACvC;AAqCD;;;GAGG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAItE"}
@@ -0,0 +1,49 @@
1
+ import { getNodeValue, printParseErrorCode } from "jsonc-parser";
2
+ import { isJsonUri, isYamlUri } from "./gate.js";
3
+ import { parseJsonTree, rangeForInstancePath, findActionKeyedSteps, } from "./json/positions.js";
4
+ import { parseYamlTree, yamlSyntaxErrors, rangeForInstancePathYaml, findActionKeyedStepsYaml, } from "./yaml/positions.js";
5
+ function buildJsonModel(text) {
6
+ const { root, errors } = parseJsonTree(text);
7
+ return {
8
+ value: root ? getNodeValue(root) : undefined,
9
+ syntaxErrors: errors.map((e) => ({
10
+ range: { start: e.offset, end: e.offset + e.length },
11
+ message: `JSON syntax: ${printParseErrorCode(e.error)}`,
12
+ })),
13
+ rangeForPath: (path) => (root ? rangeForInstancePath(root, path) : null),
14
+ actionKeyedSteps: () => (root ? findActionKeyedSteps(root) : []),
15
+ };
16
+ }
17
+ function buildYamlModel(text) {
18
+ const { doc, value, valueError } = parseYamlTree(text);
19
+ const syntaxErrors = yamlSyntaxErrors(doc).map((e) => ({
20
+ range: e.range,
21
+ message: `YAML syntax: ${e.message}`,
22
+ }));
23
+ // A `toJS()` failure (e.g. an alias bomb) has no single node to blame; anchor
24
+ // it at the document start so the author still sees the problem.
25
+ if (valueError) {
26
+ syntaxErrors.push({
27
+ range: { start: 0, end: Math.min(text.length, 1) },
28
+ message: `YAML error: ${valueError}`,
29
+ });
30
+ }
31
+ return {
32
+ value,
33
+ syntaxErrors,
34
+ rangeForPath: (path) => rangeForInstancePathYaml(doc, path),
35
+ actionKeyedSteps: () => findActionKeyedStepsYaml(doc),
36
+ };
37
+ }
38
+ /**
39
+ * Build the right model for a buffer by extension, or null for an unsupported
40
+ * one. Callers gate on the classifier separately (spec vs config).
41
+ */
42
+ export function buildModel(uri, text) {
43
+ if (isJsonUri(uri))
44
+ return buildJsonModel(text);
45
+ if (isYamlUri(uri))
46
+ return buildYamlModel(text);
47
+ return null;
48
+ }
49
+ //# sourceMappingURL=model.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model.js","sourceRoot":"","sources":["../../src/lsp/model.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACjE,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACjD,OAAO,EACL,aAAa,EACb,oBAAoB,EACpB,oBAAoB,GAGrB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,aAAa,EACb,gBAAgB,EAChB,wBAAwB,EACxB,wBAAwB,GACzB,MAAM,qBAAqB,CAAC;AAwB7B,SAAS,cAAc,CAAC,IAAY;IAClC,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;IAC7C,OAAO;QACL,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS;QAC5C,YAAY,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YAC/B,KAAK,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,MAAM,EAAE;YACpD,OAAO,EAAE,gBAAgB,mBAAmB,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE;SACxD,CAAC,CAAC;QACH,YAAY,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,oBAAoB,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QACxE,gBAAgB,EAAE,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,oBAAoB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;KACjE,CAAC;AACJ,CAAC;AAED,SAAS,cAAc,CAAC,IAAY;IAClC,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,UAAU,EAAE,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;IACvD,MAAM,YAAY,GAAsB,gBAAgB,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACxE,KAAK,EAAE,CAAC,CAAC,KAAK;QACd,OAAO,EAAE,gBAAgB,CAAC,CAAC,OAAO,EAAE;KACrC,CAAC,CAAC,CAAC;IACJ,8EAA8E;IAC9E,iEAAiE;IACjE,IAAI,UAAU,EAAE,CAAC;QACf,YAAY,CAAC,IAAI,CAAC;YAChB,KAAK,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE;YAClD,OAAO,EAAE,eAAe,UAAU,EAAE;SACrC,CAAC,CAAC;IACL,CAAC;IACD,OAAO;QACL,KAAK;QACL,YAAY;QACZ,YAAY,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,wBAAwB,CAAC,GAAG,EAAE,IAAI,CAAC;QAC3D,gBAAgB,EAAE,GAAG,EAAE,CAAC,wBAAwB,CAAC,GAAG,CAAC;KACtD,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,UAAU,CAAC,GAAW,EAAE,IAAY;IAClD,IAAI,SAAS,CAAC,GAAG,CAAC;QAAE,OAAO,cAAc,CAAC,IAAI,CAAC,CAAC;IAChD,IAAI,SAAS,CAAC,GAAG,CAAC;QAAE,OAAO,cAAc,CAAC,IAAI,CAAC,CAAC;IAChD,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -0,0 +1,61 @@
1
+ /** The kind of scalar an action's compact form accepts, if any. */
2
+ export type PrimitiveKind = "string" | "number" | "boolean" | null;
3
+ /**
4
+ * A field inside an action's object form — used for field-name completion and
5
+ * (Phase 3) enum-value completion.
6
+ */
7
+ export interface ActionField {
8
+ name: string;
9
+ description?: string;
10
+ /**
11
+ * The scalar kind this field accepts, or null for object/array fields. Drives
12
+ * whether a completion snippet quotes the value placeholder.
13
+ */
14
+ primitiveKind: PrimitiveKind;
15
+ /** Enumerated values, when the field's schema (or a branch) pins them. */
16
+ enumValues?: Array<string | number | boolean>;
17
+ }
18
+ /** Everything the language features need to know about one action. */
19
+ export interface ActionInfo {
20
+ /** The action key, which IS the step key (`goTo`, `find`, …). */
21
+ key: string;
22
+ title?: string;
23
+ description?: string;
24
+ /** True when the compact scalar form (e.g. `"goTo": "https://…"`) is valid. */
25
+ acceptsPrimitive: boolean;
26
+ /**
27
+ * The scalar kind the compact form accepts (`"goTo"` → string, `"wait"` →
28
+ * number, `"stopRecord"` → boolean), or null for object-only actions. Drives
29
+ * whether a completion snippet quotes the placeholder.
30
+ */
31
+ primitiveKind: PrimitiveKind;
32
+ /** Fields available inside the object form. */
33
+ fields: ActionField[];
34
+ }
35
+ export interface Registry {
36
+ actions: ActionInfo[];
37
+ byKey: Map<string, ActionInfo>;
38
+ }
39
+ /** Collect the candidate sub-schemas of a schema: itself plus anyOf/oneOf/allOf. */
40
+ export declare function branchesOf(schema: any): any[];
41
+ /** Dig for a human description across a schema and its immediate branches. */
42
+ export declare function findDescription(schema: any): string | undefined;
43
+ /**
44
+ * The scalar kind a schema (or a branch) accepts in its compact form, or null.
45
+ * The first primitive type encountered across branches wins.
46
+ */
47
+ export declare function primitiveKindOf(schema: any): PrimitiveKind;
48
+ /** Does the schema (or a branch) accept a primitive scalar value? */
49
+ export declare function acceptsPrimitive(schema: any): boolean;
50
+ /** Merge the `properties` maps found across a schema's object branches. */
51
+ export declare function collectFields(schema: any): ActionField[];
52
+ /** Pull an enum list from a schema or its branches, if any. */
53
+ export declare function extractEnum(schema: any): Array<string | number | boolean> | undefined;
54
+ /**
55
+ * Build the action registry from the live `step_v3` schema. Derived at runtime
56
+ * (not a build step) so a new action added to the schemas automatically appears
57
+ * in completion/hover — the anti-drift test pins that guarantee.
58
+ */
59
+ export declare function buildRegistry(step?: any): Registry;
60
+ export declare function getRegistry(): Registry;
61
+ //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/lsp/registry.ts"],"names":[],"mappings":"AAEA,mEAAmE;AACnE,MAAM,MAAM,aAAa,GAAG,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,IAAI,CAAC;AAEnE;;;GAGG;AACH,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,aAAa,EAAE,aAAa,CAAC;IAC7B,0EAA0E;IAC1E,UAAU,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,CAAC;CAC/C;AAED,sEAAsE;AACtE,MAAM,WAAW,UAAU;IACzB,iEAAiE;IACjE,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,+EAA+E;IAC/E,gBAAgB,EAAE,OAAO,CAAC;IAC1B;;;;OAIG;IACH,aAAa,EAAE,aAAa,CAAC;IAC7B,+CAA+C;IAC/C,MAAM,EAAE,WAAW,EAAE,CAAC;CACvB;AAED,MAAM,WAAW,QAAQ;IACvB,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;CAChC;AAED,oFAAoF;AACpF,wBAAgB,UAAU,CAAC,MAAM,EAAE,GAAG,GAAG,GAAG,EAAE,CAO7C;AAED,8EAA8E;AAC9E,wBAAgB,eAAe,CAAC,MAAM,EAAE,GAAG,GAAG,MAAM,GAAG,SAAS,CAO/D;AAUD;;;GAGG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,GAAG,GAAG,aAAa,CAU1D;AAED,qEAAqE;AACrE,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,GAAG,GAAG,OAAO,CAErD;AAED,2EAA2E;AAC3E,wBAAgB,aAAa,CAAC,MAAM,EAAE,GAAG,GAAG,WAAW,EAAE,CAgBxD;AAED,+DAA+D;AAC/D,wBAAgB,WAAW,CAAC,MAAM,EAAE,GAAG,GAAG,KAAK,CAAC,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,GAAG,SAAS,CAKrF;AAgBD;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,IAAI,GAAE,GAAiC,GAAG,QAAQ,CAoB/E;AAID,wBAAgB,WAAW,IAAI,QAAQ,CAGtC"}