@telorun/ide-support 0.11.3 → 0.13.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.
@@ -0,0 +1,17 @@
1
+ /** Rendering a diagnostic's repair back into YAML source.
2
+ *
3
+ * A `fix.replacement` is a bare VALUE — a CEL expression, a kind name — while
4
+ * the span it replaces is the value node as written, which includes the
5
+ * scalar's quotes. (The YAML tag sits outside that span, so `!cel` survives a
6
+ * replacement without anything doing it on purpose.) Writing the bare value
7
+ * into a quoted span therefore strips the quotes, and a CEL expression is
8
+ * exactly the kind of text that stops being one scalar once unquoted.
9
+ *
10
+ * **The rule itself lives in `@telorun/analyzer`** (`yaml-source-edit.ts`),
11
+ * not here. It started here because both editors' quick fixes had to agree
12
+ * about how a value is written; `telo migrate` then became a third writer of
13
+ * the same files, and the analyzer is below all three. Re-exported rather than
14
+ * moved outright so a host keeps importing its repair rendering from the
15
+ * package that owns the rest of its diagnostic presentation. */
16
+ export { applyTextEdits, isPlainSafe, quoteStyleOf, renderFixReplacement, type QuoteStyle, type TextEdit, } from "@telorun/analyzer";
17
+ //# sourceMappingURL=fix-edit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fix-edit.d.ts","sourceRoot":"","sources":["../../src/diagnostics/fix-edit.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;iEAciE;AAEjE,OAAO,EACL,cAAc,EACd,WAAW,EACX,YAAY,EACZ,oBAAoB,EACpB,KAAK,UAAU,EACf,KAAK,QAAQ,GACd,MAAM,mBAAmB,CAAC"}
@@ -0,0 +1,16 @@
1
+ /** Rendering a diagnostic's repair back into YAML source.
2
+ *
3
+ * A `fix.replacement` is a bare VALUE — a CEL expression, a kind name — while
4
+ * the span it replaces is the value node as written, which includes the
5
+ * scalar's quotes. (The YAML tag sits outside that span, so `!cel` survives a
6
+ * replacement without anything doing it on purpose.) Writing the bare value
7
+ * into a quoted span therefore strips the quotes, and a CEL expression is
8
+ * exactly the kind of text that stops being one scalar once unquoted.
9
+ *
10
+ * **The rule itself lives in `@telorun/analyzer`** (`yaml-source-edit.ts`),
11
+ * not here. It started here because both editors' quick fixes had to agree
12
+ * about how a value is written; `telo migrate` then became a third writer of
13
+ * the same files, and the analyzer is below all three. Re-exported rather than
14
+ * moved outright so a host keeps importing its repair rendering from the
15
+ * package that owns the rest of its diagnostic presentation. */
16
+ export { applyTextEdits, isPlainSafe, quoteStyleOf, renderFixReplacement, } from "@telorun/analyzer";
@@ -21,9 +21,9 @@ export declare function compromisedFiles(graph: LoadedGraph): Set<string>;
21
21
  * (`suppressed`). The presentation policy lives here — not in the analyzer,
22
22
  * which only emits raw channels — so every host applies it identically.
23
23
  *
24
- * `diagnostics` folds parse, version-reconciliation, import-resolution, and the
25
- * *live* analysis diagnostics (those on non-compromised files) into one list,
26
- * in that order. `suppressed` carries the analysis cascade dropped from
24
+ * `diagnostics` folds parse, migration, version-reconciliation,
25
+ * import-resolution, and the *live* analysis diagnostics (those on
26
+ * non-compromised files) into one list, in that order. `suppressed` carries the analysis cascade dropped from
27
27
  * compromised files, still available to a host that wants to render it dimmed /
28
28
  * as related information rather than hide it.
29
29
  *
