@the-open-engine/zeroshot 5.4.0

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 (295) hide show
  1. package/CHANGELOG.md +539 -0
  2. package/LICENSE +21 -0
  3. package/README.md +508 -0
  4. package/cli/commands/inspect-render.js +135 -0
  5. package/cli/commands/inspect.js +294 -0
  6. package/cli/commands/providers.js +149 -0
  7. package/cli/index.js +5431 -0
  8. package/cli/lib/first-run.js +211 -0
  9. package/cli/lib/update-checker.js +281 -0
  10. package/cli/message-formatter-utils.js +75 -0
  11. package/cli/message-formatters-normal.js +275 -0
  12. package/cli/message-formatters-watch.js +185 -0
  13. package/cluster-templates/base-templates/debug-workflow.json +422 -0
  14. package/cluster-templates/base-templates/full-workflow.json +727 -0
  15. package/cluster-templates/base-templates/heavy-validation.json +272 -0
  16. package/cluster-templates/base-templates/quick-validation.json +285 -0
  17. package/cluster-templates/base-templates/single-worker.json +71 -0
  18. package/cluster-templates/base-templates/worker-validator.json +230 -0
  19. package/cluster-templates/conductor-bootstrap.json +130 -0
  20. package/docker/zeroshot-cluster/Dockerfile +153 -0
  21. package/docker/zeroshot-cluster/pre-baked-deps.json +28 -0
  22. package/lib/agent-cli-provider/adapters/claude-parser.d.ts +3 -0
  23. package/lib/agent-cli-provider/adapters/claude-parser.d.ts.map +1 -0
  24. package/lib/agent-cli-provider/adapters/claude-parser.js +122 -0
  25. package/lib/agent-cli-provider/adapters/claude-parser.js.map +1 -0
  26. package/lib/agent-cli-provider/adapters/claude-recovery.d.ts +15 -0
  27. package/lib/agent-cli-provider/adapters/claude-recovery.d.ts.map +1 -0
  28. package/lib/agent-cli-provider/adapters/claude-recovery.js +165 -0
  29. package/lib/agent-cli-provider/adapters/claude-recovery.js.map +1 -0
  30. package/lib/agent-cli-provider/adapters/claude.d.ts +3 -0
  31. package/lib/agent-cli-provider/adapters/claude.d.ts.map +1 -0
  32. package/lib/agent-cli-provider/adapters/claude.js +181 -0
  33. package/lib/agent-cli-provider/adapters/claude.js.map +1 -0
  34. package/lib/agent-cli-provider/adapters/codex-parser.d.ts +3 -0
  35. package/lib/agent-cli-provider/adapters/codex-parser.d.ts.map +1 -0
  36. package/lib/agent-cli-provider/adapters/codex-parser.js +192 -0
  37. package/lib/agent-cli-provider/adapters/codex-parser.js.map +1 -0
  38. package/lib/agent-cli-provider/adapters/codex.d.ts +3 -0
  39. package/lib/agent-cli-provider/adapters/codex.d.ts.map +1 -0
  40. package/lib/agent-cli-provider/adapters/codex.js +151 -0
  41. package/lib/agent-cli-provider/adapters/codex.js.map +1 -0
  42. package/lib/agent-cli-provider/adapters/common.d.ts +28 -0
  43. package/lib/agent-cli-provider/adapters/common.d.ts.map +1 -0
  44. package/lib/agent-cli-provider/adapters/common.js +71 -0
  45. package/lib/agent-cli-provider/adapters/common.js.map +1 -0
  46. package/lib/agent-cli-provider/adapters/gemini.d.ts +3 -0
  47. package/lib/agent-cli-provider/adapters/gemini.d.ts.map +1 -0
  48. package/lib/agent-cli-provider/adapters/gemini.js +176 -0
  49. package/lib/agent-cli-provider/adapters/gemini.js.map +1 -0
  50. package/lib/agent-cli-provider/adapters/index.d.ts +9 -0
  51. package/lib/agent-cli-provider/adapters/index.d.ts.map +1 -0
  52. package/lib/agent-cli-provider/adapters/index.js +95 -0
  53. package/lib/agent-cli-provider/adapters/index.js.map +1 -0
  54. package/lib/agent-cli-provider/adapters/opencode.d.ts +3 -0
  55. package/lib/agent-cli-provider/adapters/opencode.d.ts.map +1 -0
  56. package/lib/agent-cli-provider/adapters/opencode.js +228 -0
  57. package/lib/agent-cli-provider/adapters/opencode.js.map +1 -0
  58. package/lib/agent-cli-provider/contract-actions.d.ts +5 -0
  59. package/lib/agent-cli-provider/contract-actions.d.ts.map +1 -0
  60. package/lib/agent-cli-provider/contract-actions.js +140 -0
  61. package/lib/agent-cli-provider/contract-actions.js.map +1 -0
  62. package/lib/agent-cli-provider/contract-env.d.ts +11 -0
  63. package/lib/agent-cli-provider/contract-env.d.ts.map +1 -0
  64. package/lib/agent-cli-provider/contract-env.js +113 -0
  65. package/lib/agent-cli-provider/contract-env.js.map +1 -0
  66. package/lib/agent-cli-provider/contract-envelope.d.ts +49 -0
  67. package/lib/agent-cli-provider/contract-envelope.d.ts.map +1 -0
  68. package/lib/agent-cli-provider/contract-envelope.js +52 -0
  69. package/lib/agent-cli-provider/contract-envelope.js.map +1 -0
  70. package/lib/agent-cli-provider/contract-errors.d.ts +22 -0
  71. package/lib/agent-cli-provider/contract-errors.d.ts.map +1 -0
  72. package/lib/agent-cli-provider/contract-errors.js +71 -0
  73. package/lib/agent-cli-provider/contract-errors.js.map +1 -0
  74. package/lib/agent-cli-provider/contract-fallback.d.ts +7 -0
  75. package/lib/agent-cli-provider/contract-fallback.d.ts.map +1 -0
  76. package/lib/agent-cli-provider/contract-fallback.js +102 -0
  77. package/lib/agent-cli-provider/contract-fallback.js.map +1 -0
  78. package/lib/agent-cli-provider/contract-invoke.d.ts +5 -0
  79. package/lib/agent-cli-provider/contract-invoke.d.ts.map +1 -0
  80. package/lib/agent-cli-provider/contract-invoke.js +89 -0
  81. package/lib/agent-cli-provider/contract-invoke.js.map +1 -0
  82. package/lib/agent-cli-provider/contract-options.d.ts +3 -0
  83. package/lib/agent-cli-provider/contract-options.d.ts.map +1 -0
  84. package/lib/agent-cli-provider/contract-options.js +140 -0
  85. package/lib/agent-cli-provider/contract-options.js.map +1 -0
  86. package/lib/agent-cli-provider/contract-parse.d.ts +15 -0
  87. package/lib/agent-cli-provider/contract-parse.d.ts.map +1 -0
  88. package/lib/agent-cli-provider/contract-parse.js +81 -0
  89. package/lib/agent-cli-provider/contract-parse.js.map +1 -0
  90. package/lib/agent-cli-provider/contract-support.d.ts +18 -0
  91. package/lib/agent-cli-provider/contract-support.d.ts.map +1 -0
  92. package/lib/agent-cli-provider/contract-support.js +154 -0
  93. package/lib/agent-cli-provider/contract-support.js.map +1 -0
  94. package/lib/agent-cli-provider/contract.d.ts +13 -0
  95. package/lib/agent-cli-provider/contract.d.ts.map +1 -0
  96. package/lib/agent-cli-provider/contract.js +30 -0
  97. package/lib/agent-cli-provider/contract.js.map +1 -0
  98. package/lib/agent-cli-provider/env-safety.d.ts +11 -0
  99. package/lib/agent-cli-provider/env-safety.d.ts.map +1 -0
  100. package/lib/agent-cli-provider/env-safety.js +83 -0
  101. package/lib/agent-cli-provider/env-safety.js.map +1 -0
  102. package/lib/agent-cli-provider/errors.d.ts +5 -0
  103. package/lib/agent-cli-provider/errors.d.ts.map +1 -0
  104. package/lib/agent-cli-provider/errors.js +115 -0
  105. package/lib/agent-cli-provider/errors.js.map +1 -0
  106. package/lib/agent-cli-provider/executable.d.ts +3 -0
  107. package/lib/agent-cli-provider/executable.d.ts.map +1 -0
  108. package/lib/agent-cli-provider/executable.js +24 -0
  109. package/lib/agent-cli-provider/executable.js.map +1 -0
  110. package/lib/agent-cli-provider/index.d.ts +8 -0
  111. package/lib/agent-cli-provider/index.d.ts.map +1 -0
  112. package/lib/agent-cli-provider/index.js +31 -0
  113. package/lib/agent-cli-provider/index.js.map +1 -0
  114. package/lib/agent-cli-provider/invoke-evidence.d.ts +4 -0
  115. package/lib/agent-cli-provider/invoke-evidence.d.ts.map +1 -0
  116. package/lib/agent-cli-provider/invoke-evidence.js +17 -0
  117. package/lib/agent-cli-provider/invoke-evidence.js.map +1 -0
  118. package/lib/agent-cli-provider/json.d.ts +16 -0
  119. package/lib/agent-cli-provider/json.d.ts.map +1 -0
  120. package/lib/agent-cli-provider/json.js +110 -0
  121. package/lib/agent-cli-provider/json.js.map +1 -0
  122. package/lib/agent-cli-provider/log-prefix.d.ts +2 -0
  123. package/lib/agent-cli-provider/log-prefix.d.ts.map +1 -0
  124. package/lib/agent-cli-provider/log-prefix.js +22 -0
  125. package/lib/agent-cli-provider/log-prefix.js.map +1 -0
  126. package/lib/agent-cli-provider/process-runner.d.ts +17 -0
  127. package/lib/agent-cli-provider/process-runner.d.ts.map +1 -0
  128. package/lib/agent-cli-provider/process-runner.js +89 -0
  129. package/lib/agent-cli-provider/process-runner.js.map +1 -0
  130. package/lib/agent-cli-provider/redaction.d.ts +9 -0
  131. package/lib/agent-cli-provider/redaction.d.ts.map +1 -0
  132. package/lib/agent-cli-provider/redaction.js +227 -0
  133. package/lib/agent-cli-provider/redaction.js.map +1 -0
  134. package/lib/agent-cli-provider/schema.d.ts +5 -0
  135. package/lib/agent-cli-provider/schema.d.ts.map +1 -0
  136. package/lib/agent-cli-provider/schema.js +136 -0
  137. package/lib/agent-cli-provider/schema.js.map +1 -0
  138. package/lib/agent-cli-provider/single-agent-runtime.d.ts +15 -0
  139. package/lib/agent-cli-provider/single-agent-runtime.d.ts.map +1 -0
  140. package/lib/agent-cli-provider/single-agent-runtime.js +228 -0
  141. package/lib/agent-cli-provider/single-agent-runtime.js.map +1 -0
  142. package/lib/agent-cli-provider/types.d.ts +194 -0
  143. package/lib/agent-cli-provider/types.d.ts.map +1 -0
  144. package/lib/agent-cli-provider/types.js +12 -0
  145. package/lib/agent-cli-provider/types.js.map +1 -0
  146. package/lib/completion.js +174 -0
  147. package/lib/detached-startup.js +220 -0
  148. package/lib/docker-config.js +220 -0
  149. package/lib/git-remote-utils.js +165 -0
  150. package/lib/id-detector.js +55 -0
  151. package/lib/provider-defaults.js +62 -0
  152. package/lib/provider-detection.js +59 -0
  153. package/lib/provider-names.js +57 -0
  154. package/lib/repo-settings.js +69 -0
  155. package/lib/settings/claude-auth.js +78 -0
  156. package/lib/settings.js +542 -0
  157. package/lib/start-cluster.js +321 -0
  158. package/lib/stream-json-parser.js +67 -0
  159. package/package.json +162 -0
  160. package/scripts/fix-node-pty-permissions.js +75 -0
  161. package/scripts/record-demo.sh +279 -0
  162. package/scripts/setup-merge-queue.sh +170 -0
  163. package/scripts/test-install.sh +40 -0
  164. package/scripts/validate-templates.js +107 -0
  165. package/src/agent/agent-config.js +266 -0
  166. package/src/agent/agent-context-builder.js +189 -0
  167. package/src/agent/agent-context-sections.js +338 -0
  168. package/src/agent/agent-context-sources.js +147 -0
  169. package/src/agent/agent-hook-executor.js +721 -0
  170. package/src/agent/agent-input-injector.js +141 -0
  171. package/src/agent/agent-lifecycle.js +982 -0
  172. package/src/agent/agent-quality-gate-schema.js +93 -0
  173. package/src/agent/agent-quality-gates-context.js +51 -0
  174. package/src/agent/agent-stuck-detector.js +256 -0
  175. package/src/agent/agent-task-executor.js +2028 -0
  176. package/src/agent/agent-trigger-evaluator.js +67 -0
  177. package/src/agent/context-metrics.js +160 -0
  178. package/src/agent/context-pack-builder.js +367 -0
  179. package/src/agent/context-replay-policy.js +51 -0
  180. package/src/agent/guidance-queue.js +77 -0
  181. package/src/agent/output-extraction.js +367 -0
  182. package/src/agent/output-reformatter.js +175 -0
  183. package/src/agent/pr-verification.js +653 -0
  184. package/src/agent/rate-limit-backoff.js +82 -0
  185. package/src/agent/schema-utils.js +146 -0
  186. package/src/agent/validation-platform.js +35 -0
  187. package/src/agent-cli-provider/adapters/claude-parser.ts +133 -0
  188. package/src/agent-cli-provider/adapters/claude-recovery.ts +203 -0
  189. package/src/agent-cli-provider/adapters/claude.ts +247 -0
  190. package/src/agent-cli-provider/adapters/codex-parser.ts +211 -0
  191. package/src/agent-cli-provider/adapters/codex.ts +217 -0
  192. package/src/agent-cli-provider/adapters/common.ts +124 -0
  193. package/src/agent-cli-provider/adapters/gemini.ts +243 -0
  194. package/src/agent-cli-provider/adapters/index.ts +126 -0
  195. package/src/agent-cli-provider/adapters/opencode.ts +286 -0
  196. package/src/agent-cli-provider/contract-actions.ts +150 -0
  197. package/src/agent-cli-provider/contract-env.ts +111 -0
  198. package/src/agent-cli-provider/contract-envelope.ts +110 -0
  199. package/src/agent-cli-provider/contract-errors.ts +66 -0
  200. package/src/agent-cli-provider/contract-fallback.ts +121 -0
  201. package/src/agent-cli-provider/contract-invoke.ts +104 -0
  202. package/src/agent-cli-provider/contract-options.ts +173 -0
  203. package/src/agent-cli-provider/contract-parse.ts +94 -0
  204. package/src/agent-cli-provider/contract-support.ts +167 -0
  205. package/src/agent-cli-provider/contract.ts +56 -0
  206. package/src/agent-cli-provider/env-safety.ts +82 -0
  207. package/src/agent-cli-provider/errors.ts +122 -0
  208. package/src/agent-cli-provider/executable.ts +24 -0
  209. package/src/agent-cli-provider/index.ts +83 -0
  210. package/src/agent-cli-provider/invoke-evidence.ts +18 -0
  211. package/src/agent-cli-provider/json.ts +114 -0
  212. package/src/agent-cli-provider/log-prefix.ts +20 -0
  213. package/src/agent-cli-provider/process-runner.ts +145 -0
  214. package/src/agent-cli-provider/redaction.ts +282 -0
  215. package/src/agent-cli-provider/schema.ts +115 -0
  216. package/src/agent-cli-provider/single-agent-runtime.ts +311 -0
  217. package/src/agent-cli-provider/types.ts +237 -0
  218. package/src/agent-wrapper.js +615 -0
  219. package/src/agents/git-pusher-template.js +705 -0
  220. package/src/attach/attach-client.js +438 -0
  221. package/src/attach/attach-server.js +543 -0
  222. package/src/attach/index.js +37 -0
  223. package/src/attach/protocol.js +220 -0
  224. package/src/attach/ring-buffer.js +121 -0
  225. package/src/attach/send-input.js +88 -0
  226. package/src/attach/socket-discovery.js +267 -0
  227. package/src/claude-task-runner.js +661 -0
  228. package/src/config-router.js +89 -0
  229. package/src/config-validator.js +2202 -0
  230. package/src/copy-worker.js +43 -0
  231. package/src/guidance-topics.js +10 -0
  232. package/src/input-helpers.js +65 -0
  233. package/src/isolation-manager.js +1734 -0
  234. package/src/issue-providers/README.md +305 -0
  235. package/src/issue-providers/azure-devops-provider.js +307 -0
  236. package/src/issue-providers/base-provider.js +232 -0
  237. package/src/issue-providers/github-provider.js +210 -0
  238. package/src/issue-providers/gitlab-provider.js +262 -0
  239. package/src/issue-providers/index.js +196 -0
  240. package/src/issue-providers/jira-provider.js +260 -0
  241. package/src/ledger.js +692 -0
  242. package/src/lib/gc.js +232 -0
  243. package/src/lib/safe-exec.js +88 -0
  244. package/src/logic-engine.js +201 -0
  245. package/src/message-buffer.js +81 -0
  246. package/src/message-bus-bridge.js +144 -0
  247. package/src/message-bus.js +256 -0
  248. package/src/name-generator.js +232 -0
  249. package/src/orchestrator.js +3924 -0
  250. package/src/preflight.js +712 -0
  251. package/src/process-metrics.js +608 -0
  252. package/src/providers/anthropic/index.js +3 -0
  253. package/src/providers/base-provider.js +355 -0
  254. package/src/providers/capabilities.js +60 -0
  255. package/src/providers/google/index.js +3 -0
  256. package/src/providers/index.js +293 -0
  257. package/src/providers/openai/index.js +3 -0
  258. package/src/providers/opencode/index.js +3 -0
  259. package/src/quality-gates.js +143 -0
  260. package/src/schemas/sub-cluster.js +208 -0
  261. package/src/state-snapshot.js +398 -0
  262. package/src/state-snapshotter.js +142 -0
  263. package/src/status-footer.js +1026 -0
  264. package/src/sub-cluster-wrapper.js +693 -0
  265. package/src/task-runner.js +30 -0
  266. package/src/template-resolver.js +425 -0
  267. package/src/template-validation/index.js +338 -0
  268. package/src/template-validation/simulate-consensus-gates.js +324 -0
  269. package/src/template-validation/simulate-random-topology.js +541 -0
  270. package/src/template-validation/simulate-two-stage-validation.js +270 -0
  271. package/src/worktree-claude-config.js +135 -0
  272. package/src/worktree-tooling-env.js +150 -0
  273. package/task-lib/attachable-watcher.js +381 -0
  274. package/task-lib/commands/clean.js +50 -0
  275. package/task-lib/commands/episodes.js +105 -0
  276. package/task-lib/commands/get-log-path.js +23 -0
  277. package/task-lib/commands/kill.js +32 -0
  278. package/task-lib/commands/list.js +105 -0
  279. package/task-lib/commands/logs.js +439 -0
  280. package/task-lib/commands/resume.js +42 -0
  281. package/task-lib/commands/run.js +57 -0
  282. package/task-lib/commands/schedule.js +105 -0
  283. package/task-lib/commands/scheduler-cmd.js +96 -0
  284. package/task-lib/commands/schedules.js +148 -0
  285. package/task-lib/commands/status.js +44 -0
  286. package/task-lib/commands/unschedule.js +16 -0
  287. package/task-lib/completion.js +9 -0
  288. package/task-lib/config.js +11 -0
  289. package/task-lib/name-generator.js +230 -0
  290. package/task-lib/package.json +3 -0
  291. package/task-lib/provider-helper-runtime.js +29 -0
  292. package/task-lib/runner.js +190 -0
  293. package/task-lib/scheduler.js +252 -0
  294. package/task-lib/store.js +529 -0
  295. package/task-lib/watcher.js +305 -0
