Commit Graph

32 Commits

Author SHA1 Message Date
mika kuns
b72a7888e4 feat(worker): expose max-turns override over signalr and mcp config tools 2026-06-04 12:22:34 +02:00
mika kuns
ac137f7c1c feat(data): persist max_turns in list and task repositories
Add MaxTurns to ListRepository.SetConfigAsync upsert branch and
TaskRepository.UpdateAgentSettingsAsync; fix positional CancellationToken
call in ConfigMcpTools. Covered by MaxTurnsRoundTripTests (2 tests).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-04 12:18:32 +02:00
mika kuns
fd7f8ac78f feat(daily-prep): add set_my_day MCP tool with cap-guard 2026-06-03 16:19:36 +02:00
mika kuns
0bb809445e feat(daily-prep): add get_daily_prep_candidates MCP tool 2026-06-03 16:15:27 +02:00
mika kuns
c88ed9d5eb feat(worker): add review_task MCP tool and status reference updates
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-01 17:17:56 +02:00
Mika Kuns
c0978df19a feat(claude-do): MCP surface: worktree/diff/merge/log tools + status-enum doc
BUNDLE — all changes live in src/ClaudeDo.Worker/External/ExternalMcpService.cs only, so this is one worktree / one merge. Do NOT touch run-recording or data-layer code (those are separate tasks). Reuse the existing services behind the UI modals (WorktreesOverviewModalView, DiffModalView, MergeModalView) — do not reimplement git plumbing. Build green after each addition.

Add these MCP tools:
1. g

ClaudeDo-Task: f6bdfb5b-8cbf-4e65-93d4-6c758a160484
2026-06-01 16:15:26 +02:00
Mika Kuns
23326a1833 merge: return confirmation payload from delete_task and cancel_task 2026-06-01 15:29:30 +02:00
mika kuns
6c3afce329 chore(claude-do): Return confirmation payload from delete_task and cancel_task
delete_task (and likely cancel_task) return no output on success. Silent success is indistinguishable from a no-op, so callers can't verify the action took effect.

Fix: return a small confirmation object, e.g. { deleted: true, id } / { cancelled: true, id }. Indicate not-found vs deleted distinctly.

ClaudeDo-Task: 97a87ebb-0d87-4ee0-800c-aa1a0b3a06c5
2026-06-01 15:20:20 +02:00
mika kuns
f8e387bbc1 chore(claude-do): Make add_task optional params actually optional
add_task currently marks description, createdBy, and queueImmediately as required, forcing callers to invent values for fields that have obvious defaults.

Fix: make them optional with sensible defaults — description: null, queueImmediately: false, createdBy: server default like "mcp". Keep only listId and title as truly required.