@@ -1 +1 @@
1
- {"version":3,"file":"graph-diagnostics.d.ts","sourceRoot":"","sources":["../../src/diagnostics/graph-diagnostics.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,kBAAkB,EACvB,KAAK,WAAW,EACjB,MAAM,mBAAmB,CAAC;AAG3B;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,WAAW,GAAG,GAAG,CAAC,MAAM,CAAC,CAShE;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,WAAW,EAClB,mBAAmB,EAAE,kBAAkB,EAAE,GACxC;IAAE,WAAW,EAAE,kBAAkB,EAAE,CAAC;IAAC,UAAU,EAAE,kBAAkB,EAAE,CAAA;CAAE,CAoBzE"}
1
+ {"version":3,"file":"graph-diagnostics.d.ts","sourceRoot":"","sources":["../../src/diagnostics/graph-diagnostics.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,kBAAkB,EACvB,KAAK,WAAW,EACjB,MAAM,mBAAmB,CAAC;AAG3B;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,WAAW,GAAG,GAAG,CAAC,MAAM,CAAC,CAShE;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,WAAW,EAClB,mBAAmB,EAAE,kBAAkB,EAAE,GACxC;IAAE,WAAW,EAAE,kBAAkB,EAAE,CAAC;IAAC,UAAU,EAAE,kBAAkB,EAAE,CAAA;CAAE,CA0BzE"}
@@ -1,4 +1,4 @@
1
- import { importResolutionDiagnostics, } from "@telorun/analyzer";
1
+ import { importResolutionDiagnostics, remapMigratedPaths, } from "@telorun/analyzer";
2
2
  import { findPositions } from "./find-positions.js";
3
3
  /**
4
4
  * Files whose static-analysis output is an unreliable cascade rather than a set
@@ -33,9 +33,9 @@ export function compromisedFiles(graph) {
33
33
  * (`suppressed`). The presentation policy lives here — not in the analyzer,
34
34
  * which only emits raw channels — so every host applies it identically.
35
35
  *
36
- * `diagnostics` folds parse, version-reconciliation, import-resolution, and the
37
- * *live* analysis diagnostics (those on non-compromised files) into one list,
38
- * in that order. `suppressed` carries the analysis cascade dropped from
36
+ * `diagnostics` folds parse, migration, version-reconciliation,
37
+ * import-resolution, and the *live* analysis diagnostics (those on
38
+ * non-compromised files) into one list, in that order. `suppressed` carries the analysis cascade dropped from
39
39
  * compromised files, still available to a host that wants to render it dimmed /
40
40
  * as related information rather than hide it.
41
41
  *
@@ -54,7 +54,12 @@ export function assembleGraphDiagnostics(graph, analysisDiagnostics) {
54
54
  const entrySource = graph.entry.owner.source;
55
55
  const live = [];
56
56
  const suppressed = [];
57
- for (const d of analysisDiagnostics) {
57
+ // Analysis ran over the MIGRATED tree, while positions come from the raw
58
+ // file. Remapping each `data.path` back through the driver's provenance
59
+ // record is what keeps a squiggle on the author's own line after a key
60
+ // rename — and what stops a fix among them writing across a parent's span.
61
+ // A no-op when nothing in the graph was migrated.
62
+ for (const d of remapMigratedPaths(graph, analysisDiagnostics)) {
58
63
  const rawFilePath = d.data?.filePath;
59
64
  const file = findPositions(graph, d.data)?.file ?? rawFilePath ?? entrySource;
60
65
  (compromised.has(file) ? suppressed : live).push(d);
@@ -62,6 +67,7 @@ export function assembleGraphDiagnostics(graph, analysisDiagnostics) {
62
67
  return {
63
68
  diagnostics: [
64
69
  ...graph.parseDiagnostics,
70
+ ...graph.migrationDiagnostics,
65
71
  ...graph.versionDiagnostics,
66
72
  ...importResolutionDiagnostics(graph),
67
73
  ...live,
@@ -1,4 +1,5 @@
1
1
  export { findPositions } from "./find-positions.js";
2
+ export { isPlainSafe, quoteStyleOf, renderFixReplacement, type QuoteStyle, } from "./fix-edit.js";
2
3
  export { assembleGraphDiagnostics, compromisedFiles } from "./graph-diagnostics.js";
3
4
  export { normalizeDiagnostic } from "./normalize.js";
4
5
  export { resolveRange } from "./range-resolver.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/diagnostics/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,wBAAwB,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AACpF,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/diagnostics/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EACL,WAAW,EACX,YAAY,EACZ,oBAAoB,EACpB,KAAK,UAAU,GAChB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,wBAAwB,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AACpF,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC"}
@@ -1,4 +1,5 @@
1
1
  export { findPositions } from "./find-positions.js";
2
+ export { isPlainSafe, quoteStyleOf, renderFixReplacement, } from "./fix-edit.js";
2
3
  export { assembleGraphDiagnostics, compromisedFiles } from "./graph-diagnostics.js";
3
4
  export { normalizeDiagnostic } from "./normalize.js";
4
5
  export { resolveRange } from "./range-resolver.js";
@@ -1,11 +1,15 @@
1
- import type { AnalysisDiagnostic } from "@telorun/analyzer";
1
+ import { type AnalysisDiagnostic } from "@telorun/analyzer";
2
2
  import type { DiagnosticContext, NormalizedDiagnostic } from "../types.js";
3
3
  /** Converts a raw analyzer diagnostic into a host-ready shape:
4
4
  * - Guarantees `range` and `severity`.
5
- * - Surfaces `data.suggestedKind` (stamped by the analyzer for UNDEFINED_KIND)
6
- * as a structured `{ kind: "replace-kind", replacement }` entry in
7
- * `suggestions`, which editor hosts can wire into CodeActions.
8
- * Does not rewrite the message the analyzer already formatted the human-readable
9
- * "Did you mean '…'?" hint, keeping CLI and IDE output in sync. */
5
+ * - Surfaces the analyzer's `fix` stamp as a structured `suggestions` entry
6
+ * hosts wire into a CodeAction.
7
+ * Does not rewrite the message the analyzer already formatted the
8
+ * human-readable hint, keeping CLI and IDE output in sync.
9
+ *
10
+ * One suggestion kind, not one per producer: an unknown kind name and a
11
+ * mis-called CEL function are the same gesture at the host (replace the value
12
+ * at this range), and a second kind would mean a second action path in every
13
+ * editor for no difference the user can see. */
10
14
  export declare function normalizeDiagnostic(d: AnalysisDiagnostic, ctx: DiagnosticContext): NormalizedDiagnostic;
11
15
  //# sourceMappingURL=normalize.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"normalize.d.ts","sourceRoot":"","sources":["../../src/diagnostics/normalize.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,KAAK,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAI3E;;;;;;oEAMoE;AACpE,wBAAgB,mBAAmB,CACjC,CAAC,EAAE,kBAAkB,EACrB,GAAG,EAAE,iBAAiB,GACrB,oBAAoB,CAetB"}
1
+ {"version":3,"file":"normalize.d.ts","sourceRoot":"","sources":["../../src/diagnostics/normalize.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,KAAK,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAC3E,OAAO,KAAK,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAI3E;;;;;;;;;;iDAUiD;AACjD,wBAAgB,mBAAmB,CACjC,CAAC,EAAE,kBAAkB,EACrB,GAAG,EAAE,iBAAiB,GACrB,oBAAoB,CAatB"}
@@ -1,17 +1,20 @@
1
+ import { diagnosticFix } from "@telorun/analyzer";
1
2
  import { resolveRange } from "./range-resolver.js";
2
3
  import { resolveSeverity } from "./severity.js";
3
4
  /** Converts a raw analyzer diagnostic into a host-ready shape:
4
5
  * - Guarantees `range` and `severity`.
5
- * - Surfaces `data.suggestedKind` (stamped by the analyzer for UNDEFINED_KIND)
6
- * as a structured `{ kind: "replace-kind", replacement }` entry in
7
- * `suggestions`, which editor hosts can wire into CodeActions.
8
- * Does not rewrite the message the analyzer already formatted the human-readable
9
- * "Did you mean '…'?" hint, keeping CLI and IDE output in sync. */
6
+ * - Surfaces the analyzer's `fix` stamp as a structured `suggestions` entry
7
+ * hosts wire into a CodeAction.
8
+ * Does not rewrite the message the analyzer already formatted the
9
+ * human-readable hint, keeping CLI and IDE output in sync.
10
+ *
11
+ * One suggestion kind, not one per producer: an unknown kind name and a
12
+ * mis-called CEL function are the same gesture at the host (replace the value
13
+ * at this range), and a second kind would mean a second action path in every
14
+ * editor for no difference the user can see. */
10
15
  export function normalizeDiagnostic(d, ctx) {
11
- const suggestedKind = d.data?.suggestedKind;
12
- const suggestions = suggestedKind
13
- ? [{ kind: "replace-kind", replacement: suggestedKind }]
14
- : undefined;
16
+ const fix = diagnosticFix(d);
17
+ const suggestions = fix ? [{ kind: "replace", replacement: fix.replacement }] : undefined;
15
18
  return {
16
19
  range: resolveRange(d, ctx),
17
20
  severity: resolveSeverity(d),
package/dist/types.d.ts CHANGED
@@ -97,8 +97,10 @@ export interface NormalizedDiagnostic {
97
97
  code: string;
98
98
  source: string;
99
99
  message: string;
100
+ /** Mechanically applicable repairs. `replacement` is the whole corrected
101
+ * value at the diagnostic's range — apply it by replacing that range. */
100
102
  suggestions?: Array<{
101
- kind: "replace-kind";
103
+ kind: "replace";
102
104
  replacement: string;
103
105
  }>;
104
106
  /** Preserved verbatim from the source `AnalysisDiagnostic`. Carries
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@telorun/ide-support",
3
- "version": "0.11.3",
3
+ "version": "0.13.0",
4
4
  "description": "Editor-host-agnostic IDE support (completions, diagnostic normalization) for Telo manifests.",
5
5
  "keywords": [
6
6
  "telo",
@@ -36,7 +36,7 @@
36
36
  "src/**"
37
37
  ],
38
38
  "dependencies": {
39
- "@telorun/analyzer": "0.56.1"
39
+ "@telorun/analyzer": "0.58.0"
40
40
  },
41
41
  "devDependencies": {
42
42
  "@types/node": "^20.0.0",
@@ -0,0 +1,24 @@
1
+ /** Rendering a diagnostic's repair back into YAML source.
2
+ *
3
+ * A `fix.replacement` is a bare VALUE — a CEL expression, a kind name — while
4
+ * the span it replaces is the value node as written, which includes the
5
+ * scalar's quotes. (The YAML tag sits outside that span, so `!cel` survives a
6
+ * replacement without anything doing it on purpose.) Writing the bare value
7
+ * into a quoted span therefore strips the quotes, and a CEL expression is
8
+ * exactly the kind of text that stops being one scalar once unquoted.
9
+ *
10
+ * **The rule itself lives in `@telorun/analyzer`** (`yaml-source-edit.ts`),
11
+ * not here. It started here because both editors' quick fixes had to agree
12
+ * about how a value is written; `telo migrate` then became a third writer of
13
+ * the same files, and the analyzer is below all three. Re-exported rather than
14
+ * moved outright so a host keeps importing its repair rendering from the
15
+ * package that owns the rest of its diagnostic presentation. */
16
+
17
+ export {
18
+ applyTextEdits,
19
+ isPlainSafe,
20
+ quoteStyleOf,
21
+ renderFixReplacement,
22
+ type QuoteStyle,
23
+ type TextEdit,
24
+ } from "@telorun/analyzer";
@@ -1,5 +1,6 @@
1
1
  import {
2
2
  importResolutionDiagnostics,
3
+ remapMigratedPaths,
3
4
  type AnalysisDiagnostic,
4
5
  type LoadedGraph,
5
6
  } from "@telorun/analyzer";
@@ -37,9 +38,9 @@ export function compromisedFiles(graph: LoadedGraph): Set<string> {
37
38
  * (`suppressed`). The presentation policy lives here — not in the analyzer,
38
39
  * which only emits raw channels — so every host applies it identically.
39
40
  *
40
- * `diagnostics` folds parse, version-reconciliation, import-resolution, and the
41
- * *live* analysis diagnostics (those on non-compromised files) into one list,
42
- * in that order. `suppressed` carries the analysis cascade dropped from
41
+ * `diagnostics` folds parse, migration, version-reconciliation,
42
+ * import-resolution, and the *live* analysis diagnostics (those on
43
+ * non-compromised files) into one list, in that order. `suppressed` carries the analysis cascade dropped from
43
44
  * compromised files, still available to a host that wants to render it dimmed /
44
45
  * as related information rather than hide it.
45
46
  *
@@ -61,7 +62,12 @@ export function assembleGraphDiagnostics(
61
62
  const entrySource = graph.entry.owner.source;
62
63
  const live: AnalysisDiagnostic[] = [];
63
64
  const suppressed: AnalysisDiagnostic[] = [];
64
- for (const d of analysisDiagnostics) {
65
+ // Analysis ran over the MIGRATED tree, while positions come from the raw
66
+ // file. Remapping each `data.path` back through the driver's provenance
67
+ // record is what keeps a squiggle on the author's own line after a key
68
+ // rename — and what stops a fix among them writing across a parent's span.
69
+ // A no-op when nothing in the graph was migrated.
70
+ for (const d of remapMigratedPaths(graph, analysisDiagnostics)) {
65
71
  const rawFilePath = (d.data as { filePath?: string } | undefined)?.filePath;
66
72
  const file = findPositions(graph, d.data)?.file ?? rawFilePath ?? entrySource;
67
73
  (compromised.has(file) ? suppressed : live).push(d);
@@ -70,6 +76,7 @@ export function assembleGraphDiagnostics(
70
76
  return {
71
77
  diagnostics: [
72
78
  ...graph.parseDiagnostics,
79
+ ...graph.migrationDiagnostics,
73
80
  ...graph.versionDiagnostics,
74
81
  ...importResolutionDiagnostics(graph),
75
82
  ...live,
@@ -1,4 +1,10 @@
1
1
  export { findPositions } from "./find-positions.js";
2
+ export {
3
+ isPlainSafe,
4
+ quoteStyleOf,
5
+ renderFixReplacement,
6
+ type QuoteStyle,
7
+ } from "./fix-edit.js";
2
8
  export { assembleGraphDiagnostics, compromisedFiles } from "./graph-diagnostics.js";
3
9
  export { normalizeDiagnostic } from "./normalize.js";
4
10
  export { resolveRange } from "./range-resolver.js";
@@ -1,23 +1,25 @@
1
- import type { AnalysisDiagnostic } from "@telorun/analyzer";
1
+ import { diagnosticFix, type AnalysisDiagnostic } from "@telorun/analyzer";
2
2
  import type { DiagnosticContext, NormalizedDiagnostic } from "../types.js";
3
3
  import { resolveRange } from "./range-resolver.js";
4
4
  import { resolveSeverity } from "./severity.js";
5
5
 
6
6
  /** Converts a raw analyzer diagnostic into a host-ready shape:
7
7
  * - Guarantees `range` and `severity`.
8
- * - Surfaces `data.suggestedKind` (stamped by the analyzer for UNDEFINED_KIND)
9
- * as a structured `{ kind: "replace-kind", replacement }` entry in
10
- * `suggestions`, which editor hosts can wire into CodeActions.
11
- * Does not rewrite the message the analyzer already formatted the human-readable
12
- * "Did you mean '…'?" hint, keeping CLI and IDE output in sync. */
8
+ * - Surfaces the analyzer's `fix` stamp as a structured `suggestions` entry
9
+ * hosts wire into a CodeAction.
10
+ * Does not rewrite the message the analyzer already formatted the
11
+ * human-readable hint, keeping CLI and IDE output in sync.
12
+ *
13
+ * One suggestion kind, not one per producer: an unknown kind name and a
14
+ * mis-called CEL function are the same gesture at the host (replace the value
15
+ * at this range), and a second kind would mean a second action path in every
16
+ * editor for no difference the user can see. */
13
17
  export function normalizeDiagnostic(
14
18
  d: AnalysisDiagnostic,
15
19
  ctx: DiagnosticContext,
16
20
  ): NormalizedDiagnostic {
17
- const suggestedKind = (d.data as { suggestedKind?: string } | undefined)?.suggestedKind;
18
- const suggestions = suggestedKind
19
- ? [{ kind: "replace-kind" as const, replacement: suggestedKind }]
20
- : undefined;
21
+ const fix = diagnosticFix(d);
22
+ const suggestions = fix ? [{ kind: "replace" as const, replacement: fix.replacement }] : undefined;
21
23
 
22
24
  return {
23
25
  range: resolveRange(d, ctx),
package/src/types.ts CHANGED
@@ -124,7 +124,9 @@ export interface NormalizedDiagnostic {
124
124
  code: string;
125
125
  source: string;
126
126
  message: string;
127
- suggestions?: Array<{ kind: "replace-kind"; replacement: string }>;
127
+ /** Mechanically applicable repairs. `replacement` is the whole corrected
128
+ * value at the diagnostic's range — apply it by replacing that range. */
129
+ suggestions?: Array<{ kind: "replace"; replacement: string }>;
128
130
  /** Preserved verbatim from the source `AnalysisDiagnostic`. Carries
129
131
  * resource/path stamps that downstream UIs (popovers, "at <path>" hints,
130
132
  * CodeAction wiring) read after normalization. Opaque on purpose so this