Skip to content

Agent Branch Patterns

LumenFlow maintains a central registry of AI agent branch patterns that can bypass worktree requirements. This enables cloud-hosted agents and automation tools to work in the main checkout while still enforcing worktree discipline for human developers.

  1. Fetch from Registry - The isAgentBranch() function fetches patterns from lumenflow.dev/registry/agent-patterns.json
  2. Cache Locally - Patterns are cached for 7 days in ~/.lumenflow/cache/
  3. Merge with Config - Registry patterns are merged with any custom patterns from config
  4. Check Branch Name - Branch names are matched against glob patterns using micromatch

The registry includes patterns for popular AI agents:

{
  "patterns": [
    "agent/*",
    "claude/*",
    "codex/*",
    "copilot/*",
    "cursor/*",
    "aider/*",
    "cline/*",
    "continue/*",
    "devin/*",
    "windsurf/*",
    "bolt/*",
    "replit/*",
    "tabnine/*",
    "codeium/*",
    "ai/*",
    "bot/*",
    "automation/*"
  ]
}
import { isAgentBranch, isAgentBranchWithDetails } from '@lumenflow/core';

// Check if a branch can bypass worktree requirements
if (await isAgentBranch('claude/session-12345')) {
  console.log('Agent branch detected - bypass allowed');
}

// Get detailed result for observability
const result = await isAgentBranchWithDetails('claude/session-123');
if (result.isMatch) {
  console.log(`Matched via ${result.patternResult.source}`);
  // source: 'registry' | 'merged' | 'override' | 'config' | 'defaults'
  console.log(`Registry fetched: ${result.patternResult.registryFetched}`);
}
#!/bin/bash
# Example pre-commit hook
if node_modules/.bin/is-agent-branch "$BRANCH"; then
  echo "Agent branch - skipping worktree check"
  exit 0
fi

For backwards compatibility, a sync version is available:

import { isAgentBranchSync } from '@lumenflow/core';

// Uses only local config patterns, no registry fetch
const result = isAgentBranchSync('agent/task-123');

Configure agent patterns in .lumenflow.config.yaml. There are three modes:

Custom patterns are merged with registry patterns:

# .lumenflow.config.yaml
git:
  # These patterns are ADDED to registry patterns
  agentBranchPatterns:
    - 'my-custom-agent/*'
    - 'internal-tool/*'

Result: Your patterns + registry patterns (deduplicated)

OptionTypeDefaultDescription
agentBranchPatternsstring[][]Patterns to merge with registry
agentBranchPatternsOverridestring[]undefinedPatterns that replace registry
disableAgentPatternRegistrybooleanfalseSkip network fetch (airgapped mode)
Registry DisabledOverride SetConfig PatternsResultSource
falsenononeRegistry patternsregistry
falseno['custom/*']Config + Registrymerged
falseyesanyOverride onlyoverride
truenononeDefaults (['agent/*'])defaults
trueno['custom/*']Config onlyconfig
trueyesanyOverride onlyoverride

Some branches are never bypassed, 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-123'); // false
ScenarioBehavior
Fresh cache (<7d)Use cached patterns, no network request
Stale cache (>=7d)Attempt fetch, use fresh if successful
Fetch failsUse stale cache if available, else use defaults
No cache, no networkUse defaults (['agent/*'])

Patterns are cached in:

~/.lumenflow/cache/agent-patterns-cache.json

Or if LUMENFLOW_HOME is set:

$LUMENFLOW_HOME/cache/agent-patterns-cache.json
import { clearCache } from '@lumenflow/core';

// Clear in-memory cache (disk cache remains)
clearCache();

To clear disk cache, delete the cache file:

rm ~/.lumenflow/cache/agent-patterns-cache.json

Use resolveAgentPatterns() for testing or custom resolution:

import { resolveAgentPatterns } from '@lumenflow/core';

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

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

For testing, inject a custom fetcher:

const mockFetcher = async () => ['test/*'];

const result = await resolveAgentPatterns({
  registryFetcher: mockFetcher,
});

expect(result.patterns).toEqual(['test/*']);

The registry is served as static JSON:

URL: https://lumenflow.dev/registry/agent-patterns.json

Response Schema:

interface RegistryResponse {
  version: string;
  description?: string;
  patterns: string[];
  documentation?: string;
  updated?: string;
}

To request a new agent pattern be added:

  1. Open an issue on hellmai/os
  2. Include the agent name and typical branch pattern
  3. Patterns are added to the registry after review

For CI/CD environments that don’t use agent branches, enable guarded headless mode:

export LUMENFLOW_HEADLESS=1
export CI=true  # or GITHUB_ACTIONS=true or LUMENFLOW_ADMIN=1

This bypasses all worktree checks. See AI Agent Integration for details.

The system is fail-closed:

  • Unknown branches are protected (require worktrees)
  • Detached HEAD is protected
  • Null/empty branches are protected
  • Network errors fall back to cache/defaults (not bypass)

This ensures accidental work in the wrong location is prevented.