@gricha/perry 0.1.6 → 0.1.7

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.
@@ -22,6 +22,7 @@ const WorkspaceInfoSchema = z.object({
22
22
  created: z.string(),
23
23
  repo: z.string().optional(),
24
24
  ports: WorkspacePortsSchema,
25
+ lastUsed: z.string().optional(),
25
26
  });
26
27
  const CredentialsSchema = z.object({
27
28
  env: z.record(z.string(), z.string()),
@@ -172,6 +173,16 @@ export function createRouter(ctx) {
172
173
  results,
173
174
  };
174
175
  });
176
+ const touchWorkspace = os
177
+ .input(z.object({ name: z.string() }))
178
+ .output(WorkspaceInfoSchema)
179
+ .handler(async ({ input }) => {
180
+ const workspace = await ctx.workspaces.touch(input.name);
181
+ if (!workspace) {
182
+ throw new ORPCError('NOT_FOUND', { message: 'Workspace not found' });
183
+ }
184
+ return workspace;
185
+ });
175
186
  const getInfo = os.handler(async () => {
176
187
  let dockerVersion = 'unknown';
177
188
  try {
@@ -589,42 +600,23 @@ export function createRouter(ctx) {
589
600
  await deleteSessionName(ctx.stateDir, input.workspaceName, input.sessionId);
590
601
  return { success: true };
591
602
  });
592
- const listAllSessions = os
603
+ const getRecentSessions = os
593
604
  .input(z.object({
594
- agentType: z.enum(['claude-code', 'opencode', 'codex']).optional(),
595
- limit: z.number().optional().default(100),
596
- offset: z.number().optional().default(0),
605
+ limit: z.number().optional().default(10),
597
606
  }))
598
607
  .handler(async ({ input }) => {
599
- const allWorkspaces = await ctx.workspaces.list();
600
- const runningWorkspaces = allWorkspaces.filter((w) => w.status === 'running');
601
- const allSessions = [];
602
- for (const workspace of runningWorkspaces) {
603
- try {
604
- const result = await listSessionsCore({
605
- workspaceName: workspace.name,
606
- agentType: input.agentType,
607
- limit: 1000,
608
- offset: 0,
609
- });
610
- for (const session of result.sessions) {
611
- allSessions.push({
612
- ...session,
613
- workspaceName: workspace.name,
614
- });
615
- }
616
- }
617
- catch {
618
- continue;
619
- }
620
- }
621
- allSessions.sort((a, b) => new Date(b.lastActivity).getTime() - new Date(a.lastActivity).getTime());
622
- const paginatedSessions = allSessions.slice(input.offset, input.offset + input.limit);
623
- return {
624
- sessions: paginatedSessions,
625
- total: allSessions.length,
626
- hasMore: input.offset + input.limit < allSessions.length,
627
- };
608
+ const recent = await ctx.sessionsCache.getRecent(input.limit);
609
+ return { sessions: recent };
610
+ });
611
+ const recordSessionAccess = os
612
+ .input(z.object({
613
+ workspaceName: z.string(),
614
+ sessionId: z.string(),
615
+ agentType: z.enum(['claude-code', 'opencode', 'codex']),
616
+ }))
617
+ .handler(async ({ input }) => {
618
+ await ctx.sessionsCache.recordAccess(input.workspaceName, input.sessionId, input.agentType);
619
+ return { success: true };
628
620
  });
629
621
  const getHostInfo = os.handler(async () => {
630
622
  const config = ctx.config.get();
@@ -660,13 +652,15 @@ export function createRouter(ctx) {
660
652
  logs: getLogs,
661
653
  sync: syncWorkspace,
662
654
  syncAll: syncAllWorkspaces,
655
+ touch: touchWorkspace,
663
656
  },
664
657
  sessions: {
665
658
  list: listSessions,
666
- listAll: listAllSessions,
667
659
  get: getSession,
668
660
  rename: renameSession,
669
661
  clearName: clearSessionName,
662
+ getRecent: getRecentSessions,
663
+ recordAccess: recordSessionAccess,
670
664
  },
671
665
  host: {
672
666
  info: getHostInfo,
package/dist/agent/run.js CHANGED
@@ -10,6 +10,7 @@ import { ChatWebSocketServer } from '../chat/websocket';
10
10
  import { OpencodeWebSocketServer } from '../chat/opencode-websocket';
11
11
  import { createRouter } from './router';
12
12
  import { serveStatic } from './static';
13
+ import { SessionsCacheManager } from '../sessions/cache';
13
14
  import pkg from '../../package.json';
14
15
  const startTime = Date.now();
15
16
  function sendJson(res, status, data) {
@@ -19,6 +20,7 @@ function sendJson(res, status, data) {
19
20
  function createAgentServer(configDir, config) {
20
21
  let currentConfig = config;
21
22
  const workspaces = new WorkspaceManager(configDir, currentConfig);
23
+ const sessionsCache = new SessionsCacheManager(configDir);
22
24
  const isWorkspaceRunning = async (name) => {
23
25
  if (name === HOST_WORKSPACE_NAME) {
24
26
  return currentConfig.allowHostAccess === true;
@@ -52,6 +54,7 @@ function createAgentServer(configDir, config) {
52
54
  stateDir: configDir,
53
55
  startTime,
54
56
  terminalServer,
57
+ sessionsCache,
55
58
  });
56
59
  const rpcHandler = new RPCHandler(router);
57
60
  const server = createServer(async (req, res) => {