Skip to content

Gatsby1s/ai-chat-interface

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

9 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Claude Code Task Panel

A local-first web control panel for scheduling, running, and auditing recurring Claude Code and script tasks.

This project started as a small AI chat interface and has evolved into a desktop-style operations console for maintainers who keep lots of repeatable work in Markdown task files, shell scripts, and local automation jobs. It runs on your own machine, stores runtime state in SQLite, and is designed to stay on 127.0.0.1 unless you deliberately add your own authentication and network controls.

What It Does

  • Create recurring tasks from local task step files.
  • Run Markdown-based LLM tasks through the claude CLI.
  • Run local script tasks with shebang, .py, .sh, or direct executable resolution.
  • Group related tasks into folders and collapse or expand each group in the queue.
  • Switch the interface theme between system, light, and dark mode. The default is system.
  • Assign stable task codes such as T001, T002, and T003.
  • Schedule work with daily, interval, weekly, monthly, or cron expressions.
  • Trigger tasks manually from the UI or CLI.
  • Inspect recent runs, task-specific run history, stdout and stderr logs, and verification details.
  • Retry failed LLM tasks through a watchdog flow.
  • Resume Claude Code sessions from previous LLM runs.
  • Manage macOS LaunchAgents from the same local console.
  • View LaunchAgent stdout and stderr tails with explicit empty, missing, and unavailable log states.
  • Protect local state-changing routes from cross-site writes.

Screens

The first screen is the actual task console, not a marketing page. It contains:

  • A task queue with status filters, folder chips, and collapsible groups.
  • A run log panel for the selected task.
  • Scheduler, watchdog, and LaunchAgent status summaries.
  • A task editor for LLM and script tasks.
  • A macOS LaunchAgent inventory panel with search, scope filters, actions, and log viewing.
  • A display-mode control for system, light, and dark theme selection.

Requirements

  • macOS, for the LaunchAgent management features.
  • Node.js 18 or newer.
  • npm.
  • Claude Code CLI on PATH if you want to run LLM tasks.
  • Any interpreters required by your script tasks, such as python3, sh, or custom executables.

The basic web UI and SQLite-backed task storage work without Claude Code, but LLM task execution requires the claude CLI to be available to the backend process.

Quick Start

git clone https://github.com/Gatsby1s/ai-chat-interface.git
cd ai-chat-interface/backend
npm install
npm run db:init
npm run dev

Open the local console:

http://127.0.0.1:3000

There is also a convenience script at the repository root:

./start.sh

The script installs backend dependencies when needed, initializes the database when missing, seeds sample data on first setup, and starts the server.

Configuration

The backend loads environment files in this order:

  1. backend/.env
  2. backend/.env.local, overriding values from backend/.env

Create one of those files from the example:

cd backend
cp ../.env.example .env

Supported variables:

Variable Default Purpose
HOST 127.0.0.1 Interface bind host. Keep this loopback-only for normal use.
PORT 3000 Interface port.
ANTHROPIC_BASE_URL empty Optional override passed through the runtime environment.
ANTHROPIC_AUTH_TOKEN empty Optional auth token passed through the runtime environment.
ANTHROPIC_MODEL empty Optional model override for services that use it.

Real .env* files are ignored by git. Do not commit local tokens, database files, logs, or personal task paths.

How Tasks Work

Each task has:

  • execution_mode: llm or script
  • task_path: a local Markdown task file or script path
  • group_name: optional folder label used by the UI
  • schedule fields
  • status and recent run metadata
  • an automatically assigned stable code

LLM Tasks

LLM tasks read a local task step file and pass its contents to the claude CLI. The executor builds a prompt that includes:

  • the source task file path
  • the stable task code or task label
  • the task file content

It then runs:

claude -p --session-id <generated-session-id> <prompt>

The backend stores the generated Claude session ID and the source directory so the UI can offer a resume command later:

cd '<task-directory>' && claude --resume '<session-id>'

LLM scheduled tasks are scanned by the running Node.js server once per minute.

Script Tasks

Script tasks execute a local script or executable directly from the backend. Resolution order:

  1. Use the script shebang if present.
  2. Use python3 for .py files.
  3. Use sh for .sh files.
  4. Execute the path directly for other files.

Script tasks can also define:

  • working_directory
  • script_args, stored as an array

Scheduled script tasks are scanned by a macOS LaunchAgent once per minute. The app writes and reconciles this LaunchAgent automatically when script tasks are created, updated, enabled, disabled, or deleted.

Schedule Types

The scheduler supports:

Type Payload field Example
daily daily_time 09:00
interval interval_hours 6
weekly weekly_days and daily_time Mondays, Wednesdays, and Fridays at 09:30
monthly monthly_day and daily_time day 1 at 08:00
cron cron_expr */15 * * * *

Weekly day values use numbers from 0 to 6. The CLI accepts comma-separated weekdays in the same form used by the backend.

CLI

Run commands from the backend directory:

cd backend

List tasks:

npm run tasks:cli -- list

Create a daily LLM task:

npm run tasks:cli -- create llm ~/tasks/check-panel.md daily 09:00

Create a cron-based LLM task:

npm run tasks:cli -- create llm ~/tasks/check-panel.md cron "*/15 * * * *"

Create a weekly script task:

npm run tasks:cli -- create script ~/bin/daily-report.sh weekly 1,3,5@09:30 ~/projects/report-job '["--dry-run"]'

Update a task:

npm run tasks:cli -- update <taskId> script ~/bin/daily-report.sh cron "0 9 * * 1-5" ~ '["--env","prod"]'

Run a task immediately:

npm run tasks:cli -- run <taskId>

Toggle a task:

npm run tasks:cli -- toggle <taskId>

