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 | Preview the entire wizard without writing nova.config.json to disk. |
-r, --replace-file | Overwrite the existing nova.config.json instead of creating a dated copy. |
Flow Overview
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, github, npm, 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.
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 suffix, triggers (selected from the template's available options), an optional depends-on (when using
workflow-run-*triggers), and per-variable settings. Each variable prompt includes a description and example value to guide input. - Things to watch: The suffix must be unique within the same template so the output filenames remain distinct. When using
workflow-run-*triggers, the depends-on field references other workflows by their{template}-{suffix}composite key.
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.
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": "Sample settings for a Nova-powered JavaScript toolkit.",
"long": "Use Nova to keep linting, typing, and release metadata consistent across your JavaScript and TypeScript projects."
},
"keywords": [
"example",
"nova",
"tooling",
"config"
],
"legalName": "Example Author LLC",
"pronouns": "business",
"platforms": [
"nodejs",
"macos",
"linux",
"windows"
],
"startingYear": 2025,
"license": "MIT"
},
"entities": [
{
"name": "Example Author",
"email": "[email protected]",
"url": "https://example.com/author",
"roles": [
"author"
]
},
{
"name": "Example Collaborator",
"email": "[email protected]",
"url": "https://example.com/collaborator",
"roles": [
"contributor",
"supporter"
]
}
],
"emails": {
"bugs": "[email protected]"
},
"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",
"github": "https://github.com/example/example-project",
"npm": "https://www.npmjs.com/package/example-project",
"fundSources": [
"https://github.com/sponsors/example",
"https://opencollective.com/example"
],
"privacyPolicy": "https://example.com/privacy",
"termsOfUse": "https://example.com/terms"
},
"workspaces": {
"./": {
"name": "example-project",
"role": "project",
"policy": "freezable",
"recipes": {
"cleanup": [
true,
{
"removeUnknownKeys": true,
"reorderKeys": true
}
],
"normalize-artifacts": [
true
],
"normalize-bundler": [
true
],
"normalize-dependencies": [
true,
{
"pinDependencyVersions": true,
"pinDevDependencyVersions": true
}
],
"normalize-modules": [
true
],
"normalize-tooling": [
true
],
"sync-environment": [
true,
{
"trackNodeLtsVersions": true
}
],
"sync-identity": [
true
],
"sync-ownership": [
true
]
}
},
"./apps/docs": {
"name": "example-docs",
"role": "docs",
"policy": "freezable",
"recipes": {
"cleanup": [
true,
{
"removeUnknownKeys": true,
"reorderKeys": true
}
],
"normalize-artifacts": [
true
],
"normalize-bundler": [
true
],
"normalize-dependencies": [
true,
{
"pinDependencyVersions": true,
"pinDevDependencyVersions": true
}
],
"normalize-modules": [
true
],
"normalize-tooling": [
true
],
"sync-environment": [
true,
{
"trackNodeLtsVersions": true
}
],
"sync-identity": [
true
],
"sync-ownership": [
true
]
}
},
"./packages/nova": {
"name": "@company/example",
"role": "package",
"policy": "distributable",
"recipes": {
"cleanup": [
true,
{
"removeUnknownKeys": true,
"reorderKeys": true
}
],
"normalize-artifacts": [
true
],
"normalize-bundler": [
true
],
"normalize-dependencies": [
true,
{
"pinDependencyVersions": true,
"pinDevDependencyVersions": true
}
],
"normalize-modules": [
true
],
"normalize-tooling": [
true
],
"sync-environment": [
true,
{
"trackNodeLtsVersions": true
}
],
"sync-identity": [
true,
{
"description": true,
"keywords": true
}
],
"sync-ownership": [
true,
{
"homepage": true,
"bugs": true,
"author": true,
"contributors": true,
"funding": true,
"repository": true
}
]
}
}
},
"workflows": [
{
"template": "lock-inactive-issues",
"suffix": "project",
"triggers": ["schedule-weekly"]
},
{
"template": "publish",
"suffix": "project",
"triggers": ["release"],
"scopes": ["./packages/my-package"],
"targets": [
{
"type": "npm",
"workingDir": "./packages/my-package"
}
],
"settings": {
"NPM_TOKEN": "NPM_TOKEN",
"ROOT_WORKING_DIR": "./"
}
}
]
}
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.