Background
While building an agent-driven integration scaffolding skill for Lefthook's Frigg projects, I compared what frigg init produces against Lefthook's production Frigg templates (e.g. aes--frigg, quo--frigg, clyde--frigg). The gap is large and consistent across templates — frigg init produces a minimal stub, while every production project independently reinvents the same production posture on top.
Concretely, the Lefthook templates layer the following on top of what frigg init gives you:
- App definition with production posture —
vpcIsolation: 'isolated' + enableVPCEndpoints: true + selfHeal: true; encryption.fieldLevelEncryptionMethod: 'kms'; Aurora Postgres (publiclyAccessible: false, capacity 0.5–1); multi-mode auth (friggToken, sharedSecret, password) pre-wired; ~50 lines of env var mapping.
- Full dev/test harness — ~39 prod + 25 dev deps (
@friggframework/serverless-plugin, @friggframework/test, @friggframework/devtools, jest + chai + nock + faker, serverless-esbuild + serverless-kms-grants + serverless-offline).
- CI/CD + Changesets — 5 GitHub Actions workflows (ci, deploy-dev, deploy-prod, release, rollback),
.changeset/ with @changesets/cli configured for GitHub changelog automation, AWS credential rotation, 30-minute job timeouts.
- Reference structure + local dev — working reference integration under
src/integrations/, jest setup with integration test examples, ESLint + Prettier + knip configs, Docker Compose for local Postgres + auth-server, ~8 npm test scripts.
This means every new production Frigg project today is a copy-paste-from-another-project exercise. There's no first-class path from frigg init to a production-shaped scaffold, and the current --template flag is vestigial — see "Current state" below.
Proposal
Replace the hardcoded BackendFirstHandler with a proper template system + an interactive init interview that scaffolds production-grade defaults and common starter integrations.
1. Template system (function, not hardcode)
- Define a
Template interface: name, description, files (with token substitution), post-install steps, prompts.
- Ship a small set of first-party templates:
minimal (today's BackendFirstHandler), production (Lefthook-equivalent posture), oauth-starter (production + reference OAuth integration), api-key-starter (production + reference API-key integration).
- Allow community/external templates via
frigg init --template <name> or frigg init --template github:<owner>/<repo> so org-specific scaffolds (like Lefthook's) can be selected directly rather than copy-pasted.
2. Common starter integrations
Bundle 2–3 reference integrations under src/integrations/ in the production templates:
- One OAuth2 integration (e.g. HubSpot-style, full event lifecycle wired up).
- One API-key integration (e.g. with
getAuthorizationRequirements rendering an interactive form).
- One webhook-driven integration (signature validation, queue fan-out, Process Model usage).
These serve as both copy-paste starting points and as living documentation of integration patterns (createFriggCommands, QueueManager, SyncOrchestrator, the USER_ACTION / CRON / QUEUE / WEBHOOK event types).
3. Default config presets
Expose the production posture as named presets the template can select:
posture: 'production' → vpcIsolation: 'isolated', enableVPCEndpoints: true, selfHeal: true, KMS field-level encryption, Aurora Postgres non-public.
posture: 'development' → public Postgres, AES encryption, no VPC isolation.
posture: 'experimental' → today's minimal stub.
Templates declare their preset; the interview can override it.
4. Init interview that scaffolds overrides
After template selection, prompt for the choices that diverge per-project:
- Database (Mongo vs Postgres-Aurora, capacity range)
- Encryption method (KMS vs AES)
- Auth modes to enable (friggToken / sharedSecret / password / SSO)
- VPC configuration (isolated / shared / off)
- Initial API modules to pre-install (multi-select from a curated list)
- CI provider (GitHub Actions / none) and deploy targets (dev / staging / prod stages)
- Changesets on/off
Write the answers into the generated backend/index.js appDefinition and the relevant CI workflows, so the project starts with overrides reflecting real choices rather than commented placeholders. Re-running frigg init in an existing project (or a frigg init --reconfigure mode) could update overrides without overwriting integration code.
Current state — --template flag is vestigial
packages/devtools/frigg-cli/index.js:93-98 declares:
.command('init [templateName]')
.option('-t, --template <template>', 'template to use', 'backend-only')
But init-command/index.js:65-90 then has:
if (!options.template && !options.legacyFrontend) {
// ...BackendFirstHandler...
}
// otherwise:
console.log(chalk.red('Legacy template system is no longer supported.'));
process.exit(1);
Because the --template flag has a default of 'backend-only', options.template is always truthy, so the condition !options.template is always false. By the literal reading, every frigg init should hit the "Legacy template system is no longer supported" error path. Either commander's default semantics here behave differently than I expect, or this command is broken in HEAD. Either way, the template flag is half-removed and the templates directory (templates/backend/) referenced by the legacy TemplateHandler is orphaned. This proposal is also the cleanup path for that ambiguity.
Related
Why now
Agent-driven scaffolding (Claude Code skills, internal automations) needs a deterministic, parameterized way to spin up production-shaped Frigg projects. Without a template system, every agent has to either (a) copy a known-good external repo and template-substitute, or (b) re-implement the production posture procedurally. Both options exist today in Lefthook's tooling; neither scales as more orgs adopt Frigg. A first-class template system would also let the Frigg docs / starter examples stay in sync with the framework itself rather than drifting in downstream repos.
Happy to scope down (e.g. ship posture presets + the interactive interview first, leave external-template loading for a follow-up) — flagging the whole picture here so the team can decide where to draw the line.
Background
While building an agent-driven integration scaffolding skill for Lefthook's Frigg projects, I compared what
frigg initproduces against Lefthook's production Frigg templates (e.g.aes--frigg,quo--frigg,clyde--frigg). The gap is large and consistent across templates —frigg initproduces a minimal stub, while every production project independently reinvents the same production posture on top.Concretely, the Lefthook templates layer the following on top of what
frigg initgives you:vpcIsolation: 'isolated'+enableVPCEndpoints: true+selfHeal: true;encryption.fieldLevelEncryptionMethod: 'kms'; Aurora Postgres (publiclyAccessible: false, capacity 0.5–1); multi-mode auth (friggToken,sharedSecret,password) pre-wired; ~50 lines of env var mapping.@friggframework/serverless-plugin,@friggframework/test,@friggframework/devtools, jest + chai + nock + faker, serverless-esbuild + serverless-kms-grants + serverless-offline)..changeset/with@changesets/cliconfigured for GitHub changelog automation, AWS credential rotation, 30-minute job timeouts.src/integrations/, jest setup with integration test examples, ESLint + Prettier + knip configs, Docker Compose for local Postgres + auth-server, ~8 npm test scripts.This means every new production Frigg project today is a copy-paste-from-another-project exercise. There's no first-class path from
frigg initto a production-shaped scaffold, and the current--templateflag is vestigial — see "Current state" below.Proposal
Replace the hardcoded
BackendFirstHandlerwith a proper template system + an interactive init interview that scaffolds production-grade defaults and common starter integrations.1. Template system (function, not hardcode)
Templateinterface: name, description, files (with token substitution), post-install steps, prompts.minimal(today'sBackendFirstHandler),production(Lefthook-equivalent posture),oauth-starter(production + reference OAuth integration),api-key-starter(production + reference API-key integration).frigg init --template <name>orfrigg init --template github:<owner>/<repo>so org-specific scaffolds (like Lefthook's) can be selected directly rather than copy-pasted.2. Common starter integrations
Bundle 2–3 reference integrations under
src/integrations/in the production templates:getAuthorizationRequirementsrendering an interactive form).These serve as both copy-paste starting points and as living documentation of integration patterns (
createFriggCommands,QueueManager,SyncOrchestrator, theUSER_ACTION/CRON/QUEUE/WEBHOOKevent types).3. Default config presets
Expose the production posture as named presets the template can select:
posture: 'production'→vpcIsolation: 'isolated',enableVPCEndpoints: true,selfHeal: true, KMS field-level encryption, Aurora Postgres non-public.posture: 'development'→ public Postgres, AES encryption, no VPC isolation.posture: 'experimental'→ today's minimal stub.Templates declare their preset; the interview can override it.
4. Init interview that scaffolds overrides
After template selection, prompt for the choices that diverge per-project:
Write the answers into the generated
backend/index.jsappDefinitionand the relevant CI workflows, so the project starts with overrides reflecting real choices rather than commented placeholders. Re-runningfrigg initin an existing project (or afrigg init --reconfiguremode) could update overrides without overwriting integration code.Current state —
--templateflag is vestigialpackages/devtools/frigg-cli/index.js:93-98declares:But
init-command/index.js:65-90then has:Because the
--templateflag has a default of'backend-only',options.templateis always truthy, so the condition!options.templateis always false. By the literal reading, everyfrigg initshould hit the "Legacy template system is no longer supported" error path. Either commander's default semantics here behave differently than I expect, or this command is broken in HEAD. Either way, the template flag is half-removed and the templates directory (templates/backend/) referenced by the legacyTemplateHandleris orphaned. This proposal is also the cleanup path for that ambiguity.Related
Why now
Agent-driven scaffolding (Claude Code skills, internal automations) needs a deterministic, parameterized way to spin up production-shaped Frigg projects. Without a template system, every agent has to either (a) copy a known-good external repo and template-substitute, or (b) re-implement the production posture procedurally. Both options exist today in Lefthook's tooling; neither scales as more orgs adopt Frigg. A first-class template system would also let the Frigg docs / starter examples stay in sync with the framework itself rather than drifting in downstream repos.
Happy to scope down (e.g. ship
posturepresets + the interactive interview first, leave external-template loading for a follow-up) — flagging the whole picture here so the team can decide where to draw the line.