Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
Create Llama
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Iterations
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Locked files
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package Registry
Container Registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Service Desk
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Code review analytics
Issue analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
mirrored_repos
MachineLearning
run-llama
Create Llama
Commits
6f48831d
Commit
6f48831d
authored
1 year ago
by
Marcus Schiesser
Browse files
Options
Downloads
Patches
Plain Diff
refactor: factor out questions and use strong-typing for question args
parent
58a852c0
No related branches found
Branches containing commit
No related tags found
Tags containing commit
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
index.ts
+5
-268
5 additions, 268 deletions
index.ts
questions.ts
+277
-0
277 additions, 0 deletions
questions.ts
with
282 additions
and
268 deletions
index.ts
+
5
−
268
View file @
6f48831d
#!/usr/bin/env node
/* eslint-disable import/no-extraneous-dependencies */
import
ciInfo
from
"
ci-info
"
;
import
Commander
from
"
commander
"
;
import
Conf
from
"
conf
"
;
import
fs
from
"
fs
"
;
import
path
from
"
path
"
;
import
{
blue
,
bold
,
cyan
,
green
,
red
,
yellow
}
from
"
picocolors
"
;
import
{
bold
,
cyan
,
green
,
red
,
yellow
}
from
"
picocolors
"
;
import
prompts
from
"
prompts
"
;
import
checkForUpdate
from
"
update-check
"
;
import
{
InstallAppArgs
,
createApp
}
from
"
./create-app
"
;
import
{
COMMUNITY_OWNER
,
COMMUNITY_REPO
}
from
"
./helpers/constant
"
;
import
{
createApp
}
from
"
./create-app
"
;
import
{
getPkgManager
}
from
"
./helpers/get-pkg-manager
"
;
import
{
isFolderEmpty
}
from
"
./helpers/is-folder-empty
"
;
import
{
getRepoRootFolders
}
from
"
./helpers/repo
"
;
import
{
validateNpmName
}
from
"
./helpers/validate-pkg
"
;
import
packageJson
from
"
./package.json
"
;
import
{
QuestionArgs
,
askQuestions
,
onPromptState
}
from
"
./questions
"
;
let
projectPath
:
string
=
""
;
...
...
@@ -23,16 +21,6 @@ const handleSigTerm = () => process.exit(0);
process
.
on
(
"
SIGINT
"
,
handleSigTerm
);
process
.
on
(
"
SIGTERM
"
,
handleSigTerm
);
const
onPromptState
=
(
state
:
any
)
=>
{
if
(
state
.
aborted
)
{
// If we don't re-enable the terminal cursor before exiting
// the program, the cursor will remain hidden
process
.
stdout
.
write
(
"
\
x1B[?25h
"
);
process
.
stdout
.
write
(
"
\n
"
);
process
.
exit
(
1
);
}
};
const
program
=
new
Commander
.
Command
(
packageJson
.
name
)
.
version
(
packageJson
.
version
)
.
arguments
(
"
<project-directory>
"
)
...
...
@@ -157,259 +145,8 @@ async function run(): Promise<void> {
process
.
exit
(
1
);
}
// TODO: use Args also for program
type
Args
=
Omit
<
InstallAppArgs
,
"
appPath
"
|
"
packageManager
"
>
;
const
preferences
=
(
conf
.
get
(
"
preferences
"
)
||
{})
as
Args
;
const
defaults
:
Args
=
{
template
:
"
streaming
"
,
framework
:
"
nextjs
"
,
engine
:
"
simple
"
,
ui
:
"
html
"
,
eslint
:
true
,
frontend
:
false
,
openAIKey
:
""
,
model
:
"
gpt-3.5-turbo
"
,
communityProjectPath
:
""
,
};
const
getPrefOrDefault
=
(
field
:
keyof
Args
)
=>
preferences
[
field
]
??
defaults
[
field
];
const
handlers
=
{
onCancel
:
()
=>
{
console
.
error
(
"
Exiting.
"
);
process
.
exit
(
1
);
},
};
if
(
!
program
.
template
)
{
if
(
ciInfo
.
isCI
)
{
program
.
template
=
getPrefOrDefault
(
"
template
"
);
}
else
{
const
{
template
}
=
await
prompts
(
{
type
:
"
select
"
,
name
:
"
template
"
,
message
:
"
Which template would you like to use?
"
,
choices
:
[
{
title
:
"
Chat without streaming
"
,
value
:
"
simple
"
},
{
title
:
"
Chat with streaming
"
,
value
:
"
streaming
"
},
{
title
:
"
Community templates
"
,
value
:
"
community
"
},
],
initial
:
1
,
},
handlers
,
);
program
.
template
=
template
;
preferences
.
template
=
template
;
}
}
if
(
program
.
template
===
"
community
"
)
{
const
rootFolderNames
=
await
getRepoRootFolders
(
COMMUNITY_OWNER
,
COMMUNITY_REPO
,
);
const
{
communityProjectPath
}
=
await
prompts
(
{
type
:
"
select
"
,
name
:
"
communityProjectPath
"
,
message
:
"
Select community templates?
"
,
choices
:
rootFolderNames
.
map
((
name
)
=>
({
title
:
name
,
value
:
name
,
})),
initial
:
0
,
},
{
onCancel
:
()
=>
{
console
.
error
(
"
Exiting.
"
);
process
.
exit
(
1
);
},
},
);
program
.
communityProjectPath
=
communityProjectPath
;
preferences
.
communityProjectPath
=
communityProjectPath
;
}
else
{
if
(
!
program
.
framework
)
{
if
(
ciInfo
.
isCI
)
{
program
.
framework
=
getPrefOrDefault
(
"
framework
"
);
}
else
{
const
allChoices
=
[
{
title
:
"
NextJS
"
,
value
:
"
nextjs
"
},
{
title
:
"
Express
"
,
value
:
"
express
"
},
{
title
:
"
FastAPI (Python)
"
,
value
:
"
fastapi
"
},
];
const
choiceIndexes
=
program
.
template
===
"
simple
"
?
[
1
,
2
]
:
[
0
,
1
,
2
];
const
choices
=
allChoices
.
filter
((
_
,
i
)
=>
choiceIndexes
.
includes
(
i
));
const
{
framework
}
=
await
prompts
(
{
type
:
"
select
"
,
name
:
"
framework
"
,
message
:
"
Which framework would you like to use?
"
,
choices
,
initial
:
0
,
},
handlers
,
);
program
.
framework
=
framework
;
preferences
.
framework
=
framework
;
}
}
if
(
program
.
framework
===
"
nextjs
"
)
{
program
.
template
=
"
streaming
"
;
}
if
(
program
.
framework
===
"
express
"
||
program
.
framework
===
"
fastapi
"
)
{
// if a backend-only framework is selected, ask whether we should create a frontend
if
(
!
program
.
frontend
)
{
if
(
ciInfo
.
isCI
)
{
program
.
frontend
=
getPrefOrDefault
(
"
frontend
"
);
}
else
{
const
styledNextJS
=
blue
(
"
NextJS
"
);
const
styledBackend
=
green
(
program
.
framework
===
"
express
"
?
"
Express
"
:
program
.
framework
===
"
fastapi
"
?
"
FastAPI (Python)
"
:
""
,
);
const
{
frontend
}
=
await
prompts
({
onState
:
onPromptState
,
type
:
"
toggle
"
,
name
:
"
frontend
"
,
message
:
`Would you like to generate a
${
styledNextJS
}
frontend for your
${
styledBackend
}
backend?`
,
initial
:
getPrefOrDefault
(
"
frontend
"
),
active
:
"
Yes
"
,
inactive
:
"
No
"
,
});
program
.
frontend
=
Boolean
(
frontend
);
preferences
.
frontend
=
Boolean
(
frontend
);
}
}
}
if
(
program
.
framework
===
"
nextjs
"
||
program
.
frontend
)
{
if
(
!
program
.
ui
)
{
if
(
ciInfo
.
isCI
)
{
program
.
ui
=
getPrefOrDefault
(
"
ui
"
);
}
else
{
const
{
ui
}
=
await
prompts
(
{
type
:
"
select
"
,
name
:
"
ui
"
,
message
:
"
Which UI would you like to use?
"
,
choices
:
[
{
title
:
"
Just HTML
"
,
value
:
"
html
"
},
{
title
:
"
Shadcn
"
,
value
:
"
shadcn
"
},
],
initial
:
0
,
},
handlers
,
);
program
.
ui
=
ui
;
preferences
.
ui
=
ui
;
}
}
}
if
(
program
.
framework
===
"
nextjs
"
)
{
if
(
!
program
.
model
)
{
if
(
ciInfo
.
isCI
)
{
program
.
model
=
getPrefOrDefault
(
"
model
"
);
}
else
{
const
{
model
}
=
await
prompts
(
{
type
:
"
select
"
,
name
:
"
model
"
,
message
:
"
Which model would you like to use?
"
,
choices
:
[
{
title
:
"
gpt-3.5-turbo
"
,
value
:
"
gpt-3.5-turbo
"
},
{
title
:
"
gpt-4
"
,
value
:
"
gpt-4
"
},
{
title
:
"
gpt-4-1106-preview
"
,
value
:
"
gpt-4-1106-preview
"
},
{
title
:
"
gpt-4-vision-preview
"
,
value
:
"
gpt-4-vision-preview
"
,
},
],
initial
:
0
,
},
handlers
,
);
program
.
model
=
model
;
preferences
.
model
=
model
;
}
}
}
if
(
program
.
framework
===
"
express
"
||
program
.
framework
===
"
nextjs
"
)
{
if
(
!
program
.
engine
)
{
if
(
ciInfo
.
isCI
)
{
program
.
engine
=
getPrefOrDefault
(
"
engine
"
);
}
else
{
const
{
engine
}
=
await
prompts
(
{
type
:
"
select
"
,
name
:
"
engine
"
,
message
:
"
Which chat engine would you like to use?
"
,
choices
:
[
{
title
:
"
ContextChatEngine
"
,
value
:
"
context
"
},
{
title
:
"
SimpleChatEngine (no data, just chat)
"
,
value
:
"
simple
"
,
},
],
initial
:
0
,
},
handlers
,
);
program
.
engine
=
engine
;
preferences
.
engine
=
engine
;
}
}
}
if
(
!
program
.
openAIKey
)
{
const
{
key
}
=
await
prompts
(
{
type
:
"
text
"
,
name
:
"
key
"
,
message
:
"
Please provide your OpenAI API key (leave blank to skip):
"
,
},
handlers
,
);
program
.
openAIKey
=
key
;
preferences
.
openAIKey
=
key
;
}
if
(
program
.
framework
!==
"
fastapi
"
&&
!
process
.
argv
.
includes
(
"
--eslint
"
)
&&
!
process
.
argv
.
includes
(
"
--no-eslint
"
)
)
{
if
(
ciInfo
.
isCI
)
{
program
.
eslint
=
getPrefOrDefault
(
"
eslint
"
);
}
else
{
const
styledEslint
=
blue
(
"
ESLint
"
);
const
{
eslint
}
=
await
prompts
({
onState
:
onPromptState
,
type
:
"
toggle
"
,
name
:
"
eslint
"
,
message
:
`Would you like to use
${
styledEslint
}
?`
,
initial
:
getPrefOrDefault
(
"
eslint
"
),
active
:
"
Yes
"
,
inactive
:
"
No
"
,
});
program
.
eslint
=
Boolean
(
eslint
);
preferences
.
eslint
=
Boolean
(
eslint
);
}
}
}
const
preferences
=
(
conf
.
get
(
"
preferences
"
)
||
{})
as
QuestionArgs
;
await
askQuestions
(
program
as
unknown
as
QuestionArgs
,
preferences
);
await
createApp
({
template
:
program
.
template
,
...
...
This diff is collapsed.
Click to expand it.
questions.ts
0 → 100644
+
277
−
0
View file @
6f48831d
import
ciInfo
from
"
ci-info
"
;
import
{
blue
,
green
}
from
"
picocolors
"
;
import
prompts
from
"
prompts
"
;
import
{
InstallAppArgs
}
from
"
./create-app
"
;
import
{
COMMUNITY_OWNER
,
COMMUNITY_REPO
}
from
"
./helpers/constant
"
;
import
{
getRepoRootFolders
}
from
"
./helpers/repo
"
;
export
type
QuestionArgs
=
Omit
<
InstallAppArgs
,
"
appPath
"
|
"
packageManager
"
>
;
const
defaults
:
QuestionArgs
=
{
template
:
"
streaming
"
,
framework
:
"
nextjs
"
,
engine
:
"
simple
"
,
ui
:
"
html
"
,
eslint
:
true
,
frontend
:
false
,
openAIKey
:
""
,
model
:
"
gpt-3.5-turbo
"
,
communityProjectPath
:
""
,
};
const
handlers
=
{
onCancel
:
()
=>
{
console
.
error
(
"
Exiting.
"
);
process
.
exit
(
1
);
},
};
export
const
onPromptState
=
(
state
:
any
)
=>
{
if
(
state
.
aborted
)
{
// If we don't re-enable the terminal cursor before exiting
// the program, the cursor will remain hidden
process
.
stdout
.
write
(
"
\
x1B[?25h
"
);
process
.
stdout
.
write
(
"
\n
"
);
process
.
exit
(
1
);
}
};
export
const
askQuestions
=
async
(
program
:
QuestionArgs
,
preferences
:
QuestionArgs
,
)
=>
{
const
getPrefOrDefault
=
<
K
extends
keyof
QuestionArgs
>
(
field
:
K
,
):
QuestionArgs
[
K
]
=>
preferences
[
field
]
??
defaults
[
field
];
if
(
!
program
.
template
)
{
if
(
ciInfo
.
isCI
)
{
program
.
template
=
getPrefOrDefault
(
"
template
"
);
}
else
{
const
styledRepo
=
blue
(
`https://github.com/
${
COMMUNITY_OWNER
}
/
${
COMMUNITY_REPO
}
`
,
);
const
{
template
}
=
await
prompts
(
{
type
:
"
select
"
,
name
:
"
template
"
,
message
:
"
Which template would you like to use?
"
,
choices
:
[
{
title
:
"
Chat without streaming
"
,
value
:
"
simple
"
},
{
title
:
"
Chat with streaming
"
,
value
:
"
streaming
"
},
{
title
:
`Community template from
${
styledRepo
}
`
,
value
:
"
community
"
,
},
],
initial
:
1
,
},
handlers
,
);
program
.
template
=
template
;
preferences
.
template
=
template
;
}
}
if
(
program
.
template
===
"
community
"
)
{
const
rootFolderNames
=
await
getRepoRootFolders
(
COMMUNITY_OWNER
,
COMMUNITY_REPO
,
);
const
{
communityProjectPath
}
=
await
prompts
(
{
type
:
"
select
"
,
name
:
"
communityProjectPath
"
,
message
:
"
Select community template
"
,
choices
:
rootFolderNames
.
map
((
name
)
=>
({
title
:
name
,
value
:
name
,
})),
initial
:
0
,
},
{
onCancel
:
()
=>
{
console
.
error
(
"
Exiting.
"
);
process
.
exit
(
1
);
},
},
);
program
.
communityProjectPath
=
communityProjectPath
;
preferences
.
communityProjectPath
=
communityProjectPath
;
return
;
// early return - no further questions needed for community projects
}
if
(
!
program
.
framework
)
{
if
(
ciInfo
.
isCI
)
{
program
.
framework
=
getPrefOrDefault
(
"
framework
"
);
}
else
{
const
choices
=
[
{
title
:
"
Express
"
,
value
:
"
express
"
},
{
title
:
"
FastAPI (Python)
"
,
value
:
"
fastapi
"
},
];
if
(
program
.
template
===
"
streaming
"
)
{
// allow NextJS only for streaming template
choices
.
unshift
({
title
:
"
NextJS
"
,
value
:
"
nextjs
"
});
}
const
{
framework
}
=
await
prompts
(
{
type
:
"
select
"
,
name
:
"
framework
"
,
message
:
"
Which framework would you like to use?
"
,
choices
,
initial
:
0
,
},
handlers
,
);
program
.
framework
=
framework
;
preferences
.
framework
=
framework
;
}
}
if
(
program
.
framework
===
"
express
"
||
program
.
framework
===
"
fastapi
"
)
{
// if a backend-only framework is selected, ask whether we should create a frontend
if
(
!
program
.
frontend
)
{
if
(
ciInfo
.
isCI
)
{
program
.
frontend
=
getPrefOrDefault
(
"
frontend
"
);
}
else
{
const
styledNextJS
=
blue
(
"
NextJS
"
);
const
styledBackend
=
green
(
program
.
framework
===
"
express
"
?
"
Express
"
:
program
.
framework
===
"
fastapi
"
?
"
FastAPI (Python)
"
:
""
,
);
const
{
frontend
}
=
await
prompts
({
onState
:
onPromptState
,
type
:
"
toggle
"
,
name
:
"
frontend
"
,
message
:
`Would you like to generate a
${
styledNextJS
}
frontend for your
${
styledBackend
}
backend?`
,
initial
:
getPrefOrDefault
(
"
frontend
"
),
active
:
"
Yes
"
,
inactive
:
"
No
"
,
});
program
.
frontend
=
Boolean
(
frontend
);
preferences
.
frontend
=
Boolean
(
frontend
);
}
}
}
if
(
program
.
framework
===
"
nextjs
"
||
program
.
frontend
)
{
if
(
!
program
.
ui
)
{
if
(
ciInfo
.
isCI
)
{
program
.
ui
=
getPrefOrDefault
(
"
ui
"
);
}
else
{
const
{
ui
}
=
await
prompts
(
{
type
:
"
select
"
,
name
:
"
ui
"
,
message
:
"
Which UI would you like to use?
"
,
choices
:
[
{
title
:
"
Just HTML
"
,
value
:
"
html
"
},
{
title
:
"
Shadcn
"
,
value
:
"
shadcn
"
},
],
initial
:
0
,
},
handlers
,
);
program
.
ui
=
ui
;
preferences
.
ui
=
ui
;
}
}
}
if
(
program
.
framework
===
"
nextjs
"
)
{
if
(
!
program
.
model
)
{
if
(
ciInfo
.
isCI
)
{
program
.
model
=
getPrefOrDefault
(
"
model
"
);
}
else
{
const
{
model
}
=
await
prompts
(
{
type
:
"
select
"
,
name
:
"
model
"
,
message
:
"
Which model would you like to use?
"
,
choices
:
[
{
title
:
"
gpt-3.5-turbo
"
,
value
:
"
gpt-3.5-turbo
"
},
{
title
:
"
gpt-4
"
,
value
:
"
gpt-4
"
},
{
title
:
"
gpt-4-1106-preview
"
,
value
:
"
gpt-4-1106-preview
"
},
{
title
:
"
gpt-4-vision-preview
"
,
value
:
"
gpt-4-vision-preview
"
,
},
],
initial
:
0
,
},
handlers
,
);
program
.
model
=
model
;
preferences
.
model
=
model
;
}
}
}
if
(
program
.
framework
===
"
express
"
||
program
.
framework
===
"
nextjs
"
)
{
if
(
!
program
.
engine
)
{
if
(
ciInfo
.
isCI
)
{
program
.
engine
=
getPrefOrDefault
(
"
engine
"
);
}
else
{
const
{
engine
}
=
await
prompts
(
{
type
:
"
select
"
,
name
:
"
engine
"
,
message
:
"
Which chat engine would you like to use?
"
,
choices
:
[
{
title
:
"
ContextChatEngine
"
,
value
:
"
context
"
},
{
title
:
"
SimpleChatEngine (no data, just chat)
"
,
value
:
"
simple
"
,
},
],
initial
:
0
,
},
handlers
,
);
program
.
engine
=
engine
;
preferences
.
engine
=
engine
;
}
}
}
if
(
!
program
.
openAIKey
)
{
const
{
key
}
=
await
prompts
(
{
type
:
"
text
"
,
name
:
"
key
"
,
message
:
"
Please provide your OpenAI API key (leave blank to skip):
"
,
},
handlers
,
);
program
.
openAIKey
=
key
;
preferences
.
openAIKey
=
key
;
}
if
(
program
.
framework
!==
"
fastapi
"
&&
!
process
.
argv
.
includes
(
"
--eslint
"
)
&&
!
process
.
argv
.
includes
(
"
--no-eslint
"
)
)
{
if
(
ciInfo
.
isCI
)
{
program
.
eslint
=
getPrefOrDefault
(
"
eslint
"
);
}
else
{
const
styledEslint
=
blue
(
"
ESLint
"
);
const
{
eslint
}
=
await
prompts
({
onState
:
onPromptState
,
type
:
"
toggle
"
,
name
:
"
eslint
"
,
message
:
`Would you like to use
${
styledEslint
}
?`
,
initial
:
getPrefOrDefault
(
"
eslint
"
),
active
:
"
Yes
"
,
inactive
:
"
No
"
,
});
program
.
eslint
=
Boolean
(
eslint
);
preferences
.
eslint
=
Boolean
(
eslint
);
}
}
};
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment