jules-orchestrator-kit 0.8.5 โ 0.9.4
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-queue/README.md +4 -4
- package/.agent/prompts/Bolt.md +18 -0
- package/.agent/prompts/Overseer.md +18 -0
- package/.agent/prompts/Sentinel.md +18 -0
- package/.agent/prompts/Task_Template.md +26 -0
- package/JULES_RULES_TEMPLATE.md +6 -1
- package/README.md +54 -31
- package/bin/agentctl.mjs +281 -0
- package/bin/mcp-server.mjs +5 -0
- package/index.mjs +32 -5
- package/package.json +13 -2
- package/scripts/asset-integrity-check.mjs +35 -0
- package/scripts/command-resolver.mjs +37 -214
- package/scripts/jules-cleanup.mjs +23 -164
- package/scripts/jules-create.mjs +12 -56
- package/scripts/jules-dispatch.mjs +103 -449
- package/scripts/jules-merge-swarm.mjs +19 -173
- package/scripts/jules-nightly.mjs +7 -128
- package/scripts/jules-patch.mjs +15 -103
- package/scripts/jules-queue-runner.mjs +28 -221
- package/scripts/jules-scan-todos.mjs +31 -125
- package/scripts/jules-self-audit.mjs +69 -656
- package/scripts/jules-status.mjs +42 -70
- package/scripts/jules-swarm.mjs +23 -327
- package/scripts/jules-webhook-receiver.mjs +70 -0
- package/scripts/lock-manager.mjs +11 -177
- package/scripts/risk-tier.mjs +29 -0
- package/scripts/rules-lint.mjs +20 -0
- package/scripts/stale-base-check.mjs +26 -0
- package/scripts/utils.mjs +107 -369
- package/scripts/validate-envelope.mjs +44 -0
- package/src/asset_integrity.mjs +76 -0
- package/src/config.mjs +325 -0
- package/src/engine.mjs +217 -0
- package/src/envelope.mjs +105 -0
- package/src/git.mjs +127 -0
- package/src/mcp.mjs +211 -0
- package/src/provider.mjs +179 -0
- package/src/risk.mjs +120 -0
- package/src/rules_budget.mjs +77 -0
- package/src/security.mjs +212 -0
- package/src/state.mjs +217 -0
- package/src/webhook.mjs +138 -0
|
@@ -19,12 +19,12 @@ Implement sliding window rate limiting for public API routes.
|
|
|
19
19
|
Process all queued tasks in batch:
|
|
20
20
|
|
|
21
21
|
```bash
|
|
22
|
-
|
|
23
|
-
# or
|
|
22
|
+
agentctl queue
|
|
23
|
+
# or npm run jules:queue
|
|
24
24
|
```
|
|
25
25
|
|
|
26
|
-
Or dispatch a single
|
|
26
|
+
Or dispatch a single task using `agentctl dispatch`:
|
|
27
27
|
|
|
28
28
|
```bash
|
|
29
|
-
|
|
29
|
+
agentctl dispatch --title "TASK-001 Rate Limiting" --prompt "$(cat .agent/jules-queue/TASK-001-rate-limiting.md)"
|
|
30
30
|
```
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Bolt - Performance & Payload Optimization Specialist โก
|
|
2
|
+
|
|
3
|
+
> **Role:** Codebase Micro-Optimizer & Payload Governor.
|
|
4
|
+
> **Scope:** Performance tuning, bundle size reduction, and asset optimization with zero structural side-effects.
|
|
5
|
+
|
|
6
|
+
## Core Directives
|
|
7
|
+
|
|
8
|
+
1. **Payload Budgeting:**
|
|
9
|
+
- Keep total diff payload strictly under 75 KB (`git diff | wc -c`).
|
|
10
|
+
- Eliminate redundant dependencies by replacing 3rd-party modules with Node.js built-ins (`node:fs`, `node:path`, `node:crypto`).
|
|
11
|
+
|
|
12
|
+
2. **Asset & Memory Optimization:**
|
|
13
|
+
- Replace heavy raster assets with modern WebP/AVIF equivalents or clean SVGs.
|
|
14
|
+
- Optimize hot execution paths: remove redundant object allocations inside tight loops.
|
|
15
|
+
|
|
16
|
+
3. **Zero Regressions Invariant:**
|
|
17
|
+
- Execute test suite (`npm test`) before and after every micro-optimization pass.
|
|
18
|
+
- Never disable type-checks, skip tests, or alter public API signatures.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Overseer Protocol - Codebase Audit Specialist ๐ค
|
|
2
|
+
|
|
3
|
+
> **Role:** Codebase Architecture Auditor & Technical Debt Mapper.
|
|
4
|
+
> **Scope:** Audit, map, and document codebase structural health without introducing destructive refactors.
|
|
5
|
+
|
|
6
|
+
## Core Directives
|
|
7
|
+
|
|
8
|
+
1. **Systematic Inspection:**
|
|
9
|
+
- Scan physical directory tree and identify monolithic files (> 300 lines).
|
|
10
|
+
- Locate empty catch blocks, swallowed errors, and dead code pathways ("Semantic Dust").
|
|
11
|
+
- Find hardcoded configuration strings, API keys, or raw `console.log` telemetry.
|
|
12
|
+
|
|
13
|
+
2. **Audit Journal Protocol:**
|
|
14
|
+
- Maintain a persistent audit journal in `.jules/Overseer.md` (or `.agent/history/overseer-journal.md`).
|
|
15
|
+
- Log mapped domains, architectural debt, and priority tasks for worker agents (`Bolt`, `Janitor`, `Sentinel`).
|
|
16
|
+
|
|
17
|
+
3. **Handover Invariant:**
|
|
18
|
+
- Do NOT execute sweeping refactors in the audit pass. Produce actionable, highly specific task definitions with file paths and line numbers.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Sentinel - Security Audit & Hardening Specialist ๐ก๏ธ
|
|
2
|
+
|
|
3
|
+
> **Role:** Codebase Security Auditor & AST Vulnerability Scanner.
|
|
4
|
+
> **Scope:** Input sanitization, secret scanning, RBAC verification, and prompt injection defense.
|
|
5
|
+
|
|
6
|
+
## Core Directives
|
|
7
|
+
|
|
8
|
+
1. **Vulnerability Mitigation:**
|
|
9
|
+
- Scan for unescaped SQL queries, `eval()`, dynamic `exec()`, or unvalidated shell arguments.
|
|
10
|
+
- Enforce explicit input validation and type coercion on all external API entry points.
|
|
11
|
+
|
|
12
|
+
2. **Secret Leak Prevention:**
|
|
13
|
+
- Ensure credentials, private keys, API tokens, and JWT secrets are loaded strictly from `process.env`.
|
|
14
|
+
- Never log sensitive tokens or unmasked PII into console logs or file artifacts.
|
|
15
|
+
|
|
16
|
+
3. **Untrusted Fencing:**
|
|
17
|
+
- Label user-controllable input data with `<UNTRUSTED>` fencing tags.
|
|
18
|
+
- Instruct parsing logic to fail-closed on malformed or malicious payload structures.
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Master Task Prompt Template ๐
|
|
2
|
+
|
|
3
|
+
> **Role:** You are Jules, an expert AI software engineer. Your purpose is to solve engineering tasks by autonomously exploring the codebase, creating a plan, executing it, and verifying your work.
|
|
4
|
+
|
|
5
|
+
## Objective
|
|
6
|
+
[State the exact goal of the task clearly and concisely. E.g., "Implement JWT authentication middleware for REST API endpoints."]
|
|
7
|
+
|
|
8
|
+
## Context
|
|
9
|
+
- **Project Goals:** [Describe key architectural or business goals.]
|
|
10
|
+
- **Key Files & Folders:** [List critical files, directories, or schemas, e.g. `src/auth.ts`, `schema.sql`.]
|
|
11
|
+
- **Tech Stack:** [List frameworks and libraries, e.g. Node.js, Express, TypeScript, Drizzle ORM.]
|
|
12
|
+
|
|
13
|
+
## Requirements & Hard Constraints
|
|
14
|
+
- **Functional Requirements:** [List specific, non-negotiable functional requirements.]
|
|
15
|
+
- **Hard Constraints:**
|
|
16
|
+
- Do NOT introduce third-party npm dependencies without explicit authorization.
|
|
17
|
+
- Do NOT modify command files (`package.json`, `.github/`) or Agent Scope files.
|
|
18
|
+
- Keep total diff payload strictly under 75 KB (`git diff | wc -c`).
|
|
19
|
+
|
|
20
|
+
## Verification Loop
|
|
21
|
+
- **Verification Command:** Execute automated verification tests: `npm test`.
|
|
22
|
+
- **Zero Errors Invariant:** Ensure 100% of tests pass cleanly with 0 errors before submitting.
|
|
23
|
+
|
|
24
|
+
## Expected Artifacts
|
|
25
|
+
- **Code Changes:** Clean, production-grade implementation preserving existing symbol contracts.
|
|
26
|
+
- **Test Coverage:** Updated or new unit/integration test cases covering modified logic.
|
package/JULES_RULES_TEMPLATE.md
CHANGED
|
@@ -50,9 +50,12 @@ Jules automatically infers test and build verification commands via `scripts/com
|
|
|
50
50
|
|
|
51
51
|
- **Read Before Write**: Always inspect target files and surrounding symbol signatures (via grep or view tools) before applying changes.
|
|
52
52
|
- **Scope Locks**: Strictly adhere to designated file bounds. Do NOT modify files outside the explicit task scope or alter shared infrastructural components unless assigned.
|
|
53
|
+
- **Falsifiable Criteria**: Never use unfalsifiable goals ("utterly perfect", "complete refactor"). Define tasks with binary scoreable criteria (e.g. passing test counts, 0 lint errors, explicit hard-fails).
|
|
54
|
+
- **Carry Evidence with Claims**: "It works" means pasting terminal verification output. Exit code 0 alone proves only process survival; inspect outputs/artifacts to prove function.
|
|
55
|
+
- **No Test Weakening Rule**: Never make a test pass by deleting assertions, commenting out checks, or weakening requirements. Leave unmet requirements RED with clear fix rationale.
|
|
56
|
+
- **Explicit File Ownership**: Sequence parallel swarm agents with explicit non-overlapping file ownership to prevent concurrent drift.
|
|
53
57
|
- **Rebase Before PR**: Fetch latest `main`, rebase onto `origin/main`, re-execute verification suite. If the resulting diff is empty, close/abort PR without pushing.
|
|
54
58
|
- **Minimal Interference**: Preserve existing function signatures, comments, and style conventions.
|
|
55
|
-
- **Falsifiable Claims**: Base all code changes on explicit error logs, file paths, line numbers, or test results.
|
|
56
59
|
- **No Token Bloat**: Exclude lockfiles, minified bundles, and binary assets from diff representations.
|
|
57
60
|
|
|
58
61
|
---
|
|
@@ -101,6 +104,8 @@ TASK: <description>
|
|
|
101
104
|
HARD CONSTRAINTS:
|
|
102
105
|
- Do NOT modify package.json, pnpm-lock.yaml, tsconfig.json, or .github/ files. Enforced in CI by Agent Scope Guard.
|
|
103
106
|
- Diff Payload Governor: Keep total diff payload under 75 KB (`git diff | wc -c`) to prevent API truncation (~80 KB limit).
|
|
107
|
+
- Falsifiable & Evidence-Based: Attach full terminal verification output to PR. Never weaken assertions or delete failing tests to force a pass.
|
|
108
|
+
- Declare Scope Deviations: If modifying files outside task bounds, explicitly state rationale in PR.
|
|
104
109
|
- Verify before finishing: Run full type-check, lint, and unit test suites.
|
|
105
110
|
- BEFORE opening the PR: Run `git fetch origin main && git rebase origin/main`, then re-verify. If the rebase leaves an empty diff, the work already landed โ do NOT submit.
|
|
106
111
|
- Delete ALL temporary files (.py, .sh, .patch, debug logs) before submitting.
|
package/README.md
CHANGED
|
@@ -22,16 +22,21 @@ To use this kit, you will need:
|
|
|
22
22
|
- A Google Jules REST API key (set as `JULES_API_KEY`) **OR** the native `jules` binary in your PATH.
|
|
23
23
|
|
|
24
24
|
## Quick Start
|
|
25
|
-
|
|
25
|
+
Initialize your repository:
|
|
26
26
|
```bash
|
|
27
|
-
npx jules-orchestrator-kit
|
|
28
|
-
npm run jules:create "Refactor Auth"
|
|
29
|
-
npm run jules:queue
|
|
27
|
+
npx jules-orchestrator-kit init
|
|
30
28
|
```
|
|
31
29
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
30
|
+
Dispatch a task or run the queue using `agentctl`:
|
|
31
|
+
```bash
|
|
32
|
+
agentctl dispatch --title "Refactor Auth" --prompt "Implement JWT verification in auth handler"
|
|
33
|
+
agentctl queue
|
|
34
|
+
agentctl gate
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
> ๐ก **Unified Engine CLI (`agentctl`)**:
|
|
38
|
+
> `agentctl` is the zero-dependency CLI executable that powers dispatching, safety gate auditing, mutex locks, and swarm management across all project types (Node, Rust, Go, Python, etc.).
|
|
39
|
+
> Legacy `scripts/jules-*.mjs` shims are preserved for backward compatibility.
|
|
35
40
|
|
|
36
41
|
---
|
|
37
42
|
|
|
@@ -53,6 +58,7 @@ sequenceDiagram
|
|
|
53
58
|
|
|
54
59
|
box "Control Plane" #E8F4F8
|
|
55
60
|
participant Orc as Orchestrator Core
|
|
61
|
+
participant Envelope as Task Envelope Validator
|
|
56
62
|
participant Gate as Self-Audit Gatekeeper
|
|
57
63
|
end
|
|
58
64
|
|
|
@@ -61,12 +67,19 @@ sequenceDiagram
|
|
|
61
67
|
participant Git as Git Worktree Sandbox
|
|
62
68
|
end
|
|
63
69
|
|
|
64
|
-
Trigger->>+Orc: Dispatch Task Payload
|
|
70
|
+
Trigger->>+Orc: Dispatch Task Payload / Envelope
|
|
65
71
|
|
|
66
|
-
note over Orc,
|
|
67
|
-
Orc
|
|
68
|
-
|
|
69
|
-
|
|
72
|
+
note over Orc,Envelope: Phase 1: Pre-Flight Premise & Security Validation
|
|
73
|
+
Orc->>+Envelope: Validate Envelope (referenced_paths exist? base commit fresh?)
|
|
74
|
+
alt Premise Failure / Missing Referenced Paths / Stale Base
|
|
75
|
+
Envelope-->>Orc: Validation Failed (Premise Error)
|
|
76
|
+
Orc-->>Trigger: Abort Pre-Dispatch (Exit 1)
|
|
77
|
+
else Envelope Validated
|
|
78
|
+
Envelope-->>-Orc: Envelope Approved
|
|
79
|
+
Orc->>Orc: Redact Secrets (Entropy > 3.6) & Enforce Dynamic Guardrails
|
|
80
|
+
Orc->>+Git: Provision Isolation Sandbox (git worktree)
|
|
81
|
+
Git-->>-Orc: Sandbox Ready
|
|
82
|
+
end
|
|
70
83
|
|
|
71
84
|
loop OODA Repair Cycle (Max 3 Retries)
|
|
72
85
|
note over Orc,Git: Phase 2: Agent Execution & Dispatch
|
|
@@ -75,28 +88,29 @@ sequenceDiagram
|
|
|
75
88
|
Git-->>-API: Changes Written
|
|
76
89
|
API-->>-Orc: Execution Complete
|
|
77
90
|
|
|
78
|
-
note over Orc,Gate: Phase 3:
|
|
91
|
+
note over Orc,Gate: Phase 3: Multi-Gate Verification & Risk Classification
|
|
79
92
|
Orc->>+Gate: Trigger Self-Audit (trusted origin/main rules)
|
|
80
93
|
|
|
81
|
-
Gate->>+Git: Scope Audit (`git diff
|
|
82
|
-
Git-->>-Gate: Diff Stats &
|
|
94
|
+
Gate->>+Git: Run Scope, Payload & Stale-Base Audit (`git diff`)
|
|
95
|
+
Git-->>-Gate: Diff Stats & Base Commit Age
|
|
83
96
|
|
|
84
|
-
alt Scope Breach
|
|
85
|
-
Gate-->>Orc: Security / Scope Violation
|
|
97
|
+
alt Scope Breach / Payload > 75 KB / Stale Base > 25 commits
|
|
98
|
+
Gate-->>Orc: Security / Scope / Stale-Base Violation
|
|
86
99
|
Orc->>Orc: Record Telemetry (metrics.jsonl)
|
|
87
100
|
Orc-->>Trigger: Abort Execution (Exit 3)
|
|
88
|
-
break Fatal Security Error
|
|
101
|
+
break Fatal Security or Base Error
|
|
89
102
|
Orc->>Git: Teardown Worktree Sandbox
|
|
90
103
|
end
|
|
91
|
-
else Scope
|
|
92
|
-
Gate
|
|
93
|
-
Git
|
|
104
|
+
else Static Scope & Base Passed
|
|
105
|
+
Gate->>Gate: Classify Risk Tier (R0 Cosmetic, R1 Routine, R2 Consequential, R3 Restricted)
|
|
106
|
+
Gate->>+Git: Run Integrity Checks (Asset Magic-Bytes, Rules Budget, testCmd & buildCmd)
|
|
107
|
+
Git-->>-Gate: Execution & Integrity Proof (stdout/stderr)
|
|
94
108
|
end
|
|
95
109
|
|
|
96
|
-
alt 100% Verification Suite Passed
|
|
97
|
-
Gate-->>-Orc: Verification Success
|
|
110
|
+
alt 100% Verification Suite & Integrity Passed
|
|
111
|
+
Gate-->>-Orc: Verification Success + Risk Tier Metadata
|
|
98
112
|
Orc->>+Git: Commit & Push to Remote Branch / PR
|
|
99
|
-
Git-->>-Orc: PR Ready
|
|
113
|
+
Git-->>-Orc: PR Ready (Attached Execution Receipts)
|
|
100
114
|
Orc->>Orc: Record Telemetry (metrics.jsonl)
|
|
101
115
|
Orc-->>Trigger: Dispatch Succeeded (Exit 0)
|
|
102
116
|
break Task Completed
|
|
@@ -117,10 +131,12 @@ sequenceDiagram
|
|
|
117
131
|
```
|
|
118
132
|
|
|
119
133
|
> ๐ก **Core Architectural Invariants**:
|
|
134
|
+
> - **Task Envelope Premise Validation**: Pre-flight checks verify referenced paths and base freshness before dispatching tasks to prevent session burnout.
|
|
135
|
+
> - **Risk Tier Classification Engine (R0โR3)**: Classifies changes by blast radius to route auto-merge vs mandatory human review.
|
|
120
136
|
> - **Zero-Trust Base-Branch Security**: Security rules (`forbidden_paths`) are fetched exclusively from `origin/main` (never untrusted PR branches).
|
|
137
|
+
> - **Asset & Rules Integrity**: Guards binary assets against HTML corruption and enforces character/line budgets on rule files.
|
|
121
138
|
> - **Automatic PII & Secret Redaction**: Outbound task prompts are automatically sanitized to redact API secrets and mask sensitive PII (emails, IPs, phone numbers).
|
|
122
139
|
> - **Ledger Hash-Chain Integrity**: Hashing over JSONL event streams detects unauthorized log tampering or record deletions.
|
|
123
|
-
> - **Dynamic Command Resolution (`command-resolver.mjs`)**: Auto-detects workspace boundaries (Turborepo, pnpm, Nx, Cargo, pytest, npm).
|
|
124
140
|
>
|
|
125
141
|
> ๐ For a deep dive into the execution protocol, see the [Architecture & Pipeline Flow](docs/architecture.md).
|
|
126
142
|
|
|
@@ -171,16 +187,16 @@ If no API key is configured, the kit seamlessly falls back to invoking your loca
|
|
|
171
187
|
**3. Programmatic Node.js SDK (`index.mjs`)**
|
|
172
188
|
Downstream Node.js tools, MCP servers, and LLM orchestrators can import kit functions directly:
|
|
173
189
|
```js
|
|
174
|
-
import {
|
|
190
|
+
import { gate, dispatch, validateEnvelope, classifyRiskTier, checkAssetIntegrity, checkRulesBudget, redactSecrets } from "jules-orchestrator-kit";
|
|
175
191
|
|
|
176
192
|
// Anonymize sensitive PII (emails, IPs, phone numbers) before sending prompts
|
|
177
193
|
const cleanPrompt = anonymizePii("Contact support at john@example.com");
|
|
178
194
|
|
|
179
195
|
// Programmatically dispatch tasks
|
|
180
|
-
await
|
|
196
|
+
await dispatch({ title: "Refactor Auth", prompt: cleanPrompt });
|
|
181
197
|
|
|
182
|
-
//
|
|
183
|
-
const
|
|
198
|
+
// Run 4-phase safety gate audit
|
|
199
|
+
const audit = await gate({ base: "main" });
|
|
184
200
|
```
|
|
185
201
|
|
|
186
202
|
---
|
|
@@ -227,14 +243,21 @@ All commands are registered in `package.json` and can be run via `npm run <comma
|
|
|
227
243
|
| `npm run jules:dispatch` | Dispatches a single task directly to Jules |
|
|
228
244
|
| `npm run jules:queue` | Runs the local queue processor (picks up tasks from `.agent/jules-queue`) |
|
|
229
245
|
| `npm run jules:create` | Scaffolds a new boilerplate task markdown file |
|
|
230
|
-
| `npm run jules:status` | Shows
|
|
246
|
+
| `npm run jules:status` | Shows real-time 3-bucket status (Action Required, In Progress, Completed) |
|
|
231
247
|
| `npm run jules:audit` | Runs the self-audit gatekeeper (verifies tests, forbidden paths, and scope) |
|
|
232
248
|
| `npm run jules:cleanup` | Audits and closes merged or stale REST sessions |
|
|
233
249
|
| `npm run jules:scan` | Scans the codebase for TODO/FIXME comments and generates a suggested tasks file |
|
|
234
250
|
| `npm run jules:swarm` | Launches a multi-agent swarm in parallel across isolated worktrees |
|
|
235
|
-
| `npm run jules:merge-swarm` | Autonomous PR merge engine
|
|
251
|
+
| `npm run jules:merge-swarm` | Autonomous PR merge engine with Safety Gate lock verification |
|
|
236
252
|
| `npm run jules:nightly` | Nightly maintenance job (usually triggered in CI) |
|
|
237
253
|
|
|
254
|
+
### Specialist Agent Prompts & Templates (`.agent/prompts/`)
|
|
255
|
+
The kit includes pre-configured single-responsibility prompt presets in `.agent/prompts/`:
|
|
256
|
+
- **`Overseer.md`**: Codebase architecture auditor & technical debt mapper.
|
|
257
|
+
- **`Bolt.md`**: Performance micro-optimizer and payload governor (enforces < 75 KB payload diff limits).
|
|
258
|
+
- **`Sentinel.md`**: Security audit specialist for input sanitization and secret scanning.
|
|
259
|
+
- **`Task_Template.md`**: Machine-readable master task prompt template schema.
|
|
260
|
+
|
|
238
261
|
### Environment Variables
|
|
239
262
|
|
|
240
263
|
| Variable | Description |
|
package/bin/agentctl.mjs
ADDED
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { parseArgs } from "node:util";
|
|
4
|
+
import { readFileSync, writeFileSync, existsSync, readdirSync } from "node:fs";
|
|
5
|
+
import { join } from "node:path";
|
|
6
|
+
import { loadConfig, resolveRoot, detectStack } from "../src/config.mjs";
|
|
7
|
+
import { gate, dispatch, run } from "../src/engine.mjs";
|
|
8
|
+
import { acquireLock, releaseLock, lockStatus, checkDailyBudget, getQueueDir, ensureDir } from "../src/state.mjs";
|
|
9
|
+
import { worktreePrune } from "../src/git.mjs";
|
|
10
|
+
|
|
11
|
+
const args = process.argv.slice(2);
|
|
12
|
+
const command = args[0];
|
|
13
|
+
|
|
14
|
+
function printHelp() {
|
|
15
|
+
console.log(`
|
|
16
|
+
๐ agentctl v0.9.4 โ Universal Agent Orchestrator & Safety Gatekeeper
|
|
17
|
+
|
|
18
|
+
Usage: agentctl <command> [options]
|
|
19
|
+
|
|
20
|
+
Commands:
|
|
21
|
+
dispatch Dispatch a single task to an AI agent
|
|
22
|
+
gate | audit Run CI security and verification gate against current branch
|
|
23
|
+
queue Run pending task queue
|
|
24
|
+
swarm Run parallel task swarm
|
|
25
|
+
mcp Start stdio Model Context Protocol (MCP) server
|
|
26
|
+
clean Clean stale branches, worktrees, locks, and ledgers
|
|
27
|
+
lock <action> Manage mutex locks (acquire | release | status | cleanup)
|
|
28
|
+
doctor Run system diagnostics and stack resolution checks
|
|
29
|
+
init Scaffold .agent/ directory and config.yml
|
|
30
|
+
version Output agentctl version
|
|
31
|
+
|
|
32
|
+
Options:
|
|
33
|
+
--dry-run, -d Simulate action without making API calls or modifying git
|
|
34
|
+
--json, -j Emit machine-readable JSON output
|
|
35
|
+
--help, -h Show command help
|
|
36
|
+
`);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
async function main() {
|
|
40
|
+
if (!command || command === "--help" || command === "-h") {
|
|
41
|
+
printHelp();
|
|
42
|
+
process.exit(0);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if (command === "version" || command === "--version" || command === "-v") {
|
|
46
|
+
console.log("agentctl v0.9.4");
|
|
47
|
+
process.exit(0);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const root = resolveRoot();
|
|
51
|
+
const config = loadConfig(root);
|
|
52
|
+
|
|
53
|
+
switch (command) {
|
|
54
|
+
case "dispatch": {
|
|
55
|
+
const { values } = parseArgs({
|
|
56
|
+
args: args.slice(1),
|
|
57
|
+
options: {
|
|
58
|
+
title: { type: "string", short: "t" },
|
|
59
|
+
prompt: { type: "string", short: "p" },
|
|
60
|
+
"prompt-file": { type: "string", short: "f" },
|
|
61
|
+
"dry-run": { type: "boolean", short: "d" },
|
|
62
|
+
json: { type: "boolean", short: "j" },
|
|
63
|
+
},
|
|
64
|
+
allowPositionals: true,
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
let promptContent = values.prompt || "";
|
|
68
|
+
if (values["prompt-file"] && existsSync(values["prompt-file"])) {
|
|
69
|
+
promptContent = readFileSync(values["prompt-file"], "utf-8");
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if (!promptContent && args[1] && !args[1].startsWith("-")) {
|
|
73
|
+
promptContent = args.slice(1).join(" ");
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
if (!promptContent) {
|
|
77
|
+
console.error("Error: --prompt or --prompt-file is required.");
|
|
78
|
+
process.exit(1);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const task = {
|
|
82
|
+
title: values.title || "CLI Dispatch Task",
|
|
83
|
+
prompt: promptContent,
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
try {
|
|
87
|
+
const session = await dispatch(task, { root, config, dryRun: values["dry-run"] });
|
|
88
|
+
if (values.json) {
|
|
89
|
+
console.log(JSON.stringify({ ok: true, session }, null, 2));
|
|
90
|
+
} else {
|
|
91
|
+
console.log(`\nโ
Task Dispatched Successfully!`);
|
|
92
|
+
console.log(` Session ID : ${session.id}`);
|
|
93
|
+
console.log(` Session URL : ${session.url || "N/A"}`);
|
|
94
|
+
}
|
|
95
|
+
process.exit(0);
|
|
96
|
+
} catch (err) {
|
|
97
|
+
if (values.json) {
|
|
98
|
+
console.log(JSON.stringify({ ok: false, error: err.message, code: err.code || 1 }, null, 2));
|
|
99
|
+
} else {
|
|
100
|
+
console.error(`โ Dispatch Failed: ${err.message}`);
|
|
101
|
+
}
|
|
102
|
+
process.exit(err.code || 1);
|
|
103
|
+
}
|
|
104
|
+
break;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
case "gate":
|
|
108
|
+
case "audit": {
|
|
109
|
+
const { values } = parseArgs({
|
|
110
|
+
args: args.slice(1),
|
|
111
|
+
options: {
|
|
112
|
+
base: { type: "string", short: "b", default: config.baseBranch || "main" },
|
|
113
|
+
fix: { type: "boolean" },
|
|
114
|
+
"allow-protected": { type: "boolean" },
|
|
115
|
+
json: { type: "boolean", short: "j" },
|
|
116
|
+
},
|
|
117
|
+
allowPositionals: true,
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
const res = await gate({
|
|
121
|
+
root,
|
|
122
|
+
config,
|
|
123
|
+
base: values.base,
|
|
124
|
+
fix: values.fix,
|
|
125
|
+
allowProtected: values["allow-protected"],
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
if (values.json) {
|
|
129
|
+
console.log(JSON.stringify(res, null, 2));
|
|
130
|
+
} else {
|
|
131
|
+
console.log(`\n๐ก๏ธ agentctl Safety Gate Audit Results (Base: ${values.base})`);
|
|
132
|
+
console.log(`-----------------------------------------------------`);
|
|
133
|
+
for (const p of res.phases) {
|
|
134
|
+
const status = p.ok ? "โ
PASS" : "โ FAIL";
|
|
135
|
+
console.log(` Phase [${p.phase.toUpperCase()}] : ${status}`);
|
|
136
|
+
if (p.violations) {
|
|
137
|
+
p.violations.forEach((v) => console.log(` - Violation: ${v.file} (Rule: ${v.rule})`));
|
|
138
|
+
}
|
|
139
|
+
if (p.findings) {
|
|
140
|
+
p.findings.forEach((f) => console.log(` - Finding: ${f.id} at line ${f.line}`));
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
console.log(`-----------------------------------------------------`);
|
|
144
|
+
console.log(`Overall Result: ${res.ok ? "APPROVED (Exit 0)" : `REJECTED (Exit ${res.code})`}\n`);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
process.exit(res.code);
|
|
148
|
+
break;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
case "queue": {
|
|
152
|
+
const queueDir = getQueueDir(root);
|
|
153
|
+
const files = readdirSync(queueDir).filter((f) => f.endsWith(".md"));
|
|
154
|
+
console.log(` Found ${files.length} queued task(s) in .agent/queue/`);
|
|
155
|
+
if (files.length > 0) {
|
|
156
|
+
const tasks = files.map((f) => ({
|
|
157
|
+
id: f,
|
|
158
|
+
title: f.replace(/\.md$/, ""),
|
|
159
|
+
prompt: readFileSync(join(queueDir, f), "utf-8"),
|
|
160
|
+
}));
|
|
161
|
+
const results = await run(tasks, { root, config });
|
|
162
|
+
console.log(`\nProcessed ${results.length} tasks.`);
|
|
163
|
+
}
|
|
164
|
+
process.exit(0);
|
|
165
|
+
break;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
case "swarm": {
|
|
169
|
+
console.log("๐ Running Swarm Orchestrator...");
|
|
170
|
+
const queueDir = getQueueDir(root);
|
|
171
|
+
const files = readdirSync(queueDir).filter((f) => f.endsWith(".md"));
|
|
172
|
+
if (files.length === 0) {
|
|
173
|
+
console.log("No pending tasks found for swarm.");
|
|
174
|
+
process.exit(0);
|
|
175
|
+
}
|
|
176
|
+
const tasks = files.map((f) => ({
|
|
177
|
+
id: f,
|
|
178
|
+
title: f.replace(/\.md$/, ""),
|
|
179
|
+
prompt: readFileSync(join(queueDir, f), "utf-8"),
|
|
180
|
+
}));
|
|
181
|
+
const results = await run(tasks, { root, config, concurrency: config.limits.concurrency || 3 });
|
|
182
|
+
console.log(`Swarm completed ${results.length} tasks.`);
|
|
183
|
+
process.exit(0);
|
|
184
|
+
break;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
case "clean": {
|
|
188
|
+
console.log("๐งน Running System Cleanup...");
|
|
189
|
+
worktreePrune(root);
|
|
190
|
+
console.log(" โ
Pruned stale Git worktrees.");
|
|
191
|
+
process.exit(0);
|
|
192
|
+
break;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
case "lock": {
|
|
196
|
+
const action = args[1];
|
|
197
|
+
if (action === "acquire") {
|
|
198
|
+
const agent = args[2] || "agent";
|
|
199
|
+
const taskId = args[3] || "task-1";
|
|
200
|
+
const filePaths = args.slice(4);
|
|
201
|
+
const res = acquireLock(agent, taskId, filePaths, root);
|
|
202
|
+
if (res.ok) {
|
|
203
|
+
console.log(`โ
Acquired lock for ${taskId}`);
|
|
204
|
+
} else {
|
|
205
|
+
console.log(`โ Lock conflict detected: held by ${res.holder}`);
|
|
206
|
+
process.exit(1);
|
|
207
|
+
}
|
|
208
|
+
} else if (action === "release") {
|
|
209
|
+
const taskId = args[2] || "task-1";
|
|
210
|
+
const ok = releaseLock(taskId, root);
|
|
211
|
+
if (ok) {
|
|
212
|
+
console.log(`โ
Released lock for ${taskId}`);
|
|
213
|
+
} else {
|
|
214
|
+
console.log(`โ Lock for ${taskId} not found or release failed`);
|
|
215
|
+
process.exit(1);
|
|
216
|
+
}
|
|
217
|
+
} else {
|
|
218
|
+
const locks = lockStatus(root);
|
|
219
|
+
console.log(`Active Locks (${locks.length}):`, locks);
|
|
220
|
+
}
|
|
221
|
+
process.exit(0);
|
|
222
|
+
break;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
case "doctor": {
|
|
226
|
+
console.log(`\n๐ agentctl System Diagnostics (v0.9.0)`);
|
|
227
|
+
console.log(`--------------------------------------------------`);
|
|
228
|
+
console.log(` Project Root : ${root}`);
|
|
229
|
+
console.log(` Config File : ${config._file || "None (Using defaults)"}`);
|
|
230
|
+
console.log(` Detected Stack : ${detectStack(root).stack}`);
|
|
231
|
+
console.log(` Test Command : ${config.verify.test || "(None)"}`);
|
|
232
|
+
console.log(` Build Command : ${config.verify.build || "(None)"}`);
|
|
233
|
+
const budget = checkDailyBudget(root, config.limits.dailyTasks);
|
|
234
|
+
console.log(` Daily Budget : ${budget.used} / ${budget.budget} sessions used`);
|
|
235
|
+
console.log(`--------------------------------------------------\n`);
|
|
236
|
+
process.exit(0);
|
|
237
|
+
break;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
case "init": {
|
|
241
|
+
const agentDir = join(root, ".agent");
|
|
242
|
+
ensureDir(agentDir);
|
|
243
|
+
const configPath = join(agentDir, "config.yml");
|
|
244
|
+
if (!existsSync(configPath)) {
|
|
245
|
+
writeFileSync(
|
|
246
|
+
configPath,
|
|
247
|
+
`version: 1
|
|
248
|
+
provider: jules
|
|
249
|
+
limits:
|
|
250
|
+
diff_kb: 75
|
|
251
|
+
daily_tasks: 300
|
|
252
|
+
branch_prefix: agent/
|
|
253
|
+
base_branch: main
|
|
254
|
+
`,
|
|
255
|
+
"utf-8"
|
|
256
|
+
);
|
|
257
|
+
console.log(`โ
Created .agent/config.yml`);
|
|
258
|
+
} else {
|
|
259
|
+
console.log(`โน๏ธ .agent/config.yml already exists.`);
|
|
260
|
+
}
|
|
261
|
+
process.exit(0);
|
|
262
|
+
break;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
case "mcp": {
|
|
266
|
+
const { startMcpServer } = await import("../src/mcp.mjs");
|
|
267
|
+
startMcpServer();
|
|
268
|
+
break;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
default:
|
|
272
|
+
console.error(`Unknown command: ${command}`);
|
|
273
|
+
printHelp();
|
|
274
|
+
process.exit(1);
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
main().catch((err) => {
|
|
279
|
+
console.error(`[FATAL ERROR] ${err.message}`);
|
|
280
|
+
process.exit(err.code || 1);
|
|
281
|
+
});
|
package/index.mjs
CHANGED
|
@@ -1,12 +1,39 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
2
|
+
* Google Jules Orchestrator Kit - Node.js SDK (v0.9.0)
|
|
3
|
+
*
|
|
4
|
+
* Exposes core orchestrator functions for programmatically driving agent tasks,
|
|
5
|
+
* security auditing, repo gating, and state operations.
|
|
5
6
|
*/
|
|
6
7
|
|
|
8
|
+
export { loadConfig, detectStack, resolveVerify, resolveRoot, normalizePath } from "./src/config.mjs";
|
|
9
|
+
export {
|
|
10
|
+
shannonEntropy,
|
|
11
|
+
redactSecrets,
|
|
12
|
+
anonymizePii,
|
|
13
|
+
matchesGlob,
|
|
14
|
+
checkScope,
|
|
15
|
+
scanDiff,
|
|
16
|
+
} from "./src/security.mjs";
|
|
17
|
+
export { git, runCmd, changedFiles, diffBytes, diffText } from "./src/git.mjs";
|
|
18
|
+
export { createProvider, JULES_PRESET, CLAUDE_PRESET, CODEX_PRESET } from "./src/provider.mjs";
|
|
19
|
+
export {
|
|
20
|
+
appendLedger,
|
|
21
|
+
readLedger,
|
|
22
|
+
withBudget,
|
|
23
|
+
checkDailyBudget,
|
|
24
|
+
acquireLock,
|
|
25
|
+
releaseLock,
|
|
26
|
+
lockStatus,
|
|
27
|
+
} from "./src/state.mjs";
|
|
28
|
+
export { gate, dispatch, repair, run } from "./src/engine.mjs";
|
|
29
|
+
export { validateEnvelope } from "./src/envelope.mjs";
|
|
30
|
+
export { checkAssetIntegrity } from "./src/asset_integrity.mjs";
|
|
31
|
+
export { classifyRiskTier, RISK_TIERS } from "./src/risk.mjs";
|
|
32
|
+
export { checkRulesBudget } from "./src/rules_budget.mjs";
|
|
33
|
+
|
|
34
|
+
// Legacy SDK shims for backward compatibility
|
|
7
35
|
export { resolveProjectCommands, resolveWorkspaceExecutionBoundary } from "./scripts/command-resolver.mjs";
|
|
8
|
-
export { runSelfAudit, runPreflightSandbox
|
|
36
|
+
export { runSelfAudit, runPreflightSandbox } from "./scripts/jules-self-audit.mjs";
|
|
9
37
|
export { scanCodebaseForTodos, runScanner } from "./scripts/jules-scan-todos.mjs";
|
|
10
|
-
export { log, logToHistory, ensureDir, resolveMarkdownConflict, redactSecrets, anonymizePii, verifyLedgerIntegrity, loadEnv } from "./scripts/utils.mjs";
|
|
11
38
|
export { getDynamicGuardrails, dispatchTask } from "./scripts/jules-dispatch.mjs";
|
|
12
39
|
export { classifyQueueFailure } from "./scripts/jules-queue-runner.mjs";
|