@nexical/cli 0.1.6 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (236) hide show
  1. package/.github/workflows/deploy.yml +3 -3
  2. package/README.md +317 -104
  3. package/dist/chunk-JYASTIIW.js +42 -0
  4. package/dist/chunk-JYASTIIW.js.map +1 -0
  5. package/dist/chunk-LZ3YQWAR.js +2204 -0
  6. package/dist/chunk-LZ3YQWAR.js.map +1 -0
  7. package/dist/chunk-OKXOCNXP.js +105 -0
  8. package/dist/chunk-OKXOCNXP.js.map +1 -0
  9. package/dist/chunk-OYFWMYPG.js +52 -0
  10. package/dist/chunk-OYFWMYPG.js.map +1 -0
  11. package/dist/chunk-WKERTCM6.js +74 -0
  12. package/dist/chunk-WKERTCM6.js.map +1 -0
  13. package/dist/index.js +33 -6
  14. package/dist/index.js.map +1 -1
  15. package/dist/src/commands/init.d.ts +11 -0
  16. package/dist/src/commands/init.js +88 -0
  17. package/dist/src/commands/init.js.map +1 -0
  18. package/dist/src/commands/module/add.d.ts +14 -0
  19. package/dist/src/commands/module/add.js +136 -0
  20. package/dist/src/commands/module/add.js.map +1 -0
  21. package/dist/src/commands/module/list.d.ts +10 -0
  22. package/dist/src/commands/module/list.js +73 -0
  23. package/dist/src/commands/module/list.js.map +1 -0
  24. package/dist/src/commands/module/remove.d.ts +12 -0
  25. package/dist/src/commands/module/remove.js +71 -0
  26. package/dist/src/commands/module/remove.js.map +1 -0
  27. package/dist/src/commands/module/update.d.ts +11 -0
  28. package/dist/src/commands/module/update.js +52 -0
  29. package/dist/src/commands/module/update.js.map +1 -0
  30. package/dist/src/commands/run.d.ts +11 -0
  31. package/dist/src/commands/run.js +93 -0
  32. package/dist/src/commands/run.js.map +1 -0
  33. package/dist/src/utils/discovery.d.ts +13 -0
  34. package/dist/src/utils/discovery.js +9 -0
  35. package/dist/src/utils/git.d.ts +16 -0
  36. package/dist/src/utils/git.js +29 -0
  37. package/dist/src/utils/git.js.map +1 -0
  38. package/dist/src/utils/url-resolver.d.ts +15 -0
  39. package/dist/src/utils/url-resolver.js +9 -0
  40. package/dist/src/utils/url-resolver.js.map +1 -0
  41. package/index.ts +29 -5
  42. package/package.json +32 -30
  43. package/src/commands/init.ts +85 -0
  44. package/src/commands/module/add.ts +169 -0
  45. package/src/commands/module/list.ts +69 -0
  46. package/src/commands/module/remove.ts +74 -0
  47. package/src/commands/module/update.ts +50 -0
  48. package/src/commands/run.ts +98 -0
  49. package/src/utils/discovery.ts +134 -0
  50. package/src/utils/git.ts +65 -0
  51. package/src/utils/url-resolver.ts +57 -0
  52. package/test/e2e/lifecycle.e2e.test.ts +152 -0
  53. package/test/integration/commands/init.integration.test.ts +82 -0
  54. package/test/integration/commands/module.integration.test.ts +144 -0
  55. package/test/integration/commands/run.integration.test.ts +90 -0
  56. package/test/integration/utils/command-loading.integration.test.ts +80 -0
  57. package/test/unit/commands/init.test.ts +153 -0
  58. package/test/unit/commands/module/add.test.ts +262 -0
  59. package/test/unit/commands/module/list.test.ts +115 -0
  60. package/test/unit/commands/module/remove.test.ts +89 -0
  61. package/test/unit/commands/module/update.test.ts +91 -0
  62. package/test/unit/commands/run.test.ts +252 -0
  63. package/test/unit/utils/command-discovery.test.ts +176 -0
  64. package/test/unit/utils/git.test.ts +152 -0
  65. package/test/unit/utils/integration-helpers.test.ts +72 -0
  66. package/test/unit/utils/url-resolver.test.ts +39 -0
  67. package/test/utils/integration-helpers.ts +66 -0
  68. package/vitest.e2e.config.ts +0 -1
  69. package/dist/chunk-JDRAVUKK.js +0 -48
  70. package/dist/chunk-JDRAVUKK.js.map +0 -1
  71. package/dist/src/commands/admin/create-user.d.ts +0 -15
  72. package/dist/src/commands/admin/create-user.js +0 -49
  73. package/dist/src/commands/admin/create-user.js.map +0 -1
  74. package/dist/src/commands/branch/create.d.ts +0 -19
  75. package/dist/src/commands/branch/create.js +0 -59
  76. package/dist/src/commands/branch/create.js.map +0 -1
  77. package/dist/src/commands/branch/delete.d.ts +0 -15
  78. package/dist/src/commands/branch/delete.js +0 -50
  79. package/dist/src/commands/branch/delete.js.map +0 -1
  80. package/dist/src/commands/branch/get.d.ts +0 -15
  81. package/dist/src/commands/branch/get.js +0 -53
  82. package/dist/src/commands/branch/get.js.map +0 -1
  83. package/dist/src/commands/branch/list.d.ts +0 -15
  84. package/dist/src/commands/branch/list.js +0 -51
  85. package/dist/src/commands/branch/list.js.map +0 -1
  86. package/dist/src/commands/job/get.d.ts +0 -15
  87. package/dist/src/commands/job/get.js +0 -62
  88. package/dist/src/commands/job/get.js.map +0 -1
  89. package/dist/src/commands/job/list.d.ts +0 -15
  90. package/dist/src/commands/job/list.js +0 -57
  91. package/dist/src/commands/job/list.js.map +0 -1
  92. package/dist/src/commands/job/logs.d.ts +0 -15
  93. package/dist/src/commands/job/logs.js +0 -67
  94. package/dist/src/commands/job/logs.js.map +0 -1
  95. package/dist/src/commands/job/trigger.d.ts +0 -19
  96. package/dist/src/commands/job/trigger.js +0 -74
  97. package/dist/src/commands/job/trigger.js.map +0 -1
  98. package/dist/src/commands/login.d.ts +0 -8
  99. package/dist/src/commands/login.js +0 -31
  100. package/dist/src/commands/login.js.map +0 -1
  101. package/dist/src/commands/project/create.d.ts +0 -24
  102. package/dist/src/commands/project/create.js +0 -63
  103. package/dist/src/commands/project/create.js.map +0 -1
  104. package/dist/src/commands/project/delete.d.ts +0 -20
  105. package/dist/src/commands/project/delete.js +0 -58
  106. package/dist/src/commands/project/delete.js.map +0 -1
  107. package/dist/src/commands/project/get.d.ts +0 -15
  108. package/dist/src/commands/project/get.js +0 -49
  109. package/dist/src/commands/project/get.js.map +0 -1
  110. package/dist/src/commands/project/list.d.ts +0 -15
  111. package/dist/src/commands/project/list.js +0 -45
  112. package/dist/src/commands/project/list.js.map +0 -1
  113. package/dist/src/commands/project/update.d.ts +0 -19
  114. package/dist/src/commands/project/update.js +0 -66
  115. package/dist/src/commands/project/update.js.map +0 -1
  116. package/dist/src/commands/team/create.d.ts +0 -19
  117. package/dist/src/commands/team/create.js +0 -45
  118. package/dist/src/commands/team/create.js.map +0 -1
  119. package/dist/src/commands/team/delete.d.ts +0 -20
  120. package/dist/src/commands/team/delete.js +0 -52
  121. package/dist/src/commands/team/delete.js.map +0 -1
  122. package/dist/src/commands/team/get.d.ts +0 -15
  123. package/dist/src/commands/team/get.js +0 -42
  124. package/dist/src/commands/team/get.js.map +0 -1
  125. package/dist/src/commands/team/list.d.ts +0 -8
  126. package/dist/src/commands/team/list.js +0 -30
  127. package/dist/src/commands/team/list.js.map +0 -1
  128. package/dist/src/commands/team/member/invite.d.ts +0 -20
  129. package/dist/src/commands/team/member/invite.js +0 -54
  130. package/dist/src/commands/team/member/invite.js.map +0 -1
  131. package/dist/src/commands/team/member/remove.d.ts +0 -15
  132. package/dist/src/commands/team/member/remove.js +0 -43
  133. package/dist/src/commands/team/member/remove.js.map +0 -1
  134. package/dist/src/commands/team/update.d.ts +0 -19
  135. package/dist/src/commands/team/update.js +0 -55
  136. package/dist/src/commands/team/update.js.map +0 -1
  137. package/dist/src/commands/token/generate.d.ts +0 -19
  138. package/dist/src/commands/token/generate.js +0 -48
  139. package/dist/src/commands/token/generate.js.map +0 -1
  140. package/dist/src/commands/token/list.d.ts +0 -8
  141. package/dist/src/commands/token/list.js +0 -31
  142. package/dist/src/commands/token/list.js.map +0 -1
  143. package/dist/src/commands/token/revoke.d.ts +0 -15
  144. package/dist/src/commands/token/revoke.js +0 -38
  145. package/dist/src/commands/token/revoke.js.map +0 -1
  146. package/dist/src/commands/whoami.d.ts +0 -8
  147. package/dist/src/commands/whoami.js +0 -26
  148. package/dist/src/commands/whoami.js.map +0 -1
  149. package/dist/src/utils/nexical-client.d.ts +0 -10
  150. package/dist/src/utils/nexical-client.js +0 -12
  151. package/src/commands/admin/create-user.ts +0 -46
  152. package/src/commands/branch/create.ts +0 -57
  153. package/src/commands/branch/delete.ts +0 -47
  154. package/src/commands/branch/get.ts +0 -50
  155. package/src/commands/branch/list.ts +0 -50
  156. package/src/commands/job/get.ts +0 -59
  157. package/src/commands/job/list.ts +0 -56
  158. package/src/commands/job/logs.ts +0 -67
  159. package/src/commands/job/trigger.ts +0 -73
  160. package/src/commands/login.ts +0 -31
  161. package/src/commands/project/create.ts +0 -61
  162. package/src/commands/project/delete.ts +0 -56
  163. package/src/commands/project/get.ts +0 -46
  164. package/src/commands/project/list.ts +0 -44
  165. package/src/commands/project/update.ts +0 -63
  166. package/src/commands/team/create.ts +0 -43
  167. package/src/commands/team/delete.ts +0 -50
  168. package/src/commands/team/get.ts +0 -39
  169. package/src/commands/team/list.ts +0 -26
  170. package/src/commands/team/member/invite.ts +0 -56
  171. package/src/commands/team/member/remove.ts +0 -40
  172. package/src/commands/team/update.ts +0 -53
  173. package/src/commands/token/generate.ts +0 -45
  174. package/src/commands/token/list.ts +0 -27
  175. package/src/commands/token/revoke.ts +0 -35
  176. package/src/commands/whoami.ts +0 -21
  177. package/src/utils/nexical-client.ts +0 -47
  178. package/test/e2e/auth.e2e.test.ts +0 -46
  179. package/test/e2e/job-workflow.e2e.test.ts +0 -33
  180. package/test/e2e/project-lifecycle.e2e.test.ts +0 -48
  181. package/test/e2e/setup.ts +0 -237
  182. package/test/e2e/utils.ts +0 -33
  183. package/test/integration/commands/admin/create-user.test.ts +0 -51
  184. package/test/integration/commands/branch/create.test.ts +0 -51
  185. package/test/integration/commands/branch/delete.test.ts +0 -43
  186. package/test/integration/commands/branch/get.test.ts +0 -49
  187. package/test/integration/commands/branch/list.test.ts +0 -47
  188. package/test/integration/commands/job/get.test.ts +0 -54
  189. package/test/integration/commands/job/list.test.ts +0 -47
  190. package/test/integration/commands/job/logs.test.ts +0 -47
  191. package/test/integration/commands/job/trigger.test.ts +0 -57
  192. package/test/integration/commands/login.test.ts +0 -62
  193. package/test/integration/commands/project/create.test.ts +0 -53
  194. package/test/integration/commands/project/delete.test.ts +0 -43
  195. package/test/integration/commands/project/get.test.ts +0 -51
  196. package/test/integration/commands/project/list.test.ts +0 -47
  197. package/test/integration/commands/project/update.test.ts +0 -53
  198. package/test/integration/commands/team/create.test.ts +0 -53
  199. package/test/integration/commands/team/delete.test.ts +0 -43
  200. package/test/integration/commands/team/get.test.ts +0 -50
  201. package/test/integration/commands/team/list.test.ts +0 -47
  202. package/test/integration/commands/team/member/invite.test.ts +0 -46
  203. package/test/integration/commands/team/member/remove.test.ts +0 -43
  204. package/test/integration/commands/team/update.test.ts +0 -50
  205. package/test/integration/commands/token/generate.test.ts +0 -51
  206. package/test/integration/commands/token/list.test.ts +0 -47
  207. package/test/integration/commands/token/revoke.test.ts +0 -43
  208. package/test/integration/commands/whoami.test.ts +0 -49
  209. package/test/unit/commands/admin/create-user.test.ts +0 -51
  210. package/test/unit/commands/branch/create.test.ts +0 -57
  211. package/test/unit/commands/branch/delete.test.ts +0 -49
  212. package/test/unit/commands/branch/get.test.ts +0 -67
  213. package/test/unit/commands/branch/list.test.ts +0 -62
  214. package/test/unit/commands/job/get.test.ts +0 -76
  215. package/test/unit/commands/job/list.test.ts +0 -62
  216. package/test/unit/commands/job/logs.test.ts +0 -60
  217. package/test/unit/commands/job/trigger.test.ts +0 -75
  218. package/test/unit/commands/login.test.ts +0 -64
  219. package/test/unit/commands/project/create.test.ts +0 -64
  220. package/test/unit/commands/project/delete.test.ts +0 -72
  221. package/test/unit/commands/project/get.test.ts +0 -73
  222. package/test/unit/commands/project/list.test.ts +0 -62
  223. package/test/unit/commands/project/update.test.ts +0 -58
  224. package/test/unit/commands/team/create.test.ts +0 -68
  225. package/test/unit/commands/team/delete.test.ts +0 -71
  226. package/test/unit/commands/team/get.test.ts +0 -70
  227. package/test/unit/commands/team/list.test.ts +0 -56
  228. package/test/unit/commands/team/member/invite.test.ts +0 -52
  229. package/test/unit/commands/team/member/remove.test.ts +0 -49
  230. package/test/unit/commands/team/update.test.ts +0 -63
  231. package/test/unit/commands/token/generate.test.ts +0 -65
  232. package/test/unit/commands/token/list.test.ts +0 -58
  233. package/test/unit/commands/token/revoke.test.ts +0 -49
  234. package/test/unit/commands/whoami.test.ts +0 -49
  235. package/test/unit/utils/nexical-client.test.ts +0 -113
  236. /package/dist/src/utils/{nexical-client.js.map → discovery.js.map} +0 -0
