From 5c4370a8fe1845ff8214dd3834054217595f3e65 Mon Sep 17 00:00:00 2001 From: EtienneLescot Date: Wed, 24 Jun 2026 15:24:47 +0200 Subject: [PATCH] =?UTF-8?q?docs+ci:=20add=20public=20ROADMAP.md,=20README?= =?UTF-8?q?=20link,=20and=20#=F0=9F=97=BA=EF=B8=8F=E3=83=BBroadmap=20auto-?= =?UTF-8?q?post?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add ROADMAP.md at repo root for top-level discoverability. - Stability queue pulled from open issues / PRs on getopenscreen/openscreen (#8, #21, #22, #19, #18, #24). - AI direction framed as opt-in / off by default, with per-feature tags. - Link the new roadmap from the README Community section. - Extend .github/workflows/discord.yaml with a roadmap-notify job that posts an embed to the #🗺️・roadmap Discord channel whenever a PR changes ROADMAP.md (or docs/roadmap.md). Mirrors the existing PR -> #pr-reviews sync pattern. Activated by setting the DISCORD_ROADMAP_WEBHOOK_URL repo secret; silently skipped otherwise so CI never breaks. --- .github/workflows/discord.yaml | 119 +++++++++++++++++++++++++++++++++ README.md | 1 + ROADMAP.md | 53 +++++++++++++++ 3 files changed, 173 insertions(+) create mode 100644 ROADMAP.md diff --git a/.github/workflows/discord.yaml b/.github/workflows/discord.yaml index 950abae3d..9266d2b7a 100644 --- a/.github/workflows/discord.yaml +++ b/.github/workflows/discord.yaml @@ -514,3 +514,122 @@ jobs: const txt = await res.text(); core.setFailed(`Leaderboard post failed ${res.status}: ${txt}`); } + + # Posts a notification to the #🗺️・roadmap Discord channel whenever a PR + # changes ROADMAP.md (the public roadmap file). This mirrors the way the + # `notify` job above syncs PR activity to the 🔎・pr-reviews channel — + # the user-facing community gets pinged in Discord when the roadmap moves. + # + # Required secret: + # DISCORD_ROADMAP_WEBHOOK_URL — webhook URL of the #🗺️・roadmap channel + # Optional (re-used from the existing notify job): + # DISCORD_WEBHOOK_USERNAME, DISCORD_WEBHOOK_AVATAR_URL + roadmap-notify: + if: github.event_name == 'pull_request_target' + concurrency: + group: discord-roadmap-sync-${{ github.repository }}-${{ github.event.pull_request.number }} + cancel-in-progress: true + runs-on: ubuntu-latest + steps: + - name: Post roadmap change to #🗺️・roadmap Discord channel + continue-on-error: true + uses: actions/github-script@v7 + env: + DISCORD_ROADMAP_WEBHOOK_URL: ${{ secrets.DISCORD_ROADMAP_WEBHOOK_URL }} + DISCORD_WEBHOOK_USERNAME: ${{ secrets.DISCORD_WEBHOOK_USERNAME }} + DISCORD_WEBHOOK_AVATAR_URL: ${{ secrets.DISCORD_WEBHOOK_AVATAR_URL }} + with: + script: | + const ROADMAP_PATTERN = /(^|\/)ROADMAP\.md$|(^|\/)docs\/roadmap\.md$/i; + const VALID_ACTIONS = ["opened", "reopened", "synchronize", "closed"]; + + const pr = context.payload.pull_request; + if (!pr) { + core.info("No PR context; skipping roadmap notify."); + return; + } + + const action = context.payload.action || ""; + if (!VALID_ACTIONS.includes(action)) { + core.info(`Skipping roadmap notify for action '${action}'.`); + return; + } + + let files; + try { + const res = await github.rest.pulls.listFiles({ + owner: context.repo.owner, + repo: context.repo.repo, + pull_number: pr.number, + per_page: 100, + }); + files = res.data; + } catch (err) { + core.warning(`Failed to list PR files: ${err && err.message ? err.message : err}`); + return; + } + + const roadmapFiles = files.filter(f => ROADMAP_PATTERN.test(f.filename)); + if (roadmapFiles.length === 0) { + core.info("No roadmap files in PR; skipping roadmap notify."); + return; + } + + const webhookUrl = (process.env.DISCORD_ROADMAP_WEBHOOK_URL || "").trim(); + if (!webhookUrl) { + core.info("DISCORD_ROADMAP_WEBHOOK_URL not set; skipping roadmap notify. Add it as a repo secret to enable #🗺️・roadmap auto-posts."); + return; + } + + const webhookUsername = (process.env.DISCORD_WEBHOOK_USERNAME || "OpenScreen").trim(); + const webhookAvatar = (process.env.DISCORD_WEBHOOK_AVATAR_URL || "").trim(); + + const fileList = roadmapFiles.map(f => { + const icon = f.status === "added" ? "🆕" : f.status === "removed" ? "🗑️" : "✏️"; + return `${icon} \`${f.filename}\` (+${f.additions}/-${f.deletions})`; + }).join("\n"); + + const isMerged = action === "closed" && !!pr.merged; + const titlePrefix = isMerged ? "✅ Roadmap merged" : "🗺️ Roadmap updated"; + const color = isMerged ? 5763719 : 1998671; + const status = pr.draft ? "Draft" : (isMerged ? "Merged" : (action === "closed" ? "Closed (not merged)" : "Open")); + + const description = (pr.body || "No description provided.").trim() || "No description provided."; + + const payload = { + username: webhookUsername, + ...(webhookAvatar ? { avatar_url: webhookAvatar } : {}), + content: `${titlePrefix} via PR #${pr.number}`, + embeds: [ + { + title: `${pr.title} • #${pr.number}`, + url: pr.html_url, + description: description.length > 1800 ? description.slice(0, 1799) + "…" : description, + color, + fields: [ + { name: "Roadmap files", value: fileList, inline: false }, + { name: "Author", value: `[${pr.user?.login || "unknown"}](${pr.user?.html_url || pr.html_url})`, inline: true }, + { name: "Status", value: status, inline: true }, + ], + footer: { text: `${context.repo.owner}/${context.repo.repo}` }, + timestamp: new Date().toISOString(), + }, + ], + allowed_mentions: { parse: [] }, + }; + + try { + const res = await fetch(`${webhookUrl}?wait=true`, { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify(payload), + }); + if (!res.ok) { + const txt = await res.text(); + core.warning(`Roadmap Discord notify failed ${res.status}: ${txt}`); + return; + } + core.info(`Roadmap Discord notify posted for PR #${pr.number} (${roadmapFiles.length} file(s)).`); + } catch (err) { + core.warning(`Roadmap Discord notify threw: ${err && err.message ? err.message : err}`); + } diff --git a/README.md b/README.md index 92ead588b..2a58e132d 100644 --- a/README.md +++ b/README.md @@ -167,6 +167,7 @@ OpenScreen is community-driven. If you need help, want to report a bug, or just - 💬 **Discord** — [Join the OpenScreen Discord](https://discord.gg/VvT6Vtnyh) for real-time help, showcase, and discussion - 🐞 **[GitHub Issues](https://github.com/EtienneLescot/openscreen/issues)** — bug reports and feature requests +- 🗺️ **[Roadmap](./ROADMAP.md)** — see what we're building next --- diff --git a/ROADMAP.md b/ROADMAP.md new file mode 100644 index 000000000..28d73902d --- /dev/null +++ b/ROADMAP.md @@ -0,0 +1,53 @@ +# OpenScreen Roadmap +The recorder you love, with an optional AI sidekick. Same sleek, low-friction recorder UX. An opt-in AI editing layer is on the way for users who want it — never required, never snuck in. + +This roadmap is the source of truth for what we're shipping next in OpenScreen. It is a living document — items move between tiers as work lands. Have an idea, a vote, or a dissenting opinion? Drop into the 🗺️・roadmap channel on our Discord or open a GitHub issue with the `roadmap` label. + +## 🧭 North Star +**Record → Edit → Export.** (with an optional AI shortcut for users who want one) + +OpenScreen is, first and foremost, a polished screen recorder. Record, trim on the timeline, export. Most users will keep using exactly this workflow. + +We're also exploring an optional AI editing layer — for users who want to edit by talking or by editing a transcript. It's opt-in, off by default, and never required. If you don't enable it, the AI layer doesn't exist for your install: nothing downloads, nothing leaves your machine, no LLM is contacted. + +Three axes guide every decision on this roadmap: + +- **Stability first** — the recorder must work reliably on macOS, Windows, and Linux. Bugs found by real users ship before new features. +- **Sleek UX stays** — every AI feature must keep the OpenScreen feel: minimal clicks, instant feedback, no clutter. +- **100% free, forever** — no paywalls, no premium tier, no usage caps. Every feature on this page ships under MIT. + +## 🤖 Direction — the optional AI Edition +A Screen Studio + Descript clone, open-source and free forever. The recorder-first UX stays intact, and the AI layer sits beside it, off by default. + +Capabilities we're exploring (each one opt-in, each one toggleable independently): + +- **Local Whisper transcription (opt-in, on-device)** — OpenScreen already ships on-device Whisper transcription for automatic captions. This extends that foundation: the same local transcript powers the editing features below, with no upload, no cloud, no extra setup required. +- **Transcript-driven editing (opt-in, local)** — edit video like a doc (Descript-style: delete a word, cut the span). Works with the local transcript; no cloud needed. +- **One-click cleanup (opt-in, local)** — filler-word removal, silence trimming, Studio Sound voice enhancement. All on-device. +- **Edit by chat (opt-in, requires BYO LLM key)** — say "cut the part where I repeat myself between 0:42 and 1:10" and the agent applies a structured timeline operation. Off until you connect a provider. +- **Non-destructive project document (always on)** — every edit, AI or manual, is undoable; the timeline is always recoverable. +- **Bring-your-own LLM (opt-in)** — OpenAI, Anthropic, Google, Mistral, OpenRouter, GitHub Copilot, OpenAI-compatible endpoints, ChatGPT account auth. You choose; we never see your keys or your data. + +This section is a direction, not a sprint plan. Concrete items land here as RFCs once the recorder is stable enough to build on top of. + +## 🛠️ Stability & quality (what we're actually shipping) +Pulled from real user bug reports on getopenscreen/openscreen. This is the queue for the next release window. + +- [ ] **Fix:** video disappears from editor after export — [#8](../../issues/8) (Linux, Manjaro). Renderer regression after export. +- [ ] **Fix:** crash after stopping macOS recording — [#21](../../issues/21) (macOS 26.4.1, Apple Silicon). Crash is in the Electron / Node async fs shutdown path; recording artifacts are written correctly. +- [ ] **Fix:** macOS cursor offset in single-window capture — [#22](../../issues/22). +- [ ] **Fix:** recover preview from WebGL context loss on Linux / Wayland — [#19](../../issues/19). +- [ ] **Feature:** software H.264 fallback when no GPU encoder MFT is available — [#18](../../issues/18). Critical for VMs, broken-driver machines, and headless environments. +- [ ] **Feature:** copy / paste attributes & effects in the timeline — [#24](../../issues/24). Right-click menu + standard Ctrl/Cmd+C / Ctrl/Cmd+V shortcuts. + +## 📬 How to influence this roadmap +- **Discord** — join the OpenScreen Discord and post in [#🗺️・roadmap](). The fastest way to get a thumbs-up or thumbs-down on a feature. +- **GitHub** — open an issue with the `enhancement` label, or react with 👍 / 👎 on existing items. +- **PRs** — if you want to ship one of these, open a PR and link the relevant issue. We review fast and help with native-bridge / i18n questions. + +Anything not on this list yet? Open an issue and tag it `roadmap` — we'll triage it into a tier within a week. + +--- + +## Changelog +- **2026-06-24** — initial draft. Stability items pulled from open issues / PRs on getopenscreen/openscreen. AI section presented as opt-in / off by default. Whisper entry updated to reflect existing caption feature. \ No newline at end of file