@codori/client 0.0.1 → 0.0.3

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.
Files changed (41) hide show
  1. package/app/components/ChatWorkspace.vue +882 -187
  2. package/app/components/MessageContent.vue +4 -2
  3. package/app/components/MessagePartRenderer.ts +12 -2
  4. package/app/components/ProjectSidebar.vue +2 -2
  5. package/app/components/SubagentDrawerList.vue +64 -0
  6. package/app/components/SubagentTranscriptPanel.vue +305 -0
  7. package/app/components/ThreadList.vue +5 -5
  8. package/app/components/ThreadPanel.vue +65 -46
  9. package/app/components/VisualSubagentStack.vue +14 -244
  10. package/app/components/message-item/CommandExecution.vue +2 -2
  11. package/app/components/message-item/DynamicToolCall.vue +2 -2
  12. package/app/components/message-item/FileChange.vue +2 -2
  13. package/app/components/message-item/McpToolCall.vue +2 -2
  14. package/app/components/message-item/SubagentActivity.vue +2 -2
  15. package/app/components/message-item/WebSearch.vue +2 -2
  16. package/app/components/message-part/Attachment.vue +61 -0
  17. package/app/components/message-part/Event.vue +1 -1
  18. package/app/components/message-part/Item.ts +1 -1
  19. package/app/composables/useChatAttachments.ts +208 -0
  20. package/app/composables/useChatSession.ts +33 -2
  21. package/app/composables/useProjects.ts +4 -5
  22. package/app/composables/useRpc.ts +3 -3
  23. package/app/composables/useVisualSubagentPanels.ts +1 -1
  24. package/app/pages/projects/[...projectId]/index.vue +5 -5
  25. package/app/pages/projects/[...projectId]/threads/[threadId].vue +228 -75
  26. package/app/utils/chat-turn-engagement.ts +46 -0
  27. package/package.json +1 -1
  28. package/server/api/codori/projects/[projectId]/attachments/file.get.ts +62 -0
  29. package/server/api/codori/projects/[projectId]/attachments.post.ts +53 -0
  30. package/server/api/codori/projects/[projectId]/start.post.ts +3 -3
  31. package/server/api/codori/projects/[projectId]/status.get.ts +3 -3
  32. package/server/api/codori/projects/[projectId]/stop.post.ts +3 -3
  33. package/server/api/codori/projects/[projectId].get.ts +3 -3
  34. package/server/api/codori/projects/index.get.ts +2 -2
  35. package/server/utils/server-proxy.ts +23 -0
  36. package/shared/chat-attachments.ts +135 -0
  37. package/shared/chat-prompt-controls.ts +339 -0
  38. package/shared/codex-chat.ts +33 -11
  39. package/shared/codex-rpc.ts +19 -0
  40. package/shared/network.ts +8 -0
  41. package/shared/subagent-panels.ts +158 -0
