New:Introducing Socket Scanning for VS Code Marketplace Extensions.Learn more →
Get Started

@profoundlogic/coderflow-server

Package Overview
Dependencies
Maintainers
1
Versions
356
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@profoundlogic/coderflow-server

AI Coder Server - Manages Docker containers for AI agent task execution

dev
npmnpm
Version
0.15.3-dev.10
Version published
Weekly downloads
1.3K
-9.3%
Maintainers
1
Weekly downloads
 
Created
Source

CoderFlow Server

CoderFlow is an enterprise platform that runs autonomous engineering agents inside your infrastructure. Instead of merely suggesting code, agents compile, test, validate, and fix legacy systems end-to-end — delivering verified, ready-to-commit results and 5–10x productivity gains.

CoderFlow:

  • Submits coding tasks to AI agents (Claude, Codex, Gemini) running in isolated Docker containers
  • Lets agents execute code, compile, test, and validate changes automatically
  • Supports both headless execution (submit once, review results later) and interactive sessions (work within containers for guided work)
  • Manages multi-repository workspaces with build pipelines and test suites
  • Allows developers to review, iterate, and approve changes before committing

Quick Start

Prerequisites

  • Linux host
  • Node.js 24
  • Docker — Install Docker Engine
  • Git

Install

npm install -g @profoundlogic/coderflow-server

Initialize

coder-server init mycompany-coder-setup
coder-server config set coder_setup_path mycompany-coder-setup
coder-server license set <your-license-key>
coder-server create-user --username=admin --email=admin@example.com --name="Admin User" --admin
coder-server start

Documentation

For complete installation instructions, configuration options, environment setup, and administration guides, see the full documentation:

CoderFlow Documentation — Installation Guide

For production browser traffic, CoderFlow can terminate TLS and serve HTTP/2 itself without another service. See the built-in HTTP/2 deployment guide. It uses the existing certificate settings and retains HTTP/1.1 on the same port for WebSockets and compatibility clients.

The default auto mode selects built-in HTTP/2 when both a TLS certificate and key are configured, and HTTP/1.1 otherwise. http_protocol http1 keeps HTTP/1.1 even with TLS and is the rollback control. Explicit http2 requires TLS. This applies only when CoderFlow terminates TLS itself; HTTPS terminated by an upstream Nginx or load balancer does not use this listener.

User activity reporting

Server Administration → Usage includes a User Activity History report and CSV export for the selected period and environment. It lists all current accounts (including zero-activity accounts) and former users with activity in the period. Active days use UTC. The last-activity column is limited to the selected period. The 7-day and 30-day filters provide weekly and monthly adoption views.

The report counts task creation and follow-up submissions using the recorded actor and event time, including follow-ups on older tasks. Known automation, review-loop events, and automatically created child/judge tasks are counted separately. Missing attribution and unknown sources appear in the unattributed count. Attributed API submissions are included: this is not proof that a human typed each request. Terminal interactions, logins, approvals, and time spent working are not measured. Counts indicate adoption, not productivity.

Activity is retained in usage-activity/ under the server data directory (SERVER_DATA_PATH, default ~/.coder/data). Task-container App Servers use their isolated runtime data directory instead. Include this directory in server backups. The ledger stores only task IDs, timestamps, user identity, environment, event type, and source; it does not store prompts, code, or task titles. Atomic per-task records retain previously captured events through task deletion and conversation rewinds. Repeated metadata saves do not add duplicate events. Deletion is refused if the activity record cannot be saved, so a retry can preserve it before removing the task.

Surviving loaded tasks are backfilled in the background after the host starts listening and when the report is requested, with historical coverage explicitly marked partial. Already-deleted or unloaded old tasks cannot be reconstructed by this backfill. Existing operational task statistics and drilldowns still describe loaded tasks; the separate activity report survives unloading and deletion. Activity has no automatic expiry and is retained until an operator removes the ledger. Do not edit it while the server is running; it has one writer process per server data directory.

Ledger failures are logged without failing server startup or an already saved task metadata update. The Usage page shows an activity-history error while continuing to display operational statistics. Refreshing retries reconciliation from surviving loaded tasks. Task deletion still requires a successful activity save. Displayed timestamps use the viewer's local time zone with a zone label; active-day counts and exported timestamps remain UTC.

Inactive task containers

The normal host cleanup stops inactive task containers after two hours by default. Set container_cleanup_hours in setup.json (fractional hours are supported), or use the legacy CONTAINER_CLEANUP_HOURS environment override. For CPU- or memory-constrained hosts, 0.5–1 hour is recommended; other installations keep the two-hour default unless explicitly configured. Pinned task containers retain a 48-hour inactivity grace before they are stopped.

