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

feat: redesign network workspace - #59

Merged
pedronauck merged 7 commits into
mainfrom
feat/network-slack-redesign
Apr 24, 2026
Merged

pedronauck merged 7 commits into
mainfrom
feat/network-slack-redesign

Conversation

@pedronauck

@pedronauck pedronauck commented Apr 22, 2026 •

Copy link
Copy Markdown
Member

Summary

  • redesign /network into a Slack-style workspace shell with rooms, details tabs, kind filters, and compose flows for both channel and directed peer messaging
  • expand the persisted network contract to store durable channel metadata plus a richer timeline log for multiple message kinds, preview text, routing metadata, and peer-directed queries
  • regenerate the OpenAPI/web types and refresh the network mocks, stories, and tests around the new room-oriented model
  • harden ACP prompt-event ordering under race scheduling and relax the WhatsApp bridge test wait budget so the full verification suite stays stable

Backend

  • add network_channels persistence, registry wiring, and global-db CRUD alongside a richer network_timeline_log
  • persist all renderable network envelopes in the timeline pipeline instead of only say events
  • add GET /api/network/peers/:peer_id/messages, richer channel detail payloads, cursor-based before/after timeline queries, and required channel purpose metadata

Frontend

  • replace the old network inspector panels with NetworkWorkspaceShell and route-backed room selection state
  • support purpose-driven channel creation, starred rooms, unread markers, kind filtering, unified room details, and direct-message compose flows
  • remove obsolete network stories/panels and update MSW fixtures plus route/storybook tests for the new API surface

Verification

  • make verify

Summary by CodeRabbit

  • New Features

    • Unified workspace UI for channels and direct messages (NetworkWorkspaceShell), room-based navigation, message-kind filters, starred/read persistence, and richer room details
    • Direct peer messaging endpoint, peer-message history with cursor support, and client send-message flow
    • Channels now include purpose, creator, workspace, last-activity, preview, kind counts, and structured message bodies
  • Bug Fixes

    • Improved ordering/flush and bounded buffering for deferred tool-result events
    • Increased test wait timeout for flaky bridge tests
  • Documentation

    • Channel creation now requires a non-empty purpose and updated validation

@coderabbitai

coderabbitai Bot commented Apr 22, 2026 •

Copy link
Copy Markdown

Caution

Review failed

Pull request was closed or merged during review

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Adds durable network channel metadata and richer timeline messages (direction, correlation IDs, JSON body), a peer-directed messages endpoint and web peer flows, a new NetworkWorkspaceShell UI replacing legacy panels, DB migrations/tests, and ACP buffering for out-of-order ToolResult events until matching ToolCall or Done.

Changes

Cohort / File(s) Summary
ACP tool-result buffering
internal/acp/types.go, internal/acp/types_test.go
Introduce buffering for EventTypeToolResult until matching ToolCall or Done; dedupe by trimmed ToolCallID, cap pending queue, flush per-tool on tool_call and flush-all on done; update and add tests for ordering, dedupe, and bounded buffering.
Network API contract & responses
internal/api/contract/contract.go, internal/api/contract/responses.go
Add purpose and workspace/audit metadata, replace last_message_at → last_activity_at, expand channel/message payloads to include kind/direction/peer endpoints/trace/causation/preview/body, and add NetworkPeerMessagesResponse.
Core handlers, interfaces & tests
internal/api/core/... (network_details.go, network.go, interfaces.go, network_test.go, test_helpers_test.go)
Add NetworkPeerMessages handler/route, persist and prefer channel metadata for existence, bulk session enrichment, adjust message payload construction, extend NetworkStore interface with channel CRUD, and update tests/fixtures to new shapes.
Store types, DB, migrations & tests
internal/store/types.go, internal/store/store.go, internal/store/globaldb/... (global_db.go, global_db_network_channels.go, global_db_network_messages.go, *_test.go, migrate_workspace.go)
Add NetworkChannelEntry and NetworkChannelStore interface; replace network_message_log with network_timeline_log and add network_channels; expand persisted message schema (direction, peer_to, correlation IDs, preview, body), add cursor pagination, implement list/get/write/delete, update migrations and tests.
Network audit ingestion
internal/network/audit.go, internal/network/audit_test.go
Broaden timeline normalization beyond Say-only: clone raw body, compute preview, set Direction/PeerTo and correlation IDs, and conditionally populate intent/text for recognized bodies; update tests to cover multiple envelope kinds.
Routes, spec & test doubles
internal/api/httpapi/routes.go, internal/api/udsapi/routes.go, internal/api/spec/spec.go, internal/api/httpapi/handlers_test.go, internal/api/udsapi/handlers_test.go, internal/api/testutil/apitest.go
Register GET /api/network/peers/:peer_id/messages with OpenAPI pagination, extend StubNetworkStore with channel CRUD methods, and update route/handler tests.
Daemon, CLI & test infra
internal/daemon/daemon.go, internal/daemon/daemon_test.go, internal/cli/*, internal/testutil/e2e/runtime_harness_helpers_test.go
Embed NetworkChannelStore in registry interface; extend test registry stubs; include peer JoinedAt in CLI peers output; update e2e/test harness fixtures to new channel/message shapes.
Web adapters, hooks & query infra
web/src/systems/network/adapters/network-api.ts, web/src/systems/network/hooks/*, web/src/systems/network/lib/query-keys.ts, web/src/systems/network/lib/query-options.ts
Switch channel messages API to structured query (before/after/limit), add listNetworkPeerMessages and sendNetworkMessage, add hooks for peer messages and sending, and normalize query keys/options with default timeline limit.
Web types, formatters & route state
web/src/systems/network/types.ts, web/src/systems/network/lib/network-formatters.ts, web/src/hooks/routes/use-network-page.ts, web/src/routes/_app/network.tsx
Add peer/send/timeline types, kind filters and formatters, require channel purpose in drafts, convert page to route-driven search with persistence, and adapt ordering/search to last_activity_at/preview.
Web UI components & stories
Added: web/src/systems/network/components/network-workspace-shell.tsx; Removed: many web/src/systems/network/components/* and associated stories/tests
Introduce NetworkWorkspaceShell (sidebar, timeline, composer, details tabs) and remove legacy panels, their tests, and Storybook stories; add focused tests for the new shell.
Mocks, fixtures & MSW handlers
web/src/systems/network/mocks/fixtures.ts, web/src/systems/network/mocks/handlers.ts, web/src/systems/network/mocks/index.ts
Revise fixtures to new channel metadata and message schema; add networkPeerMessagesFixture, require purpose on channel creation mock, and add peer-messages MSW endpoint.
Extensions & misc tests/infra tweaks
extensions/bridges/*, internal/acp/*, web/*, assorted tests
Slack webhook handling now threads request context and improves path-conflict handling; ACP tests updated; minor test timeouts/accessibility tweaks; Vite build grouping; small provider test timeout change.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant ACP as ACP Manager
    participant Buffer as PendingResults (rgba(200,120,0,0.5))
    participant Emitter as EventEmitter (rgba(0,120,200,0.5))

    Client->>ACP: emit EventTypeToolResult(toolCallID="tool-1")
    ACP->>Buffer: deferToolResultLocked(toolResult)
    Note right of Buffer: pendingToolResults = ["tool-1"]

    Client->>ACP: emit EventTypeToolCall(toolCallID="tool-1")
    ACP->>ACP: markToolCallSeenLocked("tool-1")
    ACP->>Buffer: flushDeferredToolResultsForToolLocked("tool-1")
    Buffer->>Emitter: sendEventLocked(ToolResult(tool-1))
    ACP->>Emitter: sendEventLocked(ToolCall(tool-1))

    Client->>ACP: emit EventTypeDone
    ACP->>Buffer: flushDeferredToolResultsLocked()
    Buffer->>Emitter: send remaining ToolResult(s)
    ACP->>Emitter: sendEventLocked(Done)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~75 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.55% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: redesign network workspace' is fully related to the PR's main objective of redesigning the network UI into a Slack-style workspace shell with rooms, details tabs, and compose flows.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch

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: 18

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
internal/api/core/network_test.go (1)

703-721: ⚠️ Potential issue | 🟡 Minor

The new durable channel-metadata path is still unverified in the create-channel tests.

Both updated cases only add purpose to the request JSON. With testutil.StubNetworkStore{} / a stub that only implements ListNetworkMessagesFn, these tests still pass if the handler never calls WriteNetworkChannel, drops purpose, or fails to delete the row during rollback. Please capture the store interactions and assert Channel, WorkspaceID, and Purpose on success, plus cleanup on the readback-failure path.

As per coding guidelines, "Focus on critical paths: workflow execution, state management, error handling".

Also applies to: 1833-1888

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@internal/api/core/network_test.go` around lines 703 - 721, Update the tests
that set fixture.Handlers.NetworkStore = testutil.StubNetworkStore{} (and the
cases using performRequest and rolledBack) to replace the no-op stub with a
spy/mock implementation that records calls to WriteNetworkChannel and
DeleteNetworkChannel (or the rollback delete path) and implement
ListNetworkMessagesFn as needed; then assert that on successful create the
recorded Channel, WorkspaceID and Purpose match the request JSON, and on the
readback-failure path assert the store was instructed to delete the persisted
channel (cleanup) and that rolledBack contains the expected session ids; target
the test functions around the create-channel cases (the block using
performRequest and the related case at lines ~1833-1888) and ensure assertions
verify Channel, WorkspaceID, Purpose and delete/rollback calls.
internal/api/core/network_details.go (1)

445-460: 🛠️ Refactor suggestion | 🟠 Major

Wrap these upstream failures with operation context.

These branches return raw errors from ListPeers, ListAll, ListNetworkChannels, and ListNetworkMessages, so the handler loses the failing operation when the error bubbles up. Please wrap each return with a short label before propagating it.

As per coding guidelines, **/*.go: Use explicit error returns with wrapped context: fmt.Errorf("context: %w", err).

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@internal/api/core/network_details.go` around lines 445 - 460, The calls to
service.ListPeers, h.Sessions.ListAll, networkStore.ListNetworkChannels, and
networkStore.ListNetworkMessages return raw errors which should be wrapped with
operation context before returning; update each error return in the handler (the
block calling runtimePeers, sessions, channelMetadata, messages) to wrap the
underlying error using fmt.Errorf with a short label (e.g. fmt.Errorf("list
peers: %w", err), fmt.Errorf("list sessions: %w", err), fmt.Errorf("list network
channels: %w", err), fmt.Errorf("list network messages: %w", err)) so callers
can see which operation failed.
🧹 Nitpick comments (5)
internal/store/globaldb/global_db.go (1)

143-144: Use a composite index for workspace channel listings.

Two single-column indexes do not help much for the common WHERE workspace_id = ? ORDER BY updated_at DESC path. A composite index on workspace and activity time will serve the new room-list query much better.

Suggested index change
-`CREATE INDEX IF NOT EXISTS idx_network_channels_workspace ON network_channels(workspace_id);`,
-`CREATE INDEX IF NOT EXISTS idx_network_channels_updated_at ON network_channels(updated_at);`,
+`CREATE INDEX IF NOT EXISTS idx_network_channels_workspace_updated ON network_channels(workspace_id, updated_at DESC, channel);`,
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@internal/store/globaldb/global_db.go` around lines 143 - 144, Replace the two
single-column indexes idx_network_channels_workspace and
idx_network_channels_updated_at on the network_channels table with a composite
index for the common query path: create a single composite index (e.g.,
idx_network_channels_workspace_updated_at) on (workspace_id, updated_at) so
WHERE workspace_id = ? ORDER BY updated_at DESC can use the index; remove the
two existing single-column index statements and add the composite CREATE INDEX
statement where indexes are defined.
extensions/bridges/whatsapp/provider_test.go (1)