@@ -0,0 +1,279 @@
1
+ #!/bin/bash
2
+ # record-demo.sh - Create ephemeral project, run zeroshot demo, record it, cleanup
3
+ #
4
+ # Usage:
5
+ # ./scripts/record-demo.sh # Interactive mode (you run zeroshot manually)
6
+ # ./scripts/record-demo.sh --record # Record with asciinema automatically
7
+ #
8
+ # Output: zeroshot-demo.cast (asciinema recording)
9
+ # Convert to gif: agg zeroshot-demo.cast zeroshot-demo.gif --idle-time-limit 2
10
+
11
+ set -e
12
+
13
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
14
+ REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
15
+ DEMO_DIR=""
16
+ RECORD_MODE=false
17
+ FORCE_MODE=false
18
+ LOCK_FILE="/tmp/zeroshot-demo-recording.lock"
19
+ CAST_FILE="$REPO_ROOT/zeroshot-demo.cast"
20
+
21
+ # Check for existing recording session
22
+ check_existing_session() {
23
+ # Check lock file
24
+ if [[ -f "$LOCK_FILE" ]]; then
25
+ local old_pid
26
+ old_pid=$(cat "$LOCK_FILE" 2>/dev/null || echo "")
27
+ if [[ -n "$old_pid" ]] && kill -0 "$old_pid" 2>/dev/null; then
28
+ echo "ERROR: Recording already in progress (PID $old_pid)"
29
+ echo "Kill it with: kill $old_pid"
30
+ exit 1
31
+ fi
32
+ # Stale lock file
33
+ rm -f "$LOCK_FILE"
34
+ fi
35
+
36
+ # Check for any asciinema processes recording to our file
37
+ local existing_asciinema
38
+ existing_asciinema=$(pgrep -f "asciinema.*zeroshot-demo.cast" 2>/dev/null || true)
39
+ if [[ -n "$existing_asciinema" ]]; then
40
+ echo "ERROR: Existing asciinema process(es) found: $existing_asciinema"
41
+ echo "Kill them with: pkill -f 'asciinema.*zeroshot-demo.cast'"
42
+ exit 1
43
+ fi
44
+
45
+ # Check for any running zeroshot clusters
46
+ local existing_zeroshot
47
+ existing_zeroshot=$(pgrep -f "zeroshot.*rate limiting" 2>/dev/null || true)
48
+ if [[ -n "$existing_zeroshot" ]]; then
49
+ echo "ERROR: Existing zeroshot process(es) found: $existing_zeroshot"
50
+ echo "Kill them with: pkill -f 'zeroshot.*rate limiting'"
51
+ exit 1
52
+ fi
53
+ }
54
+
55
+ # Parse args
56
+ while [[ $# -gt 0 ]]; do
57
+ case "$1" in
58
+ --record) RECORD_MODE=true; shift ;;
59
+ --force|-f) FORCE_MODE=true; shift ;;
60
+ *) echo "Unknown option: $1"; exit 1 ;;
61
+ esac
62
+ done
63
+
64
+ # Cleanup on exit
65
+ cleanup() {
66
+ # Remove lock file
67
+ rm -f "$LOCK_FILE"
68
+
69
+ if [[ -n "$DEMO_DIR" && -d "$DEMO_DIR" ]]; then
70
+ echo ""
71
+ echo "Cleaning up $DEMO_DIR..."
72
+ rm -rf "$DEMO_DIR"
73
+ echo "Done."
74
+ fi
75
+ }
76
+ trap cleanup EXIT
77
+
78
+ # Check for conflicts before doing anything
79
+ check_existing_session
80
+
81
+ # Create temp project
82
+ DEMO_DIR=$(mktemp -d -t zeroshot-demo-XXXXXX)
83
+ echo "Creating demo project in $DEMO_DIR"
84
+
85
+ cd "$DEMO_DIR"
86
+
87
+ # Initialize package.json
88
+ cat > package.json << 'EOF'
89
+ {
90
+ "name": "demo-api",
91
+ "version": "1.0.0",
92
+ "type": "commonjs",
93
+ "scripts": {
94
+ "dev": "ts-node src/index.ts",
95
+ "build": "tsc",
96
+ "start": "node dist/index.js"
97
+ }
98
+ }
99
+ EOF
100
+
101
+ # Install dependencies (quiet)
102
+ echo "Installing dependencies..."
103
+ npm install --silent express typescript ts-node @types/express @types/node
104
+
105
+ # Create tsconfig
106
+ cat > tsconfig.json << 'EOF'
107
+ {
108
+ "compilerOptions": {
109
+ "target": "ES2020",
110
+ "module": "commonjs",
111
+ "strict": true,
112
+ "esModuleInterop": true,
113
+ "outDir": "dist",
114
+ "rootDir": "src"
115
+ },
116
+ "include": ["src/**/*"]
117
+ }
118
+ EOF
119
+
120
+ # Create minimal server with users "database"
121
+ mkdir -p src
122
+
123
+ cat > src/db.ts << 'EOF'
124
+ // Simple in-memory database
125
+ export interface User {
126
+ id: number;
127
+ username: string;
128
+ email: string;
129
+ password_hash: string;
130
+ avatar: string;
131
+ created_at: Date;
132
+ }
133
+
134
+ export const users: User[] = [
135
+ {
136
+ id: 1,
137
+ username: "alice",
138
+ email: "alice@example.com",
139
+ password_hash: "$2b$10$X7VYKzPQ...",
140
+ avatar: "https://example.com/alice.jpg",
141
+ created_at: new Date("2024-01-15"),
142
+ },
143
+ {
144
+ id: 2,
145
+ username: "bob",
146
+ email: "bob@example.com",
147
+ password_hash: "$2b$10$Y8WZLaQR...",
148
+ avatar: "https://example.com/bob.jpg",
149
+ created_at: new Date("2024-02-20"),
150
+ },
151
+ ];
152
+ EOF
153
+
154
+ cat > src/index.ts << 'EOF'
155
+ import express from "express";
156
+
157
+ const app = express();
158
+ const PORT = 3000;
159
+
160
+ app.use(express.json());
161
+
162
+ // Health check
163
+ app.get("/health", (_, res) => {
164
+ res.json({ status: "ok" });
165
+ });
166
+
167
+ app.listen(PORT, () => {
168
+ console.log(`Server running on http://localhost:${PORT}`);
169
+ });
170
+ EOF
171
+
172
+ # Initialize git repo
173
+ git init --quiet
174
+ git add -A
175
+ git commit --quiet -m "Initial commit: Express API with users database"
176
+
177
+ echo ""
178
+ echo "=========================================="
179
+ echo "Demo project ready!"
180
+ echo "=========================================="
181
+ echo ""
182
+ echo "Directory: $DEMO_DIR"
183
+ echo ""
184
+ echo "Suggested demo task:"
185
+ echo " zeroshot 'Add PUT /users/:id endpoint to update user profile'"
186
+ echo ""
187
+
188
+ if [[ "$RECORD_MODE" == "true" ]]; then
189
+ echo "Recording with asciinema..."
190
+ echo ""
191
+
192
+ # Check asciinema is installed
193
+ if ! command -v asciinema &> /dev/null; then
194
+ echo "Error: asciinema not installed. Run: pip install asciinema"
195
+ exit 1
196
+ fi
197
+
198
+ # Warn if cast file exists (skip with --force)
199
+ if [[ -f "$CAST_FILE" ]] && [[ "$FORCE_MODE" != "true" ]]; then
200
+ echo "WARNING: $CAST_FILE already exists!"
201
+ echo "Previous recording will be OVERWRITTEN."
202
+ echo ""
203
+ read -p "Continue? [y/N] " -n 1 -r
204
+ echo ""
205
+ if [[ ! $REPLY =~ ^[Yy]$ ]]; then
206
+ echo "Aborted."
207
+ exit 1
208
+ fi
209
+ fi
210
+
211
+ # Create lock file with our PID
212
+ echo $$ > "$LOCK_FILE"
213
+
214
+ # Record the session
215
+ # CRITICAL: Use bash -l -c to get full PATH (includes npm global binaries)
216
+ ZEROSHOT_PATH=$(which zeroshot)
217
+ TASK="Add rate limiting middleware: sliding window algorithm (not fixed window), per-IP tracking with in-memory store and automatic TTL cleanup to prevent memory leaks, configurable limits per endpoint. Return 429 Too Many Requests with Retry-After header (seconds until reset) and X-RateLimit-Remaining header on ALL responses. Must handle both IPv4 and IPv6, normalizing IPv6 to consistent format."
218
+
219
+ # SIGNAL ISOLATION: Use setsid to create new session, completely immune to terminal signals
220
+ # The recording process will NOT be killed by Ctrl+C or signals to this script
221
+ # We wait for it explicitly and only cleanup AFTER it naturally completes
222
+ echo "Starting recording in isolated session (immune to Ctrl+C)..."
223
+ echo "To kill it manually: pkill -f 'asciinema.*zeroshot-demo.cast'"
224
+ echo ""
225
+
226
+ # Disable cleanup trap during recording - we'll handle it manually
227
+ trap - EXIT
228
+
229
+ # Start asciinema in new session (setsid) so it's immune to our signals
230
+ # Save the session leader PID so we can wait for it
231
+ setsid bash -c "
232
+ # Ignore all signals - this recording WILL NOT DIE
233
+ trap '' INT TERM HUP QUIT
234
+
235
+ cd '$DEMO_DIR'
236
+ asciinema rec \
237
+ --overwrite \
238
+ --title 'Zeroshot Demo' \
239
+ --command \"bash -l -c '$ZEROSHOT_PATH \\\"$TASK\\\"'\" \
240
+ '$CAST_FILE'
241
+ " &
242
+ RECORDING_PID=$!
243
+
244
+ # Update lock file with the actual recording PID
245
+ echo $RECORDING_PID > "$LOCK_FILE"
246
+
247
+ echo "Recording started (session PID: $RECORDING_PID)"
248
+ echo "Waiting for recording to complete..."
249
+ echo ""
250
+
251
+ # Wait for recording to finish - this script will NOT kill it on Ctrl+C
252
+ # Ignore signals while waiting
253
+ trap '' INT TERM HUP
254
+ wait $RECORDING_PID 2>/dev/null || true
255
+
256
+ # Recording finished naturally - now cleanup
257
+ echo ""
258
+ echo "Recording saved to: $CAST_FILE"
259
+ echo ""
260
+ echo "Convert to gif with:"
261
+ echo " agg $CAST_FILE $REPO_ROOT/zeroshot-demo.gif --idle-time-limit 2"
262
+
263
+ # Now do cleanup
264
+ rm -f "$LOCK_FILE"
265
+ if [[ -n "$DEMO_DIR" && -d "$DEMO_DIR" ]]; then
266
+ echo ""
267
+ echo "Cleaning up $DEMO_DIR..."
268
+ rm -rf "$DEMO_DIR"
269
+ echo "Done."
270
+ fi
271
+ else
272
+ echo "Interactive mode - run zeroshot manually:"
273
+ echo ""
274
+ echo " cd $DEMO_DIR"
275
+ echo " zeroshot 'Add PUT /users/:id endpoint to update user profile'"
276
+ echo ""
277
+ echo "Press Enter when done to cleanup..."
278
+ read -r
279
+ fi
@@ -0,0 +1,170 @@
1
+ #!/bin/bash
2
+ # Setup GitHub merge queue and branch protection for zeroshot
3
+ # Run once after creating the repo or to update settings
4
+
5
+ set -e
6
+
7
+ REPO="the-open-engine/zeroshot"
8
+
9
+ echo "╔═══════════════════════════════════════════════════════════════════╗"
10
+ echo "║ Setting up merge queue for $REPO ║"
11
+ echo "╚═══════════════════════════════════════════════════════════════════╝"
12
+ echo ""
13
+
14
+ # Check gh is authenticated
15
+ if ! gh auth status &>/dev/null; then
16
+ echo "❌ ERROR: Not authenticated with GitHub CLI"
17
+ echo " Run: gh auth login"
18
+ exit 1
19
+ fi
20
+
21
+ # Check we have admin access
22
+ if ! gh api "repos/$REPO" --jq '.permissions.admin' | grep -q true; then
23
+ echo "❌ ERROR: You need admin access to $REPO"
24
+ exit 1
25
+ fi
26
+
27
+ echo "✓ Authenticated with admin access"
28
+ echo ""
29
+
30
+ # ============================================================================
31
+ # Configure 'dev' branch protection (merge target)
32
+ # ============================================================================
33
+
34
+ echo "→ Configuring 'dev' branch protection..."
35
+
36
+ gh api --method PUT "repos/$REPO/branches/dev/protection" \
37
+ --input - <<EOF
38
+ {
39
+ "required_status_checks": {
40
+ "strict": true,
41
+ "contexts": ["check", "install-matrix (ubuntu-latest, 20)", "install-matrix (macos-latest, 20)"]
42
+ },
43
+ "enforce_admins": false,
44
+ "required_pull_request_reviews": null,
45
+ "restrictions": null,
46
+ "allow_force_pushes": false,
47
+ "allow_deletions": false,
48
+ "required_linear_history": true,
49
+ "required_conversation_resolution": false
50
+ }
51
+ EOF
52
+
53
+ echo "✓ 'dev' branch protection configured"
54
+
55
+ # Enable merge queue for dev branch
56
+ echo "→ Enabling merge queue for 'dev' branch..."
57
+
58
+ # Note: Merge queue requires GitHub Enterprise or public repos with Actions
59
+ # Using the ruleset API which supports merge queue
60
+ gh api --method POST "repos/$REPO/rulesets" \
61
+ --input - <<EOF 2>/dev/null || echo " (ruleset may already exist)"
62
+ {
63
+ "name": "dev-merge-queue",
64
+ "target": "branch",
65
+ "enforcement": "active",
66
+ "conditions": {
67
+ "ref_name": {
68
+ "include": ["refs/heads/dev"],
69
+ "exclude": []
70
+ }
71
+ },
72
+ "rules": [
73
+ {
74
+ "type": "merge_queue",
75
+ "parameters": {
76
+ "check_response_timeout_minutes": 30,
77
+ "grouping_strategy": "ALLGREEN",
78
+ "max_entries_to_build": 5,
79
+ "max_entries_to_merge": 5,
80
+ "merge_method": "SQUASH",
81
+ "min_entries_to_merge": 1,
82
+ "min_entries_to_merge_wait_minutes": 1
83
+ }
84
+ }
85
+ ]
86
+ }
87
+ EOF
88
+
89
+ echo "✓ Merge queue enabled for 'dev'"
90
+
91
+ # ============================================================================
92
+ # Configure 'main' branch protection (release branch)
93
+ # ============================================================================
94
+
95
+ echo "→ Configuring 'main' branch protection..."
96
+
97
+ gh api --method PUT "repos/$REPO/branches/main/protection" \
98
+ --input - <<EOF
99
+ {
100
+ "required_status_checks": {
101
+ "strict": true,
102
+ "contexts": ["check", "install-matrix (ubuntu-latest, 20)", "install-matrix (macos-latest, 20)"]
103
+ },
104
+ "enforce_admins": false,
105
+ "required_pull_request_reviews": {
106
+ "required_approving_review_count": 1,
107
+ "dismiss_stale_reviews": true,
108
+ "require_code_owner_reviews": false
109
+ },
110
+ "restrictions": null,
111
+ "allow_force_pushes": false,
112
+ "allow_deletions": false,
113
+ "required_linear_history": true,
114
+ "required_conversation_resolution": false
115
+ }
116
+ EOF
117
+
118
+ echo "✓ 'main' branch protection configured"
119
+
120
+ # ============================================================================
121
+ # Configure repository settings
122
+ # ============================================================================
123
+
124
+ echo "→ Configuring repository settings..."
125
+
126
+ gh api --method PATCH "repos/$REPO" \
127
+ --input - <<EOF
128
+ {
129
+ "allow_squash_merge": true,
130
+ "allow_merge_commit": false,
131
+ "allow_rebase_merge": false,
132
+ "squash_merge_commit_title": "PR_TITLE",
133
+ "squash_merge_commit_message": "PR_BODY",
134
+ "delete_branch_on_merge": true,
135
+ "allow_auto_merge": true
136
+ }
137
+ EOF
138
+
139
+ echo "✓ Repository settings configured"
140
+
141
+ # ============================================================================
142
+ # Summary
143
+ # ============================================================================
144
+
145
+ echo ""
146
+ echo "╔═══════════════════════════════════════════════════════════════════╗"
147
+ echo "║ ✓ Merge queue setup complete! ║"
148
+ echo "╚═══════════════════════════════════════════════════════════════════╝"
149
+ echo ""
150
+ echo "Workflow:"
151
+ echo " feature-branch (local)"
152
+ echo " ↓"
153
+ echo " pre-push hook → lint + typecheck (~5s)"
154
+ echo " ↓"
155
+ echo " push to origin/feature-branch"
156
+ echo " ↓"
157
+ echo " gh pr create --base dev"
158
+ echo " ↓"
159
+ echo " CI runs tests on PR branch"
160
+ echo " ↓"
161
+ echo " gh pr merge --auto --squash → enters merge queue"
162
+ echo " ↓"
163
+ echo " Queue rebases PR on latest dev + runs CI again"
164
+ echo " ↓"
165
+ echo " Merge to dev (only if CI passes on rebased code)"
166
+ echo ""
167
+ echo "Release workflow:"
168
+ echo " gh pr create --base main --head dev --title \"Release\""
169
+ echo " → CI passes → merge → semantic-release publishes"
170
+ echo ""
@@ -0,0 +1,40 @@
1
+ #!/bin/bash
2
+ # Test zeroshot installation on any platform
3
+ # Run: ./scripts/test-install.sh
4
+
5
+ set -e
6
+
7
+ echo "=== Zeroshot Install Test ==="
8
+ echo "Platform: $(uname -s) $(uname -m)"
9
+ echo "Node: $(node --version)"
10
+ echo "npm: $(npm --version)"
11
+ echo ""
12
+
13
+ echo "1. Installing dependencies..."
14
+ npm install
15
+
16
+ echo ""
17
+ echo "2. Linking CLI..."
18
+ npm link
19
+
20
+ echo ""
21
+ echo "3. Testing CLI commands..."
22
+
23
+ echo " zeroshot --version"
24
+ zeroshot --version
25
+
26
+ echo ""
27
+ echo " zeroshot --help"
28
+ zeroshot --help | head -20
29
+
30
+ echo ""
31
+ echo " zeroshot list"
32
+ zeroshot list 2>/dev/null || echo " (no clusters yet - this is expected)"
33
+
34
+ echo ""
35
+ echo " zeroshot config list"
36
+ zeroshot config list
37
+
38
+ echo ""
39
+ echo "=== ALL TESTS PASSED ==="
40
+ echo "Zeroshot installed successfully on $(uname -s)!"
@@ -0,0 +1,107 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Validate all cluster templates for config errors
4
+ * Run in CI to prevent broken templates from being merged
5
+ *
6
+ * Usage: node scripts/validate-templates.js
7
+ * Exit codes: 0 = all valid, 1 = validation errors found
8
+ */
9
+
10
+ const path = require('path');
11
+ const { validateTemplates } = require('../src/template-validation');
12
+
13
+ const TEMPLATES_DIR = path.join(__dirname, '../cluster-templates');
14
+
15
+ function parseArgs(argv) {
16
+ const simModeArg = argv.find((arg) => arg.startsWith('--sim='));
17
+ const simMode = simModeArg ? simModeArg.split('=')[1] : process.env.ZEROSHOT_TEMPLATE_SIM;
18
+ const randomScopeArg = argv.find((arg) => arg.startsWith('--random-scope='));
19
+ const randomScope = randomScopeArg
20
+ ? randomScopeArg.split('=')[1]
21
+ : process.env.ZEROSHOT_TEMPLATE_RANDOM_SCOPE || 'resolved';
22
+ const samplesArg = argv.find((arg) => arg.startsWith('--samples='));
23
+ const sampleStepsArg = argv.find((arg) => arg.startsWith('--sample-steps='));
24
+ const sampleMsArg = argv.find((arg) => arg.startsWith('--sample-ms='));
25
+
26
+ const sampleCount = Number(
27
+ samplesArg ? samplesArg.split('=')[1] : process.env.ZEROSHOT_TEMPLATE_SIM_SAMPLES
28
+ );
29
+ const sampleSteps = Number(
30
+ sampleStepsArg ? sampleStepsArg.split('=')[1] : process.env.ZEROSHOT_TEMPLATE_SIM_STEPS
31
+ );
32
+ const sampleMs = Number(
33
+ sampleMsArg ? sampleMsArg.split('=')[1] : process.env.ZEROSHOT_TEMPLATE_SIM_MS
34
+ );
35
+
36
+ const deep =
37
+ argv.includes('--deep') ||
38
+ argv.includes('--sim=deep') ||
39
+ simMode === 'deep' ||
40
+ simMode === 'all';
41
+ const randomSampling = argv.includes('--sim=random') || simMode === 'random' || simMode === 'all';
42
+
43
+ return {
44
+ deep,
45
+ randomSampling,
46
+ randomScope,
47
+ randomOptions: {
48
+ samples: Number.isFinite(sampleCount) && sampleCount > 0 ? sampleCount : undefined,
49
+ maxSteps: Number.isFinite(sampleSteps) && sampleSteps > 0 ? sampleSteps : undefined,
50
+ maxScenarioMs: Number.isFinite(sampleMs) && sampleMs > 0 ? sampleMs : undefined,
51
+ },
52
+ };
53
+ }
54
+
55
+ async function main() {
56
+ console.log('Validating cluster templates...\n');
57
+
58
+ const { deep, randomSampling, randomScope, randomOptions } = parseArgs(process.argv.slice(2));
59
+ const report = await validateTemplates({
60
+ templatesDir: TEMPLATES_DIR,
61
+ deep,
62
+ randomSampling,
63
+ randomScope,
64
+ randomOptions,
65
+ });
66
+
67
+ let hasErrors = false;
68
+
69
+ for (const { filePath, result } of report.results) {
70
+ const relativePath = path.relative(process.cwd(), filePath);
71
+
72
+ if (!result.valid) {
73
+ hasErrors = true;
74
+ console.error(`\n❌ ${relativePath}`);
75
+ for (const error of result.errors) {
76
+ console.error(` ERROR: ${error}`);
77
+ }
78
+ continue;
79
+ }
80
+
81
+ if (result.warnings.length > 0) {
82
+ console.warn(`\n⚠️ ${relativePath}`);
83
+ for (const warning of result.warnings) {
84
+ console.warn(` WARN: ${warning}`);
85
+ }
86
+ continue;
87
+ }
88
+
89
+ console.log(`✓ ${relativePath}`);
90
+ }
91
+
92
+ console.log(`\n${'='.repeat(60)}`);
93
+ console.log(`Validated: ${report.validated} templates, Skipped: ${report.skipped} files`);
94
+
95
+ if (hasErrors) {
96
+ console.error('\n❌ VALIDATION FAILED - Fix errors above before merging\n');
97
+ process.exit(1);
98
+ } else {
99
+ console.log('\n✓ All templates valid\n');
100
+ process.exit(0);
101
+ }
102
+ }
103
+
104
+ main().catch((err) => {
105
+ console.error(`\n❌ Template validation crashed: ${err.message}\n`);
106
+ process.exit(1);
107
+ });