@probelabs/visor 0.1.179-ee → 0.1.180-ee
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.
- package/README.md +6 -4
- package/defaults/assistant.yaml +29 -1
- package/defaults/code-talk.yaml +331 -441
- package/defaults/engineer.yaml +608 -0
- package/defaults/project-setup.yaml +489 -0
- package/defaults/skills/engineer.yaml +41 -0
- package/dist/{560.index.js → 736.index.js} +359 -3132
- package/dist/agent-protocol/task-store.d.ts +3 -0
- package/dist/agent-protocol/task-store.d.ts.map +1 -1
- package/dist/agent-protocol/track-execution.d.ts.map +1 -1
- package/dist/ai-review-service.d.ts +6 -0
- package/dist/ai-review-service.d.ts.map +1 -1
- package/dist/cli-main.d.ts.map +1 -1
- package/dist/cli.d.ts +5 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/defaults/assistant.yaml +29 -1
- package/dist/defaults/code-talk.yaml +331 -441
- package/dist/defaults/engineer.yaml +608 -0
- package/dist/defaults/project-setup.yaml +489 -0
- package/dist/defaults/skills/engineer.yaml +41 -0
- package/dist/docs/advanced-ai.md +39 -0
- package/dist/docs/ai-configuration.md +32 -0
- package/dist/docs/ai-custom-tools.md +25 -0
- package/dist/docs/architecture.md +3 -0
- package/dist/docs/assistant-workflows.md +395 -25
- package/dist/docs/configuration.md +2 -1
- package/dist/docs/glossary.md +27 -1
- package/dist/docs/guides/build-ai-agent.md +4 -0
- package/dist/docs/mcp.md +26 -0
- package/dist/docs/migration.md +2 -0
- package/dist/docs/pluggable.md +28 -1
- package/dist/docs/telemetry-reference.md +41 -0
- package/dist/docs/timeouts.md +86 -1
- package/dist/docs/utcp-provider.md +343 -0
- package/dist/docs/workflows.md +30 -0
- package/dist/examples/negotiated-timeout.yaml +65 -0
- package/dist/examples/screenshot-tool.yaml +100 -0
- package/dist/examples/utcp-provider-example.yaml +290 -0
- package/dist/examples/workflows/helper-workflow.yaml +15 -0
- package/dist/frontends/slack-frontend.d.ts.map +1 -1
- package/dist/generated/config-schema.d.ts +75 -8
- package/dist/generated/config-schema.d.ts.map +1 -1
- package/dist/generated/config-schema.json +86 -8
- package/dist/index.js +42497 -33912
- package/dist/providers/ai-check-provider.d.ts.map +1 -1
- package/dist/providers/check-provider-registry.d.ts.map +1 -1
- package/dist/providers/check-provider.interface.d.ts +6 -0
- package/dist/providers/check-provider.interface.d.ts.map +1 -1
- package/dist/providers/http-client-provider.d.ts.map +1 -1
- package/dist/providers/index.d.ts +1 -0
- package/dist/providers/index.d.ts.map +1 -1
- package/dist/providers/mcp-check-provider.d.ts +0 -8
- package/dist/providers/mcp-check-provider.d.ts.map +1 -1
- package/dist/providers/mcp-custom-sse-server.d.ts +5 -0
- package/dist/providers/mcp-custom-sse-server.d.ts.map +1 -1
- package/dist/providers/utcp-check-provider.d.ts +81 -0
- package/dist/providers/utcp-check-provider.d.ts.map +1 -0
- package/dist/providers/workflow-check-provider.d.ts.map +1 -1
- package/dist/sandbox/check-runner.d.ts +1 -1
- package/dist/sandbox/check-runner.d.ts.map +1 -1
- package/dist/sandbox/compose-generator.d.ts +45 -0
- package/dist/sandbox/compose-generator.d.ts.map +1 -0
- package/dist/sandbox/index.d.ts +2 -1
- package/dist/sandbox/index.d.ts.map +1 -1
- package/dist/sandbox/sandbox-manager.d.ts +21 -1
- package/dist/sandbox/sandbox-manager.d.ts.map +1 -1
- package/dist/sandbox/types.d.ts +40 -0
- package/dist/sandbox/types.d.ts.map +1 -1
- package/dist/sdk/{a2a-frontend-KJFLIZJT.mjs → a2a-frontend-6FNPD53G.mjs} +20 -2
- package/dist/sdk/a2a-frontend-6FNPD53G.mjs.map +1 -0
- package/dist/sdk/{check-provider-registry-SYAHJMWJ.mjs → check-provider-registry-T4HIUBMT.mjs} +8 -7
- package/dist/sdk/{check-provider-registry-J27YX4IT.mjs → check-provider-registry-Z4MVXFLJ.mjs} +9 -8
- package/dist/sdk/{chunk-ZJYQMNPA.mjs → chunk-3ZKBUWDB.mjs} +3 -3
- package/dist/sdk/{chunk-OYHDBTKY.mjs → chunk-5DQY4LTK.mjs} +2 -2
- package/dist/sdk/chunk-ANCIFGQH.mjs +825 -0
- package/dist/sdk/chunk-ANCIFGQH.mjs.map +1 -0
- package/dist/sdk/chunk-F25U4YWJ.mjs +825 -0
- package/dist/sdk/chunk-F25U4YWJ.mjs.map +1 -0
- package/dist/sdk/{chunk-UBTZE3FO.mjs → chunk-J27D43HS.mjs} +51 -8
- package/dist/sdk/chunk-J27D43HS.mjs.map +1 -0
- package/dist/sdk/{chunk-BMXVAJ2M.mjs → chunk-KAVOGMLR.mjs} +90 -15
- package/dist/sdk/chunk-KAVOGMLR.mjs.map +1 -0
- package/dist/sdk/{chunk-FTPLYUQ3.mjs → chunk-MWUQFSEK.mjs} +6981 -6461
- package/dist/sdk/chunk-MWUQFSEK.mjs.map +1 -0
- package/dist/sdk/{chunk-CHARL3TY.mjs → chunk-NBUN22ZG.mjs} +12 -2
- package/dist/sdk/chunk-NBUN22ZG.mjs.map +1 -0
- package/dist/sdk/{chunk-KWHLB5E3.mjs → chunk-STAAKOPU.mjs} +6516 -5996
- package/dist/sdk/chunk-STAAKOPU.mjs.map +1 -0
- package/dist/sdk/{config-DFOF7LP4.mjs → config-ZZKC47SV.mjs} +2 -2
- package/dist/sdk/dist-X4HSBKSA.mjs +5716 -0
- package/dist/sdk/dist-X4HSBKSA.mjs.map +1 -0
- package/dist/sdk/dist-XF2FTM6E.mjs +5716 -0
- package/dist/sdk/dist-XF2FTM6E.mjs.map +1 -0
- package/dist/sdk/{failure-condition-evaluator-V2YGFRKO.mjs → failure-condition-evaluator-WNCCIP6N.mjs} +3 -3
- package/dist/sdk/{github-frontend-4LM4NAZK.mjs → github-frontend-QVMVUL3Y.mjs} +3 -3
- package/dist/sdk/{host-GBXJKNHL.mjs → host-5TJBWGGH.mjs} +4 -4
- package/dist/sdk/{host-XXPPPC76.mjs → host-RVLIZMTE.mjs} +4 -4
- package/dist/sdk/{loader-Q7K76ZIY.mjs → loader-ZNKKJEZ3.mjs} +1 -1
- package/dist/sdk/{routing-YAYBIVPL.mjs → routing-5DHNS7IW.mjs} +4 -4
- package/dist/sdk/{schedule-tool-OIVJDIDK.mjs → schedule-tool-25CFKVOI.mjs} +8 -7
- package/dist/sdk/{schedule-tool-WACIV77L.mjs → schedule-tool-UGWYLGJK.mjs} +9 -8
- package/dist/sdk/{schedule-tool-handler-ODKY57FO.mjs → schedule-tool-handler-VWBX4JEF.mjs} +8 -7
- package/dist/sdk/{schedule-tool-handler-SJF4ZKSB.mjs → schedule-tool-handler-WK22RO3M.mjs} +9 -8
- package/dist/sdk/sdk.d.mts +42 -2
- package/dist/sdk/sdk.d.ts +42 -2
- package/dist/sdk/sdk.js +28250 -21090
- package/dist/sdk/sdk.js.map +1 -1
- package/dist/sdk/sdk.mjs +8 -7
- package/dist/sdk/sdk.mjs.map +1 -1
- package/dist/sdk/{slack-frontend-OWD7BSWF.mjs → slack-frontend-BPWXNIHE.mjs} +3 -3
- package/dist/sdk/slack-frontend-BPWXNIHE.mjs.map +1 -0
- package/dist/sdk/{trace-helpers-QL2B75AK.mjs → trace-helpers-GCLQ3YKO.mjs} +2 -2
- package/dist/sdk/{track-execution-2Q66SXBZ.mjs → track-execution-GCGJKMAO.mjs} +6 -4
- package/dist/sdk/track-execution-GCGJKMAO.mjs.map +1 -0
- package/dist/sdk/utcp-check-provider-6YTBN5WQ.mjs +16 -0
- package/dist/sdk/utcp-check-provider-HT2MA5SS.mjs +16 -0
- package/dist/sdk/{workflow-check-provider-IXW6BMQA.mjs → workflow-check-provider-I732XE7D.mjs} +8 -7
- package/dist/sdk/{workflow-check-provider-UZQZYPOE.mjs → workflow-check-provider-T4PFK2EG.mjs} +9 -8
- package/dist/sdk/workflow-check-provider-T4PFK2EG.mjs.map +1 -0
- package/dist/sdk/{workflow-registry-LRSRWUM5.mjs → workflow-registry-X2IPY35M.mjs} +2 -2
- package/dist/sdk/workflow-registry-X2IPY35M.mjs.map +1 -0
- package/dist/slack/adapter.d.ts +8 -0
- package/dist/slack/adapter.d.ts.map +1 -1
- package/dist/slack/client.d.ts +1 -0
- package/dist/slack/client.d.ts.map +1 -1
- package/dist/slack/socket-runner.d.ts +1 -0
- package/dist/slack/socket-runner.d.ts.map +1 -1
- package/dist/state-machine/dispatch/execution-invoker.d.ts.map +1 -1
- package/dist/state-machine/dispatch/sandbox-routing.d.ts +25 -1
- package/dist/state-machine/dispatch/sandbox-routing.d.ts.map +1 -1
- package/dist/state-machine-execution-engine.d.ts.map +1 -1
- package/dist/telemetry/opentelemetry.d.ts +6 -0
- package/dist/telemetry/opentelemetry.d.ts.map +1 -1
- package/dist/test-runner/core/flow-stage.d.ts +1 -2
- package/dist/test-runner/core/flow-stage.d.ts.map +1 -1
- package/dist/test-runner/index.d.ts +0 -3
- package/dist/test-runner/index.d.ts.map +1 -1
- package/dist/test-runner/validator.d.ts.map +1 -1
- package/dist/types/config.d.ts +36 -2
- package/dist/types/config.d.ts.map +1 -1
- package/dist/utils/issue-normalizer.d.ts +27 -0
- package/dist/utils/issue-normalizer.d.ts.map +1 -0
- package/dist/utils/worktree-manager.d.ts +9 -2
- package/dist/utils/worktree-manager.d.ts.map +1 -1
- package/dist/workflow-registry.d.ts +5 -0
- package/dist/workflow-registry.d.ts.map +1 -1
- package/package.json +12 -2
- package/dist/sdk/a2a-frontend-KJFLIZJT.mjs.map +0 -1
- package/dist/sdk/chunk-BMXVAJ2M.mjs.map +0 -1
- package/dist/sdk/chunk-CHARL3TY.mjs.map +0 -1
- package/dist/sdk/chunk-FTPLYUQ3.mjs.map +0 -1
- package/dist/sdk/chunk-KWHLB5E3.mjs.map +0 -1
- package/dist/sdk/chunk-UBTZE3FO.mjs.map +0 -1
- package/dist/sdk/slack-frontend-OWD7BSWF.mjs.map +0 -1
- package/dist/sdk/track-execution-2Q66SXBZ.mjs.map +0 -1
- /package/dist/sdk/{check-provider-registry-J27YX4IT.mjs.map → check-provider-registry-T4HIUBMT.mjs.map} +0 -0
- /package/dist/sdk/{check-provider-registry-SYAHJMWJ.mjs.map → check-provider-registry-Z4MVXFLJ.mjs.map} +0 -0
- /package/dist/sdk/{chunk-ZJYQMNPA.mjs.map → chunk-3ZKBUWDB.mjs.map} +0 -0
- /package/dist/sdk/{chunk-OYHDBTKY.mjs.map → chunk-5DQY4LTK.mjs.map} +0 -0
- /package/dist/sdk/{config-DFOF7LP4.mjs.map → config-ZZKC47SV.mjs.map} +0 -0
- /package/dist/sdk/{failure-condition-evaluator-V2YGFRKO.mjs.map → failure-condition-evaluator-WNCCIP6N.mjs.map} +0 -0
- /package/dist/sdk/{github-frontend-4LM4NAZK.mjs.map → github-frontend-QVMVUL3Y.mjs.map} +0 -0
- /package/dist/sdk/{host-GBXJKNHL.mjs.map → host-5TJBWGGH.mjs.map} +0 -0
- /package/dist/sdk/{host-XXPPPC76.mjs.map → host-RVLIZMTE.mjs.map} +0 -0
- /package/dist/sdk/{loader-Q7K76ZIY.mjs.map → loader-ZNKKJEZ3.mjs.map} +0 -0
- /package/dist/sdk/{routing-YAYBIVPL.mjs.map → routing-5DHNS7IW.mjs.map} +0 -0
- /package/dist/sdk/{schedule-tool-OIVJDIDK.mjs.map → schedule-tool-25CFKVOI.mjs.map} +0 -0
- /package/dist/sdk/{schedule-tool-WACIV77L.mjs.map → schedule-tool-UGWYLGJK.mjs.map} +0 -0
- /package/dist/sdk/{schedule-tool-handler-ODKY57FO.mjs.map → schedule-tool-handler-VWBX4JEF.mjs.map} +0 -0
- /package/dist/sdk/{schedule-tool-handler-SJF4ZKSB.mjs.map → schedule-tool-handler-WK22RO3M.mjs.map} +0 -0
- /package/dist/sdk/{trace-helpers-QL2B75AK.mjs.map → trace-helpers-GCLQ3YKO.mjs.map} +0 -0
- /package/dist/sdk/{workflow-check-provider-IXW6BMQA.mjs.map → utcp-check-provider-6YTBN5WQ.mjs.map} +0 -0
- /package/dist/sdk/{workflow-check-provider-UZQZYPOE.mjs.map → utcp-check-provider-HT2MA5SS.mjs.map} +0 -0
- /package/dist/sdk/{workflow-registry-LRSRWUM5.mjs.map → workflow-check-provider-I732XE7D.mjs.map} +0 -0
|
@@ -0,0 +1,489 @@
|
|
|
1
|
+
# =============================================================================
|
|
2
|
+
# project-setup: Shared project routing and checkout workflow
|
|
3
|
+
# =============================================================================
|
|
4
|
+
#
|
|
5
|
+
# Reusable workflow that handles:
|
|
6
|
+
# 1. Docs checkout
|
|
7
|
+
# 2. AI-based project routing (or pre-selected projects)
|
|
8
|
+
# 3. Project checkout with metadata (services, setup, knowledge)
|
|
9
|
+
#
|
|
10
|
+
# Used by code-talk and engineer workflows.
|
|
11
|
+
#
|
|
12
|
+
# Usage:
|
|
13
|
+
# imports:
|
|
14
|
+
# - ./project-setup.yaml
|
|
15
|
+
#
|
|
16
|
+
# checks:
|
|
17
|
+
# setup:
|
|
18
|
+
# type: workflow
|
|
19
|
+
# workflow: project-setup
|
|
20
|
+
# args:
|
|
21
|
+
# question: "How does auth work?"
|
|
22
|
+
# architecture: ./ARCHITECTURE.md
|
|
23
|
+
# docs_repo: my-org/docs
|
|
24
|
+
# projects:
|
|
25
|
+
# - id: backend
|
|
26
|
+
# repo: my-org/backend
|
|
27
|
+
# description: Backend API services
|
|
28
|
+
#
|
|
29
|
+
# =============================================================================
|
|
30
|
+
|
|
31
|
+
id: project-setup
|
|
32
|
+
name: Project Setup
|
|
33
|
+
description: Shared project routing and checkout with metadata propagation
|
|
34
|
+
version: "1.0.0"
|
|
35
|
+
|
|
36
|
+
inputs:
|
|
37
|
+
- name: question
|
|
38
|
+
required: true
|
|
39
|
+
description: The question or task driving project selection
|
|
40
|
+
schema:
|
|
41
|
+
type: string
|
|
42
|
+
|
|
43
|
+
- name: architecture
|
|
44
|
+
required: true
|
|
45
|
+
description: |
|
|
46
|
+
Architecture model - file path or inline markdown describing
|
|
47
|
+
project topology and routing rules
|
|
48
|
+
schema:
|
|
49
|
+
type: string
|
|
50
|
+
|
|
51
|
+
- name: docs_repo
|
|
52
|
+
required: true
|
|
53
|
+
description: Documentation repository (owner/name format)
|
|
54
|
+
schema:
|
|
55
|
+
type: string
|
|
56
|
+
|
|
57
|
+
- name: projects
|
|
58
|
+
required: true
|
|
59
|
+
description: |
|
|
60
|
+
Array of available code projects for AI routing:
|
|
61
|
+
- id: unique identifier for routing
|
|
62
|
+
- repo: GitHub repository (owner/name)
|
|
63
|
+
- description: used by AI for routing decisions
|
|
64
|
+
schema:
|
|
65
|
+
type: array
|
|
66
|
+
items:
|
|
67
|
+
type: object
|
|
68
|
+
properties:
|
|
69
|
+
id: { type: string }
|
|
70
|
+
repo: { type: string }
|
|
71
|
+
description: { type: string }
|
|
72
|
+
sandbox: { type: string }
|
|
73
|
+
services:
|
|
74
|
+
type: object
|
|
75
|
+
additionalProperties:
|
|
76
|
+
type: object
|
|
77
|
+
properties:
|
|
78
|
+
image: { type: string }
|
|
79
|
+
ports:
|
|
80
|
+
type: array
|
|
81
|
+
items: { type: number }
|
|
82
|
+
environment:
|
|
83
|
+
type: object
|
|
84
|
+
additionalProperties: { type: string }
|
|
85
|
+
volumes:
|
|
86
|
+
type: array
|
|
87
|
+
items: { type: string }
|
|
88
|
+
healthcheck:
|
|
89
|
+
type: object
|
|
90
|
+
properties:
|
|
91
|
+
test:
|
|
92
|
+
type: array
|
|
93
|
+
items: { type: string }
|
|
94
|
+
interval: { type: string }
|
|
95
|
+
timeout: { type: string }
|
|
96
|
+
retries: { type: number }
|
|
97
|
+
required: [image]
|
|
98
|
+
setup:
|
|
99
|
+
type: array
|
|
100
|
+
items: { type: string }
|
|
101
|
+
knowledge: { type: string }
|
|
102
|
+
required: [id, repo, description]
|
|
103
|
+
|
|
104
|
+
- name: max_projects
|
|
105
|
+
default: 3
|
|
106
|
+
description: Maximum code projects to checkout (excludes docs)
|
|
107
|
+
schema:
|
|
108
|
+
type: number
|
|
109
|
+
|
|
110
|
+
- name: docs_ref
|
|
111
|
+
default: main
|
|
112
|
+
description: Git ref for docs repository
|
|
113
|
+
schema:
|
|
114
|
+
type: string
|
|
115
|
+
|
|
116
|
+
- name: routing_prompt
|
|
117
|
+
required: false
|
|
118
|
+
description: Additional routing instructions (appended to built-in)
|
|
119
|
+
schema:
|
|
120
|
+
type: string
|
|
121
|
+
|
|
122
|
+
- name: selected_projects
|
|
123
|
+
required: false
|
|
124
|
+
description: |
|
|
125
|
+
Pre-selected project IDs to skip AI routing. When provided,
|
|
126
|
+
route-projects is skipped and these projects are used directly.
|
|
127
|
+
default: []
|
|
128
|
+
schema:
|
|
129
|
+
type: array
|
|
130
|
+
items:
|
|
131
|
+
type: string
|
|
132
|
+
|
|
133
|
+
outputs:
|
|
134
|
+
- name: docs_path
|
|
135
|
+
description: Path where docs repo was checked out
|
|
136
|
+
value_js: |
|
|
137
|
+
return outputs?.['checkout-docs']?.path ?? null;
|
|
138
|
+
|
|
139
|
+
- name: project_items
|
|
140
|
+
description: Routed project descriptors with metadata
|
|
141
|
+
value_js: |
|
|
142
|
+
const historyItems = outputs?.history?.['project-items'];
|
|
143
|
+
const lastItems = Array.isArray(historyItems) ? historyItems[historyItems.length - 1] : historyItems;
|
|
144
|
+
return Array.isArray(lastItems) ? lastItems : (Array.isArray(outputs?.['project-items']) ? outputs['project-items'] : []);
|
|
145
|
+
|
|
146
|
+
- name: routing_decision
|
|
147
|
+
description: Raw routing output from AI (or null if pre-selected)
|
|
148
|
+
value_js: |
|
|
149
|
+
return outputs?.['route-projects'] ?? null;
|
|
150
|
+
|
|
151
|
+
- name: checkout_projects
|
|
152
|
+
description: Checked-out project paths aligned with routed projects
|
|
153
|
+
value_js: |
|
|
154
|
+
const historyItems = outputs?.history?.['project-items'];
|
|
155
|
+
const lastHistory = Array.isArray(historyItems) ? historyItems[historyItems.length - 1] : historyItems;
|
|
156
|
+
const items = Array.isArray(outputs?.['project-items'])
|
|
157
|
+
? outputs['project-items']
|
|
158
|
+
: Array.isArray(lastHistory)
|
|
159
|
+
? lastHistory
|
|
160
|
+
: [];
|
|
161
|
+
|
|
162
|
+
const checkoutOutput = outputs?.['checkout-projects'];
|
|
163
|
+
const checkouts = Array.isArray(checkoutOutput?.forEachItems)
|
|
164
|
+
? checkoutOutput.forEachItems
|
|
165
|
+
: Array.isArray(checkoutOutput)
|
|
166
|
+
? checkoutOutput
|
|
167
|
+
: [];
|
|
168
|
+
|
|
169
|
+
const result = [];
|
|
170
|
+
if (!Array.isArray(items) || !Array.isArray(checkouts)) return result;
|
|
171
|
+
|
|
172
|
+
for (let i = 0; i < items.length; i++) {
|
|
173
|
+
const item = items[i];
|
|
174
|
+
if (!item?.project_id) continue;
|
|
175
|
+
const checkout = checkouts[i] ?? {};
|
|
176
|
+
result.push({
|
|
177
|
+
project_id: item.project_id,
|
|
178
|
+
repository: item.repository ?? item.repo ?? '',
|
|
179
|
+
description: item.description ?? '',
|
|
180
|
+
path: checkout.path ?? checkout.workspace_path ?? '',
|
|
181
|
+
sandbox: item.sandbox ?? null,
|
|
182
|
+
services: item.services ?? null,
|
|
183
|
+
setup: item.setup ?? null,
|
|
184
|
+
knowledge: item.knowledge ?? null
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
return result;
|
|
188
|
+
|
|
189
|
+
steps:
|
|
190
|
+
# ===========================================================================
|
|
191
|
+
# Step 1: Checkout documentation (always first)
|
|
192
|
+
# ===========================================================================
|
|
193
|
+
checkout-docs:
|
|
194
|
+
type: git-checkout
|
|
195
|
+
criticality: internal
|
|
196
|
+
assume:
|
|
197
|
+
- "true"
|
|
198
|
+
repository: "{{ inputs.docs_repo }}"
|
|
199
|
+
ref: "{{ inputs.docs_ref }}"
|
|
200
|
+
fetch_depth: 1
|
|
201
|
+
description: "Documentation"
|
|
202
|
+
|
|
203
|
+
# ===========================================================================
|
|
204
|
+
# Step 2: Route to relevant projects (AI-based)
|
|
205
|
+
# Skipped when selected_projects are provided.
|
|
206
|
+
# ===========================================================================
|
|
207
|
+
route-projects:
|
|
208
|
+
type: ai
|
|
209
|
+
criticality: internal
|
|
210
|
+
depends_on: [checkout-docs]
|
|
211
|
+
continue_on_failure: true
|
|
212
|
+
if: "!inputs.selected_projects || inputs.selected_projects.length === 0"
|
|
213
|
+
assume:
|
|
214
|
+
- "true"
|
|
215
|
+
guarantee: "(output?.projects?.length ?? 0) > 0 || (output?.notes?.length ?? 0) > 0"
|
|
216
|
+
fail_if: "(output?.projects?.length ?? 0) === 0 && !(output?.notes?.length > 0)"
|
|
217
|
+
ai:
|
|
218
|
+
skip_code_context: true
|
|
219
|
+
prompt_type: general
|
|
220
|
+
system_prompt: |
|
|
221
|
+
<role>
|
|
222
|
+
You are a project routing planner. Given a question, you decide which
|
|
223
|
+
code repositories need to be queried. You do NOT answer questions
|
|
224
|
+
directly - you only plan which projects to consult.
|
|
225
|
+
</role>
|
|
226
|
+
|
|
227
|
+
<context_handling>
|
|
228
|
+
The full conversation context (e.g., Slack thread) may be available in
|
|
229
|
+
<slack_context>. Use it to understand the real question. If the latest
|
|
230
|
+
message is a correction, reconstruct the original question from earlier
|
|
231
|
+
messages. Questions may include appended ticket/page context.
|
|
232
|
+
</context_handling>
|
|
233
|
+
|
|
234
|
+
<architecture>
|
|
235
|
+
{{ inputs.architecture }}
|
|
236
|
+
</architecture>
|
|
237
|
+
|
|
238
|
+
<docs_context>
|
|
239
|
+
The documentation has been checked out and is available for reference.
|
|
240
|
+
Use it to understand feature behavior, configuration options, and
|
|
241
|
+
cross-component interactions before deciding which code projects to query.
|
|
242
|
+
Path: {{ outputs['checkout-docs'].path }}
|
|
243
|
+
</docs_context>
|
|
244
|
+
|
|
245
|
+
<available_projects>
|
|
246
|
+
{% for p in inputs.projects %}
|
|
247
|
+
- id: {{ p.id }}
|
|
248
|
+
repo: {{ p.repo }}
|
|
249
|
+
description: {{ p.description }}
|
|
250
|
+
{% endfor %}
|
|
251
|
+
</available_projects>
|
|
252
|
+
schema: |
|
|
253
|
+
{
|
|
254
|
+
"type": "object",
|
|
255
|
+
"additionalProperties": false,
|
|
256
|
+
"properties": {
|
|
257
|
+
"projects": {
|
|
258
|
+
"type": "array",
|
|
259
|
+
"description": "Projects to query for this question",
|
|
260
|
+
"items": {
|
|
261
|
+
"type": "object",
|
|
262
|
+
"additionalProperties": false,
|
|
263
|
+
"properties": {
|
|
264
|
+
"project_id": {
|
|
265
|
+
"type": "string",
|
|
266
|
+
"description": "One of the available project IDs",
|
|
267
|
+
"enum": [{% for p in inputs.projects %}"{{ p.id }}"{% unless forloop.last %}, {% endunless %}{% endfor %}]
|
|
268
|
+
},
|
|
269
|
+
"reason": {
|
|
270
|
+
"type": "string",
|
|
271
|
+
"description": "Brief explanation of why this project is relevant"
|
|
272
|
+
}
|
|
273
|
+
},
|
|
274
|
+
"required": ["project_id"]
|
|
275
|
+
}
|
|
276
|
+
},
|
|
277
|
+
"notes": {
|
|
278
|
+
"type": "string",
|
|
279
|
+
"description": "Optional planner notes"
|
|
280
|
+
}
|
|
281
|
+
},
|
|
282
|
+
"required": ["projects"]
|
|
283
|
+
}
|
|
284
|
+
prompt: |
|
|
285
|
+
<question>{{ inputs.question }}</question>
|
|
286
|
+
|
|
287
|
+
<task>
|
|
288
|
+
Determine which projects are needed to answer this question.
|
|
289
|
+
Consider all parts of the stack that the functionality touches, then
|
|
290
|
+
select the smallest set that covers the behavior.
|
|
291
|
+
|
|
292
|
+
Return a "projects" array with:
|
|
293
|
+
- "project_id": from the available project IDs listed above
|
|
294
|
+
- "reason" (optional): brief explanation of relevance
|
|
295
|
+
- If you cannot determine the relevant projects from the context,
|
|
296
|
+
return an empty "projects" array and include a "notes" string
|
|
297
|
+
asking for the missing details you need.
|
|
298
|
+
|
|
299
|
+
Routing guidelines:
|
|
300
|
+
- When functionality spans multiple components, include ALL affected projects
|
|
301
|
+
- It's better to include a small superset than to miss a relevant project
|
|
302
|
+
- Typical plans contain 1-3 projects, but include more when necessary
|
|
303
|
+
- Consider how data/config flows between services
|
|
304
|
+
- Maximum projects: {{ inputs.max_projects }}
|
|
305
|
+
</task>
|
|
306
|
+
|
|
307
|
+
{% if inputs.routing_prompt %}
|
|
308
|
+
<additional_routing_rules>
|
|
309
|
+
{{ inputs.routing_prompt }}
|
|
310
|
+
</additional_routing_rules>
|
|
311
|
+
{% endif %}
|
|
312
|
+
|
|
313
|
+
# ===========================================================================
|
|
314
|
+
# Step 3: Map routed projects to checkout descriptors
|
|
315
|
+
# Uses AI routing output when available, falls back to selected_projects.
|
|
316
|
+
# Depends on checkout-docs (not route-projects) to avoid skip cascade.
|
|
317
|
+
# ===========================================================================
|
|
318
|
+
project-items:
|
|
319
|
+
type: script
|
|
320
|
+
criticality: internal
|
|
321
|
+
depends_on: [checkout-docs, route-projects]
|
|
322
|
+
assume:
|
|
323
|
+
- "true"
|
|
324
|
+
guarantee: "Array.isArray(output)"
|
|
325
|
+
schema:
|
|
326
|
+
type: array
|
|
327
|
+
content: |
|
|
328
|
+
// Build a map of project ID -> project info from inputs
|
|
329
|
+
const projectMap = {};
|
|
330
|
+
const inputProjects = Array.isArray(inputs?.projects) ? inputs.projects : [];
|
|
331
|
+
for (let i = 0; i < inputProjects.length; i++) {
|
|
332
|
+
const p = inputProjects[i];
|
|
333
|
+
if (p?.id) {
|
|
334
|
+
projectMap[p.id] = {
|
|
335
|
+
repo: p.repo,
|
|
336
|
+
description: p.description ?? p.id,
|
|
337
|
+
sandbox: p.sandbox ?? null,
|
|
338
|
+
services: p.services ?? null,
|
|
339
|
+
setup: p.setup ?? null,
|
|
340
|
+
knowledge: p.knowledge ?? null
|
|
341
|
+
};
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
// Determine routed projects: AI output or pre-selected
|
|
346
|
+
let routedProjects = [];
|
|
347
|
+
const routeOutput = outputs?.['route-projects'];
|
|
348
|
+
if (routeOutput && Array.isArray(routeOutput.projects)) {
|
|
349
|
+
routedProjects = routeOutput.projects;
|
|
350
|
+
} else {
|
|
351
|
+
// Fall back to selected_projects input
|
|
352
|
+
const selected = Array.isArray(inputs?.selected_projects) ? inputs.selected_projects : [];
|
|
353
|
+
for (let s = 0; s < selected.length; s++) {
|
|
354
|
+
routedProjects.push({ project_id: selected[s], reason: 'pre-selected' });
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
// Map to checkout descriptors
|
|
359
|
+
const result = [];
|
|
360
|
+
const maxProjects = inputs?.max_projects ?? 3;
|
|
361
|
+
|
|
362
|
+
for (let j = 0; j < routedProjects.length && result.length < maxProjects; j++) {
|
|
363
|
+
const routed = routedProjects[j];
|
|
364
|
+
if (!routed?.project_id) continue;
|
|
365
|
+
|
|
366
|
+
const info = projectMap[routed.project_id];
|
|
367
|
+
// Skip unknown project IDs (not in inputs.projects)
|
|
368
|
+
if (!info?.repo) continue;
|
|
369
|
+
|
|
370
|
+
result.push({
|
|
371
|
+
project_id: routed.project_id,
|
|
372
|
+
reason: routed.reason ?? '',
|
|
373
|
+
repository: info.repo,
|
|
374
|
+
description: info.description,
|
|
375
|
+
sandbox: info.sandbox,
|
|
376
|
+
services: info.services,
|
|
377
|
+
setup: info.setup,
|
|
378
|
+
knowledge: info.knowledge
|
|
379
|
+
});
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
return result;
|
|
383
|
+
forEach: true
|
|
384
|
+
|
|
385
|
+
# ===========================================================================
|
|
386
|
+
# Step 4: Checkout each selected project
|
|
387
|
+
# ===========================================================================
|
|
388
|
+
checkout-projects:
|
|
389
|
+
type: git-checkout
|
|
390
|
+
criticality: internal
|
|
391
|
+
depends_on: [project-items]
|
|
392
|
+
assume:
|
|
393
|
+
- "output != null"
|
|
394
|
+
repository: "{{ outputs['project-items'].repository }}"
|
|
395
|
+
ref: main
|
|
396
|
+
fetch_depth: 1
|
|
397
|
+
description: "{{ outputs['project-items'].description }}"
|
|
398
|
+
|
|
399
|
+
# =============================================================================
|
|
400
|
+
# Tests
|
|
401
|
+
# =============================================================================
|
|
402
|
+
tests:
|
|
403
|
+
defaults:
|
|
404
|
+
strict: true
|
|
405
|
+
ai_provider: mock
|
|
406
|
+
|
|
407
|
+
cases:
|
|
408
|
+
- name: basic-routing
|
|
409
|
+
event: manual
|
|
410
|
+
fixture: local.minimal
|
|
411
|
+
workflow_input:
|
|
412
|
+
question: "How does authentication work?"
|
|
413
|
+
architecture: |
|
|
414
|
+
# Architecture
|
|
415
|
+
## Projects
|
|
416
|
+
- gateway: API Gateway
|
|
417
|
+
- backend: Backend services
|
|
418
|
+
docs_repo: org/docs
|
|
419
|
+
projects:
|
|
420
|
+
- id: gateway
|
|
421
|
+
repo: org/gateway
|
|
422
|
+
description: API Gateway
|
|
423
|
+
- id: backend
|
|
424
|
+
repo: org/backend
|
|
425
|
+
description: Backend services
|
|
426
|
+
mocks:
|
|
427
|
+
checkout-docs:
|
|
428
|
+
path: "/tmp/visor/docs"
|
|
429
|
+
repository: "org/docs"
|
|
430
|
+
ref: "main"
|
|
431
|
+
checkout-projects:
|
|
432
|
+
path: "/tmp/visor/project"
|
|
433
|
+
repository: "org/gateway"
|
|
434
|
+
ref: "main"
|
|
435
|
+
route-projects:
|
|
436
|
+
projects:
|
|
437
|
+
- project_id: "gateway"
|
|
438
|
+
reason: "Gateway handles authentication"
|
|
439
|
+
expect:
|
|
440
|
+
calls:
|
|
441
|
+
- step: checkout-docs
|
|
442
|
+
exactly: 1
|
|
443
|
+
- step: route-projects
|
|
444
|
+
exactly: 1
|
|
445
|
+
- step: project-items
|
|
446
|
+
exactly: 1
|
|
447
|
+
- step: checkout-projects
|
|
448
|
+
exactly: 1
|
|
449
|
+
prompts:
|
|
450
|
+
- step: route-projects
|
|
451
|
+
contains:
|
|
452
|
+
- "How does authentication work?"
|
|
453
|
+
- "Maximum projects:"
|
|
454
|
+
|
|
455
|
+
- name: pre-selected-projects
|
|
456
|
+
event: manual
|
|
457
|
+
fixture: local.minimal
|
|
458
|
+
workflow_input:
|
|
459
|
+
question: "Fix the auth bug"
|
|
460
|
+
architecture: "# Arch"
|
|
461
|
+
docs_repo: org/docs
|
|
462
|
+
projects:
|
|
463
|
+
- id: gateway
|
|
464
|
+
repo: org/gateway
|
|
465
|
+
description: API Gateway
|
|
466
|
+
- id: backend
|
|
467
|
+
repo: org/backend
|
|
468
|
+
description: Backend services
|
|
469
|
+
selected_projects:
|
|
470
|
+
- gateway
|
|
471
|
+
mocks:
|
|
472
|
+
checkout-docs:
|
|
473
|
+
path: "/tmp/visor/docs"
|
|
474
|
+
repository: "org/docs"
|
|
475
|
+
ref: "main"
|
|
476
|
+
checkout-projects:
|
|
477
|
+
path: "/tmp/visor/project"
|
|
478
|
+
repository: "org/gateway"
|
|
479
|
+
ref: "main"
|
|
480
|
+
expect:
|
|
481
|
+
calls:
|
|
482
|
+
- step: checkout-docs
|
|
483
|
+
exactly: 1
|
|
484
|
+
- step: route-projects
|
|
485
|
+
exactly: 0
|
|
486
|
+
- step: project-items
|
|
487
|
+
exactly: 1
|
|
488
|
+
- step: checkout-projects
|
|
489
|
+
exactly: 1
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# =============================================================================
|
|
2
|
+
# Default engineer skill shipped with visor
|
|
3
|
+
# =============================================================================
|
|
4
|
+
#
|
|
5
|
+
# Provides a ready-to-use code modification capability. Users only need to
|
|
6
|
+
# provide project-specific config (repos, architecture) via extends:
|
|
7
|
+
#
|
|
8
|
+
# - extends: "visor://skills/engineer.yaml"
|
|
9
|
+
# tools:
|
|
10
|
+
# engineer:
|
|
11
|
+
# inputs:
|
|
12
|
+
# expression: "loadConfig('config/my-projects.yaml')"
|
|
13
|
+
#
|
|
14
|
+
# =============================================================================
|
|
15
|
+
|
|
16
|
+
id: engineer
|
|
17
|
+
description: >
|
|
18
|
+
user wants to modify files, edit code, fix bugs, implement features,
|
|
19
|
+
refactor code, or create a pull request. READ-WRITE — can modify files
|
|
20
|
+
and create PRs.
|
|
21
|
+
requires: [code-explorer]
|
|
22
|
+
knowledge: |
|
|
23
|
+
## Engineer — Code Changes and PR Creation
|
|
24
|
+
The `engineer` tool modifies code, implements features, fixes bugs, and creates PRs.
|
|
25
|
+
|
|
26
|
+
**IMPORTANT**: Call `code-explorer` FIRST to understand the codebase before making changes.
|
|
27
|
+
The engineer tool needs pre-resolved project paths from code-explorer's output.
|
|
28
|
+
|
|
29
|
+
Workflow:
|
|
30
|
+
1. Use `code-explorer` to investigate and understand relevant code
|
|
31
|
+
2. Pass the explored project information to `engineer` for implementation
|
|
32
|
+
3. The engineer will create branches, make changes, run tests, and optionally create PRs
|
|
33
|
+
|
|
34
|
+
The tool returns:
|
|
35
|
+
- `text`: Summary of changes made
|
|
36
|
+
- `changes`: Array of modified files with actions (created/modified/deleted)
|
|
37
|
+
- `pr_url`: URL of created pull request (if applicable)
|
|
38
|
+
tools:
|
|
39
|
+
engineer:
|
|
40
|
+
workflow: engineer
|
|
41
|
+
inputs: {}
|