Repository navigation
feat: tasks ui - #36
Conversation
|
Important Review skippedReview was skipped due to path filters ⛔ Files ignored due to path filters (1)
CodeRabbit blocks several paths by default. You can override this behavior by explicitly including those paths in the path filters. For example, including ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
WalkthroughAdds comprehensive task read/observe surfaces: new API contract types, converters, parsers, handlers (live timeline/stream/tree, dashboard, inbox, triage/approval), DB schema/migration and persistence for task fields/triage/event sequences, domain/live service implementations, and extensive unit/integration tests across HTTP, UDS, Host API, CLI, and daemon layers. Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant Handler as HTTP Handler
participant Parser as Query Parser
participant Service as Task Service
participant Store as GlobalDB
participant Converter as Payload Converter
Client->>Handler: GET /tasks/{id}/timeline
Handler->>Parser: ParseTaskTimelineQuery
Parser-->>Handler: TimelineQuery
Handler->>Service: Timeline(ctx, taskID, query, actor)
Service->>Store: ListTaskEventRecords(taskID, after_sequence, limit)
Store-->>Service: []EventRecord
Service->>Converter: timelineItemsFromRecords
Converter-->>Service: []TimelineItemPayload
Service-->>Handler: timeline payload
Handler->>Converter: TaskTimelineResponse wrapper
Converter-->>Handler: JSON payload
Handler-->>Client: 200 OK + JSON
sequenceDiagram
participant Client
participant Handler as HTTP Handler
participant Observer
participant Registry as Observe Registry/Store
participant Converter as Payload Converter
Client->>Handler: GET /observe/tasks/dashboard
Handler->>Handler: ParseTaskDashboardQuery
Handler->>Observer: QueryTaskDashboard(ctx, query)
Observer->>Registry: ListTasks(snapshot query)
Registry-->>Observer: []Summary
Observer->>Registry: CountDependencies per task
Registry-->>Observer: dependency counts
Observer->>Observer: compute totals/cards/health
Observer-->>Handler: TaskDashboardView
Handler->>Converter: TaskDashboardPayloadFromView
Converter-->>Handler: JSON payload
Handler-->>Client: 200 OK + JSON
sequenceDiagram
participant Client
participant Handler as HTTP Handler
participant Service as Task Manager
participant Store as GlobalDB
participant Events as Event Recorder
Client->>Handler: POST /tasks/{id}/approve
Handler->>Handler: validate actor & authority
Handler->>Service: ApproveTask(ctx, id, actor)
Service->>Store: GetTask(id)
Store-->>Service: Task
Service->>Store: UpdateTask(approval_state=approved)
Store-->>Service: updated Task
Service->>Events: recordTaskEvent(task.approved)
Events-->>Service: persisted event (seq)
Service-->>Handler: updated Task
Handler->>Converter: TaskPayloadFromTask
Converter-->>Handler: JSON payload
Handler-->>Client: 200 OK + JSON
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Comment |
There was a problem hiding this comment.
Actionable comments posted: 15
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
internal/api/core/tasks.go (1)
118-129:⚠️ Potential issue | 🟠 MajorMove draft filtering ahead of the database limit.
The
manager.ListTaskscall on line 124 appliesquery.Limitat the SQL level (inGlobalDB.ListTasks, line 226), so draft rows returned from the database consume the page budget. ThefilterTaskListDraftscall on line 129 removes these drafts after the fact, leaving fewer results than requested.For example, if
query.Limit=10and the database returns 3 drafts among 10 total rows, the client receives 7 published tasks instead of 10. This occurs wheneverIncludeDraftsis false and no explicitStatusfilter is set.Push the draft predicate into
taskListDomainQuery/ListTasks, or overfetch until you havetransportQuery.Limitvisible (non-draft) rows.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@internal/api/core/tasks.go` around lines 118 - 129, The current flow calls manager.ListTasks using query (which applies query.Limit at SQL) and then removes drafts with filterTaskListDrafts, causing drafts to consume the page budget; change this by pushing the draft predicate into the DB query or overfetching until you return transportQuery.Limit non-draft rows: update taskListDomainQuery (and the query it returns) to respect transportQuery.IncludeDrafts/Status by adding a WHERE clause that excludes drafts when IncludeDrafts is false, or modify ListTasks/GlobalDB.ListTasks to accept an includeDrafts flag and apply the predicate at SQL; alternatively implement overfetch logic in the handler around manager.ListTasks to request extra rows and loop fetching until you have transportQuery.Limit non-draft tasks before trimming with filterTaskListDrafts.
🧹 Nitpick comments (16)
internal/daemon/automation_task_e2e_assertions_test.go (1)
84-87: Add a nil guard infindTaskRunInDetailto avoid panic-prone helper behavior.Since the helper now accepts a pointer, a nil input will panic on
detail.Runs. Returningfalseis safer for test diagnostics.Suggested change
func findTaskRunInDetail( detail *aghcontract.TaskDetailPayload, runID string, ) (aghcontract.TaskRunPayload, bool) { + if detail == nil { + return aghcontract.TaskRunPayload{}, false + } return findTaskRunPayload(detail.Runs, runID) }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@internal/daemon/automation_task_e2e_assertions_test.go` around lines 84 - 87, In findTaskRunInDetail, add a nil guard for the detail pointer before accessing detail.Runs: if detail == nil return the zero-value aghcontract.TaskRunPayload and false; otherwise call findTaskRunPayload(detail.Runs, runID) as before. This prevents a panic when detail is nil and preserves the helper's boolean-found semantics.internal/api/udsapi/handlers_test.go (1)
218-256: Use explicitt.Run("Should...")subtests for each expected route binding.This map-driven assertion block is a good table candidate; subtests will make failures isolated and guideline-compliant.
As per coding guidelines, "MUST use t.Run("Should...") pattern for ALL test cases".
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@internal/api/udsapi/handlers_test.go` around lines 218 - 256, The test TestRegisterTaskRoutesUseSharedHandlerBindings should be converted from a single map-driven assertion block into explicit t.Run subtests: iterate the expectedHandlers map and for each entry call t.Run with a descriptive name starting with "Should..." (e.g., "Should register GET /api/observe/tasks/dashboard" or "Should bind TaskDashboard"), move the route lookup and assertions (the engine.Routes() scan and the two t.Fatalf checks) inside the subtest closure so failures are isolated, and keep use of the matched variable and strings.Contains(matched.Handler, handlerName) logic unchanged; ensure each subtest uses the same test helpers (newTestRouter, newTestHandlers) context or captures necessary variables to avoid race issues.internal/api/httpapi/handlers_test.go (1)
167-205: Prefert.Run("Should...")subtests for each expected handler binding.This keeps failures scoped to a single route assertion and aligns with the test standards.
As per coding guidelines, "MUST use t.Run("Should...") pattern for ALL test cases".
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@internal/api/httpapi/handlers_test.go` around lines 167 - 205, Replace the single-loop assertions in TestRegisterTaskRoutesUseSharedHandlerBindings with per-route subtests using t.Run to scope failures: iterate over expectedHandlers (the map in TestRegisterTaskRoutesUseSharedHandlerBindings), and for each key/handlerName call t.Run(fmt.Sprintf("Should register %s", key), func(t *testing.T) { /* copy key/handlerName into locals to avoid closure capture */ /* lookup routes := engine.Routes() and perform the same matched/handler substring assertions inside the subtest; optionally call t.Parallel() inside the subtest if desired */ }), so each route assertion is its own subtest while keeping the existing route lookup logic and assertions intact.internal/store/globaldb/global_db_task.go (2)
20-48: Potential performance concern with correlated subquery ordering.The
taskListOrderByActivitySQLuses a correlated subquery that scanstask_runsandtask_eventsfor each task row. For large datasets, this could become slow. Consider whether a denormalizedlast_activity_atcolumn ontasks(updated via triggers or application logic) would be warranted if performance becomes an issue.For now, this is acceptable for the expected scale, but monitor query times as the task table grows.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@internal/store/globaldb/global_db_task.go` around lines 20 - 48, The ORDER BY defined in taskListOrderByActivitySQL uses a correlated subquery that scans task_runs and task_events per tasks row which can degrade performance at scale; to mitigate, add a denormalized last_activity_at column on the tasks table and maintain it (either with DB triggers or in application logic whenever tasks, task_runs, or task_events change), then update taskListOrderByActivitySQL to order by tasks.last_activity_at (falling back to updated_at/created_at as needed) to avoid repeated subqueries over task_runs and task_events.
252-262: Case-insensitive search prevents index usage.Using
LOWER(title) LIKE ?andLOWER(COALESCE(identifier, ''))prevents SQLite from using indexes on these columns. For small-to-medium datasets this is fine. If search performance becomes problematic, consider:
- Adding computed columns or expression indexes (SQLite 3.9+)
- Storing lowercase versions of title/identifier
- Using FTS5 for full-text search
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@internal/store/globaldb/global_db_task.go` around lines 252 - 262, The current appendTaskSearchClause uses LOWER(...) which prevents SQLite from using indexes; update appendTaskSearchClause to avoid wrapping columns in LOWER and instead use case-insensitive collation: replace "(LOWER(title) LIKE ? OR LOWER(COALESCE(identifier, '')) LIKE ?)" and the lowercased likePattern with "(title LIKE ? COLLATE NOCASE OR COALESCE(identifier, '') LIKE ? COLLATE NOCASE)" and use likePattern := "%" + strings.TrimSpace(search) + "%"; keep args append order the same so the query can use indexes or expression indexes more effectively.internal/store/globaldb/global_db_task_test.go (1)
1148-1158: Consider using existingtestutil.EqualStringSlices.This local
equalStringSlicesfunction duplicatestestutil.EqualStringSliceswhich is already imported and used elsewhere in this file (line 294, 424, etc.). Consider removing this duplicate and using the shared utility consistently.♻️ Remove duplicate helper
-func equalStringSlices(left []string, right []string) bool { - if len(left) != len(right) { - return false - } - for idx := range left { - if left[idx] != right[idx] { - return false - } - } - return true -}Then replace usages at lines 847-850 with
testutil.EqualStringSlices(got, want).🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@internal/store/globaldb/global_db_task_test.go` around lines 1148 - 1158, Remove the duplicate local helper equalStringSlices and replace its usages with the existing testutil.EqualStringSlices utility: delete the equalStringSlices function definition and update any calls (e.g., where equalStringSlices(got, want) is used, such as the call around lines referenced in the review) to call testutil.EqualStringSlices(got, want) instead, ensuring imports remain intact and tests still compile.internal/api/contract/tasks_test.go (1)
11-436: Break this suite intot.Run("Should...")cases.These tests cover good scenarios, but they pack multiple independent assertions into a few top-level functions. Converting them to table-driven
Should...subtests would make failures easier to localize and align the new coverage with the repo’s test shape.As per coding guidelines,
Use table-driven tests with subtests (t.Run) as default in Go testsandMUST use t.Run("Should...") pattern for ALL test cases.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@internal/api/contract/tasks_test.go` around lines 11 - 436, The tests TestTaskContractsMarshalExpandedTaskReadModels, TestTaskContractsMarshalLiveDashboardAndInboxPayloads, and TestUpdateTaskRequestHasChangesIncludesExpandedFields pack multiple independent assertions into single top-level tests; split each into t.Run subtests using the "Should..." naming pattern (e.g., t.Run("ShouldMarshalSummaryDependencies", func(t *testing.T){...})), convert repeated/variant cases (like HasChanges checks) to a small table-driven slice and iterate with t.Run for each case, and move setup shared in those functions into helper variables or closures so each subtest is focused and fails independently; refer to the existing test functions by name (TestTaskContractsMarshalExpandedTaskReadModels, TestTaskContractsMarshalLiveDashboardAndInboxPayloads, TestUpdateTaskRequestHasChangesIncludesExpandedFields) and the specific assertions (marshalObject/nestedObject/assertObjectKeys and UpdateTaskRequest{}.HasChanges) when extracting cases.internal/observe/tasks_test.go (1)
392-1135: Convert these observer scenarios intoShould...subtests.The new dashboard/inbox coverage is solid, but it’s still organized as large standalone tests with many assertions per function. Recasting the scenarios as
t.Run("Should...")cases would make the suite easier to maintain and much quicker to debug when one branch regresses.As per coding guidelines,
Use table-driven tests with subtests (t.Run) as default in Go testsandMUST use t.Run("Should...") pattern for ALL test cases.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@internal/observe/tasks_test.go` around lines 392 - 1135, The tests under TestQueryTaskDashboardAggregatesCardsAndBreakdown, TestQueryTaskDashboardFlagsBacklogAndStaleSnapshots, TestQueryTaskDashboardSelectsRecentActiveRunsAndFiltersWorkspaces, TestTaskObserveQueryValidationAndConfigOption and TestQueryTaskInboxAssignsLanesAndSupportsFilters should be refactored so each distinct scenario becomes a t.Run("Should ...") subtest (or table-driven subtests) instead of one large function; for each scenario move its setup and assertions into its own t.Run block (calling t.Parallel() inside the subtest where safe), use descriptive "Should ..." names, and ensure helpers like newHarness, createObserveTask/createObserveRun/createObserveTriage and QueryTaskDashboard/QueryTaskInbox are invoked per-subtest so state is isolated and failures show the specific subtest name.internal/api/core/tasks_surface_test.go (1)
20-960: Reshape this file aroundShould...subtests.The coverage is good, but the new file still relies on large top-level tests and subtests that don’t use the repo’s
Should...pattern. Splitting the route/payload/error-path assertions into table-style subtests would make failures much easier to isolate.As per coding guidelines,
Use table-driven tests with subtests (t.Run) as default in Go testsandMUST use t.Run("Should...") pattern for ALL test cases.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@internal/api/core/tasks_surface_test.go` around lines 20 - 960, Split the large top-level tests (notably TestBaseHandlersExpandedTaskEndpoints and TestBaseHandlersExpandedTaskEndpointErrorPaths) into table-driven subtests using t.Run with "Should..." names for each scenario (e.g., "Should publish task", "Should return run detail", "Should return timeline", "Should handle stream SSE", and corresponding error-path cases); for each entry use its own test case struct (input path/method/headers/expected code and expected side-effects like publishActor, runDetailActor, timelineQuery) and run assertions inside the subtest so failures isolate to a single "Should..." case; keep use of fixture creation helpers (newHandlerFixtureWithTasks, newHandlerFixture), preserve existing actor/query variable captures (publishActor, runDetailActor, timelineActor, streamActor, dashboardQuery, inboxQuery, etc.) by resetting or scoping them per subtest, and ensure t.Parallel is called inside subtests where safe; also refactor the long payload-assertion block in TestExpandedTaskPayloadBuildersPreserveLiveAndAggregateFields into smaller t.Run("Should...") checks for Summary, Detail, RunDetail, Tree, Dashboard, Inbox payloads.internal/api/httpapi/httpapi_integration_test.go (1)
1214-1489: PreferShould...subtests for these new route flows.Both additions are meaningful end-to-end scenarios, but they’re still broad single-path tests. Breaking the route/assertion sets into
t.Run("Should...")cases would improve failure isolation and match the repo’s expected test layout.As per coding guidelines,
Use table-driven tests with subtests (t.Run) as default in Go testsandMUST use t.Run("Should...") pattern for ALL test cases.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@internal/api/httpapi/httpapi_integration_test.go` around lines 1214 - 1489, Both large tests (TestHTTPTaskPublishRunDetailAndLiveRoutesRoundTrip and TestHTTPTaskDashboardInboxApprovalAndTriageRoutesRoundTrip) must be split into t.Run subtests named "Should..." so failures are isolated; refactor each logical assertion block (e.g. publish, enqueue/claim/start, run detail, timeline, tree, stream for the first test; dashboard, inbox, approve/reject, triage actions, inbox-after checks for the second) into separate t.Run("Should ...") calls, moving repeated setup into the top-level test body or small helper functions (reuse createIntegrationTask, enqueueIntegrationTaskRun, claimIntegrationTaskRun, mustHTTPRequest, decodeHTTPJSON). Ensure each subtest performs only its single responsibility and retains the original assertions and decoding logic, so the tests remain table-driven/subtest-structured and follow the repo pattern.internal/api/core/parsers.go (1)
185-286: Validate enum-like query params in the exported parse helpers.
ParseTaskListQuery,ParseTaskDashboardQuery, andParseTaskInboxQuerynormalize fields likescope,status,owner_kind,origin_kind, andlane, but they still return invalid values without error. Right now that only gets caught later in the domain-query builders, so any caller that reuses these exported parsers directly gets inconsistent validation behavior.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@internal/api/core/parsers.go` around lines 185 - 286, The exported parsers (ParseTaskListQuery, ParseTaskDashboardQuery, ParseTaskInboxQuery) normalize enum-like inputs but do not validate them, allowing invalid values to pass through; update each parser to validate the normalized enum values and return a NewTaskValidationError on invalid input. Concretely: after computing Scope := taskpkg.Scope(...).Normalize(), Status := taskpkg.Status(...).Normalize(), Priority := taskpkg.Priority(...).Normalize(), OwnerKind := taskpkg.OwnerKind(...).Normalize(), ApprovalState := taskpkg.ApprovalState(...).Normalize(), OriginKind := taskpkg.OriginKind(...).Normalize(), and the inbox Lane := contract.TaskInboxLane(strings.ToLower(...)), call the corresponding validation predicates (e.g. Scope.IsValid(), Status.IsValid(), OwnerKind.IsValid(), OriginKind.IsValid(), contract.TaskInboxLane.IsValid() or equivalent) and if any return false, return an appropriate NewTaskValidationError; keep existing ParseOptionalBool/Int error handling unchanged and only add these validation checks before returning the constructed query objects.internal/observe/tasks_integration_test.go (1)
260-747: Restructure these integration cases intoShould...subtests.The new scenarios are valuable, but each test is still a large linear flow. Splitting the state transitions/assertions into
t.Run("Should...")cases would make regressions easier to pinpoint and keep the integration suite consistent with the repo standard.As per coding guidelines,
Use table-driven tests with subtests (t.Run) as default in Go testsandMUST use t.Run("Should...") pattern for ALL test cases.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@internal/observe/tasks_integration_test.go` around lines 260 - 747, These large linear integration tests (TestObserveTaskDashboardAggregatesPersistedLifecycleState, TestObserveTaskDashboardRefreshesAfterPersistedTransitions, TestObserveTaskInboxReflectsApprovalAndTriageTransitions) must be refactored into t.Run("Should...") subtests so each scenario/assertion block is isolated; extract common setup (newHarness, newObserveTaskManager, observeSessionExecutor, clock, actor derivation) into shared helper(s) and then create subtests for each distinct behavior (e.g. "Should report totals after persisted lifecycle transitions", "Should refresh dashboard after persisted transitions", "Should reflect approval and triage transitions in inbox") that run the specific sequence of manager.CreateTask / manager.EnqueueRun / manager.ClaimRun / manager.StartRun / manager.FailRun / manager.CompleteRun and then call h.observer.QueryTaskDashboard or h.observer.QueryTaskInbox to assert results; keep helper names (newHarness, newObserveTaskManager, observeTaskClock, observeSessionExecutor, manager.*, h.observer.QueryTaskDashboard, h.observer.QueryTaskInbox) to locate code and ensure each t.Run has a descriptive "Should..." title and minimal focused assertions.internal/extension/host_api.go (1)
428-436: Use the shared Host API method constants here.These new dispatch entries add more raw method strings to a surface that already has a protocol/capability contract. Reusing the shared constants would make routing drift much harder and avoid silent
method not foundmismatches when one side is renamed.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@internal/extension/host_api.go` around lines 428 - 436, Replace the raw method string keys in the dispatch map (e.g., "tasks/timeline", "tasks/tree", "tasks/dashboard", "tasks/inbox", "tasks/create", "tasks/update", "tasks/cancel", "tasks/runs", "tasks/runs/get") with the shared Host API method constants used across the codebase; locate the dispatch map that registers handler.handleTasksTimeline, handler.handleTasksTree, handler.handleTasksDashboard, handler.handleTasksInbox, handler.handleTasksCreate, handler.handleTasksUpdate, handler.handleTasksCancel, handler.handleTasksRuns and handler.handleTasksRunsGet and swap each string key for the corresponding constant (for example HostAPIMethodTasksTimeline or whatever constant names are defined) so routing relies on the centralized constants rather than hardcoded strings.internal/store/globaldb/global_db_task_aux.go (1)
141-143: Handle the newrows.Close()errors explicitly.Both new query paths discard
Close()errors with_, which hides finalization failures and breaks the repo rule for ignored errors.As per coding guidelines, "Never ignore errors with
_— every error must be handled or have a written justification."Also applies to: 544-546
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@internal/store/globaldb/global_db_task_aux.go` around lines 141 - 143, Replace the deferred discard of rows.Close() with explicit error handling: in each defer func() that currently does `_ = rows.Close()` (the deferred closure that finalizes SQL rows in the new query paths), capture the Close() return (e.g., `if cerr := rows.Close(); cerr != nil { /* handle */ }`) and handle it consistently — either log it via the package logger (e.g., processLogger.Errorf/Warningf with context "closing rows") or combine it into the function's return error (wrap/append to the existing error) instead of ignoring; apply this change to both places where rows.Close() is currently discarded.internal/api/core/tasks_surface_integration_test.go (1)
20-403: Wrap these new scenarios int.Run("Should...")subtests.This new file adds standalone cases instead of the repo's required subtest pattern, which makes it drift from the expected test structure for new coverage.
As per coding guidelines, "
**/*_test.go: Use table-driven tests with subtests (t.Run) as default" and "MUST uset.Run(\"Should...\")pattern for ALL test cases."🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@internal/api/core/tasks_surface_integration_test.go` around lines 20 - 403, Wrap each independent scenario inside the three tests into t.Run subtests using the "Should ..." naming pattern: modify TestExpandedTaskReadHandlersDelegateIntegration to wrap the list/detail/run/timeline/tree/dashboard/inbox checks (the blocks that performRequest and assert listResp, detailResp, runResp, timelineResp, treeResp, dashboardResp, inboxResp and their related assertions) in t.Run("Should ...", func(t *testing.T){ ... }); modify TestExpandedTaskMutationHandlersDelegateIntegration to wrap the loop that POSTs the mutation paths and the final assertions on calls/origins in a t.Run("Should ...", func(t *testing.T){ ... }); and modify TestTaskStreamHandlerUsesSharedSSEPathIntegration to wrap the stream request/assertions (streamQuery/streamActor checks and SSE parsing) in a t.Run("Should ...", func(t *testing.T){ ... }); keep t.Parallel() behavior consistent (call t.Parallel() inside subtests if you want them parallel) and ensure all existing local variables used by each scenario are moved/declared into the corresponding subtest scope so tests compile.internal/api/core/conversions.go (1)
592-995: These task mappers are duplicated across transports.This block now mirrors the task mapping code in
internal/extension/host_api_tasks.goalmost field-for-field. With timeline/tree/run-detail/dashboard/inbox all growing together, keeping both copies aligned will be brittle. Consider centralizing the task→payload transforms and letting each transport only wrap its transport-specific response shape.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@internal/api/core/conversions.go` around lines 592 - 995, The task→payload mapping functions (e.g., TaskReferencePayloadFromReference, TaskRunSummaryPayloadFromSummary, TaskTimelineItemPayloadFromItem, TaskTreePayloadFromView, TaskRunDetailPayloadFromView, TaskDashboardPayloadFromView, TaskInboxPayloadFromView and their helpers) are duplicated in another transport (internal/extension/host_api_tasks.go); extract these mappers into a single shared package (e.g., internal/api/core/taskmappers or internal/api/conversions/shared) and have both transports call the centralized functions, leaving only transport-specific response shaping in each transport file; update imports/usages to point at the new shared location and remove the duplicate implementations so all callers use the single source of truth.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@internal/api/contract/tasks.go`:
- Around line 51-72: The TaskPayload struct is missing the draft flag so
responses returned by
CreateTask/UpdateTask/PublishTask/CancelTask/ApproveTask/RejectTask lose draft
state; add a Draft bool `json:"draft,omitempty"` field to
internal/api/contract/tasks.go:TaskPayload and update
internal/api/core/tasks.go:TaskPayloadFromTask to set TaskPayload.Draft =
task.Draft (or equivalent) when converting from the domain Task so all
TaskResponse payloads include the draft value.
In `@internal/api/core/tasks_surface_internal_test.go`:
- Around line 195-219: The test currently exercises validation failure only
(ParseTaskInboxQuery with lane=bogus) so the workspaceServiceStub returning
workspacepkg.ErrWorkspaceNotFound is never reached; add a separate test case
that uses ParseTaskInboxQuery with a valid lane value and a workspace query
parameter (e.g., workspace=some-id) so that handlers.taskInboxDomainQuery is
invoked past validation and the workspaceServiceStub (configured to return
workspacepkg.ErrWorkspaceNotFound) triggers the workspace-resolution error path;
update assertions to expect a non-nil error and verify it matches
ErrWorkspaceNotFound (using the same assertTaskValidationError or a new
assertion for workspace resolution).
- Around line 20-27: The workspaceServiceStub passed into BaseHandlers (see
BaseHandlers and workspaceServiceStub with its get method) closes over the
parent *testing.T and calls t.Fatalf, which breaks isolation when subtests run
in parallel; fix by moving the handlers initialization into each t.Run subtest
so each subtest constructs its own BaseHandlers and stub bound to that subtest's
t, or change the stub's get implementation to return an error instead of calling
t.Fatalf and assert that error inside the specific subtest—ensure you update
references to the stub/get and remove direct t.Fatalf calls from code run
outside the subtest.
- Around line 16-20: The workspace service stub in
TestExpandedTaskQueryParsingAndDomainConversion closes over the parent
*testing.T (causing parallel-subtest reporting issues) and is unreachable
because taskInboxDomainQuery only triggers workspace lookup when both scope and
workspace params are present; either (A) change the stub interface used by the
test to accept a context or a *testing.T from the subtest (pass the subtest t
into the stub when calling TestExpandedTaskQueryParsingAndDomainConversion or
its subtests) so failures are reported to the correct test, or (B) remove the
unused workspace stub and instead add matching query parameters (scope and
workspace) to the test input so taskInboxDomainQuery exercises the
workspace-not-found path; locate the stub and the call site by the symbols
workspace service stub (closure) and taskInboxDomainQuery in
TestExpandedTaskQueryParsingAndDomainConversion to implement the chosen fix.
In `@internal/api/core/tasks_surface_test.go`:
- Around line 731-733: Replace the exact Content-Type equality check with a
prefix match to accept parameters: import the "strings" package and change the
test assertion that inspects streamResp.Header().Get("Content-Type") to use
strings.HasPrefix(got, "text/event-stream") (and adjust the failure message
accordingly) so responses like "text/event-stream; charset=utf-8" are accepted.
In `@internal/extension/host_api_integration_test.go`:
- Around line 665-667: The current assertion assumes the approval task is
exactly at inbox.Groups[0].Items[0] which is order-dependent; instead search
through inbox.Groups and their Items for an item whose Task.ID equals
approvalTask.ID (or use a helper like findTaskInInbox) and assert that such an
item exists; update the test around inbox.Groups/Items/Task.ID to perform a loop
or use a predicate that returns true if any group's items contain the expected
approvalTask.ID, and fail the test only if no match is found.
In `@internal/extension/host_api_tasks.go`:
- Around line 576-611: The workspace filter is only being resolved when
query.Scope == taskpkg.ScopeWorkspace which lets callers pass a workspace while
using a different scope and bypass the workspace filter; change
taskDashboardQueryFromParams (and the similar taskInboxQueryFromParams) to
always resolve and set query.WorkspaceID when params.Workspace is non-empty:
first TrimSpace params.Workspace, call taskpkg.ValidateScopeBinding as before to
validate the binding, then unconditionally call h.resolveTaskWorkspaceID(ctx,
workspaceRef) and assign the resulting workspaceID to query.WorkspaceID (still
return errors as currently done); keep scope logic and query.Validate() intact
so scope validation remains separate from workspace ID resolution.
- Around line 1406-1422: filtering out drafts in filterTaskListDrafts after
manager.ListTasks has already honored query.Limit breaks pagination by possibly
returning fewer non-draft items; fix by moving the draft predicate into the
original task query (so manager.ListTasks receives an explicit exclude-drafts
flag) or by changing this path to over-fetch until you accumulate query.Limit
non-draft items: either 1) add/propagate a flag on apicontract.TaskListQuery (or
set the existing IncludeDrafts appropriately) so manager.ListTasks returns only
non-drafts, or 2) implement an over-fetch loop in filterTaskListDrafts that
requests additional pages from ListTasks until len(filtered)==query.Limit or no
more tasks remain (use filterTaskListDrafts, apicontract.TaskListQuery,
taskpkg.Summary and the query.Limit semantics to locate where to change).
In `@internal/observe/observer.go`:
- Around line 91-95: The struct taskDashboardConfig currently uses hardcoded
threshold literals; change it to accept values from configuration or functional
options by exposing these fields as settable (or adding a constructor like
NewTaskDashboardConfig(cfg *Config) or NewTaskDashboardConfig(opts
...TaskDashboardOption)) and wire it into observer construction so callers
supply backlogWarnAfter, staleAfter and activeRunLimit from the TOML-loaded
config or provided options; update any place that instantiates
taskDashboardConfig with literal values (including the other occurrences noted)
to call the new constructor or option setters so thresholds are not hardcoded.
In `@internal/store/globaldb/global_db_task_aux.go`:
- Around line 497-503: The code currently exposes SQLite's internal rowid (see
the SELECT that returns rowid) which is unstable; add and use an explicit
monotonic sequence column (e.g., sequence INTEGER PRIMARY KEY AUTOINCREMENT or a
separate sequence field like event_seq INTEGER NOT NULL UNIQUE with DB-side
auto-increment behavior) in the task_events schema and replace all uses of
"rowid" in queries and ordering with that new sequence column (update INSERTs,
SELECTs, and any ordering/pagination logic that referenced rowid). Also replace
the ignored close patterns (defer func() { _ = rows.Close() }() and similar)
with proper error handling: capture the error from rows.Close(), propagate or
log it alongside the primary error (e.g., if scan returns err and closeErr !=
nil, wrap/return a combined error), or explicitly document why close errors are
safe to ignore per coding guidelines; update the routines referencing
rows.Close() (the QueryRowContext/rows handling around the SELECT of event by id
and the other rows loops) to implement this change.
In `@internal/store/globaldb/migrate_workspace.go`:
- Around line 227-233: The migration drops the old tasks table and renames
tasks_new but never re-creates indexes, causing query regressions; update
taskTableMigrationStatements (and related logic around
taskTableCreateStatement/taskTableCopyStatement) to collect the existing index
definitions for the original "tasks" table (e.g. via pg_indexes/pg_get_indexdef)
and append corresponding CREATE INDEX / CONCURRENTLY statements after the `ALTER
TABLE tasks_new RENAME TO tasks` step (or alternatively recreate them before
dropping the old table), ensuring unique constraint/index expressions and names
are preserved and any pg-specific options (CONCURRENTLY) are respected.
In `@internal/task/live.go`:
- Around line 43-55: The code currently closes the deliver channel in
taskStreamSubscriber.stop(), which can race with taskStreamSubscriber.enqueue()
(called from emitTaskLiveEventBestEffort) and cause a panic; change the shutdown
signalling to avoid closing deliver: add a separate done chan struct{} (or an
atomic/locked closed flag) on taskStreamSubscriber, have stop() close(done) via
closeOnce, and remove close(s.deliver); update enqueue(event StreamEvent) to
first select on <-s.done to return false if closed, otherwise attempt to send to
s.deliver (preserving the non-blocking default path), e.g., select { case
<-s.done: return false; case s.deliver <- event: return true; default: return
false }, and ensure any other code that iterates subscribers uses the done
signal rather than relying on closed deliver.
In `@internal/task/manager.go`:
- Around line 1315-1369: prepareEnqueueRun is vulnerable to race conditions
because idempotency lookup (lookupIdempotentRun) and attempt calculation
(nextEnqueueAttempt which calls ListTaskRuns/nextRunAttempt) happen outside any
atomic store operation; update the flow to perform these steps inside a single
store-level atomic operation (e.g., a DB transaction or a store method that does
it atomically) so that creating the TaskRun and saving the idempotency mapping
(CreateTaskRun and SaveTaskRunIdempotency) are done together with the attempt
check (or enforce a unique constraint and handle conflicts); concretely
implement a new store method (or transaction wrapper) that: checks for an
existing idempotent run, computes/validates next attempt against
normalizeTaskMaxAttemptsOrDefault(task.MaxAttempts), creates the run, and writes
the idempotency mapping atomically, returning a duplicate/conflict error if
another concurrent enqueuer wins.
- Around line 1105-1188:
listTaskSummaries/enrichTaskSummary/buildDependencyReferences cause N+1 queries:
each summary calls CountDirectChildren, ListDependencies, ListTaskRuns,
ListTaskEvents and taskReference for each dependency; instead add batched store
APIs (e.g. ListTasksWithMeta or separate methods like
CountDirectChildrenForTasks(ctx, []taskID), ListDependenciesForTasks(ctx,
[]taskID), ListTaskRunsForTasks(ctx, []taskID), ListTaskEventsForTasks(ctx,
[]taskID), and ResolveTaskReferences(ctx, []taskID)) and use them in
listTaskSummaries to fetch all counts/dependencies/runs/events/references in
bulk, then change
enrichTaskSummary/enrichTaskSummaryFromState/buildDependencyReferences to accept
pre-fetched maps/slices and build summaries from those maps (lookup by task ID)
rather than issuing per-item store calls, preserving existing return types and
status logic.
---
Outside diff comments:
In `@internal/api/core/tasks.go`:
- Around line 118-129: The current flow calls manager.ListTasks using query
(which applies query.Limit at SQL) and then removes drafts with
filterTaskListDrafts, causing drafts to consume the page budget; change this by
pushing the draft predicate into the DB query or overfetching until you return
transportQuery.Limit non-draft rows: update taskListDomainQuery (and the query
it returns) to respect transportQuery.IncludeDrafts/Status by adding a WHERE
clause that excludes drafts when IncludeDrafts is false, or modify
ListTasks/GlobalDB.ListTasks to accept an includeDrafts flag and apply the
predicate at SQL; alternatively implement overfetch logic in the handler around
manager.ListTasks to request extra rows and loop fetching until you have
transportQuery.Limit non-draft tasks before trimming with filterTaskListDrafts.
---
Nitpick comments:
In `@internal/api/contract/tasks_test.go`:
- Around line 11-436: The tests TestTaskContractsMarshalExpandedTaskReadModels,
TestTaskContractsMarshalLiveDashboardAndInboxPayloads, and
TestUpdateTaskRequestHasChangesIncludesExpandedFields pack multiple independent
assertions into single top-level tests; split each into t.Run subtests using the
"Should..." naming pattern (e.g., t.Run("ShouldMarshalSummaryDependencies",
func(t *testing.T){...})), convert repeated/variant cases (like HasChanges
checks) to a small table-driven slice and iterate with t.Run for each case, and
move setup shared in those functions into helper variables or closures so each
subtest is focused and fails independently; refer to the existing test functions
by name (TestTaskContractsMarshalExpandedTaskReadModels,
TestTaskContractsMarshalLiveDashboardAndInboxPayloads,
TestUpdateTaskRequestHasChangesIncludesExpandedFields) and the specific
assertions (marshalObject/nestedObject/assertObjectKeys and
UpdateTaskRequest{}.HasChanges) when extracting cases.
In `@internal/api/core/conversions.go`:
- Around line 592-995: The task→payload mapping functions (e.g.,
TaskReferencePayloadFromReference, TaskRunSummaryPayloadFromSummary,
TaskTimelineItemPayloadFromItem, TaskTreePayloadFromView,
TaskRunDetailPayloadFromView, TaskDashboardPayloadFromView,
TaskInboxPayloadFromView and their helpers) are duplicated in another transport
(internal/extension/host_api_tasks.go); extract these mappers into a single
shared package (e.g., internal/api/core/taskmappers or
internal/api/conversions/shared) and have both transports call the centralized
functions, leaving only transport-specific response shaping in each transport
file; update imports/usages to point at the new shared location and remove the
duplicate implementations so all callers use the single source of truth.
In `@internal/api/core/parsers.go`:
- Around line 185-286: The exported parsers (ParseTaskListQuery,
ParseTaskDashboardQuery, ParseTaskInboxQuery) normalize enum-like inputs but do
not validate them, allowing invalid values to pass through; update each parser
to validate the normalized enum values and return a NewTaskValidationError on
invalid input. Concretely: after computing Scope :=
taskpkg.Scope(...).Normalize(), Status := taskpkg.Status(...).Normalize(),
Priority := taskpkg.Priority(...).Normalize(), OwnerKind :=
taskpkg.OwnerKind(...).Normalize(), ApprovalState :=
taskpkg.ApprovalState(...).Normalize(), OriginKind :=
taskpkg.OriginKind(...).Normalize(), and the inbox Lane :=
contract.TaskInboxLane(strings.ToLower(...)), call the corresponding validation
predicates (e.g. Scope.IsValid(), Status.IsValid(), OwnerKind.IsValid(),
OriginKind.IsValid(), contract.TaskInboxLane.IsValid() or equivalent) and if any
return false, return an appropriate NewTaskValidationError; keep existing
ParseOptionalBool/Int error handling unchanged and only add these validation
checks before returning the constructed query objects.
In `@internal/api/core/tasks_surface_integration_test.go`:
- Around line 20-403: Wrap each independent scenario inside the three tests into
t.Run subtests using the "Should ..." naming pattern: modify
TestExpandedTaskReadHandlersDelegateIntegration to wrap the
list/detail/run/timeline/tree/dashboard/inbox checks (the blocks that
performRequest and assert listResp, detailResp, runResp, timelineResp, treeResp,
dashboardResp, inboxResp and their related assertions) in t.Run("Should ...",
func(t *testing.T){ ... }); modify
TestExpandedTaskMutationHandlersDelegateIntegration to wrap the loop that POSTs
the mutation paths and the final assertions on calls/origins in a t.Run("Should
...", func(t *testing.T){ ... }); and modify
TestTaskStreamHandlerUsesSharedSSEPathIntegration to wrap the stream
request/assertions (streamQuery/streamActor checks and SSE parsing) in a
t.Run("Should ...", func(t *testing.T){ ... }); keep t.Parallel() behavior
consistent (call t.Parallel() inside subtests if you want them parallel) and
ensure all existing local variables used by each scenario are moved/declared
into the corresponding subtest scope so tests compile.
In `@internal/api/core/tasks_surface_test.go`:
- Around line 20-960: Split the large top-level tests (notably
TestBaseHandlersExpandedTaskEndpoints and
TestBaseHandlersExpandedTaskEndpointErrorPaths) into table-driven subtests using
t.Run with "Should..." names for each scenario (e.g., "Should publish task",
"Should return run detail", "Should return timeline", "Should handle stream
SSE", and corresponding error-path cases); for each entry use its own test case
struct (input path/method/headers/expected code and expected side-effects like
publishActor, runDetailActor, timelineQuery) and run assertions inside the
subtest so failures isolate to a single "Should..." case; keep use of fixture
creation helpers (newHandlerFixtureWithTasks, newHandlerFixture), preserve
existing actor/query variable captures (publishActor, runDetailActor,
timelineActor, streamActor, dashboardQuery, inboxQuery, etc.) by resetting or
scoping them per subtest, and ensure t.Parallel is called inside subtests where
safe; also refactor the long payload-assertion block in
TestExpandedTaskPayloadBuildersPreserveLiveAndAggregateFields into smaller
t.Run("Should...") checks for Summary, Detail, RunDetail, Tree, Dashboard, Inbox
payloads.
In `@internal/api/httpapi/handlers_test.go`:
- Around line 167-205: Replace the single-loop assertions in
TestRegisterTaskRoutesUseSharedHandlerBindings with per-route subtests using
t.Run to scope failures: iterate over expectedHandlers (the map in
TestRegisterTaskRoutesUseSharedHandlerBindings), and for each key/handlerName
call t.Run(fmt.Sprintf("Should register %s", key), func(t *testing.T) { /* copy
key/handlerName into locals to avoid closure capture */ /* lookup routes :=
engine.Routes() and perform the same matched/handler substring assertions inside
the subtest; optionally call t.Parallel() inside the subtest if desired */ }),
so each route assertion is its own subtest while keeping the existing route
lookup logic and assertions intact.
In `@internal/api/httpapi/httpapi_integration_test.go`:
- Around line 1214-1489: Both large tests
(TestHTTPTaskPublishRunDetailAndLiveRoutesRoundTrip and
TestHTTPTaskDashboardInboxApprovalAndTriageRoutesRoundTrip) must be split into
t.Run subtests named "Should..." so failures are isolated; refactor each logical
assertion block (e.g. publish, enqueue/claim/start, run detail, timeline, tree,
stream for the first test; dashboard, inbox, approve/reject, triage actions,
inbox-after checks for the second) into separate t.Run("Should ...") calls,
moving repeated setup into the top-level test body or small helper functions
(reuse createIntegrationTask, enqueueIntegrationTaskRun,
claimIntegrationTaskRun, mustHTTPRequest, decodeHTTPJSON). Ensure each subtest
performs only its single responsibility and retains the original assertions and
decoding logic, so the tests remain table-driven/subtest-structured and follow
the repo pattern.
In `@internal/api/udsapi/handlers_test.go`:
- Around line 218-256: The test TestRegisterTaskRoutesUseSharedHandlerBindings
should be converted from a single map-driven assertion block into explicit t.Run
subtests: iterate the expectedHandlers map and for each entry call t.Run with a
descriptive name starting with "Should..." (e.g., "Should register GET
/api/observe/tasks/dashboard" or "Should bind TaskDashboard"), move the route
lookup and assertions (the engine.Routes() scan and the two t.Fatalf checks)
inside the subtest closure so failures are isolated, and keep use of the matched
variable and strings.Contains(matched.Handler, handlerName) logic unchanged;
ensure each subtest uses the same test helpers (newTestRouter, newTestHandlers)
context or captures necessary variables to avoid race issues.
In `@internal/daemon/automation_task_e2e_assertions_test.go`:
- Around line 84-87: In findTaskRunInDetail, add a nil guard for the detail
pointer before accessing detail.Runs: if detail == nil return the zero-value
aghcontract.TaskRunPayload and false; otherwise call
findTaskRunPayload(detail.Runs, runID) as before. This prevents a panic when
detail is nil and preserves the helper's boolean-found semantics.
In `@internal/extension/host_api.go`:
- Around line 428-436: Replace the raw method string keys in the dispatch map
(e.g., "tasks/timeline", "tasks/tree", "tasks/dashboard", "tasks/inbox",
"tasks/create", "tasks/update", "tasks/cancel", "tasks/runs", "tasks/runs/get")
with the shared Host API method constants used across the codebase; locate the
dispatch map that registers handler.handleTasksTimeline,
handler.handleTasksTree, handler.handleTasksDashboard, handler.handleTasksInbox,
handler.handleTasksCreate, handler.handleTasksUpdate, handler.handleTasksCancel,
handler.handleTasksRuns and handler.handleTasksRunsGet and swap each string key
for the corresponding constant (for example HostAPIMethodTasksTimeline or
whatever constant names are defined) so routing relies on the centralized
constants rather than hardcoded strings.
In `@internal/observe/tasks_integration_test.go`:
- Around line 260-747: These large linear integration tests
(TestObserveTaskDashboardAggregatesPersistedLifecycleState,
TestObserveTaskDashboardRefreshesAfterPersistedTransitions,
TestObserveTaskInboxReflectsApprovalAndTriageTransitions) must be refactored
into t.Run("Should...") subtests so each scenario/assertion block is isolated;
extract common setup (newHarness, newObserveTaskManager, observeSessionExecutor,
clock, actor derivation) into shared helper(s) and then create subtests for each
distinct behavior (e.g. "Should report totals after persisted lifecycle
transitions", "Should refresh dashboard after persisted transitions", "Should
reflect approval and triage transitions in inbox") that run the specific
sequence of manager.CreateTask / manager.EnqueueRun / manager.ClaimRun /
manager.StartRun / manager.FailRun / manager.CompleteRun and then call
h.observer.QueryTaskDashboard or h.observer.QueryTaskInbox to assert results;
keep helper names (newHarness, newObserveTaskManager, observeTaskClock,
observeSessionExecutor, manager.*, h.observer.QueryTaskDashboard,
h.observer.QueryTaskInbox) to locate code and ensure each t.Run has a
descriptive "Should..." title and minimal focused assertions.
In `@internal/observe/tasks_test.go`:
- Around line 392-1135: The tests under
TestQueryTaskDashboardAggregatesCardsAndBreakdown,
TestQueryTaskDashboardFlagsBacklogAndStaleSnapshots,
TestQueryTaskDashboardSelectsRecentActiveRunsAndFiltersWorkspaces,
TestTaskObserveQueryValidationAndConfigOption and
TestQueryTaskInboxAssignsLanesAndSupportsFilters should be refactored so each
distinct scenario becomes a t.Run("Should ...") subtest (or table-driven
subtests) instead of one large function; for each scenario move its setup and
assertions into its own t.Run block (calling t.Parallel() inside the subtest
where safe), use descriptive "Should ..." names, and ensure helpers like
newHarness, createObserveTask/createObserveRun/createObserveTriage and
QueryTaskDashboard/QueryTaskInbox are invoked per-subtest so state is isolated
and failures show the specific subtest name.
In `@internal/store/globaldb/global_db_task_aux.go`:
- Around line 141-143: Replace the deferred discard of rows.Close() with
explicit error handling: in each defer func() that currently does `_ =
rows.Close()` (the deferred closure that finalizes SQL rows in the new query
paths), capture the Close() return (e.g., `if cerr := rows.Close(); cerr != nil
{ /* handle */ }`) and handle it consistently — either log it via the package
logger (e.g., processLogger.Errorf/Warningf with context "closing rows") or
combine it into the function's return error (wrap/append to the existing error)
instead of ignoring; apply this change to both places where rows.Close() is
currently discarded.
In `@internal/store/globaldb/global_db_task_test.go`:
- Around line 1148-1158: Remove the duplicate local helper equalStringSlices and
replace its usages with the existing testutil.EqualStringSlices utility: delete
the equalStringSlices function definition and update any calls (e.g., where
equalStringSlices(got, want) is used, such as the call around lines referenced
in the review) to call testutil.EqualStringSlices(got, want) instead, ensuring
imports remain intact and tests still compile.
In `@internal/store/globaldb/global_db_task.go`:
- Around line 20-48: The ORDER BY defined in taskListOrderByActivitySQL uses a
correlated subquery that scans task_runs and task_events per tasks row which can
degrade performance at scale; to mitigate, add a denormalized last_activity_at
column on the tasks table and maintain it (either with DB triggers or in
application logic whenever tasks, task_runs, or task_events change), then update
taskListOrderByActivitySQL to order by tasks.last_activity_at (falling back to
updated_at/created_at as needed) to avoid repeated subqueries over task_runs and
task_events.
- Around line 252-262: The current appendTaskSearchClause uses LOWER(...) which
prevents SQLite from using indexes; update appendTaskSearchClause to avoid
wrapping columns in LOWER and instead use case-insensitive collation: replace
"(LOWER(title) LIKE ? OR LOWER(COALESCE(identifier, '')) LIKE ?)" and the
lowercased likePattern with "(title LIKE ? COLLATE NOCASE OR
COALESCE(identifier, '') LIKE ? COLLATE NOCASE)" and use likePattern := "%" +
strings.TrimSpace(search) + "%"; keep args append order the same so the query
can use indexes or expression indexes more effectively.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
Adds the first-class /_app/tasks area with base, detail, and run-detail deep-link routes, a shared TasksPageShell, and a Tasks sidebar nav entry that stays active across the full tasks family. Later tasks can mount screen orchestration inside this shell instead of forking new route-shell layouts. Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
Builds the main browsing and creation surfaces on the /_app/tasks shell. The useTasksPage hook now orchestrates mode switching, kanban grouping, draft authoring, template defaults, publish, and create-and-enqueue flows on top of the task_13 systems barrel; presentational components render the split-view list, the kanban board, the templated empty state, and the create modal. Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
Replace the placeholder /_app/tasks/$id and /_app/tasks/$id/runs/$runId routes with task-native detail and run-detail experiences backed by the tasks system live reads. Add header, tabs, overview, timeline, runs, children, and dependencies panels to the detail route; add identity, progress, activity, and linked-session drill-down to the run-detail route. Extend use-task-detail-page with timeline pagination plus cancel, publish, and enqueue actions; extend use-task-run-page with cancel run and isLive derivations. Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
Exposes the observer-backed task dashboard and inbox as first-class `/_app/tasks` modes alongside list and kanban. Dashboard renders summary cards, status breakdown, queue/health, freshness, and active runs. Inbox renders lane tabs with unread counts plus grouped items and approve/reject/retry/archive/dismiss/mark-read triage actions. Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
Extends useTaskDetailPage with a new "agents" panel and a MultiAgentView derived from the existing task-tree read, then mounts TasksMultiAgentPanel in /tasks/$id with parent + descendant agent cards, live pill, session/run drill-downs, reused interleaved timeline, and loading/disconnected/no- descendants/no-active fallbacks. Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
## Release v0.0.1 This PR prepares the release of version v0.0.1. ### Changelog ## 0.0.1 - 2026-05-26 ### Other Changes - Lessons learned ### ♻️ Refactoring - Project structure (#7) - Kb improvements (#12) - Rename spaces to channels (#17) - Add extensions gaps (#21) - Improve tool calls ui (#22) - Remove web app header - Module improvements (#29) - Memory improvements (#35) - Storybook for web and ui (#38) - Enable AGH network by default for new installs (#57) - Hermes adjustments (#69) - Badges design (#84) - Storybook scenario and logos gallery - Migrate typescript tests (#114) - Internal go packages (#120) - Ui patterns (#127) - Improve e2e tests (#130) - Ui redesign - Workspace isolation across runtime surfaces (#145) - Prod ready applies (#162) - Tool card ui (#164) - Alpha on logo - Prod ready features (#167) - Thread sheet (#202) ### 🎉 Features - Implement config foundation packages - Implement sqlite store package - Add ACP client package - Add session lifecycle manager - Implement observe package - Add daemon composition root - Add uds api server - Implement cli package - Add http api server - Add system design - Add foundation types, schemas, and layout shell for web client - Add daemon health polling and agent sidebar systems for web client - Add session system CRUD, streaming core, and session store for web client - Add chat view, messages, and composer tests for web client - Add tool cards and renderers for web client - Add file-backed memory store core - Scaffold memory session seams - Add memory dream consolidation service - Wire memory assembler into daemon - Add memory api and cli - New skills system (#1) - Add workspace entity (#5) - Add new skill capabilities (#8) - Web ui v2 (#9) - Improve hooks system (#10) - Session resilience (#11) - Add extensability (#13) - Add automation (#16) - Add channels (#14) - Add network implementation (#15) - Add network, bridges and automations web pages (#18) - Ext registry (#20) - Add core tasks (#19) - Bridge adapters (#23) - Add site (#26) - Add ext refac and sandbox (#25) - Settings ui (#37) - Tasks ui (#36) - Harness improvements (#44) - Agent capabilities (#49) - Redesign ui (#48) - Unify capability (#53) - Redesign network workspace (#59) - Add task deletion and split session delete from stop (#58) - Session provider selection (#60) - Production grade adjustments (#66) - Autonomous system (#75) - Add agent session route (#80) - Tools registry (#85) - Agents soul (#88) - Add network threads (#105) - Orchestration improvements (#106) - Memory v2 (#108) - Agent categories (#113) - Providers model (#118) - Add canonical AGH bundled skill (#143) - Onboarding and improvements (#198) - Onboarding and improvements (#201) ### 🐛 Bug Fixes - Review round - Review rounds - Resolve memory extensibility review batch - Embed web into daemon - Defaults agents - Acp integration (#4) - Lint errors - Prd folder - Remove orphan web actions and dead surfaces (#55) - Qa testing and fixes (#73) - New review rounds (#82) - Security audit (#90) - Release qa round (#95) - Add missing tools (#141) - New qa round (#147) - Advanced qa round (#149) - Homebrew tap - Final review round (#151) - Daemon healthy - Reasoning models (#158) - Lint errors (#160) - Review round (#168) - Release adjustments (#171) - Stabilize release ci fixtures - Stabilize release integration gate - Stabilize release verify gates - Stabilize release integration flows - Stabilize release verify gates - Stabilize main verify shutdown - Ignore stale acpmock cancel - Marketplace search focus and filtering (#193) - Website video - Workspace command select ### 📚 Documentation - Update agents.md - Update prd - Update skills - Update compozy tasks - Update compozy - Update compozy - Add new skills - Archive prd - Update prds - Update rfc - Update prds - Update prds - Add automation prd - Channels prd - Update prd - Update prd - New prds - Archive prds - Bridges adapters prd - Sandbox prd - Update - Archive prd - Update - Add new prd - New design - Update prd - Archive prds - Update prds - Tasks-ui prd tasks - Update prd - Update design docs - Agent capabilities prd - Improve site docs - Remove old design references - Udpate - Autonomous prd - Update skills - Blog design - Agent sould prd - Final qa plan - Update - Remove codex ledgers from gitignore - Remove not needed files - Udpate ledger - Update cy-codex-loop skill - Orchestration improves prd - Update prds - Orch improvs prd - Memv2 prd - Providers model prd - Update refacs prd - New design proposal - Update rules - Update skills - New blog posts (#173) - Format docs - Remove old design files - Remove old - Skeeper update ### 📦 Build System - Initial structure - Commitlint - Frontend base structure - Update vscode settings - Add subagents - Coderabbit - Prd and tooling - Bun lock - Lint tooling - Copy.md and tooling adjusts - Add repoclone rc - Upgrade skeeper to v0.2.0 - Update go.mod - Adopt task artifacts into skeeper - Sync codex plans with skeeper - Skeeper lock - Skeeper lock - New skills - Skeeper lock - Skeeper lock - Skeeper lock - Update deps and go - Regenerate daytona sidecar assets for go 1.26.3 - Fix cliff - Ignore docs on fmt - Build web assets before goreleaser - Extend release dry-run timeout ### 🔧 CI/CD - Lint errors - Fint release pr - Fix goreleaser ### 🧪 Testing - Add e2e tests (#27) - Qa rounds (#78) - Improve test suite (#138) - Harden daemon-served restart reloads - Harden daemon-served readiness waits - Stabilize dashboard focus assertion - Stabilize release integration gates - Stabilize release e2e markers - Stabilize release e2e flows Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
## Release v0.0.1 This PR prepares the release of version v0.0.1. ### Changelog ## 0.0.1 - 2026-05-26 ### Other Changes - Lessons learned ### ♻️ Refactoring - Project structure (#7) - Kb improvements (#12) - Rename spaces to channels (#17) - Add extensions gaps (#21) - Improve tool calls ui (#22) - Remove web app header - Module improvements (#29) - Memory improvements (#35) - Storybook for web and ui (#38) - Enable AGH network by default for new installs (#57) - Hermes adjustments (#69) - Badges design (#84) - Storybook scenario and logos gallery - Migrate typescript tests (#114) - Internal go packages (#120) - Ui patterns (#127) - Improve e2e tests (#130) - Ui redesign - Workspace isolation across runtime surfaces (#145) - Prod ready applies (#162) - Tool card ui (#164) - Alpha on logo - Prod ready features (#167) - Thread sheet (#202) ### 🎉 Features - Implement config foundation packages - Implement sqlite store package - Add ACP client package - Add session lifecycle manager - Implement observe package - Add daemon composition root - Add uds api server - Implement cli package - Add http api server - Add system design - Add foundation types, schemas, and layout shell for web client - Add daemon health polling and agent sidebar systems for web client - Add session system CRUD, streaming core, and session store for web client - Add chat view, messages, and composer tests for web client - Add tool cards and renderers for web client - Add file-backed memory store core - Scaffold memory session seams - Add memory dream consolidation service - Wire memory assembler into daemon - Add memory api and cli - New skills system (#1) - Add workspace entity (#5) - Add new skill capabilities (#8) - Web ui v2 (#9) - Improve hooks system (#10) - Session resilience (#11) - Add extensability (#13) - Add automation (#16) - Add channels (#14) - Add network implementation (#15) - Add network, bridges and automations web pages (#18) - Ext registry (#20) - Add core tasks (#19) - Bridge adapters (#23) - Add site (#26) - Add ext refac and sandbox (#25) - Settings ui (#37) - Tasks ui (#36) - Harness improvements (#44) - Agent capabilities (#49) - Redesign ui (#48) - Unify capability (#53) - Redesign network workspace (#59) - Add task deletion and split session delete from stop (#58) - Session provider selection (#60) - Production grade adjustments (#66) - Autonomous system (#75) - Add agent session route (#80) - Tools registry (#85) - Agents soul (#88) - Add network threads (#105) - Orchestration improvements (#106) - Memory v2 (#108) - Agent categories (#113) - Providers model (#118) - Add canonical AGH bundled skill (#143) - Onboarding and improvements (#198) - Onboarding and improvements (#201) ### 🐛 Bug Fixes - Review round - Review rounds - Resolve memory extensibility review batch - Embed web into daemon - Defaults agents - Acp integration (#4) - Lint errors - Prd folder - Remove orphan web actions and dead surfaces (#55) - Qa testing and fixes (#73) - New review rounds (#82) - Security audit (#90) - Release qa round (#95) - Add missing tools (#141) - New qa round (#147) - Advanced qa round (#149) - Homebrew tap - Final review round (#151) - Daemon healthy - Reasoning models (#158) - Lint errors (#160) - Review round (#168) - Release adjustments (#171) - Stabilize release ci fixtures - Stabilize release integration gate - Stabilize release verify gates - Stabilize release integration flows - Stabilize release verify gates - Stabilize main verify shutdown - Ignore stale acpmock cancel - Marketplace search focus and filtering (#193) - Website video - Workspace command select ### 📚 Documentation - Update agents.md - Update prd - Update skills - Update compozy tasks - Update compozy - Update compozy - Add new skills - Archive prd - Update prds - Update rfc - Update prds - Update prds - Add automation prd - Channels prd - Update prd - Update prd - New prds - Archive prds - Bridges adapters prd - Sandbox prd - Update - Archive prd - Update - Add new prd - New design - Update prd - Archive prds - Update prds - Tasks-ui prd tasks - Update prd - Update design docs - Agent capabilities prd - Improve site docs - Remove old design references - Udpate - Autonomous prd - Update skills - Blog design - Agent sould prd - Final qa plan - Update - Remove codex ledgers from gitignore - Remove not needed files - Udpate ledger - Update cy-codex-loop skill - Orchestration improves prd - Update prds - Orch improvs prd - Memv2 prd - Providers model prd - Update refacs prd - New design proposal - Update rules - Update skills - New blog posts (#173) - Format docs - Remove old design files - Remove old - Skeeper update ### 📦 Build System - Initial structure - Commitlint - Frontend base structure - Update vscode settings - Add subagents - Coderabbit - Prd and tooling - Bun lock - Lint tooling - Copy.md and tooling adjusts - Add repoclone rc - Upgrade skeeper to v0.2.0 - Update go.mod - Adopt task artifacts into skeeper - Sync codex plans with skeeper - Skeeper lock - Skeeper lock - New skills - Skeeper lock - Skeeper lock - Skeeper lock - Update deps and go - Regenerate daytona sidecar assets for go 1.26.3 - Fix cliff - Ignore docs on fmt - Build web assets before goreleaser - Extend release dry-run timeout ### 🔧 CI/CD - Lint errors - Fint release pr - Fix goreleaser - Fix release ### 🧪 Testing - Add e2e tests (#27) - Qa rounds (#78) - Improve test suite (#138) - Harden daemon-served restart reloads - Harden daemon-served readiness waits - Stabilize dashboard focus assertion - Stabilize release integration gates - Stabilize release e2e markers - Stabilize release e2e flows Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
## Release v0.0.2 This PR prepares the release of version v0.0.2. ### Changelog ## 0.0.2 - 2026-05-26 ### Other Changes - Lessons learned ### ♻️ Refactoring - Project structure (#7) - Kb improvements (#12) - Rename spaces to channels (#17) - Add extensions gaps (#21) - Improve tool calls ui (#22) - Remove web app header - Module improvements (#29) - Memory improvements (#35) - Storybook for web and ui (#38) - Enable AGH network by default for new installs (#57) - Hermes adjustments (#69) - Badges design (#84) - Storybook scenario and logos gallery - Migrate typescript tests (#114) - Internal go packages (#120) - Ui patterns (#127) - Improve e2e tests (#130) - Ui redesign - Workspace isolation across runtime surfaces (#145) - Prod ready applies (#162) - Tool card ui (#164) - Alpha on logo - Prod ready features (#167) - Thread sheet (#202) ### 🎉 Features - Implement config foundation packages - Implement sqlite store package - Add ACP client package - Add session lifecycle manager - Implement observe package - Add daemon composition root - Add uds api server - Implement cli package - Add http api server - Add system design - Add foundation types, schemas, and layout shell for web client - Add daemon health polling and agent sidebar systems for web client - Add session system CRUD, streaming core, and session store for web client - Add chat view, messages, and composer tests for web client - Add tool cards and renderers for web client - Add file-backed memory store core - Scaffold memory session seams - Add memory dream consolidation service - Wire memory assembler into daemon - Add memory api and cli - New skills system (#1) - Add workspace entity (#5) - Add new skill capabilities (#8) - Web ui v2 (#9) - Improve hooks system (#10) - Session resilience (#11) - Add extensability (#13) - Add automation (#16) - Add channels (#14) - Add network implementation (#15) - Add network, bridges and automations web pages (#18) - Ext registry (#20) - Add core tasks (#19) - Bridge adapters (#23) - Add site (#26) - Add ext refac and sandbox (#25) - Settings ui (#37) - Tasks ui (#36) - Harness improvements (#44) - Agent capabilities (#49) - Redesign ui (#48) - Unify capability (#53) - Redesign network workspace (#59) - Add task deletion and split session delete from stop (#58) - Session provider selection (#60) - Production grade adjustments (#66) - Autonomous system (#75) - Add agent session route (#80) - Tools registry (#85) - Agents soul (#88) - Add network threads (#105) - Orchestration improvements (#106) - Memory v2 (#108) - Agent categories (#113) - Providers model (#118) - Add canonical AGH bundled skill (#143) - Onboarding and improvements (#198) - Onboarding and improvements (#201) ### 🐛 Bug Fixes - Review round - Review rounds - Resolve memory extensibility review batch - Embed web into daemon - Defaults agents - Acp integration (#4) - Lint errors - Prd folder - Remove orphan web actions and dead surfaces (#55) - Qa testing and fixes (#73) - New review rounds (#82) - Security audit (#90) - Release qa round (#95) - Add missing tools (#141) - New qa round (#147) - Advanced qa round (#149) - Homebrew tap - Final review round (#151) - Daemon healthy - Reasoning models (#158) - Lint errors (#160) - Review round (#168) - Release adjustments (#171) - Stabilize release ci fixtures - Stabilize release integration gate - Stabilize release verify gates - Stabilize release integration flows - Stabilize release verify gates - Stabilize main verify shutdown - Ignore stale acpmock cancel - Marketplace search focus and filtering (#193) - Website video - Workspace command select ### 📚 Documentation - Update agents.md - Update prd - Update skills - Update compozy tasks - Update compozy - Update compozy - Add new skills - Archive prd - Update prds - Update rfc - Update prds - Update prds - Add automation prd - Channels prd - Update prd - Update prd - New prds - Archive prds - Bridges adapters prd - Sandbox prd - Update - Archive prd - Update - Add new prd - New design - Update prd - Archive prds - Update prds - Tasks-ui prd tasks - Update prd - Update design docs - Agent capabilities prd - Improve site docs - Remove old design references - Udpate - Autonomous prd - Update skills - Blog design - Agent sould prd - Final qa plan - Update - Remove codex ledgers from gitignore - Remove not needed files - Udpate ledger - Update cy-codex-loop skill - Orchestration improves prd - Update prds - Orch improvs prd - Memv2 prd - Providers model prd - Update refacs prd - New design proposal - Update rules - Update skills - New blog posts (#173) - Format docs - Remove old design files - Remove old - Skeeper update ### 📦 Build System - Initial structure - Commitlint - Frontend base structure - Update vscode settings - Add subagents - Coderabbit - Prd and tooling - Bun lock - Lint tooling - Copy.md and tooling adjusts - Add repoclone rc - Upgrade skeeper to v0.2.0 - Update go.mod - Adopt task artifacts into skeeper - Sync codex plans with skeeper - Skeeper lock - Skeeper lock - New skills - Skeeper lock - Skeeper lock - Skeeper lock - Update deps and go - Regenerate daytona sidecar assets for go 1.26.3 - Fix cliff - Ignore docs on fmt - Build web assets before goreleaser - Extend release dry-run timeout ### 🔧 CI/CD - Lint errors - Fint release pr - Fix goreleaser - Fix release - Fix release process ### 🧪 Testing - Add e2e tests (#27) - Qa rounds (#78) - Improve test suite (#138) - Harden daemon-served restart reloads - Harden daemon-served readiness waits - Stabilize dashboard focus assertion - Stabilize release integration gates - Stabilize release e2e markers - Stabilize release e2e flows - Improve suite speed Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
## Release v0.0.2 This PR prepares the release of version v0.0.2. ### Changelog ## 0.0.2 - 2026-05-26 ### Other Changes - Lessons learned ### ♻️ Refactoring - Project structure (#7) - Kb improvements (#12) - Rename spaces to channels (#17) - Add extensions gaps (#21) - Improve tool calls ui (#22) - Remove web app header - Module improvements (#29) - Memory improvements (#35) - Storybook for web and ui (#38) - Enable AGH network by default for new installs (#57) - Hermes adjustments (#69) - Badges design (#84) - Storybook scenario and logos gallery - Migrate typescript tests (#114) - Internal go packages (#120) - Ui patterns (#127) - Improve e2e tests (#130) - Ui redesign - Workspace isolation across runtime surfaces (#145) - Prod ready applies (#162) - Tool card ui (#164) - Alpha on logo - Prod ready features (#167) - Thread sheet (#202) ### 🎉 Features - Implement config foundation packages - Implement sqlite store package - Add ACP client package - Add session lifecycle manager - Implement observe package - Add daemon composition root - Add uds api server - Implement cli package - Add http api server - Add system design - Add foundation types, schemas, and layout shell for web client - Add daemon health polling and agent sidebar systems for web client - Add session system CRUD, streaming core, and session store for web client - Add chat view, messages, and composer tests for web client - Add tool cards and renderers for web client - Add file-backed memory store core - Scaffold memory session seams - Add memory dream consolidation service - Wire memory assembler into daemon - Add memory api and cli - New skills system (#1) - Add workspace entity (#5) - Add new skill capabilities (#8) - Web ui v2 (#9) - Improve hooks system (#10) - Session resilience (#11) - Add extensability (#13) - Add automation (#16) - Add channels (#14) - Add network implementation (#15) - Add network, bridges and automations web pages (#18) - Ext registry (#20) - Add core tasks (#19) - Bridge adapters (#23) - Add site (#26) - Add ext refac and sandbox (#25) - Settings ui (#37) - Tasks ui (#36) - Harness improvements (#44) - Agent capabilities (#49) - Redesign ui (#48) - Unify capability (#53) - Redesign network workspace (#59) - Add task deletion and split session delete from stop (#58) - Session provider selection (#60) - Production grade adjustments (#66) - Autonomous system (#75) - Add agent session route (#80) - Tools registry (#85) - Agents soul (#88) - Add network threads (#105) - Orchestration improvements (#106) - Memory v2 (#108) - Agent categories (#113) - Providers model (#118) - Add canonical AGH bundled skill (#143) - Onboarding and improvements (#198) - Onboarding and improvements (#201) ### 🐛 Bug Fixes - Review round - Review rounds - Resolve memory extensibility review batch - Embed web into daemon - Defaults agents - Acp integration (#4) - Lint errors - Prd folder - Remove orphan web actions and dead surfaces (#55) - Qa testing and fixes (#73) - New review rounds (#82) - Security audit (#90) - Release qa round (#95) - Add missing tools (#141) - New qa round (#147) - Advanced qa round (#149) - Homebrew tap - Final review round (#151) - Daemon healthy - Reasoning models (#158) - Lint errors (#160) - Review round (#168) - Release adjustments (#171) - Stabilize release ci fixtures - Stabilize release integration gate - Stabilize release verify gates - Stabilize release integration flows - Stabilize release verify gates - Stabilize main verify shutdown - Ignore stale acpmock cancel - Marketplace search focus and filtering (#193) - Website video - Workspace command select ### 📚 Documentation - Update agents.md - Update prd - Update skills - Update compozy tasks - Update compozy - Update compozy - Add new skills - Archive prd - Update prds - Update rfc - Update prds - Update prds - Add automation prd - Channels prd - Update prd - Update prd - New prds - Archive prds - Bridges adapters prd - Sandbox prd - Update - Archive prd - Update - Add new prd - New design - Update prd - Archive prds - Update prds - Tasks-ui prd tasks - Update prd - Update design docs - Agent capabilities prd - Improve site docs - Remove old design references - Udpate - Autonomous prd - Update skills - Blog design - Agent sould prd - Final qa plan - Update - Remove codex ledgers from gitignore - Remove not needed files - Udpate ledger - Update cy-codex-loop skill - Orchestration improves prd - Update prds - Orch improvs prd - Memv2 prd - Providers model prd - Update refacs prd - New design proposal - Update rules - Update skills - New blog posts (#173) - Format docs - Remove old design files - Remove old - Skeeper update ### 📦 Build System - Initial structure - Commitlint - Frontend base structure - Update vscode settings - Add subagents - Coderabbit - Prd and tooling - Bun lock - Lint tooling - Copy.md and tooling adjusts - Add repoclone rc - Upgrade skeeper to v0.2.0 - Update go.mod - Adopt task artifacts into skeeper - Sync codex plans with skeeper - Skeeper lock - Skeeper lock - New skills - Skeeper lock - Skeeper lock - Skeeper lock - Update deps and go - Regenerate daytona sidecar assets for go 1.26.3 - Fix cliff - Ignore docs on fmt - Build web assets before goreleaser - Extend release dry-run timeout ### 🔧 CI/CD - Lint errors - Fint release pr - Fix goreleaser - Fix release - Fix release process - Fix release sync - Decouple release dry-run npm auth - Persist web assets git auth ### 🧪 Testing - Add e2e tests (#27) - Qa rounds (#78) - Improve test suite (#138) - Harden daemon-served restart reloads - Harden daemon-served readiness waits - Stabilize dashboard focus assertion - Stabilize release integration gates - Stabilize release e2e markers - Stabilize release e2e flows - Improve suite speed <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Chores** * Updated web assets dependency to a newer version for improved stability and performance. <!-- review_stack_entry_start --> [](https://app.coderabbit.ai/change-stack/compozy/agh/pull/211?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack) <!-- review_stack_entry_end --> <!-- end of auto-generated comment: release notes by coderabbit.ai --> Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
## Release v0.0.2 This PR prepares the release of version v0.0.2. ### Changelog ## 0.0.2 - 2026-05-27 ### Other Changes - Lessons learned ### ♻️ Refactoring - Project structure (#7) - Kb improvements (#12) - Rename spaces to channels (#17) - Add extensions gaps (#21) - Improve tool calls ui (#22) - Remove web app header - Module improvements (#29) - Memory improvements (#35) - Storybook for web and ui (#38) - Enable AGH network by default for new installs (#57) - Hermes adjustments (#69) - Badges design (#84) - Storybook scenario and logos gallery - Migrate typescript tests (#114) - Internal go packages (#120) - Ui patterns (#127) - Improve e2e tests (#130) - Ui redesign - Workspace isolation across runtime surfaces (#145) - Prod ready applies (#162) - Tool card ui (#164) - Alpha on logo - Prod ready features (#167) - Thread sheet (#202) ### 🎉 Features - Implement config foundation packages - Implement sqlite store package - Add ACP client package - Add session lifecycle manager - Implement observe package - Add daemon composition root - Add uds api server - Implement cli package - Add http api server - Add system design - Add foundation types, schemas, and layout shell for web client - Add daemon health polling and agent sidebar systems for web client - Add session system CRUD, streaming core, and session store for web client - Add chat view, messages, and composer tests for web client - Add tool cards and renderers for web client - Add file-backed memory store core - Scaffold memory session seams - Add memory dream consolidation service - Wire memory assembler into daemon - Add memory api and cli - New skills system (#1) - Add workspace entity (#5) - Add new skill capabilities (#8) - Web ui v2 (#9) - Improve hooks system (#10) - Session resilience (#11) - Add extensability (#13) - Add automation (#16) - Add channels (#14) - Add network implementation (#15) - Add network, bridges and automations web pages (#18) - Ext registry (#20) - Add core tasks (#19) - Bridge adapters (#23) - Add site (#26) - Add ext refac and sandbox (#25) - Settings ui (#37) - Tasks ui (#36) - Harness improvements (#44) - Agent capabilities (#49) - Redesign ui (#48) - Unify capability (#53) - Redesign network workspace (#59) - Add task deletion and split session delete from stop (#58) - Session provider selection (#60) - Production grade adjustments (#66) - Autonomous system (#75) - Add agent session route (#80) - Tools registry (#85) - Agents soul (#88) - Add network threads (#105) - Orchestration improvements (#106) - Memory v2 (#108) - Agent categories (#113) - Providers model (#118) - Add canonical AGH bundled skill (#143) - Onboarding and improvements (#198) - Onboarding and improvements (#201) ### 🐛 Bug Fixes - Review round - Review rounds - Resolve memory extensibility review batch - Embed web into daemon - Defaults agents - Acp integration (#4) - Lint errors - Prd folder - Remove orphan web actions and dead surfaces (#55) - Qa testing and fixes (#73) - New review rounds (#82) - Security audit (#90) - Release qa round (#95) - Add missing tools (#141) - New qa round (#147) - Advanced qa round (#149) - Homebrew tap - Final review round (#151) - Daemon healthy - Reasoning models (#158) - Lint errors (#160) - Review round (#168) - Release adjustments (#171) - Stabilize release ci fixtures - Stabilize release integration gate - Stabilize release verify gates - Stabilize release integration flows - Stabilize release verify gates - Stabilize main verify shutdown - Ignore stale acpmock cancel - Marketplace search focus and filtering (#193) - Website video - Workspace command select ### 📚 Documentation - Update agents.md - Update prd - Update skills - Update compozy tasks - Update compozy - Update compozy - Add new skills - Archive prd - Update prds - Update rfc - Update prds - Update prds - Add automation prd - Channels prd - Update prd - Update prd - New prds - Archive prds - Bridges adapters prd - Sandbox prd - Update - Archive prd - Update - Add new prd - New design - Update prd - Archive prds - Update prds - Tasks-ui prd tasks - Update prd - Update design docs - Agent capabilities prd - Improve site docs - Remove old design references - Udpate - Autonomous prd - Update skills - Blog design - Agent sould prd - Final qa plan - Update - Remove codex ledgers from gitignore - Remove not needed files - Udpate ledger - Update cy-codex-loop skill - Orchestration improves prd - Update prds - Orch improvs prd - Memv2 prd - Providers model prd - Update refacs prd - New design proposal - Update rules - Update skills - New blog posts (#173) - Format docs - Remove old design files - Remove old - Skeeper update ### 📦 Build System - Initial structure - Commitlint - Frontend base structure - Update vscode settings - Add subagents - Coderabbit - Prd and tooling - Bun lock - Lint tooling - Copy.md and tooling adjusts - Add repoclone rc - Upgrade skeeper to v0.2.0 - Update go.mod - Adopt task artifacts into skeeper - Sync codex plans with skeeper - Skeeper lock - Skeeper lock - New skills - Skeeper lock - Skeeper lock - Skeeper lock - Update deps and go - Regenerate daytona sidecar assets for go 1.26.3 - Fix cliff - Ignore docs on fmt - Build web assets before goreleaser - Extend release dry-run timeout - Fix release dry-run token contract ### 🔧 CI/CD - Lint errors - Fint release pr - Fix goreleaser - Fix release - Fix release process - Fix release sync - Decouple release dry-run npm auth - Persist web assets git auth - Require npm auth before release merge ### 🧪 Testing - Add e2e tests (#27) - Qa rounds (#78) - Improve test suite (#138) - Harden daemon-served restart reloads - Harden daemon-served readiness waits - Stabilize dashboard focus assertion - Stabilize release integration gates - Stabilize release e2e markers - Stabilize release e2e flows - Improve suite speed <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Chores** * Updated dependencies to latest versions. <!-- review_stack_entry_start --> [](https://app.coderabbit.ai/change-stack/compozy/agh/pull/214?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack) <!-- review_stack_entry_end --> <!-- end of auto-generated comment: release notes by coderabbit.ai --> Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Summary by CodeRabbit