@@ -17,10 +17,10 @@ jobs:
17
17
  uses: actions/setup-node@v4
18
18
  with:
19
19
  node-version: 22
20
- registry-url: "https://registry.npmjs.org"
20
+ registry-url: 'https://registry.npmjs.org'
21
21
 
22
22
  - name: Install Dependencies
23
- run: npm ci
23
+ run: npm install
24
24
 
25
25
  - name: Build
26
26
  run: npm run build
@@ -31,4 +31,4 @@ jobs:
31
31
  - name: Publish to NPM
32
32
  run: npm publish --access public
33
33
  env:
34
- NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
34
+ NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
package/README.md CHANGED
@@ -1,183 +1,396 @@
1
- # Nexical CLI
1
+ # @nexical/cli
2
2
 
3
- The **Nexical CLI** is the official command-line interface for the Nexical Orchestrator. It allows developers, platform engineers, and administrators to interact with the Nexical API directly from their terminal.
3
+ The official Command Line Interface (CLI) for the Nexical framework.
4
4
 
5
- Whether you are managing teams, configuring projects, triggering jobs, or handling authentication tokens, the CLI provides a robust and scriptable interface for all your orchestration needs.
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.
6
+
7
+ ## Table of Contents
8
+
9
+ - [Purpose](#purpose)
10
+ - [Architecture & Design](#architecture--design)
11
+ - [Getting Started](#getting-started)
12
+ - [Project Structure](#project-structure)
13
+ - [Development Workflow](#development-workflow)
14
+ - [Prerequisites](#prerequisites)
15
+ - [Setup](#setup)
16
+ - [Running Tests](#running-tests)
17
+ - [Adding New Commands](#adding-new-commands)
18
+ - [Contributing](#contributing)
19
+ - [License](#license)
6
20
 
7
21
  ---
8
22
 
9
- ## 🚀 Getting Started
23
+ ## Purpose
10
24
 
11
- ### Prerequisites
25
+ The Nexical CLI allows developers to:
26
+ 1. **Initialize** new Nexical projects with best practices built-in.
27
+ 2. **Manage** project configuration and dependencies.
28
+ 3. **Extend** the framework functionality through modular commands.
29
+
30
+ It acts as a unification layer, bringing together various tools and configurations into a cohesive developer experience.
31
+
32
+ ## Architecture & Design
12
33
 
13
- - **Node.js**: v22 or higher
14
- - **NPM**: v10 or higher
34
+ This CLI is built with **TypeScript** and follows a **Class-Based Command Pattern** to ensure type safety and maintainability.
35
+
36
+ ### Key Technologies
37
+ * **[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.
38
+ * **[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 `nexical.yml`, `nexical.yaml`) akin to `cosmiconfig` but lighter.
40
+ * **Vitest**: A blazing fast unit test framework powered by Vite.
41
+
42
+ ### Core Components
43
+ 1. **`CLI` Class** (`src/core/CLI.ts`): The orchestrator. It initializes the CAC instance, discovers commands using the `CommandLoader`, registers them, and handles the execution lifecycle.
44
+ 2. **`CommandLoader`** (`src/core/CommandLoader.ts`): Responsible for dynamically discovering and importing command files from the filesystem. It supports:
45
+ * Recursive directory scanning.
46
+ * Nested commands (e.g., `module/add.ts` -> `module add`).
47
+ * Index files as parent commands (e.g., `module/index.ts` -> `module`).
48
+ 3. **`BaseCommand`** (`src/core/BaseCommand.ts`): The abstract base class that all commands MUST extend. It provides:
49
+ * Standardized `init()` and `run()` lifecycle methods.
50
+ * Built-in access to global options (like `--root-dir`).
51
+ * Helper methods for logging (`this.log`, `this.warn`, `this.error`).
52
+ * Project root detection (`this.projectRoot`).
53
+
54
+ ### Design Goals
55
+ * **Zero-Config Defaults**: It should work out of the box but allow rich configuration via `nexical.yaml`.
56
+ * **Extensibility**: Adding a command should be as simple as adding a file.
57
+ * **Testability**: Every component is designed to be unit-testable, with dependency injection where appropriate (e.g., `CommandLoader` importer).
58
+
59
+ ---
60
+
61
+ ## Getting Started
15
62
 
16
63
  ### Installation
17
64
 
18
- Install the package from NPM package repository:
65
+ While currently in development, you can run the CLI from the repository source or link it.
19
66
 
20
67
  ```bash
21
- npm install -g @nexical/cli
68
+ # From within the package directory
69
+ npm install
70
+ npm run build
22
71
  ```
23
72
 
24
- ### Local Development
25
-
26
- To run the CLI locally during development, you can use `npm start`. To pass arguments to the CLI, use the `--` separator:
73
+ ### Usage
27
74
 
28
75
  ```bash
29
- # Example: Running the 'whoami' command
30
- npm start -- whoami
76
+ # Run the built CLI
77
+ npx nexical <command> [options]
78
+
79
+ # Example: Initialize a new project
80
+ npx nexical init my-new-project
31
81
 
32
- # Example: Logging in
33
- npm start -- login
82
+ # Get help
83
+ npx nexical help
84
+
85
+ # Get help for a specific command
86
+ npx nexical help init
87
+ npx nexical help module add
34
88
  ```
35
89
 
36
- Alternatively, you can link the binary globally to use the `nexical` command directly:
90
+ ### Command Reference
91
+
92
+ #### `init`
37
93
 
94
+ Initializes a new Nexical project by cloning a starter repository, setting up dependencies, and preparing a fresh git history.
95
+
96
+ **Usage:**
38
97
  ```bash
39
- npm link
40
- nexical --help
98
+ npx nexical init <directory> [options]
41
99
  ```
42
100
 
101
+ **Arguments:**
102
+ - `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.
103
+
104
+ **Options:**
105
+ - `--repo <url>` (Default: `https://github.com/nexical/app-core`): The URL of the starter repository to clone.
106
+ - Supports standard Git URLs (e.g., `https://github.com/user/repo.git`).
107
+ - Supports GitHub short syntax `gh@owner/repo` (e.g., `gh@nexical/app-core`).
108
+
109
+ **What it does:**
110
+ 1. **Clones** the specified starter repository (recursively, including submodules) into the target directory.
111
+ 2. **Updates** all submodules to their latest `main` branch.
112
+ 3. **Installs** dependencies using `npm install`.
113
+ 4. **Resets** Git history:
114
+ - Creates an orphan branch (`new-main`).
115
+ - Commits all files as an "Initial commit".
116
+ - Deletes the old history (removes `main`/`master`).
117
+ - Renames the branch to `main`.
118
+ - Removes the `origin` remote to prevent accidental pushes to the starter repo.
119
+
120
+ **Output:**
121
+ - A ready-to-use Nexical project in the specified directory, with fresh git history and installed dependencies.
122
+
43
123
  ---
44
124
 
45
- ## 🔑 Authentication
125
+ #### `dev`
126
+
127
+ Starts the development server in ephemeral mode. It constructs a temporary build environment in `site` and runs the Astro dev server with Hot Module Replacement (HMR).
128
+
129
+ **Usage:**
130
+ ```bash
131
+ npx nexical dev
132
+ ```
133
+
134
+ **What it does:**
135
+ 2. **Starts** the Astro development server (accessible at `http://localhost:4321` by default).
136
+ 3. **Watches** for changes in your project and updates the ephemeral build automatically.
137
+
138
+ ---
46
139
 
47
- The CLI supports a secure **Device Flow** for authentication, making it easy to log in from your terminal without handling sensitive passwords directly.
140
+ #### `build`
48
141
 
49
- ### 1. Log In
50
- Start the authentication process. This will provide a verification URL and a code.
142
+ Compiles the project for production. It assembles the final site structure in `site` and generates static assets.
51
143
 
144
+ **Usage:**
52
145
  ```bash
53
- nexical login
146
+ npx nexical build
54
147
  ```
55
- *Follow the on-screen instructions to authorize the device via your browser.*
56
148
 
57
- ### 2. Verify Session
58
- Check your current logged-in status and user details.
149
+ **What it does:**
150
+ 1. **Cleans** the `site` directory to ensure a fresh build.
151
+ 2. **Copies** all necessary source files (`src/`, `modules`, `src/content`, `public`) into `site`.
152
+ 3. **Runs** `astro build` to generate the production output in `site/dist`.
59
153
 
154
+ **Output:**
155
+ - A production-ready static site in `site/dist`.
156
+
157
+ ---
158
+
159
+ #### `preview`
160
+
161
+ Previews the locally built production site. This is useful for verifying the output of `nexical build` before deploying.
162
+
163
+ **Usage:**
60
164
  ```bash
61
- nexical whoami
165
+ npx nexical preview
62
166
  ```
63
167
 
168
+ **Prerequisites:**
169
+ - You must run `nexical build` first.
170
+
171
+ **What it does:**
172
+ - Starts a local web server serving the static files from `site/dist`.
173
+
64
174
  ---
65
175
 
66
- ## 🛠️ Usage & Commands
176
+ #### `clean`
67
177
 
68
- The CLI is structured into resource-based commands. You can always run `nexical <command> --help` to see available subcommands and options.
178
+ Removes generated build artifacts and temporary directories to ensure a clean state.
69
179
 
70
- ### 👥 Teams (`team`)
180
+ **Usage:**
181
+ ```bash
182
+ npx nexical clean
183
+ ```
71
184
 
72
- Manage user teams and memberships.
185
+ **What it does:**
186
+ - Deletes `site`, `dist`, and `node_modules/.vite`.
73
187
 
74
- | Command | Usage | Description |
75
- | :--- | :--- | :--- |
76
- | `list` | `nexical team list` | List all teams you belong to or own. |
77
- | `create` | `nexical team create <name> [--slug <slug>]` | Create a new team. |
78
- | `get` | `nexical team get <teamId>` | View details of a specific team. |
79
- | `update` | `nexical team update <teamId> [--name <n>] [--slug <s>]` | Update team settings. |
80
- | `invite` | `nexical team invite <teamId> <email> [--role <role>]` | Invite a user to a team. |
81
- | `delete` | `nexical team delete <teamId> [--confirm]` | Delete a team permanently. |
188
+ ---
82
189
 
83
- ### 📂 Projects (`project`)
190
+ #### `run`
84
191
 
85
- Manage projects within your teams.
192
+ Executes a script within the Nexical environment context. This handles path resolution and environment variable setup for you.
86
193
 
87
- | Command | Usage | Description |
88
- | :--- | :--- | :--- |
89
- | `list` | `nexical project list <teamId>` | List all projects in a team. |
90
- | `create` | `nexical project create <teamId> <name> [--repo <url>]` | Create a new project. |
91
- | `get` | `nexical project get <teamId> <projectId>` | Get project details. |
92
- | `update` | `nexical project update <teamId> <projectId> ...` | Update project configuration. |
93
- | `delete` | `nexical project delete <teamId> <projectId>` | Delete a project. |
194
+ **Usage:**
195
+ ```bash
196
+ npx nexical run <script> [args...]
197
+ ```
94
198
 
95
- ### 🌿 Branches (`branch`)
199
+ **Arguments:**
200
+ - `script` (Required): The name of the script to run.
201
+ - Can be a standard `package.json` script (e.g., `test`).
202
+ - Can be a module-specific script using `module:script` syntax (e.g., `blog:sync`).
203
+ - `args` (Optional): Additional arguments to pass to the script.
96
204
 
97
- Manage development branches for your projects.
205
+ **Examples:**
206
+ ```bash
207
+ # Run a core project script
208
+ npx nexical run test
98
209
 
99
- | Command | Usage | Description |
100
- | :--- | :--- | :--- |
101
- | `list` | `nexical branch list <teamId> <projectId>` | List branches. |
102
- | `create` | `nexical branch create <teamId> <projectId> <name>` | Create a branch. |
103
- | `get` | `nexical branch get <teamId> <projectId> <branchId>` | Get branch details. |
104
- | `delete` | `nexical branch delete ...` | Delete a branch. |
210
+ # Run a script defined in the 'blog' module's package.json
211
+ npx nexical run blog:sync --force
212
+ ```
213
+
214
+ ---
105
215
 
106
- ### ⚙️ Jobs (`job`)
216
+ #### `module`
107
217
 
108
- Trigger and monitor orchestration jobs.
218
+ Manages the modular architecture of your Nexical project. Allows you to add, remove, update, and list Git-based modules.
109
219
 
110
- | Command | Usage | Description |
111
- | :--- | :--- | :--- |
112
- | `list` | `nexical job list <teamId> <projectId> <branchId>` | List recent jobs. |
113
- | `trigger`| `nexical job trigger ... <type> [--input <json>]` | Trigger a new job (e.g., deploy). |
114
- | `get` | `nexical job get ... <jobId>` | Get job details. |
115
- | `logs` | `nexical job logs ... <jobId>` | Stream or view logs for a job. |
220
+ ##### `module add`
116
221
 
117
- ### 🎟️ API Tokens (`token`)
222
+ Adds a new module as a Git submodule.
118
223
 
119
- Manage personal access tokens for scripting and CI/CD.
224
+ **Usage:**
225
+ ```bash
226
+ npx nexical module add <url> [name]
227
+ ```
120
228
 
121
- | Command | Usage | Description |
122
- | :--- | :--- | :--- |
123
- | `list` | `nexical token list` | List your active tokens. |
124
- | `create` | `nexical token create <name> [--scopes <list>]` | Generate a new API token. |
125
- | `revoke` | `nexical token revoke <id>` | Revoke a token. |
229
+ **Arguments:**
230
+ - `url` (Required): The Git repository URL of the module.
231
+ - Supports `gh@owner/repo` shorthand.
232
+ - `name` (Optional): The folder name for the module. Defaults to the repository name.
126
233
 
127
- ### 🛡️ Admin (`admin`)
234
+ **What it does:**
235
+ 1. Adds the repository as a git submodule in `src/modules/<name>`.
236
+ 2. Installs any new dependencies via `npm install`.
128
237
 
129
- System administration commands (requires elevated permissions).
238
+ ##### `module list`
130
239
 
131
- | Command | Usage | Description |
132
- | :--- | :--- | :--- |
133
- | `create-user` | `nexical admin create-user <name> <email> <password>` | Create a system user. |
240
+ Lists all installed modules in the project.
134
241
 
135
- ---
242
+ **Usage:**
243
+ ```bash
244
+ npx nexical module list
245
+ ```
136
246
 
137
- ## 🏗️ Project Structure
247
+ **Output:**
248
+ - A table showing the name, version, and description of each installed module found in `src/modules`.
138
249
 
139
- The codebase is organized to be modular and extensible:
250
+ ##### `module update`
140
251
 
252
+ Updates one or all modules to their latest remote commit.
253
+
254
+ **Usage:**
255
+ ```bash
256
+ npx nexical module update [name]
141
257
  ```
142
- src/
143
- ├── commands/ # Command implementations
144
- │ ├── team/ # Team-related commands
145
- │ ├── project/ # Project-related commands
146
- │ └── ...
147
- ├── utils/ # Shared utilities (API client, config)
148
- └── index.ts # CLI entry point
258
+
259
+ **Arguments:**
260
+ - `name` (Optional): The specific module to update. If omitted, all modules are updated.
261
+
262
+ **What it does:**
263
+ 1. Runs `git submodule update --remote --merge` for the target(s).
264
+ 2. Re-installs dependencies to ensure `package-lock.json` is consistent.
265
+
266
+ ##### `module remove`
267
+
268
+ Removes an installed module and cleans up references.
269
+
270
+ **Usage:**
271
+ ```bash
272
+ npx nexical module remove <name>
149
273
  ```
150
274
 
151
- Each command is a class extending `BaseCommand` from `@nexical/cli-core`, enforcing a consistent structure for arguments, help text, and error handling.
275
+ **Arguments:**
276
+ - `name` (Required): The name of the module to remove.
277
+
278
+ **What it does:**
279
+ 1. De-initializes the git submodule.
280
+ 2. Removes the module directory from `src/modules`.
281
+ 3. Cleans up internal git metadata (`.git/modules`).
282
+ 4. Updates `npm` dependencies.
152
283
 
153
284
  ---
154
285
 
155
- ## 🧪 Testing
286
+ ## Project Structure
287
+
288
+ ```mermaid
289
+ graph TD
290
+ src-->commands
291
+ src-->core
292
+ src-->utils
293
+ commands-->init.ts
294
+ core-->CLI.ts
295
+ core-->BaseCommand.ts
296
+ core-->CommandLoader.ts
297
+ utils-->config.ts
298
+ utils-->logger.ts
299
+ ```
300
+
301
+ * **`src/commands/`**: Contains the implementations of individual CLI commands. File names correspond to command names.
302
+ * **`src/core/`**: The framework logic (Command loading, Base class, CLI orchestration).
303
+ * **`src/utils/`**: Shared utilities (Logging, Configuration parsing).
304
+ * **`test/unit/`**: Co-located unit tests. Mirrors the `src` structure.
305
+
306
+ ---
307
+
308
+ ## Development Workflow
309
+
310
+ ### Prerequisites
311
+ * Node.js (v18+ recommended)
312
+ * NPM
313
+
314
+ ### Setup
315
+
316
+ 1. **Install Dependencies**:
317
+ ```bash
318
+ npm install
319
+ ```
156
320
 
157
- We use **Vitest** for testing.
321
+ 2. **Build in Watch Mode**:
322
+ ```bash
323
+ npm run dev
324
+ ```
325
+ This uses `tsup` to watch for changes and rebuild `dist/`.
326
+
327
+ ### Running Tests
328
+
329
+ We prioritize **100% Test Coverage**. All logic branches, statements, and lines must be covered.
158
330
 
159
331
  ```bash
160
- # Run unit tests
161
- npm run test:unit
332
+ # Run all unit tests (with coverage report)
333
+ npm run test
162
334
  ```
163
335
 
336
+ Tests are written using `vitest` and are located in `test/unit/`. When submitting changes, ensure coverage remains at 100%.
337
+
338
+ ---
339
+
340
+ ## Adding New Commands
341
+
342
+ To create a new command, add a TypeScript file to `src/commands/`.
343
+
344
+ **Example:** Create `src/commands/hello.ts`
345
+
346
+ ```typescript
347
+ import { BaseCommand } from '../core/BaseCommand.js';
348
+
349
+ export default class HelloCommand extends BaseCommand {
350
+ // 1. Define command metadata
351
+ static description = 'Say hello to the world';
352
+
353
+ static args = {
354
+ args: [
355
+ { name: 'name', required: false, description: 'User name' }
356
+ ],
357
+ options: [
358
+ { name: '--shout', description: 'Say it loud', default: false }
359
+ ]
360
+ };
361
+
362
+ // 2. Implement the run method
363
+ async run(options: any) {
364
+ const name = options.name || 'World';
365
+
366
+ if (options.shout) {
367
+ this.success(`HELLO ${name.toUpperCase()}!`);
368
+ } else {
369
+ this.log(`Hello ${name}`);
370
+ }
371
+ }
372
+ }
373
+ ```
374
+
375
+ **Key Requirement**: The file MUST default export a class extending `BaseCommand`.
376
+
377
+ * **File Naming**:
378
+ * `hello.ts` -> Command: `hello`
379
+ * `users/create.ts` -> Command: `users create`
380
+ * `users/index.ts` -> Command: `users` (Parent command)
381
+
164
382
  ---
165
383
 
166
- ## 🤝 Contributing
384
+ ## Contributing
167
385
 
168
- 1. **Fork** the repository.
169
- 2. **Clone** your fork.
170
- 3. **Install** dependencies (`npm install`).
171
- 4. **Creating a Command**:
172
- - Add a new file in `src/commands/<topic>/<verb>.ts`.
173
- - Extend `BaseCommand`.
174
- - Define `static description` and `static args`.
175
- - Implement `run()`.
176
- 5. **Test** your changes.
177
- 6. **Submit** a Pull Request.
386
+ Contributions are welcome! Please follow these steps:
387
+ 1. Fork the repository.
388
+ 2. Create a feature branch.
389
+ 3. Add your changes and **ensure tests pass with 100% coverage**.
390
+ 4. Submit a Pull Request.
178
391
 
179
392
  ---
180
393
 
181
394
  ## License
182
395
 
183
- Apache-2.0
396
+ This project is licensed under the **Apache License 2.0**.
@@ -0,0 +1,42 @@
1
+ import { createRequire } from "module"; const require = createRequire(import.meta.url);
2
+ import {
3
+ init_esm_shims
4
+ } from "./chunk-OYFWMYPG.js";
5
+
6
+ // src/utils/url-resolver.ts
7
+ init_esm_shims();
8
+ function resolveGitUrl(url) {
9
+ if (!url) {
10
+ throw new Error("URL cannot be empty");
11
+ }
12
+ let resolved = url;
13
+ if (resolved.startsWith("gh@")) {
14
+ resolved = resolved.replace(/^gh@/, "https://github.com/");
15
+ }
16
+ const protocolMatch = resolved.match(/^[a-z0-9]+:\/\//i);
17
+ let splitIndex = -1;
18
+ if (protocolMatch) {
19
+ splitIndex = resolved.indexOf("//", protocolMatch[0].length);
20
+ } else {
21
+ splitIndex = resolved.indexOf("//");
22
+ }
23
+ let repoUrl = resolved;
24
+ let subPath = "";
25
+ if (splitIndex !== -1) {
26
+ repoUrl = resolved.substring(0, splitIndex);
27
+ subPath = resolved.substring(splitIndex + 2);
28
+ }
29
+ const isLocal = repoUrl.startsWith("/") || repoUrl.startsWith("./") || repoUrl.startsWith("../") || repoUrl.startsWith("file:") || repoUrl.startsWith("~");
30
+ if (!isLocal && !repoUrl.endsWith(".git")) {
31
+ repoUrl += ".git";
32
+ }
33
+ if (subPath) {
34
+ return `${repoUrl}//${subPath}`;
35
+ }
36
+ return repoUrl;
37
+ }
38
+
39
+ export {
40
+ resolveGitUrl
41
+ };
42
+ //# sourceMappingURL=chunk-JYASTIIW.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/utils/url-resolver.ts"],"sourcesContent":["/**\n * Resolves a git URL from various shorthand formats.\n * \n * Supported formats:\n * - gh@org/repo -> https://github.com/org/repo.git\n * - gh@org/repo//path -> https://github.com/org/repo.git//path\n * - https://github.com/org/repo -> https://github.com/org/repo.git\n * - https://github.com/org/repo.git -> https://github.com/org/repo.git\n * \n * @param url The URL string to resolve\n * @returns The fully qualified git URL with .git extension\n */\nexport function resolveGitUrl(url: string): string {\n if (!url) {\n throw new Error('URL cannot be empty');\n }\n\n let resolved = url;\n\n // Handle gh@ syntax\n if (resolved.startsWith('gh@')) {\n resolved = resolved.replace(/^gh@/, 'https://github.com/');\n }\n\n // Handle subpaths (split by //)\n // We must be careful not to split the protocol (e.g. https://)\n const protocolMatch = resolved.match(/^[a-z0-9]+:\\/\\//i);\n let splitIndex = -1;\n\n if (protocolMatch) {\n splitIndex = resolved.indexOf('//', protocolMatch[0].length);\n } else {\n splitIndex = resolved.indexOf('//');\n }\n\n let repoUrl = resolved;\n let subPath = '';\n\n if (splitIndex !== -1) {\n repoUrl = resolved.substring(0, splitIndex);\n subPath = resolved.substring(splitIndex + 2);\n }\n\n // Ensure .git extension, but ONLY for remote URLs (not local paths)\n const isLocal = repoUrl.startsWith('/') || repoUrl.startsWith('./') || repoUrl.startsWith('../') || repoUrl.startsWith('file:') || repoUrl.startsWith('~');\n\n if (!isLocal && !repoUrl.endsWith('.git')) {\n repoUrl += '.git';\n }\n\n // Reconstruction\n if (subPath) {\n return `${repoUrl}//${subPath}`;\n }\n\n return repoUrl;\n}\n"],"mappings":";;;;;;AAAA;AAYO,SAAS,cAAc,KAAqB;AAC/C,MAAI,CAAC,KAAK;AACN,UAAM,IAAI,MAAM,qBAAqB;AAAA,EACzC;AAEA,MAAI,WAAW;AAGf,MAAI,SAAS,WAAW,KAAK,GAAG;AAC5B,eAAW,SAAS,QAAQ,QAAQ,qBAAqB;AAAA,EAC7D;AAIA,QAAM,gBAAgB,SAAS,MAAM,kBAAkB;AACvD,MAAI,aAAa;AAEjB,MAAI,eAAe;AACf,iBAAa,SAAS,QAAQ,MAAM,cAAc,CAAC,EAAE,MAAM;AAAA,EAC/D,OAAO;AACH,iBAAa,SAAS,QAAQ,IAAI;AAAA,EACtC;AAEA,MAAI,UAAU;AACd,MAAI,UAAU;AAEd,MAAI,eAAe,IAAI;AACnB,cAAU,SAAS,UAAU,GAAG,UAAU;AAC1C,cAAU,SAAS,UAAU,aAAa,CAAC;AAAA,EAC/C;AAGA,QAAM,UAAU,QAAQ,WAAW,GAAG,KAAK,QAAQ,WAAW,IAAI,KAAK,QAAQ,WAAW,KAAK,KAAK,QAAQ,WAAW,OAAO,KAAK,QAAQ,WAAW,GAAG;AAEzJ,MAAI,CAAC,WAAW,CAAC,QAAQ,SAAS,MAAM,GAAG;AACvC,eAAW;AAAA,EACf;AAGA,MAAI,SAAS;AACT,WAAO,GAAG,OAAO,KAAK,OAAO;AAAA,EACjC;AAEA,SAAO;AACX;","names":[]}