Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[93] - feat: llm command to generate spec using prompt #188

Open
wants to merge 1 commit into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions spec-actor/.env.sample
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
OPENAI_API_KEY
131 changes: 131 additions & 0 deletions spec-actor/.gitignore
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.*
104 changes: 104 additions & 0 deletions spec-actor/Readme.md
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

76 changes: 76 additions & 0 deletions spec-actor/bin/specgpt.ts
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);
Loading