diff --git a/packages/gpt-runner-core/src/core/get-common-file-tree.ts b/packages/gpt-runner-core/src/core/get-common-file-tree.ts index b9479d7..d68dd33 100644 --- a/packages/gpt-runner-core/src/core/get-common-file-tree.ts +++ b/packages/gpt-runner-core/src/core/get-common-file-tree.ts @@ -180,5 +180,12 @@ ${content} tips += fileTips } + tips += `When you want to create/modify/delete a file or talk about a file, you should always return the full path of the file. + +For example, if I provide you with a file path \`src/component/button.ts\`, you should return \`src/component/button.ts\` instead of \`button.ts\ when you talk about it. + +Return full path is very important !!! +` + return tips } diff --git a/packages/gpt-runner-shared/src/common/types/server.ts b/packages/gpt-runner-shared/src/common/types/server.ts index ff4eef5..2ae32ed 100644 --- a/packages/gpt-runner-shared/src/common/types/server.ts +++ b/packages/gpt-runner-shared/src/common/types/server.ts @@ -31,6 +31,13 @@ export interface GetGptFilesTreeResData { filesInfoTree: GptFileInfoTree } +export interface InitGptFilesReqParams { + rootPath: string + gptFilesNames: string[] +} + +export type InitGptFilesResData = null + export type GetProjectConfigReqParams = null export interface GetProjectConfigResData { gptRunnerVersion: string diff --git a/packages/gpt-runner-shared/src/common/zod/server.zod.ts b/packages/gpt-runner-shared/src/common/zod/server.zod.ts index 784f588..88c0a55 100644 --- a/packages/gpt-runner-shared/src/common/zod/server.zod.ts +++ b/packages/gpt-runner-shared/src/common/zod/server.zod.ts @@ -1,5 +1,5 @@ import { z } from 'zod' -import type { ChatStreamReqParams, GetCommonFilesReqParams, GetGptFilesReqParams, GetUserConfigReqParams, OpenEditorReqParams, StorageClearReqParams, StorageGetItemReqParams, StorageRemoveItemReqParams, StorageSetItemReqParams } from '../types' +import type { ChatStreamReqParams, GetCommonFilesReqParams, GetGptFilesReqParams, GetUserConfigReqParams, InitGptFilesReqParams, OpenEditorReqParams, StorageClearReqParams, StorageGetItemReqParams, StorageRemoveItemReqParams, StorageSetItemReqParams } from '../types' import { SingleChatMessageSchema, SingleFileConfigSchema } from './config.zod' import { ServerStorageNameSchema } from './enum.zod' @@ -16,6 +16,11 @@ export const GetGptFilesReqParamsSchema = z.object({ rootPath: z.string(), }) satisfies z.ZodType +export const InitGptFilesReqParamsSchema = z.object({ + rootPath: z.string(), + gptFilesNames: z.array(z.string()), +}) satisfies z.ZodType + export const GetUserConfigReqParamsSchema = z.object({ rootPath: z.string(), }) satisfies z.ZodType diff --git a/packages/gpt-runner-shared/src/node/helpers/network.ts b/packages/gpt-runner-shared/src/node/helpers/network.ts index a6fa515..4e18c6a 100644 --- a/packages/gpt-runner-shared/src/node/helpers/network.ts +++ b/packages/gpt-runner-shared/src/node/helpers/network.ts @@ -17,22 +17,27 @@ export function openInBrowser(props: OpenInBrowserProps) { } export interface GetPortProps { - defaultPort: number + defaultPort?: number autoFreePort?: boolean } export async function getPort(props: GetPortProps): Promise { const { defaultPort, autoFreePort } = props - if (!autoFreePort) - return defaultPort + if (defaultPort) { + if (!autoFreePort) + return defaultPort - const canUseDefaultPort = await fp.isFreePort(defaultPort) + const canUseDefaultPort = await fp.isFreePort(defaultPort) - if (canUseDefaultPort) - return defaultPort + if (canUseDefaultPort) + return defaultPort + } - const [freePort] = await fp.findFreePorts(1) + const [freePort] = await fp.findFreePorts(1, { + startPort: 3001, + endPort: 9999, + }) return freePort } diff --git a/packages/gpt-runner-vscode/src/register/server.ts b/packages/gpt-runner-vscode/src/register/server.ts index 335a1f9..304deba 100644 --- a/packages/gpt-runner-vscode/src/register/server.ts +++ b/packages/gpt-runner-vscode/src/register/server.ts @@ -29,14 +29,20 @@ export async function registerServer( const { extensionUri } = ext const serverUri = vscode.Uri.joinPath(extensionUri, './dist/web/start-server.cjs') + // always get a random free port const finalPort = await getPort({ - defaultPort: 3003, autoFreePort: true, }) state.serverPort = finalPort - serverProcess = child_process.spawn('node', [serverUri.fsPath, '--port', String(finalPort)], { + serverProcess = child_process.spawn('node', [ + serverUri.fsPath, + '--port', + String(finalPort), + '--client-dist-path', + vscode.Uri.joinPath(extensionUri, './dist/web/browser').fsPath, + ], { env: { ...process.env, NODE_OPTIONS: '--experimental-fetch', diff --git a/packages/gpt-runner-web/client/public/favicon.ico b/packages/gpt-runner-web/client/public/favicon.ico new file mode 100644 index 0000000..8bac211 Binary files /dev/null and b/packages/gpt-runner-web/client/public/favicon.ico differ diff --git a/packages/gpt-runner-web/client/src/components/drag-resize-view/drag-resize-view.styles.ts b/packages/gpt-runner-web/client/src/components/drag-resize-view/drag-resize-view.styles.ts index 0a4118b..fa77659 100644 --- a/packages/gpt-runner-web/client/src/components/drag-resize-view/drag-resize-view.styles.ts +++ b/packages/gpt-runner-web/client/src/components/drag-resize-view/drag-resize-view.styles.ts @@ -1,18 +1,25 @@ import { styled } from 'styled-components' +// actual line weight is 8px, because we need to make it bigger to make it easier to grab +const lineWeight = '8px' + export const DragLine = styled.div<{ $dragLineColor: string; $dragLineActiveColor: string; $dragLineWidth: string }>` position: absolute; - background: ${({ $dragLineColor }) => $dragLineColor}; - /* z-index: 2; */ + /* background: ${({ $dragLineColor }) => $dragLineColor}; */ + border-color: ${({ $dragLineColor }) => $dragLineColor}; + border-style: solid; + border-width: 0; touch-action: none; &:active { - background: ${({ $dragLineActiveColor }) => $dragLineActiveColor}; + /* background: ${({ $dragLineActiveColor }) => $dragLineActiveColor}; */ + border-color: ${({ $dragLineActiveColor }) => $dragLineActiveColor}; } &[data-direction='left'] { cursor: col-resize; - width: ${({ $dragLineWidth }) => $dragLineWidth}; + width: ${lineWeight}; + border-left-width: ${({ $dragLineWidth }) => $dragLineWidth}; left: 0; top: 0; bottom: 0; @@ -20,7 +27,8 @@ export const DragLine = styled.div<{ $dragLineColor: string; $dragLineActiveColo &[data-direction='right'] { cursor: col-resize; - width: ${({ $dragLineWidth }) => $dragLineWidth}; + width: ${lineWeight}; + border-right-width: ${({ $dragLineWidth }) => $dragLineWidth}; right: 0; top: 0; bottom: 0; @@ -28,7 +36,8 @@ export const DragLine = styled.div<{ $dragLineColor: string; $dragLineActiveColo &[data-direction='top'] { cursor: row-resize; - height: ${({ $dragLineWidth }) => $dragLineWidth}; + height: ${lineWeight}; + border-top-width: ${({ $dragLineWidth }) => $dragLineWidth}; top: 0; left: 0; right: 0; @@ -36,7 +45,8 @@ export const DragLine = styled.div<{ $dragLineColor: string; $dragLineActiveColo &[data-direction='bottom'] { cursor: row-resize; - height: ${({ $dragLineWidth }) => $dragLineWidth}; + height: ${lineWeight}; + border-bottom-width: ${({ $dragLineWidth }) => $dragLineWidth}; bottom: 0; left: 0; right: 0; diff --git a/packages/gpt-runner-web/client/src/networks/chatgpt.ts b/packages/gpt-runner-web/client/src/networks/chatgpt.ts index 4dafc39..db2be5c 100644 --- a/packages/gpt-runner-web/client/src/networks/chatgpt.ts +++ b/packages/gpt-runner-web/client/src/networks/chatgpt.ts @@ -42,6 +42,7 @@ export async function fetchChatgptStream( contextFilePaths, rootPath, } satisfies ChatStreamReqParams), + openWhenHidden: true, onmessage: onMessage, onerror: onError, }) diff --git a/packages/gpt-runner-web/client/src/networks/gpt-files.ts b/packages/gpt-runner-web/client/src/networks/gpt-files.ts index 3b4f752..fe8c772 100644 --- a/packages/gpt-runner-web/client/src/networks/gpt-files.ts +++ b/packages/gpt-runner-web/client/src/networks/gpt-files.ts @@ -1,4 +1,5 @@ -import { type BaseResponse, type GetGptFilesReqParams, type GetGptFilesTreeResData, objectToQueryString } from '@nicepkg/gpt-runner-shared/common' +import { objectToQueryString } from '@nicepkg/gpt-runner-shared/common' +import type { BaseResponse, GetGptFilesReqParams, GetGptFilesTreeResData, InitGptFilesReqParams, InitGptFilesResData } from '@nicepkg/gpt-runner-shared/common' import { getGlobalConfig } from '../helpers/global-config' export async function fetchGptFilesTree(params: GetGptFilesReqParams): Promise> { @@ -13,3 +14,17 @@ export async function fetchGptFilesTree(params: GetGptFilesReqParams): Promise> { + const res = await fetch(`${getGlobalConfig().serverBaseUrl}/api/gpt-files/init-gpt-files?${objectToQueryString({ + ...params, + })}`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify(params), + }) + const data = await res.json() + return data +} diff --git a/packages/gpt-runner-web/client/src/pages/chat/components/chat-panel/index.tsx b/packages/gpt-runner-web/client/src/pages/chat/components/chat-panel/index.tsx index 3940659..b469a1b 100644 --- a/packages/gpt-runner-web/client/src/pages/chat/components/chat-panel/index.tsx +++ b/packages/gpt-runner-web/client/src/pages/chat/components/chat-panel/index.tsx @@ -31,9 +31,28 @@ export interface ChatPanelProps { } export const ChatPanel: FC = (props) => { - const { scrollDownRef, chatTreeView, fileTreeView, settingsView, chatId, onChatIdChange } = props - const { createChatAndActive, getGptFileTreeItemFromChatId } = useGlobalStore() - const { chatInstance, updateCurrentChatInstance, generateCurrentChatAnswer, regenerateCurrentLastChatAnswer, stopCurrentGeneratingChatAnswer } = useChatInstance({ chatId }) + const { + scrollDownRef, + chatTreeView, + fileTreeView, + settingsView, + chatId, + onChatIdChange, + } = props + + const { + createChatAndActive, + getGptFileTreeItemFromChatId, + } = useGlobalStore() + + const { + chatInstance, + updateCurrentChatInstance, + generateCurrentChatAnswer, + regenerateCurrentLastChatAnswer, + stopCurrentGeneratingChatAnswer, + } = useChatInstance({ chatId }) + const status = chatInstance?.status ?? ChatMessageStatus.Success const [gptFileTreeItem, setGptFileTreeItem] = useState() const [chatPanelRef, { width: chatPanelWidth }] = useElementSizeRealTime() @@ -334,8 +353,8 @@ export const ChatPanel: FC = (props) => { {/* file tree */} {fileTreeView && { }} + // isPopoverOpen={true} + // onPopoverDisplayChange={() => { }} childrenInMenuWhenOpen={false} clickOutSideToClose={false} menuStyle={{ diff --git a/packages/gpt-runner-web/client/src/pages/chat/components/chat-sidebar/index.tsx b/packages/gpt-runner-web/client/src/pages/chat/components/chat-sidebar/index.tsx index 2101bad..691192e 100644 --- a/packages/gpt-runner-web/client/src/pages/chat/components/chat-sidebar/index.tsx +++ b/packages/gpt-runner-web/client/src/pages/chat/components/chat-sidebar/index.tsx @@ -21,7 +21,17 @@ export type GptTreeItemOtherInfo = GptFileInfoTreeItem export const ChatSidebar: FC = (props) => { const { rootPath } = props - const { activeChatId, sidebarTree, expandChatTreeItem, createChatAndActive, updateSidebarTreeItem, updateActiveChatId, updateUserConfigFromRemote, updateSidebarTreeFromRemote } = useGlobalStore() + const { + activeChatId, + sidebarTree, + expandChatTreeItem, + createChatAndActive, + updateSidebarTreeItem, + updateActiveChatId, + updateUserConfigFromRemote, + updateSidebarTreeFromRemote, + } = useGlobalStore() + const [isLoading, setIsLoading] = useState(false) const { removeChatInstance } = useChatInstance({ diff --git a/packages/gpt-runner-web/client/src/pages/chat/components/file-tree/file-tree.styles.ts b/packages/gpt-runner-web/client/src/pages/chat/components/file-tree/file-tree.styles.ts index 8501def..60ce57a 100644 --- a/packages/gpt-runner-web/client/src/pages/chat/components/file-tree/file-tree.styles.ts +++ b/packages/gpt-runner-web/client/src/pages/chat/components/file-tree/file-tree.styles.ts @@ -10,9 +10,12 @@ export const FileTreeItemRightWrapper = styled.div` export const FileTreeSidebarUnderSearchWrapper = styled.div` font-size: var(--type-ramp-base-font-size); - margin-top: 0.25rem; color: var(--input-foreground); - padding: 0.5rem 0; + margin-bottom: 1rem; + + & ::part(control) { + flex-shrink: 0; + } ` export const FileTreeSidebarHighlight = styled(VSCodeBadge)` diff --git a/packages/gpt-runner-web/client/src/pages/chat/components/file-tree/index.tsx b/packages/gpt-runner-web/client/src/pages/chat/components/file-tree/index.tsx index 6058434..5c72169 100644 --- a/packages/gpt-runner-web/client/src/pages/chat/components/file-tree/index.tsx +++ b/packages/gpt-runner-web/client/src/pages/chat/components/file-tree/index.tsx @@ -363,7 +363,7 @@ const FileTree: FC = (props: FileTreeProps) => { } return - {checkedFilePaths.length} + {checkedFilePaths.length} Files. {formatNumWithK(totalTokenNum)} Tokens. diff --git a/packages/gpt-runner-web/client/src/pages/chat/components/init-gpt-files/index.tsx b/packages/gpt-runner-web/client/src/pages/chat/components/init-gpt-files/index.tsx new file mode 100644 index 0000000..0045992 --- /dev/null +++ b/packages/gpt-runner-web/client/src/pages/chat/components/init-gpt-files/index.tsx @@ -0,0 +1,60 @@ +import { type FC, useState } from 'react' +import { useMutation } from '@tanstack/react-query' +import { type MaybePromise, sleep } from '@nicepkg/gpt-runner-shared/common' +import { IconButton } from '../../../../components/icon-button' +import { initGptFiles } from '../../../../networks/gpt-files' +import { getGlobalConfig } from '../../../../helpers/global-config' +import { LoadingView } from '../../../../components/loading-view' +import { StyledVSCodeTag, Title, Wrapper } from './init-gpt-files.styles' + +export interface InitGptFilesProps { + rootPath: string + onCreated?: () => MaybePromise +} + +export const InitGptFiles: FC = (props) => { + const { rootPath, onCreated } = props + const [isLoading, setIsLoading] = useState(false) + + const { mutate: runInitGptFiles } = useMutation({ + mutationKey: ['initGptFiles', rootPath], + mutationFn: () => initGptFiles({ + rootPath: getGlobalConfig().rootPath, + gptFilesNames: ['copilot'], + }), + }) + + const handleCreate = async () => { + setIsLoading(true) + + try { + await runInitGptFiles() + await sleep(1000) + await onCreated?.() + } + finally { + setIsLoading(false) + } + } + + return + + There is no + <StyledVSCodeTag>xxx.gpt.md</StyledVSCodeTag> + file in the current directory. + + + Do you need to create a + <StyledVSCodeTag>./gpt-presets/copilot.gpt.md</StyledVSCodeTag> + file? + + + {isLoading && } + +} + +InitGptFiles.displayName = 'InitGptFiles' diff --git a/packages/gpt-runner-web/client/src/pages/chat/components/init-gpt-files/init-gpt-files.styles.ts b/packages/gpt-runner-web/client/src/pages/chat/components/init-gpt-files/init-gpt-files.styles.ts new file mode 100644 index 0000000..92ab9a7 --- /dev/null +++ b/packages/gpt-runner-web/client/src/pages/chat/components/init-gpt-files/init-gpt-files.styles.ts @@ -0,0 +1,30 @@ +import { VSCodeTag } from '@vscode/webview-ui-toolkit/react' +import { styled } from 'styled-components' + +export const Wrapper = styled.div` + position: relative; + display: flex; + flex-direction: column; + width: 100%; + height: 100%; + overflow: hidden; + padding: 1rem; + align-items: center; + justify-content: center; +` + +export const Title = styled.div` + display: flex; + align-items: center; + font-size: 1.2rem; + margin-bottom: 1rem; +` + +export const StyledVSCodeTag = styled(VSCodeTag)` + margin: 0 0.5rem; + + &::part(control) { + font-size: 1.1rem; + text-transform: lowercase; + } +` diff --git a/packages/gpt-runner-web/client/src/pages/chat/index.tsx b/packages/gpt-runner-web/client/src/pages/chat/index.tsx index 0f9fabc..7c70cf1 100644 --- a/packages/gpt-runner-web/client/src/pages/chat/index.tsx +++ b/packages/gpt-runner-web/client/src/pages/chat/index.tsx @@ -18,6 +18,7 @@ import { ChatSidebar } from './components/chat-sidebar' import { ChatPanel } from './components/chat-panel' import FileTree from './components/file-tree' import { Settings } from './components/settings' +import { InitGptFiles } from './components/init-gpt-files' enum TabId { Explore = 'explore', @@ -28,7 +29,7 @@ enum TabId { const Chat: FC = () => { const isMobile = useIsMobile() const { width: windowWidth, height: windowHeight } = useWindowSize() - const { activeChatId, updateActiveChatId } = useGlobalStore() + const { activeChatId, sidebarTree, updateActiveChatId, updateSidebarTreeFromRemote } = useGlobalStore() const { chatInstance } = useChatInstance({ chatId: activeChatId }) const [scrollDownRef, scrollDown, getScrollBottom] = useScrollDown() const [tabActiveId, setTabActiveId] = useState(TabId.Explore) @@ -37,6 +38,7 @@ const Chat: FC = () => { queryKey: ['fetchProjectInfo'], queryFn: () => fetchProjectInfo(), }) + const rootPath = getGlobalConfig().rootPath // when active chat id change, change tab active id useEffect(() => { @@ -63,25 +65,25 @@ const Chat: FC = () => { }, [scrollDownRef.current]) const renderSidebar = useCallback(() => { - if (!getGlobalConfig().rootPath) + if (!rootPath) return null return - + }, []) const renderFileTree = useCallback(() => { - if (!getGlobalConfig().rootPath) + if (!rootPath) return null return - + }, []) const renderSettings = useCallback((showSingleFileConfig = false) => { - if (!getGlobalConfig().rootPath) + if (!rootPath) return null return @@ -108,12 +110,19 @@ const Chat: FC = () => { updateActiveChatId, ]) - if (!getGlobalConfig().rootPath) + if (!rootPath) return if (fetchProjectInfoRes?.data?.nodeVersionValidMessage) return + if (!sidebarTree?.length) { + return updateSidebarTreeFromRemote(rootPath)} + > + } + if (isMobile) { const viewStyle: CSSProperties = { height: '100%', diff --git a/packages/gpt-runner-web/client/src/styles/markdown.styles.ts b/packages/gpt-runner-web/client/src/styles/markdown.styles.ts index e9f1700..e4502e8 100644 --- a/packages/gpt-runner-web/client/src/styles/markdown.styles.ts +++ b/packages/gpt-runner-web/client/src/styles/markdown.styles.ts @@ -291,6 +291,7 @@ export const MarkdownStyle = createGlobalStyle` padding: 0 0.25rem; white-space: nowrap; background: var(--button-primary-background); + color: var(--button-primary-foreground); border-radius: 0.25rem; margin: 0 0.25rem; } diff --git a/packages/gpt-runner-web/server/index.ts b/packages/gpt-runner-web/server/index.ts index 8f57390..c9fd73b 100644 --- a/packages/gpt-runner-web/server/index.ts +++ b/packages/gpt-runner-web/server/index.ts @@ -13,15 +13,16 @@ const dirname = PathUtils.getCurrentDirName(import.meta.url, () => __dirname) const resolvePath = (...paths: string[]) => path.resolve(dirname, ...paths) -export const clientDistPath = resolvePath('../dist/browser') +export const DEFAULT_CLIENT_DIST_PATH = resolvePath('../dist/browser') export interface StartServerProps { port?: number autoFreePort?: boolean + clientDistPath?: string } export async function startServer(props: StartServerProps): Promise { - const { port = 3003, autoFreePort } = props + const { port = 3003, autoFreePort, clientDistPath = DEFAULT_CLIENT_DIST_PATH } = props const finalPort = await getPort({ defaultPort: port, diff --git a/packages/gpt-runner-web/server/src/controllers/gpt-files.controller.ts b/packages/gpt-runner-web/server/src/controllers/gpt-files.controller.ts index 108b828..d4086d2 100644 --- a/packages/gpt-runner-web/server/src/controllers/gpt-files.controller.ts +++ b/packages/gpt-runner-web/server/src/controllers/gpt-files.controller.ts @@ -1,7 +1,8 @@ -import { getGptFilesInfo, loadUserConfig } from '@nicepkg/gpt-runner-core' +import type { GptInitFileName } from '@nicepkg/gpt-runner-core' +import { getGptFilesInfo, initGptFiles, loadUserConfig } from '@nicepkg/gpt-runner-core' import { PathUtils, sendFailResponse, sendSuccessResponse, verifyParamsByZod } from '@nicepkg/gpt-runner-shared/node' -import type { GetGptFilesReqParams, GetGptFilesTreeResData } from '@nicepkg/gpt-runner-shared/common' -import { Debug, GetGptFilesReqParamsSchema, resetUserConfigUnsafeKey } from '@nicepkg/gpt-runner-shared/common' +import type { GetGptFilesReqParams, GetGptFilesTreeResData, InitGptFilesReqParams, InitGptFilesResData } from '@nicepkg/gpt-runner-shared/common' +import { Debug, GetGptFilesReqParamsSchema, InitGptFilesReqParamsSchema, resetUserConfigUnsafeKey } from '@nicepkg/gpt-runner-shared/common' import type { ControllerConfig } from '../types' const debug = new Debug('gpt-files.controller') @@ -45,5 +46,34 @@ export const gptFilesControllers: ControllerConfig = { }) }, }, + { + url: '/init-gpt-files', + method: 'post', + handler: async (req, res) => { + const body = req.body as InitGptFilesReqParams + + verifyParamsByZod(body, InitGptFilesReqParamsSchema) + + const { rootPath, gptFilesNames } = body + const finalPath = PathUtils.resolve(rootPath) + + if (!PathUtils.isDirectory(finalPath)) { + sendFailResponse(res, { + message: 'rootPath is not a valid directory', + }) + + return + } + + await initGptFiles({ + rootPath: finalPath, + gptFilesNames: gptFilesNames as GptInitFileName[], + }) + + sendSuccessResponse(res, { + data: null satisfies InitGptFilesResData, + }) + }, + }, ], } diff --git a/packages/gpt-runner-web/server/start-server.ts b/packages/gpt-runner-web/server/start-server.ts index d423ee6..9ded9be 100644 --- a/packages/gpt-runner-web/server/start-server.ts +++ b/packages/gpt-runner-web/server/start-server.ts @@ -1,18 +1,19 @@ import { program } from 'commander' import pkg from '../package.json' -import type { StartServerProps } from './index' import { startServer } from './index' program.option('-p, --port ', 'Port number', parseInt) program.option('--auto-free-port', 'Automatically find a free port') program.option('--auto-open', 'Automatically open the browser') +program.option('--client-dist-path ', 'Client dist path') program.option('-v, --version', 'Version number') program.parse(process.argv) interface ProgramOpts { - port?: StartServerProps['port'] + port?: number autoFreePort?: boolean autoOpen?: boolean + clientDistPath?: string version?: boolean } diff --git a/playground/scripts/gpt/frontend-eng.gpt.md b/playground/scripts/gpt/frontend-eng.gpt.md index 8de849b..55619a9 100644 --- a/playground/scripts/gpt/frontend-eng.gpt.md +++ b/playground/scripts/gpt/frontend-eng.gpt.md @@ -11,10 +11,9 @@ #01 你充当前端开发专家。 #02 user 将提供一些关于前端代码问题的具体信息,而你的工作就是想出为 user 解决问题的策略。这可能包括建议代码、代码逻辑思路策略。 -#03 你如果想要增删改文件,应该需要告诉 user 文件的完整路径,以及你想要增删改的内容。 -#04 你的代码应该遵循 SOLID and KISS and DRY principles -#05 你应该一步步思考完再作答 -#06 你应该非常细心,不要遗漏 user 提问的任何信息或需求,回答要完整 +#03 你的代码应该遵循 SOLID and KISS and DRY principles +#04 你应该一步步思考完再作答 +#05 你应该非常细心,不要遗漏 user 提问的任何信息或需求,回答要完整 # User Prompt