Skip to content

Commit b5a9e66

Browse files
committed
Merge branch 'dev' into fix/placeholder-color-5088
2 parents 7183ae3 + 070ced0 commit b5a9e66

File tree

1,171 files changed

+1545
-30
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

1,171 files changed

+1545
-30
lines changed

packages/desktop/src/components/prompt-input.tsx

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,43 @@ import { Button } from "@opencode-ai/ui/button"
1414
import { Icon } from "@opencode-ai/ui/icon"
1515
import { Tooltip } from "@opencode-ai/ui/tooltip"
1616
import { IconButton } from "@opencode-ai/ui/icon-button"
17+
import { ProviderIcon } from "@opencode-ai/ui/provider-icon"
1718
import { Select } from "@opencode-ai/ui/select"
1819
import { getDirectory, getFilename } from "@opencode-ai/util/path"
20+
import { type IconName } from "@opencode-ai/ui/icons/provider"
1921

2022
interface PromptInputProps {
2123
class?: string
2224
ref?: (el: HTMLDivElement) => void
2325
}
2426

25-
const PLACEHOLDERS = ["Fix a TODO in the codebase", "What is the tech stack of this project?", "Fix broken tests"]
27+
const PLACEHOLDERS = [
28+
"Fix a TODO in the codebase",
29+
"What is the tech stack of this project?",
30+
"Fix broken tests",
31+
"Explain how authentication works",
32+
"Find and fix security vulnerabilities",
33+
"Add unit tests for the user service",
34+
"Refactor this function to be more readable",
35+
"What does this error mean?",
36+
"Help me debug this issue",
37+
"Generate API documentation",
38+
"Optimize database queries",
39+
"Add input validation",
40+
"Create a new component for...",
41+
"How do I deploy this project?",
42+
"Review my code for best practices",
43+
"Add error handling to this function",
44+
"Explain this regex pattern",
45+
"Convert this to TypeScript",
46+
"Add logging throughout the codebase",
47+
"What dependencies are outdated?",
48+
"Help me write a migration script",
49+
"Implement caching for this endpoint",
50+
"Add pagination to this list",
51+
"Create a CLI command for...",
52+
"How do environment variables work here?",
53+
]
2654

2755
export const PromptInput: Component<PromptInputProps> = (props) => {
2856
const navigate = useNavigate()
@@ -43,7 +71,7 @@ export const PromptInput: Component<PromptInputProps> = (props) => {
4371
onMount(() => {
4472
const interval = setInterval(() => {
4573
setPlaceholder((prev) => (prev + 1) % PLACEHOLDERS.length)
46-
}, 5000)
74+
}, 6500)
4775
onCleanup(() => clearInterval(interval))
4876
})
4977

