Architecture

Feature manifest

Every user-visible feature, generated from features.toml with the pull request that added it.

This page is MANIFEST.md, which cargo run -p niles-bin -- generate-manifest writes from features.toml. A test fails when the two disagree.

Niles is an AI-first home-automation system for private homes. It listens to natural-language voice commands, dispatches them through a tiered intent router, and can escalate to an LLM when a request exceeds the deterministic tier. The feature catalog below tracks every user-observable capability shipped so far. For the crate map, the house rules and the big decisions see ARCHITECTURE.md.

ambient

FeatureSummarySince
curve-brightnessPer-minute adaptive brightness curve based on time of day#5
curve-color-tempPer-minute adaptive color-temperature curve based on time of day#7
curve-morning-routineGradual morning-routine ramp that respects per-room claims#24
morning-routine-keeps-manualAt the end of the morning routine, a light set by hand during the ramp keeps its level instead of going to full#466
manual-mode-from-tools-and-rulesA level, warmth, colour or effect set by the model or an automation puts the light in manual mode; on or off does not#466
manual-mode-overrideClear manual-mode overrides after a configurable timeout#32

api

FeatureSummarySince
api-events-approval-changedapproval_changed on /events/stream when one is held, answered or lapses, to its person only#455
api-events-streamWebSocket /events/stream pushes real-time device and system events#86
events-artifact-statusartifact_changed on /events/stream, to its owner and whoever it is shared with only: the status line follows a job#429
api-artifact-imagesGET /me/artifacts/{id}/images/{image}: a picture an artifact keeps, its owner's only; GET lists them#442
api-get-devicesGET /devices returns the full device registry snapshot#13
api-get-roomGET /rooms/{room} returns the devices in a single room#13
api-healthzGET /healthz returns a liveness probe for load balancers#13
api-plugin-log-imageGET /plugins/{id}/log for a plugin's last lines, and /plugins/{id}/image for its pages' pictures, fetched by Niles#391
api-pluginsGET /plugins lists installed plugins with their status and last error#388
api-plugins-libraryGET /plugins/install/library: the add-on library from the registry's one index.json, kept 6 hours; no GitHub API calls#469
api-training-todayGET /me/training/today: the signed-in person's training plan read for today, or plan null without one#438
api-artifact-pagesAn artifact's page_html and the house's today on GET /me/artifacts/{id}; PATCH remove_page; each version with its page#440
api-artifact-sharesGET/PUT/DELETE /me/artifacts/{id}/shares, its owner's only; every artifact route answers by owner, edit or view#452
api-chat-attachmentsPOST /chat takes a multipart body with up to 5 files of 10 MB; GET …/attachments/{a} serves one to its owner#449
api-me-approvalsGET /me/approvals, POST /me/approvals/{id}, GET /me/approvals/history?before=; the caller's own only#455
api-plugins-managePOST /plugins/install/preview and /plugins/install; update, rollback, enable, disable and DELETE per plugin#390
api-post-devicePOST /rooms/{room}/{device} sets one light, in whichever source it comes from#59
api-post-lightsPOST /lights sets every light in the house in one request#189
api-post-roomPOST /rooms/{room} sets every light in a room in one request#178
api-pushGET /push/key; GET, POST and DELETE /me/push for this person's devices; POST /me/push/test#432
api-web-search-testPOST /integrations/web_search/test runs a web and an image query through the saved SearXNG and counts the results#451

automations

FeatureSummarySince
automations-any-device-actionAny device that reports an action, such as a printer finishing, can start a rule, and the editor offers it#393
automations-motion-groupsA motion trigger or condition over several sensors or rooms: no motion in any of them for 2 minutes, or motion in one#450
automations-rule-in-fullA rule said a line at a time from the rule itself, shown with Save in the chat and used for the confirmation#450
automations-save-warningsSaving or proposing a rule warns when a check after a wait could end it with nothing to try again#450

automations-motion-groups — example phrasings

  • keep the hallway and kitchen lights on while I move between them
  • turn both off once neither room has had motion for two minutes

llm

