jiranimo 1.0.0 → 1.2.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/dist/.build-meta.json +2 -2
- package/dist/index.js +1 -1
- package/package.json +1 -4
package/dist/.build-meta.json
CHANGED
package/dist/index.js
CHANGED
|
@@ -369,7 +369,7 @@ data:
|
|
|
369
369
|
`;return n&&(o+=`id: ${n}
|
|
370
370
|
`),o+=`data: ${JSON.stringify(i)}
|
|
371
371
|
|
|
372
|
-
`,e.enqueue(r.encode(o)),!0}catch(o){return this.onerror?.(o),!1}}handleUnsupportedRequest(){return this.onerror?.(new Error("Method not allowed.")),new Response(JSON.stringify({jsonrpc:"2.0",error:{code:-32e3,message:"Method not allowed."},id:null}),{status:405,headers:{Allow:"GET, POST, DELETE","Content-Type":"application/json"}})}async handlePostRequest(e,r){try{let i=e.headers.get("accept");if(!i?.includes("application/json")||!i.includes("text/event-stream"))return this.onerror?.(new Error("Not Acceptable: Client must accept both application/json and text/event-stream")),this.createJsonErrorResponse(406,-32e3,"Not Acceptable: Client must accept both application/json and text/event-stream");let n=e.headers.get("content-type");if(!n||!n.includes("application/json"))return this.onerror?.(new Error("Unsupported Media Type: Content-Type must be application/json")),this.createJsonErrorResponse(415,-32e3,"Unsupported Media Type: Content-Type must be application/json");let o={headers:Object.fromEntries(e.headers.entries()),url:new URL(e.url)},a;if(r?.parsedBody!==void 0)a=r.parsedBody;else try{a=await e.json()}catch{return this.onerror?.(new Error("Parse error: Invalid JSON")),this.createJsonErrorResponse(400,-32700,"Parse error: Invalid JSON")}let s;try{Array.isArray(a)?s=a.map(x=>Ay.parse(x)):s=[Ay.parse(a)]}catch{return this.onerror?.(new Error("Parse error: Invalid JSON-RPC message")),this.createJsonErrorResponse(400,-32700,"Parse error: Invalid JSON-RPC message")}let c=s.some(Ny);if(c){if(this._initialized&&this.sessionId!==void 0)return this.onerror?.(new Error("Invalid Request: Server already initialized")),this.createJsonErrorResponse(400,-32600,"Invalid Request: Server already initialized");if(s.length>1)return this.onerror?.(new Error("Invalid Request: Only one initialization request is allowed")),this.createJsonErrorResponse(400,-32600,"Invalid Request: Only one initialization request is allowed");this.sessionId=this.sessionIdGenerator?.(),this._initialized=!0,this.sessionId&&this._onsessioninitialized&&await Promise.resolve(this._onsessioninitialized(this.sessionId))}if(!c){let x=this.validateSession(e);if(x)return x;let $=this.validateProtocolVersion(e);if($)return $}if(!s.some(Pn)){for(let x of s)this.onmessage?.(x,{authInfo:r?.authInfo,requestInfo:o});return new Response(null,{status:202})}let l=crypto.randomUUID(),p=s.find(x=>Ny(x)),d=p?p.params.protocolVersion:e.headers.get("mcp-protocol-version")??fS;if(this._enableJsonResponse)return new Promise(x=>{this._streamMapping.set(l,{resolveJson:x,cleanup:()=>{this._streamMapping.delete(l)}});for(let $ of s)Pn($)&&this._requestToStreamMapping.set($.id,l);for(let $ of s)this.onmessage?.($,{authInfo:r?.authInfo,requestInfo:o})});let f=new TextEncoder,m,h=new ReadableStream({start:x=>{m=x},cancel:()=>{this._streamMapping.delete(l)}}),g={"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"};this.sessionId!==void 0&&(g["mcp-session-id"]=this.sessionId);for(let x of s)Pn(x)&&(this._streamMapping.set(l,{controller:m,encoder:f,cleanup:()=>{this._streamMapping.delete(l);try{m.close()}catch{}}}),this._requestToStreamMapping.set(x.id,l));await this.writePrimingEvent(m,f,l,d);for(let x of s){let $,_;Pn(x)&&this._eventStore&&d>="2025-11-25"&&($=()=>{this.closeSSEStream(x.id)},_=()=>{this.closeStandaloneSSEStream()}),this.onmessage?.(x,{authInfo:r?.authInfo,requestInfo:o,closeSSEStream:$,closeStandaloneSSEStream:_})}return new Response(h,{status:200,headers:g})}catch(i){return this.onerror?.(i),this.createJsonErrorResponse(400,-32700,"Parse error",{data:String(i)})}}async handleDeleteRequest(e){let r=this.validateSession(e);if(r)return r;let i=this.validateProtocolVersion(e);return i||(await Promise.resolve(this._onsessionclosed?.(this.sessionId)),await this.close(),new Response(null,{status:200}))}validateSession(e){if(this.sessionIdGenerator===void 0)return;if(!this._initialized)return this.onerror?.(new Error("Bad Request: Server not initialized")),this.createJsonErrorResponse(400,-32e3,"Bad Request: Server not initialized");let r=e.headers.get("mcp-session-id");if(!r)return this.onerror?.(new Error("Bad Request: Mcp-Session-Id header is required")),this.createJsonErrorResponse(400,-32e3,"Bad Request: Mcp-Session-Id header is required");if(r!==this.sessionId)return this.onerror?.(new Error("Session not found")),this.createJsonErrorResponse(404,-32001,"Session not found")}validateProtocolVersion(e){let r=e.headers.get("mcp-protocol-version");if(r!==null&&!No.includes(r))return this.onerror?.(new Error(`Bad Request: Unsupported protocol version: ${r} (supported versions: ${No.join(", ")})`)),this.createJsonErrorResponse(400,-32e3,`Bad Request: Unsupported protocol version: ${r} (supported versions: ${No.join(", ")})`)}async close(){this._streamMapping.forEach(({cleanup:e})=>{e()}),this._streamMapping.clear(),this._requestResponseMap.clear(),this.onclose?.()}closeSSEStream(e){let r=this._requestToStreamMapping.get(e);if(!r)return;let i=this._streamMapping.get(r);i&&i.cleanup()}closeStandaloneSSEStream(){let e=this._streamMapping.get(this._standaloneSseStreamId);e&&e.cleanup()}async send(e,r){let i=r?.relatedRequestId;if((Vr(e)||Do(e))&&(i=e.id),i===void 0){if(Vr(e)||Do(e))throw new Error("Cannot send a response on a standalone SSE stream unless resuming a previous client request");let a;this._eventStore&&(a=await this._eventStore.storeEvent(this._standaloneSseStreamId,e));let s=this._streamMapping.get(this._standaloneSseStreamId);if(s===void 0)return;s.controller&&s.encoder&&this.writeSSEEvent(s.controller,s.encoder,e,a);return}let n=this._requestToStreamMapping.get(i);if(!n)throw new Error(`No connection established for request ID: ${String(i)}`);let o=this._streamMapping.get(n);if(!this._enableJsonResponse&&o?.controller&&o?.encoder){let a;this._eventStore&&(a=await this._eventStore.storeEvent(n,e)),this.writeSSEEvent(o.controller,o.encoder,e,a)}if(Vr(e)||Do(e)){this._requestResponseMap.set(i,e);let a=Array.from(this._requestToStreamMapping.entries()).filter(([c,u])=>u===n).map(([c])=>c);if(a.every(c=>this._requestResponseMap.has(c))){if(!o)throw new Error(`No connection established for request ID: ${String(i)}`);if(this._enableJsonResponse&&o.resolveJson){let c={"Content-Type":"application/json"};this.sessionId!==void 0&&(c["mcp-session-id"]=this.sessionId);let u=a.map(l=>this._requestResponseMap.get(l));u.length===1?o.resolveJson(new Response(JSON.stringify(u[0]),{status:200,headers:c})):o.resolveJson(new Response(JSON.stringify(u),{status:200,headers:c}))}else o.cleanup();for(let c of a)this._requestResponseMap.delete(c),this._requestToStreamMapping.delete(c)}}}};var Xf=class{constructor(e={}){this._requestContext=new WeakMap,this._webStandardTransport=new Kf(e),this._requestListener=t0(async r=>{let i=this._requestContext.get(r);return this._webStandardTransport.handleRequest(r,{authInfo:i?.authInfo,parsedBody:i?.parsedBody})},{overrideGlobalObjects:!1})}get sessionId(){return this._webStandardTransport.sessionId}set onclose(e){this._webStandardTransport.onclose=e}get onclose(){return this._webStandardTransport.onclose}set onerror(e){this._webStandardTransport.onerror=e}get onerror(){return this._webStandardTransport.onerror}set onmessage(e){this._webStandardTransport.onmessage=e}get onmessage(){return this._webStandardTransport.onmessage}async start(){return this._webStandardTransport.start()}async close(){return this._webStandardTransport.close()}async send(e,r){return this._webStandardTransport.send(e,r)}async handleRequest(e,r,i){let n=e.auth;await t0(async a=>this._webStandardTransport.handleRequest(a,{authInfo:n,parsedBody:i}),{overrideGlobalObjects:!1})(e,r)}closeSSEStream(e){this._webStandardTransport.closeSSEStream(e)}closeStandaloneSSEStream(){this._webStandardTransport.closeStandaloneSSEStream()}};import{writeFileSync as fZ,unlinkSync as mZ,readFileSync as hZ}from"node:fs";import{join as dI}from"node:path";var gZ="7922f663cfcfe9b4b0c3119c2b61b7d8";async function vZ(t){let r=hZ(t).toString("base64"),i=new URLSearchParams({key:gZ,image:r}),n=await fetch("https://api.imgbb.com/1/upload",{method:"POST",body:i});if(!n.ok)throw new Error(`imgbb upload failed: ${n.status} ${await n.text()}`);return(await n.json()).data.url}function fI(t){return async(e,r)=>{let i=new Hf({name:"jiranimo",version:"1.0.0"});i.tool("jiranimo_progress",{task_key:G.string(),message:G.string()},async({task_key:o,message:a})=>(t.reportProgress(o,a),{content:[{type:"text",text:"ok"}]})),i.tool("jiranimo_report_pr",{task_key:G.string(),pr_url:G.string(),pr_number:G.number().int(),branch_name:G.string()},async({task_key:o,pr_url:a,pr_number:s,branch_name:c})=>(t.reportPr(o,a,s,c),{content:[{type:"text",text:"PR recorded"}]})),i.tool("jiranimo_complete",{task_key:G.string(),summary:G.string()},async({task_key:o,summary:a})=>(t.completeViaAgent(o,a),{content:[{type:"text",text:"Task marked complete"}]})),i.tool("jiranimo_fail",{task_key:G.string(),error_message:G.string()},async({task_key:o,error_message:a})=>(t.failViaAgent(o,a),{content:[{type:"text",text:"Task marked failed"}]})),i.tool("jiranimo_screenshot_failed",{task_key:G.string(),reason:G.string()},async({task_key:o,reason:a})=>(t.reportScreenshotFailed(o,a),{content:[{type:"text",text:"Screenshot failure recorded"}]})),i.tool("jiranimo_upload_screenshot",{file_path:G.string()},async({file_path:o})=>({content:[{type:"text",text:await vZ(o)}]}));let n=new Xf({sessionIdGenerator:void 0});await i.connect(n),await n.handleRequest(e,r,e.body),r.on("close",()=>{n.close(),i.close()})}}function mI(t,e){let r={mcpServers:{jiranimo:{type:"http",url:`http://127.0.0.1:${e}/mcp`},playwright:{type:"stdio",command:"npx",args:["@playwright/mcp@latest","--headless"]}}};fZ(dI(t,".mcp.json"),JSON.stringify(r,null,2))}function hI(t){try{mZ(dI(t,".mcp.json"))}catch{}}import{appendFileSync as yZ,mkdirSync as xZ}from"node:fs";import{homedir as bZ}from"node:os";import{dirname as _Z,join as wZ,resolve as $Z}from"node:path";var kZ={level:"info",logHttpRequests:!1,logHttpBodies:!1,logClaudeRawOutput:!1},gI={debug:10,info:20,warn:30,error:40},r0=class t{config;filePath;scope;constructor(e,r){this.config=Fc(e);let i=e?.logsDir??$Z(bZ(),".jiranimo","logs");xZ(i,{recursive:!0}),this.filePath=wZ(i,"server.log"),this.scope=r}child(e){let r=this.scope?`${this.scope}:${e}`:e;return new t({logsDir:_Z(this.filePath),logging:this.config},r)}debug(e,r){this.write("debug",e,r)}info(e,r){this.write("info",e,r)}warn(e,r){this.write("warn",e,r)}error(e,r){this.write("error",e,r)}isConsoleLevelEnabled(e){return gI[e]>=gI[this.config.level]}getConfig(){return this.config}write(e,r,i){if(!this.isConsoleLevelEnabled(e))return;let n=EZ(e,this.scope,r,i),o=SZ(n);try{yZ(this.filePath,`${o}
|
|
372
|
+
`,e.enqueue(r.encode(o)),!0}catch(o){return this.onerror?.(o),!1}}handleUnsupportedRequest(){return this.onerror?.(new Error("Method not allowed.")),new Response(JSON.stringify({jsonrpc:"2.0",error:{code:-32e3,message:"Method not allowed."},id:null}),{status:405,headers:{Allow:"GET, POST, DELETE","Content-Type":"application/json"}})}async handlePostRequest(e,r){try{let i=e.headers.get("accept");if(!i?.includes("application/json")||!i.includes("text/event-stream"))return this.onerror?.(new Error("Not Acceptable: Client must accept both application/json and text/event-stream")),this.createJsonErrorResponse(406,-32e3,"Not Acceptable: Client must accept both application/json and text/event-stream");let n=e.headers.get("content-type");if(!n||!n.includes("application/json"))return this.onerror?.(new Error("Unsupported Media Type: Content-Type must be application/json")),this.createJsonErrorResponse(415,-32e3,"Unsupported Media Type: Content-Type must be application/json");let o={headers:Object.fromEntries(e.headers.entries()),url:new URL(e.url)},a;if(r?.parsedBody!==void 0)a=r.parsedBody;else try{a=await e.json()}catch{return this.onerror?.(new Error("Parse error: Invalid JSON")),this.createJsonErrorResponse(400,-32700,"Parse error: Invalid JSON")}let s;try{Array.isArray(a)?s=a.map(x=>Ay.parse(x)):s=[Ay.parse(a)]}catch{return this.onerror?.(new Error("Parse error: Invalid JSON-RPC message")),this.createJsonErrorResponse(400,-32700,"Parse error: Invalid JSON-RPC message")}let c=s.some(Ny);if(c){if(this._initialized&&this.sessionId!==void 0)return this.onerror?.(new Error("Invalid Request: Server already initialized")),this.createJsonErrorResponse(400,-32600,"Invalid Request: Server already initialized");if(s.length>1)return this.onerror?.(new Error("Invalid Request: Only one initialization request is allowed")),this.createJsonErrorResponse(400,-32600,"Invalid Request: Only one initialization request is allowed");this.sessionId=this.sessionIdGenerator?.(),this._initialized=!0,this.sessionId&&this._onsessioninitialized&&await Promise.resolve(this._onsessioninitialized(this.sessionId))}if(!c){let x=this.validateSession(e);if(x)return x;let $=this.validateProtocolVersion(e);if($)return $}if(!s.some(Pn)){for(let x of s)this.onmessage?.(x,{authInfo:r?.authInfo,requestInfo:o});return new Response(null,{status:202})}let l=crypto.randomUUID(),p=s.find(x=>Ny(x)),d=p?p.params.protocolVersion:e.headers.get("mcp-protocol-version")??fS;if(this._enableJsonResponse)return new Promise(x=>{this._streamMapping.set(l,{resolveJson:x,cleanup:()=>{this._streamMapping.delete(l)}});for(let $ of s)Pn($)&&this._requestToStreamMapping.set($.id,l);for(let $ of s)this.onmessage?.($,{authInfo:r?.authInfo,requestInfo:o})});let f=new TextEncoder,m,h=new ReadableStream({start:x=>{m=x},cancel:()=>{this._streamMapping.delete(l)}}),g={"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"};this.sessionId!==void 0&&(g["mcp-session-id"]=this.sessionId);for(let x of s)Pn(x)&&(this._streamMapping.set(l,{controller:m,encoder:f,cleanup:()=>{this._streamMapping.delete(l);try{m.close()}catch{}}}),this._requestToStreamMapping.set(x.id,l));await this.writePrimingEvent(m,f,l,d);for(let x of s){let $,_;Pn(x)&&this._eventStore&&d>="2025-11-25"&&($=()=>{this.closeSSEStream(x.id)},_=()=>{this.closeStandaloneSSEStream()}),this.onmessage?.(x,{authInfo:r?.authInfo,requestInfo:o,closeSSEStream:$,closeStandaloneSSEStream:_})}return new Response(h,{status:200,headers:g})}catch(i){return this.onerror?.(i),this.createJsonErrorResponse(400,-32700,"Parse error",{data:String(i)})}}async handleDeleteRequest(e){let r=this.validateSession(e);if(r)return r;let i=this.validateProtocolVersion(e);return i||(await Promise.resolve(this._onsessionclosed?.(this.sessionId)),await this.close(),new Response(null,{status:200}))}validateSession(e){if(this.sessionIdGenerator===void 0)return;if(!this._initialized)return this.onerror?.(new Error("Bad Request: Server not initialized")),this.createJsonErrorResponse(400,-32e3,"Bad Request: Server not initialized");let r=e.headers.get("mcp-session-id");if(!r)return this.onerror?.(new Error("Bad Request: Mcp-Session-Id header is required")),this.createJsonErrorResponse(400,-32e3,"Bad Request: Mcp-Session-Id header is required");if(r!==this.sessionId)return this.onerror?.(new Error("Session not found")),this.createJsonErrorResponse(404,-32001,"Session not found")}validateProtocolVersion(e){let r=e.headers.get("mcp-protocol-version");if(r!==null&&!No.includes(r))return this.onerror?.(new Error(`Bad Request: Unsupported protocol version: ${r} (supported versions: ${No.join(", ")})`)),this.createJsonErrorResponse(400,-32e3,`Bad Request: Unsupported protocol version: ${r} (supported versions: ${No.join(", ")})`)}async close(){this._streamMapping.forEach(({cleanup:e})=>{e()}),this._streamMapping.clear(),this._requestResponseMap.clear(),this.onclose?.()}closeSSEStream(e){let r=this._requestToStreamMapping.get(e);if(!r)return;let i=this._streamMapping.get(r);i&&i.cleanup()}closeStandaloneSSEStream(){let e=this._streamMapping.get(this._standaloneSseStreamId);e&&e.cleanup()}async send(e,r){let i=r?.relatedRequestId;if((Vr(e)||Do(e))&&(i=e.id),i===void 0){if(Vr(e)||Do(e))throw new Error("Cannot send a response on a standalone SSE stream unless resuming a previous client request");let a;this._eventStore&&(a=await this._eventStore.storeEvent(this._standaloneSseStreamId,e));let s=this._streamMapping.get(this._standaloneSseStreamId);if(s===void 0)return;s.controller&&s.encoder&&this.writeSSEEvent(s.controller,s.encoder,e,a);return}let n=this._requestToStreamMapping.get(i);if(!n)throw new Error(`No connection established for request ID: ${String(i)}`);let o=this._streamMapping.get(n);if(!this._enableJsonResponse&&o?.controller&&o?.encoder){let a;this._eventStore&&(a=await this._eventStore.storeEvent(n,e)),this.writeSSEEvent(o.controller,o.encoder,e,a)}if(Vr(e)||Do(e)){this._requestResponseMap.set(i,e);let a=Array.from(this._requestToStreamMapping.entries()).filter(([c,u])=>u===n).map(([c])=>c);if(a.every(c=>this._requestResponseMap.has(c))){if(!o)throw new Error(`No connection established for request ID: ${String(i)}`);if(this._enableJsonResponse&&o.resolveJson){let c={"Content-Type":"application/json"};this.sessionId!==void 0&&(c["mcp-session-id"]=this.sessionId);let u=a.map(l=>this._requestResponseMap.get(l));u.length===1?o.resolveJson(new Response(JSON.stringify(u[0]),{status:200,headers:c})):o.resolveJson(new Response(JSON.stringify(u),{status:200,headers:c}))}else o.cleanup();for(let c of a)this._requestResponseMap.delete(c),this._requestToStreamMapping.delete(c)}}}};var Xf=class{constructor(e={}){this._requestContext=new WeakMap,this._webStandardTransport=new Kf(e),this._requestListener=t0(async r=>{let i=this._requestContext.get(r);return this._webStandardTransport.handleRequest(r,{authInfo:i?.authInfo,parsedBody:i?.parsedBody})},{overrideGlobalObjects:!1})}get sessionId(){return this._webStandardTransport.sessionId}set onclose(e){this._webStandardTransport.onclose=e}get onclose(){return this._webStandardTransport.onclose}set onerror(e){this._webStandardTransport.onerror=e}get onerror(){return this._webStandardTransport.onerror}set onmessage(e){this._webStandardTransport.onmessage=e}get onmessage(){return this._webStandardTransport.onmessage}async start(){return this._webStandardTransport.start()}async close(){return this._webStandardTransport.close()}async send(e,r){return this._webStandardTransport.send(e,r)}async handleRequest(e,r,i){let n=e.auth;await t0(async a=>this._webStandardTransport.handleRequest(a,{authInfo:n,parsedBody:i}),{overrideGlobalObjects:!1})(e,r)}closeSSEStream(e){this._webStandardTransport.closeSSEStream(e)}closeStandaloneSSEStream(){this._webStandardTransport.closeStandaloneSSEStream()}};import{writeFileSync as fZ,unlinkSync as mZ,readFileSync as hZ}from"node:fs";import{join as dI}from"node:path";var gZ="7922f663cfcfe9b4b0c3119c2b61b7d8";async function vZ(t){let r=hZ(t).toString("base64"),i=new URLSearchParams({key:gZ,image:r}),n=await fetch("https://api.imgbb.com/1/upload",{method:"POST",body:i});if(!n.ok)throw new Error(`imgbb upload failed: ${n.status} ${await n.text()}`);return(await n.json()).data.url}function fI(t){return async(e,r)=>{let i=new Hf({name:"jiranimo",version:"1.2.0"});i.tool("jiranimo_progress",{task_key:G.string(),message:G.string()},async({task_key:o,message:a})=>(t.reportProgress(o,a),{content:[{type:"text",text:"ok"}]})),i.tool("jiranimo_report_pr",{task_key:G.string(),pr_url:G.string(),pr_number:G.number().int(),branch_name:G.string()},async({task_key:o,pr_url:a,pr_number:s,branch_name:c})=>(t.reportPr(o,a,s,c),{content:[{type:"text",text:"PR recorded"}]})),i.tool("jiranimo_complete",{task_key:G.string(),summary:G.string()},async({task_key:o,summary:a})=>(t.completeViaAgent(o,a),{content:[{type:"text",text:"Task marked complete"}]})),i.tool("jiranimo_fail",{task_key:G.string(),error_message:G.string()},async({task_key:o,error_message:a})=>(t.failViaAgent(o,a),{content:[{type:"text",text:"Task marked failed"}]})),i.tool("jiranimo_screenshot_failed",{task_key:G.string(),reason:G.string()},async({task_key:o,reason:a})=>(t.reportScreenshotFailed(o,a),{content:[{type:"text",text:"Screenshot failure recorded"}]})),i.tool("jiranimo_upload_screenshot",{file_path:G.string()},async({file_path:o})=>({content:[{type:"text",text:await vZ(o)}]}));let n=new Xf({sessionIdGenerator:void 0});await i.connect(n),await n.handleRequest(e,r,e.body),r.on("close",()=>{n.close(),i.close()})}}function mI(t,e){let r={mcpServers:{jiranimo:{type:"http",url:`http://127.0.0.1:${e}/mcp`},playwright:{type:"stdio",command:"npx",args:["@playwright/mcp@latest","--headless"]}}};fZ(dI(t,".mcp.json"),JSON.stringify(r,null,2))}function hI(t){try{mZ(dI(t,".mcp.json"))}catch{}}import{appendFileSync as yZ,mkdirSync as xZ}from"node:fs";import{homedir as bZ}from"node:os";import{dirname as _Z,join as wZ,resolve as $Z}from"node:path";var kZ={level:"info",logHttpRequests:!1,logHttpBodies:!1,logClaudeRawOutput:!1},gI={debug:10,info:20,warn:30,error:40},r0=class t{config;filePath;scope;constructor(e,r){this.config=Fc(e);let i=e?.logsDir??$Z(bZ(),".jiranimo","logs");xZ(i,{recursive:!0}),this.filePath=wZ(i,"server.log"),this.scope=r}child(e){let r=this.scope?`${this.scope}:${e}`:e;return new t({logsDir:_Z(this.filePath),logging:this.config},r)}debug(e,r){this.write("debug",e,r)}info(e,r){this.write("info",e,r)}warn(e,r){this.write("warn",e,r)}error(e,r){this.write("error",e,r)}isConsoleLevelEnabled(e){return gI[e]>=gI[this.config.level]}getConfig(){return this.config}write(e,r,i){if(!this.isConsoleLevelEnabled(e))return;let n=EZ(e,this.scope,r,i),o=SZ(n);try{yZ(this.filePath,`${o}
|
|
373
373
|
`,"utf-8")}catch{}if(e==="error"){console.error(n);return}if(e==="warn"){console.warn(n);return}console.log(n)}};function SZ(t){return t.replace(/\u001B\[[0-9;]*m/g,"")}function Mn(t,e){return new r0(t,e)}function Fc(t){return{...kZ,...t?.logging??{}}}function vI(t){return[/chrome\/updater\//i,/GoogleUpdater/i,/VERBOSE\d?:chrome\//i].some(e=>e.test(t))}function EZ(t,e,r,i){let n=[new Date().toISOString(),t.toUpperCase()];e&&n.push(`[${e}]`),n.push(r);let o=TZ(i);return o&&n.push(o),n.join(" ")}function TZ(t){if(!t)return"";let e=Object.entries(t).filter(([,r])=>r!==void 0);return e.length===0?"":JSON.stringify(Object.fromEntries(e))}import{execFile as IZ}from"node:child_process";var PZ=10*1024*1024;function zZ(t){let e;try{e=new URL(t)}catch{throw new Error(`Invalid PR URL: ${t}`)}let r=e.pathname.match(/^\/([^/]+)\/([^/]+)\/pull\/(\d+)(?:\/|$)/);if(!r)throw new Error(`Unsupported PR URL: ${t}`);return{owner:r[1],repo:r[2],prNumber:Number(r[3])}}function xI(t,e){if(typeof e.id!="number")return;let r=e.updated_at??e.created_at;return r?`${t}:${e.id}:${r}`:void 0}function jZ(t){if(typeof t.id!="number"||typeof t.body!="string"||t.body.trim().length===0)return;let e=xI("review",t);if(e)return{id:t.id,fingerprint:e,kind:"review",author:t.user?.login||"unknown",body:t.body,path:typeof t.path=="string"?t.path:void 0,line:typeof t.line=="number"?t.line:typeof t.original_line=="number"?t.original_line:void 0,url:typeof t.html_url=="string"?t.html_url:void 0,created:typeof t.created_at=="string"?t.created_at:void 0,updated:typeof t.updated_at=="string"?t.updated_at:void 0}}function OZ(t){if(typeof t.id!="number"||typeof t.body!="string"||t.body.trim().length===0)return;let e=xI("conversation",t);if(e)return{id:t.id,fingerprint:e,kind:"conversation",author:t.user?.login||"unknown",body:t.body,url:typeof t.html_url=="string"?t.html_url:void 0,created:typeof t.created_at=="string"?t.created_at:void 0,updated:typeof t.updated_at=="string"?t.updated_at:void 0}}async function yI(t){let e=await new Promise((n,o)=>{IZ("gh",["api",t,"--paginate","--slurp"],{maxBuffer:PZ},(a,s)=>{if(a){o(a);return}n(s)})}),r=JSON.parse(e);return(Array.isArray(r)?r:[]).flatMap(n=>Array.isArray(n)?n:[])}async function bI(t,e=[]){let{owner:r,repo:i,prNumber:n}=zZ(t),o=new Set(e),[a,s]=await Promise.all([yI(`repos/${r}/${i}/pulls/${n}/comments`),yI(`repos/${r}/${i}/issues/${n}/comments`)]);return[...a.map(jZ),...s.map(OZ)].filter(c=>!!c&&!o.has(c.fingerprint)).sort((c,u)=>{let l=c.updated??c.created??"",p=u.updated??u.created??"";return l.localeCompare(p)})}var n0=2e4;async function i0(t,e,r,i){let n=CZ(t);if(!n.trim())return"No conversation content found in log.";let o=["You are summarizing an AI agent execution log for a developer dashboard.",`Task: "${e}"`,"","Write a concise but sufficiently detailed summary that covers:","1. The main steps the agent took","2. Important findings, decisions, or deviations","3. Any problems or failures encountered","4. The final outcome","","Rules:","- Use 5-12 bullet points.","- Focus on task-specific implementation details, not filler.","- Prefer what changed in the repo, what was discovered, and how the task was solved.","- Do not spend bullets on routine workflow boilerplate such as worktree setup/cleanup, generic git add/commit/push, PR creation, or Jira status/reporting unless something unusual happened there.","- Mention concrete files, commands, tools, or errors when they materially explain the implementation.","- Do not mention token usage, compaction, or transcript mechanics.","- Do not invent details that are not in the log.","","Execution log:",RZ(n)].join(`
|
|
374
374
|
`),a=await Mr({prompt:o,cwd:i,config:r});if(!a.resultText.trim())throw new Error("No compact log generated");return a.resultText.trim()}function CZ(t){let e=t.split(`
|
|
375
375
|
`).filter(i=>i.trim()),r=[];for(let i of e){let n;try{n=JSON.parse(i)}catch{continue}switch(n.type){case"assistant":{let o=n.message?.content??[];for(let a of o)if(a.type==="text"&&a.text)r.push(`[Claude] ${a.text}`);else if(a.type==="tool_use"){let s=a.name??"unknown";if(NZ(s,a.input))continue;let c=AZ(a.input);r.push(`[Tool] ${s}${c?`(${c})`:""}`)}break}case"result":{let o=typeof n.cost_usd=="number"?` (cost: $${n.cost_usd.toFixed(4)})`:"",a=n.result?`
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "jiranimo",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Local automation server for the Jiranimo Jira extension",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -12,9 +12,6 @@
|
|
|
12
12
|
"README.md",
|
|
13
13
|
"LICENSE"
|
|
14
14
|
],
|
|
15
|
-
"engines": {
|
|
16
|
-
"node": ">=20"
|
|
17
|
-
},
|
|
18
15
|
"publishConfig": {
|
|
19
16
|
"access": "public"
|
|
20
17
|
},
|