better-codex 0.1.4 → 0.2.1
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/apps/backend/README.md +43 -2
- package/apps/backend/src/core/app-server.ts +68 -2
- package/apps/backend/src/core/jsonrpc.ts +13 -0
- package/apps/backend/src/server.ts +156 -1
- package/apps/backend/src/services/codex-config.ts +561 -0
- package/apps/backend/src/thread-activity/service.ts +47 -0
- package/apps/web/README.md +18 -2
- package/apps/web/src/components/layout/codex-settings.tsx +1208 -0
- package/apps/web/src/components/layout/session-view.tsx +203 -8
- package/apps/web/src/components/layout/settings-dialog.tsx +9 -1
- package/apps/web/src/components/layout/virtualized-message-list.tsx +594 -90
- package/apps/web/src/components/session-view/rate-limit-banner.tsx +178 -0
- package/apps/web/src/components/session-view/session-dialogs.tsx +93 -2
- package/apps/web/src/components/session-view/session-header.tsx +21 -2
- package/apps/web/src/components/session-view/thread-account-switcher.tsx +191 -0
- package/apps/web/src/components/ui/icons.tsx +12 -0
- package/apps/web/src/hooks/use-hub-connection.ts +59 -19
- package/apps/web/src/hooks/use-thread-history.ts +94 -5
- package/apps/web/src/services/hub-client.ts +98 -1
- package/apps/web/src/store/index.ts +36 -1
- package/apps/web/src/types/index.ts +25 -0
- package/apps/web/src/utils/item-format.ts +55 -9
- package/apps/web/src/utils/slash-commands.ts +2 -0
- package/package.json +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Message, MessageKind } from '../types'
|
|
1
|
+
import type { CommandAction, FileChangeMeta, Message, MessageKind, MessageMeta } from '../types'
|
|
2
2
|
|
|
3
3
|
type ThreadItem = {
|
|
4
4
|
type: string
|
|
@@ -6,11 +6,11 @@ type ThreadItem = {
|
|
|
6
6
|
[key: string]: unknown
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
-
type CommandAction =
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
9
|
+
// type CommandAction =
|
|
10
|
+
// | { type: 'read'; command: string; name: string; path: string }
|
|
11
|
+
// | { type: 'listFiles'; command: string; path?: string | null }
|
|
12
|
+
// | { type: 'search'; command: string; query?: string | null; path?: string | null }
|
|
13
|
+
// | { type: 'unknown'; command: string }
|
|
14
14
|
|
|
15
15
|
const clampText = (value: string, max = 1400) => {
|
|
16
16
|
if (value.length <= max) {
|
|
@@ -99,7 +99,43 @@ const formatCommandActions = (actions: CommandAction[], commandFallback: string)
|
|
|
99
99
|
}
|
|
100
100
|
}
|
|
101
101
|
|
|
102
|
-
|
|
102
|
+
type FormattedThreadItem = {
|
|
103
|
+
kind: MessageKind
|
|
104
|
+
content: string
|
|
105
|
+
title?: string
|
|
106
|
+
meta?: MessageMeta
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
const toFileChangeMeta = (change: {
|
|
110
|
+
path?: unknown
|
|
111
|
+
kind?: unknown
|
|
112
|
+
diff?: string
|
|
113
|
+
movePath?: unknown
|
|
114
|
+
move_path?: unknown
|
|
115
|
+
}): FileChangeMeta => {
|
|
116
|
+
const path = typeof change.path === 'string' ? change.path : 'unknown'
|
|
117
|
+
const kind =
|
|
118
|
+
typeof change.kind === 'string'
|
|
119
|
+
? change.kind
|
|
120
|
+
: typeof (change.kind as { type?: string } | null | undefined)?.type === 'string'
|
|
121
|
+
? String((change.kind as { type?: string }).type)
|
|
122
|
+
: 'update'
|
|
123
|
+
const movePath =
|
|
124
|
+
typeof change.movePath === 'string'
|
|
125
|
+
? change.movePath
|
|
126
|
+
: typeof change.move_path === 'string'
|
|
127
|
+
? change.move_path
|
|
128
|
+
: undefined
|
|
129
|
+
|
|
130
|
+
return {
|
|
131
|
+
path,
|
|
132
|
+
kind: kind === 'add' || kind === 'delete' ? kind : 'update',
|
|
133
|
+
diff: typeof change.diff === 'string' ? change.diff : undefined,
|
|
134
|
+
movePath: movePath ?? null,
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
export const formatThreadItem = (item: ThreadItem): FormattedThreadItem | null => {
|
|
103
139
|
switch (item.type) {
|
|
104
140
|
case 'reasoning': {
|
|
105
141
|
const summary = Array.isArray(item.summary) ? item.summary.join('\n') : ''
|
|
@@ -113,13 +149,22 @@ export const formatThreadItem = (item: ThreadItem): { kind: MessageKind; content
|
|
|
113
149
|
const actions = Array.isArray(item.commandActions) ? (item.commandActions as CommandAction[]) : []
|
|
114
150
|
const actionSummary = formatCommandActions(actions, command)
|
|
115
151
|
const content = output ? `${actionSummary.content}\n\n${output}` : actionSummary.content
|
|
116
|
-
|
|
152
|
+
const meta: MessageMeta = {
|
|
153
|
+
commandActions: actions.length ? actions : undefined,
|
|
154
|
+
command,
|
|
155
|
+
status,
|
|
156
|
+
}
|
|
157
|
+
return { kind: actionSummary.kind, content: clampText(content), title: actionSummary.title, meta }
|
|
117
158
|
}
|
|
118
159
|
case 'fileChange': {
|
|
119
160
|
const changes = Array.isArray(item.changes) ? item.changes : []
|
|
120
161
|
const content = formatFileChanges(changes as Array<{ path?: string; kind?: string; diff?: string; movePath?: string }>)
|
|
121
162
|
const status = typeof item.status === 'string' ? item.status : 'inProgress'
|
|
122
|
-
|
|
163
|
+
const meta: MessageMeta = {
|
|
164
|
+
fileChanges: changes.length ? changes.map((change) => toFileChangeMeta(change as Record<string, unknown>)) : undefined,
|
|
165
|
+
status,
|
|
166
|
+
}
|
|
167
|
+
return { kind: 'file', content, title: 'Files', meta }
|
|
123
168
|
}
|
|
124
169
|
case 'mcpToolCall': {
|
|
125
170
|
const server = typeof item.server === 'string' ? item.server : 'mcp'
|
|
@@ -166,5 +211,6 @@ export const buildSystemMessage = (item: ThreadItem): Message | null => {
|
|
|
166
211
|
title: formatted.title,
|
|
167
212
|
content: formatted.content,
|
|
168
213
|
timestamp: '',
|
|
214
|
+
meta: formatted.meta,
|
|
169
215
|
}
|
|
170
216
|
}
|
|
@@ -4,6 +4,7 @@ export type SlashCommandId =
|
|
|
4
4
|
| 'cwd'
|
|
5
5
|
| 'approvals'
|
|
6
6
|
| 'skills'
|
|
7
|
+
| 'switch'
|
|
7
8
|
| 'review'
|
|
8
9
|
| 'new'
|
|
9
10
|
| 'resume'
|
|
@@ -32,6 +33,7 @@ export const SLASH_COMMANDS: SlashCommandDefinition[] = [
|
|
|
32
33
|
{ id: 'cwd', description: 'set working directory for the thread', availableDuringTask: false },
|
|
33
34
|
{ id: 'approvals', description: 'choose what Codex can do without approval', availableDuringTask: false },
|
|
34
35
|
{ id: 'skills', description: 'browse and insert skills', availableDuringTask: true },
|
|
36
|
+
{ id: 'switch', description: 'switch to a different account for this thread', availableDuringTask: false },
|
|
35
37
|
{ id: 'review', description: 'review my current changes and find issues', availableDuringTask: false },
|
|
36
38
|
{ id: 'new', description: 'start a new chat during a conversation', availableDuringTask: false },
|
|
37
39
|
{ id: 'resume', description: 'resume a saved chat', availableDuringTask: false },
|