omnilane 0.20.0 → 0.31.0

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.
@@ -6,14 +6,14 @@
6
6
  },
7
7
  "metadata": {
8
8
  "description": "One routing table, cross-vendor dispatch, foreman completion inbox.",
9
- "version": "0.20.0"
9
+ "version": "0.31.0"
10
10
  },
11
11
  "plugins": [
12
12
  {
13
13
  "name": "omnilane",
14
14
  "source": "./",
15
15
  "description": "Route each subtask to the model that fits, dispatch it to any vendor CLI, and have finished dispatches report back into the foreman's next prompt.",
16
- "version": "0.20.0",
16
+ "version": "0.31.0",
17
17
  "category": "development",
18
18
  "keywords": [
19
19
  "routing",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "omnilane",
3
- "version": "0.20.0",
3
+ "version": "0.31.0",
4
4
  "description": "One routing table, every harness: classify subtasks into lanes and auto-dispatch each lane to the best vendor CLI (Codex, Claude Code, Grok Build, Antigravity) with background jobs, depth guard, and serialized codex dispatch.",
5
5
  "author": {
6
6
  "name": "Seraphim0916"
package/CHANGELOG.md CHANGED
@@ -6,6 +6,36 @@ semantic version tags.
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [0.31.0] - 2026-09-01
10
+
11
+ ### Changed
12
+
13
+ - Goal budgets now default to unlimited. `--budget-jobs N` and `--budget-seconds S` opt in to hard caps; the previous implicit 8-job and 900-second caps are gone. The repeat-failure fuse is not a budget and remains enabled by default.
14
+
15
+ ### Fixed
16
+
17
+ - `omnilane goal status` no longer fails when its consumer closes the pipe early. It exits 0 instead of raising `BrokenPipeError`, so `| head` and `| grep -q` work under `pipefail`.
18
+
19
+ ## [0.30.0] - 2026-08-31
20
+
21
+ ### Added
22
+
23
+ - `omnilane goal` — a bounded ledger around dispatch. `goal open` holds job and wall-clock budgets; `goal dispatch` gates each job on the job cap, wall clock, and repeat-failure fuse before it runs. `goal note` records the caller's narrative, `goal status` shows budgets and per-job lines, and `goal close` writes `goals/<id>/report.md`.
24
+ - `omnilane doctor` now includes a read-only goal-orchestrator check.
25
+
26
+ ### Changed
27
+
28
+ - The goal loop lives in the caller. omnilane never runs a planner model; the agent session or human that opened a goal chooses, dispatches, reviews, and closes the work.
29
+
30
+ ## [0.21.0] - 2026-08-30
31
+
32
+ ### Added
33
+
34
+ - Explicit session-mode selection for background dispatches: `--live` requires a resident session, while `--single-shot` forces a one-shot job. `--live` fails fast for a vendor without live support and names the live-capable vendors; the chosen `session_mode` is recorded in `meta.json`.
35
+ - Gemini joins Claude in the live mailbox through the `agy` stream protocol, with the shared protocol implementation in `scripts/lib/live-protocol.sh`.
36
+ - `--idle-timeout N` automatically closes an untended live session, records `closed by idle cap after Ns` as its close reason, and writes `idle_timeout` to `meta.json`.
37
+ - `tests/test_live_mailbox.sh` is wired into `tests/run.sh`, expanding the suite to 94 checks.
38
+
9
39
  ## [0.20.0] - 2026-08-30
10
40
 
11
41
  ### Added
@@ -660,7 +690,13 @@ work to the wrong model, and records the evidence behind the shipped defaults.
660
690
  - Initial shared routing table, cross-vendor dispatcher, runners, installer,
661
691
  and baseline lint fixes.
662
692
 
663
- [Unreleased]: https://github.com/Seraphim0916/omnilane/compare/v0.20.0...HEAD
693
+ [Unreleased]: https://github.com/Seraphim0916/omnilane/compare/v0.31.0...HEAD
694
+
695
+ [0.31.0]: https://github.com/Seraphim0916/omnilane/compare/v0.30.0...v0.31.0
696
+
697
+ [0.30.0]: https://github.com/Seraphim0916/omnilane/compare/v0.21.0...v0.30.0
698
+
699
+ [0.21.0]: https://github.com/Seraphim0916/omnilane/compare/v0.20.0...v0.21.0
664
700
 
665
701
  [0.20.0]: https://github.com/Seraphim0916/omnilane/compare/v0.15.0...v0.20.0
666
702
 
package/README.ja.md CHANGED
@@ -366,7 +366,7 @@ configure.sh set|get|unset|list|diff LANE [SPEC] # routing.local.yaml を非
366
366
 
367
367
  ## 📬 ライブメールボックス
368
368
 
369
- ライブメールボックスは、1 回で完結するディスパッチとは別の、Claude 専用の常駐バックグラウンド実行です。フォアマンが `--background` で開始し、実行中にも追加の指示を送れます。終わったらフォアマンが `jobs.sh close ID` で閉じます。放置しても常駐し続けるわけではなく、設定済みのジョブ全体タイムアウト(`--job-timeout`)に達すれば終了します。
369
+ ライブメールボックスは、1 回で完結するディスパッチとは別の、Claude Gemini が利用できる常駐バックグラウンド実行です。フォアマンが `--background` で開始し、実行中にも追加の指示を送れます。終わったらフォアマンが `jobs.sh close ID` で閉じます。放置しても常駐し続けるわけではなく、アイドル上限または設定済みのジョブ全体タイムアウト(`--job-timeout`)に達すれば終了します。
370
370
 
371
371
  ```bash
372
372
  scripts/dispatch.sh --background --vendor claude hard-judgment "タイムアウトしたテストを確認する"
@@ -378,9 +378,25 @@ scripts/jobs.sh close "$ID"
378
378
  scripts/jobs.sh retry "$ID" --background
379
379
  ```
380
380
 
381
- `watch` は `$JOB_DIR/events.jsonl` を追跡し、`tail` は公開出力の `out.txt` を読みます。ライブメールボックスを使えるのは現時点で Claude だけです。ほかのベンダーは通常の単発ディスパッチへフォールバックしますが、無通知ではありません。stderr と `$JOB_DIR/mode-notice.txt` に通知が残り、`jobs.sh status ID` にも表示されます。
381
+ `watch` は `$JOB_DIR/events.jsonl` を追跡し、`tail` は公開出力の `out.txt` を読みます。ライブメールボックスは Claude と Gemini に対応し、ほかのベンダーは通常の単発ディスパッチとして実行され、stderr と `$JOB_DIR/mode-notice.txt` に通知が残ります。`--live` は常駐セッションを必須にし、解決されたベンダーが非対応なら即時失敗します。`--single-shot` は Claude や Gemini でも単発実行を強制します。`--idle-timeout SECONDS` はアイドル上限を設定し、既定値は 900 秒、`0` で無効になります。
382
382
 
383
- アイドル中は API 呼び出しも料金も発生しませんが、ジョブ全体タイムアウトの時間は進みます。やり取りが終わったら `close` してください。終了済み、またはライブでないジョブへの `jobs.sh send` は明確なエラーで失敗します。送った後に追跡しない作業、ライブ対応していないベンダー、クリーンな状態からの再実行が必要な場合には使わず、新しいディスパッチ(または完了後の `retry`)を使ってください。
383
+ アイドル中は API 呼び出しも料金も発生しません。既定では、新しい受信メッセージまたは結果イベントが 900 秒間なければ worker が自動で終了し、ジョブ全体タイムアウトは外側の上限として残ります。やり取りが終わったら早めに `close` できます。終了済み、またはライブでないジョブへの `jobs.sh send` は明確なエラーで失敗します。送った後に追跡しない作業、ライブ対応していないベンダー、クリーンな状態からの再実行が必要な場合には使わず、新しいディスパッチ(または完了後の `retry`)を使ってください。
384
+
385
+ ## 🎯 ゴールオーケストレーション
386
+
387
+ `omnilane goal` は、フォアマンが進行する作業台帳です。ループを担当するのは、ゴールを開いたエージェントセッションまたは端末の利用者です。ジョブをディスパッチし、完了受信箱または `omnilane jobs wait` で結果を受け取り、次のジョブを判断して繰り返します。ジョブ数と経過秒数の予算はデフォルトで無制限です。`--budget-jobs N` または `--budget-seconds S` を指定した場合に限り、対応する上限が有効になります。omnilane は記録だけを担い、各 goal dispatch の前に呼び出し元が指定した上限とデフォルトで有効な同一失敗のヒューズを検査し、フォアマンがゴールを閉じるときにレポートをまとめます。
388
+
389
+ ```bash
390
+ GOAL_ID="$(omnilane goal open "不安定な決済統合を修正する" \
391
+ --budget-jobs 4 --budget-seconds 900 --workdir /path/to/repo)"
392
+ JOB_ID="$(omnilane goal dispatch "$GOAL_ID" --mode work hardest-coding \
393
+ "決済エラーを再現し、最小修正を実装して検証する")"
394
+ omnilane jobs wait "$JOB_ID" --timeout 900
395
+ omnilane goal note "$GOAL_ID" "決済統合テストが成功した"
396
+ omnilane goal close "$GOAL_ID" --summary "決済統合は安定した"
397
+ ```
398
+
399
+ ゴールの状態は `$OMNILANE_HOME/goals/<goal-id>/` に保存されます。`goal status` では、予算使用量、ヒューズ作動回数、各ジョブから順次届くメタデータと終了状態を確認できます。`goal close` は `report.md` を書き、そのパスを表示します。手順が明白な単一タスクは直接ディスパッチしてください。予算フラグを指定した場合、その上限は厳格な制約であり、完了を保証するものではありません。
384
400
 
385
401
  ## ❓ FAQ
386
402
 
@@ -534,6 +550,23 @@ scripts/dispatch.sh --dry-run hardest-coding "…" # 解決済みプラン、
534
550
 
535
551
  ## 📜 リリース履歴
536
552
 
553
+ ## v0.31.0 の新機能
554
+
555
+ - **ゴール予算はデフォルトで無制限。** `budget_jobs` と `budget_seconds` は JSON `null` として保存され、`unlimited` と表示されるようになりました。従来の暗黙的な 8 ジョブと 900 秒の上限は廃止され、`--budget-jobs N` または `--budget-seconds S` を指定した場合にのみ厳格な上限が有効になります。同一失敗のヒューズは予算ではなく、デフォルトで引き続き有効です。
556
+ - **パイプ経由のゴール状態表示を修正。** `omnilane goal status` は、出力先がパイプを早期に閉じた場合でも `BrokenPipeError` を発生させず、終了コード 0 で終了します。これにより、`pipefail` の環境でも `| head` と `| grep -q` が正常に動作します。
557
+
558
+ ## v0.30.0 の新機能
559
+
560
+ - **ゴール台帳。** `omnilane goal open` はジョブ数と経過秒数がデフォルトで無制限のゴール台帳を作成します。`goal dispatch` は各ジョブの実行前に呼び出し元が指定した上限と、デフォルトで有効な繰り返し失敗のヒューズを確認します。`goal note` は呼び出し元の記録を残し、`goal status` は予算とジョブごとの記録を表示し、`goal close` は `goals/<id>/report.md` を書き込みます。
561
+ - **ループは呼び出し元が担当。** ゴールを開いたセッションまたは利用者が選択、ディスパッチ、確認、クローズを行います。omnilane は組み込みの計画モデルを実行しません。
562
+ - **doctor チェック。** `omnilane doctor` はゴールオーケストレーションをチェックします。
563
+
564
+ ## v0.21.0 の新機能
565
+
566
+ - **セッションモードを明示的に選択。** `dispatch --live` で常駐セッションを必須にするか、`--single-shot` で単発ジョブを強制できます。ライブセッション非対応ベンダーでは `--live` が即時に失敗し、対応ベンダーを表示します。
567
+ - **Gemini がライブメールボックスに参加。** Gemini は `agy` ストリームプロトコルを介し、Claude と並んで常駐ライブジョブを実行できます。
568
+ - **ライブジョブのアイドル上限。** `--idle-timeout N` は放置されたライブセッションを自動で閉じ、終了理由とタイムアウトを `meta.json` に記録します。
569
+
537
570
  ## v0.20.0 の新機能
538
571
 
539
572
  - **フォアマン完了インボックス。** バックグラウンド dispatch の完了時に非公開の
package/README.ko.md CHANGED
@@ -353,7 +353,7 @@ CLI 를 사용할 수 없음, `5` 1라운드 성공 투표자 부족, `6` 2라
353
353
 
354
354
  ## 📬 라이브 메일함
355
355
 
356
- 라이브 메일함은 일회성 dispatch와 다른 Claude 전용 상주 백그라운드 실행입니다. 포어맨이 `--background`로 열고, 실행 중에도 추가 지시를 보낼 수 있으며, 끝나면 `jobs.sh close ID`로 닫을 책임이 있습니다. 방치해도 영구히 남아 있지는 않습니다. 설정된 전체 작업 시간 제한(`--job-timeout`)에 도달하면 종료됩니다.
356
+ 라이브 메일함은 일회성 dispatch와 다른 Claude Gemini용 상주 백그라운드 실행입니다. 포어맨이 `--background`로 열고, 실행 중에도 추가 지시를 보낼 수 있으며, 끝나면 `jobs.sh close ID`로 닫을 책임이 있습니다. 방치해도 영구히 남아 있지는 않습니다. 유휴 상한 또는 설정된 전체 작업 시간 제한(`--job-timeout`)에 도달하면 종료됩니다.
357
357
 
358
358
  ```bash
359
359
  scripts/dispatch.sh --background --vendor claude hard-judgment "시간 제한 테스트 실패를 확인해 주세요"
@@ -365,9 +365,25 @@ scripts/jobs.sh close "$ID"
365
365
  scripts/jobs.sh retry "$ID" --background
366
366
  ```
367
367
 
368
- `watch`는 `$JOB_DIR/events.jsonl`을 따라가고, `tail`은 공개 `out.txt`를 읽습니다. 라이브 메일함은 현재 Claude 지원합니다. 다른 벤더는 일반 일회성 dispatch로 내려가지만 조용히 처리되지는 않습니다. stderr와 `$JOB_DIR/mode-notice.txt`에 알림이 남고, `jobs.sh status ID`에도 표시됩니다.
368
+ `watch`는 `$JOB_DIR/events.jsonl`을 따라가고, `tail`은 공개 `out.txt`를 읽습니다. 라이브 메일함은 Claude Gemini를 지원하며, 다른 벤더는 일반 일회성 dispatch로 실행되고 stderr와 `$JOB_DIR/mode-notice.txt`에 알림이 남습니다. `--live`는 상주 세션을 필수로 하며 결정된 벤더가 지원하지 않으면 즉시 실패합니다. `--single-shot`은 Claude나 Gemini에서도 일회성 실행을 강제합니다. `--idle-timeout SECONDS`는 유휴 상한을 설정하며 기본값은 900초이고 `0`이면 비활성화됩니다.
369
369
 
370
- 유휴 상태에서는 API 호출이나 비용이 발생하지 않지만 전체 작업 시간 제한은 계속 소모됩니다. 대화가 끝나면 `close`하세요. 끝났거나 라이브가 아닌 작업에 `jobs.sh send`를 실행하면 명확한 오류와 함께 실패합니다. 보낸 뒤 추적하지 않을 작업, 라이브 지원이 없는 벤더, 깨끗한 상태에서 다시 실행해야 하는 경우에는 쓰지 말고 새 dispatch 또는 완료 뒤 `retry`를 사용하세요.
370
+ 유휴 상태에서는 API 호출이나 비용이 발생하지 않습니다. 기본적으로 새 수신 메시지나 결과 이벤트가 900초 동안 없으면 worker가 자동으로 종료되며, 전체 작업 시간 제한은 바깥쪽 상한으로 유지됩니다. 대화가 끝나면 더 일찍 `close`할 수 있습니다. 끝났거나 라이브가 아닌 작업에 `jobs.sh send`를 실행하면 명확한 오류와 함께 실패합니다. 보낸 뒤 추적하지 않을 작업, 라이브 지원이 없는 벤더, 깨끗한 상태에서 다시 실행해야 하는 경우에는 쓰지 말고 새 dispatch 또는 완료 뒤 `retry`를 사용하세요.
371
+
372
+ ## 🎯 목표 오케스트레이션
373
+
374
+ `omnilane goal`은 포어맨이 진행하는 작업 원장입니다. 루프는 목표를 연 에이전트 세션이나 터미널 사용자가 담당합니다. 작업을 디스패치하고 완료 수신함 또는 `omnilane jobs wait`로 결과를 받은 뒤 다음 작업을 판단하여 반복합니다. 작업 수와 경과 시간 예산은 기본적으로 무제한입니다. `--budget-jobs N` 또는 `--budget-seconds S`를 지정한 경우에만 해당 상한이 활성화됩니다. omnilane은 기록만 담당하며, 각 goal dispatch 전에 호출자가 지정한 상한과 기본적으로 활성화된 동일 실패 퓨즈를 검사하고 포어맨이 목표를 닫을 때 보고서를 작성합니다.
375
+
376
+ ```bash
377
+ GOAL_ID="$(omnilane goal open "불안정한 결제 통합 수정" \
378
+ --budget-jobs 4 --budget-seconds 900 --workdir /path/to/repo)"
379
+ JOB_ID="$(omnilane goal dispatch "$GOAL_ID" --mode work hardest-coding \
380
+ "결제 오류를 재현하고 최소 수정 후 검증")"
381
+ omnilane jobs wait "$JOB_ID" --timeout 900
382
+ omnilane goal note "$GOAL_ID" "결제 통합 테스트 통과"
383
+ omnilane goal close "$GOAL_ID" --summary "결제 통합이 안정화됨"
384
+ ```
385
+
386
+ 목표 상태는 `$OMNILANE_HOME/goals/<goal-id>/`에 저장됩니다. `goal status`로 예산 사용량, 퓨즈 작동 횟수, 각 작업에서 순차적으로 도착하는 메타데이터와 종료 상태를 확인할 수 있습니다. `goal close`는 `report.md`를 기록하고 경로를 출력합니다. 절차가 명확한 단일 작업은 바로 디스패치하십시오. 예산 플래그를 지정한 경우 해당 상한은 엄격한 제한이며 완료를 보장하지 않습니다.
371
387
 
372
388
  ## ❓ FAQ
373
389
 
@@ -517,6 +533,23 @@ scripts/dispatch.sh --dry-run hardest-coding "…" # 완전히 해석된 계
517
533
 
518
534
  ## 📜 릴리스 기록
519
535
 
536
+ ## v0.31.0 새 기능
537
+
538
+ - **목표 예산은 기본적으로 무제한입니다.** `budget_jobs`와 `budget_seconds`는 이제 JSON `null`로 저장되고 `unlimited`로 표시됩니다. 이전의 암묵적인 8개 작업 및 900초 상한은 제거되었으며, `--budget-jobs N` 또는 `--budget-seconds S`를 지정할 때만 엄격한 상한이 활성화됩니다. 반복 실패 퓨즈는 예산이 아니며 기본적으로 계속 활성화됩니다.
539
+ - **파이프를 통한 목표 상태 출력을 수정했습니다.** `omnilane goal status`는 출력 소비자가 파이프를 일찍 닫아도 `BrokenPipeError`를 발생시키지 않고 종료 코드 0으로 끝납니다. 따라서 `pipefail` 환경에서도 `| head`와 `| grep -q`가 정상적으로 작동합니다.
540
+
541
+ ## v0.30.0 새 기능
542
+
543
+ - **목표 원장.** `omnilane goal open`은 작업 수와 경과 시간이 기본적으로 무제한인 목표 원장을 만듭니다. `goal dispatch`는 각 작업을 실행하기 전에 호출자가 지정한 상한과 기본적으로 활성화된 반복 실패 퓨즈를 검사합니다. `goal note`는 호출자의 기록을 남기고, `goal status`는 예산과 작업별 기록을 표시하며, `goal close`는 `goals/<id>/report.md`를 작성합니다.
544
+ - **루프는 호출자가 담당합니다.** 목표를 연 세션이나 사용자가 선택, 디스패치, 검토, 종료를 수행합니다. omnilane은 내장 계획 모델을 실행하지 않습니다.
545
+ - **doctor 검사.** `omnilane doctor`가 이제 목표 오케스트레이션 기능을 검사합니다.
546
+
547
+ ## v0.21.0 새 기능
548
+
549
+ - **세션 모드를 명시적으로 선택.** `dispatch --live`로 상주 세션을 요구하거나 `--single-shot`으로 단발 작업을 강제할 수 있습니다. 라이브 세션을 지원하지 않는 벤더에서는 `--live`가 즉시 실패하고 지원 벤더를 표시합니다.
550
+ - **Gemini가 라이브 메일함에 합류.** Gemini는 `agy` 스트림 프로토콜을 통해 Claude와 함께 상주 라이브 작업을 실행할 수 있습니다.
551
+ - **라이브 작업의 유휴 제한.** `--idle-timeout N`은 방치된 라이브 세션을 자동으로 닫고 종료 사유와 제한 시간을 `meta.json`에 기록합니다.
552
+
520
553
  ## v0.20.0 새 기능
521
554
 
522
555
  - **Foreman 완료 수신함.** 백그라운드 디스패치가 끝나면 비공개 완료 레코드를
package/README.md CHANGED
@@ -423,7 +423,7 @@ code passes through.
423
423
 
424
424
  ## 📬 Live mailbox
425
425
 
426
- A live mailbox is a resident Claude background dispatch, not a one-shot dispatch. The foreman opens it with `--background`, can send another instruction while it is still running, and is responsible for closing it with `jobs.sh close ID`. Leaving it unattended does not make it permanent: the configured whole-job timeout (`--job-timeout`) still ends it.
426
+ A live mailbox is a resident Claude or Gemini background dispatch, not a one-shot dispatch. The foreman opens it with `--background`, can send another instruction while it is still running, and is responsible for closing it with `jobs.sh close ID`. Leaving it unattended does not make it permanent: the idle cap and configured whole-job timeout (`--job-timeout`) can still end it.
427
427
 
428
428
  ```bash
429
429
  scripts/dispatch.sh --background --vendor claude hard-judgment "Review the timeout failure"
@@ -435,9 +435,27 @@ scripts/jobs.sh close "$ID"
435
435
  scripts/jobs.sh retry "$ID" --background
436
436
  ```
437
437
 
438
- `watch` follows `$JOB_DIR/events.jsonl`; `tail` reads the public `out.txt`. Live mailbox support is Claude-only today. Any other vendor runs as a normal one-shot dispatch, with a degradation notice sent to stderr and stored in `$JOB_DIR/mode-notice.txt`; `jobs.sh status ID` prints that notice as well.
438
+ `watch` follows `$JOB_DIR/events.jsonl`; `tail` reads the public `out.txt`. Live mailbox support covers Claude and Gemini; other vendors run as normal one-shot dispatches, with a notice sent to stderr and stored in `$JOB_DIR/mode-notice.txt`. `--live` requires a resident session and fails fast when the resolved vendor is not capable. `--single-shot` forces one-shot execution even for Claude or Gemini. `--idle-timeout SECONDS` sets the inactivity cap (default 900; `0` disables it).
439
439
 
440
- An idle mailbox makes no API calls and incurs no API spend, but it keeps consuming its job-timeout window. Close it when its exchange is finished. `jobs.sh send` to a finished job or a job that is not live fails with a clear error. Do not use this for fire-and-forget work, vendors without live support, or a clean-slate rerun; start a fresh dispatch (or retry a completed job) instead.
440
+ An idle mailbox makes no API calls and incurs no API spend. By default it closes after 900 seconds without a new inbox message or result event, while the whole-job timeout remains the outer cap. Close it sooner when its exchange is finished. `jobs.sh send` to a finished job or a job that is not live fails with a clear error. Do not use this for fire-and-forget work, vendors without live support, or a clean-slate rerun; start a fresh dispatch (or retry a completed job) instead.
441
+
442
+ ## 🎯 Goal orchestration
443
+
444
+ `omnilane goal` is a foreman-driven ledger for exploratory work. The caller—an agent session or a human terminal—owns the loop: dispatch a job, receive its result through the completion inbox or `omnilane jobs wait`, decide the next job, and repeat. Job and elapsed-time budgets are unlimited by default; `--budget-jobs N` and `--budget-seconds S` opt in to each hard cap. omnilane supplies bookkeeping only, enforces any caller-supplied caps plus the always-on repeated-failure fuse before each goal dispatch, then assembles the report when the foreman closes the goal.
445
+
446
+ ```bash
447
+ GOAL_ID="$(omnilane goal open "Fix the flaky checkout integration" \
448
+ --budget-jobs 4 --budget-seconds 900 --workdir /path/to/repo)"
449
+ JOB_ID="$(omnilane goal dispatch "$GOAL_ID" --mode work hardest-coding \
450
+ "Reproduce the checkout failure and implement the smallest verified fix")"
451
+ omnilane jobs wait "$JOB_ID" --timeout 900
452
+ omnilane goal note "$GOAL_ID" "Fix verified by the checkout integration test"
453
+ omnilane goal close "$GOAL_ID" --summary "Checkout integration is stable"
454
+ ```
455
+
456
+ Goal state lives under `$OMNILANE_HOME/goals/<goal-id>/`. Use `goal status` to inspect budget usage, fuse trips, and each recorded job as its metadata and exit status land. `goal close` writes `report.md` and prints its path. For one obvious task, dispatch directly. When budget flags are supplied, those caps are hard bounds, not completion promises.
457
+
458
+ Do not use goal orchestration for a single obvious task; dispatch that task directly. The default unlimited budgets let the caller keep exploring without omnilane imposing a cap; pass either budget flag only when that limit is wanted.
441
459
 
442
460
  ## ❓ FAQ
443
461
 
@@ -596,6 +614,23 @@ working notes, including per-benchmark caveats, live in
596
614
 
597
615
  ## 📜 Release history
598
616
 
617
+ ## What's new in v0.31.0
618
+
619
+ - **Unlimited goal budgets by default.** `budget_jobs` and `budget_seconds` now persist as JSON `null` and render as `unlimited`; the previous implicit 8-job and 900-second caps are gone. Use `--budget-jobs N` or `--budget-seconds S` to opt in to a hard cap. The repeat-failure fuse remains enabled by default.
620
+ - **Pipe-safe goal status.** `omnilane goal status` now exits 0 when its consumer closes the pipe early instead of raising `BrokenPipeError`, so `| head` and `| grep -q` work under `pipefail`.
621
+
622
+ ## What's new in v0.30.0
623
+
624
+ - **Goal ledger.** `omnilane goal open` creates a goal ledger with unlimited default budgets; `goal dispatch` gates each job on caller-supplied job or wall-clock caps and the always-on repeat-failure fuse. `goal note` preserves the caller's narrative, `goal status` shows budgets and per-job records, and `goal close` writes `goals/<id>/report.md`.
625
+ - **Caller owns the loop.** The session or person that opened the goal chooses, dispatches, reviews, and closes the work; omnilane does not run a built-in planning model.
626
+ - **Doctor coverage.** `omnilane doctor` now checks the goal-orchestrator surface.
627
+
628
+ ## What's new in v0.21.0
629
+
630
+ - **Explicit session mode.** Use `dispatch --live` to require a resident session or `--single-shot` to force a one-shot job. `--live` fails immediately for incompatible vendors and lists the live-capable choices.
631
+ - **Gemini joins the live mailbox.** Gemini can now run a resident live job through the `agy` stream protocol alongside Claude.
632
+ - **Idle cap for live jobs.** `--idle-timeout N` automatically closes an untended live session and preserves the close reason and timeout in `meta.json`.
633
+
599
634
  ## What's new in v0.20.0
600
635
 
601
636
  - **Foreman completion inbox.** Finished background dispatches write a private
package/README.zh-CN.md CHANGED
@@ -335,7 +335,7 @@ configure.sh set|get|unset|list|diff LANE [SPEC] # 非交互编辑/查看 rou
335
335
 
336
336
  ## 📬 实时邮箱
337
337
 
338
- 实时邮箱是 Claude 专用的常驻后台派发,不是一次性派发。派发方以 `--background` 打开后,运行中仍可追加指令,并负责用 `jobs.sh close ID` 收尾。即使无人处理,它也不会永久存在:已配置的整个作业超时(`--job-timeout`)到期后仍会终止它。
338
+ 实时邮箱是 Claude Gemini 可用的常驻后台派发,不是一次性派发。派发方以 `--background` 打开后,运行中仍可追加指令,并负责用 `jobs.sh close ID` 收尾。即使无人处理,它也不会永久存在:空闲上限或已配置的整个作业超时(`--job-timeout`)到期后都会终止它。
339
339
 
340
340
  ```bash
341
341
  scripts/dispatch.sh --background --vendor claude hard-judgment "检查超时测试失败的原因"
@@ -347,9 +347,25 @@ scripts/jobs.sh close "$ID"
347
347
  scripts/jobs.sh retry "$ID" --background
348
348
  ```
349
349
 
350
- `watch` 会跟随 `$JOB_DIR/events.jsonl`;`tail` 读取公开的 `out.txt`。目前只有 Claude 支持实时邮箱。其他供应商都会降级为普通的一次性派发,但不是静默发生:stderr 和 `$JOB_DIR/mode-notice.txt` 都会留下提示,`jobs.sh status ID` 也会显示该提示。
350
+ `watch` 会跟随 `$JOB_DIR/events.jsonl`;`tail` 读取公开的 `out.txt`。目前 Claude 和 Gemini 支持实时邮箱;其他供应商会执行普通的一次性派发,并在 stderr 和 `$JOB_DIR/mode-notice.txt` 留下提示。`--live` 明确要求常驻会话,解析出的供应商不支持时立即失败。`--single-shot` 即使遇到 Claude 或 Gemini 也强制一次性派发。`--idle-timeout SECONDS` 设置空闲上限,默认 900 秒,设为 `0` 可禁用。
351
351
 
352
- 空闲时不会发出 API 调用,也不会产生 API 费用,但整个作业超时的时间仍在流逝。处理结束就应执行 `close`。向已结束或不是实时邮箱的作业执行 `jobs.sh send` 会明确报错并失败。即发即忘的工作、没有实时支持的供应商,或需要从干净状态重新运行的情况都不适用;请新建一次派发,或在作业完成后使用 `retry`。
352
+ 空闲时不会发出 API 调用,也不会产生 API 费用。默认若 900 秒内没有新邮箱消息或新结果事件,worker 会自动收尾;整个作业超时仍是外层上限。处理结束可提前执行 `close`。向已结束或不是实时邮箱的作业执行 `jobs.sh send` 会明确报错并失败。即发即忘的工作、没有实时支持的供应商,或需要从干净状态重新运行的情况都不适用;请新建一次派发,或在作业完成后使用 `retry`。
353
+
354
+ ## 🎯 目标编排
355
+
356
+ `omnilane goal` 是由领班驱动的工作台账。循环由调用方负责,也就是打开目标的代理会话或终端用户:派发一个作业,从完成收件箱或 `omnilane jobs wait` 取回结果,决定下一个作业,再重复执行。作业数量和秒数预算默认均不设上限;只有传入 `--budget-jobs N` 或 `--budget-seconds S` 时,才会启用对应的硬上限。omnilane 只负责记账;每次 goal dispatch 前都会检查调用方设置的上限和默认启用的重复失败熔断器,领班关闭目标时才汇总报告。
357
+
358
+ ```bash
359
+ GOAL_ID="$(omnilane goal open "修复不稳定的结账集成" \
360
+ --budget-jobs 4 --budget-seconds 900 --workdir /path/to/repo)"
361
+ JOB_ID="$(omnilane goal dispatch "$GOAL_ID" --mode work hardest-coding \
362
+ "重现结账失败,完成最小修复并验证")"
363
+ omnilane jobs wait "$JOB_ID" --timeout 900
364
+ omnilane goal note "$GOAL_ID" "结账集成测试已通过"
365
+ omnilane goal close "$GOAL_ID" --summary "结账集成已稳定"
366
+ ```
367
+
368
+ 目标状态保存在 `$OMNILANE_HOME/goals/<goal-id>/`。使用 `goal status` 可以查看预算用量、熔断次数,以及各作业陆续写入的元数据和退出状态。`goal close` 会写入 `report.md` 并打印路径。单个且做法明确的任务直接派发即可;传入预算参数后,对应的上限是硬限制,并不保证任务完成。
353
369
 
354
370
  ## ❓ 常见问题
355
371
 
@@ -491,6 +507,23 @@ vendor 一律当成 `work`,而且它只能逐次明确指定,永远不是 lane
491
507
 
492
508
  ## 📜 版本历程
493
509
 
510
+ ## v0.31.0 新功能
511
+
512
+ - **目标预算默认不设上限。** `budget_jobs` 和 `budget_seconds` 现在以 JSON `null` 保存并显示为 `unlimited`;此前隐含的 8 个任务和 900 秒上限已移除。只有使用 `--budget-jobs N` 或 `--budget-seconds S` 才会启用硬性上限;重复失败保险丝不是预算,默认仍然启用。
513
+ - **管道中的目标状态不再误报失败。** `omnilane goal status` 的消费端提前关闭管道时,现在会以状态码 0 退出,而不是触发 `BrokenPipeError`,因此 `| head` 和 `| grep -q` 可在 `pipefail` 下正常工作。
514
+
515
+ ## v0.30.0 新功能
516
+
517
+ - **目标台账。** `omnilane goal open` 创建默认不限制作业数量和秒数的目标台账;`goal dispatch` 会在每个作业运行前检查调用方设置的作业数量或总耗时上限,以及默认启用的重复失败熔断器。`goal note` 保留调用方叙事,`goal status` 显示预算和每个作业记录,`goal close` 会写入 `goals/<id>/report.md`。
518
+ - **循环由调用方负责。** 打开目标的会话或用户负责选择、派发、审阅和收尾;omnilane 不会运行内置的规划模型。
519
+ - **doctor 检查。** `omnilane doctor` 现在会检查目标编排功能。
520
+
521
+ ## v0.21.0 新功能
522
+
523
+ - **显式选择会话模式。** 可使用 `dispatch --live` 要求常驻会话,或用 `--single-shot` 强制单次派发;对不支持实时会话的供应商,`--live` 会立即失败并列出可用供应商。
524
+ - **Gemini 加入实时邮箱。** Gemini 通过 `agy` 流式协议加入常驻实时任务,与 Claude 并列支持。
525
+ - **实时任务的空闲上限。** `--idle-timeout N` 会自动关闭无人处理的实时会话,并在关闭原因与 `meta.json` 中保留超时信息。
526
+
494
527
  ## v0.20.0 新功能
495
528
 
496
529
  - **Foreman 完成收件箱。** 后台派发完成后会写入私有完成记录,内置 Claude
package/README.zh-TW.md CHANGED
@@ -362,7 +362,7 @@ codex/claude/grok/gemini 自選 1-4 個評審。開了之後,同一個問題丟
362
362
 
363
363
  ## 📬 即時信箱
364
364
 
365
- 即時信箱是 Claude 專用的常駐背景派工,不是一次性派工。派工者以 `--background` 開啟後,執行中仍能補傳指示,並負責用 `jobs.sh close ID` 收尾。即使沒人處理,也不會永久存在:設定的整體工作逾時(`--job-timeout`)一到就會結束。
365
+ 即時信箱是 Claude Gemini 可用的常駐背景派工,不是一次性派工。派工者以 `--background` 開啟後,執行中仍能補傳指示,並負責用 `jobs.sh close ID` 收尾。即使沒人處理,也不會永久存在:閒置上限或設定的整體工作逾時(`--job-timeout`)一到就會結束。
366
366
 
367
367
  ```bash
368
368
  scripts/dispatch.sh --background --vendor claude hard-judgment "檢查逾時測試失敗的原因"
@@ -374,9 +374,25 @@ scripts/jobs.sh close "$ID"
374
374
  scripts/jobs.sh retry "$ID" --background
375
375
  ```
376
376
 
377
- `watch` 追隨 `$JOB_DIR/events.jsonl`;`tail` 讀取公開的 `out.txt`。目前只有 Claude 支援即時信箱。其他供應商都會降級成一般的一次性派工,但通知不會被隱藏:stderr 與 `$JOB_DIR/mode-notice.txt` 都會留下提示,`jobs.sh status ID` 也會顯示它。
377
+ `watch` 追隨 `$JOB_DIR/events.jsonl`;`tail` 讀取公開的 `out.txt`。目前 Claude 與 Gemini 支援即時信箱;其他供應商會執行一般的一次性派工,stderr 與 `$JOB_DIR/mode-notice.txt` 都會留下提示。`--live` 會明確要求常駐工作階段,解析出的供應商不支援時立即失敗。`--single-shot` 即使遇到 Claude 或 Gemini 也會強制一次性派工。`--idle-timeout SECONDS` 設定閒置上限,預設 900 秒,設為 `0` 則停用。
378
378
 
379
- 閒置時不會發出 API 呼叫,也不會增加 API 費用,但仍會持續消耗整體工作逾時的時間。處理完成就應執行 `close`。對已結束或不是即時信箱的工作使用 `jobs.sh send`,會明確報錯並失敗。送出後不需追蹤的工作、沒有即時支援的供應商,或必須從乾淨狀態重跑的情況都不適用;請改用新的派工,或在工作完成後使用 `retry`。
379
+ 閒置時不會發出 API 呼叫,也不會增加 API 費用。預設若 900 秒內沒有新信箱訊息或新結果事件,工作程序會自動收尾;整體工作逾時仍是外層上限。處理完成可提早執行 `close`。對已結束或不是即時信箱的工作使用 `jobs.sh send`,會明確報錯並失敗。送出後不需追蹤的工作、沒有即時支援的供應商,或必須從乾淨狀態重跑的情況都不適用;請使用新的派工,或在工作完成後使用 `retry`。
380
+
381
+ ## 🎯 目標編排
382
+
383
+ `omnilane goal` 是工頭式工作台帳。迴圈由呼叫端負責,也就是開啟目標的代理工作階段或終端機前的人:派出一份工作,從完成信箱或 `omnilane jobs wait` 收回結果,判斷下一份工作,再重複執行。工作數與秒數預算預設都不設上限;只有傳入 `--budget-jobs N` 或 `--budget-seconds S` 時,才會啟用對應的硬上限。omnilane 只負責記帳;每次 goal dispatch 前會檢查呼叫端設定的上限與預設啟用的重複失敗熔斷器,工頭關閉目標時才彙整報告。
384
+
385
+ ```bash
386
+ GOAL_ID="$(omnilane goal open "修好不穩定的結帳整合" \
387
+ --budget-jobs 4 --budget-seconds 900 --workdir /path/to/repo)"
388
+ JOB_ID="$(omnilane goal dispatch "$GOAL_ID" --mode work hardest-coding \
389
+ "重現結帳失敗,完成最小修正並驗證")"
390
+ omnilane jobs wait "$JOB_ID" --timeout 900
391
+ omnilane goal note "$GOAL_ID" "結帳整合測試已通過"
392
+ omnilane goal close "$GOAL_ID" --summary "結帳整合已穩定"
393
+ ```
394
+
395
+ 目標狀態存放在 `$OMNILANE_HOME/goals/<goal-id>/`。用 `goal status` 可查看預算用量、熔斷次數,以及每份工作陸續寫入的中繼資料與結束狀態。`goal close` 會寫入 `report.md` 並印出路徑。單一而且作法明確的工作直接派工即可;有傳入預算旗標時,該上限是硬限制,不代表保證完成。
380
396
 
381
397
  ## ❓ 常見問題
382
398
 
@@ -515,6 +531,23 @@ vendor 一律當成 `work`,而且它只能逐次明確指定,永遠不是 lane
515
531
 
516
532
  ## 📜 版本歷程
517
533
 
534
+ ## v0.31.0 新功能
535
+
536
+ - **目標預算預設無上限。** `budget_jobs` 與 `budget_seconds` 現在會以 JSON `null` 儲存並顯示為 `unlimited`;原先隱含的 8 個工作與 900 秒上限已移除。使用 `--budget-jobs N` 或 `--budget-seconds S` 才會啟用硬性上限;重複失敗保險絲不是預算,預設仍會啟用。
537
+ - **管線中的目標狀態不再誤判失敗。** `omnilane goal status` 的消費端提早關閉管線時,現在會以狀態碼 0 結束,不再引發 `BrokenPipeError`,因此 `| head` 與 `| grep -q` 可在 `pipefail` 下正常運作。
538
+
539
+ ## v0.30.0 新功能
540
+
541
+ - **目標台帳。** `omnilane goal open` 建立預設不限制工作數與秒數的目標台帳;`goal dispatch` 會在每份工作執行前檢查呼叫端設定的工作數或總經過時間上限,以及預設啟用的重複失敗熔斷器。`goal note` 保留呼叫端敘事,`goal status` 顯示預算與各工作紀錄,`goal close` 會寫入 `goals/<id>/report.md`。
542
+ - **迴圈由呼叫端掌握。** 開啟目標的工作階段或使用者負責選擇、派工、檢視與收尾;omnilane 不會執行內建的規劃模型。
543
+ - **doctor 檢查。** `omnilane doctor` 現在會檢查目標編排功能。
544
+
545
+ ## v0.21.0 新功能
546
+
547
+ - **明確選擇工作階段模式。** 可用 `dispatch --live` 要求常駐工作階段,或以 `--single-shot` 強制單次派工;對不支援即時工作階段的供應商,`--live` 會立即失敗並列出可用供應商。
548
+ - **Gemini 加入即時信箱。** Gemini 透過 `agy` 串流協定加入常駐即時工作,與 Claude 並列支援。
549
+ - **即時工作的閒置上限。** `--idle-timeout N` 會自動關閉無人處理的即時工作階段,並在關閉原因與 `meta.json` 留下逾時資訊。
550
+
518
551
  ## v0.20.0 新功能
519
552
 
520
553
  - **Foreman 完成收件匣。** 背景派工完成後會寫入私有完成紀錄,內建的 Claude
package/VERSION CHANGED
@@ -1 +1 @@
1
- 0.20.0
1
+ 0.31.0
package/bin/omnilane CHANGED
@@ -30,7 +30,8 @@ case "$cmd" in
30
30
  ;;
31
31
  list) exec bash "$REPO/scripts/dispatch.sh" --list ;;
32
32
  route|dispatch) exec bash "$REPO/scripts/dispatch.sh" "$@" ;;
33
- jobs) exec bash "$REPO/scripts/jobs.sh" "$@" ;;
33
+ jobs) exec bash "$REPO/scripts/jobs.sh" "$@" ;;
34
+ goal) exec bash "$REPO/scripts/lib/goal-loop.sh" "$@" ;;
34
35
  mcp)
