CodeHarbor is a self-hosted Matrix bot and AI chat bridge for codex, claude, and gemini 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
- Latest release notes: docs/releases/v0.1.105-release-notes.md
- Latest bilingual announcement: docs/releases/v0.1.105-announcement-bilingual.md
- v0.1.105 notes: docs/releases/v0.1.105-release-notes.md
- v0.1.105 announcement (EN/δΈζ): docs/releases/v0.1.105-announcement-bilingual.md
- v0.1.104 notes: docs/releases/v0.1.104-release-notes.md
- v0.1.104 announcement (EN/δΈζ): docs/releases/v0.1.104-announcement-bilingual.md
- v0.1.103 notes: docs/releases/v0.1.103-release-notes.md
- v0.1.103 announcement (EN/δΈζ): docs/releases/v0.1.103-announcement-bilingual.md
- v0.1.102 notes: docs/releases/v0.1.102-release-notes.md
- v0.1.102 announcement (EN/δΈζ): docs/releases/v0.1.102-announcement-bilingual.md
- v0.1.69 notes: docs/releases/v0.1.69-release-notes.md
- v0.1.69 announcement (EN/δΈζ): docs/releases/v0.1.69-announcement-bilingual.md
- 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|gemini [model] | /backend 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)
- Semantic file-delivery intent (for example: βζηζη xxx ζδ»Άειη»ζβ)
- Request observability (request_id, queue/exec/send durations, status counters)
- NPM-distributed CLI (
codeharbor)
Matrix Room -> MatrixChannel -> Orchestrator -> AI CLI Executor (codex/claude/gemini)
|
-> 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 - Gemini CLI:
gemini
- Codex:
- A Matrix bot user + access token
Install globally from npm (after publish):
npm install -g codeharborRecommended npm package lifecycle (install/upgrade/verify):
# install latest
npm install -g codeharbor@latest
# verify installed version
codeharbor --version
# upgrade helper (installs latest + restart strategy)
codeharbor self-updateSystemd multi-instance example (Linux):
codeharbor service install --instance bot-a --runtime-home /srv/codeharbor-bot-a --with-admin
codeharbor service install --instance bot-b --runtime-home /srv/codeharbor-bot-b --with-adminLinux 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 per platform:- Linux: active
codeharbor*.servicesystemd units (including multi-instance units) - macOS: configured launchd labels (
CODEHARBOR_LAUNCHD_MAIN_LABEL,CODEHARBOR_LAUNCHD_ADMIN_LABEL) - Windows: safe fallback (prints manual PowerShell restart commands)
- set
CODEHARBOR_SKIP_POSTINSTALL_RESTART=1to disable postinstall restart attempts.
- Linux: active
- 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, use escaped
//...form for all slash controls (for example//status,//version,//diag queue 5,//diag limiter 5,//upgrade,//autodev init StrawBerry,//autodev run T6.2) /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)/diag limiter [count]show limiter diagnostics (shared mode + denial ratio + recovery latency + recent decision records)/trace <requestId|latest>show one-request trace (prompt/progress/reply + related workflow/media events;latestresolves the newest request in current session)- Chat final reply includes
requestIdfooter so you can copy it directly for/trace.- access is restricted to the same session sender or Matrix admin user
/upgrade [version]run self-update and auto-restart service from Matrix DM only- auth priority:
MATRIX_UPGRADE_ALLOWED_USERS>MATRIX_ADMIN_USERS> any DM user (when both empty) - supports Linux systemd signal restart fallback, macOS launchd/manual fallback, and Windows safe manual fallback
- emits structured success/failure summary with rollback and restart command templates
- auth priority:
/backend codex|claude|gemini [model] | /backend auto|statusswitch or inspect active AI backend (autorestores rule-based routing)/resetclear current conversation context and suppress one-shot history bridge on the next request/stopcancel current running request (or queue the stop), clear session context, and drop pending queued tasks for this session- aliases:
/cancel,/esc,/ζ€ε,/ζ€ι
- aliases:
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 the same checks as npm run release:verify (changelog + docs guards, typecheck, lint, unit tests, coverage, Admin UI Playwright, build, CLI smoke, package 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 and the workflow prints a suggested next patch version.
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). - Run release verification:
npm run release:verify
- Push to
mainwith[publish-npm]orrelease vX.Y.Zin commit message. - Verify workflow status in GitHub Actions.
- Verify package on npm:
npm view codeharbor versionIf release CI fails before npm publish, keep the same version and retry publish after fixing CI. Do not skip to the next version number.
Run e2e locally:
npm run test:e2eIf your machine has no system Chrome, install Playwright Chromium once. The test config will then automatically fall back to the bundled browser:
npm run e2e:install
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 versionnpm run docs:check-consistency: validate README/REQUIREMENTS/TASK_LIST version and Node requirement syncnpm run release:verify: run release-grade local verification before publishscripts/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; auto-uses system Chrome when available, otherwise bundled Chromium)
- 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/bots/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/globalGET /api/admin/config/skillsPUT /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/bot-profilesPUT /api/admin/bot-profilesPOST /api/admin/bot-profiles/migrate(single-instance -> primary-bot migration, supportsdryRun,force,profileId)POST /api/admin/bot-profiles/apply(supportsdryRun,includeDisabled,instanceIds,retireDefaultSingleInstance)GET /api/admin/healthGET /api/admin/audit?limit=50&kind=config|operations|all&surface=admin|api|webhook&outcome=allowed|denied|error&actor=...&source=...&action=...&method=GET&pathPrefix=/api/...&reasonContains=...&createdFrom=...&createdTo=...GET /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
GET /api/admin/config/skills returns a read-only snapshot for role-skill management:
- effective
agentWorkflow.roleSkillsconfig catalog.availableSkills(builtin + discovered local skills)catalog.missingAssignments(per-role unresolved skill ids)
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 (supportsadmin/viewerrole defaults and customscopes)API_TOKEN_SCOPES_JSON: optional API token scope override (JSON array, for example["tasks.submit.api"]or["tasks.read.api"])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 accessEXTERNAL_INTEGRATION_*: optional outbound callback config for API/webhook lifecycle + ticket sync (queued/executing/retrying/completed/failed)
RBAC behavior:
viewerrole defaults:admin.read+metrics.read(broad read compatibility)adminrole defaults:admin.read+metrics.read+admin.write- optional
scopesinADMIN_TOKENS_JSONoverrides role defaults for that token (supports patterns likeadmin.read.audit,admin.write.config.*,*) - API token defaults to broad compatibility scopes
tasks.submit+tasks.read;API_TOKEN_SCOPES_JSONcan narrow it to submit-only/read-only - legacy broad scopes (
admin.read,admin.write,tasks.submit,tasks.read,webhook.ingest) still authorize new fine-grained actions for backward compatibility - 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
External integration callbacks:
- inbound
POST /api/webhooks/ci|ticketrequests are normalized intoexternalContextand persisted into queue payloads - when
EXTERNAL_INTEGRATION_ENABLED=true, CodeHarbor emits non-blocking lifecycle callbacks with short-timeout retries (EXTERNAL_NOTIFY_WEBHOOK_URL) - optional ticket callback (
EXTERNAL_TICKET_WEBHOOK_URL) is emitted only for ticket-source tasks - delivery failures never block task execution; outcomes are written into operation audit logs (
source=integration:notify|ticket)
Operation audit behavior:
kind=config(default): configuration revision audit entrieskind=operations: authorization and operation outcomes for Admin/API/Webhook (allowed/denied/error)kind=all: merged timeline of config + operation audit entries (sorted by latest first)- operation entries support additional filters:
actor,source,action,method,pathPrefix,reasonContains,createdFrom,createdTo
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
Limiter metrics exported:
codeharbor_rate_limiter_decisions_total{source="local|shared|shared_fallback",outcome="allowed|denied"}codeharbor_rate_limiter_denied_total{reason="..."}codeharbor_rate_limiter_rejection_ratiocodeharbor_rate_limiter_shared_mode{mode="local|redis"}codeharbor_rate_limiter_shared_errors_totalcodeharbor_rate_limiter_recovery_last_ms/codeharbor_rate_limiter_recovery_avg_ms
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-audit
./scripts/rotate-admin-token.sh --target rbac --role viewer --actor ops-audit --scopes admin.read.auth,admin.read.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. - Open
Global Settings -> Skills & Advanced:- click
Refresh SKILL catalogto review builtin/local skill IDs - check
Missing SKILLhint before saving role assignments
- click
- 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).
Recommended role split in group rooms:
main-hub: primary bot (isPrimary=true), can enablegroupDirectModeEnabled=truefor non-@ group messages.dev-main/review-guard: execution/review bots (isPrimary=false), keep group direct mode disabled to avoid cross-talk.
Migration from legacy single-instance:
- Open
/settings/bots. - Click
Migration Dry-Run(POST /api/admin/bot-profiles/migratewithdryRun=true). - Click
Migrate As Primary, thenApply Changes. - Optional: enable
Retire default single-instance servicesto disablecodeharbor.service/codeharbor-admin.service.
Safety boundaries:
groupDirectModeEnabledis rejected on non-primary profiles.- Direct mode requires an enabled primary profile (
isPrimary=true+enabled=true). - Migration returns actionable errors for conflicting primaries; use
force=trueonly when switching ownership intentionally.
Troubleshooting quick checks:
- Error
groupDirectModeEnabled requires an enabled primary profile: Set one profile toisPrimary=trueandenabled=true, or disable direct mode. - Migration blocked by existing primary:
Use another
profileIdor rerun migration withforce=trueafter confirming primary ownership switch. - Group messages no longer trigger without @:
Verify primary profile has
groupDirectModeEnabled=trueand profile changes were applied.
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 all slash controls (for example//status,//version,//diag queue 5,//diag limiter 5,//trace req-123,//trace latest,//upgrade,//autodev init StrawBerry,//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)/diag limiter [count]show limiter diagnostics (shared mode + rejection/recovery metrics + recent records)/trace <requestId|latest>show per-request trace (prompt/progress/reply + related workflow/media events; same-session sender/admin only;latest= current session latest)/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|gemini [model] | /backend auto|statusswitch backend AI CLI tool at runtime (autorestores rule routing; next request auto-bridges recent local history)/resetclear bound Codex session, keep conversation active, and suppress one-shot history bridge on the next request/stopcancel in-flight execution (or queue a pending stop when busy), reset session context, and clear pending queue tasks for current session- aliases:
/cancel,/esc,/ζ€ε,/ζ€ι
- aliases:
/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 reconcilereconcileTASK_LIST.mdtask states from recent AutoDev run records/autodev workdir|wd [path]|status|clearshow/set/clear AutoDev workdir override for current session/autodev init|i [path] [--from file]initializeREQUIREMENTS.md+TASK_LIST.md+docs/AUTODEV_TASK_COMPASS.mdin target project- short mobile-friendly flow:
//autodev init StrawBerry->//autodev run - omit
--fromto auto-discover design/spec docs in project; use--fromto force one source file
- short mobile-friendly flow:
/autodev skills [on|off|summary|progressive|full|status]control role-skill injection and disclosure mode per session
- Natural-language file delivery
- supports intent-style requests such as
ζηζη result.mp4 ζδ»Άειη»ζ - for contextual requests such as
θΏεδΈͺθ§ι’εη»ζorζι£δΈζΉι½εη»ζ, bot prefers model-driven structured delivery actions over the latest session artifact batch - for explicit file names/paths, bot still keeps direct rule-based fallback for safety and compatibility
- bot first resolves against the latest session artifact batch captured from recent AI-generated outputs, then falls back to matching local files under current room workdir
- supports batch requests such as
θΏεδΈͺθ§ι’ζδ»Άδ»₯ζΆζ―ηε½’εΌεη»ζorζηζηθ§ι’ι½εη»ζ, and sends multiple matched attachments sequentially - if no file name is specified (for example
ζηζηζδ»Άειη»ζ), bot picks the most recently updated file in workdir (with size guardrail)
- supports intent-style requests such as
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
CODEHARBOR_LAUNCHD_MAIN_LABEL=com.codeharbor.mainCODEHARBOR_LAUNCHD_ADMIN_LABEL=com.codeharbor.admin- optional launchd labels used by macOS upgrade/postinstall restart flow
CLI update helper:
codeharbor self-update- install latest npm package and run cross-platform restart strategy (Linux systemd / macOS launchd / Windows manual fallback)
- prints structured result summary with rollback + restart command templates for failure recovery
AI CLI backend controls:
AI_CLI_PROVIDER=codex|claude|gemini- select runtime backend (
codexby default)
- select runtime backend (
CODEX_BIN=<path-or-command>- executable for selected provider (for example
codex/claude/gemini)
- 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|gemini [model]or/backend 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.CONTEXT_BRIDGE_HISTORY_LIMITcontrols how many recent local turns are considered for bridge assembly.CONTEXT_BRIDGE_MAX_CHARScontrols the max bridge payload length (characters).
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|gemini) 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[]) - defaults map to install-ready builtin fallback skills; local skills with the same id override builtin entries automatically
- builtin fallback skill prompts are maintained in English for consistent global defaults
- default builtin assignment baseline:
- planner:
task-planner,requirements-doc,builtin-planner-core,dependency-analyzer - executor:
autonomous-dev,bug-finder,test-generator,builtin-executor-core,refactoring - reviewer:
code-reviewer,security-audit,builtin-reviewer-core,changelog-generator,commit-message
- planner:
- additional builtin fallbacks are also available for assignment override:
- planning/design:
api-designer,superpowers-workflow,brainstorming,planning-with-files - execution/testing:
performance-optimizer,auto-code-pipeline,migration-helper,tdd-workflow,webapp-testing,ui-ux-pro-max,pptx,ralph-loop - review/release:
commit-message,code-simplifier,multi-agent-code-review
- planning/design:
- optional role-to-skill mapping override JSON (
AUTODEV_LOOP_MAX_RUNS- max task attempts for one
/autodev runloop execution (default20,0= unlimited)
- max task attempts for one
AUTODEV_LOOP_MAX_MINUTES- max wall-clock minutes for one
/autodev runloop execution (default120,0= unlimited)
- 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_GIT_AUTHOR_NAME- git author name for AutoDev auto-commit/release commit (default
CodeHarbor AutoDev; empty falls back to default)
- git author name for AutoDev auto-commit/release commit (default
AUTODEV_GIT_AUTHOR_EMAIL- git author email for AutoDev auto-commit/release commit (default
autodev@codeharbor.local; empty falls back to default)
- git author email for AutoDev auto-commit/release commit (default
AUTODEV_AUTO_RELEASE_ENABLED=true|false- enable/disable AutoDev "big feature done -> release commit" flow (default
true)
- enable/disable AutoDev "big feature done -> release commit" flow (default
AUTODEV_AUTO_RELEASE_PUSH=true|false- push release commit automatically after local release commit (default
false)
- push release commit automatically after local release commit (default
AUTODEV_RUN_ARCHIVE_ENABLED=true|false- persist each
/autodev runexecution archive as local JSON (defaulttrue)
- persist each
AUTODEV_RUN_ARCHIVE_DIR- archive directory (relative to workdir or absolute path, default
.codeharbor/autodev-runs)
- archive directory (relative to workdir or absolute path, default
AUTODEV_STAGE_OUTPUT_ECHO_ENABLED=true|false- echo planner/executor/reviewer full stage output to Matrix during
/autodev run(defaulttrue)
- echo planner/executor/reviewer full stage output to Matrix during
AUTODEV_PREFLIGHT_AUTO_STASH=true|false- when git preflight detects a dirty worktree, auto-stash (
git stash --include-untracked) and continue run (defaultfalse)
- when git preflight detects a dirty worktree, auto-stash (
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_VALIDATION_STRICT=true|false- fail closed on validation gate when structured evidence is missing (
VALIDATION_STATUS/__EXIT_CODES__); defaultfalse
- fail closed on validation gate when structured evidence is missing (
AutoDev (/autodev) conventions:
- Architecture, control-chain, and troubleshooting handbook:
docs/AUTODEV_OPERATIONS_ZH.md. - Workspace must contain
REQUIREMENTS.mdandTASK_LIST.md. /autodev init|i [path] [--from file]scaffolds missing AutoDev files and binds workdir override for current session.- when
--fromis omitted, CodeHarbor auto-discovers design/spec docs and uses them to generate initial REQUIREMENTS/TASK_LIST templates. - init uses a 3-stage flow: Stage-A deterministic scaffold, Stage-B AI enhancement, Stage-C hard validation with fallback to Stage-A baseline on invalid output.
- Stage-B AI enhancement runs only when both
REQUIREMENTS.mdandTASK_LIST.mdwere generated in this init run (existing files are preserved). - if
pathis a project name (no/), CodeHarbor resolves both<room_workdir>/<name>and sibling<parent>/<name>. - when target path is missing/not-directory, init fails explicitly and keeps current workdir unchanged.
- when
/autodev workdir|wd [path]|status|clearinspects or changes session-level workdir override.TASK_LIST.mdshould include task IDs and status markers (β¬,π,β,β,π«) in table rows or checklist rows.TASK_LIST.mdtask status is system-managed by orchestrator; avoid manual edits and use/autodev reconcilewhen drift needs healing./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 pauses safely with a summary notice, and you can resume with/autodev run./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 reconcileperforms one-shot task-state reconciliation using recent AutoDev run records (useful after manual edits or interrupted sessions).- Loop guardrail rules:
AUTODEV_LOOP_MAX_RUNS=0means unlimited loop rounds.AUTODEV_LOOP_MAX_MINUTES=0means unlimited loop wall-clock time.- Hitting run/time limit is a safe pause (not hard failure): AutoDev prints remaining task summary and resume hint.
- Resume command is always
/autodev run(or/autodev run <taskId>for targeted rerun). /autodev run <taskId>is single-task mode and does not consume loop run/time budgets.- Recommended for long roadmap execution: set both loop limits to
0, and keepAUTODEV_MAX_CONSECUTIVE_FAILURES+ no-progress detection enabled as safety rails.
/autodev skills ...controls role-skill injection (on|off) and disclosure mode (summary|progressive|full) for current session./autodev content on|off|statuscontrols AutoDev stage output echo (planner/executor/reviewer content) for current session.- Task closes to
βonly when completion gate passes (reviewer approved + no explicit validation failure + auto-commit success when commit is required). - In strict mode (
AUTODEV_VALIDATION_STRICT=true), completion gate requires structured validation evidence (VALIDATION_STATUSand/or__EXIT_CODES__). - When workflow/reviewer execution succeeds but completion gate fails,
/autodev statusreportsrunState: completed_with_gate_failed(instead ofsucceeded). /autodev statusexposes validation observability fields:runValidationFailureClass,runValidationEvidenceSource, andrunValidationAt.- Validation fuse rule: if the same task hits the same
validationFailureClassconsecutively forAUTODEV_MAX_CONSECUTIVE_FAILURES, AutoDev stops and marks itπ«with next-action guidance. - When reviewer verdict is
APPROVEDand the workdir is a clean Git repo, CodeHarbor auto-commits changes with a semantic subject:<type>(<scope>): <business-summary> (<taskId>). - AutoDev commit intent uses a hybrid strategy: prefer reviewer
SUMMARY(role-skill output) when it matches the selected commit language; otherwise fall back to deterministic template inference. - Commit language policy: for a brand-new project (no history) the first AutoDev commit defaults to English; for existing projects, AutoDev follows the recent repository commit language trend.
- AutoDev commit body includes
Task-ID,Changed-files, andGenerated-byfor traceability. - AutoDev result notice always includes git commit status and changed files (
git changed files). - If
TASK_LIST.mdhas a dedicatedεεΈζ ε°section with rows like| T8.4 | v0.1.55 | ... |, AutoDev can create a follow-up release commit after task completion:release: vX.Y.Z [publish-npm](updatespackage.json/package-lock.json/CHANGELOG.md). - AutoDev release mapping parser only reads the
εεΈζ ε°section; keep community-priority/milestone tables in separate headings (for exampleη€ΎεΊδΌε ηΊ§ -> ε―ζ§θ‘ιη¨η’) to avoid ambiguous version parsing. - Current community roadmap milestones are aligned as:
T8.1~T8.3 -> v0.1.53~v0.1.54,T8.4~T8.5 -> v0.1.55~v0.1.56,T8.6 -> v0.1.57,T8.7~T8.8 -> v0.1.58~v0.1.59. - When CI detects that the target version already exists on npm, the release workflow skips publishing and prints
Suggested next versionto keep release flow idempotent. - 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
AUTODEV_PREFLIGHT_AUTO_STASH=true, dirty git preflight is auto-stashed and the run continues (stash ref is reported in notices). - If workflow attempts to edit
TASK_LIST.md, AutoDev rolls it back and fails completion gate withtask-list-policy-violated. - 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_ROOMRATE_LIMIT_SHARED_MODE=local|redisRATE_LIMIT_SHARED_REDIS_URL(required when shared mode isredis)RATE_LIMIT_SHARED_REDIS_KEY_PREFIXRATE_LIMIT_SHARED_REDIS_COMMAND_TIMEOUT_MSRATE_LIMIT_SHARED_REDIS_CONCURRENCY_TTL_MSRATE_LIMIT_SHARED_FALLBACK_TO_LOCAL=true|false
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_PROGRESS_DELIVERY_MODE=upsert|timelineupsertedits one progress notice in group chats;timelineappends progress notices
MATRIX_TYPING_TIMEOUT_MS=10000- typing indicator timeout; CodeHarbor refreshes typing state while handling a request
MATRIX_NOTICE_BADGE_ENABLED=true|false- enable/disable rich-message badge headers (
CodeHarbor ζη€Ί/CodeHarbor AI εε€)
- enable/disable rich-message badge headers (
- Group rooms default to notice edit (
m.replace) to coalesce progress and reduce spam (MATRIX_PROGRESS_DELIVERY_MODE=upsert). - 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.