@cotal-ai/connector-hermes 0.133.4 → 0.133.5
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/docs-bundle.bin
CHANGED
|
Binary file
|
package/dist/docs-index.bin
CHANGED
|
Binary file
|
package/dist/launch.js
CHANGED
|
@@ -125,7 +125,7 @@ ${blocks.join("\n")}
|
|
|
125
125
|
${lines.join("\n")}`}channelInfo(channel){const cfg=this.ep.getChannelConfig(channel);return{description:cfg?.description,instructions:cfg?.instructions,replay:this.ep.channelReplay(channel),registered:cfg!==void 0,event:this.eventChannelOf(channel)}}eventChannelOf(channel){const principal=eventChannelPrincipal(channel);if(!principal)return void 0;const own=this.ep.principal;return principal.owner===own.owner&&principal.actor===own.actor?"own":"agent"}joinedChannels(){return this.ep.joinedChannels()}async listChannels(){const mine=this.ep.joinedChannels();const pending=this.ep.pendingDurableLeaves();const unclosed=new Set(pending);let leaseLive=false;let leaseReadable=false;let daemonMemberships;try{leaseLive=(await this.ep.readDeliveryLease(0))?.ready===true;leaseReadable=true}catch{}if(leaseReadable){try{daemonMemberships=await this.ep.fetchMemberships()}catch{daemonMemberships=void 0;leaseReadable=false}}const health=(channel,joined)=>joined&&this.ep.channelDeliveryClass(channel)==="durable"?!leaseReadable?"unknown":daemonMemberships===void 0?"degraded":daemonMemberships.some(m=>m.channel===channel)&&leaseLive?"active":"degraded":void 0;const rows=(await this.ep.listChannels()).map(c=>{const joined=mine.some(p=>subjectMatches(p,c.channel));return{channel:c.channel,description:c.config?.description,replay:this.ep.channelReplay(c.channel),joined,durableUnclosed:unclosed.has(c.channel),deliveryHealth:health(c.channel,joined),messages:c.messages,mode:this.channelMode(c.channel)??"normal",event:this.eventChannelOf(c.channel)}});const present=new Set(rows.map(r=>r.channel));for(const ch of pending){if(present.has(ch))continue;rows.push({channel:ch,description:void 0,replay:this.ep.channelReplay(ch),joined:false,durableUnclosed:true,deliveryHealth:void 0,messages:0,mode:this.channelMode(ch)??"normal",event:this.eventChannelOf(ch)})}return rows}async joinChannel(channel){await this.requireConnected();return this.ep.joinChannel(channel)}async leaveChannel(channel){await this.requireConnected();return this.ep.leaveChannel(channel)}async requireConnected(){return this.whenConnected(CONNECT_GRACE_MS)}async whenConnected(timeoutMs=CONNECT_GRACE_MS){if(this._connected)return;if(!await this.awaitConnection(timeoutMs))throw new Error(this.notConnectedMessage())}awaitConnection(timeoutMs){return new Promise(resolve3=>{let settled=false;const finish=ok3=>{if(settled)return;settled=true;clearTimeout(timer);this.ep.off("connection",onConnection);resolve3(ok3)};const onConnection=e=>{if(e.connected)finish(true)};const timer=setTimeout(()=>finish(false),Math.max(1,timeoutMs));this.ep.on("connection",onConnection);if(this._connected)finish(true)})}notConnectedMessage(){const issue2=this.connectionIssue;if(issue2)return`not connected to the mesh at ${this.config.servers}: ${issue2}`;const remedy=isLocalServer(this.config.servers)?"is it running? (`cotal up`)":"it did not become reachable \u2014 check that the mesh is up and that this machine can reach it.";return`not connected to the mesh at ${this.config.servers} \u2014 ${remedy}`}handleEndpointError(error51){if(!this._connected&&!this._stopping)this.lastConnectionError=error51.message;this.logEndpointNotice("error",error51)}handleEndpointWarning(error51){this.logEndpointNotice("warning",error51)}logEndpointNotice(kind,error51){const now=Date.now();const fingerprint=error51.message.replace(/oc_[A-Za-z0-9]+_\d+/g,"oc_*");const prior=this.endpointNoticeLog.get(fingerprint);if(prior&&now-prior.lastLoggedAt<ENDPOINT_ERROR_LOG_WINDOW_MS){prior.suppressed++;return}const suffix=prior?.suppressed?` (${prior.suppressed} repeats suppressed)`:"";this.endpointNoticeLog.set(fingerprint,{lastLoggedAt:now,suppressed:0});if(this.endpointNoticeLog.size>MAX_ENDPOINT_NOTICES)this.endpointNoticeLog.delete(this.endpointNoticeLog.keys().next().value);this.log(`endpoint ${kind}: ${error51.message}${suffix}`)}log(msg){process.stderr.write(`[cotal-connector] ${msg}
|
|
126
126
|
`)}};function presenceReadCondition(failure){return`the presence read failed (${failure.message})`}function closeChannelNames(channel,known){const out=[];for(const name of known){if(name!==channel&&editDistanceAtMostOne(channel,name))out.push(name)}out.sort((a,b)=>a.localeCompare(b));return out.slice(0,3)}function editDistanceAtMostOne(a,b){if(a===b)return true;const da=a.length-b.length;if(da>1||da<-1)return false;let i=0;let j=0;let skipped=false;while(i<a.length&&j<b.length){if(a[i]===b[j]){i++;j++;continue}if(skipped)return false;skipped=true;if(a.length>b.length)i++;else if(b.length>a.length)j++;else{i++;j++}}return true}import{tmpdir as tmpdir2}from"node:os";import{join as join4}from"node:path";import{createHash as createHash7,randomBytes as randomBytes3}from"node:crypto";var SUN_PATH_MAX_BYTES=process.platform==="darwin"?104:108;function controlEndpoint(space2,name,token2=randomBytes3(32).toString("base64url")){const id2=createHash7("sha256").update(`${space2}\0${name}\0${process.pid}\0${token2}`).digest("base64url").slice(0,32);const path=process.platform==="win32"?`\\\\.\\pipe\\cotal-${id2}`:join4(tmpdir2(),`cotal-${id2}.sock`);const bytes=Buffer.byteLength(path);if(process.platform!=="win32"&&bytes>SUN_PATH_MAX_BYTES){const tail=`/cotal-${id2}.sock`.length;throw new Error(`control socket path is ${bytes} bytes, over the ${SUN_PATH_MAX_BYTES}-byte sun_path limit on ${process.platform}, so it cannot be bound and the kernel would report only EINVAL: ${path}. The socket name is a fixed ${tail} bytes, so the temp root must be at most ${SUN_PATH_MAX_BYTES-tail} bytes \u2014 TMPDIR is ${Buffer.byteLength(tmpdir2())} bytes (${tmpdir2()}). Point TMPDIR at a shorter directory.`)}return{path,token:token2}}var TRUNCATABLE_FIELDS=[{type:AGUI_EVENT_TYPE.TOOL_CALL_ARGS,field:"delta"},{type:AGUI_EVENT_TYPE.TOOL_CALL_RESULT,field:"content"},{type:AGUI_EVENT_TYPE.TEXT_MESSAGE_CONTENT,field:"delta"}];var EGRESS_FORBIDDEN_TYPES=new Set([AGUI_EVENT_TYPE.TOOL_CALL_ARGS,AGUI_EVENT_TYPE.TOOL_CALL_RESULT]);var KNOWN_EVENT_KEYS_BY_TYPE=new Map([[AGUI_EVENT_TYPE.RUN_STARTED,new Set(["type","timestamp","rawEvent","threadId","runId","parentRunId","input","cotal"])],[AGUI_EVENT_TYPE.RUN_FINISHED,new Set(["type","timestamp","rawEvent","threadId","runId","result","outcome","cotal"])],[AGUI_EVENT_TYPE.RUN_ERROR,new Set(["type","timestamp","rawEvent","message","code","cotal"])],[AGUI_EVENT_TYPE.TEXT_MESSAGE_START,new Set(["type","timestamp","rawEvent","messageId","role","name","cotal"])],[AGUI_EVENT_TYPE.TEXT_MESSAGE_CONTENT,new Set(["type","timestamp","rawEvent","messageId","delta","cotal"])],[AGUI_EVENT_TYPE.TEXT_MESSAGE_END,new Set(["type","timestamp","rawEvent","messageId","cotal"])],[AGUI_EVENT_TYPE.TOOL_CALL_START,new Set(["type","timestamp","rawEvent","toolCallId","toolCallName","parentMessageId","cotal"])],[AGUI_EVENT_TYPE.TOOL_CALL_ARGS,new Set(["type","timestamp","rawEvent","toolCallId","delta","cotal"])],[AGUI_EVENT_TYPE.TOOL_CALL_END,new Set(["type","timestamp","rawEvent","toolCallId","cotal"])],[AGUI_EVENT_TYPE.TOOL_CALL_RESULT,new Set(["type","timestamp","rawEvent","messageId","toolCallId","content","role","cotal"])],[AGUI_EVENT_TYPE.REASONING_MESSAGE_START,new Set(["type","timestamp","rawEvent","messageId","role","cotal"])],[AGUI_EVENT_TYPE.REASONING_MESSAGE_CONTENT,new Set(["type","timestamp","rawEvent","messageId","delta","cotal"])],[AGUI_EVENT_TYPE.REASONING_MESSAGE_END,new Set(["type","timestamp","rawEvent","messageId","cotal"])],[AGUI_EVENT_TYPE.CUSTOM,new Set(["type","timestamp","rawEvent","name","value","cotal"])]]);var SIZING_ID="S".repeat(64);var SIZING_EXPECTATION=Number.MAX_SAFE_INTEGER;var str=v=>typeof v==="string"?v:void 0;var CONT=" \xB7 ";var TEXT_PREFIX="\xBB ";var THINK_PREFIX="(thinking) ";var TOOL_PREFIX="\u2699 ";var RESULT_PREFIX=" \u21B3 ";var BLOCK_START_CHARS=new Set([..."#>|`~=_*+-[<0123456789"," "]);function renderEvents(events){const lines=[];const text2=new Map;const reasoning=new Map;const toolName=new Map;const toolArgs=new Map;const emit=(first,cont,body)=>{const[head,...rest]=body.split("\n");lines.push(first+head);for(const l of rest)lines.push(cont+l)};const flush=(map2,id2,first,cont,suffix="")=>{const acc=map2.get(id2);if(acc!==void 0&&acc.length>0)emit(first,cont,acc+suffix);map2.delete(id2)};for(const e of events){const type=typeof e==="object"&&e!==null?str(e.type):void 0;switch(type){case AGUI_EVENT_TYPE.RUN_STARTED:emit("\u25B8 ",CONT,`run ${str(e.runId)??"?"} started`);break;case AGUI_EVENT_TYPE.RUN_FINISHED:{const outcome=str(e.outcome?.type);emit("\u25C2 ",CONT,`run ${str(e.runId)??"?"} finished${outcome?` (${outcome})`:""}`);break}case AGUI_EVENT_TYPE.RUN_ERROR:{const code=str(e.code);emit("\u2717 ",CONT,`run error${code?` [${code}]`:""}: ${str(e.message)??"(no message)"}`);break}case AGUI_EVENT_TYPE.TEXT_MESSAGE_START:text2.set(str(e.messageId)??"","");break;case AGUI_EVENT_TYPE.TEXT_MESSAGE_CONTENT:{const id2=str(e.messageId)??"";text2.set(id2,(text2.get(id2)??"")+(str(e.delta)??""));break}case AGUI_EVENT_TYPE.TEXT_MESSAGE_END:flush(text2,str(e.messageId)??"",TEXT_PREFIX,TEXT_PREFIX);break;case AGUI_EVENT_TYPE.REASONING_MESSAGE_START:reasoning.set(str(e.messageId)??"","");break;case AGUI_EVENT_TYPE.REASONING_MESSAGE_CONTENT:{const id2=str(e.messageId)??"";reasoning.set(id2,(reasoning.get(id2)??"")+(str(e.delta)??""));break}case AGUI_EVENT_TYPE.REASONING_MESSAGE_END:flush(reasoning,str(e.messageId)??"",THINK_PREFIX,CONT);break;case AGUI_EVENT_TYPE.TOOL_CALL_START:{const id2=str(e.toolCallId)??"";toolName.set(id2,str(e.toolCallName)??"?");toolArgs.set(id2,"");break}case AGUI_EVENT_TYPE.TOOL_CALL_ARGS:{const id2=str(e.toolCallId)??"";toolArgs.set(id2,(toolArgs.get(id2)??"")+(str(e.delta)??""));break}case AGUI_EVENT_TYPE.TOOL_CALL_END:{const id2=str(e.toolCallId)??"";emit(TOOL_PREFIX,CONT,`${toolName.get(id2)??"?"}(${toolArgs.get(id2)??""})`);toolName.delete(id2);toolArgs.delete(id2);break}case AGUI_EVENT_TYPE.TOOL_CALL_RESULT:emit(RESULT_PREFIX,CONT,str(e.content)??"(no content)");break;case AGUI_EVENT_TYPE.CUSTOM:emit("\u2022 ",CONT,`custom ${str(e.name)??"(unnamed)"}`);break;default:emit("\u2022 ",CONT,`unrecognised event ${JSON.stringify(type??null)}`)}}for(const id2 of[...text2.keys()])flush(text2,id2,TEXT_PREFIX,TEXT_PREFIX," \u2026");for(const id2 of[...reasoning.keys()])flush(reasoning,id2,THINK_PREFIX,CONT," \u2026");for(const id2 of[...toolName.keys()])emit(TOOL_PREFIX,CONT,`${toolName.get(id2)??"?"}(${toolArgs.get(id2)??""}) \u2026`);return lines}var aguiFramePartRenderer=Object.freeze({kind:"part-renderer",name:AGUI_FRAME_KIND,render(part){if(!isAguiFramePart(part))return`[not an AG-UI frame]`;const events=part.events;if(!Array.isArray(events)||events.length===0)return`[AG-UI frame carrying no events]`;const lines=renderEvents(events);return lines.length>0?lines.join("\n"):`[AG-UI frame with ${events.length} event(s) and nothing to show]`}});function registerAguiFramePartRenderer(){if(registry2.has("part-renderer",AGUI_FRAME_KIND))return;registry2.register(aguiFramePartRenderer)}registerAguiFramePartRenderer();import{connect as connect2,createServer}from"node:net";import{lstatSync as lstatSync4,unlinkSync as unlinkSync3}from"node:fs";import{createHash as createHash8,timingSafeEqual}from"node:crypto";var HANDOFF_DEADLINE_MS=5e3;var LEGACY_WRITE_DEADLINE_MS=5e3;var MAX_FRAME_BYTES=1<<20;var AUTH_DEADLINE_MS=5e3;function tokenMatches(presented,digest){if(typeof presented!=="string")return false;return timingSafeEqual(createHash8("sha256").update(presented).digest(),digest)}function writeReply(sock,reply,awaitHandoff){return new Promise(resolve3=>{let settled=false;const done=ok3=>{if(settled)return;settled=true;resolve3(ok3)};sock.once("error",()=>done(false));sock.once("close",()=>done(false));if(!awaitHandoff){const stall=setTimeout(()=>done(false),LEGACY_WRITE_DEADLINE_MS);stall.unref?.();try{sock.end(JSON.stringify(reply)+"\n",(err3=>{clearTimeout(stall);done(!err3)}))}catch{clearTimeout(stall);done(false)}return}const deadline=setTimeout(()=>{sock.destroy();done(false)},HANDOFF_DEADLINE_MS);deadline.unref?.();let receipt="";sock.on("data",d=>{receipt+=d;if(!receipt.includes("\n"))return;clearTimeout(deadline);try{sock.end()}catch{}done(true)});try{sock.write(JSON.stringify(reply)+"\n",err3=>{if(!err3)return;clearTimeout(deadline);done(false)})}catch{clearTimeout(deadline);done(false)}})}function startControlServer(agent,endpoint,handle,opts={}){const{path}=endpoint;const digest=createHash8("sha256").update(endpoint.token).digest();const server=createServer(sock=>{let buf="";let handled=false;sock.setEncoding("utf8");const deadline=setTimeout(()=>sock.destroy(),AUTH_DEADLINE_MS);deadline.unref?.();sock.on("close",()=>clearTimeout(deadline));sock.on("data",async d=>{if(handled)return;buf+=d;if(buf.length>MAX_FRAME_BYTES){sock.destroy();return}const nl=buf.indexOf("\n");if(nl<0)return;handled=true;clearTimeout(deadline);let frame={};try{frame=JSON.parse(buf.slice(0,nl)||"{}")}catch{}if(!tokenMatches(frame.token,digest)){sock.destroy();return}const op=frame.op;if(op==="shutdown"){try{sock.end(JSON.stringify({ok:true})+"\n")}catch{}opts.onShutdown?.();return}if(op==="session"){const sessionId=opts.onSession?.();try{sock.end(JSON.stringify(sessionId?{ok:true,sessionId}:{ok:false,error:"session not ready"})+"\n")}catch{}return}const ev=frame.event??{};const awaitHandoff=frame.handoff===true;const reply=await handle(agent,ev);const delivered=await writeReply(sock,reply,awaitHandoff);opts.onReply?.(ev,delivered)});sock.on("error",()=>{})});let bound=false;let retried=false;const emit=server.emit.bind(server);server.emit=(event,...args)=>{const error51=args[0];if(event!=="error"||bound||retried||process.platform==="win32"||path.startsWith("\0")||error51?.code!=="EADDRINUSE")return emit(event,...args);retried=true;let original;try{original=lstatSync4(path);if(!original.isSocket())return emit(event,...args)}catch(e){if(e.code!=="ENOENT")return emit(event,...args)}const probe=connect2(path);let settled=false;const finish=stale=>{if(settled)return;settled=true;clearTimeout(deadline);probe.destroy();server.off("close",cancel);if(!stale){emit(event,...args);return}try{const current=lstatSync4(path);if(!original||!current.isSocket()||current.dev!==original.dev||current.ino!==original.ino){emit(event,...args);return}unlinkSync3(path)}catch(e){if(e.code!=="ENOENT"){emit("error",e);return}}server.listen(path)};const cancel=()=>{settled=true;clearTimeout(deadline);probe.destroy()};const deadline=setTimeout(()=>finish(false),250);server.once("close",cancel);probe.once("connect",()=>finish(false));probe.once("error",e=>finish(e.code==="ECONNREFUSED"||e.code==="ENOENT"));return true};server.on("error",e=>{process.stderr.write(`[cotal-connector] control server error: ${e.message}
|
|
127
127
|
`);if(opts.fatalBind&&!bound)process.exit(1)});server.listen(path,()=>{bound=true;process.stderr.write(`[cotal-connector] control socket: ${path}
|
|
128
|
-
`)});return server}var ok=text2=>({text:text2});var err=text2=>({text:text2,isError:true});async function submitFeedback(input,options={}){const url2=options.url??(options.key?FEEDBACK_URL:PUBLIC_FEEDBACK_URL);const headers3={"content-type":"application/json"};const body={...input};if(options.key){headers3.authorization=`Bearer ${options.key}`}else{if(!options.email)return err("Keyless feedback goes to the public cotal.ai intake, which requires a traceable contact email \u2014 ask the user for one and retry with the email argument (or set COTAL_FEEDBACK_EMAIL).");body.email=options.email}try{const res=await fetch(url2,{method:"POST",headers:headers3,body:JSON.stringify(body)});const raw=await res.text();let reply={};if(raw)try{reply=JSON.parse(raw)}catch{reply={error:raw}}if(!res.ok)return err(`Feedback rejected (${res.status}${reply.error?`: ${reply.error}`:""}).`);const note=reply.published===false?" (stored, but the internal feedback channel publish failed)":"";return ok(`Feedback sent${reply.id?` (id ${reply.id})`:""}${note}. Thanks!`)}catch(e){return err(`Couldn't reach the feedback intake at ${url2}: ${e.message}`)}}import{execFileSync as execFileSync3}from"node:child_process";init_external();init_external();import{createHash as createHash9}from"node:crypto";import{readFileSync as readFileSync5}from"node:fs";import{join as join5}from"node:path";import{gunzipSync}from"node:zlib";var DOCS_VERSION="0.133.4";function loadDocsMetadata(){return{"version":"0.133.4","pages":[{"slug":"what-is-cotal","title":"What is Cotal","kind":"Start here (informative)","category":"Start here","summary":"Cotal is an open pub/sub standard for AI agents and software services to work together."},{"slug":"getting-started","title":"Quickstart","kind":"Start here (informative)","category":"Start here","summary":"Paste this into any coding agent (Claude Code, OpenCode, Cursor, Codex) and it will do the whole page for you:"},{"slug":"architecture","title":"Architecture","kind":"Concept (informative)","category":"Concept","summary":"Cotal is built as a thin waist: the normative wire contract (subjects, message schemas, presence/discovery, delivery semantics, the auth grammar) is the standard (SPEC), and everything else is a pl\u2026"},{"slug":"mcp-tools","title":"MCP tool catalog","kind":"Reference: the `cotal_*` tool surface every connected agent gets.","category":"Reference","summary":"The tools are defined once, platform-neutrally, in @cotal-ai/connector-core and rendered onto each host's native tool API (an MCP server for Claude Code, Codex and Jcode, native plugin tools for Op\u2026"},{"slug":"channels-and-permissions","title":"Channel permissions","kind":"Reference (informative task card)","category":"Reference","summary":"Channel permissions decide who can read, who can post, and what each agent tunes into at boot."},{"slug":"identity-and-auth","title":"Identity","kind":"Concept (informative)","category":"Concept","summary":"Who can do what on a mesh, and how it is enforced."},{"slug":"agent-files","title":"Agent files","kind":"Reference (the persisted form of an agent's identity + persona, read by every launcher)","category":"Reference","summary":"An agent's identity and persona live in one Markdown file instead of being passed flag-by-flag, the same shape Claude Code uses for subagents:"},{"slug":"api-reference","title":"API reference","kind":"Reference (informative)","category":"Reference","summary":"Cotal exposes a wire protocol, TypeScript libraries, CLI commands and agent tools."},{"slug":"auth-api","title":"Auth HTTP API","kind":"Reference (informative)","category":"Reference","summary":"HTTP interface of the stock auth public listener: 11 paths and 12 operations."},{"slug":"authoring-a-connector","title":"Authoring a connector","kind":"Reference: describes the TypeScript reference implementation, not the wire contract.","category":"Reference","summary":"A connector teaches Cotal how to launch one agent harness (Claude Code, OpenCode, your own) as a mesh node."},{"slug":"build-a-client","title":"Build a Cotal client","kind":"Guide (informative)","category":"Guide","summary":"This page is the reading order for implementing a Cotal client in another language (Go, Python, Rust, or anything with a NATS client library) against the spec, without reimplementing the protocol."},{"slug":"cli","title":"`cotal` CLI reference","kind":"Reference: describes the TypeScript reference implementation (the `cotal` CLI), not the wire contract.","category":"Reference","summary":"cotal is the operator command line for the reference implementation: bring a mesh up, mint identities, launch agents, watch what they do, and tear it all down."},{"slug":"config","title":"Configuration","kind":"Reference: describes the TypeScript reference implementation (the `cotal` CLI and connectors), not the wire contract.","category":"Reference","summary":"Four things configure a Cotal workstation: the config file (per-connector settings, notably which of your MCP servers get shared with spawned agents), your preferences (the defaults your own comman\u2026"},{"slug":"connect-claude","title":"Connect Claude","kind":"Guide (informative)","category":"Guide","summary":"The Claude Code connector turns a real claude session into a Cotal mesh peer."},{"slug":"connect-codex","title":"Connect Codex (beta)","kind":"Guide (informative)","category":"Guide","summary":"OpenAI Codex joins a Cotal mesh as a lateral peer: the same cotal tool surface, the same message delivery and attention model as the other connectors, plus mid-turn steering: a directed peer messag\u2026"},{"slug":"connect-hermes","title":"Connect Hermes (alpha)","kind":"Guide (informative)","category":"Guide","summary":"Hermes (Nous Research) joins a Cotal mesh as a lateral peer, with the same shared cotal tool surface and delivery model as the other connectors."},{"slug":"connect-jcode","title":"Connect Jcode (beta)","kind":"Guide (informative)","category":"Guide","summary":"Jcode joins a Cotal mesh as a lateral peer."},{"slug":"connect-opencode","title":"Connect OpenCode (beta)","kind":"Guide (informative)","category":"Guide","summary":"OpenCode joins a Cotal mesh as a lateral peer, at parity with Claude Code: the same cotal tool surface, the same message delivery and attention model."},{"slug":"connect-pi","title":"Connect pi (alpha)","kind":"Guide (informative)","category":"Guide","summary":"@cotal-ai/pi is Cotal's first host-native framework adapter."},{"slug":"connectors","title":"Connectors","kind":"Guide (informative)","category":"Guide","summary":"Every connector puts a real agent session on the mesh with the same cotal tools, presence, and delivery model (MCP tools)."},{"slug":"control-surface","title":"The control surface","kind":"Concept (informative)","category":"Concept","summary":"Cotal once had a privileged control rail: a fixed set of named service tiers (self / manager / admin / delivery) on their own ctl."},{"slug":"dashboard-api","title":"Dashboard HTTP API","kind":"Reference (informative)","category":"Reference","summary":"HTTP interface of the @cotal-ai/web reference implementation."},{"slug":"define-a-team","title":"Define a team","kind":"Guide (informative)","category":"Guide","summary":"The Quickstart gives you one agent. To run a specific team (your own channels, your own agents, and the channel access for each agent), describe it once in a cotal.yaml and launch it with a single\u2026"},{"slug":"delivery-daemon","title":"The delivery daemon (Plane-3)","kind":"Concept (informative)","category":"Concept","summary":"Live channel delivery is at-most-once: a message reaches only the peers subscribed at the moment it is published (SPEC \xA74)."},{"slug":"deploy","title":"Deploying agent teams","kind":"Guide (informative)","category":"Guide","summary":"The deploy/ tree runs a team of agents in an isolated container that dials out to an existing Cotal broker."},{"slug":"embedding","title":"Embedding Cotal","kind":"Guide (informative)","category":"Guide","summary":"The cotal binary in this repo is one composition root: an operator CLI."},{"slug":"examples","title":"Examples","kind":"Guide (informative)","category":"Guide","summary":"Examples live in examples/, one self-contained folder each."},{"slug":"glossary","title":"Glossary","kind":"Reference (informative)","category":"Reference","summary":"One-line definitions of the terms used across these docs and the spec."},{"slug":"lang-card","title":"The cotal-lang card","kind":"Reference (informative)","category":"Reference","summary":"One page to write a correct workflow program."},{"slug":"manifest","title":"Mesh manifest (`cotal.yaml`)","kind":"Reference: every field of the mesh manifest.","category":"Reference","summary":"A manifest (cotal.yaml, kind: Mesh) describes a whole team (its channels, its agents, and who may read and post where) in one file."},{"slug":"mesh-view","title":"MeshView","kind":"Reference: TypeScript observer surfaces (`MeshView`)","category":"Reference","summary":"MeshView is the CLI's shared model for the terminal console and its plain stream."},{"slug":"presence-and-delivery","title":"Message flow","kind":"Concept (informative)","category":"Concept","summary":"How peers see each other and how messages reach them: the presence directory, the three delivery modes, and the two delivery guarantees."},{"slug":"release","title":"Publishing a release","kind":"Project (non-normative maintainer notes)","category":"Project","summary":"Cotal uses pnpm, Changesets and one GitHub Actions workflow."},{"slug":"roadmap","title":"Roadmap","kind":"Project (non-normative)","category":"Project","summary":"Cotal is pre-1.0. The wire contract (v0.x) may still change under the change process. This page tracks what is deliberately not built yet, and the direction each area is headed."},{"slug":"run-a-mesh","title":"Run a mesh","kind":"Guide (informative)","category":"Guide","summary":"Day-to-day operation of a local mesh: what cotal up actually runs, how spawning resolves personas, harnesses, and models, how to reach a mesh from any directory, and the operator-only maintenance v\u2026"},{"slug":"security","title":"Security model","kind":"Concept (informative threat model)","category":"Concept","summary":"Cotal v0 provides containment and sender authenticity for peers sharing one trusted NATS broker."},{"slug":"setup-internals","title":"Setup internals (maintainer notes)","kind":"Project (non-normative maintainer notes)","category":"Project","summary":"cotal setup (implementations/cli/src/commands/setup.ts) saves configuration by default: it checks prerequisites, sets up the chosen application and runtimes, and seeds persona files."},{"slug":"spaces","title":"Spaces","kind":"Concept (informative)","category":"Concept","summary":"The space concept, and why it is distinct from a channel."},{"slug":"stability","title":"Substrate stability","kind":"Project (informative)","category":"Project","summary":"Cotal's packages are pre-1.0 and publish in lockstep."},{"slug":"telemetry","title":"Telemetry","kind":"Reference","category":"Reference","summary":"The cotal CLI sends usage data about commands, failures and platforms."},{"slug":"transport","title":"Transport vs protocol","kind":"Concept (informative)","category":"Concept","summary":"What in Cotal is the protocol, what is the transport, and what a transport binding must provide."},{"slug":"upgrading","title":"Upgrading a running deployment","kind":"Guide (informative)","category":"Guide","summary":"Substrate stability tells you what the version numbers promise."},{"slug":"using-cotal","title":"Choose a workflow","kind":"Guide (informative)","category":"Guide","summary":"Cotal can run a local team, connect a session to a shared space, or expose a service to agents."},{"slug":"watch-a-mesh","title":"Watch a mesh","kind":"Guide (informative)","category":"Guide","summary":"Cotal's watch surfaces show who is present, their reported activity and the messages your credential permits you to read."},{"slug":"workflows","title":"Workflow runs","kind":"Concept (informative)","category":"Concept","summary":"A workflow run is a program that coordinates agents over hours or days and survives the process that started it."}],"spec":{"title":"Cotal Wire Specification"},"lang":{"title":"Cotal Lang: the workflow language"},"schema":{"title":"Cotal message schema (JSON Schema)"}}}function loadDocsBundle(){const packed=readFileSync5(join5(import.meta.dirname,"docs-bundle.bin"));if(packed.length!==979447||createHash9("sha256").update(packed).digest("hex")!=="ad4619c7c6e5969a579604aa58faf2f4d37293b0c39fd0e32c67cf782fedb429")throw new Error("docs data file docs-bundle.bin beside this module is not the one built with it");return JSON.parse(gunzipSync(packed).toString("utf8"))}function loadDocsIndex(){const packed=readFileSync5(join5(import.meta.dirname,"docs-index.bin"));if(packed.length!==437017||createHash9("sha256").update(packed).digest("hex")!=="72627bb737a5846329508321ecfa613eb649107b301714518ad830e9be3e17f2")throw new Error("docs data file docs-index.bin beside this module is not the one built with it");return gunzipSync(packed)}var TOKEN=/[a-z0-9_$.#>*-]+/gi;var EDGE=/^[.>*#-]+|[.>*#-]+$/g;function tokenize(s){const raw=s.toLowerCase().match(TOKEN);if(!raw)return[];const out=[];for(const r of raw){if(r.length>=2)out.push(r);const t=r.replace(EDGE,"");if(t.length>=2&&t!==r)out.push(t);if(t.includes(".")){for(const seg of t.split("."))if(seg.length>=2)out.push(seg)}}return out}var STOP=new Set("a an and are as at be by do for from has how in is it of on or that the this to use using was what when where which who with you your".split(" "));function decodeIndex(bytes,bodyLengths,version2){if(bytes.length<4)throw new Error("docs index is truncated or malformed");const headerLength=bytes.readUInt32LE(0);if(4+headerLength>bytes.length)throw new Error("docs index is truncated or malformed");const header=JSON.parse(bytes.toString("utf8",4,4+headerLength));if(header.version!==version2||header.bodyLengths.length!==bodyLengths.length||header.bodyLengths.some((length2,i)=>length2!==bodyLengths[i]))throw new Error("docs index does not match the docs bundle it is searching");const n=header.sections;const length=4*n+header.terms.length+1+2*header.postings;if(bytes.length-4-headerLength!==4*length)throw new Error("docs index is truncated or malformed");const columns=new Uint32Array(length);for(let i=0;i<length;i++)columns[i]=bytes.readUInt32LE(4+headerLength+4*i);const offsets=4*n;const sectionColumn=offsets+header.terms.length+1;let total=0;for(let i=0;i<n;i++)total+=columns[3*n+i];return{sections:n,terms:header.terms,headings:header.headings,source:columns.subarray(0,n),start:columns.subarray(n,2*n),end:columns.subarray(2*n,3*n),length:columns.subarray(3*n,4*n),offsets:columns.subarray(offsets,sectionColumn),postSection:columns.subarray(sectionColumn,sectionColumn+header.postings),postWeight:columns.subarray(sectionColumn+header.postings),avgdl:total/Math.max(1,n)}}var indexed;function metadata(){return indexed??=loadDocsMetadata()}var bundled;function bundle(){return bundled??=loadDocsBundle()}var REMOTE_BASE="https://docs.cotal.ai";function resolvePage(page){const key=page.trim().toLowerCase().replace(/\.md$/,"");if(key==="spec")return{slug:"spec",title:bundle().spec.title,kind:"normative",category:"normative",summary:"",body:bundle().spec.body};if(key==="lang"||key==="cotal-lang")return{slug:"lang",title:bundle().lang.title,kind:"normative",category:"normative",summary:"",body:bundle().lang.body};if(key==="schema")return{slug:"schema",title:bundle().schema.title,kind:"reference",category:"reference",summary:"",body:bundle().schema.body};return bundle().pages.find(p=>p.slug===key)}function remoteUrl(slug){const base=`${REMOTE_BASE}/v/${bundle().version}`;if(slug==="schema")return`${base}/cotal.schema.json`;if(slug==="lang")return`${base}/cotal-lang.md`;return`${base}/${slug}.md`}function renderDocsIndex(){const b=metadata();const rows=b.pages.map(p=>{const kind=p.kind?`: ${p.kind}`:"";return`- \`${p.slug}\`${kind}
|
|
128
|
+
`)});return server}var ok=text2=>({text:text2});var err=text2=>({text:text2,isError:true});async function submitFeedback(input,options={}){const url2=options.url??(options.key?FEEDBACK_URL:PUBLIC_FEEDBACK_URL);const headers3={"content-type":"application/json"};const body={...input};if(options.key){headers3.authorization=`Bearer ${options.key}`}else{if(!options.email)return err("Keyless feedback goes to the public cotal.ai intake, which requires a traceable contact email \u2014 ask the user for one and retry with the email argument (or set COTAL_FEEDBACK_EMAIL).");body.email=options.email}try{const res=await fetch(url2,{method:"POST",headers:headers3,body:JSON.stringify(body)});const raw=await res.text();let reply={};if(raw)try{reply=JSON.parse(raw)}catch{reply={error:raw}}if(!res.ok)return err(`Feedback rejected (${res.status}${reply.error?`: ${reply.error}`:""}).`);const note=reply.published===false?" (stored, but the internal feedback channel publish failed)":"";return ok(`Feedback sent${reply.id?` (id ${reply.id})`:""}${note}. Thanks!`)}catch(e){return err(`Couldn't reach the feedback intake at ${url2}: ${e.message}`)}}import{execFileSync as execFileSync3}from"node:child_process";init_external();init_external();import{createHash as createHash9}from"node:crypto";import{readFileSync as readFileSync5}from"node:fs";import{join as join5}from"node:path";import{gunzipSync}from"node:zlib";var DOCS_VERSION="0.133.5";function loadDocsMetadata(){return{"version":"0.133.5","pages":[{"slug":"what-is-cotal","title":"What is Cotal","kind":"Start here (informative)","category":"Start here","summary":"Cotal is an open pub/sub standard for AI agents and software services to work together."},{"slug":"getting-started","title":"Quickstart","kind":"Start here (informative)","category":"Start here","summary":"Paste this into any coding agent (Claude Code, OpenCode, Cursor, Codex) and it will do the whole page for you:"},{"slug":"architecture","title":"Architecture","kind":"Concept (informative)","category":"Concept","summary":"Cotal is built as a thin waist: the normative wire contract (subjects, message schemas, presence/discovery, delivery semantics, the auth grammar) is the standard (SPEC), and everything else is a pl\u2026"},{"slug":"mcp-tools","title":"MCP tool catalog","kind":"Reference: the `cotal_*` tool surface every connected agent gets.","category":"Reference","summary":"The tools are defined once, platform-neutrally, in @cotal-ai/connector-core and rendered onto each host's native tool API (an MCP server for Claude Code, Codex and Jcode, native plugin tools for Op\u2026"},{"slug":"channels-and-permissions","title":"Channel permissions","kind":"Reference (informative task card)","category":"Reference","summary":"Channel permissions decide who can read, who can post, and what each agent tunes into at boot."},{"slug":"identity-and-auth","title":"Identity","kind":"Concept (informative)","category":"Concept","summary":"Who can do what on a mesh, and how it is enforced."},{"slug":"agent-files","title":"Agent files","kind":"Reference (the persisted form of an agent's identity + persona, read by every launcher)","category":"Reference","summary":"An agent's identity and persona live in one Markdown file instead of being passed flag-by-flag, the same shape Claude Code uses for subagents:"},{"slug":"api-reference","title":"API reference","kind":"Reference (informative)","category":"Reference","summary":"Cotal exposes a wire protocol, TypeScript libraries, CLI commands and agent tools."},{"slug":"auth-api","title":"Auth HTTP API","kind":"Reference (informative)","category":"Reference","summary":"HTTP interface of the stock auth public listener: 11 paths and 12 operations."},{"slug":"authoring-a-connector","title":"Authoring a connector","kind":"Reference: describes the TypeScript reference implementation, not the wire contract.","category":"Reference","summary":"A connector teaches Cotal how to launch one agent harness (Claude Code, OpenCode, your own) as a mesh node."},{"slug":"build-a-client","title":"Build a Cotal client","kind":"Guide (informative)","category":"Guide","summary":"This page is the reading order for implementing a Cotal client in another language (Go, Python, Rust, or anything with a NATS client library) against the spec, without reimplementing the protocol."},{"slug":"cli","title":"`cotal` CLI reference","kind":"Reference: describes the TypeScript reference implementation (the `cotal` CLI), not the wire contract.","category":"Reference","summary":"cotal is the operator command line for the reference implementation: bring a mesh up, mint identities, launch agents, watch what they do, and tear it all down."},{"slug":"config","title":"Configuration","kind":"Reference: describes the TypeScript reference implementation (the `cotal` CLI and connectors), not the wire contract.","category":"Reference","summary":"Four things configure a Cotal workstation: the config file (per-connector settings, notably which of your MCP servers get shared with spawned agents), your preferences (the defaults your own comman\u2026"},{"slug":"connect-claude","title":"Connect Claude","kind":"Guide (informative)","category":"Guide","summary":"The Claude Code connector turns a real claude session into a Cotal mesh peer."},{"slug":"connect-codex","title":"Connect Codex (beta)","kind":"Guide (informative)","category":"Guide","summary":"OpenAI Codex joins a Cotal mesh as a lateral peer: the same cotal tool surface, the same message delivery and attention model as the other connectors, plus mid-turn steering: a directed peer messag\u2026"},{"slug":"connect-hermes","title":"Connect Hermes (alpha)","kind":"Guide (informative)","category":"Guide","summary":"Hermes (Nous Research) joins a Cotal mesh as a lateral peer, with the same shared cotal tool surface and delivery model as the other connectors."},{"slug":"connect-jcode","title":"Connect Jcode (beta)","kind":"Guide (informative)","category":"Guide","summary":"Jcode joins a Cotal mesh as a lateral peer."},{"slug":"connect-opencode","title":"Connect OpenCode (beta)","kind":"Guide (informative)","category":"Guide","summary":"OpenCode joins a Cotal mesh as a lateral peer, at parity with Claude Code: the same cotal tool surface, the same message delivery and attention model."},{"slug":"connect-pi","title":"Connect pi (alpha)","kind":"Guide (informative)","category":"Guide","summary":"@cotal-ai/pi is Cotal's first host-native framework adapter."},{"slug":"connectors","title":"Connectors","kind":"Guide (informative)","category":"Guide","summary":"Every connector puts a real agent session on the mesh with the same cotal tools, presence, and delivery model (MCP tools)."},{"slug":"control-surface","title":"The control surface","kind":"Concept (informative)","category":"Concept","summary":"Cotal once had a privileged control rail: a fixed set of named service tiers (self / manager / admin / delivery) on their own ctl."},{"slug":"dashboard-api","title":"Dashboard HTTP API","kind":"Reference (informative)","category":"Reference","summary":"HTTP interface of the @cotal-ai/web reference implementation."},{"slug":"define-a-team","title":"Define a team","kind":"Guide (informative)","category":"Guide","summary":"The Quickstart gives you one agent. To run a specific team (your own channels, your own agents, and the channel access for each agent), describe it once in a cotal.yaml and launch it with a single\u2026"},{"slug":"delivery-daemon","title":"The delivery daemon (Plane-3)","kind":"Concept (informative)","category":"Concept","summary":"Live channel delivery is at-most-once: a message reaches only the peers subscribed at the moment it is published (SPEC \xA74)."},{"slug":"deploy","title":"Deploying agent teams","kind":"Guide (informative)","category":"Guide","summary":"The deploy/ tree runs a team of agents in an isolated container that dials out to an existing Cotal broker."},{"slug":"embedding","title":"Embedding Cotal","kind":"Guide (informative)","category":"Guide","summary":"The cotal binary in this repo is one composition root: an operator CLI."},{"slug":"examples","title":"Examples","kind":"Guide (informative)","category":"Guide","summary":"Examples live in examples/, one self-contained folder each."},{"slug":"glossary","title":"Glossary","kind":"Reference (informative)","category":"Reference","summary":"One-line definitions of the terms used across these docs and the spec."},{"slug":"lang-card","title":"The cotal-lang card","kind":"Reference (informative)","category":"Reference","summary":"One page to write a correct workflow program."},{"slug":"manifest","title":"Mesh manifest (`cotal.yaml`)","kind":"Reference: every field of the mesh manifest.","category":"Reference","summary":"A manifest (cotal.yaml, kind: Mesh) describes a whole team (its channels, its agents, and who may read and post where) in one file."},{"slug":"mesh-view","title":"MeshView","kind":"Reference: TypeScript observer surfaces (`MeshView`)","category":"Reference","summary":"MeshView is the CLI's shared model for the terminal console and its plain stream."},{"slug":"presence-and-delivery","title":"Message flow","kind":"Concept (informative)","category":"Concept","summary":"How peers see each other and how messages reach them: the presence directory, the three delivery modes, and the two delivery guarantees."},{"slug":"release","title":"Publishing a release","kind":"Project (non-normative maintainer notes)","category":"Project","summary":"Cotal uses pnpm, Changesets and one GitHub Actions workflow."},{"slug":"roadmap","title":"Roadmap","kind":"Project (non-normative)","category":"Project","summary":"Cotal is pre-1.0. The wire contract (v0.x) may still change under the change process. This page tracks what is deliberately not built yet, and the direction each area is headed."},{"slug":"run-a-mesh","title":"Run a mesh","kind":"Guide (informative)","category":"Guide","summary":"Day-to-day operation of a local mesh: what cotal up actually runs, how spawning resolves personas, harnesses, and models, how to reach a mesh from any directory, and the operator-only maintenance v\u2026"},{"slug":"security","title":"Security model","kind":"Concept (informative threat model)","category":"Concept","summary":"Cotal v0 provides containment and sender authenticity for peers sharing one trusted NATS broker."},{"slug":"setup-internals","title":"Setup internals (maintainer notes)","kind":"Project (non-normative maintainer notes)","category":"Project","summary":"cotal setup (implementations/cli/src/commands/setup.ts) saves configuration by default: it checks prerequisites, sets up the chosen application and runtimes, and seeds persona files."},{"slug":"spaces","title":"Spaces","kind":"Concept (informative)","category":"Concept","summary":"The space concept, and why it is distinct from a channel."},{"slug":"stability","title":"Substrate stability","kind":"Project (informative)","category":"Project","summary":"Cotal's packages are pre-1.0 and publish in lockstep."},{"slug":"telemetry","title":"Telemetry","kind":"Reference","category":"Reference","summary":"The cotal CLI sends usage data about commands, failures and platforms."},{"slug":"transport","title":"Transport vs protocol","kind":"Concept (informative)","category":"Concept","summary":"What in Cotal is the protocol, what is the transport, and what a transport binding must provide."},{"slug":"upgrading","title":"Upgrading a running deployment","kind":"Guide (informative)","category":"Guide","summary":"Substrate stability tells you what the version numbers promise."},{"slug":"using-cotal","title":"Choose a workflow","kind":"Guide (informative)","category":"Guide","summary":"Cotal can run a local team, connect a session to a shared space, or expose a service to agents."},{"slug":"watch-a-mesh","title":"Watch a mesh","kind":"Guide (informative)","category":"Guide","summary":"Cotal's watch surfaces show who is present, their reported activity and the messages your credential permits you to read."},{"slug":"workflows","title":"Workflow runs","kind":"Concept (informative)","category":"Concept","summary":"A workflow run is a program that coordinates agents over hours or days and survives the process that started it."}],"spec":{"title":"Cotal Wire Specification"},"lang":{"title":"Cotal Lang: the workflow language"},"schema":{"title":"Cotal message schema (JSON Schema)"}}}function loadDocsBundle(){const packed=readFileSync5(join5(import.meta.dirname,"docs-bundle.bin"));if(packed.length!==979447||createHash9("sha256").update(packed).digest("hex")!=="b742b1751f319892081418ffcb408df4253452953992ebe98f7bebed9796288f")throw new Error("docs data file docs-bundle.bin beside this module is not the one built with it");return JSON.parse(gunzipSync(packed).toString("utf8"))}function loadDocsIndex(){const packed=readFileSync5(join5(import.meta.dirname,"docs-index.bin"));if(packed.length!==437017||createHash9("sha256").update(packed).digest("hex")!=="9e814f93b292f5af1c4fee1ce09abbbebb6e80f19dc912987020f20e8129dfe3")throw new Error("docs data file docs-index.bin beside this module is not the one built with it");return gunzipSync(packed)}var TOKEN=/[a-z0-9_$.#>*-]+/gi;var EDGE=/^[.>*#-]+|[.>*#-]+$/g;function tokenize(s){const raw=s.toLowerCase().match(TOKEN);if(!raw)return[];const out=[];for(const r of raw){if(r.length>=2)out.push(r);const t=r.replace(EDGE,"");if(t.length>=2&&t!==r)out.push(t);if(t.includes(".")){for(const seg of t.split("."))if(seg.length>=2)out.push(seg)}}return out}var STOP=new Set("a an and are as at be by do for from has how in is it of on or that the this to use using was what when where which who with you your".split(" "));function decodeIndex(bytes,bodyLengths,version2){if(bytes.length<4)throw new Error("docs index is truncated or malformed");const headerLength=bytes.readUInt32LE(0);if(4+headerLength>bytes.length)throw new Error("docs index is truncated or malformed");const header=JSON.parse(bytes.toString("utf8",4,4+headerLength));if(header.version!==version2||header.bodyLengths.length!==bodyLengths.length||header.bodyLengths.some((length2,i)=>length2!==bodyLengths[i]))throw new Error("docs index does not match the docs bundle it is searching");const n=header.sections;const length=4*n+header.terms.length+1+2*header.postings;if(bytes.length-4-headerLength!==4*length)throw new Error("docs index is truncated or malformed");const columns=new Uint32Array(length);for(let i=0;i<length;i++)columns[i]=bytes.readUInt32LE(4+headerLength+4*i);const offsets=4*n;const sectionColumn=offsets+header.terms.length+1;let total=0;for(let i=0;i<n;i++)total+=columns[3*n+i];return{sections:n,terms:header.terms,headings:header.headings,source:columns.subarray(0,n),start:columns.subarray(n,2*n),end:columns.subarray(2*n,3*n),length:columns.subarray(3*n,4*n),offsets:columns.subarray(offsets,sectionColumn),postSection:columns.subarray(sectionColumn,sectionColumn+header.postings),postWeight:columns.subarray(sectionColumn+header.postings),avgdl:total/Math.max(1,n)}}var indexed;function metadata(){return indexed??=loadDocsMetadata()}var bundled;function bundle(){return bundled??=loadDocsBundle()}var REMOTE_BASE="https://docs.cotal.ai";function resolvePage(page){const key=page.trim().toLowerCase().replace(/\.md$/,"");if(key==="spec")return{slug:"spec",title:bundle().spec.title,kind:"normative",category:"normative",summary:"",body:bundle().spec.body};if(key==="lang"||key==="cotal-lang")return{slug:"lang",title:bundle().lang.title,kind:"normative",category:"normative",summary:"",body:bundle().lang.body};if(key==="schema")return{slug:"schema",title:bundle().schema.title,kind:"reference",category:"reference",summary:"",body:bundle().schema.body};return bundle().pages.find(p=>p.slug===key)}function remoteUrl(slug){const base=`${REMOTE_BASE}/v/${bundle().version}`;if(slug==="schema")return`${base}/cotal.schema.json`;if(slug==="lang")return`${base}/cotal-lang.md`;return`${base}/${slug}.md`}function renderDocsIndex(){const b=metadata();const rows=b.pages.map(p=>{const kind=p.kind?`: ${p.kind}`:"";return`- \`${p.slug}\`${kind}
|
|
129
129
|
${p.summary}`});return[`# Cotal v${b.version} documentation`,"","The authoritative docs bundled with this installed version. This index lists what","exists; it holds no answers itself. Your next call:",'- Know the page? Read it in full: `cotal_docs(page: "<slug>")` (e.g. "spec", "architecture").','- Not sure which page? Search: `cotal_docs(query: "\u2026")` returns the most relevant sections.',"Prefer these docs over training memory, and read the full page before writing code or wire","frames. Docs are bundled and version-exact; add `refresh: true` to also pull any patches","published to docs.cotal.ai for this same version.","","## The normative sources",`- \`spec\`: ${b.spec.title} (the wire contract; where a page disagrees, the spec wins)`,`- \`lang\`: ${b.lang.title} (the workflow language a durable run executes; spec \xA714)`,`- \`schema\`: ${b.schema.title} (authoritative for message shapes)`,"","## Pages",...rows].join("\n")}function renderPage(p,note){return`${note}
|
|
130
130
|
|
|
131
131
|
${p.body}`.trimStart()}var K1=1.2;var B=.75;function sources(){const b=bundle();return[...b.pages,{slug:"spec",...b.spec},{slug:"lang",...b.lang},{slug:"schema",...b.schema}]}var index;function searchIndex(){return index??=decodeIndex(loadDocsIndex(),sources().map(source=>source.body.length),DOCS_VERSION)}function termId(terms,term){let low=0;let high=terms.length-1;while(low<=high){const mid=low+high>>>1;const candidate2=terms[mid];if(candidate2===term)return mid;if(candidate2<term)low=mid+1;else high=mid-1}return-1}function searchDocs(query,limit=5){if(limit<=0)return[];let terms=tokenize(query).filter(t=>!STOP.has(t));if(!terms.length)terms=tokenize(query);const termSet=new Set(terms);if(!termSet.size)return[];const idx=searchIndex();const N=idx.sections;const scores=new Float64Array(N);for(const t of termSet){const id2=termId(idx.terms,t);if(id2<0)continue;const from=idx.offsets[id2];const to=idx.offsets[id2+1];const n=to-from;const idf=Math.log(1+(N-n+.5)/(n+.5));for(let p=from;p<to;p++){const s=idx.postSection[p];const f=idx.postWeight[p];scores[s]+=idf*(f*(K1+1)/(f+K1*(1-B+B*idx.length[s]/idx.avgdl)))}}const scored=[];for(let s=0;s<N;s++)if(scores[s]>0)scored.push({s,score:scores[s]});scored.sort((a,b)=>b.score-a.score);const all=sources();const perPage=new Map;const hits=[];for(const{s,score}of scored){const source=all[idx.source[s]];const seen=perPage.get(source.slug)??0;if(seen>=2)continue;perPage.set(source.slug,seen+1);hits.push({slug:source.slug,pageTitle:source.title,heading:idx.headings[s],text:source.body.slice(idx.start[s],idx.end[s]),score});if(hits.length>=limit)break}return hits}function capSection(text2,maxLines=48){const lines=text2.split("\n");if(lines.length<=maxLines)return text2.trim();return lines.slice(0,maxLines).join("\n").trimEnd()+"\n\n\u2026 (section continues; read the full page)"}function renderSearch(query,hits){if(!hits.length){return`No matches for "${query}" in the Cotal v${bundle().version} docs. Call cotal_docs() for the page index, or search an exact identifier (a subject, a cotal_* tool, a field name).`}const blocks=hits.map(h=>`## ${h.heading}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cotal-ai/connector-hermes",
|
|
3
3
|
"description": "Cotal connector for the Hermes (Nous Research) agent.",
|
|
4
|
-
"version": "0.133.
|
|
4
|
+
"version": "0.133.5",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -24,8 +24,8 @@
|
|
|
24
24
|
"@cotal-ai/core": ">=0.1.0"
|
|
25
25
|
},
|
|
26
26
|
"devDependencies": {
|
|
27
|
-
"@cotal-ai/core": "0.133.
|
|
28
|
-
"@cotal-ai/connector-core": "0.133.
|
|
27
|
+
"@cotal-ai/core": "0.133.5",
|
|
28
|
+
"@cotal-ai/connector-core": "0.133.5",
|
|
29
29
|
"@cotal-ai/smoke-kit": "0.0.0",
|
|
30
30
|
"esbuild": "^0.28.0",
|
|
31
31
|
"tsx": "^4.22.4",
|
|
Binary file
|
|
Binary file
|
|
@@ -124,7 +124,7 @@ ${blocks.join("\n")}
|
|
|
124
124
|
${lines.join("\n")}`}channelInfo(channel){const cfg=this.ep.getChannelConfig(channel);return{description:cfg?.description,instructions:cfg?.instructions,replay:this.ep.channelReplay(channel),registered:cfg!==void 0,event:this.eventChannelOf(channel)}}eventChannelOf(channel){const principal=eventChannelPrincipal(channel);if(!principal)return void 0;const own=this.ep.principal;return principal.owner===own.owner&&principal.actor===own.actor?"own":"agent"}joinedChannels(){return this.ep.joinedChannels()}async listChannels(){const mine=this.ep.joinedChannels();const pending=this.ep.pendingDurableLeaves();const unclosed=new Set(pending);let leaseLive=false;let leaseReadable=false;let daemonMemberships;try{leaseLive=(await this.ep.readDeliveryLease(0))?.ready===true;leaseReadable=true}catch{}if(leaseReadable){try{daemonMemberships=await this.ep.fetchMemberships()}catch{daemonMemberships=void 0;leaseReadable=false}}const health=(channel,joined)=>joined&&this.ep.channelDeliveryClass(channel)==="durable"?!leaseReadable?"unknown":daemonMemberships===void 0?"degraded":daemonMemberships.some(m=>m.channel===channel)&&leaseLive?"active":"degraded":void 0;const rows=(await this.ep.listChannels()).map(c=>{const joined=mine.some(p=>subjectMatches(p,c.channel));return{channel:c.channel,description:c.config?.description,replay:this.ep.channelReplay(c.channel),joined,durableUnclosed:unclosed.has(c.channel),deliveryHealth:health(c.channel,joined),messages:c.messages,mode:this.channelMode(c.channel)??"normal",event:this.eventChannelOf(c.channel)}});const present=new Set(rows.map(r=>r.channel));for(const ch of pending){if(present.has(ch))continue;rows.push({channel:ch,description:void 0,replay:this.ep.channelReplay(ch),joined:false,durableUnclosed:true,deliveryHealth:void 0,messages:0,mode:this.channelMode(ch)??"normal",event:this.eventChannelOf(ch)})}return rows}async joinChannel(channel){await this.requireConnected();return this.ep.joinChannel(channel)}async leaveChannel(channel){await this.requireConnected();return this.ep.leaveChannel(channel)}async requireConnected(){return this.whenConnected(CONNECT_GRACE_MS)}async whenConnected(timeoutMs=CONNECT_GRACE_MS){if(this._connected)return;if(!await this.awaitConnection(timeoutMs))throw new Error(this.notConnectedMessage())}awaitConnection(timeoutMs){return new Promise(resolve=>{let settled=false;const finish=ok3=>{if(settled)return;settled=true;clearTimeout(timer);this.ep.off("connection",onConnection);resolve(ok3)};const onConnection=e=>{if(e.connected)finish(true)};const timer=setTimeout(()=>finish(false),Math.max(1,timeoutMs));this.ep.on("connection",onConnection);if(this._connected)finish(true)})}notConnectedMessage(){const issue2=this.connectionIssue;if(issue2)return`not connected to the mesh at ${this.config.servers}: ${issue2}`;const remedy=isLocalServer(this.config.servers)?"is it running? (`cotal up`)":"it did not become reachable \u2014 check that the mesh is up and that this machine can reach it.";return`not connected to the mesh at ${this.config.servers} \u2014 ${remedy}`}handleEndpointError(error51){if(!this._connected&&!this._stopping)this.lastConnectionError=error51.message;this.logEndpointNotice("error",error51)}handleEndpointWarning(error51){this.logEndpointNotice("warning",error51)}logEndpointNotice(kind,error51){const now=Date.now();const fingerprint=error51.message.replace(/oc_[A-Za-z0-9]+_\d+/g,"oc_*");const prior=this.endpointNoticeLog.get(fingerprint);if(prior&&now-prior.lastLoggedAt<ENDPOINT_ERROR_LOG_WINDOW_MS){prior.suppressed++;return}const suffix=prior?.suppressed?` (${prior.suppressed} repeats suppressed)`:"";this.endpointNoticeLog.set(fingerprint,{lastLoggedAt:now,suppressed:0});if(this.endpointNoticeLog.size>MAX_ENDPOINT_NOTICES)this.endpointNoticeLog.delete(this.endpointNoticeLog.keys().next().value);this.log(`endpoint ${kind}: ${error51.message}${suffix}`)}log(msg){process.stderr.write(`[cotal-connector] ${msg}
|
|
125
125
|
`)}};function presenceReadCondition(failure){return`the presence read failed (${failure.message})`}function closeChannelNames(channel,known){const out=[];for(const name of known){if(name!==channel&&editDistanceAtMostOne(channel,name))out.push(name)}out.sort((a,b)=>a.localeCompare(b));return out.slice(0,3)}function editDistanceAtMostOne(a,b){if(a===b)return true;const da=a.length-b.length;if(da>1||da<-1)return false;let i=0;let j=0;let skipped=false;while(i<a.length&&j<b.length){if(a[i]===b[j]){i++;j++;continue}if(skipped)return false;skipped=true;if(a.length>b.length)i++;else if(b.length>a.length)j++;else{i++;j++}}return true}var SUN_PATH_MAX_BYTES=process.platform==="darwin"?104:108;var TRUNCATABLE_FIELDS=[{type:AGUI_EVENT_TYPE.TOOL_CALL_ARGS,field:"delta"},{type:AGUI_EVENT_TYPE.TOOL_CALL_RESULT,field:"content"},{type:AGUI_EVENT_TYPE.TEXT_MESSAGE_CONTENT,field:"delta"}];var EGRESS_FORBIDDEN_TYPES=new Set([AGUI_EVENT_TYPE.TOOL_CALL_ARGS,AGUI_EVENT_TYPE.TOOL_CALL_RESULT]);var KNOWN_EVENT_KEYS_BY_TYPE=new Map([[AGUI_EVENT_TYPE.RUN_STARTED,new Set(["type","timestamp","rawEvent","threadId","runId","parentRunId","input","cotal"])],[AGUI_EVENT_TYPE.RUN_FINISHED,new Set(["type","timestamp","rawEvent","threadId","runId","result","outcome","cotal"])],[AGUI_EVENT_TYPE.RUN_ERROR,new Set(["type","timestamp","rawEvent","message","code","cotal"])],[AGUI_EVENT_TYPE.TEXT_MESSAGE_START,new Set(["type","timestamp","rawEvent","messageId","role","name","cotal"])],[AGUI_EVENT_TYPE.TEXT_MESSAGE_CONTENT,new Set(["type","timestamp","rawEvent","messageId","delta","cotal"])],[AGUI_EVENT_TYPE.TEXT_MESSAGE_END,new Set(["type","timestamp","rawEvent","messageId","cotal"])],[AGUI_EVENT_TYPE.TOOL_CALL_START,new Set(["type","timestamp","rawEvent","toolCallId","toolCallName","parentMessageId","cotal"])],[AGUI_EVENT_TYPE.TOOL_CALL_ARGS,new Set(["type","timestamp","rawEvent","toolCallId","delta","cotal"])],[AGUI_EVENT_TYPE.TOOL_CALL_END,new Set(["type","timestamp","rawEvent","toolCallId","cotal"])],[AGUI_EVENT_TYPE.TOOL_CALL_RESULT,new Set(["type","timestamp","rawEvent","messageId","toolCallId","content","role","cotal"])],[AGUI_EVENT_TYPE.REASONING_MESSAGE_START,new Set(["type","timestamp","rawEvent","messageId","role","cotal"])],[AGUI_EVENT_TYPE.REASONING_MESSAGE_CONTENT,new Set(["type","timestamp","rawEvent","messageId","delta","cotal"])],[AGUI_EVENT_TYPE.REASONING_MESSAGE_END,new Set(["type","timestamp","rawEvent","messageId","cotal"])],[AGUI_EVENT_TYPE.CUSTOM,new Set(["type","timestamp","rawEvent","name","value","cotal"])]]);var SIZING_ID="S".repeat(64);var SIZING_EXPECTATION=Number.MAX_SAFE_INTEGER;var str=v=>typeof v==="string"?v:void 0;var CONT=" \xB7 ";var TEXT_PREFIX="\xBB ";var THINK_PREFIX="(thinking) ";var TOOL_PREFIX="\u2699 ";var RESULT_PREFIX=" \u21B3 ";var BLOCK_START_CHARS=new Set([..."#>|`~=_*+-[<0123456789"," "]);function renderEvents(events){const lines=[];const text2=new Map;const reasoning=new Map;const toolName=new Map;const toolArgs=new Map;const emit=(first,cont,body)=>{const[head,...rest]=body.split("\n");lines.push(first+head);for(const l of rest)lines.push(cont+l)};const flush=(map2,id2,first,cont,suffix="")=>{const acc=map2.get(id2);if(acc!==void 0&&acc.length>0)emit(first,cont,acc+suffix);map2.delete(id2)};for(const e of events){const type=typeof e==="object"&&e!==null?str(e.type):void 0;switch(type){case AGUI_EVENT_TYPE.RUN_STARTED:emit("\u25B8 ",CONT,`run ${str(e.runId)??"?"} started`);break;case AGUI_EVENT_TYPE.RUN_FINISHED:{const outcome=str(e.outcome?.type);emit("\u25C2 ",CONT,`run ${str(e.runId)??"?"} finished${outcome?` (${outcome})`:""}`);break}case AGUI_EVENT_TYPE.RUN_ERROR:{const code=str(e.code);emit("\u2717 ",CONT,`run error${code?` [${code}]`:""}: ${str(e.message)??"(no message)"}`);break}case AGUI_EVENT_TYPE.TEXT_MESSAGE_START:text2.set(str(e.messageId)??"","");break;case AGUI_EVENT_TYPE.TEXT_MESSAGE_CONTENT:{const id2=str(e.messageId)??"";text2.set(id2,(text2.get(id2)??"")+(str(e.delta)??""));break}case AGUI_EVENT_TYPE.TEXT_MESSAGE_END:flush(text2,str(e.messageId)??"",TEXT_PREFIX,TEXT_PREFIX);break;case AGUI_EVENT_TYPE.REASONING_MESSAGE_START:reasoning.set(str(e.messageId)??"","");break;case AGUI_EVENT_TYPE.REASONING_MESSAGE_CONTENT:{const id2=str(e.messageId)??"";reasoning.set(id2,(reasoning.get(id2)??"")+(str(e.delta)??""));break}case AGUI_EVENT_TYPE.REASONING_MESSAGE_END:flush(reasoning,str(e.messageId)??"",THINK_PREFIX,CONT);break;case AGUI_EVENT_TYPE.TOOL_CALL_START:{const id2=str(e.toolCallId)??"";toolName.set(id2,str(e.toolCallName)??"?");toolArgs.set(id2,"");break}case AGUI_EVENT_TYPE.TOOL_CALL_ARGS:{const id2=str(e.toolCallId)??"";toolArgs.set(id2,(toolArgs.get(id2)??"")+(str(e.delta)??""));break}case AGUI_EVENT_TYPE.TOOL_CALL_END:{const id2=str(e.toolCallId)??"";emit(TOOL_PREFIX,CONT,`${toolName.get(id2)??"?"}(${toolArgs.get(id2)??""})`);toolName.delete(id2);toolArgs.delete(id2);break}case AGUI_EVENT_TYPE.TOOL_CALL_RESULT:emit(RESULT_PREFIX,CONT,str(e.content)??"(no content)");break;case AGUI_EVENT_TYPE.CUSTOM:emit("\u2022 ",CONT,`custom ${str(e.name)??"(unnamed)"}`);break;default:emit("\u2022 ",CONT,`unrecognised event ${JSON.stringify(type??null)}`)}}for(const id2 of[...text2.keys()])flush(text2,id2,TEXT_PREFIX,TEXT_PREFIX," \u2026");for(const id2 of[...reasoning.keys()])flush(reasoning,id2,THINK_PREFIX,CONT," \u2026");for(const id2 of[...toolName.keys()])emit(TOOL_PREFIX,CONT,`${toolName.get(id2)??"?"}(${toolArgs.get(id2)??""}) \u2026`);return lines}var aguiFramePartRenderer=Object.freeze({kind:"part-renderer",name:AGUI_FRAME_KIND,render(part){if(!isAguiFramePart(part))return`[not an AG-UI frame]`;const events=part.events;if(!Array.isArray(events)||events.length===0)return`[AG-UI frame carrying no events]`;const lines=renderEvents(events);return lines.length>0?lines.join("\n"):`[AG-UI frame with ${events.length} event(s) and nothing to show]`}});function registerAguiFramePartRenderer(){if(registry2.has("part-renderer",AGUI_FRAME_KIND))return;registry2.register(aguiFramePartRenderer)}registerAguiFramePartRenderer();var import_node_net3=require("node:net");var import_node_fs6=require("node:fs");var import_node_crypto12=require("node:crypto");var HANDOFF_DEADLINE_MS=5e3;var LEGACY_WRITE_DEADLINE_MS=5e3;var MAX_FRAME_BYTES=1<<20;var AUTH_DEADLINE_MS=5e3;function tokenMatches(presented,digest){if(typeof presented!=="string")return false;return(0,import_node_crypto12.timingSafeEqual)((0,import_node_crypto12.createHash)("sha256").update(presented).digest(),digest)}function writeReply(sock,reply,awaitHandoff){return new Promise(resolve=>{let settled=false;const done=ok3=>{if(settled)return;settled=true;resolve(ok3)};sock.once("error",()=>done(false));sock.once("close",()=>done(false));if(!awaitHandoff){const stall=setTimeout(()=>done(false),LEGACY_WRITE_DEADLINE_MS);stall.unref?.();try{sock.end(JSON.stringify(reply)+"\n",(err3=>{clearTimeout(stall);done(!err3)}))}catch{clearTimeout(stall);done(false)}return}const deadline=setTimeout(()=>{sock.destroy();done(false)},HANDOFF_DEADLINE_MS);deadline.unref?.();let receipt="";sock.on("data",d=>{receipt+=d;if(!receipt.includes("\n"))return;clearTimeout(deadline);try{sock.end()}catch{}done(true)});try{sock.write(JSON.stringify(reply)+"\n",err3=>{if(!err3)return;clearTimeout(deadline);done(false)})}catch{clearTimeout(deadline);done(false)}})}function startControlServer(agent,endpoint,handle,opts={}){const{path}=endpoint;const digest=(0,import_node_crypto12.createHash)("sha256").update(endpoint.token).digest();const server=(0,import_node_net3.createServer)(sock=>{let buf="";let handled=false;sock.setEncoding("utf8");const deadline=setTimeout(()=>sock.destroy(),AUTH_DEADLINE_MS);deadline.unref?.();sock.on("close",()=>clearTimeout(deadline));sock.on("data",async d=>{if(handled)return;buf+=d;if(buf.length>MAX_FRAME_BYTES){sock.destroy();return}const nl=buf.indexOf("\n");if(nl<0)return;handled=true;clearTimeout(deadline);let frame={};try{frame=JSON.parse(buf.slice(0,nl)||"{}")}catch{}if(!tokenMatches(frame.token,digest)){sock.destroy();return}const op=frame.op;if(op==="shutdown"){try{sock.end(JSON.stringify({ok:true})+"\n")}catch{}opts.onShutdown?.();return}if(op==="session"){const sessionId=opts.onSession?.();try{sock.end(JSON.stringify(sessionId?{ok:true,sessionId}:{ok:false,error:"session not ready"})+"\n")}catch{}return}const ev=frame.event??{};const awaitHandoff=frame.handoff===true;const reply=await handle(agent,ev);const delivered=await writeReply(sock,reply,awaitHandoff);opts.onReply?.(ev,delivered)});sock.on("error",()=>{})});let bound=false;let retried=false;const emit=server.emit.bind(server);server.emit=(event,...args)=>{const error51=args[0];if(event!=="error"||bound||retried||process.platform==="win32"||path.startsWith("\0")||error51?.code!=="EADDRINUSE")return emit(event,...args);retried=true;let original;try{original=(0,import_node_fs6.lstatSync)(path);if(!original.isSocket())return emit(event,...args)}catch(e){if(e.code!=="ENOENT")return emit(event,...args)}const probe=(0,import_node_net3.connect)(path);let settled=false;const finish=stale=>{if(settled)return;settled=true;clearTimeout(deadline);probe.destroy();server.off("close",cancel);if(!stale){emit(event,...args);return}try{const current=(0,import_node_fs6.lstatSync)(path);if(!original||!current.isSocket()||current.dev!==original.dev||current.ino!==original.ino){emit(event,...args);return}(0,import_node_fs6.unlinkSync)(path)}catch(e){if(e.code!=="ENOENT"){emit("error",e);return}}server.listen(path)};const cancel=()=>{settled=true;clearTimeout(deadline);probe.destroy()};const deadline=setTimeout(()=>finish(false),250);server.once("close",cancel);probe.once("connect",()=>finish(false));probe.once("error",e=>finish(e.code==="ECONNREFUSED"||e.code==="ENOENT"));return true};server.on("error",e=>{process.stderr.write(`[cotal-connector] control server error: ${e.message}
|
|
126
126
|
`);if(opts.fatalBind&&!bound)process.exit(1)});server.listen(path,()=>{bound=true;process.stderr.write(`[cotal-connector] control socket: ${path}
|
|
127
|
-
`)});return server}var ok=text2=>({text:text2});var err=text2=>({text:text2,isError:true});async function submitFeedback(input,options={}){const url2=options.url??(options.key?FEEDBACK_URL:PUBLIC_FEEDBACK_URL);const headers3={"content-type":"application/json"};const body={...input};if(options.key){headers3.authorization=`Bearer ${options.key}`}else{if(!options.email)return err("Keyless feedback goes to the public cotal.ai intake, which requires a traceable contact email \u2014 ask the user for one and retry with the email argument (or set COTAL_FEEDBACK_EMAIL).");body.email=options.email}try{const res=await fetch(url2,{method:"POST",headers:headers3,body:JSON.stringify(body)});const raw=await res.text();let reply={};if(raw)try{reply=JSON.parse(raw)}catch{reply={error:raw}}if(!res.ok)return err(`Feedback rejected (${res.status}${reply.error?`: ${reply.error}`:""}).`);const note=reply.published===false?" (stored, but the internal feedback channel publish failed)":"";return ok(`Feedback sent${reply.id?` (id ${reply.id})`:""}${note}. Thanks!`)}catch(e){return err(`Couldn't reach the feedback intake at ${url2}: ${e.message}`)}}var import_node_child_process3=require("node:child_process");init_external();init_external();var import_node_crypto13=require("node:crypto");var import_node_fs7=require("node:fs");var import_node_path3=require("node:path");var import_node_zlib=require("node:zlib");var DOCS_VERSION="0.133.4";function loadDocsMetadata(){return{"version":"0.133.4","pages":[{"slug":"what-is-cotal","title":"What is Cotal","kind":"Start here (informative)","category":"Start here","summary":"Cotal is an open pub/sub standard for AI agents and software services to work together."},{"slug":"getting-started","title":"Quickstart","kind":"Start here (informative)","category":"Start here","summary":"Paste this into any coding agent (Claude Code, OpenCode, Cursor, Codex) and it will do the whole page for you:"},{"slug":"architecture","title":"Architecture","kind":"Concept (informative)","category":"Concept","summary":"Cotal is built as a thin waist: the normative wire contract (subjects, message schemas, presence/discovery, delivery semantics, the auth grammar) is the standard (SPEC), and everything else is a pl\u2026"},{"slug":"mcp-tools","title":"MCP tool catalog","kind":"Reference: the `cotal_*` tool surface every connected agent gets.","category":"Reference","summary":"The tools are defined once, platform-neutrally, in @cotal-ai/connector-core and rendered onto each host's native tool API (an MCP server for Claude Code, Codex and Jcode, native plugin tools for Op\u2026"},{"slug":"channels-and-permissions","title":"Channel permissions","kind":"Reference (informative task card)","category":"Reference","summary":"Channel permissions decide who can read, who can post, and what each agent tunes into at boot."},{"slug":"identity-and-auth","title":"Identity","kind":"Concept (informative)","category":"Concept","summary":"Who can do what on a mesh, and how it is enforced."},{"slug":"agent-files","title":"Agent files","kind":"Reference (the persisted form of an agent's identity + persona, read by every launcher)","category":"Reference","summary":"An agent's identity and persona live in one Markdown file instead of being passed flag-by-flag, the same shape Claude Code uses for subagents:"},{"slug":"api-reference","title":"API reference","kind":"Reference (informative)","category":"Reference","summary":"Cotal exposes a wire protocol, TypeScript libraries, CLI commands and agent tools."},{"slug":"auth-api","title":"Auth HTTP API","kind":"Reference (informative)","category":"Reference","summary":"HTTP interface of the stock auth public listener: 11 paths and 12 operations."},{"slug":"authoring-a-connector","title":"Authoring a connector","kind":"Reference: describes the TypeScript reference implementation, not the wire contract.","category":"Reference","summary":"A connector teaches Cotal how to launch one agent harness (Claude Code, OpenCode, your own) as a mesh node."},{"slug":"build-a-client","title":"Build a Cotal client","kind":"Guide (informative)","category":"Guide","summary":"This page is the reading order for implementing a Cotal client in another language (Go, Python, Rust, or anything with a NATS client library) against the spec, without reimplementing the protocol."},{"slug":"cli","title":"`cotal` CLI reference","kind":"Reference: describes the TypeScript reference implementation (the `cotal` CLI), not the wire contract.","category":"Reference","summary":"cotal is the operator command line for the reference implementation: bring a mesh up, mint identities, launch agents, watch what they do, and tear it all down."},{"slug":"config","title":"Configuration","kind":"Reference: describes the TypeScript reference implementation (the `cotal` CLI and connectors), not the wire contract.","category":"Reference","summary":"Four things configure a Cotal workstation: the config file (per-connector settings, notably which of your MCP servers get shared with spawned agents), your preferences (the defaults your own comman\u2026"},{"slug":"connect-claude","title":"Connect Claude","kind":"Guide (informative)","category":"Guide","summary":"The Claude Code connector turns a real claude session into a Cotal mesh peer."},{"slug":"connect-codex","title":"Connect Codex (beta)","kind":"Guide (informative)","category":"Guide","summary":"OpenAI Codex joins a Cotal mesh as a lateral peer: the same cotal tool surface, the same message delivery and attention model as the other connectors, plus mid-turn steering: a directed peer messag\u2026"},{"slug":"connect-hermes","title":"Connect Hermes (alpha)","kind":"Guide (informative)","category":"Guide","summary":"Hermes (Nous Research) joins a Cotal mesh as a lateral peer, with the same shared cotal tool surface and delivery model as the other connectors."},{"slug":"connect-jcode","title":"Connect Jcode (beta)","kind":"Guide (informative)","category":"Guide","summary":"Jcode joins a Cotal mesh as a lateral peer."},{"slug":"connect-opencode","title":"Connect OpenCode (beta)","kind":"Guide (informative)","category":"Guide","summary":"OpenCode joins a Cotal mesh as a lateral peer, at parity with Claude Code: the same cotal tool surface, the same message delivery and attention model."},{"slug":"connect-pi","title":"Connect pi (alpha)","kind":"Guide (informative)","category":"Guide","summary":"@cotal-ai/pi is Cotal's first host-native framework adapter."},{"slug":"connectors","title":"Connectors","kind":"Guide (informative)","category":"Guide","summary":"Every connector puts a real agent session on the mesh with the same cotal tools, presence, and delivery model (MCP tools)."},{"slug":"control-surface","title":"The control surface","kind":"Concept (informative)","category":"Concept","summary":"Cotal once had a privileged control rail: a fixed set of named service tiers (self / manager / admin / delivery) on their own ctl."},{"slug":"dashboard-api","title":"Dashboard HTTP API","kind":"Reference (informative)","category":"Reference","summary":"HTTP interface of the @cotal-ai/web reference implementation."},{"slug":"define-a-team","title":"Define a team","kind":"Guide (informative)","category":"Guide","summary":"The Quickstart gives you one agent. To run a specific team (your own channels, your own agents, and the channel access for each agent), describe it once in a cotal.yaml and launch it with a single\u2026"},{"slug":"delivery-daemon","title":"The delivery daemon (Plane-3)","kind":"Concept (informative)","category":"Concept","summary":"Live channel delivery is at-most-once: a message reaches only the peers subscribed at the moment it is published (SPEC \xA74)."},{"slug":"deploy","title":"Deploying agent teams","kind":"Guide (informative)","category":"Guide","summary":"The deploy/ tree runs a team of agents in an isolated container that dials out to an existing Cotal broker."},{"slug":"embedding","title":"Embedding Cotal","kind":"Guide (informative)","category":"Guide","summary":"The cotal binary in this repo is one composition root: an operator CLI."},{"slug":"examples","title":"Examples","kind":"Guide (informative)","category":"Guide","summary":"Examples live in examples/, one self-contained folder each."},{"slug":"glossary","title":"Glossary","kind":"Reference (informative)","category":"Reference","summary":"One-line definitions of the terms used across these docs and the spec."},{"slug":"lang-card","title":"The cotal-lang card","kind":"Reference (informative)","category":"Reference","summary":"One page to write a correct workflow program."},{"slug":"manifest","title":"Mesh manifest (`cotal.yaml`)","kind":"Reference: every field of the mesh manifest.","category":"Reference","summary":"A manifest (cotal.yaml, kind: Mesh) describes a whole team (its channels, its agents, and who may read and post where) in one file."},{"slug":"mesh-view","title":"MeshView","kind":"Reference: TypeScript observer surfaces (`MeshView`)","category":"Reference","summary":"MeshView is the CLI's shared model for the terminal console and its plain stream."},{"slug":"presence-and-delivery","title":"Message flow","kind":"Concept (informative)","category":"Concept","summary":"How peers see each other and how messages reach them: the presence directory, the three delivery modes, and the two delivery guarantees."},{"slug":"release","title":"Publishing a release","kind":"Project (non-normative maintainer notes)","category":"Project","summary":"Cotal uses pnpm, Changesets and one GitHub Actions workflow."},{"slug":"roadmap","title":"Roadmap","kind":"Project (non-normative)","category":"Project","summary":"Cotal is pre-1.0. The wire contract (v0.x) may still change under the change process. This page tracks what is deliberately not built yet, and the direction each area is headed."},{"slug":"run-a-mesh","title":"Run a mesh","kind":"Guide (informative)","category":"Guide","summary":"Day-to-day operation of a local mesh: what cotal up actually runs, how spawning resolves personas, harnesses, and models, how to reach a mesh from any directory, and the operator-only maintenance v\u2026"},{"slug":"security","title":"Security model","kind":"Concept (informative threat model)","category":"Concept","summary":"Cotal v0 provides containment and sender authenticity for peers sharing one trusted NATS broker."},{"slug":"setup-internals","title":"Setup internals (maintainer notes)","kind":"Project (non-normative maintainer notes)","category":"Project","summary":"cotal setup (implementations/cli/src/commands/setup.ts) saves configuration by default: it checks prerequisites, sets up the chosen application and runtimes, and seeds persona files."},{"slug":"spaces","title":"Spaces","kind":"Concept (informative)","category":"Concept","summary":"The space concept, and why it is distinct from a channel."},{"slug":"stability","title":"Substrate stability","kind":"Project (informative)","category":"Project","summary":"Cotal's packages are pre-1.0 and publish in lockstep."},{"slug":"telemetry","title":"Telemetry","kind":"Reference","category":"Reference","summary":"The cotal CLI sends usage data about commands, failures and platforms."},{"slug":"transport","title":"Transport vs protocol","kind":"Concept (informative)","category":"Concept","summary":"What in Cotal is the protocol, what is the transport, and what a transport binding must provide."},{"slug":"upgrading","title":"Upgrading a running deployment","kind":"Guide (informative)","category":"Guide","summary":"Substrate stability tells you what the version numbers promise."},{"slug":"using-cotal","title":"Choose a workflow","kind":"Guide (informative)","category":"Guide","summary":"Cotal can run a local team, connect a session to a shared space, or expose a service to agents."},{"slug":"watch-a-mesh","title":"Watch a mesh","kind":"Guide (informative)","category":"Guide","summary":"Cotal's watch surfaces show who is present, their reported activity and the messages your credential permits you to read."},{"slug":"workflows","title":"Workflow runs","kind":"Concept (informative)","category":"Concept","summary":"A workflow run is a program that coordinates agents over hours or days and survives the process that started it."}],"spec":{"title":"Cotal Wire Specification"},"lang":{"title":"Cotal Lang: the workflow language"},"schema":{"title":"Cotal message schema (JSON Schema)"}}}function loadDocsBundle(){const packed=(0,import_node_fs7.readFileSync)((0,import_node_path3.join)(__dirname,"docs-bundle.bin"));if(packed.length!==979447||(0,import_node_crypto13.createHash)("sha256").update(packed).digest("hex")!=="ad4619c7c6e5969a579604aa58faf2f4d37293b0c39fd0e32c67cf782fedb429")throw new Error("docs data file docs-bundle.bin beside this module is not the one built with it");return JSON.parse((0,import_node_zlib.gunzipSync)(packed).toString("utf8"))}function loadDocsIndex(){const packed=(0,import_node_fs7.readFileSync)((0,import_node_path3.join)(__dirname,"docs-index.bin"));if(packed.length!==437017||(0,import_node_crypto13.createHash)("sha256").update(packed).digest("hex")!=="72627bb737a5846329508321ecfa613eb649107b301714518ad830e9be3e17f2")throw new Error("docs data file docs-index.bin beside this module is not the one built with it");return(0,import_node_zlib.gunzipSync)(packed)}var TOKEN=/[a-z0-9_$.#>*-]+/gi;var EDGE=/^[.>*#-]+|[.>*#-]+$/g;function tokenize(s){const raw=s.toLowerCase().match(TOKEN);if(!raw)return[];const out=[];for(const r of raw){if(r.length>=2)out.push(r);const t=r.replace(EDGE,"");if(t.length>=2&&t!==r)out.push(t);if(t.includes(".")){for(const seg of t.split("."))if(seg.length>=2)out.push(seg)}}return out}var STOP=new Set("a an and are as at be by do for from has how in is it of on or that the this to use using was what when where which who with you your".split(" "));function decodeIndex(bytes,bodyLengths,version2){if(bytes.length<4)throw new Error("docs index is truncated or malformed");const headerLength=bytes.readUInt32LE(0);if(4+headerLength>bytes.length)throw new Error("docs index is truncated or malformed");const header=JSON.parse(bytes.toString("utf8",4,4+headerLength));if(header.version!==version2||header.bodyLengths.length!==bodyLengths.length||header.bodyLengths.some((length2,i)=>length2!==bodyLengths[i]))throw new Error("docs index does not match the docs bundle it is searching");const n=header.sections;const length=4*n+header.terms.length+1+2*header.postings;if(bytes.length-4-headerLength!==4*length)throw new Error("docs index is truncated or malformed");const columns=new Uint32Array(length);for(let i=0;i<length;i++)columns[i]=bytes.readUInt32LE(4+headerLength+4*i);const offsets=4*n;const sectionColumn=offsets+header.terms.length+1;let total=0;for(let i=0;i<n;i++)total+=columns[3*n+i];return{sections:n,terms:header.terms,headings:header.headings,source:columns.subarray(0,n),start:columns.subarray(n,2*n),end:columns.subarray(2*n,3*n),length:columns.subarray(3*n,4*n),offsets:columns.subarray(offsets,sectionColumn),postSection:columns.subarray(sectionColumn,sectionColumn+header.postings),postWeight:columns.subarray(sectionColumn+header.postings),avgdl:total/Math.max(1,n)}}var indexed;function metadata(){return indexed??=loadDocsMetadata()}var bundled;function bundle(){return bundled??=loadDocsBundle()}var REMOTE_BASE="https://docs.cotal.ai";function resolvePage(page){const key=page.trim().toLowerCase().replace(/\.md$/,"");if(key==="spec")return{slug:"spec",title:bundle().spec.title,kind:"normative",category:"normative",summary:"",body:bundle().spec.body};if(key==="lang"||key==="cotal-lang")return{slug:"lang",title:bundle().lang.title,kind:"normative",category:"normative",summary:"",body:bundle().lang.body};if(key==="schema")return{slug:"schema",title:bundle().schema.title,kind:"reference",category:"reference",summary:"",body:bundle().schema.body};return bundle().pages.find(p=>p.slug===key)}function remoteUrl(slug){const base=`${REMOTE_BASE}/v/${bundle().version}`;if(slug==="schema")return`${base}/cotal.schema.json`;if(slug==="lang")return`${base}/cotal-lang.md`;return`${base}/${slug}.md`}function renderDocsIndex(){const b=metadata();const rows=b.pages.map(p=>{const kind=p.kind?`: ${p.kind}`:"";return`- \`${p.slug}\`${kind}
|
|
127
|
+
`)});return server}var ok=text2=>({text:text2});var err=text2=>({text:text2,isError:true});async function submitFeedback(input,options={}){const url2=options.url??(options.key?FEEDBACK_URL:PUBLIC_FEEDBACK_URL);const headers3={"content-type":"application/json"};const body={...input};if(options.key){headers3.authorization=`Bearer ${options.key}`}else{if(!options.email)return err("Keyless feedback goes to the public cotal.ai intake, which requires a traceable contact email \u2014 ask the user for one and retry with the email argument (or set COTAL_FEEDBACK_EMAIL).");body.email=options.email}try{const res=await fetch(url2,{method:"POST",headers:headers3,body:JSON.stringify(body)});const raw=await res.text();let reply={};if(raw)try{reply=JSON.parse(raw)}catch{reply={error:raw}}if(!res.ok)return err(`Feedback rejected (${res.status}${reply.error?`: ${reply.error}`:""}).`);const note=reply.published===false?" (stored, but the internal feedback channel publish failed)":"";return ok(`Feedback sent${reply.id?` (id ${reply.id})`:""}${note}. Thanks!`)}catch(e){return err(`Couldn't reach the feedback intake at ${url2}: ${e.message}`)}}var import_node_child_process3=require("node:child_process");init_external();init_external();var import_node_crypto13=require("node:crypto");var import_node_fs7=require("node:fs");var import_node_path3=require("node:path");var import_node_zlib=require("node:zlib");var DOCS_VERSION="0.133.5";function loadDocsMetadata(){return{"version":"0.133.5","pages":[{"slug":"what-is-cotal","title":"What is Cotal","kind":"Start here (informative)","category":"Start here","summary":"Cotal is an open pub/sub standard for AI agents and software services to work together."},{"slug":"getting-started","title":"Quickstart","kind":"Start here (informative)","category":"Start here","summary":"Paste this into any coding agent (Claude Code, OpenCode, Cursor, Codex) and it will do the whole page for you:"},{"slug":"architecture","title":"Architecture","kind":"Concept (informative)","category":"Concept","summary":"Cotal is built as a thin waist: the normative wire contract (subjects, message schemas, presence/discovery, delivery semantics, the auth grammar) is the standard (SPEC), and everything else is a pl\u2026"},{"slug":"mcp-tools","title":"MCP tool catalog","kind":"Reference: the `cotal_*` tool surface every connected agent gets.","category":"Reference","summary":"The tools are defined once, platform-neutrally, in @cotal-ai/connector-core and rendered onto each host's native tool API (an MCP server for Claude Code, Codex and Jcode, native plugin tools for Op\u2026"},{"slug":"channels-and-permissions","title":"Channel permissions","kind":"Reference (informative task card)","category":"Reference","summary":"Channel permissions decide who can read, who can post, and what each agent tunes into at boot."},{"slug":"identity-and-auth","title":"Identity","kind":"Concept (informative)","category":"Concept","summary":"Who can do what on a mesh, and how it is enforced."},{"slug":"agent-files","title":"Agent files","kind":"Reference (the persisted form of an agent's identity + persona, read by every launcher)","category":"Reference","summary":"An agent's identity and persona live in one Markdown file instead of being passed flag-by-flag, the same shape Claude Code uses for subagents:"},{"slug":"api-reference","title":"API reference","kind":"Reference (informative)","category":"Reference","summary":"Cotal exposes a wire protocol, TypeScript libraries, CLI commands and agent tools."},{"slug":"auth-api","title":"Auth HTTP API","kind":"Reference (informative)","category":"Reference","summary":"HTTP interface of the stock auth public listener: 11 paths and 12 operations."},{"slug":"authoring-a-connector","title":"Authoring a connector","kind":"Reference: describes the TypeScript reference implementation, not the wire contract.","category":"Reference","summary":"A connector teaches Cotal how to launch one agent harness (Claude Code, OpenCode, your own) as a mesh node."},{"slug":"build-a-client","title":"Build a Cotal client","kind":"Guide (informative)","category":"Guide","summary":"This page is the reading order for implementing a Cotal client in another language (Go, Python, Rust, or anything with a NATS client library) against the spec, without reimplementing the protocol."},{"slug":"cli","title":"`cotal` CLI reference","kind":"Reference: describes the TypeScript reference implementation (the `cotal` CLI), not the wire contract.","category":"Reference","summary":"cotal is the operator command line for the reference implementation: bring a mesh up, mint identities, launch agents, watch what they do, and tear it all down."},{"slug":"config","title":"Configuration","kind":"Reference: describes the TypeScript reference implementation (the `cotal` CLI and connectors), not the wire contract.","category":"Reference","summary":"Four things configure a Cotal workstation: the config file (per-connector settings, notably which of your MCP servers get shared with spawned agents), your preferences (the defaults your own comman\u2026"},{"slug":"connect-claude","title":"Connect Claude","kind":"Guide (informative)","category":"Guide","summary":"The Claude Code connector turns a real claude session into a Cotal mesh peer."},{"slug":"connect-codex","title":"Connect Codex (beta)","kind":"Guide (informative)","category":"Guide","summary":"OpenAI Codex joins a Cotal mesh as a lateral peer: the same cotal tool surface, the same message delivery and attention model as the other connectors, plus mid-turn steering: a directed peer messag\u2026"},{"slug":"connect-hermes","title":"Connect Hermes (alpha)","kind":"Guide (informative)","category":"Guide","summary":"Hermes (Nous Research) joins a Cotal mesh as a lateral peer, with the same shared cotal tool surface and delivery model as the other connectors."},{"slug":"connect-jcode","title":"Connect Jcode (beta)","kind":"Guide (informative)","category":"Guide","summary":"Jcode joins a Cotal mesh as a lateral peer."},{"slug":"connect-opencode","title":"Connect OpenCode (beta)","kind":"Guide (informative)","category":"Guide","summary":"OpenCode joins a Cotal mesh as a lateral peer, at parity with Claude Code: the same cotal tool surface, the same message delivery and attention model."},{"slug":"connect-pi","title":"Connect pi (alpha)","kind":"Guide (informative)","category":"Guide","summary":"@cotal-ai/pi is Cotal's first host-native framework adapter."},{"slug":"connectors","title":"Connectors","kind":"Guide (informative)","category":"Guide","summary":"Every connector puts a real agent session on the mesh with the same cotal tools, presence, and delivery model (MCP tools)."},{"slug":"control-surface","title":"The control surface","kind":"Concept (informative)","category":"Concept","summary":"Cotal once had a privileged control rail: a fixed set of named service tiers (self / manager / admin / delivery) on their own ctl."},{"slug":"dashboard-api","title":"Dashboard HTTP API","kind":"Reference (informative)","category":"Reference","summary":"HTTP interface of the @cotal-ai/web reference implementation."},{"slug":"define-a-team","title":"Define a team","kind":"Guide (informative)","category":"Guide","summary":"The Quickstart gives you one agent. To run a specific team (your own channels, your own agents, and the channel access for each agent), describe it once in a cotal.yaml and launch it with a single\u2026"},{"slug":"delivery-daemon","title":"The delivery daemon (Plane-3)","kind":"Concept (informative)","category":"Concept","summary":"Live channel delivery is at-most-once: a message reaches only the peers subscribed at the moment it is published (SPEC \xA74)."},{"slug":"deploy","title":"Deploying agent teams","kind":"Guide (informative)","category":"Guide","summary":"The deploy/ tree runs a team of agents in an isolated container that dials out to an existing Cotal broker."},{"slug":"embedding","title":"Embedding Cotal","kind":"Guide (informative)","category":"Guide","summary":"The cotal binary in this repo is one composition root: an operator CLI."},{"slug":"examples","title":"Examples","kind":"Guide (informative)","category":"Guide","summary":"Examples live in examples/, one self-contained folder each."},{"slug":"glossary","title":"Glossary","kind":"Reference (informative)","category":"Reference","summary":"One-line definitions of the terms used across these docs and the spec."},{"slug":"lang-card","title":"The cotal-lang card","kind":"Reference (informative)","category":"Reference","summary":"One page to write a correct workflow program."},{"slug":"manifest","title":"Mesh manifest (`cotal.yaml`)","kind":"Reference: every field of the mesh manifest.","category":"Reference","summary":"A manifest (cotal.yaml, kind: Mesh) describes a whole team (its channels, its agents, and who may read and post where) in one file."},{"slug":"mesh-view","title":"MeshView","kind":"Reference: TypeScript observer surfaces (`MeshView`)","category":"Reference","summary":"MeshView is the CLI's shared model for the terminal console and its plain stream."},{"slug":"presence-and-delivery","title":"Message flow","kind":"Concept (informative)","category":"Concept","summary":"How peers see each other and how messages reach them: the presence directory, the three delivery modes, and the two delivery guarantees."},{"slug":"release","title":"Publishing a release","kind":"Project (non-normative maintainer notes)","category":"Project","summary":"Cotal uses pnpm, Changesets and one GitHub Actions workflow."},{"slug":"roadmap","title":"Roadmap","kind":"Project (non-normative)","category":"Project","summary":"Cotal is pre-1.0. The wire contract (v0.x) may still change under the change process. This page tracks what is deliberately not built yet, and the direction each area is headed."},{"slug":"run-a-mesh","title":"Run a mesh","kind":"Guide (informative)","category":"Guide","summary":"Day-to-day operation of a local mesh: what cotal up actually runs, how spawning resolves personas, harnesses, and models, how to reach a mesh from any directory, and the operator-only maintenance v\u2026"},{"slug":"security","title":"Security model","kind":"Concept (informative threat model)","category":"Concept","summary":"Cotal v0 provides containment and sender authenticity for peers sharing one trusted NATS broker."},{"slug":"setup-internals","title":"Setup internals (maintainer notes)","kind":"Project (non-normative maintainer notes)","category":"Project","summary":"cotal setup (implementations/cli/src/commands/setup.ts) saves configuration by default: it checks prerequisites, sets up the chosen application and runtimes, and seeds persona files."},{"slug":"spaces","title":"Spaces","kind":"Concept (informative)","category":"Concept","summary":"The space concept, and why it is distinct from a channel."},{"slug":"stability","title":"Substrate stability","kind":"Project (informative)","category":"Project","summary":"Cotal's packages are pre-1.0 and publish in lockstep."},{"slug":"telemetry","title":"Telemetry","kind":"Reference","category":"Reference","summary":"The cotal CLI sends usage data about commands, failures and platforms."},{"slug":"transport","title":"Transport vs protocol","kind":"Concept (informative)","category":"Concept","summary":"What in Cotal is the protocol, what is the transport, and what a transport binding must provide."},{"slug":"upgrading","title":"Upgrading a running deployment","kind":"Guide (informative)","category":"Guide","summary":"Substrate stability tells you what the version numbers promise."},{"slug":"using-cotal","title":"Choose a workflow","kind":"Guide (informative)","category":"Guide","summary":"Cotal can run a local team, connect a session to a shared space, or expose a service to agents."},{"slug":"watch-a-mesh","title":"Watch a mesh","kind":"Guide (informative)","category":"Guide","summary":"Cotal's watch surfaces show who is present, their reported activity and the messages your credential permits you to read."},{"slug":"workflows","title":"Workflow runs","kind":"Concept (informative)","category":"Concept","summary":"A workflow run is a program that coordinates agents over hours or days and survives the process that started it."}],"spec":{"title":"Cotal Wire Specification"},"lang":{"title":"Cotal Lang: the workflow language"},"schema":{"title":"Cotal message schema (JSON Schema)"}}}function loadDocsBundle(){const packed=(0,import_node_fs7.readFileSync)((0,import_node_path3.join)(__dirname,"docs-bundle.bin"));if(packed.length!==979447||(0,import_node_crypto13.createHash)("sha256").update(packed).digest("hex")!=="b742b1751f319892081418ffcb408df4253452953992ebe98f7bebed9796288f")throw new Error("docs data file docs-bundle.bin beside this module is not the one built with it");return JSON.parse((0,import_node_zlib.gunzipSync)(packed).toString("utf8"))}function loadDocsIndex(){const packed=(0,import_node_fs7.readFileSync)((0,import_node_path3.join)(__dirname,"docs-index.bin"));if(packed.length!==437017||(0,import_node_crypto13.createHash)("sha256").update(packed).digest("hex")!=="9e814f93b292f5af1c4fee1ce09abbbebb6e80f19dc912987020f20e8129dfe3")throw new Error("docs data file docs-index.bin beside this module is not the one built with it");return(0,import_node_zlib.gunzipSync)(packed)}var TOKEN=/[a-z0-9_$.#>*-]+/gi;var EDGE=/^[.>*#-]+|[.>*#-]+$/g;function tokenize(s){const raw=s.toLowerCase().match(TOKEN);if(!raw)return[];const out=[];for(const r of raw){if(r.length>=2)out.push(r);const t=r.replace(EDGE,"");if(t.length>=2&&t!==r)out.push(t);if(t.includes(".")){for(const seg of t.split("."))if(seg.length>=2)out.push(seg)}}return out}var STOP=new Set("a an and are as at be by do for from has how in is it of on or that the this to use using was what when where which who with you your".split(" "));function decodeIndex(bytes,bodyLengths,version2){if(bytes.length<4)throw new Error("docs index is truncated or malformed");const headerLength=bytes.readUInt32LE(0);if(4+headerLength>bytes.length)throw new Error("docs index is truncated or malformed");const header=JSON.parse(bytes.toString("utf8",4,4+headerLength));if(header.version!==version2||header.bodyLengths.length!==bodyLengths.length||header.bodyLengths.some((length2,i)=>length2!==bodyLengths[i]))throw new Error("docs index does not match the docs bundle it is searching");const n=header.sections;const length=4*n+header.terms.length+1+2*header.postings;if(bytes.length-4-headerLength!==4*length)throw new Error("docs index is truncated or malformed");const columns=new Uint32Array(length);for(let i=0;i<length;i++)columns[i]=bytes.readUInt32LE(4+headerLength+4*i);const offsets=4*n;const sectionColumn=offsets+header.terms.length+1;let total=0;for(let i=0;i<n;i++)total+=columns[3*n+i];return{sections:n,terms:header.terms,headings:header.headings,source:columns.subarray(0,n),start:columns.subarray(n,2*n),end:columns.subarray(2*n,3*n),length:columns.subarray(3*n,4*n),offsets:columns.subarray(offsets,sectionColumn),postSection:columns.subarray(sectionColumn,sectionColumn+header.postings),postWeight:columns.subarray(sectionColumn+header.postings),avgdl:total/Math.max(1,n)}}var indexed;function metadata(){return indexed??=loadDocsMetadata()}var bundled;function bundle(){return bundled??=loadDocsBundle()}var REMOTE_BASE="https://docs.cotal.ai";function resolvePage(page){const key=page.trim().toLowerCase().replace(/\.md$/,"");if(key==="spec")return{slug:"spec",title:bundle().spec.title,kind:"normative",category:"normative",summary:"",body:bundle().spec.body};if(key==="lang"||key==="cotal-lang")return{slug:"lang",title:bundle().lang.title,kind:"normative",category:"normative",summary:"",body:bundle().lang.body};if(key==="schema")return{slug:"schema",title:bundle().schema.title,kind:"reference",category:"reference",summary:"",body:bundle().schema.body};return bundle().pages.find(p=>p.slug===key)}function remoteUrl(slug){const base=`${REMOTE_BASE}/v/${bundle().version}`;if(slug==="schema")return`${base}/cotal.schema.json`;if(slug==="lang")return`${base}/cotal-lang.md`;return`${base}/${slug}.md`}function renderDocsIndex(){const b=metadata();const rows=b.pages.map(p=>{const kind=p.kind?`: ${p.kind}`:"";return`- \`${p.slug}\`${kind}
|
|
128
128
|
${p.summary}`});return[`# Cotal v${b.version} documentation`,"","The authoritative docs bundled with this installed version. This index lists what","exists; it holds no answers itself. Your next call:",'- Know the page? Read it in full: `cotal_docs(page: "<slug>")` (e.g. "spec", "architecture").','- Not sure which page? Search: `cotal_docs(query: "\u2026")` returns the most relevant sections.',"Prefer these docs over training memory, and read the full page before writing code or wire","frames. Docs are bundled and version-exact; add `refresh: true` to also pull any patches","published to docs.cotal.ai for this same version.","","## The normative sources",`- \`spec\`: ${b.spec.title} (the wire contract; where a page disagrees, the spec wins)`,`- \`lang\`: ${b.lang.title} (the workflow language a durable run executes; spec \xA714)`,`- \`schema\`: ${b.schema.title} (authoritative for message shapes)`,"","## Pages",...rows].join("\n")}function renderPage(p,note){return`${note}
|
|
129
129
|
|
|
130
130
|
${p.body}`.trimStart()}var K1=1.2;var B=.75;function sources(){const b=bundle();return[...b.pages,{slug:"spec",...b.spec},{slug:"lang",...b.lang},{slug:"schema",...b.schema}]}var index;function searchIndex(){return index??=decodeIndex(loadDocsIndex(),sources().map(source=>source.body.length),DOCS_VERSION)}function termId(terms,term){let low=0;let high=terms.length-1;while(low<=high){const mid=low+high>>>1;const candidate2=terms[mid];if(candidate2===term)return mid;if(candidate2<term)low=mid+1;else high=mid-1}return-1}function searchDocs(query,limit=5){if(limit<=0)return[];let terms=tokenize(query).filter(t=>!STOP.has(t));if(!terms.length)terms=tokenize(query);const termSet=new Set(terms);if(!termSet.size)return[];const idx=searchIndex();const N=idx.sections;const scores=new Float64Array(N);for(const t of termSet){const id2=termId(idx.terms,t);if(id2<0)continue;const from=idx.offsets[id2];const to=idx.offsets[id2+1];const n=to-from;const idf=Math.log(1+(N-n+.5)/(n+.5));for(let p=from;p<to;p++){const s=idx.postSection[p];const f=idx.postWeight[p];scores[s]+=idf*(f*(K1+1)/(f+K1*(1-B+B*idx.length[s]/idx.avgdl)))}}const scored=[];for(let s=0;s<N;s++)if(scores[s]>0)scored.push({s,score:scores[s]});scored.sort((a,b)=>b.score-a.score);const all=sources();const perPage=new Map;const hits=[];for(const{s,score}of scored){const source=all[idx.source[s]];const seen=perPage.get(source.slug)??0;if(seen>=2)continue;perPage.set(source.slug,seen+1);hits.push({slug:source.slug,pageTitle:source.title,heading:idx.headings[s],text:source.body.slice(idx.start[s],idx.end[s]),score});if(hits.length>=limit)break}return hits}function capSection(text2,maxLines=48){const lines=text2.split("\n");if(lines.length<=maxLines)return text2.trim();return lines.slice(0,maxLines).join("\n").trimEnd()+"\n\n\u2026 (section continues; read the full page)"}function renderSearch(query,hits){if(!hits.length){return`No matches for "${query}" in the Cotal v${bundle().version} docs. Call cotal_docs() for the page index, or search an exact identifier (a subject, a cotal_* tool, a field name).`}const blocks=hits.map(h=>`## ${h.heading}
|