CodeHarbor is a self-hosted Matrix bot and AI chat bridge for codex and claude CLI.
Users send messages in Matrix rooms, CodeHarbor routes each request to the selected backend,
keeps room/session state in SQLite, and sends the final result back to the same room.
Maintainer: https://github.com/biglone Verified by CI:
Quick feedback:
- Questions/usage: https://github.com/biglone/CodeHarbor/discussions
- Bug report: https://github.com/biglone/CodeHarbor/issues/new?template=bug_report.yml
- Feature request: https://github.com/biglone/CodeHarbor/issues/new?template=feature_request.yml
- Release announcements (EN/δΈζ in one thread): #3
- Roadmap poll (EN/δΈζ in one thread): #4
- Matrix channel adapter (receive + reply)
- Session-to-backend mapping via persistent SQLite state
- One-time migration import from legacy
state.json - Duplicate Matrix event protection
- Context-aware trigger (DM direct chat + group mention/reply + active session window)
- Room-level trigger policy overrides
- Runtime backend switch:
/backend codex|claude|auto|status - Cross-backend context bridge on next request after switch
- Real
/stopcancellation (kills in-flight AI CLI process) - Session runtime workers (logical worker per
channel:room:user, with worker stats in/status) - Rate limiting + concurrency guardrails (user/room/global)
- Progress + typing updates with group notice coalescing (
m.replaceedit) - CLI-compat mode (
cli_compat_mode) for minimal prompt rewriting + raw event passthrough - Image attachment metadata passthrough from Matrix events into prompt context
- Voice attachment transcription (local Whisper/OpenAI fallback)
- Request observability (request_id, queue/exec/send durations, status counters)
- NPM-distributed CLI (
codeharbor)
Matrix Room -> MatrixChannel -> Orchestrator -> AI CLI Executor (codex/claude)
|
-> StateStore (SQLite)
- Primary runtime: TypeScript/Node (
src/,dist/,npm run ...) - Legacy/reference implementation: Python (
app/,tests/) - New features and fixes target the TypeScript runtime.
- Python code is kept as legacy reference only (maintenance mode).
- Node.js 22+
- AI CLI installed and authenticated:
- Codex:
codex login - Claude Code:
claude login
- Codex:
- A Matrix bot user + access token
Install globally from npm (after publish):
npm install -g codeharborLinux one-command install (creates /opt/codeharbor, sets ownership, installs latest package):
curl -fsSL https://raw.githubusercontent.com/biglone/CodeHarbor/main/scripts/install-linux.sh | bashLinux easy mode (install + write .env + enable/start systemd in one run):
curl -fsSL https://raw.githubusercontent.com/biglone/CodeHarbor/main/scripts/install-linux-easy.sh | bash -s -- \
--matrix-homeserver https://matrix.example.com \
--matrix-user-id @bot:example.com \
--matrix-access-token 'your-token'Install first, then enable systemd service with one command:
codeharbor service installInstall + enable main and admin services:
codeharbor service install --with-adminRestart installed service(s):
codeharbor service restart --with-adminRemove installed services:
codeharbor service uninstall --with-adminNotes:
- Service commands auto-elevate with
sudowhen root privileges are required. codeharbor service install --with-adminandinstall-linux-easy.sh --enable-admin-servicenow install/etc/sudoers.d/codeharbor-restartfor non-root service users, so Admin UI restart actions work out-of-box.npm install -g codeharbor@latestnow performs best-effort restart for activecodeharbor(.service)units on Linux so upgrades take effect immediately (setCODEHARBOR_SKIP_POSTINSTALL_RESTART=1to disable).- If your environment blocks interactive
sudo, use explicit fallback:sudo <node-bin> <codeharbor-cli-script> service ...
Enable Admin service at install time:
curl -fsSL https://raw.githubusercontent.com/biglone/CodeHarbor/main/scripts/install-linux-easy.sh | bash -s -- \
--matrix-homeserver https://matrix.example.com \
--matrix-user-id @bot:example.com \
--matrix-access-token 'your-token' \
--enable-admin-service \
--admin-token 'replace-with-strong-token'Run local script with custom options:
./scripts/install-linux.sh --app-dir /srv/codeharbor --package codeharbor@0.1.1 --initRuntime home behavior:
- By default, all
codeharborcommands use~/.codeharborfor.envand relative data paths. - Backward compatibility: if
/opt/codeharbor/.envalready exists, it continues to be used automatically. - No manual
cdis required after installation. - To use a custom runtime directory, set
CODEHARBOR_HOME(for exampleexport CODEHARBOR_HOME=/srv/codeharbor).
Install directly from GitHub:
npm install -g github:biglone/CodeHarborBuild a local package tarball and install it:
npm pack
npm install -g ./codeharbor-<version>.tgzShow CLI help:
codeharbor --help
codeharbor admin --help
codeharbor config --help
codeharbor service --helpCommon in-chat control commands:
/helpshow command help- if Matrix client intercepts slash commands, send escaped form like
//autodev run T6.2(also supports//agents,//diag,//upgrade) /statusshow session status, version/update hint, latest upgrade result + recent upgrade ids + upgrade metrics/lock, and runtime metrics/versionforce-refresh latest version check/diag versionshow runtime version diagnostics (pid/start time/bin path/backend)/diag media [count]show multimodal diagnostics (image/audio counters + recent records)/diag upgrade [count]show upgrade diagnostics (distributed lock, aggregate stats, recent upgrade records)/diag route [count]show backend routing diagnostics (rule hit/fallback reason + recent route records)/diag autodev [count]show AutoDev diagnostics (stage trace, live loop snapshot, and recent git commit records)/diag queue [count]show recoverable queue diagnostics (pending/running/retry/failure archive)/upgrade [version]run self-update and auto-restart service from Matrix chat- auth priority:
MATRIX_UPGRADE_ALLOWED_USERS>MATRIX_ADMIN_USERS> any DM user (when both empty) - supports hardened systemd (
NoNewPrivileges=true) by using signal-based restart fallback
- auth priority:
/backend codex|claude|auto|statusswitch or inspect active AI backend (autorestores rule-based routing)/resetclear current conversation context/stopcancel current running request
CodeHarbor supports auto publish to npm from GitHub Actions.
Setup once:
- Configure npm Trusted Publishing for this repository/workflow (preferred):
- npm package settings -> Trusted publishing -> Add publisher
- Provider: GitHub Actions
- Repository:
biglone/CodeHarbor - Workflow file:
.github/workflows/release-npm.yml
- Optional fallback: set repository secret
NPM_TOKEN(npm automation token). - Push to
mainwith a publish trigger commit message.
Trigger rules:
pushtomain+ commit message includes[publish-npm]-> run publish workflowpushtomain+ commit message includes bothreleaseand a semver version -> run publish workflow- examples:
release v0.1.1,chore: release 0.1.2
- examples:
workflow_dispatch-> manual publish from GitHub Actions UI
The workflow runs typecheck, test, test:e2e (Admin UI Playwright), build, node dist/cli.js --help, npm pack --dry-run, then publishes with:
npm publish --provenance --access publicAuth mode selection:
- If
NPM_TOKENsecret exists: publish with token. - If
NPM_TOKENis absent: publish via npm Trusted Publishing (OIDC).
If the same package version already exists on npm, publish is skipped automatically.
Release checklist (recommended):
- Update
CHANGELOG.mdwith a new version section and bullet-point release notes. - Update version in
package.json(npm version patch|minor|major). - Validate changelog entry:
npm run changelog:check
- Push to
mainwith[publish-npm]orrelease vX.Y.Zin commit message. - Verify workflow status in GitHub Actions.
- Verify package on npm:
npm view codeharbor versionRun e2e locally:
npm run test:e2eIf your machine has no system Chrome, run:
PLAYWRIGHT_USE_SYSTEM_CHROME=false npm run e2e:install
PLAYWRIGHT_USE_SYSTEM_CHROME=false npm run test:e2eREQUIREMENTS.md: current baseline + next-stage requirementsTASK_LIST.md: implementation task breakdown and statusdocs/USER_MANUAL_ZH.md: Chinese user manual (installation, configuration, verification)docs/COMPLETE_CONFIGURATION_GUIDE.md: end-to-end setup flow + full feature-to-config mappingdocs/CONFIG_UI_DESIGN.md: configuration UI MVP designdocs/CONFIG_CATALOG.md: consolidated configuration matrix (required/runtime/UI/effective timing)docs/MULTIMODAL_VERIFICATION_ZH.md: multimodal verification playbook (Codex/Claude image + audio transcription)docs/GROWTH_PLAYBOOK_ZH.md: growth and community feedback playbookdocs/SOCIAL_PREVIEW_UPLOAD_ZH.md: GitHub social preview image upload guidedocs/DISCUSSION_TEMPLATE_BILINGUAL.md: single-thread bilingual discussion templatedocs/ADMIN_STANDALONE_DEPLOY.md: standalone admin deployment and Cloudflare Tunnel exposure guidedocs/BACKUP_AUTOMATION.md: scheduled config backup and restore operationsdocs/RELEASE.md: release process and CI/publish policy
For local development from source:
- Install dependencies:
npm install- Configure environment:
export CODEHARBOR_HOME="$(pwd)"
codeharbor initRequired values:
MATRIX_HOMESERVERMATRIX_USER_IDMATRIX_ACCESS_TOKEN
- Run in dev mode:
export CODEHARBOR_HOME="$(pwd)"
npm run dev- Build and run as CLI:
npm run build
export CODEHARBOR_HOME="$(pwd)"
node dist/cli.js startUse this layered reference to avoid mixing boot-only and runtime tuning items:
It documents:
- which keys are required vs optional
- which keys can be edited in Admin UI
- whether changes are immediate or restart-scoped
- hot-update rollback paths (quick hot rollback vs full snapshot rollback)
- recommended profiles for local/internal/public deployment
- a complete setup sequence from install to production operations
codeharbor init: guided setup for.env(supports--forceto overwrite directly)codeharbor start: start servicecodeharbor doctor: check AI CLI and Matrix connectivitycodeharbor admin serve: start admin UI + config API servercodeharbor service install: install/enable systemd unit(s) after npm install (supports--with-admin)codeharbor service restart: restart installed systemd unit(s) (supports--with-admin)codeharbor service uninstall: remove installed systemd unit(s) (supports--with-admin)codeharbor config export: export current config snapshot as JSONcodeharbor config import <file>: import config snapshot JSON (supports--dry-run)npm run changelog:check: validateCHANGELOG.mdhas notes for current package versionscripts/install-linux.sh: Linux bootstrap installer (creates runtime dir + installs npm package)scripts/install-linux-easy.sh: one-shot Linux install + config + systemd auto-startscripts/backup-config.sh: export timestamped snapshot and keep latest N backupsscripts/install-backup-timer.sh: install/update user-level systemd timer for automatic backupsnpm run test:e2e: run Admin UI end-to-end tests (Playwright)
- Questions and usage help: GitHub Discussions (
Q&A) - Feature ideas: GitHub Discussions (
Ideas) orFeature requestissue template - Bug reports: use
Bug reportissue template for reproducible diagnostics - Contribution guide:
CONTRIBUTING.md - Growth and community playbook:
docs/GROWTH_PLAYBOOK_ZH.md
Create a timestamped snapshot in backups/config and keep latest 20 by default:
./scripts/backup-config.shCustom directory and retention:
./scripts/backup-config.sh --dir /var/backups/codeharbor --keep 30Install/update automatic backup timer:
./scripts/install-backup-timer.sh --schedule "*-*-* 03:30:00" --dir /var/backups/codeharbor --keep 30Full guide:
Start server:
codeharbor admin serveOptional overrides:
codeharbor admin serve --host 127.0.0.1 --port 8787If you bind Admin to a non-loopback host and both ADMIN_TOKEN and ADMIN_TOKENS_JSON are empty, startup is rejected by default.
Explicit bypass exists but is not recommended:
codeharbor admin serve --host 0.0.0.0 --allow-insecure-no-tokenOpen these UI routes in browser:
/or/settings/global/settings/rooms/health/audit
/health now includes a CodeHarbor app row with current version, latest version, and update availability.
Main endpoints:
GET /metrics(Prometheus exposition format)GET /api/admin/auth/statusGET /api/admin/config/globalPUT /api/admin/config/globalGET /api/admin/config/roomsGET /api/admin/config/rooms/:roomIdPUT /api/admin/config/rooms/:roomIdDELETE /api/admin/config/rooms/:roomIdGET /api/admin/healthGET /api/admin/audit?limit=50GET /api/admin/sessions?roomId=...&userId=...&from=...&to=...&limit=50&offset=0GET /api/admin/sessions/export?roomId=...&userId=...&from=...&to=...&limit=50&offset=0&includeMessages=trueGET /api/admin/sessions/:sessionKey/messages?limit=100GET /api/admin/history/retentionPUT /api/admin/history/retentionPOST /api/admin/history/cleanupGET /api/admin/history/cleanup/runs?limit=20
When ADMIN_TOKEN or ADMIN_TOKENS_JSON is set, requests must include:
Authorization: Bearer <ADMIN_TOKEN>Access control options:
ADMIN_TOKEN: require bearer token for/api/admin/*and/metricsADMIN_TOKENS_JSON: optional multi-token RBAC list (supportsadminandviewerroles)ADMIN_IP_ALLOWLIST: optional comma-separated client IP whitelist (for example127.0.0.1,192.168.1.10)ADMIN_ALLOWED_ORIGINS: optional CORS origin allowlist for browser-based cross-origin admin access
RBAC behavior:
viewertokens can call read endpoints (GET /api/admin/*andGET /metrics)admintokens can call read + write endpoints (PUT/POST/DELETE /api/admin/*)- for
ADMIN_TOKENS_JSON, audit actor is derived from token identity (actorfield), notx-admin-actor - Admin UI shows current permission status (role/source) after saving auth
Metrics quick check:
curl -H "Authorization: Bearer <ADMIN_TOKEN>" \
http://127.0.0.1:8787/metricsAutoDev metrics exported:
codeharbor_autodev_runs_total{outcome="succeeded|failed|cancelled"}codeharbor_autodev_loop_stops_total{reason="no_task|drained|max_runs|deadline|stop_requested|task_incomplete"}codeharbor_autodev_tasks_blocked_total
Alerting baseline:
- Example Prometheus alert rules:
docs/PROMETHEUS_ALERT_RULES_EXAMPLE.yml - Includes:
- high request failure ratio
- high queue wait p95
- recent upgrade failure detection
- AutoDev loop stop/block anomaly signals
Rotate tokens quickly (repository script):
./scripts/rotate-admin-token.sh --target rbac --role admin --actor ops-admin
./scripts/rotate-admin-token.sh --target rbac --role viewer --actor ops-auditNote: PUT /api/admin/config/global always writes .env; high-frequency whitelist keys hot-apply for new requests, while non-whitelist keys still require restart.
- Backup before change:
codeharbor config export -o backups/pre-hot-update.json- Fast rollback for hot-whitelist keys (
restartRequired=false):
- write previous value back via Admin UI, or call
PUT /api/admin/config/global - confirm response
hotAppliedKeyscontains expected key(s)
- Full rollback for mixed/restart-required changes:
codeharbor config import backups/pre-hot-update.json --dry-run
codeharbor config import backups/pre-hot-update.json
codeharbor service restart- Verify + audit:
GET /api/admin/audit?limit=20GET /api/admin/health- send one Matrix smoke request in each critical room
Boundary: hot updates affect new requests only; in-flight requests are not rolled back.
- Start server:
codeharbor admin serve. - Open
/settings/global, setAdmin Token(if enabled), then clickSave Auth. - Adjust global fields and click
Save Global Config(UI shows restart-required warning). - Use
Restart Main ServiceorRestart Main + Adminbuttons for one-click restart from Admin UI. If services were installed with--with-admin, restart permissions are auto-configured by installer. - Open
/settings/rooms, fillRoom ID + Workdir, thenSave Room. - Open
/healthto run connectivity checks (codex+ Matrix). - Open
/auditto verify config revisions (actor/summary/payload).
codeharbor admin serve can run as an independent service on target servers without browser/desktop.
Access can come from your local browser through a gateway (for example Cloudflare Tunnel).
See:
Before codeharbor start and codeharbor doctor, CodeHarbor runs a preflight check for:
- required Matrix env vars
- selected AI CLI binary availability (
AI_CLI_PROVIDER+CODEX_BIN) CODEX_WORKDIRvalidity.envpresence warning
If any check fails, it prints actionable fix commands (for example codeharbor init).
- Direct Message (DM)
- all text messages are processed by default (no prefix required)
- Group Room
- when
GROUP_DIRECT_MODE_ENABLED=true, all non-empty messages are processed directly (no prefix/mention/reply required) - processed when any allowed trigger matches:
- message mentions bot user id
- message replies to a bot message
- sender has an active conversation window
- optional explicit prefix match (
MATRIX_COMMAND_PREFIX)
- when
- Trigger Policy
GROUP_DIRECT_MODE_ENABLEDcontrols whether groups bypass trigger matching entirely- global defaults via
GROUP_TRIGGER_ALLOW_* - per-room overrides via
ROOM_TRIGGER_POLICY_JSON
- Active Conversation Window
- each accepted request activates the sender's conversation in that room
- activation TTL:
SESSION_ACTIVE_WINDOW_MINUTES(default:20)
- Control commands
/helpshow command cheat sheet for in-chat controls- if Matrix intercepts
/..., use escaped//...command form (for example//autodev run T6.2) /statusshow session + limiter + metrics + runtime worker status, current version, update hint, latest upgrade result, recent upgrade ids, upgrade metrics/lock, and update checked time (cached by TTL)/versionshow current package version and latest-update hint (force refresh)/diag versionshow runtime diagnostics (pid/start time/binary path/backend)/diag media [count]show multimodal diagnostics (image/audio counters + recent records)/diag upgrade [count]show distributed lock + aggregate stats + recent upgrade run diagnostics/diag route [count]show backend routing diagnostics (rule hit + fallback reason + recent route records)/diag autodev [count]show AutoDev diagnostics (stage trace + loop status + recent git commit records + error summary)/diag queue [count]show queue diagnostics (counts + pending sessions + failure archive)/upgrade [version]install latest (or specified) npm version and trigger service restart (DM only)- auth priority:
MATRIX_UPGRADE_ALLOWED_USERS>MATRIX_ADMIN_USERS> any DM user (when both empty) - includes service-context signal restart fallback when sudo escalation is unavailable
- auth priority:
/backend codex|claude|auto|statusswitch backend AI CLI tool at runtime (autorestores rule routing; next request auto-bridges recent local history)/resetclear bound Codex session and keep conversation active/stopcancel in-flight execution (if running) and reset session context/agents statusshow multi-agent workflow status for current session (when enabled)/agents run <objective>run Planner -> Executor -> Reviewer workflow (when enabled)/autodev statusshow AutoDev doc/task summary + currentTask/nextTask + run snapshot (when enabled)/autodev run [taskId]auto-pick pending task (or run specified task) fromTASK_LIST.md(when enabled)/autodev stopgraceful loop stop: finish current task, then stop before next task/autodev skills [on|off|summary|progressive|full|status]control role-skill injection and disclosure mode per session
Version update check controls:
PACKAGE_UPDATE_CHECK_ENABLED=true|false- enable/disable npm latest-version check used by
/status,/version, and Admin health app row
- enable/disable npm latest-version check used by
PACKAGE_UPDATE_CHECK_TIMEOUT_MS=3000- timeout (ms) for npm registry version lookup
PACKAGE_UPDATE_CHECK_TTL_MS=21600000- cache TTL (ms) for update-check results (
/statusreads cache;/versionforces refresh)
- cache TTL (ms) for update-check results (
MATRIX_ADMIN_USERS=@admin:example.com,@ops:example.com- optional Matrix admin list used as
/upgradepermission fallback whenMATRIX_UPGRADE_ALLOWED_USERSis empty
- optional Matrix admin list used as
MATRIX_UPGRADE_ALLOWED_USERS=@admin:example.com,@ops:example.com- optional explicit
/upgradeallowlist (higher priority thanMATRIX_ADMIN_USERS)
- optional explicit
CLI update helper:
codeharbor self-update- install latest npm package and attempt auto-restart for installed systemd service
AI CLI backend controls:
AI_CLI_PROVIDER=codex|claude- select runtime backend (
codexby default)
- select runtime backend (
CODEX_BIN=<path-or-command>- executable for selected provider (for example
codexorclaude)
- executable for selected provider (for example
CODEX_MODEL=<model>- optional model override for selected provider
CODEX_EXEC_TIMEOUT_MS- base timeout for one backend execution (default
600000) /agentsand/autodevusemax(CODEX_EXEC_TIMEOUT_MS, 1800000)per role to reduce long-task timeout loops
- base timeout for one backend execution (default
Cross-backend context bridge behavior:
- CodeHarbor stores recent local
user/assistantturns per Matrix session. - After
/backend codex|claude|auto, the next non-command request injects a[conversation_bridge]block so the new backend can continue with recent context. /resetand/stopexplicitly suppress this one-shot bridge on the immediate next request so users can start fresh.
Backend/model rule routing:
BACKEND_MODEL_ROUTING_RULES_JSON- optional JSON array rule engine for automatic backend/model selection per request
- conditions support
roomIds/senderIds/taskTypes/directMessage/textIncludes/textRegex - targets support
provider(codex|claude) and/ormodel; rules are evaluated bypriority(high -> low), then declaration order - when rule target cannot be instantiated (for example no
executorFactoryruntime), CodeHarbor falls back to default backend and marks status reason asfactory_unavailable
AGENT_WORKFLOW_ENABLED=true- enable
/agentsand/autodevworkflow commands
- enable
AGENT_WORKFLOW_AUTO_REPAIR_MAX_ROUNDS- reviewer reject loop upper bound (default
1)
- reviewer reject loop upper bound (default
AGENT_WORKFLOW_PLAN_CONTEXT_MAX_CHARS- optional planner-plan context char budget per role prompt (default: unlimited / no truncation)
AGENT_WORKFLOW_OUTPUT_CONTEXT_MAX_CHARS- optional executor/reviewer output context char budget per role prompt (default: unlimited / no truncation)
AGENT_WORKFLOW_FEEDBACK_CONTEXT_MAX_CHARS- optional reviewer feedback context char budget per repair prompt (default: unlimited / no truncation)
AGENT_WORKFLOW_ROLE_SKILLS_ENABLED=true|false- enable/disable Planner/Executor/Reviewer role-skill prompt injection (default
true)
- enable/disable Planner/Executor/Reviewer role-skill prompt injection (default
AGENT_WORKFLOW_ROLE_SKILLS_MODE=summary|progressive|full- role-skill disclosure mode (
progressivedefault: summary first round, full in later rounds/repair)
- role-skill disclosure mode (
AGENT_WORKFLOW_ROLE_SKILLS_MAX_CHARS- max chars for injected
[role_skills]block (default2400)
- max chars for injected
AGENT_WORKFLOW_ROLE_SKILLS_ROOTS- optional comma-separated local skill roots (default
~/.codex/skills)
- optional comma-separated local skill roots (default
AGENT_WORKFLOW_ROLE_SKILLS_ASSIGNMENTS_JSON- optional role-to-skill mapping override JSON (
planner/executor/reviewer->string[])
- optional role-to-skill mapping override JSON (
AUTODEV_LOOP_MAX_RUNS- max task attempts for one
/autodev runloop execution (default20)
- max task attempts for one
AUTODEV_LOOP_MAX_MINUTES- max wall-clock minutes for one
/autodev runloop execution (default120)
- max wall-clock minutes for one
AUTODEV_AUTO_COMMIT=true|false- enable/disable AutoDev git auto-commit after reviewer
APPROVED(defaulttrue)
- enable/disable AutoDev git auto-commit after reviewer
AUTODEV_MAX_CONSECUTIVE_FAILURES- when the same task fails repeatedly and reaches this threshold, mark it
π«blocked (default3)
- when the same task fails repeatedly and reaches this threshold, mark it
AutoDev (/autodev) conventions:
- Workspace must contain
REQUIREMENTS.mdandTASK_LIST.md. TASK_LIST.mdshould include task IDs and status markers (β¬,π,β,β,π«) in table rows or checklist rows./autodev run(without task id) loops through task list: selectsπfirst, thenβ¬, and keeps running until no executable task remains./autodev runloop is guarded byAUTODEV_LOOP_MAX_RUNSandAUTODEV_LOOP_MAX_MINUTES; reaching either limit stops safely with a summary notice./autodev run <taskId>runs only the specified task./autodev stopdoes not interrupt the current task; it stops loop scheduling after the current task completes./autodev skills ...controls role-skill injection (on|off) and disclosure mode (summary|progressive|full) for current session.- When reviewer verdict is
APPROVED, CodeHarbor updates the task status toβautomatically. - When reviewer verdict is
APPROVEDand the workdir is a clean Git repo, CodeHarbor auto-commits changes with a semantic subject:<type>(<scope>): <taskId> <task-summary>. - AutoDev commit body includes
Task,Changed-files, andGenerated-byfor traceability. - AutoDev result notice always includes git commit status and changed files (
git changed files). - If the same task fails consecutively and reaches
AUTODEV_MAX_CONSECUTIVE_FAILURES, CodeHarbor marks it asπ«and skips it in later loops. - If the repo is missing or already dirty before run, AutoDev skips commit and reports the reason in the result notice.
- When using
scripts/autodev-loop-runner.sh, a new trigger is skipped while any task is alreadyπin progress.
Default is disabled to keep legacy behavior unchanged.
To make IM behavior closer to local codex CLI interaction, enable:
CLI_COMPAT_MODE=true- preserve user prompt whitespace
- avoid stripping
@botmention text in prompt body - enable richer raw event passthrough summaries
CLI_COMPAT_PASSTHROUGH_EVENTS=true- emit raw event summaries from codex JSON stream
CLI_COMPAT_PRESERVE_WHITESPACE=true- keep incoming Matrix message body untrimmed for execution
CLI_COMPAT_DISABLE_REPLY_CHUNK_SPLIT=true|false- optionally send one full message chunk to Matrix without auto split
CLI_COMPAT_PROGRESS_THROTTLE_MS- lower update throttle for near-real-time progress
CLI_COMPAT_FETCH_MEDIA=true|false- download Matrix
mxc://media (image) to temp file and pass image context to backend
- download Matrix
CLI_COMPAT_IMAGE_MAX_BYTES- per-image max size guard (bytes), oversized images are skipped with user notice
CLI_COMPAT_IMAGE_MAX_COUNT- max number of images passed to backend in one request
CLI_COMPAT_IMAGE_ALLOWED_MIME_TYPES- comma-separated image MIME allowlist (
image/png,image/jpeg,...)
- comma-separated image MIME allowlist (
CLI_COMPAT_TRANSCRIBE_AUDIO=true|false- download Matrix
m.audioattachments and transcribe them into prompt context
- download Matrix
CLI_COMPAT_AUDIO_TRANSCRIBE_MODEL- OpenAI transcription model (default
gpt-4o-mini-transcribe)
- OpenAI transcription model (default
CLI_COMPAT_AUDIO_TRANSCRIBE_TIMEOUT_MS- timeout for each audio transcription request
CLI_COMPAT_AUDIO_TRANSCRIBE_MAX_CHARS- max transcript length appended to prompt for one attachment
CLI_COMPAT_AUDIO_TRANSCRIBE_MAX_RETRIES- retry count for local/OpenAI transcription failures (default
1)
- retry count for local/OpenAI transcription failures (default
CLI_COMPAT_AUDIO_TRANSCRIBE_RETRY_DELAY_MS- base retry delay between attempts
CLI_COMPAT_AUDIO_TRANSCRIBE_MAX_BYTES- skip transcription when attachment is larger than this size
CLI_COMPAT_AUDIO_LOCAL_WHISPER_COMMAND- optional local whisper command template (use
{input}placeholder for audio file path) - helper command shipped by package:
codeharbor-whisper-transcribe --input {input} --model small
- optional local whisper command template (use
CLI_COMPAT_AUDIO_LOCAL_WHISPER_TIMEOUT_MS- timeout for local whisper command execution
CLI_COMPAT_RECORD_PATH=/abs/path/records.jsonl- append executed prompts as JSONL for replay benchmarking
Note: execution still uses codex exec/resume per request; compatibility mode focuses on behavior parity and reduced middleware interference.
STATE_DB_PATH=data/state.db- SQLite store for sessions + processed event ids
STATE_PATH=data/state.json- legacy JSON source for one-time migration import when SQLite is empty
MAX_SESSION_AGE_DAYS=30- prune stale sessions by age
MAX_SESSIONS=5000- prune least-recently-updated sessions when over limit
RATE_LIMIT_WINDOW_SECONDSRATE_LIMIT_MAX_REQUESTS_PER_USERRATE_LIMIT_MAX_REQUESTS_PER_ROOMRATE_LIMIT_MAX_CONCURRENT_GLOBALRATE_LIMIT_MAX_CONCURRENT_PER_USERRATE_LIMIT_MAX_CONCURRENT_PER_ROOM
Set a value to 0 to disable a specific limiter.
Use these to align runtime with your terminal CLI profile:
CODEX_SANDBOX_MODECODEX_APPROVAL_POLICYCODEX_EXTRA_ARGSCODEX_EXTRA_ENV_JSON
When image attachments are present and CLI_COMPAT_FETCH_MEDIA=true, CodeHarbor will:
- download
mxc://media to a temp file - apply image policy guardrails (
CLI_COMPAT_IMAGE_MAX_BYTES,CLI_COMPAT_IMAGE_MAX_COUNT,CLI_COMPAT_IMAGE_ALLOWED_MIME_TYPES) - for Codex backend, pass local file paths as
--image - for Claude backend, use stream-json input with base64 image blocks
- if Claude image input fails, auto-retry once without image blocks and notify user
- best-effort cleanup temp files after the request
- optional prompt record append (
CLI_COMPAT_RECORD_PATH) for deterministic replay input
When audio attachments are present and both CLI_COMPAT_FETCH_MEDIA=true and CLI_COMPAT_TRANSCRIBE_AUDIO=true, CodeHarbor will:
- download
m.audiomedia to a temp file - skip oversized audio files based on
CLI_COMPAT_AUDIO_TRANSCRIBE_MAX_BYTES - if
CLI_COMPAT_AUDIO_LOCAL_WHISPER_COMMANDis configured, execute local whisper first - if local whisper fails and
OPENAI_API_KEYis available, fallback to OpenAI transcription API - retry transient failures using
CLI_COMPAT_AUDIO_TRANSCRIBE_MAX_RETRIES - append transcript to
[audio_transcripts]prompt block - continue request even if transcription fails (warn log + no transcript)
- best-effort cleanup temp files after the request
OPENAI_API_KEY is optional when local whisper command is configured, and required only for OpenAI fallback.
For codeharbor-whisper-transcribe, install runtime first: python3 -m pip install faster-whisper.
Replay recorded prompts directly against codex CLI to quantify drift and latency:
npm run replay:cli-compat -- --input data/cli-compat-record.jsonl --out data/replay-report.json --max 50Useful flags:
--model <name>--workdir <path>--timeout-ms <n>--sandbox <mode>--approval <policy>--dangerous
MATRIX_PROGRESS_UPDATES=true- emit stage progress updates (for example reasoning/thinking snippets)
MATRIX_PROGRESS_MIN_INTERVAL_MS=2500- minimum interval between progress updates
MATRIX_TYPING_TIMEOUT_MS=10000- typing indicator timeout; CodeHarbor refreshes typing state while handling a request
- Group rooms use notice edit (
m.replace) to coalesce progress and reduce spam. - Reply chunking is paragraph/code-block aware to avoid cutting fenced blocks when possible.
npm run typecheck
npm test
npm run build
npm run test:legacyIf Python legacy dependencies are missing, install them first:
python3 -m pip install -r requirements.txt- Legacy Python runtime exists in
app/andtests/. - It is not part of default release/CI gates.
- Use
npm run test:legacyfor optional regression checks.