jules-orchestrator-kit 0.8.0 → 0.8.5
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/rules/dynamic-guardrails.json +0 -4
- package/.env.example +3 -0
- package/.github/workflows/jules-audit.yml +16 -5
- package/JULES_RULES_TEMPLATE.md +1 -1
- package/README.md +95 -14
- package/bin/init.js +4 -1
- package/index.mjs +5 -4
- package/package.json +12 -5
- package/scripts/command-resolver.mjs +17 -17
- package/scripts/jules-cleanup.mjs +15 -25
- package/scripts/jules-create.mjs +10 -5
- package/scripts/jules-dispatch.mjs +163 -63
- package/scripts/jules-merge-swarm.mjs +184 -0
- package/scripts/jules-nightly.mjs +11 -7
- package/scripts/jules-patch.mjs +111 -0
- package/scripts/jules-queue-runner.mjs +39 -15
- package/scripts/jules-scan-todos.mjs +1 -1
- package/scripts/jules-self-audit.mjs +137 -48
- package/scripts/jules-status.mjs +52 -47
- package/scripts/jules-swarm.mjs +138 -39
- package/scripts/lock-manager.mjs +17 -10
- package/scripts/utils.mjs +154 -8
- package/.github/ISSUE_TEMPLATE/bug_report.md +0 -63
- package/.github/ISSUE_TEMPLATE/feature_request.md +0 -34
- package/.github/social-preview.png +0 -0
- package/.github/workflows/agent-scope-guard.yml +0 -57
- package/.github/workflows/jules-nightly.yml +0 -21
- package/.github/workflows/publish.yml +0 -24
|
@@ -1,9 +1,5 @@
|
|
|
1
1
|
{
|
|
2
2
|
"rules": [
|
|
3
|
-
{
|
|
4
|
-
"trigger": "\\.astro",
|
|
5
|
-
"guardrail": "## 🟢 ASTRO GUARDRAILS\n- DO NOT run `biome check --write --unsafe` on `.astro` files (destroys frontmatter).\n- DO NOT import 'sharp' into runtime bundles."
|
|
6
|
-
},
|
|
7
3
|
{
|
|
8
4
|
"trigger": "\\b(db|database|drizzle|sql\\w*|postgres\\w*|sqlite\\w*|mysql\\w*)\\b",
|
|
9
5
|
"guardrail": "## 🗄️ DATABASE GUARDRAILS\n- Always batch multiple database statements.\n- DO NOT write destructive migrations (`DROP TABLE`) without explicit user consent."
|
package/.env.example
CHANGED
|
@@ -27,6 +27,9 @@ JULES_REPO=owner/repo
|
|
|
27
27
|
# Allow modifications to command-defining files (package.json, Cargo.toml, etc.) in PRs (Default: false)
|
|
28
28
|
# JULES_ALLOW_COMMAND_FILE_CHANGES=false
|
|
29
29
|
|
|
30
|
+
# Allow modifications to agent rule files (AGENTS.md, JULES_RULES_TEMPLATE.md, .agent/rules/**) in PRs (Default: false)
|
|
31
|
+
# JULES_ALLOW_AGENT_RULE_CHANGES=false
|
|
32
|
+
|
|
30
33
|
# --- Execution Scope & Git ---
|
|
31
34
|
# Base Branch for PR Audits & Merge-Base Calculations (Default: main)
|
|
32
35
|
BASE_BRANCH=main
|
|
@@ -11,7 +11,7 @@ jobs:
|
|
|
11
11
|
runs-on: ubuntu-latest
|
|
12
12
|
strategy:
|
|
13
13
|
matrix:
|
|
14
|
-
node-version: ['
|
|
14
|
+
node-version: ['22.x', '24.x']
|
|
15
15
|
steps:
|
|
16
16
|
- name: Checkout repository
|
|
17
17
|
uses: actions/checkout@v4
|
|
@@ -23,14 +23,25 @@ jobs:
|
|
|
23
23
|
with:
|
|
24
24
|
node-version: ${{ matrix.node-version }}
|
|
25
25
|
|
|
26
|
-
- name:
|
|
27
|
-
|
|
26
|
+
- name: Cache OODA state & ledgers
|
|
27
|
+
uses: actions/cache@v4
|
|
28
|
+
with:
|
|
29
|
+
path: .agent/state/
|
|
30
|
+
key: ooda-state-${{ runner.os }}-${{ github.run_id }}
|
|
31
|
+
restore-keys: |
|
|
32
|
+
ooda-state-${{ runner.os }}-
|
|
33
|
+
|
|
34
|
+
- name: Install dependencies
|
|
35
|
+
run: npm install
|
|
36
|
+
|
|
37
|
+
- name: Run Linter
|
|
38
|
+
run: npm run lint --if-present
|
|
28
39
|
|
|
29
40
|
- name: Run Unit Tests
|
|
30
|
-
run: npm test
|
|
41
|
+
run: npm test --if-present
|
|
31
42
|
|
|
32
43
|
- name: Run Jules PR Self-Audit Gatekeeper
|
|
33
|
-
if: matrix.node-version == '
|
|
44
|
+
if: matrix.node-version == '22.x' && github.event_name == 'pull_request'
|
|
34
45
|
run: node scripts/jules-self-audit.mjs
|
|
35
46
|
env:
|
|
36
47
|
CI: "true"
|
package/JULES_RULES_TEMPLATE.md
CHANGED
|
@@ -99,7 +99,7 @@ Follow all rules strictly.
|
|
|
99
99
|
TASK: <description>
|
|
100
100
|
|
|
101
101
|
HARD CONSTRAINTS:
|
|
102
|
-
- Do NOT modify package.json, pnpm-lock.yaml, tsconfig.json,
|
|
102
|
+
- Do NOT modify package.json, pnpm-lock.yaml, tsconfig.json, or .github/ files. Enforced in CI by Agent Scope Guard.
|
|
103
103
|
- Diff Payload Governor: Keep total diff payload under 75 KB (`git diff | wc -c`) to prevent API truncation (~80 KB limit).
|
|
104
104
|
- Verify before finishing: Run full type-check, lint, and unit test suites.
|
|
105
105
|
- 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.
|
package/README.md
CHANGED
|
@@ -37,14 +37,89 @@ npm run jules:queue
|
|
|
37
37
|
|
|
38
38
|
## How It Works
|
|
39
39
|
|
|
40
|
-
1. **You Assign Task:** Define what needs fixing or building.
|
|
40
|
+
1. **You Assign Task:** Define what needs fixing or building (supports text and multimodal image mockups).
|
|
41
41
|
2. **Jules Writes Code:** Proposes changes in an isolated Git worktree sandbox.
|
|
42
42
|
3. **Run Tests & Linters:** The Gatekeeper runs your test suite, linters, and type checks.
|
|
43
43
|
4. **Self-Correction:** If anything fails, Jules automatically retries with fixes (OODA loop).
|
|
44
44
|
5. **Safe Delivery:** Once tests pass, the PR is verified and ready for review.
|
|
45
45
|
|
|
46
|
+
```mermaid
|
|
47
|
+
sequenceDiagram
|
|
48
|
+
autonumber
|
|
49
|
+
|
|
50
|
+
box "Client Edge" #F4F4F4
|
|
51
|
+
actor Trigger as Client (CLI / CI / SDK)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
box "Control Plane" #E8F4F8
|
|
55
|
+
participant Orc as Orchestrator Core
|
|
56
|
+
participant Gate as Self-Audit Gatekeeper
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
box "Execution Sandbox" #F8E8E8
|
|
60
|
+
participant API as Google Jules API
|
|
61
|
+
participant Git as Git Worktree Sandbox
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
Trigger->>+Orc: Dispatch Task Payload
|
|
65
|
+
|
|
66
|
+
note over Orc,Git: Phase 1: Security Redaction & Provisioning
|
|
67
|
+
Orc->>Orc: Redact Secrets (Entropy > 3.6) & Enforce Dynamic Guardrails
|
|
68
|
+
Orc->>+Git: Provision Isolation Sandbox (git worktree)
|
|
69
|
+
Git-->>-Orc: Sandbox Ready
|
|
70
|
+
|
|
71
|
+
loop OODA Repair Cycle (Max 3 Retries)
|
|
72
|
+
note over Orc,Git: Phase 2: Agent Execution & Dispatch
|
|
73
|
+
Orc->>+API: Dispatch Task + <MCP_DIRECTIVE> & Target Scope
|
|
74
|
+
API->>+Git: Apply Proposed Code Changes
|
|
75
|
+
Git-->>-API: Changes Written
|
|
76
|
+
API-->>-Orc: Execution Complete
|
|
77
|
+
|
|
78
|
+
note over Orc,Gate: Phase 3: Tiered Verification & Gatekeeping
|
|
79
|
+
Orc->>+Gate: Trigger Self-Audit (trusted origin/main rules)
|
|
80
|
+
|
|
81
|
+
Gate->>+Git: Scope Audit (`git diff -z --name-only` vs forbidden_paths)
|
|
82
|
+
Git-->>-Gate: Diff Stats & File List
|
|
83
|
+
|
|
84
|
+
alt Scope Breach (Forbidden Path OR Diff Payload > 75 KB)
|
|
85
|
+
Gate-->>Orc: Security / Scope Violation Detected
|
|
86
|
+
Orc->>Orc: Record Telemetry (metrics.jsonl)
|
|
87
|
+
Orc-->>Trigger: Abort Execution (Exit 3)
|
|
88
|
+
break Fatal Security Error
|
|
89
|
+
Orc->>Git: Teardown Worktree Sandbox
|
|
90
|
+
end
|
|
91
|
+
else Scope Verification Passed
|
|
92
|
+
Gate->>+Git: Run Dynamic Verification (`testCmd` & `buildCmd`)
|
|
93
|
+
Git-->>-Gate: stdout / stderr verification results
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
alt 100% Verification Suite Passed
|
|
97
|
+
Gate-->>-Orc: Verification Success
|
|
98
|
+
Orc->>+Git: Commit & Push to Remote Branch / PR
|
|
99
|
+
Git-->>-Orc: PR Ready
|
|
100
|
+
Orc->>Orc: Record Telemetry (metrics.jsonl)
|
|
101
|
+
Orc-->>Trigger: Dispatch Succeeded (Exit 0)
|
|
102
|
+
break Task Completed
|
|
103
|
+
Orc->>Git: Teardown Worktree Sandbox
|
|
104
|
+
end
|
|
105
|
+
else Verification Failed
|
|
106
|
+
Gate-->>Orc: Verification Failed (Stderr Trace output)
|
|
107
|
+
Orc->>Orc: Record Failure Telemetry
|
|
108
|
+
|
|
109
|
+
alt Retries Remaining (< 3)
|
|
110
|
+
Orc->>Orc: Construct Repair Prompt with Stderr Trace
|
|
111
|
+
else Max Retries Exceeded (3/3)
|
|
112
|
+
Orc-->>-Trigger: Abort & Log Diagnostic Feedback (Exit 4)
|
|
113
|
+
Orc->>Git: Teardown Worktree Sandbox
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
```
|
|
118
|
+
|
|
46
119
|
> 💡 **Core Architectural Invariants**:
|
|
47
120
|
> - **Zero-Trust Base-Branch Security**: Security rules (`forbidden_paths`) are fetched exclusively from `origin/main` (never untrusted PR branches).
|
|
121
|
+
> - **Automatic PII & Secret Redaction**: Outbound task prompts are automatically sanitized to redact API secrets and mask sensitive PII (emails, IPs, phone numbers).
|
|
122
|
+
> - **Ledger Hash-Chain Integrity**: Hashing over JSONL event streams detects unauthorized log tampering or record deletions.
|
|
48
123
|
> - **Dynamic Command Resolution (`command-resolver.mjs`)**: Auto-detects workspace boundaries (Turborepo, pnpm, Nx, Cargo, pytest, npm).
|
|
49
124
|
>
|
|
50
125
|
> 🔍 For a deep dive into the execution protocol, see the [Architecture & Pipeline Flow](docs/architecture.md).
|
|
@@ -96,13 +171,16 @@ If no API key is configured, the kit seamlessly falls back to invoking your loca
|
|
|
96
171
|
**3. Programmatic Node.js SDK (`index.mjs`)**
|
|
97
172
|
Downstream Node.js tools, MCP servers, and LLM orchestrators can import kit functions directly:
|
|
98
173
|
```js
|
|
99
|
-
import { runSelfAudit,
|
|
174
|
+
import { runSelfAudit, dispatchTask, anonymizePii, verifyLedgerIntegrity, validateJulesConfig } from "jules-orchestrator-kit";
|
|
175
|
+
|
|
176
|
+
// Anonymize sensitive PII (emails, IPs, phone numbers) before sending prompts
|
|
177
|
+
const cleanPrompt = anonymizePii("Contact support at john@example.com");
|
|
100
178
|
|
|
101
|
-
//
|
|
102
|
-
await
|
|
179
|
+
// Programmatically dispatch tasks
|
|
180
|
+
await dispatchTask({ title: "Refactor Auth", prompt: cleanPrompt });
|
|
103
181
|
|
|
104
|
-
//
|
|
105
|
-
const
|
|
182
|
+
// Verify cryptographic hash chain of event ledgers
|
|
183
|
+
const integrity = verifyLedgerIntegrity(".agent/state/sessions/2026-08-03.jsonl");
|
|
106
184
|
```
|
|
107
185
|
|
|
108
186
|
---
|
|
@@ -154,6 +232,7 @@ All commands are registered in `package.json` and can be run via `npm run <comma
|
|
|
154
232
|
| `npm run jules:cleanup` | Audits and closes merged or stale REST sessions |
|
|
155
233
|
| `npm run jules:scan` | Scans the codebase for TODO/FIXME comments and generates a suggested tasks file |
|
|
156
234
|
| `npm run jules:swarm` | Launches a multi-agent swarm in parallel across isolated worktrees |
|
|
235
|
+
| `npm run jules:merge-swarm` | Autonomous PR merge engine: squash-merges passing, disjoint Jules PRs |
|
|
157
236
|
| `npm run jules:nightly` | Nightly maintenance job (usually triggered in CI) |
|
|
158
237
|
|
|
159
238
|
### Environment Variables
|
|
@@ -167,7 +246,9 @@ All commands are registered in `package.json` and can be run via `npm run <comma
|
|
|
167
246
|
| `JULES_REPOLESS` | Set to `true` or `1` to run in repoless/serverless mode |
|
|
168
247
|
| `JULES_DRY_RUN` | Set to `true` or `1` to simulate dispatching without making API calls |
|
|
169
248
|
| `JULES_DAILY_BUDGET` | Daily max session budget for autonomous dispatches (Default: `300`) |
|
|
170
|
-
| `
|
|
249
|
+
| `JULES_MAX_DIFF_KB` | Maximum git diff payload size in KB before aborting with Exit Code 5 (Default: `50`) |
|
|
250
|
+
| `JULES_ALLOW_COMMAND_FILE_CHANGES` | Set to `true` to allow PR changes to command/config files like `package.json`, `tsconfig.json`, `vite.config.ts` (Default: `false`) |
|
|
251
|
+
| `JULES_ALLOW_AGENT_RULE_CHANGES` | Set to `true` to allow PR changes to agent rule files like `AGENTS.md`, `JULES_RULES_TEMPLATE.md` (Default: `false`) |
|
|
171
252
|
| `BASE_BRANCH` | Base branch for PR Audits & Merge-Base calculations (Default: `main`) |
|
|
172
253
|
| `GITHUB_HEAD_REF` | PR Head Branch (Used dynamically by CI during OODA repair) |
|
|
173
254
|
| `JULES_PROJECT_ROOT` | Root directory of the project (Auto-assigned during swarm executions) |
|
|
@@ -192,19 +273,19 @@ The Gatekeeper (`jules-self-audit.mjs` and related scripts) uses standard exit c
|
|
|
192
273
|
| Code | Meaning | Action Taken |
|
|
193
274
|
| ---- | ------- | ------------ |
|
|
194
275
|
| `0` | **Success** | All tests and security checks passed. |
|
|
195
|
-
| `1` | **
|
|
196
|
-
| `2` | **
|
|
197
|
-
| `3` | **Security Violation** | Modified file breached `forbidden_paths` or changed command-defining files (`package.json`, `Cargo.toml`). Fails closed immediately. |
|
|
198
|
-
| `4` | **Verification Exhausted** | Tests failed and the OODA Auto-Repair loop either exhausted its max retries or is disabled. |
|
|
199
|
-
| `5` | **Diff Payload
|
|
200
|
-
| `6` | **Secret Leak Prevented** |
|
|
276
|
+
| `1` | **Pre-Dispatch / Arg Error** | Missing dependencies, prompt > 50 KB, syntax error, or pre-dispatch failure. |
|
|
277
|
+
| `2` | **API / Network / Quota Error** | REST API HTTP 429 rate limit, HTTP 400 `FAILED_PRECONDITION` quota (~30 active limit), or connection timeout. |
|
|
278
|
+
| `3` | **Security / Scope Violation** | Modified file breached `forbidden_paths` or changed command-defining files (`package.json`, `Cargo.toml`). Fails closed immediately. |
|
|
279
|
+
| `4` | **Verification Exhausted** | Tests failed and the OODA Auto-Repair loop either exhausted its max retries (3) or is disabled. |
|
|
280
|
+
| `5` | **Diff Payload Limit** | Diff payload size exceeded payload governor budget (`JULES_MAX_DIFF_KB`, default 50 KB). Split task. |
|
|
281
|
+
| `6` | **Secret Leak Prevented** | High-confidence secret or private key pattern detected in diff. Aborted immediately. |
|
|
201
282
|
| `7` | **Budget Exhausted** | Daily session budget limit reached or budget state locked. |
|
|
202
283
|
|
|
203
284
|
---
|
|
204
285
|
|
|
205
286
|
## Contributing
|
|
206
287
|
We welcome contributions! Please follow these core principles:
|
|
207
|
-
1. **Zero
|
|
288
|
+
1. **Zero Runtime Dependencies**: Use ONLY native Node.js built-in modules (`node:fs`, `node:path`, `node:child_process`, `node:crypto`, `node:util`).
|
|
208
289
|
2. **Verification Suite**: Ensure 100% of unit tests pass cleanly (`npm test`).
|
|
209
290
|
3. **Conventional Commits**: Use standardized prefixes (`feat:`, `fix:`, `docs:`, `test:`, `chore:`).
|
|
210
291
|
4. **Cross-Platform Compatibility**: Normalize Windows backslashes (`\`) to POSIX slashes (`/`) for glob patterns and paths.
|
package/bin/init.js
CHANGED
|
@@ -157,7 +157,7 @@ if (!fs.existsSync(yamlConfigPath) || isForce) {
|
|
|
157
157
|
version: 2
|
|
158
158
|
test_cmd: "${detected.testCmd || "npm test"}"
|
|
159
159
|
build_cmd: "${detected.buildCmd || "npm run build"}"
|
|
160
|
-
forbidden_paths: [".github/**", "
|
|
160
|
+
forbidden_paths: [".github/**", "**/.env*", "**/*.pem", "**/lock-manager*"]
|
|
161
161
|
`;
|
|
162
162
|
fs.writeFileSync(yamlConfigPath, yamlContent, "utf-8");
|
|
163
163
|
console.log("✅ Created: .agent/jules.yml");
|
|
@@ -265,6 +265,9 @@ const requiredGitignoreEntries = [
|
|
|
265
265
|
".env",
|
|
266
266
|
".agent/history/",
|
|
267
267
|
".agent/state/",
|
|
268
|
+
".agent/jules-queue/.state/",
|
|
269
|
+
".agent/jules-queue/failed/",
|
|
270
|
+
".agent/jules-queue/.processing/",
|
|
268
271
|
".agent/jules-queue/*.md",
|
|
269
272
|
"!.agent/jules-queue/README.md"
|
|
270
273
|
];
|
package/index.mjs
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* jules-orchestrator-kit Node.js SDK
|
|
3
3
|
* Primary entrypoint for programmatically orchestrating Google Jules workflows.
|
|
4
|
-
* Zero
|
|
4
|
+
* Zero runtime dependencies.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
export { resolveProjectCommands, resolveWorkspaceExecutionBoundary } from "./scripts/command-resolver.mjs";
|
|
8
|
-
export { runSelfAudit, runPreflightSandbox, loadForbiddenPatterns, loadAllowedPatterns, matchGlob } from "./scripts/jules-self-audit.mjs";
|
|
8
|
+
export { runSelfAudit, runPreflightSandbox, loadForbiddenPatterns, loadAllowedPatterns, matchGlob, validateJulesConfig } from "./scripts/jules-self-audit.mjs";
|
|
9
9
|
export { scanCodebaseForTodos, runScanner } from "./scripts/jules-scan-todos.mjs";
|
|
10
|
-
export { log, logToHistory, ensureDir, resolveMarkdownConflict, redactSecrets } from "./scripts/utils.mjs";
|
|
11
|
-
export { getDynamicGuardrails } from "./scripts/jules-dispatch.mjs";
|
|
10
|
+
export { log, logToHistory, ensureDir, resolveMarkdownConflict, redactSecrets, anonymizePii, verifyLedgerIntegrity, loadEnv } from "./scripts/utils.mjs";
|
|
11
|
+
export { getDynamicGuardrails, dispatchTask } from "./scripts/jules-dispatch.mjs";
|
|
12
|
+
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.8.
|
|
3
|
+
"version": "0.8.5",
|
|
4
4
|
"description": "Orchestration kit for running Google Jules autonomous agents.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
".agent/rules/",
|
|
28
28
|
".agent/workflows/",
|
|
29
29
|
".agent/jules-queue/README.md",
|
|
30
|
-
".github/",
|
|
30
|
+
".github/workflows/jules-audit.yml",
|
|
31
31
|
".env.example",
|
|
32
32
|
"JULES_RULES_TEMPLATE.md",
|
|
33
33
|
"README.md",
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
],
|
|
36
36
|
"scripts": {
|
|
37
37
|
"init": "node bin/init.js",
|
|
38
|
-
"test": "node --test test
|
|
38
|
+
"test": "node --test test/*.test.mjs",
|
|
39
39
|
"jules:dispatch": "node scripts/jules-dispatch.mjs",
|
|
40
40
|
"jules:queue": "node scripts/jules-queue-runner.mjs",
|
|
41
41
|
"jules:create": "node scripts/jules-create.mjs",
|
|
@@ -44,7 +44,10 @@
|
|
|
44
44
|
"jules:cleanup": "node scripts/jules-cleanup.mjs",
|
|
45
45
|
"jules:scan": "node scripts/jules-scan-todos.mjs",
|
|
46
46
|
"jules:swarm": "node scripts/jules-swarm.mjs",
|
|
47
|
-
"jules:
|
|
47
|
+
"jules:merge-swarm": "node scripts/jules-merge-swarm.mjs",
|
|
48
|
+
"jules:patch": "node scripts/jules-patch.mjs",
|
|
49
|
+
"jules:nightly": "node scripts/jules-nightly.mjs",
|
|
50
|
+
"lint": "eslint ."
|
|
48
51
|
},
|
|
49
52
|
"engines": {
|
|
50
53
|
"node": ">=18.0.0"
|
|
@@ -58,5 +61,9 @@
|
|
|
58
61
|
"automation"
|
|
59
62
|
],
|
|
60
63
|
"author": "FullThrottle83",
|
|
61
|
-
"license": "MIT"
|
|
64
|
+
"license": "MIT",
|
|
65
|
+
"devDependencies": {
|
|
66
|
+
"eslint": "^9.39.5",
|
|
67
|
+
"globals": "^17.8.0"
|
|
68
|
+
}
|
|
62
69
|
}
|
|
@@ -1,6 +1,23 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
|
|
4
|
+
export function detectPackageManager(root = process.cwd(), pkg = {}) {
|
|
5
|
+
if (fs.existsSync(path.join(root, "pnpm-lock.yaml"))) return "pnpm";
|
|
6
|
+
if (fs.existsSync(path.join(root, "yarn.lock"))) return "yarn";
|
|
7
|
+
if (fs.existsSync(path.join(root, "bun.lockb"))) return "bun";
|
|
8
|
+
if (fs.existsSync(path.join(root, "package-lock.json"))) return "npm";
|
|
9
|
+
|
|
10
|
+
const pm = pkg.packageManager;
|
|
11
|
+
if (typeof pm === "string") {
|
|
12
|
+
if (pm.startsWith("pnpm")) return "pnpm";
|
|
13
|
+
if (pm.startsWith("yarn")) return "yarn";
|
|
14
|
+
if (pm.startsWith("bun")) return "bun";
|
|
15
|
+
if (pm.startsWith("npm")) return "npm";
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
return "npm";
|
|
19
|
+
}
|
|
20
|
+
|
|
4
21
|
/**
|
|
5
22
|
* Dynamic Framework-Agnostic Command Resolver
|
|
6
23
|
* Sniffs project manifests to return proper build & test verification commands.
|
|
@@ -44,23 +61,6 @@ export function resolveProjectCommands(projectRoot = process.cwd()) {
|
|
|
44
61
|
}
|
|
45
62
|
}
|
|
46
63
|
|
|
47
|
-
function detectPackageManager(root, pkg = {}) {
|
|
48
|
-
if (fs.existsSync(path.join(root, "pnpm-lock.yaml"))) return "pnpm";
|
|
49
|
-
if (fs.existsSync(path.join(root, "yarn.lock"))) return "yarn";
|
|
50
|
-
if (fs.existsSync(path.join(root, "bun.lockb"))) return "bun";
|
|
51
|
-
if (fs.existsSync(path.join(root, "package-lock.json"))) return "npm";
|
|
52
|
-
|
|
53
|
-
const pm = pkg.packageManager;
|
|
54
|
-
if (typeof pm === "string") {
|
|
55
|
-
if (pm.startsWith("pnpm")) return "pnpm";
|
|
56
|
-
if (pm.startsWith("yarn")) return "yarn";
|
|
57
|
-
if (pm.startsWith("bun")) return "bun";
|
|
58
|
-
if (pm.startsWith("npm")) return "npm";
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
return "npm";
|
|
62
|
-
}
|
|
63
|
-
|
|
64
64
|
// 2. Dynamic Detector Strategy List
|
|
65
65
|
const detectors = [
|
|
66
66
|
{
|
|
@@ -3,36 +3,19 @@
|
|
|
3
3
|
* Jules Session Cleanup & PR Audit Utility
|
|
4
4
|
* Cross-references active/completed Jules REST API sessions with GitHub PR merge status
|
|
5
5
|
* to report and safely close merged or stale sessions.
|
|
6
|
-
* Zero
|
|
6
|
+
* Zero runtime dependencies.
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
import { execFileSync } from "node:child_process";
|
|
10
|
-
import fs from "node:fs";
|
|
11
10
|
import path from "node:path";
|
|
12
|
-
import {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
const trimmed = line.trim();
|
|
20
|
-
if (!trimmed || trimmed.startsWith("#")) continue;
|
|
21
|
-
const eqIdx = trimmed.indexOf("=");
|
|
22
|
-
if (eqIdx > 0) {
|
|
23
|
-
const key = trimmed.slice(0, eqIdx).trim().replace(/^export\s+/, "");
|
|
24
|
-
let val = trimmed.slice(eqIdx + 1).trim();
|
|
25
|
-
if ((val.startsWith('"') && val.endsWith('"')) || (val.startsWith("'") && val.endsWith("'"))) {
|
|
26
|
-
val = val.slice(1, -1);
|
|
27
|
-
}
|
|
28
|
-
if (!process.env[key]) {
|
|
29
|
-
process.env[key] = val;
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
}
|
|
11
|
+
import { fileURLToPath } from "node:url";
|
|
12
|
+
import { log, loadEnv } from "./utils.mjs";
|
|
13
|
+
|
|
14
|
+
const isMainModule = process.argv[1] && path.resolve(process.argv[1]) === path.resolve(fileURLToPath(import.meta.url));
|
|
15
|
+
|
|
16
|
+
if (isMainModule) {
|
|
17
|
+
loadEnv();
|
|
34
18
|
}
|
|
35
|
-
loadEnv();
|
|
36
19
|
|
|
37
20
|
const args = process.argv.slice(2);
|
|
38
21
|
const isDryRun = args.includes("--dry-run") || process.env.JULES_DRY_RUN === "true" || process.env.JULES_DRY_RUN === "1";
|
|
@@ -198,3 +181,10 @@ export async function runCleanup() {
|
|
|
198
181
|
}
|
|
199
182
|
}
|
|
200
183
|
}
|
|
184
|
+
|
|
185
|
+
if (isMainModule) {
|
|
186
|
+
runCleanup().catch((err) => {
|
|
187
|
+
log.error(`Cleanup audit failed: ${err.message}`);
|
|
188
|
+
process.exit(1);
|
|
189
|
+
});
|
|
190
|
+
}
|
package/scripts/jules-create.mjs
CHANGED
|
@@ -6,14 +6,18 @@
|
|
|
6
6
|
|
|
7
7
|
import fs from "node:fs";
|
|
8
8
|
import path from "node:path";
|
|
9
|
+
import { fileURLToPath } from "node:url";
|
|
9
10
|
import { log, ensureDir } from "./utils.mjs";
|
|
10
11
|
|
|
11
|
-
const
|
|
12
|
+
const isMainModule = process.argv[1] && path.resolve(process.argv[1]) === path.resolve(fileURLToPath(import.meta.url));
|
|
12
13
|
|
|
13
|
-
if (
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
14
|
+
if (isMainModule) {
|
|
15
|
+
const taskTitle = process.argv[2];
|
|
16
|
+
|
|
17
|
+
if (!taskTitle) {
|
|
18
|
+
log.error("Usage: npm run jules:create \"Task Title\"");
|
|
19
|
+
process.exit(1);
|
|
20
|
+
}
|
|
17
21
|
|
|
18
22
|
const queueDir = path.resolve(process.cwd(), ".agent/jules-queue");
|
|
19
23
|
ensureDir(queueDir);
|
|
@@ -65,3 +69,4 @@ try {
|
|
|
65
69
|
log.error(`Failed to create task file: ${err.message}`);
|
|
66
70
|
process.exit(1);
|
|
67
71
|
}
|
|
72
|
+
}
|