Merge remote-tracking branch 'origin/v2' into search-integration

# Conflicts:
#	packages/client/src/promise/generated/client.ts
#	packages/client/src/promise/generated/types.ts
#	packages/client/test/promise.test.ts
#	packages/core/src/plugin/host.ts
#	packages/core/src/plugin/internal.ts
#	packages/core/src/plugin/promise.ts
#	packages/core/test/plugin/host.ts
#	packages/plugin/src/v2/effect/index.ts
#	packages/plugin/src/v2/effect/integration.ts
#	packages/plugin/src/v2/promise/index.ts
#	packages/plugin/src/v2/promise/integration.ts
#	packages/protocol/src/client.ts
#	packages/schema/src/index.ts
#	packages/sdk/js/src/v2/gen/sdk.gen.ts
This commit is contained in:
Shoubhit Dash 2026-07-08 15:09:39 +05:30
commit a6acc2397d
374 changed files with 15254 additions and 10009 deletions

View file

@ -61,27 +61,5 @@ export const groupNames = {
"server.vcs": "vcs",
} as const
export const endpointNames = {
"session.messages": "list",
"integration.connect.key": "connectKey",
"search.provider.get": "provider",
"search.provider.select": "selectProvider",
"integration.connect.oauth": "connectOauth",
"integration.attempt.status": "attemptStatus",
"integration.attempt.complete": "attemptComplete",
"integration.attempt.cancel": "attemptCancel",
"session.instructions.entry.list": ["instructions", "entry", "list"],
"session.instructions.entry.put": ["instructions", "entry", "put"],
"session.instructions.entry.remove": ["instructions", "entry", "remove"],
"session.revert.stage": "revertStage",
"session.revert.clear": "revertClear",
"session.revert.commit": "revertCommit",
"permission.request.list": "listRequests",
"permission.saved.list": "listSaved",
"permission.saved.remove": "removeSaved",
"form.request.list": "listRequests",
"question.request.list": "listRequests",
} as const
export const promiseOmitEndpoints = new Set(["pty.connect", "pty.connectToken"])
export const effectOmitEndpoints = new Set(["fs.read", "pty.connect", "pty.connectToken"])

View file

@ -1,4 +1,5 @@
import { Schema } from "effect"
import { Skill } from "@opencode-ai/schema/skill"
export class InvalidRequestError extends Schema.TaggedErrorClass<InvalidRequestError>()(
"InvalidRequestError",
@ -83,7 +84,7 @@ export class MessageNotFoundError extends Schema.TaggedErrorClass<MessageNotFoun
export class SkillNotFoundError extends Schema.TaggedErrorClass<SkillNotFoundError>()(
"SkillNotFoundError",
{
skill: Schema.String,
skill: Skill.ID,
message: Schema.String,
},
{ httpApiStatus: 404 },

View file

@ -1,6 +1,7 @@
import { Location } from "@opencode-ai/schema/location"
import { Schema } from "effect"
import { HttpApiEndpoint, HttpApiGroup, OpenApi } from "effect/unstable/httpapi"
import { HttpApiEndpoint, HttpApiGroup, HttpApiSchema, OpenApi } from "effect/unstable/httpapi"
import { LocationQuery, locationQueryOpenApi } from "./location.js"
export const DebugGroup = HttpApiGroup.make("server.debug")
.add(
@ -8,10 +9,24 @@ export const DebugGroup = HttpApiGroup.make("server.debug")
success: Schema.Array(Location.Ref),
}).annotateMerge(
OpenApi.annotations({
identifier: "v2.debug.location",
identifier: "v2.debug.location.list",
summary: "List loaded locations",
description: "List locations currently loaded by the server.",
}),
),
)
.add(
HttpApiEndpoint.delete("debug.location.evict", "/api/debug/location", {
query: LocationQuery,
success: HttpApiSchema.NoContent,
})
.annotateMerge(locationQueryOpenApi)
.annotateMerge(
OpenApi.annotations({
identifier: "v2.debug.location.evict",
summary: "Evict a loaded location",
description: "Dispose the requested location's cached services so its next use boots them fresh.",
}),
),
)
.annotateMerge(OpenApi.annotations({ title: "debug" }))

View file

@ -19,4 +19,18 @@ export const McpGroup = HttpApiGroup.make("server.mcp")
}),
),
)
.annotateMerge(OpenApi.annotations({ title: "mcp", description: "MCP server status routes." }))
.add(
HttpApiEndpoint.get("mcp.resource.catalog", "/api/mcp/resource", {
query: LocationQuery,
success: Location.response(Mcp.ResourceCatalog),
})
.annotateMerge(locationQueryOpenApi)
.annotateMerge(
OpenApi.annotations({
identifier: "v2.mcp.resource.catalog",
summary: "List MCP resources",
description: "Retrieve resources and resource templates from connected MCP servers.",
}),
),
)
.annotateMerge(OpenApi.annotations({ title: "mcp", description: "MCP server and resource routes." }))

View file

