onlycode 1.18.0 → 1.20.0
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/bin/{opencode.cjs → onlycode.cjs} +8 -42
- package/package.json +12 -147
- package/src/account/account.ts +0 -463
- package/src/account/repo.ts +0 -173
- 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 -203
- package/src/acp/content.ts +0 -250
- package/src/acp/directory.ts +0 -210
- package/src/acp/error.ts +0 -90
- package/src/acp/event.ts +0 -342
- package/src/acp/permission.ts +0 -124
- package/src/acp/profile.ts +0 -42
- package/src/acp/service.ts +0 -1048
- package/src/acp/session.ts +0 -231
- package/src/acp/tool.ts +0 -367
- package/src/acp/usage.ts +0 -232
- package/src/agent/agent.ts +0 -459
- package/src/agent/generate.txt +0 -75
- package/src/agent/prompt/compaction.txt +0 -9
- 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 -99
- package/src/background/job.ts +0 -39
- package/src/bus/global.ts +0 -22
- package/src/cli/bootstrap.ts +0 -11
- package/src/cli/cmd/account.ts +0 -264
- package/src/cli/cmd/acp.ts +0 -73
- package/src/cli/cmd/agent.ts +0 -259
- package/src/cli/cmd/attach.ts +0 -97
- package/src/cli/cmd/cmd.ts +0 -7
- package/src/cli/cmd/db.ts +0 -62
- package/src/cli/cmd/debug/agent.handler.ts +0 -193
- package/src/cli/cmd/debug/agent.ts +0 -27
- package/src/cli/cmd/debug/config.ts +0 -14
- package/src/cli/cmd/debug/file.ts +0 -73
- package/src/cli/cmd/debug/index.ts +0 -87
- package/src/cli/cmd/debug/lsp.ts +0 -50
- package/src/cli/cmd/debug/ripgrep.ts +0 -79
- package/src/cli/cmd/debug/scrap.ts +0 -15
- package/src/cli/cmd/debug/skill.ts +0 -15
- package/src/cli/cmd/debug/snapshot.ts +0 -50
- package/src/cli/cmd/debug/startup.ts +0 -11
- package/src/cli/cmd/debug/v2.ts +0 -44
- package/src/cli/cmd/export.ts +0 -292
- package/src/cli/cmd/generate.ts +0 -54
- package/src/cli/cmd/github.handler.ts +0 -1593
- package/src/cli/cmd/github.shared.ts +0 -30
- package/src/cli/cmd/github.ts +0 -42
- package/src/cli/cmd/import.ts +0 -224
- package/src/cli/cmd/mcp.ts +0 -849
- package/src/cli/cmd/models.ts +0 -66
- package/src/cli/cmd/plug.ts +0 -230
- package/src/cli/cmd/pr.ts +0 -115
- package/src/cli/cmd/prompt-display.ts +0 -1
- package/src/cli/cmd/providers.ts +0 -534
- package/src/cli/cmd/run/demo.ts +0 -1274
- package/src/cli/cmd/run/entry.body.ts +0 -205
- package/src/cli/cmd/run/footer.command.tsx +0 -1064
- package/src/cli/cmd/run/footer.menu.tsx +0 -351
- package/src/cli/cmd/run/footer.permission.tsx +0 -472
- package/src/cli/cmd/run/footer.prompt.tsx +0 -1306
- package/src/cli/cmd/run/footer.question.tsx +0 -573
- package/src/cli/cmd/run/footer.subagent.tsx +0 -173
- package/src/cli/cmd/run/footer.ts +0 -1129
- package/src/cli/cmd/run/footer.view.tsx +0 -943
- package/src/cli/cmd/run/footer.width.ts +0 -27
- package/src/cli/cmd/run/permission.shared.ts +0 -256
- package/src/cli/cmd/run/prompt.editor.ts +0 -157
- package/src/cli/cmd/run/prompt.shared.ts +0 -153
- package/src/cli/cmd/run/question.shared.ts +0 -340
- package/src/cli/cmd/run/runtime.boot.ts +0 -202
- package/src/cli/cmd/run/runtime.lifecycle.ts +0 -406
- package/src/cli/cmd/run/runtime.queue.ts +0 -349
- package/src/cli/cmd/run/runtime.shared.ts +0 -17
- package/src/cli/cmd/run/runtime.stdin.ts +0 -37
- package/src/cli/cmd/run/runtime.ts +0 -814
- package/src/cli/cmd/run/scrollback.shared.ts +0 -92
- package/src/cli/cmd/run/scrollback.surface.ts +0 -431
- package/src/cli/cmd/run/scrollback.writer.tsx +0 -352
- package/src/cli/cmd/run/session-data.ts +0 -1113
- package/src/cli/cmd/run/session-replay.ts +0 -374
- package/src/cli/cmd/run/session.shared.ts +0 -196
- package/src/cli/cmd/run/splash.ts +0 -275
- package/src/cli/cmd/run/stream.transport.ts +0 -1462
- package/src/cli/cmd/run/stream.ts +0 -175
- package/src/cli/cmd/run/subagent-data.ts +0 -876
- package/src/cli/cmd/run/theme.ts +0 -690
- package/src/cli/cmd/run/tool.ts +0 -1489
- package/src/cli/cmd/run/trace.ts +0 -94
- package/src/cli/cmd/run/turn-summary.ts +0 -47
- package/src/cli/cmd/run/types.ts +0 -350
- package/src/cli/cmd/run/variant.shared.ts +0 -215
- package/src/cli/cmd/run.ts +0 -894
- package/src/cli/cmd/serve.ts +0 -24
- package/src/cli/cmd/session.ts +0 -147
- package/src/cli/cmd/stats.ts +0 -393
- package/src/cli/cmd/tui.ts +0 -224
- package/src/cli/cmd/uninstall.ts +0 -353
- package/src/cli/cmd/upgrade.ts +0 -74
- package/src/cli/cmd/web.ts +0 -84
- 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-pixel.ts +0 -35
- package/src/cli/logo.ts +0 -1
- package/src/cli/network.ts +0 -64
- package/src/cli/tui/layer.ts +0 -7
- package/src/cli/tui/validate-session.ts +0 -29
- package/src/cli/tui/worker.ts +0 -71
- package/src/cli/ui.ts +0 -148
- package/src/cli/upgrade.ts +0 -53
- package/src/command/index.ts +0 -184
- 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 -686
- 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 -79
- package/src/config/paths.ts +0 -45
- package/src/config/plugin.ts +0 -79
- package/src/config/tui-cwd.ts +0 -5
- package/src/config/tui-host-attention.ts +0 -21
- package/src/config/tui-migrate.ts +0 -132
- package/src/config/tui.ts +0 -274
- 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 -989
- package/src/effect/app-runtime.ts +0 -132
- package/src/effect/bootstrap-runtime.ts +0 -23
- 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 -79
- package/src/env/index.ts +0 -43
- package/src/event-v2-bridge.ts +0 -79
- package/src/format/formatter.ts +0 -404
- package/src/format/index.ts +0 -205
- package/src/git/index.ts +0 -350
- package/src/id/id.ts +0 -80
- package/src/ide/index.ts +0 -61
- package/src/image/image.ts +0 -174
- package/src/index.ts +0 -142
- package/src/installation/index.ts +0 -350
- 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 -511
- package/src/lsp/server.ts +0 -1983
- package/src/markdown.d.ts +0 -4
- package/src/mcp/auth.ts +0 -174
- package/src/mcp/catalog.ts +0 -153
- package/src/mcp/index.ts +0 -953
- package/src/mcp/oauth-callback.ts +0 -233
- package/src/mcp/oauth-provider.ts +0 -206
- 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 -230
- package/src/plugin/azure.ts +0 -26
- package/src/plugin/cloudflare.ts +0 -76
- package/src/plugin/digitalocean.ts +0 -383
- package/src/plugin/github-copilot/copilot.ts +0 -414
- package/src/plugin/github-copilot/models.ts +0 -246
- package/src/plugin/index.ts +0 -316
- 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 -641
- package/src/plugin/openai/ws-pool.ts +0 -270
- package/src/plugin/openai/ws.ts +0 -381
- package/src/plugin/pty-environment.ts +0 -24
- package/src/plugin/shared.ts +0 -323
- package/src/plugin/snowflake-cortex.ts +0 -529
- package/src/plugin/tui/internal.ts +0 -10
- package/src/plugin/tui/runtime.ts +0 -1130
- package/src/plugin/xai.ts +0 -716
- package/src/project/bootstrap-service.ts +0 -9
- package/src/project/bootstrap.ts +0 -76
- package/src/project/instance-context.ts +0 -24
- package/src/project/instance-layer.ts +0 -11
- package/src/project/instance-runtime.ts +0 -16
- package/src/project/instance-store.ts +0 -209
- package/src/project/project.ts +0 -519
- package/src/project/vcs.ts +0 -431
- package/src/provider/auth.ts +0 -233
- package/src/provider/error.ts +0 -188
- package/src/provider/model-status.ts +0 -8
- package/src/provider/provider.ts +0 -1975
- package/src/provider/transform.ts +0 -1543
- package/src/question/index.ts +0 -229
- package/src/question/schema.ts +0 -10
- package/src/server/auth.ts +0 -48
- package/src/server/event.ts +0 -13
- package/src/server/global-lifecycle.ts +0 -28
- package/src/server/init-projectors.ts +0 -3
- package/src/server/mdns.ts +0 -47
- package/src/server/projectors.ts +0 -1
- 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 -78
- 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 -138
- 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 -192
- package/src/server/routes/instance/httpapi/handlers/file.ts +0 -139
- package/src/server/routes/instance/httpapi/handlers/global.ts +0 -156
- 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 -113
- 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 -440
- 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 -43
- 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 -108
- 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 -535
- package/src/server/routes/instance/httpapi/server.ts +0 -298
- package/src/server/routes/instance/httpapi/websocket-tracker.ts +0 -57
- package/src/server/server.ts +0 -225
- 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 -38
- package/src/server/tui-event.ts +0 -53
- package/src/session/compaction.ts +0 -620
- package/src/session/instruction.ts +0 -241
- package/src/session/llm/AGENTS.md +0 -90
- package/src/session/llm/ai-sdk.ts +0 -288
- 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 -216
- package/src/session/llm.ts +0 -415
- package/src/session/message-error.ts +0 -14
- package/src/session/message-v2.ts +0 -747
- package/src/session/message.ts +0 -148
- package/src/session/overflow.ts +0 -34
- package/src/session/processor.ts +0 -1084
- package/src/session/prompt/anthropic.txt +0 -109
- package/src/session/prompt/beast.txt +0 -151
- package/src/session/prompt/build-switch.txt +0 -9
- package/src/session/prompt/codex.txt +0 -83
- package/src/session/prompt/copilot-gpt-5.txt +0 -147
- package/src/session/prompt/default.txt +0 -99
- package/src/session/prompt/gemini.txt +0 -159
- package/src/session/prompt/gpt.txt +0 -111
- package/src/session/prompt/kimi.txt +0 -99
- package/src/session/prompt/plan-mode.txt +0 -74
- package/src/session/prompt/plan-reminder-anthropic.txt +0 -71
- package/src/session/prompt/plan.txt +0 -30
- package/src/session/prompt/trinity.txt +0 -101
- package/src/session/prompt.ts +0 -1707
- package/src/session/reminders.ts +0 -92
- package/src/session/retry.ts +0 -201
- package/src/session/revert.ts +0 -160
- package/src/session/run-state.ts +0 -156
- package/src/session/schema.ts +0 -26
- package/src/session/session.ts +0 -1119
- package/src/session/status.ts +0 -97
- package/src/session/summary.ts +0 -165
- package/src/session/system.ts +0 -117
- package/src/session/todo.ts +0 -90
- package/src/session/tools.ts +0 -207
- package/src/share/session.ts +0 -61
- package/src/share/share-next.ts +0 -385
- package/src/skill/discovery.ts +0 -109
- package/src/skill/index.ts +0 -366
- package/src/snapshot/index.ts +0 -808
- package/src/sql.d.ts +0 -4
- package/src/storage/schema.ts +0 -5
- package/src/storage/storage.ts +0 -329
- 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 -315
- package/src/tool/apply_patch.txt +0 -33
- package/src/tool/apply_patch.zh.txt +0 -33
- package/src/tool/description.ts +0 -100
- package/src/tool/edit.ts +0 -739
- package/src/tool/edit.txt +0 -10
- package/src/tool/edit.zh.txt +0 -10
- package/src/tool/external-directory.ts +0 -49
- package/src/tool/glob.ts +0 -78
- package/src/tool/glob.txt +0 -6
- package/src/tool/glob.zh.txt +0 -6
- package/src/tool/grep.ts +0 -114
- package/src/tool/grep.txt +0 -8
- package/src/tool/grep.zh.txt +0 -8
- package/src/tool/invalid.ts +0 -21
- package/src/tool/json-schema.ts +0 -164
- package/src/tool/lsp.ts +0 -115
- package/src/tool/lsp.txt +0 -24
- package/src/tool/lsp.zh.txt +0 -24
- package/src/tool/mcp-websearch.ts +0 -96
- package/src/tool/plan-enter.txt +0 -14
- package/src/tool/plan-enter.zh.txt +0 -14
- package/src/tool/plan-exit.txt +0 -13
- package/src/tool/plan-exit.zh.txt +0 -13
- package/src/tool/plan.ts +0 -81
- package/src/tool/question.ts +0 -46
- package/src/tool/question.txt +0 -10
- package/src/tool/question.zh.txt +0 -10
- package/src/tool/read.ts +0 -388
- package/src/tool/read.txt +0 -14
- package/src/tool/read.zh.txt +0 -14
- package/src/tool/registry.ts +0 -440
- package/src/tool/schema.ts +0 -14
- package/src/tool/shell/id.ts +0 -19
- package/src/tool/shell/prompt.ts +0 -307
- package/src/tool/shell/shell.txt +0 -21
- package/src/tool/shell.ts +0 -657
- package/src/tool/skill.ts +0 -73
- package/src/tool/skill.txt +0 -5
- package/src/tool/skill.zh.txt +0 -5
- package/src/tool/task.ts +0 -348
- package/src/tool/task.txt +0 -19
- package/src/tool/task.zh.txt +0 -19
- package/src/tool/todo.ts +0 -59
- package/src/tool/todowrite.txt +0 -44
- package/src/tool/todowrite.zh.txt +0 -44
- package/src/tool/tool.ts +0 -183
- package/src/tool/truncate.ts +0 -158
- package/src/tool/truncation-dir.ts +0 -4
- package/src/tool/webfetch.ts +0 -194
- package/src/tool/webfetch.txt +0 -13
- package/src/tool/webfetch.zh.txt +0 -13
- package/src/tool/websearch.ts +0 -145
- package/src/tool/websearch.txt +0 -14
- package/src/tool/websearch.zh.txt +0 -14
- package/src/tool/write.ts +0 -106
- package/src/tool/write.txt +0 -8
- package/src/tool/write.zh.txt +0 -8
- 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 -1
- 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 -2
- 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 -1
- 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 -654
package/src/format/index.ts
DELETED
|
@@ -1,205 +0,0 @@
|
|
|
1
|
-
import { LayerNode } from "@opencode-ai/core/effect/layer-node"
|
|
2
|
-
import { Effect, Layer, Context, Schema } from "effect"
|
|
3
|
-
import { serviceUse } from "@opencode-ai/core/effect/service-use"
|
|
4
|
-
import { ChildProcess } from "effect/unstable/process"
|
|
5
|
-
import { AppProcess } from "@opencode-ai/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
|
-
export 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 defaultLayer = layer.pipe(
|
|
198
|
-
Layer.provide(Config.defaultLayer),
|
|
199
|
-
Layer.provide(AppProcess.defaultLayer),
|
|
200
|
-
Layer.provide(RuntimeFlags.defaultLayer),
|
|
201
|
-
)
|
|
202
|
-
|
|
203
|
-
export const node = LayerNode.make(layer, [Config.node, AppProcess.node, RuntimeFlags.node])
|
|
204
|
-
|
|
205
|
-
export * as Format from "."
|
package/src/git/index.ts
DELETED
|
@@ -1,350 +0,0 @@
|
|
|
1
|
-
import { LayerNode } from "@opencode-ai/core/effect/layer-node"
|
|
2
|
-
import { AppProcess } from "@opencode-ai/core/process"
|
|
3
|
-
import { Effect, Layer, Context, Stream } from "effect"
|
|
4
|
-
import { ChildProcess } from "effect/unstable/process"
|
|
5
|
-
|
|
6
|
-
const cfg = [
|
|
7
|
-
"--no-optional-locks",
|
|
8
|
-
"-c",
|
|
9
|
-
"core.autocrlf=false",
|
|
10
|
-
"-c",
|
|
11
|
-
"core.fsmonitor=false",
|
|
12
|
-
"-c",
|
|
13
|
-
"core.longpaths=true",
|
|
14
|
-
"-c",
|
|
15
|
-
"core.symlinks=true",
|
|
16
|
-
"-c",
|
|
17
|
-
"core.quotepath=false",
|
|
18
|
-
] as const
|
|
19
|
-
|
|
20
|
-
const out = (result: { text(): string }) => result.text().trim()
|
|
21
|
-
const nuls = (text: string) => text.split("\0").filter(Boolean)
|
|
22
|
-
const fail = (err: unknown) =>
|
|
23
|
-
({
|
|
24
|
-
exitCode: 1,
|
|
25
|
-
text: () => "",
|
|
26
|
-
stdout: Buffer.alloc(0),
|
|
27
|
-
stderr: Buffer.from(err instanceof Error ? err.message : String(err)),
|
|
28
|
-
truncated: false,
|
|
29
|
-
}) satisfies Result
|
|
30
|
-
|
|
31
|
-
export type Kind = "added" | "deleted" | "modified"
|
|
32
|
-
|
|
33
|
-
export type Base = {
|
|
34
|
-
readonly name: string
|
|
35
|
-
readonly ref: string
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
export type Item = {
|
|
39
|
-
readonly file: string
|
|
40
|
-
readonly code: string
|
|
41
|
-
readonly status: Kind
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
export type Stat = {
|
|
45
|
-
readonly file: string
|
|
46
|
-
readonly additions: number
|
|
47
|
-
readonly deletions: number
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
export type Patch = {
|
|
51
|
-
readonly text: string
|
|
52
|
-
readonly truncated: boolean
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
export interface PatchOptions {
|
|
56
|
-
readonly context?: number
|
|
57
|
-
readonly maxOutputBytes?: number
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
export interface Result {
|
|
61
|
-
readonly exitCode: number
|
|
62
|
-
readonly text: () => string
|
|
63
|
-
readonly stdout: Buffer
|
|
64
|
-
readonly stderr: Buffer
|
|
65
|
-
readonly truncated: boolean
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
export interface Options {
|
|
69
|
-
readonly cwd: string
|
|
70
|
-
readonly env?: Record<string, string>
|
|
71
|
-
readonly maxOutputBytes?: number
|
|
72
|
-
readonly stdin?: ChildProcess.CommandInput
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
export interface Interface {
|
|
76
|
-
readonly run: (args: string[], opts: Options) => Effect.Effect<Result>
|
|
77
|
-
readonly branch: (cwd: string) => Effect.Effect<string | undefined>
|
|
78
|
-
readonly prefix: (cwd: string) => Effect.Effect<string>
|
|
79
|
-
readonly defaultBranch: (cwd: string) => Effect.Effect<Base | undefined>
|
|
80
|
-
readonly hasHead: (cwd: string) => Effect.Effect<boolean>
|
|
81
|
-
readonly mergeBase: (cwd: string, base: string, head?: string) => Effect.Effect<string | undefined>
|
|
82
|
-
readonly show: (cwd: string, ref: string, file: string, prefix?: string) => Effect.Effect<string>
|
|
83
|
-
readonly status: (cwd: string) => Effect.Effect<Item[]>
|
|
84
|
-
readonly diff: (cwd: string, ref: string) => Effect.Effect<Item[]>
|
|
85
|
-
readonly stats: (cwd: string, ref: string) => Effect.Effect<Stat[]>
|
|
86
|
-
readonly patch: (cwd: string, ref: string, file: string, options?: PatchOptions) => Effect.Effect<Patch>
|
|
87
|
-
readonly patchAll: (cwd: string, ref: string, options?: PatchOptions) => Effect.Effect<Patch>
|
|
88
|
-
readonly patchUntracked: (cwd: string, file: string, options?: PatchOptions) => Effect.Effect<Patch>
|
|
89
|
-
readonly statUntracked: (cwd: string, file: string) => Effect.Effect<Stat | undefined>
|
|
90
|
-
readonly applyPatch: (cwd: string, patch: string) => Effect.Effect<Result>
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
const kind = (code: string): Kind => {
|
|
94
|
-
if (code === "??") return "added"
|
|
95
|
-
if (code.includes("U")) return "modified"
|
|
96
|
-
if (code.includes("A") && !code.includes("D")) return "added"
|
|
97
|
-
if (code.includes("D") && !code.includes("A")) return "deleted"
|
|
98
|
-
return "modified"
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
export class Service extends Context.Service<Service, Interface>()("@opencode/Git") {}
|
|
102
|
-
|
|
103
|
-
export const layer = Layer.effect(
|
|
104
|
-
Service,
|
|
105
|
-
Effect.gen(function* () {
|
|
106
|
-
const appProcess = yield* AppProcess.Service
|
|
107
|
-
const encoder = new TextEncoder()
|
|
108
|
-
const stdin = (text: string) => Stream.make(encoder.encode(text))
|
|
109
|
-
|
|
110
|
-
const run = Effect.fn("Git.run")(
|
|
111
|
-
function* (args: string[], opts: Options) {
|
|
112
|
-
const result = yield* appProcess.run(
|
|
113
|
-
ChildProcess.make("git", [...cfg, ...args], {
|
|
114
|
-
cwd: opts.cwd,
|
|
115
|
-
env: opts.env,
|
|
116
|
-
extendEnv: true,
|
|
117
|
-
stdin: opts.stdin ?? "ignore",
|
|
118
|
-
stdout: "pipe",
|
|
119
|
-
stderr: "pipe",
|
|
120
|
-
}),
|
|
121
|
-
{ maxOutputBytes: opts.maxOutputBytes },
|
|
122
|
-
)
|
|
123
|
-
return {
|
|
124
|
-
exitCode: result.exitCode,
|
|
125
|
-
text: () => result.stdout.toString("utf8"),
|
|
126
|
-
stdout: result.stdout,
|
|
127
|
-
stderr: result.stderr,
|
|
128
|
-
truncated: result.stdoutTruncated || result.stderrTruncated,
|
|
129
|
-
} satisfies Result
|
|
130
|
-
},
|
|
131
|
-
Effect.catch((err) => Effect.succeed(fail(err))),
|
|
132
|
-
)
|
|
133
|
-
|
|
134
|
-
const text = Effect.fn("Git.text")(function* (args: string[], opts: Options) {
|
|
135
|
-
return (yield* run(args, opts)).text()
|
|
136
|
-
})
|
|
137
|
-
|
|
138
|
-
const lines = Effect.fn("Git.lines")(function* (args: string[], opts: Options) {
|
|
139
|
-
return (yield* text(args, opts))
|
|
140
|
-
.split(/\r?\n/)
|
|
141
|
-
.map((item) => item.trim())
|
|
142
|
-
.filter(Boolean)
|
|
143
|
-
})
|
|
144
|
-
|
|
145
|
-
const refs = Effect.fnUntraced(function* (cwd: string) {
|
|
146
|
-
return yield* lines(["for-each-ref", "--format=%(refname:short)", "refs/heads"], { cwd })
|
|
147
|
-
})
|
|
148
|
-
|
|
149
|
-
const configured = Effect.fnUntraced(function* (cwd: string, list: string[]) {
|
|
150
|
-
const result = yield* run(["config", "init.defaultBranch"], { cwd })
|
|
151
|
-
const name = out(result)
|
|
152
|
-
if (!name || !list.includes(name)) return
|
|
153
|
-
return { name, ref: name } satisfies Base
|
|
154
|
-
})
|
|
155
|
-
|
|
156
|
-
const primary = Effect.fnUntraced(function* (cwd: string) {
|
|
157
|
-
const list = yield* lines(["remote"], { cwd })
|
|
158
|
-
if (list.includes("origin")) return "origin"
|
|
159
|
-
if (list.length === 1) return list[0]
|
|
160
|
-
if (list.includes("upstream")) return "upstream"
|
|
161
|
-
return list[0]
|
|
162
|
-
})
|
|
163
|
-
|
|
164
|
-
const branch = Effect.fn("Git.branch")(function* (cwd: string) {
|
|
165
|
-
const result = yield* run(["symbolic-ref", "--quiet", "--short", "HEAD"], { cwd })
|
|
166
|
-
if (result.exitCode !== 0) return
|
|
167
|
-
const text = out(result)
|
|
168
|
-
return text || undefined
|
|
169
|
-
})
|
|
170
|
-
|
|
171
|
-
const prefix = Effect.fn("Git.prefix")(function* (cwd: string) {
|
|
172
|
-
const result = yield* run(["rev-parse", "--show-prefix"], { cwd })
|
|
173
|
-
if (result.exitCode !== 0) return ""
|
|
174
|
-
return out(result)
|
|
175
|
-
})
|
|
176
|
-
|
|
177
|
-
const defaultBranch = Effect.fn("Git.defaultBranch")(function* (cwd: string) {
|
|
178
|
-
const remote = yield* primary(cwd)
|
|
179
|
-
if (remote) {
|
|
180
|
-
const head = yield* run(["symbolic-ref", `refs/remotes/${remote}/HEAD`], { cwd })
|
|
181
|
-
if (head.exitCode === 0) {
|
|
182
|
-
const ref = out(head).replace(/^refs\/remotes\//, "")
|
|
183
|
-
const name = ref.startsWith(`${remote}/`) ? ref.slice(`${remote}/`.length) : ""
|
|
184
|
-
if (name) return { name, ref } satisfies Base
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
const list = yield* refs(cwd)
|
|
189
|
-
const next = yield* configured(cwd, list)
|
|
190
|
-
if (next) return next
|
|
191
|
-
if (list.includes("main")) return { name: "main", ref: "main" } satisfies Base
|
|
192
|
-
if (list.includes("master")) return { name: "master", ref: "master" } satisfies Base
|
|
193
|
-
})
|
|
194
|
-
|
|
195
|
-
const hasHead = Effect.fn("Git.hasHead")(function* (cwd: string) {
|
|
196
|
-
const result = yield* run(["rev-parse", "--verify", "HEAD"], { cwd })
|
|
197
|
-
return result.exitCode === 0
|
|
198
|
-
})
|
|
199
|
-
|
|
200
|
-
const mergeBase = Effect.fn("Git.mergeBase")(function* (cwd: string, base: string, head = "HEAD") {
|
|
201
|
-
const result = yield* run(["merge-base", base, head], { cwd })
|
|
202
|
-
if (result.exitCode !== 0) return
|
|
203
|
-
const text = out(result)
|
|
204
|
-
return text || undefined
|
|
205
|
-
})
|
|
206
|
-
|
|
207
|
-
const show = Effect.fn("Git.show")(function* (cwd: string, ref: string, file: string, prefix = "") {
|
|
208
|
-
const target = prefix ? `${prefix}${file}` : file
|
|
209
|
-
const result = yield* run(["show", `${ref}:${target}`], { cwd })
|
|
210
|
-
if (result.exitCode !== 0) return ""
|
|
211
|
-
if (result.stdout.includes(0)) return ""
|
|
212
|
-
return result.text()
|
|
213
|
-
})
|
|
214
|
-
|
|
215
|
-
const status = Effect.fn("Git.status")(function* (cwd: string) {
|
|
216
|
-
return nuls(
|
|
217
|
-
yield* text(["status", "--porcelain=v1", "--untracked-files=all", "--no-renames", "-z", "--", "."], {
|
|
218
|
-
cwd,
|
|
219
|
-
}),
|
|
220
|
-
).flatMap((item) => {
|
|
221
|
-
const file = item.slice(3)
|
|
222
|
-
if (!file) return []
|
|
223
|
-
const code = item.slice(0, 2)
|
|
224
|
-
return [{ file, code, status: kind(code) } satisfies Item]
|
|
225
|
-
})
|
|
226
|
-
})
|
|
227
|
-
|
|
228
|
-
const diff = Effect.fn("Git.diff")(function* (cwd: string, ref: string) {
|
|
229
|
-
const list = nuls(
|
|
230
|
-
yield* text(["diff", "--no-ext-diff", "--no-renames", "--name-status", "-z", ref, "--", "."], { cwd }),
|
|
231
|
-
)
|
|
232
|
-
return list.flatMap((code, idx) => {
|
|
233
|
-
if (idx % 2 !== 0) return []
|
|
234
|
-
const file = list[idx + 1]
|
|
235
|
-
if (!code || !file) return []
|
|
236
|
-
return [{ file, code, status: kind(code) } satisfies Item]
|
|
237
|
-
})
|
|
238
|
-
})
|
|
239
|
-
|
|
240
|
-
const stats = Effect.fn("Git.stats")(function* (cwd: string, ref: string) {
|
|
241
|
-
return nuls(
|
|
242
|
-
yield* text(["diff", "--no-ext-diff", "--no-renames", "--numstat", "-z", ref, "--", "."], { cwd }),
|
|
243
|
-
).flatMap((item) => {
|
|
244
|
-
const a = item.indexOf("\t")
|
|
245
|
-
const b = item.indexOf("\t", a + 1)
|
|
246
|
-
if (a === -1 || b === -1) return []
|
|
247
|
-
const file = item.slice(b + 1)
|
|
248
|
-
if (!file) return []
|
|
249
|
-
const adds = item.slice(0, a)
|
|
250
|
-
const dels = item.slice(a + 1, b)
|
|
251
|
-
const additions = adds === "-" ? 0 : Number.parseInt(adds || "0", 10)
|
|
252
|
-
const deletions = dels === "-" ? 0 : Number.parseInt(dels || "0", 10)
|
|
253
|
-
return [
|
|
254
|
-
{
|
|
255
|
-
file,
|
|
256
|
-
additions: Number.isFinite(additions) ? additions : 0,
|
|
257
|
-
deletions: Number.isFinite(deletions) ? deletions : 0,
|
|
258
|
-
} satisfies Stat,
|
|
259
|
-
]
|
|
260
|
-
})
|
|
261
|
-
})
|
|
262
|
-
|
|
263
|
-
const patch = Effect.fn("Git.patch")(function* (cwd: string, ref: string, file: string, options?: PatchOptions) {
|
|
264
|
-
const result = yield* run(
|
|
265
|
-
["diff", "--patch", "--no-ext-diff", "--no-renames", `--unified=${options?.context ?? 3}`, ref, "--", file],
|
|
266
|
-
{ cwd, maxOutputBytes: options?.maxOutputBytes },
|
|
267
|
-
)
|
|
268
|
-
return { text: result.truncated ? "" : result.text(), truncated: result.truncated } satisfies Patch
|
|
269
|
-
})
|
|
270
|
-
|
|
271
|
-
const patchAll = Effect.fn("Git.patchAll")(function* (cwd: string, ref: string, options?: PatchOptions) {
|
|
272
|
-
const result = yield* run(
|
|
273
|
-
["diff", "--patch", "--no-ext-diff", "--no-renames", `--unified=${options?.context ?? 3}`, ref, "--", "."],
|
|
274
|
-
{ cwd, maxOutputBytes: options?.maxOutputBytes },
|
|
275
|
-
)
|
|
276
|
-
return { text: result.text(), truncated: result.truncated } satisfies Patch
|
|
277
|
-
})
|
|
278
|
-
|
|
279
|
-
const patchUntracked = Effect.fn("Git.patchUntracked")(function* (
|
|
280
|
-
cwd: string,
|
|
281
|
-
file: string,
|
|
282
|
-
options?: PatchOptions,
|
|
283
|
-
) {
|
|
284
|
-
const result = yield* run(
|
|
285
|
-
[
|
|
286
|
-
"diff",
|
|
287
|
-
"--no-index",
|
|
288
|
-
"--patch",
|
|
289
|
-
"--no-ext-diff",
|
|
290
|
-
"--no-renames",
|
|
291
|
-
`--unified=${options?.context ?? 3}`,
|
|
292
|
-
"--",
|
|
293
|
-
"/dev/null",
|
|
294
|
-
file,
|
|
295
|
-
],
|
|
296
|
-
{ cwd, maxOutputBytes: options?.maxOutputBytes },
|
|
297
|
-
)
|
|
298
|
-
return { text: result.truncated ? "" : result.text(), truncated: result.truncated } satisfies Patch
|
|
299
|
-
})
|
|
300
|
-
|
|
301
|
-
const statUntracked = Effect.fn("Git.statUntracked")(function* (cwd: string, file: string) {
|
|
302
|
-
const result = yield* run(["diff", "--no-index", "--numstat", "--", "/dev/null", file], {
|
|
303
|
-
cwd,
|
|
304
|
-
maxOutputBytes: 4096,
|
|
305
|
-
})
|
|
306
|
-
|
|
307
|
-
if (result.truncated) return
|
|
308
|
-
const text = result.text()
|
|
309
|
-
|
|
310
|
-
const parts = text.split("\t")
|
|
311
|
-
if (parts.length < 2) return
|
|
312
|
-
|
|
313
|
-
const additions = parts[0] === "-" ? 0 : Number.parseInt(parts[0] || "0", 10)
|
|
314
|
-
const deletions = parts[1] === "-" ? 0 : Number.parseInt(parts[1] || "0", 10)
|
|
315
|
-
return {
|
|
316
|
-
file,
|
|
317
|
-
additions: Number.isFinite(additions) ? additions : 0,
|
|
318
|
-
deletions: Number.isFinite(deletions) ? deletions : 0,
|
|
319
|
-
} satisfies Stat
|
|
320
|
-
})
|
|
321
|
-
|
|
322
|
-
const applyPatch = Effect.fn("Git.applyPatch")(function* (cwd: string, patch: string) {
|
|
323
|
-
return yield* run(["apply", "-"], { cwd, stdin: stdin(patch) })
|
|
324
|
-
})
|
|
325
|
-
|
|
326
|
-
return Service.of({
|
|
327
|
-
run,
|
|
328
|
-
branch,
|
|
329
|
-
prefix,
|
|
330
|
-
defaultBranch,
|
|
331
|
-
hasHead,
|
|
332
|
-
mergeBase,
|
|
333
|
-
show,
|
|
334
|
-
status,
|
|
335
|
-
diff,
|
|
336
|
-
stats,
|
|
337
|
-
patch,
|
|
338
|
-
patchAll,
|
|
339
|
-
patchUntracked,
|
|
340
|
-
statUntracked,
|
|
341
|
-
applyPatch,
|
|
342
|
-
})
|
|
343
|
-
}),
|
|
344
|
-
)
|
|
345
|
-
|
|
346
|
-
export const defaultLayer = layer.pipe(Layer.provide(AppProcess.defaultLayer))
|
|
347
|
-
|
|
348
|
-
export const node = LayerNode.make(layer, [AppProcess.node])
|
|
349
|
-
|
|
350
|
-
export * as Git from "."
|
package/src/id/id.ts
DELETED
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
import { randomBytes } from "crypto"
|
|
2
|
-
|
|
3
|
-
const prefixes = {
|
|
4
|
-
job: "job",
|
|
5
|
-
event: "evt",
|
|
6
|
-
session: "ses",
|
|
7
|
-
message: "msg",
|
|
8
|
-
permission: "per",
|
|
9
|
-
question: "que",
|
|
10
|
-
part: "prt",
|
|
11
|
-
pty: "pty",
|
|
12
|
-
tool: "tool",
|
|
13
|
-
workspace: "wrk",
|
|
14
|
-
} as const
|
|
15
|
-
|
|
16
|
-
const LENGTH = 26
|
|
17
|
-
|
|
18
|
-
// State for monotonic ID generation
|
|
19
|
-
let lastTimestamp = 0
|
|
20
|
-
let counter = 0
|
|
21
|
-
|
|
22
|
-
export function ascending(prefix: keyof typeof prefixes, given?: string) {
|
|
23
|
-
return generateID(prefix, "ascending", given)
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export function descending(prefix: keyof typeof prefixes, given?: string) {
|
|
27
|
-
return generateID(prefix, "descending", given)
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
function generateID(prefix: keyof typeof prefixes, direction: "descending" | "ascending", given?: string): string {
|
|
31
|
-
if (!given) {
|
|
32
|
-
return create(prefixes[prefix], direction)
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
if (!given.startsWith(prefixes[prefix])) {
|
|
36
|
-
throw new Error(`ID ${given} does not start with ${prefixes[prefix]}`)
|
|
37
|
-
}
|
|
38
|
-
return given
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
function randomBase62(length: number): string {
|
|
42
|
-
const chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
|
|
43
|
-
let result = ""
|
|
44
|
-
const bytes = randomBytes(length)
|
|
45
|
-
for (let i = 0; i < length; i++) {
|
|
46
|
-
result += chars[bytes[i] % 62]
|
|
47
|
-
}
|
|
48
|
-
return result
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
export function create(prefix: string, direction: "descending" | "ascending", timestamp?: number): string {
|
|
52
|
-
const currentTimestamp = timestamp ?? Date.now()
|
|
53
|
-
|
|
54
|
-
if (currentTimestamp !== lastTimestamp) {
|
|
55
|
-
lastTimestamp = currentTimestamp
|
|
56
|
-
counter = 0
|
|
57
|
-
}
|
|
58
|
-
counter++
|
|
59
|
-
|
|
60
|
-
let now = BigInt(currentTimestamp) * BigInt(0x1000) + BigInt(counter)
|
|
61
|
-
|
|
62
|
-
now = direction === "descending" ? ~now : now
|
|
63
|
-
|
|
64
|
-
const timeBytes = Buffer.alloc(6)
|
|
65
|
-
for (let i = 0; i < 6; i++) {
|
|
66
|
-
timeBytes[i] = Number((now >> BigInt(40 - 8 * i)) & BigInt(0xff))
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
return prefix + "_" + timeBytes.toString("hex") + randomBase62(LENGTH - 12)
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
/** Extract timestamp from an ascending ID. Does not work with descending IDs. */
|
|
73
|
-
export function timestamp(id: string): number {
|
|
74
|
-
const prefix = id.split("_")[0]
|
|
75
|
-
const hex = id.slice(prefix.length + 1, prefix.length + 13)
|
|
76
|
-
const encoded = BigInt("0x" + hex)
|
|
77
|
-
return Number(encoded / BigInt(0x1000))
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
export * as Identifier from "./id"
|
package/src/ide/index.ts
DELETED
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
import { EventV2 } from "@opencode-ai/core/event"
|
|
2
|
-
import { Schema } from "effect"
|
|
3
|
-
import { NamedError } from "@opencode-ai/core/util/error"
|
|
4
|
-
import { Process } from "@/util/process"
|
|
5
|
-
|
|
6
|
-
const SUPPORTED_IDES = [
|
|
7
|
-
{ name: "Windsurf" as const, cmd: "windsurf" },
|
|
8
|
-
{ name: "Visual Studio Code - Insiders" as const, cmd: "code-insiders" },
|
|
9
|
-
{ name: "Visual Studio Code" as const, cmd: "code" },
|
|
10
|
-
{ name: "Cursor" as const, cmd: "cursor" },
|
|
11
|
-
{ name: "VSCodium" as const, cmd: "codium" },
|
|
12
|
-
]
|
|
13
|
-
|
|
14
|
-
export const Event = {
|
|
15
|
-
Installed: EventV2.define({
|
|
16
|
-
type: "ide.installed",
|
|
17
|
-
schema: {
|
|
18
|
-
ide: Schema.String,
|
|
19
|
-
},
|
|
20
|
-
}),
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export const AlreadyInstalledError = NamedError.create("AlreadyInstalledError", {})
|
|
24
|
-
|
|
25
|
-
export const InstallFailedError = NamedError.create("InstallFailedError", {
|
|
26
|
-
stderr: Schema.String,
|
|
27
|
-
})
|
|
28
|
-
|
|
29
|
-
export function ide() {
|
|
30
|
-
if (process.env["TERM_PROGRAM"] === "vscode") {
|
|
31
|
-
const v = process.env["GIT_ASKPASS"]
|
|
32
|
-
for (const ide of SUPPORTED_IDES) {
|
|
33
|
-
if (v?.includes(ide.name)) return ide.name
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
return "unknown"
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
export function alreadyInstalled() {
|
|
40
|
-
return process.env["OPENCODE_CALLER"] === "vscode" || process.env["OPENCODE_CALLER"] === "vscode-insiders"
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
export async function install(ide: (typeof SUPPORTED_IDES)[number]["name"]) {
|
|
44
|
-
const cmd = SUPPORTED_IDES.find((i) => i.name === ide)?.cmd
|
|
45
|
-
if (!cmd) throw new Error(`Unknown IDE: ${ide}`)
|
|
46
|
-
|
|
47
|
-
const p = await Process.run([cmd, "--install-extension", "sst-dev.opencode"], {
|
|
48
|
-
nothrow: true,
|
|
49
|
-
})
|
|
50
|
-
const stdout = p.stdout.toString()
|
|
51
|
-
const stderr = p.stderr.toString()
|
|
52
|
-
|
|
53
|
-
if (p.code !== 0) {
|
|
54
|
-
throw new InstallFailedError({ stderr })
|
|
55
|
-
}
|
|
56
|
-
if (stdout.includes("already installed")) {
|
|
57
|
-
throw new AlreadyInstalledError({})
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
export * as Ide from "."
|