@probelabs/visor 0.1.107 → 0.1.112

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 (235) hide show
  1. package/README.md +6 -0
  2. package/defaults/task-refinement.yaml +7 -3
  3. package/defaults/visor.tests.yaml +13 -2
  4. package/defaults/visor.yaml +1 -0
  5. package/dist/663.index.js +3 -2
  6. package/dist/80.index.js +3 -2
  7. package/dist/ai-review-service.d.ts +13 -9
  8. package/dist/ai-review-service.d.ts.map +1 -1
  9. package/dist/cli-main.d.ts.map +1 -1
  10. package/dist/cli.d.ts.map +1 -1
  11. package/dist/config.d.ts.map +1 -1
  12. package/dist/debug-visualizer/ws-server.d.ts +7 -1
  13. package/dist/debug-visualizer/ws-server.d.ts.map +1 -1
  14. package/dist/defaults/task-refinement.yaml +7 -3
  15. package/dist/defaults/visor.tests.yaml +13 -2
  16. package/dist/defaults/visor.yaml +1 -0
  17. package/dist/docs/advanced-ai.md +60 -1
  18. package/dist/docs/ai-configuration.md +67 -0
  19. package/dist/docs/ai-custom-tools-usage.md +261 -0
  20. package/dist/docs/ai-custom-tools.md +392 -0
  21. package/dist/docs/bot-transports-rfc.md +23 -0
  22. package/dist/docs/configuration.md +21 -0
  23. package/dist/docs/engine-pause-resume-rfc.md +192 -0
  24. package/dist/docs/lifecycle-hooks.md +253 -0
  25. package/dist/docs/liquid-templates.md +143 -0
  26. package/dist/docs/providers/git-checkout.md +589 -0
  27. package/dist/docs/recipes.md +458 -5
  28. package/dist/docs/rfc/git-checkout-step.md +601 -0
  29. package/dist/docs/rfc/on_init-hook.md +1294 -0
  30. package/dist/docs/rfc/workspace-isolation.md +216 -0
  31. package/dist/docs/router-patterns.md +339 -0
  32. package/dist/event-bus/types.d.ts +14 -0
  33. package/dist/event-bus/types.d.ts.map +1 -1
  34. package/dist/examples/ai-custom-tools-example.yaml +206 -0
  35. package/dist/examples/ai-custom-tools-simple.yaml +76 -0
  36. package/dist/examples/git-checkout-basic.yaml +32 -0
  37. package/dist/examples/git-checkout-compare.yaml +59 -0
  38. package/dist/examples/git-checkout-cross-repo.yaml +76 -0
  39. package/dist/examples/on-init-import-demo.yaml +179 -0
  40. package/dist/examples/reusable-tools.yaml +92 -0
  41. package/dist/examples/reusable-workflows.yaml +88 -0
  42. package/dist/examples/session-reuse-self.yaml +81 -0
  43. package/dist/examples/slack-simple-chat.yaml +775 -0
  44. package/dist/failure-condition-evaluator.d.ts +2 -0
  45. package/dist/failure-condition-evaluator.d.ts.map +1 -1
  46. package/dist/frontends/github-frontend.d.ts +20 -0
  47. package/dist/frontends/github-frontend.d.ts.map +1 -1
  48. package/dist/frontends/host.d.ts +4 -0
  49. package/dist/frontends/host.d.ts.map +1 -1
  50. package/dist/frontends/slack-frontend.d.ts +58 -0
  51. package/dist/frontends/slack-frontend.d.ts.map +1 -0
  52. package/dist/generated/config-schema.d.ts +409 -41
  53. package/dist/generated/config-schema.d.ts.map +1 -1
  54. package/dist/generated/config-schema.json +436 -47
  55. package/dist/github-comments.d.ts +2 -0
  56. package/dist/github-comments.d.ts.map +1 -1
  57. package/dist/index.d.ts.map +1 -1
  58. package/dist/index.js +83587 -56085
  59. package/dist/liquid-extensions.d.ts.map +1 -1
  60. package/dist/logger.d.ts +1 -0
  61. package/dist/logger.d.ts.map +1 -1
  62. package/dist/output/traces/{run-2025-11-21T11-50-46-505Z.ndjson → run-2026-01-21T05-37-24-446Z.ndjson} +91 -91
  63. package/dist/output/traces/run-2026-01-21T05-38-18-580Z.ndjson +1067 -0
  64. package/dist/output-formatters.d.ts.map +1 -1
  65. package/dist/providers/ai-check-provider.d.ts +12 -0
  66. package/dist/providers/ai-check-provider.d.ts.map +1 -1
  67. package/dist/providers/check-provider-registry.d.ts.map +1 -1
  68. package/dist/providers/check-provider.interface.d.ts +9 -0
  69. package/dist/providers/check-provider.interface.d.ts.map +1 -1
  70. package/dist/providers/command-check-provider.d.ts.map +1 -1
  71. package/dist/providers/custom-tool-executor.d.ts.map +1 -1
  72. package/dist/providers/git-checkout-provider.d.ts +25 -0
  73. package/dist/providers/git-checkout-provider.d.ts.map +1 -0
  74. package/dist/providers/http-client-provider.d.ts +3 -0
  75. package/dist/providers/http-client-provider.d.ts.map +1 -1
  76. package/dist/providers/human-input-check-provider.d.ts +2 -0
  77. package/dist/providers/human-input-check-provider.d.ts.map +1 -1
  78. package/dist/providers/log-check-provider.d.ts.map +1 -1
  79. package/dist/providers/mcp-check-provider.d.ts +1 -1
  80. package/dist/providers/mcp-check-provider.d.ts.map +1 -1
  81. package/dist/providers/mcp-custom-sse-server.d.ts +66 -0
  82. package/dist/providers/mcp-custom-sse-server.d.ts.map +1 -0
  83. package/dist/providers/memory-check-provider.d.ts.map +1 -1
  84. package/dist/providers/script-check-provider.d.ts.map +1 -1
  85. package/dist/providers/workflow-check-provider.d.ts.map +1 -1
  86. package/dist/reviewer.d.ts.map +1 -1
  87. package/dist/sdk/check-provider-registry-534KL5HT.mjs +27 -0
  88. package/dist/sdk/chunk-23L3QRYX.mjs +16872 -0
  89. package/dist/sdk/chunk-23L3QRYX.mjs.map +1 -0
  90. package/dist/sdk/{chunk-OOZITMRU.mjs → chunk-3OMWVM6J.mjs} +11 -1
  91. package/dist/sdk/{chunk-OOZITMRU.mjs.map → chunk-3OMWVM6J.mjs.map} +1 -1
  92. package/dist/sdk/{chunk-37ZSCMFC.mjs → chunk-7UK3NIIT.mjs} +2 -2
  93. package/dist/sdk/{chunk-VMPLF6FT.mjs → chunk-AGIZJ4UZ.mjs} +50 -4
  94. package/dist/sdk/chunk-AGIZJ4UZ.mjs.map +1 -0
  95. package/dist/sdk/{chunk-IEO6CFLG.mjs → chunk-AIVFBIS4.mjs} +161 -5
  96. package/dist/sdk/chunk-AIVFBIS4.mjs.map +1 -0
  97. package/dist/sdk/chunk-AK6BVWIT.mjs +426 -0
  98. package/dist/sdk/chunk-AK6BVWIT.mjs.map +1 -0
  99. package/dist/sdk/chunk-AUT26LHW.mjs +139 -0
  100. package/dist/sdk/chunk-AUT26LHW.mjs.map +1 -0
  101. package/dist/sdk/chunk-BOVFH3LI.mjs +232 -0
  102. package/dist/sdk/chunk-BOVFH3LI.mjs.map +1 -0
  103. package/dist/sdk/chunk-HTOKWMPO.mjs +157 -0
  104. package/dist/sdk/chunk-HTOKWMPO.mjs.map +1 -0
  105. package/dist/sdk/{chunk-6Y4YTKCF.mjs → chunk-NAW3DB3I.mjs} +2 -2
  106. package/dist/sdk/{chunk-OWUVOILT.mjs → chunk-QR7MOMJH.mjs} +4 -3
  107. package/dist/sdk/{chunk-OWUVOILT.mjs.map → chunk-QR7MOMJH.mjs.map} +1 -1
  108. package/dist/sdk/{chunk-PTL3K3PN.mjs → chunk-QY2XYPEV.mjs} +488 -60
  109. package/dist/sdk/chunk-QY2XYPEV.mjs.map +1 -0
  110. package/dist/sdk/{chunk-OZJ263FM.mjs → chunk-SIWNBRTK.mjs} +29 -215
  111. package/dist/sdk/chunk-SIWNBRTK.mjs.map +1 -0
  112. package/dist/sdk/command-executor-TYUV6HUS.mjs +14 -0
  113. package/dist/sdk/{config-M4ZNO6NU.mjs → config-YNC2EOOT.mjs} +5 -3
  114. package/dist/sdk/{failure-condition-evaluator-NBO5YRXW.mjs → failure-condition-evaluator-YGTF2GHG.mjs} +6 -5
  115. package/dist/sdk/{github-frontend-4AWRJT7D.mjs → github-frontend-SIAEOCON.mjs} +190 -12
  116. package/dist/sdk/github-frontend-SIAEOCON.mjs.map +1 -0
  117. package/dist/sdk/{host-7GBC3S7L.mjs → host-DXUYTNMU.mjs} +5 -2
  118. package/dist/sdk/host-DXUYTNMU.mjs.map +1 -0
  119. package/dist/sdk/{liquid-extensions-C7EG3YKH.mjs → liquid-extensions-PKWCKK7E.mjs} +5 -4
  120. package/dist/sdk/memory-store-XGBB7LX7.mjs +12 -0
  121. package/dist/sdk/prompt-state-YRJY6QAL.mjs +16 -0
  122. package/dist/sdk/{renderer-schema-6RF26VUS.mjs → renderer-schema-LPKN5UJS.mjs} +3 -2
  123. package/dist/sdk/{renderer-schema-6RF26VUS.mjs.map → renderer-schema-LPKN5UJS.mjs.map} +1 -1
  124. package/dist/sdk/{routing-RP56JTV2.mjs → routing-6N45MJ4F.mjs} +7 -6
  125. package/dist/sdk/sdk.d.mts +219 -5
  126. package/dist/sdk/sdk.d.ts +219 -5
  127. package/dist/sdk/sdk.js +21329 -14908
  128. package/dist/sdk/sdk.js.map +1 -1
  129. package/dist/sdk/sdk.mjs +407 -12874
  130. package/dist/sdk/sdk.mjs.map +1 -1
  131. package/dist/sdk/{session-registry-N5FFYFTM.mjs → session-registry-4E6YRQ77.mjs} +2 -2
  132. package/dist/sdk/session-registry-4E6YRQ77.mjs.map +1 -0
  133. package/dist/sdk/slack-frontend-BVKW3GD5.mjs +735 -0
  134. package/dist/sdk/slack-frontend-BVKW3GD5.mjs.map +1 -0
  135. package/dist/sdk/{tracer-init-WP4X46IF.mjs → tracer-init-GSLPPLCD.mjs} +2 -2
  136. package/dist/sdk/tracer-init-GSLPPLCD.mjs.map +1 -0
  137. package/dist/sdk/workflow-registry-R6KSACFR.mjs +12 -0
  138. package/dist/sdk/workflow-registry-R6KSACFR.mjs.map +1 -0
  139. package/dist/slack/adapter.d.ts +36 -0
  140. package/dist/slack/adapter.d.ts.map +1 -0
  141. package/dist/slack/cache-prewarmer.d.ts +31 -0
  142. package/dist/slack/cache-prewarmer.d.ts.map +1 -0
  143. package/dist/slack/client.d.ts +77 -0
  144. package/dist/slack/client.d.ts.map +1 -0
  145. package/dist/slack/markdown.d.ts +45 -0
  146. package/dist/slack/markdown.d.ts.map +1 -0
  147. package/dist/slack/prompt-state.d.ts +33 -0
  148. package/dist/slack/prompt-state.d.ts.map +1 -0
  149. package/dist/slack/rate-limiter.d.ts +56 -0
  150. package/dist/slack/rate-limiter.d.ts.map +1 -0
  151. package/dist/slack/signature.d.ts +2 -0
  152. package/dist/slack/signature.d.ts.map +1 -0
  153. package/dist/slack/socket-runner.d.ts +42 -0
  154. package/dist/slack/socket-runner.d.ts.map +1 -0
  155. package/dist/slack/thread-cache.d.ts +51 -0
  156. package/dist/slack/thread-cache.d.ts.map +1 -0
  157. package/dist/state-machine/context/build-engine-context.d.ts +8 -0
  158. package/dist/state-machine/context/build-engine-context.d.ts.map +1 -1
  159. package/dist/state-machine/dispatch/execution-invoker.d.ts.map +1 -1
  160. package/dist/state-machine/dispatch/foreach-processor.d.ts.map +1 -1
  161. package/dist/state-machine/dispatch/on-init-handlers.d.ts +43 -0
  162. package/dist/state-machine/dispatch/on-init-handlers.d.ts.map +1 -0
  163. package/dist/state-machine/dispatch/stats-manager.d.ts.map +1 -1
  164. package/dist/state-machine/dispatch/template-renderer.d.ts.map +1 -1
  165. package/dist/state-machine/runner.d.ts +6 -0
  166. package/dist/state-machine/runner.d.ts.map +1 -1
  167. package/dist/state-machine/states/level-dispatch.d.ts.map +1 -1
  168. package/dist/state-machine/states/plan-ready.d.ts.map +1 -1
  169. package/dist/state-machine/states/routing.d.ts.map +1 -1
  170. package/dist/state-machine/states/wave-planning.d.ts.map +1 -1
  171. package/dist/state-machine/workflow-projection.d.ts.map +1 -1
  172. package/dist/state-machine-execution-engine.d.ts +21 -9
  173. package/dist/state-machine-execution-engine.d.ts.map +1 -1
  174. package/dist/telemetry/state-capture.d.ts +5 -0
  175. package/dist/telemetry/state-capture.d.ts.map +1 -1
  176. package/dist/test-runner/core/flow-stage.d.ts.map +1 -1
  177. package/dist/test-runner/core/test-execution-wrapper.d.ts.map +1 -1
  178. package/dist/test-runner/evaluators.d.ts +37 -4
  179. package/dist/test-runner/evaluators.d.ts.map +1 -1
  180. package/dist/test-runner/index.d.ts +7 -0
  181. package/dist/test-runner/index.d.ts.map +1 -1
  182. package/dist/test-runner/recorders/slack-recorder.d.ts +17 -0
  183. package/dist/test-runner/recorders/slack-recorder.d.ts.map +1 -0
  184. package/dist/test-runner/validator.d.ts.map +1 -1
  185. package/dist/traces/{run-2025-11-21T11-50-46-505Z.ndjson → run-2026-01-21T05-37-24-446Z.ndjson} +91 -91
  186. package/dist/traces/run-2026-01-21T05-38-18-580Z.ndjson +1067 -0
  187. package/dist/types/bot.d.ts +109 -0
  188. package/dist/types/bot.d.ts.map +1 -0
  189. package/dist/types/cli.d.ts +4 -0
  190. package/dist/types/cli.d.ts.map +1 -1
  191. package/dist/types/config.d.ts +182 -5
  192. package/dist/types/config.d.ts.map +1 -1
  193. package/dist/types/engine.d.ts +5 -0
  194. package/dist/types/engine.d.ts.map +1 -1
  195. package/dist/types/git-checkout.d.ts +76 -0
  196. package/dist/types/git-checkout.d.ts.map +1 -0
  197. package/dist/utils/json-text-extractor.d.ts +17 -0
  198. package/dist/utils/json-text-extractor.d.ts.map +1 -0
  199. package/dist/utils/sandbox.d.ts +10 -0
  200. package/dist/utils/sandbox.d.ts.map +1 -1
  201. package/dist/utils/template-context.d.ts +1 -0
  202. package/dist/utils/template-context.d.ts.map +1 -1
  203. package/dist/utils/tracer-init.d.ts.map +1 -1
  204. package/dist/utils/workspace-manager.d.ts +118 -0
  205. package/dist/utils/workspace-manager.d.ts.map +1 -0
  206. package/dist/utils/worktree-cleanup.d.ts +33 -0
  207. package/dist/utils/worktree-cleanup.d.ts.map +1 -0
  208. package/dist/utils/worktree-manager.d.ts +153 -0
  209. package/dist/utils/worktree-manager.d.ts.map +1 -0
  210. package/dist/webhook-server.d.ts.map +1 -1
  211. package/dist/workflow-executor.d.ts.map +1 -1
  212. package/dist/workflow-registry.d.ts.map +1 -1
  213. package/package.json +5 -4
  214. package/dist/output/traces/run-2025-11-21T11-51-33-674Z.ndjson +0 -839
  215. package/dist/sdk/chunk-IEO6CFLG.mjs.map +0 -1
  216. package/dist/sdk/chunk-JEHPDJIF.mjs +0 -223
  217. package/dist/sdk/chunk-JEHPDJIF.mjs.map +0 -1
  218. package/dist/sdk/chunk-OZJ263FM.mjs.map +0 -1
  219. package/dist/sdk/chunk-PTL3K3PN.mjs.map +0 -1
  220. package/dist/sdk/chunk-VMPLF6FT.mjs.map +0 -1
  221. package/dist/sdk/github-frontend-4AWRJT7D.mjs.map +0 -1
  222. package/dist/sdk/host-7GBC3S7L.mjs.map +0 -1
  223. package/dist/sdk/memory-store-GJACZC2A.mjs +0 -11
  224. package/dist/sdk/workflow-registry-2YIIXQCK.mjs +0 -11
  225. package/dist/traces/run-2025-11-21T11-51-33-674Z.ndjson +0 -839
  226. /package/dist/sdk/{config-M4ZNO6NU.mjs.map → check-provider-registry-534KL5HT.mjs.map} +0 -0
  227. /package/dist/sdk/{chunk-37ZSCMFC.mjs.map → chunk-7UK3NIIT.mjs.map} +0 -0
  228. /package/dist/sdk/{chunk-6Y4YTKCF.mjs.map → chunk-NAW3DB3I.mjs.map} +0 -0
  229. /package/dist/sdk/{failure-condition-evaluator-NBO5YRXW.mjs.map → command-executor-TYUV6HUS.mjs.map} +0 -0
  230. /package/dist/sdk/{liquid-extensions-C7EG3YKH.mjs.map → config-YNC2EOOT.mjs.map} +0 -0
  231. /package/dist/sdk/{memory-store-GJACZC2A.mjs.map → failure-condition-evaluator-YGTF2GHG.mjs.map} +0 -0
  232. /package/dist/sdk/{routing-RP56JTV2.mjs.map → liquid-extensions-PKWCKK7E.mjs.map} +0 -0
  233. /package/dist/sdk/{session-registry-N5FFYFTM.mjs.map → memory-store-XGBB7LX7.mjs.map} +0 -0
  234. /package/dist/sdk/{tracer-init-WP4X46IF.mjs.map → prompt-state-YRJY6QAL.mjs.map} +0 -0
  235. /package/dist/sdk/{workflow-registry-2YIIXQCK.mjs.map → routing-6N45MJ4F.mjs.map} +0 -0