Delete a task:

npm run tasks:cli -- delete <taskId>

The CLI accepts an optional base URL as the first argument:

node src/cli/tasks-cli.js http://127.0.0.1:4000 list

API Overview

All API routes are served under /api.

Tasks

Method Route Purpose
GET /api/tasks List tasks.
POST /api/tasks Create a task.
PUT /api/tasks/:id Update a task.
DELETE /api/tasks/:id Move a task to the recycle bin.
POST /api/tasks/:id/restore Restore a deleted task.
DELETE /api/tasks/:id/permanent Permanently delete a task.
POST /api/tasks/:id/toggle Enable or disable a task.
POST /api/tasks/:id/run Run a task immediately.
POST /api/tasks/:id/open-session Open the latest resumable Claude session.
GET /api/tasks/:id/runs List runs for one task.

Example:

curl -s http://127.0.0.1:3000/api/tasks | jq

Create a task:

curl -s http://127.0.0.1:3000/api/tasks \
  -H 'Content-Type: application/json' \
  -d '{
    "execution_mode": "llm",
    "task_path": "~/tasks/check-panel.md",
    "group_name": "Maintenance",
    "schedule_type": "daily",
    "daily_time": "09:00",
    "enabled": true
  }' | jq

Runs, Watchdog, and App LaunchAgent

Method Route Purpose
GET /api/runs/recent?limit=10 List recent runs.
GET /api/runs/:id Get one run.
GET /api/runs/:id/log Read a run log and log status.
POST /api/runs/:id/open-session Open a resumable Claude session for a run.
GET /api/watchdog/status Read scheduler, watchdog, and app LaunchAgent state.
POST /api/watchdog/run Trigger the watchdog immediately.
GET /api/launchd/status Read the app-owned script scheduler LaunchAgent state.
POST /api/launchd/reconcile Reconcile the app-owned script scheduler LaunchAgent.

System LaunchAgents

Method Route Purpose
GET /api/system-launch-agents?scope=user List LaunchAgents.
GET /api/system-launch-agents/:label Inspect one LaunchAgent.
GET /api/system-launch-agents/:label/log?type=stdout Read stdout or stderr tail.
POST /api/system-launch-agents/:label/bootstrap Bootstrap a LaunchAgent.
POST /api/system-launch-agents/:label/bootout Boot out a LaunchAgent.
POST /api/system-launch-agents/:label/kickstart Kickstart a LaunchAgent.
POST /api/system-launch-agents/:label/enable Enable a LaunchAgent.
POST /api/system-launch-agents/:label/disable Disable a LaunchAgent.

Scopes:

  • user: ~/Library/LaunchAgents
  • global: /Library/LaunchAgents
  • all: both locations

The control panel protects its own app-related LaunchAgent labels. Destructive actions against protected labels require force=true.

Runtime Data

The application writes local runtime state under backend/data/.

Path Purpose
backend/data/chat.db SQLite database.
backend/data/logs/ Per-task logs and LaunchAgent logs.
backend/data/.gitkeep Keeps the runtime directory in git.

The database and logs are intentionally ignored by git.

Project Layout

.
+-- backend/
|   +-- package.json
|   +-- src/
|       +-- cli/                 # HTTP task CLI and script runner
|       +-- config/              # env loading, paths, task file resolution
|       +-- routes/              # Express API routes
|       +-- services/            # schedulers, executors, LaunchAgent services
|       +-- utils/               # SQLite initialization and schedule helpers
+-- frontend/
|   +-- index.html
|   +-- app.js
|   +-- styles.css
+-- SETUP.md
+-- LICENSE
+-- README.md

Security Model

This is a local control panel for running commands on your machine. Treat it as a privileged local operations tool.

Important defaults:

  • The server binds to 127.0.0.1 by default.
  • Cross-site state-changing requests are blocked using Origin, Referer, and Fetch Metadata checks.
  • Runtime secrets and local state are ignored by git.
  • The UI warns through structure rather than pretending LaunchAgent operations are harmless.

Do not expose this service directly to the public Internet. If you want remote access, put it behind authentication, TLS, and a network boundary you control.

Development

Install dependencies:

cd backend
npm install

Initialize or migrate the SQLite database:

npm run db:init

Start the local server:

npm run dev

Static frontend files are served directly from frontend/ by the Express server. There is no separate frontend build step.

Useful syntax checks:

node --check src/server.js
node --check src/cli/tasks-cli.js
node --check ../frontend/app.js

Troubleshooting

The server cannot start

If port 3000 is already in use, either stop the existing server or change the port:

PORT=4000 npm run dev

The database is missing

Run:

npm run db:init

LLM tasks fail immediately

Confirm that the Claude Code CLI is installed and available to the backend process:

which claude
claude --version

Also confirm that your local Claude credentials and environment are configured outside this repository.

Script tasks do not run on schedule

Check the app-owned LaunchAgent status:

curl -s http://127.0.0.1:3000/api/launchd/status | jq

Then reconcile it:

curl -s -X POST http://127.0.0.1:3000/api/launchd/reconcile | jq

Scheduled script tasks require macOS LaunchAgent support and at least one enabled script task.

A LaunchAgent action is blocked

Some app-owned labels are protected so the control panel does not accidentally disable its own scheduler or host process. If you deliberately need to operate on a protected label, pass force=true after reviewing the target.

Roadmap Ideas

  • Authentication for remote deployment scenarios.
  • Import and export of task definitions.
  • Better cron preview and next-run explanations.
  • Pluggable executors beyond Claude Code and local scripts.
  • Built-in test fixtures for scheduler edge cases.

License

MIT. See LICENSE.

About

Local Claude Code task scheduler and control panel

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors