@eyeglass/bridge 0.1.4 → 0.1.5
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/http.js +91 -0
- package/package.json +1 -1
package/dist/http.js
CHANGED
|
@@ -85,6 +85,97 @@ export function startHttpServer() {
|
|
|
85
85
|
}
|
|
86
86
|
res.json({ success: true, message: result.message });
|
|
87
87
|
});
|
|
88
|
+
// ============================================================================
|
|
89
|
+
// REST API for non-MCP agents (Codex CLI, Aider, etc.)
|
|
90
|
+
// These mirror the MCP tools but over HTTP
|
|
91
|
+
// ============================================================================
|
|
92
|
+
// Get current focus as markdown (mirrors get_focused_element)
|
|
93
|
+
app.get('/api/focus', (_req, res) => {
|
|
94
|
+
res.type('text/markdown').send(store.formatAsMarkdown());
|
|
95
|
+
});
|
|
96
|
+
// Wait for a new focus request (mirrors wait_for_request)
|
|
97
|
+
// This is a blocking/long-polling endpoint
|
|
98
|
+
app.get('/api/wait', async (req, res) => {
|
|
99
|
+
const timeout = parseInt(req.query.timeout) || 300000; // 5 min default
|
|
100
|
+
try {
|
|
101
|
+
await store.waitForFocus(timeout);
|
|
102
|
+
res.type('text/markdown').send(store.formatAsMarkdown());
|
|
103
|
+
}
|
|
104
|
+
catch (err) {
|
|
105
|
+
res.status(408).json({ error: 'Timeout waiting for focus request' });
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
// Update status (mirrors update_status)
|
|
109
|
+
app.post('/api/status', (req, res) => {
|
|
110
|
+
const { status, message } = req.body;
|
|
111
|
+
if (!status || !['idle', 'pending', 'fixing', 'success', 'failed'].includes(status)) {
|
|
112
|
+
res.status(400).json({ error: 'Invalid status. Must be: idle, pending, fixing, success, or failed' });
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
const active = store.getActive();
|
|
116
|
+
if (!active) {
|
|
117
|
+
res.status(404).json({ error: 'No active focus' });
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
store.updateStatus(active.interactionId, status, message);
|
|
121
|
+
res.json({ success: true, status, message });
|
|
122
|
+
});
|
|
123
|
+
// Send a thought (mirrors send_thought)
|
|
124
|
+
app.post('/api/thought', (req, res) => {
|
|
125
|
+
const { content } = req.body;
|
|
126
|
+
if (!content || typeof content !== 'string') {
|
|
127
|
+
res.status(400).json({ error: 'Missing or invalid content' });
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
const active = store.getActive();
|
|
131
|
+
if (!active) {
|
|
132
|
+
res.status(404).json({ error: 'No active focus' });
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
store.sendThought(active.interactionId, content);
|
|
136
|
+
res.json({ success: true });
|
|
137
|
+
});
|
|
138
|
+
// Report an action (mirrors report_action)
|
|
139
|
+
app.post('/api/action', (req, res) => {
|
|
140
|
+
const { action, target, complete } = req.body;
|
|
141
|
+
if (!action || !['reading', 'writing', 'searching', 'thinking'].includes(action)) {
|
|
142
|
+
res.status(400).json({ error: 'Invalid action. Must be: reading, writing, searching, or thinking' });
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
if (!target || typeof target !== 'string') {
|
|
146
|
+
res.status(400).json({ error: 'Missing or invalid target' });
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
const active = store.getActive();
|
|
150
|
+
if (!active) {
|
|
151
|
+
res.status(404).json({ error: 'No active focus' });
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
store.reportAction(active.interactionId, action, target, complete ?? false);
|
|
155
|
+
res.json({ success: true });
|
|
156
|
+
});
|
|
157
|
+
// Get focus history (mirrors get_focus_history)
|
|
158
|
+
app.get('/api/history', (_req, res) => {
|
|
159
|
+
const history = store.getHistory();
|
|
160
|
+
if (history.length === 0) {
|
|
161
|
+
res.type('text/markdown').send('# No Focus History\n\nNo previous focus requests.');
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
const summary = history
|
|
165
|
+
.map((p, i) => {
|
|
166
|
+
const { snapshot, snapshots, userNote } = p;
|
|
167
|
+
const firstSnapshot = snapshot || (snapshots && snapshots[0]);
|
|
168
|
+
if (!firstSnapshot)
|
|
169
|
+
return `${i + 1}. **unknown** - "${userNote}"`;
|
|
170
|
+
const elementCount = snapshots ? ` (${snapshots.length} elements)` : '';
|
|
171
|
+
return `${i + 1}. **${firstSnapshot.framework.componentName || firstSnapshot.tagName}**${elementCount} - "${userNote}"`;
|
|
172
|
+
})
|
|
173
|
+
.join('\n');
|
|
174
|
+
res.type('text/markdown').send(`## Focus History\n\n${summary}`);
|
|
175
|
+
});
|
|
176
|
+
// ============================================================================
|
|
177
|
+
// SSE and Browser endpoints
|
|
178
|
+
// ============================================================================
|
|
88
179
|
// SSE endpoint for real-time activity updates
|
|
89
180
|
app.get('/events', (req, res) => {
|
|
90
181
|
res.setHeader('Content-Type', 'text/event-stream');
|