Talome
Guides

Self-Improvement

How Talome rewrites its own TypeScript source code — with a full plan-apply-verify pipeline and automatic rollback.

Talome is the first self-hosted platform that improves its own source code. When you report a slow page, a UI bug, or ask for a new feature, the AI reads the relevant source files, understands the implementation, writes a targeted modification, runs the TypeScript compiler, and either commits the change or rolls it back. Every step is audited.

This isn't theoretical. The AI has access to the full Talome monorepo, understands the architecture, and has purpose-built tools for safe code modification. You can watch it plan a change, review the diff, approve it, and see the result on your next page refresh.

Watch: The AI identifying and fixing a performance issue in its own code

The Three-Stage Pipeline

Self-improvement follows a strict plan-apply-verify pipeline. No stage can be skipped.

Stage 1: Plan

The plan_change tool reads the relevant source files, understands the current implementation, and generates a detailed change plan. This is a read-only operation — nothing is modified.

Talome Assistant
The container list loads slowly when I have 20+ containers
plan_changeOptimize container list performance
read_fileread apps/core/src/routes/containers.ts
read_fileread apps/dashboard/src/components/containers/container-list.tsx

Found the bottleneck. The container list route calls Docker's /containers/id/stats endpoint for each container sequentially. With 23 containers, that's 23 serial HTTP calls -- each taking 150-200ms. Proposed change: in containers.ts, replace sequential inspect+stats calls with a single /containers/json call using Docker's built-in stats summary, add a 5-second cache, and move per-container details to a separate endpoint. In container-list.tsx, remove the per-row stats fetch and use summary stats from the list endpoint. Expected improvement: ~4 seconds to ~200ms for 23 containers. Should I apply this?

The plan stage is critical because it lets you review what will change before anything is modified. The AI shows:

  • Which files will be touched
  • What the current code does
  • What the new code will do
  • Why the change improves things

Stage 2: Apply

The apply_change tool writes the modification and immediately validates it:

Talome Assistant
Do it.
apply_change2 files modified, TypeScript compilation succeeded (0 errors)

Change applied and committed. Modified apps/core/src/routes/containers.ts and apps/dashboard/src/components/containers/container-list.tsx. The container list now fetches all stats in a single Docker API call with a 5-second cache. Refresh the Containers page to see the difference.

What happens inside apply_change:

  1. The modification is written to disk
  2. pnpm exec tsc --noEmit runs from the affected app directory
  3. If compilation succeeds — the change is committed to git with a descriptive message
  4. If compilation fails — the change is automatically stashed with git stash, the error is reported, and the codebase returns to its previous state

The apply stage runs in a detached worker process that survives server restarts. If Talome restarts mid-apply, the worker finishes and reports the result when the server comes back.

Stage 3: Verify

After applying, you can:

  • Test the change — refresh the page or trigger the behavior that was fixed
  • Review the difflist_changes shows the full history with before/after
  • Roll backrollback_change reverts the most recent change cleanly
Talome Assistant
Show me recent changes
list_changes3 changes: container list optimization, media player seek bar, dark mode settings

Recent changes: 1. Container list optimization (Applied, 2 files, 5 min ago), 2. Fixed media player seek bar (Applied, 1 file, 2 days ago), 3. Added dark mode to settings (Applied, 3 files, 1 week ago).

Roll back the container list change -- I want to test more first
rollback_changerolled back change #1

Rolled back "Container list optimization." Both files restored to their previous state.

Safety Mechanisms

Every safety net exists because self-modifying code is inherently dangerous. Here's what prevents the AI from breaking your system:

Safety NetWhat It DoesWhen It Triggers
TypeScript validationEvery change must pass pnpm exec tsc --noEmit with zero errorsAfter every apply
Git stash rollbackFailed changes are stashed (not lost) and the codebase reverts to the last good stateOn compilation failure
Scope restrictionOnly files within the Talome project root can be modified — no system files, no files outside the repoAlways enforced
One change at a timeThe AI cannot chain multiple apply_change calls without confirming each result with youAlways enforced
Audit trailEvery change is logged with full diff, timestamp, description, and success/failure statusAfter every apply
User confirmationapply_change is a destructive-tier tool — in the default "cautious" security mode, the AI asks before executingIn cautious mode
Detached workerThe apply process runs independently of the Talome server — if the server crashes during apply, the worker finishes and cleans upAlways

What Happens on Failure

Talome Assistant
apply_changeTypeScript compilation FAILED: TS2345 type mismatch in sidebar.tsx

Applying changes to apps/dashboard/src/components/sidebar.tsx... TypeScript validation failed with error TS2345: Argument of type string is not assignable to parameter of type SidebarItem. Change failed. The modification was automatically stashed (git stash). Your codebase is back to the last working state. The stash can be inspected with: git stash show -p. I need to fix the type mismatch. The SidebarItem type expects an object, but I passed a string. Let me revise the approach.

The failed change is never lost — it's in the git stash. But your running codebase is never broken.

Supervisor Protection

After a self-improvement change is applied and the backend restarts, the supervisor monitors whether the new code is stable:

  1. 60-second grace period — immediately after a code change restart, crashes are tolerated without escalation. Transient startup issues resolve themselves.
  2. Clean-tree awareness — if the working tree is clean (changes were committed), the supervisor falls through to AI diagnosis instead of uselessly stashing.
  3. Dashboard autofix — if the dashboard crashes with build errors, Claude Code attempts a fix automatically before reverting.
  4. Known-good safety — reverts never overwrite code that's ahead of the known-good tag, protecting committed improvements.

