feat: expose skills and $ autocomplete (#92)

This commit is contained in:
freespace8
2026-01-21 16:28:15 +08:00
committed by GitHub
parent 8b368024e3
commit 2cb8727874
17 changed files with 471 additions and 5 deletions
+12
View File
@@ -177,6 +177,18 @@ export class RpcGateway {
}
}
async listSkills(sessionId: string): Promise<{
success: boolean
skills?: Array<{ name: string; description?: string }>
error?: string
}> {
return await this.sessionRpc(sessionId, 'listSkills', {}) as {
success: boolean
skills?: Array<{ name: string; description?: string }>
error?: string
}
}
private async sessionRpc(sessionId: string, method: string, params: unknown): Promise<unknown> {
return await this.rpcCall(`${sessionId}:${method}`, params)
}
+8
View File
@@ -316,4 +316,12 @@ export class SyncEngine {
}> {
return await this.rpcGateway.listSlashCommands(sessionId, agent)
}
async listSkills(sessionId: string): Promise<{
success: boolean
skills?: Array<{ name: string; description?: string }>
error?: string
}> {
return await this.rpcGateway.listSkills(sessionId)
}
}
+23
View File
@@ -347,5 +347,28 @@ export function createSessionsRoutes(getSyncEngine: () => SyncEngine | null): Ho
}
})
app.get('/sessions/:id/skills', async (c) => {
const engine = requireSyncEngine(c, getSyncEngine)
if (engine instanceof Response) {
return engine
}
// Session must exist but doesn't need to be active
const sessionResult = requireSessionFromParam(c, engine)
if (sessionResult instanceof Response) {
return sessionResult
}
try {
const result = await engine.listSkills(sessionResult.sessionId)
return c.json(result)
} catch (error) {
return c.json({
success: false,
error: error instanceof Error ? error.message : 'Failed to list skills'
})
}
})
return app
}