jules-orchestrator-kit 0.32.6 → 0.32.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -120,7 +120,7 @@ Autonomous coding agents can write software at 100× human speed—but unconstra
120
120
 
121
121
  * **🚀 Zero-Test Bootstrapping (`agentctl bootstrap`):** Synthesizes deterministic syntax-check and smoke-test verification oracles for untested legacy repositories so agents always operate against a falsifiable feedback loop.
122
122
 
123
- * **📈 Proven Scale & Reliability:** Empirically tested with **458 unit tests across 66 suites passing in < 10.0s**, supporting 300+ daily agent sessions per repository. An adversarial red-team suite (`test/adversarial-claims.test.mjs`) continuously attempts to falsify the safety guarantees documented above — including cross-platform probes for the case-insensitive filesystems on macOS and Windows — and a documentation-sync gate (`scripts/doc-sync-check.mjs`) blocks any release whose docs have drifted from the code.
123
+ * **📈 Proven Scale & Reliability:** Empirically tested with **461 unit tests across 66 suites passing in < 10.0s**, supporting 300+ daily agent sessions per repository. An adversarial red-team suite (`test/adversarial-claims.test.mjs`) continuously attempts to falsify the safety guarantees documented above — including cross-platform probes for the case-insensitive filesystems on macOS and Windows — and a documentation-sync gate (`scripts/doc-sync-check.mjs`) blocks any release whose docs have drifted from the code.
124
124
 
125
125
  <br/>
126
126
 
package/bin/agentctl.mjs CHANGED
@@ -12,11 +12,11 @@ import { reapOrphanedIntents, reapStaleMutexDirs } from "../src/journal.mjs";
12
12
  const args = process.argv.slice(2);
13
13
  const command = args[0];
14
14
 
15
- export const VERSION = "0.32.6";
15
+ export const VERSION = "0.32.8";
16
16
 
17
17
  export function printHelp() {
18
18
  console.log(`
19
- 🚀 agentctl v0.32.6 — Universal Agent Orchestrator & Safety Gatekeeper
19
+ 🚀 agentctl v0.32.8 — Universal Agent Orchestrator & Safety Gatekeeper
20
20
 
21
21
  Usage: agentctl <command> [options]
22
22
 
@@ -62,6 +62,7 @@ Options:
62
62
  `);
63
63
  }
64
64
 
65
+
65
66
  async function main() {
66
67
  if (!command || command === "--help" || command === "-h") {
67
68
  printHelp();
@@ -69,7 +70,14 @@ async function main() {
69
70
  }
70
71
 
71
72
  if (command === "version" || command === "--version" || command === "-v") {
72
- console.log("agentctl v0.32.6");
73
+ console.log(`agentctl v${VERSION}`);
74
+ process.exit(0);
75
+ }
76
+
77
+ // Intercept --help / -h on any subcommand (e.g. `agentctl init --help`)
78
+ const subArgs = args.slice(1);
79
+ if (subArgs.includes("--help") || subArgs.includes("-h")) {
80
+ printHelp();
73
81
  process.exit(0);
74
82
  }
75
83
 
@@ -171,6 +179,7 @@ async function main() {
171
179
  fix: { type: "boolean" },
172
180
  "allow-protected": { type: "boolean" },
173
181
  json: { type: "boolean", short: "j" },
182
+ "dry-run": { type: "boolean", short: "d" },
174
183
  },
175
184
  allowPositionals: true,
176
185
  });
@@ -304,7 +313,7 @@ async function main() {
304
313
  }
305
314
 
306
315
  case "doctor": {
307
- console.log(`\n🔍 agentctl System Diagnostics (v0.29.1)`);
316
+ console.log(`\n🔍 agentctl System Diagnostics (v${VERSION})`);
308
317
  console.log(`--------------------------------------------------`);
309
318
  console.log(` Project Root : ${root}`);
310
319
  console.log(` Config File : ${config._file || "None (Using defaults)"}`);
@@ -323,6 +332,7 @@ async function main() {
323
332
  args: args.slice(1),
324
333
  options: {
325
334
  force: { type: "boolean", short: "f" },
335
+ "dry-run": { type: "boolean", short: "d" },
326
336
  },
327
337
  allowPositionals: true,
328
338
  });
