@mrclrchtr/supi-insights 7.4.0 → 8.0.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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mrclrchtr/supi-core",
3
- "version": "7.4.0",
3
+ "version": "8.0.0",
4
4
  "description": "Shared settings, configuration, reporting, and session infrastructure",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -70,6 +70,116 @@ export interface SupiConfigOptions {
70
70
  homeDir?: string;
71
71
  }
72
72
 
73
+ /** Options for loading automatic code-intelligence exclusions. */
74
+ export interface AutomaticExclusionOptions extends SupiConfigOptions {
75
+ /** Whether the project config is trusted and can apply. Defaults to true. */
76
+ projectTrusted?: boolean;
77
+ }
78
+
79
+ /**
80
+ * Load the one configured exclusion list shared by automatic LSP work and
81
+ * broad AST searches.
82
+ *
83
+ * Project values replace global values. An explicit empty project list clears
84
+ * the global list. The old `lsp.exclude` key is rejected in every applicable
85
+ * scope so automatic work cannot start without its former protection.
86
+ */
87
+ export function loadAutomaticExclusionPatterns(
88
+ cwd: string,
89
+ options: AutomaticExclusionOptions = {},
90
+ ): readonly string[] {
91
+ const projectTrusted = options.projectTrusted !== false;
92
+ const globalCodeIntelligence = loadSupiConfigSectionForScope("code-intelligence", cwd, {
93
+ scope: "global",
94
+ homeDir: options.homeDir,
95
+ });
96
+ const projectCodeIntelligence = projectTrusted
97
+ ? loadSupiConfigSectionForScope("code-intelligence", cwd, { scope: "project" })
98
+ : null;
99
+ const globalLsp = loadSupiConfigSectionForScope("lsp", cwd, {
100
+ scope: "global",
101
+ homeDir: options.homeDir,
102
+ });
103
+ const projectLsp = projectTrusted
104
+ ? loadSupiConfigSectionForScope("lsp", cwd, { scope: "project" })
105
+ : null;
106
+
107
+ const legacyPath = findLegacyExclusionPath(cwd, options, globalLsp, projectLsp);
108
+ if (legacyPath) {
109
+ throw new Error(
110
+ `Unsupported ${legacyPath.scope} configuration at ${legacyPath.path}: "lsp.exclude" was removed. Move its value to "code-intelligence.exclude". Automatic LSP and broad AST work did not start; reload after migration.`,
111
+ );
112
+ }
113
+
114
+ const source = findExclusionSource(cwd, options, {
115
+ projectTrusted,
116
+ globalCodeIntelligence,
117
+ projectCodeIntelligence,
118
+ });
119
+ return validateExclusionSource(source);
120
+ }
121
+
122
+ interface ExclusionSource {
123
+ value: unknown;
124
+ path: string;
125
+ }
126
+
127
+ interface LegacyExclusionPath {
128
+ scope: "global" | "project";
129
+ path: string;
130
+ }
131
+
132
+ function findLegacyExclusionPath(
133
+ cwd: string,
134
+ options: AutomaticExclusionOptions,
135
+ globalLsp: Record<string, unknown> | null,
136
+ projectLsp: Record<string, unknown> | null,
137
+ ): LegacyExclusionPath | null {
138
+ if (globalLsp && Object.hasOwn(globalLsp, "exclude")) {
139
+ return { scope: "global", path: getSupiConfigPath("global", cwd, options) };
140
+ }
141
+ if (projectLsp && Object.hasOwn(projectLsp, "exclude")) {
142
+ return { scope: "project", path: getSupiConfigPath("project", cwd) };
143
+ }
144
+ return null;
145
+ }
146
+
147
+ function findExclusionSource(
148
+ cwd: string,
149
+ options: AutomaticExclusionOptions,
150
+ sections: {
151
+ projectTrusted: boolean;
152
+ globalCodeIntelligence: Record<string, unknown> | null;
153
+ projectCodeIntelligence: Record<string, unknown> | null;
154
+ },
155
+ ): ExclusionSource | null {
156
+ const { projectTrusted, globalCodeIntelligence, projectCodeIntelligence } = sections;
157
+ if (
158
+ projectTrusted &&
159
+ projectCodeIntelligence &&
160
+ Object.hasOwn(projectCodeIntelligence, "exclude")
161
+ ) {
162
+ return { value: projectCodeIntelligence.exclude, path: getSupiConfigPath("project", cwd) };
163
+ }
164
+ if (globalCodeIntelligence && Object.hasOwn(globalCodeIntelligence, "exclude")) {
165
+ return {
166
+ value: globalCodeIntelligence.exclude,
167
+ path: getSupiConfigPath("global", cwd, options),
168
+ };
169
+ }
170
+ return null;
171
+ }
172
+
173
+ function validateExclusionSource(source: ExclusionSource | null): readonly string[] {
174
+ if (!source) return Object.freeze([]);
175
+ if (!Array.isArray(source.value) || !source.value.every((entry) => typeof entry === "string")) {
176
+ throw new Error(
177
+ `Invalid "code-intelligence.exclude" in ${source.path}: expected an array of gitignore-style strings. Automatic LSP and broad AST work did not start.`,
178
+ );
179
+ }
180
+ return Object.freeze([...source.value]);
181
+ }
182
+
73
183
  /**
74
184
  * Load and merge config for a given extension section.
75
185
  *
@@ -1,7 +1,12 @@
1
1
  // supi-core config domain — config loading.
2
- export type { SupiConfigLocation, SupiConfigOptions } from "./config/config.ts";
2
+ export type {
3
+ AutomaticExclusionOptions,
4
+ SupiConfigLocation,
5
+ SupiConfigOptions,
6
+ } from "./config/config.ts";
3
7
  export {
4
8
  getSupiConfigPath,
9
+ loadAutomaticExclusionPatterns,
5
10
  loadSupiConfig,
6
11
  loadSupiConfigForScope,
7
12
  loadSupiConfigSectionForScope,
@@ -151,6 +151,7 @@ export interface CustomField extends BaseField {
151
151
  cwd: string,
152
152
  action: SettingsAction,
153
153
  helpers: ConfigHelpers,
154
+ ctx?: ExtensionContext,
154
155
  ) => void | Promise<void>;
155
156
  }
156
157
 
@@ -404,7 +405,7 @@ async function applyConfigAction(
404
405
  const helpers = createConfigHelpers(options.section, scope, cwd, options.homeDir);
405
406
  let storedValue: unknown;
406
407
  if (field.kind === "custom") {
407
- await field.persist(scope, cwd, action, helpers);
408
+ await field.persist(scope, cwd, action, helpers, ctx);
408
409
  storedValue = action.kind === "set" ? action.value : undefined;
409
410
  } else if (action.kind === "set") {
410
411
  storedValue = parseTypedValue(action.value, field);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mrclrchtr/supi-insights",
3
- "version": "7.4.0",
3
+ "version": "8.0.0",
4
4
  "description": "Historical Pi-session reports and shareable HTML",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -34,7 +34,7 @@
34
34
  "README.md"
35
35
  ],
36
36
  "dependencies": {
37
- "@mrclrchtr/supi-core": "7.4.0"
37
+ "@mrclrchtr/supi-core": "8.0.0"
38
38
  },
39
39
  "bundledDependencies": [
40
40
  "@mrclrchtr/supi-core"