Skip to content

Commit 15df59c

Browse files
committed
More updates to the Nexical CLI to align it to the app-core architecture.
1 parent 6a80922 commit 15df59c

23 files changed

Lines changed: 80 additions & 105 deletions

.github/workflows/deploy.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name: Deploy Astrical CLI
1+
name: Deploy Nexical CLI
22

33
on:
44
push:

README.md

Lines changed: 33 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
# @astrical/cli
1+
# @nexical/cli
22

3-
The official Command Line Interface (CLI) for the Astrical framework.
3+
The official Command Line Interface (CLI) for the Nexical framework.
44

5-
This project serves as the primary entry point for managing Astrical projects, handling tasks such as project initialization, module management, and development workflows. It is designed to be **extensible**, **fast**, and **developer-friendly**, focusing on a clean architecture that allows for easy addition of new commands.
5+
This project serves as the primary entry point for managing Nexical projects, handling tasks such as project initialization, module management, and development workflows. It is designed to be **extensible**, **fast**, and **developer-friendly**, focusing on a clean architecture that allows for easy addition of new commands.
66

77
## Table of Contents
88

@@ -22,8 +22,8 @@ This project serves as the primary entry point for managing Astrical projects, h
2222

2323
## Purpose
2424

25-
The Astrical CLI allows developers to:
26-
1. **Initialize** new Astrical projects with best practices built-in.
25+
The Nexical CLI allows developers to:
26+
1. **Initialize** new Nexical projects with best practices built-in.
2727
2. **Manage** project configuration and dependencies.
2828
3. **Extend** the framework functionality through modular commands.
2929