@ -27,7 +27,7 @@ export const MessageGroup = HttpApiGroup.make("server.message")
params: { sessionID: Session.ID },
query: SessionMessagesQuery,
success: Schema.Struct({
data: Schema.Array(SessionMessage.Message),
data: Schema.Array(SessionMessage.Info),
cursor: Schema.Struct({
previous: Schema.String.pipe(Schema.optional),
next: Schema.String.pipe(Schema.optional),
@ -36,7 +36,7 @@ export const MessageGroup = HttpApiGroup.make("server.message")
error: [InvalidCursorError, SessionNotFoundError, UnknownError],
}).annotateMerge(
OpenApi.annotations({
identifier: "v2.session.messages",
identifier: "v2.message.list",
summary: "Get session messages",
description:
"Retrieve projected messages for a session. Items keep the requested order across pages; use cursor.next or cursor.previous to move through the ordered timeline.",

View file

@ -107,7 +107,7 @@ export const PtyGroup = HttpApiGroup.make("server.pty")
.annotateMerge(locationQueryOpenApi)
.annotateMerge(
OpenApi.annotations({
identifier: "v2.pty.connectToken",
identifier: "v2.pty.connect.token",
summary: "Create PTY WebSocket token",
description: "Create a short-lived single-use ticket for opening a PTY WebSocket connection.",
}),

View file

@ -23,9 +23,9 @@ import {
UnknownError,
} from "../errors.js"
import { Agent } from "@opencode-ai/schema/agent"
import { Skill } from "@opencode-ai/schema/skill"
import { Model } from "@opencode-ai/schema/model"
import { Location } from "@opencode-ai/schema/location"
import { Revert } from "@opencode-ai/schema/revert"
import { SessionEvent } from "@opencode-ai/schema/session-event"
import { EventLog } from "@opencode-ai/schema/event-log"
@ -269,6 +269,25 @@ export const makeSessionGroup = <I extends HttpApiMiddleware.AnyId, S>(sessionLo
}),
),
)
.add(
HttpApiEndpoint.post("session.move", "/api/session/:sessionID/move", {
params: { sessionID: Session.ID },
payload: Schema.Struct({
destination: Schema.Struct({ directory: AbsolutePath }),
moveChanges: Schema.Boolean.pipe(Schema.optional),
}),
success: HttpApiSchema.NoContent,
error: [SessionNotFoundError, InvalidRequestError],
})
.middleware(sessionLocationMiddleware)
.annotateMerge(
OpenApi.annotations({
identifier: "v2.session.move",
summary: "Move session",
description: "Move a session to another project directory, optionally transferring local changes.",
}),
),
)
.add(
HttpApiEndpoint.post("session.prompt", "/api/session/:sessionID/prompt", {
params: { sessionID: Session.ID },
@ -297,7 +316,7 @@ export const makeSessionGroup = <I extends HttpApiMiddleware.AnyId, S>(sessionLo
id: SessionMessage.ID.pipe(Schema.optional),
command: Schema.String,
arguments: Schema.String.pipe(Schema.optional),
agent: Schema.String.pipe(Schema.optional),
agent: Agent.ID.pipe(Schema.optional),
model: Model.Ref.pipe(Schema.optional),
files: PromptInput.Prompt.fields.files,
agents: PromptInput.Prompt.fields.agents,
@ -322,7 +341,7 @@ export const makeSessionGroup = <I extends HttpApiMiddleware.AnyId, S>(sessionLo
params: { sessionID: Session.ID },
payload: Schema.Struct({
id: SessionMessage.ID.pipe(Schema.optional),
skill: Schema.String,
skill: Skill.ID,
resume: Schema.Boolean.pipe(Schema.optional),
}),
success: HttpApiSchema.NoContent,
@ -344,6 +363,7 @@ export const makeSessionGroup = <I extends HttpApiMiddleware.AnyId, S>(sessionLo
text: Schema.String,
description: Schema.String.pipe(Schema.optional),
metadata: SessionMessage.Synthetic.fields.metadata,
resume: Schema.Boolean.pipe(Schema.optional),
}),
success: HttpApiSchema.NoContent,
error: SessionNotFoundError,
@ -412,7 +432,7 @@ export const makeSessionGroup = <I extends HttpApiMiddleware.AnyId, S>(sessionLo
HttpApiEndpoint.post("session.revert.stage", "/api/session/:sessionID/revert/stage", {
params: { sessionID: Session.ID },
payload: Schema.Struct({ messageID: SessionMessage.ID, files: Schema.Boolean.pipe(Schema.optional) }),
success: Schema.Struct({ data: Revert.State }),
success: Schema.Struct({ data: Session.Revert }),
error: [MessageNotFoundError, SessionNotFoundError, SessionBusyError, UnknownError],
})
.middleware(sessionLocationMiddleware)
@ -447,7 +467,7 @@ export const makeSessionGroup = <I extends HttpApiMiddleware.AnyId, S>(sessionLo
.add(
HttpApiEndpoint.get("session.context", "/api/session/:sessionID/context", {
params: { sessionID: Session.ID },
success: Schema.Struct({ data: Schema.Array(SessionMessage.Message) }),
success: Schema.Struct({ data: Schema.Array(SessionMessage.Info) }),
error: [SessionNotFoundError, UnknownError],
})
.middleware(sessionLocationMiddleware)
@ -563,7 +583,7 @@ export const makeSessionGroup = <I extends HttpApiMiddleware.AnyId, S>(sessionLo
.add(
HttpApiEndpoint.get("session.message", "/api/session/:sessionID/message/:messageID", {
params: { sessionID: Session.ID, messageID: SessionMessage.ID },
success: Schema.Struct({ data: SessionMessage.Message }),
success: Schema.Struct({ data: SessionMessage.Info }),
error: [SessionNotFoundError, MessageNotFoundError],
})
.middleware(sessionLocationMiddleware)

View file

@ -4,5 +4,6 @@ import { isOpenCodeEvent } from "../src/groups/event.js"
test("classifies public events by type", () => {
expect(isOpenCodeEvent({ type: "server.connected" })).toBe(true)
expect(isOpenCodeEvent({ type: "mcp.status.changed" })).toBe(true)
expect(isOpenCodeEvent({ type: "mcp.resources.changed" })).toBe(true)
expect(isOpenCodeEvent({ type: "mcp.tools.changed" })).toBe(false)
})