jules-orchestrator-kit 0.5.2 → 0.6.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.
- package/.agent/jules.yml +1 -1
- package/.env.example +7 -0
- package/.github/ISSUE_TEMPLATE/bug_report.md +63 -0
- package/.github/ISSUE_TEMPLATE/feature_request.md +34 -0
- package/.github/social-preview.png +0 -0
- package/.github/workflows/agent-scope-guard.yml +3 -2
- package/.github/workflows/jules-audit.yml +2 -2
- package/README.md +105 -204
- package/index.mjs +2 -2
- package/package.json +1 -1
- package/scripts/command-resolver.mjs +2 -2
- package/scripts/jules-create.mjs +22 -2
- package/scripts/jules-dispatch.mjs +36 -39
- package/scripts/jules-queue-runner.mjs +48 -3
- package/scripts/jules-scan-todos.mjs +7 -7
- package/scripts/jules-self-audit.mjs +148 -19
- package/scripts/jules-swarm.mjs +4 -1
- package/scripts/lock-manager.mjs +51 -17
- package/scripts/utils.mjs +181 -0
package/.agent/jules.yml
CHANGED
package/.env.example
CHANGED
|
@@ -20,6 +20,13 @@ JULES_REPO=owner/repo
|
|
|
20
20
|
# Enable Dry-Run mode to simulate payload dispatch without making API calls
|
|
21
21
|
# JULES_DRY_RUN=false
|
|
22
22
|
|
|
23
|
+
# --- Budget & Security Gatekeeper ---
|
|
24
|
+
# Daily max session limit for autonomous dispatches (Default: 300)
|
|
25
|
+
# JULES_DAILY_BUDGET=300
|
|
26
|
+
|
|
27
|
+
# Allow modifications to command-defining files (package.json, Cargo.toml, etc.) in PRs (Default: false)
|
|
28
|
+
# JULES_ALLOW_COMMAND_FILE_CHANGES=false
|
|
29
|
+
|
|
23
30
|
# --- Execution Scope & Git ---
|
|
24
31
|
# Base Branch for PR Audits & Merge-Base Calculations (Default: main)
|
|
25
32
|
BASE_BRANCH=main
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
name: Bug Report
|
|
2
|
+
description: Create a report to help us improve Jules Orchestrator Kit
|
|
3
|
+
title: "[BUG] "
|
|
4
|
+
labels: ["bug"]
|
|
5
|
+
assignees: []
|
|
6
|
+
body:
|
|
7
|
+
- type: markdown
|
|
8
|
+
attributes:
|
|
9
|
+
value: |
|
|
10
|
+
Thanks for taking the time to fill out this bug report!
|
|
11
|
+
- type: input
|
|
12
|
+
id: version
|
|
13
|
+
attributes:
|
|
14
|
+
label: "Node.js Version"
|
|
15
|
+
description: "What version of Node.js are you using? (e.g. v20.11.0)"
|
|
16
|
+
placeholder: "v20.x"
|
|
17
|
+
validations:
|
|
18
|
+
required: true
|
|
19
|
+
- type: dropdown
|
|
20
|
+
id: package_manager
|
|
21
|
+
attributes:
|
|
22
|
+
label: "Package Manager"
|
|
23
|
+
description: "Which package manager are you using?"
|
|
24
|
+
options:
|
|
25
|
+
- npm
|
|
26
|
+
- pnpm
|
|
27
|
+
- yarn
|
|
28
|
+
- bun
|
|
29
|
+
validations:
|
|
30
|
+
required: true
|
|
31
|
+
- type: dropdown
|
|
32
|
+
id: execution_mode
|
|
33
|
+
attributes:
|
|
34
|
+
label: "Execution Mode"
|
|
35
|
+
description: "How are you running Jules?"
|
|
36
|
+
options:
|
|
37
|
+
- API Mode (JULES_API_KEY set)
|
|
38
|
+
- CLI Mode (Local jules binary)
|
|
39
|
+
validations:
|
|
40
|
+
required: true
|
|
41
|
+
- type: textarea
|
|
42
|
+
id: description
|
|
43
|
+
attributes:
|
|
44
|
+
label: "Bug Description"
|
|
45
|
+
description: "A clear and concise description of what the bug is."
|
|
46
|
+
placeholder: "When I run npm run jules:queue..."
|
|
47
|
+
validations:
|
|
48
|
+
required: true
|
|
49
|
+
- type: textarea
|
|
50
|
+
id: reproduction
|
|
51
|
+
attributes:
|
|
52
|
+
label: "Steps to Reproduce"
|
|
53
|
+
description: "Steps to reproduce the behavior."
|
|
54
|
+
placeholder: "1. Go to...\n2. Click on...\n3. See error"
|
|
55
|
+
validations:
|
|
56
|
+
required: true
|
|
57
|
+
- type: textarea
|
|
58
|
+
id: expected
|
|
59
|
+
attributes:
|
|
60
|
+
label: "Expected Behavior"
|
|
61
|
+
description: "A clear and concise description of what you expected to happen."
|
|
62
|
+
validations:
|
|
63
|
+
required: true
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
name: Feature Request
|
|
2
|
+
description: Suggest an idea for Jules Orchestrator Kit
|
|
3
|
+
title: "[FEATURE] "
|
|
4
|
+
labels: ["enhancement"]
|
|
5
|
+
assignees: []
|
|
6
|
+
body:
|
|
7
|
+
- type: markdown
|
|
8
|
+
attributes:
|
|
9
|
+
value: |
|
|
10
|
+
Thanks for suggesting a new feature!
|
|
11
|
+
- type: textarea
|
|
12
|
+
id: description
|
|
13
|
+
attributes:
|
|
14
|
+
label: "Is your feature request related to a problem? Please describe."
|
|
15
|
+
description: "A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]"
|
|
16
|
+
placeholder: "..."
|
|
17
|
+
validations:
|
|
18
|
+
required: true
|
|
19
|
+
- type: textarea
|
|
20
|
+
id: solution
|
|
21
|
+
attributes:
|
|
22
|
+
label: "Describe the solution you'd like"
|
|
23
|
+
description: "A clear and concise description of what you want to happen."
|
|
24
|
+
placeholder: "..."
|
|
25
|
+
validations:
|
|
26
|
+
required: true
|
|
27
|
+
- type: textarea
|
|
28
|
+
id: alternatives
|
|
29
|
+
attributes:
|
|
30
|
+
label: "Describe alternatives you've considered"
|
|
31
|
+
description: "A clear and concise description of any alternative solutions or features you've considered."
|
|
32
|
+
placeholder: "..."
|
|
33
|
+
validations:
|
|
34
|
+
required: false
|
|
Binary file
|
|
@@ -23,12 +23,13 @@ jobs:
|
|
|
23
23
|
env:
|
|
24
24
|
BASE_SHA: ${{ github.event.pull_request.base.sha }}
|
|
25
25
|
HEAD_SHA: ${{ github.event.pull_request.head.sha }}
|
|
26
|
+
BASE_REF: ${{ github.base_ref }}
|
|
26
27
|
run: |
|
|
27
28
|
echo "Checking files modified in PR..."
|
|
28
29
|
MODIFIED_FILES=$(git diff --name-only $BASE_SHA $HEAD_SHA)
|
|
29
30
|
|
|
30
|
-
# Read protected paths from origin
|
|
31
|
-
PROTECTED_PATHS=$(node -e "const paths = JSON.parse(require('child_process').execSync('git show origin/
|
|
31
|
+
# Read protected paths from origin/${{ github.base_ref }}
|
|
32
|
+
PROTECTED_PATHS=$(node -e "const paths = JSON.parse(require('child_process').execSync('git show origin/' + process.env.BASE_REF + ':.agent/protected-paths.json', {encoding:'utf8'})).protected; console.log(paths.join(' '));")
|
|
32
33
|
|
|
33
34
|
echo "Protected patterns: $PROTECTED_PATHS"
|
|
34
35
|
|
|
@@ -24,13 +24,13 @@ jobs:
|
|
|
24
24
|
node-version: ${{ matrix.node-version }}
|
|
25
25
|
|
|
26
26
|
- name: Syntax Check
|
|
27
|
-
run:
|
|
27
|
+
run: for f in scripts/*.mjs bin/*.js index.mjs; do node --check "$f" || exit 1; done
|
|
28
28
|
|
|
29
29
|
- name: Run Unit Tests
|
|
30
30
|
run: npm test
|
|
31
31
|
|
|
32
32
|
- name: Run Jules PR Self-Audit Gatekeeper
|
|
33
|
-
if: github.event_name == 'pull_request' && (startsWith(github.actor, 'google-labs-jules') || contains(github.actor, 'jules'))
|
|
33
|
+
if: matrix.node-version == '20.x' && github.event_name == 'pull_request' && (startsWith(github.actor, 'google-labs-jules') || contains(github.actor, 'jules'))
|
|
34
34
|
run: node scripts/jules-self-audit.mjs
|
|
35
35
|
env:
|
|
36
36
|
CI: "true"
|
package/README.md
CHANGED
|
@@ -1,169 +1,53 @@
|
|
|
1
|
-
#
|
|
1
|
+
# jules-orchestrator-kit
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
*Disclaimer: This is an independent open-source orchestration tool and is not officially affiliated with or endorsed by Google.*
|
|
4
|
+
|
|
5
|
+
[](https://github.com/FullThrottle83/jules-orchestrator-kit/actions/workflows/jules-audit.yml)
|
|
4
6
|
[](https://www.npmjs.com/package/jules-orchestrator-kit)
|
|
5
7
|
[](https://opensource.org/licenses/MIT)
|
|
6
|
-
[](https://nodejs.org)
|
|
7
|
-
[](#)
|
|
8
8
|
|
|
9
9
|
**Turn Google Jules into an autonomous code builder that writes, tests, and fixes itself.**
|
|
10
|
+
The orchestrator automates verification, scopes file boundaries, and prevents Jules from breaking your CI.
|
|
10
11
|
|
|
11
12
|
> [!WARNING]
|
|
12
13
|
> **Alpha Release:** This kit is in active development. Please exercise caution before integrating it into critical production pipelines.
|
|
13
|
-
>
|
|
14
|
-
> **Task Limit Warning:** Autonomous loops (like OODA self-healing or large swarms) can quickly consume your daily Google Jules task limits (e.g., 100 tasks/day on Pro, 300 tasks/day on Ultra). We strongly recommend starting with `JULES_DRY_RUN=1` to understand the workflow before scaling up!
|
|
15
|
-
|
|
16
|
-
> **💡 TL;DR**: Run `npx jules-orchestrator-kit` in your repo, assign tasks, and get working, tested Pull Requests—no manual review needed.
|
|
17
14
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
## 🎯 Is This For You?
|
|
15
|
+
> [!CAUTION]
|
|
16
|
+
> **Task Limit Warning:** Autonomous loops can quickly consume your daily API limits. We strongly recommend starting with `JULES_DRY_RUN=1` to understand the workflow before scaling up.
|
|
21
17
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
| **Open Source Maintainer** | Limited time to review AI contributions | Self-correcting PRs that pass your CI |
|
|
28
|
-
| **Power User** | Need deterministic, production-grade orchestration | Git Worktrees, entropy-based secret redaction, MCP directives, OODA loops |
|
|
18
|
+
## Prerequisites
|
|
19
|
+
To use this kit, you will need:
|
|
20
|
+
- Node.js `18.0.0` or higher
|
|
21
|
+
- `git` installed and available in your PATH
|
|
22
|
+
- A Google Jules REST API key (set as `JULES_API_KEY`) **OR** the native `jules` binary in your PATH.
|
|
29
23
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
## 🚀 Get Started in 2 Minutes
|
|
33
|
-
|
|
34
|
-
### 1. Initialize (Auto-detects your tech stack)
|
|
24
|
+
## Quick Start
|
|
35
25
|
Navigate to your project root and run:
|
|
36
26
|
```bash
|
|
37
27
|
npx jules-orchestrator-kit
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
### 2. Scaffold a Task
|
|
41
|
-
Generate a clean boilerplate markdown file so you don't have to start from scratch:
|
|
42
|
-
```bash
|
|
43
28
|
npm run jules:create "Refactor Auth"
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
### 3. Queue and Track
|
|
47
|
-
Edit the generated markdown file in `.agent/jules-queue/` and dispatch it:
|
|
48
|
-
```bash
|
|
49
29
|
npm run jules:queue
|
|
50
30
|
```
|
|
51
31
|
|
|
52
|
-
You can view the real-time status of your dispatched tasks using:
|
|
53
|
-
```bash
|
|
54
|
-
npm run jules:status
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
**What just happened?**
|
|
58
|
-
- Jules wrote code to fulfill your task.
|
|
59
|
-
- The orchestrator ran your tests automatically.
|
|
60
|
-
- If tests failed, Jules fixed the code and re-ran tests.
|
|
61
|
-
- You'll receive a Pull Request with working, verified code.
|
|
62
|
-
|
|
63
|
-
> 🔐 **New in v0.5.0 (The Epistemic Bridge)**: The init script generates a cryptographic Handshake Token (`.agent/JULES_WEB_SETUP.md`). Paste this into the Jules Web UI to sync your environment perfectly.
|
|
64
|
-
|
|
65
32
|
---
|
|
66
33
|
|
|
67
|
-
##
|
|
34
|
+
## How It Works
|
|
68
35
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
B --> C["Run Tests & Linters"]
|
|
75
|
-
C --> D{"Tests Pass?"}
|
|
76
|
-
D -->|Yes| E["Create PR for Review"]
|
|
77
|
-
D -->|No| F["Jules Fixes Code"]
|
|
78
|
-
F --> C
|
|
79
|
-
```
|
|
80
|
-
|
|
81
|
-
1. **You define the task** - "Fix the memory leak in the cache module"
|
|
82
|
-
2. **Jules proposes changes** - In an isolated Git worktree sandbox
|
|
83
|
-
3. **Automatic verification** - Runs your test suite, linters, and type checks
|
|
84
|
-
4. **Self-correction** - If anything fails, Jules automatically retries with fixes
|
|
85
|
-
5. **Safe delivery** - Only working, tested code reaches your main branch
|
|
86
|
-
|
|
87
|
-
## 🏗️ Architecture & Pipeline Flow
|
|
88
|
-
|
|
89
|
-
```mermaid
|
|
90
|
-
graph TD
|
|
91
|
-
classDef start fill:#1f2937,stroke:#4b5563,color:#f9fafb;
|
|
92
|
-
classDef core fill:#111827,stroke:#374151,color:#f9fafb;
|
|
93
|
-
classDef gate fill:#1e1b4b,stroke:#4338ca,color:#e0e7ff;
|
|
94
|
-
classDef success fill:#064e3b,stroke:#059669,color:#ecfdf5;
|
|
95
|
-
classDef error fill:#4c0519,stroke:#e11d48,color:#fff1f2;
|
|
96
|
-
|
|
97
|
-
A["1. Client Trigger<br/><i>(CLI / CI / SDK / REST API)</i>"]:::start --> B["2. Orchestrator Core<br/><i>(Redaction & Guardrails)</i>"]:::core
|
|
98
|
-
B --> C["3. Google Jules Agent<br/><i>(Code Gen in Sandbox)</i>"]:::core
|
|
99
|
-
C --> D{"4. Gatekeeper<br/><i>(Scope & Tests)</i>"}:::gate
|
|
100
|
-
|
|
101
|
-
D -->|Scope Breach| E["❌ Exit 3<br/>Security Violation"]:::error
|
|
102
|
-
D -->|100% Passed| F["✅ Exit 0<br/>Success & Log"]:::success
|
|
103
|
-
D -->|Test Failure| G{"5. OODA Repair<br/><i>(Retries < 3?)</i>"}:::gate
|
|
104
|
-
|
|
105
|
-
G -->|Retry| C
|
|
106
|
-
G -->|Circuit Tripped| H["❌ Exit 4<br/>Diagnostic Abort"]:::error
|
|
107
|
-
```
|
|
36
|
+
1. **You Assign Task:** Define what needs fixing or building.
|
|
37
|
+
2. **Jules Writes Code:** Proposes changes in an isolated Git worktree sandbox.
|
|
38
|
+
3. **Run Tests & Linters:** The Gatekeeper runs your test suite, linters, and type checks.
|
|
39
|
+
4. **Self-Correction:** If anything fails, Jules automatically retries with fixes (OODA loop).
|
|
40
|
+
5. **Safe Delivery:** Once tests pass, the PR is verified and ready for review.
|
|
108
41
|
|
|
109
42
|
> 💡 **Core Architectural Invariants**:
|
|
110
43
|
> - **Zero-Trust Base-Branch Security**: Security rules (`forbidden_paths`) are fetched exclusively from `origin/main` (never untrusted PR branches).
|
|
111
44
|
> - **Dynamic Command Resolution (`command-resolver.mjs`)**: Auto-detects workspace boundaries (Turborepo, pnpm, Nx, Cargo, pytest, npm).
|
|
112
|
-
>
|
|
113
|
-
|
|
114
|
-
<details>
|
|
115
|
-
<summary><b>🔍 View Detailed Sequence Diagram (Step-by-Step Execution Protocol)</b></summary>
|
|
116
|
-
|
|
117
|
-
```mermaid
|
|
118
|
-
sequenceDiagram
|
|
119
|
-
autonumber
|
|
120
|
-
actor Trigger as Client (CLI / CI / SDK)
|
|
121
|
-
participant Orc as Orchestrator Core
|
|
122
|
-
participant API as Google Jules API
|
|
123
|
-
participant Git as Git / Worktree Sandbox
|
|
124
|
-
participant Gate as Self-Audit Gatekeeper
|
|
125
|
-
|
|
126
|
-
Trigger->>Orc: Dispatch Task Payload
|
|
127
|
-
|
|
128
|
-
note over Orc,Git: Phase 1: Security Redaction & Context Enrichment
|
|
129
|
-
Orc->>Orc: Redact Secrets (Entropy > 3.6) & Enforce Dynamic Guardrails
|
|
130
|
-
Orc->>Git: Provision Isolation Sandbox (Worktree / Repoless)
|
|
131
|
-
Orc->>API: Dispatch Task + <MCP_DIRECTIVE> & Target Scope
|
|
132
|
-
|
|
133
|
-
API->>Git: Apply Proposed Code Changes
|
|
134
|
-
|
|
135
|
-
note over Orc,Gate: Phase 2: Tiered Verification & OODA Gatekeeper
|
|
136
|
-
Orc->>Gate: Trigger Self-Audit (fetch trusted origin/main rules)
|
|
137
|
-
Gate->>Git: Scope Audit (`git diff -z --name-only` vs forbidden_paths)
|
|
138
|
-
|
|
139
|
-
alt Scope Breach (Forbidden Path Modified)
|
|
140
|
-
Gate-->>Orc: Security Violation Detected
|
|
141
|
-
Orc-->>Trigger: Abort Execution (Exit 3)
|
|
142
|
-
else Scope Verification Passed
|
|
143
|
-
Gate->>Git: Resolve & Run Dynamic Verification Suite (`test_cmd` & `build_cmd`)
|
|
144
|
-
end
|
|
145
|
-
|
|
146
|
-
alt 100% Verification Suite Passed
|
|
147
|
-
Gate->>Orc: Verification Success
|
|
148
|
-
Orc->>Git: Record Telemetry (`metrics.jsonl`)
|
|
149
|
-
Orc-->>Trigger: Dispatch Succeeded (Exit 0)
|
|
150
|
-
else Verification Failed (OODA Feedback Triggered)
|
|
151
|
-
Gate->>Gate: Fingerprint Trace (SHA-256 Error Hash & Check Circuit Breaker)
|
|
152
|
-
alt Auto-Repair Eligible (Retries < 3 & Circuit OK)
|
|
153
|
-
Gate->>API: Auto-Dispatch Repair Prompt with Stderr Trace
|
|
154
|
-
else Circuit Tripped / Max Retries Exceeded
|
|
155
|
-
Gate-->>Orc: Verification Exhausted
|
|
156
|
-
Orc-->>Trigger: Abort & Log Diagnostic Feedback (Exit 4)
|
|
157
|
-
end
|
|
158
|
-
end
|
|
159
|
-
```
|
|
160
|
-
</details>
|
|
45
|
+
>
|
|
46
|
+
> 🔍 For a deep dive into the execution protocol, see the [Architecture & Pipeline Flow](docs/architecture.md).
|
|
161
47
|
|
|
162
48
|
---
|
|
163
49
|
|
|
164
|
-
##
|
|
165
|
-
|
|
166
|
-
### Custom Configuration (`.agent/jules.yml`)
|
|
50
|
+
## Configuration
|
|
167
51
|
|
|
168
52
|
The orchestrator automatically detects your tech stack, but you can edit `.agent/jules.yml` for fine-grained control:
|
|
169
53
|
|
|
@@ -182,58 +66,22 @@ forbidden_paths:
|
|
|
182
66
|
allow_paths: []
|
|
183
67
|
```
|
|
184
68
|
|
|
185
|
-
> 🛡️ **Zero-Trust Security Model**: Configuration is always read from your target base branch (`origin/main`), never from untrusted PR branches.
|
|
186
|
-
|
|
187
69
|
---
|
|
188
70
|
|
|
189
|
-
##
|
|
190
|
-
|
|
191
|
-
### 🛡️ Core Safety (For Everyone)
|
|
192
|
-
|
|
193
|
-
| Feature | What It Does | Example |
|
|
194
|
-
| --------------------- | -------------------------------------------- | ------------------------------------- |
|
|
195
|
-
| **Automatic Testing** | Runs test suite against every AI change | `test_cmd: "npm test"` |
|
|
196
|
-
| **Self-Fixing** | Jules automatically corrects failed tests | Retries up to 3 times before blocking |
|
|
197
|
-
| **Secret Protection** | Hides API keys, passwords, tokens | Entropy > 3.6, length ≥ 20 |
|
|
198
|
-
| **Path Restrictions** | Blocks changes to sensitive files | `.env`, `*.pem`, `.github/**` |
|
|
199
|
-
| **Scope Boundaries** | Prevents changes outside task scope | `scope: ["src/auth/**"]` |
|
|
200
|
-
| **Agent Scope Guard** | CI-enforced protected paths manifestation | `.agent/protected-paths.json` |
|
|
201
|
-
| **Payload Governor** | Hard cap to prevent > 80 KB payload failures | Diffs capped at 75 KB |
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
| Feature | Use Case | Command |
|
|
205
|
-
| ----------------------- | ----------------------------------------- | ------------------------------------------ |
|
|
206
|
-
| **Git Worktree Swarms** | Parallel tasks with slot isolation | `node scripts/jules-swarm.mjs tasks.json` |
|
|
207
|
-
| **Suggested Scanner** | Scan TODO/FIXME comments into task queues | `npm run jules:scan` |
|
|
208
|
-
| **Session Cleanup** | Audit & close merged/stale REST sessions | `npm run jules:cleanup -- --close-merged` |
|
|
209
|
-
| **Repoless Sessions** | Serverless ad-hoc analysis without repos | `npm run jules:dispatch -- --repoless ...` |
|
|
210
|
-
| **Monorepo Support** | Auto-detects Turbo, Nx, pnpm, Cargo | Runs affected package tests only |
|
|
211
|
-
| **Queue Pacing** | Rate-limit queue launches (`--pace-ms`) | `npm run jules:queue -- --pace-ms 500` |
|
|
212
|
-
| **Pre-Flight Sandbox** | Test setup locally before cloud execution | `node scripts/jules-self-audit.mjs --preflight` |
|
|
213
|
-
| **Security Fencing** | Prompt injection defense & secret masking | Automatic `<UNTRUSTED_TASK_CONTEXT>` encapsulation |
|
|
214
|
-
| **OODA Feedback** | Self-healing from test failures | Logs to `.agent/history/metrics.jsonl` |
|
|
215
|
-
| **Mutex Lock Protocol** | Prevent concurrent file collisions | `node scripts/lock-manager.mjs acquire` |
|
|
216
|
-
| **Baton Pass Protocol** | Stateful handovers to human/other AI | `.agent/history/*-handover-*.md` |
|
|
217
|
-
|
|
218
|
-
---
|
|
219
|
-
|
|
220
|
-
## 🔌 Expand with MCP (Model Context Protocol)
|
|
221
|
-
|
|
222
|
-
All task dispatches dynamically inject `<MCP_DIRECTIVE>` envelopes into task prompts. This forces Jules to adhere to strict read-before-write invariants and deterministic execution when operating alongside **MCP server tools**.
|
|
223
|
-
|
|
224
|
-
**Pro-tip:** You can supercharge Jules with external MCP servers! By connecting standard MCP servers to your environment, you give Jules direct access to your infrastructure and real-time documentation. Some powerful examples include:
|
|
71
|
+
## Expand with MCP
|
|
225
72
|
|
|
226
|
-
|
|
227
|
-
* **Databases & Cloud:** Render, Neon, Supabase, Stitch, and Tinybird.
|
|
228
|
-
* **Framework Documentation:** Astro Docs, Cloudflare Docs, Next.js Docs, etc.
|
|
73
|
+
All task dispatches dynamically inject `<MCP_DIRECTIVE>` envelopes into task prompts. This forces Jules to adhere to strict read-before-write invariants.
|
|
229
74
|
|
|
230
|
-
|
|
75
|
+
You can supercharge Jules with external MCP servers by connecting them to your environment, granting Jules direct access to your infrastructure and real-time documentation. Examples:
|
|
76
|
+
* **SaaS APIs & Tooling:** Context 7, Linear, and v0.
|
|
77
|
+
* **Databases & Cloud:** Render, Neon, Supabase, Stitch.
|
|
78
|
+
* **Framework Documentation:** Astro Docs, Cloudflare Docs, Next.js Docs.
|
|
231
79
|
|
|
232
80
|
---
|
|
233
81
|
|
|
234
|
-
##
|
|
82
|
+
## Integration Interfaces
|
|
235
83
|
|
|
236
|
-
The orchestrator supports
|
|
84
|
+
The orchestrator supports three primary integration channels:
|
|
237
85
|
|
|
238
86
|
**1. Direct REST API Mode (`jules.googleapis.com`)**
|
|
239
87
|
When `JULES_API_KEY` and `JULES_REPO` are present in your environment, payloads are dispatched directly to the official Google Jules REST API endpoint. Handles HTTP 429 rate limits gracefully.
|
|
@@ -255,21 +103,16 @@ const tasks = scanCodebaseForTodos(process.cwd());
|
|
|
255
103
|
|
|
256
104
|
---
|
|
257
105
|
|
|
258
|
-
##
|
|
106
|
+
## Known Limitations
|
|
259
107
|
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
### Code Suggestions (Web UI Only)
|
|
108
|
+
**Code Suggestions (Web UI Only)**
|
|
263
109
|
Currently, there is no way to automatically extract "Suggestions" (the inline code review comments Jules sometimes proposes instead of direct commits) via the CLI or API. Suggestions can only be read directly inside the **Jules Web UI**.
|
|
264
110
|
|
|
265
|
-
*
|
|
111
|
+
*Workaround for Local LLM Users:* If you are tinkering with Jules alongside a local LLM and Jules leaves a Suggestion, the easiest workflow is to open the Jules Web UI, copy the suggestion block, and paste it back into your local LLM.
|
|
266
112
|
|
|
267
113
|
---
|
|
268
114
|
|
|
269
|
-
##
|
|
270
|
-
|
|
271
|
-
<details>
|
|
272
|
-
<summary><b>🛠️ View Supported Language Manifests & Workspace Graphs</b></summary>
|
|
115
|
+
## Supported Tech Stacks
|
|
273
116
|
|
|
274
117
|
| Stack / Ecosystem | Manifest / Workspace File | Test Command | Build Command |
|
|
275
118
|
| --------------------------- | ------------------------------------- | ---------------------------------------- | ---------------------------------------- |
|
|
@@ -288,23 +131,81 @@ Currently, there is no way to automatically extract "Suggestions" (the inline co
|
|
|
288
131
|
| **Java (Maven/Gradle)** | `pom.xml` / `build.gradle` | `mvn test` / `./gradlew test` | `mvn compile` / `./gradlew assemble` |
|
|
289
132
|
| **C / C++** | `Makefile` | `make test` | `make build` |
|
|
290
133
|
|
|
291
|
-
</details>
|
|
292
|
-
|
|
293
134
|
---
|
|
294
135
|
|
|
295
|
-
##
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
136
|
+
## Reference Material
|
|
137
|
+
|
|
138
|
+
### CLI Commands
|
|
139
|
+
All commands are registered in `package.json` and can be run via `npm run <command>`.
|
|
140
|
+
|
|
141
|
+
| Command | Description |
|
|
142
|
+
| ------- | ----------- |
|
|
143
|
+
| `npm run init` | Initializes the orchestrator and `.agent/` directory |
|
|
144
|
+
| `npm run test` | Runs the orchestrator kit's own unit tests |
|
|
145
|
+
| `npm run jules:dispatch` | Dispatches a single task directly to Jules |
|
|
146
|
+
| `npm run jules:queue` | Runs the local queue processor (picks up tasks from `.agent/jules-queue`) |
|
|
147
|
+
| `npm run jules:create` | Scaffolds a new boilerplate task markdown file |
|
|
148
|
+
| `npm run jules:status` | Shows the real-time status of all queued and completed tasks |
|
|
149
|
+
| `npm run jules:audit` | Runs the self-audit gatekeeper (verifies tests, forbidden paths, and scope) |
|
|
150
|
+
| `npm run jules:cleanup` | Audits and closes merged or stale REST sessions |
|
|
151
|
+
| `npm run jules:scan` | Scans the codebase for TODO/FIXME comments and generates a suggested tasks file |
|
|
152
|
+
| `npm run jules:swarm` | Launches a multi-agent swarm in parallel across isolated worktrees |
|
|
153
|
+
| `npm run jules:nightly` | Nightly maintenance job (usually triggered in CI) |
|
|
154
|
+
|
|
155
|
+
### Environment Variables
|
|
156
|
+
|
|
157
|
+
| Variable | Description |
|
|
158
|
+
| -------- | ----------- |
|
|
159
|
+
| `JULES_API_KEY` | Your Google Jules REST API key (required for API mode) |
|
|
160
|
+
| `GEMINI_API_KEY` | Alias for `JULES_API_KEY` (fallback) |
|
|
161
|
+
| `JULES_API_URL` | Override the Jules REST API URL |
|
|
162
|
+
| `JULES_REPO` | Target GitHub Repository (Format: `owner/repo`) |
|
|
163
|
+
| `JULES_REPOLESS` | Set to `true` or `1` to run in repoless/serverless mode |
|
|
164
|
+
| `JULES_DRY_RUN` | Set to `true` or `1` to simulate dispatching without making API calls |
|
|
165
|
+
| `JULES_DAILY_BUDGET` | Daily max session budget for autonomous dispatches (Default: `300`) |
|
|
166
|
+
| `JULES_ALLOW_COMMAND_FILE_CHANGES` | Set to `true` to allow PR changes to command-defining files like `package.json` (Default: `false`) |
|
|
167
|
+
| `BASE_BRANCH` | Base branch for PR Audits & Merge-Base calculations (Default: `main`) |
|
|
168
|
+
| `GITHUB_HEAD_REF` | PR Head Branch (Used dynamically by CI during OODA repair) |
|
|
169
|
+
| `JULES_PROJECT_ROOT` | Root directory of the project (Auto-assigned during swarm executions) |
|
|
170
|
+
| `JULES_SWARM_CONCURRENCY` | Maximum parallel dispatches for swarm runs (Default: `3`) |
|
|
171
|
+
| `JULES_SWARM_STAGGER_MS` | Dispatch stagger interval in milliseconds (Default: `1500`) |
|
|
172
|
+
| `JULES_PACE_MS` | Rate-limit for the `jules:queue` command (Default: `500`) |
|
|
173
|
+
| `JULES_USE_WORKTREES` | Use Git Worktrees instead of cloning for swarm isolation (Default: `false`) |
|
|
174
|
+
| `JULES_SLOT_INDEX` | Current slot index for partitioning tasks (Swarm mode) |
|
|
175
|
+
| `JULES_SLOT_TOTAL` | Total number of slots for partitioning tasks (Swarm mode) |
|
|
176
|
+
| `CI` | Set to `true` to change log output and fail-fast behaviors for CI environments |
|
|
177
|
+
| `ALLOW_AUTO_REPAIR` | Set to `true` to allow OODA Auto-Repair even when running in CI |
|
|
178
|
+
| `GITHUB_STEP_SUMMARY` | GitHub Actions Step Summary File Path |
|
|
179
|
+
| `NO_COLOR` | Set to `true` to disable ANSI color output |
|
|
180
|
+
|
|
181
|
+
> [!NOTE]
|
|
182
|
+
> **Scope Enforcement via `allow_paths`**
|
|
183
|
+
> In `.agent/jules.yml`, defining `allow_paths` acts as a strict allowlist (deny-by-default). When non-empty, any file modified outside `allow_paths` will trigger a security violation (Exit Code 3). `forbidden_paths` always take absolute precedence and cannot be overridden.
|
|
184
|
+
|
|
185
|
+
### Exit Codes
|
|
186
|
+
The Gatekeeper (`jules-self-audit.mjs` and related scripts) uses standard exit codes to signal status to CI systems.
|
|
187
|
+
|
|
188
|
+
| Code | Meaning | Action Taken |
|
|
189
|
+
| ---- | ------- | ------------ |
|
|
190
|
+
| `0` | **Success** | All tests and security checks passed. |
|
|
191
|
+
| `1` | **General Error** | Missing dependencies, syntax error, or general failure. |
|
|
192
|
+
| `2` | **Setup / Context Error** | Git not found, invalid `BASE_BRANCH`, or trusted base branch extraction failure. |
|
|
193
|
+
| `3` | **Security Violation** | Modified file breached `forbidden_paths` or changed command-defining files (`package.json`, `Cargo.toml`). Fails closed immediately. |
|
|
194
|
+
| `4` | **Verification Exhausted** | Tests failed and the OODA Auto-Repair loop either exhausted its max retries or is disabled. |
|
|
195
|
+
| `5` | **Diff Payload Too Large** | Diff payload size exceeded 75 KB payload governor limit. Split task. |
|
|
196
|
+
| `6` | **Secret Leak Prevented** | Secret-like pattern detected in diff. Aborted immediately. |
|
|
197
|
+
| `7` | **Budget Exhausted** | Daily session budget limit reached or budget state locked. |
|
|
303
198
|
|
|
304
199
|
---
|
|
305
200
|
|
|
306
|
-
##
|
|
201
|
+
## Contributing
|
|
202
|
+
We welcome contributions! Please follow these core principles:
|
|
203
|
+
1. **Zero External Dependencies**: Use ONLY native Node.js built-in modules (`node:fs`, `node:path`, `node:child_process`, `node:crypto`, `node:util`).
|
|
204
|
+
2. **Verification Suite**: Ensure 100% of unit tests pass cleanly (`npm test`).
|
|
205
|
+
3. **Conventional Commits**: Use standardized prefixes (`feat:`, `fix:`, `docs:`, `test:`, `chore:`).
|
|
206
|
+
4. **Cross-Platform Compatibility**: Normalize Windows backslashes (`\`) to POSIX slashes (`/`) for glob patterns and paths.
|
|
307
207
|
|
|
308
|
-
|
|
208
|
+
Please read our [Code of Conduct](CODE_OF_CONDUCT.md) before participating.
|
|
309
209
|
|
|
310
|
-
|
|
210
|
+
## License
|
|
211
|
+
MIT License - feel free to use, modify, and share!
|
package/index.mjs
CHANGED
|
@@ -7,5 +7,5 @@
|
|
|
7
7
|
export { resolveProjectCommands, resolveWorkspaceExecutionBoundary } from "./scripts/command-resolver.mjs";
|
|
8
8
|
export { runSelfAudit, runPreflightSandbox, loadForbiddenPatterns, loadAllowedPatterns, matchGlob } from "./scripts/jules-self-audit.mjs";
|
|
9
9
|
export { scanCodebaseForTodos, runScanner } from "./scripts/jules-scan-todos.mjs";
|
|
10
|
-
export { log, logToHistory, ensureDir, resolveMarkdownConflict } from "./scripts/utils.mjs";
|
|
11
|
-
export {
|
|
10
|
+
export { log, logToHistory, ensureDir, resolveMarkdownConflict, redactSecrets } from "./scripts/utils.mjs";
|
|
11
|
+
export { getDynamicGuardrails } from "./scripts/jules-dispatch.mjs";
|
package/package.json
CHANGED
|
@@ -185,8 +185,8 @@ export function resolveWorkspaceExecutionBoundary(modifiedFiles = [], projectRoo
|
|
|
185
185
|
if (fs.existsSync(path.join(projectRoot, "pnpm-workspace.yaml"))) {
|
|
186
186
|
const filters = targets.map((t) => `--filter=...${t}`).join(" ");
|
|
187
187
|
return {
|
|
188
|
-
buildCmd: `pnpm ${filters} build`,
|
|
189
|
-
testCmd: `pnpm ${filters} test`,
|
|
188
|
+
buildCmd: `pnpm ${filters} run build`,
|
|
189
|
+
testCmd: `pnpm ${filters} run test`,
|
|
190
190
|
source: `pnpm Workspace (${targets.join(", ")})`,
|
|
191
191
|
};
|
|
192
192
|
}
|
package/scripts/jules-create.mjs
CHANGED
|
@@ -19,8 +19,28 @@ const queueDir = path.resolve(process.cwd(), ".agent/jules-queue");
|
|
|
19
19
|
ensureDir(queueDir);
|
|
20
20
|
|
|
21
21
|
const safeTitle = taskTitle.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/(^-|-$)/g, "");
|
|
22
|
-
|
|
23
|
-
|
|
22
|
+
|
|
23
|
+
let maxId = 0;
|
|
24
|
+
const dirsToCheck = [queueDir, path.join(queueDir, ".processing"), path.join(queueDir, "completed")];
|
|
25
|
+
|
|
26
|
+
for (const dir of dirsToCheck) {
|
|
27
|
+
try {
|
|
28
|
+
const files = fs.readdirSync(dir);
|
|
29
|
+
for (const f of files) {
|
|
30
|
+
if (f.startsWith("TASK-") && f.endsWith(".md")) {
|
|
31
|
+
const match = f.match(/^TASK-(\d+)-/);
|
|
32
|
+
if (match) {
|
|
33
|
+
const id = parseInt(match[1], 10);
|
|
34
|
+
if (id > maxId) maxId = id;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
} catch (e) {
|
|
39
|
+
// Directory might not exist yet, that's fine
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const nextId = (maxId + 1).toString().padStart(3, "0");
|
|
24
44
|
const filename = `TASK-${nextId}-${safeTitle}.md`;
|
|
25
45
|
const filepath = path.join(queueDir, filename);
|
|
26
46
|
|