@probelabs/visor 0.1.148 → 0.1.149

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/defaults/assistant.yaml +2141 -0
  2. package/defaults/code-talk.yaml +1250 -0
  3. package/defaults/intent-router.yaml +478 -0
  4. package/dist/defaults/assistant.yaml +2141 -0
  5. package/dist/defaults/code-talk.yaml +1250 -0
  6. package/dist/defaults/intent-router.yaml +478 -0
  7. package/dist/index.js +17 -4
  8. package/dist/output/traces/{run-2026-03-02T18-32-11-359Z.ndjson → run-2026-03-03T07-19-07-543Z.ndjson} +84 -84
  9. package/dist/{traces/run-2026-03-02T18-32-55-702Z.ndjson → output/traces/run-2026-03-03T07-19-50-933Z.ndjson} +1866 -1187
  10. package/dist/sdk/{check-provider-registry-35BPTY4W.mjs → check-provider-registry-IYSUDKPB.mjs} +7 -7
  11. package/dist/sdk/{check-provider-registry-DVQDGTOE.mjs → check-provider-registry-LVLC4EPF.mjs} +4 -4
  12. package/dist/sdk/{check-provider-registry-KHPY6LB4.mjs → check-provider-registry-X4OZJWPK.mjs} +4 -4
  13. package/dist/sdk/{chunk-6N6JRWCW.mjs → chunk-6EXCUX7Y.mjs} +10 -10
  14. package/dist/sdk/{chunk-S2YO4ZE3.mjs → chunk-BR7DYA3S.mjs} +2 -2
  15. package/dist/sdk/{chunk-DIND4ZCV.mjs → chunk-DNDS7R3N.mjs} +11 -1
  16. package/dist/sdk/{chunk-DIND4ZCV.mjs.map → chunk-DNDS7R3N.mjs.map} +1 -1
  17. package/dist/sdk/{chunk-IF2UD2KS.mjs → chunk-GFNXX64M.mjs} +18 -18
  18. package/dist/sdk/{chunk-AYQE4JCU.mjs → chunk-Q6EPAJ6Z.mjs} +3 -3
  19. package/dist/sdk/{chunk-H4AYMOAT.mjs → chunk-V6GI4U2M.mjs} +10 -10
  20. package/dist/sdk/{chunk-EGUHXVWS.mjs → chunk-VLUGLWLA.mjs} +2 -2
  21. package/dist/sdk/{chunk-EGUHXVWS.mjs.map → chunk-VLUGLWLA.mjs.map} +1 -1
  22. package/dist/sdk/{chunk-XNTBSV6M.mjs → chunk-YYZAN5NK.mjs} +3 -3
  23. package/dist/sdk/{config-G5UU4WXT.mjs → config-KQH254CA.mjs} +2 -2
  24. package/dist/sdk/{failure-condition-evaluator-I6QWFKV3.mjs → failure-condition-evaluator-LZ2AG5PY.mjs} +3 -3
  25. package/dist/sdk/{github-frontend-2MC77L7F.mjs → github-frontend-S523EEJB.mjs} +3 -3
  26. package/dist/sdk/{host-4F6I3ZXN.mjs → host-7YKRMOUJ.mjs} +2 -2
  27. package/dist/sdk/{routing-UT3BXBXH.mjs → routing-ZMBKWMVI.mjs} +4 -4
  28. package/dist/sdk/{schedule-tool-K3GQXCBN.mjs → schedule-tool-CDVUSZEG.mjs} +7 -7
  29. package/dist/sdk/{schedule-tool-SBXAEBDD.mjs → schedule-tool-EOMZFICZ.mjs} +4 -4
  30. package/dist/sdk/{schedule-tool-CONR4VW3.mjs → schedule-tool-NX75VKGA.mjs} +4 -4
  31. package/dist/sdk/{schedule-tool-handler-GFQCJAVZ.mjs → schedule-tool-handler-3FJHDIPG.mjs} +7 -7
  32. package/dist/sdk/{schedule-tool-handler-R7PG3VMR.mjs → schedule-tool-handler-KKN7XJYT.mjs} +4 -4
  33. package/dist/sdk/{schedule-tool-handler-YUC6CAXX.mjs → schedule-tool-handler-QNZG55DX.mjs} +4 -4
  34. package/dist/sdk/sdk.js +11 -1
  35. package/dist/sdk/sdk.js.map +1 -1
  36. package/dist/sdk/sdk.mjs +6 -6
  37. package/dist/sdk/{trace-helpers-J463EU4B.mjs → trace-helpers-EJUIOP6L.mjs} +2 -2
  38. package/dist/sdk/{workflow-check-provider-GJNGTS3F.mjs → workflow-check-provider-6ERNNCNA.mjs} +7 -7
  39. package/dist/sdk/{workflow-check-provider-DYSO3PML.mjs → workflow-check-provider-AGZ5JY2I.mjs} +4 -4
  40. package/dist/sdk/{workflow-check-provider-FIFFQDQU.mjs → workflow-check-provider-PTNUWM5W.mjs} +4 -4
  41. package/dist/sdk/{workflow-registry-AAD37XKZ.mjs → workflow-registry-MHUSKSD6.mjs} +2 -2
  42. package/dist/traces/{run-2026-03-02T18-32-11-359Z.ndjson → run-2026-03-03T07-19-07-543Z.ndjson} +84 -84
  43. package/dist/{output/traces/run-2026-03-02T18-32-55-702Z.ndjson → traces/run-2026-03-03T07-19-50-933Z.ndjson} +1866 -1187
  44. package/dist/workflow-registry.d.ts.map +1 -1
  45. package/package.json +1 -1
  46. /package/dist/sdk/{check-provider-registry-35BPTY4W.mjs.map → check-provider-registry-IYSUDKPB.mjs.map} +0 -0
  47. /package/dist/sdk/{check-provider-registry-DVQDGTOE.mjs.map → check-provider-registry-LVLC4EPF.mjs.map} +0 -0
  48. /package/dist/sdk/{check-provider-registry-KHPY6LB4.mjs.map → check-provider-registry-X4OZJWPK.mjs.map} +0 -0
  49. /package/dist/sdk/{chunk-6N6JRWCW.mjs.map → chunk-6EXCUX7Y.mjs.map} +0 -0
  50. /package/dist/sdk/{chunk-S2YO4ZE3.mjs.map → chunk-BR7DYA3S.mjs.map} +0 -0
  51. /package/dist/sdk/{chunk-IF2UD2KS.mjs.map → chunk-GFNXX64M.mjs.map} +0 -0
  52. /package/dist/sdk/{chunk-AYQE4JCU.mjs.map → chunk-Q6EPAJ6Z.mjs.map} +0 -0
  53. /package/dist/sdk/{chunk-H4AYMOAT.mjs.map → chunk-V6GI4U2M.mjs.map} +0 -0
  54. /package/dist/sdk/{chunk-XNTBSV6M.mjs.map → chunk-YYZAN5NK.mjs.map} +0 -0
  55. /package/dist/sdk/{config-G5UU4WXT.mjs.map → config-KQH254CA.mjs.map} +0 -0
  56. /package/dist/sdk/{failure-condition-evaluator-I6QWFKV3.mjs.map → failure-condition-evaluator-LZ2AG5PY.mjs.map} +0 -0
  57. /package/dist/sdk/{github-frontend-2MC77L7F.mjs.map → github-frontend-S523EEJB.mjs.map} +0 -0
  58. /package/dist/sdk/{host-4F6I3ZXN.mjs.map → host-7YKRMOUJ.mjs.map} +0 -0
  59. /package/dist/sdk/{routing-UT3BXBXH.mjs.map → routing-ZMBKWMVI.mjs.map} +0 -0
  60. /package/dist/sdk/{schedule-tool-CONR4VW3.mjs.map → schedule-tool-CDVUSZEG.mjs.map} +0 -0
  61. /package/dist/sdk/{schedule-tool-K3GQXCBN.mjs.map → schedule-tool-EOMZFICZ.mjs.map} +0 -0
  62. /package/dist/sdk/{schedule-tool-SBXAEBDD.mjs.map → schedule-tool-NX75VKGA.mjs.map} +0 -0
  63. /package/dist/sdk/{schedule-tool-handler-GFQCJAVZ.mjs.map → schedule-tool-handler-3FJHDIPG.mjs.map} +0 -0
  64. /package/dist/sdk/{schedule-tool-handler-R7PG3VMR.mjs.map → schedule-tool-handler-KKN7XJYT.mjs.map} +0 -0
  65. /package/dist/sdk/{schedule-tool-handler-YUC6CAXX.mjs.map → schedule-tool-handler-QNZG55DX.mjs.map} +0 -0
  66. /package/dist/sdk/{trace-helpers-J463EU4B.mjs.map → trace-helpers-EJUIOP6L.mjs.map} +0 -0
  67. /package/dist/sdk/{workflow-check-provider-DYSO3PML.mjs.map → workflow-check-provider-6ERNNCNA.mjs.map} +0 -0
  68. /package/dist/sdk/{workflow-check-provider-FIFFQDQU.mjs.map → workflow-check-provider-AGZ5JY2I.mjs.map} +0 -0
  69. /package/dist/sdk/{workflow-check-provider-GJNGTS3F.mjs.map → workflow-check-provider-PTNUWM5W.mjs.map} +0 -0
  70. /package/dist/sdk/{workflow-registry-AAD37XKZ.mjs.map → workflow-registry-MHUSKSD6.mjs.map} +0 -0
