Skip to content

Commit 6d948bf

Browse files
committed
feat(id): brand remaining permission, pty, question, and tool IDs
1 parent 7476637 commit 6d948bf

17 files changed

Lines changed: 121 additions & 46 deletions

File tree

packages/opencode/src/id/id.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,12 @@ export namespace Identifier {
55
const prefixes = {
66
session: "ses",
77
message: "msg",
8-
permission: "per",
9-
question: "que",
8+
permission: "prm",
9+
question: "qst",
1010
user: "usr",
1111
part: "prt",
1212
pty: "pty",
13-
tool: "tool",
13+
tool: "tol",
1414
workspace: "wrk",
1515
} as const
1616

packages/opencode/src/permission/index.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@ import { Bus } from "@/bus"
33
import { SessionID, MessageID } from "@/session/schema"
44
import z from "zod"
55
import { Log } from "../util/log"
6-
import { Identifier } from "../id/id"
76
import { Plugin } from "../plugin"
87
import { Instance } from "../project/instance"
98
import { Wildcard } from "../util/wildcard"
9+
import { PermissionID } from "./schema"
1010

1111
export namespace Permission {
1212
const log = Log.create({ service: "permission" })
@@ -22,7 +22,7 @@ export namespace Permission {
2222

2323
export const Info = z
2424
.object({
25-
id: z.string(),
25+
id: PermissionID.zod,
2626
type: z.string(),
2727
pattern: z.union([z.string(), z.array(z.string())]).optional(),
2828
sessionID: SessionID.zod,
@@ -45,7 +45,7 @@ export namespace Permission {
4545
"permission.replied",
4646
z.object({
4747
sessionID: SessionID.zod,
48-
permissionID: z.string(),
48+
permissionID: PermissionID.zod,
4949
response: z.string(),
5050
}),
5151
),
@@ -118,7 +118,7 @@ export namespace Permission {
118118
const keys = toKeys(input.pattern, input.type)
119119
if (covered(keys, approvedForSession)) return
120120
const info: Info = {
121-
id: Identifier.ascending("permission"),
121+
id: PermissionID.ascending(),
122122
type: input.type,
123123
pattern: input.pattern,
124124
sessionID: input.sessionID,

packages/opencode/src/permission/next.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import { Bus } from "@/bus"
22
import { BusEvent } from "@/bus/bus-event"
33
import { Config } from "@/config/config"
4-
import { Identifier } from "@/id/id"
54
import { SessionID, MessageID } from "@/session/schema"
5+
import { PermissionID } from "./schema"
66
import { Instance } from "@/project/instance"
77
import { Database, eq } from "@/storage/db"
88
import { PermissionTable } from "@/session/session.sql"
@@ -69,7 +69,7 @@ export namespace PermissionNext {
6969

7070
export const Request = z
7171
.object({
72-
id: Identifier.schema("permission"),
72+
id: PermissionID.zod,
7373
sessionID: SessionID.zod,
7474
permission: z.string(),
7575
patterns: z.string().array(),
@@ -102,7 +102,7 @@ export namespace PermissionNext {
102102
"permission.replied",
103103
z.object({
104104
sessionID: SessionID.zod,
105-
requestID: z.string(),
105+
requestID: PermissionID.zod,
106106
reply: Reply,
107107
}),
108108
),
@@ -143,7 +143,7 @@ export namespace PermissionNext {
143143
if (rule.action === "deny")
144144
throw new DeniedError(ruleset.filter((r) => Wildcard.match(request.permission, r.permission)))
145145
if (rule.action === "ask") {
146-
const id = input.id ?? Identifier.ascending("permission")
146+
const id = input.id ?? PermissionID.ascending()
147147
return new Promise<void>((resolve, reject) => {
148148
const info: Request = {
149149
id,
@@ -164,7 +164,7 @@ export namespace PermissionNext {
164164

165165
export const reply = fn(
166166
z.object({
167-
requestID: Identifier.schema("permission"),
167+
requestID: PermissionID.zod,
168168
reply: Reply,
169169
message: z.string().optional(),
170170
}),
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { Schema } from "effect"
2+
import z from "zod"
3+
4+
import { Identifier } from "@/id/id"
5+
import { withStatics } from "@/util/schema"
6+
7+
const permissionIdSchema = Schema.String.pipe(Schema.brand("PermissionId"))
8+
9+
export type PermissionID = typeof permissionIdSchema.Type
10+
11+
export const PermissionID = permissionIdSchema.pipe(
12+
withStatics((schema: typeof permissionIdSchema) => ({
13+
make: (id: string) => schema.makeUnsafe(id),
14+
ascending: (id?: string) => schema.makeUnsafe(Identifier.ascending("permission", id)),
15+
zod: z.string().startsWith("prm").pipe(z.custom<PermissionID>()),
16+
})),
17+
)

packages/opencode/src/pty/index.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@ import { BusEvent } from "@/bus/bus-event"
22
import { Bus } from "@/bus"
33
import { type IPty } from "bun-pty"
44
import z from "zod"
5-
import { Identifier } from "../id/id"
65
import { Log } from "../util/log"
76
import { Instance } from "../project/instance"
87
import { lazy } from "@opencode-ai/util/lazy"
98
import { Shell } from "@/shell/shell"
109
import { Plugin } from "@/plugin"
10+
import { PtyID } from "./schema"
1111

1212
export namespace Pty {
1313
const log = Log.create({ service: "pty" })
@@ -40,7 +40,7 @@ export namespace Pty {
4040

4141
export const Info = z
4242
.object({
43-
id: Identifier.schema("pty"),
43+
id: PtyID.zod,
4444
title: z.string(),
4545
command: z.string(),
4646
args: z.array(z.string()),
@@ -77,8 +77,8 @@ export namespace Pty {
7777
export const Event = {
7878
Created: BusEvent.define("pty.created", z.object({ info: Info })),
7979
Updated: BusEvent.define("pty.updated", z.object({ info: Info })),
80-
Exited: BusEvent.define("pty.exited", z.object({ id: Identifier.schema("pty"), exitCode: z.number() })),
81-
Deleted: BusEvent.define("pty.deleted", z.object({ id: Identifier.schema("pty") })),
80+
Exited: BusEvent.define("pty.exited", z.object({ id: PtyID.zod, exitCode: z.number() })),
81+
Deleted: BusEvent.define("pty.deleted", z.object({ id: PtyID.zod })),
8282
}
8383

8484
interface ActiveSession {
@@ -118,7 +118,7 @@ export namespace Pty {
118118
}
119119

120120
export async function create(input: CreateInput) {
121-
const id = Identifier.create("pty", false)
121+
const id = PtyID.ascending()
122122
const command = input.command || Shell.preferred()
123123
const args = input.args || []
124124
if (command.endsWith("sh")) {
@@ -234,7 +234,7 @@ export namespace Pty {
234234
}
235235
}
236236
session.subscribers.clear()
237-
Bus.publish(Event.Deleted, { id })
237+
Bus.publish(Event.Deleted, { id: session.info.id })
238238
}
239239

240240
export function resize(id: string, cols: number, rows: number) {
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { Schema } from "effect"
2+
import z from "zod"
3+
4+
import { Identifier } from "@/id/id"
5+
import { withStatics } from "@/util/schema"
6+
7+
const ptyIdSchema = Schema.String.pipe(Schema.brand("PtyId"))
8+
9+
export type PtyID = typeof ptyIdSchema.Type
10+
11+
export const PtyID = ptyIdSchema.pipe(
12+
withStatics((schema: typeof ptyIdSchema) => ({
13+
make: (id: string) => schema.makeUnsafe(id),
14+
ascending: (id?: string) => schema.makeUnsafe(Identifier.ascending("pty", id)),
15+
zod: z.string().startsWith("pty").pipe(z.custom<PtyID>()),
16+
})),
17+
)

packages/opencode/src/question/index.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import { Bus } from "@/bus"
22
import { BusEvent } from "@/bus/bus-event"
3-
import { Identifier } from "@/id/id"
43
import { SessionID, MessageID } from "@/session/schema"
54
import { Instance } from "@/project/instance"
65
import { Log } from "@/util/log"
76
import z from "zod"
7+
import { QuestionID } from "./schema"
88

99
export namespace Question {
1010
const log = Log.create({ service: "question" })
@@ -34,7 +34,7 @@ export namespace Question {
3434

3535
export const Request = z
3636
.object({
37-
id: Identifier.schema("question"),
37+
id: QuestionID.zod,
3838
sessionID: SessionID.zod,
3939
questions: z.array(Info).describe("Questions to ask"),
4040
tool: z
@@ -67,15 +67,15 @@ export namespace Question {
6767
"question.replied",
6868
z.object({
6969
sessionID: SessionID.zod,
70-
requestID: z.string(),
70+
requestID: QuestionID.zod,
7171
answers: z.array(Answer),
7272
}),
7373
),
7474
Rejected: BusEvent.define(
7575
"question.rejected",
7676
z.object({
7777
sessionID: SessionID.zod,
78-
requestID: z.string(),
78+
requestID: QuestionID.zod,
7979
}),
8080
),
8181
}
@@ -101,7 +101,7 @@ export namespace Question {
101101
tool?: { messageID: MessageID; callID: string }
102102
}): Promise<Answer[]> {
103103
const s = await state()
104-
const id = Identifier.ascending("question")
104+
const id = QuestionID.ascending()
105105

106106
log.info("asking", { id, questions: input.questions.length })
107107

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { Schema } from "effect"
2+
import z from "zod"
3+
4+
import { Identifier } from "@/id/id"
5+
import { withStatics } from "@/util/schema"
6+
7+
const questionIdSchema = Schema.String.pipe(Schema.brand("QuestionId"))
8+
9+
export type QuestionID = typeof questionIdSchema.Type
10+
11+
export const QuestionID = questionIdSchema.pipe(
12+
withStatics((schema: typeof questionIdSchema) => ({
13+
make: (id: string) => schema.makeUnsafe(id),
14+
ascending: (id?: string) => schema.makeUnsafe(Identifier.ascending("question", id)),
15+
zod: z.string().startsWith("qst").pipe(z.custom<QuestionID>()),
16+
})),
17+
)

packages/opencode/src/server/routes/permission.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { Hono } from "hono"
22
import { describeRoute, validator, resolver } from "hono-openapi"
33
import z from "zod"
44
import { PermissionNext } from "@/permission/next"
5+
import { PermissionID } from "@/permission/schema"
56
import { errors } from "../error"
67
import { lazy } from "../../util/lazy"
78

@@ -28,7 +29,7 @@ export const PermissionRoutes = lazy(() =>
2829
validator(
2930
"param",
3031
z.object({
31-
requestID: z.string(),
32+
requestID: PermissionID.zod,
3233
}),
3334
),
3435
validator("json", z.object({ reply: PermissionNext.Reply, message: z.string().optional() })),

packages/opencode/src/server/routes/pty.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { describeRoute, validator, resolver } from "hono-openapi"
33
import { upgradeWebSocket } from "hono/bun"
44
import z from "zod"
55
import { Pty } from "@/pty"
6+
import { PtyID } from "@/pty/schema"
67
import { NotFoundError } from "../../storage/db"
78
import { errors } from "../error"
89
import { lazy } from "../../util/lazy"
@@ -72,7 +73,7 @@ export const PtyRoutes = lazy(() =>
7273
...errors(404),
7374
},
7475
}),
75-
validator("param", z.object({ ptyID: z.string() })),
76+
validator("param", z.object({ ptyID: PtyID.zod })),
7677
async (c) => {
7778
const info = Pty.get(c.req.valid("param").ptyID)
7879
if (!info) {
@@ -99,7 +100,7 @@ export const PtyRoutes = lazy(() =>
99100
...errors(400),
100101
},
101102
}),
102-
validator("param", z.object({ ptyID: z.string() })),
103+
validator("param", z.object({ ptyID: PtyID.zod })),
103104
validator("json", Pty.UpdateInput),
104105
async (c) => {
105106
const info = await Pty.update(c.req.valid("param").ptyID, c.req.valid("json"))
@@ -124,7 +125,7 @@ export const PtyRoutes = lazy(() =>
124125
...errors(404),
125126
},
126127
}),
127-
validator("param", z.object({ ptyID: z.string() })),
128+
validator("param", z.object({ ptyID: PtyID.zod })),
128129
async (c) => {
129130
await Pty.remove(c.req.valid("param").ptyID)
130131
return c.json(true)
@@ -148,9 +149,9 @@ export const PtyRoutes = lazy(() =>
148149
...errors(404),
149150
},
150151
}),
151-
validator("param", z.object({ ptyID: z.string() })),
152+
validator("param", z.object({ ptyID: PtyID.zod })),
152153
upgradeWebSocket((c) => {
153-
const id = c.req.param("ptyID")
154+
const id = PtyID.zod.parse(c.req.param("ptyID"))
154155
const cursor = (() => {
155156
const value = c.req.query("cursor")
156157
if (!value) return

0 commit comments

Comments
 (0)