triss-coworker 0.26.0 → 0.27.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 +28 -1
- package/README.md +94 -24
- package/bin/triss.js +51 -3
- package/docs/coder-model-management-plan.md +1312 -0
- package/docs/configuration.md +142 -7
- package/docs/glm-clients.md +186 -40
- package/docs/mcp.md +9 -9
- package/docs/opencode-zen.md +216 -102
- package/package.json +1 -1
- package/src/client.js +13 -0
- package/src/coder-models.js +2869 -0
- package/src/commands/ask.js +3 -2
- package/src/commands/coder-models.js +1051 -0
- package/src/commands/coder.js +337 -33
- package/src/commands/completion.js +77 -16
- package/src/commands/config.js +36 -5
- package/src/commands/review.js +16 -5
- package/src/commands/status.js +48 -9
- package/src/mcp/handlers.js +3 -3
- package/src/mcp/tools.js +1 -1
- package/src/secrets.js +6 -3
- package/templates/claude-full.md +1 -1
- package/templates/claude.md +1 -1
- package/templates/codex-full.md +3 -3
- package/templates/codex.md +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,32 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.27.0] — 2026-08-05
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- **Coder model management.** `triss coder models` discovers the effective
|
|
15
|
+
model configuration and live provider catalogue; `triss coder model set`
|
|
16
|
+
safely switches persistent main/small model pairs with wizard diagnostics,
|
|
17
|
+
transactional writes, and retained-record rollback recovery.
|
|
18
|
+
|
|
19
|
+
### Changed
|
|
20
|
+
|
|
21
|
+
- OpenCode Zen's preferred/offline-fallback pair now starts with
|
|
22
|
+
`opencode/deepseek-v4-flash-free` instead of the retired
|
|
23
|
+
`opencode/hy3-free`; the live catalogue remains authoritative. Existing
|
|
24
|
+
provider/model mismatches produce actionable recovery choices without
|
|
25
|
+
silently switching providers.
|
|
26
|
+
|
|
27
|
+
### Fixed
|
|
28
|
+
|
|
29
|
+
- One-shot `ask` and `review` responses now preserve providers' top-level
|
|
30
|
+
`final_text` instead of reporting an empty result after a successful call.
|
|
31
|
+
- GLM model switching no longer requires `--allow-unverified` when the provider
|
|
32
|
+
has no catalogue API; Crush accepts the documented Z.AI aliases, omitted
|
|
33
|
+
small-model values are preserved, and locks owned by dead processes can be
|
|
34
|
+
reclaimed safely.
|
|
35
|
+
|
|
10
36
|
## [0.26.0] — 2026-07-27
|
|
11
37
|
|
|
12
38
|
### Added
|
|
@@ -780,7 +806,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
780
806
|
|
|
781
807
|
- Initial release of `triss-coworker`.
|
|
782
808
|
|
|
783
|
-
[Unreleased]: https://github.com/ayleen/triss-coworker/compare/v0.
|
|
809
|
+
[Unreleased]: https://github.com/ayleen/triss-coworker/compare/v0.27.0...HEAD
|
|
810
|
+
[0.27.0]: https://github.com/ayleen/triss-coworker/compare/v0.26.0...v0.27.0
|
|
784
811
|
[0.26.0]: https://github.com/ayleen/triss-coworker/compare/v0.25.0...v0.26.0
|
|
785
812
|
[0.25.0]: https://github.com/ayleen/triss-coworker/compare/v0.24.2...v0.25.0
|
|
786
813
|
[0.24.2]: https://github.com/ayleen/triss-coworker/compare/v0.24.1...v0.24.2
|
package/README.md
CHANGED
|
@@ -271,7 +271,7 @@ and writing**.
|
|
|
271
271
|
| `triss review` | Code review on current branch or a PR (diff + linked ticket) | The agent reading the whole diff |
|
|
272
272
|
| `triss commit-msg` | Generates a commit message from staged diff | Hand-writing or copy-pasting from web LLMs |
|
|
273
273
|
| `triss usage` | Cumulative cost / token usage with per-project breakdown | Squinting at stderr after each call |
|
|
274
|
-
| `triss coder init` | Sets up a coding agent (default `opencode` engine; `--engine crush` for crush): provider key (Z.AI GLM default; `--provider opencode-zen` for free OpenCode Zen models
|
|
274
|
+
| `triss coder init` | Sets up a coding agent (default `opencode` engine; `--engine crush` for crush): provider key (Z.AI GLM default; `--provider opencode-zen` for free rotating OpenCode Zen models — discover the current id with `triss coder models`; `--provider moonshot` for Kimi pay-as-you-go; `--provider kimi-for-coding` for the Kimi subscription), `opencode.json` / crush models + `permissions.run` policy, agent templates. Blocks (non-zero) on an unsafe existing `opencode.json` — missing deny-first bash policy (override with `--allow-unsafe-bash`) or a stale/cross-provider `small_model` | Manually installing/configuring opencode |
|
|
275
275
|
| `triss coder run` | Spawns the coding agent (GLM, Kimi, or Zen models) and prints one JSON envelope (`--engine opencode\|crush`; `--isolate` for a disposable worktree — opencode defaults to isolate-OFF, crush defaults to isolate-ON; crush adds opt-in `--restrict`/`--no-restrict` for its CLI allowlist). **POSIX only** (macOS/Linux) — refuses to run on Windows. | Manually driving `opencode run` and parsing its ndjson stream |
|
|
276
276
|
| `triss coder clean` | Removes finished `.triss/wt` isolation worktrees (`--all` forces all) | Manually finding and deleting stale git worktrees |
|
|
277
277
|
| `triss init` | Drops a tiny (~15 line) delegation block into `CLAUDE.md` / `AGENTS.md` | Hand-writing routing rules |
|
|
@@ -464,8 +464,8 @@ triss coder clean # remove finished isolation wo
|
|
|
464
464
|
```
|
|
465
465
|
|
|
466
466
|
`triss coder init` first asks which provider to configure — **Z.AI GLM**
|
|
467
|
-
(default), **OpenCode Zen** (`--provider opencode-zen`, free
|
|
468
|
-
|
|
467
|
+
(default), **OpenCode Zen** (`--provider opencode-zen`, free rotating
|
|
468
|
+
models), **Moonshot Kimi** (`--provider moonshot`, pay-as-you-go
|
|
469
469
|
`moonshotai/*` models like `kimi-k2.7-code`), or **Kimi for Coding**
|
|
470
470
|
(`--provider kimi-for-coding`, the flat-rate subscription serving Kimi K3).
|
|
471
471
|
For Z.AI it probes which plan your key works with (subscription vs.
|
|
@@ -509,23 +509,17 @@ natively; triss also forwards it as `ZAI_API_KEY` for older binaries; see
|
|
|
509
509
|
**Providers** — the `opencode` engine isn't limited to Z.AI. The required
|
|
510
510
|
API key follows the model's `<provider>/` prefix: `zai-coding-plan/*` and
|
|
511
511
|
`zai/*` (GLM) use `ZHIPU_API_KEY`; `opencode/*` models — served free by
|
|
512
|
-
[OpenCode Zen](https://opencode.ai/docs/zen/)
|
|
513
|
-
(
|
|
514
|
-
|
|
515
|
-
`kimi-for-coding/*` models — the flat-rate
|
|
512
|
+
[OpenCode Zen](https://opencode.ai/docs/zen/) — use `OPENCODE_API_KEY`;
|
|
513
|
+
`moonshotai/*` (and the China-mainland `moonshotai-cn/*`) Kimi models use
|
|
514
|
+
`MOONSHOT_API_KEY`; and `kimi-for-coding/*` models — the flat-rate
|
|
516
515
|
[Kimi for Coding](https://www.kimi.com/code/docs/en/) subscription, e.g.
|
|
517
|
-
**`kimi-for-coding/k3`** (Kimi K3) — use `KIMI_API_KEY`.
|
|
518
|
-
|
|
516
|
+
**`kimi-for-coding/k3`** (Kimi K3) — use `KIMI_API_KEY`. Zen ids rotate
|
|
517
|
+
freely, so discover the current id and pass it rather than hard-coding one:
|
|
519
518
|
|
|
520
519
|
```bash
|
|
521
|
-
triss coder init --provider opencode-zen
|
|
522
|
-
#
|
|
523
|
-
triss
|
|
524
|
-
export TRISS_CODER_MODEL=opencode/hy3-free # default it for every run
|
|
525
|
-
export TRISS_CODER_SMALL_MODEL=opencode/hy3-free
|
|
526
|
-
triss coder run "add input validation to /signup"
|
|
527
|
-
# …or per-run, without changing the default:
|
|
528
|
-
triss coder run "..." --model opencode/hy3-free
|
|
520
|
+
triss coder init --provider opencode-zen # guided: key + opencode.json
|
|
521
|
+
triss coder models --provider opencode-zen # see live Zen ids
|
|
522
|
+
triss coder run "..." --model opencode/<current-id> # per-run override
|
|
529
523
|
```
|
|
530
524
|
|
|
531
525
|
Kimi works the same way:
|
|
@@ -539,13 +533,16 @@ triss coder run "..." --model kimi-for-coding/k3
|
|
|
539
533
|
```
|
|
540
534
|
|
|
541
535
|
`triss coder run` passes the resolved model to opencode with `--model` and
|
|
542
|
-
forwards only the key that model needs
|
|
543
|
-
`
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
536
|
+
forwards only the key that model needs — no Z.AI key is required for Zen or
|
|
537
|
+
Kimi runs. A shell-exported `TRISS_CODER_MODEL` is a runtime override of the
|
|
538
|
+
MAIN model only (it sits in the OpenCode-main precedence chain: one-run `--model`
|
|
539
|
+
→ shell `TRISS_CODER_MODEL` → project `.triss.env` → global `.env` → built-in
|
|
540
|
+
default), so it changes the main model for every run until unset.
|
|
541
|
+
`TRISS_CODER_SMALL_MODEL` is setup intent consumed by `triss coder init` /
|
|
542
|
+
`triss coder model` — it does not swap the small model mid-run (opencode reads
|
|
543
|
+
`small_model` from `opencode.json`); use `--model` for a one-run main-model
|
|
544
|
+
override. The deny-first `opencode.json` bash policy applies to every provider.
|
|
545
|
+
Full details, the model catalogue, and every configuration path are in
|
|
549
546
|
[docs/opencode-zen.md](docs/opencode-zen.md).
|
|
550
547
|
|
|
551
548
|
If your Z.AI plan hits its usage limit, `triss coder run` fails fast with
|
|
@@ -555,6 +552,73 @@ opencode retries the throttled call silently, so the reset time is read
|
|
|
555
552
|
from the engine log and the run is killed within a few seconds of the
|
|
556
553
|
limit.
|
|
557
554
|
|
|
555
|
+
**Model management — engine vs provider.** Two independent axes; most
|
|
556
|
+
confusion is conflating them:
|
|
557
|
+
|
|
558
|
+
- **Engine** = *how* the agent is launched: `opencode` (default) or
|
|
559
|
+
`crush`. Set at `triss coder init --engine …` or per run with
|
|
560
|
+
`triss coder run --engine …`.
|
|
561
|
+
- **Provider** = *which* API serves the model: Z.AI GLM, OpenCode Zen,
|
|
562
|
+
Moonshot Kimi, Kimi for Coding. Set at `triss coder init --provider …`.
|
|
563
|
+
|
|
564
|
+
Not every engine speaks every provider:
|
|
565
|
+
|
|
566
|
+
| Engine | Providers served |
|
|
567
|
+
| ---------- | ------------------------------------------------- |
|
|
568
|
+
| `opencode` | Z.AI GLM, OpenCode Zen, Moonshot, Kimi for Coding |
|
|
569
|
+
| `crush` | Z.AI GLM (coding-plan only) |
|
|
570
|
+
|
|
571
|
+
`triss coder init` drives setup in that order — **engine, then provider,
|
|
572
|
+
then it asks for only that provider's credential** and writes the matching
|
|
573
|
+
model prefix (`opencode/<id>`, `zai-coding-plan/*`, `moonshotai/*`, or
|
|
574
|
+
`kimi-for-coding/*`).
|
|
575
|
+
|
|
576
|
+
**Choosing a model.** `--model` on `triss coder run` is a
|
|
577
|
+
**single-run override of the main model only** — it does not persist
|
|
578
|
+
and does not change the small/summarization model. To persist a
|
|
579
|
+
choice, use `triss coder model set` — positional main plus `--small` —
|
|
580
|
+
which requires you to name the engine and the scope explicitly:
|
|
581
|
+
|
|
582
|
+
```bash
|
|
583
|
+
# global, opencode engine: positional main + --small; --yes for noninteractive use
|
|
584
|
+
triss coder model set --engine opencode --global \
|
|
585
|
+
opencode/<id> --small opencode/<id> --yes
|
|
586
|
+
# local, crush engine: canonical coding-plan GLM pair
|
|
587
|
+
triss coder model set --engine crush --local \
|
|
588
|
+
zai-coding-plan/glm-5.2 --small zai-coding-plan/glm-5-turbo --yes
|
|
589
|
+
```
|
|
590
|
+
|
|
591
|
+
**Discovering models.** `triss coder models` lists what the resolved
|
|
592
|
+
engine/provider offers for that invocation, with filters and a
|
|
593
|
+
machine-readable form:
|
|
594
|
+
|
|
595
|
+
```bash
|
|
596
|
+
triss coder models # current effective engine/provider
|
|
597
|
+
triss coder models --engine opencode # resolved provider for the OpenCode engine
|
|
598
|
+
triss coder models --provider opencode-zen # just OpenCode Zen
|
|
599
|
+
triss coder models --json # for scripting
|
|
600
|
+
```
|
|
601
|
+
|
|
602
|
+
**When a Zen model goes stale.** Free OpenCode Zen models rotate — no
|
|
603
|
+
specific id is guaranteed to stay (the once-free `opencode/hy3-free`
|
|
604
|
+
Hunyuan model is the canonical stale-model incident). If a model is
|
|
605
|
+
removed upstream, recovery stays **inside Zen**, not a silent jump to
|
|
606
|
+
GLM. See what is live and re-pick explicitly:
|
|
607
|
+
|
|
608
|
+
```bash
|
|
609
|
+
triss coder models --provider opencode-zen # current Zen ids
|
|
610
|
+
triss coder model set --engine opencode --global \
|
|
611
|
+
opencode/<current-id> --small opencode/<current-id> --yes
|
|
612
|
+
```
|
|
613
|
+
|
|
614
|
+
Triss surfaces that replacement command rather than auto-switching you
|
|
615
|
+
to GLM.
|
|
616
|
+
|
|
617
|
+
Full flag reference, the model catalogues, key/endpoint routing, and
|
|
618
|
+
the stale-model recovery flow are in [docs/glm-clients.md](docs/glm-clients.md),
|
|
619
|
+
[docs/opencode-zen.md](docs/opencode-zen.md), and
|
|
620
|
+
[docs/configuration.md](docs/configuration.md).
|
|
621
|
+
|
|
558
622
|
## Integrations
|
|
559
623
|
|
|
560
624
|
External-service plugins live under `src/integrations/<name>/`. They are
|
|
@@ -636,6 +700,12 @@ triss review --provider kimi # pro preset → kimi-k3
|
|
|
636
700
|
triss ask --paths ... --question "..." --provider kimi --model flash # kimi-k2.6
|
|
637
701
|
```
|
|
638
702
|
|
|
703
|
+
One-shot `ask` / `review` output is provider-shape tolerant: Triss emits the
|
|
704
|
+
assistant text whether the successful response carries OpenAI-style
|
|
705
|
+
`choices[0].message.content` or a top-level `final_text`. A present
|
|
706
|
+
`final_text` must never be treated as an empty response or dropped by the CLI
|
|
707
|
+
or MCP renderer.
|
|
708
|
+
|
|
639
709
|
For GLM, `pro` maps to `glm-5.2` on both endpoints, while `flash` — the cheap
|
|
640
710
|
bulk-read tier — maps to `glm-4.7` on the subscription endpoint and to
|
|
641
711
|
`glm-4.5-air` ($0.20/$1.10 per 1M) on pay-as-you-go. The subscription endpoint
|
package/bin/triss.js
CHANGED
|
@@ -39,6 +39,7 @@ import {
|
|
|
39
39
|
runUnset,
|
|
40
40
|
} from '../src/commands/config.js';
|
|
41
41
|
import { runCoderInit, runCoderRun, runCoderClean } from '../src/commands/coder.js';
|
|
42
|
+
import { runCoderModels, runCoderModelSet, runCoderModelRollback } from '../src/commands/coder-models.js';
|
|
42
43
|
import { loadIntegrations } from '../src/integrations/_registry.js';
|
|
43
44
|
import { withCall } from '../src/call-context.js';
|
|
44
45
|
|
|
@@ -181,6 +182,8 @@ config
|
|
|
181
182
|
.option('-f, --force', 're-prompt for keys that are already set')
|
|
182
183
|
.option('--standard', 'API key + one model only — skip the standard/advanced prompt')
|
|
183
184
|
.option('--advanced', 'full wizard with presets, base URL, integrations — skip the prompt')
|
|
185
|
+
.option('--coder-engine <name>', 'coder target only: coding engine to configure (opencode default, or crush). `coder init` uses --engine')
|
|
186
|
+
.option('--coder-provider <name>', 'coder target only: opencode engine provider (zai, opencode-zen, moonshot, kimi-for-coding). `coder init` uses --provider')
|
|
184
187
|
.action(wrap(runWizard));
|
|
185
188
|
|
|
186
189
|
config
|
|
@@ -227,7 +230,7 @@ config
|
|
|
227
230
|
|
|
228
231
|
const coder = program
|
|
229
232
|
.command('coder')
|
|
230
|
-
.description('Run a
|
|
233
|
+
.description('Run a coding agent (OpenCode or Crush engine)');
|
|
231
234
|
|
|
232
235
|
coder
|
|
233
236
|
.command('init')
|
|
@@ -235,7 +238,7 @@ coder
|
|
|
235
238
|
.option('-g, --global', 'save to the global scope (~/.config/triss/.env, ~/.config/opencode/)')
|
|
236
239
|
.option('-l, --local', 'save to the project scope (./.triss.env, ./opencode.json)')
|
|
237
240
|
.option('--engine <name>', 'coding engine to configure: opencode (default) or crush')
|
|
238
|
-
.option('--provider <name>', 'opencode engine model provider: zai (Z.AI GLM, default), opencode-zen (free models
|
|
241
|
+
.option('--provider <name>', 'opencode engine model provider: zai (Z.AI GLM, default), opencode-zen (free rotating models — discover with `triss coder models`), moonshot (Kimi pay-as-you-go), or kimi-for-coding (subscription)')
|
|
239
242
|
.option('--allow-unsafe-bash', 'proceed even if an existing opencode.json has no deny-first bash policy (the agent runs with --auto)')
|
|
240
243
|
.action(wrap(runCoderInit));
|
|
241
244
|
|
|
@@ -246,7 +249,7 @@ coder
|
|
|
246
249
|
.option('--session <id>', 'triss-side session slug, mapped to a real opencode session id in .triss/sessions.json')
|
|
247
250
|
.option('--continue', 'continue the most recent opencode session (maps to opencode --continue)')
|
|
248
251
|
.option('--agent <name>', 'opencode agent template to use', 'coder')
|
|
249
|
-
.option('--model <p/m>', 'override the model for this run only')
|
|
252
|
+
.option('--model <p/m>', 'override the MAIN model for this one run only (does not change small_model or repair persistent config; use `triss coder model set` for that)')
|
|
250
253
|
.option('--isolate', 'run in a disposable git worktree under .triss/wt/<slug>')
|
|
251
254
|
.option('--no-isolate', 'disable worktree isolation (opencode defaults to OFF; crush defaults to ON)')
|
|
252
255
|
.option('--restrict', 'crush only: enforce the allowlist via CLI --allow-bash/--allow-tool flags (--restrict-run). Opt-in (default OFF)')
|
|
@@ -263,6 +266,51 @@ coder
|
|
|
263
266
|
.option('--all', 'force-remove every worktree under .triss/wt, regardless of diff state')
|
|
264
267
|
.action(wrap(runCoderClean));
|
|
265
268
|
|
|
269
|
+
coder
|
|
270
|
+
.command('models')
|
|
271
|
+
.description('List current + live coder models, provider compatibility, and credential readiness (read-only)\n\n' +
|
|
272
|
+
'Configuration sources:\n' +
|
|
273
|
+
' • opencode: project opencode.json (local) or ~/.config/opencode/opencode.json (global)\n' +
|
|
274
|
+
' • crush: ./.crush/crush.json (local) or ~/.local/share/crush/crush.json (global)')
|
|
275
|
+
.option('--engine <name>', 'coding engine: opencode (default) or crush')
|
|
276
|
+
.option('--provider <name>', 'provider kind: zai, opencode-zen, moonshot, or kimi-for-coding')
|
|
277
|
+
.option('--json', 'print the stable machine-readable state object (no secrets)')
|
|
278
|
+
.action(wrap(runCoderModels));
|
|
279
|
+
|
|
280
|
+
// `coder model` is a command GROUP whose only leaf today is `set`. Registered
|
|
281
|
+
// as a nested group so `triss coder model set --help` prints its OWN usage line
|
|
282
|
+
// (`Usage: triss coder model set ...`) rather than the parent `coder` usage.
|
|
283
|
+
const coderModel = coder
|
|
284
|
+
.command('model')
|
|
285
|
+
.description('Inspect or change persistent coder models (e.g. `triss coder model set`)');
|
|
286
|
+
|
|
287
|
+
coderModel
|
|
288
|
+
.command('set [main-model]')
|
|
289
|
+
.description(
|
|
290
|
+
'Persistently switch the coder main/small models for one engine+scope (non-interactive; needs --yes to write). ' +
|
|
291
|
+
'A one-run main override is `triss coder run --model` (main-only, not a persistent repair).\n\n' +
|
|
292
|
+
'Engines and configuration targets:\n' +
|
|
293
|
+
' • opencode: project opencode.json (local) or ~/.config/opencode/opencode.json (global); runtime main follows TRISS_CODER_MODEL env precedence, config main is opencode.json.model\n' +
|
|
294
|
+
' • crush: project .crush/crush.json (local) or ~/.local/share/crush/crush.json (global)'
|
|
295
|
+
)
|
|
296
|
+
.option('--small <model>', 'small/fast model id (omit to keep the current compatible value)')
|
|
297
|
+
.option('--engine <name>', 'coding engine: opencode (default) or crush')
|
|
298
|
+
.option('--provider <name>', 'provider kind: zai, opencode-zen, moonshot, or kimi-for-coding')
|
|
299
|
+
.option('-g, --global', 'write to the global scope (OpenCode: ~/.config/opencode/opencode.json + global .env; Crush: ~/.local/share/crush/crush.json)')
|
|
300
|
+
.option('-l, --local', 'write to the project scope (OpenCode: ./opencode.json + ./.triss.env; Crush: ./.crush/crush.json)')
|
|
301
|
+
.option('--allow-unverified', 'proceed past a not-verified catalogue (timeout/http-error/parse-error) ONLY — never auth or an authoritative unavailable result')
|
|
302
|
+
.option('--allow-unsafe-bash', 'proceed even if the existing opencode.json lacks the deny-first bash policy')
|
|
303
|
+
.option('--yes', 'non-interactive confirmation: apply the planned switch (required to write; without it the plan is printed and nothing is changed)')
|
|
304
|
+
.action((mainModel, opts) => wrap(runCoderModelSet)(mainModel, opts));
|
|
305
|
+
|
|
306
|
+
coderModel
|
|
307
|
+
.command('rollback')
|
|
308
|
+
.description('Restore retained transaction record (opencode.json / crush.json + env pins)')
|
|
309
|
+
.requiredOption('--from <absolute-record-dir>', 'absolute path to the retained transaction record directory')
|
|
310
|
+
.option('-g, --global', 'restore to the global scope (~/.config/opencode/ or ~/.local/share/crush/)')
|
|
311
|
+
.option('-l, --local', 'restore to the project scope (./opencode.json or ./.crush/crush.json)')
|
|
312
|
+
.action((opts) => wrap(runCoderModelRollback)(opts.from, opts));
|
|
313
|
+
|
|
266
314
|
function wrap(fn) {
|
|
267
315
|
return async (...args) => {
|
|
268
316
|
try {
|