summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--bun.lock14
-rw-r--r--packages/opencode/package.json1
-rw-r--r--packages/opencode/specs/effect/http-api.md13
-rw-r--r--packages/opencode/src/provider/auth.ts121
-rw-r--r--packages/opencode/src/server/instance/httpapi/provider.ts46
-rw-r--r--packages/opencode/src/server/instance/httpapi/server.ts7
-rw-r--r--packages/opencode/src/server/instance/provider.ts4
-rw-r--r--packages/server/package.json30
-rw-r--r--packages/server/src/api/index.ts2
-rw-r--r--packages/server/src/api/question.ts37
-rw-r--r--packages/server/src/definition/api.ts12
-rw-r--r--packages/server/src/definition/index.ts2
-rw-r--r--packages/server/src/definition/question.ts94
-rw-r--r--packages/server/src/index.ts6
-rw-r--r--packages/server/src/openapi.ts5
-rw-r--r--packages/server/src/types.ts5
-rw-r--r--packages/server/sst-env.d.ts10
-rw-r--r--packages/server/tsconfig.json15
18 files changed, 123 insertions, 301 deletions
diff --git a/bun.lock b/bun.lock
index 48243e652..705181160 100644
--- a/bun.lock
+++ b/bun.lock
@@ -358,7 +358,6 @@
"@opencode-ai/plugin": "workspace:*",
"@opencode-ai/script": "workspace:*",
"@opencode-ai/sdk": "workspace:*",
- "@opencode-ai/server": "workspace:*",
"@openrouter/ai-sdk-provider": "2.5.1",
"@opentelemetry/api": "1.9.0",
"@opentelemetry/context-async-hooks": "2.6.1",
@@ -506,17 +505,6 @@
"typescript": "catalog:",
},
},
- "packages/server": {
- "name": "@opencode-ai/server",
- "version": "1.4.6",
- "dependencies": {
- "effect": "catalog:",
- },
- "devDependencies": {
- "@typescript/native-preview": "catalog:",
- "typescript": "catalog:",
- },
- },
"packages/shared": {
"name": "@opencode-ai/shared",
"version": "1.4.6",
@@ -1568,8 +1556,6 @@
"@opencode-ai/sdk": ["@opencode-ai/sdk@workspace:packages/sdk/js"],
- "@opencode-ai/server": ["@opencode-ai/server@workspace:packages/server"],
-
"@opencode-ai/shared": ["@opencode-ai/shared@workspace:packages/shared"],
"@opencode-ai/slack": ["@opencode-ai/slack@workspace:packages/slack"],
diff --git a/packages/opencode/package.json b/packages/opencode/package.json
index 59be93d62..c0f82c149 100644
--- a/packages/opencode/package.json
+++ b/packages/opencode/package.json
@@ -115,7 +115,6 @@
"@opencode-ai/plugin": "workspace:*",
"@opencode-ai/script": "workspace:*",
"@opencode-ai/sdk": "workspace:*",
- "@opencode-ai/server": "workspace:*",
"@openrouter/ai-sdk-provider": "2.5.1",
"@opentelemetry/api": "1.9.0",
"@opentelemetry/context-async-hooks": "2.6.1",
diff --git a/packages/opencode/specs/effect/http-api.md b/packages/opencode/specs/effect/http-api.md
index 1794927cc..bd1213bb6 100644
--- a/packages/opencode/specs/effect/http-api.md
+++ b/packages/opencode/specs/effect/http-api.md
@@ -156,6 +156,14 @@ Ordering for a route-group migration:
3. move tagged route-facing errors to `Schema.TaggedErrorClass` where needed
4. switch existing Zod boundary validators to derived `.zod`
5. define the `HttpApi` contract from the canonical Effect schemas
+6. regenerate the SDK (`./packages/sdk/js/script/build.ts`) and verify zero diff against `dev`
+
+SDK shape rule:
+
+- every schema migration must preserve the generated SDK output byte-for-byte
+- `Schema.Class` emits a named `$ref` in OpenAPI via its identifier — use it only for types that already had `.meta({ ref })` in the old Zod schema
+- inner / nested types that were anonymous in the old Zod schema should stay as `Schema.Struct` (not `Schema.Class`) to avoid introducing new named components in the OpenAPI spec
+- if a diff appears in `packages/sdk/js/src/v2/gen/types.gen.ts`, the migration introduced an unintended API surface change — fix it before merging
Temporary exception:
@@ -195,8 +203,9 @@ Use the same sequence for each route group.
4. Define the `HttpApi` contract separately from the handlers.
5. Implement handlers by yielding the existing service from context.
6. Mount the new surface in parallel under an experimental prefix.
-7. Add one end-to-end test and one OpenAPI-focused test.
-8. Compare ergonomics before migrating the next endpoint.
+7. Regenerate the SDK and verify zero diff against `dev` (see SDK shape rule above).
+8. Add one end-to-end test and one OpenAPI-focused test.
+9. Compare ergonomics before migrating the next endpoint.
Rule of thumb:
diff --git a/packages/opencode/src/provider/auth.ts b/packages/opencode/src/provider/auth.ts
index c66ccffc1..0f2923a58 100644
--- a/packages/opencode/src/provider/auth.ts
+++ b/packages/opencode/src/provider/auth.ts
@@ -2,70 +2,62 @@ import type { AuthOAuthResult, Hooks } from "@opencode-ai/plugin"
import { NamedError } from "@opencode-ai/shared/util/error"
import { Auth } from "@/auth"
import { InstanceState } from "@/effect/instance-state"
+import { zod } from "@/util/effect-zod"
+import { withStatics } from "@/util/schema"
import { Plugin } from "../plugin"
import { ProviderID } from "./schema"
-import { Array as Arr, Effect, Layer, Record, Result, Context } from "effect"
+import { Array as Arr, Effect, Layer, Record, Result, Context, Schema } from "effect"
import z from "zod"
export namespace ProviderAuth {
- export const Method = z
- .object({
- type: z.union([z.literal("oauth"), z.literal("api")]),
- label: z.string(),
- prompts: z
- .array(
- z.union([
- z.object({
- type: z.literal("text"),
- key: z.string(),
- message: z.string(),
- placeholder: z.string().optional(),
- when: z
- .object({
- key: z.string(),
- op: z.union([z.literal("eq"), z.literal("neq")]),
- value: z.string(),
- })
- .optional(),
- }),
- z.object({
- type: z.literal("select"),
- key: z.string(),
- message: z.string(),
- options: z.array(
- z.object({
- label: z.string(),
- value: z.string(),
- hint: z.string().optional(),
- }),
- ),
- when: z
- .object({
- key: z.string(),
- op: z.union([z.literal("eq"), z.literal("neq")]),
- value: z.string(),
- })
- .optional(),
- }),
- ]),
- )
- .optional(),
- })
- .meta({
- ref: "ProviderAuthMethod",
- })
- export type Method = z.infer<typeof Method>
-
- export const Authorization = z
- .object({
- url: z.string(),
- method: z.union([z.literal("auto"), z.literal("code")]),
- instructions: z.string(),
- })
- .meta({
- ref: "ProviderAuthAuthorization",
- })
- export type Authorization = z.infer<typeof Authorization>
+ const When = Schema.Struct({
+ key: Schema.String,
+ op: Schema.Literals(["eq", "neq"]),
+ value: Schema.String,
+ })
+
+ const TextPrompt = Schema.Struct({
+ type: Schema.Literal("text"),
+ key: Schema.String,
+ message: Schema.String,
+ placeholder: Schema.optional(Schema.String),
+ when: Schema.optional(When),
+ })
+
+ const SelectOption = Schema.Struct({
+ label: Schema.String,
+ value: Schema.String,
+ hint: Schema.optional(Schema.String),
+ })
+
+ const SelectPrompt = Schema.Struct({
+ type: Schema.Literal("select"),
+ key: Schema.String,
+ message: Schema.String,
+ options: Schema.Array(SelectOption),
+ when: Schema.optional(When),
+ })
+
+ const Prompt = Schema.Union([TextPrompt, SelectPrompt])
+
+ export class Method extends Schema.Class<Method>("ProviderAuthMethod")({
+ type: Schema.Literals(["oauth", "api"]),
+ label: Schema.String,
+ prompts: Schema.optional(Schema.Array(Prompt)),
+ }) {
+ static readonly zod = zod(this)
+ }
+
+ export const Methods = Schema.Record(Schema.String, Schema.Array(Method)).pipe(withStatics((s) => ({ zod: zod(s) })))
+ export type Methods = typeof Methods.Type
+
+ export class Authorization extends Schema.Class<Authorization>("ProviderAuthAuthorization")({
+ url: Schema.String,
+ method: Schema.Literals(["auto", "code"]),
+ instructions: Schema.String,
+ }) {
+ static readonly zod = zod(this)
+ }
export const OauthMissing = NamedError.create("ProviderAuthOauthMissing", z.object({ providerID: ProviderID.zod }))
@@ -94,7 +86,7 @@ export namespace ProviderAuth {
type Hook = NonNullable<Hooks["auth"]>
export interface Interface {
- readonly methods: () => Effect.Effect<Record<ProviderID, Method[]>>
+ readonly methods: () => Effect.Effect<Methods>
readonly authorize: (input: {
providerID: ProviderID
method: number
@@ -131,11 +123,12 @@ export namespace ProviderAuth {
}),
)
+ const decode = Schema.decodeUnknownSync(Methods)
const methods = Effect.fn("ProviderAuth.methods")(function* () {
const hooks = (yield* InstanceState.get(state)).hooks
- return Record.map(hooks, (item) =>
- item.methods.map(
- (method): Method => ({
+ return decode(
+ Record.map(hooks, (item) =>
+ item.methods.map((method) => ({
type: method.type,
label: method.label,
prompts: method.prompts?.map((prompt) => {
@@ -156,7 +149,7 @@ export namespace ProviderAuth {
when: prompt.when,
}
}),
- }),
+ })),
),
)
})
diff --git a/packages/opencode/src/server/instance/httpapi/provider.ts b/packages/opencode/src/server/instance/httpapi/provider.ts
new file mode 100644
index 000000000..23e2d1ea7
--- /dev/null
+++ b/packages/opencode/src/server/instance/httpapi/provider.ts
@@ -0,0 +1,46 @@
+import { ProviderAuth } from "@/provider/auth"
+import { Effect, Layer } from "effect"
+import { HttpApi, HttpApiBuilder, HttpApiEndpoint, HttpApiGroup, OpenApi } from "effect/unstable/httpapi"
+
+const root = "/experimental/httpapi/provider"
+
+export const ProviderApi = HttpApi.make("provider")
+ .add(
+ HttpApiGroup.make("provider")
+ .add(
+ HttpApiEndpoint.get("auth", `${root}/auth`, {
+ success: ProviderAuth.Methods,
+ }).annotateMerge(
+ OpenApi.annotations({
+ identifier: "provider.auth",
+ summary: "Get provider auth methods",
+ description: "Retrieve available authentication methods for all AI providers.",
+ }),
+ ),
+ )
+ .annotateMerge(
+ OpenApi.annotations({
+ title: "provider",
+ description: "Experimental HttpApi provider routes.",
+ }),
+ ),
+ )
+ .annotateMerge(
+ OpenApi.annotations({
+ title: "opencode experimental HttpApi",
+ version: "0.0.1",
+ description: "Experimental HttpApi surface for selected instance routes.",
+ }),
+ )
+
+export const ProviderLive = Layer.unwrap(
+ Effect.gen(function* () {
+ const svc = yield* ProviderAuth.Service
+
+ const auth = Effect.fn("ProviderHttpApi.auth")(function* () {
+ return yield* svc.methods()
+ })
+
+ return HttpApiBuilder.group(ProviderApi, "provider", (handlers) => handlers.handle("auth", auth))
+ }),
+).pipe(Layer.provide(ProviderAuth.defaultLayer))
diff --git a/packages/opencode/src/server/instance/httpapi/server.ts b/packages/opencode/src/server/instance/httpapi/server.ts
index 54c3c57ff..9894343c5 100644
--- a/packages/opencode/src/server/instance/httpapi/server.ts
+++ b/packages/opencode/src/server/instance/httpapi/server.ts
@@ -10,8 +10,10 @@ import { InstanceBootstrap } from "@/project/bootstrap"
import { Instance } from "@/project/instance"
import { Filesystem } from "@/util/filesystem"
import { Permission } from "@/permission"
+import { ProviderAuth } from "@/provider/auth"
import { Question } from "@/question"
import { PermissionApi, PermissionLive } from "./permission"
+import { ProviderApi, ProviderLive } from "./provider"
import { QuestionApi, QuestionLive } from "./question"
const Query = Schema.Struct({
@@ -108,6 +110,7 @@ export namespace ExperimentalHttpApiServer {
const QuestionSecured = QuestionApi.middleware(Authorization)
const PermissionSecured = PermissionApi.middleware(Authorization)
+ const ProviderSecured = ProviderApi.middleware(Authorization)
export const routes = Layer.mergeAll(
HttpApiBuilder.layer(QuestionSecured, { openapiPath: "/experimental/httpapi/question/doc" }).pipe(
@@ -116,6 +119,9 @@ export namespace ExperimentalHttpApiServer {
HttpApiBuilder.layer(PermissionSecured, { openapiPath: "/experimental/httpapi/permission/doc" }).pipe(
Layer.provide(PermissionLive),
),
+ HttpApiBuilder.layer(ProviderSecured, { openapiPath: "/experimental/httpapi/provider/doc" }).pipe(
+ Layer.provide(ProviderLive),
+ ),
).pipe(Layer.provide(auth), Layer.provide(normalize), Layer.provide(instance))
export const layer = (opts: { hostname: string; port: number }) =>
@@ -127,5 +133,6 @@ export namespace ExperimentalHttpApiServer {
Layer.provideMerge(NodeHttpServer.layerTest),
Layer.provideMerge(Question.defaultLayer),
Layer.provideMerge(Permission.defaultLayer),
+ Layer.provideMerge(ProviderAuth.defaultLayer),
)
}
diff --git a/packages/opencode/src/server/instance/provider.ts b/packages/opencode/src/server/instance/provider.ts
index bbde4c955..0057218f3 100644
--- a/packages/opencode/src/server/instance/provider.ts
+++ b/packages/opencode/src/server/instance/provider.ts
@@ -82,7 +82,7 @@ export const ProviderRoutes = lazy(() =>
description: "Provider auth methods",
content: {
"application/json": {
- schema: resolver(z.record(z.string(), z.array(ProviderAuth.Method))),
+ schema: resolver(ProviderAuth.Methods.zod),
},
},
},
@@ -103,7 +103,7 @@ export const ProviderRoutes = lazy(() =>
description: "Authorization URL and method",
content: {
"application/json": {
- schema: resolver(ProviderAuth.Authorization.optional()),
+ schema: resolver(ProviderAuth.Authorization.zod.optional()),
},
},
},
diff --git a/packages/server/package.json b/packages/server/package.json
deleted file mode 100644
index 9b8b31299..000000000
--- a/packages/server/package.json
+++ /dev/null
@@ -1,30 +0,0 @@
-{
- "$schema": "https://json.schemastore.org/package.json",
- "name": "@opencode-ai/server",
- "version": "1.4.6",
- "type": "module",
- "license": "MIT",
- "exports": {
- ".": "./src/index.ts",
- "./openapi": "./src/openapi.ts",
- "./definition": "./src/definition/index.ts",
- "./definition/api": "./src/definition/api.ts",
- "./definition/question": "./src/definition/question.ts",
- "./api": "./src/api/index.ts",
- "./api/question": "./src/api/question.ts"
- },
- "files": [
- "dist"
- ],
- "scripts": {
- "typecheck": "tsgo --noEmit",
- "build": "tsc"
- },
- "devDependencies": {
- "@typescript/native-preview": "catalog:",
- "typescript": "catalog:"
- },
- "dependencies": {
- "effect": "catalog:"
- }
-}
diff --git a/packages/server/src/api/index.ts b/packages/server/src/api/index.ts
deleted file mode 100644
index 375e3584b..000000000
--- a/packages/server/src/api/index.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-export { makeQuestionHandler } from "./question.js"
-export type { QuestionOps } from "./question.js"
diff --git a/packages/server/src/api/question.ts b/packages/server/src/api/question.ts
deleted file mode 100644
index f72c37aa1..000000000
--- a/packages/server/src/api/question.ts
+++ /dev/null
@@ -1,37 +0,0 @@
-import { Effect, Schema } from "effect"
-import { HttpApiBuilder } from "effect/unstable/httpapi"
-import { QuestionReply, QuestionRequest, questionApi } from "../definition/question.js"
-
-export interface QuestionOps<R = never> {
- readonly list: () => Effect.Effect<ReadonlyArray<unknown>, never, R>
- readonly reply: (input: {
- requestID: string
- answers: Schema.Schema.Type<typeof QuestionReply>["answers"]
- }) => Effect.Effect<void, never, R>
-}
-
-export const makeQuestionHandler = <R>(ops: QuestionOps<R>) =>
- HttpApiBuilder.group(
- questionApi,
- "question",
- Effect.fn("QuestionHttpApi.handlers")(function* (handlers) {
- const decode = Schema.decodeUnknownSync(Schema.Array(QuestionRequest))
-
- const list = Effect.fn("QuestionHttpApi.list")(function* () {
- return decode(yield* ops.list())
- })
-
- const reply = Effect.fn("QuestionHttpApi.reply")(function* (ctx: {
- params: { requestID: string }
- payload: Schema.Schema.Type<typeof QuestionReply>
- }) {
- yield* ops.reply({
- requestID: ctx.params.requestID,
- answers: ctx.payload.answers,
- })
- return true
- })
-
- return handlers.handle("list", list).handle("reply", reply)
- }),
- )
diff --git a/packages/server/src/definition/api.ts b/packages/server/src/definition/api.ts
deleted file mode 100644
index e2f70196d..000000000
--- a/packages/server/src/definition/api.ts
+++ /dev/null
@@ -1,12 +0,0 @@
-import { HttpApi, OpenApi } from "effect/unstable/httpapi"
-import { questionApi } from "./question.js"
-
-export const api = HttpApi.make("opencode")
- .addHttpApi(questionApi)
- .annotateMerge(
- OpenApi.annotations({
- title: "opencode experimental HttpApi",
- version: "0.0.1",
- description: "Experimental HttpApi surface for selected instance routes.",
- }),
- )
diff --git a/packages/server/src/definition/index.ts b/packages/server/src/definition/index.ts
deleted file mode 100644
index e9a52dc93..000000000
--- a/packages/server/src/definition/index.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-export { api } from "./api.js"
-export { questionApi, QuestionReply, QuestionRequest } from "./question.js"
diff --git a/packages/server/src/definition/question.ts b/packages/server/src/definition/question.ts
deleted file mode 100644
index 0d161e013..000000000
--- a/packages/server/src/definition/question.ts
+++ /dev/null
@@ -1,94 +0,0 @@
-import { Schema } from "effect"
-import { HttpApi, HttpApiEndpoint, HttpApiGroup, OpenApi } from "effect/unstable/httpapi"
-
-const root = "/experimental/httpapi/question"
-
-// Temporary transport-local schemas until canonical question schemas move into packages/core.
-export const QuestionID = Schema.String.annotate({ identifier: "QuestionID" })
-export const SessionID = Schema.String.annotate({ identifier: "SessionID" })
-export const MessageID = Schema.String.annotate({ identifier: "MessageID" })
-
-export class QuestionOption extends Schema.Class<QuestionOption>("QuestionOption")({
- label: Schema.String.annotate({
- description: "Display text (1-5 words, concise)",
- }),
- description: Schema.String.annotate({
- description: "Explanation of choice",
- }),
-}) {}
-
-const base = {
- question: Schema.String.annotate({
- description: "Complete question",
- }),
- header: Schema.String.annotate({
- description: "Very short label (max 30 chars)",
- }),
- options: Schema.Array(QuestionOption).annotate({
- description: "Available choices",
- }),
- multiple: Schema.optional(Schema.Boolean).annotate({
- description: "Allow selecting multiple choices",
- }),
-}
-
-export class QuestionInfo extends Schema.Class<QuestionInfo>("QuestionInfo")({
- ...base,
- custom: Schema.optional(Schema.Boolean).annotate({
- description: "Allow typing a custom answer (default: true)",
- }),
-}) {}
-
-export class QuestionTool extends Schema.Class<QuestionTool>("QuestionTool")({
- messageID: MessageID,
- callID: Schema.String,
-}) {}
-
-export class QuestionRequest extends Schema.Class<QuestionRequest>("QuestionRequest")({
- id: QuestionID,
- sessionID: SessionID,
- questions: Schema.Array(QuestionInfo).annotate({
- description: "Questions to ask",
- }),
- tool: Schema.optional(QuestionTool),
-}) {}
-
-export const QuestionAnswer = Schema.Array(Schema.String).annotate({ identifier: "QuestionAnswer" })
-
-export class QuestionReply extends Schema.Class<QuestionReply>("QuestionReply")({
- answers: Schema.Array(QuestionAnswer).annotate({
- description: "User answers in order of questions (each answer is an array of selected labels)",
- }),
-}) {}
-
-export const questionApi = HttpApi.make("question").add(
- HttpApiGroup.make("question")
- .add(
- HttpApiEndpoint.get("list", root, {
- success: Schema.Array(QuestionRequest),
- }).annotateMerge(
- OpenApi.annotations({
- identifier: "question.list",
- summary: "List pending questions",
- description: "Get all pending question requests across all sessions.",
- }),
- ),
- HttpApiEndpoint.post("reply", `${root}/:requestID/reply`, {
- params: { requestID: QuestionID },
- payload: QuestionReply,
- success: Schema.Boolean,
- }).annotateMerge(
- OpenApi.annotations({
- identifier: "question.reply",
- summary: "Reply to question request",
- description: "Provide answers to a question request from the AI assistant.",
- }),
- ),
- )
- .annotateMerge(
- OpenApi.annotations({
- title: "question",
- description: "Experimental HttpApi question routes.",
- }),
- ),
-)
diff --git a/packages/server/src/index.ts b/packages/server/src/index.ts
deleted file mode 100644
index 67b82a0be..000000000
--- a/packages/server/src/index.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-export { openapi } from "./openapi.js"
-export { makeQuestionHandler } from "./api/question.js"
-export { api } from "./definition/api.js"
-export { questionApi, QuestionReply, QuestionRequest } from "./definition/question.js"
-export type { OpenApiSpec, ServerApi } from "./types.js"
-export type { QuestionOps } from "./api/question.js"
diff --git a/packages/server/src/openapi.ts b/packages/server/src/openapi.ts
deleted file mode 100644
index dda870d2b..000000000
--- a/packages/server/src/openapi.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-import { OpenApi } from "effect/unstable/httpapi"
-import { api } from "./definition/api.js"
-import type { OpenApiSpec } from "./types.js"
-
-export const openapi = (): OpenApiSpec => OpenApi.fromApi(api)
diff --git a/packages/server/src/types.ts b/packages/server/src/types.ts
deleted file mode 100644
index 9e89fe74c..000000000
--- a/packages/server/src/types.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-import type { HttpApi, HttpApiGroup, OpenApi } from "effect/unstable/httpapi"
-
-export type ServerApi = HttpApi.HttpApi<string, HttpApiGroup.Any>
-
-export type OpenApiSpec = OpenApi.OpenAPISpec
diff --git a/packages/server/sst-env.d.ts b/packages/server/sst-env.d.ts
deleted file mode 100644
index 64441936d..000000000
--- a/packages/server/sst-env.d.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-/* This file is auto-generated by SST. Do not edit. */
-/* tslint:disable */
-/* eslint-disable */
-/* deno-fmt-ignore-file */
-/* biome-ignore-all lint: auto-generated */
-
-/// <reference path="../../sst-env.d.ts" />
-
-import "sst"
-export {} \ No newline at end of file
diff --git a/packages/server/tsconfig.json b/packages/server/tsconfig.json
deleted file mode 100644
index eac2af384..000000000
--- a/packages/server/tsconfig.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- "$schema": "https://json.schemastore.org/tsconfig.json",
- "compilerOptions": {
- "target": "ES2022",
- "rootDir": "src",
- "outDir": "dist",
- "module": "nodenext",
- "declaration": true,
- "moduleResolution": "nodenext",
- "lib": ["es2022", "dom", "dom.iterable"],
- "strict": true,
- "skipLibCheck": true
- },
- "include": ["src"]
-}