From 2a3242771aec0c3593080dca408c3c1176eb5399 Mon Sep 17 00:00:00 2001 From: Kit Langton Date: Wed, 5 Aug 2026 22:02:29 -0400 Subject: [PATCH] refactor(core): remove obsolete migration relics --- bun.lock | 1 + packages/core/src/id/id.ts | 49 ------------------- packages/core/src/job.ts | 4 +- packages/core/src/util/identifier.ts | 1 - packages/core/test/shared-schema.test.ts | 2 +- packages/enterprise/package.json | 1 + packages/enterprise/test/core/share.test.ts | 28 +++++------ packages/schema/src/job-id.ts | 9 ++++ packages/schema/test/contract-hygiene.test.ts | 2 + 9 files changed, 30 insertions(+), 67 deletions(-) delete mode 100644 packages/core/src/id/id.ts delete mode 100644 packages/core/src/util/identifier.ts create mode 100644 packages/schema/src/job-id.ts diff --git a/bun.lock b/bun.lock index b913a57cd3..a09535b03d 100644 --- a/bun.lock +++ b/bun.lock @@ -513,6 +513,7 @@ }, "devDependencies": { "@cloudflare/workers-types": "catalog:", + "@opencode-ai/schema": "workspace:*", "@tailwindcss/vite": "catalog:", "@types/bun": "catalog:", "@types/luxon": "catalog:", diff --git a/packages/core/src/id/id.ts b/packages/core/src/id/id.ts deleted file mode 100644 index b4d6e496ea..0000000000 --- a/packages/core/src/id/id.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { create } from "@opencode-ai/schema/identifier" - -const prefixes = { - job: "job", - event: "evt", - session: "ses", - message: "msg", - permission: "per", - question: "que", - part: "prt", - pty: "pty", - tool: "tool", - workspace: "wrk", -} as const - -export function ascending(prefix: keyof typeof prefixes, given?: string) { - return generateID(prefix, "ascending", given) -} - -export function descending(prefix: keyof typeof prefixes, given?: string) { - return generateID(prefix, "descending", given) -} - -function generateID(prefix: keyof typeof prefixes, direction: "descending" | "ascending", given?: string): string { - if (!given) { - return createID(prefixes[prefix], direction) - } - - if (!given.startsWith(prefixes[prefix])) { - throw new Error(`ID ${given} does not start with ${prefixes[prefix]}`) - } - return given -} - -function createID(prefix: string, direction: "descending" | "ascending", timestamp?: number): string { - return prefix + "_" + create(direction === "descending", timestamp) -} - -export { createID as create } - -/** Extract timestamp from an ascending ID. Does not work with descending IDs. */ -export function timestamp(id: string): number { - const prefix = id.split("_")[0] - const hex = id.slice(prefix.length + 1, prefix.length + 13) - const encoded = BigInt("0x" + hex) - return Number(encoded / BigInt(0x1000)) -} - -export * as Identifier from "./id" diff --git a/packages/core/src/job.ts b/packages/core/src/job.ts index eb2efb2fd1..a9df101031 100644 --- a/packages/core/src/job.ts +++ b/packages/core/src/job.ts @@ -1,8 +1,8 @@ export * as Job from "./job" import { Cause, Clock, Context, Deferred, Effect, Exit, Layer, Scope, SynchronizedRef } from "effect" +import { JobID } from "@opencode-ai/schema/job-id" import { makeGlobalNode } from "@opencode-ai/util/effect/app-node" -import { Identifier } from "./id/id" import { SessionSchema } from "./session/schema" export type Status = "running" | "completed" | "error" | "cancelled" @@ -202,7 +202,7 @@ export const make = Effect.gen(function* () { const start: Interface["start"] = Effect.fn("Job.start")(function* (input) { return yield* Effect.uninterruptibleMask((restore) => Effect.gen(function* () { - const id = input.id ?? Identifier.ascending("job") + const id = input.id ?? JobID.create() const started_at = yield* Clock.currentTimeMillis const done = yield* Deferred.make() const backgrounded = yield* Deferred.make() diff --git a/packages/core/src/util/identifier.ts b/packages/core/src/util/identifier.ts deleted file mode 100644 index 442fbb3983..0000000000 --- a/packages/core/src/util/identifier.ts +++ /dev/null @@ -1 +0,0 @@ -export * as Identifier from "@opencode-ai/schema/identifier" diff --git a/packages/core/test/shared-schema.test.ts b/packages/core/test/shared-schema.test.ts index ac57342e8d..635cec5920 100644 --- a/packages/core/test/shared-schema.test.ts +++ b/packages/core/test/shared-schema.test.ts @@ -23,7 +23,7 @@ import { Permission } from "@opencode-ai/schema/permission" import { Pty } from "@opencode-ai/schema/pty" import { Reference } from "@opencode-ai/schema/reference" import { Skill } from "@opencode-ai/schema/skill" -import { AbsolutePath, DateTimeUtcFromMillis, optional, statics } from "@opencode-ai/schema/schema" +import { AbsolutePath, optional, statics } from "@opencode-ai/schema/schema" test("Core reuses the canonical shared schemas", async () => { const schemaAgent = await import("@opencode-ai/schema/agent") diff --git a/packages/enterprise/package.json b/packages/enterprise/package.json index 8ebc71d060..e43b9ea805 100644 --- a/packages/enterprise/package.json +++ b/packages/enterprise/package.json @@ -33,6 +33,7 @@ }, "devDependencies": { "@cloudflare/workers-types": "catalog:", + "@opencode-ai/schema": "workspace:*", "@tailwindcss/vite": "catalog:", "@typescript/native-preview": "catalog:", "@types/bun": "catalog:", diff --git a/packages/enterprise/test/core/share.test.ts b/packages/enterprise/test/core/share.test.ts index 35d52735e2..5bec933da6 100644 --- a/packages/enterprise/test/core/share.test.ts +++ b/packages/enterprise/test/core/share.test.ts @@ -1,11 +1,11 @@ import { describe, expect, test } from "bun:test" +import { descending } from "@opencode-ai/schema/identifier" import { Share } from "../../src/core/share" import { Storage } from "../../src/core/storage" -import { Identifier } from "@opencode-ai/core/util/identifier" describe.concurrent("core.share", () => { test("should create a share", async () => { - const sessionID = Identifier.descending() + const sessionID = descending() const share = await Share.create({ sessionID }) expect(share.sessionID).toBe(sessionID) @@ -15,7 +15,7 @@ describe.concurrent("core.share", () => { }) test("should remove a share as admin", async () => { - const share = await Share.create({ sessionID: Identifier.descending() }) + const share = await Share.create({ sessionID: descending() }) await Share.removeAdmin({ id: share.id }) @@ -23,7 +23,7 @@ describe.concurrent("core.share", () => { }) test("should sync data to a share", async () => { - const sessionID = Identifier.descending() + const sessionID = descending() const share = await Share.create({ sessionID }) const data: Share.Data[] = [ @@ -45,7 +45,7 @@ describe.concurrent("core.share", () => { }) test("should sync multiple batches of data", async () => { - const sessionID = Identifier.descending() + const sessionID = descending() const share = await Share.create({ sessionID }) const data1: Share.Data[] = [ @@ -79,7 +79,7 @@ describe.concurrent("core.share", () => { }) test("should retrieve synced data", async () => { - const sessionID = Identifier.descending() + const sessionID = descending() const share = await Share.create({ sessionID }) const data: Share.Data[] = [ @@ -108,7 +108,7 @@ describe.concurrent("core.share", () => { }) test("should retrieve data from multiple syncs", async () => { - const sessionID = Identifier.descending() + const sessionID = descending() const share = await Share.create({ sessionID }) const data1: Share.Data[] = [ @@ -154,7 +154,7 @@ describe.concurrent("core.share", () => { }) test("should return latest data when syncing duplicate parts", async () => { - const sessionID = Identifier.descending() + const sessionID = descending() const share = await Share.create({ sessionID }) const data1: Share.Data[] = [ @@ -192,7 +192,7 @@ describe.concurrent("core.share", () => { }) test("should return empty array for share with no data", async () => { - const sessionID = Identifier.descending() + const sessionID = descending() const share = await Share.create({ sessionID }) const result = await Share.data(share.id) @@ -203,7 +203,7 @@ describe.concurrent("core.share", () => { }) test("should migrate legacy event data into the snapshot", async () => { - const sessionID = Identifier.descending() + const sessionID = descending() const share = await Share.create({ sessionID }) const data: Share.Data[] = [ { @@ -213,7 +213,7 @@ describe.concurrent("core.share", () => { ] await Storage.remove(["share_snapshot", share.id]) - await Storage.write(["share_event", share.id, Identifier.descending()], data) + await Storage.write(["share_event", share.id, descending()], data) const result = await Share.data(share.id) const snapshot = await Storage.read<{ data: Share.Data[] }>(["share_snapshot", share.id]) @@ -225,7 +225,7 @@ describe.concurrent("core.share", () => { }) test("should throw error for invalid secret", async () => { - const sessionID = Identifier.descending() + const sessionID = descending() const share = await Share.create({ sessionID }) const data: Share.Data[] = [ @@ -246,7 +246,7 @@ describe.concurrent("core.share", () => { }) test("should throw error for non-existent share", async () => { - const sessionID = Identifier.descending() + const sessionID = descending() const data: Share.Data[] = [ { type: "part", @@ -263,7 +263,7 @@ describe.concurrent("core.share", () => { }) test("should handle different data types", async () => { - const sessionID = Identifier.descending() + const sessionID = descending() const share = await Share.create({ sessionID }) const data: Share.Data[] = [ diff --git a/packages/schema/src/job-id.ts b/packages/schema/src/job-id.ts new file mode 100644 index 0000000000..da1cf674be --- /dev/null +++ b/packages/schema/src/job-id.ts @@ -0,0 +1,9 @@ +import { Schema } from "effect" +import { ascending } from "./identifier.js" +import { statics } from "./schema.js" + +export const JobID = Schema.String.check(Schema.isStartsWith("job_")).pipe( + Schema.brand("JobID"), + statics((schema) => ({ create: () => schema.make("job_" + ascending()) })), +) +export type JobID = typeof JobID.Type diff --git a/packages/schema/test/contract-hygiene.test.ts b/packages/schema/test/contract-hygiene.test.ts index 7ab52ba549..3478ae6dbe 100644 --- a/packages/schema/test/contract-hygiene.test.ts +++ b/packages/schema/test/contract-hygiene.test.ts @@ -3,6 +3,7 @@ import { DateTime, Schema } from "effect" import { Agent } from "../src/agent.js" import { FileSystem } from "../src/filesystem.js" import { Form } from "../src/form.js" +import { JobID } from "../src/job-id.js" import { Mcp } from "../src/mcp.js" import { Model } from "../src/model.js" import { Project } from "../src/project.js" @@ -131,6 +132,7 @@ describe("contract hygiene", () => { }) test("current ID constructors expose create", () => { + expect(JobID.create()).toStartWith("job_") expect(Question.ID.create()).toStartWith("que_") expect(Pty.ID.create()).toStartWith("pty_") })