Hook Naming Convention .bg.js Suffix for Background Daemon Hooks in abx-dl

Background daemon hooks in abx-dl use the .bg segment in the filename—such as on_Snapshot__21_consolelog.bg.js—to indicate they run as long-lived processes managed via PID files.

The abx-dl repository implements a strict filename-based convention for detecting which hooks should execute as background daemons versus one-shot scripts. Understanding the hook naming convention .bg.js suffix is essential for developers building plugins that require persistent processes during ArchiveBox events.

The Complete Naming Schema

Background daemon hooks follow a specific pattern that encodes metadata directly in the filename:


on_{Event}__{XX}_{description}[.bg].{ext}

Filename Segments Explained

  • on_{Event} — Specifies the ArchiveBox event that triggers the hook (e.g., Snapshot, ArchiveResult).
  • __{XX} — Two-digit code where the first digit represents the execution step and the second indicates priority within that step.
  • _{description} — A snake_case description of the hook's purpose for human readability.
  • .bg — The critical optional marker that designates the hook as a background daemon. When present, the executor treats the process as long-lived and manages it through PID files.
  • .{ext} — The file extension indicating the implementation language (js, py, or sh).

A typical background JavaScript hook uses the full .bg.js suffix:


on_Snapshot__21_consolelog.bg.js

How the Executor Detects Background Mode

The system extracts the .bg indicator during the plugin loading phase and maintains it as a boolean flag throughout execution.

Parsing Logic in plugins.py

In abx_dl/plugins.py, a regular expression parses the filename to set the is_background flag:


# Inside abx_dl/plugins.py (lines 71-84)

pattern = r'^on_(\w+)__(\d)(\d)_(\w+)(\.bg)?\.(\w+)$'
match = re.match(pattern, filename)
is_background = match.group(5) is not None   # True when ".bg" is present

This regex captures the optional \.bg group and translates its presence into the boolean is_background attribute.

Execution Behavior in executor.py

When hook.is_background evaluates to True, the executor in abx_dl/executor.py (lines 71-73) configures the subprocess as a daemon with dedicated PID, stdout, and stderr files:


# Inside abx_dl/executor.py (simplified from lines 71-73)

hook_basename = hook.name                     # e.g. "on_Snapshot__21_consolelog.bg"

stdout_file = output_dir / f'{hook_basename}.stdout.log'
stderr_file = output_dir / f'{hook_basename}.stderr.log'
pid_file   = output_dir / f'{hook_basename}.pid'

with open(stdout_file, 'w') as out, open(stderr_file, 'w') as err:
    process = subprocess.Popen(
        cmd,
        cwd=str(output_dir),
        stdout=out,
        stderr=err,
        env=env,
    )

# PID is written to pid_file for later cleanup

According to the CLAUDE.md documentation (lines 77-80), these hooks "run as daemons and are cleaned up via PID files at the end" of the execution cycle.

Creating a Background Daemon Hook

To implement a background JavaScript hook, create a file following the naming convention with the .bg.js extension:

// File: my_plugin/on_Snapshot__21_consolelog.bg.js
#!/usr/bin/env node

// This hook runs as a background daemon during the Snapshot event.
// It continuously logs the page console output to a file.
const fs = require('fs');
const path = require('path');

const outputPath = path.join(process.env.OUTPUT_DIR, 'console.log');
const stream = fs.createWriteStream(outputPath, { flags: 'a' });

process.on('message', (msg) => {
    if (msg.type === 'console') {
        stream.write(msg.text + '\n');
    }
});

The .bg.js suffix tells abx-dl to start this script as a persistent process rather than awaiting a single exit code, and to track it using a PID file for proper cleanup when the Snapshot event completes.

Summary

  • The hook naming convention .bg.js suffix requires the format on_{Event}__{XX}_{description}.bg.{ext}.
  • In abx_dl/plugins.py, a regex extracts the .bg segment to set is_background=True.
  • Background hooks execute via subprocess.Popen in abx_dl/executor.py with dedicated pid, stdout, and stderr files.
  • The .bg marker must appear immediately before the file extension (e.g., .bg.js, .bg.py).
  • See CLAUDE.md lines 77-80 for high-level documentation on daemon lifecycle management.

Frequently Asked Questions

What happens if I omit the .bg segment from my hook filename?

If you omit the .bg segment (e.g., naming the file on_Snapshot__21_consolelog.js), the executor treats the script as a standard one-shot hook. It will wait for the process to exit before continuing, and it will not create a PID file for lifecycle management.

Can I use the .bg suffix with Python or Shell scripts, or only JavaScript?

Yes, the .bg suffix works with any supported language extension. The naming convention supports .bg.js, .bg.py, and .bg.sh equally. The executor checks for the .bg segment before the extension, not the language itself.

How does abx-dl clean up background daemon hooks after execution?

According to the implementation in abx_dl/executor.py, the system writes the process ID to a {hook_name}.pid file when starting the daemon. At the end of the event cycle, the executor reads this PID file and terminates the process appropriately, as documented in CLAUDE.md lines 77-80.

Where is the is_background flag actually set in the source code?

The is_background boolean is derived in abx_dl/plugins.py (lines 71-84) using the regex pattern r'^on_(\w+)__(\d)(\d)_(\w+)(\.bg)?\.(\w+)$'. When the optional fifth capture group containing .bg is present, the flag is set to True and passed to the executor.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →