refactor: add extensions gaps#21
Conversation
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: ⛔ Files ignored due to path filters (34)
📒 Files selected for processing (10)
WalkthroughAdds bundle activation lifecycle: bundle spec loading/validation, persistent activations and inventory, reconciliation syncing automations and managed bridges, bundle network settings exposure, bridge secret‑binding CRUD, DB migrations, daemon wiring, API routes/handlers, and extensive tests and fixtures. Changes
Sequence Diagram(s)sequenceDiagram
participant Client as Client
participant HTTP as API Handler
participant Service as Bundle Service
participant ExtLoader as Extension Loader
participant AutoSync as Automation Syncer
participant BridgeSync as Bridge Managed Syncer
participant Store as Activation Store
Client->>HTTP: POST /api/bundles/activations (ActivateRequest)
HTTP->>Service: Activate(ctx, request)
Service->>ExtLoader: Load extension & bundle spec
ExtLoader-->>Service: BundleSpec / Profile
Service->>Service: Materialize jobs/triggers, bridges, inventory
Service->>Store: CreateBundleActivation(record)
Store-->>Service: Created
Service->>AutoSync: SyncManagedDefinitions(jobs, triggers)
AutoSync-->>Service: Sync result
Service->>BridgeSync: SyncManagedInstances(desired bridge instances)
BridgeSync-->>Service: Sync result
Service->>Store: ReplaceBundleActivationInventory(items)
Store-->>Service: OK
Service-->>HTTP: ActivationPreview (201 Created)
HTTP-->>Client: 201 Created + payload
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 1 | ❌ 2❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (1 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
Comment |
There was a problem hiding this comment.
Actionable comments posted: 13
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (4)
internal/automation/manager.go (2)
1385-1388:⚠️ Potential issue | 🟠 MajorPreserve
CreatedAtbefore managed updates.The desired jobs/triggers passed into
UpdateJobandUpdateTriggerare rebuilt from config/package state and do not carry the persistedCreatedAt. Everywhere else in this file the update path copiescurrent.CreatedAtfirst; skipping that here risks zeroing audit data or failing validation on managed updates.Also applies to: 1430-1433
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@internal/automation/manager.go` around lines 1385 - 1388, The update path for managed jobs/triggers is overwriting persisted CreatedAt because the rebuilt desired job/trigger (passed to m.store.UpdateJob / m.store.UpdateTrigger) doesn't copy current.CreatedAt; modify the branches where sameJobDefinition(current, job) is false (and the analogous trigger branch at the 1430-1433 region) to first set job.CreatedAt = current.CreatedAt (and trigger.CreatedAt = current.CreatedAt) before calling m.store.UpdateJob / m.store.UpdateTrigger so the persisted CreatedAt is preserved during updates.
1296-1456:⚠️ Potential issue | 🔴 CriticalManaged sync never updates the live scheduler or trigger engine.
SyncManagedDefinitionsonly mutates persistence and webhook secrets. When bundle activation calls this afterStart, new/updated managed jobs and triggers are never registered into the in-memory runtime, and removed ones keep running until restart. This makes activation reconciliation look successful while the live daemon still serves stale automation state.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@internal/automation/manager.go` around lines 1296 - 1456, SyncManagedDefinitions only updates the store but never updates in-memory runtime, so after creating/updating/deleting in syncJobsForSource and syncTriggersForSource you must also register/unregister those changes with the Manager's runtime registries: call the Manager's runtime registration methods (e.g. m.registerJob / m.unregisterJob or m.scheduler.RegisterJob / m.scheduler.RemoveJob) immediately after successful CreateJob/UpdateJob/DeleteJob, and likewise call m.registerTrigger / m.unregisterTrigger or m.triggerEngine.RegisterTrigger / m.triggerEngine.RemoveTrigger and ensure webhook secrets are applied to the live trigger engine (e.g. m.syncTriggerWebhookSecret or m.triggerEngine.UpdateSecret) after CreateTrigger/UpdateTrigger/DeleteTrigger; make these runtime calls only after the store operation succeeds and keep the same conflict/definition checks in syncJobsForSource and syncTriggersForSource.internal/daemon/extensions.go (2)
206-223:⚠️ Potential issue | 🟠 MajorBundle specs may never populate when manifest is already present.
The guard at Line 206 exits when
ext.Manifest != nil, which also skips the new bundle-spec loading block. Runtime-provided extensions that already includeManifestcan still end up with missingext.Bundles.💡 Suggested fix
func populateExtensionManifest(logger *slog.Logger, ext *extensionpkg.Extension) { - if ext == nil || ext.Manifest != nil || strings.TrimSpace(ext.Info.ManifestPath) == "" { + if ext == nil || strings.TrimSpace(ext.Info.ManifestPath) == "" { return } - manifest, err := extensionpkg.LoadManifest(filepath.Dir(ext.Info.ManifestPath)) - if err != nil { - if logger != nil { - logger.Debug("daemon: load extension manifest for status failed", "path", ext.Info.ManifestPath, "error", err) - } - return + manifest := ext.Manifest + if manifest == nil { + loaded, err := extensionpkg.LoadManifest(filepath.Dir(ext.Info.ManifestPath)) + if err != nil { + if logger != nil { + logger.Debug("daemon: load extension manifest for status failed", "path", ext.Info.ManifestPath, "error", err) + } + return + } + manifest = loaded + ext.Manifest = loaded } - ext.Manifest = manifest + if bundles, err := extensionpkg.LoadBundleSpecs(filepath.Dir(ext.Info.ManifestPath), manifest); err == nil { ext.Bundles = bundles } else if logger != nil { logger.Debug("daemon: load extension bundles for status failed", "path", ext.Info.ManifestPath, "error", err) } }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@internal/daemon/extensions.go` around lines 206 - 223, The early return in the guard (checking ext == nil || ext.Manifest != nil || strings.TrimSpace(ext.Info.ManifestPath) == "") prevents bundle specs from being loaded for extensions that already have a Manifest, causing ext.Bundles to remain unset for runtime-provided extensions; change the logic in the function so that if ext is non-nil and ext.Info.ManifestPath is set you still call extensionpkg.LoadBundleSpecs (e.g., remove ext.Manifest != nil from the guard or add a separate branch that calls extensionpkg.LoadBundleSpecs when ext.Bundles is nil and ext.Info.ManifestPath is present), and ensure you assign ext.Bundles when extensionpkg.LoadBundleSpecs succeeds and log errors via logger.Debug on failure (referencing ext.Manifest, ext.Bundles, extensionpkg.LoadBundleSpecs, and ext.Info.ManifestPath).
137-155:⚠️ Potential issue | 🟠 MajorBundle reconciliation is skipped when runtime is nil.
At Line 138,
reload()returns early ifs.runtime == nil, sos.bundles.Reconcile(ctx)is never executed in that path. That leaves bundle state stale even when a bundle service is available.💡 Suggested fix
func (s *daemonExtensionService) reload(ctx context.Context) error { - if s.runtime == nil { - return nil - } - - reloadErr := s.runtime.Reload(ctx) + var reloadErr error + if s.runtime != nil { + reloadErr = s.runtime.Reload(ctx) + } if s.hooks == nil { if s.bundles == nil { return reloadErr } return errors.Join(reloadErr, s.bundles.Reconcile(ctx)) } rebuildErr := s.hooks.Rebuild(ctx) if s.bundles == nil { return errors.Join(reloadErr, rebuildErr) } return errors.Join(reloadErr, rebuildErr, s.bundles.Reconcile(ctx)) }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@internal/daemon/extensions.go` around lines 137 - 155, The reload function exits early when s.runtime == nil which prevents s.bundles.Reconcile(ctx) from running; update reload in daemonExtensionService so that when s.runtime is nil it does not return immediately but instead treats reloadErr as nil and continues to run hooks.Rebuild(ctx) and s.bundles.Reconcile(ctx) as appropriate, collecting errors with errors.Join; specifically adjust the logic in reload to avoid the early return and ensure calls to s.hooks.Rebuild and s.bundles.Reconcile still occur (referencing reload(), s.runtime, s.hooks.Rebuild, and s.bundles.Reconcile) and return the joined error result.
🧹 Nitpick comments (6)
internal/extension/install_managed_test.go (2)
11-126: Uset.Run("Should...")subtests for these scenarios.These are both single-case top-level tests today. Wrapping the scenarios in
t.Run("Should ...")keeps them aligned with the repo’s required test shape and makes it easier to extend the symlink matrix without cloning more setup.As per coding guidelines,
**/*_test.go: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/extension/install_managed_test.go` around lines 11 - 126, Both tests (TestCopyInstallTreeMaterializesSymlinkTargets and TestInstallLocalManagedUsesInstalledChecksumForMaterializedSymlinks) must use the t.Run("Should ...") subtest pattern; update each test to call t.Run with a descriptive "Should ..." name wrapping the existing test logic (keeping t.Parallel at the top of the parent test) so the current body becomes the subtest function, e.g., inside TestCopyInstallTreeMaterializesSymlinkTargets use t.Run("Should materialize symlink targets", func(t *testing.T){ ...existing code... }), and similarly wrap the body of TestInstallLocalManagedUsesInstalledChecksumForMaterializedSymlinks in a t.Run("Should record installed checksum for materialized symlinks", func(t *testing.T){ ... }), leaving all referenced helpers unchanged (copyInstallTree, ComputeDirectoryChecksum, InstallLocalManaged, ManagedInstallPath, recordingManagedInstallRegistry, Manifest).
128-139: Add a compile-time assertion for the test double.
recordingManagedInstallRegistryis clearly meant to implementmanagedInstallRegistry, but that contract is only checked indirectly right now. A compile-time assertion here will fail fast if the interface changes.Suggested change
type recordingManagedInstallRegistry struct { installedChecksum string } + +var _ managedInstallRegistry = (*recordingManagedInstallRegistry)(nil)As per coding guidelines,
**/*.go: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/extension/install_managed_test.go` around lines 128 - 139, Add a compile-time interface assertion to ensure recordingManagedInstallRegistry implements managedInstallRegistry; specifically, add a package-level var assertion using the pattern var _ managedInstallRegistry = (*recordingManagedInstallRegistry)(nil) so changes to the interface will fail at compile time.internal/store/globaldb/global_db_bridges_test.go (1)
20-34: Consider assertingsourcedefault semantics, not only column presence.This test currently verifies existence, but not the expected default (
dynamic) and NOT NULL behavior that migrations depend on.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@internal/store/globaldb/global_db_bridges_test.go` around lines 20 - 34, The test only checks column presence via assertTableColumns but must also assert the `source` column's default value and NOT NULL constraint for the "bridge_instances" table; update the test (using globalDB.db and the existing helper/assert patterns) to verify that `source` has default 'dynamic' and is NOT NULL—either by inspecting the schema/PRAGMA for the `bridge_instances` table to assert default='dynamic' and notnull=1 or by inserting a row without `source` and asserting the persisted value equals 'dynamic' and insert fails when explicitly setting NULL.internal/store/globaldb/global_db_bundles_test.go (1)
33-80: Seed a legacy row before asserting migration success.This currently proves the column exists after reopen, but not that the migration preserved existing activations. A destructive table rebuild would still pass. Insert one legacy row before
OpenGlobalDB()and assert it survives with a sanespec_content_hashvalue after migration.As per coding guidelines,
**/*_test.go: 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/store/globaldb/global_db_bundles_test.go` around lines 33 - 80, The test TestOpenGlobalDBMigratesLegacyBundleActivationSpecHashColumn currently only checks that the spec_content_hash column exists after OpenGlobalDB; modify it to insert a legacy row into the bundle_activations table (omitting spec_content_hash) before calling OpenGlobalDB, then after opening the DB verify that the inserted row still exists and that its spec_content_hash has been populated with a sane value; use the same helpers used in the test (sql.ExecContext/testutil.Context(t)) to insert a row with required fields (id, extension_name, bundle_name, profile_name, scope, created_at, updated_at) and then query the bundle_activations row from globalDB.db to assert the original values are preserved and spec_content_hash is non-empty/valid.internal/bridges/managed_sync_test.go (1)
103-105: Assert the preserved timestamp exactly.
IsZero()still passes if the syncer overwritesCreatedAtwith a new non-zero value. Compare it to the original persisted timestamp so this test actually pins the preservation contract it describes.As per coding guidelines,
**/*_test.go: Must Check: 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/bridges/managed_sync_test.go` around lines 103 - 105, Replace the weak IsZero() check with an exact equality assertion against the original persisted timestamp: capture the original CreatedAt into a local (e.g., originalCreatedAt := someExisting.CreatedAt) before running the sync, then after the sync assert that updated[0].CreatedAt.Equal(originalCreatedAt) (or compare UnixNano values) instead of using updated[0].CreatedAt.IsZero(), ensuring the test pins the preservation contract for the CreatedAt field.internal/bundles/service_test.go (1)
261-539: Consider converting these lifecycle scenarios to table-drivent.Run("Should...")subtests.The cases are independent and already follow the same arrange/act/assert shape. A table-driven harness would cut the duplicated fixture setup and make it easier to add new bundle/profile/scope permutations without growing the file linearly.
As per coding guidelines,
**/*_test.go: Use table-driven tests with subtests (t.Run) as default, andMUST 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/bundles/service_test.go` around lines 261 - 539, Several independent lifecycle tests should be converted into table-driven subtests using t.Run("Should...") to follow the repo guideline; refactor tests like TestServiceActivateMaterializesManagedResources, TestServiceRejectsMultipleDefaultChannelClaims, TestServiceDeactivateCleansUpManagedResources, TestServiceUpdateActivationRestoresRecordOnReconcileFailure, TestServiceDeactivateReturnsRollbackFailureWhenRestoreFails, and TestServiceActivateWorkspaceScopedResources into a single table of scenarios that share common setup (store := newMemoryStore(), automation := &recordingAutomationSyncer(), service := newMarketingService(...) or custom resolver), then iterate over the table and for each case call t.Run("Should <behavior>", func(t *testing.T){ t.Parallel(); arrange/act/assert using the case-specific Activate/Deactivate/UpdateActivation inputs and expected checks (e.g. preview.Inventory length, automation.source/jobs/triggers, store.bridges, Activation.WorkspaceID, errors like ErrDefaultChannelBusy, stored rollback flags, etc.); keep per-case custom hooks (e.g. automation.err, store.createBundleActivationHook) in the case struct so assertions and rollback checks run per subtest. Ensure each subtest name starts with "Should..." and preserve existing assertions and t.Parallel semantics.
🤖 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/bundles.go`:
- Around line 311-329: The default branch of StatusForBundleError currently
returns http.StatusBadRequest which misclassifies server-side failures; change
the default return value in the StatusForBundleError function to
http.StatusInternalServerError so unknown/store/loader/syncer errors map to 500
while keeping the existing explicit 4xx mappings (e.g., ErrActivationNotFound,
ErrBundleNotFound, ErrDefaultChannelBusy, ErrWebhookUnsupported) and the
workspace-specific delegation to StatusForWorkspaceError unchanged.
- Around line 214-279: The Jobs/Triggers/Bridges IDs in BundleActivationPayload
are built with bundlepkgStableID(...) but the persisted/materialized IDs use the
hashed stableID(...) helper, causing mismatch with Inventory and managers;
update the payload construction in BundleActivationPayload to call
stableID("job"/"trg"/"bri", item.Activation.ID,
job.Name/trigger.Name/bridge.Name) (instead of bundlepkgStableID) so the
returned IDs match the materialized IDs used elsewhere (ensure stableID is
referenced/imported where BundleActivationPayload is defined).
In `@internal/api/core/handlers.go`:
- Around line 683-686: The call to h.Bundles.NetworkSettings returns err
directly (in the block around settings, err := h.Bundles.NetworkSettings(ctx)),
losing operation context; change the return to wrap the error with fmt.Errorf
(e.g. return nil, fmt.Errorf("fetching bundle network settings: %w", err)) and
add/import the fmt package if not already present so the returned error
preserves call-site context.
In `@internal/bridges/managed_sync.go`:
- Around line 96-145: The store calls in syncManaged
(s.store.ListBridgeInstances, s.store.InsertBridgeInstance,
s.store.UpdateBridgeInstance, s.store.DeleteBridgeInstance) return raw
errors—wrap each returned error with contextual reconcile info using fmt.Errorf,
e.g. include the normalized source (normalizedSource), the bridge id (next.ID or
id) and the phase ("list", "insert", "update", "delete") so the function
(syncManaged) returns errors like fmt.Errorf("bridges: reconcile %s %q: %w",
"<phase>", "<source|id>", err); update the error returns in the
ListBridgeInstances failure, and in the branches that call InsertBridgeInstance,
UpdateBridgeInstance and DeleteBridgeInstance to include that context.
In `@internal/bridges/registry.go`:
- Around line 219-220: In UpdateInstance, the return of the sentinel
ErrBridgeInstanceReadOnly is not wrapped with context; change the bare return
that checks if instance.Source == BridgeInstanceSourcePackage to wrap the
sentinel using fmt.Errorf so callers and logs include the instance ID (or other
identifying info) while preserving errors.Is() matching (e.g.,
fmt.Errorf("instance %s: %w", instance.ID, ErrBridgeInstanceReadOnly)); update
the return at the check for instance.Source == BridgeInstanceSourcePackage
accordingly.
In `@internal/bundles/service_test.go`:
- Around line 433-485: The tests currently assert error text with
strings.Contains; instead define sentinel errors (e.g., syncErr :=
errors.New("sync failed") and recreateErr := errors.New("recreate failed")),
assign syncErr to automation.err and return recreateErr from
store.createBundleActivationHook, then replace the string checks after
service.UpdateActivation and service.Deactivate with semantic checks using
errors.Is(err, syncErr) and errors.Is(err, recreateErr) (referencing symbols
UpdateActivation, Deactivate, automation.err, and
store.createBundleActivationHook to locate changes).
In `@internal/bundles/service.go`:
- Around line 480-533: The loop over activations can continue and perform
destructive syncs even if some activations failed to resolve; change the flow so
that if any resolveActivation(ctx, activation) returned an error (i.e., errs is
non-empty after the activations loop) you short-circuit and return that
aggregated error instead of proceeding to call
s.automation.SyncManagedDefinitions or s.bridges.SyncManagedInstances; in
practice, after the for ... range loop check if len(errs) > 0 and return the
composed error (or errors.Join(errs)) so no destructive reconciliation of
desiredJobs/desiredTriggers/desiredBridges occurs when any activation resolution
failed.
In `@internal/daemon/bridges.go`:
- Around line 148-194: ListSecretBindings, PutSecretBinding, and
DeleteSecretBinding in bridgeRuntime must normalize binding keys and wrap store
errors: trim BridgeInstanceID and BindingName on write by updating
PutSecretBinding to sanitize binding.BridgeInstanceID and binding.BindingName
(bridgepkg.BridgeSecretBinding) before calling r.store.PutBridgeSecretBinding,
and ensure any call to r.store.ListBridgeSecretBindings,
r.store.PutBridgeSecretBinding, and r.store.DeleteBridgeSecretBinding wraps
returned errors with fmt.Errorf("daemon: <operation> failed: %w", err) (use
appropriate operation names) while keeping the existing trimming of parameters
on ListSecretBindings/DeleteSecretBinding to avoid key-mismatch.
In `@internal/extension/bundle.go`:
- Around line 147-169: When loading bundle specs in LoadBundleSpecs, normalize
bundle and profile names to a consistent case before performing duplicate checks
and before calling BundleSpec.Validate: after obtaining spec from
loadBundleSpecAtPath, replace spec.Name with strings.ToLower(spec.Name) (and
likewise normalize any profile identifiers in spec.Profiles) and then run
spec.Validate(manifest) and the duplicate-existence check against the normalized
name stored in the loaded map; do the same normalization wherever duplicate
checks occur (e.g., the other block that mirrors this logic) so case-only name
differences (Foo vs foo) are treated as duplicates.
- Around line 334-339: The current check uses json.Marshal on b.DeliveryDefaults
which doesn't validate raw JSON; replace it with a real validation (e.g., use
json.Valid(b.DeliveryDefaults) or attempt json.Unmarshal(b.DeliveryDefaults,
&var) and check the error) and only return the ErrBundleInvalid formatted error
if the JSON is non-empty and invalid; update the branch that references
b.DeliveryDefaults to perform this validation and keep the same error formatting
including bundleName, profileName and b.Name.
In `@internal/extension/install_managed.go`:
- Around line 230-249: copyInstallSymlink currently follows symlinks and
immediately calls copyInstallDirectoryContents without guarding against
directory cycles; modify copyInstallSymlink to detect and reject cycles by
tracking a visited set of resolved directory paths (e.g., map[string]struct{})
for the current copy operation, check if resolvedPath is already in that set and
return a clear error if so, and pass this visited set down into
copyInstallDirectoryContents (and any other recursive helpers) so every
recursive entry first records the resolved path and checks for repeats before
recursing.
- Around line 69-72: Wrap errors returned from ComputeDirectoryChecksum and
registry.Install with contextual messages using error wrapping (e.g.,
fmt.Errorf("...: %w", err)) so callers know which install phase failed; for the
ComputeDirectoryChecksum call that produces actualSourceChecksum use a message
like "compute checksum for sourceDir <sourceDir>" and for registry.Install wrap
its errors with messages indicating the operation and extension/ID (e.g.,
"registry install for extension <extensionName/ID>" or "verify install for
<extensionName>"). Ensure you include the original error via %w to preserve the
cause.
In `@internal/extension/registry_bundles_test.go`:
- Around line 14-47: Refactor
TestRegistryBlocksDisableAndUninstallWithActiveBundles into t.Run subtests: keep
the shared setup (newRegistryTestEnvWithBundleActivations,
createRegistryTestExtension, env.registry.Install and the INSERT into
bundle_activations) in the parent test, call t.Parallel() at top-level, then add
two subtests using t.Run("Should block Disable when active bundles exist") and
t.Run("Should block Uninstall when active bundles exist") that respectively
invoke env.registry.Disable(manifest.Name) and
env.registry.Uninstall(manifest.Name) and assert errors.Is(err,
ErrExtensionHasActiveBundles); ensure assertions and error messages are moved
into the corresponding subtests and no duplicated setup is performed.
---
Outside diff comments:
In `@internal/automation/manager.go`:
- Around line 1385-1388: The update path for managed jobs/triggers is
overwriting persisted CreatedAt because the rebuilt desired job/trigger (passed
to m.store.UpdateJob / m.store.UpdateTrigger) doesn't copy current.CreatedAt;
modify the branches where sameJobDefinition(current, job) is false (and the
analogous trigger branch at the 1430-1433 region) to first set job.CreatedAt =
current.CreatedAt (and trigger.CreatedAt = current.CreatedAt) before calling
m.store.UpdateJob / m.store.UpdateTrigger so the persisted CreatedAt is
preserved during updates.
- Around line 1296-1456: SyncManagedDefinitions only updates the store but never
updates in-memory runtime, so after creating/updating/deleting in
syncJobsForSource and syncTriggersForSource you must also register/unregister
those changes with the Manager's runtime registries: call the Manager's runtime
registration methods (e.g. m.registerJob / m.unregisterJob or
m.scheduler.RegisterJob / m.scheduler.RemoveJob) immediately after successful
CreateJob/UpdateJob/DeleteJob, and likewise call m.registerTrigger /
m.unregisterTrigger or m.triggerEngine.RegisterTrigger /
m.triggerEngine.RemoveTrigger and ensure webhook secrets are applied to the live
trigger engine (e.g. m.syncTriggerWebhookSecret or m.triggerEngine.UpdateSecret)
after CreateTrigger/UpdateTrigger/DeleteTrigger; make these runtime calls only
after the store operation succeeds and keep the same conflict/definition checks
in syncJobsForSource and syncTriggersForSource.
In `@internal/daemon/extensions.go`:
- Around line 206-223: The early return in the guard (checking ext == nil ||
ext.Manifest != nil || strings.TrimSpace(ext.Info.ManifestPath) == "") prevents
bundle specs from being loaded for extensions that already have a Manifest,
causing ext.Bundles to remain unset for runtime-provided extensions; change the
logic in the function so that if ext is non-nil and ext.Info.ManifestPath is set
you still call extensionpkg.LoadBundleSpecs (e.g., remove ext.Manifest != nil
from the guard or add a separate branch that calls extensionpkg.LoadBundleSpecs
when ext.Bundles is nil and ext.Info.ManifestPath is present), and ensure you
assign ext.Bundles when extensionpkg.LoadBundleSpecs succeeds and log errors via
logger.Debug on failure (referencing ext.Manifest, ext.Bundles,
extensionpkg.LoadBundleSpecs, and ext.Info.ManifestPath).
- Around line 137-155: The reload function exits early when s.runtime == nil
which prevents s.bundles.Reconcile(ctx) from running; update reload in
daemonExtensionService so that when s.runtime is nil it does not return
immediately but instead treats reloadErr as nil and continues to run
hooks.Rebuild(ctx) and s.bundles.Reconcile(ctx) as appropriate, collecting
errors with errors.Join; specifically adjust the logic in reload to avoid the
early return and ensure calls to s.hooks.Rebuild and s.bundles.Reconcile still
occur (referencing reload(), s.runtime, s.hooks.Rebuild, and
s.bundles.Reconcile) and return the joined error result.
---
Nitpick comments:
In `@internal/bridges/managed_sync_test.go`:
- Around line 103-105: Replace the weak IsZero() check with an exact equality
assertion against the original persisted timestamp: capture the original
CreatedAt into a local (e.g., originalCreatedAt := someExisting.CreatedAt)
before running the sync, then after the sync assert that
updated[0].CreatedAt.Equal(originalCreatedAt) (or compare UnixNano values)
instead of using updated[0].CreatedAt.IsZero(), ensuring the test pins the
preservation contract for the CreatedAt field.
In `@internal/bundles/service_test.go`:
- Around line 261-539: Several independent lifecycle tests should be converted
into table-driven subtests using t.Run("Should...") to follow the repo
guideline; refactor tests like TestServiceActivateMaterializesManagedResources,
TestServiceRejectsMultipleDefaultChannelClaims,
TestServiceDeactivateCleansUpManagedResources,
TestServiceUpdateActivationRestoresRecordOnReconcileFailure,
TestServiceDeactivateReturnsRollbackFailureWhenRestoreFails, and
TestServiceActivateWorkspaceScopedResources into a single table of scenarios
that share common setup (store := newMemoryStore(), automation :=
&recordingAutomationSyncer(), service := newMarketingService(...) or custom
resolver), then iterate over the table and for each case call t.Run("Should
<behavior>", func(t *testing.T){ t.Parallel(); arrange/act/assert using the
case-specific Activate/Deactivate/UpdateActivation inputs and expected checks
(e.g. preview.Inventory length, automation.source/jobs/triggers, store.bridges,
Activation.WorkspaceID, errors like ErrDefaultChannelBusy, stored rollback
flags, etc.); keep per-case custom hooks (e.g. automation.err,
store.createBundleActivationHook) in the case struct so assertions and rollback
checks run per subtest. Ensure each subtest name starts with "Should..." and
preserve existing assertions and t.Parallel semantics.
In `@internal/extension/install_managed_test.go`:
- Around line 11-126: Both tests (TestCopyInstallTreeMaterializesSymlinkTargets
and TestInstallLocalManagedUsesInstalledChecksumForMaterializedSymlinks) must
use the t.Run("Should ...") subtest pattern; update each test to call t.Run with
a descriptive "Should ..." name wrapping the existing test logic (keeping
t.Parallel at the top of the parent test) so the current body becomes the
subtest function, e.g., inside TestCopyInstallTreeMaterializesSymlinkTargets use
t.Run("Should materialize symlink targets", func(t *testing.T){ ...existing
code... }), and similarly wrap the body of
TestInstallLocalManagedUsesInstalledChecksumForMaterializedSymlinks in a
t.Run("Should record installed checksum for materialized symlinks", func(t
*testing.T){ ... }), leaving all referenced helpers unchanged (copyInstallTree,
ComputeDirectoryChecksum, InstallLocalManaged, ManagedInstallPath,
recordingManagedInstallRegistry, Manifest).
- Around line 128-139: Add a compile-time interface assertion to ensure
recordingManagedInstallRegistry implements managedInstallRegistry; specifically,
add a package-level var assertion using the pattern var _ managedInstallRegistry
= (*recordingManagedInstallRegistry)(nil) so changes to the interface will fail
at compile time.
In `@internal/store/globaldb/global_db_bridges_test.go`:
- Around line 20-34: The test only checks column presence via assertTableColumns
but must also assert the `source` column's default value and NOT NULL constraint
for the "bridge_instances" table; update the test (using globalDB.db and the
existing helper/assert patterns) to verify that `source` has default 'dynamic'
and is NOT NULL—either by inspecting the schema/PRAGMA for the
`bridge_instances` table to assert default='dynamic' and notnull=1 or by
inserting a row without `source` and asserting the persisted value equals
'dynamic' and insert fails when explicitly setting NULL.
In `@internal/store/globaldb/global_db_bundles_test.go`:
- Around line 33-80: The test
TestOpenGlobalDBMigratesLegacyBundleActivationSpecHashColumn currently only
checks that the spec_content_hash column exists after OpenGlobalDB; modify it to
insert a legacy row into the bundle_activations table (omitting
spec_content_hash) before calling OpenGlobalDB, then after opening the DB verify
that the inserted row still exists and that its spec_content_hash has been
populated with a sane value; use the same helpers used in the test
(sql.ExecContext/testutil.Context(t)) to insert a row with required fields (id,
extension_name, bundle_name, profile_name, scope, created_at, updated_at) and
then query the bundle_activations row from globalDB.db to assert the original
values are preserved and spec_content_hash is non-empty/valid.
🪄 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: 2dec77c2-2777-436d-824d-0d637ae8c572
⛔ Files ignored due to path filters (77)
.agents/skills/documentation-writer/SKILL.mdis excluded by!**/*.md,!.agents/**.codex/plans/2026-04-14-extension-bundles.mdis excluded by!**/*.md.compozy/tasks/extgaps/_techspec.mdis excluded by!**/*.md.compozy/tasks/extgaps/adrs/adr-001.mdis excluded by!**/*.md.compozy/tasks/extgaps/adrs/adr-002.mdis excluded by!**/*.md.compozy/tasks/extgaps/adrs/adr-003.mdis excluded by!**/*.md.compozy/tasks/extgaps/qa/evidence/cli-extension-disable-after-deactivate.jsonis excluded by!**/*.json.compozy/tasks/extgaps/qa/evidence/cli-extension-enable.jsonis excluded by!**/*.json.compozy/tasks/extgaps/qa/evidence/http-automation-jobs.jsonis excluded by!**/*.json.compozy/tasks/extgaps/qa/evidence/http-automation-triggers.jsonis excluded by!**/*.json.compozy/tasks/extgaps/qa/evidence/http-bridges.jsonis excluded by!**/*.json.compozy/tasks/extgaps/qa/evidence/http-bundles-activate.jsonis excluded by!**/*.json.compozy/tasks/extgaps/qa/evidence/http-bundles-activation-get.jsonis excluded by!**/*.json.compozy/tasks/extgaps/qa/evidence/http-bundles-activation-patch.jsonis excluded by!**/*.json.compozy/tasks/extgaps/qa/evidence/http-bundles-activations-list.jsonis excluded by!**/*.json.compozy/tasks/extgaps/qa/evidence/http-bundles-catalog.jsonis excluded by!**/*.json.compozy/tasks/extgaps/qa/evidence/http-bundles-get-after-delete.jsonis excluded by!**/*.json.compozy/tasks/extgaps/qa/evidence/http-bundles-network-after-bind.jsonis excluded by!**/*.json.compozy/tasks/extgaps/qa/evidence/http-bundles-network-after-delete.jsonis excluded by!**/*.json.compozy/tasks/extgaps/qa/evidence/http-bundles-network-before-bind.jsonis excluded by!**/*.json.compozy/tasks/extgaps/qa/evidence/http-bundles-preview.jsonis excluded by!**/*.json.compozy/tasks/extgaps/qa/evidence/http-bundles-reactivate.jsonis excluded by!**/*.json.compozy/tasks/extgaps/qa/evidence/uds-bundles-catalog.jsonis excluded by!**/*.json.compozy/tasks/extgaps/qa/issues/BUG-001.mdis excluded by!**/*.md.compozy/tasks/extgaps/qa/issues/BUG-002.mdis excluded by!**/*.md.compozy/tasks/extgaps/qa/issues/BUG-003.mdis excluded by!**/*.md.compozy/tasks/extgaps/qa/issues/BUG-004.mdis excluded by!**/*.md.compozy/tasks/extgaps/qa/issues/BUG-005.mdis excluded by!**/*.md.compozy/tasks/extgaps/qa/issues/BUG-006.mdis excluded by!**/*.md.compozy/tasks/extgaps/qa/issues/BUG-007.mdis excluded by!**/*.md.compozy/tasks/extgaps/qa/screenshots/ui-after-workspace.pngis excluded by!**/*.png.compozy/tasks/extgaps/qa/screenshots/ui-automation-fresh2.pngis excluded by!**/*.png.compozy/tasks/extgaps/qa/screenshots/ui-automation-live.pngis excluded by!**/*.png.compozy/tasks/extgaps/qa/screenshots/ui-automation-triggers-after-workspace.pngis excluded by!**/*.png.compozy/tasks/extgaps/qa/screenshots/ui-automation-triggers-final.pngis excluded by!**/*.png.compozy/tasks/extgaps/qa/screenshots/ui-automation.pngis excluded by!**/*.png.compozy/tasks/extgaps/qa/screenshots/ui-bridges-after-workspace.pngis excluded by!**/*.png.compozy/tasks/extgaps/qa/screenshots/ui-bridges-live.pngis excluded by!**/*.png.compozy/tasks/extgaps/qa/screenshots/ui-bridges.pngis excluded by!**/*.png.compozy/tasks/extgaps/qa/test-cases/SMOKE-001.mdis excluded by!**/*.md.compozy/tasks/extgaps/qa/test-cases/SMOKE-002.mdis excluded by!**/*.md.compozy/tasks/extgaps/qa/test-cases/SMOKE-003.mdis excluded by!**/*.md.compozy/tasks/extgaps/qa/test-cases/SMOKE-004.mdis excluded by!**/*.md.compozy/tasks/extgaps/qa/test-cases/SMOKE-005.mdis excluded by!**/*.md.compozy/tasks/extgaps/qa/test-cases/TC-FUNC-001.mdis excluded by!**/*.md.compozy/tasks/extgaps/qa/test-cases/TC-FUNC-002.mdis excluded by!**/*.md.compozy/tasks/extgaps/qa/test-cases/TC-FUNC-003.mdis excluded by!**/*.md.compozy/tasks/extgaps/qa/test-cases/TC-FUNC-004.mdis excluded by!**/*.md.compozy/tasks/extgaps/qa/test-cases/TC-FUNC-005.mdis excluded by!**/*.md.compozy/tasks/extgaps/qa/test-cases/TC-FUNC-006.mdis excluded by!**/*.md.compozy/tasks/extgaps/qa/test-cases/TC-FUNC-007.mdis excluded by!**/*.md.compozy/tasks/extgaps/qa/test-cases/TC-FUNC-008.mdis excluded by!**/*.md.compozy/tasks/extgaps/qa/test-cases/TC-FUNC-009.mdis excluded by!**/*.md.compozy/tasks/extgaps/qa/test-cases/TC-FUNC-010.mdis excluded by!**/*.md.compozy/tasks/extgaps/qa/test-cases/TC-FUNC-011.mdis excluded by!**/*.md.compozy/tasks/extgaps/qa/test-cases/TC-FUNC-012.mdis excluded by!**/*.md.compozy/tasks/extgaps/qa/test-cases/TC-FUNC-013.mdis excluded by!**/*.md.compozy/tasks/extgaps/qa/test-cases/TC-FUNC-014.mdis excluded by!**/*.md.compozy/tasks/extgaps/qa/test-cases/TC-FUNC-015.mdis excluded by!**/*.md.compozy/tasks/extgaps/qa/test-cases/TC-INT-001.mdis excluded by!**/*.md.compozy/tasks/extgaps/qa/test-cases/TC-INT-002.mdis excluded by!**/*.md.compozy/tasks/extgaps/qa/test-cases/TC-INT-003.mdis excluded by!**/*.md.compozy/tasks/extgaps/qa/test-cases/TC-INT-004.mdis excluded by!**/*.md.compozy/tasks/extgaps/qa/test-cases/TC-INT-005.mdis excluded by!**/*.md.compozy/tasks/extgaps/qa/test-cases/TC-INT-006.mdis excluded by!**/*.md.compozy/tasks/extgaps/qa/test-cases/TC-INT-010.mdis excluded by!**/*.md.compozy/tasks/extgaps/qa/test-cases/TC-SEC-001.mdis excluded by!**/*.md.compozy/tasks/extgaps/qa/test-cases/TC-SEC-002.mdis excluded by!**/*.md.compozy/tasks/extgaps/qa/test-cases/TC-SEC-003.mdis excluded by!**/*.md.compozy/tasks/extgaps/qa/test-plans/extension-bundles-regression.mdis excluded by!**/*.md.compozy/tasks/extgaps/qa/test-plans/extension-bundles-test-plan.mdis excluded by!**/*.md.compozy/tasks/extgaps/qa/verification-report.mdis excluded by!**/*.mddocs/_refacs/20260414-bundle-runtime-reconcile.mdis excluded by!**/*.mdopenapi/agh.jsonis excluded by!**/*.jsonsdk/typescript/src/generated/contracts.tsis excluded by!**/generated/**skills-lock.jsonis excluded by!**/*.jsonweb/src/generated/agh-openapi.d.tsis excluded by!**/generated/**
📒 Files selected for processing (55)
.compozy/tasks/extgaps/qa/evidence/http-bundles-delete.status.compozy/tasks/extgaps/qa/evidence/http-bundles-get-after-delete.statusinternal/api/contract/bridges.gointernal/api/contract/bundles.gointernal/api/contract/contract.gointernal/api/core/bridges.gointernal/api/core/bundles.gointernal/api/core/errors.gointernal/api/core/handlers.gointernal/api/core/interfaces.gointernal/api/httpapi/handlers.gointernal/api/httpapi/handlers_test.gointernal/api/httpapi/httpapi_integration_test.gointernal/api/httpapi/routes.gointernal/api/httpapi/server.gointernal/api/testutil/apitest.gointernal/api/udsapi/extensions.gointernal/api/udsapi/handlers_test.gointernal/api/udsapi/routes.gointernal/api/udsapi/server.gointernal/api/udsapi/udsapi_integration_test.gointernal/automation/manager.gointernal/automation/model/persistence.gointernal/automation/model/types.gointernal/automation/model/validate.gointernal/automation/types.gointernal/bridges/delivery_projection_test.gointernal/bridges/managed_sync.gointernal/bridges/managed_sync_test.gointernal/bridges/registry.gointernal/bridges/registry_test.gointernal/bridges/types.gointernal/bundles/model/model.gointernal/bundles/service.gointernal/bundles/service_test.gointernal/cli/cli_integration_test.gointernal/daemon/boot.gointernal/daemon/bridges.gointernal/daemon/daemon.gointernal/daemon/daemon_test.gointernal/daemon/extensions.gointernal/extension/bundle.gointernal/extension/describe.gointernal/extension/install_managed.gointernal/extension/install_managed_test.gointernal/extension/manager.gointernal/extension/manifest.gointernal/extension/registry.gointernal/extension/registry_bundles_test.gointernal/store/globaldb/global_db.gointernal/store/globaldb/global_db_bridge.gointernal/store/globaldb/global_db_bridges_test.gointernal/store/globaldb/global_db_bundles.gointernal/store/globaldb/global_db_bundles_test.gointernal/store/globaldb/migrate_workspace.go
There was a problem hiding this comment.
Actionable comments posted: 4
🧹 Nitpick comments (4)
internal/bridges/managed_sync.go (1)
46-64: Constructor silently returnsnilfor nil store.Returning
nilfrom a constructor when a required dependency is missing is an unusual pattern that shifts error discovery to runtime. While the nil-receiver check at line 82 catches this, it produces a generic error message that doesn't indicate the root cause was anilstore passed to the constructor.Consider returning
(*ManagedSyncService, error)or panicking during construction if this is truly a programmer error, rather than returning a nil service that fails later.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@internal/bridges/managed_sync.go` around lines 46 - 64, The constructor NewManagedSyncer currently returns nil when the required ManagedSyncStore is nil, which defers a vague runtime error; change NewManagedSyncer to return (*ManagedSyncService, error) (or alternatively panic) and return a clear error when the store argument is nil, update callers to handle the error, and adjust downstream code that currently checks for a nil receiver on ManagedSyncService (e.g., methods that early-return on a nil receiver) to assume a non-nil service when construction succeeds; reference NewManagedSyncer, ManagedSyncService, and ManagedSyncStore when making these changes.internal/api/core/bundles.go (1)
18-22: Nil receiver check is misleading — callingh.respondErroron nilhwill panic.The check
h == nilis defensive but creates a false sense of safety. Ifhis actually nil, the subsequent call toh.respondError(c, ...)will dereference the nil pointer and panic.In practice,
his instantiated during server setup and will never be nil at runtime, so the check is unnecessary. Consider removing theh == nilportion or responding directly viac.JSONif you want to keep this ultra-defensive path.🔧 Suggested fix
func (h *BaseHandlers) ListBundleCatalog(c *gin.Context) { - if h == nil || h.Bundles == nil { - h.respondError(c, http.StatusServiceUnavailable, errors.New("api: bundle service is not configured")) + if h.Bundles == nil { + c.JSON(http.StatusServiceUnavailable, contract.ErrorPayload{Error: "api: bundle service is not configured"}) return }This same pattern repeats in
ListBundleActivations,GetBundleActivation,UpdateBundleActivation,DeleteBundleActivation,BundleNetworkSettings, andbindBundleActivateRequest.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@internal/api/core/bundles.go` around lines 18 - 22, The nil-receiver check `h == nil || h.Bundles == nil` is misleading because calling h.respondError when h is nil will panic; remove the `h == nil` portion and only check `h.Bundles == nil`, or if you want an ultra-defensive path use the gin context directly (e.g., c.JSON/http.Error) instead of calling methods on h when h is nil. Update this pattern in ListBundleCatalog and the other affected handlers (ListBundleActivations, GetBundleActivation, UpdateBundleActivation, DeleteBundleActivation, BundleNetworkSettings, bindBundleActivateRequest) so you do not call h.respondError on a nil receiver.internal/daemon/bridges_test.go (2)
33-52: Fail fast on unexpected stub calls instead of returning zero-values.Returning success defaults (
nil/nil, nil) can hide unconfigured stub usage and create false-positive tests. Prefer explicit unexpected-call errors.♻️ Proposed fix
func (s bridgeRuntimeStoreStub) ListBridgeSecretBindings(ctx context.Context, bridgeInstanceID string) ([]bridgepkg.BridgeSecretBinding, error) { if s.listBridgeSecretBindingsFn != nil { return s.listBridgeSecretBindingsFn(ctx, bridgeInstanceID) } - return nil, nil + return nil, errors.New("unexpected call: ListBridgeSecretBindings") } @@ func (s bridgeRuntimeStoreStub) PutBridgeSecretBinding(ctx context.Context, binding bridgepkg.BridgeSecretBinding) error { if s.putBridgeSecretBindingFn != nil { return s.putBridgeSecretBindingFn(ctx, binding) } - return nil + return errors.New("unexpected call: PutBridgeSecretBinding") } @@ func (s bridgeRuntimeStoreStub) DeleteBridgeSecretBinding(ctx context.Context, bridgeInstanceID string, bindingName string) error { if s.deleteBridgeSecretBindingFn != nil { return s.deleteBridgeSecretBindingFn(ctx, bridgeInstanceID, bindingName) } - return nil + return errors.New("unexpected call: DeleteBridgeSecretBinding") }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@internal/daemon/bridges_test.go` around lines 33 - 52, The stub methods ListBridgeSecretBindings, PutBridgeSecretBinding and DeleteBridgeSecretBinding should fail fast when their corresponding function fields (listBridgeSecretBindingsFn, putBridgeSecretBindingFn, deleteBridgeSecretBindingFn) are not configured; update each method to return a non-nil error (for example using fmt.Errorf with clear text like "unexpected call to ListBridgeSecretBindings") instead of returning zero-values (nil / nil, nil), and ensure fmt is imported; keep calling the configured fn when present.
26-31: Add explicit compile-time interface verification forbridgeRuntimeStoreStub.The test stub embeds
bridgeRuntimeStore, which is an interface. Per coding guidelines ("Use compile-time interface verification:var _ Interface = (*Type)(nil)"), add an explicit assertion to catch silent drift if the interface changes:var _ bridgeRuntimeStore = (*bridgeRuntimeStoreStub)(nil)Add this line after the struct definition (around line 32).
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@internal/daemon/bridges_test.go` around lines 26 - 31, Add an explicit compile-time interface verification for the test stub by inserting the assertion var _ bridgeRuntimeStore = (*bridgeRuntimeStoreStub)(nil) immediately after the bridgeRuntimeStoreStub struct definition so the compiler will fail if bridgeRuntimeStore's shape drifts; reference the bridgeRuntimeStoreStub type and the bridgeRuntimeStore interface when adding this line.
🤖 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/handlers_internal_test.go`:
- Around line 334-361: Wrap the existing
TestNetworkStatusPayloadWrapsBundleSettingsErrors body in a t.Run subtest (e.g.,
t.Run("Should wrap bundle settings errors", func(t *testing.T) { ... })) and
move the t.Parallel() call inside that subtest so the test still runs in
parallel; keep all existing setup and assertions (handlers and the call to
handlers.networkStatusPayload) unchanged but placed inside the t.Run closure to
satisfy the subtest pattern.
In `@internal/extension/bundle.go`:
- Around line 210-220: The channel/jobs/triggers/bridges duplicate checks
currently use raw trimmed names; change them to normalize keys with
bundleLookupKey(name) before storing/checking in maps (e.g., replace usage in
channelNames, jobNames, triggerNames, bridgeNames checks) so comparisons are
case-insensitive and consistent with bundle/profile validation; keep the same
empty-name validation and error messages (ErrBundleInvalid, bundleName, p.Name)
but report the original trimmed name in the error text while using
bundleLookupKey(name) for map lookup.
In `@internal/extension/install_managed.go`:
- Around line 59-60: The precheck is using the raw checksum request value which
can have surrounding whitespace or uppercase hex and will mismatch later
normalization in registry.Install; normalize the input checksum variable (e.g.,
apply strings.TrimSpace and strings.ToLower) before performing the empty check
and any comparisons against actualSourceChecksum so that comparisons in places
like the block referencing actualSourceChecksum and the later comparison region
(the code around the other checksum checks) use the same normalized form as
registry.Install; update references to use the normalized checksum variable for
the empty validation and equality checks.
- Around line 153-155: copyInstallTree currently canonicalizes the source root
but does not pass it down, so EvalSymlinks in
copyInstallDirectoryContents/copyInstallEntry can dereference links outside the
extension root; plumb the canonical source root from copyInstallTree into
copyInstallDirectoryContents and copyInstallEntry (seed it with the
canonicalized absSourceRoot) and, after resolving any symlink target, call
filepath.Rel(sourceRoot, resolvedPath) and reject the entry if the result
escapes (starts with ".." or returns an error). Ensure all traversal sites
mentioned (the calls around lines 175-197 and 238-263) use the new sourceRoot
parameter and perform the same relative-root check before copying.
---
Nitpick comments:
In `@internal/api/core/bundles.go`:
- Around line 18-22: The nil-receiver check `h == nil || h.Bundles == nil` is
misleading because calling h.respondError when h is nil will panic; remove the
`h == nil` portion and only check `h.Bundles == nil`, or if you want an
ultra-defensive path use the gin context directly (e.g., c.JSON/http.Error)
instead of calling methods on h when h is nil. Update this pattern in
ListBundleCatalog and the other affected handlers (ListBundleActivations,
GetBundleActivation, UpdateBundleActivation, DeleteBundleActivation,
BundleNetworkSettings, bindBundleActivateRequest) so you do not call
h.respondError on a nil receiver.
In `@internal/bridges/managed_sync.go`:
- Around line 46-64: The constructor NewManagedSyncer currently returns nil when
the required ManagedSyncStore is nil, which defers a vague runtime error; change
NewManagedSyncer to return (*ManagedSyncService, error) (or alternatively panic)
and return a clear error when the store argument is nil, update callers to
handle the error, and adjust downstream code that currently checks for a nil
receiver on ManagedSyncService (e.g., methods that early-return on a nil
receiver) to assume a non-nil service when construction succeeds; reference
NewManagedSyncer, ManagedSyncService, and ManagedSyncStore when making these
changes.
In `@internal/daemon/bridges_test.go`:
- Around line 33-52: The stub methods ListBridgeSecretBindings,
PutBridgeSecretBinding and DeleteBridgeSecretBinding should fail fast when their
corresponding function fields (listBridgeSecretBindingsFn,
putBridgeSecretBindingFn, deleteBridgeSecretBindingFn) are not configured;
update each method to return a non-nil error (for example using fmt.Errorf with
clear text like "unexpected call to ListBridgeSecretBindings") instead of
returning zero-values (nil / nil, nil), and ensure fmt is imported; keep calling
the configured fn when present.
- Around line 26-31: Add an explicit compile-time interface verification for the
test stub by inserting the assertion var _ bridgeRuntimeStore =
(*bridgeRuntimeStoreStub)(nil) immediately after the bridgeRuntimeStoreStub
struct definition so the compiler will fail if bridgeRuntimeStore's shape
drifts; reference the bridgeRuntimeStoreStub type and the bridgeRuntimeStore
interface when adding this line.
🪄 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: 57ca7a1f-bb82-4a75-a497-31c9d0c32697
⛔ Files ignored due to path filters (19)
.compozy/tasks/extgaps/reviews-001/issue_001.mdis excluded by!**/*.md.compozy/tasks/extgaps/reviews-001/issue_002.mdis excluded by!**/*.md.compozy/tasks/extgaps/reviews-001/issue_003.mdis excluded by!**/*.md.compozy/tasks/extgaps/reviews-001/issue_004.mdis excluded by!**/*.md.compozy/tasks/extgaps/reviews-001/issue_005.mdis excluded by!**/*.md.compozy/tasks/extgaps/reviews-001/issue_006.mdis excluded by!**/*.md.compozy/tasks/extgaps/reviews-001/issue_007.mdis excluded by!**/*.md.compozy/tasks/extgaps/reviews-001/issue_008.mdis excluded by!**/*.md.compozy/tasks/extgaps/reviews-001/issue_009.mdis excluded by!**/*.md.compozy/tasks/extgaps/reviews-001/issue_010.mdis excluded by!**/*.md.compozy/tasks/extgaps/reviews-001/issue_011.mdis excluded by!**/*.md.compozy/tasks/extgaps/reviews-001/issue_012.mdis excluded by!**/*.md.compozy/tasks/extgaps/reviews-001/issue_013.mdis excluded by!**/*.md.compozy/tasks/extgaps/reviews-001/issue_014.mdis excluded by!**/*.md.compozy/tasks/extgaps/reviews-001/issue_015.mdis excluded by!**/*.md.compozy/tasks/extgaps/reviews-001/issue_016.mdis excluded by!**/*.md.compozy/tasks/extgaps/reviews-001/issue_017.mdis excluded by!**/*.md.compozy/tasks/extgaps/reviews-001/issue_018.mdis excluded by!**/*.md.compozy/tasks/extgaps/reviews-001/issue_019.mdis excluded by!**/*.md
📒 Files selected for processing (17)
internal/api/core/bundles.gointernal/api/core/handlers.gointernal/api/core/handlers_internal_test.gointernal/api/core/network_test.gointernal/bridges/managed_sync.gointernal/bridges/managed_sync_test.gointernal/bridges/registry.gointernal/bundles/service.gointernal/bundles/service_test.gointernal/daemon/bridges.gointernal/daemon/bridges_test.gointernal/extension/bundle.gointernal/extension/install_managed.gointernal/extension/install_managed_test.gointernal/extension/registry_bundles_test.gointernal/store/globaldb/global_db_bridges_test.gointernal/store/globaldb/global_db_bundles_test.go
✅ Files skipped from review due to trivial changes (4)
- internal/store/globaldb/global_db_bundles_test.go
- internal/extension/install_managed_test.go
- internal/bundles/service_test.go
- internal/bundles/service.go
🚧 Files skipped from review as they are similar to previous changes (6)
- internal/store/globaldb/global_db_bridges_test.go
- internal/api/core/handlers.go
- internal/extension/registry_bundles_test.go
- internal/daemon/bridges.go
- internal/bridges/registry.go
- internal/bridges/managed_sync_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
Improvements
Persistence