triss-coworker 0.13.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.
Files changed (63) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +546 -0
  3. package/bin/triss.js +263 -0
  4. package/docs/configuration.md +275 -0
  5. package/docs/extending.md +255 -0
  6. package/docs/integrations/confluence.md +65 -0
  7. package/docs/integrations/github.md +74 -0
  8. package/docs/integrations/gitlab.md +71 -0
  9. package/docs/integrations/jira.md +88 -0
  10. package/docs/integrations/linear.md +87 -0
  11. package/docs/mcp.md +267 -0
  12. package/docs/testing/test-plan-main.md +326 -0
  13. package/package.json +54 -0
  14. package/src/client.js +104 -0
  15. package/src/commands/ask.js +97 -0
  16. package/src/commands/chat.js +59 -0
  17. package/src/commands/commit-msg.js +91 -0
  18. package/src/commands/completion.js +179 -0
  19. package/src/commands/config.js +525 -0
  20. package/src/commands/extract.js +59 -0
  21. package/src/commands/fetch.js +35 -0
  22. package/src/commands/init.js +194 -0
  23. package/src/commands/mcp.js +135 -0
  24. package/src/commands/review.js +170 -0
  25. package/src/commands/status.js +75 -0
  26. package/src/commands/usage.js +77 -0
  27. package/src/commands/write.js +58 -0
  28. package/src/config.js +47 -0
  29. package/src/git.js +75 -0
  30. package/src/integrations/_atlassian.js +32 -0
  31. package/src/integrations/_contract.js +189 -0
  32. package/src/integrations/_registry.js +85 -0
  33. package/src/integrations/confluence/client.js +78 -0
  34. package/src/integrations/confluence/commands.js +94 -0
  35. package/src/integrations/confluence/index.js +71 -0
  36. package/src/integrations/github/client.js +112 -0
  37. package/src/integrations/github/commands.js +112 -0
  38. package/src/integrations/github/index.js +99 -0
  39. package/src/integrations/gitlab/client.js +97 -0
  40. package/src/integrations/gitlab/commands.js +119 -0
  41. package/src/integrations/gitlab/index.js +88 -0
  42. package/src/integrations/jira/adf.js +82 -0
  43. package/src/integrations/jira/client.js +97 -0
  44. package/src/integrations/jira/commands.js +163 -0
  45. package/src/integrations/jira/index.js +104 -0
  46. package/src/integrations/linear/client.js +166 -0
  47. package/src/integrations/linear/commands.js +133 -0
  48. package/src/integrations/linear/index.js +105 -0
  49. package/src/mcp/handlers.js +773 -0
  50. package/src/mcp/install.js +276 -0
  51. package/src/mcp/review-core.js +130 -0
  52. package/src/mcp/server.js +56 -0
  53. package/src/mcp/tools.js +665 -0
  54. package/src/models.js +20 -0
  55. package/src/net.js +89 -0
  56. package/src/paths.js +162 -0
  57. package/src/picker.js +137 -0
  58. package/src/safety.js +49 -0
  59. package/src/secrets.js +249 -0
  60. package/src/usage.js +163 -0
  61. package/src/web.js +172 -0
  62. package/templates/claude.md +151 -0
  63. package/templates/codex.md +51 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 ayleen
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,546 @@
1
+ # Triss Coworker
2
+
3
+ > A cheap **DeepSeek**-backed coworker for your AI coding agent.
4
+ > Delegate bulk reads, boilerplate generation, and chat extraction.
5
+ > Save 60–70% of your token budget. Pay cents, not dollars.
6
+
7
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
8
+ [![npm](https://img.shields.io/badge/npm-triss--coworker-cb3837.svg)](https://www.npmjs.com/package/triss-coworker)
9
+
10
+ Triss is a small CLI (`triss`) that hands token-heavy I/O off to a cheap
11
+ DeepSeek model so your expensive primary agent (Claude Code today, Codex
12
+ soon) stays focused on reasoning and edits. Inspired by
13
+ [`claude-coworker-model`](https://github.com/imkunal007219/claude-coworker-model)
14
+ by Kunal Bhardwaj.
15
+
16
+ The name is a Witcher reference. Triss is the helpful sorceress on your team.
17
+
18
+ It now also ships with **first-class integrations for Jira and Linear**, so
19
+ your agent can search, read, create, update, comment on, and transition
20
+ tickets via Triss instead of pulling thousands of tokens of MCP output into
21
+ context. Adding a new provider (GitHub Issues, Notion, …) takes one folder
22
+ — see [docs/extending.md](docs/extending.md).
23
+
24
+ ---
25
+
26
+ ## Requirements
27
+
28
+ - **Node.js ≥ 18** (LTS recommended). Check with `node --version`.
29
+ - Don't have it? Install via [nvm](https://github.com/nvm-sh/nvm), [fnm](https://github.com/Schniz/fnm), Homebrew (`brew install node`), or [nodejs.org](https://nodejs.org/).
30
+ - **npm** (ships with Node.js) — used for the `npm install -g` path.
31
+ - **git** — used by the bash one-liner installer to clone the repo.
32
+ - A **DeepSeek API key** (free tier works) for the worker model: <https://platform.deepseek.com/>.
33
+
34
+ Triss has no other runtime dependencies.
35
+
36
+ ## Install
37
+
38
+ ### Option A — npm (recommended)
39
+
40
+ ```bash
41
+ npm install -g triss-coworker
42
+ ```
43
+
44
+ ### Option B — one-line bash installer
45
+
46
+ ```bash
47
+ curl -fsSL https://raw.githubusercontent.com/ayleen/triss-coworker/main/install.sh | bash
48
+ ```
49
+
50
+ ### Option C — from source
51
+
52
+ ```bash
53
+ git clone https://github.com/ayleen/triss-coworker.git
54
+ cd triss-coworker
55
+ npm install
56
+ npm link
57
+ ```
58
+
59
+ Then verify:
60
+
61
+ ```bash
62
+ triss --help
63
+ ```
64
+
65
+ ## Configure
66
+
67
+ ```bash
68
+ triss config wizard
69
+ ```
70
+
71
+ The wizard first asks **Standard** vs **Advanced**:
72
+
73
+ - **Standard** — for most users. Just two prompts: API key + worker model
74
+ name. Triss writes the model into both `flash` and `pro` presets so
75
+ `--model pro` works the same as `--model flash`. No questions about
76
+ Jira/Linear/base URL/etc. *Recommended starting point.*
77
+ - **Advanced** — full control: separate `flash`/`pro` presets, custom
78
+ base URL, integrations (Jira, Linear, …), default-preset choice.
79
+
80
+ Skip the prompt with `--standard` or `--advanced`. Add `--local` to save
81
+ into `<project>/.triss.env` instead of the global file (useful when
82
+ different repos use different Jira instances).
83
+
84
+ Then verify:
85
+
86
+ ```bash
87
+ triss status
88
+ ```
89
+
90
+ ### Per-project credentials
91
+
92
+ Different orgs / Jira instances per project? `triss config wizard --local`
93
+ saves to `<project>/.triss.env` instead of the global file. Project values
94
+ override global values when you `cd` into that repo. The file is
95
+ automatically `chmod 600`'d and added to `.gitignore`.
96
+
97
+ Step-by-step recipes for the common setups (single workspace, multi-Jira
98
+ per project, CI, etc.) live in
99
+ [docs/configuration.md](docs/configuration.md#recipes--common-setups-end-to-end).
100
+
101
+ ### Updating one variable
102
+
103
+ ```bash
104
+ triss config set DEEPSEEK_API_KEY # masked prompt → global
105
+ triss config set ATLASSIAN_API_TOKEN --local # masked prompt → ./.triss.env
106
+ echo "$KEY" | triss config set LINEAR_API_KEY - # from stdin (CI)
107
+ ```
108
+
109
+ Full reference: [docs/configuration.md](docs/configuration.md).
110
+
111
+ ### Shell completions
112
+
113
+ ```bash
114
+ # bash:
115
+ echo 'eval "$(triss completion bash)"' >> ~/.bashrc
116
+
117
+ # zsh:
118
+ echo 'eval "$(triss completion zsh)"' >> ~/.zshrc
119
+ ```
120
+
121
+ After re-sourcing your shell profile, `triss <Tab>` lists all
122
+ top-level commands; `triss config <Tab>`, `triss jira <Tab>`,
123
+ `triss linear <Tab>` list subcommands.
124
+
125
+ ## Wire it into Claude Code
126
+
127
+ ### Wizard takes care of this for you
128
+
129
+ | Mode in `triss config wizard` | What it does about Claude Code |
130
+ | ----------------------------- | ------------------------------ |
131
+ | **Standard** (default) | Installs **both** paths automatically — MCP server *and* a global `CLAUDE.md`. No question asked. |
132
+ | **Advanced** (`--advanced`) | Asks at the end: Both / MCP only / CLAUDE.md only / Skip. Default = Both. |
133
+
134
+ The two paths cooperate: MCP is primary, CLAUDE.md is the fallback. If
135
+ MCP fails to load, the CLAUDE.md rules keep the agent working. If you
136
+ don't know what to pick, just use Standard.
137
+
138
+ Two complementary paths — pick either, both, or neither.
139
+
140
+ ### Option 1 — `CLAUDE.md` rules (lightweight)
141
+
142
+ ```bash
143
+ cd ~/my-project
144
+ triss init # asks: Claude / Codex / Both, then writes the rules file(s)
145
+ triss init --target claude # writes ./CLAUDE.md without asking
146
+ triss init --target codex # writes ./AGENTS.md for Codex
147
+ triss init --target both # writes both ./CLAUDE.md and ./AGENTS.md
148
+ triss init --global # same prompt, but writes into ~/.claude/ or ~/.codex/
149
+ ```
150
+
151
+ Agent reads the rules and invokes Triss via the shell. No special
152
+ setup. Best when you also want the same commands available outside the
153
+ agent (in your own scripts, CI, etc).
154
+
155
+ ### Option 2 — MCP server (deeper integration)
156
+
157
+ ```bash
158
+ triss mcp install # asks: Claude / Codex / Both, then writes the config
159
+ triss mcp install --target claude # ~/.claude.json (no prompt)
160
+ triss mcp install --target codex # ~/.codex/config.toml (no prompt)
161
+ triss mcp install --target both # both configs
162
+ triss mcp install --local # ./.mcp.json (claude target only — Codex has no project-local config)
163
+ ```
164
+
165
+ For **Claude Code**: restart your session — `triss` appears in `claude /mcp`
166
+ with the per-tool list. For **Codex**: restart the Codex CLI session;
167
+ verify with `codex mcp list`. Tools become first-class (faster, per-tool
168
+ permissions, no Bash subprocess overhead).
169
+
170
+ The Codex entry includes `startup_timeout_sec = 30` and `tool_timeout_sec
171
+ = 120` defaults so `--model pro` calls have headroom.
172
+
173
+ The exposed tool set is **filtered by configured credentials**:
174
+
175
+ - **Always** (need only `DEEPSEEK_API_KEY`): `triss_chat`, `triss_ask`,
176
+ `triss_fetch`, `triss_review`, `triss_commit_msg`, `triss_status`.
177
+ - **`triss_jira_*` + `triss_confluence_*`** when `ATLASSIAN_*` is set.
178
+ - **`triss_linear_*`** when `LINEAR_API_KEY` is set.
179
+ - **`triss_github_*`** when `GITHUB_TOKEN` is set (or `gh` CLI logged in).
180
+ - **`triss_gitlab_*`** when `GITLAB_TOKEN` is set.
181
+
182
+ Add credentials later → restart session → new tools appear automatically.
183
+
184
+ Full reference: [docs/mcp.md](docs/mcp.md).
185
+
186
+ ## Wire it into a project
187
+
188
+ In any project directory:
189
+
190
+ ```bash
191
+ triss init # interactive: pick Claude / Codex / Both
192
+ triss init --target claude # ./CLAUDE.md (Claude Code reads it on startup)
193
+ triss init --target codex # ./AGENTS.md (Codex reads it on startup)
194
+ triss init --target both # ./CLAUDE.md and ./AGENTS.md (when you use both agents)
195
+ triss init --global # write to ~/.claude/ or ~/.codex/ instead of the project
196
+ ```
197
+
198
+ This adds a delegation block that tells Claude Code when to call `triss ask`,
199
+ `triss write`, and `triss extract` instead of burning tokens on file reads
200
+ and boilerplate. Re-running `triss init` updates the block in place.
201
+
202
+ ## What it does
203
+
204
+ The expensive primary agent decides **what** to do. Triss does the **reading
205
+ and writing**.
206
+
207
+ | Command | Does | Replaces |
208
+ | --------------- | ----------------------------------------------------- | ----------------------------------- |
209
+ | `triss ask` | Reads files, URLs, and/or piped stdin — returns a summary | The agent reading the source itself |
210
+ | `triss chat` | Bare prompt to the worker model — no corpus | A separate `gpt`-style CLI |
211
+ | `triss write` | Generates code/docs from a spec + reference file | The agent typing out boilerplate |
212
+ | `triss extract` | Pulls readable transcript from JSONL session logs | Manually scraping `~/.claude/...` |
213
+ | `triss fetch` | Fetches URL(s) and returns readable markdown | The agent's WebFetch tool |
214
+ | `triss review` | Code review on current branch or a PR (diff + linked ticket) | The agent reading the whole diff |
215
+ | `triss commit-msg` | Generates a commit message from staged diff | Hand-writing or copy-pasting from web LLMs |
216
+ | `triss usage` | Cumulative cost / token usage with per-project breakdown | Squinting at stderr after each call |
217
+ | `triss init` | Drops a delegation block into `CLAUDE.md` / `AGENTS.md` | Hand-writing routing rules |
218
+ | `triss status` | Shows current model + key + .env sources | — |
219
+ | `triss config` | Interactive credential management | Manual `.env` editing |
220
+ | `triss mcp` | Register Triss as MCP server in Claude Code | Editing `~/.claude.json` by hand |
221
+ | `triss completion` | Shell completion script (bash/zsh) | Hand-rolled completion |
222
+
223
+ ### `triss ask`
224
+
225
+ ```bash
226
+ triss ask --paths src/auth.ts src/db.ts \
227
+ --question "List every place we read DEEPSEEK_API_KEY"
228
+
229
+ triss ask --paths "src/**/*.ts" \
230
+ --question "Find SQL injection risks" \
231
+ --model pro --max-tokens 16384
232
+ ```
233
+
234
+ ### `triss write`
235
+
236
+ ```bash
237
+ triss write --spec "Pytest tests for auth.py covering OAuth2 happy path" \
238
+ --context tests/test_main.py \
239
+ --target tests/test_auth.py
240
+ ```
241
+
242
+ ### `triss extract`
243
+
244
+ ```bash
245
+ triss extract ~/.claude/projects/my-project/session.jsonl -o /tmp/chat.txt
246
+ ```
247
+
248
+ ### `triss commit-msg`
249
+
250
+ ```bash
251
+ git add src/foo.js src/bar.js
252
+ triss commit-msg # prints a Conventional Commits message
253
+ triss commit-msg --apply # prints + runs `git commit -m`
254
+ triss commit-msg --type fix --scope auth # nudge the type/scope
255
+ triss commit-msg --no-conventional # plain subject + body
256
+ ```
257
+
258
+ Reads `git diff --staged`, sends it to the worker model with a Conventional
259
+ Commits-aware system prompt, prints the message. Defaults to your
260
+ `TRISS_DEFAULT_MODEL` preset.
261
+
262
+ ### `triss usage`
263
+
264
+ ```bash
265
+ triss usage # last 24h: total tokens + $$$
266
+ triss usage --since 7d # last week
267
+ triss usage --month # last 30 days
268
+ triss usage --by-project # split by working directory
269
+ triss usage --by-model # flash vs pro breakdown
270
+ triss usage --by-label # ask / chat / review / commit-msg / …
271
+ triss usage --json # raw log records
272
+ triss usage --reset # clear the log
273
+ ```
274
+
275
+ Every worker call (CLI **and** MCP) appends one record to
276
+ `~/.cache/triss/usage.jsonl` with model, tokens, cached tokens, computed
277
+ USD cost, working directory, and a label like `triss/ask`. List-price
278
+ defaults for DeepSeek are baked in; override per-model with
279
+ `TRISS_PRICE_<MODEL_ID>=miss,hit,out` (USD per token). Disable tracking
280
+ entirely with `TRISS_USAGE_LOG=0`.
281
+
282
+ ### Streaming output
283
+
284
+ Long `--model pro` calls (review, ask) now stream tokens as they arrive
285
+ when stdout is a TTY, so you see progress instead of 1-3 minutes of
286
+ silence. Disable per-call with `--no-stream`. Streaming is automatically
287
+ off for piped output, MCP tool calls, and any `--json` flag.
288
+
289
+ ### `triss chat`
290
+
291
+ ```bash
292
+ triss chat "what's a JWT in one paragraph"
293
+ triss chat --model pro "design a rate limiter for ..."
294
+ triss chat --system "you are a postgres expert" "explain MVCC"
295
+ echo "long prompt..." | triss chat --stdin
296
+ ```
297
+
298
+ Bare prompt to the worker model — no corpus, no retrieval, just a
299
+ direct call to `chat()`. Cheap one-shot lookups go here so the primary
300
+ model's budget stays on actual code work.
301
+
302
+ ### `triss ask --stdin`
303
+
304
+ The universal pipe input — any command's stdout can become the corpus:
305
+
306
+ ```bash
307
+ git diff main..HEAD | triss ask --stdin --question "summarise the changes"
308
+ git log --since=1.week --stat | triss ask --stdin --question "what did I do?"
309
+ kubectl logs my-pod | triss ask --stdin --question "errors?"
310
+ ```
311
+
312
+ Combine with `--paths`/`--urls` to mix sources in one round-trip. Triss
313
+ errors out if `--stdin` is used in a TTY — it always wants piped input.
314
+
315
+ ### `triss review [PR]`
316
+
317
+ Code review composed from `git diff` (or `gh pr diff`), PR metadata, and
318
+ a linked Jira / Linear ticket auto-detected from the branch name or PR
319
+ title (e.g. `feature/ENG-42-foo` → fetches `ENG-42`).
320
+
321
+ ```bash
322
+ triss review # current branch vs auto-detected base
323
+ triss review 123 # GitHub PR #123 (requires `gh` CLI)
324
+ triss review --base develop # explicit base
325
+ triss review --skip-issue # don't try ticket lookup
326
+ ```
327
+
328
+ Defaults to the `pro` preset because review needs reasoning. Output is
329
+ a list of concrete issues with file:line citations — not a diff
330
+ summary. Cost: a 25KB diff review on `pro` runs ~$0.005-0.01 with
331
+ prompt caching.
332
+
333
+ ### `triss fetch` / `triss ask --urls`
334
+
335
+ ```bash
336
+ # Just clean markdown
337
+ triss fetch https://api-docs.example.com/
338
+
339
+ # Fetch + summarise via DeepSeek
340
+ triss fetch https://blog.example.com/long-post --question "key takeaways?"
341
+
342
+ # Mix URLs with files (or several URLs together)
343
+ triss ask --urls https://spec.example.com/v2 https://spec.example.com/v3 \
344
+ --paths README.md \
345
+ --question "what's missing from README that's in the spec?"
346
+ ```
347
+
348
+ HTML is stripped of `<script>`, `<style>`, `<nav>`, `<aside>`, `<footer>`,
349
+ forms, and SVG; `<main>` / `<article>` are preferred when present;
350
+ non-HTML responses (JSON, plain text) are returned verbatim. 30-second
351
+ default timeout, configurable via `--timeout <ms>`.
352
+
353
+ ## Integrations
354
+
355
+ External-service plugins live under `src/integrations/<name>/`. They are
356
+ auto-discovered at startup and appear as top-level subcommands.
357
+
358
+ | Integration | Subcommand | Operations | Reference |
359
+ | ----------- | ------------------ | ------------------------------------------------------------- | --------- |
360
+ | Jira | `triss jira` | search, issue, create, update, comments, transitions, attachments | [docs/integrations/jira.md](docs/integrations/jira.md) |
361
+ | Confluence | `triss confluence` | search (CQL), page, create, update, spaces | [docs/integrations/confluence.md](docs/integrations/confluence.md) |
362
+ | Linear | `triss linear` | search, issue, create, update, comments, states, attachments | [docs/integrations/linear.md](docs/integrations/linear.md) |
363
+ | GitHub | `triss github` | search, issue, create, update, comments | [docs/integrations/github.md](docs/integrations/github.md) |
364
+ | GitLab | `triss gitlab` | search, issue, create, update, comments | [docs/integrations/gitlab.md](docs/integrations/gitlab.md) |
365
+
366
+ Two design rules:
367
+
368
+ - **Read commands accept `--question`** — instead of dumping the raw API
369
+ response, Triss runs it through DeepSeek and returns a focused summary.
370
+ - **Write commands stay direct** — `create`, `update`, `comments --post`,
371
+ `transitions --apply` make HTTP calls without LLM in the loop.
372
+
373
+ `triss status` shows each integration's env-var readiness so you know what
374
+ still needs configuring.
375
+
376
+ `triss init` injects per-integration delegation rules into your
377
+ `CLAUDE.md` / `AGENTS.md` **only for integrations whose credentials are
378
+ present**. Add a Linear key later? Run `triss config wizard linear` then
379
+ `triss init` again — the new section appears automatically. Users who
380
+ never use Jira never see Jira instructions in their agent's prompt.
381
+
382
+ ### Adding your own integration
383
+
384
+ The plugin contract is one folder + one file. A working **GitHub Issues**
385
+ integration in ~80 lines is documented end-to-end in
386
+ [**docs/extending.md**](docs/extending.md). High-level recipe:
387
+
388
+ 1. Create `src/integrations/<name>/index.js`.
389
+ 2. `export default { name, description, envVars, register(program, { wrap }) {}, agentInstructions: { claude, codex } }`.
390
+ 3. Use the helpers in `src/integrations/_contract.js`
391
+ (`httpJson`, `requireEnv`, `summarize`, `printResult`,
392
+ `IntegrationError`).
393
+ 4. Drop tests in `test/<name>-*.test.js` (mock `globalThis.fetch`).
394
+ 5. Run `triss --help` — your subcommand appears automatically. The
395
+ wizard, `triss status`, and `triss init` (CLAUDE.md / AGENTS.md generation) all
396
+ pick up the new manifest with no further wiring.
397
+
398
+ ## Models
399
+
400
+ By default, Triss exposes two presets so you can switch quickly:
401
+
402
+ | Preset | Default model | Use for |
403
+ | ------- | -------------------- | ------------------------------------ |
404
+ | `flash` | `deepseek-v4-flash` | Bulk reads, summaries, doc updates |
405
+ | `pro` | `deepseek-v4-pro` | Harder analysis, careful generation |
406
+
407
+ Pick a preset per call:
408
+
409
+ ```bash
410
+ triss ask --paths ... --question "..." --model flash # default
411
+ triss write --spec ... --target ... --model pro
412
+ ```
413
+
414
+ If DeepSeek renames the models or you want to point Triss at a different
415
+ provider, override the names without touching code. Triss only requires
416
+ an OpenAI-compatible chat-completions endpoint.
417
+
418
+ You can also pass any model id directly: `--model deepseek-chat`.
419
+
420
+ ### Provider recipes
421
+
422
+ #### DeepSeek (default, recommended)
423
+ ```bash
424
+ triss config set DEEPSEEK_API_KEY # masked prompt
425
+ # That's it — DEEPSEEK_BASE_URL / FLASH / PRO are auto-defaulted.
426
+ ```
427
+
428
+ #### Kimi / Moonshot
429
+ ```bash
430
+ triss config set DEEPSEEK_API_KEY $MOONSHOT_API_KEY
431
+ triss config set DEEPSEEK_BASE_URL https://api.moonshot.ai/v1
432
+ triss config set DEEPSEEK_FLASH_MODEL kimi-k2.5
433
+ triss config set DEEPSEEK_PRO_MODEL kimi-k2.5
434
+ ```
435
+
436
+ #### Ollama (local, free)
437
+ ```bash
438
+ triss config set DEEPSEEK_API_KEY ollama
439
+ triss config set DEEPSEEK_BASE_URL http://localhost:11434/v1
440
+ triss config set DEEPSEEK_FLASH_MODEL qwen2.5-coder:14b
441
+ triss config set DEEPSEEK_PRO_MODEL qwen2.5-coder:32b
442
+ ```
443
+
444
+ #### OpenRouter (any model, one key)
445
+ ```bash
446
+ triss config set DEEPSEEK_API_KEY $OPENROUTER_API_KEY
447
+ triss config set DEEPSEEK_BASE_URL https://openrouter.ai/api/v1
448
+ triss config set DEEPSEEK_FLASH_MODEL deepseek/deepseek-chat
449
+ triss config set DEEPSEEK_PRO_MODEL anthropic/claude-3.5-sonnet
450
+ ```
451
+
452
+ Add `--local` to scope any of these to the current project only
453
+ (e.g. one repo on Ollama, the rest on cloud DeepSeek).
454
+
455
+ ## Environment reference
456
+
457
+ ### Worker model
458
+
459
+ | Variable | Required | Default | Notes |
460
+ | ----------------------- | -------- | -------------------------------- | ------------------------------------- |
461
+ | `DEEPSEEK_API_KEY` | yes | — | Your provider key |
462
+ | `DEEPSEEK_BASE_URL` | no | `https://api.deepseek.com/v1` | Any OpenAI-compatible endpoint |
463
+ | `DEEPSEEK_FLASH_MODEL` | no | `deepseek-v4-flash` | Override the `flash` preset |
464
+ | `DEEPSEEK_PRO_MODEL` | no | `deepseek-v4-pro` | Override the `pro` preset |
465
+ | `TRISS_DEFAULT_MODEL` | no | `flash` | Which preset is used when no `--model`|
466
+
467
+ ### Integrations
468
+
469
+ | Variable | Required for | Notes |
470
+ | ----------------------- | ----------------- | --------------------------------------------------------- |
471
+ | `ATLASSIAN_BASE_URL` | jira, confluence | e.g. `https://yourorg.atlassian.net` |
472
+ | `ATLASSIAN_EMAIL` | jira, confluence | account email |
473
+ | `ATLASSIAN_API_TOKEN` | jira, confluence | <https://id.atlassian.com/manage-profile/security/api-tokens> |
474
+ | `LINEAR_API_KEY` | linear | <https://linear.app/settings/api> |
475
+ | `LINEAR_API_URL` | linear (optional) | endpoint override (default `https://api.linear.app/graphql`) |
476
+ | `GITHUB_TOKEN` | github | falls back to `gh auth token` if unset |
477
+ | `GITLAB_TOKEN` | gitlab | <https://gitlab.com/-/profile/personal_access_tokens> (`api` scope) |
478
+ | `GITLAB_URL` | gitlab (optional) | self-hosted base URL (default `https://gitlab.com`) |
479
+
480
+ ### Tunables
481
+
482
+ | Variable | Default | Effect |
483
+ | ------------------------------ | ----------- | --------------------------------------------------------- |
484
+ | `TRISS_HTTP_TIMEOUT_MS` | `30000` | Per-request timeout for integration HTTP calls (Jira/GitHub/GitLab/Linear/Confluence) |
485
+ | `TRISS_HTTP_MAX_BYTES` | `26214400` | Max response body size for integration calls (25 MB default) |
486
+ | `TRISS_FILE_MAX_BYTES` | `1048576` | Per-file cap for `triss ask --paths`; oversized files are reported and skipped (1 MB default) |
487
+ | `TRISS_CORPUS_MAX_BYTES` | `16777216` | Total corpus cap across all files in one `ask` call (16 MB default) |
488
+ | `TRISS_GLOB_MAX_FILES` | `500` | Max files a single glob may expand to (`src/**/*.ts` etc.) |
489
+ | `TRISS_PROJECT_ROOT` | `process.cwd()` | Pin the project root used by the sandbox and `.triss.env` lookup. `triss mcp install` writes this into the MCP launcher config automatically. |
490
+ | `TRISS_USAGE_LOG` | (on) | `0` disables the usage tracker (`~/.cache/triss/usage.jsonl`) |
491
+ | `TRISS_USAGE_LOG_CWD` | (on) | `0` omits the absolute cwd from each record (then `--by-project` groups under `(unknown)`) |
492
+ | `TRISS_USAGE_LOG_MAX_BYTES` | `10485760` | Rotate the active log to `usage.jsonl.old` once it crosses this size (10 MB default) |
493
+ | `TRISS_PRICE_<MODEL_ID>` | list prices | `miss,hit,out` USD-per-token override per model (e.g. for promo or non-DeepSeek providers) |
494
+ | `TRISS_FETCH_MAX_BYTES` | `10485760` | Max body size for `triss fetch` (default 10 MB) |
495
+ | `TRISS_RESTRICT_PATHS` | `1` in MCP, unset in CLI | `0` opts the MCP server out of the project-root file IO sandbox |
496
+ | `TRISS_ALLOW_PRIVATE_NETWORKS` | (off) | `1` allows `triss fetch` / `triss ask --urls` to hit RFC1918, loopback, link-local, and cloud-metadata IPs. Off blocks SSRF; turn on only for self-hosted internal docs. **Known residual risk:** the guard checks DNS once before fetch; the underlying connection performs another lookup, leaving a narrow DNS-rebinding window. For high-trust environments use network-level egress filtering as the primary control. |
497
+
498
+ `.env` files are loaded from `~/.config/triss/.env` (global) and
499
+ `<project-root>/.triss.env` (project, overrides global). Real `process.env`
500
+ always wins. See [docs/configuration.md](docs/configuration.md) for
501
+ recipes (per-project Jira, CI, switching providers).
502
+
503
+ ## Cost in practice
504
+
505
+ We have not run a multi-week study like the original
506
+ `claude-coworker-model`, so the headline 60–70% savings is sourced from
507
+ their data — but here is one fully-measured run from this codebase:
508
+
509
+ | Task | Source bytes | DeepSeek (pro, -75%) | DeepSeek (pro, list price) | Same job in Opus 4.x |
510
+ | ------------------------------------------------------------- | ------------ | -------------------- | -------------------------- | -------------------- |
511
+ | Compare original `claude-coworker-model` README + 12 of our source files (one `triss ask --urls --paths`, 18.3K in / 2.4K out, structured 4-section report) | ≈ 65 KB | **\$0.010** | \$0.040 | ≈ \$0.45 |
512
+
513
+ For this single benchmark `triss` was **~45× cheaper** than letting the
514
+ primary model read those bytes itself. Real savings depend on which
515
+ operations you delegate (bulk reads win the most; tiny lookups break
516
+ even); see `templates/claude.md` for the rules of thumb.
517
+
518
+ ## Roadmap
519
+
520
+ **Shipped** — see the Tools table for usage:
521
+ Claude Code support · Plugin-style integrations · Interactive credential
522
+ management with per-project overrides · Web fetching · Standard/Advanced
523
+ wizard · bash + zsh completions · `--stdin` · `triss review [PR]` ·
524
+ `triss chat` · MCP server · Cost tracking · `triss commit-msg` · GitHub /
525
+ Confluence / GitLab integrations · Streaming output for `ask`/`chat`/
526
+ `review` · Codex `AGENTS.md` rules · Path-safety sandbox in MCP mode ·
527
+ test suite.
528
+
529
+ **Planned**:
530
+
531
+ - [ ] `triss exec <task>` — auto-route a freeform task to the right
532
+ sub-command
533
+ - [ ] Optional `npm publish` so `npm install -g triss-coworker` works
534
+ out of the box
535
+ - [ ] More provider recipe blocks in the docs (Kimi, Ollama,
536
+ OpenRouter — examples already present, but with terse setup steps)
537
+
538
+ ## Acknowledgements
539
+
540
+ Original idea & rationale: [Kunal Bhardwaj — *I was burning through Claude
541
+ Code's weekly limit in 3 days*](https://medium.com/@kunalbhardwaj598/i-was-burning-through-claude-codes-weekly-limit-in-3-days-here-s-how-i-fixed-it-0344c555abda),
542
+ based on [`imkunal007219/claude-coworker-model`](https://github.com/imkunal007219/claude-coworker-model).
543
+
544
+ ## License
545
+
546
+ MIT — see [LICENSE](LICENSE).