@crustjs/skills 0.0.21 → 0.0.23

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.
Files changed (2) hide show
  1. package/dist/index.js +10 -10
  2. package/package.json +6 -5
package/dist/index.js CHANGED
@@ -1,11 +1,11 @@
1
1
  // @bun
2
- import{accessSync as nQ,constants as tQ}from"fs";import{homedir as i}from"os";import{delimiter as eQ,join as Y}from"path";var E=Y(".agents","skills"),QZ=Y(".crust","skills");function MQ(Q){if(Q!==i())return Y(Q,".config");let Z=process.env.XDG_CONFIG_HOME?.trim();return Z&&Z.length>0?Z:Y(Q,".config")}function j(Q){return Y(Q,".agents","skills")}function ZZ(Q){return Y(Q,".crust","skills")}function u(Q){return Q==="project"&&process.cwd()===i()?"global":Q}var C={amp:{label:"Amp",class:"universal",projectSkillsDir:E,globalSkillsDir:j},adal:{label:"AdaL",class:"additional",projectSkillsDir:Y(".adal","skills"),globalSkillsDir:(Q)=>Y(Q,".adal","skills"),detectCommands:["adal"]},antigravity:{label:"Antigravity",class:"additional",projectSkillsDir:Y(".agent","skills"),globalSkillsDir:(Q)=>Y(Q,".gemini","antigravity","skills"),detectCommands:["antigravity"]},augment:{label:"Augment",class:"additional",projectSkillsDir:Y(".augment","skills"),globalSkillsDir:(Q)=>Y(Q,".augment","skills"),detectCommands:["augment"]},"claude-code":{label:"Claude Code",class:"additional",projectSkillsDir:Y(".claude","skills"),globalSkillsDir:(Q)=>Y(process.env.CLAUDE_CONFIG_DIR?.trim()||Y(Q,".claude"),"skills"),detectCommands:["claude","claude-code"]},cline:{label:"Cline",class:"universal",projectSkillsDir:E,globalSkillsDir:j},codebuddy:{label:"CodeBuddy",class:"additional",projectSkillsDir:Y(".codebuddy","skills"),globalSkillsDir:(Q)=>Y(Q,".codebuddy","skills"),detectCommands:["codebuddy"]},codex:{label:"Codex",class:"universal",projectSkillsDir:E,globalSkillsDir:j},"command-code":{label:"Command Code",class:"additional",projectSkillsDir:Y(".commandcode","skills"),globalSkillsDir:(Q)=>Y(Q,".commandcode","skills"),detectCommands:["command-code","commandcode"]},continue:{label:"Continue",class:"additional",projectSkillsDir:Y(".continue","skills"),globalSkillsDir:(Q)=>Y(Q,".continue","skills"),detectCommands:["continue"]},cortex:{label:"Cortex Code",class:"additional",projectSkillsDir:Y(".cortex","skills"),globalSkillsDir:(Q)=>Y(Q,".snowflake","cortex","skills"),detectCommands:["cortex"]},crush:{label:"Crush",class:"additional",projectSkillsDir:Y(".crush","skills"),globalSkillsDir:(Q)=>Y(MQ(Q),"crush","skills"),detectCommands:["crush"]},cursor:{label:"Cursor",class:"universal",projectSkillsDir:E,globalSkillsDir:j},droid:{label:"Droid",class:"additional",projectSkillsDir:Y(".factory","skills"),globalSkillsDir:(Q)=>Y(Q,".factory","skills"),detectCommands:["droid"]},"gemini-cli":{label:"Gemini CLI",class:"universal",projectSkillsDir:E,globalSkillsDir:j},"github-copilot":{label:"GitHub Copilot",class:"universal",projectSkillsDir:E,globalSkillsDir:j},goose:{label:"Goose",class:"additional",projectSkillsDir:Y(".goose","skills"),globalSkillsDir:(Q)=>Y(MQ(Q),"goose","skills"),detectCommands:["goose"]},"iflow-cli":{label:"iFlow CLI",class:"additional",projectSkillsDir:Y(".iflow","skills"),globalSkillsDir:(Q)=>Y(Q,".iflow","skills"),detectCommands:["iflow","iflow-cli"]},junie:{label:"Junie",class:"additional",projectSkillsDir:Y(".junie","skills"),globalSkillsDir:(Q)=>Y(Q,".junie","skills"),detectCommands:["junie"]},kilo:{label:"Kilo Code",class:"additional",projectSkillsDir:Y(".kilocode","skills"),globalSkillsDir:(Q)=>Y(Q,".kilocode","skills"),detectCommands:["kilo","kilocode"]},"kimi-cli":{label:"Kimi Code CLI",class:"universal",projectSkillsDir:E,globalSkillsDir:j},"kiro-cli":{label:"Kiro CLI",class:"additional",projectSkillsDir:Y(".kiro","skills"),globalSkillsDir:(Q)=>Y(Q,".kiro","skills"),detectCommands:["kiro","kiro-cli"]},kode:{label:"Kode",class:"additional",projectSkillsDir:Y(".kode","skills"),globalSkillsDir:(Q)=>Y(Q,".kode","skills"),detectCommands:["kode"]},mcpjam:{label:"MCPJam",class:"additional",projectSkillsDir:Y(".mcpjam","skills"),globalSkillsDir:(Q)=>Y(Q,".mcpjam","skills"),detectCommands:["mcpjam"]},"mistral-vibe":{label:"Mistral Vibe",class:"additional",projectSkillsDir:Y(".vibe","skills"),globalSkillsDir:(Q)=>Y(Q,".vibe","skills"),detectCommands:["mistral-vibe","vibe"]},mux:{label:"Mux",class:"additional",projectSkillsDir:Y(".mux","skills"),globalSkillsDir:(Q)=>Y(Q,".mux","skills"),detectCommands:["mux"]},neovate:{label:"Neovate",class:"additional",projectSkillsDir:Y(".neovate","skills"),globalSkillsDir:(Q)=>Y(Q,".neovate","skills"),detectCommands:["neovate"]},opencode:{label:"OpenCode",class:"universal",projectSkillsDir:E,globalSkillsDir:j},openclaw:{label:"OpenClaw",class:"additional",projectSkillsDir:"skills",globalSkillsDir:(Q)=>Y(Q,".openclaw","skills"),detectCommands:["openclaw"]},openhands:{label:"OpenHands",class:"additional",projectSkillsDir:Y(".openhands","skills"),globalSkillsDir:(Q)=>Y(Q,".openhands","skills"),detectCommands:["openhands"]},pi:{label:"Pi",class:"additional",projectSkillsDir:Y(".pi","skills"),globalSkillsDir:(Q)=>Y(Q,".pi","agent","skills"),detectCommands:["pi"]},pochi:{label:"Pochi",class:"additional",projectSkillsDir:Y(".pochi","skills"),globalSkillsDir:(Q)=>Y(Q,".pochi","skills"),detectCommands:["pochi"]},qoder:{label:"Qoder",class:"additional",projectSkillsDir:Y(".qoder","skills"),globalSkillsDir:(Q)=>Y(Q,".qoder","skills"),detectCommands:["qoder"]},"qwen-code":{label:"Qwen Code",class:"additional",projectSkillsDir:Y(".qwen","skills"),globalSkillsDir:(Q)=>Y(Q,".qwen","skills"),detectCommands:["qwen","qwen-code"]},replit:{label:"Replit",class:"universal",projectSkillsDir:E,globalSkillsDir:j},roo:{label:"Roo Code",class:"additional",projectSkillsDir:Y(".roo","skills"),globalSkillsDir:(Q)=>Y(Q,".roo","skills"),detectCommands:["roo","roo-code"]},trae:{label:"Trae",class:"additional",projectSkillsDir:Y(".trae","skills"),globalSkillsDir:(Q)=>Y(Q,".trae","skills"),detectCommands:["trae"]},"trae-cn":{label:"Trae CN",class:"additional",projectSkillsDir:Y(".trae","skills"),globalSkillsDir:(Q)=>Y(Q,".trae-cn","skills"),detectCommands:["trae-cn","trae"]},windsurf:{label:"Windsurf",class:"additional",projectSkillsDir:Y(".windsurf","skills"),globalSkillsDir:(Q)=>Y(Q,".codeium","windsurf","skills"),detectCommands:["windsurf"]},zencoder:{label:"Zencoder",class:"additional",projectSkillsDir:Y(".zencoder","skills"),globalSkillsDir:(Q)=>Y(Q,".zencoder","skills"),detectCommands:["zencoder"]}},c=Object.keys(C),y=Object.fromEntries(c.map((Q)=>[Q,C[Q].label]));function D(){return c.filter((Q)=>C[Q].class==="universal")}function h(){return c.filter((Q)=>C[Q].class==="additional")}function XZ(Q){return C[Q].class==="universal"}async function ZQ(Q){let Z=typeof Q==="string"?{home:Q}:Q??{},X=Z.cwd??process.cwd(),$=Z.commandChecker??((H)=>Promise.resolve($Z(H))),W=[];for(let H of h()){let B=C[H].detectCommands??[],K=!1;for(let z of B)if(await $(z,X)){K=!0;break}if(K)W.push(H)}return W}function O(Q,Z,X){let $=u(Z),W=C[Q];if($==="project")return Y(process.cwd(),W.projectSkillsDir,X);return Y(W.globalSkillsDir(i()),X)}function P(Q,Z){if(u(Q)==="project")return Y(process.cwd(),QZ,Z);return Y(ZZ(i()),Z)}function $Z(Q){let X=(process.env.PATH??"").split(eQ).filter((H)=>H.length>0),$=process.platform==="win32",W=$?(process.env.PATHEXT??".EXE;.CMD;.BAT;.COM").split(";").filter((H)=>H.length>0):[];for(let H of X){if(!$&&TQ(Y(H,Q)))return!0;if($){for(let B of W)if(TQ(Y(H,Q+B)))return!0}}return!1}function TQ(Q){try{return nQ(Q,tQ.X_OK),!0}catch{return!1}}import{Crust as WZ}from"@crustjs/core";function o(Q){if(Q===void 0)return[];return(Array.isArray(Q)?Q:[Q]).flatMap((X)=>X.split(/\r?\n/)).map((X)=>X.trim()).filter((X)=>X.length>0)}function _Q(Q){let Z=Q?.trim();if(!Z)return[];return Z.split(/\r?\n/)}function XQ(Q){return Q.length>0}var bQ=Symbol("crust.skill.commandAnnotations");function HZ(Q){return Q instanceof WZ?Q._node:Q}function YZ(Q,Z){let X=HZ(Q),$=o(typeof Z==="string"||Array.isArray(Z)?Z:Z.instructions??[]);if($.length===0)return Q;let W=$Q(X)?.instructions??[],H=[...new Set([...W,...$])];return Object.defineProperty(X,bQ,{value:{instructions:H},enumerable:!0,configurable:!0}),Q}function $Q(Q){let Z=Q[bQ];if(!Z?.instructions||Z.instructions.length===0)return;return{instructions:[...Z.instructions]}}class I extends Error{name="SkillConflictError";details;constructor(Q){let Z=`Skill conflict for agent "${Q.agent}": directory "${Q.outputDir}" already exists but was not created by Crust (no crust.json found). Delete or rename the conflicting skill to resolve.`;super(Z);this.details=Q}}import{lstat as LZ,mkdir as pQ,readlink as PZ,realpath as CZ,rm as d,symlink as yZ,writeFile as DZ}from"fs/promises";import{dirname as gQ,join as SQ}from"path";function OQ(Q){return RQ(Q,[])}function RQ(Q,Z){let X=qZ(Q.meta.name),$=[...Z,X],W=BZ(Q.args),H=zZ(Q.effectiveFlags),B=xZ(Q.subCommands,$),K=$Q(Q);return{name:X,path:$,description:Q.meta.description,usage:Q.meta.usage,instructions:K?.instructions,runnable:typeof Q.run==="function",args:W,flags:H,children:B}}function qZ(Q){return Q.trim().toLowerCase()}function BZ(Q){if(!Q||Q.length===0)return[];return Q.map(JZ)}function JZ(Q){let Z={name:Q.name,type:Q.type,required:Q.required===!0,variadic:Q.variadic===!0};if(Q.description!==void 0)Z.description=Q.description;if(Q.default!==void 0)Z.default=kQ(Q.default);return Z}function zZ(Q){if(!Q)return[];return Object.keys(Q).sort().map((X)=>{return KZ(X,Q[X])})}function KZ(Q,Z){let X={name:Q,type:Z.type,required:Z.required===!0,multiple:Z.multiple===!0,short:Z.short,aliases:Z.aliases?[...Z.aliases].sort():[]};if(Z.description!==void 0)X.description=Z.description;if(Z.default!==void 0)X.default=kQ(Z.default);return X}function xZ(Q,Z){return Object.keys(Q).sort().map(($)=>{return RQ(Q[$],Z)})}function kQ(Q){if(Array.isArray(Q))return JSON.stringify(Q);return String(Q)}function m(Q){if(/[:#[\]{}&*!|>'"`,@?\\]|^\s|\s$|^---|[\n\r]/.test(Q))return`"${Q.replace(/\\/g,"\\\\").replace(/"/g,"\\\"").replace(/\n/g,"\\n").replace(/\r/g,"\\r")}"`;return Q}function EQ(Q){return Q.replace(/(?<!\\)\|/g,"\\|")}function jQ(Q,Z){let X=[],$=IQ(Q);X.push({path:"SKILL.md",content:GZ(Q,Z,$)});for(let W of $){let H=S(W),B=W.children.length>0?VZ(W,Q):UZ(W,Q);X.push({path:H,content:B})}return X}function IQ(Q){let Z=[Q];for(let X of Q.children)Z.push(...IQ(X));return Z}function S(Q){if(Q.path.length<=1)return`commands/${Q.name}.md`;return`commands/${Q.path.slice(1).join("/")}.md`}function HQ(Q){return Q.path.join(" ")}function WQ(Q,Z){let X=Q.split("/").slice(0,-1),$=Z.split("/"),W=0;while(W<X.length&&W<$.length&&X[W]===$[W])W++;let H=X.length-W,B=$.slice(W);if(H===0)return B.join("/");return[...Array.from({length:H},()=>".."),...B].join("/")}function GZ(Q,Z,X){let $=[];if($.push("---"),$.push(`name: ${m(Z.name)}`),$.push(`description: ${m(Z.description)}`),Z.license)$.push(`license: ${m(Z.license)}`);if(Z.compatibility)$.push(`compatibility: ${m(Z.compatibility)}`);if(Z.disableModelInvocation)$.push("disable-model-invocation: true");if(Z.allowedTools)$.push(`allowed-tools: ${m(Z.allowedTools)}`);if($.push("metadata:"),$.push(` version: "${Z.version}"`),$.push("---"),$.push(""),$.push(`# ${Z.name}`),$.push(""),Q.description)$.push(Q.description),$.push("");$.push(`You should use this skill when you need accurate help with \`${Z.name}\` commands, including command selection, syntax, arguments, flags, defaults, and subcommands.`),$.push("");let W=EZ(Z.instructions);if($.push("## How to Use This Skill"),$.push(""),$.push("1. You must find the command that best matches the user's task from the Command Reference below."),$.push("2. You must check the `Type` column before suggesting execution: `runnable` and `runnable, group` commands can be executed, while `group` commands are organizational only."),$.push("3. You should read only the linked file or files you need from `commands/`."),$.push("4. You must read a command's file before answering a command-specific question or suggesting that command."),$.push("5. You must treat the command file as the source of truth for usage, arguments, flags, aliases, and defaults."),$.push("6. If a flag, argument, alias, or default is not documented there, you must say it is not documented instead of guessing."),$.push(""),XQ(W))$.push("## General Guidance"),$.push(""),$.push(...W),$.push("");if($.push("## Command Reference"),$.push(""),$.push("You should use this table to locate the command file you need."),$.push(""),$.push(...FZ(X)),$.push(""),Q.runnable){$.push("## Usage"),$.push("");let H=S(Q);$.push(`The root command is directly executable. You should see [${Q.name}](${H}) for usage details.`),$.push("")}return $.join(`
3
- `)}function FZ(Q){let Z=[];Z.push("| Command | Type | Documentation |"),Z.push("| ------- | ---- | ------------- |");for(let X of Q){let $=HQ(X),W=S(X),H=wZ(X);Z.push(`| \`${$}\` | ${H} | [${W}](${W}) |`)}return Z}function wZ(Q){if(Q.runnable&&Q.children.length>0)return"runnable, group";if(Q.runnable)return"runnable";return"group"}function UZ(Q,Z){let X=[];return X.push(...NQ(Q)),X.push(...LQ(Q)),X.push(...PQ(Q)),X.push(...yQ(Q,Z)),X.join(`
4
- `)}function VZ(Q,Z){let X=[],$=S(Q);if(X.push(...NQ(Q)),X.push(...LQ(Q)),Q.runnable)X.push(...PQ(Q));return X.push(...TZ(Q,$)),X.push(...yQ(Q,Z)),X.join(`
5
- `)}function MZ(Q){let Z=[...Q.path];for(let X of Q.args)if(X.variadic)Z.push(X.required?`<${X.name}...>`:`[${X.name}...]`);else Z.push(X.required?`<${X.name}>`:`[${X.name}]`);if(Q.flags.length>0)Z.push("[options]");return Z.join(" ")}function NQ(Q){let Z=[`# \`${HQ(Q)}\``,""];if(Q.description)Z.push(Q.description,"");return Z}function LQ(Q){let Z=Q.instructions??[];if(!XQ(Z))return[];return["## Command Instructions","",...CQ(Z),""]}function PQ(Q){let Z=["## Usage","","```",Q.usage??MZ(Q),"```",""];if(Q.args.length>0)Z.push("## Arguments","",..._Z(Q.args),"");if(Q.flags.length>0)Z.push("## Flags","",...OZ(Q.flags),"");return Z.push("## Command Documentation Authority","","You must treat only the arguments, flags, options, aliases, and defaults documented in this file as supported for this command.","You must not infer or invent additional command-line options.",""),Z}function TZ(Q,Z){let X=["## Subcommands",""];for(let $ of Q.children){let W=S($),H=WQ(Z,W),B=$.description?` - ${$.description}`:"";X.push(`- [\`${$.name}\`](${H})${B}`)}return X.push(""),X}function _Z(Q){let Z=[];Z.push("| Argument | Type | Required | Description |"),Z.push("| -------- | ---- | -------- | ----------- |");for(let X of Q){let $=X.variadic?`${X.name}...`:X.name,W=X.required?"Yes":"No",H=EQ(bZ(X));Z.push(`| \`${$}\` | ${X.type} | ${W} | ${H} |`)}return Z}function bZ(Q){let Z=[];if(Q.description)Z.push(Q.description);if(Q.default!==void 0)Z.push(`Default: \`${Q.default}\``);return Z.join(". ")||"-"}function OZ(Q){let Z=[];Z.push("| Flag | Type | Required | Description |"),Z.push("| ---- | ---- | -------- | ----------- |");for(let X of Q){let $=RZ(X),W=X.required?"Yes":"No",H=EQ(kZ(X));Z.push(`| ${$} | ${X.type} | ${W} | ${H} |`)}return Z}function RZ(Q){let Z=[`\`--${Q.name}\``];if(Q.short)Z.push(`\`-${Q.short}\``);for(let X of Q.aliases)Z.push(`\`--${X}\``);return Z.join(", ")}function kZ(Q){let Z=[];if(Q.description)Z.push(Q.description);if(Q.multiple)Z.push("Can be specified multiple times");if(Q.default!==void 0)Z.push(`Default: \`${Q.default}\``);return Z.join(". ")||"-"}function CQ(Q){return Q.map((Z)=>`- ${Z}`)}function EZ(Q){if(typeof Q==="string")return _Q(Q);return CQ(o(Q))}function yQ(Q,Z){let X=[],$=S(Q);if(X.push("---"),X.push(""),Q.path.length>1){let H=Q.path.slice(0,-1),B=DQ(Z,H);if(B){let K=S(B),z=WQ($,K),J=HQ(B);X.push(`Parent: [\`${J}\`](${z})`),X.push("")}}let W=WQ($,"SKILL.md");return X.push(`[Skill Overview](${W})`),X.push(""),X}function DQ(Q,Z){if(jZ(Q.path,Z))return Q;for(let X of Q.children){let $=DQ(X,Z);if($)return $}return}function jZ(Q,Z){if(Q.length!==Z.length)return!1;for(let X=0;X<Q.length;X++)if(Q[X]!==Z[X])return!1;return!0}import{readFile as IZ}from"fs/promises";import{join as NZ}from"path";var YQ="crust.json";async function A(Q){try{let Z=await IZ(NZ(Q,YQ),"utf-8"),X=JSON.parse(Z);if(typeof X==="object"&&X!==null&&"version"in X&&typeof X.version==="string")return X.version;return null}catch{return null}}var SZ="auto",uQ=/^[a-z0-9]+(-[a-z0-9]+)*$/;function cQ(Q){return Q.length>=1&&Q.length<=64&&uQ.test(Q)}function a(Q){return Q}function JQ(Q){return Q.startsWith("use-")?Q:`use-${Q}`}async function p(Q){let{command:Z,meta:X,agents:$,scope:W="global",clean:H=!0,force:B=!1,installMode:K=SZ}=Q,z=a(X.name),J=JQ(X.name);if(!cQ(z))throw Error(`Invalid skill name "${z}": must be 1\u201364 lowercase `+`alphanumeric characters and hyphens, no leading/trailing/consecutive hyphens. Pattern: ${uQ.source}`);let x=$[0];if(!x)return{agents:[]};let w={...X,name:z},G=OQ(Z),N=jQ(G,w),M=gZ(w),b=[...N,...M].sort((q,F)=>q.path<F.path?-1:q.path>F.path?1:0),R=b.map((q)=>q.path),T=new Map;for(let q of $){let F=O(q,W,w.name),U=T.get(F);if(U)U.push(q);else T.set(F,[q])}let _=P(W,w.name),k=P(W,J),L=new Map;for(let[q,F]of T){let U=F[0];if(!U)continue;L.set(q,await xQ({outputDir:q,legacyOutputDir:O(U,W,J),canonicalOutputDir:_,legacyCanonicalOutputDir:k}))}let s=await A(_);if((await KQ(_,_)).exists&&s===null&&!B)throw new I({agent:x,outputDir:_});let v=s!==w.version;if(v){if(H)await GQ(_);await mQ(_,b)}let f=[];for(let[q,F]of T){let U=F[0];if(!U)continue;let V=L.get(q);if(!V)continue;if(V.current.inspection.exists&&!V.current.isCrustManaged&&!B)throw new I({agent:U,outputDir:q});let e=await vZ({outputDir:q,canonicalOutputDir:_,allFiles:b,clean:H,installMode:K,inspection:V.current.inspection,installedVersion:V.preferredVersion,currentVersion:w.version}),oQ=await hZ(V),QQ=AZ({installedVersion:V.preferredVersion,currentVersion:w.version,canonicalChanged:v,pathChanged:e||oQ||V.preferredOutputDir!==q});for(let aQ of F)f.push({agent:aQ,outputDir:q,files:QQ==="up-to-date"?[]:R,status:QQ,previousVersion:QQ==="updated"?V.preferredVersion??void 0:void 0})}{let q=await A(k);if(k!==_&&q!==null&&!await BQ(J,W))await d(k,{recursive:!0,force:!0})}return{agents:f}}async function zQ(Q){let{name:Z,agents:X,scope:$="global"}=Q,W=a(Z),H=JQ(Z),B=P($,W),K=P($,H),z=[],J=new Map;for(let x of X){let w=O(x,$,W),G=J.get(w);if(G)G.push(x);else J.set(w,[x])}for(let[x,w]of J){let G=w[0];if(!G)continue;let N=O(G,$,H),M=await xQ({outputDir:x,legacyOutputDir:N,canonicalOutputDir:B,legacyCanonicalOutputDir:K}),b=await qQ(M.current),R=M.legacy.outputDir!==M.current.outputDir?await qQ(M.legacy):!1,T=b||R,_=b?x:R?N:x;for(let k of w)z.push({agent:k,outputDir:_,status:T?"removed":"not-found"})}if(await A(B)!==null&&!await BQ(W,$))await d(B,{recursive:!0,force:!0});{let x=await A(K);if(K!==B&&x!==null&&!await BQ(H,$))await d(K,{recursive:!0,force:!0})}return{agents:z}}async function r(Q){let{name:Z,agents:X,scope:$="global"}=Q,W=a(Z),H=JQ(Z),B=[],K=new Map;for(let z of X){let J=O(z,$,W),x=K.get(J);if(x)x.push(z);else K.set(J,[z])}for(let[z,J]of K){let x=J[0];if(!x)continue;let w=O(x,$,H),G=P($,W),N=P($,H),M=await xQ({outputDir:z,legacyOutputDir:w,canonicalOutputDir:G,legacyCanonicalOutputDir:N}),b=M.preferredOutputDir??z,R=M.preferredVersion;for(let T of J)B.push({agent:T,outputDir:b,installed:R!==null,version:R??void 0})}return{agents:B}}function AZ(Q){let{installedVersion:Z,currentVersion:X,canonicalChanged:$,pathChanged:W}=Q;if(Z===null)return"installed";if(Z===X&&!$&&!W)return"up-to-date";return"updated"}async function vZ(Q){let{outputDir:Z,canonicalOutputDir:X,allFiles:$,clean:W,installMode:H,inspection:B,installedVersion:K,currentVersion:z}=Q;if(H==="copy")return AQ({outputDir:Z,allFiles:$,clean:W,inspection:B,installedVersion:K,currentVersion:z});try{return await fZ({outputDir:Z,canonicalOutputDir:X,inspection:B})}catch(J){if(H==="symlink")throw Error(`Failed to create symlink at "${Z}" (installMode: symlink).`,{cause:J});let x=await KQ(Z,X);return AQ({outputDir:Z,allFiles:$,clean:W,inspection:x,installedVersion:K,currentVersion:z})}}async function AQ(Q){let{outputDir:Z,allFiles:X,clean:$,inspection:W,installedVersion:H,currentVersion:B}=Q;if(!(!W.exists||W.isSymlink||H!==B))return!1;if(W.isSymlink||$)await GQ(Z);return await mQ(Z,X),!0}async function fZ(Q){let{outputDir:Z,canonicalOutputDir:X,inspection:$}=Q;if($.exists&&$.isSymlink&&$.pointsToCanonical)return!1;if($.exists)await GQ(Z);return await pZ(X,Z),!0}async function KQ(Q,Z){let X;try{X=await LZ(Q)}catch{return{exists:!1,isSymlink:!1,pointsToCanonical:!1}}let $=process.platform==="win32"&&X.isDirectory()&&await hQ(Q)!==null;if(!(X.isSymbolicLink()||$))return{exists:!0,isSymlink:!1,pointsToCanonical:!1};let[H,B,K]=await Promise.all([fQ(Q),fQ(Z),hQ(Q)]);return{exists:!0,isSymlink:!0,pointsToCanonical:H!==null&&B!==null&&H===B||K===Z}}async function vQ(Q,Z){let[X,$]=await Promise.all([A(Q),KQ(Q,Z)]),W=X!==null||$.exists&&$.isSymlink&&$.pointsToCanonical;return{outputDir:Q,version:X,inspection:$,isCrustManaged:W}}async function xQ(Q){let{outputDir:Z,legacyOutputDir:X,canonicalOutputDir:$,legacyCanonicalOutputDir:W}=Q,H=await vQ(Z,$),B=X===Z?H:await vQ(X,W);if(H.isCrustManaged)return{current:H,legacy:B,preferredVersion:H.version,preferredOutputDir:H.outputDir};if(B.isCrustManaged)return{current:H,legacy:B,preferredVersion:B.version,preferredOutputDir:B.outputDir};return{current:H,legacy:B,preferredVersion:null,preferredOutputDir:null}}async function qQ(Q){if(!Q.isCrustManaged||!Q.inspection.exists)return!1;return await d(Q.outputDir,{recursive:!0,force:!0}),!0}async function hZ(Q){if(Q.legacy.outputDir===Q.current.outputDir)return!1;return qQ(Q.legacy)}async function fQ(Q){try{return await CZ(Q)}catch{return null}}async function hQ(Q){try{return await PZ(Q)}catch{return null}}async function pZ(Q,Z){await pQ(gQ(Z),{recursive:!0});let X=process.platform==="win32"?"junction":"dir";await yZ(Q,Z,X)}async function BQ(Q,Z){let X=new Set;for(let $ of c)X.add(O($,Z,Q));for(let $ of X)if(await A($)!==null)return!0;return!1}function gZ(Q){let Z={name:Q.name,description:Q.description,version:Q.version};return[{path:YQ,content:`${JSON.stringify(Z,null,"\t")}
6
- `}]}async function GQ(Q){await d(Q,{recursive:!0,force:!0})}async function mQ(Q,Z){let X=new Set;for(let W of Z){let H=SQ(Q,W.path),B=gQ(H);X.add(B)}let $=[...X].sort();for(let W of $)await pQ(W,{recursive:!0});for(let W of Z){let H=SQ(Q,W.path);await DZ(H,W.content,"utf-8")}}import{Crust as rQ,VALIDATION_MODE_ENV as uZ}from"@crustjs/core";import{confirm as cZ,multiselect as mZ,select as dZ,spinner as l}from"@crustjs/prompts";import{bold as t,dim as g,yellow as lQ}from"@crustjs/style";var rZ="skill",sQ="global",n="__universal__";function lZ(Q){return Q==="global"||Q==="project"}async function iQ(Q,Z){if(Q!==void 0){if(!lZ(Q))throw Error(`Invalid --scope value: ${String(Q)}. Expected "project" or "global".`);return Q}if(Z.defaultScope)return Z.defaultScope;return dZ({message:"Select scope",choices:[{label:"Project",value:"project"},{label:"Global",value:"global"}],default:sQ})}function FQ(Q){let Z=new Set(D()),X=[];if(Q.some(($)=>Z.has($)))X.push("Universal");for(let $ of Q){if(Z.has($))continue;X.push(y[$])}return X}function dQ(Q){let Z=new Set(D()),X=[],$=Q.find((W)=>Z.has(W.agent));if($)X.push({label:"Universal",outputDir:$.outputDir});for(let W of Q){if(Z.has(W.agent))continue;X.push({label:y[W.agent],outputDir:W.outputDir})}return X}function wQ(Q,Z){return{name:Q.meta.name,description:Q.meta.description??"",version:Z.version,instructions:Z.instructions,license:Z.license,allowedTools:Z.allowedTools,compatibility:Z.compatibility,disableModelInvocation:Z.disableModelInvocation}}function UQ(Q,Z,X,$){if(!$.installed)return!1;let W=O(Q,Z,X.name);return $.version!==X.version||$.outputDir!==W}async function sZ(Q,Z){let X=[...D(),...h()];if(X.length===0)return;let $=wQ(Q,Z),W=[...new Set(["project","global"].map((H)=>u(H)))];for(let H of W){let K=(await r({name:$.name,agents:X,scope:H})).agents.filter((z)=>UQ(z.agent,H,$,z));if(K.length===0)continue;try{await l({message:`Updating ${H} skills...`,task:async({updateMessage:z})=>{let J=await p({command:Q,meta:$,agents:K.map((G)=>G.agent),scope:H,installMode:Z.installMode}),x=J.agents.filter((G)=>G.status==="updated").map((G)=>G.agent),w=FQ(x);if(w.length>0)z(`Updated skill "${$.name}" to v${$.version} for ${w.join(", ")} (${H})`);return J}})}catch(z){if(z instanceof I)console.warn(lQ(`Skill conflict: "${z.details.outputDir}" already exists but was not created by ${$.name}. Skipping auto-update for ${H}. Delete or rename the conflicting skill to resolve.`));else throw z}}}function iZ(Q){let Z;return{name:"skills",async setup(X,$){Z=X.rootCommand;let W=Q.command??rZ;if($.addSubCommand(Z,W,oZ(Z,Q,W)),process.env[uZ]==="1")return;if(X.argv[0]===W)return;if(Q.autoUpdate!==!1)await sZ(Z,Q)}}}function oZ(Q,Z,X){let $=aZ(Q,Z);return new rQ(X).meta({description:"Manage agent skill installations"}).flags({scope:{type:"string",description:"Install scope (project or global)"},all:{type:"boolean",description:"Install for all detected agents non-interactively (universal + detected)"}}).run(async(W)=>{let H=wQ(Q,Z),B=W.flags.all===!0,K=B?Z.defaultScope??sQ:await iQ(W.flags.scope,Z),z=await ZQ(),J=D(),x=h(),w=await r({name:H.name,agents:[...J,...x],scope:K}),G=new Set(w.agents.filter((q)=>q.installed).map((q)=>q.agent)),N=new Set(z),M=new Map(w.agents.map((q)=>[q.agent,q])),b=x.filter((q)=>{if(N.has(q))return!0;return M.get(q)?.installed===!0}),R=b.filter((q)=>G.has(q)),T=[];if(J.length>0){let q=J[0];if(!q)throw Error("Expected at least one universal agent");let U=M.get(q)?.outputDir??"path unavailable";T.push({label:"Universal",value:n,hint:U});let V=J.map((e)=>y[e]).join(", ");console.log(g(`Agents supporting universal skills: ${V}`))}for(let q of b){let U=M.get(q)?.outputDir??"path unavailable";T.push({label:y[q],value:q,hint:U})}let _=J.length>0&&J.every((q)=>G.has(q)),k=[...R.filter((q)=>!J.includes(q))];if(_)k.unshift(n);let L;if(B)L=[...J,...b];else{let q=T.length===0?[]:await mZ({message:"Select agents to install skills for",choices:T,default:k,required:!1}),F=new Set(q.filter((U)=>U!==n));if(q.includes(n))for(let U of J)F.add(U);L=[...F]}let s=L.filter((q)=>!G.has(q)),VQ=L.filter((q)=>{let F=M.get(q);return F!==void 0&&UQ(q,K,H,F)}),v=[...G].filter((q)=>!L.includes(q)),f=[...s,...VQ];if(f.length>0)try{let q=await l({message:"Installing skills...",task:async()=>p({command:Q,meta:H,agents:f,scope:K,installMode:Z.installMode})});console.log(`
7
- ${t(`Installed "${H.name}" v${H.version}`)}`);for(let F of dQ(q.agents))console.log(g(` ${F.label} \u2192 ${F.outputDir}`))}catch(q){if(q instanceof I)if(B?!0:await cZ({message:`"${q.details.outputDir}" already exists but was not created by Crust. Overwrite?`,default:!1})){let U=await l({message:"Overwriting skill...",task:async()=>p({command:Q,meta:H,agents:[q.details.agent],scope:K,force:!0,installMode:Z.installMode})});console.log(`
8
- ${t(`Installed "${H.name}" v${H.version}`)}`);for(let V of dQ(U.agents))console.log(g(` ${V.label} \u2192 ${V.outputDir}`))}else console.log(g(`
9
- Skipped ${y[q.details.agent]}`));else throw q}if(v.length>0){let F=(await l({message:"Removing skills...",task:async()=>zQ({name:H.name,agents:v,scope:K})})).agents.filter((V)=>V.status==="removed").map((V)=>V.agent),U=FQ(F);if(U.length>0)console.log(`
10
- ${t(`Removed from ${U.join(", ")}`)}`)}if(f.length===0&&v.length===0)console.log(g("No changes."))}).command($)._node}function aZ(Q,Z){return new rQ("update").meta({description:"Update installed skills to latest version"}).flags({scope:{type:"string",description:"Update scope (project or global)"}}).run(async(X)=>{let $=await iQ(X.flags.scope,Z),W=u($),H=[...D(),...h()],B=wQ(Q,Z),z=(await r({name:B.name,agents:H,scope:$})).agents.filter((J)=>UQ(J.agent,$,B,J));if(z.length===0){console.log(g(`No updates needed (${W}).`));return}try{let x=(await l({message:`Updating ${W} skills...`,task:async()=>p({command:Q,meta:B,agents:z.map((G)=>G.agent),scope:$,installMode:Z.installMode})})).agents.filter((G)=>G.status==="updated").map((G)=>G.agent),w=FQ(x);if(w.length>0)console.log(`
11
- ${t(`Updated "${B.name}" to v${B.version} for ${w.join(", ")} (${W})`)}`)}catch(J){if(J instanceof I)console.warn(lQ(`Skipped ${y[J.details.agent]}: "${J.details.outputDir}" already exists but was not created by ${B.name}. Delete or rename the conflicting directory to resolve.`));else throw J}})}export{zQ as uninstallSkill,r as skillStatus,iZ as skillPlugin,a as resolveSkillName,P as resolveCanonicalSkillPath,cQ as isValidSkillName,XZ as isUniversalAgent,D as getUniversalAgents,h as getAdditionalAgents,p as generateSkill,ZQ as detectInstalledAgents,YZ as annotate,I as SkillConflictError};
2
+ import{accessSync as nQ,constants as tQ}from"fs";import{homedir as o}from"os";import{delimiter as eQ,join as Y}from"path";var j=Y(".agents","skills"),QZ=Y(".crust","skills");function TQ(Q){if(Q!==o())return Y(Q,".config");let Z=process.env.XDG_CONFIG_HOME?.trim();return Z&&Z.length>0?Z:Y(Q,".config")}function I(Q){return Y(Q,".agents","skills")}function ZZ(Q){return Y(Q,".crust","skills")}function c(Q){return Q==="project"&&process.cwd()===o()?"global":Q}var y={amp:{label:"Amp",class:"universal",projectSkillsDir:j,globalSkillsDir:I},adal:{label:"AdaL",class:"additional",projectSkillsDir:Y(".adal","skills"),globalSkillsDir:(Q)=>Y(Q,".adal","skills"),detectCommands:["adal"]},antigravity:{label:"Antigravity",class:"additional",projectSkillsDir:Y(".agent","skills"),globalSkillsDir:(Q)=>Y(Q,".gemini","antigravity","skills"),detectCommands:["antigravity"]},augment:{label:"Augment",class:"additional",projectSkillsDir:Y(".augment","skills"),globalSkillsDir:(Q)=>Y(Q,".augment","skills"),detectCommands:["augment"]},"claude-code":{label:"Claude Code",class:"additional",projectSkillsDir:Y(".claude","skills"),globalSkillsDir:(Q)=>Y(process.env.CLAUDE_CONFIG_DIR?.trim()||Y(Q,".claude"),"skills"),detectCommands:["claude","claude-code"]},cline:{label:"Cline",class:"universal",projectSkillsDir:j,globalSkillsDir:I},codebuddy:{label:"CodeBuddy",class:"additional",projectSkillsDir:Y(".codebuddy","skills"),globalSkillsDir:(Q)=>Y(Q,".codebuddy","skills"),detectCommands:["codebuddy"]},codex:{label:"Codex",class:"universal",projectSkillsDir:j,globalSkillsDir:I},"command-code":{label:"Command Code",class:"additional",projectSkillsDir:Y(".commandcode","skills"),globalSkillsDir:(Q)=>Y(Q,".commandcode","skills"),detectCommands:["command-code","commandcode"]},continue:{label:"Continue",class:"additional",projectSkillsDir:Y(".continue","skills"),globalSkillsDir:(Q)=>Y(Q,".continue","skills"),detectCommands:["continue"]},cortex:{label:"Cortex Code",class:"additional",projectSkillsDir:Y(".cortex","skills"),globalSkillsDir:(Q)=>Y(Q,".snowflake","cortex","skills"),detectCommands:["cortex"]},crush:{label:"Crush",class:"additional",projectSkillsDir:Y(".crush","skills"),globalSkillsDir:(Q)=>Y(TQ(Q),"crush","skills"),detectCommands:["crush"]},cursor:{label:"Cursor",class:"universal",projectSkillsDir:j,globalSkillsDir:I},droid:{label:"Droid",class:"additional",projectSkillsDir:Y(".factory","skills"),globalSkillsDir:(Q)=>Y(Q,".factory","skills"),detectCommands:["droid"]},"gemini-cli":{label:"Gemini CLI",class:"universal",projectSkillsDir:j,globalSkillsDir:I},"github-copilot":{label:"GitHub Copilot",class:"universal",projectSkillsDir:j,globalSkillsDir:I},goose:{label:"Goose",class:"additional",projectSkillsDir:Y(".goose","skills"),globalSkillsDir:(Q)=>Y(TQ(Q),"goose","skills"),detectCommands:["goose"]},"iflow-cli":{label:"iFlow CLI",class:"additional",projectSkillsDir:Y(".iflow","skills"),globalSkillsDir:(Q)=>Y(Q,".iflow","skills"),detectCommands:["iflow","iflow-cli"]},junie:{label:"Junie",class:"additional",projectSkillsDir:Y(".junie","skills"),globalSkillsDir:(Q)=>Y(Q,".junie","skills"),detectCommands:["junie"]},kilo:{label:"Kilo Code",class:"additional",projectSkillsDir:Y(".kilocode","skills"),globalSkillsDir:(Q)=>Y(Q,".kilocode","skills"),detectCommands:["kilo","kilocode"]},"kimi-cli":{label:"Kimi Code CLI",class:"universal",projectSkillsDir:j,globalSkillsDir:I},"kiro-cli":{label:"Kiro CLI",class:"additional",projectSkillsDir:Y(".kiro","skills"),globalSkillsDir:(Q)=>Y(Q,".kiro","skills"),detectCommands:["kiro","kiro-cli"]},kode:{label:"Kode",class:"additional",projectSkillsDir:Y(".kode","skills"),globalSkillsDir:(Q)=>Y(Q,".kode","skills"),detectCommands:["kode"]},mcpjam:{label:"MCPJam",class:"additional",projectSkillsDir:Y(".mcpjam","skills"),globalSkillsDir:(Q)=>Y(Q,".mcpjam","skills"),detectCommands:["mcpjam"]},"mistral-vibe":{label:"Mistral Vibe",class:"additional",projectSkillsDir:Y(".vibe","skills"),globalSkillsDir:(Q)=>Y(Q,".vibe","skills"),detectCommands:["mistral-vibe","vibe"]},mux:{label:"Mux",class:"additional",projectSkillsDir:Y(".mux","skills"),globalSkillsDir:(Q)=>Y(Q,".mux","skills"),detectCommands:["mux"]},neovate:{label:"Neovate",class:"additional",projectSkillsDir:Y(".neovate","skills"),globalSkillsDir:(Q)=>Y(Q,".neovate","skills"),detectCommands:["neovate"]},opencode:{label:"OpenCode",class:"universal",projectSkillsDir:j,globalSkillsDir:I},openclaw:{label:"OpenClaw",class:"additional",projectSkillsDir:"skills",globalSkillsDir:(Q)=>Y(Q,".openclaw","skills"),detectCommands:["openclaw"]},openhands:{label:"OpenHands",class:"additional",projectSkillsDir:Y(".openhands","skills"),globalSkillsDir:(Q)=>Y(Q,".openhands","skills"),detectCommands:["openhands"]},pi:{label:"Pi",class:"additional",projectSkillsDir:Y(".pi","skills"),globalSkillsDir:(Q)=>Y(Q,".pi","agent","skills"),detectCommands:["pi"]},pochi:{label:"Pochi",class:"additional",projectSkillsDir:Y(".pochi","skills"),globalSkillsDir:(Q)=>Y(Q,".pochi","skills"),detectCommands:["pochi"]},qoder:{label:"Qoder",class:"additional",projectSkillsDir:Y(".qoder","skills"),globalSkillsDir:(Q)=>Y(Q,".qoder","skills"),detectCommands:["qoder"]},"qwen-code":{label:"Qwen Code",class:"additional",projectSkillsDir:Y(".qwen","skills"),globalSkillsDir:(Q)=>Y(Q,".qwen","skills"),detectCommands:["qwen","qwen-code"]},replit:{label:"Replit",class:"universal",projectSkillsDir:j,globalSkillsDir:I},roo:{label:"Roo Code",class:"additional",projectSkillsDir:Y(".roo","skills"),globalSkillsDir:(Q)=>Y(Q,".roo","skills"),detectCommands:["roo","roo-code"]},trae:{label:"Trae",class:"additional",projectSkillsDir:Y(".trae","skills"),globalSkillsDir:(Q)=>Y(Q,".trae","skills"),detectCommands:["trae"]},"trae-cn":{label:"Trae CN",class:"additional",projectSkillsDir:Y(".trae","skills"),globalSkillsDir:(Q)=>Y(Q,".trae-cn","skills"),detectCommands:["trae-cn","trae"]},windsurf:{label:"Windsurf",class:"additional",projectSkillsDir:Y(".windsurf","skills"),globalSkillsDir:(Q)=>Y(Q,".codeium","windsurf","skills"),detectCommands:["windsurf"]},zencoder:{label:"Zencoder",class:"additional",projectSkillsDir:Y(".zencoder","skills"),globalSkillsDir:(Q)=>Y(Q,".zencoder","skills"),detectCommands:["zencoder"]}},m=Object.keys(y),D=Object.fromEntries(m.map((Q)=>[Q,y[Q].label]));function S(){return m.filter((Q)=>y[Q].class==="universal")}function h(){return m.filter((Q)=>y[Q].class==="additional")}function XZ(Q){return y[Q].class==="universal"}async function XQ(Q){let Z=typeof Q==="string"?{home:Q}:Q??{},X=Z.cwd??process.cwd(),$=Z.commandChecker??((H)=>Promise.resolve($Z(H))),W=[];for(let H of h()){let q=y[H].detectCommands??[],x=!1;for(let J of q)if(await $(J,X)){x=!0;break}if(x)W.push(H)}return W}function E(Q,Z,X){let $=c(Z),W=y[Q];if($==="project")return Y(process.cwd(),W.projectSkillsDir,X);return Y(W.globalSkillsDir(o()),X)}function C(Q,Z){if(c(Q)==="project")return Y(process.cwd(),QZ,Z);return Y(ZZ(o()),Z)}function $Z(Q){let X=(process.env.PATH??"").split(eQ).filter((H)=>H.length>0),$=process.platform==="win32",W=$?(process.env.PATHEXT??".EXE;.CMD;.BAT;.COM").split(";").filter((H)=>H.length>0):[];for(let H of X){if(!$&&_Q(Y(H,Q)))return!0;if($){for(let q of W)if(_Q(Y(H,Q+q)))return!0}}return!1}function _Q(Q){try{return nQ(Q,tQ.X_OK),!0}catch{return!1}}import{Crust as WZ}from"@crustjs/core";function a(Q){if(Q===void 0)return[];return(Array.isArray(Q)?Q:[Q]).flatMap((X)=>X.split(/\r?\n/)).map((X)=>X.trim()).filter((X)=>X.length>0)}function bQ(Q){let Z=Q?.trim();if(!Z)return[];return Z.split(/\r?\n/)}function $Q(Q){return Q.length>0}var OQ=Symbol("crust.skill.commandAnnotations");function HZ(Q){return Q instanceof WZ?Q._node:Q}function YZ(Q,Z){let X=HZ(Q),$=a(typeof Z==="string"||Array.isArray(Z)?Z:Z.instructions??[]);if($.length===0)return Q;let W=WQ(X)?.instructions??[],H=[...new Set([...W,...$])];return Object.defineProperty(X,OQ,{value:{instructions:H},enumerable:!0,configurable:!0}),Q}function WQ(Q){let Z=Q[OQ];if(!Z?.instructions||Z.instructions.length===0)return;return{instructions:[...Z.instructions]}}class N extends Error{name="SkillConflictError";details;constructor(Q){let Z=`Skill conflict for agent "${Q.agent}": directory "${Q.outputDir}" already exists but was not created by Crust (no crust.json found). Delete or rename the conflicting skill to resolve.`;super(Z);this.details=Q}}import{lstat as LZ,mkdir as gQ,readlink as PZ,realpath as CZ,rm as r,symlink as yZ,writeFile as DZ}from"fs/promises";import{dirname as uQ,join as AQ}from"path";function RQ(Q){return kQ(Q,[])}function kQ(Q,Z){let X=qZ(Q.meta.name),$=[...Z,X],W=BZ(Q.args),H=zZ(Q.effectiveFlags),q=xZ(Q.subCommands,$),x=WQ(Q);return{name:X,path:$,description:Q.meta.description,usage:Q.meta.usage,instructions:x?.instructions,runnable:typeof Q.run==="function",args:W,flags:H,children:q}}function qZ(Q){return Q.trim().toLowerCase()}function BZ(Q){if(!Q||Q.length===0)return[];return Q.map(JZ)}function JZ(Q){let Z={name:Q.name,type:Q.type,required:Q.required===!0,variadic:Q.variadic===!0};if(Q.description!==void 0)Z.description=Q.description;if(Q.default!==void 0)Z.default=EQ(Q.default);return Z}function zZ(Q){if(!Q)return[];return Object.keys(Q).sort().map((X)=>{return KZ(X,Q[X])})}function KZ(Q,Z){let X={name:Q,type:Z.type,required:Z.required===!0,multiple:Z.multiple===!0,short:Z.short,aliases:Z.aliases?[...Z.aliases].sort():[]};if(Z.description!==void 0)X.description=Z.description;if(Z.default!==void 0)X.default=EQ(Z.default);return X}function xZ(Q,Z){return Object.keys(Q).sort().map(($)=>{return kQ(Q[$],Z)})}function EQ(Q){if(Array.isArray(Q))return JSON.stringify(Q);return String(Q)}function d(Q){if(/[:#[\]{}&*!|>'"`,@?\\]|^\s|\s$|^---|[\n\r]/.test(Q))return`"${Q.replace(/\\/g,"\\\\").replace(/"/g,"\\\"").replace(/\n/g,"\\n").replace(/\r/g,"\\r")}"`;return Q}function jQ(Q){return Q.replace(/(?<!\\)\|/g,"\\|")}function IQ(Q,Z){let X=[],$=NQ(Q);X.push({path:"SKILL.md",content:GZ(Q,Z,$)});for(let W of $){let H=A(W),q=W.children.length>0?VZ(W,Q):UZ(W,Q);X.push({path:H,content:q})}return X}function NQ(Q){let Z=[Q];for(let X of Q.children)Z.push(...NQ(X));return Z}function A(Q){if(Q.path.length<=1)return`commands/${Q.name}.md`;return`commands/${Q.path.slice(1).join("/")}.md`}function YQ(Q){return Q.path.join(" ")}function HQ(Q,Z){let X=Q.split("/").slice(0,-1),$=Z.split("/"),W=0;while(W<X.length&&W<$.length&&X[W]===$[W])W++;let H=X.length-W,q=$.slice(W);if(H===0)return q.join("/");return[...Array.from({length:H},()=>".."),...q].join("/")}function GZ(Q,Z,X){let $=[];if($.push("---"),$.push(`name: ${d(Z.name)}`),$.push(`description: ${d(Z.description)}`),Z.license)$.push(`license: ${d(Z.license)}`);if(Z.compatibility)$.push(`compatibility: ${d(Z.compatibility)}`);if(Z.disableModelInvocation)$.push("disable-model-invocation: true");if(Z.allowedTools)$.push(`allowed-tools: ${d(Z.allowedTools)}`);if($.push("metadata:"),$.push(` version: "${Z.version}"`),$.push("---"),$.push(""),$.push(`# ${Z.name}`),$.push(""),Q.description)$.push(Q.description),$.push("");$.push(`You should use this skill when you need accurate help with \`${Z.name}\` commands, including command selection, syntax, arguments, flags, defaults, and subcommands.`),$.push("");let W=EZ(Z.instructions);if($.push("## How to Use This Skill"),$.push(""),$.push("1. You must find the command that best matches the user's task from the Command Reference below."),$.push("2. You must check the `Type` column before suggesting execution: `runnable` and `runnable, group` commands can be executed, while `group` commands are organizational only."),$.push("3. You should read only the linked file or files you need from `commands/`."),$.push("4. You must read a command's file before answering a command-specific question or suggesting that command."),$.push("5. You must treat the command file as the source of truth for usage, arguments, flags, aliases, and defaults."),$.push("6. If a flag, argument, alias, or default is not documented there, you must say it is not documented instead of guessing."),$.push(""),$Q(W))$.push("## General Guidance"),$.push(""),$.push(...W),$.push("");if($.push("## Command Reference"),$.push(""),$.push("You should use this table to locate the command file you need."),$.push(""),$.push(...FZ(X)),$.push(""),Q.runnable){$.push("## Usage"),$.push("");let H=A(Q);$.push(`The root command is directly executable. You should see [${Q.name}](${H}) for usage details.`),$.push("")}return $.join(`
3
+ `)}function FZ(Q){let Z=[];Z.push("| Command | Type | Documentation |"),Z.push("| ------- | ---- | ------------- |");for(let X of Q){let $=YQ(X),W=A(X),H=wZ(X);Z.push(`| \`${$}\` | ${H} | [${W}](${W}) |`)}return Z}function wZ(Q){if(Q.runnable&&Q.children.length>0)return"runnable, group";if(Q.runnable)return"runnable";return"group"}function UZ(Q,Z){let X=[];return X.push(...LQ(Q)),X.push(...PQ(Q)),X.push(...CQ(Q)),X.push(...DQ(Q,Z)),X.join(`
4
+ `)}function VZ(Q,Z){let X=[],$=A(Q);if(X.push(...LQ(Q)),X.push(...PQ(Q)),Q.runnable)X.push(...CQ(Q));return X.push(...TZ(Q,$)),X.push(...DQ(Q,Z)),X.join(`
5
+ `)}function MZ(Q){let Z=[...Q.path];for(let X of Q.args)if(X.variadic)Z.push(X.required?`<${X.name}...>`:`[${X.name}...]`);else Z.push(X.required?`<${X.name}>`:`[${X.name}]`);if(Q.flags.length>0)Z.push("[options]");return Z.join(" ")}function LQ(Q){let Z=[`# \`${YQ(Q)}\``,""];if(Q.description)Z.push(Q.description,"");return Z}function PQ(Q){let Z=Q.instructions??[];if(!$Q(Z))return[];return["## Command Instructions","",...yQ(Z),""]}function CQ(Q){let Z=["## Usage","","```",Q.usage??MZ(Q),"```",""];if(Q.args.length>0)Z.push("## Arguments","",..._Z(Q.args),"");if(Q.flags.length>0)Z.push("## Flags","",...OZ(Q.flags),"");return Z.push("## Command Documentation Authority","","You must treat only the arguments, flags, options, aliases, and defaults documented in this file as supported for this command.","You must not infer or invent additional command-line options.",""),Z}function TZ(Q,Z){let X=["## Subcommands",""];for(let $ of Q.children){let W=A($),H=HQ(Z,W),q=$.description?` - ${$.description}`:"";X.push(`- [\`${$.name}\`](${H})${q}`)}return X.push(""),X}function _Z(Q){let Z=[];Z.push("| Argument | Type | Required | Description |"),Z.push("| -------- | ---- | -------- | ----------- |");for(let X of Q){let $=X.variadic?`${X.name}...`:X.name,W=X.required?"Yes":"No",H=jQ(bZ(X));Z.push(`| \`${$}\` | ${X.type} | ${W} | ${H} |`)}return Z}function bZ(Q){let Z=[];if(Q.description)Z.push(Q.description);if(Q.default!==void 0)Z.push(`Default: \`${Q.default}\``);return Z.join(". ")||"-"}function OZ(Q){let Z=[];Z.push("| Flag | Type | Required | Description |"),Z.push("| ---- | ---- | -------- | ----------- |");for(let X of Q){let $=RZ(X),W=X.required?"Yes":"No",H=jQ(kZ(X));Z.push(`| ${$} | ${X.type} | ${W} | ${H} |`)}return Z}function RZ(Q){let Z=[`\`--${Q.name}\``];if(Q.short)Z.push(`\`-${Q.short}\``);for(let X of Q.aliases)Z.push(`\`--${X}\``);return Z.join(", ")}function kZ(Q){let Z=[];if(Q.description)Z.push(Q.description);if(Q.multiple)Z.push("Can be specified multiple times");if(Q.default!==void 0)Z.push(`Default: \`${Q.default}\``);return Z.join(". ")||"-"}function yQ(Q){return Q.map((Z)=>`- ${Z}`)}function EZ(Q){if(typeof Q==="string")return bQ(Q);return yQ(a(Q))}function DQ(Q,Z){let X=[],$=A(Q);if(X.push("---"),X.push(""),Q.path.length>1){let H=Q.path.slice(0,-1),q=SQ(Z,H);if(q){let x=A(q),J=HQ($,x),K=YQ(q);X.push(`Parent: [\`${K}\`](${J})`),X.push("")}}let W=HQ($,"SKILL.md");return X.push(`[Skill Overview](${W})`),X.push(""),X}function SQ(Q,Z){if(jZ(Q.path,Z))return Q;for(let X of Q.children){let $=SQ(X,Z);if($)return $}return}function jZ(Q,Z){if(Q.length!==Z.length)return!1;for(let X=0;X<Q.length;X++)if(Q[X]!==Z[X])return!1;return!0}import{readFile as IZ}from"fs/promises";import{join as NZ}from"path";var qQ="crust.json";async function v(Q){try{let Z=await IZ(NZ(Q,qQ),"utf-8"),X=JSON.parse(Z);if(typeof X==="object"&&X!==null&&"version"in X&&typeof X.version==="string")return X.version;return null}catch{return null}}var SZ="auto",cQ=/^[a-z0-9]+(-[a-z0-9]+)*$/;function mQ(Q){return Q.length>=1&&Q.length<=64&&cQ.test(Q)}function n(Q){return Q}function zQ(Q){return Q.startsWith("use-")?Q:`use-${Q}`}async function p(Q){let{command:Z,meta:X,agents:$,scope:W="global",clean:H=!0,force:q=!1,installMode:x=SZ}=Q,J=n(X.name),K=zQ(X.name);if(!mQ(J))throw Error(`Invalid skill name "${J}": must be 1\u201364 lowercase `+`alphanumeric characters and hyphens, no leading/trailing/consecutive hyphens. Pattern: ${cQ.source}`);let z=$[0];if(!z)return{agents:[]};let G={...X,name:J},F=RQ(Z),_=IQ(F,G),b=gZ(G),T=[..._,...b].sort((w,B)=>w.path<B.path?-1:w.path>B.path?1:0),O=T.map((w)=>w.path),R=new Map;for(let w of $){let B=E(w,W,G.name),U=R.get(B);if(U)U.push(w);else R.set(B,[w])}let M=C(W,G.name),L=C(W,K),u=new Map;for(let[w,B]of R){let U=B[0];if(!U)continue;u.set(w,await GQ({outputDir:w,legacyOutputDir:E(U,W,K),canonicalOutputDir:M,legacyCanonicalOutputDir:L}))}let P=await v(M);if((await xQ(M,M)).exists&&P===null&&!q)throw new N({agent:z,outputDir:M});let i=P!==G.version;if(i){if(H)await FQ(M);await dQ(M,T)}let f=[];for(let[w,B]of R){let U=B[0];if(!U)continue;let V=u.get(w);if(!V)continue;if(V.current.inspection.exists&&!V.current.isCrustManaged&&!q)throw new N({agent:U,outputDir:w});let k=await vZ({outputDir:w,canonicalOutputDir:M,allFiles:T,clean:H,installMode:x,inspection:V.current.inspection,installedVersion:V.preferredVersion,currentVersion:G.version}),QQ=await hZ(V),ZQ=AZ({installedVersion:V.preferredVersion,currentVersion:G.version,canonicalChanged:i,pathChanged:k||QQ||V.preferredOutputDir!==w});for(let aQ of B)f.push({agent:aQ,outputDir:w,files:ZQ==="up-to-date"?[]:O,status:ZQ,previousVersion:ZQ==="updated"?V.preferredVersion??void 0:void 0})}{let w=await v(L);if(L!==M&&w!==null&&!await JQ(K,W))await r(L,{recursive:!0,force:!0})}return{agents:f}}async function KQ(Q){let{name:Z,agents:X,scope:$="global"}=Q,W=n(Z),H=zQ(Z),q=C($,W),x=C($,H),J=[],K=new Map;for(let z of X){let G=E(z,$,W),F=K.get(G);if(F)F.push(z);else K.set(G,[z])}for(let[z,G]of K){let F=G[0];if(!F)continue;let _=E(F,$,H),b=await GQ({outputDir:z,legacyOutputDir:_,canonicalOutputDir:q,legacyCanonicalOutputDir:x}),T=await BQ(b.current),O=b.legacy.outputDir!==b.current.outputDir?await BQ(b.legacy):!1,R=T||O,M=T?z:O?_:z;for(let L of G)J.push({agent:L,outputDir:M,status:R?"removed":"not-found"})}if(await v(q)!==null&&!await JQ(W,$))await r(q,{recursive:!0,force:!0});{let z=await v(x);if(x!==q&&z!==null&&!await JQ(H,$))await r(x,{recursive:!0,force:!0})}return{agents:J}}async function l(Q){let{name:Z,agents:X,scope:$="global"}=Q,W=n(Z),H=zQ(Z),q=[],x=new Map;for(let J of X){let K=E(J,$,W),z=x.get(K);if(z)z.push(J);else x.set(K,[J])}for(let[J,K]of x){let z=K[0];if(!z)continue;let G=E(z,$,H),F=C($,W),_=C($,H),b=await GQ({outputDir:J,legacyOutputDir:G,canonicalOutputDir:F,legacyCanonicalOutputDir:_}),T=b.preferredOutputDir??J,O=b.preferredVersion;for(let R of K)q.push({agent:R,outputDir:T,installed:O!==null,version:O??void 0})}return{agents:q}}function AZ(Q){let{installedVersion:Z,currentVersion:X,canonicalChanged:$,pathChanged:W}=Q;if(Z===null)return"installed";if(Z===X&&!$&&!W)return"up-to-date";return"updated"}async function vZ(Q){let{outputDir:Z,canonicalOutputDir:X,allFiles:$,clean:W,installMode:H,inspection:q,installedVersion:x,currentVersion:J}=Q;if(H==="copy")return vQ({outputDir:Z,allFiles:$,clean:W,inspection:q,installedVersion:x,currentVersion:J});try{return await fZ({outputDir:Z,canonicalOutputDir:X,inspection:q})}catch(K){if(H==="symlink")throw Error(`Failed to create symlink at "${Z}" (installMode: symlink).`,{cause:K});let z=await xQ(Z,X);return vQ({outputDir:Z,allFiles:$,clean:W,inspection:z,installedVersion:x,currentVersion:J})}}async function vQ(Q){let{outputDir:Z,allFiles:X,clean:$,inspection:W,installedVersion:H,currentVersion:q}=Q;if(!(!W.exists||W.isSymlink||H!==q))return!1;if(W.isSymlink||$)await FQ(Z);return await dQ(Z,X),!0}async function fZ(Q){let{outputDir:Z,canonicalOutputDir:X,inspection:$}=Q;if($.exists&&$.isSymlink&&$.pointsToCanonical)return!1;if($.exists)await FQ(Z);return await pZ(X,Z),!0}async function xQ(Q,Z){let X;try{X=await LZ(Q)}catch{return{exists:!1,isSymlink:!1,pointsToCanonical:!1}}let $=process.platform==="win32"&&X.isDirectory()&&await pQ(Q)!==null;if(!(X.isSymbolicLink()||$))return{exists:!0,isSymlink:!1,pointsToCanonical:!1};let[H,q,x]=await Promise.all([hQ(Q),hQ(Z),pQ(Q)]);return{exists:!0,isSymlink:!0,pointsToCanonical:H!==null&&q!==null&&H===q||x===Z}}async function fQ(Q,Z){let[X,$]=await Promise.all([v(Q),xQ(Q,Z)]),W=X!==null||$.exists&&$.isSymlink&&$.pointsToCanonical;return{outputDir:Q,version:X,inspection:$,isCrustManaged:W}}async function GQ(Q){let{outputDir:Z,legacyOutputDir:X,canonicalOutputDir:$,legacyCanonicalOutputDir:W}=Q,H=await fQ(Z,$),q=X===Z?H:await fQ(X,W);if(H.isCrustManaged)return{current:H,legacy:q,preferredVersion:H.version,preferredOutputDir:H.outputDir};if(q.isCrustManaged)return{current:H,legacy:q,preferredVersion:q.version,preferredOutputDir:q.outputDir};return{current:H,legacy:q,preferredVersion:null,preferredOutputDir:null}}async function BQ(Q){if(!Q.isCrustManaged||!Q.inspection.exists)return!1;return await r(Q.outputDir,{recursive:!0,force:!0}),!0}async function hZ(Q){if(Q.legacy.outputDir===Q.current.outputDir)return!1;return BQ(Q.legacy)}async function hQ(Q){try{return await CZ(Q)}catch{return null}}async function pQ(Q){try{return await PZ(Q)}catch{return null}}async function pZ(Q,Z){await gQ(uQ(Z),{recursive:!0});let X=process.platform==="win32"?"junction":"dir";await yZ(Q,Z,X)}async function JQ(Q,Z){let X=new Set;for(let $ of m)X.add(E($,Z,Q));for(let $ of X)if(await v($)!==null)return!0;return!1}function gZ(Q){let Z={name:Q.name,description:Q.description,version:Q.version};return[{path:qQ,content:`${JSON.stringify(Z,null,"\t")}
6
+ `}]}async function FQ(Q){await r(Q,{recursive:!0,force:!0})}async function dQ(Q,Z){let X=new Set;for(let W of Z){let H=AQ(Q,W.path),q=uQ(H);X.add(q)}let $=[...X].sort();for(let W of $)await gQ(W,{recursive:!0});for(let W of Z){let H=AQ(Q,W.path);await DZ(H,W.content,"utf-8")}}import{Crust as lQ,VALIDATION_MODE_ENV as uZ}from"@crustjs/core";import{spinner as s}from"@crustjs/progress";import{confirm as cZ,multiselect as mZ,select as dZ}from"@crustjs/prompts";import{bold as e,dim as g,yellow as sQ}from"@crustjs/style";var rZ="skill",iQ="global",t="__universal__";function lZ(Q){return Q==="global"||Q==="project"}async function oQ(Q,Z){if(Q!==void 0){if(!lZ(Q))throw Error(`Invalid --scope value: ${String(Q)}. Expected "project" or "global".`);return Q}if(Z.defaultScope)return Z.defaultScope;return dZ({message:"Select scope",choices:[{label:"Project",value:"project"},{label:"Global",value:"global"}],default:iQ})}function wQ(Q){let Z=new Set(S()),X=[];if(Q.some(($)=>Z.has($)))X.push("Universal");for(let $ of Q){if(Z.has($))continue;X.push(D[$])}return X}function rQ(Q){let Z=new Set(S()),X=[],$=Q.find((W)=>Z.has(W.agent));if($)X.push({label:"Universal",outputDir:$.outputDir});for(let W of Q){if(Z.has(W.agent))continue;X.push({label:D[W.agent],outputDir:W.outputDir})}return X}function UQ(Q,Z){return{name:Q.meta.name,description:Q.meta.description??"",version:Z.version,instructions:Z.instructions,license:Z.license,allowedTools:Z.allowedTools,compatibility:Z.compatibility,disableModelInvocation:Z.disableModelInvocation}}function VQ(Q,Z,X,$){if(!$.installed)return!1;let W=E(Q,Z,X.name);return $.version!==X.version||$.outputDir!==W}async function sZ(Q,Z){let X=[...S(),...h()];if(X.length===0)return;let $=UQ(Q,Z),W=[...new Set(["project","global"].map((H)=>c(H)))];for(let H of W){let x=(await l({name:$.name,agents:X,scope:H})).agents.filter((J)=>VQ(J.agent,H,$,J));if(x.length===0)continue;try{await s({message:`Updating ${H} skills...`,task:async({updateMessage:J})=>{let K=await p({command:Q,meta:$,agents:x.map((F)=>F.agent),scope:H,installMode:Z.installMode}),z=K.agents.filter((F)=>F.status==="updated").map((F)=>F.agent),G=wQ(z);if(G.length>0)J(`Updated skill "${$.name}" to v${$.version} for ${G.join(", ")} (${H})`);return K}})}catch(J){if(J instanceof N)console.warn(sQ(`Skill conflict: "${J.details.outputDir}" already exists but was not created by ${$.name}. Skipping auto-update for ${H}. Delete or rename the conflicting skill to resolve.`));else throw J}}}function iZ(Q){let Z;return{name:"skills",async setup(X,$){Z=X.rootCommand;let W=Q.command??rZ;if($.addSubCommand(Z,W,oZ(Z,Q,W)),process.env[uZ]==="1")return;if(X.argv[0]===W)return;if(Q.autoUpdate!==!1)await sZ(Z,Q)}}}function oZ(Q,Z,X){let $=aZ(Q,Z);return new lQ(X).meta({description:"Manage agent skill installations"}).flags({scope:{type:"string",description:"Install scope (project or global)"},all:{type:"boolean",description:"Install for all detected agents non-interactively (universal + detected)"}}).run(async(W)=>{let H=UQ(Q,Z),q=W.flags.all===!0,x=!!process.stdin.isTTY,J=q?Z.defaultScope??iQ:await oQ(W.flags.scope,Z),K=await XQ(),z=S(),G=h(),F=await l({name:H.name,agents:[...z,...G],scope:J}),_=new Set(F.agents.filter((B)=>B.installed).map((B)=>B.agent)),b=new Set(K),T=new Map(F.agents.map((B)=>[B.agent,B])),O=G.filter((B)=>{if(b.has(B))return!0;return T.get(B)?.installed===!0}),R=O.filter((B)=>_.has(B)),M=[];if(z.length>0){let B=z[0];if(!B)throw Error("Expected at least one universal agent");let V=T.get(B)?.outputDir??"path unavailable";M.push({label:"Universal",value:t,hint:V});let k=z.map((QQ)=>D[QQ]).join(", ");if(x&&!q)console.log(g(`Agents supporting universal skills: ${k}`))}for(let B of O){let V=T.get(B)?.outputDir??"path unavailable";M.push({label:D[B],value:B,hint:V})}let L=z.length>0&&z.every((B)=>_.has(B)),u=[...R.filter((B)=>!z.includes(B))];if(L)u.unshift(t);let P;if(q)P=[...z,...O];else{let B=M.length===0?[]:await mZ({message:"Select agents to install skills for",choices:M,default:u,required:!1}),U=new Set(B.filter((V)=>V!==t));if(B.includes(t))for(let V of z)U.add(V);P=[...U]}let MQ=P.filter((B)=>!_.has(B)),i=P.filter((B)=>{let U=T.get(B);return U!==void 0&&VQ(B,J,H,U)}),f=[..._].filter((B)=>!P.includes(B)),w=[...MQ,...i];if(w.length>0)try{let B=await s({message:"Installing skills...",task:async()=>p({command:Q,meta:H,agents:w,scope:J,installMode:Z.installMode})});console.log(`
7
+ ${e(`Installed "${H.name}" v${H.version}`)}`);for(let U of rQ(B.agents))console.log(g(` ${U.label} \u2192 ${U.outputDir}`))}catch(B){if(B instanceof N)if(q?!0:await cZ({message:`"${B.details.outputDir}" already exists but was not created by Crust. Overwrite?`,default:!1})){let V=await s({message:"Overwriting skill...",task:async()=>p({command:Q,meta:H,agents:[B.details.agent],scope:J,force:!0,installMode:Z.installMode})});console.log(`
8
+ ${e(`Installed "${H.name}" v${H.version}`)}`);for(let k of rQ(V.agents))console.log(g(` ${k.label} \u2192 ${k.outputDir}`))}else console.log(g(`
9
+ Skipped ${D[B.details.agent]}`));else throw B}if(f.length>0){let U=(await s({message:"Removing skills...",task:async()=>KQ({name:H.name,agents:f,scope:J})})).agents.filter((k)=>k.status==="removed").map((k)=>k.agent),V=wQ(U);if(V.length>0)console.log(`
10
+ ${e(`Removed from ${V.join(", ")}`)}`)}if(w.length===0&&f.length===0)console.log(g("No changes."))}).command($)._node}function aZ(Q,Z){return new lQ("update").meta({description:"Update installed skills to latest version"}).flags({scope:{type:"string",description:"Update scope (project or global)"}}).run(async(X)=>{let $=await oQ(X.flags.scope,Z),W=c($),H=[...S(),...h()],q=UQ(Q,Z),J=(await l({name:q.name,agents:H,scope:$})).agents.filter((K)=>VQ(K.agent,$,q,K));if(J.length===0){console.log(g(`No updates needed (${W}).`));return}try{let z=(await s({message:`Updating ${W} skills...`,task:async()=>p({command:Q,meta:q,agents:J.map((F)=>F.agent),scope:$,installMode:Z.installMode})})).agents.filter((F)=>F.status==="updated").map((F)=>F.agent),G=wQ(z);if(G.length>0)console.log(`
11
+ ${e(`Updated "${q.name}" to v${q.version} for ${G.join(", ")} (${W})`)}`)}catch(K){if(K instanceof N)console.warn(sQ(`Skipped ${D[K.details.agent]}: "${K.details.outputDir}" already exists but was not created by ${q.name}. Delete or rename the conflicting directory to resolve.`));else throw K}})}export{KQ as uninstallSkill,l as skillStatus,iZ as skillPlugin,n as resolveSkillName,C as resolveCanonicalSkillPath,mQ as isValidSkillName,XZ as isUniversalAgent,S as getUniversalAgents,h as getAdditionalAgents,p as generateSkill,XQ as detectInstalledAgents,YZ as annotate,N as SkillConflictError};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@crustjs/skills",
3
- "version": "0.0.21",
3
+ "version": "0.0.23",
4
4
  "description": "Agent skill generation from Crust command definitions",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -43,16 +43,17 @@
43
43
  "publish": "bun publish --no-git-checks || true"
44
44
  },
45
45
  "dependencies": {
46
- "@crustjs/prompts": "0.0.10",
46
+ "@crustjs/progress": "0.0.2",
47
+ "@crustjs/prompts": "0.0.12",
47
48
  "@crustjs/style": "0.0.6"
48
49
  },
49
50
  "devDependencies": {
50
51
  "@crustjs/config": "0.0.0",
51
- "@crustjs/core": "0.0.15",
52
+ "@crustjs/core": "0.0.16",
52
53
  "bunup": "^0.16.31"
53
54
  },
54
55
  "peerDependencies": {
55
- "@crustjs/core": "0.0.15",
56
- "typescript": "^5"
56
+ "@crustjs/core": "0.0.16",
57
+ "typescript": "^6.0.2"
57
58
  }
58
59
  }