@@ -0,0 +1,158 @@
1
+ import type { SubagentAgentStatus, VisualSubagentPanel } from './codex-chat'
2
+
3
+ export type SubagentAccent = {
4
+ textClass: string
5
+ avatarClass: string
6
+ dotClass: string
7
+ headerClass: string
8
+ }
9
+
10
+ export type SubagentPanelAutoOpenInput = {
11
+ isMobile: boolean
12
+ hasAvailableSubagents: boolean
13
+ hasResolvedState: boolean
14
+ hasUserToggled: boolean
15
+ previousActiveCount: number
16
+ nextActiveCount: number
17
+ }
18
+
19
+ export type SubagentPanelAutoOpenResult = {
20
+ hasResolvedState: boolean
21
+ previousActiveCount: number
22
+ nextOpen: boolean | null
23
+ }
24
+
25
+ const SUBAGENT_ACCENT_STYLES = [
26
+ {
27
+ textClass: 'text-emerald-700 dark:text-emerald-300',
28
+ avatarClass: 'bg-emerald-500/15 text-emerald-700 ring-1 ring-inset ring-emerald-500/30 dark:text-emerald-300',
29
+ dotClass: 'bg-emerald-500 ring-emerald-500/25',
30
+ headerClass: 'border-s-2 border-emerald-500/45 bg-emerald-500/6'
31
+ },
32
+ {
33
+ textClass: 'text-sky-700 dark:text-sky-300',
34
+ avatarClass: 'bg-sky-500/15 text-sky-700 ring-1 ring-inset ring-sky-500/30 dark:text-sky-300',
35
+ dotClass: 'bg-sky-500 ring-sky-500/25',
36
+ headerClass: 'border-s-2 border-sky-500/45 bg-sky-500/6'
37
+ },
38
+ {
39
+ textClass: 'text-amber-800 dark:text-amber-300',
40
+ avatarClass: 'bg-amber-500/15 text-amber-800 ring-1 ring-inset ring-amber-500/35 dark:text-amber-300',
41
+ dotClass: 'bg-amber-500 ring-amber-500/25',
42
+ headerClass: 'border-s-2 border-amber-500/45 bg-amber-500/6'
43
+ },
44
+ {
45
+ textClass: 'text-rose-700 dark:text-rose-300',
46
+ avatarClass: 'bg-rose-500/15 text-rose-700 ring-1 ring-inset ring-rose-500/30 dark:text-rose-300',
47
+ dotClass: 'bg-rose-500 ring-rose-500/25',
48
+ headerClass: 'border-s-2 border-rose-500/45 bg-rose-500/6'
49
+ },
50
+ {
51
+ textClass: 'text-violet-700 dark:text-violet-300',
52
+ avatarClass: 'bg-violet-500/15 text-violet-700 ring-1 ring-inset ring-violet-500/30 dark:text-violet-300',
53
+ dotClass: 'bg-violet-500 ring-violet-500/25',
54
+ headerClass: 'border-s-2 border-violet-500/45 bg-violet-500/6'
55
+ },
56
+ {
57
+ textClass: 'text-cyan-700 dark:text-cyan-300',
58
+ avatarClass: 'bg-cyan-500/15 text-cyan-700 ring-1 ring-inset ring-cyan-500/30 dark:text-cyan-300',
59
+ dotClass: 'bg-cyan-500 ring-cyan-500/25',
60
+ headerClass: 'border-s-2 border-cyan-500/45 bg-cyan-500/6'
61
+ },
62
+ {
63
+ textClass: 'text-lime-800 dark:text-lime-300',
64
+ avatarClass: 'bg-lime-500/15 text-lime-800 ring-1 ring-inset ring-lime-500/35 dark:text-lime-300',
65
+ dotClass: 'bg-lime-500 ring-lime-500/25',
66
+ headerClass: 'border-s-2 border-lime-500/45 bg-lime-500/6'
67
+ },
68
+ {
69
+ textClass: 'text-orange-700 dark:text-orange-300',
70
+ avatarClass: 'bg-orange-500/15 text-orange-700 ring-1 ring-inset ring-orange-500/30 dark:text-orange-300',
71
+ dotClass: 'bg-orange-500 ring-orange-500/25',
72
+ headerClass: 'border-s-2 border-orange-500/45 bg-orange-500/6'
73
+ }
74
+ ] as const
75
+
76
+ export const resolveSubagentAccent = (index: number): SubagentAccent =>
77
+ SUBAGENT_ACCENT_STYLES[index % SUBAGENT_ACCENT_STYLES.length] ?? SUBAGENT_ACCENT_STYLES[0]!
78
+
79
+ export const toSubagentAvatarText = (name: string) => {
80
+ const normalized = name.replace(/\s+/g, '').trim()
81
+ return Array.from(normalized || 'AG').slice(0, 2).join('')
82
+ }
83
+
84
+ export const resolveSubagentStatusMeta = (status: SubagentAgentStatus) => {
85
+ switch (status) {
86
+ case 'pendingInit':
87
+ return { color: 'primary', label: 'pending' }
88
+ case 'running':
89
+ return { color: 'info', label: 'running' }
90
+ case 'completed':
91
+ return { color: 'success', label: 'completed' }
92
+ case 'interrupted':
93
+ return { color: 'warning', label: 'interrupted' }
94
+ case 'errored':
95
+ return { color: 'error', label: 'errored' }
96
+ case 'shutdown':
97
+ return { color: 'neutral', label: 'shutdown' }
98
+ case 'notFound':
99
+ return { color: 'neutral', label: 'not found' }
100
+ default:
101
+ return { color: 'neutral', label: 'active' }
102
+ }
103
+ }
104
+
105
+ export const resolveSubagentPanelAutoOpen = (
106
+ input: SubagentPanelAutoOpenInput
107
+ ): SubagentPanelAutoOpenResult => {
108
+ if (!input.hasAvailableSubagents) {
109
+ return {
110
+ hasResolvedState: false,
111
+ previousActiveCount: 0,
112
+ nextOpen: false
113
+ }
114
+ }
115
+
116
+ if (!input.hasResolvedState) {
117
+ return {
118
+ hasResolvedState: true,
119
+ previousActiveCount: input.nextActiveCount,
120
+ nextOpen: input.isMobile ? false : input.nextActiveCount > 0
121
+ }
122
+ }
123
+
124
+ if (
125
+ !input.isMobile
126
+ && !input.hasUserToggled
127
+ && input.previousActiveCount === 0
128
+ && input.nextActiveCount > 0
129
+ ) {
130
+ return {
131
+ hasResolvedState: true,
132
+ previousActiveCount: input.nextActiveCount,
133
+ nextOpen: true
134
+ }
135
+ }
136
+
137
+ return {
138
+ hasResolvedState: true,
139
+ previousActiveCount: input.nextActiveCount,
140
+ nextOpen: null
141
+ }
142
+ }
143
+
144
+ export const resolveExpandedSubagentPanel = (
145
+ panels: VisualSubagentPanel[],
146
+ expandedThreadId: string | null
147
+ ) => {
148
+ if (!expandedThreadId) {
149
+ return null
150
+ }
151
+
152
+ return panels.find(panel => panel.threadId === expandedThreadId) ?? null
153
+ }
154
+
155
+ export const pruneExpandedSubagentThreadId = (
156
+ panels: VisualSubagentPanel[],
157
+ expandedThreadId: string | null
158
+ ) => resolveExpandedSubagentPanel(panels, expandedThreadId)?.threadId ?? null