@@ -0,0 +1,478 @@
1
+ # =============================================================================
2
+ # intent-router: Reusable intent classification workflow
3
+ # =============================================================================
4
+ #
5
+ # A lightweight routing helper that classifies user intent and rewrites the
6
+ # request into a short question. Intended to be reused by assistant configs.
7
+ #
8
+ # Usage:
9
+ # imports:
10
+ # - visor://intent-router.yaml
11
+ #
12
+ # checks:
13
+ # route-intent:
14
+ # type: workflow
15
+ # workflow: intent-router
16
+ # args:
17
+ # question: "How does auth work?"
18
+ # intents:
19
+ # - id: chat
20
+ # description: general Q&A or small talk
21
+ #
22
+ # =============================================================================
23
+
24
+ id: intent-router
25
+ name: Intent Router
26
+ description: Classify user intent and rewrite the request as a short question
27
+ version: "1.0.0"
28
+
29
+ inputs:
30
+ - name: question
31
+ required: true
32
+ description: Primary user message to classify
33
+ schema:
34
+ type: string
35
+
36
+ - name: intents
37
+ required: true
38
+ description: |
39
+ Array of intent definitions:
40
+ - id: unique identifier for routing
41
+ - description: short description of when to use
42
+ schema:
43
+ type: array
44
+ items:
45
+ type: object
46
+ properties:
47
+ id: { type: string }
48
+ description: { type: string }
49
+ required: [id, description]
50
+
51
+ - name: tags
52
+ required: false
53
+ description: |
54
+ Optional tag definitions to classify capabilities or resources needed:
55
+ - id: tag identifier
56
+ - description: when the tag applies
57
+ NOTE: Consider using 'skills' instead for unified skill-based classification.
58
+ schema:
59
+ type: array
60
+ items:
61
+ type: object
62
+ properties:
63
+ id: { type: string }
64
+ description: { type: string }
65
+ required: [id, description]
66
+
67
+ - name: skills
68
+ required: false
69
+ description: |
70
+ Unified skill definitions for classification. Each skill bundles:
71
+ - id: skill identifier (used for classification and activation)
72
+ - description: when this skill should be activated
73
+ - requires: (optional) array of other skill IDs to auto-activate
74
+ When provided, skills are used instead of tags for classification.
75
+ The classifier will output selected skill IDs in the 'skills' array.
76
+ schema:
77
+ type: array
78
+ items:
79
+ type: object
80
+ properties:
81
+ id: { type: string }
82
+ description: { type: string }
83
+ requires: { type: array, items: { type: string } }
84
+ required: [id, description]
85
+
86
+ - name: routing_instructions
87
+ required: false
88
+ description: Additional routing rules to append (optional)
89
+ schema:
90
+ type: string
91
+
92
+ outputs:
93
+ - name: intent
94
+ description: Selected intent ID
95
+ value_js: |
96
+ return outputs?.classify?.intent ?? null;
97
+
98
+ - name: topic
99
+ description: Short question summarizing the request
100
+ value_js: |
101
+ return outputs?.classify?.topic ?? null;
102
+
103
+ - name: tags
104
+ description: Selected tag IDs (legacy, use skills instead)
105
+ value_js: |
106
+ return outputs?.classify?.tags ?? [];
107
+
108
+ - name: skills
109
+ description: Selected skill IDs (dependencies expanded in assistant workflow)
110
+ value_js: |
111
+ // Return raw selected skills - dependencies are expanded in assistant's build-config
112
+ return outputs?.classify?.skills ?? [];
113
+
114
+ - name: raw
115
+ description: Raw classifier output
116
+ value_js: |
117
+ return outputs?.classify ?? null;
118
+
119
+ - name: error
120
+ description: Error message if explicit %intent was invalid (check rationale for ERROR prefix)
121
+ value_js: |
122
+ const rationale = outputs?.classify?.rationale ?? '';
123
+ if (rationale.includes('ERROR:')) {
124
+ return rationale;
125
+ }
126
+ return null;
127
+
128
+ steps:
129
+ classify:
130
+ type: ai
131
+ criticality: internal
132
+ reuse_ai_session: false
133
+ assume:
134
+ - "true"
135
+ guarantee: "output?.intent != null"
136
+ ai:
137
+ skip_code_context: true
138
+ skip_slack_context: false
139
+ disableTools: true
140
+ allowedTools: []
141
+ system_prompt: |
142
+ You are an intent router. Your ONLY job is to:
143
+ 1) pick the best intent, and
144
+ 2) rewrite the request as a SHORT question (1-2 sentences),
145
+ 3) assign relevant tags (if provided).
146
+ NEVER answer the question or speculate about root causes.
147
+ Output ONLY JSON that matches the schema.
148
+ schema: |
149
+ {
150
+ "type": "object",
151
+ "additionalProperties": false,
152
+ "properties": {
153
+ "intent": {
154
+ "type": "string",
155
+ "enum": [{% for i in inputs.intents %}"{{ i.id }}"{% unless forloop.last %}, {% endunless %}{% endfor %}]
156
+ },
157
+ "topic": {
158
+ "type": "string",
159
+ "maxLength": 240,
160
+ "pattern": "^[^`\\n]*\\?$"
161
+ },
162
+ {% if inputs.skills and inputs.skills.size > 0 %}"skills": {
163
+ "type": "array",
164
+ "items": {
165
+ "type": "string",
166
+ "enum": [{% for s in inputs.skills %}"{{ s.id }}"{% unless forloop.last %}, {% endunless %}{% endfor %}]
167
+ },
168
+ "maxItems": 12
169
+ }{% else %}"tags": {
170
+ "type": "array",
171
+ "items": {
172
+ "type": "string"{% if inputs.tags and inputs.tags.size > 0 %},
173
+ "enum": [{% for t in inputs.tags %}"{{ t.id }}"{% unless forloop.last %}, {% endunless %}{% endfor %}]{% endif %}
174
+ },
175
+ "maxItems": 12
176
+ }{% endif %},
177
+ "rationale": {
178
+ "type": "string"
179
+ }
180
+ },
181
+ "required": ["intent", "topic"]
182
+ }
183
+ prompt: |
184
+ <role>
185
+ You are an internal routing assistant. Classify the request and produce a short question.
186
+ </role>
187
+
188
+ Primary message (main signal):
189
+ {{ inputs.question }}
190
+
191
+ <slack_context_instructions>
192
+ This is an ONGOING DIALOGUE. The full thread history is in <slack_context> inside the <context> block.
193
+
194
+ CRITICAL: Treat this as a continuous conversation, not isolated messages.
195
+ - If there are unfinished tasks or pending work from earlier in the thread, the current message likely relates to them
196
+ - Short messages like "ok", "do it", "continue", "yes", "what about X?" are follow-ups to previous context
197
+ - When the user references "it", "this", "that", or "the task", connect it to the most recent relevant topic
198
+ - If the assistant previously proposed something or was working on something, assume follow-ups relate to that work
199
+
200
+ When reconstructing the topic:
201
+ - Include enough context from the thread so the topic is self-contained
202
+ - If continuing previous work, mention what work (e.g., "Continue fixing the auth bug discussed earlier?")
203
+ - Don't just echo the last message if it's a short follow-up - expand it with thread context
204
+ </slack_context_instructions>
205
+
206
+ <intent_options>
207
+ {% for i in inputs.intents %}
208
+ <option value="{{ i.id }}">
209
+ {{ i.description }}
210
+ </option>
211
+ {% endfor %}
212
+ </intent_options>
213
+
214
+ {% if inputs.skills and inputs.skills.size > 0 %}
215
+ <skill_options>
216
+ Select which skills should be activated for this request.
217
+ Multiple skills can be selected if needed.
218
+ {% for s in inputs.skills %}
219
+ <option value="{{ s.id }}">
220
+ {{ s.description }}
221
+ </option>
222
+ {% endfor %}
223
+ </skill_options>
224
+ {% elsif inputs.tags and inputs.tags.size > 0 %}
225
+ <tag_options>
226
+ {% for t in inputs.tags %}
227
+ <option value="{{ t.id }}">
228
+ {{ t.description }}
229
+ </option>
230
+ {% endfor %}
231
+ </tag_options>
232
+ {% endif %}
233
+
234
+ {% if inputs.routing_instructions %}
235
+ <additional_routing_rules>
236
+ {{ inputs.routing_instructions }}
237
+ </additional_routing_rules>
238
+ {% endif %}
239
+
240
+ <topic_instructions>
241
+ Always output a short, self-contained question (1-2 sentences).
242
+ Do NOT answer the question or speculate about root causes.
243
+ Only include details explicitly stated in the thread or ticket context.
244
+ Remove any #tag or %intent markers from the topic.
245
+ </topic_instructions>
246
+
247
+ {% if inputs.skills and inputs.skills.size > 0 %}
248
+ <skill_instructions>
249
+ Return a "skills" array of zero or more skill IDs that should be activated.
250
+ Include only skills that clearly apply to the current request.
251
+ Multiple skills can be selected - each skill provides specific knowledge and/or tools.
252
+ Use an empty array if no skills apply.
253
+ </skill_instructions>
254
+ {% else %}
255
+ <tag_instructions>
256
+ If tag options are provided, return a "tags" array of zero or more tag IDs.
257
+ Include only tags that clearly apply to the current request. Use an empty
258
+ array if none apply.
259
+ </tag_instructions>
260
+ {% endif %}
261
+
262
+ <explicit_markers>
263
+ IMPORTANT: The user may include explicit markers in their message:
264
+
265
+ {% if inputs.skills and inputs.skills.size > 0 %}
266
+ 1. **Hash skills (#skill)**: If the message contains #skill_name patterns (e.g., "#jira #engineer"),
267
+ you MUST include those exact skill IDs in the output skills array (only if they match available skills).
268
+ Example: "Create a ticket for this bug #jira" → skills should include "jira"
269
+ {% else %}
270
+ 1. **Hash tags (#tag)**: If the message contains #tag_name patterns (e.g., "#codebase #urgent"),
271
+ you MUST include those exact tag IDs in the output tags array (only if they match available tags).
272
+ Example: "How does auth work? #codebase #security" → tags should include "codebase" and "security"
273
+ {% endif %}
274
+
275
+ 2. **Percent intent (%intent)**: If the message contains a %intent_name pattern (e.g., "%code_help"),
276
+ you MUST use that exact intent ID if it matches one of the available intents.
277
+ Example: "What is this function doing? %code_help" → intent should be "code_help"
278
+ If the specified %intent does NOT match any available option, include an error note in the
279
+ rationale field like "ERROR: explicit intent 'xyz' not found" and pick the closest matching intent.
280
+
281
+ Always strip the #skill/#tag and %intent markers from the topic output.
282
+ These explicit markers take precedence over your classification when they match valid options.
283
+ </explicit_markers>
284
+
285
+ # =============================================================================
286
+ # Tests
287
+ # =============================================================================
288
+ tests:
289
+ defaults:
290
+ strict: true
291
+ ai_provider: mock
292
+
293
+ cases:
294
+ - name: basic-intent-routing
295
+ event: manual
296
+ fixture: local.minimal
297
+ workflow_input:
298
+ question: "How does authentication work?"
299
+ intents:
300
+ - id: chat
301
+ description: general Q&A
302
+ - id: code_help
303
+ description: questions about code or implementation details
304
+ tags:
305
+ - id: codebase
306
+ description: request needs codebase context
307
+ mocks:
308
+ classify:
309
+ intent: code_help
310
+ topic: "How does authentication work?"
311
+ tags: ["codebase"]
312
+ expect:
313
+ calls:
314
+ - step: classify
315
+ exactly: 1
316
+ workflow_output:
317
+ - path: intent
318
+ equals: "code_help"
319
+ - path: topic
320
+ equals: "How does authentication work?"
321
+ - path: tags
322
+ equals: ["codebase"]
323
+
324
+ - name: explicit-hashtag-markers
325
+ description: "#tag markers should be automatically included in tags"
326
+ event: manual
327
+ fixture: local.minimal
328
+ workflow_input:
329
+ question: "How does auth work? #codebase #security"
330
+ intents:
331
+ - id: chat
332
+ description: general Q&A
333
+ - id: code_help
334
+ description: questions about code or implementation details
335
+ tags:
336
+ - id: codebase
337
+ description: request needs codebase context
338
+ - id: security
339
+ description: security-related request
340
+ - id: urgent
341
+ description: urgent request
342
+ mocks:
343
+ classify:
344
+ intent: code_help
345
+ topic: "How does auth work?"
346
+ tags: ["codebase", "security"]
347
+ expect:
348
+ calls:
349
+ - step: classify
350
+ exactly: 1
351
+ workflow_output:
352
+ - path: intent
353
+ equals: "code_help"
354
+ - path: topic
355
+ equals: "How does auth work?"
356
+ - path: tags
357
+ contains: "codebase"
358
+ - path: tags
359
+ contains: "security"
360
+
361
+ - name: explicit-percent-intent
362
+ description: "%intent marker should set the intent directly"
363
+ event: manual
364
+ fixture: local.minimal
365
+ workflow_input:
366
+ question: "What is this code doing? %code_help"
367
+ intents:
368
+ - id: chat
369
+ description: general Q&A
370
+ - id: code_help
371
+ description: questions about code or implementation details
372
+ mocks:
373
+ classify:
374
+ intent: code_help
375
+ topic: "What is this code doing?"
376
+ tags: []
377
+ expect:
378
+ calls:
379
+ - step: classify
380
+ exactly: 1
381
+ workflow_output:
382
+ - path: intent
383
+ equals: "code_help"
384
+ - path: topic
385
+ equals: "What is this code doing?"
386
+
387
+ - name: invalid-percent-intent
388
+ description: "Invalid %intent should return an error in rationale and pick closest intent"
389
+ event: manual
390
+ fixture: local.minimal
391
+ workflow_input:
392
+ question: "How do I deploy? %nonexistent_intent"
393
+ intents:
394
+ - id: chat
395
+ description: general Q&A
396
+ - id: code_help
397
+ description: questions about code or implementation details
398
+ mocks:
399
+ classify:
400
+ intent: "chat"
401
+ topic: "How do I deploy?"
402
+ tags: []
403
+ rationale: "ERROR: explicit intent 'nonexistent_intent' not found, using closest match 'chat'"
404
+ expect:
405
+ calls:
406
+ - step: classify
407
+ exactly: 1
408
+ workflow_output:
409
+ - path: intent
410
+ equals: "chat"
411
+ - path: error
412
+ contains: "ERROR:"
413
+
414
+ - name: skills-based-classification
415
+ description: "Skills replace tags for unified classification"
416
+ event: manual
417
+ fixture: local.minimal
418
+ workflow_input:
419
+ question: "Get ticket TT-123 and create a PR to fix it"
420
+ intents:
421
+ - id: chat
422
+ description: general Q&A
423
+ - id: code_help
424
+ description: questions about code or implementation
425
+ skills:
426
+ - id: jira
427
+ description: request references Jira tickets
428
+ - id: engineer
429
+ description: user wants code changes or PR created
430
+ - id: code-explorer
431
+ description: needs codebase exploration
432
+ mocks:
433
+ classify:
434
+ intent: code_help
435
+ topic: "Fix ticket TT-123 and create a PR?"
436
+ skills: ["jira", "engineer"]
437
+ expect:
438
+ calls:
439
+ - step: classify
440
+ exactly: 1
441
+ workflow_output:
442
+ - path: intent
443
+ equals: "code_help"
444
+ - path: skills
445
+ contains: "jira"
446
+ - path: skills
447
+ contains: "engineer"
448
+
449
+ - name: skills-no-tags-fallback
450
+ description: "Skills mode outputs skills, not tags"
451
+ event: manual
452
+ fixture: local.minimal
453
+ workflow_input:
454
+ question: "Create a Jira ticket for this bug"
455
+ intents:
456
+ - id: chat
457
+ description: general Q&A
458
+ skills:
459
+ - id: jira
460
+ description: request references Jira tickets
461
+ - id: jira-creation
462
+ description: user wants to create or modify a Jira ticket
463
+ mocks:
464
+ classify:
465
+ intent: chat
466
+ topic: "Create a Jira ticket for this bug?"
467
+ skills: ["jira", "jira-creation"]
468
+ expect:
469
+ calls:
470
+ - step: classify
471
+ exactly: 1
472
+ workflow_output:
473
+ - path: intent
474
+ equals: "chat"
475
+ - path: skills
476
+ contains: "jira"
477
+ - path: skills
478
+ contains: "jira-creation"
package/dist/index.js CHANGED
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
- process.env.VISOR_VERSION = '0.1.148';
2
+ process.env.VISOR_VERSION = '0.1.149';
3
3
  process.env.PROBE_VERSION = '0.6.0-rc264';
4
- process.env.VISOR_COMMIT_SHA = '8d09da19e112d8649810da46458aa77d3f034fc6';
5
- process.env.VISOR_COMMIT_SHORT = '8d09da19';
4
+ process.env.VISOR_COMMIT_SHA = 'd901e8c80aae0beb675cc9664eb380d4ad9dc4b7';
5
+ process.env.VISOR_COMMIT_SHORT = 'd901e8c8';
6
6
  /******/ (() => { // webpackBootstrap
7
7
  /******/ var __webpack_modules__ = ({
8
8
 
@@ -223248,6 +223248,19 @@ class WorkflowRegistry {
223248
223248
  */
223249
223249
  async loadWorkflowContent(source, basePath) {
223250
223250
  const baseIsUrl = basePath?.startsWith('http://') || basePath?.startsWith('https://');
223251
+ // Handle visor:// and visor-ee:// built-in workflow URLs
223252
+ // Resolves to the defaults/ directory shipped with the package
223253
+ if (source.startsWith('visor://') || source.startsWith('visor-ee://')) {
223254
+ const relativePath = source.replace(/^visor(?:-ee)?:\/\//, '');
223255
+ const defaultsDir = path.resolve(__dirname, '..', 'defaults');
223256
+ const filePath = path.resolve(defaultsDir, relativePath);
223257
+ // Prevent path traversal outside defaults directory
223258
+ if (!filePath.startsWith(defaultsDir + path.sep)) {
223259
+ throw new Error(`Invalid visor:// path: resolved path escapes defaults directory`);
223260
+ }
223261
+ const content = await fs_1.promises.readFile(filePath, 'utf-8');
223262
+ return { content, resolvedSource: filePath, importBasePath: path.dirname(filePath) };
223263
+ }
223251
223264
  // Handle URLs
223252
223265
  if (source.startsWith('http://') || source.startsWith('https://')) {
223253
223266
  const response = await fetch(source);
@@ -395866,7 +395879,7 @@ module.exports = /*#__PURE__*/JSON.parse('{"100":"Continue","101":"Switching Pro
395866
395879
  /***/ ((module) => {
395867
395880
 
395868
395881
  "use strict";
395869
- module.exports = /*#__PURE__*/JSON.parse('{"name":"@probelabs/visor","version":"0.1.148","main":"dist/index.js","bin":{"visor":"./dist/index.js"},"exports":{".":{"require":"./dist/index.js","import":"./dist/index.js"},"./sdk":{"types":"./dist/sdk/sdk.d.ts","import":"./dist/sdk/sdk.mjs","require":"./dist/sdk/sdk.js"},"./cli":{"require":"./dist/index.js"}},"files":["dist/","defaults/","action.yml","README.md","LICENSE"],"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"scripts":{"build:cli":"ncc build src/index.ts -o dist && cp -r defaults dist/ && cp -r output dist/ && cp -r docs dist/ && cp -r examples dist/ && cp -r src/debug-visualizer/ui dist/debug-visualizer/ && node scripts/inject-version.js && echo \'#!/usr/bin/env node\' | cat - dist/index.js > temp && mv temp dist/index.js && chmod +x dist/index.js","build:sdk":"tsup src/sdk.ts --dts --sourcemap --format esm,cjs --out-dir dist/sdk","build":"./scripts/build-oss.sh","build:ee":"npm run build:cli && npm run build:sdk","test":"jest && npm run test:yaml","test:unit":"jest","prepublishOnly":"npm run build","test:watch":"jest --watch","test:coverage":"jest --coverage","test:ee":"jest --testPathPatterns=\'tests/ee\' --testPathIgnorePatterns=\'/node_modules/\' --no-coverage","test:manual:bash":"RUN_MANUAL_TESTS=true jest tests/manual/bash-config-manual.test.ts","lint":"eslint src tests --ext .ts","lint:fix":"eslint src tests --ext .ts --fix","format":"prettier --write src tests","format:check":"prettier --check src tests","clean":"","clean:traces":"node scripts/clean-traces.js","prebuild":"npm run clean && node scripts/generate-config-schema.js","pretest":"npm run clean:traces && node scripts/generate-config-schema.js && npm run build:cli","pretest:unit":"npm run clean:traces && node scripts/generate-config-schema.js && npm run build:cli","test:with-build":"npm run build:cli && jest","test:yaml":"node dist/index.js test --progress compact","test:yaml:parallel":"node dist/index.js test --progress compact --max-parallel 4","prepare":"husky","pre-commit":"lint-staged","deploy:site":"cd site && npx wrangler pages deploy . --project-name=visor-site --commit-dirty=true","deploy:worker":"npx wrangler deploy","deploy":"npm run deploy:site && npm run deploy:worker","publish:ee":"./scripts/publish-ee.sh","release":"./scripts/release.sh","release:patch":"./scripts/release.sh patch","release:minor":"./scripts/release.sh minor","release:major":"./scripts/release.sh major","release:prerelease":"./scripts/release.sh prerelease","docs:validate":"node scripts/validate-readme-links.js","workshop:setup":"npm install -D reveal-md@6.1.2","workshop:serve":"cd workshop && reveal-md slides.md -w","workshop:export":"reveal-md workshop/slides.md --static workshop/build","workshop:pdf":"reveal-md workshop/slides.md --print workshop/Visor-Workshop.pdf --print-size letter","workshop:pdf:ci":"reveal-md workshop/slides.md --print workshop/Visor-Workshop.pdf --print-size letter --puppeteer-launch-args=\\"--no-sandbox --disable-dev-shm-usage\\"","workshop:pdf:a4":"reveal-md workshop/slides.md --print workshop/Visor-Workshop-A4.pdf --print-size A4","workshop:build":"npm run workshop:export && npm run workshop:pdf","simulate:issue":"TS_NODE_TRANSPILE_ONLY=1 ts-node scripts/simulate-gh-run.ts --event issues --action opened --debug","simulate:comment":"TS_NODE_TRANSPILE_ONLY=1 ts-node scripts/simulate-gh-run.ts --event issue_comment --action created --debug"},"keywords":["code-review","ai","github-action","cli","pr-review","visor"],"author":"Probe Labs","license":"MIT","description":"AI workflow engine for code review, assistants, and automation — orchestrate checks, MCP tools, and AI providers with YAML-driven pipelines","repository":{"type":"git","url":"git+https://github.com/probelabs/visor.git"},"bugs":{"url":"https://github.com/probelabs/visor/issues"},"homepage":"https://github.com/probelabs/visor#readme","dependencies":{"@actions/core":"^1.11.1","@apidevtools/swagger-parser":"^12.1.0","@modelcontextprotocol/sdk":"^1.25.3","@nyariv/sandboxjs":"github:probelabs/SandboxJS#f1c13b8eee98734a8ea024061eada4aa9a9ff2e9","@octokit/action":"^8.0.2","@octokit/auth-app":"^8.1.0","@octokit/core":"^7.0.3","@octokit/rest":"^22.0.0","@opentelemetry/api":"^1.9.0","@opentelemetry/core":"^1.30.1","@opentelemetry/exporter-trace-otlp-grpc":"^0.203.0","@opentelemetry/exporter-trace-otlp-http":"^0.203.0","@opentelemetry/instrumentation":"^0.203.0","@opentelemetry/resources":"^1.30.1","@opentelemetry/sdk-metrics":"^1.30.1","@opentelemetry/sdk-node":"^0.203.0","@opentelemetry/sdk-trace-base":"^1.30.1","@opentelemetry/semantic-conventions":"^1.30.1","@probelabs/probe":"^0.6.0-rc264","@types/commander":"^2.12.0","@types/uuid":"^10.0.0","acorn":"^8.16.0","acorn-walk":"^8.3.5","ajv":"^8.17.1","ajv-formats":"^3.0.1","better-sqlite3":"^11.0.0","blessed":"^0.1.81","cli-table3":"^0.6.5","commander":"^14.0.0","deepmerge":"^4.3.1","dotenv":"^17.2.3","ignore":"^7.0.5","js-yaml":"^4.1.0","jsonpath-plus":"^10.4.0","liquidjs":"^10.21.1","minimatch":"^10.2.2","node-cron":"^3.0.3","open":"^9.1.0","simple-git":"^3.28.0","uuid":"^11.1.0","ws":"^8.18.3"},"optionalDependencies":{"@anthropic/claude-code-sdk":"npm:null@*","@open-policy-agent/opa-wasm":"^1.10.0","knex":"^3.1.0","mysql2":"^3.11.0","pg":"^8.13.0","tedious":"^19.0.0"},"devDependencies":{"@eslint/js":"^9.34.0","@kie/act-js":"^2.6.2","@kie/mock-github":"^2.0.1","@swc/core":"^1.13.2","@swc/jest":"^0.2.37","@types/better-sqlite3":"^7.6.0","@types/blessed":"^0.1.27","@types/jest":"^30.0.0","@types/js-yaml":"^4.0.9","@types/node":"^24.3.0","@types/node-cron":"^3.0.11","@types/ws":"^8.18.1","@typescript-eslint/eslint-plugin":"^8.42.0","@typescript-eslint/parser":"^8.42.0","@vercel/ncc":"^0.38.4","eslint":"^9.34.0","eslint-config-prettier":"^10.1.8","eslint-plugin-prettier":"^5.5.4","husky":"^9.1.7","jest":"^30.1.3","lint-staged":"^16.1.6","prettier":"^3.6.2","reveal-md":"^6.1.2","ts-json-schema-generator":"^1.5.1","ts-node":"^10.9.2","tsup":"^8.5.0","typescript":"^5.9.2","wrangler":"^3.0.0"},"peerDependenciesMeta":{"@anthropic/claude-code-sdk":{"optional":true}},"directories":{"test":"tests"},"lint-staged":{"src/**/*.{ts,js}":["eslint --fix","prettier --write"],"tests/**/*.{ts,js}":["eslint --fix","prettier --write"],"*.{json,md,yml,yaml}":["prettier --write"]}}');
395882
+ module.exports = /*#__PURE__*/JSON.parse('{"name":"@probelabs/visor","version":"0.1.149","main":"dist/index.js","bin":{"visor":"./dist/index.js"},"exports":{".":{"require":"./dist/index.js","import":"./dist/index.js"},"./sdk":{"types":"./dist/sdk/sdk.d.ts","import":"./dist/sdk/sdk.mjs","require":"./dist/sdk/sdk.js"},"./cli":{"require":"./dist/index.js"}},"files":["dist/","defaults/","action.yml","README.md","LICENSE"],"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"scripts":{"build:cli":"ncc build src/index.ts -o dist && cp -r defaults dist/ && cp -r output dist/ && cp -r docs dist/ && cp -r examples dist/ && cp -r src/debug-visualizer/ui dist/debug-visualizer/ && node scripts/inject-version.js && echo \'#!/usr/bin/env node\' | cat - dist/index.js > temp && mv temp dist/index.js && chmod +x dist/index.js","build:sdk":"tsup src/sdk.ts --dts --sourcemap --format esm,cjs --out-dir dist/sdk","build":"./scripts/build-oss.sh","build:ee":"npm run build:cli && npm run build:sdk","test":"jest && npm run test:yaml","test:unit":"jest","prepublishOnly":"npm run build","test:watch":"jest --watch","test:coverage":"jest --coverage","test:ee":"jest --testPathPatterns=\'tests/ee\' --testPathIgnorePatterns=\'/node_modules/\' --no-coverage","test:manual:bash":"RUN_MANUAL_TESTS=true jest tests/manual/bash-config-manual.test.ts","lint":"eslint src tests --ext .ts","lint:fix":"eslint src tests --ext .ts --fix","format":"prettier --write src tests","format:check":"prettier --check src tests","clean":"","clean:traces":"node scripts/clean-traces.js","prebuild":"npm run clean && node scripts/generate-config-schema.js","pretest":"npm run clean:traces && node scripts/generate-config-schema.js && npm run build:cli","pretest:unit":"npm run clean:traces && node scripts/generate-config-schema.js && npm run build:cli","test:with-build":"npm run build:cli && jest","test:yaml":"node dist/index.js test --progress compact","test:yaml:parallel":"node dist/index.js test --progress compact --max-parallel 4","prepare":"husky","pre-commit":"lint-staged","deploy:site":"cd site && npx wrangler pages deploy . --project-name=visor-site --commit-dirty=true","deploy:worker":"npx wrangler deploy","deploy":"npm run deploy:site && npm run deploy:worker","publish:ee":"./scripts/publish-ee.sh","release":"./scripts/release.sh","release:patch":"./scripts/release.sh patch","release:minor":"./scripts/release.sh minor","release:major":"./scripts/release.sh major","release:prerelease":"./scripts/release.sh prerelease","docs:validate":"node scripts/validate-readme-links.js","workshop:setup":"npm install -D reveal-md@6.1.2","workshop:serve":"cd workshop && reveal-md slides.md -w","workshop:export":"reveal-md workshop/slides.md --static workshop/build","workshop:pdf":"reveal-md workshop/slides.md --print workshop/Visor-Workshop.pdf --print-size letter","workshop:pdf:ci":"reveal-md workshop/slides.md --print workshop/Visor-Workshop.pdf --print-size letter --puppeteer-launch-args=\\"--no-sandbox --disable-dev-shm-usage\\"","workshop:pdf:a4":"reveal-md workshop/slides.md --print workshop/Visor-Workshop-A4.pdf --print-size A4","workshop:build":"npm run workshop:export && npm run workshop:pdf","simulate:issue":"TS_NODE_TRANSPILE_ONLY=1 ts-node scripts/simulate-gh-run.ts --event issues --action opened --debug","simulate:comment":"TS_NODE_TRANSPILE_ONLY=1 ts-node scripts/simulate-gh-run.ts --event issue_comment --action created --debug"},"keywords":["code-review","ai","github-action","cli","pr-review","visor"],"author":"Probe Labs","license":"MIT","description":"AI workflow engine for code review, assistants, and automation — orchestrate checks, MCP tools, and AI providers with YAML-driven pipelines","repository":{"type":"git","url":"git+https://github.com/probelabs/visor.git"},"bugs":{"url":"https://github.com/probelabs/visor/issues"},"homepage":"https://github.com/probelabs/visor#readme","dependencies":{"@actions/core":"^1.11.1","@apidevtools/swagger-parser":"^12.1.0","@modelcontextprotocol/sdk":"^1.25.3","@nyariv/sandboxjs":"github:probelabs/SandboxJS#f1c13b8eee98734a8ea024061eada4aa9a9ff2e9","@octokit/action":"^8.0.2","@octokit/auth-app":"^8.1.0","@octokit/core":"^7.0.3","@octokit/rest":"^22.0.0","@opentelemetry/api":"^1.9.0","@opentelemetry/core":"^1.30.1","@opentelemetry/exporter-trace-otlp-grpc":"^0.203.0","@opentelemetry/exporter-trace-otlp-http":"^0.203.0","@opentelemetry/instrumentation":"^0.203.0","@opentelemetry/resources":"^1.30.1","@opentelemetry/sdk-metrics":"^1.30.1","@opentelemetry/sdk-node":"^0.203.0","@opentelemetry/sdk-trace-base":"^1.30.1","@opentelemetry/semantic-conventions":"^1.30.1","@probelabs/probe":"^0.6.0-rc264","@types/commander":"^2.12.0","@types/uuid":"^10.0.0","acorn":"^8.16.0","acorn-walk":"^8.3.5","ajv":"^8.17.1","ajv-formats":"^3.0.1","better-sqlite3":"^11.0.0","blessed":"^0.1.81","cli-table3":"^0.6.5","commander":"^14.0.0","deepmerge":"^4.3.1","dotenv":"^17.2.3","ignore":"^7.0.5","js-yaml":"^4.1.0","jsonpath-plus":"^10.4.0","liquidjs":"^10.21.1","minimatch":"^10.2.2","node-cron":"^3.0.3","open":"^9.1.0","simple-git":"^3.28.0","uuid":"^11.1.0","ws":"^8.18.3"},"optionalDependencies":{"@anthropic/claude-code-sdk":"npm:null@*","@open-policy-agent/opa-wasm":"^1.10.0","knex":"^3.1.0","mysql2":"^3.11.0","pg":"^8.13.0","tedious":"^19.0.0"},"devDependencies":{"@eslint/js":"^9.34.0","@kie/act-js":"^2.6.2","@kie/mock-github":"^2.0.1","@swc/core":"^1.13.2","@swc/jest":"^0.2.37","@types/better-sqlite3":"^7.6.0","@types/blessed":"^0.1.27","@types/jest":"^30.0.0","@types/js-yaml":"^4.0.9","@types/node":"^24.3.0","@types/node-cron":"^3.0.11","@types/ws":"^8.18.1","@typescript-eslint/eslint-plugin":"^8.42.0","@typescript-eslint/parser":"^8.42.0","@vercel/ncc":"^0.38.4","eslint":"^9.34.0","eslint-config-prettier":"^10.1.8","eslint-plugin-prettier":"^5.5.4","husky":"^9.1.7","jest":"^30.1.3","lint-staged":"^16.1.6","prettier":"^3.6.2","reveal-md":"^6.1.2","ts-json-schema-generator":"^1.5.1","ts-node":"^10.9.2","tsup":"^8.5.0","typescript":"^5.9.2","wrangler":"^3.0.0"},"peerDependenciesMeta":{"@anthropic/claude-code-sdk":{"optional":true}},"directories":{"test":"tests"},"lint-staged":{"src/**/*.{ts,js}":["eslint --fix","prettier --write"],"tests/**/*.{ts,js}":["eslint --fix","prettier --write"],"*.{json,md,yml,yaml}":["prettier --write"]}}');
395870
395883
 
395871
395884
  /***/ })
395872
395885