@ccoalm/ccl-skills 0.15.0 → 0.15.1
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/assets/marketplace/plugins/ccl-skills/packages/opencode-plugin/ccl-skills.ts +80 -4
- package/dist/assets/marketplace/plugins/ccl-skills/packages/opencode-plugin/commands/ccl-install-skills.md +16 -4
- package/dist/assets/marketplace/plugins/ccl-skills/scripts/owner-dispatch/owner-dispatch.sh +13 -2
- package/dist/assets/marketplace/plugins/ccl-skills/scripts/owner-dispatch/test.sh +53 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/review_gate.py +7 -1
- package/dist/assets/marketplace/plugins/ccl-skills/skills/code-review/scripts/test_review_gate.sh +65 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-observability/SKILL.md +4 -4
- package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-observability/references/alerting-and-on-call.md +8 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-service-connectivity/SKILL.md +14 -14
- package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-service-connectivity/references/dual-sidecar-and-traffic-config-center.md +1 -1
- package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-service-connectivity/references/grpc-authority-workaround.md +40 -83
- package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-service-connectivity/references/mesh-architecture.md +2 -2
- package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-service-connectivity/references/retry-timeout-circuit-breaker.md +44 -37
- package/dist/assets/marketplace/plugins/ccl-skills/skills/platform-service-connectivity/references/service-discovery-recipe.md +1 -1
- package/dist/assets/marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/delivery-lifecycle.md +1 -1
- package/dist/assets/marketplace/plugins/ccl-skills/skills/requirement-scope/SKILL.md +8 -5
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/external-practice-controls.md +3 -3
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/source-register.md +13 -0
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/eval-golden-trace.rb +31 -7
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/impact-chain-gate.rb +74 -3
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/skill-behavior-eval.py +103 -21
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_check_ccl_impact_chain_refscripts.sh +74 -1
- package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_eval_runtime.py +428 -0
- package/dist/assets/release.json +45 -30
- package/dist/claude-adapter.js +14 -7
- package/dist/codex-host.d.ts +1 -3
- package/dist/codex-host.js +6 -9
- package/dist/host-probe.d.ts +11 -0
- package/dist/host-probe.js +27 -0
- package/dist/opencode-adapter.js +24 -19
- package/dist/unified.js +11 -9
- package/package.json +1 -1
package/dist/assets/release.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schema": 1,
|
|
3
3
|
"npmPackage": "@ccoalm/ccl-skills",
|
|
4
|
-
"version": "0.15.
|
|
5
|
-
"sourceCommit": "
|
|
4
|
+
"version": "0.15.1",
|
|
5
|
+
"sourceCommit": "32570b61c4ffb37f6e931ba7f2d16b6617136507",
|
|
6
6
|
"sourceState": "clean",
|
|
7
7
|
"files": [
|
|
8
8
|
{
|
|
@@ -162,12 +162,12 @@
|
|
|
162
162
|
},
|
|
163
163
|
{
|
|
164
164
|
"path": "marketplace/plugins/ccl-skills/packages/opencode-plugin/ccl-skills.ts",
|
|
165
|
-
"sha256": "
|
|
165
|
+
"sha256": "4cc8c560cbbcfe9c7723c9986ea93645ca1926503a0ea80ae93af80f0eabd10e",
|
|
166
166
|
"mode": 420
|
|
167
167
|
},
|
|
168
168
|
{
|
|
169
169
|
"path": "marketplace/plugins/ccl-skills/packages/opencode-plugin/commands/ccl-install-skills.md",
|
|
170
|
-
"sha256": "
|
|
170
|
+
"sha256": "323c5055bf608ac70fffac47d8581a3e31c3f21489fd325983f022511e711a55",
|
|
171
171
|
"mode": 420
|
|
172
172
|
},
|
|
173
173
|
{
|
|
@@ -197,7 +197,7 @@
|
|
|
197
197
|
},
|
|
198
198
|
{
|
|
199
199
|
"path": "marketplace/plugins/ccl-skills/scripts/owner-dispatch/owner-dispatch.sh",
|
|
200
|
-
"sha256": "
|
|
200
|
+
"sha256": "76efb7c5d98b8944aaee11c537aabc82259faddfa6b60bb2bfabdbf7d0602ce2",
|
|
201
201
|
"mode": 493
|
|
202
202
|
},
|
|
203
203
|
{
|
|
@@ -207,7 +207,7 @@
|
|
|
207
207
|
},
|
|
208
208
|
{
|
|
209
209
|
"path": "marketplace/plugins/ccl-skills/scripts/owner-dispatch/test.sh",
|
|
210
|
-
"sha256": "
|
|
210
|
+
"sha256": "df5d23aef020066b427d0424c200eb64863427ea03a90de84ba5c3fbe76d450d",
|
|
211
211
|
"mode": 493
|
|
212
212
|
},
|
|
213
213
|
{
|
|
@@ -372,7 +372,7 @@
|
|
|
372
372
|
},
|
|
373
373
|
{
|
|
374
374
|
"path": "marketplace/plugins/ccl-skills/skills/code-review/scripts/review_gate.py",
|
|
375
|
-
"sha256": "
|
|
375
|
+
"sha256": "31841b7feda1fc2ddf36654cfdc94df0bbee84d590b23cde867aae821e2b1218",
|
|
376
376
|
"mode": 493
|
|
377
377
|
},
|
|
378
378
|
{
|
|
@@ -477,7 +477,7 @@
|
|
|
477
477
|
},
|
|
478
478
|
{
|
|
479
479
|
"path": "marketplace/plugins/ccl-skills/skills/code-review/scripts/test_review_gate.sh",
|
|
480
|
-
"sha256": "
|
|
480
|
+
"sha256": "55366dc96415e175c1b9a23f6fa6e118679bb656ed96c818f4a534ca14826ef0",
|
|
481
481
|
"mode": 493
|
|
482
482
|
},
|
|
483
483
|
{
|
|
@@ -1087,7 +1087,7 @@
|
|
|
1087
1087
|
},
|
|
1088
1088
|
{
|
|
1089
1089
|
"path": "marketplace/plugins/ccl-skills/skills/platform-observability/references/alerting-and-on-call.md",
|
|
1090
|
-
"sha256": "
|
|
1090
|
+
"sha256": "8124c37f30783970ce681ba1aa05cfe507f0054640ed68b19f89da32a35105ce",
|
|
1091
1091
|
"mode": 420
|
|
1092
1092
|
},
|
|
1093
1093
|
{
|
|
@@ -1132,7 +1132,7 @@
|
|
|
1132
1132
|
},
|
|
1133
1133
|
{
|
|
1134
1134
|
"path": "marketplace/plugins/ccl-skills/skills/platform-observability/SKILL.md",
|
|
1135
|
-
"sha256": "
|
|
1135
|
+
"sha256": "3da20332d76fba3b982f5b920794074f7599826f063352fe5c394aaf5e66ad58",
|
|
1136
1136
|
"mode": 420
|
|
1137
1137
|
},
|
|
1138
1138
|
{
|
|
@@ -1217,7 +1217,7 @@
|
|
|
1217
1217
|
},
|
|
1218
1218
|
{
|
|
1219
1219
|
"path": "marketplace/plugins/ccl-skills/skills/platform-service-connectivity/references/dual-sidecar-and-traffic-config-center.md",
|
|
1220
|
-
"sha256": "
|
|
1220
|
+
"sha256": "9f929f6b9bdc03c88f415cf99169d1b7bd508a49a0a80d9f2da2ffc4e079f4a7",
|
|
1221
1221
|
"mode": 420
|
|
1222
1222
|
},
|
|
1223
1223
|
{
|
|
@@ -1227,7 +1227,7 @@
|
|
|
1227
1227
|
},
|
|
1228
1228
|
{
|
|
1229
1229
|
"path": "marketplace/plugins/ccl-skills/skills/platform-service-connectivity/references/grpc-authority-workaround.md",
|
|
1230
|
-
"sha256": "
|
|
1230
|
+
"sha256": "40c7c658a86e08afd47aa7e6cecdf71e2af08ef6c7b5768c5571e17f78b55b32",
|
|
1231
1231
|
"mode": 420
|
|
1232
1232
|
},
|
|
1233
1233
|
{
|
|
@@ -1237,7 +1237,7 @@
|
|
|
1237
1237
|
},
|
|
1238
1238
|
{
|
|
1239
1239
|
"path": "marketplace/plugins/ccl-skills/skills/platform-service-connectivity/references/mesh-architecture.md",
|
|
1240
|
-
"sha256": "
|
|
1240
|
+
"sha256": "41b7e324969a3d21065fa9139ecabfda86439a5b02eeb18bac4300c1de0e6767",
|
|
1241
1241
|
"mode": 420
|
|
1242
1242
|
},
|
|
1243
1243
|
{
|
|
@@ -1252,7 +1252,7 @@
|
|
|
1252
1252
|
},
|
|
1253
1253
|
{
|
|
1254
1254
|
"path": "marketplace/plugins/ccl-skills/skills/platform-service-connectivity/references/retry-timeout-circuit-breaker.md",
|
|
1255
|
-
"sha256": "
|
|
1255
|
+
"sha256": "936383132340fec08539ded8cce57a9d3027af3b90eab6673af562b5c358a412",
|
|
1256
1256
|
"mode": 420
|
|
1257
1257
|
},
|
|
1258
1258
|
{
|
|
@@ -1272,12 +1272,12 @@
|
|
|
1272
1272
|
},
|
|
1273
1273
|
{
|
|
1274
1274
|
"path": "marketplace/plugins/ccl-skills/skills/platform-service-connectivity/references/service-discovery-recipe.md",
|
|
1275
|
-
"sha256": "
|
|
1275
|
+
"sha256": "e0f46825eeb423505e44d2deb7d3c4abecd859bc7b61c304085b02dc2a798533",
|
|
1276
1276
|
"mode": 420
|
|
1277
1277
|
},
|
|
1278
1278
|
{
|
|
1279
1279
|
"path": "marketplace/plugins/ccl-skills/skills/platform-service-connectivity/SKILL.md",
|
|
1280
|
-
"sha256": "
|
|
1280
|
+
"sha256": "558b1d6864527d981d5811fb709acb08405218aced5a1515ae9394ab2fb1a81a",
|
|
1281
1281
|
"mode": 420
|
|
1282
1282
|
},
|
|
1283
1283
|
{
|
|
@@ -1332,7 +1332,7 @@
|
|
|
1332
1332
|
},
|
|
1333
1333
|
{
|
|
1334
1334
|
"path": "marketplace/plugins/ccl-skills/skills/product-rd-workflow/references/delivery-lifecycle.md",
|
|
1335
|
-
"sha256": "
|
|
1335
|
+
"sha256": "3cf969368a7c0343c74ea891fbf78dde8f63295e73c7121a700757df9d0ab1e5",
|
|
1336
1336
|
"mode": 420
|
|
1337
1337
|
},
|
|
1338
1338
|
{
|
|
@@ -1977,7 +1977,7 @@
|
|
|
1977
1977
|
},
|
|
1978
1978
|
{
|
|
1979
1979
|
"path": "marketplace/plugins/ccl-skills/skills/requirement-scope/SKILL.md",
|
|
1980
|
-
"sha256": "
|
|
1980
|
+
"sha256": "31f46a35743b8da351f5a517a3d15a0cbe92ca4f0b778d21aec6d0b5574a9546",
|
|
1981
1981
|
"mode": 420
|
|
1982
1982
|
},
|
|
1983
1983
|
{
|
|
@@ -2042,7 +2042,7 @@
|
|
|
2042
2042
|
},
|
|
2043
2043
|
{
|
|
2044
2044
|
"path": "marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/external-practice-controls.md",
|
|
2045
|
-
"sha256": "
|
|
2045
|
+
"sha256": "98c8ef6d9250f96feb9e996e108ca473475c9b690c7a0efc57ed5a30e2665d2c",
|
|
2046
2046
|
"mode": 420
|
|
2047
2047
|
},
|
|
2048
2048
|
{
|
|
@@ -2127,7 +2127,7 @@
|
|
|
2127
2127
|
},
|
|
2128
2128
|
{
|
|
2129
2129
|
"path": "marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/source-register.md",
|
|
2130
|
-
"sha256": "
|
|
2130
|
+
"sha256": "006325a862d0bac253bfdd61c940c29fa20b1ddcf1ddebae4726a7a866a45f5a",
|
|
2131
2131
|
"mode": 420
|
|
2132
2132
|
},
|
|
2133
2133
|
{
|
|
@@ -2207,7 +2207,7 @@
|
|
|
2207
2207
|
},
|
|
2208
2208
|
{
|
|
2209
2209
|
"path": "marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/eval-golden-trace.rb",
|
|
2210
|
-
"sha256": "
|
|
2210
|
+
"sha256": "70d0b824c79f701606f752e815fbe7b643324b6f56d601e4e55b3ceae578ad62",
|
|
2211
2211
|
"mode": 493
|
|
2212
2212
|
},
|
|
2213
2213
|
{
|
|
@@ -2247,7 +2247,7 @@
|
|
|
2247
2247
|
},
|
|
2248
2248
|
{
|
|
2249
2249
|
"path": "marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/impact-chain-gate.rb",
|
|
2250
|
-
"sha256": "
|
|
2250
|
+
"sha256": "c2a4816b7c7043a7868c0ced2b7a4046b5aba088dda622ffec49360306f59ce1",
|
|
2251
2251
|
"mode": 493
|
|
2252
2252
|
},
|
|
2253
2253
|
{
|
|
@@ -2277,7 +2277,7 @@
|
|
|
2277
2277
|
},
|
|
2278
2278
|
{
|
|
2279
2279
|
"path": "marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/skill-behavior-eval.py",
|
|
2280
|
-
"sha256": "
|
|
2280
|
+
"sha256": "d65c8a76ae6d4ceacbe16885abc3e0c51d6fd152d491437db7e1e8fc9988ad08",
|
|
2281
2281
|
"mode": 493
|
|
2282
2282
|
},
|
|
2283
2283
|
{
|
|
@@ -2307,7 +2307,7 @@
|
|
|
2307
2307
|
},
|
|
2308
2308
|
{
|
|
2309
2309
|
"path": "marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_check_ccl_impact_chain_refscripts.sh",
|
|
2310
|
-
"sha256": "
|
|
2310
|
+
"sha256": "dbc090be57b6f14795e6b7dcd79abe83bb1efa3d2f090040c4b7225b4e10d2fa",
|
|
2311
2311
|
"mode": 493
|
|
2312
2312
|
},
|
|
2313
2313
|
{
|
|
@@ -2405,6 +2405,11 @@
|
|
|
2405
2405
|
"sha256": "8ddd704eac6f4ffdc5d5b6566f9a2b3d5e940b944af448586dfec0e920a54ee5",
|
|
2406
2406
|
"mode": 493
|
|
2407
2407
|
},
|
|
2408
|
+
{
|
|
2409
|
+
"path": "marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_eval_runtime.py",
|
|
2410
|
+
"sha256": "b40fb184ba6e98d767f3d9c8e9c7d20a834bba79e644b1626c6071aa777d3f60",
|
|
2411
|
+
"mode": 420
|
|
2412
|
+
},
|
|
2408
2413
|
{
|
|
2409
2414
|
"path": "marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_extraction_review_gate.sh",
|
|
2410
2415
|
"sha256": "b3284aef648eb0b6bde2cd6084b4ac9b7d060e3fb244dace59fe491bab0e05e2",
|
|
@@ -3264,7 +3269,7 @@
|
|
|
3264
3269
|
},
|
|
3265
3270
|
{
|
|
3266
3271
|
"path": "claude-adapter.js",
|
|
3267
|
-
"sha256": "
|
|
3272
|
+
"sha256": "75386ab4c98d7e4056fa22683168da1867536bdc2de4d02c8b6fbef68e908713",
|
|
3268
3273
|
"mode": 420
|
|
3269
3274
|
},
|
|
3270
3275
|
{
|
|
@@ -3289,12 +3294,12 @@
|
|
|
3289
3294
|
},
|
|
3290
3295
|
{
|
|
3291
3296
|
"path": "codex-host.d.ts",
|
|
3292
|
-
"sha256": "
|
|
3297
|
+
"sha256": "1f1987b0820ff80c915e2a66f5324fa3790465d23b9d1fca55be178ed1c0dbdd",
|
|
3293
3298
|
"mode": 420
|
|
3294
3299
|
},
|
|
3295
3300
|
{
|
|
3296
3301
|
"path": "codex-host.js",
|
|
3297
|
-
"sha256": "
|
|
3302
|
+
"sha256": "09649bcb081b97b947a1b83441d0ac8fd2868461e5f295f241d731932d3ba04a",
|
|
3298
3303
|
"mode": 420
|
|
3299
3304
|
},
|
|
3300
3305
|
{
|
|
@@ -3307,6 +3312,16 @@
|
|
|
3307
3312
|
"sha256": "4e2cf0e4742d91d8f9b2024d7df3fc93690fa3a71ab35a4762bed59705e87044",
|
|
3308
3313
|
"mode": 420
|
|
3309
3314
|
},
|
|
3315
|
+
{
|
|
3316
|
+
"path": "host-probe.d.ts",
|
|
3317
|
+
"sha256": "49974a5794f49a27b1bbacdb476f4d6049aad756e17a0f9856172053ed746173",
|
|
3318
|
+
"mode": 420
|
|
3319
|
+
},
|
|
3320
|
+
{
|
|
3321
|
+
"path": "host-probe.js",
|
|
3322
|
+
"sha256": "db73d028fa5fc9f70887c09539bcce10ff21b0cef76101445c8820028153e2d5",
|
|
3323
|
+
"mode": 420
|
|
3324
|
+
},
|
|
3310
3325
|
{
|
|
3311
3326
|
"path": "index.d.ts",
|
|
3312
3327
|
"sha256": "37bf7ef65f13c512112942fa78257e84d42535993669cd97fbea2374dd20e174",
|
|
@@ -3334,7 +3349,7 @@
|
|
|
3334
3349
|
},
|
|
3335
3350
|
{
|
|
3336
3351
|
"path": "opencode-adapter.js",
|
|
3337
|
-
"sha256": "
|
|
3352
|
+
"sha256": "637d3df5182ad6a51ed310736be65471fd0b432c078483af163d340ac04d6460",
|
|
3338
3353
|
"mode": 420
|
|
3339
3354
|
},
|
|
3340
3355
|
{
|
|
@@ -3374,7 +3389,7 @@
|
|
|
3374
3389
|
},
|
|
3375
3390
|
{
|
|
3376
3391
|
"path": "unified.js",
|
|
3377
|
-
"sha256": "
|
|
3392
|
+
"sha256": "e5f2870f5ba9689b3cc903c9403b8ade85b7df5364e2037fe7a3eed04aeedc4a",
|
|
3378
3393
|
"mode": 420
|
|
3379
3394
|
},
|
|
3380
3395
|
{
|
|
@@ -3408,5 +3423,5 @@
|
|
|
3408
3423
|
"mode": 420
|
|
3409
3424
|
}
|
|
3410
3425
|
],
|
|
3411
|
-
"snapshotHash": "
|
|
3426
|
+
"snapshotHash": "8fd7e270f237790aff425a4e1ece90ddd91919b4a94191b3bfb17e2e75780e04"
|
|
3412
3427
|
}
|
package/dist/claude-adapter.js
CHANGED
|
@@ -5,6 +5,7 @@ import { fileURLToPath } from "node:url";
|
|
|
5
5
|
import { atomicJson, canonicalAlias, copyRegularTree, verifyTree } from "./fs-safe.js";
|
|
6
6
|
import { manifestFor, readManifest, readRelease } from "./manifest.js";
|
|
7
7
|
import { compare } from "./version.js";
|
|
8
|
+
import { probeHostVersion } from "./host-probe.js";
|
|
8
9
|
const MARKET = "ccl-skills-npm", REF = `ccl-skills@${MARKET}`;
|
|
9
10
|
function paths(context) {
|
|
10
11
|
const rawHome = context.home ?? (context.env ? context.env.HOME : process.env.HOME);
|
|
@@ -46,9 +47,9 @@ function command(args, context, allowFailure = false) {
|
|
|
46
47
|
return result;
|
|
47
48
|
}
|
|
48
49
|
function state(context) {
|
|
49
|
-
const version =
|
|
50
|
-
if (version.
|
|
51
|
-
return { host: false,
|
|
50
|
+
const version = probeHostVersion("claude", context.env || process.env);
|
|
51
|
+
if (!version.ok)
|
|
52
|
+
return { host: false, hostFailure: { code: 4, status: `host-${version.kind}`, message: version.message } };
|
|
52
53
|
const marketsRaw = command(["plugin", "marketplace", "list", "--json"], context), pluginsRaw = command(["plugin", "list", "--json"], context);
|
|
53
54
|
let markets, plugins;
|
|
54
55
|
try {
|
|
@@ -100,6 +101,8 @@ function prepare(context, old) {
|
|
|
100
101
|
}
|
|
101
102
|
function removeRegistration(context) {
|
|
102
103
|
const current = state(context);
|
|
104
|
+
if (!current.host)
|
|
105
|
+
throw new Error(current.hostFailure.message);
|
|
103
106
|
if (current.plugin)
|
|
104
107
|
command(["plugin", "uninstall", REF, "--scope", "user"], context);
|
|
105
108
|
if (current.marketplace)
|
|
@@ -109,6 +112,8 @@ function installRegistration(marketplace, context) {
|
|
|
109
112
|
command(["plugin", "marketplace", "add", marketplace, "--scope", "user"], context);
|
|
110
113
|
command(["plugin", "install", REF, "--scope", "user"], context);
|
|
111
114
|
const current = state(context);
|
|
115
|
+
if (!current.host)
|
|
116
|
+
throw new Error(current.hostFailure.message);
|
|
112
117
|
if (!current.plugin || !samePath(current.marketplace || "", marketplace))
|
|
113
118
|
throw new Error("Claude did not expose the exact npm marketplace candidate");
|
|
114
119
|
}
|
|
@@ -117,7 +122,7 @@ function doctor(context) {
|
|
|
117
122
|
assertExclusiveRoot(p.claudeHome, p.root);
|
|
118
123
|
const current = state(context);
|
|
119
124
|
if (!current.host)
|
|
120
|
-
return
|
|
125
|
+
return current.hostFailure;
|
|
121
126
|
if (current.legacy)
|
|
122
127
|
return { code: 3, status: "double-install", message: "Git marketplace and npm marketplace are both present; keep exactly one" };
|
|
123
128
|
const manifest = readManifest(p.manifest);
|
|
@@ -138,7 +143,7 @@ function installOrUpdate(commandName, options, context) {
|
|
|
138
143
|
assertExclusiveRoot(p.claudeHome, p.root, true);
|
|
139
144
|
const current = state(context);
|
|
140
145
|
if (!current.host)
|
|
141
|
-
return
|
|
146
|
+
return current.hostFailure;
|
|
142
147
|
if (current.legacy)
|
|
143
148
|
return { code: 3, status: "double-install", message: "Remove the Git marketplace install or choose it instead of npm" };
|
|
144
149
|
const old = readManifest(p.manifest), release = readRelease(p.release);
|
|
@@ -199,18 +204,20 @@ function uninstall(options, context) {
|
|
|
199
204
|
const p = paths(context);
|
|
200
205
|
assertExclusiveRoot(p.claudeHome, p.root);
|
|
201
206
|
const manifest = readManifest(p.manifest), current = state(context);
|
|
207
|
+
if (!current.host)
|
|
208
|
+
return { ...current.hostFailure, message: `${current.hostFailure.message}; refusing to drop ownership evidence while registration cannot be verified` };
|
|
202
209
|
if (!manifest && !current.plugin && !current.marketplace)
|
|
203
210
|
return { code: 0, status: "absent", message: "Claude npm install is already absent" };
|
|
204
211
|
if (!manifest)
|
|
205
212
|
return { code: 3, status: "unowned-registration", message: "refusing to remove an unowned Claude registration" };
|
|
206
|
-
if (!current.host)
|
|
207
|
-
return { code: 4, status: "host-missing", message: "Claude CLI is not installed; refusing to drop ownership evidence while registration cannot be verified" };
|
|
208
213
|
if (!options.yes)
|
|
209
214
|
return { code: 0, status: "dry-run", message: "Claude uninstall preview", plan: ["remove npm plugin", "remove npm marketplace", "delete exclusive owned snapshots"] };
|
|
210
215
|
if (context.isInterrupted?.())
|
|
211
216
|
return { code: 130, status: "interrupted", message: "Claude uninstall interrupted before registration mutation", interrupted: true };
|
|
212
217
|
removeRegistration(context);
|
|
213
218
|
const after = state(context);
|
|
219
|
+
if (!after.host)
|
|
220
|
+
return { code: 5, status: "partial", message: `${after.hostFailure.message}; uninstall state is unverified, retaining ownership evidence` };
|
|
214
221
|
if (after.plugin || after.marketplace)
|
|
215
222
|
return { code: 5, status: "partial", message: "Claude registration remains after uninstall" };
|
|
216
223
|
try {
|
package/dist/codex-host.d.ts
CHANGED
|
@@ -11,12 +11,10 @@ export declare function checkHost(codexHome?: string): {
|
|
|
11
11
|
ok: false;
|
|
12
12
|
kind: string;
|
|
13
13
|
message: string;
|
|
14
|
-
|
|
14
|
+
output?: undefined;
|
|
15
15
|
} | {
|
|
16
16
|
ok: true;
|
|
17
17
|
version: string;
|
|
18
|
-
kind?: undefined;
|
|
19
|
-
message?: undefined;
|
|
20
18
|
};
|
|
21
19
|
export declare function parsePluginList(text: string, marketplaceSource: string | null): {
|
|
22
20
|
ok: boolean;
|
package/dist/codex-host.js
CHANGED
|
@@ -4,6 +4,7 @@ import { isAbsolute, join, resolve } from "node:path";
|
|
|
4
4
|
import { LEGACY_REF, MARKET, REF } from "./paths.js";
|
|
5
5
|
import { canonicalAlias } from "./fs-safe.js";
|
|
6
6
|
import { compare, parseVersion } from "./version.js";
|
|
7
|
+
import { probeHostVersion } from "./host-probe.js";
|
|
7
8
|
function call(args, codexHome) {
|
|
8
9
|
const env = {
|
|
9
10
|
...process.env,
|
|
@@ -16,14 +17,10 @@ function call(args, codexHome) {
|
|
|
16
17
|
});
|
|
17
18
|
}
|
|
18
19
|
export function checkHost(codexHome) {
|
|
19
|
-
const p =
|
|
20
|
-
if (p.
|
|
21
|
-
return
|
|
22
|
-
|
|
23
|
-
kind: "missing",
|
|
24
|
-
message: "Codex CLI is missing",
|
|
25
|
-
};
|
|
26
|
-
const version = parseVersion(`${p.stdout}\n${p.stderr}`);
|
|
20
|
+
const p = probeHostVersion("codex", { ...process.env, ...(codexHome ? { CODEX_HOME: codexHome } : {}) });
|
|
21
|
+
if (!p.ok)
|
|
22
|
+
return p;
|
|
23
|
+
const version = parseVersion(p.output);
|
|
27
24
|
if (!version || compare(version, "0.133.0") < 0)
|
|
28
25
|
return {
|
|
29
26
|
ok: false,
|
|
@@ -37,7 +34,7 @@ export function parsePluginList(text, marketplaceSource) {
|
|
|
37
34
|
if (lines.length === 0 ||
|
|
38
35
|
(lines.length === 1 && lines[0] === "No marketplace plugins found."))
|
|
39
36
|
return { ok: true, plugin: false, legacy: false };
|
|
40
|
-
const header = /^PLUGIN\s+STATUS\s+VERSION\s+PATH\s*$/;
|
|
37
|
+
const header = /^PLUGIN\s+STATUS\s+VERSION\s+(?:PATH|SOURCE)\s*$/;
|
|
41
38
|
const provenance = /^Marketplace `([^`]+)`$/;
|
|
42
39
|
const sensitiveRefs = new Set();
|
|
43
40
|
let plugin = false;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { spawnSync } from "node:child_process";
|
|
2
|
+
// Version discovery must not hold up other hosts or wait for interactive input.
|
|
3
|
+
const HOST_PROBE_TIMEOUT_MS = 10000;
|
|
4
|
+
export function probeHostVersion(command, env = process.env) {
|
|
5
|
+
const result = spawnSync(command, ["--version"], {
|
|
6
|
+
encoding: "utf8",
|
|
7
|
+
env,
|
|
8
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
9
|
+
timeout: HOST_PROBE_TIMEOUT_MS,
|
|
10
|
+
// spawnSync still waits if a child catches SIGTERM and does not exit.
|
|
11
|
+
killSignal: "SIGKILL",
|
|
12
|
+
});
|
|
13
|
+
if (result.error || result.status !== 0) {
|
|
14
|
+
const errorCode = result.error?.code;
|
|
15
|
+
const kind = errorCode === "ETIMEDOUT" ? "timeout" : errorCode === "ENOENT" ? "missing" : "probe-failed";
|
|
16
|
+
return {
|
|
17
|
+
ok: false,
|
|
18
|
+
kind,
|
|
19
|
+
message: kind === "timeout"
|
|
20
|
+
? `${command} --version timed out after ${HOST_PROBE_TIMEOUT_MS}ms`
|
|
21
|
+
: kind === "missing"
|
|
22
|
+
? `${command} CLI is unavailable (ENOENT)`
|
|
23
|
+
: `${command} --version failed (${errorCode || (result.signal ? `signal ${result.signal}` : result.error ? "spawn error" : `exit ${result.status}`)})`,
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
return { ok: true, output: `${result.stdout}\n${result.stderr}` };
|
|
27
|
+
}
|
package/dist/opencode-adapter.js
CHANGED
|
@@ -6,6 +6,7 @@ import { fileURLToPath } from "node:url";
|
|
|
6
6
|
import { atomicJson, sha256 } from "./fs-safe.js";
|
|
7
7
|
import { readRelease } from "./manifest.js";
|
|
8
8
|
import { compare } from "./version.js";
|
|
9
|
+
import { probeHostVersion } from "./host-probe.js";
|
|
9
10
|
const PACKAGE = "@ccoalm/ccl-skills";
|
|
10
11
|
function paths(context) {
|
|
11
12
|
const rawHome = context.home ?? (context.env ? context.env.HOME : process.env.HOME);
|
|
@@ -21,7 +22,7 @@ function assertExclusiveRoot(base, root, createBase = false) {
|
|
|
21
22
|
throw new Error("managed root is not canonical");
|
|
22
23
|
if (createBase)
|
|
23
24
|
mkdirSync(base, { recursive: true });
|
|
24
|
-
for (const component of [base, root]) {
|
|
25
|
+
for (const component of [base, root, join(root, "snapshots")]) {
|
|
25
26
|
if (!existsSync(component))
|
|
26
27
|
continue;
|
|
27
28
|
const stat = lstatSync(component);
|
|
@@ -124,10 +125,6 @@ function readManifest(path, root) {
|
|
|
124
125
|
}).sort((a, b) => a.destination.localeCompare(b.destination));
|
|
125
126
|
return { schema: 1, npmPackage: PACKAGE, installedAt: raw.installedAt, version: raw.version, sourceCommit: raw.sourceCommit, sourceKind: raw.sourceKind, snapshot, snapshotHash: raw.snapshotHash, entries };
|
|
126
127
|
}
|
|
127
|
-
function hostAvailable(context) {
|
|
128
|
-
const result = spawnSync("opencode", ["--version"], { encoding: "utf8", env: context.env || process.env });
|
|
129
|
-
return !result.error && result.status === 0;
|
|
130
|
-
}
|
|
131
128
|
function sharedPath(base, rel) {
|
|
132
129
|
const path = resolve(base, safeRel(rel, "OpenCode destination"));
|
|
133
130
|
if (!path.startsWith(`${resolve(base)}${sep}`))
|
|
@@ -190,17 +187,19 @@ function actualFiles(directory) {
|
|
|
190
187
|
function preflight(base, next, old) {
|
|
191
188
|
assertSafeSharedParents(base, next);
|
|
192
189
|
const previous = new Map((old?.entries || []).map((entry) => [entry.destination, entry]));
|
|
190
|
+
const drift = [];
|
|
193
191
|
if (old) {
|
|
192
|
+
assertSafeSharedParents(base, old.entries);
|
|
194
193
|
for (const entry of old.entries) {
|
|
195
194
|
const path = sharedPath(base, entry.destination);
|
|
196
195
|
if (!existsSync(path) || (regular(path).mode & 0o777) !== entry.mode || sha256(path) !== entry.sha256)
|
|
197
|
-
|
|
196
|
+
drift.push(entry.destination);
|
|
198
197
|
}
|
|
199
198
|
const skillNames = new Set(old.entries.filter((entry) => entry.destination.startsWith("skills/")).map((entry) => entry.destination.split("/")[1]));
|
|
200
199
|
for (const skill of skillNames) {
|
|
201
200
|
const expected = old.entries.filter((entry) => entry.destination.startsWith(`skills/${skill}/`)).map((entry) => entry.destination.slice(`skills/${skill}/`.length)).sort();
|
|
202
201
|
if (JSON.stringify(actualFiles(join(base, "skills", skill))) !== JSON.stringify(expected))
|
|
203
|
-
|
|
202
|
+
drift.push(`skills/${skill}`);
|
|
204
203
|
}
|
|
205
204
|
}
|
|
206
205
|
const nextSkills = new Set(next.filter((entry) => entry.destination.startsWith("skills/")).map((entry) => entry.destination.split("/")[1]));
|
|
@@ -211,6 +210,7 @@ function preflight(base, next, old) {
|
|
|
211
210
|
for (const entry of next)
|
|
212
211
|
if (!previous.has(entry.destination) && existsSync(sharedPath(base, entry.destination)))
|
|
213
212
|
throw new Error(`OpenCode path collision: ${entry.destination}`);
|
|
213
|
+
return drift;
|
|
214
214
|
}
|
|
215
215
|
function prepareSnapshot(p, candidate) {
|
|
216
216
|
const snapshotRel = join("snapshots", candidate.snapshotHash, "source"), snapshot = join(p.root, snapshotRel);
|
|
@@ -305,8 +305,9 @@ function writeShared(p, snapshot, entries, old, isInterrupted, copyShared = (fro
|
|
|
305
305
|
function doctor(context) {
|
|
306
306
|
const p = paths(context);
|
|
307
307
|
assertExclusiveRoot(p.base, p.root);
|
|
308
|
-
|
|
309
|
-
|
|
308
|
+
const host = probeHostVersion("opencode", context.env || process.env);
|
|
309
|
+
if (!host.ok)
|
|
310
|
+
return { code: 4, status: `host-${host.kind}`, message: host.message };
|
|
310
311
|
const legacy = existsSync(join(p.base, "ccl-skills/install-manifest.json")), manifest = readManifest(p.manifest, p.root);
|
|
311
312
|
if (legacy && manifest)
|
|
312
313
|
return { code: 3, status: "double-install", message: "legacy checkout and npm OpenCode installs are both present; keep exactly one" };
|
|
@@ -315,20 +316,22 @@ function doctor(context) {
|
|
|
315
316
|
return { code: 3, status: legacy ? "legacy-install" : "unowned-registration", message: "OpenCode ccl-skills files exist without an npm ownership receipt" };
|
|
316
317
|
return { code: 3, status: "absent", message: "ccl-skills is not installed for OpenCode" };
|
|
317
318
|
}
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
319
|
+
let drift = [], reason;
|
|
320
|
+
try {
|
|
321
|
+
drift = preflight(p.base, manifest.entries, manifest);
|
|
322
|
+
}
|
|
323
|
+
catch (error) {
|
|
324
|
+
reason = String(error);
|
|
323
325
|
}
|
|
324
|
-
if (drift.length)
|
|
325
|
-
return { code: 3, status: "shared-drift", message: "OpenCode shared files changed after npm install; they will never be auto-deleted", details: { drift } };
|
|
326
|
+
if (drift.length || reason)
|
|
327
|
+
return { code: 3, status: "shared-drift", message: "OpenCode shared files changed after npm install; they will never be auto-deleted", details: { drift, ...(reason ? { reason } : {}) } };
|
|
326
328
|
return { code: 0, status: "healthy", message: `OpenCode uses @ccoalm/ccl-skills ${manifest.version}` };
|
|
327
329
|
}
|
|
328
330
|
function installOrUpdate(commandName, options, context) {
|
|
329
331
|
const p = paths(context);
|
|
330
|
-
|
|
331
|
-
|
|
332
|
+
const host = probeHostVersion("opencode", context.env || process.env);
|
|
333
|
+
if (!host.ok)
|
|
334
|
+
return { code: 4, status: `host-${host.kind}`, message: host.message };
|
|
332
335
|
let candidate;
|
|
333
336
|
try {
|
|
334
337
|
candidate = source(context);
|
|
@@ -350,7 +353,9 @@ function installOrUpdate(commandName, options, context) {
|
|
|
350
353
|
return { code: 3, status: "downgrade-refused", message: "newer OpenCode assets are installed" };
|
|
351
354
|
}
|
|
352
355
|
try {
|
|
353
|
-
preflight(p.base, candidate.entries, old);
|
|
356
|
+
const drift = preflight(p.base, candidate.entries, old);
|
|
357
|
+
if (drift.length)
|
|
358
|
+
throw new Error(`owned OpenCode paths drifted: ${drift.join(", ")}`);
|
|
354
359
|
}
|
|
355
360
|
catch (error) {
|
|
356
361
|
return { code: 3, status: "collision", message: String(error) };
|
package/dist/unified.js
CHANGED
|
@@ -1,14 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { probeHostVersion } from "./host-probe.js";
|
|
2
2
|
import { existsSync } from "node:fs";
|
|
3
3
|
import { join, resolve } from "node:path";
|
|
4
4
|
import { runClaude } from "./claude-adapter.js";
|
|
5
5
|
import { run as runCodex } from "./operations.js";
|
|
6
6
|
import { runOpenCode } from "./opencode-adapter.js";
|
|
7
|
-
function available(host) {
|
|
8
|
-
const command = host === "opencode" ? "opencode" : host;
|
|
9
|
-
const result = spawnSync(command, ["--version"], { encoding: "utf8" });
|
|
10
|
-
return !result.error && result.status === 0;
|
|
11
|
-
}
|
|
12
7
|
function owned(host) {
|
|
13
8
|
const home = process.env.HOME;
|
|
14
9
|
if (!home)
|
|
@@ -57,8 +52,15 @@ export function runUnified(command, options = {}, codexContext = {}) {
|
|
|
57
52
|
if (options.host)
|
|
58
53
|
return dispatch(options.host, command, options, codexContext);
|
|
59
54
|
const includeOwned = command === "doctor" || command === "uninstall";
|
|
60
|
-
const
|
|
55
|
+
const candidates = ["claude", "codex", "opencode"].filter((host) => command !== "update" || owned(host));
|
|
56
|
+
const probes = candidates.map((host) => ({ host, probe: probeHostVersion(host) }));
|
|
57
|
+
const hosts = probes.filter(({ host, probe }) => probe.ok || probe.kind !== "missing" || (includeOwned && owned(host))).map(({ host }) => host);
|
|
61
58
|
if (!hosts.length)
|
|
62
|
-
return { code: 4, status: "host-missing", message: "
|
|
63
|
-
return runHostSequence(hosts, (host) =>
|
|
59
|
+
return { code: 4, status: "host-missing", message: "no Claude Code, Codex, or OpenCode CLI is available" };
|
|
60
|
+
return runHostSequence(hosts, (host) => {
|
|
61
|
+
const probe = probes.find((entry) => entry.host === host).probe;
|
|
62
|
+
if (!probe.ok && probe.kind !== "missing")
|
|
63
|
+
return { code: 4, status: `host-${probe.kind}`, message: probe.message };
|
|
64
|
+
return dispatch(host, command, { ...options, host }, codexContext);
|
|
65
|
+
});
|
|
64
66
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ccoalm/ccl-skills",
|
|
3
|
-
"version": "0.15.
|
|
3
|
+
"version": "0.15.1",
|
|
4
4
|
"description": "Reusable workflows that help coding agents plan, build, test, review, and release software — for Claude Code, Codex, and OpenCode",
|
|
5
5
|
"keywords": ["skills", "agent-skills", "claude", "claude-code", "codex", "opencode", "agent", "ai", "ai-agents", "cli", "anthropic", "developer-tools"],
|
|
6
6
|
"type": "module",
|