Compare commits

...

3 Commits

71 changed files with 188 additions and 93 deletions

View File

@@ -20,14 +20,17 @@ python3 script/package_skills.py
```
Main outputs:
- `package/per-skill/<skill-name>.skill`
- `package/per-skill/<skill-name>.zip`
- `package/per-skill/skill/<skill-name>.skill`
- `package/per-skill/zip/<skill-name>.zip`
- `package/bundles/mechanical-skills-collection.zip`
- `package/PACKAGES_INDEX.md`
- [`package/PACKAGES_INDEX.md`](package/PACKAGES_INDEX.md)
### Package folder definitions
- `package/per-skill/`
- Contains one package per skill in both formats (`.skill` and `.zip`).
- Root folder for per-skill artifacts.
- Split by format for cleaner browsing:
- `package/per-skill/skill/` for `.skill`
- `package/per-skill/zip/` for `.zip`
- Use this folder when you want to import a single skill into Claude.
- File naming is based on the `name` field in each `SKILL.md` frontmatter.
@@ -55,15 +58,15 @@ python3 script/package_skills.py
```
5. Check results:
- Per-skill package files in `package/per-skill/`
- Validation report in `package/PACKAGES_INDEX.md`
- Per-skill package files in `package/per-skill/skill/` and `package/per-skill/zip/`
- Validation report in [`package/PACKAGES_INDEX.md`](package/PACKAGES_INDEX.md)
6. Import into Claude:
- Upload `package/per-skill/my-new-skill.skill` (or `.zip`).
- Upload `package/per-skill/skill/my-new-skill.skill` (or `.zip` from `package/per-skill/zip/`).
Notes:
- If a skill is missing `SKILL.md`, it is skipped.
- If `name` or `description` is missing in frontmatter, it is skipped.
- If two skills use the same `name`, the script auto-adds a suffix and logs a warning in `PACKAGES_INDEX.md`.
- If two skills use the same `name`, the script auto-adds a suffix and logs a warning in [`PACKAGES_INDEX.md`](package/PACKAGES_INDEX.md).
## Detailed Skill Authoring Guide (Claude-Style)
This section mirrors the depth of the official Claude Skills guidance and adapts it to this repository.
@@ -248,10 +251,10 @@ python3 script/package_skills.py
```
Generated artifacts:
- `package/per-skill/<skill-name>.skill`
- `package/per-skill/<skill-name>.zip`
- `package/per-skill/skill/<skill-name>.skill`
- `package/per-skill/zip/<skill-name>.zip`
- `package/bundles/mechanical-skills-collection.zip`
- `package/PACKAGES_INDEX.md` (validation summary, warnings, skipped items)
- [`package/PACKAGES_INDEX.md`](package/PACKAGES_INDEX.md) (validation summary, warnings, skipped items)
A skill is skipped by the packager if:
- `SKILL.md` is missing.
@@ -267,7 +270,7 @@ A skill is skipped by the packager if:
- Packaging passes and index shows no unexpected skips/warnings.
## Import in Claude
- Single import: upload a file from `package/per-skill/`.
- Single import: upload a file from `package/per-skill/skill/` (or `package/per-skill/zip/`).
- Internal distribution: use the `mechanical-skills-collection.zip` bundle.
## Operational Notes

View File

@@ -1,59 +1,64 @@
# PACKAGES INDEX
# Mechanical Skills Packages Index
- Generated: 2026-03-19 14:05:51 UTC
- Skills root: `/home/davide/cev-skills/skill`
- Valid skills packaged: 34
- Package formats: `.skill` + `.zip` (per skill)
- Bundle: `mechanical-skills-collection.zip`
- Validation status: PASS
## Snapshot
## Included Skills
| Item | Value |
| --- | --- |
| Generated (UTC) | `2026-03-19 14:25:13 UTC` |
| Valid skills packaged | **34** |
| Per-skill formats | `.skill` and `.zip` (separate folders) |
| Bundle | [`mechanical-skills-collection.zip`](bundles/mechanical-skills-collection.zip) |
| Validation status | **PASS** (8/8) |
- `bearings-seals-selection` (source dir: `bearings-seals-selection`, declared name: `bearings-seals-selection`)
- `calculation-report` (source dir: `calculation-report`, declared name: `calculation-report`)
- `cnc-sheet-casting-forging` (source dir: `cnc-sheet-casting-forging`, declared name: `cnc-sheet-casting-forging`)
- `design-review-fmea` (source dir: `design-review-fmea`, declared name: `design-review-fmea`)
- `dfm-dfa-review` (source dir: `dfm-dfa-review`, declared name: `dfm-dfa-review`)
- `dynamics-vibrations-analysis` (source dir: `dynamics-vibrations-analysis`, declared name: `dynamics-vibrations-analysis`)
- `energy-efficiency-analysis` (source dir: `energy-efficiency-analysis`, declared name: `energy-efficiency-analysis`)
- `failure-root-cause-analysis` (source dir: `failure-root-cause-analysis`, declared name: `failure-root-cause-analysis`)
- `fatigue-fracture-analysis` (source dir: `fatigue-fracture-analysis`, declared name: `fatigue-fracture-analysis`)
- `fea-cfd-review` (source dir: `fea-cfd-review`, declared name: `fea-cfd-review`)
- `fluid-analysis` (source dir: `fluid-analysis`, declared name: `fluid-analysis`)
- `gear-design` (source dir: `gear-design`, declared name: `gear-design`)
- `heat-treatment` (source dir: `heat-treatment`, declared name: `heat-treatment`)
- `joints-design` (source dir: `joints-design`, declared name: `joints-design`)
- `machine-elements-selection` (source dir: `machine-elements-selection`, declared name: `machine-elements-selection`)
- `material-failure-modes` (source dir: `material-failure-modes`, declared name: `material-failure-modes`)
- `materials-metallurgy` (source dir: `materials-metallurgy`, declared name: `materials-metallurgy`)
- `mechanical-orchestrator` (source dir: `mechanical-orchestrator`, declared name: `mechanical-orchestrator`)
- `modal-analysis` (source dir: `modal-analysis`, declared name: `modal-analysis`)
- `pressure-loss-pump-piping` (source dir: `pressure-loss-pump-piping`, declared name: `pressure-loss-pump-piping`)
- `process-selection` (source dir: `process-selection`, declared name: `process-selection`)
- `quality-metrology-plan` (source dir: `quality-metrology-plan`, declared name: `quality-metrology-plan`)
- `reliability-analysis` (source dir: `reliability-analysis`, declared name: `reliability-analysis`)
- `shafts-couplings-design` (source dir: `shafts-couplings-design`, declared name: `shafts-couplings-design`)
- `should-cost-estimation` (source dir: `should-cost-estimation`, declared name: `should-cost-estimation`)
- `spring-design` (source dir: `spring-design`, declared name: `spring-design`)
- `standards-compliance-check` (source dir: `standards-compliance-check`, declared name: `standards-compliance-check`)
- `structural-analysis` (source dir: `structural-analysis`, declared name: `structural-analysis`)
- `technical-report` (source dir: `technical-report`, declared name: `technical-report`)
- `test-plan-validation` (source dir: `test-plan-validation`, declared name: `test-plan-validation`)
- `thermal-analysis` (source dir: `thermal-analysis`, declared name: `thermal-analysis`)
- `thermal-expansion-stress` (source dir: `thermal-expansion-stress`, declared name: `thermal-expansion-stress`)
- `tolerance-gdt-fits` (source dir: `tolerance-gdt-fits`, declared name: `tolerance-gdt-fits`)
- `tribology-lubrication` (source dir: `tribology-lubrication`, declared name: `tribology-lubrication`)
## Quick Links
## Warnings
- [Per-skill root](per-skill/)
- [Per-skill `.skill`](per-skill/skill/)
- [Per-skill `.zip`](per-skill/zip/)
- [Bundle archive](bundles/mechanical-skills-collection.zip)
- [Upload markdown exports](upload-md/)
- [Skill sources](../skill/)
- None
## Skill Catalog
## Skipped
- None
## Validation
| Skill | Scope | Source | Packages | Markdown |
| --- | --- | --- | --- | --- |
| `bearings-seals-selection` | Bearing and seal selection for rotating equipment. | [`bearings-seals-selection/SKILL.md`](../skill/bearings-seals-selection/SKILL.md) | [`.skill`](per-skill/skill/bearings-seals-selection.skill) / [`.zip`](per-skill/zip/bearings-seals-selection.zip) | [`bearings-seals-selection.md`](upload-md/bearings-seals-selection.md) |
| `calculation-report` | Calculation report preparation for auditable engineering calculations. | [`calculation-report/SKILL.md`](../skill/calculation-report/SKILL.md) | [`.skill`](per-skill/skill/calculation-report.skill) / [`.zip`](per-skill/zip/calculation-report.zip) | [`calculation-report.md`](upload-md/calculation-report.md) |
| `cnc-sheet-casting-forging` | Detailed manufacturing guidance for CNC machining, sheet metal, casting, and forging. | [`cnc-sheet-casting-forging/SKILL.md`](../skill/cnc-sheet-casting-forging/SKILL.md) | [`.skill`](per-skill/skill/cnc-sheet-casting-forging.skill) / [`.zip`](per-skill/zip/cnc-sheet-casting-forging.zip) | [`cnc-sheet-casting-forging.md`](upload-md/cnc-sheet-casting-forging.md) |
| `design-review-fmea` | Structured design review and FMEA for risk reduction. | [`design-review-fmea/SKILL.md`](../skill/design-review-fmea/SKILL.md) | [`.skill`](per-skill/skill/design-review-fmea.skill) / [`.zip`](per-skill/zip/design-review-fmea.zip) | [`design-review-fmea.md`](upload-md/design-review-fmea.md) |
| `dfm-dfa-review` | Design for manufacturing and assembly review for mechanical products. | [`dfm-dfa-review/SKILL.md`](../skill/dfm-dfa-review/SKILL.md) | [`.skill`](per-skill/skill/dfm-dfa-review.skill) / [`.zip`](per-skill/zip/dfm-dfa-review.zip) | [`dfm-dfa-review.md`](upload-md/dfm-dfa-review.md) |
| `dynamics-vibrations-analysis` | Rigid-body dynamics and vibration response analysis. | [`dynamics-vibrations-analysis/SKILL.md`](../skill/dynamics-vibrations-analysis/SKILL.md) | [`.skill`](per-skill/skill/dynamics-vibrations-analysis.skill) / [`.zip`](per-skill/zip/dynamics-vibrations-analysis.zip) | [`dynamics-vibrations-analysis.md`](upload-md/dynamics-vibrations-analysis.md) |
| `energy-efficiency-analysis` | Energy efficiency optimization for mechanical and thermo-fluid systems. | [`energy-efficiency-analysis/SKILL.md`](../skill/energy-efficiency-analysis/SKILL.md) | [`.skill`](per-skill/skill/energy-efficiency-analysis.skill) / [`.zip`](per-skill/zip/energy-efficiency-analysis.zip) | [`energy-efficiency-analysis.md`](upload-md/energy-efficiency-analysis.md) |
| `failure-root-cause-analysis` | Root cause analysis for field or test failures in mechanical systems. | [`failure-root-cause-analysis/SKILL.md`](../skill/failure-root-cause-analysis/SKILL.md) | [`.skill`](per-skill/skill/failure-root-cause-analysis.skill) / [`.zip`](per-skill/zip/failure-root-cause-analysis.zip) | [`failure-root-cause-analysis.md`](upload-md/failure-root-cause-analysis.md) |
| `fatigue-fracture-analysis` | Fatigue life and fracture risk assessment for cyclic loading. | [`fatigue-fracture-analysis/SKILL.md`](../skill/fatigue-fracture-analysis/SKILL.md) | [`.skill`](per-skill/skill/fatigue-fracture-analysis.skill) / [`.zip`](per-skill/zip/fatigue-fracture-analysis.zip) | [`fatigue-fracture-analysis.md`](upload-md/fatigue-fracture-analysis.md) |
| `fea-cfd-review` | Critical review of FEA/CFD models and simulation credibility. | [`fea-cfd-review/SKILL.md`](../skill/fea-cfd-review/SKILL.md) | [`.skill`](per-skill/skill/fea-cfd-review.skill) / [`.zip`](per-skill/zip/fea-cfd-review.zip) | [`fea-cfd-review.md`](upload-md/fea-cfd-review.md) |
| `fluid-analysis` | Internal and external fluid flow analysis for engineering systems. | [`fluid-analysis/SKILL.md`](../skill/fluid-analysis/SKILL.md) | [`.skill`](per-skill/skill/fluid-analysis.skill) / [`.zip`](per-skill/zip/fluid-analysis.zip) | [`fluid-analysis.md`](upload-md/fluid-analysis.md) |
| `gear-design` | Gear train design and verification for power transmission. | [`gear-design/SKILL.md`](../skill/gear-design/SKILL.md) | [`.skill`](per-skill/skill/gear-design.skill) / [`.zip`](per-skill/zip/gear-design.zip) | [`gear-design.md`](upload-md/gear-design.md) |
| `heat-treatment` | Heat-treatment strategy for steels and alloys in mechanical design. | [`heat-treatment/SKILL.md`](../skill/heat-treatment/SKILL.md) | [`.skill`](per-skill/skill/heat-treatment.skill) / [`.zip`](per-skill/zip/heat-treatment.zip) | [`heat-treatment.md`](upload-md/heat-treatment.md) |
| `joints-design` | Joint design for bolts, welds, adhesives, and hybrid joints. | [`joints-design/SKILL.md`](../skill/joints-design/SKILL.md) | [`.skill`](per-skill/skill/joints-design.skill) / [`.zip`](per-skill/zip/joints-design.zip) | [`joints-design.md`](upload-md/joints-design.md) |
| `machine-elements-selection` | Integrated selection of machine elements for a mechanism or subsystem. | [`machine-elements-selection/SKILL.md`](../skill/machine-elements-selection/SKILL.md) | [`.skill`](per-skill/skill/machine-elements-selection.skill) / [`.zip`](per-skill/zip/machine-elements-selection.zip) | [`machine-elements-selection.md`](upload-md/machine-elements-selection.md) |
| `material-failure-modes` | Material failure mode identification and prevention. | [`material-failure-modes/SKILL.md`](../skill/material-failure-modes/SKILL.md) | [`.skill`](per-skill/skill/material-failure-modes.skill) / [`.zip`](per-skill/zip/material-failure-modes.zip) | [`material-failure-modes.md`](upload-md/material-failure-modes.md) |
| `materials-metallurgy` | Materials engineering and metallurgy guidance for design decisions. | [`materials-metallurgy/SKILL.md`](../skill/materials-metallurgy/SKILL.md) | [`.skill`](per-skill/skill/materials-metallurgy.skill) / [`.zip`](per-skill/zip/materials-metallurgy.zip) | [`materials-metallurgy.md`](upload-md/materials-metallurgy.md) |
| `mechanical-orchestrator` | Cross-domain mechanical engineering orchestration for complex design questions. | [`mechanical-orchestrator/SKILL.md`](../skill/mechanical-orchestrator/SKILL.md) | [`.skill`](per-skill/skill/mechanical-orchestrator.skill) / [`.zip`](per-skill/zip/mechanical-orchestrator.zip) | [`mechanical-orchestrator.md`](upload-md/mechanical-orchestrator.md) |
| `modal-analysis` | Modal behavior assessment for structures and assemblies. | [`modal-analysis/SKILL.md`](../skill/modal-analysis/SKILL.md) | [`.skill`](per-skill/skill/modal-analysis.skill) / [`.zip`](per-skill/zip/modal-analysis.zip) | [`modal-analysis.md`](upload-md/modal-analysis.md) |
| `pressure-loss-pump-piping` | Hydraulic network design including pressure losses, pumps, and piping. | [`pressure-loss-pump-piping/SKILL.md`](../skill/pressure-loss-pump-piping/SKILL.md) | [`.skill`](per-skill/skill/pressure-loss-pump-piping.skill) / [`.zip`](per-skill/zip/pressure-loss-pump-piping.zip) | [`pressure-loss-pump-piping.md`](upload-md/pressure-loss-pump-piping.md) |
| `process-selection` | Manufacturing process selection across machining, forming, casting, additive, and joining. | [`process-selection/SKILL.md`](../skill/process-selection/SKILL.md) | [`.skill`](per-skill/skill/process-selection.skill) / [`.zip`](per-skill/zip/process-selection.zip) | [`process-selection.md`](upload-md/process-selection.md) |
| `quality-metrology-plan` | Quality control and metrology planning for mechanical parts and assemblies. | [`quality-metrology-plan/SKILL.md`](../skill/quality-metrology-plan/SKILL.md) | [`.skill`](per-skill/skill/quality-metrology-plan.skill) / [`.zip`](per-skill/zip/quality-metrology-plan.zip) | [`quality-metrology-plan.md`](upload-md/quality-metrology-plan.md) |
| `reliability-analysis` | Reliability engineering for mechanical products and systems. | [`reliability-analysis/SKILL.md`](../skill/reliability-analysis/SKILL.md) | [`.skill`](per-skill/skill/reliability-analysis.skill) / [`.zip`](per-skill/zip/reliability-analysis.zip) | [`reliability-analysis.md`](upload-md/reliability-analysis.md) |
| `shafts-couplings-design` | Shaft and coupling design for torque and alignment demands. | [`shafts-couplings-design/SKILL.md`](../skill/shafts-couplings-design/SKILL.md) | [`.skill`](per-skill/skill/shafts-couplings-design.skill) / [`.zip`](per-skill/zip/shafts-couplings-design.zip) | [`shafts-couplings-design.md`](upload-md/shafts-couplings-design.md) |
| `should-cost-estimation` | Should-cost and cost-driver analysis for mechanical components. | [`should-cost-estimation/SKILL.md`](../skill/should-cost-estimation/SKILL.md) | [`.skill`](per-skill/skill/should-cost-estimation.skill) / [`.zip`](per-skill/zip/should-cost-estimation.zip) | [`should-cost-estimation.md`](upload-md/should-cost-estimation.md) |
| `spring-design` | Spring design for force-deflection and life requirements. | [`spring-design/SKILL.md`](../skill/spring-design/SKILL.md) | [`.skill`](per-skill/skill/spring-design.skill) / [`.zip`](per-skill/zip/spring-design.zip) | [`spring-design.md`](upload-md/spring-design.md) |
| `standards-compliance-check` | Engineering standards and compliance guidance for mechanical products. | [`standards-compliance-check/SKILL.md`](../skill/standards-compliance-check/SKILL.md) | [`.skill`](per-skill/skill/standards-compliance-check.skill) / [`.zip`](per-skill/zip/standards-compliance-check.zip) | [`standards-compliance-check.md`](upload-md/standards-compliance-check.md) |
| `structural-analysis` | Solid mechanics analysis for parts and assemblies under static loads. | [`structural-analysis/SKILL.md`](../skill/structural-analysis/SKILL.md) | [`.skill`](per-skill/skill/structural-analysis.skill) / [`.zip`](per-skill/zip/structural-analysis.zip) | [`structural-analysis.md`](upload-md/structural-analysis.md) |
| `technical-report` | Technical report writing for mechanical engineering deliverables. | [`technical-report/SKILL.md`](../skill/technical-report/SKILL.md) | [`.skill`](per-skill/skill/technical-report.skill) / [`.zip`](per-skill/zip/technical-report.zip) | [`technical-report.md`](upload-md/technical-report.md) |
| `test-plan-validation` | Test planning and validation strategy for mechanical design verification. | [`test-plan-validation/SKILL.md`](../skill/test-plan-validation/SKILL.md) | [`.skill`](per-skill/skill/test-plan-validation.skill) / [`.zip`](per-skill/zip/test-plan-validation.zip) | [`test-plan-validation.md`](upload-md/test-plan-validation.md) |
| `thermal-analysis` | Thermal behavior analysis for mechanical systems. | [`thermal-analysis/SKILL.md`](../skill/thermal-analysis/SKILL.md) | [`.skill`](per-skill/skill/thermal-analysis.skill) / [`.zip`](per-skill/zip/thermal-analysis.zip) | [`thermal-analysis.md`](upload-md/thermal-analysis.md) |
| `thermal-expansion-stress` | Thermal expansion mismatch and thermal stress assessment. | [`thermal-expansion-stress/SKILL.md`](../skill/thermal-expansion-stress/SKILL.md) | [`.skill`](per-skill/skill/thermal-expansion-stress.skill) / [`.zip`](per-skill/zip/thermal-expansion-stress.zip) | [`thermal-expansion-stress.md`](upload-md/thermal-expansion-stress.md) |
| `tolerance-gdt-fits` | Tolerance stack-up, GD&T, and fit selection for assemblies. | [`tolerance-gdt-fits/SKILL.md`](../skill/tolerance-gdt-fits/SKILL.md) | [`.skill`](per-skill/skill/tolerance-gdt-fits.skill) / [`.zip`](per-skill/zip/tolerance-gdt-fits.zip) | [`tolerance-gdt-fits.md`](upload-md/tolerance-gdt-fits.md) |
| `tribology-lubrication` | Tribology and lubrication engineering for moving interfaces. | [`tribology-lubrication/SKILL.md`](../skill/tribology-lubrication/SKILL.md) | [`.skill`](per-skill/skill/tribology-lubrication.skill) / [`.zip`](per-skill/zip/tribology-lubrication.zip) | [`tribology-lubrication.md`](upload-md/tribology-lubrication.md) |
## Validation Checks
- [x] package count check: expected 68, found 68
- [x] bearings-seals-selection.skill: OK
- [x] bearings-seals-selection.zip: OK
@@ -63,7 +68,18 @@
- [x] cnc-sheet-casting-forging.zip: OK
- [x] bundle contains all valid skill directories
## Warnings
- None
## Skipped
- None
## Output Paths
- `package/per-skill/`
- `package/bundles/`
- [`package/per-skill/`](per-skill/)
- [`package/per-skill/skill/`](per-skill/skill/)
- [`package/per-skill/zip/`](per-skill/zip/)
- [`package/bundles/`](bundles/)
- [`package/upload-md/`](upload-md/)

View File

@@ -60,8 +60,10 @@ def iter_skill_dirs(skills_root: Path) -> list[Path]:
]
def ensure_clean_output(output_dir: Path) -> tuple[Path, Path]:
def ensure_clean_output(output_dir: Path) -> tuple[Path, Path, Path, Path]:
per_skill_dir = output_dir / "per-skill"
per_skill_skill_dir = per_skill_dir / "skill"
per_skill_zip_dir = per_skill_dir / "zip"
bundles_dir = output_dir / "bundles"
if per_skill_dir.exists():
@@ -69,9 +71,10 @@ def ensure_clean_output(output_dir: Path) -> tuple[Path, Path]:
if bundles_dir.exists():
shutil.rmtree(bundles_dir)
per_skill_dir.mkdir(parents=True, exist_ok=True)
per_skill_skill_dir.mkdir(parents=True, exist_ok=True)
per_skill_zip_dir.mkdir(parents=True, exist_ok=True)
bundles_dir.mkdir(parents=True, exist_ok=True)
return per_skill_dir, bundles_dir
return per_skill_dir, per_skill_skill_dir, per_skill_zip_dir, bundles_dir
def add_directory_to_zip(zip_file: ZipFile, source_dir: Path, arc_prefix: str | None = None) -> None:
@@ -84,9 +87,13 @@ def add_directory_to_zip(zip_file: ZipFile, source_dir: Path, arc_prefix: str |
zip_file.write(file_path, relative)
def create_skill_archives(skill: SkillRecord, per_skill_dir: Path) -> tuple[Path, Path]:
skill_file = per_skill_dir / f"{skill.package_name}.skill"
zip_file = per_skill_dir / f"{skill.package_name}.zip"
def create_skill_archives(
skill: SkillRecord,
per_skill_skill_dir: Path,
per_skill_zip_dir: Path,
) -> tuple[Path, Path]:
skill_file = per_skill_skill_dir / f"{skill.package_name}.skill"
zip_file = per_skill_zip_dir / f"{skill.package_name}.zip"
with ZipFile(skill_file, "w", compression=ZIP_DEFLATED) as zf:
add_directory_to_zip(zf, skill.source_path)
@@ -123,37 +130,98 @@ def validate_bundle_contains_skills(bundle_path: Path, source_dir_names: list[st
def build_index(
output_file: Path,
skills_root: Path,
valid_skills: list[SkillRecord],
skipped: list[str],
warnings: list[str],
validations: list[tuple[bool, str]],
bundle_path: Path,
) -> None:
def table_safe(value: str) -> str:
return value.replace("|", r"\|").replace("\n", " ").strip()
def concise_scope(value: str, max_len: int = 120) -> str:
cleaned = " ".join(value.split()).strip()
if not cleaned:
return "N/A"
parts = cleaned.split(". ", 1)
scope = parts[0].strip()
if len(parts) > 1 and not scope.endswith("."):
scope = f"{scope}."
if len(scope) > max_len:
scope = scope[: max_len - 3].rstrip() + "..."
return table_safe(scope)
ts = datetime.now(timezone.utc).strftime("%Y-%m-%d %H:%M:%S UTC")
all_ok = all(ok for ok, _ in validations)
passed_validations = sum(1 for ok, _ in validations if ok)
total_validations = len(validations)
package_dir = output_file.parent
upload_md_dir = package_dir / "upload-md"
lines = [
"# PACKAGES INDEX",
"# Mechanical Skills Packages Index",
"",
f"- Generated: {ts}",
f"- Skills root: `{skills_root}`",
f"- Valid skills packaged: {len(valid_skills)}",
f"- Package formats: `.skill` + `.zip` (per skill)",
f"- Bundle: `{bundle_path.name}`",
f"- Validation status: {'PASS' if all_ok else 'FAIL'}",
"## Snapshot",
"",
"## Included Skills",
"| Item | Value |",
"| --- | --- |",
f"| Generated (UTC) | `{ts}` |",
f"| Valid skills packaged | **{len(valid_skills)}** |",
"| Per-skill formats | `.skill` and `.zip` (separate folders) |",
f"| Bundle | [`{bundle_path.name}`](bundles/{bundle_path.name}) |",
f"| Validation status | **{'PASS' if all_ok else 'FAIL'}** ({passed_validations}/{total_validations}) |",
"",
"## Quick Links",
"",
"- [Per-skill root](per-skill/)",
"- [Per-skill `.skill`](per-skill/skill/)",
"- [Per-skill `.zip`](per-skill/zip/)",
f"- [Bundle archive](bundles/{bundle_path.name})",
"- [Upload markdown exports](upload-md/)",
"- [Skill sources](../skill/)",
"",
"## Skill Catalog",
"",
"| Skill | Scope | Source | Packages | Markdown |",
"| --- | --- | --- | --- | --- |",
]
for skill in valid_skills:
for skill in sorted(valid_skills, key=lambda item: item.package_name):
source_rel = f"../skill/{skill.source_dir_name}/SKILL.md"
markdown_rel = f"upload-md/{skill.package_name}.md"
skill_rel = f"per-skill/skill/{skill.package_name}.skill"
zip_rel = f"per-skill/zip/{skill.package_name}.zip"
markdown_cell = (
f"[`{skill.package_name}.md`]({markdown_rel})"
if (upload_md_dir / f"{skill.package_name}.md").exists()
else "N/A"
)
source_cell = (
f"[`{skill.source_dir_name}/SKILL.md`]({source_rel})"
if (skill.source_path / "SKILL.md").exists()
else "N/A"
)
lines.append(
"- `{name}` (source dir: `{src}`, declared name: `{decl}`)".format(
name=skill.package_name, src=skill.source_dir_name, decl=skill.declared_name
"| `{name}` | {scope} | {source} | [`.skill`]({skill_pkg}) / [`.zip`]({zip_pkg}) | {markdown} |".format(
name=skill.package_name,
scope=concise_scope(skill.description),
source=source_cell,
markdown=markdown_cell,
skill_pkg=skill_rel,
zip_pkg=zip_rel,
)
)
lines.extend(["", "## Validation Checks"])
lines.extend(
[f"- [{'x' if ok else ' '}] {message}" for ok, message in validations]
)
lines.extend(["", "## Warnings", ""])
if warnings:
lines.extend([f"- {msg}" for msg in warnings])
@@ -166,16 +234,23 @@ def build_index(
else:
lines.append("- None")
lines.extend(["", "## Validation", ""])
for ok, message in validations:
lines.append(f"- [{'x' if ok else ' '}] {message}")
lines.extend(["", "## Output Paths", "", "- `package/per-skill/`", "- `package/bundles/`"])
lines.extend(
[
"",
"## Output Paths",
"",
"- [`package/per-skill/`](per-skill/)",
"- [`package/per-skill/skill/`](per-skill/skill/)",
"- [`package/per-skill/zip/`](per-skill/zip/)",
"- [`package/bundles/`](bundles/)",
"- [`package/upload-md/`](upload-md/)",
]
)
output_file.write_text("\n".join(lines) + "\n", encoding="utf-8")
def package_skills(skills_root: Path, output_dir: Path, bundle_name: str, spot_check_count: int) -> int:
per_skill_dir, bundles_dir = ensure_clean_output(output_dir)
per_skill_dir, per_skill_skill_dir, per_skill_zip_dir, bundles_dir = ensure_clean_output(output_dir)
skipped: list[str] = []
warnings: list[str] = []
@@ -221,7 +296,7 @@ def package_skills(skills_root: Path, output_dir: Path, bundle_name: str, spot_c
)
for skill in valid_skills:
create_skill_archives(skill, per_skill_dir)
create_skill_archives(skill, per_skill_skill_dir, per_skill_zip_dir)
bundle_path = bundles_dir / bundle_name
with ZipFile(bundle_path, "w", compression=ZIP_DEFLATED) as zf:
@@ -231,7 +306,7 @@ def package_skills(skills_root: Path, output_dir: Path, bundle_name: str, spot_c
validations: list[tuple[bool, str]] = []
expected = 2 * len(valid_skills)
produced = len(list(per_skill_dir.glob("*.skill"))) + len(list(per_skill_dir.glob("*.zip")))
produced = len(list(per_skill_skill_dir.glob("*.skill"))) + len(list(per_skill_zip_dir.glob("*.zip")))
validations.append(
(
expected == produced,
@@ -241,8 +316,8 @@ def package_skills(skills_root: Path, output_dir: Path, bundle_name: str, spot_c
check_items = valid_skills[: max(0, spot_check_count)]
for skill in check_items:
skill_archive = per_skill_dir / f"{skill.package_name}.skill"
zip_archive = per_skill_dir / f"{skill.package_name}.zip"
skill_archive = per_skill_skill_dir / f"{skill.package_name}.skill"
zip_archive = per_skill_zip_dir / f"{skill.package_name}.zip"
validations.append(validate_archive_contains_skill_md(skill_archive))
validations.append(validate_archive_contains_skill_md(zip_archive))
@@ -256,7 +331,6 @@ def package_skills(skills_root: Path, output_dir: Path, bundle_name: str, spot_c
index_path = output_dir / "PACKAGES_INDEX.md"
build_index(
output_file=index_path,
skills_root=skills_root,
valid_skills=valid_skills,
skipped=skipped,
warnings=warnings,
@@ -268,7 +342,9 @@ def package_skills(skills_root: Path, output_dir: Path, bundle_name: str, spot_c
print(f"Valid skills: {len(valid_skills)}")
print(f"Skipped: {len(skipped)}")
print(f"Warnings: {len(warnings)}")
print(f"Per-skill output: {per_skill_dir}")
print(f"Per-skill output root: {per_skill_dir}")
print(f"Per-skill .skill output: {per_skill_skill_dir}")
print(f"Per-skill .zip output: {per_skill_zip_dir}")
print(f"Bundle output: {bundle_path}")
print(f"Index: {index_path}")
all_ok = all(ok for ok, _ in validations)