docks-kit 0.18.0 → 0.19.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/AGENTS.md +8 -6
- package/README.md +7 -7
- package/cli/docs/flags.md +2 -2
- package/cli/docs/models.md +16 -7
- package/cli/docs/omp-models.md +16 -3
- package/cli/docs/sync-layers.md +1 -1
- package/cli/docs/toolchain.md +10 -0
- package/cli/src/commands/harnesses.ts +2 -2
- package/cli/src/commands/model.ts +5 -2
- package/cli/src/commands/models.ts +50 -23
- package/cli/src/commands/toolchain.ts +29 -18
- package/cli/src/engine-native/harnesses.ts +52 -78
- package/cli/src/engine-native/index.ts +1 -1
- package/cli/src/engine-native/kitDb.ts +250 -0
- package/cli/src/engine-native/liveModels.ts +263 -0
- package/cli/src/engine-native/models.ts +32 -26
- package/cli/src/engine-native/modes.ts +15 -10
- package/cli/src/engine-native/parseArgs.ts +3 -2
- package/cli/src/engine-native/parseModifiers.ts +8 -5
- package/cli/src/engine-native/sharedTypes.d.ts +19 -0
- package/cli/src/engine-native/syncDispatch.ts +1 -1
- package/cli/src/engine-native/toolchain.ts +161 -2
- package/cli/src/generated/sotPayload.ts +5 -5
- package/package.json +1 -1
package/AGENTS.md
CHANGED
|
@@ -35,12 +35,14 @@ launcher can fall back to Bun source.
|
|
|
35
35
|
| `cli/src/commands/omp.ts` | `docks-kit omp` session launcher: renders the free-model run overlay and forwards args to omp |
|
|
36
36
|
| `cli/src/engine-native/ompOverlay.ts` | Free-model overlay render plus catalog parse and thinking-ceiling helpers |
|
|
37
37
|
| `cli/src/engine-native/<axis>.ts` | One change axis per file: `codexConfig`/`codexHooks`/`codexPlugins`/`codexStatus`, `claudeSettings`/`claudeRemovals`/`claudePluginPasses`/`claudeOptionalPlugins`/`claudeLsp`, `parseModifiers`/`parseHelp`, `ompFileDeploy`/`ompMarketplace`/`ompPlugins`, `skillsManifest`/`skillsLinks`/`skillsInstall`/`skillsPrune`, `engineCtx`/`syncConcurrency`/`syncDispatch`; orchestrators keep prior exports |
|
|
38
|
-
| `cli/src/engine-native/sharedTypes.d.ts` | Single definition per shared shape (manifest records, settings edits, omp session model, scalar modifier flags) |
|
|
38
|
+
| `cli/src/engine-native/sharedTypes.d.ts` | Single definition per shared shape (manifest records, settings edits, omp session model, scalar modifier flags, resolved model catalog) |
|
|
39
|
+
| `cli/src/engine-native/kitDb.ts` | Only opener of the SQLite store `~/.docks-kit/kit.db`: append-only migrations, one-time `state.json` import, TTL cache |
|
|
40
|
+
| `cli/src/engine-native/liveModels.ts` | Live model list per enabled harness (Anthropic API via Claude Code login, Codex model cache, `omp models --json`) merged over `SoT/models.json` |
|
|
39
41
|
| `.oxlintrc.json` / `.oxfmtrc.json` | Mechanical lint (correctness, suspicious, eqeqeq, no-var, prefer-const, no-unused) and code format scope |
|
|
40
42
|
| `cli/test/fixtures/` | Golden fixtures: `home-fresh`, `home-drift`, `home-invalid-json`, `codex-toml`, `statusline` |
|
|
41
43
|
| `cli/` | Effect 4 RC CLI + bundled docs topics |
|
|
42
|
-
| `SoT/models.json` |
|
|
43
|
-
| `SoT/toolchain.json` | Toolchain floors manifest (verified pins consumed by EngineNative) |
|
|
44
|
+
| `SoT/models.json` | Curated Claude and Codex model overlay: aliases and notes always apply; id rows are the fallback when a harness live list is unavailable |
|
|
45
|
+
| `SoT/toolchain.json` | Toolchain floors manifest (verified pins consumed by EngineNative; optional `upstream` source read by `docks-kit toolchain outdated`) |
|
|
44
46
|
| `SoT/.claude/bin/` | Dependency-free Bun runtime programs for Claude's statusline, SessionStart, and Notification |
|
|
45
47
|
| `SoT/.omp/` | Kit-owned omp SoT: `AGENTS.md`, `config.yml`, `models.yml`, `mcp.json`, and `intercom.json` |
|
|
46
48
|
| `install.sh` / `install.ps1` | POSIX and Windows global installers |
|
|
@@ -73,7 +75,7 @@ omp SoT notes:
|
|
|
73
75
|
- `ompSync.ts syncMergedYaml` deep-merges `config.yml` through `ompYaml.ts mergeOmpConfig` and `models.yml` through `mergeOmpModels`. Both wrap one generic mapping merge; only the config wrapper prunes stale `retry.fallbackChains` wildcards.
|
|
74
76
|
- `ompSync.ts` runs `ompRemovals.ts syncOmpRemovals, retired-key inventory` right after the config merge, and that pass force-prunes retired kit-owned keys from `~/.omp/agent/config.yml` on every sync, without `--reconcile`. The pass is required because `mergeOmpConfig` is additive, so removing a key from the SoT alone never removes it from a deployed file. A key retired with a recorded value is pruned only while the deployed value still matches that value, so a user edit survives; a key retired outright, such as `providers.webSearchOrder`, is pruned at any value.
|
|
75
77
|
- `cycleOrder` ends with `astra` as its fifth stop. `modelRoles.astra` is `openai-codex/gpt-6-astra:xhigh`, and `modelTags.astra` is visible. Astra and Fable fall back to each other through concrete selectors. `modelRoles.fable` remains `anthropic/claude-fable-5-1:medium`, with visible `modelTags.fable`. The hidden `switch_fable` role uses the same Fable selector and keeps an empty fallback chain.
|
|
76
|
-
- `modelRoles.task` is `openai-codex/gpt-6-sol:high
|
|
78
|
+
- `modelRoles.task` is `openai-codex/gpt-6-sol:high`. `advisor` is `anthropic/claude-opus-5-5:medium` with an empty fallback chain, because a GPT-6 Sol advisor looped on repeated reads under an Opus 5.5 session; never put GPT-6 Sol in the advisor role or chain. `smol`, `commit`, and `tiny` use `openai-codex/gpt-6-luna`. The four reviewer entries in `task.agentModelOverrides` inherit `task` through `@task`. Only bundled `reviewer` and `security-reviewer` are discoverable OMP agents; `code-reviewer` and `plan-reviewer` stay dormant. omp 18.2.9 does not list `gpt-6-sol` or `gpt-6-luna` in its `openai-codex` catalog, so it fuzzy-matches both selectors to the GPT-5.6 models without a warning until the catalog lists them. The owner deployed them anyway. `cli/docs/omp-models.md` records the checks.
|
|
77
79
|
- The five Anthropic roles (`default`, `slow`, `plan`, `designer`, `vision`) and the five Anthropic retry chains use `anthropic/claude-opus-5-5` at the levels the role map records. `cli/docs/omp-models.md` carries the Artificial Analysis capture behind the role map, read 2026-09-22 at Intelligence Index v4.3.2 and Coding Agent Index v1.5 from the AA comparison-page metric tables. Opus 5.5 max has the highest index in that topic. AA has not measured speed or latency for Opus 5.5 max, GPT-6 Sol, or GPT-6 Luna.
|
|
78
80
|
- `modelRoles.web` is `web/firecrawl` and `retry.fallbackChains.web` carries the explicit 20-entry provider order. The kit declares both keys because the legacy `providers.webSearchOrder` key is retired: omp expands it in memory into these two keys and then drops it, and never writes that expansion back to disk. An explicit chain replaces omp's built-in web order wholesale, so every entry left out is a provider omp never tries. The owner removed the seven entries that named older models (Gemini 2.5 Flash, Claude Haiku 4.5, GPT-5.6, GPT-5.5, and Grok 4.5); keep every other provider.
|
|
79
81
|
- `SoT/.omp/models.yml` declares Astra's full `low, medium, high, xhigh, max` ladder with `defaultLevel: xhigh` as the worked provider ladder-override example. It also carries a temporary `anthropic.modelOverrides.claude-opus-5-5` block with that model's limits, ladder, and prices, because the shared catalog still serves the id as a stub with null limits and zero cost; remove the block once the catalog publishes the row. `ompYaml.ts mergeOmpModels` preserves deployed-only keys in `~/.omp/agent/models.yml`, because a user file may carry provider credentials. Whole-file replacement is wrong.
|
|
@@ -84,7 +86,7 @@ omp SoT notes:
|
|
|
84
86
|
- Sync installs `pi-intercom` at the verified version from `SoT/toolchain.json`.
|
|
85
87
|
- The omp CLI is upstream-owned and self-updating through `omp update`. Sync never installs or upgrades the CLI.
|
|
86
88
|
- `docks-kit omp [--model <selector>|--pick] [args...]` starts one interactive omp session with every model role set to one free model and every retry chain empty. Higher-precedence model selection can replace those overlay values. It renders the overlay to `~/.cache/docks-kit/omp-free-<model>-<digest>.yml` (mode 0600) and passes it through omp's repeatable `--config` flag. `ompOverlay.ts overlayFileName` gives each model its own file, because omp can re-read the overlay during a live session and a second launcher on another model must not rewrite it. Deployed `~/.omp/agent/` files stay untouched, so the next plain `omp` run uses the paid configuration again. Remaining arguments forward verbatim to omp.
|
|
87
|
-
- The session model persists per machine in `~/.docks-kit/
|
|
89
|
+
- The session model persists per machine in `~/.docks-kit/kit.db` (table `omp_session`), next to the harness selection. The default is `opencode-zen/muse-spark-1.3-contributor-free` at `xhigh`. `ompOverlay.ts ladderCeiling, advisorLevelFor` derive both levels from the ladder of the chosen model for the `--model` path, and `ompOverlay.ts planEffortChoice` drives the `--pick` wizard, which asks whether every role shares one level and otherwise takes one level for the main roles and one for the advisor from that model's own ladder. Levels never come from a fixed list: free ladders are not uniform, three free models publish no `medium`, and two publish no ladder, which the overlay renders as bare selectors. The picker lists only zero-cost catalog models.
|
|
88
90
|
|
|
89
91
|
For per-tool SoT layouts (`SoT/.claude/`, `SoT/.codex/`, `SoT/.omp/`), see the matching SoT directory.
|
|
90
92
|
|
|
@@ -96,7 +98,7 @@ For per-tool SoT layouts (`SoT/.claude/`, `SoT/.codex/`, `SoT/.omp/`), see the m
|
|
|
96
98
|
- **Effect 4 CLI stack.** The CLI pins `effect@4.0.0-rc.115` (including `effect/unstable/cli`), `@effect/platform-bun@4.0.0-rc.115` (`BunServices.layer`, `BunRuntime.runMain`), `@effect/vitest@4.0.0-rc.115`, and `vitest@5.0.0` (inside the `@effect/vitest` peer range `>=5.0.0 <6.0.0`; 5.0.0 is past the 5.x patch point for GHSA-82fw-gwwq-j7x9, fixed in 5.0.0-rc.2). `@effect/cli` and `@effect/platform` are removed and must not be reintroduced.
|
|
97
99
|
- **Effect skill routing.** Effect work in this checkout must verify migration and API call shapes against the installed declarations under `node_modules/effect/dist/unstable/cli/`, never from memory or a mutable dist-tag. The `effect-ts-setup`, `effect-ts-port`, and `effect-ts-specialist` skills target Effect 3.x and do not apply.
|
|
98
100
|
- **Targeted syncs.** `./docks-kit sync` accepts positional targets: `claude`, `codex`, `agents`, and `omp`. Use the narrowest target that matches the SoT change (for example, `./docks-kit sync omp` for omp-only config edits); targets can be combined with `--dry-run`, `--skip-bubblewrap` (skip optional bubblewrap bootstrap for the Codex Linux sandbox), `--skip-plugin-refresh` (install missing plugins without refreshing existing caches), `--reconcile`, `--prune`, and the deploy-time modifiers `--claude-compact-window=<tokens>` / `--claude-permissive` / `--claude-model=<m>` / `--claude-effort=<level>` / `--claude-advisor=<on|off|default>` / `--codex-model=<m>` / `--codex-effort=<level>` (see `CLAUDE.md` § Deploy-time modifiers).
|
|
99
|
-
- **Per-machine harness selection.** `~/.docks-kit/
|
|
101
|
+
- **Per-machine harness selection.** The SQLite store `~/.docks-kit/kit.db` drives a flag-less sync. A missing selection selects `claude`, `codex`, and `agents`; it never selects `omp` implicitly. `sync` never prompts and never writes the selection. `docks-kit harnesses` is the only command that writes the `harness_selection` table. The same store holds the independent `omp_session` table, which only `docks-kit omp` writes, and a TTL cache (`cache_entry`) for the live Anthropic model list and `toolchain outdated` lookups. `kitDb.ts withKitDb` is the only opener: it runs the append-only `MIGRATIONS`, imports a legacy `state.json` once and renames it to `state.json.migrated`, and refuses a store from a newer schema. Cache rows carry the kit version as fingerprint, so a new release refetches them.
|
|
100
102
|
- **Additive by default.** Keys present in deployed config but absent from SoT are preserved on default sync. This protects user-only additions, but means drift accumulates — neither flag-less reset can clean it up. The one exception is the Claude `removed` manifest (`claudeSync.ts REMOVED_MANIFEST, baseline removal inventory`), a curated list of unambiguous kit-owned artifacts that `claudeSync.ts syncRemovals, baseline artifact prune` force-prunes on every sync, including the home-relative `~/.local/bin/session-relay` artifact installed outside `~/.claude`; see `CLAUDE.md` § Pruning stale artifacts.
|
|
101
103
|
- **`--reconcile` / `--prune` are the kit-owned reconcile flags.** Orthogonal — `--reconcile` reconciles the settings layer (SoT-declared keys/tables/arrays win; user-only keys and nested objects are preserved; permissions arrays are replaced wholesale by SoT). `--prune` uninstalls kit-managed installations not in the SoT (plugins, marketplaces, and `~/.agents/skills/*` entries tracked in `~/.agents/.kit-managed-skills`). Combine for a full reset to SoT's kit-managed scope. User-only additions outside the kit's scope (custom env vars, mcpServers, manually-installed skills, third-party plugins not declared in SoT) are always preserved. Each tool's per-tool file documents the specific paths and diff recipes.
|
|
102
104
|
- **SOLID-aligned modules.** Axis modules own one concern each (see layout); orchestrators (`claudeSync.ts`, `codexSync.ts`, `skillsSync.ts`, `ompSync.ts`, `index.ts`, `argv.ts`, `parseArgs.ts`) keep prior exports. New shared shapes go in `sharedTypes.d.ts`, never a second local copy. The public CLI seam is `cli/src/engine.ts`.
|
package/README.md
CHANGED
|
@@ -47,9 +47,9 @@ docks-kit sync [claude] [codex] [agents] [omp] deploy explicit targets or the m
|
|
|
47
47
|
docks-kit harnesses view or change this machine's selection
|
|
48
48
|
docks-kit update [--no-sync] self-update the kit (autodetects checkout vs global install), then sync
|
|
49
49
|
docks-kit model <claude|codex> [value] get/set the DEPLOYED model (TTY picker)
|
|
50
|
-
docks-kit models [claude|codex]
|
|
50
|
+
docks-kit models [claude|codex|omp] [--refresh] live catalogs for enabled harnesses (`--json`)
|
|
51
51
|
docks-kit omp [--model <m>|--pick] [args...] one omp session on a free model, nothing deployed changes
|
|
52
|
-
docks-kit toolchain [check|ensure <tool
|
|
52
|
+
docks-kit toolchain [check|ensure <tool>|outdated] verified-version floors for external tools
|
|
53
53
|
docks-kit status [--json] deployed-vs-SoT drift + toolchain + counts
|
|
54
54
|
docks-kit plugins list [--json] enabledPlugins tri-state vs installed
|
|
55
55
|
docks-kit skills list [--json] universal skills vs manifest
|
|
@@ -91,16 +91,16 @@ and a later flag-less sync reverts them. Full reference: `docks-kit docs flags`
|
|
|
91
91
|
- **Additive by default** — user-only settings keys, plugins, and skills
|
|
92
92
|
survive a plain sync. Reconciliation toward the SoT is explicit
|
|
93
93
|
(`--reconcile` / `--prune`).
|
|
94
|
-
- **Per-machine selection** — `~/.docks-kit/
|
|
95
|
-
A missing
|
|
94
|
+
- **Per-machine selection** — `~/.docks-kit/kit.db` drives a flag-less sync.
|
|
95
|
+
A missing selection selects Claude Code, Codex, and universal skills. It does not
|
|
96
96
|
select omp. Use `docks-kit harnesses` to view or change the selection.
|
|
97
97
|
- **Idempotent** — every step is safe to re-run; no-change syncs are no-ops.
|
|
98
98
|
- **Toolchain floors** — `SoT/toolchain.json` records the kit-verified version
|
|
99
99
|
floors for external tools (bun, bwrap, …). `docks-kit toolchain check` prints
|
|
100
100
|
the full doctor table. Bun is the one managed install and is pinned to its
|
|
101
101
|
verified version.
|
|
102
|
-
- **Model catalog** —
|
|
103
|
-
model
|
|
102
|
+
- **Model catalog** — enabled harnesses provide live Claude, Codex, or omp
|
|
103
|
+
model IDs; `SoT/models.json` supplies aliases, notes, and the offline fallback.
|
|
104
104
|
- **Claude runtime** — sync materializes three dependency-free Bun `.mjs`
|
|
105
105
|
programs for statusline, SessionStart, and Notification. Quota display uses
|
|
106
106
|
Claude's native `rate_limits`; there is no OAuth fetch, shared usage cache,
|
|
@@ -115,7 +115,7 @@ and a later flag-less sync reverts them. Full reference: `docks-kit docs flags`
|
|
|
115
115
|
| `SoT/.codex/` | Codex SoT (config.toml, rules, AGENTS.md, marketplace) |
|
|
116
116
|
| `SoT/.omp/` | omp SoT (AGENTS.md, config.yml, models.yml, mcp.json, intercom.json) |
|
|
117
117
|
| `SoT/.agents/` | Universal-skill manifest |
|
|
118
|
-
| `SoT/models.json` |
|
|
118
|
+
| `SoT/models.json` | Curated aliases, notes, and offline Claude/Codex fallback |
|
|
119
119
|
| `SoT/toolchain.json` | Verified-version floors |
|
|
120
120
|
| `cli/src/engine-native/` | EngineNative sync/model/toolchain implementation |
|
|
121
121
|
| `cli/src/generated/sotPayload.ts` | Generated in-memory payload used by standalone and npm installs |
|
package/cli/docs/flags.md
CHANGED
|
@@ -14,7 +14,7 @@ docks-kit sync omp # opt-in harness
|
|
|
14
14
|
|
|
15
15
|
Positional targets are `claude`, `codex`, `agents`, and `omp`. A flag-less
|
|
16
16
|
`sync` deploys the per-machine harness selection stored in
|
|
17
|
-
`~/.docks-kit/
|
|
17
|
+
`~/.docks-kit/kit.db`. A missing selection or an unreadable store selects `claude`,
|
|
18
18
|
`codex`, and `agents`, and never selects `omp`. Choose the stored selection
|
|
19
19
|
with `docks-kit harnesses`.
|
|
20
20
|
|
|
@@ -56,7 +56,7 @@ ignored with a warning; Claude modifiers never touch Codex config and vice versa
|
|
|
56
56
|
|
|
57
57
|
| Flag | Effect |
|
|
58
58
|
|------|--------|
|
|
59
|
-
| `--model <selector>` | Session model for this run and later runs; rejected unless the live catalog reports zero input and output cost; recorded in `~/.docks-kit/
|
|
59
|
+
| `--model <selector>` | Session model for this run and later runs; rejected unless the live catalog reports zero input and output cost; recorded in `~/.docks-kit/kit.db` (table `omp_session`) |
|
|
60
60
|
| `--pick` | Interactive picker over free catalog models; records the choice the same way |
|
|
61
61
|
|
|
62
62
|
Remaining arguments forward verbatim to omp after the launcher flags.
|
package/cli/docs/models.md
CHANGED
|
@@ -1,9 +1,17 @@
|
|
|
1
1
|
# Models
|
|
2
2
|
|
|
3
|
-
`SoT/models.json`
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
the
|
|
3
|
+
`SoT/models.json` supplies aliases and notes for Claude and Codex. For each
|
|
4
|
+
enabled harness, `docks-kit models` and the picker list live model IDs when
|
|
5
|
+
available. Claude uses the Claude Code login to query the Anthropic models API
|
|
6
|
+
and caches the result for six hours in `~/.docks-kit/kit.db`; Codex reads
|
|
7
|
+
`~/.codex/models_cache.json`; omp runs `omp models --json`. The kit never needs
|
|
8
|
+
omp to list Claude models.
|
|
9
|
+
|
|
10
|
+
Live lists retain the curated aliases and notes, but omit curated IDs absent
|
|
11
|
+
from the live source. A disabled harness, missing login/cache, or unavailable
|
|
12
|
+
source falls back to the curated IDs. omp has no curated fallback models.
|
|
13
|
+
The `verified` field is the curated section date, not the live fetch date.
|
|
14
|
+
Bare model flags without a value print the curated list without a network call.
|
|
7
15
|
|
|
8
16
|
## Validation rules
|
|
9
17
|
|
|
@@ -33,9 +41,10 @@ the entry and date when a model ships or retires.
|
|
|
33
41
|
## Commands
|
|
34
42
|
|
|
35
43
|
```
|
|
36
|
-
docks-kit models #
|
|
37
|
-
docks-kit models claude --json #
|
|
38
|
-
docks-kit
|
|
44
|
+
docks-kit models # enabled Claude, Codex, and omp catalogs
|
|
45
|
+
docks-kit models claude --json # source, fetch date, and fallback reason
|
|
46
|
+
docks-kit models claude --refresh # bypass the six-hour Anthropic cache
|
|
47
|
+
docks-kit model claude # current deployed + live list + picker (TTY)
|
|
39
48
|
docks-kit model claude opus # per-machine override from the Opus SoT
|
|
40
49
|
docks-kit sync claude --claude-model=opus # same, as part of a sync
|
|
41
50
|
```
|
package/cli/docs/omp-models.md
CHANGED
|
@@ -12,7 +12,7 @@ against.
|
|
|
12
12
|
| `slow` | `anthropic/claude-opus-5-5` | xhigh | 56 | $3.46 | 165.20 s |
|
|
13
13
|
| `plan` | `anthropic/claude-opus-5-5` | xhigh | 56 | $3.46 | 165.20 s |
|
|
14
14
|
| `task` | `openai-codex/gpt-6-sol` | high | 43 | $0.37 | n/a |
|
|
15
|
-
| `advisor` | `
|
|
15
|
+
| `advisor` | `anthropic/claude-opus-5-5` | medium | 51 | $1.34 | 22.17 s |
|
|
16
16
|
| `designer` | `anthropic/claude-opus-5-5` | high | 54 | $1.82 | 12.49 s |
|
|
17
17
|
| `vision` | `anthropic/claude-opus-5-5` | medium | 51 | $1.34 | 22.17 s |
|
|
18
18
|
| `smol` / `commit` | `openai-codex/gpt-6-luna` | medium | 29 | $0.02 | n/a |
|
|
@@ -83,6 +83,19 @@ chains, `retry.fallbackChains.default` would send either stop to
|
|
|
83
83
|
Chain entries are concrete selectors, not role aliases, so this pair cannot
|
|
84
84
|
recurse. The hidden `switch_fable` chain stays empty.
|
|
85
85
|
|
|
86
|
+
### Why `advisor` runs Opus 5.5 medium
|
|
87
|
+
|
|
88
|
+
`advisor` runs `anthropic/claude-opus-5-5:medium` with an empty fallback
|
|
89
|
+
chain. On 2026-09-24, with omp 18.3.0, an Opus 5.5 session with the advisor
|
|
90
|
+
on `openai-codex/gpt-6-sol:medium` looped. In one session the advisor made
|
|
91
|
+
1,313 requests for 140 main-agent requests. It issued 1,272 `read` calls on
|
|
92
|
+
248 distinct paths, read one 3-line slice 249 times, and never called
|
|
93
|
+
`advise`. The advisor prompt averaged about 317k tokens, above the 272K
|
|
94
|
+
window omp lists for GPT-6 Sol. With the advisor on Opus 5.5 medium, the
|
|
95
|
+
same kind of session made about one advisor request per main-agent request
|
|
96
|
+
and called `advise` normally. The owner excluded GPT-6 Sol from the advisor
|
|
97
|
+
role and its fallback chain.
|
|
98
|
+
|
|
86
99
|
`modelRoles.web` is `web/firecrawl`, and `retry.fallbackChains.web` lists the
|
|
87
100
|
explicit 20-entry provider order that follows it. The two keys replace the
|
|
88
101
|
retired `providers.webSearchOrder` key, which omp no longer carries in its
|
|
@@ -405,8 +418,8 @@ distinct ladders: 21 include `medium`, 3 stop at `low, high, max` or
|
|
|
405
418
|
bare selectors with no `:level` suffix, because an invented level makes omp
|
|
406
419
|
fail when the session starts.
|
|
407
420
|
|
|
408
|
-
The choice persists per machine in `~/.docks-kit/
|
|
409
|
-
`
|
|
421
|
+
The choice persists per machine in `~/.docks-kit/kit.db` (table
|
|
422
|
+
`omp_session`), next to the harness selection. It survives across sessions. It is never
|
|
410
423
|
committed. `--model <selector>` records one selector and derives both levels
|
|
411
424
|
from the catalog row. `--pick` opens an interactive wizard.
|
|
412
425
|
|
package/cli/docs/sync-layers.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
`docks-kit sync [claude] [codex] [agents] [omp]` — targets are positional
|
|
4
4
|
words; no target means this machine's harness selection in
|
|
5
|
-
`~/.docks-kit/
|
|
5
|
+
`~/.docks-kit/kit.db`. The default is `claude codex agents`, and
|
|
6
6
|
`docks-kit harnesses` changes it.
|
|
7
7
|
|
|
8
8
|
## claude (→ ~/.claude, ~/.claude.json, shell rc)
|
package/cli/docs/toolchain.md
CHANGED
|
@@ -85,4 +85,14 @@ manifest's `verified` version.
|
|
|
85
85
|
```text
|
|
86
86
|
docks-kit toolchain check # doctor table (also inside docks-kit status)
|
|
87
87
|
docks-kit toolchain ensure bun # ensure the only managed tool
|
|
88
|
+
docks-kit toolchain outdated [--refresh] # verified pins vs newest upstream release
|
|
88
89
|
```
|
|
90
|
+
|
|
91
|
+
`docks-kit toolchain outdated` reads each tool's optional `upstream` entry in
|
|
92
|
+
`SoT/toolchain.json`. An `npm` entry reads the registry `latest` tag. With a
|
|
93
|
+
`line`, it reads the newest release on that major line instead, so `tsc` stays
|
|
94
|
+
on 6.x. A `github` entry reads the latest release tag and strips `tagPrefix`.
|
|
95
|
+
Set `GITHUB_TOKEN` or `GH_TOKEN` to raise the GitHub rate limit. Successful
|
|
96
|
+
lookups cache for 24 hours in `~/.docks-kit/kit.db`; `--refresh` bypasses the
|
|
97
|
+
cache. The report never installs anything and never edits a pin. A failed
|
|
98
|
+
lookup prints `lookup failed: <reason>` and the command still exits 0.
|
|
@@ -4,12 +4,12 @@ import { bail } from "../engine";
|
|
|
4
4
|
import {
|
|
5
5
|
engineHome,
|
|
6
6
|
HARNESSES,
|
|
7
|
-
harnessStateFile,
|
|
8
7
|
LEGACY_SELECTION,
|
|
9
8
|
readHarnessSelection,
|
|
10
9
|
writeHarnessSelection,
|
|
11
10
|
type Harness,
|
|
12
11
|
} from "../engine-native/harnesses";
|
|
12
|
+
import { kitDbFile } from "../engine-native/kitDb";
|
|
13
13
|
|
|
14
14
|
const DESCRIPTIONS: Record<Harness, string> = {
|
|
15
15
|
claude: "Claude Code user configuration",
|
|
@@ -50,7 +50,7 @@ export const harnessesCommand = Command.make("harnesses", {}, () =>
|
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
yield* Effect.sync(() => writeHarnessSelection(home, answer));
|
|
53
|
-
yield* Console.log(`Saved harness selection: ${answer.join(", ")} (${
|
|
53
|
+
yield* Console.log(`Saved harness selection: ${answer.join(", ")} (${kitDbFile(home)})`);
|
|
54
54
|
}),
|
|
55
55
|
).pipe(
|
|
56
56
|
Command.withDescription("Choose the harness selection that drives a flag-less docks-kit sync."),
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { Argument, Command, Flag, Prompt } from "effect/unstable/cli";
|
|
2
2
|
import { Effect, Option } from "effect";
|
|
3
3
|
import { bail, engine } from "../engine";
|
|
4
|
-
import {
|
|
4
|
+
import { engineHome } from "../engine-native/harnesses";
|
|
5
|
+
import { defaultLiveInputs, resolveCatalog } from "../engine-native/liveModels";
|
|
5
6
|
import type { Tool } from "../manifests";
|
|
6
7
|
|
|
7
8
|
const tool = Argument.String("tool").pipe(Argument.withDescription("Which tool: claude | codex"));
|
|
@@ -42,7 +43,9 @@ export const modelCommand = Command.make("model", { tool, value, dryRun, verbose
|
|
|
42
43
|
// … and offer an interactive picker when attached to a terminal.
|
|
43
44
|
if (!process.stdin.isTTY || !process.stdout.isTTY) return;
|
|
44
45
|
|
|
45
|
-
const catalog =
|
|
46
|
+
const catalog = yield* Effect.promise(() =>
|
|
47
|
+
resolveCatalog(t, defaultLiveInputs(engineHome(process.env))),
|
|
48
|
+
);
|
|
46
49
|
const chosen = yield* Prompt.Select({
|
|
47
50
|
message: `Set the deployed ${t} model (deployed config only; a flag-less sync reverts to SoT)`,
|
|
48
51
|
choices: [
|
|
@@ -1,48 +1,75 @@
|
|
|
1
1
|
import { Argument, Command, Flag } from "effect/unstable/cli";
|
|
2
2
|
import { Console, Effect, Option } from "effect";
|
|
3
3
|
import { bail } from "../engine";
|
|
4
|
-
import {
|
|
5
|
-
import
|
|
4
|
+
import { engineHome, LEGACY_SELECTION, readHarnessSelection } from "../engine-native/harnesses";
|
|
5
|
+
import { defaultLiveInputs, resolveCatalog } from "../engine-native/liveModels";
|
|
6
|
+
import type { CatalogTool, ResolvedCatalog } from "../engine-native/sharedTypes";
|
|
6
7
|
|
|
7
8
|
const tool = Argument.String("tool").pipe(
|
|
8
|
-
Argument.withDescription("claude | codex (omit for
|
|
9
|
+
Argument.withDescription("claude | codex | omp (omit for enabled harnesses)"),
|
|
9
10
|
Argument.optional,
|
|
10
11
|
);
|
|
11
12
|
const json = Flag.Boolean("json").pipe(
|
|
12
13
|
Flag.withDescription("Machine-readable output"),
|
|
13
14
|
Flag.withDefault(false),
|
|
14
15
|
);
|
|
16
|
+
const refresh = Flag.Boolean("refresh").pipe(
|
|
17
|
+
Flag.withDescription("Bypass the kit cache (~/.docks-kit/kit.db) and fetch live lists again"),
|
|
18
|
+
Flag.withDefault(false),
|
|
19
|
+
);
|
|
15
20
|
|
|
16
|
-
|
|
21
|
+
function isCatalogTool(value: string): value is CatalogTool {
|
|
22
|
+
return value === "claude" || value === "codex" || value === "omp";
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const renderTool = (t: CatalogTool, catalog: ResolvedCatalog) =>
|
|
17
26
|
Effect.gen(function* () {
|
|
18
|
-
|
|
19
|
-
|
|
27
|
+
yield* Console.log(
|
|
28
|
+
catalog.source === "curated"
|
|
29
|
+
? `${t} models (kit-verified ${catalog.verified}):`
|
|
30
|
+
: `${t} models (live — ${catalog.source}, fetched ${catalog.fetchedAt ?? "?"}):`,
|
|
31
|
+
);
|
|
32
|
+
if (catalog.fallbackReason !== undefined) {
|
|
33
|
+
yield* Console.log(` (live list unavailable: ${catalog.fallbackReason})`);
|
|
34
|
+
}
|
|
20
35
|
for (const m of catalog.models) {
|
|
21
36
|
yield* Console.log(` ${m.id.padEnd(28)} ${m.kind.padEnd(6)} ${m.note ?? ""}`);
|
|
22
37
|
}
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
)
|
|
38
|
+
if (t === "claude") {
|
|
39
|
+
yield* Console.log(
|
|
40
|
+
" (full claude-* model IDs outside the catalog are accepted with a warning)",
|
|
41
|
+
);
|
|
42
|
+
} else if (t === "codex") {
|
|
43
|
+
yield* Console.log(" (well-formed IDs outside the catalog are accepted with a warning)");
|
|
44
|
+
}
|
|
28
45
|
yield* Console.log("");
|
|
29
46
|
});
|
|
30
47
|
|
|
31
|
-
export const modelsCommand = Command.make("models", { tool, json }, (config) =>
|
|
48
|
+
export const modelsCommand = Command.make("models", { tool, json, refresh }, (config) =>
|
|
32
49
|
Effect.gen(function* () {
|
|
33
50
|
const requested = Option.getOrUndefined(config.tool);
|
|
34
|
-
if (requested !== undefined && requested
|
|
35
|
-
return yield* bail(`Unknown tool '${requested}' (valid: claude, codex)`);
|
|
36
|
-
}
|
|
37
|
-
const tools: Array<Tool> = requested !== undefined ? [requested as Tool] : ["claude", "codex"];
|
|
38
|
-
|
|
39
|
-
if (config.json) {
|
|
40
|
-
const out = Object.fromEntries(tools.map((t) => [t, modelCatalog(t)]));
|
|
41
|
-
return yield* Console.log(JSON.stringify(out, null, 2));
|
|
51
|
+
if (requested !== undefined && !isCatalogTool(requested)) {
|
|
52
|
+
return yield* bail(`Unknown tool '${requested}' (valid: claude, codex, omp)`);
|
|
42
53
|
}
|
|
43
|
-
|
|
54
|
+
const home = engineHome(process.env);
|
|
55
|
+
const tools: ReadonlyArray<CatalogTool> =
|
|
56
|
+
requested !== undefined
|
|
57
|
+
? [requested]
|
|
58
|
+
: (readHarnessSelection(home) ?? LEGACY_SELECTION).filter(isCatalogTool);
|
|
59
|
+
const inputs = defaultLiveInputs(home, config.refresh);
|
|
60
|
+
const out: Partial<Record<CatalogTool, ResolvedCatalog>> = {};
|
|
44
61
|
for (const t of tools) {
|
|
45
|
-
yield*
|
|
62
|
+
const catalog = yield* Effect.promise(() => resolveCatalog(t, inputs));
|
|
63
|
+
if (config.json) {
|
|
64
|
+
out[t] = catalog;
|
|
65
|
+
} else {
|
|
66
|
+
yield* renderTool(t, catalog);
|
|
67
|
+
}
|
|
46
68
|
}
|
|
69
|
+
if (config.json) yield* Console.log(JSON.stringify(out, null, 2));
|
|
47
70
|
}),
|
|
48
|
-
).pipe(
|
|
71
|
+
).pipe(
|
|
72
|
+
Command.withDescription(
|
|
73
|
+
"List models per enabled harness: live from each harness's login or cache, with SoT/models.json aliases and notes as overlay and offline fallback.",
|
|
74
|
+
),
|
|
75
|
+
);
|
|
@@ -5,7 +5,7 @@ import { bail, engine } from "../engine";
|
|
|
5
5
|
const MANAGED = ["bun"];
|
|
6
6
|
|
|
7
7
|
const op = Argument.String("op").pipe(
|
|
8
|
-
Argument.withDescription("check (default) | ensure <tool>"),
|
|
8
|
+
Argument.withDescription("check (default) | ensure <tool> | outdated"),
|
|
9
9
|
Argument.optional,
|
|
10
10
|
);
|
|
11
11
|
const tool = Argument.String("tool").pipe(
|
|
@@ -17,28 +17,39 @@ const verbose = Flag.Boolean("verbose").pipe(
|
|
|
17
17
|
Flag.withDescription("Also print no-op confirmations (present, up to date)"),
|
|
18
18
|
Flag.withDefault(false),
|
|
19
19
|
);
|
|
20
|
+
const refresh = Flag.Boolean("refresh").pipe(
|
|
21
|
+
Flag.withDescription("outdated: bypass the 24 h cache"),
|
|
22
|
+
Flag.withDefault(false),
|
|
23
|
+
);
|
|
20
24
|
|
|
21
|
-
export const toolchainCommand = Command.make(
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
+
export const toolchainCommand = Command.make(
|
|
26
|
+
"toolchain",
|
|
27
|
+
{ op, tool, verbose, refresh },
|
|
28
|
+
(config) =>
|
|
29
|
+
Effect.gen(function* () {
|
|
30
|
+
const operation = Option.getOrElse(config.op, () => "check");
|
|
31
|
+
const flags = config.verbose ? ["--verbose"] : [];
|
|
25
32
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
+
switch (operation) {
|
|
34
|
+
case "check":
|
|
35
|
+
return yield* engine(["toolchain", "check", ...(config.verbose ? ["--verbose"] : [])]);
|
|
36
|
+
case "ensure": {
|
|
37
|
+
const t = Option.getOrUndefined(config.tool);
|
|
38
|
+
if (t === undefined || !MANAGED.includes(t)) {
|
|
39
|
+
return yield* bail(`toolchain ensure needs a managed tool: ${MANAGED.join(", ")}`);
|
|
40
|
+
}
|
|
41
|
+
return yield* engine(["toolchain", "ensure", t, ...flags]);
|
|
33
42
|
}
|
|
34
|
-
|
|
43
|
+
case "outdated":
|
|
44
|
+
return yield* engine(["toolchain", "outdated", ...(config.refresh ? ["--refresh"] : [])]);
|
|
45
|
+
default:
|
|
46
|
+
return yield* bail(
|
|
47
|
+
`Unknown toolchain op '${operation}' (valid: check, ensure, outdated)`,
|
|
48
|
+
);
|
|
35
49
|
}
|
|
36
|
-
|
|
37
|
-
return yield* bail(`Unknown toolchain op '${operation}' (valid: check, ensure)`);
|
|
38
|
-
}
|
|
39
|
-
}),
|
|
50
|
+
}),
|
|
40
51
|
).pipe(
|
|
41
52
|
Command.withDescription(
|
|
42
|
-
"Verified-version floors for external tools (SoT/toolchain.json): check prints the doctor table; ensure installs one managed tool when it is missing.",
|
|
53
|
+
"Verified-version floors for external tools (SoT/toolchain.json): check prints the doctor table; ensure installs one managed tool when it is missing; outdated compares verified pins with the newest upstream release (network, report only).",
|
|
43
54
|
),
|
|
44
55
|
);
|
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Per-machine harness selection
|
|
3
|
-
* the omp harness opt-in. A missing or unreadable
|
|
4
|
-
* undefined so callers resolve it to LEGACY_SELECTION
|
|
5
|
-
* keep today's behavior.
|
|
2
|
+
* Per-machine harness selection and omp session model, stored in ~/.docks-kit/kit.db (kitDb.ts).
|
|
3
|
+
* The selection keeps the omp harness opt-in. A missing or unreadable store is
|
|
4
|
+
* represented by undefined so callers resolve it to LEGACY_SELECTION.
|
|
6
5
|
*/
|
|
7
|
-
import { chmodSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
8
6
|
import { homedir } from "node:os";
|
|
9
7
|
|
|
10
|
-
import {
|
|
8
|
+
import { inTransaction, isNonBlankString, nonBlankOrNull, withKitDb } from "./kitDb";
|
|
11
9
|
import type { OmpSessionModel } from "./sharedTypes";
|
|
12
10
|
|
|
13
11
|
export type Harness = "claude" | "codex" | "agents" | "omp";
|
|
@@ -41,49 +39,21 @@ export function engineHome(env: NodeJS.ProcessEnv = process.env): string {
|
|
|
41
39
|
return home !== undefined && home !== "" ? home : homedir();
|
|
42
40
|
}
|
|
43
41
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
// Read the whole state record so one key writer keeps sibling keys intact.
|
|
49
|
-
// A corrupt file degrades to undefined so callers fall back to defaults.
|
|
50
|
-
function readWholeState(home: string): Record<string, unknown> | undefined {
|
|
51
|
-
let parsed: unknown;
|
|
42
|
+
/** Read the stored selection; corruption, a too-new schema, or I/O errors yield undefined. */
|
|
43
|
+
export function readHarnessSelection(home: string): ReadonlyArray<Harness> | undefined {
|
|
52
44
|
try {
|
|
53
|
-
|
|
45
|
+
const selection = withKitDb(home, "read", (db) =>
|
|
46
|
+
normalizeHarnesses(
|
|
47
|
+
db
|
|
48
|
+
.prepare("SELECT harness FROM harness_selection")
|
|
49
|
+
.all()
|
|
50
|
+
.map((row) => row["harness"]),
|
|
51
|
+
),
|
|
52
|
+
);
|
|
53
|
+
return selection !== undefined && selection.length > 0 ? selection : undefined;
|
|
54
54
|
} catch {
|
|
55
55
|
return undefined;
|
|
56
56
|
}
|
|
57
|
-
|
|
58
|
-
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) return undefined;
|
|
59
|
-
const state = parsed as Record<string, unknown>;
|
|
60
|
-
if (state["version"] !== 1) return undefined;
|
|
61
|
-
return state;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
// Merge the patch over the stored record so independent keys never erase
|
|
65
|
-
// each other when only one writer runs.
|
|
66
|
-
function writeWholeState(home: string, patch: Record<string, unknown>): void {
|
|
67
|
-
const existing = readWholeState(home) ?? {};
|
|
68
|
-
const next = { ...existing, ...patch, version: 1 };
|
|
69
|
-
const directory = p(home, ".docks-kit");
|
|
70
|
-
const file = harnessStateFile(home);
|
|
71
|
-
const text = `${JSON.stringify(next, null, 2)}\n`;
|
|
72
|
-
// `mode` applies only when mkdir creates the path, so an existing permissive
|
|
73
|
-
// ~/.docks-kit would keep its mode.
|
|
74
|
-
mkdirSync(directory, { recursive: true, mode: 0o700 });
|
|
75
|
-
chmodSync(directory, 0o700);
|
|
76
|
-
writeFileSync(file, text, { mode: 0o600 });
|
|
77
|
-
chmodSync(file, 0o600);
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
/** Read valid local state without allowing corruption to make sync unusable. */
|
|
81
|
-
export function readHarnessSelection(home: string): ReadonlyArray<Harness> | undefined {
|
|
82
|
-
const state = readWholeState(home);
|
|
83
|
-
if (state === undefined || !Array.isArray(state["harnesses"])) return undefined;
|
|
84
|
-
|
|
85
|
-
const selection = normalizeHarnesses(state["harnesses"]);
|
|
86
|
-
return selection.length > 0 ? selection : undefined;
|
|
87
57
|
}
|
|
88
58
|
|
|
89
59
|
export function writeHarnessSelection(home: string, selection: ReadonlyArray<Harness>): void {
|
|
@@ -96,34 +66,37 @@ export function writeHarnessSelection(home: string, selection: ReadonlyArray<Har
|
|
|
96
66
|
throw new Error("Harness selection must contain at least one known harness name");
|
|
97
67
|
}
|
|
98
68
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
69
|
+
withKitDb(home, "write", (db) =>
|
|
70
|
+
inTransaction(db, () => {
|
|
71
|
+
db.exec("DELETE FROM harness_selection");
|
|
72
|
+
const insert = db.prepare("INSERT INTO harness_selection (harness) VALUES (?)");
|
|
73
|
+
for (const harness of harnesses) insert.run(harness);
|
|
74
|
+
}),
|
|
75
|
+
);
|
|
104
76
|
}
|
|
105
77
|
|
|
106
|
-
// Read the stored session model without throwing so a corrupt
|
|
78
|
+
// Read the stored session model without throwing so a corrupt store falls
|
|
107
79
|
// back to the default instead of breaking sync.
|
|
108
80
|
export function readOmpSessionModel(home: string): OmpSessionModel | undefined {
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
81
|
+
try {
|
|
82
|
+
return withKitDb(home, "read", (db) => {
|
|
83
|
+
const row = db
|
|
84
|
+
.prepare("SELECT selector, thinking, advisor_thinking FROM omp_session WHERE id = 1")
|
|
85
|
+
.get();
|
|
86
|
+
const selector = row?.["selector"];
|
|
87
|
+
if (!isNonBlankString(selector)) return undefined;
|
|
88
|
+
const thinking = row?.["thinking"];
|
|
89
|
+
const advisorThinking = row?.["advisor_thinking"];
|
|
90
|
+
const model: OmpSessionModel = {
|
|
91
|
+
selector,
|
|
92
|
+
...(isNonBlankString(thinking) ? { thinking } : {}),
|
|
93
|
+
...(isNonBlankString(advisorThinking) ? { advisorThinking } : {}),
|
|
94
|
+
};
|
|
95
|
+
return model;
|
|
96
|
+
});
|
|
97
|
+
} catch {
|
|
115
98
|
return undefined;
|
|
116
99
|
}
|
|
117
|
-
// Each level stands alone, so a level-free model reads back with no
|
|
118
|
-
// levels while a half-corrupt entry keeps the valid level.
|
|
119
|
-
const thinking = record["thinking"];
|
|
120
|
-
const advisorThinking = record["advisorThinking"];
|
|
121
|
-
const model: OmpSessionModel = {
|
|
122
|
-
selector: record["selector"],
|
|
123
|
-
...(isNonBlankString(thinking) ? { thinking } : {}),
|
|
124
|
-
...(isNonBlankString(advisorThinking) ? { advisorThinking } : {}),
|
|
125
|
-
};
|
|
126
|
-
return model;
|
|
127
100
|
}
|
|
128
101
|
|
|
129
102
|
export function writeOmpSessionModel(home: string, model: OmpSessionModel): void {
|
|
@@ -132,15 +105,16 @@ export function writeOmpSessionModel(home: string, model: OmpSessionModel): void
|
|
|
132
105
|
if (!isNonBlankString(model.selector)) {
|
|
133
106
|
throw new Error("Omp session model selector must be a non-empty string");
|
|
134
107
|
}
|
|
135
|
-
//
|
|
136
|
-
// no stale level behind
|
|
137
|
-
const thinking = model.thinking;
|
|
138
|
-
const advisorThinking = model.advisorThinking;
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
108
|
+
// Store blank or absent levels as NULL so a switch to a level-free model
|
|
109
|
+
// leaves no stale level behind.
|
|
110
|
+
const thinking = nonBlankOrNull(model.thinking);
|
|
111
|
+
const advisorThinking = nonBlankOrNull(model.advisorThinking);
|
|
112
|
+
withKitDb(home, "write", (db) =>
|
|
113
|
+
db
|
|
114
|
+
.prepare(
|
|
115
|
+
`INSERT INTO omp_session (id, selector, thinking, advisor_thinking) VALUES (1, ?, ?, ?)
|
|
116
|
+
ON CONFLICT(id) DO UPDATE SET selector = excluded.selector, thinking = excluded.thinking, advisor_thinking = excluded.advisor_thinking`,
|
|
117
|
+
)
|
|
118
|
+
.run(model.selector, thinking, advisorThinking),
|
|
119
|
+
);
|
|
146
120
|
}
|
|
@@ -48,7 +48,7 @@ export async function runEngineNative(
|
|
|
48
48
|
ctx = makeCtx(runServices);
|
|
49
49
|
switch (argv[0]) {
|
|
50
50
|
case "model":
|
|
51
|
-
return modeModel(ctx, argv.slice(1));
|
|
51
|
+
return await modeModel(ctx, argv.slice(1));
|
|
52
52
|
case "toolchain":
|
|
53
53
|
return await modeToolchain(ctx, argv.slice(1));
|
|
54
54
|
case "sync":
|