@qwen-code/qwen-code 0.16.1 → 0.16.2
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/bundled/new-app/SKILL.md +22 -0
- package/bundled/qc-helper/docs/configuration/settings.md +9 -4
- package/bundled/qc-helper/docs/features/_meta.ts +1 -0
- package/bundled/qc-helper/docs/features/headless.md +32 -0
- package/bundled/qc-helper/docs/features/memory.md +22 -5
- package/bundled/qc-helper/docs/features/worktree.md +345 -0
- package/chunks/{agent-2JCG7FDJ.js → agent-RY5EB3XR.js} +15 -15
- package/chunks/{anthropicContentGenerator-RQJNXJIY.js → anthropicContentGenerator-LYI3OHBB.js} +4 -4
- package/chunks/{askUserQuestion-PQPMPNM3.js → askUserQuestion-R3MKD2JT.js} +2 -2
- package/chunks/{ca-UZ7BANMN.js → ca-NMZFEGAU.js} +1 -0
- package/chunks/{chunk-JCR2WRXZ.js → chunk-4YNZFYJY.js} +666 -29
- package/chunks/{chunk-HW5S7L73.js → chunk-66CJCYYZ.js} +11 -11
- package/chunks/{chunk-MAY32HXD.js → chunk-6NUSWV4M.js} +1 -1
- package/chunks/{chunk-BAZDG3QU.js → chunk-7HM6OB7M.js} +2801 -1894
- package/chunks/{chunk-GGNTZ2NH.js → chunk-7YJIR2FX.js} +2 -2
- package/chunks/{chunk-XP27SJMH.js → chunk-ACBGEKB7.js} +10 -1
- package/chunks/{chunk-CAVZVZX6.js → chunk-C27V5A2J.js} +1 -1
- package/chunks/{chunk-G7YTSRES.js → chunk-EY6BDW7Y.js} +1 -1
- package/chunks/{chunk-YJLGXDQJ.js → chunk-FO7BIVSR.js} +1 -1
- package/chunks/{chunk-D6LBYOCX.js → chunk-GQXXO5HJ.js} +109 -17
- package/chunks/{chunk-F23NCRJ2.js → chunk-GVWPJCXU.js} +1 -1
- package/chunks/{chunk-CSWBPY3P.js → chunk-JVD46YJV.js} +1 -1
- package/chunks/{chunk-4AOCVI6J.js → chunk-K72FHBFO.js} +1 -1
- package/chunks/{chunk-PR4T27R7.js → chunk-NQ3E7YLD.js} +1 -1
- package/chunks/{chunk-D5NTAHYL.js → chunk-ODPVJ6JJ.js} +1 -1
- package/chunks/{chunk-KXZ4TJB4.js → chunk-OIL7KDWV.js} +1 -1
- package/chunks/{chunk-7LMPOVYW.js → chunk-PJLEMR7N.js} +38 -16
- package/chunks/{chunk-L5E26RN6.js → chunk-TXQI3VZ7.js} +1 -1
- package/chunks/{chunk-N6GSJHZ4.js → chunk-UE5LPQF7.js} +9 -14
- package/chunks/{chunk-DMIMF3CG.js → chunk-VMOWXTRC.js} +2 -2
- package/chunks/{chunk-PVVL5Q3W.js → chunk-YMDXEEOW.js} +1 -1
- package/chunks/{contextCommand-XVRGKS3Q.js → contextCommand-DDGVLQSF.js} +17 -17
- package/chunks/{cron-create-IGYXQVG4.js → cron-create-BTEOGHPH.js} +2 -2
- package/chunks/{cron-delete-ETKIZCWT.js → cron-delete-56CEWELN.js} +2 -2
- package/chunks/{cron-list-BVCUSWRU.js → cron-list-SV6QRZW2.js} +2 -2
- package/chunks/{de-V4IE2OOZ.js → de-OIMT3OMI.js} +1 -0
- package/chunks/{dist-4L54HRX2.js → dist-R2SXPG74.js} +22 -3
- package/chunks/{edit-3MLXHQPW.js → edit-4LLGNYVZ.js} +16 -16
- package/chunks/{en-HGJ2SPLM.js → en-2IFZ5THF.js} +1 -0
- package/chunks/{enter-worktree-OCA4SG6D.js → enter-worktree-E2R5XAFT.js} +18 -16
- package/chunks/{exit-worktree-6EDLXVEV.js → exit-worktree-YVBYYYDD.js} +15 -15
- package/chunks/{exitPlanMode-H75KHRX4.js → exitPlanMode-WD5IH7NS.js} +15 -15
- package/chunks/{fr-CJULI7ZX.js → fr-PVELSHTV.js} +1 -0
- package/chunks/{geminiContentGenerator-E7Y6TCPU.js → geminiContentGenerator-LM65ADWM.js} +3 -3
- package/chunks/{glob-JFFSKARO.js → glob-6X6OCEWE.js} +15 -15
- package/chunks/{grep-7TAFR7MX.js → grep-2UUPSSIQ.js} +15 -15
- package/chunks/{ja-L7CHRQEW.js → ja-P5TK5GNN.js} +1 -0
- package/chunks/{keychain-token-storage-335UOLJ6.js → keychain-token-storage-3552ENXE.js} +2 -2
- package/chunks/{ls-7HD6XG3V.js → ls-MYXAM7LJ.js} +3 -3
- package/chunks/{lsp-ZZSFCIWD.js → lsp-PFGI35JL.js} +2 -2
- package/chunks/{monitor-YX2ABLXH.js → monitor-VUHPEGUW.js} +25 -20
- package/chunks/{notebook-edit-EEJEGFZR.js → notebook-edit-P4QVLW6I.js} +16 -16
- package/chunks/{openaiContentGenerator-BSAWHGQJ.js → openaiContentGenerator-JH4YNZ3H.js} +10 -10
- package/chunks/{pt-M6JULLEQ.js → pt-A5GHG66T.js} +1 -0
- package/chunks/{qwenContentGenerator-47XRHQXM.js → qwenContentGenerator-5FE4UYUT.js} +17 -17
- package/chunks/{qwenOAuth2-EEJGROP7.js → qwenOAuth2-BAN2EGSH.js} +3 -3
- package/chunks/{read-file-O53WD46Y.js → read-file-J7DH4OKV.js} +7 -7
- package/chunks/{ripGrep-OXNZ5Z3T.js → ripGrep-33DECY4F.js} +15 -15
- package/chunks/{ru-QILM4HBC.js → ru-66XKB4QX.js} +1 -0
- package/chunks/{send-message-ULK4MQXJ.js → send-message-JUFP62VD.js} +2 -2
- package/chunks/{serve-H2REZAYD.js → serve-7FX7MREA.js} +17 -17
- package/chunks/{shell-DET66JID.js → shell-ZNTQIRK6.js} +15 -15
- package/chunks/{skill-ZIXPX3L3.js → skill-CFCUIY23.js} +9 -9
- package/chunks/{src-PN3XGQYP.js → src-AHV2CWEQ.js} +39 -15
- package/chunks/{syntheticOutput-IS2X5OZ2.js → syntheticOutput-AKTXC6FR.js} +3 -3
- package/chunks/{task-stop-7QSJGSSP.js → task-stop-2NYFR2ES.js} +2 -2
- package/chunks/{todoWrite-7CVACFUX.js → todoWrite-WHZ2O2XP.js} +3 -3
- package/chunks/{tool-search-GTYLSGZ3.js → tool-search-C2EMLFBJ.js} +7 -7
- package/chunks/{web-fetch-ENQ2I5JA.js → web-fetch-S6MZXPZ5.js} +4 -4
- package/chunks/{write-file-NILNEZCR.js → write-file-EEPVRS4Q.js} +16 -16
- package/chunks/{zh-PWL2NKY3.js → zh-OB5P2ZDO.js} +1 -0
- package/chunks/{zh-TW-S3YGWICZ.js → zh-TW-3ND6DQRX.js} +1 -0
- package/cli.js +5666 -4466
- package/locales/ca.js +1 -0
- package/locales/de.js +1 -0
- package/locales/en.js +1 -0
- package/locales/fr.js +1 -0
- package/locales/ja.js +1 -0
- package/locales/pt.js +1 -0
- package/locales/ru.js +1 -0
- package/locales/zh-TW.js +1 -0
- package/locales/zh.js +1 -0
- package/package.json +2 -2
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: new-app
|
|
3
|
+
description: Workflow for creating new applications from scratch. Covers requirements gathering, tech stack selection, scaffolding, implementation, and delivery of a functional prototype.
|
|
4
|
+
when_to_use: When the user asks to create a new application, project, website, game, mobile app, CLI tool, or library from scratch.
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
**Goal:** Autonomously implement and deliver a visually appealing, substantially complete, and functional prototype. Utilize all tools at your disposal to implement the application. Some tools you may especially find useful are 'write_file', 'edit' and 'run_shell_command'.
|
|
8
|
+
|
|
9
|
+
1. **Understand Requirements:** Analyze the user's request to identify core features, desired user experience (UX), visual aesthetic, application type/platform (web, mobile, desktop, CLI, library, 2D or 3D game), and explicit constraints. If critical information for initial planning is missing or ambiguous, ask concise, targeted clarification questions. Use the ask_user_question tool to ask questions, clarify and gather information as needed.
|
|
10
|
+
2. **Propose Plan:** Formulate an internal development plan. Present a clear, concise, high-level summary to the user. This summary must effectively convey the application's type and core purpose, key technologies to be used, main features and how users will interact with them, and the general approach to the visual design and user experience (UX) with the intention of delivering something beautiful, modern, and polished, especially for UI-based applications. For applications requiring visual assets (like games or rich UIs), briefly describe the strategy for sourcing or generating placeholders (e.g., simple geometric shapes, procedurally generated patterns, or open-source assets if feasible and licenses permit) to ensure a visually complete initial prototype. Ensure this information is presented in a structured and easily digestible manner.
|
|
11
|
+
- When key technologies aren't specified, prefer the following:
|
|
12
|
+
- **Websites (Frontend):** React (JavaScript/TypeScript) with Bootstrap CSS, incorporating Material Design principles for UI/UX.
|
|
13
|
+
- **Back-End APIs:** Node.js with Express.js (JavaScript/TypeScript) or Python with FastAPI.
|
|
14
|
+
- **Full-stack:** Next.js (React/Node.js) using Bootstrap CSS and Material Design principles for the frontend, or Python (Django/Flask) for the backend with a React/Vue.js frontend styled with Bootstrap CSS and Material Design principles.
|
|
15
|
+
- **CLIs:** Python or Go.
|
|
16
|
+
- **Mobile App:** Compose Multiplatform (Kotlin Multiplatform) or Flutter (Dart) using Material Design libraries and principles, when sharing code between Android and iOS. Jetpack Compose (Kotlin JVM) with Material Design principles or SwiftUI (Swift) for native apps targeted at either Android or iOS, respectively.
|
|
17
|
+
- **3D Games:** HTML/CSS/JavaScript with Three.js.
|
|
18
|
+
- **2D Games:** HTML/CSS/JavaScript.
|
|
19
|
+
3. **User Approval:** Obtain user approval for the proposed plan.
|
|
20
|
+
4. **Implementation:** Use the 'todo_write' tool to convert the approved plan into a structured todo list with specific, actionable tasks, then autonomously implement each task utilizing all available tools. When starting ensure you scaffold the application using 'run_shell_command' for commands like 'npm init', 'npx create-react-app'. Aim for full scope completion. Proactively create or source necessary placeholder assets (e.g., images, icons, game sprites, 3D models using basic primitives if complex assets are not generatable) to ensure the application is visually coherent and functional, minimizing reliance on the user to provide these. If the model can generate simple assets (e.g., a uniformly colored square sprite, a simple 3D cube), it should do so. Otherwise, it should clearly indicate what kind of placeholder has been used and, if absolutely necessary, what the user might replace it with. Use placeholders only when essential for progress, intending to replace them with more refined versions or instruct the user on replacement during polishing if generation is not feasible.
|
|
21
|
+
5. **Verify:** Review work against the original request, the approved plan. Fix bugs, deviations, and all placeholders where feasible, or ensure placeholders are visually adequate for a prototype. Ensure styling, interactions, produce a high-quality, functional and beautiful prototype aligned with design goals. Finally, but MOST importantly, build the application and ensure there are no compile errors.
|
|
22
|
+
6. **Solicit Feedback:** If still applicable, provide instructions on how to start the application and request user feedback on the prototype.
|
|
@@ -143,10 +143,12 @@ Settings are organized into categories. Most settings should be placed within th
|
|
|
143
143
|
| -------------------------------------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------- |
|
|
144
144
|
| `model.name` | string | The Qwen model to use for conversations. | `undefined` |
|
|
145
145
|
| `model.maxSessionTurns` | number | Maximum number of user/model/tool turns to keep in a session. -1 means unlimited. | `-1` |
|
|
146
|
+
| `model.maxWallTimeSeconds` | number | Wall-clock budget for headless / unattended runs, in seconds. `-1` means unlimited. Overridable per-invocation via `--max-wall-time`, which requires a positive duration (`90`, `30s`, `5m`, `1h`, `1.5h`); the minimum is 1 second — sub-second values (`500ms`, `0.5`) are rejected as typos. Omit the flag to fall back to this setting. Aborts with exit code 55 when exceeded. | `-1` |
|
|
147
|
+
| `model.maxToolCalls` | number | Cumulative tool-call budget for a run (counts every executed tool, success or failure; `structured_output` under `--json-schema` is exempt). `-1` means unlimited; `0` means "no tool calls allowed". Capped at 1,000,000 to catch typos. Overridable via `--max-tool-calls`. Aborts with exit code 55 when exceeded. | `-1` |
|
|
146
148
|
| `model.generationConfig` | object | Advanced overrides passed to the underlying content generator. Supports request controls such as `timeout`, `maxRetries`, `enableCacheControl`, `splitToolMedia` (set `true` for strict OpenAI-compatible servers like LM Studio that reject non-text content on `role: "tool"` messages — splits media into a follow-up user message), `contextWindowSize` (override model's context window size), `modalities` (override auto-detected input modalities), `customHeaders` (custom HTTP headers for API requests), and `extra_body` (additional body parameters for OpenAI-compatible API requests only), along with fine-tuning knobs under `samplingParams` (for example `temperature`, `top_p`, `max_tokens`). Leave unset to rely on provider defaults. | `undefined` |
|
|
147
|
-
| `model.chatCompression.contextPercentageThreshold` | number |
|
|
149
|
+
| `model.chatCompression.contextPercentageThreshold` | number | **REMOVED.** Auto-compaction now uses a three-tier threshold ladder (warn / auto / hard) computed internally from the model's context window via the `computeThresholds()` function — no longer user-configurable. Setting this field in `settings.json` is silently ignored, and a one-line deprecation warning is emitted to stderr at startup. There is currently no replacement for "disable compression entirely" — reactive overflow recovery remains the safety net at the API layer if compression itself fails. (See PR #4345 / `docs/design/auto-compaction-threshold-redesign.md` for the redesign rationale.) | `N/A` |
|
|
148
150
|
| `model.skipNextSpeakerCheck` | boolean | Skip the next speaker check. | `false` |
|
|
149
|
-
| `model.skipLoopDetection` | boolean | Disables loop detection checks.
|
|
151
|
+
| `model.skipLoopDetection` | boolean | Disables streaming loop detection checks. Defaults to `true` (loop detection is skipped) to avoid false positives interrupting legitimate workflows. Set to `false` to re-enable streaming loop detection — useful as a guardrail in headless / non-interactive runs where stuck repetition can otherwise waste budget. | `true` |
|
|
150
152
|
| `model.skipStartupContext` | boolean | Skips sending the startup workspace context (environment summary and acknowledgement) at the beginning of each session. Enable this if you prefer to provide context manually or want to save tokens on startup. | `false` |
|
|
151
153
|
| `model.enableOpenAILogging` | boolean | Enables logging of OpenAI API calls for debugging and analysis. When enabled, API requests and responses are logged to JSON files. | `false` |
|
|
152
154
|
| `model.openAILoggingDir` | string | Custom directory path for OpenAI API logs. If not specified, defaults to `logs/openai` in the current working directory. Supports absolute paths, relative paths (resolved from current working directory), and `~` expansion (home directory). | `undefined` |
|
|
@@ -272,7 +274,8 @@ If you are experiencing performance issues with file searching (e.g., with `@` c
|
|
|
272
274
|
| Setting | Type | Description | Default |
|
|
273
275
|
| -------------------------------- | ------- | --------------------------------------------------------------------------------- | ------- |
|
|
274
276
|
| `memory.enableManagedAutoMemory` | boolean | Enable background extraction of memories from conversations. | `true` |
|
|
275
|
-
| `memory.enableManagedAutoDream` | boolean | Enable automatic consolidation (deduplication and cleanup) of collected memories. | `
|
|
277
|
+
| `memory.enableManagedAutoDream` | boolean | Enable automatic consolidation (deduplication and cleanup) of collected memories. | `true` |
|
|
278
|
+
| `memory.enableAutoSkill` | boolean | Enable background review for reusable project skills after tool-heavy sessions. | `true` |
|
|
276
279
|
|
|
277
280
|
See [Memory](../features/memory) for details on how auto-memory works and how to use the `/memory`, `/remember`, and `/dream` commands.
|
|
278
281
|
|
|
@@ -703,7 +706,9 @@ Qwen Code can execute potentially unsafe operations (like shell commands and fil
|
|
|
703
706
|
|
|
704
707
|
- Using `--sandbox` or `-s` flag.
|
|
705
708
|
- Setting `QWEN_SANDBOX` environment variable.
|
|
706
|
-
-
|
|
709
|
+
- Setting `tools.sandbox` in settings.
|
|
710
|
+
|
|
711
|
+
> ⚠️ **`--yolo` does _not_ automatically enable a sandbox.** YOLO mode only auto-approves tool calls; sandboxing must still be opted into via `--sandbox`, `QWEN_SANDBOX`, or `tools.sandbox`. In headless / non-interactive runs with `--yolo` (or `--approval-mode=yolo`) and no sandbox, the model can execute shell, write, and edit tools at the current process's privilege level — Qwen Code prints a warning to stderr in that case. Suppress with `QWEN_CODE_SUPPRESS_YOLO_WARNING=1` once you've reviewed the trade-off.
|
|
707
712
|
|
|
708
713
|
By default, it uses a pre-built `qwen-code-sandbox` Docker image.
|
|
709
714
|
|
|
@@ -238,9 +238,41 @@ Key command-line options for headless usage:
|
|
|
238
238
|
| `--approval-mode` | Set approval mode | `qwen -p "query" --approval-mode auto_edit` |
|
|
239
239
|
| `--continue` | Resume the most recent session for this project | `qwen --continue -p "Pick up where we left off"` |
|
|
240
240
|
| `--resume [sessionId]` | Resume a specific session (or choose interactively) | `qwen --resume 123e... -p "Finish the refactor"` |
|
|
241
|
+
| `--max-session-turns` | Cap the number of user/model/tool turns in the run | `qwen -p "..." --max-session-turns 30` |
|
|
242
|
+
| `--max-wall-time` | Wall-clock budget; accepts `90` (s), `30s`, `5m`, `1h`, `1.5h` | `qwen -p "..." --max-wall-time 10m` |
|
|
243
|
+
| `--max-tool-calls` | Cumulative tool-call budget for the run | `qwen -p "..." --max-tool-calls 50` |
|
|
241
244
|
|
|
242
245
|
For complete details on all available configuration options, settings files, and environment variables, see the [Configuration Guide](../configuration/settings).
|
|
243
246
|
|
|
247
|
+
## Safety in unattended runs
|
|
248
|
+
|
|
249
|
+
Headless / CI runs combined with `--yolo` (or `--approval-mode=yolo`) auto-approve every tool call, including `shell`, `write`, and `edit`. **`--yolo` does not enable a sandbox** — those tools run at the host process's privilege level. When Qwen Code detects this combination with no sandbox configured, it prints a one-line warning to stderr at startup. Suppress the warning with `QWEN_CODE_SUPPRESS_YOLO_WARNING=1` once you've reviewed the trade-off.
|
|
250
|
+
|
|
251
|
+
### Run-level budgets
|
|
252
|
+
|
|
253
|
+
Qwen Code can abort an unattended run when it crosses one of the following thresholds. Each is `-1` (unlimited) by default; setting any one is enough to bound runaway behavior. They are enforced cooperatively against the same `AbortController` that already carries SIGINT, so a budget abort emits a structured `FatalBudgetExceededError` (exit code **55**) — distinct from the turn-cap exit code 53 and SIGINT's 130 so CI scripts can branch on the reason.
|
|
254
|
+
|
|
255
|
+
| Flag | Settings key | What it bounds |
|
|
256
|
+
| --------------------- | -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
257
|
+
| `--max-wall-time` | `model.maxWallTimeSeconds` | Wall-clock duration of the whole run. Flag accepts `90` (s), `30s`, `5m`, `1h`, `1.5h` (fractional units supported). Minimum 1s — sub-second values are rejected as typos. Settings is seconds. |
|
|
258
|
+
| `--max-tool-calls` | `model.maxToolCalls` | Cumulative top-level tool calls dispatched by the main run loop (counts successes _and_ failures — the model still consumes tokens on errors). See "Scope" below for subagent / structured-output exemptions. |
|
|
259
|
+
| `--max-session-turns` | `model.maxSessionTurns` | Number of user/model/tool turns; pre-existing. Exits with code 53 on overrun (distinct from budget exit 55). |
|
|
260
|
+
|
|
261
|
+
#### Scope
|
|
262
|
+
|
|
263
|
+
- **`--max-tool-calls` counts top-level dispatches only.** When the model calls the `agent` tool, the dispatch counts as **1**; inner tool calls performed by the spawned subagent are **not** counted. A model that funnels work through subagents can do unbounded inner work under a small top-level budget. Combine with `--exclude-tools agent` if you need a tighter cap.
|
|
264
|
+
- **`structured_output` is exempt from `--max-tool-calls`.** Under `--json-schema`, the model's terminal `structured_output` call is the "I'm done" contract, not real work — it doesn't count against `--max-tool-calls` so a budget-edge completion isn't aborted as a false positive. The exemption is unconditional (including failed Ajv validations), so a model stuck in a malformed-output retry loop is NOT bounded by `--max-tool-calls`; combine with `--max-session-turns` or `--max-wall-time` to cap retries.
|
|
265
|
+
- **`structured_output` is NOT exempt from `--max-session-turns`.** That counter is pre-existing and bumps for every turn including the terminal contract. Size `--max-session-turns` to `N+1` if you want to allow `N` real-work turns under `--json-schema`.
|
|
266
|
+
- **Single-shot vs `--input-format stream-json`:** in stream-json input mode the daemon resets the budget counters at the start of every user message; the budget is per-message, not per-process.
|
|
267
|
+
- **`qwen serve` / ACP sessions:** the daemon ACP session path does NOT currently consult `--max-wall-time` / `--max-tool-calls` from settings.json. These budgets only apply to single-shot `qwen -p` runs and to `--input-format stream-json` sessions. (`qwen serve` does emit the YOLO-no-sandbox warning at boot if `tools.approvalMode: 'yolo'` is set in settings.)
|
|
268
|
+
|
|
269
|
+
### Recommended combinations
|
|
270
|
+
|
|
271
|
+
- **Trusted, isolated environment (ephemeral CI runner, container):** `qwen -p "..." --yolo --max-session-turns N --max-wall-time 10m --output-format json`. Pin a turn budget and a wall-clock budget so a stuck agent can't burn through your CI minutes, and capture `--output-format json` for post-run usage / tool-call auditing.
|
|
272
|
+
- **Local machine or shared infra:** also pass `--sandbox` (or set `QWEN_SANDBOX=1`) so shell / write / edit tools run inside the sandbox image.
|
|
273
|
+
- **Long-running CI with retry-on-rate-limit:** combine `QWEN_CODE_UNATTENDED_RETRY=1` with `--max-wall-time`. The retry env keeps the run alive past transient 429 / 529 responses; the wall-clock budget ensures a persistently-failing provider can't extend the job indefinitely.
|
|
274
|
+
- **Bounded auditing / exploration:** for read-only tasks, `--max-tool-calls 25` caps how aggressively the model can grep / read. Combine with `--exclude-tools shell,write,edit` to make the bound meaningful.
|
|
275
|
+
|
|
244
276
|
## Examples
|
|
245
277
|
|
|
246
278
|
### Code review
|
|
@@ -24,15 +24,32 @@ Don't include things Qwen can figure out by reading your code. QWEN.md works bes
|
|
|
24
24
|
|
|
25
25
|
### Where to create QWEN.md
|
|
26
26
|
|
|
27
|
-
| File | Who it applies to
|
|
28
|
-
| ----------------------------- |
|
|
29
|
-
| `~/.qwen/QWEN.md` | You, across all your projects
|
|
30
|
-
| `QWEN.md` in the project root | Your whole team (commit it to source control)
|
|
27
|
+
| File | Who it applies to |
|
|
28
|
+
| ----------------------------- | ------------------------------------------------ |
|
|
29
|
+
| `~/.qwen/QWEN.md` | You, across all your projects |
|
|
30
|
+
| `QWEN.md` in the project root | Your whole team (commit it to source control) |
|
|
31
|
+
| `.qwen/QWEN.local.md` | Only you, only in this project (keep out of git) |
|
|
31
32
|
|
|
32
|
-
You can have
|
|
33
|
+
You can have any combination of these. Qwen loads all of them when you start a session.
|
|
33
34
|
|
|
34
35
|
If your repository already has an `AGENTS.md` file for other AI tools, Qwen reads that too. No need to duplicate instructions.
|
|
35
36
|
|
|
37
|
+
#### When to use `.qwen/QWEN.local.md`
|
|
38
|
+
|
|
39
|
+
Use it for **project-specific but personal** instructions — things that belong to this project but shouldn't be shared with the team:
|
|
40
|
+
|
|
41
|
+
- Your own cluster ID, container registry namespace, or cloud account
|
|
42
|
+
- A personal debug command that hardcodes your local environment
|
|
43
|
+
- Notes you want Qwen to know about your work-in-progress, but not commit
|
|
44
|
+
|
|
45
|
+
It loads **after** the shared project `QWEN.md`, so your local instructions can supplement or override the team's.
|
|
46
|
+
|
|
47
|
+
**You must gitignore it yourself.** Although `.qwen/` is often treated as a local directory, qwen-code does not generate a `.gitignore` for you, and some projects commit `.qwen/settings.json`. Add this line to your `.gitignore` (or to your global git ignore):
|
|
48
|
+
|
|
49
|
+
```
|
|
50
|
+
.qwen/QWEN.local.md
|
|
51
|
+
```
|
|
52
|
+
|
|
36
53
|
### Generate one automatically with `/init`
|
|
37
54
|
|
|
38
55
|
Run `/init` and Qwen will analyze your codebase to create a starter QWEN.md with build commands, test instructions, and conventions it finds. If one already exists, it suggests additions instead of overwriting.
|
|
@@ -0,0 +1,345 @@
|
|
|
1
|
+
# Worktrees
|
|
2
|
+
|
|
3
|
+
> Isolate experimental work in a temporary [git worktree](https://git-scm.com/docs/git-worktree) without leaving your current session. Useful when the model is about to make wide-ranging edits you want to keep separate from your main checkout, or when you want a subagent to work in a sandbox of its own.
|
|
4
|
+
|
|
5
|
+
## Quick Start
|
|
6
|
+
|
|
7
|
+
### Start the session inside a worktree (`--worktree` flag)
|
|
8
|
+
|
|
9
|
+
If you know up front that the entire session should run inside a worktree, pass `--worktree` at launch:
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
# Auto-generated slug (e.g. tender-jemison-037f0a)
|
|
13
|
+
qwen --worktree
|
|
14
|
+
|
|
15
|
+
# Explicit name
|
|
16
|
+
qwen --worktree my-feature
|
|
17
|
+
|
|
18
|
+
# `=` form (recommended when also passing a positional prompt — see tip below)
|
|
19
|
+
qwen --worktree=my-feature
|
|
20
|
+
|
|
21
|
+
# PR reference — fetches refs/pull/<N>/head from `origin`
|
|
22
|
+
qwen --worktree=#4174
|
|
23
|
+
qwen --worktree https://github.com/QwenLM/qwen-code/pull/4174
|
|
24
|
+
|
|
25
|
+
# Continue a previous --worktree session — re-attaches to the existing dir
|
|
26
|
+
qwen --resume <session-id> --worktree=my-feature
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
> **Tip — bare `--worktree` followed by a positional prompt is ambiguous.** Because `--worktree` takes an optional value, `qwen --worktree "say hi"` makes yargs consume `"say hi"` as the slug (and reject it because of the space). Use one of:
|
|
30
|
+
>
|
|
31
|
+
> - `qwen --worktree=my-feature "say hi"` (always works — explicit slug via `=`)
|
|
32
|
+
> - `qwen "say hi" --worktree` (positional first, flag at the end → auto slug)
|
|
33
|
+
> - `qwen --worktree --approval-mode yolo "say hi"` (any flag between them anchors the bare form)
|
|
34
|
+
|
|
35
|
+
> **Tip — `qwen --resume --worktree foo` (no session ID) shows an empty picker on first use.** The picker scopes to the chosen worktree's session storage; sessions started outside that worktree are not listed. To resume a session that was started inside `foo`, use `qwen --resume <id> --worktree foo` directly — the CLI re-attaches to the existing `foo/` directory rather than re-creating it.
|
|
36
|
+
|
|
37
|
+
`process.cwd()` and the model's workspace are switched to the worktree before the first turn runs. Exit with `Ctrl+C` twice and the [Exit Dialog](#exit-dialog-ctrlc--ctrld) prompts to keep or remove the worktree.
|
|
38
|
+
|
|
39
|
+
The `--worktree` flag cannot be combined with `--acp`/`--experimental-acp` — for ACP hosts (like Zed), pass the worktree path as the `cwd` of the `loadSession`/`newSession` request instead.
|
|
40
|
+
|
|
41
|
+
### Or ask mid-session
|
|
42
|
+
|
|
43
|
+
Alternatively, ask Qwen Code in plain language to create a worktree from inside an existing session:
|
|
44
|
+
|
|
45
|
+
```text
|
|
46
|
+
> start a worktree called experiment-a
|
|
47
|
+
Worktree experiment-a created on branch worktree-experiment-a
|
|
48
|
+
.qwen/worktrees/experiment-a
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
From this point on, the model routes every file edit and shell command through `.qwen/worktrees/experiment-a/`. Your original working directory is untouched.
|
|
52
|
+
|
|
53
|
+
When you are done:
|
|
54
|
+
|
|
55
|
+
```text
|
|
56
|
+
> exit the worktree and remove it
|
|
57
|
+
Removed worktree experiment-a (branch worktree-experiment-a)
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
If you want to come back later, ask to exit with the worktree kept on disk instead:
|
|
61
|
+
|
|
62
|
+
```text
|
|
63
|
+
> exit the worktree but keep it
|
|
64
|
+
Kept worktree experiment-a at .qwen/worktrees/experiment-a
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## When Worktrees Are Used
|
|
68
|
+
|
|
69
|
+
Worktrees are activated in four independent paths:
|
|
70
|
+
|
|
71
|
+
| Trigger | What happens |
|
|
72
|
+
| ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
|
|
73
|
+
| You launch with `--worktree` | The CLI creates the worktree before any model turn runs and chdirs the session into it. PR forms (`#N`, full URL) fetch first. |
|
|
74
|
+
| You explicitly ask for a worktree mid-session | Model calls `enter_worktree`; subsequent file edits go inside it. |
|
|
75
|
+
| You explicitly ask to leave | Model calls `exit_worktree` with `keep` or `remove`. |
|
|
76
|
+
| Model spawns a sub-agent with isolation enabled | A throwaway worktree (`agent-<hex>`) is created automatically and cleaned up if the agent has no diffs. |
|
|
77
|
+
|
|
78
|
+
The two mid-session tools (`enter_worktree` / `exit_worktree`) are deliberately gated behind explicit phrasing — saying "fix this bug" or "create a branch" will **not** trigger them. You must say something like "use a worktree", "start a worktree", or "in a worktree". The `--worktree` CLI flag has no such guard; it always creates one when present.
|
|
79
|
+
|
|
80
|
+
## What Gets Created
|
|
81
|
+
|
|
82
|
+
Every Qwen-managed worktree is placed under your project's `.qwen` directory:
|
|
83
|
+
|
|
84
|
+
```
|
|
85
|
+
<repoRoot>/.qwen/worktrees/<slug>/ # Working directory
|
|
86
|
+
↳ branch worktree-<slug> # Created off your current branch
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
- **Slug** — letters, digits, dot, underscore, hyphen; max 64 chars. If you don't specify a name, an `<adjective>-<noun>-<6hex>` slug is auto-generated (e.g. `tender-jemison-037f0a`). PR references produce `pr-<N>`.
|
|
90
|
+
- **Branch** — always `worktree-<slug>`, branched from whichever branch you have checked out when you ask for the worktree (not necessarily the main working tree's `HEAD`). For PR worktrees the branch is `worktree-pr-<N>` and is based on `FETCH_HEAD` (the PR's tip on the GitHub side) rather than your local branch.
|
|
91
|
+
- **Hooks** — the worktree's `core.hooksPath` is automatically pointed at the main repo's `.husky/` (preferred) or `.git/hooks/` so commits inside the worktree still trigger your existing pre-commit / commit-msg hooks.
|
|
92
|
+
- **Optional symlinks** — directories listed in `worktree.symlinkDirectories` (see [Settings](#settings)) are symlinked from the main repo into the new worktree so heavy dirs like `node_modules` can be reused without reinstalling.
|
|
93
|
+
|
|
94
|
+
The general-purpose worktree path is **not configurable** — it must live under `<repoRoot>/.qwen/worktrees/` so the CLI can find it on restart and on stale-cleanup sweeps. (The unrelated `agents.arena.worktreeBaseDir` setting controls only [Agent Arena](./arena.md) worktrees, which use a separate path tree under `~/.qwen/arena/`.)
|
|
95
|
+
|
|
96
|
+
## Footer and Status Line
|
|
97
|
+
|
|
98
|
+
When a worktree is active, the Footer shows a dim indicator on its own row:
|
|
99
|
+
|
|
100
|
+
```
|
|
101
|
+
⎇ worktree-experiment-a (experiment-a)
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
If you use a [custom status line script](./status-line.md), it also receives a `worktree` object in the JSON payload piped to stdin:
|
|
105
|
+
|
|
106
|
+
```json
|
|
107
|
+
{
|
|
108
|
+
"worktree": {
|
|
109
|
+
"name": "experiment-a",
|
|
110
|
+
"path": "/path/to/repo/.qwen/worktrees/experiment-a",
|
|
111
|
+
"branch": "worktree-experiment-a",
|
|
112
|
+
"original_cwd": "/path/to/repo",
|
|
113
|
+
"original_branch": "main"
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
The payload field is present **only** when a worktree is active, so a `null`-check (`input.worktree?.name`) is enough.
|
|
119
|
+
|
|
120
|
+
If your custom status line already renders worktree info, you can hide the built-in Footer row to avoid duplication — see [Settings](#settings) below.
|
|
121
|
+
|
|
122
|
+
## Exit Dialog (Ctrl+C / Ctrl+D)
|
|
123
|
+
|
|
124
|
+
Pressing the quit shortcut twice while a worktree is active opens the **Worktree Exit Dialog** instead of closing the CLI:
|
|
125
|
+
|
|
126
|
+
```
|
|
127
|
+
⎇ Active worktree: "experiment-a" (worktree-experiment-a)
|
|
128
|
+
|
|
129
|
+
• 2 new commit(s) on worktree-experiment-a
|
|
130
|
+
• 3 uncommitted file(s)
|
|
131
|
+
Removing the worktree will discard everything above.
|
|
132
|
+
|
|
133
|
+
What would you like to do?
|
|
134
|
+
○ Keep worktree (exit without deleting)
|
|
135
|
+
○ Remove worktree and branch (discards 2 commit(s), 3 file(s))
|
|
136
|
+
○ Cancel (stay in session)
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
The dialog inspects the worktree on open (`git status --porcelain` + `git rev-list <baseHEAD>..HEAD`) and surfaces both counts so you know exactly what you'd be discarding. `ESC` cancels.
|
|
140
|
+
|
|
141
|
+
If `git status` itself fails (e.g. corrupt index, worktree directory was removed under the CLI), the dialog shows a `⚠ Could not measure worktree state` warning and the counts may be unreliable — choose **Keep** or **Cancel** until you've diagnosed the underlying repo problem.
|
|
142
|
+
|
|
143
|
+
## `--resume` Restore
|
|
144
|
+
|
|
145
|
+
The active worktree binding is persisted to a sidecar file alongside your session transcript:
|
|
146
|
+
|
|
147
|
+
```
|
|
148
|
+
<chatsDir>/<sessionId>.worktree.json
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
When you launch the CLI with `--resume <sessionId>` (or pick the session from `/resume`), three things happen consistently across **interactive TUI**, **headless `-p`**, and **ACP/Zed** modes:
|
|
152
|
+
|
|
153
|
+
1. The sidecar is loaded and the worktree directory is verified to still exist on disk.
|
|
154
|
+
2. If alive, the model receives a one-shot reminder on its very next prompt:
|
|
155
|
+
```
|
|
156
|
+
[Resumed] Active worktree: "<slug>" at <path> (branch: <branch>). Continue using this path for all file operations.
|
|
157
|
+
```
|
|
158
|
+
3. If the worktree directory was deleted between sessions, the stale sidecar is cleaned up automatically — no error, the resume just continues without worktree context.
|
|
159
|
+
|
|
160
|
+
Each mode chooses its own injection mechanism, but the user-visible behavior is identical:
|
|
161
|
+
|
|
162
|
+
| Mode | Mechanism |
|
|
163
|
+
| ----------------- | ------------------------------------------------------------------------------------------------------ |
|
|
164
|
+
| Interactive (TUI) | `INFO` history item + system-reminder prefix on the next user prompt. |
|
|
165
|
+
| Headless (`-p`) | `<system-reminder>` prefix on the prompt + `worktree_restored` JSON system event in the output stream. |
|
|
166
|
+
| ACP (e.g. Zed) | Pending notice attached to the next `prompt()` call. |
|
|
167
|
+
|
|
168
|
+
The model is **not** automatically `chdir`'d into the worktree — the reminder is what keeps it routing edits through the worktree path.
|
|
169
|
+
|
|
170
|
+
## Sub-Agent Isolation
|
|
171
|
+
|
|
172
|
+
The `agent` tool accepts an optional `isolation: "worktree"` parameter. When set, Qwen Code creates an ephemeral worktree at `<repoRoot>/.qwen/worktrees/agent-<7hex>/` before the sub-agent starts, and:
|
|
173
|
+
|
|
174
|
+
- **No changes** → the worktree is automatically removed when the agent finishes.
|
|
175
|
+
- **Has changes** → the worktree is preserved; its path and branch are appended to the agent's result, e.g.
|
|
176
|
+
```
|
|
177
|
+
…agent output…
|
|
178
|
+
[worktree preserved: /path/to/.qwen/worktrees/agent-3f2a1b9 (branch worktree-agent-3f2a1b9)]
|
|
179
|
+
```
|
|
180
|
+
Review the diff and merge or delete it manually.
|
|
181
|
+
|
|
182
|
+
Two constraints:
|
|
183
|
+
|
|
184
|
+
- `isolation: "worktree"` requires a `subagent_type` — forked sub-agents (no `subagent_type`) reuse the parent's full conversation context, so isolating them would split intent from working tree.
|
|
185
|
+
- Background agents (`run_in_background: true`) work fine with isolation; the cleanup runs when the agent reports completion.
|
|
186
|
+
|
|
187
|
+
### Automatic Stale Cleanup
|
|
188
|
+
|
|
189
|
+
Ephemeral agent worktrees that survived a crash or `--no-cleanup` shutdown are reaped on every CLI startup, with conservative fail-closed rules:
|
|
190
|
+
|
|
191
|
+
| Guard | Behavior |
|
|
192
|
+
| -------------------------------------- | ---------------------------------------------- |
|
|
193
|
+
| Slug must match `agent-<7hex>` pattern | Named worktrees you created are never touched. |
|
|
194
|
+
| Directory `mtime` > 30 days | Newer entries are skipped. |
|
|
195
|
+
| Any uncommitted tracked change | Skip the entry (don't delete). |
|
|
196
|
+
| Any commit not reachable from a remote | Skip the entry (don't delete). |
|
|
197
|
+
| Any error reading git state | Skip the entry (don't delete). |
|
|
198
|
+
|
|
199
|
+
Named user worktrees (`enter_worktree` slugs) are **never** auto-cleaned — you keep them around until you ask to remove them.
|
|
200
|
+
|
|
201
|
+
## Safety Guards on `exit_worktree action="remove"`
|
|
202
|
+
|
|
203
|
+
Three independent guards trigger before the directory and branch are deleted:
|
|
204
|
+
|
|
205
|
+
1. **Session ownership** — each worktree carries a sidecar marker with the session ID that created it. A different session trying to remove it is refused with a clear error pointing at `git worktree remove` for the manual escape hatch.
|
|
206
|
+
2. **Dirty working tree** — uncommitted tracked or untracked changes block removal. Pass `discard_changes: true` to override. (Bypass requires explicit user confirmation — `action: "remove"` is never auto-approved in AUTO_EDIT mode.)
|
|
207
|
+
3. **Unmerged commits** — commits on `worktree-<slug>` that no other local branch or remote ref points at block removal unconditionally; there is no "discard commits" flag because losing committed work is rarely what users mean. Merge, push, or rename the branch elsewhere first.
|
|
208
|
+
|
|
209
|
+
The same three guards apply to the `WorktreeExitDialog → Remove` button.
|
|
210
|
+
|
|
211
|
+
## Settings
|
|
212
|
+
|
|
213
|
+
Two settings shape the general-purpose worktree experience:
|
|
214
|
+
|
|
215
|
+
| Key | Type | Default | Effect |
|
|
216
|
+
| --------------------------------- | ---------- | ----------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
217
|
+
| `ui.hideBuiltinWorktreeIndicator` | boolean | `false` | Hides the built-in `⎇ worktree-… (…)` Footer row. The `worktree` field is still delivered to custom status line scripts. Set to `true` only if your status line already renders the worktree — otherwise you lose all UI affordance. |
|
|
218
|
+
| `worktree.symlinkDirectories` | `string[]` | `undefined` | Directories under the main repo to symlink into every general-purpose worktree on creation. Paths are relative to the repo root; absolute paths and any entry containing `..` are rejected. Missing sources and existing destinations are silently skipped (no overwrite). |
|
|
219
|
+
|
|
220
|
+
Example:
|
|
221
|
+
|
|
222
|
+
```jsonc
|
|
223
|
+
// ~/.qwen/settings.json or <repo>/.qwen/settings.json
|
|
224
|
+
{
|
|
225
|
+
"worktree": {
|
|
226
|
+
"symlinkDirectories": ["node_modules", ".turbo", "dist"],
|
|
227
|
+
},
|
|
228
|
+
}
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
Applies to ALL worktree-creation paths: `--worktree` flag, `enter_worktree` tool, and `agent isolation: "worktree"`.
|
|
232
|
+
|
|
233
|
+
Settings unrelated to general worktrees but worth knowing about:
|
|
234
|
+
|
|
235
|
+
- `agents.arena.worktreeBaseDir` — controls **Agent Arena** worktree placement (default `~/.qwen/arena`). Does not affect general-purpose worktrees, which always live under `<repoRoot>/.qwen/worktrees/`.
|
|
236
|
+
|
|
237
|
+
There is no schema for `worktree.sparsePaths` yet — that's a roadmap item (see [Limitations](#limitations)).
|
|
238
|
+
|
|
239
|
+
## Tool Reference
|
|
240
|
+
|
|
241
|
+
### `enter_worktree`
|
|
242
|
+
|
|
243
|
+
```json
|
|
244
|
+
{ "name": "experiment-a" }
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
| Field | Type | Required | Notes |
|
|
248
|
+
| ------ | ------ | -------- | ------------------------------------------------------------------------------------------ |
|
|
249
|
+
| `name` | string | no | Slug. Letters, digits, dot, underscore, hyphen; max 64 chars. Auto-generated when omitted. |
|
|
250
|
+
|
|
251
|
+
Refuses to run when:
|
|
252
|
+
|
|
253
|
+
- The CLI is not in a git repository.
|
|
254
|
+
- The current working directory is already inside `.qwen/worktrees/` (no nested worktrees).
|
|
255
|
+
|
|
256
|
+
### `exit_worktree`
|
|
257
|
+
|
|
258
|
+
```json
|
|
259
|
+
{ "name": "experiment-a", "action": "remove", "discard_changes": false }
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
| Field | Type | Required | Notes |
|
|
263
|
+
| ----------------- | ---------------------- | ------------------------------------- | ------------------------------------------------------------------ |
|
|
264
|
+
| `name` | string | yes | Must match the slug used in `enter_worktree`. |
|
|
265
|
+
| `action` | `"keep"` \| `"remove"` | yes | `keep` preserves dir + branch; `remove` deletes both. |
|
|
266
|
+
| `discard_changes` | boolean | only when `action="remove"` and dirty | Overrides the dirty-tree guard. Has no effect for `action="keep"`. |
|
|
267
|
+
|
|
268
|
+
`action: "remove"` always prompts for confirmation, including under `AUTO_EDIT` approval mode — it is treated as a destructive shell operation, not an info-only tool.
|
|
269
|
+
|
|
270
|
+
### `agent` — `isolation` parameter
|
|
271
|
+
|
|
272
|
+
```json
|
|
273
|
+
{
|
|
274
|
+
"subagent_type": "my-agent",
|
|
275
|
+
"description": "…",
|
|
276
|
+
"prompt": "…",
|
|
277
|
+
"isolation": "worktree"
|
|
278
|
+
}
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
| Field | Type | Required | Notes |
|
|
282
|
+
| ----------- | ------------ | -------- | ------------------------------------------------------------------------------------------------- |
|
|
283
|
+
| `isolation` | `"worktree"` | no | Runs the agent in a fresh `agent-<7hex>` worktree. Requires `subagent_type` to be set (no forks). |
|
|
284
|
+
|
|
285
|
+
See [Sub-Agents](./sub-agents.md) for the rest of the agent tool reference.
|
|
286
|
+
|
|
287
|
+
## CLI Reference
|
|
288
|
+
|
|
289
|
+
### `--worktree [name | #N | url]`
|
|
290
|
+
|
|
291
|
+
```bash
|
|
292
|
+
qwen --worktree # auto-generate slug
|
|
293
|
+
qwen --worktree my-feature # explicit slug
|
|
294
|
+
qwen --worktree=my-feature # = form
|
|
295
|
+
qwen --worktree=#123 # PR reference
|
|
296
|
+
qwen --worktree https://github.com/owner/repo/pull/123 # PR URL
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
| Input | Result |
|
|
300
|
+
| ----------------------------- | --------------------------------------------------------------------------------------------------------------------- |
|
|
301
|
+
| Bare flag (no value) | Auto slug `<adjective>-<noun>-<6hex>`, branch `worktree-<slug>`, base = current branch. |
|
|
302
|
+
| Plain slug | Branch `worktree-<slug>`, base = current branch. Slug validation: letters/digits/dot/underscore/hyphen, max 64 chars. |
|
|
303
|
+
| `#N` or `<github-url>/pull/N` | Slug `pr-<N>`, branch `worktree-pr-<N>`, base = `FETCH_HEAD` after `git fetch origin pull/<N>/head` (30s timeout). |
|
|
304
|
+
|
|
305
|
+
`--worktree` cannot be combined with `--acp` / `--experimental-acp`.
|
|
306
|
+
|
|
307
|
+
When `--worktree` is combined with `--resume <session-id>`, the worktree wins: the resumed session's saved worktree (if any) is overridden and a stderr line + first-prompt reminder report the override.
|
|
308
|
+
|
|
309
|
+
For interactive (TUI) and headless (`-p`) modes the worktree is automatically created and the session chdirs into it before the first turn.
|
|
310
|
+
|
|
311
|
+
PR-fetch failure modes (exit code != 0, no worktree created):
|
|
312
|
+
|
|
313
|
+
| Cause | Message excerpt |
|
|
314
|
+
| ----------------------------- | ---------------------------------------------------------- |
|
|
315
|
+
| Missing `origin` remote | `requires an "origin" remote that points at GitHub` |
|
|
316
|
+
| PR doesn't exist on origin | `Failed to fetch PR #<N>: the PR does not exist on origin` |
|
|
317
|
+
| 30s network timeout | `Failed to fetch PR #<N>: timed out after 30s` |
|
|
318
|
+
| PR number out of range / zero | `Invalid PR number` |
|
|
319
|
+
|
|
320
|
+
## Limitations
|
|
321
|
+
|
|
322
|
+
The following items are intentionally not implemented in the current phase:
|
|
323
|
+
|
|
324
|
+
- **No sparse checkout.** Large monorepos check out the full tree. (`worktree.sparsePaths` is a roadmap item.)
|
|
325
|
+
- **No tmux integration.** The CLI does not spawn worktree sessions in new tmux windows.
|
|
326
|
+
- **Worktrees are separate "projects" for session storage.** Sessions started with `--worktree foo` are saved under that worktree's chats dir; to resume them later you must pass `--worktree foo` again. Sessions started without `--worktree` are saved under the main checkout and won't appear in the worktree's resume picker.
|
|
327
|
+
- **No cross-slug session override.** `qwen --resume <sid> --worktree second` where `<sid>` was created with `--worktree first` will fail to find the session — sessions and worktrees are tightly bound by `projectHash(cwd)`. To switch worktrees on an existing session you must exit, then re-launch with the new `--worktree` and a fresh prompt. A future architectural change (anchoring storage at the repo root instead of `cwd`) would lift this constraint.
|
|
328
|
+
- **Mid-session `enter_worktree` does NOT switch `process.cwd()` or `Config.targetDir`.** That tool uses the model-context-only convention (see [Sub-Agents](./sub-agents.md)). Only the startup `--worktree` flag actually switches the process working directory.
|
|
329
|
+
- **Relative paths in other arg fields are resolved BEFORE the worktree chdir.** Path-taking flags (`--mcp-config`, `--openai-logging-dir`, `--json-file`, `--input-file`, `--telemetry-outfile`, `--include-directories`) are normalized to absolute paths against the launch cwd when `--worktree` is set. Other path-shaped argv fields not in this list still resolve against the worktree cwd — use absolute paths to be safe.
|
|
330
|
+
|
|
331
|
+
Track the roadmap in `docs/design/worktree.md`.
|
|
332
|
+
|
|
333
|
+
## Troubleshooting
|
|
334
|
+
|
|
335
|
+
**The Footer shows no worktree indicator even though I just created one.**
|
|
336
|
+
Check that `ui.hideBuiltinWorktreeIndicator` is not set to `true`. Also confirm the slug is non-empty in the tool's success message.
|
|
337
|
+
|
|
338
|
+
**`--resume` does not restore my worktree.**
|
|
339
|
+
Check `<chatsDir>/<sessionId>.worktree.json` exists. The CLI deletes the sidecar automatically when the worktree directory is gone, so a missing sidecar plus a missing directory is the normal "no worktree to restore" state — not a bug. Run with `--debug` and grep for `restoreWorktreeContext` to see the reason.
|
|
340
|
+
|
|
341
|
+
**`exit_worktree` says "created by a different session".**
|
|
342
|
+
This is the session-ownership guard. Resume the original session and exit from there, or run the suggested `git worktree remove …` command manually.
|
|
343
|
+
|
|
344
|
+
**Stale `agent-<hex>` worktrees keep piling up.**
|
|
345
|
+
The 30-day cutoff is conservative; sweep manually with `git worktree list && git worktree remove <path>`, or wait — the next CLI startup after the 30-day mark will reap them as long as they are clean and pushed.
|
|
@@ -7,30 +7,30 @@ import {
|
|
|
7
7
|
hasRebuiltToolRegistry,
|
|
8
8
|
rebuildToolRegistryOnOverride,
|
|
9
9
|
resolveSubagentApprovalMode
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-7HM6OB7M.js";
|
|
11
11
|
import "./chunk-K5PGHDBN.js";
|
|
12
12
|
import "./chunk-O4PICXES.js";
|
|
13
13
|
import "./chunk-TW522KN6.js";
|
|
14
14
|
import "./chunk-MLZQVCF3.js";
|
|
15
|
-
import "./chunk-
|
|
16
|
-
import "./chunk-
|
|
17
|
-
import "./chunk-
|
|
15
|
+
import "./chunk-C27V5A2J.js";
|
|
16
|
+
import "./chunk-EY6BDW7Y.js";
|
|
17
|
+
import "./chunk-K72FHBFO.js";
|
|
18
18
|
import "./chunk-77WXWU44.js";
|
|
19
|
-
import "./chunk-
|
|
20
|
-
import "./chunk-
|
|
21
|
-
import "./chunk-
|
|
19
|
+
import "./chunk-GVWPJCXU.js";
|
|
20
|
+
import "./chunk-JVD46YJV.js";
|
|
21
|
+
import "./chunk-4YNZFYJY.js";
|
|
22
22
|
import "./chunk-UWCTAVOD.js";
|
|
23
23
|
import "./chunk-OFEVLU4C.js";
|
|
24
|
-
import "./chunk-
|
|
25
|
-
import "./chunk-
|
|
26
|
-
import "./chunk-
|
|
24
|
+
import "./chunk-NQ3E7YLD.js";
|
|
25
|
+
import "./chunk-6NUSWV4M.js";
|
|
26
|
+
import "./chunk-ODPVJ6JJ.js";
|
|
27
27
|
import "./chunk-T4VD6OJ4.js";
|
|
28
28
|
import "./chunk-RDYWTWEM.js";
|
|
29
|
-
import "./chunk-
|
|
30
|
-
import "./chunk-
|
|
31
|
-
import "./chunk-
|
|
32
|
-
import "./chunk-
|
|
33
|
-
import "./chunk-
|
|
29
|
+
import "./chunk-FO7BIVSR.js";
|
|
30
|
+
import "./chunk-YMDXEEOW.js";
|
|
31
|
+
import "./chunk-7YJIR2FX.js";
|
|
32
|
+
import "./chunk-OIL7KDWV.js";
|
|
33
|
+
import "./chunk-ACBGEKB7.js";
|
|
34
34
|
import "./chunk-E7E2MFYM.js";
|
|
35
35
|
import "./chunk-ZERZSAZL.js";
|
|
36
36
|
import "./chunk-QN5NZ3UQ.js";
|
package/chunks/{anthropicContentGenerator-RQJNXJIY.js → anthropicContentGenerator-LYI3OHBB.js}
RENAMED
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
} from "./chunk-KQIKOTQJ.js";
|
|
7
7
|
import {
|
|
8
8
|
RequestTokenizer
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-VMOWXTRC.js";
|
|
10
10
|
import {
|
|
11
11
|
Blob,
|
|
12
12
|
File,
|
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
import {
|
|
17
17
|
buildRuntimeFetchOptions,
|
|
18
18
|
redactProxyError
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-JVD46YJV.js";
|
|
20
20
|
import {
|
|
21
21
|
CAPPED_DEFAULT_MAX_TOKENS,
|
|
22
22
|
DEFAULT_TIMEOUT,
|
|
@@ -25,7 +25,7 @@ import {
|
|
|
25
25
|
runtimeDiagnostics,
|
|
26
26
|
safeJsonParse,
|
|
27
27
|
tokenLimit
|
|
28
|
-
} from "./chunk-
|
|
28
|
+
} from "./chunk-6NUSWV4M.js";
|
|
29
29
|
import {
|
|
30
30
|
FinishReason,
|
|
31
31
|
GenerateContentResponse
|
|
@@ -33,7 +33,7 @@ import {
|
|
|
33
33
|
import "./chunk-RDYWTWEM.js";
|
|
34
34
|
import {
|
|
35
35
|
createDebugLogger
|
|
36
|
-
} from "./chunk-
|
|
36
|
+
} from "./chunk-ACBGEKB7.js";
|
|
37
37
|
import "./chunk-E7E2MFYM.js";
|
|
38
38
|
import {
|
|
39
39
|
require_ms
|
|
@@ -6,10 +6,10 @@ import {
|
|
|
6
6
|
BaseToolInvocation,
|
|
7
7
|
ToolDisplayNames,
|
|
8
8
|
ToolNames
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-YMDXEEOW.js";
|
|
10
10
|
import {
|
|
11
11
|
createDebugLogger
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-ACBGEKB7.js";
|
|
13
13
|
import "./chunk-QWSRH265.js";
|
|
14
14
|
import {
|
|
15
15
|
init_esbuild_shims
|