FeatureSummarySince
tool-command-historyQuery the command-history log for past user requests#70
tool-datetimeReturn the current date and time in the configured timezone#84
tool-device-historyQuery the device-state history log for past state changes#71
tool-explain-device-stateProvide a natural-language explanation of a device's current state#70
tool-light-controlTurn lights on or off and set brightness or color temperature#3
tool-look-up-capabilityRetrieve a capability reference document by name for the LLM context#84
tool-scene-controlApply or delete saved scenes via structured tool calls#43
tool-sonos-transportControl Sonos speaker transport state via the speakers subsystem#65
tool-timerSet, cancel, and list timers via structured tool calls#3
tool-tv-volumetv_volume sets, steps, mutes or unmutes the TV's own speakers; music_volume turns the TV in a room with no Sonos#403
tool-weatherFetch current weather and forecast via Open-Meteo#81
tool-web-searchSearch the web via SearXNG and return summarized results; offered while the SearXNG add-on is set up#83

runtime

FeatureSummarySince
approval-logEvery approval logged when asked and answered, lapses included; one summary line, never the arguments#455
artifacts-documentsClaude or ChatGPT saves documents for you, with versions, and writes a big one in the background#429
artifacts-editsSmall changes to a saved item or its page made in the chat as edits; big or slow ones finish in the background#474
artifacts-pagesAsk Claude or ChatGPT for a page for any saved artifact: HTML that draws its data, and draws again as the data changes#440
artifacts-picturesPictures in a document, a trip or a page, found with the house's search and kept as Niles's own clean copies#442
artifacts-sharingShare a saved artifact with someone in the house, to read or to edit; an editor's own Claude or ChatGPT can change it#452
artifacts-tripA trip planned in the background: days, places, stays and bookings, a countdown, and a packing list to tick#434
assistant-built-in-searchWithout SearXNG, Claude searches with Claude Code's own WebSearch (never WebFetch); ChatGPT is told it has no search#451
assistant-noneChoose Niles's own model as the assistant: neither Claude nor ChatGPT answers, and nothing runs in the background#394
assistant-reads-attachmentsClaude or ChatGPT answers about an attached photo or PDF; a message with files always goes to the assistant#449
web-search-liveAdding, changing or removing the SearXNG address takes hold with the next search, without a restart#451
notification-historyWhat Niles says unprompted is kept in Postgres, so "what did I miss" still knows after a restart#466
notifications-for-the-houseAn announcement with no room is spoken in every room with a satellite, still under quiet hours#466
push-artifact-readyA notification on your phone or computer when a document written in the background is ready; a tap opens it#432
push-artifact-sharedA notification when someone shares an artifact with you, from the app or by asking: Mark shared “Thailand trip” with you#452
observability-command-logStructured command-history log for every voice and API request#70
observability-state-logStructured device-state history log for every state change#71
persistence-json-storeJSON file persistence for timers, scenes, and morning-routine claims#64
plugins-check-listingniles plugin check lists a plugin's permissions; --listing also checks the marker the add-on library needs#469
plugins-dev-checkniles plugin check validates a plugin as an install would; niles plugin dev runs one against a stand-in house#388
plugins-dev-loopback-waitniles plugin dev waits for MQTT before --call, runs the newer build, and reaches a fake device with --allow-loopback#393
plugins-disable-removeTurn a plugin off and keep its data, or remove it with its devices, storage, settings and secrets#390
plugins-installInstall a plugin from a GitHub release after a preview of its permissions; exactly the previewed files run#390
plugins-install-countA fresh install downloads the release's niles-installed once per house, so GitHub counts installs; previews don't#469
plugins-interface-versionsPlugins built for interface 0.1 keep running beside 0.2 ones, marked as built for an older Niles#392
plugins-mqttPlugins on interface 0.2 talk MQTT to the brokers their manifest names; Niles holds the connection and reconnects#392
plugins-mqtt-trust-deviceA device's own MQTT certificate is trusted on first use and pinned; a changed one waits for the household to accept it#392
plugins-plain-errorsPlugins' MQTT and HTTP failures read as plain reasons, such as connection refused or wrong username or password#393
plugins-room-lightA plugin can keep a light out of its room's lights, so room commands, scenes, presence and the curve leave it alone#393
plugins-runtimeRun third-party integrations as sandboxed WebAssembly components; their devices, tools and pages join the house#388
plugins-time-zonePlugins on interface 0.2.1 are told the house's time zone; 0.2.0 plugins run unchanged#393
plugins-update-rollbackPlugins are checked for newer releases; an update shows the permission change and rolls back if it soon fails#390
providers-default-elevenlabs-cerebrasA new install hears with ElevenLabs and thinks with Cerebras; stored Groq settings fall back to them and say so#394
artifacts-training-planA training plan toward a race, made from your own Strava runs: weeks, a countdown and today's session under Saved#430
training-plan-follows-runsA training plan follows your Strava runs: each marks its session done, and Claude or ChatGPT adjusts what is to come#436
training-strava-syncEach person's own Strava: 180 days on connect, then a poll every 15 minutes within Strava's rate limits#418

