@1aboveio/skills 0.20.4 → 0.21.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.
Files changed (35) hide show
  1. package/README.md +10 -4
  2. package/package.json +1 -1
  3. package/runtime/skills/distribution/generated/recipes.json +136 -24
  4. package/runtime/skills/distribution/scripts/bundles.mjs +56 -27
  5. package/runtime/skills/engineering/engineering-runtime/scripts/workflow-policy.mjs +1 -1
  6. package/skills/compliance/doc-authenticity/SKILL.md +2 -1
  7. package/skills/compliance/doc-authenticity/agents/openai.yaml +8 -0
  8. package/skills/content-creator/article-review/LICENSE +3 -0
  9. package/skills/content-creator/article-review/SKILL.md +65 -0
  10. package/skills/content-creator/article-review/references/report-format.md +68 -0
  11. package/skills/content-creator/article-review/references/template-guide.md +79 -0
  12. package/skills/content-creator/article-review/references/template-wechat-payments.md +125 -0
  13. package/skills/content-creator/article-to-image/LICENSE +3 -0
  14. package/skills/content-creator/article-to-image/SKILL.md +90 -0
  15. package/skills/content-creator/article-to-image/references/formats.md +53 -0
  16. package/skills/content-creator/wechat-article-writer/LICENSE +3 -0
  17. package/skills/content-creator/wechat-article-writer/SKILL.md +50 -0
  18. package/skills/content-creator/wechat-article-writer/references/style-comparison.md +64 -0
  19. package/skills/content-creator/wechat-article-writer/references/style-howto.md +64 -0
  20. package/skills/content-creator/wechat-article-writer/references/style-insight.md +63 -0
  21. package/skills/content-creator/wechat-article-writer/references/style-pitfall.md +60 -0
  22. package/skills/content-creator/wechat-article-writer/references/style-selector.md +133 -0
  23. package/skills/content-creator/wechat-article-writer/references/writing-rules.md +150 -0
  24. package/skills/content-creator/wechat-publisher/LICENSE +3 -0
  25. package/skills/content-creator/wechat-publisher/SKILL.md +170 -0
  26. package/skills/content-creator/wechat-publisher/references/api.md +105 -0
  27. package/skills/content-creator/wechat-publisher/references/layout-rules.md +57 -0
  28. package/skills/content-creator/wechat-publisher/references/wechat-safe-template.html +86 -0
  29. package/skills/content-creator/wechat-publisher/scripts/md_to_wechat_html.py +194 -0
  30. package/skills/content-creator/wechat-publisher/scripts/publish.py +239 -0
  31. package/skills/content-creator/wechat-search/LICENSE +3 -0
  32. package/skills/content-creator/wechat-search/SKILL.md +210 -0
  33. package/skills/content-creator/wechat-search/scripts/start-chrome.sh +83 -0
  34. package/skills/engineering/engineering-runtime/coherence/workflow.json +13 -13
  35. package/skills/engineering/engineering-runtime/scripts/workflow-policy.mjs +1 -1
package/README.md CHANGED
@@ -73,6 +73,7 @@ planned same-named skill. The coordinator still owns group and new-member consen
73
73
  - `payment` — Payment: fraud-analysis, payment-analysis, tld-detection, similar-domain
74
74
  - `document-utilities` — Document Utilities: doc-to-md, reg-parser (required: reg-parser -> doc-to-md)
75
75
  - `compliance` — Compliance: compliance-audit, doc-authenticity, report-writing (required: compliance-audit -> doc-to-md; optional: compliance-audit -> reg-parser)
76
+ - `content-creator` — Content Creator: article-review, article-to-image, wechat-article-writer, wechat-publisher, wechat-search
76
77
  - `fullstack` — Fullstack: better-auth, monorepo, nextjs-fullstack, prisma-setup, shadcn, zod-v4
77
78
 
78
79
  Internal dependencies, installed with the groups above and not selectable on their own: `harness-runtime`.
@@ -100,10 +101,13 @@ non-interactively.
100
101
  Declined skills are never uninstalled by the coordinator and stay out of the remembered acceptance,
101
102
  so the next update asks again.
102
103
 
103
- When a release archives a previously accepted skill, `update` asks before removing that installed
104
- copy. The default is No; `--yes` accepts archival non-interactively. Removal is performed by the
105
- same pinned native Skills CLI, only after the declared replacement is installed or already current.
106
- Declined or failed archival remains in selection memory so a later update offers it again.
104
+ Every `install` and `update` scans the managed global root for exact manifest-declared retired
105
+ skills. A selected former group may first make the replacement current; outside the selection, a
106
+ leftover is eligible only when its replacement was already installed and matches this release.
107
+ For each eligible leftover, the coordinator will archive it by default through the pinned
108
+ native Skills CLI. An interactive prompt defaults to Yes; non-interactive runs archive without
109
+ `--yes`. Missing or modified unselected
110
+ replacements stay untouched. Declined or failed archival remains available for a later run.
107
111
 
