-
Notifications
You must be signed in to change notification settings - Fork 34
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
12 changed files
with
4,805 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
OPENAI_API_KEY |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
# Logs | ||
logs | ||
*.log | ||
npm-debug.log* | ||
yarn-debug.log* | ||
yarn-error.log* | ||
lerna-debug.log* | ||
.pnpm-debug.log* | ||
|
||
# Diagnostic reports (https://nodejs.org/api/report.html) | ||
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json | ||
|
||
# Runtime data | ||
pids | ||
*.pid | ||
*.seed | ||
*.pid.lock | ||
|
||
# Directory for instrumented libs generated by jscoverage/JSCover | ||
lib-cov | ||
|
||
# Coverage directory used by tools like istanbul | ||
coverage | ||
*.lcov | ||
|
||
# nyc test coverage | ||
.nyc_output | ||
|
||
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) | ||
.grunt | ||
|
||
# Bower dependency directory (https://bower.io/) | ||
bower_components | ||
|
||
# node-waf configuration | ||
.lock-wscript | ||
|
||
# Compiled binary addons (https://nodejs.org/api/addons.html) | ||
build/Release | ||
|
||
# Dependency directories | ||
node_modules/ | ||
jspm_packages/ | ||
|
||
# Snowpack dependency directory (https://snowpack.dev/) | ||
web_modules/ | ||
|
||
# TypeScript cache | ||
*.tsbuildinfo | ||
/src/*.js | ||
bin/*.js | ||
# Optional npm cache directory | ||
.npm | ||
|
||
# Optional eslint cache | ||
.eslintcache | ||
|
||
# Optional stylelint cache | ||
.stylelintcache | ||
|
||
# Microbundle cache | ||
.rpt2_cache/ | ||
.rts2_cache_cjs/ | ||
.rts2_cache_es/ | ||
.rts2_cache_umd/ | ||
|
||
# Optional REPL history | ||
.node_repl_history | ||
|
||
# Output of 'npm pack' | ||
*.tgz | ||
|
||
# Yarn Integrity file | ||
.yarn-integrity | ||
|
||
# dotenv environment variable files | ||
.env | ||
.env.development.local | ||
.env.test.local | ||
.env.production.local | ||
.env.local | ||
|
||
# parcel-bundler cache (https://parceljs.org/) | ||
.cache | ||
.parcel-cache | ||
|
||
# Next.js build output | ||
.next | ||
out | ||
|
||
# Nuxt.js build / generate output | ||
.nuxt | ||
dist | ||
|
||
# Gatsby files | ||
.cache/ | ||
# Comment in the public line in if your project uses Gatsby and not Next.js | ||
# https://nextjs.org/blog/next-9-1#public-directory-support | ||
# public | ||
|
||
# vuepress build output | ||
.vuepress/dist | ||
|
||
# vuepress v2.x temp and cache directory | ||
.temp | ||
.cache | ||
|
||
# Docusaurus cache and generated files | ||
.docusaurus | ||
|
||
# Serverless directories | ||
.serverless/ | ||
|
||
# FuseBox cache | ||
.fusebox/ | ||
|
||
# DynamoDB Local files | ||
.dynamodb/ | ||
|
||
# TernJS port file | ||
.tern-port | ||
|
||
# Stores VSCode versions used for testing VSCode extensions | ||
.vscode-test | ||
|
||
# yarn v2 | ||
.yarn/cache | ||
.yarn/unplugged | ||
.yarn/build-state.yml | ||
.yarn/install-state.gz | ||
.pnp.* |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
# Spec generator | ||
This is a custom CLI tool that generates and executes stencil commands based on user prompt, creates YAML configuration files, and runs the generated stencil spec. | ||
|
||
Table of Contents | ||
- Installation | ||
- Linking the @samagra-x/stencil-cli Package | ||
- Running the CLI | ||
- Examples | ||
|
||
### Installation | ||
1. Clone this repository to your local machine. | ||
|
||
`git clone <repository-url> cd <repository-folder>` | ||
|
||
2. Install the required dependencies using your package manager (e.g., npm or pnpm). | ||
|
||
`npm install` | ||
|
||
Usage | ||
The CLI generates project initialization commands for the `stencil` framework based on user prompts, then writes the configuration into a `spec.yaml` file, and finally runs the `stencil spec` command. | ||
|
||
The tool supports the following options: | ||
|
||
#### Tooling: | ||
- prisma | ||
- user-service | ||
- monitoring | ||
- temporal | ||
- fileUpload | ||
|
||
#### Package Manager | ||
- npm | ||
- pnpm | ||
- yarn | ||
- bun | ||
|
||
#### Docker Services | ||
- Tooling Setup | ||
- logging | ||
- monitoring | ||
- temporal | ||
- Adhoc Setup | ||
- postgres | ||
- hasura | ||
- fusionauth | ||
- minio | ||
|
||
### Linking the @samagra-x/stencil-cli Package | ||
|
||
Before using the CLI, you need to link the `@samagra-x/stencil-cli` package to your global node_modules to ensure the tool can call the stencil command. | ||
|
||
1. Navigate to the @samagra-x/stencil-cli package folder. https://github.com/SamagraX-Stencil/stencil-cli/pull/31 | ||
|
||
cd path/to/@samagra-x/stencil-cli | ||
|
||
2. Run the following command to link the package globally. | ||
|
||
npm link | ||
|
||
This will allow the `stencil` command to be used globally in your terminal. | ||
|
||
3. Navigate back to the root of this project. | ||
|
||
cd path/to/this-project | ||
|
||
### Running the CLI | ||
|
||
To run the CLI, first build the project: | ||
|
||
npm run build | ||
|
||
Then, execute the CLI with a user prompt: | ||
|
||
specgpt "<your-prompt-here>" | ||
|
||
### For example: | ||
|
||
specgpt "Set up a project named AllInOneService with Prisma, user service, monitoring, temporal and file upload setup along with logging, monitoring, postgres,hasura, fusionauth and minio as docker service with npm as the package installer" | ||
|
||
### Spec File Structure | ||
``` | ||
stencil: 0.0.1 | ||
info: | ||
properties: | ||
project-name: "AllInOneService" | ||
package-manager: "npm" | ||
tooling: [prisma,user-service,temporal,fileUpload,monitoring] | ||
docker: [monitoring,postgres,hasura,logging,fusionauth,minio] | ||
endpoints: | ||
``` | ||
|
||
This will: | ||
|
||
Generate a corresponding stencil spec file with the relevant project configuration. | ||
|
||
Run the stencil spec command using the generated spec.yaml. | ||
|
||
### Demo | ||
https://github.com/user-attachments/assets/c2257f98-60ad-4531-9c55-71129c8d525b | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
#! /usr/bin/env node | ||
|
||
import { Command } from "commander"; | ||
import { getLLMResponse, runStencilSpec } from "../src/index.js"; | ||
import { writeYAMLToFile } from "../src/yamlgen.js"; | ||
import * as ora from 'ora'; | ||
import * as fs from 'fs'; | ||
import * as inquirer from 'inquirer'; | ||
import * as path from 'path'; | ||
|
||
const prompt = inquirer.createPromptModule(); | ||
|
||
const program = new Command(); | ||
|
||
program | ||
.version('0.1.0') | ||
.description('CLI to generate stencil YAML configuration and run stencil spec from a prompt') | ||
.argument('<prompt>', 'User prompt for project generation or spec.yaml') | ||
.action(async (initialPrompt: string) => { | ||
|
||
let continueFlow = true; | ||
let promptInput = initialPrompt; | ||
|
||
while (continueFlow) { | ||
const result = await getLLMResponse({ inputs: promptInput }); | ||
|
||
const specFilePath = path.join(process.cwd(), "spec.yaml"); | ||
const updatedSpecFile = writeYAMLToFile(result.response, "spec.yaml"); | ||
|
||
console.info("\nGenerated Spec File:"); | ||
console.info(updatedSpecFile); | ||
console.info(`Specification file written to ${specFilePath}`); | ||
|
||
const confirmQuestion: any = { | ||
type: 'confirm', | ||
name: 'looksGood', | ||
message: 'Does the spec file look good?', | ||
default: true, | ||
}; | ||
|
||
const answers = await prompt([confirmQuestion]); | ||
|
||
if (answers.looksGood) { | ||
runStencilSpec(); | ||
continueFlow = false; | ||
} else { | ||
const regenerateQuestion: any = { | ||
type: 'confirm', | ||
name: 'regenerate', | ||
message: 'Do you want to regenerate the spec by giving a new prompt?', | ||
default: true, | ||
}; | ||
|
||
const regenerateAnswer: any = await prompt([regenerateQuestion]); | ||
|
||
if (regenerateAnswer.regenerate) { | ||
const newPromptQuestion: any = { | ||
type: 'input', | ||
name: 'newPrompt', | ||
message: 'Please provide a new prompt:', | ||
}; | ||
|
||
const newPromptAnswer: any = await prompt([newPromptQuestion]); | ||
|
||
promptInput = newPromptAnswer.newPrompt; | ||
} else { | ||
console.info(`\nYou can manually edit the spec file at: ${specFilePath}`); | ||
console.info('Once edited, you can run the command:'); | ||
console.info(`stencil spec spec.yaml`); | ||
continueFlow = false; | ||
} | ||
} | ||
} | ||
}); | ||
|
||
program.parse(process.argv); |
Oops, something went wrong.