summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorDax Raad <[email protected]>2025-06-03 12:38:48 -0400
committerDax Raad <[email protected]>2025-06-03 12:38:48 -0400
commite5b06a2d9593bf06419829631843853e466b5265 (patch)
tree7358c7b552fcb703d98f788b38fe3c31efa5d2dd
parentfae49aaf88b22cd5a5c9172bd8fcd01c073cd319 (diff)
downloadopencode-e5b06a2d9593bf06419829631843853e466b5265.tar.gz
opencode-e5b06a2d9593bf06419829631843853e466b5265.zip
initialzie
-rw-r--r--packages/opencode/AGENTS.md23
-rw-r--r--packages/opencode/src/index.ts33
-rw-r--r--packages/opencode/src/provider/provider.ts11
-rw-r--r--packages/opencode/src/server/server.ts29
-rw-r--r--packages/opencode/src/session/prompt/initialize.txt7
-rw-r--r--packages/opencode/src/session/session.ts19
6 files changed, 113 insertions, 9 deletions
diff --git a/packages/opencode/AGENTS.md b/packages/opencode/AGENTS.md
new file mode 100644
index 000000000..0a90a2c80
--- /dev/null
+++ b/packages/opencode/AGENTS.md
@@ -0,0 +1,23 @@
+# OpenCode Agent Guidelines
+
+## Build/Test Commands
+- **Install**: `bun install`
+- **Run**: `bun run index.ts`
+- **Typecheck**: `bun run typecheck` (npm run typecheck)
+- **Test**: `bun test` (runs all tests)
+- **Single test**: `bun test test/tool/tool.test.ts` (specific test file)
+
+## Code Style
+- **Runtime**: Bun with TypeScript ESM modules
+- **Imports**: Use relative imports for local modules, named imports preferred
+- **Types**: Zod schemas for validation, TypeScript interfaces for structure
+- **Naming**: camelCase for variables/functions, PascalCase for classes/namespaces
+- **Error handling**: Use Result patterns, avoid throwing exceptions in tools
+- **File structure**: Namespace-based organization (e.g., `Tool.define()`, `Session.create()`)
+
+## Architecture
+- **Tools**: Implement `Tool.Info` interface with `execute()` method
+- **Context**: Pass `sessionID` in tool context, use `App.provide()` for DI
+- **Validation**: All inputs validated with Zod schemas
+- **Logging**: Use `Log.create({ service: "name" })` pattern
+- **Storage**: Use `Storage` namespace for persistence \ No newline at end of file
diff --git a/packages/opencode/src/index.ts b/packages/opencode/src/index.ts
index 75c91f4d9..7c514edb8 100644
--- a/packages/opencode/src/index.ts
+++ b/packages/opencode/src/index.ts
@@ -84,17 +84,11 @@ cli
unsub()
})
- const [provider] = await Provider.active().then((val) =>
- val.values().toArray(),
- )
- if (!provider) throw new Error("no providers found")
- const model = provider.models[0]
- if (!model) throw new Error("no models found")
- console.log("using", provider.id, model.id)
+ const { providerID, modelID } = await Provider.defaultModel()
const result = await Session.chat({
sessionID: session.id,
- providerID: provider.id,
- modelID: model.id,
+ providerID,
+ modelID,
parts: [
{
type: "text",
@@ -115,6 +109,27 @@ cli
})
})
+cli.command("init", "Run a chat message").action(async () => {
+ await App.provide({ cwd: process.cwd(), version }, async () => {
+ const { modelID, providerID } = await Provider.defaultModel()
+ console.log("Initializing...")
+
+ const session = await Session.create()
+
+ const unsub = Bus.subscribe(Session.Event.Updated, async (message) => {
+ if (message.properties.info.share?.url)
+ console.log("Share:", message.properties.info.share.url)
+ unsub()
+ })
+
+ await Session.initialize({
+ sessionID: session.id,
+ modelID,
+ providerID,
+ })
+ })
+})
+
cli.version(typeof OPENCODE_VERSION === "string" ? OPENCODE_VERSION : "dev")
cli.help()
cli.parse()
diff --git a/packages/opencode/src/provider/provider.ts b/packages/opencode/src/provider/provider.ts
index 68cdda0fe..a2affb963 100644
--- a/packages/opencode/src/provider/provider.ts
+++ b/packages/opencode/src/provider/provider.ts
@@ -141,6 +141,17 @@ export namespace Provider {
}
}
+ export async function defaultModel() {
+ const [provider] = await active().then((val) => val.values().toArray())
+ if (!provider) throw new Error("no providers found")
+ const model = provider.models[0]
+ if (!model) throw new Error("no models found")
+ return {
+ providerID: provider.id,
+ modelID: model.id,
+ }
+ }
+
const TOOLS = [
BashTool,
EditTool,
diff --git a/packages/opencode/src/server/server.ts b/packages/opencode/src/server/server.ts
index a4285f33a..18feb0fb5 100644
--- a/packages/opencode/src/server/server.ts
+++ b/packages/opencode/src/server/server.ts
@@ -94,6 +94,35 @@ export namespace Server {
},
)
.post(
+ "/session_initialize",
+ describeRoute({
+ description: "Analyze the app and create an AGENTS.md file",
+ responses: {
+ 200: {
+ description: "200",
+ content: {
+ "application/json": {
+ schema: resolver(z.boolean()),
+ },
+ },
+ },
+ },
+ }),
+ zValidator(
+ "json",
+ z.object({
+ sessionID: z.string(),
+ providerID: z.string(),
+ modelID: z.string(),
+ }),
+ ),
+ async (c) => {
+ const body = c.req.valid("json")
+ await Session.initialize(body)
+ return c.json(true)
+ },
+ )
+ .post(
"/path_get",
describeRoute({
description: "Get paths",
diff --git a/packages/opencode/src/session/prompt/initialize.txt b/packages/opencode/src/session/prompt/initialize.txt
new file mode 100644
index 000000000..27886b404
--- /dev/null
+++ b/packages/opencode/src/session/prompt/initialize.txt
@@ -0,0 +1,7 @@
+Please analyze this codebase and create an AGENTS.md file containing:
+1. Build/lint/test commands - especially for running a single test
+2. Code style guidelines including imports, formatting, types, naming conventions, error handling, etc.
+
+The file you create will be given to agentic coding agents (such as yourself) that operate in this repository. Make it about 20 lines long.
+If there's already an AGENTS.md, improve it.
+If there are Cursor rules (in .cursor/rules/ or .cursorrules) or Copilot rules (in .github/copilot-instructions.md), make sure to include them.
diff --git a/packages/opencode/src/session/session.ts b/packages/opencode/src/session/session.ts
index 06ee88b01..1e6b00510 100644
--- a/packages/opencode/src/session/session.ts
+++ b/packages/opencode/src/session/session.ts
@@ -18,6 +18,7 @@ import { Decimal } from "decimal.js"
import PROMPT_ANTHROPIC from "./prompt/anthropic.txt"
import PROMPT_TITLE from "./prompt/title.txt"
import PROMPT_SUMMARIZE from "./prompt/summarize.txt"
+import PROMPT_INITIALIZE from "../session/prompt/initialize.txt"
import { Share } from "../share/share"
import { Message } from "./message"
@@ -531,4 +532,22 @@ export namespace Session {
super(`Session ${sessionID} is busy`)
}
}
+
+ export async function initialize(input: {
+ sessionID: string
+ modelID: string
+ providerID: string
+ }) {
+ await Session.chat({
+ sessionID: input.sessionID,
+ providerID: input.providerID,
+ modelID: input.modelID,
+ parts: [
+ {
+ type: "text",
+ text: PROMPT_INITIALIZE,
+ },
+ ],
+ })
+ }
}