@pikku/inspector 0.12.42 → 0.12.44

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 (126) hide show
  1. package/CHANGELOG.md +266 -0
  2. package/dist/add/add-addon-bans.js +1 -0
  3. package/dist/add/add-ai-agent.d.ts +3 -1
  4. package/dist/add/add-ai-agent.js +82 -0
  5. package/dist/add/add-credential.js +5 -1
  6. package/dist/add/add-functions.js +10 -9
  7. package/dist/add/add-gateway.js +3 -0
  8. package/dist/add/add-http-route.js +2 -2
  9. package/dist/add/add-keyed-wiring.js +2 -0
  10. package/dist/add/add-mcp-prompt.js +0 -1
  11. package/dist/add/add-mcp-resource.js +0 -1
  12. package/dist/add/add-permission.d.ts +1 -1
  13. package/dist/add/add-permission.js +3 -177
  14. package/dist/add/add-queue-worker.js +3 -0
  15. package/dist/add/add-schedule.js +3 -0
  16. package/dist/add/add-scope.d.ts +2 -0
  17. package/dist/add/add-scope.js +146 -0
  18. package/dist/add/add-trigger.js +3 -0
  19. package/dist/add/add-wire-remote-addon.d.ts +10 -0
  20. package/dist/add/add-wire-remote-addon.js +66 -0
  21. package/dist/add/add-workflow-graph.js +32 -3
  22. package/dist/add/add-workflow.js +9 -4
  23. package/dist/error-codes.d.ts +3 -0
  24. package/dist/error-codes.js +4 -0
  25. package/dist/inspector.js +11 -5
  26. package/dist/types.d.ts +19 -13
  27. package/dist/utils/custom-types-generator.js +2 -1
  28. package/dist/utils/ensure-function-metadata.d.ts +15 -0
  29. package/dist/utils/ensure-function-metadata.js +24 -0
  30. package/dist/utils/filter-inspector-state.js +9 -0
  31. package/dist/utils/get-property-value.d.ts +7 -2
  32. package/dist/utils/get-property-value.js +48 -1
  33. package/dist/utils/load-addon-functions-meta.js +81 -6
  34. package/dist/utils/permissions.d.ts +1 -21
  35. package/dist/utils/permissions.js +17 -108
  36. package/dist/utils/post-process.d.ts +30 -1
  37. package/dist/utils/post-process.js +150 -72
  38. package/dist/utils/schema-generator.js +19 -4
  39. package/dist/utils/serialize-inspector-state.d.ts +13 -8
  40. package/dist/utils/serialize-inspector-state.js +12 -6
  41. package/dist/utils/serialize-permissions-groups-meta.d.ts +0 -2
  42. package/dist/utils/serialize-permissions-groups-meta.js +0 -26
  43. package/dist/utils/workflow/derive-workflow-plan.js +9 -3
  44. package/dist/utils/workflow/dsl/deserialize-dsl-workflow.js +373 -91
  45. package/dist/utils/workflow/dsl/extract-dsl-workflow.js +274 -100
  46. package/dist/utils/workflow/dsl/patterns.d.ts +4 -0
  47. package/dist/utils/workflow/dsl/patterns.js +11 -0
  48. package/dist/utils/workflow/graph/convert-dsl-to-graph.js +76 -5
  49. package/dist/utils/workflow/graph/finalize-workflows.d.ts +7 -0
  50. package/dist/utils/workflow/graph/finalize-workflows.js +11 -2
  51. package/dist/utils/workflow/graph/serialize-workflow-graph.d.ts +2 -0
  52. package/dist/utils/workflow/graph/serialize-workflow-graph.js +4 -0
  53. package/dist/utils/workflow/graph/workflow-graph.types.d.ts +8 -4
  54. package/dist/visit.js +4 -0
  55. package/package.json +3 -3
  56. package/run-tests.sh +1 -1
  57. package/src/add/add-addon-bans.ts +1 -0
  58. package/src/add/add-ai-agent.test.ts +87 -0
  59. package/src/add/add-ai-agent.ts +122 -0
  60. package/src/add/add-credential.ts +8 -0
  61. package/src/add/add-functions.ts +10 -12
  62. package/src/add/add-gateway.ts +11 -0
  63. package/src/add/add-http-route.ts +2 -8
  64. package/src/add/add-keyed-wiring.ts +2 -0
  65. package/src/add/add-mcp-prompt.ts +0 -1
  66. package/src/add/add-mcp-resource.ts +0 -1
  67. package/src/add/add-permission.ts +4 -242
  68. package/src/add/add-queue-worker.ts +11 -0
  69. package/src/add/add-schedule.ts +11 -0
  70. package/src/add/add-scope.test.ts +346 -0
  71. package/src/add/add-scope.ts +225 -0
  72. package/src/add/add-trigger.ts +11 -0
  73. package/src/add/add-wire-remote-addon.ts +77 -0
  74. package/src/add/add-workflow-edge-cases.test.ts +201 -0
  75. package/src/add/add-workflow-fanout.test.ts +60 -0
  76. package/src/add/add-workflow-graph-input.test.ts +94 -0
  77. package/src/add/add-workflow-graph-notes.test.ts +74 -0
  78. package/src/add/add-workflow-graph.ts +35 -3
  79. package/src/add/add-workflow-on-error.test.ts +118 -0
  80. package/src/add/add-workflow-return-switch.test.ts +121 -0
  81. package/src/add/add-workflow-silent-drops.test.ts +163 -0
  82. package/src/add/add-workflow-sleep-expression.test.ts +97 -0
  83. package/src/add/add-workflow.ts +9 -4
  84. package/src/add/config-value-metadata.test.ts +169 -0
  85. package/src/add/inline-wiring-function.test.ts +104 -0
  86. package/src/add/validate-workflow-graph-addons.test.ts +102 -0
  87. package/src/error-codes.ts +5 -0
  88. package/src/inspector.ts +14 -4
  89. package/src/types.ts +16 -17
  90. package/src/utils/custom-types-generator.test.ts +26 -1
  91. package/src/utils/custom-types-generator.ts +2 -1
  92. package/src/utils/ensure-function-metadata.ts +42 -0
  93. package/src/utils/filter-inspector-state.test.ts +0 -2
  94. package/src/utils/filter-inspector-state.ts +9 -0
  95. package/src/utils/get-property-value.test.ts +141 -0
  96. package/src/utils/get-property-value.ts +62 -1
  97. package/src/utils/load-addon-functions-meta.test.ts +157 -0
  98. package/src/utils/load-addon-functions-meta.ts +94 -6
  99. package/src/utils/load-addon-scopes.test.ts +138 -0
  100. package/src/utils/permissions.test.ts +7 -232
  101. package/src/utils/permissions.ts +20 -160
  102. package/src/utils/post-process.test.ts +269 -4
  103. package/src/utils/post-process.ts +216 -95
  104. package/src/utils/schema-generator.test.ts +164 -0
  105. package/src/utils/schema-generator.ts +26 -3
  106. package/src/utils/serialize-inspector-state.ts +22 -25
  107. package/src/utils/serialize-permissions-groups-meta.ts +0 -28
  108. package/src/utils/workflow/derive-workflow-plan.test.ts +41 -3
  109. package/src/utils/workflow/derive-workflow-plan.ts +11 -4
  110. package/src/utils/workflow/dsl/deserialize-dsl-workflow.ts +480 -119
  111. package/src/utils/workflow/dsl/deserialize-fanout-body.test.ts +71 -0
  112. package/src/utils/workflow/dsl/deserialize-fanout-fidelity.test.ts +99 -0
  113. package/src/utils/workflow/dsl/deserialize-graph-next.test.ts +161 -0
  114. package/src/utils/workflow/dsl/deserialize-roundtrip-bindings.test.ts +121 -0
  115. package/src/utils/workflow/dsl/deserialize-roundtrip-values.test.ts +116 -0
  116. package/src/utils/workflow/dsl/deserialize-roundtrip.test.ts +145 -0
  117. package/src/utils/workflow/dsl/extract-dsl-workflow.ts +311 -105
  118. package/src/utils/workflow/dsl/patterns.ts +18 -0
  119. package/src/utils/workflow/graph/convert-dsl-to-graph.ts +82 -10
  120. package/src/utils/workflow/graph/fanout-node-identity.test.ts +105 -0
  121. package/src/utils/workflow/graph/finalize-workflows.test.ts +50 -0
  122. package/src/utils/workflow/graph/finalize-workflows.ts +13 -2
  123. package/src/utils/workflow/graph/serialize-workflow-graph.ts +6 -0
  124. package/src/utils/workflow/graph/workflow-graph.types.ts +11 -2
  125. package/src/visit.ts +4 -0
  126. package/tsconfig.tsbuildinfo +1 -1
