@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
@@ -91,6 +91,7 @@ function convertStepToNode(
91
91
  const node: FunctionNode = {
92
92
  nodeId,
93
93
  rpcName: step.rpcName,
94
+ stepName: step.stepName,
94
95
  next: nextNodeId,
95
96
  }
96
97
  if (step.actor) {
@@ -116,9 +117,24 @@ function convertStepToNode(
116
117
  if (step.options) {
117
118
  node.options = {
118
119
  retries: step.options.retries,
119
- retryDelay: step.options.retryDelay?.toString(),
120
+ retryDelay: step.options.retryDelay,
120
121
  }
121
122
  }
123
+ // An onError handler is written as an rpc name, but the graph routes to
124
+ // node ids — materialise a node for it so the console has something to
125
+ // draw the error edge to, exactly as in a hand-authored graph.
126
+ if (step.options?.onError) {
127
+ const handlerId = `${nodeId}_onError`
128
+ node.onError = handlerId
129
+ return [
130
+ node,
131
+ {
132
+ nodeId: handlerId,
133
+ rpcName: step.options.onError,
134
+ stepName: `${step.stepName} (on error)`,
135
+ } satisfies FunctionNode,
136
+ ]
137
+ }
122
138
  return [node]
123
139
  }
124
140
 
@@ -126,7 +142,37 @@ function convertStepToNode(
126
142
  const node: FlowNode = {
127
143
  nodeId,
128
144
  flow: 'sleep',
145
+ stepName: step.stepName,
129
146
  duration: step.duration,
147
+ expression: step.expression,
148
+ next: nextNodeId,
149
+ }
150
+ return [node]
151
+ }
152
+
153
+ case 'suspend': {
154
+ // A suspend yields no value, but it must still be a node: the previous
155
+ // step's `next` points at it, so omitting it dead-ends traversal and
156
+ // silently deletes every step that follows.
157
+ const node: FlowNode = {
158
+ nodeId,
159
+ flow: 'suspend',
160
+ reason: step.reason,
161
+ next: nextNodeId,
162
+ }
163
+ return [node]
164
+ }
165
+
166
+ case 'approval': {
167
+ // Unlike `suspend` — which has no output and so is deliberately absent
168
+ // from the graph — an approval yields a value a later step can reference,
169
+ // so it must be a real node for $ref resolution and graphHash to see it.
170
+ const node: FlowNode = {
171
+ nodeId,
172
+ flow: 'approval',
173
+ reason: step.reason,
174
+ outputVar: step.outputVar,
175
+ expiry: step.expiry,
130
176
  next: nextNodeId,
131
177
  }
132
178
  return [node]
@@ -199,16 +245,32 @@ function convertStepToNode(
199
245
  entry: string
200
246
  }> = []
201
247
 
248
+ // A case with no statements falls through to the next one. Dropping it
249
+ // would lose the value entirely, so it is held until an entry exists.
250
+ let fallingThrough: Array<{ value?: unknown; expression?: string }> = []
251
+
202
252
  for (let i = 0; i < step.cases.length; i++) {
203
253
  const caseSteps = convertStepsToNodes(
204
254
  step.cases[i].steps,
205
255
  `${nodeId}_case${i}`
206
256
  )
207
- if (caseSteps.length > 0) {
257
+ if (caseSteps.length === 0) {
258
+ fallingThrough.push({
259
+ value: step.cases[i].value,
260
+ expression: step.cases[i].expression,
261
+ })
262
+ continue
263
+ }
264
+ {
265
+ const entry = caseSteps[0].nodeId
266
+ for (const pending of fallingThrough) {
267
+ cases.push({ ...pending, entry })
268
+ }
269
+ fallingThrough = []
208
270
  cases.push({
209
271
  value: step.cases[i].value,
210
272
  expression: step.cases[i].expression,
211
- entry: caseSteps[0].nodeId,
273
+ entry,
212
274
  })
213
275
  // Link last case node to next (unless terminal flow)
214
276
  if (nextNodeId) {
@@ -238,6 +300,14 @@ function convertStepToNode(
238
300
  }
239
301
  }
240
302
 
303
+ // Cases falling through past the last one land in default, or exit.
304
+ const trailingEntry = defaultEntry ?? nextNodeId
305
+ if (trailingEntry) {
306
+ for (const pending of fallingThrough) {
307
+ cases.push({ ...pending, entry: trailingEntry })
308
+ }
309
+ }
310
+
241
311
  const node: FlowNode = {
242
312
  nodeId,
243
313
  flow: 'switch',
@@ -279,13 +349,13 @@ function convertStepToNode(
279
349
  }
280
350
 
281
351
  case 'fanout': {
282
- // Convert child step
283
- const childNodes = convertStepToNode(
284
- step.child,
285
- 0,
286
- [step.child],
287
- `${nodeId}_item`
288
- )
352
+ // Convert the per-iteration body into a `next`-chained sequence
353
+ const childNodes: SerializedGraphNode[] = []
354
+ for (let i = 0; i < step.body.length; i++) {
355
+ childNodes.push(
356
+ ...convertStepToNode(step.body[i], i, step.body, `${nodeId}_item`)
357
+ )
358
+ }
289
359
 
290
360
  const node: FlowNode = {
291
361
  nodeId,
@@ -333,6 +403,7 @@ function convertStepToNode(
333
403
  nodeId,
334
404
  flow: 'return',
335
405
  outputs: step.outputs,
406
+ spread: step.spread,
336
407
  }
337
408
  return [node]
338
409
  }
@@ -352,6 +423,7 @@ function convertStepToNode(
352
423
  flow: 'set',
353
424
  variable: step.variable,
354
425
  value: step.value,
426
+ expression: step.expression,
355
427
  next: nextNodeId,
356
428
  }
357
429
  return [node]
@@ -0,0 +1,105 @@
1
+ import { strict as assert } from 'assert'
2
+ import { describe, test } from 'node:test'
3
+ import { mkdtemp, rm, writeFile } from 'node:fs/promises'
4
+ import { tmpdir } from 'node:os'
5
+ import { join } from 'node:path'
6
+ import { inspect } from '../../../inspector.js'
7
+ import type { InspectorLogger } from '../../../types.js'
8
+
9
+ const STEP_FILE = [
10
+ "import { pikkuSessionlessFunc } from '@pikku/core'",
11
+ 'export const notify = pikkuSessionlessFunc({',
12
+ " func: async () => ({ id: 'n' }),",
13
+ '})',
14
+ ].join('\n')
15
+
16
+ async function nodesFor(body: string): Promise<Record<string, any>> {
17
+ const logger = {
18
+ debug: () => {},
19
+ info: () => {},
20
+ warn: () => {},
21
+ error: () => {},
22
+ diagnostic: () => {},
23
+ critical: () => {},
24
+ hasCriticalErrors: () => false,
25
+ } as unknown as InspectorLogger
26
+
27
+ const rootDir = await mkdtemp(join(tmpdir(), 'pikku-fid-'))
28
+ const stepFile = join(rootDir, 'w.steps.ts')
29
+ const wfFile = join(rootDir, 'w.workflow.ts')
30
+ await writeFile(stepFile, STEP_FILE)
31
+ await writeFile(
32
+ wfFile,
33
+ [
34
+ "import { pikkuWorkflowFunc } from '@pikku/core/workflow'",
35
+ 'export const wf = pikkuWorkflowFunc(async (_, data: any, { workflow }) => {',
36
+ body,
37
+ '})',
38
+ ].join('\n')
39
+ )
40
+ try {
41
+ const state: any = await inspect(logger, [stepFile, wfFile], { rootDir })
42
+ const gm = state.workflows.graphMeta
43
+ const graph = (
44
+ gm instanceof Map ? [...gm.values()] : Object.values(gm)
45
+ )[0] as any
46
+ return graph?.nodes ?? {}
47
+ } finally {
48
+ await rm(rootDir, { recursive: true, force: true })
49
+ }
50
+ }
51
+
52
+ describe('fanout node identity — a body step must not overwrite its own loop', () => {
53
+ test('the fanout node survives alongside its named body step', async () => {
54
+ const nodes = await nodesFor(
55
+ [
56
+ ' await Promise.all(',
57
+ ' data.users.map(async (u: any) => {',
58
+ " await workflow.do('Notify', 'notify', { id: u.id })",
59
+ ' })',
60
+ ' )',
61
+ ' return { ok: true }',
62
+ ].join('\n')
63
+ )
64
+
65
+ const fanout = Object.values(nodes).find(
66
+ (n: any) => n.flow === 'fanout'
67
+ ) as any
68
+ assert.ok(
69
+ fanout,
70
+ `the loop must be in the graph — without it the workflow renders as a single call, got: ${JSON.stringify(nodes)}`
71
+ )
72
+ assert.ok(
73
+ fanout.childEntry && nodes[fanout.childEntry],
74
+ 'the fanout must point at a body entry node that exists'
75
+ )
76
+ assert.notEqual(
77
+ fanout.nodeId,
78
+ fanout.childEntry,
79
+ 'a fanout and its body entry must not share a node id'
80
+ )
81
+ assert.equal((nodes[fanout.childEntry] as any).rpcName, 'notify')
82
+ })
83
+
84
+ test('the step following a fanout is still reachable', async () => {
85
+ const nodes = await nodesFor(
86
+ [
87
+ ' await Promise.all(',
88
+ ' data.users.map(async (u: any) => {',
89
+ " await workflow.do('Notify', 'notify', { id: u.id })",
90
+ ' })',
91
+ ' )',
92
+ ' return { ok: true }',
93
+ ].join('\n')
94
+ )
95
+
96
+ const fanout = Object.values(nodes).find(
97
+ (n: any) => n.flow === 'fanout'
98
+ ) as any
99
+ assert.ok(fanout, 'a fanout node should exist')
100
+ assert.ok(
101
+ fanout.next && nodes[fanout.next],
102
+ `the return after the loop must stay reachable, got: ${JSON.stringify(nodes)}`
103
+ )
104
+ })
105
+ })
@@ -0,0 +1,50 @@
1
+ import { test } from 'node:test'
2
+ import assert from 'node:assert'
3
+ import { computeGraphHash } from './finalize-workflows.js'
4
+ import type {
5
+ SerializedWorkflowGraph,
6
+ FunctionNode,
7
+ } from './workflow-graph.types.js'
8
+
9
+ function graph(
10
+ overrides: Partial<SerializedWorkflowGraph> = {},
11
+ nodeOverrides: Partial<FunctionNode> = {}
12
+ ): SerializedWorkflowGraph {
13
+ const node: FunctionNode = {
14
+ nodeId: 'a',
15
+ rpcName: 'doThing',
16
+ input: { x: { $ref: 'trigger', path: 'x' } },
17
+ next: 'b',
18
+ ...nodeOverrides,
19
+ }
20
+ return {
21
+ name: 'wf',
22
+ pikkuFuncId: 'wf',
23
+ source: 'graph',
24
+ nodes: { a: node, b: { nodeId: 'b', rpcName: 'finish' } },
25
+ entryNodeIds: ['a'],
26
+ ...overrides,
27
+ }
28
+ }
29
+
30
+ test('computeGraphHash: node-level notes do not change the hash', () => {
31
+ const without = computeGraphHash(graph())
32
+ const withNote = computeGraphHash(
33
+ graph({}, { notes: 'imported node "Do Thing"' })
34
+ )
35
+ assert.strictEqual(withNote, without)
36
+ })
37
+
38
+ test('computeGraphHash: graph-level notes do not change the hash', () => {
39
+ const without = computeGraphHash(graph())
40
+ const withNotes = computeGraphHash(
41
+ graph({ notes: ['sticky note one', 'sticky note two'] })
42
+ )
43
+ assert.strictEqual(withNotes, without)
44
+ })
45
+
46
+ test('computeGraphHash: a topology change DOES change the hash', () => {
47
+ const base = computeGraphHash(graph())
48
+ const changed = computeGraphHash(graph({}, { next: 'c' }))
49
+ assert.notStrictEqual(changed, base)
50
+ })
@@ -102,12 +102,23 @@ function computeStepHashes(
102
102
  }
103
103
  }
104
104
 
105
- function computeGraphHash(graph: SerializedWorkflowGraph): string {
105
+ /**
106
+ * Hash of graph topology only. `notes` (node- and graph-level) is deliberately
107
+ * excluded so editing documentation never changes the hash / marks the workflow
108
+ * as a new version.
109
+ */
110
+ export function computeGraphHash(graph: SerializedWorkflowGraph): string {
111
+ const nodesForHash = Object.fromEntries(
112
+ Object.entries(graph.nodes).map(([nodeId, node]) => {
113
+ const { notes: _notes, ...rest } = node as { notes?: string }
114
+ return [nodeId, rest]
115
+ })
116
+ )
106
117
  return hashString(
107
118
  canonicalJSON({
108
119
  source: graph.source,
109
120
  context: graph.context,
110
- nodes: graph.nodes,
121
+ nodes: nodesForHash,
111
122
  entryNodeIds: graph.entryNodeIds,
112
123
  }),
113
124
  12
@@ -89,12 +89,14 @@ export function serializeWorkflowGraph(
89
89
  input?: (ref: any) => Record<string, unknown>
90
90
  next?: string | string[] | Record<string, string | string[]>
91
91
  onError?: string | string[]
92
+ notes?: string
92
93
  }
93
94
  >
94
95
  },
95
96
  options?: {
96
97
  description?: string
97
98
  tags?: string[]
99
+ notes?: string[]
98
100
  }
99
101
  ): SerializedWorkflowGraph {
100
102
  const nodes: Record<string, SerializedGraphNode> = {}
@@ -149,6 +151,9 @@ export function serializeWorkflowGraph(
149
151
  next: serializeNext(node.next),
150
152
  onError: node.onError,
151
153
  }
154
+ if (node.notes !== undefined) {
155
+ funcNode.notes = node.notes
156
+ }
152
157
  nodes[nodeId] = funcNode
153
158
 
154
159
  // Entry nodes have no incoming edges
@@ -163,6 +168,7 @@ export function serializeWorkflowGraph(
163
168
  source: 'graph' as const,
164
169
  description: options?.description,
165
170
  tags: options?.tags,
171
+ notes: options?.notes,
166
172
  nodes,
167
173
  entryNodeIds,
168
174
  }
@@ -76,6 +76,9 @@ export type SerializedNext =
76
76
  /** Default target if no conditions match */
77
77
  default?: string | string[]
78
78
  }
79
+ // Key-based branching: the running node picks a key via `graph.branch(key)`,
80
+ // routing to `next[key]`. Keys are branch/output identifiers, not predicates.
81
+ | Record<string, string | string[]>
79
82
 
80
83
  /**
81
84
  * Node execution options
@@ -83,8 +86,8 @@ export type SerializedNext =
83
86
  export interface NodeOptions {
84
87
  /** Number of retry attempts on failure */
85
88
  retries?: number
86
- /** Delay between retries (e.g., '1s', '5s') */
87
- retryDelay?: string
89
+ /** Delay between retries (e.g., '1s', '5s', or a number of milliseconds) */
90
+ retryDelay?: string | number
88
91
  /** Timeout for node execution (e.g., '30s', '5m') */
89
92
  timeout?: string
90
93
  }
@@ -94,6 +97,8 @@ export interface NodeOptions {
94
97
  */
95
98
  export type FlowType =
96
99
  | 'sleep'
100
+ | 'suspend'
101
+ | 'approval'
97
102
  | 'branch'
98
103
  | 'parallel'
99
104
  | 'fanout'
@@ -128,6 +133,8 @@ interface BaseNode {
128
133
  onError?: string | string[]
129
134
  /** Execution options */
130
135
  options?: NodeOptions
136
+ /** Free-text node documentation. Non-semantic — excluded from graphHash. */
137
+ notes?: string
131
138
  }
132
139
 
133
140
  /**
@@ -209,6 +216,8 @@ export interface SerializedWorkflowGraph {
209
216
  context?: WorkflowContext
210
217
  /** Serialized nodes */
211
218
  nodes: Record<string, SerializedGraphNode>
219
+ /** Graph-level free-text notes (e.g. imported sticky notes). Non-semantic — excluded from graphHash. */
220
+ notes?: string[]
212
221
  /** Entry node(s) - first nodes to execute */
213
222
  entryNodeIds: string[]
214
223
  /** Hash of graph topology (nodes, edges, input mappings) */
package/src/visit.ts CHANGED
@@ -20,12 +20,14 @@ import { addChannel } from './add/add-channel.js'
20
20
  import { addGateway } from './add/add-gateway.js'
21
21
  import { addRPCInvocations } from './add/add-rpc-invocations.js'
22
22
  import { addWireAddon } from './add/add-wire-addon.js'
23
+ import { addWireRemoteAddon } from './add/add-wire-remote-addon.js'
23
24
  import { addMiddleware } from './add/add-middleware.js'
24
25
  import { addPermission } from './add/add-permission.js'
25
26
  import { addCLI, addCLIRenderers } from './add/add-cli.js'
26
27
  import { addAuth } from './add/add-auth.js'
27
28
  import { addSecret } from './add/add-secret.js'
28
29
  import { addCredential } from './add/add-credential.js'
30
+ import { addScope } from './add/add-scope.js'
29
31
  import { addVariable } from './add/add-variable.js'
30
32
  import { addWorkflowGraph } from './add/add-workflow-graph.js'
31
33
  import { addAIAgent } from './add/add-ai-agent.js'
@@ -96,6 +98,7 @@ export const visitSetup = (
96
98
 
97
99
  addRPCInvocations(node, state, logger)
98
100
  addWireAddon(node, state, logger)
101
+ addWireRemoteAddon(node, state, logger)
99
102
  addMiddleware(logger, node, checker, state, options)
100
103
  addPermission(logger, node, checker, state, options)
101
104
  addApprovalDescription(logger, node, checker, state, options)
@@ -147,6 +150,7 @@ export const visitRoutes = (
147
150
  addAuth(logger, node, checker, state, nextOptions)
148
151
  addSecret(logger, node, checker, state, nextOptions)
149
152
  addCredential(logger, node, checker, state, nextOptions)
153
+ addScope(logger, node, checker, state, nextOptions)
150
154
  addVariable(logger, node, checker, state, nextOptions)
151
155
 
152
156
  addHTTPRoute(logger, node, checker, state, nextOptions)