tandem-mode 0.4.0 → 0.5.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/README.md CHANGED
@@ -1,233 +1,249 @@
1
- # Tandem Mode
2
-
3
- [![npm version](https://img.shields.io/npm/v/tandem-mode.svg)](https://www.npmjs.com/package/tandem-mode)
4
- [![license](https://img.shields.io/npm/l/tandem-mode.svg)](./LICENSE)
5
- [![node](https://img.shields.io/node/v/tandem-mode.svg)](./package.json)
6
- [![good first issues](https://img.shields.io/github/issues/zdrave08/Tandem-Mode/good%20first%20issue)](https://github.com/zdrave08/Tandem-Mode/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22)
7
-
8
- **English** | [Srpski](./README.sr.md)
9
-
10
- A terminal coding agent built specifically for the DeepSeek API — not a generic
11
- LLM harness with DeepSeek bolted on. Interactive REPL, planner/worker/reviewer
12
- orchestration, cache-aware prompt architecture, and first-class support for
13
- Windows, macOS, and Linux.
14
-
15
- > **Independent open-source project. Not affiliated with or endorsed by
16
- > DeepSeek.**
17
-
18
- ## Status
19
-
20
- M0–M4 of the [development plan](./deepseek-cli-development-plan.md) are done.
21
- Published on npm, usable today for real coding tasks against a local repo.
22
-
23
- First benchmark run is in — see [full results](./docs/benchmark-results.md).
24
- Headline: all three configurations (Pro-only, Flash-only, orchestration)
25
- fixed 4/4 injected bugs correctly in a real WooCommerce plugin, with a clean
26
- `php -l` and zero unnecessary file changes. But for this class of task
27
- (single-file, well-scoped fixes), orchestration cost ~9.5× more and took
28
- ~19× longer than Pro-only for the same correctness — the opposite of what
29
- you'd want orchestration for. Read as: orchestration's overhead needs a
30
- bigger, more decomposable task to pay for itself, which this first run didn't
31
- test. Reported as-is, not adjusted to fit expectations.
32
-
33
- ## Features
34
-
35
- - **Agentic loop** — `deepseek-v4-pro`/`deepseek-v4-flash` with tool calling:
36
- `read_file`, `list_dir`, `search`, `edit`, `git_diff`, `shell`, `view_image`,
37
- `web_search`.
38
- - **Two entry points** — interactive REPL for normal work, single-shot mode
39
- (`tandem "task" --yes`) for scripting and CI.
40
- - **Orchestration** (`/plan`) — a planner produces a JSON task list, workers
41
- execute each task with a fresh minimal context, a reviewer checks the git
42
- diff against the original task and either approves or requests corrections
43
- (capped by `max_review_loops`).
44
- - **Cache-aware prompts** — the worker's system prompt + repo map + plan stay
45
- byte-identical across calls in one orchestration run, so DeepSeek's context
46
- cache actually hits. Measured live: cache-hit tokens grew call over call
47
- within a single `/plan` run.
48
- - **Vision** — `view_image` lets the agent look at a screenshot you point it
49
- to; `/paste` grabs an image straight from the clipboard (Windows, macOS,
50
- and Linux via X11/`xclip` or Wayland/`wl-clipboard`).
51
- - **Web search** — isolated calls to DeepSeek's Responses API when the agent
52
- needs something outside the repo (an error message, a library's docs).
53
- - **Session persistence** — every session is a JSONL file; `/resume` continues
54
- the latest (or a named) one, `/fork` branches off without touching the
55
- original.
56
- - **Safety** — destructive actions (file edits, shell commands not on a small
57
- read-only allowlist) always ask for confirmation; `y`/`n`/`a` where `a`
58
- remembers the choice for that tool for the rest of the session. `--yes`
59
- bypasses this for CI but always prints what it auto-approved.
60
- - **Cost control** — usage is read only from the API's own `usage` field,
61
- never estimated. A budget (`/budget`, `--budget`) hard-stops the loop before
62
- the next API call if exceeded, without losing the session. `/usage` also
63
- shows what the session would have cost off-peak, and the REPL warns you at
64
- startup if you're currently in a peak-pricing window.
65
- - **ESC to interrupt** — cancels the in-flight call (and any running shell
66
- command) cleanly, keeping whatever was generated so far.
67
- - **Cross-platform** — the shell tool runs PowerShell natively on Windows and
68
- `sh` on macOS/Linux, file edits preserve the original CRLF/LF line ending
69
- style, paths are handled with `path.resolve` throughout.
70
-
71
- ## Quick start
72
-
73
- ```bash
74
- npm install -g tandem-mode
75
- tandem # interactive REPL
76
- tandem "explain what this repo does" --yes # one-shot
77
- ```
78
-
79
- Or from source (useful for contributing, or to track `main` instead of the
80
- latest npm release):
81
-
82
- ```bash
83
- git clone https://github.com/zdrave08/Tandem-Mode.git
84
- cd Tandem-Mode
85
- pnpm install
86
- pnpm dev # interactive REPL
87
- pnpm dev "explain what this repo does" --yes # one-shot
88
- ```
89
-
90
- On first run you'll be asked for a DeepSeek API key (get one at
91
- [platform.deepseek.com](https://platform.deepseek.com)) and a default
92
- model/reasoning effort. The key is stored in your OS's own secure credential
93
- store — never in a config file or log:
94
-
95
- - **Windows** — DPAPI-encrypted (tied to your OS user account) in
96
- `%LOCALAPPDATA%\TandemMode\credentials.dat`.
97
- - **macOS** — the login Keychain, via the built-in `security` CLI.
98
- - **Linux** — the Secret Service (gnome-keyring, KWallet, or similar), via
99
- `secret-tool` (install `libsecret-tools` if it's missing).
100
-
101
- `DEEPSEEK_API_KEY` works everywhere and always takes priority, for CI use.
102
-
103
- ## Usage
104
-
105
- ```bash
106
- tandem # interactive REPL
107
- tandem "fix the off-by-one in foo.ts"
108
- tandem --plan "add dark mode to the settings page"
109
- tandem "task" --model deepseek-v4-flash --effort low --budget 0.50 --yes
110
- ```
111
-
112
- | Flag | Effect |
113
- |---|---|
114
- | `--resume` / `-r` | Continue the latest session in this directory |
115
- | `--yes` / `-y` | Auto-approve destructive actions (prints what it approved) |
116
- | `--plan` | Run planner/worker/reviewer orchestration instead of a single turn |
117
- | `--model` | `deepseek-v4-pro` or `deepseek-v4-flash` |
118
- | `--effort` | `low`, `high`, or `max` reasoning effort |
119
- | `--budget` | Hard USD cap for the run |
120
- | `--max-review-loops` | Cap on orchestration correction cycles (default 3) |
121
-
122
- ### REPL commands
123
-
124
- | Command | Effect |
125
- |---|---|
126
- | `/plan <task>` | Planner/worker/reviewer orchestration |
127
- | `/model [name]` | Show or switch model |
128
- | `/thinking [on\|off]` | Toggle thinking mode |
129
- | `/effort [low\|high\|max]` | Show or set reasoning effort |
130
- | `/status` | Current session/settings |
131
- | `/diff [--staged] [path]` | Working-tree diff, no API call |
132
- | `/usage` | Tokens, cost, off-peak projection |
133
- | `/budget [amount]` | Show or set the session budget |
134
- | `/new` | Start a fresh session |
135
- | `/save-profile <name>` | Save model, effort, budget and review loops as a named profile |
136
- | `/profile [name]` | Load a saved profile, or list them |
137
- | `/compact` | Summarize the history into a new session to free up context; the old session stays on disk |
138
- | `/fork` | New session, carrying over the current history |
139
- | `/resume [id]` | Continue the latest (or a named) session |
140
- | `/paste [message]` | Send a clipboard image to the agent |
141
- | `/clear` | Clear the screen |
142
- | `/help` | This list |
143
- | `/exit` | Quit |
144
-
145
- Press **ESC** at any time during a turn to interrupt it.
146
-
147
- ## Architecture
148
-
149
- ```
150
- tandem (no args) ─┬─> interactive REPL ─┬─> single turn: agent loop (tools)
151
- │ └─> /plan: planner → worker(s) → reviewer
152
- tandem "task" ──┘ (single-shot, same agent loop, for scripts/CI)
153
- ```
154
-
155
- - `src/deepseek/` — thin client for DeepSeek's OpenAI-compatible API
156
- (streaming + non-streaming chat completions, vision, web search via
157
- Responses API). See [`docs/api-notes.en.md`](./docs/api-notes.en.md)
158
- (Serbian original: [`docs/api-notes.md`](./docs/api-notes.md)) for the
159
- API behavior this is built against, verified live rather than assumed.
160
- - `src/agent/` — the tool-calling loop, tool implementations, session
161
- persistence, usage/cost tracking.
162
- - `src/orchestrator/` — planner/worker/reviewer, repo-map generation, the
163
- cache-aware stable-prefix construction.
164
- - `src/repl/` — slash commands, runtime config, the first-run wizard.
165
- - `src/cli.tsx` — Ink-based terminal UI and the REPL/single-shot entry points.
166
-
167
- ## Configuration
168
-
169
- Layered: **session** (in-REPL commands) > **project** (`.tandem/config.json`
170
- in the current directory) > **global** (`~/.tandem/config.json`).
171
-
172
- ```json
173
- {
174
- "defaultModel": "deepseek-v4-pro",
175
- "defaultReasoningEffort": "high",
176
- "budgetUsd": 5,
177
- "maxReviewLoops": 3,
178
- "verifyCommand": "pnpm typecheck && pnpm test",
179
- "notifyCommand": "curl -s -d \"Tandem: $TANDEM_OUTCOME\" https://ntfy.sh/my-topic",
180
- "language": "en"
181
- }
182
- ```
183
-
184
- `verifyCommand` runs before each `/plan` review round and its result goes to
185
- the reviewer. `language` is the UI language (`en` or `sr`, default `en`); the
186
- `--lang` flag and the `TANDEM_LANG` environment variable override it, in that
187
- order. The first-run wizard asks for it.
188
-
189
- `notifyCommand` runs when a `/plan` run ends: reviewer approved, `max_review_loops`
190
- reached, or an error (not when you interrupt it with ESC). The details come in as
191
- environment variables, never spliced into the command text: `TANDEM_OUTCOME`
192
- (`approved`, `max_review_loops` or `error`), `TANDEM_TASK`, `TANDEM_NOTES` (the
193
- reviewer's notes, or the error message), `TANDEM_REVIEW_LOOPS` and `TANDEM_COST_USD`.
194
- The command runs in your shell (PowerShell on Windows, `sh` elsewhere) with a 15 s
195
- limit, and a failure only prints a warning. Any shell command works, so Slack,
196
- ntfy, a desktop notification or a webhook are all just examples:
197
-
198
- ```json
199
- { "notifyCommand": "curl -s -d \"Tandem: $TANDEM_OUTCOME\" https://ntfy.sh/my-topic" }
200
- ```
201
-
202
- On Windows (PowerShell) the variables are written `$env:TANDEM_OUTCOME`.
203
-
204
- Like `verifyCommand`, `notifyCommand` runs without asking, so only put it in a
205
- project's `.tandem/config.json` if you trust that project.
206
-
207
- **Profiles:** `/save-profile <name>` stores the current model, reasoning effort,
208
- budget and review loops in `~/.tandem/profiles/<name>.json`, and `/profile <name>`
209
- loads them back into the running session (only the fields present in the file are
210
- applied). `/profile` alone lists the saved ones. Names use `a-z`, `0-9`, `-` and `_`.
211
- Profiles never include `verifyCommand` or the API key.
212
-
213
- The API key is never stored in these files — it lives in the OS credential
214
- store (or `DEEPSEEK_API_KEY` env var, which takes priority, for CI use).
215
-
216
- ## Development
217
-
218
- See [CONTRIBUTING.md](./CONTRIBUTING.md).
219
-
220
- ```bash
221
- pnpm install
222
- pnpm typecheck
223
- pnpm dev "some task"
224
- ```
225
-
226
- ## Disclaimer
227
-
228
- This is an independent, community-run project. It is not affiliated with,
229
- endorsed by, or sponsored by DeepSeek.
230
-
231
- ## License
232
-
233
- [MIT](./LICENSE)
1
+ # Tandem Mode
2
+
3
+ [![npm version](https://img.shields.io/npm/v/tandem-mode.svg)](https://www.npmjs.com/package/tandem-mode)
4
+ [![license](https://img.shields.io/npm/l/tandem-mode.svg)](./LICENSE)
5
+ [![node](https://img.shields.io/node/v/tandem-mode.svg)](./package.json)
6
+ [![good first issues](https://img.shields.io/github/issues/zdrave08/Tandem-Mode/good%20first%20issue)](https://github.com/zdrave08/Tandem-Mode/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22)
7
+
8
+ **English** | [Srpski](./README.sr.md)
9
+
10
+ A terminal coding agent built specifically for the DeepSeek API — not a generic
11
+ LLM harness with DeepSeek bolted on. Interactive REPL, planner/worker/reviewer
12
+ orchestration, cache-aware prompt architecture, and first-class support for
13
+ Windows, macOS, and Linux.
14
+
15
+ > **Independent open-source project. Not affiliated with or endorsed by
16
+ > DeepSeek.**
17
+
18
+ ## Status
19
+
20
+ M0–M4 of the [development plan](./deepseek-cli-development-plan.md) are done.
21
+ Published on npm, usable today for real coding tasks against a local repo.
22
+
23
+ First benchmark run is in — see [full results](./docs/benchmark-results.md).
24
+ Headline: all three configurations (Pro-only, Flash-only, orchestration)
25
+ fixed 4/4 injected bugs correctly in a real WooCommerce plugin, with a clean
26
+ `php -l` and zero unnecessary file changes. But for this class of task
27
+ (single-file, well-scoped fixes), orchestration cost ~9.5× more and took
28
+ ~19× longer than Pro-only for the same correctness — the opposite of what
29
+ you'd want orchestration for. Read as: orchestration's overhead needs a
30
+ bigger, more decomposable task to pay for itself, which this first run didn't
31
+ test. Reported as-is, not adjusted to fit expectations.
32
+
33
+ ## Features
34
+
35
+ - **Agentic loop** — `deepseek-v4-pro`/`deepseek-v4-flash` with tool calling:
36
+ `read_file`, `list_dir`, `search`, `edit`, `git_diff`, `shell`, `view_image`,
37
+ `web_search`.
38
+ - **Two entry points** — interactive REPL for normal work, single-shot mode
39
+ (`tandem "task" --yes`) for scripting and CI.
40
+ - **Orchestration** (`/plan`) — a planner produces a JSON task list, workers
41
+ execute each task with a fresh minimal context, a reviewer checks the git
42
+ diff against the original task and either approves or requests corrections
43
+ (capped by `max_review_loops`).
44
+ - **Cache-aware prompts** — the worker's system prompt + repo map + plan stay
45
+ byte-identical across calls in one orchestration run, so DeepSeek's context
46
+ cache actually hits. Measured live: cache-hit tokens grew call over call
47
+ within a single `/plan` run.
48
+ - **Vision** — `view_image` lets the agent look at a screenshot you point it
49
+ to; `/paste` grabs an image straight from the clipboard (Windows, macOS,
50
+ and Linux via X11/`xclip` or Wayland/`wl-clipboard`).
51
+ - **Web search** — isolated calls to DeepSeek's Responses API when the agent
52
+ needs something outside the repo (an error message, a library's docs).
53
+ - **Session persistence** — every session is a JSONL file; `/resume` continues
54
+ the latest (or a named) one, `/fork` branches off without touching the
55
+ original.
56
+ - **Safety** — destructive actions (file edits, shell commands not on a small
57
+ read-only allowlist) always ask for confirmation; `y`/`n`/`a` where `a`
58
+ remembers the choice for that tool for the rest of the session. `--yes`
59
+ bypasses this for CI but always prints what it auto-approved.
60
+ - **Cost control** — usage is read only from the API's own `usage` field,
61
+ never estimated. A budget (`/budget`, `--budget`) hard-stops the loop before
62
+ the next API call if exceeded, without losing the session. `/usage` also
63
+ shows what the session would have cost off-peak, and the REPL warns you at
64
+ startup if you're currently in a peak-pricing window.
65
+ - **Status line** — the last line of every turn shows model, mode (chat/plan),
66
+ cost (and budget), and the current call out of the iteration limit; it turns
67
+ yellow, then red, as you approach the budget or the limit.
68
+ - **Readable tool output** — `edit` shows a red/green diff, `read_file`, `search`
69
+ and `list_dir` collapse to a one-line summary (`120 lines read`, `no matches`).
70
+ - **ESC to interrupt** — cancels the in-flight call (and any running shell
71
+ command) cleanly, keeping whatever was generated so far.
72
+ - **Cross-platform** — the shell tool runs PowerShell natively on Windows and
73
+ `sh` on macOS/Linux, file edits preserve the original CRLF/LF line ending
74
+ style, paths are handled with `path.resolve` throughout.
75
+
76
+ ## Quick start
77
+
78
+ ```bash
79
+ npm install -g tandem-mode
80
+ tandem # interactive REPL
81
+ tandem "explain what this repo does" --yes # one-shot
82
+ ```
83
+
84
+ Or from source (useful for contributing, or to track `main` instead of the
85
+ latest npm release):
86
+
87
+ ```bash
88
+ git clone https://github.com/zdrave08/Tandem-Mode.git
89
+ cd Tandem-Mode
90
+ pnpm install
91
+ pnpm dev # interactive REPL
92
+ pnpm dev "explain what this repo does" --yes # one-shot
93
+ ```
94
+
95
+ On first run you'll be asked for a DeepSeek API key (get one at
96
+ [platform.deepseek.com](https://platform.deepseek.com)) and a default
97
+ model/reasoning effort. The key is stored in your OS's own secure credential
98
+ store — never in a config file or log:
99
+
100
+ - **Windows** — DPAPI-encrypted (tied to your OS user account) in
101
+ `%LOCALAPPDATA%\TandemMode\credentials.dat`.
102
+ - **macOS** — the login Keychain, via the built-in `security` CLI.
103
+ - **Linux** — the Secret Service (gnome-keyring, KWallet, or similar), via
104
+ `secret-tool` (install `libsecret-tools` if it's missing).
105
+
106
+ `DEEPSEEK_API_KEY` works everywhere and always takes priority, for CI use.
107
+
108
+ ## Usage
109
+
110
+ ```bash
111
+ tandem # interactive REPL
112
+ tandem "fix the off-by-one in foo.ts"
113
+ tandem --plan "add dark mode to the settings page"
114
+ tandem "task" --model deepseek-v4-flash --effort low --budget 0.50 --yes
115
+ ```
116
+
117
+ | Flag | Effect |
118
+ |---|---|
119
+ | `--resume` / `-r` | Continue the latest session in this directory |
120
+ | `--yes` / `-y` | Auto-approve destructive actions (prints what it approved) |
121
+ | `--plan` | Run planner/worker/reviewer orchestration instead of a single turn |
122
+ | `--model` | `deepseek-v4-pro` or `deepseek-v4-flash` |
123
+ | `--effort` | `low`, `high`, or `max` reasoning effort |
124
+ | `--budget` | Hard USD cap for the run |
125
+ | `--max-review-loops` | Cap on orchestration correction cycles (default 3) |
126
+ | `--max-iterations` | Model calls per chunk of a turn (default 25); at the limit the agent asks whether to continue |
127
+ | `--auto-continue` | Continue at the iteration limit without asking — only together with a budget (`--budget`) |
128
+
129
+ ### REPL commands
130
+
131
+ | Command | Effect |
132
+ |---|---|
133
+ | `/plan <task>` | Planner/worker/reviewer orchestration |
134
+ | `/model [name]` | Show or switch model |
135
+ | `/thinking [on\|off]` | Toggle thinking mode |
136
+ | `/effort [low\|high\|max]` | Show or set reasoning effort |
137
+ | `/status` | Current session/settings |
138
+ | `/diff [--staged] [path]` | Working-tree diff, no API call |
139
+ | `/usage` | Tokens, cost, off-peak projection |
140
+ | `/budget [amount]` | Show or set the session budget |
141
+ | `/new` | Start a fresh session |
142
+ | `/save-profile <name>` | Save model, effort, budget and review loops as a named profile |
143
+ | `/profile [name]` | Load a saved profile, or list them |
144
+ | `/compact` | Summarize the history into a new session to free up context; the old session stays on disk |
145
+ | `/fork` | New session, carrying over the current history |
146
+ | `/resume [id]` | Continue the latest (or a named) session |
147
+ | `/paste [message]` | Send a clipboard image to the agent |
148
+ | `/clear` | Clear the screen |
149
+ | `/help` | This list |
150
+ | `/exit` | Quit |
151
+
152
+ Press **ESC** at any time during a turn to interrupt it.
153
+
154
+ ## Architecture
155
+
156
+ ```
157
+ tandem (no args) ─┬─> interactive REPL ─┬─> single turn: agent loop (tools)
158
+ │ └─> /plan: planner → worker(s) → reviewer
159
+ tandem "task" ──┘ (single-shot, same agent loop, for scripts/CI)
160
+ ```
161
+
162
+ - `src/deepseek/` — thin client for DeepSeek's OpenAI-compatible API
163
+ (streaming + non-streaming chat completions, vision, web search via
164
+ Responses API). See [`docs/api-notes.en.md`](./docs/api-notes.en.md)
165
+ (Serbian original: [`docs/api-notes.md`](./docs/api-notes.md)) for the
166
+ API behavior this is built against, verified live rather than assumed.
167
+ - `src/agent/` — the tool-calling loop, tool implementations, session
168
+ persistence, usage/cost tracking.
169
+ - `src/orchestrator/` — planner/worker/reviewer, repo-map generation, the
170
+ cache-aware stable-prefix construction.
171
+ - `src/repl/` — slash commands, runtime config, the first-run wizard.
172
+ - `src/cli.tsx` — Ink-based terminal UI and the REPL/single-shot entry points.
173
+
174
+ ## Configuration
175
+
176
+ Layered: **session** (in-REPL commands) > **project** (`.tandem/config.json`
177
+ in the current directory) > **global** (`~/.tandem/config.json`).
178
+
179
+ ```json
180
+ {
181
+ "defaultModel": "deepseek-v4-pro",
182
+ "defaultReasoningEffort": "high",
183
+ "budgetUsd": 5,
184
+ "maxReviewLoops": 3,
185
+ "maxIterations": 25,
186
+ "autoContinue": false,
187
+ "verifyCommand": "pnpm typecheck && pnpm test",
188
+ "notifyCommand": "curl -s -d \"Tandem: $TANDEM_OUTCOME\" https://ntfy.sh/my-topic",
189
+ "language": "en"
190
+ }
191
+ ```
192
+
193
+ `maxIterations` is how many model calls one turn may make before Tandem stops and
194
+ asks "continue for N more calls? (y/n/a)"; `a` remembers the answer for the rest of
195
+ the session. With `autoContinue` (or `--auto-continue`) it continues on its own, but
196
+ only when a budget is set, because the budget is the hard stop before the next API
197
+ call. In non-interactive runs (`--yes`) without `--auto-continue` it stops instead of
198
+ waiting for an answer, and the session is saved so you can send "continue".
199
+
200
+ `verifyCommand` runs before each `/plan` review round and its result goes to
201
+ the reviewer. `language` is the UI language (`en` or `sr`, default `en`); the
202
+ `--lang` flag and the `TANDEM_LANG` environment variable override it, in that
203
+ order. The first-run wizard asks for it.
204
+
205
+ `notifyCommand` runs when a `/plan` run ends: reviewer approved, `max_review_loops`
206
+ reached, or an error (not when you interrupt it with ESC). The details come in as
207
+ environment variables, never spliced into the command text: `TANDEM_OUTCOME`
208
+ (`approved`, `max_review_loops` or `error`), `TANDEM_TASK`, `TANDEM_NOTES` (the
209
+ reviewer's notes, or the error message), `TANDEM_REVIEW_LOOPS` and `TANDEM_COST_USD`.
210
+ The command runs in your shell (PowerShell on Windows, `sh` elsewhere) with a 15 s
211
+ limit, and a failure only prints a warning. Any shell command works, so Slack,
212
+ ntfy, a desktop notification or a webhook are all just examples:
213
+
214
+ ```json
215
+ { "notifyCommand": "curl -s -d \"Tandem: $TANDEM_OUTCOME\" https://ntfy.sh/my-topic" }
216
+ ```
217
+
218
+ On Windows (PowerShell) the variables are written `$env:TANDEM_OUTCOME`.
219
+
220
+ Like `verifyCommand`, `notifyCommand` runs without asking, so only put it in a
221
+ project's `.tandem/config.json` if you trust that project.
222
+
223
+ **Profiles:** `/save-profile <name>` stores the current model, reasoning effort,
224
+ budget and review loops in `~/.tandem/profiles/<name>.json`, and `/profile <name>`
225
+ loads them back into the running session (only the fields present in the file are
226
+ applied). `/profile` alone lists the saved ones. Names use `a-z`, `0-9`, `-` and `_`.
227
+ Profiles never include `verifyCommand` or the API key.
228
+
229
+ The API key is never stored in these files — it lives in the OS credential
230
+ store (or `DEEPSEEK_API_KEY` env var, which takes priority, for CI use).
231
+
232
+ ## Development
233
+
234
+ See [CONTRIBUTING.md](./CONTRIBUTING.md).
235
+
236
+ ```bash
237
+ pnpm install
238
+ pnpm typecheck
239
+ pnpm dev "some task"
240
+ ```
241
+
242
+ ## Disclaimer
243
+
244
+ This is an independent, community-run project. It is not affiliated with,
245
+ endorsed by, or sponsored by DeepSeek.
246
+
247
+ ## License
248
+
249
+ [MIT](./LICENSE)
@@ -17,7 +17,17 @@ const MAX_REASONING_CHARS = 200_000;
17
17
  export async function* runAgentLoop(messages, opts) {
18
18
  const ctx = { cwd: opts.cwd, env: opts.env, usage: opts.usage, ...(opts.signal ? { signal: opts.signal } : {}) };
19
19
  const maxIterations = opts.maxIterations ?? 25;
20
- for (let iteration = 0; iteration < maxIterations; iteration++) {
20
+ // Granica se pomera za još jedan "komad" svaki put kad korisnik (ili autoContinue) dozvoli nastavak.
21
+ let limit = maxIterations;
22
+ for (let iteration = 0;; iteration++) {
23
+ if (iteration >= limit) {
24
+ const proceed = opts.onIterationLimit ? await opts.onIterationLimit({ iterations: iteration }) : false;
25
+ if (!proceed) {
26
+ yield { type: "max_iterations_reached" };
27
+ return;
28
+ }
29
+ limit += maxIterations;
30
+ }
21
31
  if (opts.signal?.aborted) {
22
32
  yield { type: "interrupted" };
23
33
  return;
@@ -29,6 +39,7 @@ export async function* runAgentLoop(messages, opts) {
29
39
  return;
30
40
  }
31
41
  }
42
+ yield { type: "iteration", n: iteration + 1, max: limit };
32
43
  let reasoning = "";
33
44
  let content = "";
34
45
  const toolCallBuf = new Map();
@@ -159,6 +170,5 @@ export async function* runAgentLoop(messages, opts) {
159
170
  await appendSessionMessage(opts.session, toolMsg);
160
171
  }
161
172
  }
162
- yield { type: "max_iterations_reached" };
163
173
  }
164
174
  //# sourceMappingURL=loop.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"loop.js","sourceRoot":"","sources":["../../src/agent/loop.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"loop.js","sourceRoot":"","sources":["../../src/agent/loop.ts"],"names":[],"mappings":"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"}