module.exports=[82195,3284,e=>{"use strict";var t=e.i(82651);async function a(e){let a=new t.GatewayClient;await a.open();try{return await e(a)}finally{a.close()}}async function o(){return a(e=>e.request("agents.list",{}))}e.s(["listAllAgents",0,o],82195);let n="__notfair_cmo_provisioning_progress__",r=globalThis,s=(r[n]??={}).store??(r[n].store=new Map);e.s(["initProgress",0,function(e,t){s.set(e,t.map(e=>({...e})))},"updateStep",0,function(e,t,a){let o=s.get(e);if(!o)return;let n=o.findIndex(e=>e.key===t);n<0||(o[n]={...o[n],...a})}],3284)},58355,e=>{"use strict";e.s(["listProjectAgents",()=>u,"readAgentMeta",()=>c,"resolveAgentBySlug",()=>d,"writeAgentMeta",()=>l]);var t=e.i(2157),a=e.i(12714),o=e.i(60526),n=e.i(50227),r=e.i(61807);function s(){return process.env.NOTFAIR_CMO_DATA_DIR??(0,n.join)((0,o.homedir)(),".notfair-cmo")}function i(e){return(0,n.join)(s(),"agents",e,"notfair-meta.json")}async function l(e){let t=i(e.agent_id);await (0,a.mkdir)((0,n.join)(t,".."),{recursive:!0}),await (0,a.writeFile)(t,JSON.stringify(e,null,2),"utf8")}function c(e){let a=i(e);if(!(0,t.existsSync)(a))return null;try{return JSON.parse((0,t.readFileSync)(a,"utf8"))}catch{return null}}async function u(e){let t=new Map,o=new Map;for(let a of r.TEMPLATES){if(!a.default_onboarding)continue;let o=(0,r.agentNameFor)(e,a.key,a.default_name);t.set(a.key,{agent_id:o,slug:(0,r.agentUrlSlug)(a.key,a.default_name),name:a.default_name,description:a.description,template_key:a.key,is_template_default:!0})}let i=(0,n.join)(s(),"agents"),l=[];try{l=await (0,a.readdir)(i)}catch{return Array.from(t.values())}let u=`${e}-`;for(let e of l){if(!e.startsWith(u))continue;let a=c(e);if(!a)continue;let n=a.template_key?r.TEMPLATES.find(e=>e.key===a.template_key):void 0;if(n){let e=(0,r.agentUrlSlug)(n.key,a.name);t.set(n.key,{agent_id:a.agent_id,slug:e,name:a.name,template_key:a.template_key,source_agent_id:a.source_agent_id,is_template_default:!1})}else{let e=a.slug??a.name.toLowerCase().trim().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"").slice(0,32);o.set(a.agent_id,{agent_id:a.agent_id,slug:e,name:a.name,template_key:void 0,source_agent_id:a.source_agent_id,is_template_default:!1})}}let d=new Map;for(let e of t.values())d.set(e.agent_id,e);for(let e of o.values())d.set(e.agent_id,e);let p=new Map(r.TEMPLATES.map((e,t)=>[e.key,t]));return Array.from(d.values()).sort((e,t)=>{let a=e.template_key?p.get(e.template_key)??99:99,o=t.template_key?p.get(t.template_key)??99:99;return a!==o?a-o:e.slug.localeCompare(t.slug)})}async function d(e,t){let a=(await u(e)).find(e=>e.slug===t);return a?{agent_id:a.agent_id,name:a.name,slug:a.slug,template_key:a.template_key}:null}},61807,32642,e=>{"use strict";e.s(["TEMPLATES",()=>b,"agentExists",()=>D,"agentNameFor",()=>S,"agentUrlSlug",()=>j,"ensureProjectAgents",()=>O,"syncProjectBriefToAgents",()=>R,"templateForKey",()=>v],61807);var t=e.i(12714),a=e.i(60526),o=e.i(50227),n=e.i(25350),r=e.i(82195),s=e.i(3284),i=e.i(58355),l=e.i(2157),c=e.i(66680);let u=process.env.NOTFAIR_CMO_DATA_DIR??(0,o.join)((0,a.homedir)(),".notfair-cmo"),d=(0,o.join)(u,"mcp-server-secret");function p(){if((0,l.existsSync)(u)||(0,l.mkdirSync)(u,{recursive:!0,mode:448}),(0,l.existsSync)(d)){let e=(0,l.readFileSync)(d,"utf8").trim();if(e)return e}let e=(0,c.randomBytes)(32).toString("hex");return(0,l.writeFileSync)(d,`${e}
`,{mode:384}),e}async function h(){var e,t;let a={url:function(){if(process.env.NOTFAIR_CMO_MCP_URL?.trim())return process.env.NOTFAIR_CMO_MCP_URL.trim();let e=process.env.NOTFAIR_CMO_PORT?.trim()||"3326";return`http://127.0.0.1:${e}/api/mcp/orchestration`}(),transport:"streamable-http",headers:{Authorization:`Bearer ${p()}`}},o="notfair-orchestration",r=await m(o);if(r&&(e=r,t=a,e.url===t.url&&e.transport===t.transport&&(e.headers?.Authorization??e.headers?.authorization)===t.headers.Authorization))return{ok:!0,status:"already_installed",key:o,url:a.url};try{return await (0,n.openclaw)(["mcp","set",o,JSON.stringify(a)],{json:!1}),{ok:!0,status:r?"updated":"installed",key:o,url:a.url}}catch(t){let e=t instanceof n.OpenClawError||t instanceof Error?t.message:String(t);return{ok:!1,key:o,url:a.url,error:e}}}async function g(e){for(let t of e){let e=`${t}-notfair-orchestration`;try{await (0,n.openclaw)(["mcp","unset",e],{json:!1})}catch{}}}async function m(e){try{let t=await (0,n.openclaw)(["mcp","show",e],{json:!0});if(!t||"object"!=typeof t)return null;return t}catch(e){if(e instanceof n.OpenClawError)return null;throw e}}e.s(["getOrCreateMcpServerSecret",0,p,"verifyMcpServerSecret",0,function(e){if(!e)return!1;let t=p();return e.length===t.length&&(0,c.timingSafeEqual)(Buffer.from(e,"utf8"),Buffer.from(t,"utf8"))}],32642);var f=e.i(90886);let y=`## 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 k=e.i(57243);let w=`## 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.`,_=`## 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.`;function v(e){return b.find(t=>t.key===e||t.key.replace(/_/g,"-")===e)}let b=[{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.

${w}`,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.

${_}

## 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.

${_}

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

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

- \`project_slug\`: \`${n}\`
- \`agent_id\`: \`${r}\`

Do NOT invent other values. Every orchestration tool call requires both.
`:"";await (0,t.writeFile)((0,o.join)(e,"SKILL.md"),y,"utf8");let i="";if(n){let a=await (0,k.readProjectBrief)(n);null!==a&&(await (0,t.writeFile)((0,o.join)(e,"PROJECT.md"),a,"utf8"),i=`
## 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.

${a.trim()}
`)}let l=`# ${a.display_name}

${a.description}
${s}${i}
${a.system_prompt}

---

${y}`;await (0,t.writeFile)((0,o.join)(e,"IDENTITY.md"),l,"utf8"),await N(e)}catch(e){console.error(`Could not write IDENTITY.md for ${a.key}:`,e)}}let E=`# 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.
`,M=`# 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.
`,P=`# Local Notes

Empty by design. Domain tool usage lives in IDENTITY.md; runtime
infrastructure (cameras, SSH, TTS) does not apply to this agent.
`,x=`# 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.
`,I=`# Heartbeat

Empty by design — heartbeats are disabled. Cron-driven check-ins
arrive as normal "(task assignment)" turns instead.
`;async function N(e){await Promise.all([(0,t.writeFile)((0,o.join)(e,"AGENTS.md"),E,"utf8"),(0,t.writeFile)((0,o.join)(e,"SOUL.md"),M,"utf8"),(0,t.writeFile)((0,o.join)(e,"TOOLS.md"),P,"utf8"),(0,t.writeFile)((0,o.join)(e,"USER.md"),x,"utf8"),(0,t.writeFile)((0,o.join)(e,"HEARTBEAT.md"),I,"utf8")])}async function R(a){let{listProjectAgents:n}=await e.A(98706),r=[],s=[];for(let i of(await n(a))){if(!i.template_key){try{let n=A(i.agent_id),{readProjectBrief:s}=await e.A(31533),l=await s(a);null!==l&&(await (0,t.mkdir)(n,{recursive:!0}),await (0,t.writeFile)((0,o.join)(n,"PROJECT.md"),l,"utf8"),r.push(i.agent_id))}catch(e){s.push({name:i.agent_id,error:e instanceof Error?e.message:String(e)})}continue}let n=b.find(e=>e.key===i.template_key);if(!n){s.push({name:i.agent_id,error:`Unknown template '${i.template_key}'`});continue}try{let e=A(i.agent_id);await C(e,n,a,i.agent_id),r.push(i.agent_id)}catch(e){s.push({name:i.agent_id,error:e instanceof Error?e.message:String(e)})}}return{synced:r,failed:s}}async function D(e){try{return(await (0,n.openclaw)(["agents","list"],{json:!1})).includes(e)}catch{return!1}}}];

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