@covibes/zeroshot 5.4.0 → 5.4.1

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 (136) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +8 -465
  3. package/cli/index.js +101 -5231
  4. package/package.json +16 -130
  5. package/CHANGELOG.md +0 -537
  6. package/cli/commands/providers.js +0 -149
  7. package/cli/lib/first-run.js +0 -211
  8. package/cli/lib/update-checker.js +0 -281
  9. package/cli/message-formatter-utils.js +0 -75
  10. package/cli/message-formatters-normal.js +0 -275
  11. package/cli/message-formatters-watch.js +0 -181
  12. package/cluster-templates/base-templates/debug-workflow.json +0 -375
  13. package/cluster-templates/base-templates/full-workflow.json +0 -581
  14. package/cluster-templates/base-templates/single-worker.json +0 -63
  15. package/cluster-templates/base-templates/worker-validator.json +0 -208
  16. package/cluster-templates/conductor-bootstrap.json +0 -124
  17. package/docker/zeroshot-cluster/Dockerfile +0 -152
  18. package/docker/zeroshot-cluster/pre-baked-deps.json +0 -28
  19. package/lib/completion.js +0 -174
  20. package/lib/docker-config.js +0 -220
  21. package/lib/git-remote-utils.js +0 -165
  22. package/lib/id-detector.js +0 -56
  23. package/lib/provider-defaults.js +0 -62
  24. package/lib/provider-detection.js +0 -59
  25. package/lib/provider-names.js +0 -57
  26. package/lib/settings/claude-auth.js +0 -78
  27. package/lib/settings.js +0 -503
  28. package/lib/stream-json-parser.js +0 -10
  29. package/scripts/fix-node-pty-permissions.js +0 -75
  30. package/scripts/record-demo.sh +0 -279
  31. package/scripts/setup-merge-queue.sh +0 -170
  32. package/scripts/test-install.sh +0 -40
  33. package/scripts/validate-templates.js +0 -100
  34. package/src/agent/agent-config.js +0 -246
  35. package/src/agent/agent-context-builder.js +0 -444
  36. package/src/agent/agent-hook-executor.js +0 -599
  37. package/src/agent/agent-lifecycle.js +0 -743
  38. package/src/agent/agent-stuck-detector.js +0 -256
  39. package/src/agent/agent-task-executor.js +0 -1690
  40. package/src/agent/agent-trigger-evaluator.js +0 -67
  41. package/src/agent/output-extraction.js +0 -217
  42. package/src/agent/output-reformatter.js +0 -175
  43. package/src/agent/schema-utils.js +0 -146
  44. package/src/agent-wrapper.js +0 -579
  45. package/src/agents/git-pusher-template.js +0 -285
  46. package/src/attach/attach-client.js +0 -438
  47. package/src/attach/attach-server.js +0 -543
  48. package/src/attach/index.js +0 -35
  49. package/src/attach/protocol.js +0 -220
  50. package/src/attach/ring-buffer.js +0 -121
  51. package/src/attach/socket-discovery.js +0 -267
  52. package/src/claude-task-runner.js +0 -574
  53. package/src/config-router.js +0 -80
  54. package/src/config-validator.js +0 -1925
  55. package/src/copy-worker.js +0 -43
  56. package/src/input-helpers.js +0 -65
  57. package/src/isolation-manager.js +0 -1471
  58. package/src/issue-providers/README.md +0 -305
  59. package/src/issue-providers/azure-devops-provider.js +0 -273
  60. package/src/issue-providers/base-provider.js +0 -232
  61. package/src/issue-providers/github-provider.js +0 -179
  62. package/src/issue-providers/gitlab-provider.js +0 -241
  63. package/src/issue-providers/index.js +0 -196
  64. package/src/issue-providers/jira-provider.js +0 -239
  65. package/src/ledger.js +0 -631
  66. package/src/lib/safe-exec.js +0 -88
  67. package/src/logic-engine.js +0 -223
  68. package/src/message-bus-bridge.js +0 -139
  69. package/src/message-bus.js +0 -249
  70. package/src/name-generator.js +0 -232
  71. package/src/orchestrator.js +0 -2815
  72. package/src/preflight.js +0 -639
  73. package/src/process-metrics.js +0 -608
  74. package/src/providers/anthropic/cli-builder.js +0 -73
  75. package/src/providers/anthropic/index.js +0 -204
  76. package/src/providers/anthropic/models.js +0 -23
  77. package/src/providers/anthropic/output-parser.js +0 -177
  78. package/src/providers/base-provider.js +0 -251
  79. package/src/providers/capabilities.js +0 -60
  80. package/src/providers/google/cli-builder.js +0 -55
  81. package/src/providers/google/index.js +0 -116
  82. package/src/providers/google/models.js +0 -24
  83. package/src/providers/google/output-parser.js +0 -101
  84. package/src/providers/index.js +0 -91
  85. package/src/providers/openai/cli-builder.js +0 -133
  86. package/src/providers/openai/index.js +0 -136
  87. package/src/providers/openai/models.js +0 -21
  88. package/src/providers/openai/output-parser.js +0 -143
  89. package/src/providers/opencode/cli-builder.js +0 -42
  90. package/src/providers/opencode/index.js +0 -103
  91. package/src/providers/opencode/models.js +0 -55
  92. package/src/providers/opencode/output-parser.js +0 -122
  93. package/src/schemas/sub-cluster.js +0 -185
  94. package/src/status-footer.js +0 -1026
  95. package/src/sub-cluster-wrapper.js +0 -601
  96. package/src/task-runner.js +0 -30
  97. package/src/template-resolver.js +0 -372
  98. package/src/tui/CHANGES.txt +0 -133
  99. package/src/tui/LAYOUT.md +0 -261
  100. package/src/tui/README.txt +0 -192
  101. package/src/tui/TWO-LEVEL-NAVIGATION.md +0 -186
  102. package/src/tui/data-poller.js +0 -349
  103. package/src/tui/demo.js +0 -208
  104. package/src/tui/formatters.js +0 -129
  105. package/src/tui/index.js +0 -193
  106. package/src/tui/keybindings.js +0 -324
  107. package/src/tui/layout.js +0 -334
  108. package/src/tui/renderer.js +0 -184
  109. package/task-lib/attachable-watcher.js +0 -309
  110. package/task-lib/claude-recovery.js +0 -156
  111. package/task-lib/commands/clean.js +0 -50
  112. package/task-lib/commands/episodes.js +0 -105
  113. package/task-lib/commands/get-log-path.js +0 -23
  114. package/task-lib/commands/kill.js +0 -32
  115. package/task-lib/commands/list.js +0 -105
  116. package/task-lib/commands/logs.js +0 -453
  117. package/task-lib/commands/resume.js +0 -42
  118. package/task-lib/commands/run.js +0 -57
  119. package/task-lib/commands/schedule.js +0 -105
  120. package/task-lib/commands/scheduler-cmd.js +0 -96
  121. package/task-lib/commands/schedules.js +0 -148
  122. package/task-lib/commands/status.js +0 -44
  123. package/task-lib/commands/unschedule.js +0 -16
  124. package/task-lib/completion.js +0 -9
  125. package/task-lib/config.js +0 -8
  126. package/task-lib/name-generator.js +0 -230
  127. package/task-lib/package.json +0 -3
  128. package/task-lib/runner.js +0 -201
  129. package/task-lib/scheduler.js +0 -252
  130. package/task-lib/store.js +0 -529
  131. package/task-lib/tui/formatters.js +0 -215
  132. package/task-lib/tui/index.js +0 -197
  133. package/task-lib/tui/layout.js +0 -111
  134. package/task-lib/tui/renderer.js +0 -129
  135. package/task-lib/tui.js +0 -425
  136. package/task-lib/watcher.js +0 -226
