diff --git a/_skill-index.md b/_skill-index.md index 7e68f79..6fcebb6 100644 --- a/_skill-index.md +++ b/_skill-index.md @@ -23,6 +23,7 @@ description: Master index of all skills in your robot assistant system. Your ass | "update the skill index," "sync the skill index," "refresh the skill index," "clean up the skill index," "garbage collect the index" | **update-skill-index** | | "add a task," "create a task," "what's on my plate," "show today's tasks," "mark that done," "delete that task," "what's due," "upcoming tasks" | **vikunja-tasks** | | "run system diagnostic," "audit my skills," "check system health," "skill audit," "health check" | **system-diagnostic** | +| "write a POV doc," "create a proof of value document," "POV criteria," "proof of concept criteria," "generate a POC document" | **pov-doc** | --- @@ -88,6 +89,12 @@ description: Master index of all skills in your robot assistant system. Your ass **File:** `skills/se-note/SKILL.md` **Dependencies:** ripgrep (rg), notes directory at ~/notes with Inbox and voice_notes subdirectories +### POV Doc +**Purpose:** Generates a customer-facing proof-of-value / proof-of-concept criteria document for Verkada physical security product evaluations (cameras, access control, visitor management, alarms). +**Triggers:** "write a POV doc," "create a proof of value document," "POV criteria," "proof of concept criteria," "generate a POC document" +**File:** `skills/pov-doc/SKILL.md` +**Dependencies:** ripgrep (rg), notes directory at ~/notes + ### System Diagnostic **Purpose:** Audits the robot assistant system for consistency and health. Checks index/folder parity, trigger collisions, skill redundancy, AGENTS.md completeness, skill file quality, build log currency, and dependency status. **Triggers:** "run system diagnostic," "audit my skills," "check system health," "skill audit," "health check" diff --git a/pov-doc/SKILL.md b/pov-doc/SKILL.md new file mode 100644 index 0000000..05ab8e2 --- /dev/null +++ b/pov-doc/SKILL.md @@ -0,0 +1,147 @@ +--- +name: pov-doc +description: This skill should be used when the user asks to "write a POV doc," "create a proof of value document," "POV criteria," "proof of concept criteria," "generate a POC document," or discusses creating a proof-of-value or proof-of-concept document for a Verkada customer evaluation. Generates a customer-facing POC/POV criteria document for Verkada physical security product evaluations. +version: 1.1.0 +--- + +# POV Doc + +Generate a proof-of-value (POV) / proof-of-concept (POC) criteria document for a Verkada customer. This document is shared with the customer to formalize the scope, success criteria, and schedule of a product evaluation. + +## Information Gathering + +Before generating the document, gather the following from the user's notes and conversation: + +1. **Customer name** and any relevant context (industry, size, location) +2. **Which Verkada products** are in scope for the POC (cameras, access control, visitor management, alarms, Command Connector, etc.) +3. **Business challenge** the customer faces with their current physical security setup +4. **Key stakeholders** (names, titles, organizations) +5. **POC timeline** (discovery date, install date, review dates, etc.) +6. **Success criteria** specific to this customer +7. **Integration requirements** (Azure AD, POS, third-party cameras, etc.) +8. **What the customer will provide** (badges, infrastructure, network, etc.) + +Search `~/notes` for account notes, meeting notes, and inbox items related to the customer to populate these fields. Use ripgrep to find relevant content across all note files. + +### Logo and Mission Statement + +In addition to the fields above, gather these for the document header: + +**Customer logo:** Search the web for the customer's official logo. Prefer high-resolution PNG files (at least 1000px wide). Good sources include the customer's website, Wikipedia/Wikimedia Commons, and official brand asset portals. Download the logo to a temporary location (e.g., `/tmp/`). If no high-res version is available, download what you can find and upscale it 4x using Pillow. + +**Customer mission statement:** Search the web for the customer's official mission statement. Prefer the most recent version from their website or official publications (district improvement plans, annual reports, etc.). If the customer has both a mission and vision statement, use the mission statement. + +Leave both as placeholders in the markdown (`` and `*"..."*`). The rendering step below will inject them into the final document. + +## Document Generation and Rendering + +### Step 1: Generate Markdown + +Follow the Document Structure section below to write the markdown document. + +### Step 2: Render to .odt + +After generating the markdown, render it to a formatted .odt file using the bundled `scripts/render_poc.py` script: + +```bash +python3 skills/pov-doc/scripts/render_poc.py \ + --input "path/to/[Customer Name] POC Criteria.md" \ + --customer-logo /tmp/customer-logo.png \ + --mission "Customer mission statement here" \ + --output "path/to/[Customer Name] POC Criteria.odt" +``` + +The script does the following: +1. Replaces logo HTML comments with the actual customer logo and Verkada logo images +2. Updates the mission statement if `--mission` is provided +3. Converts the markdown to .odt using pandoc with the clean reference template (`examples/POC Reference Template.odt`) + +The reference template carries over professional formatting (fonts, heading sizes, table styles, page margins) from the City of El Paso example without any customer-specific content. + +Dependencies: `pandoc` (on PATH), `Pillow` (for logo resizing). + +## Document Structure + +The output document must follow this structure. Each section is required unless the user explicitly says it does not apply. + +### Header +- Document title: `# **Verkada Proof of Concept Criteria**` +- Customer logo placeholder: `` +- Verkada logo placeholder: `` +- Customer mission statement (if known), formatted as a blockquote: `*"MISSION STATEMENT HERE"*` +- Table of contents with anchor links to each numbered section + +### 1. POC Goals and Overview +- **Document Purpose** - Standard boilerplate: "The document will serve as the agreement between Verkada and [Customer] as to the scope and measures of success for a proof of concept engagement to demonstrate and document the proposed physical security solution." +- **Business Challenge** - Summarize the customer's current pain points with their existing security infrastructure. Be specific, not generic. +- **Objective** - List the specific objectives of this POC. Use this opening: "Verkada will be working with [Customer] in conducting a Proof-of-Concept (POC) to demonstrate the capabilities of the Verkada Physical Security platform." Then list objectives as bullet points. + +### 2. POC Site Design +- Describe the physical deployment plan: what doors, cameras, or locations are included +- Note any special configurations (identity sync, card format, badge compatibility, etc.) +- Reference specific Verkada product pages where appropriate (link to verkada.com product URLs) + +### 3. Scope +Two subsections: +- **Verkada will provide the following:** List hardware and services by product category (Video Security, Access Control, etc.) +- **[Customer] will provide the following:** List what the customer is responsible for (badges, infrastructure, network, personnel) +- Optional: **Discussion Items** for integrations or features being evaluated but not formally in scope + +### 4. Success Criteria +Group criteria into themed subsections with bold headings. Each criterion should be a clear, measurable statement the customer can evaluate. Common themes include: +- Unified/Scalable Platform +- AI Capabilities & Advanced Features +- Integration Capabilities (list specific third-party integrations) +- Simplified Management / Bulk Operations +- Identity Management Integration +- Hardware Compatibility +- Proactive Maintenance & Updates +- Reduction in Maintenance Costs +- Scalability Without Added Complexity + +Tailor these to the customer's stated business challenge. Do not include criteria that are irrelevant to the products in scope. + +### 5. Stakeholders +A markdown table with columns: Name, Title/Role, Organization. Populate with all known stakeholders from the account notes. + +### 6. POC Schedule +A markdown table with columns: Activity, Start Date, End Date (optional), Required Personnel. +Standard activities include: Discovery, Site Walk, Installation, Configuration, Admin Scenarios Review(s), Success Criteria Review, Executive Review, Obtain Executive Approval. +Use [TBD] for dates and personnel that are not yet confirmed. + +### 7. Next Steps +Numbered list of concrete next actions. Include any steps that have already been completed with a "(Completed)" notation. + +## Style Notes + +- Keep verbiage general and boardroom-appropriate. Avoid colloquial phrases. +- Do not use exaggerated adjectives. Keep problem statements curt and factual. +- Do not surround words with quotation marks for emphasis. +- Use bold formatting sparingly: only for section sub-headings and table headers, not for emphasis within body text. +- Do not use em-dashes; use commas, colons, or parentheses instead. +- The document should read like a formal agreement between two organizations, not an internal memo. + +## Formatting Requirements + +- Output valid GitHub-flavored markdown. +- Use `##` for top-level sections within the document (numbered sections 1-7). +- Use bold with asterisks only for sub-headings within sections and table headers. +- Use markdown tables for Stakeholders and POC Schedule. +- Include `` comments as placeholders for logos and diagrams. +- Do not include horizontal rules between sections. +- Do not wrap the output in a code block; output raw markdown. + +## Examples + +Example documents are provided in the `examples/` folder: +- `examples/City of El Paso POC Criteria.md` - A completed POV document for a municipal access control evaluation +- `examples/Proof of Concept Criteria - TEMPLATE.md` - A template-style POV document for a retail environment +- `examples/POC Reference Template.odt` - Clean ODT reference template for pandoc rendering (styles only, no customer content) + +Review the markdown examples to match tone, structure, and formatting conventions. The El Paso example shows how to write a finalized document with specific details filled in. The template example shows the structure with placeholder content for a broader product evaluation. + +## Output + +Write the generated markdown document to `~/notes/Inbox/` with the filename format `[Customer Name] POC Criteria.md`. + +After rendering, the .odt file should be placed alongside the markdown or in the same location the user specifies. diff --git a/pov-doc/assets/verkada-logo.png b/pov-doc/assets/verkada-logo.png new file mode 100644 index 0000000..66bde2b Binary files /dev/null and b/pov-doc/assets/verkada-logo.png differ diff --git a/pov-doc/examples/City of El Paso POC Criteria.md b/pov-doc/examples/City of El Paso POC Criteria.md new file mode 100644 index 0000000..f955c4b --- /dev/null +++ b/pov-doc/examples/City of El Paso POC Criteria.md @@ -0,0 +1,129 @@ +# **Verkada Proof of Concept Criteria** + + + +# **Verkada logo goes here** + +# The mission of the City of El Paso is to deliver exceptional services to support a high quality of life and place for our community. + +## **Table of Contents** + +[1. POC Goals and Overview](#1-poc-goals-and-overview) +[2. POC Site Design](#2-poc-site-design) +[3. Scope](#3-scope) +[4. Success Criteria](#4-success-criteria) +[5. Stakeholders](#5-stakeholders) +[6. POC Schedule](#6-poc-schedule) +[7. Next Steps](#7-next-steps) + +## **1. POC Goals and Overview** + +### **Document Purpose** + +The document will serve as the agreement between Verkada and City of El Paso as to the scope and measures of success for a proof of concept engagement to demonstrate and document the proposed physical security solution. + +### **Challenges Facing the City** + +The City of El Paso is currently facing maintenance and efficiency challenges with their existing access control system. The primary difficulty is the time required to manage access permissions, schedules, and exceptions in bulk. This inefficiency results in significant time expenditure for the support services team, specifically Gilbert Alvarez, who must often drive to various city locations to manually configure devices that cannot be managed remotely. + +### **Objective** + +Verkada will be working with the City of El Paso in conducting a Proof-of-Concept (POC) to demonstrate the capabilities of the Verkada Physical Security platform. + +The objectives of this POC are to: + +* Demonstrate the feasibility of implementing a modern, secure, and scalable access control solution +* Validate the ease of managing access credentials and schedules in bulk +* Test and confirm compatibility with the City's existing access badges +* Demonstrate the efficiencies of having a natively integrated camera and access control platform + +## **2. POC Site Design** + +**Description** + +The design focuses on two interior doors equipped with a [Verkada Access Controller](https://www.verkada.com/access-control/ac12/) and [Reader](https://www.verkada.com/access-control/door-readers/ad34/). Each is paired with a [context camera](https://www.verkada.com/security-cameras/dome/cd63/) to provide visual verification of access events. + +The testing will utilize an existing IDF door, which provides a representative environment for typical city-wide access points. + +**Identity Synchronization** + +The POC will validate synchronization of users and groups from Azure Active Directory (Microsoft Entra ID) into the Verkada platform. This integration will automate access permissions based on group membership in AD and ensure that the badges of former employees are automatically deactivated. Single-sign-on through Microsoft Azure will also be configured for a complete integration test. (setup completed on 01/30/26) + +**Existing Card Usage** + +The existing City of El Paso access cards will be used for all existing users with access to the tst doors. + +## **3. Scope** + +The scope of this POC includes the following: + +**Verkada will provide the following:** + +* **Access Control:** + * (2) Verkada single door access control panels + * (2) Verkada Access Control Badge Readers +* **Video Security:** + * (2) Context Cameras for visual verification of access events. + +**City of El Paso will provide the following:** + +* **Badges for Testing:** Sample badges mailed to the Verkada Austin office for compatibility testing. Existing badges are compatible with Verkada controllers and readers. Badge data is stored in H10301 format. +* **Infrastructure:** Power and internet connectivity for the POC devices. + +**Discussion Items:** + +* **Command Connector:** Evaluation of the Command Connector for potential integration of existing third-party cameras + +## **4. Success Criteria** + +The success criteria for this POC are as follows: + +**Simplified Bulk Management** + +* The system must demonstrate that access permissions, user schedules, and door exceptions can be easily managed in bulk, resolving the primary pain point of the existing system. +* Configuration changes should be instant and remotely manageable, eliminating the need for site visits to configure devices. + +**Identity Management Integration** + +* The system must successfully integrate with Azure Active Directory (Microsoft Entra ID). +* Demonstrate Single Sign-On (SSO) and automatic user synchronization to manage permissions at scale. + +**Hardware Compatibility** + +* **Badge Compatibility:** The Verkada readers must successfully read the City's existing access badges (successfully verified by Connor Rhodes in Austin). + +## **5. Stakeholders** + +The stakeholders for this proof of concept are as follows: + +| Name | Title/Role | Organization | +| :---- | :---- | :---- | +| **Gilbert Alvarez** | Engineer Support Services | City of El Paso | +| **Fred Saucedo** | Deputy Chief Information Officer (CIO) | City of El Paso | +| **Brian Munoz** | Business Application Manager | City of El Paso | +| **Benny Jimenez** | Deputy Chief IT Infra. Officer | City of El Paso | + +## **6. POC Schedule** + +| Activity | Start Date | Required Personnel | +| :---- | :---- | :---- | +| Discovery Meeting | 2026-01-22 | Verkada & City of El Paso | +| Badge Compatibility Testing | 2026-02-02 | Connor Rhodes (Verkada) | +| Site Walk | 2026-02-04 | Verkada & Gilbert Alvarez | +| POC Installation | 2026-02-04 | Verkada | +| POC Configuration | 2026-02-04 | Verkada | +| Admin Scenarios Review 1 | [TBD] | Connor Rhodes & Gilbert Alvarez | +| Admin Scenarios Review 2 | [TBD] | Connor Rhodes & Gilbert Alvarez | +| Success Criteria Review | [TBD] | Verkada & Stakeholders | +| Executive Review | [TBD] | Fred Saucedo & Leadership | + +## **7. Next Steps** + +The next steps for this proof of concept are as follows: + +1. Complete badge compatibility testing in Austin (Completed) +2. Perform the POC installation with Gilbert Alvarez. +3. Test common administration scenarios with Verkada deployment +4. Collect POC feedback from El Paso IT +5. Present the POC results to IT leadership for approval +6. Discuss the timeline for a potential purchase and full deployment diff --git a/pov-doc/examples/City of El Paso POC Criteria.odt b/pov-doc/examples/City of El Paso POC Criteria.odt new file mode 100644 index 0000000..02a1db5 Binary files /dev/null and b/pov-doc/examples/City of El Paso POC Criteria.odt differ diff --git a/pov-doc/examples/Proof of Concept Criteria - TEMPLATE.md b/pov-doc/examples/Proof of Concept Criteria - TEMPLATE.md new file mode 100644 index 0000000..9f82999 --- /dev/null +++ b/pov-doc/examples/Proof of Concept Criteria - TEMPLATE.md @@ -0,0 +1,125 @@ +# **Verkada Proof of Concept Criteria** + +**[CUSTOMER LOGO]** + +*"MISSION STATEMENT"* + +**Table of Contents** + +[1. POC Goals and Overview](#1-poc-goals-and-overview) +[2. POC Site Design](#2-poc-site-design) +[3. Scope](#3-scope) +[4. Success Criteria](#4-success-criteria) +[5. Stakeholders](#5-stakeholders) +[6. POC Schedule](#6-poc-schedule) +[7. Next Steps](#7-next-steps) + +# **1. POC Goals and Overview** + +## Document Purpose + +The document will serve as the agreement between Verkada and "CUSTOMER" as to the scope and measures of success for a proof of concept engagement to demonstrate and document the proposed physical security solution to "CUSTOMER". + +## Business Challenge + +CUSTOMER is challenged with managing several antiquated on premise physical security solutions, many of which may have failing hardware. Managing these systems continues to be timely and costly. In addition, the current solutions lack modern AI capabilities, advanced analytics, continuous software development/updates, and integration into third-party software solutions and a Point-Of-Sale (POS) system. + +## Objective + +Verkada is pleased to be working with CUSTOMER in conducting a Proof-of-Concept (POC) to demonstrate the capabilities of the Verkada Physical Security platform. + +The objectives of this POC are to: + +1. Demonstrate the feasibility of implementing a physical security solution that is modern, secure, easy to use, scalable, and supports integration with third-party applications. +2. Identify any potential risks or challenges that could impact a successful POC. +3. Gather feedback from key stakeholders, to align with CUSTOMER's business challenge. + +# **2. POC Site Design** + +* MOCK STORE + + + +# **3. Scope** + +The scope of this POC includes the following: + +1. **Verkada will provide the following:** + 1. **Video Security (Cameras)** + * *Hybrid cloud cameras offer onboard storage and edge-based processing to reliably deliver AI-powered insights in real-time.* + 2. **Video Security (Command Connector)** + * *Support for non-Verkada camera hardware, to provide a path forward toward a single management platform.* +2. **CUSTOMER will provide the following:** + 1. Dedicated internet access for Verkada devices to communicate with Verkada Command + 2. Network connectivity with Power-Over-Ethernet (PoE) capability to Verkada devices + 3. Technical resources to support the installation and configuration of in scope physical security solutions + +# **4. Success Criteria** + +The success criteria for this POC are as follows: + +* **Unified, Seamless, and Scalable System** + * The POC must demonstrate the ability to integrate cameras, access control, alarms, and other systems into a single, easy-to-use platform that can be scaled across CUSTOMER's locations. + * The system should support thousands of devices and users, enabling seamless control and monitoring. +* **Qualify AI Capabilities & Advanced Features** + * The POC should successfully demonstrate the AI and advanced analytics capabilities of the platform, as well as the seamless integration across products. + * **AI Powered Search** - Use freeform text to search for people and vehicles in a highly-detailed manner. + * **AI Powered Alerts** - Alerts using freeform text search. + * **Loitering** - People or vehicles detected stationary for a period of time. + * **Crowd** - A group of people or vehicles detected. + * **Occupancy Trends** - Estimate of foot traffic at critical locations. + * **People Heatmaps** - Detailed view of activity within a building by visualizing individuals' movement history. This helps businesses analyze space utilization, identify high-traffic areas, and understand movement patterns and behavior. + * **Person of Interest** - Know when a specific face is detected on a camera in your organization, and identify when your cameras detect a specific face that you choose or upload. +* **Multi-System Integration and Simplification** + * The POC should validate Verkada's capability to integrate multiple security systems (cameras, access control, and alarms) into one platform, reducing the complexity of managing disparate systems. + * It must also prove that the platform is easy for the security team to use and maintain across different locations. +* **Proactive Maintenance and System Updates** + * The POC should show how Verkada's platform can proactively alert the team to system issues (e.g., cameras going offline) and perform automatic updates, reducing maintenance costs and avoiding system downtime. +* **Reduction in Maintenance and Break/Fix Costs** + * The system should provide evidence that it can reduce ongoing maintenance and break/fix costs compared to current systems through automated monitoring and streamlined management. + * All SKUs as part of this POC come with a 10 year warranty to ensure overall reduction of traditional device replacement cost. +* **Scalability Without Added Complexity** + * The POC must demonstrate that Verkada's platform can scale with CUSTOMER's growth without introducing additional complexity, keeping the system easy to manage even as locations and users increase. +* **Integration Capabilities** + * The POC should prove that Verkada's platform integrates seamlessly with CUSTOMER's existing systems, and can incorporate future technologies without requiring major reconfigurations. + * **Auror** - Export video archives from Verkada Command to Auror to consolidate and disseminate footage to a network of retailers and law enforcement in order to better identify repeat offenders. + * **Agilence** - Pair Verkada cameras with Agilence's advanced analytics platform to quickly identify and review suspicious transactions or operational anomalies. + * **Microsoft Entra ID** - Integrate with Microsoft Entra ID, in the following capacities: + * Security Assertion Markup Language (SAML) + * System for Cross-Domain Identity Management (SCIM) + +# **5. Stakeholders** + +The stakeholders for this proof of concept are as follows: + +| Name | Title/Role | Organization | +| :---- | :---- | :---- | +| | | | +| | | | +| | | | +| | | | +| | | | + +# **6. POC Schedule** + +| Activity | Start Date | End Date | Required Personnel | +| :---- | :---- | :---- | :---- | +| Discovery | | | Verkada | +| Mock Store Installation | | | Verkada | +| Mock Store Configuration | | | Verkada | +| Mock Store Best Practice/Training | | | Verkada | +| Site Walk(s) | | | Verkada | +| POC Installation | | | Verkada | +| POC Configuration | | | Verkada | +| Reassess Success Criteria | | | Verkada | +| Meet with Leadership / Review POC | | | Verkada | +| Obtain Executive Approval | | | Verkada | +| Purchase | | | Verkada | + +# **7. Next Steps** + +The next steps for this proof of concept are as follows: + +1. Analyze the feedback from users. +2. Present the POC to the stakeholders for approval. +3. Discuss timeline for purchase of Project. diff --git a/pov-doc/examples/Proof of Concept Criteria - TEMPLATE.odt b/pov-doc/examples/Proof of Concept Criteria - TEMPLATE.odt new file mode 100644 index 0000000..1427ef2 Binary files /dev/null and b/pov-doc/examples/Proof of Concept Criteria - TEMPLATE.odt differ diff --git a/pov-doc/scripts/render_poc.py b/pov-doc/scripts/render_poc.py new file mode 100644 index 0000000..180075e --- /dev/null +++ b/pov-doc/scripts/render_poc.py @@ -0,0 +1,252 @@ +#!/usr/bin/env python3 +""" +Render a Verkada POC Criteria markdown document as a formatted .odt file. + +This script takes a POC Criteria markdown file (generated by the pov-doc skill), +replaces logo placeholders and mission statement with actual content, and converts +the result to a professionally formatted .odt using pandoc with a reference document. + +Usage: + python render_poc.py --input --customer-logo \ + [--verkada-logo ] [--mission <"mission statement">] \ + [--reference-doc ] [--output ] + +If --verkada-logo is not provided, the Verkada logo placeholder is removed. +If --mission is not provided, the existing mission statement in the markdown is kept. +If --reference-doc is not provided, defaults to the included City of El Paso reference. +If --output is not provided, defaults to the input filename with .odt extension. + +Dependencies: + - pandoc (must be installed and on PATH) + - Pillow (for logo resizing) +""" + +import argparse +import os +import re +import subprocess +import sys +import tempfile +from pathlib import Path + + +def find_skill_dir() -> Path: + """Locate the pov-doc skill directory relative to this script.""" + return Path(__file__).resolve().parent.parent + + +def find_reference_doc() -> Path: + """Find the default reference ODT template in the skill's examples directory.""" + skill_dir = find_skill_dir() + ref = skill_dir / "examples" / "POC Reference Template.odt" + if ref.exists(): + return ref + # Fallback: look for the El Paso doc and warn + alt = skill_dir / "examples" / "City of El Paso POC Criteria.odt" + if alt.exists(): + print("Warning: using City of El Paso reference (may carry over logos). " + "Run create_reference_template() to generate a clean template.", + file=sys.stderr) + return alt + return None + + +def find_verkada_logo() -> Path: + """Find the bundled Verkada logo in the skill's assets directory.""" + skill_dir = find_skill_dir() + logo = skill_dir / "assets" / "verkada-logo.png" + if logo.exists(): + return logo + return None + + +def resize_logo_if_needed(input_path: str, max_width_inches: float = 2.75, dpi: int = 150) -> str: + """ + Resize a logo image if it exceeds the target width for print. + Returns the path to the (possibly new) resized image. + """ + try: + from PIL import Image + img = Image.open(input_path) + width_px, height_px = img.size + max_width_px = int(max_width_inches * dpi) + + if width_px > max_width_px: + ratio = max_width_px / width_px + new_size = (max_width_px, int(height_px * ratio)) + img_resized = img.resize(new_size, Image.LANCZOS) + + # Write resized version to a temp file + fd, out_path = tempfile.mkstemp(suffix=".png") + os.close(fd) + img_resized.save(out_path, "PNG") + return out_path + + return input_path + except ImportError: + print("Warning: Pillow not installed, skipping logo resize", file=sys.stderr) + return input_path + + +def process_markdown( + md_content: str, + customer_logo_path: str, + verkada_logo_path: str | None, + mission_statement: str | None, +) -> str: + """ + Process the markdown content: + 1. Replace logo HTML comments with markdown image syntax + 2. Optionally update the mission statement + 3. Remove the Table of Contents section (pandoc can generate one) + """ + + # Replace customer logo placeholder (match any logo comment that is NOT Verkada) + md_content = re.sub( + r'\s*\n?', + f'![Customer Logo]({customer_logo_path})\n\n', + md_content, + flags=re.IGNORECASE, + ) + + # Replace Verkada logo placeholder + if verkada_logo_path: + md_content = re.sub( + r'\s*\n?', + f'![Verkada Logo]({verkada_logo_path})\n', + md_content, + flags=re.IGNORECASE, + ) + else: + # Remove the Verkada logo placeholder entirely + md_content = re.sub( + r'\s*\n?', + '', + md_content, + flags=re.IGNORECASE, + ) + + # Update mission statement if provided + if mission_statement: + # Match the existing italicized mission statement + md_content = re.sub( + r'\*"[^"]*"\*\s*\n', + f'*"{mission_statement}"*\n\n', + md_content, + ) + + return md_content + + +def convert_with_pandoc(md_path: str, output_path: str, reference_doc: str) -> bool: + """Convert markdown to .odt using pandoc with a reference document.""" + cmd = [ + "pandoc", + md_path, + "-o", output_path, + "--from", "markdown", + "--to", "odt", + "--reference-doc", reference_doc, + ] + + try: + result = subprocess.run(cmd, capture_output=True, text=True, timeout=30) + if result.returncode != 0: + print(f"pandoc error: {result.stderr}", file=sys.stderr) + return False + return True + except FileNotFoundError: + print("Error: pandoc not found. Install it with your package manager.", file=sys.stderr) + return False + except subprocess.TimeoutExpired: + print("Error: pandoc timed out", file=sys.stderr) + return False + + +def main(): + parser = argparse.ArgumentParser( + description="Render a Verkada POC Criteria markdown document as a formatted .odt file." + ) + parser.add_argument("--input", "-i", required=True, help="Path to the POC Criteria markdown file") + parser.add_argument("--customer-logo", required=True, help="Path to the customer logo image") + parser.add_argument("--verkada-logo", help="Path to the Verkada logo image (optional)") + parser.add_argument("--mission", help="Customer mission statement (replaces existing)") + parser.add_argument("--reference-doc", help="Path to reference .odt for formatting") + parser.add_argument("--output", "-o", help="Output .odt path (default: same as input with .odt)") + + args = parser.parse_args() + + # Validate input file + input_path = Path(args.input) + if not input_path.exists(): + print(f"Error: input file not found: {input_path}", file=sys.stderr) + sys.exit(1) + + # Validate customer logo + if not os.path.isfile(args.customer_logo): + print(f"Error: customer logo not found: {args.customer_logo}", file=sys.stderr) + sys.exit(1) + + # Find reference doc + reference_doc = args.reference_doc or find_reference_doc() + if not reference_doc or not Path(reference_doc).exists(): + print("Error: reference document not found. Provide --reference-doc or place the " + "City of El Paso POC Criteria.odt in the skill's examples directory.", + file=sys.stderr) + sys.exit(1) + + # Find Verkada logo + verkada_logo = args.verkada_logo or find_verkada_logo() + if verkada_logo and not Path(verkada_logo).exists(): + verkada_logo = None + + # Determine output path + if args.output: + output_path = args.output + else: + output_path = str(input_path.with_suffix(".odt")) + + # Resize logos for print + customer_logo_resized = resize_logo_if_needed(args.customer_logo) + verkada_logo_resized = resize_logo_if_needed(verkada_logo) if verkada_logo else None + + # Read and process markdown + md_content = input_path.read_text(encoding="utf-8") + processed = process_markdown( + md_content, + customer_logo_resized, + verkada_logo_resized, + args.mission, + ) + + # Write processed markdown to temp file (so image paths work) + fd, temp_md = tempfile.mkstemp(suffix=".md") + os.close(fd) + try: + with open(temp_md, "w", encoding="utf-8") as f: + f.write(processed) + + # Convert with pandoc + print(f"Converting {input_path.name} to {output_path}...") + print(f" Reference doc: {reference_doc}") + if verkada_logo: + print(f" Verkada logo: {verkada_logo}") + + success = convert_with_pandoc(temp_md, output_path, reference_doc) + + if success: + out_size = os.path.getsize(output_path) + print(f"Done: {output_path} ({out_size:,} bytes)") + else: + sys.exit(1) + finally: + # Clean up temp files + os.unlink(temp_md) + if customer_logo_resized != args.customer_logo: + os.unlink(customer_logo_resized) + if verkada_logo_resized and verkada_logo_resized != verkada_logo: + os.unlink(verkada_logo_resized) + + +if __name__ == "__main__": + main()