@myrialabs/clopen 0.0.8 → 0.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/backend/index.ts +9 -0
- package/backend/lib/chat/stream-manager.ts +130 -10
- package/backend/lib/database/queries/message-queries.ts +47 -0
- package/backend/lib/engine/adapters/claude/stream.ts +65 -1
- package/backend/lib/engine/adapters/opencode/message-converter.ts +35 -77
- package/backend/lib/engine/types.ts +6 -0
- package/backend/lib/files/file-operations.ts +2 -2
- package/backend/lib/files/file-reading.ts +2 -2
- package/backend/lib/files/path-browsing.ts +2 -2
- package/backend/lib/terminal/pty-session-manager.ts +1 -1
- package/backend/lib/terminal/shell-utils.ts +4 -4
- package/backend/ws/chat/background.ts +3 -0
- package/backend/ws/chat/stream.ts +43 -1
- package/bin/clopen.ts +10 -0
- package/bun.lock +259 -381
- package/frontend/lib/components/chat/ChatInterface.svelte +8 -1
- package/frontend/lib/components/chat/formatters/MessageFormatter.svelte +20 -0
- package/frontend/lib/components/chat/formatters/TextMessage.svelte +3 -15
- package/frontend/lib/components/chat/formatters/Tools.svelte +15 -8
- package/frontend/lib/components/chat/input/ChatInput.svelte +70 -21
- package/frontend/lib/components/chat/input/components/LoadingIndicator.svelte +23 -11
- package/frontend/lib/components/chat/input/composables/use-chat-actions.svelte.ts +1 -1
- package/frontend/lib/components/chat/message/ChatMessage.svelte +13 -1
- package/frontend/lib/components/chat/message/ChatMessages.svelte +2 -2
- package/frontend/lib/components/chat/message/DateSeparator.svelte +1 -1
- package/frontend/lib/components/chat/message/MessageBubble.svelte +2 -2
- package/frontend/lib/components/chat/message/MessageHeader.svelte +14 -12
- package/frontend/lib/components/chat/tools/AgentTool.svelte +95 -0
- package/frontend/lib/components/chat/tools/AskUserQuestionTool.svelte +396 -0
- package/frontend/lib/components/chat/tools/BashTool.svelte +9 -4
- package/frontend/lib/components/chat/tools/EnterPlanModeTool.svelte +24 -0
- package/frontend/lib/components/chat/tools/ExitPlanModeTool.svelte +4 -7
- package/frontend/lib/components/chat/tools/{KillShellTool.svelte → TaskStopTool.svelte} +6 -6
- package/frontend/lib/components/chat/tools/index.ts +5 -2
- package/frontend/lib/components/checkpoint/TimelineModal.svelte +7 -2
- package/frontend/lib/components/history/HistoryModal.svelte +13 -5
- package/frontend/lib/components/workspace/DesktopNavigator.svelte +2 -1
- package/frontend/lib/components/workspace/MobileNavigator.svelte +2 -1
- package/frontend/lib/services/chat/chat.service.ts +146 -12
- package/frontend/lib/stores/core/app.svelte.ts +77 -0
- package/frontend/lib/utils/chat/message-grouper.ts +94 -12
- package/frontend/lib/utils/chat/message-processor.ts +37 -4
- package/frontend/lib/utils/chat/tool-handler.ts +96 -5
- package/package.json +4 -4
- package/shared/constants/engines.ts +1 -1
- package/shared/types/database/schema.ts +1 -0
- package/shared/types/messaging/index.ts +15 -13
- package/shared/types/messaging/tool.ts +185 -361
- package/shared/utils/message-formatter.ts +1 -0
|
@@ -82,6 +82,7 @@ export const backgroundHandler = createRouter()
|
|
|
82
82
|
processId: t.String(),
|
|
83
83
|
messages: t.Array(t.Any()),
|
|
84
84
|
currentPartialText: t.Optional(t.String()),
|
|
85
|
+
currentReasoningText: t.Optional(t.String()),
|
|
85
86
|
error: t.Optional(t.String()),
|
|
86
87
|
startedAt: t.String(),
|
|
87
88
|
completedAt: t.Optional(t.String())
|
|
@@ -106,6 +107,7 @@ export const backgroundHandler = createRouter()
|
|
|
106
107
|
processId: '',
|
|
107
108
|
messages: [],
|
|
108
109
|
currentPartialText: undefined,
|
|
110
|
+
currentReasoningText: undefined,
|
|
109
111
|
error: undefined,
|
|
110
112
|
startedAt: new Date().toISOString(),
|
|
111
113
|
completedAt: new Date().toISOString()
|
|
@@ -122,6 +124,7 @@ export const backgroundHandler = createRouter()
|
|
|
122
124
|
processId: streamState.processId,
|
|
123
125
|
messages,
|
|
124
126
|
currentPartialText: streamState.currentPartialText,
|
|
127
|
+
currentReasoningText: streamState.currentReasoningText,
|
|
125
128
|
error: streamState.error,
|
|
126
129
|
startedAt: streamState.startedAt.toISOString(),
|
|
127
130
|
completedAt: streamState.completedAt?.toISOString()
|
|
@@ -13,7 +13,7 @@ import { streamManager, type StreamEvent } from '../../lib/chat/stream-manager';
|
|
|
13
13
|
import { debug } from '$shared/utils/logger';
|
|
14
14
|
import { ws } from '$backend/lib/utils/ws';
|
|
15
15
|
import { broadcastPresence } from '../projects/status';
|
|
16
|
-
import { sessionQueries } from '../../lib/database/queries';
|
|
16
|
+
import { sessionQueries, messageQueries } from '../../lib/database/queries';
|
|
17
17
|
|
|
18
18
|
// ============================================================================
|
|
19
19
|
// Global stream lifecycle handler (module-level, not per-connection)
|
|
@@ -28,6 +28,15 @@ streamManager.on('stream:lifecycle', (event: { status: string; streamId: string;
|
|
|
28
28
|
|
|
29
29
|
debug.log('chat', `Stream lifecycle: ${status} for project ${projectId} session ${chatSessionId}`);
|
|
30
30
|
|
|
31
|
+
// Mark any tool_use blocks that never got a tool_result as interrupted (persisted to DB)
|
|
32
|
+
if (chatSessionId) {
|
|
33
|
+
try {
|
|
34
|
+
messageQueries.markInterruptedMessages(chatSessionId);
|
|
35
|
+
} catch (err) {
|
|
36
|
+
debug.error('chat', 'Failed to mark interrupted messages:', err);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
31
40
|
// Notify all project members (cross-project notification for sound + push)
|
|
32
41
|
ws.emit.projectMembers(projectId, 'chat:stream-finished', {
|
|
33
42
|
projectId,
|
|
@@ -360,6 +369,39 @@ export const streamHandler = createRouter()
|
|
|
360
369
|
}
|
|
361
370
|
})
|
|
362
371
|
|
|
372
|
+
// Handle AskUserQuestion answer from user
|
|
373
|
+
.on('chat:ask-user-answer', {
|
|
374
|
+
data: t.Object({
|
|
375
|
+
chatSessionId: t.String(),
|
|
376
|
+
toolUseId: t.String(),
|
|
377
|
+
answers: t.Record(t.String(), t.String())
|
|
378
|
+
})
|
|
379
|
+
}, async ({ data, conn }) => {
|
|
380
|
+
const projectId = ws.getProjectId(conn);
|
|
381
|
+
|
|
382
|
+
try {
|
|
383
|
+
debug.log('chat', 'WS chat:ask-user-answer received:', {
|
|
384
|
+
chatSessionId: data.chatSessionId,
|
|
385
|
+
toolUseId: data.toolUseId,
|
|
386
|
+
answers: data.answers
|
|
387
|
+
});
|
|
388
|
+
|
|
389
|
+
const success = streamManager.resolveUserAnswer(
|
|
390
|
+
data.chatSessionId,
|
|
391
|
+
projectId,
|
|
392
|
+
data.toolUseId,
|
|
393
|
+
data.answers
|
|
394
|
+
);
|
|
395
|
+
|
|
396
|
+
if (!success) {
|
|
397
|
+
debug.warn('chat', 'Failed to resolve user answer for stream');
|
|
398
|
+
}
|
|
399
|
+
} catch (error) {
|
|
400
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
401
|
+
debug.error('chat', 'WS chat:ask-user-answer error:', errorMessage);
|
|
402
|
+
}
|
|
403
|
+
})
|
|
404
|
+
|
|
363
405
|
// Cancel stream
|
|
364
406
|
.on('chat:cancel', {
|
|
365
407
|
data: t.Object({
|
package/bin/clopen.ts
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
2
|
|
|
3
|
+
// Runtime guard — Bun only, reject Node.js and Deno
|
|
4
|
+
if (typeof globalThis.Bun === 'undefined') {
|
|
5
|
+
console.error('\x1b[31mError: Clopen requires Bun runtime.\x1b[0m');
|
|
6
|
+
console.error('Node.js and Deno are not supported.');
|
|
7
|
+
console.error('');
|
|
8
|
+
console.error('Install Bun: https://bun.sh');
|
|
9
|
+
console.error('Then run: bun clopen');
|
|
10
|
+
process.exit(1);
|
|
11
|
+
}
|
|
12
|
+
|
|
3
13
|
/**
|
|
4
14
|
* Clopen CLI Entry Point
|
|
5
15
|
*
|