@zibby/cli 0.2.1 → 0.4.0
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/README.md +117 -16
- package/dist/bin/zibby.js +3 -3
- package/dist/commands/chat-agents.js +1 -1
- package/dist/commands/chat.js +62 -62
- package/dist/commands/credentials-api.js +1 -1
- package/dist/commands/credentials-file.js +1 -1
- package/dist/commands/creds.js +1 -1
- package/dist/commands/init.js +180 -82
- package/dist/commands/memory.js +48 -20
- package/dist/commands/run.js +52 -55
- package/dist/commands/template.js +9 -0
- package/dist/commands/uninstall.js +15 -14
- package/dist/commands/workflows/agent-helpers.js +7 -7
- package/dist/commands/workflows/generate.js +54 -32
- package/dist/commands/workflows/run-local.js +19 -19
- package/dist/commands/workflows/run.js +5 -5
- package/dist/commands/workflows/start.js +12 -12
- package/dist/package.json +2 -2
- package/dist/templates/zibby-workflow-claude/agents-md-block.md +65 -5
- package/dist/templates/zibby-workflow-claude/claude/agents/zibby-test-author.md +16 -1
- package/dist/templates/zibby-workflow-claude/claude/agents/zibby-workflow-builder.md +22 -2
- package/dist/templates/zibby-workflow-claude/claude/commands/zibby-add-node.md +1 -1
- package/dist/templates/zibby-workflow-claude/claude/commands/zibby-debug.md +1 -1
- package/dist/templates/zibby-workflow-claude/claude/commands/zibby-delete.md +1 -1
- package/dist/templates/zibby-workflow-claude/claude/commands/zibby-deploy.md +24 -14
- package/dist/templates/zibby-workflow-claude/claude/commands/zibby-list.md +2 -2
- package/dist/templates/zibby-workflow-claude/claude/commands/zibby-memory-cost.md +39 -0
- package/dist/templates/zibby-workflow-claude/claude/commands/zibby-memory-pull.md +47 -0
- package/dist/templates/zibby-workflow-claude/claude/commands/zibby-memory-remote-use-hosted.md +61 -0
- package/dist/templates/zibby-workflow-claude/claude/commands/zibby-memory-stats.md +38 -0
- package/dist/templates/zibby-workflow-claude/claude/commands/zibby-static-ip.md +8 -6
- package/dist/templates/zibby-workflow-claude/claude/commands/zibby-tail.md +1 -1
- package/dist/templates/zibby-workflow-claude/claude/commands/zibby-test-debug.md +2 -2
- package/dist/templates/zibby-workflow-claude/claude/commands/zibby-test-generate.md +1 -1
- package/dist/templates/zibby-workflow-claude/claude/commands/zibby-test-run.md +3 -2
- package/dist/templates/zibby-workflow-claude/claude/commands/zibby-test-write.md +1 -1
- package/dist/templates/zibby-workflow-claude/claude/commands/zibby-trigger.md +10 -6
- package/dist/templates/zibby-workflow-claude/cursor/rules/zibby-workflows.mdc +76 -13
- package/dist/templates/zibby-workflow-claude/manifest.json +5 -1
- package/dist/utils/agent-credentials.js +4 -3
- package/dist/utils/apply-memory-sync-config.js +1 -0
- package/dist/utils/credentials-loader.js +1 -1
- package/dist/utils/hosted-memory-sync.js +1 -0
- package/package.json +2 -2
package/dist/commands/chat.js
CHANGED
|
@@ -1,92 +1,92 @@
|
|
|
1
|
-
var
|
|
2
|
-
`,"utf8")}function
|
|
3
|
-
`,"utf8")}function Sn(t){let e=Number(t);if(!Number.isFinite(e)||e<=0)return[];try{let o=go(`pgrep -P ${e}`,{encoding:"utf8",stdio:["ignore","pipe","ignore"],maxBuffer:524288}).trim();return o?o.split(/\n/).map(n=>parseInt(n.trim(),10)).filter(n=>Number.isFinite(n)&&n>0):[]}catch{return[]}}function po(t,e){let o=Number(t);if(!Number.isFinite(o)||o<=0)return;let n=new Set;function r(s){if(!n.has(s)){n.add(s);for(let a of Sn(s))r(a);try{process.kill(s,e)}catch{}}}r(o)}function xn(t){let e=Number(t);if(!(!Number.isFinite(e)||e<=0))try{go(`taskkill /PID ${e} /T /F`,{stdio:"ignore",windowsHide:!0})}catch{}}function mo(t){let e=Number(t);if(!Number.isFinite(e)||e<=0)return;if(process.platform==="win32"){xn(e);return}po(e,"SIGTERM");let o=setTimeout(()=>{po(e,"SIGKILL")},800);typeof o.unref=="function"&&o.unref()}function _n(t,e,o={}){let n=Number(e);if(!Number.isFinite(n)||n<=0)return;let r=Je(o),s=Ke(t,r,n),a=ft(t,r,n);for(let c of a)c!==process.pid&&mo(c);try{dt(s)&&pt(s)}catch{}}function $n(t){try{return process.kill(t,0),!0}catch{return!1}}function kn(t,e={}){let o=Je(e),n=Ze(t,o),r;try{r=hn(n)}catch{return}for(let s of r){let a=vn.exec(s);if(!a)continue;let c=Number(a[1]);if(!(!Number.isFinite(c)||c<=0)&&!$n(c))try{pt(Ze(n,s))}catch{}}}var vn,mt=ve(()=>{vn=/^\.zibby-chat-run-pids-(\d+)\.json$/});var yo={};ke(yo,{addCredential:()=>ho,deleteCredential:()=>Cn,listCredentials:()=>An,syncFromLocal:()=>In});function ht(t,e=""){return`${String(t).replace(/\/+$/,"")}/agents/credentials${e}`}function yt(){let t=new Error("Session expired \u2014 run zibby login");return t.code="AUTH_EXPIRED",t}async function An({apiUrl:t,sessionToken:e}){if(!e)return{credentials:[],by_type:{oauth:[],api:[]},total:0};let o=await fetch(ht(t),{headers:{Authorization:`Bearer ${e}`}});if(o.status===401)throw yt();if(o.status===404)return{credentials:[],by_type:{oauth:[],api:[]},total:0};if(!o.ok){let n=new Error(`List credentials failed (${o.status})`);throw n.status=o.status,n}return o.json()}async function ho({apiUrl:t,sessionToken:e,type:o,token:n,source:r="~/.zibby/credentials.env"}){if(!e)throw new Error("No session token \u2014 run zibby login first");let s=await fetch(ht(t),{method:"POST",headers:{Authorization:`Bearer ${e}`,"Content-Type":"application/json"},body:JSON.stringify({type:o,token:n,source:r})});if(s.status===401)throw yt();if(!s.ok){let a=`Add credential failed (${s.status})`;try{let l=await s.json();l?.error&&(a=`${a}: ${l.error}`)}catch{}let c=new Error(a);throw c.status=s.status,c}return s.json()}async function Cn({apiUrl:t,sessionToken:e,type:o,index:n}){if(!e)throw new Error("No session token \u2014 run zibby login first");let r=await fetch(ht(t,`/${encodeURIComponent(o)}/${encodeURIComponent(n)}`),{method:"DELETE",headers:{Authorization:`Bearer ${e}`}});if(r.status===401)throw yt();if(!r.ok){let s=new Error(`Delete credential failed (${r.status})`);throw s.status=r.status,s}return r.json()}async function In({apiUrl:t,sessionToken:e,credentials:o}){let n=0,r=0,s=[];for(let a of o)try{let c=await ho({apiUrl:t,sessionToken:e,type:a.type,token:a.token,source:a.source_var||a.source||"local"});c.deduped?r+=1:c.added&&(n+=1)}catch(c){s.push({masked:a.token?`***${a.token.slice(-4)}`:"***",error:c.message})}return{added:n,deduped:r,errors:s}}var bo=ve(()=>{});var $o={};ke($o,{AGENTS:()=>Le,deleteAgentSession:()=>Ln,fetchMyAgentSessions:()=>xo,formatRelativeTime:()=>_o,handleClaudeCodeAddon:()=>En,pickAgent:()=>Pn,pickAgentWithSessions:()=>Tn,upsertAgentSession:()=>Rn});import{select as So,confirm as bt,Separator as wo}from"@inquirer/prompts";import u from"chalk";async function Tn({apiUrl:t,sessionToken:e,currentAgentId:o="zibby"}={}){let n;try{n=await xo({apiUrl:t,sessionToken:e})}catch(s){if(/login/i.test(s.message))throw s;console.warn(u.gray(` (could not fetch sessions: ${s.message})`)),n=[]}let r=[];if(n.length>0){for(let s of n){let c=Le.find(A=>A.id===s.agent_type)?.name||s.agent_type,l=_o(s.last_active),f=typeof s.message_count=="number"&&s.message_count>0?u.gray(` \xB7 ${s.message_count} msg`):"",N=s.label?u.gray(` \xB7 "${s.label}"`):"";r.push({name:`${u.cyan("\u2726")} ${c} ${u.gray(`(${l})`)}${N}${f}`,value:{action:"resume",agentType:s.agent_type,sessionId:s.session_id,session:s},description:u.gray(` Resume your ${c} session`)})}r.push(new wo)}for(let s of Le)s.id!=="zibby"&&r.push({name:`${u.dim("+")} New ${s.name} session${s.pricePerMonth>0?u.yellow(` (+$${s.pricePerMonth}/mo)`):""}`,value:{action:"create",agentType:s.id},description:u.gray(` ${s.description}`)});r.push(new wo),r.push({name:`${u.green("\u2190")} Back to Zibby Chat (default)${o==="zibby"?u.dim(" [current]"):""}`,value:{action:"switch",agentType:"zibby"},description:u.gray(" Built-in chat using Anthropic SDK directly")});try{return await So({message:"Select chat agent:",choices:r})}catch(s){if(s?.name==="ExitPromptError")return{action:"cancel"};throw s}}async function Pn(t="zibby"){let e=await So({message:"Select chat agent for this workspace:",default:t,choices:Le.map(o=>{let n=o.pricePerMonth===0?u.green(" (included)"):u.yellow(` (+$${o.pricePerMonth}/mo)`),r=o.id===t?u.dim(" [current]"):"";return{name:`${o.name}${n}${r}`,value:o.id,description:u.gray(` ${o.description}`)}})});return Le.find(o=>o.id===e)}async function En({workspaceId:t,sessionToken:e,apiUrl:o}){let n=await On({addon:"claude-code",workspaceId:t,sessionToken:e,apiUrl:o});if(n.configured&&n.sandboxState==="ready")return console.log(""),console.log(u.green(" \u2713 Claude Code is already deployed for your team.")),console.log(u.gray(` Sandbox: ${n.sandboxId} \xB7 state: ${n.sandboxState}`)),console.log(""),{ready:!0,sandboxId:n.sandboxId};if(n.configured&&n.sandboxState!=="ready")return console.log(""),console.log(u.cyan(` \u2699 Claude Code sandbox is ${n.sandboxState}...`)),console.log(u.gray(" You can keep using Zibby Chat \u2014 we'll switch when it's ready.")),console.log(""),{ready:!1,provisioning:!0,sandboxId:n.sandboxId};if(console.log(""),console.log(u.yellow(" Claude Code add-on is not enabled for your workspace.")),console.log(""),console.log(u.white(" About this add-on:")),console.log(u.gray(" \u2022 Anthropic's official Claude Code CLI runs in YOUR isolated sandbox")),console.log(u.gray(" \u2022 YOU provide your own Anthropic credentials (in ~/.zibby/credentials.env)")),console.log(u.gray(" \u2022 Zibby NEVER accesses Anthropic on your behalf \u2014 your tokens, your API calls")),console.log(u.gray(" \u2022 Zibby stores credentials KMS-encrypted, decrypts only inside YOUR sandbox")),console.log(u.gray(" \u2022 You're responsible for ToS compliance with the credentials you provide:")),console.log(u.gray(" https://www.anthropic.com/legal/commercial-terms")),console.log(""),console.log(u.cyan(" Pricing:")),console.log(u.white(" $20 / month per workspace ")+u.gray("\xB7 Zibby infrastructure fee, billed via Stripe")),console.log(u.gray(" Your Anthropic usage bills directly to your Anthropic account")),console.log(""),!await bt({message:"Do you agree to Anthropic's Commercial Terms of Service?",default:!1}))return console.log(u.gray(" Cancelled. Continuing with Zibby Chat (default).")),console.log(""),{ready:!1,cancelled:!0};if(!await bt({message:"Enable Claude Code add-on at $20/month?",default:!1}))return console.log(u.gray(" Cancelled. Continuing with Zibby Chat (default).")),console.log(""),{ready:!1,cancelled:!0};console.log(""),console.log(u.cyan(" Enabling Claude Code add-on..."));let a;try{a=await Un({addon:"claude-code",workspaceId:t,sessionToken:e,apiUrl:o,accept:{tos:!0,billing:!0}})}catch(c){if(c?.code==="BILLING_REQUIRED"){console.log("");let l=c.upgradeUrl?.startsWith("http")?c.upgradeUrl:"https://zibby.dev/billing";return c.needsSubscription?(console.log(u.yellow(" \u26A0 You need an active Pro subscription to enable Claude Code.")),console.log(u.gray(` Upgrade here: ${l}`))):c.needsPaymentMethod?(console.log(u.yellow(" \u26A0 Your card was declined or no payment method is on file.")),console.log(u.gray(` Update billing: ${l}`))):(console.log(u.yellow(` \u26A0 ${c.message}`)),console.log(u.gray(` Manage billing: ${l}`))),console.log(""),console.log(u.gray(" Continuing with Zibby Chat (default).")),console.log(""),{ready:!1,cancelled:!0,billingRequired:!0}}throw c}return console.log(""),console.log(u.green(" \u2713 Stripe subscription created")),console.log(u.gray(` sub_id: ${a.subscriptionId}`)),console.log(u.green(" \u2713 Lambda invoked: zibby-prod-provision-sandbox")),console.log(u.gray(` request: ${a.requestId}`)),console.log(u.cyan(" \u2699 Fargate task launching: zibby/agent-runtime:claude-code-v1")),console.log(u.gray(` sandbox_id: ${a.sandboxId}`)),console.log(""),await Nn({apiUrl:o,sessionToken:e}),console.log(""),console.log(u.gray(" Sandbox provisioning in the background. Zibby Chat (default) is active until ready.")),console.log(""),{ready:!1,provisioning:!0,sandboxId:a.sandboxId,deploymentId:a.requestId}}async function Nn({apiUrl:t,sessionToken:e}){let o;try{let{discoverCredentials:s}=await Promise.resolve().then(()=>(ut(),co));o=await s()}catch(s){console.log(u.gray(` (could not scan local credentials: ${s.message})`));return}let n=o.all.length;if(n===0){console.log(u.yellow(" \u26A0 No Anthropic credentials found locally.")),console.log(""),console.log(u.white(" Two ways to authenticate Claude Code in your sandbox:")),console.log(""),console.log(u.bold(" Option A \u2014 provide your own (recommended):")),console.log(u.gray(" 1. Create ~/.zibby/credentials.env with:")),console.log(u.gray(" CLAUDE_CODE_OAUTH_TOKEN=<your-token>")),console.log(u.gray(" 2. Run: zibby creds sync")),console.log(u.gray(" 3. Re-run /agents in chat")),console.log(""),console.log(u.bold(" Option B \u2014 in-sandbox login (legacy):")),console.log(u.gray(" Skip this step. When sandbox is ready and you start")),console.log(u.gray(" Claude Code, it will prompt you to open a URL in your")),console.log(u.gray(" laptop browser to authenticate.")),console.log("");return}console.log(u.green(` \u2713 Found ${n} Anthropic ${n===1?"credential":"credentials"} in your local environment:`));for(let s of o.all){let a=s.source==="file"?`~/.zibby/credentials.env (${s.source_var})`:`process.env.${s.source_var}`;console.log(u.gray(` ${s.type} ***${s.token.slice(-4)} ${a}`))}if(console.log(""),console.log(u.white(" By proceeding you confirm:")),console.log(u.gray(" \u2022 These are YOUR credentials to use")),console.log(u.gray(" \u2022 You comply with Anthropic's ToS for the tier of these tokens")),console.log(u.gray(" \u2022 Zibby will store encrypted (AWS KMS) and inject into YOUR sandbox only")),console.log(""),!await bt({message:"Upload these credentials to your Zibby workspace?",default:!0})){console.log(u.gray(" Skipped credential upload. Sandbox will fall back to in-sandbox login."));return}console.log(""),console.log(u.cyan(" Uploading (KMS-encrypted)..."));try{let{syncFromLocal:s}=await Promise.resolve().then(()=>(bo(),yo)),a=await s({apiUrl:t,sessionToken:e,credentials:o.all});console.log(u.green(` \u2713 ${a.added} new, ${a.deduped} already stored`)),a.errors.length>0&&console.log(u.yellow(` ${a.errors.length} failed \u2014 retry with 'zibby creds sync'`))}catch(s){console.log(u.red(` \u2717 Upload failed: ${s.message}`)),console.log(u.gray(" Sandbox will fall back to in-sandbox login when ready."))}}async function On({addon:t,sessionToken:e,apiUrl:o}){let n=process.env.ZIBBY_CLAUDE_CODE_STUB_STATUS;if(n==="ready")return{configured:!0,sandboxState:"ready",sandboxId:"sb_stub_acme_001"};if(n==="provisioning")return{configured:!0,sandboxState:"provisioning",sandboxId:"sb_stub_acme_001"};if(!o||!e)return{configured:!1,sandboxState:null,sandboxId:null};let r=`${String(o).replace(/\/+$/,"")}/agents/addons/${encodeURIComponent(t)}`,s;try{s=await fetch(r,{headers:{Authorization:`Bearer ${e}`}})}catch{return{configured:!1,sandboxState:null,sandboxId:null}}if(s.status===401){let c=new Error("Session expired \u2014 run zibby login");throw c.code="AUTH_EXPIRED",c}if(s.status===404)return{configured:!1,sandboxState:null,sandboxId:null};if(!s.ok)return{configured:!1,sandboxState:null,sandboxId:null};let a=await s.json();return{configured:!!a.configured,sandboxState:a.sandbox_state||null,sandboxId:a.sandbox_id||null,subscriptionId:a.subscription_id||null,enabledAt:a.enabled_at||null}}async function Un({addon:t,workspaceId:e,sessionToken:o,apiUrl:n}){if(!n||!o)return await new Promise(c=>setTimeout(c,500)),{subscriptionId:`sub_${Math.random().toString(36).slice(2,10)}`,sandboxId:`sb_${Math.random().toString(36).slice(2,10)}`,requestId:`req_offline_${Date.now().toString(36)}`};let r=`${String(n).replace(/\/+$/,"")}/agents/addons/${encodeURIComponent(t)}/enable`,s=await fetch(r,{method:"POST",headers:{Authorization:`Bearer ${o}`,"Content-Type":"application/json"},body:JSON.stringify({workspace_id:e||null})});if(s.status===401){let c=new Error("Session expired \u2014 run zibby login");throw c.code="AUTH_EXPIRED",c}if(s.status===402){let c;try{c=await s.json()}catch{c={}}let l;try{l=typeof c.error=="string"?JSON.parse(c.error):c.error||c}catch{l={message:c.error||"Payment required"}}let f=new Error(l.message||"Payment required");throw f.code="BILLING_REQUIRED",f.status=402,f.needsSubscription=!!l.needs_subscription,f.needsPaymentMethod=!!l.needs_payment_method,f.upgradeUrl=l.upgrade_url||"/billing",f}if(!s.ok){let c=new Error(`Enable addon failed (${s.status})`);throw c.status=s.status,c}let a=await s.json();return{subscriptionId:a.subscription_id||null,sandboxId:a.sandbox_id||null,stripeSubscriptionItemId:a.stripe_subscription_item_id||null,requestId:a.request_id||`req_${Date.now().toString(36)}`}}function wt(t,e){let o=String(t).replace(/\/+$/,"");return e?`${o}/agents/sessions/${encodeURIComponent(e)}`:`${o}/agents/sessions`}async function xo({apiUrl:t,sessionToken:e}){if(!e)return[];let o=await fetch(wt(t),{headers:{Authorization:`Bearer ${e}`}});if(o.status===401)throw new Error("Not authenticated. Run `zibby login` again.");if(o.status===404)return[];if(!o.ok){let r=await o.text().catch(()=>"");throw new Error(`Failed to list agent sessions (${o.status}): ${r.slice(0,200)}`)}let n=await o.json();return Array.isArray(n.sessions)?n.sessions:[]}async function Rn({apiUrl:t,sessionToken:e,agentType:o,fields:n={}}){if(!e)throw new Error("Not authenticated");let r=await fetch(wt(t,o),{method:"PUT",headers:{Authorization:`Bearer ${e}`,"Content-Type":"application/json"},body:JSON.stringify(n)});if(!r.ok){let a=await r.text().catch(()=>"");throw new Error(`Failed to save agent session (${r.status}): ${a.slice(0,200)}`)}return(await r.json()).session}async function Ln({apiUrl:t,sessionToken:e,agentType:o}){if(!e)throw new Error("Not authenticated");let n=await fetch(wt(t,o),{method:"DELETE",headers:{Authorization:`Bearer ${e}`}});if(!n.ok){let s=await n.text().catch(()=>"");throw new Error(`Failed to delete agent session (${n.status}): ${s.slice(0,200)}`)}return(await n.json()).deleted===!0}function _o(t){if(!t)return"never";let e=new Date(t).getTime();if(Number.isNaN(e))return"unknown";let o=Math.max(0,(Date.now()-e)/1e3);if(o<60)return"just now";let n=o/60;if(n<60)return`${Math.round(n)}m ago`;let r=n/60;if(r<24)return`${Math.round(r)}h ago`;let s=r/24;if(s<30)return`${Math.round(s)}d ago`;let a=s/30;return`${Math.round(a)}mo ago`}var Le,vo=ve(()=>{Le=[{id:"zibby",name:"Zibby Chat",short:"default",description:"Built-in chat using Anthropic SDK directly \xB7 BYOK \xB7 included with workspace",pricePerMonth:0,deployment:"instant"},{id:"claude-code",name:"Claude Code",short:"add-on",description:"Anthropic's Claude Code CLI deployed in your private sandbox",pricePerMonth:20,deployment:"fargate-warm"}]});var St={};ke(St,{attachToSession:()=>Io,spawnAgentSession:()=>Co,spawnAndAttach:()=>Mn});import ko from"ws";import Ao from"chalk";function Bn({sandboxEndpoint:t,sessionId:e,useTls:o=!1}){return`${o?"wss":"ws"}://${t}/stream/${encodeURIComponent(e)}`}async function Co({sandboxEndpoint:t,sessionToken:e,agentType:o="claude-code",args:n=[],cwd:r="/workspace",useTls:s=!1}){let c=`${s?"https":"http"}://${t}/spawn`,l=await fetch(c,{method:"POST",headers:{Authorization:`Bearer ${e}`,"Content-Type":"application/json"},body:JSON.stringify({agent_type:o,args:n,cwd:r})});if(!l.ok){let N=await l.text().catch(()=>"");throw new Error(`spawn failed (${l.status}): ${N}`)}return await l.json()}async function Io({sandboxEndpoint:t,sessionId:e,sessionToken:o,useTls:n=!1,showBanner:r=!0}){let s=Bn({sandboxEndpoint:t,sessionId:e,useTls:n}),a=new ko(s,{headers:{Authorization:`Bearer ${o}`}});return new Promise((c,l)=>{let f=!1,N=!1,A=null,Y=null,J=v=>{if(!f){f=!0;try{process.stdin.isTTY&&process.stdin.setRawMode&&process.stdin.setRawMode(N)}catch{}A&&process.stdin.off("data",A),Y&&process.stdout.off("resize",Y);try{process.stdin.pause()}catch{}try{a.close()}catch{}c(v)}};a.on("open",()=>{r&&(process.stdout.write(Ao.green(`
|
|
1
|
+
var Go=Object.defineProperty;var $e=(t,e)=>()=>(t&&(e=t(t=0)),e);var ve=(t,e)=>{for(var o in e)Go(t,o,{get:e[o],enumerable:!0})};var so={};ve(so,{_resetLoaderCacheForTests:()=>mn,loadCredentialsIntoEnv:()=>gn});import oo from"node:fs";import ln from"node:path";import un from"node:os";async function no(){if(!(process.env.__ZIBBY_CLAUDE_PLAN||process.platform!=="darwin"||!(process.env.CLAUDE_CODE_OAUTH_TOKEN||process.env.CLAUDE_CODE_OAUTH_TOKEN_POOL||process.env.ANTHROPIC_AUTH_TOKEN)))try{let{execSync:e}=await import("node:child_process"),o=e('security find-generic-password -s "Claude Code-credentials" -w',{encoding:"utf-8",stdio:["ignore","pipe","ignore"]}).trim();if(o){let r=JSON.parse(o)?.claudeAiOauth?.subscriptionType;r&&(process.env.__ZIBBY_CLAUDE_PLAN=r)}}catch{}}function fn(t){try{if(!oo.existsSync(t))return{};let e=oo.readFileSync(t,"utf-8"),o=JSON.parse(e);return o&&o.agentKeys&&typeof o.agentKeys=="object"?o.agentKeys:{}}catch{return{}}}async function gn(t={}){let{verbose:e=!1,force:o=!1,configPath:n}=t;if(Ze&&!o)return Ae;if(!!(process.env.CLAUDE_CODE_OAUTH_TOKEN_POOL||process.env.ANTHROPIC_API_KEY_POOL||process.env.CLAUDE_CODE_OAUTH_TOKEN||process.env.ANTHROPIC_API_KEY||process.env.ANTHROPIC_AUTH_TOKEN))return await no(),Ze=!0,Ae={oauthCount:0,apiCount:0,source:"cloud-env"},e&&console.log("[credentials-loader] env vars already set \u2014 skipping local discovery"),Ae;let s=n||ln.join(un.homedir(),".zibby","config.json"),a=fn(s),c="none",l=0,p=0;for(let $ of dn)a[$]&&!process.env[$]&&(process.env[$]=String(a[$]).trim(),c="config.json",$.endsWith("_POOL")?l+=String(a[$]).split(",").filter(z=>z.trim()).length:l+=1);for(let $ of pn)a[$]&&!process.env[$]&&(process.env[$]=String(a[$]).trim(),c="config.json",$.endsWith("_POOL")?p+=String(a[$]).split(",").filter(z=>z.trim()).length:p+=1);return await no(),Ze=!0,Ae={oauthCount:l,apiCount:p,source:c},e&&l+p>0&&console.log(`[credentials-loader] loaded ${l} OAuth + ${p} API from ${c} (~/.zibby/config.json)`),Ae}function mn(){Ze=!1,Ae=null}var Ze,Ae,dn,pn,ro=$e(()=>{Ze=!1,Ae=null,dn=["CLAUDE_CODE_OAUTH_TOKEN","CLAUDE_CODE_OAUTH_TOKEN_POOL","ANTHROPIC_AUTH_TOKEN","ANTHROPIC_AUTH_TOKEN_POOL"],pn=["ANTHROPIC_API_KEY","ANTHROPIC_API_KEY_POOL"]});var pt={};ve(pt,{cleanupStalePidFiles:()=>kn,killAllChatOrchestratedRuns:()=>vn,killPidTreeBestEffort:()=>lo,registerChatOrchestratedRun:()=>_n,unregisterChatOrchestratedRun:()=>Sn});import{existsSync as lt,mkdirSync as hn,readFileSync as yn,readdirSync as bn,unlinkSync as ut,writeFileSync as ao}from"fs";import{join as Ke}from"path";import{execSync as co}from"child_process";import{DEFAULT_OUTPUT_BASE as wn}from"@zibby/core";function We(t){return t?.paths?.output||wn}function Je(t,e,o){return Ke(t,e,`.zibby-chat-run-pids-${o}.json`)}function dt(t,e,o){let n=Je(t,e,o);if(!lt(n))return[];try{let r=JSON.parse(yn(n,"utf8"));return(Array.isArray(r?.pids)?r.pids:[]).map(a=>Number(a)).filter(a=>Number.isFinite(a)&&a>0)}catch{return[]}}function _n(t,e,o,n={}){let r=Number(e),s=Number(o);if(!Number.isFinite(r)||r<=0||!Number.isFinite(s)||s<=0)return;let a=We(n),c=Ke(t,a);hn(c,{recursive:!0});let l=dt(t,a,r);l.includes(s)||l.push(s),ao(Je(t,a,r),`${JSON.stringify({v:1,pids:l})}
|
|
2
|
+
`,"utf8")}function Sn(t,e,o,n={}){let r=Number(e),s=Number(o);if(!Number.isFinite(r)||r<=0||!Number.isFinite(s)||s<=0)return;let a=We(n),c=Je(t,a,r);if(!lt(c))return;let l=dt(t,a,r).filter(p=>p!==s);if(l.length===0)try{ut(c)}catch{}else ao(c,`${JSON.stringify({v:1,pids:l})}
|
|
3
|
+
`,"utf8")}function xn(t){let e=Number(t);if(!Number.isFinite(e)||e<=0)return[];try{let o=co(`pgrep -P ${e}`,{encoding:"utf8",stdio:["ignore","pipe","ignore"],maxBuffer:524288}).trim();return o?o.split(/\n/).map(n=>parseInt(n.trim(),10)).filter(n=>Number.isFinite(n)&&n>0):[]}catch{return[]}}function io(t,e){let o=Number(t);if(!Number.isFinite(o)||o<=0)return;let n=new Set;function r(s){if(!n.has(s)){n.add(s);for(let a of xn(s))r(a);try{process.kill(s,e)}catch{}}}r(o)}function $n(t){let e=Number(t);if(!(!Number.isFinite(e)||e<=0))try{co(`taskkill /PID ${e} /T /F`,{stdio:"ignore",windowsHide:!0})}catch{}}function lo(t){let e=Number(t);if(!Number.isFinite(e)||e<=0)return;if(process.platform==="win32"){$n(e);return}io(e,"SIGTERM");let o=setTimeout(()=>{io(e,"SIGKILL")},800);typeof o.unref=="function"&&o.unref()}function vn(t,e,o={}){let n=Number(e);if(!Number.isFinite(n)||n<=0)return;let r=We(o),s=Je(t,r,n),a=dt(t,r,n);for(let c of a)c!==process.pid&&lo(c);try{lt(s)&&ut(s)}catch{}}function An(t){try{return process.kill(t,0),!0}catch{return!1}}function kn(t,e={}){let o=We(e),n=Ke(t,o),r;try{r=bn(n)}catch{return}for(let s of r){let a=Cn.exec(s);if(!a)continue;let c=Number(a[1]);if(!(!Number.isFinite(c)||c<=0)&&!An(c))try{ut(Ke(n,s))}catch{}}}var Cn,ft=$e(()=>{Cn=/^\.zibby-chat-run-pids-(\d+)\.json$/});var mo={};ve(mo,{DEFAULT_CONFIG_PATH:()=>uo,discoverCredentials:()=>En,maskToken:()=>On,parseConfigJson:()=>fo,readCredentialsConfig:()=>go});import In from"node:fs/promises";import Tn from"node:path";import Pn from"node:os";function fo(t){if(!t)return[];let e;try{e=JSON.parse(t)}catch{return[]}let o=e?.agentKeys;if(!o||typeof o!="object")return[];let n=[],r=new Set;for(let[s,a]of Object.entries(po)){let c=o[s];if(!c||typeof c!="string")continue;let l=s.endsWith("_POOL")?c.split(",").map(p=>p.trim()).filter(Boolean):[c.trim()];for(let p of l)p.length<8||r.has(p)||(r.add(p),n.push({type:a,token:p,source_var:s}))}return n}async function go(t=uo){let e;try{e=await In.readFile(t,"utf8")}catch(o){if(o.code==="ENOENT")return[];throw o}return fo(e)}async function En({filepath:t,env:e=process.env}={}){let o=await go(t),n=new Set(o.map(s=>s.token)),r=[];for(let[s,a]of Object.entries(po)){let c=e[s];if(!c)continue;let l=s.endsWith("_POOL")?c.split(",").map(p=>p.trim()).filter(Boolean):[c];for(let p of l)p.length<8||n.has(p)||(n.add(p),r.push({type:a,token:p,source_var:s,source:"process.env"}))}return{config:o.map(s=>({...s,source:"config.json"})),env:r,all:[...o.map(s=>({...s,source:"config.json"})),...r]}}function On(t){return!t||typeof t!="string"||t.length<=4?"***":`***${t.slice(-4)}`}var uo,po,ho=$e(()=>{uo=Tn.join(Pn.homedir(),".zibby","config.json"),po={CLAUDE_CODE_OAUTH_TOKEN:"oauth",CLAUDE_CODE_OAUTH_TOKEN_POOL:"oauth",ANTHROPIC_AUTH_TOKEN:"oauth",ANTHROPIC_API_KEY:"api",ANTHROPIC_API_KEY_POOL:"api"}});var bo={};ve(bo,{addCredential:()=>yo,deleteCredential:()=>Un,listCredentials:()=>Nn,syncFromLocal:()=>Ln});function gt(t,e=""){return`${String(t).replace(/\/+$/,"")}/agents/credentials${e}`}function mt(){let t=new Error("Session expired \u2014 run zibby login");return t.code="AUTH_EXPIRED",t}async function Nn({apiUrl:t,sessionToken:e}){if(!e)return{credentials:[],by_type:{oauth:[],api:[]},total:0};let o=await fetch(gt(t),{headers:{Authorization:`Bearer ${e}`}});if(o.status===401)throw mt();if(o.status===404)return{credentials:[],by_type:{oauth:[],api:[]},total:0};if(!o.ok){let n=new Error(`List credentials failed (${o.status})`);throw n.status=o.status,n}return o.json()}async function yo({apiUrl:t,sessionToken:e,type:o,token:n,source:r="~/.zibby/config.json"}){if(!e)throw new Error("No session token \u2014 run zibby login first");let s=await fetch(gt(t),{method:"POST",headers:{Authorization:`Bearer ${e}`,"Content-Type":"application/json"},body:JSON.stringify({type:o,token:n,source:r})});if(s.status===401)throw mt();if(!s.ok){let a=`Add credential failed (${s.status})`;try{let l=await s.json();l?.error&&(a=`${a}: ${l.error}`)}catch{}let c=new Error(a);throw c.status=s.status,c}return s.json()}async function Un({apiUrl:t,sessionToken:e,type:o,index:n}){if(!e)throw new Error("No session token \u2014 run zibby login first");let r=await fetch(gt(t,`/${encodeURIComponent(o)}/${encodeURIComponent(n)}`),{method:"DELETE",headers:{Authorization:`Bearer ${e}`}});if(r.status===401)throw mt();if(!r.ok){let s=new Error(`Delete credential failed (${r.status})`);throw s.status=r.status,s}return r.json()}async function Ln({apiUrl:t,sessionToken:e,credentials:o}){let n=0,r=0,s=[];for(let a of o)try{let c=await yo({apiUrl:t,sessionToken:e,type:a.type,token:a.token,source:a.source_var||a.source||"local"});c.deduped?r+=1:c.added&&(n+=1)}catch(c){s.push({masked:a.token?`***${a.token.slice(-4)}`:"***",error:c.message})}return{added:n,deduped:r,errors:s}}var wo=$e(()=>{});var vo={};ve(vo,{AGENTS:()=>Le,deleteAgentSession:()=>Yn,fetchMyAgentSessions:()=>xo,formatRelativeTime:()=>$o,handleClaudeCodeAddon:()=>Dn,pickAgent:()=>Bn,pickAgentWithSessions:()=>Rn,upsertAgentSession:()=>Fn});import{select as So,confirm as ht,Separator as _o}from"@inquirer/prompts";import u from"chalk";async function Rn({apiUrl:t,sessionToken:e,currentAgentId:o="zibby"}={}){let n;try{n=await xo({apiUrl:t,sessionToken:e})}catch(s){if(/login/i.test(s.message))throw s;console.warn(u.gray(` (could not fetch sessions: ${s.message})`)),n=[]}let r=[];if(n.length>0){for(let s of n){let c=Le.find(z=>z.id===s.agent_type)?.name||s.agent_type,l=$o(s.last_active),p=typeof s.message_count=="number"&&s.message_count>0?u.gray(` \xB7 ${s.message_count} msg`):"",$=s.label?u.gray(` \xB7 "${s.label}"`):"";r.push({name:`${u.cyan("\u2726")} ${c} ${u.gray(`(${l})`)}${$}${p}`,value:{action:"resume",agentType:s.agent_type,sessionId:s.session_id,session:s},description:u.gray(` Resume your ${c} session`)})}r.push(new _o)}for(let s of Le)s.id!=="zibby"&&r.push({name:`${u.dim("+")} New ${s.name} session${s.pricePerMonth>0?u.yellow(` (+$${s.pricePerMonth}/mo)`):""}`,value:{action:"create",agentType:s.id},description:u.gray(` ${s.description}`)});r.push(new _o),r.push({name:`${u.green("\u2190")} Back to Zibby Chat (default)${o==="zibby"?u.dim(" [current]"):""}`,value:{action:"switch",agentType:"zibby"},description:u.gray(" Built-in chat using Anthropic SDK directly")});try{return await So({message:"Select chat agent:",choices:r})}catch(s){if(s?.name==="ExitPromptError")return{action:"cancel"};throw s}}async function Bn(t="zibby"){let e=await So({message:"Select chat agent for this workspace:",default:t,choices:Le.map(o=>{let n=o.pricePerMonth===0?u.green(" (included)"):u.yellow(` (+$${o.pricePerMonth}/mo)`),r=o.id===t?u.dim(" [current]"):"";return{name:`${o.name}${n}${r}`,value:o.id,description:u.gray(` ${o.description}`)}})});return Le.find(o=>o.id===e)}async function Dn({workspaceId:t,sessionToken:e,apiUrl:o}){let n=await jn({addon:"claude-code",workspaceId:t,sessionToken:e,apiUrl:o});if(n.configured&&n.sandboxState==="ready")return console.log(""),console.log(u.green(" \u2713 Claude Code is already deployed for your team.")),console.log(u.gray(` Sandbox: ${n.sandboxId} \xB7 state: ${n.sandboxState}`)),console.log(""),{ready:!0,sandboxId:n.sandboxId};if(n.configured&&n.sandboxState!=="ready")return console.log(""),console.log(u.cyan(` \u2699 Claude Code sandbox is ${n.sandboxState}...`)),console.log(u.gray(" You can keep using Zibby Chat \u2014 we'll switch when it's ready.")),console.log(""),{ready:!1,provisioning:!0,sandboxId:n.sandboxId};if(console.log(""),console.log(u.yellow(" Claude Code add-on is not enabled for your workspace.")),console.log(""),console.log(u.white(" About this add-on:")),console.log(u.gray(" \u2022 Anthropic's official Claude Code CLI runs in YOUR isolated sandbox")),console.log(u.gray(" \u2022 YOU provide your own Anthropic credentials (in ~/.zibby/config.json)")),console.log(u.gray(" \u2022 Zibby NEVER accesses Anthropic on your behalf \u2014 your tokens, your API calls")),console.log(u.gray(" \u2022 Zibby stores credentials KMS-encrypted, decrypts only inside YOUR sandbox")),console.log(u.gray(" \u2022 You're responsible for ToS compliance with the credentials you provide:")),console.log(u.gray(" https://www.anthropic.com/legal/commercial-terms")),console.log(""),console.log(u.cyan(" Pricing:")),console.log(u.white(" $20 / month per workspace ")+u.gray("\xB7 Zibby infrastructure fee, billed via Stripe")),console.log(u.gray(" Your Anthropic usage bills directly to your Anthropic account")),console.log(""),!await ht({message:"Do you agree to Anthropic's Commercial Terms of Service?",default:!1}))return console.log(u.gray(" Cancelled. Continuing with Zibby Chat (default).")),console.log(""),{ready:!1,cancelled:!0};if(!await ht({message:"Enable Claude Code add-on at $20/month?",default:!1}))return console.log(u.gray(" Cancelled. Continuing with Zibby Chat (default).")),console.log(""),{ready:!1,cancelled:!0};console.log(""),console.log(u.cyan(" Enabling Claude Code add-on..."));let a;try{a=await zn({addon:"claude-code",workspaceId:t,sessionToken:e,apiUrl:o,accept:{tos:!0,billing:!0}})}catch(c){if(c?.code==="BILLING_REQUIRED"){console.log("");let l=c.upgradeUrl?.startsWith("http")?c.upgradeUrl:"https://zibby.dev/billing";return c.needsSubscription?(console.log(u.yellow(" \u26A0 You need an active Pro subscription to enable Claude Code.")),console.log(u.gray(` Upgrade here: ${l}`))):c.needsPaymentMethod?(console.log(u.yellow(" \u26A0 Your card was declined or no payment method is on file.")),console.log(u.gray(` Update billing: ${l}`))):(console.log(u.yellow(` \u26A0 ${c.message}`)),console.log(u.gray(` Manage billing: ${l}`))),console.log(""),console.log(u.gray(" Continuing with Zibby Chat (default).")),console.log(""),{ready:!1,cancelled:!0,billingRequired:!0}}throw c}return console.log(""),console.log(u.green(" \u2713 Stripe subscription created")),console.log(u.gray(` sub_id: ${a.subscriptionId}`)),console.log(u.green(" \u2713 Lambda invoked: zibby-prod-provision-sandbox")),console.log(u.gray(` request: ${a.requestId}`)),console.log(u.cyan(" \u2699 Fargate task launching: zibby/agent-runtime:claude-code-v1")),console.log(u.gray(` sandbox_id: ${a.sandboxId}`)),console.log(""),await Mn({apiUrl:o,sessionToken:e}),console.log(""),console.log(u.gray(" Sandbox provisioning in the background. Zibby Chat (default) is active until ready.")),console.log(""),{ready:!1,provisioning:!0,sandboxId:a.sandboxId,deploymentId:a.requestId}}async function Mn({apiUrl:t,sessionToken:e}){let o;try{let{discoverCredentials:s}=await Promise.resolve().then(()=>(ho(),mo));o=await s()}catch(s){console.log(u.gray(` (could not scan local credentials: ${s.message})`));return}let n=o.all.length;if(n===0){console.log(u.yellow(" \u26A0 No Anthropic credentials found locally.")),console.log(""),console.log(u.white(" Two ways to authenticate Claude Code in your sandbox:")),console.log(""),console.log(u.bold(" Option A \u2014 provide your own (recommended):")),console.log(u.gray(" 1. Run: zibby init")),console.log(u.gray(" Pick Claude \u2192 Subscription (OAuth) or API key")),console.log(u.gray(" 2. Run: zibby creds sync (uploads to your workspace)")),console.log(u.gray(" 3. Re-run /agents in chat")),console.log(""),console.log(u.bold(" Option B \u2014 in-sandbox login (legacy):")),console.log(u.gray(" Skip this step. When sandbox is ready and you start")),console.log(u.gray(" Claude Code, it will prompt you to open a URL in your")),console.log(u.gray(" laptop browser to authenticate.")),console.log("");return}console.log(u.green(` \u2713 Found ${n} Anthropic ${n===1?"credential":"credentials"} in your local environment:`));for(let s of o.all){let a=s.source==="config.json"?`~/.zibby/config.json (${s.source_var})`:`process.env.${s.source_var}`;console.log(u.gray(` ${s.type} ***${s.token.slice(-4)} ${a}`))}if(console.log(""),console.log(u.white(" By proceeding you confirm:")),console.log(u.gray(" \u2022 These are YOUR credentials to use")),console.log(u.gray(" \u2022 You comply with Anthropic's ToS for the tier of these tokens")),console.log(u.gray(" \u2022 Zibby will store encrypted (AWS KMS) and inject into YOUR sandbox only")),console.log(""),!await ht({message:"Upload these credentials to your Zibby workspace?",default:!0})){console.log(u.gray(" Skipped credential upload. Sandbox will fall back to in-sandbox login."));return}console.log(""),console.log(u.cyan(" Uploading (KMS-encrypted)..."));try{let{syncFromLocal:s}=await Promise.resolve().then(()=>(wo(),bo)),a=await s({apiUrl:t,sessionToken:e,credentials:o.all});console.log(u.green(` \u2713 ${a.added} new, ${a.deduped} already stored`)),a.errors.length>0&&console.log(u.yellow(` ${a.errors.length} failed \u2014 retry with 'zibby creds sync'`))}catch(s){console.log(u.red(` \u2717 Upload failed: ${s.message}`)),console.log(u.gray(" Sandbox will fall back to in-sandbox login when ready."))}}async function jn({addon:t,sessionToken:e,apiUrl:o}){let n=process.env.ZIBBY_CLAUDE_CODE_STUB_STATUS;if(n==="ready")return{configured:!0,sandboxState:"ready",sandboxId:"sb_stub_acme_001"};if(n==="provisioning")return{configured:!0,sandboxState:"provisioning",sandboxId:"sb_stub_acme_001"};if(!o||!e)return{configured:!1,sandboxState:null,sandboxId:null};let r=`${String(o).replace(/\/+$/,"")}/agents/addons/${encodeURIComponent(t)}`,s;try{s=await fetch(r,{headers:{Authorization:`Bearer ${e}`}})}catch{return{configured:!1,sandboxState:null,sandboxId:null}}if(s.status===401){let c=new Error("Session expired \u2014 run zibby login");throw c.code="AUTH_EXPIRED",c}if(s.status===404)return{configured:!1,sandboxState:null,sandboxId:null};if(!s.ok)return{configured:!1,sandboxState:null,sandboxId:null};let a=await s.json();return{configured:!!a.configured,sandboxState:a.sandbox_state||null,sandboxId:a.sandbox_id||null,subscriptionId:a.subscription_id||null,enabledAt:a.enabled_at||null}}async function zn({addon:t,workspaceId:e,sessionToken:o,apiUrl:n}){if(!n||!o)return await new Promise(c=>setTimeout(c,500)),{subscriptionId:`sub_${Math.random().toString(36).slice(2,10)}`,sandboxId:`sb_${Math.random().toString(36).slice(2,10)}`,requestId:`req_offline_${Date.now().toString(36)}`};let r=`${String(n).replace(/\/+$/,"")}/agents/addons/${encodeURIComponent(t)}/enable`,s=await fetch(r,{method:"POST",headers:{Authorization:`Bearer ${o}`,"Content-Type":"application/json"},body:JSON.stringify({workspace_id:e||null})});if(s.status===401){let c=new Error("Session expired \u2014 run zibby login");throw c.code="AUTH_EXPIRED",c}if(s.status===402){let c;try{c=await s.json()}catch{c={}}let l;try{l=typeof c.error=="string"?JSON.parse(c.error):c.error||c}catch{l={message:c.error||"Payment required"}}let p=new Error(l.message||"Payment required");throw p.code="BILLING_REQUIRED",p.status=402,p.needsSubscription=!!l.needs_subscription,p.needsPaymentMethod=!!l.needs_payment_method,p.upgradeUrl=l.upgrade_url||"/billing",p}if(!s.ok){let c=new Error(`Enable addon failed (${s.status})`);throw c.status=s.status,c}let a=await s.json();return{subscriptionId:a.subscription_id||null,sandboxId:a.sandbox_id||null,stripeSubscriptionItemId:a.stripe_subscription_item_id||null,requestId:a.request_id||`req_${Date.now().toString(36)}`}}function yt(t,e){let o=String(t).replace(/\/+$/,"");return e?`${o}/agents/sessions/${encodeURIComponent(e)}`:`${o}/agents/sessions`}async function xo({apiUrl:t,sessionToken:e}){if(!e)return[];let o=await fetch(yt(t),{headers:{Authorization:`Bearer ${e}`}});if(o.status===401)throw new Error("Not authenticated. Run `zibby login` again.");if(o.status===404)return[];if(!o.ok){let r=await o.text().catch(()=>"");throw new Error(`Failed to list agent sessions (${o.status}): ${r.slice(0,200)}`)}let n=await o.json();return Array.isArray(n.sessions)?n.sessions:[]}async function Fn({apiUrl:t,sessionToken:e,agentType:o,fields:n={}}){if(!e)throw new Error("Not authenticated");let r=await fetch(yt(t,o),{method:"PUT",headers:{Authorization:`Bearer ${e}`,"Content-Type":"application/json"},body:JSON.stringify(n)});if(!r.ok){let a=await r.text().catch(()=>"");throw new Error(`Failed to save agent session (${r.status}): ${a.slice(0,200)}`)}return(await r.json()).session}async function Yn({apiUrl:t,sessionToken:e,agentType:o}){if(!e)throw new Error("Not authenticated");let n=await fetch(yt(t,o),{method:"DELETE",headers:{Authorization:`Bearer ${e}`}});if(!n.ok){let s=await n.text().catch(()=>"");throw new Error(`Failed to delete agent session (${n.status}): ${s.slice(0,200)}`)}return(await n.json()).deleted===!0}function $o(t){if(!t)return"never";let e=new Date(t).getTime();if(Number.isNaN(e))return"unknown";let o=Math.max(0,(Date.now()-e)/1e3);if(o<60)return"just now";let n=o/60;if(n<60)return`${Math.round(n)}m ago`;let r=n/60;if(r<24)return`${Math.round(r)}h ago`;let s=r/24;if(s<30)return`${Math.round(s)}d ago`;let a=s/30;return`${Math.round(a)}mo ago`}var Le,Ao=$e(()=>{Le=[{id:"zibby",name:"Zibby Chat",short:"default",description:"Built-in chat using Anthropic SDK directly \xB7 BYOK \xB7 included with workspace",pricePerMonth:0,deployment:"instant"},{id:"claude-code",name:"Claude Code",short:"add-on",description:"Anthropic's Claude Code CLI deployed in your private sandbox",pricePerMonth:20,deployment:"fargate-warm"}]});var bt={};ve(bt,{attachToSession:()=>To,spawnAgentSession:()=>Io,spawnAndAttach:()=>Zn});import Co from"ws";import ko from"chalk";function Hn({sandboxEndpoint:t,sessionId:e,useTls:o=!1}){return`${o?"wss":"ws"}://${t}/stream/${encodeURIComponent(e)}`}async function Io({sandboxEndpoint:t,sessionToken:e,agentType:o="claude-code",args:n=[],cwd:r="/workspace",useTls:s=!1}){let c=`${s?"https":"http"}://${t}/spawn`,l=await fetch(c,{method:"POST",headers:{Authorization:`Bearer ${e}`,"Content-Type":"application/json"},body:JSON.stringify({agent_type:o,args:n,cwd:r})});if(!l.ok){let $=await l.text().catch(()=>"");throw new Error(`spawn failed (${l.status}): ${$}`)}return await l.json()}async function To({sandboxEndpoint:t,sessionId:e,sessionToken:o,useTls:n=!1,showBanner:r=!0}){let s=Hn({sandboxEndpoint:t,sessionId:e,useTls:n}),a=new Co(s,{headers:{Authorization:`Bearer ${o}`}});return new Promise((c,l)=>{let p=!1,$=!1,z=null,Y=null,W=A=>{if(!p){p=!0;try{process.stdin.isTTY&&process.stdin.setRawMode&&process.stdin.setRawMode($)}catch{}z&&process.stdin.off("data",z),Y&&process.stdout.off("resize",Y);try{process.stdin.pause()}catch{}try{a.close()}catch{}c(A)}};a.on("open",()=>{r&&(process.stdout.write(ko.green(`
|
|
4
4
|
\u2713 Connected to cloud sandbox session ${e}
|
|
5
|
-
`)),process.stdout.write(
|
|
5
|
+
`)),process.stdout.write(ko.gray(` Press Ctrl+\\ to detach (session keeps running).
|
|
6
6
|
|
|
7
|
-
`)));let
|
|
7
|
+
`)));let A=()=>{let R=process.stdout.columns||80,B=process.stdout.rows||24;try{a.send(JSON.stringify({type:"resize",cols:R,rows:B}))}catch{}};A(),Y=()=>A(),process.stdout.on("resize",Y),process.stdin.isTTY&&process.stdin.setRawMode&&($=!!process.stdin.isRaw,process.stdin.setRawMode(!0)),process.stdin.resume();try{process.stdin.setEncoding("utf8")}catch{}z=R=>{let B=R.toString("utf8");if(B.includes("")){W({reason:"detach"});return}try{a.send(B)}catch{}},process.stdin.on("data",z)}),a.on("message",A=>{let R=A.toString("utf8");if(R.startsWith("{")&&R.endsWith("}"))try{let B=JSON.parse(R);if(B&&B.type==="exit"){W({reason:"remote-exit",exitCode:B.exitCode,signal:B.signal});return}}catch{}try{process.stdout.write(R)}catch{}}),a.on("close",()=>{W({reason:"remote-close"})}),a.on("error",A=>{p||W({reason:"ws-error",message:A?.message||String(A)})}),setTimeout(()=>{if(a.readyState===Co.CONNECTING){try{a.terminate()}catch{}p||(p=!0,l(new Error("WS connect timed out after 30s")))}},3e4).unref()})}async function Zn({sandboxEndpoint:t,sessionToken:e,agentType:o,args:n,cwd:r,useTls:s}){let a=await Io({sandboxEndpoint:t,sessionToken:e,agentType:o,args:n,cwd:r,useTls:s});return{...await To({sandboxEndpoint:t,sessionId:a.session_id,sessionToken:e,useTls:s}),sessionId:a.session_id}}var wt=$e(()=>{});import{invokeAgent as Kn,getAgentStrategy as Wn}from"@zibby/core";import{getSkill as Re}from"@zibby/skills";import{existsSync as Ce,readFileSync as Ro,readdirSync as Jn}from"fs";import{resolve as me,join as St,dirname as Gn,basename as qn}from"path";import{createInterface as Vn,moveCursor as j,cursorTo as K,clearLine as Q,emitKeypressEvents as Xn}from"readline";import{fileURLToPath as Qn}from"url";import{homedir as es}from"os";import i from"chalk";import{highlight as Po}from"cli-highlight";import ts from"dotenv";import{existsSync as Lt,mkdirSync as qo,readFileSync as Vo,writeFileSync as Xo}from"fs";import{homedir as Rt}from"os";import{join as Fe}from"path";function Bt(){return process.env.ZIBBY_CONFIG_DIR||Fe(Rt(),".zibby")}function Dt(){return Fe(Bt(),"config.json")}var Qo=Fe(Rt(),".zibby"),Ms=Fe(Qo,"config.json");function en(){let t=Bt();Lt(t)||qo(t,{recursive:!0})}function se(){try{let t=Dt();if(Lt(t)){let e=Vo(t,"utf-8");return JSON.parse(e)}}catch{}return{}}function Pe(t){en(),Xo(Dt(),JSON.stringify(t,null,2))}function Ye(){return se().sessionToken||null}function Mt(t){let e=se();e.sessionToken=t,Pe(e)}function jt(){return se().user||null}function zt(t){let e=se();e.user=t,Pe(e)}function Ft(){let t=se();delete t.sessionToken,delete t.user,delete t.mem0ProxyUrl,Pe(t)}function Yt(){return se().proxyUrl||null}function Ht(t){let e=se();e.proxyUrl=t,Pe(e)}function Zt(){return se().mem0ProxyUrl||null}function Kt(t){let e=se();e.mem0ProxyUrl=t,Pe(e)}function Wt(){return se().projects||[]}var Ee={local:{name:"Local Development",apiUrl:"http://localhost:3001",accountApiUrl:"http://localhost:3001",frontendUrl:"http://localhost:3000",description:"Local backend running on port 3001"},prod:{name:"Production",apiUrl:process.env.ZIBBY_PROD_API_URL||"https://api-prod.zibby.app",accountApiUrl:process.env.ZIBBY_PROD_ACCOUNT_API_URL||"https://account-api-prod.zibby.app",frontendUrl:process.env.ZIBBY_PROD_FRONTEND_URL||"https://studio.zibby.dev",description:"Production environment"}};function le(){let t;if(process.env.ZIBBY_API_URL)t=process.env.ZIBBY_API_URL;else{let e=process.env.ZIBBY_ENV||"prod";Ee[e]?t=Ee[e].apiUrl:t=Ee.prod.apiUrl}try{let e=new URL(t);return e.protocol!=="http:"&&e.protocol!=="https:"?(console.error(`\u26A0\uFE0F Invalid API URL protocol: ${e.protocol} (only http/https allowed)`),Ee.prod.apiUrl):t}catch{return console.error(`\u26A0\uFE0F Invalid API URL: ${t}`),Ee.prod.apiUrl}}import{existsSync as at,mkdirSync as tn,readFileSync as Jt,writeFileSync as Gt,unlinkSync as Ys}from"fs";import{resolve as Oe}from"path";import{homedir as Ks}from"os";var on=30;function qt(t){let e=Oe(t,".zibby","output");return at(e)||tn(e,{recursive:!0}),e}function Vt(t){let e=Oe(t,".zibby","output","chat-history.json");if(!at(e))return[];try{let o=JSON.parse(Jt(e,"utf-8"));return Array.isArray(o)?o:[]}catch{return[]}}function Ne(t,e){let o=qt(t),n=Oe(o,"chat-history.json");try{Gt(n,JSON.stringify((e||[]).slice(-on*2),null,2),"utf-8")}catch{}}function Xt(t){let e=Oe(t,".zibby","output","active-skills.json");if(!at(e))return null;try{let o=JSON.parse(Jt(e,"utf-8"));return Array.isArray(o)?o:null}catch{return null}}function Ue(t,e){let o=qt(t),n=Oe(o,"active-skills.json");try{Gt(n,JSON.stringify(Array.isArray(e)?e:[]),"utf-8")}catch{}}var ct={cli_reliable_v1:{title:"General intelligence reliability contract",operatingRules:["Evidence-first reasoning: ground conclusions in observed outputs or tool evidence, not guesses.","No false completion: never claim success for a state-changing action until verification confirms it.","Execution integrity: do not claim any external action unless the matching tool call actually happened.","Bounded recovery: for transient failures, retry with adjusted parameters up to 2 times, then escalate with blocker + next step.",'Binary-answer discipline: for yes/no questions, verify the exact asked condition before answering; do not answer "yes" from a broader or approximate match.'],executionSafety:["Prefer low-blast-radius, reversible actions first.","Before irreversible or high-impact actions, confirm explicit user intent unless already authorized.","If verification cannot be run, state that limitation explicitly."],investigationLoop:["For unclear failures, follow this loop: detect -> gather evidence -> form hypothesis -> test hypothesis -> conclude.","If evidence is insufficient, explicitly collect more before proposing a root cause.","Prefer smallest validating action first before broad or costly retries."],responseQuality:["State assumptions explicitly when certainty is low.","Differentiate facts, hypotheses, and next actions.","Keep reports concise but decision-useful.","If related-but-not-identical matches exist, report them separately as context, not as the direct yes/no answer."],incidentTemplate:["ONLY when diagnosing failures or errors (never for successful actions), structure your response as: Root cause, Evidence, Attempted fixes, Current status, Next action."],skillRunbooks:{}}},eo=2e3,Qt=12e3;function He(t=[]){if(!Array.isArray(t))return[];let e=new Set,o=[];for(let n of t){let r=String(n||"").replace(/\s+/g," ").trim();r&&(e.has(r)||(e.add(r),o.push(r)))}return o}function nn(t,e=eo){let o=String(t||"");return o.length<=e?o:`${o.slice(0,Math.max(0,e-14)).trimEnd()}
|
|
8
8
|
|
|
9
|
-
[truncated]`}function
|
|
10
|
-
`);return
|
|
9
|
+
[truncated]`}function ge(t,e=[],o=eo){let n=He(e);if(n.length===0)return"";let r=[`## ${t}`,...n.map(s=>`- ${s}`)].join(`
|
|
10
|
+
`);return nn(r,o)}function sn(t){return!t||typeof t!="object"||Array.isArray(t)?null:t}function rn(t,e){let o={...t,...e},n=["operatingRules","rules","executionSafety","investigationLoop","responseQuality","incidentTemplate"];for(let r of n)Array.isArray(e?.[r])?o[r]=[...He(t?.[r]||[]),...He(e[r])]:Array.isArray(t?.[r])&&(o[r]=[...He(t[r])]);return o.skillRunbooks={...t?.skillRunbooks||{},...e?.skillRunbooks||{}},o}function an(t={},e={}){let o=Array.isArray(t?.reliabilityAppendSections)?t.reliabilityAppendSections:[],n=Array.isArray(e?.reliabilityAppendSections)?e.reliabilityAppendSections:[];return[...o,...n].map(r=>{if(typeof r=="string")return{title:"Additional reliability guidance",lines:[r]};if(!r||typeof r!="object")return null;let s=String(r.title||"Additional reliability guidance").trim(),a=Array.isArray(r.lines)?r.lines:[];return{title:s,lines:a}}).filter(Boolean)}function cn(t={},e={}){let o=String(e.reliabilityProfile||process.env.ZIBBY_RELIABILITY_PROFILE||t.reliabilityProfile||"cli_reliable_v1").trim(),n=t?.reliabilityProfiles?.[o];if(typeof n=="string"&&n.trim())return{name:o,text:n.trim()};if(n&&typeof n.instruction=="string"&&n.instruction.trim())return{name:o,text:n.instruction.trim()};let r=ct[o]||ct.cli_reliable_v1,s=sn(n),a=s?rn(r,s):r;return{name:o,defaults:a}}function to({activeSkills:t=[],chatConfig:e={},options:o={}}={}){let n=cn(e,o);if(n.text)return n.text;let r=n.defaults||ct.cli_reliable_v1,s=[ge(r.title||"Reliability contract",r.operatingRules||r.rules||[]),ge("Execution safety",r.executionSafety||[]),ge("Investigation loop",r.investigationLoop||[]),ge("Response quality",r.responseQuality||[]),ge("Failure reporting format",r.incidentTemplate||[])],a=r.skillRunbooks||{};for(let p of t)a[p]&&s.push(ge(`Runbook: ${p}`,a[p]));let c=an(e,o);for(let p of c)s.push(ge(p.title,p.lines));let l=s.filter(Boolean).join(`
|
|
11
11
|
|
|
12
|
-
`).trim();return l.length<=
|
|
12
|
+
`).trim();return l.length<=Qt?l:`${l.slice(0,Math.max(0,Qt-14)).trimEnd()}
|
|
13
13
|
|
|
14
|
-
[truncated]`}var
|
|
15
|
-
`)}function
|
|
14
|
+
[truncated]`}var os=Qn(import.meta.url),ns=Gn(os),ss=JSON.parse(Ro(St(ns,"../../package.json"),"utf-8")),Bo=30,rs=54,is=18e3,Do=12e3,Eo=42e3;function as(t){return new Promise(e=>setTimeout(e,t))}var Ge=["\u280B","\u2819","\u2839","\u2838","\u283C","\u2834","\u2826","\u2827","\u2807","\u280F"],$t=[{cmd:"/help",desc:"Show this help"},{cmd:"/agents",desc:"Choose chat agent (Zibby default or Claude Code add-on)"},{cmd:"/skills",desc:"List active & available skills"},{cmd:"/history",desc:"Show conversation history (--all or -n 50)"},{cmd:"/clear",desc:"Clear conversation history"},{cmd:"/memory",desc:"View stored memories, tasks, sessions"},{cmd:"/exit",desc:"Exit the chat"},{cmd:"/quit",desc:"Exit the chat"}];function Oo(){let t=0,e="thinking...",o=setInterval(()=>{let r=i.cyan(Ge[t%Ge.length]),s=t%3,a=s===0?i.white(".")+i.gray(".")+i.dim("."):s===1?i.dim(".")+i.white(".")+i.gray("."):i.gray(".")+i.dim(".")+i.white("."),c=e.replace(/\.+$/,""),l=` ${r} ${i.gray(c)}${a}`;process.stdout.write(`\r${" ".repeat(80)}\r${l}`),t++},300),n=()=>{clearInterval(o),process.stdout.write(`\r${" ".repeat(80)}\r`)};return n.setLabel=r=>{e=r},n}function $r(t){let e=t?.agent;return e?e.provider?e.provider:e.gemini?"gemini":e.codex?"codex":e.claude?"claude":e.cursor?"cursor":process.env.AGENT_TYPE||"cursor":process.env.AGENT_TYPE||"cursor"}function cs(t){return t.slice(-Bo).map(e=>`${e.role==="human"?"H":"AI"}: ${e.content}`).join(`
|
|
15
|
+
`)}function vr(t,e,o){let n=t;return e.length>0&&(n+=`
|
|
16
16
|
|
|
17
|
-
${
|
|
17
|
+
${cs(e)}`),n+=`
|
|
18
18
|
H: ${o}
|
|
19
|
-
AI:`,n}function
|
|
19
|
+
AI:`,n}function ls(t){let e=t.filter(o=>!process.env[o]);return{ok:e.length===0,missing:e}}function us(t){let e=me(t,".zibby.config.mjs");if(!Ce(e))return{};try{return import(e).then(o=>o.default||{})}catch{return{}}}async function ds(t){let e=me(t,".zibby","chat.mjs");if(Ce(e)){let r=await import(e);if(r.CHAT_CONFIG||r.default)return r.CHAT_CONFIG||r.default}let o=me(es(),".zibby","chat.mjs");if(o!==e&&Ce(o)){let r=await import(o);if(r.CHAT_CONFIG||r.default)return r.CHAT_CONFIG||r.default}let n=await import("@zibby/core/templates/browser-test-automation/chat.mjs");return n.CHAT_CONFIG||n.default||{}}function No(t){try{let e=me(t,".zibby","commands");return Ce(e)?Jn(e).filter(o=>o.toLowerCase().endsWith(".md")).sort((o,n)=>o.localeCompare(n)):[]}catch{return[]}}function ps(t,e){let o=String(e||"").trim();if(!o.startsWith("/"))return o;let[n,...r]=o.split(/\s+/),s=r.join(" ").trim(),a=n.slice(1);if(!a)return o;let c=a.toLowerCase().endsWith(".md")?[a]:[a,`${a}.md`],l=me(t,".zibby","commands"),p=c.find($=>Ce(St(l,$)));if(!p)return o;try{let $=Ro(St(l,p),"utf-8").trim();return s?`${$}
|
|
20
20
|
|
|
21
|
-
${s}
|
|
21
|
+
${s}`:$}catch{return o}}function fs(t){let e=t.slice(-Bo),o=[],n=0;for(let r=e.length-1;r>=0;r--){let s=e[r],a=String(s?.content||""),c=s?.role==="human"?"user":"assistant",l=a.length;if(o.length>=6&&n+l>is)break;o.push({role:c,content:a}),n+=l}return o.reverse()}function Be(t,e){let o=String(t||"");return o.length<=e?o:`${o.slice(0,Math.max(0,e-24))}
|
|
22
22
|
|
|
23
|
-
[truncated for proxy size]`}function
|
|
23
|
+
[truncated for proxy size]`}function xt(t){return t.reduce((e,o)=>e+String(o?.content||"").length+64,0)}function gs(t){let e=[...t];if(e.length===0||(e[0]?.role==="system"&&(e[0]={...e[0],content:Be(e[0].content,Do)}),xt(e)<=Eo))return e;let o=e[0],n=e[e.length-1],r=e.slice(1,-1).slice(-4).map(s=>({...s,content:Be(s.content,2500)}));return e=[o,...r,n],xt(e)<=Eo||(e=[{...o,content:Be(o?.content,6e3)},{...n,content:Be(n?.content,8e3)}]),e}function ms(t){let e=[];for(let o of t){let n=Re(o),r=String(n?.description||"").trim();if(!r){e.push(`- ${o}`);continue}e.push(`- ${o}: ${qe(r,80)}`)}return e.length===0?"":`## Active skills (call get_skill_context before first use)
|
|
24
24
|
${e.join(`
|
|
25
|
-
`)}`}var
|
|
26
|
-
`)};function
|
|
25
|
+
`)}`}var Uo={cli_plain:["## Response format for this channel","- Output plain terminal text with optional fenced code blocks.","- Use fenced code blocks (```language) when showing code or config. Always include the language tag.","- Outside of code blocks, do NOT use Markdown syntax (no **bold**, __underline__, headings, inline backticks, or markdown tables).","- Keep responses concise and readable in a terminal.","- Write in natural, conversational English. Avoid dumping raw JSON, run IDs, or technical jargon.",'- When reporting test results: summarize in plain language (e.g. "Both tests finished \u2014 the checkbox test passed but the login test failed because..."). Include ticket keys but skip internal run IDs unless the user asks.',"- When something fails, explain the root cause simply and suggest a fix."].join(`
|
|
26
|
+
`)};function hs(t={},e={}){let o=String(e.outputProfile||process.env.ZIBBY_OUTPUT_PROFILE||t.outputProfile||"cli_plain").trim(),n=t?.outputProfiles?.[o];return typeof n=="string"&&n.trim()?n.trim():n&&typeof n.instruction=="string"&&n.instruction.trim()?n.instruction.trim():Uo[o]||Uo.cli_plain}function qe(t,e){let o=String(t??"");return o.length<=e?o:e<=1?o.slice(0,e):`${o.slice(0,e-1)}\u2026`}function ys(){return!1}function bs(t){let e=/^```(\w*)\n([\s\S]*?)^```$/gm;return t.replace(e,(o,n,r)=>{let s=r.replace(/\n$/,"");try{let a=n?Po(s,{language:n,ignoreIllegals:!0}):Po(s,{ignoreIllegals:!0}),c=i.gray("\u2500".repeat(Math.min(process.stdout.columns-6||54,72))),l=n?i.dim(` ${n}`):"";return`${c}${l}
|
|
27
27
|
${a}
|
|
28
|
-
${c}`}catch{return s}})}function _t(){let t=Number(process.stdout?.columns)||0,e=t>8?Math.max(30,t-4):
|
|
29
|
-
`);
|
|
28
|
+
${c}`}catch{return s}})}function _t(){let t=Number(process.stdout?.columns)||0,e=t>8?Math.max(30,t-4):rs;return` ${"\u2500".repeat(e)}`}function Lo(t=[]){let e=$t.map(n=>({cmd:n.cmd,source:"builtin",name:n.cmd.slice(1),desc:n.desc})),o=t.map(n=>({cmd:`/${n}`,source:"template",name:n,desc:"Command template"}));return[...e,...o]}function ws(t,e){let o=String(t||""),n=Number.isFinite(e)?e:o.length;return!(!o.startsWith("/")||n!==o.length||o.includes(" "))}function _s({userName:t,cwd:e,projectName:o,restoredCount:n,skillsLine:r}){let s=Number(process.stdout?.columns)||0,a=Math.max(40,Math.min(s-8,100)),c=Math.max(20,Math.floor((a-3)*.55)),l=a-c-3,p=t||"there",$=o||"No project linked",z=qn(e||process.cwd()),Y=[`Restored ${n} messages from previous session.`,"",r],W=["Workspace details","",`v${ss.version} | Hi, ${p}`,`Company: ${$}`,`Directory: ~/${z}`,`Path: ${e}`,"","Use /help for commands"],A=Math.max(Y.length,W.length),R=(()=>{if(Y.length>=A)return Y;let H=Math.floor((A-Y.length)/2),ue=A-Y.length-H;return[...Array(H).fill(""),...Y,...Array(ue).fill("")]})(),B="\u2500",he=` \u250C${B.repeat(c+2)}\u252C${B.repeat(l+2)}\u2510`,L=` \u2514${B.repeat(c+2)}\u2534${B.repeat(l+2)}\u2518`;console.log(i.gray(he));for(let H=0;H<A;H++){let ue=qe(R[H]||"",c),ye=qe(W[H]||"",l),be=" ".repeat(Math.max(0,c-ue.length)),_=" ".repeat(Math.max(0,l-ye.length)),k=` \u2502 ${ue}${be} \u2502 ${ye}${_} \u2502`;console.log(i.gray(k))}console.log(i.gray(L)),console.log("")}function Ss(){process.stdout?.isTTY&&(j(process.stdout,0,-2),K(process.stdout,4))}function xs(t){let e=!!(process.stdout?.isTTY&&process.stdin?.isTTY),o=!1,n=!1,r=!1,s=null,a=0,c=0,l=0;function p(){return i.gray(_t())}function $(){s&&(clearInterval(s),s=null)}function z(_){!e||!o||!n||!r||(process.stdout.write("\x1B7"),j(process.stdout,0,-2),K(process.stdout,0),Q(process.stdout,0),process.stdout.write(` ${_}`),process.stdout.write("\x1B8"))}function Y(){if(!(!e||!o)&&c!==0){process.stdout.write("\x1B7"),j(process.stdout,0,2);for(let _=0;_<c;_++)K(process.stdout,0),Q(process.stdout,0),_<c-1&&j(process.stdout,0,1);process.stdout.write("\x1B8"),c=0,n&&W()}}function W(){!e||!o||!n||(process.stdout.write("\x1B7"),j(process.stdout,0,1),K(process.stdout,0),Q(process.stdout,0),process.stdout.write(p()),process.stdout.write("\x1B8"))}function A(_,k){if(!e||!o||!n)return;Y();let I=_.slice(0,6);if(I.length!==0){j(process.stdout,0,1);for(let b=0;b<I.length;b++)process.stdout.write(`
|
|
29
|
+
`);j(process.stdout,0,-(1+I.length)),process.stdout.write("\x1B7"),j(process.stdout,0,2);for(let b=0;b<I.length;b++){K(process.stdout,0),Q(process.stdout,0);let ee=b===k?i.cyan("\u203A"):" ",te=b===k?i.white(I[b]):i.gray(I[b]);process.stdout.write(` ${ee} /${te}`),b<I.length-1&&j(process.stdout,0,1)}process.stdout.write("\x1B8"),c=I.length,W()}}function R(){if(!e||!o||!n)return;Y();let _=process.stdout.columns||80,k=l>0?Math.ceil(l/_):1;K(process.stdout,0),j(process.stdout,0,-k),r&&j(process.stdout,0,-2),process.stdout.write("\x1B[J"),n=!1}function B(_={}){let k=_.preserveInput===!0;if(!e){t.prompt();return}k||(t.line="",t.cursor=0),l=_t().length;let I=p();process.stdout.write(`${I}
|
|
30
30
|
`),t.prompt(),process.stdout.write(`
|
|
31
31
|
${I}
|
|
32
|
-
`),
|
|
33
|
-
`);for(;
|
|
34
|
-
`);
|
|
35
|
-
`)}function
|
|
36
|
-
`);for(;I.length>0&&I[I.length-1]==="";)I.pop();for(let b of I)console.log(b?` ${b}`:"");console.log(),r=!1}return{enabled:e,mount(){if(!o){if(!e){t.prompt(),o=!0;return}o=!0,
|
|
32
|
+
`),Ss(),n=!0}function he(){if(!e||!o||!n)return;let _=process.stdout.columns||80,k=l>0?Math.ceil(l/_):1,I=p();process.stdout.write("\x1B7"),j(process.stdout,0,-k);for(let b=0;b<k;b++)K(process.stdout,0),Q(process.stdout,0),b<k-1&&j(process.stdout,0,1);K(process.stdout,0),process.stdout.write(I),j(process.stdout,0,2),K(process.stdout,0),Q(process.stdout,0),process.stdout.write(I);for(let b=1;b<k;b++)j(process.stdout,0,1),K(process.stdout,0),Q(process.stdout,0);process.stdout.write("\x1B8"),l=_t().length}function L(){if(!e||!o||!n)return;let _=(()=>{if(typeof t.getCursorPos!="function")return 0;try{return Math.max(0,Number(t.getCursorPos()?.rows||0))}catch{return 0}})();process.stdout.write("\x1B7"),j(process.stdout,0,-(_+1)),K(process.stdout,0),Q(process.stdout,0),process.stdout.write(p()),j(process.stdout,0,_+2),K(process.stdout,0),Q(process.stdout,0),process.stdout.write(p()),process.stdout.write("\x1B8")}function H(_){$(),R(),console.log();let k=String(_??"").replace(/\r/g,"").split(`
|
|
33
|
+
`);for(;k.length>0&&k[k.length-1]==="";)k.pop();for(let I of k)console.log(I?` ${I}`:"");r=!1}function ue(_){let k=String(_??"").replace(/\r/g,"").split(`
|
|
34
|
+
`);k.length===0&&k.push("");let I=[];for(let b of k)I.push(i.bgGray.white(` ${b||" "} `));return I.join(`
|
|
35
|
+
`)}function ye(){$();let _=()=>i.gray(`${Ge[a%Ge.length]} thinking`);if(!e){console.log(` ${_()}`),r=!0;return}Y(),R(),console.log(),console.log(` ${_()}`),B({preserveInput:!0}),r=!0,a+=1,s=setInterval(()=>{r&&(z(_()),a+=1)},120)}function be(_){$();let k=String(_??"").replace(/\r/g,"").replace(/⎿/g,"");if(!r){H(k);return}R(),console.log();let I=k.split(`
|
|
36
|
+
`);for(;I.length>0&&I[I.length-1]==="";)I.pop();for(let b of I)console.log(b?` ${b}`:"");console.log(),r=!1}return{enabled:e,mount(){if(!o){if(!e){t.prompt(),o=!0;return}o=!0,B()}},refreshPrompt(_={}){if(e&&o){n&&R(),B(_);return}t.prompt()},pushSystem(_){H(_)},pushUser(_){H(ue(_))},pushAssistant(_){be(_)},showAssistantLoading:ye,dismissTransientLoading(){$(),r&&e&&o&&n&&(process.stdout.write("\x1B7"),j(process.stdout,0,-2),K(process.stdout,0),Q(process.stdout,0),j(process.stdout,0,-1),K(process.stdout,0),Q(process.stdout,0),process.stdout.write("\x1B8")),r=!1},touchInputFrame:L,handleResize:he,showCommandDropdown:A,clearCommandDropdown:Y}}function $s(){console.log(""),console.log(i.cyan(" Available commands:"));for(let t of $t)console.log(i.white(` ${t.cmd.padEnd(10)} `)+i.gray(t.desc));console.log(""),console.log(i.cyan(" Chat options:")),console.log(i.white(" --stream, -s ")+i.gray("Enable typewriter effect (default: instant)")),console.log(""),console.log(i.gray(" To install/uninstall skills, just ask naturally:")),console.log(i.gray(' "connect to Jira" \u2022 "add GitHub" \u2022 "remove Slack"')),console.log("")}var vs=ls;async function Ar(t={}){let e=process.cwd();t.verbose&&(process.env.ZIBBY_VERBOSE="true");let o=t.stream||!1;[me(e,".env.local"),me(e,".env")].forEach(b=>{Ce(b)&&ts.config({path:b,override:!1})});try{let{loadCredentialsIntoEnv:b}=await Promise.resolve().then(()=>(ro(),so));await b({verbose:!!process.env.ZIBBY_DEBUG})}catch{}try{await import("@zibby/skills")}catch{}function r(){let b=Ye();if(!b)return!1;try{let ee=JSON.parse(atob(b.split(".")[1]));return ee.exp&&ee.exp*1e3>Date.now()}catch{return!1}}if(!r()){Ft();let b=le(),{spawn:ee}=await import("child_process"),te=await fetch(`${b}/cli/login/initiate`,{method:"POST",headers:{"Content-Type":"application/json"}});te.ok||(console.log(i.red("\n Could not start login. Try `zibby login`.\n")),process.exit(1));let{deviceCode:C,verificationUrl:d,expiresIn:Z,interval:re}=await te.json(),J=process.platform;ee(J==="darwin"?"open":J==="win32"?"cmd":"xdg-open",J==="win32"?["/c","start","",d]:[d],{detached:!0,stdio:"ignore"}).unref(),console.log(i.cyan(`
|
|
37
37
|
Opening browser to authorize Zibby CLI...`)),console.log(i.gray(` ${d}
|
|
38
|
-
`));let
|
|
38
|
+
`));let pe=Oo();pe.setLabel("waiting for authorization");let we=(re||3)*1e3,_e=Math.floor(Z/(re||3)),ie=!1;for(let de=0;de<_e;de++){await as(we);try{let ae=await fetch(`${b}/cli/login/poll`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({deviceCode:C})});if(ae.status===202)continue;if(!ae.ok)break;let q=await ae.json();if(q.status==="authorized"){Mt(q.token),zt(q.user),q.proxyUrl&&Ht(q.proxyUrl),q.mem0ProxyUrl&&Kt(q.mem0ProxyUrl),ie=!0;break}if(q.status==="denied")break}catch{break}}pe(),ie||(console.log(i.red("\n Login failed or timed out. Run `zibby login` to try again.\n")),process.exit(1))}let s=await us(e),a=await ds(e),c=t.agent||"assistant",l=Ye();l&&!process.env.ZIBBY_USER_TOKEN&&(process.env.ZIBBY_USER_TOKEN=l);let p=Zt()||Yt();p&&!process.env.ZIBBY_MEM0_OPENAI_BASE_URL&&(process.env.ZIBBY_MEM0_OPENAI_BASE_URL=p),process.env.AGENT_TYPE=c,process.env.ZIBBY_CHAT_OWNER_PID=String(process.pid);try{let{cleanupStalePidFiles:b}=await Promise.resolve().then(()=>(ft(),pt));b(e,s)}catch{}let $;try{$=Wn({state:{agentType:c}})}catch(b){console.log(i.red(`
|
|
39
39
|
${b.message}
|
|
40
|
-
`)),process.exit(1)}let
|
|
40
|
+
`)),process.exit(1)}let z=jt(),W=Wt()?.[0]?.name,A=Vt(e),R="zibby",B=a.skills||[],he=Xt(e),L=he?[...new Set([...B,...he])]:[...B],H={data:null,timestamp:0},ue=300*1e3,ye={jira:"jira",github:"github",slack:"slack",sentry:"sentry"};try{let b=Ye();if(b){let ee=le(),te=await fetch(`${ee}/integrations/status`,{method:"GET",headers:{Authorization:`Bearer ${b}`}});if(te.ok){let C=await te.json();for(let[d,Z]of Object.entries(ye)){let re=C[d]?.connected,J=L.indexOf(Z),Ve=Re(Z);re&&J===-1&&Ve?L.push(Z):!re&&J!==-1&&L.splice(J,1)}Ue(e,L)}}}catch{}let be=L.filter(b=>b!=="skill-installer"&&b!=="core-tools"),_=be.length>0?`Skills: ${be.join(", ")}`:"Skills: (none)";_s({userName:z?.name?.split(" ")[0],cwd:e,projectName:W,restoredCount:A.length,skillsLine:_});let k=No(e),I=Lo(k);return new Promise(b=>{let ee=process.env.ZIBBY_CHAT_TAB_COMPLETION==="1",te={input:process.stdin,output:process.stdout,prompt:i.green(" > "),terminal:!0};ee&&(te.completer=S=>{let g=String(S||"");if(!g.startsWith("/"))return[[],g];let v=I.map(U=>U.cmd),P=v.filter(U=>U.startsWith(g));return[P.length>0?P:v,g]});let C=Vn(te),d=xs(C),Z=null,re=!1,J=[],Ve=0,Mo=1200,pe=!1,we=!1,_e=!1,ie=!1,de="",ae=0,q=typeof C._ttyWrite=="function"?C._ttyWrite.bind(C):null;q&&(C._ttyWrite=(...S)=>{if(!(ie||Date.now()<ae))return q(...S)});function jo(){_e||!process.stdout?.isTTY||typeof process.stdout.write!="function"||(process.stdout.write("\x1B[?2004h"),_e=!0)}function vt(){_e&&(!process.stdout?.isTTY||typeof process.stdout.write!="function"||(process.stdout.write("\x1B[?2004l"),_e=!1))}function zo(S){let g="\x1B[200~",v="\x1B[201~";if(!ie&&!S.includes(g))return!1;let P=S,U=!1;for(;P.length>0;){if(!ie){let N=P.indexOf(g);if(N===-1)break;U=!0,It(),ie=!0,de="",P=P.slice(N+g.length);continue}let V=P.indexOf(v);if(V===-1){U=!0,de+=P;break}U=!0,de+=P.slice(0,V);let ce=String(de||"").replace(/\r\n/g,`
|
|
41
41
|
`).replace(/\r/g,`
|
|
42
|
-
`);if(ce.length>0){let
|
|
43
|
-
`);for(let oe of
|
|
44
|
-
`)
|
|
45
|
-
|
|
46
|
-
`,
|
|
47
|
-
`);et.push({placeholder:g,text
|
|
48
|
-
Detached from ${w?.name}. Session continues running in the cloud.`)):
|
|
49
|
-
${w?.name} session exited (code ${
|
|
50
|
-
Connection error: ${
|
|
42
|
+
`);if(ce.length>0){let N=ce.split(`
|
|
43
|
+
`);for(let oe of N)nt(oe)}Me(),de="",ie=!1,P=P.slice(V+v.length)}return U}function At(){if(!pe){pe=!0;try{Ne(e,A),Ue(e,L)}catch{}try{vt()}catch{}try{C.close()}catch{}process.exit(0)}}async function Xe(){if(!pe){pe=!0,typeof $?.cleanup=="function"&&await $.cleanup().catch(()=>{});try{let{killAllChatOrchestratedRuns:S}=await Promise.resolve().then(()=>(ft(),pt)),{postCliInterruptedRunIndex:g}=await import("@zibby/core/utils/run-index-post-cli.js");S(e,process.pid,s),g({cwd:e,config:s})}catch{}Ne(e,A),Ue(e,L),d.pushSystem(i.gray("Session saved. Goodbye!")),vt(),C.close(),process.exit(0)}}if(d.mount(),jo(),process.stdout?.isTTY){let S;process.stdout.on("resize",()=>{clearTimeout(S),S=setTimeout(()=>{d.handleResize()},80)})}let Qe=0,De=S=>{if(typeof S=="string"?S==="\x1B":S&&typeof S.length=="number"?S.length===1&&S[0]===27:!1){Z&&Z.abort(),At();return}let v=typeof S=="string"?S:S&&typeof S.length=="number"?Buffer.from(S).toString("utf8"):"";if(!v)return;if(zo(v)){Qe=Date.now()+1200,ae=Date.now()+1200,ot();return}let P=(v.includes(`
|
|
44
|
+
`)||v.includes("\r"))&&v!=="\r"&&v!==`
|
|
45
|
+
`&&v!==`\r
|
|
46
|
+
`,U=v.includes("\x1B[200~")||v.includes("\x1B[201~"),V=v.length>=16&&/\s/.test(v)&&!v.startsWith("\x1B");(P||U||V)&&(Qe=Date.now()+1200,ae=Date.now()+1200,It(),ot())},F={query:"",matches:[],selected:0},G={prefix:"",matches:[],nextIndex:0},O={active:!1,prefix:"",lines:[],timer:null},et=[],Ct=0,tt="",Fo=new Set($t.map(S=>S.cmd));function Se(S,{preserveFrame:g=!1}={}){let v=String(S||"");C.line=v,C.cursor=v.length,tt=v,typeof C._refreshLine=="function"?C._refreshLine():C.prompt(),g&&d.touchInputFrame()}function kt(){G.prefix="",G.matches=[],G.nextIndex=0}function Me(){if(O.timer&&(clearTimeout(O.timer),O.timer=null),O.active&&O.lines.length>0){Ct+=1;let S=O.lines.length,g=`[Pasted text #${Ct} +${S} lines]`,v=O.lines.join(`
|
|
47
|
+
`);et.push({placeholder:g,text:v});let P=String(O.prefix||"").trimEnd(),U=P?`${P} ${g}`:g;Se(U,{preserveFrame:!0}),xe(C.line)}O.active=!1,O.prefix="",O.lines=[],ae=0}function ot(){O.timer&&clearTimeout(O.timer),O.timer=setTimeout(()=>{Me()},180)}function It(){O.active||(O.active=!0,O.prefix=String(tt||C.line||""),O.lines=[],Se(O.prefix,{preserveFrame:!0}))}function nt(S){return O.active?(O.lines.push(String(S||"")),Se(O.prefix,{preserveFrame:!0}),ot(),!0):!1}function Yo(S){let g=String(S||"");for(let v of et)g=g.split(v.placeholder).join(v.text);return g}function xe(S){let g=String(S||"");if(!g.startsWith("/")||g.includes(" ")||g.length===0){F.query="",F.matches=[],F.selected=0,d.clearCommandDropdown();return}k=No(e),I=Lo(k);let v=g.slice(1).toLowerCase(),P=k.filter(U=>U.toLowerCase().startsWith(v));F.query=v,F.matches=P,F.selected=Math.min(F.selected,Math.max(0,P.length-1)),d.showCommandDropdown(P,F.selected)}let st=(S,g)=>{if(g?.name==="escape"||g?.sequence==="\x1B"){Z&&Z.abort(),At();return}if((g?.name==="return"||g?.name==="enter")&&(we=!0),(g?.name==="backspace"||g?.name==="delete")&&d.touchInputFrame(),g?.name==="tab"&&!g?.shift){let U=String(C.line||""),V=Number(C.cursor||U.length);if(!ws(U,V)){kt(),xe(C.line);return}let ce=U.slice(1).toLowerCase();if(G.prefix!==ce&&(G.prefix=ce,G.matches=I.map(oe=>oe.cmd).filter(oe=>oe.toLowerCase().startsWith(`/${ce}`)),G.nextIndex=0),G.matches.length===0)return;let N=G.nextIndex%G.matches.length;G.nextIndex+=1,Se(G.matches[N]),xe(C.line);return}let v=String(C.line||""),P=v.startsWith("/")&&!v.includes(" ")&&F.matches.length>0;if(g?.name==="up"||g?.name==="down"){if(!P){xe(C.line);return}let U=g.name==="up"?-1:1,V=F.matches.length;F.selected=(F.selected+U+V)%V;let ce=F.matches[F.selected];Se(`/${ce}`,{preserveFrame:!0}),d.showCommandDropdown(F.matches,F.selected);return}g?.name!=="tab"&&kt(),setTimeout(()=>{xe(C.line),O.active||(tt=String(C.line||""))},50)};process.stdin?.on&&(Xn(process.stdin,C),process.stdin.on("keypress",st)),d.enabled&&process.stdin?.on&&(typeof process.stdin.prependListener=="function"?process.stdin.prependListener("data",De):process.stdin.on("data",De)),C.on("line",async S=>{try{let g=String(S||""),v=we;if(we=!1,!v&&(O.active||ie||Date.now()<Qe||Date.now()<ae)){if(O.active&&g.length>0){nt(g);return}O.active&&(Me(),d.refreshPrompt());return}if(O.active&&(Me(),g=String(C.line||g||"")),nt(g))return;let P=g.trim(),U=F.matches[F.selected];if(P.startsWith("/")&&!P.includes(" ")&&F.matches.length>0&&!Fo.has(P)&&P!==`/${U}`){d.clearCommandDropdown(),d.refreshPrompt(),Se(`/${U}`),xe(`/${U}`);return}d.clearCommandDropdown();let N=String(g||"").replace(/[\u0000-\u001F\u007F-\u009F]/g,"").trim();if(!N){d.enabled&&process.stdout?.isTTY&&(j(process.stdout,0,-1),K(process.stdout,4));return}if(re&&N!=="/exit"&&N!=="/quit"){Z&&Z.abort(),J.push(N),d.pushSystem(i.gray("Processing your message...")),d.refreshPrompt({preserveInput:!0});return}let oe=1e4;if(N.length>oe){d.pushSystem(i.red(`\u26A0 Input too long (${N.length} chars). Maximum: ${oe} characters.`)),d.pushSystem(i.gray("Tip: If you need to share logs, use a file instead:")),d.pushSystem(i.gray(" 1. Save to file: pbpaste > debug.log")),d.pushSystem(i.gray(' 2. Ask: "analyze debug.log in current directory"')),d.refreshPrompt();return}if(N==="/exit"||N==="/quit"){Xe();return}if(N==="/help"){$s(),d.refreshPrompt();return}if(N==="/agents"){try{let{pickAgentWithSessions:m,handleClaudeCodeAddon:T,upsertAgentSession:x,AGENTS:E}=await Promise.resolve().then(()=>(Ao(),vo));console.log("");let y=await m({apiUrl:le(),sessionToken:l,currentAgentId:R});if(y.action==="cancel"){console.log(i.gray(" Cancelled.")),console.log(""),d.refreshPrompt();return}if(y.action==="switch"&&y.agentType==="zibby"){R==="zibby"?console.log(i.gray(" Already using Zibby Chat.")):(R="zibby",console.log(i.green(" \u2713 Switched to Zibby Chat (default)"))),console.log(""),d.refreshPrompt();return}if(y.action==="resume"){let w=E.find(h=>h.id===y.agentType),f=y.session?.sandbox_endpoint||process.env.ZIBBY_SANDBOX_ENDPOINT||null;if(!f||!y.sessionId){console.log(i.yellow(` Cannot resume \u2014 sandbox endpoint or session_id missing for ${w?.name||y.agentType}.`)),console.log(i.gray(" (Sandbox manager Lambda must record sandbox_endpoint in /agents/sessions when provisioning ready.)")),console.log(""),d.refreshPrompt();return}try{let{attachToSession:h}=await Promise.resolve().then(()=>(wt(),bt)),D=/^https/.test(le()),M=await h({sandboxEndpoint:f,sessionId:y.sessionId,sessionToken:l,useTls:D});M.reason==="detach"?console.log(i.gray(`
|
|
48
|
+
Detached from ${w?.name}. Session continues running in the cloud.`)):M.reason==="remote-exit"?console.log(i.gray(`
|
|
49
|
+
${w?.name} session exited (code ${M.exitCode??"?"}).`)):M.reason==="ws-error"&&console.log(i.red(`
|
|
50
|
+
Connection error: ${M.message}`))}catch(h){console.log(i.red(` Attach failed: ${h.message}`))}console.log(""),d.refreshPrompt();return}if(y.action==="create"){let w=E.find(f=>f.id===y.agentType);if(y.agentType==="claude-code"){let f=await T({workspaceId:z?.account_id||"workspace-default",sessionToken:l,apiUrl:le()});if(!f.cancelled){if(f.ready||f.provisioning){try{await x({apiUrl:le(),sessionToken:l,agentType:"claude-code",fields:{sandbox_id:f.sandboxId,workspace_id:z?.account_id}})}catch(D){console.warn(i.gray(` (could not save session metadata: ${D.message})`))}let h=f.sandboxEndpoint||process.env.ZIBBY_SANDBOX_ENDPOINT||null;if(f.ready&&h)try{let{spawnAndAttach:D}=await Promise.resolve().then(()=>(wt(),bt)),M=/^https/.test(le()),X=await D({sandboxEndpoint:h,sessionToken:l,agentType:"claude-code",useTls:M});X.reason==="detach"?console.log(i.gray(`
|
|
51
51
|
Detached from ${w.name}. Session continues in the cloud.`)):X.reason==="remote-exit"?console.log(i.gray(`
|
|
52
52
|
${w.name} session exited (code ${X.exitCode??"?"}).`)):X.reason==="ws-error"&&console.log(i.red(`
|
|
53
|
-
Connection error: ${X.message}`))}catch(D){console.log(i.red(` Spawn/attach failed: ${D.message}`))}else
|
|
54
|
-
Active skills:`)),
|
|
55
|
-
Available:`));for(let y of E){let w=T[y],
|
|
53
|
+
Connection error: ${X.message}`))}catch(D){console.log(i.red(` Spawn/attach failed: ${D.message}`))}else R="claude-code",console.log(i.green(f.ready?` \u2713 Active agent: ${w.name}`:` Provisioning ${w.name} \u2014 re-run /agents in ~30s when ready`));console.log("")}}}else{try{await x({apiUrl:le(),sessionToken:l,agentType:y.agentType,fields:{workspace_id:z?.account_id}})}catch(f){console.warn(i.gray(` (could not save session metadata: ${f.message})`))}R=y.agentType,console.log(i.green(` \u2713 New ${w?.name||y.agentType} session`)),console.log(i.gray(" (Live agent connect \u2014 wiring up in next slice.)")),console.log("")}d.refreshPrompt();return}}catch(m){m?.name==="ExitPromptError"?(console.log(i.gray(" Cancelled.")),console.log("")):/zibby login/i.test(m?.message||"")?(console.log(i.yellow(" Session expired \u2014 please run `zibby login` again.")),console.log("")):(console.log(i.red(` Agent selection failed: ${m.message}`)),console.log(""))}d.refreshPrompt();return}if(N==="/skills"){let T=Re("skill-installer")?.catalog||{},x=L.filter(y=>y!=="skill-installer");console.log(i.cyan(`
|
|
54
|
+
Active skills:`)),x.length===0&&console.log(i.gray(" (none)"));for(let y of x){let w=T[y]||{};console.log(i.green(` \u2713 ${y}`)+i.gray(w.description?` \u2014 ${w.description}`:""))}let E=Object.keys(T).filter(y=>!L.includes(y));if(E.length>0){console.log(i.cyan(`
|
|
55
|
+
Available:`));for(let y of E){let w=T[y],f=w.envKeys?.length>0?vs(w.envKeys).ok?i.green(" \u2713 configured"):i.yellow(` \u26A0 needs: ${w.envKeys.join(", ")}`):"";console.log(i.white(` - ${y}`)+i.gray(` \u2014 ${w.description}`)+f)}}console.log(i.gray(`
|
|
56
56
|
Just ask to install: "connect to Jira", "add GitHub", etc.
|
|
57
|
-
`)),d.refreshPrompt();return}if(
|
|
57
|
+
`)),d.refreshPrompt();return}if(N.startsWith("/history")){if(A.length===0)console.log(i.gray(`
|
|
58
58
|
No conversation history.
|
|
59
|
-
`));else{let m=
|
|
60
|
-
Showing ${w.length} of ${
|
|
61
|
-
`));for(let
|
|
59
|
+
`));else{let m=N.split(/\s+/).slice(1),T=m.includes("--all"),x=m.indexOf("-n"),E=x>=0&&m[x+1]?parseInt(m[x+1],10):NaN,y=T?A.length:isNaN(E)?10:E,w=A.slice(-y);console.log(i.gray(`
|
|
60
|
+
Showing ${w.length} of ${A.length} messages${T?" (all)":""}:
|
|
61
|
+
`));for(let f of w){let h=f.role==="human"?i.green(" You"):i.cyan(" Zibby"),D=T||E>10?500:100,M=f.content.length>D?`${f.content.substring(0,D)}...`:f.content;console.log(`${h}: ${i.white(M)}`)}console.log("")}d.refreshPrompt();return}if(N==="/clear"){A.length=0,Ne(e,A),console.log(i.gray(`
|
|
62
62
|
History cleared.
|
|
63
|
-
`)),d.refreshPrompt();return}if(
|
|
63
|
+
`)),d.refreshPrompt();return}if(N.startsWith("/memory")){let m=L.includes("chat-memory")?Re("chat-memory"):null;if(!m?.handleToolCall){console.log(i.yellow(`
|
|
64
64
|
Chat memory not active. Install with: "add chat memory"
|
|
65
|
-
`)),d.refreshPrompt();return}let T=
|
|
66
|
-
Stored memories (${
|
|
67
|
-
`)),
|
|
68
|
-
`));else{for(let h of
|
|
69
|
-
Task history (${
|
|
70
|
-
`)),
|
|
71
|
-
`));else{for(let h of
|
|
65
|
+
`)),d.refreshPrompt();return}let T=N.split(/\s+/).slice(1),x=T[0]||"brief",E={options:{workspace:e}};try{if(x==="facts"||x==="all"){let y=parseInt(T[1],10)||30,w=await m.handleToolCall("memory_recall",{limit:y},E),f=JSON.parse(w);if(console.log(i.cyan(`
|
|
66
|
+
Stored memories (${f.total}):
|
|
67
|
+
`)),f.total===0)console.log(i.gray(` (empty \u2014 memories are saved as the agent learns things)
|
|
68
|
+
`));else{for(let h of f.memories){let D=i.yellow(`[${h.category}]`),M=Number(h.relevance)<1?i.gray(` (${(Number(h.relevance)*100).toFixed(0)}%)`):"",X=h.ticket_key?i.magenta(` ${h.ticket_key}`):"",Te=h.source?i.gray(` via ${h.source}`):"";console.log(` ${D}${X} ${i.white(h.content)}${M}${Te}`)}console.log("")}}else if(x==="tasks"){let y=parseInt(T[1],10)||20,w=await m.handleToolCall("task_history",{limit:y},E),f=JSON.parse(w);if(console.log(i.cyan(`
|
|
69
|
+
Task history (${f.total}):
|
|
70
|
+
`)),f.total===0)console.log(i.gray(` (no tasks logged yet)
|
|
71
|
+
`));else{for(let h of f.tasks){let D=h.status==="passed"?i.green("\u2713"):h.status==="failed"?i.red("\u2717"):i.yellow("\u25CB"),M=h.ticket_key?i.magenta(` ${h.ticket_key}`):"",X=i.gray(`[${h.type}]`),Te=h.result_summary?i.gray(` \u2014 ${h.result_summary.slice(0,80)}`):"";console.log(` ${D} ${X}${M} ${i.white(h.title)}${Te}`)}console.log("")}}else if(x==="sessions"){let y=await m.handleToolCall("memory_brief",{},E),w=JSON.parse(y);if(console.log(i.cyan(`
|
|
72
72
|
Recent sessions (${w.recentSessions?.length||0}):
|
|
73
73
|
`)),!w.recentSessions?.length)console.log(i.gray(` (no sessions saved yet)
|
|
74
|
-
`));else{for(let
|
|
74
|
+
`));else{for(let f of w.recentSessions){let h=f.tickets?i.magenta(` [${f.tickets}]`):"",D=f.tasks_run>0?i.gray(` \u2014 ${f.tasks_run} tasks (${f.tasks_passed} passed, ${f.tasks_failed} failed)`):"",M=f.created_at?i.gray(` ${f.created_at.split("T")[0]}`):"";if(console.log(` ${i.white(f.summary)}${h}${D}${M}`),f.key_facts)for(let X of f.key_facts.split(";").map(Te=>Te.trim()).filter(Boolean))console.log(i.gray(` \u2192 ${X}`))}console.log("")}}else if(x==="search"){let y=T.slice(1).join(" ");if(!y)console.log(i.yellow(`
|
|
75
75
|
Usage: /memory search <keyword>
|
|
76
|
-
`));else{let w=await m.handleToolCall("memory_recall",{query:y,limit:20},E),
|
|
77
|
-
Search "${y}" \u2014 ${
|
|
78
|
-
`));for(let h of
|
|
76
|
+
`));else{let w=await m.handleToolCall("memory_recall",{query:y,limit:20},E),f=JSON.parse(w);console.log(i.cyan(`
|
|
77
|
+
Search "${y}" \u2014 ${f.total} results:
|
|
78
|
+
`));for(let h of f.memories){let D=i.yellow(`[${h.category}]`),M=h.ticket_key?i.magenta(` ${h.ticket_key}`):"";console.log(` ${D}${M} ${i.white(h.content)}`)}f.total===0&&console.log(i.gray(" (no matches)")),console.log("")}}else{let y=await m.handleToolCall("memory_brief",{},E),w=JSON.parse(y),f=w.topMemories?.length||0,h=w.recentSessions?.length||0,D=(w.taskStats||[]).map(M=>`${M.type}:${M.status}=${M.cnt}`).join(", ");console.log(i.cyan(`
|
|
79
79
|
Memory overview:
|
|
80
|
-
`)),console.log(i.white(` Facts stored: ${
|
|
80
|
+
`)),console.log(i.white(` Facts stored: ${f>0?i.cyan(f):i.gray("0")}`)),console.log(i.white(` Sessions saved: ${h>0?i.cyan(h):i.gray("0")}`)),D&&console.log(i.white(` Task history: ${i.gray(D)}`)),console.log(i.gray(`
|
|
81
81
|
Subcommands:`)),console.log(i.gray(" /memory facts [n] \u2014 List all stored memories")),console.log(i.gray(" /memory tasks [n] \u2014 List task history")),console.log(i.gray(" /memory sessions \u2014 List session summaries")),console.log(i.gray(" /memory search <keyword> \u2014 Search memories")),console.log("")}}catch(y){console.log(i.red(`
|
|
82
82
|
Memory error: ${y.message}
|
|
83
|
-
`))}d.refreshPrompt();return}d.enabled&&process.stdout?.isTTY&&(
|
|
83
|
+
`))}d.refreshPrompt();return}d.enabled&&process.stdout?.isTTY&&(j(process.stdout,0,-1),K(process.stdout,0)),d.pushUser(N),d.refreshPrompt(),d.showAssistantLoading();let Tt=Yo(N),je=ps(e,Tt);if(et.length=0,!String(je||"").trim()){d.dismissTransientLoading(),d.refreshPrompt();return}if(je.length>oe){d.pushAssistant(i.red(`Input too long after command expansion (${je.length} chars).`)),d.pushSystem(i.gray(`Try shortening the command template or user text. Limit: ${oe} chars.`)),d.refreshPrompt();return}re=!0;let ne=a.systemPrompt||"You are Zibby, a helpful AI assistant.",Pt=hs(a,t);Pt&&(ne+=`
|
|
84
84
|
|
|
85
|
-
${
|
|
85
|
+
${Pt}`);let Et=to({activeSkills:L,chatConfig:a,options:t});Et&&(ne+=`
|
|
86
86
|
|
|
87
|
-
${
|
|
87
|
+
${Et}`);let Ot=ms(L);if(Ot&&(ne+=`
|
|
88
88
|
|
|
89
|
-
${
|
|
89
|
+
${Ot}`),ne+=`
|
|
90
90
|
|
|
91
91
|
Use provided tools when external data/actions are required. Do not claim actions without tool calls. Before using a skill's tools for the first time in a conversation, call get_skill_context(skillId) to load its full guidance.`,L.includes("chat-memory")&&(ne+=`
|
|
92
92
|
|
|
@@ -103,8 +103,8 @@ Use provided tools when external data/actions are required. Do not claim actions
|
|
|
103
103
|
- Conversation flow: ask about purpose \u2192 input data \u2192 processing steps \u2192 output format \u2192 conditional logic.
|
|
104
104
|
- Then call design_workflow to create a spec, review with user, then build_workflow to generate code.
|
|
105
105
|
- After building: remind user about \`zibby workflow run <name>\` (run locally), \`zibby workflow deploy <name>\` (deploy), \`zibby workflow logs <uuid>\` (logs).
|
|
106
|
-
- Use list_workflows to show existing workflows, add_node to extend them, deploy_workflow to ship.`),L.includes("chat-memory"))try{let m=
|
|
106
|
+
- Use list_workflows to show existing workflows, add_node to extend them, deploy_workflow to ship.`),L.includes("chat-memory"))try{let m=Re("chat-memory");if(typeof m?.buildPromptContext=="function"){let T=Date.now(),x;H.data&&T-H.timestamp<ue?(x=H.data,process.env.ZIBBY_VERBOSE==="true"&&d.pushSystem(i.gray("Using cached memory context"))):(x=await m.buildPromptContext({options:{workspace:e}},{}),H={data:x,timestamp:T},process.env.ZIBBY_VERBOSE==="true"&&d.pushSystem(i.gray("Refreshed memory context cache")));let E=String(x?.backend||"dolt");process.env.ZIBBY_VERBOSE==="true"&&(d.pushSystem(i.gray(`memory backend: ${E}`)),d.pushSystem(i.gray(`memory retrieval output: ${qe(JSON.stringify(x?.debugPreview||{}),1400)}`)),x?.error&&d.pushSystem(i.yellow(`memory backend warning: ${x.error}`))),x?.promptContext&&(ne+=`
|
|
107
107
|
|
|
108
|
-
${
|
|
109
|
-
${
|
|
110
|
-
[Active test runs: ${w.runs.map(h=>`${h.runId}: ${h.ticketKey||h.spec} (${h.status})`).join(", ")}. Use run_status("all") to check progress.]`)}catch{}let
|
|
108
|
+
${x.promptContext}`)}}catch(m){process.env.ZIBBY_VERBOSE==="true"&&d.pushSystem(i.yellow(`memory backend warning: ${String(m?.message||m)}`))}ne=Be(ne,Do);let Zo=fs(A),rt=gs([{role:"system",content:ne},...Zo,{role:"user",content:je}]),Nt=xt(rt),Ko=Buffer.byteLength(JSON.stringify(rt),"utf8");process.env.ZIBBY_VERBOSE==="true"&&d.pushSystem(i.gray(`payload estimate: ${Nt} chars, ${Ko} bytes (~${Math.round(Nt/4)} tokens)`)),A.push({role:"human",content:Tt});let ke=d.enabled?(()=>{let m=()=>{};return m.setLabel=()=>{},m})():Oo(),fe=!0,ze=[],Ut="",Ie="",Cs=50,ks=500,Is=3,Ts=60,Ps=500,Es=15,Os=25,Ns=4,Us=new Set([".","!","?",",",";",":"]),Wo=m=>{fe&&(ke(),fe=!1),Ie+=m},Jo=(m,T)=>{if(!m){fe&&ke.setLabel("thinking...");return}ze.push(m);let x=70,E=m;if(T&&typeof T=="object"){let w=Object.values(T).map(h=>typeof h=="string"?h:JSON.stringify(h)).join(", "),f=`${m}(${w})`;f.length<=x?E=f:E=`${m}(${w.slice(0,x-m.length-4)}...)`}E!==Ut&&(Ut=E,d.pushSystem(i.gray(`\u23BF ${E}`)),d.refreshPrompt({preserveInput:!0}),fe&&d.showAssistantLoading()),fe&&ke.setLabel(E)},it=new AbortController;Z=it;try{let m=await Kn("",{state:{agentType:c,config:s,cwd:e,workspace:e}},{model:s?.agent?.assistant?.model||a.model||"auto",workspace:e,skills:L,activeSkills:L,config:s,timeout:a.timeout||3e5,messages:rt,skipPromptFragments:!0,stream:!0,onToken:Wo,onToolCall:Jo,signal:it.signal});fe&&ke();let T=typeof m=="string"?m:m?.structured?JSON.stringify(m.structured,null,2):m?.raw||String(m),x=Ie&&Ie.trim().length>0?Ie.trim():T.trim(),E=ys(x,ze)?x:bs(x);d.pushAssistant(E);let y=ze.length>0?`[tools used: ${ze.join(", ")}]
|
|
109
|
+
${x}`:x;A.push({role:"ai",content:y}),Ne(e,A),Ue(e,L)}catch(m){if(fe&&ke(),d.dismissTransientLoading(),it.signal.aborted){J.length===0&&d.pushAssistant(i.gray("[cancelled]"));let T="";try{let{testRunnerSkill:E}=await import("../../skills/index.js"),y=await E.handleToolCall("run_status",{runId:"all"},{options:{workspace:e}}),w=JSON.parse(y);w.runs?.length>0&&(T=`
|
|
110
|
+
[Active test runs: ${w.runs.map(h=>`${h.runId}: ${h.ticketKey||h.spec} (${h.status})`).join(", ")}. Use run_status("all") to check progress.]`)}catch{}let x=Ie.trim();x?A.push({role:"ai",content:x+T}):A.push({role:"ai",content:`[interrupted \u2014 new message]${T}`})}else{let T=String(m?.message||m||"Unknown error");/413|payload too large|request payload too large/i.test(T)?(d.pushAssistant(i.yellow("Request became too large for the proxy (413).")),d.pushSystem(i.gray("Try: /clear, then retry your command; or shorten command/context."))):d.pushAssistant(i.red(`Error: ${T}`)),A.push({role:"ai",content:`[Error: ${m.message}]`})}}finally{Z=null,re=!1}if(d.refreshPrompt(),J.length>0){let m=J.shift();we=!0,setImmediate(()=>C.emit("line",m))}}catch(g){d.pushSystem(i.red(`Input handling error: ${g?.message||String(g)}`)),d.refreshPrompt()}}),C.on("SIGINT",()=>{if(Z){Z.abort();return}Xe()}),C.on("close",Xe);let Ho=()=>{process.stdin?.off?(process.stdin.off("data",De),process.stdin.off("keypress",st)):process.stdin?.removeListener&&(process.stdin.removeListener("data",De),process.stdin.removeListener("keypress",st))};C.on("close",Ho)})}export{vr as _buildPrompt,ls as _checkEnvKeys,cs as _formatHistory,$r as _inferAgentType,Ar as chatCommand};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
function c(e,r=""){return`${String(e).replace(/\/+$/,"")}/agents/credentials${r}`}function
|
|
1
|
+
function c(e,r=""){return`${String(e).replace(/\/+$/,"")}/agents/credentials${r}`}function u(){let e=new Error("Session expired \u2014 run zibby login");return e.code="AUTH_EXPIRED",e}async function f({apiUrl:e,sessionToken:r}){if(!r)return{credentials:[],by_type:{oauth:[],api:[]},total:0};let t=await fetch(c(e),{headers:{Authorization:`Bearer ${r}`}});if(t.status===401)throw u();if(t.status===404)return{credentials:[],by_type:{oauth:[],api:[]},total:0};if(!t.ok){let a=new Error(`List credentials failed (${t.status})`);throw a.status=t.status,a}return t.json()}async function l({apiUrl:e,sessionToken:r,type:t,token:a,source:n="~/.zibby/config.json"}){if(!r)throw new Error("No session token \u2014 run zibby login first");let o=await fetch(c(e),{method:"POST",headers:{Authorization:`Bearer ${r}`,"Content-Type":"application/json"},body:JSON.stringify({type:t,token:a,source:n})});if(o.status===401)throw u();if(!o.ok){let s=`Add credential failed (${o.status})`;try{let d=await o.json();d?.error&&(s=`${s}: ${d.error}`)}catch{}let i=new Error(s);throw i.status=o.status,i}return o.json()}async function h({apiUrl:e,sessionToken:r,type:t,index:a}){if(!r)throw new Error("No session token \u2014 run zibby login first");let n=await fetch(c(e,`/${encodeURIComponent(t)}/${encodeURIComponent(a)}`),{method:"DELETE",headers:{Authorization:`Bearer ${r}`}});if(n.status===401)throw u();if(!n.ok){let o=new Error(`Delete credential failed (${n.status})`);throw o.status=n.status,o}return n.json()}async function y({apiUrl:e,sessionToken:r,credentials:t}){let a=0,n=0,o=[];for(let s of t)try{let i=await l({apiUrl:e,sessionToken:r,type:s.type,token:s.token,source:s.source_var||s.source||"local"});i.deduped?n+=1:i.added&&(a+=1)}catch(i){o.push({masked:s.token?`***${s.token.slice(-4)}`:"***",error:i.message})}return{added:a,deduped:n,errors:o}}export{l as addCredential,h as deleteCredential,f as listCredentials,y as syncFromLocal};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import
|
|
1
|
+
import p from"node:fs/promises";import O from"node:path";import _ from"node:os";var m=O.join(_.homedir(),".zibby","config.json"),u={CLAUDE_CODE_OAUTH_TOKEN:"oauth",CLAUDE_CODE_OAUTH_TOKEN_POOL:"oauth",ANTHROPIC_AUTH_TOKEN:"oauth",ANTHROPIC_API_KEY:"api",ANTHROPIC_API_KEY_POOL:"api"};function h(n){if(!n)return[];let s;try{s=JSON.parse(n)}catch{return[]}let e=s?.agentKeys;if(!e||typeof e!="object")return[];let c=[],i=new Set;for(let[t,f]of Object.entries(u)){let r=e[t];if(!r||typeof r!="string")continue;let a=t.endsWith("_POOL")?r.split(",").map(o=>o.trim()).filter(Boolean):[r.trim()];for(let o of a)o.length<8||i.has(o)||(i.add(o),c.push({type:f,token:o,source_var:t}))}return c}async function l(n=m){let s;try{s=await p.readFile(n,"utf8")}catch(e){if(e.code==="ENOENT")return[];throw e}return h(s)}async function E({filepath:n,env:s=process.env}={}){let e=await l(n),c=new Set(e.map(t=>t.token)),i=[];for(let[t,f]of Object.entries(u)){let r=s[t];if(!r)continue;let a=t.endsWith("_POOL")?r.split(",").map(o=>o.trim()).filter(Boolean):[r];for(let o of a)o.length<8||c.has(o)||(c.add(o),i.push({type:f,token:o,source_var:t,source:"process.env"}))}return{config:e.map(t=>({...t,source:"config.json"})),env:i,all:[...e.map(t=>({...t,source:"config.json"})),...i]}}function d(n){return!n||typeof n!="string"||n.length<=4?"***":`***${n.slice(-4)}`}export{m as DEFAULT_CONFIG_PATH,E as discoverCredentials,d as maskToken,h as parseConfigJson,l as readCredentialsConfig};
|