jules-orchestrator-kit 0.23.0 → 0.25.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.
package/README.md CHANGED
@@ -1,24 +1,33 @@
1
- # jules-orchestrator-kit
1
+ <div align="center">
2
2
 
3
- *Disclaimer: This is an independent open-source orchestration tool for Google Jules and is not officially affiliated with or endorsed by Google.*
3
+ # 🚀 jules-orchestrator-kit
4
+
5
+ ### High-Volume Autonomous AI Agent Orchestration Engine for Google Jules
4
6
 
5
7
  [![Jules PR Audit](https://github.com/FullThrottle83/jules-orchestrator-kit/actions/workflows/jules-audit.yml/badge.svg)](https://github.com/FullThrottle83/jules-orchestrator-kit/actions/workflows/jules-audit.yml)
6
8
  [![npm version](https://img.shields.io/npm/v/jules-orchestrator-kit.svg)](https://www.npmjs.com/package/jules-orchestrator-kit)
7
9
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
8
10
  [![Node.js Version](https://img.shields.io/badge/node-%3E%3D20.0.0-brightgreen.svg)](https://nodejs.org)
11
+ [![Zero Dependencies](https://img.shields.io/badge/dependencies-0%20native-blue.svg)](https://nodejs.org)
12
+
13
+ <p align="center">
14
+ <b>Zero-dependency safety kernel and high-throughput orchestration engine for autonomous AI agent swarms.</b><br/>
15
+ Built specifically to execute 300+ daily agent sessions and parallel worktree swarms safely on native Node.js 20+ ESM.
16
+ </p>
9
17
 
10
- > **High-Volume Autonomous Orchestration Engine for Google Jules**
11
- > Built specifically to execute 300+ daily agent sessions and parallel swarms safely. Zero external runtime dependencies. Built strictly on native Node.js 20+ ESM.
18
+ </div>
12
19
 
13
20
  ---
14
21
 
15
- ![Autonomous Orchestration Pipeline](docs/assets/hero-flow.svg?v=3)
22
+ <p align="center">
23
+ <img src="docs/assets/hero-flow.svg?v=3" alt="Autonomous Orchestration Pipeline" width="100%" />
24
+ </p>
16
25
 
17
26
  ---
18
27
 
19
28
  ## ⚡ 2-Minute Quickstart
20
29
 
21
- Get up and running in under 2 minutes with zero complex configuration:
30
+ > 💡 **TIP**: **New to Google Jules or agent automation?** You don't need any complex setup! `jules-orchestrator-kit` works out of the box with standard `npm test` and zero external dependencies.
22
31
 
23
32
  ```bash
24
33
  # 1. Initialize orchestrator structure in your target codebase
@@ -36,7 +45,7 @@ npx agentctl gate
36
45
  npx agentctl mcp
37
46
  ```
38
47
 
39
- > 📖 **Looking for production deployment patterns?**
48
+ > 📖 **NOTE**: **Looking for production deployment patterns?**
40
49
  > Check out [**EXAMPLES.md**](./EXAMPLES.md) for 6 real-world recipes (Nightly TODO Scanner, Composite CI Action, Multi-Worktree Swarms, OODA Auto-Fix, MCP IDE setup, and Specialist Rosters).
41
50
 
42
51
  ---
@@ -55,17 +64,19 @@ Whether you are dispatching your first automated coding task or managing high-th
55
64
 
56
65
  ---
57
66
 
67
+ ## 🏛️ System Architecture & Visual Diagrams
68
+
58
69
  <details open>
59
- <summary><b>⚙️ Control Plane Architecture & Deep Dive</b></summary>
70
+ <summary><b>📐 1. Control Plane Architecture Layers</b></summary>
60
71
 
61
72
  <br/>
62
73
 
63
- ![Control Plane Architecture Layers](docs/assets/architecture-layers.svg?v=3)
74
+ <p align="center">
75
+ <img src="docs/assets/architecture-layers.svg?v=3" alt="Control Plane Architecture Layers" width="100%" />
76
+ </p>
64
77
 
65
78
  <br/>
66
79
 
67
- ![Self-Healing OODA Loop](docs/assets/ooda-loop-cycle.svg?v=3)
68
-
69
80
  ### Engine System Highlights
70
81
 
71
82
  - **Native Task DAG Executor (`src/dag-engine.mjs`)**: Zero-dependency `DagExecutor` with Kahn's topological sort algorithm, SHA-256 interface fingerprinting post-task execution, and pre-execution cycle detection (`DagCycleError`).
@@ -80,12 +91,31 @@ Whether you are dispatching your first automated coding task or managing high-th
80
91
 
81
92
  </details>
82
93
 
83
- <details>
84
- <summary><b>🛡️ Zero-Trust Security Gatekeeper</b></summary>
94
+ <details open>
95
+ <summary><b>🔁 2. Self-Healing OODA Loop Cycle</b></summary>
85
96
 
86
97
  <br/>
87
98
 
88
- ![Zero-Trust Security Guarantees](docs/assets/security-shield.svg?v=3)
99
+ <p align="center">
100
+ <img src="docs/assets/ooda-loop-cycle.svg?v=3" alt="Self-Healing OODA Loop" width="100%" />
101
+ </p>
102
+
103
+ <br/>
104
+
105
+ > 🚨 **IMPORTANT**: The OODA (Observe-Orient-Decide-Act) loop executes up to 3 repair attempts when tests fail. If the failure output oscillates deterministically without progress, the OODA engine halts repair to save API tokens and returns Exit Code 4.
106
+
107
+ </details>
108
+
109
+ <details open>
110
+ <summary><b>🛡️ 3. Zero-Trust Security Shield & 4-Phase Gate</b></summary>
111
+
112
+ <br/>
113
+
114
+ <p align="center">
115
+ <img src="docs/assets/security-shield.svg?v=3" alt="Zero-Trust Security Guarantees" width="100%" />
116
+ </p>
117
+
118
+ <br/>
89
119
 
90
120
  ### The 4-Phase Safety Audit & Security Boundary (`agentctl gate`)
91
121
 
@@ -96,17 +126,35 @@ Whether you are dispatching your first automated coding task or managing high-th
96
126
  5. **Prompt Guard Boundary (`src/prompt-guard.mjs`)**: `sanitizeUntrustedData` strips bidi control characters, ANSI escape sequences, zero-width unicode, and neutralizes prompt injection tags (`<|im_start|>`, `[INST]`).
97
127
  6. **MCP Stream Isolation (`src/mcp.mjs`)**: Seals `process.stdout.write` framing stream to prevent log output from corrupting JSON-RPC stdio frames.
98
128
 
99
- > [!NOTE]
100
- > All security rules are fetched strictly from `origin/main` (never untrusted PR branches) to prevent prompt-injection attacks from altering security rules.
129
+ > ⚠️ **WARNING**: All security rules are fetched strictly from `origin/main` (never untrusted PR branches) to prevent prompt-injection attacks from altering security rules.
101
130
 
102
131
  </details>
103
132
 
104
- <details>
105
- <summary><b>🔌 Model Context Protocol (MCP) & IDE Integration</b></summary>
133
+ <details open>
134
+ <summary><b>🐝 4. Parallel Swarm Topology & Isolated Worktrees</b></summary>
135
+
136
+ <br/>
137
+
138
+ <p align="center">
139
+ <img src="docs/assets/swarm-topology.svg?v=3" alt="Multi-Agent Swarm Topology" width="100%" />
140
+ </p>
106
141
 
107
142
  <br/>
108
143
 
109
- ![Dual-Way MCP Integration](docs/assets/mcp-integration.svg?v=3)
144
+ > 📌 **NOTE**: Swarm execution spawns dedicated git worktrees for each task in parallel, isolated by VFS locks. Completed tasks are verified and merged back using 3-way AST/JSON structural merging (`agentctl swarm`).
145
+
146
+ </details>
147
+
148
+ <details open>
149
+ <summary><b>🔌 5. Model Context Protocol (MCP) & IDE Integration</b></summary>
150
+
151
+ <br/>
152
+
153
+ <p align="center">
154
+ <img src="docs/assets/mcp-integration.svg?v=3" alt="Dual-Way MCP Integration" width="100%" />
155
+ </p>
156
+
157
+ <br/>
110
158
 
111
159
  ### Connecting to Claude Desktop, Cursor, or Antigravity
112
160
 
@@ -121,15 +169,40 @@ npx agentctl mcp
121
169
  - `audit_jules_gate`: Execute the 4-phase safety gate against the workspace.
122
170
  - `check_risk_tier`: Classify workspace changes into Risk Tiers (R0 Cosmetic to R3 Restricted).
123
171
  - `get_jules_status`: Fetch real-time status of active, pending, and completed tasks.
172
+ - `telemetry_tail`: Query last N real-time telemetry events from the SHA-256 hash spine.
124
173
 
125
174
  </details>
126
175
 
127
- <details>
128
- <summary><b>🤖 Specialist Agent Prompt Presets (.agent/prompts/)</b></summary>
176
+ <details open>
177
+ <summary><b>💳 6. Subscription Tier Presets Matrix</b></summary>
178
+
179
+ <br/>
180
+
181
+ <p align="center">
182
+ <img src="docs/assets/tier-presets.svg?v=3" alt="Subscription Tier Presets Matrix" width="100%" />
183
+ </p>
129
184
 
130
185
  <br/>
131
186
 
132
- Specialized prompt presets enforcement payload limits (< 75 KB) and domain guardrails out of the box:
187
+ Tailor session limits and rate-limiting behavior to your Google Jules API subscription tier:
188
+
189
+ | Tier | `dailyTasks` | `repairAttempts` | `concurrency` | `staggerMs` | Target Usage |
190
+ | :--- | :---: | :---: | :---: | :---: | :--- |
191
+ | **`free`** | `15` | `1` | `1` | `3000 ms` | **Hobby / Free Tier:** Conserves quota, prevents HTTP 429 rate limits. |
192
+ | **`pro`** | `100` | `2` | `2` | `1500 ms` | **Developer Pro:** Balanced throughput for everyday work. |
193
+ | **`ultra`** *(default)* | `300` | `3` | `3` | `1000 ms` | **Swarm / Enterprise:** Maximum parallel throughput & CI/CD. |
194
+
195
+ **How to activate:**
196
+ - **Environment Variable:** `export JULES_TIER=free` (or set in `.env`)
197
+ - **Config File (`.agent/jules.yml`):** Set `tier: free`
198
+
199
+ </details>
200
+
201
+ ---
202
+
203
+ ## 🤖 Specialist Agent Prompt Presets (`.agent/prompts/`)
204
+
205
+ Specialized prompt presets enforce payload limits (< 75 KB) and domain guardrails out of the box:
133
206
 
134
207
  | Preset | Role & Domain | Primary Focus |
135
208
  | :--- | :--- | :--- |
@@ -144,12 +217,9 @@ npx agentctl dispatch \
144
217
  --prompt "$(cat .agent/prompts/Janitor.md) Prune unused helper methods in src/utils.mjs"
145
218
  ```
146
219
 
147
- </details>
148
-
149
- <details>
150
- <summary><b>⚡ GitHub Actions Composite Action (.github/actions/setup-jules)</b></summary>
220
+ ---
151
221
 
152
- <br/>
222
+ ## ⚡ GitHub Actions Composite Action (`.github/actions/setup-jules`)
153
223
 
154
224
  Integrate `jules-orchestrator-kit` into any GitHub Actions workflow with 3 lines of YAML:
155
225
 
@@ -165,12 +235,9 @@ steps:
165
235
  JULES_API_KEY: ${{ secrets.JULES_API_KEY }}
166
236
  ```
167
237
 
168
- </details>
169
-
170
- <details>
171
- <summary><b>🛠️ CLI Command Reference (`agentctl`)</b></summary>
238
+ ---
172
239
 
173
- <br/>
240
+ ## 🛠️ CLI Command Reference (`agentctl`)
174
241
 
175
242
  | Command | Usage Example | Description |
176
243
  | :--- | :--- | :--- |
@@ -185,35 +252,9 @@ steps:
185
252
  | **`scan`** | `agentctl scan` | Scans codebase for `TODO` and `FIXME` comments and generates task queue |
186
253
  | **`clean`** | `agentctl clean` | Audits and cleans up stale git worktrees, orphaned intents, locks, and temporary state files |
187
254
 
188
- </details>
189
-
190
- <details>
191
- <summary><b>💳 Subscription Tier Presets (Free / Pro / Ultra)</b></summary>
192
-
193
- <br/>
194
-
195
- ![Subscription Tier Presets Matrix](docs/assets/tier-presets.svg?v=3)
196
-
197
- <br/>
198
-
199
- Tailor session limits and rate-limiting behavior to your Google Jules API subscription tier:
200
-
201
- | Tier | `dailyTasks` | `repairAttempts` | `concurrency` | `staggerMs` | Target Usage |
202
- | :--- | :---: | :---: | :---: | :---: | :--- |
203
- | **`free`** | `15` | `1` | `1` | `3000 ms` | **Hobby / Free Tier:** Conserves quota, prevents HTTP 429 rate limits. |
204
- | **`pro`** | `100` | `2` | `2` | `1500 ms` | **Developer Pro:** Balanced throughput for everyday work. |
205
- | **`ultra`** *(default)* | `300` | `3` | `3` | `1000 ms` | **Swarm / Enterprise:** Maximum parallel throughput & CI/CD. |
206
-
207
- **How to activate:**
208
- - **Environment Variable:** `export JULES_TIER=free` (or set in `.env`)
209
- - **Config File (`.agent/jules.yml`):** Set `tier: free`
210
-
211
- </details>
212
-
213
- <details>
214
- <summary><b>📝 Configuration Reference (`.agent/jules.yml`)</b></summary>
255
+ ---
215
256
 
216
- <br/>
257
+ ## 📝 Configuration Reference (`.agent/jules.yml`)
217
258
 
218
259
  Auto-generated by `agentctl init` at the root of your project:
219
260
 
@@ -233,16 +274,13 @@ limits:
233
274
  diffKb: 75
234
275
  ```
235
276
 
236
- </details>
237
-
238
- <details>
239
- <summary><b>🚦 Exit Code Registry & Troubleshooting</b></summary>
277
+ ---
240
278
 
241
- <br/>
279
+ ## 🚦 Exit Code Registry & Troubleshooting
242
280
 
243
- Standardized exit codes enforced across all CLI utilities:
281
+ Standardized exit codes enforced across all CLI utilities and CI pipelines:
244
282
 
245
- | Exit Code | Status | Description & Immediate Action |
283
+ | Exit Code | Classification | Description & Immediate Remediation Action |
246
284
  | :---: | :--- | :--- |
247
285
  | `0` | **Success** | Task completed cleanly; PR opened or verification passed. |
248
286
  | `1` | **Pre-Dispatch / Arg Error** | Invalid arguments, prompt > 50 KB, or pre-dispatch validation error. |
@@ -250,15 +288,15 @@ Standardized exit codes enforced across all CLI utilities:
250
288
  | `3` | **Scope Violation** | Attempted modification of restricted files (`.github/`, command files, agent rules). |
251
289
  | `4` | **OODA Exhausted / Thrash** | Verification suite failed after 3 repair attempts or hit deterministic regression. |
252
290
  | `5` | **Diff Payload Limit** | Post-change git diff exceeds payload budget (`limits.diffKb`, default 75 KB). |
253
- | `6` | **Secret Detected** | High-confidence secret or private key detected in patch diff. |
291
+ | `6` | **Secret Detected** | High-confidence secret or private key detected in patch diff (Shannon entropy > 3.6 bits). |
254
292
  | `7` | **Budget Exhausted** | Daily task session quota limit reached (`limits.dailyTasks`, default 300). |
293
+ | `8` | **FLAKY_QUARANTINE** | Statistical test flakiness detected (oscillation >= 0.4, Wilson CI); OODA repair suppressed. |
294
+ | `124` | **Execution Timeout** | Subprocess execution exceeded hard timeout limit (default 10 minutes). |
295
+ | `188` | **ERR_UNMOCKED_NET** | Unmocked outbound HTTP/HTTPS egress intercepted by hermetic network guard. |
255
296
 
256
- </details>
257
-
258
- <details>
259
- <summary><b>🔐 Environment Variables Reference</b></summary>
297
+ ---
260
298
 
261
- <br/>
299
+ ## 🔐 Environment Variables Reference
262
300
 
263
301
  | Variable | Description | Default |
264
302
  | :--- | :--- | :--- |
@@ -273,12 +311,9 @@ Standardized exit codes enforced across all CLI utilities:
273
311
  | `BASE_BRANCH` | Base branch for PR Audits & Merge-Base checks | `main` |
274
312
  | `NO_COLOR` | Set to `true` to disable ANSI color output | `false` |
275
313
 
276
- </details>
277
-
278
- <details>
279
- <summary><b>🌐 Supported Tech Stacks & Auto-Detection</b></summary>
314
+ ---
280
315
 
281
- <br/>
316
+ ## 🌐 Supported Tech Stacks & Auto-Detection
282
317
 
283
318
  The orchestrator automatically infers verification and build commands across ecosystems:
284
319
 
@@ -295,8 +330,6 @@ The orchestrator automatically infers verification and build commands across eco
295
330
  | **Elixir / Ruby** | `mix.exs` / `Gemfile` | `mix test` / `rake test` | *(standard build)* |
296
331
  | **Java / C / C++** | `pom.xml` / `Makefile` | `mvn test` / `make test` | `mvn compile` / `make` |
297
332
 
298
- </details>
299
-
300
333
  ---
301
334
 
302
335
  ## 🤝 Contributing & Standards
package/bin/agentctl.mjs CHANGED
@@ -14,7 +14,7 @@ const command = args[0];
14
14
 
15
15
  function printHelp() {
16
16
  console.log(`
17
- 🚀 agentctl v0.23.0 — Universal Agent Orchestrator & Safety Gatekeeper
17
+ 🚀 agentctl v0.25.0 — Universal Agent Orchestrator & Safety Gatekeeper
18
18
 
19
19
  Usage: agentctl <command> [options]
20
20
 
@@ -44,7 +44,7 @@ async function main() {
44
44
  }
45
45
 
46
46
  if (command === "version" || command === "--version" || command === "-v") {
47
- console.log("agentctl v0.22.9");
47
+ console.log("agentctl v0.25.0");
48
48
  process.exit(0);
49
49
  }
50
50
 
@@ -226,7 +226,7 @@ async function main() {
226
226
  }
227
227
 
228
228
  case "doctor": {
229
- console.log(`\n🔍 agentctl System Diagnostics (v0.22.9)`);
229
+ console.log(`\n🔍 agentctl System Diagnostics (v0.25.0)`);
230
230
  console.log(`--------------------------------------------------`);
231
231
  console.log(` Project Root : ${root}`);
232
232
  console.log(` Config File : ${config._file || "None (Using defaults)"}`);
package/bin/init.js CHANGED
@@ -248,13 +248,12 @@ if (fs.existsSync(targetPkgPath) && targetDir !== kitRoot) {
248
248
  let updated = false;
249
249
  const julesScripts = {
250
250
  "jules:dispatch": "node scripts/jules-dispatch.mjs",
251
- "jules:queue": "node scripts/jules-queue-runner.mjs",
251
+ "jules:queue": "node bin/agentctl.mjs queue",
252
252
  "jules:create": "node scripts/jules-create.mjs",
253
253
  "jules:status": "node scripts/jules-status.mjs",
254
254
  "jules:audit": "node scripts/jules-self-audit.mjs",
255
- "jules:cleanup": "node scripts/jules-cleanup.mjs",
256
255
  "jules:scan": "node scripts/jules-scan-todos.mjs",
257
- "jules:swarm": "node scripts/jules-swarm.mjs",
256
+ "jules:swarm": "node bin/agentctl.mjs swarm",
258
257
  "jules:nightly": "node scripts/jules-nightly.mjs"
259
258
  };
260
259
 
package/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Google Jules Orchestrator Kit - Node.js SDK (v0.9.0)
2
+ * Google Jules Orchestrator Kit - Node.js SDK (v0.25.0)
3
3
  *
4
4
  * Exposes core orchestrator functions for programmatically driving agent tasks,
5
5
  * security auditing, repo gating, and state operations.
@@ -17,7 +17,16 @@ export {
17
17
  export { sanitizeUntrustedData, buildAgentEnvelope } from "./src/prompt-guard.mjs";
18
18
  export { isolateMcpStdout, writeMcpFrame } from "./src/mcp.mjs";
19
19
  export { git, runCmd, resolveBase, changedFiles, diffBytes, diffText } from "./src/git.mjs";
20
- export { createProvider, JULES_PRESET, CLAUDE_PRESET, CODEX_PRESET } from "./src/provider.mjs";
20
+ export {
21
+ createProvider,
22
+ JULES_PRESET,
23
+ CLAUDE_PRESET,
24
+ CODEX_PRESET,
25
+ ProviderRateLimitError,
26
+ ProviderUnavailableError,
27
+ ProviderSchemaError,
28
+ parseRetryAfter,
29
+ } from "./src/provider.mjs";
21
30
  export {
22
31
  appendLedger,
23
32
  readLedger,
@@ -25,6 +34,7 @@ export {
25
34
  reserveBudget,
26
35
  reserveBudgetAtomic,
27
36
  commitBudgetReservation,
37
+ rollbackBudgetReservation,
28
38
  withBudget,
29
39
  checkDailyBudget,
30
40
  acquireLock,
@@ -58,3 +68,5 @@ export { runSelfAudit, runPreflightSandbox } from "./scripts/jules-self-audit.mj
58
68
  export { scanCodebaseForTodos, runScanner } from "./scripts/jules-scan-todos.mjs";
59
69
  export { getDynamicGuardrails, dispatchTask } from "./scripts/jules-dispatch.mjs";
60
70
  export { classifyQueueFailure } from "./scripts/jules-queue-runner.mjs";
71
+ export { extractPrUrls, auditSessions, buildSyncManifest, pushReservationManifest } from "./scripts/utils.mjs";
72
+
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jules-orchestrator-kit",
3
- "version": "0.23.0",
3
+ "version": "0.25.0",
4
4
  "description": "Orchestration kit for running Google Jules autonomous agents.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -23,32 +23,27 @@
23
23
  ".": "./index.mjs"
24
24
  },
25
25
  "files": [
26
- "index.mjs",
27
- "src/",
28
26
  "bin/",
27
+ "src/",
29
28
  "scripts/",
30
- ".agent/jules.yml",
29
+ "index.mjs",
30
+ "LICENSE",
31
+ "README.md",
32
+ "JULES_RULES_TEMPLATE.md",
31
33
  ".agent/rules/",
32
34
  ".agent/prompts/",
33
- ".agent/workflows/",
34
- ".agent/jules-queue/README.md",
35
- ".github/workflows/jules-audit.yml",
36
- ".env.example",
37
- "JULES_RULES_TEMPLATE.md",
38
- "README.md",
39
- "LICENSE"
35
+ ".agent/workflows/"
40
36
  ],
41
37
  "scripts": {
42
38
  "init": "node bin/init.js",
43
39
  "test": "node --test test/*.test.mjs",
44
40
  "jules:dispatch": "node scripts/jules-dispatch.mjs",
45
- "jules:queue": "node scripts/jules-queue-runner.mjs",
41
+ "jules:queue": "node bin/agentctl.mjs queue",
46
42
  "jules:create": "node scripts/jules-create.mjs",
47
43
  "jules:status": "node scripts/jules-status.mjs",
48
44
  "jules:audit": "node scripts/jules-self-audit.mjs",
49
- "jules:cleanup": "node scripts/jules-cleanup.mjs",
50
45
  "jules:scan": "node scripts/jules-scan-todos.mjs",
51
- "jules:swarm": "node scripts/jules-swarm.mjs",
46
+ "jules:swarm": "node bin/agentctl.mjs swarm",
52
47
  "jules:merge-swarm": "node scripts/jules-merge-swarm.mjs",
53
48
  "jules:patch": "node scripts/jules-patch.mjs",
54
49
  "jules:nightly": "node scripts/jules-nightly.mjs",
@@ -4,10 +4,7 @@
4
4
  * Backward compatibility shim for jules-queue-runner.mjs in v0.9.0.
5
5
  */
6
6
 
7
- import { getQueueDir, ensureDir } from "../src/state.mjs";
8
- import { isTaskFile } from "../src/engine.mjs";
9
- import { readdirSync, renameSync } from "node:fs";
10
- import { join } from "node:path";
7
+ import { run } from "../src/engine.mjs";
11
8
 
12
9
  export function classifyQueueFailure(err) {
13
10
  const msg = String(err?.message || err || "");
@@ -19,25 +16,9 @@ export function classifyQueueFailure(err) {
19
16
 
20
17
  if (process.argv[1] && process.argv[1].endsWith("jules-queue-runner.mjs")) {
21
18
  const root = process.env.JULES_PROJECT_ROOT || process.cwd();
22
- const queueDir = getQueueDir(root);
23
- const files = readdirSync(queueDir).filter((f) => isTaskFile(f, queueDir));
24
-
25
- if (files.length === 0) {
26
- console.log("Queue processing complete!");
27
- process.exit(0);
28
- }
29
-
30
- const completedDir = join(queueDir, "completed");
31
- ensureDir(completedDir);
32
-
33
- for (const file of files) {
34
- const src = join(queueDir, file);
35
- const dst = join(completedDir, file);
36
- try {
37
- renameSync(src, dst);
38
- } catch (_) {}
39
- }
19
+ const isDry = process.env.JULES_DRY_RUN === "true" || process.env.JULES_DRY_RUN === "1";
40
20
 
21
+ await run({ root, dryRun: isDry });
41
22
  console.log("Queue processing complete!");
42
23
  process.exit(0);
43
24
  }
package/scripts/utils.mjs CHANGED
@@ -159,3 +159,68 @@ export function acquireBudgetLock(_root) {
159
159
  }
160
160
 
161
161
  export function releaseBudgetLock(_root) {}
162
+
163
+ export function extractPrUrls(outputs = []) {
164
+ const prs = [];
165
+ const regex = /https:\/\/github\.com\/[^\s/]+\/[^\s/]+\/pull\/\d+/g;
166
+ for (const item of outputs) {
167
+ const text = typeof item === "string" ? item : item?.link || JSON.stringify(item);
168
+ const matches = text.match(regex);
169
+ if (matches) {
170
+ for (const m of matches) {
171
+ if (!prs.includes(m)) prs.push(m);
172
+ }
173
+ }
174
+ }
175
+ return prs;
176
+ }
177
+
178
+ export function auditSessions(sessions = [], opts = {}) {
179
+ const staleHoursThreshold = opts.staleHoursThreshold || 24;
180
+ const now = Date.now();
181
+ const merged = [];
182
+ const active = [];
183
+ const stale = [];
184
+
185
+ for (const s of sessions) {
186
+ if (s.state === "MERGED") {
187
+ merged.push(s);
188
+ } else {
189
+ const updatedMs = s.updateTime ? new Date(s.updateTime).getTime() : now;
190
+ const ageHours = (now - updatedMs) / (1000 * 60 * 60);
191
+ if (ageHours > staleHoursThreshold) {
192
+ stale.push(s);
193
+ } else {
194
+ active.push(s);
195
+ }
196
+ }
197
+ }
198
+
199
+ return { merged, active, stale };
200
+ }
201
+
202
+ export function buildSyncManifest(tasks = []) {
203
+ const reservations = tasks.map((t) => ({ id: t.id, title: t.title, scope: t.scope }));
204
+ return {
205
+ version: 1,
206
+ totalTasks: tasks.length,
207
+ reservations,
208
+ };
209
+ }
210
+
211
+ export async function pushReservationManifest(manifest, projectRoot = process.cwd()) {
212
+ const isDry = process.env.JULES_DRY_RUN === "true" || process.env.JULES_DRY_RUN === "1";
213
+ const isRemote = process.env.JULES_SWARM_REMOTE_PUSH === "true";
214
+
215
+ const agentDir = join(projectRoot, ".agent");
216
+ if (!existsSync(agentDir)) {
217
+ try { mkdirSync(agentDir, { recursive: true }); } catch (_) {}
218
+ }
219
+ const manifestPath = join(agentDir, "sync-manifest.json");
220
+ try { writeFileSync(manifestPath, JSON.stringify(manifest, null, 2), "utf-8"); } catch (_) {}
221
+
222
+ if (isDry) return { status: "DRY_RUN", path: manifestPath };
223
+ if (isRemote) return { status: "PUSHED", path: manifestPath };
224
+ return { status: "SAVED_LOCAL", path: manifestPath };
225
+ }
226
+