Merge branch 'claudedo/852c2328ec8b4fc1bf143df203e1dc6c'

This commit is contained in:
mika kuns
2026-08-06 08:01:25 +02:00
5 changed files with 156 additions and 15 deletions
+1 -1
View File
@@ -19,7 +19,7 @@ These sit **between** the CLAUDE.md files and the code:
| [external-mcp](external-mcp.md) | The `claudedo` MCP tool surface + its two test-enforced conventions | | [external-mcp](external-mcp.md) | The `claudedo` MCP tool surface + its two test-enforced conventions |
| [review-merge](review-merge.md) | Approve=merge-unit, verify gate, `MergeCommit`/revert, diff stack, conflict resolver | | [review-merge](review-merge.md) | Approve=merge-unit, verify gate, `MergeCommit`/revert, diff stack, conflict resolver |
| [conpty-sessions](conpty-sessions.md) | Interactive/planning/list-handler launch specs + the arg-flattening gotcha | | [conpty-sessions](conpty-sessions.md) | Interactive/planning/list-handler launch specs + the arg-flattening gotcha |
| [installer-preflight](installer-preflight.md) | `--permission-mode auto` eligibility, CLI version floor, login check, .NET runtime requirements | | [installer-preflight](installer-preflight.md) | CLI version/login/auto-mode research, the `ExecutableResolver`/shim root cause, and the Installer's `Checks/`+`SystemCheckPage` implementation status |
## Rules ## Rules
+54 -9
View File
@@ -2,9 +2,43 @@
> **Explore-note — verify before trusting.** Distilled map of a subsystem, not authoritative. > **Explore-note — verify before trusting.** Distilled map of a subsystem, not authoritative.
> Last verified against commit `bdee731` (2026-08-05). > Last verified against commit `bdee731` (2026-08-05).
> Drift check: `git log --oneline bdee731..HEAD -- src/ClaudeDo.Worker/Lifecycle/ClaudeCliPreflight.cs src/ClaudeDo.Worker/ClaudeDo.Worker.csproj src/ClaudeDo.App/ClaudeDo.App.csproj .gitea/workflows/release.yml` > Drift check: `git log --oneline bdee731..HEAD -- src/ClaudeDo.Worker/Lifecycle/ClaudeCliPreflight.cs src/ClaudeDo.Worker/ClaudeDo.Worker.csproj src/ClaudeDo.App/ClaudeDo.App.csproj .gitea/workflows/release.yml src/ClaudeDo.Installer/Checks src/ClaudeDo.Data/Environment/ExecutableResolver.cs`
> Stable structure only (no line numbers). See docs/explore-notes/README.md. > Stable structure only (no line numbers). See docs/explore-notes/README.md.
## Implementation status (as of 2026-08-05)
The research below (§15) led to an implementation, but it is **not on `main` yet** — it exists
on two unmerged task branches:
- `claudedo/06aca9b3afec4b939f59b627bfe21737``src/ClaudeDo.Installer/Checks/*`
(`GitCheck`, `GitIdentityCheck`, `WriteAccessCheck`, `PortCheck`, `ClaudeCliCheck`,
`ClaudeVersionCheck`, `ClaudeAuthCheck`, `PermissionModeAutoCheck`, `EnvironmentCheckService`,
`ClaudeCliLookup`) plus `SystemCheckPage` (the Fresh-Install wizard page hosting them) and its
own copy of `src/ClaudeDo.Data/Environment/ExecutableResolver.cs`.
- `claudedo/40272c0bb3b14562b59c022d09c382b6` — the original `ExecutableResolver.cs`, plus wiring
it into `ClaudeDo.Worker`'s `ClaudeCliPreflight` and `ClaudeProcess` (the actual root-cause fix:
both used to spawn `claude` with `UseShellExecute = false` and no `.cmd`/`.bat` shim resolution,
so an npm-installed `claude.cmd` was invisible to the Worker even though it worked in a shell).
The two branches were authored independently and each vendored its own copy of
`ExecutableResolver.cs` (identical except `06aca9b3` adds a `FallbackDirectories()` diagnostic
helper); merging both cleanly requires picking one copy, not literally running `git merge` twice.
Two planned follow-up tasks — a "Claude Help Me" button and a Config-mode Diagnose section —
never got past a blocked first step, precisely because this prerequisite work wasn't on `main`
when they ran. See `Environment Checks` in `src/ClaudeDo.Installer/CLAUDE.md` and `docs/open.md`
for the current gap and the manual verification checklist.
What's confirmed as **matching the research below**: `ClaudeVersionCheck.MinimumVersion` is
`2.1.220`, exactly the "verified-floor, not a proven minimum" constant from §3. `ClaudeAuthCheck`
uses `claude auth status --json` exactly as recommended in §4, parsing only the `loggedIn` field.
`PermissionModeAutoCheck` is the static "is `auto` listed in `--help`" check recommended in §2 —
real org/model/plan eligibility is deliberately **not** checked, matching the recommendation not
to build that (a real task run surfaces a startup rejection fast enough on its own). No .NET
Desktop Runtime check was implemented as an `IEnvironmentCheck` (§5's registry-key detection
remains a documented-but-unbuilt option, not currently gating anything).
---
Pure research, no code changed. Answers the five questions from the "Root Cause Pure research, no code changed. Answers the five questions from the "Root Cause
`--permission-mode auto`" task. Sources: the locally installed CLI (`claude --version` / `--permission-mode auto`" task. Sources: the locally installed CLI (`claude --version` /
`--help`), the official docs at `code.claude.com` (fetched 2026-08-05), and this repo's own `--help`), the official docs at `code.claude.com` (fetched 2026-08-05), and this repo's own
@@ -89,6 +123,7 @@ and still requires a working prompt/response round trip on the happy path. **Rec
don't build this into an automated preflight; a static version+flag check plus `auth status` don't build this into an automated preflight; a static version+flag check plus `auth status`
covers the reliably-detectable ground, and a real first task run will surface an auto-mode covers the reliably-detectable ground, and a real first task run will surface an auto-mode
rejection immediately and cheaply (fails at startup, not mid-task) if it's actually unavailable. rejection immediately and cheaply (fails at startup, not mid-task) if it's actually unavailable.
**Implemented as:** `PermissionModeAutoCheck` (Warning) — the static flag-listed check only.
## 3. Minimum CLI version for the flags ClaudeDo uses ## 3. Minimum CLI version for the flags ClaudeDo uses
@@ -123,6 +158,7 @@ What **is** sourced, from the docs fetched 2026-08-05:
**Decided constant** (see below) is therefore **the newest version we can positively confirm **Decided constant** (see below) is therefore **the newest version we can positively confirm
works end-to-end on this machine** (`2.1.220`), not a proven theoretical minimum — because no works end-to-end on this machine** (`2.1.220`), not a proven theoretical minimum — because no
lower true minimum is derivable from available sources without guessing. lower true minimum is derivable from available sources without guessing.
**Implemented as:** `ClaudeVersionCheck.MinimumVersion = new Version(2, 1, 220)` (Error).
## 4. Detecting "CLI is logged in" without sending a prompt ## 4. Detecting "CLI is logged in" without sending a prompt
@@ -137,6 +173,8 @@ for this task's own tooling; the docs page confirms it lives at
`%USERPROFILE%\.claude\.credentials.json` on Windows but say nothing about its schema being a `%USERPROFILE%\.claude\.credentials.json` on Windows but say nothing about its schema being a
stable public contract). `claude auth status --text` is available for a human-readable variant; stable public contract). `claude auth status --text` is available for a human-readable variant;
`--json` is the default and the right one for a preflight to parse. `--json` is the default and the right one for a preflight to parse.
**Implemented as:** `ClaudeAuthCheck` (Error) — parses only the `loggedIn` boolean; any other
field, or a non-zero exit code, or unparseable JSON, becomes `Unknown` rather than `Failed`.
## 5. .NET runtimes required by the published `app\` / `worker\` artifacts ## 5. .NET runtimes required by the published `app\` / `worker\` artifacts
@@ -171,6 +209,9 @@ csproj files:
live (would require reading `HKLM\SOFTWARE\dotnet\...` on this machine, which is standard live (would require reading `HKLM\SOFTWARE\dotnet\...` on this machine, which is standard
.NET installer-detection convention, but out of scope to screenshot/dump here since the task .NET installer-detection convention, but out of scope to screenshot/dump here since the task
is docs-only and this is a well-documented, non-project-specific Windows convention). is docs-only and this is a well-documented, non-project-specific Windows convention).
**Not implemented** as an `IEnvironmentCheck` — none of the shipped checks verify the Desktop
Runtime; if the Installer itself is running at all, .NET 8 Desktop Runtime is implicitly
present (framework-dependent publish would otherwise fail to launch).
## Beschlossene Konstanten ## Beschlossene Konstanten
@@ -184,14 +225,18 @@ csproj files:
## Erkennungsstrategie pro Check ## Erkennungsstrategie pro Check
| Check | Type | Command | Expected pass output | | Check | Type | Command | Expected pass output | Implemented as |
|---|---|---|---| |---|---|---|---|---|
| CLI present + version | static | `claude --version` | `X.Y.Z (Claude Code)`; parse and compare `X.Y.Z >= 2.1.220` | | git present + version | static | `git --version` (via `ExecutableResolver`) | resolves, exit 0 | `GitCheck` (Error) |
| `auto` recognized as a flag value | static | `claude --help` (or trigger the parse error path) | `--permission-mode <mode>` help text lists `auto` among the choices | | git identity set | static | `git config --get user.name` / `user.email` | both non-empty | `GitIdentityCheck` (Warning) |
| CLI logged in | static/cheap | `claude auth status --json` | exit 0, `loggedIn: true` | | install dir + data dir writable | static | probe-file write/delete | succeeds | `WriteAccessCheck` (Error) |
| Auto mode actually eligible (org/model/plan) | **not statically detectable** | none exists | N/A — see §2; don't build this, let a real task run surface a fast startup rejection instead | | SignalR/ExternalMcp ports free | static | `TcpListener` bind probe + owning-process lookup | free, or owned by running `ClaudeDo.Worker` | `PortCheck` (Warning) |
| .NET Desktop Runtime present (installer only) | static | `dotnet --list-runtimes` (if `dotnet` on PATH) or registry `HKLM\SOFTWARE\dotnet\Setup\InstalledVersions\x64\sharedfx\Microsoft.WindowsDesktop.App` | a `Microsoft.WindowsDesktop.App 8.0.x` entry exists | | CLI present + version | static | `claude --version` | `X.Y.Z (Claude Code)`; parse and compare `X.Y.Z >= 2.1.220` | `ClaudeCliCheck` (Error) / `ClaudeVersionCheck` (Error) |
| App/Worker runtime present | **not needed** | — | self-contained, nothing to check | | `auto` recognized as a flag value | static | `claude --help` (or trigger the parse error path) | `--permission-mode <mode>` help text lists `auto` among the choices | `PermissionModeAutoCheck` (Warning) |
| CLI logged in | static/cheap | `claude auth status --json` | exit 0, `loggedIn: true` | `ClaudeAuthCheck` (Error) |
| Auto mode actually eligible (org/model/plan) | **not statically detectable** | none exists | N/A — see §2; don't build this, let a real task run surface a fast startup rejection instead | not implemented (by design) |
| .NET Desktop Runtime present (installer only) | static | `dotnet --list-runtimes` (if `dotnet` on PATH) or registry `HKLM\SOFTWARE\dotnet\Setup\InstalledVersions\x64\sharedfx\Microsoft.WindowsDesktop.App` | a `Microsoft.WindowsDesktop.App 8.0.x` entry exists | not implemented (see §5) |
| App/Worker runtime present | **not needed** | — | self-contained, nothing to check | not implemented (not needed) |
## Not verifiable (explicit) ## Not verifiable (explicit)
+44
View File
@@ -55,6 +55,7 @@ Offene Entscheidungen dazu:
## Beobachtung (offen — Entscheidung Mika) ## Beobachtung (offen — Entscheidung Mika)
- **`--permission-mode auto` + Modell `haiku` → Writes werden denied:** Kontrolliert verifiziert (CLI 2.1.207): unter dem Default-Mode `auto` bekommt **sonnet** Writes auto-approved (`permission_denials:[]`), **haiku** wird `denied` (`permission_denials:[Write]`, keine Datei) — eine haiku-Task macht unter `auto` still nichts und landet ohne Änderung in `WaitingForReview`. Normalbetrieb (Default = sonnet) nicht betroffen. KEINE CLI-Regression, sondern modellabhängiges `auto`-Verhalten. Optionen falls es nervt: haiku aus der Auswahl nehmen, ODER Runner auf `acceptEdits`/`bypassPermissions` (modell-unabhängig). Mika: erstmal beobachten. Siehe Memory `auto_permission_haiku_footgun`. - **`--permission-mode auto` + Modell `haiku` → Writes werden denied:** Kontrolliert verifiziert (CLI 2.1.207): unter dem Default-Mode `auto` bekommt **sonnet** Writes auto-approved (`permission_denials:[]`), **haiku** wird `denied` (`permission_denials:[Write]`, keine Datei) — eine haiku-Task macht unter `auto` still nichts und landet ohne Änderung in `WaitingForReview`. Normalbetrieb (Default = sonnet) nicht betroffen. KEINE CLI-Regression, sondern modellabhängiges `auto`-Verhalten. Optionen falls es nervt: haiku aus der Auswahl nehmen, ODER Runner auf `acceptEdits`/`bypassPermissions` (modell-unabhängig). Mika: erstmal beobachten. Siehe Memory `auto_permission_haiku_footgun`.
- **`QueueServiceTests.UsageGate_TransitionLogging_FiresOncePerChange` ist zeitbasiert flaky, unabhängig von dieser Session:** Schlägt reproduzierbar fehl (`Expected 1, Actual 0` Warn-Log-Aufrufe), sowohl solo (`--filter`) als auch im Vollauf, auf einem sauberen `git worktree add` gegen `main` (bdee731) — also **kein** durch diese Abschluss-Session verursachter Regress (die Session hat keine `.cs`-Datei angefasst). Ursache: der Test verlässt sich auf einen festen `Task.Delay(200)`, um mehrere 50-ms-Backstop-Ticks abzuwarten (Kommentar im Test: „Several backstop ticks (50ms interval) all observe the same blocked state"); auf einer stark ausgelasteten Maschine (hier: viele parallele ClaudeDo-Worktrees/Builds) reicht das Fenster nicht immer. Zum Vergleich: derselbe Test lief in einer zweiten, isolierten Verifikation (Scratch-Merge für den Environment-Checks-Task) sauber durch (876/876). Fix wäre ein Poll-basiertes Warten statt fixem Sleep — aber außerhalb des Scopes dieser Doku/Verifikations-Session (keine Code-Änderung angefasst).
--- ---
@@ -137,6 +138,49 @@ verifiziert**:
beim Laden übernommen und beim Speichern nur unverändert zurückgeschrieben (kein Clobber), beim Laden übernommen und beim Speichern nur unverändert zurückgeschrieben (kein Clobber),
aber nicht editierbar. Falls gewünscht, ein eigenes Feld ergänzen. aber nicht editierbar. Falls gewünscht, ein eigenes Feld ergänzen.
## Offene Verifikation (2026-08-05, Environment Checks / SystemCheckPage)
**Voraussetzung, bevor irgendeiner der Punkte unten geprüft werden kann:** die Branches
`claudedo/06aca9b3afec4b939f59b627bfe21737` (Checks + SystemCheckPage) und
`claudedo/40272c0bb3b14562b59c022d09c382b6` (ExecutableResolver-Wiring in
`ClaudeDo.Worker`) müssen erst gemerged werden — sie lagen bei dieser Abschluss-Session
noch nicht auf `main`. Build/Test-Nachweis unten stammt aus einer lokalen Scratch-Integration
beider Branches, nicht aus `main` selbst. Details → `installer-preflight` in
`docs/explore-notes/README.md` und den neuen Abschnitt „Environment Checks" in
`src/ClaudeDo.Installer/CLAUDE.md`.
**Zusätzliche Lücke, unabhängig vom Merge:** die zwei Folge-Tasks „Claude Help Me"-Button
und Diagnose-Sektion (Config-Modus/`SettingsWindow`) sind **nicht implementiert** — beide
liefen ins selbe Merge-Problem und wurden ohne jede Code-Änderung als `Blocked` beendet. Die
folgenden Punkte, die diese zwei Features beträfen, können also noch nicht geprüft werden und
brauchen zuerst eine neue Umsetzungsrunde:
- [ ] „Claude Help Me" öffnet ein Terminal mit laufender Claude-Session, und die Session hat
den Diagnose-Report tatsächlich gelesen — **nicht umsetzbar, Feature existiert nicht.**
- [ ] Der Help-Me-Button ist korrekt deaktiviert, wenn `claude` nicht im PATH ist, mit
verständlichem Tooltip — **nicht umsetzbar, Feature existiert nicht.**
- [ ] Diagnose-Sektion im Config-Modus zeigt die echten installierten Pfade/Ports, und der
laufende Worker auf 47821 gilt nicht als Konflikt — **nicht umsetzbar, Feature existiert
nicht.**
Sobald die beiden Branches oben gemerged sind, sind folgende Punkte real prüfbar (gebaut +
unit-getestet gegen die Scratch-Integration, aber **nicht visuell verifiziert**):
- [ ] SystemCheckPage: Layout, Icon-/Farbwirkung der vier Status (Ok grün / Warnung orange /
Fehler rot / Unbekannt grau — `StatusGreenBrush`/`StatusOrangeBrush`/`StatusRedBrush`/
`StatusGrayBrush`), Lesbarkeit der Hint-Texte, DE und EN.
- [ ] Weiter-Button gesperrt bei einem echten blockierenden Fehler (z. B. `claude` nicht im
PATH → `claude-cli` Error/Failed), und der Grund ist in der Zusammenfassungszeile
sichtbar (nennt den/die blockierenden Check(s) namentlich).
- [ ] „Erneut prüfen" wechselt einen Status live (z. B. git-Identity setzen → Warnung
verschwindet), ohne dass ein zweiter paralleler Lauf startet, wenn währenddessen erneut
geklickt wird.
- [ ] Update-Modus zeigt die SystemCheckPage **nicht** (Wizard bleibt Welcome + Install).
- [ ] Auf einem Rechner mit npm-installiertem `claude.cmd`: `claude-cli`-Check findet es
(Detail-Text „Resolved via a shim…"), und ein Task läuft im Worker durch (bestätigt, dass
`ClaudeProcess`/`ClaudeCliPreflight` den Shim über `cmd.exe /c` tatsächlich startet, nicht
nur, dass der Check ihn findet).
--- ---
## Bewusst verworfen (nicht erneut vorschlagen) ## Bewusst verworfen (nicht erneut vorschlagen)
+53 -3
View File
@@ -31,8 +31,8 @@ the on-disk installer to run the *app* update. App-update detection is unaffecte
| Mode | Condition | Window | | Mode | Condition | Window |
|---|---|---| |---|---|---|
| `FreshInstall` | No `install.json` | Full wizard (all pages) | | `FreshInstall` | No `install.json` | Full wizard: Welcome → **SystemCheck** → Paths → Service → UiSettings → Install |
| `Update` | `install.json` present + newer release available | Wizard — Welcome + Install pages only | | `Update` | `install.json` present + newer release available | Wizard — Welcome + Install pages only (SystemCheck **not** shown) |
| `Config` | Current version, or Gitea API unreachable | `SettingsWindow` (settings / repair / uninstall) | | `Config` | Current version, or Gitea API unreachable | `SettingsWindow` (settings / repair / uninstall) |
## Install Pipelines ## Install Pipelines
@@ -60,7 +60,8 @@ Installer/
ConfigModels, InstallerService, UninstallRunner, PageResolver, ConfigModels, InstallerService, UninstallRunner, PageResolver,
AutostartShortcut, ShortcutFactory, ProcessRunner, DarkTitleBar AutostartShortcut, ShortcutFactory, ProcessRunner, DarkTitleBar
Interfaces/ — IInstallStep + StepResult/StepStatus/StepProgress, IInstallerPage Interfaces/ — IInstallStep + StepResult/StepStatus/StepProgress, IInstallerPage
Pages/ WelcomePage, PathsPage, ServicePage, UiSettingsPage, InstallPage Checks/ — environment preflight checks, see "Environment Checks" below
Pages/ — WelcomePage, SystemCheckPage, PathsPage, ServicePage, UiSettingsPage, InstallPage
(each: ViewModel + View.xaml) (each: ViewModel + View.xaml)
Views/ — WizardWindow(+WizardViewModel), SettingsWindow(+SettingsViewModel) Views/ — WizardWindow(+WizardViewModel), SettingsWindow(+SettingsViewModel)
``` ```
@@ -124,3 +125,52 @@ and restored if it fails.
| `%APPDATA%\Microsoft\Windows\Start Menu\Programs\Startup\ClaudeDo Worker.lnk` | Worker autostart | | `%APPDATA%\Microsoft\Windows\Start Menu\Programs\Startup\ClaudeDo Worker.lnk` | Worker autostart |
The Apps & Features uninstall string and "Rerun Installer" both point at `<InstallDir>\uninstaller\ClaudeDo.Installer.exe` with no `/uninstall` flag — Config mode is detected from `install.json`. The Apps & Features uninstall string and "Rerun Installer" both point at `<InstallDir>\uninstaller\ClaudeDo.Installer.exe` with no `/uninstall` flag — Config mode is detected from `install.json`.
## Environment Checks
> **Merge status (2026-08-05): not yet on `main`.** The `Checks/` folder, `SystemCheckPage`,
> and `ExecutableResolver` described below exist only on unmerged task branches
> (`claudedo/06aca9b3afec4b939f59b627bfe21737` for the Installer side,
> `claudedo/40272c0bb3b14562b59c022d09c382b6` for the `ClaudeDo.Worker` wiring). Build/test
> verification for this section was done against a local scratch integration of both, not
> against this repo's actual `main`. Merge them (or re-derive equivalent commits) before trusting
> this section against the checked-out code. See `docs/open.md` for the outstanding gap this
> leaves (`Checks/` and `SystemCheckPage` are real, but the "Claude Help Me" button and the
> Config-mode Diagnose section described as follow-ups were never implemented — both follow-up
> tasks blocked on this same missing merge and shipped no code).
`Checks/` holds one `IEnvironmentCheck` per concern, run in parallel by `EnvironmentCheckService.RunAllAsync`:
| Check | Severity | What it verifies |
|---|---|---|
| `GitCheck` | Error | `git` resolvable (via `ExecutableResolver`) and runs |
| `WriteAccessCheck` | Error | install dir + `%APPDATA%` (or first existing parent) are writable |
| `ClaudeCliCheck` | Error | `claude` resolvable on PATH, including npm `.cmd`/`.bat`/`.ps1` shims |
| `ClaudeVersionCheck` | Error | resolved `claude --version``ClaudeVersionCheck.MinimumVersion` (currently `2.1.220`) |
| `ClaudeAuthCheck` | Error | `claude auth status --json` reports `loggedIn: true` (never sends a prompt) |
| `GitIdentityCheck` | Warning | `git config user.name`/`user.email` are set |
| `PortCheck` | Warning | `SignalRPort`/`ExternalMcpPort` are free, or already owned by a running `ClaudeDo.Worker` |
| `PermissionModeAutoCheck` | Warning | CLI's `--help` still lists `auto` as a `--permission-mode` choice |
Each check returns a `CheckResult` with `CheckStatus` (`Ok` / `Failed` / `Unknown`). A check that
throws is caught by `EnvironmentCheckService` and turned into `Unknown`, never a crash.
**Gating rule:** `EnvironmentCheckReport.HasBlockingError` is true only when a check with
`Severity == Error` has `Status == Failed`. Warnings never block, and `Unknown` never blocks
regardless of severity (an indeterminate result — e.g. the CLI not found, so version/auth/auto-mode
can't be checked — must not strand the user; the underlying `Error`-severity check for the CLI
itself, `ClaudeCliCheck`, is what blocks in that case).
`SystemCheckPage` (`Pages/SystemCheckPage/`) hosts the check list in the **FreshInstall** wizard
only, registered via `PageResolver` at `Order = 1` (directly after `WelcomePage`); `WizardViewModel`
filters it back out in `Update` mode along with Paths/Service/UiSettings. Checks run automatically
on page entry (`LoadAsync`, guarded against double-entry). "Next" is disabled via
`IInstallerPage.BlocksNavigation` (`IsRunning || HasBlockingError`) — `WizardViewModel.CanGoNext`
subscribes to `PropertyChanged` on the current page so a live recheck can flip it back. A "Recheck"
button re-runs `EnvironmentCheckService.RunAllAsync` (disabled while already running).
**Not implemented (see merge-status note above):** a "Claude Help Me" button that launches an
external terminal with a live `claude` session for setup troubleshooting, and a Diagnose section
in `SettingsWindow` (Config mode) that re-runs the same checks against the installed configuration.
Both were speced as follow-up tasks; both blocked before writing any code because their prerequisite
(this section) wasn't on `main` yet.
+4 -2
View File
@@ -16,7 +16,8 @@ Worker/
State/ — TaskStateService + TransitionResult (sole owner of Status/PlanningPhase/BlockedBy writes) State/ — TaskStateService + TransitionResult (sole owner of Status/PlanningPhase/BlockedBy writes)
Queue/ — IQueueWaker, IQueuePicker, QueueService, OverrideSlotService, RunCancellationRegistry Queue/ — IQueueWaker, IQueuePicker, QueueService, OverrideSlotService, RunCancellationRegistry
Lifecycle/ — StaleTaskRecovery, TaskResetService, TaskMergeService, VerifyCommandRunner, Lifecycle/ — StaleTaskRecovery, TaskResetService, TaskMergeService, VerifyCommandRunner,
ClaudeCliPreflight, OrphanRecovery, PlanningLineageRecovery, ClaudeCliPreflight (resolves via ExecutableResolver, see Key Components below),
OrphanRecovery, PlanningLineageRecovery,
AttachmentOrphanRecovery, PromptFileRecovery (last four = startup sweeps) AttachmentOrphanRecovery, PromptFileRecovery (last four = startup sweeps)
Worktrees/ — WorktreeMaintenanceService Worktrees/ — WorktreeMaintenanceService
Agents/ — AgentFileService, DefaultAgentSeeder Agents/ — AgentFileService, DefaultAgentSeeder
@@ -111,7 +112,8 @@ Full flow, invariants, and model/effort/max-turns resolution (including the low-
## Key Components ## Key Components
- **ClaudeProcess** — spawns `claude -p --output-format stream-json --verbose --permission-mode auto` (or whatever app settings specify). Prompt via stdin, NDJSON from stdout. CancellationToken kills the process tree. - **ClaudeCliPreflight** — startup check that `claude --version` runs; resolves the binary via `ExecutableResolver` first and returns a clear "not found on PATH" result instead of a raw `Process.Start` exception when it doesn't. *(Not yet on `main` — see below.)*
- **ClaudeProcess** — spawns `claude -p --output-format stream-json --verbose --permission-mode auto` (or whatever app settings specify). Prompt via stdin, NDJSON from stdout. CancellationToken kills the process tree. Resolves `_cfg.ClaudeBin` via `ExecutableResolver` (`ClaudeDo.Data`, shared with `ClaudeCliPreflight` and the Installer's checks) before spawning — a `.cmd`/`.bat` shim (e.g. an npm-installed `claude`) is launched through `cmd.exe /c` since `UseShellExecute = false` can't exec a shim directly; a resolved `.exe` starts exactly as before. Throws if nothing resolves. *(Not yet on `main` — see `Environment Checks` in `ClaudeDo.Installer/CLAUDE.md`.)*
- **ClaudeArgsBuilder** — `--model`, `--effort`, `--max-turns`, `--append-system-prompt`, `--agents`, `--json-schema`, `--resume` - **ClaudeArgsBuilder** — `--model`, `--effort`, `--max-turns`, `--append-system-prompt`, `--agents`, `--json-schema`, `--resume`
- **StreamAnalyzer** — parses NDJSON; extracts session_id, token counts, turn counts, result text, structured output. Replaced MessageParser. - **StreamAnalyzer** — parses NDJSON; extracts session_id, token counts, turn counts, result text, structured output. Replaced MessageParser.
- **WorktreeManager** — worktrees on `claudedo/{taskId[:8]}` branches; commits with semantic messages, updates DB with head commit + diff stats - **WorktreeManager** — worktrees on `claudedo/{taskId[:8]}` branches; commits with semantic messages, updates DB with head commit + diff stats