@@ -372,6 +382,7 @@ async function main() {
372
382
  interactive: { type: "boolean", short: "i" },
373
383
  tier: { type: "string", short: "t" },
374
384
  json: { type: "boolean", short: "j" },
385
+ "dry-run": { type: "boolean", short: "d" },
375
386
  },
376
387
  allowPositionals: true,
377
388
  });
@@ -412,6 +423,7 @@ async function main() {
412
423
  "require-plan-approval": { type: "boolean" },
413
424
  repoless: { type: "boolean" },
414
425
  json: { type: "boolean", short: "j" },
426
+ "dry-run": { type: "boolean", short: "d" },
415
427
  },
416
428
  allowPositionals: true,
417
429
  });
@@ -449,6 +461,7 @@ async function main() {
449
461
  list: { type: "boolean", short: "l" },
450
462
  json: { type: "boolean", short: "j" },
451
463
  "verify-cmd": { type: "string", short: "v" },
464
+ "dry-run": { type: "boolean", short: "d" },
452
465
  },
453
466
  allowPositionals: true,
454
467
  });
@@ -497,6 +510,7 @@ async function main() {
497
510
  web: { type: "boolean", short: "w" },
498
511
  json: { type: "boolean", short: "j" },
499
512
  "verify-cmd": { type: "string", short: "v" },
513
+ "dry-run": { type: "boolean" },
500
514
  },
501
515
  allowPositionals: true,
502
516
  });
@@ -559,7 +573,7 @@ async function main() {
559
573
  case "status": {
560
574
  const queueDir = getQueueDir(root);
561
575
  const files = existsSync(queueDir) ? readdirSync(queueDir).filter((f) => isTaskFile(f, queueDir)) : [];
562
- console.log(`\n📊 agentctl Status Summary (v0.29.1)`);
576
+ console.log(`\n📊 agentctl Status Summary (v${VERSION})`);
563
577
  console.log(`--------------------------------------------------`);
564
578
  console.log(` Project Root : ${root}`);
565
579
  console.log(` Pending Tasks : ${files.length}`);
@@ -653,6 +667,7 @@ async function main() {
653
667
  spec: { type: "string", short: "s" },
654
668
  run: { type: "boolean", short: "r" },
655
669
  json: { type: "boolean", short: "j" },
670
+ "dry-run": { type: "boolean", short: "d" },
656
671
  },
657
672
  allowPositionals: true,
658
673
  });
@@ -698,6 +713,7 @@ async function main() {
698
713
  options: {
699
714
  target: { type: "string", short: "t", default: "all" },
700
715
  json: { type: "boolean", short: "j" },
716
+ "dry-run": { type: "boolean", short: "d" },
701
717
  },
702
718
  allowPositionals: true,
703
719
  });
@@ -746,6 +762,7 @@ async function main() {
746
762
  task: { type: "string" },
747
763
  agent: { type: "string" },
748
764
  json: { type: "boolean", short: "j" },
765
+ "dry-run": { type: "boolean", short: "d" },
749
766
  },
750
767
  allowPositionals: true,
751
768
  });
@@ -798,6 +815,7 @@ async function main() {
798
815
  manifest: { type: "string", short: "m" },
799
816
  markdown: { type: "string" },
800
817
  json: { type: "boolean", short: "j" },
818
+ "dry-run": { type: "boolean", short: "d" },
801
819
  },
802
820
  allowPositionals: true,
803
821
  });
package/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Google Jules Orchestrator Kit - Node.js SDK (v0.29.1)
2
+ * Google Jules Orchestrator Kit - Node.js SDK
3
3
  *
4
4
  * Exposes core orchestrator functions for programmatically driving agent tasks,
5
5
  * security auditing, repo gating, and state operations.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jules-orchestrator-kit",
3
- "version": "0.32.6",
3
+ "version": "0.32.8",
4
4
  "description": "Orchestration kit for running Google Jules autonomous agents.",
