@the-open-engine/zeroshot 6.2.0 → 6.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 (43) hide show
  1. package/README.md +141 -474
  2. package/cli/event-copy.js +12 -0
  3. package/cli/index.js +314 -96
  4. package/cli/message-formatters-normal.js +14 -2
  5. package/cli/message-formatters-watch.js +9 -2
  6. package/cluster-hooks/block-ask-user-question.py +53 -0
  7. package/cluster-hooks/block-dangerous-git.py +145 -0
  8. package/lib/clusters-registry.js +48 -0
  9. package/lib/compose-utils.js +101 -0
  10. package/lib/detached-startup.js +12 -1
  11. package/lib/id-detector.js +8 -9
  12. package/lib/path-check.js +63 -0
  13. package/lib/run-mode.js +34 -0
  14. package/lib/run-plan.js +32 -0
  15. package/lib/start-cluster.js +58 -28
  16. package/package.json +7 -6
  17. package/scripts/check-path.js +19 -0
  18. package/scripts/validate-templates.js +11 -29
  19. package/src/agent/agent-hook-executor.js +1 -1
  20. package/src/agent/agent-lifecycle.js +2 -0
  21. package/src/agent/agent-task-executor.js +4 -3
  22. package/src/agent/pr-verification.js +27 -1
  23. package/src/agents/git-pusher-template.js +121 -4
  24. package/src/attach/socket-discovery.js +2 -3
  25. package/src/claude-credentials.js +75 -0
  26. package/src/claude-task-runner.js +1 -0
  27. package/src/isolation-manager.js +12 -9
  28. package/src/issue-providers/README.md +45 -15
  29. package/src/issue-providers/index.js +2 -0
  30. package/src/issue-providers/jira-provider.js +8 -1
  31. package/src/issue-providers/linear-provider.js +405 -0
  32. package/src/ledger.js +45 -3
  33. package/src/lib/gc.js +2 -3
  34. package/src/message-bus.js +22 -2
  35. package/src/orchestrator.js +271 -144
  36. package/src/preflight.js +12 -16
  37. package/src/providers/base-provider.js +7 -6
  38. package/src/status-footer.js +13 -1
  39. package/src/template-validation/index.js +3 -0
  40. package/src/template-validation/report-formatter.js +55 -0
  41. package/src/worktree-claude-config.js +2 -13
  42. package/task-lib/runner.js +1 -0
  43. package/task-lib/watcher.js +1 -0
package/src/lib/gc.js CHANGED
@@ -9,6 +9,7 @@
9
9
  const fs = require('fs');
10
10
  const path = require('path');
11
11
  const os = require('os');
12
+ const { readClustersFileSync } = require('../../lib/clusters-registry');
12
13
 
13
14
  const DEFAULT_STORAGE_DIR = path.join(os.homedir(), '.zeroshot');
14
15
 
@@ -35,10 +36,8 @@ function resolveActiveClusterIdFromEnv() {
35
36
  */
36
37
  function readKnownClusterIds(storageDir) {
37
38
  const ids = new Set();
38
- const clustersFile = path.join(storageDir, 'clusters.json');
39
39
  try {
40
- if (!fs.existsSync(clustersFile)) return ids;
41
- const raw = JSON.parse(fs.readFileSync(clustersFile, 'utf8'));
40
+ const raw = readClustersFileSync(storageDir);
42
41
  for (const id of Object.keys(raw)) ids.add(id);
43
42
  } catch {
44
43
  // Corrupt/missing — treat as empty (safe: nothing deleted incorrectly)
@@ -24,12 +24,14 @@ class MessageBus extends EventEmitter {
24
24
  this.setMaxListeners(MAX_LISTENERS);
25
25
  this.ledger = ledger || new Ledger();
26
26
  this.wsClients = new Set();
27
+ this._closed = false;
27
28
 
28
29
  // Forward ledger events
29
- this.ledger.on('message', (message) => {
30
+ this._forwardLedgerMessage = (message) => {
30
31
  this.emit('message', message);
31
32
  this._broadcastToWebSocket(message);
32
- });
33
+ };
34
+ this.ledger.on('message', this._forwardLedgerMessage);
33
35
  }
34
36
 
35
37
  /**
@@ -180,6 +182,16 @@ class MessageBus extends EventEmitter {
180
182
  return this.ledger.getTokensByRole(cluster_id);
181
183
  }
182
184
 
185
+ /**
186
+ * Read messageCount and tokensByRole as one consistent point-in-time view
187
+ * (passthrough to ledger)
188
+ * @param {String} cluster_id - Cluster ID
189
+ * @returns {{ messageCount: number, tokensByRole: Object }}
190
+ */
191
+ readSnapshot(cluster_id) {
192
+ return this.ledger.readSnapshot(cluster_id);
193
+ }
194
+
183
195
  /**
184
196
  * Register a WebSocket client for broadcasts
185
197
  * @param {WebSocket} ws - WebSocket connection
@@ -231,6 +243,14 @@ class MessageBus extends EventEmitter {
231
243
  * Close the message bus
232
244
  */
233
245
  close() {
246
+ if (this._closed) {
247
+ return;
248
+ }
249
+ this._closed = true;
250
+
251
+ this.ledger.off('message', this._forwardLedgerMessage);
252
+ this.removeAllListeners();
253
+
234
254
  // Close all WebSocket connections
235
255
  for (const ws of this.wsClients) {
236
256
  try {