"use strict";exports.id=511,exports.ids=[511,4143],exports.modules={511:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{Oj:()=>W,Y:()=>G,o8:()=>N});var e=c(73024),f=c(76760),g=c(60105),h=c(14743),i=c(19151),j=c(2167),k=c(78224),l=c(89847),m=c(1623),n=c(8727),o=c(91648),p=c(26531),q=c(40718),r=c(23230),s=c(83963),t=c(63332),u=c(64143),v=c(61423),w=c(81833),x=a([g,h,i,j,k,m,n,o,q,r,s,t,v,w]);[g,h,i,j,k,m,n,o,q,r,s,t,v,w]=x.then?(await x)():x;let T=`You are a senior UI/UX engineer producing a production-grade HTML file.

ABSOLUTE BANS — zero tolerance:
- ZERO EMOJIS — anywhere, ever. No emoji icons, no decorative emoji, no bullet emoji, no status emoji, no Unicode symbols used as graphics. This rule has no exceptions regardless of style or context.
- ALL icons and illustrations must be hand-drawn inline SVG. Draw them in the Lucide/Heroicons style: 24\xd724 viewBox, 1.5-2px stroke, strokeLinecap="round", strokeLinejoin="round", fill="none". For decorative illustrations use CSS shapes or geometric SVG — never clip-art, stock emoji, or Unicode glyphs.
- NO generic dark themes with uniform gray cards and no hierarchy
- NO default system fonts (Inter, Roboto, Arial) without design justification
- NO gradient text
- NO side-stripe colored card borders (left/top accent strips) — this is AI slop
- NO centered-everything monotonous layouts — break symmetry, create visual tension
- NO uniform identical card grids — vary sizes, emphasis, weight
- NO placeholder-quality elements — every part must be production-ready

TYPOGRAPHY:
- Clear scale: display (56-96px, lh 0.9-1.0), heading (24-40px, lh 1.1-1.2), body (15-17px, lh 1.6-1.7), caption (11-13px)
- Tight letter-spacing on large type (−0.04em to −0.08em), normal on body
- Import one quality Google Font or use system-ui with a strong type scale

COLOR:
- Max 2 accent colors, intentional palette, not random
- Strong contrast ratios — text must be readable
- Use color purposefully to guide hierarchy

LAYOUT:
- Asymmetric or varied — not monotonous equal grids
- Generous whitespace (48-96px section padding)
- Clear visual hierarchy directing the eye

MOTION:
- Subtle transitions: 150-300ms ease
- No bounce, elastic, or excessive animation
- Hover states on all interactive elements

VISIBILITY — non-negotiable:
- ALL content must be fully visible immediately on page load — no exceptions
- NEVER set opacity: 0, visibility: hidden, or display: none on any content element as an initial state
- NEVER use IntersectionObserver, scroll event listeners, or any scroll-based reveals
- NEVER use [data-aos], AOS library, ScrollReveal, or any third-party scroll animation library
- CSS transitions and animations (fade-in, slide-in) are only allowed for elements that START visible (opacity: 1)

JAVASCRIPT — strict limits:
- Use JavaScript only for essential interactions: tab switching, accordion open/close, modal open/close, slide-deck navigation
- NO scroll-triggered effects or animations of any kind
- NO IntersectionObserver, scroll event listeners, or scroll-based reveals
- NO parallax, sticky-header shrink effects, or scroll-based class toggling
- NO animation libraries (GSAP, AOS, Animate.css, etc.)
- All motion must be CSS transitions/animations only — not JavaScript-driven
- If in doubt, leave JavaScript out entirely

PRESENTATIONS / SLIDE DECKS — when the request is for a multi-page deck, pitch, slides, or "presentation":
- Wrap slides in a container with class="slides" (or include the word "slide" in the container class). Each slide gets class="slide" (or similar — the substring "slide" must appear in the class name). This signals the renderer that these elements use intentional opacity/visibility toggling.
- Show exactly one slide at a time. Toggle a CSS class (e.g. ".slide.active") to show the current slide. Use CSS opacity/visibility OR display:none — both work because slide containers are exempt from the renderer's reveal pass.
- Navigation controls must be <button> elements, NOT <a href="#"> anchors. Listen for click events plus keyboard ArrowLeft / ArrowRight on document.
- Show a slide counter formatted with leading zero: "01 / 09". Update it whenever the active slide changes.
- Do not use horizontal scroll, transform: translateX(-N*100%) sliders, or any technique that depends on the iframe being a specific size — slides should fit the iframe viewport individually.
- Each slide should fill the iframe viewport (100vh / 100vw container, slides absolutely positioned or flex-centered).

TECHNICAL:
- Single complete HTML file, CSS embedded in <style>
- No external dependencies except Google Fonts
- Fully responsive (mobile / tablet / desktop)
- Semantic HTML5

OUTPUT: HTML only. No markdown fences. No explanation. Start with <!DOCTYPE html>.`,U={balanced:"",minimal:"\nSTYLE — MINIMAL: Extreme restraint. Near-monochrome palette (black, white, one subtle accent). Maximum whitespace. Typography-first layout. No decorative elements. Every pixel earns its place.",bold:"\nSTYLE — BOLD: High contrast. Large commanding typography. Strong visual weight. Dark backgrounds or very high-contrast light. Dramatic hierarchy. Assertive, confident presence.",soft:"\nSTYLE — SOFT: Warm gentle palette. Rounded corners everywhere (16-24px). Subtle soft shadows. Light, airy feel. Pastel or muted accent colors. Comfortable, inviting reading experience."};async function y({description:a,project_id:b=null}){let c=(0,m.wA)(),d=(0,o.$F)(),e=`${T}${U[c]??""}

${(0,o.nX)(d)}`,f=await (0,i.chatWithClaude)([{role:"user",content:`Build this UI: ${a}`}],e),h=(0,n.vr)(f.content[0]?.text?.trim()??""),j=a.slice(0,80);return{...(0,g.Dg)({title:j,kind:"html",content:h,project_id:b}),style:c}}async function z({prompt:a,title:b,session_id:c,model:d,timeout_ms:e,project_id:f=null}){let h=(0,l.ZQ)(a),i=await (0,j.Nw)({prompt:h,session_id:c,model:d,timeout_ms:e}),k=b||`Hermes result: ${a.slice(0,60)}`,m=(0,l.un)(i.response,{title:k}),n=m.violations?.length?`

---

*Format enforcement — source: ${m.source}; violations: ${m.violations.join(", ")}*`:"",o=`${m.content||"(no response)"}${n}`;return{...(0,g.Dg)({title:k,kind:"markdown",content:o,project_id:f}),hermes_session_id:i.session_id,hermes_model:i.model,format_source:m.source,format_ok:m.ok,format_violations:m.violations,mocked:!0===i.mocked}}async function A({prompt:a,title:b,session_id:c,model:d,timeout_ms:e,cwd:f,project_id:g=null}){let h=(0,k.o0)({prompt:a,title:b,session_id:c,model:d,timeout_ms:e,cwd:f,project_id:g});return"1"!==process.env.HERMES_JOB_DISABLE_SPAWN&&(0,k._3)(h.id),{job_id:h.id,artifact_id:h.artifact_id,run_id:h.run_id,file_path:h.file_path,status:h.status,title:h.title}}async function B(a={}){let b,c=null;if(a.file_path){let{path:d}=(0,p.hC)(a.file_path),g=e.statSync(d);if(!g.isFile())throw Error("Brand guidelines path is not a file");if(g.size>2e6)throw Error(`Brand guidelines file is too large: ${g.size} bytes`);let h=f.extname(d).toLowerCase();if(![".html",".htm",".md",".txt",".css",".svg",".pdf"].includes(h))throw Error("Supported guidelines formats: .html, .md, .txt, .css, .svg, .pdf");b=(0,o.hO)(d),c=d}else if(a.content)b=(0,o.RN)(a.content,a.filename||"inline-brand-guidelines.md"),c=a.filename||"inline content";else throw Error("Provide either file_path or content");if(a.logo_path){let{path:c}=(0,p.hC)(a.logo_path),d=e.statSync(c);if(!d.isFile())throw Error("Logo path is not a file");if(d.size>1e6)throw Error(`Logo file is too large: ${d.size} bytes`);let g=f.extname(c).toLowerCase();if(![".svg",".png",".jpg",".jpeg",".webp"].includes(g))throw Error("Supported logo formats: .svg, .png, .jpg, .jpeg, .webp");b=(0,o.xo)(c)}return{ok:!0,imported_from:c,brand:{active:b.active,company_name:b.company_name,colors:b.colors,fonts:b.fonts,voice:b.voice,document_types:b.document_types,presentation_style:b.presentation_style,guidelines_path:b.guidelines_path,logo_path:b.logo_path}}}function C(a){return(a?.content||[]).filter(a=>a?.type==="text"||"string"==typeof a?.text).map(a=>a.text||"").join("\n").trim()}async function D({name:a,mission:b,tools:c}){try{let d=await (0,i.chatWithClaude)([{role:"user",content:`Write the skills.md file for a new local sub-agent.

<agent_name>${a}</agent_name>
<agent_mission>${b}</agent_mission>
<allowed_tools>${c.join(", ")||"web-search, browser, files, cron"}</allowed_tools>

Return a markdown document with:
- An H1 title "# ${a} Skills"
- A short "## Mission" section restating the mission in one line.
- A "## Core playbooks" section with 4 to 6 bullets, each a concrete, mission-specific play this agent will run (not generic boilerplate). Bullets must reflect the mission and use the listed tools where relevant.
- A "## Operating limits" section with 2-3 bullets covering approval, workspace boundaries, and heartbeat updates.

Hard rules: zero emojis, no decorative symbols, no horizontal rules, plain markdown only, no extra commentary outside the file content.`}],"You write concise, mission-specific playbooks for local-first AI agents. Output the markdown file content only, no preamble."),e=C(d);if(!e)return null;return e}catch{return null}}async function E(a){let b=Array.isArray(a.tools)?a.tools:String(a.tools||"").split(",").map(a=>a.trim()).filter(Boolean),c=a.name||"madarX Custom Agent",d=a.mission||"Support the user with scheduled local work.",e=null;try{let a=await (0,i.chatWithClaude)([{role:"user",content:`Create a focused system prompt for this scheduled local agent.

<agent_name>${c}</agent_name>
<agent_mission>${d}</agent_mission>
<allowed_tools>${b.join(", ")}</allowed_tools>

Return only the system prompt text. It must preserve human approval before external sends/posts/deployments and keep work inside the local workspace.`}],"You write concise, operational system prompts for local-first AI agents. Return plain text only.");e=C(a)}catch{e=null}let f=await D({name:c,mission:d,tools:b}),h=(0,n.vr)(f||function({name:a,mission:b,tools:c}){let d=c.length?c.join(", "):"web search, browser, files";return`# ${a} Skills

## Mission
${b}

## Core playbooks
- Plan each run from the mission above, then execute against the schedule window.
- Use only the approved tools (${d}); never reach for tools the owner has not enabled.
- Save every output as a local artifact under your project's artifacts folder (workspace/projects/<slug>/artifacts/).
- Hand off any external send, post, deployment, or destructive command to the main agent for approval before acting.
- After each run, update heartbeat.json with status, summary, and next-run plan.
`}({name:c,mission:d,tools:b})),j={...a,name:c,mission:d,tools:b,skills_markdown:h};return e&&(j.system_prompt=e),void 0!==a.whatsapp_notify_chat_id&&(j.whatsapp_notify_chat_id=a.whatsapp_notify_chat_id||null),(0,g.Sn)(j)}let V="tool-smith-agent";function F(a){return String(a||"").toLowerCase().replace(/[._-]+/g," ").split(/[^a-z0-9]+/).filter(a=>a.length>=3)}let W=[{name:"create_agent",description:"Create a new named sub-agent in the local workspace with files and optional schedule. Pick the engine based on what the agent actually does (see engine field).",input_schema:{type:"object",properties:{name:{type:"string",description:"Human-readable agent name."},mission:{type:"string",description:"What this agent does (its standing job — used as the default instruction every run)."},expected_output:{type:"string",description:"OPTIONAL standing deliverable contract: what a GOOD result looks like every run — format, required sections, acceptance criteria, definition of done. Set this whenever the agent has a repeatable output shape so runs are consistent and verifiable. A per-call run_agent override or a delegated task's acceptance_criteria takes precedence over this for a specific run."},schedule:{type:"string",description:'Cron-like schedule: "daily HH:MM", "every 5m", or "on demand".'},tools:{type:"array",items:{type:"string"},description:'madarX tool identifiers the agent is allowed to use (e.g. "web_search", "web_fetch", "file_read", "create_artifact"). Lowercase snake_case, NOT Claude Code tool names.'},type:{type:"string",description:'Agent type label, e.g. "custom" or "intelligence".'},engine:{type:"string",enum:["anthropic","claude-code","ollama","codex","hermes"],description:'DEFAULT is "claude-code" — uses the local Claude Code CLI with permissions from .claude/settings.json (Read/Glob/Grep/WebSearch/WebFetch auto-allowed; edits scoped to workspace/). Use this for almost everything. "anthropic" only when the agent needs the madarx tool marketplace specifically (create_artifact, generate_ui, whatsapp_send, competitor_report, marketing_plan — these do not exist under claude-code). "ollama" for cheap local-LLM work. "codex" for OpenAI Codex CLI. "hermes" rare. If the user does not specify, leave engine unset and the default applies.'},whatsapp_notify_chat_id:{type:"string",description:'OPTIONAL WhatsApp chat id (e.g. 9715XXXXXXXX@s.whatsapp.net, or plain digits). When set, every scheduled run that produces a report artifact will auto-deliver the rendered HTML file to this chat. The bridge must be paired; if not, delivery is skipped silently. Set this only when the owner explicitly says "send to whatsapp" or "deliver to me on whatsapp".'}},required:["name","mission"]}},{name:"set_agent_whatsapp_notify",description:'Enable, change, or disable WhatsApp delivery of scheduled-run artifacts for an existing agent. Pass an empty string or null in chat_id to disable. Use this when the owner says "send X to me on whatsapp", "stop whatsapping me X", or wants to switch the notify chat. The bridge must be paired for delivery to actually happen; the setting is stored either way.',input_schema:{type:"object",properties:{agent_id:{type:"string",description:"Slug id of the agent. Use get_state to look it up if unsure."},agent_name:{type:"string",description:"Fuzzy human-readable name (used only when agent_id is missing)."},chat_id:{type:"string",description:"WhatsApp chat id to receive scheduled HTML artifacts. Pass empty string to disable."}},required:["chat_id"]}},{name:"upsert_schedule",description:"Create or update a recurring schedule for an existing agent.",input_schema:{type:"object",properties:{agent_id:{type:"string",description:"Slug ID of the agent."},schedule:{type:"string",description:'Schedule spec: "daily HH:MM", "every 5m", etc.'},action_kind:{type:"string",description:'What the schedule runs: "agent-tick", "competitor-report", "marketing-plan", or "heartbeat".'},enabled:{type:"boolean",description:"Whether the schedule is active (default true)."}},required:["agent_id","schedule"]}},{name:"competitor_report",description:"Generate a daily competitor intelligence report and save it as a local artifact.",input_schema:{type:"object",properties:{triggered_by:{type:"string",description:"Source label for the audit log."}}}},{name:"marketing_plan",description:"Generate a 7-day marketing content plan and save it as a local artifact.",input_schema:{type:"object",properties:{triggered_by:{type:"string",description:"Source label for the audit log."}}}},{name:"heartbeat_tick",description:"Update the heartbeat timestamp for all generated agents.",input_schema:{type:"object",properties:{triggered_by:{type:"string",description:"Source label for the audit log."}}}},{name:"claude_dry_run",description:"Prepare a Claude Code command string for human review. Never executes automatically — requires owner approval.",input_schema:{type:"object",properties:{prompt:{type:"string",description:"The task description to pass to the Claude Code runner."}},required:["prompt"]}},{name:"get_state",description:"Retrieve a LIGHTWEIGHT snapshot of runtime state: agents, runs, schedules, connectors, and artifact metadata only. Artifact bodies are stripped to a short snippet — use find_artifacts to search and show_artifact to load full content for a specific id. Use this as a directory; never expect full document bodies here.",input_schema:{type:"object",properties:{}}},{name:"create_artifact",description:'Save a written-content artifact (report, list, plan, brief, summary, doc). Provide the body as well-structured markdown and madarX will render it into a styled HTML document automatically, with a one-click "Download .md" for the source. Do NOT include the user prompt, instructions, or meta commentary inside the body — only the result content. Do NOT use for full UI/landing pages — use generate_ui instead.',input_schema:{type:"object",properties:{title:{type:"string",description:"Short, human-readable artifact title shown in the document header."},kind:{type:"string",enum:["markdown","text"],description:'Always "markdown" unless the content is truly plain text with no structure.'},content:{type:"string",description:"The full body as GitHub-flavored markdown. Use headings (##), lists, tables, and bold sparingly. No emojis. Result content only — never echo the prompt."},project_id:{type:"string",description:"Optional destination project id or slug. Omit to use the active/default project."},space_id:{type:"string",description:"Optional dashboard space id where the artifact should appear. Omit to use the calling agent default or the main space."},dedupe_key:{type:"string",description:"Optional idempotency key. Pass empty string only when intentionally creating multiple artifacts with the same title in one day."}},required:["title","kind","content"]}},{name:"update_artifact",description:"Update an existing artifact with revised or extended content. Use this instead of create_artifact when continuing, refining, or expanding a previous result for the same task. Keeps the same artifact visible and editable rather than spawning a new one.",input_schema:{type:"object",properties:{artifact_id:{type:"string",description:"ID of the artifact to update."},title:{type:"string",description:"New title — omit to keep the existing title."},content:{type:"string",description:"Full updated body as GitHub-flavored markdown. Must be the complete content, not a diff."}},required:["artifact_id","content"]}},{name:"delete_artifact",description:"Permanently delete a saved artifact from the dashboard. Use only when the owner explicitly asks to remove or trash an artifact, or when the previous artifact is being replaced by a brand-new one and the prior result must not linger. This is irreversible from the agent side; the artifact file on disk is unlinked as well.",input_schema:{type:"object",properties:{artifact_id:{type:"string",description:"ID of the artifact to delete."}},required:["artifact_id"]}},{name:"move_artifact",description:'Move an existing artifact from one project to another. Updates the artifact\'s project_id, relocates the file on disk into the target project\'s artifacts directory, and writes changelog entries on both source and target projects. Use this when the owner asks to "move", "reassign", "relocate", or "transfer" an artifact between projects/spaces. The artifact id and title stay the same; only the project membership and disk location change.',input_schema:{type:"object",properties:{artifact_id:{type:"string",description:"ID of the artifact to move."},target_project_id:{type:"string",description:'Destination project id or slug (e.g. "planify" or "personal"). Use list_projects to discover valid values.'}},required:["artifact_id","target_project_id"]}},{name:"read_artifact",description:"Load the full content for a specific artifact after finding it. Use this before editing, summarizing, or continuing an existing document. Returns rendered content and markdown source when available.",input_schema:{type:"object",properties:{artifact_id:{type:"string",description:"Exact artifact id to read."},title_query:{type:"string",description:"Optional fuzzy title query when artifact_id is not known. Must resolve to one artifact."},max_chars:{type:"number",description:"Maximum content characters to return, default 12000."}}}},{name:"list_spaces",description:"List dashboard spaces/tabs. Use include_artifact_ids when the owner asks which artifacts are displayed in each space.",input_schema:{type:"object",properties:{include_artifact_ids:{type:"boolean",description:"When true, include artifact_ids grouped under each space."}}}},{name:"create_space",description:"Create a new dashboard space/tab where artifacts can be displayed.",input_schema:{type:"object",properties:{name:{type:"string",description:"Short dashboard space name."}},required:["name"]}},{name:"rename_space",description:"Rename an existing dashboard space/tab.",input_schema:{type:"object",properties:{space_id:{type:"string",description:"Space id to rename."},name:{type:"string",description:"New short space name."}},required:["space_id","name"]}},{name:"set_active_space",description:"Make a dashboard space/tab the active space.",input_schema:{type:"object",properties:{space_id:{type:"string",description:"Space id to activate."}},required:["space_id"]}},{name:"delete_space",description:"Delete a dashboard space/tab. Artifacts are not deleted; they are moved to a fallback space. Do not use to delete artifacts.",input_schema:{type:"object",properties:{space_id:{type:"string",description:"Space id to delete."}},required:["space_id"]}},{name:"move_artifact_to_space",description:"Display an existing artifact in a different dashboard space/tab, or remove it from a custom space by moving it back to the default main space. The artifact id, project, file, and content stay unchanged.",input_schema:{type:"object",properties:{artifact_id:{type:"string",description:"Artifact id to move between dashboard spaces."},space_id:{type:"string",description:'Destination dashboard space id. Use "default" to remove from a custom space back to main.'}},required:["artifact_id","space_id"]}},{name:"import_brand_guidelines",description:"Import a local brand guidelines file or pasted guidelines content, extract brand colors/fonts/voice/document defaults, and set it as the default brand system for future documents, presentations, and generated UI artifacts. Use this when the owner provides a brand guidelines HTML/Markdown/text file path, pastes guidelines content, or asks to update branding.",input_schema:{type:"object",properties:{file_path:{type:"string",description:"Path to a local .html, .md, .txt, .css, .svg, or .pdf brand guidelines file under an allowed root."},content:{type:"string",description:"Pasted brand guidelines content when no local file path is available."},filename:{type:"string",description:"Optional filename for pasted content, e.g. brand-guidelines.md."},logo_path:{type:"string",description:"Optional local path to the primary brand logo file (.svg, .png, .jpg, .jpeg, .webp)."}}}},{name:"generate_ui",description:"Build a production-quality HTML/CSS UI — landing page, dashboard, component, presentation, or any visual interface. Automatically applies professional design rules (typography scale, intentional color, no generic AI patterns). Use this for ALL HTML/UI creation requests.",input_schema:{type:"object",properties:{description:{type:"string",description:"What to build — be specific: layout, sections, content, purpose, and any brand or color hints."}},required:["description"]}},{name:"send_to_hermes",description:"Send a command or task to the local Hermes agent and save the final Hermes response as a dashboard artifact. Use this when the user asks Hermes to do work, wants a Hermes result, or asks to route a command through Hermes.",input_schema:{type:"object",properties:{prompt:{type:"string",description:"The exact task or command Hermes should run."},title:{type:"string",description:"Optional artifact title for the Hermes result."},session_id:{type:"string",description:"Optional stable Hermes session id. Usually omit."},model:{type:"string",description:"Optional Hermes model override. Usually omit so Hermes uses its configured model."},timeout_ms:{type:"number",description:"Optional timeout in milliseconds. Use 600000 or higher for project run/build tasks."}},required:["prompt"]}},{name:"start_hermes_job",description:"Start a long-running local Hermes job in the background and immediately create a live-updating dashboard artifact. Use for running projects, builds, tests, installs, dev servers, or multi-step Hermes work that may take more than a minute.",input_schema:{type:"object",properties:{prompt:{type:"string",description:"The full task Hermes should perform."},title:{type:"string",description:"Artifact/job title."},session_id:{type:"string",description:"Optional Hermes session id."},model:{type:"string",description:"Optional Hermes model override."},timeout_ms:{type:"number",description:"Optional job timeout in milliseconds. Use 1800000 for long project tasks."},cwd:{type:"string",description:"Optional absolute working directory for the project Hermes should run."}},required:["prompt"]}},{name:"run_agent",description:'Run an existing sub-agent NOW (on demand, outside its normal schedule). Use this when the owner says "run X", "trigger X", "do today\'s run of X", etc. The run executes synchronously and publishes live tool-call events to the dashboard. Returns the run summary and a short result preview.',input_schema:{type:"object",properties:{agent_id:{type:"string",description:'Slug id (e.g. "uae-ai-initiatives-tracker"). Prefer this if known. Use list_agents / get_state first to look it up.'},agent_name:{type:"string",description:'Fuzzy human-readable name (e.g. "UAE tracker"). Used only if agent_id is not provided. Case-insensitive substring match against agent names; ambiguous matches error.'},wake_reason:{type:"string",description:'Short label for the audit log, e.g. "owner requested via whatsapp".'},instruction:{type:"string",description:"OPTIONAL task-specific instruction for THIS run only — what to do right now. Overrides the agent's standing mission for this single run; never saved onto the agent. Use it to dispatch an existing agent at an ad-hoc job (e.g. \"compare this week's numbers to last week and flag anomalies\"). Omit to run the agent's standing mission. The agent can still only use the tools it was granted — this does not expand its permissions."},expected_output:{type:"string",description:"OPTIONAL deliverable contract for THIS run only — what a complete, correct result must contain (format, sections, acceptance criteria). Overrides the agent's standing expected_output for this run. Use it to pin down what 'done' looks like for an ad-hoc instruction."}}}},{name:"mines_run_report",description:'Generate ONE mines diligence report for a project as a single action (the workflow authors the number-free narrative and the report tool renders every figure from cited database rows). Use report_kind "pfs_readiness_report" when the owner asks to "assess PFS readiness". The report\'s LLM authoring runs on the configured engine (Claude Code CLI for the personal tier, Anthropic API for production) — it works even when no Anthropic API key is set. Returns the artifact id.',input_schema:{type:"object",properties:{project_id:{type:"string",description:"mines_projects.id. Use list/get_state or find the project first if unknown."},report_kind:{type:"string",description:"One of: pfs_readiness_report, due_diligence_memo, investor_presentation, data_quality_report, interpretation_memo."},engine:{type:"string",description:'OPTIONAL engine override: "claude-code" (personal CLI subscription) or "anthropic" (production API). Defaults to the mines agents\' configured engine. This is a cost/scale tier, not a capability change.'}},required:["project_id","report_kind"]}},{name:"find_artifacts",description:'Search past artifacts (reports, briefs, generated UIs) by title, agent, or kind. Use when the owner asks for "the latest X report", "send me yesterday\'s brief", or "what did <agent> produce". Returns up to 50 rows, most recent first, with id/title/kind/agent_name/created_at — NOT the full content. To deliver one, follow up with send_artifact_to_whatsapp. SEARCH BROADLY: title_query does word-level matching (every word must appear, any order), but if the first query returns 0 rows, RETRY with a shorter / broader query — try just the noun ("brief", "report") before concluding nothing exists. Real titles often include words the owner did not say (e.g. "AI Daily Brief scheduled report" vs the owner saying "AI brief").',input_schema:{type:"object",properties:{title_query:{type:"string",description:'Fuzzy substring of the artifact title (case-insensitive). E.g. "conflict" matches "Conflict brief 2026-05-13".'},agent_id:{type:"string",description:"Filter to one specific agent id."},agent_name:{type:"string",description:'Fuzzy substring of the agent name (case-insensitive). E.g. "conflict" matches "Conflict Brief Agent".'},kind:{type:"string",description:'Filter by kind: "html", "document" (rendered markdown), or other.'},project_id:{type:"string",description:"Filter to one project id or slug."},space_id:{type:"string",description:'Filter to one dashboard space id, e.g. "default".'},limit:{type:"number",description:"Max rows to return (default 10, max 50)."}}}},{name:"send_artifact_to_whatsapp",description:'Deliver an existing artifact as an .html file to a WhatsApp chat. Use after find_artifacts (or get_state) to send a past report on demand — e.g. "send me the latest conflict brief on whatsapp". Pass either artifact_id (preferred) or title_query (fuzzy match — must resolve to one row). If chat_id is omitted on the WhatsApp channel, defaults to the chat the owner is messaging from. The WhatsApp bridge must be paired.',input_schema:{type:"object",properties:{artifact_id:{type:"string",description:"Exact artifact id (preferred). Get this from find_artifacts."},title_query:{type:"string",description:"Fuzzy substring of the title. Used only when artifact_id is omitted; ambiguous matches error."},chat_id:{type:"string",description:"WhatsApp chat id to deliver to. Omit on inbound WhatsApp to send back to the same chat."}}}},{name:"whatsapp_send",description:'Send a WhatsApp message to a chat the owner has added to the allowlist. Use sparingly for proactive owner alerts and follow-ups (e.g., "scheduled report is ready"). The bridge must be paired and online; if not, this returns an error.',input_schema:{type:"object",properties:{chat_id:{type:"string",description:"Allowlisted WhatsApp chat id (full JID like 9715XXXXXXXX@s.whatsapp.net, or plain digits which are normalized)."},text:{type:"string",description:"Plain text message body. WhatsApp does not render markdown — keep it conversational."}},required:["chat_id","text"]}},{name:"list_available_tools",description:'List all marketplace tools with their enabled status, availability, risk level, and missing credentials. Use this before saying "I cannot do X" to check whether a tool exists. Filter by category (travel, web, github, email, supabase, vercel, local_machine, browser, voice, calendar) or by enabled_only to see what is currently active.',input_schema:{type:"object",properties:{category:{type:"string",description:"Optional category filter: travel, web, github, email, supabase, vercel, local_machine, browser, voice, calendar."},enabled_only:{type:"boolean",description:"When true, return only currently-enabled tools."}}}},{name:"install_tool",description:"Enable a marketplace tool by name so it becomes available for immediate use. Call this after list_available_tools identifies a disabled tool that can satisfy the principal's request. If the tool has missing credentials, the response includes a missing_credentials list — surface this to the principal. Tools rated irreversible_external will still require per-call owner approval when invoked.",input_schema:{type:"object",properties:{tool_name:{type:"string",description:'Exact tool name from list_available_tools, e.g. "flight_search" or "hotel_rates".'}},required:["tool_name"]}},{name:"uninstall_tool",description:"Disable a marketplace tool by name. Use when the principal asks to turn off a tool or when a tool is causing issues.",input_schema:{type:"object",properties:{tool_name:{type:"string",description:'Exact tool name to disable, e.g. "email_send".'}},required:["tool_name"]}},{name:"request_capability",description:'Delegate to Tool Smith to BUILD a capability that does not exist yet. Use when an agent needs a tool/skill/integration the system lacks (e.g. "log meetings to Notion" with no Notion tool). First dedupes against existing capabilities; if none matches, files a build task for the tool-smith-agent which authors a composite tool, a REST connector, a skill, or proposes code. Returns the task id. The authored capability is still subject to all runtime gates when used.',input_schema:{type:"object",properties:{capability_description:{type:"string",description:'Plain-language description of the capability needed, e.g. "create pages in Notion" or "summarize a daily competitor digest".'},target_agent_id:{type:"string",description:"Optional id of the agent that should be granted the capability once built."},acceptance_criteria:{type:"string",description:"Optional explicit acceptance criteria for the build."}},required:["capability_description"]}}],X=new Set(["send_to_hermes","start_hermes_job"]);function G(){let a=(0,j.oG)()?W:W.filter(a=>!X.has(a.name));return(0,q.Cz)(a)}function H(a,b=180){let c="string"==typeof a?a:null==a?"":String(a);return c.length<=b?c:c.slice(0,b)+`…[+${c.length-b} bytes, use show_artifact/find_artifacts]`}function I(a){if(!a)return a;let b="string"==typeof a.content?a.content:"";return{id:a.id,title:a.title,kind:a.kind,project_id:a.project_id??null,created_at:a.created_at,updated_at:a.updated_at,content_bytes:b.length,content_preview:b?H(b):""}}function J(a){if(!a)return a;let b=Array.isArray(a.memory)?a.memory.slice(-2):[];return{id:a.id,name:a.name,engine:a.engine,status:a.status,project_id:a.project_id??null,schedule:a.schedule,last_run_at:a.last_run_at??null,tools_count:Array.isArray(a.tools)?a.tools.length:0,memory_count:Array.isArray(a.memory)?a.memory.length:0,memory_recent:b.map(a=>"string"==typeof a?H(a,200):a)}}function K(a){return a?{id:a.id,agent_id:a.agent_id??null,project_id:a.project_id??null,status:a.status,started_at:a.started_at,finished_at:a.finished_at??null,summary:H(a.summary??a.note??"",160)}:a}function L(a){return a?{id:a.id,action_type:a.action_type,status:a.status,requested_at:a.requested_at,agent_id:a.agent_id??null,summary:H(a.summary??a.note??"",160)}:a}function M(a){return a?{id:a.id,schedule_id:a.schedule_id??null,agent_id:a.agent_id??null,status:a.status,scheduled_for:a.scheduled_for??null,attempts:a.attempts??0}:a}async function N(a,b={},c={}){let d;var e=await O(a,b,c);try{d=JSON.stringify(e)}catch{return e}return!d||d.length<=6e4?e:{ok:!1,truncated:!0,original_bytes:d.length,max_bytes:6e4,preview:d.slice(0,59744),error:`tool_result exceeded 60000 bytes (got ${d.length}); narrow the query or use show_artifact for a specific id.`}}async function O(a,b={},c={}){switch(a){case"create_agent":return E(b);case"upsert_schedule":return(0,g.Nv)(b);case"competitor_report":return(0,g.NK)({triggered_by:b.triggered_by??"claude"});case"marketing_plan":return(0,g.mk)({triggered_by:b.triggered_by??"claude"});case"heartbeat_tick":return(0,g.IG)({triggered_by:b.triggered_by??"claude"});case"claude_dry_run":return(0,g.nF)({prompt:b.prompt},{triggered_by:"claude"});case"get_state":{let a=b.project_id??null;var d,e,f=(0,g.Gu)({project_id:a?String(a):null});if(!f||"object"!=typeof f)return f;return{ok:f.ok,product:f.product,workspace:f.workspace,project_filter:f.project_filter,projects:f.projects,agents:Array.isArray(f.agents)?f.agents.map(J):f.agents,tasks:f.tasks,runs:Array.isArray(f.runs)?f.runs.slice(0,8).map(K):f.runs,audit:(d=f.audit,(Array.isArray(d)?d.slice(0,6):[]).map(a=>({id:a.id,type:a.type,at:a.at,actor:a.user_id||a.acting_on_behalf_of_user_id||null,target:a.action_target_id??null,note:H(a.note??a.detail??"",160)}))),activity:(e=f.activity,(Array.isArray(e)?e.slice(0,10):[]).map(a=>({id:a.id,type:a.type,at:a.at,agent_id:a.agent_id??null,project_id:a.project_id??null,summary:H(a.summary??a.detail??"",160)}))),schedules:f.schedules,connectors:f.connectors,artifacts:Array.isArray(f.artifacts)?f.artifacts.map(I):f.artifacts,heartbeat_tasks:Array.isArray(f.heartbeat_tasks)?f.heartbeat_tasks.slice(0,5).map(M):f.heartbeat_tasks,heartbeat_task_events_count:Array.isArray(f.heartbeat_task_events)?f.heartbeat_task_events.length:0,approvals:Array.isArray(f.approvals)?f.approvals.slice(0,6).map(L):f.approvals,pending_approvals:Array.isArray(f.pending_approvals)?f.pending_approvals.slice(0,6).map(L):f.pending_approvals,local_processes:f.local_processes,local_tool_audit_count:Array.isArray(f.local_tool_audit)?f.local_tool_audit.length:0,main_agent_trust_mode:f.main_agent_trust_mode,reporting_summary:f.reporting&&"object"==typeof f.reporting?{keys:Object.keys(f.reporting)}:null,_note:"Artifact bodies + heartbeat events + reporting stripped. Use find_artifacts/show_artifact for content; query specific endpoints (/api/heartbeat, /api/audit) for full lists."}}case"list_projects":return{ok:!0,projects:(0,v.hF)({status:"all"})};case"create_artifact":{let a=new Set(["markdown","text"]).has(b.kind)?b.kind:"markdown";return(0,g.Dg)({...b,kind:a,project_id:b.project_id??c.project_id??null,agent_id:b.agent_id??c.agent_id??null,heartbeat_task_id:b.heartbeat_task_id??c.heartbeat_task_id??null,dedupe_key:b.dedupe_key,space_id:b.space_id??c.space_id??null})}case"update_artifact":return(0,g.eP)(b.artifact_id,{title:b.title,content:b.content});case"delete_artifact":return(0,g.CM)(b.artifact_id);case"move_artifact":return(0,g.S9)(b.artifact_id,{target_project_id:b.target_project_id});case"list_spaces":return{ok:!0,...b.include_artifact_ids?(0,w.OT)():(0,w.iF)()};case"create_space":return{ok:!0,space:(0,w.bz)({name:b.name})};case"rename_space":return{ok:!0,space:(0,w.Jh)(b.space_id,b.name)};case"set_active_space":return{ok:!0,space:(0,w.BQ)(b.space_id)};case"delete_space":return{ok:!0,...(0,w.cN)(b.space_id)};case"move_artifact_to_space":return{ok:!0,...(0,w.h5)(b.artifact_id,b.space_id)};case"import_brand_guidelines":return B(b);case"generate_ui":return y({...b,project_id:b.project_id??c.project_id??null});case"send_to_hermes":return z({...b,project_id:b.project_id??c.project_id??null});case"start_hermes_job":return A({...b,project_id:b.project_id??c.project_id??null});case"whatsapp_send":return(0,u.op)(b.chat_id,b.text);case"run_agent":return S(b);case"mines_run_report":return(0,t.Ij)({projectId:b.project_id,report_kind:b.report_kind,engine:b.engine||null,user_id:c.user_id||c.acting_on_behalf_of_user_id||"local-user",org_id:c.org_id||"personal-org"});case"set_agent_whatsapp_notify":var h=b;let i=R(h);if(!i.ok)return{ok:!1,error:i.error};let j=null==h.chat_id?null:String(h.chat_id).trim()||null;return{...(0,g.bC)(i.agent.id,j),agent_name:i.agent.name};case"find_artifacts":var k=b;let l=(0,g.n1)({title_query:k.title_query,agent_id:k.agent_id,agent_name:k.agent_name,kind:k.kind,project_id:k.project_id,space_id:k.space_id,limit:k.limit});return{ok:!0,count:l.length,artifacts:l.map(a=>({id:a.id,title:a.title||"(untitled)",kind:a.kind,agent_name:a.agent_name||null,agent_id:a.agent_id||null,created_at:a.created_at,project_id:a.project_id||null,space_id:a.space_id||null,path:a.path}))};case"read_artifact":return function(a){let b=P({artifact_id:a.artifact_id,title_query:a.title_query});if(!b.ok)return b;let c=b.artifact;if(c.is_protected)return{ok:!1,error:"Artifact is passphrase-protected; cannot be read from voice without unlock."};if(c.encrypted)return{ok:!1,error:"Artifact body is encrypted at rest; voice read path does not decrypt."};let d=Math.min(Math.max(Number(a.max_chars)||12e3,1e3),14e3),e=String(c.content||""),f=c.source_md?String(c.source_md):null,g=f||e,h=g.length>d;return{ok:!0,artifact:{id:c.id,title:c.title||"(untitled)",kind:c.kind,agent_id:c.agent_id||null,created_at:c.created_at,path:c.path||null,project_id:c.project_id||null,space_id:c.space_id||null,content_format:f?"markdown":"rendered",total_chars:g.length,returned_chars:Math.min(g.length,d),truncated:h,content:h?g.slice(0,d):g}}}(b);case"send_artifact_to_whatsapp":return Q(b,c);case"list_available_tools":return function({category:a,enabled_only:b}={}){let c=(0,q.n4)();if(a){let b=String(a).toLowerCase();c=c.filter(a=>(a.category||"").toLowerCase()===b)}return b&&(c=c.filter(a=>a.enabled)),{ok:!0,count:c.length,tools:c.map(a=>({name:a.name,title:a.title,description:a.description,category:a.category,enabled:a.enabled,available:a.available,risk_level:a.risk_level,allowlist_required:a.allowlist_required,missing_env:a.missing_env}))}}(b);case"install_tool":return function({tool_name:a}={}){if(!a||"string"!=typeof a)return{ok:!1,error:"tool_name is required"};try{let b=(0,q.G7)(a,!0);if(!b)return{ok:!1,error:`Unknown tool: ${a}`};let c={ok:!0,status:"enabled",tool_name:b.name,title:b.title,category:b.category,risk_level:b.risk_level};return b.missing_env&&b.missing_env.length>0&&(c.missing_credentials=b.missing_env,c.note=`Tool enabled but not yet usable — configure: ${b.missing_env.join(", ")}`),"irreversible_external"===b.risk_level&&(c.warning="This tool is rated irreversible_external. Each call will require owner approval regardless of trust mode."),c}catch(a){return{ok:!1,error:a.message}}}(b);case"uninstall_tool":return function({tool_name:a}={}){if(!a||"string"!=typeof a)return{ok:!1,error:"tool_name is required"};try{let b=(0,q.G7)(a,!1);if(!b)return{ok:!1,error:`Unknown tool: ${a}`};return{ok:!0,status:"disabled",tool_name:b.name,title:b.title}}catch(a){return{ok:!1,error:a.message}}}(b);case"request_capability":return function(a={},b={}){let c=String(a.capability_description||"").trim();if(!c)return{ok:!1,error:"capability_description is required"};let d=function(a){let b=new Set(F(a));if(!b.size)return null;let c=[];try{for(let a of(0,q.n4)())c.push({name:a.name,kind:"tool",text:`${a.name} ${a.title||""} ${a.description||""}`})}catch{}try{for(let a of(0,r.QH)({kind:"skill"}))c.push({name:a.slug,kind:"skill",text:`${a.slug} ${a.title||""} ${a.description||""}`})}catch{}for(let a of c){let c=F(a.name);if(c.length&&c.every(a=>b.has(a)))return{name:a.name,kind:a.kind};let d=new Set(F(a.text)),e=0;for(let a of b)d.has(a)&&e++;if(e>=2&&c.some(a=>b.has(a)))return{name:a.name,kind:a.kind}}return null}(c);if(d)return{ok:!0,status:"exists",match:d,message:`A capability already covers this: ${d.name} (${d.kind}). Grant it instead of rebuilding.`};try{let a=Date.now()-36e5,b=(0,s.Vk)({assignee_agent_id:V,limit:50}).filter(b=>{if(["done","cancelled"].includes(b.status))return!1;let c=Date.parse(b.created_at||"");return Number.isFinite(c)&&c>=a});if(b.length>=5)return{ok:!1,status:"rate_limited",message:`Too many capability build requests in flight (${b.length}). Wait for some to finish.`}}catch{}try{let d=a.target_agent_id?String(a.target_agent_id):null,e=(0,s.createTask)({title:`Build capability: ${c.slice(0,80)}`,description:["A capability is needed that does not exist yet:",`  "${c}"`,"\nChoose the right authoring path and build it:\n  - composite tool (chain existing tools), or\n  - REST connector (new API + secret-by-reference), or\n  - skill (instruction recipe), or\n  - propose_tool (non-REST; staged code, human merge).\n",d?`Grant the result to agent: ${d}.`:"Return the slug so it can be granted to the requester."].join("\n"),acceptance_criteria:a.acceptance_criteria||"Capability authored and its slug returned so it can be granted to the requesting agent.",assignee_agent_id:V,created_by_agent_id:b.agent_id||"main-orchestrator",priority:"p1",project_id:b.project_id||null});return{ok:!0,status:"requested",task_id:e.id,assignee:V,target_agent_id:d,message:`Delegated to Tool Smith (task ${e.id}). It will author the capability and return a slug to grant.`}}catch(a){return{ok:!1,status:"error",error:"tool_smith_unavailable",message:String(a?.message||a)}}}(b,c);default:return(0,q.executeRegistryTool)(a,b)}}function P({artifact_id:a,title_query:b}){if(a){let b=(0,g.jZ)(a);return b?{ok:!0,artifact:b}:{ok:!1,error:`No artifact with id "${a}".`}}if(b){let a=(0,g.n1)({title_query:b,limit:5});return 0===a.length?{ok:!1,error:`No artifact title matches "${b}".`}:a.length>1?{ok:!1,error:`Ambiguous match for "${b}". Candidates: ${a.map(a=>`${a.title} (${a.id})`).join("; ")}. Pass artifact_id to disambiguate.`}:{ok:!0,artifact:(0,g.jZ)(a[0].id)}}return{ok:!1,error:"Pass either artifact_id or title_query."}}async function Q(a,b){let c=P(a);if(!c.ok)return c;let d=c.artifact;if("html"!==d.kind&&"document"!==d.kind)return{ok:!1,error:`Artifact kind "${d.kind}" is not HTML-renderable; only html and document artifacts can be sent.`};if(!d.content||!String(d.content).trim())return{ok:!1,error:`Artifact ${d.id} has no rendered content to send.`};let e=a.chat_id&&String(a.chat_id).trim()||b.chat_id||null;if(!e)return{ok:!1,error:"No chat_id available — pass chat_id, or call this from the WhatsApp channel where the sender is known."};let f=await (0,u.getBridgeHealth)();if(!f||!1===f.ok||"paired"!==f.pairing_state)return{ok:!1,error:`WhatsApp bridge not paired (state=${f?.pairing_state||"unknown"}). Pair via /whatsapp before retrying.`};let g=String(d.title||"artifact").toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"").slice(0,60)||"artifact";try{let a=await (0,u.sendWhatsAppDocument)({chat_id:e,content:d.content,filename:`${g}.html`,mimetype:"text/html",caption:d.title||void 0});return{ok:!0,artifact_id:d.id,title:d.title,chat_id:e,message_id:a?.message_id||null}}catch(a){return{ok:!1,error:`Bridge send failed: ${a.message}`,artifact_id:d.id}}}function R({agent_id:a,agent_name:b}){if(a){let b=(0,g.vc)().find(b=>b.id===a);return b?{ok:!0,agent:b}:{ok:!1,error:`No agent with id "${a}". Use get_state to list agents.`}}if(b){let a=String(b).toLowerCase().trim(),c=(0,g.vc)(),d=c.find(b=>(b.name||"").toLowerCase()===a);if(d)return{ok:!0,agent:d};let e=c.filter(b=>(b.name||"").toLowerCase().includes(a)||(b.id||"").toLowerCase().includes(a));return 1===e.length?{ok:!0,agent:e[0]}:0===e.length?{ok:!1,error:`No agent matches "${b}". Existing: ${c.map(a=>a.name).join(", ")||"(none)"}`}:{ok:!1,error:`Ambiguous match for "${b}". Candidates: ${e.map(a=>`${a.name} (${a.id})`).join(", ")}. Pass agent_id to disambiguate.`}}return{ok:!1,error:"Pass either agent_id or agent_name."}}async function S(a){let b=R(a);if(!b.ok)return{ok:!1,error:b.error};let c=b.agent,d=a.wake_reason||"on-demand from main agent",e="string"==typeof a.instruction&&a.instruction.trim()?a.instruction.trim():null,f="string"==typeof a.expected_output&&a.expected_output.trim()?a.expected_output.trim():null;try{(e||f)&&(0,g.appendAudit)({type:"agent.run.override",summary:`Ad-hoc run of ${c.name} with per-call contract`,status:"complete",meta:{agent_id:c.id,wake_reason:d,has_instruction:!!e,has_expected_output:!!f}});let a=await (0,h.G)(c.id,{triggered_by:"main_agent",wake_reason:d,instruction:e,expected_output:f});if(!a)return{ok:!1,error:`runAgentTick returned null for ${c.id}`};return{ok:!0,agent_id:c.id,agent_name:c.name,run_id:a.id,status:a.status||"complete",title:a.artifact_title||a.title,preview:(a.preview||"").slice(0,600),artifact_id:a.artifact_id||null,artifact:a.artifact||null}}catch(a){return{ok:!1,error:a.message,agent_id:c.id}}}d()}catch(a){d(a)}})},2167:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{Nw:()=>n,oG:()=>l,qC:()=>k,v8:()=>m});var e=c(31421),f=c(73024),g=c(76760),h=c(9381),i=c(24516),j=a([i]);function k(){let a=(0,i.getSecret)("HERMES_AGENT_DIR");return g.resolve(process.env.HERMES_AGENT_DIR||a||g.join(h.Dl,"..","hermes-agent"))}function l(){try{let a=k(),b=g.join(h.Dl,"scripts","hermes-command.py");return f.existsSync(a)&&f.existsSync(b)}catch{return!1}}function m(){let a=k(),b=g.join(h.Dl,"scripts","hermes-command.py"),c=f.existsSync(a),d=f.existsSync(b);return{available:c&&d,hermes_dir:a,dir_exists:c,script_exists:d,env_override:!!(process.env.HERMES_AGENT_DIR||(0,i.getSecret)("HERMES_AGENT_DIR"))}}function n({prompt:a,session_id:b,model:c,timeout_ms:d,cwd:i}={}){if(!a||"string"!=typeof a)throw Error("prompt is required");if(process.env.HERMES_MOCK_RESPONSE)return Promise.resolve({ok:!0,response:process.env.HERMES_MOCK_RESPONSE,session_id:b||"madarx-hermes-mock",model:c||null,mocked:!0});let{hermesDir:j,python:l,env:m}=function(a={}){let b=k(),c=function(a=k()){for(let b of[process.env.HERMES_PYTHON,process.env.PYTHON,g.join(a,".venv","bin","python"),"/opt/homebrew/bin/python3.12","/opt/homebrew/bin/python3.11","/opt/homebrew/bin/python3.10",g.join(process.env.HOME||"",".local","bin","python3.12"),g.join(process.env.HOME||"",".local","bin","python3.11"),g.join(process.env.HOME||"",".local","bin","python3.10"),"python3.12","python3.11","python3.10","python3"].filter(Boolean))if(!b.includes("/")||f.existsSync(b))return b;return"python3"}(b);return{hermesDir:b,python:c,env:{...function(){let a=g.join(h.Dl,".env.local");if(!f.existsSync(a))return{};let b={};for(let c of f.readFileSync(a,"utf8").split(/\r?\n/)){let a=c.trim();if(!a||a.startsWith("#")||!a.includes("="))continue;let d=a.indexOf("="),e=a.slice(0,d).trim(),f=a.slice(d+1).trim();(f.startsWith('"')&&f.endsWith('"')||f.startsWith("'")&&f.endsWith("'"))&&(f=f.slice(1,-1)),b[e]=f}return b}(),...process.env,...a,HERMES_AGENT_DIR:b,HERMES_PYTHON_USED:c}}}(),o=Number(d||process.env.HERMES_TIMEOUT_MS||6e5),p=function({prompt:a,session_id:b,model:c,cwd:d}={}){let e=k(),f=[g.join(h.Dl,"scripts","hermes-command.py"),"--hermes-dir",e,"--prompt",a];return b&&f.push("--session-id",b),c&&f.push("--model",c),d&&f.push("--cwd",d),f}({prompt:a,session_id:b,model:c,cwd:i});return new Promise((a,b)=>{let c=(0,e.spawn)(l,p,{cwd:j,env:m,stdio:["ignore","pipe","pipe"]}),d="",f="",g=!1,h=setTimeout(()=>{g=!0,c.kill("SIGTERM"),b(Error(`Hermes timed out after ${Math.round(o/1e3)}s`))},o);c.stdout.on("data",a=>{d+=a.toString()}),c.stderr.on("data",a=>{f+=a.toString()}),c.on("error",a=>{g||(g=!0,clearTimeout(h),b(a))}),c.on("close",c=>{if(!g){if(g=!0,clearTimeout(h),0!==c)return void b(Error((f||d||`Hermes exited with code ${c}`).trim()));try{let b=function(a){let b=String(a||"").trim();if(!b)throw Error("Hermes returned no output");let c=b.split("\n").filter(Boolean).at(-1);try{return JSON.parse(c)}catch{throw Error(`Hermes returned non-JSON output: ${b.slice(-500)}`)}}(d);if(!b.ok)throw Error(b.error||"Hermes command failed");if(!String(b.response||"").trim())throw Error("Hermes completed without a final response");a(b)}catch(a){b(a)}}})})}i=(j.then?(await j)():j)[0],d()}catch(a){d(a)}})},64143:(a,b,c)=>{c.d(b,{Wl:()=>g,Xj:()=>j,getBridgeHealth:()=>f,op:()=>h,sendWhatsAppDocument:()=>i});let d=process.env.WHATSAPP_BRIDGE_URL||"http://127.0.0.1:3210";async function e(a,b,c,{timeoutMs:f=1e4}={}){let g=new AbortController,h=setTimeout(()=>g.abort(),f);try{let e=await fetch(`${(process.env.WHATSAPP_BRIDGE_URL||d).replace(/\/$/,"")}${b}`,{method:a,headers:c?{"Content-Type":"application/json"}:void 0,body:c?JSON.stringify(c):void 0,signal:g.signal}),f=await e.text(),h=null;try{h=f?JSON.parse(f):null}catch{}if(!e.ok){let a=Error(h?.error||`whatsapp-bridge ${e.status}`);throw a.status=e.status,a.body=h||f,a}return h}finally{clearTimeout(h)}}async function f(){try{return await e("GET","/health",null,{timeoutMs:3e3})}catch(a){return{ok:!1,error:a.message,status:a.status||null}}}async function g(){try{return await e("GET","/qr",null,{timeoutMs:3e3})}catch(a){return{ok:!1,error:a.message,status:a.status||null}}}async function h(a,b){if(!a)throw Error("chat_id is required");if(!b||!String(b).trim())throw Error("text is required");return e("POST","/send",{chat_id:a,text:String(b)})}async function i({chat_id:a,content:b,filename:c,mimetype:d,caption:f}){if(!a)throw Error("chat_id is required");if(!c)throw Error("filename is required");if(null==b)throw Error("content is required");let g=Buffer.isBuffer(b)?b:Buffer.from(String(b),"utf8");if(!g.length)throw Error("content is empty");return e("POST","/send-document",{chat_id:a,content_base64:g.toString("base64"),filename:c,mimetype:d||"application/octet-stream",caption:f||void 0},{timeoutMs:3e4})}async function j(){return e("POST","/logout",{},{timeoutMs:15e3})}},78224:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{Z2:()=>u,Zn:()=>t,_3:()=>y,o0:()=>x,qw:()=>s,rK:()=>z,vy:()=>r});var e=c(73024),f=c(76760),g=c(31421),h=c(34255),i=c(9381),j=c(73066),k=c(61423),l=c(60105),m=c(8727),n=a([h,j,k,l,m]);[h,j,k,l,m]=n.then?(await n)():n;let A=new Set(["complete","failed","cancelled","stale"]);function o(a){return a?{...a}:null}function p(a){return a?{...a,payload:function(a,b){if(!a)return null;try{return JSON.parse(a)}catch{return null}}(a.payload,null)}:null}function q(a,b){let c=f.resolve(i.Dl,a),d=e.realpathSync(i.un),g=e.existsSync(f.dirname(c))?e.realpathSync(f.dirname(c)):f.resolve(f.dirname(c)),h=f.join(g,f.basename(c));if(!(h===d||h.startsWith(`${d}${f.sep}`)))throw Error(`Refusing to write artifact outside workspace: ${a}`);e.mkdirSync(f.dirname(c),{recursive:!0}),e.writeFileSync(c,b,"utf8")}function r(a=20){return(0,h.getDb)().prepare("SELECT * FROM hermes_jobs ORDER BY updated_at DESC LIMIT ?").all(a).map(o)}function s(a){let b=(0,h.getDb)();return o(b.prepare("SELECT * FROM hermes_jobs WHERE id = ?").get(a))}function t(a,b=200){return(0,h.getDb)().prepare("SELECT * FROM hermes_job_events WHERE job_id = ? ORDER BY at ASC LIMIT ?").all(a,b).map(p)}function u(a){let b=s(a);return b?{...b,events:t(a,500)}:null}function v(a,b=[]){let c=a.status||"queued",d=[],e=[...b].reverse().find(a=>"final"===a.type),f=[...b].reverse().find(a=>"error"===a.type);e?.message?d.push(e.message,""):(a.error||f?.message)&&d.push("## Error","",a.error||f.message,"");let g=b.filter(a=>!["final"].includes(a.type));if(g.length){for(let a of(d.push("## Progress",""),g.slice(-80))){let b=a.at?a.at.replace("T"," ").replace(/\.\d+Z$/,"Z"):"",c=(function(a,b=6e3){let c=String(a||"");return c.length>b?`${c.slice(0,b)}

[truncated ${c.length-b} chars]`:c})(a.message||a.type,1200).replace(/\n/g,"\n  ");d.push(`- ${b} ${a.type}: ${c}`.trim())}d.push("")}return"running"===c?d.push("## Current state","","Hermes is still running. This artifact updates as new progress arrives.",""):"queued"===c&&d.push("## Current state","","Hermes is queued and will start shortly.",""),`${d.join("\n")}
`}function w(a,{type:b,message:c,payload:d}={}){let e=(0,h.getDb)(),f=(0,h.newId)("hermes-event"),g=(0,h.nowIso)();return e.prepare(`
    INSERT INTO hermes_job_events (id, job_id, type, message, payload, at)
    VALUES (?, ?, ?, ?, ?, ?)
  `).run(f,a,b||"status",c||null,d?JSON.stringify(d):null,g),e.prepare("UPDATE hermes_jobs SET updated_at = ? WHERE id = ?").run(g,a),!function(a){let b=s(a);if(!b?.artifact_id)return;let c=t(a,500),d=(0,m.vr)(v(b,c)),e=(0,m.j7)({title:b.title||"Hermes Job",markdown:d,meta:`Status: ${b.status||"queued"}`}),f=(0,h.getDb)(),g=f.prepare("SELECT * FROM artifacts WHERE id = ?").get(b.artifact_id);g&&(f.prepare("UPDATE artifacts SET content = ?, source_md = ?, kind = ? WHERE id = ?").run(e,d,"document",b.artifact_id),q(g.path,d),b.artifact_id)}(a),{id:f,job_id:a,type:b||"status",message:c,payload:d,at:g}}function x({prompt:a,title:b,cwd:c,session_id:d,model:g,timeout_ms:n,project_id:o}={}){if(!a||"string"!=typeof a)throw Error("prompt is required");(0,i.Jh)();let p=function(a){if(!a)return null;let b=f.resolve(String(a));if(!e.existsSync(b)||!e.statSync(b).isDirectory())throw Error(`Working directory not found: ${b}`);let c=e.realpathSync(b);if(!(function(){let a=String(process.env.HERMES_ALLOWED_ROOTS||"").split(f.delimiter).map(a=>a.trim()).filter(Boolean);return[i.Dl,i.un,f.dirname(i.Dl),...a].map(a=>{let b=f.resolve(a);return e.existsSync(b)?e.realpathSync(b):b})})().some(a=>c===a||c.startsWith(`${a}${f.sep}`)))throw Error(`Working directory is outside allowed roots: ${b}`);return b}(c),r=(0,h.newId)("hermes-job"),t=(0,h.nowIso)(),u=b||`Hermes job: ${a.slice(0,60)}`,y=o||k.Sk,z=(0,j.Kg)(y),A=f.join(z,`${String(u||"hermes-job").toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"").slice(0,80)||"hermes-job"}-${Date.now().toString(36)}.md`),B=(0,i.z9)(A),C=(0,l.recordRun)({kind:"hermes-job",title:u,agent:"Hermes Agent",agent_id:"hermes",status:"running",artifact:B,preview:`Hermes job queued: ${a.slice(0,160)}`,triggered_by:"claude"}),D=(0,m.vr)(v({id:r,title:u,prompt:a,cwd:p,status:"queued",created_at:t,updated_at:t},[])),E=(0,m.j7)({title:u,markdown:D,meta:"Status: queued"});q(B,D);let F=(0,l.recordArtifact)({run_id:C.id,agent_id:"hermes",file_path:B,kind:"document",title:u,content:E,source_md:D,project_id:y});return(0,h.getDb)().prepare(`
    INSERT INTO hermes_jobs (
      id, artifact_id, run_id, status, title, prompt, cwd, hermes_session_id, model,
      timeout_ms, created_at, updated_at
    )
    VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
  `).run(r,F,C.id,"queued",u,a,p,d||null,g||null,n?Number(n):null,t,t),w(r,{type:"queued",message:"Hermes job queued."}),(0,l.appendAudit)({type:"hermes.job.create",summary:`Queued Hermes job: ${u}`,status:"queued",meta:{job_id:r,run_id:C.id,artifact_id:F}}),{...s(r),file_path:B}}function y(a){let b=f.join(i.QG,"scripts","hermes-job-runner.mjs"),c=(0,g.spawn)(process.execPath,[b,"--job-id",a],{cwd:(0,i.wn)(i.QG,i.un),env:process.env,stdio:"ignore",detached:!0});return c.unref(),w(a,{type:"status",message:`Background runner spawned with pid ${c.pid}.`}),{pid:c.pid}}function z({olderThanMs:a=18e5}={}){let b=(0,h.getDb)(),c=new Date(Date.now()-a).toISOString(),d=b.prepare(`
    SELECT id FROM hermes_jobs
    WHERE status IN ('queued', 'running') AND updated_at < ?
  `).all(c);for(let a of d)!function(a,{error:b,exit_code:c=null,status:d="failed"}={}){let e=A.has(d)?d:"failed",f=(0,h.getDb)(),g=(0,h.nowIso)();f.prepare(`
    UPDATE hermes_jobs
    SET status = ?, error = ?, exit_code = ?, completed_at = ?, updated_at = ?
    WHERE id = ?
  `).run(e,b||"Hermes job failed",c,g,g,a),w(a,{type:"error",message:b||"Hermes job failed."});let i=s(a);i?.run_id&&(0,l.PF)(i.run_id,{status:"cancelled"===e?"cancelled":"failed",preview:b||"Hermes job failed.",output:b||""}),(0,l.appendAudit)({type:"hermes.job.fail",summary:`Hermes job failed: ${i?.title||a}`,status:e,meta:{job_id:a,error:b}}),s(a)}(a.id,{status:"stale",error:"Hermes job became stale before completion."});return d.length}d()}catch(a){d(a)}})},89847:(a,b,c)=>{c.d(b,{ZQ:()=>k,un:()=>n});var d=c(73024),e=c(76760),f=c(9381);let g="<madarx_artifact>",h="</madarx_artifact>",i=[/\bopen\s+(the\s+)?(link|url|file|path)\b/i,/\bview\s+(it|the result|the output)\s+(at|in)\b/i,/\bcan\s+find\s+it\s+at\b/i,/\bavailable\s+at\b/i,/\bserved\s+at\s+https?:\/\//i,/\bhttp:\/\/(?:127\.0\.0\.1|localhost):\d+\b/i],j=`madarX artifact format contract:
- Your final answer MUST contain the dashboard artifact body between ${g} and ${h}.
- Inside ${g}, include the actual result content that should be displayed in the madarX artifact.
- Do NOT only tell the user to open a URL, file, localhost server, browser window, or workspace path.
- If you run a project, include the rendered result summary, command output, important logs, generated file paths, server URL if any, errors, and next steps inside the artifact body.
- If you generated a file, also paste its relevant contents or a faithful summary inside the artifact body.
- Text outside ${g} is ignored by madarX.`;function k(a){return`${a}

${j}`}function l(a){if(!a)return null;let b=String(a).replace(/[.,;:)]+$/g,""),c=b.startsWith("/")?e.resolve(b):e.resolve(f.Dl,b);return[f.Dl,f.un,e.dirname(f.Dl)].map(a=>e.resolve(a)).some(a=>c===a||c.startsWith(`${a}${e.sep}`))?c:null}function m(a){let b=e.relative(f.Dl,a),c=e.extname(a).toLowerCase(),g=d.readFileSync(a,"utf8"),h=g.length>12e4?`${g.slice(0,12e4)}

[truncated ${g.length-12e4} chars]`:g;return".md"===c||".markdown"===c?`## Inlined file: ${b}

${h}`:`## Inlined file: ${b}

\`\`\`${".html"===c?"html":".json"===c?"json":""}
${h}
\`\`\``}function n(a,{title:b="Hermes output"}={}){let c=function(a){let b=String(a||""),c=b.indexOf(g),d=b.indexOf(h);return -1===c||-1===d||d<=c?"":b.slice(c+g.length,d).trim()}(a);if(c)return{ok:!0,content:c,source:"tagged",violations:[]};let e=function(a){let b=String(a||""),c=new Set;for(let a of[/(?:workspace|\.?\/workspace)\/[^\s'"`<>]+?\.(?:md|markdown|txt|html|json|log)/gi,/\/[^\s'"`<>]+?\.(?:md|markdown|txt|html|json|log)/gi])for(let d of b.matchAll(a))c.add(d[0]);return[...c].map(l).filter(Boolean).filter(a=>d.existsSync(a)&&d.statSync(a).isFile())}(a);return e.length?{ok:!0,content:[`# ${b}`,"","Hermes returned file/path references instead of a formatted artifact body. madarX inlined the referenced local file content below.","",...e.map(m),"","## Raw Hermes response","",String(a||"").trim()].join("\n"),source:"referenced-files",violations:["missing_madarx_artifact_tags"]}:!function(a){let b=String(a||"").trim();if(!b)return!1;let c=i.some(a=>a.test(b)),d=b.split(/\s+/).filter(Boolean).length;return c&&d<220}(a)?{ok:!0,content:String(a||"").trim(),source:"raw",violations:["missing_madarx_artifact_tags"]}:{ok:!1,content:[`# ${b}`,"\nHermes returned a redirect-style answer instead of artifact content.\n\n## Format violation\n",`Hermes must return the actual artifact body between \`${g}\` and \`${h}\`, not only a link, path, or instruction to open another window.`,"\n## Raw Hermes response\n",String(a||"").trim()].join("\n"),source:"violation",violations:["missing_madarx_artifact_tags","redirect_only_response"]}}}};