mirror of
https://github.com/prompt-security/clawsec.git
synced 2026-06-15 06:21:21 +03:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f76824bdb6 |
Generated
+406
@@ -0,0 +1,406 @@
|
||||
{
|
||||
"name": "clawhub-cli-pin",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "clawhub-cli-pin",
|
||||
"dependencies": {
|
||||
"clawhub": "0.7.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@ark/schema": {
|
||||
"version": "0.56.0",
|
||||
"resolved": "https://prompt-security-443370709039.d.codeartifact.eu-north-1.amazonaws.com/npm/npm-proxy/@ark/schema/-/schema-0.56.0.tgz",
|
||||
"integrity": "sha512-ECg3hox/6Z/nLajxXqNhgPtNdHWC9zNsDyskwO28WinoFEnWow4IsERNz9AnXRhTZJnYIlAJ4uGn3nlLk65vZA==",
|
||||
"dependencies": {
|
||||
"@ark/util": "0.56.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@ark/util": {
|
||||
"version": "0.56.0",
|
||||
"resolved": "https://prompt-security-443370709039.d.codeartifact.eu-north-1.amazonaws.com/npm/npm-proxy/@ark/util/-/util-0.56.0.tgz",
|
||||
"integrity": "sha512-BghfRC8b9pNs3vBoDJhcta0/c1J1rsoS1+HgVUreMFPdhz/CRAKReAu57YEllNaSy98rWAdY1gE+gFup7OXpgA=="
|
||||
},
|
||||
"node_modules/@clack/core": {
|
||||
"version": "0.5.0",
|
||||
"resolved": "https://prompt-security-443370709039.d.codeartifact.eu-north-1.amazonaws.com/npm/npm-proxy/@clack/core/-/core-0.5.0.tgz",
|
||||
"integrity": "sha512-p3y0FIOwaYRUPRcMO7+dlmLh8PSRcrjuTndsiA0WAFbWES0mLZlrjVoBRZ9DzkPFJZG6KGkJmoEAY0ZcVWTkow==",
|
||||
"dependencies": {
|
||||
"picocolors": "^1.0.0",
|
||||
"sisteransi": "^1.0.5"
|
||||
}
|
||||
},
|
||||
"node_modules/@clack/prompts": {
|
||||
"version": "0.11.0",
|
||||
"resolved": "https://prompt-security-443370709039.d.codeartifact.eu-north-1.amazonaws.com/npm/npm-proxy/@clack/prompts/-/prompts-0.11.0.tgz",
|
||||
"integrity": "sha512-pMN5FcrEw9hUkZA4f+zLlzivQSeQf5dRGJjSUbvVYDLvpKCdQx5OaknvKzgbtXOizhP+SJJJjqEbOe55uKKfAw==",
|
||||
"dependencies": {
|
||||
"@clack/core": "0.5.0",
|
||||
"picocolors": "^1.0.0",
|
||||
"sisteransi": "^1.0.5"
|
||||
}
|
||||
},
|
||||
"node_modules/ansi-regex": {
|
||||
"version": "6.2.2",
|
||||
"resolved": "https://prompt-security-443370709039.d.codeartifact.eu-north-1.amazonaws.com/npm/npm-proxy/ansi-regex/-/ansi-regex-6.2.2.tgz",
|
||||
"integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/ansi-regex?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/arkregex": {
|
||||
"version": "0.0.5",
|
||||
"resolved": "https://prompt-security-443370709039.d.codeartifact.eu-north-1.amazonaws.com/npm/npm-proxy/arkregex/-/arkregex-0.0.5.tgz",
|
||||
"integrity": "sha512-ncYjBdLlh5/QnVsAA8De16Tc9EqmYM7y/WU9j+236KcyYNUXogpz3sC4ATIZYzzLxwI+0sEOaQLEmLmRleaEXw==",
|
||||
"dependencies": {
|
||||
"@ark/util": "0.56.0"
|
||||
}
|
||||
},
|
||||
"node_modules/arktype": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://prompt-security-443370709039.d.codeartifact.eu-north-1.amazonaws.com/npm/npm-proxy/arktype/-/arktype-2.2.0.tgz",
|
||||
"integrity": "sha512-t54MZ7ti5BhOEvzEkgKnWvqj+UbDfWig+DHr5I34xatymPusKLS0lQpNJd8M6DzmIto2QGszHfNKoFIT8tMCZQ==",
|
||||
"dependencies": {
|
||||
"@ark/schema": "0.56.0",
|
||||
"@ark/util": "0.56.0",
|
||||
"arkregex": "0.0.5"
|
||||
}
|
||||
},
|
||||
"node_modules/chalk": {
|
||||
"version": "5.6.2",
|
||||
"resolved": "https://prompt-security-443370709039.d.codeartifact.eu-north-1.amazonaws.com/npm/npm-proxy/chalk/-/chalk-5.6.2.tgz",
|
||||
"integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==",
|
||||
"engines": {
|
||||
"node": "^12.17.0 || ^14.13 || >=16.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/chalk?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/clawhub": {
|
||||
"version": "0.7.0",
|
||||
"resolved": "https://prompt-security-443370709039.d.codeartifact.eu-north-1.amazonaws.com/npm/npm-proxy/clawhub/-/clawhub-0.7.0.tgz",
|
||||
"integrity": "sha512-volW6SbX8PawlnRxxCoUTKv5Pi+N3MrBi3hlO5/m9bVaO43UFciEeYti9+01c2U5n/SKhUkw7ASvnleyNmcoSA==",
|
||||
"dependencies": {
|
||||
"@clack/prompts": "^0.11.0",
|
||||
"arktype": "^2.1.29",
|
||||
"commander": "^14.0.2",
|
||||
"fflate": "^0.8.2",
|
||||
"ignore": "^7.0.5",
|
||||
"json5": "^2.2.3",
|
||||
"mime": "^4.1.0",
|
||||
"ora": "^9.0.0",
|
||||
"p-retry": "^7.1.1",
|
||||
"semver": "^7.7.3",
|
||||
"undici": "^7.16.0"
|
||||
},
|
||||
"bin": {
|
||||
"clawdhub": "bin/clawdhub.js",
|
||||
"clawhub": "bin/clawdhub.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20"
|
||||
}
|
||||
},
|
||||
"node_modules/cli-cursor": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://prompt-security-443370709039.d.codeartifact.eu-north-1.amazonaws.com/npm/npm-proxy/cli-cursor/-/cli-cursor-5.0.0.tgz",
|
||||
"integrity": "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==",
|
||||
"dependencies": {
|
||||
"restore-cursor": "^5.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/cli-spinners": {
|
||||
"version": "3.4.0",
|
||||
"resolved": "https://prompt-security-443370709039.d.codeartifact.eu-north-1.amazonaws.com/npm/npm-proxy/cli-spinners/-/cli-spinners-3.4.0.tgz",
|
||||
"integrity": "sha512-bXfOC4QcT1tKXGorxL3wbJm6XJPDqEnij2gQ2m7ESQuE+/z9YFIWnl/5RpTiKWbMq3EVKR4fRLJGn6DVfu0mpw==",
|
||||
"engines": {
|
||||
"node": ">=18.20"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/commander": {
|
||||
"version": "14.0.3",
|
||||
"resolved": "https://prompt-security-443370709039.d.codeartifact.eu-north-1.amazonaws.com/npm/npm-proxy/commander/-/commander-14.0.3.tgz",
|
||||
"integrity": "sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==",
|
||||
"engines": {
|
||||
"node": ">=20"
|
||||
}
|
||||
},
|
||||
"node_modules/fflate": {
|
||||
"version": "0.8.3",
|
||||
"resolved": "https://prompt-security-443370709039.d.codeartifact.eu-north-1.amazonaws.com/npm/npm-proxy/fflate/-/fflate-0.8.3.tgz",
|
||||
"integrity": "sha512-tbZNuJrLwGUp3zshBtdy4W+ORxZuIh8a5ilyIEQDC5rY1f3U20JMry0Ll3WBzU58EZKsEuJFXhb5gwv8CsPvgA=="
|
||||
},
|
||||
"node_modules/get-east-asian-width": {
|
||||
"version": "1.6.0",
|
||||
"resolved": "https://prompt-security-443370709039.d.codeartifact.eu-north-1.amazonaws.com/npm/npm-proxy/get-east-asian-width/-/get-east-asian-width-1.6.0.tgz",
|
||||
"integrity": "sha512-QRbvDIbx6YklUe6RxeTeleMR0yv3cYH6PsPZHcnVn7xv7zO1BHN8r0XETu8n6Ye3Q+ahtSarc3WgtNWmehIBfA==",
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/ignore": {
|
||||
"version": "7.0.5",
|
||||
"resolved": "https://prompt-security-443370709039.d.codeartifact.eu-north-1.amazonaws.com/npm/npm-proxy/ignore/-/ignore-7.0.5.tgz",
|
||||
"integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==",
|
||||
"engines": {
|
||||
"node": ">= 4"
|
||||
}
|
||||
},
|
||||
"node_modules/is-interactive": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://prompt-security-443370709039.d.codeartifact.eu-north-1.amazonaws.com/npm/npm-proxy/is-interactive/-/is-interactive-2.0.0.tgz",
|
||||
"integrity": "sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/is-network-error": {
|
||||
"version": "1.3.2",
|
||||
"resolved": "https://prompt-security-443370709039.d.codeartifact.eu-north-1.amazonaws.com/npm/npm-proxy/is-network-error/-/is-network-error-1.3.2.tgz",
|
||||
"integrity": "sha512-PhBY86zaxNZUuWP6h13Vu5oFe0XY6/UlKzQnYFELzGVHygP3MxmvTfYSG7GN3aIab/iWudSMgjSnG9Dq+nHrgA==",
|
||||
"engines": {
|
||||
"node": ">=16"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/is-unicode-supported": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://prompt-security-443370709039.d.codeartifact.eu-north-1.amazonaws.com/npm/npm-proxy/is-unicode-supported/-/is-unicode-supported-2.1.0.tgz",
|
||||
"integrity": "sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==",
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/json5": {
|
||||
"version": "2.2.3",
|
||||
"resolved": "https://prompt-security-443370709039.d.codeartifact.eu-north-1.amazonaws.com/npm/npm-proxy/json5/-/json5-2.2.3.tgz",
|
||||
"integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
|
||||
"bin": {
|
||||
"json5": "lib/cli.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/log-symbols": {
|
||||
"version": "7.0.1",
|
||||
"resolved": "https://prompt-security-443370709039.d.codeartifact.eu-north-1.amazonaws.com/npm/npm-proxy/log-symbols/-/log-symbols-7.0.1.tgz",
|
||||
"integrity": "sha512-ja1E3yCr9i/0hmBVaM0bfwDjnGy8I/s6PP4DFp+yP+a+mrHO4Rm7DtmnqROTUkHIkqffC84YY7AeqX6oFk0WFg==",
|
||||
"dependencies": {
|
||||
"is-unicode-supported": "^2.0.0",
|
||||
"yoctocolors": "^2.1.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/mime": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://prompt-security-443370709039.d.codeartifact.eu-north-1.amazonaws.com/npm/npm-proxy/mime/-/mime-4.1.0.tgz",
|
||||
"integrity": "sha512-X5ju04+cAzsojXKes0B/S4tcYtFAJ6tTMuSPBEn9CPGlrWr8Fiw7qYeLT0XyH80HSoAoqWCaz+MWKh22P7G1cw==",
|
||||
"funding": [
|
||||
"https://github.com/sponsors/broofa"
|
||||
],
|
||||
"bin": {
|
||||
"mime": "bin/cli.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16"
|
||||
}
|
||||
},
|
||||
"node_modules/mimic-function": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://prompt-security-443370709039.d.codeartifact.eu-north-1.amazonaws.com/npm/npm-proxy/mimic-function/-/mimic-function-5.0.1.tgz",
|
||||
"integrity": "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==",
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/onetime": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://prompt-security-443370709039.d.codeartifact.eu-north-1.amazonaws.com/npm/npm-proxy/onetime/-/onetime-7.0.0.tgz",
|
||||
"integrity": "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==",
|
||||
"dependencies": {
|
||||
"mimic-function": "^5.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/ora": {
|
||||
"version": "9.4.0",
|
||||
"resolved": "https://prompt-security-443370709039.d.codeartifact.eu-north-1.amazonaws.com/npm/npm-proxy/ora/-/ora-9.4.0.tgz",
|
||||
"integrity": "sha512-84cglkRILFxdtA8hAvLNdMrtBpPNBTrQ9/ulg0FA7xLMnD6mifv+enAIeRmvtv+WgdCE+LPGOfQmtJRrVaIVhQ==",
|
||||
"dependencies": {
|
||||
"chalk": "^5.6.2",
|
||||
"cli-cursor": "^5.0.0",
|
||||
"cli-spinners": "^3.2.0",
|
||||
"is-interactive": "^2.0.0",
|
||||
"is-unicode-supported": "^2.1.0",
|
||||
"log-symbols": "^7.0.1",
|
||||
"stdin-discarder": "^0.3.2",
|
||||
"string-width": "^8.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/p-retry": {
|
||||
"version": "7.1.1",
|
||||
"resolved": "https://prompt-security-443370709039.d.codeartifact.eu-north-1.amazonaws.com/npm/npm-proxy/p-retry/-/p-retry-7.1.1.tgz",
|
||||
"integrity": "sha512-J5ApzjyRkkf601HpEeykoiCvzHQjWxPAHhyjFcEUP2SWq0+35NKh8TLhpLw+Dkq5TZBFvUM6UigdE9hIVYTl5w==",
|
||||
"dependencies": {
|
||||
"is-network-error": "^1.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/picocolors": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://prompt-security-443370709039.d.codeartifact.eu-north-1.amazonaws.com/npm/npm-proxy/picocolors/-/picocolors-1.1.1.tgz",
|
||||
"integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="
|
||||
},
|
||||
"node_modules/restore-cursor": {
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://prompt-security-443370709039.d.codeartifact.eu-north-1.amazonaws.com/npm/npm-proxy/restore-cursor/-/restore-cursor-5.1.0.tgz",
|
||||
"integrity": "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==",
|
||||
"dependencies": {
|
||||
"onetime": "^7.0.0",
|
||||
"signal-exit": "^4.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/semver": {
|
||||
"version": "7.8.4",
|
||||
"resolved": "https://prompt-security-443370709039.d.codeartifact.eu-north-1.amazonaws.com/npm/npm-proxy/semver/-/semver-7.8.4.tgz",
|
||||
"integrity": "sha512-rUCObTnP32Q08R2uuIrt7r9PlEonuTmtuXYcW6s5kjdlj3xbnwe+21yXptAUYcMAABLkYYTtnmzb3w3EDZfueA==",
|
||||
"bin": {
|
||||
"semver": "bin/semver.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/signal-exit": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://prompt-security-443370709039.d.codeartifact.eu-north-1.amazonaws.com/npm/npm-proxy/signal-exit/-/signal-exit-4.1.0.tgz",
|
||||
"integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==",
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/sisteransi": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://prompt-security-443370709039.d.codeartifact.eu-north-1.amazonaws.com/npm/npm-proxy/sisteransi/-/sisteransi-1.0.5.tgz",
|
||||
"integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg=="
|
||||
},
|
||||
"node_modules/stdin-discarder": {
|
||||
"version": "0.3.2",
|
||||
"resolved": "https://prompt-security-443370709039.d.codeartifact.eu-north-1.amazonaws.com/npm/npm-proxy/stdin-discarder/-/stdin-discarder-0.3.2.tgz",
|
||||
"integrity": "sha512-eCPu1qRxPVkl5605OTWF8Wz40b4Mf45NY5LQmVPQ599knfs5QhASUm9GbJ5BDMDOXgrnh0wyEdvzmL//YMlw0A==",
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/string-width": {
|
||||
"version": "8.2.1",
|
||||
"resolved": "https://prompt-security-443370709039.d.codeartifact.eu-north-1.amazonaws.com/npm/npm-proxy/string-width/-/string-width-8.2.1.tgz",
|
||||
"integrity": "sha512-IIaP0g3iy9Cyy18w3M9YcaDudujEAVHKt3a3QJg1+sr/oX96TbaGUubG0hJyCjCBThFH+tFpcIyoUHUn1ogaLA==",
|
||||
"dependencies": {
|
||||
"get-east-asian-width": "^1.5.0",
|
||||
"strip-ansi": "^7.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/strip-ansi": {
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://prompt-security-443370709039.d.codeartifact.eu-north-1.amazonaws.com/npm/npm-proxy/strip-ansi/-/strip-ansi-7.2.0.tgz",
|
||||
"integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==",
|
||||
"dependencies": {
|
||||
"ansi-regex": "^6.2.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/strip-ansi?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/undici": {
|
||||
"version": "7.27.2",
|
||||
"resolved": "https://prompt-security-443370709039.d.codeartifact.eu-north-1.amazonaws.com/npm/npm-proxy/undici/-/undici-7.27.2.tgz",
|
||||
"integrity": "sha512-uZsKNuzQxDMUY6M3pIMvy5tvlGmtq8XJ2oLAkfRKGNu+1VQAIvLy2xIVG5ATZl5wDXl/tddByAWCizRbOme+TA==",
|
||||
"engines": {
|
||||
"node": ">=20.18.1"
|
||||
}
|
||||
},
|
||||
"node_modules/yoctocolors": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://prompt-security-443370709039.d.codeartifact.eu-north-1.amazonaws.com/npm/npm-proxy/yoctocolors/-/yoctocolors-2.1.2.tgz",
|
||||
"integrity": "sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug==",
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"name": "clawhub-cli-pin",
|
||||
"private": true,
|
||||
"description": "Pins the clawhub CLI used by skill-release.yml; package-lock.json provides the integrity hashes. Bump the version here and regenerate the lockfile with: npm install --package-lock-only",
|
||||
"dependencies": {
|
||||
"clawhub": "0.7.0"
|
||||
}
|
||||
}
|
||||
@@ -19,8 +19,8 @@ on:
|
||||
|
||||
permissions: read-all
|
||||
|
||||
env:
|
||||
CLAWHUB_CLI_VERSION: 0.7.0
|
||||
# The clawhub CLI version is pinned (with integrity hashes) in
|
||||
# .github/clawhub-cli/package-lock.json — bump it there.
|
||||
|
||||
concurrency:
|
||||
group: skill-release-${{ github.ref }}
|
||||
@@ -90,15 +90,7 @@ jobs:
|
||||
'skills/*/**' \
|
||||
':(exclude)skills/*/test/**' \
|
||||
':(exclude)skills/*/tests/**' \
|
||||
| awk -F/ '
|
||||
NF >= 3 {
|
||||
path = tolower($0)
|
||||
name = tolower($NF)
|
||||
if (path ~ /(^|\/)(__tests__|test|tests)\//) next
|
||||
if (name ~ /^(test|spec)[_-]/ || name ~ /\.(test|spec)\./) next
|
||||
print $1 "/" $2
|
||||
}
|
||||
' \
|
||||
| awk -F/ 'NF >= 3 {print $1 "/" $2}' \
|
||||
| sort -u > "${touched_skills_file}"
|
||||
|
||||
if [ ! -s "${touched_skills_file}" ]; then
|
||||
@@ -408,15 +400,12 @@ jobs:
|
||||
}
|
||||
|
||||
touched_skills_file="$(mktemp)"
|
||||
git diff --name-only "${BASE_SHA}...${HEAD_SHA}" -- \
|
||||
'skills/*/**' \
|
||||
':(exclude)skills/*/test/**' \
|
||||
':(exclude)skills/*/tests/**' \
|
||||
git diff --name-only "${BASE_SHA}...${HEAD_SHA}" -- 'skills/*/skill.json' 'skills/*/SKILL.md' \
|
||||
| awk -F/ 'NF >= 3 {print $1 "/" $2}' \
|
||||
| sort -u > "${touched_skills_file}"
|
||||
|
||||
if [ ! -s "${touched_skills_file}" ]; then
|
||||
echo "No release-relevant skill package files changed in this PR."
|
||||
echo "No skill metadata files changed in this PR."
|
||||
rm -f "${touched_skills_file}"
|
||||
exit 0
|
||||
fi
|
||||
@@ -442,8 +431,7 @@ jobs:
|
||||
|
||||
is_test_release_path() {
|
||||
local lower="${1,,}"
|
||||
local name="${lower##*/}"
|
||||
[[ "$lower" == test/* || "$lower" == tests/* || "$lower" == __tests__/* || "$lower" == */test/* || "$lower" == */tests/* || "$lower" == */__tests__/* || "$name" == test_* || "$name" == test-* || "$name" == spec_* || "$name" == spec-* || "$name" == *.test.* || "$name" == *.spec.* ]]
|
||||
[[ "$lower" == test/* || "$lower" == tests/* || "$lower" == */test/* || "$lower" == */tests/* ]]
|
||||
}
|
||||
|
||||
generate_skillspector_report() {
|
||||
@@ -538,6 +526,11 @@ jobs:
|
||||
md_version_changed=true
|
||||
fi
|
||||
|
||||
if [ "${json_version_changed}" != "true" ] && [ "${md_version_changed}" != "true" ]; then
|
||||
echo "No version bump detected for ${skill_dir}; skipping dry-run."
|
||||
continue
|
||||
fi
|
||||
|
||||
if [ -z "${head_json_version}" ] || [ -z "${head_md_version}" ] || [ "${head_json_version}" != "${head_md_version}" ]; then
|
||||
echo "::error file=${skill_dir}::Version metadata is invalid for dry-run. Ensure validate-pr-version-sync passes."
|
||||
failures=$((failures + 1))
|
||||
@@ -626,9 +619,9 @@ jobs:
|
||||
# --- Create zip preserving directory structure ---
|
||||
zip_name="${skill_name}-v${version}.zip"
|
||||
(cd "${staging_dir}" && zip -qr "${OLDPWD}/${out_assets}/${zip_name}" .)
|
||||
if unzip -Z1 "${out_assets}/${zip_name}" | grep -Eiq '(^|/)(__tests__|test|tests)/|(^|/)(test|spec)[_-]|(^|/).*\.(test|spec)\.'; then
|
||||
if unzip -Z1 "${out_assets}/${zip_name}" | grep -Eiq '(^|/)(test|tests)/'; then
|
||||
echo "::error::Dry-run release archive contains test-only files: ${zip_name}"
|
||||
unzip -Z1 "${out_assets}/${zip_name}" | grep -Ei '(^|/)(__tests__|test|tests)/|(^|/)(test|spec)[_-]|(^|/).*\.(test|spec)\.' || true
|
||||
unzip -Z1 "${out_assets}/${zip_name}" | grep -Ei '(^|/)(test|tests)/' || true
|
||||
failures=$((failures + 1))
|
||||
fi
|
||||
|
||||
@@ -784,177 +777,12 @@ jobs:
|
||||
fi
|
||||
|
||||
if [ "${dry_run_count}" -eq 0 ]; then
|
||||
echo "No changed skill directories required dry-run assets."
|
||||
echo "No version bumps detected in changed skill metadata files."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "Release dry-run completed successfully for ${dry_run_count} changed skill(s)."
|
||||
|
||||
- name: Prepare SkillSpector PR report artifact
|
||||
if: always()
|
||||
run: |
|
||||
set -euo pipefail
|
||||
rm -rf dist/skillspector-pr-reports
|
||||
mkdir -p dist/dry-run dist/skillspector-pr-reports
|
||||
|
||||
found_reports=false
|
||||
while IFS= read -r report_path; do
|
||||
tag="${report_path#dist/dry-run/}"
|
||||
tag="${tag%%/*}"
|
||||
mkdir -p "dist/skillspector-pr-reports/${tag}"
|
||||
cp "${report_path}" "dist/skillspector-pr-reports/${tag}/skillspector-report.md"
|
||||
found_reports=true
|
||||
done < <(find dist/dry-run -path '*/release-assets/skillspector-report.md' -type f | sort)
|
||||
|
||||
if [ "${found_reports}" != "true" ]; then
|
||||
printf 'No SkillSpector reports were generated for this pull request.\n' > dist/skillspector-pr-reports/NO_SKILLSPECTOR_REPORTS.txt
|
||||
fi
|
||||
|
||||
- name: Upload SkillSpector PR reports
|
||||
if: always()
|
||||
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
||||
with:
|
||||
name: skillspector-pr-reports
|
||||
path: dist/skillspector-pr-reports
|
||||
retention-days: 14
|
||||
|
||||
comment-skillspector-report:
|
||||
if: always() && github.event_name == 'pull_request' && needs.release.result != 'cancelled'
|
||||
needs: release
|
||||
runs-on: ubuntu-latest
|
||||
continue-on-error: true
|
||||
permissions:
|
||||
actions: read
|
||||
contents: read
|
||||
issues: write
|
||||
pull-requests: read
|
||||
steps:
|
||||
- name: Download SkillSpector reports
|
||||
continue-on-error: true
|
||||
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
||||
with:
|
||||
name: skillspector-pr-reports
|
||||
path: skillspector-pr-reports
|
||||
|
||||
- name: Comment SkillSpector reports
|
||||
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
|
||||
with:
|
||||
script: |
|
||||
const fs = require("node:fs/promises");
|
||||
const path = require("node:path");
|
||||
|
||||
const root = "skillspector-pr-reports";
|
||||
const maxCommentLength = 65000;
|
||||
|
||||
async function findReports(dir) {
|
||||
let entries;
|
||||
try {
|
||||
entries = await fs.readdir(dir, { withFileTypes: true });
|
||||
} catch (error) {
|
||||
if (error.code === "ENOENT") {
|
||||
return [];
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
|
||||
const reports = [];
|
||||
for (const entry of entries) {
|
||||
const fullPath = path.join(dir, entry.name);
|
||||
if (entry.isDirectory()) {
|
||||
reports.push(...await findReports(fullPath));
|
||||
} else if (entry.isFile() && entry.name === "skillspector-report.md") {
|
||||
reports.push(fullPath);
|
||||
}
|
||||
}
|
||||
return reports;
|
||||
}
|
||||
|
||||
function tagFromReportPath(reportPath) {
|
||||
const parts = reportPath.split(path.sep);
|
||||
const releaseAssetsIndex = parts.lastIndexOf("release-assets");
|
||||
if (releaseAssetsIndex > 0) {
|
||||
return parts[releaseAssetsIndex - 1];
|
||||
}
|
||||
return path.basename(path.dirname(reportPath));
|
||||
}
|
||||
|
||||
function sanitizeReportForComment(report) {
|
||||
const omittedBlock = "_[code block omitted from PR comment; download the workflow artifact for raw details]_";
|
||||
return report
|
||||
.replace(/```[\s\S]*?```/g, omittedBlock)
|
||||
.split(/\r?\n/)
|
||||
.filter((line) => !/^\s{4,}\S/.test(line))
|
||||
.join("\n")
|
||||
.replace(/`[^`\n]*`/g, "`[inline snippet omitted]`")
|
||||
.replace(/\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}\b/gi, "[redacted-email]")
|
||||
.replace(/\b(?:AKIA|ASIA)[A-Z0-9]{16}\b/g, "[redacted-aws-key]")
|
||||
.replace(/\b(?:ghp|gho|ghu|ghs|ghr|github_pat|glpat|xox[baprs]?|sk|pk)_[A-Za-z0-9_=-]{12,}\b/gi, "[redacted-token]")
|
||||
.replace(/\b[A-Za-z0-9+/]{40,}={0,2}\b/g, "[redacted-secret-like-value]")
|
||||
.trimEnd();
|
||||
}
|
||||
|
||||
function buildComment({ tag, report }) {
|
||||
const marker = `<!-- clawsec-skillspector-report:${tag} -->`;
|
||||
const sanitizedReport = sanitizeReportForComment(report);
|
||||
const footer = [
|
||||
"_Generated by the Skill Release dry-run for `" + tag + "`._",
|
||||
"_Raw snippets, code blocks, inline code, emails, and token-like values are omitted from this PR comment._",
|
||||
"_Download the `skillspector-pr-reports` workflow artifact for the full report._",
|
||||
].join("\n");
|
||||
let body = `${marker}\n${sanitizedReport}\n\n${footer}`;
|
||||
|
||||
if (body.length <= maxCommentLength) {
|
||||
return body;
|
||||
}
|
||||
|
||||
const truncatedFooter = [
|
||||
"_Report truncated because it exceeds GitHub's comment size limit._",
|
||||
"_Download the `skillspector-pr-reports` workflow artifact for the full report._",
|
||||
footer,
|
||||
].join("\n");
|
||||
const budget = maxCommentLength - marker.length - truncatedFooter.length - 8;
|
||||
return `${marker}\n${sanitizedReport.slice(0, Math.max(0, budget)).trimEnd()}\n\n${truncatedFooter}`;
|
||||
}
|
||||
|
||||
const reports = await findReports(root);
|
||||
if (reports.length === 0) {
|
||||
core.info("No SkillSpector reports found; nothing to comment.");
|
||||
return;
|
||||
}
|
||||
|
||||
const comments = await github.paginate(github.rest.issues.listComments, {
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
issue_number: context.issue.number,
|
||||
per_page: 100,
|
||||
});
|
||||
|
||||
for (const reportPath of reports.sort()) {
|
||||
const tag = tagFromReportPath(reportPath);
|
||||
const report = await fs.readFile(reportPath, "utf8");
|
||||
const marker = `<!-- clawsec-skillspector-report:${tag} -->`;
|
||||
const body = buildComment({ tag, report });
|
||||
const existing = comments.find((comment) => comment.body?.includes(marker));
|
||||
|
||||
if (existing) {
|
||||
await github.rest.issues.updateComment({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
comment_id: existing.id,
|
||||
body,
|
||||
});
|
||||
core.info(`Updated SkillSpector PR comment for ${tag}.`);
|
||||
} else {
|
||||
await github.rest.issues.createComment({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
issue_number: context.issue.number,
|
||||
body,
|
||||
});
|
||||
core.info(`Created SkillSpector PR comment for ${tag}.`);
|
||||
}
|
||||
}
|
||||
|
||||
simulate-tag-release-build:
|
||||
if: github.event_name == 'pull_request'
|
||||
needs: validate-pr-version-sync
|
||||
@@ -1237,8 +1065,7 @@ jobs:
|
||||
|
||||
is_test_release_path() {
|
||||
local lower="${1,,}"
|
||||
local name="${lower##*/}"
|
||||
[[ "$lower" == test/* || "$lower" == tests/* || "$lower" == __tests__/* || "$lower" == */test/* || "$lower" == */tests/* || "$lower" == */__tests__/* || "$name" == test_* || "$name" == test-* || "$name" == spec_* || "$name" == spec-* || "$name" == *.test.* || "$name" == *.spec.* ]]
|
||||
[[ "$lower" == test/* || "$lower" == tests/* || "$lower" == */test/* || "$lower" == */tests/* ]]
|
||||
}
|
||||
|
||||
generate_skillspector_report() {
|
||||
@@ -1319,9 +1146,9 @@ jobs:
|
||||
# --- Create zip preserving directory structure ---
|
||||
ZIP_NAME="${SKILL_NAME}-v${VERSION}.zip"
|
||||
(cd "$STAGING_DIR" && zip -qr "$OLDPWD/release-assets/$ZIP_NAME" .)
|
||||
if unzip -Z1 "release-assets/$ZIP_NAME" | grep -Eiq '(^|/)(__tests__|test|tests)/|(^|/)(test|spec)[_-]|(^|/).*\.(test|spec)\.'; then
|
||||
if unzip -Z1 "release-assets/$ZIP_NAME" | grep -Eiq '(^|/)(test|tests)/'; then
|
||||
echo "::error::Release archive contains test-only files: $ZIP_NAME"
|
||||
unzip -Z1 "release-assets/$ZIP_NAME" | grep -Ei '(^|/)(__tests__|test|tests)/|(^|/)(test|spec)[_-]|(^|/).*\.(test|spec)\.' || true
|
||||
unzip -Z1 "release-assets/$ZIP_NAME" | grep -Ei '(^|/)(test|tests)/' || true
|
||||
exit 1
|
||||
fi
|
||||
|
||||
@@ -1597,6 +1424,8 @@ jobs:
|
||||
"",
|
||||
process.env.QUICK_INSTALL || "",
|
||||
"",
|
||||
"### SkillSpector Security Report",
|
||||
"",
|
||||
report,
|
||||
"",
|
||||
`Download the generated release-payload scan: [skillspector-report.md](https://github.com/${process.env.REPO}/releases/download/${process.env.TAG}/skillspector-report.md)`,
|
||||
@@ -1704,18 +1533,19 @@ jobs:
|
||||
|
||||
- name: Install clawhub CLI
|
||||
if: needs.release-tag.outputs.publish_clawhub == 'true' && env.CLAWHUB_TOKEN != ''
|
||||
run: npm install -g clawhub@${CLAWHUB_CLI_VERSION}
|
||||
run: |
|
||||
npm ci --prefix .github/clawhub-cli
|
||||
echo "${GITHUB_WORKSPACE}/.github/clawhub-cli/node_modules/.bin" >> "$GITHUB_PATH"
|
||||
|
||||
- name: Patch clawhub publish payload workaround
|
||||
# Temporary: clawhub@0.7.0 publish payload is missing acceptLicenseTerms.
|
||||
if: needs.release-tag.outputs.publish_clawhub == 'true' && env.CLAWHUB_TOKEN != ''
|
||||
run: |
|
||||
node <<'NODE'
|
||||
const { execSync } = require("node:child_process");
|
||||
const fs = require("node:fs");
|
||||
const path = require("node:path");
|
||||
|
||||
const npmRoot = execSync("npm root -g", { encoding: "utf8" }).trim();
|
||||
const npmRoot = path.join(process.env.GITHUB_WORKSPACE, ".github", "clawhub-cli", "node_modules");
|
||||
const publishScriptPath = path.join(
|
||||
npmRoot,
|
||||
"clawhub",
|
||||
@@ -1894,17 +1724,18 @@ jobs:
|
||||
run: node scripts/ci/validate_skill_install_docs.mjs --skills "${{ steps.parse.outputs.skill_path }}"
|
||||
|
||||
- name: Install clawhub CLI
|
||||
run: npm install -g clawhub@${CLAWHUB_CLI_VERSION}
|
||||
run: |
|
||||
npm ci --prefix .github/clawhub-cli
|
||||
echo "${GITHUB_WORKSPACE}/.github/clawhub-cli/node_modules/.bin" >> "$GITHUB_PATH"
|
||||
|
||||
- name: Patch clawhub publish payload workaround
|
||||
# Temporary: clawhub@0.7.0 publish payload is missing acceptLicenseTerms.
|
||||
run: |
|
||||
node <<'NODE'
|
||||
const { execSync } = require("node:child_process");
|
||||
const fs = require("node:fs");
|
||||
const path = require("node:path");
|
||||
|
||||
const npmRoot = execSync("npm root -g", { encoding: "utf8" }).trim();
|
||||
const npmRoot = path.join(process.env.GITHUB_WORKSPACE, ".github", "clawhub-cli", "node_modules");
|
||||
const publishScriptPath = path.join(
|
||||
npmRoot,
|
||||
"clawhub",
|
||||
|
||||
+1515
-1172
File diff suppressed because it is too large
Load Diff
@@ -1 +1 @@
|
||||
jPrlTYwicRwoQgTs5Rk3Y3g6Lz78jNRs9ZNf0R09M4jkJokZENxfvhvHphI9MH4u+7wv0sFZ+yZbQtJ42y+hCQ==
|
||||
agiAAFvzM1vNHxH2+bGtyeKqFScLWJHnNreBcPpTODUqD0xqFi0cnyP/ZaZX+Rsw1Y9uZ7pGdFdA93pD4lh2BQ==
|
||||
+206
-274
File diff suppressed because it is too large
Load Diff
@@ -1 +1 @@
|
||||
M1Jm4YHXsm0msygmd+XCJBRWMrXIjQfv1Y5v7XS8RCachLQwEzUJ1nhhic6CXxItNLmvgmDjVCMPVdHpnOMqDA==
|
||||
q1EyZ75QcdG2X6FVDkUoAyBtQE3ONA+7k9cmNFmXFgOOuGRPOpSDFUtbSvy86HPqnii26DMoeFJ1hatWJ0lBCQ==
|
||||
Generated
+948
-478
File diff suppressed because it is too large
Load Diff
+2
-2
@@ -31,13 +31,13 @@
|
||||
"@types/node": "^25.8.0",
|
||||
"@typescript-eslint/eslint-plugin": "^8.55.0",
|
||||
"@typescript-eslint/parser": "^8.58.1",
|
||||
"@vitejs/plugin-react": "^6.0.2",
|
||||
"@vitejs/plugin-react": "^5.1.4",
|
||||
"eslint": "^9.39.4",
|
||||
"eslint-plugin-react": "^7.37.5",
|
||||
"eslint-plugin-react-hooks": "^7.0.1",
|
||||
"fast-check": "^4.7.0",
|
||||
"typescript": "~5.9.3",
|
||||
"vite": "^8.0.16"
|
||||
"vite": "^7.3.2"
|
||||
},
|
||||
"overrides": {
|
||||
"ajv": "6.14.0",
|
||||
|
||||
@@ -34,13 +34,6 @@ assert.match(
|
||||
'Skill release validation must ignore test-only skill changes while inspecting release-relevant skill files',
|
||||
);
|
||||
|
||||
assert.ok(
|
||||
workflow.includes('name = tolower($NF)')
|
||||
&& workflow.includes('name ~ /^(test|spec)[_-]/')
|
||||
&& workflow.includes('name ~ /\\.(test|spec)\\./'),
|
||||
'Skill release validation must filter test-named skill files such as scripts/test_*.py before selecting dry-run skill directories',
|
||||
);
|
||||
|
||||
assert.doesNotMatch(
|
||||
workflow,
|
||||
/No version bump detected for \$\{skill_dir\}; skipping\./,
|
||||
@@ -95,16 +88,10 @@ assert.match(
|
||||
'Skill release workflow must generate a SkillSpector report for each released skill',
|
||||
);
|
||||
|
||||
assert.doesNotMatch(
|
||||
workflow,
|
||||
/"### SkillSpector Security Report"/,
|
||||
'GitHub release notes must not add a duplicate SkillSpector heading before the generated report',
|
||||
);
|
||||
|
||||
assert.match(
|
||||
workflow,
|
||||
/readFileSync\("release-assets\/skillspector-report\.md", "utf8"\)[\s\S]*report,[\s\S]*\[skillspector-report\.md\]\(https:\/\/github\.com\/\$\{process\.env\.REPO\}\/releases\/download\/\$\{process\.env\.TAG\}\/skillspector-report\.md\)/,
|
||||
'GitHub release notes must embed the generated SkillSpector report and include a direct report link',
|
||||
/### SkillSpector Security Report[\s\S]*\[skillspector-report\.md\]\(https:\/\/github\.com\/\$\{process\.env\.REPO\}\/releases\/download\/\$\{process\.env\.TAG\}\/skillspector-report\.md\)/,
|
||||
'GitHub release notes must include a direct SkillSpector report link',
|
||||
);
|
||||
|
||||
assert.match(
|
||||
@@ -131,20 +118,6 @@ assert.match(
|
||||
'PR dry-run SkillSpector scan must target the staged release payload, not the source skill directory',
|
||||
);
|
||||
|
||||
assert.match(
|
||||
workflow,
|
||||
/Run release dry-run for changed skills[\s\S]*git diff --name-only "\$\{BASE_SHA\}\.\.\.\$\{HEAD_SHA\}" --[\s\S]*'skills\/\*\/\*\*'[\s\S]*':\(exclude\)skills\/\*\/test\/\*\*'[\s\S]*':\(exclude\)skills\/\*\/tests\/\*\*'/,
|
||||
'PR dry-run SkillSpector scan must run when any release-relevant skill package file changes',
|
||||
);
|
||||
|
||||
assert.ok(
|
||||
workflow.includes('local name="${lower##*/}"')
|
||||
&& workflow.includes('"$name" == test_*')
|
||||
&& workflow.includes('"$name" == *.test.*')
|
||||
&& workflow.includes('(__tests__|test|tests)/|(^|/)(test|spec)[_-]|(^|/).*\\.(test|spec)\\.'),
|
||||
'Skill release archives must exclude test directories and test-named files from staged release payloads',
|
||||
);
|
||||
|
||||
assert.doesNotMatch(
|
||||
workflow,
|
||||
/generate_skillspector_report "\$\{skill_dir\}" "\$\{out_assets\}\/skillspector-report\.md"/,
|
||||
@@ -214,48 +187,6 @@ assert.match(
|
||||
'SkillSpector report must be included in the signed checksums manifest',
|
||||
);
|
||||
|
||||
assert.match(
|
||||
workflow,
|
||||
/Upload SkillSpector PR reports[\s\S]*actions\/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7\.0\.1[\s\S]*name: skillspector-pr-reports/,
|
||||
'PR dry-run must upload generated SkillSpector reports as workflow artifacts',
|
||||
);
|
||||
|
||||
assert.match(
|
||||
workflow,
|
||||
/comment-skillspector-report:[\s\S]*needs: release[\s\S]*issues: write[\s\S]*actions\/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8\.0\.1/,
|
||||
'Skill release workflow must download generated SkillSpector reports in a separate PR comment job with comment permissions',
|
||||
);
|
||||
|
||||
assert.match(
|
||||
workflow,
|
||||
/comment-skillspector-report:[\s\S]*if: always\(\) && github\.event_name == 'pull_request' && needs\.release\.result != 'cancelled'[\s\S]*Download SkillSpector reports[\s\S]*continue-on-error: true/,
|
||||
'SkillSpector PR comments must still run when the release dry-run produced reports but the release job failed later',
|
||||
);
|
||||
|
||||
assert.match(
|
||||
workflow,
|
||||
/function sanitizeReportForComment\(report\)[\s\S]*code block omitted from PR comment[\s\S]*inline snippet omitted[\s\S]*redacted-email[\s\S]*redacted-token/,
|
||||
'SkillSpector PR comments must sanitize raw report content before posting to the PR',
|
||||
);
|
||||
|
||||
assert.match(
|
||||
workflow,
|
||||
/const sanitizedReport = sanitizeReportForComment\(report\);[\s\S]*`\$\{marker\}\\n\$\{sanitizedReport\}/,
|
||||
'SkillSpector PR comments must use the sanitized report body, not the raw artifact text',
|
||||
);
|
||||
|
||||
assert.doesNotMatch(
|
||||
workflow,
|
||||
/`\$\{marker\}\\n\$\{report\.trimEnd\(\)\}/,
|
||||
'SkillSpector PR comments must not post report.trimEnd() verbatim',
|
||||
);
|
||||
|
||||
assert.match(
|
||||
workflow,
|
||||
/clawsec-skillspector-report:\$\{tag\}[\s\S]*github\.rest\.issues\.updateComment[\s\S]*github\.rest\.issues\.createComment/,
|
||||
'SkillSpector PR comments must use stable per-skill markers and update existing comments before creating new ones',
|
||||
);
|
||||
|
||||
assert.match(
|
||||
workflow,
|
||||
/Simulate tag release build/,
|
||||
|
||||
+1515
-1172
File diff suppressed because it is too large
Load Diff
@@ -1 +1 @@
|
||||
jPrlTYwicRwoQgTs5Rk3Y3g6Lz78jNRs9ZNf0R09M4jkJokZENxfvhvHphI9MH4u+7wv0sFZ+yZbQtJ42y+hCQ==
|
||||
agiAAFvzM1vNHxH2+bGtyeKqFScLWJHnNreBcPpTODUqD0xqFi0cnyP/ZaZX+Rsw1Y9uZ7pGdFdA93pD4lh2BQ==
|
||||
@@ -35,7 +35,6 @@
|
||||
| GitHub API | Deploy/release workflows | Discover releases, download assets, publish outputs. |
|
||||
| GitHub Pages | Deploy workflow | Serve static site and mirrored artifacts. |
|
||||
| ClawHub CLI/registry | Install scripts + optional publish jobs | Install and publish skills. |
|
||||
| [NVIDIA SkillSpector](https://github.com/NVIDIA/SkillSpector) | Skill release workflow | Scan staged skill release payloads and produce Markdown release evidence. |
|
||||
| Optional local SMTP/sendmail | `openclaw-audit-watchdog` scripts | Deliver audit reports by email. |
|
||||
|
||||
## Development Tools
|
||||
@@ -47,7 +46,6 @@
|
||||
| Bandit | `bandit -r utils/ -ll` | Python security checks. |
|
||||
| Trivy | Workflow + optional local run | FS/config vulnerability scans. |
|
||||
| Gitleaks | `scripts/prepare-to-push.sh` optional local run | Secret leak detection before push. |
|
||||
| SkillSpector | `.github/workflows/skill-release.yml` | Release-payload scanner used for PR comments and signed release artifacts. |
|
||||
|
||||
## Example Snippets
|
||||
```json
|
||||
@@ -85,7 +83,6 @@ skips = ["B101"]
|
||||
- PR validation enforces version parity between `skill.json` and `SKILL.md` frontmatter for bumped skills.
|
||||
- The public skills index keeps latest discovered version per skill for UI display.
|
||||
- Signed artifact manifests (`checksums.json`) are versioned per release and include file hashes and URLs.
|
||||
- SkillSpector reports are generated per release payload and included in signed artifact manifests.
|
||||
|
||||
## Source References
|
||||
- package.json
|
||||
|
||||
+1
-2
@@ -15,7 +15,6 @@
|
||||
| --- | --- |
|
||||
| Skill Tag | Git tag formatted as `<skill>-v<semver>` used by release automation. |
|
||||
| Release Assets | Files attached to GitHub release (zip, `skill.json`, checksums, signatures). |
|
||||
| SkillSpector Report | Markdown security scan evidence generated from a staged skill release payload. |
|
||||
| Catalog Index | `public/skills/index.json`, generated list consumed by web catalog. |
|
||||
| Embedded Components | Capability bundle from one skill included in another (for example feed embedded in suite). |
|
||||
|
||||
@@ -40,7 +39,7 @@
|
||||
| --- | --- |
|
||||
| Poll NVD CVEs Workflow | Scheduled workflow that fetches and transforms NVD CVEs into advisories. |
|
||||
| Community Advisory Workflow | Issue-label-triggered workflow that publishes approved community advisories. |
|
||||
| Skill Release Workflow | PR and tag-triggered packaging/signing/publishing pipeline for skills. |
|
||||
| Skill Release Workflow | Tag-triggered packaging/signing/publishing pipeline for skills. |
|
||||
| Deploy Pages Workflow | Workflow that builds site assets and mirrors release/advisory artifacts. |
|
||||
|
||||
## Source References
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
Track translation coverage and freshness versus English source docs.
|
||||
|
||||
_Last updated: 2026-06-14_
|
||||
_Last updated: 2026-04-27_
|
||||
|
||||
## README Coverage
|
||||
|
||||
@@ -24,12 +24,6 @@ _Last updated: 2026-06-14_
|
||||
| `wiki/testing.md` | — | pending |
|
||||
| `wiki/workflow.md` | — | pending |
|
||||
|
||||
## English Source Freshness Notes
|
||||
|
||||
| Date | Changed pages | Translation impact |
|
||||
| --- | --- | --- |
|
||||
| 2026-06-14 | `wiki/workflow.md`, `wiki/modules/automation-release.md`, `wiki/security-signing-runbook.md`, `wiki/dependencies.md`, `wiki/glossary.md` | Added SkillSpector release-pipeline documentation, signed-report behavior, and PR comment behavior. Translation refresh pending. |
|
||||
|
||||
## Wiki Coverage (KO)
|
||||
|
||||
| Source page | Korean page | Status |
|
||||
|
||||
@@ -19,38 +19,11 @@ This module intentionally focuses on automation/release-specific workflow behavi
|
||||
When a skill is tagged (for example, `soul-guardian-v1.0.0`), the pipeline:
|
||||
1. Validates `skill.json` version/tag alignment.
|
||||
2. Enforces signing-key consistency against canonical repo key material.
|
||||
3. Stages the release payload from SBOM-scoped files and root skill docs.
|
||||
4. Generates release trust packet files, install instructions, and a SkillSpector security report.
|
||||
5. Generates `checksums.json` for the archive and release assets.
|
||||
6. Signs and verifies release checksum artifacts.
|
||||
7. Publishes GitHub Release assets.
|
||||
8. Supersedes older releases within the same major version (tags remain).
|
||||
9. Triggers website catalog refresh.
|
||||
|
||||
### PR dry-run behavior
|
||||
PRs that touch skill packages run the release workflow in validation mode:
|
||||
- `validate-pr-version-sync` checks changed skill metadata and documentation parity.
|
||||
- `release` builds dry-run release assets for changed release-relevant skill files.
|
||||
- `comment-skillspector-report` posts a sanitized SkillSpector summary back to the PR when reports are available.
|
||||
- `simulate-tag-release-build` exercises the tag-release builder across skills without publishing.
|
||||
|
||||
The PR path exists to catch packaging, signing, and release-evidence regressions before a maintainer pushes a real release tag.
|
||||
|
||||
### SkillSpector release evidence
|
||||
The pipeline installs [NVIDIA SkillSpector](https://github.com/NVIDIA/SkillSpector) inside GitHub Actions and runs:
|
||||
|
||||
```bash
|
||||
skillspector scan <staged-release-payload> --no-llm --format markdown --output skillspector-report.md
|
||||
```
|
||||
|
||||
The scan target is the staged payload, not the raw `skills/<name>/` source directory. That matters because release evidence should describe what users install, while source-only tests and fixtures stay outside the packaged payload.
|
||||
|
||||
SkillSpector output is used in three places:
|
||||
- PR dry-run artifact: `skillspector-pr-reports`
|
||||
- GitHub release asset: `skillspector-report.md`
|
||||
- Signed checksum manifest: `checksums.json` includes the SkillSpector report hash
|
||||
|
||||
PR comments intentionally use a sanitized summary. Raw code blocks, inline snippets, emails, and token-like values are omitted from the comment body, and reviewers can download the workflow artifact when they need the full report.
|
||||
3. Generates `checksums.json` for SBOM files.
|
||||
4. Signs and verifies release checksum artifacts.
|
||||
5. Publishes GitHub Release assets.
|
||||
6. Supersedes older releases within the same major version (tags remain).
|
||||
7. Triggers website catalog refresh.
|
||||
|
||||
### Signing-key consistency guardrails
|
||||
Guardrail script:
|
||||
@@ -67,16 +40,9 @@ Enforced in:
|
||||
|
||||
### Release artifacts
|
||||
Each skill release includes:
|
||||
- `<skill>-v<version>.zip`
|
||||
- `checksums.json`
|
||||
- `checksums.sig`
|
||||
- `signing-public.pem`
|
||||
- `skill.json`
|
||||
- `SKILL.md`
|
||||
- `skill-card.md`
|
||||
- `permissions.json`
|
||||
- `install.md`
|
||||
- `skillspector-report.md`
|
||||
- Additional SBOM-scoped files
|
||||
|
||||
Operational docs:
|
||||
@@ -92,7 +58,6 @@ Operational docs:
|
||||
- `.github/workflows/deploy-pages.yml`: site build + asset mirroring to GitHub Pages.
|
||||
- `.github/workflows/wiki-sync.yml`: syncs repository `wiki/` into GitHub Wiki.
|
||||
- `.github/actions/sign-and-verify/action.yml`: shared Ed25519 sign/verify composite action.
|
||||
- `https://github.com/NVIDIA/SkillSpector`: upstream SkillSpector scanner installed by the release workflow.
|
||||
- `scripts/prepare-to-push.sh`: local CI-like quality gate.
|
||||
- `scripts/release-skill.sh`: manual helper for version bump + tag workflow.
|
||||
|
||||
|
||||
@@ -141,18 +141,11 @@ Current behavior:
|
||||
Current release generator:
|
||||
- `.github/workflows/skill-release.yml`
|
||||
|
||||
Detailed packaging and SkillSpector behavior lives in [Automation and Release Pipelines](modules/automation-release.md). This runbook only records the signing controls operators must verify.
|
||||
|
||||
Signing controls:
|
||||
Current behavior:
|
||||
- creates `checksums.json`, signs it as `checksums.sig`, and verifies signature before publish
|
||||
- includes `signing-public.pem` in release assets
|
||||
- validates generated public-key fingerprint against canonical key material
|
||||
|
||||
Operator review points:
|
||||
- verify `checksums.json` includes the release-evidence files documented in `wiki/modules/automation-release.md`
|
||||
- verify `checksums.sig` validates against `signing-public.pem`
|
||||
- review the release workflow run and PR evidence links before pushing or approving follow-up release tags
|
||||
|
||||
## 8) Rotation policy and runbook
|
||||
|
||||
### Rotation cadence
|
||||
|
||||
+1
-7
@@ -32,16 +32,11 @@
|
||||
|
||||
## Release Workflow Details
|
||||
- Version bump and docs parity are enforced for PR/tag paths.
|
||||
- PR runs validate changed skill packages with a dry-run build before anything is published.
|
||||
- Tag pushes matching `<skill>-v<semver>` build the real release payload, sign `checksums.json`, verify the signature, and publish GitHub Release assets.
|
||||
- Skill packaging includes SBOM-declared files, release trust packet files, install instructions, security scan evidence, and integrity manifests.
|
||||
- Skill packaging includes SBOM-declared files and integrity manifests.
|
||||
- `checksums.json` is signed and immediately verified in workflow execution.
|
||||
- Optional publish-to-ClawHub job runs after successful GitHub release when configured.
|
||||
- Older releases within same major line can be superseded/deleted by automation.
|
||||
|
||||
## SkillSpector Release Evidence
|
||||
Detailed SkillSpector release behavior lives in [Automation and Release Pipelines](modules/automation-release.md). Keep the detailed scanner command, staged-payload rules, PR comment behavior, and release-asset list there so scanner changes have one primary documentation owner.
|
||||
|
||||
## Advisory Workflow Details
|
||||
- NVD workflow determines incremental window from previous feed `updated` timestamp.
|
||||
- Transform phase maps CVE metrics to severity/type and normalizes affected targets.
|
||||
@@ -79,7 +74,6 @@ on:
|
||||
- .github/workflows/poll-nvd-cves.yml
|
||||
- .github/workflows/community-advisory.yml
|
||||
- .github/workflows/skill-release.yml
|
||||
- https://github.com/NVIDIA/SkillSpector
|
||||
- .github/workflows/deploy-pages.yml
|
||||
- .github/workflows/pages-verify.yml
|
||||
- .github/workflows/wiki-sync.yml
|
||||
|
||||
Reference in New Issue
Block a user