ohwow 0.6.9 → 0.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +1293 -841
- package/dist/mcp-server/index.js +12 -12
- package/dist/migrations/091-skills-sop-columns.sql +18 -0
- package/dist/migrations/092-operational-pillars.sql +55 -0
- package/dist/migrations/093-seed-operational-pillars.sql +176 -0
- package/dist/migrations/094-person-models.sql +58 -0
- package/dist/migrations/095-transition-engine.sql +52 -0
- package/dist/migrations/096-work-router.sql +95 -0
- package/dist/migrations/097-human-growth.sql +58 -0
- package/dist/migrations/098-observation-layer.sql +5 -0
- package/dist/migrations/099-collective-intelligence.sql +5 -0
- package/dist/migrations/100-agent-model-policy.sql +32 -0
- package/dist/migrations/101-llm-calls.sql +36 -0
- package/dist/migrations/102-team-member-guide.sql +14 -0
- package/dist/migrations/103-fix-person-models-fk.sql +89 -0
- package/dist/migrations/104-fix-person-observations-fk.sql +48 -0
- package/dist/migrations/105-onboarding-plans.sql +56 -0
- package/dist/migrations/106-deliverable-actor-link.sql +29 -0
- package/dist/scrapling-server/requirements.txt +3 -0
- package/dist/scrapling-server/server.py +224 -0
- package/dist/web/assets/{index-B2PzvKIq.js → index-Bgm-uSeA.js} +1 -1
- package/dist/web/index.html +1 -1
- package/package.json +5 -4
package/dist/mcp-server/index.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { createRequire } from 'module'; const require = createRequire(import.meta.url);
|
|
2
|
-
import{McpServer as
|
|
3
|
-
`);
|
|
4
|
-
[Using tool: ${
|
|
5
|
-
`);else if(
|
|
6
|
-
[Error: ${
|
|
7
|
-
`);else if(
|
|
8
|
-
[Timed out after ${e/1e3}s. The task may still be running. Check with ohwow_list_tasks.]`;throw a}finally{clearTimeout(s)}}};import{z as h}from"zod";function $(n,o){n.tool("ohwow_chat","[Orchestrator] Send a message to the OHWOW orchestrator (88+ internal tools). Use this for: desktop control, automation creation, agent scheduling, approval management, agent state persistence, A2A protocol, PDF forms, media generation, and any multi-step request not covered by the direct tools. Do NOT use for simple listing or CRUD operations that have dedicated tools.",{message:h.string().describe("The message or instruction to send to the orchestrator")},async({message:t})=>{try{return{content:[{type:"text",text:await o.postSSE("/api/chat",{message:t})||"No response from orchestrator"}]}}catch(e){return{content:[{type:"text",text:`Error: ${e instanceof Error?e.message:"Unknown error"}`}],isError:!0}}}),n.tool("ohwow_list_agents","[Agents] List all agents in the OHWOW workspace with their status, role, and capabilities.",{},async()=>{try{let t=await o.get("/api/agents"),e=t.data||t;return{content:[{type:"text",text:JSON.stringify(e,null,2)}]}}catch(t){return{content:[{type:"text",text:`Error: ${t instanceof Error?t.message:"Unknown error"}`}],isError:!0}}}),n.tool("ohwow_run_agent","[Agents] Execute a specific agent with a prompt. Returns a task ID immediately (execution is async). Use ohwow_get_task to poll for status and result. Use ohwow_list_agents to find agent IDs.",{agentId:h.string().describe("The ID of the agent to run"),prompt:h.string().describe("The task or instruction for the agent")},async({agentId:t,prompt:e})=>{try{let r=await o.post("/api/tasks",{agentId:t,title:e});return{content:[{type:"text",text:JSON.stringify(r,null,2)}]}}catch(r){return{content:[{type:"text",text:`Error: ${r instanceof Error?r.message:"Unknown error"}`}],isError:!0}}}),n.tool("ohwow_get_task","[Tasks] Get the status and result of a task by its ID.",{taskId:h.string().describe("The task ID to look up")},async({taskId:t})=>{try{let e=await o.get(`/api/tasks/${t}`);return{content:[{type:"text",text:JSON.stringify(e,null,2)}]}}catch(e){return{content:[{type:"text",text:`Error: ${e instanceof Error?e.message:"Unknown error"}`}],isError:!0}}}),n.tool("ohwow_list_tasks","[Tasks] List recent tasks. Optionally filter by status or agent.",{status:h.string().optional().describe("Filter by status: pending, running, completed, failed"),agentId:h.string().optional().describe("Filter by agent ID"),limit:h.number().optional().describe("Max number of tasks to return (default: 20)")},async({status:t,agentId:e,limit:r})=>{try{let s=new URLSearchParams;t&&s.set("status",t),e&&s.set("agentId",e),r&&s.set("limit",String(r));let i=s.toString(),c=await o.get(`/api/tasks${i?`?${i}`:""}`);return{content:[{type:"text",text:JSON.stringify(c,null,2)}]}}catch(s){return{content:[{type:"text",text:`Error: ${s instanceof Error?s.message:"Unknown error"}`}],isError:!0}}}),n.tool("ohwow_workspace_status","[Workspace] Get workspace status: agent count, uptime, tier, and system stats.",{},async()=>{try{let t=await o.get("/api/dashboard/init");return{content:[{type:"text",text:JSON.stringify(t,null,2)}]}}catch(t){return{content:[{type:"text",text:`Error: ${t instanceof Error?t.message:"Unknown error"}`}],isError:!0}}})}import{z as l}from"zod";function j(n,o){n.tool("ohwow_list_contacts","[CRM] List contacts in the workspace. Returns name, email, company, pipeline stage, and tags.",{search:l.string().optional().describe("Filter by name, email, or company"),limit:l.number().optional().describe("Max results (default: 50)")},async({search:t,limit:e})=>{try{let r=new URLSearchParams;t&&r.set("search",t),e&&r.set("limit",String(e));let s=r.toString(),i=await o.get(`/api/contacts${s?`?${s}`:""}`),c=i.data||i;return{content:[{type:"text",text:JSON.stringify(c,null,2)}]}}catch(r){return{content:[{type:"text",text:`Error: ${r instanceof Error?r.message:"Unknown error"}`}],isError:!0}}}),n.tool("ohwow_create_contact","[CRM] Add a new contact to the CRM.",{name:l.string().describe("Contact full name"),email:l.string().optional().describe("Email address"),phone:l.string().optional().describe("Phone number"),company:l.string().optional().describe("Company or organization"),tags:l.array(l.string()).optional().describe("Tags for categorization"),notes:l.string().optional().describe("Additional notes about the contact")},async({name:t,email:e,phone:r,company:s,tags:i,notes:c})=>{try{let a={name:t};e&&(a.email=e),r&&(a.phone=r),s&&(a.company=s),i&&(a.tags=i),c&&(a.notes=c);let p=await o.post("/api/contacts",a);return{content:[{type:"text",text:JSON.stringify(p,null,2)}]}}catch(a){return{content:[{type:"text",text:`Error: ${a instanceof Error?a.message:"Unknown error"}`}],isError:!0}}}),n.tool("ohwow_search_contacts","[CRM] Full-text search across contacts by name, email, company, or notes.",{query:l.string().describe("Search query")},async({query:t})=>{try{return{content:[{type:"text",text:await o.postSSE("/api/chat",{message:`Use the search_contacts tool with query: "${t}". Return the results as-is.`},15e3)||"No contacts found"}]}}catch(e){return{content:[{type:"text",text:`Error: ${e instanceof Error?e.message:"Unknown error"}`}],isError:!0}}})}import{z as d}from"zod";function v(n,o){n.tool("ohwow_list_workflows","[Workflows] List all workflows in the workspace with their steps and status.",{},async()=>{try{let t=await o.get("/api/workflows"),e=t.data||t;return{content:[{type:"text",text:JSON.stringify(e,null,2)}]}}catch(t){return{content:[{type:"text",text:`Error: ${t instanceof Error?t.message:"Unknown error"}`}],isError:!0}}}),n.tool("ohwow_run_workflow","[Workflows] Execute a workflow by ID. Use ohwow_list_workflows to find IDs. May take up to 60 seconds depending on complexity.",{workflowId:d.string().describe("The workflow ID to execute"),variables:d.record(d.string(),d.unknown()).optional().describe("Input variables for the workflow")},async({workflowId:t,variables:e})=>{try{let r=e?` with variables: ${JSON.stringify(e)}`:"";return{content:[{type:"text",text:await o.postSSE("/api/chat",{message:`Use the run_workflow tool with workflowId: "${t}"${r}.`},6e4)||"Workflow started"}]}}catch(r){return{content:[{type:"text",text:`Error: ${r instanceof Error?r.message:"Unknown error"}`}],isError:!0}}}),n.tool("ohwow_list_automations","[Automations] List all automations with their triggers and status.",{},async()=>{try{let t=await o.get("/api/automations"),e=t.data||t;return{content:[{type:"text",text:JSON.stringify(e,null,2)}]}}catch(t){return{content:[{type:"text",text:`Error: ${t instanceof Error?t.message:"Unknown error"}`}],isError:!0}}}),n.tool("ohwow_run_automation","[Automations] Manually trigger an automation by ID. Use ohwow_list_automations to find IDs.",{automationId:d.string().describe("The automation ID to trigger")},async({automationId:t})=>{try{let e=await o.post(`/api/automations/${t}/execute`,{});return{content:[{type:"text",text:JSON.stringify(e,null,2)}]}}catch(e){return{content:[{type:"text",text:`Error: ${e instanceof Error?e.message:"Unknown error"}`}],isError:!0}}})}import{z as A}from"zod";function U(n,o){n.tool("ohwow_list_projects","[Projects] List all projects with status and task counts.",{},async()=>{try{let t=await o.get("/api/projects"),e=t.data||t;return{content:[{type:"text",text:JSON.stringify(e,null,2)}]}}catch(t){return{content:[{type:"text",text:`Error: ${t instanceof Error?t.message:"Unknown error"}`}],isError:!0}}}),n.tool("ohwow_create_project","[Projects] Create a new project for organizing work.",{name:A.string().describe("Project name"),description:A.string().optional().describe("Project description")},async({name:t,description:e})=>{try{let r={name:t};e&&(r.description=e);let s=await o.post("/api/projects",r);return{content:[{type:"text",text:JSON.stringify(s,null,2)}]}}catch(r){return{content:[{type:"text",text:`Error: ${r instanceof Error?r.message:"Unknown error"}`}],isError:!0}}}),n.tool("ohwow_list_goals","[Goals] List workspace goals with progress tracking.",{},async()=>{try{return{content:[{type:"text",text:await o.postSSE("/api/chat",{message:"Use the list_goals tool. Return the results as-is."},15e3)||"No goals found"}]}}catch(t){return{content:[{type:"text",text:`Error: ${t instanceof Error?t.message:"Unknown error"}`}],isError:!0}}})}import{z as k}from"zod";function N(n,o){n.tool("ohwow_list_knowledge","[Knowledge] List all documents in the knowledge base.",{},async()=>{try{return{content:[{type:"text",text:await o.postSSE("/api/chat",{message:"Use the list_knowledge tool. Return the results as-is."},15e3)||"No knowledge documents found"}]}}catch(t){return{content:[{type:"text",text:`Error: ${t instanceof Error?t.message:"Unknown error"}`}],isError:!0}}}),n.tool("ohwow_search_knowledge","[Knowledge] Semantic search across the knowledge base. Returns relevant document chunks.",{query:k.string().describe("The search query")},async({query:t})=>{try{return{content:[{type:"text",text:await o.postSSE("/api/chat",{message:`Use the search_knowledge tool with query: "${t}". Return the results as-is.`},15e3)||"No results found"}]}}catch(e){return{content:[{type:"text",text:`Error: ${e instanceof Error?e.message:"Unknown error"}`}],isError:!0}}}),n.tool("ohwow_add_knowledge_url","[Knowledge] Add a web page to the knowledge base. Fetches, chunks, and embeds the content for later search.",{url:k.string().describe("The URL to ingest"),title:k.string().optional().describe("Optional title for the document")},async({url:t,title:e})=>{try{let r=e?` with title: "${e}"`:"";return{content:[{type:"text",text:await o.postSSE("/api/chat",{message:`Use the add_knowledge_from_url tool with url: "${t}"${r}.`},3e4)||"Knowledge document added"}]}}catch(r){return{content:[{type:"text",text:`Error: ${r instanceof Error?r.message:"Unknown error"}`}],isError:!0}}})}import{z as _}from"zod";function D(n,o){n.tool("ohwow_deep_research","[Research] Multi-source web research with synthesis. Timing: quick ~30s, thorough ~60s, comprehensive ~120s.",{question:_.string().describe("The research question"),depth:_.enum(["quick","thorough","comprehensive"]).optional().describe("Research depth (default: thorough)")},async({question:t,depth:e})=>{try{let r=e?` with depth: "${e}"`:"";return{content:[{type:"text",text:await o.postSSE("/api/chat",{message:`Use the deep_research tool with question: "${t}"${r}. Return the full research report.`},18e4)||"No research results"}]}}catch(r){return{content:[{type:"text",text:`Error: ${r instanceof Error?r.message:"Unknown error"}`}],isError:!0}}}),n.tool("ohwow_scrape_url","[Research] Scrape a web page and return its structured content. Automatically handles anti-bot protection.",{url:_.string().describe("The URL to scrape")},async({url:t})=>{try{return{content:[{type:"text",text:await o.postSSE("/api/chat",{message:`Use the scrape_url tool with url: "${t}". Return the scraped content.`},3e4)||"No content scraped"}]}}catch(e){return{content:[{type:"text",text:`Error: ${e instanceof Error?e.message:"Unknown error"}`}],isError:!0}}})}import{z as y}from"zod";function M(n,o){n.tool("ohwow_send_message","[Messaging] Send a message via WhatsApp or Telegram. Use ohwow_list_chats to find chat IDs. The channel must be connected in the ohwow dashboard first.",{channel:y.enum(["whatsapp","telegram"]).describe("Messaging channel"),chatId:y.string().describe("Chat or contact ID to send to"),message:y.string().describe("Message text to send")},async({channel:t,chatId:e,message:r})=>{try{let s=t==="whatsapp"?"send_whatsapp_message":"send_telegram_message";return{content:[{type:"text",text:await o.postSSE("/api/chat",{message:`Use the ${s} tool to send this message to chat "${e}": ${r}`},15e3)||"Message sent"}]}}catch(s){return{content:[{type:"text",text:`Error: ${s instanceof Error?s.message:"Unknown error"}`}],isError:!0}}}),n.tool("ohwow_list_chats","[Messaging] List connected chats for WhatsApp or Telegram.",{channel:y.enum(["whatsapp","telegram"]).describe("Messaging channel")},async({channel:t})=>{try{let e=t==="whatsapp"?"list_whatsapp_chats":"list_telegram_chats";return{content:[{type:"text",text:await o.postSSE("/api/chat",{message:`Use the ${e} tool. Return the results as-is.`},15e3)||"No chats found"}]}}catch(e){return{content:[{type:"text",text:`Error: ${e instanceof Error?e.message:"Unknown error"}`}],isError:!0}}})}function W(n,o){n.tool("ohwow_list_sites","[Cloud] List all sites on the ohwow.fun cloud dashboard with status and URLs. Requires cloud connection.",{},async()=>{try{let t=await o.get("/api/cloud/sites");if(t.cloudConnected===!1)return{content:[{type:"text",text:"Not connected to ohwow.fun. Run `ohwow connect` to link your cloud account."}]};let e=t.data||[];return{content:[{type:"text",text:JSON.stringify(e,null,2)}]}}catch(t){return{content:[{type:"text",text:`Error: ${t instanceof Error?t.message:"Unknown error"}`}],isError:!0}}}),n.tool("ohwow_list_integrations","[Cloud] List connected integrations (Gmail, GitHub, Stripe, etc.) and their status. Requires cloud connection.",{},async()=>{try{let t=await o.get("/api/cloud/integrations");if(t.cloudConnected===!1)return{content:[{type:"text",text:"Not connected to ohwow.fun. Run `ohwow connect` to link your cloud account."}]};let e=t.data||[];return{content:[{type:"text",text:JSON.stringify(e,null,2)}]}}catch(t){return{content:[{type:"text",text:`Error: ${t instanceof Error?t.message:"Unknown error"}`}],isError:!0}}})}function I(n,o){$(n,o),j(n,o),v(n,o),U(n,o),N(n,o),D(n,o),M(n,o),W(n,o)}function P(n,o){n.resource("agents","ohwow://agents",{description:"All OHWOW agents with their descriptions, roles, and available tools"},async()=>{try{let t=await o.get("/api/agents"),e=t.data||t;return{contents:[{uri:"ohwow://agents",mimeType:"application/json",text:JSON.stringify(e,null,2)}]}}catch{return{contents:[{uri:"ohwow://agents",mimeType:"text/plain",text:"Could not load agents. Is the OHWOW daemon running?"}]}}}),n.resource("workspace","ohwow://workspace",{description:"OHWOW workspace status: tier, uptime, agent count, system stats"},async()=>{try{let t=await o.get("/api/dashboard/init");return{contents:[{uri:"ohwow://workspace",mimeType:"application/json",text:JSON.stringify(t,null,2)}]}}catch{return{contents:[{uri:"ohwow://workspace",mimeType:"text/plain",text:"Could not load workspace status. Is the OHWOW daemon running?"}]}}}),n.resource("contacts","ohwow://contacts",{description:"Recent CRM contacts with pipeline stage breakdown"},async()=>{try{let t=await o.get("/api/contacts?limit=10"),e=t.data||t;return{contents:[{uri:"ohwow://contacts",mimeType:"application/json",text:JSON.stringify(e,null,2)}]}}catch{return{contents:[{uri:"ohwow://contacts",mimeType:"text/plain",text:"Could not load contacts. Is the OHWOW daemon running?"}]}}}),n.resource("projects","ohwow://projects",{description:"Active projects with task counts and status"},async()=>{try{let t=await o.get("/api/projects"),e=t.data||t;return{contents:[{uri:"ohwow://projects",mimeType:"application/json",text:JSON.stringify(e,null,2)}]}}catch{return{contents:[{uri:"ohwow://projects",mimeType:"text/plain",text:"Could not load projects. Is the OHWOW daemon running?"}]}}}),n.resource("workflows","ohwow://workflows",{description:"Workflow and automation catalog with descriptions and trigger types"},async()=>{try{let[t,e]=await Promise.all([o.get("/api/workflows"),o.get("/api/automations")]),r=t.data||t,s=e.data||e;return{contents:[{uri:"ohwow://workflows",mimeType:"application/json",text:JSON.stringify({workflows:r,automations:s},null,2)}]}}catch{return{contents:[{uri:"ohwow://workflows",mimeType:"text/plain",text:"Could not load workflows. Is the OHWOW daemon running?"}]}}}),n.resource("capabilities","ohwow://capabilities",{description:"Complete list of all OHWOW MCP tools grouped by domain"},async()=>({contents:[{uri:"ohwow://capabilities",mimeType:"text/plain",text:q}]}))}var q=`OHWOW MCP Plugin \u2014 Quick Reference
|
|
2
|
+
import{McpServer as Ct}from"@modelcontextprotocol/sdk/server/mcp.js";import{StdioServerTransport as Pt}from"@modelcontextprotocol/sdk/server/stdio.js";import{readFileSync as R,existsSync as J}from"fs";import{join as D}from"path";import{homedir as nt}from"os";var k=class r{constructor(o,t,e){this.baseUrl=`http://127.0.0.1:${o}`,this.token=t,this.tokenPath=e}static async create(){let o=D(nt(),".ohwow"),t=D(o,"config.json"),e=D(o,"data","daemon.token"),n=7700;if(J(t))try{let c=R(t,"utf-8"),a=JSON.parse(c);a.port&&(n=a.port)}catch{}if(!J(e))throw new Error("OHWOW daemon is not running. Start it with: ohwow");let s=R(e,"utf-8").trim();if(!s)throw new Error("Couldn't authenticate with OHWOW daemon. Try: ohwow restart");let i=new r(n,s,e);try{await i.get("/health")}catch{throw new Error("OHWOW daemon is not running. Start it with: ohwow")}return i}refreshToken(){try{let o=R(this.tokenPath,"utf-8").trim();if(o&&o!==this.token)return this.token=o,!0}catch{}return!1}authHeaders(){return{Authorization:`Bearer ${this.token}`}}async fetchWithRetry(o,t){let e=await fetch(o,t);if(e.status===401&&this.refreshToken()){let n={...t.headers,...this.authHeaders()};e=await fetch(o,{...t,headers:n})}return e}async get(o){let t=await this.fetchWithRetry(`${this.baseUrl}${o}`,{headers:this.authHeaders()});if(!t.ok)throw new Error(`ohwow daemon error on GET ${o}: ${t.status}. Check daemon with: ohwow logs`);return t.json()}async post(o,t){let e=await this.fetchWithRetry(`${this.baseUrl}${o}`,{method:"POST",headers:{...this.authHeaders(),"Content-Type":"application/json"},body:JSON.stringify(t)});if(!e.ok)throw new Error(`ohwow daemon error on POST ${o}: ${e.status}. Check daemon with: ohwow logs`);return e.json()}async postSSE(o,t,e=12e4){let n=new AbortController,s=setTimeout(()=>n.abort(),e),i=[],c=async()=>fetch(`${this.baseUrl}${o}`,{method:"POST",headers:{...this.authHeaders(),"Content-Type":"application/json",Accept:"text/event-stream"},body:JSON.stringify(t),signal:n.signal});try{let a=await c();if(a.status===401&&this.refreshToken()&&(a=await c()),!a.ok)throw new Error(`Daemon API error: ${a.status} ${a.statusText}`);if(!a.body)throw new Error("No response body from daemon");let p=a.body.getReader(),g=new TextDecoder,f="";for(;;){let{done:m,value:rt}=await p.read();if(m)break;f+=g.decode(rt,{stream:!0});let M=f.split(`
|
|
3
|
+
`);f=M.pop()||"";for(let I of M){if(!I.startsWith("data: "))continue;let W=I.slice(6).trim();if(W!=="[DONE]")try{let w=JSON.parse(W);if(w.type==="text"&&w.content)i.push(w.content);else if(w.type==="tool_start")i.push(`
|
|
4
|
+
[Using tool: ${w.name}]
|
|
5
|
+
`);else if(w.type==="error")i.push(`
|
|
6
|
+
[Error: ${w.error}]
|
|
7
|
+
`);else if(w.type==="done")break}catch{}}}return i.join("")}catch(a){if(a instanceof Error&&a.name==="AbortError")return i.join("")+`
|
|
8
|
+
[Timed out after ${e/1e3}s. The task may still be running. Check with ohwow_list_tasks.]`;throw a}finally{clearTimeout(s)}}};import{z as l}from"zod";function L(r,o){r.tool("ohwow_chat","[Orchestrator] Send a message to the OHWOW orchestrator (88+ internal tools). Use this for: desktop control, automation creation, agent scheduling, approval management, agent state persistence, A2A protocol, PDF forms, media generation, and any multi-step request not covered by the direct tools. Do NOT use for simple listing or CRUD operations that have dedicated tools.",{message:l.string().describe("The message or instruction to send to the orchestrator")},async({message:t})=>{try{return{content:[{type:"text",text:await o.postSSE("/api/chat",{message:t})||"No response from orchestrator"}]}}catch(e){return{content:[{type:"text",text:`Error: ${e instanceof Error?e.message:"Unknown error"}`}],isError:!0}}}),r.tool("ohwow_list_agents","[Agents] List all agents in the OHWOW workspace with their status, role, and capabilities.",{},async()=>{try{let t=await o.get("/api/agents"),e=t.data||t;return{content:[{type:"text",text:JSON.stringify(e,null,2)}]}}catch(t){return{content:[{type:"text",text:`Error: ${t instanceof Error?t.message:"Unknown error"}`}],isError:!0}}}),r.tool("ohwow_run_agent","[Agents] Execute a specific agent with a prompt. Returns a task ID immediately (execution is async). Use ohwow_get_task to poll for status and result. Use ohwow_list_agents to find agent IDs.",{agentId:l.string().describe("The ID of the agent to run"),prompt:l.string().describe("The task or instruction for the agent")},async({agentId:t,prompt:e})=>{try{let n=await o.post("/api/tasks",{agentId:t,title:e});return{content:[{type:"text",text:JSON.stringify(n,null,2)}]}}catch(n){return{content:[{type:"text",text:`Error: ${n instanceof Error?n.message:"Unknown error"}`}],isError:!0}}}),r.tool("ohwow_get_task","[Tasks] Get the status and result of a task by its ID.",{taskId:l.string().describe("The task ID to look up")},async({taskId:t})=>{try{let e=await o.get(`/api/tasks/${t}`);return{content:[{type:"text",text:JSON.stringify(e,null,2)}]}}catch(e){return{content:[{type:"text",text:`Error: ${e instanceof Error?e.message:"Unknown error"}`}],isError:!0}}}),r.tool("ohwow_list_tasks","[Tasks] List recent tasks. Optionally filter by status or agent.",{status:l.string().optional().describe("Filter by status: pending, running, completed, failed"),agentId:l.string().optional().describe("Filter by agent ID"),limit:l.number().optional().describe("Max number of tasks to return (default: 20)")},async({status:t,agentId:e,limit:n})=>{try{let s=new URLSearchParams;t&&s.set("status",t),e&&s.set("agentId",e),n&&s.set("limit",String(n));let i=s.toString(),c=await o.get(`/api/tasks${i?`?${i}`:""}`);return{content:[{type:"text",text:JSON.stringify(c,null,2)}]}}catch(s){return{content:[{type:"text",text:`Error: ${s instanceof Error?s.message:"Unknown error"}`}],isError:!0}}}),r.tool("ohwow_workspace_status","[Workspace] Get workspace status: agent count, uptime, tier, and system stats.",{},async()=>{try{let t=await o.get("/api/dashboard/init");return{content:[{type:"text",text:JSON.stringify(t,null,2)}]}}catch(t){return{content:[{type:"text",text:`Error: ${t instanceof Error?t.message:"Unknown error"}`}],isError:!0}}}),r.tool("ohwow_llm","[LLM Organ] Invoke ohwow's model router for a specific sub-task. Pass a `purpose` (reasoning, generation, summarization, extraction, critique, translation, planning, classification, etc.) and a `prompt` string. ohwow resolves the agent's model_policy (if agentId is given), workspace defaults, and constraints, then picks a provider+model and runs the call. Returns { text, model_used, provider, purpose, tokens, cost_cents, latency_ms }. Use this when you want ohwow to act as your model selector instead of pinning to a specific model yourself.",{purpose:l.enum(["orchestrator_chat","agent_task","planning","browser_automation","memory_extraction","ocr","workflow_step","simple_classification","desktop_control","reasoning","generation","summarization","extraction","critique","translation","embedding"]).optional().describe('Semantic purpose that drives routing. Defaults to "reasoning".'),prompt:l.string().describe("The user prompt to send to the selected model."),system:l.string().optional().describe("Optional system prompt."),agentId:l.string().optional().describe("Agent ID to load model_policy from. Omit to use workspace defaults only."),max_tokens:l.number().optional().describe("Maximum output tokens."),temperature:l.number().optional().describe("Sampling temperature."),local_only:l.boolean().optional().describe("Force local inference (clamps modelSource to local)."),prefer_model:l.string().optional().describe("Call-site model override; wins over agent policy."),max_cost_cents:l.number().optional().describe("Advisory cost ceiling in cents."),difficulty:l.enum(["simple","moderate","complex"]).optional().describe("Difficulty hint for escalation.")},async t=>{try{let e=await o.post("/api/llm",t);return{content:[{type:"text",text:JSON.stringify(e,null,2)}]}}catch(e){return{content:[{type:"text",text:`Error: ${e instanceof Error?e.message:"Unknown error"}`}],isError:!0}}})}import{z as d}from"zod";function H(r,o){r.tool("ohwow_list_contacts","[CRM] List contacts in the workspace. Returns name, email, company, pipeline stage, and tags.",{search:d.string().optional().describe("Filter by name, email, or company"),limit:d.number().optional().describe("Max results (default: 50)")},async({search:t,limit:e})=>{try{let n=new URLSearchParams;t&&n.set("search",t),e&&n.set("limit",String(e));let s=n.toString(),i=await o.get(`/api/contacts${s?`?${s}`:""}`),c=i.data||i;return{content:[{type:"text",text:JSON.stringify(c,null,2)}]}}catch(n){return{content:[{type:"text",text:`Error: ${n instanceof Error?n.message:"Unknown error"}`}],isError:!0}}}),r.tool("ohwow_create_contact","[CRM] Add a new contact to the CRM.",{name:d.string().describe("Contact full name"),email:d.string().optional().describe("Email address"),phone:d.string().optional().describe("Phone number"),company:d.string().optional().describe("Company or organization"),tags:d.array(d.string()).optional().describe("Tags for categorization"),notes:d.string().optional().describe("Additional notes about the contact")},async({name:t,email:e,phone:n,company:s,tags:i,notes:c})=>{try{let a={name:t};e&&(a.email=e),n&&(a.phone=n),s&&(a.company=s),i&&(a.tags=i),c&&(a.notes=c);let p=await o.post("/api/contacts",a);return{content:[{type:"text",text:JSON.stringify(p,null,2)}]}}catch(a){return{content:[{type:"text",text:`Error: ${a instanceof Error?a.message:"Unknown error"}`}],isError:!0}}}),r.tool("ohwow_search_contacts","[CRM] Full-text search across contacts by name, email, company, or notes.",{query:d.string().describe("Search query")},async({query:t})=>{try{return{content:[{type:"text",text:await o.postSSE("/api/chat",{message:`Use the search_contacts tool with query: "${t}". Return the results as-is.`},15e3)||"No contacts found"}]}}catch(e){return{content:[{type:"text",text:`Error: ${e instanceof Error?e.message:"Unknown error"}`}],isError:!0}}})}import{z as y}from"zod";function F(r,o){r.tool("ohwow_list_workflows","[Workflows] List all workflows in the workspace with their steps and status.",{},async()=>{try{let t=await o.get("/api/workflows"),e=t.data||t;return{content:[{type:"text",text:JSON.stringify(e,null,2)}]}}catch(t){return{content:[{type:"text",text:`Error: ${t instanceof Error?t.message:"Unknown error"}`}],isError:!0}}}),r.tool("ohwow_run_workflow","[Workflows] Execute a workflow by ID. Use ohwow_list_workflows to find IDs. May take up to 60 seconds depending on complexity.",{workflowId:y.string().describe("The workflow ID to execute"),variables:y.record(y.string(),y.unknown()).optional().describe("Input variables for the workflow")},async({workflowId:t,variables:e})=>{try{let n=e?` with variables: ${JSON.stringify(e)}`:"";return{content:[{type:"text",text:await o.postSSE("/api/chat",{message:`Use the run_workflow tool with workflowId: "${t}"${n}.`},6e4)||"Workflow started"}]}}catch(n){return{content:[{type:"text",text:`Error: ${n instanceof Error?n.message:"Unknown error"}`}],isError:!0}}}),r.tool("ohwow_list_automations","[Automations] List all automations with their triggers and status.",{},async()=>{try{let t=await o.get("/api/automations"),e=t.data||t;return{content:[{type:"text",text:JSON.stringify(e,null,2)}]}}catch(t){return{content:[{type:"text",text:`Error: ${t instanceof Error?t.message:"Unknown error"}`}],isError:!0}}}),r.tool("ohwow_run_automation","[Automations] Manually trigger an automation by ID. Use ohwow_list_automations to find IDs.",{automationId:y.string().describe("The automation ID to trigger")},async({automationId:t})=>{try{let e=await o.post(`/api/automations/${t}/execute`,{});return{content:[{type:"text",text:JSON.stringify(e,null,2)}]}}catch(e){return{content:[{type:"text",text:`Error: ${e instanceof Error?e.message:"Unknown error"}`}],isError:!0}}})}import{z as q}from"zod";function G(r,o){r.tool("ohwow_list_projects","[Projects] List all projects with status and task counts.",{},async()=>{try{let t=await o.get("/api/projects"),e=t.data||t;return{content:[{type:"text",text:JSON.stringify(e,null,2)}]}}catch(t){return{content:[{type:"text",text:`Error: ${t instanceof Error?t.message:"Unknown error"}`}],isError:!0}}}),r.tool("ohwow_create_project","[Projects] Create a new project for organizing work.",{name:q.string().describe("Project name"),description:q.string().optional().describe("Project description")},async({name:t,description:e})=>{try{let n={name:t};e&&(n.description=e);let s=await o.post("/api/projects",n);return{content:[{type:"text",text:JSON.stringify(s,null,2)}]}}catch(n){return{content:[{type:"text",text:`Error: ${n instanceof Error?n.message:"Unknown error"}`}],isError:!0}}}),r.tool("ohwow_list_goals","[Goals] List workspace goals with progress tracking.",{},async()=>{try{return{content:[{type:"text",text:await o.postSSE("/api/chat",{message:"Use the list_goals tool. Return the results as-is."},15e3)||"No goals found"}]}}catch(t){return{content:[{type:"text",text:`Error: ${t instanceof Error?t.message:"Unknown error"}`}],isError:!0}}})}import{z as T}from"zod";function z(r,o){r.tool("ohwow_list_knowledge","[Knowledge] List all documents in the knowledge base.",{},async()=>{try{return{content:[{type:"text",text:await o.postSSE("/api/chat",{message:"Use the list_knowledge tool. Return the results as-is."},15e3)||"No knowledge documents found"}]}}catch(t){return{content:[{type:"text",text:`Error: ${t instanceof Error?t.message:"Unknown error"}`}],isError:!0}}}),r.tool("ohwow_search_knowledge","[Knowledge] Semantic search across the knowledge base. Returns relevant document chunks.",{query:T.string().describe("The search query")},async({query:t})=>{try{return{content:[{type:"text",text:await o.postSSE("/api/chat",{message:`Use the search_knowledge tool with query: "${t}". Return the results as-is.`},15e3)||"No results found"}]}}catch(e){return{content:[{type:"text",text:`Error: ${e instanceof Error?e.message:"Unknown error"}`}],isError:!0}}}),r.tool("ohwow_add_knowledge_url","[Knowledge] Add a web page to the knowledge base. Fetches, chunks, and embeds the content for later search.",{url:T.string().describe("The URL to ingest"),title:T.string().optional().describe("Optional title for the document")},async({url:t,title:e})=>{try{let n=e?` with title: "${e}"`:"";return{content:[{type:"text",text:await o.postSSE("/api/chat",{message:`Use the add_knowledge_from_url tool with url: "${t}"${n}.`},3e4)||"Knowledge document added"}]}}catch(n){return{content:[{type:"text",text:`Error: ${n instanceof Error?n.message:"Unknown error"}`}],isError:!0}}})}import{z as v}from"zod";function K(r,o){r.tool("ohwow_deep_research","[Research] Multi-source web research with synthesis. Timing: quick ~30s, thorough ~60s, comprehensive ~120s.",{question:v.string().describe("The research question"),depth:v.enum(["quick","thorough","comprehensive"]).optional().describe("Research depth (default: thorough)")},async({question:t,depth:e})=>{try{let n=e?` with depth: "${e}"`:"";return{content:[{type:"text",text:await o.postSSE("/api/chat",{message:`Use the deep_research tool with question: "${t}"${n}. Return the full research report.`},18e4)||"No research results"}]}}catch(n){return{content:[{type:"text",text:`Error: ${n instanceof Error?n.message:"Unknown error"}`}],isError:!0}}}),r.tool("ohwow_scrape_url","[Research] Scrape a web page and return its structured content. Automatically handles anti-bot protection.",{url:v.string().describe("The URL to scrape")},async({url:t})=>{try{return{content:[{type:"text",text:await o.postSSE("/api/chat",{message:`Use the scrape_url tool with url: "${t}". Return the scraped content.`},3e4)||"No content scraped"}]}}catch(e){return{content:[{type:"text",text:`Error: ${e instanceof Error?e.message:"Unknown error"}`}],isError:!0}}})}import{z as S}from"zod";function B(r,o){r.tool("ohwow_send_message","[Messaging] Send a message via WhatsApp or Telegram. Use ohwow_list_chats to find chat IDs. The channel must be connected in the ohwow dashboard first.",{channel:S.enum(["whatsapp","telegram"]).describe("Messaging channel"),chatId:S.string().describe("Chat or contact ID to send to"),message:S.string().describe("Message text to send")},async({channel:t,chatId:e,message:n})=>{try{let s=t==="whatsapp"?"send_whatsapp_message":"send_telegram_message";return{content:[{type:"text",text:await o.postSSE("/api/chat",{message:`Use the ${s} tool to send this message to chat "${e}": ${n}`},15e3)||"Message sent"}]}}catch(s){return{content:[{type:"text",text:`Error: ${s instanceof Error?s.message:"Unknown error"}`}],isError:!0}}}),r.tool("ohwow_list_chats","[Messaging] List connected chats for WhatsApp or Telegram.",{channel:S.enum(["whatsapp","telegram"]).describe("Messaging channel")},async({channel:t})=>{try{let e=t==="whatsapp"?"list_whatsapp_chats":"list_telegram_chats";return{content:[{type:"text",text:await o.postSSE("/api/chat",{message:`Use the ${e} tool. Return the results as-is.`},15e3)||"No chats found"}]}}catch(e){return{content:[{type:"text",text:`Error: ${e instanceof Error?e.message:"Unknown error"}`}],isError:!0}}})}function V(r,o){r.tool("ohwow_list_sites","[Cloud] List all sites on the ohwow.fun cloud dashboard with status and URLs. Requires cloud connection.",{},async()=>{try{let t=await o.get("/api/cloud/sites");if(t.cloudConnected===!1)return{content:[{type:"text",text:"Not connected to ohwow.fun. Run `ohwow connect` to link your cloud account."}]};let e=t.data||[];return{content:[{type:"text",text:JSON.stringify(e,null,2)}]}}catch(t){return{content:[{type:"text",text:`Error: ${t instanceof Error?t.message:"Unknown error"}`}],isError:!0}}}),r.tool("ohwow_list_integrations","[Cloud] List connected integrations (Gmail, GitHub, Stripe, etc.) and their status. Requires cloud connection.",{},async()=>{try{let t=await o.get("/api/cloud/integrations");if(t.cloudConnected===!1)return{content:[{type:"text",text:"Not connected to ohwow.fun. Run `ohwow connect` to link your cloud account."}]};let e=t.data||[];return{content:[{type:"text",text:JSON.stringify(e,null,2)}]}}catch(t){return{content:[{type:"text",text:`Error: ${t instanceof Error?t.message:"Unknown error"}`}],isError:!0}}})}import{z as b}from"zod";import{join as h,dirname as gt}from"path";import{homedir as ft}from"os";import{existsSync as Z,readFileSync as yt}from"fs";import{fileURLToPath as xt}from"url";import{join as X}from"path";import{spawn as ct}from"child_process";import{openSync as pt,existsSync as lt,statSync as ut,renameSync as dt,writeFileSync as ie,unlinkSync as ce,readFileSync as pe}from"fs";import{readFileSync as st,writeFileSync as Zt,unlinkSync as Yt,existsSync as at,mkdirSync as te}from"fs";function _(r){try{if(!at(r))return null;let o=st(r,"utf-8");return JSON.parse(o)}catch{return null}}function E(r){try{return process.kill(r,0),!0}catch{return!1}}import it from"pino";var Q=it({level:process.env.LOG_LEVEL||(process.env.NODE_ENV==="production"?"info":"debug"),...process.env.NODE_ENV!=="production"&&{transport:{target:"pino-pretty",options:{colorize:!0}}}});var mt=10*1024*1024;function wt(r){return X(r,"daemon.log")}function ht(r){try{if(!lt(r))return;ut(r).size>mt&&dt(r,`${r}.1`)}catch{}}function C(r){return X(r,"daemon.pid")}async function x(r,o){let t=_(C(r));if(!t)return{running:!1};if(!E(t.pid))return{running:!1};let e=t.port||o;try{let n=await fetch(`http://localhost:${e}/health`,{signal:AbortSignal.timeout(2e3)});if(n.ok){let s=await n.json();if(s.status==="healthy"||s.status==="degraded")return{running:!0,pid:t.pid}}}catch{return{running:!0,pid:t.pid,healthy:!1}}return{running:!1}}function P(r,o,t){let e=wt(t);ht(e);let n=pt(e,"a"),i=r.endsWith(".ts")?["--import","tsx",r,"--daemon"]:[r,"--daemon"],c={...process.env,OHWOW_PORT:String(o)};process.env.OHWOW_WORKSPACE&&(c.OHWOW_WORKSPACE=process.env.OHWOW_WORKSPACE);let a=ct(process.execPath,i,{detached:!0,windowsHide:!0,stdio:["ignore",n,n],env:c});return a.unref(),a.pid}async function N(r,o=15e3){let t=Date.now()+o,e=300;for(;Date.now()<t;){try{if((await fetch(`http://localhost:${r}/health`,{signal:AbortSignal.timeout(1e3)})).ok)return!0}catch{}await new Promise(n=>setTimeout(n,e))}return!1}async function j(r){let o=_(C(r));if(!o||!E(o.pid))return!1;if(process.platform==="win32"&&o.port)try{return await fetch(`http://localhost:${o.port}/shutdown`,{method:"POST",signal:AbortSignal.timeout(3e3)}),!0}catch{try{return process.kill(o.pid),!0}catch{return!1}}try{return process.kill(o.pid,"SIGTERM"),!0}catch(t){return t.code==="EPERM"&&Q.error("Cannot stop daemon (PID %d): permission denied. It may be running as a different user.",o.pid),!1}}async function $(r,o=5e3){let t=C(r),e=Date.now()+o,n=200;for(;Date.now()<e;){let s=_(t);if(!s||!E(s.pid))return!0;await new Promise(i=>setTimeout(i,n))}return!1}function O(){let r=h(ft(),".ohwow"),o=h(r,"data"),t=7700,e=h(r,"config.json");if(Z(e))try{let c=yt(e,"utf-8"),a=JSON.parse(c);typeof a.port=="number"&&(t=a.port)}catch{}let n=gt(xt(import.meta.url)),i=[h(n,"..","..","index.js"),h(n,"..","..","..","index.js"),h(n,"..","..","..","index.ts"),h(n,"..","..","index.ts")].find(c=>Z(c))??null;return{dataDir:o,port:t,entryPath:i}}async function u(r){let o=await x(r.dataDir,r.port);return{running:o.running,healthy:o.running&&o.healthy!==!1,pid:o.pid??null,port:r.port,dataDir:r.dataDir,entryPath:r.entryPath}}function Y(r){r.tool("ohwow_daemon_status","[Daemon] Check whether the ohwow local daemon is running. Reports pid, port, health, and the resolved entry path. Does not modify state.",{},async()=>{try{let o=O(),t=await u(o);return{content:[{type:"text",text:JSON.stringify(t,null,2)}]}}catch(o){return{content:[{type:"text",text:`Error: ${o instanceof Error?o.message:"Unknown error"}`}],isError:!0}}}),r.tool("ohwow_daemon_stop","[Daemon] Stop the running ohwow daemon gracefully (SIGTERM on Unix, /shutdown on Windows). Returns whether it actually stopped within the timeout.",{timeoutMs:b.number().optional().describe("How long to wait for the daemon to stop before reporting failure. Default 5000ms.")},async({timeoutMs:o})=>{try{let t=O();if(!(await x(t.dataDir,t.port)).running)return{content:[{type:"text",text:JSON.stringify({ok:!0,alreadyStopped:!0,...await u(t)},null,2)}]};if(!await j(t.dataDir))return{content:[{type:"text",text:JSON.stringify({ok:!1,error:"Could not send stop signal (permission denied or stale pid)",...await u(t)},null,2)}],isError:!0};let s=await $(t.dataDir,o??5e3),i=await u(t);return{content:[{type:"text",text:JSON.stringify({ok:s,...i},null,2)}],isError:!s}}catch(t){return{content:[{type:"text",text:`Error: ${t instanceof Error?t.message:"Unknown error"}`}],isError:!0}}}),r.tool("ohwow_daemon_start","[Daemon] Start the ohwow daemon in the background if it is not already running. Waits for the health endpoint before returning. No-op if the daemon is already healthy.",{timeoutMs:b.number().optional().describe("How long to wait for the daemon to become healthy. Default 15000ms.")},async({timeoutMs:o})=>{try{let t=O(),e=await x(t.dataDir,t.port);if(e.running&&e.healthy!==!1)return{content:[{type:"text",text:JSON.stringify({ok:!0,alreadyRunning:!0,...await u(t)},null,2)}]};if(!t.entryPath)return{content:[{type:"text",text:JSON.stringify({ok:!1,error:"Could not locate daemon entry (dist/index.js or src/index.ts)",...await u(t)},null,2)}],isError:!0};let n=P(t.entryPath,t.port,t.dataDir),s=await N(t.port,o??15e3),i=await u(t);return{content:[{type:"text",text:JSON.stringify({ok:s,spawnedPid:n,entryPath:t.entryPath,...i},null,2)}],isError:!s}}catch(t){return{content:[{type:"text",text:`Error: ${t instanceof Error?t.message:"Unknown error"}`}],isError:!0}}}),r.tool("ohwow_daemon_restart","[Daemon] Restart the ohwow daemon: stop if running, wait for the PID to clear, then spawn a fresh background instance and wait for health. Use this after rebuilding dist/index.js so the running daemon picks up the new code. Safe to call even when the daemon is already dead \u2014 it will just start a fresh one.",{stopTimeoutMs:b.number().optional().describe("Timeout for the stop phase. Default 5000ms."),startTimeoutMs:b.number().optional().describe("Timeout for the start/health phase. Default 15000ms.")},async({stopTimeoutMs:o,startTimeoutMs:t})=>{try{let e=O();if(!e.entryPath)return{content:[{type:"text",text:JSON.stringify({ok:!1,error:"Could not locate daemon entry (dist/index.js or src/index.ts)",...await u(e)},null,2)}],isError:!0};let n=await x(e.dataDir,e.port),s={wasRunning:n.running,previousPid:n.pid??null};if(n.running){let p=await j(e.dataDir);if(s.stopSignalSent=p,!p)return{content:[{type:"text",text:JSON.stringify({ok:!1,phase:"stop",error:"Could not send stop signal",...s,...await u(e)},null,2)}],isError:!0};let g=await $(e.dataDir,o??5e3);if(s.stopped=g,!g)return{content:[{type:"text",text:JSON.stringify({ok:!1,phase:"stop",error:"Previous daemon did not exit within timeout",...s,...await u(e)},null,2)}],isError:!0}}let i=P(e.entryPath,e.port,e.dataDir);s.spawnedPid=i;let c=await N(e.port,t??15e3);s.ready=c;let a=await u(e);return{content:[{type:"text",text:JSON.stringify({ok:c,phase:c?"ready":"start",...s,...a},null,2)}],isError:!c}}catch(e){return{content:[{type:"text",text:`Error: ${e instanceof Error?e.message:"Unknown error"}`}],isError:!0}}})}function tt(r,o){L(r,o),H(r,o),F(r,o),G(r,o),z(r,o),K(r,o),B(r,o),V(r,o),Y(r)}function et(r,o){r.resource("agents","ohwow://agents",{description:"All OHWOW agents with their descriptions, roles, and available tools"},async()=>{try{let t=await o.get("/api/agents"),e=t.data||t;return{contents:[{uri:"ohwow://agents",mimeType:"application/json",text:JSON.stringify(e,null,2)}]}}catch{return{contents:[{uri:"ohwow://agents",mimeType:"text/plain",text:"Could not load agents. Is the OHWOW daemon running?"}]}}}),r.resource("workspace","ohwow://workspace",{description:"OHWOW workspace status: tier, uptime, agent count, system stats"},async()=>{try{let t=await o.get("/api/dashboard/init");return{contents:[{uri:"ohwow://workspace",mimeType:"application/json",text:JSON.stringify(t,null,2)}]}}catch{return{contents:[{uri:"ohwow://workspace",mimeType:"text/plain",text:"Could not load workspace status. Is the OHWOW daemon running?"}]}}}),r.resource("contacts","ohwow://contacts",{description:"Recent CRM contacts with pipeline stage breakdown"},async()=>{try{let t=await o.get("/api/contacts?limit=10"),e=t.data||t;return{contents:[{uri:"ohwow://contacts",mimeType:"application/json",text:JSON.stringify(e,null,2)}]}}catch{return{contents:[{uri:"ohwow://contacts",mimeType:"text/plain",text:"Could not load contacts. Is the OHWOW daemon running?"}]}}}),r.resource("projects","ohwow://projects",{description:"Active projects with task counts and status"},async()=>{try{let t=await o.get("/api/projects"),e=t.data||t;return{contents:[{uri:"ohwow://projects",mimeType:"application/json",text:JSON.stringify(e,null,2)}]}}catch{return{contents:[{uri:"ohwow://projects",mimeType:"text/plain",text:"Could not load projects. Is the OHWOW daemon running?"}]}}}),r.resource("workflows","ohwow://workflows",{description:"Workflow and automation catalog with descriptions and trigger types"},async()=>{try{let[t,e]=await Promise.all([o.get("/api/workflows"),o.get("/api/automations")]),n=t.data||t,s=e.data||e;return{contents:[{uri:"ohwow://workflows",mimeType:"application/json",text:JSON.stringify({workflows:n,automations:s},null,2)}]}}catch{return{contents:[{uri:"ohwow://workflows",mimeType:"text/plain",text:"Could not load workflows. Is the OHWOW daemon running?"}]}}}),r.resource("capabilities","ohwow://capabilities",{description:"Complete list of all OHWOW MCP tools grouped by domain"},async()=>({contents:[{uri:"ohwow://capabilities",mimeType:"text/plain",text:kt}]}))}var kt=`OHWOW MCP Plugin \u2014 Quick Reference
|
|
9
9
|
|
|
10
10
|
GETTING STARTED
|
|
11
11
|
1. ohwow_workspace_status Check connection and workspace overview
|
|
@@ -57,9 +57,9 @@ CLOUD (instant, requires ohwow.fun)
|
|
|
57
57
|
USE ohwow_chat FOR: desktop control, scheduling, agent state, approvals,
|
|
58
58
|
A2A protocol, PDF forms, media generation, automation creation, and
|
|
59
59
|
anything not listed above.
|
|
60
|
-
`;import{createServer as
|
|
60
|
+
`;import{createServer as St}from"http";import{writeFileSync as _t,unlinkSync as Et,existsSync as bt}from"fs";import{join as Ot}from"path";import{homedir as Rt}from"os";var A=Ot(Rt(),".ohwow","data","mcp-sampling.port");function ot(r){let o=null,t=St(async(n,s)=>{if(n.method!=="POST"||n.url!=="/sampling"){s.writeHead(404),s.end("Not found");return}let i="";for await(let a of n)i+=a;let c;try{c=JSON.parse(i)}catch{s.writeHead(400),s.end(JSON.stringify({error:"Invalid JSON"}));return}if(!c.messages?.length){s.writeHead(400),s.end(JSON.stringify({error:"messages array is required"}));return}try{let a=c.messages.map(m=>({role:m.role,content:{type:"text",text:m.content}})),p=await r.server.createMessage({messages:a,systemPrompt:c.systemPrompt,maxTokens:c.maxTokens||4096,temperature:c.temperature}),f={content:Array.isArray(p.content)?p.content.filter(m=>m.type==="text").map(m=>m.text).join(""):typeof p.content=="object"&&"text"in p.content?p.content.text:String(p.content),model:p.model,stopReason:p.stopReason??void 0};s.writeHead(200,{"Content-Type":"application/json"}),s.end(JSON.stringify(f))}catch(a){let p=a instanceof Error?a.message:"Sampling failed";s.writeHead(500),s.end(JSON.stringify({error:p}))}});return o=t,t.listen(0,"127.0.0.1",()=>{let n=t.address();if(n&&typeof n=="object"){let s=n.port;try{_t(A,String(s)),process.stderr.write(`[ohwow-mcp] Sampling bridge listening on port ${s}
|
|
61
61
|
`)}catch{process.stderr.write(`[ohwow-mcp] Could not write sampling port file
|
|
62
|
-
`)}}}),{cleanup:()=>{o&&(o.close(),o=null);try{
|
|
63
|
-
`),process.exit(1)}let o=new
|
|
64
|
-
`),e=
|
|
65
|
-
`),process.exit(1)}}export{
|
|
62
|
+
`)}}}),{cleanup:()=>{o&&(o.close(),o=null);try{bt(A)&&Et(A)}catch{}}}}import{readFileSync as Dt}from"fs";import{join as Tt}from"path";function vt(){try{let r=Dt(Tt(process.cwd(),"package.json"),"utf-8");return JSON.parse(r).version}catch{return"0.0.0"}}var U=vt();async function ze(){let r;try{r=await k.create()}catch(s){process.stderr.write(`[ohwow-mcp] ${s instanceof Error?s.message:"Unknown error"}
|
|
63
|
+
`),process.exit(1)}let o=new Ct({name:"ohwow",version:U});tt(o,r),et(o,r);let t=new Pt,e=null,n=async()=>{e?.();try{await o.close()}catch{}process.exit(0)};process.on("SIGTERM",n),process.on("SIGINT",n);try{await o.connect(t),process.stderr.write(`[ohwow-mcp] Connected (v${U})
|
|
64
|
+
`),e=ot(o).cleanup}catch(s){process.stderr.write(`[ohwow-mcp] Failed to connect: ${s instanceof Error?s.message:"Unknown error"}
|
|
65
|
+
`),process.exit(1)}}export{ze as startMcpServer};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
-- Add columns for SOP system: trigger matching, usage tracking, and cloud sync.
|
|
2
|
+
-- Uses IF NOT EXISTS pattern to handle partial application safely.
|
|
3
|
+
|
|
4
|
+
-- Skills: trigger matching + usage tracking + sync
|
|
5
|
+
ALTER TABLE agent_workforce_skills ADD COLUMN triggers TEXT DEFAULT '[]';
|
|
6
|
+
ALTER TABLE agent_workforce_skills ADD COLUMN times_used INTEGER DEFAULT 0;
|
|
7
|
+
ALTER TABLE agent_workforce_skills ADD COLUMN success_rate REAL;
|
|
8
|
+
ALTER TABLE agent_workforce_skills ADD COLUMN last_used_at TEXT;
|
|
9
|
+
ALTER TABLE agent_workforce_skills ADD COLUMN locality_policy TEXT DEFAULT 'sync';
|
|
10
|
+
ALTER TABLE agent_workforce_skills ADD COLUMN source_device_id TEXT;
|
|
11
|
+
|
|
12
|
+
-- Discovered processes: trigger matching + auto-execution + sync
|
|
13
|
+
ALTER TABLE agent_workforce_discovered_processes ADD COLUMN trigger_message TEXT;
|
|
14
|
+
ALTER TABLE agent_workforce_discovered_processes ADD COLUMN last_auto_executed_at TEXT;
|
|
15
|
+
ALTER TABLE agent_workforce_discovered_processes ADD COLUMN auto_execute_count INTEGER DEFAULT 0;
|
|
16
|
+
ALTER TABLE agent_workforce_discovered_processes ADD COLUMN updated_at TEXT;
|
|
17
|
+
ALTER TABLE agent_workforce_discovered_processes ADD COLUMN locality_policy TEXT DEFAULT 'sync';
|
|
18
|
+
ALTER TABLE agent_workforce_discovered_processes ADD COLUMN source_device_id TEXT;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
-- Operational Pillars: what a business SHOULD be doing at each stage
|
|
2
|
+
-- Global reference table + per-workspace instance tracking
|
|
3
|
+
|
|
4
|
+
CREATE TABLE IF NOT EXISTS agent_workforce_operational_pillars (
|
|
5
|
+
id TEXT PRIMARY KEY,
|
|
6
|
+
slug TEXT UNIQUE NOT NULL,
|
|
7
|
+
name TEXT NOT NULL,
|
|
8
|
+
description TEXT NOT NULL,
|
|
9
|
+
category TEXT NOT NULL CHECK (category IN (
|
|
10
|
+
'acquisition', 'retention', 'operations', 'finance', 'product', 'team', 'strategy'
|
|
11
|
+
)),
|
|
12
|
+
icon TEXT NOT NULL DEFAULT 'circle',
|
|
13
|
+
business_types TEXT NOT NULL DEFAULT '[]', -- JSON array of business types
|
|
14
|
+
min_stage INTEGER NOT NULL DEFAULT 0,
|
|
15
|
+
max_stage INTEGER NOT NULL DEFAULT 9,
|
|
16
|
+
priority_by_stage TEXT NOT NULL DEFAULT '{}', -- JSON: { "0": "critical", "1": "important" }
|
|
17
|
+
kpis TEXT NOT NULL DEFAULT '[]', -- JSON array
|
|
18
|
+
best_practices TEXT NOT NULL DEFAULT '[]', -- JSON array
|
|
19
|
+
setup_steps TEXT NOT NULL DEFAULT '[]', -- JSON array
|
|
20
|
+
estimated_setup_hours REAL DEFAULT 1,
|
|
21
|
+
prerequisite_pillar_ids TEXT DEFAULT '[]', -- JSON array of IDs
|
|
22
|
+
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
23
|
+
updated_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
24
|
+
);
|
|
25
|
+
|
|
26
|
+
CREATE TABLE IF NOT EXISTS agent_workforce_pillar_instances (
|
|
27
|
+
id TEXT PRIMARY KEY,
|
|
28
|
+
workspace_id TEXT NOT NULL REFERENCES agent_workforce_workspaces(id) ON DELETE CASCADE,
|
|
29
|
+
pillar_id TEXT NOT NULL REFERENCES agent_workforce_operational_pillars(id) ON DELETE CASCADE,
|
|
30
|
+
status TEXT NOT NULL DEFAULT 'not_started' CHECK (status IN (
|
|
31
|
+
'not_started', 'suggested', 'building', 'running', 'optimizing', 'paused', 'dismissed'
|
|
32
|
+
)),
|
|
33
|
+
mode TEXT NOT NULL DEFAULT 'builder' CHECK (mode IN ('builder', 'optimizer')),
|
|
34
|
+
health_score REAL DEFAULT 0 CHECK (health_score >= 0 AND health_score <= 1),
|
|
35
|
+
last_health_check TEXT,
|
|
36
|
+
health_details TEXT DEFAULT '{}',
|
|
37
|
+
agent_ids TEXT DEFAULT '[]',
|
|
38
|
+
automation_ids TEXT DEFAULT '[]',
|
|
39
|
+
schedule_cron TEXT,
|
|
40
|
+
blueprint TEXT DEFAULT NULL,
|
|
41
|
+
blueprint_approved_at TEXT,
|
|
42
|
+
total_tasks_completed INTEGER DEFAULT 0,
|
|
43
|
+
total_cost_cents INTEGER DEFAULT 0,
|
|
44
|
+
estimated_hours_saved REAL DEFAULT 0,
|
|
45
|
+
suggested_at TEXT,
|
|
46
|
+
building_started_at TEXT,
|
|
47
|
+
running_since TEXT,
|
|
48
|
+
last_activity_at TEXT,
|
|
49
|
+
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
50
|
+
updated_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
51
|
+
UNIQUE(workspace_id, pillar_id)
|
|
52
|
+
);
|
|
53
|
+
|
|
54
|
+
CREATE INDEX IF NOT EXISTS idx_pillar_instances_workspace ON agent_workforce_pillar_instances(workspace_id);
|
|
55
|
+
CREATE INDEX IF NOT EXISTS idx_pillar_instances_status ON agent_workforce_pillar_instances(workspace_id, status);
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
-- Seed operational pillars (SQLite version)
|
|
2
|
+
-- Same data as cloud migration 342 but with SQLite-compatible syntax
|
|
3
|
+
|
|
4
|
+
INSERT OR REPLACE INTO agent_workforce_operational_pillars (id, slug, name, description, category, icon, business_types, min_stage, max_stage, priority_by_stage, kpis, setup_steps, estimated_setup_hours) VALUES
|
|
5
|
+
|
|
6
|
+
-- ACQUISITION
|
|
7
|
+
(lower(hex(randomblob(16))), 'content_pipeline', 'Content Pipeline',
|
|
8
|
+
'Systematic content creation and distribution. Blog posts, social media, newsletters, videos. Builds organic discovery and establishes authority in your space.',
|
|
9
|
+
'acquisition', 'pencil-line', '[]', 0, 9,
|
|
10
|
+
'{"0":"important","1":"critical","2":"critical","3":"important","4":"important","5":"recommended","6":"recommended","7":"recommended","8":"critical","9":"recommended"}',
|
|
11
|
+
'[{"name":"Posts published per week","target":2,"unit":"count"},{"name":"Organic traffic growth","target":10,"unit":"percent_monthly"},{"name":"Email subscribers","target":null,"unit":"count"}]',
|
|
12
|
+
'[{"order":1,"title":"Audit existing content and brand voice","description":"Review what content exists, identify gaps, establish tone and style.","agent_role":"Content Strategist"},{"order":2,"title":"Build content calendar","description":"Plan 4 weeks of content across channels, aligned with business goals.","agent_role":"Content Strategist"},{"order":3,"title":"Draft first batch of content","description":"Create 4-6 pieces of content ready for review.","agent_role":"Content Creator"},{"order":4,"title":"Set up distribution channels","description":"Configure social media scheduling, newsletter tool, and cross-posting.","agent_role":"Social Media Manager"},{"order":5,"title":"Launch and measure","description":"Publish first batch, set up analytics tracking, establish baseline metrics.","agent_role":"Content Strategist"}]',
|
|
13
|
+
3),
|
|
14
|
+
|
|
15
|
+
(lower(hex(randomblob(16))), 'outbound_outreach', 'Outbound Outreach',
|
|
16
|
+
'Proactive outreach to potential customers. Cold email, DMs, partnerships, community engagement. Direct path to first customers and rapid feedback.',
|
|
17
|
+
'acquisition', 'send', '[]', 0, 6,
|
|
18
|
+
'{"0":"critical","1":"critical","2":"important","3":"recommended","4":"recommended","5":"recommended","6":"nice_to_have"}',
|
|
19
|
+
'[{"name":"Outreach messages sent per week","target":50,"unit":"count"},{"name":"Reply rate","target":15,"unit":"percent"},{"name":"Conversations started","target":10,"unit":"count_weekly"}]',
|
|
20
|
+
'[{"order":1,"title":"Define ideal customer profile","description":"Who exactly are you reaching out to? What pain do they have?","agent_role":"Sales Strategist"},{"order":2,"title":"Build prospect list","description":"Research and compile list of 200+ prospects from relevant communities, directories, and social platforms.","agent_role":"Lead Researcher"},{"order":3,"title":"Craft outreach sequences","description":"Write personalized message templates for 3 different angles. Test which resonates.","agent_role":"Outreach Specialist"},{"order":4,"title":"Launch first campaign","description":"Send first batch of 50 messages. Track replies, iterate on messaging.","agent_role":"Outreach Specialist"}]',
|
|
21
|
+
2),
|
|
22
|
+
|
|
23
|
+
(lower(hex(randomblob(16))), 'community_building', 'Community Building',
|
|
24
|
+
'Build and nurture a community around your product or niche. Discord, forum, social groups. Creates organic word-of-mouth and deep customer relationships.',
|
|
25
|
+
'acquisition', 'users', '[]', 1, 9,
|
|
26
|
+
'{"1":"recommended","2":"important","3":"important","4":"important","5":"critical","6":"important","7":"important","8":"critical","9":"important"}',
|
|
27
|
+
'[{"name":"Active community members","target":null,"unit":"count"},{"name":"Weekly engagement rate","target":20,"unit":"percent"},{"name":"Community-sourced leads","target":null,"unit":"count_monthly"}]',
|
|
28
|
+
'[{"order":1,"title":"Choose platform and structure","description":"Discord, GitHub Discussions, or forum. Define channels/categories for your audience.","agent_role":"Community Manager"},{"order":2,"title":"Seed with initial content","description":"Create 10+ discussion starters, resources, and guides.","agent_role":"Community Manager"},{"order":3,"title":"Invite first members","description":"Personal invites to existing users, supporters, and relevant contacts.","agent_role":"Outreach Specialist"},{"order":4,"title":"Establish engagement rhythm","description":"Weekly discussions, AMAs, showcases. Build habits.","agent_role":"Community Manager"}]',
|
|
29
|
+
4),
|
|
30
|
+
|
|
31
|
+
(lower(hex(randomblob(16))), 'paid_acquisition', 'Paid Acquisition',
|
|
32
|
+
'Paid advertising and sponsorships. Google Ads, social ads, newsletter sponsorships, influencer partnerships. Scalable customer acquisition with measurable ROI.',
|
|
33
|
+
'acquisition', 'currency-dollar', '["saas_startup","ecommerce","b2b_enterprise_saas","education_edtech"]', 2, 9,
|
|
34
|
+
'{"2":"recommended","3":"important","4":"critical","5":"critical","6":"important","7":"important","8":"important","9":"recommended"}',
|
|
35
|
+
'[{"name":"Customer acquisition cost","target":null,"unit":"dollars"},{"name":"Return on ad spend","target":3,"unit":"ratio"},{"name":"Paid leads per week","target":null,"unit":"count"}]',
|
|
36
|
+
'[{"order":1,"title":"Define unit economics","description":"Know your LTV, target CAC, and breakeven timeline before spending.","agent_role":"Financial Analyst"},{"order":2,"title":"Choose initial channel","description":"Pick ONE paid channel based on where your customers are. Start small.","agent_role":"Ad Strategist"},{"order":3,"title":"Create ad assets","description":"Write copy, design creatives, build landing pages for first campaign.","agent_role":"Ad Copywriter"},{"order":4,"title":"Launch and iterate","description":"Start with $20-50/day budget. Measure, optimize, scale what works.","agent_role":"Ad Strategist"}]',
|
|
37
|
+
2),
|
|
38
|
+
|
|
39
|
+
(lower(hex(randomblob(16))), 'partnership_channel', 'Partnerships and Referrals',
|
|
40
|
+
'Structured partnerships, affiliate programs, and referral systems. Leverage other people''s audiences and networks for scalable, trust-based growth.',
|
|
41
|
+
'acquisition', 'handshake', '[]', 2, 9,
|
|
42
|
+
'{"2":"nice_to_have","3":"recommended","4":"important","5":"critical","6":"critical","7":"important","8":"important","9":"important"}',
|
|
43
|
+
'[{"name":"Active partners","target":null,"unit":"count"},{"name":"Partner-sourced revenue","target":null,"unit":"dollars_monthly"},{"name":"Referral conversion rate","target":20,"unit":"percent"}]',
|
|
44
|
+
'[]', 3),
|
|
45
|
+
|
|
46
|
+
(lower(hex(randomblob(16))), 'seo_optimization', 'SEO and Organic Search',
|
|
47
|
+
'Search engine optimization for long-term organic discovery. Keyword research, on-page optimization, link building.',
|
|
48
|
+
'acquisition', 'search', '["saas_startup","ecommerce","agency","content_creator","service_business","consulting","education_edtech","b2b_enterprise_saas"]', 1, 9,
|
|
49
|
+
'{"1":"recommended","2":"important","3":"important","4":"critical","5":"critical","6":"important","7":"recommended","8":"important","9":"recommended"}',
|
|
50
|
+
'[{"name":"Organic search traffic","target":null,"unit":"visits_monthly"},{"name":"Keywords ranking top 10","target":null,"unit":"count"}]',
|
|
51
|
+
'[]', 2),
|
|
52
|
+
|
|
53
|
+
-- RETENTION
|
|
54
|
+
(lower(hex(randomblob(16))), 'user_onboarding', 'User Onboarding',
|
|
55
|
+
'Structured onboarding that gets new users to their first success moment. Emails, in-app guides, tutorials.',
|
|
56
|
+
'retention', 'door-open', '["saas_startup","ecommerce","tech_company","education_edtech","b2b_enterprise_saas"]', 0, 9,
|
|
57
|
+
'{"0":"important","1":"critical","2":"critical","3":"important","4":"important","5":"important"}',
|
|
58
|
+
'[{"name":"Activation rate","target":40,"unit":"percent"},{"name":"Time to first value","target":null,"unit":"minutes"}]',
|
|
59
|
+
'[]', 3),
|
|
60
|
+
|
|
61
|
+
(lower(hex(randomblob(16))), 'customer_feedback', 'Customer Feedback Loops',
|
|
62
|
+
'Systematic collection and analysis of customer feedback. NPS, surveys, interviews, support tickets.',
|
|
63
|
+
'retention', 'message-circle', '[]', 0, 9,
|
|
64
|
+
'{"0":"critical","1":"critical","2":"important","3":"important","4":"important"}',
|
|
65
|
+
'[{"name":"NPS score","target":40,"unit":"score"},{"name":"Feedback responses per month","target":null,"unit":"count"}]',
|
|
66
|
+
'[]', 2),
|
|
67
|
+
|
|
68
|
+
(lower(hex(randomblob(16))), 'customer_support', 'Customer Support',
|
|
69
|
+
'Responsive support system. Help docs, chatbot, ticket management, escalation paths.',
|
|
70
|
+
'retention', 'life-buoy', '["saas_startup","ecommerce","tech_company","service_business","b2b_enterprise_saas","healthcare_wellness"]', 1, 9,
|
|
71
|
+
'{"1":"recommended","2":"important","3":"critical","4":"critical","5":"critical"}',
|
|
72
|
+
'[{"name":"First response time","target":4,"unit":"hours"},{"name":"Resolution rate","target":90,"unit":"percent"}]',
|
|
73
|
+
'[]', 2),
|
|
74
|
+
|
|
75
|
+
(lower(hex(randomblob(16))), 'customer_success', 'Customer Success',
|
|
76
|
+
'Proactive relationship management with existing customers. Check-ins, usage monitoring, expansion opportunities.',
|
|
77
|
+
'retention', 'heart-handshake', '["saas_startup","agency","consulting","service_business","b2b_enterprise_saas"]', 3, 9,
|
|
78
|
+
'{"3":"recommended","4":"important","5":"critical","6":"critical","7":"important"}',
|
|
79
|
+
'[{"name":"Net revenue retention","target":110,"unit":"percent"},{"name":"Churn rate","target":5,"unit":"percent_monthly"}]',
|
|
80
|
+
'[]', 3),
|
|
81
|
+
|
|
82
|
+
-- OPERATIONS
|
|
83
|
+
(lower(hex(randomblob(16))), 'process_documentation', 'Process Documentation (SOPs)',
|
|
84
|
+
'Document how things work. Standard operating procedures for recurring tasks.',
|
|
85
|
+
'operations', 'file-text', '[]', 3, 9,
|
|
86
|
+
'{"3":"critical","4":"important","5":"important","6":"critical","7":"critical"}',
|
|
87
|
+
'[{"name":"Documented processes","target":null,"unit":"count"}]',
|
|
88
|
+
'[]', 4),
|
|
89
|
+
|
|
90
|
+
(lower(hex(randomblob(16))), 'reporting_analytics', 'Reporting and Analytics',
|
|
91
|
+
'Know your numbers. Dashboards, weekly reports, KPI tracking.',
|
|
92
|
+
'operations', 'chart-bar', '[]', 0, 9,
|
|
93
|
+
'{"0":"recommended","1":"important","2":"critical","3":"critical","4":"critical"}',
|
|
94
|
+
'[{"name":"Metrics tracked","target":null,"unit":"count"},{"name":"Report delivery consistency","target":100,"unit":"percent_weekly"}]',
|
|
95
|
+
'[]', 2),
|
|
96
|
+
|
|
97
|
+
(lower(hex(randomblob(16))), 'automation_workflows', 'Workflow Automation',
|
|
98
|
+
'Automate repetitive tasks. Scheduled jobs, triggered actions. Every manual step eliminated is time reclaimed forever.',
|
|
99
|
+
'operations', 'workflow', '[]', 2, 9,
|
|
100
|
+
'{"2":"recommended","3":"critical","4":"critical","5":"important","6":"critical"}',
|
|
101
|
+
'[{"name":"Automated workflows running","target":null,"unit":"count"},{"name":"Hours saved per week","target":null,"unit":"hours"}]',
|
|
102
|
+
'[]', 2),
|
|
103
|
+
|
|
104
|
+
-- FINANCE
|
|
105
|
+
(lower(hex(randomblob(16))), 'pricing_strategy', 'Pricing Strategy',
|
|
106
|
+
'Intentional pricing that reflects value and supports growth.',
|
|
107
|
+
'finance', 'tag', '[]', 1, 9,
|
|
108
|
+
'{"1":"critical","2":"important","3":"important","4":"critical","5":"important","6":"critical"}',
|
|
109
|
+
'[{"name":"Revenue per customer","target":null,"unit":"dollars"}]',
|
|
110
|
+
'[]', 2),
|
|
111
|
+
|
|
112
|
+
(lower(hex(randomblob(16))), 'financial_tracking', 'Financial Tracking',
|
|
113
|
+
'Know where your money goes and comes from. Revenue tracking, expense management, runway calculation.',
|
|
114
|
+
'finance', 'wallet', '[]', 1, 9,
|
|
115
|
+
'{"1":"recommended","2":"important","3":"critical","4":"critical","5":"critical","6":"critical","7":"critical"}',
|
|
116
|
+
'[{"name":"Monthly burn rate known","target":null,"unit":"boolean"},{"name":"Runway months","target":null,"unit":"months"}]',
|
|
117
|
+
'[]', 2),
|
|
118
|
+
|
|
119
|
+
(lower(hex(randomblob(16))), 'fundraise_readiness', 'Fundraise Readiness',
|
|
120
|
+
'Passive preparation for fundraising or exit. Data room, metrics history, narrative.',
|
|
121
|
+
'finance', 'briefcase', '["saas_startup","tech_company","b2b_enterprise_saas","education_edtech"]', 2, 9,
|
|
122
|
+
'{"2":"nice_to_have","3":"nice_to_have","4":"recommended","5":"important","6":"important","7":"critical","8":"critical","9":"critical"}',
|
|
123
|
+
'[{"name":"Data room completeness","target":100,"unit":"percent"}]',
|
|
124
|
+
'[]', 2),
|
|
125
|
+
|
|
126
|
+
-- PRODUCT
|
|
127
|
+
(lower(hex(randomblob(16))), 'product_analytics', 'Product Analytics',
|
|
128
|
+
'Understand how people actually use your product. Feature adoption, user flows, drop-off points.',
|
|
129
|
+
'product', 'chart-line', '["saas_startup","ecommerce","tech_company","education_edtech","b2b_enterprise_saas"]', 0, 9,
|
|
130
|
+
'{"0":"important","1":"critical","2":"critical","3":"important","4":"critical"}',
|
|
131
|
+
'[{"name":"Weekly active users","target":null,"unit":"count"},{"name":"Feature adoption rate","target":null,"unit":"percent"}]',
|
|
132
|
+
'[]', 2),
|
|
133
|
+
|
|
134
|
+
(lower(hex(randomblob(16))), 'competitive_intel', 'Competitive Intelligence',
|
|
135
|
+
'Know what your competitors are doing. Product changes, pricing moves, marketing campaigns.',
|
|
136
|
+
'strategy', 'binoculars', '[]', 0, 9,
|
|
137
|
+
'{"0":"recommended","1":"important","2":"important","3":"recommended","4":"important","5":"important","8":"critical"}',
|
|
138
|
+
'[{"name":"Competitors tracked","target":null,"unit":"count"},{"name":"Intel reports delivered","target":1,"unit":"count_weekly"}]',
|
|
139
|
+
'[]', 2),
|
|
140
|
+
|
|
141
|
+
(lower(hex(randomblob(16))), 'uptime_monitoring', 'Uptime and Performance Monitoring',
|
|
142
|
+
'Know when things break before your customers tell you. Uptime checks, performance monitoring, alerting.',
|
|
143
|
+
'product', 'activity', '["saas_startup","ecommerce","tech_company","b2b_enterprise_saas"]', 0, 9,
|
|
144
|
+
'{"0":"important","1":"critical","2":"critical","3":"critical","4":"important"}',
|
|
145
|
+
'[{"name":"Uptime percentage","target":99.9,"unit":"percent"},{"name":"Mean time to detection","target":5,"unit":"minutes"}]',
|
|
146
|
+
'[]', 1),
|
|
147
|
+
|
|
148
|
+
-- TEAM
|
|
149
|
+
(lower(hex(randomblob(16))), 'hiring_pipeline', 'Hiring Pipeline',
|
|
150
|
+
'Structured approach to finding and onboarding new team members.',
|
|
151
|
+
'team', 'user-plus', '[]', 3, 9,
|
|
152
|
+
'{"3":"recommended","4":"recommended","5":"important","6":"important","7":"critical","8":"critical"}',
|
|
153
|
+
'[{"name":"Open positions filled","target":null,"unit":"count"},{"name":"Time to hire","target":30,"unit":"days"}]',
|
|
154
|
+
'[]', 4),
|
|
155
|
+
|
|
156
|
+
(lower(hex(randomblob(16))), 'delegation_system', 'Delegation System',
|
|
157
|
+
'Structured delegation of founder/leader decisions to team members and agents.',
|
|
158
|
+
'team', 'git-branch', '[]', 3, 9,
|
|
159
|
+
'{"3":"critical","4":"critical","5":"important","6":"important","7":"critical"}',
|
|
160
|
+
'[{"name":"Decisions requiring founder","target":null,"unit":"count_weekly"}]',
|
|
161
|
+
'[]', 3),
|
|
162
|
+
|
|
163
|
+
-- STRATEGY
|
|
164
|
+
(lower(hex(randomblob(16))), 'positioning', 'Market Positioning',
|
|
165
|
+
'Clear articulation of who you are, who you serve, and why you''re different.',
|
|
166
|
+
'strategy', 'target', '[]', 0, 9,
|
|
167
|
+
'{"0":"critical","1":"critical","2":"important","3":"recommended","4":"critical","5":"important","8":"critical"}',
|
|
168
|
+
'[{"name":"Positioning statement exists","target":null,"unit":"boolean"}]',
|
|
169
|
+
'[]', 2),
|
|
170
|
+
|
|
171
|
+
(lower(hex(randomblob(16))), 'customer_research', 'Customer Research',
|
|
172
|
+
'Deep understanding of your customers beyond surface demographics. Jobs-to-be-done, pain points, buying triggers.',
|
|
173
|
+
'strategy', 'microscope', '[]', 0, 9,
|
|
174
|
+
'{"0":"critical","1":"critical","2":"important","3":"recommended","4":"critical"}',
|
|
175
|
+
'[{"name":"Customer interviews this month","target":4,"unit":"count"},{"name":"Personas documented","target":null,"unit":"count"}]',
|
|
176
|
+
'[]', 2);
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
-- Person Models: deep understanding of each human in the workspace
|
|
2
|
+
|
|
3
|
+
CREATE TABLE IF NOT EXISTS agent_workforce_person_models (
|
|
4
|
+
id TEXT PRIMARY KEY,
|
|
5
|
+
workspace_id TEXT NOT NULL REFERENCES agent_workforce_workspaces(id) ON DELETE CASCADE,
|
|
6
|
+
team_member_id TEXT REFERENCES team_members(id) ON DELETE SET NULL,
|
|
7
|
+
name TEXT NOT NULL,
|
|
8
|
+
email TEXT,
|
|
9
|
+
avatar_url TEXT,
|
|
10
|
+
role_title TEXT,
|
|
11
|
+
variant TEXT NOT NULL DEFAULT 'team_member' CHECK (variant IN ('founder', 'team_member', 'new_hire')),
|
|
12
|
+
work_history TEXT DEFAULT '[]',
|
|
13
|
+
skills_map TEXT DEFAULT '{}',
|
|
14
|
+
domain_expertise TEXT DEFAULT '{}',
|
|
15
|
+
blind_spots TEXT DEFAULT '[]',
|
|
16
|
+
tool_proficiency TEXT DEFAULT '{}',
|
|
17
|
+
communication_style TEXT DEFAULT '{}',
|
|
18
|
+
energy_patterns TEXT DEFAULT '{}',
|
|
19
|
+
learning_style TEXT,
|
|
20
|
+
collaboration_preferences TEXT DEFAULT '{}',
|
|
21
|
+
ambitions TEXT DEFAULT '{}',
|
|
22
|
+
values_and_motivations TEXT DEFAULT '[]',
|
|
23
|
+
friction_points TEXT DEFAULT '[]',
|
|
24
|
+
flow_triggers TEXT DEFAULT '[]',
|
|
25
|
+
skill_gaps_to_close TEXT DEFAULT '[]',
|
|
26
|
+
external_context TEXT DEFAULT '{}',
|
|
27
|
+
growth_arc TEXT DEFAULT '{}',
|
|
28
|
+
growth_velocity REAL DEFAULT 0,
|
|
29
|
+
growth_direction TEXT DEFAULT 'ascending' CHECK (growth_direction IN ('ascending', 'plateau', 'declining', 'transforming')),
|
|
30
|
+
growth_snapshots TEXT DEFAULT '[]',
|
|
31
|
+
ingestion_status TEXT DEFAULT 'not_started' CHECK (ingestion_status IN ('not_started', 'in_progress', 'initial_complete', 'mature')),
|
|
32
|
+
ingestion_variant TEXT,
|
|
33
|
+
last_ingestion_at TEXT,
|
|
34
|
+
observation_count INTEGER DEFAULT 0,
|
|
35
|
+
refinement_count INTEGER DEFAULT 0,
|
|
36
|
+
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
37
|
+
updated_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
38
|
+
);
|
|
39
|
+
|
|
40
|
+
CREATE TABLE IF NOT EXISTS agent_workforce_person_observations (
|
|
41
|
+
id TEXT PRIMARY KEY,
|
|
42
|
+
person_model_id TEXT NOT NULL REFERENCES agent_workforce_person_models(id) ON DELETE CASCADE,
|
|
43
|
+
workspace_id TEXT NOT NULL REFERENCES agent_workforce_workspaces(id) ON DELETE CASCADE,
|
|
44
|
+
dimension TEXT NOT NULL,
|
|
45
|
+
observation_type TEXT NOT NULL CHECK (observation_type IN (
|
|
46
|
+
'task_outcome', 'communication', 'feedback', 'self_report', 'behavioral', 'peer_observation', 'correction'
|
|
47
|
+
)),
|
|
48
|
+
content TEXT NOT NULL,
|
|
49
|
+
data TEXT DEFAULT '{}',
|
|
50
|
+
confidence REAL DEFAULT 0.5 CHECK (confidence >= 0 AND confidence <= 1),
|
|
51
|
+
processed INTEGER DEFAULT 0,
|
|
52
|
+
source_type TEXT,
|
|
53
|
+
source_id TEXT,
|
|
54
|
+
created_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
CREATE INDEX IF NOT EXISTS idx_person_models_workspace ON agent_workforce_person_models(workspace_id);
|
|
58
|
+
CREATE INDEX IF NOT EXISTS idx_person_observations_model ON agent_workforce_person_observations(person_model_id);
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
-- Transition Engine: task patterns + task transitions (SQLite)
|
|
2
|
+
|
|
3
|
+
CREATE TABLE IF NOT EXISTS task_patterns (
|
|
4
|
+
id TEXT PRIMARY KEY,
|
|
5
|
+
workspace_id TEXT NOT NULL,
|
|
6
|
+
person_model_id TEXT,
|
|
7
|
+
name TEXT NOT NULL,
|
|
8
|
+
description TEXT,
|
|
9
|
+
category TEXT NOT NULL DEFAULT 'general' CHECK (category IN (
|
|
10
|
+
'email', 'content', 'research', 'data', 'social',
|
|
11
|
+
'scheduling', 'crm', 'support', 'ops', 'general'
|
|
12
|
+
)),
|
|
13
|
+
detection_method TEXT NOT NULL DEFAULT 'auto_detected' CHECK (detection_method IN ('manual', 'auto_detected', 'pillar_derived')),
|
|
14
|
+
frequency TEXT CHECK (frequency IN ('daily', 'weekly', 'biweekly', 'monthly', 'irregular')),
|
|
15
|
+
avg_human_duration_minutes INTEGER,
|
|
16
|
+
avg_agent_duration_minutes INTEGER,
|
|
17
|
+
title_keywords TEXT DEFAULT '[]',
|
|
18
|
+
tool_fingerprint TEXT DEFAULT '[]',
|
|
19
|
+
department_id TEXT,
|
|
20
|
+
preferred_agent_id TEXT,
|
|
21
|
+
instance_count INTEGER DEFAULT 0,
|
|
22
|
+
first_observed_at TEXT DEFAULT (datetime('now')),
|
|
23
|
+
last_observed_at TEXT DEFAULT (datetime('now')),
|
|
24
|
+
archived_at TEXT,
|
|
25
|
+
created_at TEXT DEFAULT (datetime('now')),
|
|
26
|
+
updated_at TEXT DEFAULT (datetime('now'))
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
CREATE TABLE IF NOT EXISTS task_transitions (
|
|
30
|
+
id TEXT PRIMARY KEY,
|
|
31
|
+
workspace_id TEXT NOT NULL,
|
|
32
|
+
pattern_id TEXT NOT NULL,
|
|
33
|
+
person_model_id TEXT,
|
|
34
|
+
current_stage INTEGER NOT NULL DEFAULT 1 CHECK (current_stage BETWEEN 1 AND 5),
|
|
35
|
+
stage_history TEXT DEFAULT '[]',
|
|
36
|
+
confidence_score REAL DEFAULT 0.0,
|
|
37
|
+
correction_count INTEGER DEFAULT 0,
|
|
38
|
+
total_instances INTEGER DEFAULT 0,
|
|
39
|
+
successful_instances INTEGER DEFAULT 0,
|
|
40
|
+
human_edit_rate REAL DEFAULT 1.0,
|
|
41
|
+
last_promoted_at TEXT,
|
|
42
|
+
last_demoted_at TEXT,
|
|
43
|
+
time_saved_minutes INTEGER DEFAULT 0,
|
|
44
|
+
active INTEGER NOT NULL DEFAULT 1,
|
|
45
|
+
created_at TEXT DEFAULT (datetime('now')),
|
|
46
|
+
updated_at TEXT DEFAULT (datetime('now'))
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
CREATE INDEX IF NOT EXISTS idx_task_patterns_workspace ON task_patterns(workspace_id);
|
|
50
|
+
CREATE INDEX IF NOT EXISTS idx_task_patterns_person ON task_patterns(workspace_id, person_model_id);
|
|
51
|
+
CREATE INDEX IF NOT EXISTS idx_task_transitions_pattern ON task_transitions(pattern_id);
|
|
52
|
+
CREATE INDEX IF NOT EXISTS idx_task_transitions_workspace ON task_transitions(workspace_id);
|