Initialize Config
Generate or update the Nova config file with an interactive wizard that guides you through each step and saves when you confirm.
Summary
The initialize command scaffolds and maintains the nova.config.json file by opening a guided flow across project metadata, key entities, and canonical URLs.
Existing values populate each prompt so you can edit an accurate snapshot and only persist changes when you confirm them.
Why Use This Command?
- The wizard writes the JSON with only the fields you confirm, no extra cleanup required.
- The wizard lists each field, explains what each field is for, and guides you to fill known values.
- Avoid typos and mismatched formats with built-in validation for slugs, emails, and URLs.
- Dry run lets you walk through the questions without touching the config file until you're ready.
Use Cases
- Onboarding — Create the first
nova.config.jsonfor a new or migrated repository. - Metadata refresh — Keep project descriptions, entities, and canonical URLs in sync after ownership changes.
- Normalization — Clean up manually edited entries without hunting for typos in raw JSON.
- Generator support — Feed consistent metadata to Nova generators so docs, README files, and release notes stay accurate.
Requirements
- Node.js runtime — Use any Node.js LTS release with either the installed
novaCLI ornpx. - Project root — Run the command from the directory containing the top-level
package.json(monorepo root included). - Interactive terminal — The session needs to support interactive prompts for the wizard to function.
Usage
You can run this command in two ways:
Options
| Flag | Description |
|---|---|
-d, --dry-run | Run without writing any files. |
-r, --replace-file | Overwrite the existing nova.config.json instead of creating a dated copy. |
-s, --status | Show the read-only GitHub environment status and exit without opening the wizard. |
Read-Only Environment Status
Use --status when you only want to compare the environment declarations with their GitHub Variable and Secret names. This path does not open the wizard and does not write nova.config.json or reconcile any values.
nova utility initialize --status
Flow Overview
Without --status, the command loops until you choose Save & Exit or Cancel. You can edit any category multiple times during the same run.
Editing an existing config?
Existing values are pre-filled in each prompt. Press Enter to keep a value, type a new value to replace it, or enter a single space to clear that field.
Project
- Purpose: Edit project display name, slug, short/long descriptions, keywords, legal name, pronouns, supported platforms, starting year, and license in one guided step.
- Nice to know: Slug updates propagate to workspace names for roles that depend on it (
project,docs,config,app,tool) to keep names consistent. Pronouns control first-person wording (we/us/our vs I/me/my) in generated files, platforms drive bug report dropdowns, and starting year plus license feed the LICENSE generator. - Things to watch: Slug allows only letters, numbers, hyphens, and underscores up to 214 characters; keywords are validated per item (50 characters max); starting year must be an integer ≥ 1970.
Entities
- Purpose: Manage project-related people and organizations with name, email, URL, and roles in a single flow.
- Nice to know: Roles are chosen from the allowed set (author, contributor, supporter) so you don't have to remember labels.
- Things to watch: Emails must be valid (contain
@and a domain); URLs must be validhttp://orhttps://before they're saved.
Emails
- Purpose: Capture a canonical contact for issues/support so tools and metadata can reference a single address.
- Nice to know: Single email field today, kept simple for quick updates.
- Things to watch: Only valid addresses persist; blanks remove the stored email.
URLs
- Purpose: Configure canonical links with validation/normalization before persisting: homepage, repository, bugs, license, logo, docs, npm, docker, funding, privacy policy, and terms of use.
- Nice to know: Repository accepts
git:,git+https:,git+ssh:,git+http:plushttp://,https://; all other URLs arehttp://,https://only. Privacy policy and terms of use URLs appear in generated GitHub issue templates. - Things to watch: Funding sources are entered comma-separated and saved as a list after validation.
Workspaces
- Purpose: List detected workspaces (
package.json) and edit each with role/policy in one place. - Nice to know: Roles (project, config, docs, app, package, tool, template) and policies (freezable, trackable, distributable) are constrained to allowed combinations so you don't accidentally pick an invalid pairing.
- Things to watch: Naming rules enforced by role (config/app/tool require the project-slug prefix when set); distributable workspaces can opt into syncing selected metadata fields.
Environment variables
Environment variables and secrets live in the top-level environment block and are editable in the Environment category below.
Workflows
- Purpose: Manage the list of GitHub Actions workflow templates that the workflow generator reads from at generation time.
- Nice to know: The menu lists existing workflow entries with Edit and Remove actions alongside an Add option and a Back option to return to the category menu. When adding or editing, the wizard prompts for a template (chosen from the bundled set), a name, triggers (selected from the template's available options), upstream workflows when using a
workflow-run-*trigger, and per-variable settings. Each variable prompt includes a description and example value to guide input. - Things to watch: The name must be unique within the same template so the output filenames remain distinct. Upstream choices use another workflow's
{template}-{name}key. Multiple upstream choices are alternatives: any one completion can start this workflow; the wizard does not create a wait-for-all chain.
Multiline values
The interactive prompt is single-line. To include line breaks in a setting value (e.g., issue messages with paragraphs), type \n where you want a newline.
The wizard converts \n sequences to actual line breaks when saving. Alternatively, edit nova.config.json directly.
GitHub
- Purpose: Configure GitHub repository settings, policies, issue-template fields, and the GitHub recipes stored under the top-level
recipes.githubblock. - Nice to know: Recipe toggles cover
sync-actions,sync-features,sync-identity,sync-labels,sync-policies,sync-rulesets, andsync-security. Features cover Issues, Wiki, Projects, Discussions, and Sponsorships. Guided policies cover visibility, default branch, merge methods, and automatic head-branch deletion. - Advanced repository settings: Actions, labels, security, rulesets, merge presentation, auto-merge, update-branch, and web-signoff values already in the config are preserved when the wizard saves. Edit those values through the complete
githubconfig reference; the wizard does not invent GitHub policy defaults for you. - Bug report fields: A multiselect chooses which platform field files the issue template generator includes, saved under
github.issueTemplate.bugReportFields. Leaving every option unselected omits the field so the generator falls back to fields derived fromproject.platforms. - Things to watch: Owner and repository name are required (non-empty) and trimmed before they're saved.
Ignores
- Purpose: Manage the project-specific
.gitignoreexcludes that the gitignore generator appends under the Project Excludes section, saved undergitignore.projectExcludes. - Nice to know: On first open with nothing configured yet, the editor imports any entries already beneath the Project Excludes marker in your current
.gitignoreso you start from your existing list. - Things to watch: Patterns are managed as a plain list with Add, Edit, and Remove actions; the generator stays non-interactive and reads only what you save here.
Migrating an existing project
If your repository already has a hand-maintained .gitignore, open the Ignores category once to import those entries into nova.config.json before regenerating. A regenerate emits only what the config holds, so excludes that were never imported are dropped from the output.
AI Tools
- Purpose: Select which AI tools the agent-conventions generator emits files for, saved under the top-level
agentsfield. Claude Code writesCLAUDE.mdand Codex writesAGENTS.md; both shareVISION.md,PROJECT_RULES.md, andconventions/*.md. - Nice to know: The category is a multiselect that pre-checks whatever is already stored, so reopening it shows your current selection.
- Things to watch: At least one tool must stay selected — the menu will not let you save an empty list, since the generator has nothing to emit for zero tools.
Environment
- Purpose: Manage the
environmentblock — per-workspace environment values, project-wide keys, and their namespace prefixes — without editingnova.config.jsonby hand. - Nice to know: Each value has a required
reach:localstays on the developer machine,managedis tracked locally and on GitHub but delivered nowhere,buildis injected into CI builds, andruntimeis reconciled to deployed servers.managed,build, andruntimevalues also requiresecretto choose GitHub Secret or Variable storage. The wizard can add the repo root./workspace alongside the others, bringing its.envunder management. - Things to watch: Removing a value is confirm-gated and offers to drop its local
.envline as well. Every namespace — theprojectgroup, each workspace (including the root./), and each workflow — requires a non-emptyprefixbefore it can be saved. On exit, the section can check GitHub status and reconcile — stubbing missing keys and deleting stale ones through theghCLI — so Nova manages key names and existence only, never their values.
Settings
- Purpose: Select the project's release strategy: SemVer (
major.minor.patch) or CalVer (YYYY.MM.MICRO). - Nice to know: With no release history, you can revisit this category and change the strategy before the first release.
- Things to watch: Once the root or any non-freezable workspace changelog contains a release heading, Nova detects that history and makes the strategy read-only. A configured mismatch, mixed strategies, or an unsupported numeric heading stops initialization and identifies the affected changelog.
Saving and Canceling
- Choosing Save & Exit writes to a file called
nova.config.json. - Choosing Cancel exits immediately without persisting changes and prints a debug log.
Output Example
{
"project": {
"name": {
"slug": "example",
"title": "Example"
},
"description": {
"short": "A Nova-powered JavaScript toolkit."
},
"keywords": ["example", "nova", "tooling"],
"legalName": "Example Author LLC",
"pronouns": "business",
"platforms": ["nodejs", "linux", "windows"],
"startingYear": 2025,
"license": "MIT"
},
"entities": [
{
"name": "Example Author",
"email": "[email protected]",
"url": "https://example.com/author",
"roles": ["author"]
}
],
"emails": {
"bugs": "[email protected]"
},
"github": {
"owner": "example",
"repo": "example-project",
"topics": ["nova", "tooling"],
"features": {
"issues": true,
"wiki": false,
"projects": false,
"discussions": false,
"sponsorships": true
},
"policies": {
"visibility": "public",
"defaultBranch": "main",
"mergeMethods": {
"merge": false,
"squash": true,
"rebase": false
},
"autoDeleteHeadBranch": true
},
"issueTemplate": {
"bugReportFields": ["nodejs.yml", "screenshots.yml"]
}
},
"urls": {
"homepage": "https://example.com",
"repository": "https://github.com/example/example-project",
"bugs": "https://github.com/example/example-project/issues",
"license": "https://github.com/example/example-project/blob/main/LICENSE",
"logo": "https://example.com/assets/logo.svg",
"documentation": "https://docs.example.com/project",
"npm": "https://www.npmjs.com/package/example-project",
"docker": "https://hub.docker.com/r/example/example-project",
"fundSources": ["https://github.com/sponsors/example"],
"privacyPolicy": "https://example.com/privacy",
"termsOfUse": "https://example.com/terms"
},
"workspaces": {
"./": {
"name": "example-project",
"role": "project",
"policy": "freezable"
},
"./apps/docs": {
"name": "example-docs",
"role": "docs",
"policy": "freezable"
},
"./packages/nova": {
"name": "@company/example",
"role": "package",
"policy": "distributable"
}
},
"workflows": [
{
"template": "lock-inactive-issues",
"name": "project",
"triggers": ["schedule-weekly"]
},
{
"template": "publish",
"name": "project",
"triggers": ["release"],
"build": ["./packages/nova"],
"deploy": [
{
"to": "npm",
"path": "./packages/nova"
}
],
"with": {
"NPM_TOKEN": "NPM_TOKEN"
}
}
],
"gitignore": {
"projectExcludes": [".local/", "scratch/"]
},
"agents": ["claude-code", "codex"],
"recipes": {
"github": {
"sync-actions": { "enabled": false },
"sync-features": { "enabled": true },
"sync-identity": { "enabled": true },
"sync-labels": { "enabled": false },
"sync-policies": { "enabled": true },
"sync-rulesets": { "enabled": false },
"sync-security": { "enabled": false }
},
"license": {
"update-copyright": { "enabled": true }
},
"read-me": {
"update-badges": { "enabled": true },
"update-credits": { "enabled": true }
},
"package-json": {
"./": {
"cleanup": {
"enabled": true,
"settings": {
"removeUnknownKeys": true,
"reorderKeys": true
}
},
"normalize-dependencies": {
"enabled": true,
"settings": {
"pinDependencyVersions": true,
"pinDevDependencyVersions": true
}
}
},
"./packages/nova": {
"sync-identity": {
"enabled": true,
"settings": {
"description": true,
"keywords": true,
"displayName": true
}
}
}
}
},
"environment": {
"project": {
"prefix": "EXAMPLE_",
"variables": [
{ "key": "NPM_TOKEN", "reach": "managed", "secret": true }
]
},
"workspaces": {
"./": {
"prefix": "ROOT_"
},
"./apps/docs": {
"prefix": "DOCS_",
"variables": [
{ "key": "LOCAL_API_MOCK", "reach": "local", "defaultValue": "http://127.0.0.1:8787" },
{ "key": "SENTRY_PROJECT", "reach": "managed", "secret": false },
{ "key": "PUBLIC_SITE_URL", "reach": "build", "secret": false, "defaultValue": "https://docs.example.com" },
{ "key": "STRIPE_SECRET_KEY", "reach": "runtime", "secret": true }
]
}
},
"workflows": {
"project": {
"prefix": "PUBLISH_"
}
}
},
"settings": {
"lockStepVersioning": false,
"versionStrategy": "semver"
}
}
Troubleshooting
- "Must be run inside the project root directory." — Verify you execute the command where the project root
package.jsonresides. App or package folders inside monorepos are not allowed. - Validation loops keep reappearing — Fix the highlighted email or URL before continuing. To drop the value, enter a single space and press Enter.
- No file was created — Confirm that
nova.config.jsonis writable and that--dry-runwas not passed or Cancel was not chosen.