108
112
  Install and update are best-effort per member over bulk source commands: they continue after a
109
113
  member failure except for skills whose required dependency is unavailable, summarize
@@ -139,6 +143,8 @@ npx skills@1.5.22 remove --global --agent universal claude-code --skill fraud-an
139
143
  npx skills@1.5.22 remove --global --agent universal claude-code --skill doc-to-md reg-parser
140
144
  # Compliance
141
145
  npx skills@1.5.22 remove --global --agent universal claude-code --skill compliance-audit doc-authenticity report-writing
146
+ # Content Creator
147
+ npx skills@1.5.22 remove --global --agent universal claude-code --skill article-review article-to-image wechat-article-writer wechat-publisher wechat-search
142
148
  # Fullstack
143
149
  npx skills@1.5.22 remove --global --agent universal claude-code --skill better-auth monorepo nextjs-fullstack prisma-setup shadcn zod-v4
144
150
  ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@1aboveio/skills",
3
- "version": "0.20.4",
3
+ "version": "0.21.1",
4
4
  "description": "Install the 1AboveIO first-party skill groups through the native Skills CLI.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -24,7 +24,7 @@
24
24
  "id": "first-party",
25
25
  "type": "first-party",
26
26
  "package": "@1aboveio/skills",
27
- "version": "0.20.4",
27
+ "version": "0.21.1",
28
28
  "updatePolicy": "pinned-npm-version",
29
29
  "members": [
30
30
  {
@@ -204,6 +204,36 @@
204
204
  "role": "skill",
205
205
  "licenseResponsibility": "1aboveio-mit"
206
206
  },
207
+ {
208
+ "installName": "article-review",
209
+ "path": "skills/content-creator/article-review",
210
+ "role": "skill",
211
+ "licenseResponsibility": "1aboveio-mit"
212
+ },
213
+ {
214
+ "installName": "article-to-image",
215
+ "path": "skills/content-creator/article-to-image",
216
+ "role": "skill",
217
+ "licenseResponsibility": "1aboveio-mit"
218
+ },
219
+ {
220
+ "installName": "wechat-article-writer",
221
+ "path": "skills/content-creator/wechat-article-writer",
222
+ "role": "skill",
223
+ "licenseResponsibility": "1aboveio-mit"
224
+ },
225
+ {
226
+ "installName": "wechat-publisher",
227
+ "path": "skills/content-creator/wechat-publisher",
228
+ "role": "skill",
229
+ "licenseResponsibility": "1aboveio-mit"
230
+ },
231
+ {
232
+ "installName": "wechat-search",
233
+ "path": "skills/content-creator/wechat-search",
234
+ "role": "skill",
235
+ "licenseResponsibility": "1aboveio-mit"
236
+ },
207
237
  {
208
238
  "installName": "better-auth",
209
239
  "path": "skills/fullstack/better-auth",
@@ -263,7 +293,7 @@
263
293
  "sourceId": "first-party",
264
294
  "sourceType": "first-party",
265
295
  "package": "@1aboveio/skills",
266
- "version": "0.20.4",
296
+ "version": "0.21.1",
267
297
  "installPath": null,
268
298
  "members": [
269
299
  "harness-runtime",
@@ -297,7 +327,7 @@
297
327
  "sourceId": "first-party",
298
328
  "sourceType": "first-party",
299
329
  "package": "@1aboveio/skills",
300
- "version": "0.20.4",
330
+ "version": "0.21.1",
301
331
  "installPath": null,
302
332
  "members": [
303
333
  "harness-runtime",
@@ -341,7 +371,7 @@
341
371
  "sourceId": "first-party",
342
372
  "sourceType": "first-party",
343
373
  "package": "@1aboveio/skills",
344
- "version": "0.20.4",
374
+ "version": "0.21.1",
345
375
  "installPath": null,
346
376
  "members": [
347
377
  "harness-runtime",
@@ -374,7 +404,7 @@
374
404
  "sourceId": "first-party",
375
405
  "sourceType": "first-party",
376
406
  "package": "@1aboveio/skills",
377
- "version": "0.20.4",
407
+ "version": "0.21.1",
378
408
  "installPath": null,
379
409
  "members": [
380
410
  "harness-runtime",
@@ -417,7 +447,7 @@
417
447
  "sourceId": "first-party",
418
448
  "sourceType": "first-party",
419
449
  "package": "@1aboveio/skills",
420
- "version": "0.20.4",
450
+ "version": "0.21.1",
421
451
  "installPath": null,
422
452
  "members": [
423
453
  "harness-runtime",
@@ -445,7 +475,7 @@
445
475
  "sourceId": "first-party",
446
476
  "sourceType": "first-party",
447
477
  "package": "@1aboveio/skills",
448
- "version": "0.20.4",
478
+ "version": "0.21.1",
449
479
  "installPath": null,
450
480
  "members": [
451
481
  "harness-runtime",
@@ -483,7 +513,7 @@
483
513
  "sourceId": "first-party",
484
514
  "sourceType": "first-party",
485
515
  "package": "@1aboveio/skills",
486
- "version": "0.20.4",
516
+ "version": "0.21.1",
487
517
  "installPath": null,
488
518
  "members": [
489
519
  "harness-runtime",
@@ -511,7 +541,7 @@
511
541
  "sourceId": "first-party",
512
542
  "sourceType": "first-party",
513
543
  "package": "@1aboveio/skills",
514
- "version": "0.20.4",
544
+ "version": "0.21.1",
515
545
  "installPath": null,
516
546
  "members": [
517
547
  "harness-runtime",
@@ -549,7 +579,7 @@
549
579
  "sourceId": "first-party",
550
580
  "sourceType": "first-party",
551
581
  "package": "@1aboveio/skills",
552
- "version": "0.20.4",
582
+ "version": "0.21.1",
553
583
  "installPath": null,
554
584
  "members": [
555
585
  "harness-runtime",
@@ -579,7 +609,7 @@
579
609
  "sourceId": "first-party",
580
610
  "sourceType": "first-party",
581
611
  "package": "@1aboveio/skills",
582
- "version": "0.20.4",
612
+ "version": "0.21.1",
583
613
  "installPath": null,
584
614
  "members": [
585
615
  "harness-runtime",
@@ -619,7 +649,7 @@
619
649
  "sourceId": "first-party",
620
650
  "sourceType": "first-party",
621
651
  "package": "@1aboveio/skills",
622
- "version": "0.20.4",
652
+ "version": "0.21.1",
623
653
  "installPath": null,
624
654
  "members": [
625
655
  "harness-runtime",
@@ -647,7 +677,7 @@
647
677
  "sourceId": "first-party",
648
678
  "sourceType": "first-party",
649
679
  "package": "@1aboveio/skills",
650
- "version": "0.20.4",
680
+ "version": "0.21.1",
651
681
  "installPath": null,
652
682
  "members": [
653
683
  "harness-runtime",
@@ -685,7 +715,7 @@
685
715
  "sourceId": "first-party",
686
716
  "sourceType": "first-party",
687
717
  "package": "@1aboveio/skills",
688
- "version": "0.20.4",
718
+ "version": "0.21.1",
689
719
  "installPath": null,
690
720
  "members": [
691
721
  "harness-runtime",
@@ -715,7 +745,7 @@
715
745
  "sourceId": "first-party",
716
746
  "sourceType": "first-party",
717
747
  "package": "@1aboveio/skills",
718
- "version": "0.20.4",
748
+ "version": "0.21.1",
719
749
  "installPath": null,
720
750
  "members": [
721
751
  "harness-runtime",
@@ -742,6 +772,78 @@
742
772
  "removesDependencies": false
743
773
  }
744
774
  },
775
+ {
776
+ "id": "content-creator",
777
+ "displayName": "Content Creator",
778
+ "dependsOn": [
779
+ "harness-runtime"
780
+ ],
781
+ "install": {
782
+ "stopOnFailure": true,
783
+ "steps": [
784
+ {
785
+ "sourceId": "first-party",
786
+ "sourceType": "first-party",
787
+ "package": "@1aboveio/skills",
788
+ "version": "0.21.1",
789
+ "installPath": null,
790
+ "members": [
791
+ "harness-runtime",
792
+ "article-review",
793
+ "article-to-image",
794
+ "wechat-article-writer",
795
+ "wechat-publisher",
796
+ "wechat-search"
797
+ ],
798
+ "commands": [
799
+ {
800
+ "transport": "local",
801
+ "command": "npx skills@1.5.22 add . --global --agent universal claude-code --skill harness-runtime article-review article-to-image wechat-article-writer wechat-publisher wechat-search"
802
+ }
803
+ ],
804
+ "onFailure": {
805
+ "action": "stop",
806
+ "message": "Source first-party fetch failed; stop this recipe before running another source."
807
+ }
808
+ }
809
+ ]
810
+ },
811
+ "update": {
812
+ "mode": "rerun-install-recipe",
813
+ "stopOnFailure": true,
814
+ "steps": [
815
+ {
816
+ "sourceId": "first-party",
817
+ "sourceType": "first-party",
818
+ "package": "@1aboveio/skills",
819
+ "version": "0.21.1",
820
+ "installPath": null,
821
+ "members": [
822
+ "harness-runtime",
823
+ "article-review",
824
+ "article-to-image",
825
+ "wechat-article-writer",
826
+ "wechat-publisher",
827
+ "wechat-search"
828
+ ],
829
+ "commands": [
830
+ {
831
+ "transport": "local",
832
+ "command": "npx skills@1.5.22 add . --global --agent universal claude-code --skill harness-runtime article-review article-to-image wechat-article-writer wechat-publisher wechat-search"
833
+ }
834
+ ],
835
+ "onFailure": {
836
+ "action": "stop",
837
+ "message": "Source first-party fetch failed; stop this recipe before running another source."
838
+ }
839
+ }
840
+ ]
841
+ },
842
+ "uninstall": {
843
+ "command": "npx skills@1.5.22 remove --global --agent universal claude-code --skill article-review article-to-image wechat-article-writer wechat-publisher wechat-search",
844
+ "removesDependencies": false
845
+ }
846
+ },
745
847
  {
746
848
  "id": "fullstack",
747
849
  "displayName": "Fullstack",
@@ -755,7 +857,7 @@
755
857
  "sourceId": "first-party",
756
858
  "sourceType": "first-party",
757
859
  "package": "@1aboveio/skills",
758
- "version": "0.20.4",
860
+ "version": "0.21.1",
759
861
  "installPath": null,
760
862
  "members": [
761
863
  "harness-runtime",
@@ -787,7 +889,7 @@
787
889
  "sourceId": "first-party",
788
890
  "sourceType": "first-party",
789
891
  "package": "@1aboveio/skills",
790
- "version": "0.20.4",
892
+ "version": "0.21.1",
791
893
  "installPath": null,
792
894
  "members": [
793
895
  "harness-runtime",
@@ -827,7 +929,7 @@
827
929
  "sourceId": "first-party",
828
930
  "sourceType": "first-party",
829
931
  "package": "@1aboveio/skills",
830
- "version": "0.20.4",
932
+ "version": "0.21.1",
831
933
  "installPath": null,
832
934
  "members": [
833
935
  "harness-runtime"
@@ -853,7 +955,7 @@
853
955
  "sourceId": "first-party",
854
956
  "sourceType": "first-party",
855
957
  "package": "@1aboveio/skills",
856
- "version": "0.20.4",
958
+ "version": "0.21.1",
857
959
  "installPath": null,
858
960
  "members": [
859
961
  "harness-runtime"
@@ -885,7 +987,7 @@
885
987
  "sourceId": "first-party",
886
988
  "sourceType": "first-party",
887
989
  "package": "@1aboveio/skills",
888
- "version": "0.20.4",
990
+ "version": "0.21.1",
889
991
  "installPath": null,
890
992
  "members": [
891
993
  "harness-runtime",
@@ -917,6 +1019,11 @@
917
1019
  "compliance-audit",
918
1020
  "doc-authenticity",
919
1021
  "report-writing",
1022
+ "article-review",
1023
+ "article-to-image",
1024
+ "wechat-article-writer",
1025
+ "wechat-publisher",
1026
+ "wechat-search",
920
1027
  "better-auth",
921
1028
  "monorepo",
922
1029
  "nextjs-fullstack",
@@ -927,7 +1034,7 @@
927
1034
  "commands": [
928
1035
  {
929
1036
  "transport": "local",
930
- "command": "npx skills@1.5.22 add . --global --agent universal claude-code --skill harness-runtime e2e-test ensure-coverage implement-and-pr rush-issues rush-release review-pr smoke engineering-runtime cloud-build cloud-debug cloud-deploy docker google-cloud mergify podman app-debug python-backend airflow pyspark fraud-analysis payment-analysis tld-detection similar-domain doc-to-md reg-parser compliance-audit doc-authenticity report-writing better-auth monorepo nextjs-fullstack prisma-setup shadcn zod-v4 && npm --prefix \"$(realpath \"$HOME/.agents/skills/engineering-runtime/scripts\")\" ci --ignore-scripts"
1037
+ "command": "npx skills@1.5.22 add . --global --agent universal claude-code --skill harness-runtime e2e-test ensure-coverage implement-and-pr rush-issues rush-release review-pr smoke engineering-runtime cloud-build cloud-debug cloud-deploy docker google-cloud mergify podman app-debug python-backend airflow pyspark fraud-analysis payment-analysis tld-detection similar-domain doc-to-md reg-parser compliance-audit doc-authenticity report-writing article-review article-to-image wechat-article-writer wechat-publisher wechat-search better-auth monorepo nextjs-fullstack prisma-setup shadcn zod-v4 && npm --prefix \"$(realpath \"$HOME/.agents/skills/engineering-runtime/scripts\")\" ci --ignore-scripts"
931
1038
  }
932
1039
  ],
933
1040
  "onFailure": {
@@ -945,7 +1052,7 @@
945
1052
  "sourceId": "first-party",
946
1053
  "sourceType": "first-party",
947
1054
  "package": "@1aboveio/skills",
948
- "version": "0.20.4",
1055
+ "version": "0.21.1",
949
1056
  "installPath": null,
950
1057
  "members": [
951
1058
  "harness-runtime",
@@ -977,6 +1084,11 @@
977
1084
  "compliance-audit",
978
1085
  "doc-authenticity",
979
1086
  "report-writing",
1087
+ "article-review",
1088
+ "article-to-image",
1089
+ "wechat-article-writer",
1090
+ "wechat-publisher",
1091
+ "wechat-search",
980
1092
  "better-auth",
981
1093
  "monorepo",
982
1094
  "nextjs-fullstack",
@@ -987,7 +1099,7 @@
987
1099
  "commands": [
988
1100
  {
989
1101
  "transport": "local",
990
- "command": "npx skills@1.5.22 add . --global --agent universal claude-code --skill harness-runtime e2e-test ensure-coverage implement-and-pr rush-issues rush-release review-pr smoke engineering-runtime cloud-build cloud-debug cloud-deploy docker google-cloud mergify podman app-debug python-backend airflow pyspark fraud-analysis payment-analysis tld-detection similar-domain doc-to-md reg-parser compliance-audit doc-authenticity report-writing better-auth monorepo nextjs-fullstack prisma-setup shadcn zod-v4 && npm --prefix \"$(realpath \"$HOME/.agents/skills/engineering-runtime/scripts\")\" ci --ignore-scripts"
1102
+ "command": "npx skills@1.5.22 add . --global --agent universal claude-code --skill harness-runtime e2e-test ensure-coverage implement-and-pr rush-issues rush-release review-pr smoke engineering-runtime cloud-build cloud-debug cloud-deploy docker google-cloud mergify podman app-debug python-backend airflow pyspark fraud-analysis payment-analysis tld-detection similar-domain doc-to-md reg-parser compliance-audit doc-authenticity report-writing article-review article-to-image wechat-article-writer wechat-publisher wechat-search better-auth monorepo nextjs-fullstack prisma-setup shadcn zod-v4 && npm --prefix \"$(realpath \"$HOME/.agents/skills/engineering-runtime/scripts\")\" ci --ignore-scripts"
991
1103
  }
992
1104
  ],
993
1105
  "onFailure": {
@@ -998,7 +1110,7 @@
998
1110
  ]
999
1111
  },
1000
1112
  "uninstall": {
1001
- "command": "npx skills@1.5.22 remove --global --agent universal claude-code --skill e2e-test ensure-coverage implement-and-pr rush-issues rush-release review-pr smoke engineering-runtime cloud-build cloud-debug cloud-deploy docker google-cloud mergify podman app-debug python-backend airflow pyspark fraud-analysis payment-analysis tld-detection similar-domain doc-to-md reg-parser compliance-audit doc-authenticity report-writing better-auth monorepo nextjs-fullstack prisma-setup shadcn zod-v4 harness-runtime"
1113
+ "command": "npx skills@1.5.22 remove --global --agent universal claude-code --skill e2e-test ensure-coverage implement-and-pr rush-issues rush-release review-pr smoke engineering-runtime cloud-build cloud-debug cloud-deploy docker google-cloud mergify podman app-debug python-backend airflow pyspark fraud-analysis payment-analysis tld-detection similar-domain doc-to-md reg-parser compliance-audit doc-authenticity report-writing article-review article-to-image wechat-article-writer wechat-publisher wechat-search better-auth monorepo nextjs-fullstack prisma-setup shadcn zod-v4 harness-runtime"
1002
1114
  }
1003
1115
  }
1004
1116
  }
@@ -204,18 +204,45 @@ export function newMemberCandidates(action, groupIds, priorState, transport = {}
204
204
  return candidates;
205
205
  }
206
206
 
207
- // Archived members are offered only to users who previously accepted them in the same group.
208
- // This keeps retirement explicit and prevents a release from treating filesystem presence as
209
- // consent. A successful removal drops the old acceptance; a decline or failure preserves it so a
210
- // later update offers the archive again.
207
+ // A selected former group may retire its accepted or installed leftovers because this run can make
208
+ // the replacement ready. An unrelated group may retire an installed leftover only when the
209
+ // replacement already matches this release: global cleanup must never install an unselected group
210
+ // or turn a missing/modified replacement into an unrelated run failure.
211
211
  export function archivedMemberCandidates(action, groupIds, priorState, transport = {}) {
212
- if (action !== 'update' || !priorState) return [];
213
- const recipes = readRecipes(resolveBundleTransport(transport).recipesPath);
212
+ if (!ACTIONS.has(action)) return [];
213
+ const { recipesPath, localRoot } = resolveBundleTransport(transport);
214
+ const recipes = readRecipes(recipesPath);
214
215
  const selected = new Set(groupIds);
215
- const acceptedByGroup = new Map(priorState.groups
216
+ const acceptedByGroup = new Map((priorState?.groups ?? [])
216
217
  .map((group) => [group.id, new Set(group.acceptedMembers)]));
217
- return (recipes.archives ?? []).filter((archive) => selected.has(archive.formerGroupId)
218
- && acceptedByGroup.get(archive.formerGroupId)?.has(archive.installName));
218
+ const leftover = (name) => Boolean(
219
+ transport.skillsRoot
220
+ && statSync(join(transport.skillsRoot, name), { throwIfNoEntry: false }),
221
+ );
222
+ const membersByName = new Map((recipes.sources ?? []).flatMap((source) => (
223
+ (source.members ?? []).map((member) => [member.installName, { source, member }])
224
+ )));
225
+ return (recipes.archives ?? []).flatMap((archive) => {
226
+ if (selected.has(archive.formerGroupId)) {
227
+ return (acceptedByGroup.get(archive.formerGroupId)?.has(archive.installName)
228
+ || leftover(archive.installName)) ? [archive] : [];
229
+ }
230
+ if (!leftover(archive.installName)) return [];
231
+ const replacement = membersByName.get(archive.replacement);
232
+ if (!replacement) return [];
233
+ try {
234
+ if (classifyInstalledMember(replacement.source, replacement.member, {
235
+ enableTdd: transport.enableTdd,
236
+ localRoot,
237
+ skillsRoot: transport.skillsRoot,
238
+ }).status !== 'unchanged') return [];
239
+ } catch {
240
+ // A scoped transport may declare an archive without carrying an unselected replacement's
241
+ // source bytes. Without an expected digest this cleanup is ineligible, never presence-based.
242
+ return [];
243
+ }
244
+ return [{ ...archive, replacementAlreadyCurrent: true }];
245
+ });
219
246
  }
220
247
 
221
248
  // Prior acceptance for the new-member consent delta on explicit selections (picker, --group,
@@ -686,8 +713,9 @@ install without --group/--all opens the interactive picker; update without them
686
713
  remembered selection (\${XDG_STATE_HOME:-~/.local/state}/1aboveio-skills/selection.json).
687
714
  When a remembered group's current recipe declares members you have not accepted yet, each new skill
688
715
  is offered individually and defaults to No; --yes accepts them all, --dry-run lists them without
689
- prompting. Retired accepted skills are likewise kept by default; --yes archives them through the
690
- native Skills CLI after their replacement is current. TDD implicit model invocation is enabled by default; --disable-tdd makes TDD explicit-only,
716
+ prompting. Every run archives exact retired leftovers from the managed global root by default when
717
+ their replacement is current; it never installs an unselected replacement. Decline interactively to
718
+ keep them. TDD implicit model invocation is enabled by default; --disable-tdd makes TDD explicit-only,
691
719
  and --enable-tdd restores implicit invocation. --manual-tdd remains a compatibility alias for
692
720
  --disable-tdd.
693
721
  `;
@@ -862,29 +890,24 @@ async function consentNewMembers(candidates, { yes, stdin, stdout, stderr }) {
862
890
  return declined;
863
891
  }
864
892
 
865
- async function consentArchivedMembers(candidates, { yes, stdin, stdout, stderr }) {
893
+ async function consentArchivedMembers(candidates, { yes, stdin, stdout }) {
866
894
  const declined = new Set();
867
- if (yes) {
868
- for (const candidate of candidates) stdout.write(`Accepting archive of retired skill "${candidate.installName}" (--yes)\n`);
869
- return declined;
870
- }
871
- if (!stdin.isTTY) {
895
+ if (yes || !stdin.isTTY) {
896
+ const how = yes ? '--yes' : 'default Yes';
872
897
  for (const candidate of candidates) {
873
- stderr.write(`Keeping retired skill "${candidate.installName}": no interactive terminal (default No; re-run with --yes to archive)\n`);
874
- declined.add(candidate.installName);
898
+ stdout.write(`Archiving retired skill "${candidate.installName}" (${how}; replaced by ${candidate.replacement})\n`);
875
899
  }
876
900
  return declined;
877
901
  }
878
902
  const prompter = createLinePrompter({ stdin, stdout });
879
903
  for (const candidate of candidates) {
880
904
  const answer = await prompter.ask(
881
- `Archive retired skill "${candidate.installName}" (replaced by ${candidate.replacement})? [y/N] `,
905
+ `Archive retired skill "${candidate.installName}" (replaced by ${candidate.replacement})? [Y/n] `,
882
906
  );
883
- if (/^y(es)?$/i.test(answer)) stdout.write(`Archiving ${candidate.installName}\n`);
884
- else {
907
+ if (/^n(o)?$/i.test(answer)) {
885
908
  stdout.write(`Keeping ${candidate.installName}\n`);
886
909
  declined.add(candidate.installName);
887
- }
910
+ } else stdout.write(`Archiving ${candidate.installName}\n`);
888
911
  }
889
912
  return declined;
890
913
  }
@@ -993,18 +1016,22 @@ export async function runCli(args, {
993
1016
  } else if (candidates.length > 0) {
994
1017
  declined = await consentNewMembers(candidates, { yes: parsed.yes, stdin, stdout, stderr });
995
1018
  }
996
- const archiveCandidates = archivedMemberCandidates(parsed.action, groupIds, priorState, transport);
1019
+ const skillsRoot = join(env.HOME || homedir(), '.agents', 'skills');
1020
+ const archiveCandidates = archivedMemberCandidates(parsed.action, groupIds, priorState, {
1021
+ ...transport,
1022
+ enableTdd,
1023
+ skillsRoot,
1024
+ });
997
1025
  let declinedArchives = new Set();
998
1026
  if (archiveCandidates.length > 0 && parsed.dryRun) {
999
1027
  for (const candidate of archiveCandidates) {
1000
- stdout.write(`Retired skill "${candidate.installName}" (replaced by ${candidate.replacement}) — would prompt to archive (default: No); --yes accepts archival\n`);
1028
+ stdout.write(`Retired skill "${candidate.installName}" (replaced by ${candidate.replacement}) — would archive by default; decline interactively to keep\n`);
1001
1029
  }
1002
1030
  } else if (archiveCandidates.length > 0) {
1003
1031
  declinedArchives = await consentArchivedMembers(archiveCandidates, {
1004
1032
  yes: parsed.yes,
1005
1033
  stdin,
1006
1034
  stdout,
1007
- stderr,
1008
1035
  });
1009
1036
  }
1010
1037
  // Digest skip (#1127): `update` classifies the accepted members against the installed tree and
@@ -1013,7 +1040,6 @@ export async function runCli(args, {
1013
1040
  // from classification: they never run, so they are not buckets.
1014
1041
  let buckets;
1015
1042
  let skipMembers;
1016
- const skillsRoot = join(env.HOME || homedir(), '.agents', 'skills');
1017
1043
  if (parsed.action === 'update') {
1018
1044
  buckets = classifySelectedMembers(parsed.action, groupIds, { ...transport, enableTdd, skillsRoot });
1019
1045
  skipMembers = new Set(buckets.unchanged.map((entry) => entry.member));
@@ -1069,6 +1095,9 @@ export async function runCli(args, {
1069
1095
  const readyMembers = new Set([
1070
1096
  ...succeeded.map((planned) => planned.member),
1071
1097
  ...(buckets?.unchanged.map((entry) => entry.member) ?? []),
1098
+ ...archiveCandidates
1099
+ .filter((candidate) => candidate.replacementAlreadyCurrent)
1100
+ .map((candidate) => candidate.replacement),
1072
1101
  ]);
1073
1102
  failed.push(...enforceReadyDependencies(
1074
1103
  readyMembers,
@@ -86,7 +86,7 @@ export const WORKFLOW_TRUSTED_SOURCES = deepFreeze({
86
86
  id: 'first-party',
87
87
  type: 'first-party',
88
88
  package: '@1aboveio/skills',
89
- version: '0.20.4',
89
+ version: '0.21.1',
90
90
  },
91
91
  matt: {
92
92
  id: 'matt-pocock',
@@ -1,7 +1,8 @@
1
1
  ---
2
2
  name: doc-authenticity
3
- version: 0.4.0
3
+ version: 0.4.1
4
4
  description: "Screen PDF documents and raster images for fabrication, tampering, Photoshop or other image-editor use, and content validity. Detects file type, runs format-specific authenticity forensics, classifies bank statements, conversation logs, invoices, agreements, and other documents, then applies type-specific validity checks. Produces separate authenticity (NO_EVIDENCE_OF_MODIFICATION / SUSPICIOUS / LIKELY_MODIFIED / INCONCLUSIVE) and validity (VALID / INVALID / INCONCLUSIVE) verdicts. Use whenever a user asks whether a document, screenshot, scan, statement, invoice, contract, chat log, receipt, or payment evidence is genuine, original, edited, Photoshopped, manipulated, fake, or valid."
5
+ disable-model-invocation: true
5
6
  ---
6
7
 
7
8
  # Document and Image Authenticity
@@ -0,0 +1,8 @@
1
+ interface:
2
+ display_name: "Document Authenticity"
3
+ short_description: "Explicit-only document and image authenticity screening"
4
+
5
+ policy:
6
+ # Codex counterpart to SKILL.md disable-model-invocation: true.
7
+ # Keeps explicit invocation while blocking description-based selection.
8
+ allow_implicit_invocation: false
@@ -0,0 +1,3 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 1AboveIO
@@ -0,0 +1,65 @@
1
+ ---
2
+ name: article-review
3
+ description: >
4
+ Evaluate and score articles across multiple dimensions including originality,
5
+ readability, shareability, timeliness, and factual accuracy.
6
+ Use when a user shares an article, pastes article text, sends a URL, or asks to
7
+ review, rate, critique, evaluate, 评价, 点评, 分析, or 看看 any article, post, or 文章.
8
+ Default template is 公众号-支付行业.
9
+ ---
10
+
11
+ # 文章评审引擎
12
+
13
+ 模板化的文章评审系统。评审标准由模板文件定义,引擎负责执行评审流程并输出标准化报告。
14
+
15
+ **开始任何评审前,先读取 `references/report-format.md`**,熟悉输出结构。
16
+
17
+ ## 可用模板
18
+
19
+ - **公众号-支付行业** (`references/template-wechat-payments.md`) — 面向支付/金融科技从业者的公众号内容(默认)
20
+
21
+ 如需其他模板,或用户请求的模板不存在,读取 `references/template-guide.md` 创建新模板,再继续评审。
22
+
23
+ ## 输入处理
24
+
25
+ **粘贴文字:** 直接进入评审流程。
26
+
27
+ **URL:** 用 `web_fetch` 抓取文章正文。若被拦截(如微信需要登录),提示用户粘贴文章内容后继续。
28
+
29
+ ## 评审流程
30
+
31
+ ### 第一步:确认模板
32
+ 在每次评审开始时,读取对应模板文件(默认 `references/template-wechat-payments.md`),获取维度列表和 Level 2 细则。用户未指定模板时使用默认。
33
+
34
+ ### 第二步:通读文章
35
+ 通读全文,理解核心主张、论据、结构、受众定位。
36
+
37
+ ### 第三步:事实核查(Fact-Check Pass)
38
+ 在逐维度评分之前,先做事实核查:
39
+
40
+ 1. 提取文章中所有可验证的主张:
41
+ - 数字、统计、比例、排名
42
+ - 引用他人言论或研究结论
43
+ - 行业事实陈述(市场规模、政策、技术参数等)
44
+
45
+ 2. 对每条主张用 `web_search` 核查,标注结果:
46
+ - ✅ **已核实** — 找到一致的可信来源
47
+ - ❌ **有误** — 找到与之矛盾的可信来源,记录正确值
48
+ - ⚠️ **无法核实** — 无法找到来源或来源相互矛盾,标注存疑
49
+
50
+ 3. 将核查结果用于事实准确性维度的评分依据
51
+
52
+ ### 第四步:逐维度评分
53
+ 按模板定义的每个 Level 1 维度:
54
+ - 给出 1-10 分
55
+ - 引用文章原文 2-3 处作为依据
56
+ - 给出 1-2 条具体可执行的改进建议(如有)
57
+
58
+ 事实准确性维度的评分必须基于第三步的核查结果,而非主观判断。
59
+
60
+ ### 第五步:输出报告
61
+ 按 `references/report-format.md` 中的模板输出完整报告。
62
+
63
+ ## 注意事项
64
+
65
+ 严格按流程执行:评分必须有原文引用,不接受笼统判断;事实准确性必须基于 web_search 核查;改进建议要具体可执行;发布建议根据综合分和事实核查结果综合判断。