artifacts-documents — example phrasings

  • write a packing list for the cabin
  • make a travel plan for our Thailand trip
  • add sunscreen to my packing list

artifacts-edits — example phrasings

  • make the headings on the Thailand page green
  • move the ferry to Koh Tao to 9:30
  • make our trip a week longer

artifacts-pages — example phrasings

  • make my trip plan look nicer
  • make a page for my training plan
  • make the packing list into a poster

artifacts-pictures — example phrasings

  • add some pictures to my trip
  • put a photo of the beach on day three
  • make a page for our trip with pictures of each place

artifacts-sharing — example phrasings

  • share the Thailand trip with Majse so she can edit it
  • let Majse see my training plan
  • add Chiang Mai to our Thailand trip
  • stop sharing the packing list with Majse

artifacts-trip — example phrasings

  • plan our trip to Thailand from 3 to 23 January
  • make an itinerary for two weeks in Japan
  • add a day in Chiang Mai to our Thailand trip

assistant-built-in-search — example phrasings

  • what's the news today
  • when does the ferry to Samsø leave

assistant-reads-attachments — example phrasings

  • what's this plant
  • add what's on this receipt to the shopping list

artifacts-training-plan — example phrasings

  • make me a half marathon training plan
  • plan my training for the Copenhagen Half on 13 December
  • move my long run to Saturday

ui

FeatureSummarySince
auth-api-key-madeNiles makes its own API key on a start with a database, and a new one works at once with no restart#405
auth-api-tokenA bearer token for reading the API from a terminal#186
auth-github-sign-inSign in with GitHub, against an allowlist of verified email addresses#186
chat-attachmentsAttach photos and PDFs to a chat message by dragging, the paperclip or a paste; chips before sending, thumbnails after#449
ui-approvals-historyApprovals history in the panel and on My profile: each decided or lapsed, "Allowed once · 15:34", Show older#455
ui-approvals-panelApprovals tab in Niles's panel: what needs review, folded with Details, answered there; a count on the tab#455
ui-artifact-page-frameAn artifact's page in a sealed frame, no network and no Niles: a Page / Built-in switch, links opened on a yes#440
ui-artifact-picturesPictures drawn from Niles's own copies with their credit; a picture by its web address is never fetched#442
ui-artifact-share-menuA share menu on an open artifact: Share, Copy, Word for documents, plans and trips, Markdown, a podcast's MP3#472
ui-artifact-sharingShare from an open artifact: None, View or Edit for each person; Saved marks what is shared and who changed it last#452
ui-push-nudgeWhile a document is being written, one tap on "Notify me when it's done" turns notifications on for this device#432
ui-saved-artifactsSaved tab: pin, archive, rename, tick checklists, restore versions; a card with a preview under the reply#429
ui-training-plan-sessionsTap a training plan's session to mark it done or skipped, and read the coach's notes on the plan#436
ui-todays-run-cardToday's run on the dashboard: the session, the next one, the week's km and the coach's note, with Done and Skipped#438
linear-webhookLinear's card takes a webhook signing secret; once saved, an issue going to review or done is announced#466
plugins-libraryBrowse lists add-ons others published, Listed before Unreviewed, with installs and stars; Install opens the same preview#469
plugins-widget-room-settingA plugin's widget can start in the room one of its settings names, and moves when the setting changes#393
ui-media-without-sonosMedia without Sonos: the TV's switch, what is on and its own volume; no Sonos-only cards; with no TV, where to add one#408
ui-plugin-pagesPlugins' pages join the menu and their widgets the front page and rooms, drawn from their declared trees#391
ui-plugin-setupA plugin's panel: a setup form generated from its manifest's settings, its log, and where its widgets go#391
ui-pluginsAdd-ons page: add-on from GitHub, and a panel per plugin to turn it off, update, roll back or remove it#390
ui-tv-volumeThe TV row has volume down and up, a slider and mute while it is on, where the TV is the speaker; POST /tv/volume#403
ui-tv-wake-macTV panel: the wake MAC, detected or set by hand and kept through pairing; power-on says when the TV did not answer#409
ui-web-search-addonWeb search (SearXNG) as an add-on: its address saved in the app, its status, a Test of web and image search, Remove#451
ui-installableInstall the dashboard to a phone's Home Screen as an app#179
ui-room-card-blindsA room card with lights and blinds has separate Lights and Blinds buttons beside Heating, each opening its own sheet#404
ui-room-dashboardWeb dashboard of every room, switching a whole room or one light#178
ui-room-hiddenHide a room from the dashboard's grid in Settings → Rooms; voice, rules, the API and the house's counts still reach it#404
ui-api-accessSettings → API access: the key masked, with reveal, copy, a curl example and New key, for a signed-in person only#405
ui-profile-sectionsMy profile laid out like Settings: About you, My phone, Notifications, each add-on a page, Approvals#455
ui-push-notificationsMy profile → Notifications: on for this device, your devices, Send a test; iPhone asks for the Home Screen app#432
ui-settings-systemSettings splits the system (Devices: the broker; Voice & AI: hearing, thinking, speaking) from optional add-ons#394
ui-setup-checklistOn a new install each System page leads with what it still needs, and the settings list counts it#394
ui-strava-connectMy profile → Strava: set up your own Strava app, save its keys, connect, last sync, Sync now, disconnect#418
ui-voice-rolesPicking a hearing or thinking provider sets it up: its API key sits beside it, and one save declares it#394

