Skip to content
Open
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
22 changes: 21 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@ jobs:
quality:
name: Format, Lint, Typecheck, Test, Browser Test, Build
runs-on: ubuntu-latest
timeout-minutes: 20
# 20 minutes starves dependency-bump branches: a lockfile change cold-starts
# every cache and slow runners then hit the cap mid-pipeline.
timeout-minutes: 30
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
Expand Down Expand Up @@ -58,12 +60,30 @@ jobs:
- name: Test
run: vp exec vp run test

# Hosted runners point apt at azure.archive.ubuntu.com, which
# intermittently stalls for 20+ minutes and starves the job timeout.
# Ubuntu 24.04 keeps the active mirror in apt-mirrors.txt, while older
# images use .list or .sources files, so update every supported format.
- name: Use main Ubuntu mirror for apt
run: sudo find /etc/apt -type f \( -name "*.list" -o -name "*.sources" -o -name "apt-mirrors.txt" \) -exec sed -i 's|azure.archive.ubuntu.com|archive.ubuntu.com|g' {} +

- name: Install browser test runtime
timeout-minutes: 10
run: vp exec vp run --filter @threadlines/web test:browser:install

- name: Browser test
run: vp exec vp run --filter @threadlines/web test:browser

# Browser test failures are timing-sensitive and CI-only more often than
# not; the on-failure screenshot is the only evidence of what rendered.
- name: Upload browser test failure screenshots
if: failure()
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
with:
name: browser-test-screenshots
path: apps/web/src/**/__screenshots__/**
if-no-files-found: ignore

- name: Build desktop pipeline
run: vp exec vp run build:desktop

Expand Down
2 changes: 1 addition & 1 deletion apps/marketing/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
},
"dependencies": {
"@vercel/analytics": "^2.0.1",
"astro": "^7.2.0"
"astro": "^7.2.3"
},
"devDependencies": {
"@astrojs/check": "^0.9.10",
Expand Down
2 changes: 1 addition & 1 deletion apps/relay-worker/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,6 @@
"vite": "catalog:",
"vite-plus": "catalog:",
"vitest": "catalog:",
"wrangler": "^4.123.0"
"wrangler": "^4.124.0"
}
}
2 changes: 1 addition & 1 deletion apps/server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
"@effect/platform-node": "catalog:",
"@effect/platform-node-shared": "catalog:",
"@effect/sql-sqlite-bun": "catalog:",
"@opencode-ai/sdk": "^1.18.15",
"@opencode-ai/sdk": "^1.18.18",
"@pierre/diffs": "catalog:",
"effect": "catalog:",
"node-pty": "^1.1.0"
Expand Down
4 changes: 4 additions & 0 deletions apps/server/src/provider/Layers/ClaudeAdapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6124,6 +6124,10 @@ export const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (
...(runsInManagedWorktree ? { append: MANAGED_WORKTREE_INSTRUCTION } : {}),
},
settingSources: [...CLAUDE_SETTING_SOURCES],
// SDK 0.3.233 dropped the todo/task tools from the default tool
// surface on newer models; the plan timeline reads them, so keep
// them enabled explicitly.
allowedTools: ["TodoWrite", "TaskCreate", "TaskGet", "TaskUpdate", "TaskList"],
...(effectiveEffort
? {
effort: effectiveEffort,
Expand Down
10 changes: 5 additions & 5 deletions apps/web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,12 @@
"@effect/atom-react": "catalog:",
"@fontsource-variable/cascadia-mono": "^5.3.0",
"@fontsource-variable/schibsted-grotesk": "^5.3.0",
"@legendapp/list": "^3.3.3",
"@legendapp/list": "^3.3.7",
"@lexical/react": "^0.47.0",
"@pierre/diffs": "catalog:",
"@tanstack/react-pacer": "^0.23.0",
"@tanstack/react-query": "^5.101.4",
"@tanstack/react-router": "^1.170.22",
"@tanstack/react-router": "^1.170.29",
"@threadlines/client-runtime": "workspace:*",
"@threadlines/contracts": "workspace:*",
"@threadlines/shared": "workspace:*",
Expand All @@ -34,18 +34,18 @@
"class-variance-authority": "^0.7.1",
"effect": "catalog:",
"lexical": "^0.47.0",
"lucide-react": "^1.30.0",
"lucide-react": "^1.32.0",
"react": "19.2.8",
"react-dom": "19.2.8",
"react-markdown": "^10.1.0",
"remark-gfm": "^4.0.1",
"tailwind-merge": "^3.4.0",
"zustand": "^5.0.11"
"zustand": "^5.0.15"
},
"devDependencies": {
"@rolldown/plugin-babel": "^0.2.0",
"@tailwindcss/vite": "^4.3.3",
"@tanstack/router-plugin": "^1.168.31",
"@tanstack/router-plugin": "^1.168.32",
"@types/babel__core": "^7.20.5",
"@types/react": "~19.2.18",
"@types/react-dom": "~19.2.4",
Expand Down
29 changes: 19 additions & 10 deletions apps/web/src/components/ChatView.browser.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ import {
import { type TerminalContextDraft } from "../lib/terminalContext";
import { isMacPlatform } from "../lib/utils";
import { __resetLocalApiForTests } from "../localApi";
import { useOptimisticThreadMessagesStore } from "../optimisticThreadMessages";
import { AppAtomRegistryProvider } from "../rpc/atomRegistry";
import { getServerConfig } from "../rpc/serverState";
import { getRouter } from "../router";
Expand Down Expand Up @@ -2187,6 +2188,7 @@ describe("ChatView timeline estimator parity (full app)", () => {
stickyModelSelectionByProvider: {},
stickyActiveProvider: null,
});
useOptimisticThreadMessagesStore.setState({ messagesByThreadKey: {} });
useCommandPaletteStore.setState({
open: false,
openIntent: null,
Expand Down Expand Up @@ -9618,16 +9620,23 @@ describe("ChatView timeline estimator parity (full app)", () => {
});

try {
const sourceMessageText = page.getByText("Original prompt for branching.", { exact: true });
await sourceMessageText.hover();
const sourceMessageRow = sourceMessageText
.element()
.closest<HTMLElement>(`[data-message-id="${sourceMessageId}"]`);
const editAndBranchButton = sourceMessageRow?.querySelector<HTMLButtonElement>(
'button[aria-label="Edit and branch"]',
);
expect(editAndBranchButton).not.toBeNull();
await page.elementLocator(editAndBranchButton!).click();
const sourceMessageRow = await waitForElement(
() => document.querySelector<HTMLElement>(`[data-message-id="${sourceMessageId}"]`),
() =>
`Source message did not render. Rendered message ids: ${[
...document.querySelectorAll<HTMLElement>("[data-message-id]"),
]
.map((element) => element.dataset.messageId)
.join(", ")}`,
);
expect(sourceMessageRow.textContent).toContain("Original prompt for branching.");
await page.elementLocator(sourceMessageRow).hover();
const editAndBranchButton = await waitForElement(
() =>
sourceMessageRow.querySelector<HTMLButtonElement>('button[aria-label="Edit and branch"]'),
"Edit-and-branch button did not render for the source message.",
);
await page.elementLocator(editAndBranchButton).click();
await expect
.element(page.getByText("Edit this prompt in a new thread?", { exact: true }))
.toBeInTheDocument();
Expand Down
2 changes: 1 addition & 1 deletion oxlint-plugin-threadlines/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
},
"dependencies": {
"@effect/platform-node": "catalog:",
"@oxlint/plugins": "^1.77.0",
"@oxlint/plugins": "^1.78.0",
"effect": "catalog:"
},
"devDependencies": {
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@
},
"devDependencies": {
"@effect/tsgo": "catalog:",
"@oxlint/plugins": "^1.77.0",
"@oxlint/plugins": "^1.78.0",
"@types/node": "catalog:",
"@typescript/native-preview": "catalog:",
"vite": "catalog:",
Expand Down
Loading
Loading