@bibobonking/opensol 3.0.3 → 3.1.1
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/.github/workflows/build.yml +60 -8
- package/CHANGELOG.md +21 -0
- package/README.md +2 -2
- package/desktop/README.md +39 -0
- package/desktop/loading/index.html +36 -0
- package/desktop/src-tauri/Cargo.lock +4301 -0
- package/desktop/src-tauri/Cargo.toml +23 -0
- package/desktop/src-tauri/binaries/.gitkeep +0 -0
- package/desktop/src-tauri/build.rs +3 -0
- package/desktop/src-tauri/capabilities/default.json +7 -0
- package/desktop/src-tauri/icons/128x128.png +0 -0
- package/desktop/src-tauri/icons/128x128@2x.png +0 -0
- package/desktop/src-tauri/icons/32x32.png +0 -0
- package/desktop/src-tauri/icons/64x64.png +0 -0
- package/desktop/src-tauri/icons/Square107x107Logo.png +0 -0
- package/desktop/src-tauri/icons/Square142x142Logo.png +0 -0
- package/desktop/src-tauri/icons/Square150x150Logo.png +0 -0
- package/desktop/src-tauri/icons/Square284x284Logo.png +0 -0
- package/desktop/src-tauri/icons/Square30x30Logo.png +0 -0
- package/desktop/src-tauri/icons/Square310x310Logo.png +0 -0
- package/desktop/src-tauri/icons/Square44x44Logo.png +0 -0
- package/desktop/src-tauri/icons/Square71x71Logo.png +0 -0
- package/desktop/src-tauri/icons/Square89x89Logo.png +0 -0
- package/desktop/src-tauri/icons/StoreLogo.png +0 -0
- package/desktop/src-tauri/icons/icon.icns +0 -0
- package/desktop/src-tauri/icons/icon.ico +0 -0
- package/desktop/src-tauri/icons/icon.png +0 -0
- package/desktop/src-tauri/src/lib.rs +210 -0
- package/desktop/src-tauri/src/main.rs +6 -0
- package/desktop/src-tauri/tauri.conf.json +48 -0
- package/dist/assets/index-CeN54A2N.css +1 -0
- package/dist/assets/index-fhIO9a7_.js +318 -0
- package/dist/index.html +4 -4
- package/index.html +2 -2
- package/package.json +2 -1
- package/server/README.md +2 -2
- package/server/daemon.mjs +138 -2
- package/server/lib/mcp-oauth.mjs +219 -0
- package/server/lib/mcp-oauth.test.mjs +175 -0
- package/server/lib/mcp.mjs +899 -0
- package/server/lib/mcp.test.mjs +46 -0
- package/server/lib/store.mjs +22 -0
- package/server/lib/tools.mjs +59 -1
- package/src/App.tsx +2 -0
- package/src/agent/tools.ts +6 -5
- package/src/components/CommandPalette.tsx +14 -1
- package/src/components/Composer.tsx +22 -38
- package/src/components/DiffView.tsx +98 -0
- package/src/components/Logo.tsx +1 -1
- package/src/components/McpPanel.tsx +687 -0
- package/src/components/MessageItem.tsx +62 -13
- package/src/components/ModelDeck.tsx +661 -0
- package/src/components/SessionsTab.tsx +206 -0
- package/src/components/SettingsModal.tsx +146 -71
- package/src/components/Sidebar.tsx +79 -24
- package/src/components/Splash.tsx +1 -1
- package/src/components/ToolCallCard.tsx +29 -7
- package/src/components/WorkspacePanel.tsx +16 -1
- package/src/core/kernel.ts +2 -0
- package/src/core/mcp-tools.ts +63 -0
- package/src/core/plugins/tools/fs.ts +24 -3
- package/src/core/services/agent-loop.ts +3 -1
- package/src/core/services/approval.ts +2 -1
- package/src/core/services/titles.ts +135 -0
- package/src/core/services/tools.ts +11 -8
- package/src/core/types.ts +4 -0
- package/src/data/providers.ts +1 -1
- package/src/index.css +97 -1
- package/src/lib/daemon.ts +38 -0
- package/src/lib/diff.ts +62 -0
- package/src/lib/mcp-config.test.mjs +47 -0
- package/src/lib/mcp-config.ts +203 -0
- package/src/lib/permissions.ts +6 -6
- package/src/store/chats.ts +9 -1
- package/src/store/mcp.ts +94 -0
- package/src/store/settings.ts +10 -7
- package/src/store/ui.ts +17 -0
- package/src/store/workspace.ts +26 -0
- package/src/types.ts +63 -2
- package/tsconfig.tsbuildinfo +1 -1
- package/dist/assets/index-BmN7pBji.css +0 -1
- package/dist/assets/index-DgNDjkOz.js +0 -301
- package/src/components/ModelPicker.tsx +0 -487
|
@@ -21,7 +21,8 @@ import { createId, useChats } from '../store/chats'
|
|
|
21
21
|
import { toolLabel } from '../agent/tools'
|
|
22
22
|
import { formatBytes, cn } from '../lib/utils'
|
|
23
23
|
import { Markdown } from './Markdown'
|
|
24
|
-
import { ToolCallCard } from './ToolCallCard'
|
|
24
|
+
import { ToolCallCard, diffForTool } from './ToolCallCard'
|
|
25
|
+
import { DiffBadge } from './DiffView'
|
|
25
26
|
import { ArrowRight } from 'lucide-react'
|
|
26
27
|
import { LogoMark } from './Logo'
|
|
27
28
|
|
|
@@ -168,7 +169,15 @@ function changedFiles(tools: ToolMessage[]): string[] {
|
|
|
168
169
|
}
|
|
169
170
|
|
|
170
171
|
/** Lets the person roll back every file the agent wrote or edited during one turn. */
|
|
171
|
-
function UndoBar({
|
|
172
|
+
function UndoBar({
|
|
173
|
+
turnId,
|
|
174
|
+
files,
|
|
175
|
+
diff,
|
|
176
|
+
}: {
|
|
177
|
+
turnId: string
|
|
178
|
+
files: string[]
|
|
179
|
+
diff: { added: number; removed: number } | null
|
|
180
|
+
}) {
|
|
172
181
|
const askConfirm = useUi((state) => state.askConfirm)
|
|
173
182
|
const notify = useUi((state) => state.notify)
|
|
174
183
|
const [state, setState] = useState<'idle' | 'working' | 'undone'>('idle')
|
|
@@ -204,6 +213,7 @@ function UndoBar({ turnId, files }: { turnId: string; files: string[] }) {
|
|
|
204
213
|
<span className="min-w-0 truncate">
|
|
205
214
|
{state === 'undone' ? 'Changes undone' : `Changed ${shown}${rest > 0 ? ` and ${rest} more` : ''}`}
|
|
206
215
|
</span>
|
|
216
|
+
{state !== 'undone' && diff && <DiffBadge added={diff.added} removed={diff.removed} className="shrink-0" />}
|
|
207
217
|
{state !== 'undone' && (
|
|
208
218
|
<button
|
|
209
219
|
type="button"
|
|
@@ -218,6 +228,48 @@ function UndoBar({ turnId, files }: { turnId: string; files: string[] }) {
|
|
|
218
228
|
)
|
|
219
229
|
}
|
|
220
230
|
|
|
231
|
+
function ThoughtToggle({ text }: { text: string }) {
|
|
232
|
+
const [open, setOpen] = useState(false)
|
|
233
|
+
return (
|
|
234
|
+
<div>
|
|
235
|
+
<button
|
|
236
|
+
type="button"
|
|
237
|
+
onClick={() => setOpen((value) => !value)}
|
|
238
|
+
className="group/think flex max-w-full items-baseline gap-1.5 py-0.5 text-left text-[12px]"
|
|
239
|
+
aria-expanded={open}
|
|
240
|
+
>
|
|
241
|
+
<ArrowRight
|
|
242
|
+
size={11}
|
|
243
|
+
strokeWidth={2}
|
|
244
|
+
className={cn('relative top-[1px] shrink-0 self-center text-faint transition-transform duration-200 ease-out', open && 'rotate-90')}
|
|
245
|
+
/>
|
|
246
|
+
<span className="shrink-0 font-medium text-muted group-hover/think:text-ink">Thought</span>
|
|
247
|
+
{!open && <span className="min-w-0 truncate text-[11px] text-faint">{text.replace(/\s+/g, ' ').trim().slice(0, 100)}</span>}
|
|
248
|
+
</button>
|
|
249
|
+
{open && (
|
|
250
|
+
<div className="thin-scroll animate-fade max-h-40 overflow-y-auto whitespace-pre-wrap pl-[17px] font-mono text-[11px] leading-relaxed text-faint">
|
|
251
|
+
{text}
|
|
252
|
+
</div>
|
|
253
|
+
)}
|
|
254
|
+
</div>
|
|
255
|
+
)
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
function totalDiff(tools: ToolMessage[]) {
|
|
259
|
+
let added = 0
|
|
260
|
+
let removed = 0
|
|
261
|
+
let any = false
|
|
262
|
+
for (const tool of tools) {
|
|
263
|
+
if (!FILE_EDIT_TOOLS.has(tool.call.name)) continue
|
|
264
|
+
const diff = diffForTool(tool)
|
|
265
|
+
if (!diff) continue
|
|
266
|
+
any = true
|
|
267
|
+
added += diff.added
|
|
268
|
+
removed += diff.removed
|
|
269
|
+
}
|
|
270
|
+
return any ? { added, removed } : null
|
|
271
|
+
}
|
|
272
|
+
|
|
221
273
|
export function TaskCompletedBox({
|
|
222
274
|
tools,
|
|
223
275
|
intermediateMessages = [],
|
|
@@ -291,6 +343,10 @@ export function TaskCompletedBox({
|
|
|
291
343
|
{summary ? ` (${summary})` : ''}
|
|
292
344
|
</span>
|
|
293
345
|
{failed > 0 && <span className="shrink-0 text-[12px] text-danger">· {failed} failed</span>}
|
|
346
|
+
{(() => {
|
|
347
|
+
const total = totalDiff(tools)
|
|
348
|
+
return total ? <DiffBadge added={total.added} removed={total.removed} className="shrink-0 text-[11.5px]" /> : null
|
|
349
|
+
})()}
|
|
294
350
|
</button>
|
|
295
351
|
|
|
296
352
|
{open && (
|
|
@@ -300,11 +356,7 @@ export function TaskCompletedBox({
|
|
|
300
356
|
<ToolCallCard key={item.tool.id} message={item.tool} compact={!detailed} />
|
|
301
357
|
) : (
|
|
302
358
|
<div key={item.message.id} className="py-1">
|
|
303
|
-
{item.message.reasoning.trim() &&
|
|
304
|
-
<div className="thin-scroll max-h-40 overflow-y-auto whitespace-pre-wrap font-mono text-[11px] leading-relaxed text-faint">
|
|
305
|
-
{item.message.reasoning}
|
|
306
|
-
</div>
|
|
307
|
-
)}
|
|
359
|
+
{item.message.reasoning.trim() && <ThoughtToggle text={item.message.reasoning} />}
|
|
308
360
|
{item.message.content.trim() && (
|
|
309
361
|
<div className="mt-1 text-[12.5px] leading-relaxed text-muted">
|
|
310
362
|
<Markdown content={item.message.content} />
|
|
@@ -347,7 +399,8 @@ export function AssistantBlock({
|
|
|
347
399
|
message.provider ? state.byProvider[message.provider] : undefined,
|
|
348
400
|
)
|
|
349
401
|
const [copied, setCopied] = useState(false)
|
|
350
|
-
|
|
402
|
+
// Thoughts stay closed until the person opens them, even while the model is still thinking.
|
|
403
|
+
const [reasoningOpen, setReasoningOpen] = useState(false)
|
|
351
404
|
const hasBody = Boolean(message.content.trim() || message.reasoning.trim() || message.error)
|
|
352
405
|
const modelName =
|
|
353
406
|
providerModels?.find((model) => model.id === message.model)?.name ?? message.model ?? ''
|
|
@@ -368,10 +421,6 @@ export function AssistantBlock({
|
|
|
368
421
|
.filter(Boolean)
|
|
369
422
|
.join(' · ')
|
|
370
423
|
|
|
371
|
-
useEffect(() => {
|
|
372
|
-
if (streaming) setReasoningOpen(true)
|
|
373
|
-
}, [streaming])
|
|
374
|
-
|
|
375
424
|
const copy = async () => {
|
|
376
425
|
try {
|
|
377
426
|
await navigator.clipboard.writeText(message.content)
|
|
@@ -648,7 +697,7 @@ export function TurnBlock({
|
|
|
648
697
|
)}
|
|
649
698
|
|
|
650
699
|
{turn.user && changedFiles(allTools).length > 0 && (
|
|
651
|
-
<UndoBar turnId={turn.user.id} files={changedFiles(allTools)} />
|
|
700
|
+
<UndoBar turnId={turn.user.id} files={changedFiles(allTools)} diff={totalDiff(allTools)} />
|
|
652
701
|
)}
|
|
653
702
|
</div>
|
|
654
703
|
)
|