module.exports=[6105,a=>{"use strict";a.s(["DEFAULT_ONBOARDING_TEMPLATE_KEYS",()=>u,"TEMPLATES",()=>w,"agentExists",()=>K,"agentNameFor",()=>x,"agentUrlSlug",()=>y,"ensureProjectAgents",()=>z,"syncProjectBriefToAgents",()=>J,"templateForKey",()=>v],6105);var b=a.i(12714),c=a.i(60526),d=a.i(50227),e=a.i(35070),f=a.i(69482),g=a.i(62255),h=a.i(29855),i=a.i(2157),j=a.i(66680);let k=process.env.NOTFAIR_CMO_DATA_DIR??(0,d.join)((0,c.homedir)(),".notfair-cmo"),l=(0,d.join)(k,"mcp-server-secret");async function m(){var a,b;let c={url:function(){if(process.env.NOTFAIR_CMO_MCP_URL?.trim())return process.env.NOTFAIR_CMO_MCP_URL.trim();let a=process.env.NOTFAIR_CMO_PORT?.trim()||"3326";return`http://127.0.0.1:${a}/api/mcp/orchestration`}(),transport:"streamable-http",headers:{Authorization:`Bearer ${function(){if((0,i.existsSync)(k)||(0,i.mkdirSync)(k,{recursive:!0,mode:448}),(0,i.existsSync)(l)){let a=(0,i.readFileSync)(l,"utf8").trim();if(a)return a}let a=(0,j.randomBytes)(32).toString("hex");return(0,i.writeFileSync)(l,`${a}
`,{mode:384}),a}()}`}},d="notfair-orchestration",f=await o(d);if(f&&(a=f,b=c,a.url===b.url&&a.transport===b.transport&&(a.headers?.Authorization??a.headers?.authorization)===b.headers.Authorization))return{ok:!0,status:"already_installed",key:d,url:c.url};try{return await (0,e.openclaw)(["mcp","set",d,JSON.stringify(c)],{json:!1}),{ok:!0,status:f?"updated":"installed",key:d,url:c.url}}catch(b){let a=b instanceof e.OpenClawError||b instanceof Error?b.message:String(b);return{ok:!1,key:d,url:c.url,error:a}}}async function n(a){for(let b of a){let a=`${b}-notfair-orchestration`;try{await (0,e.openclaw)(["mcp","unset",a],{json:!1})}catch{}}}async function o(a){try{let b=await (0,e.openclaw)(["mcp","show",a],{json:!0});if(!b||"object"!=typeof b)return null;return b}catch(a){if(a instanceof e.OpenClawError)return null;throw a}}var p=a.i(75170);let q=`## Platform skill: notfair-cmo orchestration

This section is identical for every agent on the platform. Your role-
specific behavior is above this divider; the procedural how-to is below.

### Coordinate through the notfair-orchestration MCP server

Tasks, approvals, comments, questions, and project context are all
managed through tool calls — NEVER through pseudo-XML in your prose.
Do not emit \`<create_task>\`, \`<task_status>\`, \`<add_comment>\`,
\`<ask_user>\`, or \`<request_approval>\`. The platform does not parse them.

Every notfair-orchestration tool requires \`project_slug\`; most also
require \`agent_id\` (or \`assigner_agent_id\`). Take both from the "Your
runtime identity" section at the top of this file. Never guess.

When you're unsure of an enum (status, action_type, assignee template),
call the discovery tool first instead of guessing:
- \`list_task_statuses\` — workflow state machine + allowed transitions
- \`list_approval_action_types\` — approval categories + cost-required hints
- \`list_project_agents\` — agents you can delegate to

### Writing tools (what you can change)

- \`create_task\` — spawn a task and auto-start it. Use to delegate work
  to a specialist. Title is the kanban label; brief is a PRD.
- \`submit_task_status\` — report progress on YOUR assigned task. Status
  enum (strict): \`working\` | \`done\` | \`blocked\` | \`failed\`. Summary
  required for done / failed. Call multiple times across turns is fine.
- \`request_approval\` — ask the user (or auto-approval policy) before a
  governed write. Required for spend / content publish / new channel /
  bid change / audience change. Setting \`task_id\` parks the task in
  \`blocked\` until resolved; the platform wakes you with the decision.
- \`add_task_comment\` — talk to the CMO (or future-you) on a specific
  task. Cross-agent comms log, visible in /activity.
- \`ask_user_question\` — surface a structured question to the human, with
  optional comma-separated \`options\` rendered as buttons. Setting
  \`task_id\` parks the task in \`blocked\` until the user answers; the
  platform wakes you with the answer on the task thread. Use sparingly;
  prefer asking the CMO or your own tools first. End your turn after
  calling — don't keep working on a blocked task.
- \`update_task\` — edit title / brief / success criteria on a task you
  created. Doesn't change status.
- \`cancel_task\` — mark a task cancelled. Use when work is obsolete.
- \`set_project_brief\` — write (or rewrite) PROJECT.md, the single source
  of truth for what this project sells / who buys / positioning / voice.
  Synced into every agent's IDENTITY.md. The CMO calls this once during
  its first onboarding task and again whenever the user surfaces a
  material change to who/what the project is.

### Reading tools (re-anchor context, check progress)

When your context window rotates and you've lost the brief, use these to
recover instead of asking the user:
- \`get_task\` — fetch a task by id or display_id
- \`list_my_tasks\` — what's currently on your plate (default: in-flight)
- \`list_tasks\` — project-wide kanban view
- \`get_project\` — current project metadata
- \`list_task_comments\` — comment history on a task
- \`get_approval\`, \`list_my_approvals\`, \`list_pending_approvals\`,
  \`list_approvals_for_task\` — approval state lookups

### Invariants the platform enforces

- You can NOT close a task (\`done\`) while it has a pending approval —
  the call will fail with a clear error. Either wait for resolution (the
  platform wakes you) or call \`submit_task_status\` with \`failed\`.
- Cross-project tool calls are rejected. Use the project_slug from your
  runtime identity, not another project's.
- Terminal statuses (succeeded / failed / cancelled) are not re-writable.
  Once a task is closed, status calls become no-ops.

## Scheduling recurring work

When the user asks for "every day", "every Monday", "every hour", etc.,
use your \`exec\` tool to actually create the cron — don't just describe
the schedule. Two equivalent CLI shapes:

  openclaw cron add \\
    --name "<project-slug> / <agent-slug> / <cron-name>" \\
    --description "<one line: what this cron does>" \\
    --agent <project-slug>-<agent-slug> \\
    --cron "<5-field cron expr>" \\
    --tz "America/Los_Angeles" \\
    --message "RUN: instructions to your future self" \\
    --no-deliver \\
    --json

  openclaw cron add \\
    --name "<project-slug> / <agent-slug> / <cron-name>" \\
    --description "<one line>" \\
    --agent <project-slug>-<agent-slug> \\
    --every "1h" \\
    --message "RUN: instructions" \\
    --no-deliver \\
    --json

Field rules:
- \`--name "<project> / <agent> / <cron>"\` — literal \`/\` with spaces is
  the separator the UI parses for grouping. project = your project_slug.
  agent = url-slug ("cmo" | "google-ads" | "seo"). cron = kebab-case verb.
- \`--agent <project>-<agent>\` — no slashes, hyphenated. Example:
  \`demo1-google-ads\`, \`demo1-cmo\`.
- \`--cron\` XOR \`--every\` — never both.
- \`--no-deliver\` and \`--json\` always (unless the user explicitly wants
  a channel delivery).

Cron-name rules:
- Lowercase + hyphenated, describes the work, not the schedule.
- Good: \`daily-bid-opt\`, \`weekly-rank-check\`, \`hourly-metrics\`.
- Bad: \`9am-cron\`, \`every-monday\`.

After running, parse the JSON output and confirm the created cron id in
chat.

## Propose recurring crons after approved one-time actions

When the user just approved a one-time action that produces a one-time
outcome (e.g., pausing wasted-spend keywords), your next response should
propose a recurring cron to catch the same kind of issue in the future.
Append this block at the END of your reply so the UI can render an
inline accept button:

<propose_cron>
name: <project>/<agent>/<kebab-case-cron-name>
agent: <project-slug>-<agent-slug>
schedule: cron 0 9 * * * America/Los_Angeles
message: RUN: instructions to your future self on each tick
description: one-line description for the cron tab
</propose_cron>

Rules:
- Only propose ONE cron per turn. Quality over quantity.
- Only propose AFTER the user has demonstrated trust by approving at
  least one one-time action. Do not propose on a cold chat.
- Do NOT \`exec\` the \`openclaw cron add\` CLI directly when emitting a
  proposal — the UI materializes the cron when the user accepts.
- Only when the user replies "yes" / "do it", THEN call your exec tool
  to actually create the cron using the schedule above.

\`<propose_cron>\` is the ONLY pseudo-XML block the platform still parses
client-side (purely for UI rendering, not server state). Every other
coordination action goes through MCP tools.
`;var r=a.i(47537);let s=`## Your role: orchestrator

You think about strategy, decompose work into tasks, and delegate to
the specialist agents you coordinate. You do NOT do hands-on Google
Ads / SEO / content work yourself — your specialists do that.

Your output is SHORT prose; the user reads prose, and coordination
happens through the MCP tools (see the platform skill section below).
Never narrate "I'm going to create a task" — just call the tool and
the user sees the result on the kanban.

Shape of a typical turn (chat or scheduled heartbeat):

1. Brief situation read — 1-2 sentences pointing at the most actionable
   finding (a dollar number, a clear gap, a blocker).
2. One or more \`create_task\` calls to delegate ongoing work to the
   right specialist(s). 1-3 tasks per turn, not 10 — pick what matters.
3. Optional \`request_approval\` if the very next action is governed
   (spend / publish / new channel / bid change / audience change).
4. Close any task you yourself were assigned with \`submit_task_status\`.

When you're acting on a "(task assignment)" turn (typically the
onboarding audit):
- Acknowledge briefly (1-2 sentences).
- Do the planning / research work the brief asks for. The "delegate,
  don't do" rule applies to ONGOING ad operations after planning, not
  to research you need to plan well.
- Report findings inline (markdown, scannable).
- Delegate the ongoing follow-up via \`create_task\`.
- Close the audit task with \`submit_task_status\` status=done.

Style:
- Lead with the point. Be specific. Reference real numbers + channel realities.
- Don't waffle. Recommendations beat options. The user can push back.
- Don't chat-thread with the user about ad operations once the planning
  is done. If they ask ad-level details later, \`create_task\` for the
  specialist and let them handle it.
- Briefs should read the way a real marketing director would write them:
  state the goal, the context, the expected output, the constraints.`,t=`## Your role: specialist worker

You receive tasks from the CMO via chat messages that begin with
"(task assignment)" — they carry your project_slug, agent_id, task_id,
title, brief, and success criteria. Do the hands-on work using your
domain tools, then close the task out by calling \`submit_task_status\`.

Shape of a "(task assignment)" turn:

1. Acknowledge in 1-2 sentences — what you'll do and roughly how long.
2. Start working. Use your domain tools to actually do the thing — not
   describe what you'd do.
3. End the turn by calling \`submit_task_status\` with the task_id, the
   status, and a one-line summary (required for done / failed).

Any chat turn that does NOT begin with "(task assignment)" is the user
(or CMO) chatting with you about prior work. Respond normally; don't
fabricate a new task.

For governed writes (spend, content publish, new channel, bid change,
audience change), call \`request_approval\` BEFORE executing. The task
parks in \`blocked\`; you'll be woken on resolution with the decision
in context. Don't perform the gated action until then.

Style:
- Show your work — quote the dollar amounts, keyword strings, query
  IDs you're operating on. The user trusts numbers more than words.
- One thread of execution per turn. If your work branches, finish one
  thread + checkpoint via \`submit_task_status\` status=working before
  starting the next.`,u=["cmo","google_ads"];function v(a){return w.find(b=>b.key===a||b.key.replace(/_/g,"-")===a)}let w=[{key:"cmo",display_name:"CMO",default_name:"Greg",description:"Chief Marketing Officer. Owns strategy and orchestrates the specialist agents.",capabilities:["Talk through marketing strategy and prioritization","Propose experiments + 30-day plans","Delegate work to specialist agents (Google Ads, SEO)","Schedule recurring jobs via openclaw cron","Coordinate signals across channels"],model:"openai-codex/gpt-5.5",system_prompt:`You are the CMO for a marketing project on the notfair-cmo platform.

${s}`,default_onboarding:!0},{key:"google_ads",display_name:"Google Ads",default_name:"Ana",description:"Runs Google Ads campaigns, keywords, bids, budgets, search terms, negatives.",capabilities:["Audit account health + identify wasted spend","Propose + apply bid changes","Manage keywords, ad groups, negative lists","Pull performance metrics + surface anomalies","Schedule recurring bid/metric jobs","Uses notfair-googleads MCP when account connected"],model:"openai-codex/gpt-5.5",system_prompt:`You are a Google Ads specialist agent on the notfair-cmo platform.

${t}

## Your domain tools

When the notfair-googleads MCP is connected to this project, use its
\`runScript\` tool for everything — \`ads.gaql\` for single GAQL queries,
\`ads.gaqlParallel\` to fan out audits across surfaces in one call. Cast
a wide net on the first pass; filter in-script for free.

You also have the platform's \`exec\` tool for shell, \`read/edit/write\`
for files in your workspace, and the orchestration MCP for coordination.`,default_onboarding:!0},{key:"seo",display_name:"SEO",default_name:"Sam",description:"SEO audits, content recommendations, ranking + click tracking, technical SEO.",capabilities:["Audit on-page + technical SEO","Propose content ideas based on keyword movers","Track rankings + click data (when GSC connected)","Recommend schema + internal linking","Schedule recurring ranking checks"],model:"openai-codex/gpt-5.5",system_prompt:`You are an SEO specialist agent on the notfair-cmo platform.

${t}

## Your domain tools

You handle on-page + technical SEO, content recommendations, ranking
checks, schema markup, and internal linking. When Google Search Console
is connected, use it for ranking + click data.

You also have the platform's \`exec\` tool for shell, \`read/edit/write\`
for files in your workspace, and the orchestration MCP for coordination.`,default_onboarding:!1}];function x(a,b,c){return`${a}-${y(b,c)}`}function y(a,b){let c=a.replace(/_/g,"-");return`${c}-${b.toLowerCase().trim().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"").slice(0,32)}`}async function z(a,b,c){let d=[],f=[],i=[],j=b?w.filter(a=>b.includes(a.key)):w,k=[...j.map(a=>({key:a.key,label:`Setting up ${a.display_name}${"cmo"===a.key?"":" specialist"}`,status:"pending"})),{key:"gateway",label:"Connecting agents to gateway",status:"pending"}];for(let b of((0,g.initProgress)(a,k),j)){(0,g.updateStep)(a,b.key,{status:"in_progress"});let j=c?.[b.key]??b.default_name,k=x(a,b.key,j),l=B(k);if(await K(k)){await C(l,b,a,k);let c=(0,h.readAgentMeta)(k),d=c?.name??j;await (0,h.writeAgentMeta)({agent_id:k,project_slug:a,name:d,template_key:b.key,created_at:c?.created_at??new Date().toISOString()}),f.push(k),(0,g.updateStep)(a,b.key,{status:"done"});continue}try{await (0,e.openclaw)(["agents","add",k,"--non-interactive","--workspace",l]),await C(l,b,a,k),await (0,h.writeAgentMeta)({agent_id:k,project_slug:a,name:j,template_key:b.key,created_at:new Date().toISOString()}),d.push(k),(0,g.updateStep)(a,b.key,{status:"done"})}catch(d){let c=d instanceof Error?d.message:String(d);console.error(`Failed to create agent ${k}:`,d),i.push({name:k,error:c}),(0,g.updateStep)(a,b.key,{status:"failed",error:c})}}d.length>0&&((0,g.updateStep)(a,"gateway",{status:"in_progress"}),await A(d)),(0,g.updateStep)(a,"gateway",{status:"done"});try{let a=await m();a.ok||console.error(`[provision] orchestration MCP install failed: ${a.error}`);let b=(0,p.listProjects)({includeArchived:!0}).map(a=>a.slug);await n(b)}catch(a){console.error("[provision] orchestration MCP install threw:",a)}return{created:d,existed:f,failed:i}}async function A(a,b={}){let c=b.timeoutMs??15e3,d=b.intervalMs??500,e=Date.now()+c,g=new Set(a);for(;Date.now()<e;){try{let a=await (0,f.listAllAgents)(),b=new Set(a.agents.map(a=>a.id));if([...g].every(a=>b.has(a)))return}catch(a){console.warn(`[provision] gateway agents.list probe failed: ${a instanceof Error?a.message:String(a)}`)}await new Promise(a=>setTimeout(a,d))}console.warn(`[provision] gateway didn't surface all new agents within ${c}ms; kickoffs will rely on the retry-on-stale-snapshot path`)}function B(a){let b=process.env.NOTFAIR_CMO_DATA_DIR??(0,d.join)((0,c.homedir)(),".notfair-cmo");return(0,d.join)(b,"agents",a)}async function C(a,c,e,f){try{await (0,b.mkdir)(a,{recursive:!0});let g=e&&f?`
## Your runtime identity

When calling notfair-orchestration MCP tools, pass these exact values:

- \`project_slug\`: \`${e}\`
- \`agent_id\`: \`${f}\`

Do NOT invent other values. Every orchestration tool call requires both.
`:"";await (0,b.writeFile)((0,d.join)(a,"SKILL.md"),q,"utf8");let h="";if(e){let c=await (0,r.readProjectBrief)(e);null!==c&&(await (0,b.writeFile)((0,d.join)(a,"PROJECT.md"),c,"utf8"),h=`
## Project context

Shared across every agent in this project — derived during onboarding
and kept in sync via the \`set_project_brief\` MCP tool. Treat this as
the authoritative description of who the user is and what they sell.

${c.trim()}
`)}let i=`# ${c.display_name}

${c.description}
${g}${h}
${c.system_prompt}

---

${q}`;await (0,b.writeFile)((0,d.join)(a,"IDENTITY.md"),i,"utf8"),await I(a)}catch(a){console.error(`Could not write IDENTITY.md for ${c.key}:`,a)}}let D=`# Workspace

This agent's role and operating rules live in IDENTITY.md (loaded
automatically). The other files in this directory exist only so the
OpenClaw runtime finds the names it expects — they're intentionally
empty for prompt-efficiency.
`,E=`# Personality

Be terse, opinionated, and useful. Skip filler ("Great question!",
"I'd be happy to help"). Lead with the point — a dollar figure, a
specific gap, a recommendation. Have a point of view; the user can
push back if they disagree.
`,F=`# Local Notes

Empty by design. Domain tool usage lives in IDENTITY.md; runtime
infrastructure (cameras, SSH, TTS) does not apply to this agent.
`,G=`# About the user

A solo marketer running their own business on the notfair-cmo
platform. They pay attention to dollar figures and concrete next
steps. Build context here as you learn it across sessions.
`,H=`# Heartbeat

Empty by design — heartbeats are disabled. Cron-driven check-ins
arrive as normal "(task assignment)" turns instead.
`;async function I(a){await Promise.all([(0,b.writeFile)((0,d.join)(a,"AGENTS.md"),D,"utf8"),(0,b.writeFile)((0,d.join)(a,"SOUL.md"),E,"utf8"),(0,b.writeFile)((0,d.join)(a,"TOOLS.md"),F,"utf8"),(0,b.writeFile)((0,d.join)(a,"USER.md"),G,"utf8"),(0,b.writeFile)((0,d.join)(a,"HEARTBEAT.md"),H,"utf8")])}async function J(c){let{listProjectAgents:e}=await a.A(84839),f=[],g=[];for(let h of(await e(c))){if(!h.template_key){try{let e=B(h.agent_id),{readProjectBrief:g}=await a.A(78220),i=await g(c);null!==i&&(await (0,b.mkdir)(e,{recursive:!0}),await (0,b.writeFile)((0,d.join)(e,"PROJECT.md"),i,"utf8"),f.push(h.agent_id))}catch(a){g.push({name:h.agent_id,error:a instanceof Error?a.message:String(a)})}continue}let e=w.find(a=>a.key===h.template_key);if(!e){g.push({name:h.agent_id,error:`Unknown template '${h.template_key}'`});continue}try{let a=B(h.agent_id);await C(a,e,c,h.agent_id),f.push(h.agent_id)}catch(a){g.push({name:h.agent_id,error:a instanceof Error?a.message:String(a)})}}return{synced:f,failed:g}}async function K(a){try{return(await (0,e.openclaw)(["agents","list"],{json:!1})).includes(a)}catch{return!1}}},29855,a=>{"use strict";a.s(["listProjectAgents",()=>k,"readAgentMeta",()=>j,"resolveAgentBySlug",()=>m,"workspaceDirFor",()=>l,"writeAgentMeta",()=>i]);var b=a.i(2157),c=a.i(12714),d=a.i(60526),e=a.i(50227),f=a.i(6105);function g(){return process.env.NOTFAIR_CMO_DATA_DIR??(0,e.join)((0,d.homedir)(),".notfair-cmo")}function h(a){return(0,e.join)(g(),"agents",a,"notfair-meta.json")}async function i(a){let b=h(a.agent_id);await (0,c.mkdir)((0,e.join)(b,".."),{recursive:!0}),await (0,c.writeFile)(b,JSON.stringify(a,null,2),"utf8")}function j(a){let c=h(a);if(!(0,b.existsSync)(c))return null;try{return JSON.parse((0,b.readFileSync)(c,"utf8"))}catch{return null}}async function k(a){let b=new Map,d=new Map;for(let c of f.TEMPLATES){if(!c.default_onboarding)continue;let d=(0,f.agentNameFor)(a,c.key,c.default_name);b.set(c.key,{agent_id:d,slug:(0,f.agentUrlSlug)(c.key,c.default_name),name:c.default_name,description:c.description,template_key:c.key,is_template_default:!0})}let h=(0,e.join)(g(),"agents"),i=[];try{i=await (0,c.readdir)(h)}catch{return Array.from(b.values())}let k=`${a}-`;for(let a of i){if(!a.startsWith(k))continue;let c=j(a);if(!c)continue;let e=c.template_key?f.TEMPLATES.find(a=>a.key===c.template_key):void 0;if(e){let a=(0,f.agentUrlSlug)(e.key,c.name);b.set(e.key,{agent_id:c.agent_id,slug:a,name:c.name,template_key:c.template_key,source_agent_id:c.source_agent_id,is_template_default:!1})}else{let a=c.slug??c.name.toLowerCase().trim().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"").slice(0,32);d.set(c.agent_id,{agent_id:c.agent_id,slug:a,name:c.name,template_key:void 0,source_agent_id:c.source_agent_id,is_template_default:!1})}}let l=new Map;for(let a of b.values())l.set(a.agent_id,a);for(let a of d.values())l.set(a.agent_id,a);let m=new Map(f.TEMPLATES.map((a,b)=>[a.key,b]));return Array.from(l.values()).sort((a,b)=>{let c=a.template_key?m.get(a.template_key)??99:99,d=b.template_key?m.get(b.template_key)??99:99;return c!==d?c-d:a.slug.localeCompare(b.slug)})}function l(a){return(0,e.join)(g(),"agents",a)}async function m(a,b){let c=(await k(a)).find(a=>a.slug===b);return c?{agent_id:c.agent_id,name:c.name,slug:c.slug,template_key:c.template_key}:null}}];

//# sourceMappingURL=src_server_0uz77gr._.js.map