@pikku/inspector 0.11.1 → 0.11.2
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 +16 -1
- package/dist/add/add-forge-credential.d.ts +8 -0
- package/dist/add/add-forge-credential.js +77 -0
- package/dist/add/add-forge-node.d.ts +7 -0
- package/dist/add/add-forge-node.js +77 -0
- package/dist/add/add-functions.js +102 -9
- package/dist/add/add-http-route.js +24 -1
- package/dist/add/add-rpc-invocations.d.ts +3 -0
- package/dist/add/add-rpc-invocations.js +51 -25
- package/dist/add/add-workflow-graph.d.ts +6 -0
- package/dist/add/add-workflow-graph.js +659 -0
- package/dist/add/add-workflow.js +118 -22
- package/dist/error-codes.d.ts +3 -1
- package/dist/error-codes.js +3 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.js +2 -0
- package/dist/inspector.js +19 -3
- package/dist/types.d.ts +26 -0
- package/dist/utils/extract-function-name.js +7 -7
- package/dist/utils/get-property-value.d.ts +2 -1
- package/dist/utils/get-property-value.js +6 -2
- package/dist/utils/serialize-inspector-state.d.ts +24 -1
- package/dist/utils/serialize-inspector-state.js +24 -0
- package/dist/utils/workflow/dsl/deserialize-dsl-workflow.d.ts +24 -0
- package/dist/utils/workflow/dsl/deserialize-dsl-workflow.js +898 -0
- package/dist/{workflow/extract-simple-workflow.d.ts → utils/workflow/dsl/extract-dsl-workflow.d.ts} +4 -2
- package/dist/{workflow/extract-simple-workflow.js → utils/workflow/dsl/extract-dsl-workflow.js} +549 -68
- package/dist/utils/workflow/dsl/index.d.ts +7 -0
- package/dist/utils/workflow/dsl/index.js +7 -0
- package/dist/{workflow → utils/workflow/dsl}/patterns.d.ts +21 -0
- package/dist/{workflow → utils/workflow/dsl}/patterns.js +90 -10
- package/dist/{workflow → utils/workflow/dsl}/validation.d.ts +2 -0
- package/dist/{workflow → utils/workflow/dsl}/validation.js +25 -7
- package/dist/utils/workflow/graph/convert-dsl-to-graph.d.ts +13 -0
- package/dist/utils/workflow/graph/convert-dsl-to-graph.js +316 -0
- package/dist/utils/workflow/graph/index.d.ts +6 -0
- package/dist/utils/workflow/graph/index.js +6 -0
- package/dist/utils/workflow/graph/serialize-workflow-graph.d.ts +43 -0
- package/dist/utils/workflow/graph/serialize-workflow-graph.js +152 -0
- package/dist/utils/workflow/graph/workflow-graph.types.d.ts +229 -0
- package/dist/utils/workflow/graph/workflow-graph.types.js +38 -0
- package/dist/visit.js +6 -0
- package/package.json +14 -2
- package/src/add/add-forge-credential.ts +119 -0
- package/src/add/add-forge-node.ts +132 -0
- package/src/add/add-functions.ts +129 -15
- package/src/add/add-http-route.ts +25 -1
- package/src/add/add-rpc-invocations.ts +61 -31
- package/src/add/add-workflow-graph.ts +864 -0
- package/src/add/add-workflow.ts +112 -26
- package/src/error-codes.ts +3 -1
- package/src/index.ts +10 -0
- package/src/inspector.ts +20 -4
- package/src/types.ts +25 -1
- package/src/utils/extract-function-name.ts +7 -7
- package/src/utils/get-property-value.ts +9 -2
- package/src/utils/serialize-inspector-state.ts +39 -1
- package/src/utils/workflow/dsl/deserialize-dsl-workflow.ts +1180 -0
- package/src/{workflow/extract-simple-workflow.ts → utils/workflow/dsl/extract-dsl-workflow.ts} +654 -81
- package/src/utils/workflow/dsl/index.ts +11 -0
- package/src/{workflow → utils/workflow/dsl}/patterns.ts +108 -11
- package/src/{workflow → utils/workflow/dsl}/validation.ts +34 -7
- package/src/utils/workflow/graph/convert-dsl-to-graph.ts +415 -0
- package/src/utils/workflow/graph/index.ts +6 -0
- package/src/utils/workflow/graph/serialize-workflow-graph.ts +223 -0
- package/src/utils/workflow/graph/workflow-graph.types.ts +280 -0
- package/src/visit.ts +6 -0
- package/tsconfig.tsbuildinfo +1 -1
package/src/add/add-workflow.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { AddWiring, InspectorState } from '../types.js'
|
|
|
3
3
|
import { extractFunctionName } from '../utils/extract-function-name.js'
|
|
4
4
|
import { extractFunctionNode } from '../utils/extract-function-node.js'
|
|
5
5
|
import { ErrorCode } from '../error-codes.js'
|
|
6
|
-
import { WorkflowStepMeta } from '@pikku/core/workflow'
|
|
6
|
+
import { WorkflowStepMeta, WorkflowContext } from '@pikku/core/workflow'
|
|
7
7
|
import {
|
|
8
8
|
extractStringLiteral,
|
|
9
9
|
isStringLike,
|
|
@@ -11,8 +11,62 @@ import {
|
|
|
11
11
|
extractDescription,
|
|
12
12
|
extractDuration,
|
|
13
13
|
} from '../utils/extract-node-value.js'
|
|
14
|
-
import { extractSimpleWorkflow } from '../workflow/extract-simple-workflow.js'
|
|
15
14
|
import { getCommonWireMetaData } from '../utils/get-property-value.js'
|
|
15
|
+
import { extractDSLWorkflow } from '../utils/workflow/dsl/extract-dsl-workflow.js'
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Recursively check if any step has inline type (non-serializable)
|
|
19
|
+
*/
|
|
20
|
+
function hasInlineSteps(steps: WorkflowStepMeta[]): boolean {
|
|
21
|
+
for (const step of steps) {
|
|
22
|
+
if (step.type === 'inline') {
|
|
23
|
+
return true
|
|
24
|
+
} else if (step.type === 'branch') {
|
|
25
|
+
for (const branch of step.branches) {
|
|
26
|
+
if (hasInlineSteps(branch.steps)) return true
|
|
27
|
+
}
|
|
28
|
+
if (step.elseSteps && hasInlineSteps(step.elseSteps)) return true
|
|
29
|
+
} else if (step.type === 'switch' && step.cases) {
|
|
30
|
+
for (const c of step.cases) {
|
|
31
|
+
if (c.steps && hasInlineSteps(c.steps)) return true
|
|
32
|
+
}
|
|
33
|
+
if (step.defaultSteps && hasInlineSteps(step.defaultSteps)) return true
|
|
34
|
+
} else if (step.type === 'fanout' && step.child) {
|
|
35
|
+
if (hasInlineSteps([step.child])) return true
|
|
36
|
+
} else if (step.type === 'parallel' && step.children) {
|
|
37
|
+
if (hasInlineSteps(step.children)) return true
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return false
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Recursively collect all RPC names from workflow steps
|
|
45
|
+
*/
|
|
46
|
+
function collectInvokedRPCs(
|
|
47
|
+
steps: WorkflowStepMeta[],
|
|
48
|
+
rpcs: Set<string>
|
|
49
|
+
): void {
|
|
50
|
+
for (const step of steps) {
|
|
51
|
+
if (step.type === 'rpc' && step.rpcName) {
|
|
52
|
+
rpcs.add(step.rpcName)
|
|
53
|
+
} else if (step.type === 'branch') {
|
|
54
|
+
for (const branch of step.branches) {
|
|
55
|
+
collectInvokedRPCs(branch.steps, rpcs)
|
|
56
|
+
}
|
|
57
|
+
if (step.elseSteps) collectInvokedRPCs(step.elseSteps, rpcs)
|
|
58
|
+
} else if (step.type === 'switch' && step.cases) {
|
|
59
|
+
for (const c of step.cases) {
|
|
60
|
+
if (c.steps) collectInvokedRPCs(c.steps, rpcs)
|
|
61
|
+
}
|
|
62
|
+
if (step.defaultSteps) collectInvokedRPCs(step.defaultSteps, rpcs)
|
|
63
|
+
} else if (step.type === 'fanout' && step.child) {
|
|
64
|
+
collectInvokedRPCs([step.child], rpcs)
|
|
65
|
+
} else if (step.type === 'parallel' && step.children) {
|
|
66
|
+
collectInvokedRPCs(step.children, rpcs)
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
16
70
|
|
|
17
71
|
/**
|
|
18
72
|
* Scan for workflow.do(), workflow.sleep(), and workflow.cancel() calls to extract workflow steps
|
|
@@ -87,13 +141,10 @@ function getWorkflowInvocations(
|
|
|
87
141
|
}
|
|
88
142
|
}
|
|
89
143
|
|
|
90
|
-
//
|
|
144
|
+
// Recurse into children, including arrow functions (for Promise.all callbacks)
|
|
145
|
+
// but skip function declarations (which would be separate functions)
|
|
91
146
|
ts.forEachChild(node, (child) => {
|
|
92
|
-
if (
|
|
93
|
-
ts.isFunctionDeclaration(child) ||
|
|
94
|
-
ts.isFunctionExpression(child) ||
|
|
95
|
-
ts.isArrowFunction(child)
|
|
96
|
-
) {
|
|
147
|
+
if (ts.isFunctionDeclaration(child)) {
|
|
97
148
|
return
|
|
98
149
|
}
|
|
99
150
|
getWorkflowInvocations(child, checker, state, workflowName, steps)
|
|
@@ -117,11 +168,11 @@ export const addWorkflow: AddWiring = (logger, node, checker, state) => {
|
|
|
117
168
|
return
|
|
118
169
|
}
|
|
119
170
|
|
|
120
|
-
let wrapperType: '
|
|
171
|
+
let wrapperType: 'dsl' | 'regular' | null = null
|
|
121
172
|
if (expression.text === 'pikkuWorkflowFunc') {
|
|
173
|
+
wrapperType = 'dsl'
|
|
174
|
+
} else if (expression.text === 'pikkuWorkflowComplexFunc') {
|
|
122
175
|
wrapperType = 'regular'
|
|
123
|
-
} else if (expression.text === 'pikkuSimpleWorkflowFunc') {
|
|
124
|
-
wrapperType = 'simple'
|
|
125
176
|
} else {
|
|
126
177
|
return
|
|
127
178
|
}
|
|
@@ -198,41 +249,76 @@ export const addWorkflow: AddWiring = (logger, node, checker, state) => {
|
|
|
198
249
|
}
|
|
199
250
|
|
|
200
251
|
let steps: WorkflowStepMeta[] = []
|
|
201
|
-
let
|
|
252
|
+
let context: WorkflowContext | undefined = undefined
|
|
253
|
+
let dsl: boolean | undefined = undefined
|
|
202
254
|
|
|
203
|
-
// Try
|
|
255
|
+
// Try DSL workflow extraction first
|
|
204
256
|
// Pass the whole CallExpression node so findWorkflowFunction can find the arrow function
|
|
205
|
-
const result =
|
|
257
|
+
const result = extractDSLWorkflow(node, checker)
|
|
206
258
|
|
|
207
259
|
if (result.status === 'ok' && result.steps) {
|
|
208
|
-
//
|
|
260
|
+
// Extraction succeeded
|
|
209
261
|
steps = result.steps
|
|
210
|
-
|
|
262
|
+
context = result.context
|
|
263
|
+
|
|
264
|
+
// Check if workflow contains inline steps (non-serializable)
|
|
265
|
+
if (hasInlineSteps(steps)) {
|
|
266
|
+
if (wrapperType === 'dsl') {
|
|
267
|
+
// pikkuWorkflowFunc should not have inline steps
|
|
268
|
+
logger.critical(
|
|
269
|
+
ErrorCode.INVALID_DSL_WORKFLOW,
|
|
270
|
+
`Workflow '${workflowName}' uses pikkuWorkflowFunc but contains inline steps which are not allowed in DSL workflows. Use pikkuWorkflowComplexFunc instead.`
|
|
271
|
+
)
|
|
272
|
+
return
|
|
273
|
+
}
|
|
274
|
+
// pikkuWorkflowComplexFunc with inline steps is marked as non-dsl
|
|
275
|
+
dsl = false
|
|
276
|
+
} else {
|
|
277
|
+
// pikkuWorkflowComplexFunc is always non-dsl, pikkuWorkflowFunc is dsl
|
|
278
|
+
dsl = wrapperType === 'dsl'
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
// Collect all invoked RPCs from workflow steps
|
|
282
|
+
const rpcs = new Set<string>()
|
|
283
|
+
collectInvokedRPCs(steps, rpcs)
|
|
284
|
+
for (const rpc of rpcs) {
|
|
285
|
+
state.rpc.invokedFunctions.add(rpc)
|
|
286
|
+
}
|
|
211
287
|
} else {
|
|
212
|
-
//
|
|
213
|
-
if (wrapperType === '
|
|
214
|
-
// For
|
|
288
|
+
// DSL extraction failed
|
|
289
|
+
if (wrapperType === 'dsl') {
|
|
290
|
+
// For pikkuWorkflowFunc, this is a critical error
|
|
291
|
+
// But still track RPC invocations for function registration
|
|
292
|
+
getWorkflowInvocations(resolvedFunc, checker, state, workflowName, steps)
|
|
215
293
|
logger.critical(
|
|
216
|
-
ErrorCode.
|
|
217
|
-
`Workflow '${workflowName}' uses
|
|
294
|
+
ErrorCode.INVALID_DSL_WORKFLOW,
|
|
295
|
+
`Workflow '${workflowName}' uses pikkuWorkflowFunc but does not conform to DSL workflow rules:\n${result.reason || 'Unknown error'}`
|
|
218
296
|
)
|
|
219
297
|
return
|
|
220
298
|
} else {
|
|
221
|
-
// For
|
|
299
|
+
// For pikkuWorkflowComplexFunc, fall back to basic extraction
|
|
222
300
|
logger.debug(
|
|
223
|
-
`Workflow '${workflowName}' could not be extracted as
|
|
301
|
+
`Workflow '${workflowName}' could not be extracted as DSL workflow: ${result.reason || 'Unknown error'}. Falling back to basic extraction.`
|
|
224
302
|
)
|
|
225
|
-
|
|
303
|
+
dsl = false
|
|
226
304
|
}
|
|
227
305
|
}
|
|
228
306
|
|
|
229
|
-
|
|
307
|
+
/**
|
|
308
|
+
* For non-dsl workflows or pikkuWorkflowComplexFunc, run basic extraction
|
|
309
|
+
* to ensure all RPC invocations are tracked for function registration.
|
|
310
|
+
* This catches RPCs in Promise.all callbacks and other patterns DSL can't extract.
|
|
311
|
+
*/
|
|
312
|
+
if (!dsl || wrapperType === 'regular') {
|
|
313
|
+
getWorkflowInvocations(resolvedFunc, checker, state, workflowName, steps)
|
|
314
|
+
}
|
|
230
315
|
|
|
231
316
|
state.workflows.meta[workflowName] = {
|
|
232
317
|
pikkuFuncName,
|
|
233
318
|
workflowName,
|
|
234
319
|
steps,
|
|
235
|
-
|
|
320
|
+
context,
|
|
321
|
+
dsl,
|
|
236
322
|
summary,
|
|
237
323
|
description,
|
|
238
324
|
errors,
|
package/src/error-codes.ts
CHANGED
|
@@ -11,6 +11,7 @@ export enum ErrorCode {
|
|
|
11
11
|
// Validation errors
|
|
12
12
|
MISSING_NAME = 'PKU111',
|
|
13
13
|
MISSING_DESCRIPTION = 'PKU123',
|
|
14
|
+
INVALID_VALUE = 'PKU124',
|
|
14
15
|
MISSING_URI = 'PKU220',
|
|
15
16
|
MISSING_FUNC = 'PKU236',
|
|
16
17
|
INVALID_TAGS_TYPE = 'PKU247',
|
|
@@ -21,7 +22,7 @@ export enum ErrorCode {
|
|
|
21
22
|
CLI_CLIENTSIDE_RENDERER_HAS_SERVICES = 'PKU672',
|
|
22
23
|
DYNAMIC_STEP_NAME = 'PKU529',
|
|
23
24
|
WORKFLOW_ORCHESTRATOR_NOT_CONFIGURED = 'PKU600',
|
|
24
|
-
|
|
25
|
+
INVALID_DSL_WORKFLOW = 'PKU641',
|
|
25
26
|
|
|
26
27
|
// Configuration errors
|
|
27
28
|
CONFIG_TYPE_NOT_FOUND = 'PKU426',
|
|
@@ -29,6 +30,7 @@ export enum ErrorCode {
|
|
|
29
30
|
SCHEMA_NO_ROOT = 'PKU431',
|
|
30
31
|
SCHEMA_GENERATION_ERROR = 'PKU456',
|
|
31
32
|
SCHEMA_LOAD_ERROR = 'PKU488',
|
|
33
|
+
INLINE_ZOD_SCHEMA = 'PKU489',
|
|
32
34
|
|
|
33
35
|
// Function errors
|
|
34
36
|
FUNCTION_METADATA_NOT_FOUND = 'PKU559',
|
package/src/index.ts
CHANGED
|
@@ -16,3 +16,13 @@ export type { SerializableInspectorState } from './utils/serialize-inspector-sta
|
|
|
16
16
|
export { filterInspectorState } from './utils/filter-inspector-state.js'
|
|
17
17
|
export { writeAllServiceMetadata } from './utils/write-service-metadata.js'
|
|
18
18
|
export type { ServiceMetadata } from './utils/extract-service-metadata.js'
|
|
19
|
+
export {
|
|
20
|
+
convertAllDslToGraphs,
|
|
21
|
+
convertDslToGraph,
|
|
22
|
+
} from './utils/workflow/graph/convert-dsl-to-graph.js'
|
|
23
|
+
export {
|
|
24
|
+
deserializeDslWorkflow,
|
|
25
|
+
deserializeGraphWorkflow,
|
|
26
|
+
deserializeAllDslWorkflows,
|
|
27
|
+
} from './utils/workflow/dsl/deserialize-dsl-workflow.js'
|
|
28
|
+
export type { SerializedWorkflowGraph } from './utils/workflow/graph/workflow-graph.types.js'
|
package/src/inspector.ts
CHANGED
|
@@ -29,6 +29,7 @@ export function getInitialInspectorState(rootDir: string): InspectorState {
|
|
|
29
29
|
filesAndMethods: {},
|
|
30
30
|
filesAndMethodsErrors: new Map(),
|
|
31
31
|
typesLookup: new Map(),
|
|
32
|
+
zodLookup: new Map(),
|
|
32
33
|
functions: {
|
|
33
34
|
typesMap: new TypesMap(),
|
|
34
35
|
meta: {},
|
|
@@ -64,6 +65,8 @@ export function getInitialInspectorState(rootDir: string): InspectorState {
|
|
|
64
65
|
workflows: {
|
|
65
66
|
meta: {},
|
|
66
67
|
files: new Map(),
|
|
68
|
+
graphMeta: {},
|
|
69
|
+
graphFiles: new Map(),
|
|
67
70
|
},
|
|
68
71
|
rpc: {
|
|
69
72
|
internalMeta: {},
|
|
@@ -71,6 +74,7 @@ export function getInitialInspectorState(rootDir: string): InspectorState {
|
|
|
71
74
|
exposedMeta: {},
|
|
72
75
|
exposedFiles: new Map(),
|
|
73
76
|
invokedFunctions: new Set(),
|
|
77
|
+
usedExternalPackages: new Set(),
|
|
74
78
|
},
|
|
75
79
|
mcpEndpoints: {
|
|
76
80
|
resourcesMeta: {},
|
|
@@ -85,6 +89,14 @@ export function getInitialInspectorState(rootDir: string): InspectorState {
|
|
|
85
89
|
},
|
|
86
90
|
files: new Set(),
|
|
87
91
|
},
|
|
92
|
+
forgeNodes: {
|
|
93
|
+
meta: {},
|
|
94
|
+
files: new Set(),
|
|
95
|
+
},
|
|
96
|
+
forgeCredentials: {
|
|
97
|
+
meta: {},
|
|
98
|
+
files: new Set(),
|
|
99
|
+
},
|
|
88
100
|
middleware: {
|
|
89
101
|
meta: {},
|
|
90
102
|
tagMiddleware: new Map(),
|
|
@@ -131,15 +143,19 @@ export const inspect = (
|
|
|
131
143
|
`Got type checker in ${(performance.now() - startChecker).toFixed(2)}ms`
|
|
132
144
|
)
|
|
133
145
|
|
|
146
|
+
// Use provided rootDir or infer from source files
|
|
147
|
+
const rootDir = options.rootDir || findCommonAncestor(routeFiles)
|
|
148
|
+
|
|
134
149
|
const startSourceFiles = performance.now()
|
|
135
|
-
|
|
150
|
+
// Filter source files to only include files within the project rootDir
|
|
151
|
+
// This prevents picking up types from external packages (including workspace symlinks)
|
|
152
|
+
const sourceFiles = program
|
|
153
|
+
.getSourceFiles()
|
|
154
|
+
.filter((sf) => sf.fileName.startsWith(rootDir))
|
|
136
155
|
logger.debug(
|
|
137
156
|
`Got source files in ${(performance.now() - startSourceFiles).toFixed(2)}ms`
|
|
138
157
|
)
|
|
139
158
|
|
|
140
|
-
// Infer root directory from source files
|
|
141
|
-
const rootDir = findCommonAncestor(routeFiles)
|
|
142
|
-
|
|
143
159
|
const state = getInitialInspectorState(rootDir)
|
|
144
160
|
|
|
145
161
|
// First sweep: add all functions
|
package/src/types.ts
CHANGED
|
@@ -6,9 +6,11 @@ import { QueueWorkersMeta } from '@pikku/core/queue'
|
|
|
6
6
|
import { WorkflowsMeta } from '@pikku/core/workflow'
|
|
7
7
|
import { MCPResourceMeta, MCPToolMeta, MCPPromptMeta } from '@pikku/core/mcp'
|
|
8
8
|
import { CLIMeta } from '@pikku/core/cli'
|
|
9
|
+
import { ForgeNodesMeta, ForgeCredentialsMeta } from '@pikku/core/forge-node'
|
|
9
10
|
import { TypesMap } from './types-map.js'
|
|
10
11
|
import { FunctionsMeta, FunctionServicesMeta } from '@pikku/core'
|
|
11
12
|
import { ErrorCode } from './error-codes.js'
|
|
13
|
+
import type { SerializedWorkflowGraphs } from './utils/workflow/graph/workflow-graph.types.js'
|
|
12
14
|
|
|
13
15
|
export type PathToNameAndType = Map<
|
|
14
16
|
string,
|
|
@@ -56,6 +58,14 @@ export interface InspectorHTTPState {
|
|
|
56
58
|
routePermissions: Map<string, PermissionGroupMeta>
|
|
57
59
|
}
|
|
58
60
|
|
|
61
|
+
/**
|
|
62
|
+
* Zod schema reference for deferred conversion to JSON Schema at build time
|
|
63
|
+
*/
|
|
64
|
+
export interface ZodSchemaRef {
|
|
65
|
+
variableName: string
|
|
66
|
+
sourceFile: string
|
|
67
|
+
}
|
|
68
|
+
|
|
59
69
|
export interface InspectorFunctionState {
|
|
60
70
|
typesMap: TypesMap
|
|
61
71
|
meta: FunctionsMeta
|
|
@@ -116,6 +126,8 @@ export type InspectorFilters = {
|
|
|
116
126
|
|
|
117
127
|
export type InspectorOptions = Partial<{
|
|
118
128
|
setupOnly: boolean
|
|
129
|
+
/** Project root directory - used to filter out external package files */
|
|
130
|
+
rootDir: string
|
|
119
131
|
types: Partial<{
|
|
120
132
|
configFileType: string
|
|
121
133
|
userSessionType: string
|
|
@@ -198,6 +210,7 @@ export interface InspectorState {
|
|
|
198
210
|
filesAndMethods: InspectorFilesAndMethods
|
|
199
211
|
filesAndMethodsErrors: Map<string, PathToNameAndType>
|
|
200
212
|
typesLookup: Map<string, ts.Type[]> // Lookup for types by name (e.g., function input types, Config type)
|
|
213
|
+
zodLookup: Map<string, ZodSchemaRef> // Lookup for Zod schemas by name for deferred JSON Schema conversion
|
|
201
214
|
http: InspectorHTTPState
|
|
202
215
|
functions: InspectorFunctionState
|
|
203
216
|
channels: InspectorChannelState
|
|
@@ -212,13 +225,16 @@ export interface InspectorState {
|
|
|
212
225
|
workflows: {
|
|
213
226
|
meta: WorkflowsMeta
|
|
214
227
|
files: Map<string, { path: string; exportedName: string }>
|
|
228
|
+
graphMeta: SerializedWorkflowGraphs
|
|
229
|
+
graphFiles: Map<string, { path: string; exportedName: string }>
|
|
215
230
|
}
|
|
216
231
|
rpc: {
|
|
217
232
|
internalMeta: Record<string, string>
|
|
218
233
|
internalFiles: Map<string, { path: string; exportedName: string }>
|
|
219
234
|
exposedMeta: Record<string, string>
|
|
220
235
|
exposedFiles: Map<string, { path: string; exportedName: string }>
|
|
221
|
-
invokedFunctions: Set<string>
|
|
236
|
+
invokedFunctions: Set<string>
|
|
237
|
+
usedExternalPackages: Set<string>
|
|
222
238
|
}
|
|
223
239
|
mcpEndpoints: {
|
|
224
240
|
resourcesMeta: MCPResourceMeta
|
|
@@ -230,6 +246,14 @@ export interface InspectorState {
|
|
|
230
246
|
meta: CLIMeta
|
|
231
247
|
files: Set<string>
|
|
232
248
|
}
|
|
249
|
+
forgeNodes: {
|
|
250
|
+
meta: ForgeNodesMeta
|
|
251
|
+
files: Set<string>
|
|
252
|
+
}
|
|
253
|
+
forgeCredentials: {
|
|
254
|
+
meta: ForgeCredentialsMeta
|
|
255
|
+
files: Set<string>
|
|
256
|
+
}
|
|
233
257
|
middleware: InspectorMiddlewareState
|
|
234
258
|
permissions: InspectorPermissionState
|
|
235
259
|
serviceAggregation: {
|
|
@@ -360,10 +360,10 @@ export function extractFunctionName(
|
|
|
360
360
|
if (
|
|
361
361
|
ts.isPropertyAssignment(prop) &&
|
|
362
362
|
ts.isIdentifier(prop.name) &&
|
|
363
|
-
prop.name.text === '
|
|
363
|
+
prop.name.text === 'override' &&
|
|
364
364
|
ts.isStringLiteral(prop.initializer)
|
|
365
365
|
) {
|
|
366
|
-
// Priority 1: Object with
|
|
366
|
+
// Priority 1: Object with override property
|
|
367
367
|
result.explicitName = prop.initializer.text
|
|
368
368
|
break
|
|
369
369
|
}
|
|
@@ -614,17 +614,17 @@ export function extractFunctionName(
|
|
|
614
614
|
// instead of the variable declaration position
|
|
615
615
|
originalCallExpr = decl.initializer
|
|
616
616
|
|
|
617
|
-
// Check for object with '
|
|
617
|
+
// Check for object with 'override' property in first argument
|
|
618
618
|
const firstArg = decl.initializer.arguments[0]
|
|
619
619
|
if (firstArg && ts.isObjectLiteralExpression(firstArg)) {
|
|
620
620
|
for (const prop of firstArg.properties) {
|
|
621
621
|
if (
|
|
622
622
|
ts.isPropertyAssignment(prop) &&
|
|
623
623
|
ts.isIdentifier(prop.name) &&
|
|
624
|
-
prop.name.text === '
|
|
624
|
+
prop.name.text === 'override' &&
|
|
625
625
|
ts.isStringLiteral(prop.initializer)
|
|
626
626
|
) {
|
|
627
|
-
// Priority 1: Object with
|
|
627
|
+
// Priority 1: Object with override property
|
|
628
628
|
result.explicitName = prop.initializer.text
|
|
629
629
|
break
|
|
630
630
|
}
|
|
@@ -713,7 +713,7 @@ export function extractFunctionName(
|
|
|
713
713
|
) {
|
|
714
714
|
result.propertyName = parent.name.text
|
|
715
715
|
}
|
|
716
|
-
// 3) Handle any remaining cases for pikkuFunc({
|
|
716
|
+
// 3) Handle any remaining cases for pikkuFunc({ override: '…', func: … })
|
|
717
717
|
else if (ts.isCallExpression(originalCallExpr)) {
|
|
718
718
|
const firstArg = originalCallExpr.arguments[0]
|
|
719
719
|
if (firstArg && ts.isObjectLiteralExpression(firstArg)) {
|
|
@@ -721,7 +721,7 @@ export function extractFunctionName(
|
|
|
721
721
|
if (
|
|
722
722
|
ts.isPropertyAssignment(prop) &&
|
|
723
723
|
ts.isIdentifier(prop.name) &&
|
|
724
|
-
prop.name.text === '
|
|
724
|
+
prop.name.text === 'override' &&
|
|
725
725
|
ts.isStringLiteral(prop.initializer) &&
|
|
726
726
|
!result.explicitName // Only set if not already set
|
|
727
727
|
) {
|
|
@@ -57,7 +57,7 @@ export const getPropertyValue = (
|
|
|
57
57
|
}
|
|
58
58
|
|
|
59
59
|
/**
|
|
60
|
-
* Extracts common wire metadata (tags, summary, description, errors) directly from an object
|
|
60
|
+
* Extracts common wire metadata (title, tags, summary, description, errors) directly from an object
|
|
61
61
|
* @param obj - The TypeScript object literal expression to extract metadata from
|
|
62
62
|
* @param wiringType - The type of wiring (e.g., 'HTTP route', 'Channel', 'Queue worker')
|
|
63
63
|
* @param wiringName - The name/identifier of the wiring (e.g., route path, channel name)
|
|
@@ -70,12 +70,14 @@ export const getCommonWireMetaData = (
|
|
|
70
70
|
wiringName: string | null,
|
|
71
71
|
logger?: { critical: (code: ErrorCode, message: string) => void }
|
|
72
72
|
): {
|
|
73
|
+
title?: string
|
|
73
74
|
tags?: string[]
|
|
74
75
|
summary?: string
|
|
75
76
|
description?: string
|
|
76
77
|
errors?: string[]
|
|
77
78
|
} => {
|
|
78
79
|
const metadata: {
|
|
80
|
+
title?: string
|
|
79
81
|
tags?: string[]
|
|
80
82
|
summary?: string
|
|
81
83
|
description?: string
|
|
@@ -86,7 +88,12 @@ export const getCommonWireMetaData = (
|
|
|
86
88
|
if (ts.isPropertyAssignment(prop) && ts.isIdentifier(prop.name)) {
|
|
87
89
|
const propName = prop.name.text
|
|
88
90
|
|
|
89
|
-
if (propName === '
|
|
91
|
+
if (propName === 'title' && ts.isStringLiteral(prop.initializer)) {
|
|
92
|
+
metadata.title = prop.initializer.text
|
|
93
|
+
} else if (
|
|
94
|
+
propName === 'summary' &&
|
|
95
|
+
ts.isStringLiteral(prop.initializer)
|
|
96
|
+
) {
|
|
90
97
|
metadata.summary = prop.initializer.text
|
|
91
98
|
} else if (
|
|
92
99
|
propName === 'description' &&
|
|
@@ -62,6 +62,7 @@ export interface SerializableInspectorState {
|
|
|
62
62
|
>,
|
|
63
63
|
]
|
|
64
64
|
>
|
|
65
|
+
zodLookup: Array<[string, { variableName: string; sourceFile: string }]>
|
|
65
66
|
functions: {
|
|
66
67
|
typesMap: {
|
|
67
68
|
map: Array<[string, { originalName: string; path: string | null }]>
|
|
@@ -115,6 +116,8 @@ export interface SerializableInspectorState {
|
|
|
115
116
|
workflows: {
|
|
116
117
|
meta: InspectorState['workflows']['meta']
|
|
117
118
|
files: Array<[string, { path: string; exportedName: string }]>
|
|
119
|
+
graphMeta: InspectorState['workflows']['graphMeta']
|
|
120
|
+
graphFiles: Array<[string, { path: string; exportedName: string }]>
|
|
118
121
|
}
|
|
119
122
|
rpc: {
|
|
120
123
|
internalMeta: InspectorState['rpc']['internalMeta']
|
|
@@ -122,6 +125,7 @@ export interface SerializableInspectorState {
|
|
|
122
125
|
exposedMeta: InspectorState['rpc']['exposedMeta']
|
|
123
126
|
exposedFiles: Array<[string, { path: string; exportedName: string }]>
|
|
124
127
|
invokedFunctions: string[]
|
|
128
|
+
usedExternalPackages: string[]
|
|
125
129
|
}
|
|
126
130
|
mcpEndpoints: {
|
|
127
131
|
resourcesMeta: InspectorState['mcpEndpoints']['resourcesMeta']
|
|
@@ -133,6 +137,14 @@ export interface SerializableInspectorState {
|
|
|
133
137
|
meta: InspectorState['cli']['meta']
|
|
134
138
|
files: string[]
|
|
135
139
|
}
|
|
140
|
+
forgeNodes: {
|
|
141
|
+
meta: InspectorState['forgeNodes']['meta']
|
|
142
|
+
files: string[]
|
|
143
|
+
}
|
|
144
|
+
forgeCredentials: {
|
|
145
|
+
meta: InspectorState['forgeCredentials']['meta']
|
|
146
|
+
files: string[]
|
|
147
|
+
}
|
|
136
148
|
middleware: {
|
|
137
149
|
meta: InspectorState['middleware']['meta']
|
|
138
150
|
tagMiddleware: Array<
|
|
@@ -231,6 +243,7 @@ export function serializeInspectorState(
|
|
|
231
243
|
filesAndMethodsErrors: Array.from(
|
|
232
244
|
state.filesAndMethodsErrors.entries()
|
|
233
245
|
).map(([key, mapValue]) => [key, Array.from(mapValue.entries())] as const),
|
|
246
|
+
zodLookup: Array.from(state.zodLookup.entries()),
|
|
234
247
|
functions: {
|
|
235
248
|
typesMap: serializeTypesMap(state.functions.typesMap),
|
|
236
249
|
meta: state.functions.meta,
|
|
@@ -258,6 +271,8 @@ export function serializeInspectorState(
|
|
|
258
271
|
workflows: {
|
|
259
272
|
meta: state.workflows.meta,
|
|
260
273
|
files: Array.from(state.workflows.files.entries()),
|
|
274
|
+
graphMeta: state.workflows.graphMeta,
|
|
275
|
+
graphFiles: Array.from(state.workflows.graphFiles.entries()),
|
|
261
276
|
},
|
|
262
277
|
rpc: {
|
|
263
278
|
internalMeta: state.rpc.internalMeta,
|
|
@@ -265,6 +280,7 @@ export function serializeInspectorState(
|
|
|
265
280
|
exposedMeta: state.rpc.exposedMeta,
|
|
266
281
|
exposedFiles: Array.from(state.rpc.exposedFiles.entries()),
|
|
267
282
|
invokedFunctions: Array.from(state.rpc.invokedFunctions),
|
|
283
|
+
usedExternalPackages: Array.from(state.rpc.usedExternalPackages),
|
|
268
284
|
},
|
|
269
285
|
mcpEndpoints: {
|
|
270
286
|
resourcesMeta: state.mcpEndpoints.resourcesMeta,
|
|
@@ -276,6 +292,14 @@ export function serializeInspectorState(
|
|
|
276
292
|
meta: state.cli.meta,
|
|
277
293
|
files: Array.from(state.cli.files),
|
|
278
294
|
},
|
|
295
|
+
forgeNodes: {
|
|
296
|
+
meta: state.forgeNodes.meta,
|
|
297
|
+
files: Array.from(state.forgeNodes.files),
|
|
298
|
+
},
|
|
299
|
+
forgeCredentials: {
|
|
300
|
+
meta: state.forgeCredentials.meta,
|
|
301
|
+
files: Array.from(state.forgeCredentials.files),
|
|
302
|
+
},
|
|
279
303
|
middleware: {
|
|
280
304
|
meta: state.middleware.meta,
|
|
281
305
|
tagMiddleware: Array.from(state.middleware.tagMiddleware.entries()),
|
|
@@ -302,7 +326,9 @@ export function serializeInspectorState(
|
|
|
302
326
|
*/
|
|
303
327
|
export function deserializeInspectorState(
|
|
304
328
|
data: SerializableInspectorState
|
|
305
|
-
): Omit<InspectorState, 'typesLookup'> {
|
|
329
|
+
): Omit<InspectorState, 'typesLookup' | 'zodLookup'> & {
|
|
330
|
+
zodLookup: Map<string, { variableName: string; sourceFile: string }>
|
|
331
|
+
} {
|
|
306
332
|
// Helper to deserialize TypesMap
|
|
307
333
|
const deserializeTypesMap = (
|
|
308
334
|
serialized: SerializableInspectorState['functions']['typesMap']
|
|
@@ -337,6 +363,7 @@ export function deserializeInspectorState(
|
|
|
337
363
|
new Map(entries),
|
|
338
364
|
])
|
|
339
365
|
),
|
|
366
|
+
zodLookup: new Map(data.zodLookup || []),
|
|
340
367
|
functions: {
|
|
341
368
|
typesMap: deserializeTypesMap(data.functions.typesMap),
|
|
342
369
|
meta: data.functions.meta,
|
|
@@ -364,6 +391,8 @@ export function deserializeInspectorState(
|
|
|
364
391
|
workflows: {
|
|
365
392
|
meta: data.workflows.meta,
|
|
366
393
|
files: new Map(data.workflows.files),
|
|
394
|
+
graphMeta: data.workflows.graphMeta || {},
|
|
395
|
+
graphFiles: new Map(data.workflows.graphFiles || []),
|
|
367
396
|
},
|
|
368
397
|
rpc: {
|
|
369
398
|
internalMeta: data.rpc.internalMeta,
|
|
@@ -371,6 +400,7 @@ export function deserializeInspectorState(
|
|
|
371
400
|
exposedMeta: data.rpc.exposedMeta,
|
|
372
401
|
exposedFiles: new Map(data.rpc.exposedFiles),
|
|
373
402
|
invokedFunctions: new Set(data.rpc.invokedFunctions),
|
|
403
|
+
usedExternalPackages: new Set(data.rpc.usedExternalPackages || []),
|
|
374
404
|
},
|
|
375
405
|
mcpEndpoints: {
|
|
376
406
|
resourcesMeta: data.mcpEndpoints.resourcesMeta,
|
|
@@ -382,6 +412,14 @@ export function deserializeInspectorState(
|
|
|
382
412
|
meta: data.cli.meta,
|
|
383
413
|
files: new Set(data.cli.files),
|
|
384
414
|
},
|
|
415
|
+
forgeNodes: {
|
|
416
|
+
meta: data.forgeNodes?.meta || {},
|
|
417
|
+
files: new Set(data.forgeNodes?.files || []),
|
|
418
|
+
},
|
|
419
|
+
forgeCredentials: {
|
|
420
|
+
meta: data.forgeCredentials?.meta || {},
|
|
421
|
+
files: new Set(data.forgeCredentials?.files || []),
|
|
422
|
+
},
|
|
385
423
|
middleware: {
|
|
386
424
|
meta: data.middleware.meta,
|
|
387
425
|
tagMiddleware: new Map(data.middleware.tagMiddleware),
|