mu-coding 0.5.0 → 0.9.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/README.md +49 -3
- package/package.json +9 -4
- package/prompts/SYSTEM.md +16 -0
- package/src/app/shutdown.ts +1 -1
- package/src/app/startApp.ts +11 -8
- package/src/cli/args.ts +14 -11
- package/src/cli/install.ts +18 -3
- package/src/config/index.test.ts +26 -0
- package/src/config/index.ts +25 -7
- package/src/plugin.ts +124 -0
- package/src/runtime/codingTools/bash.ts +114 -0
- package/src/runtime/codingTools/edit-file.ts +60 -0
- package/src/runtime/codingTools/index.ts +39 -0
- package/src/runtime/codingTools/read-file.ts +83 -0
- package/src/runtime/codingTools/utils.ts +21 -0
- package/src/runtime/codingTools/write-file.ts +42 -0
- package/src/runtime/createRegistry.test.ts +147 -0
- package/src/runtime/createRegistry.ts +160 -23
- package/src/runtime/fileMentionProvider.ts +116 -0
- package/src/runtime/messageBus.test.ts +62 -0
- package/src/runtime/messageBus.ts +78 -0
- package/src/runtime/pluginLoader.ts +59 -15
- package/src/sessions/index.ts +2 -9
- package/src/tui/channel/tuiChannel.test.ts +107 -0
- package/src/tui/channel/tuiChannel.ts +62 -0
- package/src/tui/chat/MessageRendererContext.ts +44 -0
- package/src/tui/chat/ToolDisplayContext.ts +1 -1
- package/src/tui/chat/useAbort.ts +5 -0
- package/src/tui/chat/useAttachment.ts +1 -1
- package/src/tui/chat/useChat.ts +38 -3
- package/src/tui/chat/useChatPanel.ts +29 -6
- package/src/tui/chat/useChatSession.ts +324 -57
- package/src/tui/chat/useModels.ts +26 -1
- package/src/tui/chat/usePluginStatus.ts +1 -1
- package/src/tui/chat/useSessionPersistence.ts +48 -21
- package/src/tui/chat/useStatusSegments.ts +38 -5
- package/src/tui/chat/useSubagentBrowser.ts +133 -0
- package/src/tui/components/chat/ChatPanel.tsx +25 -4
- package/src/tui/components/chat/ChatPanelBody.tsx +22 -1
- package/src/tui/components/chat/SubagentBrowserPanel.tsx +145 -0
- package/src/tui/components/messageView.tsx +4 -2
- package/src/tui/components/messages/EditOutput.tsx +17 -9
- package/src/tui/components/messages/ReadOutput.tsx +1 -1
- package/src/tui/components/messages/ToolHeader.tsx +8 -4
- package/src/tui/components/messages/WriteOutput.tsx +12 -4
- package/src/tui/components/messages/assistantMessage.tsx +55 -7
- package/src/tui/components/messages/markdown.tsx +402 -0
- package/src/tui/components/messages/messageItem.tsx +19 -1
- package/src/tui/components/messages/reasoningBlock.tsx +10 -6
- package/src/tui/components/messages/streamingOutput.tsx +6 -2
- package/src/tui/components/messages/toolCallBlock.tsx +7 -6
- package/src/tui/components/messages/userMessage.tsx +22 -7
- package/src/tui/components/primitives/dropdown.tsx +8 -4
- package/src/tui/components/primitives/modal.tsx +4 -2
- package/src/tui/components/primitives/pickerModal.tsx +3 -1
- package/src/tui/components/primitives/toast.tsx +43 -10
- package/src/tui/components/statusBar.tsx +26 -10
- package/src/tui/components/ui/dialogLayer.tsx +11 -6
- package/src/tui/context/ThemeContext.tsx +18 -0
- package/src/tui/hooks/useChordKeyboard.ts +87 -0
- package/src/tui/hooks/useInputInfoSegments.ts +22 -0
- package/src/tui/input/InputBoxView.tsx +191 -26
- package/src/tui/input/commands.test.ts +3 -1
- package/src/tui/input/commands.ts +11 -1
- package/src/tui/input/cursor.test.ts +136 -0
- package/src/tui/input/cursor.ts +214 -0
- package/src/tui/input/dumpContext.ts +107 -0
- package/src/tui/input/sanitize.ts +1 -1
- package/src/tui/input/useCommandExecutor.ts +1 -1
- package/src/tui/input/useInputBox.ts +160 -15
- package/src/tui/input/useInputHandler.ts +317 -126
- package/src/tui/input/useMentionPicker.ts +133 -0
- package/src/tui/input/usePluginShortcuts.ts +29 -0
- package/src/tui/plugins/InkApprovalChannel.test.ts +51 -0
- package/src/tui/plugins/InkApprovalChannel.ts +30 -0
- package/src/tui/plugins/InkUIService.ts +1 -1
- package/src/tui/renderApp.tsx +47 -13
- package/src/tui/theme/index.ts +1 -0
- package/src/tui/theme/merge.test.ts +49 -0
- package/src/tui/theme/merge.ts +43 -0
- package/src/tui/theme/presets.ts +90 -0
- package/src/tui/theme/types.ts +138 -0
- package/src/utils/clipboard.ts +1 -1
- package/src/tui/chat/useStreamConsumer.ts +0 -118
|
@@ -1,118 +0,0 @@
|
|
|
1
|
-
import { type AgentEvent, type PluginRegistry, runAgent } from 'mu-agents';
|
|
2
|
-
import type { ChatMessage, ProviderConfig } from 'mu-provider';
|
|
3
|
-
import { useCallback, useState } from 'react';
|
|
4
|
-
|
|
5
|
-
export interface StreamState {
|
|
6
|
-
text: string;
|
|
7
|
-
reasoning: string;
|
|
8
|
-
tps: number;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
const EMPTY_STREAM: StreamState = { text: '', reasoning: '', tps: 0 };
|
|
12
|
-
const TPS_WARMUP_SEC = 0.5;
|
|
13
|
-
|
|
14
|
-
export interface StreamConsumerState {
|
|
15
|
-
streaming: boolean;
|
|
16
|
-
error: string | null;
|
|
17
|
-
stream: StreamState;
|
|
18
|
-
/**
|
|
19
|
-
* Run the agent against `messages` and stream events into local state.
|
|
20
|
-
* Returns the final message array (or null if the agent didn't produce one,
|
|
21
|
-
* e.g. on abort). Throws are caught and reported via `error`.
|
|
22
|
-
*/
|
|
23
|
-
runStream: (
|
|
24
|
-
messages: ChatMessage[],
|
|
25
|
-
config: ProviderConfig,
|
|
26
|
-
model: string,
|
|
27
|
-
signal: AbortSignal,
|
|
28
|
-
registry: PluginRegistry,
|
|
29
|
-
onMessages: (messages: ChatMessage[]) => void,
|
|
30
|
-
) => Promise<ChatMessage[] | null>;
|
|
31
|
-
resetError: () => void;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
function applyEvent(prev: StreamState, event: AgentEvent, tps: number): StreamState {
|
|
35
|
-
switch (event.type) {
|
|
36
|
-
case 'content':
|
|
37
|
-
return { ...prev, text: event.text, tps };
|
|
38
|
-
case 'reasoning':
|
|
39
|
-
return { ...prev, reasoning: event.text, tps };
|
|
40
|
-
case 'turn_end':
|
|
41
|
-
return { ...prev, text: '', reasoning: '' };
|
|
42
|
-
default:
|
|
43
|
-
return prev;
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
async function consumeAgent(
|
|
48
|
-
events: AsyncGenerator<AgentEvent>,
|
|
49
|
-
onStream: (updater: (prev: StreamState) => StreamState) => void,
|
|
50
|
-
onMessages: (messages: ChatMessage[]) => void,
|
|
51
|
-
): Promise<ChatMessage[] | null> {
|
|
52
|
-
let final: ChatMessage[] | null = null;
|
|
53
|
-
const start = Date.now();
|
|
54
|
-
let tokenCount = 0;
|
|
55
|
-
|
|
56
|
-
for await (const event of events) {
|
|
57
|
-
if (event.type === 'content' || event.type === 'reasoning') {
|
|
58
|
-
tokenCount++;
|
|
59
|
-
const elapsed = (Date.now() - start) / 1000;
|
|
60
|
-
const tps = elapsed > TPS_WARMUP_SEC ? Math.round(tokenCount / elapsed) : 0;
|
|
61
|
-
onStream((prev) => applyEvent(prev, event, tps));
|
|
62
|
-
} else if (event.type === 'messages') {
|
|
63
|
-
final = event.messages;
|
|
64
|
-
onMessages(event.messages);
|
|
65
|
-
} else {
|
|
66
|
-
onStream((prev) => applyEvent(prev, event, 0));
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
return final;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
/**
|
|
73
|
-
* Owns the in-flight streaming view: which tokens have been received, the
|
|
74
|
-
* tokens-per-second meter, error text, and the streaming flag. Decoupled
|
|
75
|
-
* from message persistence so it can be reused by single-shot agents or
|
|
76
|
-
* test harnesses.
|
|
77
|
-
*/
|
|
78
|
-
export function useStreamConsumer(): StreamConsumerState {
|
|
79
|
-
const [streaming, setStreaming] = useState(false);
|
|
80
|
-
const [error, setError] = useState<string | null>(null);
|
|
81
|
-
const [stream, setStream] = useState<StreamState>(EMPTY_STREAM);
|
|
82
|
-
|
|
83
|
-
const resetError = useCallback(() => setError(null), []);
|
|
84
|
-
|
|
85
|
-
const runStream = useCallback(
|
|
86
|
-
async (
|
|
87
|
-
messages: ChatMessage[],
|
|
88
|
-
config: ProviderConfig,
|
|
89
|
-
model: string,
|
|
90
|
-
signal: AbortSignal,
|
|
91
|
-
registry: PluginRegistry,
|
|
92
|
-
onMessages: (messages: ChatMessage[]) => void,
|
|
93
|
-
): Promise<ChatMessage[] | null> => {
|
|
94
|
-
setStream(EMPTY_STREAM);
|
|
95
|
-
setError(null);
|
|
96
|
-
setStreaming(true);
|
|
97
|
-
try {
|
|
98
|
-
return await consumeAgent(runAgent(messages, config, model, signal, registry), setStream, onMessages);
|
|
99
|
-
} catch (err) {
|
|
100
|
-
if (!(err instanceof Error && err.name === 'AbortError')) {
|
|
101
|
-
setError(err instanceof Error ? err.message : 'Unknown error');
|
|
102
|
-
}
|
|
103
|
-
return null;
|
|
104
|
-
} finally {
|
|
105
|
-
setStreaming(false);
|
|
106
|
-
// Preserve partial output on abort so the user can see what arrived;
|
|
107
|
-
// clear it on clean completion so the persisted assistant message
|
|
108
|
-
// doesn't render twice.
|
|
109
|
-
if (!signal.aborted) {
|
|
110
|
-
setStream((s) => ({ ...s, text: '', reasoning: '' }));
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
},
|
|
114
|
-
[],
|
|
115
|
-
);
|
|
116
|
-
|
|
117
|
-
return { streaming, error, stream, runStream, resetError };
|
|
118
|
-
}
|