Dax Raad 9 months ago
parent
commit
5f750b7368
5 changed files with 72 additions and 13 deletions
  1. 5 1
      js/src/app/index.ts
  2. 6 8
      js/src/index.ts
  3. 12 0
      js/src/session/session.ts
  4. 45 0
      js/src/share/share.ts
  5. 4 4
      js/src/storage/storage.ts

+ 5 - 1
js/src/app/index.ts

@@ -3,6 +3,7 @@ import { AppPath } from "./path";
 import { Log } from "../util/log";
 import { Context } from "../util/context";
 import { Config } from "./config";
+import { Share } from "../share/share";
 
 export namespace App {
   const log = Log.create({ service: "app" });
@@ -61,6 +62,9 @@ export namespace App {
     cb: T,
   ) {
     const app = await create(input);
-    return ctx.provide(app, () => cb(app));
+
+    return ctx.provide(app, async () => {
+      return cb(app);
+    });
   }
 }

+ 6 - 8
js/src/index.ts

@@ -6,11 +6,13 @@ import { Bus } from "./bus";
 import { Session } from "./session/session";
 import cac from "cac";
 import { Storage } from "./storage/storage";
+import { Share } from "./share/share";
 
 const cli = cac("opencode");
 
 cli.command("", "Start the opencode in interactive mode").action(async () => {
-  await App.provide({ directory: process.cwd() }, () => {
+  await App.provide({ directory: process.cwd() }, async () => {
+    await Share.init();
     Server.listen();
   });
 });
@@ -35,14 +37,10 @@ cli
   .action(async (message: string[]) => {
     await App.provide({ directory: process.cwd() }, async () => {
       console.log("Thinking...");
-      Bus.subscribe(Storage.Event.Write, (evt) => {
-        const splits = evt.properties.key.split("/");
-
-        if (splits[0] === "session" && splits[1] === "message") {
-          console.log("opencode:", evt.properties.body);
-        }
-      });
+      await Share.init();
       const session = await Session.create();
+      const shareID = await Session.share(session.id);
+      if (shareID) console.log("Share ID:", shareID);
       const result = await Session.chat(session.id, {
         type: "text",
         text: message.join(" "),

+ 12 - 0
js/src/session/session.ts

@@ -18,12 +18,14 @@ import * as tools from "../tool";
 
 import ANTHROPIC_PROMPT from "./prompt/anthropic.txt";
 import type { Tool } from "../tool/tool";
+import { Share } from "../share/share";
 
 export namespace Session {
   const log = Log.create({ service: "session" });
 
   export const Info = z.object({
     id: Identifier.schema("session"),
+    shareID: z.string().optional(),
     title: z.string(),
     tokens: z.object({
       input: z.number(),
@@ -77,6 +79,16 @@ export namespace Session {
     return read as Info;
   }
 
+  export async function share(id: string) {
+    const session = await get(id);
+    if (session.shareID) return session.shareID;
+    const shareID = await Share.create(id);
+    if (!shareID) return;
+    session.shareID = shareID;
+    await update(session);
+    return shareID;
+  }
+
   export async function update(session: Info) {
     state().sessions.set(session.id, session);
     await Storage.writeJSON("session/info/" + session.id, session);

+ 45 - 0
js/src/share/share.ts

@@ -0,0 +1,45 @@
+import { App } from "../app";
+import { Bus } from "../bus";
+import { Session } from "../session/session";
+import { Storage } from "../storage/storage";
+
+export namespace Share {
+  const state = App.state("share", async () => {
+    Bus.subscribe(Storage.Event.Write, async (payload) => {
+      const [root, ...splits] = payload.properties.key.split("/");
+      if (root !== "session") return;
+      const [type, sessionID] = splits;
+      const session = await Session.get(sessionID);
+      if (!session.shareID) return;
+      console.log({
+        sessionID: sessionID,
+        shareID: session.shareID,
+        key: payload.properties.key,
+        content: payload.properties.content,
+      });
+      await fetch(`${URL}/share_sync`, {
+        method: "POST",
+        body: JSON.stringify({
+          sessionID: sessionID,
+          shareID: session.shareID,
+          key: payload.properties.key,
+          content: payload.properties.content,
+        }),
+      }).then(console.log);
+    });
+  });
+
+  export async function init() {
+    await state();
+  }
+
+  const URL = "https://api.dev.opencode.ai";
+  export async function create(sessionID: string) {
+    return fetch(`${URL}/share_create`, {
+      method: "POST",
+      body: JSON.stringify({ sessionID: sessionID }),
+    })
+      .then((x) => x.json())
+      .then((x) => x.shareID);
+  }
+}

+ 4 - 4
js/src/storage/storage.ts

@@ -13,7 +13,7 @@ export namespace Storage {
   export const Event = {
     Write: Bus.event(
       "storage.write",
-      z.object({ key: z.string(), body: z.any() }),
+      z.object({ key: z.string(), content: z.any() }),
     ),
   };
 
@@ -50,9 +50,9 @@ export namespace Storage {
     return JSON.parse(data) as T;
   }
 
-  export async function writeJSON<T>(key: string, data: T) {
-    Bus.publish(Event.Write, { key, body: data });
-    const json = JSON.stringify(data);
+  export async function writeJSON<T>(key: string, content: T) {
+    const json = JSON.stringify(content);
     await write(key + ".json", json);
+    Bus.publish(Event.Write, { key, content });
   }
 }