projects, contexts continued

frdel committed Nov 4, 2025 at 13:05 UTC 1f37bcd844d28ba3fc25df5804491e0cc2ba4ea5
14 files changed +333 -240
python/helpers/task_scheduler.py
+1
@@ -776,6 +776,7 @@ class TaskScheduler:
776 self._printer.print(f"Scheduler Task '{current_task.name}' started")
777
778 context = await self._get_chat_context(current_task)
779 + AgentContext.use(context.id)
780
781 # Ensure the context is properly registered in the AgentContext._contexts
782 # This is critical for the polling mechanism to find and stream logs
webui/components/projects/project-create.html
+1 -1
@@ -3,7 +3,7 @@
3 <head>
4 <title>Create a new project</title>
5 <script type="module">
6 - import { store } from "/components/projects/projectsStore.js";
6 + import { store } from "/components/projects/projects-store.js";
7 </script>
8 </head>
9
webui/components/projects/project-edit-basic-data.html
+1 -1
@@ -3,7 +3,7 @@
3 <head>
4 <title>Project basic data</title>
5 <script type="module">
6 - import { store } from "/components/projects/projectsStore.js";
6 + import { store } from "/components/projects/projects-store.js";
7 </script>
8 </head>
9
webui/components/projects/project-edit-instructions.html
+1 -1
@@ -3,7 +3,7 @@
3 <head>
4 <title>Create a new project</title>
5 <script type="module">
6 - import { store } from "/components/projects/projectsStore.js";
6 + import { store } from "/components/projects/projects-store.js";
7 </script>
8 </head>
9
webui/components/projects/project-edit-memory.html new
+60
@@ -0,0 +1,60 @@
1 +<html>
2 +
3 +<head>
4 + <title>Create a new project</title>
5 + <script type="module">
6 + import { store } from "/components/projects/projects-store.js";
7 + </script>
8 +</head>
9 +
10 +<body>
11 + <div x-data>
12 + <template x-if="$store.projects && $store.projects.selectedProject">
13 + <div>
14 +
15 + <div class="projects-setting-row" style="padding: 1rem 0;">
16 + <div class="projects-setting-text">
17 + <label class="projects-form-label">Project-specific memory</label>
18 + <span class="projects-form-description">When turned on, the agent's memory while working on this
19 + project will be isolated from the global memory. The memory will be stored in <strong><span
20 + x-text="$store.projects.getSelectedAbsPath('.a0proj','memory')"></span></strong>.</span>
21 + </div>
22 + <div class="projects-setting-control">
23 + <label class="toggle">
24 + <input type="checkbox" x-model="$store.projects.selectedProject._ownMemory">
25 + <span class="toggler"></span>
26 + </label>
27 + </div>
28 + </div>
29 +
30 + <style>
31 + .projects-setting-row {
32 + display: flex;
33 + align-items: center;
34 + justify-content: space-between;
35 + gap: 2rem;
36 + }
37 + .projects-setting-text {
38 + flex-grow: 1;
39 + flex-shrink: 1;
40 + min-width: 0;
41 + }
42 + .projects-setting-control {
43 + flex-grow: 0;
44 + flex-shrink: 0;
45 + }
46 + .projects-form-label {
47 + display: block;
48 + }
49 + </style>
50 +
51 + </div>
52 +
53 +
54 + </template>
55 + </div>
56 +</body>
57 +<style>
58 +</style>
59 +
60 +</html>
\ No newline at end of file
webui/components/projects/project-edit-secrets.html
+1 -1
@@ -3,7 +3,7 @@
3 <head>
4 <title>Create a new project</title>
5 <script type="module">
6 - import { store } from "/components/projects/projectsStore.js";
6 + import { store } from "/components/projects/projects-store.js";
7 </script>
8 </head>
9
webui/components/projects/project-edit.html
+9 -1
@@ -3,7 +3,7 @@
3 <head>
4 <title>Edit project</title>
5 <script type="module">
6 - import { store } from "/components/projects/projectsStore.js";
6 + import { store } from "/components/projects/projects-store.js";
7 </script>
8 </head>
9
@@ -42,6 +42,14 @@
42 </x-component>
43 </div>
44
45 + <div class="project-detail">
46 + <div class="project-detail-header">
47 + <span class="projects-project-card-title">Memory</span>
48 + </div>
49 + <x-component path="projects/project-edit-memory.html">
50 + </x-component>
51 + </div>
52 +
53 <div class="project-detail">
54 <div class="project-detail-header">
55 <span class="projects-project-card-title">Secrets</span>
webui/components/projects/project-list.html
+4 -4
@@ -3,7 +3,7 @@
3 <head>
4 <title>Projects</title>
5 <script type="module">
6 - import { store as projectsStore } from "/components/projects/projectsStore.js";
6 + import { store as projectsStore } from "/components/projects/projects-store.js";
7 import { store as chatsStore } from "/components/sidebar/chats/chats-store.js";
8 </script>
9 </head>
@@ -16,7 +16,7 @@
16 instructions and files.
17 You can create projects for your tasks and switch between them easily.</p>
18 <div class="projects-list-header">
19 - <div x-show="$store.chats.selectedContext?.project" class="active-project-display">
19 + <div x-show="$store.chats.selectedContext && $store.chats.selectedContext?.project" class="active-project-display">
20 <span style="display: inline-flex; align-items: center; gap: 0.5em;">
21 <span>Active:</span>
22 <span class="project-color-ball" :style="$store.chats.selectedContext?.project?.color ? { backgroundColor: $store.chats.selectedContext?.project?.color } : { border: '1px solid var(--color-border)' }"></span>
@@ -46,12 +46,12 @@
46 <div class="projects-project-card-name">/<span x-text="project.name"></span></div>
47 </div>
48 <div class="projects-project-card-actions" style="display: flex; gap: 0.5em;">
49 - <template x-if="project.name === $store.chats.selectedContext?.project?.name">
49 + <template x-if="$store.chats.selectedContext && project.name === $store.chats.selectedContext?.project?.name">
50 <button type="button" class="button cancel" title="Deactivate" style="width:9em" @click="$store.projects.deactivateProject()">
51 <span class="icon material-symbols-outlined">close</span> Deactivate
52 </button>
53 </template>
54 - <template x-if="project.name !== $store.chats.selectedContext?.project?.name">
54 + <template x-if="$store.chats.selectedContext && project.name !== $store.chats.selectedContext?.project?.name">
55 <button type="button" class="button confirm" title="Activate" style="width:9em" @click="$store.projects.activateProject(project.name)">
56 <span class="icon material-symbols-outlined">play_arrow</span> Activate
57 </button>
webui/components/projects/project-selector.html
+5 -5
@@ -2,22 +2,22 @@
2
3 <head>
4 <script type="module">
5 - import { store as projectsStore } from "/components/projects/projectsStore.js";
5 + import { store as projectsStore } from "/components/projects/projects-store.js";
6 import { store as chatsStore } from "/components/sidebar/chats/chats-store.js";
7 </script>
8 </head>
9
10 <body>
11 <div x-data>
12 - <template x-if="$store.projects && $store.chats">
12 + <template x-if="$store.projects && $store.chats && $store.chats.selectedContext">
13 <div>
14 - <template x-if="$store.chats.selectedContext?.project?.name">
14 + <template x-if="$store.chats.selectedContext.project?.name">
15 <button @click="$store.projects.openProjectsModal()" type="button" class="button project-button">
16 <span class="project-color-ball" :style="$store.chats.selectedContext.project.color ? { backgroundColor: $store.chats.selectedContext.project.color } : { border: '1px solid var(--color-border)' }"></span>
17 - <span x-text="$store.chats.selectedContext?.project?.name"></span>
17 + <span x-text="$store.chats.selectedContext.project.name"></span>
18 </button>
19 </template>
20 - <template x-if="!$store.chats.selectedContext?.project?.name">
20 + <template x-if="!$store.chats.selectedContext.project?.name">
21 <button @click="$store.projects.openProjectsModal()" type="button" class="button project-button">
22 No project</button>
23 </template>
webui/components/projects/projects-store.js renamed
+7 -1
@@ -228,8 +228,12 @@ const model = {
228 // prepare data
229 const data = {
230 ...this.selectedProject,
231 - _meta: undefined,
231 + memory: this.selectedProject._ownMemory ? "own" : "global",
232 };
233 + // remove internal fields
234 + for (const kvp of Object.entries(data))
235 + if (kvp[0].startsWith("_")) delete data[kvp[0]];
236 +
237 // call backend
238 const response = await api.callJsonApi("projects", {
239 action: creating ? "create" : "update",
@@ -276,6 +280,7 @@ const model = {
280 _meta: {
281 creating: true,
282 },
283 + _ownMemory: true,
284 name: ``,
285 title: `Project #${this.projectList.length + 1}`,
286 description: "",
@@ -295,6 +300,7 @@ const model = {
300 creating: false,
301 },
302 ...projectData,
303 + _ownMemory: projectData.memory == "own",
304 };
305 },
306
webui/components/sidebar/chats/chats-store.js
+8 -2
@@ -26,7 +26,8 @@ const model = {
26 // Initialize from localStorage
27 const lastSelectedChat = localStorage.getItem("lastSelectedChat");
28 if (lastSelectedChat) {
29 - this.selected = lastSelectedChat;
29 + this.selectChat(lastSelectedChat);
30 + // this.selected = lastSelectedChat;
31 }
32 },
33
@@ -107,7 +108,8 @@ const model = {
108 await this.selectChat(alternateChat.id);
109 } else {
110 // If no other chats, create a new empty context
110 - await this.newChat();
111 + this.deselectChat();
112 + //await this.newChat();
113 }
114 },
115
@@ -158,6 +160,10 @@ const model = {
160 }
161 },
162
163 + deselectChat(){
164 + globalThis.deselectChat(); //TODO move here
165 + },
166 +
167 // Smoothly scroll the chats list to top if present
168 _scrollChatsToTop() {
169 const listEl = document.querySelector('#chats-section .chats-config-list');
webui/components/welcome/welcome-screen.html
+207 -207
@@ -1,241 +1,241 @@
1 <html>
2 - <head>
3 - <script type="module">
4 - import { store } from "/components/welcome/welcome-store.js";
5 - </script>
6 - </head>
7 - <body>
8 - <div x-data x-show="$store.welcomeStore && $store.welcomeStore.isVisible">
9 - <template x-if="$store.welcomeStore">
10 - <div x-data="$store.welcomeStore" class="welcome-container">
11 - <!-- Agent Zero Logo -->
12 - <div class="welcome-logo-container">
13 - <img
14 - src="./public/darkSymbol.svg"
15 - alt="Agent Zero Logo"
16 - class="welcome-logo"
17 - />
2 +
3 +<head>
4 + <script type="module">
5 + import { store } from "/components/welcome/welcome-store.js";
6 + </script>
7 +</head>
8 +
9 +<body>
10 + <div x-data x-show="$store.welcomeStore && $store.welcomeStore.isVisible">
11 + <template x-if="$store.welcomeStore">
12 + <div x-data="$store.welcomeStore" class="welcome-container">
13 + <!-- Agent Zero Logo -->
14 + <div class="welcome-logo-container">
15 + <img src="./public/darkSymbol.svg" alt="Agent Zero Logo" class="welcome-logo" />
16 + </div>
17 +
18 + <!-- Welcome Title -->
19 + <h1 class="welcome-title">Welcome to Agent Zero</h1>
20 + <p class="welcome-subtitle">
21 + Start a new conversation or explore the features below.
22 + </p>
23 +
24 + <!-- Action Cards -->
25 + <div class="welcome-actions">
26 + <div class="welcome-action-card" @click="executeAction('new-chat')">
27 + <span class="material-symbols-outlined welcome-action-icon">add_circle</span>
28 + <h3 class="welcome-action-title">New Chat</h3>
29 + <p class="welcome-action-description">
30 + Start a new conversation
31 + </p>
32 </div>
33
20 - <!-- Welcome Title -->
21 - <h1 class="welcome-title">Welcome to Agent Zero</h1>
22 - <p class="welcome-subtitle">
23 - Start a new conversation or explore the features below.
24 - </p>
25 -
26 - <!-- Action Cards -->
27 - <div class="welcome-actions">
28 - <div
29 - class="welcome-action-card"
30 - @click="executeAction('new-chat')"
31 - >
32 - <span
33 - class="material-symbols-outlined welcome-action-icon"
34 - >add_circle</span
35 - >
36 - <h3 class="welcome-action-title">New Chat</h3>
37 - <p class="welcome-action-description">
38 - Start a new conversation
39 - </p>
40 - </div>
41 - <div
42 - class="welcome-action-card"
43 - @click="executeAction('settings')"
44 - >
45 - <span
46 - class="material-symbols-outlined welcome-action-icon"
47 - >settings</span
48 - >
49 - <h3 class="welcome-action-title">Settings</h3>
50 - <p class="welcome-action-description">
51 - Configure Agent Zero
52 - </p>
53 - </div>
54 - <div
55 - class="welcome-action-card"
56 - @click="executeAction('website')"
57 - >
58 - <span
59 - class="material-symbols-outlined welcome-action-icon"
60 - >language</span
61 - >
62 - <h3 class="welcome-action-title">Visit Website</h3>
63 - <p class="welcome-action-description">
64 - Learn more about Agent Zero
65 - </p>
66 - </div>
67 - <div
68 - class="welcome-action-card"
69 - @click="executeAction('github')"
70 - >
71 - <span
72 - class="material-symbols-outlined welcome-action-icon"
73 - >code</span
74 - >
75 - <h3 class="welcome-action-title">Visit GitHub</h3>
76 - <p class="welcome-action-description">
77 - View source code and documentation
78 - </p>
79 - </div>
34 + <div class="welcome-action-card" @click="executeAction('projects')">
35 + <span class="material-symbols-outlined welcome-action-icon">folder</span>
36 + <h3 class="welcome-action-title">Projects</h3>
37 + <p class="welcome-action-description">
38 + Manage your projects
39 + </p>
40 + </div>
41 + <div class="welcome-action-card" @click="executeAction('memory')">
42 + <span class="material-symbols-outlined welcome-action-icon">memory</span>
43 + <h3 class="welcome-action-title">Memory</h3>
44 + <p class="welcome-action-description">
45 + Open Memory Dashboard
46 + </p>
47 + </div>
48 + <div class="welcome-action-card" @click="executeAction('settings')">
49 + <span class="material-symbols-outlined welcome-action-icon">settings</span>
50 + <h3 class="welcome-action-title">Settings</h3>
51 + <p class="welcome-action-description">
52 + Configure Agent Zero
53 + </p>
54 + </div>
55 + <div class="welcome-action-card" @click="executeAction('website')">
56 + <span class="material-symbols-outlined welcome-action-icon">language</span>
57 + <h3 class="welcome-action-title">Visit Website</h3>
58 + <p class="welcome-action-description">
59 + Learn more about Agent Zero
60 + </p>
61 + </div>
62 + <div class="welcome-action-card" @click="executeAction('github')">
63 + <span class="material-symbols-outlined welcome-action-icon">code</span>
64 + <h3 class="welcome-action-title">Visit GitHub</h3>
65 + <p class="welcome-action-description">
66 + View source code and documentation
67 + </p>
68 </div>
69 </div>
82 - </template>
83 - </div>
70 + </div>
71 + </template>
72 + </div>
73 +
74 + <style>
75 + /* Welcome Screen Styles */
76 + .welcome-container {
77 + display: flex;
78 + flex-direction: column;
79 + align-items: center;
80 + justify-content: center;
81 + padding: 3%;
82 + text-align: center;
83 + background: var(--color-background);
84 + color: var(--color-text);
85 + min-height: 100vh;
86 + }
87 +
88 + /* Welcome container styles */
89 + .welcome-logo-container {
90 + display: flex;
91 + justify-content: center;
92 + align-items: center;
93 + }
94 +
95 + .welcome-logo {
96 + width: 7rem;
97 + height: 7rem;
98 + }
99 +
100 + /* Themes adjustments for logo */
101 + .light-mode .welcome-logo {
102 + filter: invert(0.5);
103 + }
104 +
105 + .dark-mode .welcome-logo {
106 + filter: invert(0.8);
107 + }
108 +
109 + .welcome-title {
110 + font-size: 2rem;
111 + font-weight: 400;
112 + margin: var(--spacing-xs) 0 0 0;
113 + color: var(--color-text);
114 + }
115
85 - <style>
86 - /* Welcome Screen Styles */
116 + .welcome-action-title {
117 + margin-bottom: 0;
118 + }
119 +
120 + .welcome-subtitle {
121 + font-size: 1rem;
122 + margin-bottom: 2rem;
123 + color: var(--color-secondary);
124 + max-width: 600px;
125 + line-height: 1.5;
126 + }
127 +
128 + .welcome-actions {
129 + display: grid;
130 + grid-template-columns: repeat(3, 1fr);
131 + gap: 1.2rem;
132 + max-width: 520px;
133 + width: 100%;
134 + margin: 1.5rem 0;
135 + }
136 +
137 + .welcome-action-card {
138 + background: var(--color-panel);
139 + border: 1px solid var(--color-border);
140 + border-radius: 12px;
141 + padding: 1.5rem;
142 + transition: all 0.3s ease;
143 + cursor: pointer;
144 + text-decoration: none;
145 + color: inherit;
146 + display: flex;
147 + flex-direction: column;
148 + align-items: center;
149 + text-align: center;
150 + min-height: 10rem;
151 + justify-content: center;
152 + }
153 +
154 + .welcome-action-card:hover {
155 + border-color: var(--color-primary);
156 + background: var(--color-message-bg);
157 + }
158 +
159 + .welcome-action-icon {
160 + font-size: 2rem;
161 + margin-bottom: 0;
162 + color: var(--color-highlight-dark);
163 + }
164 +
165 + .welcome-action-description {
166 + font-size: 0.8rem;
167 + color: var(--color-secondary);
168 + line-height: 1.3;
169 + }
170 +
171 + /* Light mode adjustments */
172 + .light-mode .welcome-title {
173 + color: #2d2d2d;
174 + }
175 +
176 + .light-mode .welcome-subtitle {
177 + color: #666;
178 + }
179 +
180 + .light-mode .welcome-action-title {
181 + color: #2d2d2d;
182 + }
183 +
184 + .light-mode .welcome-action-description {
185 + color: #666;
186 + }
187 +
188 + .light-mode .welcome-footer {
189 + color: #666;
190 + }
191 +
192 + /* Responsive design */
193 + @media (max-width: 768px) {
194 .welcome-container {
88 - display: flex;
89 - flex-direction: column;
90 - align-items: center;
91 - justify-content: center;
92 - padding: 3%;
93 - text-align: center;
94 - background: var(--color-background);
95 - color: var(--color-text);
96 - min-height: 100vh;
97 - }
98 - /* Welcome container styles */
99 - .welcome-logo-container {
100 - display: flex;
101 - justify-content: center;
102 - align-items: center;
195 + padding: 1rem;
196 + padding-top: 3rem;
197 }
198
199 .welcome-logo {
106 - width: 7rem;
107 - height: 7rem;
200 + width: 5rem;
201 + height: 5rem;
202 }
203
110 - /* Themes adjustments for logo */
111 - .light-mode .welcome-logo {
112 - filter: invert(0.5);
113 - }
114 - .dark-mode .welcome-logo {
115 - filter: invert(0.8);
204 + .welcome-logo-container {
205 + margin-top: 2rem;
206 }
207
208 .welcome-title {
119 - font-size: 2rem;
120 - font-weight: 400;
121 - margin: var(--spacing-xs) 0 0 0;
122 - color: var(--color-text);
123 - }
124 -
125 - .welcome-action-title {
126 - margin-bottom: 0;
209 + font-size: 1.5rem;
210 + margin: 0 !important;
211 }
212
213 .welcome-subtitle {
214 font-size: 1rem;
131 - margin-bottom: 2rem;
132 - color: var(--color-secondary);
133 - max-width: 600px;
134 - line-height: 1.5;
215 + margin-top: var(--spacing-xs);
216 + margin-bottom: 0;
217 }
218
219 .welcome-actions {
138 - display: grid;
139 - grid-template-columns: repeat(2, 1fr);
140 - gap: 1.2rem;
141 - max-width: 520px;
142 - width: 100%;
143 - margin: 1.5rem 0;
220 + grid-template-columns: 1fr;
221 + gap: 1rem;
222 + margin-bottom: 2rem;
223 }
224
225 .welcome-action-card {
147 - background: var(--color-panel);
148 - border: 1px solid var(--color-border);
149 - border-radius: 12px;
226 padding: 1.5rem;
151 - transition: all 0.3s ease;
152 - cursor: pointer;
153 - text-decoration: none;
154 - color: inherit;
155 - display: flex;
156 - flex-direction: column;
157 - align-items: center;
158 - text-align: center;
159 - min-height: 10rem;
160 - justify-content: center;
161 - }
162 -
163 - .welcome-action-card:hover {
164 - border-color: var(--color-primary);
165 - background: var(--color-message-bg);
227 + min-height: 120px;
228 }
229
230 .welcome-action-icon {
231 font-size: 2rem;
170 - margin-bottom: 0;
171 - color: var(--color-highlight-dark);
172 - }
173 -
174 - .welcome-action-description {
175 - font-size: 0.8rem;
176 - color: var(--color-secondary);
177 - line-height: 1.3;
232 }
233
180 - /* Light mode adjustments */
181 - .light-mode .welcome-title {
182 - color: #2d2d2d;
183 - }
184 -
185 - .light-mode .welcome-subtitle {
186 - color: #666;
187 - }
188 -
189 - .light-mode .welcome-action-title {
190 - color: #2d2d2d;
191 - }
192 -
193 - .light-mode .welcome-action-description {
194 - color: #666;
195 - }
196 -
197 - .light-mode .welcome-footer {
198 - color: #666;
199 - }
200 -
201 - /* Responsive design */
202 - @media (max-width: 768px) {
203 - .welcome-container {
204 - padding: 1rem;
205 - padding-top: 3rem;
206 - }
207 - .welcome-logo {
208 - width: 5rem;
209 - height: 5rem;
210 - }
211 - .welcome-logo-container {
212 - margin-top: 2rem;
213 - }
214 - .welcome-title {
215 - font-size: 1.5rem;
216 - margin: 0 !important;
217 - }
218 - .welcome-subtitle {
219 - font-size: 1rem;
220 - margin-top: var(--spacing-xs);
221 - margin-bottom: 0;
222 - }
223 - .welcome-actions {
224 - grid-template-columns: 1fr;
225 - gap: 1rem;
226 - margin-bottom: 2rem;
227 - }
228 - .welcome-action-card {
229 - padding: 1.5rem;
230 - min-height: 120px;
231 - }
232 - .welcome-action-icon {
233 - font-size: 2rem;
234 - }
234 .welcome-action-title {
236 - font-size: 1.1rem;
235 + font-size: 1.1rem;
236 }
238 - }
239 - </style>
240 - </body>
241 -</html>
237 + }
238 + </style>
239 +</body>
240 +
241 +</html>
\ No newline at end of file
webui/components/welcome/welcome-store.js
+8
@@ -1,6 +1,8 @@
1 import { createStore } from "/js/AlpineStore.js";
2 import { getContext } from "/index.js";
3 import { store as chatsStore } from "/components/sidebar/chats/chats-store.js";
4 +import { store as memoryStore } from "/components/settings/memory/memory-dashboard-store.js";
5 +import { store as projectsStore } from "/components/projects/projects-store.js";
6
7 const model = {
8 // State
@@ -45,6 +47,12 @@ const model = {
47 settingsButton.click();
48 }
49 break;
50 + case "projects":
51 + projectsStore.openProjectsModal();
52 + break;
53 + case "memory":
54 + memoryStore.openModal();
55 + break;
56 case "website":
57 window.open("https://agent-zero.ai", "_blank");
58 break;
webui/index.js
+20 -16
@@ -154,15 +154,13 @@ export function updateChatInput(text) {
154 }
155
156 async function updateUserTime() {
157 -
157 let userTimeElement = document.getElementById("time-date");
158
160 - while(!userTimeElement){
159 + while (!userTimeElement) {
160 await sleep(100);
161 userTimeElement = document.getElementById("time-date");
162 }
163
165 -
164 const now = new Date();
165 const hours = now.getHours();
166 const minutes = now.getMinutes();
@@ -276,6 +274,12 @@ export async function poll() {
274 return false;
275 }
276
277 + // deselect chat if it is requested by the backend
278 + if (response.deselect_chat) {
279 + chatsStore.deselectChat();
280 + return
281 + }
282 +
283 if (
284 response.context != context &&
285 !(response.context === null && context === null) &&
@@ -356,21 +360,21 @@ export async function poll() {
360 tasksStore.setSelected(context);
361 }
362 } else {
359 - const welcomeStore =
360 - globalThis.Alpine && typeof globalThis.Alpine.store === "function"
361 - ? globalThis.Alpine.store("welcomeStore")
362 - : null;
363 - const welcomeVisible = Boolean(welcomeStore && welcomeStore.isVisible);
364 -
365 - // No context selected, try to select the first available item unless welcome screen is active
366 - if (!welcomeVisible && contexts.length > 0) {
367 - const firstChatId = chatsStore.firstId();
368 - if (firstChatId) {
369 - setContext(firstChatId);
370 - chatsStore.setSelected(firstChatId);
363 + const welcomeStore =
364 + globalThis.Alpine && typeof globalThis.Alpine.store === "function"
365 + ? globalThis.Alpine.store("welcomeStore")
366 + : null;
367 + const welcomeVisible = Boolean(welcomeStore && welcomeStore.isVisible);
368 +
369 + // No context selected, try to select the first available item unless welcome screen is active
370 + if (!welcomeVisible && contexts.length > 0) {
371 + const firstChatId = chatsStore.firstId();
372 + if (firstChatId) {
373 + setContext(firstChatId);
374 + chatsStore.setSelected(firstChatId);
375 + }
376 }
377 }
373 - }
378
379 lastLogVersion = response.log_version;
380 lastLogGuid = response.log_guid;