@@ -0,0 +1,589 @@
1
+ # Git Checkout Provider
2
+
3
+ The `git-checkout` provider enables workflows to checkout code from git repositories using efficient worktree management for multi-workflow execution.
4
+
5
+ ## Features
6
+
7
+ - **Git Worktrees**: Efficient disk usage by sharing git objects across checkouts
8
+ - **Dynamic Variables**: Support for Liquid templates to resolve branches/refs dynamically
9
+ - **Parallel Workflows**: Multiple workflows can checkout different branches simultaneously
10
+ - **Automatic Cleanup**: Worktrees are cleaned up when workflows complete
11
+ - **GitHub Actions Compatible**: Similar configuration to `actions/checkout@v4`
12
+
13
+ ## Configuration
14
+
15
+ ### Basic Usage
16
+
17
+ ```yaml
18
+ version: "1.0"
19
+
20
+ steps:
21
+ checkout:
22
+ type: git-checkout
23
+ ref: "{{ pr.head }}"
24
+ ```
25
+
26
+ ### Full Configuration Options
27
+
28
+ ```yaml
29
+ steps:
30
+ checkout-with-options:
31
+ type: git-checkout
32
+
33
+ # Required: Git reference to checkout
34
+ ref: "{{ pr.head }}" # Branch, tag, commit SHA, or dynamic variable
35
+
36
+ # Optional: Repository (defaults to current PR repository)
37
+ repository: owner/repo # GitHub repository or URL
38
+
39
+ # Optional: Authentication token (defaults to GITHUB_TOKEN env var)
40
+ token: "{{ env.GITHUB_TOKEN }}"
41
+
42
+ # Optional: Fetch configuration
43
+ fetch_depth: 1 # Shallow clone depth (default: 1)
44
+ fetch_tags: false # Fetch tags (default: false)
45
+ submodules: false # Checkout submodules (default: false)
46
+ # Can be: true, false, or 'recursive'
47
+
48
+ # Optional: Working directory (auto-generated if not specified)
49
+ working_directory: /tmp/my-checkout
50
+
51
+ # Optional: Worktree behavior
52
+ use_worktree: true # Use git worktrees (default: true)
53
+ clean: true # Clean before checkout (default: true)
54
+
55
+ # Optional: Advanced features
56
+ sparse_checkout: [] # Sparse checkout paths
57
+ lfs: false # Git LFS support (default: false)
58
+
59
+ # Standard check options
60
+ timeout: 60 # Timeout in seconds (default: 60)
61
+ criticality: internal
62
+ depends_on: []
63
+ if: "true"
64
+
65
+ # Cleanup behavior
66
+ cleanup_on_failure: true # Cleanup if step fails (default: true)
67
+ persist_worktree: false # Keep worktree after workflow (default: false)
68
+ ```
69
+
70
+ ## Output
71
+
72
+ The provider returns the following output structure:
73
+
74
+ ```typescript
75
+ {
76
+ success: boolean, // Whether checkout succeeded
77
+ path: string, // Absolute path to checked out code
78
+ ref: string, // Resolved ref that was checked out
79
+ commit: string, // Full commit SHA
80
+ worktree_id: string, // Unique worktree identifier
81
+ repository: string, // Repository that was checked out
82
+ is_worktree: boolean, // Whether this is a worktree
83
+ error?: string, // Error message if failed
84
+ }
85
+ ```
86
+
87
+ ## Examples
88
+
89
+ ### Example 1: Checkout PR Head
90
+
91
+ ```yaml
92
+ version: "1.0"
93
+
94
+ steps:
95
+ checkout:
96
+ type: git-checkout
97
+ ref: "{{ pr.head }}"
98
+
99
+ build:
100
+ type: command
101
+ depends_on: [checkout]
102
+ exec: "npm run build"
103
+ working_directory: "{{ outputs.checkout.path }}"
104
+ ```
105
+
106
+ ### Example 2: Checkout Multiple Branches
107
+
108
+ ```yaml
109
+ version: "1.0"
110
+
111
+ steps:
112
+ checkout-head:
113
+ type: git-checkout
114
+ ref: "{{ pr.head }}"
115
+
116
+ checkout-base:
117
+ type: git-checkout
118
+ ref: "{{ pr.base }}"
119
+
120
+ compare:
121
+ type: command
122
+ depends_on: [checkout-head, checkout-base]
123
+ exec: |
124
+ echo "Comparing branches:"
125
+ echo "Head: {{ outputs['checkout-head'].commit }}"
126
+ echo "Base: {{ outputs['checkout-base'].commit }}"
127
+ diff -r "{{ outputs['checkout-head'].path }}" "{{ outputs['checkout-base'].path }}" || true
128
+ ```
129
+
130
+ ### Example 3: Cross-Repository Checkout
131
+
132
+ ```yaml
133
+ version: "1.0"
134
+
135
+ steps:
136
+ checkout-main:
137
+ type: git-checkout
138
+ repository: myorg/main-repo
139
+ ref: main
140
+
141
+ checkout-dependency:
142
+ type: git-checkout
143
+ repository: myorg/dependency-repo
144
+ ref: v1.0.0
145
+ token: "{{ env.DEPENDENCY_TOKEN }}"
146
+
147
+ integration-test:
148
+ type: command
149
+ depends_on: [checkout-main, checkout-dependency]
150
+ exec: ./scripts/integration-test.sh
151
+ working_directory: "{{ outputs['checkout-main'].path }}"
152
+ env:
153
+ DEPENDENCY_PATH: "{{ outputs['checkout-dependency'].path }}"
154
+ ```
155
+
156
+ ### Example 4: Dynamic Branch Resolution
157
+
158
+ ```yaml
159
+ version: "1.0"
160
+
161
+ steps:
162
+ determine-branch:
163
+ type: command
164
+ exec: |
165
+ if [ "{{ pr.base }}" == "main" ]; then
166
+ echo '{"branch": "stable"}'
167
+ else
168
+ echo '{"branch": "{{ pr.base }}"}'
169
+ fi
170
+ transform_js: JSON.parse(output)
171
+
172
+ checkout-resolved:
173
+ type: git-checkout
174
+ depends_on: [determine-branch]
175
+ ref: "{{ outputs['determine-branch'].branch }}"
176
+ ```
177
+
178
+ ### Example 5: Sparse Checkout
179
+
180
+ ```yaml
181
+ version: "1.0"
182
+
183
+ steps:
184
+ checkout-partial:
185
+ type: git-checkout
186
+ ref: main
187
+ sparse_checkout:
188
+ - src/
189
+ - tests/
190
+ - package.json
191
+ - package-lock.json
192
+
193
+ test:
194
+ type: command
195
+ depends_on: [checkout-partial]
196
+ exec: npm test
197
+ working_directory: "{{ outputs['checkout-partial'].path }}"
198
+ ```
199
+
200
+ ### Example 6: Deep Clone with Full History
201
+
202
+ ```yaml
203
+ version: "1.0"
204
+
205
+ steps:
206
+ checkout-full:
207
+ type: git-checkout
208
+ ref: main
209
+ fetch_depth: 0 # Full history
210
+ fetch_tags: true # Include all tags
211
+
212
+ analyze-history:
213
+ type: command
214
+ depends_on: [checkout-full]
215
+ exec: |
216
+ git log --oneline --graph --all --decorate
217
+ git describe --tags --always
218
+ working_directory: "{{ outputs['checkout-full'].path }}"
219
+ ```
220
+
221
+ ### Example 7: Submodules Support
222
+
223
+ ```yaml
224
+ version: "1.0"
225
+
226
+ steps:
227
+ checkout-with-submodules:
228
+ type: git-checkout
229
+ ref: "{{ pr.head }}"
230
+ submodules: recursive
231
+
232
+ build-all:
233
+ type: command
234
+ depends_on: [checkout-with-submodules]
235
+ exec: |
236
+ npm install
237
+ npm run build
238
+ working_directory: "{{ outputs['checkout-with-submodules'].path }}"
239
+ ```
240
+
241
+ ### Example 8: Conditional Checkout
242
+
243
+ ```yaml
244
+ version: "1.0"
245
+
246
+ steps:
247
+ check-should-checkout:
248
+ type: command
249
+ exec: |
250
+ # Only checkout if PR has specific label
251
+ if [[ "{{ pr.labels }}" == *"needs-checkout"* ]]; then
252
+ echo '{"should_checkout": true}'
253
+ else
254
+ echo '{"should_checkout": false}'
255
+ fi
256
+ transform_js: JSON.parse(output)
257
+
258
+ checkout:
259
+ type: git-checkout
260
+ depends_on: [check-should-checkout]
261
+ if: "outputs['check-should-checkout'].should_checkout"
262
+ ref: "{{ pr.head }}"
263
+
264
+ test:
265
+ type: command
266
+ depends_on: [checkout]
267
+ if: "outputs.checkout?.success"
268
+ exec: npm test
269
+ working_directory: "{{ outputs.checkout.path }}"
270
+ ```
271
+
272
+ ### Example 9: Persistent Worktree for Multiple Workflows
273
+
274
+ ```yaml
275
+ version: "1.0"
276
+
277
+ steps:
278
+ checkout-persistent:
279
+ type: git-checkout
280
+ ref: main
281
+ persist_worktree: true # Keep after workflow completes
282
+ working_directory: /tmp/persistent-workspace
283
+
284
+ # This worktree will remain after the workflow completes
285
+ # and can be reused by subsequent workflows
286
+ ```
287
+
288
+ ## Error Handling
289
+
290
+ The provider handles various error scenarios:
291
+
292
+ ```yaml
293
+ steps:
294
+ checkout:
295
+ type: git-checkout
296
+ ref: "{{ pr.head }}"
297
+ guarantee: "output.success == true"
298
+
299
+ handle-failure:
300
+ type: command
301
+ depends_on: [checkout]
302
+ if: "!outputs.checkout.success"
303
+ exec: |
304
+ echo "Checkout failed: {{ outputs.checkout.error }}"
305
+ exit 1
306
+ ```
307
+
308
+ ## Worktree Management
309
+
310
+ ### How Worktrees Work
311
+
312
+ The provider uses git worktrees to efficiently manage multiple checkouts:
313
+
314
+ 1. **Bare Repository**: A bare repository is cached at `${base_path}/repos/`
315
+ 2. **Fetch Updates**: On each checkout, run `git remote update --prune` to get latest code
316
+ 3. **Worktrees**: Working directories are created at `${base_path}/worktrees/`
317
+ 4. **Shared Objects**: Git objects are shared between worktrees, saving disk space
318
+ 5. **Automatic Cleanup**: Worktrees are cleaned up when workflows complete
319
+
320
+ **Important**: The bare repository is updated on **every checkout run**, ensuring you always get the latest code, similar to GitHub Actions behavior.
321
+
322
+ ### Storage Structure
323
+
324
+ By default, worktrees are stored in `.visor/worktrees/` in your project root:
325
+
326
+ ```
327
+ .visor/worktrees/
328
+ ├── repos/
329
+ │ └── owner-repo.git/ # Bare repository (shared)
330
+ │ ├── objects/ # Git objects (shared)
331
+ │ └── worktrees/ # Worktree metadata
332
+ └── worktrees/
333
+ ├── owner-repo-main-abc123/ # Worktree 1
334
+ └── owner-repo-dev-def456/ # Worktree 2
335
+ ```
336
+
337
+ **Benefits of project-local storage:**
338
+ - Worktrees stay with the project
339
+ - Easy to locate and debug
340
+ - Can be excluded from version control (add `.visor/worktrees/` to `.gitignore`)
341
+ - Automatic cleanup when removing the project
342
+
343
+ ### Configuration
344
+
345
+ Configure worktree behavior globally in `.visor.yaml`:
346
+
347
+ ```yaml
348
+ version: "1.0"
349
+
350
+ worktree_cache:
351
+ enabled: true
352
+ base_path: .visor/worktrees # Default: .visor/worktrees/ in project root
353
+ cleanup_on_exit: true # Default: true
354
+ max_age_hours: 24 # Cleanup after 24 hours
355
+
356
+ steps:
357
+ # ... your steps
358
+ ```
359
+
360
+ **Environment Variable Override:**
361
+
362
+ You can also set the base path via environment variable:
363
+
364
+ ```bash
365
+ export VISOR_WORKTREE_PATH=/custom/path/to/worktrees
366
+ ```
367
+
368
+ This takes precedence over the config file.
369
+
370
+ ### CLI Commands for Worktree Management
371
+
372
+ ```bash
373
+ # List all worktrees
374
+ visor worktree list
375
+
376
+ # Cleanup stale worktrees
377
+ visor worktree cleanup
378
+
379
+ # Cleanup all worktrees for a repository
380
+ visor worktree cleanup --repo=owner/repo
381
+
382
+ # Cleanup all worktrees (careful!)
383
+ visor worktree cleanup --all
384
+ ```
385
+
386
+ ## Best Practices
387
+
388
+ ### 1. Use Shallow Clones for Speed (Recommended for CI/CD)
389
+
390
+ ```yaml
391
+ steps:
392
+ checkout:
393
+ type: git-checkout
394
+ ref: "{{ pr.head }}"
395
+ fetch_depth: 1 # Only fetch latest commit (much faster)
396
+ ```
397
+
398
+ **Why shallow clones?**
399
+ - **Faster initial clone**: 5-10x faster for large repositories
400
+ - **Less bandwidth**: Only downloads recent commit history
401
+ - **Sufficient for most workflows**: Tests, builds, and deployments rarely need full history
402
+
403
+ **When to use full history (fetch_depth: 0 or omit):**
404
+ - Git operations that need history (e.g., `git log`, `git blame`)
405
+ - Generating changelogs
406
+ - License compliance scanning
407
+ - Full repository analysis
408
+
409
+ **Default behavior**: If `fetch_depth` is not specified, clones full history (all commits)
410
+
411
+ ### 2. Cleanup Failed Checkouts
412
+
413
+ ```yaml
414
+ steps:
415
+ checkout:
416
+ type: git-checkout
417
+ ref: "{{ pr.head }}"
418
+ cleanup_on_failure: true # Remove on failure
419
+ ```
420
+
421
+ ### 3. Use Specific Working Directories for Predictability
422
+
423
+ ```yaml
424
+ steps:
425
+ checkout:
426
+ type: git-checkout
427
+ ref: "{{ pr.head }}"
428
+ working_directory: /tmp/my-build-{{ pr.number }}
429
+ ```
430
+
431
+ ### 4. Validate Checkout Success
432
+
433
+ ```yaml
434
+ steps:
435
+ checkout:
436
+ type: git-checkout
437
+ ref: "{{ pr.head }}"
438
+ guarantee: "output.success == true && output.commit != null"
439
+ ```
440
+
441
+ ### 5. Pass Checkout Path to Subsequent Steps
442
+
443
+ ```yaml
444
+ steps:
445
+ checkout:
446
+ type: git-checkout
447
+ ref: "{{ pr.head }}"
448
+
449
+ build:
450
+ type: command
451
+ depends_on: [checkout]
452
+ exec: npm run build
453
+ working_directory: "{{ outputs.checkout.path }}"
454
+ assume: "outputs.checkout.success"
455
+ ```
456
+
457
+ ## Troubleshooting
458
+
459
+ ### Problem: Checkout Times Out
460
+
461
+ **Solution**: Increase the timeout or use shallow clones:
462
+
463
+ ```yaml
464
+ steps:
465
+ checkout:
466
+ type: git-checkout
467
+ ref: "{{ pr.head }}"
468
+ fetch_depth: 1 # Shallow clone
469
+ timeout: 120 # 2 minutes
470
+ ```
471
+
472
+ ### Problem: Authentication Fails
473
+
474
+ **Solution**: Ensure token is set correctly:
475
+
476
+ ```yaml
477
+ steps:
478
+ checkout:
479
+ type: git-checkout
480
+ ref: "{{ pr.head }}"
481
+ token: "{{ env.GITHUB_TOKEN }}" # Explicit token
482
+ ```
483
+
484
+ ### Problem: Worktrees Not Cleaned Up
485
+
486
+ **Solution**: Enable cleanup and check configuration:
487
+
488
+ ```yaml
489
+ worktree_cache:
490
+ cleanup_on_exit: true
491
+ max_age_hours: 24
492
+
493
+ steps:
494
+ checkout:
495
+ type: git-checkout
496
+ ref: "{{ pr.head }}"
497
+ persist_worktree: false # Don't persist
498
+ ```
499
+
500
+ ### Problem: Multiple Workflows Conflict
501
+
502
+ **Solution**: Use unique working directories:
503
+
504
+ ```yaml
505
+ steps:
506
+ checkout:
507
+ type: git-checkout
508
+ ref: "{{ pr.head }}"
509
+ working_directory: /tmp/workflow-{{ inputs.workflow_id }}-checkout
510
+ ```
511
+
512
+ ### Problem: Disk Space Issues
513
+
514
+ **Solution**: Cleanup stale worktrees regularly:
515
+
516
+ ```bash
517
+ # Via CLI
518
+ visor worktree cleanup
519
+
520
+ # Or configure automatic cleanup
521
+ worktree_cache:
522
+ max_age_hours: 12 # Cleanup after 12 hours
523
+ ```
524
+
525
+ ## Comparison with GitHub Actions Checkout
526
+
527
+ | Feature | git-checkout | actions/checkout@v4 |
528
+ |---------|--------------|---------------------|
529
+ | Branch checkout | ✅ | ✅ |
530
+ | Tag checkout | ✅ | ✅ |
531
+ | Commit checkout | ✅ | ✅ |
532
+ | Shallow clone | ✅ | ✅ |
533
+ | Submodules | ✅ | ✅ |
534
+ | LFS | ✅ | ✅ |
535
+ | Sparse checkout | ✅ | ✅ |
536
+ | Dynamic variables | ✅ | ❌ |
537
+ | Worktrees | ✅ | ❌ |
538
+ | Multiple checkouts | ✅ | ✅ |
539
+ | Automatic cleanup | ✅ | ✅ |
540
+
541
+ ## Performance Considerations
542
+
543
+ ### Worktree Benefits
544
+
545
+ - **Disk savings**: Shared objects between checkouts
546
+ - **Faster checkouts**: No need to re-download objects
547
+ - **Parallel execution**: Multiple branches checked out simultaneously
548
+
549
+ ### Benchmarks
550
+
551
+ Typical performance (example repository: 100MB):
552
+
553
+ | Operation | Time |
554
+ |-----------|------|
555
+ | First checkout (bare clone) | 30s |
556
+ | Subsequent checkout (worktree) | 5s |
557
+ | Regular clone (comparison) | 30s |
558
+
559
+ ### Optimization Tips
560
+
561
+ 1. Use shallow clones for CI: `fetch_depth: 1`
562
+ 2. Limit sparse checkout to needed paths
563
+ 3. Disable tags if not needed: `fetch_tags: false`
564
+ 4. Reuse worktrees across workflows when possible
565
+
566
+ ## Security Considerations
567
+
568
+ ### Token Handling
569
+
570
+ - Tokens are never logged or exposed in output
571
+ - Use environment variables for tokens: `{{ env.GITHUB_TOKEN }}`
572
+ - Tokens are redacted from error messages
573
+
574
+ ### Path Safety
575
+
576
+ - Working directory paths are validated to prevent traversal attacks
577
+ - Worktrees are isolated to configured base path
578
+
579
+ ### Resource Limits
580
+
581
+ - Configure `max_age_hours` to prevent disk exhaustion
582
+ - Use timeouts to prevent hanging checkouts
583
+ - Monitor disk usage in `/tmp/visor-worktrees/`
584
+
585
+ ## Related Documentation
586
+
587
+ - [Command Provider](./command.md) - Execute commands in checked out code
588
+ - [Workflow Provider](./workflow.md) - Compose multi-step workflows
589
+ - [Configuration Reference](../configuration.md) - Full configuration options