argument('key'))); if (! preg_match('/^[a-z0-9][a-z0-9_-]*$/', $key)) { $this->error('Theme keys may contain lowercase letters, numbers, dashes, and underscores only.'); return self::FAILURE; } $path = rtrim((string) config('stylist.themes_path'), '/\\').DIRECTORY_SEPARATOR.$key; if ($this->files->exists($path)) { $this->error("Theme [{$key}] already exists."); return self::FAILURE; } $parent = trim((string) $this->option('parent')); $name = trim((string) ($this->option('name') ?: str($key)->headline())); $this->files->ensureDirectoryExists($path.'/views'); $manifest = [ 'manifest_version' => 1, 'name' => $name, 'slug' => $key, 'version' => '1.0.0', 'description' => "Child theme for {$name}.", 'extends' => $parent !== '' ? $parent : null, 'entry_view' => 'home', 'views' => true, 'variables' => [], 'settings' => [], ]; if ($manifest['extends'] === null) { unset($manifest['extends']); } $this->files->put($path.'/theme.json', json_encode($manifest, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES).PHP_EOL); $this->files->put($path.'/views/.gitkeep', ''); $this->info("Theme [{$key}] created at {$path}."); $this->line('Shared views will resolve through its parent; only add genuine overrides.'); return self::SUCCESS; } }