paneful 0.5.2 → 0.6.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/dist/server/index.js
CHANGED
|
@@ -204,14 +204,27 @@ function startServer(devMode, port) {
|
|
|
204
204
|
const killed = ptyManager.killProject(req.params.id);
|
|
205
205
|
res.json({ killed: killed.length });
|
|
206
206
|
});
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
if (
|
|
210
|
-
res.json({
|
|
207
|
+
app.post('/api/validate-path', (req, res) => {
|
|
208
|
+
const { path: rawPath } = req.body;
|
|
209
|
+
if (!rawPath) {
|
|
210
|
+
res.json({ valid: false });
|
|
211
211
|
return;
|
|
212
212
|
}
|
|
213
|
-
|
|
214
|
-
|
|
213
|
+
const resolved = rawPath.replace(/^~/, os.homedir());
|
|
214
|
+
try {
|
|
215
|
+
const stat = fs.statSync(resolved);
|
|
216
|
+
res.json({ valid: stat.isDirectory(), resolved });
|
|
217
|
+
}
|
|
218
|
+
catch {
|
|
219
|
+
res.json({ valid: false });
|
|
220
|
+
}
|
|
221
|
+
});
|
|
222
|
+
// Active editor detection — polls server-side so the client gets an instant cached response
|
|
223
|
+
const editorPatterns = ['cursor', 'code', 'vscode', 'visual studio code', 'zed', 'windsurf'];
|
|
224
|
+
let editorCache = { projectName: null };
|
|
225
|
+
function pollActiveEditor() {
|
|
226
|
+
if (process.platform !== 'darwin')
|
|
227
|
+
return;
|
|
215
228
|
const findScript = `
|
|
216
229
|
tell application "System Events"
|
|
217
230
|
set procNames to name of every process whose background only is false
|
|
@@ -225,16 +238,15 @@ function startServer(devMode, port) {
|
|
|
225
238
|
execFile('osascript', ['-e', findScript], { timeout: 2000 }, (err, stdout, stderr) => {
|
|
226
239
|
if (err) {
|
|
227
240
|
const needsAccess = stderr?.includes('not allowed assistive access') || stderr?.includes('1719');
|
|
228
|
-
|
|
241
|
+
editorCache = { projectName: null, needsAccessibility: needsAccess || undefined };
|
|
229
242
|
return;
|
|
230
243
|
}
|
|
231
244
|
const processes = stdout.trim().split('\n').map((p) => p.trim()).filter(Boolean);
|
|
232
245
|
const editorProcess = processes.find((p) => editorPatterns.some((pat) => p.toLowerCase().includes(pat)));
|
|
233
246
|
if (!editorProcess) {
|
|
234
|
-
|
|
247
|
+
editorCache = { projectName: null };
|
|
235
248
|
return;
|
|
236
249
|
}
|
|
237
|
-
// Step 2: Get the front window title of the matched editor
|
|
238
250
|
const titleScript = `
|
|
239
251
|
tell application "System Events"
|
|
240
252
|
tell process "${editorProcess.replace(/"/g, '\\"')}"
|
|
@@ -247,7 +259,7 @@ function startServer(devMode, port) {
|
|
|
247
259
|
`;
|
|
248
260
|
execFile('osascript', ['-e', titleScript], { timeout: 2000 }, (err2, stdout2) => {
|
|
249
261
|
if (err2 || !stdout2.trim()) {
|
|
250
|
-
|
|
262
|
+
editorCache = { projectName: null };
|
|
251
263
|
return;
|
|
252
264
|
}
|
|
253
265
|
const title = stdout2.trim();
|
|
@@ -255,7 +267,6 @@ function startServer(devMode, port) {
|
|
|
255
267
|
// Try to extract a path from the title (e.g. "~/Documents/source/foo - branch")
|
|
256
268
|
const pathMatch = title.match(/^(~?\/[^\s]+)/);
|
|
257
269
|
if (pathMatch) {
|
|
258
|
-
// Grab the deepest folder from the path
|
|
259
270
|
const segments = pathMatch[1].replace(/\/$/, '').split('/');
|
|
260
271
|
projectName = segments[segments.length - 1] || null;
|
|
261
272
|
}
|
|
@@ -269,9 +280,20 @@ function startServer(devMode, port) {
|
|
|
269
280
|
projectName = parts[0];
|
|
270
281
|
}
|
|
271
282
|
}
|
|
272
|
-
|
|
283
|
+
const prev = editorCache.projectName;
|
|
284
|
+
editorCache = { projectName };
|
|
285
|
+
// Push change to client over WebSocket
|
|
286
|
+
if (projectName && projectName !== prev) {
|
|
287
|
+
wsHandler.send({ type: 'editor:active', projectName });
|
|
288
|
+
}
|
|
273
289
|
});
|
|
274
290
|
});
|
|
291
|
+
}
|
|
292
|
+
// Poll every 2 seconds server-side
|
|
293
|
+
pollActiveEditor();
|
|
294
|
+
setInterval(pollActiveEditor, 2000);
|
|
295
|
+
app.get('/api/active-editor', (_req, res) => {
|
|
296
|
+
res.json(editorCache);
|
|
275
297
|
});
|
|
276
298
|
// Resolve a dropped file's full path using OS file index (Spotlight on macOS)
|
|
277
299
|
app.post('/api/resolve-path', (req, res) => {
|