prjct-cli 1.28.0 → 1.29.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +17 -0
- package/dist/bin/prjct-core.mjs +309 -296
- package/dist/cli/linear.mjs +4 -2
- package/dist/daemon/entry.mjs +207 -193
- package/dist/templates.json +1 -1
- package/package.json +1 -1
package/dist/cli/linear.mjs
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import { createRequire as __createRequire } from 'module';
|
|
2
3
|
import { fileURLToPath as __fileURLToPath } from 'url';
|
|
3
4
|
import { dirname as __pathDirname } from 'path';
|
|
4
|
-
|
|
5
|
-
|
|
5
|
+
var require = __createRequire(import.meta.url);
|
|
6
|
+
var __filename = __fileURLToPath(import.meta.url);
|
|
7
|
+
var __dirname = __pathDirname(__filename);
|
|
6
8
|
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
9
|
`).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
10
|
-- =======================================================================
|