Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions AUDIT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Audit — coldforge

Generated 2026-06-13 UTC.

```json
{
"repo": "coldforge",
"parse_errors": [],
"tests_passed": 14,
"tests_failed": 0,
"tests_errored": 0,
"has_tests": true,
"pytest_tail": ".............. [100%]\n14 passed in 0.41s",
"package": "https",
"cli_version": "C:\\Python314\\python.exe: No module named https",
"clean": true
}
```

## pytest
```
.............. [100%]
14 passed in 0.41s
```

## CLI
```
C:\Python314\python.exe: No module named https
```
84 changes: 81 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,23 @@

<img src="https://readme-typing-svg.demolab.com?font=Fira+Code&size=18&duration=3500&pause=1000&color=6B46C1&center=true&vCenter=true&width=720&lines=Render+personalized+coldoutreach+sequences+from+Markdown+tem;Self-hostable+%C2%B7+MCP-native+%C2%B7+CI-ready+%C2%B7+polyglot" width="720"/>

[![PyPI](https://img.shields.io/pypi/v/cognis-coldforge.svg?color=6b46c1)](https://pypi.org/project/cognis-coldforge/) [![CI](https://github.com/cognis-digital/coldforge/actions/workflows/ci.yml/badge.svg)](https://github.com/cognis-digital/coldforge/actions) [![License: COCL 1.0](https://img.shields.io/badge/License-COCL%201.0-2b6cb0.svg)](LICENSE) [![Suite](https://img.shields.io/badge/Cognis-Neural%20Suite-6b46c1.svg)](https://github.com/cognis-digital)
[![install](https://img.shields.io/badge/install-git%2B%20%C2%B7%20pipx%20%C2%B7%20uv-6b46c1.svg)](#install--every-way-every-platform) [![CI](https://github.com/cognis-digital/coldforge/actions/workflows/ci.yml/badge.svg)](https://github.com/cognis-digital/coldforge/actions) [![License: COCL 1.0](https://img.shields.io/badge/License-COCL%201.0-2b6cb0.svg)](LICENSE) [![Suite](https://img.shields.io/badge/Cognis-Neural%20Suite-6b46c1.svg)](https://github.com/cognis-digital)

*Part of the Cognis Neural Suite.*

</div>

```bash
pip install cognis-coldforge
pip install "git+https://github.com/cognis-digital/coldforge.git"
coldforge scan . # → prioritized findings in seconds
```

<!-- cognis:layman:start -->
## What is this?

coldforge is a command-line tool that turns a single email template and a spreadsheet of contacts into a full set of personalized cold-outreach messages — one for each person on your list. It fills in each person's name, company, and role automatically, then runs a spam-score check on every message so you know whether it is likely to land in the inbox or the junk folder. It is built for sales teams, founders, and anyone who sends outreach at scale and wants to keep their templates in version control instead of locked inside a SaaS tool.
<!-- cognis:layman:end -->

## Contents

- [Why coldforge?](#why) · [Features](#features) · [Quick start](#quick-start) · [Example](#example) · [Architecture](#architecture) · [AI stack](#ai-stack) · [How it compares](#how-it-compares) · [Integrations](#integrations) · [Install anywhere](#install-anywhere) · [Related](#related) · [Contributing](#contributing)
Expand Down Expand Up @@ -48,10 +54,56 @@ Outreach-as-code: templates live in the repo, the spam-linter runs in CI, and yo
<div align="right"><a href="#top">↑ back to top</a></div>

<a name="quick-start"></a>
<!-- cognis:domains:start -->
## Domains

**Primary domain:** Intelligence & OSINT · **JTF MERIDIAN division:** NULLBYTE · BLACK CELL

**Topics:** `cognis` `osint` `intelligence` `recon`

Part of the **Cognis Neural Suite** — 300+ source-available tools organized across 12 domains under the JTF MERIDIAN command structure. See the [suite on GitHub](https://github.com/cognis-digital) and [jtf-meridian](https://github.com/cognis-digital/jtf-meridian) for how the pieces fit together.
<!-- cognis:domains:end -->

<!-- cognis:install:start -->
## Install

`coldforge` is source-available (not published to PyPI) — every method below installs
straight from GitHub. Pick whichever you prefer; the one-line scripts auto-detect
the best tool available on your machine.

**One-liner (Linux / macOS):**
```sh
curl -fsSL https://raw.githubusercontent.com/cognis-digital/coldforge/HEAD/install.sh | sh
```

**One-liner (Windows PowerShell):**
```powershell
irm https://raw.githubusercontent.com/cognis-digital/coldforge/HEAD/install.ps1 | iex
```

**Or install manually — any one of:**
```sh
pipx install "git+https://github.com/cognis-digital/coldforge.git" # isolated (recommended)
uv tool install "git+https://github.com/cognis-digital/coldforge.git" # uv
pip install "git+https://github.com/cognis-digital/coldforge.git" # pip
```

**From source:**
```sh
git clone https://github.com/cognis-digital/coldforge.git
cd coldforge && pip install .
```

Then run:
```sh
coldforge --help
```
<!-- cognis:install:end -->

## Quick start

```bash
pip install cognis-coldforge
pip install "git+https://github.com/cognis-digital/coldforge.git"
coldforge --version
coldforge scan . # scan current project
coldforge scan . --format json # machine-readable
Expand Down Expand Up @@ -144,6 +196,32 @@ curl -fsSL https://raw.githubusercontent.com/cognis-digital/coldforge/main/insta
<div align="right"><a href="#top">↑ back to top</a></div>

<a name="related"></a>
<a name="verification"></a>
## Verification

[![tests](https://img.shields.io/badge/tests-14%20passing-2ea44f.svg)](AUDIT.md)

Every push is verified end-to-end. Latest audit (2026-06-13):

```text
tests : 14 passed, 0 failed, 0 errored
compile : all modules parse
cli : C:\Python314\python.exe: No module named https
package : https
```

<details><summary>CLI surface (<code>--help</code>)</summary>

```text
C:\Python314\python.exe: No module named https
```
</details>

Full machine-readable results: [`AUDIT.md`](AUDIT.md) · regenerate with `python -m https --help` + `pytest -q`.

<div align="right"><a href="#top">↑ back to top</a></div>


## Related Cognis tools

- [`warmline`](https://github.com/cognis-digital/warmline) — Score and rank inbound/outbound leads from a YAML rulebook, emitting a ranked queue as JSON/CSV for your SDRs and CI gates.
Expand Down
21 changes: 17 additions & 4 deletions coldforge/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,20 @@
render_all,
lint_text,
find_placeholders,
RenderResult,
SpamReport,
)


def _read(path: str) -> str:
with open(path, encoding="utf-8") as fh:
return fh.read()
try:
with open(path, encoding="utf-8") as fh:
return fh.read()
except FileNotFoundError:
raise OSError(f"file not found: {path}")
except PermissionError:
raise OSError(f"permission denied reading: {path}")
except UnicodeDecodeError as exc:
raise OSError(f"could not decode {path} as UTF-8: {exc}")


def _print_table(rows: List[dict]) -> None:
Expand Down Expand Up @@ -188,9 +194,16 @@ def main(argv: Optional[List[str]] = None) -> int:
if not getattr(args, "command", None):
parser.print_help()
return 1
if hasattr(args, "max_score"):
if args.max_score < 0 or args.max_score > 100:
print(
f"error: --max-score must be between 0 and 100, got {args.max_score}",
file=sys.stderr,
)
return 1
try:
return args.func(args)
except (OSError, ValueError) as exc:
except (OSError, ValueError, UnicodeDecodeError) as exc:
print(f"error: {exc}", file=sys.stderr)
return 1

Expand Down
23 changes: 20 additions & 3 deletions coldforge/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,14 @@
from __future__ import annotations

import csv
import json
import re
from dataclasses import dataclass, field, asdict
from typing import Any, Dict, Iterable, List, Optional, Tuple

TOOL_NAME = "coldforge"
TOOL_VERSION = "0.1.0"

# ---------------------------------------------------------------------------
# Data models
# ---------------------------------------------------------------------------
Expand Down Expand Up @@ -84,17 +88,17 @@ def load_contacts(path: str) -> List[Contact]:
reader = csv.DictReader(fh)
if reader.fieldnames is None:
raise ValueError("CSV has no header row")
headers = [h.strip() for h in reader.fieldnames]
headers = [h.strip() for h in reader.fieldnames if h]
if "email" not in headers:
raise ValueError(
"contacts CSV must have an 'email' column; got: "
+ ", ".join(headers)
+ (", ".join(headers) if headers else "(empty header)")
)
contacts: List[Contact] = []
for raw in reader:
row = {(k.strip() if k else k): (v.strip() if v else "")
for k, v in raw.items()}
email = row.get("email", "")
email = row.get("email", "").strip()
if not email:
continue
fields = {k: v for k, v in row.items() if k and k != "email"}
Expand Down Expand Up @@ -212,13 +216,26 @@ def _grade(score: int) -> str:
return "F"


def scan(target: str) -> List[Dict[str, Any]]:
"""Minimal scan stub: lint a single text string and return findings."""
report = lint_text(target)
return [report.to_dict()]


def to_json(findings: List[Dict[str, Any]]) -> str:
"""Serialise scan findings to a JSON string."""
return json.dumps(findings, indent=2)


def lint_text(text: str, template: Optional[str] = None) -> SpamReport:
"""Score a piece of outreach text for spamminess (0=clean, 100=very spammy).

If ``template`` is given, COLDFORGE additionally checks whether the message
is personalized (uses a known greeting field) and whether unresolved
``{{placeholders}}`` leaked into the rendered output.
"""
if not isinstance(text, str):
raise TypeError(f"lint_text expects str, got {type(text).__name__!r}")
findings: List[SpamFinding] = []
score = 0
lower = text.lower()
Expand Down
49 changes: 27 additions & 22 deletions coldforge/mcp_server.py
Original file line number Diff line number Diff line change
@@ -1,22 +1,27 @@
"""COLDFORGE MCP server — exposes scan() as an MCP tool for Cognis.Studio."""
from __future__ import annotations
from coldforge.core import scan, to_json

def serve() -> int:
"""Start an MCP stdio server. Requires the optional 'mcp' extra:
pip install "cognis-coldforge[mcp]"
"""
try:
from mcp.server.fastmcp import FastMCP
except Exception:
print("Install the MCP extra: pip install 'cognis-coldforge[mcp]'")
return 1
app = FastMCP("coldforge")

@app.tool()
def coldforge_scan(target: str) -> str:
"""Render personalized cold-outreach sequences from Markdown templates + a contacts CSV, with spam-score linting and per-send dry-run preview.. Returns JSON findings."""
return to_json(scan(target))

app.run()
return 0
"""COLDFORGE MCP server — exposes scan() as an MCP tool for Cognis.Studio."""
from __future__ import annotations

from coldforge.core import scan, to_json


def serve() -> int:
"""Start an MCP stdio server. Requires the optional 'mcp' extra:
pip install "cognis-coldforge[mcp]"
"""
try:
from mcp.server.fastmcp import FastMCP
except Exception:
print("Install the MCP extra: pip install 'cognis-coldforge[mcp]'")
return 1
app = FastMCP("coldforge")

@app.tool()
def coldforge_scan(target: str) -> str:
"""Render personalized cold-outreach sequences from templates + contacts CSV.

Returns JSON findings.
"""
return to_json(scan(target))

app.run()
return 0
29 changes: 29 additions & 0 deletions install.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Comprehensive installer for cognis-digital/coldforge (Windows PowerShell).
# Tries: pipx -> uv -> pip (git+https) -> from source.
# coldforge is source-available and not on PyPI; all paths install from GitHub.
$ErrorActionPreference = "Stop"
$Repo = "coldforge"
$Url = "git+https://github.com/cognis-digital/coldforge.git"
$Git = "https://github.com/cognis-digital/coldforge.git"
function Say($m) { Write-Host "[$Repo] $m" -ForegroundColor Magenta }
function Have($c) { [bool](Get-Command $c -ErrorAction SilentlyContinue) }

if (-not (Have python) -and -not (Have py)) {
Say "Python 3.9+ is required but was not found. Install Python first."; exit 1
}
if (Have pipx) {
Say "Installing with pipx (isolated, recommended)..."
pipx install $Url; if ($LASTEXITCODE -eq 0) { Say "Done. Run: coldforge"; exit 0 }
}
if (Have uv) {
Say "Installing with uv..."
uv tool install $Url; if ($LASTEXITCODE -eq 0) { Say "Done. Run: coldforge"; exit 0 }
}
if (Have pip) {
Say "Installing with pip (user site)..."
pip install --user $Url; if ($LASTEXITCODE -eq 0) { Say "Done. Run: coldforge"; exit 0 }
}
Say "No packaging tool worked; falling back to a source clone."
$Tmp = Join-Path $env:TEMP "$Repo-src"
git clone --depth 1 $Git $Tmp
Say "Cloned to $Tmp - run: cd $Tmp; python -m pip install ."
44 changes: 34 additions & 10 deletions install.sh
Original file line number Diff line number Diff line change
@@ -1,10 +1,34 @@
#!/usr/bin/env sh
# Universal installer for coldforge. Prefers uv > pipx > pip; installs from the repo.
set -e
SRC="git+https://github.com/cognis-digital/coldforge.git"
echo "Installing coldforge ..."
if command -v uv >/dev/null 2>&1; then uv tool install "$SRC"
elif command -v pipx >/dev/null 2>&1; then pipx install "$SRC"
elif command -v python3 >/dev/null 2>&1; then python3 -m pip install --user "$SRC"
else echo "Need uv, pipx, or python3+pip"; exit 1; fi
echo "Done. Run: coldforge --help"
#!/usr/bin/env sh
# Comprehensive installer for cognis-digital/coldforge (Linux / macOS).
# Tries the best available method: pipx -> uv -> pip (git+https) -> from source.
# coldforge is source-available and not on PyPI; all paths install from GitHub.
set -eu

REPO="coldforge"
URL="git+https://github.com/cognis-digital/coldforge.git"
GITURL="https://github.com/cognis-digital/coldforge.git"

say() { printf '\033[1;35m[%s]\033[0m %s\n' "$REPO" "$1"; }
have() { command -v "$1" >/dev/null 2>&1; }

if ! have python3 && ! have python; then
say "Python 3.9+ is required but was not found. Install Python first."; exit 1
fi

if have pipx; then
say "Installing with pipx (isolated, recommended)..."
pipx install "$URL" && { say "Done. Run: coldforge"; exit 0; }
fi
if have uv; then
say "Installing with uv..."
uv tool install "$URL" && { say "Done. Run: coldforge"; exit 0; }
fi
if have pip3 || have pip; then
PIP="$(command -v pip3 || command -v pip)"
say "Installing with pip (user site)..."
"$PIP" install --user "$URL" && { say "Done. Run: coldforge"; exit 0; }
fi

say "No packaging tool worked; falling back to a source clone."
TMP="$(mktemp -d)"; git clone --depth 1 "$GITURL" "$TMP/$REPO"
say "Cloned to $TMP/$REPO — run: cd $TMP/$REPO && python3 -m pip install ."
Loading
Loading