@bloxystudios/bloxycode 1.0.1 → 1.0.4
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/bloxycode +11 -8
- package/package.json +16 -130
- package/postinstall.mjs +129 -0
- package/LICENSE +0 -21
- package/README.md +0 -272
- package/src/acp/README.md +0 -164
- package/src/acp/agent.ts +0 -1437
- package/src/acp/session.ts +0 -105
- package/src/acp/types.ts +0 -22
- package/src/agent/agent.ts +0 -356
- package/src/agent/generate.txt +0 -75
- package/src/agent/prompt/bloxy.txt +0 -46
- package/src/agent/prompt/compaction.txt +0 -12
- 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/auth/index.ts +0 -73
- package/src/bloxy/event.ts +0 -41
- package/src/bloxy/index.ts +0 -5
- package/src/bloxy/parser.ts +0 -263
- package/src/bloxy/prompt.ts +0 -121
- package/src/bloxy/runner.ts +0 -193
- package/src/bloxy/state.ts +0 -246
- package/src/bun/index.ts +0 -134
- package/src/bus/bus-event.ts +0 -43
- package/src/bus/global.ts +0 -10
- package/src/bus/index.ts +0 -105
- package/src/cli/bootstrap.ts +0 -17
- package/src/cli/cmd/acp.ts +0 -69
- package/src/cli/cmd/agent.ts +0 -257
- package/src/cli/cmd/auth.ts +0 -400
- package/src/cli/cmd/cmd.ts +0 -7
- package/src/cli/cmd/debug/agent.ts +0 -167
- package/src/cli/cmd/debug/config.ts +0 -16
- package/src/cli/cmd/debug/file.ts +0 -97
- package/src/cli/cmd/debug/index.ts +0 -48
- package/src/cli/cmd/debug/lsp.ts +0 -52
- package/src/cli/cmd/debug/ripgrep.ts +0 -87
- package/src/cli/cmd/debug/scrap.ts +0 -16
- package/src/cli/cmd/debug/skill.ts +0 -16
- package/src/cli/cmd/debug/snapshot.ts +0 -52
- package/src/cli/cmd/export.ts +0 -88
- package/src/cli/cmd/generate.ts +0 -38
- package/src/cli/cmd/github.ts +0 -1548
- package/src/cli/cmd/import.ts +0 -98
- package/src/cli/cmd/mcp.ts +0 -755
- package/src/cli/cmd/models.ts +0 -77
- package/src/cli/cmd/pr.ts +0 -112
- package/src/cli/cmd/run.ts +0 -395
- package/src/cli/cmd/serve.ts +0 -20
- package/src/cli/cmd/session.ts +0 -135
- package/src/cli/cmd/stats.ts +0 -402
- package/src/cli/cmd/tui/app.tsx +0 -771
- package/src/cli/cmd/tui/attach.ts +0 -39
- package/src/cli/cmd/tui/component/border.tsx +0 -21
- package/src/cli/cmd/tui/component/dialog-agent.tsx +0 -31
- package/src/cli/cmd/tui/component/dialog-command.tsx +0 -148
- package/src/cli/cmd/tui/component/dialog-mcp.tsx +0 -86
- package/src/cli/cmd/tui/component/dialog-model.tsx +0 -234
- package/src/cli/cmd/tui/component/dialog-provider.tsx +0 -256
- package/src/cli/cmd/tui/component/dialog-session-list.tsx +0 -114
- package/src/cli/cmd/tui/component/dialog-session-rename.tsx +0 -31
- package/src/cli/cmd/tui/component/dialog-stash.tsx +0 -87
- package/src/cli/cmd/tui/component/dialog-status.tsx +0 -164
- package/src/cli/cmd/tui/component/dialog-tag.tsx +0 -44
- package/src/cli/cmd/tui/component/dialog-theme-list.tsx +0 -50
- package/src/cli/cmd/tui/component/logo.tsx +0 -102
- package/src/cli/cmd/tui/component/prompt/autocomplete.tsx +0 -653
- package/src/cli/cmd/tui/component/prompt/frecency.tsx +0 -89
- package/src/cli/cmd/tui/component/prompt/history.tsx +0 -108
- package/src/cli/cmd/tui/component/prompt/index.tsx +0 -1138
- package/src/cli/cmd/tui/component/prompt/stash.tsx +0 -101
- package/src/cli/cmd/tui/component/textarea-keybindings.ts +0 -73
- package/src/cli/cmd/tui/component/tips.tsx +0 -153
- package/src/cli/cmd/tui/component/todo-item.tsx +0 -32
- package/src/cli/cmd/tui/context/args.tsx +0 -14
- package/src/cli/cmd/tui/context/directory.ts +0 -13
- package/src/cli/cmd/tui/context/exit.tsx +0 -23
- package/src/cli/cmd/tui/context/helper.tsx +0 -25
- package/src/cli/cmd/tui/context/keybind.tsx +0 -101
- package/src/cli/cmd/tui/context/kv.tsx +0 -52
- package/src/cli/cmd/tui/context/local.tsx +0 -402
- package/src/cli/cmd/tui/context/prompt.tsx +0 -18
- package/src/cli/cmd/tui/context/route.tsx +0 -46
- package/src/cli/cmd/tui/context/sdk.tsx +0 -94
- package/src/cli/cmd/tui/context/sync.tsx +0 -470
- package/src/cli/cmd/tui/context/theme/aura.json +0 -69
- package/src/cli/cmd/tui/context/theme/ayu.json +0 -80
- package/src/cli/cmd/tui/context/theme/bloxycode.json +0 -245
- package/src/cli/cmd/tui/context/theme/carbonfox.json +0 -248
- package/src/cli/cmd/tui/context/theme/catppuccin-frappe.json +0 -233
- package/src/cli/cmd/tui/context/theme/catppuccin-macchiato.json +0 -233
- package/src/cli/cmd/tui/context/theme/catppuccin.json +0 -112
- package/src/cli/cmd/tui/context/theme/cobalt2.json +0 -228
- package/src/cli/cmd/tui/context/theme/cursor.json +0 -249
- package/src/cli/cmd/tui/context/theme/dracula.json +0 -219
- package/src/cli/cmd/tui/context/theme/everforest.json +0 -241
- package/src/cli/cmd/tui/context/theme/flexoki.json +0 -237
- package/src/cli/cmd/tui/context/theme/github.json +0 -233
- package/src/cli/cmd/tui/context/theme/gruvbox.json +0 -242
- package/src/cli/cmd/tui/context/theme/kanagawa.json +0 -77
- package/src/cli/cmd/tui/context/theme/lucent-orng.json +0 -237
- package/src/cli/cmd/tui/context/theme/material.json +0 -235
- package/src/cli/cmd/tui/context/theme/matrix.json +0 -77
- package/src/cli/cmd/tui/context/theme/mercury.json +0 -252
- package/src/cli/cmd/tui/context/theme/monokai.json +0 -221
- package/src/cli/cmd/tui/context/theme/nightowl.json +0 -221
- package/src/cli/cmd/tui/context/theme/nord.json +0 -223
- package/src/cli/cmd/tui/context/theme/one-dark.json +0 -84
- package/src/cli/cmd/tui/context/theme/orng.json +0 -249
- package/src/cli/cmd/tui/context/theme/osaka-jade.json +0 -93
- package/src/cli/cmd/tui/context/theme/palenight.json +0 -222
- package/src/cli/cmd/tui/context/theme/rosepine.json +0 -234
- package/src/cli/cmd/tui/context/theme/solarized.json +0 -223
- package/src/cli/cmd/tui/context/theme/synthwave84.json +0 -226
- package/src/cli/cmd/tui/context/theme/tokyonight.json +0 -243
- package/src/cli/cmd/tui/context/theme/vercel.json +0 -245
- package/src/cli/cmd/tui/context/theme/vesper.json +0 -218
- package/src/cli/cmd/tui/context/theme/zenburn.json +0 -223
- package/src/cli/cmd/tui/context/theme.tsx +0 -1152
- package/src/cli/cmd/tui/event.ts +0 -48
- package/src/cli/cmd/tui/routes/home.tsx +0 -140
- package/src/cli/cmd/tui/routes/session/dialog-fork-from-timeline.tsx +0 -64
- package/src/cli/cmd/tui/routes/session/dialog-message.tsx +0 -109
- package/src/cli/cmd/tui/routes/session/dialog-subagent.tsx +0 -26
- package/src/cli/cmd/tui/routes/session/dialog-timeline.tsx +0 -47
- package/src/cli/cmd/tui/routes/session/footer.tsx +0 -91
- package/src/cli/cmd/tui/routes/session/header.tsx +0 -142
- package/src/cli/cmd/tui/routes/session/index.tsx +0 -2048
- package/src/cli/cmd/tui/routes/session/permission.tsx +0 -508
- package/src/cli/cmd/tui/routes/session/question.tsx +0 -453
- package/src/cli/cmd/tui/routes/session/sidebar.tsx +0 -313
- package/src/cli/cmd/tui/thread.ts +0 -165
- package/src/cli/cmd/tui/ui/dialog-alert.tsx +0 -57
- package/src/cli/cmd/tui/ui/dialog-confirm.tsx +0 -83
- package/src/cli/cmd/tui/ui/dialog-export-options.tsx +0 -204
- package/src/cli/cmd/tui/ui/dialog-help.tsx +0 -38
- package/src/cli/cmd/tui/ui/dialog-prompt.tsx +0 -77
- package/src/cli/cmd/tui/ui/dialog-select.tsx +0 -385
- package/src/cli/cmd/tui/ui/dialog.tsx +0 -167
- package/src/cli/cmd/tui/ui/link.tsx +0 -28
- package/src/cli/cmd/tui/ui/spinner.ts +0 -368
- package/src/cli/cmd/tui/ui/toast.tsx +0 -100
- package/src/cli/cmd/tui/util/clipboard.ts +0 -160
- package/src/cli/cmd/tui/util/editor.ts +0 -32
- package/src/cli/cmd/tui/util/signal.ts +0 -7
- package/src/cli/cmd/tui/util/terminal.ts +0 -114
- package/src/cli/cmd/tui/util/transcript.ts +0 -98
- package/src/cli/cmd/tui/worker.ts +0 -152
- package/src/cli/cmd/uninstall.ts +0 -357
- package/src/cli/cmd/upgrade.ts +0 -73
- package/src/cli/cmd/web.ts +0 -81
- package/src/cli/error.ts +0 -57
- package/src/cli/network.ts +0 -53
- package/src/cli/ui.ts +0 -86
- package/src/cli/upgrade.ts +0 -25
- package/src/command/index.ts +0 -173
- package/src/command/template/bloxy-resume.txt +0 -15
- package/src/command/template/bloxy-status.txt +0 -25
- package/src/command/template/bloxy-validate.txt +0 -22
- package/src/command/template/bloxy.txt +0 -14
- package/src/command/template/initialize.txt +0 -10
- package/src/command/template/review.txt +0 -99
- package/src/config/config.ts +0 -1367
- package/src/config/markdown.ts +0 -93
- package/src/env/index.ts +0 -26
- package/src/file/ignore.ts +0 -83
- package/src/file/index.ts +0 -415
- package/src/file/ripgrep.ts +0 -407
- package/src/file/time.ts +0 -69
- package/src/file/watcher.ts +0 -127
- package/src/flag/flag.ts +0 -79
- package/src/format/formatter.ts +0 -357
- package/src/format/index.ts +0 -137
- package/src/global/index.ts +0 -55
- package/src/id/id.ts +0 -83
- package/src/ide/index.ts +0 -76
- package/src/index.ts +0 -159
- package/src/installation/index.ts +0 -246
- package/src/lsp/client.ts +0 -252
- package/src/lsp/index.ts +0 -485
- package/src/lsp/language.ts +0 -119
- package/src/lsp/server.ts +0 -2046
- package/src/mcp/auth.ts +0 -135
- package/src/mcp/index.ts +0 -934
- package/src/mcp/oauth-callback.ts +0 -200
- package/src/mcp/oauth-provider.ts +0 -154
- package/src/patch/index.ts +0 -680
- package/src/permission/arity.ts +0 -163
- package/src/permission/index.ts +0 -210
- package/src/permission/next.ts +0 -280
- package/src/plugin/antigravity.ts +0 -378
- package/src/plugin/codex.ts +0 -506
- package/src/plugin/copilot.ts +0 -298
- package/src/plugin/index.ts +0 -136
- package/src/project/bootstrap.ts +0 -35
- package/src/project/instance.ts +0 -91
- package/src/project/project.ts +0 -371
- package/src/project/state.ts +0 -66
- package/src/project/vcs.ts +0 -76
- package/src/provider/auth.ts +0 -147
- package/src/provider/models-snapshot.ts +0 -2
- package/src/provider/models.ts +0 -133
- package/src/provider/provider.ts +0 -1241
- package/src/provider/sdk/openai-compatible/src/README.md +0 -5
- package/src/provider/sdk/openai-compatible/src/index.ts +0 -2
- package/src/provider/sdk/openai-compatible/src/openai-compatible-provider.ts +0 -100
- package/src/provider/sdk/openai-compatible/src/responses/convert-to-openai-responses-input.ts +0 -303
- package/src/provider/sdk/openai-compatible/src/responses/map-openai-responses-finish-reason.ts +0 -22
- package/src/provider/sdk/openai-compatible/src/responses/openai-config.ts +0 -18
- package/src/provider/sdk/openai-compatible/src/responses/openai-error.ts +0 -22
- package/src/provider/sdk/openai-compatible/src/responses/openai-responses-api-types.ts +0 -207
- package/src/provider/sdk/openai-compatible/src/responses/openai-responses-language-model.ts +0 -1732
- package/src/provider/sdk/openai-compatible/src/responses/openai-responses-prepare-tools.ts +0 -177
- package/src/provider/sdk/openai-compatible/src/responses/openai-responses-settings.ts +0 -1
- package/src/provider/sdk/openai-compatible/src/responses/tool/code-interpreter.ts +0 -88
- package/src/provider/sdk/openai-compatible/src/responses/tool/file-search.ts +0 -128
- package/src/provider/sdk/openai-compatible/src/responses/tool/image-generation.ts +0 -115
- package/src/provider/sdk/openai-compatible/src/responses/tool/local-shell.ts +0 -65
- package/src/provider/sdk/openai-compatible/src/responses/tool/web-search-preview.ts +0 -104
- package/src/provider/sdk/openai-compatible/src/responses/tool/web-search.ts +0 -103
- package/src/provider/transform.ts +0 -741
- package/src/pty/index.ts +0 -241
- package/src/question/index.ts +0 -171
- package/src/scheduler/index.ts +0 -61
- package/src/server/error.ts +0 -36
- package/src/server/event.ts +0 -7
- package/src/server/mdns.ts +0 -59
- package/src/server/routes/config.ts +0 -92
- package/src/server/routes/experimental.ts +0 -208
- package/src/server/routes/file.ts +0 -197
- package/src/server/routes/global.ts +0 -135
- package/src/server/routes/mcp.ts +0 -225
- package/src/server/routes/permission.ts +0 -68
- package/src/server/routes/project.ts +0 -82
- package/src/server/routes/provider.ts +0 -165
- package/src/server/routes/pty.ts +0 -169
- package/src/server/routes/question.ts +0 -98
- package/src/server/routes/session.ts +0 -939
- package/src/server/routes/tui.ts +0 -379
- package/src/server/server.ts +0 -604
- package/src/session/compaction.ts +0 -225
- package/src/session/fallback.ts +0 -246
- package/src/session/index.ts +0 -498
- package/src/session/instruction.ts +0 -164
- package/src/session/llm.ts +0 -298
- package/src/session/message-v2.ts +0 -747
- package/src/session/message.ts +0 -189
- package/src/session/processor.ts +0 -450
- package/src/session/prompt/anthropic-20250930.txt +0 -166
- package/src/session/prompt/anthropic.txt +0 -105
- package/src/session/prompt/beast.txt +0 -147
- package/src/session/prompt/build-switch.txt +0 -5
- package/src/session/prompt/codex_header.txt +0 -79
- package/src/session/prompt/copilot-gpt-5.txt +0 -143
- package/src/session/prompt/gemini.txt +0 -155
- package/src/session/prompt/max-steps.txt +0 -16
- package/src/session/prompt/plan-reminder-anthropic.txt +0 -67
- package/src/session/prompt/plan.txt +0 -26
- package/src/session/prompt/qwen.txt +0 -109
- package/src/session/prompt.ts +0 -1822
- package/src/session/retry.ts +0 -99
- package/src/session/revert.ts +0 -121
- package/src/session/status.ts +0 -100
- package/src/session/summary.ts +0 -217
- package/src/session/system.ts +0 -52
- package/src/session/todo.ts +0 -37
- package/src/share/share-next.ts +0 -200
- package/src/share/share.ts +0 -92
- package/src/shell/shell.ts +0 -67
- package/src/skill/index.ts +0 -1
- package/src/skill/skill.ts +0 -135
- package/src/snapshot/index.ts +0 -236
- package/src/storage/storage.ts +0 -227
- package/src/tool/apply_patch.ts +0 -281
- package/src/tool/apply_patch.txt +0 -33
- package/src/tool/bash.ts +0 -258
- package/src/tool/bash.txt +0 -115
- package/src/tool/batch.ts +0 -175
- package/src/tool/batch.txt +0 -24
- package/src/tool/bloxy-control.ts +0 -123
- package/src/tool/bloxy-control.txt +0 -13
- package/src/tool/codesearch.ts +0 -132
- package/src/tool/codesearch.txt +0 -12
- package/src/tool/edit.ts +0 -655
- package/src/tool/edit.txt +0 -10
- package/src/tool/external-directory.ts +0 -32
- package/src/tool/glob.ts +0 -77
- package/src/tool/glob.txt +0 -6
- package/src/tool/grep.ts +0 -154
- package/src/tool/grep.txt +0 -8
- package/src/tool/invalid.ts +0 -17
- package/src/tool/ls.ts +0 -121
- package/src/tool/ls.txt +0 -1
- package/src/tool/lsp.ts +0 -96
- package/src/tool/lsp.txt +0 -19
- package/src/tool/multiedit.ts +0 -46
- package/src/tool/multiedit.txt +0 -41
- package/src/tool/plan-enter.txt +0 -14
- package/src/tool/plan-exit.txt +0 -13
- package/src/tool/plan.ts +0 -130
- package/src/tool/question.ts +0 -33
- package/src/tool/question.txt +0 -10
- package/src/tool/read.ts +0 -211
- package/src/tool/read.txt +0 -12
- package/src/tool/registry.ts +0 -161
- package/src/tool/skill.ts +0 -82
- package/src/tool/task.ts +0 -191
- package/src/tool/task.txt +0 -60
- package/src/tool/todo.ts +0 -53
- package/src/tool/todoread.txt +0 -14
- package/src/tool/todowrite.txt +0 -167
- package/src/tool/tool.ts +0 -89
- package/src/tool/truncation.ts +0 -106
- package/src/tool/webfetch.ts +0 -188
- package/src/tool/webfetch.txt +0 -13
- package/src/tool/websearch.ts +0 -150
- package/src/tool/websearch.txt +0 -14
- package/src/tool/write.ts +0 -85
- package/src/tool/write.txt +0 -8
- package/src/util/archive.ts +0 -16
- package/src/util/binary.ts +0 -41
- package/src/util/color.ts +0 -19
- package/src/util/context.ts +0 -25
- package/src/util/defer.ts +0 -12
- package/src/util/error.ts +0 -54
- package/src/util/eventloop.ts +0 -20
- package/src/util/filesystem.ts +0 -93
- package/src/util/fn.ts +0 -11
- package/src/util/format.ts +0 -20
- package/src/util/iife.ts +0 -3
- package/src/util/keybind.ts +0 -103
- package/src/util/lazy.ts +0 -23
- package/src/util/locale.ts +0 -81
- package/src/util/lock.ts +0 -98
- package/src/util/log.ts +0 -180
- package/src/util/queue.ts +0 -32
- package/src/util/rpc.ts +0 -66
- package/src/util/scrap.ts +0 -10
- package/src/util/signal.ts +0 -12
- package/src/util/slug.ts +0 -74
- package/src/util/timeout.ts +0 -14
- package/src/util/token.ts +0 -7
- package/src/util/wildcard.ts +0 -56
- package/src/worktree/index.ts +0 -549
|
@@ -1,378 +0,0 @@
|
|
|
1
|
-
import type { Hooks, PluginInput } from "@opencode-ai/plugin"
|
|
2
|
-
import { Installation } from "@/installation"
|
|
3
|
-
import { Global } from "@/global"
|
|
4
|
-
import path from "path"
|
|
5
|
-
import fs from "fs/promises"
|
|
6
|
-
import z from "zod"
|
|
7
|
-
|
|
8
|
-
// Google OAuth configuration for Antigravity
|
|
9
|
-
const GOOGLE_CLIENT_ID = "77185425430.apps.googleusercontent.com"
|
|
10
|
-
const GOOGLE_CLIENT_SECRET = "OTJgUOQcT7lO7GsGZq2G4IlT"
|
|
11
|
-
const GOOGLE_DEVICE_AUTH_URL = "https://oauth2.googleapis.com/device/code"
|
|
12
|
-
const GOOGLE_TOKEN_URL = "https://oauth2.googleapis.com/token"
|
|
13
|
-
const ANTIGRAVITY_API_BASE = "https://autopush-aicompanion-pa.sandbox.googleapis.com"
|
|
14
|
-
|
|
15
|
-
// Account storage schema
|
|
16
|
-
const AntigravityAccountSchema = z.object({
|
|
17
|
-
email: z.string(),
|
|
18
|
-
refreshToken: z.string(),
|
|
19
|
-
accessToken: z.string().optional(),
|
|
20
|
-
accessTokenExpiry: z.number().optional(),
|
|
21
|
-
projectId: z.string().optional(),
|
|
22
|
-
rateLimitedUntil: z.number().optional(),
|
|
23
|
-
enabled: z.boolean().default(true),
|
|
24
|
-
})
|
|
25
|
-
type AntigravityAccount = z.infer<typeof AntigravityAccountSchema>
|
|
26
|
-
|
|
27
|
-
const AntigravityAccountsSchema = z.object({
|
|
28
|
-
accounts: z.array(AntigravityAccountSchema),
|
|
29
|
-
currentIndex: z.number().default(0),
|
|
30
|
-
})
|
|
31
|
-
type AntigravityAccountsData = z.infer<typeof AntigravityAccountsSchema>
|
|
32
|
-
|
|
33
|
-
// Accounts file path
|
|
34
|
-
const accountsFilePath = path.join(Global.Path.config, "antigravity-accounts.json")
|
|
35
|
-
|
|
36
|
-
// Account management
|
|
37
|
-
async function loadAccounts(): Promise<AntigravityAccountsData> {
|
|
38
|
-
try {
|
|
39
|
-
const file = Bun.file(accountsFilePath)
|
|
40
|
-
if (await file.exists()) {
|
|
41
|
-
const data = await file.json()
|
|
42
|
-
return AntigravityAccountsSchema.parse(data)
|
|
43
|
-
}
|
|
44
|
-
} catch {}
|
|
45
|
-
return { accounts: [], currentIndex: 0 }
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
async function saveAccounts(accounts: AntigravityAccountsData): Promise<void> {
|
|
49
|
-
await Bun.write(accountsFilePath, JSON.stringify(accounts, null, 2))
|
|
50
|
-
await fs.chmod(accountsFilePath, 0o600)
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
async function refreshAccessToken(account: AntigravityAccount): Promise<string | null> {
|
|
54
|
-
try {
|
|
55
|
-
const response = await fetch(GOOGLE_TOKEN_URL, {
|
|
56
|
-
method: "POST",
|
|
57
|
-
headers: {
|
|
58
|
-
"Content-Type": "application/x-www-form-urlencoded",
|
|
59
|
-
},
|
|
60
|
-
body: new URLSearchParams({
|
|
61
|
-
client_id: GOOGLE_CLIENT_ID,
|
|
62
|
-
client_secret: GOOGLE_CLIENT_SECRET,
|
|
63
|
-
refresh_token: account.refreshToken,
|
|
64
|
-
grant_type: "refresh_token",
|
|
65
|
-
}),
|
|
66
|
-
})
|
|
67
|
-
|
|
68
|
-
if (!response.ok) return null
|
|
69
|
-
|
|
70
|
-
const data = (await response.json()) as {
|
|
71
|
-
access_token: string
|
|
72
|
-
expires_in: number
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
account.accessToken = data.access_token
|
|
76
|
-
account.accessTokenExpiry = Date.now() + data.expires_in * 1000 - 60000 // 1 min buffer
|
|
77
|
-
|
|
78
|
-
return data.access_token
|
|
79
|
-
} catch {
|
|
80
|
-
return null
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
async function getValidAccount(): Promise<{ account: AntigravityAccount; index: number } | null> {
|
|
85
|
-
const accounts = await loadAccounts()
|
|
86
|
-
if (accounts.accounts.length === 0) return null
|
|
87
|
-
|
|
88
|
-
const now = Date.now()
|
|
89
|
-
const enabledAccounts = accounts.accounts
|
|
90
|
-
.map((acc: AntigravityAccount, idx: number) => ({ account: acc, index: idx }))
|
|
91
|
-
.filter((item: { account: AntigravityAccount; index: number }) => item.account.enabled)
|
|
92
|
-
|
|
93
|
-
// Try to find an account that's not rate limited
|
|
94
|
-
for (const item of enabledAccounts) {
|
|
95
|
-
if (item.account.rateLimitedUntil && item.account.rateLimitedUntil > now) {
|
|
96
|
-
continue
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
// Check if access token needs refresh
|
|
100
|
-
if (!item.account.accessToken || (item.account.accessTokenExpiry && item.account.accessTokenExpiry < now)) {
|
|
101
|
-
const newToken = await refreshAccessToken(item.account)
|
|
102
|
-
if (!newToken) continue
|
|
103
|
-
await saveAccounts(accounts)
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
return item
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
// All accounts rate limited, find the one that recovers soonest
|
|
110
|
-
type AccountWithIndex = { account: AntigravityAccount; index: number }
|
|
111
|
-
const sortedByRecovery = enabledAccounts
|
|
112
|
-
.filter((item: AccountWithIndex) => item.account.rateLimitedUntil)
|
|
113
|
-
.sort((a: AccountWithIndex, b: AccountWithIndex) => (a.account.rateLimitedUntil || 0) - (b.account.rateLimitedUntil || 0))
|
|
114
|
-
|
|
115
|
-
if (sortedByRecovery.length > 0) {
|
|
116
|
-
const first = sortedByRecovery[0]
|
|
117
|
-
const waitTime = (first.account.rateLimitedUntil || 0) - now
|
|
118
|
-
if (waitTime > 0 && waitTime < 300000) {
|
|
119
|
-
// Wait up to 5 minutes
|
|
120
|
-
await Bun.sleep(waitTime + 1000)
|
|
121
|
-
first.account.rateLimitedUntil = undefined
|
|
122
|
-
await saveAccounts(accounts)
|
|
123
|
-
return first
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
return null
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
async function markAccountRateLimited(index: number, resetAfterMs: number = 60000): Promise<void> {
|
|
131
|
-
const accounts = await loadAccounts()
|
|
132
|
-
if (accounts.accounts[index]) {
|
|
133
|
-
accounts.accounts[index].rateLimitedUntil = Date.now() + resetAfterMs
|
|
134
|
-
await saveAccounts(accounts)
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
export async function AntigravityAuthPlugin(input: PluginInput): Promise<Hooks> {
|
|
139
|
-
return {
|
|
140
|
-
auth: {
|
|
141
|
-
provider: "antigravity",
|
|
142
|
-
async loader(getAuth, provider) {
|
|
143
|
-
const accounts = await loadAccounts()
|
|
144
|
-
if (accounts.accounts.length === 0) return {}
|
|
145
|
-
|
|
146
|
-
if (provider && provider.models) {
|
|
147
|
-
for (const model of Object.values(provider.models)) {
|
|
148
|
-
// Antigravity models are free (use Google quota)
|
|
149
|
-
model.cost = {
|
|
150
|
-
input: 0,
|
|
151
|
-
output: 0,
|
|
152
|
-
cache: { read: 0, write: 0 },
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
return {
|
|
158
|
-
apiKey: "antigravity-oauth",
|
|
159
|
-
async fetch(request: RequestInfo | URL, init?: RequestInit) {
|
|
160
|
-
const accountInfo = await getValidAccount()
|
|
161
|
-
if (!accountInfo) {
|
|
162
|
-
throw new Error("No valid Antigravity accounts available. Run 'bloxycode auth login' to add an account.")
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
const { account, index } = accountInfo
|
|
166
|
-
|
|
167
|
-
const headers: Record<string, string> = {
|
|
168
|
-
...(init?.headers as Record<string, string>),
|
|
169
|
-
Authorization: `Bearer ${account.accessToken}`,
|
|
170
|
-
"User-Agent": `bloxycode/${Installation.VERSION}`,
|
|
171
|
-
"Content-Type": "application/json",
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
// Remove any conflicting auth headers
|
|
175
|
-
delete headers["x-api-key"]
|
|
176
|
-
|
|
177
|
-
const response = await fetch(request, {
|
|
178
|
-
...init,
|
|
179
|
-
headers,
|
|
180
|
-
})
|
|
181
|
-
|
|
182
|
-
// Handle rate limiting
|
|
183
|
-
if (response.status === 429) {
|
|
184
|
-
const retryAfter = response.headers.get("retry-after")
|
|
185
|
-
const resetMs = retryAfter ? parseInt(retryAfter) * 1000 : 60000
|
|
186
|
-
await markAccountRateLimited(index, resetMs)
|
|
187
|
-
|
|
188
|
-
// Try with another account
|
|
189
|
-
const nextAccount = await getValidAccount()
|
|
190
|
-
if (nextAccount && nextAccount.index !== index) {
|
|
191
|
-
headers.Authorization = `Bearer ${nextAccount.account.accessToken}`
|
|
192
|
-
return fetch(request, { ...init, headers })
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
return response
|
|
197
|
-
},
|
|
198
|
-
}
|
|
199
|
-
},
|
|
200
|
-
methods: [
|
|
201
|
-
{
|
|
202
|
-
type: "oauth",
|
|
203
|
-
label: "Login with Google (Antigravity)",
|
|
204
|
-
async authorize() {
|
|
205
|
-
// Google Device Code OAuth flow
|
|
206
|
-
const deviceResponse = await fetch(GOOGLE_DEVICE_AUTH_URL, {
|
|
207
|
-
method: "POST",
|
|
208
|
-
headers: {
|
|
209
|
-
"Content-Type": "application/x-www-form-urlencoded",
|
|
210
|
-
},
|
|
211
|
-
body: new URLSearchParams({
|
|
212
|
-
client_id: GOOGLE_CLIENT_ID,
|
|
213
|
-
scope: "openid email profile https://www.googleapis.com/auth/cloud-platform",
|
|
214
|
-
}),
|
|
215
|
-
})
|
|
216
|
-
|
|
217
|
-
if (!deviceResponse.ok) {
|
|
218
|
-
throw new Error("Failed to initiate Google device authorization")
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
const deviceData = (await deviceResponse.json()) as {
|
|
222
|
-
verification_url: string
|
|
223
|
-
user_code: string
|
|
224
|
-
device_code: string
|
|
225
|
-
interval: number
|
|
226
|
-
expires_in: number
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
return {
|
|
230
|
-
url: deviceData.verification_url,
|
|
231
|
-
instructions: `Enter code: ${deviceData.user_code}`,
|
|
232
|
-
method: "auto" as const,
|
|
233
|
-
async callback() {
|
|
234
|
-
const startTime = Date.now()
|
|
235
|
-
const expiresAt = startTime + deviceData.expires_in * 1000
|
|
236
|
-
|
|
237
|
-
while (Date.now() < expiresAt) {
|
|
238
|
-
const response = await fetch(GOOGLE_TOKEN_URL, {
|
|
239
|
-
method: "POST",
|
|
240
|
-
headers: {
|
|
241
|
-
"Content-Type": "application/x-www-form-urlencoded",
|
|
242
|
-
},
|
|
243
|
-
body: new URLSearchParams({
|
|
244
|
-
client_id: GOOGLE_CLIENT_ID,
|
|
245
|
-
client_secret: GOOGLE_CLIENT_SECRET,
|
|
246
|
-
device_code: deviceData.device_code,
|
|
247
|
-
grant_type: "urn:ietf:params:oauth:grant-type:device_code",
|
|
248
|
-
}),
|
|
249
|
-
})
|
|
250
|
-
|
|
251
|
-
const data = (await response.json()) as {
|
|
252
|
-
access_token?: string
|
|
253
|
-
refresh_token?: string
|
|
254
|
-
expires_in?: number
|
|
255
|
-
id_token?: string
|
|
256
|
-
error?: string
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
if (data.access_token && data.refresh_token) {
|
|
260
|
-
// Get user email from ID token or userinfo
|
|
261
|
-
let email = "unknown"
|
|
262
|
-
try {
|
|
263
|
-
const userInfoResponse = await fetch("https://www.googleapis.com/oauth2/v2/userinfo", {
|
|
264
|
-
headers: { Authorization: `Bearer ${data.access_token}` },
|
|
265
|
-
})
|
|
266
|
-
if (userInfoResponse.ok) {
|
|
267
|
-
const userInfo = (await userInfoResponse.json()) as { email: string }
|
|
268
|
-
email = userInfo.email
|
|
269
|
-
}
|
|
270
|
-
} catch {}
|
|
271
|
-
|
|
272
|
-
// Save to accounts file
|
|
273
|
-
const accounts = await loadAccounts()
|
|
274
|
-
|
|
275
|
-
// Check if account already exists
|
|
276
|
-
const existingIndex = accounts.accounts.findIndex((a: AntigravityAccount) => a.email === email)
|
|
277
|
-
const newAccount: AntigravityAccount = {
|
|
278
|
-
email,
|
|
279
|
-
refreshToken: data.refresh_token,
|
|
280
|
-
accessToken: data.access_token,
|
|
281
|
-
accessTokenExpiry: Date.now() + (data.expires_in || 3600) * 1000 - 60000,
|
|
282
|
-
enabled: true,
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
if (existingIndex >= 0) {
|
|
286
|
-
accounts.accounts[existingIndex] = newAccount
|
|
287
|
-
} else {
|
|
288
|
-
accounts.accounts.push(newAccount)
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
await saveAccounts(accounts)
|
|
292
|
-
|
|
293
|
-
return {
|
|
294
|
-
type: "success" as const,
|
|
295
|
-
refresh: data.refresh_token,
|
|
296
|
-
access: data.access_token,
|
|
297
|
-
expires: Date.now() + (data.expires_in || 3600) * 1000,
|
|
298
|
-
accountId: email,
|
|
299
|
-
}
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
if (data.error === "authorization_pending") {
|
|
303
|
-
await Bun.sleep(deviceData.interval * 1000 + 1000)
|
|
304
|
-
continue
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
if (data.error === "slow_down") {
|
|
308
|
-
await Bun.sleep((deviceData.interval + 5) * 1000)
|
|
309
|
-
continue
|
|
310
|
-
}
|
|
311
|
-
|
|
312
|
-
if (data.error) {
|
|
313
|
-
return { type: "failed" as const }
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
await Bun.sleep(deviceData.interval * 1000)
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
return { type: "failed" as const }
|
|
320
|
-
},
|
|
321
|
-
}
|
|
322
|
-
},
|
|
323
|
-
},
|
|
324
|
-
],
|
|
325
|
-
},
|
|
326
|
-
// Add thinking block support for Claude models via Antigravity
|
|
327
|
-
"chat.headers": async (input, output) => {
|
|
328
|
-
if (!input.model.providerID.includes("antigravity")) return
|
|
329
|
-
|
|
330
|
-
if (input.model.id.includes("claude")) {
|
|
331
|
-
output.headers["anthropic-beta"] = "interleaved-thinking-2025-05-14"
|
|
332
|
-
}
|
|
333
|
-
},
|
|
334
|
-
}
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
// Export account management functions for CLI
|
|
338
|
-
export const AntigravityAccounts = {
|
|
339
|
-
async list(): Promise<Array<{ email: string; enabled: boolean; rateLimited: boolean }>> {
|
|
340
|
-
const accounts = await loadAccounts()
|
|
341
|
-
const now = Date.now()
|
|
342
|
-
return accounts.accounts.map((acc: AntigravityAccount) => ({
|
|
343
|
-
email: acc.email,
|
|
344
|
-
enabled: acc.enabled,
|
|
345
|
-
rateLimited: acc.rateLimitedUntil ? acc.rateLimitedUntil > now : false,
|
|
346
|
-
}))
|
|
347
|
-
},
|
|
348
|
-
|
|
349
|
-
async remove(email: string): Promise<boolean> {
|
|
350
|
-
const accounts = await loadAccounts()
|
|
351
|
-
const index = accounts.accounts.findIndex((a: AntigravityAccount) => a.email === email)
|
|
352
|
-
if (index >= 0) {
|
|
353
|
-
accounts.accounts.splice(index, 1)
|
|
354
|
-
await saveAccounts(accounts)
|
|
355
|
-
return true
|
|
356
|
-
}
|
|
357
|
-
return false
|
|
358
|
-
},
|
|
359
|
-
|
|
360
|
-
async toggle(email: string, enabled: boolean): Promise<boolean> {
|
|
361
|
-
const accounts = await loadAccounts()
|
|
362
|
-
const account = accounts.accounts.find((a: AntigravityAccount) => a.email === email)
|
|
363
|
-
if (account) {
|
|
364
|
-
account.enabled = enabled
|
|
365
|
-
await saveAccounts(accounts)
|
|
366
|
-
return true
|
|
367
|
-
}
|
|
368
|
-
return false
|
|
369
|
-
},
|
|
370
|
-
|
|
371
|
-
async clearRateLimits(): Promise<void> {
|
|
372
|
-
const accounts = await loadAccounts()
|
|
373
|
-
for (const account of accounts.accounts) {
|
|
374
|
-
account.rateLimitedUntil = undefined
|
|
375
|
-
}
|
|
376
|
-
await saveAccounts(accounts)
|
|
377
|
-
},
|
|
378
|
-
}
|