idle_container_cleanup_hours (or IDLE_CONTAINER_CLEANUP_HOURS) sets a shorter grace for containers whose turn has finished and that nobody is attached to — no task-terminal WebSocket and no running App Server. It is unset by default, so behaviour does not change until an operator opts in, and a value longer than container_cleanup_hours is ignored rather than applied. Pinned containers keep their 48-hour grace even when this shorter threshold is set. Stopping such a container costs a restart on the next follow-up; leaving it running costs a share of the host for the whole linger window. 0.25 is a reasonable starting point on a busy host. A running, starting, or degraded App Server is active use and prevents inactivity stopping under both the shortened and standard thresholds. An attached browser task terminal has the same hard exclusion until its WebSocket closes. After a CoderFlow server restart, the initial cleanup pass first probes published ports from the shared inventory and reconstructs active App Server state, so a still-running preview is not stopped before its status page is opened. Cleanup re-probes those ports before every hard exclusion, and container stop/destroy events invalidate the matching state, so an old running record cannot retain an inactive container indefinitely.

Stopped task containers are removed after seven days by default. Set stopped_container_retention_days in setup.json, or use the STOPPED_CONTAINER_RETENTION_DAYS environment override. Finalized containers (approved and pushed, or losing task-group variants) are removed on the next cleanup cycle. Containers are retained while their task is still in an active or otherwise nonrecoverable state; the retention clock comes from the recorded stop, finish, or agent/container activity time, never task creation or a read-only task-page view. Pinning extends the running-container inactivity grace to 48 hours, but it does not prevent either automatic removal policy. On rollout, a stopped pinned container without a recorded stop time receives a one-time seven-day grace before any automatic removal, allowing its owner to mark it protected. Individual task containers can be protected from automatic removal from the task's More actions menu. Protection also applies to finalized containers, but it does not prevent inactivity stopping, explicit removal, or task deletion, and it is not inherited by forks. A removed task can still be continued as a fork in a new container from its saved history, although unsaved container-only state is not recoverable.

Cleanup removes at most 50 eligible containers and admits new Docker operations for at most 30 seconds per cycle, oldest first; already-admitted metadata and MCP cleanup finish for consistency, and deferred Docker work continues on the next ten-minute cycle. Container state, cleanup, health counts, and credential refreshes share one event-backed CoderFlow inventory. Its safety reconciliation starts at one minute after a correction and backs off to five, then ten minutes after clean scans. A shared running-only compatibility scan, refreshed at most every five minutes, keeps unlabeled legacy coder-* containers current in credential and entitlement propagation without adding them to every inventory reconciliation. The Health metrics docker.total, docker.running, and docker.stopped therefore count CoderFlow-labeled containers in that shared inventory, not every container on the Docker host. Administrators may see lower totals after this change when the host also runs unrelated workloads. Docker storage maintenance probes capacity first and only runs the more expensive docker df accounting under configured disk pressure; an admin can also request it explicitly with the Health page's Refresh action. If pressure-triggered storage accounting fails or times out, that cycle skips pruning instead of using stale reclaimable-byte figures while the accounting request may still be using the Docker daemon.

The default auto mode serves HTTP/2 with a TLS certificate and key, and HTTP/1.1 otherwise. HTTP/2 prevents long-lived SSE streams from filling the browser's six-connection HTTP/1.1 pool and stalling page loads. Use http1 to roll back, or use separate TLS termination with the product-specific Nginx HTTP/2 reference.

Microsoft Teams agent integration

CoderFlow hosts its Teams integration with the Microsoft 365 Agents SDK. The existing Azure Bot resource and Microsoft Entra app registration remain valid; configure their messaging endpoint as the public HTTPS URL shown under Settings > Microsoft Teams, ending in /api/teams/messages.

The saved Microsoft App ID, client secret, app type, and—for SingleTenant registrations—the Entra tenant ID are used for both inbound JWT validation and outbound/proactive activity delivery. MultiTenant registrations leave the Agents SDK tenant unset so each activity's tenant can be resolved normally; any optional saved tenant ID remains available only as a Microsoft Graph fallback. The endpoint does not use a CoderFlow browser session, but every inbound activity must carry a valid Bot Service bearer token.

If INTEGRATIONS_INGRESS_MODE=listener is used, expose the integrations listener instead of the main application while keeping the same /api/teams/messages path. After changing credentials, callback routing, or the Teams manifest, validate personal chats, group chats, channel mentions, threaded follow-ups, account linking, and proactive completion replies in a development tenant.

SSE stream limits and health metrics

The server limits long-lived task SSE responses per authenticated user, across all their tabs, sessions and API keys. Configure these positive integer settings in coder-setup's setup.json, then restart the server:

{
  "max_task_streams_per_user": 8,
  "max_update_streams_per_user": 4,
  "task_stream_warning_threshold": 6
}

