@zibby/skills 0.1.80 → 0.1.82

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.
@@ -1,4 +1,4 @@
1
- import{existsSync as S}from"fs";import{fileURLToPath as v}from"url";import{dirname as E,resolve as O}from"path";var w=Object.freeze({SENTRY:"sentry",JIRA:"jira",GITHUB:"github",GITLAB:"gitlab",SLACK:"slack",LARK:"lark",OPENAI_BILLING:"openai_billing",ANTHROPIC_BILLING:"anthropic_billing",CURSOR_ADMIN:"cursor_admin",NOTION:"notion",GOOGLE:"google",PLANE:"plane",LINEAR:"linear",FIGMA:"figma",OPEN_DESIGN:"open_design",LINKEDIN_PERSONAL:"linkedin_personal",LINKEDIN_BUSINESS:"linkedin_business",DISCORD:"discord"}),x=Object.freeze({sentry:{id:"sentry",name:"Sentry",connectPath:"/integrations?provider=sentry"},jira:{id:"jira",name:"Jira",connectPath:"/integrations?provider=jira"},github:{id:"github",name:"GitHub",connectPath:"/integrations?provider=github"},gitlab:{id:"gitlab",name:"GitLab",connectPath:"/integrations?provider=gitlab"},slack:{id:"slack",name:"Slack",connectPath:"/integrations?provider=slack"},lark:{id:"lark",name:"Lark",connectPath:"/integrations?provider=lark"},openai_billing:{id:"openai_billing",name:"OpenAI Admin",connectPath:"/integrations?provider=openai_billing"},anthropic_billing:{id:"anthropic_billing",name:"Anthropic Admin",connectPath:"/integrations?provider=anthropic_billing"},cursor_admin:{id:"cursor_admin",name:"Cursor Admin",connectPath:"/integrations?provider=cursor_admin"},notion:{id:"notion",name:"Notion",connectPath:"/integrations?provider=notion"},google:{id:"google",name:"Google Docs",connectPath:"/integrations?provider=google"},plane:{id:"plane",name:"Plane",connectPath:"/integrations?provider=plane"},linear:{id:"linear",name:"Linear",connectPath:"/integrations?provider=linear"},figma:{id:"figma",name:"Figma",connectPath:"/integrations?provider=figma"},open_design:{id:"open_design",name:"OpenDesign",connectPath:"/integrations?provider=open_design"},linkedin_personal:{id:"linkedin_personal",name:"LinkedIn (Personal)",connectPath:"/integrations?provider=linkedin_personal"},linkedin_business:{id:"linkedin_business",name:"LinkedIn (Business)",connectPath:"/integrations?provider=linkedin_business"},discord:{id:"discord",name:"Discord",connectPath:"/integrations?provider=discord"}});function T(){if(process.env.MCP_SKILL_PATH)return process.env.MCP_SKILL_PATH;let n=E(v(import.meta.url)),i=O(n,"..","bin","mcp-skill.mjs");return S(i)?i:null}var P=process.env.LINEAR_API_URL||"https://api.linear.app/graphql";function R(){if(process.env.LINEAR_OAUTH_TOKEN)return`Bearer ${process.env.LINEAR_OAUTH_TOKEN}`;let n=process.env.LINEAR_API_KEY;if(!n)throw new Error("Linear is not connected: set LINEAR_API_KEY (personal API key) or LINEAR_OAUTH_TOKEN.");return n}async function f(n,i={}){let e=await fetch(P,{method:"POST",headers:{Authorization:R(),"Content-Type":"application/json"},body:JSON.stringify({query:n,variables:i})});if(!e.ok){let s=await e.text().catch(()=>"");throw new Error(`Linear API ${e.status}: ${s.slice(0,300)}`)}let t=await e.json().catch(()=>null);if(!t)throw new Error("Linear API returned a non-JSON body");if(Array.isArray(t.errors)&&t.errors.length){let s=t.errors.map(a=>a?.message||String(a)).join("; ");throw new Error(`Linear GraphQL error: ${s.slice(0,300)}`)}return t.data}function h(n){return String(n||"").toLowerCase().replace(/\s+/g,"").replace(/[()\-_::"'`]/g,"")}function $(n,i){let e=h(n),t=h(i);if(!e||!t)return 0;if(e===t)return 1;if(e.length===1||t.length===1)return e===t?1:0;let s=d=>{let u=new Map;for(let y=0;y<d.length-1;y++){let g=d.slice(y,y+2);u.set(g,(u.get(g)||0)+1)}return u},a=s(e),r=s(t),o=0,l=0,m=0;for(let d of a.values())l+=d;for(let d of r.values())m+=d;for(let[d,u]of a.entries())o+=Math.min(u,r.get(d)||0);return 2*o/Math.max(1,l+m)}function C(n,i){let e=Array.isArray(n)?n:[];if(!e.length)return{state:null,strategy:"no-states"};let t=h(i);if(!t)return{state:null,strategy:"no-target"};let s=e.find(o=>h(o.name)===t);if(s)return{state:s,strategy:"exact"};let a={backlog:["backlog"],unstarted:["todo","unstarted","open"],started:["inprogress","started","doing","wip"],completed:["done","completed","closed","resolved","fixed"],canceled:["canceled","cancelled","wontfix","won'tfix"],triage:["triage"]};for(let[o,l]of Object.entries(a)){if(!l.some(d=>h(d)===t))continue;let m=e.find(d=>d.type===o);if(m)return{state:m,strategy:"type-alias"}}let r=e.map(o=>({s:o,score:$(i,o.name)})).sort((o,l)=>l.score-o.score);return r[0]&&r[0].score>=.5?{state:r[0].s,strategy:"fuzzy"}:{state:null,strategy:"no-match"}}var G=`
1
+ import{existsSync as S}from"fs";import{fileURLToPath as v}from"url";import{dirname as E,resolve as O}from"path";var w=Object.freeze({SENTRY:"sentry",JIRA:"jira",GITHUB:"github",GITLAB:"gitlab",SLACK:"slack",LARK:"lark",OPENAI_BILLING:"openai_billing",ANTHROPIC_BILLING:"anthropic_billing",CURSOR_ADMIN:"cursor_admin",NOTION:"notion",GOOGLE:"google",PLANE:"plane",LINEAR:"linear",FIGMA:"figma",HUBSPOT:"hubspot",OPEN_DESIGN:"open_design",LINKEDIN_PERSONAL:"linkedin_personal",LINKEDIN_BUSINESS:"linkedin_business",DISCORD:"discord"}),x=Object.freeze({sentry:{id:"sentry",name:"Sentry",connectPath:"/integrations?provider=sentry"},jira:{id:"jira",name:"Jira",connectPath:"/integrations?provider=jira"},github:{id:"github",name:"GitHub",connectPath:"/integrations?provider=github"},gitlab:{id:"gitlab",name:"GitLab",connectPath:"/integrations?provider=gitlab"},slack:{id:"slack",name:"Slack",connectPath:"/integrations?provider=slack"},lark:{id:"lark",name:"Lark",connectPath:"/integrations?provider=lark"},openai_billing:{id:"openai_billing",name:"OpenAI Admin",connectPath:"/integrations?provider=openai_billing"},anthropic_billing:{id:"anthropic_billing",name:"Anthropic Admin",connectPath:"/integrations?provider=anthropic_billing"},cursor_admin:{id:"cursor_admin",name:"Cursor Admin",connectPath:"/integrations?provider=cursor_admin"},notion:{id:"notion",name:"Notion",connectPath:"/integrations?provider=notion"},google:{id:"google",name:"Google Docs",connectPath:"/integrations?provider=google"},plane:{id:"plane",name:"Plane",connectPath:"/integrations?provider=plane"},linear:{id:"linear",name:"Linear",connectPath:"/integrations?provider=linear"},figma:{id:"figma",name:"Figma",connectPath:"/integrations?provider=figma"},hubspot:{id:"hubspot",name:"HubSpot",connectPath:"/integrations?provider=hubspot"},open_design:{id:"open_design",name:"OpenDesign",connectPath:"/integrations?provider=open_design"},linkedin_personal:{id:"linkedin_personal",name:"LinkedIn (Personal)",connectPath:"/integrations?provider=linkedin_personal"},linkedin_business:{id:"linkedin_business",name:"LinkedIn (Business)",connectPath:"/integrations?provider=linkedin_business"},discord:{id:"discord",name:"Discord",connectPath:"/integrations?provider=discord"}});function T(){if(process.env.MCP_SKILL_PATH)return process.env.MCP_SKILL_PATH;let n=E(v(import.meta.url)),i=O(n,"..","bin","mcp-skill.mjs");return S(i)?i:null}var P=process.env.LINEAR_API_URL||"https://api.linear.app/graphql";function R(){if(process.env.LINEAR_OAUTH_TOKEN)return`Bearer ${process.env.LINEAR_OAUTH_TOKEN}`;let n=process.env.LINEAR_API_KEY;if(!n)throw new Error("Linear is not connected: set LINEAR_API_KEY (personal API key) or LINEAR_OAUTH_TOKEN.");return n}async function f(n,i={}){let e=await fetch(P,{method:"POST",headers:{Authorization:R(),"Content-Type":"application/json"},body:JSON.stringify({query:n,variables:i})});if(!e.ok){let s=await e.text().catch(()=>"");throw new Error(`Linear API ${e.status}: ${s.slice(0,300)}`)}let t=await e.json().catch(()=>null);if(!t)throw new Error("Linear API returned a non-JSON body");if(Array.isArray(t.errors)&&t.errors.length){let s=t.errors.map(a=>a?.message||String(a)).join("; ");throw new Error(`Linear GraphQL error: ${s.slice(0,300)}`)}return t.data}function I(n){return String(n||"").toLowerCase().replace(/\s+/g,"").replace(/[()\-_::"'`]/g,"")}function $(n,i){let e=I(n),t=I(i);if(!e||!t)return 0;if(e===t)return 1;if(e.length===1||t.length===1)return e===t?1:0;let s=d=>{let u=new Map;for(let y=0;y<d.length-1;y++){let g=d.slice(y,y+2);u.set(g,(u.get(g)||0)+1)}return u},a=s(e),r=s(t),o=0,l=0,m=0;for(let d of a.values())l+=d;for(let d of r.values())m+=d;for(let[d,u]of a.entries())o+=Math.min(u,r.get(d)||0);return 2*o/Math.max(1,l+m)}function C(n,i){let e=Array.isArray(n)?n:[];if(!e.length)return{state:null,strategy:"no-states"};let t=I(i);if(!t)return{state:null,strategy:"no-target"};let s=e.find(o=>I(o.name)===t);if(s)return{state:s,strategy:"exact"};let a={backlog:["backlog"],unstarted:["todo","unstarted","open"],started:["inprogress","started","doing","wip"],completed:["done","completed","closed","resolved","fixed"],canceled:["canceled","cancelled","wontfix","won'tfix"],triage:["triage"]};for(let[o,l]of Object.entries(a)){if(!l.some(d=>I(d)===t))continue;let m=e.find(d=>d.type===o);if(m)return{state:m,strategy:"type-alias"}}let r=e.map(o=>({s:o,score:$(i,o.name)})).sort((o,l)=>l.score-o.score);return r[0]&&r[0].score>=.5?{state:r[0].s,strategy:"fuzzy"}:{state:null,strategy:"no-match"}}var G=`
2
2
  id
3
3
  identifier
4
4
  number
@@ -67,19 +67,19 @@ You have direct access to the user's Linear workspace (GraphQL API). Tools:
67
67
  }
68
68
  }
69
69
  }
70
- `,{first:m||30,filter:Object.keys(d).length?d:void 0,orderBy:"updatedAt"}))?.issues?.nodes||[]).map(c=>({id:c.id,identifier:c.identifier,number:c.number,title:c.title,url:c.url,priority:c.priority,state:c.state?.name,stateType:c.state?.type,assignee:c.assignee?.displayName||null,labels:(c.labels?.nodes||[]).map(p=>p.name),team:c.team?.key,createdAt:c.createdAt,updatedAt:c.updatedAt}));return JSON.stringify({count:g.length,issues:g})}case"linear_get_issue":{let e=i?.issueId||i?.identifier||i?.issueKey;if(!e)return JSON.stringify({error:"issueId or identifier is required"});let t=await I(e);return JSON.stringify(t?{id:t.id,identifier:t.identifier,number:t.number,title:t.title,description:t.description||"",url:t.url,priority:t.priority,state:t.state?.name,stateId:t.state?.id,stateType:t.state?.type,assignee:t.assignee?.displayName||t.assignee?.name||null,assigneeId:t.assignee?.id||null,labels:(t.labels?.nodes||[]).map(s=>s.name),team:t.team?{id:t.team.id,key:t.team.key,name:t.team.name}:null,createdAt:t.createdAt,updatedAt:t.updatedAt}:{error:`Issue not found: ${e}`})}case"linear_get_comments":{let e=i?.issueId||i?.identifier||i?.issueKey;if(!e)return JSON.stringify({error:"issueId or identifier is required"});let t=await I(e,`
70
+ `,{first:m||30,filter:Object.keys(d).length?d:void 0,orderBy:"updatedAt"}))?.issues?.nodes||[]).map(c=>({id:c.id,identifier:c.identifier,number:c.number,title:c.title,url:c.url,priority:c.priority,state:c.state?.name,stateType:c.state?.type,assignee:c.assignee?.displayName||null,labels:(c.labels?.nodes||[]).map(p=>p.name),team:c.team?.key,createdAt:c.createdAt,updatedAt:c.updatedAt}));return JSON.stringify({count:g.length,issues:g})}case"linear_get_issue":{let e=i?.issueId||i?.identifier||i?.issueKey;if(!e)return JSON.stringify({error:"issueId or identifier is required"});let t=await h(e);return JSON.stringify(t?{id:t.id,identifier:t.identifier,number:t.number,title:t.title,description:t.description||"",url:t.url,priority:t.priority,state:t.state?.name,stateId:t.state?.id,stateType:t.state?.type,assignee:t.assignee?.displayName||t.assignee?.name||null,assigneeId:t.assignee?.id||null,labels:(t.labels?.nodes||[]).map(s=>s.name),team:t.team?{id:t.team.id,key:t.team.key,name:t.team.name}:null,createdAt:t.createdAt,updatedAt:t.updatedAt}:{error:`Issue not found: ${e}`})}case"linear_get_comments":{let e=i?.issueId||i?.identifier||i?.issueKey;if(!e)return JSON.stringify({error:"issueId or identifier is required"});let t=await h(e,`
71
71
  id identifier
72
72
  comments(first: ${Number(i?.limit)||50}) {
73
73
  nodes { id body createdAt updatedAt user { id name displayName } }
74
74
  }
75
- `);if(!t)return JSON.stringify({error:`Issue not found: ${e}`});let s=(t.comments?.nodes||[]).map(a=>({id:a.id,author:a.user?.displayName||a.user?.name||"Unknown",body:a.body||"",createdAt:a.createdAt,updatedAt:a.updatedAt})).sort((a,r)=>String(r.createdAt).localeCompare(String(a.createdAt)));return JSON.stringify({count:s.length,issue:t.identifier,comments:s})}case"linear_add_comment":{let e=i?.issueId||i?.identifier||i?.issueKey,t=i?.body;if(!e||!t)return JSON.stringify({error:"issueId/identifier and body are required"});let s=await I(e,"id identifier");if(!s)return JSON.stringify({error:`Issue not found: ${e}`});let r=(await f(`
75
+ `);if(!t)return JSON.stringify({error:`Issue not found: ${e}`});let s=(t.comments?.nodes||[]).map(a=>({id:a.id,author:a.user?.displayName||a.user?.name||"Unknown",body:a.body||"",createdAt:a.createdAt,updatedAt:a.updatedAt})).sort((a,r)=>String(r.createdAt).localeCompare(String(a.createdAt)));return JSON.stringify({count:s.length,issue:t.identifier,comments:s})}case"linear_add_comment":{let e=i?.issueId||i?.identifier||i?.issueKey,t=i?.body;if(!e||!t)return JSON.stringify({error:"issueId/identifier and body are required"});let s=await h(e,"id identifier");if(!s)return JSON.stringify({error:`Issue not found: ${e}`});let r=(await f(`
76
76
  mutation AddComment($input: CommentCreateInput!) {
77
77
  commentCreate(input: $input) {
78
78
  success
79
79
  comment { id url createdAt }
80
80
  }
81
81
  }
82
- `,{input:{issueId:s.id,body:t}}))?.commentCreate;return JSON.stringify({ok:!!r?.success,commentId:r?.comment?.id,url:r?.comment?.url})}case"linear_update_state":{let e=i?.issueId||i?.identifier||i?.issueKey,{stateId:t,stateName:s,toStatus:a,status:r}=i||{};if(!e)return JSON.stringify({error:"issueId or identifier is required"});let o=await I(e,`
82
+ `,{input:{issueId:s.id,body:t}}))?.commentCreate;return JSON.stringify({ok:!!r?.success,commentId:r?.comment?.id,url:r?.comment?.url})}case"linear_update_state":{let e=i?.issueId||i?.identifier||i?.issueKey,{stateId:t,stateName:s,toStatus:a,status:r}=i||{};if(!e)return JSON.stringify({error:"issueId or identifier is required"});let o=await h(e,`
83
83
  id identifier
84
84
  state { id name type }
85
85
  team { id key states { nodes { id name type position } } }
@@ -90,7 +90,7 @@ You have direct access to the user's Linear workspace (GraphQL API). Tools:
90
90
  issue { id identifier state { id name type } }
91
91
  }
92
92
  }
93
- `,{id:o.id,input:{stateId:l}}))?.issueUpdate;return JSON.stringify({ok:!!u?.success,issue:u?.issue?.identifier||o.identifier,stateAfter:u?.issue?.state?.name||null,stateTypeAfter:u?.issue?.state?.type||null,resolution:m})}case"linear_link_attachment":{let e=i?.issueId||i?.identifier||i?.issueKey,{url:t,title:s,subtitle:a}=i||{};if(!e||!t)return JSON.stringify({error:"issueId/identifier and url are required"});let r=await I(e,"id identifier");if(!r)return JSON.stringify({error:`Issue not found: ${e}`});let l=(await f(`
93
+ `,{id:o.id,input:{stateId:l}}))?.issueUpdate;return JSON.stringify({ok:!!u?.success,issue:u?.issue?.identifier||o.identifier,stateAfter:u?.issue?.state?.name||null,stateTypeAfter:u?.issue?.state?.type||null,resolution:m})}case"linear_link_attachment":{let e=i?.issueId||i?.identifier||i?.issueKey,{url:t,title:s,subtitle:a}=i||{};if(!e||!t)return JSON.stringify({error:"issueId/identifier and url are required"});let r=await h(e,"id identifier");if(!r)return JSON.stringify({error:`Issue not found: ${e}`});let l=(await f(`
94
94
  mutation LinkAttachment($input: AttachmentCreateInput!) {
95
95
  attachmentCreate(input: $input) {
96
96
  success
@@ -101,7 +101,7 @@ You have direct access to the user's Linear workspace (GraphQL API). Tools:
101
101
  query TeamByKey($filter: TeamFilter) {
102
102
  teams(first: 1, filter: $filter) { nodes { id key } }
103
103
  }
104
- `,{filter:{key:{eq:n}}}))?.teams?.nodes?.[0]?.id||null}async function I(n,i=G){let e=String(n).trim(),t=/^([A-Za-z][A-Za-z0-9]*)-(\d+)$/.exec(e);if(t){let a=t[1].toUpperCase(),r=Number(t[2]);return(await f(`
104
+ `,{filter:{key:{eq:n}}}))?.teams?.nodes?.[0]?.id||null}async function h(n,i=G){let e=String(n).trim(),t=/^([A-Za-z][A-Za-z0-9]*)-(\d+)$/.exec(e);if(t){let a=t[1].toUpperCase(),r=Number(t[2]);return(await f(`
105
105
  query IssueByIdentifier($filter: IssueFilter) {
106
106
  issues(first: 1, filter: $filter) {
107
107
  nodes { ${i} }
@@ -111,4 +111,4 @@ You have direct access to the user's Linear workspace (GraphQL API). Tools:
111
111
  query IssueById($id: String!) {
112
112
  issue(id: $id) { ${i} }
113
113
  }
114
- `,{id:e}))?.issue||null}var q={triage:"todo",backlog:"todo",unstarted:"todo",started:"in_progress",completed:"done",canceled:"done"},J=/\b(blocked|on[\s-]?hold|waiting|stuck)\b/i;function k(n){return n?n.name&&J.test(n.name)?"blocked":q[n.type]||"unknown":"unknown"}function b(n){let i=JSON.parse(n);if(i&&i.error)throw new Error(i.error);return i}function A(n){let i=n.state||null,e=n.stateType||null;return{id:String(n.id||n.identifier||""),key:n.identifier||String(n.id||""),title:n.title||"",body:n.description||"",state:i,stateCategory:k(i?{name:i,type:e}:null),assignee:n.assignee||null,url:n.url||null,_raw:n}}var K={id:"linear",toStateCategory:k,toNeutral:A,async listCandidates(n={}){let i=n.ctx||{},e={teamId:i.teamId,teamKey:i.teamKey,stateName:n.state,label:Array.isArray(n.labels)?n.labels[0]:n.labels,assigneeId:i.assigneeId,updatedAfter:n.updatedAfter,limit:n.limit};return(b(await _.handleToolCall("linear_list_issues",e)).issues||[]).map(A)},async getTicket(n){if(!n)throw new Error("key is required");let i=JSON.parse(await _.handleToolCall("linear_get_issue",{identifier:n}));return i.error?null:A(i)},async getComments(n){if(!n)throw new Error("key is required");return(b(await _.handleToolCall("linear_get_comments",{identifier:n})).comments||[]).map(e=>({id:String(e.id),author:e.author||"Unknown",body:e.body||"",createdAt:e.createdAt||null,updatedAt:e.updatedAt||null,_raw:e}))},async addComment(n,i){if(!n||!i)throw new Error("key and body are required");let e=b(await _.handleToolCall("linear_add_comment",{identifier:n,body:i}));return{ok:!!e.ok,id:e.commentId||null}},async transition(n,i){if(!n)throw new Error("key is required");let e=JSON.parse(await _.handleToolCall("linear_update_state",{identifier:n,toStatus:i}));if(!e.ok)return{ok:!1,error:e.error||"state update failed",_raw:e};let t=e.stateAfter||null;return{ok:!0,stateAfter:t,stateCategoryAfter:k(t?{name:t,type:e.stateTypeAfter}:null),_raw:e}},async linkPullRequest(n,i,e){if(!n||!i)throw new Error("key and prUrl are required");try{if(b(await _.handleToolCall("linear_link_attachment",{identifier:n,url:i,title:e||i})).ok)return{ok:!0,via:"attachment"};throw new Error("attachmentCreate returned ok:false")}catch(t){let s=`${e?`${e}: `:"Linked PR: "}${i}`;return{ok:!!b(await _.handleToolCall("linear_add_comment",{identifier:n,body:s})).ok,via:"comment",error:String(t?.message||t)}}}},H=K;export{H as default,K as linearAdapter};
114
+ `,{id:e}))?.issue||null}var q={triage:"todo",backlog:"todo",unstarted:"todo",started:"in_progress",completed:"done",canceled:"done"},J=/\b(blocked|on[\s-]?hold|waiting|stuck)\b/i;function k(n){return n?n.name&&J.test(n.name)?"blocked":q[n.type]||"unknown":"unknown"}function b(n){let i=JSON.parse(n);if(i&&i.error)throw new Error(i.error);return i}function A(n){let i=n.state||null,e=n.stateType||null;return{id:String(n.id||n.identifier||""),key:n.identifier||String(n.id||""),title:n.title||"",body:n.description||"",state:i,stateCategory:k(i?{name:i,type:e}:null),assignee:n.assignee||null,url:n.url||null,_raw:n}}var K={id:"linear",toStateCategory:k,toNeutral:A,async listCandidates(n={}){let i=n.ctx||{},e={teamId:i.teamId,teamKey:i.teamKey,stateName:n.state,label:Array.isArray(n.labels)?n.labels[0]:n.labels,assigneeId:i.assigneeId,updatedAfter:n.updatedAfter,limit:n.limit};return(b(await _.handleToolCall("linear_list_issues",e)).issues||[]).map(A)},async getTicket(n){if(!n)throw new Error("key is required");let i=JSON.parse(await _.handleToolCall("linear_get_issue",{identifier:n}));return i.error?null:A(i)},async getComments(n){if(!n)throw new Error("key is required");return(b(await _.handleToolCall("linear_get_comments",{identifier:n})).comments||[]).map(e=>({id:String(e.id),author:e.author||"Unknown",body:e.body||"",createdAt:e.createdAt||null,updatedAt:e.updatedAt||null,_raw:e}))},async addComment(n,i){if(!n||!i)throw new Error("key and body are required");let e=b(await _.handleToolCall("linear_add_comment",{identifier:n,body:i}));return{ok:!!e.ok,id:e.commentId||null}},async transition(n,i){if(!n)throw new Error("key is required");let e=JSON.parse(await _.handleToolCall("linear_update_state",{identifier:n,toStatus:i}));if(!e.ok)return{ok:!1,error:e.error||"state update failed",_raw:e};let t=e.stateAfter||null;return{ok:!0,stateAfter:t,stateCategoryAfter:k(t?{name:t,type:e.stateTypeAfter}:null),_raw:e}},async linkPullRequest(n,i,e){if(!n||!i)throw new Error("key and prUrl are required");try{if(b(await _.handleToolCall("linear_link_attachment",{identifier:n,url:i,title:e||i})).ok)return{ok:!0,via:"attachment"};throw new Error("attachmentCreate returned ok:false")}catch(t){let s=`${e?`${e}: `:"Linked PR: "}${i}`;return{ok:!!b(await _.handleToolCall("linear_add_comment",{identifier:n,body:s})).ok,via:"comment",error:String(t?.message||t)}}}},z=K;export{z as default,K as linearAdapter};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zibby/skills",
3
- "version": "0.1.80",
3
+ "version": "0.1.82",
4
4
  "description": "Built-in skill definitions for the Zibby agent-workflow framework",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",