build.ts 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. import { NodeFileSystem } from "@effect/platform-node"
  2. import { compile, emitEffectImported, emitEffectShape, emitPromise, write } from "@opencode-ai/httpapi-codegen"
  3. import { ClientApi, effectOmitEndpoints, groupNames, promiseOmitEndpoints } from "@opencode-ai/protocol/client"
  4. import { Agent } from "@opencode-ai/schema/agent"
  5. import { Command } from "@opencode-ai/schema/command"
  6. import { Config } from "@opencode-ai/schema/config"
  7. import { Credential } from "@opencode-ai/schema/credential"
  8. import { Event } from "@opencode-ai/schema/event"
  9. import { EventLog } from "@opencode-ai/schema/event-log"
  10. import { FileDiff } from "@opencode-ai/schema/file-diff"
  11. import { FileSystem } from "@opencode-ai/schema/filesystem"
  12. import { Form } from "@opencode-ai/schema/form"
  13. import { InstructionEntry } from "@opencode-ai/schema/instruction-entry"
  14. import { Integration } from "@opencode-ai/schema/integration"
  15. import { Location } from "@opencode-ai/schema/location"
  16. import { Mcp } from "@opencode-ai/schema/mcp"
  17. import { Model } from "@opencode-ai/schema/model"
  18. import { Permission } from "@opencode-ai/schema/permission"
  19. import { PermissionSaved } from "@opencode-ai/schema/permission-saved"
  20. import { Plugin } from "@opencode-ai/schema/plugin"
  21. import { Project } from "@opencode-ai/schema/project"
  22. import { ProjectCopy } from "@opencode-ai/schema/project-copy"
  23. import { AgentAttachment, FileAttachment, Prompt, PromptMention } from "@opencode-ai/schema/prompt"
  24. import { PromptInput } from "@opencode-ai/schema/prompt-input"
  25. import { Provider } from "@opencode-ai/schema/provider"
  26. import { Pty } from "@opencode-ai/schema/pty"
  27. import { PtyTicket } from "@opencode-ai/schema/pty-ticket"
  28. import { Question } from "@opencode-ai/schema/question"
  29. import { Reference } from "@opencode-ai/schema/reference"
  30. import { AbsolutePath, PositiveInt, RelativePath } from "@opencode-ai/schema/schema"
  31. import { Session } from "@opencode-ai/schema/session"
  32. import { SessionMessage } from "@opencode-ai/schema/session-message"
  33. import { SessionPending } from "@opencode-ai/schema/session-pending"
  34. import { Shell } from "@opencode-ai/schema/shell"
  35. import { Skill } from "@opencode-ai/schema/skill"
  36. import { Vcs } from "@opencode-ai/schema/vcs"
  37. import { WebSearch } from "@opencode-ai/schema/websearch"
  38. import { Workspace } from "@opencode-ai/schema/workspace"
  39. import { Effect, Schema } from "effect"
  40. import { fileURLToPath } from "url"
  41. const promiseContract = compile(ClientApi, { groupNames, omitEndpoints: promiseOmitEndpoints })
  42. const effectContract = compile(ClientApi, { groupNames, omitEndpoints: effectOmitEndpoints })
  43. const effectTypeReferences = [
  44. ...namespaceTypes("Agent", "@opencode-ai/schema/agent", Agent),
  45. ...namespaceTypes("Command", "@opencode-ai/schema/command", Command),
  46. ...namespaceTypes("Config", "@opencode-ai/schema/config", Config),
  47. ...namespaceTypes("Credential", "@opencode-ai/schema/credential", Credential),
  48. ...namespaceTypes("Event", "@opencode-ai/schema/event", Event),
  49. ...namespaceTypes("EventLog", "@opencode-ai/schema/event-log", EventLog),
  50. ...namespaceTypes("FileDiff", "@opencode-ai/schema/file-diff", FileDiff),
  51. ...namespaceTypes("FileSystem", "@opencode-ai/schema/filesystem", FileSystem),
  52. ...namespaceTypes("Form", "@opencode-ai/schema/form", Form),
  53. ...namespaceTypes("InstructionEntry", "@opencode-ai/schema/instruction-entry", InstructionEntry),
  54. ...namespaceTypes("Integration", "@opencode-ai/schema/integration", Integration),
  55. ...namespaceTypes("Location", "@opencode-ai/schema/location", Location),
  56. ...namespaceTypes("Mcp", "@opencode-ai/schema/mcp", Mcp),
  57. ...namespaceTypes("Model", "@opencode-ai/schema/model", Model),
  58. ...namespaceTypes("Permission", "@opencode-ai/schema/permission", Permission),
  59. ...namespaceTypes("PermissionSaved", "@opencode-ai/schema/permission-saved", PermissionSaved),
  60. ...namespaceTypes("Plugin", "@opencode-ai/schema/plugin", Plugin),
  61. ...namespaceTypes("Project", "@opencode-ai/schema/project", Project),
  62. ...namespaceTypes("ProjectCopy", "@opencode-ai/schema/project-copy", ProjectCopy),
  63. ...namespaceTypes("PromptInput", "@opencode-ai/schema/prompt-input", PromptInput),
  64. ...namespaceTypes("Provider", "@opencode-ai/schema/provider", Provider),
  65. ...namespaceTypes("Pty", "@opencode-ai/schema/pty", Pty),
  66. ...namespaceTypes("PtyTicket", "@opencode-ai/schema/pty-ticket", PtyTicket),
  67. ...namespaceTypes("Question", "@opencode-ai/schema/question", Question),
  68. ...namespaceTypes("Reference", "@opencode-ai/schema/reference", Reference),
  69. ...namespaceTypes("Session", "@opencode-ai/schema/session", Session),
  70. ...namespaceTypes("SessionMessage", "@opencode-ai/schema/session-message", SessionMessage),
  71. ...namespaceTypes("SessionPending", "@opencode-ai/schema/session-pending", SessionPending),
  72. ...namespaceTypes("Shell", "@opencode-ai/schema/shell", Shell),
  73. ...namespaceTypes("Skill", "@opencode-ai/schema/skill", Skill),
  74. ...namespaceTypes("Vcs", "@opencode-ai/schema/vcs", Vcs),
  75. ...namespaceTypes("WebSearch", "@opencode-ai/schema/websearch", WebSearch),
  76. ...namespaceTypes("Workspace", "@opencode-ai/schema/workspace", Workspace),
  77. typeReference("Prompt", "@opencode-ai/schema/prompt", Prompt),
  78. typeReference("PromptMention", "@opencode-ai/schema/prompt", PromptMention),
  79. typeReference("FileAttachment", "@opencode-ai/schema/prompt", FileAttachment),
  80. typeReference("AgentAttachment", "@opencode-ai/schema/prompt", AgentAttachment),
  81. typeReference("AbsolutePath", "@opencode-ai/schema/schema", AbsolutePath),
  82. typeReference("PositiveInt", "@opencode-ai/schema/schema", PositiveInt),
  83. typeReference("RelativePath", "@opencode-ai/schema/schema", RelativePath),
  84. ]
  85. await Effect.runPromise(
  86. Effect.all(
  87. [
  88. write(
  89. emitPromise(promiseContract, {
  90. mutableOutputs: true,
  91. }),
  92. fileURLToPath(new URL("../src/promise/generated", import.meta.url)),
  93. ),
  94. write(
  95. emitEffectImported(effectContract, {
  96. module: "../../contract",
  97. api: "ClientApi",
  98. shapeModule: "../api/api.js",
  99. }),
  100. fileURLToPath(new URL("../src/effect/generated", import.meta.url)),
  101. ),
  102. write(
  103. emitEffectShape(effectContract, {
  104. typeReferences: effectTypeReferences,
  105. outputTypes: {
  106. "event.subscribe": {
  107. name: "OpenCodeEvent",
  108. import: 'import type { OpenCodeEvent } from "@opencode-ai/protocol/groups/event"',
  109. },
  110. },
  111. }),
  112. fileURLToPath(new URL("../src/effect/api", import.meta.url)),
  113. ),
  114. ],
  115. { concurrency: 3, discard: true },
  116. ).pipe(Effect.provide(NodeFileSystem.layer)),
  117. )
  118. function namespaceTypes(namespace: string, module: string, values: object) {
  119. return Object.entries(values).flatMap(([name, schema]) =>
  120. Schema.isSchema(schema) ? [typeReference(`${namespace}.${name}`, module, schema)] : [],
  121. )
  122. }
  123. function typeReference(name: string, module: string, schema: Schema.Top) {
  124. return {
  125. schema,
  126. name,
  127. import: `import type { ${name.split(".")[0]} } from ${JSON.stringify(module)}`,
  128. }
  129. }