maestro-skills 0.1.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 (56) hide show
  1. package/.github/workflows/ci.yml +26 -0
  2. package/.github/workflows/publish-npm.yml +30 -0
  3. package/CONTRIBUTING.md +31 -0
  4. package/LICENSE +21 -0
  5. package/README.md +300 -0
  6. package/SECURITY.md +33 -0
  7. package/docs/github-workflow.md +96 -0
  8. package/docs/maestro-skills-cli.md +113 -0
  9. package/package.json +35 -0
  10. package/packages/maestro-skills/README.md +37 -0
  11. package/packages/maestro-skills/agents.json +36 -0
  12. package/packages/maestro-skills/bin/cli.js +37 -0
  13. package/packages/maestro-skills/lib/detect-agents.js +28 -0
  14. package/packages/maestro-skills/lib/install.js +58 -0
  15. package/packages/maestro-skills/lib/paths.js +42 -0
  16. package/packages/maestro-skills/lib/remove.js +71 -0
  17. package/packages/maestro-skills/lib/run-manifest.js +92 -0
  18. package/packages/maestro-skills/lib/setup.js +115 -0
  19. package/packages/maestro-skills/package.json +47 -0
  20. package/packages/maestro-skills/test/agents.test.js +17 -0
  21. package/packages/rodovalhofs-maestro/agents.json +36 -0
  22. package/packages/rodovalhofs-maestro/bin/cli.js +10 -0
  23. package/packages/rodovalhofs-maestro/lib/detect-agents.js +28 -0
  24. package/packages/rodovalhofs-maestro/lib/install.js +58 -0
  25. package/packages/rodovalhofs-maestro/lib/paths.js +42 -0
  26. package/packages/rodovalhofs-maestro/lib/remove.js +71 -0
  27. package/packages/rodovalhofs-maestro/lib/run-manifest.js +92 -0
  28. package/packages/rodovalhofs-maestro/lib/setup.js +115 -0
  29. package/packages/rodovalhofs-maestro/package.json +33 -0
  30. package/scripts/sync-skill-to-cli.mjs +75 -0
  31. package/scripts/sync-templates.ps1 +22 -0
  32. package/skills/maestro/SKILL.md +272 -0
  33. package/skills/maestro/maestro-exclude.example.txt +6 -0
  34. package/skills/maestro/scripts/bm25.py +70 -0
  35. package/skills/maestro/scripts/build_manifest.py +183 -0
  36. package/skills/maestro/scripts/concept_gaps.py +196 -0
  37. package/skills/maestro/scripts/domains.py +148 -0
  38. package/skills/maestro/scripts/intents.py +167 -0
  39. package/skills/maestro/scripts/maestro_paths.py +41 -0
  40. package/skills/maestro/scripts/route_tasks.py +101 -0
  41. package/skills/maestro/scripts/routing.py +106 -0
  42. package/skills/maestro/scripts/search_skills.py +287 -0
  43. package/skills/maestro/scripts/synonyms.py +47 -0
  44. package/templates/.github/ISSUE_TEMPLATE/bug_report.yml +34 -0
  45. package/templates/.github/ISSUE_TEMPLATE/chore.yml +17 -0
  46. package/templates/.github/ISSUE_TEMPLATE/config.yml +1 -0
  47. package/templates/.github/ISSUE_TEMPLATE/feature_request.yml +27 -0
  48. package/templates/.github/workflows/ci-failure-to-issue.yml +47 -0
  49. package/templates/.github/workflows/ci.yml +27 -0
  50. package/templates/CONTRIBUTING.md +22 -0
  51. package/templates/labels.json +12 -0
  52. package/templates/pull_request_template.md +18 -0
  53. package/tests/fixtures/sample-manifest.json +76 -0
  54. package/tests/test_concept_gaps.py +63 -0
  55. package/tests/test_maestro_paths.py +29 -0
  56. package/tests/test_search_routing.py +161 -0
