xedoc-cli 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -15
- package/bin/xedoc.mjs +13 -17
- package/build/client/assets/app-layout-d99dmiup.js +1 -0
- package/build/client/assets/app-shell-Dl69tJhv.js +1 -0
- package/build/client/assets/chat-B5FboIxH.js +1 -0
- package/build/client/assets/{connect-0oYrfAJT.js → connect-CHSFTXwk.js} +1 -1
- package/build/client/assets/{document-title-Dn4sU16M.js → document-title-B6Yxyaur.js} +1 -1
- package/build/client/assets/{entry.client-CM3vH2bv.js → entry.client-BlQXdBHx.js} +1 -1
- package/build/client/assets/home-Bahc85Gk.js +1 -0
- package/build/client/assets/{label-FUU4pCWu.js → label-C7i5Qt-O.js} +1 -1
- package/build/client/assets/manifest-fe1036ff.js +1 -0
- package/build/client/assets/{react-dom-KYDDPtOx.js → react-dom-CMuFyqmq.js} +1 -1
- package/build/client/assets/{root-DKEnPIjJ.js → root-feKzGV0p.js} +1 -1
- package/build/client/assets/{session-provider-FKGj36EG.js → session-provider-2Ozr-CuV.js} +1 -1
- package/build/server/index.js +1 -1
- package/package.json +2 -2
- package/prisma/schema.prisma +3 -19
- package/server/index.mjs +24 -2
- package/server/sqlite-setup.mjs +52 -47
- package/build/client/assets/api.workspaces.directories-B0tllRDq.js +0 -0
- package/build/client/assets/app-layout-C1QtSnIO.js +0 -1
- package/build/client/assets/app-shell-Bcxy4tS4.js +0 -1
- package/build/client/assets/chat-DrelwLpW.js +0 -1
- package/build/client/assets/home-DSWMwIrE.js +0 -1
- package/build/client/assets/manifest-9479dd15.js +0 -1
- /package/build/client/assets/{api.accounts-CHoT6sYP.js → api.accounts-x_2c5-qG.js} +0 -0
- /package/build/client/assets/{api.accounts._accountId-BixDYyx8.js → api.accounts._accountId-BksU0sQ7.js} +0 -0
- /package/build/client/assets/{api.accounts._accountId.authenticate-CLzgv3py.js → api.accounts._accountId.authenticate-Bp51NHGy.js} +0 -0
- /package/build/client/assets/{api.accounts._accountId.authenticate.callback-Bqhz8sDl.js → api.accounts._accountId.authenticate.callback-DLgNMRyd.js} +0 -0
- /package/build/client/assets/{api.accounts._accountId.models-VIVpVZrj.js → api.accounts._accountId.models-DGbCmT_9.js} +0 -0
- /package/build/client/assets/{api.accounts._accountId.rate-limits-C9iUvNFt.js → api.accounts._accountId.rate-limits-DZh4HPLO.js} +0 -0
- /package/build/client/assets/{api.accounts._accountId.runtime-settings-6XNKTx--.js → api.accounts._accountId.runtime-settings-ChGZGvfx.js} +0 -0
- /package/build/client/assets/{api.accounts.export-romutOT6.js → api.accounts.export-CwjXUcyG.js} +0 -0
- /package/build/client/assets/{api.accounts.import-BiWq2jPz.js → api.accounts.import-Km-76sRE.js} +0 -0
- /package/build/client/assets/{api.chats-C6-gVaXw.js → api.chats-DZ_6Q7rY.js} +0 -0
- /package/build/client/assets/{api.chats._chatId-DaXHa-ln.js → api.chats._chatId-BEX87qHo.js} +0 -0
- /package/build/client/assets/{api.chats._chatId.context-DlBgjpCD.js → api.chats._chatId.context-v4G0lNKq.js} +0 -0
- /package/build/client/assets/{api.chats._chatId.files-DVZKcoNV.js → api.chats._chatId.files-BrN7O-wM.js} +0 -0
- /package/build/client/assets/{api.chats._chatId.git._operation-8Xtyz4hF.js → api.chats._chatId.git._operation-CiUW8Knm.js} +0 -0
- /package/build/client/assets/{api.chats._chatId.interrupt-B71lrxkc.js → api.chats._chatId.interrupt-2DlVPDlX.js} +0 -0
- /package/build/client/assets/{api.chats._chatId.messages-iVzJcgvw.js → api.chats._chatId.messages-cDawTuvN.js} +0 -0
- /package/build/client/assets/{api.chats._chatId.server-requests._requestId.respond-BLhOUK8A.js → api.chats._chatId.server-requests._requestId.respond-CTlCffOk.js} +0 -0
- /package/build/client/assets/{api.users-BLvMDkJE.js → api.workspaces.directories-nVoleT74.js} +0 -0
- /package/build/client/assets/{jsx-runtime-B9QlDcuB.js → jsx-runtime-Dafdqr5g.js} +0 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "xedoc-cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "Local web UI for Codex account, chat, execution, and workspace management.",
|
|
5
5
|
"author": "Edward Nguyen <monokaijs@gmail.com>",
|
|
6
6
|
"type": "module",
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
"clean:build": "node -e \"import('node:fs/promises').then(({ rm }) => rm('build', { recursive: true, force: true }))\"",
|
|
37
37
|
"prepublishOnly": "pnpm typecheck",
|
|
38
38
|
"prepack": "pnpm clean:build && pnpm build",
|
|
39
|
-
"publish": "npm publish --access public",
|
|
39
|
+
"publish:npm": "npm publish --access public",
|
|
40
40
|
"publish:dry-run": "npm publish --access public --dry-run",
|
|
41
41
|
"prisma:generate": "prisma generate --schema prisma/schema.prisma",
|
|
42
42
|
"db:setup": "node -e \"import('./server/sqlite-setup.mjs').then((m)=>m.setupSqliteDatabase())\""
|
package/prisma/schema.prisma
CHANGED
|
@@ -4,7 +4,7 @@ generator client {
|
|
|
4
4
|
|
|
5
5
|
datasource db {
|
|
6
6
|
provider = "sqlite"
|
|
7
|
-
url =
|
|
7
|
+
url = "file:../.xedoc/xedoc.db"
|
|
8
8
|
}
|
|
9
9
|
|
|
10
10
|
enum AccountStatus {
|
|
@@ -54,16 +54,6 @@ enum RunStatus {
|
|
|
54
54
|
CANCELLED
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
-
model User {
|
|
58
|
-
id String @id @default(uuid())
|
|
59
|
-
externalId String? @unique
|
|
60
|
-
name String?
|
|
61
|
-
createdAt DateTime @default(now())
|
|
62
|
-
updatedAt DateTime @updatedAt
|
|
63
|
-
accounts CodexAccount[]
|
|
64
|
-
chats Chat[]
|
|
65
|
-
}
|
|
66
|
-
|
|
67
57
|
model ServerAuth {
|
|
68
58
|
id String @id @default("server")
|
|
69
59
|
passwordHash String
|
|
@@ -74,7 +64,6 @@ model ServerAuth {
|
|
|
74
64
|
|
|
75
65
|
model CodexAccount {
|
|
76
66
|
id String @id @default(uuid())
|
|
77
|
-
userId String
|
|
78
67
|
displayName String
|
|
79
68
|
status AccountStatus @default(DISCONNECTED)
|
|
80
69
|
command String @default("codex")
|
|
@@ -88,16 +77,12 @@ model CodexAccount {
|
|
|
88
77
|
lastError String?
|
|
89
78
|
createdAt DateTime @default(now())
|
|
90
79
|
updatedAt DateTime @updatedAt
|
|
91
|
-
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
92
80
|
chats Chat[]
|
|
93
81
|
runs ChatRun[]
|
|
94
|
-
|
|
95
|
-
@@index([userId])
|
|
96
82
|
}
|
|
97
83
|
|
|
98
84
|
model Chat {
|
|
99
85
|
id String @id @default(uuid())
|
|
100
|
-
userId String
|
|
101
86
|
accountId String?
|
|
102
87
|
title String
|
|
103
88
|
workingDirectory String?
|
|
@@ -111,13 +96,12 @@ model Chat {
|
|
|
111
96
|
lastActivityAt DateTime @default(now())
|
|
112
97
|
createdAt DateTime @default(now())
|
|
113
98
|
updatedAt DateTime @updatedAt
|
|
114
|
-
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
115
99
|
account CodexAccount? @relation(fields: [accountId], references: [id], onDelete: SetNull)
|
|
116
100
|
messages ChatMessage[]
|
|
117
101
|
runs ChatRun[]
|
|
118
102
|
|
|
119
|
-
@@index([
|
|
120
|
-
@@index([
|
|
103
|
+
@@index([updatedAt])
|
|
104
|
+
@@index([lastActivityAt])
|
|
121
105
|
@@index([accountId])
|
|
122
106
|
}
|
|
123
107
|
|
package/server/index.mjs
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import "dotenv/config"
|
|
2
2
|
import { createHmac, createHash, timingSafeEqual } from "node:crypto"
|
|
3
|
-
import { createReadStream, statSync } from "node:fs"
|
|
3
|
+
import { createReadStream, mkdirSync, statSync } from "node:fs"
|
|
4
4
|
import { createServer } from "node:http"
|
|
5
|
+
import { homedir } from "node:os"
|
|
5
6
|
import { dirname, extname, join, normalize, resolve } from "node:path"
|
|
6
7
|
import { fileURLToPath } from "node:url"
|
|
7
8
|
import { PrismaClient } from "@prisma/client"
|
|
@@ -14,8 +15,15 @@ const DEFAULT_PORT = "6354"
|
|
|
14
15
|
const SERVER_AUTH_ID = "server"
|
|
15
16
|
const serverRoot = dirname(fileURLToPath(import.meta.url))
|
|
16
17
|
const packageRoot = resolve(serverRoot, "..")
|
|
17
|
-
const prisma = new PrismaClient()
|
|
18
18
|
const options = parseArgs(process.argv.slice(2))
|
|
19
|
+
const workspaceRoot = resolveHomePath(process.env.CODEX_WORKSPACE_ROOT ?? homedir())
|
|
20
|
+
const databasePath = join(workspaceRoot, ".xedoc", "xedoc.db")
|
|
21
|
+
const databaseUrl = sqliteDatabaseUrl(databasePath)
|
|
22
|
+
process.env.DATABASE_URL = databaseUrl
|
|
23
|
+
mkdirSync(dirname(databasePath), { recursive: true, mode: 0o700 })
|
|
24
|
+
const prisma = new PrismaClient({
|
|
25
|
+
datasources: { db: { url: databaseUrl } },
|
|
26
|
+
})
|
|
19
27
|
const build = await import(join(packageRoot, "build/server/index.js"))
|
|
20
28
|
const clientRoot = join(packageRoot, "build/client")
|
|
21
29
|
const requestListener = createRequestListener({
|
|
@@ -75,6 +83,20 @@ function fail(message) {
|
|
|
75
83
|
process.exit(1)
|
|
76
84
|
}
|
|
77
85
|
|
|
86
|
+
function resolveHomePath(path) {
|
|
87
|
+
if (path === "~") {
|
|
88
|
+
return homedir()
|
|
89
|
+
}
|
|
90
|
+
if (path.startsWith("~/")) {
|
|
91
|
+
return join(homedir(), path.slice(2))
|
|
92
|
+
}
|
|
93
|
+
return resolve(path)
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function sqliteDatabaseUrl(path) {
|
|
97
|
+
return `file:${path}?connection_limit=1&pool_timeout=30`
|
|
98
|
+
}
|
|
99
|
+
|
|
78
100
|
function installSocketServer(httpServer) {
|
|
79
101
|
const io = new SocketServer(httpServer, {
|
|
80
102
|
path: "/socket.io",
|
package/server/sqlite-setup.mjs
CHANGED
|
@@ -1,18 +1,21 @@
|
|
|
1
1
|
import "dotenv/config"
|
|
2
2
|
import { mkdir } from "node:fs/promises"
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
const schemaDirectory = dirname(
|
|
7
|
-
fileURLToPath(new URL("../prisma/schema.prisma", import.meta.url)),
|
|
8
|
-
)
|
|
3
|
+
import { homedir } from "node:os"
|
|
4
|
+
import { dirname, join, resolve } from "node:path"
|
|
9
5
|
|
|
10
6
|
export async function setupSqliteDatabase() {
|
|
11
|
-
|
|
7
|
+
const databasePath = workspaceDatabasePath()
|
|
8
|
+
const databaseUrl = sqliteDatabaseUrl(databasePath)
|
|
9
|
+
process.env.DATABASE_URL = databaseUrl
|
|
10
|
+
await mkdir(dirname(databasePath), { recursive: true, mode: 0o700 })
|
|
12
11
|
const { PrismaClient } = await import("@prisma/client")
|
|
13
|
-
const prisma = new PrismaClient(
|
|
12
|
+
const prisma = new PrismaClient({
|
|
13
|
+
datasources: { db: { url: databaseUrl } },
|
|
14
|
+
})
|
|
14
15
|
try {
|
|
15
16
|
await prisma.$executeRawUnsafe("PRAGMA foreign_keys = ON")
|
|
17
|
+
await prisma.$queryRawUnsafe("PRAGMA journal_mode = WAL")
|
|
18
|
+
await prisma.$queryRawUnsafe("PRAGMA busy_timeout = 30000")
|
|
16
19
|
for (const statement of schemaStatements) {
|
|
17
20
|
try {
|
|
18
21
|
await prisma.$executeRawUnsafe(statement)
|
|
@@ -32,39 +35,31 @@ function isDuplicateColumnError(error) {
|
|
|
32
35
|
return message.toLowerCase().includes("duplicate column name")
|
|
33
36
|
}
|
|
34
37
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
38
|
+
function workspaceDatabasePath() {
|
|
39
|
+
return join(
|
|
40
|
+
resolveHomePath(process.env.CODEX_WORKSPACE_ROOT?.trim() || homedir()),
|
|
41
|
+
".xedoc",
|
|
42
|
+
"xedoc.db",
|
|
43
|
+
)
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function resolveHomePath(path) {
|
|
47
|
+
if (path === "~") {
|
|
48
|
+
return homedir()
|
|
39
49
|
}
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
return
|
|
50
|
+
if (path.startsWith("~/")) {
|
|
51
|
+
return join(homedir(), path.slice(2))
|
|
43
52
|
}
|
|
44
|
-
|
|
45
|
-
? filePath
|
|
46
|
-
: resolve(schemaDirectory, filePath)
|
|
47
|
-
await mkdir(dirname(resolvedPath), { recursive: true })
|
|
53
|
+
return resolve(path)
|
|
48
54
|
}
|
|
49
55
|
|
|
50
|
-
|
|
51
|
-
`
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
"updatedAt" DATETIME NOT NULL
|
|
57
|
-
)`,
|
|
58
|
-
`CREATE TABLE IF NOT EXISTS "ServerAuth" (
|
|
59
|
-
"id" TEXT NOT NULL PRIMARY KEY DEFAULT 'server',
|
|
60
|
-
"passwordHash" TEXT NOT NULL,
|
|
61
|
-
"tokenSecret" TEXT NOT NULL,
|
|
62
|
-
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
63
|
-
"updatedAt" DATETIME NOT NULL
|
|
64
|
-
)`,
|
|
65
|
-
`CREATE TABLE IF NOT EXISTS "CodexAccount" (
|
|
56
|
+
function sqliteDatabaseUrl(path) {
|
|
57
|
+
return `file:${path}?connection_limit=1&pool_timeout=30`
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function createCodexAccountTable(tableName) {
|
|
61
|
+
return `CREATE TABLE IF NOT EXISTS "${tableName}" (
|
|
66
62
|
"id" TEXT NOT NULL PRIMARY KEY,
|
|
67
|
-
"userId" TEXT NOT NULL,
|
|
68
63
|
"displayName" TEXT NOT NULL,
|
|
69
64
|
"status" TEXT NOT NULL DEFAULT 'DISCONNECTED',
|
|
70
65
|
"command" TEXT NOT NULL DEFAULT 'codex',
|
|
@@ -77,12 +72,13 @@ const schemaStatements = [
|
|
|
77
72
|
"lastAuthUrl" TEXT,
|
|
78
73
|
"lastError" TEXT,
|
|
79
74
|
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
80
|
-
"updatedAt" DATETIME NOT NULL
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
75
|
+
"updatedAt" DATETIME NOT NULL
|
|
76
|
+
)`
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function createChatTable(tableName) {
|
|
80
|
+
return `CREATE TABLE IF NOT EXISTS "${tableName}" (
|
|
84
81
|
"id" TEXT NOT NULL PRIMARY KEY,
|
|
85
|
-
"userId" TEXT NOT NULL,
|
|
86
82
|
"accountId" TEXT,
|
|
87
83
|
"title" TEXT NOT NULL,
|
|
88
84
|
"workingDirectory" TEXT,
|
|
@@ -96,9 +92,20 @@ const schemaStatements = [
|
|
|
96
92
|
"lastActivityAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
97
93
|
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
98
94
|
"updatedAt" DATETIME NOT NULL,
|
|
99
|
-
CONSTRAINT "
|
|
100
|
-
|
|
95
|
+
CONSTRAINT "${tableName}_accountId_fkey" FOREIGN KEY ("accountId") REFERENCES "CodexAccount" ("id") ON DELETE SET NULL ON UPDATE CASCADE
|
|
96
|
+
)`
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const schemaStatements = [
|
|
100
|
+
`CREATE TABLE IF NOT EXISTS "ServerAuth" (
|
|
101
|
+
"id" TEXT NOT NULL PRIMARY KEY DEFAULT 'server',
|
|
102
|
+
"passwordHash" TEXT NOT NULL,
|
|
103
|
+
"tokenSecret" TEXT NOT NULL,
|
|
104
|
+
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
105
|
+
"updatedAt" DATETIME NOT NULL
|
|
101
106
|
)`,
|
|
107
|
+
createCodexAccountTable("CodexAccount"),
|
|
108
|
+
createChatTable("Chat"),
|
|
102
109
|
`CREATE TABLE IF NOT EXISTS "ChatMessage" (
|
|
103
110
|
"id" TEXT NOT NULL PRIMARY KEY,
|
|
104
111
|
"chatId" TEXT NOT NULL,
|
|
@@ -134,14 +141,12 @@ const schemaStatements = [
|
|
|
134
141
|
CONSTRAINT "ChatRun_chatId_fkey" FOREIGN KEY ("chatId") REFERENCES "Chat" ("id") ON DELETE CASCADE ON UPDATE CASCADE,
|
|
135
142
|
CONSTRAINT "ChatRun_accountId_fkey" FOREIGN KEY ("accountId") REFERENCES "CodexAccount" ("id") ON DELETE RESTRICT ON UPDATE CASCADE
|
|
136
143
|
)`,
|
|
137
|
-
'CREATE UNIQUE INDEX IF NOT EXISTS "User_externalId_key" ON "User"("externalId")',
|
|
138
144
|
'ALTER TABLE "CodexAccount" ADD COLUMN "defaultModel" TEXT',
|
|
139
145
|
'ALTER TABLE "CodexAccount" ADD COLUMN "defaultPermissionMode" TEXT',
|
|
140
146
|
'ALTER TABLE "CodexAccount" ADD COLUMN "defaultReasoningEffort" TEXT',
|
|
141
147
|
'ALTER TABLE "CodexAccount" ADD COLUMN "defaultServiceTier" TEXT',
|
|
142
|
-
'CREATE INDEX IF NOT EXISTS "
|
|
143
|
-
'CREATE INDEX IF NOT EXISTS "
|
|
144
|
-
'CREATE INDEX IF NOT EXISTS "Chat_userId_lastActivityAt_idx" ON "Chat"("userId", "lastActivityAt")',
|
|
148
|
+
'CREATE INDEX IF NOT EXISTS "Chat_updatedAt_idx" ON "Chat"("updatedAt")',
|
|
149
|
+
'CREATE INDEX IF NOT EXISTS "Chat_lastActivityAt_idx" ON "Chat"("lastActivityAt")',
|
|
145
150
|
'CREATE INDEX IF NOT EXISTS "Chat_accountId_idx" ON "Chat"("accountId")',
|
|
146
151
|
'CREATE INDEX IF NOT EXISTS "ChatMessage_chatId_sequence_idx" ON "ChatMessage"("chatId", "sequence")',
|
|
147
152
|
'CREATE INDEX IF NOT EXISTS "ChatMessage_chatId_turnId_idx" ON "ChatMessage"("chatId", "turnId")',
|
|
File without changes
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{j as r,t as s}from"./jsx-runtime-B9QlDcuB.js";import{t}from"./app-shell-Bcxy4tS4.js";var a=s(),o=r(function(){return(0,a.jsx)(t,{})});export{o as default};
|