These are the defaults; missing or invalid values (including zero) use the default. Each new response beyond its endpoint's cap evicts that user's oldest response of the same kind, across all task IDs. The server sends a terminal stream-evicted event before closing it and immediately clears its polling or keepalive timer. The Web UI logs eviction to the console and stops automatic reconnection for that subscription. Close surplus tabs before reopening an evicted page. An evicted shared updates connection remains stopped for the worker lifetime, so close all CoderFlow tabs using that worker before reopening.

Warnings are logged once when a user's task stream count rises above the warning threshold, and re-arm when it falls back to or below the threshold. Replacing streams while continuously above the threshold does not repeat the warning. Set the threshold below the task cap to receive warnings before eviction.

Admin GET /health/metrics includes sseStreams: live task/update totals, effective limits, and users with user ID, username, counts, oldest stream age in seconds, and a tasks entry (task ID and age) for every task response. Duplicate task IDs represent separate open responses. The admin Health page shows the same data in Open SSE Streams. Counts cover this server process; they do not include other SSE endpoint types or aggregate multiple servers.

Compressing the task activity stream

The first load of a task page downloads the task's whole activity history through GET /tasks/:id/stream, often tens of MB. Like other responses, the stream is compressed for browsers that accept it. Every other streaming endpoint stays uncompressed.

Browsers that accept Brotli get Brotli at quality 4 with a 1 MB window; others get gzip at level 6. On real task histories Brotli made the stream 2.9–5.4× smaller and gzip 1.4–2.9×, and Brotli took less server CPU: gzip's 32 KB window misses tool output that is repeated further apart. Each open compressed stream holds its compressor, about 3.4 MB for Brotli at this window. The route flushes after each replay batch of 50 records, after the initial replay, at the end of each one-second poll tick that wrote something, and after events pushed by other routes, so live events are not held back.

With or without compression, the stream is written at the client's pace: when the connection backs up, the replay, and a poll that finds a large append, wait for it to drain between batches rather than buffering the rest in server memory.

Responses carry Cache-Control: no-cache, no-transform and X-Accel-Buffering: no. A reverse proxy in front of the server should forward the browser's Accept-Encoding, and must not buffer the response or decompress and re-compress it; new events should reach the page within about a second while a task is running. To serve the stream uncompressed through a proxy that cannot do that, have the proxy stop forwarding Accept-Encoding for /tasks/*/stream, or send X-No-Compression: 1 with those requests.

Container callback URLs for local servers

Tasks created through MCP and other background triggers resolve their callback URL in this order: CODERFLOW_INTERNAL_URL, CODERFLOW_SERVER_URL, configured site_url, then the callback URL learned from an admin request. Task creation still requires a configured or learned URL; it does not guess a port when none is available.

For automatically derived URLs, loopback hosts (localhost, IPv4 127.0.0.0/8, and IPv6 ::1, including IPv4-mapped loopback) become host.docker.internal, just as for UI launches. Protocol, non-default port, and base path are retained; query strings, fragments, and trailing slashes are removed. Public hostnames and non-loopback IPs are unchanged. This works from source and packaged builds, independently of NODE_ENV, without a local environment-variable workaround.

Explicit environment overrides keep their hostnames, including loopback, for custom network topologies. No URL is taken from a parent task. Normalization is limited to container callbacks; server-side URLs and stored configuration are not rewritten. Task containers using host.docker.internal receive Docker's host-gateway mapping when no custom mapping already exists (Docker Engine 20.10+). The host server must listen on an interface reachable from Docker; remote Docker daemons and loopback-only listeners need appropriate networking.

Personal work reporting

Open the task dashboard’s user menu (your avatar), then My Work (my-work.html) to review your recorded activity for an inclusive date range (up to 366 days). The page automatically uses the viewer’s browser timezone (UTC if unavailable), without asking for a timezone. The environment and task-field dropdowns use the shared CustomSelect component. The report uses the existing durable usage-activity ledger: task creation and follow-up submissions are selected by the submitting user and event date, including activity on older, unpinned, or snoozed tasks. It does not interpret task lifetime or submission counts as human hours.

The authenticated GET /my-work endpoint accepts from, to (YYYY-MM-DD), timeZone, optional environment, JSON-encoded fields (exact current custom field values by key), and offset/limit (default 20, maximum 50). Rows are ordered by descending local date and then task ID/environment. nextOffset is null on the last page. format=csv exports all matching rows regardless of pagination, with date/timezone/coverage metadata and spreadsheet-safe escaping. Each request reads current records; concurrent activity or classification edits can change the result between pages, so refresh after ongoing work settles for a consistent review. The CSV is generated from a single report read.

