@pikku/inspector 0.11.2 → 0.12.1

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 (211) hide show
  1. package/CHANGELOG.md +36 -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 +81 -61
  6. package/dist/add/add-cli.d.ts +1 -1
  7. package/dist/add/add-cli.js +42 -19
  8. package/dist/add/add-file-extends-core-type.d.ts +1 -1
  9. package/dist/add/add-file-with-config.d.ts +1 -1
  10. package/dist/add/add-file-with-factory.d.ts +1 -1
  11. package/dist/add/add-file-with-factory.js +2 -0
  12. package/dist/add/add-functions.d.ts +1 -1
  13. package/dist/add/add-functions.js +256 -82
  14. package/dist/add/add-http-route.d.ts +20 -10
  15. package/dist/add/add-http-route.js +156 -66
  16. package/dist/add/add-http-routes.d.ts +5 -0
  17. package/dist/add/add-http-routes.js +160 -0
  18. package/dist/add/add-keyed-wiring.d.ts +12 -0
  19. package/dist/add/add-keyed-wiring.js +97 -0
  20. package/dist/add/add-mcp-prompt.d.ts +1 -1
  21. package/dist/add/add-mcp-prompt.js +14 -9
  22. package/dist/add/add-mcp-resource.d.ts +1 -1
  23. package/dist/add/add-mcp-resource.js +14 -9
  24. package/dist/add/add-middleware.d.ts +1 -4
  25. package/dist/add/add-middleware.js +364 -79
  26. package/dist/add/add-permission.d.ts +1 -1
  27. package/dist/add/add-permission.js +152 -40
  28. package/dist/add/add-queue-worker.d.ts +1 -1
  29. package/dist/add/add-queue-worker.js +18 -12
  30. package/dist/add/add-rpc-invocations.d.ts +3 -3
  31. package/dist/add/add-rpc-invocations.js +24 -10
  32. package/dist/add/add-schedule.d.ts +1 -1
  33. package/dist/add/add-schedule.js +11 -5
  34. package/dist/add/add-secret.d.ts +3 -0
  35. package/dist/add/add-secret.js +82 -0
  36. package/dist/add/add-trigger.d.ts +2 -0
  37. package/dist/add/add-trigger.js +87 -0
  38. package/dist/add/add-variable.d.ts +1 -0
  39. package/dist/add/add-variable.js +8 -0
  40. package/dist/add/add-wire-addon.d.ts +7 -0
  41. package/dist/add/add-wire-addon.js +70 -0
  42. package/dist/add/add-workflow-graph.d.ts +3 -2
  43. package/dist/add/add-workflow-graph.js +143 -406
  44. package/dist/add/add-workflow.d.ts +1 -1
  45. package/dist/add/add-workflow.js +6 -4
  46. package/dist/error-codes.d.ts +15 -1
  47. package/dist/error-codes.js +20 -1
  48. package/dist/index.d.ts +9 -8
  49. package/dist/index.js +5 -4
  50. package/dist/inspector.d.ts +2 -2
  51. package/dist/inspector.js +95 -15
  52. package/dist/schema-generator.d.ts +1 -0
  53. package/dist/schema-generator.js +1 -0
  54. package/dist/types-map.js +10 -1
  55. package/dist/types.d.ts +180 -50
  56. package/dist/utils/compute-required-schemas.d.ts +4 -0
  57. package/dist/utils/compute-required-schemas.js +40 -0
  58. package/dist/utils/contract-hashes.d.ts +52 -0
  59. package/dist/utils/contract-hashes.js +269 -0
  60. package/dist/utils/custom-types-generator.d.ts +9 -0
  61. package/dist/utils/custom-types-generator.js +71 -0
  62. package/dist/utils/detect-schema-vendor.d.ts +22 -0
  63. package/dist/utils/detect-schema-vendor.js +76 -0
  64. package/dist/utils/does-type-extend-core-type.d.ts +1 -1
  65. package/dist/utils/ensure-function-metadata.d.ts +6 -3
  66. package/dist/utils/ensure-function-metadata.js +220 -6
  67. package/dist/utils/extract-function-name.d.ts +5 -16
  68. package/dist/utils/extract-function-name.js +86 -291
  69. package/dist/utils/extract-services.d.ts +2 -1
  70. package/dist/utils/extract-services.js +25 -1
  71. package/dist/utils/filter-inspector-state.d.ts +1 -1
  72. package/dist/utils/filter-inspector-state.js +107 -23
  73. package/dist/utils/filter-utils.d.ts +2 -2
  74. package/dist/utils/get-files-and-methods.d.ts +1 -1
  75. package/dist/utils/get-property-value.d.ts +6 -1
  76. package/dist/utils/get-property-value.js +28 -3
  77. package/dist/utils/hash.d.ts +2 -0
  78. package/dist/utils/hash.js +23 -0
  79. package/dist/utils/middleware.d.ts +9 -32
  80. package/dist/utils/middleware.js +80 -66
  81. package/dist/utils/permissions.d.ts +4 -4
  82. package/dist/utils/permissions.js +10 -10
  83. package/dist/utils/post-process.d.ts +11 -11
  84. package/dist/utils/post-process.js +247 -24
  85. package/dist/utils/resolve-addon-package.d.ts +16 -0
  86. package/dist/utils/resolve-addon-package.js +34 -0
  87. package/dist/utils/resolve-function-types.d.ts +6 -0
  88. package/dist/utils/resolve-function-types.js +29 -0
  89. package/dist/utils/resolve-identifier.d.ts +10 -0
  90. package/dist/utils/resolve-identifier.js +36 -0
  91. package/dist/utils/resolve-versions.d.ts +2 -0
  92. package/dist/utils/resolve-versions.js +78 -0
  93. package/dist/utils/schema-generator.d.ts +9 -0
  94. package/dist/utils/schema-generator.js +209 -0
  95. package/dist/utils/serialize-inspector-state.d.ts +70 -23
  96. package/dist/utils/serialize-inspector-state.js +98 -22
  97. package/dist/utils/serialize-mcp-json.d.ts +2 -0
  98. package/dist/utils/serialize-mcp-json.js +99 -0
  99. package/dist/utils/serialize-middleware-groups-meta.d.ts +12 -0
  100. package/dist/utils/serialize-middleware-groups-meta.js +28 -0
  101. package/dist/utils/serialize-openapi-json.d.ts +85 -0
  102. package/dist/utils/serialize-openapi-json.js +151 -0
  103. package/dist/utils/serialize-permissions-groups-meta.d.ts +6 -0
  104. package/dist/utils/serialize-permissions-groups-meta.js +31 -0
  105. package/dist/utils/validate-auth-sessionless.d.ts +3 -0
  106. package/dist/utils/validate-auth-sessionless.js +14 -0
  107. package/dist/utils/workflow/dsl/deserialize-dsl-workflow.js +34 -102
  108. package/dist/utils/workflow/dsl/extract-dsl-workflow.d.ts +1 -1
  109. package/dist/utils/workflow/dsl/extract-dsl-workflow.js +23 -4
  110. package/dist/utils/workflow/graph/convert-dsl-to-graph.js +12 -10
  111. package/dist/utils/workflow/graph/finalize-workflow-wires.d.ts +3 -0
  112. package/dist/utils/workflow/graph/finalize-workflow-wires.js +276 -0
  113. package/dist/utils/workflow/graph/finalize-workflows.d.ts +2 -0
  114. package/dist/utils/workflow/graph/finalize-workflows.js +75 -0
  115. package/dist/utils/workflow/graph/index.d.ts +2 -0
  116. package/dist/utils/workflow/graph/index.js +2 -0
  117. package/dist/utils/workflow/graph/serialize-workflow-graph.d.ts +0 -8
  118. package/dist/utils/workflow/graph/serialize-workflow-graph.js +1 -3
  119. package/dist/utils/workflow/graph/workflow-graph.types.d.ts +53 -79
  120. package/dist/utils/workflow/graph/workflow-graph.types.js +1 -1
  121. package/dist/visit.d.ts +1 -1
  122. package/dist/visit.js +13 -6
  123. package/package.json +14 -4
  124. package/src/add/add-ai-agent.ts +468 -0
  125. package/src/add/add-channel.ts +103 -79
  126. package/src/add/add-cli.ts +68 -24
  127. package/src/add/add-file-extends-core-type.ts +1 -1
  128. package/src/add/add-file-with-config.ts +1 -1
  129. package/src/add/add-file-with-factory.ts +3 -1
  130. package/src/add/add-functions.ts +349 -103
  131. package/src/add/add-http-route.ts +263 -89
  132. package/src/add/add-http-routes.ts +229 -0
  133. package/src/add/add-keyed-wiring.ts +151 -0
  134. package/src/add/add-mcp-prompt.ts +27 -16
  135. package/src/add/add-mcp-resource.ts +28 -16
  136. package/src/add/add-middleware.ts +482 -80
  137. package/src/add/add-permission.ts +199 -40
  138. package/src/add/add-queue-worker.ts +25 -20
  139. package/src/add/add-rpc-invocations.ts +28 -11
  140. package/src/add/add-schedule.ts +17 -12
  141. package/src/add/add-secret.ts +140 -0
  142. package/src/add/add-trigger.ts +154 -0
  143. package/src/add/add-variable.ts +9 -0
  144. package/src/add/add-wire-addon.ts +80 -0
  145. package/src/add/add-workflow-graph.ts +180 -522
  146. package/src/add/add-workflow.ts +7 -6
  147. package/src/error-codes.ts +25 -1
  148. package/src/index.ts +23 -13
  149. package/src/inspector.ts +139 -19
  150. package/src/schema-generator.ts +1 -0
  151. package/src/types-map.ts +12 -1
  152. package/src/types.ts +199 -69
  153. package/src/utils/compute-required-schemas.ts +48 -0
  154. package/src/utils/contract-hashes.test.ts +553 -0
  155. package/src/utils/contract-hashes.ts +386 -0
  156. package/src/utils/custom-types-generator.ts +88 -0
  157. package/src/utils/detect-schema-vendor.ts +90 -0
  158. package/src/utils/does-type-extend-core-type.ts +1 -1
  159. package/src/utils/ensure-function-metadata.ts +325 -8
  160. package/src/utils/extract-function-name.ts +101 -351
  161. package/src/utils/extract-services.ts +35 -2
  162. package/src/utils/filter-inspector-state.test.ts +37 -25
  163. package/src/utils/filter-inspector-state.ts +146 -32
  164. package/src/utils/filter-utils.test.ts +1 -1
  165. package/src/utils/filter-utils.ts +2 -2
  166. package/src/utils/get-files-and-methods.ts +1 -1
  167. package/src/utils/get-property-value.ts +42 -4
  168. package/src/utils/hash.ts +26 -0
  169. package/src/utils/middleware.test.ts +204 -0
  170. package/src/utils/middleware.ts +131 -69
  171. package/src/utils/permissions.test.ts +35 -12
  172. package/src/utils/permissions.ts +12 -12
  173. package/src/utils/post-process.ts +306 -44
  174. package/src/utils/resolve-addon-package.ts +49 -0
  175. package/src/utils/resolve-function-types.ts +42 -0
  176. package/src/utils/resolve-identifier.ts +46 -0
  177. package/src/utils/resolve-versions.test.ts +249 -0
  178. package/src/utils/resolve-versions.ts +105 -0
  179. package/src/utils/schema-generator.ts +329 -0
  180. package/src/utils/serialize-inspector-state.ts +184 -43
  181. package/src/utils/serialize-mcp-json.ts +145 -0
  182. package/src/utils/serialize-middleware-groups-meta.ts +33 -0
  183. package/src/utils/serialize-openapi-json.ts +277 -0
  184. package/src/utils/serialize-permissions-groups-meta.ts +35 -0
  185. package/src/utils/test-data/inspector-state.json +69 -66
  186. package/src/utils/validate-auth-sessionless.ts +29 -0
  187. package/src/utils/workflow/dsl/deserialize-dsl-workflow.ts +43 -119
  188. package/src/utils/workflow/dsl/extract-dsl-workflow.ts +26 -6
  189. package/src/utils/workflow/graph/convert-dsl-to-graph.ts +17 -10
  190. package/src/utils/workflow/graph/finalize-workflow-wires.ts +310 -0
  191. package/src/utils/workflow/graph/finalize-workflows.ts +100 -0
  192. package/src/utils/workflow/graph/index.ts +5 -0
  193. package/src/utils/workflow/graph/serialize-workflow-graph.ts +1 -8
  194. package/src/utils/workflow/graph/workflow-graph.types.ts +29 -78
  195. package/src/visit.ts +19 -7
  196. package/tsconfig.tsbuildinfo +1 -1
  197. package/dist/add/add-forge-credential.d.ts +0 -8
  198. package/dist/add/add-forge-credential.js +0 -77
  199. package/dist/add/add-forge-node.d.ts +0 -7
  200. package/dist/add/add-forge-node.js +0 -77
  201. package/dist/add/add-mcp-tool.d.ts +0 -2
  202. package/dist/add/add-mcp-tool.js +0 -81
  203. package/dist/utils/extract-service-metadata.d.ts +0 -19
  204. package/dist/utils/extract-service-metadata.js +0 -244
  205. package/dist/utils/write-service-metadata.d.ts +0 -13
  206. package/dist/utils/write-service-metadata.js +0 -37
  207. package/src/add/add-forge-credential.ts +0 -119
  208. package/src/add/add-forge-node.ts +0 -132
  209. package/src/add/add-mcp-tool.ts +0 -141
  210. package/src/utils/extract-service-metadata.ts +0 -353
  211. package/src/utils/write-service-metadata.ts +0 -51
