omnilane 0.21.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.21.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.21.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.21.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,27 @@ 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
+
9
30
  ## [0.21.0] - 2026-08-30
10
31
 
11
32
  ### Added
@@ -669,7 +690,11 @@ work to the wrong model, and records the evidence behind the shipped defaults.
669
690
  - Initial shared routing table, cross-vendor dispatcher, runners, installer,
670
691
  and baseline lint fixes.
671
692
 
672
- [Unreleased]: https://github.com/Seraphim0916/omnilane/compare/v0.21.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
673
698
 
674
699
  [0.21.0]: https://github.com/Seraphim0916/omnilane/compare/v0.20.0...v0.21.0
675
700
 
package/README.ja.md CHANGED
@@ -382,6 +382,22 @@ scripts/jobs.sh retry "$ID" --background
382
382
 
383
383
  アイドル中は API 呼び出しも料金も発生しません。既定では、新しい受信メッセージまたは結果イベントが 900 秒間なければ worker が自動で終了し、ジョブ全体タイムアウトは外側の上限として残ります。やり取りが終わったら早めに `close` できます。終了済み、またはライブでないジョブへの `jobs.sh send` は明確なエラーで失敗します。送った後に追跡しない作業、ライブ対応していないベンダー、クリーンな状態からの再実行が必要な場合には使わず、新しいディスパッチ(または完了後の `retry`)を使ってください。
384
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` を書き、そのパスを表示します。手順が明白な単一タスクは直接ディスパッチしてください。予算フラグを指定した場合、その上限は厳格な制約であり、完了を保証するものではありません。
400
+
385
401
  ## ❓ FAQ
386
402
 
387
403
  <details>
@@ -534,6 +550,17 @@ 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
+
537
564
  ## v0.21.0 の新機能
538
565
 
539
566
  - **セッションモードを明示的に選択。** `dispatch --live` で常駐セッションを必須にするか、`--single-shot` で単発ジョブを強制できます。ライブセッション非対応ベンダーでは `--live` が即時に失敗し、対応ベンダーを表示します。
package/README.ko.md CHANGED
@@ -369,6 +369,22 @@ scripts/jobs.sh retry "$ID" --background
369
369
 
370
370
  유휴 상태에서는 API 호출이나 비용이 발생하지 않습니다. 기본적으로 새 수신 메시지나 결과 이벤트가 900초 동안 없으면 worker가 자동으로 종료되며, 전체 작업 시간 제한은 바깥쪽 상한으로 유지됩니다. 대화가 끝나면 더 일찍 `close`할 수 있습니다. 끝났거나 라이브가 아닌 작업에 `jobs.sh send`를 실행하면 명확한 오류와 함께 실패합니다. 보낸 뒤 추적하지 않을 작업, 라이브 지원이 없는 벤더, 깨끗한 상태에서 다시 실행해야 하는 경우에는 쓰지 말고 새 dispatch 또는 완료 뒤 `retry`를 사용하세요.
371
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`를 기록하고 경로를 출력합니다. 절차가 명확한 단일 작업은 바로 디스패치하십시오. 예산 플래그를 지정한 경우 해당 상한은 엄격한 제한이며 완료를 보장하지 않습니다.
387
+
372
388
  ## ❓ FAQ
373
389
 
374
390
  <details>
@@ -517,6 +533,17 @@ 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
+
520
547
  ## v0.21.0 새 기능
521
548
 
522
549
  - **세션 모드를 명시적으로 선택.** `dispatch --live`로 상주 세션을 요구하거나 `--single-shot`으로 단발 작업을 강제할 수 있습니다. 라이브 세션을 지원하지 않는 벤더에서는 `--live`가 즉시 실패하고 지원 벤더를 표시합니다.
package/README.md CHANGED
@@ -439,6 +439,24 @@ scripts/jobs.sh retry "$ID" --background
439
439
 
440
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
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.
459
+
442
460
  ## ❓ FAQ
443
461
 
444
462
  <details>
@@ -596,6 +614,17 @@ 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
+
599
628
  ## What's new in v0.21.0
600
629
 
601
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.
package/README.zh-CN.md CHANGED
@@ -351,6 +351,22 @@ scripts/jobs.sh retry "$ID" --background
351
351
 
352
352
  空闲时不会发出 API 调用,也不会产生 API 费用。默认若 900 秒内没有新邮箱消息或新结果事件,worker 会自动收尾;整个作业超时仍是外层上限。处理结束可提前执行 `close`。向已结束或不是实时邮箱的作业执行 `jobs.sh send` 会明确报错并失败。即发即忘的工作、没有实时支持的供应商,或需要从干净状态重新运行的情况都不适用;请新建一次派发,或在作业完成后使用 `retry`。