@@ -112,14 +112,6 @@ export interface SerializableInspectorState {
112
112
  : never,
113
113
  ]
114
114
  >
115
- routePermissions: Array<
116
- [
117
- string,
118
- InspectorState['http']['routePermissions'] extends Map<string, infer V>
119
- ? V
120
- : never,
121
- ]
122
- >
123
115
  }
124
116
  channels: {
125
117
  files: string[]
@@ -154,6 +146,8 @@ export interface SerializableInspectorState {
154
146
  internalFiles: Array<[string, { path: string; exportedName: string }]>
155
147
  exposedMeta: InspectorState['rpc']['exposedMeta']
156
148
  exposedFiles: Array<[string, { path: string; exportedName: string }]>
149
+ remoteMeta: InspectorState['rpc']['remoteMeta']
150
+ remoteFiles: Array<[string, { path: string; exportedName: string }]>
157
151
  invokedFunctions: string[]
158
152
  invokedFunctionsByFile?: Array<[string, string[]]>
159
153
  usedAddons: string[]
@@ -163,6 +157,10 @@ export interface SerializableInspectorState {
163
157
  {
164
158
  package: string
165
159
  rpcEndpoint?: string
160
+ remote?: boolean
161
+ hasAuth?: boolean
162
+ authCredentialId?: string
163
+ authSecretId?: string
166
164
  secretOverrides?: Record<string, string>
167
165
  variableOverrides?: Record<string, string>
168
166
  credentialOverrides?: Record<string, string>
@@ -203,6 +201,10 @@ export interface SerializableInspectorState {
203
201
  definitions: InspectorState['credentials']['definitions']
204
202
  files: string[]
205
203
  }
204
+ scopes: {
205
+ definitions: InspectorState['scopes']['definitions']
206
+ files: string[]
207
+ }
206
208
  variables: {
207
209
  definitions: InspectorState['variables']['definitions']
208
210
  files: string[]
@@ -244,17 +246,6 @@ export interface SerializableInspectorState {
244
246
  permissions: {
245
247
  definitions: InspectorState['permissions']['definitions']
246
248
  instances: InspectorState['permissions']['instances']
247
- tagPermissions: Array<
248
- [
249
- string,
250
- InspectorState['permissions']['tagPermissions'] extends Map<
251
- string,
252
- infer V
253
- >
254
- ? V
255
- : never,
256
- ]
257
- >
258
249
  }
259
250
  serviceAggregation: {
260
251
  requiredServices: string[]
@@ -344,7 +335,6 @@ export function serializeInspectorState(
344
335
  meta: state.http.meta,
345
336
  files: Array.from(state.http.files),
346
337
  routeMiddleware: Array.from(state.http.routeMiddleware.entries()),
347
- routePermissions: Array.from(state.http.routePermissions.entries()),
348
338
  },
349
339
  channels: {
350
340
  files: Array.from(state.channels.files),
@@ -379,6 +369,8 @@ export function serializeInspectorState(
379
369
  internalFiles: Array.from(state.rpc.internalFiles.entries()),
380
370
  exposedMeta: state.rpc.exposedMeta,
381
371
  exposedFiles: Array.from(state.rpc.exposedFiles.entries()),
372
+ remoteMeta: state.rpc.remoteMeta,
373
+ remoteFiles: Array.from(state.rpc.remoteFiles.entries()),
382
374
  invokedFunctions: Array.from(state.rpc.invokedFunctions),
383
375
  invokedFunctionsByFile: Array.from(
384
376
  (
@@ -423,6 +415,10 @@ export function serializeInspectorState(
423
415
  definitions: state.credentials.definitions,
424
416
  files: Array.from(state.credentials.files),
425
417
  },
418
+ scopes: {
419
+ definitions: state.scopes.definitions,
420
+ files: Array.from(state.scopes.files),
421
+ },
426
422
  variables: {
427
423
  definitions: state.variables.definitions,
428
424
  files: Array.from(state.variables.files),
@@ -446,7 +442,6 @@ export function serializeInspectorState(
446
442
  permissions: {
447
443
  definitions: state.permissions.definitions,
448
444
  instances: state.permissions.instances,
449
- tagPermissions: Array.from(state.permissions.tagPermissions.entries()),
450
445
  },
451
446
  serviceAggregation: {
452
447
  requiredServices: Array.from(state.serviceAggregation.requiredServices),
@@ -536,7 +531,6 @@ export function deserializeInspectorState(
536
531
  meta: data.http.meta,
537
532
  files: new Set(data.http.files),
538
533
  routeMiddleware: new Map(data.http.routeMiddleware),
539
- routePermissions: new Map(data.http.routePermissions),
540
534
  },
541
535
  channels: {
542
536
  files: new Set(data.channels.files),
@@ -571,6 +565,8 @@ export function deserializeInspectorState(
571
565
  internalFiles: new Map(data.rpc.internalFiles),
572
566
  exposedMeta: data.rpc.exposedMeta,
573
567
  exposedFiles: new Map(data.rpc.exposedFiles),
568
+ remoteMeta: data.rpc.remoteMeta ?? {},
569
+ remoteFiles: new Map(data.rpc.remoteFiles ?? []),
574
570
  invokedFunctions: new Set(data.rpc.invokedFunctions),
575
571
  invokedFunctionsByFile: new Map(
576
572
  (data.rpc.invokedFunctionsByFile || []).map(
@@ -613,6 +609,10 @@ export function deserializeInspectorState(
613
609
  definitions: data.credentials?.definitions || [],
614
610
  files: new Set(data.credentials?.files || []),
615
611
  },
612
+ scopes: {
613
+ definitions: data.scopes?.definitions || [],
614
+ files: new Set(data.scopes?.files || []),
615
+ },
616
616
  variables: {
617
617
  definitions: data.variables?.definitions || [],
618
618
  files: new Set(data.variables?.files || []),
@@ -634,7 +634,6 @@ export function deserializeInspectorState(
634
634
  permissions: {
635
635
  definitions: data.permissions.definitions,
636
636
  instances: data.permissions.instances || {},
637
- tagPermissions: new Map(data.permissions.tagPermissions),
638
637
  },
639
638
  serviceAggregation: {
640
639
  requiredServices: new Set(data.serviceAggregation.requiredServices),
@@ -654,8 +653,6 @@ export function deserializeInspectorState(
654
653
  },
655
654
  permissionsGroupsMeta: data.permissionsGroupsMeta || {
656
655
  definitions: {},
657
- httpGroups: {},
658
- tagGroups: {},
659
656
  },
660
657
  requiredSchemas: new Set(data.requiredSchemas || []),
661
658
  openAPISpec: data.openAPISpec || null,
@@ -1,35 +1,7 @@
1
1
  import type { InspectorState } from '../types.js'
2
2
 
3
3
  export const serializePermissionsGroupsMeta = (state: InspectorState) => {
4
- const httpGroups: Record<string, any> = {}
5
- for (const [pattern, meta] of state.http.routePermissions.entries()) {
6
- httpGroups[pattern] = {
7
- exportName: meta.exportName,
8
- sourceFile: meta.sourceFile,
9
- position: meta.position,
10
- services: meta.services,
11
- count: meta.count,
12
- instanceIds: meta.instanceIds,
13
- isFactory: meta.isFactory,
14
- }
15
- }
16
-
17
- const tagGroups: Record<string, any> = {}
18
- for (const [tag, meta] of state.permissions.tagPermissions.entries()) {
19
- tagGroups[tag] = {
20
- exportName: meta.exportName,
21
- sourceFile: meta.sourceFile,
22
- position: meta.position,
23
- services: meta.services,
24
- count: meta.count,
25
- instanceIds: meta.instanceIds,
26
- isFactory: meta.isFactory,
27
- }
28
- }
29
-
30
4
  return {
31
5
  definitions: state.permissions.definitions,
32
- httpGroups,
33
- tagGroups,
34
6
  }
35
7
  }
@@ -84,7 +84,11 @@ describe('deriveWorkflowPlan', () => {
84
84
  } as WorkflowStepMeta,
85
85
  ])
86
86
  assert.equal(plan.deterministic, false)
87
- assert.equal(plan.plannedSteps, undefined, 'loop count is runtime-dependent')
87
+ assert.equal(
88
+ plan.plannedSteps,
89
+ undefined,
90
+ 'loop count is runtime-dependent'
91
+ )
88
92
  })
89
93
 
90
94
  test('a fanout nested inside a branch still suppresses the plan', () => {
@@ -133,8 +137,42 @@ describe('deriveWorkflowPlan', () => {
133
137
  { stepName: 'build' },
134
138
  { stepName: '__workflow_suspend:building', displayName: 'Building' },
135
139
  { stepName: 'publish' },
136
- { stepName: '__workflow_suspend:awaiting_approval', displayName: 'Awaiting approval' },
137
- { stepName: '__workflow_suspend:building-image', displayName: 'Building image' },
140
+ {
141
+ stepName: '__workflow_suspend:awaiting_approval',
142
+ displayName: 'Awaiting approval',
143
+ },
144
+ {
145
+ stepName: '__workflow_suspend:building-image',
146
+ displayName: 'Building image',
147
+ },
148
+ ])
149
+ })
150
+
151
+ test('approval steps appear in the plan with __workflow_approval: key and sentence-case displayName', () => {
152
+ const plan = deriveWorkflowPlan([
153
+ rpc('build'),
154
+ { type: 'approval', reason: 'awaiting_approval' } as WorkflowStepMeta,
155
+ rpc('publish'),
156
+ ])
157
+ assert.equal(plan.deterministic, true)
158
+ assert.deepEqual(plan.plannedSteps, [
159
+ { stepName: 'build' },
160
+ {
161
+ stepName: '__workflow_approval:awaiting_approval',
162
+ displayName: 'Awaiting approval',
163
+ },
164
+ { stepName: 'publish' },
165
+ ])
166
+ })
167
+
168
+ test('an approval is namespaced apart from a suspend sharing its reason', () => {
169
+ const plan = deriveWorkflowPlan([
170
+ { type: 'suspend', reason: 'sign_off' } as WorkflowStepMeta,
171
+ { type: 'approval', reason: 'sign_off' } as WorkflowStepMeta,
138
172
  ])
173
+ assert.deepEqual(
174
+ plan.plannedSteps.map((s) => s.stepName),
175
+ ['__workflow_suspend:sign_off', '__workflow_approval:sign_off']
176
+ )
139
177
  })
140
178
  })
@@ -63,9 +63,7 @@ function containsConditional(steps: WorkflowStepMeta[]): boolean {
63
63
  * e.g. "awaiting_approval" → "Awaiting approval", "building-image" → "Building image"
64
64
  */
65
65
  function reasonToLabel(reason: string): string {
66
- return reason
67
- .replace(/[-_]/g, ' ')
68
- .replace(/^(.)/, (c) => c.toUpperCase())
66
+ return reason.replace(/[-_]/g, ' ').replace(/^(.)/, (c) => c.toUpperCase())
69
67
  }
70
68
 
71
69
  /** Flatten named steps (rpc/inline/sleep/parallel children) in source order. */
@@ -88,13 +86,22 @@ function collectNamedSteps(steps: WorkflowStepMeta[]): WorkflowPlannedStep[] {
88
86
  displayName: reasonToLabel(step.reason),
89
87
  })
90
88
  break
89
+ case 'approval':
90
+ // Same as suspend, but namespaced `__workflow_approval:` to match the
91
+ // runtime's separate step key.
92
+ planned.push({
93
+ stepName: `__workflow_approval:${step.reason}`,
94
+ displayName: reasonToLabel(step.reason),
95
+ })
96
+ break
91
97
  case 'parallel':
92
98
  for (const child of step.children) {
93
99
  planned.push({ stepName: child.stepName })
94
100
  }
95
101
  break
96
102
  case 'branch':
97
- for (const b of step.branches) planned.push(...collectNamedSteps(b.steps))
103
+ for (const b of step.branches)
104
+ planned.push(...collectNamedSteps(b.steps))
98
105
  if (step.elseSteps) planned.push(...collectNamedSteps(step.elseSteps))
99
106
  break
100
107
  case 'switch':