Die Claude-CLI bietet unter Windows kein "Bash"-Tool an, sondern ein
separates Shell-Tool "PowerShell" (eigener Tool-Name + Permission-Regel).
Ohne PowerShell(*) fiel jeder Shell-Aufruf headless auf "ask" und wurde
still abgelehnt ("keine Permissions"). Auf Linux/macOS harmlos.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Entkoppelt "Server erzeugen" von "Server erlauben": Ein MCP-Eintrag ohne
URL erzeugt keinen eigenen (kollidierenden) HTTP-Server mehr, steuert aber
weiterhin die Allowlist-Freigabe mcp__<name>__* bei. Gedacht für extern
(z.B. stdio via ~/.claude.json) laufende Server, die gott nur erlauben,
aber nicht selbst starten soll – sonst kollidiert gotts URL-Server mit dem
gleichnamigen externen und der Server verschwindet ganz.
- ParseMcpServers: Url optional (null erlaubt), nur Name+leer wird verworfen
- Frontend: Name genügt, URL-Placeholder + Hinweistext angepasst
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Die Claude-CLI-Permission-Engine parst eine Allowlist-Regel via split("__")
zu {serverName, toolName} und vergleicht den Servernamen per strenger
Gleichheit (===); ein '*' wirkt ausschliesslich im Tool-Teil, nie im
Server-Teil. Die generalisierte Form "mcp__*<name>*" parste damit zu einem
Server namens "*<name>*" und matchte NIE -> jeder ueber die MCP-Liste
eingetragene Server wurde headless still abgelehnt (Regression aus 5f7dec6).
- ClaudeCliService.cs: Allowlist-Glob mcp__*<name>* -> mcp__<name>__*
(exakter Server + Tool-Wildcard, dieselbe Form wie mcp__web-search-prime__*);
Kommentar erklaert die strenge Server-Gleichheit.
- index.html: UI-Hinweis korrigiert - Name muss exakt dem Tool-Praefix
entsprechen (z.B. UnityMCP, nicht Unity); Freigabe als mcp__<name>__*.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Bisher wurden Workflow-Subagent-Outputs nur beim sauberen FinalizeChain in
die DB gerettet - bei Abbruch (529/Timeout/Stop/Hard-Kill) war alles weg,
Tokens standen auf 0.
- A) Inkrementelle Persistenz: MaybeFlushWorkflowProgress() (throttled 6s)
schreibt workflow_info + Token + runId waehrend des Laufs -> ueberlebt
Hard-Kill (OOM/Redeploy), wo kein catch/finally laeuft.
- B) Output-Rettung: ReadLive liest jetzt vollstaendige Subagent-Outputs aus
journal.jsonl (nicht nur Counts), inkl. State.
- C) Token-Fix: neuer assistant-Branch -> CliEventType.Usage; EffectiveUsage()
rettet Orchestrator-Token bei Abbruch statt 0.
- D) Resume: Feld/Migration workflow_run_id; FinalizeChain persistiert die
runId; naechster Chat injiziert einen resumeFromRunId-Hinweis.
- UI: Workflow-Status-Modal zeigt geretteten Output + runId/"fortsetzbar"-Banner.
Build 0/0, ReadLive gegen echtes journal.jsonl verifiziert, adversarial 2x geprueft.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- MCP: replace fixed single Unity field with a generic list of servers
({name, url, token?}); dynamic mcp-config + allowlist glob mcp__*<name>*
per entry; new mcp-servers-ui.js editor (no data migration)
- Models: frontend refresh button wired to existing POST /api/models/refresh,
reloads optgroups and restores selection
- Model: add sonnet-5 alias + dropdown option (bare "sonnet" stays 4.6)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Ergänzt mcp__UnityMCP__* neben mcp__unity__* in der --allowed-tools-Liste
(innerhalb von hasUnityMcp), damit ein unter dem Namen "UnityMCP" statt
"unity" laufender MCP-Server im headless -p-Pfad nicht still abgelehnt wird.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Die runId ist bereits mit "wf_" praefixiert; der Code erzeugt
<proj>/workflows/<runId>.json. Die Kurz-Referenzen in den Code-Kommentaren
(WorkflowProgressTracker, ClaudeCliService, AnthropicService, SessionEndpoint)
nutzten faelschlich das doppelte "wf_"-Praefix.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Dynamic ultracode workflows run as a detached background task with their
own transcript dir, so their subagent events never flow through the main
-p stream. The previous parent_tool_use_id tap therefore captured nothing
for real workflows and the status stayed "none" the whole run.
Replace the tap with a file-based reader:
- TapWorkflowLaunch parses the "Transcript dir:" line from the Workflow
tool_result and registers the run.
- WorkflowProgressTracker becomes a per-session registry of transcript
paths (no longer a stream accumulator).
- WorkflowTelemetryReader reads journal.jsonl for live counts (running)
and <runId>.json for rich per-agent telemetry (completed); FinalizeChain
persists the rich JSON into chains.workflow_info.
- Modal renders phases + a per-agent list (label/phase/state/tokens/
tool-calls/duration) instead of the obsolete tool breakdown.
Sync ARCHITECTURE.md, ARCHITECTURE_QUICK.md and README.md to the new
mechanism.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Workflow-status: a new WorkflowProgressTracker singleton taps the
suppressed dynamic-workflow subagent events (those carrying
parent_tool_use_id) into per-session telemetry without altering the
existing guard; the snapshot is serialized into the new chains.workflow_info
column on FinalizeChain (ChainId-matched so a panel member of the same
session cannot clear it) and exposed via GET /api/sessions/{id}/workflow-status
(live -> persisted -> none). The header menu gains a 'Workflow-Status' entry
with a modal that live-polls every 2s while running and self-stops on close.
Panel on-demand: Fusion/MoA is now a transient per-request multiModelMode
flag (like plan/ultracode) instead of a persisted session column. Session
settings keep only the panel members + moa_layers; the mode <select> was
removed and the composer dropdown drives the mode per request.
Docs: ARCHITECTURE.md, ARCHITECTURE_QUICK.md and README.md updated for both
features plus the already-shipped z.ai/GLM provider, GLM 5.2+ effort
passthrough, web-search-prime MCP and the ultracode toggle.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
A new transient per-request toggle state (off→plan→ultracode→fusion→moa)
that whitelists the CLI's Workflow + Task tools so Anthropic's native
dynamic-workflow orchestration runs in gott's headless -p mode without a
permission gate (the engine silently denies Workflow otherwise). Effort is
raised to xhigh (the real ultracode equivalent; "ultracode" itself is not a
valid effort value) without downgrading an explicit max. Only enabled for
Claude models (z.ai/GLM has no workflow runtime) and not in plan mode. The
frontend injects a "use a workflow" hint, like plan mode injects its own.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
GLM models cannot run Anthropic's server-side WebSearch/WebFetch, so when a
GLM model has web search enabled and ZaiApiKey is set, GenerateMcpConfig
registers z.ai's web_search_prime HTTP MCP server and CreateCliStartInfo
allows mcp__web-search-prime__* while disallowing the native WebSearch/WebFetch
tools — otherwise the model tries the (headless-ungranted) native tool first
and only falls back to the MCP search on the second attempt.
Effort is now passed through for GLM-5.2 and newer (version compare, not a
prefix match, so 5.3/6 are picked up automatically and glm-5.2[1m]/glm-5-turbo
parse correctly); older GLM models still drop CLAUDE_CODE_EFFORT_LEVEL.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Route glm:-prefixed models through the CLI/Anthropic path: ResolveModelId
strips the glm: prefix, and CreateCliStartInfo activates the z.ai
Anthropic-compatible endpoint (ANTHROPIC_BASE_URL/AUTH_TOKEN) only for that
process when IsZaiModel matches, leaving every other request's OAuth login
untouched. GLM model list is loaded through the existing model cache and
exposed via /api/models/glm with a "GLM (z.ai)" optgroup in the agent form.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
When a panel member spawned a subagent via the Agent tool, the Claude CLI
emitted the subagent's internal steps as separate top-level messages
carrying parent_tool_use_id: tool_use blocks arrived as type:"assistant"
(no handler → dropped) and the matching tool_result as type:"user", which
created a nameless, label-less collapsible box in the frontend — both in
the live stream and in the persisted history (same segment source).
Skip any top-level event with a non-empty parent_tool_use_id at the single
stream JSON parser, so subagent internals never become CliStreamEvents.
This covers worker and panel-member paths at once. The Agent tool call
itself (parent_tool_use_id=null) stays visible, and the final result event
— which aggregates subagent tokens — carries no parent_tool_use_id, so the
token balance is unaffected.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Two bugs surfaced when driving the composite toggle (off→plan→fusion→moa)
in an all-CLI setup (no API keys):
1. MoA ran only 1 round instead of the configured 2. cycleCompositeMode
fired the multiModelMode PATCH un-serialized and sendMessage did not
await it, so a message sent right after toggling loaded the session
before 'moa' was committed → the backend read the prior 'fusion' value
→ 1 round. Persisted totalLayers in the DB confirmed fusion (1) for all
post-toggle chains. Serialize mode PATCHes into a promise chain (last
click wins, in order) and await it in sendMessage/sendMessageDirect.
2. A read-only panel member could still write files. ClaudeCliService
hard-coded --permission-mode acceptEdits, which auto-accepts Write/Edit
regardless of --allowed-tools, so a member running with planMode=true
(tools limited to Read/Glob/Grep) could still call write_file. Use
'plan' when planMode is set; this also closes the same latent hole for
regular plan-mode users on the shared CLI path.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The Claude CLI child process inherited the gott server's CWD because
CreateCliStartInfo never set WorkingDirectory. On Linux systemd usually
sets WorkingDirectory= to the workspace, so it worked by accident; on
Windows the service starts from its install directory, so the CLI's own
built-in tools resolved relative patterns (e.g. Glob "Sources/**")
against the wrong directory and returned "No files found", while
absolute paths still worked. --add-dir only grants access, it does not
set the CWD.
Thread the workspace through ChatStreamingAsync -> RunCliStreamingAsync
-> CreateCliStartInfo and set psi.WorkingDirectory (guarded by
Directory.Exists). GetStatusAsync stays without a CWD.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Opus 4.5+ and Sonnet 4.6+ support a new "effort" knob that controls how
much budget the model spends on thinking and tool calls. Plumb it through
end to end so each agent can pick its own level.
Storage & shape:
- New TEXT column agents.effort (default '') added via TryAddColumn.
- AgentRecord.Effort + INSERT/UPDATE in DatabaseService.Agents.cs.
- ChatContext.Effort + SubAgentContext.Effort so the value travels with the
request alongside model and tool settings.
Agent editor:
- Effort dropdown above git-commit behavior in the agent form (low/medium/
high/xhigh/max plus empty = "use default"). Always visible; on OpenAI
providers the value is sent but silently ignored.
- agent-page.js load/save and AgentEndpoint create/update wired up.
Anthropic API path:
- StreamChat and RunNonStreamingToolLoop add output_config: { effort } when
effort is set and not "high" – empty/null/"high" means "omit and let the
API pick its default".
- Sub-agents (preparer/review/finalizer) get the parameter through
RunAgentChat so each step uses its own agent's effort.
Anthropic CLI path:
- ClaudeCliService.ChatStreamingAsync takes an effort parameter and exports
CLAUDE_CODE_EFFORT_LEVEL on the spawned process. Env-var beats the
--effort flag because it also covers "max" and "ultracode".
- StreamChatViaCli, ChatNonStreamingViaCli, RunSubAgentViaCli, and the
ChatEndpoint anthropic branches all hand the value through.
ARCHITECTURE.md / ARCHITECTURE_QUICK.md updated with the new field.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Anthropic hat Anfang März 2026 die Default-Cache-TTL stillschweigend
von 1h auf 5min gesenkt. Bei Sessions mit Pausen >5min wird der Cache
jedes Mal neu geschrieben (teuer). Dieser Commit aktiviert die
extended 1h-TTL über beide Pfade.
API-Pfad (AnthropicService):
- Beta-Header "extended-cache-ttl-2025-04-11" hinzugefügt
- Falsches Top-Level cache_control (Root-Level wurde ignoriert) entfernt
- Neue Helper ApplyCacheControlToLast() setzt cache_control idempotent
auf das letzte Element via JSON-Roundtrip zu Dictionary
- 2 Cache-Breakpoints pro Iteration:
* Letztes Tool (cached gesamten Tool-Block)
* Letzter System-Prompt-Block (cached System-Prompt)
- Sub-Agent-Loop (Preparer/Review/Finalizer): String-System-Prompt wird
bei Bedarf in Block-Form mit cache_control konvertiert
CLI-Pfad (ClaudeCliService):
- Env-Var ENABLE_PROMPT_CACHING_1H=1 für jeden CLI-Child-Prozess gesetzt
(offizieller Opt-in seit Claude CLI 2.1.108, gilt für API-Key,
Bedrock, Vertex, Foundry)
Aktivierung: Umgebungsvariable GOTT_CLI_DEBUG_BYTES=1
Im Debug-Modus wird ein TeeReadStream zwischengeschaltet, der alle rohen Bytes
vom Claude-CLI-Prozess in eine .bin-Datei schreibt (vor dem UTF-8-Decode).
Zusätzlich wird jedes Vorkommen von U+FFFD im decoded Output mit Position,
Kontext und FFFD-Counter in eine .log-Datei protokolliert.
Logs landen in data/cli-debug/cli-stdout-{timestamp}.{bin,log}.
So können wir das intermittierende �-Problem auf Windows beweisbar einkreisen:
- Wenn .bin valide UTF-8-Bytes enthält aber .log FFFD-Treffer hat → unser Decoder
- Wenn .bin bereits invalide Bytes (CP1252) enthält → Claude-CLI/Node ist schuld
- Wenn .bin bereits EF BF BD enthält → Anthropic-Server schickt schon kaputt
Im Default-Modus (Env-Var nicht gesetzt) bleibt der ursprüngliche Default-Reader
aktiv – kein zusätzlicher Disk-IO im Normalbetrieb.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Setzt die folgenden Commits zurück, da sie das Problem nicht behoben haben:
- e75c437 fix(encoding): UTF-8 prozess-global + 16-KB-StreamReader für CLI-Output
- bfd550e fix: UTF-8-Encoding gehärtet (SSE-Reader + CLI-Workspace)
- 32aad7f fix: UTF-8-Encoding für Claude CLI auf Windows erzwingen
Trotz cmd.exe-Wrapper mit chcp 65001, explizitem UTF-8-StreamReader (16 KB Buffer,
ohne BOM-Detection), Console.OutputEncoding global auf UTF-8 und LANG/LC_ALL/
PYTHONIOENCODING-Env-Vars treten weiterhin Replacement-Chars (�) für Umlaute
und Em-Dashes auf Windows auf. Der Bug muss separat per Diagnose-Logging
nachgestellt werden.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Zwei zusätzliche Härtungen gegen intermittierende �-Replacement-Chars
(Umlaute, Em-Dash) im CLI-Output unter Windows:
- Program.cs: Auf Windows Console.OutputEncoding/InputEncoding = UTF-8
setzen. Wirkt prozess-global via Win32 SetConsoleOutputCP/SetConsoleCP
und wird von direkt gestarteten Child-Prozessen geerbt – ergänzt den
bestehenden chcp-65001-cmd-Wrapper. In try/catch, falls als Windows-
Dienst ohne Console gestartet.
- ClaudeCliService.cs: stdout-Lesen mit eigenem StreamReader (16-KB-
Buffer, explizit UTF-8 ohne BOM-Detection) statt Default-Reader (1 KB).
Verhindert, dass bei gefragmentierten Pipe-Reads Multi-Byte-UTF-8-
Sequenzen über Buffer-Grenzen aufgesplittet werden und der Decoder
den State verliert.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- AnthropicService.Streaming.cs + OpenAiService.cs: SSE-StreamReader nutzt
jetzt expliziten UTF-8-Encoder mit 16-KB-Buffer (statt default 1 KB) und
ohne BOM-Detection. Verhindert intermittierende Replacement-Chars (�),
die entstehen können, wenn Multi-Byte-UTF-8-Sequenzen ungünstig über die
Read-Boundary eines NetworkStreams gesplittet werden.
- ClaudeCliService.cs: cmd.exe-Wrapper jetzt mit /D (AutoRun-Skripte aus
Registry deaktivieren) und WorkingDirectory wird auf den Session-Workspace
gesetzt. Vorher erbte der Child-Prozess das CWD von gott (bei Windows-
Diensten C:\WINDOWS\system32).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Auf Windows kam es sporadisch zu Replacement-Chars (�) für Umlaute
und Em-Dash, weil claude.exe Output mit CP1252/CP850 schreiben konnte.
Lösung: CLI über cmd.exe wrappen und Codepage 65001 (UTF-8) erzwingen,
zusätzlich LANG/LC_ALL/PYTHONIOENCODING auf UTF-8 setzen.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Process.Dispose() gibt nur den Handle frei, killt aber nicht den Prozess.
Jetzt wird per CancellationToken.Register() der gesamte Prozessbaum
(entireProcessTree: true) sofort beendet wenn der User auf Stoppen klickt.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- CLAUDE_CLI_PATH Umgebungsvariable als höchste Priorität bei CLI-Suche
- CreateCliStartInfo() Helper dedupliziert ProcessStartInfo-Erstellung
- .cmd-Wrapper-Logik entfernt (nicht benötigt)
- PATH-Suche priorisiert .exe für Windows
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Sessions können jetzt einen Unity MCP-Server (URL + Token) konfigurieren.
Die CLI erhält automatisch die MCP-Config mit korrektem Transport-Typ
(URL-basierte Erkennung: /sse → SSE, sonst HTTP für streamableHttp).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Read-Tool wird jetzt immer erlaubt (nicht nur mit Workspace), und
/tmp/gott-cli-images/ wird als --add-dir hinzugefügt, damit gesendete
Bilder von der CLI gelesen werden können.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
MCP-Server erweitert um ask_user_choice (Long-Poll), memory_read, memory_write
und memory_list Tools. MCP-Config wird jetzt immer generiert (nicht nur bei
Remote-Verbindung). InternalEndpoint um PendingChoices + choice-respond Endpoint
ergänzt. Frontend differenziert CLI-Modus (choice-respond API) vs. API-Modus.
Gesamter :::ASK_USER_CHOICE::: Text-Marker-Mechanismus aus ClaudeCliService,
AnthropicService, markdown.js und stream-ui.js entfernt.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Python MCP-Server (stdio, JSON-RPC 2.0) für remote_execute via Claude CLI
- Interner API-Endpoint /api/internal/remote-execute mit Token-Auth
- MCP-Config wird automatisch generiert wenn Remote-Verbindung vorhanden
- Auth-Middleware: /api/internal/ von Auth ausgenommen
- Frontend: :::ASK_USER_CHOICE::: Blöcke als interaktive Buttons rendern
- Streaming: Unvollständige Choice-Blöcke werden während des Streams versteckt
- tool-ui.js: MCP-Tool-Namen generisch normalisieren (mcp__server__tool → tool)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Tool-Namen/Inputs von CLI-Konvention auf gott-Konvention mappen (Edit→edit_file, file_path→path etc.)
- Text vor Tool-Use in DB flushen für korrekte Reihenfolge (statt alles am Ende als Blob)
- lineBuffer in ClaudeCliService vor Tool-Start und bei Text-Block-Ende flushen
- ToolResult-Events parsen und in DB speichern (CLI sendet diese als type:"user" Messages)
- Errors in DB speichern und als SSE-Event senden
- Bild-Attachments als Temp-Dateien für CLI bereitstellen (Read-Tool kann sie lesen)
- Frontend: tool_result Handler, Tool-Name-Normalisierung, appendToolResult()
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- ClaudeCliService: Marker-basierte ask_user_choice Erkennung im Stream-Parser
- AnthropicService: StreamChatViaCli mit allowUserChoice, planMode, webSearch
- BuildHistoryContext erweitert für tool_use/tool_result (Choice-Antworten)
- Tool-Use Records werden in DB persistiert (Poll-Kompatibilität)
- CLI Tools konfigurierbar: Workspace/Plan-Modus/WebSearch/kein Workspace
- OAuth DB-Felder für zukünftige Token-Verwaltung
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>