ClaudeDo-Task: b9fadf0b-a20e-4deb-932d-29ef9c0b83f3
2026-06-01 15:18:27 +02:00
mika kuns
1856943925 refactor: merge TaskRunner failure handlers and reuse NullIfBlank
Unify the near-identical HandleFailure/MarkFailed into a single MarkFailed that
always persists the failed state and never throws, and replace the inline
null-if-blank checks in ListMcpTools with the existing extension.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-30 15:51:14 +02:00
mika kuns
ce9fadc0b5 refactor: fold single-consumer helper types into their owners
Consolidate small single-purpose types into the files that own them:
StreamResult into StreamAnalyzer, the Planning context records into
PlanningSessionContext, PrimeClock/PrimeSchedulerOptions into PrimeScheduler,
AgentMcpTools into LifecycleMcpTools, the locator subclasses into
InstallArtifactLocator, LogLineViewModel into DetailsIslandViewModel,
RepoImportItemViewModel into its modal, and StepViewModel into InstallPageViewModel.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-30 15:47:46 +02:00
mika kuns
41da124a31 refactor: extract interfaces to Interfaces folders and consolidate filters
Move interface declarations into per-area Interfaces/ subfolders, merge the
small task-list filter classes into StatusFilter/SmartFlagFilter, and simplify
related services, converters and hub DTO handling.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-30 15:41:10 +02:00
mika kuns
9ea60701d2 feat(worker): add external MCP app-settings read tool
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-30 14:12:18 +02:00
mika kuns
5a592c4be6 feat(worker): add external MCP reset-failed-task tool
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-30 14:07:59 +02:00
mika kuns
7196aab31f feat(worker): add external MCP agent-listing tool
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-30 14:05:30 +02:00
mika kuns
fec2fe2dda fix(worker): cap run-log read size and harden run-history tests
- GetTaskLog reads at most last 256 KB; prepends truncation marker if file exceeds cap
- Wrap temp-file cleanup in finally block to prevent leak on assertion failure
- Add GetRun_NotFound_Throws, GetTaskLog_RunExistsButNoLogPath_Throws, and GetTaskLog_LargeFile_ReturnsTruncatedTail tests

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-30 14:04:22 +02:00
mika kuns
3afe29d721 feat(worker): add external MCP run-history and log tools
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-30 13:59:54 +02:00
mika kuns
f3f8af4b11 docs(worker): clarify SetTaskConfig null-clears-override wording
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-30 13:57:59 +02:00
mika kuns
c3493a3a74 feat(worker): add external MCP list/task config tools
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-30 13:54:08 +02:00
mika kuns
ac2f1d824e fix(worker): reuse shared hub fake and guard blank list name
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-30 13:51:34 +02:00
mika kuns
53f4e2de0f feat(worker): add external MCP list-management tools
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-30 13:47:02 +02:00
mika kuns
623ebf147b refactor(tags): remove tag entity and all references
Drops TagEntity, TagRepository, and tag wiring across data layer, worker,
and UI. Adds RemoveTags migration to clean up schema.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-19 08:07:24 +02:00
Mika Kuns
dc3fc443b4 refactor(data): retire legacy TaskStatus values and backfill existing rows
Slice 6 of the worker state and queue consolidation refactor.

* Drop Manual, Planning, Planned, Draft, Waiting from the TaskStatus enum
  and from the EF value converter; only the lifecycle values remain
  (Idle, Queued, Running, Done, Failed, Cancelled).
* Add migration RetireLegacyTaskStatus that rewrites existing rows:
  manual/draft -> idle, planning -> idle+planning_phase=active,
  planned -> idle+planning_phase=finalized, waiting -> queued+blocked_by
  derived from sort_order via a CTE with LAG().
* Reroute every call site that compared/set legacy values to the new
  three-field model (Status + PlanningPhase + BlockedByTaskId), including
  the planning repo helpers, MCP services, the planning chain coordinator,
  and the UI view-models. TaskRowViewModel now exposes PlanningPhase to
  drive the planning badge.
* Refresh Worker/CLAUDE.md and Data/CLAUDE.md, the docs/plan.md status
  section, and the planning verification notes in docs/open.md.
2026-04-27 15:28:55 +02:00
Mika Kuns
ff7c239959 refactor(worker): extract OverrideSlotService and reorganize Worker/Services into domain folders
Slice 5 of the worker state consolidation refactor.

OverrideSlotService (new in Worker/Queue/) owns RunNow, ContinueTask,
and the override-slot piece of CancelTask. QueueService keeps the
queue-slot guard for "task is already running" rejection and delegates
to OverrideSlotService for execution; CancelTask tries the override
slot first, then the queue slot. QueueSlotState is extracted to its own
file.

Folder reorg (via git mv to preserve history):
- Worker/Queue/      QueueService, OverrideSlotService, QueueSlotState
                     (alongside existing waker/picker)
- Worker/Lifecycle/  StaleTaskRecovery, TaskResetService, TaskMergeService
- Worker/Worktrees/  WorktreeMaintenanceService
- Worker/Agents/     AgentFileService, DefaultAgentSeeder

Worker/Services/ folder removed. All consumers updated to the new
namespaces (Program.cs, WorkerHub, ExternalMcpService,
PlanningMergeOrchestrator, all Worker tests).

OverrideSlotService is registered as a DI singleton in both the main
worker app and the external MCP app.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 14:42:13 +02:00
Mika Kuns
064a903076 refactor(worker/queue): split queue waker and picker, auto-wake on enqueue
Slice 3 of the worker state and queue consolidation refactor.

- Add IQueueWaker / QueueWaker (singleton holding the wake semaphore).
- Add IQueuePicker / QueuePicker; raw SQL UPDATE...RETURNING moves out of
  TaskRepository.GetNextQueuedAgentTaskAsync (deleted) and now also filters
  on blocked_by_task_id IS NULL and writes started_at on claim.
