triss-coworker 0.35.0 → 0.37.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 +224 -0
- package/README.md +72 -5
- package/bin/triss.js +94 -12
- package/docs/coder-one-shot-provider-plan.md +14 -0
- package/docs/configuration.md +18 -4
- package/docs/glm-clients.md +17 -16
- package/docs/mcp.md +22 -4
- package/docs/opencode2-engine-plan.md +1280 -0
- package/docs/opencode2.md +110 -0
- package/docs/reliable-delegation-contract-plan.md +37 -8
- package/docs/reliable-delegation-release-a.md +263 -0
- package/docs/usage-accounting.md +3 -3
- package/package.json +2 -2
- package/src/coder-credential-proxy.js +443 -0
- package/src/coder-engines/crush.js +10 -1
- package/src/coder-engines/opencode2.js +414 -0
- package/src/coder-git-mediator.js +226 -0
- package/src/coder-lease.js +240 -0
- package/src/coder-lock.js +5 -1
- package/src/coder-models.js +231 -44
- package/src/coder-orchestration.js +211 -0
- package/src/coder-process-supervisor.js +159 -0
- package/src/coder-result-owner-adapter.js +108 -0
- package/src/coder-result-quarantine.js +358 -0
- package/src/coder-result-registry-codec.js +231 -0
- package/src/coder-result-transitions.js +297 -0
- package/src/coder-result.js +542 -0
- package/src/coder-run-state.js +98 -0
- package/src/coder-sandbox.js +270 -0
- package/src/coder-session-inventory-codec.js +275 -0
- package/src/coder-session-owner-adapter.js +177 -0
- package/src/coder-session-store.js +327 -0
- package/src/coder-session-transitions.js +296 -0
- package/src/coder-state-backup.js +384 -0
- package/src/coder-state.js +346 -0
- package/src/coder-write-quota.js +171 -0
- package/src/commands/ask.js +2 -10
- package/src/commands/coder-models.js +32 -0
- package/src/commands/coder-state-backup.js +80 -0
- package/src/commands/coder.js +2009 -111
- package/src/commands/exec.js +8 -1
- package/src/commands/review.js +310 -54
- package/src/commands/status.js +14 -0
- package/src/config.js +103 -1
- package/src/fixed-kernel-lock.js +243 -0
- package/src/integrations/_contract.js +55 -16
- package/src/managed-root.js +253 -0
- package/src/mcp/handlers.js +95 -3
- package/src/mcp/review-core.js +310 -36
- package/src/mcp/tools.js +79 -6
- package/src/opencode-config.js +523 -0
- package/src/opencode2-preflight.js +724 -0
- package/src/owned-process-journal.js +310 -0
- package/src/owned-process-reconcile.js +298 -0
- package/src/provider-errors.js +300 -0
- package/src/release-a-acceptance.js +605 -0
- package/src/review-executor.js +218 -0
- package/src/review-git.js +320 -0
- package/src/review-input.js +142 -0
- package/src/review-live.js +75 -0
- package/src/review-payload.js +379 -0
- package/src/review-pr-fetch.js +158 -0
- package/src/review-pr-identity.js +154 -0
- package/src/review-pr-metadata.js +112 -0
- package/src/review-pr-registry.js +267 -0
- package/src/review-pr.js +161 -0
- package/src/review-scoped.js +265 -0
- package/src/update/install.js +1 -1
- package/src/usage.js +30 -5
- package/src/worktree-fingerprint.js +302 -0
- package/templates/claude-full.md +16 -4
- package/templates/claude.md +2 -1
- package/templates/codex-full.md +4 -2
- package/templates/codex.md +2 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,10 +7,213 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.37.0] — 2026-08-18
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- **Reliable delegation (Release C)** — sequential sharding per
|
|
15
|
+
`docs/reliable-delegation-contract-plan.md`:
|
|
16
|
+
- `--payload-mode shard` CLI + MCP shard parity: source-ordered
|
|
17
|
+
whole-file shards (a file is never split across shards);
|
|
18
|
+
- sequential executor with first-failure stop, cancellation
|
|
19
|
+
between/in-flight shards, fresh limit re-checks, and per-shard
|
|
20
|
+
attempt/usage facts;
|
|
21
|
+
- **no global verdict**: completed sharded execution prints
|
|
22
|
+
`global verdict: unavailable_for_sharded`; no aggregation call, no
|
|
23
|
+
cross-shard analysis, no global approval;
|
|
24
|
+
- structured partial errors carry completed shard verdicts only —
|
|
25
|
+
never completed prose or raw diff content;
|
|
26
|
+
- `evidence + shard` and `shard + --stream` rejected before any model
|
|
27
|
+
call;
|
|
28
|
+
- Release C synthetic acceptance (`--synthetic --release C`) and live
|
|
29
|
+
acceptance (`--live --release C`; PASS / SKIPPED_NO_CREDENTIALS /
|
|
30
|
+
BLOCKED_ENVIRONMENT recorded separately, never upgraded to success).
|
|
31
|
+
|
|
32
|
+
- **Reliable delegation (Release B)** — bounded single review, exact PR
|
|
33
|
+
diff acquisition, and the issue trust boundary per
|
|
34
|
+
`docs/reliable-delegation-contract-plan.md`:
|
|
35
|
+
- reloadable review limits (`TRISS_REVIEW_SINGLE_MAX_BYTES`,
|
|
36
|
+
`TRISS_REVIEW_SHARD_MAX_BYTES`, `TRISS_REVIEW_TOTAL_MAX_BYTES`,
|
|
37
|
+
`TRISS_REVIEW_MAX_SHARDS`) with atomic validation and full-default
|
|
38
|
+
fallback on contradictions;
|
|
39
|
+
- pure diff parser with exact byte accounting and coverage model
|
|
40
|
+
(repository vs requested-scope axes);
|
|
41
|
+
- exact merge-base-to-head comparison identity with sanitized Git
|
|
42
|
+
execution (no external diff/textconv/config, grafts and nonempty
|
|
43
|
+
shallow repositories rejected) and sealed empty-attribute projection;
|
|
44
|
+
- inventory-first rename expansion (old-only/new-only selection keeps
|
|
45
|
+
both sides) and selected-content acquisition bounded by pathspec;
|
|
46
|
+
- bounded PR acquisition: canonical input, minimum-field `gh`
|
|
47
|
+
metadata, disposable bare repository under a registry lock (three
|
|
48
|
+
concurrent runs, 120 MiB pack / 128 MiB filesystem quotas), exact
|
|
49
|
+
OID re-verification, source-common-dir immutability;
|
|
50
|
+
- streaming bounded stdin with no partial buffering;
|
|
51
|
+
- issue trust boundary: PR prose never triggers tracker access;
|
|
52
|
+
explicit `--issue` uses minimum-field bounded queries; `--skip-issue`
|
|
53
|
+
deprecated;
|
|
54
|
+
- shared single-review executor with stable error codes
|
|
55
|
+
(`TRISS_REVIEW_LIMIT`, `TRISS_REVIEW_INVALID_INPUT`,
|
|
56
|
+
`TRISS_PROVIDER_EMPTY`, `TRISS_CANCELLED`) and scoped verdict
|
|
57
|
+
framing; MCP single-review parity with root enforcement and
|
|
58
|
+
structured coverage.
|
|
59
|
+
|
|
60
|
+
### Fixed
|
|
61
|
+
|
|
62
|
+
- `triss coder run --isolate` / `triss_coder_run` isolation downgrade
|
|
63
|
+
(`--allow-best-effort-caller-worktree` /
|
|
64
|
+
`allowBestEffortCallerWorktree`): exact opt-in semantics, stable
|
|
65
|
+
public codes `TRISS_CODER_ISOLATION_ENFORCEMENT_REQUIRED` and
|
|
66
|
+
`TRISS_CODER_ISOLATION_DOWNGRADED` in message + `err.code` +
|
|
67
|
+
stderr + envelope warnings, and `effective_isolation:
|
|
68
|
+
best_effort_caller_worktree` (advisory-only); mechanism
|
|
69
|
+
unavailability downgrades while slug/branch conflicts
|
|
70
|
+
(`already exists`) fail closed even with the opt-in via stable
|
|
71
|
+
`err.code` dispatch (no message parsing).
|
|
72
|
+
|
|
73
|
+
### Artifact integrity (0.37.0)
|
|
74
|
+
|
|
75
|
+
- `triss-dsh-provider-bundle-0.37.0.tgz` — sha256
|
|
76
|
+
`6fd343622443b8e2b15a0d0365fa6a893054d7eb51a26fc1bca5db3c0e068b2d`,
|
|
77
|
+
integrity `sha512-lBTCSU8kRHm5YN9twwnw1F5wH0OXuU8iwkKyQjXSZVaVCq5ga7z20BirXCJo65rMfcMLVBrbsl1GMXYXCqzpyw==`
|
|
78
|
+
(computed with the pinned release npm 11.6.2 via
|
|
79
|
+
`scripts/publish-gate.js pack-inspect`; `npm pack` output is
|
|
80
|
+
byte-deterministic — tar entries carry the fixed npm epoch mtime — so a
|
|
81
|
+
test pins this value against every future pack of the same content).
|
|
82
|
+
- Root `triss-coworker-0.37.0.tgz` sha256 is reproducible via
|
|
83
|
+
`npm pack` at tag `v0.37.0` (the root tarball ships `CHANGELOG.md`, so its
|
|
84
|
+
hash cannot be recorded inside this file); registry verification compares
|
|
85
|
+
the packed artifact against the published tarball byte-for-byte
|
|
86
|
+
(`scripts/publish-gate.js pack-inspect`).
|
|
87
|
+
|
|
88
|
+
## [0.36.0] — 2026-08-18
|
|
89
|
+
|
|
90
|
+
### Added
|
|
91
|
+
|
|
92
|
+
- **OpenCode 2 coder engine (beta)**: `triss coder run --engine opencode2`
|
|
93
|
+
and `triss coder init --engine opencode2`, pinned to the exact verified
|
|
94
|
+
build `@opencode-ai/cli@0.0.0-next-17430` (`TRISS_CODER_OPENCODE2_VERSION`
|
|
95
|
+
to override). The beta runs every managed invocation `--standalone` with
|
|
96
|
+
auto-update disabled, isolates V2 state under `<project>/.triss/opencode2/`
|
|
97
|
+
(0700), folds the V2 event stream into the shared usage envelope
|
|
98
|
+
(`usage_source: "opencode2"`, terminal-error precedence, no fabricated
|
|
99
|
+
zeros), namespaces sessions per engine, and rides the shared opencode-v1
|
|
100
|
+
configuration backend for `coder model set` / rollback. See
|
|
101
|
+
docs/opencode2.md and docs/opencode2-engine-plan.md.
|
|
102
|
+
|
|
103
|
+
### Security (opencode2 engine beta)
|
|
104
|
+
|
|
105
|
+
- Fail-closed effective-configuration preflight for `coder run --engine
|
|
106
|
+
opencode2`: the managed provider projection (exact package, settings keys,
|
|
107
|
+
credential placeholder, and the worker `baseURL` compared against the
|
|
108
|
+
configured Triss worker endpoint), `provider.api` and model-level
|
|
109
|
+
transport overrides are rejected before any credential is forwarded, and
|
|
110
|
+
the permission gate requires deny-everything shell policy (no live
|
|
111
|
+
allow/ask rule — the credential sits in the child environment), proven
|
|
112
|
+
with a real last-match-wins evaluator.
|
|
113
|
+
- `opencode2` runs resolve the engine binary to an absolute path
|
|
114
|
+
(`which` + `realpath`) and spawn exactly that path, re-verifying the same
|
|
115
|
+
path and version after the run.
|
|
116
|
+
- Session store reads fail closed on malformed namespaces (no silent data
|
|
117
|
+
loss on rewrite); the lookup happens inside the isolation cleanup guard so
|
|
118
|
+
a malformed store never leaks a worktree/branch.
|
|
119
|
+
- XDG runtime roots reject symlinked path components anywhere in the chain
|
|
120
|
+
below the project root.
|
|
121
|
+
- `opencode init --engine opencode2` owns its flow: credential prompt and
|
|
122
|
+
`--local`/`--global` scope are honored, an exact-pin mismatch is terminal
|
|
123
|
+
before any config mutation, and the post-setup audit is the full provider
|
|
124
|
+
+ permission preflight (not just the plugin/agent scan).
|
|
125
|
+
- The full run preflight parses config layers through the JSONC-aware
|
|
126
|
+
canonical parser (comments and trailing commas no longer abort the run),
|
|
127
|
+
and `parseOpenCodeDocument` drops trailing commas followed by comments.
|
|
128
|
+
|
|
129
|
+
### Fixed (review rounds 4–6)
|
|
130
|
+
|
|
131
|
+
- Dual legacy/native config forms (`provider`+`providers`,
|
|
132
|
+
`plugin`+`plugins`, `permission`+`permissions`) reject — the pinned build
|
|
133
|
+
prefers the native value while a legacy-first projection audits the other
|
|
134
|
+
one; the worker key/endpoint provenance gate resolves each field's
|
|
135
|
+
EFFECTIVE source from the pre-dotenv snapshot (a decoy key in the project
|
|
136
|
+
`.triss.env` cannot mask a shell key); unrelated provider definitions
|
|
137
|
+
(in-process npm code) reject; the audit walks the canonical
|
|
138
|
+
(`realpathSync.native`) runtime directory; audited sources are re-audited
|
|
139
|
+
immediately before the credential-bearing spawn (TOCTOU); the top-level
|
|
140
|
+
key table is captured from the official schema (benign keys no longer
|
|
141
|
+
false-reject; object `lsp`/`formatter` and `experimental` reject).
|
|
142
|
+
- A held session-store lock no longer discards a finished run:
|
|
143
|
+
`persistSessionMapping` retries with backoff and degrades to the lock-free
|
|
144
|
+
protocol (mapping kept, warning emitted, foreign lock untouched).
|
|
145
|
+
- A corrupted `sessions.json` on the V1 `--isolate` path no longer strands
|
|
146
|
+
the `.triss/wt/<slug>` worktree and `coder/<slug>` branch.
|
|
147
|
+
- `TRISS_CODER_ENGINE=opencode2` from a `.env` file now routes `coder init`
|
|
148
|
+
to the V2 flow (the engine is resolved after the env files load); the
|
|
149
|
+
pre-dotenv snapshots are threaded through so the provenance and
|
|
150
|
+
pin-shadow checks stay exact.
|
|
151
|
+
- `coder init --engine opencode2` on a tree carrying the V1 bash allowlist
|
|
152
|
+
rejects BEFORE any credential/config write with actionable guidance; a
|
|
153
|
+
fresh V2 init warns that the shared deny-everything policy removes the
|
|
154
|
+
allowlisted commands from plain V1 runs (documented in
|
|
155
|
+
docs/opencode2.md, including two new troubleshooting rows).
|
|
156
|
+
- Model inspection tolerates unrelated hostile config shapes (a non-string
|
|
157
|
+
plugin reference, unreadable directories) — the post-commit audit of a
|
|
158
|
+
successful `coder model set` no longer rolls back over them; `coder
|
|
159
|
+
models` warnings use the OpenCode branch for `opencode2` (no false
|
|
160
|
+
`configured-model-unavailable` for a shell-exported foreign model);
|
|
161
|
+
rollback of an `opencode2` record reports engine `opencode2`.
|
|
162
|
+
- `opencode-go/` routes price as unknown (the Go reseller's tariffs are
|
|
163
|
+
unmodeled); the prefixed `TRISS_PRICE_OPENCODE_GO_<MODEL>` override is
|
|
164
|
+
the documented way to price them.
|
|
165
|
+
- Unknown `engines.*` namespaces in the session store fail closed;
|
|
166
|
+
`ensureOpenCode2RuntimeDirs` reports the directories it created;
|
|
167
|
+
`.env.example` documents `TRISS_CODER_OPENCODE2_VERSION`.
|
|
168
|
+
|
|
169
|
+
### Artifact integrity (0.36.0)
|
|
170
|
+
|
|
171
|
+
- `triss-dsh-provider-bundle-0.36.0.tgz` — sha256
|
|
172
|
+
`0e3100362fc02d242deac114ec6e0c4c966bbe5edde4f156a2ffdb76ef2eb329`,
|
|
173
|
+
integrity `sha512-P2QoA6Ahu/J9swIJhk9IkuP1OLR+bzn4zJdUKyuskutbis2GUSt5m3n+QmqP7B0rB1JAqi0WGIMkUrTBcmf9cQ==`
|
|
174
|
+
(computed with the pinned release npm 11.6.2 via
|
|
175
|
+
`scripts/publish-gate.js pack-inspect`; `npm pack` output is
|
|
176
|
+
byte-deterministic — tar entries carry the fixed npm epoch mtime — so a
|
|
177
|
+
test pins this value against every future pack of the same content).
|
|
178
|
+
- Root `triss-coworker-0.36.0.tgz` sha256 is reproducible via
|
|
179
|
+
`npm pack` at tag `v0.36.0` (the root tarball ships `CHANGELOG.md`, so its
|
|
180
|
+
hash cannot be recorded inside this file); registry verification compares
|
|
181
|
+
the packed artifact against the published tarball byte-for-byte
|
|
182
|
+
(`scripts/publish-gate.js pack-inspect`).
|
|
183
|
+
|
|
10
184
|
## [0.35.0] — 2026-08-14
|
|
11
185
|
|
|
12
186
|
### Added
|
|
13
187
|
|
|
188
|
+
- **Reliable delegation (Release A)** — coder envelope v2 orchestration per
|
|
189
|
+
`docs/reliable-delegation-contract-plan.md`:
|
|
190
|
+
- envelope fields `session_slug`, `result_retention`, `result_id`, and
|
|
191
|
+
`execution_capabilities` (eight honest `enforced|best_effort|unavailable`
|
|
192
|
+
values + `effective_isolation`) on every safe envelope
|
|
193
|
+
(`docs/reliable-delegation-release-a.md`);
|
|
194
|
+
- v2 session CLI: `triss coder session list`, `triss coder session clean
|
|
195
|
+
<slug> --engine <opencode|crush>` (per-engine store only, legacy
|
|
196
|
+
`.triss/sessions.json` never touched);
|
|
197
|
+
- retained-result registry: `triss coder result list`, `triss coder result
|
|
198
|
+
clean <run-id>`, and the exact result-registry codec/transitions
|
|
199
|
+
(1 GiB reservation / 3 GiB payload budget + 1 GiB headroom,
|
|
200
|
+
`TRISS_CODER_RESULT_CAP`, `TRISS_CODER_RESULT_QUOTA_REQUIRED`);
|
|
201
|
+
- rollback contract: `triss coder state backup|validate|adopt|reset` with
|
|
202
|
+
bounded no-follow backup, completion marker, and
|
|
203
|
+
`TRISS_CODER_ROLLBACK_RESULTS_PENDING` guard;
|
|
204
|
+
- quarantine transaction and quarantine clean (`quarantine-v1`,
|
|
205
|
+
phase-aware manifest machine, completion-marker hashing);
|
|
206
|
+
- credential proxy (loopback one-run token) on both engines — the real
|
|
207
|
+
provider key never reaches the engine environment; every run requires
|
|
208
|
+
the proxy (Release A rejects runs when it is unavailable);
|
|
209
|
+
- pure provider error classifier with stable public codes
|
|
210
|
+
(`TRISS_PROVIDER_AUTH/POLICY/RATE/TIMEOUT/NOT_FOUND/CONNECTION/UNKNOWN/
|
|
211
|
+
CONFLICT/EMPTY`);
|
|
212
|
+
- bounded blocker diagnostics (`environment_permission`,
|
|
213
|
+
`execution_policy`, `lock_or_process_state`, `unknown`; ≤16 entries,
|
|
214
|
+
duplicate categories collapsed);
|
|
215
|
+
- MCP: `allowBestEffortCallerWorktree` (default false),
|
|
216
|
+
`triss_coder_result_list`, `triss_coder_result_clean`.
|
|
14
217
|
- `triss-dsh-provider-bundle`, a standalone npm package (workspace
|
|
15
218
|
`packages/dsh-provider-bundle`) that activates the DeepSeek Harness
|
|
16
219
|
`llm-pi-ai` adapter for `opencode`, `opencode-go`, and `zai` routes in a
|
|
@@ -80,6 +283,27 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
80
283
|
the packed artifact against the published tarball byte-for-byte
|
|
81
284
|
(`scripts/publish-gate.js pack-inspect`).
|
|
82
285
|
|
|
286
|
+
### Changed
|
|
287
|
+
|
|
288
|
+
- Non-isolated `files_changed` is now `null` rather than `[]`;
|
|
289
|
+
`run_files_changed` is the only changes-expectation evidence. Consumers
|
|
290
|
+
must branch on `envelope_version` and `change_detection.status`.
|
|
291
|
+
- Bare `--continue` is rejected with migration guidance; v2 state is
|
|
292
|
+
selected only via `--session <slug>`.
|
|
293
|
+
- `ask`/`review`/MCP fail empty responses with the stable
|
|
294
|
+
`TRISS_PROVIDER_EMPTY` code instead of a direct `process.exit`.
|
|
295
|
+
- Capability-dependent Windows npm support wording: an unavailable OS
|
|
296
|
+
sandbox/cleanup/lock/quota never blocks a non-isolated/best-effort run but
|
|
297
|
+
provides none of those guarantees; unavailable credential isolation always
|
|
298
|
+
blocks before spawn.
|
|
299
|
+
|
|
300
|
+
### Fixed
|
|
301
|
+
|
|
302
|
+
- `fd.readFile` position semantics in fixed-kernel-lock release (marker
|
|
303
|
+
clearing reads via path, keeping the fixed inode).
|
|
304
|
+
- Quarantine `readdir` import; result-state deletion moved to an immutable
|
|
305
|
+
tombstone sidecar.
|
|
306
|
+
|
|
83
307
|
## [0.34.0] — 2026-08-13
|
|
84
308
|
|
|
85
309
|
### Added
|
package/README.md
CHANGED
|
@@ -279,7 +279,8 @@ The exposed tool set is **filtered by configured credentials**:
|
|
|
279
279
|
`ZHIPU_API_KEY` (Z.AI GLM), `OPENCODE_API_KEY` (OpenCode Zen or Go),
|
|
280
280
|
`MOONSHOT_API_KEY` (Moonshot Kimi), or `KIMI_API_KEY` (Kimi for Coding)
|
|
281
281
|
(setup: `triss coder init`). `triss_coder_run` takes an optional `engine`
|
|
282
|
-
(`opencode` default
|
|
282
|
+
(`opencode` V1 default; `--engine opencode2` beta — see
|
|
283
|
+
[opencode2.md](docs/opencode2.md) — or `crush`); its timeout defaults to
|
|
283
284
|
1500s (25 min) over MCP, above the CLI's 900s, since coding runs are
|
|
284
285
|
expected to be long; override per call via the `timeout` arg. For
|
|
285
286
|
runs that may exceed it, use `triss coder run` on the CLI instead.
|
|
@@ -311,8 +312,8 @@ and writing**.
|
|
|
311
312
|
| `triss review` | Code review on a branch, PR, or explicitly piped diff (linked ticket only for branch/PR) | The agent reading the whole diff |
|
|
312
313
|
| `triss commit-msg` | Generates a commit message from staged diff | Hand-writing or copy-pasting from web LLMs |
|
|
313
314
|
| `triss usage` | Cumulative cost / token usage with per-project breakdown | Squinting at stderr after each call |
|
|
314
|
-
| `triss coder init` | Sets up a coding agent (default `opencode` engine; `--engine crush` for crush): provider key/profile (`--provider worker` reuses `TRISS_WORKER_*`; Z.AI GLM default; Zen, Go, and Kimi are also supported), config, permission policy, and 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 |
|
|
315
|
-
| `triss coder run` | Spawns the coding agent (the OpenAI-compatible Triss worker, GLM, Kimi, OpenCode Zen, or OpenCode Go) and prints one JSON envelope (`--engine opencode
|
|
315
|
+
| `triss coder init` | Sets up a coding agent (default `opencode` V1 engine; `--engine opencode2` for the V2 beta — shares the `opencode.json` config, see [docs/opencode2.md](docs/opencode2.md); `--engine crush` for crush): provider key/profile (`--provider worker` reuses `TRISS_WORKER_*`; Z.AI GLM default; Zen, Go, and Kimi are also supported), config, permission policy, and 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 |
|
|
316
|
+
| `triss coder run` | Spawns the coding agent (the OpenAI-compatible Triss worker, GLM, Kimi, OpenCode Zen, or OpenCode Go) and prints one JSON envelope (`--engine opencode|opencode2|crush` — opencode V1 default, opencode2 beta per [docs/opencode2.md](docs/opencode2.md); `--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 |
|
|
316
317
|
| `triss coder clean` | Removes finished `.triss/wt` isolation worktrees (`--all` forces all) | Manually finding and deleting stale git worktrees |
|
|
317
318
|
| `triss init` | Drops a tiny (~15 line) delegation block into `CLAUDE.md` / `AGENTS.md` | Hand-writing routing rules |
|
|
318
319
|
| `triss agent-help` | Prints the full delegation cookbook on demand (the nano block points here) | A 200-line CLAUDE.md that always loads |
|
|
@@ -532,8 +533,44 @@ git diff main...HEAD | triss review --stdin # review this branch's merge-base d
|
|
|
532
533
|
triss review --skip-issue # don't try ticket lookup
|
|
533
534
|
triss review --provider glm # same review flow, one-shot GLM inference
|
|
534
535
|
triss review --provider kimi # …or Kimi (pro preset = kimi-k3)
|
|
536
|
+
triss review --files src/a.js test/b.test.js # literal file selection (after --)
|
|
537
|
+
triss review --issue ENG-42 # explicit tracker issue (never inferred from prose)
|
|
535
538
|
```
|
|
536
539
|
|
|
540
|
+
### Reliable delegation — review safety (Release B)
|
|
541
|
+
|
|
542
|
+
Review runs are bounded and fail closed (see
|
|
543
|
+
[`docs/reliable-delegation-release-a.md`](docs/reliable-delegation-release-a.md)):
|
|
544
|
+
|
|
545
|
+
- **Limits**: single request (256 KiB default / 1 MiB hard max), shard
|
|
546
|
+
(96 KiB / 256 KiB), total corpus (4 MiB / 16 MiB), shard count (64 /
|
|
547
|
+
256) — all reloadable via `TRISS_REVIEW_*_BYTES` / `TRISS_REVIEW_MAX_SHARDS`;
|
|
548
|
+
any contradiction falls back to the complete default set.
|
|
549
|
+
- **Git**: exact merge-base-to-head identity, one unique merge base, a
|
|
550
|
+
sanitized environment (no external diff/textconv/config injection,
|
|
551
|
+
grafts and nonempty shallow repositories rejected).
|
|
552
|
+
- **Selection**: literal `--files` selectors are expanded across renames
|
|
553
|
+
and only the selected content is acquired — a huge change with a small
|
|
554
|
+
selected file never buffers the full diff first.
|
|
555
|
+
- **PRs**: canonical input only, exact OID re-verification, disposable
|
|
556
|
+
bare repository under a registry lock (3 concurrent runs, 120 MiB pack /
|
|
557
|
+
128 MiB filesystem quotas); the source directory is never mutated.
|
|
558
|
+
- **Issues**: PR or branch prose NEVER triggers tracker access. Only an
|
|
559
|
+
explicit `--issue KEY` performs a bounded minimum-field lookup;
|
|
560
|
+
`--skip-issue` is deprecated.
|
|
561
|
+
- **Empty responses** fail with `TRISS_PROVIDER_EMPTY` instead of
|
|
562
|
+
producing a clean verdict; usable non-empty text is never trimmed.
|
|
563
|
+
|
|
564
|
+
### Sharding (Release C)
|
|
565
|
+
|
|
566
|
+
`triss review --payload-mode shard` runs source-ordered whole-file shards
|
|
567
|
+
sequentially. A file is never split across shards; the first failure or
|
|
568
|
+
cancellation stops the sequence. **Completed sharded execution is not a
|
|
569
|
+
global review**: there is no aggregation call, no cross-shard analysis, and
|
|
570
|
+
no global approval — the CLI prints `global verdict: unavailable_for_sharded`.
|
|
571
|
+
Partial errors carry completed shard verdicts only (never raw diff content).
|
|
572
|
+
`evidence + shard` and `shard + --stream` are rejected before any model call.
|
|
573
|
+
|
|
537
574
|
The three diff sources are mutually exclusive: local Git (`triss review` or
|
|
538
575
|
`--base`), a GitHub PR (`triss review <PR>`), or UTF-8 text piped to
|
|
539
576
|
`triss review --stdin`. `--stdin` cannot be combined with a PR number or
|
|
@@ -587,8 +624,9 @@ default timeout, configurable via `--timeout <ms>`.
|
|
|
587
624
|
|
|
588
625
|
Delegates an implementation task to a cheap coding agent — the existing
|
|
589
626
|
OpenAI-compatible Triss worker, GLM, Kimi,
|
|
590
|
-
OpenCode Zen, or OpenCode Go models (the `opencode` engine by default;
|
|
591
|
-
|
|
627
|
+
OpenCode Zen, or OpenCode Go models (the `opencode` V1 engine by default;
|
|
628
|
+
`opencode2` beta — see [docs/opencode2.md](docs/opencode2.md) — or `crush`; see
|
|
629
|
+
**Engines** below) instead of the primary model writing
|
|
592
630
|
the code itself.
|
|
593
631
|
|
|
594
632
|
```bash
|
|
@@ -597,8 +635,37 @@ triss coder run "add input validation to /signup" --isolate
|
|
|
597
635
|
triss coder run "..." --engine crush # crush engine (isolates by default; restrict is opt-in)
|
|
598
636
|
triss coder run "..." --engine crush --restrict # crush + CLI allowlist on top of the worktree
|
|
599
637
|
triss coder clean # remove finished isolation worktrees
|
|
638
|
+
triss coder session list # list v2 sessions (per engine)
|
|
639
|
+
triss coder session clean <slug> --engine opencode # remove one inactive isolated session
|
|
640
|
+
triss coder result list # list retained result artifacts
|
|
641
|
+
triss coder state backup --project <path> # Section 15 rollback backup
|
|
642
|
+
triss coder state validate --project <path> --backup <dir>
|
|
600
643
|
```
|
|
601
644
|
|
|
645
|
+
Every `triss coder run` envelope (and the matching MCP tool) carries the
|
|
646
|
+
Release A contract fields: `session_slug` (explicit slug or an anonymous
|
|
647
|
+
generated one — never an implicit persistent conversation), `result_retention`
|
|
648
|
+
/ `result_id` (`retained` only for isolated changed runs with enforced
|
|
649
|
+
result-store quota and a successful reservation), and `execution_capabilities`
|
|
650
|
+
(eight honest `enforced|best_effort|unavailable` values plus
|
|
651
|
+
`effective_isolation`). Non-isolated `files_changed` is `null`; the only
|
|
652
|
+
changes-expectation evidence is `run_files_changed`. Process completion is not
|
|
653
|
+
task satisfaction — use `--expect changes --isolate` and inspect `git status`
|
|
654
|
+
yourself. Unavailable OS sandbox/cleanup/lock/quota does not block a
|
|
655
|
+
non-isolated/best-effort run but provides none of those guarantees; explicit
|
|
656
|
+
or default isolation needs `--allow-best-effort-caller-worktree` (default
|
|
657
|
+
off) or fails before spawn with `TRISS_CODER_ISOLATION_ENFORCEMENT_REQUIRED`
|
|
658
|
+
(stable `err.code`; retry hint when the isolation mechanism is unavailable),
|
|
659
|
+
and unavailable credential isolation always blocks before spawn. With the
|
|
660
|
+
opt-in and only when the isolation mechanism itself is unavailable (no git
|
|
661
|
+
repository or worktree creation failure — slug/branch conflicts like
|
|
662
|
+
`already exists` still fail closed), the run downgrades to
|
|
663
|
+
`best_effort_caller_worktree`: stderr and envelope `warnings` carry
|
|
664
|
+
`TRISS_CODER_ISOLATION_DOWNGRADED` and `effective_isolation` becomes
|
|
665
|
+
`best_effort_caller_worktree` (advisory-only, `files_changed` is `null`,
|
|
666
|
+
edits may reach the caller worktree). Full details:
|
|
667
|
+
`docs/reliable-delegation-release-a.md`.
|
|
668
|
+
|
|
602
669
|
`triss coder init` first asks which provider to configure — **Z.AI GLM**
|
|
603
670
|
(default), the existing **Triss worker** (`--provider worker`, aliases
|
|
604
671
|
`openai` / `openai-compatible`), **OpenCode Zen** (`--provider opencode-zen`, free rotating
|
package/bin/triss.js
CHANGED
|
@@ -40,8 +40,19 @@ import {
|
|
|
40
40
|
runEdit,
|
|
41
41
|
runUnset,
|
|
42
42
|
} from '../src/commands/config.js';
|
|
43
|
-
import {
|
|
43
|
+
import {
|
|
44
|
+
runCoderInit,
|
|
45
|
+
runCoderRun,
|
|
46
|
+
runCoderClean,
|
|
47
|
+
runCoderSessionList,
|
|
48
|
+
runCoderSessionClean,
|
|
49
|
+
runCoderStateAdopt,
|
|
50
|
+
runCoderStateReset,
|
|
51
|
+
runCoderResultList,
|
|
52
|
+
runCoderResultClean,
|
|
53
|
+
} from '../src/commands/coder.js';
|
|
44
54
|
import { runCoderModels, runCoderModelSet, runCoderModelRollback } from '../src/commands/coder-models.js';
|
|
55
|
+
import { runCoderStateBackup, runCoderStateValidate } from '../src/commands/coder-state-backup.js';
|
|
45
56
|
import { loadIntegrations } from '../src/integrations/_registry.js';
|
|
46
57
|
import { withCall } from '../src/call-context.js';
|
|
47
58
|
import { positiveIntegerOption, positiveNumberOption } from '../src/option-validation.js';
|
|
@@ -191,6 +202,7 @@ program
|
|
|
191
202
|
.option('--small-model <p/m>', 'forward coder small model')
|
|
192
203
|
.option('--isolate', 'forward coder isolation')
|
|
193
204
|
.option('--no-isolate', 'disable coder isolation')
|
|
205
|
+
.option('--allow-best-effort-caller-worktree', 'forward coder isolation downgrade')
|
|
194
206
|
.option('--restrict', 'forward coder restriction')
|
|
195
207
|
.option('--no-restrict', 'disable coder restriction')
|
|
196
208
|
.option('--cwd <path>', 'forward coder working directory')
|
|
@@ -214,6 +226,8 @@ program
|
|
|
214
226
|
.option('-b, --base <branch>', 'compare against this branch (default: auto-detect origin/HEAD or main/master/develop)')
|
|
215
227
|
.option('--skip-issue', "don't try to look up a Jira/Linear ticket from the branch/PR title")
|
|
216
228
|
.option('--stdin', 'read an explicitly piped UTF-8 diff instead of Git or PR sources')
|
|
229
|
+
.option('--files <paths...>', 'literal path selectors: review ONLY these files (repeatable; renames select both sides)')
|
|
230
|
+
.option('--issue <key>', 'explicit linked-issue key (e.g. PROJ-123); PR prose never triggers tracker access')
|
|
217
231
|
.option('-q, --question <text>', 'override the default review question')
|
|
218
232
|
.option('--provider <name>', 'inference provider: worker (default), deepseek (alias), glm, or kimi (alias: moonshot)')
|
|
219
233
|
.option('-m, --model <name>', 'model preset (flash | pro) or full model id (default: pro)')
|
|
@@ -221,6 +235,7 @@ program
|
|
|
221
235
|
.option('--format <format>', 'response format: text (default) or evidence')
|
|
222
236
|
.option('--stream', 'force streaming even when stdout is not a TTY')
|
|
223
237
|
.option('--no-stream', 'disable streaming output (default streams when stdout is a TTY)')
|
|
238
|
+
.option('--payload-mode <mode>', 'review payload mode: single (default) or shard (sequential whole-file shards; no global verdict)')
|
|
224
239
|
.action((pr, opts) => wrap(runReview)(pr, opts));
|
|
225
240
|
|
|
226
241
|
program
|
|
@@ -276,7 +291,7 @@ config
|
|
|
276
291
|
.option('-f, --force', 're-prompt for keys that are already set')
|
|
277
292
|
.option('--standard', 'API key + one model only — skip the standard/advanced prompt')
|
|
278
293
|
.option('--advanced', 'full wizard with presets, base URL, integrations — skip the prompt')
|
|
279
|
-
.option('--coder-engine <name>', 'coder target only: coding engine to configure (opencode default, or crush). `coder init` uses --engine')
|
|
294
|
+
.option('--coder-engine <name>', 'coder target only: coding engine to configure (opencode default, opencode2 beta, or crush). `coder init` uses --engine')
|
|
280
295
|
.option('--coder-provider <name>', 'coder target only: opencode engine provider (zai, worker, opencode-zen, opencode-go, moonshot, kimi-for-coding). `coder init` uses --provider')
|
|
281
296
|
.action(wrap(runWizard));
|
|
282
297
|
|
|
@@ -324,14 +339,14 @@ config
|
|
|
324
339
|
|
|
325
340
|
const coder = program
|
|
326
341
|
.command('coder')
|
|
327
|
-
.description('Run a coding agent (OpenCode or Crush engine)');
|
|
342
|
+
.description('Run a coding agent (OpenCode V1, OpenCode 2 beta, or Crush engine)');
|
|
328
343
|
|
|
329
344
|
coder
|
|
330
345
|
.command('init')
|
|
331
|
-
.description('Install/configure a coding engine (opencode default, or crush), provider key, permission policy, and agent templates')
|
|
346
|
+
.description('Install/configure a coding engine (opencode default, opencode2 beta, or crush), provider key, permission policy, and agent templates')
|
|
332
347
|
.option('-g, --global', 'save to the global scope (~/.config/triss/.env, ~/.config/opencode/)')
|
|
333
348
|
.option('-l, --local', 'save to the project scope (./.triss.env, ./opencode.json)')
|
|
334
|
-
.option('--engine <name>', 'coding engine to configure: opencode (default) or crush')
|
|
349
|
+
.option('--engine <name>', 'coding engine to configure: opencode (default), opencode2 (beta — shares the opencode.json config; see docs/opencode2.md), or crush')
|
|
335
350
|
.option('--provider <name>', 'opencode engine model provider: zai, worker (existing OpenAI-compatible TRISS_WORKER_* profile), opencode-zen, opencode-go, moonshot, or kimi-for-coding')
|
|
336
351
|
.option('--allow-unverified', 'requires explicit --provider opencode-go (alias: go): allow the built-in fallback only after a temporary network or HTTP 408/429/500/502/503/504 catalogue failure (never bypasses 401/403, empty, or invalid responses)')
|
|
337
352
|
.option('--allow-unsafe-bash', 'proceed even if an existing opencode.json has no deny-first bash policy (the agent runs with --auto)')
|
|
@@ -339,11 +354,11 @@ coder
|
|
|
339
354
|
|
|
340
355
|
coder
|
|
341
356
|
.command('run [prompt]')
|
|
342
|
-
.description('Spawn a coding agent — GLM, the OpenAI-compatible Triss worker, Kimi, OpenCode Zen, or OpenCode Go (opencode default
|
|
343
|
-
.option('--engine <name>', 'coding engine: opencode (default) or crush')
|
|
357
|
+
.description('Spawn a coding agent — GLM, the OpenAI-compatible Triss worker, Kimi, OpenCode Zen, or OpenCode Go (opencode default; opencode2 beta or --engine crush) — and print a JSON envelope to stdout')
|
|
358
|
+
.option('--engine <name>', 'coding engine: opencode (default), opencode2 (beta — see docs/opencode2.md), or crush')
|
|
344
359
|
.option('--session <id>', 'triss-side session slug, mapped to a real opencode session id in .triss/sessions.json')
|
|
345
360
|
.option('--continue', 'continue the most recent opencode session (maps to opencode --continue)')
|
|
346
|
-
.option('--agent <name>', '
|
|
361
|
+
.option('--agent <name>', 'agent template to use (V1 default: coder; opencode2 beta uses its built-in primary agent unless set)')
|
|
347
362
|
.option('--provider <name>', 'OpenCode only: select a provider for one run; requires --model and does not modify .env or opencode.json')
|
|
348
363
|
.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)')
|
|
349
364
|
.option('--small-model <p/m>', 'with --provider, override small_model for one run (defaults to the one-shot main model)')
|
|
@@ -353,6 +368,7 @@ coder
|
|
|
353
368
|
.option('--no-restrict', 'crush only: disable restrict (crush auto-approves every tool — the default)')
|
|
354
369
|
.option('--cwd <path>', 'working directory (ignored with --isolate)')
|
|
355
370
|
.option('--timeout <sec>', 'kill the engine after this many seconds', parsePositiveNumber, 900)
|
|
371
|
+
.option('--allow-best-effort-caller-worktree', 'allow downgrade to caller worktree when isolated isolation cannot be enforced (default off — fails before spawn without it)')
|
|
356
372
|
.option('--stdin', 'read the prompt from piped stdin instead of the [prompt] argument')
|
|
357
373
|
.option('--json', 'no-op — the envelope is always JSON; kept for symmetry with other commands')
|
|
358
374
|
.action((prompt, opts) => wrap(runCoderRun)(prompt, opts));
|
|
@@ -366,10 +382,10 @@ coder
|
|
|
366
382
|
coder
|
|
367
383
|
.command('models')
|
|
368
384
|
.description('List current + live coder models, provider compatibility, and credential readiness (read-only)\n\n' +
|
|
369
|
-
'Configuration sources:\n' +
|
|
370
|
-
' • opencode:
|
|
385
|
+
'Configuration sources (layered; later sources win):\n' +
|
|
386
|
+
' • opencode & opencode2: JSONC-aware layered config — global ~/.config/opencode/opencode.json, then every opencode.json/.opencode/opencode.json up from the project root to the Git boundary (project-local wins)\n' +
|
|
371
387
|
' • crush: ./.crush/crush.json (local) or ~/.local/share/crush/crush.json (global)')
|
|
372
|
-
.option('--engine <name>', 'coding engine: opencode (default) or crush')
|
|
388
|
+
.option('--engine <name>', 'coding engine: opencode (default), opencode2 (beta — layered JSONC config), or crush')
|
|
373
389
|
.option('--provider <name>', 'provider kind: zai, worker, opencode-zen, opencode-go, moonshot, or kimi-for-coding')
|
|
374
390
|
.option('--json', 'print the stable machine-readable state object (no secrets)')
|
|
375
391
|
.action(wrap(runCoderModels));
|
|
@@ -391,7 +407,7 @@ coderModel
|
|
|
391
407
|
' • crush: project .crush/crush.json (local) or ~/.local/share/crush/crush.json (global)'
|
|
392
408
|
)
|
|
393
409
|
.option('--small <model>', 'small/fast model id (omit to keep the current compatible value)')
|
|
394
|
-
.option('--engine <name>', 'coding engine: opencode (default) or crush')
|
|
410
|
+
.option('--engine <name>', 'coding engine: opencode (default), opencode2 (beta — layered JSONC config), or crush')
|
|
395
411
|
.option('--provider <name>', 'provider kind: zai, worker, opencode-zen, opencode-go, moonshot, or kimi-for-coding')
|
|
396
412
|
.option('-g, --global', 'write to the global scope (OpenCode: ~/.config/opencode/opencode.json + global .env; Crush: ~/.local/share/crush/crush.json)')
|
|
397
413
|
.option('-l, --local', 'write to the project scope (OpenCode: ./opencode.json + ./.triss.env; Crush: ./.crush/crush.json)')
|
|
@@ -408,6 +424,72 @@ coderModel
|
|
|
408
424
|
.option('-l, --local', 'restore to the project scope (./opencode.json or ./.crush/crush.json)')
|
|
409
425
|
.action((opts) => wrap(runCoderModelRollback)(opts.from, opts));
|
|
410
426
|
|
|
427
|
+
// `coder state` is a command GROUP whose leaves are `backup` and `validate`
|
|
428
|
+
// (Section 15 rollback contract).
|
|
429
|
+
const coderState = coder
|
|
430
|
+
.command('state')
|
|
431
|
+
.description('Back up or validate the v2 coder state of a project (rollback contract)');
|
|
432
|
+
|
|
433
|
+
coderState
|
|
434
|
+
.command('backup')
|
|
435
|
+
.description('Create a bounded rollback backup of the v2 coder state (both engine session stores + coder-state-v2)')
|
|
436
|
+
.requiredOption('--project <absolute-path>', 'absolute path of the validated project root')
|
|
437
|
+
.option('--backup <path>', 'backup destination directory (default: <project>/.triss/backups/<timestamp>)')
|
|
438
|
+
.option('--json', 'print the stable machine-readable result (no secrets)')
|
|
439
|
+
.action((opts) => wrap(runCoderStateBackup)(opts));
|
|
440
|
+
|
|
441
|
+
coderState
|
|
442
|
+
.command('validate')
|
|
443
|
+
.description('Validate a rollback backup: manifest schema, completion marker hash, per-entry verification')
|
|
444
|
+
.requiredOption('--project <absolute-path>', 'absolute path of the validated project root')
|
|
445
|
+
.requiredOption('--backup <basename>', 'backup directory to validate')
|
|
446
|
+
.option('--json', 'print the stable machine-readable result (no secrets)')
|
|
447
|
+
.action((opts) => wrap(runCoderStateValidate)(opts));
|
|
448
|
+
|
|
449
|
+
coderState
|
|
450
|
+
.command('adopt')
|
|
451
|
+
.description('Adopt owned v2 state under a NEW project id: quarantine the old id, rewrite validated owner records')
|
|
452
|
+
.requiredOption('--from-project-id <32hex>', 'the old project id (32 lowercase hex) to quarantine')
|
|
453
|
+
.action((opts) => wrap(runCoderStateAdopt)(opts));
|
|
454
|
+
|
|
455
|
+
coderState
|
|
456
|
+
.command('reset')
|
|
457
|
+
.description('Quarantine all validated local v2 state and create an empty identity (never deletes it)')
|
|
458
|
+
.requiredOption('--project <absolute-path>', 'absolute path of the validated project root')
|
|
459
|
+
.action((opts) => wrap(runCoderStateReset)(opts));
|
|
460
|
+
|
|
461
|
+
// `coder session` group (v2 session CLI contract, Atomic 23).
|
|
462
|
+
const coderSession = coder
|
|
463
|
+
.command('session')
|
|
464
|
+
.description('List or clean v2 isolated sessions (per-engine store; legacy .triss/sessions.json is never touched)');
|
|
465
|
+
|
|
466
|
+
coderSession
|
|
467
|
+
.command('list')
|
|
468
|
+
.description('Serialize the bounded v2 session inventory projection to stdout')
|
|
469
|
+
.option('--engine <name>', 'coding engine: opencode (default) or crush')
|
|
470
|
+
.action((opts) => wrap(runCoderSessionList)(opts));
|
|
471
|
+
|
|
472
|
+
coderSession
|
|
473
|
+
.command('clean <slug>')
|
|
474
|
+
.description('Remove a selected inactive v2 isolated session/workspace transaction')
|
|
475
|
+
.requiredOption('--engine <name>', 'coding engine: opencode or crush (MANDATORY)')
|
|
476
|
+
.action((slug, opts) => wrap(runCoderSessionClean)(slug, opts));
|
|
477
|
+
|
|
478
|
+
// `coder result` group (retained-result CLI, Atomic 23).
|
|
479
|
+
const coderResult = coder
|
|
480
|
+
.command('result')
|
|
481
|
+
.description('List or clean retained result artifacts (never persistent sessions)');
|
|
482
|
+
|
|
483
|
+
coderResult
|
|
484
|
+
.command('list')
|
|
485
|
+
.description('Serialize the bounded retained-result projection to stdout')
|
|
486
|
+
.action((opts) => wrap(runCoderResultList)(opts));
|
|
487
|
+
|
|
488
|
+
coderResult
|
|
489
|
+
.command('clean <run-id>')
|
|
490
|
+
.description('Remove only a validated retained result artifact (run-<32 lowercase hex>)')
|
|
491
|
+
.action((runId, opts) => wrap(runCoderResultClean)(runId, opts));
|
|
492
|
+
|
|
411
493
|
function wrap(fn) {
|
|
412
494
|
return async (...args) => {
|
|
413
495
|
try {
|
|
@@ -124,3 +124,17 @@ RED tests must establish:
|
|
|
124
124
|
Acceptance requires focused tests, the full Node test/lint suite, package
|
|
125
125
|
smoke, a live synthetic worker run from a GLM-persisted temporary project, and
|
|
126
126
|
sequential GLM 5.2 plus independent agent reviews.
|
|
127
|
+
|
|
128
|
+
## Current credential-proxy limitation (2026-08)
|
|
129
|
+
|
|
130
|
+
The parent-owned credential proxy pins the upstream ORIGIN plus a path prefix
|
|
131
|
+
per provider. For opencode built-in providers without a documented base-URL
|
|
132
|
+
override (`moonshot`, `kimi-for-coding`), the engine cannot be verifiably
|
|
133
|
+
pointed at the proxy, so `triss coder run` fails closed BEFORE spawn instead
|
|
134
|
+
of handing the real upstream a one-run proxy token it would reject. `zai`
|
|
135
|
+
(ZAI_BASE_URL/ZHIPU_BASEURL), `opencode-zen/go` (OPENCODE_BASE_URL), the
|
|
136
|
+
managed `triss-worker` overlay, and every crush run keep working. Direct
|
|
137
|
+
non-coder calls (`triss ask/review/chat --provider kimi|moonshot`) are
|
|
138
|
+
unaffected — they never spawn an engine. Lifting the limitation requires an
|
|
139
|
+
audited provider overlay (the same mechanism the worker block uses) for these
|
|
140
|
+
providers.
|
package/docs/configuration.md
CHANGED
|
@@ -263,16 +263,30 @@ self-hosted endpoints).
|
|
|
263
263
|
| Variable | Required | Default | Notes |
|
|
264
264
|
| -------------------------------- | -------- | ------------------ | ------------------------------------------ |
|
|
265
265
|
| `ZHIPU_API_KEY` | yes¹ | — | Z.AI API key for `ask`/`review --provider glm` and GLM coder models — <https://z.ai/manage-apikey/apikey-list> |
|
|
266
|
-
| `OPENCODE_API_KEY` | no¹ | — | Shared OpenCode credential for Zen `opencode/*` and paid Go `opencode-go/*` models (opencode
|
|
266
|
+
| `OPENCODE_API_KEY` | no¹ | — | Shared OpenCode credential for Zen `opencode/*` and paid Go `opencode-go/*` models (opencode engines). A key alone does not prove Go subscription, quota, or regional readiness. See [opencode-zen.md](opencode-zen.md) and [opencode-go.md](opencode-go.md). |
|
|
267
267
|
| `MOONSHOT_API_KEY` | no¹ | — | Moonshot AI (Kimi) key for `ask`/`review --provider kimi` and `moonshotai/*` coder models — <https://platform.kimi.ai/console/api-keys> |
|
|
268
|
-
| `KIMI_API_KEY` | no¹ | — | Kimi for Coding subscription key (opencode
|
|
268
|
+
| `KIMI_API_KEY` | no¹ | — | Kimi for Coding subscription key (opencode engines) — unlocks `kimi-for-coding/*` models like `kimi-for-coding/k3` — <https://www.kimi.com/code/docs/en/> |
|
|
269
269
|
| `TRISS_KIMI_BASE_URL` | no | `https://api.moonshot.ai/v1` | Endpoint for `--provider kimi` ask/review calls — set `https://api.moonshot.cn/v1` for a China-mainland key. Trailing slashes are stripped; a blank/degenerate value falls back to the default |
|
|
270
270
|
| `TRISS_CODER_MODEL` | no | `zai-coding-plan/glm-5.2` | Resolved **main** model, passed to opencode via `--model`. Worker uses `triss-worker/<id>`, Go uses `opencode-go/<id>`, and Zen uses `opencode/<id>`. Main and small must stay within one provider prefix. |
|
|
271
271
|
| `TRISS_CODER_SMALL_MODEL` | no | `zai-coding-plan/glm-5-turbo` | Small/fast **management/init intent** — written to `opencode.json` `small_model` by `init`/`triss coder model set`. **Not** a runtime override of an already-pinned small role (see precedence) |
|
|
272
272
|
| `TRISS_CODER_OPENCODE_VERSION` | no | `1.18.7` | Pin override for the `opencode-ai` npm install |
|
|
273
|
-
| `TRISS_CODER_ENGINE` | no | `opencode` | Coding engine: `opencode` (default) or `crush` |
|
|
273
|
+
| `TRISS_CODER_ENGINE` | no | `opencode` | Coding engine: `opencode` (default), `opencode2` (beta — see [opencode2.md](./opencode2.md)), or `crush` |
|
|
274
|
+
| `TRISS_CODER_OPENCODE2_VERSION` | no | `0.0.0-next-17430` | Exact pin override for the `@opencode-ai/cli` npm install (opencode2 engine — exact match required) |
|
|
274
275
|
| `TRISS_CODER_CRUSH_VERSION` | no | `0.1.6` | Pin override for the `@phpcraftdream/crush` npm install (crush engine) |
|
|
275
|
-
| `
|
|
276
|
+
| `TRISS_CODER_SESSION_CAP` | no | `4` | Persistent v2 session inventory cap per engine (fail closed) |
|
|
277
|
+
|
|
278
|
+
### Review limits (Release B)
|
|
279
|
+
|
|
280
|
+
All four limits are reloadable at runtime; values are independently clamped
|
|
281
|
+
to their hard maxima, and any contradiction (e.g. `shard_max > single_max`)
|
|
282
|
+
falls back to the complete default set — never a partial application.
|
|
283
|
+
|
|
284
|
+
| Variable | Default | Hard max | Notes |
|
|
285
|
+
| ------------------------------- | ------------------ | --------------- | ----------------------------------------- |
|
|
286
|
+
| `TRISS_REVIEW_SINGLE_MAX_BYTES` | `262144` (256 KiB) | `1048576` (1 MiB) | Single-request payload bound (metadata + question + diff) |
|
|
287
|
+
| `TRISS_REVIEW_SHARD_MAX_BYTES` | `98304` (96 KiB) | `262144` (256 KiB) | Per-shard payload bound (sharding not yet available) |
|
|
288
|
+
| `TRISS_REVIEW_TOTAL_MAX_BYTES` | `4194304` (4 MiB) | `16777216` (16 MiB) | Total corpus bound; also the stdin acquisition cap |
|
|
289
|
+
| `TRISS_REVIEW_MAX_SHARDS` | `64` | `256` | Shard-count bound (sharding not yet available) |
|
|
276
290
|
|
|
277
291
|
`triss coder init` auto-detects which Z.AI endpoint `ZHIPU_API_KEY`
|
|
278
292
|
actually authenticates against — the `zai-coding-plan` (subscription)
|