feat: add automation#16
Conversation
WalkthroughAdds a full automation subsystem: domain model, validation and template tooling, dispatcher/scheduler/trigger engine, manager runtime, API + CLI surfaces (including webhook endpoints), TOML config support, extensive tests, and Go module dependency updates. Changes
Sequence Diagram(s)sequenceDiagram
participant Client as Client/CLI
participant API as API Server
participant Manager as Automation Manager
participant Dispatcher as Dispatcher
participant Store as Run Store
participant Session as Session Manager
Client->>API: POST /api/automation/jobs/:id/trigger
API->>Manager: TriggerJob(ctx, id)
Manager->>Dispatcher: Dispatch(Request{Kind: Manual, Job: ...})
Dispatcher->>Store: CreateRun(status=scheduled)
Dispatcher->>Session: Create(sessionOpts)
Session-->>Dispatcher: sessionID
Dispatcher->>Session: Prompt(sessionID, prompt)
Dispatcher->>Store: UpdateRun(status=completed/failed)
Dispatcher-->>Manager: run result
Manager-->>API: RunPayload
API-->>Client: 200 { run }
Estimated code review effort🎯 5 (Critical) | ⏱️ ~120 minutes Possibly related PRs
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
|
There was a problem hiding this comment.
Actionable comments posted: 14
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
internal/api/udsapi/handlers_test.go (1)
67-147: 🛠️ Refactor suggestion | 🟠 MajorRefactor this route-coverage test into
t.Run("Should...")subtests.The updated test is still a single-case function; project test policy requires subtests by default, and this case is a good candidate for a “Should register all tech-spec routes” subtest wrapper (or table-driven variants for route groups).
As per coding guidelines, "Use table-driven tests with subtests (
t.Run) as default" and "MUST use t.Run("Should...") pattern for ALL test cases".🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@internal/api/udsapi/handlers_test.go` around lines 67 - 147, Refactor TestRegisterRoutesCoversTechSpecEndpoints into a subtest by wrapping the existing setup and assertions in t.Run("Should register all tech-spec routes", func(t *testing.T) { ... }), keeping the current calls to newTestHomePaths, newTestHandlers, newTestRouter and the route collection/assertion logic intact but executed inside the subtest; if you prefer clearer structure, extract the expected routes slice into a local variable and/or use a small table-driven subtest loop for route groups, but ensure the main test function only defines the subtest(s) via t.Run and preserves the same comparisons and failure behavior.
🧹 Nitpick comments (11)
internal/api/contract/contract_test.go (1)
249-268: Cover zero-value PATCH fields inHasChanges()tests.The risky case for pointer-based update DTOs is an explicit zero value like
Enabled: ptr(false): it should still count as a change. Right now this only proves string-backed fields, so a regression in bool handling would still pass.Suggested test additions
func TestAutomationUpdateRequestsHasChanges(t *testing.T) { t.Parallel() name := "updated" secret := "secret" + disabled := false if (contract.UpdateJobRequest{}).HasChanges() { t.Fatal("UpdateJobRequest{}.HasChanges() = true, want false") } if !(contract.UpdateJobRequest{Name: &name}).HasChanges() { t.Fatal("UpdateJobRequest{Name}.HasChanges() = false, want true") } + if !(contract.UpdateJobRequest{Enabled: &disabled}).HasChanges() { + t.Fatal("UpdateJobRequest{Enabled:false}.HasChanges() = false, want true") + } if (contract.UpdateTriggerRequest{}).HasChanges() { t.Fatal("UpdateTriggerRequest{}.HasChanges() = true, want false") } if !(contract.UpdateTriggerRequest{WebhookSecret: &secret}).HasChanges() { t.Fatal("UpdateTriggerRequest{WebhookSecret}.HasChanges() = false, want true") } + if !(contract.UpdateTriggerRequest{Enabled: &disabled}).HasChanges() { + t.Fatal("UpdateTriggerRequest{Enabled:false}.HasChanges() = false, want true") + } }As per coding guidelines, "MUST test meaningful business logic, not trivial operations".
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@internal/api/contract/contract_test.go` around lines 249 - 268, Add test cases to TestAutomationUpdateRequestsHasChanges that cover pointer-based fields with explicit zero values so HasChanges() treats them as changes; specifically, assert that UpdateJobRequest{Enabled: ptr(false)}.HasChanges() returns true and similarly assert for any boolean pointer fields on UpdateTriggerRequest (e.g., Enabled or other bool pointers) using a ptr(false) value. Locate the existing TestAutomationUpdateRequestsHasChanges and extend it by creating local bool variables (or a helper ptr function) and adding assertions analogous to the existing string-pointer checks to ensure zero-value pointers are counted as changes.internal/cli/client_test.go (1)
411-676: Split the automation client E2E test into focusedt.Run("Should...")cases.This test exercises a large slice of the client surface in one flow, so the first failure hides the rest of the regressions and makes the failing capability harder to isolate. Breaking it up by operation (
Should list jobs,Should create job,Should list runs, etc.) will keep failures actionable and aligns with the repo's test conventions.As per coding guidelines, "Use table-driven tests with subtests (
t.Run) as default" and "MUST uset.Run("Should...")pattern for ALL test cases".🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@internal/cli/client_test.go` around lines 411 - 676, The single large TestUnixSocketClientAutomationMethods should be split into focused subtests using t.Run("Should ...") for each operation so failures are isolated; refactor the test body into multiple subtests that each exercise one client method or logical group (e.g. "Should list jobs" -> ListAutomationJobs, "Should create job" -> CreateAutomationJob/GetAutomationJob/UpdateAutomationJob/DeleteAutomationJob, "Should trigger and list job runs" -> TriggerAutomationJob/AutomationJobRuns, "Should manage triggers" -> ListAutomationTriggers/CreateAutomationTrigger/GetAutomationTrigger/UpdateAutomationTrigger/AutomationTriggerRuns/DeleteAutomationTrigger, and "Should list and get runs" -> ListAutomationRuns/GetAutomationRun), keep the same request mock behavior and assertions but move them into the appropriate t.Run blocks, sharing the same test httpClient setup and ctx while ensuring each subtest calls t.Parallel() only where safe.internal/automation/trigger_test.go (1)
445-472: Use named subtests for these table cases.Both loops stop on the first failure and make it harder to see which scenario broke. Wrapping each case in
t.Run("Should...")and callingt.Parallel()inside independent subtests would make the failures much easier to triage.As per coding guidelines, "Use table-driven tests with subtests (
t.Run) as default" and "Uset.Parallel()for independent subtests".Also applies to: 479-510
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@internal/automation/trigger_test.go` around lines 445 - 472, The table-driven loop over testCases should be converted into named subtests so failures are isolated and parallelizable: for each entry in testCases, call t.Run with a descriptive name (e.g., the path or expectation) and inside the subtest call t.Parallel(); then execute envelopeFilterValue(envelope, tc.path) and perform the same ok/got assertions there. Apply the same refactor to the other table-driven cases later in the file so each scenario runs as an independent, parallel subtest.internal/api/testutil/apitest.go (1)
142-163: Add compile-time verification forStubAutomationManager.This new stub is meant to satisfy
core.AutomationManager, but unlike the other stubs in this file it is not pinned with avar _ ...assertion. Adding one will catch interface drift earlier as the automation surface evolves.♻️ Proposed change
var _ core.SessionManager = StubSessionManager{} var _ core.Observer = StubObserver{} +var _ core.AutomationManager = StubAutomationManager{} var _ core.WorkspaceService = StubWorkspaceService{}As per coding guidelines, "Use compile-time interface verification: var _ Interface = (*Type)(nil)".
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@internal/api/testutil/apitest.go` around lines 142 - 163, The StubAutomationManager type is missing a compile-time interface assertion to ensure it implements core.AutomationManager; add the standard verification line referencing those symbols (e.g., var _ core.AutomationManager = (*StubAutomationManager)(nil)) adjacent to the StubAutomationManager declaration so changes to the automation interface will fail at compile time.internal/automation/trigger_integration_test.go (1)
94-99: GuardpromptCalls()before indexing it.Both assertions read
[0]without first checking the slice length. If dispatch creates the session but never reachesPrompt, the test fails with an index panic instead of a clear assertion.♻️ Proposed change
+ if got, want := len(creator.promptCalls()), 1; got != want { + t.Fatalf("len(Prompt calls) = %d, want %d", got, want) + } if got, want := creator.promptCalls()[0].message, "Digest fresh context"; got != want { t.Fatalf("Prompt().message = %q, want %q", got, want) }Also applies to: 160-165
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@internal/automation/trigger_integration_test.go` around lines 94 - 99, The test indexes creator.promptCalls()[0] without checking the slice length, which can cause an index panic; update the assertions that reference creator.promptCalls()[0] (and the similar checks later around the other block) to first assert the length of creator.promptCalls() (e.g., check len(creator.promptCalls()) == expected) and only then inspect promptCalls()[0].message (and other fields) so failures produce clear test errors instead of panics; ensure you modify both the block around the createCalls() check and the similar assertions in the later section (the lines referencing creator.promptCalls()[0] and Prompt().message).internal/cli/automation_test.go (1)
467-490: Assert the webhook fields on trigger update.This case passes
--event webhook,--webhook-id, and--endpoint-slug, but the test only checksRetry,Filter, andWebhookSecret. If any of those new flags stopped being wired intoupdateTriggerRequest, this test would still pass.As per coding guidelines, "Focus on critical paths: workflow execution, state management, error handling".
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@internal/cli/automation_test.go` around lines 467 - 490, The test calls executeRootCommand to update a trigger with --event webhook, --webhook-id and --endpoint-slug but assertions only verify Retry, Filter and WebhookSecret; update the test (after json.Unmarshal into updated and with access to updateTriggerRequest) to also assert that updateTriggerRequest.Event == "webhook" (or the enum/value used), updateTriggerRequest.WebhookID == "wbh_123" and updateTriggerRequest.EndpointSlug == "branch-review" and that the returned updated.ID == "trg-1"; reference the existing symbols updatedTriggerJSON, executeRootCommand, updateTriggerRequest and TriggerRecord (and automationpkg.RetryStrategyBackoff) when adding these checks so the test fails if webhook flags are not wired through.internal/automation/manager_test.go (1)
1024-1075: Make the nil-context assertions specific.Right now any error satisfies these branches, so a validation or persistence regression would still look like a passing nil-context test. Please match the sentinel or message the manager is expected to return for nil contexts.
As per coding guidelines, "MUST have specific error assertions (ErrorContains, ErrorAs)".
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@internal/automation/manager_test.go` around lines 1024 - 1075, The nil-context tests currently only check for a non-nil error; change each assertion to verify the specific sentinel or message the manager returns for missing contexts (e.g., use errors.Is(err, ErrMissingContext) or require.ErrorContains(t, err, "missing context")/assert.ErrorContains as your codebase uses). Update the checks for all manager methods listed (CreateJob, ListJobs, GetJob, UpdateJob, DeleteJob, TriggerJob, SetJobEnabled, CreateTrigger, ListTriggers, GetTrigger, UpdateTrigger, DeleteTrigger, SetTriggerEnabled, ListRuns, GetRun, Status) to assert the exact expected error by using ErrorIs/ErrorAs or ErrorContains instead of err == nil.internal/automation/validate_test.go (1)
460-515: Assert which validation failed, not just that something failed.These cases only check
err != nil, so they still pass if validation breaks for an unrelated field or rule. Please carry awantErr/field path per case and assert it, like the earlier table-driven sections in this file already do.As per coding guidelines, "MUST have specific error assertions (ErrorContains, ErrorAs)".
Also applies to: 621-732, 734-787
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@internal/automation/validate_test.go` around lines 460 - 515, The table-driven test TestJobValidateRejectsMissingRequiredFields currently only checks err != nil; update each test case to include a wantErr string (or expected field path) that identifies which validation must fail (e.g., "name", "agent_name", "prompt"), call tc.job.Validate("job"), and assert the returned error contains the expected substring using a specific assertion (ErrorContains / require.ErrorContains) rather than a nil-check; reference Job.Validate and the test cases in TestJobValidateRejectsMissingRequiredFields and mirror the pattern used in earlier table-driven sections that include wantErr to ensure the test fails if a different validation rule breaks.internal/cli/automation.go (1)
1016-1023: Potential unnecessarytime.Now()call whennowfunction is provided.The code calls
time.Now()unconditionally before checking if a customnowfunction is provided. While functionally correct (it gets overwritten), this is slightly wasteful and could be simplified.♻️ Suggested simplification
- current := time.Now().UTC() - if now != nil { - current = now().UTC() - } + var current time.Time + if now != nil { + current = now().UTC() + } else { + current = time.Now().UTC() + }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@internal/cli/automation.go` around lines 1016 - 1023, The code unconditionally calls time.Now() before checking the optional now function; change the logic in the function that computes the time (using the current, now and duration variables) to only call time.Now() when now is nil: set current from now().UTC() if now != nil, otherwise set current to time.Now().UTC(), then return current.Add(-duration), nil. This removes the unnecessary unconditional time.Now() invocation while preserving behavior.internal/config/automation.go (2)
255-281: Unused error return value.
toAutomationTriggeralways returnsnilerror but the signature includes an error return. Same consideration astoAutomationJobabove.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@internal/config/automation.go` around lines 255 - 281, The toAutomationTrigger method (parsedAutomationTrigger.toAutomationTrigger) currently returns an error but never produces one; remove the unused error return from its signature and update all callers to expect only (AutomationTrigger) instead of (AutomationTrigger, error); alternatively, if you prefer to keep the error return for future validation, add appropriate validation logic that can return a non-nil error before the final return—ensure consistency with toAutomationJob's approach and update references to trigger := parsedAutomationTrigger.toAutomationTrigger(...) accordingly.
227-253: Unused error return value.
toAutomationJobalways returnsnilerror but the signature includes an error return. If this is intentional for future extensibility, consider documenting it; otherwise, simplify the signature.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@internal/config/automation.go` around lines 227 - 253, The function parsedAutomationJob.toAutomationJob declares an error return but never returns a non-nil error; either remove the error from the signature or implement validation that can produce meaningful errors. If you choose to simplify, change toAutomationJob to return only (AutomationJob) and update all callers to stop expecting an error; if you choose to keep it for future extensibility, add input validation (e.g., validate required fields like Name, Scope, AgentName, Prompt, Schedule) inside toAutomationJob and return a descriptive error when validation fails so the error return is used consistently. Ensure you update all references to parsedAutomationJob.toAutomationJob or toAutomationJob accordingly.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@internal/api/core/automation.go`:
- Around line 618-621: The code uses io.ReadAll(c.Request.Body) which is
unbounded; replace it with a size-limited read by wrapping c.Request.Body with a
MaxBytesReader or LimitReader before reading: define a constant (e.g.
maxWebhookBodySize) and do c.Request.Body = http.MaxBytesReader(c.Writer,
c.Request.Body, maxWebhookBodySize) (or use io.LimitReader) and then call
io.ReadAll on that wrapped reader; update the error handling around the existing
payload, err block to return a clear error when the body exceeds the limit.
In `@internal/api/core/errors.go`:
- Around line 97-121: StatusForAutomationError currently falls through to 500
for the new overlay sentinel errors; add explicit mappings in
StatusForAutomationError so these domain outcomes return the intended statuses:
check errors.Is(err, automationpkg.ErrOverlayRequiresConfigSource) and return
http.StatusConflict, and check errors.Is(err,
automationpkg.ErrJobOverlayNotFound) and errors.Is(err,
automationpkg.ErrTriggerOverlayNotFound) and return http.StatusNotFound; insert
these cases before the default branch in the StatusForAutomationError switch so
overlay failures no longer produce 500.
- Around line 89-94: The NewAutomationValidationError function wraps an incoming
error but currently uses "%v" which loses the original error in the chain;
change the fmt.Errorf call in NewAutomationValidationError to use two %w verbs
so both ErrAutomationValidation and the provided err are wrapped (use
fmt.Errorf("%w: %w", ErrAutomationValidation, err)) to preserve error unwrapping
via errors.Is/errors.As.
In `@internal/api/udsapi/udsapi_integration_test.go`:
- Around line 246-260: The test currently reads run history immediately after
stopIntegrationSession and can flake; modify the section after
stopIntegrationSession(t, runtime, sessionID) to poll the runs endpoint (use
mustUnixRequest with http.MethodGet to
"http://unix/api/automation/triggers/"+created.Trigger.ID+"/runs") until
contract.RunsResponse.Runs is non-empty or a deadline expires (e.g., now+several
seconds), sleeping briefly between attempts (e.g., 100–200ms); on each attempt
decodeHTTPJSON into contract.RunsResponse, ensure response bodies are closed,
and if the deadline is reached call t.Fatalf reporting no run found. Use the
existing identifiers createIntegrationSession, stopIntegrationSession,
mustUnixRequest, decodeHTTPJSON, and contract.RunsResponse to locate and update
the code.
In `@internal/automation/dispatch.go`:
- Around line 526-552: These post-fire hook calls currently ignore returned
errors (in dispatchPostFireHook and the other post/lifecycle dispatches) causing
failures to be silent; capture the error returned by each hook call (e.g., the
calls to DispatchAutomationJobPostFire, DispatchAutomationTriggerPostFire,
DispatchAutomationRunCompleted, DispatchAutomationRunFailed), then handle it
instead of using "_, _ =" — at minimum call the dispatcher logger (e.g.,
d.logger.Errorf or similar logger on the Dispatcher) with a clear message and
error details including the relevant IDs (JobID/TriggerID/RunID), or propagate
the error by returning it from the function if the call site expects error
handling. Ensure you replace each "_, _ =" usage with proper err checking (if
err != nil { ... }) referencing the specific function names above.
- Around line 759-777: collectPromptError currently blocks reading from events
until the channel closes and doesn't respect context cancellation; update
collectPromptError to use a select loop that watches both ctx.Done() and the
events channel (e.g., for { select { case <-ctx.Done(): return ctx.Err() case
event, ok := <-events: if !ok { break out of loop } ... } }) so you stop
draining when context is canceled, still collect trimmed event.Error into errs
(as currently) when events are received, and after the loop return
errors.Join(errs...) or ctx.Err() appropriately; reference the
collectPromptError function and the errs slice and event.Error symbols when
applying the change.
In `@internal/automation/extension_test.go`:
- Around line 14-28: Update the table-driven tests in
internal/automation/extension_test.go so each test name follows the "Should..."
pattern (e.g., "Should reject built-in event names") and for the case where
Event is "session.stopped" (and generally any non-`ext.` event) replace the
loose wantErr check with a specific assertion that the validation failure
contains the ext-prefix error (use ErrorContains/ErrorAs helper) when calling
Validate("trigger_fire") on the ExtensionTriggerRequest; refer to the table
entries and the ExtensionTriggerRequest struct to locate and modify the failing
subtests.
In `@internal/automation/extension.go`:
- Around line 17-27: The Validate method on ExtensionTriggerRequest currently
trims r.Event only for checks but leaves the original value intact; change
Validate (in ExtensionTriggerRequest.Validate) to first compute trimmed :=
strings.TrimSpace(r.Event), then if trimmed == "" return the existing required
error, then if trimmed != r.Event return an error indicating surrounding
whitespace is not allowed (use nestedPath(path, "event") in the message), and
then proceed to use trimmed for the HasPrefix("ext.") check and the rest of
validation (including the existing ValidateScopeBinding call).
In `@internal/automation/manager.go`:
- Around line 365-387: The cleanup calls currently swallow errors and use
context.Background(); update the error handling in the startup/cleanup sequence
around m.loadSchedulerRegistrations, m.loadTriggerRegistrations,
triggerEngine.Start and scheduler.Start so that Shutdown(...) returns are
checked and handled (log the error and/or aggregate/return a wrapped error)
instead of using `_`, and replace context.Background() with the provided ctx or
a derived context with timeout/cancellation; ensure runtimeCancel() is still
called, then call scheduler.Shutdown(ctx) and triggerEngine.Shutdown(ctx) (or
ctxWithTimeout) and propagate or log any shutdown error rather than discarding
it.
- Around line 1682-1705: The session trigger calls currently ignore errors from
engine.FireSessionCreated and engine.FireSessionStopped; update
fireSessionCreated and fireSessionStopped to capture the returned error, check
if err != nil, and log the failure (including the error and relevant session
info) using the Manager's logger consistent with trigger.go's pattern; keep the
existing triggerRuntime and mergedRuntimeContext usage and defer cancel, but
replace "_, _ = ..." with "if _, err := engine.FireSessionCreated(...); err !=
nil { m.log.Errorf(..., err) }" (and similarly for FireSessionStopped),
referencing the functions fireSessionCreated, fireSessionStopped,
triggerRuntime, mergedRuntimeContext, and the
engine.FireSessionCreated/FireSessionStopped calls.
- Around line 358-387: The Start method currently creates runtimeCtx with
context.WithCancel(context.Background()), severing the caller's context chain;
change it to derive from the incoming ctx using context.WithoutCancel(ctx)
(i.e., runtimeCtx, runtimeCancel := context.WithoutCancel(ctx)) and update the
call to m.buildRuntimes to accept the parent ctx so buildRuntimes can also use
context.WithoutCancel(ctx) instead of context.Background(); ensure all
shutdown/cancel logic still uses runtimeCancel and that buildRuntimes signature
and its internal uses are updated accordingly (reference: Start method,
runtimeCtx, runtimeCancel, m.buildRuntimes, buildRuntimes).
In `@internal/automation/model/template.go`:
- Around line 153-171: The validator currently skips VariableNode roots, so
update validateTemplateArg to explicitly handle *parse.VariableNode* and return
an error (or otherwise reject) when a variable is used as a root for field
lookups or indexing; also adjust templateFieldPath and validateIndexArgs to
treat a VariableNode root as a disallowed/invalid path (i.e., return an error or
false that causes validation failure) instead of silently returning ok, ensuring
functions named validateTemplateArg, templateFieldPath, validateIndexArgs,
validateActivationFieldPath (and the callers
validatePipeNode/validateCommandNode) will conservatively reject any $var.Field
or index $var "field" usages.
In `@internal/automation/trigger.go`:
- Around line 99-108: The webhook handler is vulnerable to replay because
WebhookRequest lacks a delivery identifier and HandleWebhook only validates
HMAC+timestamp; add an explicit DeliveryID (string) field to WebhookRequest and
make HandleWebhook verify that DeliveryID is present, check a durable/fast dedup
store (e.g., Redis or in-memory cache with TTL) for prior processing, and
atomically mark the DeliveryID as seen with an expiration equal to your
freshness window to reject duplicates; ensure the signature validation still
runs and that HandleWebhook returns a clear error for already-seen DeliveryIDs
so replays are dropped.
In `@internal/cli/cli_integration_test.go`:
- Around line 865-879: Start the automation manager with the surrounding ctx
(not context.Background()) and register its cleanup immediately after Start
returns; i.e., call automationManager.Start(ctx) and right after a successful
start immediately defer automationManager.Stop(ctx) (or the manager's
appropriate shutdown method) before creating udsapi.New() or calling
server.Start(), then continue to append automationManager.SessionObserver() to
fanout.notifiers—this ensures the automationManager is tied to the daemon
context and always cleaned up if subsequent initialization fails.
---
Outside diff comments:
In `@internal/api/udsapi/handlers_test.go`:
- Around line 67-147: Refactor TestRegisterRoutesCoversTechSpecEndpoints into a
subtest by wrapping the existing setup and assertions in t.Run("Should register
all tech-spec routes", func(t *testing.T) { ... }), keeping the current calls to
newTestHomePaths, newTestHandlers, newTestRouter and the route
collection/assertion logic intact but executed inside the subtest; if you prefer
clearer structure, extract the expected routes slice into a local variable
and/or use a small table-driven subtest loop for route groups, but ensure the
main test function only defines the subtest(s) via t.Run and preserves the same
comparisons and failure behavior.
---
Nitpick comments:
In `@internal/api/contract/contract_test.go`:
- Around line 249-268: Add test cases to TestAutomationUpdateRequestsHasChanges
that cover pointer-based fields with explicit zero values so HasChanges() treats
them as changes; specifically, assert that UpdateJobRequest{Enabled:
ptr(false)}.HasChanges() returns true and similarly assert for any boolean
pointer fields on UpdateTriggerRequest (e.g., Enabled or other bool pointers)
using a ptr(false) value. Locate the existing
TestAutomationUpdateRequestsHasChanges and extend it by creating local bool
variables (or a helper ptr function) and adding assertions analogous to the
existing string-pointer checks to ensure zero-value pointers are counted as
changes.
In `@internal/api/testutil/apitest.go`:
- Around line 142-163: The StubAutomationManager type is missing a compile-time
interface assertion to ensure it implements core.AutomationManager; add the
standard verification line referencing those symbols (e.g., var _
core.AutomationManager = (*StubAutomationManager)(nil)) adjacent to the
StubAutomationManager declaration so changes to the automation interface will
fail at compile time.
In `@internal/automation/manager_test.go`:
- Around line 1024-1075: The nil-context tests currently only check for a
non-nil error; change each assertion to verify the specific sentinel or message
the manager returns for missing contexts (e.g., use errors.Is(err,
ErrMissingContext) or require.ErrorContains(t, err, "missing
context")/assert.ErrorContains as your codebase uses). Update the checks for all
manager methods listed (CreateJob, ListJobs, GetJob, UpdateJob, DeleteJob,
TriggerJob, SetJobEnabled, CreateTrigger, ListTriggers, GetTrigger,
UpdateTrigger, DeleteTrigger, SetTriggerEnabled, ListRuns, GetRun, Status) to
assert the exact expected error by using ErrorIs/ErrorAs or ErrorContains
instead of err == nil.
In `@internal/automation/trigger_integration_test.go`:
- Around line 94-99: The test indexes creator.promptCalls()[0] without checking
the slice length, which can cause an index panic; update the assertions that
reference creator.promptCalls()[0] (and the similar checks later around the
other block) to first assert the length of creator.promptCalls() (e.g., check
len(creator.promptCalls()) == expected) and only then inspect
promptCalls()[0].message (and other fields) so failures produce clear test
errors instead of panics; ensure you modify both the block around the
createCalls() check and the similar assertions in the later section (the lines
referencing creator.promptCalls()[0] and Prompt().message).
In `@internal/automation/trigger_test.go`:
- Around line 445-472: The table-driven loop over testCases should be converted
into named subtests so failures are isolated and parallelizable: for each entry
in testCases, call t.Run with a descriptive name (e.g., the path or expectation)
and inside the subtest call t.Parallel(); then execute
envelopeFilterValue(envelope, tc.path) and perform the same ok/got assertions
there. Apply the same refactor to the other table-driven cases later in the file
so each scenario runs as an independent, parallel subtest.
In `@internal/automation/validate_test.go`:
- Around line 460-515: The table-driven test
TestJobValidateRejectsMissingRequiredFields currently only checks err != nil;
update each test case to include a wantErr string (or expected field path) that
identifies which validation must fail (e.g., "name", "agent_name", "prompt"),
call tc.job.Validate("job"), and assert the returned error contains the expected
substring using a specific assertion (ErrorContains / require.ErrorContains)
rather than a nil-check; reference Job.Validate and the test cases in
TestJobValidateRejectsMissingRequiredFields and mirror the pattern used in
earlier table-driven sections that include wantErr to ensure the test fails if a
different validation rule breaks.
In `@internal/cli/automation_test.go`:
- Around line 467-490: The test calls executeRootCommand to update a trigger
with --event webhook, --webhook-id and --endpoint-slug but assertions only
verify Retry, Filter and WebhookSecret; update the test (after json.Unmarshal
into updated and with access to updateTriggerRequest) to also assert that
updateTriggerRequest.Event == "webhook" (or the enum/value used),
updateTriggerRequest.WebhookID == "wbh_123" and
updateTriggerRequest.EndpointSlug == "branch-review" and that the returned
updated.ID == "trg-1"; reference the existing symbols updatedTriggerJSON,
executeRootCommand, updateTriggerRequest and TriggerRecord (and
automationpkg.RetryStrategyBackoff) when adding these checks so the test fails
if webhook flags are not wired through.
In `@internal/cli/automation.go`:
- Around line 1016-1023: The code unconditionally calls time.Now() before
checking the optional now function; change the logic in the function that
computes the time (using the current, now and duration variables) to only call
time.Now() when now is nil: set current from now().UTC() if now != nil,
otherwise set current to time.Now().UTC(), then return current.Add(-duration),
nil. This removes the unnecessary unconditional time.Now() invocation while
preserving behavior.
In `@internal/cli/client_test.go`:
- Around line 411-676: The single large TestUnixSocketClientAutomationMethods
should be split into focused subtests using t.Run("Should ...") for each
operation so failures are isolated; refactor the test body into multiple
subtests that each exercise one client method or logical group (e.g. "Should
list jobs" -> ListAutomationJobs, "Should create job" ->
CreateAutomationJob/GetAutomationJob/UpdateAutomationJob/DeleteAutomationJob,
"Should trigger and list job runs" -> TriggerAutomationJob/AutomationJobRuns,
"Should manage triggers" ->
ListAutomationTriggers/CreateAutomationTrigger/GetAutomationTrigger/UpdateAutomationTrigger/AutomationTriggerRuns/DeleteAutomationTrigger,
and "Should list and get runs" -> ListAutomationRuns/GetAutomationRun), keep the
same request mock behavior and assertions but move them into the appropriate
t.Run blocks, sharing the same test httpClient setup and ctx while ensuring each
subtest calls t.Parallel() only where safe.
In `@internal/config/automation.go`:
- Around line 255-281: The toAutomationTrigger method
(parsedAutomationTrigger.toAutomationTrigger) currently returns an error but
never produces one; remove the unused error return from its signature and update
all callers to expect only (AutomationTrigger) instead of (AutomationTrigger,
error); alternatively, if you prefer to keep the error return for future
validation, add appropriate validation logic that can return a non-nil error
before the final return—ensure consistency with toAutomationJob's approach and
update references to trigger := parsedAutomationTrigger.toAutomationTrigger(...)
accordingly.
- Around line 227-253: The function parsedAutomationJob.toAutomationJob declares
an error return but never returns a non-nil error; either remove the error from
the signature or implement validation that can produce meaningful errors. If you
choose to simplify, change toAutomationJob to return only (AutomationJob) and
update all callers to stop expecting an error; if you choose to keep it for
future extensibility, add input validation (e.g., validate required fields like
Name, Scope, AgentName, Prompt, Schedule) inside toAutomationJob and return a
descriptive error when validation fails so the error return is used
consistently. Ensure you update all references to
parsedAutomationJob.toAutomationJob or toAutomationJob accordingly.
🪄 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: 587e0339-c0e2-4e67-b7f2-7b9f7b7bd2ac
⛔ Files ignored due to path filters (28)
.compozy/tasks/automation/_meta.mdis excluded by!**/*.md.compozy/tasks/automation/_tasks.mdis excluded by!**/*.md.compozy/tasks/automation/memory/MEMORY.mdis excluded by!**/*.md.compozy/tasks/automation/memory/task_01.mdis excluded by!**/*.md.compozy/tasks/automation/memory/task_02.mdis excluded by!**/*.md.compozy/tasks/automation/memory/task_03.mdis excluded by!**/*.md.compozy/tasks/automation/memory/task_04.mdis excluded by!**/*.md.compozy/tasks/automation/memory/task_05.mdis excluded by!**/*.md.compozy/tasks/automation/memory/task_06.mdis excluded by!**/*.md.compozy/tasks/automation/memory/task_07.mdis excluded by!**/*.md.compozy/tasks/automation/memory/task_08.mdis excluded by!**/*.md.compozy/tasks/automation/memory/task_09.mdis excluded by!**/*.md.compozy/tasks/automation/memory/task_10.mdis excluded by!**/*.md.compozy/tasks/automation/task_01.mdis excluded by!**/*.md.compozy/tasks/automation/task_02.mdis excluded by!**/*.md.compozy/tasks/automation/task_03.mdis excluded by!**/*.md.compozy/tasks/automation/task_04.mdis excluded by!**/*.md.compozy/tasks/automation/task_05.mdis excluded by!**/*.md.compozy/tasks/automation/task_06.mdis excluded by!**/*.md.compozy/tasks/automation/task_07.mdis excluded by!**/*.md.compozy/tasks/automation/task_08.mdis excluded by!**/*.md.compozy/tasks/automation/task_09.mdis excluded by!**/*.md.compozy/tasks/automation/task_10.mdis excluded by!**/*.mdbun.lockis excluded by!**/*.lockgo.sumis excluded by!**/*.sumopenapi/agh.jsonis excluded by!**/*.jsonsdk/typescript/src/generated/contracts.tsis excluded by!**/generated/**web/src/generated/agh-openapi.d.tsis excluded by!**/generated/**
📒 Files selected for processing (123)
go.modinternal/api/contract/automation.gointernal/api/contract/contract_test.gointernal/api/contract/responses.gointernal/api/core/automation.gointernal/api/core/automation_test.gointernal/api/core/conversions.gointernal/api/core/errors.gointernal/api/core/handlers.gointernal/api/core/interfaces.gointernal/api/core/test_helpers_test.gointernal/api/httpapi/handlers.gointernal/api/httpapi/handlers_test.gointernal/api/httpapi/helpers_test.gointernal/api/httpapi/httpapi_integration_test.gointernal/api/httpapi/routes.gointernal/api/httpapi/server.gointernal/api/spec/spec.gointernal/api/spec/spec_test.gointernal/api/testutil/apitest.gointernal/api/udsapi/handlers_test.gointernal/api/udsapi/helpers_test.gointernal/api/udsapi/routes.gointernal/api/udsapi/server.gointernal/api/udsapi/udsapi_integration_test.gointernal/automation/dispatch.gointernal/automation/dispatch_hooks_test.gointernal/automation/dispatch_integration_test.gointernal/automation/dispatch_test.gointernal/automation/doc.gointernal/automation/extension.gointernal/automation/extension_test.gointernal/automation/manager.gointernal/automation/manager_test.gointernal/automation/model/doc.gointernal/automation/model/persistence.gointernal/automation/model/template.gointernal/automation/model/types.gointernal/automation/model/validate.gointernal/automation/persistence.gointernal/automation/schedule.gointernal/automation/schedule_integration_test.gointernal/automation/schedule_test.gointernal/automation/template.gointernal/automation/template_test.gointernal/automation/trigger.gointernal/automation/trigger_integration_test.gointernal/automation/trigger_test.gointernal/automation/types.gointernal/automation/validate.gointernal/automation/validate_test.gointernal/cli/automation.gointernal/cli/automation_test.gointernal/cli/cli_integration_test.gointernal/cli/client.gointernal/cli/client_test.gointernal/cli/helpers_test.gointernal/cli/root.gointernal/config/automation.gointernal/config/automation_integration_test.gointernal/config/automation_test.gointernal/config/config.gointernal/config/merge.gointernal/daemon/boot.gointernal/daemon/daemon.gointernal/daemon/daemon_integration_test.gointernal/daemon/daemon_test.gointernal/daemon/hooks_bridge.gointernal/extension/capability.gointernal/extension/capability_test.gointernal/extension/contract/host_api.gointernal/extension/contract/host_api_test.gointernal/extension/contract/sdk.gointernal/extension/host_api.gointernal/extension/host_api_integration_test.gointernal/extension/host_api_test.gointernal/extension/protocol/host_api.gointernal/extension/protocol/host_api_test.gointernal/hooks/dispatch.gointernal/hooks/events.gointernal/hooks/events_test.gointernal/hooks/introspection.gointernal/hooks/introspection_test.gointernal/hooks/matcher.gointernal/hooks/matcher_test.gointernal/hooks/payloads.gointernal/hooks/payloads_test.gointernal/observe/hooks_test.gointernal/store/globaldb/global_db.gointernal/store/globaldb/global_db_automation.gointernal/store/globaldb/global_db_automation_integration_test.gointernal/store/globaldb/global_db_automation_test.goweb/src/components/app-sidebar.test.tsxweb/src/components/app-sidebar.tsxweb/src/routeTree.gen.tsweb/src/routes/_app/-automation.integration.test.tsxweb/src/routes/_app/automation.tsxweb/src/systems/automation/adapters/automation-api.test.tsweb/src/systems/automation/adapters/automation-api.tsweb/src/systems/automation/components/automation-detail-panel.test.tsxweb/src/systems/automation/components/automation-detail-panel.tsxweb/src/systems/automation/components/automation-form-primitives.tsxweb/src/systems/automation/components/automation-job-form.test.tsxweb/src/systems/automation/components/automation-job-form.tsxweb/src/systems/automation/components/automation-list-panel.test.tsxweb/src/systems/automation/components/automation-list-panel.tsxweb/src/systems/automation/components/automation-run-history.tsxweb/src/systems/automation/components/automation-trigger-form.test.tsxweb/src/systems/automation/components/automation-trigger-form.tsxweb/src/systems/automation/hooks/use-automation-actions.test.tsxweb/src/systems/automation/hooks/use-automation-actions.tsweb/src/systems/automation/hooks/use-automation.test.tsxweb/src/systems/automation/hooks/use-automation.tsweb/src/systems/automation/index.tsweb/src/systems/automation/lib/automation-drafts.test.tsweb/src/systems/automation/lib/automation-drafts.tsweb/src/systems/automation/lib/automation-formatters.test.tsweb/src/systems/automation/lib/automation-formatters.tsweb/src/systems/automation/lib/query-keys.test.tsweb/src/systems/automation/lib/query-keys.tsweb/src/systems/automation/lib/query-options.test.tsweb/src/systems/automation/lib/query-options.tsweb/src/systems/automation/types.ts
There was a problem hiding this comment.
Actionable comments posted: 7
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@internal/api/contract/contract_test.go`:
- Around line 159-275: The new tests (TestAutomationJobPayloadJSONShape,
TestAutomationTriggerPayloadJSONShape, TestAutomationUpdateRequestsHasChanges)
must be refactored to use t.Run subtests with the "Should..." naming convention
and table-driven style: wrap each assertion block in a t.Run("Should ...") call
(e.g., t.Run("Should marshal next_run and scope for JobPayload") and
t.Run("Should include endpoint_slug and webhook_id for TriggerPayload")), and
convert TestAutomationUpdateRequestsHasChanges into a table-driven test where
each case contains an input (e.g., contract.UpdateJobRequest{Name: &name}) and
expected bool, looping over cases and calling t.Run("Should ...", func(t
*testing.T){ ... assert case.HasChanges() == expected }), keeping existing
helpers like marshalJSON and referencing the same types (contract.JobPayload,
contract.TriggerPayload, contract.UpdateJobRequest/UpdateTriggerRequest) and
fields to locate the code.
In `@internal/api/core/automation.go`:
- Around line 86-92: The call to h.automationNextRunByJobID (used after
persisting a job in the create/update handlers) must be treated as best-effort
so its failure doesn't turn a successful write into an error response; update
the code around the call (the block that assigns nextRunByID and currently
returns on err) to instead log the error (or use h.logger) and set nextRunByID
to nil/empty so JobPayloadFromJob/timePointerFromMap receives nil for next_run;
apply the same change for the second occurrence (the similar block around lines
161-167) to ensure manager.Status()/automationNextRunByJobID errors are
non-fatal and the handler still returns the created/updated job with
next_run=null.
In `@internal/api/core/errors.go`:
- Around line 96-128: StatusForAutomationError currently falls through to 500
for two expected domain sentinels; add explicit mappings: detect
automationpkg.ErrWebhookSecretRequired with errors.Is and return
http.StatusBadRequest, and detect automationpkg.ErrDefinitionReadOnly with
errors.Is and return http.StatusConflict. Update the switch in
StatusForAutomationError to include these two cases (using errors.Is checks)
before the default branch so user/config validation errors produce 400/409
instead of 500.
In `@internal/automation/manager.go`:
- Around line 314-316: The NewDispatcher constructor error is returned raw; wrap
it with context before returning so failures indicate the failing phase. Replace
the bare "return nil, err" after the NewDispatcher(...) call with a wrapped
error like fmt.Errorf("create dispatcher: %w", err). Apply the same pattern to
other constructor/startup error returns in this file (the block around lines
1117-1129) so functions such as NewDispatcher and the manager New/Start paths
return errors wrapped with descriptive context using fmt.Errorf("%s: %w", ...).
- Around line 1247-1254: The loop that calls m.store.DeleteJob (and the similar
trigger removal at lines ~1292-1299) only removes base rows and leaves persisted
overlays and webhook secrets behind; replace direct
store.DeleteJob/DeleteTrigger calls with the manager-level deletion routines
that perform full cleanup (e.g., call m.DeleteJob(ctx, id) and
m.DeleteTrigger(ctx, id) or the manager methods that encapsulate overlay and
secret removal) so overlays and trigger secrets are explicitly removed when
config-backed definitions disappear. Ensure the removed++ accounting stays
correct and propagate errors from the manager-level calls as before.
In `@internal/automation/model/template.go`:
- Around line 146-152: The validation currently returns nil when
templateFieldPath(args[0]) fails or yields an empty path, allowing unsupported
index targets to slip through; change the early return so it returns the same
kind of error as the subsequent check. Specifically, in the block that calls
templateFieldPath (the variables path, ok), replace the "return nil" with a
formatted error (using fmt.Errorf) indicating the unsupported index target and
that only .Data is allowed (use dottedPath(path) or args[0] to populate the %q),
so both failure-to-normalize and empty-path cases are rejected consistently
before the later path[0] check.
In `@internal/automation/trigger.go`:
- Around line 415-420: The current flow calls
e.claimWebhookDelivery(registration.Trigger.ID, request.DeliveryID) before
dispatchMatches, causing a permanent claim even if dispatch fails; change to
either (A) make the claim "in-flight" and finalize it only after dispatchMatches
returns successfully (e.g., call a finalizeClaim/confirmClaim method after
dispatch), or (B) keep the existing claim but immediately release/rollback it if
dispatchMatches returns an error (e.g., call an unclaim/release method in the
error path). Update the logic around webhookEnvelope(...) and
e.dispatchMatches(...) so the delivery ID is only permanently marked claimed
after a successful dispatch or is explicitly released on dispatch failure; use
the unique symbols e.claimWebhookDelivery, e.dispatchMatches, webhookEnvelope,
TriggerRegistration and ensure TriggerResult error paths unclaim when needed.
🪄 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: 13015e78-7de3-4866-bc59-01a890737727
⛔ Files ignored due to path filters (26)
.compozy/tasks/automation/reviews-001/_meta.mdis excluded by!**/*.md.compozy/tasks/automation/reviews-001/issue_001.mdis excluded by!**/*.md.compozy/tasks/automation/reviews-001/issue_002.mdis excluded by!**/*.md.compozy/tasks/automation/reviews-001/issue_003.mdis excluded by!**/*.md.compozy/tasks/automation/reviews-001/issue_004.mdis excluded by!**/*.md.compozy/tasks/automation/reviews-001/issue_005.mdis excluded by!**/*.md.compozy/tasks/automation/reviews-001/issue_006.mdis excluded by!**/*.md.compozy/tasks/automation/reviews-001/issue_007.mdis excluded by!**/*.md.compozy/tasks/automation/reviews-001/issue_008.mdis excluded by!**/*.md.compozy/tasks/automation/reviews-001/issue_009.mdis excluded by!**/*.md.compozy/tasks/automation/reviews-001/issue_010.mdis excluded by!**/*.md.compozy/tasks/automation/reviews-001/issue_011.mdis excluded by!**/*.md.compozy/tasks/automation/reviews-001/issue_012.mdis excluded by!**/*.md.compozy/tasks/automation/reviews-001/issue_013.mdis excluded by!**/*.md.compozy/tasks/automation/reviews-001/issue_014.mdis excluded by!**/*.md.compozy/tasks/automation/reviews-001/issue_015.mdis excluded by!**/*.md.compozy/tasks/automation/reviews-001/issue_016.mdis excluded by!**/*.md.compozy/tasks/automation/reviews-001/issue_017.mdis excluded by!**/*.md.compozy/tasks/automation/reviews-001/issue_018.mdis excluded by!**/*.md.compozy/tasks/automation/reviews-001/issue_019.mdis excluded by!**/*.md.compozy/tasks/automation/reviews-001/issue_020.mdis excluded by!**/*.md.compozy/tasks/automation/reviews-001/issue_021.mdis excluded by!**/*.md.compozy/tasks/automation/reviews-001/issue_022.mdis excluded by!**/*.md.compozy/tasks/automation/reviews-001/issue_023.mdis excluded by!**/*.md.compozy/tasks/automation/reviews-001/issue_024.mdis excluded by!**/*.md.compozy/tasks/automation/reviews-001/issue_025.mdis excluded by!**/*.md
📒 Files selected for processing (23)
internal/api/contract/contract_test.gointernal/api/core/automation.gointernal/api/core/automation_test.gointernal/api/core/errors.gointernal/api/httpapi/httpapi_integration_test.gointernal/api/testutil/apitest.gointernal/api/udsapi/udsapi_integration_test.gointernal/automation/dispatch.gointernal/automation/dispatch_test.gointernal/automation/extension.gointernal/automation/extension_test.gointernal/automation/manager.gointernal/automation/manager_test.gointernal/automation/model/template.gointernal/automation/trigger.gointernal/automation/trigger_integration_test.gointernal/automation/trigger_test.gointernal/automation/validate_test.gointernal/cli/automation.gointernal/cli/automation_test.gointernal/cli/cli_integration_test.gointernal/cli/client_test.gointernal/config/automation.go
✅ Files skipped from review due to trivial changes (4)
- internal/automation/extension_test.go
- internal/api/core/automation_test.go
- internal/automation/validate_test.go
- internal/automation/dispatch.go
🚧 Files skipped from review as they are similar to previous changes (5)
- internal/api/udsapi/udsapi_integration_test.go
- internal/automation/extension.go
- internal/automation/trigger_integration_test.go
- internal/api/testutil/apitest.go
- internal/automation/dispatch_test.go
There was a problem hiding this comment.
Actionable comments posted: 5
🧹 Nitpick comments (7)
internal/api/contract/contract_test.go (1)
267-287: ExpandHasChanges()cases to cover all mutable fields.Current cases are valid, but they only sample a subset of mutable fields. Adding one positive case per mutable field would make regressions in
HasChanges()much harder to miss.As per coding guidelines, `**/*_test.go`: "MUST test meaningful business logic, not trivial operations" and "Must Check: Focus on critical paths: workflow execution, state management, error handling".Suggested test expansion (pattern)
testCases := []struct { name string req contract.UpdateJobRequest want bool }{ { name: "Should return false for an empty job update", req: contract.UpdateJobRequest{}, want: false, }, { name: "Should return true when the job name is set", req: contract.UpdateJobRequest{Name: &name}, want: true, }, + { + name: "Should return true when the agent name is set", + req: contract.UpdateJobRequest{AgentName: &name}, + want: true, + }, + { + name: "Should return true when the workspace ID is set", + req: contract.UpdateJobRequest{WorkspaceID: &name}, + want: true, + }, + // ...add Prompt, Schedule, Retry, FireLimit { name: "Should return true when the job enabled flag is set", req: contract.UpdateJobRequest{Enabled: &disabled}, want: true, }, }testCases := []struct { name string req contract.UpdateTriggerRequest want bool }{ { name: "Should return false for an empty trigger update", req: contract.UpdateTriggerRequest{}, want: false, }, { name: "Should return true when the webhook secret is set", req: contract.UpdateTriggerRequest{WebhookSecret: &secret}, want: true, }, + { + name: "Should return true when event is set", + req: contract.UpdateTriggerRequest{Event: &name}, + want: true, + }, + { + name: "Should return true when webhook ID is set", + req: contract.UpdateTriggerRequest{WebhookID: &name}, + want: true, + }, + // ...add Name, AgentName, WorkspaceID, Prompt, Filter, Retry, FireLimit, EndpointSlug { name: "Should return true when the trigger enabled flag is set", req: contract.UpdateTriggerRequest{Enabled: &disabled}, want: true, }, }Also applies to: 304-324
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@internal/api/contract/contract_test.go` around lines 267 - 287, The HasChanges() tests only cover Name and Enabled; add one positive test case per mutable field on contract.UpdateJobRequest so HasChanges() is exercised for every updatable property (e.g., Schedule, Metadata, RuntimeVersion, BackoffPolicy, Resources — use the actual mutable field names present in UpdateJobRequest) and keep the existing empty-request and other positives; update the testCases slice in contract_test.go to include a case for each field (referencing UpdateJobRequest and HasChanges()) that sets that single field and expects want: true, ensuring each mutable field change is asserted.internal/automation/manager_test.go (6)
663-664: Missingt.Parallel()declaration.Same issue as
TestManagerHandleWebhookWithSecretResolver- this test should declaret.Parallel()for consistency with other tests in the file.As per coding guidelines: "Use t.Parallel() for independent subtests in Go tests".
Proposed fix
func TestManagerHandleWebhookWithConfigSecretEnv(t *testing.T) { + t.Parallel() + h := newManagerHarness(t)🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@internal/automation/manager_test.go` around lines 663 - 664, The test TestManagerHandleWebhookWithConfigSecretEnv is missing t.Parallel(); add a call to t.Parallel() as the first statement inside the test function (similar to TestManagerHandleWebhookWithSecretResolver) to mark it as an independent parallelizable test; locate the function TestManagerHandleWebhookWithConfigSecretEnv and insert t.Parallel() immediately after the existing t := newManagerHarness(t) setup or at the top of the function body per file convention.
840-842: Constructor test checks only!= nilwithout verifying meaningful state.This assertion only verifies the ID is non-empty, which is a weak test. Consider asserting on meaningful business properties like
Source,Scope, orWorkspaceIDthat confirm correct initialization.As per coding guidelines: "Constructor tests that only check != nil" is listed as an anti-pattern to reject.
Proposed enhancement
if created.ID == "" { t.Fatal("manager.CreateJob() id = empty, want non-empty") } + if got, want := created.Source, JobSourceDynamic; got != want { + t.Fatalf("manager.CreateJob() source = %q, want %q", got, want) + } + if got, want := created.WorkspaceID, h.workspace.ID; got != want { + t.Fatalf("manager.CreateJob() workspace_id = %q, want %q", got, want) + }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@internal/automation/manager_test.go` around lines 840 - 842, The test currently only checks created.ID is non-empty after calling manager.CreateJob(), which is too weak; extend the assertions to verify meaningful fields on the returned job (e.g., check created.Source, created.Scope, created.WorkspaceID and any other business-critical fields set by CreateJob or the Job constructor) to ensure correct initialization, and assert their expected values (non-empty or specific expected constants) alongside the existing ID check so the constructor behavior is validated beyond nil/empty ID.
590-591: Missingt.Parallel()declaration.This test modifies environment variables with
t.Setenv()but doesn't callt.Parallel(). Whilet.Setenv()is safe in parallel tests (it automatically marks the test as incompatible with parallel execution), the missingt.Parallel()is inconsistent with other tests in this file.As per coding guidelines: "Use t.Parallel() for independent subtests in Go tests".
Proposed fix
func TestManagerHandleWebhookWithSecretResolver(t *testing.T) { + t.Parallel() + h := newManagerHarness(t)🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@internal/automation/manager_test.go` around lines 590 - 591, Add t.Parallel() at the start of the TestManagerHandleWebhookWithSecretResolver test to match other tests and mark it as safe for parallel execution; locate the TestManagerHandleWebhookWithSecretResolver function (which calls newManagerHarness(t) and uses t.Setenv()) and insert t.Parallel() immediately after the function's first line so the test is consistently declared parallel with the rest of the file.
1789-1823: Tests verify trivial helper behavior with minimal business value.This test function verifies nil-safe observer calls and basic sorting — functionality that's unlikely to regress and provides limited confidence in the system. Consider removing these in favor of tests that exercise the helpers through actual business flows, or consolidate them into a single focused helper verification test.
As per coding guidelines: "Getter/setter tests without business logic" and "Tests that verify Go standard library functionality" are anti-patterns to reject.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@internal/automation/manager_test.go` around lines 1789 - 1823, Remove or consolidate the low-value TestManagerObserverNoopsAndSortHelpers test: either delete the entire TestManagerObserverNoopsAndSortHelpers function, or replace it with a single focused helper-verification test that briefly asserts the nil-safe no-op observer calls (managerHookTelemetrySink.WriteHookRecord and managerMemoryObserver.OnMemoryConsolidated) and that the sort helpers (sortJobs and sortTriggers) produce the expected deterministic ordering; keep the minimal assertions only and avoid duplicative checks of standard library behavior.
1128-1137: Error comparison uses string matching instead oferrors.Is().The
assertContextErrorhelper compares error messages usingerr.Error() != want, which is fragile and violates the coding guidelines. Consider using sentinel errors anderrors.Is()for type-safe error matching, or at minimum usestrings.Contains()if the exact message format might change.As per coding guidelines: "Use errors.Is() and errors.As() for error matching — never compare error strings".
Alternative approach using strings.Contains
assertContextError := func(name string, err error, want string) { t.Helper() if err == nil { t.Fatalf("%s error = nil, want %q", name, want) } - if err.Error() != want { + if !strings.Contains(err.Error(), want) { t.Fatalf("%s error = %q, want %q", name, err.Error(), want) } }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@internal/automation/manager_test.go` around lines 1128 - 1137, The helper assertContextError currently compares error text using err.Error() != want which is fragile; update assertContextError (used alongside nilContextForTests) to accept a target error value instead of a string and use errors.Is(err, target) for comparison (or, if a sentinel error is not available, use strings.Contains(err.Error(), wantSubstring)); adjust all calls to assertContextError to pass the sentinel/target error (or substring) so tests use errors.Is/errors.Contains rather than direct string equality.
25-127: Consider using table-driven subtests for improved test organization.This test and others in the file use a flat structure without
t.Run()subtests. While the test logic is sound, the coding guidelines require usingt.Run("Should...")pattern. This would improve:
- Test output readability (each subtest is named)
- Ability to run specific scenarios in isolation
- Failure localization
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/automation/manager_test.go` around lines 25 - 127, Split TestManagerStartSyncsConfigDefinitionsAndPreservesDynamicEntries into named t.Run subtests: wrap setup and each assertion group (e.g., "starts manager and preserves dynamic jobs", "config job resolved and marked JobSourceConfig", "triggers preserved and config trigger resolved") in separate t.Run blocks so failures are localized; keep shared setup (newManagerHarness, creating dynamicJob/dynamicTrigger, manager.Start, and cleanup) in the parent test body and move only the related checks into their respective t.Run closures, referencing the existing functions and methods like manager.Start, manager.Jobs, manager.Triggers, resolveConfigJob, and resolveConfigTrigger to locate the assertions to move.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@internal/api/core/errors.go`:
- Around line 97-131: StatusForAutomationError currently falls through for
automationpkg.ErrWebhookEndpointInvalid and returns 500; update the function
(StatusForAutomationError) to map automationpkg.ErrWebhookEndpointInvalid to
http.StatusBadRequest (400). Add errors.Is(err,
automationpkg.ErrWebhookEndpointInvalid) into the BadRequest branch (the same
branch that handles ErrAutomationValidation and
automationpkg.ErrWebhookSecretRequired) or add a dedicated case returning
http.StatusBadRequest so malformed webhook endpoint input is treated as a client
error.
In `@internal/api/testutil/apitest.go`:
- Line 618: Change the compile-time interface assertion from a value literal to
the pointer-form pattern: replace the line setting var _ core.AutomationManager
= StubAutomationManager{} with var _ core.AutomationManager =
(*StubAutomationManager)(nil) so the interface compliance check uses a nil
pointer to StubAutomationManager instead of a value.
In `@internal/automation/model/template.go`:
- Around line 26-27: The calls that return raw errors from validateTemplateNode
(e.g., the check using validateTemplateNode(subtemplate.Root)) should wrap the
propagated error with local context before returning so callers know where
validation failed; update the return paths to use fmt.Errorf with descriptive
context (for example: "validate template root: %w") and apply the same wrapping
pattern to the other similar return(s) around the template validation checks
(referencing validateTemplateNode and subtemplate.Root).
- Line 85: The field/chain validation in validateTemplateNodeWithState is using
unscoped paths; change those checks to use scopedTemplateFieldPath (the same
helper used in validateIndexArgs) so lookups inside a {{with .Data}} are
resolved relative to the current dot (e.g., `.foo` -> `.Data.foo`). Also update
the two call sites that currently propagate validation errors directly (the
returns that do `return err`) to wrap the error with context using
fmt.Errorf("validate template: %w", err) (or equivalent) so validation failures
include caller context instead of raw errors.
In `@internal/automation/trigger.go`:
- Around line 384-390: The FireHookCompletion method should validate that ctx is
non-nil before calling hookCompletionEnvelope to prevent a nil-context from
reaching HookSessionResolver.Status; modify TriggerEngine.FireHookCompletion to
check if ctx == nil and return a clear error (e.g., fmt.Errorf("nil context") or
a package-specific error) before invoking hookCompletionEnvelope or Fire so the
early guard protects downstream calls.
---
Nitpick comments:
In `@internal/api/contract/contract_test.go`:
- Around line 267-287: The HasChanges() tests only cover Name and Enabled; add
one positive test case per mutable field on contract.UpdateJobRequest so
HasChanges() is exercised for every updatable property (e.g., Schedule,
Metadata, RuntimeVersion, BackoffPolicy, Resources — use the actual mutable
field names present in UpdateJobRequest) and keep the existing empty-request and
other positives; update the testCases slice in contract_test.go to include a
case for each field (referencing UpdateJobRequest and HasChanges()) that sets
that single field and expects want: true, ensuring each mutable field change is
asserted.
In `@internal/automation/manager_test.go`:
- Around line 663-664: The test TestManagerHandleWebhookWithConfigSecretEnv is
missing t.Parallel(); add a call to t.Parallel() as the first statement inside
the test function (similar to TestManagerHandleWebhookWithSecretResolver) to
mark it as an independent parallelizable test; locate the function
TestManagerHandleWebhookWithConfigSecretEnv and insert t.Parallel() immediately
after the existing t := newManagerHarness(t) setup or at the top of the function
body per file convention.
- Around line 840-842: The test currently only checks created.ID is non-empty
after calling manager.CreateJob(), which is too weak; extend the assertions to
verify meaningful fields on the returned job (e.g., check created.Source,
created.Scope, created.WorkspaceID and any other business-critical fields set by
CreateJob or the Job constructor) to ensure correct initialization, and assert
their expected values (non-empty or specific expected constants) alongside the
existing ID check so the constructor behavior is validated beyond nil/empty ID.
- Around line 590-591: Add t.Parallel() at the start of the
TestManagerHandleWebhookWithSecretResolver test to match other tests and mark it
as safe for parallel execution; locate the
TestManagerHandleWebhookWithSecretResolver function (which calls
newManagerHarness(t) and uses t.Setenv()) and insert t.Parallel() immediately
after the function's first line so the test is consistently declared parallel
with the rest of the file.
- Around line 1789-1823: Remove or consolidate the low-value
TestManagerObserverNoopsAndSortHelpers test: either delete the entire
TestManagerObserverNoopsAndSortHelpers function, or replace it with a single
focused helper-verification test that briefly asserts the nil-safe no-op
observer calls (managerHookTelemetrySink.WriteHookRecord and
managerMemoryObserver.OnMemoryConsolidated) and that the sort helpers (sortJobs
and sortTriggers) produce the expected deterministic ordering; keep the minimal
assertions only and avoid duplicative checks of standard library behavior.
- Around line 1128-1137: The helper assertContextError currently compares error
text using err.Error() != want which is fragile; update assertContextError (used
alongside nilContextForTests) to accept a target error value instead of a string
and use errors.Is(err, target) for comparison (or, if a sentinel error is not
available, use strings.Contains(err.Error(), wantSubstring)); adjust all calls
to assertContextError to pass the sentinel/target error (or substring) so tests
use errors.Is/errors.Contains rather than direct string equality.
- Around line 25-127: Split
TestManagerStartSyncsConfigDefinitionsAndPreservesDynamicEntries into named
t.Run subtests: wrap setup and each assertion group (e.g., "starts manager and
preserves dynamic jobs", "config job resolved and marked JobSourceConfig",
"triggers preserved and config trigger resolved") in separate t.Run blocks so
failures are localized; keep shared setup (newManagerHarness, creating
dynamicJob/dynamicTrigger, manager.Start, and cleanup) in the parent test body
and move only the related checks into their respective t.Run closures,
referencing the existing functions and methods like manager.Start, manager.Jobs,
manager.Triggers, resolveConfigJob, and resolveConfigTrigger to locate the
assertions to move.
🪄 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: 801b8957-6c2d-4c30-955d-210dc3b449d3
⛔ Files ignored due to path filters (16)
.agents/skills/cy-idea-factory/SKILL.mdis excluded by!**/*.md,!.agents/**.agents/skills/cy-idea-factory/references/council.mdis excluded by!**/*.md,!.agents/**.agents/skills/tmux/SKILL.mdis excluded by!**/*.md,!.agents/**.agents/skills/tmux/scripts/find-sessions.shis excluded by!.agents/**.agents/skills/tmux/scripts/wait-for-text.shis excluded by!.agents/**.compozy/tasks/automation/_techspec.mdis excluded by!**/*.md.compozy/tasks/automation/qa/review_001.mdis excluded by!**/*.md.compozy/tasks/automation/reviews-002/_meta.mdis excluded by!**/*.md.compozy/tasks/automation/reviews-002/issue_001.mdis excluded by!**/*.md.compozy/tasks/automation/reviews-002/issue_002.mdis excluded by!**/*.md.compozy/tasks/automation/reviews-002/issue_003.mdis excluded by!**/*.md.compozy/tasks/automation/reviews-002/issue_004.mdis excluded by!**/*.md.compozy/tasks/automation/reviews-002/issue_005.mdis excluded by!**/*.md.compozy/tasks/automation/reviews-002/issue_006.mdis excluded by!**/*.md.compozy/tasks/automation/reviews-002/issue_007.mdis excluded by!**/*.mdskills-lock.jsonis excluded by!**/*.json
📒 Files selected for processing (20)
internal/api/contract/contract_test.gointernal/api/core/automation.gointernal/api/core/automation_test.gointernal/api/core/errors.gointernal/api/core/interfaces.gointernal/api/testutil/apitest.gointernal/automation/dispatch.gointernal/automation/dispatch_test.gointernal/automation/manager.gointernal/automation/manager_test.gointernal/automation/model/template.gointernal/automation/template_test.gointernal/automation/trigger.gointernal/automation/trigger_test.gointernal/config/automation.gointernal/config/automation_test.gointernal/session/session.gointernal/session/stop_cause.gointernal/session/stop_reason.gointernal/session/stop_reason_test.go
✅ Files skipped from review due to trivial changes (3)
- internal/automation/template_test.go
- internal/automation/dispatch.go
- internal/automation/manager.go
🚧 Files skipped from review as they are similar to previous changes (4)
- internal/api/core/interfaces.go
- internal/api/core/automation_test.go
- internal/automation/dispatch_test.go
- internal/api/core/automation.go
There was a problem hiding this comment.
🧹 Nitpick comments (4)
internal/automation/manager_test.go (4)
1301-1307: Consider simplifying the error check condition.The double-negative condition
!errors.Is(err, ...) && err != nilis harder to parse. This could be inverted for clarity.Suggested fix
resolvedSecret, err := resolver.SecretForTrigger(h.ctx, webhookTrigger) - if !errors.Is(err, ErrTriggerWebhookSecretNotFound) && err != nil { - t.Fatalf("storeWebhookSecretResolver.SecretForTrigger() error = %v", err) + if err != nil && !errors.Is(err, ErrTriggerWebhookSecretNotFound) { + t.Fatalf("storeWebhookSecretResolver.SecretForTrigger() unexpected error = %v", err) }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@internal/automation/manager_test.go` around lines 1301 - 1307, Invert and simplify the error check in the test: instead of the double-negative `!errors.Is(err, ErrTriggerWebhookSecretNotFound) && err != nil`, reorder to first check `err != nil` and then `!errors.Is(err, ErrTriggerWebhookSecretNotFound)` (or explicitly branch: if errors.Is(err, ErrTriggerWebhookSecretNotFound) { /* expected */ } else if err != nil { t.Fatalf... }) when calling resolver.SecretForTrigger; update the condition surrounding resolver.SecretForTrigger(h.ctx, webhookTrigger) and the subsequent t.Fatalf to use this clearer logic referencing resolver.SecretForTrigger and ErrTriggerWebhookSecretNotFound.
590-591: Missingt.Parallel()call.This test function is missing the
t.Parallel()call that's present in most other tests in this file. Sincet.Setenv(line 592) is used, ensure Go 1.17+ is the minimum version, ast.Setenvcombined witht.Parallel()is safe from that version onwards.Suggested fix
func TestManagerHandleWebhookWithSecretResolver(t *testing.T) { + t.Parallel() + h := newManagerHarness(t)As per coding guidelines: "Use t.Parallel() for independent subtests in Go tests"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@internal/automation/manager_test.go` around lines 590 - 591, TestManagerHandleWebhookWithSecretResolver is missing a t.Parallel() call; update the test by adding t.Parallel() near the start of TestManagerHandleWebhookWithSecretResolver (before calling newManagerHarness) so the test runs in parallel like the others—ensure this is compatible with the existing use of t.Setenv in the test.
663-664: Missingt.Parallel()call.Same issue as the previous webhook test—this test is missing
t.Parallel().Suggested fix
func TestManagerHandleWebhookWithConfigSecretEnv(t *testing.T) { + t.Parallel() + h := newManagerHarness(t)As per coding guidelines: "Use t.Parallel() for independent subtests in Go tests"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@internal/automation/manager_test.go` around lines 663 - 664, The test function TestManagerHandleWebhookWithConfigSecretEnv is missing t.Parallel(); add a call to t.Parallel() as the first statement inside the TestManagerHandleWebhookWithConfigSecretEnv function (before calling newManagerHarness or other setup) so the test runs in parallel with other independent tests.
1140-1149: Fragile exact error string comparison.The
assertContextErrorhelper uses exact string comparison (err.Error() != want) which is brittle—error messages may change without breaking functionality. Consider usingstrings.Containsto check for key substrings instead.Suggested fix
assertContextError := func(name string, err error, want string) { t.Helper() if err == nil { t.Fatalf("%s error = nil, want %q", name, want) } - if err.Error() != want { + if !strings.Contains(err.Error(), want) { t.Fatalf("%s error = %q, want %q", name, err.Error(), want) } }As per coding guidelines: "MUST have specific error assertions (ErrorContains, ErrorAs)" and "never compare error strings"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@internal/automation/manager_test.go` around lines 1140 - 1149, The helper assertContextError currently compares error strings exactly which is brittle; update assertContextError to assert that the actual error contains the expected substring (using strings.Contains(err.Error(), want)) or, where a specific error type is intended, use errors.Is/errors.As to match the error type instead of string equality; update the helper (assertContextError) to call t.Fatalf when !strings.Contains(...) (and add the strings import) or to perform errors.Is/errors.As checks as appropriate for each call site.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@internal/automation/manager_test.go`:
- Around line 1301-1307: Invert and simplify the error check in the test:
instead of the double-negative `!errors.Is(err, ErrTriggerWebhookSecretNotFound)
&& err != nil`, reorder to first check `err != nil` and then `!errors.Is(err,
ErrTriggerWebhookSecretNotFound)` (or explicitly branch: if errors.Is(err,
ErrTriggerWebhookSecretNotFound) { /* expected */ } else if err != nil {
t.Fatalf... }) when calling resolver.SecretForTrigger; update the condition
surrounding resolver.SecretForTrigger(h.ctx, webhookTrigger) and the subsequent
t.Fatalf to use this clearer logic referencing resolver.SecretForTrigger and
ErrTriggerWebhookSecretNotFound.
- Around line 590-591: TestManagerHandleWebhookWithSecretResolver is missing a
t.Parallel() call; update the test by adding t.Parallel() near the start of
TestManagerHandleWebhookWithSecretResolver (before calling newManagerHarness) so
the test runs in parallel like the others—ensure this is compatible with the
existing use of t.Setenv in the test.
- Around line 663-664: The test function
TestManagerHandleWebhookWithConfigSecretEnv is missing t.Parallel(); add a call
to t.Parallel() as the first statement inside the
TestManagerHandleWebhookWithConfigSecretEnv function (before calling
newManagerHarness or other setup) so the test runs in parallel with other
independent tests.
- Around line 1140-1149: The helper assertContextError currently compares error
strings exactly which is brittle; update assertContextError to assert that the
actual error contains the expected substring (using
strings.Contains(err.Error(), want)) or, where a specific error type is
intended, use errors.Is/errors.As to match the error type instead of string
equality; update the helper (assertContextError) to call t.Fatalf when
!strings.Contains(...) (and add the strings import) or to perform
errors.Is/errors.As checks as appropriate for each call site.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: b03b0fb1-0dc6-4620-a218-9cc4f2b184f3
⛔ Files ignored due to path filters (13)
.compozy/tasks/automation/reviews-003/_meta.mdis excluded by!**/*.md.compozy/tasks/automation/reviews-003/issue_001.mdis excluded by!**/*.md.compozy/tasks/automation/reviews-003/issue_002.mdis excluded by!**/*.md.compozy/tasks/automation/reviews-003/issue_003.mdis excluded by!**/*.md.compozy/tasks/automation/reviews-003/issue_004.mdis excluded by!**/*.md.compozy/tasks/automation/reviews-003/issue_005.mdis excluded by!**/*.md.compozy/tasks/automation/reviews-003/issue_006.mdis excluded by!**/*.md.compozy/tasks/automation/reviews-003/issue_007.mdis excluded by!**/*.md.compozy/tasks/automation/reviews-003/issue_008.mdis excluded by!**/*.md.compozy/tasks/automation/reviews-003/issue_009.mdis excluded by!**/*.md.compozy/tasks/automation/reviews-003/issue_010.mdis excluded by!**/*.md.compozy/tasks/automation/reviews-003/issue_011.mdis excluded by!**/*.md.compozy/tasks/automation/reviews-003/issue_012.mdis excluded by!**/*.md
📒 Files selected for processing (9)
internal/api/contract/contract_test.gointernal/api/core/automation_test.gointernal/api/core/errors.gointernal/api/testutil/apitest.gointernal/automation/manager_test.gointernal/automation/model/template.gointernal/automation/template_test.gointernal/automation/trigger.gointernal/automation/trigger_test.go
🚧 Files skipped from review as they are similar to previous changes (3)
- internal/api/contract/contract_test.go
- internal/automation/template_test.go
- internal/api/core/automation_test.go
## Release v0.0.1 This PR prepares the release of version v0.0.1. ### Changelog ## 0.0.1 - 2026-05-26 ### Other Changes - Lessons learned ### ♻️ Refactoring - Project structure (#7) - Kb improvements (#12) - Rename spaces to channels (#17) - Add extensions gaps (#21) - Improve tool calls ui (#22) - Remove web app header - Module improvements (#29) - Memory improvements (#35) - Storybook for web and ui (#38) - Enable AGH network by default for new installs (#57) - Hermes adjustments (#69) - Badges design (#84) - Storybook scenario and logos gallery - Migrate typescript tests (#114) - Internal go packages (#120) - Ui patterns (#127) - Improve e2e tests (#130) - Ui redesign - Workspace isolation across runtime surfaces (#145) - Prod ready applies (#162) - Tool card ui (#164) - Alpha on logo - Prod ready features (#167) - Thread sheet (#202) ### 🎉 Features - Implement config foundation packages - Implement sqlite store package - Add ACP client package - Add session lifecycle manager - Implement observe package - Add daemon composition root - Add uds api server - Implement cli package - Add http api server - Add system design - Add foundation types, schemas, and layout shell for web client - Add daemon health polling and agent sidebar systems for web client - Add session system CRUD, streaming core, and session store for web client - Add chat view, messages, and composer tests for web client - Add tool cards and renderers for web client - Add file-backed memory store core - Scaffold memory session seams - Add memory dream consolidation service - Wire memory assembler into daemon - Add memory api and cli - New skills system (#1) - Add workspace entity (#5) - Add new skill capabilities (#8) - Web ui v2 (#9) - Improve hooks system (#10) - Session resilience (#11) - Add extensability (#13) - Add automation (#16) - Add channels (#14) - Add network implementation (#15) - Add network, bridges and automations web pages (#18) - Ext registry (#20) - Add core tasks (#19) - Bridge adapters (#23) - Add site (#26) - Add ext refac and sandbox (#25) - Settings ui (#37) - Tasks ui (#36) - Harness improvements (#44) - Agent capabilities (#49) - Redesign ui (#48) - Unify capability (#53) - Redesign network workspace (#59) - Add task deletion and split session delete from stop (#58) - Session provider selection (#60) - Production grade adjustments (#66) - Autonomous system (#75) - Add agent session route (#80) - Tools registry (#85) - Agents soul (#88) - Add network threads (#105) - Orchestration improvements (#106) - Memory v2 (#108) - Agent categories (#113) - Providers model (#118) - Add canonical AGH bundled skill (#143) - Onboarding and improvements (#198) - Onboarding and improvements (#201) ### 🐛 Bug Fixes - Review round - Review rounds - Resolve memory extensibility review batch - Embed web into daemon - Defaults agents - Acp integration (#4) - Lint errors - Prd folder - Remove orphan web actions and dead surfaces (#55) - Qa testing and fixes (#73) - New review rounds (#82) - Security audit (#90) - Release qa round (#95) - Add missing tools (#141) - New qa round (#147) - Advanced qa round (#149) - Homebrew tap - Final review round (#151) - Daemon healthy - Reasoning models (#158) - Lint errors (#160) - Review round (#168) - Release adjustments (#171) - Stabilize release ci fixtures - Stabilize release integration gate - Stabilize release verify gates - Stabilize release integration flows - Stabilize release verify gates - Stabilize main verify shutdown - Ignore stale acpmock cancel - Marketplace search focus and filtering (#193) - Website video - Workspace command select ### 📚 Documentation - Update agents.md - Update prd - Update skills - Update compozy tasks - Update compozy - Update compozy - Add new skills - Archive prd - Update prds - Update rfc - Update prds - Update prds - Add automation prd - Channels prd - Update prd - Update prd - New prds - Archive prds - Bridges adapters prd - Sandbox prd - Update - Archive prd - Update - Add new prd - New design - Update prd - Archive prds - Update prds - Tasks-ui prd tasks - Update prd - Update design docs - Agent capabilities prd - Improve site docs - Remove old design references - Udpate - Autonomous prd - Update skills - Blog design - Agent sould prd - Final qa plan - Update - Remove codex ledgers from gitignore - Remove not needed files - Udpate ledger - Update cy-codex-loop skill - Orchestration improves prd - Update prds - Orch improvs prd - Memv2 prd - Providers model prd - Update refacs prd - New design proposal - Update rules - Update skills - New blog posts (#173) - Format docs - Remove old design files - Remove old - Skeeper update ### 📦 Build System - Initial structure - Commitlint - Frontend base structure - Update vscode settings - Add subagents - Coderabbit - Prd and tooling - Bun lock - Lint tooling - Copy.md and tooling adjusts - Add repoclone rc - Upgrade skeeper to v0.2.0 - Update go.mod - Adopt task artifacts into skeeper - Sync codex plans with skeeper - Skeeper lock - Skeeper lock - New skills - Skeeper lock - Skeeper lock - Skeeper lock - Update deps and go - Regenerate daytona sidecar assets for go 1.26.3 - Fix cliff - Ignore docs on fmt - Build web assets before goreleaser - Extend release dry-run timeout ### 🔧 CI/CD - Lint errors - Fint release pr - Fix goreleaser ### 🧪 Testing - Add e2e tests (#27) - Qa rounds (#78) - Improve test suite (#138) - Harden daemon-served restart reloads - Harden daemon-served readiness waits - Stabilize dashboard focus assertion - Stabilize release integration gates - Stabilize release e2e markers - Stabilize release e2e flows Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
## Release v0.0.1 This PR prepares the release of version v0.0.1. ### Changelog ## 0.0.1 - 2026-05-26 ### Other Changes - Lessons learned ### ♻️ Refactoring - Project structure (#7) - Kb improvements (#12) - Rename spaces to channels (#17) - Add extensions gaps (#21) - Improve tool calls ui (#22) - Remove web app header - Module improvements (#29) - Memory improvements (#35) - Storybook for web and ui (#38) - Enable AGH network by default for new installs (#57) - Hermes adjustments (#69) - Badges design (#84) - Storybook scenario and logos gallery - Migrate typescript tests (#114) - Internal go packages (#120) - Ui patterns (#127) - Improve e2e tests (#130) - Ui redesign - Workspace isolation across runtime surfaces (#145) - Prod ready applies (#162) - Tool card ui (#164) - Alpha on logo - Prod ready features (#167) - Thread sheet (#202) ### 🎉 Features - Implement config foundation packages - Implement sqlite store package - Add ACP client package - Add session lifecycle manager - Implement observe package - Add daemon composition root - Add uds api server - Implement cli package - Add http api server - Add system design - Add foundation types, schemas, and layout shell for web client - Add daemon health polling and agent sidebar systems for web client - Add session system CRUD, streaming core, and session store for web client - Add chat view, messages, and composer tests for web client - Add tool cards and renderers for web client - Add file-backed memory store core - Scaffold memory session seams - Add memory dream consolidation service - Wire memory assembler into daemon - Add memory api and cli - New skills system (#1) - Add workspace entity (#5) - Add new skill capabilities (#8) - Web ui v2 (#9) - Improve hooks system (#10) - Session resilience (#11) - Add extensability (#13) - Add automation (#16) - Add channels (#14) - Add network implementation (#15) - Add network, bridges and automations web pages (#18) - Ext registry (#20) - Add core tasks (#19) - Bridge adapters (#23) - Add site (#26) - Add ext refac and sandbox (#25) - Settings ui (#37) - Tasks ui (#36) - Harness improvements (#44) - Agent capabilities (#49) - Redesign ui (#48) - Unify capability (#53) - Redesign network workspace (#59) - Add task deletion and split session delete from stop (#58) - Session provider selection (#60) - Production grade adjustments (#66) - Autonomous system (#75) - Add agent session route (#80) - Tools registry (#85) - Agents soul (#88) - Add network threads (#105) - Orchestration improvements (#106) - Memory v2 (#108) - Agent categories (#113) - Providers model (#118) - Add canonical AGH bundled skill (#143) - Onboarding and improvements (#198) - Onboarding and improvements (#201) ### 🐛 Bug Fixes - Review round - Review rounds - Resolve memory extensibility review batch - Embed web into daemon - Defaults agents - Acp integration (#4) - Lint errors - Prd folder - Remove orphan web actions and dead surfaces (#55) - Qa testing and fixes (#73) - New review rounds (#82) - Security audit (#90) - Release qa round (#95) - Add missing tools (#141) - New qa round (#147) - Advanced qa round (#149) - Homebrew tap - Final review round (#151) - Daemon healthy - Reasoning models (#158) - Lint errors (#160) - Review round (#168) - Release adjustments (#171) - Stabilize release ci fixtures - Stabilize release integration gate - Stabilize release verify gates - Stabilize release integration flows - Stabilize release verify gates - Stabilize main verify shutdown - Ignore stale acpmock cancel - Marketplace search focus and filtering (#193) - Website video - Workspace command select ### 📚 Documentation - Update agents.md - Update prd - Update skills - Update compozy tasks - Update compozy - Update compozy - Add new skills - Archive prd - Update prds - Update rfc - Update prds - Update prds - Add automation prd - Channels prd - Update prd - Update prd - New prds - Archive prds - Bridges adapters prd - Sandbox prd - Update - Archive prd - Update - Add new prd - New design - Update prd - Archive prds - Update prds - Tasks-ui prd tasks - Update prd - Update design docs - Agent capabilities prd - Improve site docs - Remove old design references - Udpate - Autonomous prd - Update skills - Blog design - Agent sould prd - Final qa plan - Update - Remove codex ledgers from gitignore - Remove not needed files - Udpate ledger - Update cy-codex-loop skill - Orchestration improves prd - Update prds - Orch improvs prd - Memv2 prd - Providers model prd - Update refacs prd - New design proposal - Update rules - Update skills - New blog posts (#173) - Format docs - Remove old design files - Remove old - Skeeper update ### 📦 Build System - Initial structure - Commitlint - Frontend base structure - Update vscode settings - Add subagents - Coderabbit - Prd and tooling - Bun lock - Lint tooling - Copy.md and tooling adjusts - Add repoclone rc - Upgrade skeeper to v0.2.0 - Update go.mod - Adopt task artifacts into skeeper - Sync codex plans with skeeper - Skeeper lock - Skeeper lock - New skills - Skeeper lock - Skeeper lock - Skeeper lock - Update deps and go - Regenerate daytona sidecar assets for go 1.26.3 - Fix cliff - Ignore docs on fmt - Build web assets before goreleaser - Extend release dry-run timeout ### 🔧 CI/CD - Lint errors - Fint release pr - Fix goreleaser - Fix release ### 🧪 Testing - Add e2e tests (#27) - Qa rounds (#78) - Improve test suite (#138) - Harden daemon-served restart reloads - Harden daemon-served readiness waits - Stabilize dashboard focus assertion - Stabilize release integration gates - Stabilize release e2e markers - Stabilize release e2e flows Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
## Release v0.0.2 This PR prepares the release of version v0.0.2. ### Changelog ## 0.0.2 - 2026-05-26 ### Other Changes - Lessons learned ### ♻️ Refactoring - Project structure (#7) - Kb improvements (#12) - Rename spaces to channels (#17) - Add extensions gaps (#21) - Improve tool calls ui (#22) - Remove web app header - Module improvements (#29) - Memory improvements (#35) - Storybook for web and ui (#38) - Enable AGH network by default for new installs (#57) - Hermes adjustments (#69) - Badges design (#84) - Storybook scenario and logos gallery - Migrate typescript tests (#114) - Internal go packages (#120) - Ui patterns (#127) - Improve e2e tests (#130) - Ui redesign - Workspace isolation across runtime surfaces (#145) - Prod ready applies (#162) - Tool card ui (#164) - Alpha on logo - Prod ready features (#167) - Thread sheet (#202) ### 🎉 Features - Implement config foundation packages - Implement sqlite store package - Add ACP client package - Add session lifecycle manager - Implement observe package - Add daemon composition root - Add uds api server - Implement cli package - Add http api server - Add system design - Add foundation types, schemas, and layout shell for web client - Add daemon health polling and agent sidebar systems for web client - Add session system CRUD, streaming core, and session store for web client - Add chat view, messages, and composer tests for web client - Add tool cards and renderers for web client - Add file-backed memory store core - Scaffold memory session seams - Add memory dream consolidation service - Wire memory assembler into daemon - Add memory api and cli - New skills system (#1) - Add workspace entity (#5) - Add new skill capabilities (#8) - Web ui v2 (#9) - Improve hooks system (#10) - Session resilience (#11) - Add extensability (#13) - Add automation (#16) - Add channels (#14) - Add network implementation (#15) - Add network, bridges and automations web pages (#18) - Ext registry (#20) - Add core tasks (#19) - Bridge adapters (#23) - Add site (#26) - Add ext refac and sandbox (#25) - Settings ui (#37) - Tasks ui (#36) - Harness improvements (#44) - Agent capabilities (#49) - Redesign ui (#48) - Unify capability (#53) - Redesign network workspace (#59) - Add task deletion and split session delete from stop (#58) - Session provider selection (#60) - Production grade adjustments (#66) - Autonomous system (#75) - Add agent session route (#80) - Tools registry (#85) - Agents soul (#88) - Add network threads (#105) - Orchestration improvements (#106) - Memory v2 (#108) - Agent categories (#113) - Providers model (#118) - Add canonical AGH bundled skill (#143) - Onboarding and improvements (#198) - Onboarding and improvements (#201) ### 🐛 Bug Fixes - Review round - Review rounds - Resolve memory extensibility review batch - Embed web into daemon - Defaults agents - Acp integration (#4) - Lint errors - Prd folder - Remove orphan web actions and dead surfaces (#55) - Qa testing and fixes (#73) - New review rounds (#82) - Security audit (#90) - Release qa round (#95) - Add missing tools (#141) - New qa round (#147) - Advanced qa round (#149) - Homebrew tap - Final review round (#151) - Daemon healthy - Reasoning models (#158) - Lint errors (#160) - Review round (#168) - Release adjustments (#171) - Stabilize release ci fixtures - Stabilize release integration gate - Stabilize release verify gates - Stabilize release integration flows - Stabilize release verify gates - Stabilize main verify shutdown - Ignore stale acpmock cancel - Marketplace search focus and filtering (#193) - Website video - Workspace command select ### 📚 Documentation - Update agents.md - Update prd - Update skills - Update compozy tasks - Update compozy - Update compozy - Add new skills - Archive prd - Update prds - Update rfc - Update prds - Update prds - Add automation prd - Channels prd - Update prd - Update prd - New prds - Archive prds - Bridges adapters prd - Sandbox prd - Update - Archive prd - Update - Add new prd - New design - Update prd - Archive prds - Update prds - Tasks-ui prd tasks - Update prd - Update design docs - Agent capabilities prd - Improve site docs - Remove old design references - Udpate - Autonomous prd - Update skills - Blog design - Agent sould prd - Final qa plan - Update - Remove codex ledgers from gitignore - Remove not needed files - Udpate ledger - Update cy-codex-loop skill - Orchestration improves prd - Update prds - Orch improvs prd - Memv2 prd - Providers model prd - Update refacs prd - New design proposal - Update rules - Update skills - New blog posts (#173) - Format docs - Remove old design files - Remove old - Skeeper update ### 📦 Build System - Initial structure - Commitlint - Frontend base structure - Update vscode settings - Add subagents - Coderabbit - Prd and tooling - Bun lock - Lint tooling - Copy.md and tooling adjusts - Add repoclone rc - Upgrade skeeper to v0.2.0 - Update go.mod - Adopt task artifacts into skeeper - Sync codex plans with skeeper - Skeeper lock - Skeeper lock - New skills - Skeeper lock - Skeeper lock - Skeeper lock - Update deps and go - Regenerate daytona sidecar assets for go 1.26.3 - Fix cliff - Ignore docs on fmt - Build web assets before goreleaser - Extend release dry-run timeout ### 🔧 CI/CD - Lint errors - Fint release pr - Fix goreleaser - Fix release - Fix release process ### 🧪 Testing - Add e2e tests (#27) - Qa rounds (#78) - Improve test suite (#138) - Harden daemon-served restart reloads - Harden daemon-served readiness waits - Stabilize dashboard focus assertion - Stabilize release integration gates - Stabilize release e2e markers - Stabilize release e2e flows - Improve suite speed Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
## Release v0.0.2 This PR prepares the release of version v0.0.2. ### Changelog ## 0.0.2 - 2026-05-26 ### Other Changes - Lessons learned ### ♻️ Refactoring - Project structure (#7) - Kb improvements (#12) - Rename spaces to channels (#17) - Add extensions gaps (#21) - Improve tool calls ui (#22) - Remove web app header - Module improvements (#29) - Memory improvements (#35) - Storybook for web and ui (#38) - Enable AGH network by default for new installs (#57) - Hermes adjustments (#69) - Badges design (#84) - Storybook scenario and logos gallery - Migrate typescript tests (#114) - Internal go packages (#120) - Ui patterns (#127) - Improve e2e tests (#130) - Ui redesign - Workspace isolation across runtime surfaces (#145) - Prod ready applies (#162) - Tool card ui (#164) - Alpha on logo - Prod ready features (#167) - Thread sheet (#202) ### 🎉 Features - Implement config foundation packages - Implement sqlite store package - Add ACP client package - Add session lifecycle manager - Implement observe package - Add daemon composition root - Add uds api server - Implement cli package - Add http api server - Add system design - Add foundation types, schemas, and layout shell for web client - Add daemon health polling and agent sidebar systems for web client - Add session system CRUD, streaming core, and session store for web client - Add chat view, messages, and composer tests for web client - Add tool cards and renderers for web client - Add file-backed memory store core - Scaffold memory session seams - Add memory dream consolidation service - Wire memory assembler into daemon - Add memory api and cli - New skills system (#1) - Add workspace entity (#5) - Add new skill capabilities (#8) - Web ui v2 (#9) - Improve hooks system (#10) - Session resilience (#11) - Add extensability (#13) - Add automation (#16) - Add channels (#14) - Add network implementation (#15) - Add network, bridges and automations web pages (#18) - Ext registry (#20) - Add core tasks (#19) - Bridge adapters (#23) - Add site (#26) - Add ext refac and sandbox (#25) - Settings ui (#37) - Tasks ui (#36) - Harness improvements (#44) - Agent capabilities (#49) - Redesign ui (#48) - Unify capability (#53) - Redesign network workspace (#59) - Add task deletion and split session delete from stop (#58) - Session provider selection (#60) - Production grade adjustments (#66) - Autonomous system (#75) - Add agent session route (#80) - Tools registry (#85) - Agents soul (#88) - Add network threads (#105) - Orchestration improvements (#106) - Memory v2 (#108) - Agent categories (#113) - Providers model (#118) - Add canonical AGH bundled skill (#143) - Onboarding and improvements (#198) - Onboarding and improvements (#201) ### 🐛 Bug Fixes - Review round - Review rounds - Resolve memory extensibility review batch - Embed web into daemon - Defaults agents - Acp integration (#4) - Lint errors - Prd folder - Remove orphan web actions and dead surfaces (#55) - Qa testing and fixes (#73) - New review rounds (#82) - Security audit (#90) - Release qa round (#95) - Add missing tools (#141) - New qa round (#147) - Advanced qa round (#149) - Homebrew tap - Final review round (#151) - Daemon healthy - Reasoning models (#158) - Lint errors (#160) - Review round (#168) - Release adjustments (#171) - Stabilize release ci fixtures - Stabilize release integration gate - Stabilize release verify gates - Stabilize release integration flows - Stabilize release verify gates - Stabilize main verify shutdown - Ignore stale acpmock cancel - Marketplace search focus and filtering (#193) - Website video - Workspace command select ### 📚 Documentation - Update agents.md - Update prd - Update skills - Update compozy tasks - Update compozy - Update compozy - Add new skills - Archive prd - Update prds - Update rfc - Update prds - Update prds - Add automation prd - Channels prd - Update prd - Update prd - New prds - Archive prds - Bridges adapters prd - Sandbox prd - Update - Archive prd - Update - Add new prd - New design - Update prd - Archive prds - Update prds - Tasks-ui prd tasks - Update prd - Update design docs - Agent capabilities prd - Improve site docs - Remove old design references - Udpate - Autonomous prd - Update skills - Blog design - Agent sould prd - Final qa plan - Update - Remove codex ledgers from gitignore - Remove not needed files - Udpate ledger - Update cy-codex-loop skill - Orchestration improves prd - Update prds - Orch improvs prd - Memv2 prd - Providers model prd - Update refacs prd - New design proposal - Update rules - Update skills - New blog posts (#173) - Format docs - Remove old design files - Remove old - Skeeper update ### 📦 Build System - Initial structure - Commitlint - Frontend base structure - Update vscode settings - Add subagents - Coderabbit - Prd and tooling - Bun lock - Lint tooling - Copy.md and tooling adjusts - Add repoclone rc - Upgrade skeeper to v0.2.0 - Update go.mod - Adopt task artifacts into skeeper - Sync codex plans with skeeper - Skeeper lock - Skeeper lock - New skills - Skeeper lock - Skeeper lock - Skeeper lock - Update deps and go - Regenerate daytona sidecar assets for go 1.26.3 - Fix cliff - Ignore docs on fmt - Build web assets before goreleaser - Extend release dry-run timeout ### 🔧 CI/CD - Lint errors - Fint release pr - Fix goreleaser - Fix release - Fix release process - Fix release sync - Decouple release dry-run npm auth - Persist web assets git auth ### 🧪 Testing - Add e2e tests (#27) - Qa rounds (#78) - Improve test suite (#138) - Harden daemon-served restart reloads - Harden daemon-served readiness waits - Stabilize dashboard focus assertion - Stabilize release integration gates - Stabilize release e2e markers - Stabilize release e2e flows - Improve suite speed <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Chores** * Updated web assets dependency to a newer version for improved stability and performance. <!-- review_stack_entry_start --> [](https://app.coderabbit.ai/change-stack/compozy/agh/pull/211?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack) <!-- review_stack_entry_end --> <!-- end of auto-generated comment: release notes by coderabbit.ai --> Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
## Release v0.0.2 This PR prepares the release of version v0.0.2. ### Changelog ## 0.0.2 - 2026-05-27 ### Other Changes - Lessons learned ### ♻️ Refactoring - Project structure (#7) - Kb improvements (#12) - Rename spaces to channels (#17) - Add extensions gaps (#21) - Improve tool calls ui (#22) - Remove web app header - Module improvements (#29) - Memory improvements (#35) - Storybook for web and ui (#38) - Enable AGH network by default for new installs (#57) - Hermes adjustments (#69) - Badges design (#84) - Storybook scenario and logos gallery - Migrate typescript tests (#114) - Internal go packages (#120) - Ui patterns (#127) - Improve e2e tests (#130) - Ui redesign - Workspace isolation across runtime surfaces (#145) - Prod ready applies (#162) - Tool card ui (#164) - Alpha on logo - Prod ready features (#167) - Thread sheet (#202) ### 🎉 Features - Implement config foundation packages - Implement sqlite store package - Add ACP client package - Add session lifecycle manager - Implement observe package - Add daemon composition root - Add uds api server - Implement cli package - Add http api server - Add system design - Add foundation types, schemas, and layout shell for web client - Add daemon health polling and agent sidebar systems for web client - Add session system CRUD, streaming core, and session store for web client - Add chat view, messages, and composer tests for web client - Add tool cards and renderers for web client - Add file-backed memory store core - Scaffold memory session seams - Add memory dream consolidation service - Wire memory assembler into daemon - Add memory api and cli - New skills system (#1) - Add workspace entity (#5) - Add new skill capabilities (#8) - Web ui v2 (#9) - Improve hooks system (#10) - Session resilience (#11) - Add extensability (#13) - Add automation (#16) - Add channels (#14) - Add network implementation (#15) - Add network, bridges and automations web pages (#18) - Ext registry (#20) - Add core tasks (#19) - Bridge adapters (#23) - Add site (#26) - Add ext refac and sandbox (#25) - Settings ui (#37) - Tasks ui (#36) - Harness improvements (#44) - Agent capabilities (#49) - Redesign ui (#48) - Unify capability (#53) - Redesign network workspace (#59) - Add task deletion and split session delete from stop (#58) - Session provider selection (#60) - Production grade adjustments (#66) - Autonomous system (#75) - Add agent session route (#80) - Tools registry (#85) - Agents soul (#88) - Add network threads (#105) - Orchestration improvements (#106) - Memory v2 (#108) - Agent categories (#113) - Providers model (#118) - Add canonical AGH bundled skill (#143) - Onboarding and improvements (#198) - Onboarding and improvements (#201) ### 🐛 Bug Fixes - Review round - Review rounds - Resolve memory extensibility review batch - Embed web into daemon - Defaults agents - Acp integration (#4) - Lint errors - Prd folder - Remove orphan web actions and dead surfaces (#55) - Qa testing and fixes (#73) - New review rounds (#82) - Security audit (#90) - Release qa round (#95) - Add missing tools (#141) - New qa round (#147) - Advanced qa round (#149) - Homebrew tap - Final review round (#151) - Daemon healthy - Reasoning models (#158) - Lint errors (#160) - Review round (#168) - Release adjustments (#171) - Stabilize release ci fixtures - Stabilize release integration gate - Stabilize release verify gates - Stabilize release integration flows - Stabilize release verify gates - Stabilize main verify shutdown - Ignore stale acpmock cancel - Marketplace search focus and filtering (#193) - Website video - Workspace command select ### 📚 Documentation - Update agents.md - Update prd - Update skills - Update compozy tasks - Update compozy - Update compozy - Add new skills - Archive prd - Update prds - Update rfc - Update prds - Update prds - Add automation prd - Channels prd - Update prd - Update prd - New prds - Archive prds - Bridges adapters prd - Sandbox prd - Update - Archive prd - Update - Add new prd - New design - Update prd - Archive prds - Update prds - Tasks-ui prd tasks - Update prd - Update design docs - Agent capabilities prd - Improve site docs - Remove old design references - Udpate - Autonomous prd - Update skills - Blog design - Agent sould prd - Final qa plan - Update - Remove codex ledgers from gitignore - Remove not needed files - Udpate ledger - Update cy-codex-loop skill - Orchestration improves prd - Update prds - Orch improvs prd - Memv2 prd - Providers model prd - Update refacs prd - New design proposal - Update rules - Update skills - New blog posts (#173) - Format docs - Remove old design files - Remove old - Skeeper update ### 📦 Build System - Initial structure - Commitlint - Frontend base structure - Update vscode settings - Add subagents - Coderabbit - Prd and tooling - Bun lock - Lint tooling - Copy.md and tooling adjusts - Add repoclone rc - Upgrade skeeper to v0.2.0 - Update go.mod - Adopt task artifacts into skeeper - Sync codex plans with skeeper - Skeeper lock - Skeeper lock - New skills - Skeeper lock - Skeeper lock - Skeeper lock - Update deps and go - Regenerate daytona sidecar assets for go 1.26.3 - Fix cliff - Ignore docs on fmt - Build web assets before goreleaser - Extend release dry-run timeout - Fix release dry-run token contract ### 🔧 CI/CD - Lint errors - Fint release pr - Fix goreleaser - Fix release - Fix release process - Fix release sync - Decouple release dry-run npm auth - Persist web assets git auth - Require npm auth before release merge ### 🧪 Testing - Add e2e tests (#27) - Qa rounds (#78) - Improve test suite (#138) - Harden daemon-served restart reloads - Harden daemon-served readiness waits - Stabilize dashboard focus assertion - Stabilize release integration gates - Stabilize release e2e markers - Stabilize release e2e flows - Improve suite speed <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Chores** * Updated dependencies to latest versions. <!-- review_stack_entry_start --> [](https://app.coderabbit.ai/change-stack/compozy/agh/pull/214?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack) <!-- review_stack_entry_end --> <!-- end of auto-generated comment: release notes by coderabbit.ai --> Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Summary by CodeRabbit
New Features
Tests