@@ -460,7 +488,7 @@ export const PromptInput: Component<PromptInputProps> = (props) => {
460488
{(i) => (
461489
<div class="w-full flex items-center justify-between gap-x-3">
462490
<div class="flex items-center gap-x-2.5 text-text-muted grow min-w-0">
463-
<img src={`https://models.dev/logos/${i.provider.id}.svg`} class="size-6 p-0.5 shrink-0" />
491+
<ProviderIcon name={i.provider.id as IconName} class="size-6 p-0.5 shrink-0" />
464492
<div class="flex gap-x-3 items-baseline flex-[1_0_0]">
465493
<span class="text-14-medium text-text-strong overflow-hidden text-ellipsis">{i.name}</span>
466494
<Show when={false}>

packages/desktop/src/context/global-sync.tsx

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,20 @@ const PASTEL_COLORS = [
3131
"#C1E1C1", // pastel mint
3232
]
3333

34-
function randomPastelColor() {
35-
return PASTEL_COLORS[Math.floor(Math.random() * PASTEL_COLORS.length)]
34+
function pickAvailableColor(usedColors: Set<string>) {
35+
const available = PASTEL_COLORS.filter((c) => !usedColors.has(c))
36+
if (available.length === 0) return PASTEL_COLORS[Math.floor(Math.random() * PASTEL_COLORS.length)]
37+
return available[Math.floor(Math.random() * available.length)]
3638
}
3739

38-
async function ensureProjectColor(project: Project, sdk: ReturnType<typeof useGlobalSDK>): Promise<Project> {
40+
async function ensureProjectColor(
41+
project: Project,
42+
sdk: ReturnType<typeof useGlobalSDK>,
43+
usedColors: Set<string>,
44+
): Promise<Project> {
3945
if (project.icon?.color) return project
40-
const color = randomPastelColor()
46+
const color = pickAvailableColor(usedColors)
47+
usedColors.add(color)
4148
const updated = { ...project, icon: { ...project.icon, color } }
4249
sdk.client.project.update({ projectID: project.id, icon: { color } })
4350
return updated
@@ -117,7 +124,8 @@ export const { use: useGlobalSync, provider: GlobalSyncProvider } = createSimple
117124
if (directory === "global") {
118125
switch (event.type) {
119126
case "project.updated": {
120-
ensureProjectColor(event.properties, sdk).then((project) => {
127+
const usedColors = new Set(globalStore.projects.map((p) => p.icon?.color).filter(Boolean) as string[])
128+
ensureProjectColor(event.properties, sdk, usedColors).then((project) => {
121129
const result = Binary.search(globalStore.projects, project.id, (s) => s.id)
122130
if (result.found) {
123131
setGlobalStore("projects", result.index, reconcile(project))
@@ -209,7 +217,8 @@ export const { use: useGlobalSync, provider: GlobalSyncProvider } = createSimple
209217
Promise.all([
210218
sdk.client.project.list().then(async (x) => {
211219
const filtered = x.data!.filter((p) => !p.worktree.includes("opencode-test") && p.vcs)
212-
const projects = await Promise.all(filtered.map((p) => ensureProjectColor(p, sdk)))
220+
const usedColors = new Set(filtered.map((p) => p.icon?.color).filter(Boolean) as string[])
221+
const projects = await Promise.all(filtered.map((p) => ensureProjectColor(p, sdk, usedColors)))
213222
setGlobalStore(
214223
"projects",
215224
projects.sort((a, b) => a.id.localeCompare(b.id)),

packages/enterprise/src/routes/share/[shareID].tsx

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { createEffect, createMemo, ErrorBoundary, For, Match, Show, Switch } fro
88
import { Share } from "~/core/share"
99
import { Logo, Mark } from "@opencode-ai/ui/logo"
1010
import { IconButton } from "@opencode-ai/ui/icon-button"
11+
import { ProviderIcon } from "@opencode-ai/ui/provider-icon"
1112
import { createDefaultOptions } from "@opencode-ai/ui/pierre"
1213
import { iife } from "@opencode-ai/util/iife"
1314
import { Binary } from "@opencode-ai/util/binary"
@@ -21,6 +22,7 @@ import { Tabs } from "@opencode-ai/ui/tabs"
2122
import { preloadMultiFileDiff, PreloadMultiFileDiffResult } from "@pierre/precision-diffs/ssr"
2223
import { Diff as SSRDiff } from "@opencode-ai/ui/diff-ssr"
2324
import { clientOnly } from "@solidjs/start"
25+
import { type IconName } from "@opencode-ai/ui/icons/provider"
2426

2527
const ClientOnlyDiff = clientOnly(() => import("@opencode-ai/ui/diff").then((m) => ({ default: m.Diff })))
2628

@@ -210,10 +212,7 @@ export default function () {
210212
<div class="text-12-mono text-text-base">v{info().version}</div>
211213
</div>
212214
<div class="flex gap-2 items-center">
213-
<img
214-
src={`https://models.dev/logos/${provider()}.svg`}
215-
class="size-3.5 shrink-0 dark:invert"
216-
/>
215+
<ProviderIcon name={provider() as IconName} class="size-3.5 shrink-0 text-icon-strong-base" />
217216
<div class="text-12-regular text-text-base">{model()?.name ?? modelID()}</div>
218217
</div>
219218
<div class="text-12-regular text-text-weaker">

packages/opencode/src/plugin/index.ts

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -61,14 +61,10 @@ export namespace Plugin {
6161
for (const hook of await state().then((x) => x.hooks)) {
6262
const fn = hook[name]
6363
if (!fn) continue
64-
try {
65-
// @ts-expect-error if you feel adventurous, please fix the typing, make sure to bump the try-counter if you
66-
// give up.
67-
// try-counter: 2
68-
await fn(input, output)
69-
} catch (e) {
70-
log.error("failed to trigger hook", { name, error: e })
71-
}
64+
// @ts-expect-error if you feel adventurous, please fix the typing, make sure to bump the try-counter if you
65+
// give up.
66+
// try-counter: 2
67+
await fn(input, output)
7268
}
7369
return output
7470
}

packages/opencode/src/session/prompt.ts

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1231,8 +1231,8 @@ export namespace SessionPrompt {
12311231
},
12321232
}
12331233
await Session.updatePart(part)
1234-
const shell = process.env["SHELL"] ?? "bash"
1235-
const shellName = path.basename(shell)
1234+
const shell = process.env["SHELL"] ?? (process.platform === "win32" ? process.env["COMSPEC"] || "cmd.exe" : "bash")
1235+
const shellName = path.basename(shell).toLowerCase()
12361236

12371237
const invocations: Record<string, { args: string[] }> = {
12381238
nu: {
@@ -1262,6 +1262,14 @@ export namespace SessionPrompt {
12621262
`,
12631263
],
12641264
},
1265+
// Windows cmd.exe
1266+
"cmd.exe": {
1267+
args: ["/c", input.command],
1268+
},
1269+
// Windows PowerShell
1270+
"powershell.exe": {
1271+
args: ["-NoProfile", "-Command", input.command],
1272+
},
12651273
// Fallback: any shell that doesn't match those above
12661274
"": {
12671275
args: ["-c", "-l", `${input.command}`],
@@ -1273,7 +1281,7 @@ export namespace SessionPrompt {
12731281

12741282
const proc = spawn(shell, args, {
12751283
cwd: Instance.directory,
1276-
detached: true,
1284+
detached: process.platform !== "win32",
12771285
stdio: ["ignore", "pipe", "pipe"],
12781286
env: {
12791287
...process.env,

packages/ui/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
"./context/*": "./src/context/*.tsx",
1111
"./styles": "./src/styles/index.css",
1212
"./styles/tailwind": "./src/styles/tailwind/index.css",
13+
"./icons/provider": "./src/components/provider-icons/types.ts",
14+
"./icons/file-type": "./src/components/file-icons/types.ts",
1315
"./fonts/*": "./src/assets/fonts/*"
1416
},
1517
"scripts": {
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.

0 commit comments

Comments
 (0)