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.
- package/LICENSE +21 -0
- package/README.md +546 -0
- package/bin/triss.js +263 -0
- package/docs/configuration.md +275 -0
- package/docs/extending.md +255 -0
- package/docs/integrations/confluence.md +65 -0
- package/docs/integrations/github.md +74 -0
- package/docs/integrations/gitlab.md +71 -0
- package/docs/integrations/jira.md +88 -0
- package/docs/integrations/linear.md +87 -0
- package/docs/mcp.md +267 -0
- package/docs/testing/test-plan-main.md +326 -0
- package/package.json +54 -0
- package/src/client.js +104 -0
- package/src/commands/ask.js +97 -0
- package/src/commands/chat.js +59 -0
- package/src/commands/commit-msg.js +91 -0
- package/src/commands/completion.js +179 -0
- package/src/commands/config.js +525 -0
- package/src/commands/extract.js +59 -0
- package/src/commands/fetch.js +35 -0
- package/src/commands/init.js +194 -0
- package/src/commands/mcp.js +135 -0
- package/src/commands/review.js +170 -0
- package/src/commands/status.js +75 -0
- package/src/commands/usage.js +77 -0
- package/src/commands/write.js +58 -0
- package/src/config.js +47 -0
- package/src/git.js +75 -0
- package/src/integrations/_atlassian.js +32 -0
- package/src/integrations/_contract.js +189 -0
- package/src/integrations/_registry.js +85 -0
- package/src/integrations/confluence/client.js +78 -0
- package/src/integrations/confluence/commands.js +94 -0
- package/src/integrations/confluence/index.js +71 -0
- package/src/integrations/github/client.js +112 -0
- package/src/integrations/github/commands.js +112 -0
- package/src/integrations/github/index.js +99 -0
- package/src/integrations/gitlab/client.js +97 -0
- package/src/integrations/gitlab/commands.js +119 -0
- package/src/integrations/gitlab/index.js +88 -0
- package/src/integrations/jira/adf.js +82 -0
- package/src/integrations/jira/client.js +97 -0
- package/src/integrations/jira/commands.js +163 -0
- package/src/integrations/jira/index.js +104 -0
- package/src/integrations/linear/client.js +166 -0
- package/src/integrations/linear/commands.js +133 -0
- package/src/integrations/linear/index.js +105 -0
- package/src/mcp/handlers.js +773 -0
- package/src/mcp/install.js +276 -0
- package/src/mcp/review-core.js +130 -0
- package/src/mcp/server.js +56 -0
- package/src/mcp/tools.js +665 -0
- package/src/models.js +20 -0
- package/src/net.js +89 -0
- package/src/paths.js +162 -0
- package/src/picker.js +137 -0
- package/src/safety.js +49 -0
- package/src/secrets.js +249 -0
- package/src/usage.js +163 -0
- package/src/web.js +172 -0
- package/templates/claude.md +151 -0
- 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
|
+
[](https://opensource.org/licenses/MIT)
|
|
8
|
+
[](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).
|