prjct-cli 1.25.0 → 1.27.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.
@@ -3,8 +3,8 @@ import { fileURLToPath as __fileURLToPath } from 'url';
3
3
  import { dirname as __pathDirname } from 'path';
4
4
  const __filename = __fileURLToPath(import.meta.url);
5
5
  const __dirname = __pathDirname(__filename);
6
- var W=Object.defineProperty;var mt=Object.getOwnPropertyDescriptor;var gt=Object.getOwnPropertyNames;var ft=Object.prototype.hasOwnProperty;var o=(r,e)=>W(r,"name",{value:e,configurable:!0});var j=(r,e)=>()=>(r&&(e=r(r=0)),e);var Re=(r,e)=>{for(var t in e)W(r,t,{get:e[t],enumerable:!0})},ht=(r,e,t,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of gt(e))!ft.call(r,i)&&i!==t&&W(r,i,{get:()=>e[i],enumerable:!(s=mt(e,i))||s.enumerable});return r};var ue=r=>ht(W({},"__esModule",{value:!0}),r);function yt(r){return r instanceof Error&&"code"in r}function q(r){return yt(r)&&r.code==="ENOENT"}function w(r){return r instanceof Error?r.message:typeof r=="string"?r:"Unknown error"}var R=j(()=>{"use strict";o(yt,"isNodeError");o(q,"isNotFoundError");o(w,"getErrorMessage")});var ke={};Re(ke,{deleteCredential:()=>wt,getCredential:()=>U,getCredentialWithSource:()=>St,hasCredential:()=>Pt,setCredential:()=>It});import{exec as Et}from"node:child_process";import{promisify as Tt}from"node:util";async function It(r,e){if(process.platform!=="darwin")return console.warn("[keychain] macOS Keychain only available on macOS"),!1;try{return await G(`security delete-generic-password -s "${K}" -a "${r}" 2>/dev/null || true`),await G(`security add-generic-password -s "${K}" -a "${r}" -w "${e}"`),!0}catch(t){return console.error("[keychain] Failed to store credential:",w(t)),!1}}async function U(r){if(process.platform!=="darwin")return me(r);try{let{stdout:e}=await G(`security find-generic-password -s "${K}" -a "${r}" -w 2>/dev/null`);return e.trim()||null}catch{return me(r)}}async function wt(r){if(process.platform!=="darwin")return!1;try{return await G(`security delete-generic-password -s "${K}" -a "${r}" 2>/dev/null`),!0}catch{return!1}}async function Pt(r){let e=await U(r);return e!==null&&e.length>0}function me(r){let t={"linear-api-key":"LINEAR_API_KEY","jira-api-token":"JIRA_API_TOKEN"}[r];return process.env[t]||null}async function St(r){if(process.platform==="darwin")try{let{stdout:t}=await G(`security find-generic-password -s "${K}" -a "${r}" -w 2>/dev/null`),s=t.trim();if(s)return{value:s,source:"keychain"}}catch{}let e=me(r);return e?{value:e,source:"env"}:{value:null,source:"none"}}var G,K,Q=j(()=>{"use strict";R();G=Tt(Et),K="prjct-cli";o(It,"setCredential");o(U,"getCredential");o(wt,"deleteCredential");o(Pt,"hasCredential");o(me,"getEnvFallback");o(St,"getCredentialWithSource")});var Me=j(()=>{"use strict";R()});import ge from"node:fs/promises";async function g(r){try{return await ge.access(r),!0}catch(e){if(q(e))return!1;throw e}}async function fe(r){try{return(await ge.stat(r)).isDirectory()}catch(e){if(q(e))return!1;throw e}}async function k(r){await ge.mkdir(r,{recursive:!0})}var te=j(()=>{"use strict";Me();R();o(g,"fileExists");o(fe,"dirExists");o(k,"ensureDir")});import{z as x}from"zod";function $e(r,e){let t=r.split(".").map(Number),s=e.split(".").map(Number);for(let i=0;i<3;i++){let n=t[i]??0,a=s[i]??0;if(n<a)return-1;if(n>a)return 1}return 0}var Jr,Yr,Hr,kt,Br,Fe=j(()=>{"use strict";Jr=x.enum(["opus","sonnet","haiku"]),Yr=x.enum(["2.5-pro","2.5-flash","2.0-flash"]),Hr=x.string().min(1),kt=x.object({provider:x.string(),model:x.string(),cliVersion:x.string().optional(),recordedAt:x.string()}),Br=x.object({preferredModel:x.string().optional(),lastAnalysisModel:kt.optional()});o($e,"compareSemver")});import he from"node:fs/promises";import Lt from"node:os";import Ue from"node:path";async function Ke(){try{let r=await he.readFile(Ge,"utf-8"),e=JSON.parse(r);return!e.timestamp||!e.detection||Date.now()-new Date(e.timestamp).getTime()>_t?null:e.detection}catch{return null}}async function ze(r){let e={timestamp:new Date().toISOString(),detection:r};await he.mkdir(Xe,{recursive:!0}),await he.writeFile(Ge,JSON.stringify(e,null,2))}var Xe,Ge,_t,Je=j(()=>{"use strict";Xe=Ue.join(Lt.homedir(),".prjct-cli","cache"),Ge=Ue.join(Xe,"providers.json"),_t=600*1e3;o(Ke,"readProviderCache");o(ze,"writeProviderCache")});var ie={};Re(ie,{AntigravityProvider:()=>Te,ClaudeProvider:()=>re,CursorProvider:()=>Be,GeminiProvider:()=>Ee,Providers:()=>A,WindsurfProvider:()=>We,detectAllProviders:()=>Ie,detectAntigravity:()=>Kt,detectCursorProject:()=>qe,detectProvider:()=>ye,detectWindsurfProject:()=>Qe,getActiveProvider:()=>Ft,getCommandsDir:()=>Ht,getGlobalContextPath:()=>zt,getGlobalSettingsPath:()=>Jt,getProjectCommandsPath:()=>Bt,getProviderBranding:()=>se,getSkillsPath:()=>Yt,hasProviderConfig:()=>Ut,needsCursorRouterRegeneration:()=>Xt,needsWindsurfRouterRegeneration:()=>Gt,selectProvider:()=>Wt,validateCliVersion:()=>Ve});import{exec as jt}from"node:child_process";import X from"node:os";import E from"node:path";import{promisify as Ot}from"node:util";async function Mt(r){try{let{stdout:e}=await Ye(`which ${r}`,{timeout:He});return e.trim()}catch{return null}}async function $t(r){try{let{stdout:e}=await Ye(`${r} --version`,{timeout:He}),t=e.match(/\d+\.\d+\.\d+/);return t?t[0]:e.trim()}catch{return null}}async function ye(r){let e=A[r];if(!e.cliCommand)return{installed:!1};let t=await Mt(e.cliCommand);if(!t)return{installed:!1};let s=await $t(e.cliCommand),i=Ve(r,s||void 0);return{installed:!0,version:s||void 0,path:t,versionWarning:i||void 0}}function Ve(r,e){let t=A[r];return!t.minCliVersion||!e?null:$e(e,t.minCliVersion)<0?`\u26A0\uFE0F ${t.displayName} v${e} is below minimum v${t.minCliVersion}. Some features may not work correctly.`:null}async function Ie(r=!1){if(!r){let i=await Ke();if(i)return i}let[e,t]=await Promise.all([ye("claude"),ye("gemini")]),s={claude:e,gemini:t};return await ze(s).catch(()=>{}),s}async function Ft(r){if(r&&A[r])return A[r];let e=await Ie();return e.claude.installed&&!e.gemini.installed?re:e.gemini.installed&&!e.claude.installed?Ee:re}async function Ut(r){let e=A[r];return e.configDir?g(e.configDir):!1}function se(r){return{commitFooter:"Generated with [p/](https://www.prjct.app/)",signature:{claude:"\u26A1 prjct + Claude",gemini:"\u26A1 prjct + Gemini",cursor:"\u26A1 prjct + Cursor",antigravity:"\u26A1 prjct + Antigravity",windsurf:"\u26A1 prjct + Windsurf"}[r]||"\u26A1 prjct"}}async function qe(r){let e=E.join(r,".cursor"),t=E.join(e,"rules"),s=E.join(t,"prjct.mdc"),[i,n]=await Promise.all([g(e),g(s)]);return{detected:i,routerInstalled:n,projectRoot:i?r:void 0}}async function Xt(r){let e=await qe(r);return e.detected&&!e.routerInstalled}async function Qe(r){let e=E.join(r,".windsurf"),t=E.join(e,"rules"),s=E.join(t,"prjct.md"),[i,n]=await Promise.all([g(e),g(s)]);return{detected:i,routerInstalled:n,projectRoot:i?r:void 0}}async function Gt(r){let e=await Qe(r);return e.detected&&!e.routerInstalled}async function Kt(){let r=Te.configDir;if(!r)return{installed:!1,skillInstalled:!1};let e=E.join(r,"skills","prjct","SKILL.md"),[t,s]=await Promise.all([g(r),g(e)]);return{installed:t,skillInstalled:s,configPath:t?r:void 0}}function zt(r){let e=A[r];return e.configDir?E.join(e.configDir,e.contextFile):null}function Jt(r){let e=A[r];return!e.configDir||!e.settingsFile?null:E.join(e.configDir,e.settingsFile)}function Yt(r){return A[r].skillsDir}function Ht(r){return A[r].commandsDir}function Bt(r,e){let t=A[r];return E.join(e,t.commandsDir)}async function Wt(){let r=await Ie(),e=r.claude.installed,t=r.gemini.installed;return!e&&!t?{provider:"claude",userSelected:!1,detection:r}:e&&!t?{provider:"claude",userSelected:!1,detection:r}:t&&!e?{provider:"gemini",userSelected:!1,detection:r}:{provider:"claude",userSelected:!0,detection:r}}var Ye,He,re,Ee,Te,Be,We,A,z=j(()=>{"use strict";Fe();te();Je();Ye=Ot(jt),He=2e3,re={name:"claude",displayName:"Claude Code",cliCommand:"claude",configDir:E.join(X.homedir(),".claude"),contextFile:"CLAUDE.md",skillsDir:E.join(X.homedir(),".claude","skills"),commandsDir:".claude/commands",commandFormat:"md",settingsFile:"settings.json",projectSettingsFile:"settings.local.json",ignoreFile:".claudeignore",websiteUrl:"https://www.anthropic.com/claude",docsUrl:"https://docs.anthropic.com/claude-code",defaultModel:"sonnet",supportedModels:["opus","sonnet","haiku"],minCliVersion:"1.0.0"},Ee={name:"gemini",displayName:"Gemini CLI",cliCommand:"gemini",configDir:E.join(X.homedir(),".gemini"),contextFile:"GEMINI.md",skillsDir:E.join(X.homedir(),".gemini","skills"),commandsDir:".gemini/commands",commandFormat:"toml",settingsFile:"settings.json",projectSettingsFile:"settings.json",ignoreFile:".geminiignore",websiteUrl:"https://geminicli.com",docsUrl:"https://geminicli.com/docs",defaultModel:"2.5-flash",supportedModels:["2.5-pro","2.5-flash","2.0-flash"],minCliVersion:"1.0.0"},Te={name:"antigravity",displayName:"Google Antigravity",cliCommand:null,configDir:E.join(X.homedir(),".gemini","antigravity"),contextFile:"ANTIGRAVITY.md",skillsDir:E.join(X.homedir(),".gemini","antigravity","global_skills"),commandsDir:".agent/skills",commandFormat:"md",settingsFile:"mcp_config.json",projectSettingsFile:null,ignoreFile:".agentignore",websiteUrl:"https://gemini.google.com/app/antigravity",docsUrl:"https://gemini.google.com/app/antigravity",defaultModel:null,supportedModels:[],minCliVersion:null},Be={name:"cursor",displayName:"Cursor IDE",cliCommand:null,configDir:null,contextFile:"prjct.mdc",skillsDir:null,commandsDir:".cursor/commands",rulesDir:".cursor/rules",commandFormat:"md",settingsFile:null,projectSettingsFile:null,ignoreFile:".cursorignore",isProjectLevel:!0,websiteUrl:"https://cursor.com",docsUrl:"https://cursor.com/docs",defaultModel:null,supportedModels:[],minCliVersion:null},We={name:"windsurf",displayName:"Windsurf IDE",cliCommand:null,configDir:null,contextFile:"prjct.md",skillsDir:null,commandsDir:".windsurf/workflows",rulesDir:".windsurf/rules",commandFormat:"md",settingsFile:null,projectSettingsFile:null,ignoreFile:".windsurfignore",isProjectLevel:!0,websiteUrl:"https://windsurf.com",docsUrl:"https://docs.windsurf.com",defaultModel:null,supportedModels:[],minCliVersion:null},A={claude:re,gemini:Ee,cursor:Be,antigravity:Te,windsurf:We};o(Mt,"whichCommand");o($t,"getCliVersion");o(ye,"detectProvider");o(Ve,"validateCliVersion");o(Ie,"detectAllProviders");o(Ft,"getActiveProvider");o(Ut,"hasProviderConfig");o(se,"getProviderBranding");o(qe,"detectCursorProject");o(Xt,"needsCursorRouterRegeneration");o(Qe,"detectWindsurfProject");o(Gt,"needsWindsurfRouterRegeneration");o(Kt,"detectAntigravity");o(zt,"getGlobalContextPath");o(Jt,"getGlobalSettingsPath");o(Yt,"getSkillsPath");o(Ht,"getCommandsDir");o(Bt,"getProjectCommandsPath");o(Wt,"selectProvider")});var O=class{static{o(this,"TTLCache")}cache=new Map;ttl;maxSize;constructor(e={}){this.ttl=e.ttl??5e3,this.maxSize=e.maxSize??50}isValid(e){let t=this.cache.get(e);return t?Date.now()-t.timestamp<this.ttl:!1}get(e){let t=this.cache.get(e);return t?this.isValid(e)?t.data:(this.cache.delete(e),null):null}set(e,t){this.cache.set(e,{data:t,timestamp:Date.now()}),this.evictOldEntries()}delete(e){this.cache.delete(e)}clear(){this.cache.clear()}has(e){return this.cache.has(e)}get size(){return this.cache.size}evictOldEntries(){if(this.cache.size<=this.maxSize)return;let t=Array.from(this.cache.entries()).sort((s,i)=>s[1].timestamp-i[1].timestamp).slice(0,this.cache.size-this.maxSize);for(let[s]of t)this.cache.delete(s)}stats(){return{size:this.cache.size,maxSize:this.maxSize,ttl:this.ttl}}prune(){let e=0;for(let t of this.cache.keys())this.isValid(t)||(this.cache.delete(t),e++);return e}};var V=300*1e3,y=new O({ttl:V,maxSize:100}),v=new O({ttl:V,maxSize:10}),$=new O({ttl:V,maxSize:5}),F=new O({ttl:V,maxSize:5});function de(){y.clear(),v.clear(),$.clear(),F.clear()}o(de,"clearLinearCache");function pe(){return{issues:y.stats(),assignedIssues:v.stats(),teams:$.stats(),projects:F.stats()}}o(pe,"getLinearCacheStats");R();Q();var vt={backlog:"backlog",unstarted:"todo",started:"in_progress",completed:"done",canceled:"cancelled",cancelled:"cancelled"},At={0:"none",1:"urgent",2:"high",3:"medium",4:"low"},Le={none:0,urgent:1,high:2,medium:3,low:4},Z=class{static{o(this,"LinearProvider")}name="linear";displayName="Linear";sdk=null;config=null;isConfigured(){return this.sdk!==null&&this.config?.enabled===!0}async initialize(e){this.config=e;let t=e.apiKey||await U("linear-api-key");if(!t)throw new Error("LINEAR_API_KEY not configured. Run `p. linear setup` to configure.");let{LinearClient:s}=await import("@linear/sdk");this.sdk=new s({apiKey:t});try{await this.sdk.viewer}catch(i){throw this.sdk=null,new Error(`Linear connection failed: ${w(i)}`)}}async fetchAssignedIssues(e){if(!this.sdk)throw new Error("Linear not initialized");let t=await this.sdk.viewer,s={};e?.includeCompleted||(s.state={type:{nin:["completed","canceled"]}}),this.config?.defaultTeamId&&(s.team={id:{eq:this.config.defaultTeamId}});let i=await t.assignedIssues({first:e?.limit||50,filter:Object.keys(s).length>0?s:void 0});return Promise.all(i.nodes.map(n=>this.mapIssue(n)))}async fetchTeamIssues(e,t){if(!this.sdk)throw new Error("Linear not initialized");let i=await(await this.sdk.team(e)).issues({first:t?.limit||50,filter:t?.includeCompleted?void 0:{state:{type:{nin:["completed","canceled"]}}}});return Promise.all(i.nodes.map(n=>this.mapIssue(n)))}async fetchIssue(e){if(!this.sdk)throw new Error("Linear not initialized");try{if(e.includes("-")&&/^[A-Z]+-\d+$/.test(e)){let s=e.match(/^([A-Z]+)-(\d+)$/);if(!s)return null;let[,i,n]=s,a=parseInt(n,10),m=(await this.sdk.teams({first:50})).nodes.find(S=>S.key===i);if(!m)return null;let C=await m.issues({first:1,filter:{number:{eq:a}}});return C.nodes.length>0?this.mapIssue(C.nodes[0]):null}let t=await this.sdk.issue(e);return this.mapIssue(t)}catch{return null}}async createIssue(e){if(!this.sdk)throw new Error("Linear not initialized");let t=e.teamId||this.config?.defaultTeamId;if(!t)throw new Error("Team ID required for creating issues");let i=await(await this.sdk.createIssue({teamId:t,title:e.title,description:e.description,priority:e.priority?Le[e.priority]:void 0,projectId:e.projectId||this.config?.defaultProjectId,assigneeId:e.assigneeId,labelIds:e.labels?await this.resolveLabelIds(t,e.labels):void 0})).issue;if(!i)throw new Error("Failed to create issue");return this.mapIssue(i)}async updateIssue(e,t){if(!this.sdk)throw new Error("Linear not initialized");let s=await this.fetchIssue(e);if(!s)throw new Error(`Issue ${e} not found`);let i={};t.title!==void 0&&(i.title=t.title),t.description!==void 0&&(i.description=t.description),t.priority!==void 0&&(i.priority=Le[t.priority]),t.assigneeId!==void 0&&(i.assigneeId=t.assigneeId),t.stateId!==void 0&&(i.stateId=t.stateId),t.projectId!==void 0&&(i.projectId=t.projectId),t.labels!==void 0&&s.team&&(i.labelIds=await this.resolveLabelIds(s.team.id,t.labels)),await this.sdk.updateIssue(s.id,i);let n=await this.fetchIssue(s.id);if(!n)throw new Error("Failed to fetch updated issue");return n}async markInProgress(e){if(!this.sdk)throw new Error("Linear not initialized");let t=await this.fetchIssue(e);if(!t)throw new Error(`Issue ${e} not found`);let i=await(await this.sdk.issue(t.id)).team;if(!i)throw new Error("Issue has no team");let a=(await i.states()).nodes.find(l=>l.type==="started");a&&await this.sdk.updateIssue(t.id,{stateId:a.id})}async markDone(e){if(!this.sdk)throw new Error("Linear not initialized");let t=await this.fetchIssue(e);if(!t)throw new Error(`Issue ${e} not found`);let i=await(await this.sdk.issue(t.id)).team;if(!i)throw new Error("Issue has no team");let a=(await i.states()).nodes.find(l=>l.type==="completed");a&&await this.sdk.updateIssue(t.id,{stateId:a.id})}async addComment(e,t){if(!this.sdk)throw new Error("Linear not initialized");let s=await this.fetchIssue(e);if(!s)throw new Error(`Issue ${e} not found`);await this.sdk.createComment({issueId:s.id,body:t})}async getTeams(){if(!this.sdk)throw new Error("Linear not initialized");return(await this.sdk.teams({first:50})).nodes.map(t=>({id:t.id,name:t.name,key:t.key}))}async getProjects(){if(!this.sdk)throw new Error("Linear not initialized");return(await this.sdk.projects({first:50})).nodes.map(t=>({id:t.id,name:t.name}))}async mapIssue(e){let t=await e.state,s=await e.assignee,i=await e.team,n=await e.project,a=await e.labels();return{id:e.id,externalId:e.identifier,provider:"linear",title:e.title,description:e.description||void 0,status:vt[t?.type||"backlog"]||"backlog",priority:At[e.priority]||"none",type:this.inferType(e.title,a.nodes.map(l=>l.name)),assignee:s?{id:s.id,name:s.name,email:s.email}:void 0,labels:a.nodes.map(l=>l.name),team:i?{id:i.id,name:i.name,key:i.key}:void 0,project:n?{id:n.id,name:n.name}:void 0,url:e.url,createdAt:e.createdAt.toISOString(),updatedAt:e.updatedAt.toISOString(),raw:e}}inferType(e,t){let s=e.toLowerCase(),i=t.map(n=>n.toLowerCase());return i.includes("bug")||s.includes("fix")||s.includes("bug")?"bug":i.includes("feature")||s.includes("add")||s.includes("implement")?"feature":i.includes("improvement")||s.includes("improve")||s.includes("enhance")?"improvement":i.includes("chore")||s.includes("chore")||s.includes("deps")?"chore":"task"}async resolveLabelIds(e,t){return this.sdk?(await(await this.sdk.team(e)).labels()).nodes.filter(n=>t.includes(n.name)).map(n=>n.id):[]}},I=new Z;var ee=class{static{o(this,"LinearService")}initialized=!1;userId=null;isReady(){return this.initialized&&I.isConfigured()}async initialize(e){this.initialized||(await I.initialize(e),this.initialized=!0)}async initializeFromApiKey(e,t){let s={enabled:!0,provider:"linear",apiKey:e,defaultTeamId:t,syncOn:{task:!0,done:!0,ship:!0},enrichment:{enabled:!0,updateProvider:!0}};await this.initialize(s)}async fetchAssignedIssues(e){this.ensureInitialized();let t=`assigned:${this.userId||"me"}`,s=v.get(t);if(s)return s;let i=await I.fetchAssignedIssues(e);v.set(t,i);for(let n of i)y.set(`issue:${n.id}`,n),y.set(`issue:${n.externalId}`,n);return i}async fetchTeamIssues(e,t){this.ensureInitialized();let s=`team:${e}`,i=v.get(s);if(i)return i;let n=await I.fetchTeamIssues(e,t);v.set(s,n);for(let a of n)y.set(`issue:${a.id}`,a),y.set(`issue:${a.externalId}`,a);return n}async fetchIssue(e){this.ensureInitialized();let t=`issue:${e}`,s=y.get(t);if(s)return s;let i=await I.fetchIssue(e);return i&&(y.set(`issue:${i.id}`,i),y.set(`issue:${i.externalId}`,i)),i}async createIssue(e){this.ensureInitialized();let t=await I.createIssue(e);return y.set(`issue:${t.id}`,t),y.set(`issue:${t.externalId}`,t),v.clear(),t}async updateIssue(e,t){this.ensureInitialized();let s=await I.updateIssue(e,t);return y.set(`issue:${s.id}`,s),y.set(`issue:${s.externalId}`,s),s}async markInProgress(e){this.ensureInitialized(),await I.markInProgress(e),y.delete(`issue:${e}`),v.clear()}async markDone(e){this.ensureInitialized(),await I.markDone(e),y.delete(`issue:${e}`),v.clear()}async addComment(e,t){this.ensureInitialized(),await I.addComment(e,t)}async getTeams(){this.ensureInitialized();let e=$.get("teams");if(e)return e;let t=await I.getTeams();return $.set("teams",t),t}async getProjects(){this.ensureInitialized();let e=F.get("projects");if(e)return e;let t=await I.getProjects();return F.set("projects",t),t}clearCache(){de()}getCacheStats(){return pe()}ensureInitialized(){if(!this.initialized)throw new Error("Linear service not initialized. Call linearService.initialize() first or run `p. linear setup`.")}},p=new ee;import{z as u}from"zod";var _e=u.enum(["linear","jira","github","monday","asana","none"]),Nt=u.enum(["backlog","todo","in_progress","in_review","done","cancelled"]),xt=u.enum(["none","urgent","high","medium","low"]),Dt=u.enum(["feature","bug","improvement","task","chore","epic"]),Ct=u.object({id:u.string(),identifier:u.string(),title:u.string(),description:u.string().optional(),status:Nt,priority:xt,type:Dt.optional(),assignee:u.object({id:u.string(),name:u.string(),email:u.string().optional()}).optional(),labels:u.array(u.string()).default([]),team:u.object({id:u.string(),name:u.string(),key:u.string().optional()}).optional(),project:u.object({id:u.string(),name:u.string()}).optional(),url:u.string(),createdAt:u.string(),updatedAt:u.string(),fetchedAt:u.string()}),Cr=u.object({provider:_e,lastSync:u.string(),staleAfter:u.number().default(18e5),issues:u.record(u.string(),Ct)}),br=u.object({provider:_e,fetched:u.number(),updated:u.number(),errors:u.array(u.object({issueId:u.string(),error:u.string()})),timestamp:u.string()});function je(r){return{provider:r,lastSync:"",staleAfter:18e5,issues:{}}}o(je,"createEmptyIssues");import{Database as Zt}from"bun:sqlite";import Se from"node:fs";import et from"node:path";import Vt from"node:crypto";import D from"node:fs/promises";import we from"node:os";import c from"node:path";import{globSync as qt}from"glob";import{formatDistanceToNowStrict as _r}from"date-fns";function Oe(r){return{year:r.getFullYear().toString(),month:(r.getMonth()+1).toString().padStart(2,"0"),day:r.getDate().toString().padStart(2,"0")}}o(Oe,"getYearMonthDay");te();var Pe=class{static{o(this,"PathManager")}globalBaseDir;globalProjectsDir;globalConfigDir;constructor(){let e=process.env.PRJCT_CLI_HOME?.trim();this.globalBaseDir=e?c.resolve(e):c.join(we.homedir(),".prjct-cli"),this.globalProjectsDir=c.join(this.globalBaseDir,"projects"),this.globalConfigDir=c.join(this.globalBaseDir,"config")}setGlobalBaseDir(e){this.globalBaseDir=c.resolve(e),this.globalProjectsDir=c.join(this.globalBaseDir,"projects"),this.globalConfigDir=c.join(this.globalBaseDir,"config")}generateProjectId(e){return Vt.randomUUID()}getGlobalBasePath(){return this.globalBaseDir}getGlobalProjectPath(e){return c.join(this.globalProjectsDir,e)}getLocalConfigPath(e){return c.join(e,".prjct","prjct.config.json")}getGlobalProjectConfigPath(e){return c.join(this.getGlobalProjectPath(e),"project.json")}getLegacyPrjctPath(e){return c.join(e,".prjct")}async hasLegacyStructure(e){let t=this.getLegacyPrjctPath(e);return await fe(t)}async hasConfig(e){let t=this.getLocalConfigPath(e);return await g(t)}async ensureGlobalStructure(){await k(this.globalBaseDir),await k(this.globalProjectsDir),await k(this.globalConfigDir)}async ensureProjectStructure(e){await this.ensureGlobalStructure();let t=this.getGlobalProjectPath(e),s=["core","progress","planning","analysis","memory","agents"];for(let i of s)await k(c.join(t,i));return await k(c.join(t,"planning","tasks")),await k(c.join(t,"sessions")),t}getSessionPath(e,t=new Date){let{year:s,month:i,day:n}=Oe(t);return c.join(this.getGlobalProjectPath(e),"sessions",s,i,n)}getCurrentSessionPath(e){return this.getSessionPath(e,new Date)}async ensureSessionPath(e,t=new Date){let s=this.getSessionPath(e,t);return await k(s),s}async listSessions(e,t=null,s=null){let i=c.join(this.getGlobalProjectPath(e),"sessions"),n=[];try{let a=await D.readdir(i,{withFileTypes:!0});for(let l of a){if(!l.isDirectory()||t&&l.name!==t.toString())continue;let m=c.join(i,l.name),C=await D.readdir(m,{withFileTypes:!0});for(let S of C){if(!S.isDirectory()||s&&S.name!==s.toString().padStart(2,"0"))continue;let H=c.join(m,S.name),le=await D.readdir(H,{withFileTypes:!0});for(let B of le)B.isDirectory()&&n.push({year:l.name,month:S.name,day:B.name,path:c.join(H,B.name),date:new Date(`${l.name}-${S.name}-${B.name}`)})}}return n.sort((l,m)=>m.date.getTime()-l.date.getTime()),n}catch{return[]}}async getSessionsInRange(e,t,s=new Date){return(await this.listSessions(e)).filter(n=>n.date>=t&&n.date<=s)}getFilePath(e,t,s){return c.join(this.getGlobalProjectPath(e),t,s)}async listProjects(){try{return await this.ensureGlobalStructure(),(await D.readdir(this.globalProjectsDir,{withFileTypes:!0})).filter(t=>t.isDirectory()).map(t=>t.name)}catch{return[]}}async projectExists(e){let t=this.getGlobalProjectPath(e);return await fe(t)}getDisplayPath(e){let t=we.homedir();return e.startsWith(t)?e.replace(t,"~"):e}getAuthConfigPath(){return c.join(this.globalConfigDir,"auth.json")}getSyncPendingPath(e){return c.join(this.getGlobalProjectPath(e),"sync","pending.json")}getLastSyncPath(e){return c.join(this.getGlobalProjectPath(e),"sync","last-sync.json")}getRunningStatusPath(){return c.join(this.globalBaseDir,".running")}getDocsPath(){return c.join(this.globalBaseDir,"docs")}async getAgentDir(){return(await(z(),ue(ie)).getActiveProvider()).configDir}async getAgentSettingsPath(){let e=await(z(),ue(ie)).getActiveProvider();return(z(),ue(ie)).getGlobalSettingsPath(e.name)}getClaudeDir(){return c.join(we.homedir(),".claude")}getClaudeSettingsPath(){return c.join(this.getClaudeDir(),"settings.json")}getAgentsPath(e){return e?c.join(this.getGlobalProjectPath(e),"agents"):c.join(this.globalBaseDir,"agents")}getStoragePath(e,t){return c.join(this.getGlobalProjectPath(e),"storage",t)}getContextPath(e){return c.join(this.getGlobalProjectPath(e),"context")}async detectMonorepo(e){let t={isMonorepo:!1,type:null,rootPath:e,packages:[]},s=[{file:"pnpm-workspace.yaml",type:"pnpm"},{file:"lerna.json",type:"lerna"},{file:"nx.json",type:"nx"},{file:"rush.json",type:"rush"},{file:"turbo.json",type:"turborepo"}];for(let i of s){let n=c.join(e,i.file);if(await g(n)){t.isMonorepo=!0,t.type=i.type;break}}if(!t.isMonorepo){let i=c.join(e,"package.json");if(await g(i))try{let n=await D.readFile(i,"utf-8");JSON.parse(n).workspaces&&(t.isMonorepo=!0,t.type="npm")}catch{}}return t.isMonorepo&&(t.packages=await this.discoverMonorepoPackages(e,t.type)),t}async discoverMonorepoPackages(e,t){let s=[],i=[];try{if(t==="pnpm"){let a=(await D.readFile(c.join(e,"pnpm-workspace.yaml"),"utf-8")).match(/packages:\s*\n((?:\s*-\s*.+\n?)+)/);a&&(i=a[1].split(`
7
- `).map(l=>l.replace(/^\s*-\s*['"]?|['"]?\s*$/g,"")).filter(Boolean))}else if(t==="npm"||t==="lerna"){let n=c.join(e,"package.json"),a=await D.readFile(n,"utf-8"),l=JSON.parse(a);if(Array.isArray(l.workspaces)?i=l.workspaces:l.workspaces?.packages&&(i=l.workspaces.packages),t==="lerna"){let m=c.join(e,"lerna.json");if(await g(m)){let C=await D.readFile(m,"utf-8"),S=JSON.parse(C);S.packages&&(i=S.packages)}}}else if(t==="nx")i=["apps/*","libs/*","packages/*"];else if(t==="turborepo"){let n=c.join(e,"package.json"),a=await D.readFile(n,"utf-8"),l=JSON.parse(a);Array.isArray(l.workspaces)&&(i=l.workspaces)}i.length===0&&(i=["packages/*","apps/*","libs/*"]);for(let n of i){if(n.startsWith("!"))continue;let a=qt(n,{cwd:e,absolute:!1});for(let l of a){let m=c.join(e,l),C=c.join(m,"package.json");if(await g(C))try{let S=await D.readFile(C,"utf-8"),H=JSON.parse(S),le=c.join(m,"PRJCT.md");s.push({name:H.name||c.basename(l),path:m,relativePath:l,hasPrjctMd:await g(le)})}catch{}}}}catch{}return s}async findContainingPackage(e,t){if(!t.isMonorepo)return null;let s=c.resolve(e);for(let i of t.packages){let n=c.resolve(i.path);if(s.startsWith(n))return i}return null}async findMonorepoRoot(e){let t=c.resolve(e),s=c.parse(t).root;for(;t!==s;){if((await this.detectMonorepo(t)).isMonorepo)return t;t=c.dirname(t)}return null}},Qt=new Pe,Ze=Qt;var er=[{version:1,name:"initial-schema",up:o(r=>{r.run(`
6
+ var H=Object.defineProperty;var ft=Object.getOwnPropertyDescriptor;var ht=Object.getOwnPropertyNames;var yt=Object.prototype.hasOwnProperty;var o=(r,e)=>H(r,"name",{value:e,configurable:!0}),Re=(r=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(r,{get:(e,t)=>(typeof require<"u"?require:e)[t]}):r)(function(r){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+r+'" is not supported')});var j=(r,e)=>()=>(r&&(e=r(r=0)),e);var ke=(r,e)=>{for(var t in e)H(r,t,{get:e[t],enumerable:!0})},Et=(r,e,t,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of ht(e))!yt.call(r,n)&&n!==t&&H(r,n,{get:()=>e[n],enumerable:!(s=ft(e,n))||s.enumerable});return r};var ue=r=>Et(H({},"__esModule",{value:!0}),r);function Tt(r){return r instanceof Error&&"code"in r}function V(r){return Tt(r)&&r.code==="ENOENT"}function w(r){return r instanceof Error?r.message:typeof r=="string"?r:"Unknown error"}var R=j(()=>{"use strict";o(Tt,"isNodeError");o(V,"isNotFoundError");o(w,"getErrorMessage")});var Le={};ke(Le,{deleteCredential:()=>St,getCredential:()=>U,getCredentialWithSource:()=>bt,hasCredential:()=>vt,setCredential:()=>Pt});import{exec as It}from"node:child_process";import{promisify as wt}from"node:util";async function Pt(r,e){if(process.platform!=="darwin")return console.warn("[keychain] macOS Keychain only available on macOS"),!1;try{return await G(`security delete-generic-password -s "${K}" -a "${r}" 2>/dev/null || true`),await G(`security add-generic-password -s "${K}" -a "${r}" -w "${e}"`),!0}catch(t){return console.error("[keychain] Failed to store credential:",w(t)),!1}}async function U(r){if(process.platform!=="darwin")return ge(r);try{let{stdout:e}=await G(`security find-generic-password -s "${K}" -a "${r}" -w 2>/dev/null`);return e.trim()||null}catch{return ge(r)}}async function St(r){if(process.platform!=="darwin")return!1;try{return await G(`security delete-generic-password -s "${K}" -a "${r}" 2>/dev/null`),!0}catch{return!1}}async function vt(r){let e=await U(r);return e!==null&&e.length>0}function ge(r){let t={"linear-api-key":"LINEAR_API_KEY","jira-api-token":"JIRA_API_TOKEN"}[r];return process.env[t]||null}async function bt(r){if(process.platform==="darwin")try{let{stdout:t}=await G(`security find-generic-password -s "${K}" -a "${r}" -w 2>/dev/null`),s=t.trim();if(s)return{value:s,source:"keychain"}}catch{}let e=ge(r);return e?{value:e,source:"env"}:{value:null,source:"none"}}var G,K,Z=j(()=>{"use strict";R();G=wt(It),K="prjct-cli";o(Pt,"setCredential");o(U,"getCredential");o(St,"deleteCredential");o(vt,"hasCredential");o(ge,"getEnvFallback");o(bt,"getCredentialWithSource")});var $e=j(()=>{"use strict";R()});import me from"node:fs/promises";async function m(r){try{return await me.access(r),!0}catch(e){if(V(e))return!1;throw e}}async function fe(r){try{return(await me.stat(r)).isDirectory()}catch(e){if(V(e))return!1;throw e}}async function k(r){await me.mkdir(r,{recursive:!0})}var te=j(()=>{"use strict";$e();R();o(m,"fileExists");o(fe,"dirExists");o(k,"ensureDir")});import{z as x}from"zod";function Fe(r,e){let t=r.split(".").map(Number),s=e.split(".").map(Number);for(let n=0;n<3;n++){let i=t[n]??0,a=s[n]??0;if(i<a)return-1;if(i>a)return 1}return 0}var Br,Hr,Wr,_t,Vr,Ue=j(()=>{"use strict";Br=x.enum(["opus","sonnet","haiku"]),Hr=x.enum(["2.5-pro","2.5-flash","2.0-flash"]),Wr=x.string().min(1),_t=x.object({provider:x.string(),model:x.string(),cliVersion:x.string().optional(),recordedAt:x.string()}),Vr=x.object({preferredModel:x.string().optional(),lastAnalysisModel:_t.optional()});o(Fe,"compareSemver")});import he from"node:fs/promises";import jt from"node:os";import Xe from"node:path";async function ze(){try{let r=await he.readFile(Ke,"utf-8"),e=JSON.parse(r);return!e.timestamp||!e.detection||Date.now()-new Date(e.timestamp).getTime()>Ot?null:e.detection}catch{return null}}async function qe(r){let e={timestamp:new Date().toISOString(),detection:r};await he.mkdir(Ge,{recursive:!0}),await he.writeFile(Ke,JSON.stringify(e,null,2))}var Ge,Ke,Ot,Je=j(()=>{"use strict";Ge=Xe.join(jt.homedir(),".prjct-cli","cache"),Ke=Xe.join(Ge,"providers.json"),Ot=600*1e3;o(ze,"readProviderCache");o(qe,"writeProviderCache")});var ne={};ke(ne,{AntigravityProvider:()=>Te,ClaudeProvider:()=>re,CursorProvider:()=>He,GeminiProvider:()=>Ee,Providers:()=>b,WindsurfProvider:()=>We,detectAllProviders:()=>Ie,detectAntigravity:()=>qt,detectCursorProject:()=>Ze,detectProvider:()=>ye,detectWindsurfProject:()=>Qe,getActiveProvider:()=>Xt,getCommandsDir:()=>Ht,getGlobalContextPath:()=>Jt,getGlobalSettingsPath:()=>Yt,getProjectCommandsPath:()=>Wt,getProviderBranding:()=>se,getSkillsPath:()=>Bt,hasProviderConfig:()=>Gt,needsCursorRouterRegeneration:()=>Kt,needsWindsurfRouterRegeneration:()=>zt,selectProvider:()=>Vt,validateCliVersion:()=>Ve});import{exec as Mt}from"node:child_process";import X from"node:os";import E from"node:path";import{promisify as $t}from"node:util";async function Ft(r){try{let{stdout:e}=await Ye(`which ${r}`,{timeout:Be});return e.trim()}catch{return null}}async function Ut(r){try{let{stdout:e}=await Ye(`${r} --version`,{timeout:Be}),t=e.match(/\d+\.\d+\.\d+/);return t?t[0]:e.trim()}catch{return null}}async function ye(r){let e=b[r];if(!e.cliCommand)return{installed:!1};let t=await Ft(e.cliCommand);if(!t)return{installed:!1};let s=await Ut(e.cliCommand),n=Ve(r,s||void 0);return{installed:!0,version:s||void 0,path:t,versionWarning:n||void 0}}function Ve(r,e){let t=b[r];return!t.minCliVersion||!e?null:Fe(e,t.minCliVersion)<0?`\u26A0\uFE0F ${t.displayName} v${e} is below minimum v${t.minCliVersion}. Some features may not work correctly.`:null}async function Ie(r=!1){if(!r){let n=await ze();if(n)return n}let[e,t]=await Promise.all([ye("claude"),ye("gemini")]),s={claude:e,gemini:t};return await qe(s).catch(()=>{}),s}async function Xt(r){if(r&&b[r])return b[r];let e=await Ie();return e.claude.installed&&!e.gemini.installed?re:e.gemini.installed&&!e.claude.installed?Ee:re}async function Gt(r){let e=b[r];return e.configDir?m(e.configDir):!1}function se(r){return{commitFooter:"Generated with [p/](https://www.prjct.app/)",signature:{claude:"\u26A1 prjct + Claude",gemini:"\u26A1 prjct + Gemini",cursor:"\u26A1 prjct + Cursor",antigravity:"\u26A1 prjct + Antigravity",windsurf:"\u26A1 prjct + Windsurf"}[r]||"\u26A1 prjct"}}async function Ze(r){let e=E.join(r,".cursor"),t=E.join(e,"rules"),s=E.join(t,"prjct.mdc"),[n,i]=await Promise.all([m(e),m(s)]);return{detected:n,routerInstalled:i,projectRoot:n?r:void 0}}async function Kt(r){let e=await Ze(r);return e.detected&&!e.routerInstalled}async function Qe(r){let e=E.join(r,".windsurf"),t=E.join(e,"rules"),s=E.join(t,"prjct.md"),[n,i]=await Promise.all([m(e),m(s)]);return{detected:n,routerInstalled:i,projectRoot:n?r:void 0}}async function zt(r){let e=await Qe(r);return e.detected&&!e.routerInstalled}async function qt(){let r=Te.configDir;if(!r)return{installed:!1,skillInstalled:!1};let e=E.join(r,"skills","prjct","SKILL.md"),[t,s]=await Promise.all([m(r),m(e)]);return{installed:t,skillInstalled:s,configPath:t?r:void 0}}function Jt(r){let e=b[r];return e.configDir?E.join(e.configDir,e.contextFile):null}function Yt(r){let e=b[r];return!e.configDir||!e.settingsFile?null:E.join(e.configDir,e.settingsFile)}function Bt(r){return b[r].skillsDir}function Ht(r){return b[r].commandsDir}function Wt(r,e){let t=b[r];return E.join(e,t.commandsDir)}async function Vt(){let r=await Ie(),e=r.claude.installed,t=r.gemini.installed;return!e&&!t?{provider:"claude",userSelected:!1,detection:r}:e&&!t?{provider:"claude",userSelected:!1,detection:r}:t&&!e?{provider:"gemini",userSelected:!1,detection:r}:{provider:"claude",userSelected:!0,detection:r}}var Ye,Be,re,Ee,Te,He,We,b,z=j(()=>{"use strict";Ue();te();Je();Ye=$t(Mt),Be=2e3,re={name:"claude",displayName:"Claude Code",cliCommand:"claude",configDir:E.join(X.homedir(),".claude"),contextFile:"CLAUDE.md",skillsDir:E.join(X.homedir(),".claude","skills"),commandsDir:".claude/commands",commandFormat:"md",settingsFile:"settings.json",projectSettingsFile:"settings.local.json",ignoreFile:".claudeignore",websiteUrl:"https://www.anthropic.com/claude",docsUrl:"https://docs.anthropic.com/claude-code",defaultModel:"sonnet",supportedModels:["opus","sonnet","haiku"],minCliVersion:"1.0.0"},Ee={name:"gemini",displayName:"Gemini CLI",cliCommand:"gemini",configDir:E.join(X.homedir(),".gemini"),contextFile:"GEMINI.md",skillsDir:E.join(X.homedir(),".gemini","skills"),commandsDir:".gemini/commands",commandFormat:"toml",settingsFile:"settings.json",projectSettingsFile:"settings.json",ignoreFile:".geminiignore",websiteUrl:"https://geminicli.com",docsUrl:"https://geminicli.com/docs",defaultModel:"2.5-flash",supportedModels:["2.5-pro","2.5-flash","2.0-flash"],minCliVersion:"1.0.0"},Te={name:"antigravity",displayName:"Google Antigravity",cliCommand:null,configDir:E.join(X.homedir(),".gemini","antigravity"),contextFile:"ANTIGRAVITY.md",skillsDir:E.join(X.homedir(),".gemini","antigravity","global_skills"),commandsDir:".agent/skills",commandFormat:"md",settingsFile:"mcp_config.json",projectSettingsFile:null,ignoreFile:".agentignore",websiteUrl:"https://gemini.google.com/app/antigravity",docsUrl:"https://gemini.google.com/app/antigravity",defaultModel:null,supportedModels:[],minCliVersion:null},He={name:"cursor",displayName:"Cursor IDE",cliCommand:null,configDir:null,contextFile:"prjct.mdc",skillsDir:null,commandsDir:".cursor/commands",rulesDir:".cursor/rules",commandFormat:"md",settingsFile:null,projectSettingsFile:null,ignoreFile:".cursorignore",isProjectLevel:!0,websiteUrl:"https://cursor.com",docsUrl:"https://cursor.com/docs",defaultModel:null,supportedModels:[],minCliVersion:null},We={name:"windsurf",displayName:"Windsurf IDE",cliCommand:null,configDir:null,contextFile:"prjct.md",skillsDir:null,commandsDir:".windsurf/workflows",rulesDir:".windsurf/rules",commandFormat:"md",settingsFile:null,projectSettingsFile:null,ignoreFile:".windsurfignore",isProjectLevel:!0,websiteUrl:"https://windsurf.com",docsUrl:"https://docs.windsurf.com",defaultModel:null,supportedModels:[],minCliVersion:null},b={claude:re,gemini:Ee,cursor:He,antigravity:Te,windsurf:We};o(Ft,"whichCommand");o(Ut,"getCliVersion");o(ye,"detectProvider");o(Ve,"validateCliVersion");o(Ie,"detectAllProviders");o(Xt,"getActiveProvider");o(Gt,"hasProviderConfig");o(se,"getProviderBranding");o(Ze,"detectCursorProject");o(Kt,"needsCursorRouterRegeneration");o(Qe,"detectWindsurfProject");o(zt,"needsWindsurfRouterRegeneration");o(qt,"detectAntigravity");o(Jt,"getGlobalContextPath");o(Yt,"getGlobalSettingsPath");o(Bt,"getSkillsPath");o(Ht,"getCommandsDir");o(Wt,"getProjectCommandsPath");o(Vt,"selectProvider")});var O=class{static{o(this,"TTLCache")}cache=new Map;ttl;maxSize;constructor(e={}){this.ttl=e.ttl??5e3,this.maxSize=e.maxSize??50}isValid(e){let t=this.cache.get(e);return t?Date.now()-t.timestamp<this.ttl:!1}get(e){let t=this.cache.get(e);return t?this.isValid(e)?t.data:(this.cache.delete(e),null):null}set(e,t){this.cache.set(e,{data:t,timestamp:Date.now()}),this.evictOldEntries()}delete(e){this.cache.delete(e)}clear(){this.cache.clear()}has(e){return this.cache.has(e)}get size(){return this.cache.size}evictOldEntries(){if(this.cache.size<=this.maxSize)return;let t=Array.from(this.cache.entries()).sort((s,n)=>s[1].timestamp-n[1].timestamp).slice(0,this.cache.size-this.maxSize);for(let[s]of t)this.cache.delete(s)}stats(){return{size:this.cache.size,maxSize:this.maxSize,ttl:this.ttl}}prune(){let e=0;for(let t of this.cache.keys())this.isValid(t)||(this.cache.delete(t),e++);return e}};var W=300*1e3,y=new O({ttl:W,maxSize:100}),v=new O({ttl:W,maxSize:10}),$=new O({ttl:W,maxSize:5}),F=new O({ttl:W,maxSize:5});function de(){y.clear(),v.clear(),$.clear(),F.clear()}o(de,"clearLinearCache");function pe(){return{issues:y.stats(),assignedIssues:v.stats(),teams:$.stats(),projects:F.stats()}}o(pe,"getLinearCacheStats");R();Z();var At={backlog:"backlog",unstarted:"todo",started:"in_progress",completed:"done",canceled:"cancelled",cancelled:"cancelled"},xt={0:"none",1:"urgent",2:"high",3:"medium",4:"low"},_e={none:0,urgent:1,high:2,medium:3,low:4},Q=class{static{o(this,"LinearProvider")}name="linear";displayName="Linear";sdk=null;config=null;isConfigured(){return this.sdk!==null&&this.config?.enabled===!0}async initialize(e){this.config=e;let t=e.apiKey||await U("linear-api-key");if(!t)throw new Error("LINEAR_API_KEY not configured. Run `p. linear setup` to configure.");let{LinearClient:s}=await import("@linear/sdk");this.sdk=new s({apiKey:t});try{await this.sdk.viewer}catch(n){throw this.sdk=null,new Error(`Linear connection failed: ${w(n)}`)}}async fetchAssignedIssues(e){if(!this.sdk)throw new Error("Linear not initialized");let t=await this.sdk.viewer,s={};e?.includeCompleted||(s.state={type:{nin:["completed","canceled"]}}),this.config?.defaultTeamId&&(s.team={id:{eq:this.config.defaultTeamId}});let n=await t.assignedIssues({first:e?.limit||50,filter:Object.keys(s).length>0?s:void 0});return Promise.all(n.nodes.map(i=>this.mapIssue(i)))}async fetchTeamIssues(e,t){if(!this.sdk)throw new Error("Linear not initialized");let n=await(await this.sdk.team(e)).issues({first:t?.limit||50,filter:t?.includeCompleted?void 0:{state:{type:{nin:["completed","canceled"]}}}});return Promise.all(n.nodes.map(i=>this.mapIssue(i)))}async fetchIssue(e){if(!this.sdk)throw new Error("Linear not initialized");try{if(e.includes("-")&&/^[A-Z]+-\d+$/.test(e)){let s=e.match(/^([A-Z]+)-(\d+)$/);if(!s)return null;let[,n,i]=s,a=parseInt(i,10),g=(await this.sdk.teams({first:50})).nodes.find(S=>S.key===n);if(!g)return null;let N=await g.issues({first:1,filter:{number:{eq:a}}});return N.nodes.length>0?this.mapIssue(N.nodes[0]):null}let t=await this.sdk.issue(e);return this.mapIssue(t)}catch{return null}}async createIssue(e){if(!this.sdk)throw new Error("Linear not initialized");let t=e.teamId||this.config?.defaultTeamId;if(!t)throw new Error("Team ID required for creating issues");let n=await(await this.sdk.createIssue({teamId:t,title:e.title,description:e.description,priority:e.priority?_e[e.priority]:void 0,projectId:e.projectId||this.config?.defaultProjectId,assigneeId:e.assigneeId,labelIds:e.labels?await this.resolveLabelIds(t,e.labels):void 0})).issue;if(!n)throw new Error("Failed to create issue");return this.mapIssue(n)}async updateIssue(e,t){if(!this.sdk)throw new Error("Linear not initialized");let s=await this.fetchIssue(e);if(!s)throw new Error(`Issue ${e} not found`);let n={};t.title!==void 0&&(n.title=t.title),t.description!==void 0&&(n.description=t.description),t.priority!==void 0&&(n.priority=_e[t.priority]),t.assigneeId!==void 0&&(n.assigneeId=t.assigneeId),t.stateId!==void 0&&(n.stateId=t.stateId),t.projectId!==void 0&&(n.projectId=t.projectId),t.labels!==void 0&&s.team&&(n.labelIds=await this.resolveLabelIds(s.team.id,t.labels)),await this.sdk.updateIssue(s.id,n);let i=await this.fetchIssue(s.id);if(!i)throw new Error("Failed to fetch updated issue");return i}async markInProgress(e){if(!this.sdk)throw new Error("Linear not initialized");let t=await this.fetchIssue(e);if(!t)throw new Error(`Issue ${e} not found`);let n=await(await this.sdk.issue(t.id)).team;if(!n)throw new Error("Issue has no team");let a=(await n.states()).nodes.find(l=>l.type==="started");a&&await this.sdk.updateIssue(t.id,{stateId:a.id})}async markDone(e){if(!this.sdk)throw new Error("Linear not initialized");let t=await this.fetchIssue(e);if(!t)throw new Error(`Issue ${e} not found`);let n=await(await this.sdk.issue(t.id)).team;if(!n)throw new Error("Issue has no team");let a=(await n.states()).nodes.find(l=>l.type==="completed");a&&await this.sdk.updateIssue(t.id,{stateId:a.id})}async addComment(e,t){if(!this.sdk)throw new Error("Linear not initialized");let s=await this.fetchIssue(e);if(!s)throw new Error(`Issue ${e} not found`);await this.sdk.createComment({issueId:s.id,body:t})}async getTeams(){if(!this.sdk)throw new Error("Linear not initialized");return(await this.sdk.teams({first:50})).nodes.map(t=>({id:t.id,name:t.name,key:t.key}))}async getProjects(){if(!this.sdk)throw new Error("Linear not initialized");return(await this.sdk.projects({first:50})).nodes.map(t=>({id:t.id,name:t.name}))}async mapIssue(e){let t=await e.state,s=await e.assignee,n=await e.team,i=await e.project,a=await e.labels();return{id:e.id,externalId:e.identifier,provider:"linear",title:e.title,description:e.description||void 0,status:At[t?.type||"backlog"]||"backlog",priority:xt[e.priority]||"none",type:this.inferType(e.title,a.nodes.map(l=>l.name)),assignee:s?{id:s.id,name:s.name,email:s.email}:void 0,labels:a.nodes.map(l=>l.name),team:n?{id:n.id,name:n.name,key:n.key}:void 0,project:i?{id:i.id,name:i.name}:void 0,url:e.url,createdAt:e.createdAt.toISOString(),updatedAt:e.updatedAt.toISOString(),raw:e}}inferType(e,t){let s=e.toLowerCase(),n=t.map(i=>i.toLowerCase());return n.includes("bug")||s.includes("fix")||s.includes("bug")?"bug":n.includes("feature")||s.includes("add")||s.includes("implement")?"feature":n.includes("improvement")||s.includes("improve")||s.includes("enhance")?"improvement":n.includes("chore")||s.includes("chore")||s.includes("deps")?"chore":"task"}async resolveLabelIds(e,t){return this.sdk?(await(await this.sdk.team(e)).labels()).nodes.filter(i=>t.includes(i.name)).map(i=>i.id):[]}},I=new Q;var ee=class{static{o(this,"LinearService")}initialized=!1;userId=null;isReady(){return this.initialized&&I.isConfigured()}async initialize(e){this.initialized||(await I.initialize(e),this.initialized=!0)}async initializeFromApiKey(e,t){let s={enabled:!0,provider:"linear",apiKey:e,defaultTeamId:t,syncOn:{task:!0,done:!0,ship:!0},enrichment:{enabled:!0,updateProvider:!0}};await this.initialize(s)}async fetchAssignedIssues(e){this.ensureInitialized();let t=`assigned:${this.userId||"me"}`,s=v.get(t);if(s)return s;let n=await I.fetchAssignedIssues(e);v.set(t,n);for(let i of n)y.set(`issue:${i.id}`,i),y.set(`issue:${i.externalId}`,i);return n}async fetchTeamIssues(e,t){this.ensureInitialized();let s=`team:${e}`,n=v.get(s);if(n)return n;let i=await I.fetchTeamIssues(e,t);v.set(s,i);for(let a of i)y.set(`issue:${a.id}`,a),y.set(`issue:${a.externalId}`,a);return i}async fetchIssue(e){this.ensureInitialized();let t=`issue:${e}`,s=y.get(t);if(s)return s;let n=await I.fetchIssue(e);return n&&(y.set(`issue:${n.id}`,n),y.set(`issue:${n.externalId}`,n)),n}async createIssue(e){this.ensureInitialized();let t=await I.createIssue(e);return y.set(`issue:${t.id}`,t),y.set(`issue:${t.externalId}`,t),v.clear(),t}async updateIssue(e,t){this.ensureInitialized();let s=await I.updateIssue(e,t);return y.set(`issue:${s.id}`,s),y.set(`issue:${s.externalId}`,s),s}async markInProgress(e){this.ensureInitialized(),await I.markInProgress(e),y.delete(`issue:${e}`),v.clear()}async markDone(e){this.ensureInitialized(),await I.markDone(e),y.delete(`issue:${e}`),v.clear()}async addComment(e,t){this.ensureInitialized(),await I.addComment(e,t)}async getTeams(){this.ensureInitialized();let e=$.get("teams");if(e)return e;let t=await I.getTeams();return $.set("teams",t),t}async getProjects(){this.ensureInitialized();let e=F.get("projects");if(e)return e;let t=await I.getProjects();return F.set("projects",t),t}clearCache(){de()}getCacheStats(){return pe()}ensureInitialized(){if(!this.initialized)throw new Error("Linear service not initialized. Call linearService.initialize() first or run `p. linear setup`.")}},p=new ee;import{z as u}from"zod";var je=u.enum(["linear","jira","github","monday","asana","none"]),Dt=u.enum(["backlog","todo","in_progress","in_review","done","cancelled"]),Nt=u.enum(["none","urgent","high","medium","low"]),Ct=u.enum(["feature","bug","improvement","task","chore","epic"]),Rt=u.object({id:u.string(),identifier:u.string(),title:u.string(),description:u.string().optional(),status:Dt,priority:Nt,type:Ct.optional(),assignee:u.object({id:u.string(),name:u.string(),email:u.string().optional()}).optional(),labels:u.array(u.string()).default([]),team:u.object({id:u.string(),name:u.string(),key:u.string().optional()}).optional(),project:u.object({id:u.string(),name:u.string()}).optional(),url:u.string(),createdAt:u.string(),updatedAt:u.string(),fetchedAt:u.string()}),kr=u.object({provider:je,lastSync:u.string(),staleAfter:u.number().default(18e5),issues:u.record(u.string(),Rt)}),Lr=u.object({provider:je,fetched:u.number(),updated:u.number(),errors:u.array(u.object({issueId:u.string(),error:u.string()})),timestamp:u.string()});function Oe(r){return{provider:r,lastSync:"",staleAfter:18e5,issues:{}}}o(Oe,"createEmptyIssues");import Se from"node:fs";import rt from"node:path";import Zt from"node:crypto";import D from"node:fs/promises";import we from"node:os";import c from"node:path";import{globSync as Qt}from"glob";import{formatDistanceToNowStrict as Mr}from"date-fns";function Me(r){return{year:r.getFullYear().toString(),month:(r.getMonth()+1).toString().padStart(2,"0"),day:r.getDate().toString().padStart(2,"0")}}o(Me,"getYearMonthDay");te();var Pe=class{static{o(this,"PathManager")}globalBaseDir;globalProjectsDir;globalConfigDir;constructor(){let e=process.env.PRJCT_CLI_HOME?.trim();this.globalBaseDir=e?c.resolve(e):c.join(we.homedir(),".prjct-cli"),this.globalProjectsDir=c.join(this.globalBaseDir,"projects"),this.globalConfigDir=c.join(this.globalBaseDir,"config")}setGlobalBaseDir(e){this.globalBaseDir=c.resolve(e),this.globalProjectsDir=c.join(this.globalBaseDir,"projects"),this.globalConfigDir=c.join(this.globalBaseDir,"config")}generateProjectId(e){return Zt.randomUUID()}getGlobalBasePath(){return this.globalBaseDir}getGlobalProjectPath(e){return c.join(this.globalProjectsDir,e)}getLocalConfigPath(e){return c.join(e,".prjct","prjct.config.json")}getGlobalProjectConfigPath(e){return c.join(this.getGlobalProjectPath(e),"project.json")}getLegacyPrjctPath(e){return c.join(e,".prjct")}async hasLegacyStructure(e){let t=this.getLegacyPrjctPath(e);return await fe(t)}async hasConfig(e){let t=this.getLocalConfigPath(e);return await m(t)}async ensureGlobalStructure(){await k(this.globalBaseDir),await k(this.globalProjectsDir),await k(this.globalConfigDir)}async ensureProjectStructure(e){await this.ensureGlobalStructure();let t=this.getGlobalProjectPath(e),s=["core","progress","planning","analysis","memory","agents"];for(let n of s)await k(c.join(t,n));return await k(c.join(t,"planning","tasks")),await k(c.join(t,"sessions")),t}getSessionPath(e,t=new Date){let{year:s,month:n,day:i}=Me(t);return c.join(this.getGlobalProjectPath(e),"sessions",s,n,i)}getCurrentSessionPath(e){return this.getSessionPath(e,new Date)}async ensureSessionPath(e,t=new Date){let s=this.getSessionPath(e,t);return await k(s),s}async listSessions(e,t=null,s=null){let n=c.join(this.getGlobalProjectPath(e),"sessions"),i=[];try{let a=await D.readdir(n,{withFileTypes:!0});for(let l of a){if(!l.isDirectory()||t&&l.name!==t.toString())continue;let g=c.join(n,l.name),N=await D.readdir(g,{withFileTypes:!0});for(let S of N){if(!S.isDirectory()||s&&S.name!==s.toString().padStart(2,"0"))continue;let Y=c.join(g,S.name),le=await D.readdir(Y,{withFileTypes:!0});for(let B of le)B.isDirectory()&&i.push({year:l.name,month:S.name,day:B.name,path:c.join(Y,B.name),date:new Date(`${l.name}-${S.name}-${B.name}`)})}}return i.sort((l,g)=>g.date.getTime()-l.date.getTime()),i}catch{return[]}}async getSessionsInRange(e,t,s=new Date){return(await this.listSessions(e)).filter(i=>i.date>=t&&i.date<=s)}getFilePath(e,t,s){return c.join(this.getGlobalProjectPath(e),t,s)}async listProjects(){try{return await this.ensureGlobalStructure(),(await D.readdir(this.globalProjectsDir,{withFileTypes:!0})).filter(t=>t.isDirectory()).map(t=>t.name)}catch{return[]}}async projectExists(e){let t=this.getGlobalProjectPath(e);return await fe(t)}getDisplayPath(e){let t=we.homedir();return e.startsWith(t)?e.replace(t,"~"):e}getAuthConfigPath(){return c.join(this.globalConfigDir,"auth.json")}getSyncPendingPath(e){return c.join(this.getGlobalProjectPath(e),"sync","pending.json")}getLastSyncPath(e){return c.join(this.getGlobalProjectPath(e),"sync","last-sync.json")}getRunningStatusPath(){return c.join(this.globalBaseDir,".running")}getDocsPath(){return c.join(this.globalBaseDir,"docs")}async getAgentDir(){return(await(z(),ue(ne)).getActiveProvider()).configDir}async getAgentSettingsPath(){let e=await(z(),ue(ne)).getActiveProvider();return(z(),ue(ne)).getGlobalSettingsPath(e.name)}getClaudeDir(){return c.join(we.homedir(),".claude")}getClaudeSettingsPath(){return c.join(this.getClaudeDir(),"settings.json")}getAgentsPath(e){return e?c.join(this.getGlobalProjectPath(e),"agents"):c.join(this.globalBaseDir,"agents")}getStoragePath(e,t){return c.join(this.getGlobalProjectPath(e),"storage",t)}getContextPath(e){return c.join(this.getGlobalProjectPath(e),"context")}async detectMonorepo(e){let t={isMonorepo:!1,type:null,rootPath:e,packages:[]},s=[{file:"pnpm-workspace.yaml",type:"pnpm"},{file:"lerna.json",type:"lerna"},{file:"nx.json",type:"nx"},{file:"rush.json",type:"rush"},{file:"turbo.json",type:"turborepo"}];for(let n of s){let i=c.join(e,n.file);if(await m(i)){t.isMonorepo=!0,t.type=n.type;break}}if(!t.isMonorepo){let n=c.join(e,"package.json");if(await m(n))try{let i=await D.readFile(n,"utf-8");JSON.parse(i).workspaces&&(t.isMonorepo=!0,t.type="npm")}catch{}}return t.isMonorepo&&(t.packages=await this.discoverMonorepoPackages(e,t.type)),t}async discoverMonorepoPackages(e,t){let s=[],n=[];try{if(t==="pnpm"){let a=(await D.readFile(c.join(e,"pnpm-workspace.yaml"),"utf-8")).match(/packages:\s*\n((?:\s*-\s*.+\n?)+)/);a&&(n=a[1].split(`
7
+ `).map(l=>l.replace(/^\s*-\s*['"]?|['"]?\s*$/g,"")).filter(Boolean))}else if(t==="npm"||t==="lerna"){let i=c.join(e,"package.json"),a=await D.readFile(i,"utf-8"),l=JSON.parse(a);if(Array.isArray(l.workspaces)?n=l.workspaces:l.workspaces?.packages&&(n=l.workspaces.packages),t==="lerna"){let g=c.join(e,"lerna.json");if(await m(g)){let N=await D.readFile(g,"utf-8"),S=JSON.parse(N);S.packages&&(n=S.packages)}}}else if(t==="nx")n=["apps/*","libs/*","packages/*"];else if(t==="turborepo"){let i=c.join(e,"package.json"),a=await D.readFile(i,"utf-8"),l=JSON.parse(a);Array.isArray(l.workspaces)&&(n=l.workspaces)}n.length===0&&(n=["packages/*","apps/*","libs/*"]);for(let i of n){if(i.startsWith("!"))continue;let a=Qt(i,{cwd:e,absolute:!1});for(let l of a){let g=c.join(e,l),N=c.join(g,"package.json");if(await m(N))try{let S=await D.readFile(N,"utf-8"),Y=JSON.parse(S),le=c.join(g,"PRJCT.md");s.push({name:Y.name||c.basename(l),path:g,relativePath:l,hasPrjctMd:await m(le)})}catch{}}}}catch{}return s}async findContainingPackage(e,t){if(!t.isMonorepo)return null;let s=c.resolve(e);for(let n of t.packages){let i=c.resolve(n.path);if(s.startsWith(i))return n}return null}async findMonorepoRoot(e){let t=c.resolve(e),s=c.parse(t).root;for(;t!==s;){if((await this.detectMonorepo(t)).isMonorepo)return t;t=c.dirname(t)}return null}},er=new Pe,et=er;function tr(){return typeof globalThis<"u"&&"Bun"in globalThis?"bun":"node"}o(tr,"detectRuntime");function tt(){return tr()==="bun"}o(tt,"isBun");function rr(r){if(tt()){let{Database:n}=Re("bun:sqlite");return new n(r,{create:!0})}let e=Re("better-sqlite3"),t=new e(r),s=t.exec.bind(t);return t.run=n=>s(n),t}o(rr,"openDatabase");var sr=[{version:1,name:"initial-schema",up:o(r=>{r.run(`
8
8
  -- =======================================================================
9
9
  -- Document storage (backward-compatible with JSON file pattern)
10
10
  -- =======================================================================
@@ -235,18 +235,18 @@ var W=Object.defineProperty;var mt=Object.getOwnPropertyDescriptor;var gt=Object
235
235
  CREATE INDEX idx_archives_entity_type ON archives(entity_type);
236
236
  CREATE INDEX idx_archives_archived_at ON archives(archived_at);
237
237
  CREATE INDEX idx_archives_entity_id ON archives(entity_id);
238
- `)},"up")}],ve=class{static{o(this,"PrjctDatabase")}connections=new Map;getDbPath(e){return et.join(Ze.getGlobalProjectPath(e),"prjct.db")}getDb(e){let t=this.connections.get(e);if(t)return t;let s=this.getDbPath(e),i=et.dirname(s);Se.existsSync(i)||Se.mkdirSync(i,{recursive:!0});let n=new Zt(s,{create:!0});return n.run("PRAGMA journal_mode = WAL"),n.run("PRAGMA synchronous = NORMAL"),n.run("PRAGMA cache_size = -2000"),n.run("PRAGMA temp_store = MEMORY"),n.run("PRAGMA mmap_size = 268435456"),this.runMigrations(n),this.connections.set(e,n),n}close(e){if(e){let t=this.connections.get(e);t&&(t.close(),this.connections.delete(e))}else this.connections.forEach(t=>{t.close()}),this.connections.clear()}exists(e){return Se.existsSync(this.getDbPath(e))}getDoc(e,t){let i=this.getDb(e).prepare("SELECT data FROM kv_store WHERE key = ?").get(t);return i?JSON.parse(i.data):null}setDoc(e,t,s){let i=this.getDb(e),n=JSON.stringify(s),a=new Date().toISOString();i.prepare("INSERT OR REPLACE INTO kv_store (key, data, updated_at) VALUES (?, ?, ?)").run(t,n,a)}deleteDoc(e,t){this.getDb(e).prepare("DELETE FROM kv_store WHERE key = ?").run(t)}hasDoc(e,t){return this.getDb(e).prepare("SELECT 1 FROM kv_store WHERE key = ?").get(t)!==null}appendEvent(e,t,s,i){let n=this.getDb(e),a=new Date().toISOString();n.prepare("INSERT INTO events (type, task_id, data, timestamp) VALUES (?, ?, ?, ?)").run(t,i??null,JSON.stringify(s),a)}getEvents(e,t,s=100){let i=this.getDb(e);return t?i.prepare("SELECT * FROM events WHERE type = ? ORDER BY id DESC LIMIT ?").all(t,s):i.prepare("SELECT * FROM events ORDER BY id DESC LIMIT ?").all(s)}query(e,t,...s){return this.getDb(e).prepare(t).all(...s)}run(e,t,...s){this.getDb(e).prepare(t).run(...s)}get(e,t,...s){return this.getDb(e).prepare(t).get(...s)??null}transaction(e,t){let s=this.getDb(e);return s.transaction(t)(s)}runMigrations(e){e.run(`
238
+ `)},"up")}],ve=class{static{o(this,"PrjctDatabase")}connections=new Map;getDbPath(e){return rt.join(et.getGlobalProjectPath(e),"prjct.db")}getDb(e){let t=this.connections.get(e);if(t)return t;let s=this.getDbPath(e),n=rt.dirname(s);Se.existsSync(n)||Se.mkdirSync(n,{recursive:!0});let i=rr(s);return i.run("PRAGMA journal_mode = WAL"),i.run("PRAGMA synchronous = NORMAL"),i.run("PRAGMA cache_size = -2000"),i.run("PRAGMA temp_store = MEMORY"),i.run("PRAGMA mmap_size = 268435456"),this.runMigrations(i),this.connections.set(e,i),i}close(e){if(e){let t=this.connections.get(e);t&&(t.close(),this.connections.delete(e))}else this.connections.forEach(t=>{t.close()}),this.connections.clear()}exists(e){return Se.existsSync(this.getDbPath(e))}getDoc(e,t){let n=this.getDb(e).prepare("SELECT data FROM kv_store WHERE key = ?").get(t);return n?JSON.parse(n.data):null}setDoc(e,t,s){let n=this.getDb(e),i=JSON.stringify(s),a=new Date().toISOString();n.prepare("INSERT OR REPLACE INTO kv_store (key, data, updated_at) VALUES (?, ?, ?)").run(t,i,a)}deleteDoc(e,t){this.getDb(e).prepare("DELETE FROM kv_store WHERE key = ?").run(t)}hasDoc(e,t){return this.getDb(e).prepare("SELECT 1 FROM kv_store WHERE key = ?").get(t)!==null}appendEvent(e,t,s,n){let i=this.getDb(e),a=new Date().toISOString();i.prepare("INSERT INTO events (type, task_id, data, timestamp) VALUES (?, ?, ?, ?)").run(t,n??null,JSON.stringify(s),a)}getEvents(e,t,s=100){let n=this.getDb(e);return t?n.prepare("SELECT * FROM events WHERE type = ? ORDER BY id DESC LIMIT ?").all(t,s):n.prepare("SELECT * FROM events ORDER BY id DESC LIMIT ?").all(s)}query(e,t,...s){return this.getDb(e).prepare(t).all(...s)}run(e,t,...s){this.getDb(e).prepare(t).run(...s)}get(e,t,...s){return this.getDb(e).prepare(t).get(...s)??null}transaction(e,t){let s=this.getDb(e);return s.transaction(t)(s)}runMigrations(e){e.run(`
239
239
  CREATE TABLE IF NOT EXISTS _migrations (
240
240
  version INTEGER PRIMARY KEY,
241
241
  name TEXT NOT NULL,
242
242
  applied_at TEXT NOT NULL
243
243
  )
244
- `);let t=new Set(e.prepare("SELECT version FROM _migrations").all().map(s=>s.version));for(let s of er)t.has(s.version)||e.transaction(()=>{s.up(e),e.prepare("INSERT INTO _migrations (version, name, applied_at) VALUES (?, ?, ?)").run(s.version,s.name,new Date().toISOString())})()}getMigrations(e){return this.getDb(e).prepare("SELECT * FROM _migrations ORDER BY version").all()}getSchemaVersion(e){return this.getDb(e).prepare("SELECT MAX(version) as version FROM _migrations").get()?.version??0}},ne=new ve;R();var tt=1800*1e3,oe=class{static{o(this,"LinearSync")}async pullAll(e){let t=new Date().toISOString(),s=[];try{let i=await p.fetchAssignedIssues({limit:100}),n={};for(let l of i)try{n[l.externalId]=this.toCachedIssue(l,t)}catch(m){s.push({issueId:l.externalId||l.id,error:w(m)})}let a={provider:"linear",lastSync:t,staleAfter:tt,issues:n};return ne.setDoc(e,"issues",a),{provider:"linear",fetched:i.length,updated:Object.keys(n).length,errors:s,timestamp:t}}catch(i){return s.push({issueId:"all",error:w(i)}),{provider:"linear",fetched:0,updated:0,errors:s,timestamp:t}}}async getIssue(e,t){let s=this.loadIssues(e);if(s?.issues[t]){let i=s.issues[t],n=new Date(i.fetchedAt).getTime(),a=Date.now(),l=600*1e3;if(a-n<l)return i}try{let i=await p.fetchIssue(t);if(!i)return null;let n=new Date().toISOString(),a=this.toCachedIssue(i,n);return this.updateIssueInCache(e,t,a),a}catch{return s?.issues[t]?s.issues[t]:null}}async getIssueLocal(e,t){return this.loadIssues(e)?.issues[t]||null}async pushStatus(e,t,s){s==="in_progress"?await p.markInProgress(t):s==="done"&&await p.markDone(t);let i=this.loadIssues(e);if(i?.issues[t]){let n=s==="done"?"done":"in_progress";i.issues[t].status=n,i.issues[t].fetchedAt=new Date().toISOString(),this.saveIssues(e,i)}}async isStale(e){let t=this.loadIssues(e);if(!t||!t.lastSync)return!0;let s=new Date(t.lastSync).getTime(),i=Date.now(),n=t.staleAfter||tt;return i-s>n}async getSyncStatus(e){let t=this.loadIssues(e);return t?{hasCache:!0,lastSync:t.lastSync||null,issueCount:Object.keys(t.issues).length,isStale:await this.isStale(e)}:{hasCache:!1,lastSync:null,issueCount:0,isStale:!0}}async listCachedIssues(e){let t=this.loadIssues(e);return t?Object.values(t.issues):[]}loadIssues(e){try{return ne.getDoc(e,"issues")}catch{return null}}saveIssues(e,t){ne.setDoc(e,"issues",t)}updateIssueInCache(e,t,s){let i=this.loadIssues(e);i||(i=je("linear")),i.issues[t]=s,this.saveIssues(e,i)}toCachedIssue(e,t){return{id:e.id,identifier:e.externalId,title:e.title,description:e.description,status:e.status,priority:e.priority,type:e.type,assignee:e.assignee,labels:e.labels,team:e.team,project:e.project,url:e.url,createdAt:e.createdAt,updatedAt:e.updatedAt,fetchedAt:t}}},J=new oe;R();import P from"chalk";z();import M from"chalk";var rt=["\u280B","\u2819","\u2839","\u2838","\u283C","\u2834","\u2826","\u2827","\u2807","\u280F"],tr=80,rr={name:"prjct",icon:"\u26A1",signature:"\u26A1 prjct",spinner:{frames:rt,speed:tr},cli:{header:o(()=>`${M.cyan.bold("\u26A1")} ${M.cyan("prjct")}`,"header"),footer:o(()=>M.dim("\u26A1 prjct"),"footer"),spin:o((r,e)=>`${M.cyan("\u26A1")} ${M.cyan("prjct")} ${M.cyan(rt[r%10])} ${M.dim(e||"")}`,"spin")},template:{header:"\u26A1 prjct",footer:"\u26A1 prjct"},commitFooter:"Generated with [p/](https://www.prjct.app/)",urls:{website:"https://prjct.app",docs:"https://prjct.app/docs"},getCommitFooter:o((r="claude")=>se(r).commitFooter,"getCommitFooter"),getSignature:o((r="claude")=>se(r).signature,"getSignature")},Ae=rr;var Ne={SPINNER_MSG:45,DONE_MSG:50,FAIL_MSG:65,WARN_MSG:65,STEP_MSG:35,PROGRESS_TEXT:25,ISSUE_TITLE:50,FALLBACK_TRUNCATE:50,CLEAR_WIDTH:80};var Vs=Ae.spinner.frames,qs=Ae.spinner.speed,ir={silent:{maxLines:0,maxCharsPerLine:0,showMetrics:!1},minimal:{maxLines:1,maxCharsPerLine:65,showMetrics:!1},compact:{maxLines:4,maxCharsPerLine:80,showMetrics:!0},verbose:{maxLines:1/0,maxCharsPerLine:1/0,showMetrics:!0}},Y="compact";function it(r){Y=r}o(it,"setOutputTier");function De(){return ir[Y]}o(De,"getTierConfig");var Qs={success:P.green("\u2713"),fail:P.red("\u2717"),warn:P.yellow("\u26A0"),info:P.blue("\u2139"),debug:P.dim("\u{1F527}"),bullet:P.dim("\u2022"),arrow:P.dim("\u2192"),check:P.green("\u2713"),cross:P.red("\u2717"),spinner:P.cyan("\u25D0")};var ae=o((r,e)=>{let t=e??(De().maxCharsPerLine||Ne.FALLBACK_TRUNCATE);return r&&r.length>t?`${r.slice(0,t-1)}\u2026`:r||""},"truncate");function xe(r,e){let t=e??De().maxLines;if(t===1/0||t===0)return r;let s=r.split(`
245
- `);if(s.length<=t)return r;let i=s.slice(0,t),n=s.length-t;return`${i.join(`
244
+ `);let t=new Set(e.prepare("SELECT version FROM _migrations").all().map(s=>s.version));for(let s of sr)t.has(s.version)||e.transaction(()=>{s.up(e),e.prepare("INSERT INTO _migrations (version, name, applied_at) VALUES (?, ?, ?)").run(s.version,s.name,new Date().toISOString())})()}getMigrations(e){return this.getDb(e).prepare("SELECT * FROM _migrations ORDER BY version").all()}getSchemaVersion(e){return this.getDb(e).prepare("SELECT MAX(version) as version FROM _migrations").get()?.version??0}},ie=new ve;R();var st=1800*1e3,oe=class{static{o(this,"LinearSync")}async pullAll(e){let t=new Date().toISOString(),s=[];try{let n=await p.fetchAssignedIssues({limit:100}),i={};for(let l of n)try{i[l.externalId]=this.toCachedIssue(l,t)}catch(g){s.push({issueId:l.externalId||l.id,error:w(g)})}let a={provider:"linear",lastSync:t,staleAfter:st,issues:i};return ie.setDoc(e,"issues",a),{provider:"linear",fetched:n.length,updated:Object.keys(i).length,errors:s,timestamp:t}}catch(n){return s.push({issueId:"all",error:w(n)}),{provider:"linear",fetched:0,updated:0,errors:s,timestamp:t}}}async getIssue(e,t){let s=this.loadIssues(e);if(s?.issues[t]){let n=s.issues[t],i=new Date(n.fetchedAt).getTime(),a=Date.now(),l=600*1e3;if(a-i<l)return n}try{let n=await p.fetchIssue(t);if(!n)return null;let i=new Date().toISOString(),a=this.toCachedIssue(n,i);return this.updateIssueInCache(e,t,a),a}catch{return s?.issues[t]?s.issues[t]:null}}async getIssueLocal(e,t){return this.loadIssues(e)?.issues[t]||null}async pushStatus(e,t,s){s==="in_progress"?await p.markInProgress(t):s==="done"&&await p.markDone(t);let n=this.loadIssues(e);if(n?.issues[t]){let i=s==="done"?"done":"in_progress";n.issues[t].status=i,n.issues[t].fetchedAt=new Date().toISOString(),this.saveIssues(e,n)}}async isStale(e){let t=this.loadIssues(e);if(!t||!t.lastSync)return!0;let s=new Date(t.lastSync).getTime(),n=Date.now(),i=t.staleAfter||st;return n-s>i}async getSyncStatus(e){let t=this.loadIssues(e);return t?{hasCache:!0,lastSync:t.lastSync||null,issueCount:Object.keys(t.issues).length,isStale:await this.isStale(e)}:{hasCache:!1,lastSync:null,issueCount:0,isStale:!0}}async listCachedIssues(e){let t=this.loadIssues(e);return t?Object.values(t.issues):[]}loadIssues(e){try{return ie.getDoc(e,"issues")}catch{return null}}saveIssues(e,t){ie.setDoc(e,"issues",t)}updateIssueInCache(e,t,s){let n=this.loadIssues(e);n||(n=Oe("linear")),n.issues[t]=s,this.saveIssues(e,n)}toCachedIssue(e,t){return{id:e.id,identifier:e.externalId,title:e.title,description:e.description,status:e.status,priority:e.priority,type:e.type,assignee:e.assignee,labels:e.labels,team:e.team,project:e.project,url:e.url,createdAt:e.createdAt,updatedAt:e.updatedAt,fetchedAt:t}}},q=new oe;R();import P from"chalk";z();import M from"chalk";var nt=["\u280B","\u2819","\u2839","\u2838","\u283C","\u2834","\u2826","\u2827","\u2807","\u280F"],nr=80,ir={name:"prjct",icon:"\u26A1",signature:"\u26A1 prjct",spinner:{frames:nt,speed:nr},cli:{header:o(()=>`${M.cyan.bold("\u26A1")} ${M.cyan("prjct")}`,"header"),footer:o(()=>M.dim("\u26A1 prjct"),"footer"),spin:o((r,e)=>`${M.cyan("\u26A1")} ${M.cyan("prjct")} ${M.cyan(nt[r%10])} ${M.dim(e||"")}`,"spin")},template:{header:"\u26A1 prjct",footer:"\u26A1 prjct"},commitFooter:"Generated with [p/](https://www.prjct.app/)",urls:{website:"https://prjct.app",docs:"https://prjct.app/docs"},getCommitFooter:o((r="claude")=>se(r).commitFooter,"getCommitFooter"),getSignature:o((r="claude")=>se(r).signature,"getSignature")},be=ir;var Ae={SPINNER_MSG:45,DONE_MSG:50,FAIL_MSG:65,WARN_MSG:65,STEP_MSG:35,PROGRESS_TEXT:25,ISSUE_TITLE:50,FALLBACK_TRUNCATE:50,CLEAR_WIDTH:80};var tn=be.spinner.frames,rn=be.spinner.speed,ar={silent:{maxLines:0,maxCharsPerLine:0,showMetrics:!1},minimal:{maxLines:1,maxCharsPerLine:65,showMetrics:!1},compact:{maxLines:4,maxCharsPerLine:80,showMetrics:!0},verbose:{maxLines:1/0,maxCharsPerLine:1/0,showMetrics:!0}},J="compact";function ot(r){J=r}o(ot,"setOutputTier");function De(){return ar[J]}o(De,"getTierConfig");var sn={success:P.green("\u2713"),fail:P.red("\u2717"),warn:P.yellow("\u26A0"),info:P.blue("\u2139"),debug:P.dim("\u{1F527}"),bullet:P.dim("\u2022"),arrow:P.dim("\u2192"),check:P.green("\u2713"),cross:P.red("\u2717"),spinner:P.cyan("\u25D0")};var ae=o((r,e)=>{let t=e??(De().maxCharsPerLine||Ae.FALLBACK_TRUNCATE);return r&&r.length>t?`${r.slice(0,t-1)}\u2026`:r||""},"truncate");function xe(r,e){let t=e??De().maxLines;if(t===1/0||t===0)return r;let s=r.split(`
245
+ `);if(s.length<=t)return r;let n=s.slice(0,t),i=s.length-t;return`${n.join(`
246
246
  `)}
247
- ${P.dim(`...${n} more lines`)}`}o(xe,"limitLines");function nt(r){let e=De();if(Y==="silent")return"";if(Y==="verbose")return JSON.stringify(r,null,2);if(typeof r!="object"||r===null)return ae(String(r),e.maxCharsPerLine);let t=r;if("identifier"in t&&"title"in t){let n=[];return n.push(`${t.identifier}: ${ae(String(t.title),e.maxCharsPerLine-10)}`),t.status&&n.push(`Status: ${t.status}`),t.priority&&t.priority!=="none"&&n.push(`Priority: ${t.priority}`),t.url&&Y==="compact"&&n.push(P.dim(String(t.url))),xe(n.join(`
248
- `),e.maxLines)}if("issues"in t&&Array.isArray(t.issues)){let n=t.issues,a=n.slice(0,e.maxLines).map(l=>{let m=l.priority&&l.priority!=="none"?` [${l.priority}]`:"";return`${l.identifier} ${ae(String(l.title),Ne.ISSUE_TITLE)}${m}`});return n.length>e.maxLines&&a.push(P.dim(`...${n.length-e.maxLines} more`)),a.join(`
249
- `)}let i=["id","name","title","status","message","success","error"].filter(n=>n in t);return i.length>0?xe(i.map(n=>`${n}: ${ae(String(t[n]),e.maxCharsPerLine-n.length-2)}`).join(`
250
- `),e.maxLines):xe(JSON.stringify(r,null,2),e.maxLines)}o(nt,"formatForHuman");R();te();Q();import Ce from"node:fs/promises";import nr from"node:os";import ot from"node:path";function at(r){return ot.join(nr.homedir(),".prjct-cli","projects",r,"config","credentials.json")}o(at,"getCredentialsPath");async function L(r){let e=at(r);if(!await g(e))return{};try{return JSON.parse(await Ce.readFile(e,"utf-8"))}catch(t){return console.error("[project-credentials] Failed to read credentials:",w(t)),{}}}o(L,"getProjectCredentials");async function ct(r,e){let t=at(r),s=ot.dirname(t);await g(s)||await Ce.mkdir(s,{recursive:!0});let i=await L(r);i.linear=e,await Ce.writeFile(t,JSON.stringify(i,null,2))}o(ct,"setLinearCredentials");async function be(r){let e=await L(r);return e.linear?.apiKey?e.linear.apiKey:U("linear-api-key")}o(be,"getLinearApiKey");async function lt(r){if((await L(r)).linear?.apiKey)return"project";let{getCredentialWithSource:t}=await Promise.resolve().then(()=>(Q(),ke)),s=await t("linear-api-key");return s.value?s.source==="keychain"?"keychain":"env":"none"}o(lt,"getCredentialSource");var b=process.argv.slice(2),ce=b.indexOf("--project"),h=null;ce!==-1&&b[ce+1]&&(h=b[ce+1],b.splice(ce,2));var dt=b.indexOf("--json"),_=dt!==-1;_&&b.splice(dt,1);var pt=b.indexOf("--verbose"),or=pt!==-1;or&&(b.splice(pt,1),it("verbose"));var[ut,...T]=b;function f(r){console.log(_?JSON.stringify(r,null,2):nt(r))}o(f,"output");function d(r,e=1){console.error(_?JSON.stringify({error:r}):`Error: ${r}`),process.exit(e)}o(d,"error");async function N(){h||d("No --project specified. Usage: linear.ts --project <projectId> <command>");let r=await be(h);r||d("Linear not configured. Run: p. linear setup");let e=await L(h);await p.initializeFromApiKey(r,e.linear?.teamId)}o(N,"initFromProject");async function ar(){try{switch(ut){case"setup":{h||d("--project required for setup");let r=T[0],e=T[1];r||d("API key required. Usage: setup <apiKey> [teamId]"),await p.initializeFromApiKey(r,e);let t=await p.getTeams();t.length===0&&d("No teams found. Check your API key permissions.");let s=e,i;if(!s&&t.length===1)s=t[0].id,i=t[0].key;else if(s){let n=t.find(a=>a.id===s||a.key===s);n&&(s=n.id,i=n.key)}await ct(h,{apiKey:r,teamId:s,teamKey:i,setupAt:new Date().toISOString()}),f({success:!0,teams:t,defaultTeam:s?{id:s,key:i}:null});break}case"list":{await N();let r=T[0]?parseInt(T[0],10):20,e=await L(h),t;e.linear?.teamId?t=await p.fetchTeamIssues(e.linear.teamId,{limit:r}):t=await p.fetchAssignedIssues({limit:r});let s=t.map(i=>({id:i.id,identifier:i.externalId,title:i.title,status:i.status,priority:i.priority,url:i.url}));if(_)f({count:t.length,issues:s});else{console.log(`Your issues (${t.length}):`);for(let i of s.slice(0,10)){let n=i.priority&&i.priority!=="none"?` [${i.priority}]`:"";console.log(` ${i.identifier} ${i.title.slice(0,50)}${n}`)}t.length>10&&console.log(` ...${t.length-10} more`)}break}case"list-team":{await N();let r=T[0],e=T[1]?parseInt(T[1],10):20;r||d("Team ID required. Usage: list-team <teamId> [limit]");let t=await p.fetchTeamIssues(r,{limit:e});f({count:t.length,issues:t.map(s=>({id:s.id,identifier:s.externalId,title:s.title,status:s.status,priority:s.priority,url:s.url}))});break}case"get":{await N();let r=T[0];r||d("Issue ID required. Usage: get <id>");let e=await p.fetchIssue(r);if(e||d(`Issue not found: ${r}`),_)f(e);else{if(console.log(`${e.externalId}: ${e.title}`),console.log(`Status: ${e.status} | Priority: ${e.priority||"none"}`),e.description){let t=e.description.slice(0,200);console.log(`
247
+ ${P.dim(`...${i} more lines`)}`}o(xe,"limitLines");function at(r){let e=De();if(J==="silent")return"";if(J==="verbose")return JSON.stringify(r,null,2);if(typeof r!="object"||r===null)return ae(String(r),e.maxCharsPerLine);let t=r;if("identifier"in t&&"title"in t){let i=[];return i.push(`${t.identifier}: ${ae(String(t.title),e.maxCharsPerLine-10)}`),t.status&&i.push(`Status: ${t.status}`),t.priority&&t.priority!=="none"&&i.push(`Priority: ${t.priority}`),t.url&&J==="compact"&&i.push(P.dim(String(t.url))),xe(i.join(`
248
+ `),e.maxLines)}if("issues"in t&&Array.isArray(t.issues)){let i=t.issues,a=i.slice(0,e.maxLines).map(l=>{let g=l.priority&&l.priority!=="none"?` [${l.priority}]`:"";return`${l.identifier} ${ae(String(l.title),Ae.ISSUE_TITLE)}${g}`});return i.length>e.maxLines&&a.push(P.dim(`...${i.length-e.maxLines} more`)),a.join(`
249
+ `)}let n=["id","name","title","status","message","success","error"].filter(i=>i in t);return n.length>0?xe(n.map(i=>`${i}: ${ae(String(t[i]),e.maxCharsPerLine-i.length-2)}`).join(`
250
+ `),e.maxLines):xe(JSON.stringify(r,null,2),e.maxLines)}o(at,"formatForHuman");R();te();Z();import Ne from"node:fs/promises";import cr from"node:os";import ct from"node:path";function lt(r){return ct.join(cr.homedir(),".prjct-cli","projects",r,"config","credentials.json")}o(lt,"getCredentialsPath");async function L(r){let e=lt(r);if(!await m(e))return{};try{return JSON.parse(await Ne.readFile(e,"utf-8"))}catch(t){return console.error("[project-credentials] Failed to read credentials:",w(t)),{}}}o(L,"getProjectCredentials");async function ut(r,e){let t=lt(r),s=ct.dirname(t);await m(s)||await Ne.mkdir(s,{recursive:!0});let n=await L(r);n.linear=e,await Ne.writeFile(t,JSON.stringify(n,null,2))}o(ut,"setLinearCredentials");async function Ce(r){let e=await L(r);return e.linear?.apiKey?e.linear.apiKey:U("linear-api-key")}o(Ce,"getLinearApiKey");async function dt(r){if((await L(r)).linear?.apiKey)return"project";let{getCredentialWithSource:t}=await Promise.resolve().then(()=>(Z(),Le)),s=await t("linear-api-key");return s.value?s.source==="keychain"?"keychain":"env":"none"}o(dt,"getCredentialSource");var C=process.argv.slice(2),ce=C.indexOf("--project"),h=null;ce!==-1&&C[ce+1]&&(h=C[ce+1],C.splice(ce,2));var gt=C.indexOf("--json"),_=gt!==-1;_&&C.splice(gt,1);var mt=C.indexOf("--verbose"),lr=mt!==-1;lr&&(C.splice(mt,1),ot("verbose"));var[pt,...T]=C;function f(r){console.log(_?JSON.stringify(r,null,2):at(r))}o(f,"output");function d(r,e=1){console.error(_?JSON.stringify({error:r}):`Error: ${r}`),process.exit(e)}o(d,"error");async function A(){h||d("No --project specified. Usage: linear.ts --project <projectId> <command>");let r=await Ce(h);r||d("Linear not configured. Run: p. linear setup");let e=await L(h);await p.initializeFromApiKey(r,e.linear?.teamId)}o(A,"initFromProject");async function ur(){try{switch(pt){case"setup":{h||d("--project required for setup");let r=T[0],e=T[1];r||d("API key required. Usage: setup <apiKey> [teamId]"),await p.initializeFromApiKey(r,e);let t=await p.getTeams();t.length===0&&d("No teams found. Check your API key permissions.");let s=e,n;if(!s&&t.length===1)s=t[0].id,n=t[0].key;else if(s){let i=t.find(a=>a.id===s||a.key===s);i&&(s=i.id,n=i.key)}await ut(h,{apiKey:r,teamId:s,teamKey:n,setupAt:new Date().toISOString()}),f({success:!0,teams:t,defaultTeam:s?{id:s,key:n}:null});break}case"list":{await A();let r=T[0]?parseInt(T[0],10):20,e=await L(h),t;e.linear?.teamId?t=await p.fetchTeamIssues(e.linear.teamId,{limit:r}):t=await p.fetchAssignedIssues({limit:r});let s=t.map(n=>({id:n.id,identifier:n.externalId,title:n.title,status:n.status,priority:n.priority,url:n.url}));if(_)f({count:t.length,issues:s});else{console.log(`Your issues (${t.length}):`);for(let n of s.slice(0,10)){let i=n.priority&&n.priority!=="none"?` [${n.priority}]`:"";console.log(` ${n.identifier} ${n.title.slice(0,50)}${i}`)}t.length>10&&console.log(` ...${t.length-10} more`)}break}case"list-team":{await A();let r=T[0],e=T[1]?parseInt(T[1],10):20;r||d("Team ID required. Usage: list-team <teamId> [limit]");let t=await p.fetchTeamIssues(r,{limit:e});f({count:t.length,issues:t.map(s=>({id:s.id,identifier:s.externalId,title:s.title,status:s.status,priority:s.priority,url:s.url}))});break}case"get":{await A();let r=T[0];r||d("Issue ID required. Usage: get <id>");let e=await p.fetchIssue(r);if(e||d(`Issue not found: ${r}`),_)f(e);else{if(console.log(`${e.externalId}: ${e.title}`),console.log(`Status: ${e.status} | Priority: ${e.priority||"none"}`),e.description){let t=e.description.slice(0,200);console.log(`
251
251
  ${t}${e.description.length>200?"...":""}`)}console.log(`
252
- ${e.url}`)}break}case"get-local":{h||d("--project required for get-local");let r=T[0];r||d("Issue ID required. Usage: get-local <id>");let e=await J.getIssueLocal(h,r);e||d(`Issue not in local cache: ${r}. Run 'sync' first.`),f(e);break}case"sync":{h||d("--project required for sync"),await N();let r=await J.pullAll(h);f({success:r.errors.length===0,...r});break}case"sync-status":{h||d("--project required for sync-status");let r=await J.getSyncStatus(h);f(r);break}case"create":{await N();let r=T[0];r||d(`JSON input required. Usage: create '{"title":"...", "teamId":"..."}'`);let e;try{e=JSON.parse(r)}catch{d(`Invalid JSON: ${r}`)}if(e.title||d("title is required"),!e.teamId){let s=await L(h);s.linear?.teamId?e.teamId=s.linear.teamId:d("teamId is required (no default team configured)")}let t=await p.createIssue(e);f(t);break}case"update":{await N();let r=T[0],e=T[1];r||d(`Issue ID required. Usage: update <id> '{"description":"..."}'`),e||d(`JSON input required. Usage: update <id> '{"description":"..."}'`);let t;try{t=JSON.parse(e)}catch{d(`Invalid JSON: ${e}`)}let s=await p.updateIssue(r,t);f(s);break}case"start":{await N();let r=T[0];r||d("Issue ID required. Usage: start <id>"),await p.markInProgress(r),f({success:!0,id:r,status:"in_progress"});break}case"done":{await N();let r=T[0];r||d("Issue ID required. Usage: done <id>"),await p.markDone(r),f({success:!0,id:r,status:"done"});break}case"comment":{await N();let r=T[0],e=T.slice(1).join(" ");r||d("Issue ID required. Usage: comment <id> <text>"),e||d("Comment text required. Usage: comment <id> <text>"),await p.addComment(r,e),f({success:!0,id:r});break}case"teams":{await N();let r=await p.getTeams();f({count:r.length,teams:r});break}case"projects":{await N();let r=await p.getProjects();f({count:r.length,projects:r});break}case"status":{h||d("--project required for status");let r=await lt(h),e=await be(h),t=await L(h);if(!e){_?f({configured:!1,source:"none",message:"Linear not configured"}):(console.log("Linear: Not configured"),console.log("Run: p. linear setup"));break}try{await p.initializeFromApiKey(e,t.linear?.teamId);let s=await p.getTeams();_?f({configured:!0,source:r,teamId:t.linear?.teamId,teamKey:t.linear?.teamKey,teamsAvailable:s.length}):(console.log("Linear: Connected"),t.linear?.teamKey&&console.log(`Team: ${t.linear.teamKey}`),console.log(`Teams: ${s.length} available`))}catch(s){_?f({configured:!0,source:r,connectionError:w(s)}):(console.log("Linear: Connection error"),console.log(`Error: ${w(s)}`))}break}case"help":case"--help":case"-h":case void 0:{f({usage:"linear.ts --project <projectId> <command> [args...]",commands:{setup:"setup <apiKey> [teamId] - Store API key",list:"list [limit] - List my assigned issues","list-team":"list-team <teamId> [limit] - List team issues",get:"get <id> - Get issue by ID or identifier","get-local":"get-local <id> - Get from local cache (no API)",sync:"sync - Pull all assigned issues to local storage","sync-status":"sync-status - Check local cache status",create:"create <json> - Create issue",update:"update <id> <json> - Update issue",start:"start <id> - Mark as in progress",done:"done <id> - Mark as done",comment:"comment <id> <text> - Add comment",teams:"teams - List available teams",projects:"projects - List available projects",status:"status - Check connection"}});break}default:d(`Unknown command: ${ut}. Use --help to see available commands.`)}}catch(r){d(w(r))}}o(ar,"main");ar();
252
+ ${e.url}`)}break}case"get-local":{h||d("--project required for get-local");let r=T[0];r||d("Issue ID required. Usage: get-local <id>");let e=await q.getIssueLocal(h,r);e||d(`Issue not in local cache: ${r}. Run 'sync' first.`),f(e);break}case"sync":{h||d("--project required for sync"),await A();let r=await q.pullAll(h);f({success:r.errors.length===0,...r});break}case"sync-status":{h||d("--project required for sync-status");let r=await q.getSyncStatus(h);f(r);break}case"create":{await A();let r=T[0];r||d(`JSON input required. Usage: create '{"title":"...", "teamId":"..."}'`);let e;try{e=JSON.parse(r)}catch{d(`Invalid JSON: ${r}`)}if(e.title||d("title is required"),!e.teamId){let s=await L(h);s.linear?.teamId?e.teamId=s.linear.teamId:d("teamId is required (no default team configured)")}let t=await p.createIssue(e);f(t);break}case"update":{await A();let r=T[0],e=T[1];r||d(`Issue ID required. Usage: update <id> '{"description":"..."}'`),e||d(`JSON input required. Usage: update <id> '{"description":"..."}'`);let t;try{t=JSON.parse(e)}catch{d(`Invalid JSON: ${e}`)}let s=await p.updateIssue(r,t);f(s);break}case"start":{await A();let r=T[0];r||d("Issue ID required. Usage: start <id>"),await p.markInProgress(r),f({success:!0,id:r,status:"in_progress"});break}case"done":{await A();let r=T[0];r||d("Issue ID required. Usage: done <id>"),await p.markDone(r),f({success:!0,id:r,status:"done"});break}case"comment":{await A();let r=T[0],e=T.slice(1).join(" ");r||d("Issue ID required. Usage: comment <id> <text>"),e||d("Comment text required. Usage: comment <id> <text>"),await p.addComment(r,e),f({success:!0,id:r});break}case"teams":{await A();let r=await p.getTeams();f({count:r.length,teams:r});break}case"projects":{await A();let r=await p.getProjects();f({count:r.length,projects:r});break}case"status":{h||d("--project required for status");let r=await dt(h),e=await Ce(h),t=await L(h);if(!e){_?f({configured:!1,source:"none",message:"Linear not configured"}):(console.log("Linear: Not configured"),console.log("Run: p. linear setup"));break}try{await p.initializeFromApiKey(e,t.linear?.teamId);let s=await p.getTeams();_?f({configured:!0,source:r,teamId:t.linear?.teamId,teamKey:t.linear?.teamKey,teamsAvailable:s.length}):(console.log("Linear: Connected"),t.linear?.teamKey&&console.log(`Team: ${t.linear.teamKey}`),console.log(`Teams: ${s.length} available`))}catch(s){_?f({configured:!0,source:r,connectionError:w(s)}):(console.log("Linear: Connection error"),console.log(`Error: ${w(s)}`))}break}case"help":case"--help":case"-h":case void 0:{f({usage:"linear.ts --project <projectId> <command> [args...]",commands:{setup:"setup <apiKey> [teamId] - Store API key",list:"list [limit] - List my assigned issues","list-team":"list-team <teamId> [limit] - List team issues",get:"get <id> - Get issue by ID or identifier","get-local":"get-local <id> - Get from local cache (no API)",sync:"sync - Pull all assigned issues to local storage","sync-status":"sync-status - Check local cache status",create:"create <json> - Create issue",update:"update <id> <json> - Update issue",start:"start <id> - Mark as in progress",done:"done <id> - Mark as done",comment:"comment <id> <text> - Add comment",teams:"teams - List available teams",projects:"projects - List available projects",status:"status - Check connection"}});break}default:d(`Unknown command: ${pt}. Use --help to see available commands.`)}}catch(r){d(w(r))}}o(ur,"main");ur();