manager.ts 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. import path from 'node:path';
  2. import type { PluginInput } from '@opencode-ai/plugin';
  3. import type { PluginConfig } from '../config';
  4. import { DEFAULT_DASHBOARD_PORT } from './dashboard';
  5. import { createDashboardManager } from './dashboard-manager';
  6. import { createInterviewServer } from './server';
  7. import { createInterviewService } from './service';
  8. export function createInterviewManager(
  9. ctx: PluginInput,
  10. config: PluginConfig,
  11. ): {
  12. registerCommand: (config: Record<string, unknown>) => void;
  13. handleCommandExecuteBefore: (
  14. input: { command: string; sessionID: string; arguments: string },
  15. output: { parts: Array<{ type: string; text?: string }> },
  16. ) => Promise<void>;
  17. handleEvent: (input: {
  18. event: { type: string; properties?: Record<string, unknown> };
  19. }) => Promise<void>;
  20. } {
  21. const interviewConfig = config.interview;
  22. const effectivePort = interviewConfig?.port ?? 0;
  23. const dashboardEnabled =
  24. interviewConfig?.dashboard === true || effectivePort > 0;
  25. const outputFolder = interviewConfig?.outputFolder ?? 'interview';
  26. // ─── Per-session mode (upstream behavior) ───────────────────────
  27. if (!dashboardEnabled) {
  28. const service = createInterviewService(ctx, interviewConfig);
  29. const resolvedOutputPath = path.join(ctx.directory, outputFolder);
  30. const server = createInterviewServer({
  31. getState: async (interviewId) => service.getInterviewState(interviewId),
  32. listInterviewFiles: async () => service.listInterviewFiles(),
  33. listInterviews: () => service.listInterviews(),
  34. submitAnswers: async (interviewId, answers) =>
  35. service.submitAnswers(interviewId, answers),
  36. submitBlockComment: async (interviewId, section, comment) =>
  37. service.submitBlockComment(interviewId, section, comment),
  38. submitChat: async (interviewId, message) =>
  39. service.submitChat(interviewId, message),
  40. handleNudgeAction: async (interviewId, action) =>
  41. service.handleNudgeAction(interviewId, action),
  42. outputFolder: resolvedOutputPath,
  43. port: 0, // random port
  44. });
  45. service.setBaseUrlResolver(() => server.ensureStarted());
  46. return {
  47. registerCommand: (c) => service.registerCommand(c),
  48. handleCommandExecuteBefore: async (input, output) =>
  49. service.handleCommandExecuteBefore(input, output),
  50. handleEvent: async (input) => service.handleEvent(input),
  51. };
  52. }
  53. // ─── Dashboard mode ─────────────────────────────────────────────
  54. const dashboardPort =
  55. effectivePort > 0 ? effectivePort : DEFAULT_DASHBOARD_PORT;
  56. return createDashboardManager(ctx, config, dashboardPort, outputFolder);
  57. }