Compare commits
1 commit
dev
...
cleanup/lo
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
075cbb9d94 |
12 changed files with 65 additions and 78 deletions
|
|
@ -3,7 +3,7 @@ import { type AgentPartInput, type FilePartInput, type Part, type TextPartInput
|
||||||
import type { FileSelection } from "@/context/file"
|
import type { FileSelection } from "@/context/file"
|
||||||
import { encodeFilePath } from "@/context/file/path"
|
import { encodeFilePath } from "@/context/file/path"
|
||||||
import type { AgentPart, FileAttachmentPart, ImageAttachmentPart, Prompt } from "@/context/prompt"
|
import type { AgentPart, FileAttachmentPart, ImageAttachmentPart, Prompt } from "@/context/prompt"
|
||||||
import { Identifier } from "@/utils/id"
|
import { PartID } from "@/utils/id"
|
||||||
import { createCommentMetadata, formatCommentNote } from "@/utils/comment-note"
|
import { createCommentMetadata, formatCommentNote } from "@/utils/comment-note"
|
||||||
|
|
||||||
type PromptRequestPart = (TextPartInput | FilePartInput | AgentPartInput) & { id: string }
|
type PromptRequestPart = (TextPartInput | FilePartInput | AgentPartInput) & { id: string }
|
||||||
|
|
@ -91,7 +91,7 @@ const toOptimisticPart = (part: PromptRequestPart, sessionID: string, messageID:
|
||||||
export function buildRequestParts(input: BuildRequestPartsInput) {
|
export function buildRequestParts(input: BuildRequestPartsInput) {
|
||||||
const requestParts: PromptRequestPart[] = [
|
const requestParts: PromptRequestPart[] = [
|
||||||
{
|
{
|
||||||
id: Identifier.ascending("part"),
|
id: PartID.ascending(),
|
||||||
type: "text",
|
type: "text",
|
||||||
text: input.text,
|
text: input.text,
|
||||||
},
|
},
|
||||||
|
|
@ -100,7 +100,7 @@ export function buildRequestParts(input: BuildRequestPartsInput) {
|
||||||
const files = input.prompt.filter(isFileAttachment).map((attachment) => {
|
const files = input.prompt.filter(isFileAttachment).map((attachment) => {
|
||||||
const path = absolute(input.sessionDirectory, attachment.path)
|
const path = absolute(input.sessionDirectory, attachment.path)
|
||||||
return {
|
return {
|
||||||
id: Identifier.ascending("part"),
|
id: PartID.ascending(),
|
||||||
type: "file",
|
type: "file",
|
||||||
mime: "text/plain",
|
mime: "text/plain",
|
||||||
url: `file://${encodeFilePath(path)}${fileQuery(attachment.selection)}`,
|
url: `file://${encodeFilePath(path)}${fileQuery(attachment.selection)}`,
|
||||||
|
|
@ -119,7 +119,7 @@ export function buildRequestParts(input: BuildRequestPartsInput) {
|
||||||
|
|
||||||
const agents = input.prompt.filter(isAgentAttachment).map((attachment) => {
|
const agents = input.prompt.filter(isAgentAttachment).map((attachment) => {
|
||||||
return {
|
return {
|
||||||
id: Identifier.ascending("part"),
|
id: PartID.ascending(),
|
||||||
type: "agent",
|
type: "agent",
|
||||||
name: attachment.name,
|
name: attachment.name,
|
||||||
source: {
|
source: {
|
||||||
|
|
@ -139,7 +139,7 @@ export function buildRequestParts(input: BuildRequestPartsInput) {
|
||||||
used.add(url)
|
used.add(url)
|
||||||
|
|
||||||
const filePart = {
|
const filePart = {
|
||||||
id: Identifier.ascending("part"),
|
id: PartID.ascending(),
|
||||||
type: "file",
|
type: "file",
|
||||||
mime: "text/plain",
|
mime: "text/plain",
|
||||||
url,
|
url,
|
||||||
|
|
@ -154,7 +154,7 @@ export function buildRequestParts(input: BuildRequestPartsInput) {
|
||||||
used.add(url)
|
used.add(url)
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
id: Identifier.ascending("part"),
|
id: PartID.ascending(),
|
||||||
type: "file",
|
type: "file",
|
||||||
mime: "text/plain",
|
mime: "text/plain",
|
||||||
url,
|
url,
|
||||||
|
|
@ -165,7 +165,7 @@ export function buildRequestParts(input: BuildRequestPartsInput) {
|
||||||
|
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
id: Identifier.ascending("part"),
|
id: PartID.ascending(),
|
||||||
type: "text",
|
type: "text",
|
||||||
text: formatCommentNote({ path: item.path, selection: item.selection, comment }),
|
text: formatCommentNote({ path: item.path, selection: item.selection, comment }),
|
||||||
synthetic: true,
|
synthetic: true,
|
||||||
|
|
@ -184,7 +184,7 @@ export function buildRequestParts(input: BuildRequestPartsInput) {
|
||||||
|
|
||||||
const images = input.images.map((attachment) => {
|
const images = input.images.map((attachment) => {
|
||||||
return {
|
return {
|
||||||
id: Identifier.ascending("part"),
|
id: PartID.ascending(),
|
||||||
type: "file",
|
type: "file",
|
||||||
mime: attachment.mime,
|
mime: attachment.mime,
|
||||||
url: attachment.dataUrl,
|
url: attachment.dataUrl,
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ import { usePermission } from "@/context/permission"
|
||||||
import { type ContextItem, type ImageAttachmentPart, type Prompt, usePrompt } from "@/context/prompt"
|
import { type ContextItem, type ImageAttachmentPart, type Prompt, usePrompt } from "@/context/prompt"
|
||||||
import { useSDK } from "@/context/sdk"
|
import { useSDK } from "@/context/sdk"
|
||||||
import { useSync } from "@/context/sync"
|
import { useSync } from "@/context/sync"
|
||||||
import { Identifier } from "@/utils/id"
|
import { MessageID, PartID } from "@/utils/id"
|
||||||
import { Worktree as WorktreeState } from "@/utils/worktree"
|
import { Worktree as WorktreeState } from "@/utils/worktree"
|
||||||
import { buildRequestParts } from "./build-request-parts"
|
import { buildRequestParts } from "./build-request-parts"
|
||||||
import { setCursorPosition } from "./editor-dom"
|
import { setCursorPosition } from "./editor-dom"
|
||||||
|
|
@ -89,7 +89,7 @@ export async function sendFollowupDraft(input: FollowupSendInput) {
|
||||||
model: `${input.draft.model.providerID}/${input.draft.model.modelID}`,
|
model: `${input.draft.model.providerID}/${input.draft.model.modelID}`,
|
||||||
variant: input.draft.variant,
|
variant: input.draft.variant,
|
||||||
parts: images.map((attachment) => ({
|
parts: images.map((attachment) => ({
|
||||||
id: Identifier.ascending("part"),
|
id: PartID.ascending(),
|
||||||
type: "file" as const,
|
type: "file" as const,
|
||||||
mime: attachment.mime,
|
mime: attachment.mime,
|
||||||
url: attachment.dataUrl,
|
url: attachment.dataUrl,
|
||||||
|
|
@ -103,7 +103,7 @@ export async function sendFollowupDraft(input: FollowupSendInput) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const messageID = input.messageID ?? Identifier.ascending("message")
|
const messageID = input.messageID ?? MessageID.ascending()
|
||||||
const { requestParts, optimisticParts } = buildRequestParts({
|
const { requestParts, optimisticParts } = buildRequestParts({
|
||||||
prompt: input.draft.prompt,
|
prompt: input.draft.prompt,
|
||||||
context: input.draft.context,
|
context: input.draft.context,
|
||||||
|
|
@ -467,7 +467,7 @@ export function createPromptSubmit(input: PromptSubmitInput) {
|
||||||
model: `${model.providerID}/${model.modelID}`,
|
model: `${model.providerID}/${model.modelID}`,
|
||||||
variant,
|
variant,
|
||||||
parts: images.map((attachment) => ({
|
parts: images.map((attachment) => ({
|
||||||
id: Identifier.ascending("part"),
|
id: PartID.ascending(),
|
||||||
type: "file" as const,
|
type: "file" as const,
|
||||||
mime: attachment.mime,
|
mime: attachment.mime,
|
||||||
url: attachment.dataUrl,
|
url: attachment.dataUrl,
|
||||||
|
|
@ -486,7 +486,7 @@ export function createPromptSubmit(input: PromptSubmitInput) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const commentItems = context.filter((item) => item.type === "file" && !!item.comment?.trim())
|
const commentItems = context.filter((item) => item.type === "file" && !!item.comment?.trim())
|
||||||
const messageID = Identifier.ascending("message")
|
const messageID = MessageID.ascending()
|
||||||
|
|
||||||
const removeOptimisticMessage = () => {
|
const removeOptimisticMessage = () => {
|
||||||
sync.session.optimistic.remove({
|
sync.session.optimistic.remove({
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,7 @@ import { SessionSidePanel } from "@/pages/session/session-side-panel"
|
||||||
import { TerminalPanel } from "@/pages/session/terminal-panel"
|
import { TerminalPanel } from "@/pages/session/terminal-panel"
|
||||||
import { useSessionCommands } from "@/pages/session/use-session-commands"
|
import { useSessionCommands } from "@/pages/session/use-session-commands"
|
||||||
import { useSessionHashScroll } from "@/pages/session/use-session-hash-scroll"
|
import { useSessionHashScroll } from "@/pages/session/use-session-hash-scroll"
|
||||||
import { Identifier } from "@/utils/id"
|
import { MessageID } from "@/utils/id"
|
||||||
import { diffs as list } from "@/utils/diffs"
|
import { diffs as list } from "@/utils/diffs"
|
||||||
import { Persist, persisted } from "@/utils/persist"
|
import { Persist, persisted } from "@/utils/persist"
|
||||||
import { extractPromptFromParts } from "@/utils/prompt"
|
import { extractPromptFromParts } from "@/utils/prompt"
|
||||||
|
|
@ -1575,10 +1575,7 @@ export default function Page() {
|
||||||
}
|
}
|
||||||
|
|
||||||
const queueFollowup = (draft: FollowupDraft) => {
|
const queueFollowup = (draft: FollowupDraft) => {
|
||||||
setFollowup("items", draft.sessionID, (items) => [
|
setFollowup("items", draft.sessionID, (items) => [...(items ?? []), { id: MessageID.ascending(), ...draft }])
|
||||||
...(items ?? []),
|
|
||||||
{ id: Identifier.ascending("message"), ...draft },
|
|
||||||
])
|
|
||||||
setFollowup("failed", draft.sessionID, undefined)
|
setFollowup("failed", draft.sessionID, undefined)
|
||||||
setFollowup("paused", draft.sessionID, undefined)
|
setFollowup("paused", draft.sessionID, undefined)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,31 +1,15 @@
|
||||||
import z from "zod"
|
|
||||||
|
|
||||||
const prefixes = {
|
|
||||||
session: "ses",
|
|
||||||
message: "msg",
|
|
||||||
permission: "per",
|
|
||||||
user: "usr",
|
|
||||||
part: "prt",
|
|
||||||
pty: "pty",
|
|
||||||
} as const
|
|
||||||
|
|
||||||
const LENGTH = 26
|
const LENGTH = 26
|
||||||
let lastTimestamp = 0
|
let lastTimestamp = 0
|
||||||
let counter = 0
|
let counter = 0
|
||||||
|
|
||||||
type Prefix = keyof typeof prefixes
|
type Prefix = "msg" | "prt"
|
||||||
export namespace Identifier {
|
|
||||||
export function schema(prefix: Prefix) {
|
|
||||||
return z.string().startsWith(prefixes[prefix])
|
|
||||||
}
|
|
||||||
|
|
||||||
export function ascending(prefix: Prefix, given?: string) {
|
export const MessageID = {
|
||||||
return generateID(prefix, false, given)
|
ascending: (given?: string) => generateID("msg", false, given),
|
||||||
}
|
}
|
||||||
|
|
||||||
export function descending(prefix: Prefix, given?: string) {
|
export const PartID = {
|
||||||
return generateID(prefix, true, given)
|
ascending: (given?: string) => generateID("prt", false, given),
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function generateID(prefix: Prefix, descending: boolean, given?: string): string {
|
function generateID(prefix: Prefix, descending: boolean, given?: string): string {
|
||||||
|
|
@ -33,8 +17,8 @@ function generateID(prefix: Prefix, descending: boolean, given?: string): string
|
||||||
return create(prefix, descending)
|
return create(prefix, descending)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!given.startsWith(prefixes[prefix])) {
|
if (!given.startsWith(prefix)) {
|
||||||
throw new Error(`ID ${given} does not start with ${prefixes[prefix]}`)
|
throw new Error(`ID ${given} does not start with ${prefix}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
return given
|
return given
|
||||||
|
|
@ -61,7 +45,7 @@ function create(prefix: Prefix, descending: boolean, timestamp?: number): string
|
||||||
timeBytes[i] = Number((now >> BigInt(40 - 8 * i)) & BigInt(0xff))
|
timeBytes[i] = Number((now >> BigInt(40 - 8 * i)) & BigInt(0xff))
|
||||||
}
|
}
|
||||||
|
|
||||||
return prefixes[prefix] + "_" + bytesToHex(timeBytes) + randomBase62(LENGTH - 12)
|
return prefix + "_" + bytesToHex(timeBytes) + randomBase62(LENGTH - 12)
|
||||||
}
|
}
|
||||||
|
|
||||||
function bytesToHex(bytes: Uint8Array): string {
|
function bytesToHex(bytes: Uint8Array): string {
|
||||||
|
|
|
||||||
|
|
@ -4,13 +4,14 @@ import { Identifier } from "@/id/id"
|
||||||
import { zod } from "@opencode-ai/core/effect-zod"
|
import { zod } from "@opencode-ai/core/effect-zod"
|
||||||
import { withStatics } from "@opencode-ai/core/schema"
|
import { withStatics } from "@opencode-ai/core/schema"
|
||||||
|
|
||||||
const workspaceIdSchema = Schema.String.check(Schema.isStartsWith("wrk")).pipe(Schema.brand("WorkspaceID"))
|
const workspacePrefix = "wrk"
|
||||||
|
const workspaceIdSchema = Schema.String.check(Schema.isStartsWith(workspacePrefix)).pipe(Schema.brand("WorkspaceID"))
|
||||||
|
|
||||||
export type WorkspaceID = typeof workspaceIdSchema.Type
|
export type WorkspaceID = typeof workspaceIdSchema.Type
|
||||||
|
|
||||||
export const WorkspaceID = workspaceIdSchema.pipe(
|
export const WorkspaceID = workspaceIdSchema.pipe(
|
||||||
withStatics((schema: typeof workspaceIdSchema) => ({
|
withStatics((schema: typeof workspaceIdSchema) => ({
|
||||||
ascending: (id?: string) => schema.make(Identifier.ascending("workspace", id)),
|
ascending: (id?: string) => schema.make(Identifier.ascending(workspacePrefix, id)),
|
||||||
zod: zod(schema),
|
zod: zod(schema),
|
||||||
})),
|
})),
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,6 @@
|
||||||
import { randomBytes } from "crypto"
|
import { randomBytes } from "crypto"
|
||||||
|
|
||||||
const prefixes = {
|
export type Prefix = "evt" | "ses" | "msg" | "per" | "que" | "prt" | "pty" | "tool" | "wrk"
|
||||||
event: "evt",
|
|
||||||
session: "ses",
|
|
||||||
message: "msg",
|
|
||||||
permission: "per",
|
|
||||||
question: "que",
|
|
||||||
part: "prt",
|
|
||||||
pty: "pty",
|
|
||||||
tool: "tool",
|
|
||||||
workspace: "wrk",
|
|
||||||
} as const
|
|
||||||
|
|
||||||
const LENGTH = 26
|
const LENGTH = 26
|
||||||
|
|
||||||
|
|
@ -18,21 +8,21 @@ const LENGTH = 26
|
||||||
let lastTimestamp = 0
|
let lastTimestamp = 0
|
||||||
let counter = 0
|
let counter = 0
|
||||||
|
|
||||||
export function ascending(prefix: keyof typeof prefixes, given?: string) {
|
export function ascending(prefix: Prefix, given?: string) {
|
||||||
return generateID(prefix, "ascending", given)
|
return generateID(prefix, "ascending", given)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function descending(prefix: keyof typeof prefixes, given?: string) {
|
export function descending(prefix: Prefix, given?: string) {
|
||||||
return generateID(prefix, "descending", given)
|
return generateID(prefix, "descending", given)
|
||||||
}
|
}
|
||||||
|
|
||||||
function generateID(prefix: keyof typeof prefixes, direction: "descending" | "ascending", given?: string): string {
|
function generateID(prefix: Prefix, direction: "descending" | "ascending", given?: string): string {
|
||||||
if (!given) {
|
if (!given) {
|
||||||
return create(prefixes[prefix], direction)
|
return create(prefix, direction)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!given.startsWith(prefixes[prefix])) {
|
if (!given.startsWith(prefix)) {
|
||||||
throw new Error(`ID ${given} does not start with ${prefixes[prefix]}`)
|
throw new Error(`ID ${given} does not start with ${prefix}`)
|
||||||
}
|
}
|
||||||
return given
|
return given
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,12 +4,14 @@ import { Identifier } from "@/id/id"
|
||||||
import { zod } from "@opencode-ai/core/effect-zod"
|
import { zod } from "@opencode-ai/core/effect-zod"
|
||||||
import { Newtype } from "@opencode-ai/core/schema"
|
import { Newtype } from "@opencode-ai/core/schema"
|
||||||
|
|
||||||
|
const permissionPrefix = "per"
|
||||||
|
|
||||||
export class PermissionID extends Newtype<PermissionID>()(
|
export class PermissionID extends Newtype<PermissionID>()(
|
||||||
"PermissionID",
|
"PermissionID",
|
||||||
Schema.String.check(Schema.isStartsWith("per")),
|
Schema.String.check(Schema.isStartsWith(permissionPrefix)),
|
||||||
) {
|
) {
|
||||||
static ascending(id?: string): PermissionID {
|
static ascending(id?: string): PermissionID {
|
||||||
return this.make(Identifier.ascending("permission", id))
|
return this.make(Identifier.ascending(permissionPrefix, id))
|
||||||
}
|
}
|
||||||
|
|
||||||
static readonly zod = zod(this)
|
static readonly zod = zod(this)
|
||||||
|
|
|
||||||
|
|
@ -4,13 +4,14 @@ import { Identifier } from "@/id/id"
|
||||||
import { zod } from "@opencode-ai/core/effect-zod"
|
import { zod } from "@opencode-ai/core/effect-zod"
|
||||||
import { withStatics } from "@opencode-ai/core/schema"
|
import { withStatics } from "@opencode-ai/core/schema"
|
||||||
|
|
||||||
const ptyIdSchema = Schema.String.check(Schema.isStartsWith("pty")).pipe(Schema.brand("PtyID"))
|
const ptyPrefix = "pty"
|
||||||
|
const ptyIdSchema = Schema.String.check(Schema.isStartsWith(ptyPrefix)).pipe(Schema.brand("PtyID"))
|
||||||
|
|
||||||
export type PtyID = typeof ptyIdSchema.Type
|
export type PtyID = typeof ptyIdSchema.Type
|
||||||
|
|
||||||
export const PtyID = ptyIdSchema.pipe(
|
export const PtyID = ptyIdSchema.pipe(
|
||||||
withStatics((schema: typeof ptyIdSchema) => ({
|
withStatics((schema: typeof ptyIdSchema) => ({
|
||||||
ascending: (id?: string) => schema.make(Identifier.ascending("pty", id)),
|
ascending: (id?: string) => schema.make(Identifier.ascending(ptyPrefix, id)),
|
||||||
zod: zod(schema),
|
zod: zod(schema),
|
||||||
})),
|
})),
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -4,9 +4,14 @@ import { Identifier } from "@/id/id"
|
||||||
import { zod } from "@opencode-ai/core/effect-zod"
|
import { zod } from "@opencode-ai/core/effect-zod"
|
||||||
import { Newtype } from "@opencode-ai/core/schema"
|
import { Newtype } from "@opencode-ai/core/schema"
|
||||||
|
|
||||||
export class QuestionID extends Newtype<QuestionID>()("QuestionID", Schema.String.check(Schema.isStartsWith("que"))) {
|
const questionPrefix = "que"
|
||||||
|
|
||||||
|
export class QuestionID extends Newtype<QuestionID>()(
|
||||||
|
"QuestionID",
|
||||||
|
Schema.String.check(Schema.isStartsWith(questionPrefix)),
|
||||||
|
) {
|
||||||
static ascending(id?: string): QuestionID {
|
static ascending(id?: string): QuestionID {
|
||||||
return this.make(Identifier.ascending("question", id))
|
return this.make(Identifier.ascending(questionPrefix, id))
|
||||||
}
|
}
|
||||||
|
|
||||||
static readonly zod = zod(this)
|
static readonly zod = zod(this)
|
||||||
|
|
|
||||||
|
|
@ -4,30 +4,34 @@ import { Identifier } from "@/id/id"
|
||||||
import { zod } from "@opencode-ai/core/effect-zod"
|
import { zod } from "@opencode-ai/core/effect-zod"
|
||||||
import { withStatics } from "@opencode-ai/core/schema"
|
import { withStatics } from "@opencode-ai/core/schema"
|
||||||
|
|
||||||
export const SessionID = Schema.String.check(Schema.isStartsWith("ses")).pipe(
|
const sessionPrefix = "ses"
|
||||||
|
const messagePrefix = "msg"
|
||||||
|
const partPrefix = "prt"
|
||||||
|
|
||||||
|
export const SessionID = Schema.String.check(Schema.isStartsWith(sessionPrefix)).pipe(
|
||||||
Schema.brand("SessionID"),
|
Schema.brand("SessionID"),
|
||||||
withStatics((s) => ({
|
withStatics((s) => ({
|
||||||
descending: (id?: string) => s.make(Identifier.descending("session", id)),
|
descending: (id?: string) => s.make(Identifier.descending(sessionPrefix, id)),
|
||||||
zod: zod(s),
|
zod: zod(s),
|
||||||
})),
|
})),
|
||||||
)
|
)
|
||||||
|
|
||||||
export type SessionID = Schema.Schema.Type<typeof SessionID>
|
export type SessionID = Schema.Schema.Type<typeof SessionID>
|
||||||
|
|
||||||
export const MessageID = Schema.String.check(Schema.isStartsWith("msg")).pipe(
|
export const MessageID = Schema.String.check(Schema.isStartsWith(messagePrefix)).pipe(
|
||||||
Schema.brand("MessageID"),
|
Schema.brand("MessageID"),
|
||||||
withStatics((s) => ({
|
withStatics((s) => ({
|
||||||
ascending: (id?: string) => s.make(Identifier.ascending("message", id)),
|
ascending: (id?: string) => s.make(Identifier.ascending(messagePrefix, id)),
|
||||||
zod: zod(s),
|
zod: zod(s),
|
||||||
})),
|
})),
|
||||||
)
|
)
|
||||||
|
|
||||||
export type MessageID = Schema.Schema.Type<typeof MessageID>
|
export type MessageID = Schema.Schema.Type<typeof MessageID>
|
||||||
|
|
||||||
export const PartID = Schema.String.check(Schema.isStartsWith("prt")).pipe(
|
export const PartID = Schema.String.check(Schema.isStartsWith(partPrefix)).pipe(
|
||||||
Schema.brand("PartID"),
|
Schema.brand("PartID"),
|
||||||
withStatics((s) => ({
|
withStatics((s) => ({
|
||||||
ascending: (id?: string) => s.make(Identifier.ascending("part", id)),
|
ascending: (id?: string) => s.make(Identifier.ascending(partPrefix, id)),
|
||||||
zod: zod(s),
|
zod: zod(s),
|
||||||
})),
|
})),
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -4,10 +4,12 @@ import { Identifier } from "@/id/id"
|
||||||
import { zod } from "@opencode-ai/core/effect-zod"
|
import { zod } from "@opencode-ai/core/effect-zod"
|
||||||
import { withStatics } from "@opencode-ai/core/schema"
|
import { withStatics } from "@opencode-ai/core/schema"
|
||||||
|
|
||||||
export const EventID = Schema.String.check(Schema.isStartsWith("evt")).pipe(
|
const eventPrefix = "evt"
|
||||||
|
|
||||||
|
export const EventID = Schema.String.check(Schema.isStartsWith(eventPrefix)).pipe(
|
||||||
Schema.brand("EventID"),
|
Schema.brand("EventID"),
|
||||||
withStatics((s) => ({
|
withStatics((s) => ({
|
||||||
ascending: (id?: string) => s.make(Identifier.ascending("event", id)),
|
ascending: (id?: string) => s.make(Identifier.ascending(eventPrefix, id)),
|
||||||
zod: zod(s),
|
zod: zod(s),
|
||||||
})),
|
})),
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -4,13 +4,14 @@ import { Identifier } from "@/id/id"
|
||||||
import { zod } from "@opencode-ai/core/effect-zod"
|
import { zod } from "@opencode-ai/core/effect-zod"
|
||||||
import { withStatics } from "@opencode-ai/core/schema"
|
import { withStatics } from "@opencode-ai/core/schema"
|
||||||
|
|
||||||
const toolIdSchema = Schema.String.check(Schema.isStartsWith("tool")).pipe(Schema.brand("ToolID"))
|
const toolPrefix = "tool"
|
||||||
|
const toolIdSchema = Schema.String.check(Schema.isStartsWith(toolPrefix)).pipe(Schema.brand("ToolID"))
|
||||||
|
|
||||||
export type ToolID = typeof toolIdSchema.Type
|
export type ToolID = typeof toolIdSchema.Type
|
||||||
|
|
||||||
export const ToolID = toolIdSchema.pipe(
|
export const ToolID = toolIdSchema.pipe(
|
||||||
withStatics((schema: typeof toolIdSchema) => ({
|
withStatics((schema: typeof toolIdSchema) => ({
|
||||||
ascending: (id?: string) => schema.make(Identifier.ascending("tool", id)),
|
ascending: (id?: string) => schema.make(Identifier.ascending(toolPrefix, id)),
|
||||||
zod: zod(schema),
|
zod: zod(schema),
|
||||||
})),
|
})),
|
||||||
)
|
)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue