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/format/formatter.ts
DELETED
|
@@ -1,404 +0,0 @@
|
|
|
1
|
-
import { Npm } from "@soraacode/core/npm"
|
|
2
|
-
import type { InstanceContext } from "../project/instance-context"
|
|
3
|
-
import { Filesystem } from "@/util/filesystem"
|
|
4
|
-
import { Process } from "@/util/process"
|
|
5
|
-
import { which } from "@soraacode/core/util/which"
|
|
6
|
-
|
|
7
|
-
export interface Context extends Pick<InstanceContext, "directory" | "worktree"> {
|
|
8
|
-
experimentalOxfmt: boolean
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export interface Info {
|
|
12
|
-
name: string
|
|
13
|
-
environment?: Record<string, string>
|
|
14
|
-
extensions: string[]
|
|
15
|
-
enabled(context: Context): Promise<string[] | false>
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export const gofmt: Info = {
|
|
19
|
-
name: "gofmt",
|
|
20
|
-
extensions: [".go"],
|
|
21
|
-
async enabled() {
|
|
22
|
-
const match = which("gofmt")
|
|
23
|
-
if (!match) return false
|
|
24
|
-
return [match, "-w", "$FILE"]
|
|
25
|
-
},
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export const mix: Info = {
|
|
29
|
-
name: "mix",
|
|
30
|
-
extensions: [".ex", ".exs", ".eex", ".heex", ".leex", ".neex", ".sface"],
|
|
31
|
-
async enabled() {
|
|
32
|
-
const match = which("mix")
|
|
33
|
-
if (!match) return false
|
|
34
|
-
return [match, "format", "$FILE"]
|
|
35
|
-
},
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
export const prettier: Info = {
|
|
39
|
-
name: "prettier",
|
|
40
|
-
environment: {
|
|
41
|
-
BUN_BE_BUN: "1",
|
|
42
|
-
},
|
|
43
|
-
extensions: [
|
|
44
|
-
".js",
|
|
45
|
-
".jsx",
|
|
46
|
-
".mjs",
|
|
47
|
-
".cjs",
|
|
48
|
-
".ts",
|
|
49
|
-
".tsx",
|
|
50
|
-
".mts",
|
|
51
|
-
".cts",
|
|
52
|
-
".html",
|
|
53
|
-
".htm",
|
|
54
|
-
".css",
|
|
55
|
-
".scss",
|
|
56
|
-
".sass",
|
|
57
|
-
".less",
|
|
58
|
-
".vue",
|
|
59
|
-
".svelte",
|
|
60
|
-
".json",
|
|
61
|
-
".jsonc",
|
|
62
|
-
".yaml",
|
|
63
|
-
".yml",
|
|
64
|
-
".toml",
|
|
65
|
-
".xml",
|
|
66
|
-
".md",
|
|
67
|
-
".mdx",
|
|
68
|
-
".graphql",
|
|
69
|
-
".gql",
|
|
70
|
-
],
|
|
71
|
-
async enabled(context) {
|
|
72
|
-
const items = await Filesystem.findUp("package.json", context.directory, context.worktree)
|
|
73
|
-
for (const item of items) {
|
|
74
|
-
const json = await Filesystem.readJson<{
|
|
75
|
-
dependencies?: Record<string, string>
|
|
76
|
-
devDependencies?: Record<string, string>
|
|
77
|
-
}>(item)
|
|
78
|
-
if (json.dependencies?.prettier || json.devDependencies?.prettier) {
|
|
79
|
-
const bin = await Npm.which("prettier")
|
|
80
|
-
if (bin) return [bin, "--write", "$FILE"]
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
return false
|
|
84
|
-
},
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
export const oxfmt: Info = {
|
|
88
|
-
name: "oxfmt",
|
|
89
|
-
environment: {
|
|
90
|
-
BUN_BE_BUN: "1",
|
|
91
|
-
},
|
|
92
|
-
extensions: [".js", ".jsx", ".mjs", ".cjs", ".ts", ".tsx", ".mts", ".cts"],
|
|
93
|
-
async enabled(context) {
|
|
94
|
-
if (!context.experimentalOxfmt) return false
|
|
95
|
-
const items = await Filesystem.findUp("package.json", context.directory, context.worktree)
|
|
96
|
-
for (const item of items) {
|
|
97
|
-
const json = await Filesystem.readJson<{
|
|
98
|
-
dependencies?: Record<string, string>
|
|
99
|
-
devDependencies?: Record<string, string>
|
|
100
|
-
}>(item)
|
|
101
|
-
if (json.dependencies?.oxfmt || json.devDependencies?.oxfmt) {
|
|
102
|
-
const bin = await Npm.which("oxfmt")
|
|
103
|
-
if (bin) return [bin, "$FILE"]
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
return false
|
|
107
|
-
},
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
export const biome: Info = {
|
|
111
|
-
name: "biome",
|
|
112
|
-
environment: {
|
|
113
|
-
BUN_BE_BUN: "1",
|
|
114
|
-
},
|
|
115
|
-
extensions: [
|
|
116
|
-
".js",
|
|
117
|
-
".jsx",
|
|
118
|
-
".mjs",
|
|
119
|
-
".cjs",
|
|
120
|
-
".ts",
|
|
121
|
-
".tsx",
|
|
122
|
-
".mts",
|
|
123
|
-
".cts",
|
|
124
|
-
".html",
|
|
125
|
-
".htm",
|
|
126
|
-
".css",
|
|
127
|
-
".scss",
|
|
128
|
-
".sass",
|
|
129
|
-
".less",
|
|
130
|
-
".vue",
|
|
131
|
-
".svelte",
|
|
132
|
-
".json",
|
|
133
|
-
".jsonc",
|
|
134
|
-
".yaml",
|
|
135
|
-
".yml",
|
|
136
|
-
".toml",
|
|
137
|
-
".xml",
|
|
138
|
-
".md",
|
|
139
|
-
".mdx",
|
|
140
|
-
".graphql",
|
|
141
|
-
".gql",
|
|
142
|
-
],
|
|
143
|
-
async enabled(context) {
|
|
144
|
-
const configs = ["biome.json", "biome.jsonc"]
|
|
145
|
-
for (const config of configs) {
|
|
146
|
-
const found = await Filesystem.findUp(config, context.directory, context.worktree)
|
|
147
|
-
if (found.length > 0) {
|
|
148
|
-
const bin = await Npm.which("@biomejs/biome")
|
|
149
|
-
if (bin) return [bin, "format", "--write", "$FILE"]
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
return false
|
|
153
|
-
},
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
export const zig: Info = {
|
|
157
|
-
name: "zig",
|
|
158
|
-
extensions: [".zig", ".zon"],
|
|
159
|
-
async enabled() {
|
|
160
|
-
const match = which("zig")
|
|
161
|
-
if (!match) return false
|
|
162
|
-
return [match, "fmt", "$FILE"]
|
|
163
|
-
},
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
export const clang: Info = {
|
|
167
|
-
name: "clang-format",
|
|
168
|
-
extensions: [".c", ".cc", ".cpp", ".cxx", ".c++", ".h", ".hh", ".hpp", ".hxx", ".h++", ".ino", ".C", ".H"],
|
|
169
|
-
async enabled(context) {
|
|
170
|
-
const items = await Filesystem.findUp(".clang-format", context.directory, context.worktree)
|
|
171
|
-
if (items.length > 0) {
|
|
172
|
-
const match = which("clang-format")
|
|
173
|
-
if (match) return [match, "-i", "$FILE"]
|
|
174
|
-
}
|
|
175
|
-
return false
|
|
176
|
-
},
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
export const ktlint: Info = {
|
|
180
|
-
name: "ktlint",
|
|
181
|
-
extensions: [".kt", ".kts"],
|
|
182
|
-
async enabled() {
|
|
183
|
-
const match = which("ktlint")
|
|
184
|
-
if (!match) return false
|
|
185
|
-
return [match, "-F", "$FILE"]
|
|
186
|
-
},
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
export const ruff: Info = {
|
|
190
|
-
name: "ruff",
|
|
191
|
-
extensions: [".py", ".pyi"],
|
|
192
|
-
async enabled(context) {
|
|
193
|
-
if (!which("ruff")) return false
|
|
194
|
-
const configs = ["pyproject.toml", "ruff.toml", ".ruff.toml"]
|
|
195
|
-
for (const config of configs) {
|
|
196
|
-
const found = await Filesystem.findUp(config, context.directory, context.worktree)
|
|
197
|
-
if (found.length > 0) {
|
|
198
|
-
if (config === "pyproject.toml") {
|
|
199
|
-
const content = await Filesystem.readText(found[0])
|
|
200
|
-
if (content.includes("[tool.ruff]")) return ["ruff", "format", "$FILE"]
|
|
201
|
-
} else {
|
|
202
|
-
return ["ruff", "format", "$FILE"]
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
const deps = ["requirements.txt", "pyproject.toml", "Pipfile"]
|
|
207
|
-
for (const dep of deps) {
|
|
208
|
-
const found = await Filesystem.findUp(dep, context.directory, context.worktree)
|
|
209
|
-
if (found.length > 0) {
|
|
210
|
-
const content = await Filesystem.readText(found[0])
|
|
211
|
-
if (content.includes("ruff")) return ["ruff", "format", "$FILE"]
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
return false
|
|
215
|
-
},
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
export const rlang: Info = {
|
|
219
|
-
name: "air",
|
|
220
|
-
extensions: [".R"],
|
|
221
|
-
async enabled() {
|
|
222
|
-
const air = which("air")
|
|
223
|
-
if (air == null) return false
|
|
224
|
-
|
|
225
|
-
const output = await Process.text([air, "--help"], { nothrow: true })
|
|
226
|
-
|
|
227
|
-
// Check for "Air: An R language server and formatter"
|
|
228
|
-
const firstLine = output.text.split("\n")[0]
|
|
229
|
-
const hasR = firstLine.includes("R language")
|
|
230
|
-
const hasFormatter = firstLine.includes("formatter")
|
|
231
|
-
if (output.code === 0 && hasR && hasFormatter) return [air, "format", "$FILE"]
|
|
232
|
-
return false
|
|
233
|
-
},
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
export const uvformat: Info = {
|
|
237
|
-
name: "uv",
|
|
238
|
-
extensions: [".py", ".pyi"],
|
|
239
|
-
async enabled(context) {
|
|
240
|
-
if (await ruff.enabled(context)) return false
|
|
241
|
-
const uv = which("uv")
|
|
242
|
-
if (uv == null) return false
|
|
243
|
-
const output = await Process.run([uv, "format", "--help"], { nothrow: true })
|
|
244
|
-
if (output.code === 0) return [uv, "format", "--", "$FILE"]
|
|
245
|
-
return false
|
|
246
|
-
},
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
export const rubocop: Info = {
|
|
250
|
-
name: "rubocop",
|
|
251
|
-
extensions: [".rb", ".rake", ".gemspec", ".ru"],
|
|
252
|
-
async enabled() {
|
|
253
|
-
const match = which("rubocop")
|
|
254
|
-
if (!match) return false
|
|
255
|
-
return [match, "--autocorrect", "$FILE"]
|
|
256
|
-
},
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
export const standardrb: Info = {
|
|
260
|
-
name: "standardrb",
|
|
261
|
-
extensions: [".rb", ".rake", ".gemspec", ".ru"],
|
|
262
|
-
async enabled() {
|
|
263
|
-
const match = which("standardrb")
|
|
264
|
-
if (!match) return false
|
|
265
|
-
return [match, "--fix", "$FILE"]
|
|
266
|
-
},
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
export const htmlbeautifier: Info = {
|
|
270
|
-
name: "htmlbeautifier",
|
|
271
|
-
extensions: [".erb", ".html.erb"],
|
|
272
|
-
async enabled() {
|
|
273
|
-
const match = which("htmlbeautifier")
|
|
274
|
-
if (!match) return false
|
|
275
|
-
return [match, "$FILE"]
|
|
276
|
-
},
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
export const dart: Info = {
|
|
280
|
-
name: "dart",
|
|
281
|
-
extensions: [".dart"],
|
|
282
|
-
async enabled() {
|
|
283
|
-
const match = which("dart")
|
|
284
|
-
if (!match) return false
|
|
285
|
-
return [match, "format", "$FILE"]
|
|
286
|
-
},
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
export const ocamlformat: Info = {
|
|
290
|
-
name: "ocamlformat",
|
|
291
|
-
extensions: [".ml", ".mli"],
|
|
292
|
-
async enabled(context) {
|
|
293
|
-
if (!which("ocamlformat")) return false
|
|
294
|
-
const items = await Filesystem.findUp(".ocamlformat", context.directory, context.worktree)
|
|
295
|
-
if (items.length > 0) return ["ocamlformat", "-i", "$FILE"]
|
|
296
|
-
return false
|
|
297
|
-
},
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
export const terraform: Info = {
|
|
301
|
-
name: "terraform",
|
|
302
|
-
extensions: [".tf", ".tfvars"],
|
|
303
|
-
async enabled() {
|
|
304
|
-
const match = which("terraform")
|
|
305
|
-
if (!match) return false
|
|
306
|
-
return [match, "fmt", "$FILE"]
|
|
307
|
-
},
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
export const latexindent: Info = {
|
|
311
|
-
name: "latexindent",
|
|
312
|
-
extensions: [".tex"],
|
|
313
|
-
async enabled() {
|
|
314
|
-
const match = which("latexindent")
|
|
315
|
-
if (!match) return false
|
|
316
|
-
return [match, "-w", "-s", "$FILE"]
|
|
317
|
-
},
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
export const gleam: Info = {
|
|
321
|
-
name: "gleam",
|
|
322
|
-
extensions: [".gleam"],
|
|
323
|
-
async enabled() {
|
|
324
|
-
const match = which("gleam")
|
|
325
|
-
if (!match) return false
|
|
326
|
-
return [match, "format", "$FILE"]
|
|
327
|
-
},
|
|
328
|
-
}
|
|
329
|
-
|
|
330
|
-
export const shfmt: Info = {
|
|
331
|
-
name: "shfmt",
|
|
332
|
-
extensions: [".sh", ".bash"],
|
|
333
|
-
async enabled() {
|
|
334
|
-
const match = which("shfmt")
|
|
335
|
-
if (!match) return false
|
|
336
|
-
return [match, "-w", "$FILE"]
|
|
337
|
-
},
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
export const nixfmt: Info = {
|
|
341
|
-
name: "nixfmt",
|
|
342
|
-
extensions: [".nix"],
|
|
343
|
-
async enabled() {
|
|
344
|
-
const match = which("nixfmt")
|
|
345
|
-
if (!match) return false
|
|
346
|
-
return [match, "$FILE"]
|
|
347
|
-
},
|
|
348
|
-
}
|
|
349
|
-
|
|
350
|
-
export const rustfmt: Info = {
|
|
351
|
-
name: "rustfmt",
|
|
352
|
-
extensions: [".rs"],
|
|
353
|
-
async enabled() {
|
|
354
|
-
const match = which("rustfmt")
|
|
355
|
-
if (!match) return false
|
|
356
|
-
return [match, "$FILE"]
|
|
357
|
-
},
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
export const pint: Info = {
|
|
361
|
-
name: "pint",
|
|
362
|
-
extensions: [".php"],
|
|
363
|
-
async enabled(context) {
|
|
364
|
-
const items = await Filesystem.findUp("composer.json", context.directory, context.worktree)
|
|
365
|
-
for (const item of items) {
|
|
366
|
-
const json = await Filesystem.readJson<{
|
|
367
|
-
require?: Record<string, string>
|
|
368
|
-
"require-dev"?: Record<string, string>
|
|
369
|
-
}>(item)
|
|
370
|
-
if (json.require?.["laravel/pint"] || json["require-dev"]?.["laravel/pint"]) return ["./vendor/bin/pint", "$FILE"]
|
|
371
|
-
}
|
|
372
|
-
return false
|
|
373
|
-
},
|
|
374
|
-
}
|
|
375
|
-
|
|
376
|
-
export const ormolu: Info = {
|
|
377
|
-
name: "ormolu",
|
|
378
|
-
extensions: [".hs"],
|
|
379
|
-
async enabled() {
|
|
380
|
-
const match = which("ormolu")
|
|
381
|
-
if (!match) return false
|
|
382
|
-
return [match, "-i", "$FILE"]
|
|
383
|
-
},
|
|
384
|
-
}
|
|
385
|
-
|
|
386
|
-
export const cljfmt: Info = {
|
|
387
|
-
name: "cljfmt",
|
|
388
|
-
extensions: [".clj", ".cljs", ".cljc", ".edn"],
|
|
389
|
-
async enabled() {
|
|
390
|
-
const match = which("cljfmt")
|
|
391
|
-
if (!match) return false
|
|
392
|
-
return [match, "fix", "--quiet", "$FILE"]
|
|
393
|
-
},
|
|
394
|
-
}
|
|
395
|
-
|
|
396
|
-
export const dfmt: Info = {
|
|
397
|
-
name: "dfmt",
|
|
398
|
-
extensions: [".d"],
|
|
399
|
-
async enabled() {
|
|
400
|
-
const match = which("dfmt")
|
|
401
|
-
if (!match) return false
|
|
402
|
-
return [match, "-i", "$FILE"]
|
|
403
|
-
},
|
|
404
|
-
}
|
package/src/format/index.ts
DELETED
|
@@ -1,203 +0,0 @@
|
|
|
1
|
-
import { LayerNode } from "@soraacode/core/effect/layer-node"
|
|
2
|
-
import { Effect, Layer, Context, Schema } from "effect"
|
|
3
|
-
import { serviceUse } from "@soraacode/core/effect/service-use"
|
|
4
|
-
import { ChildProcess } from "effect/unstable/process"
|
|
5
|
-
import { AppProcess } from "@soraacode/core/process"
|
|
6
|
-
import { InstanceState } from "@/effect/instance-state"
|
|
7
|
-
import path from "path"
|
|
8
|
-
import { mergeDeep } from "remeda"
|
|
9
|
-
import { Config } from "@/config/config"
|
|
10
|
-
import { RuntimeFlags } from "@/effect/runtime-flags"
|
|
11
|
-
import { errorMessage } from "@/util/error"
|
|
12
|
-
import * as Formatter from "./formatter"
|
|
13
|
-
|
|
14
|
-
export const Status = Schema.Struct({
|
|
15
|
-
name: Schema.String,
|
|
16
|
-
extensions: Schema.Array(Schema.String),
|
|
17
|
-
enabled: Schema.Boolean,
|
|
18
|
-
}).annotate({ identifier: "FormatterStatus" })
|
|
19
|
-
export type Status = Schema.Schema.Type<typeof Status>
|
|
20
|
-
|
|
21
|
-
export interface Interface {
|
|
22
|
-
readonly init: () => Effect.Effect<void>
|
|
23
|
-
readonly status: () => Effect.Effect<Status[]>
|
|
24
|
-
readonly file: (filepath: string) => Effect.Effect<boolean>
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export class Service extends Context.Service<Service, Interface>()("@opencode/Format") {}
|
|
28
|
-
|
|
29
|
-
export const use = serviceUse(Service)
|
|
30
|
-
|
|
31
|
-
const layer = Layer.effect(
|
|
32
|
-
Service,
|
|
33
|
-
Effect.gen(function* () {
|
|
34
|
-
const config = yield* Config.Service
|
|
35
|
-
const appProcess = yield* AppProcess.Service
|
|
36
|
-
const flags = yield* RuntimeFlags.Service
|
|
37
|
-
|
|
38
|
-
const state = yield* InstanceState.make(
|
|
39
|
-
Effect.fn("Format.state")(function* (ctx) {
|
|
40
|
-
const commands: Record<string, string[] | false> = {}
|
|
41
|
-
const formatters: Record<string, Formatter.Info> = {}
|
|
42
|
-
|
|
43
|
-
async function getCommand(item: Formatter.Info) {
|
|
44
|
-
let cmd = commands[item.name]
|
|
45
|
-
if (cmd === false || cmd === undefined) {
|
|
46
|
-
cmd = await item.enabled({ ...ctx, experimentalOxfmt: flags.experimentalOxfmt })
|
|
47
|
-
commands[item.name] = cmd
|
|
48
|
-
}
|
|
49
|
-
return cmd
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
async function isEnabled(item: Formatter.Info) {
|
|
53
|
-
const cmd = await getCommand(item)
|
|
54
|
-
return cmd !== false
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
async function getFormatter(ext: string) {
|
|
58
|
-
const matching = Object.values(formatters).filter((item) => item.extensions.includes(ext))
|
|
59
|
-
const checks = await Promise.all(
|
|
60
|
-
matching.map(async (item) => {
|
|
61
|
-
const cmd = await getCommand(item)
|
|
62
|
-
return {
|
|
63
|
-
item,
|
|
64
|
-
cmd,
|
|
65
|
-
}
|
|
66
|
-
}),
|
|
67
|
-
)
|
|
68
|
-
return checks
|
|
69
|
-
.filter((x): x is { item: Formatter.Info; cmd: string[] } => x.cmd !== false)
|
|
70
|
-
.map((x) => ({ item: x.item, cmd: x.cmd }))
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
function formatFile(filepath: string) {
|
|
74
|
-
return Effect.gen(function* () {
|
|
75
|
-
yield* Effect.logInfo("formatting", { file: filepath })
|
|
76
|
-
const formatters = yield* Effect.promise(() => getFormatter(path.extname(filepath)))
|
|
77
|
-
|
|
78
|
-
if (!formatters.length) return false
|
|
79
|
-
|
|
80
|
-
for (const { item, cmd } of formatters) {
|
|
81
|
-
yield* Effect.logInfo("running", { command: cmd })
|
|
82
|
-
const replaced = cmd.map((x) => x.replace("$FILE", filepath))
|
|
83
|
-
const dir = yield* InstanceState.directory
|
|
84
|
-
const result = yield* appProcess
|
|
85
|
-
.run(
|
|
86
|
-
ChildProcess.make(replaced[0]!, replaced.slice(1), {
|
|
87
|
-
cwd: dir,
|
|
88
|
-
env: item.environment,
|
|
89
|
-
extendEnv: true,
|
|
90
|
-
stdin: "ignore",
|
|
91
|
-
stdout: "ignore",
|
|
92
|
-
stderr: "ignore",
|
|
93
|
-
}),
|
|
94
|
-
)
|
|
95
|
-
.pipe(
|
|
96
|
-
Effect.catch((error) =>
|
|
97
|
-
Effect.logError("failed to format file", {
|
|
98
|
-
error: "spawn failed",
|
|
99
|
-
command: cmd,
|
|
100
|
-
...item.environment,
|
|
101
|
-
file: filepath,
|
|
102
|
-
cause: errorMessage(error.cause ?? error),
|
|
103
|
-
}).pipe(Effect.as(undefined)),
|
|
104
|
-
),
|
|
105
|
-
)
|
|
106
|
-
if (result && result.exitCode !== 0) {
|
|
107
|
-
yield* Effect.logError("failed", {
|
|
108
|
-
command: cmd,
|
|
109
|
-
...item.environment,
|
|
110
|
-
})
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
return true
|
|
115
|
-
})
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
const cfg = yield* config.get()
|
|
119
|
-
|
|
120
|
-
if (!cfg.formatter) {
|
|
121
|
-
yield* Effect.logInfo("all formatters are disabled")
|
|
122
|
-
yield* Effect.logInfo("init")
|
|
123
|
-
return {
|
|
124
|
-
formatters,
|
|
125
|
-
isEnabled,
|
|
126
|
-
formatFile,
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
for (const item of Object.values(Formatter)) {
|
|
131
|
-
formatters[item.name] = item
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
if (cfg.formatter !== true) {
|
|
135
|
-
for (const [name, item] of Object.entries(cfg.formatter)) {
|
|
136
|
-
const builtIn = Formatter[name as keyof typeof Formatter]
|
|
137
|
-
|
|
138
|
-
// Ruff and uv are both the same formatter, so disabling either should disable both.
|
|
139
|
-
if (["ruff", "uv"].includes(name) && (cfg.formatter.ruff?.disabled || cfg.formatter.uv?.disabled)) {
|
|
140
|
-
// TODO combine formatters so shared backends like Ruff/uv don't need linked disable handling here.
|
|
141
|
-
delete formatters.ruff
|
|
142
|
-
delete formatters.uv
|
|
143
|
-
continue
|
|
144
|
-
}
|
|
145
|
-
if (item.disabled) {
|
|
146
|
-
delete formatters[name]
|
|
147
|
-
continue
|
|
148
|
-
}
|
|
149
|
-
const info = mergeDeep(builtIn ?? { extensions: [] }, item)
|
|
150
|
-
|
|
151
|
-
formatters[name] = {
|
|
152
|
-
...info,
|
|
153
|
-
name,
|
|
154
|
-
extensions: info.extensions ?? [],
|
|
155
|
-
enabled: builtIn && !info.command ? builtIn.enabled : async (_context) => info.command ?? false,
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
yield* Effect.logInfo("init")
|
|
161
|
-
|
|
162
|
-
return {
|
|
163
|
-
formatters,
|
|
164
|
-
isEnabled,
|
|
165
|
-
formatFile,
|
|
166
|
-
}
|
|
167
|
-
}),
|
|
168
|
-
)
|
|
169
|
-
|
|
170
|
-
const init = Effect.fn("Format.init")(function* () {
|
|
171
|
-
yield* InstanceState.get(state)
|
|
172
|
-
})
|
|
173
|
-
|
|
174
|
-
const status = Effect.fn("Format.status")(function* () {
|
|
175
|
-
const { formatters, isEnabled } = yield* InstanceState.get(state)
|
|
176
|
-
const result: Status[] = []
|
|
177
|
-
for (const formatter of Object.values(formatters)) {
|
|
178
|
-
const isOn = yield* Effect.promise(() => isEnabled(formatter))
|
|
179
|
-
result.push({
|
|
180
|
-
name: formatter.name,
|
|
181
|
-
extensions: formatter.extensions,
|
|
182
|
-
enabled: isOn,
|
|
183
|
-
})
|
|
184
|
-
}
|
|
185
|
-
return result
|
|
186
|
-
})
|
|
187
|
-
|
|
188
|
-
const file = Effect.fn("Format.file")(function* (filepath: string) {
|
|
189
|
-
const { formatFile } = yield* InstanceState.get(state)
|
|
190
|
-
return yield* formatFile(filepath)
|
|
191
|
-
})
|
|
192
|
-
|
|
193
|
-
return Service.of({ init, status, file })
|
|
194
|
-
}),
|
|
195
|
-
)
|
|
196
|
-
|
|
197
|
-
export const node = LayerNode.make({
|
|
198
|
-
service: Service,
|
|
199
|
-
layer: layer,
|
|
200
|
-
deps: [Config.node, AppProcess.node, RuntimeFlags.node],
|
|
201
|
-
})
|
|
202
|
-
|
|
203
|
-
export * as Format from "."
|