voice

FeatureSummarySince
tier-two-escalationEscalate a voice request to the Tier 2 LLM when Tier 0/1 cannot answer#87
light-all-brightnessSet brightness for every light in a room simultaneously#25
light-all-on-offTurn all lights in a room on or off at once#3
light-all-tempSet color temperature for every light in a room simultaneously#72
light-brightnessSet a light's brightness to a specific percent#25
light-named-whiteSet a light to a named white such as warm or cool#74
light-on-offTurn a single light on or off by room and name#3
light-stepStep a light brighter or dimmer by one increment#27
light-temp-stepStep a light warmer or cooler by one color-temperature increment#72
media-duckTemporarily lower volume for voice responses#73
media-next-previousSkip to the next or previous track#75
media-play-pausePlay or pause media playback on the active speaker#65
media-volume-setSet the speaker volume to a specific level#65
media-volume-stepRaise or lower the speaker volume by one step#65
podcastsA researched two-host episode, voiced by the house's own Kokoro, played in the app or on a Sonos#457
tv-volumeThe LG TV's own speakers by voice, and a room's volume on its TV when the room has no Sonos#403
tv-wake-connected-interfaceTurning on the LG TV wakes the interface it is connected by, and every other MAC it reported too#409
memory-addAppend a note to the user's persistent memory#77
memory-removeRemove a note from the user's persistent memory#77
memory-replaceReplace an existing memory entry#77
memory-viewShow the contents of the user's persistent memory#77
scene-applyRestore a previously saved scene by name#43
scene-deleteDelete a saved scene by name#45
scene-listList all saved scenes#45
scene-room-by-name"cosy in the living room" saves or applies the living room's cosy when the house has that room#466
scene-saveSave the current device states as a named scene#43
skill-background-reviewReview skill suggestions generated in the background#85
skill-curatorAutomatic background transitions for stale and archived skills#80
skill-deleteDelete a saved skill by name#78
skill-mintCreate a new skill from a natural-language description#78
skill-patchUpdate an existing skill's body while keeping its name#78
skill-viewRead the full body of a saved skill#78
timer-cancelCancel an active timer by name or duration#3
timer-listList all currently active timers#3
timer-setSet a timer for a given duration#3
voice-training-questionsAsk about your own runs and workouts from your Strava by voice or chat, and have a week or month added up#410
voice-training-todayAsk what your run is today or tomorrow, from your own training plan, with the week's distance and the countdown#436

tier-two-escalation — example phrasings

  • ask the smart assistant
  • escalate this to tier two

light-all-brightness — example phrasings

  • set all lights to 75 percent

light-all-on-off — example phrasings

  • turn on all the lights
  • switch everything off

light-all-temp — example phrasings

  • make all the lights warmer

