Skip to content
This repository was archived by the owner on Aug 10, 2026. It is now read-only.

feat: tasks ui - #36

Merged
pedronauck merged 26 commits into
mainfrom
tasks-ui
Apr 18, 2026
Merged

pedronauck merged 26 commits into
mainfrom
tasks-ui

Conversation

@pedronauck

@pedronauck pedronauck commented Apr 18, 2026 •

Copy link
Copy Markdown
Member

Summary by CodeRabbit

  • New Features
    • Task timeline viewing and real-time SSE streaming (replay via Last-Event-ID)
    • Task run detail retrieval and publish-to-live endpoint
    • Task tree hierarchy navigation
    • Approval workflow (publish, approve, reject)
    • Triage actions (mark read, archive, dismiss) and inbox lanes (my work, approvals, failed, blocked, archived)
    • Task dashboard with aggregated metrics, cards and status breakdown
    • Enhanced task attributes and filters: priority, max attempts, approval policy/state, include_drafts, and free-text search

@pedronauck pedronauck self-assigned this Apr 18, 2026
@coderabbitai

coderabbitai Bot commented Apr 18, 2026 •

Copy link
Copy Markdown

Important

Review skipped

Review was skipped due to path filters

⛔ Files ignored due to path filters (1)
  • .codex/plans/2026-04-18-tasks-ui-redesign-plan.md is excluded by !**/*.md

CodeRabbit blocks several paths by default. You can override this behavior by explicitly including those paths in the path filters. For example, including **/dist/** will override the default block on the dist directory, by removing the pattern from both the lists.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 3ca918cc-d8aa-4928-876d-e15f93ba00e3

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Walkthrough

Adds 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

Cohort / File(s) Summary
API Response Contracts
internal/api/contract/responses.go
Added exported response wrappers: TaskTimelineResponse, TaskTreeResponse, TaskRunDetailResponse, TaskDashboardResponse, TaskInboxResponse, TaskTriageStateResponse.
API Payload Contracts
internal/api/contract/tasks.go
Expanded payloads (summary/detail/payloads) with priority/max_attempts/approval fields, dependency/run summaries, timeline/stream/tree/run/dashboard/inbox/triage types, and extended request/query contracts (list/timeline/stream/dashboard/inbox).
Contract Tests
internal/api/contract/tasks_test.go
Added JSON contract tests validating marshaled shapes for detail/run/tree/timeline/dashboard/inbox and UpdateTaskRequest.HasChanges behavior.
Conversions
internal/api/core/conversions.go
Added many converters mapping domain/observer task views to contract payloads (timeline, stream, tree, run detail/session/summary, dashboard, inbox, triage, dependency refs).
Interfaces
internal/api/core/interfaces.go
Extended Observer with QueryTaskDashboard/QueryTaskInbox; replaced explicit TaskService methods by embedding taskpkg.Manager.
Parsers
internal/api/core/parsers.go
Added parsing functions for task list/run/timeline/stream/dashboard/inbox queries and domain-query builders with validation and workspace binding.
Handlers & SSE
internal/api/core/tasks.go, internal/api/core/sse.go
Added handlers: publish, get run, timeline, stream (SSE), tree, dashboard, inbox, approve/reject/mark-read/archive/dismiss; added WriteTaskStreamEvent SSE helper; refactored query handling and response mapping.
Handler Tests & Surface Integration
internal/api/core/tasks_surface_*.go, internal/api/core/test_helpers_test.go
Added unit/integration tests for handler delegation, query parsing, SSE streaming, triage/approval delegation, and route registrations; test router fixtures updated.
HTTP/UDS Routes
internal/api/httpapi/routes.go, internal/api/udsapi/routes.go
Registered new HTTP and UDS endpoints for observe/dashboard/inbox, publish, timeline/stream/tree, approval/reject, triage, and task-run GET.
HTTP Integration & Parity Tests
internal/api/httpapi/*.go, internal/api/udsapi/*.go
Added end-to-end HTTP/UDS integration tests covering publish/run lifecycle, run detail, timeline/tree/stream, dashboard/inbox, approval/triage flows, and transport parity checks against OpenAPI spec.
OpenAPI Spec
internal/api/spec/spec.go, internal/api/spec/spec_test.go
Added response ContentType, after_sequence param helper, enums for task priority/approval/state/inbox lane, updated operation specs for new endpoints and tests verifying schemas/uniqueness.
Test Utilities
internal/api/testutil/apitest.go
Extended StubObserver and StubTaskManager with dashboard/inbox and publish/approve/reject/triage/timeline/stream/tree/run-detail hooks.
Task Domain: Live & Types
internal/task/live_types.go
Added LiveService interface and types for Timeline/Stream/Tree/RunDetail, timeline/stream/event record types, tree/run/session/operational summary, and runtime view reader interface.
Task Domain: Implementation
internal/task/live.go, internal/task/manager.go, internal/task/interfaces.go, internal/task/limits.go, internal/task/errors.go
Implemented Timeline/Stream/Tree/RunDetail and new lifecycle/triage mutations (Publish/Approve/Reject/MarkRead/Archive/Dismiss); added triage error sentinel and new mutable field constants and limits.
Observer / Aggregation
internal/observe/*.go
Added TaskDashboardQuery/View and TaskInboxQuery/View and implemented QueryTaskDashboard/QueryTaskInbox, dependency counting, dashboard aggregation, triage-aware inbox grouping, and related tests.
Database Schema & Migration
internal/store/globaldb/global_db.go, internal/store/globaldb/migrate_workspace.go
Added columns priority, max_attempts, approval_policy, approval_state with constraints and draft status; added task_triage_state table, event event_seq and indexes; migration logic to rebuild/backfill when needed.
Persistence APIs & Logic
internal/store/globaldb/global_db_task.go, internal/store/globaldb/global_db_task_aux.go
Persist/retrieve new task fields; added triage persistence (Get/Upsert/List), event-record retrieval (Get/List) with stable sequences, search filtering and activity-based ordering, and event sequence allocation on write.
Store Tests & Integration
internal/store/globaldb/*
Expanded tests for new fields, triage table round-trips, event sequence behavior, search/ordering, migration compatibility, and concurrency idempotency.
CLI & Daemon Adjustments
internal/cli/*, internal/daemon/*
Updated CLI renderers to accept pointer detail; updated daemon test doubles and helpers to support new observer/triage/event methods and pointer-based helpers.
Extension Host API
internal/extension/*
Added Host API method constants/param types for tasks timeline/tree/dashboard/inbox/runs-get; extended host observer/manager interfaces and handlers; added capability grants and tests.

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
Loading
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
Loading
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
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • feat: add core tasks #19: Modifies and extends task API surface and contract types; overlaps with added contract and core handler changes.
  • test: add e2e tests #27: Adds e2e test harness helpers and runtime tests that exercise the new task endpoints and flows introduced here.

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 | 🟠 Major

Move draft filtering ahead of the database limit.

The manager.ListTasks call on line 124 applies query.Limit at the SQL level (in GlobalDB.ListTasks, line 226), so draft rows returned from the database consume the page budget. The filterTaskListDrafts call on line 129 removes these drafts after the fact, leaving fewer results than requested.

For example, if query.Limit=10 and the database returns 3 drafts among 10 total rows, the client receives 7 published tasks instead of 10. This occurs whenever IncludeDrafts is false and no explicit Status filter is set.

Push the draft predicate into taskListDomainQuery / ListTasks, or overfetch until you have transportQuery.Limit visible (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 in findTaskRunInDetail to avoid panic-prone helper behavior.

Since the helper now accepts a pointer, a nil input will panic on detail.Runs. Returning false is 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 explicit t.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: Prefer t.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 taskListOrderByActivitySQL uses a correlated subquery that scans task_runs and task_events for each task row. For large datasets, this could become slow. Consider whether a denormalized last_activity_at column on tasks (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 ? and LOWER(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 existing testutil.EqualStringSlices.

This local equalStringSlices function duplicates testutil.EqualStringSlices which 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 into t.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 tests and 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/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 into Should... 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 tests and 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/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 around Should... 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 tests and 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/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: Prefer Should... 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 tests and 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/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, and ParseTaskInboxQuery normalize fields like scope, status, owner_kind, origin_kind, and lane, 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 into Should... 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 tests and 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/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 found mismatches 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 new rows.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 in t.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 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_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.go almost 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

Comment thread internal/api/contract/tasks.go
Comment thread internal/api/core/tasks_surface_internal_test.go Outdated
Comment thread internal/api/core/tasks_surface_internal_test.go Outdated
Comment thread internal/api/core/tasks_surface_internal_test.go Outdated
Comment thread internal/api/core/tasks_surface_test.go Outdated
Comment thread internal/store/globaldb/global_db_task_aux.go
Comment thread internal/store/globaldb/migrate_workspace.go
Comment thread internal/task/live.go
Comment thread internal/task/manager.go
Comment thread internal/task/manager.go Outdated
pedronauck and others added 25 commits April 18, 2026 00:46
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]>
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]>
pedronauck added a commit that referenced this pull request May 26, 2026
## 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>
This was referenced May 26, 2026
pedronauck added a commit that referenced this pull request May 26, 2026
## 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>
pedronauck added a commit that referenced this pull request May 26, 2026
## 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>
pedronauck added a commit that referenced this pull request May 27, 2026
## 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 -->

[![Review Change
Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](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>
pedronauck added a commit that referenced this pull request May 27, 2026
## 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 -->

[![Review Change
Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](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>
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant