skillware 0.3.8__tar.gz → 0.3.9__tar.gz

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 (122) hide show
  1. {skillware-0.3.8 → skillware-0.3.9}/MANIFEST.in +0 -1
  2. {skillware-0.3.8/skillware.egg-info → skillware-0.3.9}/PKG-INFO +1 -1
  3. {skillware-0.3.8 → skillware-0.3.9}/pyproject.toml +1 -1
  4. {skillware-0.3.8 → skillware-0.3.9}/skillware/cli.py +54 -20
  5. {skillware-0.3.8 → skillware-0.3.9/skillware.egg-info}/PKG-INFO +1 -1
  6. {skillware-0.3.8 → skillware-0.3.9}/skillware.egg-info/SOURCES.txt +0 -1
  7. {skillware-0.3.8 → skillware-0.3.9}/tests/test_cli.py +41 -0
  8. skillware-0.3.8/examples/README.md +0 -61
  9. {skillware-0.3.8 → skillware-0.3.9}/LICENSE +0 -0
  10. {skillware-0.3.8 → skillware-0.3.9}/README.md +0 -0
  11. {skillware-0.3.8 → skillware-0.3.9}/setup.cfg +0 -0
  12. {skillware-0.3.8 → skillware-0.3.9}/skills/__init__.py +0 -0
  13. {skillware-0.3.8 → skillware-0.3.9}/skills/compliance/__init__.py +0 -0
  14. {skillware-0.3.8 → skillware-0.3.9}/skills/compliance/mica_module/__init__.py +0 -0
  15. {skillware-0.3.8 → skillware-0.3.9}/skills/compliance/mica_module/card.json +0 -0
  16. {skillware-0.3.8 → skillware-0.3.9}/skills/compliance/mica_module/instructions.md +0 -0
  17. {skillware-0.3.8 → skillware-0.3.9}/skills/compliance/mica_module/manifest.yaml +0 -0
  18. {skillware-0.3.8 → skillware-0.3.9}/skills/compliance/mica_module/mica_corpus.json +0 -0
  19. {skillware-0.3.8 → skillware-0.3.9}/skills/compliance/mica_module/skill.py +0 -0
  20. {skillware-0.3.8 → skillware-0.3.9}/skills/compliance/mica_module/test_skill.py +0 -0
  21. {skillware-0.3.8 → skillware-0.3.9}/skills/compliance/pii_masker/__init__.py +0 -0
  22. {skillware-0.3.8 → skillware-0.3.9}/skills/compliance/pii_masker/card.json +0 -0
  23. {skillware-0.3.8 → skillware-0.3.9}/skills/compliance/pii_masker/instructions.md +0 -0
  24. {skillware-0.3.8 → skillware-0.3.9}/skills/compliance/pii_masker/manifest.yaml +0 -0
  25. {skillware-0.3.8 → skillware-0.3.9}/skills/compliance/pii_masker/skill.py +0 -0
  26. {skillware-0.3.8 → skillware-0.3.9}/skills/compliance/pii_masker/test_skill.py +0 -0
  27. {skillware-0.3.8 → skillware-0.3.9}/skills/compliance/tos_evaluator/__init__.py +0 -0
  28. {skillware-0.3.8 → skillware-0.3.9}/skills/compliance/tos_evaluator/card.json +0 -0
  29. {skillware-0.3.8 → skillware-0.3.9}/skills/compliance/tos_evaluator/instructions.md +0 -0
  30. {skillware-0.3.8 → skillware-0.3.9}/skills/compliance/tos_evaluator/manifest.yaml +0 -0
  31. {skillware-0.3.8 → skillware-0.3.9}/skills/compliance/tos_evaluator/skill.py +0 -0
  32. {skillware-0.3.8 → skillware-0.3.9}/skills/compliance/tos_evaluator/test_skill.py +0 -0
  33. {skillware-0.3.8 → skillware-0.3.9}/skills/data_engineering/__init__.py +0 -0
  34. {skillware-0.3.8 → skillware-0.3.9}/skills/data_engineering/novelty_extractor/__init__.py +0 -0
  35. {skillware-0.3.8 → skillware-0.3.9}/skills/data_engineering/novelty_extractor/card.json +0 -0
  36. {skillware-0.3.8 → skillware-0.3.9}/skills/data_engineering/novelty_extractor/instructions.md +0 -0
  37. {skillware-0.3.8 → skillware-0.3.9}/skills/data_engineering/novelty_extractor/manifest.yaml +0 -0
  38. {skillware-0.3.8 → skillware-0.3.9}/skills/data_engineering/novelty_extractor/skill.py +0 -0
  39. {skillware-0.3.8 → skillware-0.3.9}/skills/data_engineering/novelty_extractor/test_skill.py +0 -0
  40. {skillware-0.3.8 → skillware-0.3.9}/skills/data_engineering/synthetic_generator/__init__.py +0 -0
  41. {skillware-0.3.8 → skillware-0.3.9}/skills/data_engineering/synthetic_generator/card.json +0 -0
  42. {skillware-0.3.8 → skillware-0.3.9}/skills/data_engineering/synthetic_generator/instructions.md +0 -0
  43. {skillware-0.3.8 → skillware-0.3.9}/skills/data_engineering/synthetic_generator/manifest.yaml +0 -0
  44. {skillware-0.3.8 → skillware-0.3.9}/skills/data_engineering/synthetic_generator/skill.py +0 -0
  45. {skillware-0.3.8 → skillware-0.3.9}/skills/data_engineering/synthetic_generator/test_skill.py +0 -0
  46. {skillware-0.3.8 → skillware-0.3.9}/skills/defi/__init__.py +0 -0
  47. {skillware-0.3.8 → skillware-0.3.9}/skills/defi/evm_tx_handler/__init__.py +0 -0
  48. {skillware-0.3.8 → skillware-0.3.9}/skills/defi/evm_tx_handler/abis.py +0 -0
  49. {skillware-0.3.8 → skillware-0.3.9}/skills/defi/evm_tx_handler/card.json +0 -0
  50. {skillware-0.3.8 → skillware-0.3.9}/skills/defi/evm_tx_handler/config.yaml.example +0 -0
  51. {skillware-0.3.8 → skillware-0.3.9}/skills/defi/evm_tx_handler/data/addressbook.yaml +0 -0
  52. {skillware-0.3.8 → skillware-0.3.9}/skills/defi/evm_tx_handler/data/chains.yaml +0 -0
  53. {skillware-0.3.8 → skillware-0.3.9}/skills/defi/evm_tx_handler/data/tokens.yaml +0 -0
  54. {skillware-0.3.8 → skillware-0.3.9}/skills/defi/evm_tx_handler/instructions.md +0 -0
  55. {skillware-0.3.8 → skillware-0.3.9}/skills/defi/evm_tx_handler/manifest.yaml +0 -0
  56. {skillware-0.3.8 → skillware-0.3.9}/skills/defi/evm_tx_handler/skill.py +0 -0
  57. {skillware-0.3.8 → skillware-0.3.9}/skills/defi/evm_tx_handler/test_skill.py +0 -0
  58. {skillware-0.3.8 → skillware-0.3.9}/skills/dev_tools/__init__.py +0 -0
  59. {skillware-0.3.8 → skillware-0.3.9}/skills/dev_tools/issue_resolver/__init__.py +0 -0
  60. {skillware-0.3.8 → skillware-0.3.9}/skills/dev_tools/issue_resolver/card.json +0 -0
  61. {skillware-0.3.8 → skillware-0.3.9}/skills/dev_tools/issue_resolver/instructions.md +0 -0
  62. {skillware-0.3.8 → skillware-0.3.9}/skills/dev_tools/issue_resolver/manifest.yaml +0 -0
  63. {skillware-0.3.8 → skillware-0.3.9}/skills/dev_tools/issue_resolver/skill.py +0 -0
  64. {skillware-0.3.8 → skillware-0.3.9}/skills/dev_tools/issue_resolver/test_skill.py +0 -0
  65. {skillware-0.3.8 → skillware-0.3.9}/skills/dev_tools/issue_resolver/workflow.py +0 -0
  66. {skillware-0.3.8 → skillware-0.3.9}/skills/finance/__init__.py +0 -0
  67. {skillware-0.3.8 → skillware-0.3.9}/skills/finance/wallet_screening/__init__.py +0 -0
  68. {skillware-0.3.8 → skillware-0.3.9}/skills/finance/wallet_screening/card.json +0 -0
  69. {skillware-0.3.8 → skillware-0.3.9}/skills/finance/wallet_screening/data/entities.ftm.json +0 -0
  70. {skillware-0.3.8 → skillware-0.3.9}/skills/finance/wallet_screening/data/malicious_scs_2025.json +0 -0
  71. {skillware-0.3.8 → skillware-0.3.9}/skills/finance/wallet_screening/data/normalized_fbi_lazarus_20250722_180019.json +0 -0
  72. {skillware-0.3.8 → skillware-0.3.9}/skills/finance/wallet_screening/data/normalized_israel_nbctf_20250722_180019.json +0 -0
  73. {skillware-0.3.8 → skillware-0.3.9}/skills/finance/wallet_screening/data/normalized_uniswap_trm.json +0 -0
  74. {skillware-0.3.8 → skillware-0.3.9}/skills/finance/wallet_screening/instructions.md +0 -0
  75. {skillware-0.3.8 → skillware-0.3.9}/skills/finance/wallet_screening/maintenance/normalization_tool.py +0 -0
  76. {skillware-0.3.8 → skillware-0.3.9}/skills/finance/wallet_screening/maintenance/normalize_uniswap_trm.py +0 -0
  77. {skillware-0.3.8 → skillware-0.3.9}/skills/finance/wallet_screening/manifest.yaml +0 -0
  78. {skillware-0.3.8 → skillware-0.3.9}/skills/finance/wallet_screening/skill.py +0 -0
  79. {skillware-0.3.8 → skillware-0.3.9}/skills/finance/wallet_screening/test_skill.py +0 -0
  80. {skillware-0.3.8 → skillware-0.3.9}/skills/office/__init__.py +0 -0
  81. {skillware-0.3.8 → skillware-0.3.9}/skills/office/pdf_form_filler/__init__.py +0 -0
  82. {skillware-0.3.8 → skillware-0.3.9}/skills/office/pdf_form_filler/card.json +0 -0
  83. {skillware-0.3.8 → skillware-0.3.9}/skills/office/pdf_form_filler/instructions.md +0 -0
  84. {skillware-0.3.8 → skillware-0.3.9}/skills/office/pdf_form_filler/manifest.yaml +0 -0
  85. {skillware-0.3.8 → skillware-0.3.9}/skills/office/pdf_form_filler/skill.py +0 -0
  86. {skillware-0.3.8 → skillware-0.3.9}/skills/office/pdf_form_filler/test_skill.py +0 -0
  87. {skillware-0.3.8 → skillware-0.3.9}/skills/office/pdf_form_filler/utils.py +0 -0
  88. {skillware-0.3.8 → skillware-0.3.9}/skills/optimization/__init__.py +0 -0
  89. {skillware-0.3.8 → skillware-0.3.9}/skills/optimization/prompt_rewriter/__init__.py +0 -0
  90. {skillware-0.3.8 → skillware-0.3.9}/skills/optimization/prompt_rewriter/card.json +0 -0
  91. {skillware-0.3.8 → skillware-0.3.9}/skills/optimization/prompt_rewriter/instructions.md +0 -0
  92. {skillware-0.3.8 → skillware-0.3.9}/skills/optimization/prompt_rewriter/manifest.yaml +0 -0
  93. {skillware-0.3.8 → skillware-0.3.9}/skills/optimization/prompt_rewriter/skill.py +0 -0
  94. {skillware-0.3.8 → skillware-0.3.9}/skills/optimization/prompt_rewriter/test_skill.py +0 -0
  95. {skillware-0.3.8 → skillware-0.3.9}/skills/wellness/__init__.py +0 -0
  96. {skillware-0.3.8 → skillware-0.3.9}/skills/wellness/mental_coach/__init__.py +0 -0
  97. {skillware-0.3.8 → skillware-0.3.9}/skills/wellness/mental_coach/card.json +0 -0
  98. {skillware-0.3.8 → skillware-0.3.9}/skills/wellness/mental_coach/constraints.py +0 -0
  99. {skillware-0.3.8 → skillware-0.3.9}/skills/wellness/mental_coach/crisis_gate.py +0 -0
  100. {skillware-0.3.8 → skillware-0.3.9}/skills/wellness/mental_coach/instructions.md +0 -0
  101. {skillware-0.3.8 → skillware-0.3.9}/skills/wellness/mental_coach/kb/corpus.json +0 -0
  102. {skillware-0.3.8 → skillware-0.3.9}/skills/wellness/mental_coach/kb/crisis_resources.json +0 -0
  103. {skillware-0.3.8 → skillware-0.3.9}/skills/wellness/mental_coach/kb/hard_constraints.yaml +0 -0
  104. {skillware-0.3.8 → skillware-0.3.9}/skills/wellness/mental_coach/kb_provider.py +0 -0
  105. {skillware-0.3.8 → skillware-0.3.9}/skills/wellness/mental_coach/manifest.yaml +0 -0
  106. {skillware-0.3.8 → skillware-0.3.9}/skills/wellness/mental_coach/resources.py +0 -0
  107. {skillware-0.3.8 → skillware-0.3.9}/skills/wellness/mental_coach/skill.py +0 -0
  108. {skillware-0.3.8 → skillware-0.3.9}/skills/wellness/mental_coach/test_skill.py +0 -0
  109. {skillware-0.3.8 → skillware-0.3.9}/skillware/__init__.py +0 -0
  110. {skillware-0.3.8 → skillware-0.3.9}/skillware/__main__.py +0 -0
  111. {skillware-0.3.8 → skillware-0.3.9}/skillware/core/__init__.py +0 -0
  112. {skillware-0.3.8 → skillware-0.3.9}/skillware/core/base_skill.py +0 -0
  113. {skillware-0.3.8 → skillware-0.3.9}/skillware/core/env.py +0 -0
  114. {skillware-0.3.8 → skillware-0.3.9}/skillware/core/loader.py +0 -0
  115. {skillware-0.3.8 → skillware-0.3.9}/skillware/version_policy.py +0 -0
  116. {skillware-0.3.8 → skillware-0.3.9}/skillware.egg-info/dependency_links.txt +0 -0
  117. {skillware-0.3.8 → skillware-0.3.9}/skillware.egg-info/entry_points.txt +0 -0
  118. {skillware-0.3.8 → skillware-0.3.9}/skillware.egg-info/requires.txt +0 -0
  119. {skillware-0.3.8 → skillware-0.3.9}/skillware.egg-info/top_level.txt +0 -0
  120. {skillware-0.3.8 → skillware-0.3.9}/tests/test_loader.py +0 -0
  121. {skillware-0.3.8 → skillware-0.3.9}/tests/test_skill_issuer.py +0 -0
  122. {skillware-0.3.8 → skillware-0.3.9}/tests/test_version_policy.py +0 -0
@@ -1,4 +1,3 @@
1
1
  graft skills
2
- include examples/README.md
3
2
  global-exclude __pycache__
4
3
  global-exclude *.py[cod]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: skillware
3
- Version: 0.3.8
3
+ Version: 0.3.9
4
4
  Summary: A framework for modular, self-contained AI skills.
5
5
  Author-email: ARPA Hellenic Logical Systems <skillware-os@arpacorp.net>
6
6
  License: MIT License
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "skillware"
7
- version = "0.3.8"
7
+ version = "0.3.9"
8
8
  description = "A framework for modular, self-contained AI skills."
9
9
  readme = "README.md"
10
10
  authors = [
@@ -5,7 +5,9 @@ import sys
5
5
  import yaml
6
6
  from collections import defaultdict
7
7
  from pathlib import Path
8
- from typing import List, Dict, Any, Optional, Tuple
8
+ from typing import List, Dict, Any, Optional, Tuple, Union
9
+
10
+ import requests
9
11
 
10
12
  from rich.table import Table
11
13
  from rich.console import Console
@@ -29,6 +31,13 @@ _EXAMPLES_README_REL = Path("examples") / "README.md"
29
31
  _PARENT_WALK_LIMIT = 6
30
32
  _SKILL_ID_PATTERN = re.compile(r"`([\w-]+/[\w-]+)`")
31
33
  _EXAMPLES_GITHUB_BLOB_BASE = "https://github.com/ARPAHLS/skillware/blob/main/examples"
34
+ _EXAMPLES_README_GITHUB_URL = (
35
+ "https://github.com/ARPAHLS/skillware/blob/main/examples/README.md"
36
+ )
37
+ _EXAMPLES_README_RAW_URL = (
38
+ "https://raw.githubusercontent.com/ARPAHLS/skillware/main/examples/README.md"
39
+ )
40
+ _EXAMPLES_INDEX_SOURCE = Union[Path, str]
32
41
 
33
42
 
34
43
  def _flatten_table_cell(text: str, max_len: int = 80) -> str:
@@ -39,10 +48,12 @@ def _flatten_table_cell(text: str, max_len: int = 80) -> str:
39
48
  return cleaned
40
49
 
41
50
 
42
- def _examples_readme_display_path(readme_path: Path) -> str:
43
- """Prefer a short relative path in CLI output."""
51
+ def _examples_readme_display_path(source: _EXAMPLES_INDEX_SOURCE) -> str:
52
+ """Prefer a short relative path in CLI output; GitHub URL when loaded remotely."""
53
+ if isinstance(source, str):
54
+ return source
44
55
  try:
45
- return readme_path.relative_to(Path.cwd()).as_posix()
56
+ return source.relative_to(Path.cwd()).as_posix()
46
57
  except ValueError:
47
58
  return "examples/README.md"
48
59
 
@@ -53,7 +64,7 @@ def _example_github_url(script: str) -> str:
53
64
 
54
65
 
55
66
  def _examples_readme_path() -> Optional[Path]:
56
- """Resolve examples/README.md for editable checkout or bundled install."""
67
+ """Resolve a local examples/README.md from checkout or cwd walk."""
57
68
  candidates: List[Path] = []
58
69
 
59
70
  package_root = Path(__file__).resolve().parent.parent
@@ -75,9 +86,18 @@ def _examples_readme_path() -> Optional[Path]:
75
86
  return None
76
87
 
77
88
 
78
- def _parse_examples_index(readme_path: Path) -> List[Dict[str, Any]]:
79
- """Parse the Runnable Scripts table from examples/README.md."""
80
- text = readme_path.read_text(encoding="utf-8")
89
+ def _fetch_examples_readme_from_github() -> Optional[str]:
90
+ """Download examples/README.md from the canonical repo on GitHub."""
91
+ try:
92
+ response = requests.get(_EXAMPLES_README_RAW_URL, timeout=10)
93
+ response.raise_for_status()
94
+ return response.text
95
+ except (requests.RequestException, OSError):
96
+ return None
97
+
98
+
99
+ def _parse_examples_index_text(text: str) -> List[Dict[str, Any]]:
100
+ """Parse the Runnable Scripts table from examples/README.md content."""
81
101
  section_start = text.find("## Runnable Scripts")
82
102
  if section_start == -1:
83
103
  return []
@@ -112,6 +132,11 @@ def _parse_examples_index(readme_path: Path) -> List[Dict[str, Any]]:
112
132
  return rows
113
133
 
114
134
 
135
+ def _parse_examples_index(readme_path: Path) -> List[Dict[str, Any]]:
136
+ """Parse the Runnable Scripts table from a local examples/README.md file."""
137
+ return _parse_examples_index_text(readme_path.read_text(encoding="utf-8"))
138
+
139
+
115
140
  def _example_counts_by_skill(rows: List[Dict[str, Any]]) -> Dict[str, int]:
116
141
  """Map skill ID to indexed script count (multi-skill rows count toward each ID)."""
117
142
  counts: Dict[str, int] = defaultdict(int)
@@ -121,11 +146,16 @@ def _example_counts_by_skill(rows: List[Dict[str, Any]]) -> Dict[str, int]:
121
146
  return dict(counts)
122
147
 
123
148
 
124
- def _load_examples_index() -> Tuple[List[Dict[str, Any]], Optional[Path]]:
149
+ def _load_examples_index() -> Tuple[List[Dict[str, Any]], Optional[_EXAMPLES_INDEX_SOURCE]]:
125
150
  readme_path = _examples_readme_path()
126
- if readme_path is None:
127
- return [], None
128
- return _parse_examples_index(readme_path), readme_path
151
+ if readme_path is not None:
152
+ return _parse_examples_index_text(readme_path.read_text(encoding="utf-8")), readme_path
153
+
154
+ text = _fetch_examples_readme_from_github()
155
+ if text is not None:
156
+ return _parse_examples_index_text(text), _EXAMPLES_README_GITHUB_URL
157
+
158
+ return [], None
129
159
 
130
160
 
131
161
  def _get_skill_roots(skills_root_override: Optional[Path] = None) -> List[Path]:
@@ -323,10 +353,11 @@ def cmd_list(
323
353
 
324
354
  example_counts: Dict[str, int] = {}
325
355
  if show_examples:
326
- rows, readme_path = _load_examples_index()
327
- if readme_path is None:
356
+ rows, readme_source = _load_examples_index()
357
+ if readme_source is None:
328
358
  console.print(
329
- "examples/README.md not found; cannot show example counts.",
359
+ "examples/README.md not found locally or on GitHub; "
360
+ "cannot show example counts.",
330
361
  style="bold #FF9AA2",
331
362
  )
332
363
  else:
@@ -373,9 +404,12 @@ def cmd_examples(
373
404
  if console is None:
374
405
  console = Console()
375
406
 
376
- rows, readme_path = _load_examples_index()
377
- if readme_path is None:
378
- console.print("examples/README.md not found.", style="bold #FF9AA2")
407
+ rows, readme_source = _load_examples_index()
408
+ if readme_source is None:
409
+ console.print(
410
+ "Could not load examples/README.md from the repo or GitHub.",
411
+ style="bold #FF9AA2",
412
+ )
379
413
  return 1
380
414
 
381
415
  if skill_id:
@@ -391,7 +425,7 @@ def cmd_examples(
391
425
  if not rows:
392
426
  console.print(
393
427
  f"No indexed examples for '{skill_id}'. "
394
- f"See {_examples_readme_display_path(readme_path)} for the full inventory.",
428
+ f"See {_examples_readme_display_path(readme_source)} for the full inventory.",
395
429
  style="bold #FF9AA2",
396
430
  )
397
431
  return 1
@@ -423,7 +457,7 @@ def cmd_examples(
423
457
 
424
458
  console.print(table)
425
459
  console.print(
426
- f"Full notes: {_examples_readme_display_path(readme_path)}",
460
+ f"Full notes: {_examples_readme_display_path(readme_source)}",
427
461
  style="dim",
428
462
  )
429
463
  return 0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: skillware
3
- Version: 0.3.8
3
+ Version: 0.3.9
4
4
  Summary: A framework for modular, self-contained AI skills.
5
5
  Author-email: ARPA Hellenic Logical Systems <skillware-os@arpacorp.net>
6
6
  License: MIT License
@@ -2,7 +2,6 @@ LICENSE
2
2
  MANIFEST.in
3
3
  README.md
4
4
  pyproject.toml
5
- examples/README.md
6
5
  skills/__init__.py
7
6
  skills/compliance/__init__.py
8
7
  skills/compliance/mica_module/__init__.py
@@ -2,6 +2,7 @@ from skillware.cli import (
2
2
  _discover_skills,
3
3
  _resolve_pytest_targets,
4
4
  _parse_examples_index,
5
+ _load_examples_index,
5
6
  _example_counts_by_skill,
6
7
  _example_github_url,
7
8
  cmd_list,
@@ -583,6 +584,46 @@ def test_cmd_examples_unknown_skill_returns_nonzero(examples_readme):
583
584
  assert rc == 1
584
585
 
585
586
 
587
+ def test_load_examples_index_prefers_local_readme(examples_readme):
588
+ rows, source = _load_examples_index()
589
+ assert len(rows) == 2
590
+ assert source == examples_readme
591
+
592
+
593
+ def test_load_examples_index_github_fallback(monkeypatch):
594
+ monkeypatch.setattr("skillware.cli._examples_readme_path", lambda: None)
595
+
596
+ class FakeResponse:
597
+ text = SAMPLE_EXAMPLES_README
598
+
599
+ def raise_for_status(self):
600
+ return None
601
+
602
+ monkeypatch.setattr(
603
+ "skillware.cli.requests.get",
604
+ lambda url, timeout: FakeResponse(),
605
+ )
606
+
607
+ rows, source = _load_examples_index()
608
+ assert len(rows) == 2
609
+ assert source == (
610
+ "https://github.com/ARPAHLS/skillware/blob/main/examples/README.md"
611
+ )
612
+
613
+
614
+ def test_load_examples_index_github_failure(monkeypatch):
615
+ monkeypatch.setattr("skillware.cli._examples_readme_path", lambda: None)
616
+
617
+ def raise_error(url, timeout):
618
+ raise OSError("offline")
619
+
620
+ monkeypatch.setattr("skillware.cli.requests.get", raise_error)
621
+
622
+ rows, source = _load_examples_index()
623
+ assert rows == []
624
+ assert source is None
625
+
626
+
586
627
  def test_main_examples_subcommand_exits_with_cmd_examples_code(monkeypatch):
587
628
  import sys
588
629
  from skillware.cli import main
@@ -1,61 +0,0 @@
1
- # Skillware Examples Index
2
-
3
- > **These are usage examples, not tests.** Runnable provider demos live here; automated tests live in `skills/**/test_skill.py` (bundle) and `tests/` (framework and optional maintainer depth). See [TESTING.md](../docs/TESTING.md).
4
-
5
- Runnable examples in this directory show how to load Skillware skills, adapt
6
- them for a provider, execute local skill logic, and return tool results to an
7
- agent loop. From the repository root, run `skillware examples` or
8
- `skillware list --examples` to browse the index in the terminal (see
9
- [CLI reference](../docs/usage/cli.md)). Provider setup details live in the usage guides:
10
-
11
- - [API keys for skills](../docs/usage/api_keys.md)
12
- - [Gemini](../docs/usage/gemini.md)
13
- - [Claude](../docs/usage/claude.md)
14
- - [OpenAI](../docs/usage/openai.md)
15
- - [DeepSeek](../docs/usage/deepseek.md)
16
- - [Ollama](../docs/usage/ollama.md)
17
- - [Agent loops](../docs/usage/agent_loops.md)
18
-
19
- Use the package extra shown below when installing from PyPI:
20
- `pip install "skillware[gemini]"`. For local development, use the same extra
21
- with editable install: `pip install -e ".[gemini]"`.
22
-
23
- ## Runnable Scripts
24
-
25
- | Script | Skill ID | Provider | Required extra | Required env vars | Description |
26
- | :--- | :--- | :--- | :--- | :--- | :--- |
27
- | `mental_coach_demo.py` | `wellness/mental_coach` | Local execute | base install only | None | Demonstrates coaching, crisis escalation, and blocked clinical paths locally. |
28
- | `build_dataset_demo.py` | `data_engineering/synthetic_generator` | Local execute (Gemini backend) | `[gemini]` | `GOOGLE_API_KEY` | Generates a JSONL synthetic dataset with the synthetic generator skill. |
29
- | `claude_pdf_form_filler.py` | `office/pdf_form_filler` | Claude | `[claude]`, `[office]` | `ANTHROPIC_API_KEY` | Uses Claude with the PDF form filler skill to map instructions to fields. |
30
- | `claude_tos_evaluator.py` | `compliance/tos_evaluator` | Claude | `[claude]` | `ANTHROPIC_API_KEY` | Runs a Claude tool loop for website automation policy review. |
31
- | `claude_issue_resolver.py` | `dev_tools/issue_resolver` | Claude | `[claude]` | `ANTHROPIC_API_KEY`; optional `GITHUB_TOKEN` | Claude loop for GitHub issue analysis; fetches issue data after `prepare` (sample: issue #123). |
32
- | `claude_wallet_check.py` | `finance/wallet_screening` | Claude | `[claude]` | `ANTHROPIC_API_KEY`, `ETHERSCAN_API_KEY` | Screens an Ethereum wallet and returns the result through a Claude tool loop. |
33
- | `deepseek_tos_evaluator.py` | `compliance/tos_evaluator` | DeepSeek | `[openai]` | `DEEPSEEK_API_KEY` | Uses the OpenAI-compatible DeepSeek API for terms-of-service evaluation. |
34
- | `gemini_pdf_form_filler.py` | `office/pdf_form_filler` | Gemini | `[gemini]`, `[office]` | `GOOGLE_API_KEY`, `ANTHROPIC_API_KEY` | Uses Gemini as the agent while the PDF skill calls Anthropic for form filling. |
35
- | `gemini_tos_evaluator.py` | `compliance/tos_evaluator` | Gemini | `[gemini]` | `GOOGLE_API_KEY` | Runs the terms-of-service evaluator with a Gemini function-calling loop. |
36
- | `gemini_wallet_check.py` | `finance/wallet_screening` | Gemini | `[gemini]` | `GOOGLE_API_KEY`, `ETHERSCAN_API_KEY` | Screens an Ethereum wallet with Gemini orchestration and Etherscan data. |
37
- | `gemini_evm_tx_handler.py` | `defi/evm_tx_handler` | Gemini | `[gemini]` | `GOOGLE_API_KEY`; for live swaps also `AGENT_WALLET_PRIVATE_KEY`, `BASE_RPC_URL` or `ETHEREUM_RPC_URL`. Set `EVM_TX_HANDLER_EXAMPLE_DEMO=1` for mocked flow without keys. | Resolve → quote → preview → execute buy flow via Gemini tool loop (or demo mode). |
38
- | `claude_evm_tx_handler.py` | `defi/evm_tx_handler` | Claude | `[claude]` | `ANTHROPIC_API_KEY`; for live swaps also `AGENT_WALLET_PRIVATE_KEY`, RPC URLs. Demo: `EVM_TX_HANDLER_EXAMPLE_DEMO=1`. | Claude tool loop for structured DeFi intent and optional execute after confirmation. |
39
- | `mica_claude_flow.py` | `compliance/mica_module` | Claude | `[claude]` | `ANTHROPIC_API_KEY` | Runs a MiCA compliance agent loop through Claude. |
40
- | `mica_ollama_flow.py` | `compliance/mica_module` | Ollama | No Skillware extra; install `ollama` separately | None | Runs a local Ollama MiCA flow with prompt-mode tool calling. |
41
- | `mica_rag_flow.py` | `compliance/mica_module` | Gemini | `[gemini]` | `GOOGLE_API_KEY` | Runs the MiCA RAG flow with Gemini. |
42
- | `ollama_skills_test.py` | `finance/wallet_screening`, `office/pdf_form_filler`, `optimization/prompt_rewriter` | Ollama | `[office]`; install `ollama` separately | `ETHERSCAN_API_KEY`, `ANTHROPIC_API_KEY` | Loads multiple skills and tests prompt-mode tool calling with Ollama. |
43
- | `ollama_tos_evaluator.py` | `compliance/tos_evaluator` | Ollama | No Skillware extra; install `ollama` separately | None | Runs the terms-of-service evaluator with local Ollama prompt-mode calls. |
44
- | `openai_tos_evaluator.py` | `compliance/tos_evaluator` | OpenAI | `[openai]` | `OPENAI_API_KEY` | Runs the terms-of-service evaluator with OpenAI function calling. |
45
- | `pii_guardrail_flow.py` | `compliance/pii_masker` | Local execute | base install only | None | Demonstrates local PII masking before passing text to an external agent. |
46
- | `prompt_compression_demo.py` | `optimization/prompt_rewriter` | Local execute | base install only | None | Demonstrates prompt compression without a provider loop. |
47
- | `novelty_extractor_demo.py` | `data_engineering/novelty_extractor` | Local execute | `pip install fastembed numpy` | None | Demonstrates multi-turn corpus distillation using local embeddings with no API key. |
48
- | `gemini_novelty_extractor.py` | `data_engineering/novelty_extractor` | Gemini | `[gemini]`, `pip install fastembed numpy` | `GOOGLE_API_KEY` | Runs the novelty extractor with a Gemini function-calling loop. |
49
- | `ollama_novelty_extractor.py` | `data_engineering/novelty_extractor` | Ollama | `pip install fastembed numpy`; install `ollama` separately | None | Runs the novelty extractor with local Ollama prompt-mode calls. |
50
- | `gemini_issue_resolver.py` | `dev_tools/issue_resolver` | Gemini | `[gemini]` | `GOOGLE_API_KEY`; optional `GITHUB_TOKEN` | Gemini loop for GitHub issue analysis; fetches issue data after `prepare` (sample: issue #123). |
51
- | `ollama_issue_resolver.py` | `dev_tools/issue_resolver` | Ollama | No Skillware extra; install `ollama` separately | optional `GITHUB_TOKEN`; `OLLAMA_MODEL` (default `gemma4:e2b`) | Ollama prompt-mode loop for GitHub issue analysis (sample: issue #123). |
52
-
53
- ## Notes
54
-
55
- - Agent-side model keys such as `GOOGLE_API_KEY`, `ANTHROPIC_API_KEY`,
56
- `OPENAI_API_KEY`, and `DEEPSEEK_API_KEY` are documented in the provider
57
- guides.
58
- - Skill runtime keys such as `ETHERSCAN_API_KEY` are documented in each skill
59
- manifest and on the skill catalog pages.
60
- - Ollama examples require the Python `ollama` package, a local Ollama server,
61
- and the model named in the script, but no cloud API key.
File without changes
File without changes
File without changes
File without changes