Skip to content

Commit 9dac1ea

Browse files
committed
- replaced *.hbs with *.md for actions code syntax highlighting
- added support for ':pre' template execution code script blocks - added input text classification into a suitable action template - added support for running nodejs pre code blocks and returning data chaining between code blocks - added 2/3 functioning write-readme action
1 parent 8d47980 commit 9dac1ea

7 files changed

+82
-26
lines changed

actions/create-react-website.hbs actions/create-react-website.md

+4-3
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,17 @@
22
Creates a reactJS webapp project.
33
```
44

5-
```pre:js
5+
```js:pre
66
// javascript code to run on project before executing the template prompt
77
// contains a 'context' object with the keys:
88
// 'input' = user input text prompt
99
// if you want, you may return an object to make the values available for the next code-block or template
1010
// this codeblock gets executed isolated within an async function
11+
// you can also use any of the variables available on the handlebar template such as source_tree, absolute_code_path, etc
1112
// you also have some methods for asking info to the user like (await prompt)
1213
// anything queried to the user is translated to the user's language using the LLM
1314
const project_name = await prompt('What is the name of your project?')
14-
const app_name = await queryLLM('Create a short folder name (max 10 chars without spaces) for the following text: ' + project_name,
15+
const app_name = await queryLLM('Create a short but meaningful folder name (between 8-12 chars, dash-case, lowercase) extracted from the following text: ' + project_name,
1516
z.object({
1617
name: z.string().describe('the reactjs folder name for the text'),
1718
})
@@ -21,7 +22,7 @@ return {
2122
}
2223
```
2324

24-
```pre:bash
25+
```bash:pre
2526
# terminal commands to run on project before executing the template prompt
2627
# if OS is different than MacOS we could ask the LLM for translating them to another OS later before execution
2728
# any bash here executes with the env CI=true so it won't prompt the user for anything
File renamed without changes.

actions/index.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// read all .hbs files in the current directory
1+
// read all .md files in the current directory
22
// parse the md code-blocks looking for 'description' lang field blocks
33
// create a prompt for the CLI to choose the best action template based on the user input
44
//
@@ -15,8 +15,8 @@ class indexFolder {
1515
}
1616

