Skip to content

Commit cc90b3e

Browse files
authored
Merge pull request #32 from njhale/fix/dir-init
fix: ensure app dirs exist
2 parents de7395c + 69c4dab commit cc90b3e

File tree

10 files changed

+57
-84
lines changed

10 files changed

+57
-84
lines changed

.gitignore

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,6 @@ yarn-error.log*
3737
*.tsbuildinfo
3838
next-env.d.ts
3939

40-
# app output
41-
gptscripts
42-
43-
# ignore root level threads directory
44-
/threads
40+
# app output directories
41+
/gptscripts
42+
/threads

actions/scripts/fetch.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
"use server"
2-
import { Tool, GPTScript, Block } from '@gptscript-ai/gptscript';
2+
import { Tool, Block } from '@gptscript-ai/gptscript';
33
import { SCRIPTS_PATH, gpt } from '@/config/env';
44
import fs from 'fs/promises';
55

actions/scripts/new.tsx

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,17 @@ import { SCRIPTS_PATH } from '@/config/env';
44
import fs from 'fs/promises';
55

66
export async function newFile(name: string, instructions: string, fileName: string) {
7-
try {
8-
const files = await fs.readdir(SCRIPTS_PATH());
9-
const gptFiles = files.filter(file => file.endsWith('.gpt'));
7+
const scriptsPath = SCRIPTS_PATH()
8+
await fs.mkdir(scriptsPath, {recursive: true})
109

11-
if(gptFiles.includes(fileName)) throw new Error('file already exists');
12-
if (!fileName.endsWith('.gpt')) {
13-
throw new Error('file cannot be empty and must end with .gpt');
14-
}
15-
16-
await fs.writeFile(`${SCRIPTS_PATH()}/${fileName}`, `---\nName: ${name}\nChat: true\n\n${instructions}\n\n`);
17-
return fileName.replace('.gpt', '')
18-
} catch (e) {
19-
throw e;
10+
const files = await fs.readdir(scriptsPath);
11+
const gptFiles = files.filter(file => file.endsWith('.gpt'));
12+
13+
if (gptFiles.includes(fileName)) throw new Error('file already exists');
14+
if (!fileName.endsWith('.gpt')) {
15+
throw new Error('file cannot be empty and must end with .gpt');
2016
}
17+
18+
await fs.writeFile(`${scriptsPath}/${fileName}`, `---\nName: ${name}\nChat: true\n\n${instructions}\n\n`);
19+
return fileName.replace('.gpt', '')
2120
}

actions/threads.tsx

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ export async function createThread(script: string, firstMessage?: string): Promi
106106

107107
if (firstMessage) {
108108
const generatedThreadName = await generateThreadName(firstMessage)
109-
renameThread(id, generatedThreadName);
109+
await renameThread(id, generatedThreadName);
110110
}
111111

112112
return {
@@ -129,15 +129,3 @@ export async function renameThread(id: string, name: string) {
129129
threadMeta.name = name;
130130
await fs.writeFile(path.join(threadPath, META_FILE), JSON.stringify(threadMeta));
131131
}
132-
133-
export async function updateThread(id: string, thread: Thread) {
134-
const threadsDir = THREADS_DIR();
135-
const threadPath = path.join(threadsDir,id);
136-
137-
if (thread.state) await fs.writeFile(path.join(threadPath, STATE_FILE), thread.state);
138-
if (thread.meta) {
139-
const existingMeta = await fs.readFile(path.join(threadPath, META_FILE), "utf-8");
140-
const mergedMeta = { ...JSON.parse(existingMeta), ...thread.meta };
141-
await fs.writeFile(path.join(threadPath, META_FILE), JSON.stringify(mergedMeta));
142-
}
143-
}

actions/upload.tsx

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,23 +7,17 @@ import { WORKSPACE_DIR } from '@/config/env';
77
import { Dirent } from 'fs';
88

99
export async function uploadFile(formData: FormData) {
10+
const workspaceDir = WORKSPACE_DIR()
11+
await fs.mkdir(workspaceDir, { recursive: true })
12+
1013
const file = formData.get("file") as File;
1114
const arrayBuffer = await file.arrayBuffer();
1215
const buffer = new Uint8Array(arrayBuffer);
13-
await fs.writeFile(path.join(WORKSPACE_DIR(),file.name), buffer);
16+
await fs.writeFile(path.join(workspaceDir, file.name), buffer);
17+
1418
revalidatePath("/");
1519
}
1620

17-
export async function openFile(path: string): Promise<string> {
18-
try {
19-
const buffer = await fs.readFile(path);
20-
const blob = new Blob([buffer]);
21-
return URL.createObjectURL(blob);
22-
} catch (error) {
23-
console.error("Error opening file:", error);
24-
throw error;
25-
}
26-
}
2721
export async function deleteFile(path: string) {
2822
try {
2923
await fs.unlink(path);
@@ -34,11 +28,15 @@ export async function deleteFile(path: string) {
3428
}
3529

3630
export async function lsWorkspaceFiles(): Promise<string> {
31+
let files: Dirent[] = []
3732
try {
3833
const dirents = await fs.readdir(WORKSPACE_DIR(), { withFileTypes: true });
39-
const filesOnly = dirents.filter((dirent: Dirent) => !dirent.isDirectory());
40-
return JSON.stringify(filesOnly);
34+
files = dirents.filter((dirent: Dirent) => !dirent.isDirectory());
4135
} catch (e) {
42-
throw e;
36+
if ((e as NodeJS.ErrnoException).code !== 'ENOENT') {
37+
throw e;
38+
}
4339
}
44-
};
40+
41+
return JSON.stringify(files);
42+
}

app/api/file/[name]/[tool]/route.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
export const dynamic = 'force-dynamic' // defaults to autover'
2+
import {NextResponse} from "next/server";
23
import {type Block, Tool} from '@gptscript-ai/gptscript'
34
import { Positions } from '../route';
45
import { promises as fs } from 'fs';
@@ -17,13 +18,13 @@ export async function PUT(
1718
const updatedScript = updateScript(script, tool, (await req.json()) as Tool);
1819

1920
await fs.writeFile(path.join(SCRIPTS_PATH(),`${name}.gpt`), await gpt().stringify(updatedScript));
20-
return Response.json(await gpt().parse(path.join(SCRIPTS_PATH(),`${name}.gpt`)));
21+
return NextResponse.json(await gpt().parse(path.join(SCRIPTS_PATH(),`${name}.gpt`)));
2122
} catch (e) {
2223
if (`${e}`.includes('no such file')){
23-
return Response.json({ error: '.gpt file not found' }, { status: 404 });
24+
return NextResponse.json({ error: '.gpt file not found' }, { status: 404 });
2425
}
2526
console.error(e)
26-
return Response.json({ error: e }, {status: 500});
27+
return NextResponse.json({ error: e }, {status: 500});
2728
}
2829
}
2930

app/api/file/[name]/route.ts

Lines changed: 10 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
export const dynamic = 'force-dynamic' // defaults to auto
2-
import { NextRequest } from 'next/server'
2+
import { NextRequest, NextResponse } from 'next/server'
33
import { type Block, Text } from '@gptscript-ai/gptscript'
44
import { promises as fs } from 'fs';
55
import path from 'path';
@@ -17,26 +17,12 @@ export async function DELETE(
1717
try {
1818
const { name } = params as any;
1919
await fs.unlink(path.join(`${SCRIPTS_PATH()}/${name}.gpt`));
20-
return Response.json({ success: true });
20+
return NextResponse.json({ success: true });
2121
} catch (e) {
22-
return Response.json({ error: e }, { status: 500 });
22+
return NextResponse.json({ error: e }, { status: 500 });
2323
}
2424
}
2525

26-
// export async function PUT(req: Request) {
27-
// try {
28-
// const scriptsPath = process.env.SCRIPTS_PATH() || 'gptscripts';
29-
// const { name } = req.params as any;
30-
// const content = await req.text();
31-
32-
// await fs.rename(`${scriptsPath}/${name}`, `${scriptsPath}/${name}.bak`);
33-
// await fs.writeFile(`${scriptsPath}/${name}`, content);
34-
// return Response.json({ success: true });
35-
// } catch (e) {
36-
// return Response.json({ error: e }, { status: 500 });
37-
// }
38-
// }
39-
4026
export async function GET(
4127
req: NextRequest,
4228
{ params }: { params: { slug: string } }
@@ -46,14 +32,14 @@ export async function GET(
4632
const script = await gpt().parse(path.join(SCRIPTS_PATH(),`${name}.gpt`));
4733
if (req.nextUrl.searchParams.get('nodeify') === 'true') {
4834
const { nodes, edges } = await nodeify(script);
49-
return Response.json({ nodes: nodes, edges: edges });
35+
return NextResponse.json({ nodes: nodes, edges: edges });
5036
}
51-
return Response.json(script);
37+
return NextResponse.json(script);
5238
} catch (e) {
5339
if (`${e}`.includes('no such file')){
54-
return Response.json({ error: '.gpt file not found' }, { status: 404 });
40+
return NextResponse.json({ error: '.gpt file not found' }, { status: 404 });
5541
}
56-
return Response.json({ error: e }, {status: 500});
42+
return NextResponse.json({ error: e }, {status: 500});
5743
}
5844
}
5945

@@ -67,12 +53,12 @@ export async function PUT(
6753
const script = denodeify(nodes);
6854

6955
await fs.writeFile(path.join(SCRIPTS_PATH(),`${name}.gpt`), await gpt().stringify(script));
70-
return Response.json(await gpt().parse(path.join(SCRIPTS_PATH(),`${name}.gpt`)));
56+
return NextResponse.json(await gpt().parse(path.join(SCRIPTS_PATH(),`${name}.gpt`)));
7157
} catch (e) {
7258
if (`${e}`.includes('no such file')){
73-
return Response.json({ error: '.gpt file not found' }, { status: 404 });
59+
return NextResponse.json({ error: '.gpt file not found' }, { status: 404 });
7460
}
75-
return Response.json({ error: e }, {status: 500});
61+
return NextResponse.json({ error: e }, {status: 500});
7662
}
7763
}
7864

app/api/file/route.ts

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
export const dynamic = 'force-dynamic' // defaults to auto
2-
import { GPTScript } from '@gptscript-ai/gptscript'
32
import { promises as fs } from 'fs';
3+
import { NextResponse } from 'next/server';
44
import { SCRIPTS_PATH, gpt } from '@/config/env';
55

66
export async function GET() {
@@ -9,7 +9,7 @@ export async function GET() {
99
const gptFiles = files.filter(file => file.endsWith('.gpt'));
1010

1111
if (gptFiles.length === 0)
12-
return Response.json({ error: 'no .gpt files found' }, { status: 404 });
12+
return NextResponse.json({ error: 'no .gpt files found' }, { status: 404 });
1313

1414
const scripts: Record<string, string> = {};
1515
for (const file of gptFiles) {
@@ -23,20 +23,23 @@ export async function GET() {
2323
scripts[file] = description || '';
2424
}
2525

26-
return Response.json(scripts);
26+
return NextResponse.json(scripts);
2727
} catch (e) {
2828
const error = e as NodeJS.ErrnoException;
2929
if (error.code === 'ENOENT'){
30-
return Response.json({ error: 'no .gpt files found' }, { status: 404 });
30+
return NextResponse.json({ error: 'no .gpt files found' }, { status: 404 });
3131
}
3232
console.error(e)
33-
return Response.json({ error: e }, { status: 500 });
33+
return NextResponse.json({ error: e }, { status: 500 });
3434
}
3535
}
3636

3737
export async function POST(_req: Request) {
3838
try {
39-
const files = await fs.readdir(SCRIPTS_PATH());
39+
const scriptsPath = SCRIPTS_PATH()
40+
await fs.mkdir(scriptsPath, { recursive: true })
41+
42+
const files = await fs.readdir(scriptsPath);
4043
const gptFiles = files.filter(file => file.endsWith('.gpt'));
4144

4245
let id = 0;
@@ -45,9 +48,9 @@ export async function POST(_req: Request) {
4548
id++;
4649
newFileName = `new-file-${id}.gpt`;
4750
}
48-
await fs.writeFile(`${SCRIPTS_PATH()}/${newFileName}`, '---\nname: main');
49-
return Response.json({ file: newFileName });
51+
await fs.writeFile(`${scriptsPath}/${newFileName}`, '---\nname: main');
52+
return NextResponse.json({ file: newFileName });
5053
} catch (e) {
51-
return Response.json({ error: e }, { status: 500 });
54+
return NextResponse.json({ error: e }, { status: 500 });
5255
}
5356
}

config/env.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import path from "path";
33

44
export const SCRIPTS_PATH = () => process.env.SCRIPTS_PATH || "gptscripts";
55
export const WORKSPACE_DIR = () => process.env.GPTSCRIPT_WORKSPACE_DIR || "";
6-
export const THREADS_DIR = () => process.env.THREADS_DIR|| path.join(WORKSPACE_DIR(), "threads");
6+
export const THREADS_DIR = () => process.env.THREADS_DIR || path.join(WORKSPACE_DIR(), "threads");
77

88
export const set_WORKSPACE_DIR = (dir: string) => process.env.GPTSCRIPT_WORKSPACE_DIR = dir;
99
export const set_SCRIPTS_PATH = (dir: string) => process.env.SCRIPTS_PATH = dir;

server.mjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import {createServer} from "node:http";
22
import next from "next";
33
import {Server} from "socket.io";
4-
import {GPTScript, RunEventType, RunState} from '@gptscript-ai/gptscript';
4+
import {GPTScript, RunEventType} from '@gptscript-ai/gptscript';
55
import dotenv from 'dotenv';
66
import fs from 'fs';
77
import path from 'path';

0 commit comments

Comments
 (0)