1804-1804: Keep the longer timeout local to the flaky path.

waitForCondition is shared across this file, so Line 1804 makes every broken condition take up to 5s to fail. If only one scenario needed extra slack, prefer a per-call timeout (or a dedicated helper) so unrelated regressions still fail fast.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@extensions/bridges/whatsapp/provider_test.go` at line 1804, The test
currently extends the shared waitForCondition timeout by setting deadline :=
time.Now().Add(5 * time.Second) globally which slows all failing cases; instead
keep the standard timeout as-is and apply the longer timeout only to the flaky
scenario by either calling a new helper like
waitForConditionWithTimeout(condition, 5*time.Second) or by passing a local
timeout parameter to waitForCondition for that single call (referencing
waitForCondition and the local deadline variable) so only the flaky path uses
the 5s slack.
internal/network/audit_test.go (1)

167-237: Run these subtests in parallel.

Each case builds its own writer/store and does not share state, so adding t.Parallel() inside the subtests would keep this aligned with the repo's default test pattern.

As per coding guidelines, "Add t.Parallel() to independent subtests in Go tests".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@internal/network/audit_test.go` around lines 167 - 237, The subtests ("Should
persist sent say...", "Should persist received say...", "Should persist direct
envelopes...") are independent and should be run in parallel: inside each t.Run
anonymous test function (the closures that call NewAuditWriter, use
recordingAuditStore, call writer.RecordSent/RecordReceived with
testSayAuditEnvelope/testAuditEnvelope), add a call to t.Parallel() as the first
statement in the closure so each subtest executes concurrently without shared
state.
internal/api/core/coverage_helpers_test.go (1)

354-398: Split the new helper assertions into named subtests.

The preview and payload cases are independent now, but they are still bundled into one large test body. Breaking them into t.Run("Should...") cases will make failures much easier to localize.

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/core/coverage_helpers_test.go` around lines 354 - 398, Split the
assertions into named t.Run subtests so each case is isolated: create subtests
like t.Run("Should preview text fallback", ...) to assert networkMessagePreview
with only Text, t.Run("Should preview previewText", ...) to assert
networkMessagePreview with PreviewText, t.Run("Should trim session IDs in
sessionInfoMapByID", ...) to assert sessionInfoMapByID behavior, and
t.Run("Should build payload from entry", ...) to assert
NetworkChannelMessagePayloadFromEntry checks (Direction, PeerFrom, DisplayName).
Move the relevant assertions for networkMessagePreview, sessionInfoMapByID, and
NetworkChannelMessagePayloadFromEntry into these separate t.Run blocks and keep
the same expectations and input values.
internal/api/core/interfaces.go (1)

106-114: Refresh the NetworkStore doc comment.

It now owns channel metadata CRUD as well, so "audit and timeline queries" undersells the actual contract and makes the interface easier to misuse.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@internal/api/core/interfaces.go` around lines 106 - 114, Update the
NetworkStore doc comment to accurately describe its responsibilities: state that
NetworkStore exposes persisted network audit, timeline, message queries and full
channel metadata CRUD (GetNetworkChannel, ListNetworkChannels,
WriteNetworkChannel, DeleteNetworkChannel) to the API layer, so callers
understand it manages both read queries (ListNetworkAudit, ListNetworkMessages)
and channel metadata lifecycle rather than only "audit and timeline queries."
🤖 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/acp/types_test.go`:
- Around line 89-138: Wrap each new top-level test body in a t.Run subtest using
the required "Should..." titles: inside
TestEmitPromptEventDefersToolResultUntilToolCall call t.Run("Should defer tool
results until the tool call", func(t *testing.T) { t.Parallel(); /* move the
current body here */ }) and inside
TestEmitPromptEventFlushesDeferredToolResultsBeforeDone call t.Run("Should flush
deferred tool results before done", func(t *testing.T) { t.Parallel(); /* move
the current body here */ }), preserving the use of AgentProcess, beginPrompt,
emitPromptEvent and reads from active.events unchanged; ensure t.Parallel() is
invoked inside the subtest functions (not only at the top) so the tests follow
the project's t.Run("Should...") subtest pattern.

In `@internal/acp/types.go`:
- Around line 395-396: pendingToolResults can grow unbounded because unique
ToolCallID values are appended until a matching tool call arrives; update the
buffering logic around pendingToolResults and seenToolCalls (and the code paths
that push into pendingToolResults, e.g., emitPromptEvent and the related handler
at the other location referenced) to dedupe by ToolCallID using seenToolCalls
(skip adding if already seen) and enforce a hard cap (e.g.,
maxPendingToolResults constant) so when the cap is reached you drop oldest
entries or refuse new ones; ensure the dedupe check uses the
AgentEvent.ToolCallID (or equivalent field) and that seenToolCalls is kept in
sync when removing entries.

In `@internal/api/core/coverage_helpers_test.go`:
- Around line 118-125: The tests call networkChannelExists(...) with nil for the
new persisted-channel parameter, leaving the durable/persisted-channel branch
untested; update coverage_helpers_test.go to add at least one assertion that
passes a non-nil persistedChannels value (e.g., a slice/map containing "match"
or "sessionChannel") into networkChannelExists and assert true, and add a
complementary case where persistedChannels does not include the channel and
assert false so the persisted-channel branch in networkChannelExists is covered.

In `@internal/api/core/network_details.go`:
- Around line 541-558: The issue is that applyNetworkChannelMetadata can advance
aggregate.lastActivityAt past the newest message timestamp, causing
aggregateMessageIsLatest to reject message previews; fix by tracking the latest
message timestamp separately (e.g., add a field like latestMessageAt or
lastMessageTimestamp to networkChannelAggregate), update
ensureNetworkChannelAggregate to initialize that field, update the loop where
messages are processed to set/advance aggregate.latestMessageAt based on
message.Timestamp (independent of lastActivityAt), and change
aggregateMessageIsLatest (or the preview check) to compare message.Timestamp
against aggregate.latestMessageAt instead of aggregate.lastActivityAt so
metadata updates no longer suppress previews.

In `@internal/store/globaldb/global_db_network_channels_test.go`:
- Around line 81-94: The test assumes a stable row order and a working LIMIT,
but the store query in global_db_network_channels.go (the ListNetworkChannels
implementation) currently omits ORDER BY and LIMIT; update the store code to
apply a deterministic ORDER BY (e.g., by Channel or created_at) and honor Limit
from NetworkChannelQuery inside ListNetworkChannels, or alternatively change the
test in global_db_network_channels_test.go to assert the returned channels as an
unordered set (compare entries' Channel values regardless of order) and verify
the length respects Limit; reference ListNetworkChannels, NetworkChannelQuery,
entries, and global_db_network_channels.go when making the change.

In `@internal/store/globaldb/global_db_network_channels.go`:
- Around line 14-25: Trim the channel string before validating or persisting it
in WriteNetworkChannel: call strings.TrimSpace on entry.Channel at the top of
WriteNetworkChannel (before entry.Validate() and before setting
CreatedAt/UpdatedAt) so the stored key matches the trimmed lookup key; do the
same canonicalization in the related functions GetNetworkChannel and
DeleteNetworkChannel (and any other write/update handlers in this file
referenced in the diff) to ensure all CRUD operations use the same trimmed
channel key.

In `@internal/store/globaldb/global_db_network_messages_test.go`:
- Around line 127-206: TestGlobalDBListNetworkMessagesSupportsMessageIDCursors
currently only uses strictly increasing Timestamp values; add at least one pair
of entries that share the exact same Timestamp but have different MessageID
values (e.g., "msg-2a" and "msg-2b") and write them via
globalDB.WriteNetworkMessage so the test covers tie-break ordering; then update
the subsequent ListNetworkMessages queries and assertions (the before and after
checks) to account for the deterministic (timestamp, message_id) ordering
expected by ListNetworkMessages so the test verifies no skips/duplicates when
timestamps are equal.

In `@internal/store/globaldb/global_db_network_messages.go`:
- Around line 160-174: When using before/after cursors in
buildNetworkMessageListQuery, resolve and validate the cursor under the same
query scope: call lookupNetworkMessageCursor and then verify the resolved
cursor's channel/peer/timeline fields match the current query filters (e.g.,
channel_id, peer_pubkey, timeline filters); if they don't match, return an
explicit error instead of using the cursor. Alternatively, extend
lookupNetworkMessageCursor to accept the same filters and have it fail when the
cursor belongs to a different room/timeline. Apply this validation in both the
before and after branches inside buildNetworkMessageListQuery (the branches that
call lookupNetworkMessageCursor).

In `@internal/store/globaldb/global_db.go`:
- Around line 135-142: The network_channels table currently defines workspace_id
as free text which can leave orphaned rows; modify the CREATE TABLE for
network_channels to make workspace_id a proper foreign key referencing
workspaces(id) with ON DELETE CASCADE (i.e., add a FOREIGN KEY (workspace_id)
REFERENCES workspaces(id) ON DELETE CASCADE and ensure the column types match
the referenced id), and update any migration/initializer that uses the
network_channels schema so the constraint is applied for new deployments (or
provide an ALTER TABLE migration to add the foreign key for existing DBs).

In `@web/src/hooks/routes/use-network-page.ts`:
- Around line 522-573: activeRoomItem is being derived from
filteredChannels/filteredPeers so typing a sidebar query can change/clear the
selected room; instead compute the active room from the full room set
(allChannels/allPeers) and only use filteredChannels/filteredPeers for what the
sidebar renders. Concretely, build unfiltered room arrays by mapping allChannels
and allPeers with makeChannelRoomItem/makePeerRoomItem (respecting
starredChannels, readMarkers, selectedRoomKey) and use those unfiltered arrays
to compute activeRoomItem, while leaving
starredChannelRooms/channelRooms/directRooms (used for rendering) to be created
from filteredChannels/filteredPeers; update the activeRoomItem useMemo
dependencies to reference the new unfiltered arrays (and apply the same fix
around the similar block at lines 575-593).
- Around line 462-475: validateNetworkSearch currently can return both channel
and peer which lets a stale peer param suppress a valid channel selection;
update validateNetworkSearch to make channel and peer mutually exclusive by
preferring channel when both are present: compute normalizedChannel =
normalizeSearchValue(search.channel) and normalizedPeer =
normalizeSearchValue(search.peer), then if normalizedChannel is truthy return
channel=normalizedChannel and peer=undefined, else return peer=normalizedPeer
and channel=undefined (keeping existing handling for kind/details). Apply the
same change to the other identical validation block referenced in the diff so
only one of channel/peer is ever returned.

In `@web/src/systems/network/components/network-create-channel-dialog.tsx`:
- Around line 90-102: Add the required attribute (and aria-required="true") to
the Textarea control so assistive tech and native form validation recognize the
field as mandatory; update the Textarea with id "network-channel-purpose" (the
control using value={draft.purpose} and onChange={event =>
onPurposeChange(event.target.value)}) to include required and
aria-required="true" attributes.

In `@web/src/systems/network/components/network-workspace-shell.tsx`:
- Around line 565-569: The StatusDot in network-workspace-shell.tsx is
hard-coded to tone="success"; change it to use the mapping function instead
(call getNetworkStatusTone with the current status value, e.g.
getNetworkStatusTone(status.status)) so the dot reflects
"running"/"online"/"degraded"/"stopped" correctly; ensure getNetworkStatusTone
is imported/available in the file and remove the literal "success" prop.
- Around line 332-339: The badges are using readStringList(peerCard,
"capabilities") but peerCard.capabilities is an array of capability objects, so
the branch never renders; change the code to read the actual object list (e.g.,
use readList(peerCard, "capabilities") or access peerCard.capabilities) and map
each capability object to its display string (for example capability.name or
capability.type) before rendering MonoBadge; update the map callback that
currently uses capabilityName to accept the object (e.g., capability) and render
MonoBadge key and contents from the appropriate property.
- Around line 174-246: The row's onKeyDown handler (the anonymous handler that
checks event.key === "Enter" || " ") currently catches keyboard events for the
whole item; add an onKeyDown on the star button (the button that renders
Sparkles and calls onToggleStar) that stops propagation so keyboard presses on
the star don't bubble to the row. Concretely, in the star button element add an
onKeyDown handler that calls event.stopPropagation() (and for safety you can
check keys "Enter" and " " before stopping) so keyboard activation still
triggers the button but won't trigger the row's onSelect.

In `@web/src/systems/network/lib/query-options.ts`:
- Around line 49-57: Normalize the timeline query object once inside
networkChannelMessagesOptions: create a single normalizedQuery that applies the
default (DEFAULT_TIMELINE_LIMIT) to undefined/missing fields, then use that
normalizedQuery both when building the cache key via
networkKeys.channelMessages(channel, normalizedQuery) and when calling
listNetworkChannelMessages(channel, normalizedQuery, signal). Do the same
refactor for the analogous function around the later block (the other
*MessagesOptions function) so keys and fetch payloads match exactly.

In `@web/src/systems/network/mocks/fixtures.ts`:
- Around line 191-243: The fixture networkChannelMessagesFixture contains
entries whose fields don't match the server mapper: update each message so only
local/sent messages include session_id and their display_name uses the session
name (not the peer card name) when a session is known, and ensure received
messages (direction: "received") do NOT carry session_id; adjust the three
entries (message_id "msg_storybook_1", "msg_storybook_2", "msg_storybook_3")
accordingly and apply the same corrections to the later fixtures in the 245-276
range so the NetworkChannelMessage shape matches
NetworkChannelMessagePayloadFromEntry and the server-mapped payloads the app
expects.

In `@web/src/systems/network/mocks/handlers.ts`:
- Around line 70-82: The handler for GET "/api/network/peers/:peer_id/messages"
only remaps peer_from causing inconsistent DM timelines; update the mapping to
remap both peer_from and peer_to when swapping fixture peer IDs so neither side
keeps the original networkPeerFixture.peer_id. In the http.get handler (callback
using params) change the networkPeerMessagesFixture.map callback to replace
occurrences of networkPeerFixture.peer_id with the runtime peerId for both
message.peer_from and message.peer_to (leave other fields unchanged), and apply
the same change to the other conversation endpoint handler that performs the
same fixture-id swap.

---

Outside diff comments:
In `@internal/api/core/network_details.go`:
- Around line 445-460: The calls to service.ListPeers, h.Sessions.ListAll,
networkStore.ListNetworkChannels, and networkStore.ListNetworkMessages return
raw errors which should be wrapped with operation context before returning;
update each error return in the handler (the block calling runtimePeers,
sessions, channelMetadata, messages) to wrap the underlying error using
fmt.Errorf with a short label (e.g. fmt.Errorf("list peers: %w", err),
fmt.Errorf("list sessions: %w", err), fmt.Errorf("list network channels: %w",
err), fmt.Errorf("list network messages: %w", err)) so callers can see which
operation failed.

In `@internal/api/core/network_test.go`:
- Around line 703-721: Update the tests that set fixture.Handlers.NetworkStore =
testutil.StubNetworkStore{} (and the cases using performRequest and rolledBack)
to replace the no-op stub with a spy/mock implementation that records calls to
WriteNetworkChannel and DeleteNetworkChannel (or the rollback delete path) and
implement ListNetworkMessagesFn as needed; then assert that on successful create
the recorded Channel, WorkspaceID and Purpose match the request JSON, and on the
readback-failure path assert the store was instructed to delete the persisted
channel (cleanup) and that rolledBack contains the expected session ids; target
the test functions around the create-channel cases (the block using
performRequest and the related case at lines ~1833-1888) and ensure assertions
verify Channel, WorkspaceID, Purpose and delete/rollback calls.

---

Nitpick comments:
In `@extensions/bridges/whatsapp/provider_test.go`:
- Line 1804: The test currently extends the shared waitForCondition timeout by
setting deadline := time.Now().Add(5 * time.Second) globally which slows all
failing cases; instead keep the standard timeout as-is and apply the longer
timeout only to the flaky scenario by either calling a new helper like
waitForConditionWithTimeout(condition, 5*time.Second) or by passing a local
timeout parameter to waitForCondition for that single call (referencing
waitForCondition and the local deadline variable) so only the flaky path uses
the 5s slack.

In `@internal/api/core/coverage_helpers_test.go`:
- Around line 354-398: Split the assertions into named t.Run subtests so each
case is isolated: create subtests like t.Run("Should preview text fallback",
...) to assert networkMessagePreview with only Text, t.Run("Should preview
previewText", ...) to assert networkMessagePreview with PreviewText,
t.Run("Should trim session IDs in sessionInfoMapByID", ...) to assert
sessionInfoMapByID behavior, and t.Run("Should build payload from entry", ...)
to assert NetworkChannelMessagePayloadFromEntry checks (Direction, PeerFrom,
DisplayName). Move the relevant assertions for networkMessagePreview,
sessionInfoMapByID, and NetworkChannelMessagePayloadFromEntry into these
separate t.Run blocks and keep the same expectations and input values.

In `@internal/api/core/interfaces.go`:
- Around line 106-114: Update the NetworkStore doc comment to accurately
describe its responsibilities: state that NetworkStore exposes persisted network
audit, timeline, message queries and full channel metadata CRUD
(GetNetworkChannel, ListNetworkChannels, WriteNetworkChannel,
DeleteNetworkChannel) to the API layer, so callers understand it manages both
read queries (ListNetworkAudit, ListNetworkMessages) and channel metadata
lifecycle rather than only "audit and timeline queries."

In `@internal/network/audit_test.go`:
- Around line 167-237: The subtests ("Should persist sent say...", "Should
persist received say...", "Should persist direct envelopes...") are independent
and should be run in parallel: inside each t.Run anonymous test function (the
closures that call NewAuditWriter, use recordingAuditStore, call
writer.RecordSent/RecordReceived with testSayAuditEnvelope/testAuditEnvelope),
add a call to t.Parallel() as the first statement in the closure so each subtest
executes concurrently without shared state.

In `@internal/store/globaldb/global_db.go`:
- Around line 143-144: Replace the two single-column indexes
idx_network_channels_workspace and idx_network_channels_updated_at on the
network_channels table with a composite index for the common query path: create
a single composite index (e.g., idx_network_channels_workspace_updated_at) on
(workspace_id, updated_at) so WHERE workspace_id = ? ORDER BY updated_at DESC
can use the index; remove the two existing single-column index statements and
add the composite CREATE INDEX statement where indexes are defined.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 3a695f69-9192-4fa7-891e-9000f459b9ed

📥 Commits

Reviewing files that changed from the base of the PR and between 33f4ee4 and 9450141.

⛔ Files ignored due to path filters (2)
  • openapi/agh.json is excluded by !**/*.json
  • web/src/generated/agh-openapi.d.ts is excluded by !**/generated/**
📒 Files selected for processing (62)
  • extensions/bridges/whatsapp/provider_test.go
  • internal/acp/types.go
  • internal/acp/types_test.go
  • internal/api/contract/contract.go
  • internal/api/contract/responses.go
  • internal/api/core/coverage_helpers_test.go
  • internal/api/core/interfaces.go
  • internal/api/core/network_details.go
  • internal/api/core/network_test.go
  • internal/api/httpapi/handlers_test.go
  • internal/api/httpapi/routes.go
  • internal/api/spec/spec.go
  • internal/api/testutil/apitest.go
  • internal/api/udsapi/handlers_test.go
  • internal/api/udsapi/routes.go
  • internal/daemon/daemon.go
  • internal/daemon/daemon_test.go
  • internal/network/audit.go
  • internal/network/audit_test.go
  • internal/store/globaldb/global_db.go
  • internal/store/globaldb/global_db_network_channels.go
  • internal/store/globaldb/global_db_network_channels_test.go
  • internal/store/globaldb/global_db_network_messages.go
  • internal/store/globaldb/global_db_network_messages_test.go
  • internal/store/store.go
  • internal/store/store_helpers_test.go
  • internal/store/types.go
  • internal/testutil/e2e/runtime_harness_helpers_test.go
  • web/src/hooks/routes/use-network-page.ts
  • web/src/routes/_app/-network.test.tsx
  • web/src/routes/_app/network.tsx
  • web/src/routes/_app/stories/-network.stories.tsx
  • web/src/storybook/web-storybook-stories-and-fixtures.test.tsx
  • web/src/systems/network/adapters/network-api.ts
  • web/src/systems/network/components/network-channel-detail-panel.test.tsx
  • web/src/systems/network/components/network-channel-detail-panel.tsx
  • web/src/systems/network/components/network-channels-list-panel.test.tsx
  • web/src/systems/network/components/network-channels-list-panel.tsx
  • web/src/systems/network/components/network-create-channel-dialog.test.tsx
  • web/src/systems/network/components/network-create-channel-dialog.tsx
  • web/src/systems/network/components/network-empty-state.tsx
  • web/src/systems/network/components/network-peer-detail-panel.test.tsx
  • web/src/systems/network/components/network-peer-detail-panel.tsx
  • web/src/systems/network/components/network-peers-list-panel.test.tsx
  • web/src/systems/network/components/network-peers-list-panel.tsx
  • web/src/systems/network/components/network-workspace-shell.tsx
  • web/src/systems/network/components/stories/network-channel-detail-panel.stories.tsx
  • web/src/systems/network/components/stories/network-channels-list-panel.stories.tsx
  • web/src/systems/network/components/stories/network-create-channel-dialog.stories.tsx
  • web/src/systems/network/components/stories/network-empty-state.stories.tsx
  • web/src/systems/network/components/stories/network-peer-detail-panel.stories.tsx
  • web/src/systems/network/components/stories/network-peers-list-panel.stories.tsx
  • web/src/systems/network/hooks/use-network-actions.ts
  • web/src/systems/network/hooks/use-network.ts
  • web/src/systems/network/index.ts
  • web/src/systems/network/lib/network-formatters.ts
  • web/src/systems/network/lib/query-keys.ts
  • web/src/systems/network/lib/query-options.ts
  • web/src/systems/network/mocks/fixtures.ts
  • web/src/systems/network/mocks/handlers.ts
  • web/src/systems/network/mocks/index.ts
  • web/src/systems/network/types.ts
💤 Files with no reviewable changes (15)
  • web/src/systems/network/components/stories/network-empty-state.stories.tsx
  • web/src/systems/network/components/network-channels-list-panel.test.tsx
  • web/src/systems/network/components/network-channel-detail-panel.test.tsx
  • web/src/systems/network/components/network-empty-state.tsx
  • web/src/systems/network/components/stories/network-channel-detail-panel.stories.tsx
  • web/src/systems/network/components/network-peers-list-panel.test.tsx
  • web/src/systems/network/components/stories/network-channels-list-panel.stories.tsx
  • web/src/systems/network/components/stories/network-peers-list-panel.stories.tsx
  • web/src/systems/network/components/network-channels-list-panel.tsx
  • web/src/systems/network/components/network-peers-list-panel.tsx
  • web/src/systems/network/components/network-channel-detail-panel.tsx
  • web/src/routes/_app/stories/-network.stories.tsx
  • web/src/systems/network/components/network-peer-detail-panel.test.tsx
  • web/src/systems/network/components/stories/network-peer-detail-panel.stories.tsx
  • web/src/systems/network/components/network-peer-detail-panel.tsx

Comment thread internal/acp/types_test.go
Comment thread internal/acp/types.go Outdated
Comment thread internal/api/core/coverage_helpers_test.go Outdated
Comment thread internal/api/core/network_details.go
Comment thread internal/store/globaldb/global_db_network_channels_test.go
Comment thread web/src/systems/network/components/network-workspace-shell.tsx
Comment thread web/src/systems/network/components/network-workspace-shell.tsx
Comment thread web/src/systems/network/lib/query-options.ts Outdated
Comment thread web/src/systems/network/mocks/fixtures.ts
Comment thread web/src/systems/network/mocks/handlers.ts

@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: 2

🧹 Nitpick comments (3)
internal/store/globaldb/global_db_network_messages_test.go (1)

128-238: Cover cursor tie-breaks with equal timestamps.

The cursor pagination test only exercises strictly increasing timestamp values. To fully validate the (timestamp, message_id) ordering contract, add at least one pair of entries with the same timestamp but different message IDs (e.g., msg-2a and msg-2b at recordedAt.Add(time.Minute)). This ensures entries sharing a timestamp aren't skipped or duplicated during pagination.

💡 Suggested test data addition
 		{
 			MessageID:   "msg-2",
 			Channel:     "builders",
 			Direction:   "sent",
 			PeerFrom:    "peer-a",
 			Kind:        "say",
 			PreviewText: "two",
 			Body:        []byte(`{"text":"two"}`),
 			Timestamp:   recordedAt.Add(time.Minute),
 		},
+		{
+			MessageID:   "msg-2b",
+			Channel:     "builders",
+			Direction:   "sent",
+			PeerFrom:    "peer-a",
+			Kind:        "say",
+			PreviewText: "two-b",
+			Body:        []byte(`{"text":"two-b"}`),
+			Timestamp:   recordedAt.Add(time.Minute), // Same timestamp as msg-2
+		},

Then update assertions to verify both msg-2 and msg-2b appear in correct order during pagination.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@internal/store/globaldb/global_db_network_messages_test.go` around lines 128
- 238, TestGlobalDBListNetworkMessagesSupportsMessageIDCursors currently only
uses strictly increasing timestamps; add a pair of entries with identical
Timestamp (e.g., insert "msg-2a" and "msg-2b" both at
recordedAt.Add(time.Minute)) into the entries slice so the test exercises the
(Timestamp, MessageID) tie-break ordering, then update the ListNetworkMessages
assertions (the "before" and "after" checks) to expect both message IDs in the
correct deterministic order; refer to the entries variable and the test function
TestGlobalDBListNetworkMessagesSupportsMessageIDCursors when making the change.
web/src/systems/network/lib/network-formatters.test.ts (1)

99-103: Consider expanding test coverage for formatNetworkKindLabel.

The current test only validates one kind ("capability"). Consider adding tests for:

  • Other valid kinds (say, direct, trace, etc.)
  • Unknown/unrecognized kind strings (should return the original string per implementation)
🧪 Suggested additional test cases
 describe("formatNetworkKindLabel", () => {
   it("Should keep capability timeline events aligned with the API kind name", () => {
     expect(formatNetworkKindLabel("capability")).toBe("capability");
   });
+
+  it("Should return the label for all known kinds", () => {
+    expect(formatNetworkKindLabel("say")).toBe("say");
+    expect(formatNetworkKindLabel("direct")).toBe("direct");
+    expect(formatNetworkKindLabel("trace")).toBe("trace");
+  });
+
+  it("Should return unknown kinds unchanged", () => {
+    expect(formatNetworkKindLabel("unknown-kind")).toBe("unknown-kind");
+  });
 });
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@web/src/systems/network/lib/network-formatters.test.ts` around lines 99 -
103, Add more unit tests for formatNetworkKindLabel: expand the test suite in
network-formatters.test.ts to include assertions for other known kinds (e.g.,
"say", "direct", "trace", etc.) verifying they map to the expected labels, and
add at least one test that passes an unknown/unrecognized string (e.g.,
"foo-bar") and asserts the function returns the original input. Locate the tests
under the describe("formatNetworkKindLabel", ...) block and add these cases
using the same expect(...).toBe(...) pattern so behavior for valid kinds and
unknown kinds is covered.
web/src/systems/network/lib/network-formatters.ts (1)

286-291: Redundant === true comparisons.

The .includes() method already returns a boolean, so the explicit === true is unnecessary. However, this is a minor stylistic preference.

♻️ Optional simplification
   return (
     channel.channel.toLowerCase().includes(normalized) ||
-    channel.purpose?.toLowerCase().includes(normalized) === true ||
-    channel.last_message_preview?.toLowerCase().includes(normalized) === true
+    channel.purpose?.toLowerCase().includes(normalized) ||
+    channel.last_message_preview?.toLowerCase().includes(normalized)
   );
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@web/src/systems/network/lib/network-formatters.ts` around lines 286 - 291,
The return expression in network-formatters.ts is using redundant "=== true"
comparisons; update the boolean checks for channel.purpose and
channel.last_message_preview so they just use the result of .includes(...) (keep
the optional chaining and .toLowerCase() calls), e.g., replace
"channel.purpose?.toLowerCase().includes(normalized) === true" and
"channel.last_message_preview?.toLowerCase().includes(normalized) === true" with
"channel.purpose?.toLowerCase().includes(normalized)" and
"channel.last_message_preview?.toLowerCase().includes(normalized)" respectively
to simplify the logic while preserving behavior for
channel.channel.toLowerCase().includes(normalized).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@web/src/systems/network/components/network-workspace-shell.tsx`:
- Around line 284-291: The list rendering in network-workspace-shell.tsx uses
the step string as the React key (inside the map over readStringList(capability,
"execution_outline")), which can produce duplicate keys when steps repeat;
update the map to use a stable per-item index-based key (e.g.,
key={`${index}-${step}` or just key={index}) to guarantee uniqueness and avoid
React warnings and DOM reuse issues for identical step text.
- Around line 493-495: The key generation in the fields.map callback uses a
composite `${field.label}-${field.value}` which can collide; update the JSX in
network-workspace-shell.tsx where fields.map is used (the map callback creating
the <div key=...>) to use a stable unique identifier instead—preferably a
dedicated property like field.id if available, otherwise fall back to the
iteration index (e.g., use field.id or index) so keys are guaranteed unique and
React list reconciliation remains correct.

---

Nitpick comments:
In `@internal/store/globaldb/global_db_network_messages_test.go`:
- Around line 128-238: TestGlobalDBListNetworkMessagesSupportsMessageIDCursors
currently only uses strictly increasing timestamps; add a pair of entries with
identical Timestamp (e.g., insert "msg-2a" and "msg-2b" both at
recordedAt.Add(time.Minute)) into the entries slice so the test exercises the
(Timestamp, MessageID) tie-break ordering, then update the ListNetworkMessages
assertions (the "before" and "after" checks) to expect both message IDs in the
correct deterministic order; refer to the entries variable and the test function
TestGlobalDBListNetworkMessagesSupportsMessageIDCursors when making the change.

In `@web/src/systems/network/lib/network-formatters.test.ts`:
- Around line 99-103: Add more unit tests for formatNetworkKindLabel: expand the
test suite in network-formatters.test.ts to include assertions for other known
kinds (e.g., "say", "direct", "trace", etc.) verifying they map to the expected
labels, and add at least one test that passes an unknown/unrecognized string
(e.g., "foo-bar") and asserts the function returns the original input. Locate
the tests under the describe("formatNetworkKindLabel", ...) block and add these
cases using the same expect(...).toBe(...) pattern so behavior for valid kinds
and unknown kinds is covered.

In `@web/src/systems/network/lib/network-formatters.ts`:
- Around line 286-291: The return expression in network-formatters.ts is using
redundant "=== true" comparisons; update the boolean checks for channel.purpose
and channel.last_message_preview so they just use the result of .includes(...)
(keep the optional chaining and .toLowerCase() calls), e.g., replace
"channel.purpose?.toLowerCase().includes(normalized) === true" and
"channel.last_message_preview?.toLowerCase().includes(normalized) === true" with
"channel.purpose?.toLowerCase().includes(normalized)" and
"channel.last_message_preview?.toLowerCase().includes(normalized)" respectively
to simplify the logic while preserving behavior for
channel.channel.toLowerCase().includes(normalized).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 9d97be6f-8bf9-4c45-b3d5-58e5cbf44ae1

📥 Commits

Reviewing files that changed from the base of the PR and between 9450141 and 8d594a1.

⛔ Files ignored due to path filters (53)
  • .compozy/tasks/unified-capabilities/qa/issues/BUG-004.md is excluded by !**/*.md
  • .compozy/tasks/unified-capabilities/qa/issues/BUG-005.md is excluded by !**/*.md
  • .compozy/tasks/unified-capabilities/qa/issues/BUG-006.md is excluded by !**/*.md
  • .compozy/tasks/unified-capabilities/qa/screenshots/network-operator-reloaded.png is excluded by !**/*.png
  • .compozy/tasks/unified-capabilities/qa/screenshots/tc-func-001-settings-shell-navigation.png is excluded by !**/*.png
  • .compozy/tasks/unified-capabilities/qa/screenshots/tc-func-002-general-restart-polling.png is excluded by !**/*.png
  • .compozy/tasks/unified-capabilities/qa/screenshots/tc-func-005-skills-applied-now-vs-restart.png is excluded by !**/*.png
  • .compozy/tasks/unified-capabilities/qa/screenshots/tc-func-008-providers-crud-and-builtin-fallback.png is excluded by !**/*.png
  • .compozy/tasks/unified-capabilities/qa/screenshots/tc-func-012-hooks-extensions-hybrid.png is excluded by !**/*.png
  • .compozy/tasks/unified-capabilities/qa/screenshots/tc-int-011-mcp-workspace-scope.png is excluded by !**/*.png
  • .compozy/tasks/unified-capabilities/qa/screenshots/tc-int-016-general-restart-ready.png is excluded by !**/*.png
  • .compozy/tasks/unified-capabilities/qa/test-cases/SMOKE-001.md is excluded by !**/*.md
  • .compozy/tasks/unified-capabilities/qa/test-cases/SMOKE-002.md is excluded by !**/*.md
  • .compozy/tasks/unified-capabilities/qa/test-cases/SMOKE-003.md is excluded by !**/*.md
  • .compozy/tasks/unified-capabilities/qa/test-cases/TC-FUNC-001.md is excluded by !**/*.md
  • .compozy/tasks/unified-capabilities/qa/test-cases/TC-FUNC-002.md is excluded by !**/*.md
  • .compozy/tasks/unified-capabilities/qa/test-cases/TC-FUNC-003.md is excluded by !**/*.md
  • .compozy/tasks/unified-capabilities/qa/test-cases/TC-FUNC-004.md is excluded by !**/*.md
  • .compozy/tasks/unified-capabilities/qa/test-cases/TC-FUNC-005.md is excluded by !**/*.md
  • .compozy/tasks/unified-capabilities/qa/test-cases/TC-FUNC-006.md is excluded by !**/*.md
  • .compozy/tasks/unified-capabilities/qa/test-cases/TC-FUNC-007.md is excluded by !**/*.md
  • .compozy/tasks/unified-capabilities/qa/test-cases/TC-FUNC-008.md is excluded by !**/*.md
  • .compozy/tasks/unified-capabilities/qa/test-cases/TC-FUNC-009.md is excluded by !**/*.md
  • .compozy/tasks/unified-capabilities/qa/test-cases/TC-FUNC-010.md is excluded by !**/*.md
  • .compozy/tasks/unified-capabilities/qa/test-cases/TC-FUNC-011.md is excluded by !**/*.md
  • .compozy/tasks/unified-capabilities/qa/test-cases/TC-INT-005.md is excluded by !**/*.md
  • .compozy/tasks/unified-capabilities/qa/test-cases/TC-INT-006.md is excluded by !**/*.md
  • .compozy/tasks/unified-capabilities/qa/test-cases/TC-INT-007.md is excluded by !**/*.md
  • .compozy/tasks/unified-capabilities/qa/test-cases/TC-INT-101.md is excluded by !**/*.md
  • .compozy/tasks/unified-capabilities/qa/test-cases/TC-INT-102.md is excluded by !**/*.md
  • .compozy/tasks/unified-capabilities/qa/test-cases/TC-INT-103.md is excluded by !**/*.md
  • .compozy/tasks/unified-capabilities/qa/test-cases/TC-INT-104.md is excluded by !**/*.md
  • .compozy/tasks/unified-capabilities/qa/test-cases/TC-PERF-001.md is excluded by !**/*.md
  • .compozy/tasks/unified-capabilities/qa/test-cases/TC-PERF-002.md is excluded by !**/*.md
  • .compozy/tasks/unified-capabilities/qa/test-cases/TC-PERF-003.md is excluded by !**/*.md
  • .compozy/tasks/unified-capabilities/qa/test-cases/TC-SEC-001.md is excluded by !**/*.md
  • .compozy/tasks/unified-capabilities/qa/test-cases/TC-SEC-002.md is excluded by !**/*.md
  • .compozy/tasks/unified-capabilities/qa/test-cases/TC-SEC-003.md is excluded by !**/*.md
  • .compozy/tasks/unified-capabilities/qa/test-cases/TC-SEC-004.md is excluded by !**/*.md
  • .compozy/tasks/unified-capabilities/qa/test-cases/TC-UI-002.md is excluded by !**/*.md
  • .compozy/tasks/unified-capabilities/qa/test-cases/TC-UI-003.md is excluded by !**/*.md
  • .compozy/tasks/unified-capabilities/qa/test-cases/TC-UI-004.md is excluded by !**/*.md
  • .compozy/tasks/unified-capabilities/qa/test-cases/TC-UI-005.md is excluded by !**/*.md
  • .compozy/tasks/unified-capabilities/qa/test-cases/TC-UI-006.md is excluded by !**/*.md
  • .compozy/tasks/unified-capabilities/qa/test-cases/TC-UI-007.md is excluded by !**/*.md
  • .compozy/tasks/unified-capabilities/qa/test-cases/TC-UI-008.md is excluded by !**/*.md
  • .compozy/tasks/unified-capabilities/qa/test-cases/TC-UI-101.md is excluded by !**/*.md
  • .compozy/tasks/unified-capabilities/qa/test-plans/network-redesign-round2-test-plan.md is excluded by !**/*.md
  • .compozy/tasks/unified-capabilities/qa/verification-report-round2.md is excluded by !**/*.md
  • web/e2e/fixtures/browser-artifact-session.test.ts is excluded by !**/fixtures/**
  • web/e2e/fixtures/browser-artifact-session.ts is excluded by !**/fixtures/**
  • web/e2e/fixtures/selectors.test.ts is excluded by !**/fixtures/**
  • web/e2e/fixtures/selectors.ts is excluded by !**/fixtures/**
📒 Files selected for processing (20)
  • extensions/bridges/slack/provider.go
  • extensions/bridges/slack/provider_test.go
  • internal/api/core/network.go
  • internal/api/core/network_test.go
  • internal/api/core/test_helpers_test.go
  • internal/cli/cli_integration_test.go
  • internal/cli/network.go
  • internal/store/globaldb/global_db_network_messages.go
  • internal/store/globaldb/global_db_network_messages_test.go
  • internal/store/types.go
  • web/e2e/network.spec.ts
  • web/src/routes/_app/-network.test.tsx
  • web/src/routes/_app/network.tsx
  • web/src/routes/_app/settings/-network.test.tsx
  • web/src/routes/_app/settings/network.tsx
  • web/src/systems/network/components/network-workspace-shell.tsx
  • web/src/systems/network/components/stories/network-create-channel-dialog.stories.tsx
  • web/src/systems/network/lib/network-formatters.test.ts
  • web/src/systems/network/lib/network-formatters.ts
  • web/vite.config.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • web/src/systems/network/components/stories/network-create-channel-dialog.stories.tsx
  • web/src/routes/_app/-network.test.tsx

Comment thread web/src/systems/network/components/network-workspace-shell.tsx Outdated
Comment thread web/src/systems/network/components/network-workspace-shell.tsx

@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: 3

♻️ Duplicate comments (1)
web/src/systems/network/components/network-workspace-shell.tsx (1)

331-339: ⚠️ Potential issue | 🟡 Minor

greet capability badges still read the wrong shape.

readStringList(peerCard, "capabilities") expects an array of strings, but peer_card.capabilities is an array of objects with id and summary fields. This always returns [], so badges never render.

🐛 Proposed fix
-          {readStringList(peerCard, "capabilities").length > 0 ? (
+          {Array.isArray(peerCard?.capabilities) && peerCard.capabilities.length > 0 ? (
             <div className="flex flex-wrap gap-2">
-              {readStringList(peerCard, "capabilities").map(capabilityName => (
-                <MonoBadge key={capabilityName} uppercase={false}>
-                  {capabilityName}
+              {(peerCard.capabilities as Array<{ id?: string; summary?: string }>).map(
+                (capability, index) => (
+                  <MonoBadge key={capability.id ?? index} uppercase={false}>
+                    {capability.id ?? "unknown"}
+                  </MonoBadge>
+                )
-                </MonoBadge>
-              ))}
+              )}
             </div>
           ) : null}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@web/src/systems/network/components/network-workspace-shell.tsx` around lines
331 - 339, readStringList(peerCard, "capabilities") returns [] because
peerCard.capabilities is an array of objects ({id, summary}) not strings;
replace the readStringList usage with the actual object list and render badge
text from the object's summary (fall back to id) and use the object's id as the
key. Concretely, in the rendering around MonoBadge, iterate
(peerCard?.capabilities ?? []) and check length > 0, map each capability ->
MonoBadge with key={capability.id} and content={capability.summary ||
capability.id} so badges display correctly.
🧹 Nitpick comments (5)
internal/network/audit_test.go (2)

224-245: Add a mirrored received-direct case for direction coverage.

This subtest now validates only the sent direct path. Adding a received direct variant would better protect direction-specific timeline mapping.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@internal/network/audit_test.go` around lines 224 - 245, Add a mirrored
subtest that covers the "received direct" path: create a recordingAuditStore and
NewAuditWriter as in the existing test, call writer.RecordReceived(ctx,
"sess-audit", testAuditEnvelope(t)) instead of RecordSent, assert
storeSink.messages length is 1, check storeSink.messages[0].Direction equals
AuditDirectionReceived (instead of AuditDirectionSent) and check the addressing
metadata field for inbound envelopes (e.g., PeerFrom) equals "reviewer.sess-xyz"
to mirror the sent-direct assertions; reuse the same helpers
(recordingAuditStore, NewAuditWriter, testAuditEnvelope) and pattern of t.Fatalf
checks.

166-246: Refactor to a table-driven test pattern to match repository standards.

The three subtests repeat identical setup: storeSink, NewAuditWriter(), writer.now, and assertions on storeSink.messages. Consolidate into a table-driven structure with t.Run() for each case. This aligns with the coding guideline: "Use table-driven tests with subtests (t.Run) as default pattern for Go tests."

♻️ Refactoring sketch
 func TestAuditWriterPersistsTimelineMessagesForRenderableEnvelopes(t *testing.T) {
 	t.Parallel()
-
-	t.Run("Should persist sent say envelopes to the timeline store", func(t *testing.T) {
-		t.Parallel()
-		// setup + call + assertions...
-	})
-	t.Run("Should persist received say envelopes to the timeline store", func(t *testing.T) {
-		t.Parallel()
-		// setup + call + assertions...
-	})
-	t.Run("Should persist direct envelopes with addressing metadata", func(t *testing.T) {
-		t.Parallel()
-		// setup + call + assertions...
-	})
+	type testCase struct {
+		name      string
+		sessionID string
+		record    func(*FileAuditWriter, context.Context, string, Envelope) error
+		envelope  func(*testing.T) Envelope
+		assert    func(*testing.T, []store.NetworkMessageEntry)
+	}
+	cases := []testCase{
+		// sent say
+		// received say
+		// direct sent
+	}
+	for _, tc := range cases {
+		tc := tc
+		t.Run(tc.name, func(t *testing.T) {
+			t.Parallel()
+			storeSink := &recordingAuditStore{}
+			writer, err := NewAuditWriter("", storeSink)
+			if err != nil {
+				t.Fatalf("NewAuditWriter() error = %v", err)
+			}
+			writer.now = func() time.Time { return time.Date(2026, 4, 10, 12, 0, 0, 0, time.UTC) }
+			if err := tc.record(writer, context.Background(), tc.sessionID, tc.envelope(t)); err != nil {
+				t.Fatalf("record() error = %v", err)
+			}
+			tc.assert(t, storeSink.messages)
+		})
+	}
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@internal/network/audit_test.go` around lines 166 - 246, The test repeats
identical setup and assertions across three subtests in
TestAuditWriterPersistsTimelineMessagesForRenderableEnvelopes; refactor into a
table-driven test: create a slice of cases (with fields name, callType e.g.
"sent"/"received", sessionID, envelopeFunc
(testSayAuditEnvelope/testAuditEnvelope), optional setNow time for deterministic
writer.now, and expected checks against recordingAuditStore.messages), then loop
over cases and for each do t.Run(case.name, func(t *testing.T) { create
storeSink := &recordingAuditStore{}, writer, err := NewAuditWriter("",
storeSink), set writer.now if case provides, call writer.RecordSent or
writer.RecordReceived based on callType with case.sessionID and
case.envelopeFunc(t), then assert len(storeSink.messages) and the specific
expected fields (MessageID, Intent, Text, SessionID, Direction, PeerTo) instead
of duplicating setup; keep unique symbols:
TestAuditWriterPersistsTimelineMessagesForRenderableEnvelopes, NewAuditWriter,
writer.now, RecordSent, RecordReceived, testSayAuditEnvelope, testAuditEnvelope,
and recordingAuditStore to locate code.
web/src/systems/network/components/network-workspace-shell.tsx (1)

493-510: Composite key may collide if multiple fields share the same label-value pair.

Using ${field.label}-${field.value} could produce duplicate keys. Consider using the array index for uniqueness.

♻️ Use index-based key
-      {fields.map(field => (
-        <div className="space-y-1" key={`${field.label}-${field.value}`}>
+      {fields.map((field, index) => (
+        <div className="space-y-1" key={index}>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@web/src/systems/network/components/network-workspace-shell.tsx` around lines
493 - 510, The current list rendering in fields.map uses a composite key
`${field.label}-${field.value}` which can collide; update the key on the mapped
element so it is unique and stable—prefer using a unique identifier on each
field (e.g., field.id) if present, otherwise fallback to the map index from
fields.map((field, index) => ...) as the key; ensure you change the key on the
outer div (the element that currently uses `${field.label}-${field.value}`) and
keep the rest of the rendering (including MonoBadge and conditional mono
rendering) unchanged.
web/src/systems/network/mocks/handlers.ts (1)

70-80: Mock handler returns fixture directly without peer ID remapping.

The handler validates that peerId exists in networkPeersFixture before returning, which limits it to the two hardcoded fixture peers. This is acceptable for current mock/test purposes, but if tests need to query arbitrary peer IDs, the fixture messages would have inconsistent peer_from/peer_to values.

For improved mock fidelity, consider remapping both peer_from and peer_to when the requested peer differs from the fixture's primary peer:

♻️ Optional enhancement for flexible peer ID handling
   http.get("/api/network/peers/:peer_id/messages", ({ params }) => {
     const peerId = String(params.peer_id);

     if (!networkPeersFixture.some(peer => peer.peer_id === peerId)) {
       return HttpResponse.json({ error: `Peer not found: ${peerId}` }, { status: 404 });
     }

     return HttpResponse.json({
-      messages: networkPeerMessagesFixture,
+      messages: networkPeerMessagesFixture.map(message => ({
+        ...message,
+        peer_from: message.peer_from === networkPeerFixture.peer_id ? peerId : message.peer_from,
+        peer_to: message.peer_to === networkPeerFixture.peer_id ? peerId : message.peer_to,
+      })),
     });
   }),
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@web/src/systems/network/mocks/handlers.ts` around lines 70 - 80, The mock
handler at http.get("/api/network/peers/:peer_id/messages") currently returns
networkPeerMessagesFixture directly, causing mismatched peer IDs; update the
handler to produce a mapped copy of networkPeerMessagesFixture that remaps
message.peer_from and message.peer_to from the fixture's primary peer ID (e.g.,
networkPeersFixture[0].peer_id or the peer that the fixture messages use) to the
requested params.peer_id, without mutating the original fixture, and still
return the remapped array (preserving other fields and statuses).
internal/acp/types_test.go (1)

206-229: Assert the flushed ToolCallID, not just the event type.

This case still passes if the buffer releases the wrong deferred result as long as it is some EventTypeToolResult. Checking the emitted ToolCallID makes the cap test prove the newest retained entry actually wins.

♻️ Suggested test tightening
+		newestToolCallID := "tool-" + strconv.Itoa(maxPendingToolResults)
 		if _, ok := active.pendingToolResultIDs["tool-0"]; ok {
 			t.Fatal("oldest deferred tool result remained buffered after the cap was exceeded")
 		}
-		if _, ok := active.pendingToolResultIDs["tool-128"]; !ok {
+		if _, ok := active.pendingToolResultIDs[newestToolCallID]; !ok {
 			t.Fatal("newest deferred tool result was not retained after the cap was exceeded")
 		}
@@
-		proc.emitPromptEvent(AgentEvent{Type: EventTypeToolCall, TurnID: "turn-1", ToolCallID: "tool-128"})
+		proc.emitPromptEvent(AgentEvent{Type: EventTypeToolCall, TurnID: "turn-1", ToolCallID: newestToolCallID})
 		first := <-active.events
 		if first.Type != EventTypeToolCall {
 			t.Fatalf("newest tool call event = %q, want %q", first.Type, EventTypeToolCall)
 		}
+		if got := first.ToolCallID; got != newestToolCallID {
+			t.Fatalf("newest tool call id = %q, want %q", got, newestToolCallID)
+		}
 		second := <-active.events
 		if second.Type != EventTypeToolResult {
 			t.Fatalf("newest tool result event = %q, want %q", second.Type, EventTypeToolResult)
 		}
+		if got := second.ToolCallID; got != newestToolCallID {
+			t.Fatalf("newest tool result id = %q, want %q", got, newestToolCallID)
+		}

As per coding guidelines, Ensure tests verify behavior outcomes, not just function calls.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@internal/acp/types_test.go` around lines 206 - 229, The test currently only
asserts event.Type for the flushed events; update the assertions to also verify
the ToolCallID to ensure the newest deferred result is the one emitted. After
proc.emitPromptEvent(AgentEvent{... ToolCallID: "tool-0"}) where you read event
:= <-active.events, assert event.ToolCallID == "tool-0" (and similarly ensure no
extra events); after emitting the "tool-128" call and reading first and second
from active.events, assert first.ToolCallID == "tool-128" and second.ToolCallID
== "tool-128" and that second.Type == EventTypeToolResult so the test proves
pendingToolResultIDs retained the newest entry. Ensure references:
active.events, proc.emitPromptEvent, AgentEvent.ToolCallID, EventTypeToolCall,
EventTypeToolResult, and pendingToolResultIDs.
🤖 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/store/globaldb/global_db_network_channels_test.go`:
- Around line 15-300: You need to convert the top-level Test* functions for
network channel behavior into subtests using the t.Run("Should ...") pattern:
create a parent test (e.g. TestNetworkChannelsSuite) and move each existing test
body (from TestOpenGlobalDBCreatesNetworkChannelsSchema,
TestGlobalDBWriteAndListNetworkChannels, TestGlobalDBGetNetworkChannelNotFound,
TestGlobalDBDeleteNetworkChannel,
TestGlobalDBDeleteWorkspaceCascadesNetworkChannels,
TestGlobalDBListNetworkChannelsWrapsTimestampParseFailures,
TestMigrateGlobalSchemaRebuildsNetworkChannelsWithWorkspaceForeignKey) into its
own t.Run("Should <describe action>") { ... } block, keeping each subtest's
t.Parallel() where present and preserving all calls to helpers like
openTestGlobalDB, registerWorkspaceForGlobalTests, globalDB.WriteNetworkChannel,
globalDB.GetNetworkChannel, ListNetworkChannels, migrateGlobalSchema,
tableHasForeignKey, etc.; leave helper names and assertions unchanged, only
refactor test entry points into subtests under a single parent test function.
- Line 223: The cleanup currently discards the error from db.Close() with `_`,
violating the no-ignored-errors rule; update the t.Cleanup closure to call
db.Close(), capture its error, and report it via the testing.T instance (e.g.,
t.Errorf or t.Fatalf) so failures are surfaced — locate the t.Cleanup(func() { _
= db.Close() }) line and replace it with a closure that checks err := db.Close()
and reports it using t (preserving test context).

In `@internal/store/globaldb/migrate_workspace.go`:
- Around line 801-806: The INSERT selects untrimmed workspace_id but only trims
it in the WHERE clause, causing inserted FK values to include whitespace; update
the SELECT to insert TRIM(workspace_id) (e.g., SELECT channel,
TRIM(workspace_id) AS workspace_id, purpose, created_by, created_at, updated_at
FROM network_channels WHERE TRIM(workspace_id) IN (SELECT id FROM workspaces))
so the stored workspace_id matches workspace ids and the new FK/ON DELETE
CASCADE will work correctly.

---

Duplicate comments:
In `@web/src/systems/network/components/network-workspace-shell.tsx`:
- Around line 331-339: readStringList(peerCard, "capabilities") returns []
because peerCard.capabilities is an array of objects ({id, summary}) not
strings; replace the readStringList usage with the actual object list and render
badge text from the object's summary (fall back to id) and use the object's id
as the key. Concretely, in the rendering around MonoBadge, iterate
(peerCard?.capabilities ?? []) and check length > 0, map each capability ->
MonoBadge with key={capability.id} and content={capability.summary ||
capability.id} so badges display correctly.

---

Nitpick comments:
In `@internal/acp/types_test.go`:
- Around line 206-229: The test currently only asserts event.Type for the
flushed events; update the assertions to also verify the ToolCallID to ensure
the newest deferred result is the one emitted. After
proc.emitPromptEvent(AgentEvent{... ToolCallID: "tool-0"}) where you read event
:= <-active.events, assert event.ToolCallID == "tool-0" (and similarly ensure no
extra events); after emitting the "tool-128" call and reading first and second
from active.events, assert first.ToolCallID == "tool-128" and second.ToolCallID
== "tool-128" and that second.Type == EventTypeToolResult so the test proves
pendingToolResultIDs retained the newest entry. Ensure references:
active.events, proc.emitPromptEvent, AgentEvent.ToolCallID, EventTypeToolCall,
EventTypeToolResult, and pendingToolResultIDs.

In `@internal/network/audit_test.go`:
- Around line 224-245: Add a mirrored subtest that covers the "received direct"
path: create a recordingAuditStore and NewAuditWriter as in the existing test,
call writer.RecordReceived(ctx, "sess-audit", testAuditEnvelope(t)) instead of
RecordSent, assert storeSink.messages length is 1, check
storeSink.messages[0].Direction equals AuditDirectionReceived (instead of
AuditDirectionSent) and check the addressing metadata field for inbound
envelopes (e.g., PeerFrom) equals "reviewer.sess-xyz" to mirror the sent-direct
assertions; reuse the same helpers (recordingAuditStore, NewAuditWriter,
testAuditEnvelope) and pattern of t.Fatalf checks.
- Around line 166-246: The test repeats identical setup and assertions across
three subtests in TestAuditWriterPersistsTimelineMessagesForRenderableEnvelopes;
refactor into a table-driven test: create a slice of cases (with fields name,
callType e.g. "sent"/"received", sessionID, envelopeFunc
(testSayAuditEnvelope/testAuditEnvelope), optional setNow time for deterministic
writer.now, and expected checks against recordingAuditStore.messages), then loop
over cases and for each do t.Run(case.name, func(t *testing.T) { create
storeSink := &recordingAuditStore{}, writer, err := NewAuditWriter("",
storeSink), set writer.now if case provides, call writer.RecordSent or
writer.RecordReceived based on callType with case.sessionID and
case.envelopeFunc(t), then assert len(storeSink.messages) and the specific
expected fields (MessageID, Intent, Text, SessionID, Direction, PeerTo) instead
of duplicating setup; keep unique symbols:
TestAuditWriterPersistsTimelineMessagesForRenderableEnvelopes, NewAuditWriter,
writer.now, RecordSent, RecordReceived, testSayAuditEnvelope, testAuditEnvelope,
and recordingAuditStore to locate code.

In `@web/src/systems/network/components/network-workspace-shell.tsx`:
- Around line 493-510: The current list rendering in fields.map uses a composite
key `${field.label}-${field.value}` which can collide; update the key on the
mapped element so it is unique and stable—prefer using a unique identifier on
each field (e.g., field.id) if present, otherwise fallback to the map index from
fields.map((field, index) => ...) as the key; ensure you change the key on the
outer div (the element that currently uses `${field.label}-${field.value}`) and
keep the rest of the rendering (including MonoBadge and conditional mono
rendering) unchanged.

In `@web/src/systems/network/mocks/handlers.ts`:
- Around line 70-80: The mock handler at
http.get("/api/network/peers/:peer_id/messages") currently returns
networkPeerMessagesFixture directly, causing mismatched peer IDs; update the
handler to produce a mapped copy of networkPeerMessagesFixture that remaps
message.peer_from and message.peer_to from the fixture's primary peer ID (e.g.,
networkPeersFixture[0].peer_id or the peer that the fixture messages use) to the
requested params.peer_id, without mutating the original fixture, and still
return the remapped array (preserving other fields and statuses).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: af42a13a-efad-410c-b5d4-81d84ca7b7db

📥 Commits

Reviewing files that changed from the base of the PR and between 8d594a1 and 9064840.

⛔ Files ignored due to path filters (27)
  • .compozy/tasks/network-redesign/reviews-001/_meta.md is excluded by !**/*.md
  • .compozy/tasks/network-redesign/reviews-001/issue_001.md is excluded by !**/*.md
  • .compozy/tasks/network-redesign/reviews-001/issue_002.md is excluded by !**/*.md
  • .compozy/tasks/network-redesign/reviews-001/issue_003.md is excluded by !**/*.md
  • .compozy/tasks/network-redesign/reviews-001/issue_004.md is excluded by !**/*.md
  • .compozy/tasks/network-redesign/reviews-001/issue_005.md is excluded by !**/*.md
  • .compozy/tasks/network-redesign/reviews-001/issue_006.md is excluded by !**/*.md
  • .compozy/tasks/network-redesign/reviews-001/issue_007.md is excluded by !**/*.md
  • .compozy/tasks/network-redesign/reviews-001/issue_008.md is excluded by !**/*.md
  • .compozy/tasks/network-redesign/reviews-001/issue_009.md is excluded by !**/*.md
  • .compozy/tasks/network-redesign/reviews-001/issue_010.md is excluded by !**/*.md
  • .compozy/tasks/network-redesign/reviews-001/issue_011.md is excluded by !**/*.md
  • .compozy/tasks/network-redesign/reviews-001/issue_012.md is excluded by !**/*.md
  • .compozy/tasks/network-redesign/reviews-001/issue_013.md is excluded by !**/*.md
  • .compozy/tasks/network-redesign/reviews-001/issue_014.md is excluded by !**/*.md
  • .compozy/tasks/network-redesign/reviews-001/issue_015.md is excluded by !**/*.md
  • .compozy/tasks/network-redesign/reviews-001/issue_016.md is excluded by !**/*.md
  • .compozy/tasks/network-redesign/reviews-001/issue_017.md is excluded by !**/*.md
  • .compozy/tasks/network-redesign/reviews-001/issue_018.md is excluded by !**/*.md
  • .compozy/tasks/network-redesign/reviews-001/issue_019.md is excluded by !**/*.md
  • .compozy/tasks/network-redesign/reviews-001/issue_020.md is excluded by !**/*.md
  • .compozy/tasks/network-redesign/reviews-001/issue_021.md is excluded by !**/*.md
  • .compozy/tasks/network-redesign/reviews-001/issue_022.md is excluded by !**/*.md
  • .compozy/tasks/network-redesign/reviews-001/issue_023.md is excluded by !**/*.md
  • .compozy/tasks/network-redesign/reviews-001/issue_024.md is excluded by !**/*.md
  • .compozy/tasks/network-redesign/reviews-001/issue_025.md is excluded by !**/*.md
  • .compozy/tasks/network-redesign/reviews-001/issue_026.md is excluded by !**/*.md
📒 Files selected for processing (23)
  • internal/acp/types.go
  • internal/acp/types_test.go
  • internal/api/core/coverage_helpers_test.go
  • internal/api/core/interfaces.go
  • internal/api/core/network_details.go
  • internal/network/audit_test.go
  • internal/store/globaldb/global_db.go
  • internal/store/globaldb/global_db_network_channels.go
  • internal/store/globaldb/global_db_network_channels_test.go
  • internal/store/globaldb/global_db_network_messages_test.go
  • internal/store/globaldb/migrate_workspace.go
  • web/src/hooks/routes/use-network-page.ts
  • web/src/routes/_app/-network.test.tsx
  • web/src/systems/network/components/network-create-channel-dialog.test.tsx
  • web/src/systems/network/components/network-create-channel-dialog.tsx
  • web/src/systems/network/components/network-workspace-shell.test.tsx
  • web/src/systems/network/components/network-workspace-shell.tsx
  • web/src/systems/network/lib/network-formatters.test.ts
  • web/src/systems/network/lib/query-options.test.ts
  • web/src/systems/network/lib/query-options.ts
  • web/src/systems/network/mocks/fixtures.ts
  • web/src/systems/network/mocks/handlers.ts
  • web/src/systems/network/mocks/network-mocks.test.ts
✅ Files skipped from review due to trivial changes (2)
  • web/src/systems/network/lib/network-formatters.test.ts
  • internal/api/core/network_details.go
🚧 Files skipped from review as they are similar to previous changes (4)
  • web/src/systems/network/components/network-create-channel-dialog.tsx
  • web/src/systems/network/lib/query-options.ts
  • internal/store/globaldb/global_db_network_channels.go
  • internal/store/globaldb/global_db_network_messages_test.go

Comment thread internal/store/globaldb/global_db_network_channels_test.go Outdated
Comment thread internal/store/globaldb/global_db_network_channels_test.go Outdated
Comment thread internal/store/globaldb/migrate_workspace.go
compozybot and others added 7 commits April 23, 2026 22:55
Comprehensive fixes from gpt-5.5 xhigh code review across 10 domains:

High priority (4):
- Scope network message cursors to active channel/peer query filters
- Propagate request context through all Slack webhook dispatch paths
- Degrade all conflicting duplicate webhook paths deterministically
- Fix invalid nested interactive controls in network workspace sidebar

Medium priority (4):
- Replace N+1 session status lookups with single ListAll snapshot
- Canonicalize direction enum validation with TrimSpace rejection
- Unify UI terminology: 'recipe' → 'capability'
- Add joined_at to human-readable CLI network peers output

Design system (2):
- Replace custom Tailwind radii with CSS variable tokens
- Remove negative letter-spacing from workspace headings

Accessibility (6):
- Add aria-labels, aria-pressed, role=tablist/tab to filters/tabs
- Fix composer textarea, details toggle, loading states accessibility
- Label icon-only controls and kind filter button groups

Test coverage (+282 lines):
- Cross-channel/cross-peer cursor rejection tests
- Duplicate webhook path degradation tests
- Slack context propagation tests
- Web accessibility and copy change tests

All changes pass make verify (5569 Go tests + 1377 web tests)
Phase 1 — qa-report:
- Generated Round 2 test plan covering all 10 network domains
- Created 36 additive test cases (SMOKE, FUNC, INT, PERF, REG, SEC, UI)
- Documented 6 bug reports (BUG-001 through BUG-006):
  - BUG-001/002: High/P0 functional issues (discovery mismatch, lifecycle drop)
  - BUG-003: Medium/P1 browser flow instability
  - BUG-004: High/P0 CLI integration NetworkStore wiring missing
  - BUG-005: Medium/P1 Playwright selectors outdated for unified workspace
  - BUG-006: Medium/P1 Vite production build chunk-size warning

Phase 2 — qa-execution:
- Fixed BUG-004: Wired udsapi.WithNetworkStore in CLI integration daemon
- Fixed BUG-005: Updated Playwright selectors/artifacts/network.spec.ts for
  unified room workspace model; fixed agent-option actionability race with
  dispatchEvent click pattern
- Fixed BUG-006: Added Rolldown code split for React runtime packages,
  largest chunk now ~498kB (< 500kB threshold)
- Ran full verification matrix: make verify, go vet ./..., integration tests,
  focused race coverage, Vitest unit tests, Playwright E2E

Verification results (all PASS):
- make verify: 0 warnings/errors, 1377 web tests, 5569 Go tests
- go vet ./...: exit code 0
- Integration tests (-race -tags): network/cli/udsapi pass
- Playwright E2E: network operator flow + settings flows (6 tests) pass
- Production build: zero chunk-size warnings

QA artifacts:
- verification-report-round2.md (full evidence report)
- 8 browser screenshots captured
- 43 total test case files (36 new R2)
- Test plans: round2 + regression + unified capabilities

@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.

♻️ Duplicate comments (1)
internal/store/globaldb/global_db_network_channels_test.go (1)

325-325: ⚠️ Potential issue | 🟡 Minor

Handle rows.Close() errors instead of discarding them.

Line 325 currently uses _ = rows.Close(), which suppresses cleanup failures in a DB migration test path.

🔧 Proposed fix
-	defer func() { _ = rows.Close() }()
+	defer func() {
+		if err := rows.Close(); err != nil {
+			t.Errorf("rows.Close() error = %v", err)
+		}
+	}()
#!/bin/bash
# Verify ignored Close() errors in Go files
rg -nP --type go '\b_\s*=\s*[^;\n]*\.Close\s*\('

As per coding guidelines, **/*.go: Never ignore errors with _ — every error must be handled or have a written justification.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@internal/store/globaldb/global_db_network_channels_test.go` at line 325, The
defer currently discards the error from rows.Close(); replace the ignored close
with an explicit check and fail the test on error. Change defer func() { _ =
rows.Close() }() to a deferred closure that captures the returned error (e.g.
defer func() { if err := rows.Close(); err != nil { t.Fatalf("rows.Close failed:
%v", err) } }()) so the test surface any cleanup failures from rows.Close(); use
the test's *testing.T (t) or your project's test assertion helper (e.g.,
require.NoError) if preferred.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@internal/store/globaldb/global_db_network_channels_test.go`:
- Line 325: The defer currently discards the error from rows.Close(); replace
the ignored close with an explicit check and fail the test on error. Change
defer func() { _ = rows.Close() }() to a deferred closure that captures the
returned error (e.g. defer func() { if err := rows.Close(); err != nil {
t.Fatalf("rows.Close failed: %v", err) } }()) so the test surface any cleanup
failures from rows.Close(); use the test's *testing.T (t) or your project's test
assertion helper (e.g., require.NoError) if preferred.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 80d51c97-801e-4470-80cf-118ca96a07d8

📥 Commits

Reviewing files that changed from the base of the PR and between 9064840 and 0e01448.

⛔ Files ignored due to path filters (9)
  • .compozy/tasks/network-redesign/reviews-002/_meta.md is excluded by !**/*.md
  • .compozy/tasks/network-redesign/reviews-002/issue_001.md is excluded by !**/*.md
  • .compozy/tasks/network-redesign/reviews-002/issue_002.md is excluded by !**/*.md
  • .compozy/tasks/network-redesign/reviews-002/issue_003.md is excluded by !**/*.md
  • .compozy/tasks/network-redesign/reviews-002/issue_004.md is excluded by !**/*.md
  • .compozy/tasks/network-redesign/reviews-002/issue_005.md is excluded by !**/*.md
  • .compozy/tasks/network-redesign/reviews-002/issue_006.md is excluded by !**/*.md
  • .compozy/tasks/network-redesign/reviews-002/issue_007.md is excluded by !**/*.md
  • .compozy/tasks/network-redesign/reviews-002/issue_008.md is excluded by !**/*.md
📒 Files selected for processing (4)
  • internal/acp/types_test.go
  • internal/network/audit_test.go
  • internal/store/globaldb/global_db_network_channels_test.go
  • internal/store/globaldb/migrate_workspace.go
✅ Files skipped from review due to trivial changes (2)
  • internal/store/globaldb/migrate_workspace.go
  • internal/acp/types_test.go

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.

2 participants