Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/workflows/windows-advisory.yml
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ jobs:
test/config
test/project
test/worktree
test/file
test/file/
test/github
test/settings
test/settings.test.ts
Expand All @@ -176,11 +176,11 @@ jobs:
test/question
test/effect
test/agent
test/git
test/git/
test/storage
test/provider
test/pty
test/share
test/share/
test/script
test/memory
test/lsp
Expand Down
14 changes: 13 additions & 1 deletion packages/opencode/test/github/bun-version-workflow.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,14 @@ const workflowsRoot = path.join(repoRoot, ".github", "workflows")
const expectedBunVersion = "1.3.14"
const auditComment = "Load-bearing for `bun audit` exit semantics"

function repoRelativeWorkflowPath(workflowPath: string) {
return normalizeWorkflowPath(path.relative(repoRoot, workflowPath))
}

function normalizeWorkflowPath(relativePath: string) {
return relativePath.replaceAll("\\", "/")
}

function collectSetupBunPins(workflow: Workflow, relativePath: string) {
const pins: string[] = []

Expand All @@ -25,6 +33,10 @@ function collectSetupBunPins(workflow: Workflow, relativePath: string) {
}

describe("GitHub workflow Bun version pin", () => {
test("normalizes workflow paths for cross-platform assertions", () => {
expect(normalizeWorkflowPath(".github\\workflows\\ci.yml")).toBe(".github/workflows/ci.yml")
})

test("detects setup-bun steps that omit bun-version", () => {
const workflow: Workflow = {
jobs: {
Expand Down Expand Up @@ -55,7 +67,7 @@ describe("GitHub workflow Bun version pin", () => {
const missingComments: string[] = []

for (const workflowPath of workflowFiles) {
const relativePath = path.relative(repoRoot, workflowPath)
const relativePath = repoRelativeWorkflowPath(workflowPath)
setupBunPins.push(...collectSetupBunPins(parseWorkflow(workflowPath), relativePath))

const lines = fs.readFileSync(workflowPath, "utf8").split(/\r?\n/)
Expand Down
26 changes: 24 additions & 2 deletions packages/opencode/test/github/ci-workflow.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,14 +66,14 @@ const windowsOpencodeShards = [
suffix: "opencode-config-project",
usesTurbo: false,
command:
"cd packages/opencode && bun test --timeout 30000 --reporter=junit --reporter-outfile=.artifacts/unit/junit-windows-config-project.xml test/config test/project test/worktree test/file test/github test/settings test/settings.test.ts",
"cd packages/opencode && bun test --timeout 30000 --reporter=junit --reporter-outfile=.artifacts/unit/junit-windows-config-project.xml test/config test/project test/worktree test/file/ test/github test/settings test/settings.test.ts",
reportPath: "packages/opencode/.artifacts/unit/junit-windows-config-project.xml",
},
{
suffix: "opencode-server-tools",
usesTurbo: false,
command:
"cd packages/opencode && bun test --timeout 30000 --reporter=junit --reporter-outfile=.artifacts/unit/junit-windows-server-tools.xml test/server test/snapshot test/tool test/mcp test/question test/effect test/agent test/git test/storage test/provider test/pty test/share test/script test/memory test/lsp test/fixture test/acp test/bus test/cli test/global test/format test/account test/sync test/filesystem test/patch test/shell test/control-plane test/ide test/installation test/auth",
"cd packages/opencode && bun test --timeout 30000 --reporter=junit --reporter-outfile=.artifacts/unit/junit-windows-server-tools.xml test/server test/snapshot test/tool test/mcp test/question test/effect test/agent test/git/ test/storage test/provider test/pty test/share/ test/script test/memory test/lsp test/fixture test/acp test/bus test/cli test/global test/format test/account test/sync test/filesystem test/patch test/shell test/control-plane test/ide test/installation test/auth",
reportPath: "packages/opencode/.artifacts/unit/junit-windows-server-tools.xml",
},
] as const
Expand Down Expand Up @@ -149,6 +149,19 @@ function expandOpencodeTestPath(testPath: string): string[] {
return [testPath]
}

function ambiguousDirectoryShardArgs(testPaths: string[]) {
const testRootEntries = readdirSync(opencodeTestRoot, { withFileTypes: true })
.filter((entry) => entry.isDirectory())
.map((entry) => `test/${entry.name}`)
const testRootEntrySet = new Set(testRootEntries)

return testPaths.filter((testPath) => {
if (testPath.endsWith("/")) return false
if (!testRootEntrySet.has(testPath)) return false
return testRootEntries.some((entry) => entry !== testPath && entry.startsWith(testPath))
})
}

function testPathArgs(command: string) {
const testArgs = command.split(" bun test ")[1]
if (!testArgs) {
Expand Down Expand Up @@ -601,6 +614,15 @@ describe("ci workflow", () => {
})
})

test("keeps Windows opencode shard paths from prefix-matching sibling test directories", () => {
const parsed = parseWorkflow(windowsAdvisoryWorkflowPath)
const matrixIncludes = parsed.jobs?.[windowsUnitJobName]?.strategy?.matrix?.include ?? []
const opencodeShards = matrixIncludes.filter(isWindowsOpencodeShard)
const shardArgs = opencodeShards.flatMap((item) => testPathArgs(item.command))

expect(ambiguousDirectoryShardArgs(shardArgs)).toEqual([])
})

test("keeps docs-only behavior and excludes Windows from the blocking aggregate", () => {
const parsed = parseWorkflow(ciWorkflowPath)
const check = parsed.jobs?.check
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,10 @@ describe("session.listGlobal activity order", () => {

await Instance.provide({
directory: tmp.path,
fn: async () => userMessageWithSyntheticReminder(oldMixedUser.id, 4_000),
fn: async () => {
now = 4_000
return userMessageWithSyntheticReminder(oldMixedUser.id, 4_000)
},
})

const sessions = [
Expand Down
2 changes: 1 addition & 1 deletion packages/opencode/test/session/processor-effect.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1645,7 +1645,7 @@ it.live("disabled unknown tools do not block safe connect-timeout auto retry", (
inputSchema: z.object({}),
}),
},
connectTimeoutMs: 20,
connectTimeoutMs: 250,
streamTimeoutMs: 1_000,
})

Expand Down
31 changes: 31 additions & 0 deletions packages/opencode/test/session/run-observability.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { describe, expect, test } from "bun:test"
import { LLM } from "../../src/session/llm"
import { MessageID, SessionID } from "../../src/session/schema"
import { RunIncident } from "../../src/session/run-incident"
import { RunObservability } from "../../src/session/run-observability"
Expand Down Expand Up @@ -1281,6 +1282,36 @@ describe("RunObservability", () => {
})
})

test("disabled unknown tools are absent from before-progress retry boundary proof", () => {
const tools = LLM.resolveTools({
agent: { permission: [] } as never,
permission: [],
user: { tools: { mcp_write: false } } as never,
tools: {
read: {},
mcp_write: {},
} as never,
})
const snapshot = RunObservability.sideEffectBoundarySnapshot(tools)
const decision = recoveryForBeforeProgress({
side_effect_facts_complete: true,
side_effect_boundary_snapshot: snapshot,
})

expect(Object.keys(tools)).toEqual(["read"])
expect(snapshot).toMatchObject({
exposed_tool_count: 1,
unknown_tool_count: 0,
unclassified_effect_count: 0,
proof_result: "complete",
proof_reason: "all_boundaries_classified",
})
expect(decision).toMatchObject({
recommendation: "auto_retry_once",
reason: "no_visible_output_or_tool_execution",
})
})

test("before-progress retry stays conservative when the boundary snapshot is missing", () => {
const decision = recoveryForBeforeProgress({ side_effect_boundary_snapshot: undefined })

Expand Down
Loading