norn-cli 2.4.0 → 2.6.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 (96) hide show
  1. package/AGENTS.md +2 -2
  2. package/CHANGELOG.md +26 -1
  3. package/dist/cli.js +330 -85
  4. package/package.json +24 -5
  5. package/schemas/norn.config.schema.json +43 -1
  6. package/scripts/__pycache__/reddit_signal_miner.cpython-312.pyc +0 -0
  7. package/scripts/reddit_signal_miner.py +482 -0
  8. package/.claude/settings.local.json +0 -18
  9. package/.claude/skills/norn-social-campaign/SKILL.md +0 -70
  10. package/out/apiResponseIntellisenseCache.js +0 -394
  11. package/out/assertionRunner.js +0 -567
  12. package/out/cacheDir.js +0 -136
  13. package/out/chatParticipant.js +0 -763
  14. package/out/cli/colors.js +0 -127
  15. package/out/cli/formatters/assertion.js +0 -102
  16. package/out/cli/formatters/index.js +0 -23
  17. package/out/cli/formatters/response.js +0 -106
  18. package/out/cli/formatters/summary.js +0 -246
  19. package/out/cli/redaction.js +0 -237
  20. package/out/cli/reporters/html.js +0 -689
  21. package/out/cli/reporters/index.js +0 -22
  22. package/out/cli/reporters/junit.js +0 -226
  23. package/out/codeLensProvider.js +0 -351
  24. package/out/compareContentProvider.js +0 -85
  25. package/out/completionProvider.js +0 -3739
  26. package/out/contractAssertionSummary.js +0 -225
  27. package/out/contractDecorationProvider.js +0 -243
  28. package/out/coverageCalculator.js +0 -879
  29. package/out/coveragePanel.js +0 -597
  30. package/out/debug/breakpointResolver.js +0 -84
  31. package/out/debug/breakpoints.js +0 -52
  32. package/out/debug/nornDebugAdapter.js +0 -166
  33. package/out/debug/nornDebugSession.js +0 -613
  34. package/out/debug/sequenceLocationIndex.js +0 -77
  35. package/out/debug/types.js +0 -3
  36. package/out/deepClone.js +0 -21
  37. package/out/diagnosticProvider.js +0 -2554
  38. package/out/environmentParser.js +0 -736
  39. package/out/environmentProvider.js +0 -544
  40. package/out/environmentTemplates.js +0 -146
  41. package/out/errors/formatError.js +0 -113
  42. package/out/errors/nornError.js +0 -29
  43. package/out/formUrlEncoded.js +0 -89
  44. package/out/httpClient.js +0 -348
  45. package/out/httpRuntimeOptions.js +0 -16
  46. package/out/importErrors.js +0 -31
  47. package/out/inlayHintResolver.js +0 -70
  48. package/out/jsonFileReader.js +0 -323
  49. package/out/mcpClient.js +0 -193
  50. package/out/mcpConfig.js +0 -184
  51. package/out/mcpToolIntellisenseCache.js +0 -96
  52. package/out/mcpToolSchema.js +0 -50
  53. package/out/nornConfig.js +0 -132
  54. package/out/nornHoverProvider.js +0 -124
  55. package/out/nornInlayHintsProvider.js +0 -191
  56. package/out/nornPrompt.js +0 -755
  57. package/out/nornSqlParser.js +0 -286
  58. package/out/nornapiHoverProvider.js +0 -135
  59. package/out/nornapiInlayHintsProvider.js +0 -94
  60. package/out/nornapiParser.js +0 -324
  61. package/out/nornenvCodeActionProvider.js +0 -101
  62. package/out/nornenvDecorationProvider.js +0 -239
  63. package/out/nornenvFoldingProvider.js +0 -63
  64. package/out/nornenvHoverProvider.js +0 -114
  65. package/out/nornenvInlayHintsProvider.js +0 -99
  66. package/out/nornenvLanguageModel.js +0 -187
  67. package/out/nornenvRegionRefactor.js +0 -267
  68. package/out/nornsqlHoverProvider.js +0 -95
  69. package/out/nornsqlInlayHintsProvider.js +0 -114
  70. package/out/parser.js +0 -839
  71. package/out/pathAccess.js +0 -28
  72. package/out/postmanImportPanel.js +0 -732
  73. package/out/postmanImportPlanner.js +0 -1155
  74. package/out/postmanImportSidebarView.js +0 -532
  75. package/out/quotedString.js +0 -35
  76. package/out/requestPreparation.js +0 -179
  77. package/out/requestValidation.js +0 -146
  78. package/out/responsePanel.js +0 -7754
  79. package/out/schemaGenerator.js +0 -562
  80. package/out/scriptRunner.js +0 -419
  81. package/out/secrets/cliSecrets.js +0 -415
  82. package/out/secrets/crypto.js +0 -105
  83. package/out/secrets/envFileSecrets.js +0 -177
  84. package/out/secrets/keyStore.js +0 -259
  85. package/out/sequenceDeclaration.js +0 -15
  86. package/out/sequenceRunner.js +0 -3590
  87. package/out/sqlAdapterRunner.js +0 -122
  88. package/out/sqlBuiltInAdapters.js +0 -604
  89. package/out/sqlConfig.js +0 -184
  90. package/out/starterCatalog.js +0 -554
  91. package/out/stringUtils.js +0 -25
  92. package/out/swaggerBodyIntellisenseCache.js +0 -114
  93. package/out/swaggerParser.js +0 -464
  94. package/out/testProvider.js +0 -767
  95. package/out/theoryCaseLoader.js +0 -113
  96. package/out/validationCache.js +0 -211
