mirror of
https://github.com/sst/opencode.git
synced 2025-12-23 10:11:41 +00:00
Merge branch 'dev' into opentui
This commit is contained in:
commit
ea530da05d
17 changed files with 259 additions and 105 deletions
22
bun.lock
22
bun.lock
|
|
@ -39,7 +39,7 @@
|
|||
},
|
||||
"packages/console/core": {
|
||||
"name": "@opencode-ai/console-core",
|
||||
"version": "0.15.10",
|
||||
"version": "0.15.11",
|
||||
"dependencies": {
|
||||
"@aws-sdk/client-sts": "3.782.0",
|
||||
"@jsx-email/render": "1.1.1",
|
||||
|
|
@ -66,7 +66,7 @@
|
|||
},
|
||||
"packages/console/function": {
|
||||
"name": "@opencode-ai/console-function",
|
||||
"version": "0.15.10",
|
||||
"version": "0.15.11",
|
||||
"dependencies": {
|
||||
"@ai-sdk/anthropic": "2.0.0",
|
||||
"@ai-sdk/openai": "2.0.2",
|
||||
|
|
@ -90,7 +90,7 @@
|
|||
},
|
||||
"packages/console/mail": {
|
||||
"name": "@opencode-ai/console-mail",
|
||||
"version": "0.15.10",
|
||||
"version": "0.15.11",
|
||||
"dependencies": {
|
||||
"@jsx-email/all": "2.2.3",
|
||||
"@jsx-email/cli": "1.4.3",
|
||||
|
|
@ -111,7 +111,7 @@
|
|||
},
|
||||
"packages/desktop": {
|
||||
"name": "@opencode-ai/desktop",
|
||||
"version": "0.15.10",
|
||||
"version": "0.15.11",
|
||||
"dependencies": {
|
||||
"@kobalte/core": "catalog:",
|
||||
"@opencode-ai/sdk": "workspace:*",
|
||||
|
|
@ -149,7 +149,7 @@
|
|||
},
|
||||
"packages/function": {
|
||||
"name": "@opencode-ai/function",
|
||||
"version": "0.15.10",
|
||||
"version": "0.15.11",
|
||||
"dependencies": {
|
||||
"@octokit/auth-app": "8.0.1",
|
||||
"@octokit/rest": "22.0.0",
|
||||
|
|
@ -165,7 +165,7 @@
|
|||
},
|
||||
"packages/opencode": {
|
||||
"name": "opencode",
|
||||
"version": "0.15.10",
|
||||
"version": "0.15.11",
|
||||
"bin": {
|
||||
"opencode": "./bin/opencode",
|
||||
},
|
||||
|
|
@ -239,7 +239,7 @@
|
|||
},
|
||||
"packages/plugin": {
|
||||
"name": "@opencode-ai/plugin",
|
||||
"version": "0.15.10",
|
||||
"version": "0.15.11",
|
||||
"dependencies": {
|
||||
"@opencode-ai/sdk": "workspace:*",
|
||||
"zod": "catalog:",
|
||||
|
|
@ -259,7 +259,7 @@
|
|||
},
|
||||
"packages/sdk/js": {
|
||||
"name": "@opencode-ai/sdk",
|
||||
"version": "0.15.10",
|
||||
"version": "0.15.11",
|
||||
"devDependencies": {
|
||||
"@hey-api/openapi-ts": "0.81.0",
|
||||
"@tsconfig/node22": "catalog:",
|
||||
|
|
@ -270,7 +270,7 @@
|
|||
},
|
||||
"packages/slack": {
|
||||
"name": "@opencode-ai/slack",
|
||||
"version": "0.15.10",
|
||||
"version": "0.15.11",
|
||||
"dependencies": {
|
||||
"@opencode-ai/sdk": "workspace:*",
|
||||
"@slack/bolt": "^3.17.1",
|
||||
|
|
@ -283,7 +283,7 @@
|
|||
},
|
||||
"packages/ui": {
|
||||
"name": "@opencode-ai/ui",
|
||||
"version": "0.15.10",
|
||||
"version": "0.15.11",
|
||||
"dependencies": {
|
||||
"@kobalte/core": "catalog:",
|
||||
"@solidjs/meta": "catalog:",
|
||||
|
|
@ -304,7 +304,7 @@
|
|||
},
|
||||
"packages/web": {
|
||||
"name": "@opencode-ai/web",
|
||||
"version": "0.15.10",
|
||||
"version": "0.15.11",
|
||||
"dependencies": {
|
||||
"@astrojs/cloudflare": "12.6.3",
|
||||
"@astrojs/markdown-remark": "6.3.1",
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
"dev:remote": "VITE_AUTH_URL=https://auth.dev.opencode.ai bun sst shell --stage=dev bun dev",
|
||||
"build": "vinxi build && ../../opencode/script/schema.ts ./.output/public/config.json",
|
||||
"start": "vinxi start",
|
||||
"version": "0.15.10"
|
||||
"version": "0.15.11"
|
||||
},
|
||||
"dependencies": {
|
||||
"@ibm/plex": "6.4.1",
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"$schema": "https://json.schemastore.org/package.json",
|
||||
"name": "@opencode-ai/console-core",
|
||||
"version": "0.15.10",
|
||||
"version": "0.15.11",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"dependencies": {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@opencode-ai/console-function",
|
||||
"version": "0.15.10",
|
||||
"version": "0.15.11",
|
||||
"$schema": "https://json.schemastore.org/package.json",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@opencode-ai/console-mail",
|
||||
"version": "0.15.10",
|
||||
"version": "0.15.11",
|
||||
"dependencies": {
|
||||
"@jsx-email/all": "2.2.3",
|
||||
"@jsx-email/cli": "1.4.3",
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@opencode-ai/desktop",
|
||||
"version": "0.15.10",
|
||||
"version": "0.15.11",
|
||||
"description": "",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@opencode-ai/function",
|
||||
"version": "0.15.10",
|
||||
"version": "0.15.11",
|
||||
"$schema": "https://json.schemastore.org/package.json",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"$schema": "https://json.schemastore.org/package.json",
|
||||
"version": "0.15.10",
|
||||
"version": "0.15.11",
|
||||
"name": "opencode",
|
||||
"type": "module",
|
||||
"private": true,
|
||||
|
|
|
|||
|
|
@ -147,12 +147,7 @@ export namespace Session {
|
|||
})
|
||||
})
|
||||
|
||||
export async function createNext(input: {
|
||||
id?: string
|
||||
title?: string
|
||||
parentID?: string
|
||||
directory: string
|
||||
}) {
|
||||
export async function createNext(input: { id?: string; title?: string; parentID?: string; directory: string }) {
|
||||
const result: Info = {
|
||||
id: Identifier.descending("session", input.id),
|
||||
version: Installation.VERSION,
|
||||
|
|
@ -372,9 +367,7 @@ export namespace Session {
|
|||
.add(new Decimal(tokens.input).mul(input.model.cost?.input ?? 0).div(1_000_000))
|
||||
.add(new Decimal(tokens.output).mul(input.model.cost?.output ?? 0).div(1_000_000))
|
||||
.add(new Decimal(tokens.cache.read).mul(input.model.cost?.cache_read ?? 0).div(1_000_000))
|
||||
.add(
|
||||
new Decimal(tokens.cache.write).mul(input.model.cost?.cache_write ?? 0).div(1_000_000),
|
||||
)
|
||||
.add(new Decimal(tokens.cache.write).mul(input.model.cost?.cache_write ?? 0).div(1_000_000))
|
||||
.toNumber(),
|
||||
tokens,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,15 +26,8 @@ export namespace Snapshot {
|
|||
.nothrow()
|
||||
log.info("initialized")
|
||||
}
|
||||
await $`git --git-dir ${git} add .`
|
||||
.quiet()
|
||||
.cwd(Instance.directory)
|
||||
.nothrow()
|
||||
const hash = await $`git --git-dir ${git} write-tree`
|
||||
.quiet()
|
||||
.cwd(Instance.directory)
|
||||
.nothrow()
|
||||
.text()
|
||||
await $`git --git-dir ${git} add .`.quiet().cwd(Instance.directory).nothrow()
|
||||
const hash = await $`git --git-dir ${git} write-tree`.quiet().cwd(Instance.directory).nothrow().text()
|
||||
log.info("tracking", { hash, cwd: Instance.directory, git })
|
||||
return hash.trim()
|
||||
}
|
||||
|
|
@ -47,14 +40,8 @@ export namespace Snapshot {
|
|||
|
||||
export async function patch(hash: string): Promise<Patch> {
|
||||
const git = gitdir()
|
||||
await $`git --git-dir ${git} add .`
|
||||
.quiet()
|
||||
.cwd(Instance.directory)
|
||||
.nothrow()
|
||||
const result = await $`git --git-dir ${git} diff --name-only ${hash} -- .`
|
||||
.quiet()
|
||||
.cwd(Instance.directory)
|
||||
.nothrow()
|
||||
await $`git --git-dir ${git} add .`.quiet().cwd(Instance.directory).nothrow()
|
||||
const result = await $`git --git-dir ${git} diff --name-only ${hash} -- .`.quiet().cwd(Instance.directory).nothrow()
|
||||
|
||||
// If git diff fails, return empty patch
|
||||
if (result.exitCode !== 0) {
|
||||
|
|
@ -76,11 +63,10 @@ export namespace Snapshot {
|
|||
export async function restore(snapshot: string) {
|
||||
log.info("restore", { commit: snapshot })
|
||||
const git = gitdir()
|
||||
const result =
|
||||
await $`git --git-dir=${git} read-tree ${snapshot} && git --git-dir=${git} checkout-index -a -f`
|
||||
.quiet()
|
||||
.cwd(Instance.worktree)
|
||||
.nothrow()
|
||||
const result = await $`git --git-dir=${git} read-tree ${snapshot} && git --git-dir=${git} checkout-index -a -f`
|
||||
.quiet()
|
||||
.cwd(Instance.worktree)
|
||||
.nothrow()
|
||||
|
||||
if (result.exitCode !== 0) {
|
||||
log.error("failed to restore snapshot", {
|
||||
|
|
@ -99,18 +85,16 @@ export namespace Snapshot {
|
|||
for (const file of item.files) {
|
||||
if (files.has(file)) continue
|
||||
log.info("reverting", { file, hash: item.hash })
|
||||
const result =
|
||||
await $`git --git-dir=${git} checkout ${item.hash} -- ${file}`
|
||||
const result = await $`git --git-dir=${git} checkout ${item.hash} -- ${file}`
|
||||
.quiet()
|
||||
.cwd(Instance.worktree)
|
||||
.nothrow()
|
||||
if (result.exitCode !== 0) {
|
||||
const relativePath = path.relative(Instance.worktree, file)
|
||||
const checkTree = await $`git --git-dir=${git} ls-tree ${item.hash} -- ${relativePath}`
|
||||
.quiet()
|
||||
.cwd(Instance.worktree)
|
||||
.nothrow()
|
||||
if (result.exitCode !== 0) {
|
||||
const relativePath = path.relative(Instance.worktree, file)
|
||||
const checkTree =
|
||||
await $`git --git-dir=${git} ls-tree ${item.hash} -- ${relativePath}`
|
||||
.quiet()
|
||||
.cwd(Instance.worktree)
|
||||
.nothrow()
|
||||
if (checkTree.exitCode === 0 && checkTree.text().trim()) {
|
||||
log.info("file existed in snapshot but checkout failed, keeping", {
|
||||
file,
|
||||
|
|
@ -128,14 +112,8 @@ export namespace Snapshot {
|
|||
|
||||
export async function diff(hash: string) {
|
||||
const git = gitdir()
|
||||
await $`git --git-dir ${git} add .`
|
||||
.quiet()
|
||||
.cwd(Instance.directory)
|
||||
.nothrow()
|
||||
const result = await $`git --git-dir=${git} diff ${hash} -- .`
|
||||
.quiet()
|
||||
.cwd(Instance.worktree)
|
||||
.nothrow()
|
||||
await $`git --git-dir ${git} add .`.quiet().cwd(Instance.directory).nothrow()
|
||||
const result = await $`git --git-dir=${git} diff ${hash} -- .`.quiet().cwd(Instance.worktree).nothrow()
|
||||
|
||||
if (result.exitCode !== 0) {
|
||||
log.warn("failed to get diff", {
|
||||
|
|
@ -153,37 +131,33 @@ export namespace Snapshot {
|
|||
export const FileDiff = z
|
||||
.object({
|
||||
file: z.string(),
|
||||
left: z.string(),
|
||||
right: z.string(),
|
||||
before: z.string(),
|
||||
after: z.string(),
|
||||
additions: z.number(),
|
||||
deletions: z.number(),
|
||||
})
|
||||
.meta({
|
||||
ref: "FileDiff",
|
||||
})
|
||||
export type FileDiff = z.infer<typeof FileDiff>
|
||||
export async function diffFull(
|
||||
from: string,
|
||||
to: string,
|
||||
): Promise<FileDiff[]> {
|
||||
export async function diffFull(from: string, to: string): Promise<FileDiff[]> {
|
||||
const git = gitdir()
|
||||
const result: FileDiff[] = []
|
||||
for await (const line of $`git --git-dir=${git} diff --name-only ${from} ${to} -- .`
|
||||
for await (const line of $`git --git-dir=${git} diff --numstat ${from} ${to} -- .`
|
||||
.quiet()
|
||||
.cwd(Instance.directory)
|
||||
.nothrow()
|
||||
.lines()) {
|
||||
if (!line) continue
|
||||
const left = await $`git --git-dir=${git} show ${from}:${line}`
|
||||
.quiet()
|
||||
.nothrow()
|
||||
.text()
|
||||
const right = await $`git --git-dir=${git} show ${to}:${line}`
|
||||
.quiet()
|
||||
.nothrow()
|
||||
.text()
|
||||
const [additions, deletions, file] = line.split("\t")
|
||||
const before = await $`git --git-dir=${git} show ${from}:${file}`.quiet().nothrow().text()
|
||||
const after = await $`git --git-dir=${git} show ${to}:${file}`.quiet().nothrow().text()
|
||||
result.push({
|
||||
file: line,
|
||||
left,
|
||||
right,
|
||||
file,
|
||||
before,
|
||||
after,
|
||||
additions: parseInt(additions),
|
||||
deletions: parseInt(deletions),
|
||||
})
|
||||
}
|
||||
return result
|
||||
|
|
|
|||
|
|
@ -585,7 +585,7 @@ test("revert preserves file that existed in snapshot when deleted then recreated
|
|||
})
|
||||
})
|
||||
|
||||
test("diffFull function", async () => {
|
||||
test("diffFull with new file additions", async () => {
|
||||
await using tmp = await bootstrap()
|
||||
await Instance.provide({
|
||||
directory: tmp.path,
|
||||
|
|
@ -594,26 +594,103 @@ test("diffFull function", async () => {
|
|||
expect(before).toBeTruthy()
|
||||
|
||||
await Bun.write(`${tmp.path}/new.txt`, "new content")
|
||||
|
||||
const after = await Snapshot.track()
|
||||
expect(after).toBeTruthy()
|
||||
|
||||
const diffs = await Snapshot.diffFull(before!, after!)
|
||||
expect(diffs.length).toBe(1)
|
||||
|
||||
const newFileDiff = diffs[0]
|
||||
expect(newFileDiff.file).toBe("new.txt")
|
||||
expect(newFileDiff.before).toBe("")
|
||||
expect(newFileDiff.after).toBe("new content")
|
||||
expect(newFileDiff.additions).toBe(1)
|
||||
expect(newFileDiff.deletions).toBe(0)
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
test("diffFull with file modifications", async () => {
|
||||
await using tmp = await bootstrap()
|
||||
await Instance.provide({
|
||||
directory: tmp.path,
|
||||
fn: async () => {
|
||||
const before = await Snapshot.track()
|
||||
expect(before).toBeTruthy()
|
||||
|
||||
await Bun.write(`${tmp.path}/b.txt`, "modified content")
|
||||
|
||||
const after = await Snapshot.track()
|
||||
expect(after).toBeTruthy()
|
||||
|
||||
const diffs = await Snapshot.diffFull(before!, after!)
|
||||
expect(diffs.length).toBe(2)
|
||||
expect(diffs.length).toBe(1)
|
||||
|
||||
const newFileDiff = diffs.find((d) => d.file === "new.txt")
|
||||
expect(newFileDiff).toBeDefined()
|
||||
expect(newFileDiff!.left).toBe("")
|
||||
expect(newFileDiff!.right).toBe("new content")
|
||||
|
||||
const modifiedFileDiff = diffs.find((d) => d.file === "b.txt")
|
||||
expect(modifiedFileDiff).toBeDefined()
|
||||
expect(modifiedFileDiff!.left).toBe(tmp.extra.bContent)
|
||||
expect(modifiedFileDiff!.right).toBe("modified content")
|
||||
const modifiedFileDiff = diffs[0]
|
||||
expect(modifiedFileDiff.file).toBe("b.txt")
|
||||
expect(modifiedFileDiff.before).toBe(tmp.extra.bContent)
|
||||
expect(modifiedFileDiff.after).toBe("modified content")
|
||||
expect(modifiedFileDiff.additions).toBeGreaterThan(0)
|
||||
expect(modifiedFileDiff.deletions).toBeGreaterThan(0)
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
test("diffFull with file deletions", async () => {
|
||||
await using tmp = await bootstrap()
|
||||
await Instance.provide({
|
||||
directory: tmp.path,
|
||||
fn: async () => {
|
||||
const before = await Snapshot.track()
|
||||
expect(before).toBeTruthy()
|
||||
|
||||
await $`rm ${tmp.path}/a.txt`.quiet()
|
||||
|
||||
const after = await Snapshot.track()
|
||||
expect(after).toBeTruthy()
|
||||
|
||||
const diffs = await Snapshot.diffFull(before!, after!)
|
||||
expect(diffs.length).toBe(1)
|
||||
|
||||
const removedFileDiff = diffs[0]
|
||||
expect(removedFileDiff.file).toBe("a.txt")
|
||||
expect(removedFileDiff.before).toBe(tmp.extra.aContent)
|
||||
expect(removedFileDiff.after).toBe("")
|
||||
expect(removedFileDiff.additions).toBe(0)
|
||||
expect(removedFileDiff.deletions).toBe(1)
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
test("diffFull with multiple line additions", async () => {
|
||||
await using tmp = await bootstrap()
|
||||
await Instance.provide({
|
||||
directory: tmp.path,
|
||||
fn: async () => {
|
||||
const before = await Snapshot.track()
|
||||
expect(before).toBeTruthy()
|
||||
|
||||
await Bun.write(`${tmp.path}/multi.txt`, "line1\nline2\nline3")
|
||||
|
||||
const after = await Snapshot.track()
|
||||
expect(after).toBeTruthy()
|
||||
|
||||
const diffs = await Snapshot.diffFull(before!, after!)
|
||||
expect(diffs.length).toBe(1)
|
||||
|
||||
const multiDiff = diffs[0]
|
||||
expect(multiDiff.file).toBe("multi.txt")
|
||||
expect(multiDiff.before).toBe("")
|
||||
expect(multiDiff.after).toBe("line1\nline2\nline3")
|
||||
expect(multiDiff.additions).toBe(3)
|
||||
expect(multiDiff.deletions).toBe(0)
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
test("diffFull with addition and deletion", async () => {
|
||||
await using tmp = await bootstrap()
|
||||
await Instance.provide({
|
||||
directory: tmp.path,
|
||||
fn: async () => {
|
||||
|
|
@ -631,13 +708,123 @@ test("diffFull function", async () => {
|
|||
|
||||
const addedFileDiff = diffs.find((d) => d.file === "added.txt")
|
||||
expect(addedFileDiff).toBeDefined()
|
||||
expect(addedFileDiff!.left).toBe("")
|
||||
expect(addedFileDiff!.right).toBe("added content")
|
||||
expect(addedFileDiff!.before).toBe("")
|
||||
expect(addedFileDiff!.after).toBe("added content")
|
||||
expect(addedFileDiff!.additions).toBe(1)
|
||||
expect(addedFileDiff!.deletions).toBe(0)
|
||||
|
||||
const removedFileDiff = diffs.find((d) => d.file === "a.txt")
|
||||
expect(removedFileDiff).toBeDefined()
|
||||
expect(removedFileDiff!.left).toBe(tmp.extra.aContent)
|
||||
expect(removedFileDiff!.right).toBe("")
|
||||
expect(removedFileDiff!.before).toBe(tmp.extra.aContent)
|
||||
expect(removedFileDiff!.after).toBe("")
|
||||
expect(removedFileDiff!.additions).toBe(0)
|
||||
expect(removedFileDiff!.deletions).toBe(1)
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
test("diffFull with multiple additions and deletions", async () => {
|
||||
await using tmp = await bootstrap()
|
||||
await Instance.provide({
|
||||
directory: tmp.path,
|
||||
fn: async () => {
|
||||
const before = await Snapshot.track()
|
||||
expect(before).toBeTruthy()
|
||||
|
||||
await Bun.write(`${tmp.path}/multi1.txt`, "line1\nline2\nline3")
|
||||
await Bun.write(`${tmp.path}/multi2.txt`, "single line")
|
||||
await $`rm ${tmp.path}/a.txt`.quiet()
|
||||
await $`rm ${tmp.path}/b.txt`.quiet()
|
||||
|
||||
const after = await Snapshot.track()
|
||||
expect(after).toBeTruthy()
|
||||
|
||||
const diffs = await Snapshot.diffFull(before!, after!)
|
||||
expect(diffs.length).toBe(4)
|
||||
|
||||
const multi1Diff = diffs.find((d) => d.file === "multi1.txt")
|
||||
expect(multi1Diff).toBeDefined()
|
||||
expect(multi1Diff!.additions).toBe(3)
|
||||
expect(multi1Diff!.deletions).toBe(0)
|
||||
|
||||
const multi2Diff = diffs.find((d) => d.file === "multi2.txt")
|
||||
expect(multi2Diff).toBeDefined()
|
||||
expect(multi2Diff!.additions).toBe(1)
|
||||
expect(multi2Diff!.deletions).toBe(0)
|
||||
|
||||
const removedADiff = diffs.find((d) => d.file === "a.txt")
|
||||
expect(removedADiff).toBeDefined()
|
||||
expect(removedADiff!.additions).toBe(0)
|
||||
expect(removedADiff!.deletions).toBe(1)
|
||||
|
||||
const removedBDiff = diffs.find((d) => d.file === "b.txt")
|
||||
expect(removedBDiff).toBeDefined()
|
||||
expect(removedBDiff!.additions).toBe(0)
|
||||
expect(removedBDiff!.deletions).toBe(1)
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
test("diffFull with no changes", async () => {
|
||||
await using tmp = await bootstrap()
|
||||
await Instance.provide({
|
||||
directory: tmp.path,
|
||||
fn: async () => {
|
||||
const before = await Snapshot.track()
|
||||
expect(before).toBeTruthy()
|
||||
|
||||
const after = await Snapshot.track()
|
||||
expect(after).toBeTruthy()
|
||||
|
||||
const diffs = await Snapshot.diffFull(before!, after!)
|
||||
expect(diffs.length).toBe(0)
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
test("diffFull with binary file changes", async () => {
|
||||
await using tmp = await bootstrap()
|
||||
await Instance.provide({
|
||||
directory: tmp.path,
|
||||
fn: async () => {
|
||||
const before = await Snapshot.track()
|
||||
expect(before).toBeTruthy()
|
||||
|
||||
await Bun.write(`${tmp.path}/binary.bin`, new Uint8Array([0x00, 0x01, 0x02, 0x03]))
|
||||
|
||||
const after = await Snapshot.track()
|
||||
expect(after).toBeTruthy()
|
||||
|
||||
const diffs = await Snapshot.diffFull(before!, after!)
|
||||
expect(diffs.length).toBe(1)
|
||||
|
||||
const binaryDiff = diffs[0]
|
||||
expect(binaryDiff.file).toBe("binary.bin")
|
||||
expect(binaryDiff.before).toBe("")
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
test("diffFull with whitespace changes", async () => {
|
||||
await using tmp = await bootstrap()
|
||||
await Instance.provide({
|
||||
directory: tmp.path,
|
||||
fn: async () => {
|
||||
await Bun.write(`${tmp.path}/whitespace.txt`, "line1\nline2")
|
||||
const before = await Snapshot.track()
|
||||
expect(before).toBeTruthy()
|
||||
|
||||
await Bun.write(`${tmp.path}/whitespace.txt`, "line1\n\nline2\n")
|
||||
|
||||
const after = await Snapshot.track()
|
||||
expect(after).toBeTruthy()
|
||||
|
||||
const diffs = await Snapshot.diffFull(before!, after!)
|
||||
expect(diffs.length).toBe(1)
|
||||
|
||||
const whitespaceDiff = diffs[0]
|
||||
expect(whitespaceDiff.file).toBe("whitespace.txt")
|
||||
expect(whitespaceDiff.additions).toBeGreaterThan(0)
|
||||
},
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"$schema": "https://json.schemastore.org/package.json",
|
||||
"name": "@opencode-ai/plugin",
|
||||
"version": "0.15.10",
|
||||
"version": "0.15.11",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"typecheck": "tsgo --noEmit",
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"$schema": "https://json.schemastore.org/package.json",
|
||||
"name": "@opencode-ai/sdk",
|
||||
"version": "0.15.10",
|
||||
"version": "0.15.11",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"typecheck": "tsgo --noEmit",
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@opencode-ai/slack",
|
||||
"version": "0.15.10",
|
||||
"version": "0.15.11",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "bun run src/index.ts",
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@opencode-ai/ui",
|
||||
"version": "0.15.10",
|
||||
"version": "0.15.11",
|
||||
"type": "module",
|
||||
"exports": {
|
||||
".": "./src/components/index.ts",
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "@opencode-ai/web",
|
||||
"type": "module",
|
||||
"version": "0.15.10",
|
||||
"version": "0.15.11",
|
||||
"scripts": {
|
||||
"dev": "astro dev",
|
||||
"dev:remote": "VITE_API_URL=https://api.opencode.ai astro dev",
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
"name": "opencode",
|
||||
"displayName": "opencode",
|
||||
"description": "opencode for VS Code",
|
||||
"version": "0.15.10",
|
||||
"version": "0.15.11",
|
||||
"publisher": "sst-dev",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue