iris-chatbot 2.0.0 → 4.0.0

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": "iris-chatbot",
3
- "version": "2.0.0",
3
+ "version": "4.0.0",
4
4
  "private": false,
5
5
  "description": "One-command installer for the Iris project template.",
6
6
  "bin": {
@@ -1,6 +1,6 @@
1
1
  /// <reference types="next" />
2
2
  /// <reference types="next/image-types/global" />
3
- import "./.next/types/routes.d.ts";
3
+ import "./.next/dev/types/routes.d.ts";
4
4
 
5
5
  // NOTE: This file should not be edited
6
6
  // see https://nextjs.org/docs/app/api-reference/config/typescript for more information.
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "iris",
3
- "version": "2.0.0",
3
+ "version": "4.0.0",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "iris",
9
- "version": "2.0.0",
9
+ "version": "4.0.0",
10
10
  "dependencies": {
11
11
  "@anthropic-ai/sdk": "^0.72.1",
12
12
  "clsx": "^2.1.1",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "iris",
3
- "version": "2.0.0",
3
+ "version": "4.0.0",
4
4
  "private": true,
5
5
  "description": "One-command installer for the Iris project template.",
6
6
  "engines": {
@@ -784,8 +784,8 @@ a {
784
784
  height: 38px;
785
785
  width: 38px;
786
786
  border-radius: 12px;
787
- border: 1px solid var(--border);
788
- background: var(--panel-2);
787
+ border: 1px solid transparent;
788
+ background: transparent;
789
789
  color: var(--text-secondary);
790
790
  display: flex;
791
791
  align-items: center;
@@ -794,7 +794,7 @@ a {
794
794
  }
795
795
 
796
796
  .sidebar-icon-button:hover {
797
- border-color: var(--border-strong);
797
+ border-color: var(--border);
798
798
  color: var(--text-primary);
799
799
  transform: translateY(-1px);
800
800
  }
@@ -132,6 +132,11 @@ export default function Home() {
132
132
  [threads, activeThreadId]
133
133
  );
134
134
 
135
+ const sidebarThreads = useMemo(
136
+ () => threads?.filter((t) => t.headMessageId != null) ?? [],
137
+ [threads]
138
+ );
139
+
135
140
  const conversationMessages = useConversationMessages(
136
141
  activeThread?.conversationId || null
137
142
  );
@@ -333,11 +338,23 @@ export default function Home() {
333
338
  }
334
339
  >
335
340
  <Sidebar
336
- threads={threads || []}
341
+ threads={sidebarThreads}
337
342
  activeThreadId={activeThreadId}
338
343
  collapsed={sidebarCollapsed}
339
- onSelect={(id) => setActiveThreadId(id)}
344
+ onSelect={async (id) => {
345
+ if (id !== activeThreadId) {
346
+ const prev = threads?.find((t) => t.id === activeThreadId);
347
+ if (prev?.headMessageId == null) {
348
+ await deleteThread(prev.id);
349
+ }
350
+ }
351
+ setActiveThreadId(id);
352
+ }}
340
353
  onNewChat={async () => {
354
+ const prev = threads?.find((t) => t.id === activeThreadId);
355
+ if (prev?.headMessageId == null) {
356
+ await deleteThread(prev.id);
357
+ }
341
358
  const thread = await createNewThread();
342
359
  setViewMode("chat");
343
360
  setActiveThreadId(thread.id);
@@ -432,7 +449,7 @@ export default function Home() {
432
449
  ) : null}
433
450
  {searchOpen ? (
434
451
  <SearchModal
435
- threads={threads || []}
452
+ threads={sidebarThreads}
436
453
  onClose={() => setSearchOpen(false)}
437
454
  onSelect={(id) => {
438
455
  setActiveThreadId(id);
@@ -1,6 +1,5 @@
1
1
  "use client";
2
2
 
3
- import { ArrowDown } from "lucide-react";
4
3
  import { useCallback, useEffect, useMemo, useRef, useState } from "react";
5
4
  import type {
6
5
  ChatCitationSource,
@@ -27,6 +26,7 @@ import {
27
26
  } from "../lib/memory";
28
27
  import { useUIStore } from "../lib/store";
29
28
  import { toChatConnectionPayload } from "../lib/connections";
29
+ import { ArrowDown } from "lucide-react";
30
30
  import MessageCard from "./MessageCard";
31
31
  import Composer from "./Composer";
32
32
 
@@ -1506,9 +1506,9 @@ export default function ChatView({
1506
1506
  {threadMessages.length > 0 ? (
1507
1507
  <>
1508
1508
  {showJumpToBottom ? (
1509
- <div className="pointer-events-none absolute bottom-24 right-8 z-30">
1509
+ <div className="pointer-events-none absolute bottom-28 left-1/2 z-30 -translate-x-1/2 opacity-80 transition-opacity duration-200">
1510
1510
  <button
1511
- className="pointer-events-auto inline-flex h-11 w-11 items-center justify-center rounded-full border border-[var(--border-strong)] bg-[var(--panel)] text-[var(--text-primary)] shadow-[var(--shadow)] transition hover:translate-y-[1px] hover:border-[var(--accent)]"
1511
+ className="pointer-events-auto inline-flex h-9 w-9 items-center justify-center rounded-full border border-[var(--border-strong)] bg-[var(--panel)] text-[var(--text-primary)] shadow-[var(--shadow)] transition hover:translate-y-[1px] hover:border-[var(--accent)] hover:opacity-100"
1512
1512
  onClick={() => {
1513
1513
  shouldStickToBottomRef.current = true;
1514
1514
  setShowJumpToBottom(false);
@@ -1518,7 +1518,7 @@ export default function ChatView({
1518
1518
  aria-label="Jump to latest message"
1519
1519
  title="Jump to latest"
1520
1520
  >
1521
- <ArrowDown className="h-5 w-5" />
1521
+ <ArrowDown className="h-4 w-4" />
1522
1522
  </button>
1523
1523
  </div>
1524
1524
  ) : null}
@@ -90,23 +90,33 @@ export default function Sidebar({
90
90
  {groups.map(({ root }) => (
91
91
  <div key={root.id} className="space-y-1">
92
92
  <div
93
- className={`group flex h-11 items-center justify-between rounded-lg px-3 text-sm transition ${
93
+ role="button"
94
+ tabIndex={0}
95
+ onClick={() => onSelect(root.id)}
96
+ onKeyDown={(e) => {
97
+ if (e.key === "Enter" || e.key === " ") {
98
+ e.preventDefault();
99
+ onSelect(root.id);
100
+ }
101
+ }}
102
+ className={`group flex h-11 cursor-pointer items-center justify-between rounded-lg px-3 text-sm transition ${
94
103
  activeThreadId === root.id
95
104
  ? "bg-[var(--panel-2)] text-[var(--text-primary)]"
96
105
  : "text-[var(--text-secondary)] hover:bg-[var(--panel)]"
97
106
  }`}
98
107
  >
99
- <button
100
- onClick={() => onSelect(root.id)}
101
- className="flex min-w-0 flex-1 items-center gap-2 text-left"
102
- >
108
+ <div className="flex min-w-0 flex-1 items-center gap-2">
103
109
  <Folder className="h-4 w-4 shrink-0 text-[var(--text-muted)]" />
104
110
  <div className="sidebar-text min-w-0 truncate">
105
111
  {root.title || "Main chat"}
106
112
  </div>
107
- </button>
113
+ </div>
108
114
  <button
109
- onClick={() => onDeleteThread(root)}
115
+ type="button"
116
+ onClick={(e) => {
117
+ e.stopPropagation();
118
+ onDeleteThread(root);
119
+ }}
110
120
  className="ml-2 rounded-full border border-transparent p-1 text-[var(--text-muted)] opacity-0 transition hover:border-[var(--border)] hover:text-[var(--danger)] group-hover:opacity-100"
111
121
  >
112
122
  <Trash2 className="h-3 w-3" />