@@ -1,75 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * Fix node-pty spawn-helper permissions.
4
- *
5
- * node-pty prebuilds ship with spawn-helper lacking execute permission (mode 644).
6
- * This causes "posix_spawnp failed" errors on macOS/Linux.
7
- *
8
- * Upstream bug: https://github.com/microsoft/node-pty/issues/XXX
9
- * (File issue if not already reported)
10
- *
11
- * This script runs as postinstall to fix it automatically.
12
- */
13
-
14
- const fs = require('fs');
15
- const path = require('path');
16
-
17
- // Skip on Windows - chmod doesn't apply
18
- if (process.platform === 'win32') {
19
- process.exit(0);
20
- }
21
-
22
- const prebuildsDir = path.join(__dirname, '..', 'node_modules', 'node-pty', 'prebuilds');
23
-
24
- if (!fs.existsSync(prebuildsDir)) {
25
- // node-pty not installed yet or using compiled version
26
- process.exit(0);
27
- }
28
-
29
- let fixed = 0;
30
- let errors = 0;
31
-
32
- try {
33
- const platforms = fs.readdirSync(prebuildsDir).filter(f => {
34
- try {
35
- return fs.statSync(path.join(prebuildsDir, f)).isDirectory();
36
- } catch {
37
- return false;
38
- }
39
- });
40
-
41
- for (const platform of platforms) {
42
- // Only fix Unix platforms (darwin, linux)
43
- if (!platform.startsWith('darwin') && !platform.startsWith('linux')) {
44
- continue;
45
- }
46
-
47
- const helper = path.join(prebuildsDir, platform, 'spawn-helper');
48
- try {
49
- if (!fs.existsSync(helper)) continue;
50
-
51
- const stat = fs.statSync(helper);
52
- // Check if not executable (missing user execute bit)
53
- if (!(stat.mode & 0o100)) {
54
- fs.chmodSync(helper, 0o755);
55
- fixed++;
56
- }
57
- } catch (err) {
58
- // Log but don't fail install - permission fix is best-effort
59
- console.warn(`[postinstall] Warning: Could not fix ${helper}: ${err.message}`);
60
- errors++;
61
- }
62
- }
63
- } catch (err) {
64
- // Don't fail install on unexpected errors
65
- console.warn(`[postinstall] Warning: node-pty permission fix failed: ${err.message}`);
66
- process.exit(0);
67
- }
68
-
69
- if (fixed > 0) {
70
- console.log(`[postinstall] Fixed node-pty spawn-helper permissions (${fixed} platform(s))`);
71
- }
72
-
73
- if (errors > 0) {
74
- console.warn(`[postinstall] ${errors} platform(s) could not be fixed - may need manual chmod`);
75
- }
@@ -1,279 +0,0 @@
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
@@ -1,170 +0,0 @@
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="covibes/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 ""
@@ -1,40 +0,0 @@
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)!"
@@ -1,100 +0,0 @@
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 fs = require('fs');
11
- const path = require('path');
12
- const { validateConfig } = require('../src/config-validator');
13
-
14
- const TEMPLATES_DIR = path.join(__dirname, '../cluster-templates');
15
-
16
- function findJsonFiles(dir) {
17
- const files = [];
18
- if (!fs.existsSync(dir)) return files;
19
-
20
- for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
21
- const fullPath = path.join(dir, entry.name);
22
- if (entry.isDirectory()) {
23
- files.push(...findJsonFiles(fullPath));
24
- } else if (entry.name.endsWith('.json')) {
25
- files.push(fullPath);
26
- }
27
- }
28
- return files;
29
- }
30
-
31
- function validateTemplate(filePath) {
32
- const relativePath = path.relative(process.cwd(), filePath);
33
-
34
- try {
35
- const content = fs.readFileSync(filePath, 'utf-8');
36
- const config = JSON.parse(content);
37
-
38
- // Skip non-cluster configs (like package.json)
39
- if (!config.agents && !config.name) {
40
- return { valid: true, skipped: true };
41
- }
42
-
43
- const result = validateConfig(config);
44
-
45
- if (!result.valid) {
46
- console.error(`\n❌ ${relativePath}`);
47
- for (const error of result.errors) {
48
- console.error(` ERROR: ${error}`);
49
- }
50
- } else if (result.warnings.length > 0) {
51
- console.warn(`\n⚠️ ${relativePath}`);
52
- for (const warning of result.warnings) {
53
- console.warn(` WARN: ${warning}`);
54
- }
55
- } else {
56
- console.log(`✓ ${relativePath}`);
57
- }
58
-
59
- return result;
60
- } catch (err) {
61
- console.error(`\n❌ ${relativePath}`);
62
- console.error(` PARSE ERROR: ${err.message}`);
63
- return { valid: false, errors: [err.message], warnings: [] };
64
- }
65
- }
66
-
67
- function main() {
68
- console.log('Validating cluster templates...\n');
69
-
70
- const templateFiles = [...findJsonFiles(TEMPLATES_DIR)];
71
-
72
- let hasErrors = false;
73
- let validated = 0;
74
- let skipped = 0;
75
-
76
- for (const file of templateFiles) {
77
- const result = validateTemplate(file);
78
- if (result.skipped) {
79
- skipped++;
80
- } else {
81
- validated++;
82
- if (!result.valid) {
83
- hasErrors = true;
84
- }
85
- }
86
- }
87
-
88
- console.log(`\n${'='.repeat(60)}`);
89
- console.log(`Validated: ${validated} templates, Skipped: ${skipped} files`);
90
-
91
- if (hasErrors) {
92
- console.error('\n❌ VALIDATION FAILED - Fix errors above before merging\n');
93
- process.exit(1);
94
- } else {
95
- console.log('\n✓ All templates valid\n');
96
- process.exit(0);
97
- }
98
- }
99
-
100
- main();