Skip to content

Commit d320177

Browse files
authored
fix(opencode): discontinue session sharing (#55718)
1 parent a95d9c0 commit d320177

20 files changed

Lines changed: 42 additions & 1183 deletions

File tree

‎github/action.yml‎

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ inputs:
1414
required: false
1515

1616
share:
17-
description: "Share the opencode session (defaults to true for public repos)"
17+
description: "Deprecated and ignored: session sharing was discontinued"
1818
required: false
1919

2020
prompt:
@@ -71,7 +71,6 @@ runs:
7171
env:
7272
MODEL: ${{ inputs.model }}
7373
AGENT: ${{ inputs.agent }}
74-
SHARE: ${{ inputs.share }}
7574
PROMPT: ${{ inputs.prompt }}
7675
USE_GITHUB_TOKEN: ${{ inputs.use_github_token }}
7776
MENTIONS: ${{ inputs.mentions }}

‎packages/app/src/pages/session/timeline/message-timeline.tsx‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -299,7 +299,8 @@ export function MessageTimeline(props: {
299299
const titleValue = createMemo(() => info()?.title)
300300
const titleLabel = createMemo(() => sessionTitle(titleValue()))
301301
const shareUrl = createMemo(() => info()?.share?.url)
302-
const shareEnabled = createMemo(() => sync().data.config.share !== "disabled")
302+
// Session sharing was discontinued; keep the share menu and popover hidden.
303+
const shareEnabled = () => false
303304
const parentID = createMemo(() => info()?.parentID)
304305
const parent = createMemo(() => {
305306
const id = parentID()

‎packages/app/src/pages/session/use-session-commands.tsx‎

Lines changed: 0 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -147,93 +147,6 @@ export const useSessionCommands = (actions: SessionCommandContext) => {
147147
if (sessionID) return permission.isAutoAccepting(sessionID, sdk().directory)
148148
return permission.isAutoAcceptingDirectory(sdk().directory)
149149
}
150-
const write = async (value: string) => {
151-
const body = typeof document === "undefined" ? undefined : document.body
152-
if (body) {
153-
const textarea = document.createElement("textarea")
154-
textarea.value = value
155-
textarea.setAttribute("readonly", "")
156-
textarea.style.position = "fixed"
157-
textarea.style.opacity = "0"
158-
textarea.style.pointerEvents = "none"
159-
body.appendChild(textarea)
160-
textarea.select()
161-
const copied = document.execCommand("copy")
162-
body.removeChild(textarea)
163-
if (copied) return true
164-
}
165-
166-
const clipboard = typeof navigator === "undefined" ? undefined : navigator.clipboard
167-
if (!clipboard?.writeText) return false
168-
return clipboard.writeText(value).then(
169-
() => true,
170-
() => false,
171-
)
172-
}
173-
174-
const copyShare = async (url: string, existing: boolean) => {
175-
if (!(await write(url))) {
176-
showToast({
177-
title: language.t("toast.session.share.copyFailed.title"),
178-
variant: "error",
179-
})
180-
return
181-
}
182-
183-
showToast({
184-
title: existing ? language.t("session.share.copy.copied") : language.t("toast.session.share.success.title"),
185-
description: language.t("toast.session.share.success.description"),
186-
variant: "success",
187-
})
188-
}
189-
190-
const share = async () => {
191-
const sessionID = params.id
192-
if (!sessionID) return
193-
194-
const existing = info()?.share?.url
195-
if (existing) {
196-
await copyShare(existing, true)
197-
return
198-
}
199-
200-
const url = await sdk()
201-
.client.session.share({ sessionID })
202-
.then((res) => res.data?.share?.url)
203-
.catch(() => undefined)
204-
if (!url) {
205-
showToast({
206-
title: language.t("toast.session.share.failed.title"),
207-
description: language.t("toast.session.share.failed.description"),
208-
variant: "error",
209-
})
210-
return
211-
}
212-
213-
await copyShare(url, false)
214-
}
215-
216-
const unshare = async () => {
217-
const sessionID = params.id
218-
if (!sessionID) return
219-
220-
await sdk()
221-
.client.session.unshare({ sessionID })
222-
.then(() =>
223-
showToast({
224-
title: language.t("toast.session.unshare.success.title"),
225-
description: language.t("toast.session.unshare.success.description"),
226-
variant: "success",
227-
}),
228-
)
229-
.catch(() =>
230-
showToast({
231-
title: language.t("toast.session.unshare.failed.title"),
232-
description: language.t("toast.session.unshare.failed.description"),
233-
variant: "error",
234-
}),
235-
)
236-
}
237150

238151
const exportSession = async () => {
239152
const sessionID = params.id
@@ -421,30 +334,6 @@ export const useSessionCommands = (actions: SessionCommandContext) => {
421334
)
422335
}
423336

424-
const shareCmds = () => {
425-
if (sync().data.config.share === "disabled") return []
426-
return [
427-
sessionCommand({
428-
id: "session.share",
429-
title: info()?.share?.url ? language.t("session.share.copy.copyLink") : language.t("command.session.share"),
430-
description: info()?.share?.url
431-
? language.t("toast.session.share.success.description")
432-
: language.t("command.session.share.description"),
433-
slash: "share",
434-
disabled: !params.id,
435-
onSelect: share,
436-
}),
437-
sessionCommand({
438-
id: "session.unshare",
439-
title: language.t("command.session.unshare"),
440-
description: language.t("command.session.unshare.description"),
441-
slash: "unshare",
442-
disabled: !params.id || !info()?.share?.url,
443-
onSelect: unshare,
444-
}),
445-
]
446-
}
447-
448337
const sessionCmds = () => [
449338
sessionCommand({
450339
id: "session.new",
@@ -645,7 +534,6 @@ export const useSessionCommands = (actions: SessionCommandContext) => {
645534

646535
command.register("session", () => [
647536
...sessionCmds(),
648-
...shareCmds(),
649537
...fileCmds(),
650538
...contextCmds(),
651539
...viewCmds(),

‎packages/opencode/src/cli/cmd/github.handler.ts‎

Lines changed: 10 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ import type {
1919
import { UI } from "../ui"
2020
import { ModelsDev } from "@opencode-ai/core/models-dev"
2121
import { InstanceRef } from "@/effect/instance-ref"
22-
import { SessionShare } from "@/share/session"
2322
import { Session } from "@/session/session"
2423
import type { SessionID } from "../../session/schema"
2524
import { MessageID, PartID } from "../../session/schema"
@@ -380,7 +379,6 @@ export const githubRun = Effect.fn("Cli.github.run")(function* (args: { event?:
380379
if (!ctx) return yield* Effect.die("InstanceRef not provided")
381380
const gitSvc = yield* Git.Service
382381
const sessionSvc = yield* Session.Service
383-
const sessionShare = yield* SessionShare.Service
384382
const sessionPrompt = yield* SessionPrompt.Service
385383
const events = yield* EventV2Bridge.Service
386384
const runLocalEffect = <A, E>(effect: Effect.Effect<A, E>) =>
@@ -407,7 +405,6 @@ export const githubRun = Effect.fn("Cli.github.run")(function* (args: { event?:
407405
const { providerID, modelID } = normalizeModel()
408406
const variant = process.env["VARIANT"] || undefined
409407
const runId = normalizeRunId()
410-
const share = normalizeShare()
411408
const oidcBaseUrl = normalizeOidcBaseUrl()
412409
const { owner, repo } = context.repo
413410
// For repo events (schedule, workflow_dispatch), payload has no issue/comment data
@@ -428,14 +425,12 @@ export const githubRun = Effect.fn("Cli.github.run")(function* (args: { event?:
428425
? (payload as IssueCommentEvent | IssuesEvent).issue.number
429426
: (payload as PullRequestEvent | PullRequestReviewCommentEvent).pull_request.number
430427
const runUrl = `/${owner}/${repo}/actions/runs/${runId}`
431-
const shareBaseUrl = isMock ? "https://dev.opencode.ai" : "https://opencode.ai"
432428

433429
let appToken: string
434430
let octoRest: Octokit
435431
let octoGraph: typeof graphql
436432
let gitConfig: string
437433
let session: { id: SessionID; title: string; version: string }
438-
let shareId: string | undefined
439434
let exitCode = 0
440435
let githubClientReady = false
441436
type PromptFiles = Awaited<ReturnType<typeof getUserPrompt>>["promptFiles"]
@@ -512,12 +507,6 @@ export const githubRun = Effect.fn("Cli.github.run")(function* (args: { event?:
512507
}),
513508
)
514509
await subscribeSessionEvents()
515-
shareId = await (async () => {
516-
if (share === false) return
517-
if (!share && repoData.data.private) return
518-
await runLocalEffect(sessionShare.share(session.id))
519-
return session.id.slice(-8)
520-
})()
521510
console.log("opencode session", session.id)
522511

523512
// Handle event types:
@@ -547,7 +536,7 @@ export const githubRun = Effect.fn("Cli.github.run")(function* (args: { event?:
547536
repoData.data.default_branch,
548537
branch,
549538
summary,
550-
`${response}\n\nTriggered by ${triggerType}${footer({ image: true })}`,
539+
`${response}\n\nTriggered by ${triggerType}${footer()}`,
551540
)
552541
if (pr) {
553542
console.log(`Created PR #${pr}`)
@@ -576,8 +565,7 @@ export const githubRun = Effect.fn("Cli.github.run")(function* (args: { event?:
576565
const summary = await summarize(response)
577566
await pushToLocalBranch(summary, uncommittedChanges)
578567
}
579-
const hasShared = prData.comments.nodes.some((c) => c.body.includes(`${shareBaseUrl}/s/${shareId}`))
580-
await createComment(`${response}${footer({ image: !hasShared })}`)
568+
await createComment(`${response}${footer()}`)
581569
await removeReaction(commentType)
582570
}
583571
// Fork PR
@@ -594,8 +582,7 @@ export const githubRun = Effect.fn("Cli.github.run")(function* (args: { event?:
594582
const summary = await summarize(response)
595583
await pushToForkBranch(summary, prData, uncommittedChanges)
596584
}
597-
const hasShared = prData.comments.nodes.some((c) => c.body.includes(`${shareBaseUrl}/s/${shareId}`))
598-
await createComment(`${response}${footer({ image: !hasShared })}`)
585+
await createComment(`${response}${footer()}`)
599586
await removeReaction(commentType)
600587
}
601588
}
@@ -610,7 +597,7 @@ export const githubRun = Effect.fn("Cli.github.run")(function* (args: { event?:
610597
if (switched) {
611598
// Agent switched branches (likely created its own branch/PR).
612599
// Don't push the stale infrastructure branch — just comment.
613-
await createComment(`${response}${footer({ image: true })}`)
600+
await createComment(`${response}${footer()}`)
614601
await removeReaction(commentType)
615602
} else if (dirty) {
616603
const summary = await summarize(response)
@@ -619,16 +606,16 @@ export const githubRun = Effect.fn("Cli.github.run")(function* (args: { event?:
619606
repoData.data.default_branch,
620607
branch,
621608
summary,
622-
`${response}\n\nCloses #${issueId}${footer({ image: true })}`,
609+
`${response}\n\nCloses #${issueId}${footer()}`,
623610
)
624611
if (pr) {
625-
await createComment(`Created PR #${pr}${footer({ image: true })}`)
612+
await createComment(`Created PR #${pr}${footer()}`)
626613
} else {
627-
await createComment(`${response}${footer({ image: true })}`)
614+
await createComment(`${response}${footer()}`)
628615
}
629616
await removeReaction(commentType)
630617
} else {
631-
await createComment(`${response}${footer({ image: true })}`)
618+
await createComment(`${response}${footer()}`)
632619
await removeReaction(commentType)
633620
}
634621
}
@@ -677,14 +664,6 @@ export const githubRun = Effect.fn("Cli.github.run")(function* (args: { event?:
677664
return value
678665
}
679666

680-
function normalizeShare() {
681-
const value = process.env["SHARE"]
682-
if (!value) return undefined
683-
if (value === "true") return true
684-
if (value === "false") return false
685-
throw new Error(`Invalid share value: ${value}. Share must be a boolean.`)
686-
}
687-
688667
function normalizeUseGithubToken() {
689668
const value = process.env["USE_GITHUB_TOKEN"]
690669
if (!value) return false
@@ -1351,18 +1330,8 @@ export const githubRun = Effect.fn("Cli.github.run")(function* (args: { event?:
13511330
}
13521331
}
13531332

1354-
function footer(opts?: { image?: boolean }) {
1355-
const image = (() => {
1356-
if (!shareId) return ""
1357-
if (!opts?.image) return ""
1358-
1359-
const titleAlt = encodeURIComponent(session.title.substring(0, 50))
1360-
const title64 = Buffer.from(session.title.substring(0, 700), "utf8").toString("base64")
1361-
1362-
return `<a href="${shareBaseUrl}/s/${shareId}"><img width="200" alt="${titleAlt}" src="https://social-cards.sst.dev/opencode-share/${title64}.png?model=${providerID}/${modelID}&version=${session.version}&id=${shareId}" /></a>\n`
1363-
})()
1364-
const shareUrl = shareId ? `[opencode session](${shareBaseUrl}/s/${shareId})&nbsp;&nbsp;|&nbsp;&nbsp;` : ""
1365-
return `\n\n${image}${shareUrl}[github run](${runUrl})`
1333+
function footer() {
1334+
return `\n\n[github run](${runUrl})`
13661335
}
13671336

13681337
async function fetchRepo() {

0 commit comments

Comments
 (0)