@atlashub/smartstack-cli 1.7.0 → 1.8.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.
- package/.documentation/init.html +9 -65
- package/README.md +556 -78
- package/dist/index.js +29 -134
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/templates/agents/gitflow/status.md +98 -11
- package/templates/commands/efcore/conflicts.md +98 -32
- package/templates/commands/efcore/db-deploy.md +107 -10
- package/templates/commands/efcore/db-reset.md +69 -14
- package/templates/commands/efcore/db-seed.md +67 -11
- package/templates/commands/efcore/db-status.md +57 -20
- package/templates/commands/efcore/migration.md +84 -23
- package/templates/commands/efcore/rebase-snapshot.md +81 -23
- package/templates/commands/efcore/scan.md +94 -29
- package/templates/commands/efcore/squash.md +97 -41
- package/templates/commands/gitflow/1-init.md +216 -5
- package/templates/commands/gitflow/10-start.md +194 -24
- package/templates/commands/gitflow/11-finish.md +141 -59
- package/templates/commands/gitflow/2-status.md +238 -58
- package/templates/commands/gitflow/3-commit.md +93 -0
- package/templates/commands/gitflow/7-pull-request.md +133 -16
package/dist/index.js
CHANGED
|
@@ -38995,7 +38995,7 @@ var import_child_process = require("child_process");
|
|
|
38995
38995
|
var import_fs_extra = __toESM(require_lib());
|
|
38996
38996
|
var PACKAGE_ROOT = (0, import_path.join)(__dirname, "..");
|
|
38997
38997
|
var TEMPLATES_DIR = (0, import_path.join)(PACKAGE_ROOT, "templates");
|
|
38998
|
-
var INSTALL_DIRS = ["commands", "agents", "hooks"];
|
|
38998
|
+
var INSTALL_DIRS = ["commands", "agents", "hooks", "skills"];
|
|
38999
38999
|
var DEFAULT_PLUGINS = [];
|
|
39000
39000
|
function getClaudeDir(global3) {
|
|
39001
39001
|
if (global3) {
|
|
@@ -39165,7 +39165,8 @@ async function checkInstallation(options = {}) {
|
|
|
39165
39165
|
components: {
|
|
39166
39166
|
commands: { installed: false, count: 0 },
|
|
39167
39167
|
agents: { installed: false, count: 0 },
|
|
39168
|
-
hooks: { installed: false, count: 0 }
|
|
39168
|
+
hooks: { installed: false, count: 0 },
|
|
39169
|
+
skills: { installed: false, count: 0 }
|
|
39169
39170
|
},
|
|
39170
39171
|
gitflow: {
|
|
39171
39172
|
configExists: false,
|
|
@@ -39191,6 +39192,12 @@ async function checkInstallation(options = {}) {
|
|
|
39191
39192
|
result.components.hooks.installed = await import_fs_extra.default.pathExists((0, import_path.join)(hooksDir, "hooks.json"));
|
|
39192
39193
|
result.components.hooks.count = result.components.hooks.installed ? 1 : 0;
|
|
39193
39194
|
}
|
|
39195
|
+
const skillsDir = (0, import_path.join)(claudeDir, "skills");
|
|
39196
|
+
if (await import_fs_extra.default.pathExists(skillsDir)) {
|
|
39197
|
+
const files = await getTemplateFiles(skillsDir);
|
|
39198
|
+
result.components.skills.count = files.filter((f) => f.endsWith(".md")).length;
|
|
39199
|
+
result.components.skills.installed = result.components.skills.count > 0;
|
|
39200
|
+
}
|
|
39194
39201
|
const gitflowDir = (0, import_path.join)(claudeDir, "gitflow");
|
|
39195
39202
|
result.gitflow.configExists = await import_fs_extra.default.pathExists((0, import_path.join)(gitflowDir, "config.json"));
|
|
39196
39203
|
const plansDir = (0, import_path.join)(gitflowDir, "plans");
|
|
@@ -39198,7 +39205,7 @@ async function checkInstallation(options = {}) {
|
|
|
39198
39205
|
const plans = await import_fs_extra.default.readdir(plansDir);
|
|
39199
39206
|
result.gitflow.plansCount = plans.filter((f) => f.endsWith(".md")).length;
|
|
39200
39207
|
}
|
|
39201
|
-
result.installed = result.components.commands.installed || result.components.agents.installed || result.components.hooks.installed;
|
|
39208
|
+
result.installed = result.components.commands.installed || result.components.agents.installed || result.components.hooks.installed || result.components.skills.installed;
|
|
39202
39209
|
return result;
|
|
39203
39210
|
}
|
|
39204
39211
|
async function listInstalledCommands(options = {}) {
|
|
@@ -41886,6 +41893,10 @@ var statusCommand = new Command("status").alias("s").description("Show installat
|
|
|
41886
41893
|
"Hooks",
|
|
41887
41894
|
installation.components.hooks.installed ? source_default.green(`\u2713 Configured`) : source_default.gray("Not installed")
|
|
41888
41895
|
],
|
|
41896
|
+
[
|
|
41897
|
+
"Skills",
|
|
41898
|
+
installation.components.skills.installed ? source_default.green(`\u2713 ${installation.components.skills.count} files`) : source_default.gray("Not installed")
|
|
41899
|
+
],
|
|
41889
41900
|
[""],
|
|
41890
41901
|
[
|
|
41891
41902
|
"GitFlow Config",
|
|
@@ -42018,9 +42029,7 @@ function checkPrerequisites() {
|
|
|
42018
42029
|
}
|
|
42019
42030
|
};
|
|
42020
42031
|
return {
|
|
42021
|
-
dotnet: check("dotnet", ["--version"])
|
|
42022
|
-
node: check("node", ["--version"]),
|
|
42023
|
-
npm: check("npm", ["--version"])
|
|
42032
|
+
dotnet: check("dotnet", ["--version"])
|
|
42024
42033
|
};
|
|
42025
42034
|
}
|
|
42026
42035
|
async function checkMcpServers() {
|
|
@@ -42159,61 +42168,6 @@ async function createBackendStructure(config, dryRun) {
|
|
|
42159
42168
|
}
|
|
42160
42169
|
}
|
|
42161
42170
|
}
|
|
42162
|
-
async function createFrontendStructure(config, dryRun) {
|
|
42163
|
-
const { name, nameLower } = config;
|
|
42164
|
-
const webDir = (0, import_path4.join)(name, "web", `${nameLower}-web`);
|
|
42165
|
-
logger.info("Creating React application...");
|
|
42166
|
-
if (!dryRun) {
|
|
42167
|
-
await import_fs_extra3.default.ensureDir(webDir);
|
|
42168
|
-
}
|
|
42169
|
-
execCommand(`npm create vite@latest . -- --template react-ts`, webDir, dryRun);
|
|
42170
|
-
execCommand("npm install", webDir, dryRun);
|
|
42171
|
-
logger.info("Installing @atlashub/smartstack-react...");
|
|
42172
|
-
execCommand("npm install @atlashub/smartstack-react", webDir, dryRun);
|
|
42173
|
-
execCommand("npm install axios react-router-dom i18next react-i18next", webDir, dryRun);
|
|
42174
|
-
execCommand("npm install -D tailwindcss @tailwindcss/vite", webDir, dryRun);
|
|
42175
|
-
if (!dryRun) {
|
|
42176
|
-
const viteConfig = `import { defineConfig } from 'vite'
|
|
42177
|
-
import react from '@vitejs/plugin-react'
|
|
42178
|
-
import tailwindcss from '@tailwindcss/vite'
|
|
42179
|
-
|
|
42180
|
-
export default defineConfig({
|
|
42181
|
-
plugins: [react(), tailwindcss()],
|
|
42182
|
-
server: {
|
|
42183
|
-
port: 5173,
|
|
42184
|
-
proxy: {
|
|
42185
|
-
'/api': {
|
|
42186
|
-
target: 'https://localhost:5001',
|
|
42187
|
-
changeOrigin: true,
|
|
42188
|
-
secure: false
|
|
42189
|
-
}
|
|
42190
|
-
}
|
|
42191
|
-
}
|
|
42192
|
-
})
|
|
42193
|
-
`;
|
|
42194
|
-
await import_fs_extra3.default.writeFile((0, import_path4.join)(webDir, "vite.config.ts"), viteConfig);
|
|
42195
|
-
}
|
|
42196
|
-
if (!dryRun) {
|
|
42197
|
-
const mainTsx = `import { StrictMode } from 'react'
|
|
42198
|
-
import { createRoot } from 'react-dom/client'
|
|
42199
|
-
import { BrowserRouter } from 'react-router-dom'
|
|
42200
|
-
import { SmartStackProvider } from '@atlashub/smartstack-react'
|
|
42201
|
-
import '@atlashub/smartstack-react/styles'
|
|
42202
|
-
import App from './App'
|
|
42203
|
-
|
|
42204
|
-
createRoot(document.getElementById('root')!).render(
|
|
42205
|
-
<StrictMode>
|
|
42206
|
-
<BrowserRouter>
|
|
42207
|
-
<SmartStackProvider apiUrl="https://localhost:5001/api">
|
|
42208
|
-
<App />
|
|
42209
|
-
</SmartStackProvider>
|
|
42210
|
-
</BrowserRouter>
|
|
42211
|
-
</StrictMode>
|
|
42212
|
-
)
|
|
42213
|
-
`;
|
|
42214
|
-
await import_fs_extra3.default.writeFile((0, import_path4.join)(webDir, "src", "main.tsx"), mainTsx);
|
|
42215
|
-
}
|
|
42216
|
-
}
|
|
42217
42171
|
async function createConfigFiles(config, dryRun) {
|
|
42218
42172
|
const { name } = config;
|
|
42219
42173
|
if (dryRun) {
|
|
@@ -42296,13 +42250,9 @@ A SmartStack application.
|
|
|
42296
42250
|
## Prerequisites
|
|
42297
42251
|
|
|
42298
42252
|
- .NET 10.0 SDK
|
|
42299
|
-
- Node.js 18+
|
|
42300
|
-
- npm 9+
|
|
42301
42253
|
|
|
42302
42254
|
## Getting Started
|
|
42303
42255
|
|
|
42304
|
-
### Backend
|
|
42305
|
-
|
|
42306
42256
|
\`\`\`bash
|
|
42307
42257
|
# Restore packages
|
|
42308
42258
|
dotnet restore
|
|
@@ -42317,14 +42267,6 @@ dotnet ef database update -p src/${name}.Infrastructure -s src/${name}.Api
|
|
|
42317
42267
|
dotnet run --project src/${name}.Api
|
|
42318
42268
|
\`\`\`
|
|
42319
42269
|
|
|
42320
|
-
### Frontend
|
|
42321
|
-
|
|
42322
|
-
\`\`\`bash
|
|
42323
|
-
cd web/${name.toLowerCase()}-web
|
|
42324
|
-
npm install
|
|
42325
|
-
npm run dev
|
|
42326
|
-
\`\`\`
|
|
42327
|
-
|
|
42328
42270
|
## Project Structure
|
|
42329
42271
|
|
|
42330
42272
|
\`\`\`
|
|
@@ -42334,8 +42276,6 @@ ${name}/
|
|
|
42334
42276
|
\u2502 \u251C\u2500\u2500 ${name}.Application/ # Application services and DTOs
|
|
42335
42277
|
\u2502 \u251C\u2500\u2500 ${name}.Infrastructure/ # EF Core, repositories, external services
|
|
42336
42278
|
\u2502 \u2514\u2500\u2500 ${name}.Api/ # Web API controllers and configuration
|
|
42337
|
-
\u251C\u2500\u2500 web/
|
|
42338
|
-
\u2502 \u2514\u2500\u2500 ${name.toLowerCase()}-web/ # React frontend
|
|
42339
42279
|
\u2514\u2500\u2500 tests/ # Unit and integration tests
|
|
42340
42280
|
\`\`\`
|
|
42341
42281
|
|
|
@@ -42357,7 +42297,7 @@ async function initializeGit(config, dryRun) {
|
|
|
42357
42297
|
execCommand("git add .", name, dryRun);
|
|
42358
42298
|
execCommand('git commit -m "chore: initial SmartStack project setup"', name, dryRun);
|
|
42359
42299
|
}
|
|
42360
|
-
var initCommand = new Command("init").description("Initialize a new SmartStack project").argument("<name>", "Project name").option("--
|
|
42300
|
+
var initCommand = new Command("init").description("Initialize a new SmartStack project").argument("<name>", "Project name").option("--db <type>", "Database type (sqlserver, postgresql, sqlite)", "sqlserver").option("--dry-run", "Show what would be created without actually creating").option("-y, --yes", "Skip prompts and use defaults").option("--skip-mcp-check", "Skip MCP servers verification").action(async (name, options) => {
|
|
42361
42301
|
logger.header("SmartStack Project Initialization");
|
|
42362
42302
|
if (!options.skipMcpCheck) {
|
|
42363
42303
|
logger.info("Checking MCP servers...");
|
|
@@ -42410,45 +42350,24 @@ var initCommand = new Command("init").description("Initialize a new SmartStack p
|
|
|
42410
42350
|
}
|
|
42411
42351
|
}
|
|
42412
42352
|
const prereqs = checkPrerequisites();
|
|
42413
|
-
|
|
42414
|
-
const needsFrontend = !options.backend;
|
|
42415
|
-
if (needsBackend && !prereqs.dotnet) {
|
|
42353
|
+
if (!prereqs.dotnet) {
|
|
42416
42354
|
logger.error(".NET SDK not found. Please install .NET 10.0 or later.");
|
|
42417
42355
|
process.exit(1);
|
|
42418
42356
|
}
|
|
42419
|
-
if (needsFrontend && (!prereqs.node || !prereqs.npm)) {
|
|
42420
|
-
logger.error("Node.js/npm not found. Please install Node.js 18 or later.");
|
|
42421
|
-
process.exit(1);
|
|
42422
|
-
}
|
|
42423
42357
|
if (await import_fs_extra3.default.pathExists(name)) {
|
|
42424
42358
|
logger.error(`Directory '${name}' already exists.`);
|
|
42425
42359
|
process.exit(1);
|
|
42426
42360
|
}
|
|
42427
|
-
let projectType = "full-stack";
|
|
42428
|
-
if (options.backend) projectType = "backend";
|
|
42429
|
-
if (options.frontend) projectType = "frontend";
|
|
42430
42361
|
let config;
|
|
42431
42362
|
if (options.yes) {
|
|
42432
42363
|
config = {
|
|
42433
42364
|
name,
|
|
42434
42365
|
nameLower: name.toLowerCase(),
|
|
42435
|
-
type: projectType,
|
|
42436
42366
|
database: options.db || "sqlserver",
|
|
42437
42367
|
modules: ["Auth", "Navigation", "Notifications"]
|
|
42438
42368
|
};
|
|
42439
42369
|
} else {
|
|
42440
42370
|
const answers = await lib_default.prompt([
|
|
42441
|
-
{
|
|
42442
|
-
type: "list",
|
|
42443
|
-
name: "type",
|
|
42444
|
-
message: "What type of project do you want to create?",
|
|
42445
|
-
choices: [
|
|
42446
|
-
{ name: "Full Stack (Backend .NET + Frontend React)", value: "full-stack" },
|
|
42447
|
-
{ name: "Backend Only (.NET API)", value: "backend" },
|
|
42448
|
-
{ name: "Frontend Only (React)", value: "frontend" }
|
|
42449
|
-
],
|
|
42450
|
-
default: projectType
|
|
42451
|
-
},
|
|
42452
42371
|
{
|
|
42453
42372
|
type: "list",
|
|
42454
42373
|
name: "database",
|
|
@@ -42458,8 +42377,7 @@ var initCommand = new Command("init").description("Initialize a new SmartStack p
|
|
|
42458
42377
|
{ name: "PostgreSQL", value: "postgresql" },
|
|
42459
42378
|
{ name: "SQLite", value: "sqlite" }
|
|
42460
42379
|
],
|
|
42461
|
-
default: options.db || "sqlserver"
|
|
42462
|
-
when: (ans) => ans.type !== "frontend"
|
|
42380
|
+
default: options.db || "sqlserver"
|
|
42463
42381
|
},
|
|
42464
42382
|
{
|
|
42465
42383
|
type: "checkbox",
|
|
@@ -42470,14 +42388,12 @@ var initCommand = new Command("init").description("Initialize a new SmartStack p
|
|
|
42470
42388
|
{ name: "Navigation (Dynamic menus)", value: "Navigation", checked: true },
|
|
42471
42389
|
{ name: "AI (OpenAI/Claude integration)", value: "AI", checked: false },
|
|
42472
42390
|
{ name: "Notifications (SignalR real-time)", value: "Notifications", checked: true }
|
|
42473
|
-
]
|
|
42474
|
-
when: (ans) => ans.type !== "frontend"
|
|
42391
|
+
]
|
|
42475
42392
|
}
|
|
42476
42393
|
]);
|
|
42477
42394
|
config = {
|
|
42478
42395
|
name,
|
|
42479
42396
|
nameLower: name.toLowerCase(),
|
|
42480
|
-
type: answers.type,
|
|
42481
42397
|
database: answers.database || "sqlserver",
|
|
42482
42398
|
modules: answers.modules || []
|
|
42483
42399
|
};
|
|
@@ -42488,25 +42404,15 @@ var initCommand = new Command("init").description("Initialize a new SmartStack p
|
|
|
42488
42404
|
}
|
|
42489
42405
|
console.log();
|
|
42490
42406
|
logger.info(`Project: ${source_default.cyan(config.name)}`);
|
|
42491
|
-
logger.info(`
|
|
42492
|
-
|
|
42493
|
-
logger.info(`Database: ${source_default.cyan(config.database)}`);
|
|
42494
|
-
logger.info(`Modules: ${source_default.cyan(config.modules.join(", ") || "None")}`);
|
|
42495
|
-
}
|
|
42407
|
+
logger.info(`Database: ${source_default.cyan(config.database)}`);
|
|
42408
|
+
logger.info(`Modules: ${source_default.cyan(config.modules.join(", ") || "None")}`);
|
|
42496
42409
|
console.log();
|
|
42497
42410
|
try {
|
|
42498
42411
|
if (!dryRun) {
|
|
42499
42412
|
await import_fs_extra3.default.ensureDir(name);
|
|
42500
42413
|
}
|
|
42501
|
-
|
|
42502
|
-
|
|
42503
|
-
}
|
|
42504
|
-
if (config.type === "full-stack" || config.type === "frontend") {
|
|
42505
|
-
await createFrontendStructure(config, dryRun);
|
|
42506
|
-
}
|
|
42507
|
-
if (config.type !== "frontend") {
|
|
42508
|
-
await createConfigFiles(config, dryRun);
|
|
42509
|
-
}
|
|
42414
|
+
await createBackendStructure(config, dryRun);
|
|
42415
|
+
await createConfigFiles(config, dryRun);
|
|
42510
42416
|
await initializeGit(config, dryRun);
|
|
42511
42417
|
const summary = [
|
|
42512
42418
|
source_default.green.bold("Project created successfully!"),
|
|
@@ -42514,27 +42420,16 @@ var initCommand = new Command("init").description("Initialize a new SmartStack p
|
|
|
42514
42420
|
`Location: ${source_default.cyan((0, import_path4.join)(process.cwd(), name))}`,
|
|
42515
42421
|
"",
|
|
42516
42422
|
source_default.bold("Next steps:"),
|
|
42517
|
-
""
|
|
42518
|
-
|
|
42519
|
-
|
|
42520
|
-
|
|
42521
|
-
|
|
42522
|
-
` 2. Create migration: ${source_default.cyan(`dotnet ef migrations add InitialCreate -p src/${name}.Infrastructure -s src/${name}.Api`)}`,
|
|
42523
|
-
` 3. Apply migration: ${source_default.cyan(`dotnet ef database update -p src/${name}.Infrastructure -s src/${name}.Api`)}`,
|
|
42524
|
-
` 4. Run backend: ${source_default.cyan(`dotnet run --project src/${name}.Api`)}`
|
|
42525
|
-
);
|
|
42526
|
-
}
|
|
42527
|
-
if (config.type !== "backend") {
|
|
42528
|
-
summary.push(
|
|
42529
|
-
` 5. Run frontend: ${source_default.cyan(`cd web/${name.toLowerCase()}-web && npm run dev`)}`
|
|
42530
|
-
);
|
|
42531
|
-
}
|
|
42532
|
-
summary.push(
|
|
42423
|
+
"",
|
|
42424
|
+
` 1. Configure connection string in ${source_default.cyan("appsettings.json")}`,
|
|
42425
|
+
` 2. Create migration: ${source_default.cyan(`dotnet ef migrations add InitialCreate -p src/${name}.Infrastructure -s src/${name}.Api`)}`,
|
|
42426
|
+
` 3. Apply migration: ${source_default.cyan(`dotnet ef database update -p src/${name}.Infrastructure -s src/${name}.Api`)}`,
|
|
42427
|
+
` 4. Run the API: ${source_default.cyan(`dotnet run --project src/${name}.Api`)}`,
|
|
42533
42428
|
"",
|
|
42534
42429
|
source_default.bold("Documentation:"),
|
|
42535
42430
|
` SmartStack: ${source_default.cyan("https://docs.smartstack.app")}`,
|
|
42536
42431
|
` API Reference: ${source_default.cyan("https://localhost:5001/scalar")} (when running)`
|
|
42537
|
-
|
|
42432
|
+
];
|
|
42538
42433
|
logger.box(summary, "success");
|
|
42539
42434
|
} catch (error) {
|
|
42540
42435
|
logger.error(`Failed to create project: ${error instanceof Error ? error.message : error}`);
|