@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.
Files changed (182) hide show
  1. package/CHANGELOG.md +11 -1
  2. package/OPTIMIZATION-PLAN.md +195 -0
  3. package/dist/add/add-ai-agent.d.ts +2 -0
  4. package/dist/add/add-ai-agent.js +314 -0
  5. package/dist/add/add-channel.js +69 -61
  6. package/dist/add/add-cli.js +36 -18
  7. package/dist/add/add-file-with-factory.js +2 -0
  8. package/dist/add/add-functions.js +250 -75
  9. package/dist/add/add-http-route.d.ts +19 -10
  10. package/dist/add/add-http-route.js +152 -66
  11. package/dist/add/add-http-routes.d.ts +5 -0
  12. package/dist/add/add-http-routes.js +159 -0
  13. package/dist/add/add-keyed-wiring.d.ts +12 -0
  14. package/dist/add/add-keyed-wiring.js +97 -0
  15. package/dist/add/add-mcp-prompt.js +14 -9
  16. package/dist/add/add-mcp-resource.js +14 -9
  17. package/dist/add/add-middleware.d.ts +1 -4
  18. package/dist/add/add-middleware.js +364 -79
  19. package/dist/add/add-permission.d.ts +1 -1
  20. package/dist/add/add-permission.js +152 -40
  21. package/dist/add/add-queue-worker.js +18 -12
  22. package/dist/add/add-rpc-invocations.js +14 -0
  23. package/dist/add/add-schedule.js +11 -5
  24. package/dist/add/add-secret.d.ts +3 -0
  25. package/dist/add/add-secret.js +82 -0
  26. package/dist/add/add-trigger.d.ts +2 -0
  27. package/dist/add/add-trigger.js +87 -0
  28. package/dist/add/add-variable.d.ts +1 -0
  29. package/dist/add/add-variable.js +8 -0
  30. package/dist/add/add-workflow-graph.d.ts +3 -2
  31. package/dist/add/add-workflow-graph.js +143 -406
  32. package/dist/add/add-workflow.js +6 -4
  33. package/dist/error-codes.d.ts +14 -1
  34. package/dist/error-codes.js +19 -1
  35. package/dist/index.d.ts +9 -8
  36. package/dist/index.js +5 -4
  37. package/dist/inspector.d.ts +1 -1
  38. package/dist/inspector.js +91 -14
  39. package/dist/schema-generator.d.ts +1 -0
  40. package/dist/schema-generator.js +1 -0
  41. package/dist/types-map.js +10 -1
  42. package/dist/types.d.ts +163 -39
  43. package/dist/utils/compute-required-schemas.d.ts +4 -0
  44. package/dist/utils/compute-required-schemas.js +41 -0
  45. package/dist/utils/contract-hashes.d.ts +35 -0
  46. package/dist/utils/contract-hashes.js +202 -0
  47. package/dist/utils/custom-types-generator.d.ts +9 -0
  48. package/dist/utils/custom-types-generator.js +71 -0
  49. package/dist/utils/detect-schema-vendor.d.ts +22 -0
  50. package/dist/utils/detect-schema-vendor.js +76 -0
  51. package/dist/utils/ensure-function-metadata.d.ts +5 -2
  52. package/dist/utils/ensure-function-metadata.js +220 -6
  53. package/dist/utils/extract-function-name.d.ts +5 -16
  54. package/dist/utils/extract-function-name.js +86 -291
  55. package/dist/utils/extract-services.d.ts +2 -1
  56. package/dist/utils/extract-services.js +25 -1
  57. package/dist/utils/filter-inspector-state.js +107 -23
  58. package/dist/utils/get-property-value.d.ts +6 -1
  59. package/dist/utils/get-property-value.js +28 -3
  60. package/dist/utils/hash.d.ts +2 -0
  61. package/dist/utils/hash.js +23 -0
  62. package/dist/utils/middleware.d.ts +7 -30
  63. package/dist/utils/middleware.js +80 -66
  64. package/dist/utils/permissions.d.ts +2 -2
  65. package/dist/utils/permissions.js +10 -10
  66. package/dist/utils/post-process.d.ts +9 -10
  67. package/dist/utils/post-process.js +231 -24
  68. package/dist/utils/resolve-external-package.d.ts +12 -0
  69. package/dist/utils/resolve-external-package.js +34 -0
  70. package/dist/utils/resolve-function-types.d.ts +6 -0
  71. package/dist/utils/resolve-function-types.js +29 -0
  72. package/dist/utils/resolve-identifier.d.ts +10 -0
  73. package/dist/utils/resolve-identifier.js +36 -0
  74. package/dist/utils/resolve-versions.d.ts +2 -0
  75. package/dist/utils/resolve-versions.js +78 -0
  76. package/dist/utils/schema-generator.d.ts +9 -0
  77. package/dist/utils/schema-generator.js +209 -0
  78. package/dist/utils/serialize-inspector-state.d.ts +59 -22
  79. package/dist/utils/serialize-inspector-state.js +92 -20
  80. package/dist/utils/serialize-mcp-json.d.ts +2 -0
  81. package/dist/utils/serialize-mcp-json.js +99 -0
  82. package/dist/utils/serialize-middleware-groups-meta.d.ts +12 -0
  83. package/dist/utils/serialize-middleware-groups-meta.js +28 -0
  84. package/dist/utils/serialize-openapi-json.d.ts +85 -0
  85. package/dist/utils/serialize-openapi-json.js +151 -0
  86. package/dist/utils/serialize-permissions-groups-meta.d.ts +6 -0
  87. package/dist/utils/serialize-permissions-groups-meta.js +31 -0
  88. package/dist/utils/workflow/dsl/deserialize-dsl-workflow.js +34 -102
  89. package/dist/utils/workflow/dsl/extract-dsl-workflow.js +23 -4
  90. package/dist/utils/workflow/graph/convert-dsl-to-graph.js +12 -10
  91. package/dist/utils/workflow/graph/finalize-workflow-wires.d.ts +3 -0
  92. package/dist/utils/workflow/graph/finalize-workflow-wires.js +276 -0
  93. package/dist/utils/workflow/graph/finalize-workflows.d.ts +2 -0
  94. package/dist/utils/workflow/graph/finalize-workflows.js +75 -0
  95. package/dist/utils/workflow/graph/index.d.ts +2 -0
  96. package/dist/utils/workflow/graph/index.js +2 -0
  97. package/dist/utils/workflow/graph/serialize-workflow-graph.d.ts +0 -8
  98. package/dist/utils/workflow/graph/serialize-workflow-graph.js +1 -3
  99. package/dist/utils/workflow/graph/workflow-graph.types.d.ts +53 -79
  100. package/dist/utils/workflow/graph/workflow-graph.types.js +1 -1
  101. package/dist/visit.js +11 -6
  102. package/package.json +14 -4
  103. package/src/add/add-ai-agent.ts +468 -0
  104. package/src/add/add-channel.ts +82 -79
  105. package/src/add/add-cli.ts +49 -20
  106. package/src/add/add-file-with-factory.ts +2 -0
  107. package/src/add/add-functions.ts +330 -86
  108. package/src/add/add-http-route.ts +245 -88
  109. package/src/add/add-http-routes.ts +228 -0
  110. package/src/add/add-keyed-wiring.ts +151 -0
  111. package/src/add/add-mcp-prompt.ts +26 -15
  112. package/src/add/add-mcp-resource.ts +27 -15
  113. package/src/add/add-middleware.ts +482 -80
  114. package/src/add/add-permission.ts +199 -40
  115. package/src/add/add-queue-worker.ts +24 -19
  116. package/src/add/add-rpc-invocations.ts +17 -0
  117. package/src/add/add-schedule.ts +16 -11
  118. package/src/add/add-secret.ts +140 -0
  119. package/src/add/add-trigger.ts +154 -0
  120. package/src/add/add-variable.ts +9 -0
  121. package/src/add/add-workflow-graph.ts +180 -522
  122. package/src/add/add-workflow.ts +5 -4
  123. package/src/error-codes.ts +24 -1
  124. package/src/index.ts +22 -13
  125. package/src/inspector.ts +129 -17
  126. package/src/schema-generator.ts +1 -0
  127. package/src/types-map.ts +12 -1
  128. package/src/types.ts +175 -58
  129. package/src/utils/compute-required-schemas.ts +49 -0
  130. package/src/utils/contract-hashes.test.ts +528 -0
  131. package/src/utils/contract-hashes.ts +290 -0
  132. package/src/utils/custom-types-generator.ts +88 -0
  133. package/src/utils/detect-schema-vendor.ts +90 -0
  134. package/src/utils/ensure-function-metadata.ts +324 -7
  135. package/src/utils/extract-function-name.ts +101 -351
  136. package/src/utils/extract-services.ts +35 -2
  137. package/src/utils/filter-inspector-state.test.ts +34 -20
  138. package/src/utils/filter-inspector-state.ts +140 -31
  139. package/src/utils/get-property-value.ts +42 -4
  140. package/src/utils/hash.ts +26 -0
  141. package/src/utils/middleware.test.ts +204 -0
  142. package/src/utils/middleware.ts +129 -67
  143. package/src/utils/permissions.test.ts +35 -12
  144. package/src/utils/permissions.ts +10 -10
  145. package/src/utils/post-process.ts +283 -43
  146. package/src/utils/resolve-external-package.ts +42 -0
  147. package/src/utils/resolve-function-types.ts +42 -0
  148. package/src/utils/resolve-identifier.ts +46 -0
  149. package/src/utils/resolve-versions.test.ts +249 -0
  150. package/src/utils/resolve-versions.ts +105 -0
  151. package/src/utils/schema-generator.ts +329 -0
  152. package/src/utils/serialize-inspector-state.ts +163 -40
  153. package/src/utils/serialize-mcp-json.ts +145 -0
  154. package/src/utils/serialize-middleware-groups-meta.ts +33 -0
  155. package/src/utils/serialize-openapi-json.ts +277 -0
  156. package/src/utils/serialize-permissions-groups-meta.ts +35 -0
  157. package/src/utils/test-data/inspector-state.json +69 -66
  158. package/src/utils/workflow/dsl/deserialize-dsl-workflow.ts +43 -119
  159. package/src/utils/workflow/dsl/extract-dsl-workflow.ts +24 -4
  160. package/src/utils/workflow/graph/convert-dsl-to-graph.ts +17 -10
  161. package/src/utils/workflow/graph/finalize-workflow-wires.ts +310 -0
  162. package/src/utils/workflow/graph/finalize-workflows.ts +100 -0
  163. package/src/utils/workflow/graph/index.ts +5 -0
  164. package/src/utils/workflow/graph/serialize-workflow-graph.ts +1 -8
  165. package/src/utils/workflow/graph/workflow-graph.types.ts +29 -78
  166. package/src/visit.ts +12 -6
  167. package/tsconfig.tsbuildinfo +1 -1
  168. package/dist/add/add-forge-credential.d.ts +0 -8
  169. package/dist/add/add-forge-credential.js +0 -77
  170. package/dist/add/add-forge-node.d.ts +0 -7
  171. package/dist/add/add-forge-node.js +0 -77
  172. package/dist/add/add-mcp-tool.d.ts +0 -2
  173. package/dist/add/add-mcp-tool.js +0 -81
  174. package/dist/utils/extract-service-metadata.d.ts +0 -19
  175. package/dist/utils/extract-service-metadata.js +0 -244
  176. package/dist/utils/write-service-metadata.d.ts +0 -13
  177. package/dist/utils/write-service-metadata.js +0 -37
  178. package/src/add/add-forge-credential.ts +0 -119
  179. package/src/add/add-forge-node.ts +0 -132
  180. package/src/add/add-mcp-tool.ts +0 -141
  181. package/src/utils/extract-service-metadata.ts +0 -353
  182. 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 { InspectorState } from '../types.js';
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
- zodLookup: Array<[string, {
78
- variableName: string;
79
- sourceFile: string;
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
- forgeNodes: {
167
- meta: InspectorState['forgeNodes']['meta'];
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
- forgeCredentials: {
171
- meta: InspectorState['forgeCredentials']['meta'];
193
+ variables: {
194
+ definitions: InspectorState['variables']['definitions'];
172
195
  files: string[];
173
196
  };
197
+ manifest: InspectorState['manifest'];
174
198
  middleware: {
175
- meta: InspectorState['middleware']['meta'];
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
- meta: InspectorState['permissions']['meta'];
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
- serviceMetadata: Array<{
197
- name: string;
198
- summary: string;
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' | 'zodLookup'> & {
217
- zodLookup: Map<string, {
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
- zodLookup: Array.from(state.zodLookup.entries()),
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
- forgeNodes: {
79
- meta: state.forgeNodes.meta,
80
- files: Array.from(state.forgeNodes.files),
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
- forgeCredentials: {
83
- meta: state.forgeCredentials.meta,
84
- files: Array.from(state.forgeCredentials.files),
97
+ variables: {
98
+ definitions: state.variables.definitions,
99
+ files: Array.from(state.variables.files),
85
100
  },
101
+ manifest: state.manifest,
86
102
  middleware: {
87
- meta: state.middleware.meta,
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
- meta: state.permissions.meta,
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
- serviceMetadata: state.serviceMetadata,
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
- zodLookup: new Map(data.zodLookup || []),
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
- forgeNodes: {
183
- meta: data.forgeNodes?.meta || {},
184
- files: new Set(data.forgeNodes?.files || []),
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
- forgeCredentials: {
187
- meta: data.forgeCredentials?.meta || {},
188
- files: new Set(data.forgeCredentials?.files || []),
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
- meta: data.middleware.meta,
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
- meta: data.permissions.meta,
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
- serviceMetadata: data.serviceMetadata || [],
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,2 @@
1
+ import type { InspectorLogger, InspectorState } from '../types.js';
2
+ export declare const serializeMCPJson: (logger: InspectorLogger, state: InspectorState) => string;
@@ -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
+ };