skillscokac 1.4.0 → 1.4.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/bin/skillscokac.js +132 -1
  2. package/package.json +1 -1
@@ -1180,6 +1180,137 @@ async function findSkillByName(skillName, apiKey) {
1180
1180
  }
1181
1181
  }
1182
1182
 
1183
+ /**
1184
+ * Update skill using individual API calls (alternative to batch)
1185
+ */
1186
+ async function updateSkillIndividually(postId, skillMdContent, skillDir, apiKey, silent = false) {
1187
+ // Collect all files to upload
1188
+ const files = []
1189
+
1190
+ function findFiles(dir, baseDir) {
1191
+ const entries = fs.readdirSync(dir, { withFileTypes: true })
1192
+
1193
+ for (const entry of entries) {
1194
+ const fullPath = path.join(dir, entry.name)
1195
+
1196
+ if (entry.isDirectory()) {
1197
+ if (entry.name.startsWith('.') || entry.name === '__pycache__' || entry.name === 'node_modules') {
1198
+ continue
1199
+ }
1200
+ findFiles(fullPath, baseDir)
1201
+ } else if (entry.isFile()) {
1202
+ const relativePath = path.relative(baseDir, fullPath)
1203
+ if (relativePath === 'SKILL.md') {
1204
+ continue
1205
+ }
1206
+ if (entry.name.startsWith('.')) {
1207
+ continue
1208
+ }
1209
+
1210
+ // Check file size
1211
+ const stats = fs.statSync(fullPath)
1212
+ if (stats.size > MAX_FILE_SIZE) {
1213
+ if (!silent) {
1214
+ console.warn(chalk.yellow(`⚠ Skipping large file (${Math.round(stats.size / 1024 / 1024)}MB): ${relativePath}`))
1215
+ }
1216
+ continue
1217
+ }
1218
+
1219
+ // Try to read as text
1220
+ let content
1221
+ try {
1222
+ content = fs.readFileSync(fullPath, 'utf8')
1223
+ } catch (err) {
1224
+ // Skip binary files
1225
+ continue
1226
+ }
1227
+
1228
+ files.push({
1229
+ path: relativePath.replace(/\\/g, '/'),
1230
+ content: content
1231
+ })
1232
+ }
1233
+ }
1234
+ }
1235
+
1236
+ findFiles(skillDir, skillDir)
1237
+
1238
+ // Step 1: Update SKILL.md content
1239
+ await axios.patch(
1240
+ `${API_BASE_URL}/api/posts/${postId}`,
1241
+ { skillMd: skillMdContent },
1242
+ {
1243
+ headers: {
1244
+ 'Authorization': `Bearer ${apiKey}`,
1245
+ 'Content-Type': 'application/json',
1246
+ 'User-Agent': `skillscokac-cli/${VERSION}`
1247
+ },
1248
+ timeout: AXIOS_TIMEOUT
1249
+ }
1250
+ )
1251
+
1252
+ // Step 2: Get existing files
1253
+ const existingSkill = await axios.get(`${API_BASE_URL}/api/posts/${postId}`, {
1254
+ headers: {
1255
+ 'Authorization': `Bearer ${apiKey}`,
1256
+ 'User-Agent': `skillscokac-cli/${VERSION}`
1257
+ },
1258
+ timeout: AXIOS_TIMEOUT
1259
+ })
1260
+
1261
+ const existingFiles = existingSkill.data.skillFiles || []
1262
+
1263
+ // Step 3: Delete existing files
1264
+ for (const file of existingFiles) {
1265
+ try {
1266
+ await axios.delete(
1267
+ `${API_BASE_URL}/api/posts/${postId}/files/${file.id}`,
1268
+ {
1269
+ headers: {
1270
+ 'Authorization': `Bearer ${apiKey}`,
1271
+ 'User-Agent': `skillscokac-cli/${VERSION}`
1272
+ },
1273
+ timeout: AXIOS_TIMEOUT
1274
+ }
1275
+ )
1276
+ } catch (err) {
1277
+ // Continue even if delete fails
1278
+ if (!silent) {
1279
+ console.warn(chalk.yellow(`⚠ Failed to delete file: ${file.path}`))
1280
+ }
1281
+ }
1282
+ }
1283
+
1284
+ // Step 4: Create new files
1285
+ let uploadedCount = 0
1286
+ for (const file of files) {
1287
+ try {
1288
+ await axios.post(
1289
+ `${API_BASE_URL}/api/posts/${postId}/files`,
1290
+ file,
1291
+ {
1292
+ headers: {
1293
+ 'Authorization': `Bearer ${apiKey}`,
1294
+ 'Content-Type': 'application/json',
1295
+ 'User-Agent': `skillscokac-cli/${VERSION}`
1296
+ },
1297
+ timeout: AXIOS_TIMEOUT
1298
+ }
1299
+ )
1300
+ uploadedCount++
1301
+ } catch (err) {
1302
+ if (!silent) {
1303
+ console.warn(chalk.yellow(`⚠ Failed to upload file: ${file.path}`))
1304
+ }
1305
+ }
1306
+ }
1307
+
1308
+ return {
1309
+ uploadedCount: uploadedCount,
1310
+ deletedCount: existingFiles.length
1311
+ }
1312
+ }
1313
+
1183
1314
  /**
1184
1315
  * Update skill using batch API
1185
1316
  */
@@ -1334,7 +1465,7 @@ async function uploadModifySkillCommand(skillDir, apiKey) {
1334
1465
  console.log(chalk.yellow(`Skill "${skillName}" already exists. Updating...`))
1335
1466
 
1336
1467
  spinner.text = 'Updating skill and files...'
1337
- const { uploadedCount, deletedCount } = await updateSkillWithBatch(
1468
+ const { uploadedCount, deletedCount } = await updateSkillIndividually(
1338
1469
  existingSkill.id,
1339
1470
  skillMdContent,
1340
1471
  resolvedSkillDir,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "skillscokac",
3
- "version": "1.4.0",
3
+ "version": "1.4.3",
4
4
  "description": "CLI tool to install and manage Claude Code skills from skills.cokac.com",
5
5
  "main": "bin/skillscokac.js",
6
6
  "bin": {