chad-code 1.3.1
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/AGENTS.md +27 -0
- package/Dockerfile +18 -0
- package/README.md +15 -0
- package/README.npm.md +64 -0
- package/bin/chad-code +84 -0
- package/bunfig.toml +7 -0
- package/eslint.config.js +29 -0
- package/package.json +107 -0
- package/parsers-config.ts +253 -0
- package/script/build.ts +167 -0
- package/script/postinstall.mjs +122 -0
- package/script/publish-registries.ts +187 -0
- package/script/publish.ts +93 -0
- package/script/schema.ts +47 -0
- package/src/acp/README.md +164 -0
- package/src/acp/agent.ts +1086 -0
- package/src/acp/session.ts +101 -0
- package/src/acp/types.ts +22 -0
- package/src/agent/agent.ts +253 -0
- package/src/agent/generate.txt +75 -0
- package/src/agent/prompt/compaction.txt +12 -0
- package/src/agent/prompt/explore.txt +18 -0
- package/src/agent/prompt/summary.txt +11 -0
- package/src/agent/prompt/title.txt +36 -0
- package/src/auth/index.ts +70 -0
- package/src/bun/index.ts +130 -0
- package/src/bus/bus-event.ts +43 -0
- package/src/bus/global.ts +10 -0
- package/src/bus/index.ts +105 -0
- package/src/cli/bootstrap.ts +17 -0
- package/src/cli/cmd/acp.ts +69 -0
- package/src/cli/cmd/agent.ts +257 -0
- package/src/cli/cmd/auth.ts +132 -0
- package/src/cli/cmd/cmd.ts +7 -0
- package/src/cli/cmd/debug/agent.ts +28 -0
- package/src/cli/cmd/debug/config.ts +15 -0
- package/src/cli/cmd/debug/file.ts +91 -0
- package/src/cli/cmd/debug/index.ts +45 -0
- package/src/cli/cmd/debug/lsp.ts +48 -0
- package/src/cli/cmd/debug/ripgrep.ts +83 -0
- package/src/cli/cmd/debug/scrap.ts +15 -0
- package/src/cli/cmd/debug/skill.ts +15 -0
- package/src/cli/cmd/debug/snapshot.ts +48 -0
- package/src/cli/cmd/export.ts +88 -0
- package/src/cli/cmd/generate.ts +38 -0
- package/src/cli/cmd/github.ts +32 -0
- package/src/cli/cmd/import.ts +98 -0
- package/src/cli/cmd/mcp.ts +670 -0
- package/src/cli/cmd/models.ts +42 -0
- package/src/cli/cmd/pr.ts +112 -0
- package/src/cli/cmd/run.ts +374 -0
- package/src/cli/cmd/serve.ts +16 -0
- package/src/cli/cmd/session.ts +135 -0
- package/src/cli/cmd/stats.ts +402 -0
- package/src/cli/cmd/tui/app.tsx +705 -0
- package/src/cli/cmd/tui/attach.ts +32 -0
- package/src/cli/cmd/tui/component/border.tsx +21 -0
- package/src/cli/cmd/tui/component/dialog-agent.tsx +31 -0
- package/src/cli/cmd/tui/component/dialog-command.tsx +124 -0
- package/src/cli/cmd/tui/component/dialog-mcp.tsx +86 -0
- package/src/cli/cmd/tui/component/dialog-model.tsx +232 -0
- package/src/cli/cmd/tui/component/dialog-provider.tsx +228 -0
- package/src/cli/cmd/tui/component/dialog-session-list.tsx +115 -0
- package/src/cli/cmd/tui/component/dialog-session-rename.tsx +31 -0
- package/src/cli/cmd/tui/component/dialog-stash.tsx +86 -0
- package/src/cli/cmd/tui/component/dialog-status.tsx +162 -0
- package/src/cli/cmd/tui/component/dialog-tag.tsx +44 -0
- package/src/cli/cmd/tui/component/dialog-theme-list.tsx +50 -0
- package/src/cli/cmd/tui/component/did-you-know.tsx +85 -0
- package/src/cli/cmd/tui/component/logo.tsx +43 -0
- package/src/cli/cmd/tui/component/prompt/autocomplete.tsx +654 -0
- package/src/cli/cmd/tui/component/prompt/history.tsx +108 -0
- package/src/cli/cmd/tui/component/prompt/index.tsx +1078 -0
- package/src/cli/cmd/tui/component/prompt/stash.tsx +101 -0
- package/src/cli/cmd/tui/component/textarea-keybindings.ts +73 -0
- package/src/cli/cmd/tui/component/tips.ts +92 -0
- package/src/cli/cmd/tui/component/todo-item.tsx +32 -0
- package/src/cli/cmd/tui/context/args.tsx +14 -0
- package/src/cli/cmd/tui/context/directory.ts +13 -0
- package/src/cli/cmd/tui/context/exit.tsx +23 -0
- package/src/cli/cmd/tui/context/helper.tsx +25 -0
- package/src/cli/cmd/tui/context/keybind.tsx +101 -0
- package/src/cli/cmd/tui/context/kv.tsx +49 -0
- package/src/cli/cmd/tui/context/local.tsx +392 -0
- package/src/cli/cmd/tui/context/prompt.tsx +18 -0
- package/src/cli/cmd/tui/context/route.tsx +46 -0
- package/src/cli/cmd/tui/context/sdk.tsx +75 -0
- package/src/cli/cmd/tui/context/sync.tsx +384 -0
- package/src/cli/cmd/tui/context/theme/aura.json +69 -0
- package/src/cli/cmd/tui/context/theme/ayu.json +80 -0
- package/src/cli/cmd/tui/context/theme/catppuccin-frappe.json +233 -0
- package/src/cli/cmd/tui/context/theme/catppuccin-macchiato.json +233 -0
- package/src/cli/cmd/tui/context/theme/catppuccin.json +112 -0
- package/src/cli/cmd/tui/context/theme/chad.json +245 -0
- package/src/cli/cmd/tui/context/theme/cobalt2.json +228 -0
- package/src/cli/cmd/tui/context/theme/cursor.json +249 -0
- package/src/cli/cmd/tui/context/theme/dracula.json +219 -0
- package/src/cli/cmd/tui/context/theme/everforest.json +241 -0
- package/src/cli/cmd/tui/context/theme/flexoki.json +237 -0
- package/src/cli/cmd/tui/context/theme/github.json +233 -0
- package/src/cli/cmd/tui/context/theme/gruvbox.json +95 -0
- package/src/cli/cmd/tui/context/theme/kanagawa.json +77 -0
- package/src/cli/cmd/tui/context/theme/lucent-orng.json +227 -0
- package/src/cli/cmd/tui/context/theme/material.json +235 -0
- package/src/cli/cmd/tui/context/theme/matrix.json +77 -0
- package/src/cli/cmd/tui/context/theme/mercury.json +252 -0
- package/src/cli/cmd/tui/context/theme/monokai.json +221 -0
- package/src/cli/cmd/tui/context/theme/nightowl.json +221 -0
- package/src/cli/cmd/tui/context/theme/nord.json +223 -0
- package/src/cli/cmd/tui/context/theme/one-dark.json +84 -0
- package/src/cli/cmd/tui/context/theme/orng.json +245 -0
- package/src/cli/cmd/tui/context/theme/osaka-jade.json +93 -0
- package/src/cli/cmd/tui/context/theme/palenight.json +222 -0
- package/src/cli/cmd/tui/context/theme/rosepine.json +234 -0
- package/src/cli/cmd/tui/context/theme/solarized.json +223 -0
- package/src/cli/cmd/tui/context/theme/synthwave84.json +226 -0
- package/src/cli/cmd/tui/context/theme/tokyonight.json +243 -0
- package/src/cli/cmd/tui/context/theme/vercel.json +245 -0
- package/src/cli/cmd/tui/context/theme/vesper.json +218 -0
- package/src/cli/cmd/tui/context/theme/zenburn.json +223 -0
- package/src/cli/cmd/tui/context/theme.tsx +1137 -0
- package/src/cli/cmd/tui/event.ts +46 -0
- package/src/cli/cmd/tui/routes/home.tsx +138 -0
- package/src/cli/cmd/tui/routes/session/dialog-fork-from-timeline.tsx +64 -0
- package/src/cli/cmd/tui/routes/session/dialog-message.tsx +109 -0
- package/src/cli/cmd/tui/routes/session/dialog-subagent.tsx +26 -0
- package/src/cli/cmd/tui/routes/session/dialog-timeline.tsx +47 -0
- package/src/cli/cmd/tui/routes/session/footer.tsx +88 -0
- package/src/cli/cmd/tui/routes/session/header.tsx +125 -0
- package/src/cli/cmd/tui/routes/session/index.tsx +1814 -0
- package/src/cli/cmd/tui/routes/session/permission.tsx +416 -0
- package/src/cli/cmd/tui/routes/session/sidebar.tsx +318 -0
- package/src/cli/cmd/tui/spawn.ts +48 -0
- package/src/cli/cmd/tui/thread.ts +111 -0
- package/src/cli/cmd/tui/ui/dialog-alert.tsx +57 -0
- package/src/cli/cmd/tui/ui/dialog-confirm.tsx +83 -0
- package/src/cli/cmd/tui/ui/dialog-export-options.tsx +204 -0
- package/src/cli/cmd/tui/ui/dialog-help.tsx +38 -0
- package/src/cli/cmd/tui/ui/dialog-prompt.tsx +77 -0
- package/src/cli/cmd/tui/ui/dialog-select.tsx +345 -0
- package/src/cli/cmd/tui/ui/dialog.tsx +171 -0
- package/src/cli/cmd/tui/ui/link.tsx +28 -0
- package/src/cli/cmd/tui/ui/spinner.ts +368 -0
- package/src/cli/cmd/tui/ui/toast.tsx +100 -0
- package/src/cli/cmd/tui/util/clipboard.ts +127 -0
- package/src/cli/cmd/tui/util/editor.ts +32 -0
- package/src/cli/cmd/tui/util/signal.ts +7 -0
- package/src/cli/cmd/tui/util/terminal.ts +114 -0
- package/src/cli/cmd/tui/util/transcript.ts +98 -0
- package/src/cli/cmd/tui/worker.ts +68 -0
- package/src/cli/cmd/uninstall.ts +344 -0
- package/src/cli/cmd/upgrade.ts +67 -0
- package/src/cli/cmd/web.ts +73 -0
- package/src/cli/error.ts +56 -0
- package/src/cli/network.ts +53 -0
- package/src/cli/ui.ts +87 -0
- package/src/cli/upgrade.ts +25 -0
- package/src/command/index.ts +131 -0
- package/src/command/template/initialize.txt +10 -0
- package/src/command/template/review.txt +97 -0
- package/src/config/config.ts +1124 -0
- package/src/config/markdown.ts +41 -0
- package/src/env/index.ts +26 -0
- package/src/file/ignore.ts +83 -0
- package/src/file/index.ts +411 -0
- package/src/file/ripgrep.ts +402 -0
- package/src/file/time.ts +64 -0
- package/src/file/watcher.ts +117 -0
- package/src/flag/flag.ts +52 -0
- package/src/format/formatter.ts +359 -0
- package/src/format/index.ts +137 -0
- package/src/global/index.ts +55 -0
- package/src/id/id.ts +73 -0
- package/src/ide/index.ts +77 -0
- package/src/index.ts +159 -0
- package/src/installation/index.ts +198 -0
- package/src/lsp/client.ts +252 -0
- package/src/lsp/index.ts +485 -0
- package/src/lsp/language.ts +119 -0
- package/src/lsp/server.ts +2023 -0
- package/src/mcp/auth.ts +135 -0
- package/src/mcp/index.ts +874 -0
- package/src/mcp/oauth-callback.ts +200 -0
- package/src/mcp/oauth-provider.ts +154 -0
- package/src/patch/index.ts +622 -0
- package/src/permission/arity.ts +163 -0
- package/src/permission/index.ts +210 -0
- package/src/permission/next.ts +268 -0
- package/src/plugin/index.ts +106 -0
- package/src/project/bootstrap.ts +31 -0
- package/src/project/instance.ts +78 -0
- package/src/project/project.ts +263 -0
- package/src/project/state.ts +65 -0
- package/src/project/vcs.ts +76 -0
- package/src/provider/auth.ts +143 -0
- package/src/provider/models-macro.ts +4 -0
- package/src/provider/models.ts +77 -0
- package/src/provider/provider.ts +516 -0
- package/src/provider/transform.ts +114 -0
- package/src/pty/index.ts +212 -0
- package/src/server/error.ts +36 -0
- package/src/server/mdns.ts +57 -0
- package/src/server/project.ts +79 -0
- package/src/server/server.ts +2866 -0
- package/src/server/tui.ts +71 -0
- package/src/session/compaction.ts +225 -0
- package/src/session/index.ts +469 -0
- package/src/session/llm.ts +213 -0
- package/src/session/message-v2.ts +742 -0
- package/src/session/message.ts +189 -0
- package/src/session/processor.ts +402 -0
- package/src/session/prompt/anthropic-20250930.txt +166 -0
- package/src/session/prompt/anthropic.txt +105 -0
- package/src/session/prompt/anthropic_spoof.txt +1 -0
- package/src/session/prompt/beast.txt +147 -0
- package/src/session/prompt/build-switch.txt +5 -0
- package/src/session/prompt/codex.txt +318 -0
- package/src/session/prompt/copilot-gpt-5.txt +143 -0
- package/src/session/prompt/gemini.txt +155 -0
- package/src/session/prompt/max-steps.txt +16 -0
- package/src/session/prompt/plan-reminder-anthropic.txt +67 -0
- package/src/session/prompt/plan.txt +26 -0
- package/src/session/prompt/qwen.txt +109 -0
- package/src/session/prompt.ts +1621 -0
- package/src/session/retry.ts +90 -0
- package/src/session/revert.ts +108 -0
- package/src/session/status.ts +76 -0
- package/src/session/summary.ts +194 -0
- package/src/session/system.ts +108 -0
- package/src/session/todo.ts +37 -0
- package/src/share/share-next.ts +194 -0
- package/src/share/share.ts +23 -0
- package/src/shell/shell.ts +67 -0
- package/src/skill/index.ts +1 -0
- package/src/skill/skill.ts +124 -0
- package/src/snapshot/index.ts +197 -0
- package/src/storage/storage.ts +226 -0
- package/src/tool/bash.ts +262 -0
- package/src/tool/bash.txt +116 -0
- package/src/tool/batch.ts +175 -0
- package/src/tool/batch.txt +24 -0
- package/src/tool/codesearch.ts +132 -0
- package/src/tool/codesearch.txt +12 -0
- package/src/tool/edit.ts +655 -0
- package/src/tool/edit.txt +10 -0
- package/src/tool/glob.ts +75 -0
- package/src/tool/glob.txt +6 -0
- package/src/tool/grep.ts +132 -0
- package/src/tool/grep.txt +8 -0
- package/src/tool/invalid.ts +17 -0
- package/src/tool/ls.ts +119 -0
- package/src/tool/ls.txt +1 -0
- package/src/tool/lsp.ts +94 -0
- package/src/tool/lsp.txt +19 -0
- package/src/tool/multiedit.ts +46 -0
- package/src/tool/multiedit.txt +41 -0
- package/src/tool/patch.ts +210 -0
- package/src/tool/patch.txt +1 -0
- package/src/tool/read.ts +191 -0
- package/src/tool/read.txt +12 -0
- package/src/tool/registry.ts +137 -0
- package/src/tool/skill.ts +77 -0
- package/src/tool/task.ts +167 -0
- package/src/tool/task.txt +60 -0
- package/src/tool/todo.ts +53 -0
- package/src/tool/todoread.txt +14 -0
- package/src/tool/todowrite.txt +167 -0
- package/src/tool/tool.ts +73 -0
- package/src/tool/webfetch.ts +182 -0
- package/src/tool/webfetch.txt +13 -0
- package/src/tool/websearch.ts +144 -0
- package/src/tool/websearch.txt +11 -0
- package/src/tool/write.ts +84 -0
- package/src/tool/write.txt +8 -0
- package/src/util/archive.ts +16 -0
- package/src/util/color.ts +19 -0
- package/src/util/context.ts +25 -0
- package/src/util/defer.ts +12 -0
- package/src/util/eventloop.ts +20 -0
- package/src/util/filesystem.ts +83 -0
- package/src/util/fn.ts +11 -0
- package/src/util/iife.ts +3 -0
- package/src/util/keybind.ts +102 -0
- package/src/util/lazy.ts +18 -0
- package/src/util/locale.ts +81 -0
- package/src/util/lock.ts +98 -0
- package/src/util/log.ts +180 -0
- package/src/util/queue.ts +32 -0
- package/src/util/rpc.ts +42 -0
- package/src/util/scrap.ts +10 -0
- package/src/util/signal.ts +12 -0
- package/src/util/timeout.ts +14 -0
- package/src/util/token.ts +7 -0
- package/src/util/wildcard.ts +54 -0
- package/src/worktree/index.ts +217 -0
- package/sst-env.d.ts +9 -0
- package/test/agent/agent.test.ts +448 -0
- package/test/bun.test.ts +53 -0
- package/test/cli/github-action.test.ts +129 -0
- package/test/cli/github-remote.test.ts +80 -0
- package/test/cli/tui/transcript.test.ts +297 -0
- package/test/config/agent-color.test.ts +66 -0
- package/test/config/config.test.ts +870 -0
- package/test/config/markdown.test.ts +89 -0
- package/test/file/ignore.test.ts +10 -0
- package/test/file/path-traversal.test.ts +115 -0
- package/test/fixture/fixture.ts +45 -0
- package/test/fixture/lsp/fake-lsp-server.js +77 -0
- package/test/ide/ide.test.ts +82 -0
- package/test/keybind.test.ts +421 -0
- package/test/lsp/client.test.ts +95 -0
- package/test/mcp/headers.test.ts +153 -0
- package/test/patch/patch.test.ts +348 -0
- package/test/permission/arity.test.ts +33 -0
- package/test/permission/next.test.ts +652 -0
- package/test/preload.ts +63 -0
- package/test/project/project.test.ts +120 -0
- package/test/provider/amazon-bedrock.test.ts +236 -0
- package/test/provider/provider.test.ts +2127 -0
- package/test/provider/transform.test.ts +980 -0
- package/test/server/session-select.test.ts +78 -0
- package/test/session/compaction.test.ts +251 -0
- package/test/session/message-v2.test.ts +570 -0
- package/test/session/retry.test.ts +131 -0
- package/test/session/revert-compact.test.ts +285 -0
- package/test/session/session.test.ts +71 -0
- package/test/skill/skill.test.ts +185 -0
- package/test/snapshot/snapshot.test.ts +939 -0
- package/test/tool/__snapshots__/tool.test.ts.snap +9 -0
- package/test/tool/bash.test.ts +232 -0
- package/test/tool/grep.test.ts +109 -0
- package/test/tool/patch.test.ts +261 -0
- package/test/tool/read.test.ts +167 -0
- package/test/util/iife.test.ts +36 -0
- package/test/util/lazy.test.ts +50 -0
- package/test/util/timeout.test.ts +21 -0
- package/test/util/wildcard.test.ts +55 -0
- package/tsconfig.json +16 -0
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { Auth } from "../../auth"
|
|
2
|
+
import { cmd } from "./cmd"
|
|
3
|
+
import * as prompts from "@clack/prompts"
|
|
4
|
+
import { UI } from "../ui"
|
|
5
|
+
import path from "path"
|
|
6
|
+
import os from "os"
|
|
7
|
+
import { Global } from "../../global"
|
|
8
|
+
import { Instance } from "../../project/instance"
|
|
9
|
+
|
|
10
|
+
export const AuthCommand = cmd({
|
|
11
|
+
command: "auth",
|
|
12
|
+
describe: "manage credentials",
|
|
13
|
+
builder: (yargs) =>
|
|
14
|
+
yargs.command(AuthLoginCommand).command(AuthLogoutCommand).command(AuthListCommand).demandCommand(),
|
|
15
|
+
async handler() {},
|
|
16
|
+
})
|
|
17
|
+
|
|
18
|
+
export const AuthListCommand = cmd({
|
|
19
|
+
command: "list",
|
|
20
|
+
aliases: ["ls"],
|
|
21
|
+
describe: "list providers",
|
|
22
|
+
async handler() {
|
|
23
|
+
UI.empty()
|
|
24
|
+
const authPath = path.join(Global.Path.data, "auth.json")
|
|
25
|
+
const homedir = os.homedir()
|
|
26
|
+
const displayPath = authPath.startsWith(homedir) ? authPath.replace(homedir, "~") : authPath
|
|
27
|
+
prompts.intro(`Credentials ${UI.Style.TEXT_DIM}${displayPath}`)
|
|
28
|
+
const results = Object.entries(await Auth.all())
|
|
29
|
+
|
|
30
|
+
for (const [providerID, result] of results) {
|
|
31
|
+
prompts.log.info(`${providerID} ${UI.Style.TEXT_DIM}${result.type}`)
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
prompts.outro(`${results.length} credentials`)
|
|
35
|
+
|
|
36
|
+
// Check for CORETHINK_API_KEY environment variable
|
|
37
|
+
if (process.env.CORETHINK_API_KEY) {
|
|
38
|
+
UI.empty()
|
|
39
|
+
prompts.intro("Environment")
|
|
40
|
+
prompts.log.info(`Chad ${UI.Style.TEXT_DIM}CORETHINK_API_KEY`)
|
|
41
|
+
prompts.outro("1 environment variable")
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
export const AuthLoginCommand = cmd({
|
|
47
|
+
command: "login [url]",
|
|
48
|
+
describe: "log in to Chad",
|
|
49
|
+
builder: (yargs) =>
|
|
50
|
+
yargs.positional("url", {
|
|
51
|
+
describe: "opencode auth provider",
|
|
52
|
+
type: "string",
|
|
53
|
+
}),
|
|
54
|
+
async handler(args) {
|
|
55
|
+
await Instance.provide({
|
|
56
|
+
directory: process.cwd(),
|
|
57
|
+
async fn() {
|
|
58
|
+
UI.empty()
|
|
59
|
+
prompts.intro("Add Chad credential")
|
|
60
|
+
|
|
61
|
+
if (args.url) {
|
|
62
|
+
const wellknown = await fetch(`${args.url}/.well-known/opencode`).then((x) => x.json() as any)
|
|
63
|
+
prompts.log.info(`Running \`${wellknown.auth.command.join(" ")}\``)
|
|
64
|
+
const proc = Bun.spawn({
|
|
65
|
+
cmd: wellknown.auth.command,
|
|
66
|
+
stdout: "pipe",
|
|
67
|
+
})
|
|
68
|
+
const exit = await proc.exited
|
|
69
|
+
if (exit !== 0) {
|
|
70
|
+
prompts.log.error("Failed")
|
|
71
|
+
prompts.outro("Done")
|
|
72
|
+
return
|
|
73
|
+
}
|
|
74
|
+
const token = await new Response(proc.stdout).text()
|
|
75
|
+
await Auth.set(args.url, {
|
|
76
|
+
type: "wellknown",
|
|
77
|
+
key: wellknown.auth.env,
|
|
78
|
+
token: token.trim(),
|
|
79
|
+
})
|
|
80
|
+
prompts.log.success("Logged into " + args.url)
|
|
81
|
+
prompts.outro("Done")
|
|
82
|
+
return
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
prompts.log.info("Get your Chadcode API key from the Chadcode dashboard")
|
|
86
|
+
prompts.log.info("API keys should start with 'sk_'")
|
|
87
|
+
|
|
88
|
+
const key = await prompts.password({
|
|
89
|
+
message: "Enter your Chadcode API key",
|
|
90
|
+
validate: (x) => {
|
|
91
|
+
if (!x || x.length === 0) return "Required"
|
|
92
|
+
if (!x.startsWith("sk_")) return "Chadcode API keys should start with 'sk_'"
|
|
93
|
+
return undefined
|
|
94
|
+
},
|
|
95
|
+
})
|
|
96
|
+
if (prompts.isCancel(key)) throw new UI.CancelledError()
|
|
97
|
+
|
|
98
|
+
await Auth.set("corethink", {
|
|
99
|
+
type: "api",
|
|
100
|
+
key,
|
|
101
|
+
})
|
|
102
|
+
|
|
103
|
+
prompts.log.success("Chadcode API key saved")
|
|
104
|
+
prompts.outro("Done")
|
|
105
|
+
},
|
|
106
|
+
})
|
|
107
|
+
},
|
|
108
|
+
})
|
|
109
|
+
|
|
110
|
+
export const AuthLogoutCommand = cmd({
|
|
111
|
+
command: "logout",
|
|
112
|
+
describe: "log out from Chad",
|
|
113
|
+
async handler() {
|
|
114
|
+
UI.empty()
|
|
115
|
+
const credentials = await Auth.all().then((x) => Object.entries(x))
|
|
116
|
+
prompts.intro("Remove credential")
|
|
117
|
+
if (credentials.length === 0) {
|
|
118
|
+
prompts.log.error("No credentials found")
|
|
119
|
+
return
|
|
120
|
+
}
|
|
121
|
+
const providerID = await prompts.select({
|
|
122
|
+
message: "Select provider",
|
|
123
|
+
options: credentials.map(([key, value]) => ({
|
|
124
|
+
label: key + UI.Style.TEXT_DIM + " (" + value.type + ")",
|
|
125
|
+
value: key,
|
|
126
|
+
})),
|
|
127
|
+
})
|
|
128
|
+
if (prompts.isCancel(providerID)) throw new UI.CancelledError()
|
|
129
|
+
await Auth.remove(providerID)
|
|
130
|
+
prompts.outro("Logout successful")
|
|
131
|
+
},
|
|
132
|
+
})
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { EOL } from "os"
|
|
2
|
+
import { basename } from "path"
|
|
3
|
+
import { Agent } from "../../../agent/agent"
|
|
4
|
+
import { bootstrap } from "../../bootstrap"
|
|
5
|
+
import { cmd } from "../cmd"
|
|
6
|
+
|
|
7
|
+
export const AgentCommand = cmd({
|
|
8
|
+
command: "agent <name>",
|
|
9
|
+
builder: (yargs) =>
|
|
10
|
+
yargs.positional("name", {
|
|
11
|
+
type: "string",
|
|
12
|
+
demandOption: true,
|
|
13
|
+
description: "Agent name",
|
|
14
|
+
}),
|
|
15
|
+
async handler(args) {
|
|
16
|
+
await bootstrap(process.cwd(), async () => {
|
|
17
|
+
const agentName = args.name as string
|
|
18
|
+
const agent = await Agent.get(agentName)
|
|
19
|
+
if (!agent) {
|
|
20
|
+
process.stderr.write(
|
|
21
|
+
`Agent ${agentName} not found, run '${basename(process.execPath)} agent list' to get an agent list` + EOL,
|
|
22
|
+
)
|
|
23
|
+
process.exit(1)
|
|
24
|
+
}
|
|
25
|
+
process.stdout.write(JSON.stringify(agent, null, 2) + EOL)
|
|
26
|
+
})
|
|
27
|
+
},
|
|
28
|
+
})
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { EOL } from "os"
|
|
2
|
+
import { Config } from "../../../config/config"
|
|
3
|
+
import { bootstrap } from "../../bootstrap"
|
|
4
|
+
import { cmd } from "../cmd"
|
|
5
|
+
|
|
6
|
+
export const ConfigCommand = cmd({
|
|
7
|
+
command: "config",
|
|
8
|
+
builder: (yargs) => yargs,
|
|
9
|
+
async handler() {
|
|
10
|
+
await bootstrap(process.cwd(), async () => {
|
|
11
|
+
const config = await Config.get()
|
|
12
|
+
process.stdout.write(JSON.stringify(config, null, 2) + EOL)
|
|
13
|
+
})
|
|
14
|
+
},
|
|
15
|
+
})
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { EOL } from "os"
|
|
2
|
+
import { File } from "../../../file"
|
|
3
|
+
import { bootstrap } from "../../bootstrap"
|
|
4
|
+
import { cmd } from "../cmd"
|
|
5
|
+
import { Ripgrep } from "@/file/ripgrep"
|
|
6
|
+
|
|
7
|
+
const FileSearchCommand = cmd({
|
|
8
|
+
command: "search <query>",
|
|
9
|
+
builder: (yargs) =>
|
|
10
|
+
yargs.positional("query", {
|
|
11
|
+
type: "string",
|
|
12
|
+
demandOption: true,
|
|
13
|
+
description: "Search query",
|
|
14
|
+
}),
|
|
15
|
+
async handler(args) {
|
|
16
|
+
await bootstrap(process.cwd(), async () => {
|
|
17
|
+
const results = await File.search({ query: args.query })
|
|
18
|
+
process.stdout.write(results.join(EOL) + EOL)
|
|
19
|
+
})
|
|
20
|
+
},
|
|
21
|
+
})
|
|
22
|
+
|
|
23
|
+
const FileReadCommand = cmd({
|
|
24
|
+
command: "read <path>",
|
|
25
|
+
builder: (yargs) =>
|
|
26
|
+
yargs.positional("path", {
|
|
27
|
+
type: "string",
|
|
28
|
+
demandOption: true,
|
|
29
|
+
description: "File path to read",
|
|
30
|
+
}),
|
|
31
|
+
async handler(args) {
|
|
32
|
+
await bootstrap(process.cwd(), async () => {
|
|
33
|
+
const content = await File.read(args.path)
|
|
34
|
+
process.stdout.write(JSON.stringify(content, null, 2) + EOL)
|
|
35
|
+
})
|
|
36
|
+
},
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
const FileStatusCommand = cmd({
|
|
40
|
+
command: "status",
|
|
41
|
+
builder: (yargs) => yargs,
|
|
42
|
+
async handler() {
|
|
43
|
+
await bootstrap(process.cwd(), async () => {
|
|
44
|
+
const status = await File.status()
|
|
45
|
+
process.stdout.write(JSON.stringify(status, null, 2) + EOL)
|
|
46
|
+
})
|
|
47
|
+
},
|
|
48
|
+
})
|
|
49
|
+
|
|
50
|
+
const FileListCommand = cmd({
|
|
51
|
+
command: "list <path>",
|
|
52
|
+
builder: (yargs) =>
|
|
53
|
+
yargs.positional("path", {
|
|
54
|
+
type: "string",
|
|
55
|
+
demandOption: true,
|
|
56
|
+
description: "File path to list",
|
|
57
|
+
}),
|
|
58
|
+
async handler(args) {
|
|
59
|
+
await bootstrap(process.cwd(), async () => {
|
|
60
|
+
const files = await File.list(args.path)
|
|
61
|
+
process.stdout.write(JSON.stringify(files, null, 2) + EOL)
|
|
62
|
+
})
|
|
63
|
+
},
|
|
64
|
+
})
|
|
65
|
+
|
|
66
|
+
const FileTreeCommand = cmd({
|
|
67
|
+
command: "tree [dir]",
|
|
68
|
+
builder: (yargs) =>
|
|
69
|
+
yargs.positional("dir", {
|
|
70
|
+
type: "string",
|
|
71
|
+
description: "Directory to tree",
|
|
72
|
+
default: process.cwd(),
|
|
73
|
+
}),
|
|
74
|
+
async handler(args) {
|
|
75
|
+
const files = await Ripgrep.tree({ cwd: args.dir, limit: 200 })
|
|
76
|
+
console.log(files)
|
|
77
|
+
},
|
|
78
|
+
})
|
|
79
|
+
|
|
80
|
+
export const FileCommand = cmd({
|
|
81
|
+
command: "file",
|
|
82
|
+
builder: (yargs) =>
|
|
83
|
+
yargs
|
|
84
|
+
.command(FileReadCommand)
|
|
85
|
+
.command(FileStatusCommand)
|
|
86
|
+
.command(FileListCommand)
|
|
87
|
+
.command(FileSearchCommand)
|
|
88
|
+
.command(FileTreeCommand)
|
|
89
|
+
.demandCommand(),
|
|
90
|
+
async handler() {},
|
|
91
|
+
})
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { Global } from "../../../global"
|
|
2
|
+
import { bootstrap } from "../../bootstrap"
|
|
3
|
+
import { cmd } from "../cmd"
|
|
4
|
+
import { ConfigCommand } from "./config"
|
|
5
|
+
import { FileCommand } from "./file"
|
|
6
|
+
import { LSPCommand } from "./lsp"
|
|
7
|
+
import { RipgrepCommand } from "./ripgrep"
|
|
8
|
+
import { ScrapCommand } from "./scrap"
|
|
9
|
+
import { SkillCommand } from "./skill"
|
|
10
|
+
import { SnapshotCommand } from "./snapshot"
|
|
11
|
+
import { AgentCommand } from "./agent"
|
|
12
|
+
|
|
13
|
+
export const DebugCommand = cmd({
|
|
14
|
+
command: "debug",
|
|
15
|
+
builder: (yargs) =>
|
|
16
|
+
yargs
|
|
17
|
+
.command(ConfigCommand)
|
|
18
|
+
.command(LSPCommand)
|
|
19
|
+
.command(RipgrepCommand)
|
|
20
|
+
.command(FileCommand)
|
|
21
|
+
.command(ScrapCommand)
|
|
22
|
+
.command(SkillCommand)
|
|
23
|
+
.command(SnapshotCommand)
|
|
24
|
+
.command(AgentCommand)
|
|
25
|
+
.command(PathsCommand)
|
|
26
|
+
.command({
|
|
27
|
+
command: "wait",
|
|
28
|
+
async handler() {
|
|
29
|
+
await bootstrap(process.cwd(), async () => {
|
|
30
|
+
await new Promise((resolve) => setTimeout(resolve, 1_000 * 60 * 60 * 24))
|
|
31
|
+
})
|
|
32
|
+
},
|
|
33
|
+
})
|
|
34
|
+
.demandCommand(),
|
|
35
|
+
async handler() {},
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
const PathsCommand = cmd({
|
|
39
|
+
command: "paths",
|
|
40
|
+
handler() {
|
|
41
|
+
for (const [key, value] of Object.entries(Global.Path)) {
|
|
42
|
+
console.log(key.padEnd(10), value)
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
})
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { LSP } from "../../../lsp"
|
|
2
|
+
import { bootstrap } from "../../bootstrap"
|
|
3
|
+
import { cmd } from "../cmd"
|
|
4
|
+
import { Log } from "../../../util/log"
|
|
5
|
+
import { EOL } from "os"
|
|
6
|
+
|
|
7
|
+
export const LSPCommand = cmd({
|
|
8
|
+
command: "lsp",
|
|
9
|
+
builder: (yargs) =>
|
|
10
|
+
yargs.command(DiagnosticsCommand).command(SymbolsCommand).command(DocumentSymbolsCommand).demandCommand(),
|
|
11
|
+
async handler() {},
|
|
12
|
+
})
|
|
13
|
+
|
|
14
|
+
const DiagnosticsCommand = cmd({
|
|
15
|
+
command: "diagnostics <file>",
|
|
16
|
+
builder: (yargs) => yargs.positional("file", { type: "string", demandOption: true }),
|
|
17
|
+
async handler(args) {
|
|
18
|
+
await bootstrap(process.cwd(), async () => {
|
|
19
|
+
await LSP.touchFile(args.file, true)
|
|
20
|
+
await Bun.sleep(1000)
|
|
21
|
+
process.stdout.write(JSON.stringify(await LSP.diagnostics(), null, 2) + EOL)
|
|
22
|
+
})
|
|
23
|
+
},
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
export const SymbolsCommand = cmd({
|
|
27
|
+
command: "symbols <query>",
|
|
28
|
+
builder: (yargs) => yargs.positional("query", { type: "string", demandOption: true }),
|
|
29
|
+
async handler(args) {
|
|
30
|
+
await bootstrap(process.cwd(), async () => {
|
|
31
|
+
using _ = Log.Default.time("symbols")
|
|
32
|
+
const results = await LSP.workspaceSymbol(args.query)
|
|
33
|
+
process.stdout.write(JSON.stringify(results, null, 2) + EOL)
|
|
34
|
+
})
|
|
35
|
+
},
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
export const DocumentSymbolsCommand = cmd({
|
|
39
|
+
command: "document-symbols <uri>",
|
|
40
|
+
builder: (yargs) => yargs.positional("uri", { type: "string", demandOption: true }),
|
|
41
|
+
async handler(args) {
|
|
42
|
+
await bootstrap(process.cwd(), async () => {
|
|
43
|
+
using _ = Log.Default.time("document-symbols")
|
|
44
|
+
const results = await LSP.documentSymbol(args.uri)
|
|
45
|
+
process.stdout.write(JSON.stringify(results, null, 2) + EOL)
|
|
46
|
+
})
|
|
47
|
+
},
|
|
48
|
+
})
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { EOL } from "os"
|
|
2
|
+
import { Ripgrep } from "../../../file/ripgrep"
|
|
3
|
+
import { Instance } from "../../../project/instance"
|
|
4
|
+
import { bootstrap } from "../../bootstrap"
|
|
5
|
+
import { cmd } from "../cmd"
|
|
6
|
+
|
|
7
|
+
export const RipgrepCommand = cmd({
|
|
8
|
+
command: "rg",
|
|
9
|
+
builder: (yargs) => yargs.command(TreeCommand).command(FilesCommand).command(SearchCommand).demandCommand(),
|
|
10
|
+
async handler() {},
|
|
11
|
+
})
|
|
12
|
+
|
|
13
|
+
const TreeCommand = cmd({
|
|
14
|
+
command: "tree",
|
|
15
|
+
builder: (yargs) =>
|
|
16
|
+
yargs.option("limit", {
|
|
17
|
+
type: "number",
|
|
18
|
+
}),
|
|
19
|
+
async handler(args) {
|
|
20
|
+
await bootstrap(process.cwd(), async () => {
|
|
21
|
+
process.stdout.write((await Ripgrep.tree({ cwd: Instance.directory, limit: args.limit })) + EOL)
|
|
22
|
+
})
|
|
23
|
+
},
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
const FilesCommand = cmd({
|
|
27
|
+
command: "files",
|
|
28
|
+
builder: (yargs) =>
|
|
29
|
+
yargs
|
|
30
|
+
.option("query", {
|
|
31
|
+
type: "string",
|
|
32
|
+
description: "Filter files by query",
|
|
33
|
+
})
|
|
34
|
+
.option("glob", {
|
|
35
|
+
type: "string",
|
|
36
|
+
description: "Glob pattern to match files",
|
|
37
|
+
})
|
|
38
|
+
.option("limit", {
|
|
39
|
+
type: "number",
|
|
40
|
+
description: "Limit number of results",
|
|
41
|
+
}),
|
|
42
|
+
async handler(args) {
|
|
43
|
+
await bootstrap(process.cwd(), async () => {
|
|
44
|
+
const files: string[] = []
|
|
45
|
+
for await (const file of Ripgrep.files({
|
|
46
|
+
cwd: Instance.directory,
|
|
47
|
+
glob: args.glob ? [args.glob] : undefined,
|
|
48
|
+
})) {
|
|
49
|
+
files.push(file)
|
|
50
|
+
if (args.limit && files.length >= args.limit) break
|
|
51
|
+
}
|
|
52
|
+
process.stdout.write(files.join(EOL) + EOL)
|
|
53
|
+
})
|
|
54
|
+
},
|
|
55
|
+
})
|
|
56
|
+
|
|
57
|
+
const SearchCommand = cmd({
|
|
58
|
+
command: "search <pattern>",
|
|
59
|
+
builder: (yargs) =>
|
|
60
|
+
yargs
|
|
61
|
+
.positional("pattern", {
|
|
62
|
+
type: "string",
|
|
63
|
+
demandOption: true,
|
|
64
|
+
description: "Search pattern",
|
|
65
|
+
})
|
|
66
|
+
.option("glob", {
|
|
67
|
+
type: "array",
|
|
68
|
+
description: "File glob patterns",
|
|
69
|
+
})
|
|
70
|
+
.option("limit", {
|
|
71
|
+
type: "number",
|
|
72
|
+
description: "Limit number of results",
|
|
73
|
+
}),
|
|
74
|
+
async handler(args) {
|
|
75
|
+
const results = await Ripgrep.search({
|
|
76
|
+
cwd: process.cwd(),
|
|
77
|
+
pattern: args.pattern,
|
|
78
|
+
glob: args.glob as string[] | undefined,
|
|
79
|
+
limit: args.limit,
|
|
80
|
+
})
|
|
81
|
+
process.stdout.write(JSON.stringify(results, null, 2) + EOL)
|
|
82
|
+
},
|
|
83
|
+
})
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { EOL } from "os"
|
|
2
|
+
import { Project } from "../../../project/project"
|
|
3
|
+
import { Log } from "../../../util/log"
|
|
4
|
+
import { cmd } from "../cmd"
|
|
5
|
+
|
|
6
|
+
export const ScrapCommand = cmd({
|
|
7
|
+
command: "scrap",
|
|
8
|
+
builder: (yargs) => yargs,
|
|
9
|
+
async handler() {
|
|
10
|
+
const timer = Log.Default.time("scrap")
|
|
11
|
+
const list = await Project.list()
|
|
12
|
+
process.stdout.write(JSON.stringify(list, null, 2) + EOL)
|
|
13
|
+
timer.stop()
|
|
14
|
+
},
|
|
15
|
+
})
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { EOL } from "os"
|
|
2
|
+
import { Skill } from "../../../skill"
|
|
3
|
+
import { bootstrap } from "../../bootstrap"
|
|
4
|
+
import { cmd } from "../cmd"
|
|
5
|
+
|
|
6
|
+
export const SkillCommand = cmd({
|
|
7
|
+
command: "skill",
|
|
8
|
+
builder: (yargs) => yargs,
|
|
9
|
+
async handler() {
|
|
10
|
+
await bootstrap(process.cwd(), async () => {
|
|
11
|
+
const skills = await Skill.all()
|
|
12
|
+
process.stdout.write(JSON.stringify(skills, null, 2) + EOL)
|
|
13
|
+
})
|
|
14
|
+
},
|
|
15
|
+
})
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { Snapshot } from "../../../snapshot"
|
|
2
|
+
import { bootstrap } from "../../bootstrap"
|
|
3
|
+
import { cmd } from "../cmd"
|
|
4
|
+
|
|
5
|
+
export const SnapshotCommand = cmd({
|
|
6
|
+
command: "snapshot",
|
|
7
|
+
builder: (yargs) => yargs.command(TrackCommand).command(PatchCommand).command(DiffCommand).demandCommand(),
|
|
8
|
+
async handler() {},
|
|
9
|
+
})
|
|
10
|
+
|
|
11
|
+
const TrackCommand = cmd({
|
|
12
|
+
command: "track",
|
|
13
|
+
async handler() {
|
|
14
|
+
await bootstrap(process.cwd(), async () => {
|
|
15
|
+
console.log(await Snapshot.track())
|
|
16
|
+
})
|
|
17
|
+
},
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
const PatchCommand = cmd({
|
|
21
|
+
command: "patch <hash>",
|
|
22
|
+
builder: (yargs) =>
|
|
23
|
+
yargs.positional("hash", {
|
|
24
|
+
type: "string",
|
|
25
|
+
description: "hash",
|
|
26
|
+
demandOption: true,
|
|
27
|
+
}),
|
|
28
|
+
async handler(args) {
|
|
29
|
+
await bootstrap(process.cwd(), async () => {
|
|
30
|
+
console.log(await Snapshot.patch(args.hash))
|
|
31
|
+
})
|
|
32
|
+
},
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
const DiffCommand = cmd({
|
|
36
|
+
command: "diff <hash>",
|
|
37
|
+
builder: (yargs) =>
|
|
38
|
+
yargs.positional("hash", {
|
|
39
|
+
type: "string",
|
|
40
|
+
description: "hash",
|
|
41
|
+
demandOption: true,
|
|
42
|
+
}),
|
|
43
|
+
async handler(args) {
|
|
44
|
+
await bootstrap(process.cwd(), async () => {
|
|
45
|
+
console.log(await Snapshot.diff(args.hash))
|
|
46
|
+
})
|
|
47
|
+
},
|
|
48
|
+
})
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import type { Argv } from "yargs"
|
|
2
|
+
import { Session } from "../../session"
|
|
3
|
+
import { cmd } from "./cmd"
|
|
4
|
+
import { bootstrap } from "../bootstrap"
|
|
5
|
+
import { UI } from "../ui"
|
|
6
|
+
import * as prompts from "@clack/prompts"
|
|
7
|
+
import { EOL } from "os"
|
|
8
|
+
|
|
9
|
+
export const ExportCommand = cmd({
|
|
10
|
+
command: "export [sessionID]",
|
|
11
|
+
describe: "export session data as JSON",
|
|
12
|
+
builder: (yargs: Argv) => {
|
|
13
|
+
return yargs.positional("sessionID", {
|
|
14
|
+
describe: "session id to export",
|
|
15
|
+
type: "string",
|
|
16
|
+
})
|
|
17
|
+
},
|
|
18
|
+
handler: async (args) => {
|
|
19
|
+
await bootstrap(process.cwd(), async () => {
|
|
20
|
+
let sessionID = args.sessionID
|
|
21
|
+
process.stderr.write(`Exporting session: ${sessionID ?? "latest"}`)
|
|
22
|
+
|
|
23
|
+
if (!sessionID) {
|
|
24
|
+
UI.empty()
|
|
25
|
+
prompts.intro("Export session", {
|
|
26
|
+
output: process.stderr,
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
const sessions = []
|
|
30
|
+
for await (const session of Session.list()) {
|
|
31
|
+
sessions.push(session)
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (sessions.length === 0) {
|
|
35
|
+
prompts.log.error("No sessions found", {
|
|
36
|
+
output: process.stderr,
|
|
37
|
+
})
|
|
38
|
+
prompts.outro("Done", {
|
|
39
|
+
output: process.stderr,
|
|
40
|
+
})
|
|
41
|
+
return
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
sessions.sort((a, b) => b.time.updated - a.time.updated)
|
|
45
|
+
|
|
46
|
+
const selectedSession = await prompts.autocomplete({
|
|
47
|
+
message: "Select session to export",
|
|
48
|
+
maxItems: 10,
|
|
49
|
+
options: sessions.map((session) => ({
|
|
50
|
+
label: session.title,
|
|
51
|
+
value: session.id,
|
|
52
|
+
hint: `${new Date(session.time.updated).toLocaleString()} • ${session.id.slice(-8)}`,
|
|
53
|
+
})),
|
|
54
|
+
output: process.stderr,
|
|
55
|
+
})
|
|
56
|
+
|
|
57
|
+
if (prompts.isCancel(selectedSession)) {
|
|
58
|
+
throw new UI.CancelledError()
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
sessionID = selectedSession as string
|
|
62
|
+
|
|
63
|
+
prompts.outro("Exporting session...", {
|
|
64
|
+
output: process.stderr,
|
|
65
|
+
})
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
try {
|
|
69
|
+
const sessionInfo = await Session.get(sessionID!)
|
|
70
|
+
const messages = await Session.messages({ sessionID: sessionID! })
|
|
71
|
+
|
|
72
|
+
const exportData = {
|
|
73
|
+
info: sessionInfo,
|
|
74
|
+
messages: messages.map((msg) => ({
|
|
75
|
+
info: msg.info,
|
|
76
|
+
parts: msg.parts,
|
|
77
|
+
})),
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
process.stdout.write(JSON.stringify(exportData, null, 2))
|
|
81
|
+
process.stdout.write(EOL)
|
|
82
|
+
} catch (error) {
|
|
83
|
+
UI.error(`Session not found: ${sessionID!}`)
|
|
84
|
+
process.exit(1)
|
|
85
|
+
}
|
|
86
|
+
})
|
|
87
|
+
},
|
|
88
|
+
})
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { Server } from "../../server/server"
|
|
2
|
+
import type { CommandModule } from "yargs"
|
|
3
|
+
|
|
4
|
+
export const GenerateCommand = {
|
|
5
|
+
command: "generate",
|
|
6
|
+
handler: async () => {
|
|
7
|
+
const specs = await Server.openapi()
|
|
8
|
+
for (const item of Object.values(specs.paths)) {
|
|
9
|
+
for (const method of ["get", "post", "put", "delete", "patch"] as const) {
|
|
10
|
+
const operation = item[method]
|
|
11
|
+
if (!operation?.operationId) continue
|
|
12
|
+
// @ts-expect-error
|
|
13
|
+
operation["x-codeSamples"] = [
|
|
14
|
+
{
|
|
15
|
+
lang: "js",
|
|
16
|
+
source: [
|
|
17
|
+
`import { createOpencodeClient } from "@opencode-ai/sdk`,
|
|
18
|
+
``,
|
|
19
|
+
`const client = createOpencodeClient()`,
|
|
20
|
+
`await client.${operation.operationId}({`,
|
|
21
|
+
` ...`,
|
|
22
|
+
`})`,
|
|
23
|
+
].join("\n"),
|
|
24
|
+
},
|
|
25
|
+
]
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
const json = JSON.stringify(specs, null, 2)
|
|
29
|
+
|
|
30
|
+
// Wait for stdout to finish writing before process.exit() is called
|
|
31
|
+
await new Promise<void>((resolve, reject) => {
|
|
32
|
+
process.stdout.write(json, (err) => {
|
|
33
|
+
if (err) reject(err)
|
|
34
|
+
else resolve()
|
|
35
|
+
})
|
|
36
|
+
})
|
|
37
|
+
},
|
|
38
|
+
} satisfies CommandModule
|