skillcraft 0.1.4 → 0.1.5

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/dist/index.js CHANGED
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env node
2
- import{Command as fo}from"commander";var et={name:"skillcraft",version:"0.1.4",description:"Turn your work into verifiable AI credentials. Capture what you build, share your progress, and earn verifiable credentials that prove measurable real-world AI engineering work.",keywords:["skillcraft","cli","ai","evidence","credentials","skills","loadout","git","verification","developer-tools"],repository:{type:"git",url:"git+https://github.com/skillcraft-gg/skillcraft.git"},homepage:"https://skillcraft.gg",bugs:{url:"https://github.com/skillcraft-gg/skillcraft/issues"},type:"module",bin:{skillcraft:"dist/index.js"},files:["dist/index.js","dist/index.js.map","README.md","LICENSE"],scripts:{build:"tsup",clean:"rm -rf dist",test:"npm run build && node --test tests/*.test.mjs",smoke:"npm test",format:"printf ''",start:"node dist/index.js",check:"tsc --noEmit",prepublishOnly:"npm run build"},publishConfig:{access:"public"},dependencies:{commander:"^13.1.0",ora:"^8.2.0",yaml:"^2.6.0",zod:"^3.24.2"},devDependencies:{"@types/node":"^24.8.0",tsup:"^8.5.0",typescript:"^5.7.2"}};import{execFile as $r}from"child_process";import{promisify as Er}from"util";import tt from"path";var rt=Er($r);async function h(e,t,r={}){try{let{stdout:n}=await rt("git",e,{cwd:t,encoding:"utf8",maxBuffer:10485760,env:r.env});return n.trim()}catch(n){let o=n.message??String(n);throw new Error(`git command failed in ${t}: ${o}`)}}async function q(e){try{return await h(["rev-parse","--git-dir"],e),!0}catch{return!1}}async function te(e){return tt.resolve(await h(["rev-parse","--show-toplevel"],e))}async function M(e,t="origin"){try{return await h(["config","--get",`remote.${t}.url`],e)||void 0}catch{return}}async function nt(e,t="HEAD"){return h(["log","--format=%B","-n","1",t],e)}async function re(e){return(await h(["rev-parse","HEAD"],e)).trim()}async function z(e,t){try{return await h(["show-ref","--verify","--quiet",t],e),!0}catch{return!1}}async function ot(e,t,r){try{let n=await h(["ls-tree","-r","--name-only",t,"--",...r?[r]:[]],e);return n?n.split(`
2
+ import{Command as fo}from"commander";var et={name:"skillcraft",version:"0.1.5",description:"Turn your work into verifiable AI credentials. Capture what you build, share your progress, and earn verifiable credentials that prove measurable real-world AI engineering work.",keywords:["skillcraft","cli","ai","evidence","credentials","skills","loadout","git","verification","developer-tools"],repository:{type:"git",url:"git+https://github.com/skillcraft-gg/skillcraft.git"},homepage:"https://skillcraft.gg",bugs:{url:"https://github.com/skillcraft-gg/skillcraft/issues"},type:"module",bin:{skillcraft:"dist/index.js"},files:["dist/index.js","dist/index.js.map","README.md","LICENSE"],scripts:{build:"tsup",clean:"rm -rf dist",test:"npm run build && node --test tests/*.test.mjs",smoke:"npm test",format:"printf ''",start:"node dist/index.js",check:"tsc --noEmit",prepublishOnly:"npm run build"},publishConfig:{access:"public"},dependencies:{commander:"^13.1.0",ora:"^8.2.0",yaml:"^2.6.0",zod:"^3.24.2"},devDependencies:{"@types/node":"^24.8.0",tsup:"^8.5.0",typescript:"^5.7.2"}};import{execFile as $r}from"child_process";import{promisify as Er}from"util";import tt from"path";var rt=Er($r);async function h(e,t,r={}){try{let{stdout:n}=await rt("git",e,{cwd:t,encoding:"utf8",maxBuffer:10485760,env:r.env});return n.trim()}catch(n){let o=n.message??String(n);throw new Error(`git command failed in ${t}: ${o}`)}}async function F(e){try{return await h(["rev-parse","--git-dir"],e),!0}catch{return!1}}async function te(e){return tt.resolve(await h(["rev-parse","--show-toplevel"],e))}async function z(e,t="origin"){try{return await h(["config","--get",`remote.${t}.url`],e)||void 0}catch{return}}async function nt(e,t="HEAD"){return h(["log","--format=%B","-n","1",t],e)}async function re(e){return(await h(["rev-parse","HEAD"],e)).trim()}async function D(e,t){try{return await h(["show-ref","--verify","--quiet",t],e),!0}catch{return!1}}async function ot(e,t,r){try{let n=await h(["ls-tree","-r","--name-only",t,"--",...r?[r]:[]],e);return n?n.split(`
3
3
  `).filter(Boolean):[]}catch{return[]}}async function it(e,t,r){try{return await h(["show",`${t}:${r}`],e)}catch{return}}async function pe(e,t){let r=t?String(t):"200",n=await h(["log",`--max-count=${r}`,"--pretty=%H%x00%B"],e);return n?n.split("\0").filter(Boolean).map(o=>{let[i,...s]=o.split(`
4
4
  `),c=s.join(`
5
5
  `).trimEnd();return{commit:i,message:c}}):[]}async function st(e,t){let r={...process.env,SKILLCRAFT_HOOK_DISABLED:"1"},n=tt.join(e,".git","SKILLCRAFT_COMMIT_MESSAGE"),{writeFile:o}=await import("fs/promises");return await o(n,`${t}
6
- `,"utf8"),await rt("git",["commit","--amend","--file",n,"--no-gpg-sign"],{cwd:e,encoding:"utf8",env:r}),re(e)}import xo from"fs/promises";import k from"path";import Ir from"os";function Ar(){return k.resolve(process.env.HOME||Ir.homedir(),".skillcraft")}function E(){return Ar()}function Ee(){return k.join(E(),"config.json")}function Ie(){return k.join(E(),"repos.json")}function Ae(){return k.join(E(),"credentials.json")}function at(){return k.join(E(),"cache","credentials","index.json")}function Lr(e){return k.join(e,".skillcraft")}function I(e){return k.join(e,".git","skillcraft")}function A(e){return k.join(Lr(e),".skillcraft.json")}function J(e){return k.join(e,".git","hooks","post-commit")}function fe(e){return k.join(e,".git","hooks","pre-push")}function ge(e){return k.join(e,".git","hooks","post-push")}function L(e){return k.join(I(e),"pending.json")}function R(e){return k.join(I(e),"context.json")}function he(e){return k.join(I(e),"agent.json")}function le(e){return k.join(e,".opencode","plugins","skillcraft.mjs")}function ne(e){return k.join(I(e),"ai-model-context.json")}import ue from"fs/promises";import jr from"path";async function C(e){await ue.mkdir(e,{recursive:!0})}async function Nr(e){return await ue.readFile(e,"utf8")}async function W(e,t){await C(jr.dirname(e)),await ue.writeFile(e,t,"utf8")}async function $(e){try{return await ue.access(e),!0}catch{return!1}}async function v(e){if(!await $(e))return null;let t=await Nr(e);return JSON.parse(t)}async function y(e,t){let r=JSON.stringify(t,null,2);await W(e,`${r}
7
- `)}async function F(e){try{await ue.rm(e,{force:!0})}catch{}}import oe from"fs/promises";function Le(e){let t=process.argv[1]||"skillcraft";return`#!/usr/bin/env sh
6
+ `,"utf8"),await rt("git",["commit","--amend","--file",n,"--no-gpg-sign"],{cwd:e,encoding:"utf8",env:r}),re(e)}import xo from"fs/promises";import k from"path";import Ir from"os";function Ar(){return k.resolve(process.env.HOME||Ir.homedir(),".skillcraft")}function E(){return Ar()}function Ee(){return k.join(E(),"config.json")}function Ie(){return k.join(E(),"repos.json")}function Ae(){return k.join(E(),"credentials.json")}function at(){return k.join(E(),"cache","credentials","index.json")}function Lr(e){return k.join(e,".skillcraft")}function I(e){return k.join(e,".git","skillcraft")}function A(e){return k.join(Lr(e),".skillcraft.json")}function J(e){return k.join(e,".git","hooks","post-commit")}function fe(e){return k.join(e,".git","hooks","pre-push")}function ge(e){return k.join(e,".git","hooks","post-push")}function L(e){return k.join(I(e),"pending.json")}function R(e){return k.join(I(e),"context.json")}function he(e){return k.join(I(e),"agent.json")}function le(e){return k.join(e,".opencode","plugins","skillcraft.mjs")}function ne(e){return k.join(I(e),"ai-model-context.json")}import ue from"fs/promises";import jr from"path";async function C(e){await ue.mkdir(e,{recursive:!0})}async function qr(e){return await ue.readFile(e,"utf8")}async function W(e,t){await C(jr.dirname(e)),await ue.writeFile(e,t,"utf8")}async function $(e){try{return await ue.access(e),!0}catch{return!1}}async function v(e){if(!await $(e))return null;let t=await qr(e);return JSON.parse(t)}async function y(e,t){let r=JSON.stringify(t,null,2);await W(e,`${r}
7
+ `)}async function _(e){try{await ue.rm(e,{force:!0})}catch{}}import oe from"fs/promises";function Le(e){let t=process.argv[1]||"skillcraft";return`#!/usr/bin/env sh
8
8
  if [ -n "$SKILLCRAFT_HOOK_DISABLED" ]; then
9
9
  exit 0
10
10
  fi
@@ -15,17 +15,17 @@ SKILLCRAFT_CLI=${JSON.stringify(t)}
15
15
  unset GIT_INDEX_FILE
16
16
 
17
17
  ${e}
18
- `}var qr=Le('"$SKILLCRAFT_CLI" _hook post-commit "$SKILLCRAFT_HOOK_DIR" || true'),Fr=Le(`SKILLCRAFT_HOOK_REMOTE="$1"
18
+ `}var Nr=Le('"$SKILLCRAFT_CLI" _hook post-commit "$SKILLCRAFT_HOOK_DIR" || true'),Fr=Le(`SKILLCRAFT_HOOK_REMOTE="$1"
19
19
  "$SKILLCRAFT_CLI" _hook post-push "$SKILLCRAFT_HOOK_DIR" "$SKILLCRAFT_HOOK_REMOTE" || true`),_r=Le(`SKILLCRAFT_HOOK_REMOTE="$1"
20
- "$SKILLCRAFT_CLI" _hook post-push "$SKILLCRAFT_HOOK_DIR" "$SKILLCRAFT_HOOK_REMOTE" || true`);async function ct(e){await W(J(e),`${qr}
20
+ "$SKILLCRAFT_CLI" _hook post-push "$SKILLCRAFT_HOOK_DIR" "$SKILLCRAFT_HOOK_REMOTE" || true`);async function ct(e){await W(J(e),`${Nr}
21
21
  `),await oe.chmod(J(e),493),await W(ge(e),`${Fr}
22
22
  `),await oe.chmod(ge(e),493),await W(fe(e),`${_r}
23
- `),await oe.chmod(fe(e),493)}async function dt(e){await Promise.all([oe.rm(J(e),{force:!0}),oe.rm(ge(e),{force:!0}),oe.rm(fe(e),{force:!0})])}import{z as g}from"zod";var No=g.literal(1),G="skillcraft/proofs/v1",lt=g.object({skills:g.array(g.string()).default([])}),ut=g.object({activeLoadouts:g.array(g.string()).default([])}),qo=g.object({provider:g.string().optional()}),Fo=g.object({provider:g.string().optional(),name:g.string().optional()}),V=g.object({githubUser:g.string().optional(),provider:g.enum(["gh"]).default("gh"),version:g.number().int().default(1),proofRef:g.string().default(G)}),Tr=g.object({path:g.string(),remote:g.string().optional(),enabledAt:g.string().optional()}),mt=g.object({repos:g.array(Tr).default([])}),Or=g.object({id:g.string(),trackedAt:g.string().optional()}),pt=g.object({credentials:g.array(Or).default([])});async function j(){let e=await v(Ee()),t=V.safeParse(e??{});return t.success?t.data:V.parse({})}async function we(e){let t=await v(A(e)),r=V.safeParse(t??{});return r.success?r.data:V.parse({})}async function ft(e){await C(E()),await y(Ee(),e)}async function _(){let e=await v(Ie()),t=mt.safeParse(e??{});return t.success?t.data:{repos:[]}}async function ye(e){await C(E()),await y(Ie(),e)}async function gt(e){let r=(await _()).repos.filter(n=>n.path!==e.path);r.push(e),await ye({repos:r})}async function ht(e){let r=(await _()).repos.filter(n=>n.path!==e);await ye({repos:r})}async function ke(){let e=await v(Ae()),t=pt.safeParse(e??{});return t.success?t.data:{credentials:[]}}async function wt(e){await C(E()),await y(Ae(),e)}async function yt(e){let t=await ke();return t.credentials.some(r=>r.id===e)?!1:(t.credentials.push({id:e,trackedAt:new Date().toISOString()}),t.credentials.sort(Mr),await wt(t),!0)}async function kt(e){let t=await ke(),r=t.credentials.length,n=t.credentials.filter(o=>o.id!==e);return n.length===r?!1:(await wt({credentials:n}),!0)}function Mr(e,t){return e.id.localeCompare(t.id)}async function vt(){let e=process.cwd();if(!await q(e))throw new Error("Current directory is not a git repository");let t=await te(e);await Promise.all([F(A(t)),F(L(t)),F(R(t)),F(he(t)),F(le(t)),F(ne(t)),F(I(t))]),await dt(t),await ht(t),process.stdout.write(`disabled skillcraft for ${t}
24
- `)}import{createHash as Br}from"crypto";import xe from"path";import Jr from"os";import bt from"fs/promises";var zr=/^[a-zA-Z0-9][a-zA-Z0-9._-]*\/[a-zA-Z0-9][a-zA-Z0-9._-]*(?:@[^\s/]+)?$/,Dr=/^[a-zA-Z0-9][a-zA-Z0-9._-]*\/[a-zA-Z0-9][a-zA-Z0-9._-]*$/,Hr=/^([a-zA-Z0-9][a-zA-Z0-9._-]*):([a-zA-Z0-9][a-zA-Z0-9._-]*)(?:\/([a-zA-Z0-9][a-zA-Z0-9._-]*))?$/;function xt(e){let t=D(e);if(t.id)return`${t.id}${t.version?`@${t.version}`:""}`}function je(e){return zr.test(e)}function Ne(e){return!!D(e).id}function D(e){let t=e.trim(),r=Ur(t),n=r.id||"";if(Kr(n)){let[a,u]=n.split("/");return{id:n,owner:a,slug:u,version:r.version}}let o=Hr.exec(n);if(!o)return{id:"",slug:"",version:r.version};let i=o[1],s=o[2],c=o[3];return c===void 0?{id:`${i}:${s}`,source:i,slug:s,version:r.version}:{id:`${i}:${s}/${c}`,source:i,owner:s,slug:c,version:r.version}}function Kr(e){return Dr.test(e)}function T(e,t){let r=e.trim();if(!r)throw new Error(`Expected ${t} to be provided`);return r}function Ur(e){let t=e.split("@"),r=t[0]||"",n=t.length>1?t.slice(1).join("@"):void 0;return{id:r,version:n}}function ve(e){let[t,r]=e.split("/");if(!t||!r)throw new Error(`Expected <owner>/<slug>, received ${e}`);return{owner:t,slug:r.trim()}}var qe="proofs";function Rt(e){return(e?.trim()||G).replace(/^refs\/heads\//,"")}function Ct(e){return`${qe}/${e}.json`}async function Pe(e){let t=await we(e);return Rt(t.proofRef)}async function St(e,t){let r=Rt(t),n=`refs/heads/${r}`,o=`refs/remotes/origin/${r}`,i=[];return await z(e,n)&&i.push(r),await z(e,o)&&i.push(`origin/${r}`),i.length||i.push(r),i}async function Wr(e,t){let r=`refs/heads/${t}`;await z(e,r)||await h(["branch",t],e)}async function Gr(e,t,r){await Vr(e,t);let n=await bt.mkdtemp(xe.join(Jr.tmpdir(),"skillcraft-proof-"));try{return await h(["worktree","add","--quiet",n,t],e),await r(n)}finally{await $t(e,n)}}async function $t(e,t){try{await h(["worktree","remove","--force",t],e)}catch{await bt.rm(t,{force:!0,recursive:!0})}}async function Vr(e,t){let r=`refs/heads/${t}`;try{let o=(await h(["worktree","list","--porcelain"],e)).split(`
25
- `),i,s,c=async()=>{!i||s!==r||await $t(e,i)};for(let a of o){if(!a){i=void 0,s=void 0;continue}if(a.startsWith("worktree ")){await c(),i=a.slice(9),s=void 0;continue}a.startsWith("branch ")&&(s=a.slice(7))}await c()}catch{return}}async function Fe(e){let t=await Pe(e),r=await St(e,t),n=new Set;for(let i of r){let s=await ot(e,i,qe);for(let c of s)n.add(c)}let o=[];for(let i of n){if(!i.endsWith(".json"))continue;let s=xe.basename(i,".json"),c=await _e(e,s);c&&o.push(c)}return o}function Zr(e){let t=D(e);if(t.id&&Ne(t.id))return{id:t.id,version:t.version}}function be(e){let t=e.filter(Boolean).map(r=>D(r)).filter(r=>!!r.id).map(r=>`${r.id}${r.version?`@${r.version}`:""}`);return Array.from(new Set(t)).filter(Ne).sort()}function Et(e,t,r){let n={skills:e,loadouts:r,timestamp:t};return Br("sha256").update(JSON.stringify(n)).digest("hex").slice(0,8)}async function ie(e){let t=await v(L(e)),r=lt.safeParse(t??{skills:[]});return r.success?be(r.data.skills):[]}async function Xr(e){let t=await v(R(e)),r=ut.safeParse(t??{activeLoadouts:[]});return r.success?r.data.activeLoadouts:[]}async function Yr(e){let t=await v(ne(e));if(!t||typeof t!="object"||Array.isArray(t))return{};let r=t,n=r.agent&&typeof r.agent=="object"&&!Array.isArray(r.agent)?r.agent:void 0,o=r.model&&typeof r.model=="object"&&!Array.isArray(r.model)?r.model:void 0;return{agent:typeof n?.provider=="string"?{provider:Pt(n.provider)}:void 0,model:typeof o?.provider=="string"||typeof o?.name=="string"?{provider:typeof o.provider=="string"?Pt(o.provider):void 0,name:typeof o.name=="string"?Qr(o.name):void 0}:void 0}}function Pt(e){return e.trim().toLowerCase()}function Qr(e){return e.trim()}function en(e){if(!e||typeof e!="object")return;let t=e;if(typeof t.version!="number"||typeof t.commit!="string"||!Array.isArray(t.skills)||!t.timestamp||typeof t.timestamp!="string")return;let r=Array.isArray(t.loadouts)?t.loadouts.map(String):[],n=t.skills.map(o=>{if(typeof o=="string")return{id:o};if(o&&typeof o=="object"&&"id"in o&&typeof o.id=="string")return{id:o.id,version:typeof o.version=="string"?o.version:void 0}}).filter(o=>!!o);return{version:t.version,commit:t.commit,skills:n,loadouts:r,timestamp:t.timestamp,agent:tn(t.agent),model:rn(t.model)}}function tn(e){if(!e||typeof e!="object"||Array.isArray(e))return;let t=e.provider;if(typeof t!="string")return;let r=t.trim().toLowerCase();return r?{provider:r}:void 0}function rn(e){if(!e||typeof e!="object"||Array.isArray(e))return;let t=e,r=typeof t.provider=="string"?t.provider.trim().toLowerCase():void 0,n=typeof t.name=="string"?t.name.trim():void 0;if(!(!r&&!n))return{provider:r,name:n}}async function _e(e,t){let r=await Pe(e),n=Ct(t),o=await St(e,r);for(let i of o){let s=await it(e,i,n);if(!s)continue;let c;try{c=JSON.parse(s)}catch{continue}let a=en(c);if(a)return a}}async function Te(e,t){let r=Et(t.skills.map(i=>i.id),t.timestamp,t.loadouts),n=await Pe(e);await Wr(e,n);let o=Ct(r);return await Gr(e,n,async i=>{await C(xe.join(i,qe)),await y(xe.join(i,o),t),await h(["add",o],i,{env:{...process.env,SKILLCRAFT_HOOK_DISABLED:"1"}}),await h(["status","--porcelain","--",o],i,{env:{...process.env,SKILLCRAFT_HOOK_DISABLED:"1"}})&&await h(["commit","--no-gpg-sign","-m",`add Skillcraft proof ${r}`],i,{env:{...process.env,SKILLCRAFT_HOOK_DISABLED:"1"}})}),r}async function It(e,t="origin"){let r=await Pe(e);if(!(!await M(e,t)||!t))try{await h(["push",t,`${r}:${r}`],e,{env:{...process.env,SKILLCRAFT_HOOK_DISABLED:"1"}})}catch{return}}async function At(e,t){let r=await Fe(e);for(let n of r)if(n.commit===t)return Et(n.skills.map(o=>o.id),n.timestamp,n.loadouts)}async function Lt(e,t,r=new Date().toISOString()){let n=await ie(e),o=await Xr(e),i=await Yr(e),s=n.map(u=>Zr(u)).filter(u=>!!u),c={version:1,commit:t,skills:s,loadouts:o,timestamp:r,...i};return{proofId:await Te(e,c),proof:c}}async function nn(e){return e.replace(/\nSkillcraft-Ref: .*$/gm,"").trimEnd()}async function jt(e,t){let r=await nt(e),n=await nn(r);return n.includes("Skillcraft-Ref:")?n:`${n}
23
+ `),await oe.chmod(fe(e),493)}async function dt(e){await Promise.all([oe.rm(J(e),{force:!0}),oe.rm(ge(e),{force:!0}),oe.rm(fe(e),{force:!0})])}import{z as g}from"zod";var qo=g.literal(1),G="skillcraft/proofs/v1",lt=g.object({skills:g.array(g.string()).default([])}),ut=g.object({activeLoadouts:g.array(g.string()).default([])}),No=g.object({provider:g.string().optional()}),Fo=g.object({provider:g.string().optional(),name:g.string().optional()}),V=g.object({githubUser:g.string().optional(),provider:g.enum(["gh"]).default("gh"),version:g.number().int().default(1),proofRef:g.string().default(G)}),Tr=g.object({path:g.string(),remote:g.string().optional(),enabledAt:g.string().optional()}),mt=g.object({repos:g.array(Tr).default([])}),Or=g.object({id:g.string(),trackedAt:g.string().optional()}),pt=g.object({credentials:g.array(Or).default([])});async function j(){let e=await v(Ee()),t=V.safeParse(e??{});return t.success?t.data:V.parse({})}async function we(e){let t=await v(A(e)),r=V.safeParse(t??{});return r.success?r.data:V.parse({})}async function ft(e){await C(E()),await y(Ee(),e)}async function T(){let e=await v(Ie()),t=mt.safeParse(e??{});return t.success?t.data:{repos:[]}}async function ye(e){await C(E()),await y(Ie(),e)}async function gt(e){let r=(await T()).repos.filter(n=>n.path!==e.path);r.push(e),await ye({repos:r})}async function ht(e){let r=(await T()).repos.filter(n=>n.path!==e);await ye({repos:r})}async function ke(){let e=await v(Ae()),t=pt.safeParse(e??{});return t.success?t.data:{credentials:[]}}async function wt(e){await C(E()),await y(Ae(),e)}async function yt(e){let t=await ke();return t.credentials.some(r=>r.id===e)?!1:(t.credentials.push({id:e,trackedAt:new Date().toISOString()}),t.credentials.sort(Mr),await wt(t),!0)}async function kt(e){let t=await ke(),r=t.credentials.length,n=t.credentials.filter(o=>o.id!==e);return n.length===r?!1:(await wt({credentials:n}),!0)}function Mr(e,t){return e.id.localeCompare(t.id)}async function vt(){let e=process.cwd();if(!await F(e))throw new Error("Current directory is not a git repository");let t=await te(e);await Promise.all([_(A(t)),_(L(t)),_(R(t)),_(he(t)),_(le(t)),_(ne(t)),_(I(t))]),await dt(t),await ht(t),process.stdout.write(`disabled skillcraft for ${t}
24
+ `)}import{createHash as Br}from"crypto";import xe from"path";import Jr from"os";import bt from"fs/promises";var zr=/^[a-zA-Z0-9][a-zA-Z0-9._-]*\/[a-zA-Z0-9][a-zA-Z0-9._-]*(?:@[^\s/]+)?$/,Dr=/^[a-zA-Z0-9][a-zA-Z0-9._-]*\/[a-zA-Z0-9][a-zA-Z0-9._-]*$/,Hr=/^([a-zA-Z0-9][a-zA-Z0-9._-]*):([a-zA-Z0-9][a-zA-Z0-9._-]*)(?:\/([a-zA-Z0-9][a-zA-Z0-9._-]*))?$/;function xt(e){let t=H(e);if(t.id)return`${t.id}${t.version?`@${t.version}`:""}`}function je(e){return zr.test(e)}function qe(e){return!!H(e).id}function H(e){let t=e.trim(),r=Ur(t),n=r.id||"";if(Kr(n)){let[a,u]=n.split("/");return{id:n,owner:a,slug:u,version:r.version}}let o=Hr.exec(n);if(!o)return{id:"",slug:"",version:r.version};let i=o[1],s=o[2],c=o[3];return c===void 0?{id:`${i}:${s}`,source:i,slug:s,version:r.version}:{id:`${i}:${s}/${c}`,source:i,owner:s,slug:c,version:r.version}}function Kr(e){return Dr.test(e)}function O(e,t){let r=e.trim();if(!r)throw new Error(`Expected ${t} to be provided`);return r}function Ur(e){let t=e.split("@"),r=t[0]||"",n=t.length>1?t.slice(1).join("@"):void 0;return{id:r,version:n}}function ve(e){let[t,r]=e.split("/");if(!t||!r)throw new Error(`Expected <owner>/<slug>, received ${e}`);return{owner:t,slug:r.trim()}}var Ne="proofs";function Rt(e){return(e?.trim()||G).replace(/^refs\/heads\//,"")}function Ct(e){return`${Ne}/${e}.json`}async function Pe(e){let t=await we(e);return Rt(t.proofRef)}async function St(e,t){let r=Rt(t),n=`refs/heads/${r}`,o=`refs/remotes/origin/${r}`,i=[];return await D(e,n)&&i.push(r),await D(e,o)&&i.push(`origin/${r}`),i.length||i.push(r),i}async function Wr(e,t){let r=`refs/heads/${t}`;await D(e,r)||await h(["branch",t],e)}async function Gr(e,t,r){await Vr(e,t);let n=await bt.mkdtemp(xe.join(Jr.tmpdir(),"skillcraft-proof-"));try{return await h(["worktree","add","--quiet",n,t],e),await r(n)}finally{await $t(e,n)}}async function $t(e,t){try{await h(["worktree","remove","--force",t],e)}catch{await bt.rm(t,{force:!0,recursive:!0})}}async function Vr(e,t){let r=`refs/heads/${t}`;try{let o=(await h(["worktree","list","--porcelain"],e)).split(`
25
+ `),i,s,c=async()=>{!i||s!==r||await $t(e,i)};for(let a of o){if(!a){i=void 0,s=void 0;continue}if(a.startsWith("worktree ")){await c(),i=a.slice(9),s=void 0;continue}a.startsWith("branch ")&&(s=a.slice(7))}await c()}catch{return}}async function Fe(e){let t=await Pe(e),r=await St(e,t),n=new Set;for(let i of r){let s=await ot(e,i,Ne);for(let c of s)n.add(c)}let o=[];for(let i of n){if(!i.endsWith(".json"))continue;let s=xe.basename(i,".json"),c=await _e(e,s);c&&o.push(c)}return o}function Zr(e){let t=H(e);if(t.id&&qe(t.id))return{id:t.id,version:t.version}}function be(e){let t=e.filter(Boolean).map(r=>H(r)).filter(r=>!!r.id).map(r=>`${r.id}${r.version?`@${r.version}`:""}`);return Array.from(new Set(t)).filter(qe).sort()}function Et(e,t,r){let n={skills:e,loadouts:r,timestamp:t};return Br("sha256").update(JSON.stringify(n)).digest("hex").slice(0,8)}async function ie(e){let t=await v(L(e)),r=lt.safeParse(t??{skills:[]});return r.success?be(r.data.skills):[]}async function Xr(e){let t=await v(R(e)),r=ut.safeParse(t??{activeLoadouts:[]});return r.success?r.data.activeLoadouts:[]}async function Yr(e){let t=await v(ne(e));if(!t||typeof t!="object"||Array.isArray(t))return{};let r=t,n=r.agent&&typeof r.agent=="object"&&!Array.isArray(r.agent)?r.agent:void 0,o=r.model&&typeof r.model=="object"&&!Array.isArray(r.model)?r.model:void 0;return{agent:typeof n?.provider=="string"?{provider:Pt(n.provider)}:void 0,model:typeof o?.provider=="string"||typeof o?.name=="string"?{provider:typeof o.provider=="string"?Pt(o.provider):void 0,name:typeof o.name=="string"?Qr(o.name):void 0}:void 0}}function Pt(e){return e.trim().toLowerCase()}function Qr(e){return e.trim()}function en(e){if(!e||typeof e!="object")return;let t=e;if(typeof t.version!="number"||typeof t.commit!="string"||!Array.isArray(t.skills)||!t.timestamp||typeof t.timestamp!="string")return;let r=Array.isArray(t.loadouts)?t.loadouts.map(String):[],n=t.skills.map(o=>{if(typeof o=="string")return{id:o};if(o&&typeof o=="object"&&"id"in o&&typeof o.id=="string")return{id:o.id,version:typeof o.version=="string"?o.version:void 0}}).filter(o=>!!o);return{version:t.version,commit:t.commit,skills:n,loadouts:r,timestamp:t.timestamp,agent:tn(t.agent),model:rn(t.model)}}function tn(e){if(!e||typeof e!="object"||Array.isArray(e))return;let t=e.provider;if(typeof t!="string")return;let r=t.trim().toLowerCase();return r?{provider:r}:void 0}function rn(e){if(!e||typeof e!="object"||Array.isArray(e))return;let t=e,r=typeof t.provider=="string"?t.provider.trim().toLowerCase():void 0,n=typeof t.name=="string"?t.name.trim():void 0;if(!(!r&&!n))return{provider:r,name:n}}async function _e(e,t){let r=await Pe(e),n=Ct(t),o=await St(e,r);for(let i of o){let s=await it(e,i,n);if(!s)continue;let c;try{c=JSON.parse(s)}catch{continue}let a=en(c);if(a)return a}}async function Te(e,t){let r=Et(t.skills.map(i=>i.id),t.timestamp,t.loadouts),n=await Pe(e);await Wr(e,n);let o=Ct(r);return await Gr(e,n,async i=>{await C(xe.join(i,Ne)),await y(xe.join(i,o),t),await h(["add",o],i,{env:{...process.env,SKILLCRAFT_HOOK_DISABLED:"1"}}),await h(["status","--porcelain","--",o],i,{env:{...process.env,SKILLCRAFT_HOOK_DISABLED:"1"}})&&await h(["commit","--no-gpg-sign","-m",`add Skillcraft proof ${r}`],i,{env:{...process.env,SKILLCRAFT_HOOK_DISABLED:"1"}})}),r}async function It(e,t="origin"){let r=await Pe(e);if(!(!await z(e,t)||!t))try{await h(["push",t,`${r}:${r}`],e,{env:{...process.env,SKILLCRAFT_HOOK_DISABLED:"1"}})}catch{return}}async function At(e,t){let r=await Fe(e);for(let n of r)if(n.commit===t)return Et(n.skills.map(o=>o.id),n.timestamp,n.loadouts)}async function Lt(e,t,r=new Date().toISOString()){let n=await ie(e),o=await Xr(e),i=await Yr(e),s=n.map(u=>Zr(u)).filter(u=>!!u),c={version:1,commit:t,skills:s,loadouts:o,timestamp:r,...i};return{proofId:await Te(e,c),proof:c}}async function nn(e){return e.replace(/\nSkillcraft-Ref: .*$/gm,"").trimEnd()}async function jt(e,t){let r=await nt(e),n=await nn(r);return n.includes("Skillcraft-Ref:")?n:`${n}
26
26
 
27
27
  Skillcraft-Ref: ${t}
28
- `}async function P(e){let t=A(e);if(!await $(t))return!1;let r=await v(t);return V.safeParse(r??{}).success}async function Nt(e){return $(I(e))}async function qt(){let e=process.cwd(),t=await q(e);process.stdout.write(`git: ${t?"enabled":"not a repository"}
28
+ `}async function P(e){let t=A(e);if(!await $(t))return!1;let r=await v(t);return V.safeParse(r??{}).success}async function qt(e){return $(I(e))}async function Nt(){let e=process.cwd(),t=await F(e);process.stdout.write(`git: ${t?"enabled":"not a repository"}
29
29
  `);let r=await P(e);if(process.stdout.write(`skillcraft: ${r?"enabled":"disabled"}
30
30
  `),!t||!r)return;let n=await ie(e);process.stdout.write(`pending skills: ${n.length}
31
31
  `);let o=await $(R(e)),i=await $(J(e));process.stdout.write(`context file: ${o?"present":"missing"}
@@ -33,13 +33,13 @@ Skillcraft-Ref: ${t}
33
33
  `);let s=await re(e),c=await At(e,s);process.stdout.write(`head: ${s}
34
34
  `),process.stdout.write(`latest proof: ${c??"none"}
35
35
  `);let u=(await pe(e,20)).filter(f=>f.message.includes("Skillcraft-Ref:"));process.stdout.write(`recent commits with evidence: ${u.length}
36
- `);let d=(await we(e)).proofRef?.replace(/^refs\/heads\//,"")||"skillcraft/proofs/v1",m=await z(e,`refs/heads/${d}`);process.stdout.write(`proof branch: ${m?"present":"missing"}
36
+ `);let d=(await we(e)).proofRef?.replace(/^refs\/heads\//,"")||"skillcraft/proofs/v1",m=await D(e,`refs/heads/${d}`);process.stdout.write(`proof branch: ${m?"present":"missing"}
37
37
  `),n.length>0&&process.stdout.write(`pending evidence queued: ${n.join(", ")}
38
- `)}async function Ft(){let e=process.cwd(),t=[["node",!!process.version],["git",await q(e)],["skillcraft config",await $(A(e))],["plugin hook",await $(J(e))]];for(let[r,n]of t)process.stdout.write(`${r}: ${n?"ok":"missing"}
38
+ `)}async function Ft(){let e=process.cwd(),t=[["node",!!process.version],["git",await F(e)],["skillcraft config",await $(A(e))],["plugin hook",await $(J(e))]];for(let[r,n]of t)process.stdout.write(`${r}: ${n?"ok":"missing"}
39
39
  `);if(!process.env.GITHUB_TOKEN&&!await on("gh")){process.stdout.write(`gh: not installed
40
40
  `);return}process.stdout.write(`gh: available
41
- `)}async function on(e){try{let{execSync:t}=await import("child_process");return t(`command -v ${e}`),!0}catch{return!1}}import sn from"path";async function _t(){let e=process.cwd();if(!await q(e))throw new Error("Current directory is not a git repository");let t=await te(e),r=await j();if(!r.githubUser){let i=process.env.GITHUB_USER||process.env.USER||"developer";await ft({...r,githubUser:i})}await C(I(t)),await C(sn.dirname(le(t))),await W(le(t),an()),await y(ne(t),{agent:{provider:"opencode"},model:{}});let n=`refs/heads/${G}`;await z(t,n)||await h(["branch",G],t),await y(A(t),{version:1,proofRef:G}),await C(E()),await y(L(t),{skills:[]}),await y(R(t),{activeLoadouts:[]}),await y(he(t),{version:1,providers:["opencode"],enabled:!0}),await ct(t);let o=await M(t);await gt({path:t,remote:o,enabledAt:new Date().toISOString()}),process.stdout.write(`enabled skillcraft for ${t}
42
- `)}function an(){return`import fs from 'node:fs/promises'
41
+ `)}async function on(e){try{let{execSync:t}=await import("child_process");return t(`command -v ${e}`),!0}catch{return!1}}import mn from"path";import U from"fs/promises";import Oe from"path";import{execFile as sn,execSync as an}from"child_process";import{promisify as cn}from"util";var dn=cn(sn);function ln(){try{return an("which gh",{stdio:"ignore"}),!0}catch{return!1}}async function K(e){if(!ln())throw new Error("gh CLI is required for this workflow");return(await dn("gh",e,{encoding:"utf8"})).stdout.trim()}async function _t(e,t){await U.mkdir(t,{recursive:!0});let r=await U.readdir(e,{withFileTypes:!0});for(let n of r){if(n.name===".git")continue;let o=Oe.join(e,n.name),i=Oe.join(t,n.name);if(n.isDirectory()){await _t(o,i);continue}if(n.isSymbolicLink()){let s=await U.readlink(o);await U.symlink(s,i);continue}n.isFile()&&await U.copyFile(o,i)}}var Re=class{providerName(){return"gh"}async getUser(){return await K(["api","user","--jq",".login"])}async getIssueUrl(t,r){return`https://github.com/${t}/issues/${r}`}async createIssue(t,r,n){let i=(await K(["issue","create","-R",t,"--title",r,"--body",n,"--label","skillcraft-claim"])).match(/\b(\d+)$/);return i?Number(i[1]):0}async createPullRequest(t,r,n){let i=(await K(["pr","create","--repo",t,"--head",r,"--base","main","--title",n,"--body",`Generated by skillcraft for ${n}`,"--fill-first"])).match(/\b(\d+)$/);return i?Number(i[1]):0}async openPullRequestForBranch(t,r,n,o,i){let c=(await K(["pr","create","--repo",t,"--head",`${r}:${n}`,"--base","main","--title",o,"--body",i])).match(/\b(\d+)$/);return c?Number(c[1]):0}async getIssueStatus(t,r){let n=await K(["issue","view",String(r),"--repo",t,"--json","state,labels,url"]),o=JSON.parse(n);return{state:o.state,labels:o.labels?.map(i=>i.name)??[],url:o.url}}async listClaimProcessingRuns(t,r){let n=await K(["run","list","--repo",t,"--workflow","Process credential claims","--json","name,status,conclusion,url,createdAt,workflowName"]),o=JSON.parse(n),i=`#${r}`,s=o.filter(a=>{let u=a.name||"",l=a.workflowName||"";return u.includes(i)||l.includes(i)}),c=s.length>0?s:o.filter(a=>a.status&&["in_progress","queued","waiting","action_required","canceling"].includes(a.status));return c.length?c.filter(a=>a.url).map(a=>({status:a.status||"unknown",conclusion:a.conclusion??void 0,url:a.url,name:a.name,createdAt:a.createdAt,workflowName:a.workflowName})):[]}async listClaimIssues(t){let r=await K(["issue","list","--repo",t,"--label","skillcraft-claim","--state","all","--json","number,title,state,body,labels,url","--limit","50"]);return JSON.parse(r)}async cloneRepo(t,r){let n=Oe.resolve(r);await K(["repo","clone",t,n])}async copyDirectory(t,r){await U.readdir(r).catch(()=>{})&&await U.rm(r,{recursive:!0,force:!0}),await U.mkdir(r,{recursive:!0}),await _t(t,r)}};var un={gh:()=>new Re};function q(e){return un[e]()}async function Tt(){let e=process.cwd();if(!await F(e))throw new Error("Current directory is not a git repository");let t=await te(e),r=await j();if(!r.githubUser){let s=await q(r.provider??"gh").getUser().catch(()=>process.env.GITHUB_USER||process.env.USER||"developer");await ft({...r,githubUser:s})}await C(I(t)),await C(mn.dirname(le(t))),await W(le(t),pn()),await y(ne(t),{agent:{provider:"opencode"},model:{}});let n=`refs/heads/${G}`;await D(t,n)||await h(["branch",G],t),await y(A(t),{version:1,proofRef:G}),await C(E()),await y(L(t),{skills:[]}),await y(R(t),{activeLoadouts:[]}),await y(he(t),{version:1,providers:["opencode"],enabled:!0}),await ct(t);let o=await z(t);await gt({path:t,remote:o,enabledAt:new Date().toISOString()}),process.stdout.write(`enabled skillcraft for ${t}
42
+ `)}function pn(){return`import fs from 'node:fs/promises'
43
43
  import path from 'node:path'
44
44
 
45
45
  function normalizeProvider(value) {
@@ -195,20 +195,20 @@ export default async function Skillcraft() {
195
195
  },
196
196
  }
197
197
  }
198
- `}async function Tt(){let e=await _();if(!e.repos.length){process.stdout.write(`no repositories tracked
198
+ `}async function Ot(){let e=await T();if(!e.repos.length){process.stdout.write(`no repositories tracked
199
199
  `);return}e.repos.forEach((t,r)=>{process.stdout.write(`${r+1}. ${t.path}`),t.remote&&process.stdout.write(` (${t.remote})`),process.stdout.write(`
200
- `)})}async function Ot(){let e=await _(),t=[];for(let r of e.repos)await q(r.path)&&(await te(r.path),t.push(r));await ye({repos:t}),process.stdout.write(`pruned repo list: ${e.repos.length} -> ${t.length}
201
- `)}async function se(e){return Fe(e)}import cn from"path";var dn="https://skillcraft.gg/credential-ledger/credentials/index.json",ln=360*60*1e3,Me=1,ae=at();function un(){return process.env.SKILLCRAFT_CREDENTIAL_INDEX_URL?.trim()||dn}async function Mt(e){try{let t=await v(e);if(!t||!Z(t))return null;let r=mn(t.cachedAt);if(r===void 0||r<=0||t.version!==Me||!("entries"in t))return null;let n=Re(t.entries);return{cachedAt:r,version:Me,entries:n}}catch{return null}}function mn(e){if(typeof e=="number"&&Number.isFinite(e))return e;if(typeof e=="string"&&e.trim()){let t=Number.parseInt(e,10);if(Number.isFinite(t))return t}}function pn(e){return Date.now()-e.cachedAt<ln}async function fn(e={}){let t=process.env.SKILLCRAFT_CREDENTIAL_INDEX_PATH?.trim();if(t)return zt(t);let r=e.refresh?null:await Mt(ae);if(r&&pn(r))return r.entries;try{let n=await gn(un());return await hn(n),n}catch(n){if(await $(ae)){let o=await Mt(ae);return o?o.entries:zt(ae)}throw n instanceof Error?n:new Error("failed to load credential index")}}async function gn(e){let t=await fetch(e,{headers:{"user-agent":"skillcraft-cli"}});if(!t.ok)throw new Error(`failed to download credential index from ${e}`);let r=await t.json();return Re(r)}async function zt(e){let t=await v(e);return t?Z(t)&&Array.isArray(t.entries)?Re(t.entries):Re(t):[]}async function hn(e){await C(cn.dirname(ae));let t={cachedAt:Date.now(),version:Me,entries:e};await y(ae,t)}function wn(e){let t=Z(e)?e:{};if(t.mode!==void 0)throw new Error("requirements.mode is not supported. Use nested and/or expressions instead.");let r=yn(t);return{minCommits:Kt(t.min_commits??t.minCommits,0),minRepositories:Kt(t.min_repositories??t.minRepositories,0),tree:r}}function yn(e){if(Object.prototype.hasOwnProperty.call(e,"tree"))return De(e.tree,"requirements.tree");let t=Object.prototype.hasOwnProperty.call(e,"and"),r=Object.prototype.hasOwnProperty.call(e,"or");if(t&&r)throw new Error("requirements cannot include both and and or at the same level");if(t){let n=Object.keys(e).filter(o=>!["and","min_commits","min_repositories","minRepositories","minCommits","tree"].includes(o));if(n.length)throw new Error(`Unexpected requirement fields: ${n.join(", ")}`);return{and:Dt(e.and,"requirements.and")}}if(r){let n=Object.keys(e).filter(o=>!["or","min_commits","min_repositories","minRepositories","minCommits","tree"].includes(o));if(n.length)throw new Error(`Unexpected requirement fields: ${n.join(", ")}`);return{or:Dt(e.or,"requirements.or")}}return{and:kn(e)}}function Dt(e,t){if(!Array.isArray(e))throw new Error(`Expected array at ${t}`);return e.map((r,n)=>De(r,`${t}[${n}]`))}function Ht(e,t){if(e===void 0)return[];if(Array.isArray(e))return e.map(n=>{let o=S(n);if(o===void 0)throw new Error(`Expected text values for ${t}`);return o});let r=S(e);return r?[r]:[]}function kn(e){let t=[],r=["and","or","min_commits","min_repositories","minRepositories","minCommits","tree","skill","loadout","agent","model"];for(let a of Ht(e.skill,"requirements.skill"))t.push({skill:a});for(let a of Ht(e.loadout,"requirements.loadout"))t.push({loadout:a});let n=Object.prototype.hasOwnProperty.call(e,"agent"),o=Ut(e.agent);if(o)t.push(o);else if(n)throw new Error("requirements.agent must be an object with a provider");let i=Object.prototype.hasOwnProperty.call(e,"model"),s=Bt(e.model);if(s)t.push(s);else if(i)throw new Error("requirements.model must be an object with optional provider and/or name");let c=Object.keys(e).filter(a=>!r.includes(a)&&!a.startsWith("$"));if(c.length)throw new Error(`Unexpected requirement fields: ${c.join(", ")}`);return t}function De(e,t){if(!Z(e))throw new Error(`Invalid requirement node at ${t}`);let r=Object.keys(e);if(!r.length)throw new Error(`Empty requirement node at ${t}`);if(r.length>1)throw new Error(`Requirement node has multiple keys at ${t}`);let[n]=r;if(n==="and"||n==="or"){let o=e[n];if(!Array.isArray(o))throw new Error(`Requirement node ${t} expected array for ${n}`);return{[n]:o.map((i,s)=>De(i,`${t}.${n}[${s}]`))}}if(n==="skill"){let o=S(e[n]);if(!o)throw new Error(`Requirement node ${t} has empty skill`);return{skill:o}}if(n==="loadout"){let o=S(e[n]);if(!o)throw new Error(`Requirement node ${t} has empty loadout`);return{loadout:o}}if(n==="agent"){let o=Ut(e[n]);if(!o)throw new Error(`Requirement node ${t} has invalid agent requirement`);return o}if(n==="model"){let o=Bt(e[n]);if(!o)throw new Error(`Requirement node ${t} has invalid model requirement`);return o}throw new Error(`Unexpected requirement key ${n} at ${t}`)}function Ut(e){if(!Z(e))return;let t=S(e.provider);if(t)return{agent:{provider:t.toLowerCase()}}}function Bt(e){if(!Z(e))return;let t=S(e.provider),r=S(e.name);if(!(!t&&!r))return{model:{...t?{provider:t.toLowerCase()}:{},...r?{name:r}:{}}}}function Jt(e,t,r,n){let o=[],i=[],s=[],c=[],a=Array.from(new Set((t||[]).filter(Boolean))),u=Array.from(new Set((r||[]).filter(Boolean)));for(let f of e){let p=f.proof;for(let B of p.skills){let ee=He(B.id);ee.id&&o.push({id:ee.id,version:ee.version})}for(let B of p.loadouts){let ee=S(B);ee&&i.push(ee)}p.agent?.provider&&typeof p.agent.provider=="string"&&s.push(p.agent.provider);let x=p.model?.provider,Q=p.model?.name;(typeof x=="string"||typeof Q=="string")&&c.push({provider:x,name:Q})}let l=ze(n.tree,{skills:o,loadouts:i,agents:s,models:c}),d=l.checks,m=[...vn(d)];return n.minCommits>a.length&&(m.push(`minimum required commits not met: have ${a.length}, need ${n.minCommits}`),l.passed=!1),n.minRepositories>u.length&&(m.push(`minimum required repositories not met: have ${u.length}, need ${n.minRepositories}`),l.passed=!1),{passed:l.passed,proofs:e,provenCommits:a,provenRepos:u,checks:d,reasons:m,noExplicitChecks:l.noExplicitChecks}}function ze(e,t){if("and"in e){let r=[],n=[],o=!0;for(let i of e.and){let s=ze(i,t);r.push(...s.checks),n.push(s),s.noExplicitChecks||(o=!1)}return{passed:n.every(i=>i.passed),checks:r,noExplicitChecks:o}}if("or"in e){let r=[],n=[],o=!0;for(let i of e.or){let s=ze(i,t);r.push(...s.checks),n.push(s),s.noExplicitChecks||(o=!1)}return{passed:n.some(i=>i.passed),checks:r,noExplicitChecks:o}}if("skill"in e){let r=He(e.skill),n=xn(t.skills,r);return{passed:n,checks:[{type:"skill",requirement:e.skill,satisfied:n}],noExplicitChecks:!1}}if("loadout"in e){let r=bn(e.loadout),n=t.loadouts.includes(e.loadout)||r&&r.id!==""&&t.loadouts.includes(r.id);return{passed:n,checks:[{type:"loadout",requirement:e.loadout,satisfied:n}],noExplicitChecks:!1}}if("agent"in e){let r=Oe(e.agent.provider),n=t.agents.some(o=>o===r);return{passed:n,checks:[{type:"agent",requirement:`provider=${r}`,satisfied:n}],noExplicitChecks:!1}}if("model"in e){let r=Oe(e.model.provider),n=Oe(e.model.name),o=t.models.some(s=>{let c=!r||s.provider===r,a=!n||s.name&&s.name===n;return c&&a}),i=[];return r&&i.push(`provider=${r}`),n&&i.push(`name=${n}`),{passed:o,checks:[{type:"model",requirement:i.join(",")||"model",satisfied:o}],noExplicitChecks:!1}}throw new Error("Unknown requirement node encountered during evaluation")}function vn(e){return e.filter(t=>!t.satisfied).map(t=>`${t.type} ${t.requirement} not met`)}function xn(e,t){return e.some(r=>Pn(r.id,r.version,t))}function Pn(e,t,r){return e!==r.id?!1:r.version?t===r.version:!0}function bn(e){return He(e)}function He(e){let t=S(e);if(!t)return{id:""};let r=t.split("@");return{id:r[0],version:r.length>1?r.slice(1).join("@"):void 0}}function Oe(e){return typeof e=="string"?e.trim().toLowerCase():""}function S(e){return typeof e!="string"?void 0:e.trim()||void 0}function Kt(e,t){return typeof e!="number"||!Number.isFinite(e)||e<0?t:Math.floor(e)}function Z(e){return!!e&&typeof e=="object"&&!Array.isArray(e)}function Re(e){if(!Array.isArray(e))return[];let t=[];for(let r of e){let n=Rn(r);n&&t.push(n)}return t.sort((r,n)=>r.id.localeCompare(n.id))}function Rn(e){if(!Z(e))return;let t=S(e.id);if(t)try{return{id:t,name:S(e.name),description:S(e.description),requirements:wn(e.requirements)}}catch{return}}async function Ke(e={}){return fn(e)}function Wt(e){process.stdout.write(`${e.join(`
200
+ `)})}async function Mt(){let e=await T(),t=[];for(let r of e.repos)await F(r.path)&&(await te(r.path),t.push(r));await ye({repos:t}),process.stdout.write(`pruned repo list: ${e.repos.length} -> ${t.length}
201
+ `)}async function se(e){return Fe(e)}import fn from"path";var gn="https://skillcraft.gg/credential-ledger/credentials/index.json",hn=360*60*1e3,ze=1,ae=at();function wn(){return process.env.SKILLCRAFT_CREDENTIAL_INDEX_URL?.trim()||gn}async function zt(e){try{let t=await v(e);if(!t||!Z(t))return null;let r=yn(t.cachedAt);if(r===void 0||r<=0||t.version!==ze||!("entries"in t))return null;let n=Ce(t.entries);return{cachedAt:r,version:ze,entries:n}}catch{return null}}function yn(e){if(typeof e=="number"&&Number.isFinite(e))return e;if(typeof e=="string"&&e.trim()){let t=Number.parseInt(e,10);if(Number.isFinite(t))return t}}function kn(e){return Date.now()-e.cachedAt<hn}async function vn(e={}){let t=process.env.SKILLCRAFT_CREDENTIAL_INDEX_PATH?.trim();if(t)return Dt(t);let r=e.refresh?null:await zt(ae);if(r&&kn(r))return r.entries;try{let n=await xn(wn());return await Pn(n),n}catch(n){if(await $(ae)){let o=await zt(ae);return o?o.entries:Dt(ae)}throw n instanceof Error?n:new Error("failed to load credential index")}}async function xn(e){let t=await fetch(e,{headers:{"user-agent":"skillcraft-cli"}});if(!t.ok)throw new Error(`failed to download credential index from ${e}`);let r=await t.json();return Ce(r)}async function Dt(e){let t=await v(e);return t?Z(t)&&Array.isArray(t.entries)?Ce(t.entries):Ce(t):[]}async function Pn(e){await C(fn.dirname(ae));let t={cachedAt:Date.now(),version:ze,entries:e};await y(ae,t)}function bn(e){let t=Z(e)?e:{};if(t.mode!==void 0)throw new Error("requirements.mode is not supported. Use nested and/or expressions instead.");let r=Rn(t);return{minCommits:Ut(t.min_commits??t.minCommits,0),minRepositories:Ut(t.min_repositories??t.minRepositories,0),tree:r}}function Rn(e){if(Object.prototype.hasOwnProperty.call(e,"tree"))return He(e.tree,"requirements.tree");let t=Object.prototype.hasOwnProperty.call(e,"and"),r=Object.prototype.hasOwnProperty.call(e,"or");if(t&&r)throw new Error("requirements cannot include both and and or at the same level");if(t){let n=Object.keys(e).filter(o=>!["and","min_commits","min_repositories","minRepositories","minCommits","tree"].includes(o));if(n.length)throw new Error(`Unexpected requirement fields: ${n.join(", ")}`);return{and:Ht(e.and,"requirements.and")}}if(r){let n=Object.keys(e).filter(o=>!["or","min_commits","min_repositories","minRepositories","minCommits","tree"].includes(o));if(n.length)throw new Error(`Unexpected requirement fields: ${n.join(", ")}`);return{or:Ht(e.or,"requirements.or")}}return{and:Cn(e)}}function Ht(e,t){if(!Array.isArray(e))throw new Error(`Expected array at ${t}`);return e.map((r,n)=>He(r,`${t}[${n}]`))}function Kt(e,t){if(e===void 0)return[];if(Array.isArray(e))return e.map(n=>{let o=S(n);if(o===void 0)throw new Error(`Expected text values for ${t}`);return o});let r=S(e);return r?[r]:[]}function Cn(e){let t=[],r=["and","or","min_commits","min_repositories","minRepositories","minCommits","tree","skill","loadout","agent","model"];for(let a of Kt(e.skill,"requirements.skill"))t.push({skill:a});for(let a of Kt(e.loadout,"requirements.loadout"))t.push({loadout:a});let n=Object.prototype.hasOwnProperty.call(e,"agent"),o=Bt(e.agent);if(o)t.push(o);else if(n)throw new Error("requirements.agent must be an object with a provider");let i=Object.prototype.hasOwnProperty.call(e,"model"),s=Jt(e.model);if(s)t.push(s);else if(i)throw new Error("requirements.model must be an object with optional provider and/or name");let c=Object.keys(e).filter(a=>!r.includes(a)&&!a.startsWith("$"));if(c.length)throw new Error(`Unexpected requirement fields: ${c.join(", ")}`);return t}function He(e,t){if(!Z(e))throw new Error(`Invalid requirement node at ${t}`);let r=Object.keys(e);if(!r.length)throw new Error(`Empty requirement node at ${t}`);if(r.length>1)throw new Error(`Requirement node has multiple keys at ${t}`);let[n]=r;if(n==="and"||n==="or"){let o=e[n];if(!Array.isArray(o))throw new Error(`Requirement node ${t} expected array for ${n}`);return{[n]:o.map((i,s)=>He(i,`${t}.${n}[${s}]`))}}if(n==="skill"){let o=S(e[n]);if(!o)throw new Error(`Requirement node ${t} has empty skill`);return{skill:o}}if(n==="loadout"){let o=S(e[n]);if(!o)throw new Error(`Requirement node ${t} has empty loadout`);return{loadout:o}}if(n==="agent"){let o=Bt(e[n]);if(!o)throw new Error(`Requirement node ${t} has invalid agent requirement`);return o}if(n==="model"){let o=Jt(e[n]);if(!o)throw new Error(`Requirement node ${t} has invalid model requirement`);return o}throw new Error(`Unexpected requirement key ${n} at ${t}`)}function Bt(e){if(!Z(e))return;let t=S(e.provider);if(t)return{agent:{provider:t.toLowerCase()}}}function Jt(e){if(!Z(e))return;let t=S(e.provider),r=S(e.name);if(!(!t&&!r))return{model:{...t?{provider:t.toLowerCase()}:{},...r?{name:r}:{}}}}function Wt(e,t,r,n){let o=[],i=[],s=[],c=[],a=Array.from(new Set((t||[]).filter(Boolean))),u=Array.from(new Set((r||[]).filter(Boolean)));for(let f of e){let p=f.proof;for(let B of p.skills){let ee=Ke(B.id);ee.id&&o.push({id:ee.id,version:ee.version})}for(let B of p.loadouts){let ee=S(B);ee&&i.push(ee)}p.agent?.provider&&typeof p.agent.provider=="string"&&s.push(p.agent.provider);let x=p.model?.provider,Q=p.model?.name;(typeof x=="string"||typeof Q=="string")&&c.push({provider:x,name:Q})}let l=De(n.tree,{skills:o,loadouts:i,agents:s,models:c}),d=l.checks,m=[...Sn(d)];return n.minCommits>a.length&&(m.push(`minimum required commits not met: have ${a.length}, need ${n.minCommits}`),l.passed=!1),n.minRepositories>u.length&&(m.push(`minimum required repositories not met: have ${u.length}, need ${n.minRepositories}`),l.passed=!1),{passed:l.passed,proofs:e,provenCommits:a,provenRepos:u,checks:d,reasons:m,noExplicitChecks:l.noExplicitChecks}}function De(e,t){if("and"in e){let r=[],n=[],o=!0;for(let i of e.and){let s=De(i,t);r.push(...s.checks),n.push(s),s.noExplicitChecks||(o=!1)}return{passed:n.every(i=>i.passed),checks:r,noExplicitChecks:o}}if("or"in e){let r=[],n=[],o=!0;for(let i of e.or){let s=De(i,t);r.push(...s.checks),n.push(s),s.noExplicitChecks||(o=!1)}return{passed:n.some(i=>i.passed),checks:r,noExplicitChecks:o}}if("skill"in e){let r=Ke(e.skill),n=$n(t.skills,r);return{passed:n,checks:[{type:"skill",requirement:e.skill,satisfied:n}],noExplicitChecks:!1}}if("loadout"in e){let r=In(e.loadout),n=t.loadouts.includes(e.loadout)||r&&r.id!==""&&t.loadouts.includes(r.id);return{passed:n,checks:[{type:"loadout",requirement:e.loadout,satisfied:n}],noExplicitChecks:!1}}if("agent"in e){let r=Me(e.agent.provider),n=t.agents.some(o=>o===r);return{passed:n,checks:[{type:"agent",requirement:`provider=${r}`,satisfied:n}],noExplicitChecks:!1}}if("model"in e){let r=Me(e.model.provider),n=Me(e.model.name),o=t.models.some(s=>{let c=!r||s.provider===r,a=!n||s.name&&s.name===n;return c&&a}),i=[];return r&&i.push(`provider=${r}`),n&&i.push(`name=${n}`),{passed:o,checks:[{type:"model",requirement:i.join(",")||"model",satisfied:o}],noExplicitChecks:!1}}throw new Error("Unknown requirement node encountered during evaluation")}function Sn(e){return e.filter(t=>!t.satisfied).map(t=>`${t.type} ${t.requirement} not met`)}function $n(e,t){return e.some(r=>En(r.id,r.version,t))}function En(e,t,r){return e!==r.id?!1:r.version?t===r.version:!0}function In(e){return Ke(e)}function Ke(e){let t=S(e);if(!t)return{id:""};let r=t.split("@");return{id:r[0],version:r.length>1?r.slice(1).join("@"):void 0}}function Me(e){return typeof e=="string"?e.trim().toLowerCase():""}function S(e){return typeof e!="string"?void 0:e.trim()||void 0}function Ut(e,t){return typeof e!="number"||!Number.isFinite(e)||e<0?t:Math.floor(e)}function Z(e){return!!e&&typeof e=="object"&&!Array.isArray(e)}function Ce(e){if(!Array.isArray(e))return[];let t=[];for(let r of e){let n=An(r);n&&t.push(n)}return t.sort((r,n)=>r.id.localeCompare(n.id))}function An(e){if(!Z(e))return;let t=S(e.id);if(t)try{return{id:t,name:S(e.name),description:S(e.description),requirements:bn(e.requirements)}}catch{return}}async function Ue(e={}){return vn(e)}function Gt(e){process.stdout.write(`${e.join(`
202
202
  `)}
203
- `)}async function Cn(){let e=await _(),t=new Set,r=[];for(let n of e.repos)t.has(n.path)||(t.add(n.path),await P(n.path)&&r.push(n.path));return r}async function Zt(e={}){let t=await Cn(),n=(await ke()).credentials;if(!n.length){if(e.outputMode==="json"){Vt(Gt({tracked:t,trackedCredentialsCount:0,proofFiles:0,provenCommits:0,provenRepositories:0,evaluated:[]}));return}process.stdout.write(`no credentials tracked
204
- `);return}let o=Qt(await Ke({refresh:e.refreshIndex})),i=0,s=[],c=new Set,a=new Set;for(let p of t){let x=await se(p);if(i+=x.length,!x.length)continue;let Q=await M(p)||p;c.add(Q);for(let B of x)B?.commit&&a.add(B.commit),s.push({proof:B})}let u=Array.from(a),l=Array.from(c),d=Gt({tracked:t,trackedCredentialsCount:n.length,proofFiles:i,provenCommits:u.length,provenRepositories:l.length,evaluated:[]}),m=[];for(let p of n){let x=o.get(p.id);if(!x){m.push(Sn(p.id,s.length,u.length,l.length));continue}let Q=Jt(s,u,l,x.requirements);m.push($n(p.id,x,Q,s.length,u.length,l.length))}if(d.credentials=m,e.outputMode==="json"){Vt(d);return}let f=[];f.push(`tracked credentials: ${n.length}`),f.push(`tracked repositories: ${t.length}`),f.push(`proof files: ${i}`),f.push(`proof commits: ${u.length}`),f.push(`proof repositories: ${l.length}`),f.push("");for(let p of m){if(f.push(`${p.credentialId}: ${p.status}`),f.push(` checks: ${p.passed?"passed":"blocked"}`),f.push(` proof scope: ${p.proofFiles} proofs, ${p.provenCommits}/${p.requiredMinCommits} commits, ${p.provenRepositories}/${p.requiredMinRepositories} repositories`),p.reasons.length){f.push(" reasons:");for(let x of p.reasons)f.push(` - ${x}`)}f.push("")}Wt(f)}async function Xt(e){let t=T(e,"credential id");if(!Qt(await Ke()).has(t))throw new Error(`credential not found in credential index: ${t}`);if(!await yt(t)){process.stdout.write(`credential already tracked: ${t}
203
+ `)}async function Ln(){let e=await T(),t=new Set,r=[];for(let n of e.repos)t.has(n.path)||(t.add(n.path),await P(n.path)&&r.push(n.path));return r}async function Xt(e={}){let t=await Ln(),n=(await ke()).credentials;if(!n.length){if(e.outputMode==="json"){Zt(Vt({tracked:t,trackedCredentialsCount:0,proofFiles:0,provenCommits:0,provenRepositories:0,evaluated:[]}));return}process.stdout.write(`no credentials tracked
204
+ `);return}let o=er(await Ue({refresh:e.refreshIndex})),i=0,s=[],c=new Set,a=new Set;for(let p of t){let x=await se(p);if(i+=x.length,!x.length)continue;let Q=await z(p)||p;c.add(Q);for(let B of x)B?.commit&&a.add(B.commit),s.push({proof:B})}let u=Array.from(a),l=Array.from(c),d=Vt({tracked:t,trackedCredentialsCount:n.length,proofFiles:i,provenCommits:u.length,provenRepositories:l.length,evaluated:[]}),m=[];for(let p of n){let x=o.get(p.id);if(!x){m.push(jn(p.id,s.length,u.length,l.length));continue}let Q=Wt(s,u,l,x.requirements);m.push(qn(p.id,x,Q,s.length,u.length,l.length))}if(d.credentials=m,e.outputMode==="json"){Zt(d);return}let f=[];f.push(`tracked credentials: ${n.length}`),f.push(`tracked repositories: ${t.length}`),f.push(`proof files: ${i}`),f.push(`proof commits: ${u.length}`),f.push(`proof repositories: ${l.length}`),f.push("");for(let p of m){if(f.push(`${p.credentialId}: ${p.status}`),f.push(` checks: ${p.passed?"passed":"blocked"}`),f.push(` proof scope: ${p.proofFiles} proofs, ${p.provenCommits}/${p.requiredMinCommits} commits, ${p.provenRepositories}/${p.requiredMinRepositories} repositories`),p.reasons.length){f.push(" reasons:");for(let x of p.reasons)f.push(` - ${x}`)}f.push("")}Gt(f)}async function Yt(e){let t=O(e,"credential id");if(!er(await Ue()).has(t))throw new Error(`credential not found in credential index: ${t}`);if(!await yt(t)){process.stdout.write(`credential already tracked: ${t}
205
205
  `);return}process.stdout.write(`tracking credential: ${t}
206
- `)}async function Yt(e){let t=T(e,"credential id");if(!await kt(t)){process.stdout.write(`credential not tracked: ${t}
206
+ `)}async function Qt(e){let t=O(e,"credential id");if(!await kt(t)){process.stdout.write(`credential not tracked: ${t}
207
207
  `);return}process.stdout.write(`untracked credential: ${t}
208
- `)}function Gt(e){return{trackedCredentials:e.trackedCredentialsCount,trackedRepositories:e.tracked.length,evidence:{proofFiles:e.proofFiles,provenCommits:e.provenCommits,provenRepositories:e.provenRepositories},credentials:e.evaluated}}function Vt(e){process.stdout.write(`${JSON.stringify(e)}
209
- `)}function Qt(e){return new Map(e.map(t=>[t.id,t]))}function Sn(e,t,r,n){return{credentialId:e,passed:!1,status:"blocked",reasons:["credential definition is not available"],checks:[],requiredMinCommits:0,requiredMinRepositories:0,provenCommits:r,provenRepositories:n,proofFiles:t}}function $n(e,t,r,n,o,i){return{credentialId:e,name:t.name,description:t.description,passed:r.passed,status:r.passed?"eligible":"blocked",reasons:r.reasons,checks:r.checks,requiredMinCommits:t.requirements.minCommits,requiredMinRepositories:t.requirements.minRepositories,provenCommits:o,provenRepositories:i,proofFiles:n}}import X from"path";import O from"fs/promises";import K from"fs/promises";import Ue from"path";import{execFile as En,execSync as In}from"child_process";import{promisify as An}from"util";var Ln=An(En);function jn(){try{return In("which gh",{stdio:"ignore"}),!0}catch{return!1}}async function H(e){if(!jn())throw new Error("gh CLI is required for this workflow");return(await Ln("gh",e,{encoding:"utf8"})).stdout.trim()}async function er(e,t){await K.mkdir(t,{recursive:!0});let r=await K.readdir(e,{withFileTypes:!0});for(let n of r){if(n.name===".git")continue;let o=Ue.join(e,n.name),i=Ue.join(t,n.name);if(n.isDirectory()){await er(o,i);continue}if(n.isSymbolicLink()){let s=await K.readlink(o);await K.symlink(s,i);continue}n.isFile()&&await K.copyFile(o,i)}}var Ce=class{providerName(){return"gh"}async getUser(){let t=await H(["auth","status","--json","user"]);return JSON.parse(t).user?.login||""}async getIssueUrl(t,r){return`https://github.com/${t}/issues/${r}`}async createIssue(t,r,n){let i=(await H(["issue","create","-R",t,"--title",r,"--body",n,"--label","skillcraft-claim"])).match(/\b(\d+)$/);return i?Number(i[1]):0}async createPullRequest(t,r,n){let i=(await H(["pr","create","--repo",t,"--head",r,"--base","main","--title",n,"--body",`Generated by skillcraft for ${n}`,"--fill-first"])).match(/\b(\d+)$/);return i?Number(i[1]):0}async openPullRequestForBranch(t,r,n,o,i){let c=(await H(["pr","create","--repo",t,"--head",`${r}:${n}`,"--base","main","--title",o,"--body",i])).match(/\b(\d+)$/);return c?Number(c[1]):0}async getIssueStatus(t,r){let n=await H(["issue","view",String(r),"--repo",t,"--json","state,labels,url"]),o=JSON.parse(n);return{state:o.state,labels:o.labels?.map(i=>i.name)??[],url:o.url}}async listClaimProcessingRuns(t,r){let n=await H(["run","list","--repo",t,"--workflow","Process credential claims","--json","name,status,conclusion,url,createdAt,workflowName"]),o=JSON.parse(n),i=`#${r}`,s=o.filter(a=>{let u=a.name||"",l=a.workflowName||"";return u.includes(i)||l.includes(i)}),c=s.length>0?s:o.filter(a=>a.status&&["in_progress","queued","waiting","action_required","canceling"].includes(a.status));return c.length?c.filter(a=>a.url).map(a=>({status:a.status||"unknown",conclusion:a.conclusion??void 0,url:a.url,name:a.name,createdAt:a.createdAt,workflowName:a.workflowName})):[]}async listClaimIssues(t){let r=await H(["issue","list","--repo",t,"--label","skillcraft-claim","--state","all","--json","number,title,state,body,labels,url","--limit","50"]);return JSON.parse(r)}async cloneRepo(t,r){let n=Ue.resolve(r);await H(["repo","clone",t,n])}async copyDirectory(t,r){await K.readdir(r).catch(()=>{})&&await K.rm(r,{recursive:!0,force:!0}),await K.mkdir(r,{recursive:!0}),await er(t,r)}};var Nn={gh:()=>new Ce};function U(e){return Nn[e]()}import{execFile as qn}from"child_process";import{promisify as Fn}from"util";import _n from"ora";var Tn=Fn(qn);async function sr(e){let t=T(e,"skill id"),{owner:r,slug:n}=ve(t),o=process.cwd();if(!await P(o))throw new Error("Repository is not enabled");let i=await Promise.all([O.access(X.join(o,"SKILL.md")).then(()=>!0).catch(()=>!1),O.access(X.join(o,"skill.yaml")).then(()=>!0).catch(()=>!1)]);if(!i[0]||!i[1])throw new Error("SKILL.md and skill.yaml are required for publishing");let s=await j(),c=U(s.provider??"gh");await c.getUser();let a="skillcraft-gg/skills-registry",u=`skillcraft-skill-${r}-${n}`,l=X.join(process.cwd(),".skillcraft-temp-skill-publish");try{await O.rm(l,{force:!0,recursive:!0}),await c.cloneRepo(a,l),await Se(l,["checkout","-B",u]);let d=X.join(l,"skills",r,n);await O.rm(d,{force:!0,recursive:!0}),await O.mkdir(X.dirname(d),{recursive:!0}),await O.cp(o,d,{recursive:!0}),await Se(l,["add",`skills/${r}/${n}`]),await Se(l,["commit","-m",`Publish skill ${t}`]).catch(()=>{throw new Error("nothing to commit; skill may already be published")}),await Se(l,["push","-u","origin",u]).catch(()=>{throw new Error("unable to push skill publish branch")}),await c.createPullRequest(a,u,`Publish skill: ${t}`).catch(()=>{process.stdout.write(`unable to create PR automatically. Please open one manually from your branch.
208
+ `)}function Vt(e){return{trackedCredentials:e.trackedCredentialsCount,trackedRepositories:e.tracked.length,evidence:{proofFiles:e.proofFiles,provenCommits:e.provenCommits,provenRepositories:e.provenRepositories},credentials:e.evaluated}}function Zt(e){process.stdout.write(`${JSON.stringify(e)}
209
+ `)}function er(e){return new Map(e.map(t=>[t.id,t]))}function jn(e,t,r,n){return{credentialId:e,passed:!1,status:"blocked",reasons:["credential definition is not available"],checks:[],requiredMinCommits:0,requiredMinRepositories:0,provenCommits:r,provenRepositories:n,proofFiles:t}}function qn(e,t,r,n,o,i){return{credentialId:e,name:t.name,description:t.description,passed:r.passed,status:r.passed?"eligible":"blocked",reasons:r.reasons,checks:r.checks,requiredMinCommits:t.requirements.minCommits,requiredMinRepositories:t.requirements.minRepositories,provenCommits:o,provenRepositories:i,proofFiles:n}}import X from"path";import M from"fs/promises";import{execFile as Nn}from"child_process";import{promisify as Fn}from"util";import _n from"ora";var Tn=Fn(Nn);async function sr(e){let t=O(e,"skill id"),{owner:r,slug:n}=ve(t),o=process.cwd();if(!await P(o))throw new Error("Repository is not enabled");let i=await Promise.all([M.access(X.join(o,"SKILL.md")).then(()=>!0).catch(()=>!1),M.access(X.join(o,"skill.yaml")).then(()=>!0).catch(()=>!1)]);if(!i[0]||!i[1])throw new Error("SKILL.md and skill.yaml are required for publishing");let s=await j(),c=q(s.provider??"gh");await c.getUser();let a="skillcraft-gg/skills-registry",u=`skillcraft-skill-${r}-${n}`,l=X.join(process.cwd(),".skillcraft-temp-skill-publish");try{await M.rm(l,{force:!0,recursive:!0}),await c.cloneRepo(a,l),await Se(l,["checkout","-B",u]);let d=X.join(l,"skills",r,n);await M.rm(d,{force:!0,recursive:!0}),await M.mkdir(X.dirname(d),{recursive:!0}),await M.cp(o,d,{recursive:!0}),await Se(l,["add",`skills/${r}/${n}`]),await Se(l,["commit","-m",`Publish skill ${t}`]).catch(()=>{throw new Error("nothing to commit; skill may already be published")}),await Se(l,["push","-u","origin",u]).catch(()=>{throw new Error("unable to push skill publish branch")}),await c.createPullRequest(a,u,`Publish skill: ${t}`).catch(()=>{process.stdout.write(`unable to create PR automatically. Please open one manually from your branch.
210
210
  `)}),process.stdout.write(`published skill ${t} from ${a}
211
- `)}finally{await O.rm(l,{force:!0,recursive:!0})}}async function ar(e){let t=process.cwd();if(!await P(t))throw new Error("Repository is not enabled");let r=T(e,"skill id"),n=D(r);if(!n.id)throw new Error("invalid skill id format");if(!(await Bn()).has(n.id))throw new Error(`skill ${n.id} is not listed in the search index`);let i=be([`${n.id}${n.version?`@${n.version}`:""}`]),s=await ie(t),c=be([...s,...i]);await y(L(t),{skills:c}),process.stdout.write(`queued skill: ${i[0]}
211
+ `)}finally{await M.rm(l,{force:!0,recursive:!0})}}async function ar(e){let t=process.cwd();if(!await P(t))throw new Error("Repository is not enabled");let r=O(e,"skill id"),n=H(r);if(!n.id)throw new Error("invalid skill id format");if(!(await Bn()).has(n.id))throw new Error(`skill ${n.id} is not listed in the search index`);let i=be([`${n.id}${n.version?`@${n.version}`:""}`]),s=await ie(t),c=be([...s,...i]);await y(L(t),{skills:c}),process.stdout.write(`queued skill: ${i[0]}
212
212
  `)}async function On(){let e=process.cwd(),t=[["SKILL.md",await ir(X.join(e,"SKILL.md"))],["skill.yaml",await ir(X.join(e,"skill.yaml"))]];for(let[r,n]of t)process.stdout.write(`${r}: ${n?"ok":"missing"}
213
213
  `)}async function cr(){let e=process.cwd();if(!await P(e))throw new Error("Repository is not enabled");let[t,r]=await Promise.all([se(e),ie(e)]),n=new Set;for(let i of t)for(let s of i.skills)n.add(s.id);for(let i of r)n.add(i);if(!n.size){process.stdout.write(`no skills detected
214
214
  `);return}let o=Array.from(n).sort().join(`
@@ -222,12 +222,12 @@ ${o}
222
222
  `);return}process.stdout.write(`${u} (${a.length}):
223
223
  ${l.join(`
224
224
  `)}
225
- `)}async function lr(e,t={}){let r=T(e,"skill id"),n=D(r);if(!n.id)throw new Error("invalid skill id format");let i=(await Be(t.outputMode)).find(a=>a.id===n.id);if(!i)throw new Error(`skill ${n.id} is not listed in the search index`);let s=await zn(i);if(t.outputMode==="json"){let a={id:i.id,name:i.name,source:Je(i.id),owner:i.owner,slug:i.slug,path:i.path,url:i.url,runtime:i.runtime,tags:i.tags,updatedAt:i.updatedAt,manifest:s,version:n.version};process.stdout.write(`${JSON.stringify(a)}
225
+ `)}async function lr(e,t={}){let r=O(e,"skill id"),n=H(r);if(!n.id)throw new Error("invalid skill id format");let i=(await Be(t.outputMode)).find(a=>a.id===n.id);if(!i)throw new Error(`skill ${n.id} is not listed in the search index`);let s=await zn(i);if(t.outputMode==="json"){let a={id:i.id,name:i.name,source:Je(i.id),owner:i.owner,slug:i.slug,path:i.path,url:i.url,runtime:i.runtime,tags:i.tags,updatedAt:i.updatedAt,manifest:s,version:n.version};process.stdout.write(`${JSON.stringify(a)}
226
226
  `);return}let c=Mn(i,s);process.stdout.write(`${c}
227
227
  `)}function Mn(e,t){let r=[];r.push(`skill: ${e.id}`),e.name&&r.push(`name: ${e.name}`);let n=Je(e.id);return n&&r.push(`source: ${n}`),e.owner&&r.push(`owner: ${e.owner}`),e.slug&&r.push(`slug: ${e.slug}`),e.runtime&&e.runtime.length&&r.push(`runtime: ${e.runtime.join(", ")}`),e.tags&&e.tags.length&&r.push(`tags: ${e.tags.join(", ")}`),e.updatedAt&&r.push(`updated: ${e.updatedAt}`),e.path&&r.push(`path: ${e.path}`),e.url&&r.push(`url: ${e.url}`),t&&(r.push(`manifest: ${t.url}`),t.title&&r.push(`manifest title: ${t.title}`),t.summary&&r.push(`manifest summary: ${t.summary}`),t.error&&r.push(`manifest fetch: ${t.error}`)),r.join(`
228
228
  `)}async function zn(e){let t=Dn(e.url);if(!t)return;let r=new AbortController,n=setTimeout(()=>{r.abort()},5e3);try{let o=await fetch(t,{headers:{"user-agent":"skillcraft-cli"},signal:r.signal});if(!o.ok)return{url:t,error:`unable to fetch manifest (${o.status})`};let i=await o.text();if(Kn(i))return{url:t,error:"unable to parse manifest (not markdown)"};let s=Un(i);return{url:t,title:s.title,summary:s.summary}}catch(o){return o instanceof Error&&o.name==="AbortError"?{url:t,error:"manifest fetch timed out"}:{url:t,error:o instanceof Error?o.message:"failed to fetch manifest"}}finally{clearTimeout(n)}}function Dn(e){if(!e)return;let t=e.trim();if(!t)return;let r=t.endsWith("/SKILL.md")?t:t.endsWith("/")?`${t}SKILL.md`:`${t}/SKILL.md`;return Hn(r)}function Hn(e){try{let t=new URL(e);if(t.hostname!=="github.com")return e;let r=t.pathname.split("/").filter(Boolean),n=r.indexOf("blob");if(n!==2||r.length<n+2)return e;let o=r[0],i=r[1],s=r.slice(n+1);if(!o||!i||!s.length)return e;let c=[o,i,"raw","refs","heads",...s];return`${t.protocol}//${t.host}/${c.join("/")}`}catch{return e}}function Kn(e){let t=e.replace(/^\s+/,"").toLowerCase();return t.startsWith("<!doctype html")||t.startsWith("<html")}function Un(e){let r=e.replace(/\r\n/g,`
229
229
  `).split(`
230
- `),n=0;if((r[0]||"").trim()==="---"){for(n=1;n<r.length&&r[n].trim()!=="---";)n+=1;n<r.length&&r[n].trim()==="---"&&(n+=1)}let o,i;for(let s=n;s<r.length;s+=1){let c=r[s].trim();if(!c){if(i)break;continue}if(!o&&c.startsWith("#")){o=c.replace(/^#+\s*/,"").trim();continue}if(!i&&!c.startsWith(">")){i=c;break}}return{title:o,summary:i}}function tr(e){return Array.isArray(e)}async function Bn(){let e=await Be();return new Set(e.map(t=>t.id))}async function Be(e=void 0){let t=process.env.SKILLCRAFT_SEARCH_INDEX_PATH?.trim(),r=t||process.env.SKILLCRAFT_SEARCH_INDEX_URL||"https://skillcraft.gg/skills-registry/search/index.json",n=async()=>{if(t){let u=await O.readFile(t,"utf8"),l=JSON.parse(u);return rr(tr(l)?l:[])}let s=process.env.SKILLCRAFT_SEARCH_INDEX_URL||"https://skillcraft.gg/skills-registry/search/index.json",c=await fetch(s,{headers:{"user-agent":"skillcraft-cli"}});if(!c.ok)throw new Error(`failed to download search index from ${s}`);let a=await c.json();return rr(tr(a)?a:[])};if(!Jn(e))return n();let o=t?`reading local index from ${r}`:`downloading index from ${r}`,i=_n({text:`Loading ${o}...`}).start();try{let s=await n();return i.succeed(`loaded ${s.length} indexed entries`),s}catch(s){throw i.fail("failed to load search index"),s}}function Jn(e){return e!=="text"?!1:process.stdout.isTTY===!0||process.stderr.isTTY===!0}function rr(e){return e.map(t=>Wn(t)).filter(t=>!!t)}function Wn(e){let t=ur(e.id),r=xt(t);if(r)return{id:r,name:ce(e.name),path:ce(e.path),url:ce(e.url),owner:ce(e.owner),slug:ce(e.slug),runtime:nr(e.runtime),tags:nr(e.tags),updatedAt:ce(e.updatedAt)}}function ur(e){return String(e||"").trim()}function ce(e){return ur(e)||void 0}function nr(e){if(e===void 0)return[];if(typeof e=="string")return e.split(",").map(r=>r.trim()).filter(Boolean);if(!Array.isArray(e))return[];let t=[];for(let r of e){if(typeof r!="string")continue;let n=r.trim();n&&t.push(n)}return t}function Je(e){let t=e.indexOf(":");if(t<1)return;let r=e.slice(0,t).trim();if(r)return r.toLowerCase()}function or(e){let t=e===void 0?20:Math.floor(e);return Number.isFinite(t)&&t>0?t:20}function Gn(e){let t=(e.name||"").trim();if(!t)return"";let r=Vn(e);return r&&t.toLowerCase()===r.toLowerCase()?"":t}function Vn(e){if(e.slug&&e.slug.trim())return e.slug.trim();let t=e.id.trim(),r=t.indexOf(":"),n=r>=0?t.slice(r+1):t,o=n.split("/").filter(Boolean);return o.length?o[o.length-1]:n}function Zn(e){if(!e)return"";let t=new Date(e);return Number.isNaN(t.getTime())?"":` (updated ${t.toISOString().slice(0,10)})`}async function ir(e){try{return await O.access(e),!0}catch{return!1}}async function Se(e,t){let{stdout:r}=await Tn("git",t,{cwd:e});return r.trim()}async function mr(){await On()}import{mkdtemp as Xn,rm as Yn}from"fs/promises";import Qn from"os";import eo from"path";function to(e){let t=e.trim();if(t&&!(/^[a-zA-Z]:[\\/]/.test(t)||t.startsWith("/")||t.startsWith("./")||t.startsWith("../"))&&(/^[a-z][a-z0-9+.-]*:/.test(t)||t.startsWith("git@")||t.startsWith("ssh://")||t.startsWith("http://")||t.startsWith("https://")||t.startsWith("file://")))return t}async function pr(e){try{return(await h(["config","--get-regexp","^remote..*.url$"],e)).split(`
230
+ `),n=0;if((r[0]||"").trim()==="---"){for(n=1;n<r.length&&r[n].trim()!=="---";)n+=1;n<r.length&&r[n].trim()==="---"&&(n+=1)}let o,i;for(let s=n;s<r.length;s+=1){let c=r[s].trim();if(!c){if(i)break;continue}if(!o&&c.startsWith("#")){o=c.replace(/^#+\s*/,"").trim();continue}if(!i&&!c.startsWith(">")){i=c;break}}return{title:o,summary:i}}function tr(e){return Array.isArray(e)}async function Bn(){let e=await Be();return new Set(e.map(t=>t.id))}async function Be(e=void 0){let t=process.env.SKILLCRAFT_SEARCH_INDEX_PATH?.trim(),r=t||process.env.SKILLCRAFT_SEARCH_INDEX_URL||"https://skillcraft.gg/skills-registry/search/index.json",n=async()=>{if(t){let u=await M.readFile(t,"utf8"),l=JSON.parse(u);return rr(tr(l)?l:[])}let s=process.env.SKILLCRAFT_SEARCH_INDEX_URL||"https://skillcraft.gg/skills-registry/search/index.json",c=await fetch(s,{headers:{"user-agent":"skillcraft-cli"}});if(!c.ok)throw new Error(`failed to download search index from ${s}`);let a=await c.json();return rr(tr(a)?a:[])};if(!Jn(e))return n();let o=t?`reading local index from ${r}`:`downloading index from ${r}`,i=_n({text:`Loading ${o}...`}).start();try{let s=await n();return i.succeed(`loaded ${s.length} indexed entries`),s}catch(s){throw i.fail("failed to load search index"),s}}function Jn(e){return e!=="text"?!1:process.stdout.isTTY===!0||process.stderr.isTTY===!0}function rr(e){return e.map(t=>Wn(t)).filter(t=>!!t)}function Wn(e){let t=ur(e.id),r=xt(t);if(r)return{id:r,name:ce(e.name),path:ce(e.path),url:ce(e.url),owner:ce(e.owner),slug:ce(e.slug),runtime:nr(e.runtime),tags:nr(e.tags),updatedAt:ce(e.updatedAt)}}function ur(e){return String(e||"").trim()}function ce(e){return ur(e)||void 0}function nr(e){if(e===void 0)return[];if(typeof e=="string")return e.split(",").map(r=>r.trim()).filter(Boolean);if(!Array.isArray(e))return[];let t=[];for(let r of e){if(typeof r!="string")continue;let n=r.trim();n&&t.push(n)}return t}function Je(e){let t=e.indexOf(":");if(t<1)return;let r=e.slice(0,t).trim();if(r)return r.toLowerCase()}function or(e){let t=e===void 0?20:Math.floor(e);return Number.isFinite(t)&&t>0?t:20}function Gn(e){let t=(e.name||"").trim();if(!t)return"";let r=Vn(e);return r&&t.toLowerCase()===r.toLowerCase()?"":t}function Vn(e){if(e.slug&&e.slug.trim())return e.slug.trim();let t=e.id.trim(),r=t.indexOf(":"),n=r>=0?t.slice(r+1):t,o=n.split("/").filter(Boolean);return o.length?o[o.length-1]:n}function Zn(e){if(!e)return"";let t=new Date(e);return Number.isNaN(t.getTime())?"":` (updated ${t.toISOString().slice(0,10)})`}async function ir(e){try{return await M.access(e),!0}catch{return!1}}async function Se(e,t){let{stdout:r}=await Tn("git",t,{cwd:e});return r.trim()}async function mr(){await On()}import{mkdtemp as Xn,rm as Yn}from"fs/promises";import Qn from"os";import eo from"path";function to(e){let t=e.trim();if(t&&!(/^[a-zA-Z]:[\\/]/.test(t)||t.startsWith("/")||t.startsWith("./")||t.startsWith("../"))&&(/^[a-z][a-z0-9+.-]*:/.test(t)||t.startsWith("git@")||t.startsWith("ssh://")||t.startsWith("http://")||t.startsWith("https://")||t.startsWith("file://")))return t}async function pr(e){try{return(await h(["config","--get-regexp","^remote..*.url$"],e)).split(`
231
231
  `).map(r=>r.trim()).filter(Boolean).map(r=>{let n=r.indexOf(" ");if(n===-1)return;let o=r.slice(0,n),i=r.slice(n+1).trim(),s=o.slice(7,-4);if(!(!i||!s))return{name:s,url:i}}).filter(r=>!!r)}catch{return[]}}async function fr(e){return We(e,{normalize:!0})}async function We(e,t={}){let r=t.normalize??!0,n=[];for(let o of e){let i=r?to(o.repo):o.repo;if(!i){for(let a of o.commits)n.push({repo:o.repo,commit:a});continue}let s=Array.from(new Set(o.commits.map(a=>a.trim()).filter(Boolean)));if(!s.length)continue;let c=await ro(i,s);for(let a of c)n.push({repo:i,commit:a})}return n}async function ro(e,t){let r=Array.from(new Set(t.map(o=>o.trim()).filter(Boolean)));if(!r.length)return[];let n=await Xn(eo.join(Qn.tmpdir(),"skillcraft-remote-check-"));try{try{await h(["clone","--quiet","--no-checkout",e,n],process.cwd())}catch{return r}let o=[];for(let i of r)await no(n,i)||o.push(i);return o}finally{await Yn(n,{recursive:!0,force:!0})}}async function no(e,t){try{await h(["cat-file","-e",`${t}^{commit}`],e)}catch{return!1}try{return!!await h(["branch","-r","--contains",t],e)}catch{return!1}}async function gr(){let e=process.cwd();if(!await P(e))throw new Error("Repository is not enabled");let r=(await pe(e,200)).map(l=>l.message.match(/Skillcraft-Ref:\s*(\S+)/)?.[1]).filter(Boolean),n=0,o=[];for(let l of r){let d=await _e(e,l);if(!d){n+=1,process.stdout.write(`missing proof object: ${l}
232
232
  `);continue}if(!d.commit||!d.timestamp){n+=1,process.stdout.write(`invalid proof object: ${l}
233
233
  `);continue}o.push(d.commit)}if(n>0){process.stdout.write(`verify failed: ${n} missing/invalid proofs
@@ -235,9 +235,9 @@ ${l.join(`
235
235
  `);let i=await pr(e);if(!i.length){process.stdout.write(`\u26A0\uFE0F Warning: no git remotes configured for repository
236
236
  `);return}let s=i.map(l=>({repo:l.url,commits:o})),c=await We(s,{normalize:!1}),a=new Map;for(let{repo:l,commit:d}of c){let m=a.get(l);m?m.push(d):a.set(l,[d])}let u=l=>{let d=a.get(l);return d?Array.from(new Set(d)):[]};for(let l of i){let d=u(l.url);d.length>0?process.stdout.write(`\u26A0\uFE0F Warning: proof commits not pushed to ${l.url}: ${d.join(", ")}
237
237
  `):process.stdout.write(`remote status: ${l.url} (all referenced proof commits present)
238
- `)}}import{createHash as oo}from"crypto";import hr from"yaml";async function Ge(){let e=await j(),t=U(e.provider??"gh"),r=await Ve(t),o=(await t.listClaimIssues("skillcraft-gg/credential-ledger")).filter(i=>{let s=Ze(i.body);return s?.claimant===N(r)&&!!s?.credential});if(!o.length){process.stdout.write(`no claims found for ${r||"user"}
238
+ `)}}import{createHash as oo}from"crypto";import hr from"yaml";async function Ge(){let e=await j(),t=q(e.provider??"gh"),r=await Ve(t,e.githubUser),o=(await t.listClaimIssues("skillcraft-gg/credential-ledger")).filter(i=>{let s=Ze(i.body);return s?.claimant===N(r)&&!!s?.credential});if(!o.length){process.stdout.write(`no claims found for ${r||"user"}
239
239
  `);return}for(let i of o)process.stdout.write(`#${i.number} ${i.title} (${kr(i.labels?.map(s=>s?.name)||[])})
240
- `)}async function wr(e){let t=N(e);if(!t)throw new Error("claim status requires a credential identifier");let r=await j(),n=U(r.provider??"gh"),o=await Ve(n),i=await io(n,t,o);if(!i)throw new Error(`No claim found for credential ${t} for user ${o||"unknown"}. Run "skillcraft claim" to see your claims.`);let s=await n.getIssueStatus("skillcraft-gg/credential-ledger",i),c=await n.listClaimProcessingRuns("skillcraft-gg/credential-ledger",i);if(process.stdout.write(`issue #${i}
240
+ `)}async function wr(e){let t=N(e);if(!t)throw new Error("claim status requires a credential identifier");let r=await j(),n=q(r.provider??"gh"),o=await Ve(n,r.githubUser),i=await io(n,t,o);if(!i)throw new Error(`No claim found for credential ${t} for user ${o||"unknown"}. Run "skillcraft claim" to see your claims.`);let s=await n.getIssueStatus("skillcraft-gg/credential-ledger",i),c=await n.listClaimProcessingRuns("skillcraft-gg/credential-ledger",i);if(process.stdout.write(`issue #${i}
241
241
  `),process.stdout.write(`state: ${kr(s.labels)}
242
242
  `),process.stdout.write(`labels: ${s.labels.join(", ")||"none"}
243
243
  `),process.stdout.write(`url: ${s.url}
@@ -245,16 +245,16 @@ ${l.join(`
245
245
  `);return}let a=c[0],u=a.conclusion?` (${a.conclusion})`:"";process.stdout.write(`processing actions: ${a.status}${u}
246
246
  `),process.stdout.write(`latest run: ${a.url}
247
247
  `),c.length>1&&process.stdout.write(`previous attempts: ${c.length-1}
248
- `)}async function io(e,t,r){let n=await e.listClaimIssues("skillcraft-gg/credential-ledger"),o=N(t),i=N(r);return n.map(c=>{let a=Ze(c.body);if(!(!a||a.claimant!==i||a.credential!==o))return c.number}).filter(c=>!!c).sort((c,a)=>a-c)[0]}async function yr(e,t){let r=await j(),n=U(r.provider??"gh"),o=await Ve(n),i=await co(e,{allRepos:t?.allRepos,repo:t?.repo},o),s=N(e),c=N(o),a=await fr(i.sources);if(a.length>0){process.stdout.write(`\u26A0\uFE0F Warning: some claim commits may not be pushed yet. Please push recent commits before re-submitting the claim.
248
+ `)}async function io(e,t,r){let n=await e.listClaimIssues("skillcraft-gg/credential-ledger"),o=N(t),i=N(r);return n.map(c=>{let a=Ze(c.body);if(!(!a||a.claimant!==i||a.credential!==o))return c.number}).filter(c=>!!c).sort((c,a)=>a-c)[0]}async function yr(e,t){let r=await j(),n=q(r.provider??"gh"),o=await Ve(n,r.githubUser),i=await co(e,{allRepos:t?.allRepos,repo:t?.repo},o),s=N(e),c=N(o),a=await fr(i.sources);if(a.length>0){process.stdout.write(`\u26A0\uFE0F Warning: some claim commits may not be pushed yet. Please push recent commits before re-submitting the claim.
249
249
  `);for(let d of a)process.stdout.write(`- ${d.commit} in ${d.repo}
250
250
  `);process.exitCode=1;return}s&&c&&await so(n,s,c);let u=hr.stringify(i),l=await n.createIssue("skillcraft-gg/credential-ledger",`claim: ${e}`,u);process.stdout.write(`opened claim: #${l}
251
251
  `),process.stdout.write(`payload:
252
252
  ${u}
253
- `)}async function Ve(e){let t=process.env.GITHUB_USER||process.env.USER||"";try{let r=await e.getUser();if(r)return r}catch{}return t||"unknown"}function N(e){return(e||"").trim().toLowerCase()}async function so(e,t,r){let o=(await e.listClaimIssues("skillcraft-gg/credential-ledger")).find(s=>{if(!ao(s,"skillcraft-issued"))return!1;let c=Ze(s.body);return c?c.credential===t&&c.claimant===r:!1});if(!o)return;let i=o.url?` (${o.url})`:"";throw new Error(`You already have an issued claim for ${t}. Existing issue: #${o.number}${i}`)}function Ze(e){if(e)try{let t=String(e).replace(/\\n/g,`
254
- `),r=hr.parse(t);if(!r||typeof r!="object")return;let n=r.credential&&typeof r.credential=="string"?r.credential:r.credential?.id,o=r.claimant?.github,i=N(n),s=N(o);return!i||!s?void 0:{credential:i,claimant:s}}catch{return}}function ao(e,t){let r=t.toLowerCase();return(e.labels||[]).some(n=>N(n?.name)===r)}function kr(e){let t=new Set((e||[]).map(r=>N(r)));return t.has("skillcraft-issued")?"issued":t.has("skillcraft-rejected")?"rejected":t.has("skillcraft-verified")?"verified":t.has("skillcraft-processing")?"processing":"pending"}async function co(e,t,r=process.env.GITHUB_USER||process.env.USER||"unknown"){let n=await lo(t),o=[];for(let a of n){let u=await se(a),l=await M(a)||a,d=Array.from(new Set(u.map(m=>m?.commit).filter(Boolean)));o.push({repo:l,commits:d})}let i=r,s=`${i}:${e}:${o.map(a=>`${a.repo}:${a.commits.length}`).join("|")}:${Date.now()}`,c=oo("sha256").update(s).digest("hex").slice(0,8);return{claim_version:1,claimant:{github:i},credential:{id:e},sources:o,claim_id:`sha256:${c}`}}async function lo(e){let t=e.allRepos?(await _()).repos.map(o=>o.path):[process.cwd()],r=e.repo?e.repo:t,n=[];for(let o of r)await Nt(o)&&n.push(o);return n}import me from"path";import Y from"fs/promises";import{execFile as uo}from"child_process";import{promisify as mo}from"util";var po=mo(uo);async function vr(e){if(!je(e))throw new Error("loadout id must be <owner>/<slug>");let t=process.cwd();if(!await P(t))throw new Error("Repository is not enabled");let r=await v(R(t)),n=Array.isArray(r?.activeLoadouts)?r.activeLoadouts.filter(Boolean):[];n.includes(e)||n.push(e),await y(R(t),{activeLoadouts:n}),process.stdout.write(`activated loadout: ${e}
253
+ `)}async function Ve(e,t){let r=process.env.GITHUB_USER||process.env.USER||"";try{let n=await e.getUser();if(n)return n}catch{}return t||r||"unknown"}function N(e){return(e||"").trim().toLowerCase()}async function so(e,t,r){let o=(await e.listClaimIssues("skillcraft-gg/credential-ledger")).find(s=>{if(!ao(s,"skillcraft-issued"))return!1;let c=Ze(s.body);return c?c.credential===t&&c.claimant===r:!1});if(!o)return;let i=o.url?` (${o.url})`:"";throw new Error(`You already have an issued claim for ${t}. Existing issue: #${o.number}${i}`)}function Ze(e){if(e)try{let t=String(e).replace(/\\n/g,`
254
+ `),r=hr.parse(t);if(!r||typeof r!="object")return;let n=r.credential&&typeof r.credential=="string"?r.credential:r.credential?.id,o=r.claimant?.github,i=N(n),s=N(o);return!i||!s?void 0:{credential:i,claimant:s}}catch{return}}function ao(e,t){let r=t.toLowerCase();return(e.labels||[]).some(n=>N(n?.name)===r)}function kr(e){let t=new Set((e||[]).map(r=>N(r)));return t.has("skillcraft-issued")?"issued":t.has("skillcraft-rejected")?"rejected":t.has("skillcraft-verified")?"verified":t.has("skillcraft-processing")?"processing":"pending"}async function co(e,t,r="unknown"){let n=await lo(t),o=[];for(let a of n){let u=await se(a),l=await z(a)||a,d=Array.from(new Set(u.map(m=>m?.commit).filter(Boolean)));o.push({repo:l,commits:d})}let i=r,s=`${i}:${e}:${o.map(a=>`${a.repo}:${a.commits.length}`).join("|")}:${Date.now()}`,c=oo("sha256").update(s).digest("hex").slice(0,8);return{claim_version:1,claimant:{github:i},credential:{id:e},sources:o,claim_id:`sha256:${c}`}}async function lo(e){let t=e.allRepos?(await T()).repos.map(o=>o.path):[process.cwd()],r=e.repo?e.repo:t,n=[];for(let o of r)await qt(o)&&n.push(o);return n}import me from"path";import Y from"fs/promises";import{execFile as uo}from"child_process";import{promisify as mo}from"util";var po=mo(uo);async function vr(e){if(!je(e))throw new Error("loadout id must be <owner>/<slug>");let t=process.cwd();if(!await P(t))throw new Error("Repository is not enabled");let r=await v(R(t)),n=Array.isArray(r?.activeLoadouts)?r.activeLoadouts.filter(Boolean):[];n.includes(e)||n.push(e),await y(R(t),{activeLoadouts:n}),process.stdout.write(`activated loadout: ${e}
255
255
  `)}async function xr(){let e=process.cwd();if(!await P(e))throw new Error("Repository is not enabled");await y(R(e),{activeLoadouts:[]}),process.stdout.write(`cleared active loadouts
256
- `)}async function Pr(e){let t=T(e,"loadout id");if(!je(t))throw new Error("loadout id must be <owner>/<slug>");let{owner:r,slug:n}=ve(t),o=process.cwd(),i=me.join(o,"loadout.yaml");if(await Y.access(i),!(await Y.stat(i)).isFile())throw new Error("loadout.yaml not found in current directory");let c=await j(),a=U(c.provider??"gh"),u="skillcraft-gg/loadouts",l=me.join(process.cwd(),".skillcraft-temp-loadout-share"),d=`skillcraft-loadout-${r}-${n}`;try{await Y.rm(l,{force:!0,recursive:!0}),await a.cloneRepo(u,l),await $e(l,["checkout","-B",d]);let m=me.join(l,"loadouts",r,n);await Y.rm(m,{force:!0,recursive:!0}).catch(()=>{}),await Y.mkdir(me.dirname(m),{recursive:!0}),await Y.copyFile(i,me.join(m,"loadout.yaml")),await $e(l,["add",m]),await $e(l,["commit","-m",`Loadout: publish ${t}`]).catch(async()=>{throw new Error("nothing to commit; loadout may already be published")}),await $e(l,["push","-u","origin",d]).catch(()=>{throw new Error("unable to push loadout publish branch")}),await a.createPullRequest(u,d,`Loadout publish: ${t}`).catch(()=>{process.stdout.write(`unable to create PR automatically. Please open one manually from your branch.
256
+ `)}async function Pr(e){let t=O(e,"loadout id");if(!je(t))throw new Error("loadout id must be <owner>/<slug>");let{owner:r,slug:n}=ve(t),o=process.cwd(),i=me.join(o,"loadout.yaml");if(await Y.access(i),!(await Y.stat(i)).isFile())throw new Error("loadout.yaml not found in current directory");let c=await j(),a=q(c.provider??"gh"),u="skillcraft-gg/loadouts",l=me.join(process.cwd(),".skillcraft-temp-loadout-share"),d=`skillcraft-loadout-${r}-${n}`;try{await Y.rm(l,{force:!0,recursive:!0}),await a.cloneRepo(u,l),await $e(l,["checkout","-B",d]);let m=me.join(l,"loadouts",r,n);await Y.rm(m,{force:!0,recursive:!0}).catch(()=>{}),await Y.mkdir(me.dirname(m),{recursive:!0}),await Y.copyFile(i,me.join(m,"loadout.yaml")),await $e(l,["add",m]),await $e(l,["commit","-m",`Loadout: publish ${t}`]).catch(async()=>{throw new Error("nothing to commit; loadout may already be published")}),await $e(l,["push","-u","origin",d]).catch(()=>{throw new Error("unable to push loadout publish branch")}),await a.createPullRequest(u,d,`Loadout publish: ${t}`).catch(()=>{process.stdout.write(`unable to create PR automatically. Please open one manually from your branch.
257
257
  `)}),process.stdout.write(`loadout publish workflow completed for ${t}
258
- `)}finally{await Y.rm(l,{force:!0,recursive:!0})}}async function $e(e,t){let{stdout:r}=await po("git",t,{cwd:e});return r.trim()}async function br(e){if(!await P(e))return;let t=await re(e),r=new Date().toISOString(),n=await Lt(e,t,r);if(!n)return;let o=await jt(e,n.proofId);await st(e,o);let i=await re(e);i!==t&&await Te(e,{...n.proof,commit:i}),await y(L(e),{skills:[]})}async function Rr(e,t="origin"){await It(e,t)}var b=new fo;b.name("skillcraft").description("Skillcraft CLI").version(et.version);b.option("--json","machine-readable JSON output");b.command("enable").description("Enable Skillcraft in the current repository").action(w(_t));b.command("disable").description("Disable Skillcraft in the current repository").action(w(vt));b.command("status").description("Show repository Skillcraft status").action(w(qt));b.command("doctor").description("Check environment and integration readiness").action(w(Ft));var Cr=b.command("repos").description("Manage tracked repositories");Cr.command("list").description("List tracked repositories").action(w(Tt));Cr.command("prune").description("Remove unavailable repository entries").action(w(Ot));var Xe=b.command("progress").description("Show progress for tracked credentials");Xe.option("--refresh","refresh the local credential index cache before evaluating progress").action((e,t)=>{let r=t.parent?.opts()?.json?"json":"text";w(()=>Zt({outputMode:r,refreshIndex:e.refresh}))()});Xe.command("track <credential-id>").description("Track a credential for local progress evaluation").action(e=>w(()=>Xt(e))());Xe.command("untrack <credential-id>").description("Untrack a credential from local progress evaluation").action(e=>w(()=>Yt(e))());var de=b.command("skills").description("Manage local skill publishing");de.command("add <id>").description("Add a local or external skill from the registry index").action(e=>w(()=>ar(e))());de.command("publish <owner-slug>").description("Publish a skill to the registry").action(e=>w(()=>sr(e))());de.command("validate").description("Validate local skill layout").action(w(mr));de.command("list").description("List detected skills in the current repository").action(w(cr));de.command("inspect <id>").description("Show detailed information for a registry skill").action((e,t,r)=>{let n=r.parent?.parent?.opts()?.json?"json":"text";w(()=>lr(e,{outputMode:n}))()});de.command("search [query]").description("Search the published skill index").option("--source <source>","filter to a registry source").option("--limit <n>","limit number of results",e=>Number.parseInt(e,10)).action((e,t,r)=>{let n=r.parent?.parent?.opts()?.json?"json":"text";w(()=>dr(e,{source:t.source,limit:t.limit,outputMode:n}))()});b.command("verify").description("Verify local Skillcraft proofs and trailers").action(w(gr));var Ye=b.command("claim").description("Claim a credential or inspect your claims");Ye.argument("[credential]","credential identifier").option("--all-repos","include tracked repositories").option("--repo <path...>","explicit repositories to include").action((e,t)=>{if(!e){w(()=>Ge())();return}w(()=>yr(e,{allRepos:t.allRepos,repo:t.repo}))()});Ye.command("list").description("List your claims in the credentials repository").action(w(Ge));Ye.command("status <credential>").description("Show claim status by credential identifier").action(e=>w(()=>wr(e))());var Qe=b.command("loadout").description("Manage active loadouts");Qe.command("use <id>").description("Activate a loadout in local context").action(e=>w(()=>vr(e))());Qe.command("clear").description("Clear active loadouts").action(w(xr));Qe.command("share <id>").description("Publish local loadout to registry").action(e=>w(()=>Pr(e))());b.command("_hook <name> [repoPath] [remote]",{hidden:!0}).description("internal hook command").action((e,t,r)=>w(async()=>{e==="post-commit"&&await br(t||process.cwd()),(e==="pre-push"||e==="post-push")&&await Rr(t||process.cwd(),r||"origin")})());function w(e){return(...t)=>{Promise.resolve(e(...t)).catch(r=>{process.stderr.write(`${r instanceof Error?r.message:String(r)}
258
+ `)}finally{await Y.rm(l,{force:!0,recursive:!0})}}async function $e(e,t){let{stdout:r}=await po("git",t,{cwd:e});return r.trim()}async function br(e){if(!await P(e))return;let t=await re(e),r=new Date().toISOString(),n=await Lt(e,t,r);if(!n)return;let o=await jt(e,n.proofId);await st(e,o);let i=await re(e);i!==t&&await Te(e,{...n.proof,commit:i}),await y(L(e),{skills:[]})}async function Rr(e,t="origin"){await It(e,t)}var b=new fo;b.name("skillcraft").description("Skillcraft CLI").version(et.version);b.option("--json","machine-readable JSON output");b.command("enable").description("Enable Skillcraft in the current repository").action(w(Tt));b.command("disable").description("Disable Skillcraft in the current repository").action(w(vt));b.command("status").description("Show repository Skillcraft status").action(w(Nt));b.command("doctor").description("Check environment and integration readiness").action(w(Ft));var Cr=b.command("repos").description("Manage tracked repositories");Cr.command("list").description("List tracked repositories").action(w(Ot));Cr.command("prune").description("Remove unavailable repository entries").action(w(Mt));var Xe=b.command("progress").description("Show progress for tracked credentials");Xe.option("--refresh","refresh the local credential index cache before evaluating progress").action((e,t)=>{let r=t.parent?.opts()?.json?"json":"text";w(()=>Xt({outputMode:r,refreshIndex:e.refresh}))()});Xe.command("track <credential-id>").description("Track a credential for local progress evaluation").action(e=>w(()=>Yt(e))());Xe.command("untrack <credential-id>").description("Untrack a credential from local progress evaluation").action(e=>w(()=>Qt(e))());var de=b.command("skills").description("Manage local skill publishing");de.command("add <id>").description("Add a local or external skill from the registry index").action(e=>w(()=>ar(e))());de.command("publish <owner-slug>").description("Publish a skill to the registry").action(e=>w(()=>sr(e))());de.command("validate").description("Validate local skill layout").action(w(mr));de.command("list").description("List detected skills in the current repository").action(w(cr));de.command("inspect <id>").description("Show detailed information for a registry skill").action((e,t,r)=>{let n=r.parent?.parent?.opts()?.json?"json":"text";w(()=>lr(e,{outputMode:n}))()});de.command("search [query]").description("Search the published skill index").option("--source <source>","filter to a registry source").option("--limit <n>","limit number of results",e=>Number.parseInt(e,10)).action((e,t,r)=>{let n=r.parent?.parent?.opts()?.json?"json":"text";w(()=>dr(e,{source:t.source,limit:t.limit,outputMode:n}))()});b.command("verify").description("Verify local Skillcraft proofs and trailers").action(w(gr));var Ye=b.command("claim").description("Claim a credential or inspect your claims");Ye.argument("[credential]","credential identifier").option("--all-repos","include tracked repositories").option("--repo <path...>","explicit repositories to include").action((e,t)=>{if(!e){w(()=>Ge())();return}w(()=>yr(e,{allRepos:t.allRepos,repo:t.repo}))()});Ye.command("list").description("List your claims in the credentials repository").action(w(Ge));Ye.command("status <credential>").description("Show claim status by credential identifier").action(e=>w(()=>wr(e))());var Qe=b.command("loadout").description("Manage active loadouts");Qe.command("use <id>").description("Activate a loadout in local context").action(e=>w(()=>vr(e))());Qe.command("clear").description("Clear active loadouts").action(w(xr));Qe.command("share <id>").description("Publish local loadout to registry").action(e=>w(()=>Pr(e))());b.command("_hook <name> [repoPath] [remote]",{hidden:!0}).description("internal hook command").action((e,t,r)=>w(async()=>{e==="post-commit"&&await br(t||process.cwd()),(e==="pre-push"||e==="post-push")&&await Rr(t||process.cwd(),r||"origin")})());function w(e){return(...t)=>{Promise.resolve(e(...t)).catch(r=>{process.stderr.write(`${r instanceof Error?r.message:String(r)}
259
259
  `),process.exitCode=1})}}b.parse(process.argv);
260
260
  //# sourceMappingURL=index.js.map