- TaskStateService takes IQueueWaker directly; the Func<QueueService>
  indirection is gone. State transitions to Queued auto-wake the dispatcher.
- QueueService waits via the shared waker and dispatches via the picker.
- Drop explicit _queue.WakeQueue() calls in WorkerHub.QueuePlanningSubtasksAsync
  and ExternalMcpService.AddTask. The hub WakeQueue endpoint stays for
  diagnostics, delegating to _waker.Wake().
- Migrate tests; pre-existing flaky AppSettings/ExternalMcp tests untouched.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 12:05:54 +02:00
Mika Kuns
8823265e5a refactor(worker/state): introduce TaskStateService and route mutations through it
Slice 2 of the worker state consolidation refactor (spec sections 2 and 8).

Adds Worker/State/ITaskStateService + TaskStateService as the single component
that mutates Status, PlanningPhase, and BlockedByTaskId. Each transition is one
atomic ExecuteUpdate with a WHERE filter on the expected source status, so
parallel claims are TOCTOU-free. Side effects (queue wake on -> Queued, hub
TaskUpdated broadcast, chain advance + parent completion on terminal child)
are owned by the service so callers no longer need to remember them.

Migrated callers (mechanical, behavior preserved):
- TaskRunner: HandleSuccess/HandleFailure/MarkFailed/RunAsync/ContinueAsync
- StaleTaskRecovery: bulk recover stale Running tasks
- TaskResetService: status flip (worktree cleanup stays in service)
- PlanningSessionManager.StartAsync: status flip via state, token write via repo
- PlanningChainCoordinator.OnChildFinishedAsync: routes the next-sibling write
  through state.UnblockAsync (Slice 4 finishes the rewrite)
- ExternalMcpService.UpdateTaskStatus: Queued case via state.EnqueueAsync

Repo Mark*Async helpers (MarkRunning/MarkDone/MarkFailed/FlipAllRunningToFailed)
are now internal; ClaudeDo.Data grants InternalsVisibleTo to ClaudeDo.Worker
and ClaudeDo.Worker.Tests for the existing repo-level tests.

DI: TaskStateService is registered as Singleton in both the main app and the
external-MCP app; the queue-wake delegate captures sp -> QueueService.WakeQueue
to break the TaskStateService -> QueueService -> TaskRunner -> TaskStateService
construction cycle. PlanningChainCoordinator takes Func<ITaskStateService> for
the same reason; Slice 3 will replace both with IQueueWaker.

Tests: TaskStateServiceTests covers happy + reject for every transition, the
parallel StartRunningAsync claim race, child-terminal chain advancement, and
stale recovery. Existing service/repo tests are updated to construct the new
state-service via a TaskStateServiceBuilder helper. Pre-existing constructor
drift in QueueService/ExternalMcp/PlanningHub tests is patched to keep the
test project building (the surrounding test logic is otherwise untouched).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 11:31:57 +02:00
mika kuns
59dc1e2357 feat(mcp/external): add SetTaskTags 2026-04-25 11:29:58 +02:00
mika kuns
31a394e694 feat(mcp/external): add DeleteTask
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-25 11:28:47 +02:00
mika kuns
d99cb68afb feat(mcp/external): add UpdateTask for content/tag patching
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-25 11:27:16 +02:00
mika kuns
1a74e1c058 feat(mcp/external): AddTask accepts tags on creation
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-25 11:25:42 +02:00
mika kuns
e6846b7e6d feat(mcp/external): add ListTags + inject TagRepository
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-25 11:24:10 +02:00
mika kuns
45320427e8 feat(worker): add external MCP endpoint with API-key auth
A second WebApplication runs the external MCP server on its own port (default 47822) so it can expose a different tool set under different auth than the internal /mcp endpoint. Shared singletons (config, broadcaster, queue, db factory) are injected by instance so both apps share runtime state. ExternalMcpAuthMiddleware enforces an optional X-ClaudeDo-Key header; loopback-only trust when no key is configured.

Tools: ListTaskLists, ListTasks, GetTask, AddTask, UpdateTaskStatus, RunTaskNow, CancelTask.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 09:36:46 +02:00