little-coder 1.8.4 → 1.9.1
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/.pi/extensions/branding/branding.test.ts +42 -0
- package/.pi/extensions/branding/index.ts +56 -10
- package/.pi/extensions/extra-tools/glob.ts +3 -3
- package/.pi/extensions/extra-tools/index.ts +1 -1
- package/.pi/extensions/plan-mode/index.ts +374 -0
- package/.pi/extensions/plan-mode/plan-mode.test.ts +49 -0
- package/.pi/extensions/plan-mode/status.ts +79 -0
- package/.pi/extensions/prompt-history/index.ts +154 -0
- package/.pi/extensions/prompt-history/prompt-history.test.ts +72 -0
- package/.pi/extensions/read-guard-edit/index.ts +89 -0
- package/.pi/extensions/read-guard-edit/read-guard-edit.test.ts +100 -0
- package/.pi/extensions/skill-inject/index.ts +3 -0
- package/.pi/extensions/skill-inject/selector.test.ts +2 -2
- package/.pi/extensions/subagent/index.ts +201 -0
- package/.pi/extensions/subagent/live-spawn.test.ts +47 -0
- package/.pi/extensions/subagent/spawn.test.ts +97 -0
- package/.pi/extensions/subagent/spawn.ts +373 -0
- package/.pi/extensions/subagent/tracker.ts +139 -0
- package/AGENTS.md +5 -0
- package/CHANGELOG.md +33 -0
- package/README.md +17 -3
- package/bin/little-coder.mjs +56 -5
- package/package.json +2 -2
- package/skills/tools/dispatch.md +38 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,39 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to little-coder are documented here. The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and little-coder's public interface (CLI, providers, tools, skills) follows semver starting at `v0.0.1` post-rename.
|
|
4
4
|
|
|
5
|
+
## [v1.9.1] — 2026-06-08
|
|
6
|
+
|
|
7
|
+
### Fixed
|
|
8
|
+
- **Plan Mode shortcut moved to `alt+p` so `shift+tab` stays pi's thinking-level cycle** ([#47](https://github.com/itayinbarr/little-coder/issues/47)). v1.9.0 claimed `shift+tab` for Plan Mode by rebinding pi's built-in `app.thinking.cycle` to `alt+t` in `~/.pi/agent/keybindings.json`. That collided with the muscle memory of every existing pi user — `shift+tab` is the documented thinking cycle — and pi (≥ 0.79) also surfaced an `[Extension issues]` warning whenever the rebind hadn't taken yet. Plan Mode now registers on **`alt+p`** instead (unbound by pi, so the extension claims it cleanly with no shadowing), and `shift+tab` returns to pi's default behavior. The launcher also performs a **one-time cleanup**: on first run after upgrade, if `~/.pi/agent/keybindings.json` still has the v1.9.0 rewrite (`app.thinking.cycle: "alt+t"` exactly), it is removed; any binding you set yourself is preserved untouched. README and the Plan-Mode indicator (`(alt+p to exit)`) updated to match.
|
|
9
|
+
|
|
10
|
+
### Notes for upgraders
|
|
11
|
+
- No CLI-flag or public-API changes. **Plan Mode is now `alt+p`** (was `shift+tab` in v1.9.0). `shift+tab` is again pi's thinking-level cycle. If you customized `app.thinking.cycle` yourself in `~/.pi/agent/keybindings.json`, your binding is left alone.
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## [v1.9.0] — 2026-06-15
|
|
16
|
+
|
|
17
|
+
### Added
|
|
18
|
+
- **Plan Mode (shift+tab).** A Claude-Code-style "research → ask → plan" flow, built as the new `plan-mode` extension. Press **shift+tab** to toggle it (an honey `◆ PLAN MODE` indicator appears below the input). When it's on, submitting a request does *not* run a normal coding turn — instead little-coder: (1) decomposes the request into 1-4 exploration tasks, (2) dispatches read-only explorer sub-coders to gather information (their transcripts never enter the main context — only their concise reports survive), (3) generates 1-3 clarifying questions, each with suggested answers plus a free-text "Other" option, asked via the UI, and (4) synthesizes the findings + your answers into a written plan in the chat. Each reasoning phase ("deciding what to explore…", "preparing clarifying questions…") shows an animated spinner with a running m:ss timer. The planning instructions + research are injected into the synthesis turn's system prompt, so the chat shows only your original request and the plan — never the internal scaffolding. A single continuous m:ss timer runs for the whole process (not just the per-sub-coder timers). When the plan is presented, an **Approve & implement / Keep planning** prompt (arrow keys + enter) gates implementation — only on approval does little-coder start making the changes. **Esc** (or Ctrl+C) cancels a plan in progress.
|
|
19
|
+
- **Up-arrow prompt history** (`prompt-history` extension), **persisted across sessions**. pi's default editor has no prompt recall; from an empty prompt, **↑** now walks back through your recent prompts (most-recent first) and **↓** walks forward. History is saved to `<agentDir>/little-coder-prompt-history.json`, so even a brand-new session can recall prompts from earlier runs. Implemented as a `CustomEditor` subclass (pi copies its keybindings/autocomplete/submit wiring onto it) using `keybindings.matches` for ↑/↓ detection — robust to pi's Kitty keyboard protocol and key-release events — and scoped to recall-from-empty so it never interferes with multi-line cursor movement or the autocomplete dropdown. Edits/writes are blocked during the synthesis turn so plan mode produces a plan, not changes. shift+tab previously cycled the thinking level; pi (≥ 0.79) reserves built-in shortcuts and won't let an extension claim a colliding one, so the launcher rebinds the thinking-level cycle to **alt+t** in `~/.pi/agent/keybindings.json` (non-destructively — only when you haven't set your own binding for it), freeing shift+tab for Plan Mode.
|
|
20
|
+
- **Sub-coders (`dispatch` tool).** little-coder can now spawn isolated child little-coder sessions to research a focused question — single (`{ task }`) or parallel (`{ tasks: [{ label, task }] }`, up to 4, concurrency 2 by default, override with `LITTLE_CODER_SUBCODER_CONCURRENCY`). Children run with the **same local-model provider and extensions** as the parent (spawned through the launcher headless, not bare `pi`) but are constrained to **read + browse-online** tools (read, grep, glob, webfetch, websearch, browser, read-only bash) — no edit/write and no recursive dispatch, enforced via the existing `tool-gating` + `permission-gate` env gates. Each child returns a **concise report**; its full transcript lives in the tool's UI-only `details` and never enters the parent model's context, keeping the main window clean. New `subagent` extension (`spawn.ts` engine, importable by plan mode).
|
|
21
|
+
- **Live sub-coder tracker.** A small animated panel above the input shows each running/finished sub-coder with a spinner, status (✓/✗), elapsed time, and current activity (the latest tool call or report snippet), with a diff-guarded ~120 ms repaint. Hidden on non-interactive (benchmark/RPC) runs.
|
|
22
|
+
- **Session naming + terminal title sync.** The session is auto-named from your first prompt (overridable any time with pi's `/name`), and the terminal tab title now shows the session name (`little-coder · <name>`), updating when you switch sessions with `/resume`. pi's built-in `/resume` already lists past sessions for the current directory.
|
|
23
|
+
- **Read-before-edit guard.** New `read-guard-edit` extension: a file must be **Read** in the current session before it can be **Edited** — an edit to an unread file is blocked with "File must be read first before edit" and a nudge to Read it (so `old_string` matches exactly). Files you just wrote count as read. Mirrors the `write-guard` enforcement pattern.
|
|
24
|
+
|
|
25
|
+
### Changed
|
|
26
|
+
- **`glob` match cap lowered 500 → 100** (`extra-tools/glob.ts`) to keep results focused for small models. (`grep` was already capped at 100.)
|
|
27
|
+
- **Default thinking level is now `medium`** for interactive sessions (pi's default is `minimal`) — the launcher passes `--thinking medium` unless you set a level yourself (`--thinking`, or a `--model …:<level>` shorthand) or run headless (`--mode`/`-p`).
|
|
28
|
+
- **Auto-named session titles are capped at 4 words**, cut on word boundaries (no more mid-word truncation) with a trailing `…` when the prompt was longer.
|
|
29
|
+
|
|
30
|
+
### Dependencies
|
|
31
|
+
- **Bumped bundled pi `@earendil-works/pi-coding-agent` 0.75.3 → 0.79.4.** The "Operation aborted" marker patch (`scripts/patch-pi.mjs`) still applies cleanly to the new source (verified by `patch-pi.test.mjs`). pi 0.79 no longer hoists `@earendil-works/pi-tui` to the top level, so the `dispatch` tool's result renderers now build their lines as duck-typed components via the theme (the same pattern `branding` already uses) instead of importing pi-tui primitives — no behavior change.
|
|
32
|
+
|
|
33
|
+
### Notes for upgraders
|
|
34
|
+
- No breaking CLI-flag or public-API changes. **shift+tab now toggles Plan Mode** instead of cycling the thinking level — use **alt+t** for the thinking-level cycle (the launcher writes this rebinding into `~/.pi/agent/keybindings.json`, preserving any binding you've already set). New env var `LITTLE_CODER_SUBCODER_CONCURRENCY` (default 2) tunes how many sub-coders run at once against your local backend.
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
5
38
|
## [v1.8.4] — 2026-06-08
|
|
6
39
|
|
|
7
40
|
### Added
|
package/README.md
CHANGED
|
@@ -60,6 +60,14 @@ little-coder --list-models # see everything pi knows about
|
|
|
60
60
|
|
|
61
61
|
The agent uses the directory you launched it from as its working directory — `Read` / `Write` / `Edit` / `Bash` operate on your project, not on little-coder's install path.
|
|
62
62
|
|
|
63
|
+
### Interactive features
|
|
64
|
+
|
|
65
|
+
- **Plan Mode** — press **alt+p** to toggle (a `◆ PLAN MODE` indicator shows below the input). Submit a request and little-coder researches it with sub-coders, asks you 1-3 clarifying questions (each with suggested answers and a free-text option), then writes a plan in the chat instead of editing anything. **Esc** cancels a plan mid-run. (**shift+tab** stays pi's thinking-level cycle.)
|
|
66
|
+
- **Prompt history** — from an empty input, **↑** recalls your recent prompts (most-recent first), **↓** walks forward. History persists across sessions, so a fresh session can recall prompts from earlier runs.
|
|
67
|
+
- **Sub-coders (`dispatch`)** — little-coder can spawn isolated child sessions to research a question (read the repo + browse online, read-only) and report back concisely, without cluttering the main conversation. A live panel above the input tracks them. Tune parallelism with `LITTLE_CODER_SUBCODER_CONCURRENCY` (default 2).
|
|
68
|
+
- **Sessions** — each session is auto-named from your first prompt (rename with `/name`) and shown in the terminal tab title. Use `/resume` to list and reopen past sessions for the current directory.
|
|
69
|
+
- **Read-before-edit** — editing a file requires reading it first, so edits match the file's exact current text.
|
|
70
|
+
|
|
63
71
|
For local providers (llama.cpp, Ollama, LM Studio) pi expects *some* value in the API-key env even though local servers ignore it:
|
|
64
72
|
|
|
65
73
|
```bash
|
|
@@ -99,12 +107,14 @@ build/bin/llama-server -m ~/models/Qwen3.6-35B-A3B-UD-Q4_K_M.gguf \
|
|
|
99
107
|
|
|
100
108
|
If you only need text and want to skip the projector download, drop the second `hf download` line and the `--mmproj` flag — little-coder still works text-only, but the TUI's image attachment will be rejected by the server with a 4xx.
|
|
101
109
|
|
|
110
|
+
**Context window.** `-c` sets the server's context (`-c 16384` = 16K above — a conservative default for 8 GB VRAM). little-coder **auto-detects the live `n_ctx`** from llama.cpp's `/props` at startup and registers the model with it, so whatever you pass to `-c` is what the TUI shows and budgets against — no `models.json` edit needed. To run larger, relaunch the server with e.g. `-c 131072` (128K) or `-c 262144` (256K); the KV cache grows with it, so size it to your RAM/VRAM. (`--list-models` reflects the detected window.)
|
|
111
|
+
|
|
102
112
|
**Option B — Ollama** (simpler, but slower on MoE):
|
|
103
113
|
|
|
104
114
|
```bash
|
|
105
115
|
curl -fsSL https://ollama.com/install.sh | sh
|
|
106
116
|
ollama pull qwen3.5 # 9.7B — the paper's model
|
|
107
|
-
# or: ollama pull qwen3.6
|
|
117
|
+
# or: ollama pull qwen3.6:35b-a3b
|
|
108
118
|
```
|
|
109
119
|
|
|
110
120
|
**Option C — LM Studio** (GUI; OpenAI-compatible server on port 1234):
|
|
@@ -330,11 +340,15 @@ The benchmarks harness (`benchmarks/`) is dev-only and not shipped with the npm
|
|
|
330
340
|
little-coder/
|
|
331
341
|
├── .pi/
|
|
332
342
|
│ ├── settings.json # per-model profiles + benchmark_overrides (terminal_bench, gaia)
|
|
333
|
-
│ └── extensions/ #
|
|
334
|
-
│ ├── branding/ # little-coder startup header + terminal title
|
|
343
|
+
│ └── extensions/ # 27 TypeScript extensions, auto-discovered by pi
|
|
344
|
+
│ ├── branding/ # little-coder startup header + terminal title + session auto-naming
|
|
345
|
+
│ ├── plan-mode/ # alt+p "research → ask → plan" flow (sub-coders + clarifying questions → written plan)
|
|
346
|
+
│ ├── subagent/ # `dispatch` tool: isolated read/browse-only sub-coders + live tracker (spawn.ts engine)
|
|
347
|
+
│ ├── prompt-history/ # up-arrow recall of recent prompts (from an empty input)
|
|
335
348
|
│ ├── llama-cpp-provider/ # data-driven provider registration from models.json — ships llamacpp, ollama, lmstudio (+ user override file)
|
|
336
349
|
│ ├── write-guard/ # Write refuses on existing files; rewrites root-bare /foo.md paths to cwd
|
|
337
350
|
│ ├── read-guard/ # trims a Read that would overflow the context window to its first 30 lines + a search-instead directive
|
|
351
|
+
│ ├── read-guard-edit/ # Edit refuses until the file has been Read this session
|
|
338
352
|
│ ├── extra-tools/ # glob, webfetch, websearch (pi ships grep/find)
|
|
339
353
|
│ ├── skill-inject/ # per-turn tool-skill selection (error > recency > intent)
|
|
340
354
|
│ ├── knowledge-inject/ # algorithm cheat-sheet scoring (word=1.0, bigram=2.0, threshold=2.0)
|
package/bin/little-coder.mjs
CHANGED
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
mkdirSync,
|
|
10
10
|
readdirSync,
|
|
11
11
|
readFileSync,
|
|
12
|
+
rmSync,
|
|
12
13
|
statSync,
|
|
13
14
|
writeFileSync,
|
|
14
15
|
} from "node:fs";
|
|
@@ -36,6 +37,13 @@ if (tooOld) {
|
|
|
36
37
|
const here = dirname(fileURLToPath(import.meta.url));
|
|
37
38
|
const pkgRoot = resolve(here, "..");
|
|
38
39
|
|
|
40
|
+
// Headless sub-coder fast-path. When the subagent extension re-invokes this
|
|
41
|
+
// launcher to spawn a child little-coder (--mode json -p), the update check and
|
|
42
|
+
// the global-settings merge below are pointless per-child overhead (network +
|
|
43
|
+
// disk) — and we want children to start fast. The env flag is set by
|
|
44
|
+
// .pi/extensions/subagent/spawn.ts::buildChildEnv.
|
|
45
|
+
const isSubagent = process.env.LITTLE_CODER_SUBAGENT === "1";
|
|
46
|
+
|
|
39
47
|
// ---- 3. Resolve the bundled pi CLI entry point ----
|
|
40
48
|
// We invoke pi's JS entry directly under the current Node binary instead of
|
|
41
49
|
// the `node_modules/.bin/pi` shim. Two reasons:
|
|
@@ -110,10 +118,12 @@ try {
|
|
|
110
118
|
} catch {
|
|
111
119
|
// ignore — update-check just won't fire if we can't read the version
|
|
112
120
|
}
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
121
|
+
if (!isSubagent) {
|
|
122
|
+
const exitAfterCheck = await checkForUpdate(currentVersion);
|
|
123
|
+
if (exitAfterCheck) {
|
|
124
|
+
// Successful update happened; user needs to re-run the new binary.
|
|
125
|
+
process.exit(0);
|
|
126
|
+
}
|
|
117
127
|
}
|
|
118
128
|
|
|
119
129
|
// ---- 6. Compose pi argv ----
|
|
@@ -124,10 +134,22 @@ if (exitAfterCheck) {
|
|
|
124
134
|
// Strip our own flags before forwarding to pi so it doesn't reject them.
|
|
125
135
|
const userArgs = process.argv.slice(2).filter((a) => a !== "--no-update-check");
|
|
126
136
|
const agentsMd = join(pkgRoot, "AGENTS.md");
|
|
137
|
+
|
|
138
|
+
// Default the thinking level to "medium" for interactive sessions (pi's own
|
|
139
|
+
// default is "minimal"). Only when the user hasn't asked for a level themselves
|
|
140
|
+
// (--thinking, or the --model "provider/id:level" shorthand) and this isn't a
|
|
141
|
+
// headless/sub-coder run (--mode rpc/json) where the caller controls thinking.
|
|
142
|
+
const userPickedThinking =
|
|
143
|
+
userArgs.includes("--thinking") ||
|
|
144
|
+
userArgs.some((a, i) => a === "--model" && /:/.test(userArgs[i + 1] || ""));
|
|
145
|
+
const headless = isSubagent || userArgs.includes("--mode") || userArgs.includes("-p");
|
|
146
|
+
const thinkingArgs = !userPickedThinking && !headless ? ["--thinking", "medium"] : [];
|
|
147
|
+
|
|
127
148
|
const piArgs = [
|
|
128
149
|
"--no-context-files",
|
|
129
150
|
"--no-extensions",
|
|
130
151
|
...(existsSync(agentsMd) ? ["--system-prompt", agentsMd] : []),
|
|
152
|
+
...thinkingArgs,
|
|
131
153
|
...extArgs,
|
|
132
154
|
...userArgs,
|
|
133
155
|
];
|
|
@@ -167,7 +189,10 @@ if (process.env.PI_SKIP_VERSION_CHECK === undefined) {
|
|
|
167
189
|
//
|
|
168
190
|
// Existing keys are preserved. We only write when the desired value differs
|
|
169
191
|
// from what's already on disk, so this is a no-op on warm launches.
|
|
170
|
-
|
|
192
|
+
//
|
|
193
|
+
// Skipped for headless sub-coders: they share the user's settings (already
|
|
194
|
+
// written by the interactive parent) and shouldn't each re-do the merge.
|
|
195
|
+
if (!isSubagent) try {
|
|
171
196
|
const agentDirEnv = process.env.PI_CODING_AGENT_DIR;
|
|
172
197
|
let agentDir;
|
|
173
198
|
if (agentDirEnv && agentDirEnv.trim().length > 0) {
|
|
@@ -219,6 +244,32 @@ try {
|
|
|
219
244
|
if (mutated) {
|
|
220
245
|
writeFileSync(globalSettingsPath, JSON.stringify(globalSettings, null, 2));
|
|
221
246
|
}
|
|
247
|
+
|
|
248
|
+
// ---- 8b. One-time cleanup of the v1.9.0 keybinding rewrite ----
|
|
249
|
+
// v1.9.0 wrote `app.thinking.cycle: "alt+t"` into ~/.pi/agent/keybindings.json
|
|
250
|
+
// so the plan-mode extension could claim shift+tab (issue #47). Plan mode now
|
|
251
|
+
// lives on alt+p, so shift+tab should go back to pi's default thinking-cycle
|
|
252
|
+
// binding — but only if the value is *exactly* the one we wrote. A user who
|
|
253
|
+
// chose their own binding (anything ≠ "alt+t") wins.
|
|
254
|
+
const keybindingsPath = join(agentDir, "keybindings.json");
|
|
255
|
+
if (existsSync(keybindingsPath)) {
|
|
256
|
+
try {
|
|
257
|
+
const parsed = JSON.parse(readFileSync(keybindingsPath, "utf-8"));
|
|
258
|
+
if (parsed && typeof parsed === "object" && parsed["app.thinking.cycle"] === "alt+t") {
|
|
259
|
+
delete parsed["app.thinking.cycle"];
|
|
260
|
+
if (Object.keys(parsed).length === 0) {
|
|
261
|
+
// Don't leave an empty {} sitting around — remove the file so pi
|
|
262
|
+
// reads its defaults cleanly.
|
|
263
|
+
rmSync(keybindingsPath);
|
|
264
|
+
} else {
|
|
265
|
+
writeFileSync(keybindingsPath, JSON.stringify(parsed, null, 2));
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
} catch {
|
|
269
|
+
// Corrupted JSON or unreadable — leave it alone; pi will surface its own error.
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
|
|
222
273
|
} catch {
|
|
223
274
|
// Best-effort. If we can't write the settings (read-only HOME, etc.) pi
|
|
224
275
|
// falls back to its built-in defaults — the [Extensions] block will show
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "little-coder",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.9.1",
|
|
4
4
|
"description": "A pi-based coding agent optimized for small local language models. Reproduces the whitepaper's scaffold-model-fit adaptations as pi extensions.",
|
|
5
5
|
"homepage": "https://github.com/itayinbarr/little-coder",
|
|
6
6
|
"repository": {
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"postinstall": "node scripts/patch-pi.mjs"
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
|
-
"@earendil-works/pi-coding-agent": "^0.
|
|
41
|
+
"@earendil-works/pi-coding-agent": "^0.79.4",
|
|
42
42
|
"@sinclair/typebox": "^0.34.49",
|
|
43
43
|
"playwright": "^1.59.1"
|
|
44
44
|
},
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: dispatch-guidance
|
|
3
|
+
type: tool-guidance
|
|
4
|
+
target_tool: dispatch
|
|
5
|
+
priority: 6
|
|
6
|
+
token_cost: 140
|
|
7
|
+
user-invocable: false
|
|
8
|
+
---
|
|
9
|
+
## Dispatch Tool (sub-coders)
|
|
10
|
+
Delegate focused research to isolated child little-coder sessions ("sub-coders").
|
|
11
|
+
Each runs in its own context window, can READ the repo and BROWSE online
|
|
12
|
+
(read, grep, glob, webfetch, websearch, browser, read-only bash) but CANNOT
|
|
13
|
+
edit or write files. Each returns a concise report. Use this to gather
|
|
14
|
+
information without filling your own context with raw file dumps or web pages.
|
|
15
|
+
|
|
16
|
+
SINGLE: `task` (string) — one research question.
|
|
17
|
+
PARALLEL: `tasks` — array of `{label, task}`, up to 4, run concurrently.
|
|
18
|
+
OPTIONAL: `cwd` (defaults to the current working directory).
|
|
19
|
+
|
|
20
|
+
RULES:
|
|
21
|
+
- Give each parallel task a short, distinct `label` — it shows in the live tracker.
|
|
22
|
+
- Ask narrow, answerable questions ("how does auth work in this repo?", not "do everything").
|
|
23
|
+
- You receive only each sub-coder's short report; the full transcript stays in the
|
|
24
|
+
tool's details (not in your context). Act on the reports.
|
|
25
|
+
- Sub-coders can't change files — do the editing yourself after they report back.
|
|
26
|
+
|
|
27
|
+
EXAMPLE (single):
|
|
28
|
+
```tool
|
|
29
|
+
{"name": "dispatch", "input": {"task": "Find where sessions are persisted in this repo and summarize the format."}}
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
EXAMPLE (parallel):
|
|
33
|
+
```tool
|
|
34
|
+
{"name": "dispatch", "input": {"tasks": [
|
|
35
|
+
{"label": "repo auth", "task": "How does authentication work in this codebase? Cite files."},
|
|
36
|
+
{"label": "lib docs", "task": "Look up the current recommended API for the jose JWT library online."}
|
|
37
|
+
]}}
|
|
38
|
+
```
|