mirror of
https://github.com/codewhale-hq/Codewhale.git
synced 2026-11-08 17:10:50 -10:00
fix: complete 0.10.2 terminal and release blockers
Match undo snapshots conservatively for long, multiline and trimmed prompts; keep terminal outcomes attached to the unchanged conversation prefix through rewinds, replacement and branching. Document exec Full Access, reject misplaced flags, honor stricter sandboxes, and report actual enforcement. Save tool-enabled exec sessions in every format with terminal failures and separate retention. Restore local-runtime onboarding and update complete locale packs and docs. Serialize RC test-binary builds to avoid the reproduced linker OOM. Replace both Chocolatey NSIS consumers with a checksum-pinned official installer and verified compiler version. Put the release summary first, retain detailed notes and contributor credits, and set an explicit release title. Validation on frozen 849af501cf plus this diff: workspace check and CI-flag Clippy passed; formatting passed; focused TUI 683 passed, 0 failed, 1 ignored; CLI 541 passed, 0 failed; feature registry 2 passed; localization 54 passed. The registry ran with the empty default feature disabled; an earlier redundant build was intentionally interrupted before tests. Source hashes stayed fixed. After excluding the held change and folding the pending changelog into 0.10.2 dated 2026-10-19, regenerated web data and ran the literal gate: npm test && npm run check:web passed. Wrapper 101, runtime SDK 19, extension host 413 passed/7 skipped, web 772 passed, dependency security 7 passed; all failure counts zero. Source hashes remained unchanged. The earlier stale-catalog failure was repaired before this final gate. README translations (18), locale coverage (16), release-body tests, dated version/changelog contracts and OHOS dependency guard passed. Final release body rendering preserves all notes and credits outside the held entry. Workflow syntax passed; full ShellCheck retained the same 12 pre-existing warnings. Independent reviews found no remaining concrete issue in scope. Held session-only key commit 849af501cf is excluded before pushing. The final candidate still needs exact-SHA hosted CI, RC artifacts and binary walkthrough; local checks do not qualify Windows provisioning, deployment or publication. Co-Authored-By: Claude Opus 5.5 <[email protected]> Co-Authored-By: Codex <[email protected]>
This commit is contained in:
1 parent
850f510b49
commit
ac5b611fe0
80 files changed
+1088
-416
No files matched your search
@@ -828,39 +828,7 @@ jobs:
|
||||
- name: Install NSIS for Windows installer regression
|
||||
if: needs.changes.outputs.heavy == 'true' && matrix.os == 'windows-latest'
|
||||
shell: pwsh
|
||||
# Bounded retry, not a weaker check (#5403). Every observed failure here
|
||||
# was Chocolatey's feed, not the code: a 504 from the V2 API, and
|
||||
# "package was not found with the source(s) listed". A single attempt
|
||||
# made `Test (windows-latest)` — a required check on every PR — report
|
||||
# on community.chocolatey.org's availability instead of on the tree.
|
||||
# NSIS must still install for the regression below to run; this only
|
||||
# survives a transient outage.
|
||||
#
|
||||
# A feed failure also makes `choco install` exit 0 without installing
|
||||
# anything ("Chocolatey installed 0/0 packages" after a V2 feed 504),
|
||||
# so an attempt only counts when `makensis.exe` exists where the installer
|
||||
# regression looks for it (Program Files; choco does not put it on PATH).
|
||||
# Without that check the retry reported success on an unprovisioned
|
||||
# runner and the regression below failed as an unattributable exit
|
||||
# code instead of this step naming the outage (2026-09-24).
|
||||
run: |
|
||||
$ErrorActionPreference = 'Continue'
|
||||
$delays = @(0, 20, 45)
|
||||
for ($attempt = 0; $attempt -lt $delays.Count; $attempt++) {
|
||||
if ($delays[$attempt] -gt 0) {
|
||||
Write-Host "NSIS install attempt $($attempt + 1) after $($delays[$attempt])s backoff"
|
||||
Start-Sleep -Seconds $delays[$attempt]
|
||||
}
|
||||
choco install nsis -y --no-progress
|
||||
$makensis = @("${env:ProgramFiles(x86)}\NSIS\makensis.exe", "$env:ProgramFiles\NSIS\makensis.exe") | Where-Object { Test-Path $_ } | Select-Object -First 1
|
||||
if ($LASTEXITCODE -eq 0 -and $makensis) {
|
||||
Write-Host "NSIS installed on attempt $($attempt + 1)"
|
||||
exit 0
|
||||
}
|
||||
Write-Host "::warning::NSIS is still unavailable after attempt $($attempt + 1) (choco exit $LASTEXITCODE)"
|
||||
}
|
||||
Write-Host "::error::NSIS could not be provisioned from Chocolatey after $($delays.Count) attempts"
|
||||
exit 1
|
||||
run: ./scripts/installer/install-nsis.ps1
|
||||
- name: Test Windows installer PATH regression
|
||||
if: needs.changes.outputs.heavy == 'true' && matrix.os == 'windows-latest'
|
||||
shell: pwsh
|
||||
|
||||
@@ -439,7 +439,7 @@ jobs:
|
||||
pattern: '*windows-x64*'
|
||||
- name: Install NSIS
|
||||
shell: pwsh
|
||||
run: choco install nsis -y --no-progress
|
||||
run: ./scripts/installer/install-nsis.ps1
|
||||
- name: Build NSIS installer
|
||||
shell: pwsh
|
||||
run: |
|
||||
|
||||
@@ -115,6 +115,7 @@ jobs:
|
||||
kill "$monitor" 2>/dev/null || true
|
||||
exit "$status"
|
||||
env:
|
||||
CARGO_BUILD_JOBS: '1'
|
||||
# Match the CI test lane: test threads get the same stack the product
|
||||
# gives itself (main.rs CODEWHALE_MAIN_STACK_BYTES). See the note in
|
||||
# ci.yml's "Run tests" step. Without it this gate runs the deep
|
||||
|
||||
@@ -428,6 +428,7 @@ jobs:
|
||||
- uses: softprops/action-gh-release@efb35369e0ad2afab669f228072c1b0d510eae64 # v3
|
||||
with:
|
||||
tag_name: ${{ needs.resolve.outputs.tag }}
|
||||
name: Codewhale ${{ needs.resolve.outputs.tag }}
|
||||
files: artifacts/*
|
||||
draft: true
|
||||
prerelease: false
|
||||
|
||||
+40
-16
@@ -7,6 +7,46 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
## [0.10.2] - 2026-10-19
|
||||
|
||||
Codewhale v0.10.2 adds an animated pet view (`/pet on`), a live Terminal work
|
||||
dock and per-chat composer colors (`/color`). It closes three session
|
||||
data-loss paths, a sandbox escape through the Runtime daemon socket and a
|
||||
`codewhale web` session leak; holds a `curl` or `wget` that uploads a
|
||||
credential; refuses shell commands containing invisible Unicode; keeps the
|
||||
Linux sandbox working when a hidden credential directory is a symlink; and
|
||||
uses much less CPU while the TUI waits on you. `/undo` takes back a whole
|
||||
request, including long and multiline prompts. `exec --auto` explains its
|
||||
Full Access default, honors an explicitly stricter sandbox, and saves
|
||||
tool-enabled runs and their failure receipts. Local runtimes appear during
|
||||
onboarding, `/diff` works outside a Git repository, DeepSeek's Responses route
|
||||
no longer rejects replayed tool history, and contributor fixes improve token
|
||||
accounting, relay model lists, localized replies and Windows launcher
|
||||
guidance.
|
||||
|
||||
### Latest fixes
|
||||
|
||||
- `/undo` takes back the latest request and its file changes without requiring
|
||||
trust mode, while refusing ambiguous snapshot matches. Trailing whitespace
|
||||
in a prompt label no longer prevents a match, and an empty first line in
|
||||
another request no longer blocks the whole conversation.
|
||||
- `exec --auto` help and documentation now state its default Full Access:
|
||||
automatic tool approvals, no Codewhale shell sandbox, and trust mode on.
|
||||
Selecting any sandbox other than `danger-full-access`, by flag or config,
|
||||
keeps trust mode off. This includes `external-sandbox`, which relies on
|
||||
host-managed isolation and no longer grants file tools trust-mode access.
|
||||
Stream metadata reports whether the requested sandbox is actually enforced.
|
||||
- Exec flags go before the prompt. A known long flag or `--flag=value` after
|
||||
the prompt now produces an error instead of silently becoming prompt text;
|
||||
use `--` for literal flag text or a prompt starting with `-`.
|
||||
- Exec runs that offer tools save sessions in every output format. Exec and
|
||||
interactive sessions each keep their own retention allowance, so CI runs
|
||||
cannot archive interactive conversations. Live and saved receipts include
|
||||
retained terminal failures, and conversation rewinds discard outcomes from
|
||||
removed turns so they cannot be attributed to later requests.
|
||||
- Onboarding lists Ollama, LM Studio, and vLLM even before a local runtime is
|
||||
detected, so they can be selected and configured. The `L` filter is available
|
||||
during onboarding after local-runtime detection.
|
||||
- `/fork <id>` now shows the forked conversation. Before, the screen kept
|
||||
the previous conversation while the model already had the fork's history.
|
||||
- With `/translate` on, each translated thinking block lands in its own
|
||||
@@ -96,22 +136,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
rebinding) and drive the Runtime API from your browser; such requests now
|
||||
get `421 Misdirected Request`. Servers with auth are unchanged.
|
||||
|
||||
## [0.10.2] - 2026-10-18
|
||||
|
||||
Codewhale v0.10.2 adds an animated pet view (`/pet on`), a live Terminal work
|
||||
dock and per-chat composer colors (`/color`). It closes three session
|
||||
data-loss paths, a sandbox escape through the Runtime daemon socket and a
|
||||
`codewhale web` session leak; holds a `curl` or `wget` that uploads a
|
||||
credential; refuses shell commands containing invisible Unicode; keeps the
|
||||
Linux sandbox working when a hidden credential directory is a symlink; and
|
||||
uses much less CPU while the TUI waits on you. `/undo` takes back a whole
|
||||
request, `/diff` works outside a Git repository, DeepSeek's Responses route no
|
||||
longer rejects replayed tool history, and contributor fixes improve token
|
||||
accounting, relay model lists, localized replies and Windows launcher
|
||||
guidance.
|
||||
|
||||
### Latest fixes
|
||||
|
||||
- Sandboxed commands can no longer reach Codewhale's Runtime daemon socket.
|
||||
On Linux with bubblewrap, and on macOS with sandbox network access on, a
|
||||
command the agent ran (a test script or a postinstall hook, say) could read
|
||||
|
||||
+14
-6
@@ -1,4 +1,4 @@
|
||||
<!-- source: README.md sha256:eefdc9e645b6 -->
|
||||
<!-- source: README.md sha256:30c9b9765b04 -->
|
||||
<div align="center">
|
||||
|
||||
<picture>
|
||||
@@ -80,12 +80,14 @@ Fix the failing tests and explain what changed.
|
||||
يرفضه. ويُلغي `/undo` آخر طلب لك وتغييرات الملفات الناتجة عنه (في 0.10.1، شغّل
|
||||
`/trust on` أولًا). ويسرد `/help` الأوامر واختصارات لوحة المفاتيح.
|
||||
|
||||
في السكربتات وCI، يشغّل `codewhale exec` مهمة واحدة دون الواجهة. ومع `--auto`
|
||||
يعدّل الملفات ويشغّل أوامر الصدفة دون أن يسأل، لذا شغّله داخل حاوية أو في نسخة
|
||||
checkout يمكن التخلص منها:
|
||||
في السكربتات وCI، يشغّل `codewhale exec` مهمة واحدة دون الواجهة. افتراضيًا،
|
||||
يستخدم `--auto` وضع Full Access: تعمل الأدوات دون سؤال، وتعمل أوامر الصدفة دون
|
||||
صندوق حماية Codewhale، ويتيح وضع الثقة لأدوات الملفات الكتابة خارج مساحة العمل.
|
||||
أضف `--sandbox workspace-write` للإبقاء على صندوق حماية الصدفة وقيود مساحة العمل
|
||||
على أدوات الملفات، مع تعطيل وضع الثقة:
|
||||
|
||||
```bash
|
||||
codewhale exec --auto "fix the failing tests and explain what changed"
|
||||
codewhale exec --auto --sandbox workspace-write "fix the failing tests and explain what changed"
|
||||
```
|
||||
|
||||
## الأوضاع والأذونات
|
||||
@@ -146,6 +148,12 @@ OpenAI، وكذلك النماذج المحلية عبر Ollama أو vLLM أو S
|
||||
كلها إلى لقطة سابقة؛ ولأن ذلك يكتب فوق التعديلات اللاحقة، فإنه يتطلب `/trust on`
|
||||
أو Full Access. راجع [الإيصالات](docs/RECEIPTS.md).
|
||||
|
||||
تُحفظ عمليات تشغيل exec التي تتيح أدوات بكل صيغ الإخراج، لذا يعمل
|
||||
`codewhale receipts --last` بعد `exec --auto`، بما في ذلك مع `--json`.
|
||||
أما عمليات التشغيل التي تقتصر على الإجابة بإخراج نصي أو `--json` فلا تُحفظ إلا
|
||||
عند الاستئناف أو عند بدء ضغط المحادثة؛ استخدم `--output-format stream-json`
|
||||
لحفظها دائمًا من أجل الإيصالات أو `exec --continue`.
|
||||
|
||||
### الأعمال الأطول
|
||||
|
||||
يحدد `/goal` هدفًا يستمر عبر دورات المحادثة. ويستطيع Codewhale توزيع العمل على
|
||||
@@ -182,7 +190,7 @@ OpenAI، وكذلك النماذج المحلية عبر Ollama أو vLLM أو S
|
||||
| الأمر | ما يفعله |
|
||||
| --- | --- |
|
||||
| `codewhale` | تطبيق الطرفية التفاعلي |
|
||||
| `codewhale exec "…"` | مهمة واحدة دون الواجهة. دون خيارات إضافية يجيب دون استخدام الأدوات؛ ويسمح له `--auto` بتعديل الملفات وتشغيل الأوامر، ويبث `--output-format stream-json` الأحداث بصيغة JSON |
|
||||
| `codewhale exec "…"` | مهمة واحدة دون الواجهة. دون خيارات إضافية يجيب دون استخدام الأدوات؛ ويفعّل `--auto` الأدوات مع Full Access افتراضيًا، ويقيّدها `--sandbox workspace-write`، ويبث `--output-format stream-json` الأحداث بصيغة JSON |
|
||||
| `codewhale web` | واجهة ويب محلية على `127.0.0.1` ([الدليل](docs/WEB.md)) |
|
||||
| `codewhale review --pr N` | مراجعة استشارية لطلب pull request على GitHub. لا ينشر شيئًا ما لم تضف `--post`؛ ويُجري [GitHub Action](docs/GITHUB_ACTION.md) المراجعة نفسها في CI |
|
||||
| `codewhale app-server --http` | واجهة [Runtime API](docs/RUNTIME_API.md)، وهي واجهة HTTP محلية للخيوط والأحداث والموافقات وتغييرات الملفات في كل دورة |
|
||||
|
||||
+15
-5
@@ -1,4 +1,4 @@
|
||||
<!-- source: README.md sha256:eefdc9e645b6 -->
|
||||
<!-- source: README.md sha256:30c9b9765b04 -->
|
||||
<div align="center">
|
||||
|
||||
<picture>
|
||||
@@ -88,11 +88,14 @@ teva última petició i els canvis que va fer als fitxers (a la 0.10.1, executa
|
||||
primer `/trust on`). `/help` llista les ordres i les tecles.
|
||||
|
||||
Per a scripts i CI, `codewhale exec` executa una sola tasca sense la interfície.
|
||||
Amb `--auto` edita fitxers i executa ordres de shell sense preguntar, així que
|
||||
fes-lo servir en un contenidor o en una còpia de treball d’un sol ús:
|
||||
Per defecte, `--auto` fa servir Full Access: les eines s’executen sense preguntar,
|
||||
les ordres de shell no tenen cap sandbox de Codewhale i el mode de confiança
|
||||
permet que les eines de fitxers escriguin fora de l’espai de treball. Afegeix
|
||||
`--sandbox workspace-write` per mantenir el sandbox de shell i les restriccions
|
||||
de les eines de fitxers a l’espai de treball, amb el mode de confiança desactivat:
|
||||
|
||||
```bash
|
||||
codewhale exec --auto "fix the failing tests and explain what changed"
|
||||
codewhale exec --auto --sandbox workspace-write "fix the failing tests and explain what changed"
|
||||
```
|
||||
|
||||
## Modes i permisos
|
||||
@@ -160,6 +163,13 @@ crida d’eina cada vegada. `/restore` torna tot l’espai de treball a una
|
||||
instantània anterior; com que això sobreescriu les edicions posteriors,
|
||||
necessita `/trust on` o Full Access. Consulta [Rebuts](docs/RECEIPTS.md).
|
||||
|
||||
Les execucions d’exec que ofereixen eines es desen en tots els formats de
|
||||
sortida, de manera que `codewhale receipts --last` funciona després
|
||||
d’`exec --auto`, també amb `--json`. Les execucions que només donen una resposta
|
||||
en text o amb `--json` només es desen quan es reprèn una conversa o quan
|
||||
comença la compactació de la conversa; fes servir `--output-format stream-json`
|
||||
per desar-les sempre per als rebuts o per a `exec --continue`.
|
||||
|
||||
### Feines més llargues
|
||||
|
||||
`/goal` defineix un objectiu que es manté entre torns. Codewhale pot repartir la
|
||||
@@ -199,7 +209,7 @@ l’accés i l’actives ([guia](crates/tui/plugins/computer-use/README.md)).
|
||||
| Ordre | Què fa |
|
||||
| --- | --- |
|
||||
| `codewhale` | L’aplicació interactiva de terminal |
|
||||
| `codewhale exec "…"` | Una tasca sense la interfície. Per si sol respon sense fer servir eines; `--auto` li permet editar fitxers i executar ordres, i `--output-format stream-json` emet els esdeveniments en streaming com a JSON |
|
||||
| `codewhale exec "…"` | Una tasca sense la interfície. Per si sol respon sense fer servir eines; `--auto` activa les eines amb Full Access per defecte, `--sandbox workspace-write` les restringeix, i `--output-format stream-json` emet els esdeveniments en streaming com a JSON |
|
||||
| `codewhale web` | Una interfície web local a `127.0.0.1` ([guia](docs/WEB.md)) |
|
||||
| `codewhale review --pr N` | Una revisió orientativa d’un pull request de GitHub. No publica res tret que hi afegeixis `--post`; la [GitHub Action](docs/GITHUB_ACTION.md) executa la mateixa revisió a CI |
|
||||
| `codewhale app-server --http` | La [Runtime API](docs/RUNTIME_API.md), una API HTTP local per a fils, esdeveniments, aprovacions i els canvis de fitxers de cada torn |
|
||||
|
||||
+17
-6
@@ -1,4 +1,4 @@
|
||||
<!-- source: README.md sha256:eefdc9e645b6 -->
|
||||
<!-- source: README.md sha256:30c9b9765b04 -->
|
||||
<div align="center">
|
||||
|
||||
<picture>
|
||||
@@ -89,12 +89,16 @@ Rest der Unterhaltung, `n` lehnt ab. `/undo` macht deine letzte Anfrage samt
|
||||
ihren Dateiänderungen rückgängig (in 0.10.1 führe vorher `/trust on` aus).
|
||||
`/help` listet Befehle und Tasten auf.
|
||||
|
||||
Für Skripte und CI führt `codewhale exec` eine Aufgabe ohne Oberfläche aus. Mit
|
||||
`--auto` bearbeitet es Dateien und führt Shell-Befehle aus, ohne zu fragen; gib
|
||||
ihm deshalb einen Container oder einen Wegwerf-Checkout:
|
||||
Für Skripte und CI führt `codewhale exec` eine Aufgabe ohne Oberfläche aus.
|
||||
Standardmäßig nutzt `--auto` Full Access: Tools laufen ohne Nachfrage,
|
||||
Shell-Befehle haben keine Codewhale-Sandbox, und der Vertrauensmodus erlaubt
|
||||
Datei-Tools, außerhalb des Arbeitsbereichs zu schreiben. Füge
|
||||
`--sandbox workspace-write` hinzu, um die Shell-Sandbox und die Beschränkung
|
||||
der Datei-Tools auf den Arbeitsbereich beizubehalten, bei ausgeschaltetem
|
||||
Vertrauensmodus:
|
||||
|
||||
```bash
|
||||
codewhale exec --auto "fix the failing tests and explain what changed"
|
||||
codewhale exec --auto --sandbox workspace-write "fix the failing tests and explain what changed"
|
||||
```
|
||||
|
||||
## Modi und Berechtigungen
|
||||
@@ -164,6 +168,13 @@ Arbeitsbereich auf einen früheren Snapshot zurück; weil dabei spätere
|
||||
Änderungen überschrieben werden, braucht es `/trust on` oder Full Access. Siehe
|
||||
[Belege](docs/RECEIPTS.md).
|
||||
|
||||
Exec-Läufe, die Tools anbieten, werden in jedem Ausgabeformat gespeichert,
|
||||
sodass `codewhale receipts --last` nach `exec --auto` funktioniert, auch mit
|
||||
`--json`. Läufe, die nur antworten, werden im Textformat und mit `--json` nur
|
||||
beim Fortsetzen oder beim Beginn der Gesprächskompaktierung gespeichert;
|
||||
verwende `--output-format stream-json`, um sie immer für Belege oder
|
||||
`exec --continue` zu speichern.
|
||||
|
||||
### Längere Arbeit
|
||||
|
||||
`/goal` setzt ein Ziel, das über mehrere Turns bestehen bleibt. Codewhale kann
|
||||
@@ -204,7 +215,7 @@ bis du seine Zugriffsrechte geprüft und es aktiviert hast
|
||||
| Befehl | Was er tut |
|
||||
| --- | --- |
|
||||
| `codewhale` | Die interaktive Terminal-App |
|
||||
| `codewhale exec "…"` | Eine Aufgabe ohne Oberfläche. Ohne weitere Optionen antwortet es, ohne Tools zu verwenden; `--auto` erlaubt ihm, Dateien zu bearbeiten und Befehle auszuführen, und `--output-format stream-json` streamt Ereignisse als JSON |
|
||||
| `codewhale exec "…"` | Eine Aufgabe ohne Oberfläche. Ohne weitere Optionen antwortet es, ohne Tools zu verwenden; `--auto` aktiviert Tools standardmäßig mit Full Access, `--sandbox workspace-write` schränkt sie ein, und `--output-format stream-json` streamt Ereignisse als JSON |
|
||||
| `codewhale web` | Eine lokale Web-Oberfläche auf `127.0.0.1` ([Anleitung](docs/WEB.md)) |
|
||||
| `codewhale review --pr N` | Ein beratendes Review eines GitHub-Pull-Requests. Es veröffentlicht nichts, solange du nicht `--post` angibst; die [GitHub Action](docs/GITHUB_ACTION.md) führt dasselbe Review in der CI aus |
|
||||
| `codewhale app-server --http` | Die [Runtime API](docs/RUNTIME_API.md), eine lokale HTTP-API für Threads, Ereignisse, Freigaben und die Dateiänderungen jedes Turns |
|
||||
|
||||
+17
-6
@@ -1,4 +1,4 @@
|
||||
<!-- source: README.md sha256:eefdc9e645b6 -->
|
||||
<!-- source: README.md sha256:30c9b9765b04 -->
|
||||
<div align="center">
|
||||
|
||||
<picture>
|
||||
@@ -86,12 +86,16 @@ permite comandos similares durante el resto de la conversación y `n` lo
|
||||
rechaza. `/undo` deshace tu última solicitud y sus cambios en archivos (en
|
||||
0.10.1, ejecuta primero `/trust on`). `/help` muestra los comandos y las teclas.
|
||||
|
||||
Para scripts y CI, `codewhale exec` ejecuta una tarea sin la interfaz. Con
|
||||
`--auto` edita archivos y ejecuta comandos de shell sin preguntar, así que dale
|
||||
un contenedor o un checkout desechable:
|
||||
Para scripts y CI, `codewhale exec` ejecuta una tarea sin la interfaz. Por
|
||||
defecto, `--auto` usa Full Access: las herramientas se ejecutan sin preguntar,
|
||||
los comandos de shell no tienen sandbox de Codewhale y el modo de confianza
|
||||
permite que las herramientas de archivos escriban fuera del espacio de trabajo.
|
||||
Agrega `--sandbox workspace-write` para mantener el sandbox de shell y las
|
||||
restricciones de las herramientas de archivos al espacio de trabajo, con el
|
||||
modo de confianza desactivado:
|
||||
|
||||
```bash
|
||||
codewhale exec --auto "fix the failing tests and explain what changed"
|
||||
codewhale exec --auto --sandbox workspace-write "fix the failing tests and explain what changed"
|
||||
```
|
||||
|
||||
## Modos y permisos
|
||||
@@ -159,6 +163,13 @@ espacio de trabajo a una instantánea anterior; como eso sobrescribe las
|
||||
ediciones posteriores, requiere `/trust on` o Full Access. Consulta
|
||||
[Recibos](docs/RECEIPTS.md).
|
||||
|
||||
Las ejecuciones de exec que ofrecen herramientas se guardan en todos los
|
||||
formatos de salida, así que `codewhale receipts --last` funciona después de
|
||||
`exec --auto`, incluso con `--json`. Las ejecuciones que solo dan una respuesta
|
||||
en texto o con `--json` se guardan solo al reanudar una conversación o cuando
|
||||
empieza la compactación de la conversación; usa `--output-format stream-json`
|
||||
para guardarlas siempre para los recibos o para `exec --continue`.
|
||||
|
||||
### Trabajos más largos
|
||||
|
||||
`/goal` define un objetivo que se mantiene entre turnos. Codewhale puede
|
||||
@@ -199,7 +210,7 @@ que revises su acceso y lo habilites
|
||||
| Comando | Qué hace |
|
||||
| --- | --- |
|
||||
| `codewhale` | La aplicación interactiva de terminal |
|
||||
| `codewhale exec "…"` | Una tarea sin la interfaz. Por sí solo responde sin usar herramientas; `--auto` le permite editar archivos y ejecutar comandos, y `--output-format stream-json` transmite los eventos como JSON |
|
||||
| `codewhale exec "…"` | Una tarea sin la interfaz. Por sí solo responde sin usar herramientas; `--auto` habilita las herramientas con Full Access de forma predeterminada, `--sandbox workspace-write` las restringe, y `--output-format stream-json` transmite los eventos como JSON |
|
||||
| `codewhale web` | Una interfaz web local en `127.0.0.1` ([guía](docs/WEB.md)) |
|
||||
| `codewhale review --pr N` | Una revisión orientativa de un pull request de GitHub. No publica nada a menos que agregues `--post`; la [GitHub Action](docs/GITHUB_ACTION.md) ejecuta la misma revisión en CI |
|
||||
| `codewhale app-server --http` | La [Runtime API](docs/RUNTIME_API.md), una API HTTP local para hilos, eventos, aprobaciones y los cambios de archivos de cada turno |
|
||||
|
||||
+17
-5
@@ -1,4 +1,4 @@
|
||||
<!-- source: README.md sha256:eefdc9e645b6 -->
|
||||
<!-- source: README.md sha256:30c9b9765b04 -->
|
||||
<div align="center">
|
||||
|
||||
<picture>
|
||||
@@ -91,11 +91,15 @@ annule votre dernière demande et ses modifications de fichiers (dans la 0.10.1,
|
||||
lancez d’abord `/trust on`). `/help` liste les commandes et les touches.
|
||||
|
||||
Pour les scripts et la CI, `codewhale exec` exécute une tâche sans l’interface.
|
||||
Avec `--auto`, il modifie des fichiers et exécute des commandes shell sans
|
||||
demander ; lancez-le donc dans un conteneur ou une copie de travail jetable :
|
||||
Par défaut, `--auto` utilise Full Access : les outils s’exécutent sans demander,
|
||||
les commandes shell n’ont pas de bac à sable Codewhale et le mode de confiance
|
||||
permet aux outils de fichiers d’écrire en dehors de l’espace de travail.
|
||||
Ajoutez `--sandbox workspace-write` pour conserver le bac à sable du shell et
|
||||
les restrictions des outils de fichiers à l’espace de travail, avec le mode de
|
||||
confiance désactivé :
|
||||
|
||||
```bash
|
||||
codewhale exec --auto "fix the failing tests and explain what changed"
|
||||
codewhale exec --auto --sandbox workspace-write "fix the failing tests and explain what changed"
|
||||
```
|
||||
|
||||
## Modes et permissions
|
||||
@@ -166,6 +170,14 @@ ramène tout l’espace de travail à un instantané antérieur ; comme cela éc
|
||||
les modifications ultérieures, il faut `/trust on` ou Full Access. Voir
|
||||
[Reçus](docs/RECEIPTS.md).
|
||||
|
||||
Les exécutions d’exec qui proposent des outils sont enregistrées dans tous les
|
||||
formats de sortie ; `codewhale receipts --last` fonctionne donc après
|
||||
`exec --auto`, y compris avec `--json`. Les exécutions qui se limitent à une
|
||||
réponse en texte ou avec `--json` ne sont enregistrées que lors d’une reprise
|
||||
ou lorsque la compaction de la conversation commence ; utilisez
|
||||
`--output-format stream-json` pour toujours les enregistrer pour les reçus ou
|
||||
pour `exec --continue`.
|
||||
|
||||
### Travail de longue durée
|
||||
|
||||
`/goal` fixe un objectif qui se maintient d’un tour à l’autre. Codewhale peut
|
||||
@@ -206,7 +218,7 @@ ne l’avez pas activé ([guide](crates/tui/plugins/computer-use/README.md)).
|
||||
| Commande | Ce qu’elle fait |
|
||||
| --- | --- |
|
||||
| `codewhale` | L’application interactive dans le terminal |
|
||||
| `codewhale exec "…"` | Une tâche sans l’interface. Sans option, il répond sans utiliser d’outils ; `--auto` lui permet de modifier des fichiers et d’exécuter des commandes, et `--output-format stream-json` diffuse les événements en JSON |
|
||||
| `codewhale exec "…"` | Une tâche sans l’interface. Sans option, il répond sans utiliser d’outils ; `--auto` active les outils avec Full Access par défaut, `--sandbox workspace-write` les restreint, et `--output-format stream-json` diffuse les événements en JSON |
|
||||
| `codewhale web` | Une interface web locale sur `127.0.0.1` ([guide](docs/WEB.md)) |
|
||||
| `codewhale review --pr N` | Une revue consultative d’une pull request GitHub. Elle ne publie rien sauf si vous ajoutez `--post` ; la [GitHub Action](docs/GITHUB_ACTION.md) exécute la même revue en CI |
|
||||
| `codewhale app-server --http` | La [Runtime API](docs/RUNTIME_API.md), une API HTTP locale pour les fils, les événements, les approbations et les modifications de fichiers de chaque tour |
|
||||
|
||||
+14
-6
@@ -1,4 +1,4 @@
|
||||
<!-- source: README.md sha256:eefdc9e645b6 -->
|
||||
<!-- source: README.md sha256:30c9b9765b04 -->
|
||||
<div align="center">
|
||||
|
||||
<picture>
|
||||
@@ -83,12 +83,14 @@ Codewhale पहले पूछता है: `y` उसे एक बार
|
||||
फ़ाइल बदलाव वापस करता है (0.10.1 में पहले `/trust on` चलाएँ)। `/help` कमांड और
|
||||
कीबोर्ड कुंजियों की सूची देता है।
|
||||
|
||||
स्क्रिप्ट और CI के लिए `codewhale exec` बिना इंटरफ़ेस के एक काम चलाता है। `--auto` के
|
||||
साथ यह बिना पूछे फ़ाइलें संपादित करता है और शेल कमांड चलाता है, इसलिए इसे कोई कंटेनर
|
||||
या अस्थायी checkout दें:
|
||||
स्क्रिप्ट और CI के लिए `codewhale exec` बिना इंटरफ़ेस के एक काम चलाता है। डिफ़ॉल्ट
|
||||
रूप से `--auto` Full Access का इस्तेमाल करता है: टूल बिना पूछे चलते हैं, शेल कमांड
|
||||
पर Codewhale का सैंडबॉक्स लागू नहीं होता, और ट्रस्ट मोड फ़ाइल टूल को वर्कस्पेस के
|
||||
बाहर लिखने देता है। शेल सैंडबॉक्स और फ़ाइल टूल की वर्कस्पेस सीमाएँ बनाए रखने और
|
||||
ट्रस्ट मोड बंद रखने के लिए `--sandbox workspace-write` जोड़ें:
|
||||
|
||||
```bash
|
||||
codewhale exec --auto "fix the failing tests and explain what changed"
|
||||
codewhale exec --auto --sandbox workspace-write "fix the failing tests and explain what changed"
|
||||
```
|
||||
|
||||
## मोड और अनुमतियाँ
|
||||
@@ -152,6 +154,12 @@ Mistral, Moonshot, OpenRouter और xAI शामिल हैं। कोई
|
||||
ओवरराइट हो जाते हैं, इसके लिए `/trust on` या Full Access चाहिए।
|
||||
[रसीदें](docs/RECEIPTS.md) देखें।
|
||||
|
||||
जिन exec रन में टूल उपलब्ध होते हैं, वे हर आउटपुट फ़ॉर्मैट में सहेजे जाते हैं, इसलिए
|
||||
`codewhale receipts --last`, `exec --auto` के बाद काम करता है, `--json` के साथ भी।
|
||||
केवल जवाब देने वाले टेक्स्ट और `--json` रन तभी सहेजे जाते हैं जब उन्हें फिर से शुरू
|
||||
किया जाता है या बातचीत का कॉम्पैक्शन शुरू होता है; रसीदों या `exec --continue`
|
||||
के लिए उन्हें हमेशा सहेजने के लिए `--output-format stream-json` इस्तेमाल करें।
|
||||
|
||||
### लंबे काम
|
||||
|
||||
`/goal` एक ऐसा उद्देश्य तय करता है जो कई टर्न तक बना रहता है। Codewhale काम को
|
||||
@@ -188,7 +196,7 @@ Code mode (प्रायोगिक, डिफ़ॉल्ट रूप स
|
||||
| कमांड | क्या करता है |
|
||||
| --- | --- |
|
||||
| `codewhale` | इंटरैक्टिव टर्मिनल ऐप |
|
||||
| `codewhale exec "…"` | बिना इंटरफ़ेस के एक काम। अकेले चलाने पर यह टूल का इस्तेमाल किए बिना जवाब देता है; `--auto` इसे फ़ाइलें संपादित करने और कमांड चलाने देता है, और `--output-format stream-json` इवेंट को JSON के रूप में स्ट्रीम करता है |
|
||||
| `codewhale exec "…"` | बिना इंटरफ़ेस के एक काम। अकेले चलाने पर यह टूल का इस्तेमाल किए बिना जवाब देता है; `--auto` डिफ़ॉल्ट रूप से Full Access के साथ टूल चालू करता है, `--sandbox workspace-write` उन्हें सीमित करता है, और `--output-format stream-json` इवेंट को JSON के रूप में स्ट्रीम करता है |
|
||||
| `codewhale web` | `127.0.0.1` पर एक लोकल वेब UI ([गाइड](docs/WEB.md)) |
|
||||
| `codewhale review --pr N` | किसी GitHub pull request की सलाह के तौर पर समीक्षा। जब तक आप `--post` न जोड़ें, यह कुछ पोस्ट नहीं करता; [GitHub Action](docs/GITHUB_ACTION.md) यही समीक्षा CI में चलाता है |
|
||||
| `codewhale app-server --http` | [Runtime API](docs/RUNTIME_API.md), थ्रेड, इवेंट, अनुमोदन और हर टर्न के फ़ाइल बदलावों के लिए एक लोकल HTTP API |
|
||||
|
||||
+15
-5
@@ -1,4 +1,4 @@
|
||||
<!-- source: README.md sha256:eefdc9e645b6 -->
|
||||
<!-- source: README.md sha256:30c9b9765b04 -->
|
||||
<div align="center">
|
||||
|
||||
<picture>
|
||||
@@ -88,11 +88,14 @@ Anda beserta perubahan berkasnya (di 0.10.1, jalankan `/trust on` terlebih
|
||||
dahulu). `/help` menampilkan daftar perintah dan tombol.
|
||||
|
||||
Untuk skrip dan CI, `codewhale exec` menjalankan satu tugas tanpa antarmuka.
|
||||
Dengan `--auto`, ia mengedit berkas dan menjalankan perintah shell tanpa
|
||||
bertanya, jadi jalankan di dalam container atau checkout sekali pakai:
|
||||
Secara default, `--auto` memakai Akses penuh: alat berjalan tanpa bertanya,
|
||||
perintah shell tidak dibatasi sandbox Codewhale, dan mode kepercayaan
|
||||
mengizinkan alat berkas menulis di luar workspace. Tambahkan
|
||||
`--sandbox workspace-write` untuk mempertahankan sandbox shell dan batasan
|
||||
workspace bagi alat berkas, dengan mode kepercayaan dinonaktifkan:
|
||||
|
||||
```bash
|
||||
codewhale exec --auto "fix the failing tests and explain what changed"
|
||||
codewhale exec --auto --sandbox workspace-write "fix the failing tests and explain what changed"
|
||||
```
|
||||
|
||||
## Mode dan izin
|
||||
@@ -162,6 +165,13 @@ mengembalikan seluruh workspace
|
||||
ke snapshot sebelumnya; karena itu menimpa edit yang lebih baru, perintah ini
|
||||
memerlukan `/trust on` atau Akses penuh. Lihat [Receipt](docs/RECEIPTS.md).
|
||||
|
||||
Eksekusi exec yang menyediakan alat disimpan dalam setiap format output, jadi
|
||||
`codewhale receipts --last` bisa dipakai setelah `exec --auto`, termasuk dengan
|
||||
`--json`. Eksekusi yang hanya menjawab dengan teks atau `--json` hanya disimpan
|
||||
saat melanjutkan percakapan atau ketika pemadatan percakapan dimulai; gunakan
|
||||
`--output-format stream-json` agar selalu tersimpan untuk receipt atau
|
||||
`exec --continue`.
|
||||
|
||||
### Pekerjaan yang lebih panjang
|
||||
|
||||
`/goal` menetapkan sasaran yang berlanjut lintas giliran. Codewhale dapat
|
||||
@@ -201,7 +211,7 @@ Anda meninjau aksesnya dan mengaktifkannya
|
||||
| Perintah | Fungsinya |
|
||||
| --- | --- |
|
||||
| `codewhale` | Aplikasi terminal interaktif |
|
||||
| `codewhale exec "…"` | Satu tugas tanpa antarmuka. Tanpa flag tambahan, ia menjawab tanpa memakai alat; `--auto` mengizinkannya mengedit berkas dan menjalankan perintah, dan `--output-format stream-json` men-streaming event sebagai JSON |
|
||||
| `codewhale exec "…"` | Satu tugas tanpa antarmuka. Tanpa flag tambahan, ia menjawab tanpa memakai alat; `--auto` mengaktifkan alat dengan Akses penuh secara default, `--sandbox workspace-write` membatasinya, dan `--output-format stream-json` men-streaming event sebagai JSON |
|
||||
| `codewhale web` | UI web lokal di `127.0.0.1` ([panduan](docs/WEB.md)) |
|
||||
| `codewhale review --pr N` | Tinjauan yang bersifat saran untuk pull request GitHub. Ia tidak memposting apa pun kecuali Anda menambahkan `--post`; [GitHub Action](docs/GITHUB_ACTION.md) menjalankan tinjauan yang sama di CI |
|
||||
| `codewhale app-server --http` | [Runtime API](docs/RUNTIME_API.md), API HTTP lokal untuk thread, event, persetujuan, dan perubahan berkas setiap giliran |
|
||||
|
||||
+17
-6
@@ -1,4 +1,4 @@
|
||||
<!-- source: README.md sha256:eefdc9e645b6 -->
|
||||
<!-- source: README.md sha256:30c9b9765b04 -->
|
||||
<div align="center">
|
||||
|
||||
<picture>
|
||||
@@ -86,12 +86,16 @@ simili per il resto della conversazione, `n` lo rifiuta. `/undo` annulla la tua
|
||||
ultima richiesta e le relative modifiche ai file (nella 0.10.1, esegui prima
|
||||
`/trust on`). `/help` elenca comandi e tasti.
|
||||
|
||||
Per script e CI, `codewhale exec` esegue un compito senza interfaccia. Con
|
||||
`--auto` modifica i file ed esegue comandi di shell senza chiedere, quindi
|
||||
dagli un container o un checkout usa e getta:
|
||||
Per script e CI, `codewhale exec` esegue un compito senza interfaccia. Per
|
||||
impostazione predefinita, `--auto` usa Full Access: gli strumenti vengono
|
||||
eseguiti senza chiedere, i comandi di shell non hanno la sandbox di Codewhale
|
||||
e la modalità di fiducia consente agli strumenti per i file di scrivere fuori
|
||||
dall’area di lavoro. Aggiungi `--sandbox workspace-write` per mantenere la
|
||||
sandbox della shell e le restrizioni degli strumenti per i file all’area di
|
||||
lavoro, con la modalità di fiducia disattivata:
|
||||
|
||||
```bash
|
||||
codewhale exec --auto "fix the failing tests and explain what changed"
|
||||
codewhale exec --auto --sandbox workspace-write "fix the failing tests and explain what changed"
|
||||
```
|
||||
|
||||
## Modalità e permessi
|
||||
@@ -157,6 +161,13 @@ chiamata di strumento alla volta. `/restore` riporta l’intera area di lavoro a
|
||||
uno snapshot precedente; poiché sovrascrive le modifiche successive, richiede
|
||||
`/trust on` o Full Access. Vedi [Ricevute](docs/RECEIPTS.md).
|
||||
|
||||
Le esecuzioni di exec che offrono strumenti vengono salvate in ogni formato di
|
||||
output, quindi `codewhale receipts --last` funziona dopo `exec --auto`, anche
|
||||
con `--json`. Le esecuzioni che forniscono solo una risposta in testo o con
|
||||
`--json` vengono salvate solo quando si riprende una conversazione o quando
|
||||
inizia la compattazione della conversazione; usa `--output-format stream-json`
|
||||
per salvarle sempre per le ricevute o per `exec --continue`.
|
||||
|
||||
### Lavori più lunghi
|
||||
|
||||
`/goal` imposta un obiettivo che resta valido da un turno all’altro. Codewhale
|
||||
@@ -198,7 +209,7 @@ controlli gli accessi e lo abiliti
|
||||
| Comando | Cosa fa |
|
||||
| --- | --- |
|
||||
| `codewhale` | L’app interattiva nel terminale |
|
||||
| `codewhale exec "…"` | Un compito senza interfaccia. Da solo risponde senza usare strumenti; `--auto` gli consente di modificare file ed eseguire comandi, e `--output-format stream-json` trasmette gli eventi in streaming come JSON |
|
||||
| `codewhale exec "…"` | Un compito senza interfaccia. Da solo risponde senza usare strumenti; `--auto` abilita gli strumenti con Full Access per impostazione predefinita, `--sandbox workspace-write` li limita, e `--output-format stream-json` trasmette gli eventi in streaming come JSON |
|
||||
| `codewhale web` | Un’interfaccia web locale su `127.0.0.1` ([guida](docs/WEB.md)) |
|
||||
| `codewhale review --pr N` | Una revisione consultiva di una pull request GitHub. Non pubblica nulla a meno che tu non aggiunga `--post`; la [GitHub Action](docs/GITHUB_ACTION.md) esegue la stessa revisione in CI |
|
||||
| `codewhale app-server --http` | La [Runtime API](docs/RUNTIME_API.md), un’API HTTP locale per thread, eventi, approvazioni e le modifiche ai file di ogni turno |
|
||||
|
||||
+9
-4
@@ -1,4 +1,4 @@
|
||||
<!-- source: README.md sha256:eefdc9e645b6 -->
|
||||
<!-- source: README.md sha256:30c9b9765b04 -->
|
||||
<div align="center">
|
||||
|
||||
<picture>
|
||||
@@ -80,10 +80,11 @@ Fix the failing tests and explain what changed.
|
||||
`/help` でコマンドとキーの一覧を表示します。
|
||||
|
||||
スクリプトや CI では、`codewhale exec` がインターフェースなしで 1 つのタスクを実行します。
|
||||
`--auto` を付けると確認なしでファイルを編集し、シェルコマンドを実行するため、コンテナか使い捨てのチェックアウトで実行してください。
|
||||
既定では、`--auto` はフルアクセスを使います。ツールは確認なしで実行され、シェルコマンドには Codewhale のサンドボックスが適用されず、信頼モードによりファイルツールはワークスペースの外にも書き込めます。
|
||||
`--sandbox workspace-write` を追加すると、信頼モードをオフにし、シェルのサンドボックスとファイルツールのワークスペース制限を維持できます。
|
||||
|
||||
```bash
|
||||
codewhale exec --auto "fix the failing tests and explain what changed"
|
||||
codewhale exec --auto --sandbox workspace-write "fix the failing tests and explain what changed"
|
||||
```
|
||||
|
||||
## モードと権限
|
||||
@@ -138,6 +139,10 @@ DeepSeek は 2026-10-17 にこれを DeepSeek-V4.1-Flash-1017 に切り替えま
|
||||
それ以降の編集を上書きするため、`/trust on` またはフルアクセスが必要です。
|
||||
[レシート](docs/RECEIPTS.md)を参照してください。
|
||||
|
||||
ツールを利用できる exec の実行は、どの出力形式でも保存されるため、`--json` を含む `exec --auto` の実行後に `codewhale receipts --last` を使えます。
|
||||
回答のみを返すテキスト出力や `--json` の実行は、再開時か会話の圧縮が始まるときにだけ保存されます。
|
||||
レシートや `exec --continue` のために常に保存するには、`--output-format stream-json` を使ってください。
|
||||
|
||||
### 長い作業
|
||||
|
||||
`/goal` は、ターンをまたいで持続する目標を設定します。
|
||||
@@ -166,7 +171,7 @@ Codewhale は `AGENTS.md` を自動で読み込みます。
|
||||
| コマンド | 内容 |
|
||||
| --- | --- |
|
||||
| `codewhale` | 対話型のターミナルアプリ |
|
||||
| `codewhale exec "…"` | インターフェースなしで 1 つのタスクを実行します。オプションなしではツールを使わずに回答し、`--auto` でファイルの編集とコマンドの実行を許可し、`--output-format stream-json` でイベントを JSON としてストリーミングします |
|
||||
| `codewhale exec "…"` | インターフェースなしで 1 つのタスクを実行します。オプションなしではツールを使わずに回答し、`--auto` は既定でフルアクセスでツールを有効にし、`--sandbox workspace-write` はそれらを制限し、`--output-format stream-json` でイベントを JSON としてストリーミングします |
|
||||
| `codewhale web` | `127.0.0.1` で動作するローカル Web UI([ガイド](docs/WEB.md)) |
|
||||
| `codewhale review --pr N` | GitHub のプルリクエストに対する参考としてのレビュー。`--post` を付けない限り何も投稿しません。[GitHub Action](docs/GITHUB_ACTION.md) は同じレビューを CI で実行します |
|
||||
| `codewhale app-server --http` | [Runtime API](docs/RUNTIME_API.md)。スレッド、イベント、承認、各ターンのファイル変更のためのローカル HTTP API |
|
||||
|
||||
+14
-5
@@ -1,4 +1,4 @@
|
||||
<!-- source: README.md sha256:eefdc9e645b6 -->
|
||||
<!-- source: README.md sha256:30c9b9765b04 -->
|
||||
<div align="center">
|
||||
|
||||
<picture>
|
||||
@@ -86,11 +86,14 @@ Fix the failing tests and explain what changed.
|
||||
볼 수 있습니다.
|
||||
|
||||
스크립트와 CI용으로는 인터페이스 없이 작업 하나를 실행하는 `codewhale exec`
|
||||
명령이 있습니다. `--auto`를 주면 묻지 않고 파일을 편집하고 셸 명령을
|
||||
실행하므로, 컨테이너나 버려도 되는 체크아웃에서 실행하세요.
|
||||
명령이 있습니다. 기본적으로 `--auto`는 전체 접근 권한을 사용합니다. 도구는
|
||||
묻지 않고 실행되고, 셸 명령에는 Codewhale 샌드박스가 적용되지 않으며, 신뢰
|
||||
모드에서는 파일 도구가 작업 공간 밖에도 쓸 수 있습니다.
|
||||
`--sandbox workspace-write`를 추가하면 신뢰 모드를 끄고 셸 샌드박스와 파일
|
||||
도구의 작업 공간 제한을 유지할 수 있습니다.
|
||||
|
||||
```bash
|
||||
codewhale exec --auto "fix the failing tests and explain what changed"
|
||||
codewhale exec --auto --sandbox workspace-write "fix the failing tests and explain what changed"
|
||||
```
|
||||
|
||||
## 모드와 권한
|
||||
@@ -154,6 +157,12 @@ ChatGPT 요금제를 사용할 수 있습니다(실험적). [제공업체](docs/
|
||||
스냅샷으로 되돌리는데, 이후의 편집을 덮어쓰기 때문에 `/trust on` 또는 전체
|
||||
접근 권한이 필요합니다. [영수증](docs/RECEIPTS.md)을 참고하세요.
|
||||
|
||||
도구를 사용할 수 있는 exec 실행은 모든 출력 형식에서 저장되므로, `--json`을
|
||||
포함한 `exec --auto` 실행 후에도 `codewhale receipts --last`를 쓸 수 있습니다.
|
||||
답변만 하는 텍스트 및 `--json` 실행은 재개하거나 대화 압축이 시작될 때만
|
||||
저장됩니다. 영수증이나 `exec --continue`를 위해 항상 저장하려면
|
||||
`--output-format stream-json`을 사용하세요.
|
||||
|
||||
### 긴 작업
|
||||
|
||||
`/goal`은 여러 턴에 걸쳐 유지되는 목표를 정합니다. Codewhale은 작업을
|
||||
@@ -192,7 +201,7 @@ Codewhale은 따로 설정하지 않아도 `AGENTS.md`를 읽습니다. `CLAUDE.
|
||||
| 명령 | 하는 일 |
|
||||
| --- | --- |
|
||||
| `codewhale` | 대화형 터미널 앱 |
|
||||
| `codewhale exec "…"` | 인터페이스 없이 작업 하나를 실행합니다. 옵션 없이 쓰면 도구를 사용하지 않고 답변만 하고, `--auto`는 파일 편집과 명령 실행을 허용하며, `--output-format stream-json`은 이벤트를 JSON으로 스트리밍합니다 |
|
||||
| `codewhale exec "…"` | 인터페이스 없이 작업 하나를 실행합니다. 옵션 없이 쓰면 도구를 사용하지 않고 답변만 하고, `--auto`는 기본적으로 전체 접근 권한으로 도구를 활성화하고, `--sandbox workspace-write`는 도구를 제한하며, `--output-format stream-json`은 이벤트를 JSON으로 스트리밍합니다 |
|
||||
| `codewhale web` | `127.0.0.1`에서 동작하는 로컬 웹 UI([안내서](docs/WEB.md)) |
|
||||
| `codewhale review --pr N` | GitHub 풀 리퀘스트에 대한 참고용 리뷰. `--post`를 추가하지 않으면 아무것도 게시하지 않으며, [GitHub Action](docs/GITHUB_ACTION.md)이 CI에서 같은 리뷰를 실행합니다 |
|
||||
| `codewhale app-server --http` | 스레드, 이벤트, 승인, 각 턴의 파일 변경을 다루는 로컬 HTTP API인 [Runtime API](docs/RUNTIME_API.md) |
|
||||
|
||||
@@ -82,12 +82,14 @@ asks first: `y` runs it once, `a` allows commands like it for the rest of the
|
||||
conversation, `n` refuses. `/undo` takes back your last request and its file
|
||||
changes (in 0.10.1, run `/trust on` first). `/help` lists commands and keys.
|
||||
|
||||
For scripts and CI, `codewhale exec` runs one task without the interface. With
|
||||
`--auto` it edits files and runs shell commands without asking, so give it a
|
||||
container or a throwaway checkout:
|
||||
For scripts and CI, `codewhale exec` runs one task without the interface. By
|
||||
default, `--auto` uses Full Access: tools run without asking, shell commands
|
||||
have no Codewhale sandbox, and trust mode lets file tools write outside the
|
||||
workspace. Add `--sandbox workspace-write` to keep the shell sandbox and
|
||||
file-tool workspace restrictions, with trust mode off:
|
||||
|
||||
```bash
|
||||
codewhale exec --auto "fix the failing tests and explain what changed"
|
||||
codewhale exec --auto --sandbox workspace-write "fix the failing tests and explain what changed"
|
||||
```
|
||||
|
||||
## Modes and permissions
|
||||
@@ -150,6 +152,12 @@ needs `/trust on` for files and steps back one tool call at a time. `/restore`
|
||||
rolls the whole workspace back to an earlier snapshot; because that overwrites
|
||||
later edits, it needs `/trust on` or Full Access. See [Receipts](docs/RECEIPTS.md).
|
||||
|
||||
Exec runs that offer tools are saved in every output format, so
|
||||
`codewhale receipts --last` works after `exec --auto`, including `--json`.
|
||||
Answer-only text and `--json` runs are saved only when resuming or when
|
||||
conversation compaction starts; use `--output-format stream-json` to always
|
||||
save them for receipts or `exec --continue`.
|
||||
|
||||
### Longer work
|
||||
|
||||
`/goal` sets an objective that carries across turns. Codewhale can split work
|
||||
@@ -189,7 +197,7 @@ and operate other apps. It stays off until you review its access and enable it
|
||||
| Command | What it does |
|
||||
| --- | --- |
|
||||
| `codewhale` | The interactive terminal app |
|
||||
| `codewhale exec "…"` | One task without the interface. On its own it answers without using tools; `--auto` lets it edit files and run commands, and `--output-format stream-json` streams events as JSON |
|
||||
| `codewhale exec "…"` | One task without the interface. On its own it answers without using tools; `--auto` enables tools with Full Access by default, `--sandbox workspace-write` restricts them, and `--output-format stream-json` streams events as JSON |
|
||||
| `codewhale web` | A local web UI on `127.0.0.1` ([guide](docs/WEB.md)) |
|
||||
| `codewhale review --pr N` | An advisory review of a GitHub pull request. It posts nothing unless you add `--post`; the [GitHub Action](docs/GITHUB_ACTION.md) runs the same review in CI |
|
||||
| `codewhale app-server --http` | The [Runtime API](docs/RUNTIME_API.md), a local HTTP API for threads, events, approvals, and each turn's file changes |
|
||||
|
||||
+16
-6
@@ -1,4 +1,4 @@
|
||||
<!-- source: README.md sha256:eefdc9e645b6 -->
|
||||
<!-- source: README.md sha256:30c9b9765b04 -->
|
||||
<div align="center">
|
||||
|
||||
<picture>
|
||||
@@ -87,12 +87,15 @@ zezwala na podobne polecenia do końca rozmowy, `n` odmawia. `/undo` cofa Twoje
|
||||
ostatnie zlecenie i zmiany, które wprowadziło w plikach (w 0.10.1 najpierw
|
||||
uruchom `/trust on`). `/help` wyświetla polecenia i skróty klawiszowe.
|
||||
|
||||
W skryptach i CI `codewhale exec` wykonuje jedno zadanie bez interfejsu. Z
|
||||
`--auto` edytuje pliki i uruchamia polecenia powłoki bez pytania, więc
|
||||
uruchamiaj go w kontenerze albo w jednorazowej kopii roboczej:
|
||||
W skryptach i CI `codewhale exec` wykonuje jedno zadanie bez interfejsu.
|
||||
Domyślnie `--auto` używa Full Access: narzędzia działają bez pytania, polecenia
|
||||
powłoki działają bez piaskownicy Codewhale, a tryb zaufania pozwala narzędziom
|
||||
plikowym zapisywać pliki poza obszarem roboczym. Dodaj
|
||||
`--sandbox workspace-write`, aby zachować piaskownicę powłoki i ograniczyć
|
||||
narzędzia plikowe do obszaru roboczego, z wyłączonym trybem zaufania:
|
||||
|
||||
```bash
|
||||
codewhale exec --auto "fix the failing tests and explain what changed"
|
||||
codewhale exec --auto --sandbox workspace-write "fix the failing tests and explain what changed"
|
||||
```
|
||||
|
||||
## Tryby i uprawnienia
|
||||
@@ -163,6 +166,13 @@ przywraca cały obszar roboczy do wcześniejszej migawki; ponieważ nadpisuje to
|
||||
późniejsze zmiany, wymaga `/trust on` lub Full Access. Zobacz
|
||||
[Pokwitowania](docs/RECEIPTS.md).
|
||||
|
||||
Uruchomienia exec z dostępnymi narzędziami są zapisywane w każdym formacie
|
||||
wyjściowym, więc `codewhale receipts --last` działa po `exec --auto`, także
|
||||
z `--json`. Uruchomienia bez narzędzi z wyjściem tekstowym lub `--json` są
|
||||
zapisywane tylko przy wznawianiu lub gdy zaczyna się kompakcja rozmowy; użyj
|
||||
`--output-format stream-json`, aby zawsze je zapisywać na potrzeby pokwitowań
|
||||
lub `exec --continue`.
|
||||
|
||||
### Dłuższa praca
|
||||
|
||||
`/goal` ustawia cel, który obowiązuje przez kolejne tury. Codewhale może
|
||||
@@ -203,7 +213,7 @@ Pozostaje wyłączona, dopóki nie sprawdzisz jej dostępu i jej nie włączysz
|
||||
| Polecenie | Co robi |
|
||||
| --- | --- |
|
||||
| `codewhale` | Interaktywna aplikacja terminalowa |
|
||||
| `codewhale exec "…"` | Jedno zadanie bez interfejsu. Bez dodatkowych flag odpowiada bez użycia narzędzi; `--auto` pozwala mu edytować pliki i uruchamiać polecenia, a `--output-format stream-json` strumieniuje zdarzenia jako JSON |
|
||||
| `codewhale exec "…"` | Jedno zadanie bez interfejsu. Bez dodatkowych flag odpowiada bez użycia narzędzi; `--auto` domyślnie włącza narzędzia z Full Access, `--sandbox workspace-write` je ogranicza, a `--output-format stream-json` strumieniuje zdarzenia jako JSON |
|
||||
| `codewhale web` | Lokalny interfejs przeglądarkowy pod `127.0.0.1` ([przewodnik](docs/WEB.md)) |
|
||||
| `codewhale review --pr N` | Doradczy przegląd pull requesta na GitHubie. Niczego nie publikuje, chyba że dodasz `--post`; [GitHub Action](docs/GITHUB_ACTION.md) uruchamia ten sam przegląd w CI |
|
||||
| `codewhale app-server --http` | [Runtime API](docs/RUNTIME_API.md), lokalne HTTP API dla wątków, zdarzeń, zatwierdzeń i zmian w plikach z każdej tury |
|
||||
|
||||
+16
-6
@@ -1,4 +1,4 @@
|
||||
<!-- source: README.md sha256:eefdc9e645b6 -->
|
||||
<!-- source: README.md sha256:30c9b9765b04 -->
|
||||
<div align="center">
|
||||
|
||||
<picture>
|
||||
@@ -86,12 +86,15 @@ pelo resto da conversa, `n` recusa. `/undo` desfaz seu último pedido e as
|
||||
alterações de arquivos que ele fez (na 0.10.1, execute `/trust on` antes).
|
||||
`/help` lista os comandos e as teclas.
|
||||
|
||||
Para scripts e CI, `codewhale exec` executa uma tarefa sem a interface. Com
|
||||
`--auto`, ele edita arquivos e executa comandos de shell sem perguntar, então
|
||||
use um contêiner ou um checkout descartável:
|
||||
Para scripts e CI, `codewhale exec` executa uma tarefa sem a interface. Por
|
||||
padrão, `--auto` usa Acesso total: as ferramentas rodam sem perguntar, os
|
||||
comandos de shell não têm o sandbox do Codewhale e o modo de confiança permite
|
||||
que as ferramentas de arquivos escrevam fora do workspace. Adicione
|
||||
`--sandbox workspace-write` para manter o sandbox do shell e as restrições das
|
||||
ferramentas de arquivos ao workspace, com o modo de confiança desligado:
|
||||
|
||||
```bash
|
||||
codewhale exec --auto "fix the failing tests and explain what changed"
|
||||
codewhale exec --auto --sandbox workspace-write "fix the failing tests and explain what changed"
|
||||
```
|
||||
|
||||
## Modos e permissões
|
||||
@@ -159,6 +162,13 @@ ferramenta por vez. `/restore` volta o workspace inteiro para um snapshot
|
||||
anterior; como isso sobrescreve edições posteriores, exige `/trust on` ou Acesso
|
||||
total. Veja [Recibos](docs/RECEIPTS.md).
|
||||
|
||||
As execuções de exec que oferecem ferramentas são salvas em todos os formatos
|
||||
de saída, então `codewhale receipts --last` funciona depois de `exec --auto`,
|
||||
inclusive com `--json`. As execuções que só dão uma resposta em texto ou com
|
||||
`--json` são salvas apenas ao retomar uma conversa ou quando a compactação da
|
||||
conversa começa; use `--output-format stream-json` para sempre salvá-las para
|
||||
os recibos ou para `exec --continue`.
|
||||
|
||||
### Trabalhos mais longos
|
||||
|
||||
`/goal` define um objetivo que se mantém entre turnos. O Codewhale pode dividir
|
||||
@@ -199,7 +209,7 @@ revisar o acesso dele e ativá-lo
|
||||
| Comando | O que faz |
|
||||
| --- | --- |
|
||||
| `codewhale` | O aplicativo interativo de terminal |
|
||||
| `codewhale exec "…"` | Uma tarefa sem a interface. Sozinho, ele responde sem usar ferramentas; `--auto` permite que ele edite arquivos e execute comandos, e `--output-format stream-json` transmite os eventos como JSON |
|
||||
| `codewhale exec "…"` | Uma tarefa sem a interface. Sozinho, ele responde sem usar ferramentas; `--auto` habilita ferramentas com Acesso total por padrão, `--sandbox workspace-write` as restringe, e `--output-format stream-json` transmite os eventos como JSON |
|
||||
| `codewhale web` | Uma interface web local em `127.0.0.1` ([guia](docs/WEB.md)) |
|
||||
| `codewhale review --pr N` | Uma revisão consultiva de um pull request do GitHub. Não publica nada a menos que você adicione `--post`; a [GitHub Action](docs/GITHUB_ACTION.md) executa a mesma revisão no CI |
|
||||
| `codewhale app-server --http` | A [Runtime API](docs/RUNTIME_API.md), uma API HTTP local para threads, eventos, aprovações e as alterações de arquivos de cada turno |
|
||||
|
||||
+16
-6
@@ -1,4 +1,4 @@
|
||||
<!-- source: README.md sha256:eefdc9e645b6 -->
|
||||
<!-- source: README.md sha256:30c9b9765b04 -->
|
||||
<div align="center">
|
||||
|
||||
<picture>
|
||||
@@ -88,12 +88,15 @@ Fix the failing tests and explain what changed.
|
||||
последний запрос и сделанные им изменения в файлах (в 0.10.1 сначала выполните
|
||||
`/trust on`). `/help` показывает список команд и клавиш.
|
||||
|
||||
Для скриптов и CI `codewhale exec` выполняет одну задачу без интерфейса. С
|
||||
`--auto` он редактирует файлы и выполняет команды оболочки без запроса, поэтому
|
||||
запускайте его в контейнере или в одноразовой копии репозитория:
|
||||
Для скриптов и CI `codewhale exec` выполняет одну задачу без интерфейса. По
|
||||
умолчанию `--auto` использует Full Access: инструменты выполняются без запроса,
|
||||
команды оболочки работают без песочницы Codewhale, а режим доверия позволяет
|
||||
файловым инструментам записывать файлы за пределами рабочей области. Добавьте
|
||||
`--sandbox workspace-write`, чтобы сохранить песочницу оболочки и ограничить
|
||||
файловые инструменты рабочей областью, отключив режим доверия:
|
||||
|
||||
```bash
|
||||
codewhale exec --auto "fix the failing tests and explain what changed"
|
||||
codewhale exec --auto --sandbox workspace-write "fix the failing tests and explain what changed"
|
||||
```
|
||||
|
||||
## Режимы и разрешения
|
||||
@@ -160,6 +163,13 @@ API (экспериментально). См. [Провайдеры](docs/PROVID
|
||||
раннему снимку; поскольку при этом перезаписываются более поздние правки, для
|
||||
него нужен `/trust on` или Full Access. См. [Квитанции](docs/RECEIPTS.md).
|
||||
|
||||
Запуски exec, в которых доступны инструменты, сохраняются при любом формате
|
||||
вывода, поэтому `codewhale receipts --last` работает после `exec --auto`, в том
|
||||
числе с `--json`. Запуски без инструментов с текстовым выводом или `--json`
|
||||
сохраняются только при возобновлении или когда начинается сжатие разговора;
|
||||
используйте `--output-format stream-json`, чтобы всегда сохранять их для
|
||||
квитанций или `exec --continue`.
|
||||
|
||||
### Долгие задачи
|
||||
|
||||
`/goal` задаёт цель, которая сохраняется между ходами. Codewhale может
|
||||
@@ -201,7 +211,7 @@ Computer Use (экспериментальный, только macOS) может
|
||||
| Команда | Что делает |
|
||||
| --- | --- |
|
||||
| `codewhale` | Интерактивное терминальное приложение |
|
||||
| `codewhale exec "…"` | Одна задача без интерфейса. Сам по себе он отвечает, не используя инструменты; `--auto` позволяет ему редактировать файлы и выполнять команды, а `--output-format stream-json` выводит события потоком в формате JSON |
|
||||
| `codewhale exec "…"` | Одна задача без интерфейса. Сам по себе он отвечает, не используя инструменты; `--auto` по умолчанию включает инструменты с Full Access, `--sandbox workspace-write` ограничивает их, а `--output-format stream-json` выводит события потоком в формате JSON |
|
||||
| `codewhale web` | Локальный веб-интерфейс на `127.0.0.1` ([руководство](docs/WEB.md)) |
|
||||
| `codewhale review --pr N` | Рекомендательный обзор pull request на GitHub. Он ничего не публикует, если вы не добавите `--post`; [GitHub Action](docs/GITHUB_ACTION.md) выполняет тот же обзор в CI |
|
||||
| `codewhale app-server --http` | [Runtime API](docs/RUNTIME_API.md) — локальный HTTP API для тредов, событий, одобрений и изменений файлов в каждом ходе |
|
||||
|
||||
+15
-5
@@ -1,4 +1,4 @@
|
||||
<!-- source: README.md sha256:eefdc9e645b6 -->
|
||||
<!-- source: README.md sha256:30c9b9765b04 -->
|
||||
<div align="center">
|
||||
|
||||
<picture>
|
||||
@@ -88,11 +88,14 @@ değişikliklerini geri alır (0.10.1'de önce `/trust on` çalıştırın). `/h
|
||||
komutları ve tuşları listeler.
|
||||
|
||||
Betikler ve CI için `codewhale exec`, tek bir görevi arayüz olmadan çalıştırır.
|
||||
`--auto` ile dosyaları düzenler ve kabuk komutlarını sormadan çalıştırır; bu yüzden
|
||||
ona bir konteyner veya atılabilir bir checkout verin:
|
||||
Varsayılan olarak `--auto`, Full Access kullanır: araçlar sormadan çalışır,
|
||||
kabuk komutları için Codewhale korumalı alanı yoktur ve güven modu, dosya
|
||||
araçlarının çalışma alanı dışına yazmasına izin verir. Kabuk korumalı alanını
|
||||
ve dosya araçlarının çalışma alanı kısıtlamalarını güven modu kapalı olarak
|
||||
korumak için `--sandbox workspace-write` ekleyin:
|
||||
|
||||
```bash
|
||||
codewhale exec --auto "fix the failing tests and explain what changed"
|
||||
codewhale exec --auto --sandbox workspace-write "fix the failing tests and explain what changed"
|
||||
```
|
||||
|
||||
## Modlar ve izinler
|
||||
@@ -158,6 +161,13 @@ geri alır; 0.10.1'de dosyalar için `/trust on` gerektirir ve her seferinde bir
|
||||
döndürür; bu, sonraki düzenlemelerin üzerine yazdığı için `/trust on` veya Full
|
||||
Access gerektirir. Bkz. [Makbuzlar](docs/RECEIPTS.md).
|
||||
|
||||
Araçların kullanılabilir olduğu exec çalıştırmaları her çıktı biçiminde
|
||||
kaydedilir; böylece `codewhale receipts --last`, `--json` dahil olmak üzere
|
||||
`exec --auto` sonrasında çalışır. Yalnızca yanıt üreten metin ve `--json`
|
||||
çalıştırmaları ancak devam ettirilirken veya konuşma sıkıştırması başladığında
|
||||
kaydedilir; makbuzlar veya `exec --continue` için bunları her zaman kaydetmek
|
||||
üzere `--output-format stream-json` kullanın.
|
||||
|
||||
### Daha uzun işler
|
||||
|
||||
`/goal`, turlar boyunca geçerli kalan bir hedef belirler. Codewhale işi
|
||||
@@ -197,7 +207,7 @@ erişimini gözden geçirip etkinleştirene kadar kapalı kalır
|
||||
| Komut | Ne yapar |
|
||||
| --- | --- |
|
||||
| `codewhale` | Etkileşimli terminal uygulaması |
|
||||
| `codewhale exec "…"` | Arayüz olmadan tek bir görev. Tek başına araç kullanmadan yanıt verir; `--auto` dosyaları düzenlemesine ve komutları çalıştırmasına izin verir, `--output-format stream-json` olayları JSON olarak akış halinde verir |
|
||||
| `codewhale exec "…"` | Arayüz olmadan tek bir görev. Tek başına araç kullanmadan yanıt verir; `--auto` varsayılan olarak araçları Full Access ile etkinleştirir, `--sandbox workspace-write` bunları kısıtlar, `--output-format stream-json` olayları JSON olarak akış halinde verir |
|
||||
| `codewhale web` | `127.0.0.1` üzerinde yerel bir web arayüzü ([kılavuz](docs/WEB.md)) |
|
||||
| `codewhale review --pr N` | Bir GitHub pull request'inin tavsiye niteliğinde incelemesi. `--post` eklemediğiniz sürece hiçbir şey yayınlamaz; [GitHub Action](docs/GITHUB_ACTION.md) aynı incelemeyi CI'da çalıştırır |
|
||||
| `codewhale app-server --http` | [Runtime API](docs/RUNTIME_API.md); iş parçacıkları, olaylar, onaylar ve her turun dosya değişiklikleri için yerel bir HTTP API |
|
||||
|
||||
+16
-6
@@ -1,4 +1,4 @@
|
||||
<!-- source: README.md sha256:eefdc9e645b6 -->
|
||||
<!-- source: README.md sha256:30c9b9765b04 -->
|
||||
<div align="center">
|
||||
|
||||
<picture>
|
||||
@@ -89,12 +89,15 @@ Fix the failing tests and explain what changed.
|
||||
разом із його змінами у файлах (у 0.10.1 спершу виконайте `/trust on`). `/help`
|
||||
показує команди й клавіші.
|
||||
|
||||
Для скриптів і CI `codewhale exec` виконує одне завдання без інтерфейсу. З
|
||||
`--auto` він редагує файли й виконує команди оболонки без запиту, тож
|
||||
запускайте його в контейнері або в одноразовій робочій копії:
|
||||
Для скриптів і CI `codewhale exec` виконує одне завдання без інтерфейсу. За
|
||||
замовчуванням `--auto` використовує «Повний доступ»: інструменти виконуються
|
||||
без запиту, команди оболонки працюють без пісочниці Codewhale, а режим довіри
|
||||
дозволяє файловим інструментам записувати файли поза робочим простором. Додайте
|
||||
`--sandbox workspace-write`, щоб зберегти пісочницю оболонки й обмежити файлові
|
||||
інструменти робочим простором, вимкнувши режим довіри:
|
||||
|
||||
```bash
|
||||
codewhale exec --auto "fix the failing tests and explain what changed"
|
||||
codewhale exec --auto --sandbox workspace-write "fix the failing tests and explain what changed"
|
||||
```
|
||||
|
||||
## Режими й дозволи
|
||||
@@ -162,6 +165,13 @@ Google, Mistral, Moonshot, OpenRouter і xAI. Працює будь-яка OpenA
|
||||
збереженого знімка; оскільки це перезаписує пізніші зміни, потрібен
|
||||
`/trust on` або «Повний доступ». Див. [Квитанції](docs/RECEIPTS.md).
|
||||
|
||||
Запуски exec, у яких доступні інструменти, зберігаються за будь-якого формату
|
||||
виводу, тому `codewhale receipts --last` працює після `exec --auto`, зокрема
|
||||
з `--json`. Запуски без інструментів із текстовим виводом або `--json`
|
||||
зберігаються лише при відновленні або коли починається стиснення розмови;
|
||||
використовуйте `--output-format stream-json`, щоб завжди зберігати їх для
|
||||
квитанцій або `exec --continue`.
|
||||
|
||||
### Довші завдання
|
||||
|
||||
`/goal` задає ціль, яка зберігається між ходами. Codewhale може розподіляти
|
||||
@@ -203,7 +213,7 @@ Codewhale сам читає `AGENTS.md`. Файли інструкцій, нап
|
||||
| Команда | Що робить |
|
||||
| --- | --- |
|
||||
| `codewhale` | Інтерактивний термінальний застосунок |
|
||||
| `codewhale exec "…"` | Одне завдання без інтерфейсу. Без додаткових прапорців він відповідає, не використовуючи інструментів; `--auto` дозволяє йому редагувати файли й виконувати команди, а `--output-format stream-json` передає події потоком у форматі JSON |
|
||||
| `codewhale exec "…"` | Одне завдання без інтерфейсу. Без додаткових прапорців він відповідає, не використовуючи інструментів; `--auto` за замовчуванням вмикає інструменти з «Повним доступом», `--sandbox workspace-write` обмежує їх, а `--output-format stream-json` передає події потоком у форматі JSON |
|
||||
| `codewhale web` | Локальний вебінтерфейс на `127.0.0.1` ([посібник](docs/WEB.md)) |
|
||||
| `codewhale review --pr N` | Рекомендаційний огляд pull request у GitHub. Нічого не публікує, якщо не додати `--post`; [GitHub Action](docs/GITHUB_ACTION.md) виконує такий самий огляд у CI |
|
||||
| `codewhale app-server --http` | [Runtime API](docs/RUNTIME_API.md) — локальний HTTP API для тредів, подій, підтверджень і змін у файлах кожного ходу |
|
||||
|
||||
+16
-6
@@ -1,4 +1,4 @@
|
||||
<!-- source: README.md sha256:eefdc9e645b6 -->
|
||||
<!-- source: README.md sha256:30c9b9765b04 -->
|
||||
<div align="center">
|
||||
|
||||
<picture>
|
||||
@@ -86,12 +86,15 @@ trò chuyện, `n` từ chối. `/undo` hoàn tác yêu cầu gần nhất của
|
||||
đổi tệp của nó (ở 0.10.1, hãy chạy `/trust on` trước). `/help` liệt kê các lệnh
|
||||
và phím tắt.
|
||||
|
||||
Với script và CI, `codewhale exec` chạy một tác vụ mà không cần giao diện. Với
|
||||
`--auto`, nó chỉnh sửa tệp và chạy lệnh shell mà không hỏi, vì vậy hãy chạy nó
|
||||
trong một container hoặc một bản checkout dùng một lần:
|
||||
Với script và CI, `codewhale exec` chạy một tác vụ mà không cần giao diện. Theo
|
||||
mặc định, `--auto` dùng Full Access: công cụ chạy mà không hỏi, lệnh shell
|
||||
không bị sandbox của Codewhale giới hạn, và chế độ tin cậy cho phép công cụ
|
||||
tệp ghi ra ngoài không gian làm việc. Thêm `--sandbox workspace-write` để giữ
|
||||
sandbox cho shell và giới hạn công cụ tệp trong không gian làm việc, đồng thời
|
||||
tắt chế độ tin cậy:
|
||||
|
||||
```bash
|
||||
codewhale exec --auto "fix the failing tests and explain what changed"
|
||||
codewhale exec --auto --sandbox workspace-write "fix the failing tests and explain what changed"
|
||||
```
|
||||
|
||||
## Chế độ và quyền
|
||||
@@ -158,6 +161,13 @@ lại từng lệnh gọi công cụ một. `/restore` đưa toàn bộ không g
|
||||
snapshot trước đó; vì thao tác này ghi đè các chỉnh sửa sau đó, nó cần
|
||||
`/trust on` hoặc Full Access. Xem [Biên nhận](docs/RECEIPTS.md).
|
||||
|
||||
Các lần chạy exec có sẵn công cụ đều được lưu ở mọi định dạng đầu ra,
|
||||
vì vậy `codewhale receipts --last` dùng được sau `exec --auto`, kể cả khi dùng
|
||||
`--json`. Các lần chạy chỉ trả lời bằng văn bản hoặc `--json` chỉ được lưu khi
|
||||
tiếp tục cuộc trò chuyện hoặc khi bắt đầu nén cuộc trò chuyện; dùng
|
||||
`--output-format stream-json` để luôn lưu chúng cho biên nhận hoặc
|
||||
`exec --continue`.
|
||||
|
||||
### Công việc dài hơi
|
||||
|
||||
`/goal` đặt một mục tiêu được giữ qua các lượt. Codewhale có thể chia việc cho
|
||||
@@ -196,7 +206,7 @@ quyền truy cập của nó và bật nó lên
|
||||
| Lệnh | Chức năng |
|
||||
| --- | --- |
|
||||
| `codewhale` | Ứng dụng terminal tương tác |
|
||||
| `codewhale exec "…"` | Một tác vụ không có giao diện. Khi không kèm cờ, nó trả lời mà không dùng công cụ; `--auto` cho phép nó chỉnh sửa tệp và chạy lệnh, còn `--output-format stream-json` phát trực tiếp các sự kiện dưới dạng JSON |
|
||||
| `codewhale exec "…"` | Một tác vụ không có giao diện. Khi không kèm cờ, nó trả lời mà không dùng công cụ; `--auto` bật công cụ với Full Access theo mặc định, `--sandbox workspace-write` giới hạn chúng, còn `--output-format stream-json` phát trực tiếp các sự kiện dưới dạng JSON |
|
||||
| `codewhale web` | Giao diện web cục bộ tại `127.0.0.1` ([hướng dẫn](docs/WEB.md)) |
|
||||
| `codewhale review --pr N` | Đánh giá mang tính tham khảo cho một pull request trên GitHub. Nó không đăng gì trừ khi bạn thêm `--post`; [GitHub Action](docs/GITHUB_ACTION.md) chạy cùng kiểu đánh giá đó trong CI |
|
||||
| `codewhale app-server --http` | [Runtime API](docs/RUNTIME_API.md), một API HTTP cục bộ cho thread, sự kiện, phê duyệt và các thay đổi tệp của từng lượt |
|
||||
|
||||
+12
-5
@@ -1,4 +1,4 @@
|
||||
<!-- source: README.md sha256:eefdc9e645b6 -->
|
||||
<!-- source: README.md sha256:30c9b9765b04 -->
|
||||
<div align="center">
|
||||
|
||||
<picture>
|
||||
@@ -75,11 +75,13 @@ Fix the failing tests and explain what changed.
|
||||
`a` 在本次对话接下来的时间里允许类似的命令,`n` 拒绝。`/undo` 会撤销你的上一个请求及其
|
||||
文件改动(在 0.10.1 中,需先运行 `/trust on`)。`/help` 列出命令和按键。
|
||||
|
||||
在脚本和 CI 中,`codewhale exec` 不启动界面,只运行一个任务。加上 `--auto` 后,
|
||||
它会不经询问就编辑文件和运行 shell 命令,所以请在容器或一次性的检出副本中运行它:
|
||||
在脚本和 CI 中,`codewhale exec` 不启动界面,只运行一个任务。默认情况下,`--auto` 使用
|
||||
“完全访问”权限:工具不经询问就运行,shell 命令不受 Codewhale 沙箱限制,信任模式允许
|
||||
文件工具写入工作区之外的位置。加上 `--sandbox workspace-write` 可保留 shell 沙箱和
|
||||
文件工具的工作区限制,并关闭信任模式:
|
||||
|
||||
```bash
|
||||
codewhale exec --auto "fix the failing tests and explain what changed"
|
||||
codewhale exec --auto --sandbox workspace-write "fix the failing tests and explain what changed"
|
||||
```
|
||||
|
||||
## 模式与权限
|
||||
@@ -135,6 +137,11 @@ Web 和 MCP 调用、启动过的智能体、审批及审批人,以及失败
|
||||
在 0.10.1 中,撤销文件改动需要 `/trust on`,而且每次只回退一个工具调用。`/restore` 把整个工作区回滚到更早的快照;由于这会覆盖之后的编辑,它需要 `/trust on`
|
||||
或“完全访问”权限。参见[回执](docs/RECEIPTS.md)。
|
||||
|
||||
可使用工具的 exec 运行无论采用哪种输出格式都会保存,因此在 `exec --auto` 之后,
|
||||
包括使用 `--json` 时,`codewhale receipts --last` 都能正常工作。仅作答且使用文本输出或
|
||||
`--json` 的运行,只有在恢复对话或开始压缩对话时才会保存;使用
|
||||
`--output-format stream-json` 可始终保存这些运行,供回执或 `exec --continue` 使用。
|
||||
|
||||
### 更长的任务
|
||||
|
||||
`/goal` 设定一个跨回合持续有效的目标。Codewhale 可以把工作拆分给
|
||||
@@ -167,7 +174,7 @@ Codewhale 会自动读取 `AGENTS.md`。为其他工具编写的指令文件,
|
||||
| 命令 | 作用 |
|
||||
| --- | --- |
|
||||
| `codewhale` | 交互式终端应用 |
|
||||
| `codewhale exec "…"` | 不启动界面,运行一个任务。单独使用时,它只作答而不使用工具;`--auto` 允许它编辑文件和运行命令,`--output-format stream-json` 以 JSON 形式流式输出事件 |
|
||||
| `codewhale exec "…"` | 不启动界面,运行一个任务。单独使用时,它只作答而不使用工具;`--auto` 默认以“完全访问”权限启用工具,`--sandbox workspace-write` 对工具施加限制,`--output-format stream-json` 以 JSON 形式流式输出事件 |
|
||||
| `codewhale web` | 监听 `127.0.0.1` 的本地 Web 界面([指南](docs/WEB.md)) |
|
||||
| `codewhale review --pr N` | 对 GitHub PR 进行仅供参考的审查。除非你加上 `--post`,否则它不会发布任何内容;[GitHub Action](docs/GITHUB_ACTION.md) 会在 CI 中运行同样的审查 |
|
||||
| `codewhale app-server --http` | [Runtime API](docs/RUNTIME_API.md),用于对话线程、事件、审批以及每个回合文件改动的本地 HTTP API |
|
||||
|
||||
+12
-5
@@ -1,4 +1,4 @@
|
||||
<!-- source: README.md sha256:eefdc9e645b6 -->
|
||||
<!-- source: README.md sha256:30c9b9765b04 -->
|
||||
<div align="center">
|
||||
|
||||
<picture>
|
||||
@@ -74,11 +74,13 @@ Fix the failing tests and explain what changed.
|
||||
`a` 允許本次對話後續類似的指令,`n` 拒絕。`/undo` 會還原你上一個請求及其
|
||||
檔案變更(在 0.10.1 中,請先執行 `/trust on`)。`/help` 會列出指令與按鍵。
|
||||
|
||||
在腳本與 CI 中,`codewhale exec` 會在沒有介面的情況下執行一項任務。加上 `--auto` 後,
|
||||
它會在不詢問的情況下編輯檔案並執行 shell 指令,因此請讓它在容器或用完即丟的工作副本中執行:
|
||||
在腳本與 CI 中,`codewhale exec` 會在沒有介面的情況下執行一項任務。預設情況下,`--auto`
|
||||
使用「完整存取」權限:工具不經詢問就執行,shell 指令不受 Codewhale 沙箱限制,信任模式
|
||||
允許檔案工具寫入工作區以外的位置。加上 `--sandbox workspace-write` 即可保留 shell 沙箱
|
||||
與檔案工具的工作區限制,並關閉信任模式:
|
||||
|
||||
```bash
|
||||
codewhale exec --auto "fix the failing tests and explain what changed"
|
||||
codewhale exec --auto --sandbox workspace-write "fix the failing tests and explain what changed"
|
||||
```
|
||||
|
||||
## 模式與權限
|
||||
@@ -134,6 +136,11 @@ OpenRouter 與 xAI。任何相容 OpenAI 的端點都能使用,透過 Ollama
|
||||
在 0.10.1 中,還原檔案需要 `/trust on`,而且每次只退回一個工具呼叫。`/restore` 會把整個工作區回復到先前的快照;由於這會覆寫之後的編輯,因此需要 `/trust on`
|
||||
或「完整存取」。請參閱[回條](docs/RECEIPTS.md)。
|
||||
|
||||
可使用工具的 exec 執行紀錄無論採用哪種輸出格式都會儲存,因此在 `exec --auto` 之後,
|
||||
包括使用 `--json` 時,`codewhale receipts --last` 都能正常運作。只回答且使用文字輸出或
|
||||
`--json` 的執行紀錄,只有在繼續先前的對話或開始壓縮對話時才會儲存;使用
|
||||
`--output-format stream-json` 即可一律儲存這些紀錄,供回條或 `exec --continue` 使用。
|
||||
|
||||
### 長時間工作
|
||||
|
||||
`/goal` 會設定一個跨回合延續的目標。Codewhale 可以把工作分給[子代理](docs/SUBAGENTS.md)、
|
||||
@@ -166,7 +173,7 @@ Codewhale 發現這類檔案卻沒有載入時,會發出警告。
|
||||
| 指令 | 作用 |
|
||||
| --- | --- |
|
||||
| `codewhale` | 互動式終端機應用程式 |
|
||||
| `codewhale exec "…"` | 在沒有介面的情況下執行一項任務。單獨使用時,它只回答、不使用工具;`--auto` 讓它編輯檔案並執行指令,`--output-format stream-json` 以 JSON 串流輸出事件 |
|
||||
| `codewhale exec "…"` | 在沒有介面的情況下執行一項任務。單獨使用時,它只回答、不使用工具;`--auto` 預設以「完整存取」權限啟用工具,`--sandbox workspace-write` 對工具加以限制,`--output-format stream-json` 以 JSON 串流輸出事件 |
|
||||
| `codewhale web` | 在 `127.0.0.1` 上的本機 Web UI([指南](docs/WEB.md)) |
|
||||
| `codewhale review --pr N` | 對 GitHub PR(Pull Request)進行僅供參考的審查。除非你加上 `--post`,否則不會張貼任何內容;[GitHub Action](docs/GITHUB_ACTION.md) 會在 CI 中執行相同的審查 |
|
||||
| `codewhale app-server --http` | [Runtime API](docs/RUNTIME_API.md),用於執行緒、事件、核准與每個回合檔案變更的本機 HTTP API |
|
||||
|
||||
+26
-4
@@ -246,7 +246,8 @@ Run options such as --model, --provider, --config and --profile work before or a
|
||||
codewhale exec --model MODEL \"explain this function\"
|
||||
|
||||
Common forwarded flags:
|
||||
--auto Enable tool-backed agent mode with auto-approvals
|
||||
--auto Enable tools with automatic approvals and Full Access by default
|
||||
--sandbox <POLICY> Override the sandbox policy for this run
|
||||
--json Emit summary JSON
|
||||
--resume <SESSION_ID> Resume a previous session by ID or prefix
|
||||
--session-id <SESSION_ID> Resume a previous session by ID or prefix
|
||||
@@ -254,9 +255,17 @@ Common forwarded flags:
|
||||
--output-format <FORMAT> Output format: text or stream-json
|
||||
--hooks Opt in to configured hooks (tool_call_before, shell_env)
|
||||
|
||||
Plain `codewhale exec` is a one-shot model response. Use `--auto` for
|
||||
non-interactive filesystem/shell tool use, matching the supported automation
|
||||
path used by stream-json wrappers.
|
||||
Plain `codewhale exec` is a one-shot model response: one Engine turn with the
|
||||
same system prompt as every other run, and no tools. Use `--auto` for
|
||||
non-interactive agent-with-tools execution. Tools are offered only with
|
||||
`--auto`, `--yolo`, `--allowed-tools`, or when resuming a session; limits such
|
||||
as `--max-turns`, `--disallowed-tools` or `--sandbox`, and the output format,
|
||||
never add tools. A reply cut off at the provider's output limit is continued
|
||||
in the same turn, at most 8 model steps unless `--max-turns` says otherwise.
|
||||
--auto defaults to Full Access: no shell sandbox and trust mode on. Use --sandbox workspace-write to keep the shell sandbox and file-tool workspace restrictions; stricter configured policies also apply. A denied sandbox retry requires --allow-sandbox-elevation or --sandbox danger-full-access.
|
||||
Any --sandbox other than danger-full-access (or an equivalent sandbox_mode in config) disables trust mode.
|
||||
Runs that offer tools, stream-json runs, and resumed sessions are saved for codewhale sessions, exec --continue, and codewhale receipts <id>. Plain answer-only text/--json runs are not saved unless compaction needs recovery.
|
||||
Put flags before the prompt. Put -- before a prompt starting with - or containing literal exec flags.
|
||||
")]
|
||||
Exec(TuiPassthroughArgs),
|
||||
/// Manage durable Agent fleet runs.
|
||||
@@ -13231,6 +13240,19 @@ verbosity = "concise"
|
||||
assert!(exec.contains("work before or after exec"), "{exec}");
|
||||
assert!(exec.contains("codewhale --model MODEL exec"), "{exec}");
|
||||
assert!(exec.contains("codewhale exec --model MODEL"), "{exec}");
|
||||
assert!(exec.contains("--sandbox <POLICY>"), "{exec}");
|
||||
assert!(exec.contains("Full Access"), "{exec}");
|
||||
assert!(
|
||||
exec.contains("no shell sandbox and trust mode on"),
|
||||
"{exec}"
|
||||
);
|
||||
assert!(
|
||||
exec.contains("Any --sandbox other than danger-full-access"),
|
||||
"{exec}"
|
||||
);
|
||||
assert!(exec.contains("equivalent sandbox_mode in config"), "{exec}");
|
||||
assert!(exec.contains("Put flags before the prompt"), "{exec}");
|
||||
assert!(exec.contains("codewhale receipts <id>"), "{exec}");
|
||||
let rc = help_for(&["codewhale", "rc", "--help"]);
|
||||
assert!(rc.contains("hand it to the Codewhale web app"), "{rc}");
|
||||
}
|
||||
|
||||
@@ -2567,5 +2567,10 @@
|
||||
"PluginOAuthReady": "{provider}: sessió iniciada. Tria un model.",
|
||||
"PluginOAuthLocalLogout": "{provider}: sessió local eliminada. L’accés remot no ha canviat.",
|
||||
"CmdConnectDescription": "Connecta un proveïdor de plugins amb inici de sessió al navegador",
|
||||
"CmdDisconnectDescription": "Elimina l’inici de sessió local d’un proveïdor de plugins"
|
||||
"CmdDisconnectDescription": "Elimina l’inici de sessió local d’un proveïdor de plugins",
|
||||
"ExecAutoHelp": "Activa eines amb aprovació automàtica i Full Access (sense sandbox del shell i amb el mode de confiança activat), llevat que hi hagi un sandbox més restrictiu configurat; fes servir --sandbox workspace-write per restringir les escriptures de fitxers i del shell.",
|
||||
"ExecSandboxHelp": "Política de sandbox d’aquesta execució; qualsevol --sandbox diferent de danger-full-access (o un sandbox_mode equivalent a la configuració) desactiva el mode de confiança.",
|
||||
"ExecAfterHelp": "Exemples:\n codewhale exec \"explica aquesta funció\"\n codewhale exec --auto \"llista crates/ amb ls\"\n codewhale exec --auto --output-format stream-json \"corregeix la prova que falla\"\n\n`codewhale exec` sense opcions produeix una única resposta del model: un torn\ndel motor Engine amb el mateix prompt de sistema que les altres execucions i\nsense eines. Fes servir `--auto` per executar un agent amb eines sense interacció.\nNomés s’ofereixen eines amb `--auto`, `--yolo`, `--allowed-tools` o en reprendre\nuna sessió; límits com `--max-turns`, `--disallowed-tools` o `--sandbox`, i el\nformat de sortida, no afegeixen mai eines. Una resposta tallada pel límit de\nsortida del proveïdor continua en el mateix torn, amb un màxim de 8 passos\ndel model, llevat que `--max-turns` indiqui un altre valor.\n--auto fa servir Full Access per defecte: sense sandbox del shell i amb el mode de confiança activat. Fes servir --sandbox workspace-write per mantenir el sandbox del shell i les restriccions de les eines de fitxers a l’espai de treball; també s’apliquen les polítiques més restrictives configurades. Tornar a provar una operació denegada pel sandbox requereix --allow-sandbox-elevation o --sandbox danger-full-access.\nLes execucions que ofereixen eines, les execucions stream-json i les sessions represes es desen per a codewhale sessions, exec --continue i codewhale receipts <id>. Les execucions text/--json que només responen no es desen, llevat que la compactació necessiti dades de recuperació.\nQualsevol --sandbox diferent de danger-full-access (o un sandbox_mode equivalent a la configuració) desactiva el mode de confiança.\n",
|
||||
"ExecPromptHelp": "Indicació que s’enviarà al model. Posa -- abans d’una indicació que comenci amb - o contingui una opció literal d’exec; fes servir --prompt-file - per llegir l’entrada estàndard.",
|
||||
"ExecFlagAfterPrompt": "{flag} apareix després de la indicació i es tractaria com a text. Posa les opcions abans de la indicació o, per usar-les com a text literal, després de --."
|
||||
}
|
||||
@@ -2567,5 +2567,10 @@
|
||||
"PluginOAuthReady": "{provider}: angemeldet. Wählen Sie ein Modell.",
|
||||
"PluginOAuthLocalLogout": "{provider}: lokale Anmeldung entfernt. Der Fernzugriff bleibt unverändert.",
|
||||
"CmdConnectDescription": "Plugin-Anbieter per Browser-Anmeldung verbinden",
|
||||
"CmdDisconnectDescription": "Lokale Anmeldung eines Plugin-Anbieters entfernen"
|
||||
"CmdDisconnectDescription": "Lokale Anmeldung eines Plugin-Anbieters entfernen",
|
||||
"ExecAutoHelp": "Aktiviert Tools mit automatischer Genehmigung und Full Access (keine Shell-Sandbox, Vertrauensmodus aktiv), sofern keine strengere Sandbox konfiguriert ist; --sandbox workspace-write beschränkt Schreibzugriffe von Datei-Tools und Shell.",
|
||||
"ExecSandboxHelp": "Sandbox-Richtlinie für diesen Lauf; jedes --sandbox außer danger-full-access (oder ein entsprechender sandbox_mode in der Konfiguration) deaktiviert den Vertrauensmodus.",
|
||||
"ExecAfterHelp": "Beispiele:\n codewhale exec \"erkläre diese Funktion\"\n codewhale exec --auto \"liste crates/ mit ls auf\"\n codewhale exec --auto --output-format stream-json \"behebe den fehlschlagenden Test\"\n\nEin einfaches `codewhale exec` liefert eine einmalige Modellantwort: einen\nEngine-Turn mit demselben System-Prompt wie andere Läufe und ohne Tools.\nMit `--auto` wird ein Agent mit Tools ohne Interaktion ausgeführt. Tools\nwerden nur mit `--auto`, `--yolo`, `--allowed-tools` oder beim Fortsetzen einer\nSitzung angeboten; Grenzen wie `--max-turns`, `--disallowed-tools` oder\n`--sandbox` sowie das Ausgabeformat fügen niemals Tools hinzu. Eine durch das\nAusgabelimit des Anbieters abgeschnittene Antwort wird im selben Turn\nfortgesetzt, mit höchstens 8 Modellschritten, sofern `--max-turns` nichts\nanderes vorgibt.\n--auto verwendet standardmäßig Full Access: keine Shell-Sandbox und aktiver Vertrauensmodus. Mit --sandbox workspace-write bleiben die Shell-Sandbox und die Arbeitsbereichsbeschränkungen der Datei-Tools erhalten; strengere konfigurierte Richtlinien gelten ebenfalls. Ein erneuter Versuch nach einer Sandbox-Verweigerung erfordert --allow-sandbox-elevation oder --sandbox danger-full-access.\nLäufe mit angebotenen Tools, stream-json-Läufe und fortgesetzte Sitzungen werden für codewhale sessions, exec --continue und codewhale receipts <id> gespeichert. Reine Antwortläufe mit text/--json werden nicht gespeichert, es sei denn, die Komprimierung benötigt Wiederherstellungsdaten.\nJedes --sandbox außer danger-full-access (oder ein entsprechender sandbox_mode in der Konfiguration) deaktiviert den Vertrauensmodus.\n",
|
||||
"ExecPromptHelp": "Prompt für das Modell. Setze -- vor einen Prompt, der mit - beginnt oder eine exec-Option als wörtlichen Text enthält; --prompt-file - liest die Standardeingabe.",
|
||||
"ExecFlagAfterPrompt": "{flag} steht nach dem Prompt und würde als Text behandelt. Setze Optionen vor den Prompt oder wörtlichen Optionstext nach --."
|
||||
}
|
||||
@@ -2567,5 +2567,10 @@
|
||||
"PluginOAuthReady": "{provider}: connected. Choose a model.",
|
||||
"PluginOAuthLocalLogout": "{provider}: disconnected on this device. Remote access is unchanged.",
|
||||
"CmdConnectDescription": "Connect a plugin provider with browser sign-in",
|
||||
"CmdDisconnectDescription": "Remove a plugin provider's local sign-in"
|
||||
"CmdDisconnectDescription": "Remove a plugin provider's local sign-in",
|
||||
"ExecAutoHelp": "Enable tools with automatic approvals and Full Access (no shell sandbox, trust mode on), unless a stricter sandbox is configured; use --sandbox workspace-write to restrict file and shell writes.",
|
||||
"ExecSandboxHelp": "Sandbox policy for this run; any --sandbox other than danger-full-access (or an equivalent sandbox_mode in config) disables trust mode.",
|
||||
"ExecAfterHelp": "Examples:\n codewhale exec \"explain this function\"\n codewhale exec --auto \"list crates/ with ls\"\n codewhale exec --auto --output-format stream-json \"fix the failing test\"\n\nPlain `codewhale exec` is a one-shot model response: one Engine turn with the\nsame system prompt as every other run, and no tools. Use `--auto` for\nnon-interactive agent-with-tools execution. Tools are offered only with\n`--auto`, `--yolo`, `--allowed-tools`, or when resuming a session; limits such\nas `--max-turns`, `--disallowed-tools` or `--sandbox`, and the output format,\nnever add tools. A reply cut off at the provider's output limit is continued\nin the same turn, at most 8 model steps unless `--max-turns` says otherwise.\n--auto defaults to Full Access: no shell sandbox and trust mode on. Use --sandbox workspace-write to keep the shell sandbox and file-tool workspace restrictions; stricter configured policies also apply. A denied sandbox retry requires --allow-sandbox-elevation or --sandbox danger-full-access.\nRuns that offer tools, stream-json runs, and resumed sessions are saved for codewhale sessions, exec --continue, and codewhale receipts <id>. Plain answer-only text/--json runs are not saved unless compaction needs recovery.\nAny --sandbox other than danger-full-access (or an equivalent sandbox_mode in config) disables trust mode.\n",
|
||||
"ExecPromptHelp": "Prompt to send to the model. Put -- before a prompt starting with - or containing a literal exec flag; use --prompt-file - to read stdin.",
|
||||
"ExecFlagAfterPrompt": "{flag} appears after the prompt and would be treated as text. Put flags before the prompt, or put literal flag text after --."
|
||||
}
|
||||
@@ -2567,5 +2567,10 @@
|
||||
"PluginOAuthReady": "{provider}: sesión iniciada. Elige un modelo.",
|
||||
"PluginOAuthLocalLogout": "{provider}: se eliminó la sesión local. El acceso remoto no cambió.",
|
||||
"CmdConnectDescription": "Conecta un proveedor de plugins con inicio de sesión en el navegador",
|
||||
"CmdDisconnectDescription": "Elimina el inicio de sesión local de un proveedor de plugins"
|
||||
"CmdDisconnectDescription": "Elimina el inicio de sesión local de un proveedor de plugins",
|
||||
"ExecAutoHelp": "Activa herramientas con aprobación automática y Full Access (sin sandbox del shell, modo de confianza activado), salvo que haya un sandbox más restrictivo configurado; usa --sandbox workspace-write para restringir escrituras de archivos y del shell.",
|
||||
"ExecSandboxHelp": "Política de sandbox para esta ejecución; cualquier --sandbox distinto de danger-full-access (o un sandbox_mode equivalente en la configuración) desactiva el modo de confianza.",
|
||||
"ExecAfterHelp": "Ejemplos:\n codewhale exec \"explica esta función\"\n codewhale exec --auto \"lista crates/ con ls\"\n codewhale exec --auto --output-format stream-json \"corrige la prueba que falla\"\n\n`codewhale exec` sin opciones genera una única respuesta del modelo: un turno\ndel Engine con el mismo prompt del sistema que las demás ejecuciones y sin\nherramientas. Usa `--auto` para ejecutar un agente con herramientas sin interacción.\nSolo se ofrecen herramientas con `--auto`, `--yolo`, `--allowed-tools` o al\nreanudar una sesión; límites como `--max-turns`, `--disallowed-tools` o\n`--sandbox`, y el formato de salida, nunca agregan herramientas. Una respuesta\ncortada por el límite de salida del proveedor continúa en el mismo turno,\ncon un máximo de 8 pasos del modelo salvo que `--max-turns` indique otro valor.\n--auto usa Full Access de forma predeterminada: sin sandbox del shell y con el modo de confianza activado. Usa --sandbox workspace-write para mantener el sandbox del shell y las restricciones de las herramientas de archivos al espacio de trabajo; también se aplican las políticas más restrictivas configuradas. Reintentar una operación denegada por el sandbox requiere --allow-sandbox-elevation o --sandbox danger-full-access.\nLas ejecuciones que ofrecen herramientas, las ejecuciones stream-json y las sesiones reanudadas se guardan para codewhale sessions, exec --continue y codewhale receipts <id>. Las ejecuciones text/--json que solo responden no se guardan, a menos que la compactación necesite datos de recuperación.\nCualquier --sandbox distinto de danger-full-access (o un sandbox_mode equivalente en la configuración) desactiva el modo de confianza.\n",
|
||||
"ExecPromptHelp": "Prompt que se enviará al modelo. Coloca -- antes de un prompt que empiece con - o contenga una opción literal de exec; usa --prompt-file - para leer la entrada estándar.",
|
||||
"ExecFlagAfterPrompt": "{flag} aparece después del prompt y se trataría como texto. Coloca las opciones antes del prompt o, para usarlas como texto literal, después de --."
|
||||
}
|
||||
@@ -2567,5 +2567,10 @@
|
||||
"PluginOAuthReady": "{provider} : connexion établie. Choisissez un modèle.",
|
||||
"PluginOAuthLocalLogout": "{provider} : connexion locale supprimée. L’accès distant reste inchangé.",
|
||||
"CmdConnectDescription": "Connecter un fournisseur de plugin par connexion dans le navigateur",
|
||||
"CmdDisconnectDescription": "Supprimer la connexion locale d’un fournisseur de plugin"
|
||||
"CmdDisconnectDescription": "Supprimer la connexion locale d’un fournisseur de plugin",
|
||||
"ExecAutoHelp": "Active les outils avec approbation automatique et Full Access (sans bac à sable du shell, mode de confiance activé), sauf si un bac à sable plus strict est configuré ; utilisez --sandbox workspace-write pour limiter les écritures des outils de fichiers et du shell.",
|
||||
"ExecSandboxHelp": "Politique de sandbox pour cette exécution ; tout --sandbox autre que danger-full-access (ou un sandbox_mode équivalent dans la configuration) désactive le mode de confiance.",
|
||||
"ExecAfterHelp": "Exemples :\n codewhale exec \"explique cette fonction\"\n codewhale exec --auto \"liste crates/ avec ls\"\n codewhale exec --auto --output-format stream-json \"corrige le test en échec\"\n\n`codewhale exec` seul produit une réponse unique du modèle : un tour Engine\navec la même instruction système que les autres exécutions, sans outils.\nUtilisez `--auto` pour exécuter un agent avec outils sans interaction.\nLes outils sont proposés uniquement avec `--auto`, `--yolo`, `--allowed-tools`\nou lors de la reprise d’une session ; les limites comme `--max-turns`,\n`--disallowed-tools` ou `--sandbox`, ainsi que le format de sortie, n’ajoutent\njamais d’outils. Une réponse interrompue par la limite de sortie du fournisseur\nse poursuit dans le même tour, avec au plus 8 étapes du modèle, sauf indication\ncontraire de `--max-turns`.\n--auto utilise Full Access par défaut : aucun bac à sable du shell et mode de confiance activé. Utilisez --sandbox workspace-write pour conserver le bac à sable du shell et les restrictions des outils de fichiers à l’espace de travail ; les politiques configurées plus strictes s’appliquent aussi. Réessayer une opération refusée par le bac à sable nécessite --allow-sandbox-elevation ou --sandbox danger-full-access.\nLes exécutions proposant des outils, les exécutions stream-json et les sessions reprises sont enregistrées pour codewhale sessions, exec --continue et codewhale receipts <id>. Les exécutions text/--json qui ne font que répondre ne sont pas enregistrées, sauf si la compaction nécessite des données de récupération.\nTout --sandbox autre que danger-full-access (ou un sandbox_mode équivalent dans la configuration) désactive le mode de confiance.\n",
|
||||
"ExecPromptHelp": "Prompt à envoyer au modèle. Placez -- avant un prompt qui commence par - ou contient une option exec comme texte littéral ; utilisez --prompt-file - pour lire l’entrée standard.",
|
||||
"ExecFlagAfterPrompt": "{flag} apparaît après le prompt et serait traité comme du texte. Placez les options avant le prompt, ou le texte littéral d’une option après --."
|
||||
}
|
||||
@@ -2567,5 +2567,10 @@
|
||||
"PluginOAuthReady": "{provider}: साइन इन हो गया। मॉडल चुनें।",
|
||||
"PluginOAuthLocalLogout": "{provider}: स्थानीय साइन इन हटाया गया। दूरस्थ पहुँच नहीं बदली है।",
|
||||
"CmdConnectDescription": "ब्राउज़र साइन-इन से किसी प्लगइन प्रदाता को जोड़ें",
|
||||
"CmdDisconnectDescription": "किसी प्लगइन प्रदाता का स्थानीय साइन-इन हटाएँ"
|
||||
"CmdDisconnectDescription": "किसी प्लगइन प्रदाता का स्थानीय साइन-इन हटाएँ",
|
||||
"ExecAutoHelp": "अपने-आप मंज़ूरी और Full Access (शेल सैंडबॉक्स नहीं, भरोसा मोड चालू) के साथ टूल चालू करें, जब तक कोई अधिक सख्त सैंडबॉक्स कॉन्फ़िगर न हो; फ़ाइल और शेल से लिखने को सीमित करने के लिए --sandbox workspace-write इस्तेमाल करें।",
|
||||
"ExecSandboxHelp": "इस रन की sandbox नीति; danger-full-access के अलावा कोई भी --sandbox (या कॉन्फ़िगरेशन में समान sandbox_mode) ट्रस्ट मोड बंद करता है।",
|
||||
"ExecAfterHelp": "उदाहरण:\n codewhale exec \"इस फ़ंक्शन को समझाएँ\"\n codewhale exec --auto \"ls से crates/ की सूची दिखाएँ\"\n codewhale exec --auto --output-format stream-json \"विफल हो रहा टेस्ट ठीक करें\"\n\nसामान्य `codewhale exec` मॉडल से एक बार जवाब लेता है: अन्य रन वाले ही सिस्टम\nप्रॉम्प्ट के साथ Engine का एक टर्न, बिना टूल के। बिना इंटरैक्शन के टूल वाले\nएजेंट को चलाने के लिए `--auto` इस्तेमाल करें। टूल केवल `--auto`, `--yolo`,\n`--allowed-tools` के साथ या सत्र फिर शुरू करने पर उपलब्ध होते हैं;\n`--max-turns`, `--disallowed-tools` या `--sandbox` जैसी सीमाएँ और आउटपुट\nफ़ॉर्मैट कभी टूल नहीं जोड़ते। प्रदाता की आउटपुट सीमा से कटे जवाब को उसी टर्न\nमें आगे जारी रखा जाता है। `--max-turns` से अन्य सीमा न देने पर मॉडल के\nअधिकतम 8 चरण होते हैं।\n--auto डिफ़ॉल्ट रूप से Full Access इस्तेमाल करता है: शेल सैंडबॉक्स नहीं और भरोसा मोड चालू। शेल सैंडबॉक्स और फ़ाइल टूल की कार्यक्षेत्र संबंधी पाबंदियाँ बनाए रखने के लिए --sandbox workspace-write इस्तेमाल करें; कॉन्फ़िगर की गई अधिक सख्त नीतियाँ भी लागू होती हैं। सैंडबॉक्स द्वारा रोकी गई कार्रवाई दोबारा आज़माने के लिए --allow-sandbox-elevation या --sandbox danger-full-access ज़रूरी है।\nटूल उपलब्ध कराने वाले रन, stream-json रन और फिर शुरू किए गए सत्र सहेजे जाते हैं, ताकि codewhale sessions, exec --continue और codewhale receipts <id> में उनका उपयोग हो सके। केवल जवाब देने वाले सामान्य text/--json रन नहीं सहेजे जाते, जब तक संदर्भ संपीड़न के लिए पुनर्प्राप्ति डेटा की ज़रूरत न हो।\ndanger-full-access के अलावा कोई भी --sandbox (या कॉन्फ़िगरेशन में समान sandbox_mode) ट्रस्ट मोड बंद करता है।\n",
|
||||
"ExecPromptHelp": "मॉडल को भेजने वाला प्रॉम्प्ट। - से शुरू होने वाले या exec फ़्लैग को सामान्य टेक्स्ट के रूप में रखने वाले प्रॉम्प्ट से पहले -- लगाएँ; मानक इनपुट पढ़ने के लिए --prompt-file - का उपयोग करें।",
|
||||
"ExecFlagAfterPrompt": "{flag} प्रॉम्प्ट के बाद है और टेक्स्ट माना जाएगा। फ़्लैग प्रॉम्प्ट से पहले रखें, या फ़्लैग को सामान्य टेक्स्ट के रूप में भेजने के लिए उसे -- के बाद रखें।"
|
||||
}
|
||||
@@ -2567,5 +2567,10 @@
|
||||
"PluginOAuthReady": "{provider}: berhasil masuk. Pilih model.",
|
||||
"PluginOAuthLocalLogout": "{provider}: data masuk lokal dihapus. Akses jarak jauh tidak berubah.",
|
||||
"CmdConnectDescription": "Hubungkan penyedia plugin dengan masuk lewat peramban",
|
||||
"CmdDisconnectDescription": "Hapus data masuk lokal penyedia plugin"
|
||||
"CmdDisconnectDescription": "Hapus data masuk lokal penyedia plugin",
|
||||
"ExecAutoHelp": "Aktifkan alat dengan persetujuan otomatis dan Full Access (tanpa sandbox shell, mode kepercayaan aktif), kecuali sandbox yang lebih ketat telah dikonfigurasi; gunakan --sandbox workspace-write untuk membatasi penulisan oleh alat berkas dan shell.",
|
||||
"ExecSandboxHelp": "Kebijakan sandbox untuk proses ini; setiap --sandbox selain danger-full-access (atau sandbox_mode yang setara dalam konfigurasi) menonaktifkan mode kepercayaan.",
|
||||
"ExecAfterHelp": "Contoh:\n codewhale exec \"jelaskan fungsi ini\"\n codewhale exec --auto \"tampilkan isi crates/ dengan ls\"\n codewhale exec --auto --output-format stream-json \"perbaiki pengujian yang gagal\"\n\n`codewhale exec` biasa menghasilkan satu respons model: satu giliran Engine\ndengan prompt sistem yang sama seperti eksekusi lain, tanpa alat. Gunakan\n`--auto` untuk menjalankan agen dengan alat secara noninteraktif. Alat hanya\ndisediakan dengan `--auto`, `--yolo`, `--allowed-tools`, atau saat melanjutkan\nsesi; batas seperti `--max-turns`, `--disallowed-tools`, atau `--sandbox`, dan\nformat keluaran, tidak pernah menambahkan alat. Respons yang terpotong karena\nbatas keluaran penyedia dilanjutkan dalam giliran yang sama, hingga 8 langkah\nmodel kecuali `--max-turns` menentukan batas lain.\n--auto menggunakan Full Access secara bawaan: tanpa sandbox shell dan dengan mode kepercayaan aktif. Gunakan --sandbox workspace-write untuk mempertahankan sandbox shell dan pembatasan alat berkas pada ruang kerja; kebijakan lebih ketat yang dikonfigurasi juga berlaku. Mencoba ulang operasi yang ditolak sandbox memerlukan --allow-sandbox-elevation atau --sandbox danger-full-access.\nEksekusi yang menyediakan alat, eksekusi stream-json, dan sesi yang dilanjutkan disimpan untuk codewhale sessions, exec --continue, dan codewhale receipts <id>. Eksekusi text/--json biasa yang hanya memberikan jawaban tidak disimpan, kecuali pemadatan memerlukan data pemulihan.\nSetiap --sandbox selain danger-full-access (atau sandbox_mode yang setara dalam konfigurasi) menonaktifkan mode kepercayaan.\n",
|
||||
"ExecPromptHelp": "Prompt untuk dikirim ke model. Letakkan -- sebelum prompt yang diawali - atau memuat flag exec sebagai teks literal; gunakan --prompt-file - untuk membaca input standar.",
|
||||
"ExecFlagAfterPrompt": "{flag} muncul setelah prompt dan akan dianggap sebagai teks. Letakkan flag sebelum prompt, atau letakkan flag yang dimaksudkan sebagai teks literal setelah --."
|
||||
}
|
||||
@@ -2567,5 +2567,10 @@
|
||||
"PluginOAuthReady": "{provider}:ログインしました。モデルを選択してください。",
|
||||
"PluginOAuthLocalLogout": "{provider}:この端末の認証情報を削除しました。サーバーの認可は解除されていません。",
|
||||
"CmdConnectDescription": "ブラウザーのログインでプラグインプロバイダーに接続します",
|
||||
"CmdDisconnectDescription": "プラグインプロバイダーのこの端末のログイン情報を削除します"
|
||||
"CmdDisconnectDescription": "プラグインプロバイダーのこの端末のログイン情報を削除します",
|
||||
"ExecAutoHelp": "ツールを自動承認と Full Access(シェルのサンドボックスなし、信頼モード有効)で有効にします。より厳しいサンドボックス設定がある場合はそれに従います。ファイルとシェルの書き込みを制限するには --sandbox workspace-write を指定してください。",
|
||||
"ExecSandboxHelp": "この実行のサンドボックスポリシー。danger-full-access 以外の --sandbox(または設定内の同等の sandbox_mode)は信頼モードを無効にします。",
|
||||
"ExecAfterHelp": "使用例:\n codewhale exec \"この関数を説明して\"\n codewhale exec --auto \"ls で crates/ の内容を表示して\"\n codewhale exec --auto --output-format stream-json \"失敗しているテストを修正して\"\n\n通常の `codewhale exec` はモデルの単発応答です。他の実行と同じシステム\nプロンプトを使い、ツールなしで Engine を 1 ターン実行します。対話なしで\nツールを使うエージェントを実行するには `--auto` を指定してください。\nツールが提供されるのは `--auto`、`--yolo`、`--allowed-tools` の指定時、\nまたはセッションの再開時のみです。`--max-turns`、`--disallowed-tools`、\n`--sandbox` などの制限や出力形式を指定してもツールは追加されません。\nプロバイダーの出力上限で途切れた応答は同じターン内で続行されます。\n`--max-turns` で変更しない限り、モデルのステップ数は最大 8 回です。\n--auto は既定で Full Access です。シェルのサンドボックスはなく、信頼モードが有効です。シェルのサンドボックスと、ファイルツールのワークスペース制限を維持するには --sandbox workspace-write を指定してください。設定済みのより厳しいポリシーも適用されます。サンドボックスで拒否された操作の再試行には --allow-sandbox-elevation または --sandbox danger-full-access が必要です。\nツールを提供する実行、stream-json の実行、再開したセッションは保存され、codewhale sessions、exec --continue、codewhale receipts <id> で利用できます。応答のみの text/--json 実行は、圧縮時に復旧用の保存が必要な場合を除いて保存されません。\ndanger-full-access 以外の --sandbox(または設定内の同等の sandbox_mode)は信頼モードを無効にします。\n",
|
||||
"ExecPromptHelp": "モデルに送信するプロンプト。- で始まる場合や exec のフラグを文字列として含む場合は、プロンプトの前に -- を置いてください。標準入力を読むには --prompt-file - を使用してください。",
|
||||
"ExecFlagAfterPrompt": "{flag} がプロンプトの後にあり、文字列として扱われます。フラグはプロンプトの前に置くか、文字列として渡す場合は -- の後に置いてください。"
|
||||
}
|
||||
@@ -2567,5 +2567,10 @@
|
||||
"PluginOAuthReady": "{provider}: 로그인했습니다. 모델을 선택하세요.",
|
||||
"PluginOAuthLocalLogout": "{provider}: 이 기기의 로그인 정보를 삭제했습니다. 서버 권한은 유지됩니다.",
|
||||
"CmdConnectDescription": "브라우저 로그인으로 플러그인 제공자를 연결합니다",
|
||||
"CmdDisconnectDescription": "플러그인 제공자의 이 기기 로그인 정보를 삭제합니다"
|
||||
"CmdDisconnectDescription": "플러그인 제공자의 이 기기 로그인 정보를 삭제합니다",
|
||||
"ExecAutoHelp": "더 엄격한 샌드박스가 설정되어 있지 않으면 자동 승인과 Full Access(셸 샌드박스 없음, 신뢰 모드 켜짐)로 도구를 활성화합니다. 파일 및 셸 쓰기를 제한하려면 --sandbox workspace-write를 사용하세요.",
|
||||
"ExecSandboxHelp": "이번 실행의 샌드박스 정책입니다. danger-full-access 이외의 --sandbox(또는 설정의 동등한 sandbox_mode)는 신뢰 모드를 끕니다.",
|
||||
"ExecAfterHelp": "예시:\n codewhale exec \"이 함수를 설명해 줘\"\n codewhale exec --auto \"ls로 crates/ 목록을 보여 줘\"\n codewhale exec --auto --output-format stream-json \"실패한 테스트를 수정해 줘\"\n\n일반 `codewhale exec`는 모델의 일회성 응답입니다. 다른 실행과 같은 시스템\n프롬프트로 도구 없이 Engine 턴을 한 번 실행합니다. 대화형 입력 없이\n도구를 쓰는 에이전트를 실행하려면 `--auto`를 사용하세요. 도구는 `--auto`,\n`--yolo`, `--allowed-tools`를 지정하거나 세션을 재개할 때만 제공됩니다.\n`--max-turns`, `--disallowed-tools`, `--sandbox` 같은 제한이나 출력 형식은\n도구를 추가하지 않습니다. 공급자의 출력 한도로 잘린 응답은 같은 턴에서\n이어지며, `--max-turns`로 달리 지정하지 않으면 모델 단계는 최대 8회입니다.\n--auto의 기본값은 Full Access입니다. 셸 샌드박스가 없고 신뢰 모드가 켜집니다. 셸 샌드박스와 파일 도구의 워크스페이스 제한을 유지하려면 --sandbox workspace-write를 사용하세요. 설정된 더 엄격한 정책도 적용됩니다. 샌드박스에서 거부된 작업을 재시도하려면 --allow-sandbox-elevation 또는 --sandbox danger-full-access가 필요합니다.\n도구를 제공하는 실행, stream-json 실행, 재개한 세션은 저장되며 codewhale sessions, exec --continue, codewhale receipts <id>에서 사용할 수 있습니다. 응답만 제공하는 일반 text/--json 실행은 압축 시 복구 데이터가 필요한 경우를 제외하고 저장되지 않습니다.\ndanger-full-access 이외의 --sandbox(또는 설정의 동등한 sandbox_mode)는 신뢰 모드를 끕니다.\n",
|
||||
"ExecPromptHelp": "모델에 보낼 프롬프트입니다. -로 시작하거나 exec 플래그를 일반 텍스트로 포함하는 프롬프트 앞에는 --를 넣으세요. 표준 입력을 읽으려면 --prompt-file -를 사용하세요.",
|
||||
"ExecFlagAfterPrompt": "{flag}가 프롬프트 뒤에 있어 텍스트로 처리됩니다. 플래그는 프롬프트 앞에 넣고, 일반 텍스트로 사용할 플래그는 -- 뒤에 넣으세요."
|
||||
}
|
||||
@@ -2567,5 +2567,10 @@
|
||||
"PluginOAuthReady": "{provider}: sessão iniciada. Escolha um modelo.",
|
||||
"PluginOAuthLocalLogout": "{provider}: sessão local removida. O acesso remoto não foi alterado.",
|
||||
"CmdConnectDescription": "Conecta um provedor de plugin com login pelo navegador",
|
||||
"CmdDisconnectDescription": "Remove o login local de um provedor de plugin"
|
||||
"CmdDisconnectDescription": "Remove o login local de um provedor de plugin",
|
||||
"ExecAutoHelp": "Ativa ferramentas com aprovação automática e Full Access (sem sandbox do shell, modo de confiança ativado), salvo se houver um sandbox mais restritivo configurado; use --sandbox workspace-write para restringir gravações de arquivos e do shell.",
|
||||
"ExecSandboxHelp": "Política de sandbox desta execução; qualquer --sandbox diferente de danger-full-access (ou sandbox_mode equivalente na configuração) desativa o modo de confiança.",
|
||||
"ExecAfterHelp": "Exemplos:\n codewhale exec \"explique esta função\"\n codewhale exec --auto \"liste crates/ com ls\"\n codewhale exec --auto --output-format stream-json \"corrija o teste que falha\"\n\n`codewhale exec` sem opções produz uma única resposta do modelo: um turno do\nEngine com o mesmo prompt de sistema das demais execuções e sem ferramentas.\nUse `--auto` para executar um agente com ferramentas sem interação.\nAs ferramentas só são oferecidas com `--auto`, `--yolo`, `--allowed-tools`\nou ao retomar uma sessão; limites como `--max-turns`, `--disallowed-tools`\nou `--sandbox`, assim como o formato de saída, nunca adicionam ferramentas.\nUma resposta cortada pelo limite de saída do provedor continua no mesmo turno,\ncom no máximo 8 etapas do modelo, salvo indicação diferente de `--max-turns`.\n--auto usa Full Access por padrão: sem sandbox do shell e com modo de confiança ativado. Use --sandbox workspace-write para manter o sandbox do shell e as restrições das ferramentas de arquivos ao workspace; políticas mais restritivas configuradas também se aplicam. Repetir uma operação negada pelo sandbox exige --allow-sandbox-elevation ou --sandbox danger-full-access.\nExecuções que oferecem ferramentas, execuções stream-json e sessões retomadas são salvas para codewhale sessions, exec --continue e codewhale receipts <id>. Execuções text/--json que apenas respondem não são salvas, a menos que a compactação precise de dados de recuperação.\nQualquer --sandbox diferente de danger-full-access (ou sandbox_mode equivalente na configuração) desativa o modo de confiança.\n",
|
||||
"ExecPromptHelp": "Prompt enviado ao modelo. Coloque -- antes de um prompt que comece com - ou contenha uma opção literal de exec; use --prompt-file - para ler a entrada padrão.",
|
||||
"ExecFlagAfterPrompt": "{flag} aparece após o prompt e seria tratado como texto. Coloque as opções antes do prompt ou, para usá-las como texto literal, após --."
|
||||
}
|
||||
@@ -2567,5 +2567,10 @@
|
||||
"PluginOAuthReady": "{provider}: вход выполнен. Выберите модель.",
|
||||
"PluginOAuthLocalLogout": "{provider}: локальные данные входа удалены. Удалённый доступ не изменён.",
|
||||
"CmdConnectDescription": "Подключить провайдера плагина через вход в браузере",
|
||||
"CmdDisconnectDescription": "Удалить локальные данные входа провайдера плагина"
|
||||
"CmdDisconnectDescription": "Удалить локальные данные входа провайдера плагина",
|
||||
"ExecAutoHelp": "Включить инструменты с автоматическим одобрением и Full Access (без песочницы оболочки, режим доверия включён), если не настроена более строгая песочница; --sandbox workspace-write ограничивает запись через файловые инструменты и оболочку.",
|
||||
"ExecSandboxHelp": "Политика песочницы для этого запуска; любое значение --sandbox, кроме danger-full-access (или соответствующее значение sandbox_mode в конфигурации), отключает режим доверия.",
|
||||
"ExecAfterHelp": "Примеры:\n codewhale exec \"объясни эту функцию\"\n codewhale exec --auto \"покажи содержимое crates/ с помощью ls\"\n codewhale exec --auto --output-format stream-json \"исправь падающий тест\"\n\nОбычный `codewhale exec` выдаёт один ответ модели: один ход Engine с тем же\nсистемным промптом, что и в других запусках, без инструментов. Для запуска\nагента с инструментами без взаимодействия используйте `--auto`. Инструменты\nдоступны только с `--auto`, `--yolo`, `--allowed-tools` или при продолжении\nсессии; ограничения вроде `--max-turns`, `--disallowed-tools`, `--sandbox` и\nформат вывода никогда не добавляют инструменты. Ответ, прерванный лимитом\nвывода провайдера, продолжается в том же ходе, не более 8 шагов модели,\nесли `--max-turns` не задаёт другой предел.\nПо умолчанию --auto использует Full Access: без песочницы оболочки, с включённым режимом доверия. Используйте --sandbox workspace-write, чтобы сохранить песочницу оболочки и ограничения файловых инструментов рабочей областью; более строгие настроенные политики также действуют. Повтор операции, отклонённой песочницей, требует --allow-sandbox-elevation или --sandbox danger-full-access.\nЗапуски с доступными инструментами, запуски stream-json и возобновлённые сессии сохраняются для codewhale sessions, exec --continue и codewhale receipts <id>. Обычные запуски text/--json только с ответом не сохраняются, если сжатие контекста не требует данных для восстановления.\nЛюбое значение --sandbox, кроме danger-full-access (или соответствующее значение sandbox_mode в конфигурации), отключает режим доверия.\n",
|
||||
"ExecPromptHelp": "Запрос для модели. Поставьте -- перед запросом, который начинается с - или содержит флаг exec как обычный текст; --prompt-file - читает стандартный ввод.",
|
||||
"ExecFlagAfterPrompt": "{flag} указан после запроса и будет воспринят как текст. Укажите флаги перед запросом, а если флаг нужен как обычный текст — после --."
|
||||
}
|
||||
@@ -2567,5 +2567,10 @@
|
||||
"PluginOAuthReady": "{provider}: вхід виконано. Виберіть модель.",
|
||||
"PluginOAuthLocalLogout": "{provider}: локальні дані входу видалено. Віддалений доступ не змінено.",
|
||||
"CmdConnectDescription": "Підключити провайдера плагіна через вхід у браузері",
|
||||
"CmdDisconnectDescription": "Видалити локальні дані входу провайдера плагіна"
|
||||
"CmdDisconnectDescription": "Видалити локальні дані входу провайдера плагіна",
|
||||
"ExecAutoHelp": "Увімкнути інструменти з автоматичним схваленням і Full Access (без пісочниці оболонки, режим довіри ввімкнено), якщо не налаштовано суворішу пісочницю; --sandbox workspace-write обмежує запис через файлові інструменти й оболонку.",
|
||||
"ExecSandboxHelp": "Політика пісочниці для цього запуску; будь-яке значення --sandbox, крім danger-full-access (або відповідне значення sandbox_mode у конфігурації), вимикає режим довіри.",
|
||||
"ExecAfterHelp": "Приклади:\n codewhale exec \"поясни цю функцію\"\n codewhale exec --auto \"покажи вміст crates/ за допомогою ls\"\n codewhale exec --auto --output-format stream-json \"виправ тест, що не проходить\"\n\nЗвичайний `codewhale exec` дає одну відповідь моделі: один хід Engine з тією\nсамою системною підказкою, що й інші запуски, без інструментів. Використовуйте\n`--auto`, щоб запускати агента з інструментами без взаємодії. Інструменти\nдоступні лише з `--auto`, `--yolo`, `--allowed-tools` або під час поновлення\nсесії; обмеження на кшталт `--max-turns`, `--disallowed-tools`, `--sandbox` і\nформат виводу ніколи не додають інструментів. Відповідь, перервана лімітом\nвиводу провайдера, продовжується в тому самому ході, щонайбільше 8 кроків\nмоделі, якщо `--max-turns` не задає іншу межу.\nТипово --auto використовує Full Access: без пісочниці оболонки, з увімкненим режимом довіри. Використовуйте --sandbox workspace-write, щоб зберегти пісочницю оболонки та обмеження файлових інструментів робочою областю; суворіші налаштовані політики також діють. Повтор операції, відхиленої пісочницею, потребує --allow-sandbox-elevation або --sandbox danger-full-access.\nЗапуски з доступними інструментами, запуски stream-json і поновлені сесії зберігаються для codewhale sessions, exec --continue і codewhale receipts <id>. Звичайні запуски text/--json лише з відповіддю не зберігаються, якщо стиснення контексту не потребує даних для відновлення.\nБудь-яке значення --sandbox, крім danger-full-access (або відповідне значення sandbox_mode у конфігурації), вимикає режим довіри.\n",
|
||||
"ExecPromptHelp": "Запит для моделі. Поставте -- перед запитом, який починається з - або містить прапорець exec як звичайний текст; --prompt-file - читає стандартний ввід.",
|
||||
"ExecFlagAfterPrompt": "{flag} вказано після запиту, тож його буде сприйнято як текст. Указуйте прапорці перед запитом, а якщо прапорець потрібен як звичайний текст — після --."
|
||||
}
|
||||
@@ -2567,5 +2567,10 @@
|
||||
"PluginOAuthReady": "{provider}: đã đăng nhập. Hãy chọn mô hình.",
|
||||
"PluginOAuthLocalLogout": "{provider}: đã xóa thông tin đăng nhập cục bộ. Quyền truy cập từ xa không đổi.",
|
||||
"CmdConnectDescription": "Kết nối nhà cung cấp plugin bằng đăng nhập qua trình duyệt",
|
||||
"CmdDisconnectDescription": "Xóa đăng nhập cục bộ của nhà cung cấp plugin"
|
||||
"CmdDisconnectDescription": "Xóa đăng nhập cục bộ của nhà cung cấp plugin",
|
||||
"ExecAutoHelp": "Bật công cụ với phê duyệt tự động và Full Access (không có sandbox shell, bật chế độ tin cậy), trừ khi đã cấu hình sandbox chặt chẽ hơn; dùng --sandbox workspace-write để hạn chế việc ghi bằng công cụ tệp và shell.",
|
||||
"ExecSandboxHelp": "Chính sách sandbox cho lần chạy này; mọi --sandbox khác danger-full-access (hoặc sandbox_mode tương đương trong cấu hình) đều tắt chế độ tin cậy.",
|
||||
"ExecAfterHelp": "Ví dụ:\n codewhale exec \"giải thích hàm này\"\n codewhale exec --auto \"liệt kê crates/ bằng ls\"\n codewhale exec --auto --output-format stream-json \"sửa bài kiểm thử đang lỗi\"\n\n`codewhale exec` thông thường tạo một câu trả lời của mô hình: một lượt Engine\nvới cùng lời nhắc hệ thống như các lần chạy khác và không có công cụ. Dùng\n`--auto` để chạy tác nhân có công cụ mà không cần tương tác. Công cụ chỉ được\ncung cấp khi có `--auto`, `--yolo`, `--allowed-tools` hoặc khi tiếp tục phiên;\ncác giới hạn như `--max-turns`, `--disallowed-tools`, `--sandbox` và định dạng\nđầu ra không bao giờ thêm công cụ. Câu trả lời bị ngắt do giới hạn đầu ra của\nnhà cung cấp được tiếp tục trong cùng lượt, tối đa 8 bước mô hình trừ khi\n`--max-turns` quy định khác.\n--auto mặc định dùng Full Access: không có sandbox shell và bật chế độ tin cậy. Dùng --sandbox workspace-write để duy trì sandbox shell và giới hạn công cụ tệp trong không gian làm việc; các chính sách chặt chẽ hơn đã cấu hình cũng được áp dụng. Thử lại thao tác bị sandbox từ chối cần --allow-sandbox-elevation hoặc --sandbox danger-full-access.\nCác lần chạy có cung cấp công cụ, lần chạy stream-json và phiên được tiếp tục đều được lưu để dùng với codewhale sessions, exec --continue và codewhale receipts <id>. Các lần chạy text/--json thông thường chỉ trả lời sẽ không được lưu, trừ khi việc nén ngữ cảnh cần dữ liệu khôi phục.\nMọi --sandbox khác danger-full-access (hoặc sandbox_mode tương đương trong cấu hình) đều tắt chế độ tin cậy.\n",
|
||||
"ExecPromptHelp": "Lời nhắc gửi đến mô hình. Đặt -- trước lời nhắc bắt đầu bằng - hoặc chứa cờ exec dưới dạng văn bản; dùng --prompt-file - để đọc đầu vào chuẩn.",
|
||||
"ExecFlagAfterPrompt": "{flag} nằm sau lời nhắc và sẽ bị xem là văn bản. Hãy đặt cờ trước lời nhắc hoặc đặt cờ cần dùng dưới dạng văn bản sau --."
|
||||
}
|
||||
@@ -2567,5 +2567,10 @@
|
||||
"PluginOAuthReady": "{provider}:已登录,请选择模型。",
|
||||
"PluginOAuthLocalLogout": "{provider}:已删除本机登录凭据,未撤销服务端授权。",
|
||||
"CmdConnectDescription": "通过浏览器登录连接插件提供方",
|
||||
"CmdDisconnectDescription": "删除插件提供方的本机登录凭据"
|
||||
"CmdDisconnectDescription": "删除插件提供方的本机登录凭据",
|
||||
"ExecAutoHelp": "启用工具,自动批准并使用 Full Access(无 shell 沙盒,开启信任模式),除非已配置更严格的沙盒;使用 --sandbox workspace-write 可限制文件和 shell 写入。",
|
||||
"ExecSandboxHelp": "本次运行的沙盒策略;danger-full-access 以外的任何 --sandbox(或配置中等效的 sandbox_mode)都会关闭信任模式。",
|
||||
"ExecAfterHelp": "示例:\n codewhale exec \"解释这个函数\"\n codewhale exec --auto \"用 ls 列出 crates/ 的内容\"\n codewhale exec --auto --output-format stream-json \"修复失败的测试\"\n\n普通的 `codewhale exec` 仅获取一次模型回答:使用与其他运行相同的系统提示词,\n执行一轮 Engine,不提供工具。使用 `--auto` 可运行非交互式工具代理。\n只有指定 `--auto`、`--yolo`、`--allowed-tools` 或恢复会话时才会提供工具;\n`--max-turns`、`--disallowed-tools`、`--sandbox` 等限制以及输出格式\n都不会添加工具。因提供商输出上限而中断的回答会在同一轮中继续,\n除非通过 `--max-turns` 另行指定,否则最多进行 8 个模型步骤。\n--auto 默认使用 Full Access:无 shell 沙盒,开启信任模式。使用 --sandbox workspace-write 可保留 shell 沙盒和文件工具的工作区限制;已配置的更严格策略也会生效。重试被沙盒拒绝的操作需要 --allow-sandbox-elevation 或 --sandbox danger-full-access。\n提供工具的运行、stream-json 运行以及恢复的会话都会保存,可通过 codewhale sessions、exec --continue 和 codewhale receipts <id> 使用。仅回答的普通 text/--json 运行不会保存,除非上下文压缩需要保留恢复数据。\ndanger-full-access 以外的任何 --sandbox(或配置中等效的 sandbox_mode)都会关闭信任模式。\n",
|
||||
"ExecPromptHelp": "发送给模型的提示词。若以 - 开头或包含作为文本的 exec 标志,请在提示词前加 --;使用 --prompt-file - 读取标准输入。",
|
||||
"ExecFlagAfterPrompt": "{flag} 位于提示词之后,会被当作文本。请将标志放在提示词之前,或将作为文本的标志放在 -- 之后。"
|
||||
}
|
||||
@@ -2567,5 +2567,10 @@
|
||||
"PluginOAuthReady": "{provider}:已登入,請選擇模型。",
|
||||
"PluginOAuthLocalLogout": "{provider}:已刪除本機登入憑證,未撤銷伺服器授權。",
|
||||
"CmdConnectDescription": "透過瀏覽器登入連接外掛提供者",
|
||||
"CmdDisconnectDescription": "刪除外掛提供者的本機登入憑證"
|
||||
"CmdDisconnectDescription": "刪除外掛提供者的本機登入憑證",
|
||||
"ExecAutoHelp": "啟用工具,自動核准並使用 Full Access(無 shell 沙盒,開啟信任模式),除非已設定更嚴格的沙盒;使用 --sandbox workspace-write 可限制檔案與 shell 寫入。",
|
||||
"ExecSandboxHelp": "本次執行的沙盒原則;danger-full-access 以外的任何 --sandbox(或設定中等效的 sandbox_mode)都會關閉信任模式。",
|
||||
"ExecAfterHelp": "範例:\n codewhale exec \"解釋這個函式\"\n codewhale exec --auto \"用 ls 列出 crates/ 的內容\"\n codewhale exec --auto --output-format stream-json \"修正失敗的測試\"\n\n一般的 `codewhale exec` 僅取得一次模型回覆:使用與其他執行相同的系統提示詞,\n執行一輪 Engine,不提供工具。使用 `--auto` 可執行非互動式工具代理。\n只有指定 `--auto`、`--yolo`、`--allowed-tools` 或還原工作階段時才會提供工具;\n`--max-turns`、`--disallowed-tools`、`--sandbox` 等限制及輸出格式\n都不會新增工具。因供應商輸出上限而中斷的回覆會在同一輪中繼續,\n除非透過 `--max-turns` 另行指定,否則最多進行 8 個模型步驟。\n--auto 預設使用 Full Access:無 shell 沙盒,開啟信任模式。使用 --sandbox workspace-write 可保留 shell 沙盒與檔案工具的工作區限制;已設定的更嚴格政策也會生效。重試遭沙盒拒絕的操作需要 --allow-sandbox-elevation 或 --sandbox danger-full-access。\n提供工具的執行、stream-json 執行及還原的工作階段都會儲存,可透過 codewhale sessions、exec --continue 與 codewhale receipts <id> 使用。僅回覆的一般 text/--json 執行不會儲存,除非內容壓縮需要保留復原資料。\ndanger-full-access 以外的任何 --sandbox(或設定中等效的 sandbox_mode)都會關閉信任模式。\n",
|
||||
"ExecPromptHelp": "傳送給模型的提示詞。若以 - 開頭或包含作為文字的 exec 旗標,請在提示詞前加 --;使用 --prompt-file - 讀取標準輸入。",
|
||||
"ExecFlagAfterPrompt": "{flag} 位於提示詞之後,會被視為文字。請將旗標放在提示詞之前,或將作為文字的旗標放在 -- 之後。"
|
||||
}
|
||||
@@ -2808,6 +2808,11 @@ pub enum MessageId {
|
||||
PluginOAuthReady,
|
||||
PluginOAuthLocalLogout,
|
||||
PlanHandoffProceed,
|
||||
ExecAutoHelp,
|
||||
ExecSandboxHelp,
|
||||
ExecAfterHelp,
|
||||
ExecPromptHelp,
|
||||
ExecFlagAfterPrompt,
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
@@ -5382,6 +5387,11 @@ pub const ALL_MESSAGE_IDS: &[MessageId] = &[
|
||||
MessageId::PluginOAuthReady,
|
||||
MessageId::PluginOAuthLocalLogout,
|
||||
MessageId::PlanHandoffProceed,
|
||||
MessageId::ExecAutoHelp,
|
||||
MessageId::ExecSandboxHelp,
|
||||
MessageId::ExecAfterHelp,
|
||||
MessageId::ExecPromptHelp,
|
||||
MessageId::ExecFlagAfterPrompt,
|
||||
];
|
||||
|
||||
pub fn tr(locale: Locale, id: MessageId) -> Cow<'static, str> {
|
||||
|
||||
+40
-16
@@ -7,6 +7,46 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
## [0.10.2] - 2026-10-19
|
||||
|
||||
Codewhale v0.10.2 adds an animated pet view (`/pet on`), a live Terminal work
|
||||
dock and per-chat composer colors (`/color`). It closes three session
|
||||
data-loss paths, a sandbox escape through the Runtime daemon socket and a
|
||||
`codewhale web` session leak; holds a `curl` or `wget` that uploads a
|
||||
credential; refuses shell commands containing invisible Unicode; keeps the
|
||||
Linux sandbox working when a hidden credential directory is a symlink; and
|
||||
uses much less CPU while the TUI waits on you. `/undo` takes back a whole
|
||||
request, including long and multiline prompts. `exec --auto` explains its
|
||||
Full Access default, honors an explicitly stricter sandbox, and saves
|
||||
tool-enabled runs and their failure receipts. Local runtimes appear during
|
||||
onboarding, `/diff` works outside a Git repository, DeepSeek's Responses route
|
||||
no longer rejects replayed tool history, and contributor fixes improve token
|
||||
accounting, relay model lists, localized replies and Windows launcher
|
||||
guidance.
|
||||
|
||||
### Latest fixes
|
||||
|
||||
- `/undo` takes back the latest request and its file changes without requiring
|
||||
trust mode, while refusing ambiguous snapshot matches. Trailing whitespace
|
||||
in a prompt label no longer prevents a match, and an empty first line in
|
||||
another request no longer blocks the whole conversation.
|
||||
- `exec --auto` help and documentation now state its default Full Access:
|
||||
automatic tool approvals, no Codewhale shell sandbox, and trust mode on.
|
||||
Selecting any sandbox other than `danger-full-access`, by flag or config,
|
||||
keeps trust mode off. This includes `external-sandbox`, which relies on
|
||||
host-managed isolation and no longer grants file tools trust-mode access.
|
||||
Stream metadata reports whether the requested sandbox is actually enforced.
|
||||
- Exec flags go before the prompt. A known long flag or `--flag=value` after
|
||||
the prompt now produces an error instead of silently becoming prompt text;
|
||||
use `--` for literal flag text or a prompt starting with `-`.
|
||||
- Exec runs that offer tools save sessions in every output format. Exec and
|
||||
interactive sessions each keep their own retention allowance, so CI runs
|
||||
cannot archive interactive conversations. Live and saved receipts include
|
||||
retained terminal failures, and conversation rewinds discard outcomes from
|
||||
removed turns so they cannot be attributed to later requests.
|
||||
- Onboarding lists Ollama, LM Studio, and vLLM even before a local runtime is
|
||||
detected, so they can be selected and configured. The `L` filter is available
|
||||
during onboarding after local-runtime detection.
|
||||
- `/fork <id>` now shows the forked conversation. Before, the screen kept
|
||||
the previous conversation while the model already had the fork's history.
|
||||
- With `/translate` on, each translated thinking block lands in its own
|
||||
@@ -96,22 +136,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
rebinding) and drive the Runtime API from your browser; such requests now
|
||||
get `421 Misdirected Request`. Servers with auth are unchanged.
|
||||
|
||||
## [0.10.2] - 2026-10-18
|
||||
|
||||
Codewhale v0.10.2 adds an animated pet view (`/pet on`), a live Terminal work
|
||||
dock and per-chat composer colors (`/color`). It closes three session
|
||||
data-loss paths, a sandbox escape through the Runtime daemon socket and a
|
||||
`codewhale web` session leak; holds a `curl` or `wget` that uploads a
|
||||
credential; refuses shell commands containing invisible Unicode; keeps the
|
||||
Linux sandbox working when a hidden credential directory is a symlink; and
|
||||
uses much less CPU while the TUI waits on you. `/undo` takes back a whole
|
||||
request, `/diff` works outside a Git repository, DeepSeek's Responses route no
|
||||
longer rejects replayed tool history, and contributor fixes improve token
|
||||
accounting, relay model lists, localized replies and Windows launcher
|
||||
guidance.
|
||||
|
||||
### Latest fixes
|
||||
|
||||
- Sandboxed commands can no longer reach Codewhale's Runtime daemon socket.
|
||||
On Linux with bubblewrap, and on macOS with sandbox network access on, a
|
||||
command the agent ran (a test script or a postinstall hook, say) could read
|
||||
|
||||
@@ -386,6 +386,7 @@ impl CommandSessionLifecycleContext for SessionLifecycleAdapter<'_> {
|
||||
.clone()
|
||||
.unwrap_or_else(|| "(none)".to_string());
|
||||
app.clear_history();
|
||||
app.session_turn_outcomes = session.turn_outcomes.clone();
|
||||
app.session_artifacts = session.artifacts.clone();
|
||||
app.session_context_references = session.context_references.clone();
|
||||
app.extend_history(
|
||||
|
||||
@@ -36,8 +36,14 @@ impl CommandDebugReceiptsContext for DebugOperationsAdapter<'_> {
|
||||
started_at: Some(app.session_started_at),
|
||||
updated_at: None,
|
||||
};
|
||||
crate::receipts::session_receipt(source, &app.api_messages, &approvals, turn)
|
||||
.map_err(|error| DebugReceiptError::Build(error.to_string()))
|
||||
crate::receipts::session_receipt(
|
||||
source,
|
||||
&app.api_messages,
|
||||
&approvals,
|
||||
&app.session_turn_outcomes,
|
||||
turn,
|
||||
)
|
||||
.map_err(|error| DebugReceiptError::Build(error.to_string()))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -248,8 +254,8 @@ fn request_prompts(app: &App) -> Vec<Option<String>> {
|
||||
|
||||
type RequestPositionResult = Result<Option<bool>, Box<DebugUndoOutcome>>;
|
||||
|
||||
/// Match only lossless, unique prompt labels. Display snippets are not durable
|
||||
/// request identities: repeated, multiline, truncated or multipart prompts cannot
|
||||
/// Match only unique prompt snippets. Display snippets are not durable
|
||||
/// request identities: repeated snippets or multipart prompts cannot
|
||||
/// authorize a combined file/conversation rollback. `/restore` remains explicit.
|
||||
fn request_is_last(
|
||||
requests: &[Option<String>],
|
||||
@@ -269,17 +275,21 @@ fn request_is_last(
|
||||
.to_string(),
|
||||
))
|
||||
};
|
||||
// A held request with missing or shortened text could be the candidate
|
||||
// even when its display label appears to name an older request.
|
||||
if requests.iter().any(|prompt| {
|
||||
prompt.as_deref().is_none_or(|prompt| {
|
||||
prompt.is_empty() || snapshot_label_prompt_snippet(prompt).as_deref() != Some(prompt)
|
||||
})
|
||||
}) {
|
||||
if requests.iter().any(Option::is_none) {
|
||||
return Err(refusal());
|
||||
}
|
||||
let requests: Vec<_> = requests
|
||||
.iter()
|
||||
.map(|prompt| {
|
||||
prompt
|
||||
.as_deref()
|
||||
.and_then(snapshot_label_prompt_snippet)
|
||||
.map(|snippet| snippet.trim_end().to_string())
|
||||
.filter(|snippet| !snippet.is_empty())
|
||||
})
|
||||
.collect();
|
||||
let request = parse_snapshot_label(label).prompt_snippet;
|
||||
let Some(prompt) = request.as_deref().filter(|prompt| {
|
||||
let Some(prompt) = request.as_deref().map(str::trim_end).filter(|prompt| {
|
||||
!prompt.is_empty() && snapshot_label_prompt_snippet(prompt).as_deref() == Some(*prompt)
|
||||
}) else {
|
||||
return Err(refusal());
|
||||
@@ -291,7 +301,7 @@ fn request_is_last(
|
||||
if matches != 1
|
||||
|| owned_request_snippets
|
||||
.iter()
|
||||
.filter(|candidate| candidate.as_deref() == Some(prompt))
|
||||
.filter(|candidate| candidate.as_deref().map(str::trim_end) == Some(prompt))
|
||||
.count()
|
||||
> 1
|
||||
{
|
||||
@@ -299,7 +309,9 @@ fn request_is_last(
|
||||
// prompts would still confuse an older occurrence with the latest.
|
||||
return Err(refusal());
|
||||
}
|
||||
Ok(Some(requests.last() == Some(&request)))
|
||||
Ok(Some(
|
||||
requests.last().and_then(Option::as_deref) == Some(prompt),
|
||||
))
|
||||
}
|
||||
|
||||
/// Deepest fork chain [`snapshot_owners`] follows. A chain this long is
|
||||
|
||||
@@ -989,8 +989,13 @@ fn undo_refuses_lossy_shared_prefix_and_first_line_labels() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn undo_refuses_a_unique_lossy_prompt_even_without_a_collision() {
|
||||
for prompt in ["x".repeat(101), "edit a.txt\nwith a second line".into()] {
|
||||
fn undo_matches_unique_truncated_and_multiline_prompt_snippets() {
|
||||
for prompt in [
|
||||
"x".repeat(101),
|
||||
"edit a.txt\nwith a second line".into(),
|
||||
"edit a.txt \nwith trailing whitespace".into(),
|
||||
"\nwith an empty first line".into(),
|
||||
] {
|
||||
let fx = UndoFixture::new();
|
||||
fx.write("a.txt", "a0");
|
||||
fx.snapshot(
|
||||
@@ -1002,9 +1007,35 @@ fn undo_refuses_a_unique_lossy_prompt_even_without_a_collision() {
|
||||
&crate::core::turn::format_snapshot_label("post-turn", 1, Some(&prompt)),
|
||||
"s1",
|
||||
);
|
||||
fx.snapshot("pre-turn:2: update a.txt again", "s1");
|
||||
fx.write("a.txt", "a2");
|
||||
fx.snapshot("post-turn:2: update a.txt again", "s1");
|
||||
let mut app = fx.app("s1");
|
||||
push_exchange(&mut app, &prompt);
|
||||
assert_undo_identity_refused(&fx, &mut app);
|
||||
push_exchange(&mut app, "update a.txt again");
|
||||
app.session_turn_outcomes = vec![
|
||||
crate::session_manager::SavedTurnOutcome::failed("first failure", 2),
|
||||
crate::session_manager::SavedTurnOutcome::failed("second failure", 4),
|
||||
];
|
||||
|
||||
let result = super::execute("/undo", &mut app);
|
||||
assert!(!result.is_error, "{:?}", result.message);
|
||||
assert_eq!(fx.read("a.txt"), "a1");
|
||||
assert_eq!(app.history.len(), 2);
|
||||
assert_eq!(app.api_messages.len(), 2);
|
||||
assert_eq!(app.session_turn_outcomes.len(), 1);
|
||||
assert_eq!(app.session_turn_outcomes[0].error, "first failure");
|
||||
|
||||
if prompt.starts_with('\n') {
|
||||
assert_undo_identity_refused(&fx, &mut app);
|
||||
continue;
|
||||
}
|
||||
|
||||
let result = super::execute("/undo", &mut app);
|
||||
assert!(!result.is_error, "{:?}", result.message);
|
||||
assert_eq!(fx.read("a.txt"), "a0");
|
||||
assert!(app.history.is_empty() && app.api_messages.is_empty());
|
||||
assert!(app.session_turn_outcomes.is_empty());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1052,6 +1083,10 @@ fn undo_refuses_missing_prompt_labels_and_multipart_requests() {
|
||||
});
|
||||
}
|
||||
assert_undo_identity_refused(&fx, &mut app);
|
||||
if kind > 0 {
|
||||
push_exchange(&mut app, "edit a.txt");
|
||||
assert_undo_identity_refused(&fx, &mut app);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -725,6 +725,7 @@ impl CancelReason {
|
||||
#[derive(Clone)]
|
||||
pub struct EngineHandle {
|
||||
goal_state: SharedGoalState,
|
||||
pub(crate) sandbox_enforcement: crate::sandbox::policy::SandboxEnforcement,
|
||||
/// Send operations to the engine
|
||||
pub tx_op: mpsc::Sender<Op>,
|
||||
/// Receive events from the engine
|
||||
@@ -2522,6 +2523,7 @@ impl Engine {
|
||||
};
|
||||
let handle = EngineHandle {
|
||||
goal_state: engine.config.goal_state.clone(),
|
||||
sandbox_enforcement,
|
||||
tx_op,
|
||||
rx_event: Arc::new(RwLock::new(rx_event)),
|
||||
cancel_token: shared_cancel_token,
|
||||
@@ -9827,6 +9829,7 @@ pub(crate) fn mock_engine_handle() -> MockEngineHandle {
|
||||
let compaction_cancellation = Arc::new(StdMutex::new(CompactionCancellationState::default()));
|
||||
let handle = EngineHandle {
|
||||
goal_state: new_shared_goal_state(),
|
||||
sandbox_enforcement: crate::sandbox::policy::SandboxEnforcement::Unavailable,
|
||||
tx_op,
|
||||
rx_event: Arc::new(RwLock::new(rx_event)),
|
||||
cancel_token: shared_cancel_token,
|
||||
|
||||
@@ -866,6 +866,7 @@ fn engine_handle_try_send_does_not_block_when_op_channel_is_full() {
|
||||
let cancel_token = CancellationToken::new();
|
||||
let handle = EngineHandle {
|
||||
goal_state: new_shared_goal_state(),
|
||||
sandbox_enforcement: crate::sandbox::policy::SandboxEnforcement::Unavailable,
|
||||
tx_op,
|
||||
rx_event: Arc::new(RwLock::new(mpsc::channel::<Event>(1).1)),
|
||||
cancel_token: Arc::new(StdMutex::new(cancel_token)),
|
||||
|
||||
@@ -297,7 +297,6 @@ pub(crate) async fn run_exec_agent(
|
||||
auto_approve: bool,
|
||||
allow_sandbox_elevation: bool,
|
||||
explicit_sandbox: Option<&str>,
|
||||
trust_mode: bool,
|
||||
json_output: bool,
|
||||
resume_session: Option<session_manager::SavedSession>,
|
||||
force_configured_route: bool,
|
||||
@@ -407,7 +406,32 @@ pub(crate) async fn run_exec_agent(
|
||||
let prompt_sha256 = format!("sha256:{}", crate::hashing::sha256_hex(prompt.as_bytes()));
|
||||
let binary_sha256 = current_binary_sha256();
|
||||
let approval_posture = if auto_approve { "auto_tools" } else { "ask" }.to_string();
|
||||
let sandbox_posture = explicit_sandbox.unwrap_or("configured_default").to_string();
|
||||
// The Full Access posture travels in the op's auto_approve/approval_mode
|
||||
// fields; modes no longer carry permission.
|
||||
let mode = AppMode::Agent;
|
||||
let turn_approval_mode = if auto_approve {
|
||||
ApprovalMode::Bypass
|
||||
} else {
|
||||
execution_config
|
||||
.approval_policy
|
||||
.as_deref()
|
||||
.and_then(ApprovalMode::from_config_value)
|
||||
.unwrap_or_default()
|
||||
};
|
||||
let turn_sandbox_policy = crate::core::authority::sandbox_policy_for_turn(
|
||||
mode,
|
||||
turn_approval_mode,
|
||||
execution_config.sandbox_mode.as_deref(),
|
||||
&workspace,
|
||||
crate::core::authority::SandboxNetworkAccess::from_config(
|
||||
execution_config.sandbox_network_access,
|
||||
),
|
||||
);
|
||||
let trust_mode = auto_approve
|
||||
&& matches!(
|
||||
turn_sandbox_policy,
|
||||
crate::sandbox::SandboxPolicy::DangerFullAccess
|
||||
);
|
||||
let active_route_limits =
|
||||
crate::route_budget::known_route_limits(validated_route.candidate.limits());
|
||||
let max_subagents = if max_subagents
|
||||
@@ -695,48 +719,16 @@ pub(crate) async fn run_exec_agent(
|
||||
};
|
||||
|
||||
let engine_handle = spawn_engine(engine_config, &execution_config, None);
|
||||
// The Full Access posture travels in the op's auto_approve/approval_mode
|
||||
// fields; modes no longer carry permission.
|
||||
let mode = AppMode::Agent;
|
||||
let turn_approval_mode = if auto_approve {
|
||||
ApprovalMode::Bypass
|
||||
} else {
|
||||
execution_config
|
||||
.approval_policy
|
||||
.as_deref()
|
||||
.and_then(ApprovalMode::from_config_value)
|
||||
.unwrap_or_default()
|
||||
};
|
||||
// A restricted posture that resolves to no enforcing sandbox must reach
|
||||
// the person running exec, not only the model's posture line: policy-only
|
||||
// is accepted (read-only already fails closed in the shell tool), but it
|
||||
// is never silent. Mirrors the enforcement detection in `Engine::new`.
|
||||
let turn_sandbox_policy = crate::core::authority::sandbox_policy_for_turn(
|
||||
mode,
|
||||
turn_approval_mode,
|
||||
execution_config.sandbox_mode.as_deref(),
|
||||
&workspace,
|
||||
crate::core::authority::SandboxNetworkAccess::from_config(
|
||||
execution_config.sandbox_network_access,
|
||||
),
|
||||
);
|
||||
let enforcement_unavailable = crate::sandbox::backend::SandboxKind::parse(
|
||||
execution_config
|
||||
.sandbox_backend
|
||||
.as_deref()
|
||||
.unwrap_or("none"),
|
||||
) == Some(crate::sandbox::backend::SandboxKind::None)
|
||||
&& crate::sandbox::get_platform_sandbox_with_bwrap_preference(
|
||||
execution_config.prefers_bwrap(),
|
||||
)
|
||||
.is_none();
|
||||
if enforcement_unavailable && turn_sandbox_policy.should_sandbox() {
|
||||
eprintln!(
|
||||
"warning: {} — shell commands will run unrestricted",
|
||||
turn_sandbox_policy.posture_label_with_enforcement(
|
||||
crate::sandbox::policy::SandboxEnforcement::Unavailable,
|
||||
)
|
||||
);
|
||||
// is never silent. Uses the enforcement pinned by `Engine::new`.
|
||||
let sandbox_enforcement = engine_handle.sandbox_enforcement;
|
||||
let sandbox_posture = turn_sandbox_policy.posture_label_with_enforcement(sandbox_enforcement);
|
||||
if sandbox_enforcement == crate::sandbox::policy::SandboxEnforcement::Unavailable
|
||||
&& turn_sandbox_policy.should_sandbox()
|
||||
{
|
||||
eprintln!("warning: {sandbox_posture} — shell commands will run unrestricted");
|
||||
}
|
||||
|
||||
let resuming_session = resume_session.is_some();
|
||||
@@ -860,7 +852,7 @@ pub(crate) async fn run_exec_agent(
|
||||
let mut reported_sandbox_contract = false;
|
||||
|
||||
let mut should_persist_session =
|
||||
resuming_session || output_format == ExecOutputFormat::StreamJson;
|
||||
!one_shot || resuming_session || output_format == ExecOutputFormat::StreamJson;
|
||||
let mut latest_session_id = loaded_session_id;
|
||||
let mut latest_messages: Arc<Vec<Message>> = Arc::new(Vec::new());
|
||||
let mut latest_system_prompt: Option<SystemPrompt> = None;
|
||||
@@ -1369,6 +1361,13 @@ pub(crate) async fn run_exec_agent(
|
||||
&latest_system_prompt,
|
||||
latest_session_id.as_deref(),
|
||||
u64::from(usage.input_tokens) + u64::from(usage.output_tokens),
|
||||
(terminal_status == crate::core::events::TurnOutcomeStatus::Failed)
|
||||
.then_some(
|
||||
summary
|
||||
.error
|
||||
.as_deref()
|
||||
.unwrap_or(termination_reason.as_str()),
|
||||
),
|
||||
fleet_capture.as_ref().map(|(_, manager)| manager),
|
||||
) {
|
||||
Ok(id) => {
|
||||
|
||||
+61
-29
@@ -10,9 +10,7 @@ use std::sync::Arc;
|
||||
use std::time::{Duration, Instant};
|
||||
|
||||
use anyhow::{Context, Result, anyhow, bail};
|
||||
#[cfg(test)]
|
||||
use clap::CommandFactory;
|
||||
use clap::{Args, Parser, Subcommand, ValueEnum};
|
||||
use clap::{Args, CommandFactory, FromArgMatches, Parser, Subcommand, ValueEnum};
|
||||
use tempfile::NamedTempFile;
|
||||
use wait_timeout::ChildExt;
|
||||
|
||||
@@ -406,22 +404,10 @@ enum SessionsCommand {
|
||||
}
|
||||
|
||||
#[derive(Args, Debug, Clone)]
|
||||
#[command(after_help = "\
|
||||
Examples:
|
||||
codewhale exec \"explain this function\"
|
||||
codewhale exec --auto \"list crates/ with ls\"
|
||||
codewhale exec --auto --output-format stream-json \"fix the failing test\"
|
||||
|
||||
Plain `codewhale exec` is a one-shot model response: one Engine turn with the
|
||||
same system prompt as every other run, and no tools. Use `--auto` for
|
||||
non-interactive agent-with-tools execution. Tools are offered only with
|
||||
`--auto`, `--yolo`, `--allowed-tools`, or when resuming a session; limits such
|
||||
as `--max-turns`, `--disallowed-tools` or `--sandbox`, and the output format,
|
||||
never add tools. A reply cut off at the provider's output limit is continued
|
||||
in the same turn, at most 8 model steps unless `--max-turns` says otherwise.
|
||||
`--auto` does not change the sandbox posture or elevate a denied tool. Use `--sandbox danger-full-access`
|
||||
or `--allow-sandbox-elevation` to explicitly authorize sandbox elevation.
|
||||
")]
|
||||
#[command(after_help = codewhale_localization::tr(
|
||||
codewhale_localization::resolve_locale("auto"),
|
||||
codewhale_localization::MessageId::ExecAfterHelp,
|
||||
))]
|
||||
struct ExecArgs {
|
||||
/// Override model for this run
|
||||
#[arg(long)]
|
||||
@@ -437,12 +423,15 @@ struct ExecArgs {
|
||||
/// Accepted values: auto, off, low, medium, high, max.
|
||||
#[arg(long = "reasoning-effort", value_name = "EFFORT")]
|
||||
reasoning_effort: Option<String>,
|
||||
/// Enable agent-with-tools mode with automatic tool approvals. This does
|
||||
/// not authorize sandbox elevation.
|
||||
#[arg(long, default_value_t = false)]
|
||||
#[arg(long, default_value_t = false, help = codewhale_localization::tr(
|
||||
codewhale_localization::resolve_locale("auto"),
|
||||
codewhale_localization::MessageId::ExecAutoHelp,
|
||||
))]
|
||||
auto: bool,
|
||||
/// Sandbox policy for this exec run; independent from --auto.
|
||||
#[arg(long, value_name = "POLICY")]
|
||||
#[arg(long, value_name = "POLICY", help = codewhale_localization::tr(
|
||||
codewhale_localization::resolve_locale("auto"),
|
||||
codewhale_localization::MessageId::ExecSandboxHelp,
|
||||
))]
|
||||
sandbox: Option<String>,
|
||||
/// Explicitly allow a denied tool to retry with danger-full-access.
|
||||
#[arg(long, default_value_t = false)]
|
||||
@@ -497,17 +486,54 @@ struct ExecArgs {
|
||||
/// prompts past the OS per-argument limit (~128 KiB on Linux).
|
||||
#[arg(long, value_name = "PATH", conflicts_with = "prompt")]
|
||||
prompt_file: Option<PathBuf>,
|
||||
/// Prompt to send to the model. Taken literally, including a lone `-`;
|
||||
/// use `--prompt-file -` to read stdin.
|
||||
#[arg(
|
||||
value_name = "PROMPT",
|
||||
required_unless_present = "prompt_file",
|
||||
trailing_var_arg = true,
|
||||
allow_hyphen_values = true
|
||||
help = codewhale_localization::tr(
|
||||
codewhale_localization::resolve_locale("auto"),
|
||||
codewhale_localization::MessageId::ExecPromptHelp,
|
||||
)
|
||||
)]
|
||||
prompt: Vec<String>,
|
||||
}
|
||||
|
||||
fn parse_cli_args(args: &[impl AsRef<str>]) -> Result<Cli, clap::Error> {
|
||||
let mut command = Cli::command();
|
||||
let matches = command.try_get_matches_from_mut(args.iter().map(|arg| arg.as_ref()))?;
|
||||
let cli = Cli::from_arg_matches(&matches)?;
|
||||
if let Some(Commands::Exec(exec)) = &cli.command {
|
||||
let prompt_start = args.len().saturating_sub(exec.prompt.len());
|
||||
if !args[..prompt_start]
|
||||
.last()
|
||||
.is_some_and(|arg| arg.as_ref() == "--")
|
||||
{
|
||||
let command = command.find_subcommand_mut("exec").expect("exec command");
|
||||
for word in exec.prompt.iter().take_while(|word| *word != "--") {
|
||||
let flag = word.split_once('=').map_or(word.as_str(), |(flag, _)| flag);
|
||||
if flag.strip_prefix("--").is_some_and(|name| {
|
||||
command.get_arguments().any(|arg| {
|
||||
arg.get_long() == Some(name)
|
||||
|| arg
|
||||
.get_all_aliases()
|
||||
.is_some_and(|aliases| aliases.contains(&name))
|
||||
})
|
||||
}) {
|
||||
return Err(command.error(
|
||||
clap::error::ErrorKind::UnknownArgument,
|
||||
codewhale_localization::tr(
|
||||
codewhale_localization::resolve_locale("auto"),
|
||||
codewhale_localization::MessageId::ExecFlagAfterPrompt,
|
||||
)
|
||||
.replace("{flag}", flag),
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(cli)
|
||||
}
|
||||
|
||||
#[derive(Args, Debug, Clone)]
|
||||
struct WorkflowToolArgs {
|
||||
/// Authority provenance stamped by the public `workflow run` command.
|
||||
@@ -1983,7 +2009,7 @@ fn run_with_args(options: RuntimeOptions, args: Vec<String>) -> Result<()> {
|
||||
// configuration, MCP, trust, sandbox, executable lookup, or plugin
|
||||
// discovery. Plugin discovery therefore runs first, and the loader below
|
||||
// admits only built-in provider credential names from a stable file read.
|
||||
let cli = match Cli::try_parse_from(args) {
|
||||
let cli = match parse_cli_args(&args) {
|
||||
Ok(mut cli) => {
|
||||
cli.options = options.merge(cli.options)?;
|
||||
cli
|
||||
@@ -2845,7 +2871,6 @@ async fn run_async_main_dispatch(
|
||||
auto_mode,
|
||||
args.allow_sandbox_elevation,
|
||||
args.sandbox.as_deref(),
|
||||
auto_mode,
|
||||
args.json,
|
||||
resume_session,
|
||||
force_configured_route,
|
||||
@@ -14885,6 +14910,7 @@ fn persist_exec_session(
|
||||
system_prompt: &Option<SystemPrompt>,
|
||||
session_id: Option<&str>,
|
||||
total_tokens: u64,
|
||||
turn_failure: Option<&str>,
|
||||
session_manager: Option<&SessionManager>,
|
||||
) -> Result<String> {
|
||||
let default_manager;
|
||||
@@ -14933,6 +14959,12 @@ fn persist_exec_session(
|
||||
provider_route.id,
|
||||
workspace,
|
||||
);
|
||||
if let Some(error) = turn_failure {
|
||||
session_manager::push_turn_outcome(
|
||||
&mut saved.turn_outcomes,
|
||||
session_manager::SavedTurnOutcome::failed(error, messages.len()),
|
||||
);
|
||||
}
|
||||
let id = saved.metadata.id.clone();
|
||||
manager
|
||||
.save_session(&saved)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
fn parse_cli(args: &[&str]) -> Cli {
|
||||
Cli::try_parse_from(args).expect("CLI args should parse")
|
||||
parse_cli_args(args).expect("CLI args should parse")
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -979,13 +979,54 @@
|
||||
|
||||
#[test]
|
||||
fn exec_keeps_flags_before_split_prompt_words() {
|
||||
let cli = parse_cli(&["codewhale", "exec", "--json", "hello", "world"]);
|
||||
let cli = parse_cli(&["codewhale", "exec", "--json", "hello", "--world"]);
|
||||
let Some(Commands::Exec(args)) = cli.command else {
|
||||
panic!("expected exec command");
|
||||
};
|
||||
|
||||
assert!(args.json);
|
||||
assert_eq!(args.prompt, vec!["hello", "world"]);
|
||||
assert_eq!(args.prompt, vec!["hello", "--world"]);
|
||||
for flag in [
|
||||
"--sandbox",
|
||||
"--sandbox=workspace-write",
|
||||
"--auto",
|
||||
"--help",
|
||||
"--enable=web_search",
|
||||
"--operation-key=example",
|
||||
] {
|
||||
let error = parse_cli_args(&["codewhale", "exec", "--auto", "fix tests", flag])
|
||||
.expect_err("exec flags after the prompt must not silently become text");
|
||||
assert_eq!(error.kind(), clap::error::ErrorKind::UnknownArgument);
|
||||
assert!(error.to_string().contains(flag.split('=').next().unwrap()));
|
||||
}
|
||||
for prompt in [
|
||||
vec!["--", "--sandbox", "workspace-write"],
|
||||
vec!["hello", "--", "--sandbox=workspace-write"],
|
||||
] {
|
||||
let argv: Vec<&str> = ["codewhale", "exec", "--auto"]
|
||||
.into_iter()
|
||||
.chain(prompt)
|
||||
.collect();
|
||||
let cli = parse_cli(&argv);
|
||||
let Some(Commands::Exec(args)) = cli.command else {
|
||||
panic!("expected exec command");
|
||||
};
|
||||
assert!(args.sandbox.is_none());
|
||||
assert!(args.prompt.iter().any(|word| word.starts_with("--sandbox")));
|
||||
}
|
||||
let error = Cli::try_parse_from([
|
||||
"codewhale",
|
||||
"exec",
|
||||
"--auto",
|
||||
"--sandox",
|
||||
"workspace-write",
|
||||
"--max-turns",
|
||||
"1",
|
||||
"--json",
|
||||
"Reply with the single word OK and use no tools.",
|
||||
])
|
||||
.expect_err("unknown flags before the prompt must fail parsing");
|
||||
assert_eq!(error.kind(), clap::error::ErrorKind::UnknownArgument);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -1506,7 +1506,9 @@
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn exec_help_separates_agent_mode_from_sandbox_elevation() {
|
||||
fn exec_help_discloses_full_access_and_session_persistence() {
|
||||
let _env_lock = crate::test_support::lock_test_env();
|
||||
let _locale = crate::test_support::EnvVarGuard::set("LC_ALL", "en_US.UTF-8");
|
||||
let mut cli = Cli::command();
|
||||
let help = cli
|
||||
.find_subcommand_mut("exec")
|
||||
@@ -1516,8 +1518,15 @@
|
||||
assert!(help.contains("--auto"));
|
||||
assert!(help.contains("--sandbox"));
|
||||
assert!(help.contains("--allow-sandbox-elevation"));
|
||||
assert!(help.contains("does not change the"));
|
||||
assert!(help.contains("explicitly authorize sandbox elevation"));
|
||||
assert!(help.contains("Full Access"));
|
||||
assert!(help.contains("no shell sandbox"));
|
||||
assert!(help.contains("trust mode on"));
|
||||
assert!(help.contains("--sandbox workspace-write"));
|
||||
assert!(help.contains("Any --sandbox other than danger-full-access"));
|
||||
assert!(help.contains("equivalent sandbox_mode in config"));
|
||||
assert!(help.contains("Put -- before a prompt starting with -"));
|
||||
assert!(help.contains("Runs that offer tools"));
|
||||
assert!(help.contains("codewhale receipts <id>"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -698,7 +698,7 @@
|
||||
duration_ms: 2500,
|
||||
retry_count: None,
|
||||
approval_posture: "ask".to_string(),
|
||||
sandbox_posture: "configured_default".to_string(),
|
||||
sandbox_posture: "workspace-write".to_string(),
|
||||
binary_sha256: Some("sha256:binary".to_string()),
|
||||
config_sha256: None,
|
||||
prompt_sha256: "sha256:prompt".to_string(),
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
//!
|
||||
//! - a terminal session: the saved transcript (`sessions/<id>.json`, whose
|
||||
//! `tool_use`/`tool_result` blocks are the calls) plus the session's
|
||||
//! approval log (`sessions/<id>/approval_receipts.jsonl`);
|
||||
//! approval log (`sessions/<id>/approval_receipts.jsonl`) and saved turn outcomes;
|
||||
//! - a Runtime thread (the app, `codewhale serve`): the thread's turn and item
|
||||
//! records plus the `approval.*` events in its append-only event log.
|
||||
//!
|
||||
@@ -15,8 +15,9 @@
|
||||
//! shell command changed, which no tool record names.
|
||||
//!
|
||||
//! Both are normalized into [`ToolStep`]s and [`ApprovalStep`]s and then
|
||||
//! classified by the same code, so `/receipts`, `codewhale receipts`, and
|
||||
//! `GET /v1/threads/{id}/receipt` cannot disagree about what happened.
|
||||
//! classified by the same code for `/receipts`, `codewhale receipts`, and
|
||||
//! `GET /v1/threads/{id}/receipt`. Live and saved terminal sessions supply
|
||||
//! their recorded turn outcomes so both surfaces report the same failures.
|
||||
//!
|
||||
//! The builder only reads. It never calls a provider, runs a tool, or writes
|
||||
//! a file (reading the snapshots runs `git diff` inside the side repo, which
|
||||
@@ -102,6 +103,8 @@ type TurnPosture = (String, Option<&'static str>);
|
||||
/// A turn and the user's prompt text, if it had any.
|
||||
type TurnPrompt = (String, Option<String>);
|
||||
|
||||
type TurnFailure = (Option<String>, Option<DateTime<Utc>>, Option<String>);
|
||||
|
||||
/// Each matched turn's workspace change, and how many turns had no pair.
|
||||
type TurnChanges = (Vec<(String, TurnWorkspaceChange)>, usize);
|
||||
|
||||
@@ -131,10 +134,33 @@ pub(crate) fn session_receipt(
|
||||
source: ReceiptSource,
|
||||
messages: &[Message],
|
||||
approval_receipts: &[ApprovalReceipt],
|
||||
turn_outcomes: &[crate::session_manager::SavedTurnOutcome],
|
||||
turn: Option<&str>,
|
||||
) -> anyhow::Result<Receipt> {
|
||||
let mut notes = BTreeSet::new();
|
||||
let (steps, turn_postures, turn_prompts) = steps_from_messages(messages);
|
||||
let failures = turn_outcomes
|
||||
.iter()
|
||||
.filter(|outcome| {
|
||||
outcome.status == crate::core::events::TurnOutcomeStatus::Failed
|
||||
&& outcome.after_message_count <= messages.len()
|
||||
})
|
||||
.map(|outcome| {
|
||||
let turn = messages
|
||||
.iter()
|
||||
.take(outcome.after_message_count)
|
||||
.filter(|message| {
|
||||
crate::runtime_handoff::classify_user_turn_prompt(message)
|
||||
!= crate::runtime_handoff::UserTurnPromptKind::NotPrompt
|
||||
})
|
||||
.count();
|
||||
(
|
||||
(turn > 0).then(|| turn.to_string()),
|
||||
Some(outcome.ended_at),
|
||||
Some(outcome.error.clone()),
|
||||
)
|
||||
})
|
||||
.collect();
|
||||
let approvals = match ApprovalReplay::from_receipts(approval_receipts) {
|
||||
Ok(replay) => approvals_from_replay(&replay),
|
||||
Err(error) => {
|
||||
@@ -212,7 +238,7 @@ pub(crate) fn session_receipt(
|
||||
source,
|
||||
steps,
|
||||
approvals,
|
||||
Vec::new(),
|
||||
failures,
|
||||
workspace_changes,
|
||||
Assembly {
|
||||
turn,
|
||||
@@ -268,7 +294,11 @@ pub(crate) fn thread_receipt(
|
||||
}
|
||||
}
|
||||
if record.status == RuntimeTurnStatus::Failed {
|
||||
failures.push((record.id.clone(), record.ended_at, record.error.clone()));
|
||||
failures.push((
|
||||
Some(record.id.clone()),
|
||||
record.ended_at,
|
||||
record.error.clone(),
|
||||
));
|
||||
}
|
||||
}
|
||||
let approvals = approvals_from_events(events);
|
||||
@@ -380,6 +410,7 @@ pub(crate) fn run_receipts_command(
|
||||
session_source(&session.metadata),
|
||||
&session.messages,
|
||||
&session.approval_receipts,
|
||||
&session.turn_outcomes,
|
||||
turn,
|
||||
)?
|
||||
}
|
||||
@@ -405,6 +436,7 @@ pub(crate) fn run_receipts_command(
|
||||
session_source(&session.metadata),
|
||||
&session.messages,
|
||||
&session.approval_receipts,
|
||||
&session.turn_outcomes,
|
||||
turn,
|
||||
)?
|
||||
}
|
||||
@@ -1678,7 +1710,7 @@ fn assemble(
|
||||
source: ReceiptSource,
|
||||
steps: Vec<ToolStep>,
|
||||
approvals: Vec<ApprovalStep>,
|
||||
turn_failures: Vec<(String, Option<DateTime<Utc>>, Option<String>)>,
|
||||
turn_failures: Vec<TurnFailure>,
|
||||
workspace_changes: Vec<(String, TurnWorkspaceChange)>,
|
||||
scope: Assembly<'_>,
|
||||
mut notes: BTreeSet<String>,
|
||||
@@ -1841,12 +1873,12 @@ fn assemble(
|
||||
}
|
||||
|
||||
for (turn_id, ended_at, error) in turn_failures {
|
||||
if !in_scope(Some(&turn_id)) {
|
||||
if !in_scope(turn_id.as_deref()) {
|
||||
continue;
|
||||
}
|
||||
actions.push(ReceiptAction {
|
||||
seq: 0,
|
||||
turn: Some(turn_id),
|
||||
turn: turn_id,
|
||||
at: ended_at,
|
||||
call_id: None,
|
||||
tool: "turn".to_string(),
|
||||
|
||||
@@ -385,8 +385,18 @@ fn session_receipt_reads_transcript_and_approval_log_with_deciders() {
|
||||
ApprovalReceipt::asked("c5", "Web"),
|
||||
ApprovalReceipt::decided("c5", ApprovalOutcome::ApprovedOnce),
|
||||
];
|
||||
let receipt =
|
||||
session_receipt(session_source_fixture(), &messages, &receipts, None).expect("receipt");
|
||||
let outcomes = vec![
|
||||
crate::session_manager::SavedTurnOutcome::failed("provider returned 500", 8),
|
||||
crate::session_manager::SavedTurnOutcome::failed("turn budget exhausted", messages.len()),
|
||||
];
|
||||
let receipt = session_receipt(
|
||||
session_source_fixture(),
|
||||
&messages,
|
||||
&receipts,
|
||||
&outcomes,
|
||||
None,
|
||||
)
|
||||
.expect("receipt");
|
||||
|
||||
let lines: Vec<String> = receipt.actions.iter().map(action_line).collect();
|
||||
assert_eq!(
|
||||
@@ -398,6 +408,8 @@ fn session_receipt_reads_transcript_and_approval_log_with_deciders() {
|
||||
"did not run `rm -rf build` · denied by you",
|
||||
"fetched docs.rs · approved",
|
||||
"started agent reviewer — completed",
|
||||
"turn failed — failed: provider returned 500",
|
||||
"turn failed — failed: turn budget exhausted",
|
||||
]
|
||||
.into_iter()
|
||||
.map(str::to_string)
|
||||
@@ -411,6 +423,10 @@ fn session_receipt_reads_transcript_and_approval_log_with_deciders() {
|
||||
"a whole-file write has no counts"
|
||||
);
|
||||
assert_eq!((totals.commands, totals.commands_failed), (1, 1));
|
||||
assert_eq!(totals.failures, 3);
|
||||
assert_eq!(receipt.actions[6].turn.as_deref(), Some("1"));
|
||||
assert_eq!(receipt.actions[6].at, Some(outcomes[0].ended_at));
|
||||
assert_eq!(receipt.actions[7].turn.as_deref(), Some("2"));
|
||||
assert_eq!(totals.network, 1);
|
||||
assert_eq!(totals.subagents, 1);
|
||||
assert_eq!(totals.approvals.approved_by.posture, 1);
|
||||
@@ -435,14 +451,27 @@ fn session_receipt_reads_transcript_and_approval_log_with_deciders() {
|
||||
receipt.not_recorded
|
||||
);
|
||||
|
||||
let turn_two =
|
||||
session_receipt(session_source_fixture(), &messages, &receipts, Some("2")).expect("turn 2");
|
||||
assert_eq!(turn_two.actions.len(), 3);
|
||||
let turn_two = session_receipt(
|
||||
session_source_fixture(),
|
||||
&messages,
|
||||
&receipts,
|
||||
&outcomes,
|
||||
Some("2"),
|
||||
)
|
||||
.expect("turn 2");
|
||||
assert_eq!(turn_two.actions.len(), 4);
|
||||
assert_eq!(turn_two.totals.failures, 1);
|
||||
assert!(matches!(turn_two.actions[3].what, ActionKind::TurnFailed));
|
||||
assert_eq!(
|
||||
turn_two.actions[3].error.as_deref(),
|
||||
Some("turn budget exhausted")
|
||||
);
|
||||
for missing in ["x", "0", "3", "999"] {
|
||||
let error = session_receipt(
|
||||
session_source_fixture(),
|
||||
&messages,
|
||||
&receipts,
|
||||
&outcomes,
|
||||
Some(missing),
|
||||
)
|
||||
.expect_err("a turn this session does not have");
|
||||
@@ -485,7 +514,7 @@ fn markdown_and_json_share_one_record() {
|
||||
|
||||
#[test]
|
||||
fn empty_session_says_nothing_happened() {
|
||||
let receipt = session_receipt(session_source_fixture(), &[], &[], None).expect("receipt");
|
||||
let receipt = session_receipt(session_source_fixture(), &[], &[], &[], None).expect("receipt");
|
||||
assert_eq!(totals_line(&receipt), "No actions recorded.");
|
||||
assert!(receipt.actions.is_empty());
|
||||
}
|
||||
@@ -499,7 +528,7 @@ fn session_older_than_its_approval_log_does_not_claim_calls_ran_without_asking()
|
||||
];
|
||||
let mut source = session_source_fixture();
|
||||
source.started_at = Some("2026-08-01T00:00:00Z".parse().expect("time"));
|
||||
let receipt = session_receipt(source, &messages, &[], None).expect("receipt");
|
||||
let receipt = session_receipt(source, &messages, &[], &[], None).expect("receipt");
|
||||
assert_eq!(receipt.totals.files_changed, 1);
|
||||
assert_eq!(receipt.totals.ran_without_asking, 0);
|
||||
assert!(
|
||||
@@ -513,7 +542,7 @@ fn session_older_than_its_approval_log_does_not_claim_calls_ran_without_asking()
|
||||
|
||||
let mut recent = session_source_fixture();
|
||||
recent.started_at = Some("2026-09-01T00:00:00Z".parse().expect("time"));
|
||||
let receipt = session_receipt(recent, &messages, &[], None).expect("receipt");
|
||||
let receipt = session_receipt(recent, &messages, &[], &[], None).expect("receipt");
|
||||
assert_eq!(receipt.totals.ran_without_asking, 1);
|
||||
}
|
||||
|
||||
@@ -584,7 +613,7 @@ fn calls_blocked_before_running_are_not_counted_as_run() {
|
||||
];
|
||||
let mut source = session_source_fixture();
|
||||
source.started_at = Some("2026-09-24T00:00:00Z".parse().expect("time"));
|
||||
let receipt = session_receipt(source, &messages, &[], None).expect("receipt");
|
||||
let receipt = session_receipt(source, &messages, &[], &[], None).expect("receipt");
|
||||
|
||||
let statuses: Vec<ActionStatus> = receipt.actions.iter().map(|action| action.status).collect();
|
||||
assert_eq!(
|
||||
@@ -691,8 +720,8 @@ fn host_denial_reads_as_not_answered() {
|
||||
ApprovalReceipt::asked("h1", "bash"),
|
||||
ApprovalReceipt::decided_with("h1", ApprovalOutcome::Denied, Some(ApprovalDecider::Host)),
|
||||
];
|
||||
let receipt =
|
||||
session_receipt(session_source_fixture(), &messages, &receipts, None).expect("receipt");
|
||||
let receipt = session_receipt(session_source_fixture(), &messages, &receipts, &[], None)
|
||||
.expect("receipt");
|
||||
let approvals = &receipt.totals.approvals;
|
||||
assert_eq!((approvals.denied, approvals.not_answered), (0, 1));
|
||||
assert_eq!(
|
||||
@@ -801,7 +830,7 @@ fn shell_file_changes_come_from_the_turn_snapshots() {
|
||||
let mut source = session_source_fixture();
|
||||
source.id = session.to_string();
|
||||
source.workspace = Some(root.display().to_string());
|
||||
let receipt = session_receipt(source, &messages, &[], None).expect("receipt");
|
||||
let receipt = session_receipt(source, &messages, &[], &[], None).expect("receipt");
|
||||
|
||||
let outside = receipt
|
||||
.actions
|
||||
@@ -921,7 +950,7 @@ fn outside_text_cannot_mark_a_call_blocked() {
|
||||
];
|
||||
let mut source = session_source_fixture();
|
||||
source.started_at = Some("2026-09-24T00:00:00Z".parse().expect("time"));
|
||||
let receipt = session_receipt(source, &messages, &[], None).expect("receipt");
|
||||
let receipt = session_receipt(source, &messages, &[], &[], None).expect("receipt");
|
||||
|
||||
let statuses: Vec<(&str, ActionStatus)> = receipt
|
||||
.actions
|
||||
@@ -977,7 +1006,7 @@ fn file_names_cannot_add_receipt_lines_or_escape_codes() {
|
||||
];
|
||||
let mut source = session_source_fixture();
|
||||
source.title = Some("title\nwith a break\u{1b}[2J".into());
|
||||
let receipt = session_receipt(source, &messages, &[], None).expect("receipt");
|
||||
let receipt = session_receipt(source, &messages, &[], &[], None).expect("receipt");
|
||||
let line = action_line(&receipt.actions[0]);
|
||||
assert_eq!(
|
||||
line,
|
||||
@@ -1043,7 +1072,7 @@ fn a_repeated_prompt_does_not_take_another_turns_snapshots() {
|
||||
let mut source = session_source_fixture();
|
||||
source.id = session.to_string();
|
||||
source.workspace = Some(root.display().to_string());
|
||||
let receipt = session_receipt(source, &messages, &[], None).expect("receipt");
|
||||
let receipt = session_receipt(source, &messages, &[], &[], None).expect("receipt");
|
||||
|
||||
let turns: Vec<Option<&str>> = receipt
|
||||
.actions
|
||||
@@ -1083,7 +1112,8 @@ fn session_receipts_join_only_unambiguous_execution_identities() {
|
||||
ApprovalReceipt::asked("first", "bash"),
|
||||
ApprovalReceipt::decided("first", ApprovalOutcome::ApprovedOnce),
|
||||
];
|
||||
let receipt = session_receipt(session_source_fixture(), &messages, &approvals, None).unwrap();
|
||||
let receipt =
|
||||
session_receipt(session_source_fixture(), &messages, &approvals, &[], None).unwrap();
|
||||
let commands = receipt
|
||||
.actions
|
||||
.iter()
|
||||
@@ -1114,7 +1144,7 @@ fn session_receipts_join_only_unambiguous_execution_identities() {
|
||||
ApprovalReceipt::decided("wire", ApprovalOutcome::ApprovedOnce),
|
||||
];
|
||||
let receipt =
|
||||
session_receipt(session_source_fixture(), &ambiguous, &approvals, None).unwrap();
|
||||
session_receipt(session_source_fixture(), &ambiguous, &approvals, &[], None).unwrap();
|
||||
assert!(
|
||||
receipt
|
||||
.actions
|
||||
|
||||
@@ -30,7 +30,7 @@ use std::path::{Component, Path, PathBuf};
|
||||
use std::sync::atomic::AtomicBool;
|
||||
use uuid::Uuid;
|
||||
|
||||
/// Maximum number of active (non-archived) transcripts to retain.
|
||||
/// Maximum active transcripts to retain separately for exec and interactive modes.
|
||||
///
|
||||
/// A transcript that falls out of this window is archived, never unlinked
|
||||
/// (#6136); archived records sit outside the cap until the user prunes them,
|
||||
@@ -1270,7 +1270,16 @@ impl SavedSession {
|
||||
let journal = self.journal.as_mut().expect("journal ensured");
|
||||
journal.branch_to(entry_id)?;
|
||||
self.leaf_id = journal.leaf_id.clone();
|
||||
self.messages = journal.to_messages();
|
||||
let messages = journal.to_messages();
|
||||
let unchanged = self
|
||||
.messages
|
||||
.iter()
|
||||
.zip(&messages)
|
||||
.take_while(|(old, new)| old == new)
|
||||
.count();
|
||||
self.turn_outcomes
|
||||
.retain(|outcome| outcome.after_message_count <= unchanged);
|
||||
self.messages = messages;
|
||||
self.metadata.message_count = self.messages.len();
|
||||
self.metadata.updated_at = Utc::now();
|
||||
Ok(())
|
||||
@@ -2636,6 +2645,7 @@ impl SessionManager {
|
||||
prune: Option<(usize, usize)>,
|
||||
) -> std::io::Result<PathBuf> {
|
||||
let session_id = session.metadata.id.clone();
|
||||
let exec_mode = session.metadata.mode.as_deref() == Some("exec");
|
||||
let path = self.validated_session_path(&session_id)?;
|
||||
// Not a `move` closure: `session` is consumed inside, so inference
|
||||
// captures it by value while `path` and `session_id` stay borrowed for
|
||||
@@ -2677,7 +2687,7 @@ impl SessionManager {
|
||||
|
||||
// Cleanup may delete sessions, so release this session's lifecycle
|
||||
// lock first instead of recursively acquiring it during cleanup.
|
||||
self.cleanup_old_sessions()?;
|
||||
self.cleanup_old_sessions_for_mode(None, Some(exec_mode))?;
|
||||
|
||||
Ok(path)
|
||||
}
|
||||
@@ -4114,7 +4124,8 @@ impl SessionManager {
|
||||
}
|
||||
}
|
||||
|
||||
/// Clean up old sessions to stay within the active cap.
|
||||
/// Clean up old sessions to stay within each mode's active cap.
|
||||
#[cfg(test)]
|
||||
pub fn cleanup_old_sessions(&self) -> std::io::Result<()> {
|
||||
self.cleanup_old_sessions_keeping(None)
|
||||
}
|
||||
@@ -4124,12 +4135,21 @@ impl SessionManager {
|
||||
/// races session restore can retire the just-resumed session when 50+
|
||||
/// newer records exist (its `updated_at` is not bumped until first save).
|
||||
///
|
||||
/// The cap counts *active* transcripts: archived records sit outside it
|
||||
/// until the user prunes them, and empty auto-created stubs get their own
|
||||
/// small cap so they can never push a real transcript out (#6136, #6137).
|
||||
/// The cap counts *active* transcripts separately for exec and interactive
|
||||
/// modes: archived records sit outside it until the user prunes them, and
|
||||
/// empty auto-created stubs get their own small cap per mode so they can
|
||||
/// never push a real transcript out (#6136, #6137).
|
||||
/// A transcript past the cap is archived, never unlinked; the store's
|
||||
/// destructive paths stay the explicit user actions.
|
||||
pub fn cleanup_old_sessions_keeping(&self, keep: Option<&str>) -> std::io::Result<()> {
|
||||
self.cleanup_old_sessions_for_mode(keep, None)
|
||||
}
|
||||
|
||||
fn cleanup_old_sessions_for_mode(
|
||||
&self,
|
||||
keep: Option<&str>,
|
||||
exec_mode: Option<bool>,
|
||||
) -> std::io::Result<()> {
|
||||
// Archiving saves the record, and every save runs retention again.
|
||||
// Drain a backlog in one pass here instead of nesting one cleanup per
|
||||
// archived transcript.
|
||||
@@ -4139,34 +4159,43 @@ impl SessionManager {
|
||||
{
|
||||
return Ok(());
|
||||
}
|
||||
let result = self.cleanup_old_sessions_inner(keep);
|
||||
let result = self.cleanup_old_sessions_inner(keep, exec_mode);
|
||||
self.retention_in_progress
|
||||
.store(false, std::sync::atomic::Ordering::SeqCst);
|
||||
result
|
||||
}
|
||||
|
||||
fn cleanup_old_sessions_inner(&self, keep: Option<&str>) -> std::io::Result<()> {
|
||||
fn cleanup_old_sessions_inner(
|
||||
&self,
|
||||
keep: Option<&str>,
|
||||
exec_mode: Option<bool>,
|
||||
) -> std::io::Result<()> {
|
||||
let records = self.list_session_records()?;
|
||||
|
||||
// What retention owes each class (#6136/#6137): archived records are
|
||||
// already outside the cap; empty auto-created stubs are junk the
|
||||
// product writes on every boot and are capped apart so they can never
|
||||
// occupy a transcript's slot; everything else carries the
|
||||
// MAX_SESSIONS window.
|
||||
let mut active: Vec<&SessionMetadata> = Vec::new();
|
||||
let mut stubs: Vec<(&Path, &SessionMetadata)> = Vec::new();
|
||||
// occupy a transcript's slot; exec and interactive sessions carry
|
||||
// independent MAX_SESSIONS windows.
|
||||
let mut active: [Vec<&SessionMetadata>; 2] = Default::default();
|
||||
let mut stubs: [Vec<(&Path, &SessionMetadata)>; 2] = Default::default();
|
||||
for (path, session) in &records {
|
||||
if session.archived {
|
||||
let is_exec = session.mode.as_deref() == Some("exec");
|
||||
if session.archived || exec_mode.is_some_and(|expected| expected != is_exec) {
|
||||
continue;
|
||||
}
|
||||
let mode = usize::from(is_exec);
|
||||
if is_empty_auto_created_session(session) {
|
||||
stubs.push((path, session));
|
||||
stubs[mode].push((path, session));
|
||||
} else {
|
||||
active.push(session);
|
||||
active[mode].push(session);
|
||||
}
|
||||
}
|
||||
|
||||
for session in active.iter().skip(MAX_SESSIONS) {
|
||||
for session in active
|
||||
.iter()
|
||||
.flat_map(|sessions| sessions.iter().skip(MAX_SESSIONS))
|
||||
{
|
||||
if keep.is_some_and(|id| id == session.id) {
|
||||
continue;
|
||||
}
|
||||
@@ -4183,7 +4212,10 @@ impl SessionManager {
|
||||
}
|
||||
}
|
||||
|
||||
for (listed_path, session) in stubs.iter().skip(MAX_EMPTY_SESSION_STUBS) {
|
||||
for (listed_path, session) in stubs
|
||||
.iter()
|
||||
.flat_map(|sessions| sessions.iter().skip(MAX_EMPTY_SESSION_STUBS))
|
||||
{
|
||||
if keep.is_some_and(|id| id == session.id) {
|
||||
continue;
|
||||
}
|
||||
@@ -4757,6 +4789,11 @@ pub fn update_session(
|
||||
session.ensure_journal();
|
||||
let old_len = session.messages.len();
|
||||
let new_len = messages.len();
|
||||
let common = messages
|
||||
.iter()
|
||||
.zip(session.messages.iter())
|
||||
.take_while(|(a, b)| a == b)
|
||||
.count();
|
||||
if new_len >= old_len && messages[..old_len] == session.messages[..] {
|
||||
if let Some(journal) = session.journal.as_mut() {
|
||||
for msg in &messages[old_len..] {
|
||||
@@ -4767,11 +4804,6 @@ pub fn update_session(
|
||||
} else if (new_len != old_len || messages != session.messages.as_slice())
|
||||
&& let Some(journal) = session.journal.as_mut()
|
||||
{
|
||||
let common = messages
|
||||
.iter()
|
||||
.zip(session.messages.iter())
|
||||
.take_while(|(a, b)| a == b)
|
||||
.count();
|
||||
if common > 0 && common <= journal.entries.len() {
|
||||
let target_id = journal
|
||||
.root_to_leaf()
|
||||
@@ -4795,6 +4827,9 @@ pub fn update_session(
|
||||
}
|
||||
session.messages.clear();
|
||||
session.messages.extend_from_slice(messages);
|
||||
session
|
||||
.turn_outcomes
|
||||
.retain(|outcome| outcome.after_message_count <= common);
|
||||
session.metadata.updated_at = Utc::now();
|
||||
session.metadata.message_count = messages.len();
|
||||
session.metadata.total_tokens = total_tokens;
|
||||
|
||||
@@ -296,16 +296,32 @@
|
||||
let tmp = tempdir().expect("tempdir");
|
||||
|
||||
let messages = vec![make_test_message("user", "Hello")];
|
||||
let session = create_saved_session(&messages, "test-model", tmp.path(), 50, None);
|
||||
let mut session = create_saved_session(&messages, "test-model", tmp.path(), 50, None);
|
||||
session.turn_outcomes.push(SavedTurnOutcome::failed("shared failure", 1));
|
||||
|
||||
let new_messages = vec![
|
||||
make_test_message("user", "Hello"),
|
||||
make_test_message("assistant", "Hi!"),
|
||||
];
|
||||
|
||||
let updated = update_session(session, &new_messages, 100, None);
|
||||
let mut updated = update_session(session, &new_messages, 100, None);
|
||||
assert_eq!(updated.messages.len(), 2);
|
||||
assert_eq!(updated.metadata.total_tokens, 100);
|
||||
assert_eq!(updated.turn_outcomes.len(), 1);
|
||||
let original_leaf = updated.leaf_id.clone().unwrap();
|
||||
updated.turn_outcomes.push(SavedTurnOutcome::failed("old branch failure", 2));
|
||||
let alternate = vec![
|
||||
make_test_message("user", "Hello"),
|
||||
make_test_message("assistant", "Different answer"),
|
||||
];
|
||||
let mut updated = update_session(updated, &alternate, 110, None);
|
||||
assert_eq!(updated.turn_outcomes.len(), 1);
|
||||
assert_eq!(updated.turn_outcomes[0].error, "shared failure");
|
||||
updated.turn_outcomes.push(SavedTurnOutcome::failed("alternate failure", 2));
|
||||
updated.journal_branch_to(&original_leaf).expect("switch sibling branch");
|
||||
assert_eq!(updated.messages, new_messages);
|
||||
assert_eq!(updated.turn_outcomes.len(), 1);
|
||||
assert_eq!(updated.turn_outcomes[0].error, "shared failure");
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -1515,6 +1531,25 @@
|
||||
"{id} is inside the cap and must stay active"
|
||||
);
|
||||
}
|
||||
for index in 0..(MAX_SESSIONS + 3) {
|
||||
let session = create_saved_session_with_mode(
|
||||
&[make_test_message("user", &format!("exec run {index}"))],
|
||||
"test-model",
|
||||
tmp.path(),
|
||||
0,
|
||||
None,
|
||||
Some("exec"),
|
||||
);
|
||||
manager.save_session(&session).expect("save exec session");
|
||||
}
|
||||
let listed = manager.list_sessions().expect("sessions after exec runs");
|
||||
assert_eq!(listed.len(), 2 * (MAX_SESSIONS + 3));
|
||||
for is_exec in [false, true] {
|
||||
assert_eq!(
|
||||
listed.iter().filter(|session| !session.archived && (session.mode.as_deref() == Some("exec")) == is_exec).count(),
|
||||
MAX_SESSIONS,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -1580,4 +1615,4 @@
|
||||
"{id} is among the newest stubs and must stay"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5407,6 +5407,8 @@ impl App {
|
||||
.truncate(unchanged.min(self.api_message_stamps.len()));
|
||||
self.api_message_stamps
|
||||
.resize_with(messages.len(), Utc::now);
|
||||
self.session_turn_outcomes
|
||||
.retain(|outcome| outcome.after_message_count <= unchanged);
|
||||
self.api_messages = messages;
|
||||
unchanged
|
||||
}
|
||||
@@ -5471,12 +5473,15 @@ impl App {
|
||||
self.api_messages_mut().truncate(new_len);
|
||||
self.api_message_stamps
|
||||
.resize_with(self.api_messages.len(), Utc::now);
|
||||
self.session_turn_outcomes
|
||||
.retain(|outcome| outcome.after_message_count <= self.api_messages.len());
|
||||
}
|
||||
|
||||
pub fn clear_api_messages(&mut self) {
|
||||
self.session_journal = crate::session_tree::SessionJournal::new();
|
||||
self.api_messages_mut().clear();
|
||||
self.api_message_stamps.clear();
|
||||
self.session_turn_outcomes.clear();
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
|
||||
@@ -64,6 +64,15 @@ fn set_api_messages_installs_the_shared_snapshot_without_copying() {
|
||||
});
|
||||
assert_eq!(snapshot.len(), 1);
|
||||
assert_eq!(app.api_messages.len(), 2);
|
||||
app.session_turn_outcomes = vec![
|
||||
crate::session_manager::SavedTurnOutcome::failed("shared failure", 1),
|
||||
crate::session_manager::SavedTurnOutcome::failed("replaced failure", 2),
|
||||
];
|
||||
let replacement = Arc::new(vec![snapshot[0].clone(), snapshot[0].clone()]);
|
||||
app.set_api_messages(Arc::clone(&replacement));
|
||||
assert!(Arc::ptr_eq(&app.api_messages, &replacement));
|
||||
assert_eq!(app.session_turn_outcomes.len(), 1);
|
||||
assert_eq!(app.session_turn_outcomes[0].error, "shared failure");
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -2008,26 +2008,9 @@ impl ProviderPickerView {
|
||||
#[must_use]
|
||||
pub(crate) fn with_local_runtime_detected(mut self, detected: bool) -> Self {
|
||||
self.local_runtime_detected = detected;
|
||||
if !self.rows.is_empty() && !self.row_visible(self.selected_idx) {
|
||||
self.selected_idx = (0..self.rows.len())
|
||||
.find(|idx| self.row_visible(*idx))
|
||||
.unwrap_or(0);
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
fn hides_undetected_local(&self, idx: usize) -> bool {
|
||||
self.onboarding_mode
|
||||
&& !self.local_runtime_detected
|
||||
&& !self.rows[idx].is_configured
|
||||
&& self.rows[idx]
|
||||
.provider
|
||||
.provider()
|
||||
.credential_help()
|
||||
.acquisition
|
||||
== CredentialAcquisition::LocalOptional
|
||||
}
|
||||
|
||||
fn tr(&self, id: MessageId) -> Cow<'static, str> {
|
||||
tr(self.locale, id)
|
||||
}
|
||||
@@ -2188,9 +2171,6 @@ impl ProviderPickerView {
|
||||
}
|
||||
|
||||
fn row_visible(&self, idx: usize) -> bool {
|
||||
if self.hides_undetected_local(idx) {
|
||||
return false;
|
||||
}
|
||||
let query = self.query.trim();
|
||||
if !query.is_empty() {
|
||||
return self.rows[idx].matches_query(query);
|
||||
@@ -8434,6 +8414,10 @@ mod tests {
|
||||
"OPENAI_API_KEY",
|
||||
"OPENAI_BASE_URL",
|
||||
"DEEPSEEK_BASE_URL",
|
||||
"OLLAMA_API_KEY",
|
||||
"OLLAMA_BASE_URL",
|
||||
"VLLM_API_KEY",
|
||||
"VLLM_BASE_URL",
|
||||
]
|
||||
.into_iter()
|
||||
.map(EnvVarGuard::remove)
|
||||
@@ -8503,10 +8487,39 @@ mod tests {
|
||||
assert_eq!(app.onboarding, crate::tui::app::OnboardingState::None);
|
||||
assert!(!app.onboarding_recovers_configured_route());
|
||||
assert!(app.should_adopt_live_local_ollama());
|
||||
let picker =
|
||||
ProviderPickerView::new_for_onboarding(app.api_provider, None, &config, None);
|
||||
assert!(!app.local_runtime_detected);
|
||||
let mut picker =
|
||||
ProviderPickerView::new_for_onboarding(app.api_provider, None, &config, None)
|
||||
.with_local_runtime_detected(app.local_runtime_detected);
|
||||
assert_eq!(picker.stage, Stage::List);
|
||||
assert_eq!(picker.selected_provider(), ProviderKind::Deepseek);
|
||||
for (query, provider) in [
|
||||
("olla", ProviderKind::Ollama),
|
||||
("local", ProviderKind::Ollama),
|
||||
("vllm", ProviderKind::Vllm),
|
||||
] {
|
||||
for ch in query.chars() {
|
||||
picker.handle_key(key(KeyCode::Char(ch)));
|
||||
}
|
||||
assert_eq!(picker.query, query);
|
||||
assert!(
|
||||
picker
|
||||
.filtered_rows()
|
||||
.iter()
|
||||
.any(|(_, row)| row.provider == provider)
|
||||
);
|
||||
move_to_provider(&mut picker, provider);
|
||||
assert_eq!(
|
||||
picker.rows[picker.selected_idx].readiness,
|
||||
ResolvedProviderReadiness::LocalUnchecked
|
||||
);
|
||||
assert!(matches!(
|
||||
picker.handle_key(key(KeyCode::Enter)),
|
||||
ViewAction::EmitAndClose(ViewEvent::ProviderPickerApplied { identity })
|
||||
if identity.provider == provider
|
||||
));
|
||||
picker.handle_key(key(KeyCode::Esc));
|
||||
}
|
||||
let runtime = tokio::runtime::Runtime::new().unwrap();
|
||||
runtime
|
||||
.block_on(crate::tui::setup::record_configured_route(&app))
|
||||
@@ -8564,7 +8577,8 @@ mod tests {
|
||||
let _lock = crate::test_support::lock_test_env();
|
||||
let config = Config::default();
|
||||
let picker =
|
||||
ProviderPickerView::new_for_onboarding(ProviderKind::Deepseek, None, &config, None);
|
||||
ProviderPickerView::new_for_onboarding(ProviderKind::Deepseek, None, &config, None)
|
||||
.with_local_runtime_detected(false);
|
||||
|
||||
// First-run setup opens on the full catalog with the active provider
|
||||
// (DeepSeek) selected — hosted APIs are visible immediately, not
|
||||
|
||||
@@ -224,8 +224,9 @@ pub(crate) async fn cycle_permission_posture(
|
||||
|
||||
/// Open the one canonical provider setup surface for onboarding. Fresh
|
||||
/// onboarding opens on the full provider catalog, hosted providers included
|
||||
/// (#5563). Local runtimes are listed, and `L` filters to them, only once one
|
||||
/// answered the startup probe or is already configured. Missing-key
|
||||
/// (#5563). Local runtimes are always listed, as not checked until one answers
|
||||
/// the startup probe; during onboarding, `L` filters to them only after a local
|
||||
/// runtime is detected. Missing-key
|
||||
/// recovery instead focuses the already-configured route so an exact Kimi
|
||||
/// Code K3 configuration can expose its plan route before a secret is entered.
|
||||
/// Either way the picker opens on the navigable list (#4763): onboarding never
|
||||
|
||||
@@ -37,7 +37,10 @@ CODEWHALE_PROVIDER=vllm VLLM_BASE_URL=http://127.0.0.1:8000/v1 VLLM_MODEL=<id> \
|
||||
```
|
||||
|
||||
`codewhale exec` (add `--auto` for tool use) is the non-interactive path to
|
||||
exercise the full agent loop.
|
||||
exercise the full agent loop. `--auto` enables Full Access by default: no
|
||||
Codewhale shell sandbox, with trust mode on. Add `--sandbox workspace-write`
|
||||
to keep the shell sandbox and file-tool workspace restrictions, with trust
|
||||
mode off.
|
||||
|
||||
## Keeping the host awake during a turn
|
||||
|
||||
|
||||
+14
-7
@@ -780,8 +780,10 @@ codewhale exec --json "…" # summary JSON (provid
|
||||
codewhale exec --auto --output-format stream-json "…" # one JSON event per line
|
||||
```
|
||||
|
||||
`--auto` auto-approves shell commands, so use it only in a repo or sandbox you
|
||||
trust.
|
||||
`--auto` enables Full Access by default: tools run without approval, shell
|
||||
commands have no Codewhale sandbox, and trust mode permits file tools to write
|
||||
outside the workspace. Add `--sandbox workspace-write` to keep the shell
|
||||
sandbox and file-tool workspace restrictions, with trust mode off.
|
||||
|
||||
Plain `exec` offers the model no tools. Only `--auto`, `--yolo`,
|
||||
`--allowed-tools` or resuming a session opens a tool surface; limits such as
|
||||
@@ -801,9 +803,12 @@ codewhale exec --continue "…" # headless follow-up to the latest session
|
||||
codewhale exec --resume <id> "…"
|
||||
```
|
||||
|
||||
In v0.10.0, only **TUI sessions** and **`--output-format stream-json`** exec
|
||||
runs are saved. A plain `codewhale exec`/`exec --auto` run is *not* saved, so a
|
||||
following `exec --continue` fails with `No saved sessions found for workspace`.
|
||||
TUI sessions, resumed exec sessions, and exec runs that offer tools (including
|
||||
`exec --auto`) are saved in every output format. `--output-format stream-json`
|
||||
also saves answer-only runs. Use `codewhale receipts --last` for a saved run's
|
||||
receipt. Other answer-only text and `--json` runs are saved only if conversation
|
||||
compaction starts; without that, they create no session for `exec --continue`
|
||||
or a receipt.
|
||||
|
||||
---
|
||||
|
||||
@@ -932,8 +937,10 @@ You installed with npm, Cargo or Homebrew. Update with that tool instead.
|
||||
Run `sudo apt-get install -y libdbus-1-dev pkg-config`.
|
||||
|
||||
**`error: No saved sessions found for workspace …` (from `exec --continue`).**
|
||||
The previous run was plain-text `exec`, which isn't saved. Use the TUI, or
|
||||
`--output-format stream-json`.
|
||||
No session has been saved in this workspace. Fresh answer-only text and `--json`
|
||||
exec runs are saved only if conversation compaction starts; use
|
||||
`--output-format stream-json` to always save them.
|
||||
TUI sessions and exec runs that offer tools are saved in every output format.
|
||||
|
||||
**zsh completion suggests the wrong things after the first word.**
|
||||
Known v0.10.0 bug. bash and fish are fine.
|
||||
|
||||
+2
-1
@@ -171,7 +171,8 @@ From the `stream-json` metadata receipt:
|
||||
| `route_source` | records *why* that route was chosen |
|
||||
| `reasoning_tokens` | present when the receipt reports reasoning; absence can reflect model/provider behavior, configuration, or a harness omission and needs corroboration |
|
||||
| `tool_catalog_sha256` | present when a tool surface was offered |
|
||||
| `approval_posture`, `sandbox_posture` | match the flags you passed |
|
||||
| `approval_posture` | `auto_tools` for the `--auto` command above |
|
||||
| `sandbox_posture` | the policy and its enforcement: Full Access by default with `--auto`; restrictive policies say `local OS sandbox applied` or `policy only; no execution sandbox available`; external execution backends identify filesystem/network isolation as unverified by Codewhale |
|
||||
| `duration_ms`, `input_tokens`, `output_tokens` | present for a completed run |
|
||||
|
||||
Report the receipt fields. Do **not** paste the credential, the key file, or
|
||||
|
||||
+5
-2
@@ -396,8 +396,11 @@ prompt into `codewhale exec --auto --output-format stream-json --prompt-file -`,
|
||||
list models with `codewhale models --json`, and continue a run with
|
||||
`codewhale exec --resume <id>`, taking the id from the `saved_session_id` field
|
||||
of the `session_capture` event; the terminal `metadata` event carries only a
|
||||
fingerprint. [Agent runtime](AGENT_RUNTIME.md#event-vocabulary) describes the
|
||||
event stream.
|
||||
fingerprint. `--auto` enables Full Access by default (no Codewhale shell
|
||||
sandbox, trust mode on); adding `--sandbox workspace-write` keeps the shell
|
||||
sandbox and file-tool workspace restrictions, with trust mode off. These
|
||||
tool-offering exec runs are saved with either plain-text or streaming output.
|
||||
[Agent runtime](AGENT_RUNTIME.md#event-vocabulary) describes the event stream.
|
||||
|
||||
## Config File Location
|
||||
|
||||
|
||||
+2
-1
@@ -337,7 +337,8 @@ See `MCP.md`.
|
||||
Run `codewhale --help` for the canonical list. Common flags:
|
||||
|
||||
- `-p, --prompt <TEXT>`: one-shot prompt mode (prints and exits)
|
||||
- `codewhale exec --auto --output-format stream-json <PROMPT>`: run the tool-backed non-interactive agent and emit one JSON object per line for harnesses and backend wrappers. Exit codes: `0` on success, `1` for genuine task/agent failures, `75` (`EX_TEMPFAIL`) when the turn ended on a retryable infrastructure failure (provider/transport `network`/`timeout` after all in-session retries) so harnesses can tell a retryable infra exit apart from a task failure; the terminal stream `metadata` event's `error_category` carries the same classification
|
||||
- `codewhale exec --auto --output-format stream-json <PROMPT>`: run the tool-backed non-interactive agent and emit one JSON object per line for harnesses and backend wrappers. `--auto` enables Full Access by default (no Codewhale shell sandbox, trust mode on); add `--sandbox workspace-write` to keep the shell sandbox and file-tool workspace restrictions, with trust mode off. Any `--sandbox` other than `danger-full-access` (or the equivalent `sandbox_mode` in config) keeps trust mode off; `external-sandbox` relies on your own isolation. Exec runs that offer tools are saved in every output format. Exit codes: `0` on success, `1` for genuine task/agent failures, `75` (`EX_TEMPFAIL`) when the turn ended on a retryable infrastructure failure (provider/transport `network`/`timeout` after all in-session retries) so harnesses can tell a retryable infra exit apart from a task failure; the terminal stream `metadata` event's `error_category` carries the same classification
|
||||
- Put exec flags before the prompt. A prompt starting with `-` needs `--` first, for example `codewhale exec -- "- explain this option"`. A lone `-` is literal text. Known exec long flags (including `--flag=value`) after the prompt are rejected unless they follow an explicit `--`, which marks them as literal prompt text.
|
||||
- `codewhale exec --prompt-file <PATH>` / `cat prompt.txt | codewhale exec --prompt-file -`: read the prompt from a file or stdin instead of argv, for prompts past the OS per-argument limit (~128 KiB on Linux). Conflicts with a positional prompt, and a positional `-` is literal prompt text; `--prompt-file -` is refused with `--parent-death-watch`, which owns stdin
|
||||
- `codewhale exec --resume <ID|PREFIX> <PROMPT>` / `--session-id <ID|PREFIX>`: continue a saved session non-interactively
|
||||
- `codewhale exec --continue <PROMPT>`: continue the most recent saved session for this workspace non-interactively
|
||||
|
||||
+19
-5
@@ -33,18 +33,24 @@ the turn's own workspace snapshots:
|
||||
|
||||
## Surfaces
|
||||
|
||||
All three share one builder (`crates/tui/src/receipts.rs`), so they cannot
|
||||
disagree.
|
||||
All three share one builder (`crates/tui/src/receipts.rs`), but read different
|
||||
records and can report different coverage.
|
||||
|
||||
| Surface | What it reads |
|
||||
| --- | --- |
|
||||
| `/receipts [json] [<turn>]` in the terminal | The current session's transcript and approval log. `json` prints the object in a code block, so it copies out as valid JSON |
|
||||
| `codewhale receipts [ID\|--last] [--turn T] [--format md\|json]` | A saved session (id or unique prefix) or a Runtime thread (`thr_…`); with no id, the most recently updated one. `receipt` is an alias |
|
||||
| `/receipts [json] [<turn>]` in the terminal | The current session's transcript, approval log, and retained terminal failures. `json` prints the object in a code block, so it copies out as valid JSON |
|
||||
| `codewhale receipts [ID\|--last] [--turn T] [--format md\|json]` | A saved session (id or unique prefix), including its retained terminal failures, or a Runtime thread (`thr_…`); with no id, the most recently updated one. `receipt` is an alias |
|
||||
| `GET /v1/threads/{id}/receipt`, `GET /v1/threads/{id}/turns/{turn_id}/receipt` | A Runtime thread (the app, `codewhale serve`), behind the normal `/v1` bearer boundary |
|
||||
|
||||
All three only read. They never call a provider, run a tool, write a file,
|
||||
or change runtime state.
|
||||
|
||||
Exec runs that offer tools, including `exec --auto`, save a session in every
|
||||
output format, so `codewhale receipts --last` can read their receipts after
|
||||
they finish. Resumed sessions and `--output-format stream-json` runs are also
|
||||
saved. Other answer-only text and `--json` runs are saved only if conversation
|
||||
compaction starts; use `--output-format stream-json` to always keep a session.
|
||||
|
||||
`codewhale receipts` reads Runtime threads from the machine's default store
|
||||
(`tasks/runtime/`, or `$CODEWHALE_RUNTIME_DIR`). A thread kept in one
|
||||
terminal session's own store (`sessions/<id>/runtime/`) is not found by id;
|
||||
@@ -54,11 +60,19 @@ the API reads whatever store its server owns.
|
||||
|
||||
| Session kind | Record | Holds |
|
||||
| --- | --- | --- |
|
||||
| Terminal session | `sessions/<id>.json` | Every tool call and its result text, in order; each prompt's `<turn_meta>` names the posture the turn ran under |
|
||||
| Terminal session | `sessions/<id>.json` | Every tool call and its result text, in order; each prompt's `<turn_meta>` names the posture the turn ran under; `turn_outcomes` records terminal turn status and errors |
|
||||
| Terminal session | `sessions/<id>/approval_receipts.jsonl` | Every approval ask and decision, with time and who decided |
|
||||
| Runtime thread | `tasks/runtime/turns`, `items` | Every tool call with its input, status, start and end time, and structured result (exit code, diff, agent status); each turn's `permission_posture` |
|
||||
| Runtime thread | `tasks/runtime/events/<thread>.jsonl` | `approval.required` / `approval.decided`, with the flags that say who decided |
|
||||
|
||||
The saved-session CLI and live `/receipts` read terminal turn failures,
|
||||
including model errors in exec runs, as `turn_failed` actions and count them
|
||||
toward failures even when no tool failed. Truncating the conversation removes
|
||||
outcomes beyond the retained history, so later turns cannot inherit their failures.
|
||||
Saved sessions keep only the newest 64 recorded failed-turn outcomes. Older outcomes
|
||||
and legacy sessions without this record cannot provide a complete terminal
|
||||
failure history from tool results alone.
|
||||
|
||||
### Who decided an approval
|
||||
|
||||
| Receipt says | Meaning | Recorded as |
|
||||
|
||||
@@ -36,6 +36,8 @@ CODEWHALE_PROVIDER=vllm VLLM_BASE_URL=http://127.0.0.1:8000/v1 VLLM_MODEL=<id> \
|
||||
```
|
||||
|
||||
`codewhale exec`(加上 `--auto` 可启用工具调用)是跑通完整智能体循环的非交互路径。
|
||||
`--auto` 默认启用 Full Access(完全访问):没有 Codewhale shell 沙箱,并开启信任模式。
|
||||
加上 `--sandbox workspace-write` 可保留 shell 沙箱和文件工具的工作区限制,并关闭信任模式。
|
||||
|
||||
## 在回合期间让主机保持唤醒
|
||||
|
||||
|
||||
@@ -606,7 +606,7 @@ codewhale exec --auto --output-format stream-json "…" # one JSON event per l
|
||||
|
||||
(注释含义:单次回答,无工具;启用工具并自动批准;汇总 JSON(提供商、模型、用量、输出);每行一个 JSON 事件。)
|
||||
|
||||
`--auto` 会自动批准 shell 命令,所以只在你信任的仓库或沙箱里使用。
|
||||
`--auto` 默认启用 Full Access(完全访问):工具无需批准即可运行,shell 命令没有 Codewhale 沙箱,信任模式允许文件工具写入工作区以外的路径。加上 `--sandbox workspace-write` 可保留 shell 沙箱和文件工具的工作区限制,并关闭信任模式。
|
||||
|
||||
普通的 `exec` 不给模型提供任何工具。只有 `--auto`、`--yolo`、`--allowed-tools` 或恢复某个会话才会打开工具面;`--max-turns`、`--disallowed-tools`、`--sandbox` 和输出格式这类限制项从不会增加工具(仅对工具有效的参数会打印警告)。如果提供商在输出上限处截断了回复,会要求模型继续,最终打印出的答案是完整的回复。普通运行最多进行 8 个模型步骤,除非用 `--max-turns` 另设上限;在该上限处仍被截断的回复会使这次运行失败。
|
||||
|
||||
@@ -622,7 +622,7 @@ codewhale exec --resume <id> "…"
|
||||
|
||||
(注释含义:会话 ID 或其唯一前缀;继续此目录中最近的会话;列出已保存的会话;对最近会话进行无头跟进。)
|
||||
|
||||
在 v0.10.0 中,只有 **TUI 会话**和 **`--output-format stream-json`** 的 exec 运行会被保存。普通的 `codewhale exec`/`exec --auto` 运行*不会*被保存,所以紧接着的 `exec --continue` 会失败,报 `No saved sessions found for workspace`。
|
||||
TUI 会话、恢复的 exec 会话,以及向模型提供工具的 exec 运行(包括 `exec --auto`)都会保存,无论使用哪种输出格式。`--output-format stream-json` 还会保存仅作答的运行。使用 `codewhale receipts --last` 可查看已保存运行的回执。其他仅作答的纯文本和 `--json` 运行只有在开始压缩对话时才会保存;否则不会为 `exec --continue` 或回执创建会话。
|
||||
|
||||
---
|
||||
|
||||
@@ -727,7 +727,7 @@ Codewhale 没有在 `$HOME` 和它被使用过的仓库之外写入任何东西
|
||||
运行 `sudo apt-get install -y libdbus-1-dev pkg-config`。
|
||||
|
||||
**`error: No saved sessions found for workspace …`(来自 `exec --continue`)。**
|
||||
上一次运行是纯文本的 `exec`,它不会被保存。请使用 TUI,或者 `--output-format stream-json`。
|
||||
此工作区尚无已保存的会话。新建的仅作答纯文本和 `--json` exec 运行只有在开始压缩对话时才会保存;使用 `--output-format stream-json` 可确保保存。TUI 会话和向模型提供工具的 exec 运行会在所有输出格式下保存。
|
||||
|
||||
**zsh 补全在第一个词之后给出错误的建议。**
|
||||
v0.10.0 的已知 bug。bash 和 fish 没问题。
|
||||
|
||||
@@ -154,7 +154,8 @@ CW_SMOKE_MODEL="deepseek-v4-pro"
|
||||
| `route_source` | 记录*为什么*选中了那条路由 |
|
||||
| `reasoning_tokens` | 当回执报告推理时出现;缺失可能反映模型/提供商行为、配置,或 harness 的遗漏,需要旁证 |
|
||||
| `tool_catalog_sha256` | 当提供了工具表面(tool surface)时出现 |
|
||||
| `approval_posture`、`sandbox_posture` | 与你传入的标志一致 |
|
||||
| `approval_posture` | 上面的 `--auto` 命令应为 `auto_tools` |
|
||||
| `sandbox_posture` | 沙箱策略及其执行情况:`--auto` 默认是 Full Access;受限策略会标明 `local OS sandbox applied` 或 `policy only; no execution sandbox available`;外部执行后端会标明文件系统/网络隔离未经 Codewhale 验证 |
|
||||
| `duration_ms`、`input_tokens`、`output_tokens` | 一次完成的运行中会出现 |
|
||||
|
||||
报告回执字段。**不要**粘贴凭据、密钥文件,或提供商的原始错误正文
|
||||
|
||||
@@ -163,7 +163,8 @@ MCP 工具以 `mcp_<server>_<tool>` 暴露,使用与内置工具相同的审
|
||||
运行 `codewhale --help` 获取完整的规范列表。常见标志:
|
||||
|
||||
- `-p, --prompt <TEXT>`:一次性提示模式(打印后退出)
|
||||
- `codewhale exec --auto --output-format stream-json <PROMPT>`:运行带工具的非交互式智能体,并为 harness 和后端封装层每行输出一个 JSON 对象。退出码:`0` 表示成功,`1` 表示真正的任务/智能体失败,`75`(`EX_TEMPFAIL`)表示回合因可重试的基础设施故障而结束(所有会话内重试都用尽之后,提供商/传输层出现 `network`/`timeout`),这样 harness 就能把可重试的基础设施类退出与任务失败区分开;流式输出末尾 `metadata` 事件中的 `error_category` 携带同样的分类
|
||||
- `codewhale exec --auto --output-format stream-json <PROMPT>`:运行带工具的非交互式智能体,并为 harness 和后端封装层每行输出一个 JSON 对象。`--auto` 默认启用 Full Access(完全访问;没有 Codewhale shell 沙箱,开启信任模式);加上 `--sandbox workspace-write` 可保留 shell 沙箱和文件工具的工作区限制,并关闭信任模式。除 `danger-full-access` 外的任何 `--sandbox`(或配置中对应的 `sandbox_mode`)都会保持信任模式关闭;`external-sandbox` 依赖你自行提供的隔离。向模型提供工具的 exec 运行会在所有输出格式下保存。退出码:`0` 表示成功,`1` 表示真正的任务/智能体失败,`75`(`EX_TEMPFAIL`)表示回合因可重试的基础设施故障而结束(所有会话内重试都用尽之后,提供商/传输层出现 `network`/`timeout`),这样 harness 就能把可重试的基础设施类退出与任务失败区分开;流式输出末尾 `metadata` 事件中的 `error_category` 携带同样的分类
|
||||
- 请把 exec 标志放在提示词前。以 `-` 开头的提示词需要先加上 `--`,例如 `codewhale exec -- "- explain this option"`。单独的 `-` 是字面文本。提示词之后出现的已知 exec 长标志(包括 `--flag=value`)会被拒绝,除非它们位于显式的 `--` 之后,此时才按字面提示词文本处理。
|
||||
- `codewhale exec --prompt-file <PATH>` / `cat prompt.txt | codewhale exec --prompt-file -`:从文件或 stdin 读取提示词而不是命令行参数,用于超过操作系统单个参数长度上限(Linux 约 128 KiB)的提示词。不能与位置参数形式的提示词同时使用,位置参数 `-` 按字面文本处理;`--parent-death-watch` 占用 stdin,因此 `--prompt-file -` 与它一起使用会被拒绝
|
||||
- `codewhale exec --resume <ID|PREFIX> <PROMPT>` / `--session-id <ID|PREFIX>`:非交互式继续一个已保存的会话
|
||||
- `codewhale exec --continue <PROMPT>`:非交互式继续此工作区最近的已保存会话
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
$ErrorActionPreference = 'Stop'
|
||||
|
||||
if ([string]::IsNullOrWhiteSpace($env:RUNNER_TEMP)) {
|
||||
throw 'RUNNER_TEMP is required to provision NSIS.'
|
||||
}
|
||||
|
||||
$version = '3.13'
|
||||
$sha256 = 'DB9A1038BBC0E53FEF24F423FD609979BD578E942F1BE1198DB186D1C42652A3'
|
||||
$installer = Join-Path $env:RUNNER_TEMP "nsis-$version-setup.exe"
|
||||
$url = "https://sourceforge.net/projects/nsis/files/NSIS%203/$version/nsis-$version-setup.exe/download"
|
||||
|
||||
try {
|
||||
& curl.exe --fail --location --silent --show-error --proto '=https' --proto-redir '=https' --connect-timeout 15 --max-time 60 --retry 2 --retry-delay 5 --output $installer $url
|
||||
if ($LASTEXITCODE -ne 0) { throw "NSIS download failed with exit code $LASTEXITCODE." }
|
||||
if ((Get-FileHash -LiteralPath $installer -Algorithm SHA256).Hash -ne $sha256) {
|
||||
throw 'NSIS installer checksum mismatch.'
|
||||
}
|
||||
|
||||
$process = Start-Process -FilePath $installer -ArgumentList '/S' -Wait -PassThru
|
||||
if ($process.ExitCode -ne 0) { throw "NSIS setup failed with exit code $($process.ExitCode)." }
|
||||
$makensis = @("${env:ProgramFiles(x86)}\NSIS\makensis.exe", "$env:ProgramFiles\NSIS\makensis.exe") |
|
||||
Where-Object { Test-Path -LiteralPath $_ -PathType Leaf } | Select-Object -First 1
|
||||
if (!$makensis) { throw 'makensis.exe was not found after NSIS setup.' }
|
||||
$installedVersion = (& $makensis '/VERSION').Trim()
|
||||
if ($LASTEXITCODE -ne 0 -or $installedVersion -ne "v$version") {
|
||||
throw "Expected NSIS v$version, found $installedVersion."
|
||||
}
|
||||
Write-Host "NSIS $version verified at $makensis"
|
||||
} finally {
|
||||
Remove-Item -LiteralPath $installer -Force -ErrorAction SilentlyContinue
|
||||
}
|
||||
@@ -30,12 +30,21 @@ notes="$(printf '%s\n' "${section}" | awk '
|
||||
!in_contributors { print }
|
||||
')"
|
||||
|
||||
summary="$(printf '%s\n' "${notes}" | awk '/^### / { in_details = 1 } !in_details { print }')"
|
||||
details="$(printf '%s\n' "${notes}" | awk '/^### / { in_details = 1 } in_details { print }')"
|
||||
if [[ -z "${summary//[[:space:]]/}" ]]; then
|
||||
summary="${notes}"
|
||||
details=""
|
||||
fi
|
||||
|
||||
printf "## What's in %s\n\n" "${tag}"
|
||||
if [[ -n "${summary}" ]]; then
|
||||
printf '%s\n' "${summary}"
|
||||
else
|
||||
printf '%s\n' "See the changelog link below for this release's notes."
|
||||
fi
|
||||
|
||||
cat <<EOF
|
||||
> **Codewhale** is the public product from Shannon Labs. The \`codewhale\`
|
||||
> command, npm package, and release-asset names remain lowercase technical
|
||||
> identifiers. The legacy npm package \`deepseek-tui\` is deprecated and
|
||||
> receives no further releases. Users coming from v0.8.x legacy \`deepseek\` /
|
||||
> \`deepseek-tui\` names should migrate with \`docs/REBRAND.md\`.
|
||||
|
||||
## Install
|
||||
|
||||
@@ -150,13 +159,11 @@ shasum -a 256 -c codewhale-bundles-sha256.txt --ignore-missing
|
||||
shasum -a 256 -c codewhale-artifacts-sha256.txt --ignore-missing
|
||||
\`\`\`
|
||||
|
||||
## What's in ${tag}
|
||||
EOF
|
||||
|
||||
if [[ -n "${notes}" ]]; then
|
||||
printf '%s\n' "${notes}"
|
||||
else
|
||||
printf '%s\n' "See the changelog link below for this release's notes."
|
||||
if [[ -n "${details}" ]]; then
|
||||
printf '%s\n\n' '<details>' '<summary>Full release notes</summary>'
|
||||
printf '%s\n\n' "${details}" '</details>'
|
||||
fi
|
||||
|
||||
cat <<EOF
|
||||
|
||||
@@ -10,6 +10,8 @@ cat >"${tmp_dir}/CHANGELOG.md" <<'EOF'
|
||||
|
||||
## [1.2.3] - 2026-07-14
|
||||
|
||||
Release summary and highlights.
|
||||
|
||||
### Fixed
|
||||
|
||||
- A release fix.
|
||||
@@ -23,6 +25,9 @@ EOF
|
||||
|
||||
body="$("${repo_root}/scripts/release/generate-release-body.sh" v1.2.3 "${tmp_dir}/CHANGELOG.md")"
|
||||
|
||||
[[ "${body%%$'\n'*}" == "## What's in v1.2.3" ]]
|
||||
[[ "${body%%## Install*}" == *"Release summary and highlights."* ]]
|
||||
grep -Fq -- '<summary>Full release notes</summary>' <<<"${body}"
|
||||
grep -Fq -- "- A release fix." <<<"${body}"
|
||||
grep -Fq -- "## Contributors" <<<"${body}"
|
||||
grep -Fq -- "[@example](https://github.com/example)" <<<"${body}"
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
"sources": [
|
||||
{
|
||||
"path": "docs/INSTALL.md",
|
||||
"sha256": "7c3d653c8e367579bc2d1f31577e245b340e9960b7e9762defafee5705c8db28",
|
||||
"content": "# Installing Codewhale\n\n> 阅读简体中文版:[zh_hans/INSTALL.md](zh_hans/INSTALL.md)\n\nCodewhale is an open-source coding agent that runs in your terminal. You give\nit a task (\"fix the failing test\", \"add a CLI flag\"). It reads your repository,\nedits files and runs commands. In the default **Ask** posture it applies file\nedits inside the workspace immediately (and shows you the diff), but asks before\nrunning shell commands, so commit or stash anything you care about first. It\nworks with many model providers. **DeepSeek** is the default.\n\nThe command is `codewhale`. `codew` is a shorter alias for the same program.\n\nThe installation paths were first checked with **v0.10.0** (released 2026-09-22) on a\nfresh **Ubuntu 24.04 x86_64** machine. The dated\n[install receipts](https://github.com/codewhale-hq/Codewhale/blob/37ecdfcc49bc68a9b0d058b97c3946e62c34bd31/docs/install-report/v0.10.0-2026-09-23/RECEIPTS.md) record the commands and output checked at that time. Steps that\ncould not be run on that machine are marked **(untested on this VM: reason)**.\nmacOS, Windows and Android are out of scope, apart from a few notes. A second\npass re-ran the installer, manual-download, archive and npm paths, the no-key\nchecks and zsh completion on **macOS 26.1 (Apple silicon)**; see\n[macOS notes](#macos-notes). Steps that need a model call were not re-run\nthere.\n\nInstall commands that use `latest` resolve to the latest **published** GitHub\nRelease or package. Between releases, `main` may already describe the next\nversion (for example a v0.10.2 source candidate before its tag). A\nprebuilt candidate is available through the official installer only after its\ntag, checksums and release assets exist. Contributors can build `main` now.\n\n## No account needed\n\nCodewhale needs no account. Keys you save with `/provider` or\n`codewhale auth set` stay on your machine; see\n[API keys and providers](#8-api-keys-and-providers). New Codewhale accounts\nare not open, so this guide does not cover account key storage.\n\n## Test and contribute to current source\n\n`latest` selects the latest published release. To test unreleased repairs,\nbuild canonical GitHub `main`, or CNB `main` after verifying its commit matches.\nThe source version number alone does not establish a published package.\n\n```bash\ngit clone --branch main https://github.com/codewhale-hq/CodeWhale.git\ncd CodeWhale\ncargo build --release --locked -p codewhale-cli\ntarget/release/codewhale --version\n```\n\nSee the Cargo section for build prerequisites; use the repository's stable Rust\nselection (declared minimum 1.89). Windows uses `target/release/codewhale.exe`\nand needs MSVC. A development build is separate from a signed release package.\nFor mainland-China downloads and source validation, see [CNB mirror](CNB_MIRROR.md).\nThe [Tencent Lighthouse bootstrap](../scripts/tencent-lighthouse/README.md) is\nbilingual. An npm registry mirror serves the wrapper; native binary downloads\nstill need an available release asset source.\n\n---\n\n## 60-second quickstart (Linux or macOS)\n\n```bash\n# 1. Install. Downloads two checksum-verified binaries into ~/.local/bin (no sudo).\ncurl -fsSL https://codewhale.net/install.sh | sh\n\n# 2. Make sure ~/.local/bin is on your PATH, now and in future terminals.\necho 'export PATH=\"$HOME/.local/bin:$PATH\"' >> ~/.bashrc # zsh: use ~/.zshrc\nexport PATH=\"$HOME/.local/bin:$PATH\"\ncodewhale --version # -> codewhale 0.10.0 (1be1a703b975)\n\n# 3. Give it a DeepSeek API key (from https://platform.deepseek.com/api_keys).\ncodewhale auth set --provider deepseek # prompts for the key; nothing is echoed\ncodewhale auth status --provider deepseek # \"active source: secret store\"\n\n# 4. Run your first task inside a git repository.\ncd ~/your-project\ncodewhale\n```\n\nIn the TUI, type something concrete:\n\n```text\ncreate a Python file primes.py that prints the first 10 primes, run it, and show me the output\n```\n\nCodewhale writes the file, shows you a diff, then asks **APPROVAL: bash\npython3 primes.py – Do you want to proceed?** Press `y` to allow it once. It\nruns the command and reports the output. Press `Ctrl-D` (with an empty input\nbox) to quit. It prints the command to resume the session later.\n\n> **If nothing happens after you send your first message,** you have no key\n> configured. v0.10.0 doesn't warn you in that case. Press **F3**. If DeepSeek\n> shows `missing key`, press Enter, paste the key, then pick a model and\n> confirm.\n\n---\n\n## Contents\n\n1. [Before you start](#1-before-you-start)\n2. [Install: recommended installer](#2-recommended-installer-curl--sh)\n3. [Install: manual download from GitHub Releases](#3-manual-download-from-github-releases)\n4. [Install: npm](#4-npm)\n5. [Install: Cargo / build from source](#5-cargo-and-building-from-source)\n6. [Install: Homebrew (Linux) and Nix](#6-homebrew-on-linux-and-nix)\n7. [Updating and rolling back](#Line truncated
|
||||
"sha256": "546424c432d383168e80eb23797b2e5ba2a6f0d8f04bcc5adb556eca292c77a7",
|
||||
"content": "# Installing Codewhale\n\n> 阅读简体中文版:[zh_hans/INSTALL.md](zh_hans/INSTALL.md)\n\nCodewhale is an open-source coding agent that runs in your terminal. You give\nit a task (\"fix the failing test\", \"add a CLI flag\"). It reads your repository,\nedits files and runs commands. In the default **Ask** posture it applies file\nedits inside the workspace immediately (and shows you the diff), but asks before\nrunning shell commands, so commit or stash anything you care about first. It\nworks with many model providers. **DeepSeek** is the default.\n\nThe command is `codewhale`. `codew` is a shorter alias for the same program.\n\nThe installation paths were first checked with **v0.10.0** (released 2026-09-22) on a\nfresh **Ubuntu 24.04 x86_64** machine. The dated\n[install receipts](https://github.com/codewhale-hq/Codewhale/blob/37ecdfcc49bc68a9b0d058b97c3946e62c34bd31/docs/install-report/v0.10.0-2026-09-23/RECEIPTS.md) record the commands and output checked at that time. Steps that\ncould not be run on that machine are marked **(untested on this VM: reason)**.\nmacOS, Windows and Android are out of scope, apart from a few notes. A second\npass re-ran the installer, manual-download, archive and npm paths, the no-key\nchecks and zsh completion on **macOS 26.1 (Apple silicon)**; see\n[macOS notes](#macos-notes). Steps that need a model call were not re-run\nthere.\n\nInstall commands that use `latest` resolve to the latest **published** GitHub\nRelease or package. Between releases, `main` may already describe the next\nversion (for example a v0.10.2 source candidate before its tag). A\nprebuilt candidate is available through the official installer only after its\ntag, checksums and release assets exist. Contributors can build `main` now.\n\n## No account needed\n\nCodewhale needs no account. Keys you save with `/provider` or\n`codewhale auth set` stay on your machine; see\n[API keys and providers](#8-api-keys-and-providers). New Codewhale accounts\nare not open, so this guide does not cover account key storage.\n\n## Test and contribute to current source\n\n`latest` selects the latest published release. To test unreleased repairs,\nbuild canonical GitHub `main`, or CNB `main` after verifying its commit matches.\nThe source version number alone does not establish a published package.\n\n```bash\ngit clone --branch main https://github.com/codewhale-hq/CodeWhale.git\ncd CodeWhale\ncargo build --release --locked -p codewhale-cli\ntarget/release/codewhale --version\n```\n\nSee the Cargo section for build prerequisites; use the repository's stable Rust\nselection (declared minimum 1.89). Windows uses `target/release/codewhale.exe`\nand needs MSVC. A development build is separate from a signed release package.\nFor mainland-China downloads and source validation, see [CNB mirror](CNB_MIRROR.md).\nThe [Tencent Lighthouse bootstrap](../scripts/tencent-lighthouse/README.md) is\nbilingual. An npm registry mirror serves the wrapper; native binary downloads\nstill need an available release asset source.\n\n---\n\n## 60-second quickstart (Linux or macOS)\n\n```bash\n# 1. Install. Downloads two checksum-verified binaries into ~/.local/bin (no sudo).\ncurl -fsSL https://codewhale.net/install.sh | sh\n\n# 2. Make sure ~/.local/bin is on your PATH, now and in future terminals.\necho 'export PATH=\"$HOME/.local/bin:$PATH\"' >> ~/.bashrc # zsh: use ~/.zshrc\nexport PATH=\"$HOME/.local/bin:$PATH\"\ncodewhale --version # -> codewhale 0.10.0 (1be1a703b975)\n\n# 3. Give it a DeepSeek API key (from https://platform.deepseek.com/api_keys).\ncodewhale auth set --provider deepseek # prompts for the key; nothing is echoed\ncodewhale auth status --provider deepseek # \"active source: secret store\"\n\n# 4. Run your first task inside a git repository.\ncd ~/your-project\ncodewhale\n```\n\nIn the TUI, type something concrete:\n\n```text\ncreate a Python file primes.py that prints the first 10 primes, run it, and show me the output\n```\n\nCodewhale writes the file, shows you a diff, then asks **APPROVAL: bash\npython3 primes.py – Do you want to proceed?** Press `y` to allow it once. It\nruns the command and reports the output. Press `Ctrl-D` (with an empty input\nbox) to quit. It prints the command to resume the session later.\n\n> **If nothing happens after you send your first message,** you have no key\n> configured. v0.10.0 doesn't warn you in that case. Press **F3**. If DeepSeek\n> shows `missing key`, press Enter, paste the key, then pick a model and\n> confirm.\n\n---\n\n## Contents\n\n1. [Before you start](#1-before-you-start)\n2. [Install: recommended installer](#2-recommended-installer-curl--sh)\n3. [Install: manual download from GitHub Releases](#3-manual-download-from-github-releases)\n4. [Install: npm](#4-npm)\n5. [Install: Cargo / build from source](#5-cargo-and-building-from-source)\n6. [Install: Homebrew (Linux) and Nix](#6-homebrew-on-linux-and-nix)\n7. [Updating and rolling back](#Line truncated
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -80,8 +80,8 @@
|
||||
"sources": [
|
||||
{
|
||||
"path": "docs/MODES.md",
|
||||
"sha256": "fd1423c6a30e50205c1f162e8c2cd2442de6ae706a1809f7b2705fdb857a36fa",
|
||||
"content": "# Modes and Permission Postures\n\n> 阅读简体中文版:[zh_hans/MODES.md](zh_hans/MODES.md)\n\nCodewhale has three related concepts:\n\n- **TUI mode**: what kind of visible interaction you're in (Plan/Work/Operate).\n- **Permission posture**: how aggressively the UI asks before executing tools.\n- **Workflow**: named steps that coordinate sub-agents, with dependencies and\n results, available in any TUI mode.\n\nModel selection is separate. `--model auto` and `/model auto` route each turn to\na concrete model and thinking level; they are not TUI modes and are not part of\nthe `Tab` cycle.\n\nWorkflow runs named steps through the same sub-agent runtime; Fleet manages\ntheir saved roles and model assignments. A workflow adds ordering, result\nhandoffs, gates and a progress view. The active mode and permission posture\nstill control what each step may execute.\n\nBefore assigning steps, query `agent(action=\"roster\")` for the saved Fleet\nmodels and roles. A plan child can select a listed model with `model`, or use\nthe saved `role`/`profile` assignment. An Exact Fleet fixes each member's route.\n\n## TUI Modes\n\nPress `Tab` to complete composer menus or cycle through the visible modes\nwhen the composer is empty: **Plan → Work → Operate → Plan**. `Tab` never sends\nor queues composer text; use `Enter` to send or queue it.\nPress `Shift+Tab` to cycle permission posture (Ask → Auto-Review → Full Access).\nEvery change of effective permission writes a `Permissions changed to …` line\nin the transcript.\nPress `Ctrl+T` to cycle reasoning effort.\nRun `/mode` to open the mode picker, or switch directly with `/mode work`,\n`/mode plan`, or `/mode operate`.\n\n- **Plan**: design-first prompting. The stable primitive names remain familiar, but the runtime centrally refuses file mutation and shell execution. Read-only inspection and policy-allowed research, including deferred Web search/fetch, remain available. When a Plan turn successfully finishes a nonempty response, including a prose-only plan, the TUI asks how to continue: Work (Ask), Work (Auto-Review), or keep planning. Work sends the exact approved response as a normal follow-up and preserves that turn's existing To-dos, or adds one pending plan item without replacing unrelated work.\n- **Work** (internally `agent`): ordinary multi-step execution. The first-turn toolbox includes `read`, `write`, `edit`, `file_search`, `bash`, `agent`, `workflow`, `todo_write`, and `load_skill`, plus `create_goal`, `get_goal`, `update_goal`, and `task_shell_wait` so goal and background-shell controls are available without discovery. The agent calls `create_goal` when a request is a durable objective; the host never infers a goal from wording, and the contract must not tell the model otherwise. Approval, sandbox, repository law, and managed policy decide what may execute.\n- **Operate**: Work at full strength, the \"ultra\" mode. Same tools and authority as Work; the difference is how they are used. Each substantive request becomes a goal (`create_goal`), the plan stays visible (`todo_write`), multi-part work runs through `workflow` and parallel `agent` workers, non-trivial changes get an independent reviewer before they are called done, long commands keep running in the background, and recurring or watch-type work is offered as an `automation` (created after approval). It keeps going until the goal is verified, blocked on you, or paused.\n\n`Act` and `/mode act` remain compatibility aliases for Work. Saved settings\nstill normalize to the internal value `agent`.\n\n### Tool availability by mode\n\n| Tool family | Plan | Work | Operate |\n|:---|:---:|:---:|:---:|\n| `read` and policy-allowed deferred research tools | yes | yes | yes |\n| `write` and `edit` | visible names; execution denied | approval- and policy-gated | same as Work |\n| `bash` | visible name; execution denied | approval- and policy-gated | same as Work; delegation is preferred when parallelism or isolation helps |\n| `agent` | yes, subject to child-depth authority | yes, subject to child-depth authority | yes, subject to child-depth authority |\n| Deferred native, MCP, and plugin tools | discoverable through `tool_search` when policy permits | same | same |\n| Paid or external-service tools | follows permission posture | follows permission posture | follows permission posture |\n| Access outside the workspace root | explicit trusted paths only | only through trusted paths or trust mode | same trusted-path/trust policy as Work; fleet profiles never widen it |\n\nOperate changes scheduling emphasis, not authority. It neither adds a\nmode-specific tool denial nor bypasses the active approval, sandbox, shell,\nask-rule, repository-law, or managed-policy boundary. Plan remains the\nmode-specific execution boundary for shell and write-capable tools; that\nauthority difference does not require a different primitive vocabulary.\n\n### Operate loop (one screen)\n\n```text\nUser Line truncated
|
||||
"sha256": "550b10109ca44127de1efd1a92e00fc1e69198054e50e0d6c3923e8236f7d8fe",
|
||||
"content": "# Modes and Permission Postures\n\n> 阅读简体中文版:[zh_hans/MODES.md](zh_hans/MODES.md)\n\nCodewhale has three related concepts:\n\n- **TUI mode**: what kind of visible interaction you're in (Plan/Work/Operate).\n- **Permission posture**: how aggressively the UI asks before executing tools.\n- **Workflow**: named steps that coordinate sub-agents, with dependencies and\n results, available in any TUI mode.\n\nModel selection is separate. `--model auto` and `/model auto` route each turn to\na concrete model and thinking level; they are not TUI modes and are not part of\nthe `Tab` cycle.\n\nWorkflow runs named steps through the same sub-agent runtime; Fleet manages\ntheir saved roles and model assignments. A workflow adds ordering, result\nhandoffs, gates and a progress view. The active mode and permission posture\nstill control what each step may execute.\n\nBefore assigning steps, query `agent(action=\"roster\")` for the saved Fleet\nmodels and roles. A plan child can select a listed model with `model`, or use\nthe saved `role`/`profile` assignment. An Exact Fleet fixes each member's route.\n\n## TUI Modes\n\nPress `Tab` to complete composer menus or cycle through the visible modes\nwhen the composer is empty: **Plan → Work → Operate → Plan**. `Tab` never sends\nor queues composer text; use `Enter` to send or queue it.\nPress `Shift+Tab` to cycle permission posture (Ask → Auto-Review → Full Access).\nEvery change of effective permission writes a `Permissions changed to …` line\nin the transcript.\nPress `Ctrl+T` to cycle reasoning effort.\nRun `/mode` to open the mode picker, or switch directly with `/mode work`,\n`/mode plan`, or `/mode operate`.\n\n- **Plan**: design-first prompting. The stable primitive names remain familiar, but the runtime centrally refuses file mutation and shell execution. Read-only inspection and policy-allowed research, including deferred Web search/fetch, remain available. When a Plan turn successfully finishes a nonempty response, including a prose-only plan, the TUI asks how to continue: Work (Ask), Work (Auto-Review), or keep planning. Work sends the exact approved response as a normal follow-up and preserves that turn's existing To-dos, or adds one pending plan item without replacing unrelated work.\n- **Work** (internally `agent`): ordinary multi-step execution. The first-turn toolbox includes `read`, `write`, `edit`, `file_search`, `bash`, `agent`, `workflow`, `todo_write`, and `load_skill`, plus `create_goal`, `get_goal`, `update_goal`, and `task_shell_wait` so goal and background-shell controls are available without discovery. The agent calls `create_goal` when a request is a durable objective; the host never infers a goal from wording, and the contract must not tell the model otherwise. Approval, sandbox, repository law, and managed policy decide what may execute.\n- **Operate**: Work at full strength, the \"ultra\" mode. Same tools and authority as Work; the difference is how they are used. Each substantive request becomes a goal (`create_goal`), the plan stays visible (`todo_write`), multi-part work runs through `workflow` and parallel `agent` workers, non-trivial changes get an independent reviewer before they are called done, long commands keep running in the background, and recurring or watch-type work is offered as an `automation` (created after approval). It keeps going until the goal is verified, blocked on you, or paused.\n\n`Act` and `/mode act` remain compatibility aliases for Work. Saved settings\nstill normalize to the internal value `agent`.\n\n### Tool availability by mode\n\n| Tool family | Plan | Work | Operate |\n|:---|:---:|:---:|:---:|\n| `read` and policy-allowed deferred research tools | yes | yes | yes |\n| `write` and `edit` | visible names; execution denied | approval- and policy-gated | same as Work |\n| `bash` | visible name; execution denied | approval- and policy-gated | same as Work; delegation is preferred when parallelism or isolation helps |\n| `agent` | yes, subject to child-depth authority | yes, subject to child-depth authority | yes, subject to child-depth authority |\n| Deferred native, MCP, and plugin tools | discoverable through `tool_search` when policy permits | same | same |\n| Paid or external-service tools | follows permission posture | follows permission posture | follows permission posture |\n| Access outside the workspace root | explicit trusted paths only | only through trusted paths or trust mode | same trusted-path/trust policy as Work; fleet profiles never widen it |\n\nOperate changes scheduling emphasis, not authority. It neither adds a\nmode-specific tool denial nor bypasses the active approval, sandbox, shell,\nask-rule, repository-law, or managed-policy boundary. Plan remains the\nmode-specific execution boundary for shell and write-capable tools; that\nauthority difference does not require a different primitive vocabulary.\n\n### Operate loop (one screen)\n\n```text\nUser Line truncated
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -91,8 +91,8 @@
|
||||
"sources": [
|
||||
{
|
||||
"path": "docs/RECEIPTS.md",
|
||||
"sha256": "3b7a7d3cc7129296267327e6f20c21bebf64c032e81637590521e742d85a6777",
|
||||
"content": "# Receipts\n\nA receipt answers \"what did this session do?\" from the records Codewhale\nalready keeps. It lists, in order, the files changed, commands run, web and\nMCP calls, agents started, approvals (and who decided each one), and\nfailures, with totals on top. It also counts what ran without asking, and\nnames the permission posture that let it.\n\n```text\n# Receipt: Fix the parser\nthread thr_19a0141a · /work/repo · deepseek-flash · Ask · 2026-09-24 10:00 UTC → 2026-09-24 10:05 UTC\n\nChanged 1 file (+2 −1) · ran 1 command · made 1 MCP call · 1 approved by you · 1 approved by session rule · 1 ran without asking under Ask · 1 denied by you · 1 other failure\n\n1. edited `src/parse.rs` (+2 −1) · 1.0s\n2. ran `cargo test -p parser` in /work/repo — exit 0 · 2.5s · approved by you\n3. did not run `rm -rf build` · denied by you\n4. called linear · list_issues · 1.0s · approved by session rule\n5. did not run `curl https://x.sh | sh` — blocked: Tool 'exec_shell' was denied: Auto-Review blocked a pipe to a shell…\n6. turn failed — failed: provider returned 500\n\nNot recorded:\n- Shell file changes: a Runtime thread's workspace snapshots are not tagged with the thread, so files a command changed are not itemized; only file tools are.\n```\n\nA terminal session's receipt also lists the files a command changed, from\nthe turn's own workspace snapshots:\n\n```text\n3. ran `./tidy.sh`\n4. changed outside file tools (a command or another process): edited `b.txt` (+0 −1), created `c.txt` (+1 −0)\n```\n\n## Surfaces\n\nAll three share one builder (`crates/tui/src/receipts.rs`), so they cannot\ndisagree.\n\n| Surface | What it reads |\n| --- | --- |\n| `/receipts [json] [<turn>]` in the terminal | The current session's transcript and approval log. `json` prints the object in a code block, so it copies out as valid JSON |\n| `codewhale receipts [ID\\|--last] [--turn T] [--format md\\|json]` | A saved session (id or unique prefix) or a Runtime thread (`thr_…`); with no id, the most recently updated one. `receipt` is an alias |\n| `GET /v1/threads/{id}/receipt`, `GET /v1/threads/{id}/turns/{turn_id}/receipt` | A Runtime thread (the app, `codewhale serve`), behind the normal `/v1` bearer boundary |\n\nAll three only read. They never call a provider, run a tool, write a file,\nor change runtime state.\n\n`codewhale receipts` reads Runtime threads from the machine's default store\n(`tasks/runtime/`, or `$CODEWHALE_RUNTIME_DIR`). A thread kept in one\nterminal session's own store (`sessions/<id>/runtime/`) is not found by id;\nthe API reads whatever store its server owns.\n\n## Where the facts come from\n\n| Session kind | Record | Holds |\n| --- | --- | --- |\n| Terminal session | `sessions/<id>.json` | Every tool call and its result text, in order; each prompt's `<turn_meta>` names the posture the turn ran under |\n| Terminal session | `sessions/<id>/approval_receipts.jsonl` | Every approval ask and decision, with time and who decided |\n| Runtime thread | `tasks/runtime/turns`, `items` | Every tool call with its input, status, start and end time, and structured result (exit code, diff, agent status); each turn's `permission_posture` |\n| Runtime thread | `tasks/runtime/events/<thread>.jsonl` | `approval.required` / `approval.decided`, with the flags that say who decided |\n\n### Who decided an approval\n\n| Receipt says | Meaning | Recorded as |\n| --- | --- | --- |\n| approved by you / denied by you | A person answered: the terminal card, the app, the web mirror, or an API client acting for them | `decided_by: \"user\"`; Runtime event with no `auto` flag |\n| … by session rule | A remembered \"for this session\" rule answered | `decided_by: \"session_rule\"`; Runtime event with `auto` and a `grant_id` |\n| … by posture | The mode or permission posture answered without a prompt | `decided_by: \"posture\"`; Runtime event with `auto` or `posture` |\n| approval timed out | The card expired unanswered | outcome `timeout` |\n| turn stopped while waiting / nobody could be asked | Codewhale could not ask anyone: the turn had ended or stopped, or the request never reached a person. Counted as not answered, never as a denial, even where the record says `denied` | `decided_by: \"host\"` |\n| approved / denied, with no \"by\" | A record written before 0.10.1, or a sub-agent's request. The totals say \"(decider not recorded)\" | no `decided_by` |\n\nThe totals line counts approvals and denials separately, by who gave them:\n`1 approved by you · 1 denied by you` is two decisions.\n\n### Ran without asking\n\nMost calls never produce an approval. Under Full Access nothing asks; under\nAsk, reads and allowed tools run without a prompt, and a remembered rule can\nskip one. Those calls leave no approval record, so the receipt counts them\ninstead: `ran_without_asking` is every file change, command, code run, web\nor MCP call, and agent start that ran with no approval on reLine truncated
|
||||
"sha256": "5402a364db5b3a3bbb74e9fd9913bd7f1b76e3e49104bc2666aa097168550200",
|
||||
"content": "# Receipts\n\nA receipt answers \"what did this session do?\" from the records Codewhale\nalready keeps. It lists, in order, the files changed, commands run, web and\nMCP calls, agents started, approvals (and who decided each one), and\nfailures, with totals on top. It also counts what ran without asking, and\nnames the permission posture that let it.\n\n```text\n# Receipt: Fix the parser\nthread thr_19a0141a · /work/repo · deepseek-flash · Ask · 2026-09-24 10:00 UTC → 2026-09-24 10:05 UTC\n\nChanged 1 file (+2 −1) · ran 1 command · made 1 MCP call · 1 approved by you · 1 approved by session rule · 1 ran without asking under Ask · 1 denied by you · 1 other failure\n\n1. edited `src/parse.rs` (+2 −1) · 1.0s\n2. ran `cargo test -p parser` in /work/repo — exit 0 · 2.5s · approved by you\n3. did not run `rm -rf build` · denied by you\n4. called linear · list_issues · 1.0s · approved by session rule\n5. did not run `curl https://x.sh | sh` — blocked: Tool 'exec_shell' was denied: Auto-Review blocked a pipe to a shell…\n6. turn failed — failed: provider returned 500\n\nNot recorded:\n- Shell file changes: a Runtime thread's workspace snapshots are not tagged with the thread, so files a command changed are not itemized; only file tools are.\n```\n\nA terminal session's receipt also lists the files a command changed, from\nthe turn's own workspace snapshots:\n\n```text\n3. ran `./tidy.sh`\n4. changed outside file tools (a command or another process): edited `b.txt` (+0 −1), created `c.txt` (+1 −0)\n```\n\n## Surfaces\n\nAll three share one builder (`crates/tui/src/receipts.rs`), but read different\nrecords and can report different coverage.\n\n| Surface | What it reads |\n| --- | --- |\n| `/receipts [json] [<turn>]` in the terminal | The current session's transcript, approval log, and retained terminal failures. `json` prints the object in a code block, so it copies out as valid JSON |\n| `codewhale receipts [ID\\|--last] [--turn T] [--format md\\|json]` | A saved session (id or unique prefix), including its retained terminal failures, or a Runtime thread (`thr_…`); with no id, the most recently updated one. `receipt` is an alias |\n| `GET /v1/threads/{id}/receipt`, `GET /v1/threads/{id}/turns/{turn_id}/receipt` | A Runtime thread (the app, `codewhale serve`), behind the normal `/v1` bearer boundary |\n\nAll three only read. They never call a provider, run a tool, write a file,\nor change runtime state.\n\nExec runs that offer tools, including `exec --auto`, save a session in every\noutput format, so `codewhale receipts --last` can read their receipts after\nthey finish. Resumed sessions and `--output-format stream-json` runs are also\nsaved. Other answer-only text and `--json` runs are saved only if conversation\ncompaction starts; use `--output-format stream-json` to always keep a session.\n\n`codewhale receipts` reads Runtime threads from the machine's default store\n(`tasks/runtime/`, or `$CODEWHALE_RUNTIME_DIR`). A thread kept in one\nterminal session's own store (`sessions/<id>/runtime/`) is not found by id;\nthe API reads whatever store its server owns.\n\n## Where the facts come from\n\n| Session kind | Record | Holds |\n| --- | --- | --- |\n| Terminal session | `sessions/<id>.json` | Every tool call and its result text, in order; each prompt's `<turn_meta>` names the posture the turn ran under; `turn_outcomes` records terminal turn status and errors |\n| Terminal session | `sessions/<id>/approval_receipts.jsonl` | Every approval ask and decision, with time and who decided |\n| Runtime thread | `tasks/runtime/turns`, `items` | Every tool call with its input, status, start and end time, and structured result (exit code, diff, agent status); each turn's `permission_posture` |\n| Runtime thread | `tasks/runtime/events/<thread>.jsonl` | `approval.required` / `approval.decided`, with the flags that say who decided |\n\nThe saved-session CLI and live `/receipts` read terminal turn failures,\nincluding model errors in exec runs, as `turn_failed` actions and count them\ntoward failures even when no tool failed. Truncating the conversation removes\noutcomes beyond the retained history, so later turns cannot inherit their failures.\nSaved sessions keep only the newest 64 recorded failed-turn outcomes. Older outcomes\nand legacy sessions without this record cannot provide a complete terminal\nfailure history from tool results alone.\n\n### Who decided an approval\n\n| Receipt says | Meaning | Recorded as |\n| --- | --- | --- |\n| approved by you / denied by you | A person answered: the terminal card, the app, the web mirror, or an API client acting for them | `decided_by: \"user\"`; Runtime event with no `auto` flag |\n| … by session rule | A remembered \"for this session\" rule answered | `decided_by: \"session_rule\"`; Runtime event with `auto` and a `grant_id` |\n| … by posture | The mode or permission posture answered without a prompt | `decided_by: \"Line truncated
|
||||
},
|
||||
{
|
||||
"path": "docs/CONFIGURATION.md",
|
||||
@@ -208,8 +208,8 @@
|
||||
"sources": [
|
||||
{
|
||||
"path": "docs/MCP.md",
|
||||
"sha256": "10aab4090fa923e459f83ccb3f9f02af0bc71d44da6dc4d5b9f24767e2cf92f7",
|
||||
"content": "# MCP (External Tool Servers)\n\nIn the terminal, `/mcp` (also `/mcps`) opens **Extensions → MCP**. Enter opens the selected server’s recovery action or read-only details. An empty inventory offers server suggestions; browsing them installs nothing. Explicit subcommands such as `/mcp status`, `/mcp doctor`, `/mcp login`, and `/mcp add` retain their existing behavior.\n\n\n> 阅读简体中文版:[zh_hans/MCP.md](zh_hans/MCP.md)\n\ncodewhale can load additional tools via MCP (Model Context Protocol). MCP servers can be local stdio processes that the TUI starts, or remote URL-based servers that speak Streamable HTTP with legacy SSE fallback.\n\nBrowsing note:\n- `Web` is the canonical, deferred built-in browsing tool; it provides\n `search`, `fetch`, and `wait` actions when network policy permits.\n- `web_search`, `fetch_url`, and `wait_for_dev_server` are hidden replay-only\n aliases. New prompts and integrations should use `Web`.\n\nServer mode note:\n- `codewhale serve --mcp` runs the MCP stdio server.\n- `codewhale serve --http` runs the runtime HTTP/SSE API (separate mode).\n- `codewhale mcp-server` is an equivalent stdio entrypoint on the same\n consolidated runtime.\n\nIn 0.10.1, the old child-server aggregation proxy is removed. `mcp-server`\nnow uses the same native tool server as `serve --mcp`; it does not launch the\nlegacy `mcp.server_definitions` list. Saved definitions are left intact. Configure\nexternal servers in `mcp.json` for the existing MCP client, or connect to those\nservers directly from your external client. Native server write tools remain\nwithheld unless the operator explicitly permits them in its server configuration.\n\n## Setup wizard vs manual MCP setup (#3407)\n\nThe `/setup` hub includes an optional **Tools and MCP**\nstep. That step is discovery/readiness only:\n\n| Wizard can do | Still requires manual / explicit action |\n| --- | --- |\n| Show configured servers as `healthy` / `needs_config` / `off` | Start or connect MCP servers |\n| Report config path presence (global + project) | Write or edit `mcp.json` contents |\n| Safe static health probe (missing command/url, broken absolute path, missing bearer env) | `codewhale mcp validate`, live connect, OAuth login |\n| Point at safe on-ramps (`/mcp`, `codewhale mcp init`, `codewhale doctor`) | Install community skills, trust skills, enable plugins |\n| Share Hotbar source counts from the same skill/MCP adapters (#3399) | Bind Hotbar slots (Hotbar step / `H`) |\n| Record optional/`needs_action` setup_state without blocking first-run | Anything that spawns processes or installs packages |\n\nEmpty inventory is **not** an error: first-run users see “nothing configured\nyet, that’s fine.” Failing or incomplete configured servers surface as\n`needs_config` with an actionable hint and never block setup completion.\nEnumeration never executes MCP/plugin commands beyond the static probe.\nSummaries redact commands, args, env, headers, and tokens.\n\n`codewhale doctor` reports MCP/skills/tools/plugins health with the same\noptional-surface intent (paths, counts, static checks) so wizard and doctor\nstay consistent.\n\n## Plugin-contributed MCP\n\nA reviewed local plugin bundle may contribute MCP servers without creating a\nsecond transport or approval system. The servers use the same MCP manager,\ntool approval, resource, prompt, timeout, and network-policy paths documented\nhere, and appear under namespaced `<plugin>-<server>` identities.\n\nThe bundle boundary is intentionally stricter than user-authored `mcp.json`:\nunknown fields and ambiguous transports fail closed; stdio environment values\nmust be exact environment-source references; remote literal headers and\nsecret-bearing URLs are rejected; declared network hosts must exactly match\nthe normalized endpoint host set; and redirects remain on the reviewed origin.\nReviewed plugin remotes also bypass ambient HTTP proxy configuration entirely;\nproxy credentials and proxy-observed traffic are not part of the v1 review.\nThe plugin review discloses local host-user authority, structural argv,\nenvironment provenance, endpoint, auth source names, scopes, and tool filters\nwithout reading or printing secret values.\n\nTrust stages reviewed content but does not enable it. Enablement attaches that\nstaged snapshot to the current workspace's MCP pool. Disable, revoke, and other\ncross-process generation changes remove catalog entries, cancel in-flight\noperations, and terminate plugin stdio children. Source or staged-tree drift is\nfully revalidated before each dispatch/catalogue boundary and fails the next\nboundary closed; v0.9.1 does not continuously hash mutable trees during an\nalready-running call and therefore does not promise drift-triggered mid-call\ncancellation. MCP subscriptions are not exposed through plugin bundles. See\n[Plugin bundles](PLUGIN_BUNDLES.md) for the complete lifecycle contract.\n\n## Bootstrap MCP Config\n\nCreate a startLine truncated
|
||||
"sha256": "41d4cb18c0147c52e26204dbe1d0609d558abcbe2dfe2ee3aebd63f5ae913a71",
|
||||
"content": "# MCP (External Tool Servers)\n\nIn the terminal, `/mcp` (also `/mcps`) opens **Extensions → MCP**. Enter opens the selected server’s recovery action or read-only details. An empty inventory offers server suggestions; browsing them installs nothing. Explicit subcommands such as `/mcp status`, `/mcp doctor`, `/mcp login`, and `/mcp add` retain their existing behavior.\n\n\n> 阅读简体中文版:[zh_hans/MCP.md](zh_hans/MCP.md)\n\ncodewhale can load additional tools via MCP (Model Context Protocol). MCP servers can be local stdio processes that the TUI starts, or remote URL-based servers that speak Streamable HTTP with legacy SSE fallback.\n\nBrowsing note:\n- `Web` is the canonical, deferred built-in browsing tool; it provides\n `search`, `fetch`, and `wait` actions when network policy permits.\n- `web_search`, `fetch_url`, and `wait_for_dev_server` are hidden replay-only\n aliases. New prompts and integrations should use `Web`.\n\nServer mode note:\n- `codewhale serve --mcp` runs the MCP stdio server.\n- `codewhale serve --http` runs the runtime HTTP/SSE API (separate mode).\n- `codewhale mcp-server` is an equivalent stdio entrypoint on the same\n consolidated runtime.\n\nIn 0.10.1, the old child-server aggregation proxy is removed. `mcp-server`\nnow uses the same native tool server as `serve --mcp`; it does not launch the\nlegacy `mcp.server_definitions` list. Saved definitions are left intact. Configure\nexternal servers in `mcp.json` for the existing MCP client, or connect to those\nservers directly from your external client. Native server write tools remain\nwithheld unless the operator explicitly permits them in its server configuration.\n\n## Setup wizard vs manual MCP setup (#3407)\n\nThe `/setup` hub includes an optional **Tools and MCP**\nstep. That step is discovery/readiness only:\n\n| Wizard can do | Still requires manual / explicit action |\n| --- | --- |\n| Show configured servers as `healthy` / `needs_config` / `off` | Start or connect MCP servers |\n| Report config path presence (global + project) | Write or edit `mcp.json` contents |\n| Safe static health probe (missing command/url, broken absolute path, missing bearer env) | `codewhale mcp validate`, live connect, OAuth login |\n| Point at safe on-ramps (`/mcp`, `codewhale mcp init`, `codewhale doctor`) | Install community skills, trust skills, enable plugins |\n| Share Hotbar source counts from the same skill/MCP adapters (#3399) | Bind Hotbar slots (Hotbar step / `H`) |\n| Record optional/`needs_action` setup_state without blocking first-run | Anything that spawns processes or installs packages |\n\nEmpty inventory is **not** an error: first-run users see “nothing configured\nyet, that’s fine.” Failing or incomplete configured servers surface as\n`needs_config` with an actionable hint and never block setup completion.\nEnumeration never executes MCP/plugin commands beyond the static probe.\nSummaries redact commands, args, env, headers, and tokens.\n\n`codewhale doctor` reports MCP/skills/tools/plugins health with the same\noptional-surface intent (paths, counts, static checks) so wizard and doctor\nstay consistent.\n\n## Plugin-contributed MCP\n\nA reviewed local plugin bundle may contribute MCP servers without creating a\nsecond transport or approval system. The servers use the same MCP manager,\ntool approval, resource, prompt, timeout, and network-policy paths documented\nhere, and appear under namespaced `<plugin>-<server>` identities.\n\nThe bundle boundary is intentionally stricter than user-authored `mcp.json`:\nunknown fields and ambiguous transports fail closed; stdio environment values\nmust be exact environment-source references; remote literal headers and\nsecret-bearing URLs are rejected; declared network hosts must exactly match\nthe normalized endpoint host set; and redirects remain on the reviewed origin.\nReviewed plugin remotes also bypass ambient HTTP proxy configuration entirely;\nproxy credentials and proxy-observed traffic are not part of the v1 review.\nThe plugin review discloses local host-user authority, structural argv,\nenvironment provenance, endpoint, auth source names, scopes, and tool filters\nwithout reading or printing secret values.\n\nTrust stages reviewed content but does not enable it. Enablement attaches that\nstaged snapshot to the current workspace's MCP pool. Disable, revoke, and other\ncross-process generation changes remove catalog entries, cancel in-flight\noperations, and terminate plugin stdio children. Source or staged-tree drift is\nfully revalidated before each dispatch/catalogue boundary and fails the next\nboundary closed; v0.9.1 does not continuously hash mutable trees during an\nalready-running call and therefore does not promise drift-triggered mid-call\ncancellation. MCP subscriptions are not exposed through plugin bundles. See\n[Plugin bundles](PLUGIN_BUNDLES.md) for the complete lifecycle contract.\n\n## Bootstrap MCP Config\n\nCreate a startLine truncated
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -357,8 +357,8 @@
|
||||
},
|
||||
{
|
||||
"path": "docs/MODES.md",
|
||||
"sha256": "fd1423c6a30e50205c1f162e8c2cd2442de6ae706a1809f7b2705fdb857a36fa",
|
||||
"content": "# Modes and Permission Postures\n\n> 阅读简体中文版:[zh_hans/MODES.md](zh_hans/MODES.md)\n\nCodewhale has three related concepts:\n\n- **TUI mode**: what kind of visible interaction you're in (Plan/Work/Operate).\n- **Permission posture**: how aggressively the UI asks before executing tools.\n- **Workflow**: named steps that coordinate sub-agents, with dependencies and\n results, available in any TUI mode.\n\nModel selection is separate. `--model auto` and `/model auto` route each turn to\na concrete model and thinking level; they are not TUI modes and are not part of\nthe `Tab` cycle.\n\nWorkflow runs named steps through the same sub-agent runtime; Fleet manages\ntheir saved roles and model assignments. A workflow adds ordering, result\nhandoffs, gates and a progress view. The active mode and permission posture\nstill control what each step may execute.\n\nBefore assigning steps, query `agent(action=\"roster\")` for the saved Fleet\nmodels and roles. A plan child can select a listed model with `model`, or use\nthe saved `role`/`profile` assignment. An Exact Fleet fixes each member's route.\n\n## TUI Modes\n\nPress `Tab` to complete composer menus or cycle through the visible modes\nwhen the composer is empty: **Plan → Work → Operate → Plan**. `Tab` never sends\nor queues composer text; use `Enter` to send or queue it.\nPress `Shift+Tab` to cycle permission posture (Ask → Auto-Review → Full Access).\nEvery change of effective permission writes a `Permissions changed to …` line\nin the transcript.\nPress `Ctrl+T` to cycle reasoning effort.\nRun `/mode` to open the mode picker, or switch directly with `/mode work`,\n`/mode plan`, or `/mode operate`.\n\n- **Plan**: design-first prompting. The stable primitive names remain familiar, but the runtime centrally refuses file mutation and shell execution. Read-only inspection and policy-allowed research, including deferred Web search/fetch, remain available. When a Plan turn successfully finishes a nonempty response, including a prose-only plan, the TUI asks how to continue: Work (Ask), Work (Auto-Review), or keep planning. Work sends the exact approved response as a normal follow-up and preserves that turn's existing To-dos, or adds one pending plan item without replacing unrelated work.\n- **Work** (internally `agent`): ordinary multi-step execution. The first-turn toolbox includes `read`, `write`, `edit`, `file_search`, `bash`, `agent`, `workflow`, `todo_write`, and `load_skill`, plus `create_goal`, `get_goal`, `update_goal`, and `task_shell_wait` so goal and background-shell controls are available without discovery. The agent calls `create_goal` when a request is a durable objective; the host never infers a goal from wording, and the contract must not tell the model otherwise. Approval, sandbox, repository law, and managed policy decide what may execute.\n- **Operate**: Work at full strength, the \"ultra\" mode. Same tools and authority as Work; the difference is how they are used. Each substantive request becomes a goal (`create_goal`), the plan stays visible (`todo_write`), multi-part work runs through `workflow` and parallel `agent` workers, non-trivial changes get an independent reviewer before they are called done, long commands keep running in the background, and recurring or watch-type work is offered as an `automation` (created after approval). It keeps going until the goal is verified, blocked on you, or paused.\n\n`Act` and `/mode act` remain compatibility aliases for Work. Saved settings\nstill normalize to the internal value `agent`.\n\n### Tool availability by mode\n\n| Tool family | Plan | Work | Operate |\n|:---|:---:|:---:|:---:|\n| `read` and policy-allowed deferred research tools | yes | yes | yes |\n| `write` and `edit` | visible names; execution denied | approval- and policy-gated | same as Work |\n| `bash` | visible name; execution denied | approval- and policy-gated | same as Work; delegation is preferred when parallelism or isolation helps |\n| `agent` | yes, subject to child-depth authority | yes, subject to child-depth authority | yes, subject to child-depth authority |\n| Deferred native, MCP, and plugin tools | discoverable through `tool_search` when policy permits | same | same |\n| Paid or external-service tools | follows permission posture | follows permission posture | follows permission posture |\n| Access outside the workspace root | explicit trusted paths only | only through trusted paths or trust mode | same trusted-path/trust policy as Work; fleet profiles never widen it |\n\nOperate changes scheduling emphasis, not authority. It neither adds a\nmode-specific tool denial nor bypasses the active approval, sandbox, shell,\nask-rule, repository-law, or managed-policy boundary. Plan remains the\nmode-specific execution boundary for shell and write-capable tools; that\nauthority difference does not require a different primitive vocabulary.\n\n### Operate loop (one screen)\n\n```text\nUser Line truncated
|
||||
"sha256": "550b10109ca44127de1efd1a92e00fc1e69198054e50e0d6c3923e8236f7d8fe",
|
||||
"content": "# Modes and Permission Postures\n\n> 阅读简体中文版:[zh_hans/MODES.md](zh_hans/MODES.md)\n\nCodewhale has three related concepts:\n\n- **TUI mode**: what kind of visible interaction you're in (Plan/Work/Operate).\n- **Permission posture**: how aggressively the UI asks before executing tools.\n- **Workflow**: named steps that coordinate sub-agents, with dependencies and\n results, available in any TUI mode.\n\nModel selection is separate. `--model auto` and `/model auto` route each turn to\na concrete model and thinking level; they are not TUI modes and are not part of\nthe `Tab` cycle.\n\nWorkflow runs named steps through the same sub-agent runtime; Fleet manages\ntheir saved roles and model assignments. A workflow adds ordering, result\nhandoffs, gates and a progress view. The active mode and permission posture\nstill control what each step may execute.\n\nBefore assigning steps, query `agent(action=\"roster\")` for the saved Fleet\nmodels and roles. A plan child can select a listed model with `model`, or use\nthe saved `role`/`profile` assignment. An Exact Fleet fixes each member's route.\n\n## TUI Modes\n\nPress `Tab` to complete composer menus or cycle through the visible modes\nwhen the composer is empty: **Plan → Work → Operate → Plan**. `Tab` never sends\nor queues composer text; use `Enter` to send or queue it.\nPress `Shift+Tab` to cycle permission posture (Ask → Auto-Review → Full Access).\nEvery change of effective permission writes a `Permissions changed to …` line\nin the transcript.\nPress `Ctrl+T` to cycle reasoning effort.\nRun `/mode` to open the mode picker, or switch directly with `/mode work`,\n`/mode plan`, or `/mode operate`.\n\n- **Plan**: design-first prompting. The stable primitive names remain familiar, but the runtime centrally refuses file mutation and shell execution. Read-only inspection and policy-allowed research, including deferred Web search/fetch, remain available. When a Plan turn successfully finishes a nonempty response, including a prose-only plan, the TUI asks how to continue: Work (Ask), Work (Auto-Review), or keep planning. Work sends the exact approved response as a normal follow-up and preserves that turn's existing To-dos, or adds one pending plan item without replacing unrelated work.\n- **Work** (internally `agent`): ordinary multi-step execution. The first-turn toolbox includes `read`, `write`, `edit`, `file_search`, `bash`, `agent`, `workflow`, `todo_write`, and `load_skill`, plus `create_goal`, `get_goal`, `update_goal`, and `task_shell_wait` so goal and background-shell controls are available without discovery. The agent calls `create_goal` when a request is a durable objective; the host never infers a goal from wording, and the contract must not tell the model otherwise. Approval, sandbox, repository law, and managed policy decide what may execute.\n- **Operate**: Work at full strength, the \"ultra\" mode. Same tools and authority as Work; the difference is how they are used. Each substantive request becomes a goal (`create_goal`), the plan stays visible (`todo_write`), multi-part work runs through `workflow` and parallel `agent` workers, non-trivial changes get an independent reviewer before they are called done, long commands keep running in the background, and recurring or watch-type work is offered as an `automation` (created after approval). It keeps going until the goal is verified, blocked on you, or paused.\n\n`Act` and `/mode act` remain compatibility aliases for Work. Saved settings\nstill normalize to the internal value `agent`.\n\n### Tool availability by mode\n\n| Tool family | Plan | Work | Operate |\n|:---|:---:|:---:|:---:|\n| `read` and policy-allowed deferred research tools | yes | yes | yes |\n| `write` and `edit` | visible names; execution denied | approval- and policy-gated | same as Work |\n| `bash` | visible name; execution denied | approval- and policy-gated | same as Work; delegation is preferred when parallelism or isolation helps |\n| `agent` | yes, subject to child-depth authority | yes, subject to child-depth authority | yes, subject to child-depth authority |\n| Deferred native, MCP, and plugin tools | discoverable through `tool_search` when policy permits | same | same |\n| Paid or external-service tools | follows permission posture | follows permission posture | follows permission posture |\n| Access outside the workspace root | explicit trusted paths only | only through trusted paths or trust mode | same trusted-path/trust policy as Work; fleet profiles never widen it |\n\nOperate changes scheduling emphasis, not authority. It neither adds a\nmode-specific tool denial nor bypasses the active approval, sandbox, shell,\nask-rule, repository-law, or managed-policy boundary. Plan remains the\nmode-specific execution boundary for shell and write-capable tools; that\nauthority difference does not require a different primitive vocabulary.\n\n### Operate loop (one screen)\n\n```text\nUser Line truncated
|
||||
},
|
||||
{
|
||||
"path": "docs/public-surface-facts.json",
|
||||
|
||||
@@ -1206,11 +1206,11 @@
|
||||
"title": "Run one job from a script",
|
||||
"blocks": [
|
||||
{
|
||||
"code": "codewhale exec \"Reply with exactly: pong\"\ncodewhale exec --auto \"fix the failing test and run it again\"\ncodewhale exec --auto --output-format stream-json \"update the changelog\"",
|
||||
"code": "codewhale exec \"Reply with exactly: pong\"\ncodewhale exec --auto --sandbox workspace-write \"fix the failing test and run it again\"\ncodewhale exec --auto --sandbox workspace-write --output-format stream-json \"update the changelog\"",
|
||||
"lang": "Terminal"
|
||||
},
|
||||
{
|
||||
"p": "Plain `exec` answers once without tools. `--auto` lets it use tools and approves them automatically, so use it only in a repository or container you trust; it never widens the [sandbox](/docs/sandbox). `--output-format stream-json` prints one JSON event per line and saves the session so `--continue` can pick it up. `--max-turns` and `--allowed-tools` put limits on a run."
|
||||
"p": "Plain `exec` answers once without tools. By default, `--auto` enables Full Access: tools run without asking, shell commands have no Codewhale sandbox, and trust mode lets file tools write outside the workspace. Any `--sandbox` other than `danger-full-access` (or the equivalent `sandbox_mode` in config) keeps trust mode off. Add `--sandbox workspace-write` for the [shell sandbox, where available](/docs/sandbox), and file-tool workspace restrictions; `external-sandbox` relies on your own isolation. Put flags before the prompt, and use `--` before prompt text that starts with `-` or contains literal exec flags. Runs that offer tools are saved in every output format. `--output-format stream-json` prints one JSON event per line and also saves answer-only runs so `--continue` can pick them up. `--max-turns` and `--allowed-tools` put limits on a run."
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -1435,7 +1435,7 @@
|
||||
"codeTerms": true
|
||||
},
|
||||
{
|
||||
"p": "The first two are enforced only where a sandbox is available — on Linux without bubblewrap, and on Windows, they are settings without an OS wrapper behind them. A repository's own config can make the mode stricter, never looser. For one headless run, pass `--sandbox <mode>` to `codewhale exec`; `--auto` approves tools but never widens the sandbox."
|
||||
"p": "The first two are enforced only where a sandbox is available — on Linux without bubblewrap, and on Windows, they are settings without an OS wrapper behind them. A repository's own config can make the mode stricter, never looser. For one headless run, pass `--sandbox <mode>` before the prompt to `codewhale exec`. By default, `--auto` enables Full Access: tools run without asking, shell commands have no Codewhale sandbox, and trust mode lets file tools write outside the workspace. Any `--sandbox` other than `danger-full-access` (or the equivalent `sandbox_mode` in config) keeps trust mode off. Use `--sandbox workspace-write` for the shell sandbox, where available, and file-tool workspace restrictions; `external-sandbox` relies on your own isolation."
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -1206,11 +1206,11 @@
|
||||
"title": "在脚本中运行单个任务",
|
||||
"blocks": [
|
||||
{
|
||||
"code": "codewhale exec \"Reply with exactly: pong\"\ncodewhale exec --auto \"fix the failing test and run it again\"\ncodewhale exec --auto --output-format stream-json \"update the changelog\"",
|
||||
"code": "codewhale exec \"Reply with exactly: pong\"\ncodewhale exec --auto --sandbox workspace-write \"fix the failing test and run it again\"\ncodewhale exec --auto --sandbox workspace-write --output-format stream-json \"update the changelog\"",
|
||||
"lang": "终端"
|
||||
},
|
||||
{
|
||||
"p": "普通的 `exec` 只回答一次,不使用工具。`--auto` 允许它使用工具并自动批准,所以只在你信任的仓库或容器中使用;它绝不会放宽[沙箱](/docs/sandbox)。`--output-format stream-json` 每行输出一个 JSON 事件,并保存会话,以便之后用 `--continue` 接着运行。`--max-turns` 和 `--allowed-tools` 可以为一次运行设定限制。"
|
||||
"p": "普通的 `exec` 只回答一次,不使用工具。`--auto` 默认启用 Full Access(完全访问):工具无需批准即可运行,shell 命令没有 Codewhale 沙箱,信任模式允许文件工具写入工作区以外的路径。除 `danger-full-access` 外的任何 `--sandbox`(或配置中对应的 `sandbox_mode`)都会保持信任模式关闭。加上 `--sandbox workspace-write` 可在可用时启用 [shell 沙箱](/docs/sandbox),并保留文件工具的工作区限制;`external-sandbox` 则依赖你自行提供的隔离。请把标志放在提示词前;提示词以 `-` 开头或包含需要按字面理解的 exec 标志时,应先加上 `--`。向模型提供工具的运行会在所有输出格式下保存。`--output-format stream-json` 每行输出一个 JSON 事件,也会保存仅作答的运行,以便之后用 `--continue` 接着运行。`--max-turns` 和 `--allowed-tools` 可以为一次运行设定限制。"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -1435,7 +1435,7 @@
|
||||
"codeTerms": true
|
||||
},
|
||||
{
|
||||
"p": "前两种模式只有在沙箱可用时才会真正生效——在没有 bubblewrap 的 Linux 上,以及在 Windows 上,它们只是设置,背后没有操作系统沙箱。仓库自带的配置只能让模式更严格,不能更宽松。对单次无界面运行,可以给 `codewhale exec` 传 `--sandbox <mode>`;`--auto` 只会自动批准工具,绝不会放宽沙箱。"
|
||||
"p": "前两种模式只有在沙箱可用时才会真正生效——在没有 bubblewrap 的 Linux 上,以及在 Windows 上,它们只是设置,背后没有操作系统沙箱。仓库自带的配置只能让模式更严格,不能更宽松。对单次无界面运行,可以在 `codewhale exec` 的提示词前传入 `--sandbox <mode>`。`--auto` 默认启用 Full Access(完全访问):工具无需批准即可运行,shell 命令没有 Codewhale 沙箱,信任模式允许文件工具写入工作区以外的路径。除 `danger-full-access` 外的任何 `--sandbox`(或配置中对应的 `sandbox_mode`)都会保持信任模式关闭。使用 `--sandbox workspace-write` 可在沙箱可用时启用 shell 沙箱,并保留文件工具的工作区限制;`external-sandbox` 则依赖你自行提供的隔离。"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -21,12 +21,12 @@ export const docsRuntimeApi: DocsRuntimeApiDict = {
|
||||
blocks: [
|
||||
{
|
||||
code: `codewhale exec "Reply with exactly: pong"
|
||||
codewhale exec --auto "fix the failing test and run it again"
|
||||
codewhale exec --auto --output-format stream-json "update the changelog"`,
|
||||
codewhale exec --auto --sandbox workspace-write "fix the failing test and run it again"
|
||||
codewhale exec --auto --sandbox workspace-write --output-format stream-json "update the changelog"`,
|
||||
lang: "Terminal",
|
||||
},
|
||||
{
|
||||
p: "Plain `exec` answers once without tools. `--auto` lets it use tools and approves them automatically, so use it only in a repository or container you trust; it never widens the [sandbox](/docs/sandbox). `--output-format stream-json` prints one JSON event per line and saves the session so `--continue` can pick it up. `--max-turns` and `--allowed-tools` put limits on a run.",
|
||||
p: "Plain `exec` answers once without tools. By default, `--auto` enables Full Access: tools run without asking, shell commands have no Codewhale sandbox, and trust mode lets file tools write outside the workspace. Any `--sandbox` other than `danger-full-access` (or the equivalent `sandbox_mode` in config) keeps trust mode off. Add `--sandbox workspace-write` for the [shell sandbox, where available](/docs/sandbox), and file-tool workspace restrictions; `external-sandbox` relies on your own isolation. Put flags before the prompt, and use `--` before prompt text that starts with `-` or contains literal exec flags. Runs that offer tools are saved in every output format. `--output-format stream-json` prints one JSON event per line and also saves answer-only runs so `--continue` can pick them up. `--max-turns` and `--allowed-tools` put limits on a run.",
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
@@ -85,7 +85,7 @@ prefer_bwrap = false`,
|
||||
codeTerms: true,
|
||||
},
|
||||
{
|
||||
p: "The first two are enforced only where a sandbox is available — on Linux without bubblewrap, and on Windows, they are settings without an OS wrapper behind them. A repository's own config can make the mode stricter, never looser. For one headless run, pass `--sandbox <mode>` to `codewhale exec`; `--auto` approves tools but never widens the sandbox.",
|
||||
p: "The first two are enforced only where a sandbox is available — on Linux without bubblewrap, and on Windows, they are settings without an OS wrapper behind them. A repository's own config can make the mode stricter, never looser. For one headless run, pass `--sandbox <mode>` before the prompt to `codewhale exec`. By default, `--auto` enables Full Access: tools run without asking, shell commands have no Codewhale sandbox, and trust mode lets file tools write outside the workspace. Any `--sandbox` other than `danger-full-access` (or the equivalent `sandbox_mode` in config) keeps trust mode off. Use `--sandbox workspace-write` for the shell sandbox, where available, and file-tool workspace restrictions; `external-sandbox` relies on your own isolation.",
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
@@ -16,12 +16,12 @@ export const docsRuntimeApi: DocsRuntimeApiDict = {
|
||||
blocks: [
|
||||
{
|
||||
code: `codewhale exec "Reply with exactly: pong"
|
||||
codewhale exec --auto "fix the failing test and run it again"
|
||||
codewhale exec --auto --output-format stream-json "update the changelog"`,
|
||||
codewhale exec --auto --sandbox workspace-write "fix the failing test and run it again"
|
||||
codewhale exec --auto --sandbox workspace-write --output-format stream-json "update the changelog"`,
|
||||
lang: "终端",
|
||||
},
|
||||
{
|
||||
p: "普通的 `exec` 只回答一次,不使用工具。`--auto` 允许它使用工具并自动批准,所以只在你信任的仓库或容器中使用;它绝不会放宽[沙箱](/docs/sandbox)。`--output-format stream-json` 每行输出一个 JSON 事件,并保存会话,以便之后用 `--continue` 接着运行。`--max-turns` 和 `--allowed-tools` 可以为一次运行设定限制。",
|
||||
p: "普通的 `exec` 只回答一次,不使用工具。`--auto` 默认启用 Full Access(完全访问):工具无需批准即可运行,shell 命令没有 Codewhale 沙箱,信任模式允许文件工具写入工作区以外的路径。除 `danger-full-access` 外的任何 `--sandbox`(或配置中对应的 `sandbox_mode`)都会保持信任模式关闭。加上 `--sandbox workspace-write` 可在可用时启用 [shell 沙箱](/docs/sandbox),并保留文件工具的工作区限制;`external-sandbox` 则依赖你自行提供的隔离。请把标志放在提示词前;提示词以 `-` 开头或包含需要按字面理解的 exec 标志时,应先加上 `--`。向模型提供工具的运行会在所有输出格式下保存。`--output-format stream-json` 每行输出一个 JSON 事件,也会保存仅作答的运行,以便之后用 `--continue` 接着运行。`--max-turns` 和 `--allowed-tools` 可以为一次运行设定限制。",
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
@@ -80,7 +80,7 @@ prefer_bwrap = false`,
|
||||
codeTerms: true,
|
||||
},
|
||||
{
|
||||
p: "前两种模式只有在沙箱可用时才会真正生效——在没有 bubblewrap 的 Linux 上,以及在 Windows 上,它们只是设置,背后没有操作系统沙箱。仓库自带的配置只能让模式更严格,不能更宽松。对单次无界面运行,可以给 `codewhale exec` 传 `--sandbox <mode>`;`--auto` 只会自动批准工具,绝不会放宽沙箱。",
|
||||
p: "前两种模式只有在沙箱可用时才会真正生效——在没有 bubblewrap 的 Linux 上,以及在 Windows 上,它们只是设置,背后没有操作系统沙箱。仓库自带的配置只能让模式更严格,不能更宽松。对单次无界面运行,可以在 `codewhale exec` 的提示词前传入 `--sandbox <mode>`。`--auto` 默认启用 Full Access(完全访问):工具无需批准即可运行,shell 命令没有 Codewhale 沙箱,信任模式允许文件工具写入工作区以外的路径。除 `danger-full-access` 外的任何 `--sandbox`(或配置中对应的 `sandbox_mode`)都会保持信任模式关闭。使用 `--sandbox workspace-write` 可在沙箱可用时启用 shell 沙箱,并保留文件工具的工作区限制;`external-sandbox` 则依赖你自行提供的隔离。",
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
Reference in new issue
Block a user