@@ -36,7 +36,7 @@ This CLI is built with **TypeScript** and follows a **Class-Based Command Patter
3636
### Key Technologies
3737
* **[CAC (Command And Conquer)](https://github.com/cacjs/cac)**: A lightweight, robust framework for building CLIs. It handles argument parsing, help generation, and command registration.
3838
* **[Consola](https://github.com/unjs/consola)**: Elegant console logging with fallback and structured output capabilities.
39-
* **[Lilconfig](https://github.com/antonk52/lilconfig)**: Configuration loading (searching for `astrical.yml`, `astrical.yaml`) akin to `cosmiconfig` but lighter.
39+
* **[Lilconfig](https://github.com/antonk52/lilconfig)**: Configuration loading (searching for `nexical.yml`, `nexical.yaml`) akin to `cosmiconfig` but lighter.
4040
* **Vitest**: A blazing fast unit test framework powered by Vite.
4141

4242
### Core Components
@@ -52,7 +52,7 @@ This CLI is built with **TypeScript** and follows a **Class-Based Command Patter
5252
* Project root detection (`this.projectRoot`).
5353

5454
### Design Goals
55-
* **Zero-Config Defaults**: It should work out of the box but allow rich configuration via `astrical.yml`.
55+
* **Zero-Config Defaults**: It should work out of the box but allow rich configuration via `nexical.yaml`.
5656
* **Extensibility**: Adding a command should be as simple as adding a file.
5757
* **Testability**: Every component is designed to be unit-testable, with dependency injection where appropriate (e.g., `CommandLoader` importer).
5858

@@ -74,37 +74,37 @@ npm run build
7474

7575
```bash
7676
# Run the built CLI
77-
npx astrical <command> [options]
77+
npx nexical <command> [options]
7878

7979
# Example: Initialize a new project
80-
npx astrical init my-new-project
80+
npx nexical init my-new-project
8181

8282
# Get help
83-
npx astrical help
83+
npx nexical help
8484

8585
# Get help for a specific command
86-
npx astrical help init
87-
npx astrical help module add
86+
npx nexical help init
87+
npx nexical help module add
8888
```
8989

9090
### Command Reference
9191

9292
#### `init`
9393

94-
Initializes a new Astrical project by cloning a starter repository, setting up dependencies, and preparing a fresh git history.
94+
Initializes a new Nexical project by cloning a starter repository, setting up dependencies, and preparing a fresh git history.
9595

9696
**Usage:**
9797
```bash
98-
npx astrical init <directory> [options]
98+
npx nexical init <directory> [options]
9999
```
100100

101101
**Arguments:**
102102
- `directory` (Required): The directory to initialize the project in. If the directory does not exist, it will be created. If it does exist, it must be empty.
103103

104104
**Options:**
105-
- `--repo <url>` (Default: `https://github.com/nexical/astrical-starter`): The URL of the starter repository to clone.
105+
- `--repo <url>` (Default: `https://github.com/nexical/app-core`): The URL of the starter repository to clone.
106106
- Supports standard Git URLs (e.g., `https://github.com/user/repo.git`).
107-
- Supports GitHub short syntax `gh@owner/repo` (e.g., `gh@nexical/astrical-starter`).
107+
- Supports GitHub short syntax `gh@owner/repo` (e.g., `gh@nexical/app-core`).
108108

109109
**What it does:**
110110
1. **Clones** the specified starter repository (recursively, including submodules) into the target directory.
@@ -118,7 +118,7 @@ npx astrical init <directory> [options]
118118
- Removes the `origin` remote to prevent accidental pushes to the starter repo.
119119

120120
**Output:**
121-
- A ready-to-use Astrical project in the specified directory, with fresh git history and installed dependencies.
121+
- A ready-to-use Nexical project in the specified directory, with fresh git history and installed dependencies.
122122

123123
---
124124

@@ -128,11 +128,10 @@ Starts the development server in ephemeral mode. It constructs a temporary build
128128

129129
**Usage:**
130130
```bash
131-
npx astrical dev
131+
npx nexical dev
132132
```
133133

134134
**What it does:**
135-
1. **Prepares** the `site` directory by mounting `src/core`, `src/modules`, and content.
136135
2. **Starts** the Astro development server (accessible at `http://localhost:4321` by default).
137136
3. **Watches** for changes in your project and updates the ephemeral build automatically.
138137

@@ -144,12 +143,12 @@ Compiles the project for production. It assembles the final site structure in `s
144143

145144
**Usage:**
146145
```bash
147-
npx astrical build
146+
npx nexical build
148147
```
149148

150149
**What it does:**
151150
1. **Cleans** the `site` directory to ensure a fresh build.
152-
2. **Copies** all necessary source files (`src/core`, `src/modules`, `src/content`, `public`) into `site`.
151+
2. **Copies** all necessary source files (`src/`, `modules`, `src/content`, `public`) into `site`.
153152
3. **Runs** `astro build` to generate the production output in `site/dist`.
154153

155154
**Output:**
@@ -159,15 +158,15 @@ npx astrical build
159158

160159
#### `preview`
161160

162-
Previews the locally built production site. This is useful for verifying the output of `astrical build` before deploying.
161+
Previews the locally built production site. This is useful for verifying the output of `nexical build` before deploying.
163162

164163
**Usage:**
165164
```bash
166-
npx astrical preview
165+
npx nexical preview
167166
```
168167

169168
**Prerequisites:**
170-
- You must run `astrical build` first.
169+
- You must run `nexical build` first.
171170

172171
**What it does:**
173172
- Starts a local web server serving the static files from `site/dist`.
@@ -180,7 +179,7 @@ Removes generated build artifacts and temporary directories to ensure a clean st
180179

181180
**Usage:**
182181
```bash
183-
npx astrical clean
182+
npx nexical clean
184183
```
185184

186185
**What it does:**
@@ -190,11 +189,11 @@ npx astrical clean
190189

191190
#### `run`
192191

193-
Executes a script within the Astrical environment context. This handles path resolution and environment variable setup for you.
192+
Executes a script within the Nexical environment context. This handles path resolution and environment variable setup for you.
194193

195194
**Usage:**
196195
```bash
197-
npx astrical run <script> [args...]
196+
npx nexical run <script> [args...]
198197
```
199198

200199
**Arguments:**
@@ -206,25 +205,25 @@ npx astrical run <script> [args...]
206205
**Examples:**
207206
```bash
208207
# Run a core project script
209-
npx astrical run test
208+
npx nexical run test
210209

211210
# Run a script defined in the 'blog' module's package.json
212-
npx astrical run blog:sync --force
211+
npx nexical run blog:sync --force
213212
```
214213

215214
---
216215

217216
#### `module`
218217

219-
Manages the modular architecture of your Astrical project. Allows you to add, remove, update, and list Git-based modules.
218+
Manages the modular architecture of your Nexical project. Allows you to add, remove, update, and list Git-based modules.
220219

221220
##### `module add`
222221

223222
Adds a new module as a Git submodule.
224223

225224
**Usage:**
226225
```bash
227-
npx astrical module add <url> [name]
226+
npx nexical module add <url> [name]
228227
```
229228

230229
**Arguments:**
@@ -242,7 +241,7 @@ Lists all installed modules in the project.
242241

243242
**Usage:**
244243
```bash
245-
npx astrical module list
244+
npx nexical module list
246245
```
247246

248247
**Output:**
@@ -254,7 +253,7 @@ Updates one or all modules to their latest remote commit.
254253

255254
**Usage:**
256255
```bash
257-
npx astrical module update [name]
256+
npx nexical module update [name]
258257
```
259258

260259
**Arguments:**
@@ -270,7 +269,7 @@ Removes an installed module and cleans up references.
270269

271270
**Usage:**
272271
```bash
273-
npx astrical module remove <name>
272+
npx nexical module remove <name>
274273
```
275274

276275
**Arguments:**

src/commands/module/init.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ export default class ModuleInitCommand extends BaseCommand {
1818
{
1919
name: '--repo <url>',
2020
description: 'Starter repository URL',
21-
default: 'gh@astrical-modules/starter'
21+
default: 'gh@nexical-modules/starter'
2222
}
2323
]
2424
};

src/commands/run.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { linkEnvironment } from '../utils/environment.js';
77

88
export default class RunCommand extends BaseCommand {
99
static usage = 'run <script> [args...]';
10-
static description = 'Run a script inside the Astrical environment.';
10+
static description = 'Run a script inside the Nexical environment.';
1111
static requiresProject = true;
1212

1313
static args: CommandDefinition = {
@@ -67,7 +67,7 @@ export default class RunCommand extends BaseCommand {
6767
const corePkgJsonPath = path.join(siteDir, 'package.json');
6868
const pkg = await fs.readJson(corePkgJsonPath);
6969
if (!pkg.scripts || !pkg.scripts[script]) {
70-
this.error(`Script ${script} does not exist in Astrical core`);
70+
this.error(`Script ${script} does not exist in Nexical core`);
7171
return;
7272
}
7373
finalArgs = ['run', script, '--', ...scriptArgs];

src/utils/discovery.ts

Lines changed: 3 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ import fs from 'node:fs';
66
* Discovers command directories to load into the CLI.
77
*
88
* Scans for:
9-
* 1. Core commands (projectRoot/src/core/commands)
10-
* 2. Module commands (projectRoot/src/modules/ * /commands)
9+
* 1. Core commands (projectRoot/src/commands)
10+
* 2. Module commands (projectRoot/src/modules/ * /src/commands)
1111
*
1212
* @param projectRoot - The root directory of the project
1313
* @returns Array of absolute paths to command directories
@@ -33,15 +33,12 @@ export function discoverCommandDirectories(projectRoot: string): string[] {
3333
// Search in projectRoot
3434
const possibleCorePaths = [
3535
path.join(projectRoot, 'src/commands'),
36-
path.join(projectRoot, 'src/core/src/commands'),
3736
];
3837

3938
possibleCorePaths.forEach(addDir);
4039

4140
// 2. Module commands
42-
// 2. Module commands (src/modules for standalone CLI, modules for platform)
4341
const possibleModuleDirs = [
44-
path.join(projectRoot, 'src/modules'),
4542
path.join(projectRoot, 'modules')
4643
];
4744

@@ -67,8 +64,7 @@ export function discoverCommandDirectories(projectRoot: string): string[] {
6764
}
6865
});
6966

70-
// 3. Package commands (e.g. platform/core/packages/*)
71-
// This assumes we are running in the context of platform/core or similar workspace
67+
// 3. Package commands (e.g. packages/*)
7268
const packagesDir = path.join(projectRoot, 'packages');
7369
if (fs.existsSync(packagesDir)) {
7470
try {
@@ -88,25 +84,5 @@ export function discoverCommandDirectories(projectRoot: string): string[] {
8884
}
8985
}
9086

91-
// 4. Platform Core Packages (e.g. platform/core/packages/*)
92-
const platformPackagesDir = path.join(projectRoot, 'platform/core/packages');
93-
if (fs.existsSync(platformPackagesDir)) {
94-
try {
95-
const packages = fs.readdirSync(platformPackagesDir);
96-
for (const pkg of packages) {
97-
if (pkg.startsWith('.')) continue;
98-
99-
const pkgPath = path.join(platformPackagesDir, pkg);
100-
const pkgCommands = path.join(pkgPath, 'src/commands');
101-
102-
if (fs.existsSync(pkgCommands) && fs.statSync(pkgCommands).isDirectory()) {
103-
addDir(pkgCommands);
104-
}
105-
}
106-
} catch (e: any) {
107-
logger.debug(`Error scanning platform packages directory: ${e.message}`);
108-
}
109-
}
110-
11187
return directories;
11288
}

test/e2e/lifecycle.e2e.test.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ if (args[0] === 'build') {
5757
}
5858
}),
5959
'README.md': '# E2E Starter',
60-
'astrical.yml': 'name: e2e-test\nversion: 0.0.1', // ESSENTIAL for CLI to recognize project
60+
'nexical.yml': 'name: e2e-test\nversion: 0.0.1', // ESSENTIAL for CLI to recognize project
6161
'src/pages/index.astro': '--- ---',
6262
'src/core/index.ts': '// core',
6363
'src/core/package.json': JSON.stringify({
@@ -96,7 +96,7 @@ if (args[0] === 'build') {
9696
};
9797

9898
// --- STEP 1: INIT ---
99-
// Run: astrical init my-project --repo <starter>
99+
// Run: nexical init my-project --repo <starter>
100100
const initResult = await runCLI([
101101
'init',
102102
'my-project',
@@ -111,7 +111,7 @@ if (args[0] === 'build') {
111111
expect(fs.existsSync(path.join(projectDir, 'node_modules', 'astro'))).toBe(true);
112112

113113
// --- STEP 2: MODULE ADD ---
114-
// Run: astrical module add <module>
114+
// Run: nexical module add <module>
115115
const modResult = await runCLI([
116116
'module',
117117
'add',
@@ -126,7 +126,7 @@ if (args[0] === 'build') {
126126
expect(fs.existsSync(path.join(projectDir, 'src/modules/my-test-module'))).toBe(true);
127127

128128
// --- STEP 3: BUILD ---
129-
// Run: astrical build
129+
// Run: nexical build
130130
// Should trigger our mock astro binary
131131
const buildResult = await runCLI(['build'], projectDir, { env });
132132

@@ -139,7 +139,7 @@ if (args[0] === 'build') {
139139
expect(buildResult.stdout).toContain('MOCK_ASTRO_EXECUTED build');
140140

141141
// --- STEP 4: PREVIEW ---
142-
// Run: astrical preview
142+
// Run: nexical preview
143143
// Should trigger mock astro preview
144144
const previewResult = await runCLI(['preview'], projectDir, { env });
145145
// NOTE: Real astro preview blocks. Our mock bin just prints and exits.
@@ -148,7 +148,7 @@ if (args[0] === 'build') {
148148
expect(previewResult.stdout).toContain('MOCK_ASTRO_EXECUTED preview');
149149

150150
// --- STEP 5: CLEAN ---
151-
// Run: astrical clean
151+
// Run: nexical clean
152152
const cleanResult = await runCLI(['clean'], projectDir, { env });
153153

154154
expect(cleanResult.exitCode).toBe(0);

test/integration/commands/build.integration.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ describe('BuildCommand Integration', () => {
5858
});
5959

6060
it('should assemble environment and spawn astro build', async () => {
61-
const cli = new CLI({ commandName: 'astrical' });
61+
const cli = new CLI({ commandName: 'nexical' });
6262
const command = new BuildCommand(cli);
6363
Object.assign(command, { projectRoot: projectDir });
6464

0 commit comments

Comments
 (0)