35
36
  command -v node >/dev/null 2>&1 || {
36
37
  echo "omnilane: mcp requires Node.js on PATH" >&2
@@ -75,6 +76,14 @@ omnilane — one routing table, every harness
75
76
  omnilane list effective routing table
76
77
  omnilane route [--vendor V] [flags] LANE "TASK"
77
78
  dispatch or consult a model
79
+ omnilane goal open "TEXT" [--budget-jobs N] [--budget-seconds S] [--workdir DIR]
80
+ open a goal; budgets default to unlimited
81
+ omnilane goal dispatch GOAL_ID [dispatch.sh args...]
82
+ budget-gate and start one background job
83
+ omnilane goal note GOAL_ID "TEXT" append a timestamped foreman note
84
+ omnilane goal status GOAL_ID inspect budgets, fuse trips, and recorded jobs
85
+ omnilane goal close GOAL_ID [--summary "TEXT"]
86
+ write the final goal report
78
87
  omnilane jobs [--json] COMMAND [ARGS] list, status, result, stats, recommend, wait, or audit
79
88
  omnilane mcp start the MCP stdio server
80
89
  omnilane completion bash|zsh|fish print a shell completion script
@@ -1,18 +1,27 @@
1
1
  <!-- omnilane-routing:start -->
2
2
  ## omnilane — model routing (persistent reminder)
3
3
 
4
- Before delegating any subtask or choosing a model for a piece of work,
5
- consult the omnilane routing table: run `omnilane list` (or
6
- `scripts/dispatch.sh --list` inside the omnilane repo) and classify the
7
- subtask into a lane. If the lane's first available model is the one you are
8
- running as, self-execute; otherwise dispatch it headlessly:
4
+ Implementation work code edits, new files, tests, builds, deploys is
5
+ dispatched by default, even when the lane's first available model is the one
6
+ you are running as. Consult the routing table with `omnilane list` (or
7
+ `scripts/dispatch.sh --list` inside the omnilane repo), classify the subtask
8
+ into a lane, then dispatch it headlessly:
9
9
 
10
10
  omnilane route [--vendor V] [--mode work] [--workdir DIR] <lane> "<task>"
11
11
 
12
+ Advise mode is the default; pass `--mode work` only with an explicit
13
+ `--workdir`. The commander self-executes only reserved items: planning and
14
+ decomposition, writing task briefs, reviewing reports, acceptance checks,
15
+ replies to the operator, git commit/push, read-only verification, and fixes
16
+ of one line or less. "This lane is mine, so I'll do it myself" is not a
17
+ valid reason to skip dispatch.
18
+
12
19
  If the user explicitly names Claude, Codex, Grok, Gemini, or a canonical model
13
20
  alias, use the omnilane skill's consult rules and keep `--vendor` in the
14
21
  dispatch; an explicit target must not silently fall back.
15
22
 
16
- Lane definitions, modes, and safety rules live in the `omnilane` skill.
17
- Workers must never dispatch again (nested dispatch is refused, exit 86).
23
+ Lane definitions, modes, per-model rows, and safety rules live in the
24
+ `omnilane` skill load it and apply the row for the model you are running
25
+ as; legacy model-routing skill variants are retired. Workers must never
26
+ dispatch again (nested dispatch is refused, exit 86).
18
27
  <!-- omnilane-routing:end -->
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "omnilane",
3
- "version": "0.20.0",
3
+ "version": "0.31.0",
4
4
  "description": "One routing table, every harness — classify subtasks into lanes and dispatch each lane to the best vendor's agentic CLI (Codex, Claude, Gemini, Grok) using your existing subscription logins.",
5
5
  "bin": {
6
6
  "omnilane": "bin/omnilane"
package/plugin.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "https://antigravity.google/schemas/v1/plugin.json",
3
3
  "name": "omnilane",
4
- "version": "0.20.0",
4
+ "version": "0.31.0",
5
5
  "description": "One routing table, every harness: classify subtasks into lanes and auto-dispatch each lane to the best vendor CLI (Codex, Claude Code, Grok Build, Antigravity) with background jobs, depth guard, and serialized codex dispatch."
6
6
  }