index.ts 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. import "zod-openapi/extend"
  2. import yargs from "yargs"
  3. import { hideBin } from "yargs/helpers"
  4. import { RunCommand } from "./cli/cmd/run"
  5. import { GenerateCommand } from "./cli/cmd/generate"
  6. import { Log } from "./util/log"
  7. import { AuthCommand } from "./cli/cmd/auth"
  8. import { UpgradeCommand } from "./cli/cmd/upgrade"
  9. import { ModelsCommand } from "./cli/cmd/models"
  10. import { UI } from "./cli/ui"
  11. import { Installation } from "./installation"
  12. import { NamedError } from "./util/error"
  13. import { FormatError } from "./cli/error"
  14. import { ServeCommand } from "./cli/cmd/serve"
  15. import { TuiCommand } from "./cli/cmd/tui"
  16. import { DebugCommand } from "./cli/cmd/debug"
  17. const cancel = new AbortController()
  18. process.on("unhandledRejection", (e) => {
  19. Log.Default.error("rejection", {
  20. e: e instanceof Error ? e.message : e,
  21. })
  22. })
  23. process.on("uncaughtException", (e) => {
  24. Log.Default.error("exception", {
  25. e: e instanceof Error ? e.message : e,
  26. })
  27. })
  28. const cli = yargs(hideBin(process.argv))
  29. .scriptName("opencode")
  30. .help("help", "show help")
  31. .version("version", "show version number", Installation.VERSION)
  32. .alias("version", "v")
  33. .option("print-logs", {
  34. describe: "print logs to stderr",
  35. type: "boolean",
  36. })
  37. .middleware(async () => {
  38. await Log.init({ print: process.argv.includes("--print-logs") })
  39. Log.Default.info("opencode", {
  40. version: Installation.VERSION,
  41. args: process.argv.slice(2),
  42. })
  43. })
  44. .usage("\n" + UI.logo())
  45. .command(TuiCommand)
  46. .command(RunCommand)
  47. .command(GenerateCommand)
  48. .command(DebugCommand)
  49. .command(AuthCommand)
  50. .command(UpgradeCommand)
  51. .command(ServeCommand)
  52. .command(ModelsCommand)
  53. .fail((msg) => {
  54. if (
  55. msg.startsWith("Unknown argument") ||
  56. msg.startsWith("Not enough non-option arguments")
  57. ) {
  58. cli.showHelp("log")
  59. }
  60. })
  61. .strict()
  62. try {
  63. await cli.parse()
  64. } catch (e) {
  65. let data: Record<string, any> = {}
  66. if (e instanceof NamedError) {
  67. const obj = e.toObject()
  68. Object.assign(data, {
  69. ...obj.data,
  70. })
  71. }
  72. if (e instanceof Error) {
  73. Object.assign(data, {
  74. name: e.name,
  75. message: e.message,
  76. cause: e.cause?.toString(),
  77. })
  78. }
  79. if (e instanceof ResolveMessage) {
  80. Object.assign(data, {
  81. name: e.name,
  82. message: e.message,
  83. code: e.code,
  84. specifier: e.specifier,
  85. referrer: e.referrer,
  86. position: e.position,
  87. importKind: e.importKind,
  88. })
  89. }
  90. Log.Default.error("fatal", data)
  91. const formatted = FormatError(e)
  92. if (formatted) UI.error(formatted)
  93. if (formatted === undefined)
  94. UI.error(
  95. "Unexpected error, check log file at " + Log.file() + " for more details",
  96. )
  97. process.exitCode = 1
  98. }
  99. cancel.abort()