Compare commits

..
Author SHA1 Message Date
Dax Raad 4d65309efe Release v0.0.0-202507310417
publish / publish (push) Has been cancelled
2025-07-31 00:18:03 -04:00
Dax Raad df1c911764 progress 2025-07-31 00:14:39 -04:00
Dax Raad 53907843b7 sync 2025-07-30 23:03:54 -04:00
Dax Raad 62284914cd sync 2025-07-30 21:11:45 -04:00
15 changed files with 103 additions and 240 deletions
+12 -6
View File
@@ -2,11 +2,13 @@ name: publish
on:
workflow_dispatch:
inputs:
version:
description: "Version to publish"
required: true
type: string
push:
branches:
- dev
tags:
- "*"
- "!vscode-v*"
- "!github-v*"
concurrency: ${{ github.workflow }}-${{ github.ref }}
@@ -51,7 +53,11 @@ jobs:
- name: Publish
run: |
bun install
OPENCODE_VERSION=${{ inputs.version }} ./script/publish.ts
if [ "${{ startsWith(github.ref, 'refs/tags/') }}" = "true" ]; then
./script/publish.ts
else
./script/publish.ts --snapshot
fi
working-directory: ./packages/opencode
env:
GITHUB_TOKEN: ${{ secrets.SST_GITHUB_TOKEN }}
+1 -1
View File
@@ -1,6 +1,6 @@
{
"$schema": "https://json.schemastore.org/package.json",
"version": "0.0.0",
"version": "0.0.5",
"name": "opencode",
"type": "module",
"private": true,
+13 -5
View File
@@ -1,13 +1,21 @@
#!/usr/bin/env bun
const dir = new URL("..", import.meta.url).pathname
process.chdir(dir)
import { $ } from "bun"
import pkg from "../package.json"
const dry = process.env["OPENCODE_DRY"] === "true"
const version = process.env["OPENCODE_VERSION"]!
const snapshot = process.env["OPENCODE_SNAPSHOT"] === "true"
const dry = process.argv.includes("--dry")
const snapshot = process.argv.includes("--snapshot")
const version = snapshot
? `0.0.0-${new Date().toISOString().slice(0, 16).replace(/[-:T]/g, "")}`
: await $`git describe --tags --abbrev=0`
.text()
.then((x) => x.substring(1).trim())
.catch(() => {
console.error("tag not found")
process.exit(1)
})
console.log(`publishing ${version}`)
-1
View File
@@ -73,7 +73,6 @@ export namespace BunProc {
// Let Bun handle registry resolution:
// - If .npmrc files exist, Bun will use them automatically
// - If no .npmrc files exist, Bun will default to https://registry.npmjs.org
// - No need to pass --registry flag
log.info("installing package using Bun's default registry resolution", { pkg, version })
await BunProc.run(args, {
-26
View File
@@ -65,32 +65,6 @@ export namespace Config {
throw new InvalidError({ path: item }, { cause: parsed.error })
}
// Load mode markdown files
result.mode = result.mode || {}
const markdownModes = [
...(await Filesystem.globUp("mode/*.md", Global.Path.config, Global.Path.config)),
...(await Filesystem.globUp(".opencode/mode/*.md", app.path.cwd, app.path.root)),
]
for (const item of markdownModes) {
const content = await Bun.file(item).text()
const md = matter(content)
if (!md.data) continue
const config = {
name: path.basename(item, ".md"),
...md.data,
prompt: md.content.trim(),
}
const parsed = Mode.safeParse(config)
if (parsed.success) {
result.mode = mergeDeep(result.mode, {
[config.name]: parsed.data,
})
continue
}
throw new InvalidError({ path: item }, { cause: parsed.error })
}
// Handle migration from autoshare to share field
if (result.autoshare === true && !result.share) {
result.share = "auto"
+4 -46
View File
@@ -1,6 +1,7 @@
import { App } from "../app/app"
import { BunProc } from "../bun"
import { Filesystem } from "../util/filesystem"
import path from "path"
export interface Info {
name: string
@@ -64,57 +65,14 @@ export const prettier: Info = {
],
async enabled() {
const app = App.info()
const items = await Filesystem.findUp("package.json", app.path.cwd, app.path.root)
for (const item of items) {
const json = await Bun.file(item).json()
if (json.dependencies?.prettier) return true
if (json.devDependencies?.prettier) return true
const nms = await Filesystem.findUp("node_modules", app.path.cwd, app.path.root)
for (const item of nms) {
if (await Bun.file(path.join(item, ".bin", "prettier")).exists()) return true
}
return false
},
}
export const biome: Info = {
name: "biome",
command: [BunProc.which(), "x", "biome", "format", "--write", "$FILE"],
environment: {
BUN_BE_BUN: "1",
},
extensions: [
".js",
".jsx",
".mjs",
".cjs",
".ts",
".tsx",
".mts",
".cts",
".html",
".htm",
".css",
".scss",
".sass",
".less",
".vue",
".svelte",
".json",
".jsonc",
".yaml",
".yml",
".toml",
".xml",
".md",
".mdx",
".graphql",
".gql",
],
async enabled() {
const app = App.info()
const items = await Filesystem.findUp("biome.json", app.path.cwd, app.path.root)
return items.length > 0
},
}
export const zig: Info = {
name: "zig",
command: ["zig", "fmt", "$FILE"],
+14 -34
View File
@@ -97,7 +97,7 @@ export namespace Provider {
Array.isArray(msg.content) && msg.content.some((part: any) => part.type === "image_url"),
)
}
} catch { }
} catch {}
const headers: Record<string, string> = {
...init.headers,
...copilot.HEADERS,
@@ -126,15 +126,6 @@ export namespace Provider {
options: {},
}
},
azure: async () => {
return {
autoload: false,
async getModel(sdk: any, modelID: string) {
return sdk.responses(modelID)
},
options: {},
}
},
"amazon-bedrock": async () => {
if (!process.env["AWS_PROFILE"] && !process.env["AWS_ACCESS_KEY_ID"] && !process.env["AWS_BEARER_TOKEN_BEDROCK"])
return { autoload: false }
@@ -203,17 +194,6 @@ export namespace Provider {
},
}
},
vercel: async () => {
return {
autoload: false,
options: {
headers: {
"http-referer": "https://opencode.ai/",
"x-title": "opencode",
},
},
}
},
}
const state = App.state("provider", async () => {
@@ -283,26 +263,26 @@ export namespace Provider {
cost:
!model.cost && !existing?.cost
? {
input: 0,
output: 0,
cache_read: 0,
cache_write: 0,
}
input: 0,
output: 0,
cache_read: 0,
cache_write: 0,
}
: {
cache_read: 0,
cache_write: 0,
...existing?.cost,
...model.cost,
},
cache_read: 0,
cache_write: 0,
...existing?.cost,
...model.cost,
},
options: {
...existing?.options,
...model.options,
},
limit: model.limit ??
existing?.limit ?? {
context: 0,
output: 0,
},
context: 0,
output: 0,
},
}
parsed.models[modelID] = parsedModel
}
+11 -10
View File
@@ -2,17 +2,20 @@ import { z } from "zod"
import { Tool } from "./tool"
import DESCRIPTION from "./bash.txt"
import { App } from "../app/app"
import path from "path"
// import Parser from "tree-sitter"
// import Bash from "tree-sitter-bash"
// import { Config } from "../config/config"
import Parser from "tree-sitter"
import Bash from "tree-sitter-bash"
import { Config } from "../config/config"
import { Filesystem } from "../util/filesystem"
import { Permission } from "../permission"
const MAX_OUTPUT_LENGTH = 30000
const DEFAULT_TIMEOUT = 1 * 60 * 1000
const MAX_TIMEOUT = 10 * 60 * 1000
// const parser = new Parser()
// parser.setLanguage(Bash.language as any)
const parser = new Parser()
parser.setLanguage(Bash.language as any)
export const BashTool = Tool.define("bash", {
description: DESCRIPTION,
@@ -27,10 +30,9 @@ export const BashTool = Tool.define("bash", {
}),
async execute(params, ctx) {
const timeout = Math.min(params.timeout ?? DEFAULT_TIMEOUT, MAX_TIMEOUT)
const app = App.info()
/*
const _cfg = await Config.get()
const tree = parser.parse(params.command)
const cfg = await Config.get()
const app = App.info()
const permissions = (() => {
const value = cfg.permission?.bash
if (!value)
@@ -91,7 +93,7 @@ export const BashTool = Tool.define("bash", {
if (needsAsk) {
await Permission.ask({
id: "bash",
id: "basj",
sessionID: ctx.sessionID,
title: params.command,
metadata: {
@@ -99,7 +101,6 @@ export const BashTool = Tool.define("bash", {
},
})
}
*/
const process = Bun.spawn({
cmd: ["bash", "-c", params.command],
+1 -2
View File
@@ -74,8 +74,7 @@ export namespace ToolRegistry {
modelID.toLowerCase().includes("qwen") ||
modelID.includes("gpt-") ||
modelID.includes("o1") ||
modelID.includes("o3") ||
modelID.includes("codex")
modelID.includes("o3")
) {
return {
patch: false,
+1 -1
View File
@@ -1,11 +1,11 @@
{
"$schema": "https://json.schemastore.org/package.json",
"name": "@opencode-ai/sdk",
"version": "0.0.0",
"type": "module",
"exports": {
".": "./dist/index.js"
},
"version": "0.0.0-202507310417",
"files": [
"dist"
],
-3
View File
@@ -36,6 +36,3 @@ await createClient({
},
],
})
await $`rm -rf dist`
await $`bun tsc`
+5 -8
View File
@@ -9,16 +9,13 @@ const version = process.env["OPENCODE_VERSION"]
if (!version) {
throw new Error("OPENCODE_VERSION is required")
}
const dry = process.env["DRY"] === "true"
await import("./generate")
await $`rm -rf dist`
await $`bun tsc`
const snapshot = process.env["OPENCODE_SNAPSHOT"] === "true"
await $`bun pm version --allow-same-version --no-git-tag-version ${version}`
if (snapshot) {
await $`bun publish --tag snapshot`
}
if (!snapshot) {
if (!dry) {
await $`bun pm version --allow-same-version --no-git-tag-version ${version}`
await $`bun publish`
}
await $`bun pm version 0.0.0 --no-git-tag-version`
+3 -85
View File
@@ -50,11 +50,7 @@ You can switch between modes during a session using the _Tab_ key. Or your confi
## Configure
You can customize the built-in modes or create your own through configuration. Modes can be configured in two ways:
### JSON Configuration
Configure modes in your `opencode.json` config file:
You can customize the built-in modes or create your own in the opencode [config](/docs/config).
```json title="opencode.json"
{
@@ -81,35 +77,7 @@ Configure modes in your `opencode.json` config file:
}
```
### Markdown Configuration
You can also define modes using markdown files. Place them in:
- Global: `~/.config/opencode/mode/`
- Project: `.opencode/mode/`
```markdown title="~/.config/opencode/mode/review.md"
---
model: anthropic/claude-sonnet-4-20250514
temperature: 0.1
tools:
write: false
edit: false
bash: false
---
You are in code review mode. Focus on:
- Code quality and best practices
- Potential bugs and edge cases
- Performance implications
- Security considerations
Provide constructive feedback without making direct changes.
```
The markdown file name becomes the mode name (e.g., `review.md` creates a `review` mode).
Let's look at these configuration options in detail.
Let's look at these options in detail.
---
@@ -240,9 +208,7 @@ Here are all the tools can be controlled through the mode config.
## Custom modes
You can create your own custom modes by adding them to the configuration. Here are examples using both approaches:
### Using JSON configuration
You can create your own custom modes by adding them to the `mode` configuration. For example, a documentation mode that focuses on reading and analysis.
```json title="opencode.json" {4-14}
{
@@ -263,54 +229,6 @@ You can create your own custom modes by adding them to the configuration. Here a
}
```
### Using markdown files
Create mode files in `.opencode/mode/` for project-specific modes or `~/.config/opencode/mode/` for global modes:
```markdown title=".opencode/mode/debug.md"
---
temperature: 0.1
tools:
bash: true
read: true
grep: true
write: false
edit: false
---
You are in debug mode. Your primary goal is to help investigate and diagnose issues.
Focus on:
- Understanding the problem through careful analysis
- Using bash commands to inspect system state
- Reading relevant files and logs
- Searching for patterns and anomalies
- Providing clear explanations of findings
Do not make any changes to files. Only investigate and report.
```
```markdown title="~/.config/opencode/mode/refactor.md"
---
model: anthropic/claude-sonnet-4-20250514
temperature: 0.2
tools:
edit: true
read: true
grep: true
glob: true
---
You are in refactoring mode. Focus on improving code quality without changing functionality.
Priorities:
- Improve code readability and maintainability
- Apply consistent naming conventions
- Reduce code duplication
- Optimize performance where appropriate
- Ensure all tests continue to pass
```
---
### Use cases
+3 -12
View File
@@ -11,18 +11,9 @@ if (!version) {
}
process.env["OPENCODE_VERSION"] = version
await import(`../packages/opencode/script/publish.ts`)
await import(`../packages/sdk/stainless/generate.ts`)
await import(`../packages/sdk/js/script/publish.ts`)
if (!snapshot) {
await $`git commit -am "Release v${version}"`
await $`git tag v${version}`
await $`git push origin HEAD --tags`
}
if (snapshot) {
await $`git commit --allow-empty -m "Snapshot release v${version}"`
await $`git tag v${version}`
await $`git push origin v${version}`
await $`git reset --soft HEAD~1`
}
await $`git commit -am "Release v${version}"`
await $`git tag v${version}`
await $`git push HEAD --tags`
+35
View File
@@ -0,0 +1,35 @@
#!/bin/bash
set -e
# Parse command line arguments
DEV_MODE=false
for arg in "$@"; do
if [ "$arg" = "--dev" ]; then
DEV_MODE=true
fi
done
bun run ./packages/opencode/src/index.ts generate > openapi.json
echo "Running stl builds create..."
stl builds create --branch dev --pull --allow-empty --+target go --+target typescript
echo "Cleaning up..."
rm -rf packages/tui/sdk
mv opencode-go/ packages/tui/sdk/
rm -rf packages/tui/sdk/.git
rm -rf packages/sdk
mv opencode-typescript/ packages/sdk/
rm -rf packages/sdk/.git
# Only run production build if not in dev mode
if [ "$DEV_MODE" = false ]; then
echo "Kicking off production build..."
stl builds create --branch main --wait=false
else
echo "Skipping production build (--dev flag detected)"
fi
echo "Done!"