5
5
  "repository": {
6
6
  "type": "git",
package/scripts/utils.mjs CHANGED
@@ -135,9 +135,15 @@ export function checkDailyBudget(arg1 = resolveRoot(), arg2 = 300) {
135
135
  return res;
136
136
  }
137
137
 
138
- export function reserveDailyBudget(maxSessions = 300, taskKey = "") {
139
- appendLedger({ event: "budget_reserved", key: taskKey });
140
- const check = checkDailyBudget(maxSessions);
138
+ /**
139
+ * @param {number} [maxSessions=300]
140
+ * @param {string} [taskKey=""]
141
+ * @param {string} [root] - Ledger root. Defaults to the git toplevel. Pass an
142
+ * explicit root to keep callers (notably tests) off the operator's real ledger.
143
+ */
144
+ export function reserveDailyBudget(maxSessions = 300, taskKey = "", root = resolveRoot()) {
145
+ appendLedger({ event: "budget_reserved", key: taskKey }, root);
146
+ const check = checkDailyBudget(root, maxSessions);
141
147
  return { ok: check.ok, used: check.used, budget: maxSessions };
142
148
  }
143
149
 
package/src/dashboard.mjs CHANGED
@@ -4,10 +4,15 @@
4
4
  */
5
5
 
6
6
  import http from "node:http";
7
+ import { readFileSync } from "node:fs";
8
+ import { fileURLToPath } from "node:url";
9
+ import { join, dirname } from "node:path";
7
10
  import { readTelemetry, verifyTelemetryIntegrity } from "./telemetry.mjs";
8
11
  import { readVerifyRuns, flakyVerdict } from "./flaky-ledger.mjs";
9
12
  import { lockStatus } from "./state.mjs";
10
13
 
14
+ const pkgVersion = JSON.parse(readFileSync(join(dirname(fileURLToPath(import.meta.url)), "..", "package.json"), "utf-8")).version;
15
+
11
16
  export function getDashboardHtml(root = process.cwd()) {
12
17
  return `<!DOCTYPE html>
13
18
  <html lang="en">
@@ -32,7 +37,7 @@ export function getDashboardHtml(root = process.cwd()) {
32
37
  </style>
33
38
  </head>
34
39
  <body>
35
- <h1>🚀 jules-orchestrator-kit Dashboard (v0.29.1)</h1>
40
+ <h1>🚀 jules-orchestrator-kit Dashboard (v${pkgVersion})</h1>
36
41
  <div class="subtitle">Repository: <code>${root}</code></div>
37
42
 
38
43
  <div class="grid">
package/src/engine.mjs CHANGED
@@ -695,7 +695,12 @@ export async function dispatch(task = {}, opts = {}) {
695
695
  }
696
696
  const root = opts.config?._root || opts.root || process.cwd();
697
697
  const config = opts.config || loadConfig(root);
698
- const { provider, routed, classification } = resolveRoutedProvider(task, config);
698
+ // opts.provider mirrors gate()'s existing injection point, so a caller can
699
+ // exercise dispatch without reaching a live provider.
700
+ const resolved = resolveRoutedProvider(task, config);
701
+ const provider = opts.provider || resolved.provider;
702
+ const routed = opts.provider ? false : resolved.routed;
703
+ const classification = opts.provider ? null : resolved.classification;
699
704
  if (routed && classification) {
700
705
  appendTelemetry(root, "router_decision", {
701
706
  tier: classification.tier,
@@ -739,12 +744,16 @@ export async function dispatch(task = {}, opts = {}) {
739
744
 
740
745
  const cleanTask = { ...task, prompt: envelopedPrompt };
741
746
 
747
+ const runDispatch = () => provider.dispatch(cleanTask, { root, dryRun: opts.dryRun });
748
+
742
749
  try {
743
- const session = await withBudget(
744
- () => provider.dispatch(cleanTask, { root, dryRun: opts.dryRun }),
745
- root,
746
- config.limits.dailyTasks
747
- );
750
+ // A dry run performs no provider call and produces no work, so it must not
751
+ // consume one of the operator's finite daily task slots. Reserving here also
752
+ // made every `npm test` burn real budget, which eventually exhausted the
753
+ // ledger and turned the suite red for reasons unrelated to any code change.
754
+ const session = opts.dryRun
755
+ ? await runDispatch()
756
+ : await withBudget(runDispatch, root, config.limits.dailyTasks);
748
757
  return classification ? { ...session, _routeTier: classification.tier, _routeReason: classification.reason } : session;
749
758
  } catch (err) {
750
759
  if (err instanceof ProviderRateLimitError || err instanceof ProviderUnavailableError) {