← Files Investment BankingARCHIVED FILE
skills/deal-process-tracker/scripts/build_process_tracker.py
6.34 KB · Oct 2, 2026 · 00:27 UTC
#!/usr/bin/env python3
"""Build a deterministic Investment Banking deal process tracker workbook."""
from __future__ import annotations
import argparse
import json
import sys
from pathlib import Path
from typing import Any, Mapping, Sequence
PLUGIN_ROOT = Path(__file__).resolve().parents[3]
if str(PLUGIN_ROOT) not in sys.path:
sys.path.insert(0, str(PLUGIN_ROOT))
from shared.artifacts import ( # noqa: E402
artifact_item,
dict_rows_to_sheet,
support_dir,
write_artifact_manifest,
write_simple_xlsx_from_tables,
)
def load_payload(path: Path | None) -> dict[str, Any]:
if path is None:
return {}
return json.loads(path.read_text(encoding="utf-8"))
def as_rows(value: Any, fallback: list[dict[str, Any]]) -> list[dict[str, Any]]:
if isinstance(value, list) and all(isinstance(item, dict) for item in value):
return value
return fallback
def write_support_payload(
outdir: Path, payload: Mapping[str, Any], name: str = "intake.json"
) -> Path:
target = support_dir(outdir) / name
target.write_text(json.dumps(dict(payload), indent=2) + "\n", encoding="utf-8")
return target
def print_summary(
json_run_log: bool, quiet: bool, summary: dict[str, Any], human_lines: Sequence[str]
) -> None:
if json_run_log:
print(json.dumps(summary, indent=2))
elif not quiet:
for line in human_lines:
print(line)
def main() -> int:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--input", type=Path)
parser.add_argument("--output-dir", type=Path, required=True)
parser.add_argument("--json-run-log", "--json", dest="json_run_log", action="store_true")
parser.add_argument("--quiet-human-output", action="store_true")
args = parser.parse_args()
out = args.output_dir
out.mkdir(parents=True, exist_ok=True)
payload = load_payload(args.input)
buyers = as_rows(
payload.get("buyers") or payload.get("records"),
[
{
"buyer": "Example Sponsor",
"type": "Sponsor",
"status": "Not contacted",
"priority": "A",
"owner": "Associate",
}
],
)
outreach = as_rows(
payload.get("outreach"),
[
{
"buyer": buyers[0].get("buyer", "Example Sponsor"),
"last_touch": "",
"next_step": "Prepare outreach draft",
"owner": "Associate",
}
],
)
bids = as_rows(
payload.get("bids"),
[
{
"bidder": buyers[0].get("buyer", "Example Sponsor"),
"round": "IOI",
"status": "Not received",
"value": "",
"notes": "",
}
],
)
diligence = as_rows(
payload.get("diligence"),
[
{
"workstream": "Financials",
"status": "Open",
"owner": "Associate",
"blocker": "Source package not complete",
}
],
)
open_items = as_rows(
payload.get("open_items"),
[
{
"item": "Confirm process dates",
"owner": "VP",
"priority": "High",
"blocks_circulation": True,
}
],
)
sources = as_rows(
payload.get("sources"),
[
{
"source": "User/input package",
"status": "needs review",
"as_of_date": payload.get("as_of_date", "not_provided"),
}
],
)
workbook = out / "deal_process_tracker.xlsx"
write_simple_xlsx_from_tables(
workbook,
{
"Dashboard": [
["Deal Process Tracker Dashboard"],
["Company", payload.get("company", "Subject Company")],
["First read", "Use this dashboard first; intake JSON is support only."],
["Status", "Process tracker requires banker review before circulation."],
[],
["Executive Command View"],
["Top priority", open_items[0].get("item", "Review open items")],
["Next action", outreach[0].get("next_step", "Update tracker")],
[],
["Process Coverage", "Count"],
["Buyers tracked", len(buyers)],
["Bid records", len(bids)],
["Open items", len(open_items)],
],
"Buyer_Master": dict_rows_to_sheet(buyers),
"Outreach_Log": dict_rows_to_sheet(outreach),
"Bid_Grid": dict_rows_to_sheet(bids),
"Diligence_Tracker": dict_rows_to_sheet(diligence),
"Open_Items": dict_rows_to_sheet(open_items),
"Aging": [
["bucket", "count"],
["0-7 days", "review"],
["8-14 days", "review"],
["15+ days", "review"],
],
"MD_Morning_Summary": [
["item", "readout"],
["Top priority", open_items[0].get("item", "Review open items")],
["Next action", outreach[0].get("next_step", "Update tracker")],
],
"Sources": dict_rows_to_sheet(sources),
},
)
intake = write_support_payload(out, payload)
write_artifact_manifest(
out,
"deal-process-tracker",
"workbook",
workbook,
support_artifacts=[
artifact_item(
intake,
"support_artifact",
"json",
"Original tracker intake payload.",
False,
False,
"Intake JSON is support/audit material.",
),
],
blocked_or_partial_status={
"status": "partial",
"reason": "Tracker is operational but needs banker-owned process updates before circulation.",
"missing_inputs": [],
},
)
summary = {
"primary_human_deliverable": str(workbook),
"manifest": str(out / "manifest.json"),
}
print_summary(
args.json_run_log,
args.quiet_human_output,
summary,
[
"Deal process tracker complete",
f"Open first: {workbook}",
],
)
return 0
if __name__ == "__main__":
raise SystemExit(main())
SHA-256: 6f7a0bbdff903237dd004b48ac64807410721eebca4ae6d9a96a04218ad37000