Recovering from a Revert

If the supervisor reverted your changes, they're in the git stash:

git stash list                    # see what was stashed
git stash show -p stash@{0}      # inspect the most recent stash
git stash pop stash@{0}          # restore it

What the AI Can Improve

Performance Optimizations

  • Database query efficiency (N+1 queries, missing indexes)
  • React render optimization (memoization, virtual scrolling)
  • API response caching
  • Docker API call batching
  • Bundle size reduction

Bug Fixes

  • Error handling for edge cases
  • Race conditions in async code
  • Type mismatches caught at runtime but not compile time
  • UI state inconsistencies

UI Enhancements

  • Layout improvements
  • Responsive design fixes
  • Accessibility improvements
  • New component variants
  • Theme adjustments

New Features

  • New API routes and tools
  • New dashboard pages and widgets
  • New integration tools for additional apps
  • Automation enhancements
  • Custom tool templates

Complete Transcript: Performance Fix

Here's an end-to-end example of the AI identifying and fixing a real performance issue:

Talome Assistant
The settings page takes forever to load

Let me investigate.

plan_changeDiagnose and fix settings page load performance
read_fileapps/core/src/routes/settings.ts
read_fileapps/dashboard/src/app/dashboard/settings/page.tsx

Found it. The settings page fetches ALL settings on mount, including binary blobs (custom SSL certificates, backup encryption keys) stored as base64. The /api/settings endpoint returns every row without filtering. For your 47 settings entries, 3 are binary blobs totaling 2.4 MB. The page only needs key-value pairs for text settings. Proposed change: add a type column filter to exclude binary settings from GET /api/settings, and add a separate GET /api/settings/:key endpoint for individual binary lookups. No frontend changes needed. This removes 2.4 MB from the response. Load time should drop from ~3 seconds to under 100ms. Apply?

Yes
apply_changeTypeScript compilation passed (0 errors)

Change applied. Modified apps/core/src/routes/settings.ts — added binary exclusion filter to GET /api/settings and added GET /api/settings/:key for individual lookups. Refresh the Settings page — it should load instantly now.

Much faster. Thanks.
rememberstored fact about settings page binary blob fix

Good. I have noted this fix in case a similar pattern shows up elsewhere in the codebase.

Custom Tool Creation

For runtime extensions that don't require modifying Talome's source code, use create_tool instead of apply_change.

When to Use create_tool vs. apply_change

Use create_tool WhenUse apply_change When
Adding a new capability at runtimeFixing a bug in existing code
The tool is specific to your setupThe change benefits all Talome users
You want to test without risk to core codeThe change touches existing files
Adding an integration with a niche appImproving performance of core features

How Custom Tools Work

Talome Assistant
Create a tool that checks my UPS battery status via NUT
create_toolcreated ups_battery_status, read tier, triggers: ups/battery/power

Created custom tool: ups_battery_status. Location: ~/.talome/custom-tools/ups-battery-status.ts. Triggers: "ups", "battery", "power". Tier: read. The tool calls your NUT server at 192.168.1.1:3493 and returns battery percentage, load, runtime remaining, and status. Test it: "What's my UPS battery status?"

Custom tools are written to ~/.talome/custom-tools/, loaded at runtime via jiti (a TypeScript-aware module loader), and automatically registered in the tool registry. They persist across restarts.

Dangerous patterns (eval, exec, filesystem writes outside allowed paths) are blocked during tool creation.

Issue Tracking

The AI has a built-in issue tracker for improvements and bugs:

Talome Assistant
Track an issue: the notification sound plays even when notifications are muted
track_issuetracked as issue #17, type=bug

Tracked as issue #17. I can fix this now or queue it for the next improvement session.

Issues appear on the Evolution page in the dashboard, where you can see all tracked bugs, feature requests, and their status.

Issue Types

TypePurpose
bugSomething that's broken
featureSomething new to build
improvementSomething existing to make better
performanceSomething that's too slow

Scheduling Improvements

Combine self-improvement with automations for overnight maintenance:

Talome Assistant
Create an automation that runs self-improvement every night at 3am. Focus on performance issues.
create_automationcreated: Nightly performance improvements, daily at 3 AM

Automation "Nightly performance improvements" created. It will run at 3:00 AM daily and attempt up to 3 performance fixes per session. Each change still goes through the full pipeline: plan, apply, tsc validation, commit or rollback.

Key Codebase Paths

When the AI plans a change, it reads from these locations:

What to ChangeWhere to Look
Backend API routesapps/core/src/routes/
AI agent behaviorapps/core/src/ai/agent.ts
Tool definitionsapps/core/src/ai/tools/
Database schemaapps/core/src/db/schema.ts
Dashboard pagesapps/dashboard/src/app/dashboard/
UI componentsapps/dashboard/src/components/
Shared typespackages/types/
App creationapps/core/src/creator/

Limitations

  • No files outside the project root — the AI cannot modify system files, home directory configs, or other repositories
  • No global package installsnpm install -g, brew install, or similar commands are blocked
  • No system-level changes — no modifying /etc/, no changing shell configs, no touching Docker daemon settings
  • TypeScript must pass — every single change is validated. There are no exceptions, no flags to skip it, no force-commit options
  • One change at a time — the AI must confirm each change's success before attempting the next. No batch modifications.
  • Destructive tierapply_change and rollback_change require confirmation in the default security mode

On this page