jules-orchestrator-kit 0.8.5 â 0.9.3
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 +25 -13
- package/bin/agentctl.mjs +274 -0
- package/index.mjs +32 -5
- package/package.json +11 -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/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 +209 -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
|
|
|
@@ -171,16 +176,16 @@ If no API key is configured, the kit seamlessly falls back to invoking your loca
|
|
|
171
176
|
**3. Programmatic Node.js SDK (`index.mjs`)**
|
|
172
177
|
Downstream Node.js tools, MCP servers, and LLM orchestrators can import kit functions directly:
|
|
173
178
|
```js
|
|
174
|
-
import {
|
|
179
|
+
import { gate, dispatch, validateEnvelope, classifyRiskTier, checkAssetIntegrity, checkRulesBudget, redactSecrets } from "jules-orchestrator-kit";
|
|
175
180
|
|
|
176
181
|
// Anonymize sensitive PII (emails, IPs, phone numbers) before sending prompts
|
|
177
182
|
const cleanPrompt = anonymizePii("Contact support at john@example.com");
|
|
178
183
|
|
|
179
184
|
// Programmatically dispatch tasks
|
|
180
|
-
await
|
|
185
|
+
await dispatch({ title: "Refactor Auth", prompt: cleanPrompt });
|
|
181
186
|
|
|
182
|
-
//
|
|
183
|
-
const
|
|
187
|
+
// Run 4-phase safety gate audit
|
|
188
|
+
const audit = await gate({ base: "main" });
|
|
184
189
|
```
|
|
185
190
|
|
|
186
191
|
---
|
|
@@ -227,14 +232,21 @@ All commands are registered in `package.json` and can be run via `npm run <comma
|
|
|
227
232
|
| `npm run jules:dispatch` | Dispatches a single task directly to Jules |
|
|
228
233
|
| `npm run jules:queue` | Runs the local queue processor (picks up tasks from `.agent/jules-queue`) |
|
|
229
234
|
| `npm run jules:create` | Scaffolds a new boilerplate task markdown file |
|
|
230
|
-
| `npm run jules:status` | Shows
|
|
235
|
+
| `npm run jules:status` | Shows real-time 3-bucket status (Action Required, In Progress, Completed) |
|
|
231
236
|
| `npm run jules:audit` | Runs the self-audit gatekeeper (verifies tests, forbidden paths, and scope) |
|
|
232
237
|
| `npm run jules:cleanup` | Audits and closes merged or stale REST sessions |
|
|
233
238
|
| `npm run jules:scan` | Scans the codebase for TODO/FIXME comments and generates a suggested tasks file |
|
|
234
239
|
| `npm run jules:swarm` | Launches a multi-agent swarm in parallel across isolated worktrees |
|
|
235
|
-
| `npm run jules:merge-swarm` | Autonomous PR merge engine
|
|
240
|
+
| `npm run jules:merge-swarm` | Autonomous PR merge engine with Safety Gate lock verification |
|
|
236
241
|
| `npm run jules:nightly` | Nightly maintenance job (usually triggered in CI) |
|
|
237
242
|
|
|
243
|
+
### Specialist Agent Prompts & Templates (`.agent/prompts/`)
|
|
244
|
+
The kit includes pre-configured single-responsibility prompt presets in `.agent/prompts/`:
|
|
245
|
+
- **`Overseer.md`**: Codebase architecture auditor & technical debt mapper.
|
|
246
|
+
- **`Bolt.md`**: Performance micro-optimizer and payload governor (enforces < 75 KB payload diff limits).
|
|
247
|
+
- **`Sentinel.md`**: Security audit specialist for input sanitization and secret scanning.
|
|
248
|
+
- **`Task_Template.md`**: Machine-readable master task prompt template schema.
|
|
249
|
+
|
|
238
250
|
### Environment Variables
|
|
239
251
|
|
|
240
252
|
| Variable | Description |
|
package/bin/agentctl.mjs
ADDED
|
@@ -0,0 +1,274 @@
|
|
|
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.0 â 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
|
+
clean Clean stale branches, worktrees, locks, and ledgers
|
|
26
|
+
lock <action> Manage mutex locks (acquire | release | status | cleanup)
|
|
27
|
+
doctor Run system diagnostics and stack resolution checks
|
|
28
|
+
init Scaffold .agent/ directory and config.yml
|
|
29
|
+
version Output agentctl version
|
|
30
|
+
|
|
31
|
+
Options:
|
|
32
|
+
--dry-run, -d Simulate action without making API calls or modifying git
|
|
33
|
+
--json, -j Emit machine-readable JSON output
|
|
34
|
+
--help, -h Show command help
|
|
35
|
+
`);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
async function main() {
|
|
39
|
+
if (!command || command === "--help" || command === "-h") {
|
|
40
|
+
printHelp();
|
|
41
|
+
process.exit(0);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if (command === "version" || command === "--version" || command === "-v") {
|
|
45
|
+
console.log("agentctl v0.9.0");
|
|
46
|
+
process.exit(0);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const root = resolveRoot();
|
|
50
|
+
const config = loadConfig(root);
|
|
51
|
+
|
|
52
|
+
switch (command) {
|
|
53
|
+
case "dispatch": {
|
|
54
|
+
const { values } = parseArgs({
|
|
55
|
+
args: args.slice(1),
|
|
56
|
+
options: {
|
|
57
|
+
title: { type: "string", short: "t" },
|
|
58
|
+
prompt: { type: "string", short: "p" },
|
|
59
|
+
"prompt-file": { type: "string", short: "f" },
|
|
60
|
+
"dry-run": { type: "boolean", short: "d" },
|
|
61
|
+
json: { type: "boolean", short: "j" },
|
|
62
|
+
},
|
|
63
|
+
allowPositionals: true,
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
let promptContent = values.prompt || "";
|
|
67
|
+
if (values["prompt-file"] && existsSync(values["prompt-file"])) {
|
|
68
|
+
promptContent = readFileSync(values["prompt-file"], "utf-8");
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
if (!promptContent && args[1] && !args[1].startsWith("-")) {
|
|
72
|
+
promptContent = args.slice(1).join(" ");
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
if (!promptContent) {
|
|
76
|
+
console.error("Error: --prompt or --prompt-file is required.");
|
|
77
|
+
process.exit(1);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const task = {
|
|
81
|
+
title: values.title || "CLI Dispatch Task",
|
|
82
|
+
prompt: promptContent,
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
try {
|
|
86
|
+
const session = await dispatch(task, { root, config, dryRun: values["dry-run"] });
|
|
87
|
+
if (values.json) {
|
|
88
|
+
console.log(JSON.stringify({ ok: true, session }, null, 2));
|
|
89
|
+
} else {
|
|
90
|
+
console.log(`\nâ
Task Dispatched Successfully!`);
|
|
91
|
+
console.log(` Session ID : ${session.id}`);
|
|
92
|
+
console.log(` Session URL : ${session.url || "N/A"}`);
|
|
93
|
+
}
|
|
94
|
+
process.exit(0);
|
|
95
|
+
} catch (err) {
|
|
96
|
+
if (values.json) {
|
|
97
|
+
console.log(JSON.stringify({ ok: false, error: err.message, code: err.code || 1 }, null, 2));
|
|
98
|
+
} else {
|
|
99
|
+
console.error(`â Dispatch Failed: ${err.message}`);
|
|
100
|
+
}
|
|
101
|
+
process.exit(err.code || 1);
|
|
102
|
+
}
|
|
103
|
+
break;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
case "gate":
|
|
107
|
+
case "audit": {
|
|
108
|
+
const { values } = parseArgs({
|
|
109
|
+
args: args.slice(1),
|
|
110
|
+
options: {
|
|
111
|
+
base: { type: "string", short: "b", default: config.baseBranch || "main" },
|
|
112
|
+
fix: { type: "boolean" },
|
|
113
|
+
"allow-protected": { type: "boolean" },
|
|
114
|
+
json: { type: "boolean", short: "j" },
|
|
115
|
+
},
|
|
116
|
+
allowPositionals: true,
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
const res = await gate({
|
|
120
|
+
root,
|
|
121
|
+
config,
|
|
122
|
+
base: values.base,
|
|
123
|
+
fix: values.fix,
|
|
124
|
+
allowProtected: values["allow-protected"],
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
if (values.json) {
|
|
128
|
+
console.log(JSON.stringify(res, null, 2));
|
|
129
|
+
} else {
|
|
130
|
+
console.log(`\nđĄī¸ agentctl Safety Gate Audit Results (Base: ${values.base})`);
|
|
131
|
+
console.log(`-----------------------------------------------------`);
|
|
132
|
+
for (const p of res.phases) {
|
|
133
|
+
const status = p.ok ? "â
PASS" : "â FAIL";
|
|
134
|
+
console.log(` Phase [${p.phase.toUpperCase()}] : ${status}`);
|
|
135
|
+
if (p.violations) {
|
|
136
|
+
p.violations.forEach((v) => console.log(` - Violation: ${v.file} (Rule: ${v.rule})`));
|
|
137
|
+
}
|
|
138
|
+
if (p.findings) {
|
|
139
|
+
p.findings.forEach((f) => console.log(` - Finding: ${f.id} at line ${f.line}`));
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
console.log(`-----------------------------------------------------`);
|
|
143
|
+
console.log(`Overall Result: ${res.ok ? "APPROVED (Exit 0)" : `REJECTED (Exit ${res.code})`}\n`);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
process.exit(res.code);
|
|
147
|
+
break;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
case "queue": {
|
|
151
|
+
const queueDir = getQueueDir(root);
|
|
152
|
+
const files = readdirSync(queueDir).filter((f) => f.endsWith(".md"));
|
|
153
|
+
console.log(` Found ${files.length} queued task(s) in .agent/queue/`);
|
|
154
|
+
if (files.length > 0) {
|
|
155
|
+
const tasks = files.map((f) => ({
|
|
156
|
+
id: f,
|
|
157
|
+
title: f.replace(/\.md$/, ""),
|
|
158
|
+
prompt: readFileSync(join(queueDir, f), "utf-8"),
|
|
159
|
+
}));
|
|
160
|
+
const results = await run(tasks, { root, config });
|
|
161
|
+
console.log(`\nProcessed ${results.length} tasks.`);
|
|
162
|
+
}
|
|
163
|
+
process.exit(0);
|
|
164
|
+
break;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
case "swarm": {
|
|
168
|
+
console.log("đ Running Swarm Orchestrator...");
|
|
169
|
+
const queueDir = getQueueDir(root);
|
|
170
|
+
const files = readdirSync(queueDir).filter((f) => f.endsWith(".md"));
|
|
171
|
+
if (files.length === 0) {
|
|
172
|
+
console.log("No pending tasks found for swarm.");
|
|
173
|
+
process.exit(0);
|
|
174
|
+
}
|
|
175
|
+
const tasks = files.map((f) => ({
|
|
176
|
+
id: f,
|
|
177
|
+
title: f.replace(/\.md$/, ""),
|
|
178
|
+
prompt: readFileSync(join(queueDir, f), "utf-8"),
|
|
179
|
+
}));
|
|
180
|
+
const results = await run(tasks, { root, config, concurrency: config.limits.concurrency || 3 });
|
|
181
|
+
console.log(`Swarm completed ${results.length} tasks.`);
|
|
182
|
+
process.exit(0);
|
|
183
|
+
break;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
case "clean": {
|
|
187
|
+
console.log("đ§š Running System Cleanup...");
|
|
188
|
+
worktreePrune(root);
|
|
189
|
+
console.log(" â
Pruned stale Git worktrees.");
|
|
190
|
+
process.exit(0);
|
|
191
|
+
break;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
case "lock": {
|
|
195
|
+
const action = args[1];
|
|
196
|
+
if (action === "acquire") {
|
|
197
|
+
const agent = args[2] || "agent";
|
|
198
|
+
const taskId = args[3] || "task-1";
|
|
199
|
+
const filePaths = args.slice(4);
|
|
200
|
+
const res = acquireLock(agent, taskId, filePaths, root);
|
|
201
|
+
if (res.ok) {
|
|
202
|
+
console.log(`â
Acquired lock for ${taskId}`);
|
|
203
|
+
} else {
|
|
204
|
+
console.log(`â Lock conflict detected: held by ${res.holder}`);
|
|
205
|
+
process.exit(1);
|
|
206
|
+
}
|
|
207
|
+
} else if (action === "release") {
|
|
208
|
+
const taskId = args[2] || "task-1";
|
|
209
|
+
const ok = releaseLock(taskId, root);
|
|
210
|
+
if (ok) {
|
|
211
|
+
console.log(`â
Released lock for ${taskId}`);
|
|
212
|
+
} else {
|
|
213
|
+
console.log(`â Lock for ${taskId} not found or release failed`);
|
|
214
|
+
process.exit(1);
|
|
215
|
+
}
|
|
216
|
+
} else {
|
|
217
|
+
const locks = lockStatus(root);
|
|
218
|
+
console.log(`Active Locks (${locks.length}):`, locks);
|
|
219
|
+
}
|
|
220
|
+
process.exit(0);
|
|
221
|
+
break;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
case "doctor": {
|
|
225
|
+
console.log(`\nđ agentctl System Diagnostics (v0.9.0)`);
|
|
226
|
+
console.log(`--------------------------------------------------`);
|
|
227
|
+
console.log(` Project Root : ${root}`);
|
|
228
|
+
console.log(` Config File : ${config._file || "None (Using defaults)"}`);
|
|
229
|
+
console.log(` Detected Stack : ${detectStack(root).stack}`);
|
|
230
|
+
console.log(` Test Command : ${config.verify.test || "(None)"}`);
|
|
231
|
+
console.log(` Build Command : ${config.verify.build || "(None)"}`);
|
|
232
|
+
const budget = checkDailyBudget(root, config.limits.dailyTasks);
|
|
233
|
+
console.log(` Daily Budget : ${budget.used} / ${budget.budget} sessions used`);
|
|
234
|
+
console.log(`--------------------------------------------------\n`);
|
|
235
|
+
process.exit(0);
|
|
236
|
+
break;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
case "init": {
|
|
240
|
+
const agentDir = join(root, ".agent");
|
|
241
|
+
ensureDir(agentDir);
|
|
242
|
+
const configPath = join(agentDir, "config.yml");
|
|
243
|
+
if (!existsSync(configPath)) {
|
|
244
|
+
writeFileSync(
|
|
245
|
+
configPath,
|
|
246
|
+
`version: 1
|
|
247
|
+
provider: jules
|
|
248
|
+
limits:
|
|
249
|
+
diff_kb: 75
|
|
250
|
+
daily_tasks: 300
|
|
251
|
+
branch_prefix: agent/
|
|
252
|
+
base_branch: main
|
|
253
|
+
`,
|
|
254
|
+
"utf-8"
|
|
255
|
+
);
|
|
256
|
+
console.log(`â
Created .agent/config.yml`);
|
|
257
|
+
} else {
|
|
258
|
+
console.log(`âšī¸ .agent/config.yml already exists.`);
|
|
259
|
+
}
|
|
260
|
+
process.exit(0);
|
|
261
|
+
break;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
default:
|
|
265
|
+
console.error(`Unknown command: ${command}`);
|
|
266
|
+
printHelp();
|
|
267
|
+
process.exit(1);
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
main().catch((err) => {
|
|
272
|
+
console.error(`[FATAL ERROR] ${err.message}`);
|
|
273
|
+
process.exit(err.code || 1);
|
|
274
|
+
});
|
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";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "jules-orchestrator-kit",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.3",
|
|
4
4
|
"description": "Orchestration kit for running Google Jules autonomous agents.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -12,8 +12,9 @@
|
|
|
12
12
|
"homepage": "https://github.com/FullThrottle83/jules-orchestrator-kit#readme",
|
|
13
13
|
"type": "module",
|
|
14
14
|
"bin": {
|
|
15
|
+
"agentctl": "bin/agentctl.mjs",
|
|
15
16
|
"jules-init": "bin/init.js",
|
|
16
|
-
"jules-orchestrator-kit": "bin/
|
|
17
|
+
"jules-orchestrator-kit": "bin/agentctl.mjs"
|
|
17
18
|
},
|
|
18
19
|
"main": "index.mjs",
|
|
19
20
|
"exports": {
|
|
@@ -21,10 +22,12 @@
|
|
|
21
22
|
},
|
|
22
23
|
"files": [
|
|
23
24
|
"index.mjs",
|
|
25
|
+
"src/",
|
|
24
26
|
"bin/",
|
|
25
27
|
"scripts/",
|
|
26
28
|
".agent/jules.yml",
|
|
27
29
|
".agent/rules/",
|
|
30
|
+
".agent/prompts/",
|
|
28
31
|
".agent/workflows/",
|
|
29
32
|
".agent/jules-queue/README.md",
|
|
30
33
|
".github/workflows/jules-audit.yml",
|
|
@@ -47,6 +50,12 @@
|
|
|
47
50
|
"jules:merge-swarm": "node scripts/jules-merge-swarm.mjs",
|
|
48
51
|
"jules:patch": "node scripts/jules-patch.mjs",
|
|
49
52
|
"jules:nightly": "node scripts/jules-nightly.mjs",
|
|
53
|
+
"jules:webhook": "node scripts/jules-webhook-receiver.mjs",
|
|
54
|
+
"jules:validate-envelope": "node scripts/validate-envelope.mjs",
|
|
55
|
+
"jules:check-stale-base": "node scripts/stale-base-check.mjs",
|
|
56
|
+
"jules:check-asset-integrity": "node scripts/asset-integrity-check.mjs",
|
|
57
|
+
"jules:risk-tier": "node scripts/risk-tier.mjs",
|
|
58
|
+
"jules:rules-lint": "node scripts/rules-lint.mjs",
|
|
50
59
|
"lint": "eslint ."
|
|
51
60
|
},
|
|
52
61
|
"engines": {
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { checkAssetIntegrity } from "../src/asset_integrity.mjs";
|
|
4
|
+
import { existsSync } from "node:fs";
|
|
5
|
+
import { join } from "node:path";
|
|
6
|
+
|
|
7
|
+
const root = process.cwd();
|
|
8
|
+
const dirsToScan = ["public", "src/assets", "assets", "static"].map((d) => join(root, d)).filter(existsSync);
|
|
9
|
+
|
|
10
|
+
if (dirsToScan.length === 0) {
|
|
11
|
+
console.log("[asset-integrity] No asset directories (public/, src/assets/) found. Passing.");
|
|
12
|
+
process.exit(0);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
let totalChecked = 0;
|
|
16
|
+
let allCorrupted = [];
|
|
17
|
+
|
|
18
|
+
for (const dir of dirsToScan) {
|
|
19
|
+
const res = checkAssetIntegrity(dir);
|
|
20
|
+
totalChecked += res.checkedCount;
|
|
21
|
+
allCorrupted.push(...res.corruptedFiles);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
console.log(`[asset-integrity] Checked ${totalChecked} binary/font assets across ${dirsToScan.length} directories.`);
|
|
25
|
+
|
|
26
|
+
if (allCorrupted.length > 0) {
|
|
27
|
+
console.error("â ASSET INTEGRITY FAILURE: Found corrupted assets (HTML/text saved as binary):");
|
|
28
|
+
for (const item of allCorrupted) {
|
|
29
|
+
console.error(` - ${item.path}: ${item.reason}`);
|
|
30
|
+
}
|
|
31
|
+
process.exit(1);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
console.log("â
Asset integrity check passed cleanly.");
|
|
35
|
+
process.exit(0);
|