Skip to content

Instantly share code, notes, and snippets.

@jlongster
jlongster / shell-jump-demo.mp4
Last active August 27, 2026 12:39
OpenCode TUI shell completion jump demo
@jlongster
jlongster / v1-v2-config-compatibility.md
Created August 25, 2026 15:25
Plan: OpenCode V1 loading of V2 configuration

V1 Loading of V2 Configuration

Status: Planned for dev.

Problem

OpenCode V1 and OpenCode V2 read configuration from the same global and project paths. OpenCode V2 commands continue to write native V2 fields. A user can therefore start with a valid V1 file, run a V2 command such as opencode2 mcp add, and produce a mixed document that V2 accepts but V1 cannot load.

@jlongster
jlongster / clean-eof-first-retry.png
Last active August 8, 2026 02:58
OpenCode provider failure UI screenshots for PR 41179
clean-eof-first-retry.png
@jlongster
jlongster / main.ts
Last active July 17, 2026 14:50
Minimal inline OpenCode SDK session integration
import "./env.js";
import { AbsolutePath, Model, Provider } from "@opencode-ai/sdk-next";
import { Cause, Deferred, Effect, Stream } from "effect";
import { startCli } from "./cli.js";
import { createInlineOpenCode } from "./inline-opencode.js";
const location = { directory: AbsolutePath.make(process.env.QBOT_LOCATION?.trim() || process.cwd()) };
const modelName = process.env.QBOT_MODEL?.trim() || "openai/gpt-5.6-terra";
const timeoutSeconds = Number(process.env.QBOT_TIMEOUT_SECONDS ?? "600");
const timeoutMs = (Number.isFinite(timeoutSeconds) && timeoutSeconds > 0 ? timeoutSeconds : 600) * 1000;
import { useLoaderData, Link, useSearchParams } from 'remix';
import { parseISO, format } from 'date-fns';
import groupBy from 'lodash/groupBy';
let PAGE_SIZE = 5;
function safeParseInt(str) {
let parsed = parseInt(str);
return isNaN(parsed) ? 0 : parsed;
}
// Uses Buffer from https://github.com/feross/buffer
function toArrayBuffer(buffer) {
return buffer.buffer.slice(
buffer.byteOffset,
buffer.byteOffset + buffer.byteLength
);
}
async function run() {
const async_hooks = require('async_hooks');
let store = new Map();
let promiseStorageHook = async_hooks.createHook({
init(id, type, triggerId, resource) {
if (store.get(triggerId)) {
if (type === 'PROMISE') {
store.set(id, store.get(triggerId));
}
import React from 'react';
import { View, Text, ScrollView, TouchableOpacity } from 'react-native';
let NamespaceContext = React.createContext(undefined);
export default class ExamplePage extends React.Component {
constructor() {
super();
this.state = { currentMonth: 1 };
}
import Timestamp from './timestamp';
function getKeys(trie) {
return Object.keys(trie).filter(x => x !== 'hash');
}
function keyToTimestamp(key) {
// 16 is the length of the base 3 value of the current time in
// minutes. Ensure it's padded to create the full value
let fullkey = key + '0'.repeat(16 - key.length);
// UPDATE: don't use this. when it re-partitions the list when time moves forward, it does not correctly keep hashes
// Use a real merkle tree instead: https://gist.github.com/jlongster/f431b6d75ef29c1a2ed000715aef9c8c
import Timestamp from './timestamp';
// This is a compact data structure that keeps track of a list of
// hashes (representing messages) over a range of time in order to
// figure out what has changed between clients, kinda like a Merkle
// tree. It creates "buckets" that represent different time ranges,
// and divides time into smaller buckets the more recent they are. The