dotmd-parser 0.6.2__tar.gz → 0.7.0__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 (40) hide show
  1. {dotmd_parser-0.6.2/src/dotmd_parser.egg-info → dotmd_parser-0.7.0}/PKG-INFO +1 -1
  2. {dotmd_parser-0.6.2 → dotmd_parser-0.7.0}/pyproject.toml +1 -1
  3. {dotmd_parser-0.6.2 → dotmd_parser-0.7.0}/src/dotmd_parser/__init__.py +1 -1
  4. {dotmd_parser-0.6.2 → dotmd_parser-0.7.0}/src/dotmd_parser/parser.py +11 -3
  5. {dotmd_parser-0.6.2 → dotmd_parser-0.7.0/src/dotmd_parser.egg-info}/PKG-INFO +1 -1
  6. {dotmd_parser-0.6.2 → dotmd_parser-0.7.0}/src/dotmd_parser.egg-info/SOURCES.txt +1 -0
  7. dotmd_parser-0.7.0/tests/test_orchestrator_detection.py +72 -0
  8. {dotmd_parser-0.6.2 → dotmd_parser-0.7.0}/tests/test_skill_integration.py +1 -1
  9. {dotmd_parser-0.6.2 → dotmd_parser-0.7.0}/LICENSE +0 -0
  10. {dotmd_parser-0.6.2 → dotmd_parser-0.7.0}/README.md +0 -0
  11. {dotmd_parser-0.6.2 → dotmd_parser-0.7.0}/setup.cfg +0 -0
  12. {dotmd_parser-0.6.2 → dotmd_parser-0.7.0}/src/dotmd_parser/analyze.py +0 -0
  13. {dotmd_parser-0.6.2 → dotmd_parser-0.7.0}/src/dotmd_parser/cli.py +0 -0
  14. {dotmd_parser-0.6.2 → dotmd_parser-0.7.0}/src/dotmd_parser/digest.py +0 -0
  15. {dotmd_parser-0.6.2 → dotmd_parser-0.7.0}/src/dotmd_parser/index.py +0 -0
  16. {dotmd_parser-0.6.2 → dotmd_parser-0.7.0}/src/dotmd_parser/index_md.py +0 -0
  17. {dotmd_parser-0.6.2 → dotmd_parser-0.7.0}/src/dotmd_parser/inventory.py +0 -0
  18. {dotmd_parser-0.6.2 → dotmd_parser-0.7.0}/src/dotmd_parser/openrag.py +0 -0
  19. {dotmd_parser-0.6.2 → dotmd_parser-0.7.0}/src/dotmd_parser/templates/SKILL.md +0 -0
  20. {dotmd_parser-0.6.2 → dotmd_parser-0.7.0}/src/dotmd_parser/templates/__init__.py +0 -0
  21. {dotmd_parser-0.6.2 → dotmd_parser-0.7.0}/src/dotmd_parser/templates/dotmd_index/SKILL.md +0 -0
  22. {dotmd_parser-0.6.2 → dotmd_parser-0.7.0}/src/dotmd_parser/templates/dotmd_index/__init__.py +0 -0
  23. {dotmd_parser-0.6.2 → dotmd_parser-0.7.0}/src/dotmd_parser/templates/prompts/__init__.py +0 -0
  24. {dotmd_parser-0.6.2 → dotmd_parser-0.7.0}/src/dotmd_parser/templates/prompts/analyze-dependencies.md +0 -0
  25. {dotmd_parser-0.6.2 → dotmd_parser-0.7.0}/src/dotmd_parser.egg-info/dependency_links.txt +0 -0
  26. {dotmd_parser-0.6.2 → dotmd_parser-0.7.0}/src/dotmd_parser.egg-info/entry_points.txt +0 -0
  27. {dotmd_parser-0.6.2 → dotmd_parser-0.7.0}/src/dotmd_parser.egg-info/requires.txt +0 -0
  28. {dotmd_parser-0.6.2 → dotmd_parser-0.7.0}/src/dotmd_parser.egg-info/top_level.txt +0 -0
  29. {dotmd_parser-0.6.2 → dotmd_parser-0.7.0}/tests/test_aggregate.py +0 -0
  30. {dotmd_parser-0.6.2 → dotmd_parser-0.7.0}/tests/test_analyze.py +0 -0
  31. {dotmd_parser-0.6.2 → dotmd_parser-0.7.0}/tests/test_cli_dotmd_index.py +0 -0
  32. {dotmd_parser-0.6.2 → dotmd_parser-0.7.0}/tests/test_cost_estimate.py +0 -0
  33. {dotmd_parser-0.6.2 → dotmd_parser-0.7.0}/tests/test_empty_warnings.py +0 -0
  34. {dotmd_parser-0.6.2 → dotmd_parser-0.7.0}/tests/test_host_agent_plan.py +0 -0
  35. {dotmd_parser-0.6.2 → dotmd_parser-0.7.0}/tests/test_index_md.py +0 -0
  36. {dotmd_parser-0.6.2 → dotmd_parser-0.7.0}/tests/test_index_scope.py +0 -0
  37. {dotmd_parser-0.6.2 → dotmd_parser-0.7.0}/tests/test_inventory.py +0 -0
  38. {dotmd_parser-0.6.2 → dotmd_parser-0.7.0}/tests/test_openrag_push.py +0 -0
  39. {dotmd_parser-0.6.2 → dotmd_parser-0.7.0}/tests/test_parser.py +0 -0
  40. {dotmd_parser-0.6.2 → dotmd_parser-0.7.0}/tests/test_token_savings.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dotmd-parser
