@pikku/inspector 0.11.2 → 0.12.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.
- package/CHANGELOG.md +11 -1
- package/OPTIMIZATION-PLAN.md +195 -0
- package/dist/add/add-ai-agent.d.ts +2 -0
- package/dist/add/add-ai-agent.js +314 -0
- package/dist/add/add-channel.js +69 -61
- package/dist/add/add-cli.js +36 -18
- package/dist/add/add-file-with-factory.js +2 -0
- package/dist/add/add-functions.js +250 -75
- package/dist/add/add-http-route.d.ts +19 -10
- package/dist/add/add-http-route.js +152 -66
- package/dist/add/add-http-routes.d.ts +5 -0
- package/dist/add/add-http-routes.js +159 -0
- package/dist/add/add-keyed-wiring.d.ts +12 -0
- package/dist/add/add-keyed-wiring.js +97 -0
- package/dist/add/add-mcp-prompt.js +14 -9
- package/dist/add/add-mcp-resource.js +14 -9
- package/dist/add/add-middleware.d.ts +1 -4
- package/dist/add/add-middleware.js +364 -79
- package/dist/add/add-permission.d.ts +1 -1
- package/dist/add/add-permission.js +152 -40
- package/dist/add/add-queue-worker.js +18 -12
- package/dist/add/add-rpc-invocations.js +14 -0
- package/dist/add/add-schedule.js +11 -5
- package/dist/add/add-secret.d.ts +3 -0
- package/dist/add/add-secret.js +82 -0
- package/dist/add/add-trigger.d.ts +2 -0
- package/dist/add/add-trigger.js +87 -0
- package/dist/add/add-variable.d.ts +1 -0
- package/dist/add/add-variable.js +8 -0
- package/dist/add/add-workflow-graph.d.ts +3 -2
- package/dist/add/add-workflow-graph.js +143 -406
- package/dist/add/add-workflow.js +6 -4
- package/dist/error-codes.d.ts +14 -1
- package/dist/error-codes.js +19 -1
- package/dist/index.d.ts +9 -8
- package/dist/index.js +5 -4
- package/dist/inspector.d.ts +1 -1
- package/dist/inspector.js +91 -14
- package/dist/schema-generator.d.ts +1 -0
- package/dist/schema-generator.js +1 -0
- package/dist/types-map.js +10 -1
- package/dist/types.d.ts +163 -39
- package/dist/utils/compute-required-schemas.d.ts +4 -0
- package/dist/utils/compute-required-schemas.js +41 -0
- package/dist/utils/contract-hashes.d.ts +35 -0
- package/dist/utils/contract-hashes.js +202 -0
- package/dist/utils/custom-types-generator.d.ts +9 -0
- package/dist/utils/custom-types-generator.js +71 -0
- package/dist/utils/detect-schema-vendor.d.ts +22 -0
- package/dist/utils/detect-schema-vendor.js +76 -0
- package/dist/utils/ensure-function-metadata.d.ts +5 -2
- package/dist/utils/ensure-function-metadata.js +220 -6
- package/dist/utils/extract-function-name.d.ts +5 -16
- package/dist/utils/extract-function-name.js +86 -291
- package/dist/utils/extract-services.d.ts +2 -1
- package/dist/utils/extract-services.js +25 -1
- package/dist/utils/filter-inspector-state.js +107 -23
- package/dist/utils/get-property-value.d.ts +6 -1
- package/dist/utils/get-property-value.js +28 -3
- package/dist/utils/hash.d.ts +2 -0
- package/dist/utils/hash.js +23 -0
- package/dist/utils/middleware.d.ts +7 -30
- package/dist/utils/middleware.js +80 -66
- package/dist/utils/permissions.d.ts +2 -2
- package/dist/utils/permissions.js +10 -10
- package/dist/utils/post-process.d.ts +9 -10
- package/dist/utils/post-process.js +231 -24
- package/dist/utils/resolve-external-package.d.ts +12 -0
- package/dist/utils/resolve-external-package.js +34 -0
- package/dist/utils/resolve-function-types.d.ts +6 -0
- package/dist/utils/resolve-function-types.js +29 -0
- package/dist/utils/resolve-identifier.d.ts +10 -0
- package/dist/utils/resolve-identifier.js +36 -0
- package/dist/utils/resolve-versions.d.ts +2 -0
- package/dist/utils/resolve-versions.js +78 -0
- package/dist/utils/schema-generator.d.ts +9 -0
- package/dist/utils/schema-generator.js +209 -0
- package/dist/utils/serialize-inspector-state.d.ts +59 -22
- package/dist/utils/serialize-inspector-state.js +92 -20
- package/dist/utils/serialize-mcp-json.d.ts +2 -0
- package/dist/utils/serialize-mcp-json.js +99 -0
- package/dist/utils/serialize-middleware-groups-meta.d.ts +12 -0
- package/dist/utils/serialize-middleware-groups-meta.js +28 -0
- package/dist/utils/serialize-openapi-json.d.ts +85 -0
- package/dist/utils/serialize-openapi-json.js +151 -0
- package/dist/utils/serialize-permissions-groups-meta.d.ts +6 -0
- package/dist/utils/serialize-permissions-groups-meta.js +31 -0
- package/dist/utils/workflow/dsl/deserialize-dsl-workflow.js +34 -102
- package/dist/utils/workflow/dsl/extract-dsl-workflow.js +23 -4
- package/dist/utils/workflow/graph/convert-dsl-to-graph.js +12 -10
- package/dist/utils/workflow/graph/finalize-workflow-wires.d.ts +3 -0
- package/dist/utils/workflow/graph/finalize-workflow-wires.js +276 -0
- package/dist/utils/workflow/graph/finalize-workflows.d.ts +2 -0
- package/dist/utils/workflow/graph/finalize-workflows.js +75 -0
- package/dist/utils/workflow/graph/index.d.ts +2 -0
- package/dist/utils/workflow/graph/index.js +2 -0
- package/dist/utils/workflow/graph/serialize-workflow-graph.d.ts +0 -8
- package/dist/utils/workflow/graph/serialize-workflow-graph.js +1 -3
- package/dist/utils/workflow/graph/workflow-graph.types.d.ts +53 -79
- package/dist/utils/workflow/graph/workflow-graph.types.js +1 -1
- package/dist/visit.js +11 -6
- package/package.json +14 -4
- package/src/add/add-ai-agent.ts +468 -0
- package/src/add/add-channel.ts +82 -79
- package/src/add/add-cli.ts +49 -20
- package/src/add/add-file-with-factory.ts +2 -0
- package/src/add/add-functions.ts +330 -86
- package/src/add/add-http-route.ts +245 -88
- package/src/add/add-http-routes.ts +228 -0
- package/src/add/add-keyed-wiring.ts +151 -0
- package/src/add/add-mcp-prompt.ts +26 -15
- package/src/add/add-mcp-resource.ts +27 -15
- package/src/add/add-middleware.ts +482 -80
- package/src/add/add-permission.ts +199 -40
- package/src/add/add-queue-worker.ts +24 -19
- package/src/add/add-rpc-invocations.ts +17 -0
- package/src/add/add-schedule.ts +16 -11
- package/src/add/add-secret.ts +140 -0
- package/src/add/add-trigger.ts +154 -0
- package/src/add/add-variable.ts +9 -0
- package/src/add/add-workflow-graph.ts +180 -522
- package/src/add/add-workflow.ts +5 -4
- package/src/error-codes.ts +24 -1
- package/src/index.ts +22 -13
- package/src/inspector.ts +129 -17
- package/src/schema-generator.ts +1 -0
- package/src/types-map.ts +12 -1
- package/src/types.ts +175 -58
- package/src/utils/compute-required-schemas.ts +49 -0
- package/src/utils/contract-hashes.test.ts +528 -0
- package/src/utils/contract-hashes.ts +290 -0
- package/src/utils/custom-types-generator.ts +88 -0
- package/src/utils/detect-schema-vendor.ts +90 -0
- package/src/utils/ensure-function-metadata.ts +324 -7
- package/src/utils/extract-function-name.ts +101 -351
- package/src/utils/extract-services.ts +35 -2
- package/src/utils/filter-inspector-state.test.ts +34 -20
- package/src/utils/filter-inspector-state.ts +140 -31
- package/src/utils/get-property-value.ts +42 -4
- package/src/utils/hash.ts +26 -0
- package/src/utils/middleware.test.ts +204 -0
- package/src/utils/middleware.ts +129 -67
- package/src/utils/permissions.test.ts +35 -12
- package/src/utils/permissions.ts +10 -10
- package/src/utils/post-process.ts +283 -43
- package/src/utils/resolve-external-package.ts +42 -0
- package/src/utils/resolve-function-types.ts +42 -0
- package/src/utils/resolve-identifier.ts +46 -0
- package/src/utils/resolve-versions.test.ts +249 -0
- package/src/utils/resolve-versions.ts +105 -0
- package/src/utils/schema-generator.ts +329 -0
- package/src/utils/serialize-inspector-state.ts +163 -40
- package/src/utils/serialize-mcp-json.ts +145 -0
- package/src/utils/serialize-middleware-groups-meta.ts +33 -0
- package/src/utils/serialize-openapi-json.ts +277 -0
- package/src/utils/serialize-permissions-groups-meta.ts +35 -0
- package/src/utils/test-data/inspector-state.json +69 -66
- package/src/utils/workflow/dsl/deserialize-dsl-workflow.ts +43 -119
- package/src/utils/workflow/dsl/extract-dsl-workflow.ts +24 -4
- package/src/utils/workflow/graph/convert-dsl-to-graph.ts +17 -10
- package/src/utils/workflow/graph/finalize-workflow-wires.ts +310 -0
- package/src/utils/workflow/graph/finalize-workflows.ts +100 -0
- package/src/utils/workflow/graph/index.ts +5 -0
- package/src/utils/workflow/graph/serialize-workflow-graph.ts +1 -8
- package/src/utils/workflow/graph/workflow-graph.types.ts +29 -78
- package/src/visit.ts +12 -6
- package/tsconfig.tsbuildinfo +1 -1
- package/dist/add/add-forge-credential.d.ts +0 -8
- package/dist/add/add-forge-credential.js +0 -77
- package/dist/add/add-forge-node.d.ts +0 -7
- package/dist/add/add-forge-node.js +0 -77
- package/dist/add/add-mcp-tool.d.ts +0 -2
- package/dist/add/add-mcp-tool.js +0 -81
- package/dist/utils/extract-service-metadata.d.ts +0 -19
- package/dist/utils/extract-service-metadata.js +0 -244
- package/dist/utils/write-service-metadata.d.ts +0 -13
- package/dist/utils/write-service-metadata.js +0 -37
- package/src/add/add-forge-credential.ts +0 -119
- package/src/add/add-forge-node.ts +0 -132
- package/src/add/add-mcp-tool.ts +0 -141
- package/src/utils/extract-service-metadata.ts +0 -353
- package/src/utils/write-service-metadata.ts +0 -51
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
import * as ts from 'typescript';
|
|
2
|
+
import { dirname, join, resolve } from 'path';
|
|
3
|
+
import { createGenerator, RootlessError } from 'ts-json-schema-generator';
|
|
4
|
+
import { tsImport } from 'tsx/esm/api';
|
|
5
|
+
import * as z from 'zod';
|
|
6
|
+
import { zodToTs, createAuxiliaryTypeStore } from 'zod-to-ts';
|
|
7
|
+
import { ErrorCode } from '../error-codes.js';
|
|
8
|
+
import { generateCustomTypes } from './custom-types-generator.js';
|
|
9
|
+
const PRIMITIVE_TYPES = new Set([
|
|
10
|
+
'boolean',
|
|
11
|
+
'string',
|
|
12
|
+
'number',
|
|
13
|
+
'null',
|
|
14
|
+
'undefined',
|
|
15
|
+
'void',
|
|
16
|
+
'any',
|
|
17
|
+
'unknown',
|
|
18
|
+
'never',
|
|
19
|
+
]);
|
|
20
|
+
function primitiveTypeToSchema(typeStr) {
|
|
21
|
+
const normalized = typeStr.trim();
|
|
22
|
+
if (normalized === 'void' ||
|
|
23
|
+
normalized === 'undefined' ||
|
|
24
|
+
normalized === 'never') {
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
if (normalized === 'boolean' ||
|
|
28
|
+
normalized === 'false | true' ||
|
|
29
|
+
normalized === 'true | false') {
|
|
30
|
+
return { type: 'boolean' };
|
|
31
|
+
}
|
|
32
|
+
if (normalized === 'true') {
|
|
33
|
+
return { const: true };
|
|
34
|
+
}
|
|
35
|
+
if (normalized === 'false') {
|
|
36
|
+
return { const: false };
|
|
37
|
+
}
|
|
38
|
+
if (normalized === 'string') {
|
|
39
|
+
return { type: 'string' };
|
|
40
|
+
}
|
|
41
|
+
if (normalized === 'number') {
|
|
42
|
+
return { type: 'number' };
|
|
43
|
+
}
|
|
44
|
+
if (normalized === 'null') {
|
|
45
|
+
return { type: 'null' };
|
|
46
|
+
}
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
function createProgramWithVirtualFile(tsconfig, virtualFilePath, virtualFileContent) {
|
|
50
|
+
const configPath = resolve(tsconfig);
|
|
51
|
+
const configFile = ts.readConfigFile(configPath, ts.sys.readFile);
|
|
52
|
+
const basePath = dirname(configPath);
|
|
53
|
+
const parsedConfig = ts.parseJsonConfigFileContent(configFile.config, ts.sys, basePath);
|
|
54
|
+
const resolvedVirtualPath = resolve(virtualFilePath);
|
|
55
|
+
const fileNames = [...parsedConfig.fileNames, resolvedVirtualPath];
|
|
56
|
+
const defaultHost = ts.createCompilerHost(parsedConfig.options);
|
|
57
|
+
const customHost = {
|
|
58
|
+
...defaultHost,
|
|
59
|
+
getSourceFile(fileName, languageVersionOrOptions, onError, shouldCreateNewSourceFile) {
|
|
60
|
+
if (resolve(fileName) === resolvedVirtualPath) {
|
|
61
|
+
return ts.createSourceFile(fileName, virtualFileContent, languageVersionOrOptions);
|
|
62
|
+
}
|
|
63
|
+
return defaultHost.getSourceFile(fileName, languageVersionOrOptions, onError, shouldCreateNewSourceFile);
|
|
64
|
+
},
|
|
65
|
+
fileExists(fileName) {
|
|
66
|
+
if (resolve(fileName) === resolvedVirtualPath)
|
|
67
|
+
return true;
|
|
68
|
+
return defaultHost.fileExists(fileName);
|
|
69
|
+
},
|
|
70
|
+
readFile(fileName) {
|
|
71
|
+
if (resolve(fileName) === resolvedVirtualPath)
|
|
72
|
+
return virtualFileContent;
|
|
73
|
+
return defaultHost.readFile(fileName);
|
|
74
|
+
},
|
|
75
|
+
};
|
|
76
|
+
return ts.createProgram(fileNames, parsedConfig.options, customHost);
|
|
77
|
+
}
|
|
78
|
+
function generateTSSchemas(logger, tsconfig, customTypesContent, typesMap, functionMeta, httpWiringsMeta, additionalTypes, additionalProperties = false, schemaLookup) {
|
|
79
|
+
const schemasSet = new Set(typesMap.customTypes.keys());
|
|
80
|
+
for (const { inputs, outputs } of Object.values(functionMeta)) {
|
|
81
|
+
const types = [...(inputs || []), ...(outputs || [])];
|
|
82
|
+
for (const type of types) {
|
|
83
|
+
try {
|
|
84
|
+
const uniqueName = typesMap.getUniqueName(type);
|
|
85
|
+
if (uniqueName) {
|
|
86
|
+
schemasSet.add(uniqueName);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
catch {
|
|
90
|
+
// Skip types not in typesMap (e.g., inline types in generated workflow workers)
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
for (const wiringRoutes of Object.values(httpWiringsMeta)) {
|
|
95
|
+
for (const { inputTypes } of Object.values(wiringRoutes)) {
|
|
96
|
+
if (inputTypes?.body) {
|
|
97
|
+
schemasSet.add(inputTypes.body);
|
|
98
|
+
}
|
|
99
|
+
if (inputTypes?.query) {
|
|
100
|
+
schemasSet.add(inputTypes.query);
|
|
101
|
+
}
|
|
102
|
+
if (inputTypes?.params) {
|
|
103
|
+
schemasSet.add(inputTypes.params);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
if (additionalTypes) {
|
|
108
|
+
for (const type of additionalTypes) {
|
|
109
|
+
schemasSet.add(type);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
const virtualFilePath = join(dirname(resolve(tsconfig)), '__pikku_virtual_types__.ts');
|
|
113
|
+
const program = createProgramWithVirtualFile(tsconfig, virtualFilePath, customTypesContent);
|
|
114
|
+
const generator = createGenerator({
|
|
115
|
+
tsProgram: program,
|
|
116
|
+
skipTypeCheck: true,
|
|
117
|
+
topRef: false,
|
|
118
|
+
discriminatorType: 'open-api',
|
|
119
|
+
expose: 'export',
|
|
120
|
+
jsDoc: 'extended',
|
|
121
|
+
sortProps: true,
|
|
122
|
+
strictTuples: false,
|
|
123
|
+
encodeRefs: false,
|
|
124
|
+
additionalProperties,
|
|
125
|
+
});
|
|
126
|
+
const schemas = {};
|
|
127
|
+
schemasSet.forEach((schema) => {
|
|
128
|
+
if (PRIMITIVE_TYPES.has(schema)) {
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
if (schemaLookup?.has(schema)) {
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
try {
|
|
135
|
+
schemas[schema] = generator.createSchema(schema);
|
|
136
|
+
}
|
|
137
|
+
catch (e) {
|
|
138
|
+
if (e instanceof RootlessError) {
|
|
139
|
+
const customType = typesMap.customTypes.get(schema);
|
|
140
|
+
if (customType) {
|
|
141
|
+
const primitiveSchema = primitiveTypeToSchema(customType.type);
|
|
142
|
+
if (primitiveSchema) {
|
|
143
|
+
schemas[schema] = primitiveSchema;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
const customType = typesMap.customTypes.get(schema);
|
|
149
|
+
logger.error(`[${ErrorCode.SCHEMA_GENERATION_ERROR}] Error generating schema: ${schema}. Message: ${e.message}. Type info: ${customType ? `type=${customType.type}` : 'not in typesMap'}`);
|
|
150
|
+
}
|
|
151
|
+
});
|
|
152
|
+
return schemas;
|
|
153
|
+
}
|
|
154
|
+
async function generateZodSchemas(logger, schemaLookup, typesMap) {
|
|
155
|
+
const schemas = {};
|
|
156
|
+
const auxiliaryTypeStore = createAuxiliaryTypeStore();
|
|
157
|
+
const printer = ts.createPrinter();
|
|
158
|
+
const fakeSourceFile = ts.createSourceFile('zod-types.ts', '', ts.ScriptTarget.ESNext, false, ts.ScriptKind.TS);
|
|
159
|
+
for (const [schemaName, ref] of schemaLookup.entries()) {
|
|
160
|
+
if (ref.vendor && ref.vendor !== 'zod') {
|
|
161
|
+
throw new Error(`Schema '${schemaName}' uses ${ref.vendor} which is not yet supported for JSON Schema generation. ` +
|
|
162
|
+
`Currently only Zod schemas can be converted to JSON Schema. ` +
|
|
163
|
+
`Please use Zod or contribute support for ${ref.vendor}.`);
|
|
164
|
+
}
|
|
165
|
+
try {
|
|
166
|
+
const module = await tsImport(ref.sourceFile, import.meta.url);
|
|
167
|
+
const zodSchema = module[ref.variableName];
|
|
168
|
+
if (!zodSchema) {
|
|
169
|
+
logger.warn(`Could not find exported schema '${ref.variableName}' in ${ref.sourceFile} for ${schemaName}. Available exports: ${Object.keys(module).join(', ')}`);
|
|
170
|
+
continue;
|
|
171
|
+
}
|
|
172
|
+
const schema = z.toJSONSchema(zodSchema, {
|
|
173
|
+
unrepresentable: 'any',
|
|
174
|
+
override: ({ zodSchema, jsonSchema }) => {
|
|
175
|
+
if (zodSchema._zod?.def?.type === 'date') {
|
|
176
|
+
;
|
|
177
|
+
jsonSchema.type = 'string';
|
|
178
|
+
jsonSchema.format = 'date-time';
|
|
179
|
+
}
|
|
180
|
+
},
|
|
181
|
+
});
|
|
182
|
+
if (schema.required && schema.properties) {
|
|
183
|
+
schema.required = schema.required.filter((fieldName) => {
|
|
184
|
+
const prop = schema.properties[fieldName];
|
|
185
|
+
return prop && prop.default === undefined;
|
|
186
|
+
});
|
|
187
|
+
if (schema.required.length === 0) {
|
|
188
|
+
delete schema.required;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
schemas[schemaName] = schema;
|
|
192
|
+
const { node: tsType } = zodToTs(zodSchema, { auxiliaryTypeStore });
|
|
193
|
+
const typeText = printer.printNode(ts.EmitHint.Unspecified, tsType, fakeSourceFile);
|
|
194
|
+
typesMap.addCustomType(schemaName, typeText, []);
|
|
195
|
+
logger.debug(`• Generated schema from Zod: ${schemaName}`);
|
|
196
|
+
}
|
|
197
|
+
catch (e) {
|
|
198
|
+
logger.warn(`Could not convert Zod schema '${schemaName}': ${e instanceof Error ? e.message : e}`);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
return schemas;
|
|
202
|
+
}
|
|
203
|
+
export async function generateAllSchemas(logger, config, state) {
|
|
204
|
+
const zodSchemas = await generateZodSchemas(logger, state.schemaLookup, state.functions.typesMap);
|
|
205
|
+
const requiredTypes = new Set();
|
|
206
|
+
const customTypesContent = generateCustomTypes(state.functions.typesMap, requiredTypes);
|
|
207
|
+
const tsSchemas = generateTSSchemas(logger, config.tsconfig, customTypesContent, state.functions.typesMap, state.functions.meta, state.http.meta, config.schemasFromTypes, config.schema?.additionalProperties, state.schemaLookup);
|
|
208
|
+
return { ...tsSchemas, ...zodSchemas };
|
|
209
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { JSONValue } from '@pikku/core';
|
|
2
|
+
import { InspectorDiagnostic, InspectorState } from '../types.js';
|
|
2
3
|
/**
|
|
3
4
|
* Serializable version of InspectorState that can be saved to JSON
|
|
4
5
|
* Omits typesLookup (contains non-serializable ts.Type objects) and converts Maps/Sets to arrays
|
|
@@ -74,10 +75,15 @@ export interface SerializableInspectorState {
|
|
|
74
75
|
}[]
|
|
75
76
|
]>
|
|
76
77
|
]>;
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
78
|
+
schemaLookup: Array<[
|
|
79
|
+
string,
|
|
80
|
+
{
|
|
81
|
+
variableName: string;
|
|
82
|
+
sourceFile: string;
|
|
83
|
+
vendor?: 'zod' | 'valibot' | 'arktype' | 'effect' | 'unknown';
|
|
84
|
+
}
|
|
85
|
+
]>;
|
|
86
|
+
schemas: Record<string, JSONValue>;
|
|
81
87
|
functions: {
|
|
82
88
|
typesMap: {
|
|
83
89
|
map: Array<[string, {
|
|
@@ -119,6 +125,11 @@ export interface SerializableInspectorState {
|
|
|
119
125
|
files: string[];
|
|
120
126
|
meta: InspectorState['channels']['meta'];
|
|
121
127
|
};
|
|
128
|
+
triggers: {
|
|
129
|
+
meta: InspectorState['triggers']['meta'];
|
|
130
|
+
sourceMeta: InspectorState['triggers']['sourceMeta'];
|
|
131
|
+
files: string[];
|
|
132
|
+
};
|
|
122
133
|
scheduledTasks: {
|
|
123
134
|
meta: InspectorState['scheduledTasks']['meta'];
|
|
124
135
|
files: string[];
|
|
@@ -138,6 +149,7 @@ export interface SerializableInspectorState {
|
|
|
138
149
|
path: string;
|
|
139
150
|
exportedName: string;
|
|
140
151
|
}]>;
|
|
152
|
+
invokedWorkflows: string[];
|
|
141
153
|
};
|
|
142
154
|
rpc: {
|
|
143
155
|
internalMeta: InspectorState['rpc']['internalMeta'];
|
|
@@ -159,27 +171,52 @@ export interface SerializableInspectorState {
|
|
|
159
171
|
promptsMeta: InspectorState['mcpEndpoints']['promptsMeta'];
|
|
160
172
|
files: string[];
|
|
161
173
|
};
|
|
174
|
+
agents: {
|
|
175
|
+
agentsMeta: InspectorState['agents']['agentsMeta'];
|
|
176
|
+
files: [string, {
|
|
177
|
+
path: string;
|
|
178
|
+
exportedName: string;
|
|
179
|
+
}][];
|
|
180
|
+
};
|
|
162
181
|
cli: {
|
|
163
182
|
meta: InspectorState['cli']['meta'];
|
|
164
183
|
files: string[];
|
|
165
184
|
};
|
|
166
|
-
|
|
167
|
-
meta: InspectorState['
|
|
185
|
+
nodes: {
|
|
186
|
+
meta: InspectorState['nodes']['meta'];
|
|
187
|
+
files: string[];
|
|
188
|
+
};
|
|
189
|
+
secrets: {
|
|
190
|
+
definitions: InspectorState['secrets']['definitions'];
|
|
168
191
|
files: string[];
|
|
169
192
|
};
|
|
170
|
-
|
|
171
|
-
|
|
193
|
+
variables: {
|
|
194
|
+
definitions: InspectorState['variables']['definitions'];
|
|
172
195
|
files: string[];
|
|
173
196
|
};
|
|
197
|
+
manifest: InspectorState['manifest'];
|
|
174
198
|
middleware: {
|
|
175
|
-
|
|
199
|
+
definitions: InspectorState['middleware']['definitions'];
|
|
200
|
+
instances: InspectorState['middleware']['instances'];
|
|
176
201
|
tagMiddleware: Array<[
|
|
177
202
|
string,
|
|
178
203
|
InspectorState['middleware']['tagMiddleware'] extends Map<string, infer V> ? V : never
|
|
179
204
|
]>;
|
|
180
205
|
};
|
|
206
|
+
channelMiddleware: {
|
|
207
|
+
definitions: InspectorState['channelMiddleware']['definitions'];
|
|
208
|
+
instances: InspectorState['channelMiddleware']['instances'];
|
|
209
|
+
tagMiddleware: Array<[
|
|
210
|
+
string,
|
|
211
|
+
InspectorState['channelMiddleware']['tagMiddleware'] extends Map<string, infer V> ? V : never
|
|
212
|
+
]>;
|
|
213
|
+
};
|
|
214
|
+
aiMiddleware: {
|
|
215
|
+
definitions: InspectorState['aiMiddleware']['definitions'];
|
|
216
|
+
};
|
|
181
217
|
permissions: {
|
|
182
|
-
|
|
218
|
+
definitions: InspectorState['permissions']['definitions'];
|
|
219
|
+
instances: InspectorState['permissions']['instances'];
|
|
183
220
|
tagPermissions: Array<[
|
|
184
221
|
string,
|
|
185
222
|
InspectorState['permissions']['tagPermissions'] extends Map<string, infer V> ? V : never
|
|
@@ -193,16 +230,15 @@ export interface SerializableInspectorState {
|
|
|
193
230
|
allSingletonServices: string[];
|
|
194
231
|
allWireServices: string[];
|
|
195
232
|
};
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
description: string;
|
|
200
|
-
package: string;
|
|
201
|
-
path: string;
|
|
202
|
-
version: string;
|
|
203
|
-
interface: string;
|
|
204
|
-
expandedProperties: Record<string, string>;
|
|
233
|
+
resolvedIOTypes: Record<string, {
|
|
234
|
+
inputType: string;
|
|
235
|
+
outputType: string;
|
|
205
236
|
}>;
|
|
237
|
+
middlewareGroupsMeta: InspectorState['middlewareGroupsMeta'];
|
|
238
|
+
permissionsGroupsMeta: InspectorState['permissionsGroupsMeta'];
|
|
239
|
+
requiredSchemas: string[];
|
|
240
|
+
openAPISpec: Record<string, any> | null;
|
|
241
|
+
diagnostics: InspectorDiagnostic[];
|
|
206
242
|
}
|
|
207
243
|
/**
|
|
208
244
|
* Serializes InspectorState to a JSON-compatible format
|
|
@@ -213,9 +249,10 @@ export declare function serializeInspectorState(state: InspectorState): Serializ
|
|
|
213
249
|
* Deserializes JSON data back to InspectorState
|
|
214
250
|
* Creates a partial state suitable for filtering/generation (without typesLookup)
|
|
215
251
|
*/
|
|
216
|
-
export declare function deserializeInspectorState(data: SerializableInspectorState): Omit<InspectorState, 'typesLookup' | '
|
|
217
|
-
|
|
252
|
+
export declare function deserializeInspectorState(data: SerializableInspectorState): Omit<InspectorState, 'typesLookup' | 'schemaLookup'> & {
|
|
253
|
+
schemaLookup: Map<string, {
|
|
218
254
|
variableName: string;
|
|
219
255
|
sourceFile: string;
|
|
256
|
+
vendor?: 'zod' | 'valibot' | 'arktype' | 'effect' | 'unknown';
|
|
220
257
|
}>;
|
|
221
258
|
};
|
|
@@ -26,7 +26,8 @@ export function serializeInspectorState(state) {
|
|
|
26
26
|
configFactories: Array.from(state.configFactories.entries()),
|
|
27
27
|
filesAndMethods: state.filesAndMethods,
|
|
28
28
|
filesAndMethodsErrors: Array.from(state.filesAndMethodsErrors.entries()).map(([key, mapValue]) => [key, Array.from(mapValue.entries())]),
|
|
29
|
-
|
|
29
|
+
schemaLookup: Array.from(state.schemaLookup.entries()),
|
|
30
|
+
schemas: state.schemas,
|
|
30
31
|
functions: {
|
|
31
32
|
typesMap: serializeTypesMap(state.functions.typesMap),
|
|
32
33
|
meta: state.functions.meta,
|
|
@@ -43,6 +44,11 @@ export function serializeInspectorState(state) {
|
|
|
43
44
|
files: Array.from(state.channels.files),
|
|
44
45
|
meta: state.channels.meta,
|
|
45
46
|
},
|
|
47
|
+
triggers: {
|
|
48
|
+
meta: state.triggers.meta,
|
|
49
|
+
sourceMeta: state.triggers.sourceMeta,
|
|
50
|
+
files: Array.from(state.triggers.files),
|
|
51
|
+
},
|
|
46
52
|
scheduledTasks: {
|
|
47
53
|
meta: state.scheduledTasks.meta,
|
|
48
54
|
files: Array.from(state.scheduledTasks.files),
|
|
@@ -56,6 +62,7 @@ export function serializeInspectorState(state) {
|
|
|
56
62
|
files: Array.from(state.workflows.files.entries()),
|
|
57
63
|
graphMeta: state.workflows.graphMeta,
|
|
58
64
|
graphFiles: Array.from(state.workflows.graphFiles.entries()),
|
|
65
|
+
invokedWorkflows: Array.from(state.workflows.invokedWorkflows),
|
|
59
66
|
},
|
|
60
67
|
rpc: {
|
|
61
68
|
internalMeta: state.rpc.internalMeta,
|
|
@@ -71,24 +78,43 @@ export function serializeInspectorState(state) {
|
|
|
71
78
|
promptsMeta: state.mcpEndpoints.promptsMeta,
|
|
72
79
|
files: Array.from(state.mcpEndpoints.files),
|
|
73
80
|
},
|
|
81
|
+
agents: {
|
|
82
|
+
agentsMeta: state.agents?.agentsMeta ?? {},
|
|
83
|
+
files: Array.from(state.agents?.files?.entries() ?? []),
|
|
84
|
+
},
|
|
74
85
|
cli: {
|
|
75
86
|
meta: state.cli.meta,
|
|
76
87
|
files: Array.from(state.cli.files),
|
|
77
88
|
},
|
|
78
|
-
|
|
79
|
-
meta: state.
|
|
80
|
-
files: Array.from(state.
|
|
89
|
+
nodes: {
|
|
90
|
+
meta: state.nodes.meta,
|
|
91
|
+
files: Array.from(state.nodes.files),
|
|
92
|
+
},
|
|
93
|
+
secrets: {
|
|
94
|
+
definitions: state.secrets.definitions,
|
|
95
|
+
files: Array.from(state.secrets.files),
|
|
81
96
|
},
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
files: Array.from(state.
|
|
97
|
+
variables: {
|
|
98
|
+
definitions: state.variables.definitions,
|
|
99
|
+
files: Array.from(state.variables.files),
|
|
85
100
|
},
|
|
101
|
+
manifest: state.manifest,
|
|
86
102
|
middleware: {
|
|
87
|
-
|
|
103
|
+
definitions: state.middleware.definitions,
|
|
104
|
+
instances: state.middleware.instances,
|
|
88
105
|
tagMiddleware: Array.from(state.middleware.tagMiddleware.entries()),
|
|
89
106
|
},
|
|
107
|
+
channelMiddleware: {
|
|
108
|
+
definitions: state.channelMiddleware.definitions,
|
|
109
|
+
instances: state.channelMiddleware.instances,
|
|
110
|
+
tagMiddleware: Array.from(state.channelMiddleware.tagMiddleware.entries()),
|
|
111
|
+
},
|
|
112
|
+
aiMiddleware: {
|
|
113
|
+
definitions: state.aiMiddleware.definitions,
|
|
114
|
+
},
|
|
90
115
|
permissions: {
|
|
91
|
-
|
|
116
|
+
definitions: state.permissions.definitions,
|
|
117
|
+
instances: state.permissions.instances,
|
|
92
118
|
tagPermissions: Array.from(state.permissions.tagPermissions.entries()),
|
|
93
119
|
},
|
|
94
120
|
serviceAggregation: {
|
|
@@ -99,7 +125,12 @@ export function serializeInspectorState(state) {
|
|
|
99
125
|
allSingletonServices: state.serviceAggregation.allSingletonServices,
|
|
100
126
|
allWireServices: state.serviceAggregation.allWireServices,
|
|
101
127
|
},
|
|
102
|
-
|
|
128
|
+
resolvedIOTypes: state.resolvedIOTypes,
|
|
129
|
+
middlewareGroupsMeta: state.middlewareGroupsMeta,
|
|
130
|
+
permissionsGroupsMeta: state.permissionsGroupsMeta,
|
|
131
|
+
requiredSchemas: Array.from(state.requiredSchemas),
|
|
132
|
+
openAPISpec: state.openAPISpec,
|
|
133
|
+
diagnostics: state.diagnostics,
|
|
103
134
|
};
|
|
104
135
|
}
|
|
105
136
|
/**
|
|
@@ -130,7 +161,8 @@ export function deserializeInspectorState(data) {
|
|
|
130
161
|
key,
|
|
131
162
|
new Map(entries),
|
|
132
163
|
])),
|
|
133
|
-
|
|
164
|
+
schemaLookup: new Map(data.schemaLookup || []),
|
|
165
|
+
schemas: data.schemas || {},
|
|
134
166
|
functions: {
|
|
135
167
|
typesMap: deserializeTypesMap(data.functions.typesMap),
|
|
136
168
|
meta: data.functions.meta,
|
|
@@ -147,6 +179,11 @@ export function deserializeInspectorState(data) {
|
|
|
147
179
|
files: new Set(data.channels.files),
|
|
148
180
|
meta: data.channels.meta,
|
|
149
181
|
},
|
|
182
|
+
triggers: {
|
|
183
|
+
meta: data.triggers?.meta ?? {},
|
|
184
|
+
sourceMeta: data.triggers?.sourceMeta ?? {},
|
|
185
|
+
files: new Set(data.triggers?.files ?? []),
|
|
186
|
+
},
|
|
150
187
|
scheduledTasks: {
|
|
151
188
|
meta: data.scheduledTasks.meta,
|
|
152
189
|
files: new Set(data.scheduledTasks.files),
|
|
@@ -160,6 +197,7 @@ export function deserializeInspectorState(data) {
|
|
|
160
197
|
files: new Map(data.workflows.files),
|
|
161
198
|
graphMeta: data.workflows.graphMeta || {},
|
|
162
199
|
graphFiles: new Map(data.workflows.graphFiles || []),
|
|
200
|
+
invokedWorkflows: new Set(data.workflows.invokedWorkflows || []),
|
|
163
201
|
},
|
|
164
202
|
rpc: {
|
|
165
203
|
internalMeta: data.rpc.internalMeta,
|
|
@@ -175,24 +213,43 @@ export function deserializeInspectorState(data) {
|
|
|
175
213
|
promptsMeta: data.mcpEndpoints.promptsMeta,
|
|
176
214
|
files: new Set(data.mcpEndpoints.files),
|
|
177
215
|
},
|
|
216
|
+
agents: {
|
|
217
|
+
agentsMeta: data.agents?.agentsMeta || {},
|
|
218
|
+
files: new Map(data.agents?.files || []),
|
|
219
|
+
},
|
|
178
220
|
cli: {
|
|
179
221
|
meta: data.cli.meta,
|
|
180
222
|
files: new Set(data.cli.files),
|
|
181
223
|
},
|
|
182
|
-
|
|
183
|
-
meta: data.
|
|
184
|
-
files: new Set(data.
|
|
224
|
+
nodes: {
|
|
225
|
+
meta: data.nodes?.meta || {},
|
|
226
|
+
files: new Set(data.nodes?.files || []),
|
|
227
|
+
},
|
|
228
|
+
secrets: {
|
|
229
|
+
definitions: data.secrets?.definitions || [],
|
|
230
|
+
files: new Set(data.secrets?.files || []),
|
|
185
231
|
},
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
files: new Set(data.
|
|
232
|
+
variables: {
|
|
233
|
+
definitions: data.variables?.definitions || [],
|
|
234
|
+
files: new Set(data.variables?.files || []),
|
|
189
235
|
},
|
|
236
|
+
manifest: data.manifest || { initial: null, current: null, errors: [] },
|
|
190
237
|
middleware: {
|
|
191
|
-
|
|
238
|
+
definitions: data.middleware.definitions,
|
|
239
|
+
instances: data.middleware.instances || {},
|
|
192
240
|
tagMiddleware: new Map(data.middleware.tagMiddleware),
|
|
193
241
|
},
|
|
242
|
+
channelMiddleware: {
|
|
243
|
+
definitions: data.channelMiddleware?.definitions || {},
|
|
244
|
+
instances: data.channelMiddleware?.instances || {},
|
|
245
|
+
tagMiddleware: new Map(data.channelMiddleware?.tagMiddleware || []),
|
|
246
|
+
},
|
|
247
|
+
aiMiddleware: {
|
|
248
|
+
definitions: data.aiMiddleware?.definitions || {},
|
|
249
|
+
},
|
|
194
250
|
permissions: {
|
|
195
|
-
|
|
251
|
+
definitions: data.permissions.definitions,
|
|
252
|
+
instances: data.permissions.instances || {},
|
|
196
253
|
tagPermissions: new Map(data.permissions.tagPermissions),
|
|
197
254
|
},
|
|
198
255
|
serviceAggregation: {
|
|
@@ -203,6 +260,21 @@ export function deserializeInspectorState(data) {
|
|
|
203
260
|
allSingletonServices: data.serviceAggregation.allSingletonServices,
|
|
204
261
|
allWireServices: data.serviceAggregation.allWireServices,
|
|
205
262
|
},
|
|
206
|
-
|
|
263
|
+
resolvedIOTypes: data.resolvedIOTypes || {},
|
|
264
|
+
middlewareGroupsMeta: data.middlewareGroupsMeta || {
|
|
265
|
+
definitions: {},
|
|
266
|
+
instances: {},
|
|
267
|
+
httpGroups: {},
|
|
268
|
+
tagGroups: {},
|
|
269
|
+
channelMiddleware: { definitions: {}, instances: {}, tagGroups: {} },
|
|
270
|
+
},
|
|
271
|
+
permissionsGroupsMeta: data.permissionsGroupsMeta || {
|
|
272
|
+
definitions: {},
|
|
273
|
+
httpGroups: {},
|
|
274
|
+
tagGroups: {},
|
|
275
|
+
},
|
|
276
|
+
requiredSchemas: new Set(data.requiredSchemas || []),
|
|
277
|
+
openAPISpec: data.openAPISpec || null,
|
|
278
|
+
diagnostics: data.diagnostics || [],
|
|
207
279
|
};
|
|
208
280
|
}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
export const serializeMCPJson = (logger, state) => {
|
|
2
|
+
const { mcpEndpoints, functions, schemas } = state;
|
|
3
|
+
const { meta: functionsMeta, typesMap } = functions;
|
|
4
|
+
const { resourcesMeta, toolsMeta, promptsMeta } = mcpEndpoints;
|
|
5
|
+
const tools = [];
|
|
6
|
+
const resources = [];
|
|
7
|
+
const prompts = [];
|
|
8
|
+
const loadSchema = (typeName) => {
|
|
9
|
+
if (!typeName ||
|
|
10
|
+
[
|
|
11
|
+
'boolean',
|
|
12
|
+
'string',
|
|
13
|
+
'number',
|
|
14
|
+
'null',
|
|
15
|
+
'undefined',
|
|
16
|
+
'void',
|
|
17
|
+
'unknown',
|
|
18
|
+
'never',
|
|
19
|
+
].includes(typeName)) {
|
|
20
|
+
return undefined;
|
|
21
|
+
}
|
|
22
|
+
const uniqueName = typesMap.getUniqueName(typeName);
|
|
23
|
+
if (!uniqueName) {
|
|
24
|
+
return undefined;
|
|
25
|
+
}
|
|
26
|
+
const schema = schemas[uniqueName];
|
|
27
|
+
if (!schema) {
|
|
28
|
+
logger.warn(`Serialize MCP: Could not find schema for type: ${uniqueName}`);
|
|
29
|
+
return undefined;
|
|
30
|
+
}
|
|
31
|
+
return schema;
|
|
32
|
+
};
|
|
33
|
+
for (const [name, endpointMeta] of Object.entries(resourcesMeta)) {
|
|
34
|
+
const functionMeta = functionsMeta[endpointMeta.pikkuFuncId];
|
|
35
|
+
if (!functionMeta) {
|
|
36
|
+
logger.warn(`Function ${endpointMeta.pikkuFuncId} not found in functionsMeta. Skipping resource ${name}.`);
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
const inputType = functionMeta.inputs?.[0];
|
|
40
|
+
const outputType = functionMeta.outputs?.[0];
|
|
41
|
+
const parameters = loadSchema(inputType);
|
|
42
|
+
const returns = loadSchema(outputType);
|
|
43
|
+
resources.push({
|
|
44
|
+
uri: name,
|
|
45
|
+
name,
|
|
46
|
+
description: endpointMeta.description,
|
|
47
|
+
...(parameters && { parameters }),
|
|
48
|
+
...(returns && { returns }),
|
|
49
|
+
...(endpointMeta.streaming && { streaming: true }),
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
for (const [name, endpointMeta] of Object.entries(toolsMeta)) {
|
|
53
|
+
const functionMeta = functionsMeta[endpointMeta.pikkuFuncId];
|
|
54
|
+
if (!functionMeta) {
|
|
55
|
+
logger.warn(`Function ${endpointMeta.pikkuFuncId} not found in functionsMeta. Skipping tool ${name}.`);
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
const inputType = functionMeta.inputs?.[0];
|
|
59
|
+
const outputType = functionMeta.outputs?.[0];
|
|
60
|
+
const parameters = loadSchema(inputType);
|
|
61
|
+
const returns = loadSchema(outputType);
|
|
62
|
+
tools.push({
|
|
63
|
+
name,
|
|
64
|
+
description: endpointMeta.description,
|
|
65
|
+
...(parameters && { parameters }),
|
|
66
|
+
...(returns && { returns }),
|
|
67
|
+
...(endpointMeta.streaming && { streaming: true }),
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
for (const [name, endpointMeta] of Object.entries(promptsMeta)) {
|
|
71
|
+
const functionMeta = functionsMeta[endpointMeta.pikkuFuncId];
|
|
72
|
+
if (!functionMeta) {
|
|
73
|
+
logger.warn(`Function ${endpointMeta.pikkuFuncId} not found in functionsMeta. Skipping prompt ${name}.`);
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
76
|
+
const inputType = functionMeta.inputs?.[0];
|
|
77
|
+
const inputSchema = loadSchema(inputType);
|
|
78
|
+
const argumentsArray = [];
|
|
79
|
+
if (inputSchema &&
|
|
80
|
+
typeof inputSchema === 'object' &&
|
|
81
|
+
!(inputSchema instanceof Array)) {
|
|
82
|
+
const properties = inputSchema.properties;
|
|
83
|
+
const required = inputSchema.required || [];
|
|
84
|
+
for (const [propName, propSchema] of Object.entries(properties)) {
|
|
85
|
+
argumentsArray.push({
|
|
86
|
+
name: propName,
|
|
87
|
+
description: propSchema.description || `${propName} parameter`,
|
|
88
|
+
required: required.includes(propName),
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
prompts.push({
|
|
93
|
+
name,
|
|
94
|
+
description: endpointMeta.description,
|
|
95
|
+
arguments: argumentsArray,
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
return JSON.stringify({ tools, resources, prompts }, null, 2);
|
|
99
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { InspectorState } from '../types.js';
|
|
2
|
+
export declare const serializeMiddlewareGroupsMeta: (state: InspectorState) => {
|
|
3
|
+
definitions: Record<string, import("../types.js").InspectorMiddlewareDefinition>;
|
|
4
|
+
instances: Record<string, import("../types.js").InspectorMiddlewareInstance>;
|
|
5
|
+
httpGroups: Record<string, any>;
|
|
6
|
+
tagGroups: Record<string, any>;
|
|
7
|
+
channelMiddleware: {
|
|
8
|
+
definitions: Record<string, import("../types.js").InspectorMiddlewareDefinition>;
|
|
9
|
+
instances: Record<string, import("../types.js").InspectorMiddlewareInstance>;
|
|
10
|
+
tagGroups: Record<string, any>;
|
|
11
|
+
};
|
|
12
|
+
};
|