{"slug": "openai-shipped-dots-on-tuesday-by-wednesday-night-my-terminal-had-its-own-100", "title": "OpenAI shipped Dots on Tuesday. By Wednesday night my terminal had its own, running 100% locally", "summary": "A developer built Sparks, a local always-on agent feature for the open-source Flash CLI, roughly 24 hours and 17 commits after OpenAI launched its Dots background agents. Sparks run on user-supplied models via Ollama, persist as plain JSON files in ~/.flash/sparks, and stay alive after the terminal closes through systemd, launchd, or Windows Scheduled Tasks. The developer reports a concurrency bug in which the background keeper, the CLI, and the web UI can all attempt to run the same scheduled shift, and says Sparks should ship in version 0.6.12.", "body_md": "On Tuesday, OpenAI launched **Dots**: little bubbly agents with a name and an avatar that keep working in the background and come back when they have something for you.\n\nI read the announcement and had one thought:\n\nWhy does my always-on agent have to live on someone else's computer?\n\nSo I opened my editor. About 24 hours and **17 commits** later, [Flash](https://github.com/Natuworkguy/Flash), my open-source local agent CLI, has its own version. They're called **Sparks**.\n\nThey run on **your** models through Ollama, on **your** machine, and they keep working **after you close Flash**.\n\nThis is the story of day one: what I built, what broke, and the one bug that froze everything.\n\nA sub-agent does one job and disappears. **A spark keeps a job.**\n\nEvery spark gets:\n\n`Scout` becomes `@scout-spark`.` qwen3:8b`, `llama3.1`, whatever you've pulled. Each spark can run a different one.\nYou can make one with a command, or just ask for it:\n\n```\n> make a spark that checks my repo every morning and tells me which new\n  issues look like bugs. never comment on anything.\n```\n\nFlash calls its `make_spark` tool and asks you first. After that, the spark lives in `~/.flash/sparks` as one plain JSON file. There's no database and no account.\n\nEvery shift, it reads its goal, the notes it left itself last time, its last report, and every lesson you've taught it. It works with real tools. Then it files a report, or a quiet one if nothing is new, so you only hear from it when something happened.\n\n```\n● Scout has news · /sparks scout\n```\n\nIn the web UI, each spark is a little bubble with a face, and I went *way* too far with this:\n\nIt isn't only decoration. Glance at the sidebar and you know which spark is working, which is stuck, and which has news, without reading a word.\n\nOpen a spark and press **Chat**, and it answers *as itself*, from its own goal, notes and reports. It knows its current status: whether it's mid-shift, waiting on you, or paused.\n\nTell it to do its job differently and it **keeps that as a lesson** that every later shift reads. Tell it a new goal and it changes it.\n\nAnd my favorite feature, added this afternoon:\n\n```\nyou:   Actually, can you check whether the login page still loads?\nscout: On it. I've taken that on, and a shift is starting now.\n       I'll report back here.\n```\n\nThe spark calls a `take_on` tool, a shift starts **immediately**, it does *your* job first, and the report lands **back in the chat you asked in**.\n\nMid-chat with Flash about something else? Type `@scout` and the spark joins the conversation. It sees the last dozen messages as a transcript, answers under its own name, and Flash sees afterwards that Scout was called and what it said. The next message without a mention picks up right where the spark left off.\n\nIt feels like having coworkers in a group chat. Except the coworkers are on your GPU.\n\nThis was the part I cared about most. An always-on agent that dies when you close the terminal isn't always on.\n\n`/sparks always on` installs a tiny background keeper using whatever your OS already has:\n\n| OS | How it stays alive | \n|---|---|\n| Linux | a `systemd --user` service (with an autostart fallback) | \n| macOS | a `launchd` agent | \n| Windows | a Scheduled Task | \n\nNow the problem: what happens when the keeper is running **and** you open Flash **and** you have the web UI up in another terminal? Three processes all think it's their job to run Scout's 9am shift.\n\nI'll post updates as they come out and Sparks should be shipping in 0.6.12", "url": "https://wpnews.pro/news/openai-shipped-dots-on-tuesday-by-wednesday-night-my-terminal-had-its-own-100", "canonical_source": "https://dev.to/natuworkguy/openai-shipped-dots-on-tuesday-by-wednesday-night-my-terminal-had-its-own-running-100-locally-1h0d", "published_at": "2026-09-30 22:26:03+00:00", "updated_at": "2026-09-30 22:46:42.398552+00:00", "lang": "en", "topics": ["ai-agents", "ai-tools", "developer-tools", "large-language-models"], "entities": ["OpenAI", "Flash", "Sparks", "Ollama", "Dots", "qwen3:8b", "llama3.1"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/openai-shipped-dots-on-tuesday-by-wednesday-night-my-terminal-had-its-own-100", "markdown": "https://wpnews.pro/news/openai-shipped-dots-on-tuesday-by-wednesday-night-my-terminal-had-its-own-100.md", "text": "https://wpnews.pro/news/openai-shipped-dots-on-tuesday-by-wednesday-night-my-terminal-had-its-own-100.txt", "jsonld": "https://wpnews.pro/news/openai-shipped-dots-on-tuesday-by-wednesday-night-my-terminal-had-its-own-100.jsonld"}}