@vibetonomy/agent 0.0.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/bin/launch.js ADDED
@@ -0,0 +1,125 @@
1
+ #!/usr/bin/env node
2
+
3
+ // @vibetonomy/agent launcher
4
+ // Detects platform, resolves the correct Go binary from the platform-specific
5
+ // npm package, sets --sdk-bridge-path to the bundled bridge, and spawns the agent.
6
+
7
+ import { spawn } from "node:child_process";
8
+ import { createRequire } from "node:module";
9
+ import { fileURLToPath } from "node:url";
10
+ import { dirname, join, resolve } from "node:path";
11
+ import { existsSync } from "node:fs";
12
+
13
+ const __dirname = dirname(fileURLToPath(import.meta.url));
14
+ const require = createRequire(import.meta.url);
15
+
16
+ // Map Node.js platform/arch to our package names
17
+ const PLATFORMS = {
18
+ "linux-x64": "@vibetonomy/agent-linux-x64",
19
+ "linux-arm64": "@vibetonomy/agent-linux-arm64",
20
+ "darwin-arm64": "@vibetonomy/agent-darwin-arm64",
21
+ "darwin-x64": "@vibetonomy/agent-darwin-x64",
22
+ "win32-x64": "@vibetonomy/agent-win-x64",
23
+ };
24
+
25
+ function getBinaryPath() {
26
+ const key = `${process.platform}-${process.arch}`;
27
+ const pkg = PLATFORMS[key];
28
+
29
+ if (!pkg) {
30
+ console.error(
31
+ `Unsupported platform: ${process.platform}-${process.arch}\n` +
32
+ `Supported: ${Object.keys(PLATFORMS).join(", ")}`,
33
+ );
34
+ process.exit(1);
35
+ }
36
+
37
+ // Resolve the platform package directory, then find the binary inside it
38
+ let pkgDir;
39
+ try {
40
+ const pkgJson = require.resolve(`${pkg}/package.json`);
41
+ pkgDir = dirname(pkgJson);
42
+ } catch {
43
+ console.error(
44
+ `Platform package ${pkg} is not installed.\n` +
45
+ `Try: npm install ${pkg}`,
46
+ );
47
+ process.exit(1);
48
+ }
49
+
50
+ const ext = process.platform === "win32" ? ".exe" : "";
51
+ const binaryPath = join(pkgDir, "bin", `agent${ext}`);
52
+
53
+ if (!existsSync(binaryPath)) {
54
+ console.error(
55
+ `Agent binary not found at ${binaryPath}\n` +
56
+ `The platform package may be corrupted. Try reinstalling.`,
57
+ );
58
+ process.exit(1);
59
+ }
60
+
61
+ return binaryPath;
62
+ }
63
+
64
+ function getBridgePath() {
65
+ // The bundled sdk-bridge lives alongside this launcher
66
+ const bridgePath = resolve(__dirname, "..", "bridge", "dist", "index.js");
67
+
68
+ if (!existsSync(bridgePath)) {
69
+ // Bridge is optional — agent falls back to Chat V1 (tmux) without it
70
+ return null;
71
+ }
72
+
73
+ return bridgePath;
74
+ }
75
+
76
+ function main() {
77
+ const binaryPath = getBinaryPath();
78
+ const bridgePath = getBridgePath();
79
+
80
+ // Build args: pass through everything the user provided
81
+ const args = process.argv.slice(2);
82
+
83
+ // If the user hasn't explicitly set --sdk-bridge-path and we have a bundled bridge,
84
+ // inject it so Chat V2 works out of the box
85
+ if (bridgePath && !args.some((a) => a.startsWith("--sdk-bridge-path"))) {
86
+ // Find the subcommand position to inject the flag after it
87
+ // Commands: start, pair, stop, status
88
+ const subcommands = ["start", "pair", "stop", "status"];
89
+ const subIdx = args.findIndex((a) => subcommands.includes(a));
90
+
91
+ if (subIdx !== -1 && args[subIdx] === "start") {
92
+ // Inject after the subcommand
93
+ args.splice(subIdx + 1, 0, "--sdk-bridge-path", bridgePath);
94
+ } else if (args.length === 0) {
95
+ // No subcommand — agent will show help, just pass through
96
+ }
97
+ }
98
+
99
+ const child = spawn(binaryPath, args, {
100
+ stdio: "inherit",
101
+ env: process.env,
102
+ });
103
+
104
+ child.on("error", (err) => {
105
+ console.error(`Failed to start agent: ${err.message}`);
106
+ process.exit(1);
107
+ });
108
+
109
+ child.on("exit", (code, signal) => {
110
+ if (signal) {
111
+ process.kill(process.pid, signal);
112
+ } else {
113
+ process.exit(code ?? 1);
114
+ }
115
+ });
116
+
117
+ // Forward signals to child
118
+ for (const sig of ["SIGINT", "SIGTERM"]) {
119
+ process.on(sig, () => {
120
+ child.kill(sig);
121
+ });
122
+ }
123
+ }
124
+
125
+ main();
@@ -0,0 +1,5 @@
1
+ import{createInterface as q}from"node:readline";function x(t,e,r){if(e.session_id&&typeof e.session_id=="string"&&e.session_id!==t.cliSessionId&&(t.cliSessionId=e.session_id,r({type:"session_id",cliSessionId:t.cliSessionId,...t.relaySessionId?{relaySessionId:t.relaySessionId}:{}})),e.uuid&&typeof e.uuid=="string"&&(e.type==="user"&&!e.parent_tool_use_id?r({type:"message_uuid",uuid:e.uuid,messageType:"user"}):e.type==="assistant"&&r({type:"message_uuid",uuid:e.uuid,messageType:"assistant"})),e.type==="system"&&e.subtype==="init"){e.slash_commands&&Array.isArray(e.slash_commands)&&r({type:"slash_commands",commands:e.slash_commands}),e.model&&typeof e.model=="string"&&r({type:"model_info",model:e.model,models:e.models||[]}),e.fast_mode_state&&typeof e.fast_mode_state=="string"&&r({type:"fast_mode_state",state:e.fast_mode_state});return}if(e.type==="stream_event"&&e.event){P(t,e.event,r);return}if((e.type==="assistant"||e.type==="user")&&e.message&&typeof e.message=="object"){let o=e.message.content;if(e.parent_tool_use_id&&typeof e.parent_tool_use_id=="string"){U(t,e,r);return}if(e.type==="assistant"&&!t.streamedText&&Array.isArray(o)){let i=o.filter(n=>n.type==="text").map(n=>n.text).join("");i&&r({type:"delta",text:i})}if(e.type==="user"){let i="";if(typeof o=="string"?i=o:Array.isArray(o)&&(i=o.filter(n=>n.type==="text").map(n=>n.text).join(`
2
+ `)),i.indexOf("local-command-stdout")!==-1){let n=i.match(/<local-command-stdout>([\s\S]*?)<\/local-command-stdout>/);n&&r({type:"slash_command_result",text:n[1].trim()})}}if(Array.isArray(o)){for(let i of o)if(i.type==="tool_result"&&typeof i.tool_use_id=="string"&&!t.sentToolResults[i.tool_use_id]){t.activeTaskToolIds[i.tool_use_id]&&(r({type:"subagent_done",parentToolId:i.tool_use_id}),delete t.activeTaskToolIds[i.tool_use_id]);let n="";typeof i.content=="string"?n=i.content:Array.isArray(i.content)&&(n=i.content.filter(l=>l.type==="text").map(l=>l.text).join(`
3
+ `)),t.sentToolResults[i.tool_use_id]=!0,r({type:"tool_result",id:i.tool_use_id,content:n,is_error:i.is_error||!1})}}return}if(e.type==="result"){t.blocks={},t.sentToolResults={},t.activeTaskToolIds={},t.taskIdMap={},t.isProcessing=!1,r({type:"result",cost:e.total_cost_usd??null,duration:e.duration_ms??null,usage:e.usage??null,modelUsage:e.modelUsage??null,sessionId:e.session_id}),e.fast_mode_state&&typeof e.fast_mode_state=="string"&&r({type:"fast_mode_state",state:e.fast_mode_state}),r({type:"done",code:0}),t.responsePreview="",t.streamedText=!1;return}if(e.type==="system"&&e.subtype==="status"){e.status==="compacting"?(r({type:"compacting",active:!0}),t.compacting=!0):t.compacting&&(r({type:"compacting",active:!1}),t.compacting=!1);return}if(e.type==="system"&&e.subtype==="task_started"){let s=e.tool_use_id;s&&(e.task_id&&(t.taskIdMap[s]=e.task_id),r({type:"task_started",parentToolId:s,taskId:e.task_id||"",description:e.description||""}));return}if(e.type==="system"&&e.subtype==="task_progress"){let s=e.tool_use_id;s&&r({type:"task_progress",parentToolId:s,taskId:e.task_id,usage:e.usage??null,lastToolName:e.last_tool_name||void 0,description:e.description||""});return}if(e.type==="tool_progress"){let s=e.parent_tool_use_id;s&&r({type:"subagent_activity",parentToolId:s,text:e.content||""});return}if(e.type==="task_notification"){let s=e.parent_tool_use_id;if(s&&r({type:"subagent_done",parentToolId:s,status:e.status||"completed",summary:e.summary||"",usage:e.usage??null}),e.task_id&&typeof e.task_id=="string"){for(let o of Object.keys(t.taskIdMap))if(t.taskIdMap[o]===e.task_id){delete t.taskIdMap[o];break}}return}if(e.type==="rate_limit_event"&&e.rate_limit_info){let s=e.rate_limit_info;(s.status==="allowed_warning"||s.status==="rejected")&&r({type:"rate_limit",status:s.status,resetsAt:s.resetsAt?s.resetsAt*1e3:null,rateLimitType:s.rateLimitType||null,utilization:s.utilization||null});return}if(e.type==="prompt_suggestion"){r({type:"prompt_suggestion",suggestion:e.suggestion||""});return}}function P(t,e,r){if(e.type==="content_block_start"){let s=e.content_block,o=e.index;s.type==="tool_use"?(t.blocks[o]={type:"tool_use",id:s.id,name:s.name,inputJson:""},r({type:"tool_start",id:s.id,name:s.name})):s.type==="thinking"?(t.blocks[o]={type:"thinking",thinkingText:"",startTime:Date.now()},r({type:"thinking_start"})):s.type==="text"&&(t.blocks[o]={type:"text"});return}if(e.type==="content_block_delta"&&e.delta){let s=e.index,o=e.delta;o.type==="text_delta"&&typeof o.text=="string"?(t.streamedText=!0,t.responsePreview.length<200&&(t.responsePreview+=o.text),r({type:"delta",text:o.text})):o.type==="input_json_delta"&&t.blocks[s]?t.blocks[s].inputJson=(t.blocks[s].inputJson||"")+o.partial_json:o.type==="thinking_delta"&&t.blocks[s]&&(t.blocks[s].thinkingText=(t.blocks[s].thinkingText||"")+o.thinking,r({type:"thinking_delta",text:o.thinking}));return}if(e.type==="content_block_stop"){let s=e.index,o=t.blocks[s];if(o&&o.type==="tool_use"){let i={};try{i=JSON.parse(o.inputJson||"{}")}catch{}r({type:"tool_executing",id:o.id,name:o.name,input:i}),o.name==="Task"&&(t.activeTaskToolIds[o.id]=!0)}else if(o&&o.type==="thinking"){let i=o.startTime?(Date.now()-o.startTime)/1e3:0;r({type:"thinking_stop",duration:i})}delete t.blocks[s];return}}function U(t,e,r){let s=e.parent_tool_use_id,i=e.message.content;if(Array.isArray(i)&&e.type==="assistant")for(let n of i)if(n.type==="tool_use"){let l=A(n.name,n.input);r({type:"subagent_tool",parentToolId:s,toolName:n.name,toolId:n.id,text:l})}else n.type==="thinking"?r({type:"subagent_activity",parentToolId:s,text:"Thinking..."}):n.type==="text"&&n.text&&r({type:"subagent_activity",parentToolId:s,text:"Writing response..."})}function A(t,e){return t==="Bash"&&e?.description?e.description:t==="Read"&&e?.file_path?"Reading "+e.file_path.split("/").pop():t==="Edit"&&e?.file_path?"Editing "+e.file_path.split("/").pop():t==="Write"&&e?.file_path?"Writing "+e.file_path.split("/").pop():t==="Grep"&&e?.pattern?"Searching for "+e.pattern:t==="Glob"&&e?.pattern?"Finding "+e.pattern:t==="WebSearch"&&e?.query?"Searching: "+e.query:t==="WebFetch"?"Fetching URL...":t==="Task"&&e?.description?e.description:"Running "+t+"..."}function S(){let t=[],e=null,r=!1;return{push(s){if(!r)if(e){let o=e;e=null,o({value:s,done:!1})}else t.push(s)},end(){if(r=!0,e){let s=e;e=null,s({value:void 0,done:!0})}},[Symbol.asyncIterator](){return{next(){return t.length>0?Promise.resolve({value:t.shift(),done:!1}):r?Promise.resolve({value:void 0,done:!0}):new Promise(s=>{e=s})}}}}}import{randomUUID as R}from"node:crypto";function w(t){let e={},r={},s={};return{handleCanUseTool(o,i,n){return o==="AskUserQuestion"?new Promise(l=>{r[n.toolUseID]={resolve:l,input:i},n.signal&&n.signal.addEventListener("abort",()=>{delete r[n.toolUseID],t({type:"ask_user_answered",toolId:n.toolUseID}),l({behavior:"deny",message:"Cancelled"})})}):s[o]?Promise.resolve({behavior:"allow",updatedInput:i}):new Promise(l=>{let y=R();e[y]={resolve:l,requestId:y,toolName:o},t({type:"permission_request",requestId:y,toolName:o,toolInput:i,toolUseId:n.toolUseID,decisionReason:n.decisionReason||""}),n.signal&&n.signal.addEventListener("abort",()=>{delete e[y],t({type:"permission_cancel",requestId:y}),l({behavior:"deny",message:"Request cancelled"})})})},handlePermissionResponse(o,i,n){let l=e[o];l&&(delete e[o],t({type:"permission_resolved",requestId:o,decision:i}),i==="allow"?(n&&(s[l.toolName]=!0),l.resolve({behavior:"allow"})):l.resolve({behavior:"deny",message:"User denied"}))},handleAskUserResponse(o,i){let n=r[o];n&&(delete r[o],t({type:"ask_user_answered",toolId:o}),n.resolve({behavior:"allow",updatedInput:i}))},clearPending(o){for(let i of Object.keys(r))o({type:"ask_user_answered",toolId:i}),r[i].resolve({behavior:"deny",message:"Session ended"}),delete r[i];for(let i of Object.keys(e))o({type:"permission_cancel",requestId:i}),e[i].resolve({behavior:"deny",message:"Session ended"}),delete e[i]}}}function k(){return{cliSessionId:null,relaySessionId:null,blocks:{},sentToolResults:{},streamedText:!1,responsePreview:"",activeTaskToolIds:{},taskIdMap:{},isProcessing:!1,compacting:!1}}function T(t){let e=null,r=null,s=null,o=null,i=k(),n=null,l="",y="acceptEdits",b="",g=0;async function I(){if(e)return e;try{return e=await import("@anthropic-ai/claude-agent-sdk"),e}catch(a){let c=a;throw new Error(`Failed to load Claude SDK: ${c.message}`)}}async function M(){if(!s)return;let a=g;try{for await(let c of s)x(i,c,t)}catch(c){if(a!==g)return;let u=c;if(i.isProcessing)if(i.isProcessing=!1,u.name==="AbortError"||o&&o.signal.aborted)t({type:"info",text:"Interrupted"}),t({type:"done",code:0});else{let f=(u.message||String(u)).toLowerCase(),h=f.includes("prompt is too long")||f.includes("context_length")||f.includes("maximum context length");t(h?{type:"error",text:"Conversation too long to continue."}:{type:"error",text:`Claude process error: ${u.message}`}),t({type:"done",code:1})}}finally{a===g&&(s=null,r=null,o=null,n&&n.clearPending(t))}}return{async startSession(a){let c=await I();g++,i=k(),i.isProcessing=!0,a.relaySessionId&&(i.relaySessionId=a.relaySessionId),n=w(t),r=S(),o=new AbortController,b=a.cwd;let u={cwd:a.cwd,settingSources:["user","project","local"],includePartialMessages:!0,enableFileCheckpointing:!0,abortController:o,promptSuggestions:!0,canUseTool:(d,f,h)=>n.handleCanUseTool(d,f,h)};if(a.model&&(u.model=a.model,l=a.model),a.permissionMode?(u.permissionMode=a.permissionMode,y=a.permissionMode):u.permissionMode=y,a.resume&&(u.resume=a.resume,i.cliSessionId=a.resume,c.getSessionMessages))try{let d=await c.getSessionMessages(a.resume);d&&d.length>0&&t({type:"session_history",messages:d,...i.relaySessionId?{relaySessionId:i.relaySessionId}:{}})}catch(d){t({type:"info",text:`Could not restore session history: ${d.message}`})}try{s=c.query({prompt:r,options:u})}catch(d){let f=d;i.isProcessing=!1,s=null,r=null,o=null,t({type:"error",text:`Failed to start query: ${f.message}`}),t({type:"done",code:1});return}M().catch(()=>{})},async requestHistory(a,c){let u=await I();if(!u.getSessionMessages)return;let d=c||i.relaySessionId;try{let f=await u.getSessionMessages(a);f&&f.length>0&&t({type:"session_history",messages:f,...d?{relaySessionId:d}:{}})}catch(f){t({type:"info",text:`Could not restore session history: ${f.message}`})}},pushUserMessage(a,c){if(a&&a.startsWith("/")&&a.split(/\s/)[0].toLowerCase()==="/clear"){g++,o&&o.abort(),r&&r.end(),this.startSession({cwd:b,model:l||void 0,permissionMode:y||void 0}).then(()=>{t({type:"slash_command_result",command:"clear",text:"Conversation cleared."})}).catch(f=>{t({type:"error",text:`Failed to clear session: ${f.message}`})});return}if(!r){t({type:"error",text:"No active session"});return}let u=[];if(c&&c.length>0)for(let d of c)u.push({type:"image",source:{type:"base64",media_type:d.mediaType,data:d.data}});a&&u.push({type:"text",text:a}),i.isProcessing=!0,i.streamedText=!1,i.responsePreview="",i.blocks={},i.sentToolResults={},r.push({type:"user",message:{role:"user",content:u}})},interrupt(){s?.interrupt?s.interrupt().catch(()=>{o&&o.abort()}):o&&o.abort()},async setModel(a){if(!s?.setModel){l=a,t({type:"model_info",model:a,models:[]});return}try{await s.setModel(a),l=a,t({type:"model_info",model:a,models:[]}),t({type:"config_state",model:l,mode:y,effort:"medium",betas:[]})}catch(c){t({type:"error",text:`Failed to switch model: ${c.message}`})}},async setMode(a){if(!s?.setPermissionMode){y=a,t({type:"config_state",model:l,mode:y,effort:"medium",betas:[]});return}try{await s.setPermissionMode(a),y=a,t({type:"config_state",model:l,mode:y,effort:"medium",betas:[]})}catch(c){t({type:"error",text:`Failed to set permission mode: ${c.message}`})}},handlePermissionResponse(a,c,u){n?.handlePermissionResponse(a,c,u)},handleAskUserResponse(a,c){n?.handleAskUserResponse(a,c)},shutdown(){s?.close?s.close():o&&o.abort(),r&&r.end()}}}function _(t){let e=JSON.stringify(t);process.stdout.write(e+`
4
+ `)}function m(t,e,r){let s={level:t,message:e,ts:new Date().toISOString(),...r};process.stderr.write(JSON.stringify(s)+`
5
+ `)}var p=T(_),v=q({input:process.stdin,crlfDelay:1/0});v.on("line",async t=>{if(!t.trim())return;let e;try{e=JSON.parse(t)}catch{m("error","Failed to parse inbound message",{raw:t.slice(0,200)});return}try{switch(e.type){case"start_session":m("info","Starting session",{cwd:e.cwd,model:e.model}),await p.startSession({cwd:e.cwd,model:e.model,permissionMode:e.permissionMode,resume:e.resume,relaySessionId:e.relaySessionId});break;case"user_message":m("info","User message received",{textLength:e.text?.length??0}),p.pushUserMessage(e.text,e.images);break;case"interrupt":m("info","Interrupt requested"),p.interrupt();break;case"permission_response":m("info","Permission response",{requestId:e.requestId,decision:e.decision}),p.handlePermissionResponse(e.requestId,e.decision,e.allowForSession);break;case"ask_user_response":m("info","Ask user response",{toolId:e.toolId}),p.handleAskUserResponse(e.toolId,e.answers);break;case"set_model":m("info","Set model",{model:e.model}),await p.setModel(e.model);break;case"set_mode":m("info","Set mode",{mode:e.mode}),await p.setMode(e.mode);break;case"request_history":m("info","History request",{resume:e.resume}),await p.requestHistory(e.resume,e.relaySessionId);break;case"shutdown":m("info","Shutdown requested"),p.shutdown(),setTimeout(()=>process.exit(0),500);break;default:m("warn","Unknown message type",{type:e.type})}}catch(r){let s=r;m("error",`Error handling message type=${e.type}`,{error:s.message}),_({type:"error",text:`Internal bridge error: ${s.message}`})}});v.on("close",()=>{m("info","stdin closed, shutting down"),p.shutdown(),setTimeout(()=>process.exit(0),500)});process.on("uncaughtException",t=>{m("error","Uncaught exception",{error:t.message,stack:t.stack}),_({type:"error",text:`Bridge crash: ${t.message}`}),_({type:"done",code:1}),process.exit(1)});process.on("unhandledRejection",t=>{let e=t instanceof Error?t.message:String(t);m("error","Unhandled rejection",{error:e})});_({type:"ready"});m("info","SDK bridge ready");
package/package.json ADDED
@@ -0,0 +1,27 @@
1
+ {
2
+ "name": "@vibetonomy/agent",
3
+ "version": "0.0.0",
4
+ "description": "Vibetonomy agent — managed Claude Code sessions via npx",
5
+ "license": "UNLICENSED",
6
+ "type": "module",
7
+ "bin": {
8
+ "vibetonomy-agent": "./bin/launch.js"
9
+ },
10
+ "files": [
11
+ "bin/launch.js",
12
+ "bridge/dist/index.js"
13
+ ],
14
+ "dependencies": {
15
+ "@anthropic-ai/claude-agent-sdk": "^0.2.63"
16
+ },
17
+ "optionalDependencies": {
18
+ "@vibetonomy/agent-linux-x64": "0.1.0",
19
+ "@vibetonomy/agent-linux-arm64": "0.1.0",
20
+ "@vibetonomy/agent-darwin-arm64": "0.1.0",
21
+ "@vibetonomy/agent-darwin-x64": "0.1.0",
22
+ "@vibetonomy/agent-win-x64": "0.1.0"
23
+ },
24
+ "engines": {
25
+ "node": ">=18.0.0"
26
+ }
27
+ }