@pathrule/cli 0.0.14 → 0.0.15
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/README.md +4 -12
- package/dist/index.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -104,11 +104,10 @@ pathrule doctor
|
|
|
104
104
|
|
|
105
105
|
Notes:
|
|
106
106
|
|
|
107
|
-
- Windows autostart for the bridge daemon is
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
no-op from a real failure.
|
|
107
|
+
- Windows autostart for the bridge daemon is not yet wired up. Start
|
|
108
|
+
it manually with `pathrule daemon start`. `pathrule daemon status
|
|
109
|
+
--json` reports `supported: false, method: "task-scheduler"` so
|
|
110
|
+
scripts can distinguish a planned no-op from a real failure.
|
|
112
111
|
- The CLI writes a `pathrule-hook.cmd` shim next to `pathrule-hook.js`
|
|
113
112
|
inside `%USERPROFILE%\.pathrule\bin\`. AI clients that spawn hooks
|
|
114
113
|
without a shell (Codex on Windows) execute the `.cmd` directly.
|
|
@@ -163,11 +162,4 @@ repository:
|
|
|
163
162
|
- The local bridge binds to loopback and is intended for local browser and CLI
|
|
164
163
|
workflows only.
|
|
165
164
|
|
|
166
|
-
## Troubleshooting and Release Operations
|
|
167
|
-
|
|
168
|
-
- Cross-platform troubleshooting:
|
|
169
|
-
[docs/cli/troubleshooting.md](../../docs/cli/troubleshooting.md)
|
|
170
|
-
- Release operator checklist (canary → promote → rollback):
|
|
171
|
-
[docs/cli/release-checklist.md](../../docs/cli/release-checklist.md)
|
|
172
|
-
|
|
173
165
|
For more details, visit [pathrule.io](https://pathrule.io).
|
package/dist/index.js
CHANGED
|
@@ -2738,7 +2738,7 @@ switch (eventName) {
|
|
|
2738
2738
|
}
|
|
2739
2739
|
`,wX=`@echo off
|
|
2740
2740
|
node "%~dp0pathrule-hook.js" %*
|
|
2741
|
-
`;});async function Kt(t,e){let{supabase:r}=await U(e),n=await Ie(e),o=(e.PATHRULE_WEB_URL??"https://app.pathrule.io").replace(/\/$/,"");if(!n)return Qi(t,"org_required",{web_url:`${o}/settings`,suggested_command_after_resolution:"pathrule org use <slug-or-id>"});let{data:s,error:i}=await r.from("organizations").select("id, slug, plan, seat_count, subscription_status").eq("id",n.id).single();if(i)throw i;let a=String(s.plan??n.plan),c=n.role,l=`${o}/org/${n.slug}/billing`;if(t==="create_workspace"){if(!CX(c))return Qi(t,"permission_denied",{role:c,plan:a,organization_id:n.id,web_url:`${o}/org/${n.slug}/settings/members`});let f=await qv(r,"workspaces","organization_id",n.id,{archived_at:null}),p=Wv(a,"workspaces");return zD(f,p)?Qi(t,"capacity_full",{role:c,plan:a,organization_id:n.id,usage:{dimension:"workspaces",used:f,limit:p},web_url:l,suggested_command_after_resolution:"pathrule init"}):LD(t,{role:c,plan:a,organization_id:n.id})}let u=await xe(e);if(!u)return Qi(t,"workspace_required",{role:c,plan:a,organization_id:n.id,web_url:`${o}/org/${n.slug}`,suggested_command_after_resolution:"pathrule workspace use <name-or-id>"});if(kX.has(t)&&!EX(c))return Qi(t,"permission_denied",{role:c,plan:a,organization_id:n.id,workspace_id:u.id,web_url:`${o}/org/${n.slug}/settings/members`});let d=await xX(t,a,u.id,r);return d&&zD(d.used,d.limit)?Qi(t,"capacity_full",{role:c,plan:a,organization_id:n.id,workspace_id:u.id,usage:d,web_url:l,suggested_command_after_resolution:"pathrule status"}):LD(t,{role:c,plan:a,organization_id:n.id,workspace_id:u.id,usage:d})}function Hv(t){return ["create_workspace","write_memory","write_rule","write_skill","sync_agents","materialize_skills"].includes(t)}function ea(t){return t.allowed?{summary:`${t.action} is allowed.`,details:[],url:null,suggested_command_after_resolution:null}:t.blocking_reason==="capacity_full"&&t.usage?{summary:`${vX(t.usage.dimension)} limit reached on the ${t.plan??"current"} plan (${t.usage.used} / ${SX(t.usage.limit)}).`,details:["Open Pathrule Web to upgrade or clean up usage."],url:t.web_url,suggested_command_after_resolution:t.suggested_command_after_resolution}:t.blocking_reason==="permission_denied"?{summary:`Your current role (${t.role??"unknown"}) cannot run ${t.action}.`,details:["Ask an organization admin to update your role or run the action from an admin account."],url:t.web_url,suggested_command_after_resolution:t.suggested_command_after_resolution}:t.blocking_reason==="workspace_required"?{summary:"No current workspace is selected for this folder.",details:["Run setup or choose a workspace before retrying."],url:t.web_url,suggested_command_after_resolution:t.suggested_command_after_resolution??"pathrule setup --json"}:t.blocking_reason==="org_required"?{summary:"No organization is selected.",details:["Choose an organization before retrying."],url:t.web_url,suggested_command_after_resolution:t.suggested_command_after_resolution??"pathrule org use <slug-or-id>"}:{summary:`${t.action} blocked: ${t.blocking_reason??"preflight_blocked"}.`,details:[],url:t.web_url,suggested_command_after_resolution:t.suggested_command_after_resolution}}function vX(t){return t.charAt(0).toLocaleUpperCase("en-US")+t.slice(1)}function SX(t){return t===-1?"unlimited":String(t)}async function xX(t,e,r,n){return t==="write_memory"?{dimension:"memories",used:await qv(n,"memories","workspace_id",r),limit:Wv(e,"memories")}:t==="write_rule"?{dimension:"rules",used:await qv(n,"rules","workspace_id",r),limit:Wv(e,"rules")}:null}async function qv(t,e,r,n,o={}){let s=t.from(e).select("id",{count:"exact",head:true}).eq(r,n);for(let c of Object.keys(o))s=s.is(c,null);let{count:i,error:a}=await s;if(a)throw a;return i??0}function CX(t){return t==="owner"||t==="admin"||t==="member"}function EX(t){return t==="owner"||t==="admin"||t==="member"}function Wv(t,e){return no[t]?.[e]??no.free[e]}function zD(t,e){return e!==-1&&t>=e}function LD(t,e={}){return {action:t,allowed:true,blocking_reason:null,role:null,plan:null,organization_id:null,workspace_id:null,usage:null,web_url:null,suggested_command_after_resolution:null,...e}}function Qi(t,e,r={}){return {action:t,allowed:false,blocking_reason:e,role:null,plan:null,organization_id:null,workspace_id:null,usage:null,web_url:null,suggested_command_after_resolution:null,...r}}var kX,jf=m(()=>{de();Ve();Yr();zt();kX=new Set(["write_memory","write_rule","write_skill","sync_agents","materialize_skills"]);});async function Cn(t,e,r={}){let{session:n,supabase:o}=await U(t),s=await xe(t);if(!s)throw new Error("workspace_required");if(!s.local_root_path)throw new Error("workspace_not_attached");if(s.local_root_path!==e)throw new Error("workspace_cwd_mismatch");await jD(t);let i=await Kt(r.skillsOnly?"materialize_skills":"sync_agents",t);if(!i.allowed)return {ok:false,workspace_id:s.id,workspace_root:s.local_root_path,preflight:i,error:i.blocking_reason??"preflight_blocked"};if(r.skillsOnly){let u=await jX({supabase:o,userId:n.user.id,workspaceId:s.id,workspaceRoot:s.local_root_path});return {ok:u.errors.length===0,workspace_id:s.id,workspace_root:s.local_root_path,preflight:i,skills:{ok:u.errors.length===0,enabled:u.enabled,written:u.written,skipped:u.skipped,removed:u.removed,errors:u.errors},error:u.errors.length===0?void 0:"skill_sync_failed"}}let a=await cf({supabase:o,userId:n.user.id,workspaceId:s.id,workspaceRoot:s.local_root_path,runtimeOwner:BD,runtimeVersion:qD}),c=await MX({supabase:o,userId:n.user.id,workspaceId:s.id,workspaceRoot:s.local_root_path}),l=await Mf({supabase:o,workspaceId:s.id,workspaceRoot:s.local_root_path,env:t});return {ok:a.ok&&c.errors.length===0&&l.ok,workspace_id:s.id,workspace_root:s.local_root_path,preflight:i,companion:{ok:a.ok,enabled:a.enabled,written:a.disk.written,skipped:a.disk.skipped,removed:a.disk.removed,errors:a.disk.errors,error:a.error},claude:{ok:c.errors.length===0,written:c.written,skipped:c.skipped,backed_up:c.backedUp,errors:c.errors,snapshot_changed:c.snapshotChanged},hook_index:l,error:a.error??(c.errors.length>0?"claude_sync_failed":l.ok?void 0:"hook_index_sync_failed")}}async function Ol(t,e,r,n={}){let{session:o}=await U(t),s=await Zt(o.user.id,t);await yf(o.user.id,{...s,current_workspace_id:e,schema_version:1},t);try{return await Cn(t,r,n)}finally{await yf(o.user.id,s,t);}}async function MX(t){let e={written:0,skipped:0,backedUp:[],errors:[],snapshotChanged:false},r=new Set,{body:n,snapshotChanged:o}=await cp({supabase:t.supabase,workspaceId:t.workspaceId,userId:t.userId});e.snapshotChanged=o,await UD(e,t.workspaceRoot,"CLAUDE.md",n)&&r.add("CLAUDE.md"),await UD(e,t.workspaceRoot,".claude/rules/pathrule-protocol.md",up())&&r.add(".claude/rules/pathrule-protocol.md");let s=".claude/settings.json";try{let i=join(t.workspaceRoot,s),a=await HD(i),{body:c,changed:l}=xi(a);l?(await WD(i,c),e.written+=1):e.skipped+=1,r.add(s);}catch(i){e.errors.push({path:s,message:i instanceof Error?i.message:String(i)});}try{await sf({workspaceRoot:t.workspaceRoot,paths:Array.from(r),owner:BD,ownerVersion:qD});}catch(i){e.errors.push({path:".pathrule/managed-files.json",message:i instanceof Error?i.message:String(i)});}return e}async function UD(t,e,r,n){let o=join(e,r);try{let s=await HD(o),i=await nf({workspaceRoot:e,relativePath:r,renderedBody:n,existingBody:s});return i.backupPath&&t.backedUp.push(i.backupPath),i.finalBody===null?(t.skipped+=1,!0):(await WD(o,i.finalBody),t.written+=1,!0)}catch(s){return t.errors.push({path:r,message:s instanceof Error?s.message:String(s)}),false}}async function WD(t,e){await mkdir(dirname(t),{recursive:true});let r=`${t}.tmp`;await writeFile(r,e,"utf8"),await rename(r,t);}async function HD(t){try{return await readFile(t,"utf8")}catch(e){if(e.code==="ENOENT")return null;throw e}}async function jX(t){let[e,r]=await Promise.all([DX(t.supabase,t.userId,t.workspaceId,t.workspaceRoot),zX(t.supabase,t.workspaceId)]),n=await rf({workspaceRoot:t.workspaceRoot,activeTargets:e,skills:r});return {enabled:e,written:n.written,skipped:n.skipped,removed:n.removed,errors:n.errors}}async function DX(t,e,r,n){let[{data:o},s]=await Promise.all([t.from("user_workspace_paths").select("selected_ai_clients").eq("workspace_id",r).eq("user_id",e).maybeSingle(),Kr(n)]),i=o?.selected_ai_clients??null;return Hi({selected:i,detected:s,fallback:Ci})}async function zX(t,e){let{data:r,error:n}=await t.from("skills").select("id, name, description, content, source, github_url, content_fetched_at, updated_at, skill_files(path, content, sha256)").eq("workspace_id",e);if(n)throw new Error(`skill_catalogue_read_failed: ${n.message}`);return (r??[]).map(o=>({id:o.id,name:o.name,description:o.description,content:o.content,source:o.source,githubUrl:o.github_url,contentFetchedAt:o.content_fetched_at,updatedAt:o.updated_at,files:(o.skill_files??[]).map(s=>({path:s.path,content:s.content,sha256:s.sha256}))}))}var OX,NX,BD,qD,ta=m(()=>{uo();af();de();Tk();Ek();ot();ro();Zi();xk();Ve();DD();Lv();jf();zt();OX=createRequire(import.meta.url),NX=OX("../package.json"),BD="cli",qD=NX.version;});async function KX(t){let e=fr(t),r=Fv(t);return Promise.all(JX.map(async n=>{let o=Sn(n),s=o.homeConfigPath(homedir(),e),i;try{i=await readFile(s,"utf8");}catch(a){return a.code==="ENOENT"?{client:n,config_path:s,code:"config_missing"}:{client:n,config_path:s,code:"rewrite_failed",detail:a instanceof Error?a.message:String(a)}}try{let a=o.getManagedEntry(i);if(!a.present||!a.staleReason)return {client:n,config_path:s,code:"no_change"};let c=o.inject(i,r);return await GX(s,c.body),{client:n,config_path:s,code:"stale_mcp_entry_rewritten",detail:a.staleReason}}catch(a){return {client:n,config_path:s,code:"rewrite_failed",detail:a instanceof Error?a.message:String(a)}}}))}async function GX(t,e){await mkdir(dirname(t),{recursive:true});let r=`${t}.tmp`;await writeFile(r,e,"utf8"),await rename(r,t);}async function Nl(t,e){let r=await xn(t,e),n=await KX(t);try{let o=await Cn(t,e),s=await xn(t,e);return {ok:o.ok&&s.ok,doctor_before:r,sync:o,doctor_after:s,mcp_rewrites:n,error:o.ok&&s.ok?void 0:o.error??"repair_incomplete"}}catch(o){return {ok:false,doctor_before:r,mcp_rewrites:n,error:o instanceof Error?o.message:String(o)}}}function VD(t){let e=ZD(t.doctor_before.checks),r=t.doctor_after??t.doctor_before,n=ZD(r.checks),o=t.sync?.preflight,s=r.mcp.filter(f=>!f.installed),i=QX(e,n),a=eQ(e,n),c=tQ(r.mcp),l=rQ(t),u=nQ(t),d=oQ(o);return {ok:t.ok,headline:t.ok?"Local runtime repaired":"Repair incomplete",next_command:sQ(t,n,s.length),sections:[i,a,c,l,u,d]}}async function Zv(t,e={}){let{session:r,supabase:n}=await U(t),{data:o,error:s}=await n.from("user_security_state").select("security_epoch").eq("user_id",r.user.id).maybeSingle();if(s)throw s;let i=typeof o?.security_epoch=="number"?o.security_epoch:0,a=ts(r.user.id,i,t),c=[];for(let l=0;l<i;l+=1){let u=join(a.userCacheDir,`epoch-${l}`),d=await XX(u);if(d===0)continue;let f=e.dryRun!==false?false:await YX(u);c.push({path:u,epoch:l,removed:f,bytes:d});}return {ok:true,dry_run:e.dryRun!==false,current_epoch:i,candidates:c,reclaimed_bytes:c.filter(l=>l.removed).reduce((l,u)=>l+u.bytes,0)}}async function YX(t){return await rm$1(t,{recursive:true,force:true}),true}async function XX(t){try{let e=await stat(t);return e.isFile()?e.size:e.isDirectory()?1:0}catch{return 0}}function ZD(t){return new Map(t.map(e=>[e.name,e]))}function QX(t,e){let r=t.get("auth"),n=e.get("auth"),o=t.get("organization"),s=e.get("organization"),i=[Df(r,n,{pass:(a,c)=>c?`Signed in again as ${a??"the current account"}.`:`Signed in as ${a??"the current account"}.`,warn:a=>`Authentication still needs attention${a?`: ${a}`:""}.`,fail:a=>`Authentication is still blocked${a?`: ${a}`:""}.`}),Df(o,s,{pass:(a,c)=>c?`Organization context restored: ${a??"selected"}.`:`Organization context: ${a??"selected"}.`,warn:a=>`Organization selection is still missing${a&&a!=="no organization selected"?`: ${a}`:""}.`,fail:a=>`Organization lookup failed${a?`: ${a}`:""}.`})];return {title:"Account",status:JD(n?.status,s?.status),lines:i}}function eQ(t,e){let r=t.get("workspace"),n=e.get("workspace"),o=t.get("cwd_attach"),s=e.get("cwd_attach"),i=[Df(r,n,{pass:(a,c)=>c?`Workspace selection recovered: ${a??"current workspace"}.`:`Workspace selection: ${a??"current workspace"}.`,warn:a=>`Workspace selection is still incomplete${a&&a!=="no workspace selected"?`: ${a}`:""}.`,fail:a=>`Workspace lookup failed${a?`: ${a}`:""}.`}),Df(o,s,{pass:(a,c)=>c?"Current folder is attached again.":"Current folder is attached.",warn:a=>a==="workspace not attached"?"Current folder is still not attached.":`Current folder still points to ${a??"another workspace root"}.`,fail:a=>`Current folder attachment check failed${a?`: ${a}`:""}.`})];return {title:"Workspace",status:JD(n?.status,s?.status),lines:i}}function tQ(t){let e=t.filter(s=>s.installed).length,r=t.filter(s=>!s.installed).map(s=>s.client),n=t.filter(s=>s.error).map(s=>`${s.client}: ${s.error}`),o=[`MCP configs ready for ${e}/${t.length} supported clients.`,r.length>0?`Still missing: ${r.join(", ")}.`:"All supported MCP client configs are present."];return n.length>0&&o.push(`Agent config read errors: ${n.join("; ")}.`),{title:"Agents",status:n.length>0?"fail":r.length>0?"warn":"pass",lines:o}}function rQ(t){let e=t.sync?.hook_index;return t.sync?e?{title:"Hooks",status:e.ok?"pass":"fail",lines:[e.ok?`Hook index refreshed${e.schema_version?` (schema ${e.schema_version})`:""}.`:`Hook index refresh failed: ${e.error??"unknown error"}.`,e.refreshed_episodes?"Hook work episodes were refreshed before rebuilding the index.":"Hook work episodes were left unchanged."]}:{title:"Hooks",status:"warn",lines:["Repair did not produce a hook index update."]}:{title:"Hooks",status:"warn",lines:["Repair stopped before hook files could be refreshed."]}}function nQ(t){if(!t.sync)return {title:"Files",status:"warn",lines:["Repair stopped before local files could be rewritten."]};let e=[],r="pass";return t.sync.companion&&(e.push(`Companion files: ${t.sync.companion.written} written, ${t.sync.companion.skipped} unchanged, ${t.sync.companion.removed} removed.`),(t.sync.companion.errors.length>0||!t.sync.companion.ok)&&(r="fail",e.push(`Companion errors: ${t.sync.companion.errors.map(n=>n.message).join("; ")||t.sync.companion.error||"unknown error"}.`))),t.sync.claude&&(e.push(`Claude files: ${t.sync.claude.written} written, ${t.sync.claude.skipped} unchanged, ${t.sync.claude.backed_up.length} backed up.`),t.sync.claude.errors.length>0&&(r="fail",e.push(`Claude sync errors: ${t.sync.claude.errors.map(n=>n.message).join("; ")}.`))),t.sync.skills&&(e.push(`Skills: ${t.sync.skills.written} written, ${t.sync.skills.skipped} unchanged, ${t.sync.skills.removed} removed.`),t.sync.skills.errors.length>0&&(r="fail",e.push(`Skill materialization errors: ${t.sync.skills.errors.map(n=>n.message).join("; ")}.`))),e.length===0&&e.push("No local file rewrites were needed."),{title:"Files",status:r,lines:e}}function oQ(t){return t?t.allowed?{title:"Capacity",status:"pass",lines:["No plan limit blocked this repair."]}:t.blocking_reason==="capacity_full"&&t.usage?{title:"Capacity",status:"fail",lines:[`${iQ(t.usage.dimension)} limit reached (${t.usage.used} / ${aQ(t.usage.limit)}).`,"Open billing or clean up usage before retrying the repair."]}:{title:"Capacity",status:"warn",lines:["Capacity is not the blocking issue for this repair."]}:{title:"Capacity",status:"warn",lines:["Capacity checks did not run because repair stopped early."]}}function Df(t,e,r){let n=e??t;if(!n)return "No status available.";let o=t!=null&&t.status!=="pass"&&n.status==="pass";return n.status==="pass"?r.pass(n.detail,o):n.status==="warn"?r.warn(n.detail,o):r.fail(n.detail,o)}function JD(...t){return t.includes("fail")?"fail":t.includes("warn")?"warn":"pass"}function sQ(t,e,r){if(e.get("auth")?.status!=="pass")return "pathrule login";if(e.get("organization")?.status!=="pass")return "pathrule org use <slug-or-id>";if(e.get("workspace")?.status!=="pass")return "pathrule workspace use <name-or-id>";if(e.get("cwd_attach")?.status!=="pass")return "pathrule attach <workspace>";let a=t.sync?.preflight;if(a&&!a.allowed&&a.suggested_command_after_resolution)return a.suggested_command_after_resolution;if(r>0)return "pathrule install";let c=!t.sync?.companion?.ok||!!t.sync?.companion?.errors.length||!!t.sync?.claude?.errors.length||!!t.sync?.skills?.errors.length||t.sync?.hook_index?.ok===false;return !t.ok||c?"pathrule sync":"pathrule doctor"}function iQ(t){return t.charAt(0).toLocaleUpperCase("en-US")+t.slice(1)}function aQ(t){return t===-1?"unlimited":String(t)}var JX,Vv=m(()=>{ot();$l();Ve();Nf();Al();Xi();ta();JX=["claude-code","cursor","codex","windsurf"];});async function Ps(t,e,r,n){let{session:o,supabase:s}=await U(t);if(o.user.id!==e)throw new Error("session_user_mismatch");let[{data:i},a]=await Promise.all([s.from("user_workspace_paths").select("selected_ai_clients").eq("user_id",e).eq("workspace_id",r).maybeSingle(),n?Kr(n):Promise.resolve([])]),c=new Set(i?.selected_ai_clients??[]),l=new Set(a),u=Object.keys(Fe);return Promise.all(u.map(async d=>{let f=await hQ(d);return {client:d,active:c.has(d)||l.has(d),selected:c.has(d),markers:l.has(d)?["workspace_marker_detected"]:[],machineInstalled:f.installed,machineConfigPath:f.configPath,machineConfigExists:f.configExists}}))}async function XD(t,e,r,n,o,s,i="restore-backup"){let a=mQ(o),{session:c,supabase:l}=await U(t);if(c.user.id!==e)throw new Error("session_user_mismatch");let{data:u,error:d}=await l.from("user_workspace_paths").select("selected_ai_clients").eq("user_id",e).eq("workspace_id",r).eq("local_root_path",n).maybeSingle();if(d)throw new Error(`workspace_client_selection_read_failed: ${d.message}`);if(!u)throw new Error("workspace_root_not_attached");let f=[],p=new Set((u.selected_ai_clients??[]).filter(QD)),h=Array.from(p);s?p.add(a):p.delete(a);let g=Array.from(p);if(!gQ(h,g)){let{error:y}=await l.from("user_workspace_paths").update({selected_ai_clients:g}).eq("user_id",e).eq("workspace_id",r).eq("local_root_path",n);if(y)throw new Error(`workspace_client_selection_update_failed: ${y.message}`)}if(s){let y=await ho(a,t);for(let k of y)k.ok||f.push(`${k.client}: ${k.error??k.status}`);}else await GD(n,a);let _=await Ol(t,r,n);return _.ok||f.push(_.error??"workspace_sync_failed"),s||await GD(n,a),{ok:true,statuses:await Ps(t,e,r,n),warnings:f}}async function hQ(t,e=process.env){let r=Sn(t),n=r.homeConfigPath(homedir(),fr(e));try{let o=await readFile(n,"utf8");return {configPath:n,configExists:!0,installed:r.read(o)!==null}}catch(o){return o.code!=="ENOENT"?{configPath:n,configExists:false,installed:false}:{configPath:n,configExists:false,installed:false}}}function mQ(t){if(QD(t))return t;throw new Error("invalid_agent_target")}function QD(t){return yb(t)!==null}function gQ(t,e){if(t.length!==e.length)return false;let r=new Set(t);return e.every(n=>r.has(n))}async function GD(t,e,r){let n=Fe[e]?.skillsDir;if(!n)return;let o=join(t,n);await rm$1(o,{recursive:true,force:true}),await _Q(dirname(o),t);}async function _Q(t,e){let r=resolve(e),n=resolve(t);for(;n!==r&&n.startsWith(`${r}${sep}`);){try{await rmdir(n);}catch{return}n=dirname(n);}}var Jv=m(()=>{$l();ro();Zi();Ve();Al();Xi();ta();});function Kv(t){if(t.startsWith("/")||/^[A-Za-z]:[\\/]/.test(t))return null;let e=t.replace(/\\/g,"/").replace(/\/+/g,"/");return e.length===0||e==="."||e.startsWith("../")||e.includes("/../")||e.startsWith(".git/")||/[\x00-\x1F]/.test(e)?null:e}function vQ(t){let r=(Buffer.isBuffer(t)?t.toString("utf8"):t).split("\0").filter(o=>o.length>0),n=[];for(let o=0;o<r.length;o+=1){let s=r[o];if(!s||s.length<4)continue;let i=s.slice(0,2),a=s.slice(3),c=SQ(i);if(i.includes("R")||i.includes("C")){let u=Kv(a);u&&n.push({relativePath:u,gitStatus:"renamed"});let d=Kv(r[o+1]??"");d&&n.push({relativePath:d,gitStatus:"renamed"}),o+=1;continue}let l=Kv(a);l&&n.push({relativePath:l,gitStatus:c});}return xQ(n)}async function ez(t,e={}){try{let{stdout:r}=await bQ("git",["status","--porcelain=v1","-z"],{cwd:t,encoding:"buffer",maxBuffer:5242880,timeout:e.timeoutMs??kQ});return {entries:vQ(r),degraded:!1}}catch{return {entries:[],degraded:true}}}function SQ(t){return t==="??"?"untracked":t.includes("A")?"added":t.includes("D")?"deleted":t.includes("R")||t.includes("C")?"renamed":t.includes("M")||t.includes("T")||t.includes("U")?"modified":"unknown"}function xQ(t){let e=new Map;for(let r of t)e.set(r.relativePath,r);return Array.from(e.values()).sort((r,n)=>r.relativePath.localeCompare(n.relativePath))}var bQ,kQ,tz=m(()=>{bQ=promisify(execFile),kQ=2e3;});async function Gv(t,e=process.env){let r=await Zt(t,e);if(r.work_state_runtime_id)return r.work_state_runtime_id;let n=`runtime:${randomUUID()}`;return await Vt(t,{work_state_runtime_id:n},e),n}function RQ(t){return t.length>0&&!t.startsWith("/")&&!t.startsWith("../")&&!t.includes("/../")&&!t.startsWith(".git/")&&!/[\x00-\x1F]/.test(t)}var EQ,PQ,zf,Ml,rz=m(()=>{uo();tz();EQ=800,PQ=6e4,zf=500,Ml=class{constructor(e){this.options=e;}options;dirty=new Map;pendingTimer=null;intervalTimer=null;stopped=false;degraded=false;lastScanAt=null;start(){this.intervalTimer||(this.reconcile(),this.intervalTimer=setInterval(()=>{this.reconcile();},this.options.scanIntervalMs??PQ),this.intervalTimer.unref?.());}stop(){this.stopped=true,this.pendingTimer&&clearTimeout(this.pendingTimer),this.intervalTimer&&clearInterval(this.intervalTimer),this.pendingTimer=null,this.intervalTimer=null;}markActivePath(e){if(this.stopped||!RQ(e))return;let r=this.isoNow();this.publishRows([{relative_path:e,is_active:true,is_dirty:this.dirty.has(e),git_status:this.dirty.get(e)?.gitStatus??"unknown",last_heartbeat_at:r,last_git_scan_at:r}],[]),this.scheduleReconcile();}scheduleReconcile(){this.stopped||(this.pendingTimer&&clearTimeout(this.pendingTimer),this.pendingTimer=setTimeout(()=>{this.pendingTimer=null,this.reconcile();},this.options.debounceMs??EQ),this.pendingTimer.unref?.());}async reconcile(){if(this.stopped)return this.status();let e=this.isoNow(),r=await ez(this.options.workspaceRoot);if(this.degraded=r.degraded,r.degraded)return this.status();let n=new Map;for(let i of r.entries){let a=this.dirty.get(i.relativePath);n.set(i.relativePath,{gitStatus:i.gitStatus,firstSeenAt:a?.firstSeenAt??e});}let o=Array.from(this.dirty.keys()).filter(i=>!n.has(i));this.dirty.clear();for(let[i,a]of n)this.dirty.set(i,a);this.lastScanAt=e;let s=Array.from(n.entries()).map(([i,a])=>({relative_path:i,is_active:false,is_dirty:true,git_status:a.gitStatus,last_local_write_at:a.firstSeenAt,last_git_scan_at:e}));return await this.publishChunked(s,o),this.status()}status(){return {healthy:!this.degraded,degraded:this.degraded,lastScanAt:this.lastScanAt,dirtyPathCount:this.dirty.size}}async publishChunked(e,r){for(let n=0;n<e.length;n+=zf)await this.publishRows(e.slice(n,n+zf),[]);for(let n=0;n<r.length;n+=zf)await this.publishRows([],r.slice(n,n+zf));}async publishRows(e,r){if(e.length===0&&r.length===0)return;let{error:n}=await this.options.supabase.rpc("pathrule_upsert_file_work_state",{p_workspace_id:this.options.workspaceId,p_runtime_id:this.options.runtimeId,p_rows:e,p_clear_paths:r});n&&(this.degraded=true);}isoNow(){return (this.options.now?.()??new Date).toISOString()}};});async function nz(t=process.env){let{session:e,supabase:r}=await U(t),{data:n,error:o}=await r.from("user_workspace_paths").select("workspace_id, local_root_path, watcher_enabled").eq("user_id",e.user.id).eq("watcher_enabled",true);if(o)throw o;let s=await Gv(e.user.id,t);for(let i of n??[]){if(!i.workspace_id||!i.local_root_path||Rs.has(i.workspace_id))continue;let a=new Ml({workspaceId:i.workspace_id,workspaceRoot:i.local_root_path,userId:e.user.id,runtimeId:s,supabase:r});Rs.set(i.workspace_id,{tracker:a,workspaceRoot:i.local_root_path}),a.start();}}async function Yv(t,e,r=process.env){if(Rs.has(t))return;let{session:n,supabase:o}=await U(r),s=await Gv(n.user.id,r),i=new Ml({workspaceId:t,workspaceRoot:e,userId:n.user.id,runtimeId:s,supabase:o});Rs.set(t,{tracker:i,workspaceRoot:e}),i.start();}async function Xv(t){return Rs.get(t)?.tracker.reconcile()??null}function oz(){for(let t of Rs.values())t.tracker.stop();Rs.clear();}var Rs,sz=m(()=>{rz();Ve();Rs=new Map;});async function ia(t){let e=await Pn(t);if(e.running)return e;let r=process.argv[1];if(!r)throw new Error("daemon_entrypoint_missing");spawn(process.execPath,[r,"daemon","run"],{detached:true,stdio:"ignore",env:{...process.env,...t}}).unref();let o=Date.now()+3e3;for(;Date.now()<o;){let s=await Pn(t);if(s.running)return s;await pee(100);}throw new Error("daemon_start_timeout")}async function Ll(t){let e=await Pn(t);if(e.state?.pid&&e.state.pid!==process.pid)try{process.kill(e.state.pid,"SIGTERM");}catch{}return await unlink(le(t).daemonFile).catch(()=>{}),Pn(t)}async function en(t=process.env){let e=gz(t);if(!e.supported)return e;if(e.method==="task-scheduler"){let r=await YQ();return {...e,enabled:r}}return {...e,enabled:e.path?await oS(e.path):false}}async function mo(t,e){let r=gz(t);if(!r.supported)return r;if(e){let n=HQ(t);if(r.method==="launchd"){if(!r.path)throw new Error("daemon_autostart_path_missing");return await ZQ(r.path,n,t),t.PATHRULE_SKIP_AUTOSTART_ACTIVATE!=="1"&&await KQ(r.path),en(t)}if(r.method==="systemd"){if(!r.path)throw new Error("daemon_autostart_path_missing");return await JQ(r.path,n,t),t.PATHRULE_SKIP_AUTOSTART_ACTIVATE!=="1"&&(await mr("systemctl",["--user","daemon-reload"]),await mr("systemctl",["--user","enable","--now",Uf])),en(t)}return await XQ(n,t),en(t)}return r.method==="launchd"?(t.PATHRULE_SKIP_AUTOSTART_ACTIVATE!=="1"&&r.path&&await GQ(r.path),r.path&&await unlink(r.path).catch(()=>{}),en(t)):r.method==="systemd"?(t.PATHRULE_SKIP_AUTOSTART_ACTIVATE!=="1"&&(await mr("systemctl",["--user","disable","--now",Uf]).catch(()=>{}),await mr("systemctl",["--user","daemon-reload"]).catch(()=>{})),r.path&&await unlink(r.path).catch(()=>{}),en(t)):(await QQ(),en(t))}async function Pn(t){let e=le(t).daemonFile,r;try{r=JSON.parse(await readFile(e,"utf8"));}catch(o){let s=o.code==="ENOENT"?"missing":"unreadable";return await az(WQ(t))?{running:true,state:null,state_path:e,reason:"probed"}:{running:false,state:null,state_path:e,reason:s}}let n=dee(r.pid);if(!n){let o=await az(r.port);if(o)return {running:true,state:o.daemonSessionId?{...r,pid:0,daemon_session_id:o.daemonSessionId,protocol_version:o.protocolVersion}:null,state_path:e,reason:"probed"}}return {running:n,state:r,state_path:e,reason:n?void 0:"stale"}}async function az(t){if(!Number.isInteger(t)||t<=0||t>65535)return null;let e=new AbortController,r=setTimeout(()=>e.abort(),250);try{let n=await fetch(`http://${oa}:${t}/v1/status`,{signal:e.signal});if(!n.ok)return null;let o=await n.json();return o.daemon_present!==!0||typeof o.protocol_version!="string"?null:{protocolVersion:o.protocol_version,daemonSessionId:typeof o.daemon_session_id=="string"&&o.daemon_session_id.length>0?o.daemon_session_id:null}}catch{return null}finally{clearTimeout(r);}}function WQ(t){let e=t.PATHRULE_DAEMON_PORT?.trim()||String(sa),r=Number(e);return Number.isInteger(r)&&r>=0&&r<=65535?r:sa}function gz(t){let e=t.PATHRULE_TEST_PLATFORM??process.platform,r=t.PATHRULE_AUTOSTART_DIR;return e==="darwin"?{supported:true,enabled:false,method:"launchd",path:r?join(r,`${zl}.plist`):join(homedir(),"Library","LaunchAgents",`${zl}.plist`)}:e==="linux"?{supported:true,enabled:false,method:"systemd",path:r?join(r,Uf):join(homedir(),".config","systemd","user",Uf)}:e==="win32"?{supported:false,enabled:false,method:"task-scheduler",path:null,reason:"deferred (M41): Windows autostart is not wired; run `pathrule daemon start` manually."}:{supported:false,enabled:false,method:"unsupported",path:null,reason:`Unsupported platform: ${e}`}}function HQ(t){let e=t.PATHRULE_CLI_ENTRYPOINT?.trim()||process.argv[1];if(!e)throw new Error("daemon_entrypoint_missing");return {command:process.execPath,args:[e,"daemon","run"]}}function nS(t){let e={PATHRULE_DAEMON_PORT:t.PATHRULE_DAEMON_PORT?.trim()||String(sa)};for(let r of ["PATH","PATHRULE_HOME","PATHRULE_WEB_URL"]){let n=t[r];n&&n.trim()!==""&&(e[r]=n);}return e}async function ZQ(t,e,r){let n=`<?xml version="1.0" encoding="UTF-8"?>
|
|
2741
|
+
`;});async function Kt(t,e){let{supabase:r}=await U(e),n=await Ie(e),o=(e.PATHRULE_WEB_URL??"https://app.pathrule.io").replace(/\/$/,"");if(!n)return Qi(t,"org_required",{web_url:`${o}/settings`,suggested_command_after_resolution:"pathrule org use <slug-or-id>"});let{data:s,error:i}=await r.from("organizations").select("id, slug, plan, seat_count, subscription_status").eq("id",n.id).single();if(i)throw i;let a=String(s.plan??n.plan),c=n.role,l=`${o}/org/${n.slug}/billing`;if(t==="create_workspace"){if(!CX(c))return Qi(t,"permission_denied",{role:c,plan:a,organization_id:n.id,web_url:`${o}/org/${n.slug}/settings/members`});let f=await qv(r,"workspaces","organization_id",n.id,{archived_at:null}),p=Wv(a,"workspaces");return zD(f,p)?Qi(t,"capacity_full",{role:c,plan:a,organization_id:n.id,usage:{dimension:"workspaces",used:f,limit:p},web_url:l,suggested_command_after_resolution:"pathrule init"}):LD(t,{role:c,plan:a,organization_id:n.id})}let u=await xe(e);if(!u)return Qi(t,"workspace_required",{role:c,plan:a,organization_id:n.id,web_url:`${o}/org/${n.slug}`,suggested_command_after_resolution:"pathrule workspace use <name-or-id>"});if(kX.has(t)&&!EX(c))return Qi(t,"permission_denied",{role:c,plan:a,organization_id:n.id,workspace_id:u.id,web_url:`${o}/org/${n.slug}/settings/members`});let d=await xX(t,a,u.id,r);return d&&zD(d.used,d.limit)?Qi(t,"capacity_full",{role:c,plan:a,organization_id:n.id,workspace_id:u.id,usage:d,web_url:l,suggested_command_after_resolution:"pathrule status"}):LD(t,{role:c,plan:a,organization_id:n.id,workspace_id:u.id,usage:d})}function Hv(t){return ["create_workspace","write_memory","write_rule","write_skill","sync_agents","materialize_skills"].includes(t)}function ea(t){return t.allowed?{summary:`${t.action} is allowed.`,details:[],url:null,suggested_command_after_resolution:null}:t.blocking_reason==="capacity_full"&&t.usage?{summary:`${vX(t.usage.dimension)} limit reached on the ${t.plan??"current"} plan (${t.usage.used} / ${SX(t.usage.limit)}).`,details:["Open Pathrule Web to upgrade or clean up usage."],url:t.web_url,suggested_command_after_resolution:t.suggested_command_after_resolution}:t.blocking_reason==="permission_denied"?{summary:`Your current role (${t.role??"unknown"}) cannot run ${t.action}.`,details:["Ask an organization admin to update your role or run the action from an admin account."],url:t.web_url,suggested_command_after_resolution:t.suggested_command_after_resolution}:t.blocking_reason==="workspace_required"?{summary:"No current workspace is selected for this folder.",details:["Run setup or choose a workspace before retrying."],url:t.web_url,suggested_command_after_resolution:t.suggested_command_after_resolution??"pathrule setup --json"}:t.blocking_reason==="org_required"?{summary:"No organization is selected.",details:["Choose an organization before retrying."],url:t.web_url,suggested_command_after_resolution:t.suggested_command_after_resolution??"pathrule org use <slug-or-id>"}:{summary:`${t.action} blocked: ${t.blocking_reason??"preflight_blocked"}.`,details:[],url:t.web_url,suggested_command_after_resolution:t.suggested_command_after_resolution}}function vX(t){return t.charAt(0).toLocaleUpperCase("en-US")+t.slice(1)}function SX(t){return t===-1?"unlimited":String(t)}async function xX(t,e,r,n){return t==="write_memory"?{dimension:"memories",used:await qv(n,"memories","workspace_id",r),limit:Wv(e,"memories")}:t==="write_rule"?{dimension:"rules",used:await qv(n,"rules","workspace_id",r),limit:Wv(e,"rules")}:null}async function qv(t,e,r,n,o={}){let s=t.from(e).select("id",{count:"exact",head:true}).eq(r,n);for(let c of Object.keys(o))s=s.is(c,null);let{count:i,error:a}=await s;if(a)throw a;return i??0}function CX(t){return t==="owner"||t==="admin"||t==="member"}function EX(t){return t==="owner"||t==="admin"||t==="member"}function Wv(t,e){return no[t]?.[e]??no.free[e]}function zD(t,e){return e!==-1&&t>=e}function LD(t,e={}){return {action:t,allowed:true,blocking_reason:null,role:null,plan:null,organization_id:null,workspace_id:null,usage:null,web_url:null,suggested_command_after_resolution:null,...e}}function Qi(t,e,r={}){return {action:t,allowed:false,blocking_reason:e,role:null,plan:null,organization_id:null,workspace_id:null,usage:null,web_url:null,suggested_command_after_resolution:null,...r}}var kX,jf=m(()=>{de();Ve();Yr();zt();kX=new Set(["write_memory","write_rule","write_skill","sync_agents","materialize_skills"]);});async function Cn(t,e,r={}){let{session:n,supabase:o}=await U(t),s=await xe(t);if(!s)throw new Error("workspace_required");if(!s.local_root_path)throw new Error("workspace_not_attached");if(s.local_root_path!==e)throw new Error("workspace_cwd_mismatch");await jD(t);let i=await Kt(r.skillsOnly?"materialize_skills":"sync_agents",t);if(!i.allowed)return {ok:false,workspace_id:s.id,workspace_root:s.local_root_path,preflight:i,error:i.blocking_reason??"preflight_blocked"};if(r.skillsOnly){let u=await jX({supabase:o,userId:n.user.id,workspaceId:s.id,workspaceRoot:s.local_root_path});return {ok:u.errors.length===0,workspace_id:s.id,workspace_root:s.local_root_path,preflight:i,skills:{ok:u.errors.length===0,enabled:u.enabled,written:u.written,skipped:u.skipped,removed:u.removed,errors:u.errors},error:u.errors.length===0?void 0:"skill_sync_failed"}}let a=await cf({supabase:o,userId:n.user.id,workspaceId:s.id,workspaceRoot:s.local_root_path,runtimeOwner:BD,runtimeVersion:qD}),c=await MX({supabase:o,userId:n.user.id,workspaceId:s.id,workspaceRoot:s.local_root_path}),l=await Mf({supabase:o,workspaceId:s.id,workspaceRoot:s.local_root_path,env:t});return {ok:a.ok&&c.errors.length===0&&l.ok,workspace_id:s.id,workspace_root:s.local_root_path,preflight:i,companion:{ok:a.ok,enabled:a.enabled,written:a.disk.written,skipped:a.disk.skipped,removed:a.disk.removed,errors:a.disk.errors,error:a.error},claude:{ok:c.errors.length===0,written:c.written,skipped:c.skipped,backed_up:c.backedUp,errors:c.errors,snapshot_changed:c.snapshotChanged},hook_index:l,error:a.error??(c.errors.length>0?"claude_sync_failed":l.ok?void 0:"hook_index_sync_failed")}}async function Ol(t,e,r,n={}){let{session:o}=await U(t),s=await Zt(o.user.id,t);await yf(o.user.id,{...s,current_workspace_id:e,schema_version:1},t);try{return await Cn(t,r,n)}finally{await yf(o.user.id,s,t);}}async function MX(t){let e={written:0,skipped:0,backedUp:[],errors:[],snapshotChanged:false},r=new Set,{body:n,snapshotChanged:o}=await cp({supabase:t.supabase,workspaceId:t.workspaceId,userId:t.userId});e.snapshotChanged=o,await UD(e,t.workspaceRoot,"CLAUDE.md",n)&&r.add("CLAUDE.md"),await UD(e,t.workspaceRoot,".claude/rules/pathrule-protocol.md",up())&&r.add(".claude/rules/pathrule-protocol.md");let s=".claude/settings.json";try{let i=join(t.workspaceRoot,s),a=await HD(i),{body:c,changed:l}=xi(a);l?(await WD(i,c),e.written+=1):e.skipped+=1,r.add(s);}catch(i){e.errors.push({path:s,message:i instanceof Error?i.message:String(i)});}try{await sf({workspaceRoot:t.workspaceRoot,paths:Array.from(r),owner:BD,ownerVersion:qD});}catch(i){e.errors.push({path:".pathrule/managed-files.json",message:i instanceof Error?i.message:String(i)});}return e}async function UD(t,e,r,n){let o=join(e,r);try{let s=await HD(o),i=await nf({workspaceRoot:e,relativePath:r,renderedBody:n,existingBody:s});return i.backupPath&&t.backedUp.push(i.backupPath),i.finalBody===null?(t.skipped+=1,!0):(await WD(o,i.finalBody),t.written+=1,!0)}catch(s){return t.errors.push({path:r,message:s instanceof Error?s.message:String(s)}),false}}async function WD(t,e){await mkdir(dirname(t),{recursive:true});let r=`${t}.tmp`;await writeFile(r,e,"utf8"),await rename(r,t);}async function HD(t){try{return await readFile(t,"utf8")}catch(e){if(e.code==="ENOENT")return null;throw e}}async function jX(t){let[e,r]=await Promise.all([DX(t.supabase,t.userId,t.workspaceId,t.workspaceRoot),zX(t.supabase,t.workspaceId)]),n=await rf({workspaceRoot:t.workspaceRoot,activeTargets:e,skills:r});return {enabled:e,written:n.written,skipped:n.skipped,removed:n.removed,errors:n.errors}}async function DX(t,e,r,n){let[{data:o},s]=await Promise.all([t.from("user_workspace_paths").select("selected_ai_clients").eq("workspace_id",r).eq("user_id",e).maybeSingle(),Kr(n)]),i=o?.selected_ai_clients??null;return Hi({selected:i,detected:s,fallback:Ci})}async function zX(t,e){let{data:r,error:n}=await t.from("skills").select("id, name, description, content, source, github_url, content_fetched_at, updated_at, skill_files(path, content, sha256)").eq("workspace_id",e);if(n)throw new Error(`skill_catalogue_read_failed: ${n.message}`);return (r??[]).map(o=>({id:o.id,name:o.name,description:o.description,content:o.content,source:o.source,githubUrl:o.github_url,contentFetchedAt:o.content_fetched_at,updatedAt:o.updated_at,files:(o.skill_files??[]).map(s=>({path:s.path,content:s.content,sha256:s.sha256}))}))}var OX,NX,BD,qD,ta=m(()=>{uo();af();de();Tk();Ek();ot();ro();Zi();xk();Ve();DD();Lv();jf();zt();OX=createRequire(import.meta.url),NX=OX("../package.json"),BD="cli",qD=NX.version;});async function KX(t){let e=fr(t),r=Fv(t);return Promise.all(JX.map(async n=>{let o=Sn(n),s=o.homeConfigPath(homedir(),e),i;try{i=await readFile(s,"utf8");}catch(a){return a.code==="ENOENT"?{client:n,config_path:s,code:"config_missing"}:{client:n,config_path:s,code:"rewrite_failed",detail:a instanceof Error?a.message:String(a)}}try{let a=o.getManagedEntry(i);if(!a.present||!a.staleReason)return {client:n,config_path:s,code:"no_change"};let c=o.inject(i,r);return await GX(s,c.body),{client:n,config_path:s,code:"stale_mcp_entry_rewritten",detail:a.staleReason}}catch(a){return {client:n,config_path:s,code:"rewrite_failed",detail:a instanceof Error?a.message:String(a)}}}))}async function GX(t,e){await mkdir(dirname(t),{recursive:true});let r=`${t}.tmp`;await writeFile(r,e,"utf8"),await rename(r,t);}async function Nl(t,e){let r=await xn(t,e),n=await KX(t);try{let o=await Cn(t,e),s=await xn(t,e);return {ok:o.ok&&s.ok,doctor_before:r,sync:o,doctor_after:s,mcp_rewrites:n,error:o.ok&&s.ok?void 0:o.error??"repair_incomplete"}}catch(o){return {ok:false,doctor_before:r,mcp_rewrites:n,error:o instanceof Error?o.message:String(o)}}}function VD(t){let e=ZD(t.doctor_before.checks),r=t.doctor_after??t.doctor_before,n=ZD(r.checks),o=t.sync?.preflight,s=r.mcp.filter(f=>!f.installed),i=QX(e,n),a=eQ(e,n),c=tQ(r.mcp),l=rQ(t),u=nQ(t),d=oQ(o);return {ok:t.ok,headline:t.ok?"Local runtime repaired":"Repair incomplete",next_command:sQ(t,n,s.length),sections:[i,a,c,l,u,d]}}async function Zv(t,e={}){let{session:r,supabase:n}=await U(t),{data:o,error:s}=await n.from("user_security_state").select("security_epoch").eq("user_id",r.user.id).maybeSingle();if(s)throw s;let i=typeof o?.security_epoch=="number"?o.security_epoch:0,a=ts(r.user.id,i,t),c=[];for(let l=0;l<i;l+=1){let u=join(a.userCacheDir,`epoch-${l}`),d=await XX(u);if(d===0)continue;let f=e.dryRun!==false?false:await YX(u);c.push({path:u,epoch:l,removed:f,bytes:d});}return {ok:true,dry_run:e.dryRun!==false,current_epoch:i,candidates:c,reclaimed_bytes:c.filter(l=>l.removed).reduce((l,u)=>l+u.bytes,0)}}async function YX(t){return await rm$1(t,{recursive:true,force:true}),true}async function XX(t){try{let e=await stat(t);return e.isFile()?e.size:e.isDirectory()?1:0}catch{return 0}}function ZD(t){return new Map(t.map(e=>[e.name,e]))}function QX(t,e){let r=t.get("auth"),n=e.get("auth"),o=t.get("organization"),s=e.get("organization"),i=[Df(r,n,{pass:(a,c)=>c?`Signed in again as ${a??"the current account"}.`:`Signed in as ${a??"the current account"}.`,warn:a=>`Authentication still needs attention${a?`: ${a}`:""}.`,fail:a=>`Authentication is still blocked${a?`: ${a}`:""}.`}),Df(o,s,{pass:(a,c)=>c?`Organization context restored: ${a??"selected"}.`:`Organization context: ${a??"selected"}.`,warn:a=>`Organization selection is still missing${a&&a!=="no organization selected"?`: ${a}`:""}.`,fail:a=>`Organization lookup failed${a?`: ${a}`:""}.`})];return {title:"Account",status:JD(n?.status,s?.status),lines:i}}function eQ(t,e){let r=t.get("workspace"),n=e.get("workspace"),o=t.get("cwd_attach"),s=e.get("cwd_attach"),i=[Df(r,n,{pass:(a,c)=>c?`Workspace selection recovered: ${a??"current workspace"}.`:`Workspace selection: ${a??"current workspace"}.`,warn:a=>`Workspace selection is still incomplete${a&&a!=="no workspace selected"?`: ${a}`:""}.`,fail:a=>`Workspace lookup failed${a?`: ${a}`:""}.`}),Df(o,s,{pass:(a,c)=>c?"Current folder is attached again.":"Current folder is attached.",warn:a=>a==="workspace not attached"?"Current folder is still not attached.":`Current folder still points to ${a??"another workspace root"}.`,fail:a=>`Current folder attachment check failed${a?`: ${a}`:""}.`})];return {title:"Workspace",status:JD(n?.status,s?.status),lines:i}}function tQ(t){let e=t.filter(s=>s.installed).length,r=t.filter(s=>!s.installed).map(s=>s.client),n=t.filter(s=>s.error).map(s=>`${s.client}: ${s.error}`),o=[`MCP configs ready for ${e}/${t.length} supported clients.`,r.length>0?`Still missing: ${r.join(", ")}.`:"All supported MCP client configs are present."];return n.length>0&&o.push(`Agent config read errors: ${n.join("; ")}.`),{title:"Agents",status:n.length>0?"fail":r.length>0?"warn":"pass",lines:o}}function rQ(t){let e=t.sync?.hook_index;return t.sync?e?{title:"Hooks",status:e.ok?"pass":"fail",lines:[e.ok?`Hook index refreshed${e.schema_version?` (schema ${e.schema_version})`:""}.`:`Hook index refresh failed: ${e.error??"unknown error"}.`,e.refreshed_episodes?"Hook work episodes were refreshed before rebuilding the index.":"Hook work episodes were left unchanged."]}:{title:"Hooks",status:"warn",lines:["Repair did not produce a hook index update."]}:{title:"Hooks",status:"warn",lines:["Repair stopped before hook files could be refreshed."]}}function nQ(t){if(!t.sync)return {title:"Files",status:"warn",lines:["Repair stopped before local files could be rewritten."]};let e=[],r="pass";return t.sync.companion&&(e.push(`Companion files: ${t.sync.companion.written} written, ${t.sync.companion.skipped} unchanged, ${t.sync.companion.removed} removed.`),(t.sync.companion.errors.length>0||!t.sync.companion.ok)&&(r="fail",e.push(`Companion errors: ${t.sync.companion.errors.map(n=>n.message).join("; ")||t.sync.companion.error||"unknown error"}.`))),t.sync.claude&&(e.push(`Claude files: ${t.sync.claude.written} written, ${t.sync.claude.skipped} unchanged, ${t.sync.claude.backed_up.length} backed up.`),t.sync.claude.errors.length>0&&(r="fail",e.push(`Claude sync errors: ${t.sync.claude.errors.map(n=>n.message).join("; ")}.`))),t.sync.skills&&(e.push(`Skills: ${t.sync.skills.written} written, ${t.sync.skills.skipped} unchanged, ${t.sync.skills.removed} removed.`),t.sync.skills.errors.length>0&&(r="fail",e.push(`Skill materialization errors: ${t.sync.skills.errors.map(n=>n.message).join("; ")}.`))),e.length===0&&e.push("No local file rewrites were needed."),{title:"Files",status:r,lines:e}}function oQ(t){return t?t.allowed?{title:"Capacity",status:"pass",lines:["No plan limit blocked this repair."]}:t.blocking_reason==="capacity_full"&&t.usage?{title:"Capacity",status:"fail",lines:[`${iQ(t.usage.dimension)} limit reached (${t.usage.used} / ${aQ(t.usage.limit)}).`,"Open billing or clean up usage before retrying the repair."]}:{title:"Capacity",status:"warn",lines:["Capacity is not the blocking issue for this repair."]}:{title:"Capacity",status:"warn",lines:["Capacity checks did not run because repair stopped early."]}}function Df(t,e,r){let n=e??t;if(!n)return "No status available.";let o=t!=null&&t.status!=="pass"&&n.status==="pass";return n.status==="pass"?r.pass(n.detail,o):n.status==="warn"?r.warn(n.detail,o):r.fail(n.detail,o)}function JD(...t){return t.includes("fail")?"fail":t.includes("warn")?"warn":"pass"}function sQ(t,e,r){if(e.get("auth")?.status!=="pass")return "pathrule login";if(e.get("organization")?.status!=="pass")return "pathrule org use <slug-or-id>";if(e.get("workspace")?.status!=="pass")return "pathrule workspace use <name-or-id>";if(e.get("cwd_attach")?.status!=="pass")return "pathrule attach <workspace>";let a=t.sync?.preflight;if(a&&!a.allowed&&a.suggested_command_after_resolution)return a.suggested_command_after_resolution;if(r>0)return "pathrule install";let c=!t.sync?.companion?.ok||!!t.sync?.companion?.errors.length||!!t.sync?.claude?.errors.length||!!t.sync?.skills?.errors.length||t.sync?.hook_index?.ok===false;return !t.ok||c?"pathrule sync":"pathrule doctor"}function iQ(t){return t.charAt(0).toLocaleUpperCase("en-US")+t.slice(1)}function aQ(t){return t===-1?"unlimited":String(t)}var JX,Vv=m(()=>{ot();$l();Ve();Nf();Al();Xi();ta();JX=["claude-code","cursor","codex","windsurf"];});async function Ps(t,e,r,n){let{session:o,supabase:s}=await U(t);if(o.user.id!==e)throw new Error("session_user_mismatch");let[{data:i},a]=await Promise.all([s.from("user_workspace_paths").select("selected_ai_clients").eq("user_id",e).eq("workspace_id",r).maybeSingle(),n?Kr(n):Promise.resolve([])]),c=new Set(i?.selected_ai_clients??[]),l=new Set(a),u=Object.keys(Fe);return Promise.all(u.map(async d=>{let f=await hQ(d);return {client:d,active:c.has(d)||l.has(d),selected:c.has(d),markers:l.has(d)?["workspace_marker_detected"]:[],machineInstalled:f.installed,machineConfigPath:f.configPath,machineConfigExists:f.configExists}}))}async function XD(t,e,r,n,o,s,i="restore-backup"){let a=mQ(o),{session:c,supabase:l}=await U(t);if(c.user.id!==e)throw new Error("session_user_mismatch");let{data:u,error:d}=await l.from("user_workspace_paths").select("selected_ai_clients").eq("user_id",e).eq("workspace_id",r).eq("local_root_path",n).maybeSingle();if(d)throw new Error(`workspace_client_selection_read_failed: ${d.message}`);if(!u)throw new Error("workspace_root_not_attached");let f=[],p=new Set((u.selected_ai_clients??[]).filter(QD)),h=Array.from(p);s?p.add(a):p.delete(a);let g=Array.from(p);if(!gQ(h,g)){let{error:y}=await l.from("user_workspace_paths").update({selected_ai_clients:g}).eq("user_id",e).eq("workspace_id",r).eq("local_root_path",n);if(y)throw new Error(`workspace_client_selection_update_failed: ${y.message}`)}if(s){let y=await ho(a,t);for(let k of y)k.ok||f.push(`${k.client}: ${k.error??k.status}`);}else await GD(n,a);let _=await Ol(t,r,n);return _.ok||f.push(_.error??"workspace_sync_failed"),s||await GD(n,a),{ok:true,statuses:await Ps(t,e,r,n),warnings:f}}async function hQ(t,e=process.env){let r=Sn(t),n=r.homeConfigPath(homedir(),fr(e));try{let o=await readFile(n,"utf8");return {configPath:n,configExists:!0,installed:r.read(o)!==null}}catch(o){return o.code!=="ENOENT"?{configPath:n,configExists:false,installed:false}:{configPath:n,configExists:false,installed:false}}}function mQ(t){if(QD(t))return t;throw new Error("invalid_agent_target")}function QD(t){return yb(t)!==null}function gQ(t,e){if(t.length!==e.length)return false;let r=new Set(t);return e.every(n=>r.has(n))}async function GD(t,e,r){let n=Fe[e]?.skillsDir;if(!n)return;let o=join(t,n);await rm$1(o,{recursive:true,force:true}),await _Q(dirname(o),t);}async function _Q(t,e){let r=resolve(e),n=resolve(t);for(;n!==r&&n.startsWith(`${r}${sep}`);){try{await rmdir(n);}catch{return}n=dirname(n);}}var Jv=m(()=>{$l();ro();Zi();Ve();Al();Xi();ta();});function Kv(t){if(t.startsWith("/")||/^[A-Za-z]:[\\/]/.test(t))return null;let e=t.replace(/\\/g,"/").replace(/\/+/g,"/");return e.length===0||e==="."||e.startsWith("../")||e.includes("/../")||e.startsWith(".git/")||/[\x00-\x1F]/.test(e)?null:e}function vQ(t){let r=(Buffer.isBuffer(t)?t.toString("utf8"):t).split("\0").filter(o=>o.length>0),n=[];for(let o=0;o<r.length;o+=1){let s=r[o];if(!s||s.length<4)continue;let i=s.slice(0,2),a=s.slice(3),c=SQ(i);if(i.includes("R")||i.includes("C")){let u=Kv(a);u&&n.push({relativePath:u,gitStatus:"renamed"});let d=Kv(r[o+1]??"");d&&n.push({relativePath:d,gitStatus:"renamed"}),o+=1;continue}let l=Kv(a);l&&n.push({relativePath:l,gitStatus:c});}return xQ(n)}async function ez(t,e={}){try{let{stdout:r}=await bQ("git",["status","--porcelain=v1","-z"],{cwd:t,encoding:"buffer",maxBuffer:5242880,timeout:e.timeoutMs??kQ});return {entries:vQ(r),degraded:!1}}catch{return {entries:[],degraded:true}}}function SQ(t){return t==="??"?"untracked":t.includes("A")?"added":t.includes("D")?"deleted":t.includes("R")||t.includes("C")?"renamed":t.includes("M")||t.includes("T")||t.includes("U")?"modified":"unknown"}function xQ(t){let e=new Map;for(let r of t)e.set(r.relativePath,r);return Array.from(e.values()).sort((r,n)=>r.relativePath.localeCompare(n.relativePath))}var bQ,kQ,tz=m(()=>{bQ=promisify(execFile),kQ=2e3;});async function Gv(t,e=process.env){let r=await Zt(t,e);if(r.work_state_runtime_id)return r.work_state_runtime_id;let n=`runtime:${randomUUID()}`;return await Vt(t,{work_state_runtime_id:n},e),n}function RQ(t){return t.length>0&&!t.startsWith("/")&&!t.startsWith("../")&&!t.includes("/../")&&!t.startsWith(".git/")&&!/[\x00-\x1F]/.test(t)}var EQ,PQ,zf,Ml,rz=m(()=>{uo();tz();EQ=800,PQ=6e4,zf=500,Ml=class{constructor(e){this.options=e;}options;dirty=new Map;pendingTimer=null;intervalTimer=null;stopped=false;degraded=false;lastScanAt=null;start(){this.intervalTimer||(this.reconcile(),this.intervalTimer=setInterval(()=>{this.reconcile();},this.options.scanIntervalMs??PQ),this.intervalTimer.unref?.());}stop(){this.stopped=true,this.pendingTimer&&clearTimeout(this.pendingTimer),this.intervalTimer&&clearInterval(this.intervalTimer),this.pendingTimer=null,this.intervalTimer=null;}markActivePath(e){if(this.stopped||!RQ(e))return;let r=this.isoNow();this.publishRows([{relative_path:e,is_active:true,is_dirty:this.dirty.has(e),git_status:this.dirty.get(e)?.gitStatus??"unknown",last_heartbeat_at:r,last_git_scan_at:r}],[]),this.scheduleReconcile();}scheduleReconcile(){this.stopped||(this.pendingTimer&&clearTimeout(this.pendingTimer),this.pendingTimer=setTimeout(()=>{this.pendingTimer=null,this.reconcile();},this.options.debounceMs??EQ),this.pendingTimer.unref?.());}async reconcile(){if(this.stopped)return this.status();let e=this.isoNow(),r=await ez(this.options.workspaceRoot);if(this.degraded=r.degraded,r.degraded)return this.status();let n=new Map;for(let i of r.entries){let a=this.dirty.get(i.relativePath);n.set(i.relativePath,{gitStatus:i.gitStatus,firstSeenAt:a?.firstSeenAt??e});}let o=Array.from(this.dirty.keys()).filter(i=>!n.has(i));this.dirty.clear();for(let[i,a]of n)this.dirty.set(i,a);this.lastScanAt=e;let s=Array.from(n.entries()).map(([i,a])=>({relative_path:i,is_active:false,is_dirty:true,git_status:a.gitStatus,last_local_write_at:a.firstSeenAt,last_git_scan_at:e}));return await this.publishChunked(s,o),this.status()}status(){return {healthy:!this.degraded,degraded:this.degraded,lastScanAt:this.lastScanAt,dirtyPathCount:this.dirty.size}}async publishChunked(e,r){for(let n=0;n<e.length;n+=zf)await this.publishRows(e.slice(n,n+zf),[]);for(let n=0;n<r.length;n+=zf)await this.publishRows([],r.slice(n,n+zf));}async publishRows(e,r){if(e.length===0&&r.length===0)return;let{error:n}=await this.options.supabase.rpc("pathrule_upsert_file_work_state",{p_workspace_id:this.options.workspaceId,p_runtime_id:this.options.runtimeId,p_rows:e,p_clear_paths:r});n&&(this.degraded=true);}isoNow(){return (this.options.now?.()??new Date).toISOString()}};});async function nz(t=process.env){let{session:e,supabase:r}=await U(t),{data:n,error:o}=await r.from("user_workspace_paths").select("workspace_id, local_root_path, watcher_enabled").eq("user_id",e.user.id).eq("watcher_enabled",true);if(o)throw o;let s=await Gv(e.user.id,t);for(let i of n??[]){if(!i.workspace_id||!i.local_root_path||Rs.has(i.workspace_id))continue;let a=new Ml({workspaceId:i.workspace_id,workspaceRoot:i.local_root_path,userId:e.user.id,runtimeId:s,supabase:r});Rs.set(i.workspace_id,{tracker:a,workspaceRoot:i.local_root_path}),a.start();}}async function Yv(t,e,r=process.env){if(Rs.has(t))return;let{session:n,supabase:o}=await U(r),s=await Gv(n.user.id,r),i=new Ml({workspaceId:t,workspaceRoot:e,userId:n.user.id,runtimeId:s,supabase:o});Rs.set(t,{tracker:i,workspaceRoot:e}),i.start();}async function Xv(t){return Rs.get(t)?.tracker.reconcile()??null}function oz(){for(let t of Rs.values())t.tracker.stop();Rs.clear();}var Rs,sz=m(()=>{rz();Ve();Rs=new Map;});async function ia(t){let e=await Pn(t);if(e.running)return e;let r=process.argv[1];if(!r)throw new Error("daemon_entrypoint_missing");spawn(process.execPath,[r,"daemon","run"],{detached:true,stdio:"ignore",env:{...process.env,...t}}).unref();let o=Date.now()+3e3;for(;Date.now()<o;){let s=await Pn(t);if(s.running)return s;await pee(100);}throw new Error("daemon_start_timeout")}async function Ll(t){let e=await Pn(t);if(e.state?.pid&&e.state.pid!==process.pid)try{process.kill(e.state.pid,"SIGTERM");}catch{}return await unlink(le(t).daemonFile).catch(()=>{}),Pn(t)}async function en(t=process.env){let e=gz(t);if(!e.supported)return e;if(e.method==="task-scheduler"){let r=await YQ();return {...e,enabled:r}}return {...e,enabled:e.path?await oS(e.path):false}}async function mo(t,e){let r=gz(t);if(!r.supported)return r;if(e){let n=HQ(t);if(r.method==="launchd"){if(!r.path)throw new Error("daemon_autostart_path_missing");return await ZQ(r.path,n,t),t.PATHRULE_SKIP_AUTOSTART_ACTIVATE!=="1"&&await KQ(r.path),en(t)}if(r.method==="systemd"){if(!r.path)throw new Error("daemon_autostart_path_missing");return await JQ(r.path,n,t),t.PATHRULE_SKIP_AUTOSTART_ACTIVATE!=="1"&&(await mr("systemctl",["--user","daemon-reload"]),await mr("systemctl",["--user","enable","--now",Uf])),en(t)}return await XQ(n,t),en(t)}return r.method==="launchd"?(t.PATHRULE_SKIP_AUTOSTART_ACTIVATE!=="1"&&r.path&&await GQ(r.path),r.path&&await unlink(r.path).catch(()=>{}),en(t)):r.method==="systemd"?(t.PATHRULE_SKIP_AUTOSTART_ACTIVATE!=="1"&&(await mr("systemctl",["--user","disable","--now",Uf]).catch(()=>{}),await mr("systemctl",["--user","daemon-reload"]).catch(()=>{})),r.path&&await unlink(r.path).catch(()=>{}),en(t)):(await QQ(),en(t))}async function Pn(t){let e=le(t).daemonFile,r;try{r=JSON.parse(await readFile(e,"utf8"));}catch(o){let s=o.code==="ENOENT"?"missing":"unreadable";return await az(WQ(t))?{running:true,state:null,state_path:e,reason:"probed"}:{running:false,state:null,state_path:e,reason:s}}let n=dee(r.pid);if(!n){let o=await az(r.port);if(o)return {running:true,state:o.daemonSessionId?{...r,pid:0,daemon_session_id:o.daemonSessionId,protocol_version:o.protocolVersion}:null,state_path:e,reason:"probed"}}return {running:n,state:r,state_path:e,reason:n?void 0:"stale"}}async function az(t){if(!Number.isInteger(t)||t<=0||t>65535)return null;let e=new AbortController,r=setTimeout(()=>e.abort(),250);try{let n=await fetch(`http://${oa}:${t}/v1/status`,{signal:e.signal});if(!n.ok)return null;let o=await n.json();return o.daemon_present!==!0||typeof o.protocol_version!="string"?null:{protocolVersion:o.protocol_version,daemonSessionId:typeof o.daemon_session_id=="string"&&o.daemon_session_id.length>0?o.daemon_session_id:null}}catch{return null}finally{clearTimeout(r);}}function WQ(t){let e=t.PATHRULE_DAEMON_PORT?.trim()||String(sa),r=Number(e);return Number.isInteger(r)&&r>=0&&r<=65535?r:sa}function gz(t){let e=t.PATHRULE_TEST_PLATFORM??process.platform,r=t.PATHRULE_AUTOSTART_DIR;return e==="darwin"?{supported:true,enabled:false,method:"launchd",path:r?join(r,`${zl}.plist`):join(homedir(),"Library","LaunchAgents",`${zl}.plist`)}:e==="linux"?{supported:true,enabled:false,method:"systemd",path:r?join(r,Uf):join(homedir(),".config","systemd","user",Uf)}:e==="win32"?{supported:false,enabled:false,method:"task-scheduler",path:null,reason:"Windows autostart is not yet wired up; run `pathrule daemon start` manually."}:{supported:false,enabled:false,method:"unsupported",path:null,reason:`Unsupported platform: ${e}`}}function HQ(t){let e=t.PATHRULE_CLI_ENTRYPOINT?.trim()||process.argv[1];if(!e)throw new Error("daemon_entrypoint_missing");return {command:process.execPath,args:[e,"daemon","run"]}}function nS(t){let e={PATHRULE_DAEMON_PORT:t.PATHRULE_DAEMON_PORT?.trim()||String(sa)};for(let r of ["PATH","PATHRULE_HOME","PATHRULE_WEB_URL"]){let n=t[r];n&&n.trim()!==""&&(e[r]=n);}return e}async function ZQ(t,e,r){let n=`<?xml version="1.0" encoding="UTF-8"?>
|
|
2742
2742
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
2743
2743
|
<plist version="1.0">
|
|
2744
2744
|
<dict>
|