soraacode 0.2.0 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/bin/soraacode.exe +10 -0
- package/package.json +17 -25
- package/{script/postinstall.mjs → postinstall.mjs} +5 -5
- package/AGENTS.md +0 -131
- package/Dockerfile +0 -18
- package/README.md +0 -15
- package/bin/opencode +0 -199
- package/bin/soraacode +0 -199
- package/bunfig.toml +0 -7
- package/git +0 -0
- package/migration/20260511173437_session-metadata/migration.sql +0 -1
- package/migration/20260511173437_session-metadata/snapshot.json +0 -1500
- package/parsers-config.ts +0 -1
- package/script/bench-search.ts +0 -94
- package/script/bench-test-suite.ts +0 -52
- package/script/build-headless.ts +0 -51
- package/script/build.ts +0 -245
- package/script/generate.ts +0 -14
- package/script/httpapi-exercise.ts +0 -1
- package/script/profile-test-files.ts +0 -42
- package/script/publish.ts +0 -213
- package/script/run-workspace-server +0 -106
- package/script/schema.ts +0 -77
- package/script/time.ts +0 -6
- package/script/trace-imports.ts +0 -153
- package/soraacode-0.1.7.tgz +0 -0
- package/specs/effect/error-boundaries-plan.md +0 -235
- package/specs/effect/errors.md +0 -207
- package/specs/effect/facades.md +0 -218
- package/specs/effect/guide.md +0 -247
- package/specs/effect/instance-context.md +0 -13
- package/specs/effect/loose-ends.md +0 -30
- package/specs/effect/migration.md +0 -62
- package/specs/effect/routes.md +0 -61
- package/specs/effect/schema.md +0 -88
- package/specs/effect/server-package.md +0 -58
- package/specs/effect/todo.md +0 -241
- package/specs/effect/tools.md +0 -88
- package/specs/openapi-translation-cleanup.md +0 -204
- package/specs/tui-plugins.md +0 -544
- package/specs/v2/api.ts +0 -67
- package/specs/v2/message-shape.md +0 -136
- package/specs/v2/notifications.md +0 -13
- package/specs/v2/tui-command-shim.md +0 -67
- package/src/account/account.ts +0 -481
- package/src/account/repo.ts +0 -171
- package/src/account/schema.ts +0 -99
- package/src/account/url.ts +0 -8
- package/src/acp/agent.ts +0 -95
- package/src/acp/config-option.ts +0 -206
- package/src/acp/content.ts +0 -269
- package/src/acp/directory.ts +0 -212
- package/src/acp/error.ts +0 -97
- package/src/acp/event.ts +0 -421
- package/src/acp/permission.ts +0 -254
- package/src/acp/profile.ts +0 -42
- package/src/acp/service.ts +0 -1226
- package/src/acp/session.ts +0 -232
- package/src/acp/tool.ts +0 -364
- package/src/acp/usage.ts +0 -243
- package/src/agent/agent.ts +0 -450
- package/src/agent/generate.txt +0 -75
- package/src/agent/prompt/compaction.txt +0 -5
- package/src/agent/prompt/explore.txt +0 -18
- package/src/agent/prompt/summary.txt +0 -11
- package/src/agent/prompt/title.txt +0 -44
- package/src/agent/subagent-permissions.ts +0 -27
- package/src/audio.d.ts +0 -14
- package/src/auth/index.ts +0 -97
- package/src/background/job.ts +0 -37
- package/src/bus/global.ts +0 -22
- package/src/cli/bootstrap.ts +0 -11
- package/src/cli/cmd/cmd.ts +0 -7
- package/src/cli/cmd/serve.ts +0 -24
- package/src/cli/effect/prompt.ts +0 -37
- package/src/cli/effect-cmd.ts +0 -96
- package/src/cli/error.ts +0 -130
- package/src/cli/heap.ts +0 -45
- package/src/cli/logo.ts +0 -2
- package/src/cli/network.ts +0 -80
- package/src/cli/ui.ts +0 -132
- package/src/command/index.ts +0 -177
- package/src/command/template/initialize.txt +0 -66
- package/src/command/template/review.txt +0 -101
- package/src/config/agent.ts +0 -59
- package/src/config/command.ts +0 -39
- package/src/config/config.ts +0 -707
- package/src/config/entry-name.ts +0 -19
- package/src/config/managed.ts +0 -69
- package/src/config/markdown.ts +0 -36
- package/src/config/parse.ts +0 -61
- package/src/config/paths.ts +0 -45
- package/src/config/plugin.ts +0 -79
- package/src/config/v2-compat.ts +0 -449
- package/src/config/variable.ts +0 -91
- package/src/control-plane/adapters/index.ts +0 -41
- package/src/control-plane/adapters/worktree.ts +0 -96
- package/src/control-plane/dev/README.md +0 -19
- package/src/control-plane/dev/debug-workspace-plugin.ts +0 -73
- package/src/control-plane/types.ts +0 -59
- package/src/control-plane/util.ts +0 -39
- package/src/control-plane/workspace-adapter-runtime.ts +0 -51
- package/src/control-plane/workspace-context.ts +0 -26
- package/src/control-plane/workspace.ts +0 -966
- package/src/effect/app-node-builder-v1.ts +0 -12
- package/src/effect/app-runtime.ts +0 -135
- package/src/effect/bootstrap-runtime.ts +0 -19
- package/src/effect/bridge.ts +0 -84
- package/src/effect/config-service.ts +0 -67
- package/src/effect/instance-ref.ts +0 -11
- package/src/effect/instance-registry.ts +0 -12
- package/src/effect/instance-state.ts +0 -69
- package/src/effect/promise.ts +0 -17
- package/src/effect/run-service.ts +0 -47
- package/src/effect/runner.ts +0 -217
- package/src/effect/runtime-flags.ts +0 -78
- package/src/env/index.ts +0 -41
- package/src/event-manifest.ts +0 -3
- package/src/event-v2-bridge.ts +0 -71
- package/src/format/formatter.ts +0 -404
- package/src/format/index.ts +0 -203
- package/src/git/index.ts +0 -348
- package/src/id/id.ts +0 -80
- package/src/ide/index.ts +0 -54
- package/src/image/image.ts +0 -172
- package/src/index-headless.ts +0 -89
- package/src/index.ts +0 -93
- package/src/installation/index.ts +0 -336
- package/src/lsp/client.ts +0 -650
- package/src/lsp/diagnostic.ts +0 -29
- package/src/lsp/language.ts +0 -121
- package/src/lsp/launch.ts +0 -21
- package/src/lsp/lsp.ts +0 -507
- package/src/lsp/server.ts +0 -1983
- package/src/markdown.d.ts +0 -4
- package/src/mcp/auth.ts +0 -163
- package/src/mcp/browser.ts +0 -37
- package/src/mcp/catalog.ts +0 -170
- package/src/mcp/index.ts +0 -1004
- package/src/mcp/oauth-callback.ts +0 -194
- package/src/mcp/oauth-provider.ts +0 -259
- package/src/node.ts +0 -4
- package/src/patch/index.ts +0 -686
- package/src/permission/arity.ts +0 -163
- package/src/permission/evaluate.ts +0 -1
- package/src/permission/index.ts +0 -223
- package/src/plugin/github-copilot/copilot.ts +0 -415
- package/src/plugin/github-copilot/models.ts +0 -261
- package/src/plugin/index.ts +0 -298
- package/src/plugin/install.ts +0 -439
- package/src/plugin/loader.ts +0 -237
- package/src/plugin/meta.ts +0 -188
- package/src/plugin/openai/README.md +0 -31
- package/src/plugin/openai/codex.ts +0 -575
- package/src/plugin/openai/ws-pool.ts +0 -271
- package/src/plugin/openai/ws.ts +0 -383
- package/src/plugin/pty-environment.ts +0 -24
- package/src/plugin/shared.ts +0 -323
- package/src/project/bootstrap-service.ts +0 -9
- package/src/project/bootstrap.ts +0 -58
- package/src/project/instance-context.ts +0 -24
- package/src/project/instance-runtime.ts +0 -16
- package/src/project/instance-store.ts +0 -213
- package/src/project/project.ts +0 -483
- package/src/project/vcs.ts +0 -423
- package/src/provider/auth.ts +0 -229
- package/src/provider/error.ts +0 -195
- package/src/provider/model-status.ts +0 -8
- package/src/provider/provider.ts +0 -1955
- package/src/provider/transform.ts +0 -1923
- package/src/question/index.ts +0 -161
- package/src/question/schema.ts +0 -4
- package/src/server/auth.ts +0 -48
- package/src/server/event.ts +0 -10
- package/src/server/global-lifecycle.ts +0 -28
- package/src/server/mdns.ts +0 -47
- package/src/server/proxy-util.ts +0 -48
- package/src/server/routes/instance/httpapi/AGENTS.md +0 -39
- package/src/server/routes/instance/httpapi/api.ts +0 -97
- package/src/server/routes/instance/httpapi/errors.ts +0 -193
- package/src/server/routes/instance/httpapi/groups/config.ts +0 -65
- package/src/server/routes/instance/httpapi/groups/control-plane.ts +0 -35
- package/src/server/routes/instance/httpapi/groups/control.ts +0 -76
- package/src/server/routes/instance/httpapi/groups/event.ts +0 -29
- package/src/server/routes/instance/httpapi/groups/experimental.ts +0 -275
- package/src/server/routes/instance/httpapi/groups/file.ts +0 -185
- package/src/server/routes/instance/httpapi/groups/global.ts +0 -139
- package/src/server/routes/instance/httpapi/groups/instance.ts +0 -206
- package/src/server/routes/instance/httpapi/groups/mcp.ts +0 -156
- package/src/server/routes/instance/httpapi/groups/metadata.ts +0 -18
- package/src/server/routes/instance/httpapi/groups/permission.ts +0 -61
- package/src/server/routes/instance/httpapi/groups/project-copy.ts +0 -32
- package/src/server/routes/instance/httpapi/groups/project.ts +0 -93
- package/src/server/routes/instance/httpapi/groups/provider.ts +0 -101
- package/src/server/routes/instance/httpapi/groups/pty.ts +0 -172
- package/src/server/routes/instance/httpapi/groups/query.ts +0 -12
- package/src/server/routes/instance/httpapi/groups/question.ts +0 -74
- package/src/server/routes/instance/httpapi/groups/session.ts +0 -462
- package/src/server/routes/instance/httpapi/groups/sync.ts +0 -113
- package/src/server/routes/instance/httpapi/groups/tui.ts +0 -208
- package/src/server/routes/instance/httpapi/groups/workspace.ts +0 -141
- package/src/server/routes/instance/httpapi/handlers/config.ts +0 -34
- package/src/server/routes/instance/httpapi/handlers/control-plane.ts +0 -37
- package/src/server/routes/instance/httpapi/handlers/control.ts +0 -43
- package/src/server/routes/instance/httpapi/handlers/event.ts +0 -99
- package/src/server/routes/instance/httpapi/handlers/experimental.ts +0 -193
- package/src/server/routes/instance/httpapi/handlers/file.ts +0 -139
- package/src/server/routes/instance/httpapi/handlers/global.ts +0 -126
- package/src/server/routes/instance/httpapi/handlers/instance.ts +0 -110
- package/src/server/routes/instance/httpapi/handlers/mcp.ts +0 -111
- package/src/server/routes/instance/httpapi/handlers/permission.ts +0 -41
- package/src/server/routes/instance/httpapi/handlers/project-copy.ts +0 -83
- package/src/server/routes/instance/httpapi/handlers/project.ts +0 -63
- package/src/server/routes/instance/httpapi/handlers/provider.ts +0 -116
- package/src/server/routes/instance/httpapi/handlers/pty.ts +0 -273
- package/src/server/routes/instance/httpapi/handlers/question.ts +0 -54
- package/src/server/routes/instance/httpapi/handlers/session-errors.ts +0 -21
- package/src/server/routes/instance/httpapi/handlers/session.ts +0 -442
- package/src/server/routes/instance/httpapi/handlers/sync.ts +0 -89
- package/src/server/routes/instance/httpapi/handlers/tui.ts +0 -131
- package/src/server/routes/instance/httpapi/handlers/workspace.ts +0 -102
- package/src/server/routes/instance/httpapi/lifecycle.ts +0 -54
- package/src/server/routes/instance/httpapi/middleware/authorization.ts +0 -150
- package/src/server/routes/instance/httpapi/middleware/compression.ts +0 -64
- package/src/server/routes/instance/httpapi/middleware/cors-vary.ts +0 -29
- package/src/server/routes/instance/httpapi/middleware/error.ts +0 -44
- package/src/server/routes/instance/httpapi/middleware/fence.ts +0 -25
- package/src/server/routes/instance/httpapi/middleware/instance-context.ts +0 -43
- package/src/server/routes/instance/httpapi/middleware/proxy.ts +0 -131
- package/src/server/routes/instance/httpapi/middleware/schema-error.ts +0 -41
- package/src/server/routes/instance/httpapi/middleware/workspace-routing.ts +0 -250
- package/src/server/routes/instance/httpapi/public.ts +0 -537
- package/src/server/routes/instance/httpapi/server.ts +0 -325
- package/src/server/routes/instance/httpapi/websocket-tracker.ts +0 -60
- package/src/server/server.ts +0 -224
- package/src/server/shared/fence.ts +0 -60
- package/src/server/shared/pty-ticket.ts +0 -15
- package/src/server/shared/public-ui.ts +0 -12
- package/src/server/shared/tui-control.ts +0 -28
- package/src/server/shared/ui.ts +0 -108
- package/src/server/shared/workspace-routing.ts +0 -45
- package/src/server/tui-event.ts +0 -1
- package/src/session/compaction.ts +0 -608
- package/src/session/instruction.ts +0 -237
- package/src/session/llm/AGENTS.md +0 -90
- package/src/session/llm/ai-sdk.ts +0 -291
- package/src/session/llm/native-request.ts +0 -196
- package/src/session/llm/native-runtime.ts +0 -195
- package/src/session/llm/request.ts +0 -226
- package/src/session/llm.ts +0 -390
- package/src/session/message-error.ts +0 -14
- package/src/session/message-v2.ts +0 -742
- package/src/session/message.ts +0 -148
- package/src/session/overflow.ts +0 -34
- package/src/session/processor.ts +0 -732
- package/src/session/prompt/build-switch.txt +0 -5
- package/src/session/prompt/default.txt +0 -35
- package/src/session/prompt/plan-mode.txt +0 -70
- package/src/session/prompt/plan.txt +0 -26
- package/src/session/prompt.ts +0 -1631
- package/src/session/reminders.ts +0 -92
- package/src/session/retry.ts +0 -209
- package/src/session/revert.ts +0 -136
- package/src/session/run-state.ts +0 -151
- package/src/session/schema.ts +0 -26
- package/src/session/session.ts +0 -1016
- package/src/session/status.ts +0 -56
- package/src/session/summary.ts +0 -160
- package/src/session/system.ts +0 -123
- package/src/session/todo.ts +0 -74
- package/src/session/tools.ts +0 -590
- package/src/share/session.ts +0 -58
- package/src/share/share-next.ts +0 -371
- package/src/skill/discovery.ts +0 -140
- package/src/skill/index.ts +0 -354
- package/src/snapshot/index.ts +0 -807
- package/src/sql.d.ts +0 -4
- package/src/storage/schema.ts +0 -5
- package/src/storage/storage.ts +0 -327
- package/src/sync/README.md +0 -179
- package/src/sync/schema.ts +0 -11
- package/src/temporary.ts +0 -31
- package/src/tool/apply_patch.ts +0 -313
- package/src/tool/apply_patch.txt +0 -14
- package/src/tool/code-mode.ts +0 -310
- package/src/tool/edit.ts +0 -737
- package/src/tool/edit.txt +0 -13
- package/src/tool/external-directory.ts +0 -49
- package/src/tool/glob.ts +0 -76
- package/src/tool/glob.txt +0 -7
- package/src/tool/grep.ts +0 -115
- package/src/tool/grep.txt +0 -7
- package/src/tool/invalid.ts +0 -21
- package/src/tool/json-schema.ts +0 -164
- package/src/tool/lsp.ts +0 -113
- package/src/tool/lsp.txt +0 -1
- package/src/tool/mcp-websearch.ts +0 -96
- package/src/tool/plan-enter.txt +0 -1
- package/src/tool/plan-exit.txt +0 -1
- package/src/tool/plan.ts +0 -79
- package/src/tool/question.ts +0 -44
- package/src/tool/question.txt +0 -1
- package/src/tool/read.ts +0 -386
- package/src/tool/read.txt +0 -13
- package/src/tool/registry.ts +0 -455
- package/src/tool/schema.ts +0 -14
- package/src/tool/shell/id.ts +0 -19
- package/src/tool/shell/prompt.ts +0 -293
- package/src/tool/shell/shell.txt +0 -21
- package/src/tool/shell.ts +0 -645
- package/src/tool/skill.ts +0 -70
- package/src/tool/skill.txt +0 -1
- package/src/tool/task.ts +0 -371
- package/src/tool/task.txt +0 -11
- package/src/tool/todo.ts +0 -46
- package/src/tool/todowrite.txt +0 -11
- package/src/tool/tool.ts +0 -183
- package/src/tool/truncate.ts +0 -156
- package/src/tool/truncation-dir.ts +0 -4
- package/src/tool/webfetch.ts +0 -192
- package/src/tool/webfetch.txt +0 -9
- package/src/tool/websearch.ts +0 -143
- package/src/tool/websearch.txt +0 -9
- package/src/tool/write.ts +0 -104
- package/src/tool/write.txt +0 -11
- package/src/util/archive.ts +0 -17
- package/src/util/bom.ts +0 -27
- package/src/util/data-url.ts +0 -9
- package/src/util/defer.ts +0 -10
- package/src/util/effect-http-client.ts +0 -11
- package/src/util/error.ts +0 -16
- package/src/util/filesystem.ts +0 -251
- package/src/util/html.ts +0 -8
- package/src/util/iife.ts +0 -3
- package/src/util/lazy.ts +0 -20
- package/src/util/local-context.ts +0 -25
- package/src/util/locale.ts +0 -4
- package/src/util/media.ts +0 -26
- package/src/util/process.ts +0 -177
- package/src/util/proxy-env.ts +0 -72
- package/src/util/queue.ts +0 -32
- package/src/util/record.ts +0 -3
- package/src/util/repository.ts +0 -232
- package/src/util/rpc.ts +0 -66
- package/src/util/signal.ts +0 -12
- package/src/util/timeout.ts +0 -13
- package/src/util/token.ts +0 -1
- package/src/util/wildcard.ts +0 -59
- package/src/worktree/index.ts +0 -623
- package/sst-env.d.ts +0 -10
- package/tsconfig.headless.json +0 -13
- package/tsconfig.json +0 -16
package/src/account/repo.ts
DELETED
|
@@ -1,171 +0,0 @@
|
|
|
1
|
-
import { LayerNode } from "@soraacode/core/effect/layer-node"
|
|
2
|
-
import { eq } from "drizzle-orm"
|
|
3
|
-
import { serviceUse } from "@soraacode/core/effect/service-use"
|
|
4
|
-
import { Effect, Layer, Option, Schema, Context } from "effect"
|
|
5
|
-
|
|
6
|
-
import { Database } from "@soraacode/core/database/database"
|
|
7
|
-
import { AccountStateTable, AccountTable } from "@soraacode/core/account/sql"
|
|
8
|
-
import { AccessToken, AccountID, AccountRepoError, Info, OrgID, RefreshToken } from "./schema"
|
|
9
|
-
import { normalizeServerUrl } from "./url"
|
|
10
|
-
|
|
11
|
-
export type AccountRow = (typeof AccountTable)["$inferSelect"]
|
|
12
|
-
|
|
13
|
-
const ACCOUNT_STATE_ID = 1
|
|
14
|
-
|
|
15
|
-
export interface Interface {
|
|
16
|
-
readonly active: () => Effect.Effect<Option.Option<Info>, AccountRepoError>
|
|
17
|
-
readonly list: () => Effect.Effect<Info[], AccountRepoError>
|
|
18
|
-
readonly remove: (accountID: AccountID) => Effect.Effect<void, AccountRepoError>
|
|
19
|
-
readonly use: (accountID: AccountID, orgID: Option.Option<OrgID>) => Effect.Effect<void, AccountRepoError>
|
|
20
|
-
readonly getRow: (accountID: AccountID) => Effect.Effect<Option.Option<AccountRow>, AccountRepoError>
|
|
21
|
-
readonly persistToken: (input: {
|
|
22
|
-
accountID: AccountID
|
|
23
|
-
accessToken: AccessToken
|
|
24
|
-
refreshToken: RefreshToken
|
|
25
|
-
expiry: Option.Option<number>
|
|
26
|
-
}) => Effect.Effect<void, AccountRepoError>
|
|
27
|
-
readonly persistAccount: (input: {
|
|
28
|
-
id: AccountID
|
|
29
|
-
email: string
|
|
30
|
-
url: string
|
|
31
|
-
accessToken: AccessToken
|
|
32
|
-
refreshToken: RefreshToken
|
|
33
|
-
expiry: number
|
|
34
|
-
orgID: Option.Option<OrgID>
|
|
35
|
-
}) => Effect.Effect<void, AccountRepoError>
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
export class Service extends Context.Service<Service, Interface>()("@opencode/AccountRepo") {}
|
|
39
|
-
|
|
40
|
-
export const use = serviceUse(Service)
|
|
41
|
-
|
|
42
|
-
const layer = Layer.effect(
|
|
43
|
-
Service,
|
|
44
|
-
Effect.gen(function* () {
|
|
45
|
-
const { db } = yield* Database.Service
|
|
46
|
-
const decode = Schema.decodeUnknownSync(Info)
|
|
47
|
-
|
|
48
|
-
const query = <A, E>(effect: Effect.Effect<A, E>) =>
|
|
49
|
-
effect.pipe(Effect.mapError((cause) => new AccountRepoError({ message: "Database operation failed", cause })))
|
|
50
|
-
|
|
51
|
-
const current = Effect.fnUntraced(function* () {
|
|
52
|
-
const state = yield* db.select().from(AccountStateTable).where(eq(AccountStateTable.id, ACCOUNT_STATE_ID)).get()
|
|
53
|
-
if (!state?.active_account_id) return
|
|
54
|
-
const account = yield* db.select().from(AccountTable).where(eq(AccountTable.id, state.active_account_id)).get()
|
|
55
|
-
if (!account) return
|
|
56
|
-
return { ...account, active_org_id: state.active_org_id ?? null }
|
|
57
|
-
})
|
|
58
|
-
|
|
59
|
-
const state = (accountID: AccountID, orgID: Option.Option<OrgID>) => {
|
|
60
|
-
const id = Option.getOrNull(orgID)
|
|
61
|
-
return db
|
|
62
|
-
.insert(AccountStateTable)
|
|
63
|
-
.values({ id: ACCOUNT_STATE_ID, active_account_id: accountID, active_org_id: id })
|
|
64
|
-
.onConflictDoUpdate({
|
|
65
|
-
target: AccountStateTable.id,
|
|
66
|
-
set: { active_account_id: accountID, active_org_id: id },
|
|
67
|
-
})
|
|
68
|
-
.run()
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
const active = Effect.fn("AccountRepo.active")(() =>
|
|
72
|
-
query(current()).pipe(Effect.map((row) => (row ? Option.some(decode(row)) : Option.none()))),
|
|
73
|
-
)
|
|
74
|
-
|
|
75
|
-
const list = Effect.fn("AccountRepo.list")(() =>
|
|
76
|
-
query(
|
|
77
|
-
db
|
|
78
|
-
.select()
|
|
79
|
-
.from(AccountTable)
|
|
80
|
-
.all()
|
|
81
|
-
.pipe(Effect.map((rows) => rows.map((row: AccountRow) => decode({ ...row, active_org_id: null })))),
|
|
82
|
-
),
|
|
83
|
-
)
|
|
84
|
-
|
|
85
|
-
const remove = Effect.fn("AccountRepo.remove")((accountID: AccountID) =>
|
|
86
|
-
query(
|
|
87
|
-
db.transaction((tx) =>
|
|
88
|
-
Effect.gen(function* () {
|
|
89
|
-
yield* tx
|
|
90
|
-
.update(AccountStateTable)
|
|
91
|
-
.set({ active_account_id: null, active_org_id: null })
|
|
92
|
-
.where(eq(AccountStateTable.active_account_id, accountID))
|
|
93
|
-
.run()
|
|
94
|
-
yield* tx.delete(AccountTable).where(eq(AccountTable.id, accountID)).run()
|
|
95
|
-
}),
|
|
96
|
-
),
|
|
97
|
-
).pipe(Effect.asVoid),
|
|
98
|
-
)
|
|
99
|
-
|
|
100
|
-
const use = Effect.fn("AccountRepo.use")((accountID: AccountID, orgID: Option.Option<OrgID>) =>
|
|
101
|
-
query(state(accountID, orgID)).pipe(Effect.asVoid),
|
|
102
|
-
)
|
|
103
|
-
|
|
104
|
-
const getRow = Effect.fn("AccountRepo.getRow")((accountID: AccountID) =>
|
|
105
|
-
query(db.select().from(AccountTable).where(eq(AccountTable.id, accountID)).get()).pipe(
|
|
106
|
-
Effect.map(Option.fromNullishOr),
|
|
107
|
-
),
|
|
108
|
-
)
|
|
109
|
-
|
|
110
|
-
const persistToken = Effect.fn("AccountRepo.persistToken")((input) =>
|
|
111
|
-
query(
|
|
112
|
-
db
|
|
113
|
-
.update(AccountTable)
|
|
114
|
-
.set({
|
|
115
|
-
access_token: input.accessToken,
|
|
116
|
-
refresh_token: input.refreshToken,
|
|
117
|
-
token_expiry: Option.getOrNull(input.expiry),
|
|
118
|
-
})
|
|
119
|
-
.where(eq(AccountTable.id, input.accountID))
|
|
120
|
-
.run(),
|
|
121
|
-
).pipe(Effect.asVoid),
|
|
122
|
-
)
|
|
123
|
-
|
|
124
|
-
const persistAccount = Effect.fn("AccountRepo.persistAccount")((input) =>
|
|
125
|
-
query(
|
|
126
|
-
db.transaction((tx) =>
|
|
127
|
-
Effect.gen(function* () {
|
|
128
|
-
const url = normalizeServerUrl(input.url)
|
|
129
|
-
|
|
130
|
-
yield* tx
|
|
131
|
-
.insert(AccountTable)
|
|
132
|
-
.values({
|
|
133
|
-
id: input.id,
|
|
134
|
-
email: input.email,
|
|
135
|
-
url,
|
|
136
|
-
access_token: input.accessToken,
|
|
137
|
-
refresh_token: input.refreshToken,
|
|
138
|
-
token_expiry: input.expiry,
|
|
139
|
-
})
|
|
140
|
-
.onConflictDoUpdate({
|
|
141
|
-
target: AccountTable.id,
|
|
142
|
-
set: {
|
|
143
|
-
email: input.email,
|
|
144
|
-
url,
|
|
145
|
-
access_token: input.accessToken,
|
|
146
|
-
refresh_token: input.refreshToken,
|
|
147
|
-
token_expiry: input.expiry,
|
|
148
|
-
},
|
|
149
|
-
})
|
|
150
|
-
.run()
|
|
151
|
-
yield* state(input.id, input.orgID)
|
|
152
|
-
}),
|
|
153
|
-
),
|
|
154
|
-
).pipe(Effect.asVoid),
|
|
155
|
-
)
|
|
156
|
-
|
|
157
|
-
return Service.of({
|
|
158
|
-
active,
|
|
159
|
-
list,
|
|
160
|
-
remove,
|
|
161
|
-
use,
|
|
162
|
-
getRow,
|
|
163
|
-
persistToken,
|
|
164
|
-
persistAccount,
|
|
165
|
-
})
|
|
166
|
-
}),
|
|
167
|
-
)
|
|
168
|
-
|
|
169
|
-
export const node = LayerNode.make({ service: Service, layer: layer, deps: [Database.node] })
|
|
170
|
-
|
|
171
|
-
export * as AccountRepo from "./repo"
|
package/src/account/schema.ts
DELETED
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
import { Schema } from "effect"
|
|
2
|
-
import type * as HttpClientError from "effect/unstable/http/HttpClientError"
|
|
3
|
-
|
|
4
|
-
export const AccountID = Schema.String.pipe(Schema.brand("AccountID"))
|
|
5
|
-
export type AccountID = Schema.Schema.Type<typeof AccountID>
|
|
6
|
-
|
|
7
|
-
export const OrgID = Schema.String.pipe(Schema.brand("OrgID"))
|
|
8
|
-
export type OrgID = Schema.Schema.Type<typeof OrgID>
|
|
9
|
-
|
|
10
|
-
export const AccessToken = Schema.String.pipe(Schema.brand("AccessToken"))
|
|
11
|
-
export type AccessToken = Schema.Schema.Type<typeof AccessToken>
|
|
12
|
-
|
|
13
|
-
export const RefreshToken = Schema.String.pipe(Schema.brand("RefreshToken"))
|
|
14
|
-
export type RefreshToken = Schema.Schema.Type<typeof RefreshToken>
|
|
15
|
-
|
|
16
|
-
export const DeviceCode = Schema.String.pipe(Schema.brand("DeviceCode"))
|
|
17
|
-
export type DeviceCode = Schema.Schema.Type<typeof DeviceCode>
|
|
18
|
-
|
|
19
|
-
export const UserCode = Schema.String.pipe(Schema.brand("UserCode"))
|
|
20
|
-
export type UserCode = Schema.Schema.Type<typeof UserCode>
|
|
21
|
-
|
|
22
|
-
export class Info extends Schema.Class<Info>("Account")({
|
|
23
|
-
id: AccountID,
|
|
24
|
-
email: Schema.String,
|
|
25
|
-
url: Schema.String,
|
|
26
|
-
active_org_id: Schema.NullOr(OrgID),
|
|
27
|
-
}) {}
|
|
28
|
-
|
|
29
|
-
export class Org extends Schema.Class<Org>("Org")({
|
|
30
|
-
id: OrgID,
|
|
31
|
-
name: Schema.String,
|
|
32
|
-
}) {}
|
|
33
|
-
|
|
34
|
-
export class AccountRepoError extends Schema.TaggedErrorClass<AccountRepoError>()("AccountRepoError", {
|
|
35
|
-
message: Schema.String,
|
|
36
|
-
cause: Schema.optional(Schema.Defect()),
|
|
37
|
-
}) {}
|
|
38
|
-
|
|
39
|
-
export class AccountServiceError extends Schema.TaggedErrorClass<AccountServiceError>()("AccountServiceError", {
|
|
40
|
-
message: Schema.String,
|
|
41
|
-
cause: Schema.optional(Schema.Defect()),
|
|
42
|
-
}) {}
|
|
43
|
-
|
|
44
|
-
export class AccountTransportError extends Schema.TaggedErrorClass<AccountTransportError>()("AccountTransportError", {
|
|
45
|
-
method: Schema.String,
|
|
46
|
-
url: Schema.String,
|
|
47
|
-
description: Schema.optional(Schema.String),
|
|
48
|
-
cause: Schema.optional(Schema.Defect()),
|
|
49
|
-
}) {
|
|
50
|
-
static fromHttpClientError(error: HttpClientError.TransportError): AccountTransportError {
|
|
51
|
-
return new AccountTransportError({
|
|
52
|
-
method: error.request.method,
|
|
53
|
-
url: error.request.url,
|
|
54
|
-
description: error.description,
|
|
55
|
-
cause: error.cause,
|
|
56
|
-
})
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
override get message(): string {
|
|
60
|
-
return [
|
|
61
|
-
`Could not reach ${this.method} ${this.url}.`,
|
|
62
|
-
`This failed before the server returned an HTTP response.`,
|
|
63
|
-
this.description,
|
|
64
|
-
`Check your network, proxy, or VPN configuration and try again.`,
|
|
65
|
-
]
|
|
66
|
-
.filter(Boolean)
|
|
67
|
-
.join("\n")
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
export type AccountError = AccountRepoError | AccountServiceError | AccountTransportError
|
|
72
|
-
|
|
73
|
-
export class Login extends Schema.Class<Login>("Login")({
|
|
74
|
-
code: DeviceCode,
|
|
75
|
-
user: UserCode,
|
|
76
|
-
url: Schema.String,
|
|
77
|
-
server: Schema.String,
|
|
78
|
-
expiry: Schema.Duration,
|
|
79
|
-
interval: Schema.Duration,
|
|
80
|
-
}) {}
|
|
81
|
-
|
|
82
|
-
export class PollSuccess extends Schema.TaggedClass<PollSuccess>()("PollSuccess", {
|
|
83
|
-
email: Schema.String,
|
|
84
|
-
}) {}
|
|
85
|
-
|
|
86
|
-
export class PollPending extends Schema.TaggedClass<PollPending>()("PollPending", {}) {}
|
|
87
|
-
|
|
88
|
-
export class PollSlow extends Schema.TaggedClass<PollSlow>()("PollSlow", {}) {}
|
|
89
|
-
|
|
90
|
-
export class PollExpired extends Schema.TaggedClass<PollExpired>()("PollExpired", {}) {}
|
|
91
|
-
|
|
92
|
-
export class PollDenied extends Schema.TaggedClass<PollDenied>()("PollDenied", {}) {}
|
|
93
|
-
|
|
94
|
-
export class PollError extends Schema.TaggedClass<PollError>()("PollError", {
|
|
95
|
-
cause: Schema.Defect(),
|
|
96
|
-
}) {}
|
|
97
|
-
|
|
98
|
-
export const PollResult = Schema.Union([PollSuccess, PollPending, PollSlow, PollExpired, PollDenied, PollError])
|
|
99
|
-
export type PollResult = Schema.Schema.Type<typeof PollResult>
|
package/src/account/url.ts
DELETED
package/src/acp/agent.ts
DELETED
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
RequestError,
|
|
3
|
-
type Agent as ACPAgent,
|
|
4
|
-
type AgentSideConnection,
|
|
5
|
-
type AuthenticateRequest,
|
|
6
|
-
type CancelNotification,
|
|
7
|
-
type CloseSessionRequest,
|
|
8
|
-
type ForkSessionRequest,
|
|
9
|
-
type InitializeRequest,
|
|
10
|
-
type ListSessionsRequest,
|
|
11
|
-
type LoadSessionRequest,
|
|
12
|
-
type NewSessionRequest,
|
|
13
|
-
type PromptRequest,
|
|
14
|
-
type ResumeSessionRequest,
|
|
15
|
-
type SetSessionConfigOptionRequest,
|
|
16
|
-
type SetSessionModelRequest,
|
|
17
|
-
type SetSessionModeRequest,
|
|
18
|
-
} from "@agentclientprotocol/sdk"
|
|
19
|
-
import { Effect } from "effect"
|
|
20
|
-
import type { OpencodeClient } from "@soraacode/sdk/v2"
|
|
21
|
-
import * as ACPError from "./error"
|
|
22
|
-
import * as ACPService from "./service"
|
|
23
|
-
|
|
24
|
-
export function init({ sdk: _sdk }: { sdk: OpencodeClient }) {
|
|
25
|
-
return {
|
|
26
|
-
create: (connection: AgentSideConnection) => {
|
|
27
|
-
return new Agent(ACPService.make({ sdk: _sdk, connection }))
|
|
28
|
-
},
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
export class Agent implements ACPAgent {
|
|
33
|
-
constructor(private readonly service: ACPService.Interface) {}
|
|
34
|
-
|
|
35
|
-
initialize(params: InitializeRequest) {
|
|
36
|
-
return run(this.service.initialize(params))
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
authenticate(params: AuthenticateRequest) {
|
|
40
|
-
return run(this.service.authenticate(params))
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
newSession(params: NewSessionRequest) {
|
|
44
|
-
return run(this.service.newSession(params))
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
loadSession(params: LoadSessionRequest) {
|
|
48
|
-
return run(this.service.loadSession(params))
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
listSessions(params: ListSessionsRequest) {
|
|
52
|
-
return run(this.service.listSessions(params))
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
resumeSession(params: ResumeSessionRequest) {
|
|
56
|
-
return run(this.service.resumeSession(params))
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
closeSession(params: CloseSessionRequest) {
|
|
60
|
-
return run(this.service.closeSession(params))
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
unstable_forkSession(params: ForkSessionRequest) {
|
|
64
|
-
return run(this.service.forkSession(params))
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
setSessionConfigOption(params: SetSessionConfigOptionRequest) {
|
|
68
|
-
return run(this.service.setSessionConfigOption(params))
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
setSessionMode(params: SetSessionModeRequest) {
|
|
72
|
-
return run(this.service.setSessionMode(params))
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
unstable_setSessionModel(params: SetSessionModelRequest) {
|
|
76
|
-
return run(this.service.setSessionModel(params))
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
prompt(params: PromptRequest) {
|
|
80
|
-
return run(this.service.prompt(params))
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
cancel(params: CancelNotification) {
|
|
84
|
-
return run(this.service.cancel(params))
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
function run<A>(effect: Effect.Effect<A, ACPService.Error>) {
|
|
89
|
-
return Effect.runPromise(effect.pipe(Effect.mapError(ACPError.toRequestError))).catch((defect: unknown) => {
|
|
90
|
-
if (defect instanceof RequestError) throw defect
|
|
91
|
-
throw ACPError.toRequestError(ACPError.fromUnknownDefect(defect))
|
|
92
|
-
})
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
export * as ACP from "./agent"
|
package/src/acp/config-option.ts
DELETED
|
@@ -1,206 +0,0 @@
|
|
|
1
|
-
import type { SessionConfigOption } from "@agentclientprotocol/sdk"
|
|
2
|
-
|
|
3
|
-
export const DEFAULT_VARIANT_VALUE = "default"
|
|
4
|
-
|
|
5
|
-
export type ConfigOptionModel = {
|
|
6
|
-
id: string
|
|
7
|
-
name: string
|
|
8
|
-
variants?: Record<string, Record<string, unknown>>
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export type ConfigOptionProvider = {
|
|
12
|
-
id: string
|
|
13
|
-
name: string
|
|
14
|
-
models: Record<string, ConfigOptionModel>
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export type ConfigOptionMode = {
|
|
18
|
-
id: string
|
|
19
|
-
name: string
|
|
20
|
-
description?: string
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export type ModelSelection = {
|
|
24
|
-
model: {
|
|
25
|
-
providerID: string
|
|
26
|
-
modelID: string
|
|
27
|
-
}
|
|
28
|
-
variant?: string
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export function buildModelSelectOption(input: {
|
|
32
|
-
providers: readonly ConfigOptionProvider[]
|
|
33
|
-
currentModel: ModelSelection["model"]
|
|
34
|
-
currentVariant?: string
|
|
35
|
-
includeVariants?: boolean
|
|
36
|
-
}): SessionConfigOption {
|
|
37
|
-
return {
|
|
38
|
-
id: "model",
|
|
39
|
-
name: "Model",
|
|
40
|
-
category: "model",
|
|
41
|
-
type: "select",
|
|
42
|
-
currentValue: formatCurrentModelId({
|
|
43
|
-
model: input.currentModel,
|
|
44
|
-
variant: input.currentVariant,
|
|
45
|
-
variants: variantsForModel(input.providers, input.currentModel),
|
|
46
|
-
includeVariant: input.includeVariants ?? false,
|
|
47
|
-
}),
|
|
48
|
-
options: buildModelSelectOptions(input.providers, { includeVariants: input.includeVariants ?? false }),
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
export function buildEffortSelectOption(input: {
|
|
53
|
-
variants: readonly string[]
|
|
54
|
-
currentVariant?: string
|
|
55
|
-
}): SessionConfigOption | undefined {
|
|
56
|
-
if (input.variants.length === 0) return undefined
|
|
57
|
-
|
|
58
|
-
return {
|
|
59
|
-
id: "effort",
|
|
60
|
-
name: "Effort",
|
|
61
|
-
description: "Available effort levels for this model",
|
|
62
|
-
category: "thought_level",
|
|
63
|
-
type: "select",
|
|
64
|
-
currentValue:
|
|
65
|
-
input.currentVariant === DEFAULT_VARIANT_VALUE
|
|
66
|
-
? DEFAULT_VARIANT_VALUE
|
|
67
|
-
: selectVariant(input.currentVariant, input.variants),
|
|
68
|
-
options: [...new Set([...input.variants, DEFAULT_VARIANT_VALUE])].map((variant) => ({
|
|
69
|
-
value: variant,
|
|
70
|
-
name: formatVariantName(variant),
|
|
71
|
-
})),
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
export function buildModeSelectOption(input: {
|
|
76
|
-
modes: readonly ConfigOptionMode[]
|
|
77
|
-
currentModeId: string
|
|
78
|
-
}): SessionConfigOption {
|
|
79
|
-
return {
|
|
80
|
-
id: "mode",
|
|
81
|
-
name: "Session Mode",
|
|
82
|
-
category: "mode",
|
|
83
|
-
type: "select",
|
|
84
|
-
currentValue: input.currentModeId,
|
|
85
|
-
options: input.modes.map((mode) => ({
|
|
86
|
-
value: mode.id,
|
|
87
|
-
name: mode.name,
|
|
88
|
-
...(mode.description ? { description: mode.description } : {}),
|
|
89
|
-
})),
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
export function buildConfigOptions(input: {
|
|
94
|
-
providers: readonly ConfigOptionProvider[]
|
|
95
|
-
currentModel: ModelSelection["model"]
|
|
96
|
-
currentVariant?: string
|
|
97
|
-
includeModelVariants?: boolean
|
|
98
|
-
modes?: readonly ConfigOptionMode[]
|
|
99
|
-
currentModeId?: string
|
|
100
|
-
}): SessionConfigOption[] {
|
|
101
|
-
const variants = variantsForModel(input.providers, input.currentModel)
|
|
102
|
-
const effort = buildEffortSelectOption({ variants, currentVariant: input.currentVariant })
|
|
103
|
-
|
|
104
|
-
return [
|
|
105
|
-
buildModelSelectOption({
|
|
106
|
-
providers: input.providers,
|
|
107
|
-
currentModel: input.currentModel,
|
|
108
|
-
currentVariant: input.currentVariant,
|
|
109
|
-
includeVariants: input.includeModelVariants ?? false,
|
|
110
|
-
}),
|
|
111
|
-
...(effort ? [effort] : []),
|
|
112
|
-
...(input.modes && input.currentModeId
|
|
113
|
-
? [buildModeSelectOption({ modes: input.modes, currentModeId: input.currentModeId })]
|
|
114
|
-
: []),
|
|
115
|
-
]
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
export function parseModelSelection(modelId: string, providers: readonly ConfigOptionProvider[]): ModelSelection {
|
|
119
|
-
const provider = providers.find((item) => modelId.startsWith(`${item.id}/`))
|
|
120
|
-
if (provider) {
|
|
121
|
-
const modelID = modelId.slice(provider.id.length + 1)
|
|
122
|
-
if (provider.models[modelID]) {
|
|
123
|
-
return { model: { providerID: provider.id, modelID } }
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
const separator = modelID.lastIndexOf("/")
|
|
127
|
-
if (separator > -1) {
|
|
128
|
-
const baseModelID = modelID.slice(0, separator)
|
|
129
|
-
const variant = modelID.slice(separator + 1)
|
|
130
|
-
if (provider.models[baseModelID]?.variants?.[variant]) {
|
|
131
|
-
return { model: { providerID: provider.id, modelID: baseModelID }, variant }
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
return { model: { providerID: provider.id, modelID } }
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
const separator = modelId.indexOf("/")
|
|
139
|
-
if (separator === -1) {
|
|
140
|
-
return { model: { providerID: modelId, modelID: "" } }
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
return {
|
|
144
|
-
model: {
|
|
145
|
-
providerID: modelId.slice(0, separator),
|
|
146
|
-
modelID: modelId.slice(separator + 1),
|
|
147
|
-
},
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
export function formatCurrentModelId(input: {
|
|
152
|
-
model: ModelSelection["model"]
|
|
153
|
-
variant?: string
|
|
154
|
-
variants?: readonly string[]
|
|
155
|
-
includeVariant?: boolean
|
|
156
|
-
}) {
|
|
157
|
-
const base = `${input.model.providerID}/${input.model.modelID}`
|
|
158
|
-
if (!input.includeVariant || !input.variants?.length) return base
|
|
159
|
-
return `${base}/${selectVariant(input.variant, input.variants)}`
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
export function formatVariantName(variant: string) {
|
|
163
|
-
return variant
|
|
164
|
-
.split(/[_-]/)
|
|
165
|
-
.map((part) => (part ? part.charAt(0).toUpperCase() + part.slice(1) : part))
|
|
166
|
-
.join(" ")
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
function buildModelSelectOptions(
|
|
170
|
-
providers: readonly ConfigOptionProvider[],
|
|
171
|
-
options: { includeVariants: boolean },
|
|
172
|
-
): Array<{ value: string; name: string }> {
|
|
173
|
-
return providers.flatMap((provider) =>
|
|
174
|
-
Object.values(provider.models)
|
|
175
|
-
.sort((a, b) => a.name.localeCompare(b.name))
|
|
176
|
-
.flatMap((model) => {
|
|
177
|
-
const base = {
|
|
178
|
-
value: `${provider.id}/${model.id}`,
|
|
179
|
-
name: `${provider.name}/${model.name}`,
|
|
180
|
-
}
|
|
181
|
-
if (!options.includeVariants || !model.variants) return [base]
|
|
182
|
-
|
|
183
|
-
return [
|
|
184
|
-
base,
|
|
185
|
-
...Object.keys(model.variants)
|
|
186
|
-
.filter((variant) => variant !== DEFAULT_VARIANT_VALUE)
|
|
187
|
-
.map((variant) => ({
|
|
188
|
-
value: `${provider.id}/${model.id}/${variant}`,
|
|
189
|
-
name: `${provider.name}/${model.name} (${formatVariantName(variant)})`,
|
|
190
|
-
})),
|
|
191
|
-
]
|
|
192
|
-
}),
|
|
193
|
-
)
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
function variantsForModel(providers: readonly ConfigOptionProvider[], model: ModelSelection["model"]) {
|
|
197
|
-
return Object.keys(
|
|
198
|
-
providers.find((provider) => provider.id === model.providerID)?.models[model.modelID]?.variants ?? {},
|
|
199
|
-
)
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
function selectVariant(variant: string | undefined, variants: readonly string[]) {
|
|
203
|
-
if (variant && variants.includes(variant)) return variant
|
|
204
|
-
if (variants.includes(DEFAULT_VARIANT_VALUE)) return DEFAULT_VARIANT_VALUE
|
|
205
|
-
return variants[0]
|
|
206
|
-
}
|