light-brightness — example phrasings

  • set the living room light to 50 percent
  • dim the hallway to twenty percent

light-named-white — example phrasings

  • set the light to warm white
  • switch to cool white

light-on-off — example phrasings

  • turn on the kitchen light
  • switch off the bedroom lamp

light-step — example phrasings

  • make it brighter
  • dim the light a little

light-temp-step — example phrasings

  • make it warmer
  • cool down the light

media-duck — example phrasings

  • duck the music
  • lower the music while you speak

media-next-previous — example phrasings

  • next song
  • previous track

media-play-pause — example phrasings

  • play music
  • pause the music

media-volume-set — example phrasings

  • set the volume to thirty
  • turn the music down to ten

media-volume-step — example phrasings

  • turn it up
  • make it quieter

podcasts — example phrasings

  • make me a quick podcast about the Øresund bridge
  • play the podcast about the bridge in the kitchen

tv-volume — example phrasings

  • set the TV volume to 20
  • turn the TV up
  • mute the TV
  • volume up in the living room

tv-wake-connected-interface — example phrasings

  • turn on the TV

memory-add — example phrasings

  • remember that I like the lights dim
  • add to my memory

memory-remove — example phrasings

  • forget that I like dim lights
  • remove from my memory

memory-replace — example phrasings

  • update my memory to say I prefer warm white

memory-view — example phrasings

  • what do you know about me
  • read my memory

scene-apply — example phrasings

  • activate movie mode
  • set the scene to dinner

scene-delete — example phrasings

  • delete the dinner scene
  • remove movie mode

scene-list — example phrasings

  • what scenes do we have
  • list my scenes

scene-room-by-name — example phrasings

  • save this as cosy in the living room
  • apply cosy in the living room

scene-save — example phrasings

  • save this as movie mode
  • remember this scene as dinner

skill-background-review — example phrasings

  • review my pending skills
  • show background skill suggestions

skill-curator — example phrasings

  • run the skill curator
  • clean up old skills

skill-delete — example phrasings

  • delete the bedtime skill
  • remove movie night

skill-mint — example phrasings

  • save this as a skill called bedtime
  • mint a skill named movie night

skill-patch — example phrasings

  • update the bedtime skill
  • patch movie night

skill-view — example phrasings

  • show me the bedtime skill
  • what is in movie night

timer-cancel — example phrasings

  • cancel the five minute timer
  • stop the timer

timer-list — example phrasings

  • what timers are running
  • list my timers

timer-set — example phrasings

  • set a timer for five minutes
  • timer ten minutes

voice-training-questions — example phrasings

  • how was my week
  • how far did I run on Sunday
  • what was my pace on my last run

voice-training-today — example phrasings

  • what's my run today
  • what run do I have tomorrow
  • what's on my training plan

On this page

ambientapiautomationsautomations-motion-groups — example phrasingsllmruntimeartifacts-documents — example phrasingsartifacts-edits — example phrasingsartifacts-pages — example phrasingsartifacts-pictures — example phrasingsartifacts-sharing — example phrasingsartifacts-trip — example phrasingsassistant-built-in-search — example phrasingsassistant-reads-attachments — example phrasingsartifacts-training-plan — example phrasingsuivoicetier-two-escalation — example phrasingslight-all-brightness — example phrasingslight-all-on-off — example phrasingslight-all-temp — example phrasingslight-brightness — example phrasingslight-named-white — example phrasingslight-on-off — example phrasingslight-step — example phrasingslight-temp-step — example phrasingsmedia-duck — example phrasingsmedia-next-previous — example phrasingsmedia-play-pause — example phrasingsmedia-volume-set — example phrasingsmedia-volume-step — example phrasingspodcasts — example phrasingstv-volume — example phrasingstv-wake-connected-interface — example phrasingsmemory-add — example phrasingsmemory-remove — example phrasingsmemory-replace — example phrasingsmemory-view — example phrasingsscene-apply — example phrasingsscene-delete — example phrasingsscene-list — example phrasingsscene-room-by-name — example phrasingsscene-save — example phrasingsskill-background-review — example phrasingsskill-curator — example phrasingsskill-delete — example phrasingsskill-mint — example phrasingsskill-patch — example phrasingsskill-view — example phrasingstimer-cancel — example phrasingstimer-list — example phrasingstimer-set — example phrasingsvoice-training-questions — example phrasingsvoice-training-today — example phrasings