3
- Version: 0.6.2
3
+ Version: 0.7.0
4
4
  Summary: Dependency graph parser, single-file folder index (dotmd-index.md), and AI analyzer for .md skill files — parse @include/@delegate/@ref directives, build graphs, resolve templates, generate RAG-friendly overviews, and ingest into OpenRAG
5
5
  Author: dotmd-projects
6
6
  License-Expression: MIT
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "dotmd-parser"
3
- version = "0.6.2"
3
+ version = "0.7.0"
4
4
  description = "Dependency graph parser, single-file folder index (dotmd-index.md), and AI analyzer for .md skill files — parse @include/@delegate/@ref directives, build graphs, resolve templates, generate RAG-friendly overviews, and ingest into OpenRAG"
5
5
  requires-python = ">=3.10"
6
6
  license = "MIT"
@@ -10,7 +10,7 @@ API:
10
10
  from dotmd_parser import digest, tree, affects
11
11
  """
12
12
 
13
- __version__ = "0.6.2"
13
+ __version__ = "0.7.0"
14
14
 
15
15
  from dotmd_parser.parser import (
16
16
  build_graph,
@@ -244,14 +244,22 @@ def build_graph(root_path: str, type_map: list[tuple[str, str]] | None = None) -
244
244
  if root.is_dir():
245
245
  candidate = root / "SKILL.md"
246
246
  if not candidate.exists():
247
- # Case-insensitive search
247
+ # Case-insensitive search at root
248
248
  candidates = list(root.glob("*.md"))
249
249
  skill_files = [f for f in candidates if f.name.upper() == "SKILL.MD"]
250
250
  if skill_files:
251
251
  candidate = skill_files[0]
252
252
  else:
253
- has_skill_md = False
254
- candidate = None
253
+ # Sprint 13 Phase 36: Claude Code plugin convention fallback
254
+ # .claude/skills/<name>/skill.md パターンを検出
255
+ plugin_skills = list(root.glob(".claude/skills/*/skill.md"))
256
+ if plugin_skills:
257
+ # 最初の plugin skill を採用 (複数ある場合は名前順)
258
+ plugin_skills.sort()
259
+ candidate = plugin_skills[0]
260
+ else:
261
+ has_skill_md = False
262
+ candidate = None
255
263
 
256
264
  if candidate:
257
265
  root = candidate
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dotmd-parser
3
- Version: 0.6.2
3
+ Version: 0.7.0
4
4
  Summary: Dependency graph parser, single-file folder index (dotmd-index.md), and AI analyzer for .md skill files — parse @include/@delegate/@ref directives, build graphs, resolve templates, generate RAG-friendly overviews, and ingest into OpenRAG
5
5
  Author: dotmd-projects
6
6
  License-Expression: MIT
@@ -32,6 +32,7 @@ tests/test_index_md.py
32
32
  tests/test_index_scope.py
33
33
  tests/test_inventory.py
34
34
  tests/test_openrag_push.py
35
+ tests/test_orchestrator_detection.py
35
36
  tests/test_parser.py
36
37
  tests/test_skill_integration.py
37
38
  tests/test_token_savings.py
@@ -0,0 +1,72 @@
1
+ """Sprint 13 Phase 36: orchestrator のマルチシグナル検出テスト.
2
+
3
+ dotmd-parser の build_graph が以下 3 パターンの orchestrator を検出できることを確認:
4
+ - root SKILL.md (大文字、既存)
5
+ - subdirectory SKILL.md (claude-ads, TradingAgents)
6
+ - .claude/skills/<name>/skill.md (Claude Code plugin convention, freee-ads-skills)
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ from pathlib import Path
12
+
13
+ import pytest
14
+
15
+ from dotmd_parser.parser import build_graph
16
+
17
+
18
+ @pytest.fixture
19
+ def temp_repo(tmp_path: Path) -> Path:
20
+ """テスト用の最小リポジトリ構造を作る."""
21
+ (tmp_path / "references").mkdir()
22
+ (tmp_path / "references" / "target.md").write_text("# target")
23
+ return tmp_path
24
+
25
+
26
+ class TestOrchestratorDetection:
27
+ def test_detects_claude_code_plugin_skill(self, temp_repo: Path) -> None:
28
+ """`.claude/skills/<name>/skill.md` が directory 引数で auto-detect される."""
29
+ plugin_dir = temp_repo / ".claude" / "skills" / "ads"
30
+ plugin_dir.mkdir(parents=True)
31
+ skill_file = plugin_dir / "skill.md"
32
+ skill_file.write_text(
33
+ "# orchestrator\n\n@delegate ../../../references/target.md\n"
34
+ )
35
+
36
+ graph = build_graph(str(temp_repo))
37
+
38
+ node_ids = [n["id"] for n in graph["nodes"]]
39
+ assert any("skill.md" in nid for nid in node_ids), (
40
+ f"plugin skill.md not detected. nodes={node_ids}"
41
+ )
42
+ assert any("target.md" in nid for nid in node_ids), (
43
+ f"@delegate target not resolved. nodes={node_ids}"
44
+ )
45
+
46
+ def test_root_skill_md_still_works(self, temp_repo: Path) -> None:
47
+ """既存の root SKILL.md (大文字) 検出が回帰していない."""
48
+ (temp_repo / "SKILL.md").write_text(
49
+ "# top\n\n@delegate references/target.md\n"
50
+ )
51
+
52
+ graph = build_graph(str(temp_repo))
53
+ node_ids = [n["id"] for n in graph["nodes"]]
54
+ assert any("SKILL.md" in nid for nid in node_ids)
55
+ assert any("target.md" in nid for nid in node_ids)
56
+
57
+ def test_root_skill_md_preferred_over_plugin(self, temp_repo: Path) -> None:
58
+ """root SKILL.md が存在する場合は plugin より優先される (後方互換)."""
59
+ (temp_repo / "SKILL.md").write_text("# root\n")
60
+ plugin_dir = temp_repo / ".claude" / "skills" / "ads"
61
+ plugin_dir.mkdir(parents=True)
62
+ (plugin_dir / "skill.md").write_text("# plugin\n")
63
+
64
+ graph = build_graph(str(temp_repo))
65
+ node_ids = [n["id"] for n in graph["nodes"]]
66
+ assert any(nid.endswith("/SKILL.md") or nid.endswith("SKILL.md") for nid in node_ids)
67
+
68
+ def test_no_skill_anywhere_returns_warning(self, temp_repo: Path) -> None:
69
+ """SKILL.md も plugin skill.md もない場合は既存 warning を返す."""
70
+ graph = build_graph(str(temp_repo))
71
+ warnings = graph.get("warnings", [])
72
+ assert any(w.get("type") == "missing" for w in warnings)
@@ -308,7 +308,7 @@ class TestBundledTemplate(unittest.TestCase):
308
308
 
309
309
  class TestVersion(unittest.TestCase):
310
310
  def test_version_bump(self):
311
- self.assertEqual(__version__, "0.6.2")
311
+ self.assertEqual(__version__, "0.7.0")
312
312
 
313
313
 
314
314
  if __name__ == "__main__":
File without changes
File without changes
File without changes