@pikku/inspector 0.12.2 → 0.12.4

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 (70) hide show
  1. package/CHANGELOG.md +46 -0
  2. package/dist/add/add-ai-agent.js +4 -0
  3. package/dist/add/add-approval-description.d.ts +5 -0
  4. package/dist/add/add-approval-description.js +52 -0
  5. package/dist/add/add-channel.js +42 -4
  6. package/dist/add/add-cli.js +73 -13
  7. package/dist/add/add-file-with-factory.js +1 -0
  8. package/dist/add/add-functions.js +22 -3
  9. package/dist/add/add-gateway.js +5 -0
  10. package/dist/add/add-http-route.js +5 -0
  11. package/dist/add/add-mcp-prompt.js +5 -0
  12. package/dist/add/add-mcp-resource.js +5 -0
  13. package/dist/add/add-middleware.js +6 -10
  14. package/dist/add/add-permission.js +10 -12
  15. package/dist/add/add-queue-worker.js +5 -0
  16. package/dist/add/add-schedule.js +5 -0
  17. package/dist/add/add-wire-addon.js +7 -0
  18. package/dist/add/add-workflow.js +7 -1
  19. package/dist/error-codes.d.ts +1 -0
  20. package/dist/error-codes.js +2 -0
  21. package/dist/index.d.ts +1 -0
  22. package/dist/index.js +1 -0
  23. package/dist/inspector.js +21 -7
  24. package/dist/types.d.ts +12 -0
  25. package/dist/utils/custom-types-generator.js +1 -0
  26. package/dist/utils/load-addon-functions-meta.d.ts +12 -0
  27. package/dist/utils/load-addon-functions-meta.js +76 -0
  28. package/dist/utils/post-process.d.ts +9 -0
  29. package/dist/utils/post-process.js +72 -0
  30. package/dist/utils/resolve-function-meta.d.ts +11 -0
  31. package/dist/utils/resolve-function-meta.js +17 -0
  32. package/dist/utils/schema-generator.js +26 -6
  33. package/dist/utils/serialize-inspector-state.d.ts +2 -0
  34. package/dist/utils/serialize-inspector-state.js +5 -0
  35. package/dist/utils/serialize-mcp-json.js +13 -7
  36. package/dist/utils/workflow/graph/convert-dsl-to-graph.js +1 -0
  37. package/dist/utils/workflow/graph/workflow-graph.types.d.ts +2 -0
  38. package/dist/visit.js +2 -0
  39. package/package.json +4 -3
  40. package/src/add/add-ai-agent.ts +6 -0
  41. package/src/add/add-approval-description.ts +76 -0
  42. package/src/add/add-channel.ts +44 -4
  43. package/src/add/add-cli.ts +108 -21
  44. package/src/add/add-file-with-factory.ts +1 -0
  45. package/src/add/add-functions.ts +28 -3
  46. package/src/add/add-gateway.ts +6 -0
  47. package/src/add/add-http-route.ts +6 -0
  48. package/src/add/add-mcp-prompt.ts +6 -0
  49. package/src/add/add-mcp-resource.ts +6 -0
  50. package/src/add/add-middleware.ts +6 -14
  51. package/src/add/add-permission.ts +10 -16
  52. package/src/add/add-queue-worker.ts +6 -0
  53. package/src/add/add-schedule.ts +6 -0
  54. package/src/add/add-wire-addon.ts +8 -0
  55. package/src/add/add-workflow.ts +11 -1
  56. package/src/error-codes.ts +3 -0
  57. package/src/index.ts +1 -0
  58. package/src/inspector.ts +33 -6
  59. package/src/types.ts +13 -0
  60. package/src/utils/custom-types-generator.ts +1 -0
  61. package/src/utils/load-addon-functions-meta.ts +94 -0
  62. package/src/utils/post-process.ts +84 -0
  63. package/src/utils/resolve-function-meta.ts +25 -0
  64. package/src/utils/schema-generator.ts +38 -10
  65. package/src/utils/serialize-inspector-state.ts +7 -0
  66. package/src/utils/serialize-mcp-json.ts +12 -7
  67. package/src/utils/workflow/graph/convert-dsl-to-graph.ts +1 -0
  68. package/src/utils/workflow/graph/workflow-graph.types.ts +2 -0
  69. package/src/visit.ts +2 -0
  70. package/tsconfig.tsbuildinfo +1 -1
@@ -63,24 +63,37 @@ function primitiveTypeToSchema(typeStr: string): JSONValue | null {
63
63
  return null
64
64
  }
65
65
 