@@ -0,0 +1,151 @@
1
+ import * as ts from 'typescript'
2
+ import { getPropertyValue } from '../utils/get-property-value.js'
3
+ import type { AddWiring, InspectorState } from '../types.js'
4
+ import { ErrorCode } from '../error-codes.js'
5
+ import { detectSchemaVendorOrError } from '../utils/detect-schema-vendor.js'
6
+
7
+ export interface KeyedWiringConfig {
8
+ functionName: string
9
+ idField: string
10
+ label: string
11
+ schemaPrefix: string
12
+ getState: (state: InspectorState) => {
13
+ definitions: any[]
14
+ files: Set<string>
15
+ }
16
+ }
17
+
18
+ export const createAddKeyedWiring = (config: KeyedWiringConfig): AddWiring => {
19
+ return (logger, node, checker, state, _options) => {
20
+ if (!ts.isCallExpression(node)) {
21
+ return
22
+ }
23
+
24
+ const args = node.arguments
25
+ const firstArg = args[0]
26
+ const expression = node.expression
27
+
28
+ if (
29
+ !ts.isIdentifier(expression) ||
30
+ expression.text !== config.functionName
31
+ ) {
32
+ return
33
+ }
34
+
35
+ if (!firstArg) {
36
+ return
37
+ }
38
+
39
+ if (ts.isObjectLiteralExpression(firstArg)) {
40
+ const obj = firstArg
41
+
42
+ const nameValue = getPropertyValue(obj, 'name') as string | null
43
+ const displayNameValue = getPropertyValue(obj, 'displayName') as
44
+ | string
45
+ | null
46
+ const descriptionValue = getPropertyValue(obj, 'description') as
47
+ | string
48
+ | null
49
+ const idValue = getPropertyValue(obj, config.idField) as string | null
50
+
51
+ let schemaVariableName: string | null = null
52
+ let schemaSourceFile: string | null = null
53
+ let schemaIdentifier: ts.Identifier | null = null
54
+ for (const prop of obj.properties) {
55
+ if (
56
+ ts.isPropertyAssignment(prop) &&
57
+ ts.isIdentifier(prop.name) &&
58
+ prop.name.text === 'schema'
59
+ ) {
60
+ if (ts.isIdentifier(prop.initializer)) {
61
+ schemaVariableName = prop.initializer.text
62
+ schemaIdentifier = prop.initializer
63
+
64
+ const symbol = checker.getSymbolAtLocation(prop.initializer)
65
+ if (symbol) {
66
+ const decl = symbol.valueDeclaration || symbol.declarations?.[0]
67
+ if (decl) {
68
+ if (ts.isImportSpecifier(decl)) {
69
+ const aliasedSymbol = checker.getAliasedSymbol(symbol)
70
+ if (aliasedSymbol) {
71
+ const aliasedDecl =
72
+ aliasedSymbol.valueDeclaration ||
73
+ aliasedSymbol.declarations?.[0]
74
+ if (aliasedDecl) {
75
+ schemaSourceFile = aliasedDecl.getSourceFile().fileName
76
+ }
77
+ }
78
+ } else {
79
+ schemaSourceFile = decl.getSourceFile().fileName
80
+ }
81
+ }
82
+ }
83
+ }
84
+ break
85
+ }
86
+ }
87
+
88
+ if (!nameValue) {
89
+ logger.critical(
90
+ ErrorCode.MISSING_NAME,
91
+ `${config.label} is missing the required 'name' property.`
92
+ )
93
+ return
94
+ }
95
+
96
+ if (!displayNameValue) {
97
+ logger.critical(
98
+ ErrorCode.MISSING_NAME,
99
+ `${config.label} '${nameValue}' is missing the required 'displayName' property.`
100
+ )
101
+ return
102
+ }
103
+
104
+ if (!idValue) {
105
+ logger.critical(
106
+ ErrorCode.MISSING_NAME,
107
+ `${config.label} '${nameValue}' is missing the required '${config.idField}' property.`
108
+ )
109
+ return
110
+ }
111
+
112
+ if (!schemaVariableName || !schemaSourceFile || !schemaIdentifier) {
113
+ logger.critical(
114
+ ErrorCode.MISSING_NAME,
115
+ `${config.label} '${nameValue}' is missing the required 'schema' property or schema is not a variable reference.`
116
+ )
117
+ return
118
+ }
119
+
120
+ const sourceFile = node.getSourceFile().fileName
121
+
122
+ const wiringState = config.getState(state)
123
+ wiringState.files.add(sourceFile)
124
+
125
+ const vendor = detectSchemaVendorOrError(
126
+ schemaIdentifier,
127
+ checker,
128
+ logger,
129
+ `${config.label} '${nameValue}'`,
130
+ schemaSourceFile
131
+ )
132
+ if (!vendor) return
133
+
134
+ const schemaLookupName = `${config.schemaPrefix}_${nameValue}`
135
+ state.schemaLookup.set(schemaLookupName, {
136
+ variableName: schemaVariableName,
137
+ sourceFile: schemaSourceFile,
138
+ vendor,
139
+ })
140
+
141
+ wiringState.definitions.push({
142
+ name: nameValue,
143
+ displayName: displayNameValue,
144
+ description: descriptionValue || undefined,
145
+ [config.idField]: idValue,
146
+ schema: schemaLookupName,
147
+ sourceFile,
148
+ })
149
+ }
150
+ }
151
+ }
@@ -5,8 +5,11 @@ import {
5
5
  } from '../utils/get-property-value.js'
