@qduc/term2 0.1.2 → 0.1.3
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/dist/agent.lite-mode.test.d.ts +2 -0
- package/dist/agent.lite-mode.test.d.ts.map +1 -0
- package/dist/agent.lite-mode.test.js +39 -0
- package/dist/agent.lite-mode.test.js.map +1 -0
- package/dist/app.d.ts.map +1 -1
- package/dist/app.js +3 -1
- package/dist/app.js.map +1 -1
- package/dist/components/ApprovalPrompt.d.ts.map +1 -1
- package/dist/components/ApprovalPrompt.js +20 -0
- package/dist/components/ApprovalPrompt.js.map +1 -1
- package/dist/components/InputBox.d.ts.map +1 -1
- package/dist/components/InputBox.js +2 -7
- package/dist/components/InputBox.js.map +1 -1
- package/dist/components/TextInput.d.ts.map +1 -1
- package/dist/components/TextInput.js +2 -1
- package/dist/components/TextInput.js.map +1 -1
- package/dist/components/TextInput.test.js.map +1 -1
- package/dist/debug_ask_mentor.d.ts +2 -0
- package/dist/debug_ask_mentor.d.ts.map +1 -0
- package/dist/debug_ask_mentor.js +73 -0
- package/dist/debug_ask_mentor.js.map +1 -0
- package/dist/hooks/use-model-selection.d.ts.map +1 -1
- package/dist/hooks/use-model-selection.js +7 -3
- package/dist/hooks/use-model-selection.js.map +1 -1
- package/dist/hooks/use-settings-completion.d.ts.map +1 -1
- package/dist/hooks/use-settings-completion.js +3 -0
- package/dist/hooks/use-settings-completion.js.map +1 -1
- package/dist/hooks/use-settings-completion.test.js +6 -0
- package/dist/hooks/use-settings-completion.test.js.map +1 -1
- package/dist/lib/openai-agent-client.d.ts.map +1 -1
- package/dist/lib/openai-agent-client.js +35 -15
- package/dist/lib/openai-agent-client.js.map +1 -1
- package/dist/lib/tool-invoke.test.js +1 -1
- package/dist/lib/tool-invoke.test.js.map +1 -1
- package/dist/modes/companion/command-index.d.ts +26 -0
- package/dist/modes/companion/command-index.d.ts.map +1 -0
- package/dist/modes/companion/command-index.js +50 -0
- package/dist/modes/companion/command-index.js.map +1 -0
- package/dist/modes/companion/command-index.test.d.ts +2 -0
- package/dist/modes/companion/command-index.test.d.ts.map +1 -0
- package/dist/modes/companion/command-index.test.js +86 -0
- package/dist/modes/companion/command-index.test.js.map +1 -0
- package/dist/modes/companion/companion-app.d.ts +12 -0
- package/dist/modes/companion/companion-app.d.ts.map +1 -0
- package/dist/modes/companion/companion-app.js +297 -0
- package/dist/modes/companion/companion-app.js.map +1 -0
- package/dist/modes/companion/companion-session.d.ts +63 -0
- package/dist/modes/companion/companion-session.d.ts.map +1 -0
- package/dist/modes/companion/companion-session.js +146 -0
- package/dist/modes/companion/companion-session.js.map +1 -0
- package/dist/modes/companion/companion-session.test.d.ts +2 -0
- package/dist/modes/companion/companion-session.test.d.ts.map +1 -0
- package/dist/modes/companion/companion-session.test.js +28 -0
- package/dist/modes/companion/companion-session.test.js.map +1 -0
- package/dist/modes/companion/components/status-bar.d.ts +13 -0
- package/dist/modes/companion/components/status-bar.d.ts.map +1 -0
- package/dist/modes/companion/components/status-bar.js +26 -0
- package/dist/modes/companion/components/status-bar.js.map +1 -0
- package/dist/modes/companion/context-buffer.d.ts +65 -0
- package/dist/modes/companion/context-buffer.d.ts.map +1 -0
- package/dist/modes/companion/context-buffer.js +156 -0
- package/dist/modes/companion/context-buffer.js.map +1 -0
- package/dist/modes/companion/context-buffer.test.d.ts +2 -0
- package/dist/modes/companion/context-buffer.test.d.ts.map +1 -0
- package/dist/modes/companion/context-buffer.test.js +154 -0
- package/dist/modes/companion/context-buffer.test.js.map +1 -0
- package/dist/modes/companion/event-detector.d.ts +46 -0
- package/dist/modes/companion/event-detector.d.ts.map +1 -0
- package/dist/modes/companion/event-detector.js +169 -0
- package/dist/modes/companion/event-detector.js.map +1 -0
- package/dist/modes/companion/event-detector.test.d.ts +2 -0
- package/dist/modes/companion/event-detector.test.d.ts.map +1 -0
- package/dist/modes/companion/event-detector.test.js +121 -0
- package/dist/modes/companion/event-detector.test.js.map +1 -0
- package/dist/modes/companion/index.d.ts +33 -0
- package/dist/modes/companion/index.d.ts.map +1 -0
- package/dist/modes/companion/index.js +21 -0
- package/dist/modes/companion/index.js.map +1 -0
- package/dist/modes/companion/input-key-mapper.d.ts +3 -0
- package/dist/modes/companion/input-key-mapper.d.ts.map +1 -0
- package/dist/modes/companion/input-key-mapper.js +31 -0
- package/dist/modes/companion/input-key-mapper.js.map +1 -0
- package/dist/modes/companion/input-key-mapper.test.d.ts +2 -0
- package/dist/modes/companion/input-key-mapper.test.d.ts.map +1 -0
- package/dist/modes/companion/input-key-mapper.test.js +26 -0
- package/dist/modes/companion/input-key-mapper.test.js.map +1 -0
- package/dist/modes/companion/input-parser.d.ts +53 -0
- package/dist/modes/companion/input-parser.d.ts.map +1 -0
- package/dist/modes/companion/input-parser.js +114 -0
- package/dist/modes/companion/input-parser.js.map +1 -0
- package/dist/modes/companion/input-parser.test.d.ts +2 -0
- package/dist/modes/companion/input-parser.test.d.ts.map +1 -0
- package/dist/modes/companion/input-parser.test.js +123 -0
- package/dist/modes/companion/input-parser.test.js.map +1 -0
- package/dist/modes/companion/mode-manager.d.ts +41 -0
- package/dist/modes/companion/mode-manager.d.ts.map +1 -0
- package/dist/modes/companion/mode-manager.js +56 -0
- package/dist/modes/companion/mode-manager.js.map +1 -0
- package/dist/modes/companion/mode-manager.test.d.ts +2 -0
- package/dist/modes/companion/mode-manager.test.d.ts.map +1 -0
- package/dist/modes/companion/mode-manager.test.js +65 -0
- package/dist/modes/companion/mode-manager.test.js.map +1 -0
- package/dist/modes/companion/output-classifier.d.ts +15 -0
- package/dist/modes/companion/output-classifier.d.ts.map +1 -0
- package/dist/modes/companion/output-classifier.js +77 -0
- package/dist/modes/companion/output-classifier.js.map +1 -0
- package/dist/modes/companion/output-classifier.test.d.ts +2 -0
- package/dist/modes/companion/output-classifier.test.d.ts.map +1 -0
- package/dist/modes/companion/output-classifier.test.js +133 -0
- package/dist/modes/companion/output-classifier.test.js.map +1 -0
- package/dist/modes/companion/pty-wrapper.d.ts +46 -0
- package/dist/modes/companion/pty-wrapper.d.ts.map +1 -0
- package/dist/modes/companion/pty-wrapper.js +143 -0
- package/dist/modes/companion/pty-wrapper.js.map +1 -0
- package/dist/modes/companion/safety-classifier.d.ts +31 -0
- package/dist/modes/companion/safety-classifier.d.ts.map +1 -0
- package/dist/modes/companion/safety-classifier.js +140 -0
- package/dist/modes/companion/safety-classifier.js.map +1 -0
- package/dist/modes/companion/safety-classifier.test.d.ts +2 -0
- package/dist/modes/companion/safety-classifier.test.d.ts.map +1 -0
- package/dist/modes/companion/safety-classifier.test.js +151 -0
- package/dist/modes/companion/safety-classifier.test.js.map +1 -0
- package/dist/modes/companion/summarizer.d.ts +24 -0
- package/dist/modes/companion/summarizer.d.ts.map +1 -0
- package/dist/modes/companion/summarizer.js +132 -0
- package/dist/modes/companion/summarizer.js.map +1 -0
- package/dist/modes/companion/terminal-history.d.ts +27 -0
- package/dist/modes/companion/terminal-history.d.ts.map +1 -0
- package/dist/modes/companion/terminal-history.js +142 -0
- package/dist/modes/companion/terminal-history.js.map +1 -0
- package/dist/prompts/simple-mentor.md +8 -0
- package/dist/providers/openai-compatible/model.d.ts.map +1 -1
- package/dist/providers/openai-compatible/model.js +13 -2
- package/dist/providers/openai-compatible/model.js.map +1 -1
- package/dist/providers/openai-compatible/reasoning-content.test.js +2 -2
- package/dist/providers/openai-compatible/reasoning-content.test.js.map +1 -1
- package/dist/providers/openrouter/reasoning-content.test.js +2 -2
- package/dist/providers/openrouter/reasoning-content.test.js.map +1 -1
- package/dist/providers/openrouter.test.js +30 -21
- package/dist/providers/openrouter.test.js.map +1 -1
- package/dist/services/check_mock.d.ts +2 -0
- package/dist/services/check_mock.d.ts.map +1 -0
- package/dist/services/check_mock.js +22 -0
- package/dist/services/check_mock.js.map +1 -0
- package/dist/services/conversation-service.test.d.ts +2 -0
- package/dist/services/conversation-service.test.d.ts.map +1 -0
- package/dist/services/conversation-service.test.js +149 -183
- package/dist/services/conversation-service.test.js.map +1 -0
- package/dist/services/conversation-store.test.js +12 -11
- package/dist/services/conversation-store.test.js.map +1 -1
- package/dist/services/settings-service.d.ts +5 -2
- package/dist/services/settings-service.d.ts.map +1 -1
- package/dist/services/settings-service.js +12 -0
- package/dist/services/settings-service.js.map +1 -1
- package/dist/tools/ask-mentor.d.ts +1 -1
- package/dist/tools/ask-mentor.d.ts.map +1 -1
- package/dist/tools/ask-mentor.js +1 -0
- package/dist/tools/ask-mentor.js.map +1 -1
- package/dist/tools/find-files.d.ts +2 -2
- package/dist/tools/find-files.d.ts.map +1 -1
- package/dist/tools/find-files.js +2 -0
- package/dist/tools/find-files.js.map +1 -1
- package/dist/tools/grep.d.ts +1 -1
- package/dist/tools/grep.d.ts.map +1 -1
- package/dist/tools/grep.js +1 -0
- package/dist/tools/grep.js.map +1 -1
- package/dist/tools/read-file.d.ts.map +1 -1
- package/dist/tools/read-file.js +10 -9
- package/dist/tools/read-file.js.map +1 -1
- package/dist/tools/read-file.test.js +24 -19
- package/dist/tools/read-file.test.js.map +1 -1
- package/dist/tools/search-replace.d.ts +1 -1
- package/dist/tools/search-replace.d.ts.map +1 -1
- package/dist/tools/search-replace.js +129 -1
- package/dist/tools/search-replace.js.map +1 -1
- package/dist/tools/search-replace.test.js +18 -0
- package/dist/tools/search-replace.test.js.map +1 -1
- package/dist/tools/search.d.ts +4 -4
- package/dist/tools/search.d.ts.map +1 -1
- package/dist/tools/search.js +4 -0
- package/dist/tools/search.js.map +1 -1
- package/dist/tools/shell.d.ts +2 -2
- package/dist/tools/shell.d.ts.map +1 -1
- package/dist/tools/shell.js +2 -0
- package/dist/tools/shell.js.map +1 -1
- package/dist/tools/types.d.ts +2 -2
- package/dist/tools/types.d.ts.map +1 -1
- package/dist/utils/command-safety.d.ts.map +1 -1
- package/dist/utils/command-safety.devnull.test.d.ts +2 -0
- package/dist/utils/command-safety.devnull.test.d.ts.map +1 -0
- package/dist/utils/command-safety.devnull.test.js +13 -0
- package/dist/utils/command-safety.devnull.test.js.map +1 -0
- package/dist/utils/command-safety.js +10 -364
- package/dist/utils/command-safety.js.map +1 -1
- package/dist/utils/extract-command-messages.test.d.ts +2 -0
- package/dist/utils/extract-command-messages.test.d.ts.map +1 -0
- package/dist/utils/extract-command-messages.test.js +58 -51
- package/dist/utils/extract-command-messages.test.js.map +1 -0
- package/dist/utils/settings-command.d.ts.map +1 -1
- package/dist/utils/settings-command.js +13 -4
- package/dist/utils/settings-command.js.map +1 -1
- package/package.json +2 -2
- package/dist/app.model-command-feedback.test.d.ts +0 -2
- package/dist/app.model-command-feedback.test.d.ts.map +0 -1
- package/dist/app.model-command-feedback.test.js +0 -19
- package/dist/app.model-command-feedback.test.js.map +0 -1
- package/dist/components/MentorMode.test.d.ts +0 -2
- package/dist/components/MentorMode.test.d.ts.map +0 -1
- package/dist/components/MentorMode.test.js.map +0 -1
- package/dist/debug-schema.d.ts +0 -2
- package/dist/debug-schema.d.ts.map +0 -1
- package/dist/debug-schema.js +0 -22
- package/dist/debug-schema.js.map +0 -1
- package/dist/hooks/use-model-selection.test.d.ts +0 -2
- package/dist/hooks/use-model-selection.test.d.ts.map +0 -1
- package/dist/hooks/use-model-selection.test.js +0 -28
- package/dist/hooks/use-model-selection.test.js.map +0 -1
- package/dist/hooks/use-path-completion.test.d.ts +0 -2
- package/dist/hooks/use-path-completion.test.d.ts.map +0 -1
- package/dist/hooks/use-path-completion.test.js +0 -29
- package/dist/hooks/use-path-completion.test.js.map +0 -1
- package/dist/prompts/default.md.bak +0 -77
- package/dist/providers/openrouter.history.test.d.ts +0 -2
- package/dist/providers/openrouter.history.test.d.ts.map +0 -1
- package/dist/providers/openrouter.history.test.js +0 -533
- package/dist/providers/openrouter.history.test.js.map +0 -1
- package/dist/test-search-tool.d.ts +0 -2
- package/dist/test-search-tool.d.ts.map +0 -1
- package/dist/test-search-tool.js +0 -36
- package/dist/test-search-tool.js.map +0 -1
- package/dist/utils/extract-command-messages.repro.test.d.ts +0 -2
- package/dist/utils/extract-command-messages.repro.test.d.ts.map +0 -1
- package/dist/utils/extract-command-messages.repro.test.js +0 -31
- package/dist/utils/extract-command-messages.repro.test.js.map +0 -1
- /package/{README.md → readme.md} +0 -0
|
@@ -0,0 +1,297 @@
|
|
|
1
|
+
import React, { useEffect, useState, useCallback } from 'react';
|
|
2
|
+
import { Box, Text, useInput, useApp } from 'ink';
|
|
3
|
+
import { PTYWrapper } from './pty-wrapper.js';
|
|
4
|
+
import { ContextBuffer } from './context-buffer.js';
|
|
5
|
+
import { ModeManager } from './mode-manager.js';
|
|
6
|
+
import { EventDetector } from './event-detector.js';
|
|
7
|
+
import { Summarizer } from './summarizer.js';
|
|
8
|
+
import { StatusBar } from './components/status-bar.js';
|
|
9
|
+
import { CompanionSession } from './companion-session.js';
|
|
10
|
+
import { parseCompanionInput, CommandOutputBuffer } from './input-parser.js';
|
|
11
|
+
import { getPtyInputSequence } from './input-key-mapper.js';
|
|
12
|
+
/** Height reserved at bottom of terminal for status bar and AI response */
|
|
13
|
+
const STATUS_BAR_RESERVED_ROWS = 4;
|
|
14
|
+
/**
|
|
15
|
+
* Infer exit code from command output patterns.
|
|
16
|
+
* Since PTY doesn't provide per-command exit codes, we use heuristics.
|
|
17
|
+
*/
|
|
18
|
+
function inferExitCodeFromOutput(output) {
|
|
19
|
+
const lowerOutput = output.toLowerCase();
|
|
20
|
+
// Common error patterns that indicate failure
|
|
21
|
+
const errorPatterns = [
|
|
22
|
+
/\berror\b/i,
|
|
23
|
+
/\bfail(ed|ure)?\b/i,
|
|
24
|
+
/\bfatal\b/i,
|
|
25
|
+
/\bexception\b/i,
|
|
26
|
+
/\bcommand not found\b/i,
|
|
27
|
+
/\bno such file\b/i,
|
|
28
|
+
/\bpermission denied\b/i,
|
|
29
|
+
/\bdoes not exist\b/i,
|
|
30
|
+
/\bcannot\b/i,
|
|
31
|
+
/\bexit status [1-9]/i,
|
|
32
|
+
/\bexit code [1-9]/i,
|
|
33
|
+
/\breturned [1-9]/i,
|
|
34
|
+
];
|
|
35
|
+
for (const pattern of errorPatterns) {
|
|
36
|
+
if (pattern.test(lowerOutput)) {
|
|
37
|
+
return 1;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return 0; // Assume success if no error patterns found
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Main companion mode application.
|
|
44
|
+
* Wraps user's shell in a PTY and provides AI assistance.
|
|
45
|
+
*/
|
|
46
|
+
export const CompanionApp = ({ settingsService, loggingService, }) => {
|
|
47
|
+
const { exit } = useApp();
|
|
48
|
+
// Core services
|
|
49
|
+
const [ptyWrapper] = useState(() => new PTYWrapper({ logger: loggingService }));
|
|
50
|
+
const [contextBuffer] = useState(() => new ContextBuffer({
|
|
51
|
+
maxSize: settingsService.get('companion.maxContextBufferSize') || 1048576,
|
|
52
|
+
maxCommands: settingsService.get('companion.maxCommandIndexSize') || 10,
|
|
53
|
+
}));
|
|
54
|
+
const [modeManager] = useState(() => new ModeManager());
|
|
55
|
+
const [eventDetector] = useState(() => new EventDetector({
|
|
56
|
+
errorCascadeThreshold: settingsService.get('companion.errorCascadeThreshold') || 3,
|
|
57
|
+
retryLoopThreshold: settingsService.get('companion.retryLoopThreshold') || 2,
|
|
58
|
+
pauseHintDelayMs: settingsService.get('companion.pauseHintDelayMs') || 30000,
|
|
59
|
+
}));
|
|
60
|
+
const [summarizer] = useState(() => new Summarizer({
|
|
61
|
+
settings: settingsService,
|
|
62
|
+
logger: loggingService,
|
|
63
|
+
}));
|
|
64
|
+
const [companionSession] = useState(() => new CompanionSession({
|
|
65
|
+
contextBuffer,
|
|
66
|
+
summarizer,
|
|
67
|
+
settings: settingsService,
|
|
68
|
+
logger: loggingService,
|
|
69
|
+
}));
|
|
70
|
+
const [commandOutputBuffer] = useState(() => new CommandOutputBuffer());
|
|
71
|
+
// UI state
|
|
72
|
+
const [currentMode, setCurrentMode] = useState(modeManager.mode);
|
|
73
|
+
const [hint, setHint] = useState();
|
|
74
|
+
const [isProcessing, setIsProcessing] = useState(false);
|
|
75
|
+
const [error, setError] = useState();
|
|
76
|
+
const [aiResponse, setAiResponse] = useState('');
|
|
77
|
+
// Input buffer for detecting ?? and !auto
|
|
78
|
+
const [inputLine, setInputLine] = useState('');
|
|
79
|
+
// Handle ?? query
|
|
80
|
+
const handleQuery = useCallback(async (query) => {
|
|
81
|
+
setIsProcessing(true);
|
|
82
|
+
setAiResponse('');
|
|
83
|
+
setHint(undefined);
|
|
84
|
+
try {
|
|
85
|
+
for await (const event of companionSession.handleWatchQuery(query)) {
|
|
86
|
+
if (event.type === 'text' && event.content) {
|
|
87
|
+
setAiResponse(prev => prev + event.content);
|
|
88
|
+
}
|
|
89
|
+
else if (event.type === 'error') {
|
|
90
|
+
loggingService.error('Query failed', { error: event.content });
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
finally {
|
|
95
|
+
setIsProcessing(false);
|
|
96
|
+
}
|
|
97
|
+
}, [companionSession, loggingService]);
|
|
98
|
+
// Handle !auto task
|
|
99
|
+
const handleAutoTask = useCallback(async (task) => {
|
|
100
|
+
setIsProcessing(true);
|
|
101
|
+
setAiResponse('');
|
|
102
|
+
setHint(undefined);
|
|
103
|
+
modeManager.enterAutoMode();
|
|
104
|
+
try {
|
|
105
|
+
for await (const event of companionSession.handleAutoTask(task)) {
|
|
106
|
+
if (event.type === 'text' && event.content) {
|
|
107
|
+
setAiResponse(prev => prev + event.content);
|
|
108
|
+
}
|
|
109
|
+
else if (event.type === 'tool_call' && event.tool) {
|
|
110
|
+
loggingService.info('Tool call', { tool: event.tool, args: event.args });
|
|
111
|
+
}
|
|
112
|
+
else if (event.type === 'error') {
|
|
113
|
+
loggingService.error('Auto task failed', { error: event.content });
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
finally {
|
|
118
|
+
setIsProcessing(false);
|
|
119
|
+
modeManager.enterWatchMode();
|
|
120
|
+
}
|
|
121
|
+
}, [companionSession, modeManager, loggingService]);
|
|
122
|
+
// Setup PTY and event handlers
|
|
123
|
+
useEffect(() => {
|
|
124
|
+
// Mode change handler
|
|
125
|
+
modeManager.on('modeChange', (mode) => {
|
|
126
|
+
setCurrentMode(mode);
|
|
127
|
+
loggingService.info('Mode changed', { mode });
|
|
128
|
+
});
|
|
129
|
+
// Event detector hint handler
|
|
130
|
+
eventDetector.on('hint', (event) => {
|
|
131
|
+
if (settingsService.get('companion.showHints') !== false) {
|
|
132
|
+
setHint(event.message);
|
|
133
|
+
}
|
|
134
|
+
});
|
|
135
|
+
// PTY output handler
|
|
136
|
+
ptyWrapper.on('output', (data) => {
|
|
137
|
+
// Pass through to stdout
|
|
138
|
+
process.stdout.write(data);
|
|
139
|
+
// Process output for command boundary detection
|
|
140
|
+
const completed = commandOutputBuffer.processData(data);
|
|
141
|
+
if (completed) {
|
|
142
|
+
// Infer exit code from output patterns when not available directly
|
|
143
|
+
// This is a heuristic since PTY doesn't provide per-command exit codes
|
|
144
|
+
const inferredExitCode = inferExitCodeFromOutput(completed.output);
|
|
145
|
+
const entry = {
|
|
146
|
+
command: completed.command,
|
|
147
|
+
output: completed.output,
|
|
148
|
+
exitCode: inferredExitCode,
|
|
149
|
+
timestamp: Date.now(),
|
|
150
|
+
outputLines: completed.output.split('\n').length,
|
|
151
|
+
};
|
|
152
|
+
contextBuffer.addEntry(entry);
|
|
153
|
+
// Check for patterns
|
|
154
|
+
const event = eventDetector.processCommand(entry);
|
|
155
|
+
if (event && settingsService.get('companion.showHints') !== false) {
|
|
156
|
+
setHint(event.message);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
// Mark activity
|
|
160
|
+
eventDetector.markActivity();
|
|
161
|
+
});
|
|
162
|
+
// PTY exit handler
|
|
163
|
+
ptyWrapper.on('exit', (exitCode) => {
|
|
164
|
+
loggingService.info('PTY exited', { exitCode });
|
|
165
|
+
exit();
|
|
166
|
+
});
|
|
167
|
+
// PTY error handler
|
|
168
|
+
ptyWrapper.on('error', (err) => {
|
|
169
|
+
loggingService.error('PTY error', { error: err.message });
|
|
170
|
+
setError(err.message);
|
|
171
|
+
});
|
|
172
|
+
// Start PTY
|
|
173
|
+
ptyWrapper.start();
|
|
174
|
+
process.stdout.write('\x1b[?25h');
|
|
175
|
+
// Setup terminal resize handling
|
|
176
|
+
const handleResize = () => {
|
|
177
|
+
if (process.stdout.columns && process.stdout.rows) {
|
|
178
|
+
// Reserve bottom rows for status bar and AI response
|
|
179
|
+
ptyWrapper.resize(process.stdout.columns, process.stdout.rows - STATUS_BAR_RESERVED_ROWS);
|
|
180
|
+
}
|
|
181
|
+
};
|
|
182
|
+
process.stdout.on('resize', handleResize);
|
|
183
|
+
handleResize();
|
|
184
|
+
return () => {
|
|
185
|
+
process.stdout.off('resize', handleResize);
|
|
186
|
+
ptyWrapper.stop();
|
|
187
|
+
process.stdout.write('\x1b[?25h');
|
|
188
|
+
};
|
|
189
|
+
}, [
|
|
190
|
+
ptyWrapper,
|
|
191
|
+
contextBuffer,
|
|
192
|
+
commandOutputBuffer,
|
|
193
|
+
modeManager,
|
|
194
|
+
eventDetector,
|
|
195
|
+
settingsService,
|
|
196
|
+
loggingService,
|
|
197
|
+
exit,
|
|
198
|
+
]);
|
|
199
|
+
// Handle keyboard input
|
|
200
|
+
useInput((input, key) => {
|
|
201
|
+
// Ctrl+C to exit or abort
|
|
202
|
+
if (key.ctrl && input === 'c') {
|
|
203
|
+
if (isProcessing) {
|
|
204
|
+
companionSession.abort();
|
|
205
|
+
setIsProcessing(false);
|
|
206
|
+
}
|
|
207
|
+
else {
|
|
208
|
+
ptyWrapper.stop();
|
|
209
|
+
exit();
|
|
210
|
+
}
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
213
|
+
// Clear hint on any input
|
|
214
|
+
if (hint) {
|
|
215
|
+
setHint(undefined);
|
|
216
|
+
}
|
|
217
|
+
const isSpecialCommandInput = inputLine.startsWith('??') || inputLine.startsWith('!auto');
|
|
218
|
+
const ptySequence = getPtyInputSequence(input, key);
|
|
219
|
+
if (key.upArrow || key.downArrow || key.leftArrow || key.rightArrow) {
|
|
220
|
+
if (!isSpecialCommandInput && ptySequence) {
|
|
221
|
+
ptyWrapper.write(ptySequence);
|
|
222
|
+
}
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
// Build up input line to detect ?? and !auto commands
|
|
226
|
+
let newInputLine = inputLine;
|
|
227
|
+
if (input === '\r' || input === '\n') {
|
|
228
|
+
const parsed = parseCompanionInput(inputLine);
|
|
229
|
+
if (parsed.type === 'query') {
|
|
230
|
+
// ?? query detected - handle with AI instead of passing to shell
|
|
231
|
+
handleQuery(parsed.content);
|
|
232
|
+
setInputLine('');
|
|
233
|
+
// Write newline to keep terminal output clean
|
|
234
|
+
process.stdout.write('\n');
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
if (parsed.type === 'auto') {
|
|
238
|
+
// !auto command detected - handle with AI instead of passing to shell
|
|
239
|
+
handleAutoTask(parsed.content);
|
|
240
|
+
setInputLine('');
|
|
241
|
+
// Write newline to keep terminal output clean
|
|
242
|
+
process.stdout.write('\n');
|
|
243
|
+
return;
|
|
244
|
+
}
|
|
245
|
+
// Normal command - pass Enter to PTY and track for context
|
|
246
|
+
ptyWrapper.write(input);
|
|
247
|
+
if (inputLine.trim()) {
|
|
248
|
+
commandOutputBuffer.startCommand(inputLine.trim());
|
|
249
|
+
}
|
|
250
|
+
setInputLine('');
|
|
251
|
+
return;
|
|
252
|
+
}
|
|
253
|
+
if (key.backspace || key.delete) {
|
|
254
|
+
newInputLine = inputLine.slice(0, -1);
|
|
255
|
+
setInputLine(newInputLine);
|
|
256
|
+
if (isSpecialCommandInput) {
|
|
257
|
+
process.stdout.write('\b \b');
|
|
258
|
+
return;
|
|
259
|
+
}
|
|
260
|
+
if (ptySequence) {
|
|
261
|
+
ptyWrapper.write(ptySequence);
|
|
262
|
+
}
|
|
263
|
+
return;
|
|
264
|
+
}
|
|
265
|
+
// Accumulate input
|
|
266
|
+
newInputLine = inputLine + input;
|
|
267
|
+
setInputLine(newInputLine);
|
|
268
|
+
// Check if we're building a ?? or !auto command
|
|
269
|
+
// If so, echo locally but don't send to PTY yet
|
|
270
|
+
if (newInputLine.startsWith('??') || newInputLine.startsWith('!auto')) {
|
|
271
|
+
// Echo the character locally (since we're not sending to PTY)
|
|
272
|
+
process.stdout.write(input);
|
|
273
|
+
}
|
|
274
|
+
else {
|
|
275
|
+
// Normal input - pass through to PTY
|
|
276
|
+
ptyWrapper.write(input);
|
|
277
|
+
}
|
|
278
|
+
});
|
|
279
|
+
if (error) {
|
|
280
|
+
return (React.createElement(Box, { flexDirection: "column" },
|
|
281
|
+
React.createElement(Text, { color: "red" },
|
|
282
|
+
"Error: ",
|
|
283
|
+
error),
|
|
284
|
+
React.createElement(Text, { color: "gray" }, "Press Ctrl+C to exit")));
|
|
285
|
+
}
|
|
286
|
+
// The main rendering is handled by PTY direct output to stdout
|
|
287
|
+
// We only render the status bar and AI response via Ink
|
|
288
|
+
const defaultRows = 24; // Standard terminal height fallback
|
|
289
|
+
const marginTop = process.stdout.rows
|
|
290
|
+
? process.stdout.rows - STATUS_BAR_RESERVED_ROWS
|
|
291
|
+
: defaultRows - STATUS_BAR_RESERVED_ROWS;
|
|
292
|
+
return (React.createElement(Box, { flexDirection: "column", position: "absolute", marginTop: marginTop },
|
|
293
|
+
aiResponse && (React.createElement(Box, { borderStyle: "single", borderColor: "cyan", paddingX: 1, marginBottom: 1 },
|
|
294
|
+
React.createElement(Text, { color: "cyan" }, aiResponse))),
|
|
295
|
+
React.createElement(StatusBar, { mode: currentMode, hint: hint, isProcessing: isProcessing })));
|
|
296
|
+
};
|
|
297
|
+
//# sourceMappingURL=companion-app.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"companion-app.js","sourceRoot":"","sources":["../../../source/modes/companion/companion-app.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import type { ContextBuffer } from './context-buffer.js';
|
|
2
|
+
import type { Summarizer } from './summarizer.js';
|
|
3
|
+
import type { ISettingsService, ILoggingService } from '../../services/service-interfaces.js';
|
|
4
|
+
import type { CompanionMode } from './mode-manager.js';
|
|
5
|
+
export interface CompanionAgentClient {
|
|
6
|
+
chat: (message: string, options?: {
|
|
7
|
+
model?: string;
|
|
8
|
+
reasoningEffort?: string;
|
|
9
|
+
instructions?: string;
|
|
10
|
+
}) => Promise<string>;
|
|
11
|
+
startStream: (userInput: string | any[], options?: {
|
|
12
|
+
previousResponseId?: string | null;
|
|
13
|
+
}) => Promise<any>;
|
|
14
|
+
abort: () => void;
|
|
15
|
+
}
|
|
16
|
+
export interface CompanionSessionDeps {
|
|
17
|
+
contextBuffer: ContextBuffer;
|
|
18
|
+
summarizer: Summarizer;
|
|
19
|
+
settings: ISettingsService;
|
|
20
|
+
logger: ILoggingService;
|
|
21
|
+
agentClient?: CompanionAgentClient;
|
|
22
|
+
}
|
|
23
|
+
export interface CompanionEvent {
|
|
24
|
+
type: 'text' | 'tool_call' | 'complete' | 'error' | 'approval_required' | 'blocked';
|
|
25
|
+
content?: string;
|
|
26
|
+
tool?: string;
|
|
27
|
+
args?: unknown;
|
|
28
|
+
safety?: 'green' | 'yellow' | 'red';
|
|
29
|
+
reason?: string;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Lightweight session for companion mode queries.
|
|
33
|
+
*
|
|
34
|
+
* Unlike chat mode's ConversationSession:
|
|
35
|
+
* - No persistent conversation history (each query is standalone)
|
|
36
|
+
* - No previousResponseId chaining
|
|
37
|
+
* - Simpler approval flow (Auto mode only)
|
|
38
|
+
*/
|
|
39
|
+
export declare class CompanionSession {
|
|
40
|
+
#private;
|
|
41
|
+
constructor(deps: CompanionSessionDeps);
|
|
42
|
+
/**
|
|
43
|
+
* Get the summarizer instance (for terminal_history tool integration).
|
|
44
|
+
*/
|
|
45
|
+
get summarizer(): Summarizer;
|
|
46
|
+
get mode(): CompanionMode;
|
|
47
|
+
setMode(mode: CompanionMode): void;
|
|
48
|
+
/**
|
|
49
|
+
* Handle a ?? query in Watch mode.
|
|
50
|
+
* Creates ephemeral session, streams response, then disposes.
|
|
51
|
+
*/
|
|
52
|
+
handleWatchQuery(query: string): AsyncGenerator<CompanionEvent>;
|
|
53
|
+
/**
|
|
54
|
+
* Handle !auto task in Auto mode.
|
|
55
|
+
* Full agent loop with tool execution.
|
|
56
|
+
*/
|
|
57
|
+
handleAutoTask(task: string): AsyncGenerator<CompanionEvent>;
|
|
58
|
+
/**
|
|
59
|
+
* Abort the current operation.
|
|
60
|
+
*/
|
|
61
|
+
abort(): void;
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=companion-session.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"companion-session.d.ts","sourceRoot":"","sources":["../../../source/modes/companion/companion-session.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,qBAAqB,CAAC;AACvD,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,iBAAiB,CAAC;AAChD,OAAO,KAAK,EAAC,gBAAgB,EAAE,eAAe,EAAC,MAAM,sCAAsC,CAAC;AAE5F,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,mBAAmB,CAAC;AAErD,MAAM,WAAW,oBAAoB;IACjC,IAAI,EAAE,CACF,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE;QACN,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,YAAY,CAAC,EAAE,MAAM,CAAC;KACzB,KACA,OAAO,CAAC,MAAM,CAAC,CAAC;IACrB,WAAW,EAAE,CACT,SAAS,EAAE,MAAM,GAAG,GAAG,EAAE,EACzB,OAAO,CAAC,EAAE;QAAC,kBAAkB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;KAAC,KAC7C,OAAO,CAAC,GAAG,CAAC,CAAC;IAClB,KAAK,EAAE,MAAM,IAAI,CAAC;CACrB;AAED,MAAM,WAAW,oBAAoB;IACjC,aAAa,EAAE,aAAa,CAAC;IAC7B,UAAU,EAAE,UAAU,CAAC;IACvB,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,MAAM,EAAE,eAAe,CAAC;IACxB,WAAW,CAAC,EAAE,oBAAoB,CAAC;CACtC;AAED,MAAM,WAAW,cAAc;IAC3B,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,UAAU,GAAG,OAAO,GAAG,mBAAmB,GAAG,SAAS,CAAC;IACpF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,KAAK,CAAC;IACpC,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;GAOG;AACH,qBAAa,gBAAgB;;gBAQb,IAAI,EAAE,oBAAoB;IAQtC;;OAEG;IACH,IAAI,UAAU,IAAI,UAAU,CAE3B;IAED,IAAI,IAAI,IAAI,aAAa,CAExB;IAED,OAAO,CAAC,IAAI,EAAE,aAAa,GAAG,IAAI;IAKlC;;;OAGG;IACI,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,cAAc,CAAC,cAAc,CAAC;IAmCtE;;;OAGG;IACI,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,CAAC,cAAc,CAAC;IAqDnE;;OAEG;IACH,KAAK,IAAI,IAAI;CAwBhB"}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import { OpenAIAgentClient } from '../../lib/openai-agent-client.js';
|
|
2
|
+
import { generateCommandIndexPrompt } from './command-index.js';
|
|
3
|
+
/**
|
|
4
|
+
* Lightweight session for companion mode queries.
|
|
5
|
+
*
|
|
6
|
+
* Unlike chat mode's ConversationSession:
|
|
7
|
+
* - No persistent conversation history (each query is standalone)
|
|
8
|
+
* - No previousResponseId chaining
|
|
9
|
+
* - Simpler approval flow (Auto mode only)
|
|
10
|
+
*/
|
|
11
|
+
export class CompanionSession {
|
|
12
|
+
#agentClient = null;
|
|
13
|
+
#contextBuffer;
|
|
14
|
+
#summarizer;
|
|
15
|
+
#settings;
|
|
16
|
+
#logger;
|
|
17
|
+
#currentMode = 'watch';
|
|
18
|
+
constructor(deps) {
|
|
19
|
+
this.#contextBuffer = deps.contextBuffer;
|
|
20
|
+
this.#summarizer = deps.summarizer;
|
|
21
|
+
this.#settings = deps.settings;
|
|
22
|
+
this.#logger = deps.logger;
|
|
23
|
+
this.#agentClient = deps.agentClient ?? null;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Get the summarizer instance (for terminal_history tool integration).
|
|
27
|
+
*/
|
|
28
|
+
get summarizer() {
|
|
29
|
+
return this.#summarizer;
|
|
30
|
+
}
|
|
31
|
+
get mode() {
|
|
32
|
+
return this.#currentMode;
|
|
33
|
+
}
|
|
34
|
+
setMode(mode) {
|
|
35
|
+
this.#currentMode = mode;
|
|
36
|
+
this.#logger.info(`Companion mode changed to: ${mode}`);
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Handle a ?? query in Watch mode.
|
|
40
|
+
* Creates ephemeral session, streams response, then disposes.
|
|
41
|
+
*/
|
|
42
|
+
async *handleWatchQuery(query) {
|
|
43
|
+
try {
|
|
44
|
+
const client = this.#getOrCreateClient();
|
|
45
|
+
const commandIndex = this.#contextBuffer.getIndex();
|
|
46
|
+
const contextPrompt = generateCommandIndexPrompt(commandIndex);
|
|
47
|
+
// Build the full query with context
|
|
48
|
+
const fullQuery = query
|
|
49
|
+
? `${contextPrompt}\n\nUser question: ${query}`
|
|
50
|
+
: `${contextPrompt}\n\nThe user typed ?? for help. Analyze the recent commands and provide helpful suggestions.`;
|
|
51
|
+
this.#logger.info('Handling watch query', {
|
|
52
|
+
query: query.slice(0, 100),
|
|
53
|
+
commandCount: commandIndex.length,
|
|
54
|
+
});
|
|
55
|
+
const response = await client.chat(fullQuery, {
|
|
56
|
+
model: this.#settings.get('agent.model'),
|
|
57
|
+
reasoningEffort: this.#settings.get('agent.reasoningEffort'),
|
|
58
|
+
instructions: 'You are a helpful terminal assistant. Answer directly without calling tools.',
|
|
59
|
+
});
|
|
60
|
+
if (response) {
|
|
61
|
+
yield { type: 'text', content: response };
|
|
62
|
+
}
|
|
63
|
+
yield { type: 'complete' };
|
|
64
|
+
}
|
|
65
|
+
catch (error) {
|
|
66
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
67
|
+
this.#logger.error('Watch query failed', { error: message });
|
|
68
|
+
yield { type: 'error', content: message };
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Handle !auto task in Auto mode.
|
|
73
|
+
* Full agent loop with tool execution.
|
|
74
|
+
*/
|
|
75
|
+
async *handleAutoTask(task) {
|
|
76
|
+
this.setMode('auto');
|
|
77
|
+
try {
|
|
78
|
+
const client = this.#getOrCreateClient();
|
|
79
|
+
const commandIndex = this.#contextBuffer.getIndex();
|
|
80
|
+
const contextPrompt = generateCommandIndexPrompt(commandIndex);
|
|
81
|
+
const fullTask = `${contextPrompt}\n\nUser task: ${task}\n\nYou are in Auto mode. Execute commands to complete this task. Use the shell tool to run commands.`;
|
|
82
|
+
this.#logger.info('Handling auto task', {
|
|
83
|
+
task: task.slice(0, 100),
|
|
84
|
+
commandCount: commandIndex.length,
|
|
85
|
+
});
|
|
86
|
+
// Stream response using existing API
|
|
87
|
+
const stream = await client.startStream(fullTask);
|
|
88
|
+
for await (const event of stream) {
|
|
89
|
+
if (event?.type === 'text_delta' || event?.data?.type === 'output_text') {
|
|
90
|
+
const delta = event?.data?.delta ?? event?.delta ?? '';
|
|
91
|
+
if (delta) {
|
|
92
|
+
yield { type: 'text', content: delta };
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
// Check for tool calls
|
|
96
|
+
if (event?.type === 'tool_call' || event?.item?.type === 'function_call') {
|
|
97
|
+
const toolName = event?.name ?? event?.item?.name ?? event?.item?.rawItem?.name;
|
|
98
|
+
const toolArgs = event?.arguments ?? event?.item?.arguments ?? event?.item?.rawItem?.arguments;
|
|
99
|
+
if (toolName) {
|
|
100
|
+
yield {
|
|
101
|
+
type: 'tool_call',
|
|
102
|
+
tool: toolName,
|
|
103
|
+
args: toolArgs,
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
yield { type: 'complete' };
|
|
109
|
+
}
|
|
110
|
+
catch (error) {
|
|
111
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
112
|
+
this.#logger.error('Auto task failed', { error: message });
|
|
113
|
+
yield { type: 'error', content: message };
|
|
114
|
+
}
|
|
115
|
+
finally {
|
|
116
|
+
this.setMode('watch');
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Abort the current operation.
|
|
121
|
+
*/
|
|
122
|
+
abort() {
|
|
123
|
+
if (this.#agentClient) {
|
|
124
|
+
this.#agentClient.abort();
|
|
125
|
+
}
|
|
126
|
+
this.setMode('watch');
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Get or create the agent client.
|
|
130
|
+
*/
|
|
131
|
+
#getOrCreateClient() {
|
|
132
|
+
if (!this.#agentClient) {
|
|
133
|
+
this.#agentClient = new OpenAIAgentClient({
|
|
134
|
+
model: this.#settings.get('agent.model'),
|
|
135
|
+
reasoningEffort: this.#settings.get('agent.reasoningEffort'),
|
|
136
|
+
maxTurns: 10, // Lower than chat mode - companion queries should be quick
|
|
137
|
+
deps: {
|
|
138
|
+
settings: this.#settings,
|
|
139
|
+
logger: this.#logger,
|
|
140
|
+
},
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
return this.#agentClient;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
//# sourceMappingURL=companion-session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"companion-session.js","sourceRoot":"","sources":["../../../source/modes/companion/companion-session.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"companion-session.test.d.ts","sourceRoot":"","sources":["../../../source/modes/companion/companion-session.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import test from 'ava';
|
|
2
|
+
import { CompanionSession } from './companion-session.js';
|
|
3
|
+
test('handleWatchQuery uses chat and yields text', async (t) => {
|
|
4
|
+
const events = [];
|
|
5
|
+
const fakeClient = {
|
|
6
|
+
chat: async (message) => {
|
|
7
|
+
t.true(message.includes('User question: why did this fail'));
|
|
8
|
+
return 'Try rerunning with verbose logging.';
|
|
9
|
+
},
|
|
10
|
+
startStream: async () => {
|
|
11
|
+
throw new Error('startStream should not be called for watch queries');
|
|
12
|
+
},
|
|
13
|
+
abort: () => undefined,
|
|
14
|
+
};
|
|
15
|
+
const session = new CompanionSession({
|
|
16
|
+
contextBuffer: { getIndex: () => [] },
|
|
17
|
+
summarizer: {},
|
|
18
|
+
settings: { get: () => 'gpt-5' },
|
|
19
|
+
logger: { info: () => undefined, error: () => undefined },
|
|
20
|
+
agentClient: fakeClient,
|
|
21
|
+
});
|
|
22
|
+
for await (const event of session.handleWatchQuery('why did this fail')) {
|
|
23
|
+
events.push(event);
|
|
24
|
+
}
|
|
25
|
+
t.true(events.some(event => event.type === 'text' && event.content === 'Try rerunning with verbose logging.'));
|
|
26
|
+
t.is(events[events.length - 1]?.type, 'complete');
|
|
27
|
+
});
|
|
28
|
+
//# sourceMappingURL=companion-session.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"companion-session.test.js","sourceRoot":"","sources":["../../../source/modes/companion/companion-session.test.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,KAAK,CAAC;AACvB,OAAO,EAAC,gBAAgB,EAAC,MAAM,wBAAwB,CAAC;AAExD,IAAI,CAAC,4CAA4C,EAAE,KAAK,EAAC,CAAC,EAAC,EAAE;IACzD,MAAM,MAAM,GAAU,EAAE,CAAC;IACzB,MAAM,UAAU,GAAG;QACf,IAAI,EAAE,KAAK,EAAE,OAAe,EAAE,EAAE;YAC5B,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,kCAAkC,CAAC,CAAC,CAAC;YAC7D,OAAO,qCAAqC,CAAC;QACjD,CAAC;QACD,WAAW,EAAE,KAAK,IAAI,EAAE;YACpB,MAAM,IAAI,KAAK,CAAC,oDAAoD,CAAC,CAAC;QAC1E,CAAC;QACD,KAAK,EAAE,GAAG,EAAE,CAAC,SAAS;KACzB,CAAC;IAEF,MAAM,OAAO,GAAG,IAAI,gBAAgB,CAAC;QACjC,aAAa,EAAE,EAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,EAAE,EAAQ;QAC1C,UAAU,EAAE,EAAS;QACrB,QAAQ,EAAE,EAAC,GAAG,EAAE,GAAG,EAAE,CAAC,OAAO,EAAQ;QACrC,MAAM,EAAE,EAAC,IAAI,EAAE,GAAG,EAAE,CAAC,SAAS,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,SAAS,EAAQ;QAC9D,WAAW,EAAE,UAAiB;KACjC,CAAC,CAAC;IAEH,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,OAAO,CAAC,gBAAgB,CAAC,mBAAmB,CAAC,EAAE,CAAC;QACtE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACvB,CAAC;IAED,CAAC,CAAC,IAAI,CACF,MAAM,CAAC,IAAI,CACP,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,MAAM,IAAI,KAAK,CAAC,OAAO,KAAK,qCAAqC,CAC5F,CACJ,CAAC;IACF,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC;AACtD,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { CompanionMode } from '../mode-manager.js';
|
|
3
|
+
export interface StatusBarProps {
|
|
4
|
+
mode: CompanionMode;
|
|
5
|
+
hint?: string;
|
|
6
|
+
isProcessing?: boolean;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Status bar component for companion mode.
|
|
10
|
+
* Shows current mode, help hints, and processing status.
|
|
11
|
+
*/
|
|
12
|
+
export declare const StatusBar: React.FC<StatusBarProps>;
|
|
13
|
+
//# sourceMappingURL=status-bar.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status-bar.d.ts","sourceRoot":"","sources":["../../../../source/modes/companion/components/status-bar.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,oBAAoB,CAAC;AAEtD,MAAM,WAAW,cAAc;IAC3B,IAAI,EAAE,aAAa,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED;;;GAGG;AACH,eAAO,MAAM,SAAS,EAAE,KAAK,CAAC,EAAE,CAAC,cAAc,CAuC9C,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Box, Text } from 'ink';
|
|
3
|
+
/**
|
|
4
|
+
* Status bar component for companion mode.
|
|
5
|
+
* Shows current mode, help hints, and processing status.
|
|
6
|
+
*/
|
|
7
|
+
export const StatusBar = ({ mode, hint, isProcessing = false, }) => {
|
|
8
|
+
const modeIcon = mode === 'watch' ? '👁' : '🤖';
|
|
9
|
+
const modeLabel = mode === 'watch' ? 'Watch' : 'Auto';
|
|
10
|
+
return (React.createElement(Box, { flexDirection: "row", justifyContent: "space-between", paddingX: 1, borderStyle: "single", borderColor: "gray" },
|
|
11
|
+
React.createElement(Box, null,
|
|
12
|
+
React.createElement(Text, { color: "cyan" },
|
|
13
|
+
"[",
|
|
14
|
+
modeLabel,
|
|
15
|
+
"] ",
|
|
16
|
+
modeIcon),
|
|
17
|
+
isProcessing && (React.createElement(Text, { color: "yellow" }, " \u23F3 Processing..."))),
|
|
18
|
+
React.createElement(Box, null,
|
|
19
|
+
React.createElement(Text, { color: "gray" }, "?? for help"),
|
|
20
|
+
mode === 'watch' && (React.createElement(Text, { color: "gray" }, " \u2502 !auto to delegate"))),
|
|
21
|
+
hint && (React.createElement(Box, null,
|
|
22
|
+
React.createElement(Text, { color: "yellow" },
|
|
23
|
+
"\uD83D\uDCA1 ",
|
|
24
|
+
hint)))));
|
|
25
|
+
};
|
|
26
|
+
//# sourceMappingURL=status-bar.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status-bar.js","sourceRoot":"","sources":["../../../../source/modes/companion/components/status-bar.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAC,GAAG,EAAE,IAAI,EAAC,MAAM,KAAK,CAAC;AAS9B;;;GAGG;AACH,MAAM,CAAC,MAAM,SAAS,GAA6B,CAAC,EAChD,IAAI,EACJ,IAAI,EACJ,YAAY,GAAG,KAAK,GACvB,EAAE,EAAE;IACD,MAAM,QAAQ,GAAG,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;IAChD,MAAM,SAAS,GAAG,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC;IAEtD,OAAO,CACH,oBAAC,GAAG,IACA,aAAa,EAAC,KAAK,EACnB,cAAc,EAAC,eAAe,EAC9B,QAAQ,EAAE,CAAC,EACX,WAAW,EAAC,QAAQ,EACpB,WAAW,EAAC,MAAM;QAElB,oBAAC,GAAG;YACA,oBAAC,IAAI,IAAC,KAAK,EAAC,MAAM;;gBACZ,SAAS;;gBAAI,QAAQ,CACpB;YACN,YAAY,IAAI,CACb,oBAAC,IAAI,IAAC,KAAK,EAAC,QAAQ,4BAAwB,CAC/C,CACC;QAEN,oBAAC,GAAG;YACA,oBAAC,IAAI,IAAC,KAAK,EAAC,MAAM,kBAAmB;YACpC,IAAI,KAAK,OAAO,IAAI,CACjB,oBAAC,IAAI,IAAC,KAAK,EAAC,MAAM,gCAA4B,CACjD,CACC;QAEL,IAAI,IAAI,CACL,oBAAC,GAAG;YACA,oBAAC,IAAI,IAAC,KAAK,EAAC,QAAQ;;gBAAK,IAAI,CAAQ,CACnC,CACT,CACC,CACT,CAAC;AACN,CAAC,CAAC"}
|