66
+ // Cached state for schema program reuse across inspect() calls
67
+ let cachedSchemaProgram: ts.Program | undefined
68
+ let cachedParsedConfig: ts.ParsedCommandLine | undefined
69
+ let cachedTsconfigPath: string | undefined
70
+ let cachedCustomTypesContent: string | undefined
71
+ let cachedTSSchemas: Record<string, JSONValue> | undefined
72
+
66
73
  function createProgramWithVirtualFile(
67
74
  tsconfig: string,
68
75
  virtualFilePath: string,
69
76
  virtualFileContent: string
70
77
  ): ts.Program {
71
78
  const configPath = resolve(tsconfig)
72
- const configFile = ts.readConfigFile(configPath, ts.sys.readFile)
73
- const basePath = dirname(configPath)
74
- const parsedConfig = ts.parseJsonConfigFileContent(
75
- configFile.config,
76
- ts.sys,
77
- basePath
78
- )
79
+
80
+ // Cache the parsed tsconfig — it doesn't change between runs
81
+ if (!cachedParsedConfig || cachedTsconfigPath !== configPath) {
82
+ const configFile = ts.readConfigFile(configPath, ts.sys.readFile)
83
+ const basePath = dirname(configPath)
84
+ cachedParsedConfig = ts.parseJsonConfigFileContent(
85
+ configFile.config,
86
+ ts.sys,
87
+ basePath
88
+ )
89
+ cachedTsconfigPath = configPath
90
+ cachedSchemaProgram = undefined
91
+ }
79
92
 
80
93
  const resolvedVirtualPath = resolve(virtualFilePath)
81
- const fileNames = [...parsedConfig.fileNames, resolvedVirtualPath]
94
+ const fileNames = [...cachedParsedConfig.fileNames, resolvedVirtualPath]
82
95
 
83
- const defaultHost = ts.createCompilerHost(parsedConfig.options)
96
+ const defaultHost = ts.createCompilerHost(cachedParsedConfig.options)
84
97
  const customHost: ts.CompilerHost = {
85
98
  ...defaultHost,
86
99
  getSourceFile(
@@ -113,7 +126,14 @@ function createProgramWithVirtualFile(
113
126
  },
114
127
  }
115
128
 
116
- return ts.createProgram(fileNames, parsedConfig.options, customHost)
129
+ const program = ts.createProgram(
130
+ fileNames,
131
+ cachedParsedConfig.options,
132
+ customHost,
133
+ cachedSchemaProgram // reuse previous program for incremental compilation
134
+ )
135
+ cachedSchemaProgram = program
136
+ return program
117
137
  }
118
138
 
119
139
  function generateTSSchemas(
@@ -313,6 +333,11 @@ export async function generateAllSchemas(
313
333
  requiredTypes
314
334
  )
315
335
 
336
+ if (cachedTSSchemas && cachedCustomTypesContent === customTypesContent) {
337
+ logger.debug('Reusing cached TS schemas (types unchanged)')
338
+ return { ...cachedTSSchemas, ...zodSchemas }
339
+ }
340
+
316
341
  const tsSchemas = generateTSSchemas(
317
342
  logger,
318
343
  config.tsconfig,
@@ -325,5 +350,8 @@ export async function generateAllSchemas(
325
350
  state.schemaLookup
326
351
  )
327
352
 
353
+ cachedCustomTypesContent = customTypesContent
354
+ cachedTSSchemas = tsSchemas
355
+
328
356
  return { ...tsSchemas, ...zodSchemas }
329
357
  }
@@ -81,6 +81,7 @@ export interface SerializableInspectorState {
81
81
  }
82
82
  meta: InspectorState['functions']['meta']
83
83
  files: Array<[string, { path: string; exportedName: string }]>
84
+ approvalDescriptions: InspectorState['functions']['approvalDescriptions']
84
85
  }
85
86
  http: {
86
87
  metaInputTypes: Array<
@@ -249,6 +250,7 @@ export interface SerializableInspectorState {
249
250
  requiredSchemas: string[]
250
251
  openAPISpec: Record<string, any> | null
251
252
  diagnostics: InspectorDiagnostic[]
253
+ addonFunctions: InspectorState['addonFunctions']
252
254
  }
253
255
 
254
256
  /**
@@ -307,6 +309,7 @@ export function serializeInspectorState(
307
309
  typesMap: serializeTypesMap(state.functions.typesMap),
308
310
  meta: state.functions.meta,
309
311
  files: Array.from(state.functions.files.entries()),
312
+ approvalDescriptions: state.functions.approvalDescriptions,
310
313
  },
311
314
  http: {
312
315
  metaInputTypes: Array.from(state.http.metaInputTypes.entries()),
@@ -416,6 +419,7 @@ export function serializeInspectorState(
416
419
  requiredSchemas: Array.from(state.requiredSchemas),
417
420
  openAPISpec: state.openAPISpec,
418
421
  diagnostics: state.diagnostics,
422
+ addonFunctions: state.addonFunctions,
419
423
  }
420
424
  }
421
425
 
@@ -475,6 +479,7 @@ export function deserializeInspectorState(
475
479
  typesMap: deserializeTypesMap(data.functions.typesMap),
476
480
  meta: data.functions.meta,
477
481
  files: new Map(data.functions.files),
482
+ approvalDescriptions: (data.functions as any).approvalDescriptions || {},
478
483
  },
479
484
  http: {
480
485
  metaInputTypes: new Map(data.http.metaInputTypes),
@@ -590,5 +595,7 @@ export function deserializeInspectorState(
590
595
  requiredSchemas: new Set(data.requiredSchemas || []),
591
596
  openAPISpec: data.openAPISpec || null,
592
597
  diagnostics: data.diagnostics || [],
598
+ addonFunctions: data.addonFunctions || {},
599
+ program: null,
593
600
  }
594
601
  }
@@ -1,5 +1,6 @@
1
1
  import type { InspectorLogger, InspectorState } from '../types.js'
2
2
  import type { JSONValue } from '@pikku/core'
3
+ import { resolveFunctionMeta } from './resolve-function-meta.js'
3
4
 
4
5
  interface MCPEndpoint {
5
6
  uri?: string
@@ -15,7 +16,7 @@ export const serializeMCPJson = (
15
16
  state: InspectorState
16
17
  ): string => {
17
18
  const { mcpEndpoints, functions, schemas } = state
18
- const { meta: functionsMeta, typesMap } = functions
19
+ const { typesMap } = functions
19
20
  const { resourcesMeta, toolsMeta, promptsMeta } = mcpEndpoints
20
21
 
21
22
  const tools: MCPEndpoint[] = []
@@ -39,9 +40,13 @@ export const serializeMCPJson = (
39
40
  return undefined
40
41
  }
41
42
 
42
- const uniqueName = typesMap.getUniqueName(typeName)
43
- if (!uniqueName) {
44
- return undefined
43
+ // Try local typesMap first, fall back to direct schema lookup (for addon types)
44
+ let uniqueName: string | undefined
45
+ try {
46
+ uniqueName = typesMap.getUniqueName(typeName)
47
+ } catch {
48
+ // Type not in local typesMap — try direct schema lookup (addon schemas)
49
+ uniqueName = typeName
45
50
  }
46
51
 
47
52
  const schema = schemas[uniqueName]
@@ -56,7 +61,7 @@ export const serializeMCPJson = (
56
61
  }
57
62
 
58
63
  for (const [name, endpointMeta] of Object.entries(resourcesMeta)) {
59
- const functionMeta = functionsMeta[endpointMeta.pikkuFuncId]
64
+ const functionMeta = resolveFunctionMeta(state, endpointMeta.pikkuFuncId)
60
65
  if (!functionMeta) {
61
66
  logger.warn(
62
67
  `Function ${endpointMeta.pikkuFuncId} not found in functionsMeta. Skipping resource ${name}.`
@@ -81,7 +86,7 @@ export const serializeMCPJson = (
81
86
  }
82
87
 
83
88
  for (const [name, endpointMeta] of Object.entries(toolsMeta)) {
84
- const functionMeta = functionsMeta[endpointMeta.pikkuFuncId]
89
+ const functionMeta = resolveFunctionMeta(state, endpointMeta.pikkuFuncId)
85
90
  if (!functionMeta) {
86
91
  logger.warn(
87
92
  `Function ${endpointMeta.pikkuFuncId} not found in functionsMeta. Skipping tool ${name}.`
@@ -105,7 +110,7 @@ export const serializeMCPJson = (
105
110
  }
106
111
 
107
112
  for (const [name, endpointMeta] of Object.entries(promptsMeta)) {
108
- const functionMeta = functionsMeta[endpointMeta.pikkuFuncId]
113
+ const functionMeta = resolveFunctionMeta(state, endpointMeta.pikkuFuncId)
109
114
  if (!functionMeta) {
110
115
  logger.warn(
111
116
  `Function ${endpointMeta.pikkuFuncId} not found in functionsMeta. Skipping prompt ${name}.`
@@ -400,6 +400,7 @@ export function convertDslToGraph(
400
400
  source,
401
401
  description: meta.description,
402
402
  tags: meta.tags,
403
+ inline: meta.inline,
403
404
  context: meta.context,
404
405
  nodes: nodesRecord,
405
406
  entryNodeIds,
@@ -192,6 +192,8 @@ export interface SerializedWorkflowGraph {
192
192
  description?: string
193
193
  /** Tags for organization */
194
194
  tags?: string[]
195
+ /** If true, workflow always executes inline without queues */
196
+ inline?: boolean
195
197
  /** Workflow context/state variables (from Zod schema) */
196
198
  context?: WorkflowContext
197
199
  /** Serialized nodes */
package/src/visit.ts CHANGED
@@ -26,6 +26,7 @@ import { addSecret, addOAuth2Credential } from './add/add-secret.js'
26
26
  import { addVariable } from './add/add-variable.js'
27
27
  import { addWorkflowGraph } from './add/add-workflow-graph.js'
28
28
  import { addAIAgent } from './add/add-ai-agent.js'
29
+ import { addApprovalDescription } from './add/add-approval-description.js'
29
30
 
30
31
  export const visitSetup = (
31
32
  logger: InspectorLogger,
@@ -87,6 +88,7 @@ export const visitSetup = (
87
88
  addWireAddon(node, state, logger)
88
89
  addMiddleware(logger, node, checker, state, options)
89
90
  addPermission(logger, node, checker, state, options)
91
+ addApprovalDescription(logger, node, checker, state, options)
90
92
  addWorkflow(logger, node, checker, state, options)
91
93
 
92
94
  ts.forEachChild(node, (child) =>