6
6
  import { extractWireNames } from '../utils/post-process.js'
7
7
  import { ensureFunctionMetadata } from '../utils/ensure-function-metadata.js'
8
- import { AddWiring } from '../types.js'
9
- import { extractFunctionName } from '../utils/extract-function-name.js'
8
+ import type { AddWiring } from '../types.js'
9
+ import {
10
+ extractFunctionName,
11
+ makeContextBasedId,
12
+ } from '../utils/extract-function-name.js'
10
13
  import { getPropertyAssignmentInitializer } from '../utils/type-utils.js'
11
14
  import { resolveMiddleware } from '../utils/middleware.js'
12
15
  import { resolvePermissions } from '../utils/permissions.js'
@@ -40,12 +43,10 @@ export const addMCPPrompt: AddWiring = (
40
43
  const obj = firstArg
41
44
 
42
45
  const nameValue = getPropertyValue(obj, 'name') as string | null
43
- const { tags, summary, description, errors } = getCommonWireMetaData(
44
- obj,
45
- 'MCP prompt',
46
- nameValue,
47
- logger
48
- )
46
+ const { disabled, tags, summary, description, errors } =
47
+ getCommonWireMetaData(obj, 'MCP prompt', nameValue, logger)
48
+
49
+ if (disabled) return
49
50
 
50
51
  const funcInitializer = getPropertyAssignmentInitializer(
51
52
  obj,
@@ -61,14 +62,24 @@ export const addMCPPrompt: AddWiring = (
61
62
  return
62
63
  }
63
64
 
64
- const pikkuFuncName = extractFunctionName(
65
+ const extracted = extractFunctionName(
65
66
  funcInitializer,
66
67
  checker,
67
68
  state.rootDir
68
- ).pikkuFuncName
69
+ )
70
+ let pikkuFuncId = extracted.pikkuFuncId
71
+ if (pikkuFuncId.startsWith('__temp_') && nameValue) {
72
+ pikkuFuncId = makeContextBasedId('mcp', 'prompt', nameValue)
73
+ }
69
74
 
70
- // Ensure function metadata exists (creates stub for inline functions)
71
- ensureFunctionMetadata(state, pikkuFuncName, nameValue || undefined)
75
+ ensureFunctionMetadata(
76
+ state,
77
+ pikkuFuncId,
78
+ nameValue || undefined,
79
+ funcInitializer,
80
+ checker,
81
+ extracted.isHelper
82
+ )
72
83
 
73
84
  if (!nameValue) {
74
85
  logger.critical(
@@ -87,11 +98,11 @@ export const addMCPPrompt: AddWiring = (
87
98
  }
88
99
 
89
100
  // lookup existing function metadata
90
- const fnMeta = state.functions.meta[pikkuFuncName]
101
+ const fnMeta = state.functions.meta[pikkuFuncId]
91
102
  if (!fnMeta) {
92
103
  logger.critical(
93
104
  ErrorCode.FUNCTION_METADATA_NOT_FOUND,
94
- `No function metadata found for '${pikkuFuncName}'.`
105
+ `No function metadata found for '${pikkuFuncId}'.`
95
106
  )
96
107
  return
97
108
  }
@@ -105,7 +116,7 @@ export const addMCPPrompt: AddWiring = (
105
116
  const permissions = resolvePermissions(state, obj, tags, checker)
106
117
 
107
118
  // --- track used functions/middleware/permissions for service aggregation ---
108
- state.serviceAggregation.usedFunctions.add(pikkuFuncName)
119
+ state.serviceAggregation.usedFunctions.add(pikkuFuncId)
109
120
  extractWireNames(middleware).forEach((name) =>
110
121
  state.serviceAggregation.usedMiddleware.add(name)
111
122
  )
@@ -116,7 +127,7 @@ export const addMCPPrompt: AddWiring = (
116
127
  state.mcpEndpoints.files.add(node.getSourceFile().fileName)
117
128
 
118
129
  state.mcpEndpoints.promptsMeta[nameValue] = {
119
- pikkuFuncName,
130
+ pikkuFuncId,
120
131
  name: nameValue,
121
132
  description,
122
133
  summary,
@@ -5,8 +5,11 @@ import {
5
5
  } from '../utils/get-property-value.js'
6
6
  import { extractWireNames } from '../utils/post-process.js'
7
7
  import { ensureFunctionMetadata } from '../utils/ensure-function-metadata.js'
8
- import { AddWiring } from '../types.js'
9
- import { extractFunctionName } from '../utils/extract-function-name.js'
8
+ import type { AddWiring } from '../types.js'
9
+ import {
10
+ extractFunctionName,
11
+ makeContextBasedId,
12
+ } from '../utils/extract-function-name.js'
10
13
  import { getPropertyAssignmentInitializer } from '../utils/type-utils.js'
11
14
  import { resolveMiddleware } from '../utils/middleware.js'
12
15
  import { resolvePermissions } from '../utils/permissions.js'
@@ -41,12 +44,11 @@ export const addMCPResource: AddWiring = (
41
44
 
42
45
  const uriValue = getPropertyValue(obj, 'uri') as string | null
43
46
  const titleValue = getPropertyValue(obj, 'title') as string | null
44
- const { tags, summary, description, errors } = getCommonWireMetaData(
45
- obj,
46
- 'MCP resource',
47
- uriValue,
48
- logger
49
- )
47
+ const { disabled, tags, summary, description, errors } =
48
+ getCommonWireMetaData(obj, 'MCP resource', uriValue, logger)
49
+
50
+ if (disabled) return
51
+
50
52
  const streamingValue = getPropertyValue(obj, 'streaming') as boolean | null
51
53
 
52
54
  if (streamingValue === true) {
@@ -69,14 +71,24 @@ export const addMCPResource: AddWiring = (
69
71
  return
70
72
  }
71
73
 
72
- const pikkuFuncName = extractFunctionName(
74
+ const extracted = extractFunctionName(
73
75
  funcInitializer,
74
76
  checker,
75
77
  state.rootDir
76
- ).pikkuFuncName
78
+ )
79
+ let pikkuFuncId = extracted.pikkuFuncId
80
+ if (pikkuFuncId.startsWith('__temp_') && uriValue) {
81
+ pikkuFuncId = makeContextBasedId('mcp', 'resource', uriValue)
82
+ }
77
83
 
78
- // Ensure function metadata exists (creates stub for inline functions)
79
- ensureFunctionMetadata(state, pikkuFuncName, uriValue || undefined)
84
+ ensureFunctionMetadata(
85
+ state,
86
+ pikkuFuncId,
87
+ uriValue || undefined,
88
+ funcInitializer,
89
+ checker,
90
+ extracted.isHelper
91
+ )
80
92
 
81
93
  if (!uriValue) {
82
94
  logger.critical(
@@ -103,11 +115,11 @@ export const addMCPResource: AddWiring = (
103
115
  }
104
116
 
105
117
  // lookup existing function metadata
106
- const fnMeta = state.functions.meta[pikkuFuncName]
118
+ const fnMeta = state.functions.meta[pikkuFuncId]
107
119
  if (!fnMeta) {
108
120
  logger.critical(
109
121
  ErrorCode.FUNCTION_METADATA_NOT_FOUND,
110
- `No function metadata found for '${pikkuFuncName}'.`
122
+ `No function metadata found for '${pikkuFuncId}'.`
111
123
  )
112
124
  return
113
125
  }
@@ -121,7 +133,7 @@ export const addMCPResource: AddWiring = (
121
133
  const permissions = resolvePermissions(state, obj, tags, checker)
122
134
 
123
135
  // --- track used functions/middleware/permissions for service aggregation ---
124
- state.serviceAggregation.usedFunctions.add(pikkuFuncName)
136
+ state.serviceAggregation.usedFunctions.add(pikkuFuncId)
125
137
  extractWireNames(middleware).forEach((name) =>
126
138
  state.serviceAggregation.usedMiddleware.add(name)
127
139
  )
@@ -132,7 +144,7 @@ export const addMCPResource: AddWiring = (
132
144
  state.mcpEndpoints.files.add(node.getSourceFile().fileName)
133
145
 
134
146
  state.mcpEndpoints.resourcesMeta[uriValue] = {
135
- pikkuFuncName,
147
+ pikkuFuncId,
136
148
  uri: uriValue,
137
149
  title: titleValue,
138
150
  description,