command.ts 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. export * as CommandV2 from "./command"
  2. import { Context, Effect, Layer, Types } from "effect"
  3. import { Command } from "@opencode-ai/schema/command"
  4. import { State } from "./state"
  5. export const Info = Command.Info
  6. export type Info = Command.Info
  7. export type Data = {
  8. commands: Map<string, Types.DeepMutable<Info>>
  9. }
  10. export type Draft = {
  11. list: () => readonly Info[]
  12. get: (name: string) => Info | undefined
  13. update: (name: string, update: (command: Types.DeepMutable<Info>) => void) => void
  14. remove: (name: string) => void
  15. }
  16. export interface Interface extends State.Transformable<Draft> {
  17. readonly get: (name: string) => Effect.Effect<Info | undefined>
  18. readonly list: () => Effect.Effect<Info[]>
  19. }
  20. export class Service extends Context.Service<Service, Interface>()("@opencode/v2/Command") {}
  21. export const layer = Layer.effect(
  22. Service,
  23. Effect.sync(() => {
  24. const state = State.create<Data, Draft>({
  25. initial: () => ({ commands: new Map() }),
  26. draft: (draft) => ({
  27. list: () => Array.from(draft.commands.values()) as Info[],
  28. get: (name) => draft.commands.get(name),
  29. update: (name, update) => {
  30. const current = draft.commands.get(name) ?? ({ name, template: "" } as Types.DeepMutable<Info>)
  31. if (!draft.commands.has(name)) draft.commands.set(name, current)
  32. update(current)
  33. current.name = name
  34. },
  35. remove: (name) => {
  36. draft.commands.delete(name)
  37. },
  38. }),
  39. })
  40. return Service.of({
  41. reload: state.reload,
  42. transform: state.transform,
  43. get: Effect.fn("CommandV2.get")(function* (name) {
  44. return state.get().commands.get(name)
  45. }),
  46. list: Effect.fn("CommandV2.list")(function* () {
  47. return Array.from(state.get().commands.values())
  48. }),
  49. })
  50. }),
  51. )
  52. export const locationLayer = layer