omnilane 0.13.0 → 0.14.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.
- package/CHANGELOG.md +34 -1
- package/README.ja.md +8 -0
- package/README.ko.md +8 -0
- package/README.md +38 -2
- package/README.zh-CN.md +8 -0
- package/README.zh-TW.md +29 -2
- package/VERSION +1 -1
- package/benchmarks/workloads.tsv +4 -0
- package/bin/omnilane +10 -2
- package/bin/omnilane-mcp +126 -0
- package/completions/_omnilane +21 -4
- package/completions/omnilane.bash +19 -4
- package/completions/omnilane.fish +15 -3
- package/package.json +2 -1
- package/scripts/benchmark.py +446 -0
- package/scripts/check.sh +1 -1
- package/scripts/doctor.sh +53 -10
- package/scripts/jobs.sh +162 -2
- package/scripts/provider-probe.sh +180 -0
- package/ui/app.js +56 -0
- package/ui/index.html +1 -0
- package/ui/styles.css +22 -0
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,37 @@ semantic version tags.
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [0.14.0] - 2026-08-10
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- Optional `omnilane doctor --probe V` and read-only MCP `provider_probe` perform
|
|
14
|
+
one bounded advise-mode live capability check only when explicitly requested;
|
|
15
|
+
reports include routing/timing metadata but never the provider response body.
|
|
16
|
+
- Live Board retained-history search and state filters now drive a local
|
|
17
|
+
**Export visible** JSON download that excludes tokens, task/result bodies,
|
|
18
|
+
workdirs, and logs.
|
|
19
|
+
- `omnilane benchmark` provides a versioned fixed-workload quality/timing report,
|
|
20
|
+
transparent user-supplied per-call cost estimates, default no-call dry-run,
|
|
21
|
+
and an explicit `--run` provider-call gate.
|
|
22
|
+
- CI runs `omnilane doctor --strict --json` against an isolated, offline fixture
|
|
23
|
+
as a post-install acceptance contract.
|
|
24
|
+
|
|
25
|
+
- `omnilane jobs recommend` and the read-only MCP `jobs_recommend` tool derive
|
|
26
|
+
per-lane vendor suggestions from bounded completed-job metadata. A configurable
|
|
27
|
+
minimum sample gate prevents one-off successes from outranking established
|
|
28
|
+
evidence; neither surface reads task/result bodies or changes routing.
|
|
29
|
+
- `omnilane doctor --strict` keeps warning diagnostics intact but exits nonzero
|
|
30
|
+
when any warning is present, so local automation and CI can enforce a complete
|
|
31
|
+
runtime setup. JSON output now includes the applied `strict` policy and makes
|
|
32
|
+
`ok` reflect it.
|
|
33
|
+
|
|
34
|
+
### Fixed
|
|
35
|
+
|
|
36
|
+
- `doctor` now validates macOS `stat -f` output before falling back to GNU
|
|
37
|
+
`stat -c`, so owner-only job-store permissions are classified consistently on
|
|
38
|
+
Linux CI instead of becoming a false strict-mode warning.
|
|
39
|
+
|
|
9
40
|
## [0.13.0] - 2026-08-03
|
|
10
41
|
|
|
11
42
|
### Changed
|
|
@@ -563,7 +594,9 @@ work to the wrong model, and records the evidence behind the shipped defaults.
|
|
|
563
594
|
- Initial shared routing table, cross-vendor dispatcher, runners, installer,
|
|
564
595
|
and baseline lint fixes.
|
|
565
596
|
|
|
566
|
-
[Unreleased]: https://github.com/Seraphim0916/omnilane/compare/v0.
|
|
597
|
+
[Unreleased]: https://github.com/Seraphim0916/omnilane/compare/v0.14.0...HEAD
|
|
598
|
+
|
|
599
|
+
[0.14.0]: https://github.com/Seraphim0916/omnilane/compare/v0.13.0...v0.14.0
|
|
567
600
|
[0.13.0]: https://github.com/Seraphim0916/omnilane/compare/v0.12.0...v0.13.0
|
|
568
601
|
[0.12.0]: https://github.com/Seraphim0916/omnilane/compare/v0.11.0...v0.12.0
|
|
569
602
|
[0.11.0]: https://github.com/Seraphim0916/omnilane/compare/v0.10.4...v0.11.0
|
package/README.ja.md
CHANGED
|
@@ -516,6 +516,14 @@ scripts/dispatch.sh --dry-run hardest-coding "…" # 解決済みプラン、
|
|
|
516
516
|
|
|
517
517
|
## 📜 リリース履歴
|
|
518
518
|
|
|
519
|
+
## v0.14.0 の新機能
|
|
520
|
+
|
|
521
|
+
- **根拠に基づくルーティング提案**:`jobs recommend` と MCP `jobs_recommend` は公開ジョブメタデータだけを読み、ルーティングを自動変更しません。
|
|
522
|
+
- **任意の実動プローブ**:`doctor --probe V` と MCP `provider_probe` は明示された場合だけプロバイダーを呼び出し、応答本文を報告しません。
|
|
523
|
+
- **Live Board の履歴検索・絞り込み・エクスポート**:直近 50 件を対象に、表示中の公開メタデータだけを出力します。
|
|
524
|
+
- **固定品質/コストベンチマーク**:`omnilane benchmark` は既定で dry-run、実呼び出しには `--run` が必要です。
|
|
525
|
+
- **厳格なインストール検証**:CI で隔離された `doctor --strict --json` を実行し、macOS/GNU `stat` の権限判定差も修正しました。
|
|
526
|
+
|
|
519
527
|
## v0.13.0 の新機能
|
|
520
528
|
|
|
521
529
|
- **`long-context` を AA-LCR で順序付け** — Artificial Analysis の長文脈推論
|
package/README.ko.md
CHANGED
|
@@ -499,6 +499,14 @@ scripts/dispatch.sh --dry-run hardest-coding "…" # 완전히 해석된 계
|
|
|
499
499
|
|
|
500
500
|
## 📜 릴리스 기록
|
|
501
501
|
|
|
502
|
+
## v0.14.0 새 기능
|
|
503
|
+
|
|
504
|
+
- **근거 기반 라우팅 제안**: `jobs recommend`와 MCP `jobs_recommend`는 공개 작업 메타데이터만 읽고 라우팅을 자동 변경하지 않습니다.
|
|
505
|
+
- **선택형 실제 기능 탐지**: `doctor --probe V`와 MCP `provider_probe`는 명시적으로 요청할 때만 공급자를 호출하며 응답 본문을 보고하지 않습니다.
|
|
506
|
+
- **Live Board 기록 검색·필터·내보내기**: 최근 50개 작업을 검색하고 현재 표시된 공개 메타데이터만 내보냅니다.
|
|
507
|
+
- **고정 품질/비용 벤치마크**: `omnilane benchmark`는 기본적으로 dry-run이며 실제 호출에는 `--run`이 필요합니다.
|
|
508
|
+
- **엄격한 설치 검증**: CI에서 격리된 `doctor --strict --json`을 실행하고 macOS/GNU `stat` 권한 판정 차이도 수정했습니다.
|
|
509
|
+
|
|
502
510
|
## v0.13.0 새 기능
|
|
503
511
|
|
|
504
512
|
- **`long-context` 를 AA-LCR 기준으로 정렬** — Artificial Analysis 의 장문맥 추론
|
package/README.md
CHANGED
|
@@ -195,6 +195,10 @@ The reference is memory-only and disappears when the page closes. The board
|
|
|
195
195
|
binds only to `127.0.0.1`, uses a random token, and is read-only. It shows
|
|
196
196
|
`task.txt` and the public `out.txt`, but never raw worker or vendor logs.
|
|
197
197
|
|
|
198
|
+
Search and state filters apply to the latest 50 retained jobs. **Export visible**
|
|
199
|
+
downloads only the currently visible public metadata as local JSON; it excludes
|
|
200
|
+
tokens, task text, result bodies, workdirs, and raw logs.
|
|
201
|
+
|
|
198
202
|
The board reads in English, Japanese, Korean, Traditional Chinese and Simplified
|
|
199
203
|
Chinese. It follows the browser language on first load; the switcher in the
|
|
200
204
|
header overrides that and the choice is remembered locally.
|
|
@@ -255,7 +259,8 @@ adding a routing reminder. Configure the host to launch the installed CLI:
|
|
|
255
259
|
|
|
256
260
|
The server exposes `route` plus read-only introspection: `list_lanes`,
|
|
257
261
|
`explain`, `validate`, `dry_run`, `jobs_list`, `jobs_status`, `jobs_result`,
|
|
258
|
-
`jobs_stats`, `jobs_audit`,
|
|
262
|
+
`jobs_stats`, `jobs_recommend`, `jobs_audit`, `doctor`, and the explicitly opt-in
|
|
263
|
+
`provider_probe`. `route` defaults to read-only `advise` mode. Calls that select `work` must also
|
|
259
264
|
provide an explicit `workdir`.
|
|
260
265
|
|
|
261
266
|
Node.js is the only runtime requirement (no npm packages). If you prefer
|
|
@@ -299,7 +304,8 @@ omnilane ui start # start/reuse the local Live UI;
|
|
|
299
304
|
omnilane ui status # report whether the Live UI is running
|
|
300
305
|
omnilane ui url # print the current authenticated local URL
|
|
301
306
|
omnilane ui stop # stop the Live UI
|
|
302
|
-
omnilane doctor [--json]
|
|
307
|
+
omnilane doctor [--json] [--strict] [--probe V] [--probe-timeout SEC] # live probe is opt-in
|
|
308
|
+
omnilane benchmark [--json] [--run] [--vendor V] [--cost-per-call V=USD] # dry-run by default
|
|
303
309
|
dispatch.sh [--background] [--dry-run] [--mode advise|work|sysops] [--workdir DIR]
|
|
304
310
|
[--vendor V] [--model M] [--effort E] [--timeout SEC] [--job-timeout SEC]
|
|
305
311
|
LANE "TASK" # "-" reads task from stdin
|
|
@@ -312,12 +318,24 @@ jobs.sh wait ID [--timeout N] # job exit; 124 timeout; 125 d
|
|
|
312
318
|
jobs.sh cancel ID # stop a running job: group SIGTERM, then SIGKILL
|
|
313
319
|
jobs.sh rm ID # delete one finished/dead job (refuses a running job)
|
|
314
320
|
jobs.sh [--json] stats [--last N] [--lane L] [--vendor V] # local success and routing aggregates
|
|
321
|
+
jobs.sh [--json] recommend [--last N] [--lane L] [--min-samples N] # evidence-gated vendor suggestion
|
|
315
322
|
jobs.sh audit [--last N] [--json] # read-only job integrity/privacy check
|
|
316
323
|
jobs.sh prune [--keep N] [--apply] # preview by default; completed jobs only
|
|
317
324
|
configure.sh # interactive lane menu
|
|
318
325
|
configure.sh set|get|unset|list|diff LANE [SPEC] # script/inspect routing.local.yaml, no tty
|
|
319
326
|
```
|
|
320
327
|
|
|
328
|
+
`jobs recommend` reads only validated public metadata and exit codes. It ranks
|
|
329
|
+
eligible vendors by success rate, sample count, then name; the default minimum
|
|
330
|
+
is three completed jobs. It never reads task/result bodies or changes routing.
|
|
331
|
+
|
|
332
|
+
`doctor --probe V` makes one bounded advise-mode provider call and returns only
|
|
333
|
+
availability, selected model, timing, and response byte count—not the response
|
|
334
|
+
body. Without `--probe`, doctor remains offline. `benchmark` uses the fixed TSV
|
|
335
|
+
suite in `benchmarks/workloads.tsv`; its default dry-run resolves every route
|
|
336
|
+
without provider calls. `--run` is the explicit call gate, and cost totals are
|
|
337
|
+
estimates based only on values supplied with `--cost-per-call`.
|
|
338
|
+
|
|
321
339
|
**Big decisions can get a panel, not a person.** The `arbitrate` lane ships
|
|
322
340
|
**disabled** — a panel costs one call per voter per round, so it is opt-in.
|
|
323
341
|
Enable it with `arbitrate: vote codex,claude,grok -` in `routing.local.yaml`,
|
|
@@ -547,6 +565,24 @@ working notes, including per-benchmark caveats, live in
|
|
|
547
565
|
|
|
548
566
|
## 📜 Release history
|
|
549
567
|
|
|
568
|
+
## What's new in v0.14.0
|
|
569
|
+
|
|
570
|
+
- **Evidence-based routing recommendations** — `jobs recommend` and MCP
|
|
571
|
+
`jobs_recommend` rank vendors from completed public job metadata, enforce a
|
|
572
|
+
minimum sample gate, and never change routing automatically.
|
|
573
|
+
- **Opt-in live capability probes** — `doctor --probe V` and MCP
|
|
574
|
+
`provider_probe` distinguish an installed CLI from a working provider call.
|
|
575
|
+
Default doctor remains offline; probe reports never include response bodies.
|
|
576
|
+
- **Search, filter, and export Live Board history** — search and state filters
|
|
577
|
+
cover the latest 50 jobs, while **Export visible** downloads only filtered
|
|
578
|
+
public metadata.
|
|
579
|
+
- **Repeatable quality/cost benchmark** — `omnilane benchmark` ships a fixed
|
|
580
|
+
workload suite, defaults to provider-free dry-run, and requires `--run` for
|
|
581
|
+
actual calls. Cost estimates use only explicit `--cost-per-call` values.
|
|
582
|
+
- **Strict installation acceptance** — CI runs isolated
|
|
583
|
+
`omnilane doctor --strict --json`, catching incomplete runtime wiring without
|
|
584
|
+
contacting providers.
|
|
585
|
+
|
|
550
586
|
## What's new in v0.13.0
|
|
551
587
|
|
|
552
588
|
- **`long-context` is ordered on AA-LCR** — Artificial Analysis's long-context
|
package/README.zh-CN.md
CHANGED
|
@@ -473,6 +473,14 @@ vendor 一律当成 `work`,而且它只能逐次明确指定,永远不是 lane
|
|
|
473
473
|
|
|
474
474
|
## 📜 版本历程
|
|
475
475
|
|
|
476
|
+
## v0.14.0 新功能
|
|
477
|
+
|
|
478
|
+
- **基于证据的路由建议**:`jobs recommend` 与 MCP `jobs_recommend` 只读取公开作业元数据,并且不会自动修改路由。
|
|
479
|
+
- **可选的真实能力探测**:`doctor --probe V` 与 MCP `provider_probe` 仅在明确请求时调用供应商,报告不包含回答正文。
|
|
480
|
+
- **Live Board 历史搜索、筛选与导出**:支持最近 50 条作业,并且只导出当前可见的公开元数据。
|
|
481
|
+
- **固定质量/成本基准**:`omnilane benchmark` 默认只做 dry-run,`--run` 才实际调用供应商。
|
|
482
|
+
- **严格安装验收**:CI 在隔离环境执行 `doctor --strict --json`,并修正 macOS/GNU `stat` 权限检测差异。
|
|
483
|
+
|
|
476
484
|
## v0.13.0 新功能
|
|
477
485
|
|
|
478
486
|
- **`long-context` 改用 AA-LCR 排序**——那是 Artificial Analysis 的长脉络推理基准,
|
package/README.zh-TW.md
CHANGED
|
@@ -178,6 +178,9 @@ omnilane ui stop # 正常停止
|
|
|
178
178
|
`127.0.0.1`、用隨機 token 保護、全程唯讀。畫面只顯示 `task.txt` 與公開的
|
|
179
179
|
`out.txt`,不顯示工作端或廠商原始 log。
|
|
180
180
|
|
|
181
|
+
搜尋與狀態篩選會套用到最近保留的 50 筆工作歷史。按「匯出目前結果」只會把畫面上
|
|
182
|
+
目前可見的公開中繼資料下載成 JSON;不含 token、任務本文、結果本文、工作目錄與原始 log。
|
|
183
|
+
|
|
181
184
|
畫面提供英文、日文、韓文、繁體中文與簡體中文。首次載入依瀏覽器語言決定,可用標題列
|
|
182
185
|
的切換器覆寫,選擇會記在本機。
|
|
183
186
|
|
|
@@ -228,7 +231,7 @@ omnilane ui stop # 正常停止
|
|
|
228
231
|
}
|
|
229
232
|
```
|
|
230
233
|
|
|
231
|
-
Server 提供 `route`,以及一組唯讀查詢工具:`list_lanes`、`explain`、`validate`、`dry_run`、`jobs_list`、`jobs_status`、`jobs_result`、`jobs_stats`、`jobs_audit`、`doctor`。
|
|
234
|
+
Server 提供 `route`,以及一組唯讀查詢工具:`list_lanes`、`explain`、`validate`、`dry_run`、`jobs_list`、`jobs_status`、`jobs_result`、`jobs_stats`、`jobs_recommend`、`jobs_audit`、`doctor`,以及必須明確選用的 `provider_probe`。
|
|
232
235
|
`route` 預設唯讀 `advise` 模式;選 `work` 的呼叫必須同時提供明確的
|
|
233
236
|
`workdir`。
|
|
234
237
|
|
|
@@ -266,7 +269,8 @@ omnilane ui start # 啟動或沿用本機 Live UI,
|
|
|
266
269
|
omnilane ui status # 查看 Live UI 是否運作中
|
|
267
270
|
omnilane ui url # 印出目前通過驗證的本機網址
|
|
268
271
|
omnilane ui stop # 停止 Live UI
|
|
269
|
-
omnilane doctor [--json]
|
|
272
|
+
omnilane doctor [--json] [--strict] [--probe V] [--probe-timeout SEC] # 實際探測必須明確選用
|
|
273
|
+
omnilane benchmark [--json] [--run] [--vendor V] [--cost-per-call V=USD] # 預設只乾跑
|
|
270
274
|
dispatch.sh [--background] [--dry-run] [--mode advise|work|sysops] [--workdir 目錄]
|
|
271
275
|
[--vendor V] [--model M] [--effort E] [--timeout SEC] [--job-timeout SEC]
|
|
272
276
|
通道 "任務" # "-" 表示從 stdin 讀任務
|
|
@@ -279,6 +283,7 @@ jobs.sh wait 工作ID [--timeout N] # 工作結束碼;124 逾
|
|
|
279
283
|
jobs.sh cancel 工作ID # 停止執行中的工作:整組 SIGTERM,再 SIGKILL
|
|
280
284
|
jobs.sh rm 工作ID # 刪除單一已完成/已死工作(執行中會被拒絕)
|
|
281
285
|
jobs.sh [--json] stats [--last N] [--lane L] [--vendor V] # 本機成功率與路由彙整
|
|
286
|
+
jobs.sh [--json] recommend [--last N] [--lane L] [--min-samples N] # 有證據門檻的廠商建議
|
|
282
287
|
jobs.sh audit [--last N] [--json] # 唯讀檢查工作完整性與隱私
|
|
283
288
|
jobs.sh prune [--keep N] [--apply] # 預設只預覽;只清理已完成工作
|
|
284
289
|
omnilane mcp # MCP stdio server(需 Node.js)
|
|
@@ -287,6 +292,15 @@ configure.sh # 互動通道選單
|
|
|
287
292
|
configure.sh set|get|unset|list|diff LANE [SPEC] # 非互動編輯/檢視 routing.local.yaml
|
|
288
293
|
```
|
|
289
294
|
|
|
295
|
+
`jobs recommend` 只讀取通過驗證的公開中繼資料與退出碼。候選達到最低樣本數後,
|
|
296
|
+
依成功率、樣本數、廠商名稱排序;預設至少三筆已完成工作。它不讀任務/結果本文,
|
|
297
|
+
也不修改路由。
|
|
298
|
+
|
|
299
|
+
`doctor --probe V` 只會做一次有逾時上限的 advise 模式供應商呼叫,回傳可用性、
|
|
300
|
+
選到的模型、耗時與回應位元組數,不回傳回答本文;未帶 `--probe` 時仍完全離線。
|
|
301
|
+
`benchmark` 使用 `benchmarks/workloads.tsv` 的固定題組,預設只解析路由、不呼叫供應商;
|
|
302
|
+
`--run` 才是實際呼叫閘門,成本總額也只依 `--cost-per-call` 明確提供的估值計算。
|
|
303
|
+
|
|
290
304
|
**重大決定可以開評審團,不是問一個人。**`arbitrate` 通道**預設關閉**——
|
|
291
305
|
評審團每評審每輪燒一次額度,所以做成選配。要用就在 `routing.local.yaml`
|
|
292
306
|
寫 `arbitrate: vote codex,claude,grok -`,或跑設定選單,從
|
|
@@ -483,6 +497,19 @@ vendor 一律當成 `work`,而且它只能逐次明確指定,永遠不是 lane
|
|
|
483
497
|
|
|
484
498
|
## 📜 版本歷程
|
|
485
499
|
|
|
500
|
+
## v0.14.0 新功能
|
|
501
|
+
|
|
502
|
+
- **依證據產生路由建議**:`jobs recommend` 與 MCP `jobs_recommend` 只用已完成工作的
|
|
503
|
+
公開中繼資料排序供應商,設有最低樣本門檻,也不會自動修改路由。
|
|
504
|
+
- **選配實際能力探測**:`doctor --probe V` 與 MCP `provider_probe` 可分辨「CLI 已安裝」
|
|
505
|
+
和「供應商呼叫真的可用」。doctor 預設仍離線,探測報告不含回答本文。
|
|
506
|
+
- **Live Board 歷史搜尋、篩選與匯出**:搜尋與狀態篩選涵蓋最近 50 筆工作;
|
|
507
|
+
「匯出目前結果」只下載篩選後的公開中繼資料。
|
|
508
|
+
- **可重現的品質/成本基準**:`omnilane benchmark` 內建固定題組,預設不呼叫供應商;
|
|
509
|
+
`--run` 才會實際執行,成本也只依明確提供的 `--cost-per-call` 估值計算。
|
|
510
|
+
- **嚴格安裝驗收**:CI 以隔離環境執行 `omnilane doctor --strict --json`,
|
|
511
|
+
不接觸供應商也能抓出 runtime 接線不完整。
|
|
512
|
+
|
|
486
513
|
## v0.13.0 新功能
|
|
487
514
|
|
|
488
515
|
- **`long-context` 改用 AA-LCR 排序**——那是 Artificial Analysis 的長脈絡推理基準,
|
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.
|
|
1
|
+
0.14.0
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
# id<TAB>preferred_lane<TAB>weight<TAB>Python regex<TAB>prompt
|
|
2
|
+
exact_alpha consult 1 ^ALPHA\s*$ Return exactly ALPHA and nothing else.
|
|
3
|
+
arithmetic consult 2 ^42\s*$ Return only the integer result of 17 + 25.
|
|
4
|
+
json_contract hard-judgment 2 ^\{"status":"pass","count":3\}\s*$ Return exactly this compact JSON object with the stated key order: {"status":"pass","count":3}
|
package/bin/omnilane
CHANGED
|
@@ -52,6 +52,13 @@ case "$cmd" in
|
|
|
52
52
|
;;
|
|
53
53
|
release-audit) exec bash "$REPO/scripts/release-audit.sh" "$@" ;;
|
|
54
54
|
doctor) exec bash "$REPO/scripts/doctor.sh" "$@" ;;
|
|
55
|
+
benchmark)
|
|
56
|
+
command -v python3 >/dev/null 2>&1 || {
|
|
57
|
+
echo "omnilane: benchmark requires Python 3.9 or newer" >&2
|
|
58
|
+
exit 1
|
|
59
|
+
}
|
|
60
|
+
exec python3 "$REPO/scripts/benchmark.py" "$@"
|
|
61
|
+
;;
|
|
55
62
|
ui)
|
|
56
63
|
command -v python3 >/dev/null 2>&1 || {
|
|
57
64
|
echo "omnilane: ui requires Python 3.9 or newer" >&2
|
|
@@ -68,11 +75,12 @@ omnilane — one routing table, every harness
|
|
|
68
75
|
omnilane list effective routing table
|
|
69
76
|
omnilane route [--vendor V] [flags] LANE "TASK"
|
|
70
77
|
dispatch or consult a model
|
|
71
|
-
omnilane jobs [--json] COMMAND [ARGS] list, status, result, stats, wait, or audit
|
|
78
|
+
omnilane jobs [--json] COMMAND [ARGS] list, status, result, stats, recommend, wait, or audit
|
|
72
79
|
omnilane mcp start the MCP stdio server
|
|
73
80
|
omnilane completion bash|zsh|fish print a shell completion script
|
|
74
81
|
omnilane release-audit [flags] offline, read-only release gate
|
|
75
|
-
omnilane doctor [--json]
|
|
82
|
+
omnilane doctor [--json] [--strict] [--probe V] local health / opt-in live probe
|
|
83
|
+
omnilane benchmark [--json] [--run] [--vendor V] fixed quality/cost comparison
|
|
76
84
|
omnilane ui start|status|url|stop
|
|
77
85
|
omnilane configure interactive lane menu
|
|
78
86
|
EOF
|
package/bin/omnilane-mcp
CHANGED
|
@@ -10,6 +10,8 @@ const ROOT = path.resolve(__dirname, '..');
|
|
|
10
10
|
const DISPATCH_SCRIPT = path.join(ROOT, 'scripts', 'dispatch.sh');
|
|
11
11
|
const JOBS_SCRIPT = path.join(ROOT, 'scripts', 'jobs.sh');
|
|
12
12
|
const DOCTOR_SCRIPT = path.join(ROOT, 'scripts', 'doctor.sh');
|
|
13
|
+
const PROVIDER_PROBE_SCRIPT = process.env.OMNILANE_PROVIDER_PROBE_SCRIPT ||
|
|
14
|
+
path.join(ROOT, 'scripts', 'provider-probe.sh');
|
|
13
15
|
const LATEST_PROTOCOL_VERSION = '2025-11-25';
|
|
14
16
|
const SUPPORTED_PROTOCOL_VERSIONS = new Set([
|
|
15
17
|
'2025-11-25',
|
|
@@ -285,6 +287,37 @@ const tools = [
|
|
|
285
287
|
openWorldHint: false,
|
|
286
288
|
},
|
|
287
289
|
},
|
|
290
|
+
{
|
|
291
|
+
name: 'provider_probe',
|
|
292
|
+
description: 'Explicitly invoke one configured provider with a bounded fixed prompt to verify live inference. Incurs one provider call; never returns the provider response.',
|
|
293
|
+
inputSchema: {
|
|
294
|
+
type: 'object',
|
|
295
|
+
required: ['vendor'],
|
|
296
|
+
properties: {
|
|
297
|
+
vendor: {
|
|
298
|
+
type: 'string',
|
|
299
|
+
enum: ['codex', 'claude', 'grok', 'gemini', 'kimi', 'qwen', 'opencode', 'openrouter', 'deepseek', 'zai', 'mistral', 'groq', 'cerebras'],
|
|
300
|
+
},
|
|
301
|
+
timeout: {
|
|
302
|
+
type: 'integer',
|
|
303
|
+
minimum: 1,
|
|
304
|
+
maximum: 300,
|
|
305
|
+
default: 30,
|
|
306
|
+
},
|
|
307
|
+
json: {
|
|
308
|
+
type: 'boolean',
|
|
309
|
+
default: true,
|
|
310
|
+
},
|
|
311
|
+
},
|
|
312
|
+
additionalProperties: false,
|
|
313
|
+
},
|
|
314
|
+
annotations: {
|
|
315
|
+
readOnlyHint: true,
|
|
316
|
+
destructiveHint: false,
|
|
317
|
+
idempotentHint: false,
|
|
318
|
+
openWorldHint: true,
|
|
319
|
+
},
|
|
320
|
+
},
|
|
288
321
|
{
|
|
289
322
|
name: 'jobs_stats',
|
|
290
323
|
description: 'Aggregate local background-job outcomes and lane/vendor distribution from bounded public metadata. Never reads task or result bodies.',
|
|
@@ -311,6 +344,45 @@ const tools = [
|
|
|
311
344
|
openWorldHint: false,
|
|
312
345
|
},
|
|
313
346
|
},
|
|
347
|
+
{
|
|
348
|
+
name: 'jobs_recommend',
|
|
349
|
+
description: 'Recommend a vendor per lane from bounded local completed-job outcomes. Read-only, evidence-gated, and never reads task or result bodies.',
|
|
350
|
+
inputSchema: {
|
|
351
|
+
type: 'object',
|
|
352
|
+
properties: {
|
|
353
|
+
last: {
|
|
354
|
+
type: 'integer',
|
|
355
|
+
minimum: 1,
|
|
356
|
+
maximum: 10000,
|
|
357
|
+
description: 'Limit analysis to the most recent N jobs.',
|
|
358
|
+
},
|
|
359
|
+
lane: {
|
|
360
|
+
type: 'string',
|
|
361
|
+
pattern: '^[a-z][a-z0-9-]*$',
|
|
362
|
+
description: 'Optionally analyze one lane.',
|
|
363
|
+
},
|
|
364
|
+
min_samples: {
|
|
365
|
+
type: 'integer',
|
|
366
|
+
minimum: 1,
|
|
367
|
+
maximum: 1000,
|
|
368
|
+
default: 3,
|
|
369
|
+
description: 'Completed samples required before a vendor is eligible for recommendation.',
|
|
370
|
+
},
|
|
371
|
+
json: {
|
|
372
|
+
type: 'boolean',
|
|
373
|
+
default: false,
|
|
374
|
+
description: 'Return the versioned JSON envelope instead of the human report.',
|
|
375
|
+
},
|
|
376
|
+
},
|
|
377
|
+
additionalProperties: false,
|
|
378
|
+
},
|
|
379
|
+
annotations: {
|
|
380
|
+
readOnlyHint: true,
|
|
381
|
+
destructiveHint: false,
|
|
382
|
+
idempotentHint: true,
|
|
383
|
+
openWorldHint: false,
|
|
384
|
+
},
|
|
385
|
+
},
|
|
314
386
|
{
|
|
315
387
|
name: 'jobs_audit',
|
|
316
388
|
description: 'Bounded read-only integrity and privacy scan of the local job store. Reports findings without printing task or result content.',
|
|
@@ -435,6 +507,24 @@ function validateJsonOnlyArguments(args) {
|
|
|
435
507
|
return null;
|
|
436
508
|
}
|
|
437
509
|
|
|
510
|
+
function validateProviderProbeArguments(args) {
|
|
511
|
+
const error = validationError(args, ['vendor', 'timeout', 'json']);
|
|
512
|
+
if (error) return error;
|
|
513
|
+
const vendors = new Set([
|
|
514
|
+
'codex', 'claude', 'grok', 'gemini', 'kimi', 'qwen', 'opencode',
|
|
515
|
+
'openrouter', 'deepseek', 'zai', 'mistral', 'groq', 'cerebras',
|
|
516
|
+
]);
|
|
517
|
+
if (typeof args.vendor !== 'string' || !vendors.has(args.vendor)) {
|
|
518
|
+
return 'vendor must name one probe-capable provider';
|
|
519
|
+
}
|
|
520
|
+
if (OWN(args, 'timeout') &&
|
|
521
|
+
(!Number.isInteger(args.timeout) || args.timeout < 1 || args.timeout > 300)) {
|
|
522
|
+
return 'timeout must be an integer from 1 to 300';
|
|
523
|
+
}
|
|
524
|
+
if (OWN(args, 'json') && typeof args.json !== 'boolean') return 'json must be a boolean';
|
|
525
|
+
return null;
|
|
526
|
+
}
|
|
527
|
+
|
|
438
528
|
function validateJobsQueryArguments(args) {
|
|
439
529
|
const error = validationError(args, ['last', 'json']);
|
|
440
530
|
if (error) return error;
|
|
@@ -445,6 +535,23 @@ function validateJobsQueryArguments(args) {
|
|
|
445
535
|
return null;
|
|
446
536
|
}
|
|
447
537
|
|
|
538
|
+
function validateJobsRecommendArguments(args) {
|
|
539
|
+
const error = validationError(args, ['last', 'lane', 'min_samples', 'json']);
|
|
540
|
+
if (error) return error;
|
|
541
|
+
if (OWN(args, 'last') && (!Number.isInteger(args.last) || args.last < 1 || args.last > 10000)) {
|
|
542
|
+
return 'last must be an integer from 1 to 10000';
|
|
543
|
+
}
|
|
544
|
+
if (OWN(args, 'lane') && (typeof args.lane !== 'string' || !LANE_PATTERN.test(args.lane))) {
|
|
545
|
+
return 'lane must match ^[a-z][a-z0-9-]*$';
|
|
546
|
+
}
|
|
547
|
+
if (OWN(args, 'min_samples') &&
|
|
548
|
+
(!Number.isInteger(args.min_samples) || args.min_samples < 1 || args.min_samples > 1000)) {
|
|
549
|
+
return 'min_samples must be an integer from 1 to 1000';
|
|
550
|
+
}
|
|
551
|
+
if (OWN(args, 'json') && typeof args.json !== 'boolean') return 'json must be a boolean';
|
|
552
|
+
return null;
|
|
553
|
+
}
|
|
554
|
+
|
|
448
555
|
function validateExplainArguments(args) {
|
|
449
556
|
const error = validationError(args, ['lane', 'json']);
|
|
450
557
|
if (error) return error;
|
|
@@ -645,6 +752,14 @@ async function callTool(name, args) {
|
|
|
645
752
|
const argv = args.json === true ? ['--json'] : [];
|
|
646
753
|
return runToolScript('doctor', DOCTOR_SCRIPT, argv);
|
|
647
754
|
}
|
|
755
|
+
if (name === 'provider_probe') {
|
|
756
|
+
const error = validateProviderProbeArguments(args);
|
|
757
|
+
if (error) return toolError(error);
|
|
758
|
+
const argv = ['--vendor', args.vendor];
|
|
759
|
+
if (OWN(args, 'timeout')) argv.push('--timeout', String(args.timeout));
|
|
760
|
+
if (args.json !== false) argv.push('--json');
|
|
761
|
+
return runToolScript('provider_probe', PROVIDER_PROBE_SCRIPT, argv);
|
|
762
|
+
}
|
|
648
763
|
if (name === 'jobs_stats' || name === 'jobs_audit') {
|
|
649
764
|
const error = validateJobsQueryArguments(args);
|
|
650
765
|
if (error) return toolError(error);
|
|
@@ -654,6 +769,17 @@ async function callTool(name, args) {
|
|
|
654
769
|
if (OWN(args, 'last')) argv.push('--last', String(args.last));
|
|
655
770
|
return runToolScript(name, JOBS_SCRIPT, argv);
|
|
656
771
|
}
|
|
772
|
+
if (name === 'jobs_recommend') {
|
|
773
|
+
const error = validateJobsRecommendArguments(args);
|
|
774
|
+
if (error) return toolError(error);
|
|
775
|
+
const argv = [];
|
|
776
|
+
if (args.json === true) argv.push('--json');
|
|
777
|
+
argv.push('recommend');
|
|
778
|
+
if (OWN(args, 'last')) argv.push('--last', String(args.last));
|
|
779
|
+
if (OWN(args, 'lane')) argv.push('--lane', args.lane);
|
|
780
|
+
if (OWN(args, 'min_samples')) argv.push('--min-samples', String(args.min_samples));
|
|
781
|
+
return runToolScript(name, JOBS_SCRIPT, argv);
|
|
782
|
+
}
|
|
657
783
|
throw new RpcError(-32602, `Unknown tool: ${name}`);
|
|
658
784
|
}
|
|
659
785
|
|
package/completions/_omnilane
CHANGED
|
@@ -53,7 +53,7 @@ _omnilane() {
|
|
|
53
53
|
local command="${words[2]:-}" sub sub_index=3
|
|
54
54
|
local -a lanes ids
|
|
55
55
|
if (( CURRENT == 2 )); then
|
|
56
|
-
_values 'command' version list route dispatch jobs doctor release-audit ui configure completion help
|
|
56
|
+
_values 'command' version list route dispatch jobs doctor benchmark release-audit ui configure completion help
|
|
57
57
|
return
|
|
58
58
|
fi
|
|
59
59
|
case "$command" in
|
|
@@ -78,7 +78,7 @@ _omnilane() {
|
|
|
78
78
|
sub="${words[4]:-}"
|
|
79
79
|
fi
|
|
80
80
|
if (( CURRENT == sub_index )); then
|
|
81
|
-
_values 'job command' list status result tail retry stats wait audit prune help
|
|
81
|
+
_values 'job command' list status result tail retry stats recommend wait audit prune help
|
|
82
82
|
elif (( CURRENT == sub_index + 1 )) &&
|
|
83
83
|
[[ "$sub" == status || "$sub" == result || "$sub" == wait ||
|
|
84
84
|
"$sub" == tail || "$sub" == retry ]]; then
|
|
@@ -92,7 +92,13 @@ _omnilane() {
|
|
|
92
92
|
_arguments '--background[re-dispatch in the background]'
|
|
93
93
|
elif [[ "$sub" == wait ]]; then
|
|
94
94
|
_arguments '--timeout[maximum wait seconds]:seconds:'
|
|
95
|
-
elif [[ "$sub" == stats
|
|
95
|
+
elif [[ "$sub" == stats ]]; then
|
|
96
|
+
_arguments '--last[maximum jobs]:count:' '--lane[filter by lane]:lane:' \
|
|
97
|
+
'--vendor[filter by vendor]:vendor:' '--json[versioned metadata output]'
|
|
98
|
+
elif [[ "$sub" == recommend ]]; then
|
|
99
|
+
_arguments '--last[maximum jobs]:count:' '--lane[filter by lane]:lane:' \
|
|
100
|
+
'--min-samples[minimum completed samples]:count:' '--json[versioned metadata output]'
|
|
101
|
+
elif [[ "$sub" == audit ]]; then
|
|
96
102
|
_arguments '--last[maximum jobs]:count:' '--json[versioned metadata output]'
|
|
97
103
|
elif [[ "$sub" == prune ]]; then
|
|
98
104
|
_arguments '--keep[completed jobs to retain]:count:' \
|
|
@@ -100,7 +106,18 @@ _omnilane() {
|
|
|
100
106
|
'--apply[delete eligible jobs]'
|
|
101
107
|
fi
|
|
102
108
|
;;
|
|
103
|
-
doctor)
|
|
109
|
+
doctor)
|
|
110
|
+
_arguments '--json[versioned JSON output]' '--strict[fail on warnings]' \
|
|
111
|
+
'--probe[run one opt-in live provider probe]:vendor:' \
|
|
112
|
+
'--probe-timeout[probe timeout in seconds]:seconds:'
|
|
113
|
+
;;
|
|
114
|
+
benchmark)
|
|
115
|
+
_arguments '--json[versioned JSON output]' '--run[invoke providers in advise mode]' \
|
|
116
|
+
'*--vendor[vendor to compare]:vendor:(codex claude grok gemini kimi qwen opencode openrouter deepseek zai mistral groq cerebras)' \
|
|
117
|
+
'--timeout[per-workload timeout]:seconds:' \
|
|
118
|
+
'--workloads[TSV workload file]:file:_files' \
|
|
119
|
+
'*--cost-per-call[user-supplied vendor USD estimate]:vendor=USD:'
|
|
120
|
+
;;
|
|
104
121
|
release-audit)
|
|
105
122
|
_arguments '--target[release version]:version:' '--allow-dirty[permit a dirty worktree]' \
|
|
106
123
|
'--require-tag[require an annotated tag at HEAD]' '--manifest[include tracked inventory]' \
|
|
@@ -58,7 +58,7 @@ _omnilane() {
|
|
|
58
58
|
prev="${COMP_WORDS[COMP_CWORD-1]:-}"
|
|
59
59
|
command="${COMP_WORDS[1]:-}"
|
|
60
60
|
if [[ "$COMP_CWORD" -eq 1 ]]; then
|
|
61
|
-
|
|
61
|
+
words="version list route dispatch jobs doctor benchmark release-audit ui configure completion help"
|
|
62
62
|
else
|
|
63
63
|
case "$command" in
|
|
64
64
|
route|dispatch)
|
|
@@ -84,7 +84,7 @@ _omnilane() {
|
|
|
84
84
|
sub="${COMP_WORDS[3]:-}"
|
|
85
85
|
fi
|
|
86
86
|
if [[ "$COMP_CWORD" -eq "$sub_index" ]]; then
|
|
87
|
-
words="list status result tail retry stats wait audit prune help"
|
|
87
|
+
words="list status result tail retry stats recommend wait audit prune help"
|
|
88
88
|
elif [[ "$COMP_CWORD" -eq $((sub_index + 1)) &&
|
|
89
89
|
( "$sub" == status || "$sub" == result || "$sub" == wait ||
|
|
90
90
|
"$sub" == tail || "$sub" == retry ) ]]; then
|
|
@@ -99,7 +99,11 @@ _omnilane() {
|
|
|
99
99
|
words="--background"
|
|
100
100
|
elif [[ "$sub" == wait ]]; then
|
|
101
101
|
words="--timeout"
|
|
102
|
-
elif [[ "$sub" == stats
|
|
102
|
+
elif [[ "$sub" == stats ]]; then
|
|
103
|
+
words="--last --lane --vendor --json"
|
|
104
|
+
elif [[ "$sub" == recommend ]]; then
|
|
105
|
+
words="--last --lane --min-samples --json"
|
|
106
|
+
elif [[ "$sub" == audit ]]; then
|
|
103
107
|
words="--last --json"
|
|
104
108
|
elif [[ "$sub" == prune ]]; then
|
|
105
109
|
words="--keep --older-than --apply"
|
|
@@ -107,7 +111,18 @@ _omnilane() {
|
|
|
107
111
|
return
|
|
108
112
|
fi
|
|
109
113
|
;;
|
|
110
|
-
doctor) words="--json" ;;
|
|
114
|
+
doctor) words="--json --strict --probe --probe-timeout" ;;
|
|
115
|
+
benchmark)
|
|
116
|
+
case "$prev" in
|
|
117
|
+
--vendor) words="codex claude grok gemini kimi qwen opencode openrouter deepseek zai mistral groq cerebras" ;;
|
|
118
|
+
--workloads)
|
|
119
|
+
COMPREPLY=( $(compgen -f -- "$cur") )
|
|
120
|
+
return
|
|
121
|
+
;;
|
|
122
|
+
--timeout|--cost-per-call) return ;;
|
|
123
|
+
*) words="--json --run --vendor --timeout --workloads --cost-per-call" ;;
|
|
124
|
+
esac
|
|
125
|
+
;;
|
|
111
126
|
release-audit) words="--target --allow-dirty --require-tag --manifest --json" ;;
|
|
112
127
|
ui) words="start status url stop" ;;
|
|
113
128
|
completion) words="bash zsh" ;;
|
|
@@ -10,6 +10,7 @@ complete -c omnilane -f -n __fish_use_subcommand -a dispatch -d 'dispatch o
|
|
|
10
10
|
complete -c omnilane -f -n __fish_use_subcommand -a jobs -d 'inspect background jobs'
|
|
11
11
|
complete -c omnilane -f -n __fish_use_subcommand -a mcp -d 'MCP stdio server'
|
|
12
12
|
complete -c omnilane -f -n __fish_use_subcommand -a doctor -d 'read-only health report'
|
|
13
|
+
complete -c omnilane -f -n __fish_use_subcommand -a benchmark -d 'fixed quality/cost comparison'
|
|
13
14
|
complete -c omnilane -f -n __fish_use_subcommand -a release-audit -d 'offline release gate'
|
|
14
15
|
complete -c omnilane -f -n __fish_use_subcommand -a ui -d 'Live Board server'
|
|
15
16
|
complete -c omnilane -f -n __fish_use_subcommand -a configure -d 'lane routing (menu or set/get/unset/list/diff)'
|
|
@@ -29,19 +30,30 @@ complete -c omnilane -n '__fish_seen_subcommand_from route dispatch' -l dry-run
|
|
|
29
30
|
|
|
30
31
|
# jobs subcommands (only before a jobs subcommand is chosen).
|
|
31
32
|
complete -c omnilane -f \
|
|
32
|
-
-n '__fish_seen_subcommand_from jobs; and not __fish_seen_subcommand_from list status result tail retry stats wait audit prune cancel rm help' \
|
|
33
|
-
-a 'list status result tail retry stats wait audit prune cancel rm help' -d 'jobs subcommand'
|
|
33
|
+
-n '__fish_seen_subcommand_from jobs; and not __fish_seen_subcommand_from list status result tail retry stats recommend wait audit prune cancel rm help' \
|
|
34
|
+
-a 'list status result tail retry stats recommend wait audit prune cancel rm help' -d 'jobs subcommand'
|
|
34
35
|
complete -c omnilane -n '__fish_seen_subcommand_from jobs' -l json -d 'JSON output'
|
|
35
36
|
# jobs list / stats filters.
|
|
36
|
-
complete -c omnilane -n '__fish_seen_subcommand_from jobs; and __fish_seen_subcommand_from list stats' -l lane
|
|
37
|
+
complete -c omnilane -n '__fish_seen_subcommand_from jobs; and __fish_seen_subcommand_from list stats recommend' -l lane -x -d 'filter by lane'
|
|
37
38
|
complete -c omnilane -n '__fish_seen_subcommand_from jobs; and __fish_seen_subcommand_from list stats' -l vendor -x -a 'codex claude grok gemini kimi qwen opencode openrouter deepseek zai mistral groq cerebras exec' -d 'filter by vendor'
|
|
38
39
|
complete -c omnilane -n '__fish_seen_subcommand_from jobs; and __fish_seen_subcommand_from list' -l status -x -a 'running done' -d 'filter by status'
|
|
40
|
+
complete -c omnilane -n '__fish_seen_subcommand_from jobs; and __fish_seen_subcommand_from stats recommend audit' -l last -x -d 'maximum recent jobs'
|
|
41
|
+
complete -c omnilane -n '__fish_seen_subcommand_from jobs; and __fish_seen_subcommand_from recommend' -l min-samples -x -d 'minimum completed samples'
|
|
39
42
|
|
|
40
43
|
# configure subcommands (non-interactive).
|
|
41
44
|
complete -c omnilane -f -n '__fish_seen_subcommand_from configure; and not __fish_seen_subcommand_from set get unset list diff' -a 'set get unset list diff' -d 'configure action'
|
|
42
45
|
|
|
43
46
|
# doctor / release-audit / ui / completion.
|
|
44
47
|
complete -c omnilane -n '__fish_seen_subcommand_from doctor' -l json -d 'JSON output'
|
|
48
|
+
complete -c omnilane -n '__fish_seen_subcommand_from doctor' -l strict -d 'fail when any warning is reported'
|
|
49
|
+
complete -c omnilane -n '__fish_seen_subcommand_from doctor' -l probe -x -a 'codex claude grok gemini kimi qwen opencode openrouter deepseek zai mistral groq cerebras' -d 'run one opt-in live probe'
|
|
50
|
+
complete -c omnilane -n '__fish_seen_subcommand_from doctor' -l probe-timeout -x -d 'probe timeout in seconds'
|
|
51
|
+
complete -c omnilane -n '__fish_seen_subcommand_from benchmark' -l json -d 'JSON output'
|
|
52
|
+
complete -c omnilane -n '__fish_seen_subcommand_from benchmark' -l run -d 'invoke providers in advise mode'
|
|
53
|
+
complete -c omnilane -n '__fish_seen_subcommand_from benchmark' -l vendor -x -a 'codex claude grok gemini kimi qwen opencode openrouter deepseek zai mistral groq cerebras' -d 'vendor to compare; repeatable'
|
|
54
|
+
complete -c omnilane -n '__fish_seen_subcommand_from benchmark' -l timeout -x -d 'per-workload timeout'
|
|
55
|
+
complete -c omnilane -n '__fish_seen_subcommand_from benchmark' -l workloads -r -d 'TSV workload file'
|
|
56
|
+
complete -c omnilane -n '__fish_seen_subcommand_from benchmark' -l cost-per-call -x -d 'user-supplied VENDOR=USD estimate'
|
|
45
57
|
complete -c omnilane -n '__fish_seen_subcommand_from release-audit' -l target -x -d 'target version'
|
|
46
58
|
complete -c omnilane -n '__fish_seen_subcommand_from release-audit' -l allow-dirty -d 'permit a dirty tree'
|
|
47
59
|
complete -c omnilane -n '__fish_seen_subcommand_from release-audit' -l require-tag -d 'require an annotated tag'
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "omnilane",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.14.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"
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
"!scripts/__pycache__",
|
|
12
12
|
"!**/*.pyc",
|
|
13
13
|
"completions/",
|
|
14
|
+
"benchmarks/",
|
|
14
15
|
"ui/",
|
|
15
16
|
"routing.yaml",
|
|
16
17
|
"routing.local.yaml.example",
|