fetch robustness + brand assets
- - MemoryGraph + CommandPalette: check response.ok before parsing JSON
- so 404/500 from sidecar fails fast instead of silently consuming
- malformed bodies as `{}` and showing empty graphs.
- - website/public/logo-lockup.{png,svg}: horizontal lockup of the
- chevron tile + "AgentiqFlow.ai" wordmark for use in Stripe Checkout
- branding and any external embed.
- - Version bump 0.2.59 -> 0.2.60. Ships the heartbeat-nudge re-enable,
- voice-convo 45s idle auto-off, MCP page engine-tools surface,
- skills.sh sitemap crawl fix, Director robot icon, Stripe per-key
- pricing + savings + automatic_tax, Windows ARM64 build pipeline fix.
v0.2.59 automated release
v0.2.58 automated release
v0.2.57 automated release
v0.2.56 automated release
v0.2.55 automated release
v0.2.54 automated release
v0.2.53 automated release
v0.2.52 automated release
v0.2.51 automated release
v0.2.50 automated release
v0.2.49 automated release
50 agents (10 money makers + 15 specialists), copy + OG updated
v0.2.47 automated release
v0.2.46 automated release
lock fix; CI for v0.2.44 missed package-lock update
real bidirectional channels (Slack/Twilio/SMTP+IMAP/Google Voice/Generic Webhook), workspace members endpoint, server backup, preferences, metrics+crashlog, agent abort, integration stubs implemented (DeepL/MaxMind/Couchbase/Fauna/EdgeDB/Redis Vector); website: og-image, 404, /changelog, /docs/quickstart, /docs/install, sitemap, robots
30+ messaging integrations on website + pricing
iMessage to top, Google Voice added
Google Voice channel
30+ messaging integrations on Channels page
more bulk tiers 35/40/50
AccountCard + dashboard swap
Login signup fallback to login
bootstrap accepts email+password
Login signup mode
auth gate + bigger convo icon
ConvoIcon fills viewBox
bigger chat input icons
ConvoIcon size match
platform brand: gradient mark + white text
blue brand mark + mic/speaker convo icon + new favicon
logo + convo icon + manual + 50 keys
brighter Live Activity text + MessagesSquare convo icon
remove dev/staging/prod env switcher
fix CI installer builds (Win ESM + Linux ARM64)
v0.2.23 automated release
v0.2.22 mobile UI sweep
- Layout
- - Hamburger top bar on small screens (md:hidden) with brand + version.
- - Sidebar becomes a slide-out drawer (translate-x), z-50, with backdrop.
- - Auto-closes on route change.
- Chat
- - Container flex-col on mobile, flex-row on lg+.
- - Horizontal padding shrinks: px-3 sm: px-6 lg: px-8.
- - ActivityPanel collapses to full-width with max-h-[40vh] on small
- so it doesn't eat the chat area.
- Workflows
- - Node palette + inspector hidden on small (md:flex). Canvas takes
- full width on phones — pinch-zoom + pan still work via react-flow.
- - Top toolbar wraps (flex-wrap) so concurrency / rate / on-error /
- history / save / run all stay reachable on narrow screens.
v0.2.21 phase 3 — all 14 remaining features
- This release closes out all 14 items left from the gap-analysis list.
- Some are full implementations, some are practical MVPs that need an
- external service (Whisper via Groq/OpenAI rather than bundled binary,
- Avatar via D-ID rather than offline). Everything is wired and reachable.
- — Server modules added —
- oauth-broker.mjs Generic OAuth 2.0 authorization-code + token
- refresh broker. Built-ins for Google / GitHub /
- Slack / Notion / Microsoft. Tokens stored in
- ~/.agentiqflow/oauth-tokens.json (mode 0600).
- cloud-sync.mjs Push/pull a snapshot of config + license +
- workflows + memory + variables to S3-compatible
- (SigV4) or WebDAV bucket. ts-based conflict
- resolution; force=true overrides.
- eval-harness.mjs Run goldens against any agent via chat/sync.
- Match modes: contains / equals / regex /
- minLength / judge. Results stream to
- ~/.agentiqflow/evals/results.jsonl.
- auth-rbac.mjs scrypt password hashing + 7-day session tokens
- + viewer/editor/admin role ladder. Single-user
- mode is the default; bootstrap() flips it on.
- stt-whisper.mjs Whisper STT via Groq (free, fast) or OpenAI.
- Bundled-binary backend tracked as future work.
- avatar.mjs D-ID Talks integration — text → talking-head
- mp4 with stock or custom presenter image.
- templates-remote.mjs Fetches a curated workflow template registry
- (default agentiqflow.ai/templates/registry.json,
- override via templates-registry.json). 1h cache
- + stale-fallback.
- — Workflow debugger —
- workflows.mjs gains runSingleNode(wf, id, pinned) and replayFromNode
- (wf, fromId, input). Wired at:
- POST /workflows/:id/test-node/:nodeId
- POST /workflows/:id/replay-from/:nodeId
- Set node.data.__pinnedInput in the editor to seed test runs.
- — Frontend —
- src/lib/environments.ts dev / staging / prod scopes; vault entries
- with __env="prod,staging" only contribute
- getKey() in matching scopes. Active env shown
- and switchable in the brand block (red for
- prod, amber for staging, emerald for dev).
- src/lib/i18n.ts + bundles English + Spanish; locale lookup uses
- localStorage + navigator.language fallback.
- src/styles/a11y.css Visible focus rings, prefers-reduced-motion
- handling, contrast bump for placeholders.
- Skip-to-main link on every page.
- Layout.tsx grid-cols-1 on mobile, restores sidebar on md+
- breakpoint. Aria-labelled nav, main element
- with id=main-content for the skip link.
- — SDKs + CLI —
- sdk/typescript/agentiqflow.ts zero-dep, single-file SDK for Node /
- Deno / browser.
- sdk/python/agentiqflow.py stdlib-only (no requests dependency),
- Python 3.10+.
- scripts/agx Node CLI: agx workflows list, agx chat,
- agx eval run, agx tts speak, agx audit,
- agx cloud-sync push/pull, agx oauth
- providers, agx whoami.
- Genuinely deferred (each its own engineering session):
- - Bundled Whisper binary (~150 MB cross-arch, model download flow)
- - Native mobile app (the responsive sweep here keeps the web UI
- usable on phones; a real mobile-first redesign of the workflow
- editor + chat is its own design effort).
- - Templates marketplace community backend (rating, submission,
- moderation) — only the client-side fetcher ships in this release.
v0.2.20 bundle full 511-kind manifest at build time
- Test machines on older builds saw only 12 kinds because the
- /__agentiqflow/workflows/node-kinds endpoint pre-v0.2.17 had a
- cold-boot race that returned only the 12 builtin kinds. Even on fixed
- servers, the UI capped the "All node kinds" list at 80 entries.
- Permanent fix:
- - scripts/build-node-kinds-manifest.mjs: imports server/workflows.mjs,
- awaits loadNodePacks(), dumps every registered kind to
- src/data/nodeKinds.ts. Runs as the first step of `npm run build`.
- - Workflows.tsx: imports NODE_KINDS from the bundled manifest as the
- primary source. Server fetch still runs and merges in any new kinds,
- but a smaller server response NEVER replaces the bundled list. Result:
- every machine, every server build, every cold boot → full 511-kind
- catalog renders immediately.
- - Removed the .slice(0, 80) cap on the kinds list. Internal scroll
- handles the full set fine.
v0.2.19 phase 2 — 8 features
- Eight orthogonal upgrades, every one fully shipping in this release:
- 1. action.subworkflow node (workflow-nodes/subworkflow.mjs)
- - Calls workflow B from inside workflow A. waitForFinish toggle for
- fire-and-forget vs blocking. Cycle detection via callPath chain;
- refuses if target id already in stack. Max depth 8.
- 2. Image generation + vision pack (workflow-nodes/image_gen.mjs)
- - integration.openai.image.generate (DALL·E 3 / gpt-image-1)
- - integration.openai.vision (GPT-4o vision over image_url)
- - integration.replicate.run (FLUX schnell default)
- - integration.stability.image.generate (SD3.5)
- All read keys from vault → secrets.env. Pure HTTP, no SDKs.
- 3. Per-workflow concurrency + rate limit (workflows.mjs)
- - Optional `concurrency` field caps in-flight runs. _checkLimits guard
- throws when exceeded. Sub-workflow + error-workflow invocations
- skip the cap to avoid composition deadlocks.
- - Optional `rateLimit` (per `rateLimitWindowMs`, default 60s)
- rejects with retry-in-N-seconds error.
- - Editor toolbar exposes both as number inputs.
- 4. Webhook HMAC auth UI (workflow-manifests.mjs)
- - Surface auth = none|basic|header|hmac in trigger.webhook fields.
- - basicUser/basicPass, headerName/headerValue, hmacHeader/hmacSecret
- /hmacAlgo/hmacPrefix exposed in the inspector. Server-side
- verification (webhook-auth.mjs) was already shipped — UI was missing.
- 5. Export workflow as PNG / SVG (lib/workflowImportExport.ts)
- - Pure-DOM SVG generator: rounded-rect nodes coloured by category
- prefix, smooth Bezier edges, arrowhead markers, dark canvas.
- - PNG export rasterizes the SVG via canvas at 2× for retina.
- - Editor "Export" button now prompts json|svg|png.
- 6. Cost router (lib/costRouter.ts)
- - Hand-curated price table for 17 frontier→local models, tier 1–5.
- - pickModel({ minQuality, maxQuality, exclude, isAvailable }) returns
- the cheapest candidate above the bar that the user actually has
- credentials for. rankCheapest() for top-N listings.
- 7. Long-term memory embeddings (memory-embeddings.mjs)
- - text-embedding-3-small via OpenAI when key present; deterministic
- hashed-token fallback otherwise (degrades gracefully).
- - Persisted to ~/.agentiqflow/memory/embeddings.json keyed by
- "<agentId>/<topic>". Cosine-sim search, model-isolated buckets.
- - GET /__agentiqflow/memory/search-semantic, POST /memory/reindex,
- GET /memory/index-stats.
- 8. Real-time exec visualization (Workflows.tsx)
- - Run-now polls /runs/:id every 600 ms until status leaves running.
- - liveNodeStates drives ring-2 ring-blue-400 animate-pulse on running,
- emerald on succeeded, red on failed — instant visual feedback on
- where the run is in the graph.
v0.2.18 phase 1 — encrypted vault + audit + versioning + error workflow + cmd-K
- Five orthogonal upgrades, each behind its own page or trigger:
- 1. Encrypted vault (lib/vault.ts)
- - WebCrypto AES-GCM with PBKDF2-SHA-256 (200k iters) key derivation.
- - Two storage modes: plaintext (legacy default) + v2 encrypted blob.
- - Setup / change / remove passphrase + lock/unlock UI on Vault page.
- - Locked vault returns no entries; UI prompts before any provider key
- is read.
- 2. Audit page (pages/Audit.tsx + nav + route)
- - Tail of /__agentiqflow/audit with filter, action breakdown pills,
- and 5s auto-refresh. Server already wrote to ~/.agentiqflow/audit.log;
- UI was missing.
- 3. Workflow versioning UI (Workflows.tsx + History modal + new revert
- endpoint /__agentiqflow/workflows/:id/git/revert/:sha)
- - History button on the editor toolbar shows commit list, restore
- button reverts the workflow to that revision and re-commits.
- - Revert is audit-logged as workflow.revert.
- 4. Error workflow pattern (workflows.mjs + Workflows.tsx select)
- - New optional `errorWorkflowId` on each workflow. Engine fires the
- selected workflow with { error, runId, workflowId, ... } when a run
- fails. Loop guard: skips when errorWorkflowId === wf.id or when the
- run was itself triggered via error workflow.
- - Editor toolbar exposes the picker next to Active.
- 5. Global cmd-K palette (components/CommandPalette.tsx, mounted in Layout)
- - Indexes nav routes, SWARM agents, /workflows list, /memory/notes.
- - Keyboard-first (↑↓, Enter, Esc), token-AND filter, deep links.
v0.2.17 fix node-kinds endpoint cold-boot race
- GET /__agentiqflow/workflows/node-kinds was responding before the lazy
- node-pack loader (`loadNodePacks` fired via setImmediate at module
- import) had finished, so only the 12 hard-coded builtin kinds came
- back. Test machines + cold-boot users saw 12 instead of 496.
- Fix: await workflows.loadNodePacks() inside the handler. Idempotent —
- loader caches its in-flight promise and skips re-running once done.
- Pack count after load: 496 kinds (454 integration.*, 14 transform.*,
- 5 control.*, 4 trigger.*, 3 action.*, 3 vector.*, 3 memory.*, 2 each
- for llm/rag/text/chain, 1 each for agent/meta).
v0.2.16 free neural voice (Edge TTS) + voice picker
- Adds Microsoft Edge TTS as the default voice provider — Azure neural
- quality (Aria, Jenny, Ava, Emma…) with no API key, no rate limits, no
- ongoing cost. OpenAI TTS stays as the paid premium option, browser
- SpeechSynthesis as the offline fallback.
- - server/tts-edge.mjs: WebSocket client to MS Edge "Read aloud" endpoint
- with the Sec-MS-GEC auth token (rolling 5-minute window) and pinned
- Edge 143 UA. Returns mp3 buffer.
- - server: POST /__agentiqflow/tts (mp3), GET /__agentiqflow/tts/voices
- - chat: provider order Edge → OpenAI → browser. Audio playback via
- HTMLAudioElement; stopSpeak() unifies cancel across both paths so the
- mic doesn't pick up TTS through speakers in convo mode.
- - settings: VoiceCard — provider dropdown, per-provider voice picker,
- Test button. Mounted on left column under AgentiqFlow.
v0.2.15 6-platform installers
v0.2.14 add Mac Intel + Linux ARM64 + Windows ARM64 + Pi installer scripts
- Build script changes only — workflow file expansion lands in a follow-up
- push that needs the GitHub `workflow` OAuth scope.
- - build-appimage.sh: ARCH env (x86_64|aarch64) drives appimagetool URL +
- output filename
- - build-dmg.sh / build-pkg.sh / build-uninstall-pkg.sh: MAC_ARCH env
- suffixes filenames so Intel + ARM PKGs/DMGs don't collide on Release
- - build-installer.ps1: WIN_ARCH env (x64|arm64) suffixes installer
- - raspberry-pi/install.sh: NodeSource Node 20, downloads universal
- tarball, installs to ~/.local/share/agentiqflow, registers systemd
- --user unit. Requires 64-bit Pi OS.
- - raspberry-pi/README.md: install + manage instructions
v0.2.13 fix CI installer build
- Installer CI for v0.2.12 failed: src/data/workflowTemplates.ts was
- git-ignored (root data/ rule swallowed src/data/), so CI tsc failed
- with implicit-any cascading from the unresolved import. Local build
- passed because the file existed on disk.
- - .gitignore: add !src/data/ exception
- - track src/data/workflowTemplates.ts (was ignored)
- - settings: AgentiqFlow card buttons restyled to match Webull/TradingView
v0.2.12 chat voice + settings layout + integrations
- - chat: voice convo mode (continuous STT + soft female TTS), push-to-talk
- mic, status pill (listening/speaking/thinking), markdown stripped before
- TTS, mic stops during TTS to prevent feedback loop
- - chat: clearChat now wipes server-side history (sessions.reset) +
- localStorage cache so refresh doesn't repopulate
- - chat: Director heartbeat moved into header as compact pill, right side
- - layout: ActivityPanel restructured — full-height right column, tools
- tail given fixed min/max height
- - nav: brand .ai now white, version moved below subtitle in brand-blue
- - settings: 2-column grid, TradingView card with install detect +
- download links, Webull download/open links added, Brand panel removed,
- AgentiqFlow header gets .ai suffix
- - server: /__agentiqflow/ag/chat/clear, /__agentiqflow/admin/tradingview-status
- - scripts: remove-jump-desktop.sh — full uninstall of Jump Desktop +
- HAL audio drivers
v0.3.3: skills.sh full ~29k catalog via sitemap
- The previous skills.sh source was hardcoded to 3 upstream repos and
- showed ~50 skills. skills.sh actually aggregates ~29k skills across
- ~3.8k GitHub repos, listed in their public sitemap.xml.
- - Sidecar /__agentix/skills-sh/catalog parses skills.sh/sitemap.xml,
- extracting every <owner>/<repo>/<slug> URL into a flat list. Disk-
- cached to ~/.agentix/skills-sh-catalog.json with a 6h TTL.
- - Sidecar /__agentix/skills-sh/skill?owner=&repo=&slug= walks the
- GitHub tree of the upstream repo (in-memory cached 24h, falls back
- from main to master), finds the directory whose leaf name matches
- the slug AND contains a SKILL.md, fetches SKILL.md + README.md, and
- returns the resolved path. Layout-agnostic — works for repos that
- put skills under skills/<slug>, agents/<slug>, or top-level.
- - Frontend loadSkillsShIndex hits the catalog endpoint and renders
- every entry in the same firehose-style grid the other sources use.
- fetchSkill routes skills-sh refs through the sidecar resolver so
- the browser never has to guess the SKILL.md path.
- - Removed the hardcoded 3-repo SKILLS_SH_REPOS table.
v0.3.2: skills.sh source uses native list view (multi-repo aggregation)
- Drops the iframe + URL-paste UX from v0.3.1 in favor of the same grid
- the curated and firehose tabs use. skills.sh is a meta-aggregator over
- GitHub-hosted skill repos (per https://skills.sh/docs/cli — `npx skills
- add owner/repo`), so we walk a hardcoded list of upstream repos and
- merge their trees.
- - HubSkillRef gains an optional `repo: { owner, repo, branch }` so a
- single SourceId can span multiple GitHub repos. fetchSkill and
- githubUrlFor honor it; existing curated/firehose refs leave it
- undefined and fall back to SOURCES[source].
- - New SKILLS_SH_REPOS table (anthropics/skills, vercel-labs/agent-skills,
- microsoft/azure-skills) with per-repo layout depth. loadSkillsShIndex
- probes each repo's branch sha, builds a combined cache key, fetches
- trees in parallel, and merges into one CachedIndex. Falls back to
- cache when GitHub is unreachable.
- - Hub page: drop the iframe panel + URL paste box (unused now). skills.sh
- loading label says "Aggregating skills.sh repos…". SkillView source
- byline shows "anthropics/skills · <author>" for skills.sh items.
- - Add SKILLS_SH_REPOS upstream repos by appending to the table — no UI
- changes needed.
v0.3.1: skills.sh blocks iframes — replace with deep-link card grid
- - skills.sh sends X-Frame-Options: DENY and CSP frame-ancestors 'none', so
- no iframe can ever load. Drop the embed entirely and surface the catalog
- as 6 deep-link cards (Trending, Hot, Picks, Audited, Official, Search)
- that open in a new tab. Each card is one click away from the live
- skills.sh listings.
- - Right pane keeps the same URL-paste import + scan-before-install flow,
- routed through /__agentix/proxy-fetch (host-allowlisted) so SKILL.md
- fetches don't hit cross-origin blocks. The user-facing wording mentions
- the X-Frame-Options block + the 'click Raw, copy URL' workflow so the
- empty embed isn't mysterious.
v0.3.0: skills.sh iframe sizing + sidecar CORS proxy for SKILL.md import
- - iframe gets explicit min-height: 70vh so the embed actually paints when
- the parent grid's percentage-based height collapses to zero. Drop the
- sandbox attribute that was causing the embedded site's auth/script to
- break, swap to referrerPolicy='no-referrer-when-downgrade'.
- - New /__agentix/proxy-fetch sidecar endpoint with a host allowlist
- (skills.sh, raw.githubusercontent.com, gist.githubusercontent.com,
- api.github.com, github.com) and a 200 KiB response cap. Skills Hub
- routes the SKILL.md import through this proxy because direct browser
- fetches hit CORS on every third-party host.
- - Bumped to 0.3.0 — fast follow on the v0.2.9 skills.sh tab that wasn't
- loading on test machines.
v0.2.9: rename Hub -> Skills Hub, add skills.sh browser tab with pre-install scan
- - Sidebar nav + page title both read 'Skills Hub' so the section name
- matches what users actually browse for. Internal route /hub stays the
- same — no router churn.
- - Add 'skills.sh' as a third source on the Hub page. Selecting it shows
- the live skills.sh site in an iframe alongside an Import box. Users
- paste a raw SKILL.md URL, the file is fetched, frontmatter parsed,
- scanSkillBundle runs, and a ScanReport renders before the Install
- button activates. Same pre-install gate the curated/firehose tabs use,
- so a malicious skill from any host is still surfaced before the agent
- reads it. Heuristic blocks HTML responses (skills.sh landing page) so
- the user has to provide the raw markdown URL.
- - skills-sh source skips the GitHub tree API path in refresh() — there's
- no repo to index, the iframe panel is self-contained.
- - Installed skills.sh entries persist via the same loadInstalledHubSkills
- store used elsewhere; the install key is namespaced 'skills-sh:owner/slug'
- so it doesn't collide with curated/firehose installs.
v0.2.8: harden iMessage enable on Models page
- - readImessageStatus now returns enabled, message, and the full allowed[]
- array instead of just allowedCount, so the Models card's toggle can
- reflect server state and the handle list renders without an extra
- round-trip. Previously j.enabled was undefined so the switch never
- flipped after the user toggled it on.
- - Wrap imessageHost.start() in try/catch in both the POST merge path and
- the DELETE-with-allow path. A start failure (sqlite3 missing, chat.db
- unreadable, FDA not granted) used to bubble up as a 500 to the browser
- while leaving config persisted — the next status poll surfaces the
- underlying error in `message` instead of the request crashing.
v0.2.7: TCC.db screen-recording probe, channel app launchers, iMessage merge fix, Director rename
- - server/index.mjs: probeScreenRecording now reads TCC.db (sqlite3) for
- candidate clients (host app bundle id + Terminal + node binary path)
- before falling back to the live screencapture probe. Eliminates the
- 'still showing missing' state after Privacy toggle — macOS only refreshes
- in-process TCC at launch, but TCC.db reflects the toggle immediately
- and the sidecar already has FDA so the read is unprompted.
- - server/index.mjs: /__agentix/system/apps + /__agentix/system/launch-app
- endpoints — the first probes /Applications and ~/Applications for
- installed chat-app .app bundles, the second shells out to `open -a` (or
- a custom URL scheme) so the UI can launch Discord/Telegram/WhatsApp
- natively.
- - server/index.mjs: iMessage POST/DELETE on /__agentix/channels/imessage
- now merge with the existing config instead of replacing it. Previously
- toggling enabled clobbered the allowlist, and sending { allow: 'x' } as
- a new handle wiped enabled state. POST { enabled }, POST { allow },
- DELETE { allow }, and DELETE (empty) all do the right thing now.
- - src/components/AppLauncher.tsx: shared 'Open <app> / Get <app>' button
- pair. Polls system/apps and renders the open button when present, the
- download link when missing. Built-in macOS apps (Messages) always show
- open. Wired into Channels page (all 4 platforms) and Models page
- iMessage card.
- - iMessage icon recolored from green #34C759 to Apple blue #007AFF in the
- Channels page card.
- - Director rename pass: Dashboard, Onboarding, Help text, ChannelWizard
- descriptions all say 'Director' instead of 'orchestrator' / 'Foreclaw'.
- Channels page agent display swaps to display-name lookup so saved
- configs render 'Director' instead of the bare id.
- - src/lib/license.ts already shipped in v0.2.6 — no change.
v0.2.6: gate agent control on license validity, app-wide invalid-key banner
- - server/update.mjs: cached cloud-validated license status (5-min TTL,
- bust-on-set/clear). New GET /__agentix/update/license/status returns
- { valid, hasLicense, keyMasked, error, status, offline, checkedAt }.
- Exports isLicenseValid() for cross-module use.
- - server/index.mjs: chat/send and chat/sync now refuse with HTTP 403
- { error: 'license-invalid' } when the license fails cloud validation,
- so every code path that talks to agents fails closed — not just the
- UI. Defense in depth: even if the SPA bundle is bypassed, the sidecar
- won't relay user prompts to engine.
- - src/lib/license.ts + src/components/LicenseBanner.tsx: useLicenseStatus
- hook polls every 30s + on focus, surfaces user-friendly copy ('Agentix
- Key Invalid', 'Expired', 'Revoked', 'Device Cap Reached', 'Missing',
- 'Unverified') with a 'Fix in Settings' link.
- - Layout shell renders the banner above every page so Dashboard, Chat,
- Models, Vault all show the same red bar — no per-page wiring needed.
- - Chat input + send button disable when license is locked, with the
- banner-message string used as placeholder + tooltip so the reason is
- visible right where the user tries to type.
- - update-server worker: per-license max-devices, device list, and unbind
- admin endpoints (POST /admin/licenses/<KEY>/max-devices,
- GET /admin/licenses/<KEY>/devices, POST /admin/licenses/<KEY>/unbind)
- so a stuck device cap doesn't require a manual D1 query. Default
- DEFAULT_MAX_DEVICES bumped 1 -> 3 for newly minted licenses.
v0.2.5: bump version
v0.2.4: chat + activity persist across page switches and refreshes
- - Chat: per-agent localStorage cache of messages (last 200) + busy flag (5min TTL). Hydrate immediately on mount, then merge server history. Streaming text + typing dots survive navigation.
- - ActivityPanel ToolCallsStrip: persist last 50 tool events to localStorage; cross-tab sync via storage event.
- - swarmEvents zustand store: wrapped in persist() middleware → events + activeRuns survive refresh; stale runs (>5min) auto-pruned on rehydrate.
- - Vault: Get key ↗ link added to every provider card header — opens setupUrl in a new tab.
- - Models: live sync expanded to openai, groq, deepseek, xai, moonshot, ollama-cloud, anthropic, google (routed through /llm/<id> proxy). Brain picker shows full account-accessible catalog.
- - Models: connected set augments with claude CLI status (anthropic) + codex CLI status (openai) so OAuth-only providers show in the picker.
v0.2.3: Director CC-parity, cancel-aborts-stream, scraper tool, live OpenAI/Anthropic, robust rotation
- Engine
- - providers.mjs: 429 still cools key 60s; 502/503 rotates without cooling (upstream issue, not key-specific)
- - providers.mjs: round-trip JSON.parse on tool_call arguments to catch malformed accumulator output (NVIDIA "Expecting value: line 1 column 13" 400)
- - providers.mjs: trim+strip-quotes on every key from secrets.env (fixes 401 missing-auth from CR/whitespace)
- - engine.mjs: dispatchToolCall enforces orchestrator allowlist at execution (not just catalog filter); refuses shell/pdf/web_fetch/etc with clear error
- - engine.mjs: abortAgent(agentId) iterates inflight Map, aborts every session matching agent:<id>:* prefix
- - subagents.mjs: per-agent FIFO lock (_agentQueues Map). Director can fan out across different agents in parallel; same-agent dispatches queue. No more overload.
- - persona.mjs: Director rewritten CC-style — "you are a router, NOT a worker"; mandatory dispatch behavior; 21-specialist roster with one-line domains; concrete dispatch_parallel example; reply format rules
- Sidecar
- - /tasks/:id/cancel + /tasks/:id/delete now look up task.assignedTo and call engine.abortAgent before updating DB → cancel actually halts the LLM stream, doesn't just mark failed
- - update.mjs: /check returns max(server.version, current) so UI doesn't show "Latest v1.69" when running v0.2.x ahead of channel
- Tools
- - tools.mjs: new scrape_url — wraps Scrapling StealthyFetcher; auto-installs scrapling[fetchers] on first ModuleNotFoundError; 90s timeout; selector-based extraction supported
- - execCmd accepts opts.timeoutMs
- UI
- - Vault: Get key ↗ link in every provider card header (opens setupUrl in new tab, all 30+ providers covered)
- - Vault: + Add Key bug fix (editing flag now checked first); sync banner brand-blue; OAuth/Sign-in button rendered inside MultiKeyCard for any provider with oauth/subscription auth option
- - Chat: skips role:tool messages — tool result JSON renders in side panel, not as chat bubbles
- - Models: connected set augments with claude CLI status (anthropic) + codex CLI status (openai) so OAuth-only providers appear in Brain picker
- - Models: live sync expanded to openai, groq, deepseek, xai, moonshot, ollama-cloud, anthropic, google (all routed through /llm/<id> proxy; browser never holds keys)
- - providerTest: getAuth() picks correct token field per auth method, skips REFRESH/EXPIRES/ID; OpenAI OAuth uses offline expiry check (no /v1/models 403)
- Installer (v0.2.2 already shipped DMG; this build re-stamps assets)
- - installer.sh: rewritten — license verify, OC purge, sidecar install, TCC permission flow, browser open
- - Terminal pop: writes ~/.agentix/oauth-*.command (no AppleScript paste mangling, zsh -f skips ~/.zshrc)
- Cleanup
- - Cleared dead z-ai/glm-5.1 overrides on dev box; default fallback nvidia/meta/llama-3.3-70b-instruct
v0.2.2: native Mac installer — no OpenClaw, TCC permission flow, license verified
- - installer.sh: rewritten from scratch
- - Step 0: verifies AGX-… license against worker /license/verify, caches at ~/.agentix/license.json
- - Step 1: discovers or downloads Node 20 (arm64/x64)
- - Step 2: purges legacy OpenClaw — bootouts com.openclaw.gateway, removes ~/.openclaw, strips ~/.zshrc openclaw lines, deletes openclaw npm binary
- - Step 3: rsyncs bundled app/ → ~/Library/Application Support/Agentix/app
- - Step 4: writes com.agentix.sidecar plist (port 8858, KeepAlive, AGENTIX_DATA_DIR set, PATH includes ~/.local/bin + ~/.npm-global/bin + brew + system)
- - Step 5: polls /__agentix/health up to 30s
- - Step 6: triggers every TCC prompt (Accessibility keystroke, Screen Recording probe, Automation osascript Finder + Terminal, Full Disk Access cat chat.db) + opens System Settings panes
- - Step 7: opens UI in browser
- - build-dmg.sh + build-pkg.sh: banner strings dropped OpenClaw refs
- - pkg-postinstall.sh: forwards AGENTIX_LICENSE through to installer.sh (already wired)
- - Idempotent: safe to re-run for upgrades-in-place
v0.2.1: 5-key rotation pool · CC-parity OAuth · brand-blue theme · CC-style Models page
- - providers.ts: every provider auto-expanded to 5-slot multiKey pool (POOL_SIZE=5)
- - engine/providers.mjs: rotation on 429/502/503 across OpenAI-compat, Anthropic, Gemini streams; per-key 60s cooldown
- - vault: MultiKeyCard now renders OAuth/Sign-in button when provider supports it; Anthropic Sign-in wired to /__agentix/claude-code/login
- - providerTest: getAuth() picks correct token field (skips REFRESH/EXPIRES/ID); OpenAI OAuth uses offline expiry check (no /v1/models 403)
- - vault: + Add Key bug fixed (editing flag now checked first); sync banner brand-blue
- - Models page: full CC-style layout — sticky header, cost ledger, Claude usage, Claude Code OAuth card, Codex OAuth card, Ollama inventory, Brain-for-every-agent provider columns, iMessage bridge, Agent assignments table
- - sidecar endpoints: /__agentix/cost/summary, /claude/usage, /claude-code/{status,login,logout}, /codex/{status,login,logout}
- - Terminal pop: writes ~/.agentix/oauth-*.command (no AppleScript paste mangling, skips ~/.zshrc with zsh -f)
- - whichBinary: searches ~/.local/bin, ~/.npm-global/bin, ~/.bun/bin, brew, /usr/local/bin
- - Inter font everywhere — dropped font-mono on Vault + Models
- - All emerald/cyan replaced with brand-* (Agentix blue #1e90ff)
- - 32 new vault providers (Moonshot, Replicate, markets, search, data, commerce, messaging, social, infra)
v0.1.69 (display v1.69): real-time chat — SSE flush, await subscribe, poll fallback
- Three fixes so chat updates instantly without page refresh:
- 1. Server SSE: add `X-Accel-Buffering: no` and `cache-control: no-transform`
- so nginx / Cloudflare / Tailscale Funnel don't buffer token deltas.
- Disable Nagle on the response socket (setNoDelay) so each event
- flushes immediately instead of waiting up to 40ms to coalesce.
- 2. chat/send handler: await ocClient.subscribeSession before chat.send.
- Previously fire-and-forget — the chat.send RPC could outrun the
- subscribe registration, and the first response's session.message
- events were dispatched before any subscriber was registered for that
- sessionKey, so they were silently dropped.
- 3. Chat.tsx: while busy, poll getChatHistory every 1.5s and merge any
- agent messages that haven't already arrived via the delta stream.
- Cheap GET, stops the moment busy clears. Acts as a self-healing
- fallback when SSE silently drops (proxy idle timeouts, network
- blips) so the UI never sits stuck on "thinking".
v0.1.68 (display v1.68): filter fallback chain against configured providers
- Fixes "unknown model ollama requires auth" on machines without Ollama
- running. The FREE_FALLBACK_CHAIN includes "ollama/gemma4:latest" as a
- last-ditch local fallback. When the primary (e.g. nvidia/...) errored
- out, OC walked the chain and tripped on ollama because no Ollama daemon
- was reachable. ensureProviderModels only filters override models, not
- fallbacks — fix now passes the set of provider ids actually present in
- OC's catalog (next.models.providers) into buildFallbacks, which skips
- fallback entries whose provider isn't configured.
v0.1.67 (display v1.67): audit fixes + sales landing page
- Audit pass (UI + sidecar):
- - src/lib/clipboard.ts (new) — copyToClipboard() with execCommand
- fallback for insecure contexts. navigator.clipboard.writeText is
- gated to HTTPS/localhost; on a tailnet HTTP origin it silently no-ops
- the same way crypto.randomUUID did. Same trap, same fix.
- - Dashboard.tsx copy() now uses copyToClipboard().
- - Sidecar audit: clean. Endpoint handlers, fs ENOENT handling, RPC
- timeouts, sessionKey suffixes (:main vs :agentix), startup ordering
- all checked out — no blocking bugs found.
- landing.html (rewrite):
- - Replaced the 713-line ClawDeck-era doc page with a focused Agentix
- sales landing.
- - Hero, 22-agent grid, 6 feature cards, 3-tier pricing
- (Starter $29/mo + $99 setup, Pro $99/mo + $299 setup, Enterprise
- custom + $1,500 setup), FAQ, footer.
- - Tailwind CDN + brand-blue palette consistent with the app.
- - Pricing CTAs mailto: [email protected] / [email protected] for now;
- swap to Stripe Checkout / payment links when those land.
v0.1.66 (display v1.66): bound dist-release/ growth + log rotation
- dist-release/ had ballooned to 4.1 GB across 132 staged version dirs —
- release.sh wrote a fresh stage on every run and never cleaned up. Same
- problem hit data/logs/ at 510 MB because launchd pipes stdout/stderr
- straight to disk with zero rotation. Repo total was 5.22 GB before this.
- scripts/release.sh now prunes after writing the new stage:
- - dist-release/0.x.y staged dirs older than the most recent 3 → rm
- - dist-release/agentix-X.Y.Z.tar.gz tarballs older than the most
- recent 3 → rm
- Three is enough for a same-machine rollback if a release goes wrong;
- GitHub Releases is the long-term archive.
- Sidecar boot now runs rotateOversizeLogs() alongside pruneStaleGatewayLabels
- + migrateGatewayPort + reapStaleSubagentRuns:
- - Walks 8 known log paths (mac install location + dev location +
- OC's own logs).
- - Anything > 50 MB gets truncated to the last 5 MB, with a marker
- line at the top noting the rotation timestamp + original size.
- - Truncates at the first newline so the kept slice doesn't start
- mid-line.
- After the manual cleanup that ran alongside this, repo went 5.22 GB
- → 690 MB; further releases now stay bounded.
v0.1.65 (display v1.65): iMessage as first-class channel (sidecar polling host)
- Until now iMessage was MCP-only — agents could call into the iMessage
- plugin's tools, but inbound iMessages couldn't trigger an agent run on
- their own and outbound replies needed manual routing. The Channels page
- already had the config UI; what was missing was the runtime that
- actually polls + dispatches.
- server/imessage.mjs (new) — ImessageHost class:
- - Polls ~/Library/Messages/chat.db every 4s via `sqlite3 -readonly
- -json` for ROWIDs newer than the last seen one.
- - For each new inbound (is_from_me=0) from a handle in the allowlist,
- dispatches to the configured agent via dispatchAgent() — same path
- Discord/Telegram/WhatsApp use.
- - Sends the reply back via `osascript "tell application \"Messages\"
- to send …"` (Apple's only sanctioned send path; needs Automation
- consent in Privacy & Security, prompted on first send).
- - Persists last-seen ROWID to ~/.agentix/imessage-state.json so a
- sidecar restart doesn't replay old chats. First boot starts at
- current MAX(ROWID) instead of 0 (don't dump 4 years of history).
- - Tracks lastPollAt / lastInboundAt / sent / received / lastError
- for the Channels page status row.
- Sidecar wiring:
- - imessageHost instantiated alongside channelsHost.
- - Auto-starts on boot when imessage.json has enabled !== false.
- - POST /channels/imessage starts/restarts on enabled=true, stops on
- enabled=false. DELETE stops + clears config.
- - GET /channels/imessage/status returns the runtime block too.
- macOS only by definition (chat.db is Apple-private). Skip on other
- platforms with a clear lastError.
v0.1.64 (display v1.64): randomId() polyfill — fixes Tailscale chat send
- Browser console from a Tailscale-hostname visit:
- Uncaught (in promise) TypeError: crypto.randomUUID is not a function
- at onSubmit (chat send handler)
- crypto.randomUUID is gated to "secure contexts" — HTTPS or localhost.
- http://<host>.<tailnet>.ts.net:8080 is plain HTTP from a non-loopback
- origin, which the browser treats as INSECURE: window.crypto stays
- defined but randomUUID is stripped. The chat send handler called it
- to mint an idempotency key, threw, and bubbled — submit silently died,
- the message bubble never sent, the Send button looked broken.
- Same trap hit Cron creation, attachment ids, swarm-event ids, usage
- ledger row ids, and chat-run ids — none of those features worked from
- the tailnet origin either.
- Added src/lib/uuid.ts: randomId() uses crypto.randomUUID when available
- (secure contexts), falls back to crypto.getRandomValues + RFC4122 v4
- formatting (works in any context with Web Crypto, including non-secure
- HTTP), and last-resorts to Math.random for environments without Web
- Crypto at all.
- All 7 call sites switched: agentMemory, usage, swarmEvents, chatRuns,
- Cron page, Chat page (newMsgId + attachment id), sidecar request log
- on /__agentix/oc/chat/send is server-side Node so randomUUID stays
- imported from node:crypto.
- The SSE ERR_INCOMPLETE_CHUNKED_ENCODING / ERR_CONNECTION_REFUSED noise
- in the same log was transient sidecar restarts; the EventSource auto-
- reconnects.
v0.1.63 (display v1.63): drop Terminal-spawn from .pkg postinstall, log inline
- The Mac .pkg postinstall used to AppleScript a Terminal window and tail
- the install log there. Two problems:
- 1. The Terminal window stayed open after install completed — users had
- to manually close it.
- 2. The user already had Apple's Installer.app open with its own progress
- bar; the extra Terminal made the install feel janky.
- Apple's Installer.app captures stdout from postinstall scripts into a
- built-in log pane (Window → Installer Log, ⌘L) which lives in the same
- window right under the progress bar. Removing the Terminal spawn lets
- that pane do its job and the install finishes with a single window.
- postinstall now also best-effort UI-scripts ⌘L to open the log pane
- automatically (needs Accessibility consent for `installer`; harmless
- no-op when not granted). Conclusion page mentions both ⌘L and the
- on-disk log path.
- Forwards AGENTIX_LICENSE through to the per-user installer.sh so the
- v1.62 license gate doesn't re-prompt when the user typed the key into
- the .pkg's preflight (env-var path) — currently the .pkg has no license
- preflight UI, but this keeps the env-var pathway open for future work.
v0.1.62 (display v1.62): license-gated installer + macOS permission opener
- License gate (mac/linux/windows installers):
- - Worker exposes GET /license/verify?key=AGX-… returning {ok, plan,
- channel, expiresAt}. Refuses non-active or expired keys.
- - Each installer reads AGENTIX_LICENSE env, falls back to ~/.agentix/
- license.json, falls back to a prompt (osascript on Mac, zenity on
- Linux, VisualBasic InputBox on Windows). Up to 3 attempts then exits
- before touching anything system-side.
- - On success the key is cached to ~/.agentix/license.json (mode 0600)
- so re-runs and the OTA self-update endpoint pick it up automatically.
- macOS permissions opener:
- - After install completes, displays a single explainer dialog and
- opens Privacy & Security panes for Accessibility, Screen Recording,
- Microphone, Camera, and Full Disk Access. TCC consent is user-only
- by Apple policy — we can't grant silently — but this removes the
- "where do I find this setting" friction. AGENTIX_SKIP_TCC=1 to
- suppress for headless installs.
- Auto-config status:
- - Node 20 — auto-downloaded if missing (existing).
- - OpenClaw — auto-installed via npm (existing).
- - Scrapling + browser binaries — auto-installed (v1.61).
- - Tailscale — still detect-only; admin/system-extension consent makes
- silent install impractical.
v0.1.61 (display v1.61): installers auto-install Scrapling for Scraper agent
- Scraper agent (added v1.60) needs python3 + scrapling + the headless
- browser binaries scrapling pulls down. Installers now do the install
- on first run so users don't have to remember the magic incantation
- (which also needs to be quoted under zsh — `pip install scrapling[fetchers]`
- expands the brackets as a glob and fails).
- Best-effort: each platform tries to locate python3 (or `py -3` on Windows),
- ensures pip is available (via `python3 -m ensurepip --user` if needed), then
- runs the equivalent of:
- python3 -m pip install --user --upgrade 'scrapling[fetchers]'
- python3 -m scrapling install
- All errors are logged to the installer log, never block the rest of the
- install. Machines without python3 see a clear "install Python 3 then run
- …" warning. Already-installed Scrapling no-ops on re-run.
v0.1.60 (display v1.60): add Scraper agent (Scrapling-backed web scraping)
- 22nd swarm member. Specializes in non-trivial web scraping where the
- Researcher's plain web.fetch falls short — JS-rendered pages, sites
- with anti-bot, Cloudflare-gated endpoints. System prompt steers it
- toward Scrapling (https://github.com/D4Vinci/Scrapling):
- - StealthyFetcher / PlayWrightFetcher for JS + anti-bot
- - AsyncFetcher for plain HTML at concurrency
- - Adaptor CSS/XPath for parsing, .css_first / .xpath_first preferred
- User installs `pip install scrapling[fetchers] && scrapling install`
- on their machine; the agent shells it out via shell.exec / code.run.
- Refuses gated/login/paywall scraping and returns parsed JSON, not raw
- HTML.
- Picks claude-haiku-4-5 by default (fast, cheap, good enough for parse).
- allowAgents is built dynamically from the swarm list, so the new id is
- automatically spawnable from any other agent — no extra wiring needed.
v0.1.59 (display v1.59): auto-allow tailnet FQDN + IP in OC controlUi.allowedOrigins
- OC's WS handshake checks the browser's Origin header against
- gateway.controlUi.allowedOrigins. v1.58 made the gateway reachable on
- the tailnet (bind=lan), but the allowedOrigins list only had loopback +
- dev origins, so opening the OC UI from a tailnet peer hit the gateway,
- got past the bind, then bounced with "origin not allowed".
- Sidecar swarm-sync now queries `tailscale status --json` for the
- machine's tailnet FQDN (Self.DNSName) + IPv4 (Self.TailscaleIPs[0])
- and appends:
- http://<host>.<tailnet>.ts.net:15585
- https://<host>.<tailnet>.ts.net:15585
- http://<tailnet-ip>:15585
- to controlUi.allowedOrigins. Idempotent — already-listed entries are
- skipped, so the gateway only restarts on the first sync after Tailscale
- comes up. Skipped entirely on machines without Tailscale logged in.
v0.1.58 (display v1.58): OC tailnet exposure (bind=lan when Tailscale up)
- User couldn't reach the OC Control UI at the tailnet hostname:15585 even
- though Agentix sidecar at :8080 was working — the installer set
- gateway.bind=loopback so OC only listened on 127.0.0.1.
- Two fixes wrapped in this release:
- 1. Strip `tailscale.*` root keys from openclaw.json. OC 2026.5.x's
- schema validator rejects them (config.patch had been failing for
- every swarm sync since v1.54 with "Unrecognized key: tailscale"
- — that error blocked agent provisioning, model overrides, MCP
- wiring, and the auth.mode/token migration the v1.50 fix relied on).
- Sidecar swarm-sync now `delete next.tailscale` defensively, and
- the installer scripts strip stale entries instead of writing them.
- 2. Sidecar swarm-sync detects whether Tailscale is logged in
- (`tailscale status --self=true`) and switches gateway.bind to
- "lan" when yes / "loopback" when no. bind="tailnet" was tempting
- but excludes loopback, which breaks the sidecar's own oc-client
- (it dials 127.0.0.1:15585). bind=lan binds all interfaces; the
- shared gateway.auth.token still gates every WS handshake, so we
- don't actually expose anything for free.
- After this release, OC is reachable at https://<host>.<tailnet>.ts.net:15585
- on machines where Tailscale is up, while a machine with no Tailscale
- stays loopback-only as before.
v0.1.57 (display v1.57): re-do port migration 18789→15585 with proper plist/env rewrite
- v1.54 tried this and broke OTA because OTA only swaps Agentix files
- and never touches the launchd plist or the OC service-env file (both
- hardcode the gateway port — the plist as a CLI arg, the env as
- OPENCLAW_GATEWAY_PORT, and either overrides openclaw.json). Existing
- installs ended up with sidecar wanting 15585 but gateway still bound
- to 18789.
- migrateGatewayPort() in sidecar boot reads
- ~/Library/LaunchAgents/ai.openclaw.gateway.plist
- ~/.openclaw/service-env/ai.openclaw.gateway.env
- and rewrites both 18789 → 15585 when present. Idempotent. plutil
- lints the rewritten plist before commit; if lint fails, the original
- is restored. Then bootouts + bootstraps the launchd job so the new
- port takes effect on this boot, no user action needed.
- swarm-sync also re-pins openclaw.json gateway.port=15585 so a
- doctor/repair pass can't drift back. Rest of the sidecar (oc-client
- WS URL, installer plists, uninstall scripts, Help.tsx, docker config)
- all switched to 15585.
v0.1.56 (display v1.56): revert OC port change — keep 18789
- The 18789 → 15585 migration in v1.54 broke OTA upgrades. The OC gateway
- plist hardcodes the port as a CLI flag (`gateway --port 18789`) AND
- inside service-env (`OPENCLAW_GATEWAY_PORT='18789'`); both override
- the config. OTA only swaps Agentix files, never the launchd plist or
- service-env, so an OTA-updated machine ended up with sidecar wanting
- 15585 but gateway still bound to 18789 → ECONNREFUSED loop until the
- user manually re-installed.
- Reverting all of it: sidecar oc-client.mjs, installer plists, uninstall
- scripts, Help copy, docker config, and the swarm-sync port-pinning
- back to 18789. The Tailscale "messages don't send" symptom we were
- trying to fix turned out to be the secrets.env wipe (handled in v1.55),
- not a port collision — the migration was unnecessary churn.
- allowedOrigins normalization stays (always make sure :18789 + :8080 +
- :5173 are listed for browser WS handshakes), just without the port-
- strip filter.
v0.1.55 (display v1.55): vault sync merges, doesn't wipe — fixes Tailscale-origin chat
- The Vault page POSTs the full localStorage vault snapshot to
- /__agentix/secrets on mount. Browser localStorage is per-origin, so a
- visit to the sidecar via a non-localhost origin (e.g. the Tailscale
- *.ts.net hostname) loaded with an empty vault and overwrote
- data/secrets.env with an empty file. Result: the in-process NVIDIA /
- OpenRouter / ollama-cloud key pools dropped to zero on every
- cross-origin visit, and chat dispatch silently failed everywhere
- ("messages don't send") until the user re-saved their keys at the
- original origin.
- writeSecretsFile() now reads the existing file, merges the incoming
- snapshot over the top (non-empty values overlay; absent keys are
- preserved), and only renders the merged set. Empty incoming snapshot
- becomes a no-op. To explicitly clear a key, the client passes an empty
- string for it.
- The /__agentix/secrets handler re-reads the merged file after the
- write and feeds that into the proxies + OC sync, so the in-memory key
- pool can't be wiped by an empty POST either.
- Doesn't fix the underlying multi-origin localStorage divergence
- (documented behavior — vault keys live in the originating browser by
- design), but stops the cross-origin "wipe everything" failure mode
- that broke chat after even a single tailnet visit.
v0.1.54 (display v1.54): Tailscale support + OC port 18789 → 15585
- Tailscale support:
- - Mac/Linux/Windows installers detect Tailscale and either confirm it's
- installed or print the platform install command (no silent install
- because every platform's Tailscale install requires admin/kernel-ext
- consent).
- - Installer + sidecar swarm-sync write `tailscale.mode = "serve"` to
- openclaw.json so the gateway accepts tailnet identity headers as soon
- as the user runs `tailscale up`. Idempotent — no restart loop when
- the value already matches.
- Port migration 18789 → 15585:
- - New default for OC gateway. 18789 collided with too many dev tools.
- - Installers explicitly set `gateway.port = 15585` in openclaw.json.
- - Sidecar swarm-sync pins the same value at runtime so existing installs
- migrate on next sidecar boot. Gateway restarts once when the port
- actually changes; subsequent syncs are no-ops.
- - controlUi.allowedOrigins gets the new port added and any lingering
- 18789 entries stripped so browsers opening the OC UI on the new port
- pass the WebSocket origin check.
- - All sidecar/UI references switched: oc-client.mjs WS URL, sidecar
- health probe, installer plist `--port`, uninstall scripts, Help.tsx
- troubleshooting copy, docker config sample.
v0.1.53 (display v1.53): auto-login bridge to OpenClaw Control UI
- OC's bundled Control UI at :18789 expects the user to paste the shared
- gateway.auth.token by hand on every machine. The token now exists (we
- generate it during install + migration), but nobody types it in.
- Two new sidecar endpoints:
- - GET /__agentix/oc/token → { token, mode } from openclaw.json
- - GET /__agentix/oc/dashboard → tiny HTML page that JS-redirects to
- http://127.0.0.1:18789/#token=<token>. OC reads the hash fragment,
- stores it in localStorage on first load, and never prompts again.
- HTTP 302 can't carry a fragment in the Location header, hence the
- inline-script bounce.
- Settings → Gateway gets an "Open OC dashboard" button that opens the
- bridge in a new tab. Loopback-only because the endpoint only listens
- on the sidecar's bind.
v0.1.52 (display v1.52): release.sh pins tag to HEAD, not main
- gh release create without --target tags at the repo's default branch
- HEAD, which on this repo is `main`. Feature-branch commits don't reach
- main, so v1.47-v1.51 all tagged at the May-2 main commit and CI built
- installers from stale source. Pin --target to the current commit so
- tags follow the actual code we're shipping.
fix: heal orphan workspaces + dual launchd label restart
fix: heal orphan workspaces + dual launchd label restart
fix: heal orphan workspaces + dual launchd label restart
fix: heal orphan workspaces + dual launchd label restart
fix: heal orphan workspaces + dual launchd label restart
fix: heal orphan workspaces + dual launchd label restart
fix: heal orphan workspaces + dual launchd label restart
fix: heal orphan workspaces + dual launchd label restart
fix: heal orphan workspaces + dual launchd label restart
fix: heal orphan workspaces + dual launchd label restart
fix: heal orphan workspaces + dual launchd label restart
fix: heal orphan workspaces + dual launchd label restart
fix: heal orphan workspaces + dual launchd label restart
fix: heal orphan workspaces + dual launchd label restart
fix: heal orphan workspaces + dual launchd label restart
fix: heal orphan workspaces + dual launchd label restart
fix: heal orphan workspaces + dual launchd label restart
fix: heal orphan workspaces + dual launchd label restart
fix: heal orphan workspaces + dual launchd label restart
fix: heal orphan workspaces + dual launchd label restart
fix: heal orphan workspaces + dual launchd label restart
fix: heal orphan workspaces + dual launchd label restart
fix: heal orphan workspaces + dual launchd label restart
fix: heal orphan workspaces + dual launchd label restart
fix: heal orphan workspaces + dual launchd label restart
fix: heal orphan workspaces + dual launchd label restart
fix: heal orphan workspaces + dual launchd label restart
fix: heal orphan workspaces + dual launchd label restart
fix: heal orphan workspaces + dual launchd label restart
fix: heal orphan workspaces + dual launchd label restart
fix: heal orphan workspaces + dual launchd label restart
fix: heal orphan workspaces + dual launchd label restart
fix: heal orphan workspaces + dual launchd label restart
fix: heal orphan workspaces + dual launchd label restart
fix: heal orphan workspaces + dual launchd label restart
fix: heal orphan workspaces + dual launchd label restart
fix: heal orphan workspaces + dual launchd label restart
fix: heal orphan workspaces + dual launchd label restart
fix: heal orphan workspaces + dual launchd label restart
fix: heal orphan workspaces + dual launchd label restart
fix: heal orphan workspaces + dual launchd label restart
fix: heal orphan workspaces + dual launchd label restart
fix: heal orphan workspaces + dual launchd label restart
fix: heal orphan workspaces + dual launchd label restart
fix: heal orphan workspaces + dual launchd label restart
fix: heal orphan workspaces + dual launchd label restart
fix: heal orphan workspaces + dual launchd label restart
ci: dispatch checks out current ref, not stale tag
Merge branch 'main' of https://github.com/ixi88ai/agentix
initial commit
initial commit