index.test.ts 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. import { afterEach, beforeEach, describe, expect, test } from 'bun:test';
  2. import plugin from './index';
  3. describe('plugin env disable', () => {
  4. let originalEnv: typeof process.env;
  5. beforeEach(() => {
  6. originalEnv = { ...process.env };
  7. });
  8. afterEach(() => {
  9. process.env = originalEnv;
  10. });
  11. test('returns empty hooks without reading plugin context', async () => {
  12. process.env.OH_MY_OPENCODE_SLIM_DISABLE = '1';
  13. const ctx = new Proxy(
  14. {},
  15. {
  16. get(_target, property) {
  17. throw new Error(`disabled plugin read ctx.${String(property)}`);
  18. },
  19. },
  20. );
  21. const hooks = await plugin(ctx as Parameters<typeof plugin>[0]);
  22. expect(hooks).toEqual({});
  23. expect(hooks.config).toBeUndefined();
  24. expect(hooks.event).toBeUndefined();
  25. expect(hooks.tool).toBeUndefined();
  26. });
  27. });
  28. describe('plugin tool registration', () => {
  29. let originalEnv: typeof process.env;
  30. beforeEach(() => {
  31. originalEnv = { ...process.env };
  32. delete process.env.OH_MY_OPENCODE_SLIM_DISABLE;
  33. process.env.OPENCODE_CONFIG_DIR =
  34. '/private/tmp/oh-my-opencode-slim-hitl-empty-config';
  35. process.env.XDG_CONFIG_HOME =
  36. '/private/tmp/oh-my-opencode-slim-hitl-empty-xdg';
  37. process.env.XDG_DATA_HOME =
  38. '/private/tmp/oh-my-opencode-slim-hitl-empty-data';
  39. process.env.XDG_CACHE_HOME =
  40. '/private/tmp/oh-my-opencode-slim-hitl-empty-cache';
  41. process.env.OPENCODE_LOG_DIR =
  42. '/private/tmp/oh-my-opencode-slim-hitl-empty-logs';
  43. });
  44. afterEach(() => {
  45. process.env = originalEnv;
  46. });
  47. test('registers wait_for_user and recovers a stale orchestrator session mapping', async () => {
  48. const noop = async () => ({});
  49. const session = new Proxy({}, { get: () => noop }) as Record<
  50. string,
  51. unknown
  52. >;
  53. const client = new Proxy(
  54. { app: { log: noop }, session },
  55. {
  56. get(target, property) {
  57. if (property in target) {
  58. return target[property as keyof typeof target];
  59. }
  60. return new Proxy({}, { get: () => noop });
  61. },
  62. },
  63. );
  64. const hooks = await plugin({
  65. client,
  66. directory: '/private/tmp/oh-my-opencode-slim-hitl-project',
  67. worktree: '/private/tmp/oh-my-opencode-slim-hitl-project',
  68. serverUrl: new URL('http://127.0.0.1:4096'),
  69. } as never);
  70. expect(hooks.tool?.wait_for_user).toBeDefined();
  71. await expect(
  72. hooks.tool?.wait_for_user?.execute(
  73. { reason: 'Complete the external approval.' },
  74. { sessionID: 'parent-after-reload', agent: 'orchestrator' } as never,
  75. ),
  76. ).resolves.toContain('state: waiting_for_user');
  77. });
  78. });