Mentions

Conversations linking to GitHub, newest first. Times are UTC.

Mentions by source

X

6,534
Nov 2, 11:00Nov 3, 11:00

Bluesky

1,977
Nov 2, 13:00Nov 3, 13:00

Reddit

2,159
Nov 2, 13:00Nov 3, 13:00
Nov 2, 13:00Nov 3, 13:00
Nov 2, 13:00Nov 3, 13:00
Nov 2, 13:00Nov 3, 13:00
Nov 2, 13:00Nov 3, 13:00
Nov 2, 13:00Nov 3, 13:00
Oct 14, 21:00Oct 15, 21:00

Delayed · data through Oct 15, 21:00 UTC

DEV

726
Nov 2, 13:00Nov 3, 13:00
Nov 2, 13:00Nov 3, 13:00
Nov 2, 12:00Nov 3, 12:00
Nov 2, 13:00Nov 3, 13:00
Oct 28, 01:00Oct 29, 01:00

Delayed · data through Oct 29, 01:00 UTC

Nov 2, 13:00Nov 3, 13:00
Nov 2, 13:00Nov 3, 13:00

Latest posts

  1. Redditu/ShakaLaka_Around · r/BootstrappedStacks · 1 point

    I added a dialer to my open-source LinkedIn/email outreach tool (opening-hours queue, scripts, call logging) I’m the author of Linki, an open-source outreach tool I built because I wanted one place to run my own outbound. You import a lead list from Sales Navigator, clean it, and run multichannel campaigns (LinkedIn + email) where an AI agent personalizes each message per lead. It also has a unified inbox and Apollo enrichment. The one channel it was missing was phone, and I was juggling calls in a separate tool. So I built a simple dialer into it. What it does: Queue by opening hours. You set opening hours per contact, and the queue sorts into open now, closing soon and later. Useful when you call businesses with fixed hours (I tested it on law firms). Scripts with variables. You write a script once, and it shows next to the call with the lead’s name and other fields filled in. One-click calling. It uses Phone Link on Windows, so the call goes through your own phone. No cloud telephony, no per-minute cost. I haven’t tested it on Mac, so if you try it there, tell me whether it works. Call outcomes. After each call you log reached, no answer, voicemail or callback. Picking callback asks when, logs it, and can create a to-do. Leads in a cooldown move to a waiting bucket and come back on schedule. Context on the side. Notes, past activity and to-dos for the contact are next to the call screen. There’s also a small cheerleader buddy, because cold calling is a lot of rejection and it helped me more than I expected. It’s simple on purpose. I’ve used it a lot over the last few days and it’s already replaced my spreadsheet. Repo: moaljumaa/linki I’d like to hear what breaks, especially on Mac and with other call setups.

  2. Diffing two PDFs in the browser: PDFs don't have lines, so you have to rebuild them ``A common request for a PDF tool: "they sent the contract back with a few small changes, what actually changed?" I wanted to answer that without uploading anyone's contract to a server, so the comparison runs entirely in the browser tab. The diff part is easy: jsdiff does it in one call. The hard part is getting text you can diff out of a PDF, because a PDF has no idea what a "line" is. What a PDF actually stores A PDF page isn't a document with paragraphs. It's a list of drawing instructions: "move to (72, 700), draw these glyphs, move to (210, 700), draw these glyphs". Text can be drawn in any order, split anywhere, and positioned anywhere. pdf.js gives you that as getTextContent(): a flat list of text items, each with a string and a transform matrix. The last two values of the matrix, transform[4] and transform[5], are the item's x and y position on the page. So a single visual line like Notice period: 30 days might come back as three items ("Notice period:", "30", "days"), all with the same y. Rebuilding lines My first version groups items by their (rounded) y coordinate, then sorts the groups top to bottom. PDF coordinates start at the bottom-left, so "top to bottom" means sorting y descending: export async function getPageLines(pdf: PDFDocumentProxy, pageNumber: number): Promise<string[]> { const page = await pdf.getPage(pageNumber); const content = await page.getTextContent(); const lines = new Map<number, string[]>(); for (const item of content.items) { if (!("str" in item)) continue; // skip marked-content items const y = Math.round(item.transform[5]); const bucket = lines.get(y) ?? []; bucket.push(item.str); lines.set(y, bucket); } const sortedYs = Array.from(lines.keys()).sort((a, b) => b - a); return sortedYs .map((y) => lines.get(y)!.join(" ").trim()) .filter((line) => line.length > 0); } This same helper turned out to be useful well beyond comparing: PDF to Word, PDF to HTML, PDF to Excel and PDF to EPUB all start from "give me the lines of each page". Diffing With lines per page, the comparison itself is short. Flatten both documents into one string each and let jsdiff do a line diff: import { diffLines, type Change } from "diff"; export async function comparePdfs(fileA: File, fileB: File): Promise<Change[]> { const [pagesA, pagesB] = await Promise.all([getAllPageLines(fileA), getAllPageLines(fileB)]); const textA = pagesA.flat().join("\n"); const textB = pagesB.flat().join("\n"); return diffLines(textA, textB); } diffLines returns an array of Change objects with added / removed flags, which map directly onto green and red blocks in the UI. Both PDFs are parsed in parallel, and nothing leaves the tab. pdf.js itself has to be loaded lazily in Next.js (it touches DOMMatrix at import time, which breaks server prerendering), so getPdfjs() does a dynamic import("pdfjs-dist") the first time it's needed. Where the naive version gets it wrong This works well for the main use case, contracts and letters that went through a small edit. But "group by y" has sharp edges, and I'd rather list them than pretend they don't exist: 1. Items on a line aren't sorted by x. I join them in the order the PDF drew them. Most generators draw left to right, but not all. Sorting each bucket by transform[4] is the obvious fix. 2. Exact y matching is fragile. Superscripts, mixed fonts, or a baseline off by 0.6pt can split one visual line into two. Bucketing with a tolerance (say, a fraction of the font height) instead of Math.round would be more robust. 3. Two-column layouts merge. Left and right columns at the same y become one "line". You'd need to detect columns by x gaps first. 4. Re-wrapping looks like a total rewrite. If one word is added early in a paragraph and the text re-flows, every following line in the paragraph changes. A line diff reports the whole paragraph as changed. Running a word diff (diffWords) inside changed blocks would show the actual edit. 5. Headers, footers and page numbers add noise, especially if pagination shifts by a page. 6. Scanned PDFs have no text at all. They're images, so there's nothing to diff without OCR first. 7. It's a text diff, not a visual diff. A moved logo or a changed font won't show up. For "did they change the notice period?", the current version does the job. For a 200-page reflowed manual, you'd want 1, 2 and 4 at least. Takeaways - A PDF stores positioned glyphs, not lines or paragraphs. Any text feature starts by reconstructing structure from coordinates. - PDF y coordinates grow upwards, so reading order is y descending. - The diff algorithm is the easy part; the quality of the comparison depends almost entirely on how you rebuild the text. If you want to try it, the tool is at Handybin Compare PDFs. It runs in your browser, so you can open DevTools' Network tab and confirm the files aren't uploaded. I'd love to hear how others have handled line reconstruction, especially multi-column layouts.

  3. Redditu/ShakaLaka_Around · r/PipelineOps · 1 point

    I added a dialer to my open-source LinkedIn/email outreach tool (opening-hours queue, scripts, call logging) I’m the author of Linki, an open-source outreach tool I built because I wanted one place to run my own outbound. You import a lead list from Sales Navigator, clean it, and run multichannel campaigns (LinkedIn + email) where an AI agent personalizes each message per lead. It also has a unified inbox and Apollo enrichment. The one channel it was missing was phone, and I was juggling calls in a separate tool. So I built a simple dialer into it. What it does: Queue by opening hours. You set opening hours per contact, and the queue sorts into open now, closing soon and later. Useful when you call businesses with fixed hours (I tested it on law firms). Scripts with variables. You write a script once, and it shows next to the call with the lead’s name and other fields filled in. One-click calling. It uses Phone Link on Windows, so the call goes through your own phone. No cloud telephony, no per-minute cost. I haven’t tested it on Mac, so if you try it there, tell me whether it works. Call outcomes. After each call you log reached, no answer, voicemail or callback. Picking callback asks when, logs it, and can create a to-do. Leads in a cooldown move to a waiting bucket and come back on schedule. Context on the side. Notes, past activity and to-dos for the contact are next to the call screen. There’s also a small cheerleader buddy, because cold calling is a lot of rejection and it helped me more than I expected. It’s simple on purpose. I’ve used it a lot over the last few days and it’s already replaced my spreadsheet. Repo: moaljumaa/linki I’d like to hear what breaks, especially on Mac and with other call setups.

  4. Redditu/nullvector88 · r/developersDesi · 1 point

    I mapped 407 Indian innovations, from 2-million-year-old stone tools to Chandrayaan, as an interactive star atla Hey everyone 👋 I keep running into the same thing online: jokes, stereotypes and plain hatred aimed at India and Indians. After a while I got tired of just scrolling past it and wanted to *show* people something instead. So I built **[India to the World](indiatotheworld.fyi)**, an open atlas of what Indians have contributed to the world, from our ancestors up to today. ### What's in it - **407 innovations** across 20+ disciplines: maths, medicine, metallurgy, textiles, astronomy, games, space, and more - **886 cited sources**, so every entry points back to where the claim comes from - Things like **zero as a number**, **cataract surgery**, **wootz steel**, **chess**, **cotton spinning**, **yoga**, **iron-cased war rockets**, the humble **button**, all the way to **Chandrayaan-3** landing near the Moon's south pole - A few ways to explore it: - 🌌 **Sky**: every innovation as a star you can fly through - 🚉 **Lines**: a transit-style map that shows how one idea led to the next - 🎨 **Rangoli**: the same data drawn as a rangoli - 🎮 **Games**: *Rewind*, *A Day in Your Life* (how much of your normal day traces back to India), and *Then → Now* ### How I built it I built the whole thing with AI coding agents, start to finish. - I ran the **research** in separate agents: digging through public sources, cross-checking claims and collecting citations - Then I used **Claude Code** to design the data model, write each entry, and build the site - All together it took roughly **a billion tokens** of agent work 🤯 - It's a fully static Next.js site. The data lives in plain SQL files, one file per innovation, so anyone can read it or change it ### The honest part **None of this is new.** All of it is already public: books, papers, museums, Wikipedia. I just brought it together in one place and made it easy to explore. Because the research was done with AI agents, **some of it will be wrong**, and I've surely **missed important things**. That's why I'm posting here. I'd love help from people who know this stuff better than I do. ### How you can help It's fully **open source**: [github.com/devsat88/india-to-the-world](devsat88/india-to-the-world) - 🐛 **Spot something wrong?** Open an issue and I'll fix it - ➕ **Know something that's missing?** Send me the details and a source, and I'll add it - 🛠️ **Want to add it yourself?** Each entry is one small SQL file. Run `npm run new-entry -- "Title"` and open a PR ### One small request 🙏 I don't have any following or influencer friends. If you think this is worth something, **please share it** with a friend, a group chat, or anyone who's ever been told India never gave the world anything. Our ancestors, and plenty of people working today, built things the world uses every day without knowing where they came from. Let's make sure people know. 🇮🇳 Thanks for reading! My X post : x.com

  5. Redditu/TheTeaBagParty · r/thelemail · 2 points

    what's going on? So, hey, Vlad here, finally found time and midnight motivation to get this subreddit started. Now as our backlog is taking shape, we can start sharing the roadmap. Initial plan was to showcase it on a fancy page on landing website, but decided will do it as initial post here. What's currently in progress? So, there are some technical debt leftovers from when I was doing the PoC of this project. The work below is mostly around crypto maintenance, shared logic and isolation of responsibilities, and I want to get it out of the way. 1. go-crypto fork We use go-crypto for backend and mobile app, while this one of the best libraries to work with OpenPGP, I had my 2 reasons to fork it: The first one is that I really don't want to carry anything legacy, I wanted to narrow it to what Thelemail is actually using, because I need to know what's going on there. So I dropped legacy support and kept MUST algos in RFC 9580 and RFC 9980. I also left out some modern options that are SHOULD, including Ed448, X448, ML-DSA-87+Ed448 and ML-KEM-1024+X448, I see no reason to support them yet on Thelemail. One more reason is below. The second reason is that I wanted to use Go stdlib cryptography instead of Cloudflare's CIRCL, again nothing wrong with it, only own reasons (please note this is factual list not comparison with CIRCL): - a core set of Go's crypto implementations has been independently audited, and Go provides FIPS 140-3 validated cryptographic module - smaller supply chain, only direct module dependency is golang.org/x/crypto - stdlib implementations are covered by Go's security policy Now that this work is done, I can move on to PQC support in Thelemail. 2. trust repository We are working on trust repository, this basically thing that will cover the gap and connect all the trust chain across all clients and backend to have consistent logic. As mentioned above go-crypto is used only on backend and mobile-app and can drift, so trust will handle this chain, and be shared across backend, tlog, mobile apps and desktop clients (it will replace rPGP). This thing is blocking us from releasing mobile app to open source 3. auth origin and per-product key custody As the title says, we are working on better isolation of responsibilities between authentication, vault unlocking and per-product key handling. The goal is to keep each product's access limited to the keys it needs. Some of this work is already in place, and we are continuing with the remaining separation. What's on the roadmap? This is the initial list, without committed dates yet: - email desk view - improved web client search - family onboarding - guided external email imports - calendar

  6. Hi Bluesky. AI Game Developer makes open source MCP plugins so the AI agent you already use (Claude Code, Cursor, Copilot) can work inside the Unity, Godot and Unreal editors. New: Unity-MCP 1.6.0, and we are now in the official MCP Registry. IvanMurzak/Unity-MCP

  7. Redditu/ShakaLaka_Around · r/appointmentsetter · 1 point

    I added a dialer to my open-source LinkedIn/email outreach tool (opening-hours queue, scripts, call logging) I’m the author of Linki, an open-source outreach tool I built because I wanted one place to run my own outbound. You import a lead list from Sales Navigator, clean it, and run multichannel campaigns (LinkedIn + email) where an AI agent personalizes each message per lead. It also has a unified inbox and Apollo enrichment. The one channel it was missing was phone, and I was juggling calls in a separate tool. So I built a simple dialer into it. What it does: Queue by opening hours. You set opening hours per contact, and the queue sorts into open now, closing soon and later. Useful when you call businesses with fixed hours (I tested it on law firms). Scripts with variables. You write a script once, and it shows next to the call with the lead’s name and other fields filled in. One-click calling. It uses Phone Link on Windows, so the call goes through your own phone. No cloud telephony, no per-minute cost. I haven’t tested it on Mac, so if you try it there, tell me whether it works. Call outcomes. After each call you log reached, no answer, voicemail or callback. Picking callback asks when, logs it, and can create a to-do. Leads in a cooldown move to a waiting bucket and come back on schedule. Context on the side. Notes, past activity and to-dos for the contact are next to the call screen. There’s also a small cheerleader buddy, because cold calling is a lot of rejection and it helped me more than I expected. It’s simple on purpose. I’ve used it a lot over the last few days and it’s already replaced my spreadsheet. Repo: moaljumaa/linki I’d like to hear what breaks, especially on Mac and with other call setups.

  8. Trust, but Verify: How We Audited OpenAI's Lean 4 Math Proofs with a Zero-Dependency Sidecar Recently, OpenAI released a repository of formal proofs (ten-proofs) demonstrating AI's capability to solve complex mathematical problems using Lean 4. When an AI lab drops thousands of lines of formal code claiming "we solved it," how does the rest of the world verify it? Currently, we rely on a handful of expert mathematicians who don't have the time to read 37,000 lines of code. Or, we rely on another LLM to "judge" it—which just hallucinates a thumbs-up. I wanted to see if an automated, physical-witness approach could do better. So, I used my open-source project, harness-audit-sidecar, to audit OpenAI's proofs locally. Here is what happened. The Setup: No Hallucinations Allowed LLM-as-a-Judge fails here. A compiler asks "does this elaborate?", but an auditor must ask "is there a physical witness?". To create a physical witness, I didn't just scan the text. I pulled the 7.2 GB Mathlib cache, compiled 8,687 jobs locally, and ran our LeanProofAuditor. The Results: 11 PASS, 12 FAIL The audit took about 40 minutes. Here are the hard facts: 1. The 11 Main Proof Files achieved a genuine PASS. All theorems elaborated successfully. Zero smuggled custom axioms. They rely only on the three standard Lean axioms (Classical.choice, propext, Quot.sound). OpenAI's core mathematical proofs are solid. 2. 12 Files returned FAIL (42 placeholders found). Wait, did OpenAI cheat? No. These 12 files are located in ComparatorChallenges/. They are templates intentionally left with sorry (Lean's unproved placeholder) for human contestants to fill out. Our auditor simply reported the physical fact: these files are not complete proofs. Why This Matters If an LLM judged this repository, it would read the comments, see the word "solved", and output a confident PASS for the whole folder—completely ignoring the 42 sorry placeholders. Our sidecar enforces a four-valued verdict: PASS, FAIL, INVALID, NOT RUN. - It didn't just guess. - It didn't accept exit code 0 as proof (because a file with sorry can compile cleanly). - It inspected the artifact's dependency graph via #print axioms to expose the truth. The Four-Valued Immune System This audit is just one application of the harness-audit-sidecar. Originally, it was built to catch AI agents lying about writing files or executing shell commands. We introduced: - Conditional Immunity: Tier 1 (cheap stat checks) and Tier 2 (full Git diffs). Two consecutive FAILs trigger an "inflammation storm" that blocks writes. - Membrane Gateway: Agents cannot define their own success criteria. They must register expectations before execution. - Agent Metabolism OS: Regulates LLM API costs and fast/slow thinking beats. A Tool that Audits Itself During development, our own auditor caught itself producing false completions. We log these in ERRATA.md. For example, we initially failed a legitimate opaque definition because we confused it with an axiom. We corrected it and wrote a regression test. An audit tool that only audits others is a decoration. You can read our ERRATA to see how the system caught its own bugs. Resources: - Agent Harness Sidecar (GitHub) - Agent Metabolism OS (GitHub) - Preprint on Zenodo

  9. Redditu/rizal72 · r/opencodeCLI · 4 points

    [Plugins] See your GO and other usage live, auto-update your plugins, get task-done notification on your phone and give OpenCode a cup of coffee to keep it awake :D (check the video to see them in action) I've just updated my opencode-plugins suite with some other useful plugins I've published: as usual they work both in Desktop and CLI: oc-budget: a live indicator in the session header with the Go percentage and a ring. Click to open a popover showing the workspace it is reading, the three windows with their resets, and the balance on each of the four providers it covers: OpenCode Go, the Console credits, DeepSeek, OpenRouter. The CLI has the same thing in the sidebar, in the footer and a /budget command. It also marks the hours when a tariff doubles (peak hours). oc-plugin-updates: a pill above the composer that appears only when a plugin is behind. Which one, which version, one click, no restart. Pinned plugins are left alone on purpose. oc-notify: a push notification to your phone when a turn finishes while you are away from the computer. It goes through ntfy, whose app you install once. It has a settings page in OpenCode settings section. The others previously published: - oc-models-pro: every model with price in and out, context, intelligence, tok/s and the credit a request burns. Sorted by what it costs, one click to switch. The one I use most. - oc-git: branch, added, changed, untracked, ahead and behind, in the sidebar and as a pill. - oc-coffee: a cup of real Italian espresso in the session header and in the CLI footer, lit only while the computer is kept awake, during real tasks, with four levels behind a click (macOS only). - oc-ponytail-widget: the ponytail level in the footer, and a pill to change it. - oc-session-search: keyword search over your past sessions, as a tool. To install: opencode plugin add @rizal72/oc-budget opencode plugin add @rizal72/oc-plugin-updates opencode plugin add @rizal72/oc-notify The other five are in the same repository, with their pages and READMEs: rizal72/opencode-plugins

  10. Redditu/Foreign-Armadillo-28 · r/QGIS · 2 points

    QGIS plugin for saving and restoring map styling across layers Ive been working on "Checkpoint", an open source plugin for keeping a local history of how a map looks. It saves checkpoints of layer styles, labels, filters, layer groups, visibility, and the map view. You can inspect what applying an earlier checkpoint would change, restore it, and undo that application. Checkpoints can be saved manually or automatically I’ve tested it with QGIS 3.44 on macOS, and I’d especially appreciate Windows and Linux testers. If you try it, please tell me your QGIS version and what worked or broke. Contributors are welcome too Git: Mooly612/checkpoint QGIS plugin page: plugins.qgis.org installation available from the apps plugin manager preview.redd.it preview.redd.it And if you find the project useful, a GitHub star would mean a lot. Thanks ;v

  11. Redditu/ShakaLaka_Around · r/ycombinator · 2 points · 1 comment

    I added a dialer to my open-source LinkedIn/email outreach tool (opening-hours queue, scripts, call logging) I’m the author of Linki, an open-source outreach tool I built because I wanted one place to run my own outbound. You import a lead list from Sales Navigator, clean it, and run multichannel campaigns (LinkedIn + email) where an AI agent personalizes each message per lead. It also has a unified inbox and Apollo enrichment. The one channel it was missing was phone, and I was juggling calls in a separate tool. So I built a simple dialer into it. What it does: Queue by opening hours. You set opening hours per contact, and the queue sorts into open now, closing soon and later. Useful when you call businesses with fixed hours (I tested it on law firms). Scripts with variables. You write a script once, and it shows next to the call with the lead’s name and other fields filled in. One-click calling. It uses Phone Link on Windows, so the call goes through your own phone. No cloud telephony, no per-minute cost. I haven’t tested it on Mac, so if you try it there, tell me whether it works. Call outcomes. After each call you log reached, no answer, voicemail or callback. Picking callback asks when, logs it, and can create a to-do. Leads in a cooldown move to a waiting bucket and come back on schedule. Context on the side. Notes, past activity and to-dos for the contact are next to the call screen. There’s also a small cheerleader buddy, because cold calling is a lot of rejection and it helped me more than I expected. It’s simple on purpose. I’ve used it a lot over the last few days and it’s already replaced my spreadsheet. Repo: moaljumaa/linki I’d like to hear what breaks, especially on Mac and with other call setups.

  12. Redditu/debba_ · r/tabularis · 1 point

    Tabularis v0.31.0: transposed results, saved-query history and more connection imports We maintain Tabularis, an open-source SQL client for Linux, macOS and Windows that also runs in a browser through tabularis web. v0.31.0 focuses on work inside the editor: - Transpose a wide result so fields become rows and records become columns. Hide columns and find text in loaded cells without running another query. Find skips hidden and unrevealed masked values. - Keep up to 50 previous SQL versions of each saved query, compare them and restore. Export a saved-query folder or filtered execution history as SQL. - Pin query tabs and explorer tables/views. Copy keyed rows as SQL UPDATE. Double-click a column border to fit its loaded values. - Import connections from HeidiSQL settings exports, Navicat .ncx files and MySQL Workbench. Passwords are not imported from these three sources. - Open EXPLAIN in a separate window, see loop counts and reorder table columns. - Choose NULL display independently from CSV/Markdown copy output. Vietnamese and Traditional Chinese bring the UI to 13 languages. Around the ecosystem, CockroachDB has its first downloadable driver alpha, built by 1-DARK. Connection, browsing, queries, transactions and row editing work, while EXPLAIN, DDL helpers and ER diagrams remain unimplemented. PostgreSQL rc.13 fixes aborted-transaction error cascades, libSQL 1.0.3 fixes ER diagrams, and Tabularium 0.25.2 fixes relative README links. For self-hosting, this release resumes a connection link after password login and updates the login page to follow system light/dark preferences. Docker, Helm and remote-access guides are in the wiki. Thanks to everyone who contributed code, translations, plugins and bug reports. 📝 tabularis.dev ⭐ TabularisDB/tabularis Demo videos - Grid: transpose, hide columns and Find - Saved-query history and restore - EXPLAIN: loop counts, column order and separate window Screenshots Processing img 0fatb33beezh1... Processing img y928ihsaeezh1... Processing img k1nj4csaeezh1...

  13. V2EX@xinnix · 奇思妙想 · 1 comment

    做了一个驻守菜单栏的 GitHub CI 监控:红了会叫你,点开就能复制错误日志 每天的工作流大概是:push 完代码 → 切走干别的 → 过五分钟想起来的 时候切回浏览器刷一下 Actions 页,确认 CI 绿了没有。 一天重复十几次,烦。 试过 Gitify(Electron,只做通知,失败了你还是得自己开网页找哪红 了)和 ActionBar(付费,仅 mac),都不太是想要的样子,就自己写了 一个—— Glint,今天发 v1.1.0-beta.1,三端全齐,MIT 开源: xinnix/glint ← 求 Star xinnix.github.io ← 官网(纯静态,无构建) [GIF:托盘变红 → 点开面板 → 失败仓库置顶 → 点「复制错误」] 它解决的就是上面那个循环: 1. 一眼即知 —— 菜单栏一颗圆点聚合所有仓库的最差状态,绿/红 (带失败数)/橙(运行中)/灰(无 CI),鼠标悬停看明细,点托盘 弹面板 2. 失败不开网页 —— 失败仓库置顶,直接下钻到具体的 job ▸ step; 「复制错误」一键拉取日志、截取 ##[error] 前后各十几行上下文进 剪贴板,连 repo@sha 一起带上,直接丢给 AI 或同事 3. 状态变化才通知 —— 轮询 + 内存 diff,失败/转绿才弹,macOS 上 点击通知直达面板 4. 省限额 —— 登录后 5000 req/h,且全部请求走 ETag 条件查询, 没变化(304)不计数;无 token 公共仓库也能用,自动降速到 4 分钟一轮 5. 零配置登录 —— RFC 8628 Device Flow(就是 gh auth login --web 同款),token 只存系统钥匙串,不落盘不进配置文件 6. 开机自启 / 检查更新横幅 / 中英双语,全部内置 下载(v1.1.0-beta.1,全平台安装包): macOS: universal DMG(7MB,Apple Silicon + Intel) Linux: deb / AppImage Windows: NSIS 安装器 / MSI,均 < 5MB github.com/xinnix/glint/releases/latest 技术栈: Tauri 2 + Rust(ureq 同步 HTTP + std::thread,没引 tokio),前端纯 HTML/JS/CSS 无任何构建步骤,托盘图标是 Rust 按几何参数程序化生成的 RGBA,没有一张静态图标资源。想二开的话 clone 下来 npm i 只装 @tauri-apps/cli 一个依赖。 如实交代目前的状态(免得大家踩坑): - 所有构建未签名: macOS 首启右键 → 打开;Windows 会过 SmartScreen (Developer ID / Authenticode 等有账号后再补) - 点击通知唤起面板目前仅 macOS,Win/Linux 上点击只是激活应用 - Linux Wayland 下面板没法贴着托盘定位(系统限制),X11 完整 - Windows/Linux 端刚打包出来,我自己没有真机长期用过,求有 条件的佬帮忙踩坑: github.com/xinnix/glint/issues demo 仓库建了一个 xinnix/glint-demo (push 一 个 FAIL 标记文件就红,删掉就绿),不想拿自己仓库做实验的可以用 它看通知效果。

  14. Redditu/ShakaLaka_Around · r/Entrepreneurs · 2 points · 2 comments

    I added a dialer to my open-source LinkedIn/email outreach tool (opening-hours queue, scripts, call logging) I’m the author of Linki, an open-source outreach tool I built because I wanted one place to run my own outbound. You import a lead list from Sales Navigator, clean it, and run multichannel campaigns (LinkedIn + email) where an AI agent personalizes each message per lead. It also has a unified inbox and Apollo enrichment. The one channel it was missing was phone, and I was juggling calls in a separate tool. So I built a simple dialer into it. What it does: Queue by opening hours. You set opening hours per contact, and the queue sorts into open now, closing soon and later. Useful when you call businesses with fixed hours (I tested it on law firms). Scripts with variables. You write a script once, and it shows next to the call with the lead’s name and other fields filled in. One-click calling. It uses Phone Link on Windows, so the call goes through your own phone. No cloud telephony, no per-minute cost. I haven’t tested it on Mac, so if you try it there, tell me whether it works. Call outcomes. After each call you log reached, no answer, voicemail or callback. Picking callback asks when, logs it, and can create a to-do. Leads in a cooldown move to a waiting bucket and come back on schedule. Context on the side. Notes, past activity and to-dos for the contact are next to the call screen. There’s also a small cheerleader buddy, because cold calling is a lot of rejection and it helped me more than I expected. It’s simple on purpose. I’ve used it a lot over the last few days and it’s already replaced my spreadsheet. Repo: moaljumaa/linki I’d like to hear what breaks, especially on Mac and with other call setups.

  15. Vue と AWS HTTP API で作る日次チェックカレンダー カレンダー形式で日次の作業をチェックする Web サービス「毎日チェック」(リポジトリ名 check-today2)を作成しました。 !screenshot-check-today2.png 背景 私は10年以上「今日ゲームにログインしたか」を自作の Web チェックカレンダーで記録しています。毎朝のルーティーンで、数独のようなパズルゲームをいくつか解く習慣なのですが、これをやり忘れるとモヤモヤするので、備忘のためにWebアプリケーションを作りました。 当初は JSP+JavaScript で実装し、テキストファイルに ON の履歴を積み上げていました。常時起動のEC2サーバ上の tomcat で動き、認証も弱く、画面も「1項目のチェック時刻を記録するだけ」に留まっていました。 今回は、この「負の遺産」を一新し、複数の項目を記録したり、カレンダー表示して振り返ったりできるようにするための開発です。 フロントは Vue 3 と TypeScript、配信は非公開 S3 と CloudFront、API は API Gateway HTTP API と Lambda、永続化は DynamoDB、インフラ定義は AWS CDK を使います。IDP には Google 認証を採用します。構成の骨格は共有ホワイトボード hakuban4 を参考にしつつ、共有は行わず、HTTP のリクエスト/レスポンスで足りる個人向け記録に振り切っています。 提供画面は次の 4 つです。 - カレンダー(当月表示、月移動、「今日」、今日の強調、当月集計) - チェック項目編集(表示名・ON/OFF 文言・記号・色・無効) - チェック状態編集(任意日の ON/OFF と変更日時) - チェック状態集計(最初に記録した日から今日までの日数・ON 回数・比率・30 日移動平均) 静的サイトとサーバレスの組み合わせで、常時起動のアプリサーバを持たない構成に変更します。 チェック項目と日次状態 ドメインの中心は「チェック項目」と「ある日の状態」です。項目はおおむね次の形です。 type CheckItem = { itemId: string; displayName: string; onLabel: string; offLabel: string; symbol: string; color: string; // #RRGGBB disabled: boolean; createdAt: string; updatedAt: string; }; 状態は次のとおりです。未操作の日は DynamoDB にレコードを作らず、画面上は OFF として扱います。ON または OFF を保存した日だけレコードを持ち、最後に保存した日時を changedAt(UTC ISO8601)として残します。 type CheckState = { itemId: string; date: string; // Asia/Tokyo の YYYY-MM-DD status: 'ON' | 'OFF'; changedAt: string; }; disabled が true の項目は、状態編集画面の一覧から外します。過去の記録やカレンダー・集計からは見えるままにして、習慣の棚卸しと日々の入力を分けています。1 ユーザあたりの項目数上限は 50 です。 アーキテクチャ全体像 論理構成は次のとおりです。 flowchart TB subgraph client [クライアント] Browser[ブラウザ_SPA_PWA] GIS[Google_Identity_Services] end subgraph edge [配信と入口] CF[CloudFront] S3[(S3_静的配信)] HttpApi[API_Gateway_HTTP_API] AuthZ[Authorizer_Lambda] end subgraph compute [処理] Items[items] States[states] Summaries[summaries] end subgraph data [データ] ItemsTable[(CheckItems_DynamoDB)] StatesTable[(CheckStates_DynamoDB)] end Browser --> GIS Browser --> CF CF --> S3 Browser -->|"Bearer_ID_token"| HttpApi CF -->|"/api/*"| HttpApi HttpApi --> AuthZ HttpApi --> Items HttpApi --> States HttpApi --> Summaries Items --> ItemsTable Items --> StatesTable States --> ItemsTable States --> StatesTable Summaries --> ItemsTable Summaries --> StatesTable ブラウザは CloudFront 経由で静的アセットを取得し、本番では同一オリジンの /api を呼び出します。Lambda オーソライザーが Google ID トークンを検証し、許可メール一覧に含まれる場合のみ通します。各ハンドラはオーソライザーが渡した email だけをユーザ識別子に使い、リクエスト本文やパスの email は採用しません。 AWS リソースは CDK で定義しています。Lambda は Node.js 20、DynamoDB はオンデマンド課金、フロントは非公開 S3 と Origin Access Control 付き CloudFront です。SPA 向けに 403/404 を index.html へフォールバックしています。ローカル開発では Vite のプロキシ、または VITE_API_BASE で HTTP API を直接指定します。設定の正本はリポジトリルートの .env で、Vite と CDK が dotenv で読みます。 データモデルと HTTP API DynamoDB | テーブル | キー | 要点 | | ----------- | ----------------------------------------------------- | -------------------------------------------------------------------------------------- | | CheckItems | PK userEmail、SK itemId | 項目属性。disabled は BOOL(省略時は false 扱い) | | CheckStates | PK userEmail、SK stateKey({itemId}#{yyyy-mm-dd}) | itemId/date/status/changedAt。月次取得用に GSI date-index(PK userEmail、SK date) | 同一ユーザ・同一項目・同一日の更新は後勝ちとし、条件付き書き込みは必須にしていません。少人数・個人利用向けの選択です。 API の概要 セッショントークンは発行しません。Authorization: Bearer <Google ID token> を付けて次を呼びます。 | メソッドとパス | 役割 | | --------------------------------- | ----------------- | | GET /api/items | 自ユーザの項目一覧 | | POST /api/items | 項目作成(上限 50 で 409) | | PUT /api/items/{itemId} | 項目更新 | | DELETE /api/items/{itemId} | 項目と、その項目の状態を削除 | | GET /api/states?from=&to= | 期間内の状態一覧 | | PUT /api/states/{itemId}/{date} | 指定日の状態 upsert | | GET /api/summaries | 全項目の通算集計 | 日付はすべて Asia/Tokyo の暦日(YYYY-MM-DD)です。画面の最新化は、その画面を開いたとき、または明示的な再読込に任せます。 認証とトークン更新 IDP には Google Identity Services を使い、Gmail アカウントの ID トークンを検証します。Issuer と Audience(クライアント ID)に加え、環境変数 ALLOWED_EMAILS の許可メール一覧で認可しています。ロール制御はなく、一覧に入っていれば自アカウントのデータに対する操作は制限しません。 hakuban4 では WebSocket 接続の手間を減らすため自前の無期限セッショントークンを発行しましたが、本サービスは HTTP のみで、毎回 ID トークンを付けます。トークンの有効期限は短いため、次の方針にしています。 - 送信前に JWT の exp を見て、切れそうなら GIS で裏から再取得する - API が 401/403、またはログイン画面の HTML を返したら、同じく再取得して 1 回だけ再試行する - 再取得できないときはセッションを破棄し、再ログインを促す - HTML 応答を JSON.parse しない(パース例外を画面に出さない) CloudFront やプロキシの設定ミスで /api が SPA の HTML を返すケースでも、同じ経路で再ログインに誘導できます。 集計とカレンダー UI 通算集計(集計画面) 集計範囲は、その項目について状態レコードが存在する最も古い日(ON/OFF を問わない)から、サーバ処理時点の Asia/Tokyo の今日までです。範囲内でレコードが無い日は OFF として数えます。今日より後の日付はカレンダーや状態編集の対象にはなりますが、集計には含めません。 | 指標 | 内容 | | -------- | -------------------------------- | | 日数 | today - firstDate + 1 | | ON 回数 | 範囲内で status が ON の日数 | | ON 比率 | ON 回数/日数(百分率、小数点以下 1 桁) | | 30 日移動平均 | 日数が 30 以上のときだけ。直近 30 日の ON 日数/30 | 算出は summaries Lambda 内の純関数とし、Vitest の対象にしています。 当月集計(カレンダー下部) カレンダーの下には、表示中の月だけの ON 回数と ON 比率を出します。分母はその月の日数(28〜31)です。通算集計にある日数や移動平均はここでは出しません。無効項目も含めて表示します。 小さい画面と PWA ビューポート幅が 640px 未満では、カレンダー上は ON の項目だけを記号と文字色で出し、項目名や ON/OFF 文言は出しません。vite-plugin-pwa でマニフェストとプリキャッシュを入れ、ホーム画面追加に耐える形にしています。表示名は VITE_APP_TITLE(既定は「毎日チェック」)です。 実装で工夫した点 ユーザ境界は Authorizer の email だけ ハンドラは requestContext.authorizer.lambda.email だけを信頼します。クライアントが本文に別の email を書いても無視します。項目削除時は当該 itemId の状態もまとめて消します。 集計の純関数 通算集計と、フロント側の当月集計はどちらも日付境界を Asia/Tokyo に固定した純関数に寄せ、境界ケース(未開始、未来日、2 月など)を単体テストで固定しています。 認証切れと HTML 応答 期限切れトークンや誤ったルーティングで HTML が返ると、素朴な res.json() は例外になります。本文を文字列で読み、認証失敗らしい応答ならチケット再取得、不能なら再ログイン、という分岐にまとめました。 旧 .dat とバックアップ/復元 旧システムの日時行を、バックアップ JSON(format: calendar-check-backup)へ一回限り変換し、DynamoDB へ復元できるようにしました。運用の正本は DynamoDB で、backend/ の CLI から書き出し・復元します。同一キーは上書き(後勝ち)です。任意で --email= により 1 ユーザ分だけを対象にできます。 ルート .env の共有 フロント専用の .env を廃止し、GOOGLE_CLIENT_ID/ALLOWED_EMAILS/VITE_APP_TITLE などをルートに集約しました。ビルド時にフロントへ埋め込む値と、CDK/Authorizer が読む値の食い違いを減らすためです。 開発の流れ 工程は要件整理、構成設計、実装と単体テスト、結合確認の順で進めました。パッケージはフロントエンド、バックエンド、インフラに分けています。 | 観点 | 内容 | | ------ | ---------------------------------------------------------------------------------------- | | フロント | Vue 3、TypeScript、Vite、vue-router、Google Identity Services、PWA | | バックエンド | TypeScript Lambda、jose、AWS SDK(DynamoDB)。backup/restore CLI | | インフラ | AWS CDK(HTTP API、DynamoDB、S3、CloudFront、Lambda) | | 検証 | Vitest(フロントは jsdom、バックエンドは Node)。Authorizer、日付境界、状態 upsert、集計、バックアップ形式、認証切れ時の再取得などを単体テスト | インフラの自動テストやブラウザ E2E、実 AWS を叩く結合テストは本稿時点では自動実行の範囲外とし、デプロイ後の手動確認で補っています。 成果物 - septigram/check-today2 まとめ - 個人向けの日次チェックカレンダーを、Vue と API Gateway HTTP API・Lambda・DynamoDB で実装しました。 - WebSocket による画面間共有は行わず、同一オリジンの REST と再表示による最新化に割り切っています。 - Google ID トークンと許可メール一覧で入り口を絞り、セッショントークンは持たず、期限切れ時は GIS での再取得と再ログイン誘導で耐えます。 - 通算集計(日数・ON 回数・比率・30 日移動平均)と、カレンダー下部の当月集計(ON 回数・比率)を分け、無効項目は入力一覧だけから外しています。 - 旧 .dat の移行、バックアップ/復元、ルート .env の共有など、長く使うための周辺も同じリポジトリに載せています。

  16. My existing Windows tools and SDK examples are listed here: physical/virtual input, device testing, networking, media and diagnostics. Check each README for setup, licensing and tested scope; some are engineering previews. titanfyre/Titan-Input-Tools

  17. Redditu/ShakaLaka_Around · r/OpenSourceeAI · 1 point · 1 comment

    I added a dialer to my open-source LinkedIn/email outreach tool (opening-hours queue, scripts, call logging) I’m the author of Linki, an open-source outreach tool I built because I wanted one place to run my own outbound. You import a lead list from Sales Navigator, clean it, and run multichannel campaigns (LinkedIn + email) where an AI agent personalizes each message per lead. It also has a unified inbox and Apollo enrichment. The one channel it was missing was phone, and I was juggling calls in a separate tool. So I built a simple dialer into it. What it does: Queue by opening hours. You set opening hours per contact, and the queue sorts into open now, closing soon and later. Useful when you call businesses with fixed hours (I tested it on law firms). Scripts with variables. You write a script once, and it shows next to the call with the lead’s name and other fields filled in. One-click calling. It uses Phone Link on Windows, so the call goes through your own phone. No cloud telephony, no per-minute cost. I haven’t tested it on Mac, so if you try it there, tell me whether it works. Call outcomes. After each call you log reached, no answer, voicemail or callback. Picking callback asks when, logs it, and can create a to-do. Leads in a cooldown move to a waiting bucket and come back on schedule. Context on the side. Notes, past activity and to-dos for the contact are next to the call screen. There’s also a small cheerleader buddy, because cold calling is a lot of rejection and it helped me more than I expected. It’s simple on purpose. I’ve used it a lot over the last few days and it’s already replaced my spreadsheet. Repo: moaljumaa/linki I’d like to hear what breaks, especially on Mac and with other call setups.

  18. Redditu/debba_ · r/tabularis · 1 point

    Start here: what is Tabularis? Downloads, supported databases, docs and community help Welcome to r/tabularis, a place to discuss Tabularis, share workflows, ask questions and suggest improvements. Tabularis is an open-source database client for Linux, macOS and Windows. You can browse schemas, run SQL, edit table data, save queries and inspect execution plans. It also runs in a browser through Tabularis Web. Which databases can I use? PostgreSQL, MySQL/MariaDB and SQLite are available through the app's driver system. Additional databases use plugins installed from the connection catalogue or Plugin Center. Capabilities vary by driver, so check the plugin's README for features and platform support. Where should I start? 1. Download Tabularis. 2. Follow the first-connection guide. 3. Browse the documentation or source code. How do I ask for help here? Use a descriptive title and include your Tabularis version, operating system, database/driver version, what you expected and the exact error. A small reproducible example is more useful than a screenshot alone. Remove passwords, access tokens, customer records and private connection strings before posting. Questions and workflow discussions belong here. Reproducible bugs can also be filed in the GitHub issue tracker, where they can be tracked alongside fixes. If you build a plugin, theme or integration, tell us what it does, which versions it supports and your role in the project.

  19. Redditu/_spaceboy1999 · r/Vivo · 4 points · 5 comments

    OriGoogle: Google features for OriginOS 7 China (X200 Ultra) OriGoogle is an open-source libxposed module that brings the global Google features to OriginOS 7 China. You can turn each one on or off in its app: - Global Google services. Play services stops treating the phone as a China device, so Timeline, Quick Share, Find Hub and other global features turn on. - Circle to Search. Long-press the gesture handle to search anything on screen with Google Lens. - Corner swipe for assistant. Adds a Google Assistant option to the bottom-left and bottom-right corner choices in Settings › System navigation. Swiping up from that corner opens Gemini. Your other corner actions are kept. - Hold power for assistant. Holding the power button opens Gemini instead of Jovi. - Quick Share in the share sheet. Quick Share is pinned as the first target in vivo’s share panel. - Control center tiles. Google Wallet, Google Lens and Gemini tiles that you can add when editing the control center. - Google Discover on the left home screen (experimental, off by default). Replaces vivo’s left screen with the Google feed. You also need to turn on Smart Launcher in your launcher settings for the feed to appear. Requirements - vivo X200 Ultra, China firmware, on OriginOS 7 (Android 17). - Other vivo phones on OriginOS 7 China could work too, since the hooks target OriginOS rather than this phone’s hardware. They’re untested, though. - Root (I use KernelSU) and Zygisk (NeoZygisk). - Vector SR as the Xposed framework. It’s what I developed and tested on, and I recommend it. Other libxposed API 102 frameworks may work, but they’re untested. - Google Play services, the Google app and Gemini. - In Vector-SR, enable OriGoogle and check that its scope includes System Framework, the vivo launcher(com.bbk.launcher2) and Interaction Cube (com.vivo.upslid). They’re preselected on a fresh install. Then soft reboot , not a full reboot, so you keep root. Later changes can be applied with the app’s Apply button, which does the soft reboot for you. Known limit - Only tested on my phone, so use at your own risk. Link - OriGoogle: kailashrs/OriGoogle (APK under Releases) GPL-3.0, with its structure based on Coogle for ColorOS. Bug reports and logs are welcome on GitHub. Each hooked process writes an origoogle.log, and the README says where to find them.

  20. Redditu/New_Description_5930 · r/LocalLLM · 1 point · 2 comments

    LLM Uncensoring Tool and OSS LLM Uncensoring Tool "Heretic" Evolves to 2.0. The popular OSS that garnered 37,700 GitHub stars has fundamentally changed its approach to removing refusal responses. ◼︎ Conventional Problems General Abliteration treats refusal responses as specific vector directions and removes their components. However, in models where refusal responses are not expressed in a single direction, it couldn't remove them sufficiently or even impaired the model's capabilities. ◼︎ Heretic 2.0's New Method "ARA" Instead of removing one direction like before, it directly optimizes the weight matrices. There are two goals. ・Bring the internal representations for refusal-targeted inputs closer to those for normal inputs ・Change the internal representations for normal inputs as little as possible This is achieved using an optimization technique called L-BFGS. A key feature is that it has no limit on the number of directions to modify. ◼︎ Handles More Than Just Refusal Removal Furthermore, version 2.0 allows evaluation metrics to be added as plugins. In addition to refusal responses, ・AI-specific unnatural canned phrases ・Excessive pandering to users ・Emotional response tendencies can also be targeted for correction. ◼︎ What's Interesting About It? Up until now, it was crucial to figure out where to extract refusal directions from, which layers to target, and how much to remove. ARA takes it a step further by letting you specify the behaviors you want to keep and those you want to eliminate, then optimizing the weight matrices accordingly. It has evolved from a mere uncensoring tool into one that edits the very behavior of LLMs. Comparing it to the refusal removal techniques I'm researching sounds intriguing too GitHub

  21. Redditu/SCARaw · r/arcanum · 5 points · 10 comments

    Trying out "Arcanum Renaissance 1.6.1" - the vibe coded mod Greetings sometime ago user u/Adraenor announced his Project for Modernized Arcanum thing i was skeptical and rather jokingly said that "i can't wait to ignore it and play original game with mods, after work." yesterday i decided to give it a go, mostly our of curiosity, but also to not leave potential ui mod unchecked Pretty good things: 1. Menus are big and possible to navigate 2. Mod introduce few new functions: leaving pins with note on the map, adding journal entry to favorites 3. Character menu was edited for the better 4. Mod introduce variety of options in settings that change dynamically without need to restart 5. Mod works with existing mods for the game and even existing saves for the game 6. Mod let you move with EVERY SINGLE COMPANION - this is cool, but takes eternity 7. mod increase your AP at least 2x 8. UAP Exe can load saves made by the mod without problems Vibe-coded hell 1. Mod ask you for a lot of time just to bloat installation with 8GB AI-upscalled textures without ability to just disable this feature! or at least waste only 1GB for ai upscale 2. Spell menu is inaccessible from UI, you need to call for big version of it and work from there 3. Item Spells DONT EXIST, Shaman staff? TOO BAD, forget about it, your spells show only spells your character know, not inventory spells 4. Spell menu might have 16 magic schools but no "inventory spells tab" 5. IF you have 7 or more followers and you press Arrow to see more, you can't ever go back 6. THERE IS NO REAL TIME COMBAT ANYMORE 7. Original shortcuts ware replaced by some basic bitch functions i never used 8. My HP and FT are unreadable on UI during combat or offcombat, i can see the vials, but numbers don't fit on 100% font size 9. There is no ONLY MOVE FOR YOURSELF IN COMBAT option that could save you a lot of time 10. Fonts can change size from menu to menu depends on the mood of GrokGBT that day 11. there is a lot of clunkyness with the map features and while i normally play fast, with mod i play like a turtle (this is not just unfamiliarity or skill issue, you would have to play it to get it) 12. Map Notes are not big enough to display general title of what i typed, it cuts abruptly and maps could use Displayed Title/Description for the note Conclusions: you can give it a try, its available here: cdomergue/arcanum-modern personally i rather go back to original exe i hope it doesn't look like i just criticize the mod, i gave it honest try i swear Honestly i believe mod can get better with time, but i mixed about it

  22. Redditu/adit428 · r/RISCV · 9 points · 1 comment

    Student RV32I 5-stage pipeline with I/D caches and AXI-style memory: I had to shrink my victim cache (4→2) and write buffer (16→4) to hit 100 MHz. Feedback and opinions welcome I’m a student. Partway through Harris & Harris I decided the only way to really get it was to build the CPU, so I wrote a single-cycle RV32I core in SystemVerilog. Once it ran programs, I wanted to see what changes when instructions overlap, and that turned into a 5-stage pipeline (fetch, decode, execute, memory, writeback). The whole thing took about two months. Splitting the stages was the easy part. The hard part was everything that goes wrong once instructions overlap. If an add needs a value the previous instruction hasn’t written back yet, you have to grab it from further down the pipe. If a jump is taken, the instructions already fetched behind it have to be thrown away. If memory is slow, everything in front has to wait. Most of my time went into those three things, and most of my bugs were an instruction being dropped or held when it shouldn’t have been, or the opposite. After that I added an instruction cache and a data cache, with a small victim cache and a write buffer on the data side. Memory is connected through an AXI-style interface: cache lines come in as bursts, and writes use separate address, data, and response channels. My first version had a 4-entry victim cache and a 16-entry write buffer, but it wouldn’t meet timing at 100 MHz, so I cut them to 2 and 4. It was the first time I actually felt a feature costing me clock speed, instead of just reading about the tradeoff. For testing, I ran the official rv32ui ISA tests plus some small programs of my own, checking registers and memory against the values I expected. When something failed, I mostly stared at waveforms. One I like: the data cache misses on a load, the front of the pipeline stops for about 8 cycles while the cache line is fetched, and then the loaded value shows up at writeback. It’s a lot more convincing to watch it happen than to read about it. I put it through Vivado for an Artix-7 (XC7A100T): 3,706 LUTs, 7,350 flip-flops, +0.191 ns of slack at 100 MHz, and an estimated 0.118 W. What it doesn’t do: it’s RV32I only, so no multiply or divide, no CSRs, no interrupts. And on the board I’m only feeding NOPs into the instruction side right now, so all my real program testing was in simulation. On hardware I only confirmed that the PC counts and the LEDs react. Connecting real instruction memory is next. I know passing rv32ui says little about how the caches and the bus behave together, so I’m sure there are cases I haven’t hit. If you can think of a hazard or cache situation that would break this, I’d really like to hear it. I built this to learn, and I’m hoping to turn it into an internship in digital design or verification. If you know of a place that takes students for that kind of work, or have advice on what to build or learn next, I’d appreciate it. GitHub: aditya42819/RV32I_CPU LinkedIn: lnkd.in

  23. Redditu/unmade7 · r/gnome · 73 points · 28 comments

    Global Menu for GNOME is finally here. Last month I made a post asking help mapping apps. Thanks to everyone who sent shortcuts and JustPerfection for reviewing it. It's now available for everyone to download. you can install it here how it works: 1. The app's own menu. If the app exports its menu over d-bus (GTK apps, and KDE/Qt apps with dbusmenu), the bar shows that exact menu 2. A shortcut menu. If the app exports nothing, the extension loads a menu built from that app's documented keyboard shortcuts. Clicking an item sends the key combo to the window. This is how Electron apps (VS Code, Discord, Obsidian) get menus on Wayland. 290 apps are covered. 3. A generic menu. If the app is in neither group, you still get a basic File / Edit / Go / Window / System menu with common actions: copy, paste, undo, close window, snap left or right, screenshots, switch workspace, lock screen. The app-name menu adds New Window and Quit. Works on GNOME 48 to 51 If your app is missing, create an issue at github.com/Unmade760/orbit-global-menu/issues with the keyboard mappings. and if you want to support it, a star on GitHub or a rating on EGO helps! :)

  24. Location: Bengaluru, India Remote: Yes Willing to relocate: No Technologies: Python, TypeScript, JavaScript, React, Next.js, Node.js, FastAPI, Django, PostgreSQL, MongoDB, AWS, Docker, LLM APIs (Claude, OpenAI), RAG, OpenCV, YOLO Résumé/CV: alanchriss.me Email: alanchrisdisilva@gmail.com Final-year CS student and Forward Deployed Engineer at Arghyam Portfolio: alanchriss.me | GitHub: github.com/alan61503

  25. Type-safe AI SDK for any provider A TypeScript SDK that lets you stream chat, tool calls and multimodal prompts with full type safety. Import only the adapters you need—swap OpenAI, Anthropic or Gemini in a single line. 🍒 Built by the TanStack team TanStack/ai #opensource #typescript

  26. Redditu/gptrv · r/node · 2 points

    Screenplay: screen recordings with Screen Studio-style editing, in Node (CDP screencast + @napi-rs/canvas + ffmpeg) I open-sourced a Node CLI + MCP server that films websites and desktop apps and edits the result like Screen Studio. A coding agent (Claude Code, Codex, Cursor…) writes a short JSON scenario, and Screenplay plays it, films it and edits it. Some of the Node side, in case it's useful to someone: - Capture: Playwright drives headless Chromium, and frames come from the Chrome DevTools Protocol (Page.startScreencast) rather than Playwright's video recorder, so each frame has a timestamp I can line up with the actions. - Editing: every output frame is composed on @napi-rs/canvas: gradient background, rounded window with shadow, a cursor drawn from the recorded positions (smoothed), click ripples, zoom that follows the action, captions. - Encoding: raw RGBA frames are piped to ffmpeg-static through stdin (-f rawvideo … pipe:0). No system ffmpeg, no native build step on install. - Desktop apps: the same scenario format is played through the OS accessibility APIs (agent-desktop), and the window is filmed with ffmpeg. - Interface: a commander CLI (check, record, render) and an MCP server on stdio, so any agent can call it. Try it: npx agent-screenplay init Repo (MIT, TypeScript): gmpetrov/agent-screenplay Happy to go deeper on any part.

  27. Redditu/ShakaLaka_Around · r/EmailOutreach · 1 point

    I added a dialer to my open-source LinkedIn/email outreach tool (opening-hours queue, scripts, call logging) I’m the author of Linki, an open-source outreach tool I built because I wanted one place to run my own outbound. You import a lead list from Sales Navigator, clean it, and run multichannel campaigns (LinkedIn + email) where an AI agent personalizes each message per lead. It also has a unified inbox and Apollo enrichment. The one channel it was missing was phone, and I was juggling calls in a separate tool. So I built a simple dialer into it. What it does: Queue by opening hours. You set opening hours per contact, and the queue sorts into open now, closing soon and later. Useful when you call businesses with fixed hours (I tested it on law firms). Scripts with variables. You write a script once, and it shows next to the call with the lead’s name and other fields filled in. One-click calling. It uses Phone Link on Windows, so the call goes through your own phone. No cloud telephony, no per-minute cost. I haven’t tested it on Mac, so if you try it there, tell me whether it works. Call outcomes. After each call you log reached, no answer, voicemail or callback. Picking callback asks when, logs it, and can create a to-do. Leads in a cooldown move to a waiting bucket and come back on schedule. Context on the side. Notes, past activity and to-dos for the contact are next to the call screen. There’s also a small cheerleader buddy, because cold calling is a lot of rejection and it helped me more than I expected. It’s simple on purpose. I’ve used it a lot over the last few days and it’s already replaced my spreadsheet. Repo: moaljumaa/linki I’d like to hear what breaks, especially on Mac and with other call setups.

  28. 3) Sadly, some other stuff that I really hoped for didn’t ship. Eg when Lighthouse computes LCP, it still treats almost all requests as LCP-blocking, even stuff like preloads or fetch. I had a proposal to make this more accurate (see pt. 2 here: lighthouse#16539) but it didn’t make it.

  29. Redditu/ShakaLaka_Around · r/Coldemailing · 1 point · 1 comment

    I added a dialer to my open-source LinkedIn/email outreach tool (opening-hours queue, scripts, call logging) I’m the author of Linki, an open-source outreach tool I built because I wanted one place to run my own outbound. You import a lead list from Sales Navigator, clean it, and run multichannel campaigns (LinkedIn + email) where an AI agent personalizes each message per lead. It also has a unified inbox and Apollo enrichment. The one channel it was missing was phone, and I was juggling calls in a separate tool. So I built a simple dialer into it. What it does: Queue by opening hours. You set opening hours per contact, and the queue sorts into open now, closing soon and later. Useful when you call businesses with fixed hours (I tested it on law firms). Scripts with variables. You write a script once, and it shows next to the call with the lead’s name and other fields filled in. One-click calling. It uses Phone Link on Windows, so the call goes through your own phone. No cloud telephony, no per-minute cost. I haven’t tested it on Mac, so if you try it there, tell me whether it works. Call outcomes. After each call you log reached, no answer, voicemail or callback. Picking callback asks when, logs it, and can create a to-do. Leads in a cooldown move to a waiting bucket and come back on schedule. Context on the side. Notes, past activity and to-dos for the contact are next to the call screen. There’s also a small cheerleader buddy, because cold calling is a lot of rejection and it helped me more than I expected. It’s simple on purpose. I’ve used it a lot over the last few days and it’s already replaced my spreadsheet. Repo: moaljumaa/linki I’d like to hear what breaks, especially on Mac and with other call setups.

  30. Redditu/rodrigotadeu · r/3DO · 2 points

    3DO ODE Menu - Brazilian Fan and Collector - 1 Month development Reddit — 3DO ODE (EN / PT / ES) Link: cyberrep/3doode (downloads → Releases) 🇬🇧 English Title: A modern, 3-language menu + custom firmware for the 3DO SataTo3DO ODE (free & open) Hi all! I've been building a modern menu and toolkit for the 3DO SataTo3DO ODE (the RP2040 board), and just pushed a new release. It's free and open. What it does: - Clean menu (boot.iso) in English, Portuguese & Spanish - Works on both firmwares: the stock/Fixel one and my custom "TADEU" fw (much faster loading) - 4 ways to browse: List, Covers grid, Carousel and Carousel FX - Box art, screenshots and video previews - Game details screen with cover + screenshot + video side by side - Favorites, Recent, and a "Most played" stats tab - Firmware backup & update straight from the console, plus NVRAM save tools - A one-file PC card generator (generate_usb.py): downloads art, builds the gamelist/covers/screenshots, copies videos and sets up the card for you - Built-in ISO and CHD converter - Renames games to the Redump naming format 👉 Download: cyberrep/3doode (under Releases) Made with a lot of love by a 3DO collector from Brazil. Feedback is very welcome — hope it's useful to fellow 3DO owners! 🇧🇷 Português Título: Menu moderno em 3 idiomas + firmware próprio para a ODE SataTo3DO do 3DO (grátis e aberto) Fala pessoal! Venho desenvolvendo um menu moderno e um kit de ferramentas para a ODE SataTo3DO do 3DO (placa RP2040), e acabei de lançar uma nova versão. É grátis e aberto. O que faz: - Menu (boot.iso) em Português, Inglês e Espanhol - Funciona nos dois firmwares: o de fábrica/Fixel e o meu, o "TADEU" (carregamento bem mais rápido) - 4 modos de navegar: Lista, Capas, Carrossel e Carrossel FX - Arte das capas, screenshots e prévias em vídeo - Tela de detalhes do jogo com capa + tela + vídeo lado a lado - Favoritos, Recentes e uma aba de Estatística (mais jogados) - Backup e atualização de firmware pelo próprio console, e ferramentas de save NVRAM - Gerador de cartão pra PC num arquivo só (generate_usb.py): baixa a arte, monta a lista/capas/telas, copia os vídeos e prepara o cartão - Conversor de ISO e CHD embutido - Renomeia para o formato Redump 👉 Baixe: cyberrep/3doode (em Releases) Feito com muito carinho por um colecionador de 3DO do Brasil. Feedback é super bem-vindo! 🇪🇸 Español Título: Menú moderno en 3 idiomas + firmware propio para el ODE SataTo3DO de 3DO (gratis y abierto) ¡Hola a todos! Llevo un tiempo desarrollando un menú moderno y un kit de herramientas para el ODE SataTo3DO de 3DO (placa RP2040), y acabo de publicar una nueva versión. Es gratis y abierto. Qué hace: - Menú (boot.iso) en Español, Inglés y Portugués - Funciona en los dos firmwares: el de fábrica/Fixel y el mío, el "TADEU" (carga mucho más rápida) - 4 modos para navegar: Lista, Carátulas, Carrusel y Carrusel FX - Carátulas, capturas y vistas previas en vídeo - Pantalla de detalles del juego con carátula + captura + vídeo lado a lado - Favoritos, Recientes y una pestaña de Estadísticas (más jugados) - Copia de seguridad y actualización de firmware desde la consola, y herramientas de guardado NVRAM - Generador de tarjeta para PC en un solo archivo (generate_usb.py): descarga el arte, arma la lista/carátulas/capturas, copia los vídeos y prepara la tarjeta - Conversor de ISO y CHD integrado - Renombra al formato Redump 👉 Descárgalo: cyberrep/3doode (en Releases) Hecho con mucho cariño por un coleccionista de 3DO de Brasil. ¡Se agradece cualquier feedback!

  31. Redditu/Glad_Issue3686 · r/u_Glad_Issue3686 · 1 point

    Hey everyone! I’ve been working through a pile of updates to my Windows apps, and the latest releases are now available. 😁 14 updated free Windows apps from RippinCraft Studios! There’s something here for Minecraft creators, audio and video projects, building app interfaces, and everyday desktop tasks. Here’s the updated lineup: RippinAppMaker 2.0.0 RippinPluginMaker 4.18.4 RippinWorldCreator 1.9.1 RippinModelStudio 1.3.1 RippinSkinStudio 1.2.2 RippinPackStudio 1.6.0 RippinModpackStudio 1.2.0 RippinServerManager 2.0.1 RippinHub Universal 1.1.0 RippinLink Universal 1.0.1 RippinAudioStudio 0.4.0 FrameCraft 0.4.0 RippinDJ 0.3.0 RippinFolderColors 0.5.0 Some highlights include SkinStudio’s combined editing workspace, improved WorldCreator camera controls, expanded audio effects and editing tools, more FrameCraft timeline tools, and additional AppMaker design components and export options. Each app is a separate download, so you can grab whichever interests you. They’re free to download and use under their included licences. 🖥️** Latest downloads**: github.com/RippingDaisy913/RippinApps-Releases/re… 🌐 Studio website: apps.rippingcraftserver.ca I’m an independent creator building these a bit at a time. Feedback, bug reports, and seeing what people make with them are always appreciated! Thanks for checking out RippinCraft Studios! 💜

  32. Redditu/localVariable_127 · r/ObsidianMD · 2 comments

    I built an AI chat plugin for Obsidian that works with any provider Hey everyone, About a month ago I started building this for myself. My problem was pretty simple: I already pay for some AI coding subscriptions like OpenCode Go, and I wanted one chat panel inside Obsidian that I could connect those to. Not a different plugin per provider. It started as a small thing for my own workflow, and it kept growing as I used it. At this point I figure it might be useful to other people too, so here it is. It's called AnyLLM, and it lives in your right sidebar. What it does - Every major provider — OpenAI, Anthropic (Claude), Google (Gemini), plus DeepSeek, Groq, Mistral, xAI (Grok), OpenRouter, Together AI, Fireworks AI, Cerebras, Perplexity, and OpenCode Go. - Bring your own key, or sign in — paste an API key, or authenticate with your ChatGPT Plus/Pro subscription via OAuth. - Local and custom endpoints — Ollama is preconfigured, and anything else (LM Studio, your own server, any OpenAI-compatible endpoint) works by setting a base URL and listing your model ids. - Switch models mid-conversation — keep the same thread and hop between providers/models as you go, instead of starting over. - Reference your notes with @ — mention any note in your vault and it gets pulled into the conversation as context. - Attachments — images, PDFs, audio, video, and text files. The composer only enables the attachment types the currently selected model actually supports, so you don't get silent failures. What I've actually tested I've tested three providers so far: OpenCode Go, a Gemini API key (free tier), and ChatGPT Plus (the $20 plan) sign-in. All three worked, including streaming and attachments. There are a few other providers in the list too, but I haven't tested those yet — so if you try one and something breaks, please open an issue and I'll look into it. Install (it's in beta) Desktop only — this won't work on Obsidian mobile. It's distributed through [BRAT](TfTHacker/obsidian42-brat) for now: 1. Install and enable the BRAT community plugin. 2. BRAT settings → Add Beta plugin → enter nethbotheju/obsidian-any-llm 3. Enable AnyLLM, then run AnyLLM: Open (or click the ribbon icon). Repo: nethbotheju/obsidian-any-llm — it's MIT licensed. Feedback If you have a feature request, feel free to add it — I'm actively working on this and I'd rather build things people actually want than guess. And if you run into any issues, please open an issue on the repo with as much detail as you can (provider, model, what you expected, what happened).

  33. Redditu/Previous-Success4685 · r/linuxapps · 2 points · 5 comments

    I built a lightweight music player with real-time audio visualization for Linux I've been working on a personal music player for Linux and wanted to share it with the community. It uses Lua, Python, LÖVE, and FFT to deliver music playback with real-time audio visualization. Features: - YouTube music search and playback - Customizable audio visualizer - Dynamic colors and visual effects - Configurable bars, spacing, and smoothing - Lightweight desktop interface It's an open-source project, and I'd appreciate honest feedback from Linux users, especially those interested in desktop customization and ricing. GitHub: HimanshuS073/music_visualizer

  34. Redditu/ShakaLaka_Around · r/SaaS · 1 point · 1 comment

    I added a dialer to my open-source LinkedIn/email outreach tool (opening-hours queue, scripts, call logging) I’m the author of Linki, an open-source outreach tool I built because I wanted one place to run my own outbound. You import a lead list from Sales Navigator, clean it, and run multichannel campaigns (LinkedIn + email) where an AI agent personalizes each message per lead. It also has a unified inbox and Apollo enrichment. The one channel it was missing was phone, and I was juggling calls in a separate tool. So I built a simple dialer into it. What it does: Queue by opening hours. You set opening hours per contact, and the queue sorts into open now, closing soon and later. Useful when you call businesses with fixed hours (I tested it on law firms). Scripts with variables. You write a script once, and it shows next to the call with the lead’s name and other fields filled in. One-click calling. It uses Phone Link on Windows, so the call goes through your own phone. No cloud telephony, no per-minute cost. I haven’t tested it on Mac, so if you try it there, tell me whether it works. Call outcomes. After each call you log reached, no answer, voicemail or callback. Picking callback asks when, logs it, and can create a to-do. Leads in a cooldown move to a waiting bucket and come back on schedule. Context on the side. Notes, past activity and to-dos for the contact are next to the call screen. There’s also a small cheerleader buddy, because cold calling is a lot of rejection and it helped me more than I expected. It’s simple on purpose. I’ve used it a lot over the last few days and it’s already replaced my spreadsheet. Repo: moaljumaa/linki I’d like to hear what breaks, especially on Mac and with other call setups.

  35. Redditu/Darkatek7 · r/ps5homebrew · 17 points · 2 comments

    [Release] ProsperoSunshine – Stream your PS5 games to Moonlight (up to 4K60, HEVC/HDR) Hey everyone! I've been working on a project called ProsperoSunshine, and I wanted to share it with the PS5 homebrew community! It's basically a Sunshine-compatible streaming host that runs directly on your jailbroken PS5. This means you can stream your PS5 games to pretty much any device running Moonlight, without needing a PC in between. What's working so far: - H.264 and HEVC video streaming, up to 4K60 with HDR - Game audio and controller input, including virtual DualSense support - Keyboard and mouse input (new in v0.2.1!) - Launch installed PS5 games directly from Moonlight - PIN pairing and management of connected devices - PS5 app to start/stop the host, change settings and enable autoload I've tested it with Moonlight on PC, iPhone and Moonlight Web. Firmware compatibility: - 13.00: Tested up to 4K60, including HEVC/HDR - 10.20: Tested up to 1080p60, including HEVC/HDR - Other firmware versions still need testing! It's still an early project, so there are definitely things that need improvement. Only one streaming session is supported at a time, and not every game or Moonlight client has been tested yet. You'll need a homebrew-enabled PS5 with an ELF loader and ShadowMountPlus. GitHub (source code & downloads): Darkatek7/ProsperoSunshine I'd really appreciate it if some of you could give it a try! Especially if you're running a different firmware version. If you run into any issues or have suggestions, feel free to open a GitHub issue or leave a comment here. I'm actively working on improving it, and feedback from the community would help a lot. Hope some of you find it useful! :)

  36. Xcode 27でExpoアプリが起動直後にクラッシュする。UIScene必須化と、SDK 57・58での対処 こんな状況の方向けです Xcode 27でビルドしたExpo / React Nativeアプリが、起動した直後に落ちる クラッシュログのスタックに UIApplicationEvaluateRuntimeIssueForNoSceneLifecycleAdoption が出ている Expo SDK 57を使っている。SDK 58に上げれば直るのか、上げずに直せるのかを知りたい 結論(先に答え) iOS 27 SDKでビルドしたUIKitアプリは、UIScene(シーン)ライフサイクルに対応していないと起動時にアサートで落ちます。Expoの ios/ は expo prebuild の生成物なので、自分でSwiftを直すのではなく、設定(config plugin)で直します。 使っているExpo 対処 SDK 58 テンプレートが対応済みです。新規プロジェクトなら、追加の設定は要りません。SDK 57から上げる場合は、公式のアップグレード手順で依存関係を更新してから、npx expo prebuild --clean し直します(ios/ をコミットせず expo prebuild で作る構成の場合)。ios/ を手で管理している場合は、公式ガイドの手順で移行します SDK 57.0.23以降 expo-build-properties に ios.enableSceneSupport: true を足して、npx expo prebuild --clean します(推奨) SDK 57.0.22以前 公式のシーン対応のコードがありません。57.0.23以上に上げてから、上の手順にします SDK 57の設定は、Expo公式のガイド(iOS scene-based life cycle)にも載っています。この記事では、その使い方に加えて、仕組みと、SceneDelegateを自作して踏んだ点を書きます。 確認した範囲は、手段によって違います。 自作のconfig plugin(後半で紹介)は、Expo 57.0.23〜57.0.27、React Native 0.86.3、Xcode 27.0、macOS 27.0で、実際にビルドして起動を確認しました enableSceneSupport は、検証用に作ったSDK 57の新規プロジェクト(expo 57.0.31、expo-build-properties 57.0.22、React Native 0.86.3、Xcode 27.0、iOS 27.0のシミュレータ)で、ビルドと起動まで確認しました。見たのは次のとおりです Release構成の起動とJSの描画、URLスキームで開く操作(起動していない状態と起動中)、バックグラウンドからの復帰 expo-dev-client 57.0.20を足したDebug構成での、ランチャーの表示とMetroからの読み込み 同じプロジェクトで設定を外すと、前節の症状(EXC_BREAKPOINT、スタックに UIApplicationEvaluateRuntimeIssueForNoSceneLifecycleAdoption)で落ちること 確認していないのは、実機、Universal Links、クイックアクション、Handoff、expo 57.0.23〜57.0.30、AppDelegate.swift をテンプレートから変えているプロジェクトです SDK 58は、テンプレートの中身を読んで確認しただけで、既存プロジェクトを上げる手順は実行していません 症状 Xcode 27でビルドしたアプリをシミュレータで起動すると、起動直後にクラッシュします。 例外は EXC_BREAKPOINT (SIGTRAP) クラッシュログのスタックに UIApplicationEvaluateRuntimeIssueForNoSceneLifecycleAdoption JavaScript側のエラーではなく、ネイティブの起動処理で落ちているので、アプリのコードを疑っても何も出てきません。Appleは2025年のWWDCで、iOS 26の次のリリース以降は、最新SDKでビルドしたUIKitアプリでUISceneライフサイクルが必須になると予告していました。それがXcode 27で現実になった形です。 この要件が掛かるのは、アプリをビルドするSDKです。AppleもWWDC26のセッションで「最新のSDKでビルドするときに必須で、なければアプリは起動しなくなる」と説明していて、Expoの公式ガイドも「Xcode 27でビルドしたアプリが、iOS 27で正しく起動しない」と書いています。実行する端末がiOS 27かどうかだけで決まる話ではありません。なお、iOS 26以前のSDKでビルド済みのアプリがiOS 27でどうなるかは、この記事では確かめていません。 UIScene対応で何が変わるか 今までのExpoのテンプレートは、AppDelegate がウィンドウを作り、React Nativeを起動していました。シーン方式では、この役割が SceneDelegate に移ります。必要なのは次の3点です。 Info.plist に UIApplicationSceneManifest を足す UIWindowSceneDelegate を実装した SceneDelegate を足す AppDelegate から、ウィンドウの生成とReact Nativeの起動を外す もう1点、地味に効くことがあります。シーン方式にすると、URLスキームやUniversal Linksを受ける AppDelegate の application(_:open:options:) と application(_:continue:restorationHandler:) は呼ばれなくなります。リンクを使うアプリは、シーン側からの転送が要ります。 ほかにも、公式ガイドは次の2点を挙げています。UIScreen.main と UIApplication.shared.keyWindow は使わず、ビューが属するシーンから取ること。ExpoAppSceneDelegate はアプリ拡張(ウィジェットなど)のターゲットでは使えないことです。 SDK 58では、テンプレートが対応済みです SDK 58のテンプレート(expo-template-bare-minimum 58.0.30)は、次の3つを持っています。 AppDelegate.swift @main class AppDelegate: ExpoAppDelegate, ExpoReactNativeFactoryProvider { var window: UIWindow? var reactNativeDelegate: ExpoReactNativeFactoryDelegate? var reactNativeFactory: RCTReactNativeFactory? public override func application( _ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil ) -> Bool { let delegate = ReactNativeDelegate() let factory = ExpoReactNativeFactory(delegate: delegate) delegate.dependencyProvider = RCTAppDependencyProvider() reactNativeDelegate = delegate reactNativeFactory = factory // The window is created and React Native is started by SceneDelegate under the // scene-based life cycle (required by the iOS 27 SDK). return super.application(application, didFinishLaunchingWithOptions: launchOptions) } } SceneDelegate.swift internal import Expo @objc(SceneDelegate) class SceneDelegate: ExpoAppSceneDelegate { // Extension point for config plugins. } Info.plist には、UIApplicationSceneManifest で $(PRODUCT_MODULE_NAME).SceneDelegate が指定されています。 SDK 57のテンプレート(57.0.33)の AppDelegate.swift には、シーン関連の記述がなく、SceneDelegate.swift もありません。Info.plist にも UIApplicationSceneManifest はありません。つまりSDK 57のアプリは、既定ではシーン方式になりません。 SDK 57では、expo-build-properties の設定で直せます(推奨) SDK 58のテンプレートに近い形にする設定が、expo-build-properties の ios.enableSceneSupport として用意されています。 app.json { "expo": { "plugins": [ [ "expo-build-properties", { "ios": { "enableSceneSupport": true } } ] ] } } すでに expo-build-properties を使っているなら、ios の中に足すだけです。そのあと、ios/ を作り直します。 npx expo prebuild --clean EAS Buildでビルドする場合は、新しいビルドを作れば、その中でprebuildされます。 条件 expo が57.0.23以上。 古いと、プラグインがエラーにします expo-build-properties が57.0.20以上。 プロパティは57.0.19で入り、57.0.20で、別のconfig pluginが起動処理に行を足している場合(CHANGELOGでは @react-native-firebase/app が例に挙がっています)への対応が入りました。npm ls expo-build-properties で確かめて、古ければ npm install expo-build-properties@sdk-57 で上げます。ただの npm install expo-build-properties は latest タグの版(2026-10-31時点で58.0.11)を入れてしまうので、SDK 57では使いません。また、57.0.23の expo が推奨する範囲(bundledNativeModules.json では ~57.0.18)は、プロパティが入る前の57.0.18も含むので、npx expo install --fix だけでは上がらないかもしれません。なお、新規のSDK 57プロジェクトで npx expo install expo-build-properties を実行したところ、57.0.22が入りました(latest の58系ではなく、SDK 57向けの版です) AppDelegate.swift がSDK 57のテンプレートのまま。 違う場合、プラグインはエラーにして、上書きしません。公式ガイドは、その場合は手で直すよう案内しています Info.plist に、シーンの設定(UIApplicationSceneManifest)がまだ無い。 すでにあれば、同じようにエラーにします。自作のシーン対応(後半の自作プラグインなど)があるときは、先にそれを外します。併用はしません 何が変わるか SceneDelegate.swift は作りません。Expo内蔵の EXExpoAppSceneDelegate(次の節の ExpoAppSceneDelegate の、Objective-Cでの名前です)を、Info.plist から直接指定します。 Info.plist に UIApplicationSceneManifest を足し、UISceneDelegateClassName に EXExpoAppSceneDelegate を指定する AppDelegate を ExpoReactNativeFactoryProvider に適合させる didFinishLaunchingWithOptions から、ウィンドウの生成と startReactNative を外す SDK 57のテンプレートの AppDelegate.swift に、プラグインの置換を当てた差分は、次のとおりです(... は、差分に出ない行を省いた印です)。 -class AppDelegate: ExpoAppDelegate { +class AppDelegate: ExpoAppDelegate, ExpoReactNativeFactoryProvider { ... -#if os(iOS) || os(tvOS) - window = UIWindow(frame: UIScreen.main.bounds) - factory.startReactNative( - withModuleName: "main", - in: window, - launchOptions: launchOptions) -#endif 起動処理は、上のSDK 58のテンプレートと同じになります。違う点が2つあります。1つは、Info.plist の指定先が、SceneDelegate ではなく EXExpoAppSceneDelegate であることです。もう1つは、SDK 57のテンプレートにある、URLとUniversal Linksの上書き(application(_:open:options:) など)を、プラグインは消さずに残すことです。残った上書きが二重に通知しないかは、次の節で書きます。 SDK 58に上げたとき SDK 58以降では、このプロパティは何もしません。prebuildが「もう要らないので消してよい」という警告を出すので、設定から外します。 公式の実装の仕組み expo パッケージの中を見ると、ios/AppDelegates/ExpoAppSceneDelegate.swift があります。クラスのコメントには、次のように書かれています。 Required by the iOS 27, which asserts at launch unless the app adopts the scene-based life cycle. やっていることは、次のとおりです。 シーンが接続されたときに UIWindow を作り、React Nativeを起動する ライフサイクル、URL、Universal Links、クイックアクションを、ExpoAppDelegate へ転送する(SceneEventForwarder.swift) AppDelegate 側は、ExpoReactNativeFactoryProvider というプロトコルに適合させます。SceneDelegate は、これを通じて AppDelegate が作った reactNativeFactory を受け取ります。 入った版: npmのtarballを開いて調べたところ、ExpoAppSceneDelegate.swift は expo 57.0.17、57.0.19〜57.0.22 には無く、57.0.23 から入っています。enableSceneSupport の下限が57.0.23なのは、このためです。 URLの通知が二重にならない仕組みと、その限界。 SDK 57のテンプレートの AppDelegate は、application(_:open:options:) などを上書きして、RCTLinkingManager を呼んでいます。シーン方式では、この上書きが SceneEventForwarder 経由でもう一度呼ばれるので、そのままだと二重に通知されます。そこで SceneEventForwarder は、RCTLinkingManager が出す通知(RCTOpenURLNotification)を監視し、すでに通知されていれば呼び直しません。この通知名はReact Nativeの内部の名前で、ソースのコメントにも、名前が変わると二重の通知が戻る(リンクが失われることはない)と書かれています。つまりこれは、対象バージョンのソースで成り立つ挙動です。自分で AppDelegate に足した転送処理が RCTLinkingManager を呼んでいる場合は、公式ガイドも二重に届くことがあるとして、その呼び出しを外すよう案内しています。検証用プロジェクト(expo 57.0.31)では、テンプレートの上書きが残ったまま、起動中にURLスキームで開いて、Linking の url イベントが1回だけ届くことを確かめました。シミュレータでの確認で、実機は未確認です。 SDK 58の修正として挙げられているもの。 公式ガイドは、コールドスタートのURL(Linking.getInitialURL() が null になる問題)の修正と、クイックアクション・Handoffの転送を、SDK 58の expo の修正として挙げています。57.0.23のソースには、どちらに当たるコードも入っています(launchOptions の組み立て直し、クイックアクションの転送)。検証用プロジェクト(expo 57.0.31)では、コールドスタートのURLは Linking.getInitialURL() に届きました。クイックアクションとHandoffは確かめていません。57.0.23〜57.0.30も確かめていないので、これらを使うアプリは、実機で確かめてください。SDK 58の expo に上げるのも選択肢ですが、既存のプロジェクトでは、依存関係の更新と動作の確認が要ります。 参考: 公式のプラグインが使えないとき、自作のconfig plugin AppDelegate.swift をテンプレートから変えているなど、enableSceneSupport が上書きを拒否する場合は、公式ガイドの「Migrating a hand-managed iOS project」の手順で、手で直すのが基本です。ios/ を expo prebuild で作り直す運用なら、同じ内容をconfig pluginにもできます。私は公式のプラグインに気づく前に、次のプラグイン(この記事では「配線版」と呼びます)で対応していました。enableSceneSupport とは併用しません。 このプラグインは、SDK 58のテンプレートと同じく、自前の SceneDelegate.swift(ExpoAppSceneDelegate のサブクラス)を作る形で、EXExpoAppSceneDelegate を直接指定する公式のプラグインとは作りが違います。 ios/ は expo prebuild で再生成されるので、直接編集しても消えます。plugins/withIosSceneDelegate.js を作り、app.json の plugins に登録します。 app.json { "expo": { "plugins": ["./plugins/withIosSceneDelegate.js"] } } プラグインがやることは、先ほどの3点を注入することだけです。 withInfoPlist で UIApplicationSceneManifest を足す withXcodeProject で SceneDelegate.swift を書き出し、Xcodeプロジェクトに登録する withAppDelegate で AppDelegate.swift を書き換える(ExpoReactNativeFactoryProvider に適合させ、ウィンドウ生成と startReactNative を外す) 全文は次のとおりです(Expo 57.0.27 / React Native 0.86.3 のアプリで使っているものです。コメントだけ、この記事の説明に合わせて書き直しています)。 withIosSceneDelegate.js の全文 plugins/withIosSceneDelegate.js const { withInfoPlist, withAppDelegate, withXcodeProject, IOSConfig } = require('expo/config-plugins'); const fs = require('fs'); const path = require('path'); // iOS 27 SDK(Xcode 27)でビルドしたUIKitアプリは、UISceneライフサイクルに対応して // いないと起動直後にクラッシュする("UIScene life cycle is required for apps built // with this SDK")。 // // Expo SDK 57 の本体には、シーン対応のネイティブ実装(ExpoAppSceneDelegate、 // ExpoReactNativeFactoryProvider)が入っているが、expo prebuild のテンプレートは // まだ配線していない(SDK 58 のテンプレートで配線される)。このプラグインは、 // SDK 58 のテンプレートと同じ配線(起動処理をSceneDelegateへ移す形)を、SDK 57 の // 生成物に当てはめるもの。生成物がSDK 58のテンプレートと完全に一致することまでは // 保証しない(URL・Universal Linksの上書きは、一致したときだけ除く)。 // - Info.plist に UIApplicationSceneManifest を追加する // - SceneDelegate.swift(ExpoAppSceneDelegate のサブクラス)を追加する // - AppDelegate.swift を、window生成とReact Native起動をSceneDelegateへ任せる形に直す // (ExpoReactNativeFactoryProvider に適合させ、didFinishLaunching内のwindow生成と // startReactNative を除く。URL・Universal Linksの上書きも、SDK 58 のテンプレートに // 合わせて除く。シーン採用後はUIKitがAppDelegate側を呼ばなくなり、 // ExpoAppSceneDelegateがExpoAppDelegateとRCTLinkingManagerへ転送する) // // ios/ は expo prebuild の自動生成物(gitignore)なので、手で直さずここで注入する。 // // 【SDK 58 へ上げるとき】テンプレートが同じ配線を持つので、このプラグインと // app.json の登録を撤去する。AppDelegateは、すでにExpoReactNativeFactoryProvider // に適合していれば何もしないが、Info.plist と SceneDelegate.swift は上書きする。 const SCENE_DELEGATE_CLASS_NAME = 'SceneDelegate'; const SCENE_DELEGATE_FILENAME = ${SCENE_DELEGATE_CLASS_NAME}.swift; // SceneDelegate.swift の内容は、SDK 58 のテンプレート(expo-template-bare-minimum)と // 同じ(先頭の生成コメントを除く)。 const SCENE_DELEGATE_SOURCE = `// このファイルは plugins/withIosSceneDelegate.js が生成する。 // 手で編集しても `expo prebuild` 実行時に上書きされる。 internal import Expo @objc(${SCENE_DELEGATE_CLASS_NAME}) class ${SCENE_DELEGATE_CLASS_NAME}: ExpoAppSceneDelegate { // Extension point for config plugins. } `; const PROVIDER_PROTOCOL = 'ExpoReactNativeFactoryProvider'; // SDK 57 のテンプレートが生成するAppDelegate.swiftの、書き換える箇所。 // クラス宣言とwindow生成・startReactNativeの2箇所は、書き換えないとシーン対応が // 成り立たない。テンプレートが変わって一致しなくなった場合は、黙って壊れた // AppDelegateを作らず、prebuildの時点で失敗させる。 // URL・Universal Linksの上書きは、一致しなくても失敗にはせず、一致したときだけ撤去する // (残っても二重に通知されない、という前提と限界は、LINKING_OVERRIDES の説明を参照)。 const CLASS_DECLARATION = 'class AppDelegate: ExpoAppDelegate {'; const CLASS_DECLARATION_PATCHED = class AppDelegate: ExpoAppDelegate, ${PROVIDER_PROTOCOL} {; const WINDOW_AND_START_REACT_NATIVE = `#if os(iOS) || os(tvOS) window = UIWindow(frame: UIScreen.main.bounds) factory.startReactNative( withModuleName: "main", in: window, launchOptions: launchOptions) #endif `; const WINDOW_AND_START_REACT_NATIVE_PATCHED = // The window is created and React Native is started by \SceneDelegate` under the // scene-based life cycle (required by the iOS 27 SDK). `; // SDK 57 のテンプレートが持つ、URL・Universal Linksの上書き。シーン採用後は // UIKitから呼ばれなくなり、代わりに ExpoAppSceneDelegate(SceneEventForwarder)が // ExpoAppDelegateへ転送する。転送側は、残った上書きが RCTLinkingManager を呼んだことを // 検知して、二重に通知しない作りになっている(Expo 57.0.23のソースで確認)。 // ただし、これはそのバージョンのソースの挙動で、テンプレートが変わった場合や、 // 自分で足した転送処理まで保証するものではない。 const LINKING_OVERRIDES = ` // Linking API public override func application( _ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey: Any] = [:] ) -> Bool { return super.application(app, open: url, options: options) || RCTLinkingManager.application(app, open: url, options: options) } // Universal Links public override func application( _ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void ) -> Bool { let result = RCTLinkingManager.application(application, continue: userActivity, restorationHandler: restorationHandler) return super.application(application, continue: userActivity, restorationHandler: restorationHandler) || result }`; function replaceOrThrow(contents, search, replacement, description) { if (!contents.includes(search)) { throw new Error( withIosSceneDelegate: AppDelegate.swift内に${description}が見つかりませんでした。 + 'Expoのテンプレートが変わった可能性があるため plugins/withIosSceneDelegate.js を確認してください。' ); } return contents.replace(search, replacement); } function patchAppDelegate(contents) { // すでにシーン対応済み(prebuildの再実行、または公式テンプレートが対応済み)。 if (contents.includes(PROVIDER_PROTOCOL)) { return contents; } let patched = contents; patched = replaceOrThrow(patched, CLASS_DECLARATION, CLASS_DECLARATION_PATCHED, 'AppDelegateのクラス宣言'); patched = replaceOrThrow( patched, WINDOW_AND_START_REACT_NATIVE, WINDOW_AND_START_REACT_NATIVE_PATCHED, 'window生成とstartReactNativeの呼び出し' ); return patched.replace(LINKING_OVERRIDES, ''); } function withIosSceneManifest(config) { return withInfoPlist(config, (config) => { config.modResults.UIApplicationSceneManifest = { UIApplicationSupportsMultipleScenes: false, UISceneConfigurations: { UIWindowSceneSessionRoleApplication: [ { UISceneConfigurationName: 'Default Configuration', UISceneDelegateClassName: $(PRODUCT_MODULE_NAME).${SCENE_DELEGATE_CLASS_NAME}, }, ], }, }; return config; }); } function withIosSceneAppDelegate(config) { return withAppDelegate(config, (config) => { config.modResults.contents = patchAppDelegate(config.modResults.contents); return config; }); } function withIosSceneDelegateFile(config) { return withXcodeProject(config, (config) => { const projectRoot = config.modRequest.projectRoot; const projectName = IOSConfig.XcodeUtils.getProjectName(projectRoot); const sourceRoot = IOSConfig.Paths.getSourceRoot(projectRoot); fs.writeFileSync(path.join(sourceRoot, SCENE_DELEGATE_FILENAME), SCENE_DELEGATE_SOURCE); const filePath = ${projectName}/${SCENE_DELEGATE_FILENAME}; if (!config.modResults.hasFile(filePath)) { IOSConfig.XcodeUtils.addBuildSourceFileToGroup({ filepath: filePath, groupName: projectName, project: config.modResults, }); } return config; }); } module.exports = function withIosSceneDelegate(config) { config = withIosSceneManifest(config); config = withIosSceneAppDelegate(config); config = withIosSceneDelegateFile(config); return config; }; 作りで気をつけた点 置換が失敗したら、prebuildを落とします。 AppDelegate.swift の書き換えは文字列の置換です。Expoのテンプレートが変わって一致しなくなったとき、黙って壊れた AppDelegate を作ると、原因の分からない起動クラッシュになります。replaceOrThrow で、失敗した時点でprebuildごと止めています。 すでに対応済みなら何もしません。 AppDelegate.swift に ExpoReactNativeFactoryProvider が含まれていれば、書き換えをスキップします。prebuildを再実行しても二重に書き換わりません。SDK 58に上げたときは、このプラグインと app.json の登録を外してください。AppDelegateは何もしませんが、Info.plist と SceneDelegate.swift は上書きするので、残す意味がありません。 ただし、この判定は弱いです。名前が含まれているかどうかだけを見るので、コメントに書かれているだけでも「対応済み」と判断しますし、起動処理が正しく移されているかまでは見ません。厳密にするなら、公式のプラグインのように、class AppDelegate: ExpoAppDelegate, ExpoReactNativeFactoryProvider { の行まで含めて判定します。 URLの上書きは、「一致したときだけ撤去」にしています。 SDK 57のテンプレートの AppDelegate は、application(_:open:options:) などを上書きして RCTLinkingManager を呼んでいます。SDK 58のテンプレートに合わせて撤去しますが、一致しなければ失敗にはせず、そのまま残します。残っても、前の節のとおり SceneEventForwarder が重複を避けるはずです。ただしこれは、対象バージョンのソースを読んだ範囲の話です。テンプレートが変わった場合や、自分で足した転送処理まで保証するものではありません。 自前のSceneDelegate(旧版)で踏んだこと この記事には、私が書いたプラグインが2つ出てきます。区別のために、名前を付けます。 旧版: 公式の部品に気づく前に書いた、SceneDelegate を自前で実装する版です(UIResponder と UIWindowSceneDelegate を直接実装します)。ウィンドウの生成は AppDelegate に残し、SceneDelegate は、そのウィンドウにシーンを割り当てるだけです。別のアプリで書いたものを、もう1つのアプリへ移して使いました 配線版: 前の節に全文を載せたものです。公式の ExpoAppSceneDelegate を継承する SceneDelegate を作り、ウィンドウの生成は AppDelegate から外します。旧版のあとに、別のアプリで使いました 公式のプラグイン(enableSceneSupport)に気づいたのは、そのあとです。標準の AppDelegate なら、どれも不要になりましたが、同じ道を通る人がいそうなので、旧版で踏んだ点を残します。次の3つは旧版で起きたことで、配線版で起きるかどうかは、確かめていません(項ごとに、配線版の扱いを書きます)。 Swift 6.2: import のアクセスレベルをそろえる 旧版の SceneDelegate.swift で import Expo と書いたところ、次のコンパイルエラーになりました。 ambiguous implicit access level for import of 'Expo' この環境では、アプリのターゲットに、アクセスレベルを明示したimportのファイルが入っていました。Expoのテンプレートの AppDelegate.swift は internal import Expo、expo-modules-autolinking が生成してアプリのターゲットに直接コンパイルされる ExpoModulesProvider.swift は internal import ExpoModulesCore です。そこへ、アクセスレベルを書かない import Expo のファイルを足した結果、アクセスレベルに関するコンパイルエラーになったようです(Swift 6.2のimportのアクセスレベル修飾子に関する挙動とみていますが、一般的な発生条件までは調べていません)。internal import Expo にそろえたら解消しました。自前のSwiftファイルを足すときは、テンプレートの書き方に合わせて internal import にします。配線版の SceneDelegate.swift は、最初から internal import Expo です。 コールドスタートのディープリンクが、JSに届かない 旧版では、アプリが起動していない状態から scheme://... で開くと、URLが無視されました(起動中は問題ありませんでした)。再現は次のとおりです。 アプリを終了させる(com.example.myapp は、自分のbundle identifierに置き換えます) xcrun simctl terminate booted com.example.myapp 起動していない状態から、URLスキームで開く(myapp://... も、自分のスキームに置き換えます) xcrun simctl openurl booted "myapp://some/path" アプリがもう起動していないなら、terminate は要りません。 起動していない状態から開くと、iOSが「"アプリ名"で開きますか?」という確認を出します。「開く」を押すまで、アプリは起動しません。起動中のアプリに開いたときは、出ませんでした。 原因は、React Nativeの Linking.getInitialURL() が、bridge.launchOptions しか見ないことです。この値は、didFinishLaunchingWithOptions でブリッジを作った時点で固定されます。シーン方式では、コールドスタートのURLは didFinishLaunchingWithOptions ではなく、シーンが接続されたときの connectionOptions で渡されます。ブリッジを作った後に来るので、あとから差し込めませんでした。 公式の ExpoAppSceneDelegate は、この点を扱っています。connectionOptions からlaunch optionsを組み立て直し、startReactNative に渡しています。ソースのコメントにも、次の趣旨が書かれています。 Linking.getInitialURL() only reads them from launch options, so rebuild them here; otherwise a link that cold-starts the app is delivered to no one 公式の ExpoAppSceneDelegate の方は、動かして確かめました。 enableSceneSupport を入れた検証用プロジェクト(expo 57.0.31、Release、シミュレータ)で、アプリを終了させてから上のコマンドで開くと、Linking.getInitialURL() が scenecheck://cold/path?x=1 を返しました。ただし、公式ガイドは、この修正をSDK 58の expo のものとして挙げています。57.0.23〜57.0.30と実機は確かめていないので、SDK 57でディープリンクを使うアプリは、上のコマンドで確かめてください。 配線版で、コールドスタートのURLが届くかどうかは、確かめていません。配線版も同じ ExpoAppSceneDelegate を継承するので、公式の構成と同じく届くと見込んでいますが、見込みです。配線版を使うなら、上のコマンドで確かめてください。 ウィンドウは、どこで作るか 旧版は、ウィンドウの生成を AppDelegate に残し、SceneDelegate は、そのウィンドウにシーンを割り当てるだけにしています(配線版と公式の実装は、逆に、ウィンドウをシーン側で作ります)。別のアプリで書いた版から引き継いだ作りで、そこには「expo-dev-launcher が didFinishLaunchingWithOptions の時点でウィンドウの存在を前提にしていて、シーン側で作ると、Dev Client(Debugビルド)が起動直後に落ちる」という趣旨のメモがありました。 ただ、私はこの理由を裏取りできていません。シーン側でウィンドウを作って落ちる場面は、再現していません。expo-dev-launcher 55.0.42・56.0.29・57.0.0・57.0.21のソースにも、ウィンドウの存在を確かめて fatalError にする処理は見つかりませんでした(ソースを読んだだけで、動かして確かめたものではありません)。ですから、「シーン側で作ると落ちる」とは言えません。旧版は、テンプレートの作りを変えない方針で、ウィンドウの生成を元の場所に残しています。 公式の ExpoAppSceneDelegate は、ウィンドウをシーン側で作ったあと、provider.window = window で AppDelegate の window に反映します(コメントには expo-system-ui が例に挙がっています)。expo-dev-client を使うアプリでこの構成が通るかは、検証用プロジェクトで確かめました。expo-dev-client 57.0.20を足したDebug構成で、enableSceneSupport のまま起動すると、ランチャーが表示され(fatalError で落ちませんでした)、ランチャーから開発サーバーのURLを開くと、Metroからバンドルを読み込んでJSが描画されました。シミュレータでの最小構成の確認なので、使っているライブラリが多いアプリは、Debugビルドの起動まで確認してください。配線版も同じ ExpoAppSceneDelegate を使いますが、Dev Clientでの起動は、確かめていません。 確認のしかた prebuildのあとで、生成物を見ます。 ios/<アプリ名>/Info.plist に UIApplicationSceneManifest が入っていること、AppDelegate.swift に ExpoReactNativeFactoryProvider があって、startReactNative が無いことを確かめます。enableSceneSupport は、合わないときはエラーにして上書きしないので、エラーが出たらその場で分かります DebugとReleaseの両方で起動を確認します。 Debugだけで終わらせないでください アプリが起動していない状態(コールドスタート)と、起動中のそれぞれで、URLスキームから開いて確認します 起動直後の白い画面で、判断しないでください。 私の環境では、Releaseの初回起動で、描画まで数秒かかりました。落ちたかどうかは、次の2つを合わせて見ます。1つは、アプリのプロセスが生きているかで、xcrun simctl spawn booted launchctl list は、それを見る手段の一つです(これだけで、落ちていないことの証明にはなりません)。もう1つは、~/Library/Logs/DiagnosticReports/ に新しい .ips が出ていないかです バックグラウンドからの復帰、AppState に依存する処理(ロック画面、同期など)も確認します。ExpoAppSceneDelegate は、シーンのライフサイクルを ExpoAppDelegate へ転送しています まとめ Xcode 27でビルドしたアプリは、UIScene未対応だと起動直後に落ちます。症状は UIApplicationEvaluateRuntimeIssueForNoSceneLifecycleAdoption Expoは 57.0.23 から 公式の ExpoAppSceneDelegate を持ちますが、SDK 57のテンプレートは配線していません。SDK 58のテンプレートは配線済みです SDK 57では、expo-build-properties の ios.enableSceneSupport: true を足して、npx expo prebuild --clean します。expo は57.0.23以上、expo-build-properties は57.0.20以上です。latest の版はSDK 58用なので、入れないでください 公式のプラグインが対象にするのは、SDK 57のテンプレートのままの AppDelegate.swift だけです。変えている場合は、エラーになるので、手で直します(自作のconfig pluginは参考です) 自前のSwiftを足すなら、internal import にそろえます(この環境のSwift 6.2で踏みました) ディープリンクとDev Clientは、シミュレータで動くことを確かめました(expo 57.0.31、実機は未確認)。使っているアプリは、実機でも確かめてください 参考 Expo: iOS scene-based life cycle Expo: expo-build-properties Apple Developer Documentation: Migrating to the UIKit scene-based life cycle (TN3187) WWDC26: Modernize your UIKit app node_modules/expo-build-properties/build/iosSceneSupport.js node_modules/expo/ios/AppDelegates/ExpoAppSceneDelegate.swift node_modules/expo/ios/AppDelegates/SceneEventForwarder.swift node_modules/expo/ios/AppDelegates/ExpoReactNativeFactoryProvider.swift ちなみに、この記事で踏んだトラブルは、自作のアプリ「Solo + Us」を作っているときに実際に遭遇したものです。 Solo + Usは、性行為・自慰行為の記録を、端末の中だけで暗号化して残す、オフラインの記録アプリです。アカウント登録も不要です。 アプリ:Google Play(Android) ソースコード:GitHub

  37. The first of its kind: how one unbounded request body became a denial-of-service class across every major MCP SDK --- title: "The first of its kind: how one unbounded request body became a denial-of-service class across every major MCP SDK" published: true description: "In April 2026 I reported CVE-2026-39313. Six months later the same flaw had been found and patched in the official Python, Java, Go, Ruby, PHP and TypeScript MCP SDKs. Here is the full class, and why most scanners still cannot see the worst of it." tags: security, mcp, ai, devsecops --- The one-line version In April 2026 I reported CVE-2026-39313, a denial-of-service flaw in an MCP server framework. It was the first CVE of its kind: an unbounded HTTP request body, CWE-770, that lets a single unauthenticated request exhaust a Model Context Protocol server's memory and take it offline. Over the next six months the identical flaw was found and patched in at least nine more MCP projects, including the official Python, Java, Go, Ruby, PHP and TypeScript SDKs. A third-party analysis in July called it "a new vulnerability category." By October two of those CVEs sat in the SDKs that the whole ecosystem is built on, together serving close to half a billion downloads a month. This is the story of that class: how far it spread, who patched and who is still exposed, and why the two worst ones are effectively invisible to the scanners most teams rely on. Every claim below links to a primary source. What the bug actually is MCP servers speak over an HTTP transport: Streamable HTTP, Server-Sent Events, and OAuth routes. To handle a request, the server reads the request body into memory before it does anything else. The flaw is simple and brutal. The read loop has no size limit. It keeps appending chunks to a buffer until the client stops sending or the process dies. There is no authentication in front of it, because the body is read before any auth check runs. So an attacker who can reach the endpoint sends one large POST, or a slow endless stream, and the server allocates memory until it is killed by the OOM reaper. One request, one dead server, no credentials required. This is CWE-770, allocation of resources without limits. It is not exotic. That is exactly why it turned up everywhere. CVE-2026-39313: the first one The first public advisory of this class was in mcp-framework, a popular TypeScript framework for building MCP servers. In versions 0.2.21 and below, the readRequestBody() function in the HTTP transport concatenated body chunks into a string with no cap. The framework even had a maxMessageSize configuration value, but readRequestBody() never referenced it. The limit existed on paper and was never enforced in code. A single large POST to /mcp crashed the server. I reported it, it was fixed in 0.2.22, and the advisory published on 16 April 2026. - Advisory (GitHub, GHSA-353c-v8x9-v7c3): github.com/QuantGeekDev/mcp-framework/security/ad… - CVSS 4.0 8.7 (High), CWE-770 At the time it looked like one framework's mistake. It was not. It was not a bug. It was a pattern. Here is the timeline of the same unbounded-body denial-of-service turning up across the MCP ecosystem, as advisories and patches landed through 2026: - 16 April — mcp-framework, CVE-2026-39313 (the first). - April to June — Google's MCP Toolbox for Databases had the identical io.ReadAll with no limit, reported four days after my advisory and fixed in June. No advisory, no CVE. - July — the official Go SDK added a request-body cap, shipped as OOM protection in its release notes, with no advisory and no CVE. - 30 July — the Ruby SDK, CVE-2026-67432. A 512 MB POST grew a worker from 44 MB to 1.66 GB. Fixed with a 4 MiB default cap. - 19 August — the PHP SDK, CVE-2026-53965, the client-side version: an unbounded SSE buffer. The Java SDK shipped a matching client-side SSE fix the same day. - 16 September — rmcp, the Rust SDK, CVE-2026-63128. - 11 October — mcp-go, CVE-2026-108859. - 14 October — the official Python SDK, CVE-2026-109527, and the official Java SDK, CVE-2026-108395. Both credited to me among the reporters. - 20 and 27 October — the official TypeScript SDK, CVE-2026-111768 and a follow-up advisory. Nine-plus independent projects. The same root cause. The same fix every single time: a default body-size cap, almost always 4 MiB. In July an independent write-up looked at this and called CVE-2026-39313 the first documented denial-of-service against the MCP HTTP transport and "a new vulnerability category." That is the right framing. This was not a run of unrelated bugs. It was one design gap in how MCP transports read input, replicated across every language the protocol ships in. The two that carry the protocol Most of the class lived in frameworks and bindings. Two of them did not. They were in the reference SDKs that nearly every MCP deployment imports. CVE-2026-109527, the official Python SDK (mcp). In versions before 1.29.1, and in the 2.0 pre-releases through 2.0.1, the Streamable HTTP session manager, the SSE message endpoint, and the OAuth authorization-server routes all buffered complete request bodies with no maximum size. An unauthenticated remote client could send a large declared or streamed body that consumed several times its own size in process memory, and repeat it until the server died. - Advisory (GHSA-fmmv-w9g8-j3gc): github.com/modelcontextprotocol/python-sdk/securi… - Fixed in 1.29.1. CVSS 7.5 (High), CWE-770. - The mcp package serves over 235 million downloads a month on PyPI. CVE-2026-108395, the official Java SDK. Unbounded request-body reads in the mcp-core HTTP server transports, same class, same impact. - Advisory (GHSA-4x8c-5vv7-973f): github.com/modelcontextprotocol/java-sdk/security… - CVSS 7.5 (High), CWE-770. For scale: the official TypeScript SDK pulls around 257 million downloads a month, the Python SDK 235 million. When the flaw sits in the SDK rather than a single server, every server built on that SDK inherits it the moment it exposes an HTTP transport. Who patched, -> Red Hat rated CVE-2026-109527 Important, assessed 44 of its products, and issued three errata: - RHSA-2026:92510 (OpenShift AI 3.4), RHSA-2026:92666 and RHSA-2026:92667 (Satellite 6.19 and 6.18). - Of the 44 products assessed, 35 are affected, 6 not affected, 3 marked will-not-fix. - access.redhat.com Debian tracks the same CVE against python-mcp at severity grave, and at the time of writing the package in unstable is still unfixed. - bugs.debian.org Downstream products started bumping their pins through October: OpenMetadata merged its upgrades, Red Hat's Open Data Hub opened fix PRs, and several hundred automated "bump mcp" pull requests have landed across GitHub since the advisories went live. So the serious operators with security teams are moving. The question is everyone else. The specification still does not require this For all the patching, the root cause has never been closed at the design level. As of early November 2026 the MCP security best-practices document still contains no guidance on request-body size limits. Every SDK solved it independently, with its own default, because the specification never told them to. That is why the same fix had to be rediscovered six, seven, eight times over. The MCP server security guidance that does exist, including the National Security Agency and CISA information sheet on MCP, discusses resource-exhaustion denial of service as a general risk but points implementers at no concrete control for this. The one place that could stop the whole class at the design level still does not mention it. The blind spot: most scanners cannot see the worst two This is current as of 3 November 2026, and it may change the day the databases catch up. Check it yourself. CVE-2026-39313, the npm one, has a full global GitHub advisory. It is in OSV, it is in npm audit, and a scan of a vulnerable project flags it. The two SDK CVEs do not behave the same way. CVE-2026-109527 and CVE-2026-108395 exist only as repository-level advisories on the Python and Java SDK projects. They were never promoted into the global GitHub Advisory Database. The downstream effect is a chain of blindness: - They are absent from the global GitHub advisory mirror, so GitHub Dependabot does not alert on them. - They are absent from OSV, so osv-scanner and everything built on OSV misses them. Querying a vulnerable mcp version returns the other 2026 CVEs but not this one. - They have no record in the PyPA advisory database, so pip-audit finds nothing. - NVD lists both as "Awaiting Analysis" with no version data, so even NVD-driven scanners have no range to match on. The practical result: a server running a vulnerable mcp package can be scanned by pip-audit, osv-scanner, Dependabot, or a popular MCP-specific scanner that wraps pip-audit, and come back clean for the denial-of-service flaw. The patch shipped, the advisory was written, and the machine-readable plumbing that is supposed to warn people never carried it. The enterprise distribution trackers, Red Hat, Debian and SUSE, do carry it, because they ingest from their own CNA and NVD feeds. Red Hat has even published a machine-readable VEX file for it. But the developer-facing supply-chain tools that most teams actually run do not. If you depend on pip-audit or Dependabot to tell you about this, right now they will not. What an attacker gets, and who is at risk You are exposed if you run an MCP server that: - exposes an HTTP-based transport (Streamable HTTP or SSE), as opposed to stdio only, and - is reachable by any client you do not fully trust, which includes the public internet, a shared internal network, or a browser-reachable origin, and - runs a vulnerable version of the framework or SDK below. The attack needs no authentication, no credentials, and no user interaction. One oversized or endless request crashes the process. Repeat it and the service stays down. It is trivially scriptable. There is no data theft here, the impact is pure availability, but for an agent backend that other systems depend on, taking it offline on demand is the whole game. Stdio-only servers and deployments already sitting behind a reverse proxy with its own request-body limit are not exposed in the same way. That proxy limit is also your fastest mitigation while you patch. The fix Upgrade. The fixed versions: - mcp-framework (npm): 0.2.22 or later. - MCP Python SDK (mcp on PyPI): 1.29.1 or later. The fix adds max_request_body_size with a DEFAULT_MAX_REQUEST_BODY_SIZE of 4 MiB in the transport security layer. - MCP Java SDK: the patched mcp-core release. - MCP Go SDK: v1.7.0 or later, which enforces DefaultMaxRequestBodyBytes of 4 MiB. - Ruby SDK (mcp gem): 0.23.0 or later. - PHP SDK, Rust rmcp, mcp-go, TypeScript SDK: upgrade to the latest; all shipped the same body-size cap through the autumn. If you cannot upgrade immediately, put a reverse proxy in front with a client body limit (for example nginx client_max_body_size), and make sure your HTTP transport is not reachable from untrusted networks. Where your SDK exposes a configurable limit, set it explicitly rather than trusting the default, especially if you legitimately handle large payloads. How to find it in your estate - Inventory every MCP server you run and whether it exposes an HTTP transport or stdio only. - For Python, do not trust pip-audit alone for this one today. Check the installed mcp version directly: anything below 1.29.1 is vulnerable. - For npm, npm audit will catch mcp-framework below 0.2.22. - For Java and Go, check the SDK version against the fixed releases above, because the advisories are not yet in the global databases your SCA tooling reads. - Grep your own HTTP handlers for the pattern itself: a body read with no length cap, io.ReadAll(r.Body) in Go, request.body.read with no bound in Ruby, a string += chunk loop in Node, before any size check. If you wrote a custom transport, you may have reproduced the class yourself. The lesson The MCP ecosystem grew faster than its security guidance. A single gap in how transports read input became a denial-of-service class that reached every major SDK in the protocol, and the one control that prevents it is still not written into the specification. The fixes exist now. The specification guidance still does not. And for the two CVEs in the core SDKs, the automated warning system that the rest of us depend on is, as of today, silent. If you run MCP in production, do not wait for a scanner to tell you. Check the versions yourself. References - CVE-2026-39313, mcp-framework: github.com/QuantGeekDev/mcp-framework/security/ad… - CVE-2026-109527, MCP Python SDK: github.com/modelcontextprotocol/python-sdk/securi… - CVE-2026-108395, MCP Java SDK: github.com/modelcontextprotocol/java-sdk/security… - Red Hat, CVE-2026-109527: access.redhat.com - Debian tracker (grave), python-mcp: bugs.debian.org - OWASP AISVS, MCP transport payload-size control citing CVE-2026-39313: github.com/OWASP/AISVS/blob/main/1.0/research/cha… --- Raza Sharif, CyberSecAI Ltd. Reported CVE-2026-39313 and is credited on CVE-2026-109527 and CVE-2026-108395. All vulnerabilities were handled through coordinated disclosure and are fixed in the versions listed above. Contact: contact@agentsign.dev.

  38. Redditu/Velmi1337 · r/ru_gamedev · 1 point

    Сделал ALOL — открытый лаунчер Arizona RP для Linux. Ищу отзывы и тестеров Привет! Я делаю ALOL (Arizona Launcher On Linux) — лаунчер, который помогает установить и запускать Arizona RP на Linux. Хотелось собрать подготовку окружения, выбор сервера и повседневный запуск в одном понятном окне. Сам ALOL написан на Rust и GTK 3, а игра запускается через Wine или Proton с UMU. Что уже есть в версии 0.5.7: • подготовка окружения, шрифтов и Visual C++ при установке; • выбор сервера и отдельный сохранённый никнейм для каждого сервера; • запуск игры прямо из ALOL после загрузки её файлов; • каталог модов, установка своих модов и восстановление заменённых файлов; • настройки графики, журнал ошибок и инструменты восстановления; • проверка обновлений самого ALOL с установкой из окна программы; • русский текст игры без включения русской локали во всей системе. Недавно переработал интерфейс и работу иконок в COSMIC. Есть режимы совместимости для официального лаунчера и клавиатуры. Попробовать: релиз 0.5.7 и пакеты: github.com/Velmi1337/ALOL/releases/tag/v0.5.7 — Arch/CachyOS x86_64 и Fedora 44+ (RPM). Исходники и инструкция: Velmi1337/ALOL · Скриншот главного экрана: github.com/Velmi1337/ALOL/blob/v0.5.7/docs/screen… · Сообщить об ошибке: github.com/Velmi1337/ALOL/issues Для первого запуска нужен установщик с официального сайта Arizona; файлы игры скачиваются через её лаунчер. ALOL — независимый проект. Пароль аккаунта вводится в игре, ALOL его не хранит. Проект разрабатываю с помощью Codex. Сейчас особенно полезны отзывы от тех, кто играет в Arizona на Linux: как проходит установка, удобно ли пользоваться интерфейсом, что хотелось бы добавить? Если встретите ошибку, напишите дистрибутив, DE/WM и используемый Wine/Proton — это поможет её воспроизвести.контент по геймдеву

  39. Redditu/Intelligent_Rub_7922 · r/ClaudeCode

    live-compact: a plugin that writes the compaction summary before you hit the limit, so auto-compact takes ~20 ms I run several Claude Code sessions in parallel on Opus, and auto-compaction kept stopping them for 80-160 seconds each time (the worst one took over 4 minutes). Nothing to do but wait. live-compact moves that work earlier. When the context gets within 40k tokens of the auto-compact threshold, it forks one background request to the same model with the same transcript, and that request only writes the summary. Your turn keeps running. When auto-compaction fires, the plugin swaps in the ready summary plus every message after the point the fork saw, word for word. In my tests that took 8-20 ms. If the summary isn't ready, you rewound the conversation, or you run /compact with instructions, Claude Code compacts the usual way. Install (then restart your sessions): claude plugin install live-compact --marketplace SocialBuzzStudio/live-compact How Claude Code was used: it read the type definitions of the plugin API, wrote small probe mods to check what the hooks allow, then wrote the plugin and its 42 tests. I checked installs on 2.1.300 to 2.1.317 and ran real compactions from a clean profile. What I learned on the way: - $.model.fork sends the main thread's last request plus your prompt, so the fork never sees the answer to that request. Early summaries commented on the half-finished turn, so the prompt now tells it not to. - A session.compact hook can return its own messages and the engine installs them. That is the whole trick. - Standard compaction re-attaches the skills you used earlier (newest first, 5k tokens each, 25k total). A plugin that replaces the messages has to carry them over itself. - If one step adds more than ~40k tokens (several big files read in parallel), the threshold comes before the summary does and you get a standard compaction. Caveats: the hook module API is early access and may change. Tested on Windows only. One extra request per compaction, mostly from the prompt cache. The first message after compaction shows up as a user message, because plugins can't mark a message as a compaction summary. Repo, MIT: SocialBuzzStudio/live-compact If you try it on macOS or Linux, tell me whether it works there.

  40. Can a user retrieve information outside their permissions, including through the lexical search path, caches, or indirect references? Jeevan Srivastava asked this question word for word in a Medium article of 18 October 2026, as one of three dimensions he would assess for a production system, beside retrieval quality and operational performance. He labels his access-control design: "These are proposed production design decisions, not features I'm claiming to have implemented as part of my retrieval fix." > TL;DR > > - Yes, through any read path the permission check does not cover. The question names three: the lexical branch of a hybrid search, filtered differently from the vector branch; a cache that answers before the check runs; and indirect references, such as a fetch by ID or exact name, a pointer to a hidden record, or a scope value supplied by the request or the model. > - One rule addresses all three: the server derives the read scope from the verified caller identity and applies one filter on every path that can return stored content. For the model's part, the Databricks agent memory documentation says of the actor_id that scopes every read: "Never let the model choose it." > - Three probes, run as a user without access, test whether a system holds: a rare word from a restricted document through every search branch; a cache warmed by a user with access; and a direct fetch, a followed pointer and a foreign scope. Each needs a positive control run as a user with access, or an empty result proves nothing. Mnemoverse (the author's company) makes one of the memory APIs quoted below. Can a user retrieve information outside their permissions? Yes, whenever a path that returns stored content skips the check that search runs. A read path is any function, endpoint or query type that can return stored content to a caller: a search, an exact get, a list, an export, an admin surface or a debug endpoint. Heinrich Neb, who works on a memory layer for coding agents, gave the audit rule in a dev.to comment of 27 August 2026: "find every function that can return stored content." | Read path | How it returns what the user may not see | What closes it | Documented by | |---|---|---|---| | Lexical branch of a hybrid search | The full-text query lacks the vector query's filter | One filter below both branches, or passed to each | Srivastava; PostgreSQL; Elasticsearch | | Cache in front of retrieval | A stored answer is served before the check | The caller's scope in the key, or the cache behind the check | RFC 9111, for shared HTTP caches | | Fetch by ID or exact name | A lookup outside search returns the record | An object-level check on every route that takes an ID or a name | OWASP API1:2023; Neb | | Pointer from a visible record | A visible record names a hidden one | The target's visibility checked when the pointer is read | Neb; PostgreSQL | | Scope from the request or the model | A user ID or tag from the path, body or a tool argument is trusted | Scope from the verified identity; supplied values checked against the configured set | Databricks; Supermemory; Mem0; Anis Meziani | | Query language as a search type | Raw queries reach the store | Off unless every user of the deployment is trusted | Cognee | The last four rows are kinds of indirect reference. Srivastava separates the two decisions: "Relevance determines whether information is useful. Authorization determines whether information is allowed to be accessed." How does the lexical search path leak in a hybrid search? The lexical branch is the half of a hybrid search that matches the query's words against a full-text index, such as BM25 or PostgreSQL full-text search, beside the vector half that matches embeddings. Srivastava's rule: "The key decision is that both vector search and lexical search must respect the same access restrictions." The failure: "If vector search filters by tenant or document permissions but PostgreSQL full-text search doesn't, the hybrid retrieval pipeline can introduce a data leak through the lexical branch." On merging the two lists: "Combining rankings must never override authorization boundaries." And at retrieval time: "Apply authorization and tenant filters to every retrieval path." One filter can reach both branches from two places. Below both branches, in the database. With row security enabled on a PostgreSQL table, "all normal access to the table for selecting rows or modifying rows must be allowed by a row security policy", and a table with no policy falls back to "a default-deny policy" (PostgreSQL, Row Security Policies). The same page sets two limits: "the table's owner is typically not subject to row security policies" unless the table is altered with FORCE ROW LEVEL SECURITY, and "Superusers and roles with the BYPASSRLS attribute always bypass the row security system when accessing a table." An application that connects as the owner of an unforced table, as a superuser or as a BYPASSRLS role is not filtered at all. One filter passed to every branch. The filter parameter of the Elasticsearch RRF retriever "Applies the specified boolean query filter to all of the specified sub-retrievers, according to each retriever's specifications." Written once, it cannot drift between two copies. OWASP's LLM08:2025 opens its prevention list with: "Implement fine-grained access controls and permission-aware vector and embedding stores." The OWASP text speaks of vector and embedding stores; a hybrid pipeline has a second index, and the same rule has to reach it. Srivastava adds a condition that holds over time: "metadata can become stale if permissions change and the retrieval index isn't updated accordingly." Does a permission filter keep a restricted user's results complete? Nothing leaks here; the risk runs the other way. The pgvector README: "With approximate indexes, filtering is applied after the index is scanned. If a condition matches 10% of rows, with HNSW and the default hnsw.ef_search of 40, only 4 rows will match on average." Its first suggestion, an index on the filter column, can give exact search in many cases, so the shortfall applies whenever the planner takes the HNSW index instead. What follows is this article's inference for a vector branch on pgvector with an HNSW index, not a measurement. A permission rule is a condition that keeps some share of the rows, so the narrower a user's rights, the fewer rows one scan of the vector index can return, while the full-text branch can still return every permitted match. For hybrid search the README offers fusion: "You can use Reciprocal Rank Fusion or a cross-encoder to combine results." Fusion ranks the lists it receives, so a restricted user's top results draw more on keyword matches than an administrator's do. An evaluation run as an administrator measures only the administrator's ranking: report retrieval quality per permission level. The README's levers: "Starting with 0.8.0, you can enable iterative index scans, which will automatically scan more of the index until enough results are found". On tenants: "For applications with multiple tenants, sharing an approximate index between tenants means vectors from one tenant can affect recall (and speed) for other tenants." And: "For tenant isolation, use list partitioning or separate tables." Can a cache answer with documents the user may not see? Yes, when it answers before the check runs. For shared HTTP caches, RFC 9111, section 3.5, sets the rule: "A shared cache MUST NOT use a cached response to a request with an Authorization header field" to satisfy a later request, unless the response allows shared storage through a Cache-Control directive such as public, s-maxage or must-revalidate. A semantic or answer cache inside an application follows whatever rule the application gives it. Naveen Metta, in an article of 12 October 2026 on RAG before production, states the requirement: > If a user cannot open the document, the model should not be able to quote it. From his team's work: "We found one prompt that could surface HR documents to any employee." He also advises: "Then add a semantic cache in Redis for repeated questions." This article's inference about any cache in front of retrieval, not a description of his system: such a cache answers without running the filter, so the caller's scope has to be part of what it matches on, or it has to sit behind the check. Srivastava would test "whether permissions and deletion requests propagate to the relevant indexed and cached data." The warm, revoke, replay test is covered in the library page on revoked access after an answer was shown, and caches after a delete in Agent Memory Deletion: What Survives a Delete. What counts as an indirect reference, and how does it leak? An indirect reference is any way to reach a record other than a search the filter covers: its ID, its exact name, a pointer from another record, a scope value or a query language. An existence leak is an answer that reveals that a hidden record exists, or something about it, without returning its content. The fetch that skips search. Neb, on his own system: "We had scoping enforced correctly on retrieval, tested, verified", and beside it "a second read path, lookup by exact name rather than similarity, that returned full content to anyone who asked." In short: "Same store, two doors, one guarded." The sign in code: "a read path that doesn't accept the caller identity cannot enforce anything". For APIs, OWASP API1:2023 Broken Object Level Authorization: "Every API endpoint that receives an ID of an object, and performs any action on the object, should implement object-level authorization checks." The pointer. On 25 August 2026, Neb reported a retired record whose banner kept naming its successor after the successor was made private: "Existence leak through the supersession pointer." His rule: "a pointer's validity and a pointer's visibility are both read-time questions, never write-time facts." PostgreSQL warns of a related channel: its referential integrity checks always bypass row security, and "Care must be taken when developing schemas and row level policies to avoid "covert channel" leaks of information through such referential integrity checks." The query language. Cognee pull request #5844, merged into its dev branch on 15 October 2026: "CYPHER and NATURAL_LANGUAGE search types run raw Cypher against the graph database." And: "Any user with read access to a dataset could execute arbitrary queries". The change: "ALLOW_CYPHER_QUERY now defaults to false." For turning it back on: "Only do that when every user of the deployment is trusted." What closes the class: a check at every entry point, and a refusal that neither names nor describes the hidden record, so that a missing record and someone else's record get the same answer. An answer that tells the two apart reveals existence, which is acceptable only where existence is not a secret. Who should set the scope of a memory read: the server, the request or the model? A caller-supplied scope is a value that selects whose data a read covers, such as a user ID, a tenant tag or an actor ID, and that arrives with the request or from the model instead of from the verified identity. The Databricks agent memory documentation (Beta, last updated 26 October 2026) states the rule: "Set actor_id in your application code from trusted caller context: the verified end-user identity for per-user memory, or a trusted team or project key for shared memory. Never let the model choose it." And: "If your strategy depends on an end-user identity, reject requests that don't carry one rather than falling back to a shared actor_id." Three classes of the error, each with a dated fix: A scope chosen by the model. Supermemory pull request #1824, merged on 16 October 2026 into the 2.x release branch of its tools package: "In 2.x, getProfile, documentList, memoryForget and documentDelete accept an optional containerTag from the model and use it unchecked as the request scope." The consequence: "So a model, or a prompt-injected input, can name another tenant's tag and read their profile, list their documents, forget their memories, or delete their documents." The fix: "A model-supplied tag must be one of the tags the developer configured", or the call fails "before any request is sent". The pull request also notes: "Tools 3.x (#1773) already removed model-selected scope." An empty scope read as everything. Mem0 pull request #7581, merged on 12 October 2026, on its hosted clients: "The dangerous one is an empty entity ID. The API treats an empty ID as matching every memory in the project." The case there is the delete calls, delete_all and delete_users, fixed on the client: "This PR blocks that client-side. The server needs its own fix, which is out of scope here." This article did not check whether the server has changed since. A scope taken from the path or the body. Anis Meziani, replying on 14 October 2026 to a comment under his own dev.to article: "Our ADK-native session routes originally checked that a token was valid, not which user it acted for, so the user_id in the path or body was trusted." His fix checks the token's subject against the user_id "on every route that reads sessions or memory, including the live WebSocket". The rule: the scope comes from the verified identity; a request without one is refused, not given a shared scope; an empty value is an error, not everything; a value from the model is checked against the configured set before any request goes out. What changes when several users share one memory store? In a shared store the question moves from the answer to the context. A preprint of 19 October 2026 (arXiv 2610.25707, version 1, not peer-reviewed) opens: "Shared long-term memory lets an LLM agent serving one user inadvertently retrieve another user's credentials, but it is unclear when such exposure leads to actual harm." Its audit used the AppWorld environment and one store for all users' logins: "In AppWorld, a store that mixes 763 past logins from all users retrieves another user's credential for 84.7 percent of required apps, yet agents rarely act on it." Of the misuse its stress test provokes: "Naming the owner before or inside each credential line prevents most of this". Its conclusion: "Agent memory should consistently record whose credential it stores, and evaluations should measure behavior, not only exposure." This article's reading: the boundary is crossed when another user's record reaches the model's context, whether or not the model uses it. Srivastava, from the design side: "The stronger approach is to prevent unauthorized information from entering the context in the first place." Databricks states where the boundary sits: "actor_id separates memories, but it is not an access control. Memory stores are workspace-scoped, so any principal that can reach a store can read and write every entry across all actors." And: "The store, not the actor, is the security boundary. For strict isolation between tenants or users, create a separate memory store per boundary." OWASP's LLM08:2025, for vector databases: "In multi-tenant environments where multiple classes of users or applications share the same vector database, there's a risk of context leakage between users or queries." How do you test that no read path leaks? Each probe has a positive control, because a probe that finds nothing proves nothing until it finds something where it should. They are this article's proposals, not any team's suite. 1. The lexical branch. As the test user, run vector-only, lexical-only and hybrid queries for a rare word, such as a code name, found only in a document the user may not open. Expected: no chunk of it. Control: a user with access gets it. Srivastava proposes this negative test: "Queries from unauthorized users should not expose protected documents, even when those documents are semantically similar to the query." 2. The cache. User A, with access, asks a question whose answer needs the restricted document; user B, without access, asks it and a paraphrase. Expected: B's answer is not built from that document. Control: A's answer is built from that document, and B's answer with the cache off matches B's answer with the cache on. 3. Indirect references. As a user without access, fetch the record by ID and by exact name, follow a pointer to it from a visible record, and send another user's scope and an empty scope. Expected: the same answer as for a record that does not exist. Controls: as a user with access, the same fetch, pointer and scope return the record, so the path is live; a made-up ID on the same path gives the answer to compare against. Three rules for the run: - Take the list of read paths from the code or the tool registry, not from a filtered listing. sam ros, on 15 October 2026, about the CI test of the scope check in his MCP server: "with a list_tools override that filters by the token's scopes, the old test passed while a tickets:read token could still delete." - Rerun the probes after a permission change and after a delete: permission data copied into an index or a cache can go stale. - Inspect what reached the model's context, not only the final answer. A passing first probe says nothing about the second and the third. How do memory APIs document where the boundary is? Two documented positions, in their own words, as read on 2 November 2026. Databricks. The store is the boundary, and application code, not the model, sets the actor ID; both are quoted above. Mnemoverse. The security page states the tenant boundary: "Every API key is bound to a unique organization_id. All database queries are scoped to your organization." Shared rooms (beta) stay apart: "room content never appears in your normal (non-room) searches". The rooms reference covers indirect references: "Knowing a room id grants no access to its contents: access is enforced by the API's membership check on every request, and non-members get 403." And: "Membership is checked before archive state, so a non-member of an archived room still gets the membership 403", so the answer does not reveal whether a room is archived. This is a documented boundary, not a test result; this article tests no product. What this article does not claim No measurement of any product and no figure for how often any system leaks. The numbers above are the pgvector README's illustration and one preprint's audit, each with its conditions. Vendor fixes are quoted from their own pull requests with their merge dates; this article did not check whether a fix has reached a release. The inference about rank fusion is for pgvector with an HNSW index and was not measured. The probes are proposals, not a description of any team's suite. --- Sources and method. Every quotation was read on 2 November 2026 with two instruments, a browser-like request and a second reading of the same text: a reader service with its cache off, and in addition the dev.to API for the dev.to comments, the RSS feed for Jeevan Srivastava's article and the arXiv API for the preprint; for the GitHub pull requests and the pgvector README, which the reader service refuses, the GitHub API and the raw file took its place. A made-up address on each host answered 404 as a control, except Medium, which answers 200 to any address, so there only the article text counts. The text describes those pages as of that date. A longer version, with the common questions and the full list of sources, is in the Mnemoverse documentation library: Can a user retrieve information outside their permissions, including through the lexical search path, caches, or indirect references? Edward Izgorodin · Mnemoverse · 2026-11-02

  41. An AST fingerprint and an embedding model both look for duplicate code. Here's where each one is wrong --- title: "An AST fingerprint and an embedding model both look for duplicate code. Here's where each one is wrong" published: true tags: typescript, ai, refactoring, testing --- We run two duplicate finders over our TypeScript repos. One is static: it parses every function, throws away the names and compares what is left. The other asks a local embedding model what each function means and compares the vectors. They disagree a lot, and most of what we learned came from the cases where they disagree. For this post I rebuilt both as small standalone scripts, with fourteen sample functions that reproduce the cases we kept running into. Everything below is real output from those scripts. The code is here: CosmicDriftGameStudio/duplicate-finder-samples. You need Bun, and for the embedding part Ollama with nomic-embed-text. Why we bother We had the static check for months, but nothing ran it. When we finally ran it over all our repos at the end of October, it reported 118 groups that span files or modules. Typically the same logic had been written a second time by someone who didn't find the first version. At one point we had six copies of an HTML escape function. The static finder: a fingerprint per function The script uses the TypeScript compiler to find every function, method and arrow function with a body of at least 120 characters. Shorter bodies match each other all the time and are never worth extracting. Each body is then normalized: every identifier becomes _, every string and number becomes #, whitespace goes away. s = s.replace(/"[^"]*"/g, "#"); s = s.replace(/'[^']*'/g, "#"); s = s.replace(/`[^`]*`/g, "#"); s = s.replace(/\b\d+(\.\d+)?n?\b/g, "#"); s = s.replace(/\b(true|false|null|undefined)\b/g, "#"); s = s.replace(/\b[a-zA-Z_$][\w$]*\b/g, (m) => (KEYWORDS.has(m) ? m : "_")); The normalized body plus the parameter count is the fingerprint. Two functions with the same fingerprint are an exact group. An optional second pass compares the rest pairwise: 70% edit distance on the normalized body, 30% overlap of the identifiers. $ bun ast-duplicates.ts samples --fuzzy 0.8 exact 1.00 accounts/disable-account.ts:disableAccount + accounts/enable-account.ts:enableAccount exact 1.00 forms/is-field-row.ts:isFieldRow + scheduling/is-instant-like.ts:isInstantLike similar 0.87 feed/escape-xml.ts:escapeXml + mail/escape-html.ts:escapeHtml 3 group(s) What it's good at: copies that only differ in names and values enableAccount and disableAccount are the same handler with true swapped for false and one audit string changed: export async function disableAccount(accountId: string, actorId: string) { const account = await db.accounts.find(accountId); if (!account) throw new Error(`account ${accountId} not found`); if (account.enabled === false) return account; const updated = await db.accounts.update(accountId, { enabled: false }); await db.audit.insert({ accountId, actorId, action: "account.disabled" }); return updated; } After normalization the two bodies are identical, so the fingerprint matches with a score of 1.0. There's no threshold and nothing to tune, and the same input always gives the same answer. That's why this is the check that runs automatically for us. We had this exact pair in our own code and replaced both with one factory that takes the flag. Where it's wrong: same shape, different meaning The second exact group is a false positive: export function isInstantLike(value: unknown): value is InstantLike { return ( typeof value === "object" && value !== null && "epochMilliseconds" in value && typeof value.epochMilliseconds === "number" && "timeZone" in value && typeof value.timeZone === "string" ); } isFieldRow in the forms code checks fieldName and fieldType in the same pattern. Every type guard over an object with two fields looks like this. Once names and strings are gone, nothing is left that tells them apart, and merging them would make no sense. We hit the same thing in our own code: a type guard for date values and one for form field rows, flagged as one group. Where it misses: same logic, different shape export function orderTotal(lines: OrderLine[]): number { let total = 0; for (const line of lines) { const gross = line.unitPrice * line.quantity; const discount = line.discountPercent ? (gross * line.discountPercent) / 100 : 0; total += gross - discount; } return Math.round(total * 100) / 100; } export const invoiceTotal = (items: InvoiceItem[]): number => { const sum = items.reduce( (acc, item) => acc + item.price * item.count * (1 - (item.rebate ?? 0) / 100), 0, ); return Math.round(sum * 100) / 100; }; Both compute the same total. One uses a loop, the other reduce, and the static finder doesn't see a group even in the fuzzy pass. A fingerprint only catches copies, and a second person solving the same problem rarely writes a copy. A gap I found while writing this escapeHtml and escapeXml should be an exact group: the only difference is &#39; against &apos;. They only show up in the fuzzy pass, at 0.87. Here is what the normalizer makes of them: escapeXml {return _._(/&/_,#)._(/</_,#)._(/>/_,#)._(/#&_;#&_;");} escapeHtml {return _._(/&/_,#)._(/</_,#)._(/>/_,#)._(/#&_;#&##;");} The " inside the regex literal /"/g pairs with the quote of the next string, so the string regexes cut across the code. The 39 in &#39; then ends up outside a string and becomes #. Our production check had the same normalizer and the same gap. While writing this post we switched it to the tokens of the already parsed syntax tree: string, template and JSX text tokens become #, regex literals stay as they are, comments are gone. The first run with the new normalizer found 12 more groups across files, real duplicates that had been hidden all along, most of them because the bodies differed only in their comments. The sample here keeps the regex version, because it's shorter to read and it shows the gap. The embedding finder: what does the function mean? The second script sends each function body to nomic-embed-text through a local Ollama, with comments stripped and whitespace collapsed, and compares every pair by cosine similarity. body: JSON.stringify({ model: MODEL, input: `search_document: ${text}` }), The search_document: prefix is what the model expects for documents. $ bun embedding-duplicates.ts samples --threshold 0.8 0.9881 accounts/disable-account.ts:disableAccount + accounts/enable-account.ts:enableAccount 0.9312 feed/escape-xml.ts:escapeXml + mail/escape-html.ts:escapeHtml 0.9304 reports/correlation.ts:correlation + stats/correlation.ts:pearsonCorrelation 0.8261 invoices/invoice-total.ts:invoiceTotal + orders/order-total.ts:orderTotal 0.8084 cache/redis-client.ts:createCacheClient + db/client.ts:createDbConnection 5 pair(s) at or above 0.8 What it's good at: the pair the fingerprint missed orderTotal and invoiceTotal are in the list, at 0.83. The model doesn't care about loop against reduce or discountPercent against rebate. The two type guards that fooled the fingerprint score 0.78, just under the cut. That margin is the catch. With --threshold 0 the scale gets visible: slugify and parseDuration, which have nothing in common, still score 0.67. The real invoice pair is 0.05 above the type guards. At the script's default of 0.9 it drops out, and only the three pairs at 0.93 and above remain. The ranking is mostly sensible, but no single threshold separates real from false, and the scores depend on the model and its version. Where it's wrong: similar words, different code createDbConnection and createCacheClient sit at 0.81, almost as high as the real duplicate. Both read a URL from the environment, throw when it's missing, parse a number and build a client. One returns a Postgres pool with a listener connection, the other a Redis client with an error handler. There is nothing to extract. We saw this at a larger scale. Three database connection factories in our code scored 0.9961 and 1.0 against each other, and they return different shapes on different layers. Seven queries on the same JSON column clustered together because they share identifiers like the column and table name, not logic. Where it's dangerous: almost the same pearsonCorrelation and correlation score 0.93, higher than the invoice pair. They are the same formula, with one difference: pearsonCorrelation returns 0 when a series has no variance, correlation returns NaN. An embedding can't see a missing early return. Merge them, and one caller changes behavior. We had this one for real. The correlation helper in a test suite stayed as it was, because the caller's tolerance check depends on getting NaN. Another pair stayed because one of them sorts its input and the other doesn't, and a later step relies on the order. How we put the two together For each pair, the question is which finders saw it. combine.ts runs both and sorts the pairs by that: $ bun combine.ts samples both ast 1.00 emb 0.99 accounts/disable-account.ts:disableAccount + accounts/enable-account.ts:enableAccount -> extract one helper both ast 0.87 emb 0.93 feed/escape-xml.ts:escapeXml + mail/escape-html.ts:escapeHtml -> extract one helper ast-only ast 1.00 emb - forms/is-field-row.ts:isFieldRow + scheduling/is-instant-like.ts:isInstantLike -> same shape: check that both mean the same thing embedding-only ast - emb 0.93 reports/correlation.ts:correlation + stats/correlation.ts:pearsonCorrelation -> same intent: run both on the same inputs before merging embedding-only ast - emb 0.83 invoices/invoice-total.ts:invoiceTotal + orders/order-total.ts:orderTotal -> same intent: run both on the same inputs before merging embedding-only ast - emb 0.81 cache/redis-client.ts:createCacheClient + db/client.ts:createDbConnection -> same intent: run both on the same inputs before merging A pair both finders report is the easy case. A pair only the static finder reports has the same shape, and someone has to check whether both functions are for the same thing. A pair only the embedding reports looks like the same idea, and someone has to check that the two functions behave the same. For that last group, check-equivalence.ts feeds both functions the same inputs: $ bun check-equivalence.ts correlation [1,2,3,4] [2,4,6,8]: stats 1, reports 1 correlation [1,2,3,4] [4,3,2,1]: stats -1, reports -1 correlation [5,5,5,5] [1,2,3,4]: stats 0, reports NaN total [{"price":19.99,"count":3}]: orders 59.97, invoices 59.97 total [{"price":19.99,"count":3,"rebate":15},{"price":4.5,"count":3}]: orders 64.47, invoices 64.47 total []: orders 0, invoices 0 The totals agree on these three inputs, which makes the merge worth trying. The correlation differs on the third input. The connection factories don't get this far, because they don't even return the same type. In our repos the combining is less automatic than this script. Both finders read one shared ignore list for deliberate parallels, such as plugins that implement the same interface. For the static check, a function can also opt out with a // guard:dup-ok comment. The static check runs after every review pass over merged pull requests and compares against a baseline: known groups pass, a new group becomes a finding in our review queue, and the baseline only ever goes down. Over three cleanup steps it went from 49 to 22, 3 and finally 0. The sample has a simpler version of the same idea behind --baseline and exits with 1 on a new group, so you can also put it in CI. The embedding finder doesn't run automatically, because it needs Ollama. We run it by hand before a cleanup round and judge the pairs in bands. In one round, the band between 0.90 and 0.95 had 77 clusters across repos: 9 real duplicates, 23 partly, 13 already on our list, and 32 that weren't duplicates at all. A pair that both finders reported became one checklist item, which is what combine.ts does automatically here. What we haven't solved The embedding band between about 0.8 and 0.95 mixes real duplicates with false positives, and the sample shows it on a small scale: the real invoice pair at 0.83 sits right next to the connection factories at 0.81. A threshold can't separate them. A few things we're considering: - Embed the signature and return type along with the body, so a function returning a Redis client and one returning a pool drift apart. - Have a language model judge the pairs in the band instead of a person. That costs money for every pair, and we'd need to measure how often it's wrong. - Make the equivalence check automatic: generate inputs from the parameter types and compare the outputs, instead of writing check-equivalence.ts by hand for each pair. If you run duplicate detection on a real codebase: what did you add to get the false positives down? And has anyone automated the "do these two actually behave the same" step in a way you'd trust before a merge?

  42. 我以前让 AI 做设计, 都是提示词→出图→完事, 结果每张都像模板。 换个顺序就好很多: 先把问题和用户讲清, 再谈结构, 最后才画界面。 DesignXI 就是按这个来的: 免费开源,MIT 协议, 27 个阶段,每阶段要你点头才往下走。 Claude Code 装法: git clone 后拷到 skills 就能用。 ahmeduxui/DesignXI

  43. Location: Lahore, Pakistan Remote: Yes, worldwide Willing to relocate: Open to discussion Technologies: TypeScript, JavaScript, React, Next.js, Node.js, NestJS, Python, Go, PostgreSQL, Docker, Kubernetes, AWS, LLMs, AI agents GitHub: github.com/hamzarehmandeveloper Email: devhamza.r@gmail.com LinkedIn: linkedin.com I'm a software engineer with 4 years of experience, mostly working with startups in the US and UK. I've worked across the stack, from building frontend applications to backend systems, APIs, infrastructure, and deploying products from scratch. Outside of work, I built claude-account(hamzarehmandeveloper/claude-account), an open-source project that has picked up traction in the developer community. It's been interesting to see people use it, fork it, and build on top of it. I enjoy building things that solve actual problems, and I tend to spend a lot of my free time doing exactly that. Happy to connect with founders and engineering teams working on interesting products.

  44. Redditu/cgpixel23 · r/sdforall

    ComfyUI Tutorial: PIKA H3 + MiniMax H3 Singularity V2 + NVIDIA Regenerative 2K Upscaling KIJAI LORA (With 6GB of VRAM) Hello everyone today I am showing you a new ComfyUI workflow that combines MiniMax H3 Singularity V2 combined with the Pika H3 LoRA to generate videos at approximately 0.6 MP with only 6 steps. Then, using the Ultimate MiniMax H3 Upscale node and Kijai's Regenerative 2K LoRA at a lower weight, the video is progressively enhanced with additional LoRAs to improve details, textures, and overall quality. My test results: - Initial generation: 0.6MP - Sampling steps: 6 - Total generation + upscaling time: ~1 hour - Final resolution: Full HD (1920×1080) The interesting part is that instead of generating directly at high resolution, we generate at a much lower resolution and let the regenerative upscaling process recover and enhance the details. I've included all the required LoRA and custom node links with the workflow. Let me know what you think, especially if you've tested this new regenerative upscaling approach! Required LoRAs and Models 1. Open Regenerate 2K LoRA (Kijai): huggingface.co 2. LMS LoRA: huggingface.co 3. Pika H3 LoRA: huggingface.co 4. Sharp Curve LoRA: huggingface.co 5. Latent H3 Upscaling Model: huggingface.co Custom Nodes to Install 1. Ultimate MiniMax H3 Upscale: cbbaudio-2025/ComfyUI-MH3-UltimateUpscale Workflow Link drive.google.com civitai.com

Older posts →