anentrypoint-design 0.0.460 → 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.460",
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';
@@ -57,6 +57,8 @@ function applyEnvelope(msgs, env, sendApprove) {
57
57
  }
58
58
  } else if (event === 'steer.append') {
59
59
  if (!isDupUser(data.text)) msgs.push({ id: 'u' + msgs.length + env.ts, role: 'user', content: data.text || '', time: formatTime(ts) });
60
+ } else if (event === 'queue.append') {
61
+ if (!isDupUser(data.text)) msgs.push({ id: 'u' + msgs.length + env.ts, role: 'user', content: data.text || '', time: formatTime(ts) });
60
62
  } else if (event === 'assistant.delta') {
61
63
  // Progressive text mid-turn: accumulate into the live bubble; the
62
64
  // settled message.append at turn end overwrites with the authoritative
@@ -84,7 +86,20 @@ function applyEnvelope(msgs, env, sendApprove) {
84
86
  }
85
87
 
86
88
  export const chat = makePage((ctx) => {
87
- 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
+ }
88
103
 
89
104
  // Offline outbox: a prompt sent while genuinely offline queues to
90
105
  // IndexedDB and auto-flushes on the real 'online' event via the legacy
@@ -142,6 +157,8 @@ export const chat = makePage((ctx) => {
142
157
  if (f.error && !c.error) c.error = f.error;
143
158
  }
144
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 */ });
145
162
  } else if (f.type === 'error') {
146
163
  const c = cur();
147
164
  if (c && c.role === 'assistant') c.error = f.error;
@@ -166,10 +183,10 @@ export const chat = makePage((ctx) => {
166
183
  const t = (typeof text === 'string' ? text : s().draft || '').trim();
167
184
  if (!t) return;
168
185
 
169
- // Mid-turn send = STEER (kimi's steering): injected at the next step
170
- // boundary instead of starting a parallel turn.
186
+ // Mid-turn send = QUEUE for after the turn (kimi 1.31's Enter channel);
187
+ // injection mid-turn is /steer in the REPL or a wire steer frame.
171
188
  if (s().busy) {
172
- if (sendFrame({ type: 'steer', text: t })) {
189
+ if (sendFrame({ type: 'queue', text: t })) {
173
190
  s().messages = [...s().messages, { id: 'u' + Date.now(), role: 'user', content: t, time: formatTime(Date.now()) }];
174
191
  ctx.set({ draft: '' });
175
192
  }
@@ -206,13 +223,21 @@ export const chat = makePage((ctx) => {
206
223
  return () => {
207
224
  const st = s();
208
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,
209
234
  AgentChat({
210
235
  messages: st.messages,
211
236
  busy: st.busy,
212
237
  draft: st.draft,
213
238
  status: st.busy ? 'streaming…' : (st.conn === 'open' ? 'ready' : 'connecting…'),
214
239
  agentName: 'freddie',
215
- placeholder: st.busy ? 'steer the turn… (or stop)' : 'message…',
240
+ placeholder: st.busy ? 'queue a follow-up… (or stop)' : 'message…',
216
241
  showMinimap: true,
217
242
  banners: st.error ? [noteAlert({ kind: 'error', msg: st.error })] : [],
218
243
  onInput: (v) => { st.draft = v; },