|
|
@@ -1,14 +1,13 @@
|
|
|
import type { Argv } from "yargs"
|
|
|
-import { App } from "../../app/app"
|
|
|
import { Bus } from "../../bus"
|
|
|
import { Provider } from "../../provider/provider"
|
|
|
import { Session } from "../../session"
|
|
|
-import { Share } from "../../share/share"
|
|
|
import { Message } from "../../session/message"
|
|
|
import { UI } from "../ui"
|
|
|
import { cmd } from "./cmd"
|
|
|
import { Flag } from "../../flag/flag"
|
|
|
import { Config } from "../../config/config"
|
|
|
+import { bootstrap } from "../bootstrap"
|
|
|
|
|
|
const TOOL: Record<string, [string, string]> = {
|
|
|
todowrite: ["Todo", UI.Style.TEXT_WARNING_BOLD],
|
|
|
@@ -56,118 +55,109 @@ export const RunCommand = cmd({
|
|
|
},
|
|
|
handler: async (args) => {
|
|
|
const message = args.message.join(" ")
|
|
|
- await App.provide(
|
|
|
- {
|
|
|
- cwd: process.cwd(),
|
|
|
- },
|
|
|
- async () => {
|
|
|
- await Share.init()
|
|
|
- const session = await (async () => {
|
|
|
- if (args.continue) {
|
|
|
- const first = await Session.list().next()
|
|
|
- if (first.done) return
|
|
|
- return first.value
|
|
|
- }
|
|
|
-
|
|
|
- if (args.session) return Session.get(args.session)
|
|
|
+ await bootstrap({ cwd: process.cwd() }, async () => {
|
|
|
+ const session = await (async () => {
|
|
|
+ if (args.continue) {
|
|
|
+ const first = await Session.list().next()
|
|
|
+ if (first.done) return
|
|
|
+ return first.value
|
|
|
+ }
|
|
|
|
|
|
- return Session.create()
|
|
|
- })()
|
|
|
+ if (args.session) return Session.get(args.session)
|
|
|
|
|
|
- if (!session) {
|
|
|
- UI.error("Session not found")
|
|
|
- return
|
|
|
- }
|
|
|
+ return Session.create()
|
|
|
+ })()
|
|
|
|
|
|
- const isPiped = !process.stdout.isTTY
|
|
|
+ if (!session) {
|
|
|
+ UI.error("Session not found")
|
|
|
+ return
|
|
|
+ }
|
|
|
|
|
|
- UI.empty()
|
|
|
- UI.println(UI.logo())
|
|
|
- UI.empty()
|
|
|
- UI.println(UI.Style.TEXT_NORMAL_BOLD + "> ", message)
|
|
|
- UI.empty()
|
|
|
+ const isPiped = !process.stdout.isTTY
|
|
|
|
|
|
- const cfg = await Config.get()
|
|
|
- if (cfg.autoshare || Flag.OPENCODE_AUTO_SHARE || args.share) {
|
|
|
- await Session.share(session.id)
|
|
|
- UI.println(
|
|
|
- UI.Style.TEXT_INFO_BOLD +
|
|
|
- "~ https://opencode.ai/s/" +
|
|
|
- session.id.slice(-8),
|
|
|
- )
|
|
|
- }
|
|
|
- UI.empty()
|
|
|
+ UI.empty()
|
|
|
+ UI.println(UI.logo())
|
|
|
+ UI.empty()
|
|
|
+ UI.println(UI.Style.TEXT_NORMAL_BOLD + "> ", message)
|
|
|
+ UI.empty()
|
|
|
|
|
|
- const { providerID, modelID } = args.model
|
|
|
- ? Provider.parseModel(args.model)
|
|
|
- : await Provider.defaultModel()
|
|
|
+ const cfg = await Config.get()
|
|
|
+ if (cfg.autoshare || Flag.OPENCODE_AUTO_SHARE || args.share) {
|
|
|
+ await Session.share(session.id)
|
|
|
UI.println(
|
|
|
- UI.Style.TEXT_NORMAL_BOLD + "@ ",
|
|
|
- UI.Style.TEXT_NORMAL + `${providerID}/${modelID}`,
|
|
|
+ UI.Style.TEXT_INFO_BOLD +
|
|
|
+ "~ https://opencode.ai/s/" +
|
|
|
+ session.id.slice(-8),
|
|
|
)
|
|
|
- UI.empty()
|
|
|
+ }
|
|
|
+ UI.empty()
|
|
|
|
|
|
- function printEvent(color: string, type: string, title: string) {
|
|
|
- UI.println(
|
|
|
- color + `|`,
|
|
|
- UI.Style.TEXT_NORMAL +
|
|
|
- UI.Style.TEXT_DIM +
|
|
|
- ` ${type.padEnd(7, " ")}`,
|
|
|
- "",
|
|
|
- UI.Style.TEXT_NORMAL + title,
|
|
|
- )
|
|
|
- }
|
|
|
+ const { providerID, modelID } = args.model
|
|
|
+ ? Provider.parseModel(args.model)
|
|
|
+ : await Provider.defaultModel()
|
|
|
+ UI.println(
|
|
|
+ UI.Style.TEXT_NORMAL_BOLD + "@ ",
|
|
|
+ UI.Style.TEXT_NORMAL + `${providerID}/${modelID}`,
|
|
|
+ )
|
|
|
+ UI.empty()
|
|
|
+
|
|
|
+ function printEvent(color: string, type: string, title: string) {
|
|
|
+ UI.println(
|
|
|
+ color + `|`,
|
|
|
+ UI.Style.TEXT_NORMAL + UI.Style.TEXT_DIM + ` ${type.padEnd(7, " ")}`,
|
|
|
+ "",
|
|
|
+ UI.Style.TEXT_NORMAL + title,
|
|
|
+ )
|
|
|
+ }
|
|
|
|
|
|
- Bus.subscribe(Message.Event.PartUpdated, async (evt) => {
|
|
|
- if (evt.properties.sessionID !== session.id) return
|
|
|
- const part = evt.properties.part
|
|
|
- const message = await Session.getMessage(
|
|
|
- evt.properties.sessionID,
|
|
|
- evt.properties.messageID,
|
|
|
- )
|
|
|
+ Bus.subscribe(Message.Event.PartUpdated, async (evt) => {
|
|
|
+ if (evt.properties.sessionID !== session.id) return
|
|
|
+ const part = evt.properties.part
|
|
|
+ const message = await Session.getMessage(
|
|
|
+ evt.properties.sessionID,
|
|
|
+ evt.properties.messageID,
|
|
|
+ )
|
|
|
|
|
|
- if (
|
|
|
- part.type === "tool-invocation" &&
|
|
|
- part.toolInvocation.state === "result"
|
|
|
- ) {
|
|
|
- const metadata =
|
|
|
- message.metadata.tool[part.toolInvocation.toolCallId]
|
|
|
- const [tool, color] = TOOL[part.toolInvocation.toolName] ?? [
|
|
|
- part.toolInvocation.toolName,
|
|
|
- UI.Style.TEXT_INFO_BOLD,
|
|
|
- ]
|
|
|
- printEvent(color, tool, metadata?.title || "Unknown")
|
|
|
- }
|
|
|
+ if (
|
|
|
+ part.type === "tool-invocation" &&
|
|
|
+ part.toolInvocation.state === "result"
|
|
|
+ ) {
|
|
|
+ const metadata = message.metadata.tool[part.toolInvocation.toolCallId]
|
|
|
+ const [tool, color] = TOOL[part.toolInvocation.toolName] ?? [
|
|
|
+ part.toolInvocation.toolName,
|
|
|
+ UI.Style.TEXT_INFO_BOLD,
|
|
|
+ ]
|
|
|
+ printEvent(color, tool, metadata?.title || "Unknown")
|
|
|
+ }
|
|
|
|
|
|
- if (part.type === "text") {
|
|
|
- if (part.text.includes("\n")) {
|
|
|
- UI.empty()
|
|
|
- UI.println(part.text)
|
|
|
- UI.empty()
|
|
|
- return
|
|
|
- }
|
|
|
- printEvent(UI.Style.TEXT_NORMAL_BOLD, "Text", part.text)
|
|
|
+ if (part.type === "text") {
|
|
|
+ if (part.text.includes("\n")) {
|
|
|
+ UI.empty()
|
|
|
+ UI.println(part.text)
|
|
|
+ UI.empty()
|
|
|
+ return
|
|
|
}
|
|
|
- })
|
|
|
+ printEvent(UI.Style.TEXT_NORMAL_BOLD, "Text", part.text)
|
|
|
+ }
|
|
|
+ })
|
|
|
|
|
|
- const result = await Session.chat({
|
|
|
- sessionID: session.id,
|
|
|
- providerID,
|
|
|
- modelID,
|
|
|
- parts: [
|
|
|
- {
|
|
|
- type: "text",
|
|
|
- text: message,
|
|
|
- },
|
|
|
- ],
|
|
|
- })
|
|
|
+ const result = await Session.chat({
|
|
|
+ sessionID: session.id,
|
|
|
+ providerID,
|
|
|
+ modelID,
|
|
|
+ parts: [
|
|
|
+ {
|
|
|
+ type: "text",
|
|
|
+ text: message,
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ })
|
|
|
|
|
|
- if (isPiped) {
|
|
|
- const match = result.parts.findLast((x) => x.type === "text")
|
|
|
- if (match) process.stdout.write(match.text)
|
|
|
- }
|
|
|
- UI.empty()
|
|
|
- },
|
|
|
- )
|
|
|
+ if (isPiped) {
|
|
|
+ const match = result.parts.findLast((x) => x.type === "text")
|
|
|
+ if (match) process.stdout.write(match.text)
|
|
|
+ }
|
|
|
+ UI.empty()
|
|
|
+ })
|
|
|
},
|
|
|
})
|