Task details require the same permissions as opening the task. The report is always personal, including for administrators; it has no user-ID override. Current custom fields support product, team, category or other customer-defined classification without a separate schema. Their values and task titles/status are current metadata, not historical snapshots. Missing task details produce unlinked placeholders, because the ledger intentionally retains no titles, code or prompts. Filters on custom fields exclude these unknown values.

The Task activity section groups rows by local date and shows a compact task and follow-up count. Each row keeps its activity summary visible, with environment, current status, custom fields and request excerpts under Details. Report limitations remain under About this report. The activity CSV action is in the section header; pagination appears only when there is another page to visit.

Rows provide a factual submission summary and up to three 600-character excerpts of still-retained, matching follow-ups. They describe requests, not verified completion outcomes. Rewound or deleted text is not reconstructed. Previously deleted/unloaded tasks, unattributed events, known automation, recording outages, terminal work and reviews without a submission are not a complete record of a person's work. Coverage limitations appear on the page and in CSV exports; the activity report itself persists no additional personal history.

Ask CoderFlow and MCP expose the read-only get_my_work tool with the same permissions, date filters and pagination. Ask CoderFlow receives the applied page filters and can summarize results by product or other fields. Its existing provider/documentation configuration is still required. Model-generated prose is an interpretation of the returned evidence; embedded task text is data, never instructions. Time is logged separately in the same page; this activity tool does not return or modify time entries.

Focused validation:

  • Server: tests/my-work.test.js, tests/my-work-route.test.js, tests/assistant-tools.test.js, and the get_my_work case in tests/mcp-server.test.js, using the isolated Node test setup in tests/README.md.
  • Web UI: tests/my-work.test.js, tests/audit-fields.test.js, and tests/ask-coderflow-fields.test.js.
  • Authenticated UI: npm run test:ui -- tests/ui/my-work.spec.js --workers=1. The normal App Server and writable test-user setup are required.
  • Isolated browser component (fictional history; does not test authentication): npm run test:ui -- --config=tests/ui/my-work-component.config.js --workers=1. Artifacts default to playwright-test-results/my-work/ in the server package. Set MY_WORK_OUTPUT_DIR to override the artifact root, or MY_WORK_SCREENSHOT_DIR to override only the screenshot directory. After building the Web UI, set MY_WORK_ASSET_DIR to its absolute dist/public path to run these same browser checks against production assets.

Time tracking

My Work includes a Time tracking card. Expand Log time, select a work date, enter decimal hours (for example, 0.5 or 1.25), and describe the work. Hours are rounded to the nearest minute. The form supports editing, removal and a CSV export. Task & notes (optional) links the entry to a task and adds notes. The task picker lists tasks you created or followed up first, then tasks shared by others, then automated runs, each most recent first. Each option shows a readable title (derived from the instructions, deploy profile or test name when a task was never named), a one-line summary, status, environment, agent, owner or automation, last activity and task ID. Search matches those details. Editing existing entries preserves their task links, notes and saved classifications; their work descriptions can be updated.

Daily and Monday-based weekly totals use the applied dates and filters. Partial weeks include only dates in the selected range. Each entry retains its work date and the browser timezone at creation. Neither elapsed task duration nor activity counts create or prefill reported hours. The daily total across all entries is limited to 24 hours. These are user-confirmed entries, not manager approvals.

Authenticated endpoints under /my-work:

  • GET /time-tasks?search=... lists up to 50 permitted tasks in picker order, with display title and summary, group (mine, shared or automated), kind, status, agent, createdBy, automation, activityAt and classifications.
  • GET /time-entries accepts the report date/timezone/environment/field filters; format=csv exports every matching active entry, independent of activity pagination.
  • POST /time-entries takes date, timeZone, whole minutes, taskId (empty for non-task work), label, notes, and fields for non-task classifications.
  • PUT /time-entries/:id takes the same fields plus the current version.
  • DELETE /time-entries/:id takes the current version in a JSON body.

Entries are scoped to the authenticated user, with task-detail permission checks when linking a task. Version conflicts return 409. Entries are atomically stored per user in work-time under the runtime data directory, separately from task activity. Edits append revisions; removal retains a tombstone and revisions but excludes the entry from reports and exports. Active-entry correction history is visible in the page. Task IDs and classification snapshots survive task deletion; task titles and prompts are not persisted in this store. Include this directory in normal server data backups. The store assumes one owning server process.

Validation: tests/work-time.test.js covers persistence, isolation, permissions, revisions, deletion, conflict handling, totals, CSV, invalid input and HTTP routes. The existing isolated My Work browser component spec covers creating, editing, exporting and removing entries as well as the rich environment selector. Timers, manager approval, Jira synchronization and external database adapters are deferred.

Keywords

ai

FAQs

Package last updated on 09 Oct 2026

Related posts