353
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` 并打印路径。单个且做法明确的任务直接派发即可;传入预算参数后,对应的上限是硬限制,并不保证任务完成。
369
+
354
370
  ## ❓ 常见问题
355
371
 
356
372
  <details>
@@ -491,6 +507,17 @@ 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
+
494
521
  ## v0.21.0 新功能
495
522
 
496
523
  - **显式选择会话模式。** 可使用 `dispatch --live` 要求常驻会话,或用 `--single-shot` 强制单次派发;对不支持实时会话的供应商,`--live` 会立即失败并列出可用供应商。
package/README.zh-TW.md CHANGED
@@ -378,6 +378,22 @@ scripts/jobs.sh retry "$ID" --background
378
378
 
379
379
  閒置時不會發出 API 呼叫,也不會增加 API 費用。預設若 900 秒內沒有新信箱訊息或新結果事件,工作程序會自動收尾;整體工作逾時仍是外層上限。處理完成可提早執行 `close`。對已結束或不是即時信箱的工作使用 `jobs.sh send`,會明確報錯並失敗。送出後不需追蹤的工作、沒有即時支援的供應商,或必須從乾淨狀態重跑的情況都不適用;請使用新的派工,或在工作完成後使用 `retry`。
380
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` 並印出路徑。單一而且作法明確的工作直接派工即可;有傳入預算旗標時,該上限是硬限制,不代表保證完成。
396
+
381
397
  ## ❓ 常見問題
382
398
 
383
399
  <details>
@@ -515,6 +531,17 @@ 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
+
518
545
  ## v0.21.0 新功能
519
546
 
520
547
  - **明確選擇工作階段模式。** 可用 `dispatch --live` 要求常駐工作階段,或以 `--single-shot` 強制單次派工;對不支援即時工作階段的供應商,`--live` 會立即失敗並列出可用供應商。
package/VERSION CHANGED
@@ -1 +1 @@
1
- 0.21.0
1
+ 0.31.0
package/bin/omnilane CHANGED
@@ -76,9 +76,14 @@ omnilane — one routing table, every harness
76
76
  omnilane list effective routing table
77
77
  omnilane route [--vendor V] [flags] LANE "TASK"
78
78
  dispatch or consult a model
79
- omnilane goal "TEXT" [--budget-jobs N] [--budget-seconds S] [--workdir DIR]
80
- run bounded sequential goal loop
81
- omnilane goal status GOAL_ID inspect goal budget and last action
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
82
87
  omnilane jobs [--json] COMMAND [ARGS] list, status, result, stats, recommend, wait, or audit
83
88
  omnilane mcp start the MCP stdio server
84
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.21.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.21.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
  }
package/scripts/doctor.sh CHANGED
@@ -31,6 +31,7 @@ done
31
31
  REPO="${OMNILANE_DOCTOR_REPO:-$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)}"
32
32
  OMNILANE_HOME="${OMNILANE_HOME:-$HOME/.omnilane}"
33
33
  PROBE_SCRIPT="${OMNILANE_PROVIDER_PROBE_SCRIPT:-$REPO/scripts/provider-probe.sh}"
34
+ GOAL_LOOP="${OMNILANE_DOCTOR_GOAL_LOOP:-$REPO/scripts/lib/goal-loop.sh}"
34
35
  PASS_COUNT=0
35
36
  WARN_COUNT=0
36
37
  FAIL_COUNT=0
@@ -123,6 +124,31 @@ else
123
124
  report PASS state "$OMNILANE_HOME is accessible"
124
125
  fi
125
126
 
127
+ goals_store="$OMNILANE_HOME/goals"
128
+ if [[ ! -f "$GOAL_LOOP" || -L "$GOAL_LOOP" ]]; then
129
+ report FAIL goal-orchestrator "$GOAL_LOOP must be a regular file"
130
+ elif ! /bin/bash -n "$GOAL_LOOP" 2>/dev/null; then
131
+ report FAIL goal-orchestrator "$GOAL_LOOP has invalid bash syntax"
132
+ elif [[ -L "$goals_store" || ( -e "$goals_store" && ! -d "$goals_store" ) ]]; then
133
+ report FAIL goal-orchestrator "$goals_store must be a real directory, not a symlink or file"
134
+ elif [[ -d "$goals_store" ]]; then
135
+ goals_mode="$(stat -f '%Lp' "$goals_store" 2>/dev/null || true)"
136
+ if [[ ! "$goals_mode" =~ ^[0-7]{3,4}$ ]]; then
137
+ goals_mode="$(stat -c '%a' "$goals_store" 2>/dev/null || true)"
138
+ fi
139
+ if [[ "$goals_mode" =~ ^0?700$ ]]; then
140
+ report PASS goal-orchestrator "goal-loop.sh parses; goals store mode is $goals_mode"
141
+ elif [[ -n "$goals_mode" ]]; then
142
+ report WARN goal-orchestrator \
143
+ "goal-loop.sh parses; goals store mode is $goals_mode, owner-only 700 is safer"
144
+ else
145
+ report WARN goal-orchestrator \
146
+ "goal-loop.sh parses; could not determine goals store permissions"
147
+ fi
148
+ else
149
+ report PASS goal-orchestrator "goal-loop.sh parses; goals store is not present yet"
150
+ fi
151
+
126
152
  completion_plugin_state() {
127
153
  local config_dir state
128
154
  config_dir="${CLAUDE_CONFIG_DIR:-${HOME:-}/.claude}"