@@ -1,70 +0,0 @@
1
- "use strict";
2
- /**
3
- * Shared resolver used by every Norn file type's inlay hint provider.
4
- *
5
- * The provider's job is to assemble the right scope (just env vars for .nornapi,
6
- * env + file-locals + sequence-locals for .norn, etc.) and hand the resulting
7
- * `variables` map to `resolveInlayValueLabel` for each `{{...}}` token it finds.
8
- *
9
- * Unresolvable references — response refs (`{{$1.body.id}}`), unknown names, cycles —
10
- * return `undefined`. The provider then renders nothing inline (no `(runtime)` label).
11
- */
12
- Object.defineProperty(exports, "__esModule", { value: true });
13
- exports.parseInlayReference = parseInlayReference;
14
- exports.resolveInlayValueLabel = resolveInlayValueLabel;
15
- const environmentTemplates_1 = require("./environmentTemplates");
16
- const ENV_TOKEN_REGEX = /^\$env\.([a-zA-Z_][a-zA-Z0-9_]*)$/;
17
- const PLAIN_TOKEN_REGEX = /^([a-zA-Z_][a-zA-Z0-9_]*)(?:\.[a-zA-Z_][a-zA-Z0-9_-]*|\[\d+\])*$/;
18
- const RESPONSE_TOKEN_REGEX = /^\$\d+/;
19
- /**
20
- * Parses a token like `name`, `$env.name`, `name.path.to.value`, or `$1.body.id`.
21
- * Returns the bare root variable name (the part we can look up at edit time)
22
- * or `undefined` for response refs / malformed tokens we can never resolve statically.
23
- */
24
- function parseInlayReference(rawReference) {
25
- const trimmed = rawReference.trim();
26
- if (RESPONSE_TOKEN_REGEX.test(trimmed)) {
27
- return undefined;
28
- }
29
- const envMatch = trimmed.match(ENV_TOKEN_REGEX);
30
- if (envMatch) {
31
- return { name: envMatch[1], envOnly: true };
32
- }
33
- const plainMatch = trimmed.match(PLAIN_TOKEN_REGEX);
34
- if (plainMatch) {
35
- return { name: plainMatch[1], envOnly: false };
36
- }
37
- return undefined;
38
- }
39
- const MAX_INLAY_LENGTH = 80;
40
- function truncateInlayValue(value) {
41
- return value.length > MAX_INLAY_LENGTH ? `${value.slice(0, MAX_INLAY_LENGTH - 3)}...` : value;
42
- }
43
- /**
44
- * Looks up a reference in `variables` and returns the label to render inline,
45
- * or `undefined` to skip (unknown name, response ref, cycle, etc).
46
- *
47
- * `variables` should already be the fully-merged scope the caller wants resolved
48
- * against — innermost wins. For example, in a `.norn` sequence the caller merges
49
- * `env + file-locals + sequence-locals` before calling this.
50
- */
51
- function resolveInlayValueLabel(rawReference, variables, secretNames) {
52
- const parsed = parseInlayReference(rawReference);
53
- if (!parsed) {
54
- return undefined;
55
- }
56
- if (!Object.prototype.hasOwnProperty.call(variables, parsed.name)) {
57
- return undefined;
58
- }
59
- const resolved = (0, environmentTemplates_1.resolveEnvironmentTemplateValue)(parsed.name, variables, secretNames);
60
- if (resolved.errors.length > 0) {
61
- return undefined;
62
- }
63
- const isSecret = resolved.secret || secretNames.has(parsed.name);
64
- return {
65
- label: isSecret ? '(secret)' : `"${truncateInlayValue(resolved.value)}"`,
66
- secret: isSecret,
67
- value: resolved.value
68
- };
69
- }
70
- //# sourceMappingURL=inlayHintResolver.js.map
@@ -1,323 +0,0 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
35
- Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.JsonVariableStore = void 0;
37
- exports.isJsonCommand = isJsonCommand;
38
- exports.parseJsonCommand = parseJsonCommand;
39
- exports.readJsonFile = readJsonFile;
40
- exports.getNestedValue = getNestedValue;
41
- exports.setNestedValue = setNestedValue;
42
- exports.isPropertyAssignment = isPropertyAssignment;
43
- exports.parsePropertyAssignment = parsePropertyAssignment;
44
- exports.valueToString = valueToString;
45
- exports.substituteVariablesWithJson = substituteVariablesWithJson;
46
- const fs = __importStar(require("fs"));
47
- const path = __importStar(require("path"));
48
- const pathAccess_1 = require("./pathAccess");
49
- /**
50
- * Checks if a line is a JSON file command.
51
- * Formats:
52
- * var name = run readJson ./path/to/file.json
53
- * var name = run readJson "/path with spaces/file.json"
54
- */
55
- function isJsonCommand(line) {
56
- const trimmed = line.trim();
57
- return /^var\s+[a-zA-Z_][a-zA-Z0-9_]*\s*=\s*run\s+readJson\s+/i.test(trimmed);
58
- }
59
- /**
60
- * Parses a JSON file command line.
61
- * Format: var <name> = run readJson <path>
62
- */
63
- function parseJsonCommand(line) {
64
- const trimmed = line.trim();
65
- // Match: var varName = run readJson path
66
- const match = trimmed.match(/^var\s+([a-zA-Z_][a-zA-Z0-9_]*)\s*=\s*run\s+readJson\s+(.+)$/i);
67
- if (!match) {
68
- return null;
69
- }
70
- let filePath = match[2].trim();
71
- // Remove quotes if present
72
- if ((filePath.startsWith('"') && filePath.endsWith('"')) ||
73
- (filePath.startsWith("'") && filePath.endsWith("'"))) {
74
- filePath = filePath.slice(1, -1);
75
- }
76
- return {
77
- varName: match[1],
78
- filePath
79
- };
80
- }
81
- /**
82
- * Reads and parses a JSON file.
83
- */
84
- function readJsonFile(filePath, workingDir) {
85
- // Resolve relative paths
86
- const resolvedPath = path.isAbsolute(filePath)
87
- ? filePath
88
- : path.resolve(workingDir || process.cwd(), filePath);
89
- try {
90
- if (!fs.existsSync(resolvedPath)) {
91
- return {
92
- success: false,
93
- error: `File not found: ${resolvedPath}`,
94
- filePath: resolvedPath
95
- };
96
- }
97
- const content = fs.readFileSync(resolvedPath, 'utf-8');
98
- const data = JSON.parse(content);
99
- return {
100
- success: true,
101
- data,
102
- filePath: resolvedPath
103
- };
104
- }
105
- catch (err) {
106
- const message = err instanceof Error ? err.message : String(err);
107
- return {
108
- success: false,
109
- error: `Failed to read/parse JSON file: ${message}`,
110
- filePath: resolvedPath
111
- };
112
- }
113
- }
114
- /**
115
- * Gets a value from an object using a dot-notation path.
116
- * Supports array indexing with brackets: obj.array[0].property
117
- *
118
- * @param obj The source object
119
- * @param path The dot-notation path (e.g., "user.addresses[0].city")
120
- * @returns The value at the path, or undefined if not found
121
- */
122
- function getNestedValue(obj, path) {
123
- return (0, pathAccess_1.getNestedPathValue)(obj, path);
124
- }
125
- /**
126
- * Sets a value in an object using a dot-notation path.
127
- * Creates intermediate objects/arrays as needed.
128
- * Supports array indexing with brackets: obj.array[0].property
129
- *
130
- * @param obj The source object to modify
131
- * @param path The dot-notation path (e.g., "user.addresses[0].city")
132
- * @param value The value to set
133
- * @returns true if successful, false if the path is invalid
134
- */
135
- function setNestedValue(obj, path, value) {
136
- if (!path || obj === null || obj === undefined || typeof obj !== 'object') {
137
- return false;
138
- }
139
- // Convert [0] to .0 and split by dots
140
- const parts = path.replace(/\[(\d+)\]/g, '.$1').split('.').filter(p => p !== '');
141
- if (parts.length === 0) {
142
- return false;
143
- }
144
- let current = obj;
145
- for (let i = 0; i < parts.length - 1; i++) {
146
- const part = parts[i];
147
- const nextPart = parts[i + 1];
148
- if (current[part] === undefined || current[part] === null) {
149
- // Create intermediate object or array based on next part
150
- current[part] = /^\d+$/.test(nextPart) ? [] : {};
151
- }
152
- current = current[part];
153
- if (typeof current !== 'object') {
154
- return false; // Can't navigate further
155
- }
156
- }
157
- const lastPart = parts[parts.length - 1];
158
- current[lastPart] = value;
159
- return true;
160
- }
161
- /**
162
- * Checks if a line is a property assignment command.
163
- * Format: varName.property.path = value
164
- * varName[0].property = value
165
- */
166
- function isPropertyAssignment(line) {
167
- const trimmed = line.trim();
168
- // Match: identifier followed by . or [ then = something
169
- // But NOT starting with 'var ' or other keywords
170
- return /^[a-zA-Z_][a-zA-Z0-9_]*[\.\[]/.test(trimmed) &&
171
- /=/.test(trimmed) &&
172
- !trimmed.startsWith('var ') &&
173
- !trimmed.startsWith('run ') &&
174
- !trimmed.startsWith('print ') &&
175
- !trimmed.startsWith('assert ') &&
176
- !trimmed.startsWith('sequence ');
177
- }
178
- /**
179
- * Parses a property assignment command.
180
- * Format: varName.path.to.property = value
181
- * Returns the variable name, the property path, and the value.
182
- */
183
- function parsePropertyAssignment(line) {
184
- const trimmed = line.trim();
185
- // Match: varName.path = value OR varName[0].path = value
186
- const match = trimmed.match(/^([a-zA-Z_][a-zA-Z0-9_]*)((?:\.[a-zA-Z_][a-zA-Z0-9_]*|\[\d+\])+)\s*=\s*(.+)$/);
187
- if (!match) {
188
- return null;
189
- }
190
- const varName = match[1];
191
- let propertyPath = match[2];
192
- const value = match[3].trim();
193
- // Remove leading dot if present
194
- if (propertyPath.startsWith('.')) {
195
- propertyPath = propertyPath.substring(1);
196
- }
197
- return {
198
- varName,
199
- propertyPath,
200
- value
201
- };
202
- }
203
- /**
204
- * Converts a value to a string for use in variable substitution.
205
- */
206
- function valueToString(value) {
207
- if (value === null) {
208
- return 'null';
209
- }
210
- if (value === undefined) {
211
- return '';
212
- }
213
- if (typeof value === 'object') {
214
- return JSON.stringify(value);
215
- }
216
- return String(value);
217
- }
218
- /**
219
- * Storage for JSON objects loaded during sequence execution.
220
- * Maps variable names to their parsed JSON data.
221
- */
222
- class JsonVariableStore {
223
- jsonObjects = new Map();
224
- /**
225
- * Stores a JSON object under the given variable name.
226
- */
227
- set(varName, data) {
228
- this.jsonObjects.set(varName, data);
229
- }
230
- /**
231
- * Gets the raw JSON object for a variable.
232
- */
233
- get(varName) {
234
- return this.jsonObjects.get(varName);
235
- }
236
- /**
237
- * Checks if a variable is a JSON object.
238
- */
239
- has(varName) {
240
- return this.jsonObjects.has(varName);
241
- }
242
- /**
243
- * Gets a nested value from a JSON variable.
244
- * @param varName The variable name
245
- * @param path Optional dot-notation path within the object
246
- */
247
- getValue(varName, path) {
248
- const obj = this.jsonObjects.get(varName);
249
- if (obj === undefined) {
250
- return undefined;
251
- }
252
- if (!path) {
253
- return obj;
254
- }
255
- return getNestedValue(obj, path);
256
- }
257
- /**
258
- * Clears all stored JSON objects.
259
- */
260
- clear() {
261
- this.jsonObjects.clear();
262
- }
263
- /**
264
- * Gets all variable names that have JSON objects stored.
265
- */
266
- getVariableNames() {
267
- return Array.from(this.jsonObjects.keys());
268
- }
269
- }
270
- exports.JsonVariableStore = JsonVariableStore;
271
- /**
272
- * Substitutes variables in text, with support for JSON object property access.
273
- * Handles both simple variables {{varName}} and nested access {{varName.property.path}}
274
- *
275
- * @param text The text containing variable references
276
- * @param variables Simple string variables (name -> value)
277
- * @param jsonStore Optional JSON variable store for complex objects
278
- */
279
- function substituteVariablesWithJson(text, variables, jsonStore) {
280
- // Match {{varName}}, {{$env.name}}, or {{varName.path.to.property}}
281
- return text.replace(/\{\{(\$env|[a-zA-Z_][a-zA-Z0-9_]*)((?:\.[a-zA-Z_][a-zA-Z0-9_]*|\[\d+\])*)\}\}/g, (match, varName, pathPart) => {
282
- // First check if it's a JSON object with a path
283
- if (jsonStore && jsonStore.has(varName)) {
284
- const path = pathPart ? pathPart.replace(/^\./, '') : '';
285
- const value = jsonStore.getValue(varName, path);
286
- return valueToString(value);
287
- }
288
- if (pathPart && varName in variables && typeof variables[varName] === 'object' && variables[varName] !== null) {
289
- const path = pathPart.replace(/^\./, '');
290
- const value = getNestedValue(variables[varName], path);
291
- return value === undefined && varName === '$env' ? match : valueToString(value);
292
- }
293
- // Check if there's a path and we have a simple variable that might be JSON
294
- if (pathPart && varName in variables && typeof variables[varName] === 'string') {
295
- // Try to parse the variable value as JSON
296
- try {
297
- const parsed = JSON.parse(variables[varName]);
298
- const path = pathPart.replace(/^\./, '');
299
- const value = getNestedValue(parsed, path);
300
- if (value === undefined && varName === '$env') {
301
- return match;
302
- }
303
- return valueToString(value);
304
- }
305
- catch {
306
- if (varName === '$env') {
307
- return match;
308
- }
309
- // Not JSON, fall through to simple substitution
310
- }
311
- }
312
- // Simple variable substitution
313
- if (varName in variables) {
314
- if (varName === '$env') {
315
- return match;
316
- }
317
- return variables[varName];
318
- }
319
- // Variable not found, return original
320
- return match;
321
- });
322
- }
323
- //# sourceMappingURL=jsonFileReader.js.map
package/out/mcpClient.js DELETED
@@ -1,193 +0,0 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
35
- Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.McpSessionManager = void 0;
37
- const fs = __importStar(require("fs"));
38
- const path = __importStar(require("path"));
39
- const index_js_1 = require("@modelcontextprotocol/sdk/client/index.js");
40
- const stdio_js_1 = require("@modelcontextprotocol/sdk/client/stdio.js");
41
- const streamableHttp_js_1 = require("@modelcontextprotocol/sdk/client/streamableHttp.js");
42
- const mcpConfig_1 = require("./mcpConfig");
43
- const mcpToolIntellisenseCache_1 = require("./mcpToolIntellisenseCache");
44
- const schemaGenerator_1 = require("./schemaGenerator");
45
- class NornJsonSchemaValidator {
46
- getValidator(schema) {
47
- return (input) => {
48
- const result = (0, schemaGenerator_1.validateAgainstSchemaObjectDetailed)(input, schema);
49
- if (result.valid) {
50
- return {
51
- valid: true,
52
- data: input,
53
- errorMessage: undefined
54
- };
55
- }
56
- return {
57
- valid: false,
58
- data: undefined,
59
- errorMessage: result.errorStrings?.join('; ') || 'Schema validation failed'
60
- };
61
- };
62
- }
63
- }
64
- function getNornClientVersion() {
65
- try {
66
- const packageJsonPath = path.resolve(__dirname, '..', 'package.json');
67
- const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));
68
- return typeof packageJson.version === 'string' ? packageJson.version : '0.0.0';
69
- }
70
- catch {
71
- return '0.0.0';
72
- }
73
- }
74
- const NORN_CLIENT_VERSION = getNornClientVersion();
75
- function createClient() {
76
- return new index_js_1.Client({ name: 'norn', version: NORN_CLIENT_VERSION }, {
77
- capabilities: {},
78
- jsonSchemaValidator: new NornJsonSchemaValidator()
79
- });
80
- }
81
- function extractTextContent(content) {
82
- return content
83
- .filter(block => block.type === 'text' && typeof block.text === 'string')
84
- .map(block => block.text)
85
- .join('\n');
86
- }
87
- function normalizeStructuredContent(value) {
88
- if (!value || typeof value !== 'object' || Array.isArray(value)) {
89
- return undefined;
90
- }
91
- return value;
92
- }
93
- class McpSessionManager {
94
- sessions = new Map();
95
- resolveSessionTarget(startPath, alias, envVariables) {
96
- const { filePath, server } = (0, mcpConfig_1.resolveMcpServer)(startPath, alias, envVariables);
97
- return {
98
- sessionKey: `${filePath}::${alias.toLowerCase()}`,
99
- server
100
- };
101
- }
102
- async createSession(server, sessionKey) {
103
- const client = createClient();
104
- if (server.transport === 'stdio') {
105
- const [command, ...args] = server.command;
106
- const transport = new stdio_js_1.StdioClientTransport({
107
- command,
108
- args,
109
- cwd: server.cwd
110
- });
111
- await client.connect(transport);
112
- }
113
- else {
114
- const transport = new streamableHttp_js_1.StreamableHTTPClientTransport(new URL(server.url), {
115
- requestInit: server.headers ? { headers: server.headers } : undefined
116
- });
117
- await client.connect(transport, server.timeoutMs ? { timeout: server.timeoutMs } : undefined);
118
- }
119
- const session = {
120
- client,
121
- config: server,
122
- toolsByName: new Map()
123
- };
124
- this.sessions.set(sessionKey, session);
125
- return session;
126
- }
127
- async getSession(startPath, alias, envVariables) {
128
- const target = this.resolveSessionTarget(startPath, alias, envVariables);
129
- const existing = this.sessions.get(target.sessionKey);
130
- if (existing) {
131
- return existing;
132
- }
133
- return this.createSession(target.server, target.sessionKey);
134
- }
135
- async listTools(startPath, alias, envVariables) {
136
- const session = await this.getSession(startPath, alias, envVariables);
137
- const tools = [];
138
- let cursor;
139
- do {
140
- const response = await session.client.listTools(cursor ? { cursor } : undefined, session.config.transport === 'http' && session.config.timeoutMs
141
- ? { timeout: session.config.timeoutMs }
142
- : undefined);
143
- for (const tool of response.tools) {
144
- tools.push(tool);
145
- session.toolsByName.set(tool.name.toLowerCase(), tool);
146
- }
147
- cursor = response.nextCursor;
148
- } while (cursor);
149
- const { filePath } = (0, mcpConfig_1.resolveMcpServer)(startPath, alias, envVariables);
150
- (0, mcpToolIntellisenseCache_1.saveMcpToolsForAlias)(filePath, alias, tools);
151
- return { tools };
152
- }
153
- async getToolDefinition(startPath, alias, toolName, envVariables) {
154
- const session = await this.getSession(startPath, alias, envVariables);
155
- const normalizedToolName = toolName.toLowerCase();
156
- const cached = session.toolsByName.get(normalizedToolName);
157
- if (cached) {
158
- return cached;
159
- }
160
- const listed = await this.listTools(startPath, alias, envVariables);
161
- const resolved = listed.tools.find(tool => tool.name.toLowerCase() === normalizedToolName);
162
- if (!resolved) {
163
- throw new Error(`Tool '${toolName}' was not found on MCP server '${alias}'.`);
164
- }
165
- return resolved;
166
- }
167
- async callTool(startPath, alias, toolName, args, envVariables) {
168
- const session = await this.getSession(startPath, alias, envVariables);
169
- await this.getToolDefinition(startPath, alias, toolName, envVariables);
170
- const result = await session.client.callTool({
171
- name: toolName,
172
- arguments: args
173
- }, undefined, session.config.transport === 'http' && session.config.timeoutMs
174
- ? { timeout: session.config.timeoutMs }
175
- : undefined);
176
- const content = (result.content || []);
177
- return {
178
- content,
179
- structuredContent: normalizeStructuredContent(result.structuredContent),
180
- isError: Boolean(result.isError),
181
- text: extractTextContent(content),
182
- server: alias,
183
- tool: toolName
184
- };
185
- }
186
- async closeAll() {
187
- const sessions = Array.from(this.sessions.values());
188
- this.sessions.clear();
189
- await Promise.allSettled(sessions.map(session => session.client.close()));
190
- }
191
- }
192
- exports.McpSessionManager = McpSessionManager;
193
- //# sourceMappingURL=mcpClient.js.map