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
{{ message }}
Repository navigation
Commit bef6369
Browse filesBrowse the repository at this point in the historyBrowse files
Adds a `template` config block (like `project`, it lives in the CLI and is
never sent to a plugin) that includes the resources of a Codify template:
a registry template (`name` or `@profile/name`) or a dashboard document
(uuid). Requires @codifycli/schemas 1.3.0.
- TemplateExpander replaces each template declaration with its resources,
in place and recursively. Templates can't declare plugins. Cycles are
skipped and a template included twice is added once. Every resource
records the template chains it came from (origins); dependsOn/os/distro
on a template declaration apply to every resource in it and
`dependsOn: ["template.<name>"]` resolves to the template's resources.
- After plugin init, TemplateResourceMerger merges template resources
that the owning plugin matches (allowMultiple identifying parameters,
or any resource of the type when allowMultiple is false) into the
project resource or an earlier template resource. Arrays are combined,
objects merged and scalar conflicts keep the winner (shown as plan
warnings). Unmatched duplicates get numeric names in declaration order.
- The template resources are planned and applied with the rest of the
project. DependencyGraphResolver is now a stable Kahn sort, so resources
keep their declaration order (template resources stay at the template's
position) unless a dependency requires a move. Previously independent
resources came out roughly reversed.
- Actions that only come from templates must be approved before planning
(their condition runs during the plan). Declining stops the run.
Approvals are remembered in ~/.codify/approved-template-commands.json
until the template or command changes. -y does not approve them;
--auto-approve-all (or -yy) does. The json reporter never approves.
- `codify apply <template>` is now a project with a single template
declaration (CodifyParser.parseTemplate removed).
- Plans show which template a resource came from.
- import/refresh/edit don't expand templates. Fixes the file modification
calculator corrupting files with template blocks when deleting a
resource (template blocks were not counted).
- Template versions are in the schema but not supported by the registry
yet: declaring one throws.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016QnBk4KjqTgmDacTAp63Un
Copy file name to clipboardExpand all lines: CLAUDE.md
+21Lines changed: 21 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -188,6 +188,27 @@ Parent Process Plugin Process
188
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
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
190
191
+
## Template Resource Architecture
192
+
193
+
`{ "type": "template", "source": "nvm" | "@profile/name" | "<dashboard document uuid>" }` is a core config block (like `project`). It lives in the CLI, is never sent to a plugin, and is replaced by the resources of the template.
194
+
195
+
**Flow** (only for `plan`, `apply` and `destroy`: `PluginInitOrchestrator` with `expandTemplates: true`):
→ TemplateCommandApproval.ensureApproved() → plan → apply
200
+
```
201
+
202
+
-**`src/entities/template-config.ts`**: `TemplateConfig` (`ConfigType.TEMPLATE`), validated against `TemplateSchema` from `@codifycli/schemas`. `Project.templateConfigs` holds the declarations and `Project.declarations` keeps the declaration order.
203
+
-**`src/templates/template-loader.ts`**: `ApiTemplateLoader` loads registry templates (`DashboardApiClient.getTemplate`, no login) or dashboard documents (uuid, login required). `version` is in the schema but not supported by the registry yet (throws). Local files are intentionally not supported.
204
+
-**`src/templates/template-expander.ts`**: expands templates recursively, in place. Templates can't declare plugins. Each resource records `origins` (the template chains it was included through). Cycles are skipped; a template included twice is added once and gains an extra origin.
205
+
-**Template constraints**: `dependsOn` on a template declaration is stored in `ResourceConfig.inheritedDependsOn` (never written to files or sent to plugins). `os`/`distro` on a template are applied through `origins` in the Project filters. `dependsOn: ["template.<name>"]` / `"template"` / `"<name>"` resolve to the resources of that template.
206
+
-**`src/templates/template-resource-merger.ts`**: after plugin init, template resources that the owning plugin `match`es with an earlier resource are merged into it (project resources win, then earlier templates). Arrays are combined, objects merged, scalar conflicts keep the winner and become `Plan.warnings`. Unmatched unnamed duplicates get numeric names in declaration order.
207
+
-**Ordering**: `DependencyGraphResolver` is a stable Kahn sort (declaration order unless a dependency requires a move), so template resources stay at the template's position.
208
+
-**`src/templates/template-command-approval.ts`**: `action` resources only declared in templates must be approved before planning (the `condition` runs during the plan). Approvals are stored in `~/.codify/approved-template-commands.json` keyed by a hash of the template sources and the full config. Declining throws `TemplateCommandsDeclinedError` (whole run stops). `-y` does not approve them; `--auto-approve-all` / `-yy` does. `Reporter.promptTemplateCommandApproval` must never auto approve (Json reporter throws, Stub declines).
209
+
-`codify apply <template>` is a project with a single template declaration (the resolver's fetched template is seeded into the loader).
210
+
-`import`/`refresh`/`edit` do not expand templates: template blocks are left untouched in files.
211
+
191
212
## Plugin Error Handling Architecture
192
213
193
214
Plugin errors flow as structured `PluginErrorData` over IPC and are caught as `PluginError` instances on the CLI side:
* --auto-approve-all (or -yy) approves everything, including commands that come from templates. A single -y never
5
+
* approves commands from templates.
6
+
*/
7
+
exportconstautoApproveAllFlag=Flags.boolean({
8
+
description: 'Approve everything without prompting, including commands (actions) that come from templates. Same as -yy. Only use this with templates you trust.',
9
+
default: false,
10
+
});
11
+
12
+
/** True if --auto-approve-all was passed or -y was passed twice (-yy or -y -y). */
0 commit comments