@@ -0,0 +1,76 @@
1
+ {
2
+ "version": 2,
3
+ "skill_count": 7,
4
+ "skills": [
5
+ {
6
+ "name": "superdesign",
7
+ "folder": "superdesign",
8
+ "description": "Frontend UI/UX design agent for superdesign canvas drafts",
9
+ "tags": ["design", "ui", "ux"],
10
+ "domain": "design",
11
+ "path": "/tmp/skills/superdesign/SKILL.md",
12
+ "scope": "agents",
13
+ "installed": true
14
+ },
15
+ {
16
+ "name": "systematic-debugging",
17
+ "folder": "systematic-debugging",
18
+ "description": "Structured root cause debugging for failing tests",
19
+ "tags": ["debug", "troubleshooting"],
20
+ "domain": "web",
21
+ "path": "/tmp/skills/systematic-debugging/SKILL.md",
22
+ "scope": "personal",
23
+ "installed": true
24
+ },
25
+ {
26
+ "name": "gh-fix-ci",
27
+ "folder": "gh-fix-ci",
28
+ "description": "Fix failing GitHub Actions CI checks on pull requests",
29
+ "tags": ["github", "ci"],
30
+ "domain": "devops-git",
31
+ "path": "/tmp/skills/gh-fix-ci/SKILL.md",
32
+ "scope": "personal",
33
+ "installed": true
34
+ },
35
+ {
36
+ "name": "performing-memory-forensics-with-volatility3",
37
+ "folder": "performing-memory-forensics-with-volatility3",
38
+ "description": "Analyze memory dumps with Volatility 3 for credential theft",
39
+ "tags": ["forensics", "volatility", "memory-forensics"],
40
+ "domain": "security",
41
+ "path": "/tmp/skills/performing-memory-forensics-with-volatility3/SKILL.md",
42
+ "scope": "agents",
43
+ "installed": true
44
+ },
45
+ {
46
+ "name": "react-best-practices",
47
+ "folder": "react-best-practices",
48
+ "description": "React component patterns and performance",
49
+ "tags": ["react", "frontend"],
50
+ "domain": "web",
51
+ "path": "/tmp/skills/react-best-practices/SKILL.md",
52
+ "scope": "personal",
53
+ "installed": true
54
+ },
55
+ {
56
+ "name": "find-skills",
57
+ "folder": "find-skills",
58
+ "description": "Discover and install agent skills from the open skills ecosystem via npx skills",
59
+ "tags": ["skills", "discover", "install"],
60
+ "domain": "meta",
61
+ "path": "/tmp/skills/find-skills/SKILL.md",
62
+ "scope": "agents",
63
+ "installed": true
64
+ },
65
+ {
66
+ "name": "maestro",
67
+ "folder": "maestro",
68
+ "description": "Meta orchestrator",
69
+ "tags": ["meta"],
70
+ "domain": "meta",
71
+ "path": "/tmp/skills/maestro/SKILL.md",
72
+ "scope": "personal",
73
+ "installed": true
74
+ }
75
+ ]
76
+ }
@@ -0,0 +1,63 @@
1
+ """Unit tests for concept gap detection."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import sys
6
+ import unittest
7
+ from pathlib import Path
8
+
9
+ SCRIPTS = Path(__file__).resolve().parents[1] / "skills" / "maestro" / "scripts"
10
+ sys.path.insert(0, str(SCRIPTS))
11
+
12
+ from concept_gaps import ( # noqa: E402
13
+ MAX_DISCOVER_GAPS,
14
+ build_discover_queries,
15
+ extract_concept_candidates,
16
+ find_concept_gaps,
17
+ )
18
+ from search_skills import skill_document # noqa: E402
19
+ from synonyms import expand_query # noqa: E402
20
+
21
+
22
+ class TestConceptGapLimits(unittest.TestCase):
23
+ def test_max_two_gaps_with_notes(self) -> None:
24
+ query = (
25
+ "colocar skeleton-loader e react-query e tanstack-table na ui"
26
+ )
27
+ candidates = extract_concept_candidates(query)
28
+ self.assertGreater(len(candidates), MAX_DISCOVER_GAPS)
29
+
30
+ pool = [
31
+ {
32
+ "name": "react-best-practices",
33
+ "folder": "react-best-practices",
34
+ "description": "React patterns",
35
+ "tags": ["react"],
36
+ "domain": "web",
37
+ }
38
+ ]
39
+ results = [
40
+ {
41
+ "name": "react-best-practices",
42
+ "description": "React patterns",
43
+ "tags": ["react"],
44
+ }
45
+ ]
46
+ gaps, notes = find_concept_gaps(
47
+ query, results, pool, skill_document, expand_query
48
+ )
49
+ self.assertLessEqual(len(gaps), MAX_DISCOVER_GAPS)
50
+ self.assertTrue(notes)
51
+
52
+ def test_build_discover_queries_includes_gap(self) -> None:
53
+ queries = build_discover_queries(
54
+ ["skeleton-loader"],
55
+ "vamos colocar skeleton-loader na ui",
56
+ "web",
57
+ )
58
+ self.assertEqual(len(queries), 1)
59
+ self.assertIn("skeleton-loader", queries[0])
60
+
61
+
62
+ if __name__ == "__main__":
63
+ unittest.main()
@@ -0,0 +1,29 @@
1
+ """Tests for multi-agent skill roots."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import sys
6
+ import unittest
7
+ from pathlib import Path
8
+
9
+ SCRIPTS = Path(__file__).resolve().parents[1] / "skills" / "maestro" / "scripts"
10
+ sys.path.insert(0, str(SCRIPTS))
11
+
12
+ from maestro_paths import GLOBAL_SKILL_ROOTS, project_skill_roots # noqa: E402
13
+
14
+
15
+ class TestMaestroPaths(unittest.TestCase):
16
+ def test_global_roots_include_codex(self) -> None:
17
+ scopes = [scope for _, scope in GLOBAL_SKILL_ROOTS]
18
+ self.assertIn("codex", scopes)
19
+ codex_path = next(path for path, scope in GLOBAL_SKILL_ROOTS if scope == "codex")
20
+ self.assertTrue(str(codex_path).replace("\\", "/").endswith("/.codex/skills"))
21
+
22
+ def test_project_roots_include_codex(self) -> None:
23
+ roots = project_skill_roots(Path("/tmp/project"))
24
+ scopes = [scope for _, scope in roots]
25
+ self.assertIn("project-codex", scopes)
26
+
27
+
28
+ if __name__ == "__main__":
29
+ unittest.main()
@@ -0,0 +1,161 @@
1
+ """Tests for maestro hybrid skill routing."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import json
6
+ import sys
7
+ import unittest
8
+ from pathlib import Path
9
+
10
+ ROOT = Path(__file__).resolve().parents[1]
11
+ SCRIPTS = ROOT / "skills" / "maestro" / "scripts"
12
+ sys.path.insert(0, str(SCRIPTS))
13
+
14
+ from concept_gaps import extract_concept_candidates, find_concept_gaps # noqa: E402
15
+ from intents import is_bypass_task, is_force_discover, task_intents # noqa: E402
16
+ from routing import build_routing, is_high_risk, select_mode # noqa: E402
17
+ from route_tasks import route_batch # noqa: E402
18
+ from search_skills import search_skills, skill_document # noqa: E402
19
+ from synonyms import expand_query # noqa: E402
20
+
21
+ FIXTURE_MANIFEST = Path(__file__).parent / "fixtures" / "sample-manifest.json"
22
+
23
+
24
+ def load_fixture() -> dict:
25
+ return json.loads(FIXTURE_MANIFEST.read_text(encoding="utf-8"))
26
+
27
+
28
+ class TestSynonyms(unittest.TestCase):
29
+ def test_portuguese_debug_expansion(self) -> None:
30
+ expanded = expand_query("depurar teste falhando")
31
+ self.assertIn("debug", expanded)
32
+ self.assertIn("test", expanded)
33
+
34
+
35
+ class TestIntents(unittest.TestCase):
36
+ def test_debug_intent_detected(self) -> None:
37
+ intents = task_intents("inspect failing test and find root cause")
38
+ names = [i["name"] for i in intents]
39
+ self.assertIn("root-cause-debugging", names)
40
+
41
+ def test_bypass_greeting(self) -> None:
42
+ self.assertTrue(is_bypass_task("oi"))
43
+
44
+ def test_force_discover_intent(self) -> None:
45
+ self.assertTrue(is_force_discover("find a skill for changelog"))
46
+ self.assertTrue(is_force_discover("tem skill para deploy"))
47
+ self.assertFalse(is_force_discover("corrigir CI no PR"))
48
+
49
+ def test_skill_discovery_intent_profile(self) -> None:
50
+ intents = task_intents("npx skills find react")
51
+ names = [i["name"] for i in intents]
52
+ self.assertIn("skill-discovery", names)
53
+
54
+
55
+ class TestRouting(unittest.TestCase):
56
+ def test_high_risk_forces_recommend(self) -> None:
57
+ self.assertTrue(is_high_risk("deploy to production with token"))
58
+ mode = select_mode(0.9, high_risk=True)
59
+ self.assertEqual(mode, "recommend")
60
+
61
+ def test_p1_auto_load(self) -> None:
62
+ matches = [{"confidence": 0.4, "mode": "auto-load"}]
63
+ routing = build_routing("design dashboard ui", matches, high_risk=False)
64
+ self.assertEqual(routing["priority"], "P1")
65
+ self.assertEqual(routing["decision"], "auto-load")
66
+
67
+
68
+ class TestConceptGaps(unittest.TestCase):
69
+ def test_extract_skeleton_loader(self) -> None:
70
+ query = "vamos fazer uma alteração na ui e vamos colocar skeleton-loader"
71
+ candidates = extract_concept_candidates(query)
72
+ self.assertIn("skeleton-loader", candidates)
73
+
74
+ def test_ui_is_stopword(self) -> None:
75
+ query = "melhorar a ui do app"
76
+ candidates = extract_concept_candidates(query)
77
+ self.assertNotIn("ui", candidates)
78
+
79
+
80
+ class TestSearchSkills(unittest.TestCase):
81
+ def setUp(self) -> None:
82
+ self.manifest = load_fixture()
83
+
84
+ def test_superdesign_ranks_for_design_query(self) -> None:
85
+ result = search_skills(
86
+ "design landing page UI with superdesign",
87
+ self.manifest,
88
+ domain="design",
89
+ )
90
+ self.assertTrue(result["results"])
91
+ self.assertEqual(result["results"][0]["name"], "superdesign")
92
+ self.assertIn("routing", result)
93
+ self.assertIn(result["routing"]["priority"], {"P1", "P2"})
94
+
95
+ def test_forensics_intent_boost(self) -> None:
96
+ result = search_skills(
97
+ "memory forensics credential dumping volatility",
98
+ self.manifest,
99
+ domain="security",
100
+ )
101
+ self.assertTrue(result["results"])
102
+ self.assertEqual(
103
+ result["results"][0]["name"],
104
+ "performing-memory-forensics-with-volatility3",
105
+ )
106
+
107
+ def test_concept_gap_triggers_discover(self) -> None:
108
+ result = search_skills(
109
+ "vamos fazer uma alteração na ui e vamos colocar skeleton-loader",
110
+ self.manifest,
111
+ domain="web",
112
+ )
113
+ discover = result["discover"]
114
+ self.assertTrue(discover["triggered"])
115
+ self.assertIn("concept_gap", discover["reasons"])
116
+ self.assertIn("skeleton-loader", discover["gaps"])
117
+ self.assertTrue(discover["queries"])
118
+ self.assertFalse(result.get("missing_skills"))
119
+
120
+ def test_force_discover_triggers_even_with_strong_local(self) -> None:
121
+ result = search_skills(
122
+ "find a skill for react performance",
123
+ self.manifest,
124
+ domain="web",
125
+ )
126
+ discover = result["discover"]
127
+ self.assertTrue(discover["triggered"])
128
+ self.assertTrue(discover["force_discover"])
129
+ self.assertIn("force_discover", discover["reasons"])
130
+
131
+ def test_ci_query_no_discover(self) -> None:
132
+ result = search_skills(
133
+ "corrigir CI quebrado no pull request",
134
+ self.manifest,
135
+ domain="devops-git",
136
+ )
137
+ self.assertEqual(result["results"][0]["name"], "gh-fix-ci")
138
+ self.assertFalse(result["discover"]["triggered"])
139
+
140
+ def test_bypass_routing(self) -> None:
141
+ result = search_skills("oi", self.manifest)
142
+ self.assertEqual(result["routing"]["priority"], "P3")
143
+ self.assertEqual(result["routing"]["decision"], "bypass")
144
+ self.assertFalse(result["discover"]["triggered"])
145
+
146
+
147
+ class TestRouteBatch(unittest.TestCase):
148
+ def test_batch_returns_per_task_results(self) -> None:
149
+ payload = route_batch(
150
+ ["design dashboard ui", "fix failing CI on PR"],
151
+ FIXTURE_MANIFEST,
152
+ )
153
+ self.assertTrue(payload["batch"])
154
+ self.assertEqual(payload["task_count"], 2)
155
+ self.assertEqual(len(payload["results"]), 2)
156
+ self.assertIn("routing", payload)
157
+ self.assertIn("discover", payload)
158
+
159
+
160
+ if __name__ == "__main__":
161
+ unittest.main()