You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
* feat: Improved apply validation errors
* feat: Refactored to share the same plugin error type. Use the reporter to determine how to present it.
* fix: Fixed display functions to be async
* feat: Improve the copy and formatting for apply validation error. Fix pretty print error for NOOP. Added to CLAUDE.md
* feat: Improved copy again
* feat: Added partial applys. If a resource fails to apply, skip it and all transitive dependent resources. Apply un-related resources.
* feat: Further refactored the error messages. Combined it with a final display message change. The final display message will now tell the user a list of all changes that were made.
* feat: refactored the code so that the final apply message is handled entirely inside the reporters.
* feat: Additional refactoring. Cleaned up dead APPLY_VALIDATION_ERROR dead code. Moved rendering logic to the ApplyComplete component instead.
* fix: Fix /etc/os-release not present
4.**Sudo Caching**: Password cached in memory during session unless `--secure` flag used
186
186
5.**File Watcher**: Use `persistent: false` option to prevent hanging processes
187
-
6.**Linting**: ESLint enforces single quotes, specific import ordering, and strict type safety
187
+
6.**Linting**: ESLint enforces single quotes, specific import ordering, and strict type safety
188
+
7.**Reporter display methods are async**: All `Reporter` interface display methods (`displayPlan`, `displayImportResult`, `displayFileModifications`, `displayMessage`, `displayPluginError`) return `Promise<void>`. Always `await` them at call sites — `DefaultReporter.updateRenderState()` has a 50ms sleep, so unawaited calls cause `process.exit(1)` to fire before the UI renders.
189
+
8.**Mock reporter async assertions**: Assertions inside `MockReporter` config callbacks (e.g. `displayFileModifications`) will silently pass if the call isn't awaited. Making display methods async surfaced latent bugs where expected file paths were wrong.
190
+
191
+
## Plugin Error Handling Architecture
192
+
193
+
Plugin errors flow as structured `PluginErrorData` over IPC and are caught as `PluginError` instances on the CLI side:
**Reporter as view model**: Reporters (not components) decide how to render each `errorType`. `DefaultReporter.displayPluginError()` branches on `errorType` to set the appropriate `RenderStatus` (`APPLY_VALIDATION_ERROR` with a `ResourcePlan` for plan diffs, `PLUGIN_ERROR` with a message string for generic errors). The `DefaultComponent` is purely display.
207
+
208
+
**Shared formatter**: `src/ui/plugin-error-formatter.ts` exports `formatApplyValidationError(error: PluginError): string` used by both `PlainReporter` and `DefaultComponent`.
209
+
210
+
**Backward compat**: `plugin.ts#toErrorData()` validates IPC data against `ErrorResponseDataSchema` (AJV); falls back to `{ errorType: 'unknown', message: data }` for old plugins sending bare strings.
"description": "Codify is a configuration-as-code tool that declaratively installs and manages developer tools and applications. Check out https://dashboard.codifycli.com for an editor.",
0 commit comments