fix: upgrade to Next.js 16.2.1 and resolve bundling issues

- Fixed client bundle contamination by moving child_process-dependent code
- Created standalone /api/robots/command route for SSH robot commands
- Created plugins router to replace robots.plugins for plugin management
- Added getStudyPlugins procedure to studies router
- Fixed trial.studyId references to trial.experiment.studyId
- Updated WizardInterface to use REST API for robot commands
This commit is contained in:
Sean O'Connor
2026-03-22 01:08:13 -04:00
parent 79bb298756
commit add3380307
16 changed files with 612 additions and 69 deletions

View File

@@ -841,6 +841,63 @@ export const studiesRouter = createTRPCRouter({
};
}),
getStudyPlugins: protectedProcedure
.input(
z.object({
studyId: z.string().uuid(),
}),
)
.query(async ({ ctx, input }) => {
const { studyId } = input;
const userId = ctx.session.user.id;
// Check if user has access to this study (any role)
const membership = await ctx.db.query.studyMembers.findFirst({
where: and(
eq(studyMembers.studyId, studyId),
eq(studyMembers.userId, userId),
),
});
if (!membership) {
throw new TRPCError({
code: "FORBIDDEN",
message: "You don't have access to this study",
});
}
const installedPlugins = await ctx.db
.select({
plugin: {
id: plugins.id,
robotId: plugins.robotId,
name: plugins.name,
version: plugins.version,
description: plugins.description,
author: plugins.author,
repositoryUrl: plugins.repositoryUrl,
trustLevel: plugins.trustLevel,
status: plugins.status,
actionDefinitions: plugins.actionDefinitions,
createdAt: plugins.createdAt,
updatedAt: plugins.updatedAt,
metadata: plugins.metadata,
},
installation: {
id: studyPlugins.id,
configuration: studyPlugins.configuration,
installedAt: studyPlugins.installedAt,
installedBy: studyPlugins.installedBy,
},
})
.from(studyPlugins)
.innerJoin(plugins, eq(studyPlugins.pluginId, plugins.id))
.where(eq(studyPlugins.studyId, studyId))
.orderBy(desc(studyPlugins.installedAt));
return installedPlugins;
}),
// Plugin configuration management
getPluginConfiguration: protectedProcedure
.input(