بنقرة واحدة
nn
@nextnode-solutions/nn — local dev DX CLI. Auto-load when working on nn package or any project that uses nn.
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
القائمة
@nextnode-solutions/nn — local dev DX CLI. Auto-load when working on nn package or any project that uses nn.
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
استنادا إلى تصنيف SOC المهني
| name | nn |
| description | @nextnode-solutions/nn — local dev DX CLI. Auto-load when working on nn package or any project that uses nn. |
| version | 1.2.1 |
| user-invocable | false |
| autoload-dirs | ["/Users/walid/Development/nextnode","/Users/walid/Development/saas"] |
Published as @nextnode-solutions/nn (v1.2.1). Built with citty, uses @nextnode/cli as workspace dependency for shared types and config.
Package: packages/nn/ in the infrastructure monorepo.
| Command | Purpose | Key Args |
|---|---|---|
nn up | Start local dev (Docker services + app dev server) | --containerized, --reset-ports |
nn down | Stop local dev (kills dev server + Docker services) | --clean (removes volumes) |
nn env show | Display resolved env vars | <env> (default: local), --reveal, --diff <env> |
nn env check | Validate env vars against requirements | <env> (default: local) |
nn env init | Create .env.local, .env.dev, .env.prod templates | — |
nn env push | Push env vars to GitHub environment secrets | <env> (required: dev, prod), --file |
nn up Flownextnode.toml (detectServices()).nn/ports.json, reusable across restarts).nn/ directory + .gitignore entries.env.local → userVars (empty if file missing)[secrets] vars → write to .env.local (add-only, 0o600 perms).nn/.env)buildLocalEnvVars()) — computed always wins over user{ ...userVars, ...computedVars } → mergedVars (warns on overrides)[auto]/[secret]/[user] labelsdocker-compose.local.yml in .nn/ (if services fresh)detectDevCommand())process.env (lowest)
<- .env.local vars (user-provided + persisted [secrets])
<- computed service vars from buildLocalEnvVars() + resolveDockerEnv() (highest)
[auto]: Service-derived vars computed by nn up (SUPABASE_URL, DATABASE_URL, REDIS_URL, etc.)[secret]: Config-declared secrets generated by nn up via [secrets] in nextnode.toml[user]: User-provided vars from .env.localKeys are generated/reused in resolveDockerEnv(), written to .nn/.env, then passed to buildLocalEnvVars() so both Docker and app use the same values. Single owner — no split brain.
nn env Subcommandsnn env init.env.local, .env.dev, .env.prod templates (skips existing files).env.local: excludes auto-generated vars (only user-provided + placeholder for secrets).env.dev / .env.prod: includes ALL vars, generates unique random [secrets] values per env.gitignore includes .env.* patternsnn env checkSERVICE_REQUIRED_VARS, [secrets] configgetAutoGeneratedVars()) from required list<...>, empty, whitespace-only) as MISSINGnn env push.env.{env} to GitHub environment secretslocal (error exit)gh secret set --env <ghEnvName> per selected varnn env show--reveal: show actual values--diff <env>: compare two environments (+ only in first, - only in second, ~ different values)packages/nn/src/lib/)| Library | Key Exports |
|---|---|
| config | requireConfig() — loads nextnode.toml via @nextnode/cli, bundles nextnode.default.toml |
| services | detectServices(config): DetectedServices, getAutoGeneratedVars(config): ReadonlySet<string> — returns max set of auto-generated var names for configured services |
| ports | resolvePortMap(services, appPort, nnDir, opts?), isPortAvailable(port), findAvailablePort(start, max), DEFAULT_PORTS, PortMap |
| compose | generateLocalCompose(config, services, ports), writeLocalComposeFiles(projectDir, config, composeContent) — writes compose + Supabase support files (kong.yml, roles.sql, init-db.sh, kong-entrypoint.sh) to .nn/ |
| docker | checkDockerAvailable(), startDockerServices(composePath, envFilePath?), stopDockerServices(composePath, opts?), areServicesRunning(composePath), getServiceStatuses(composePath) |
| env | readEnvFile(env, cwd, filePath?), parseEnvFile(content), writeEnvLocal(projectDir, vars): EnvVars, buildLocalEnvVars(services, ports, supabaseKeys?, pgPassword?), isSensitive(name), maskValue(value), formatValuePreview(value, name, reveal), isPlaceholderValue(value), resolveEnvFile(env, filePath?), mapGitHubEnvName(env), SERVICE_REQUIRED_VARS, EnvVars (re-export) |
| oauth | computeLocalOAuthEnvVars(oauthConfig, apiPort, localVars: Readonly<EnvVars>) — pure function, receives pre-parsed vars instead of reading .env.local. Falls back to process.env for credentials. Warns and skips providers with missing credentials. |
| secret-gen | generateSecret(decl: SecretDeclaration): string — hex via randomBytes, base64url via randomBytes, uuid via randomUUID. Exhaustive default: never on discriminant. |
| dev-server | detectDevCommand(projectDir) — checks package.json scripts.dev, then framework-specific defaults (astro, next, vite) |
| logs | createPrefixWriter(serviceName, colorIndex), streamDockerLogs(composePath), pipeWithPrefix(proc, serviceName, colorIndex) |
| process | gracefulKill(proc, timeoutMs), waitForHealthy(checkFn, label, maxMs), writePidFile(nnDir, pid), readPidFile(nnDir), removePidFile(nnDir), killProcess(pid), isProcessRunning(pid) |
type ServiceName = 'supabase' | 'redis'
interface DetectedServices {
names: ServiceName[]
hasSupabase: boolean
hasRedis: boolean
}
interface PortMap {
supabaseApi?: number // default 54321
supabaseStudio?: number // default 54323
supabaseDb?: number // default 54322
supabaseAuth?: number // default 9999
redis?: number // default 6379
app: number // default 4321
}
SecretDeclaration, GenerateAlgorithm, EnvVars, and ProjectConfig are defined in @nextnode/cli types — see nextnode-infra skill.
| File/Dir | Purpose | Written by |
|---|---|---|
.env.local | User secrets + generated [secrets] | User + nn up (secrets only, add-only) |
.nn/.env | Infra vars for Docker Compose | nn up (every run) |
.nn/ports.json | Persisted port assignments | nn up |
.nn/docker-compose.local.yml | Local Docker Compose | nn up |
.nn/supabase/ | Kong config, init scripts, roles.sql | nn up |
.nn/app.pid | Dev server PID | nn up |
.env.dev | Deploy vars for dev | User + nn env init |
.env.prod | Deploy vars for prod | User + nn env init |
All secret-containing files (.env.local, .nn/.env) enforced 0o600 via chmodSync after every write.
[secrets] Config (nextnode.toml)[secrets]
TOKEN_ENCRYPTION_KEY = { generate = "hex", bytes = 32 }
SESSION_SECRET = { generate = "base64url", bytes = 32 }
INTERNAL_API_KEY = { generate = "uuid" }
hex, base64url (both require bytes >= 16), uuidnn up generates missing secrets → writes to .env.local (add-only, never overwrites).env.localpackages/cli/src/lib/config.ts (validateConfig())packages/nn/src/lib/secret-gen.ts.env.local templates and local checks)getAutoGeneratedVars(config) returns the maximum possible set:
| Service | Vars |
|---|---|
| Supabase | SUPABASE_URL, DATABASE_URL, SUPABASE_ANON_KEY, SUPABASE_SERVICE_ROLE_KEY, JWT_SECRET, POSTGRES_PASSWORD |
| Redis | REDIS_URL |
SERVICE_REQUIRED_VARS| Service | Required in deploy envs |
|---|---|
| supabase | JWT_SECRET, SUPABASE_ANON_KEY, SUPABASE_SERVICE_ROLE_KEY, POSTGRES_PASSWORD |
| redis | REDIS_URL |
| r2 | R2_BUCKET_NAME, R2_ACCOUNT_ID, R2_ENDPOINT_URL |
.nn/ports.json reused across restarts. --reset-ports to reassign.localVars (pre-parsed .env.local) with process.env fallback. GitHub OAuth uses GH_* prefix (not GITHUB_*).isSensitive() checks suffixes (_KEY, _SECRET, _PASSWORD, _TOKEN, _CREDENTIALS, _API_KEY), prefixes (JWT_), exact matches (DATABASE_URL, REDIS_URL).isPlaceholderValue() returns true for <...>, empty, whitespace-only values..nn/ cleanup: writeLocalComposeFiles() cleans up stale directory artifacts (Docker creates bind-mount paths as directories when source files don't exist).Deep interview for a single feature or module brief that produces a final spec or implementation plan.
@nextnode-solutions/logger standards. Reference this skill when a project uses @nextnode-solutions/logger or when logger integration is being added.
Manage n8n workflows on the NextNode automation instance with the local n8n-cli tool.
NextNode brand guidelines — color palette, typography, logo system, and per-project branding rules. Use when doing UI/frontend work on a NextNode project.
NextNode ecosystem hub. Auto-load when working on any NextNode or SaaS project — covers nextnode.toml config, CI workflows, docker-compose rules, and cross-references to package skills.
Audit a NextNode/SaaS project against all NextNode standards — produces a compliance report with pass/fail/missing status for every required item.