1717
async initialize() {
18-
// traverse current folder and read all .hbs files
19-
const files = await glob('**/*.hbs', { cwd: this.currentFolder, nodir:true, absolute:true });
18+
// traverse current folder and read all .md (with hbs) files
19+
const files = await glob('**/*.md', { cwd: this.currentFolder, nodir:true, absolute:true });
2020
for (const file of files) {
2121
// read 'file' contents
2222
const content = await fs.readFile(file, 'utf-8');

actions/write-readme.hbs actions/write-readme.md

+34-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,39 @@
11
```description
22
Generates a README file for a project.
33
```
4+
5+
```js:pre
6+
// what kind of files should I read from this project source to generate the README?
7+
const files_ = await queryLLM('What are the main files we need from the sourcetree to generate a README of this project?\n'+source_tree,
8+
z.array(z.string()).describe('filenames to read from the given source tree')
9+
);
10+
console.log('queryLLM files_',files_.data);
11+
// read the indicated files and return object overwriting default files (use readFiles helper that takes an array of files and returns an array of objects with a field named 'code')
12+
// add absolute_code_path prefix to the files if it's not contained
13+
// filter 'files' to only include the files that are in the 'files_' array
14+
let filtered = [];
15+
files = files.map((item)=>{
16+
files_.data.some((file)=>{
17+
if (item.path.includes(file)){
18+
// also truncate the files to 1000 characters
19+
item.code = item.code.substring(0, 1000);
20+
filtered.push(item);
21+
return true;
22+
}
23+
});
24+
});
25+
console.log('filtered', filtered);
26+
console.log('files_', files_);
27+
return {
28+
files: filtered
29+
}
30+
```
31+
32+
```js:pre
33+
console.log('SECOND JS BLOCK');
34+
console.log('files2', files);
35+
```
36+
437
Project Path: {{ absolute_code_path }}
538

639
I'd like you to generate a high-quality README file for this project, suitable for hosting on GitHub. Analyze the codebase to understand the purpose, functionality, and structure of the project.
@@ -36,7 +69,7 @@ Write the content in Markdown format. Use your analysis of the code to generate
3669

3770
Feel free to infer reasonable details if needed, but try to stick to what can be determined from the codebase itself. Let me know if you have any other questions as you're writing!
3871

39-
```schema
72+
```json:schema
4073
{
4174
"readme": "content of the README file"
4275
}

index.js

+33-11
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ const argv = yargs(hideBin(process.argv))
2525
const code2prompt = require('code2prompt');
2626
const safeEval = require('safe-eval');
2727
const path = require('path');
28+
const fs = require('fs').promises;
2829
const currentWorkingDirectory = process.cwd();
2930
const actionsDirectory = path.join(__dirname, 'actions');
3031
require('dotenv').config();
@@ -38,7 +39,7 @@ const { z } = require('zod');
3839
// 0) determine if the input is an action or a question, and the user input language
3940
const general = new code2prompt({
4041
path: currentWorkingDirectory,
41-
template: path.join(actionsDirectory,'default.hbs'),
42+
template: path.join(actionsDirectory,'default.md'),
4243
extensions: ["js"],
4344
ignore: ["**/node_modules/**"],
4445
OPENAI_KEY: process.env.OPENAI_KEY
@@ -55,6 +56,7 @@ const { z } = require('zod');
5556
if (action_or_question.data.is_action) {
5657
const user_action = new actionsIndex(argv.input);
5758
const prompt = await user_action.getPrompt();
59+
// declare methods for js code blocks
5860
let additional_context = {
5961
queryLLM:async(question,schema)=>{
6062
return await general.queryLLM(question,schema);
@@ -72,28 +74,48 @@ const { z } = require('zod');
7274
path: currentWorkingDirectory,
7375
template: action.data.file,
7476
extensions: [],
75-
ignore: ["**/node_modules/**","**/*.png","**/*.jpg","**/*.gif"],
77+
ignore: ["**/node_modules/**","**/*.png","**/*.jpg","**/*.gif","**/package-lock.json","**/.env","**/.gitignore","**/LICENSE"],
7678
OPENAI_KEY: process.env.OPENAI_KEY
7779
});
7880
// get the code blocks
7981
const code_helper = new (require('./helpers/codeBlocks'));
8082
const context_prompt = await actioncode.generateContextPrompt(null,true);
83+
//console.log('context_prompt',context_prompt);
84+
additional_context = {...additional_context,...{
85+
absolute_code_path: context_prompt.context.absolutePath,
86+
source_tree: context_prompt.context.sourceTree,
87+
files: context_prompt.context.filesArray,
88+
}
89+
};
8190
const code_blocks = await actioncode.getCodeBlocks();
82-
// check if we have 'pre:' code blocks (must run before the template)
91+
// check if we have ':pre' code blocks (must run before the template)
8392
//console.log('code_blocks for choosen template',code_blocks);
8493
for (const block of code_blocks) {
85-
// if block.lang contains 'pre:'
86-
if (block.lang.startsWith('pre:js')) {
87-
const code_executed = await code_helper.executeNode(additional_context,block.code);
88-
// if code_executed is an object
89-
if (typeof code_executed === 'object') {
90-
console.log('adding context from pre:js code block',code_executed);
91-
additional_context = {...additional_context,...code_executed};
94+
// if block.lang ends with ':pre'
95+
if (block.lang.endsWith(':pre')) {
96+
// if block.lang contains 'js'
97+
if (block.lang.includes('js')) {
98+
const code_executed = await code_helper.executeNode(additional_context,block.code);
99+
// if code_executed is an object
100+
if (typeof code_executed === 'object') {
101+
console.log('adding context from pre:js code block',code_executed);
102+
additional_context = {...additional_context,...code_executed};
103+
}
92104
}
93105
}
94106
}
95107
// query the template
96-
// check if we have none 'pre:' code blocks (must run after the template)
108+
const template_res = await actioncode.request(argv.input, null, {
109+
custom_variables: {
110+
...additional_context
111+
}
112+
});
113+
console.log('template_res',template_res);
114+
// check if we have none ':pre' code blocks (must run after the template)
115+
// add results from template_res.data obj schema to additional_context object
116+
additional_context = {...additional_context, ...{
117+
schema:template_res.data
118+
}};
97119
}
98120
// 2) if the input is a question, run the question to the model with the 'default-template' and return the response
99121

package-lock.json

+7-7
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
"dependencies": {
2424
"@concepto/console": "^1.2.68",
2525
"code-blocks": "^1.1.0",
26-
"code2prompt": "^1.0.6",
26+
"code2prompt": "^1.0.71",
2727
"dotenv": "^16.4.5",
2828
"glob": "^10.3.12",
2929
"prompts": "^2.4.2",

0 commit comments

Comments
 (0)