Skip to content

Agent Branch Patterns

Cloud-hosted agents and automation tools often work on branches such as claude/session-123. LumenFlow treats a branch whose name matches an agent branch pattern as an agent branch, so those tools can run LumenFlow commands from the main checkout. Human developers still use worktrees.

  1. Shipped list - The list of agent branch patterns ships inside the installed release. LumenFlow makes no network request for it and keeps no cache file.
  2. Your config - Patterns in workspace.yaml are added to the shipped list, or replace it.
  3. Match - Branch names are matched against the glob patterns with micromatch.

Only the installed release and your own workspace.yaml decide which branches are agent branches. To change the shipped list, upgrade LumenFlow.

The list shipped with the release:

[
  "agent/*",
  "claude/*",
  "codex/*",
  "copilot/*",
  "cursor/*",
  "aider/*",
  "cline/*",
  "continue/*",
  "devin/*",
  "windsurf/*",
  "bolt/*",
  "replit/*",
  "tabnine/*",
  "codeium/*",
  "ai/*",
  "bot/*",
  "automation/*"
]
import {
  isAgentBranch,
  isAgentBranchWithDetails,
} from '@hellmai/lumenflow-packs-software-delivery/runtime/authoring';

// Check if a branch is an agent branch
if (await isAgentBranch('claude/session-12345')) {
  console.log('Agent branch detected');
}

// Get the patterns used and where they came from
const result = await isAgentBranchWithDetails('claude/session-123');
if (result.isMatch) {
  console.log(`Matched via ${result.patternResult.source}`);
  // source: 'shipped' | 'merged' | 'override' | 'config' | 'defaults'
}
#!/bin/bash
# Example pre-commit hook
if node_modules/.bin/is-agent-branch "$BRANCH"; then
  echo "Agent branch - skipping worktree check"
  exit 0
fi
import { isAgentBranchSync } from '@hellmai/lumenflow-packs-software-delivery/runtime/authoring';

// Uses only your config patterns, or agent/* when you set none
const result = isAgentBranchSync('agent/task-123');

Configure agent patterns in workspace.yaml. There are three modes:

Your patterns are added to the shipped list:

# workspace.yaml
git:
  # These patterns are ADDED to the shipped list
  agentBranchPatterns:
    - 'my-custom-agent/*'
    - 'internal-tool/*'

Result: your patterns, then the shipped list (deduplicated)

OptionTypeDefaultDescription
agentBranchPatternsstring[][]Patterns to add to the shipped list
agentBranchPatternsOverridestring[]undefinedPatterns that replace the shipped list
disableAgentPatternRegistrybooleanfalseIgnore the shipped list; use your patterns or agent/* only

No option makes a network request.

Shipped list offOverride SetConfig PatternsResultSource
falsenononeShipped listshipped
falseno['custom/*']Config + shipped listmerged
falseyesanyOverride onlyoverride
truenononeDefaults (['agent/*'])defaults
trueno['custom/*']Config onlyconfig
trueyesanyOverride onlyoverride

Some branches are never agent branches, regardless of patterns:

  • Main branch (from git.mainBranch config)
  • master (legacy protected)
  • Lane branches (matching lane/*)
// These always return false
await isAgentBranch('main'); // false
await isAgentBranch('master'); // false
await isAgentBranch('lane/operations/<wu-id>'); // false

An agent-branch match changes where a client may work; it does not authorize one checkout to reuse another checkout’s mutable dependency graph.

For local worktree claims, LumenFlow runs a frozen package-manager install inside the new worktree. Workspace package links must resolve inside that worktree. A package manager may share its content-addressed store through hardlinks, reflinks, or copies materialized into checkout-local virtual storage; a direct workspace link may never resolve to an external store. Root or package-local node_modules directories are never linked to main or another worktree. Each intermediate dependency scope and package component is realpath-checked, including directory junctions. If local installation fails, claim setup fails without creating a shared fallback.

wu:claim --skip-setup creates no dependency links and runs no install. Before gates can run, set up dependencies inside that checkout. A missing/non-directory dependency root or missing declared workspace package fails preflight, and gates never substitutes main’s CLI dist for the worktree copy. Gate preflight reports the exact path and resolved target, then refuses to execute any gate command.

Older local worktrees can be converted through wu:rebase or wu:recover --id WU-XXX --action resume. Use wu:rebase --dry-run to report conversion-required without fetching, unlinking, installing, snapshotting or repairing main, or mutating Git. An isolated result also leaves main unsnapshotted. Actual conversion records deterministic link objects, continues through safe checkout-local ancestors, checks package-local dependency roots even when a package declares no workspace dependencies, and unlinks only the first broken or escaping object after revalidation. It never traverses or mutates the resolved target.

Once conversion starts, LumenFlow snapshots main before mutation and attests it afterward even if worktree unlink, install, or verification fails. An already-unsafe main is repaired to a safe graph without restoring that unsafe snapshot. If a safe pre-mutation snapshot later drifts, recovery also requires exact restoration of that safe baseline. That lifecycle attempt still hard-fails so the operator reruns from a clean, auditable boundary. Branch-only and branch-PR modes perform no local worktree conversion, even if a stale same-WU directory remains at the canonical path.

Use resolveAgentPatterns() to see the patterns a configuration resolves to:

import { resolveAgentPatterns } from '@hellmai/lumenflow-packs-software-delivery/runtime/authoring';

const result = resolveAgentPatterns({
  configPatterns: ['my-agent/*'],
  // overridePatterns: ['only-this/*'],  // Optional
  // disableAgentPatternRegistry: true,   // Optional
});

console.log(result.patterns); // ['my-agent/*', 'agent/*', 'claude/*', ...]
console.log(result.source); // 'merged'

The shipped list is exported as SHIPPED_AGENT_PATTERNS.

Earlier releases downloaded the list from https://lumenflow.dev/registry/agent-patterns.json and cached it in ~/.lumenflow/cache/agent-patterns-cache.json. That file stays published, with the same list, for those releases. Current releases do not read it, and you can delete the old cache file.

To ask for a new pattern in the shipped list, send the agent name and its usual branch prefix. Until a release ships it, add it yourself with agentBranchPatterns.

The system is fail-closed:

  • Unknown branches are protected (require worktrees)
  • Detached HEAD is protected
  • Null/empty branches are protected
  • No network path or cache file can add a pattern