anentrypoint-design 0.0.461 → 0.0.462

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "anentrypoint-design",
3
- "version": "0.0.461",
3
+ "version": "0.0.462",
4
4
  "description": "247420 design system SDK — webjsx + modified ripple-ui, single-file ESM bundle for reproducible use of the AnEntrypoint design.",
5
5
  "type": "module",
6
6
  "main": "./dist/247420.js",
@@ -17,7 +17,7 @@
17
17
 
18
18
  import * as webjsx from '../../../vendor/webjsx/index.js';
19
19
  import { makePage, api, loadingState, emptyState } from './runtime.js';
20
- import { Table, PageHeader } from '../content.js';
20
+ import { Table, PageHeader, Select } from '../content.js';
21
21
  import { Chip } from '../shell.js';
22
22
  import { formatTime } from '../../locale.js';
23
23
  import { queueMessage, watchReconnect, isOnline } from '../../idb-outbox.js';
@@ -86,7 +86,20 @@ function applyEnvelope(msgs, env, sendApprove) {
86
86
  }
87
87
 
88
88
  export const chat = makePage((ctx) => {
89
- Object.assign(ctx.state, { loading: false, messages: [], draft: '', busy: false, error: null, sessionId: null, ws: null, conn: 'closed' });
89
+ Object.assign(ctx.state, { loading: false, messages: [], draft: '', busy: false, error: null, sessionId: null, ws: null, conn: 'closed', sessions: [] });
90
+
91
+ // Session picker (kimi web's sessions sidebar, compact form): recent
92
+ // conversations from /api/sessions, needsInput badges included. Picking
93
+ // one reconnects the WS under that id and rebuilds from server replay.
94
+ api('/api/sessions').then(rows => { ctx.state.sessions = Array.isArray(rows) ? rows : []; ctx.rerender(); }).catch(() => { /* swallow: picker degrades to new-chat-only */ });
95
+
96
+ function switchSession(id) {
97
+ const st = ctx.state;
98
+ if (!id || id === st.sessionId) return;
99
+ try { st.ws && st.ws.close(); } catch { /* already closed */ }
100
+ ctx.set({ sessionId: id, messages: [], ws: null, conn: 'closed', busy: false, error: null });
101
+ ensureWs();
102
+ }
90
103
 
91
104
  // Offline outbox: a prompt sent while genuinely offline queues to
92
105
  // IndexedDB and auto-flushes on the real 'online' event via the legacy
@@ -144,6 +157,8 @@ export const chat = makePage((ctx) => {
144
157
  if (f.error && !c.error) c.error = f.error;
145
158
  }
146
159
  ctx.set({ busy: false });
160
+ // New turns can create/rename sessions — refresh the picker.
161
+ api('/api/sessions').then(rows => { ctx.state.sessions = Array.isArray(rows) ? rows : []; ctx.rerender(); }).catch(() => { /* swallow: picker refresh is best-effort */ });
147
162
  } else if (f.type === 'error') {
148
163
  const c = cur();
149
164
  if (c && c.role === 'assistant') c.error = f.error;
@@ -208,6 +223,14 @@ export const chat = makePage((ctx) => {
208
223
  return () => {
209
224
  const st = s();
210
225
  return h('div', { class: 'fd-chat' },
226
+ st.sessions.length ? h('div', { class: 'fd-chat-picker' },
227
+ Select({
228
+ value: st.sessionId || '',
229
+ placeholder: 'new conversation',
230
+ 'aria-label': 'switch conversation',
231
+ options: st.sessions.map(row => ({ value: row.id, label: (row.title || '(untitled)').slice(0, 60) + (row.needsInput ? ' — needs input' : '') })),
232
+ onChange: switchSession,
233
+ })) : null,
211
234
  AgentChat({
212
235
  messages: st.messages,
213
236
  busy: st.busy,