ftown-bridge 0.19.11 → 0.19.12

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ftown-bridge",
3
- "version": "0.19.11",
3
+ "version": "0.19.12",
4
4
  "description": "CLI bridge for ftown — generic PTY-over-Centrifugo relay",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -361,14 +361,35 @@ export function registerFtownPiExtension(pi, options = {}) {
361
361
  });
362
362
 
363
363
  async function runSessions(params) {
364
- requireOperation(params, ['list', 'archive', 'get', 'usage', 'running', 'screen', 'grep']);
365
- if (!['list', 'archive'].includes(params.operation)) requireString(params, 'target');
364
+ requireOperation(params, ['list', 'children', 'archive', 'get', 'usage', 'running', 'screen', 'grep']);
365
+ if (!['list', 'children', 'archive'].includes(params.operation)) requireString(params, 'target');
366
366
  if (params.operation === 'grep') requireString(params, 'pattern');
367
367
  if (params.operation === 'archive') {
368
368
  return requestJson('/api/archive', { method: 'GET' });
369
369
  }
370
370
  const sessions = await listSessions();
371
- if (params.operation === 'list') return { sessions };
371
+ const filterByPattern = (candidates) => {
372
+ if (!params.pattern) return candidates;
373
+ let pattern;
374
+ try {
375
+ pattern = new RegExp(params.pattern, 'i');
376
+ } catch (error) {
377
+ throw new Error(`Invalid session pattern: ${error instanceof Error ? error.message : String(error)}`);
378
+ }
379
+ return candidates.filter((session) =>
380
+ Object.values(session).some((value) => typeof value === 'string' && pattern.test(value)));
381
+ };
382
+ if (params.operation === 'children') {
383
+ const parentSessionId = params.target
384
+ ? resolveSession(sessions, params.target).id
385
+ : ftownSessionId;
386
+ if (!parentSessionId) throw new Error('children requires target outside an ftown session');
387
+ const children = sessions.filter((session) => session.parentSessionId === parentSessionId);
388
+ return { sessions: filterByPattern(children) };
389
+ }
390
+ if (params.operation === 'list') {
391
+ return { sessions: filterByPattern(sessions) };
392
+ }
372
393
  const session = resolveSession(sessions, params.target);
373
394
  if (params.operation === 'get') {
374
395
  return requestJson(`/api/sessions/${encodeURIComponent(session.id)}`, { method: 'GET' });
@@ -400,7 +421,10 @@ export function registerFtownPiExtension(pi, options = {}) {
400
421
  });
401
422
  }
402
423
 
403
- const targetProperty = { type: 'string', description: 'Session id or unique exact name.' };
424
+ const targetProperty = {
425
+ type: 'string',
426
+ description: 'Session id or unique exact name; optional parent for children (defaults to current session).',
427
+ };
404
428
  const pageProperties = {
405
429
  offset: { type: 'integer', minimum: 0 },
406
430
  limit: { type: 'integer', minimum: 1, maximum: 1000 },
@@ -409,16 +433,19 @@ export function registerFtownPiExtension(pi, options = {}) {
409
433
  pi.registerTool({
410
434
  name: 'ftown_sessions',
411
435
  label: 'ftown sessions',
412
- description: 'List or inspect ftown sessions, running state, archive, token usage, terminal screen, and terminal log matches.',
436
+ description: 'List, filter, or inspect ftown sessions, including children, running state, archive, token usage, terminal screen, and terminal log matches.',
413
437
  parameters: {
414
438
  type: 'object',
415
439
  properties: {
416
440
  operation: {
417
441
  type: 'string',
418
- enum: ['list', 'archive', 'get', 'usage', 'running', 'screen', 'grep'],
442
+ enum: ['list', 'children', 'archive', 'get', 'usage', 'running', 'screen', 'grep'],
419
443
  },
420
444
  target: targetProperty,
421
- pattern: { type: 'string', minLength: 1 },
445
+ pattern: {
446
+ type: 'string', minLength: 1,
447
+ description: 'Case-insensitive regex for list/children filtering; required for terminal grep.',
448
+ },
422
449
  ...pageProperties,
423
450
  context: { type: 'integer', minimum: 0, maximum: 10 },
424
451
  },