normattiva2md 2.0.19__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 (127) hide show
  1. normattiva2md-2.0.19/.claude/CLAUDE.md +129 -0
  2. normattiva2md-2.0.19/.claude/commands/openspec/apply.md +23 -0
  3. normattiva2md-2.0.19/.claude/commands/openspec/archive.md +27 -0
  4. normattiva2md-2.0.19/.claude/commands/openspec/proposal.md +27 -0
  5. normattiva2md-2.0.19/.gemini/GEMINI.md +57 -0
  6. normattiva2md-2.0.19/.gitattributes +7 -0
  7. normattiva2md-2.0.19/.github/prompts/openspec-apply.prompt.md +22 -0
  8. normattiva2md-2.0.19/.github/prompts/openspec-archive.prompt.md +26 -0
  9. normattiva2md-2.0.19/.github/prompts/openspec-proposal.prompt.md +26 -0
  10. normattiva2md-2.0.19/.github/workflows/jekyll.yml +56 -0
  11. normattiva2md-2.0.19/.github/workflows/release-binaries.yml +146 -0
  12. normattiva2md-2.0.19/.gitignore +68 -0
  13. normattiva2md-2.0.19/.opencode/command/openspec-apply.md +21 -0
  14. normattiva2md-2.0.19/.opencode/command/openspec-archive.md +28 -0
  15. normattiva2md-2.0.19/.opencode/command/openspec-proposal.md +29 -0
  16. normattiva2md-2.0.19/AGENTS.md +43 -0
  17. normattiva2md-2.0.19/CLAUDE.md +19 -0
  18. normattiva2md-2.0.19/LICENSE +21 -0
  19. normattiva2md-2.0.19/LOG.md +1063 -0
  20. normattiva2md-2.0.19/Makefile +128 -0
  21. normattiva2md-2.0.19/PKG-INFO +467 -0
  22. normattiva2md-2.0.19/README.md +431 -0
  23. normattiva2md-2.0.19/ROADMAP.md +788 -0
  24. normattiva2md-2.0.19/SECURITY.md +104 -0
  25. normattiva2md-2.0.19/VERIFICATION.md +57 -0
  26. normattiva2md-2.0.19/docs/COMPATIBILITY_ROADMAP.md +78 -0
  27. normattiva2md-2.0.19/docs/EURLEX_CONVERSION_ANALYSIS.md +239 -0
  28. normattiva2md-2.0.19/docs/EUROLEX/EUR-LEX_INTEGRATION.md +99 -0
  29. normattiva2md-2.0.19/docs/EUROLEX/EURLEX_API.md +266 -0
  30. normattiva2md-2.0.19/docs/EUROLEX/EURLEX_EXPLORATION_SUMMARY.md +161 -0
  31. normattiva2md-2.0.19/docs/Gemfile +9 -0
  32. normattiva2md-2.0.19/docs/NORMATTIVA_API.md +159 -0
  33. normattiva2md-2.0.19/docs/PRD.md +80 -0
  34. normattiva2md-2.0.19/docs/README.md +94 -0
  35. normattiva2md-2.0.19/docs/URL_NORMATTIVA.md +254 -0
  36. normattiva2md-2.0.19/docs/_config.yml +19 -0
  37. normattiva2md-2.0.19/docs/_layouts/default.html +273 -0
  38. normattiva2md-2.0.19/docs/analisi_legge_53_2022.html +1225 -0
  39. normattiva2md-2.0.19/docs/assets/README.md +56 -0
  40. normattiva2md-2.0.19/docs/assets/og-image-generator.html +235 -0
  41. normattiva2md-2.0.19/docs/assets/og-image.png +0 -0
  42. normattiva2md-2.0.19/docs/atti-correlati-analisi.md +271 -0
  43. normattiva2md-2.0.19/docs/index.md +495 -0
  44. normattiva2md-2.0.19/normattiva2md +6 -0
  45. normattiva2md-2.0.19/openspec/AGENTS.md +454 -0
  46. normattiva2md-2.0.19/openspec/changes/add-conversion-validation-monitoring/design.md +190 -0
  47. normattiva2md-2.0.19/openspec/changes/add-conversion-validation-monitoring/proposal.md +35 -0
  48. normattiva2md-2.0.19/openspec/changes/add-conversion-validation-monitoring/specs/conversion-validation/spec.md +85 -0
  49. normattiva2md-2.0.19/openspec/changes/add-conversion-validation-monitoring/tasks.md +105 -0
  50. normattiva2md-2.0.19/openspec/changes/add-entry-into-force-frontmatter/proposal.md +18 -0
  51. normattiva2md-2.0.19/openspec/changes/add-entry-into-force-frontmatter/specs/markdown-conversion/spec.md +42 -0
  52. normattiva2md-2.0.19/openspec/changes/add-entry-into-force-frontmatter/tasks.md +13 -0
  53. normattiva2md-2.0.19/openspec/changes/archive/2025-11-01-add-version-flag/proposal.md +14 -0
  54. normattiva2md-2.0.19/openspec/changes/archive/2025-11-01-add-version-flag/specs/markdown-conversion/spec.md +23 -0
  55. normattiva2md-2.0.19/openspec/changes/archive/2025-11-01-add-version-flag/tasks.md +7 -0
  56. normattiva2md-2.0.19/openspec/changes/archive/2025-11-01-adjust-heading-hierarchy-and-add-frontmatter/design.md +27 -0
  57. normattiva2md-2.0.19/openspec/changes/archive/2025-11-01-adjust-heading-hierarchy-and-add-frontmatter/proposal.md +13 -0
  58. normattiva2md-2.0.19/openspec/changes/archive/2025-11-01-adjust-heading-hierarchy-and-add-frontmatter/specs/markdown-conversion/spec.md +41 -0
  59. normattiva2md-2.0.19/openspec/changes/archive/2025-11-01-adjust-heading-hierarchy-and-add-frontmatter/tasks.md +20 -0
  60. normattiva2md-2.0.19/openspec/changes/archive/2025-11-02-add-natural-language-url-lookup/design.md +28 -0
  61. normattiva2md-2.0.19/openspec/changes/archive/2025-11-02-add-natural-language-url-lookup/proposal.md +14 -0
  62. normattiva2md-2.0.19/openspec/changes/archive/2025-11-02-add-natural-language-url-lookup/specs/url-lookup/spec.md +25 -0
  63. normattiva2md-2.0.19/openspec/changes/archive/2025-11-02-add-natural-language-url-lookup/tasks.md +31 -0
  64. normattiva2md-2.0.19/openspec/changes/archive/2025-11-03-add-atto-intero-url-support/proposal.md +12 -0
  65. normattiva2md-2.0.19/openspec/changes/archive/2025-11-03-add-atto-intero-url-support/specs/markdown-conversion/spec.md +18 -0
  66. normattiva2md-2.0.19/openspec/changes/archive/2025-11-03-add-atto-intero-url-support/tasks.md +20 -0
  67. normattiva2md-2.0.19/openspec/changes/archive/2025-11-03-switch-from-gemini-to-exa/proposal.md +14 -0
  68. normattiva2md-2.0.19/openspec/changes/archive/2025-11-03-switch-from-gemini-to-exa/specs/url-lookup/spec.md +24 -0
  69. normattiva2md-2.0.19/openspec/changes/archive/2025-11-03-switch-from-gemini-to-exa/tasks.md +23 -0
  70. normattiva2md-2.0.19/openspec/changes/archive/2025-11-04-add-article-specific-url-support/proposal.md +13 -0
  71. normattiva2md-2.0.19/openspec/changes/archive/2025-11-04-add-article-specific-url-support/specs/markdown-conversion/spec.md +30 -0
  72. normattiva2md-2.0.19/openspec/changes/archive/2025-11-04-add-article-specific-url-support/tasks.md +23 -0
  73. normattiva2md-2.0.19/openspec/changes/archive/2025-11-04-add-cross-reference-download/proposal.md +17 -0
  74. normattiva2md-2.0.19/openspec/changes/archive/2025-11-04-add-cross-reference-download/specs/markdown-conversion/spec.md +43 -0
  75. normattiva2md-2.0.19/openspec/changes/archive/2025-11-04-add-cross-reference-download/tasks.md +29 -0
  76. normattiva2md-2.0.19/openspec/changes/archive/2025-11-04-add-inline-cross-references/proposal.md +15 -0
  77. normattiva2md-2.0.19/openspec/changes/archive/2025-11-04-add-inline-cross-references/specs/markdown-conversion/spec.md +44 -0
  78. normattiva2md-2.0.19/openspec/changes/archive/2025-11-04-add-inline-cross-references/tasks.md +25 -0
  79. normattiva2md-2.0.19/openspec/changes/archive/2025-11-04-add-rate-limiting-to-cross-references/proposal.md +39 -0
  80. normattiva2md-2.0.19/openspec/changes/archive/2025-11-04-add-rate-limiting-to-cross-references/specs/markdown-conversion/spec.md +63 -0
  81. normattiva2md-2.0.19/openspec/changes/archive/2025-11-05-2025-11-05-add-with-urls-param-for-article-links/proposal.md +16 -0
  82. normattiva2md-2.0.19/openspec/changes/archive/2025-11-05-2025-11-05-add-with-urls-param-for-article-links/tasks.md +5 -0
  83. normattiva2md-2.0.19/openspec/changes/archive/2025-11-05-add-complete-flag-for-article-urls/proposal.md +29 -0
  84. normattiva2md-2.0.19/openspec/changes/archive/2025-11-05-add-complete-flag-for-article-urls/specs/markdown-conversion/spec.md +26 -0
  85. normattiva2md-2.0.19/openspec/changes/archive/2025-11-05-add-complete-flag-for-article-urls/tasks.md +22 -0
  86. normattiva2md-2.0.19/openspec/changes/archive/2025-12-01-add-exa-api-key-cli-param/proposal.md +14 -0
  87. normattiva2md-2.0.19/openspec/changes/archive/2025-12-01-add-exa-api-key-cli-param/specs/url-lookup/spec.md +40 -0
  88. normattiva2md-2.0.19/openspec/changes/archive/2025-12-01-add-exa-api-key-cli-param/tasks.md +8 -0
  89. normattiva2md-2.0.19/openspec/changes/archive/2025-12-01-rename-cli-to-normattiva2md/proposal.md +27 -0
  90. normattiva2md-2.0.19/openspec/changes/archive/2025-12-01-rename-cli-to-normattiva2md/specs/cli-interface/spec.md +24 -0
  91. normattiva2md-2.0.19/openspec/changes/archive/2025-12-01-rename-cli-to-normattiva2md/tasks.md +29 -0
  92. normattiva2md-2.0.19/openspec/changes/archive/improve-error-messages/proposal.md +14 -0
  93. normattiva2md-2.0.19/openspec/changes/archive/improve-error-messages/specs/cli-ux/spec.md +30 -0
  94. normattiva2md-2.0.19/openspec/changes/archive/improve-error-messages/tasks.md +10 -0
  95. normattiva2md-2.0.19/openspec/project.md +73 -0
  96. normattiva2md-2.0.19/openspec/specs/cli-interface/spec.md +50 -0
  97. normattiva2md-2.0.19/openspec/specs/markdown-conversion/spec.md +155 -0
  98. normattiva2md-2.0.19/openspec/specs/url-lookup/spec.md +52 -0
  99. normattiva2md-2.0.19/pyproject.toml +46 -0
  100. normattiva2md-2.0.19/scripts/README.md +106 -0
  101. normattiva2md-2.0.19/scripts/build_distribution.sh +152 -0
  102. normattiva2md-2.0.19/scripts/download_eurlex.py +251 -0
  103. normattiva2md-2.0.19/scripts/test_compatibility.sh +63 -0
  104. normattiva2md-2.0.19/scripts/test_url_types.sh +71 -0
  105. normattiva2md-2.0.19/setup.cfg +4 -0
  106. normattiva2md-2.0.19/setup.py +71 -0
  107. normattiva2md-2.0.19/src/normattiva2md/__init__.py +0 -0
  108. normattiva2md-2.0.19/src/normattiva2md/akoma_utils.py +164 -0
  109. normattiva2md-2.0.19/src/normattiva2md/cli.py +401 -0
  110. normattiva2md-2.0.19/src/normattiva2md/constants.py +10 -0
  111. normattiva2md-2.0.19/src/normattiva2md/exa_api.py +261 -0
  112. normattiva2md-2.0.19/src/normattiva2md/markdown_converter.py +712 -0
  113. normattiva2md-2.0.19/src/normattiva2md/multi_document.py +262 -0
  114. normattiva2md-2.0.19/src/normattiva2md/normattiva_api.py +247 -0
  115. normattiva2md-2.0.19/src/normattiva2md/utils.py +94 -0
  116. normattiva2md-2.0.19/src/normattiva2md/xml_parser.py +161 -0
  117. normattiva2md-2.0.19/src/normattiva2md.egg-info/PKG-INFO +467 -0
  118. normattiva2md-2.0.19/src/normattiva2md.egg-info/SOURCES.txt +125 -0
  119. normattiva2md-2.0.19/src/normattiva2md.egg-info/dependency_links.txt +1 -0
  120. normattiva2md-2.0.19/src/normattiva2md.egg-info/entry_points.txt +2 -0
  121. normattiva2md-2.0.19/src/normattiva2md.egg-info/not-zip-safe +1 -0
  122. normattiva2md-2.0.19/src/normattiva2md.egg-info/requires.txt +1 -0
  123. normattiva2md-2.0.19/src/normattiva2md.egg-info/top_level.txt +2 -0
  124. normattiva2md-2.0.19/tasks/REFACTORING_PLAN.md +100 -0
  125. normattiva2md-2.0.19/test_data/20050516_005G0104_VIGENZA_20250130.xml +8825 -0
  126. normattiva2md-2.0.19/test_data/README.md +13 -0
  127. normattiva2md-2.0.19/tests/test_convert.py +448 -0
@@ -0,0 +1,129 @@
1
+ # CLAUDE.md
2
+
3
+ This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
+
5
+ ## Project Overview
6
+
7
+ **Akoma2MD** is a CLI tool that converts XML documents in Akoma Ntoso format (legal documents from normattiva.it) to readable Markdown. The tool is designed to produce LLM-friendly output for building legal AI bots.
8
+
9
+ ## Core Architecture
10
+
11
+ ### Main Components
12
+
13
+ - `convert_akomantoso.py`: Unified CLI tool (requires `requests`)
14
+ - Entry point: `main()` function with auto-detect URL/file
15
+ - URL support: `is_normattiva_url()`, `extract_params_from_normattiva_url()`, `download_akoma_ntoso()`
16
+ - Core conversion: `convert_akomantoso_to_markdown_improved(xml_path, md_path=None)` - outputs to stdout if md_path is None
17
+ - Text extraction: `clean_text_content(element)` handles inline formatting, refs, and modifications
18
+ - Article processing: `process_article(article_element, markdown_list, ns)` handles paragraphs and lists
19
+ - Status messages: routed to stderr when outputting markdown to stdout
20
+
21
+ - `fetch_normattiva.py`: Alternative fetcher (requires `tulit` library)
22
+ - Downloads documents from normattiva.it API
23
+ - Requires specific parameters (not URL-based)
24
+ - Converts to Markdown or JSON
25
+ - Entry point: `main()` with argparse CLI
26
+
27
+ - `setup.py`: Package configuration for PyPI distribution
28
+
29
+ ### XML Processing
30
+
31
+ The converter handles Akoma Ntoso 3.0 namespace: `http://docs.oasis-open.org/legaldocml/ns/akn/3.0`
32
+
33
+ Document structure extraction:
34
+
35
+ - Title: `//akn:docTitle`
36
+ - Preamble: `//akn:preamble`
37
+ - Body: `//akn:body` → chapters → sections → articles → paragraphs → lists
38
+ - Articles: `//akn:article` with `akn:num` (number) and `akn:heading` (title)
39
+ - Legislative modifications: wrapped in `(( ))` from `<ins>` and `<del>` tags
40
+
41
+ ## Common Development Tasks
42
+
43
+ ### Running the converter (auto-detect URL/file)
44
+
45
+ ```bash
46
+ # Output to file
47
+ python convert_akomantoso.py input.xml output.md
48
+ akoma2md input.xml output.md
49
+
50
+ # Output to stdout (default when -o omitted)
51
+ python convert_akomantoso.py input.xml
52
+ akoma2md input.xml > output.md
53
+ akoma2md -i input.xml
54
+
55
+ # From normattiva.it URL (auto-detected)
56
+ python convert_akomantoso.py "https://www.normattiva.it/uri-res/N2Ls?urn:nir:stato:legge:2022;53" output.md
57
+ akoma2md "URL" > output.md
58
+ akoma2md -i "URL" -o output.md
59
+
60
+ # With named arguments
61
+ akoma2md -i input.xml -o output.md
62
+
63
+ # Keep temporary XML from URL
64
+ akoma2md "URL" output.md --keep-xml
65
+ akoma2md "URL" --keep-xml > output.md
66
+ ```
67
+
68
+ ### Alternative: Fetching with specific parameters
69
+
70
+ ```bash
71
+ # Requires: pip install tulit
72
+ python fetch_normattiva.py --dataGU YYYYMMDD --codiceRedaz CODE --dataVigenza YYYYMMDD --output file.md --format markdown
73
+ ```
74
+
75
+ ### Testing
76
+
77
+ ```bash
78
+ # Basic test with sample data
79
+ python convert_akomantoso.py test_data/20050516_005G0104_VIGENZA_20250130.xml test_output.md
80
+ ```
81
+
82
+ ### Building executable
83
+
84
+ ```bash
85
+ pip install pyinstaller
86
+ pyinstaller --onefile --name akoma2md convert_akomantoso.py
87
+ ```
88
+
89
+ ### Package installation
90
+
91
+ ```bash
92
+ # CLI tool installation (recommended)
93
+ uv tool install .
94
+
95
+ # Development mode (requires venv)
96
+ pip install -e .
97
+
98
+ # From source (requires venv)
99
+ pip install .
100
+ ```
101
+
102
+ ## Key Design Decisions
103
+
104
+ ### Markdown Output Format
105
+
106
+ - Articles: `# Art. X - Title`
107
+ - Chapters: `## Chapter Title`
108
+ - Sections: `### Section Title`
109
+ - Numbered paragraphs: `1. Text content`
110
+ - Lists: Markdown bullet lists with `- a) item text`
111
+ - Legislative changes: Wrapped in `((modified text))`
112
+
113
+ ### Text Cleaning
114
+
115
+ - Removes excessive whitespace and indentation
116
+ - Preserves inline formatting (bold, emphasis)
117
+ - Extracts text from `<ref>` tags
118
+ - Prevents double-wrapping of `(( ))` in modifications
119
+ - Filters out horizontal separator lines (`----`)
120
+
121
+ ## Project Constraints
122
+
123
+ - **Minimal dependencies**: only `requests` for URL fetching
124
+ - Python 3.7+ compatibility
125
+ - CLI must support both positional and named arguments
126
+ - Auto-detect URL vs file input
127
+ - Output defaults to stdout when not specified (file optional)
128
+ - Status messages always go to stderr to keep stdout clean for piping
129
+ - Output must be LLM-friendly Markdown
@@ -0,0 +1,23 @@
1
+ ---
2
+ name: OpenSpec: Apply
3
+ description: Implement an approved OpenSpec change and keep tasks in sync.
4
+ category: OpenSpec
5
+ tags: [openspec, apply]
6
+ ---
7
+ <!-- OPENSPEC:START -->
8
+ **Guardrails**
9
+ - Favor straightforward, minimal implementations first and add complexity only when it is requested or clearly required.
10
+ - Keep changes tightly scoped to the requested outcome.
11
+ - Refer to `openspec/AGENTS.md` (located inside the `openspec/` directory—run `ls openspec` or `openspec update` if you don't see it) if you need additional OpenSpec conventions or clarifications.
12
+
13
+ **Steps**
14
+ Track these steps as TODOs and complete them one by one.
15
+ 1. Read `changes/<id>/proposal.md`, `design.md` (if present), and `tasks.md` to confirm scope and acceptance criteria.
16
+ 2. Work through tasks sequentially, keeping edits minimal and focused on the requested change.
17
+ 3. Confirm completion before updating statuses—make sure every item in `tasks.md` is finished.
18
+ 4. Update the checklist after all work is done so each task is marked `- [x]` and reflects reality.
19
+ 5. Reference `openspec list` or `openspec show <item>` when additional context is required.
20
+
21
+ **Reference**
22
+ - Use `openspec show <id> --json --deltas-only` if you need additional context from the proposal while implementing.
23
+ <!-- OPENSPEC:END -->
@@ -0,0 +1,27 @@
1
+ ---
2
+ name: OpenSpec: Archive
3
+ description: Archive a deployed OpenSpec change and update specs.
4
+ category: OpenSpec
5
+ tags: [openspec, archive]
6
+ ---
7
+ <!-- OPENSPEC:START -->
8
+ **Guardrails**
9
+ - Favor straightforward, minimal implementations first and add complexity only when it is requested or clearly required.
10
+ - Keep changes tightly scoped to the requested outcome.
11
+ - Refer to `openspec/AGENTS.md` (located inside the `openspec/` directory—run `ls openspec` or `openspec update` if you don't see it) if you need additional OpenSpec conventions or clarifications.
12
+
13
+ **Steps**
14
+ 1. Determine the change ID to archive:
15
+ - If this prompt already includes a specific change ID (for example inside a `<ChangeId>` block populated by slash-command arguments), use that value after trimming whitespace.
16
+ - If the conversation references a change loosely (for example by title or summary), run `openspec list` to surface likely IDs, share the relevant candidates, and confirm which one the user intends.
17
+ - Otherwise, review the conversation, run `openspec list`, and ask the user which change to archive; wait for a confirmed change ID before proceeding.
18
+ - If you still cannot identify a single change ID, stop and tell the user you cannot archive anything yet.
19
+ 2. Validate the change ID by running `openspec list` (or `openspec show <id>`) and stop if the change is missing, already archived, or otherwise not ready to archive.
20
+ 3. Run `openspec archive <id> --yes` so the CLI moves the change and applies spec updates without prompts (use `--skip-specs` only for tooling-only work).
21
+ 4. Review the command output to confirm the target specs were updated and the change landed in `changes/archive/`.
22
+ 5. Validate with `openspec validate --strict` and inspect with `openspec show <id>` if anything looks off.
23
+
24
+ **Reference**
25
+ - Use `openspec list` to confirm change IDs before archiving.
26
+ - Inspect refreshed specs with `openspec list --specs` and address any validation issues before handing off.
27
+ <!-- OPENSPEC:END -->
@@ -0,0 +1,27 @@
1
+ ---
2
+ name: OpenSpec: Proposal
3
+ description: Scaffold a new OpenSpec change and validate strictly.
4
+ category: OpenSpec
5
+ tags: [openspec, change]
6
+ ---
7
+ <!-- OPENSPEC:START -->
8
+ **Guardrails**
9
+ - Favor straightforward, minimal implementations first and add complexity only when it is requested or clearly required.
10
+ - Keep changes tightly scoped to the requested outcome.
11
+ - Refer to `openspec/AGENTS.md` (located inside the `openspec/` directory—run `ls openspec` or `openspec update` if you don't see it) if you need additional OpenSpec conventions or clarifications.
12
+ - Identify any vague or ambiguous details and ask the necessary follow-up questions before editing files.
13
+
14
+ **Steps**
15
+ 1. Review `openspec/project.md`, run `openspec list` and `openspec list --specs`, and inspect related code or docs (e.g., via `rg`/`ls`) to ground the proposal in current behaviour; note any gaps that require clarification.
16
+ 2. Choose a unique verb-led `change-id` and scaffold `proposal.md`, `tasks.md`, and `design.md` (when needed) under `openspec/changes/<id>/`.
17
+ 3. Map the change into concrete capabilities or requirements, breaking multi-scope efforts into distinct spec deltas with clear relationships and sequencing.
18
+ 4. Capture architectural reasoning in `design.md` when the solution spans multiple systems, introduces new patterns, or demands trade-off discussion before committing to specs.
19
+ 5. Draft spec deltas in `changes/<id>/specs/<capability>/spec.md` (one folder per capability) using `## ADDED|MODIFIED|REMOVED Requirements` with at least one `#### Scenario:` per requirement and cross-reference related capabilities when relevant.
20
+ 6. Draft `tasks.md` as an ordered list of small, verifiable work items that deliver user-visible progress, include validation (tests, tooling), and highlight dependencies or parallelizable work.
21
+ 7. Validate with `openspec validate <id> --strict` and resolve every issue before sharing the proposal.
22
+
23
+ **Reference**
24
+ - Use `openspec show <id> --json --deltas-only` or `openspec show <spec> --type spec` to inspect details when validation fails.
25
+ - Search existing requirements with `rg -n "Requirement:|Scenario:" openspec/specs` before writing new ones.
26
+ - Explore the codebase with `rg <keyword>`, `ls`, or direct file reads so proposals align with current implementation realities.
27
+ <!-- OPENSPEC:END -->
@@ -0,0 +1,57 @@
1
+ # Metodologia di Lavoro con Gemini CLI
2
+
3
+ Questo documento descrive la metodologia di lavoro adottata durante l'interazione con l'agente Gemini CLI per lo sviluppo del progetto `normattiva_2_md`.
4
+
5
+ ## 1. Agente CLI Interattivo
6
+
7
+ L'interazione avviene tramite un'interfaccia a riga di comando, dove l'agente risponde a richieste specifiche, esegue operazioni e fornisce feedback in tempo reale.
8
+
9
+ ## 2. Workflow Orientato al Task
10
+
11
+ Il processo di sviluppo segue un ciclo iterativo:
12
+
13
+ - Comprensione: L'agente analizza la richiesta dell'utente e il contesto del progetto (file esistenti, obiettivi).
14
+
15
+ - Pianificazione: Viene formulato un piano conciso per affrontare il task, spesso includendo l'uso di strumenti specifici.
16
+
17
+ - Implementazione: L'agente esegue le azioni pianificate utilizzando gli strumenti disponibili (operazioni su file, comandi shell, interazioni Git).
18
+
19
+ - Verifica: I risultati vengono verificati, spesso con il feedback diretto dell'utente o tramite l'analisi dell'output generato.
20
+
21
+ - Iterazione/Raffinamento: Sulla base della verifica, il processo si ripete per affinare la soluzione o affrontare nuovi task.
22
+
23
+ ## 3. Utilizzo degli Strumenti
24
+
25
+ L'agente utilizza una suite di strumenti per interagire con il filesystem, eseguire comandi shell, e gestire il controllo versione:
26
+
27
+ - Operazioni su File: Lettura, scrittura, modifica e ridenominazione di file (`read_file`, `write_file`, `replace`, `mv`).
28
+
29
+ - Comandi Shell: Esecuzione di comandi di sistema (`run_shell_command`) per operazioni come la creazione di directory, la rimozione di file, o l'interazione con Git.
30
+
31
+ - Operazioni Git: Gestione del repository (`git init`, `git add`, `git commit`, `git push`, `git status`, `git log`).
32
+
33
+ - Web Fetching: Recupero di contenuti da URL (`web_fetch`) per analisi o download (es. `tulit` per Normattiva).
34
+
35
+ ## 4. Collaborazione con l'Utente
36
+
37
+ La collaborazione è un aspetto centrale. L'agente si basa sulle istruzioni esplicite dell'utente e sul feedback per guidare lo sviluppo. Le decisioni chiave e i cambiamenti di strategia vengono discussi e approvati dall'utente.
38
+
39
+ ## 5. Specificità e Adattabilità
40
+
41
+ L'agente si adatta alle esigenze specifiche del progetto, come dimostrato dalla capacità di:
42
+
43
+ - Rifinire la qualità dell'output Markdown basandosi su requisiti dettagliati (es. gestione delle righe vuote, filtraggio del testo abrogato).
44
+
45
+ - Modificare la pipeline di elaborazione (es. passaggio da XML diretto a JSON intermedio e poi ritorno a XML diretto) per ottimizzare i risultati.
46
+
47
+ ## 6. Documentazione del Progetto
48
+
49
+ Durante lo sviluppo, viene mantenuta una documentazione aggiornata per tracciare i progressi e le decisioni:
50
+
51
+ - `LOG.md`: Registro cronologico degli avanzamenti e delle modifiche significative. **Nota: I log dovrebbero essere concisi, focalizzandosi sui punti chiave e sulle decisioni, evitando dettagli eccessivi.**
52
+
53
+ - `README.md`: Descrizione generale del progetto, istruzioni di installazione e utilizzo.
54
+
55
+ - `PRD.md`: Documento dei requisiti di prodotto, che evolve con la comprensione degli obiettivi.
56
+
57
+ - `VERIFICATION.md`: Checklist e stato verifiche qualità output Markdown.
@@ -0,0 +1,7 @@
1
+ # Imposta i fine riga per i file di testo
2
+ *.py text eol=lf
3
+ *.md text eol=lf
4
+ *.xml text eol=lf
5
+
6
+ # Normalizza i fine riga per tutti i file di testo
7
+ * text=auto
@@ -0,0 +1,22 @@
1
+ ---
2
+ description: Implement an approved OpenSpec change and keep tasks in sync.
3
+ ---
4
+
5
+ $ARGUMENTS
6
+ <!-- OPENSPEC:START -->
7
+ **Guardrails**
8
+ - Favor straightforward, minimal implementations first and add complexity only when it is requested or clearly required.
9
+ - Keep changes tightly scoped to the requested outcome.
10
+ - Refer to `openspec/AGENTS.md` (located inside the `openspec/` directory—run `ls openspec` or `openspec update` if you don't see it) if you need additional OpenSpec conventions or clarifications.
11
+
12
+ **Steps**
13
+ Track these steps as TODOs and complete them one by one.
14
+ 1. Read `changes/<id>/proposal.md`, `design.md` (if present), and `tasks.md` to confirm scope and acceptance criteria.
15
+ 2. Work through tasks sequentially, keeping edits minimal and focused on the requested change.
16
+ 3. Confirm completion before updating statuses—make sure every item in `tasks.md` is finished.
17
+ 4. Update the checklist after all work is done so each task is marked `- [x]` and reflects reality.
18
+ 5. Reference `openspec list` or `openspec show <item>` when additional context is required.
19
+
20
+ **Reference**
21
+ - Use `openspec show <id> --json --deltas-only` if you need additional context from the proposal while implementing.
22
+ <!-- OPENSPEC:END -->
@@ -0,0 +1,26 @@
1
+ ---
2
+ description: Archive a deployed OpenSpec change and update specs.
3
+ ---
4
+
5
+ $ARGUMENTS
6
+ <!-- OPENSPEC:START -->
7
+ **Guardrails**
8
+ - Favor straightforward, minimal implementations first and add complexity only when it is requested or clearly required.
9
+ - Keep changes tightly scoped to the requested outcome.
10
+ - Refer to `openspec/AGENTS.md` (located inside the `openspec/` directory—run `ls openspec` or `openspec update` if you don't see it) if you need additional OpenSpec conventions or clarifications.
11
+
12
+ **Steps**
13
+ 1. Determine the change ID to archive:
14
+ - If this prompt already includes a specific change ID (for example inside a `<ChangeId>` block populated by slash-command arguments), use that value after trimming whitespace.
15
+ - If the conversation references a change loosely (for example by title or summary), run `openspec list` to surface likely IDs, share the relevant candidates, and confirm which one the user intends.
16
+ - Otherwise, review the conversation, run `openspec list`, and ask the user which change to archive; wait for a confirmed change ID before proceeding.
17
+ - If you still cannot identify a single change ID, stop and tell the user you cannot archive anything yet.
18
+ 2. Validate the change ID by running `openspec list` (or `openspec show <id>`) and stop if the change is missing, already archived, or otherwise not ready to archive.
19
+ 3. Run `openspec archive <id> --yes` so the CLI moves the change and applies spec updates without prompts (use `--skip-specs` only for tooling-only work).
20
+ 4. Review the command output to confirm the target specs were updated and the change landed in `changes/archive/`.
21
+ 5. Validate with `openspec validate --strict` and inspect with `openspec show <id>` if anything looks off.
22
+
23
+ **Reference**
24
+ - Use `openspec list` to confirm change IDs before archiving.
25
+ - Inspect refreshed specs with `openspec list --specs` and address any validation issues before handing off.
26
+ <!-- OPENSPEC:END -->
@@ -0,0 +1,26 @@
1
+ ---
2
+ description: Scaffold a new OpenSpec change and validate strictly.
3
+ ---
4
+
5
+ $ARGUMENTS
6
+ <!-- OPENSPEC:START -->
7
+ **Guardrails**
8
+ - Favor straightforward, minimal implementations first and add complexity only when it is requested or clearly required.
9
+ - Keep changes tightly scoped to the requested outcome.
10
+ - Refer to `openspec/AGENTS.md` (located inside the `openspec/` directory—run `ls openspec` or `openspec update` if you don't see it) if you need additional OpenSpec conventions or clarifications.
11
+ - Identify any vague or ambiguous details and ask the necessary follow-up questions before editing files.
12
+
13
+ **Steps**
14
+ 1. Review `openspec/project.md`, run `openspec list` and `openspec list --specs`, and inspect related code or docs (e.g., via `rg`/`ls`) to ground the proposal in current behaviour; note any gaps that require clarification.
15
+ 2. Choose a unique verb-led `change-id` and scaffold `proposal.md`, `tasks.md`, and `design.md` (when needed) under `openspec/changes/<id>/`.
16
+ 3. Map the change into concrete capabilities or requirements, breaking multi-scope efforts into distinct spec deltas with clear relationships and sequencing.
17
+ 4. Capture architectural reasoning in `design.md` when the solution spans multiple systems, introduces new patterns, or demands trade-off discussion before committing to specs.
18
+ 5. Draft spec deltas in `changes/<id>/specs/<capability>/spec.md` (one folder per capability) using `## ADDED|MODIFIED|REMOVED Requirements` with at least one `#### Scenario:` per requirement and cross-reference related capabilities when relevant.
19
+ 6. Draft `tasks.md` as an ordered list of small, verifiable work items that deliver user-visible progress, include validation (tests, tooling), and highlight dependencies or parallelizable work.
20
+ 7. Validate with `openspec validate <id> --strict` and resolve every issue before sharing the proposal.
21
+
22
+ **Reference**
23
+ - Use `openspec show <id> --json --deltas-only` or `openspec show <spec> --type spec` to inspect details when validation fails.
24
+ - Search existing requirements with `rg -n "Requirement:|Scenario:" openspec/specs` before writing new ones.
25
+ - Explore the codebase with `rg <keyword>`, `ls`, or direct file reads so proposals align with current implementation realities.
26
+ <!-- OPENSPEC:END -->
@@ -0,0 +1,56 @@
1
+ name: Deploy Jekyll site to Pages
2
+
3
+ on:
4
+ push:
5
+ branches: ["main"]
6
+ workflow_dispatch:
7
+
8
+ permissions:
9
+ contents: read
10
+ pages: write
11
+ id-token: write
12
+
13
+ concurrency:
14
+ group: "pages"
15
+ cancel-in-progress: false
16
+
17
+ jobs:
18
+ build:
19
+ runs-on: ubuntu-latest
20
+ steps:
21
+ - name: Checkout
22
+ uses: actions/checkout@v4
23
+
24
+ - name: Setup Ruby
25
+ uses: ruby/setup-ruby@v1
26
+ with:
27
+ ruby-version: '3.3'
28
+ bundler-cache: true
29
+ cache-version: 0
30
+ working-directory: docs
31
+
32
+ - name: Setup Pages
33
+ id: pages
34
+ uses: actions/configure-pages@v5
35
+
36
+ - name: Build with Jekyll
37
+ run: bundle exec jekyll build --baseurl "${{ steps.pages.outputs.base_path }}"
38
+ working-directory: docs
39
+ env:
40
+ JEKYLL_ENV: production
41
+
42
+ - name: Upload artifact
43
+ uses: actions/upload-pages-artifact@v3
44
+ with:
45
+ path: docs/_site
46
+
47
+ deploy:
48
+ environment:
49
+ name: github-pages
50
+ url: ${{ steps.deployment.outputs.page_url }}
51
+ runs-on: ubuntu-latest
52
+ needs: build
53
+ steps:
54
+ - name: Deploy to GitHub Pages
55
+ id: deployment
56
+ uses: actions/deploy-pages@v4
@@ -0,0 +1,146 @@
1
+ name: Build Releases
2
+
3
+ on:
4
+ workflow_dispatch: {}
5
+ push:
6
+ tags:
7
+ - "v*"
8
+
9
+ permissions:
10
+ contents: read
11
+
12
+ jobs:
13
+ build-linux:
14
+ name: Linux Binary
15
+ runs-on: ubuntu-latest
16
+ steps:
17
+ - name: Checkout
18
+ uses: actions/checkout@v4
19
+
20
+ - name: Setup Python
21
+ uses: actions/setup-python@v5
22
+ with:
23
+ python-version: "3.11"
24
+
25
+ - name: Install dependencies
26
+ run: |
27
+ python -m pip install --upgrade pip
28
+ python -m pip install -e .
29
+ python -m pip install pyinstaller
30
+
31
+ - name: Capture package version
32
+ run: echo "AKOMA_VERSION=$(python setup.py --version)" >> $GITHUB_ENV
33
+
34
+ - name: Build binary
35
+ run: pyinstaller --onefile --name normattiva2md convert_akomantoso.py
36
+
37
+ - name: Copy XML fixture
38
+ run: cp test_data/20050516_005G0104_VIGENZA_20250130.xml .
39
+
40
+ - name: Run tests
41
+ run: make test
42
+
43
+ - name: Clean test outputs
44
+ run: rm -f test_output_*.md demo_output.md
45
+
46
+ - name: Package artifact
47
+ run: |
48
+ tar -C dist -czf normattiva2md-${AKOMA_VERSION}-linux-x86_64.tar.gz normattiva2md
49
+ env:
50
+ AKOMA_VERSION: ${{ env.AKOMA_VERSION }}
51
+
52
+ - name: Upload artifact
53
+ uses: actions/upload-artifact@v4
54
+ with:
55
+ name: normattiva2md-linux
56
+ path: normattiva2md-${{ env.AKOMA_VERSION }}-linux-x86_64.tar.gz
57
+
58
+ build-windows:
59
+ name: Windows Binary
60
+ runs-on: windows-latest
61
+ steps:
62
+ - name: Checkout
63
+ uses: actions/checkout@v4
64
+
65
+ - name: Setup Python
66
+ uses: actions/setup-python@v5
67
+ with:
68
+ python-version: "3.11"
69
+
70
+ - name: Install dependencies
71
+ shell: pwsh
72
+ run: |
73
+ python -m pip install --upgrade pip
74
+ python -m pip install -e .
75
+ python -m pip install pyinstaller
76
+
77
+ - name: Capture package version
78
+ shell: pwsh
79
+ run: |
80
+ $version = python setup.py --version
81
+ echo "AKOMA_VERSION=$version" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
82
+
83
+ - name: Build binary
84
+ shell: pwsh
85
+ run: pyinstaller --onefile --name normattiva2md convert_akomantoso.py
86
+
87
+ - name: Copy XML fixture
88
+ shell: pwsh
89
+ run: Copy-Item test_data/20050516_005G0104_VIGENZA_20250130.xml .
90
+
91
+ - name: Run unit tests
92
+ shell: pwsh
93
+ run: python -m unittest discover -s tests
94
+
95
+ - name: Exercise CLI scripts
96
+ shell: pwsh
97
+ run: |
98
+ python convert_akomantoso.py 20050516_005G0104_VIGENZA_20250130.xml test_output_python.md
99
+ ./dist/normattiva2md.exe 20050516_005G0104_VIGENZA_20250130.xml test_output_exe.md
100
+ normattiva2md 20050516_005G0104_VIGENZA_20250130.xml test_output_cmd.md
101
+
102
+ - name: Clean test outputs
103
+ shell: pwsh
104
+ run: Remove-Item test_output_*.md -ErrorAction SilentlyContinue
105
+
106
+ - name: Package artifact
107
+ shell: pwsh
108
+ env:
109
+ AKOMA_VERSION: ${{ env.AKOMA_VERSION }}
110
+ run: |
111
+ $artifactPath = Join-Path "dist" "normattiva2md-$env:AKOMA_VERSION-windows-x86_64.zip"
112
+ $binaryPath = Join-Path "dist" "normattiva2md.exe"
113
+ Compress-Archive -Path $binaryPath -DestinationPath $artifactPath -Force
114
+ Get-Item $artifactPath
115
+
116
+ - name: Upload artifact
117
+ uses: actions/upload-artifact@v4
118
+ with:
119
+ name: normattiva2md-windows
120
+ path: dist/normattiva2md-${{ env.AKOMA_VERSION }}-windows-x86_64.zip
121
+
122
+ release:
123
+ name: Publish Release
124
+ needs:
125
+ - build-linux
126
+ - build-windows
127
+ runs-on: ubuntu-latest
128
+ if: startsWith(github.ref, 'refs/tags/')
129
+ permissions:
130
+ contents: write
131
+ steps:
132
+ - name: Download artifacts
133
+ uses: actions/download-artifact@v4
134
+ with:
135
+ path: dist
136
+
137
+ - name: List download contents
138
+ run: ls -R dist
139
+
140
+ - name: Publish GitHub release
141
+ uses: softprops/action-gh-release@v1
142
+ with:
143
+ files: |
144
+ dist/normattiva2md-linux/*
145
+ dist/normattiva2md-windows/*
146
+ prerelease: ${{ contains(github.ref, '-rc') }}
@@ -0,0 +1,68 @@
1
+ # Ignora la directory di build di PyInstaller
2
+ build/
3
+ dist/
4
+
5
+ # File Python compilati
6
+ *.pyc
7
+ __pycache__/
8
+
9
+ # File temporanei e di sistema
10
+ *~
11
+ *.bak
12
+ *.swp
13
+ *.swo
14
+ .DS_Store
15
+ Thumbs.db
16
+
17
+ # File di sistema specifici di Windows
18
+ *.xml:Zone.Identifier
19
+
20
+ # File di output generati
21
+ output*.md
22
+ test_output/
23
+ test_*.md
24
+ temp_*.xml
25
+ *.debug.html
26
+
27
+ # Conversioni di leggi specifiche (non committare output in root)
28
+ anticorruzione.md
29
+ codice_civile.md
30
+ costituzione.md
31
+ privacy.md
32
+ codice_*.md
33
+ legge_*.md
34
+
35
+ # Build artifacts
36
+ akoma2md.egg-info/
37
+ build/
38
+ dist/
39
+ .env
40
+
41
+ # Virtual environment
42
+ venv/
43
+
44
+ # pytest cache
45
+ .pytest_cache/
46
+
47
+ # ruff cache
48
+ .ruff_cache/
49
+
50
+ # Coverage reports
51
+ .coverage
52
+ htmlcov/
53
+
54
+ # mypy cache
55
+ .mypy_cache/
56
+
57
+ # tox
58
+ .tox/
59
+
60
+ # Node modules (for .opencode)
61
+ node_modules/
62
+
63
+ # Virtual environments (already have venv/, but add .venv/)
64
+ .venv/
65
+
66
+ plans/
67
+ tasks/todo.md
68
+ tmp/
@@ -0,0 +1,21 @@
1
+ ---
2
+ agent: build
3
+ description: Implement an approved OpenSpec change and keep tasks in sync.
4
+ ---
5
+ <!-- OPENSPEC:START -->
6
+ **Guardrails**
7
+ - Favor straightforward, minimal implementations first and add complexity only when it is requested or clearly required.
8
+ - Keep changes tightly scoped to the requested outcome.
9
+ - Refer to `openspec/AGENTS.md` (located inside the `openspec/` directory—run `ls openspec` or `openspec update` if you don't see it) if you need additional OpenSpec conventions or clarifications.
10
+
11
+ **Steps**
12
+ Track these steps as TODOs and complete them one by one.
13
+ 1. Read `changes/<id>/proposal.md`, `design.md` (if present), and `tasks.md` to confirm scope and acceptance criteria.
14
+ 2. Work through tasks sequentially, keeping edits minimal and focused on the requested change.
15
+ 3. Confirm completion before updating statuses—make sure every item in `tasks.md` is finished.
16
+ 4. Update the checklist after all work is done so each task is marked `- [x]` and reflects reality.
17
+ 5. Reference `openspec list` or `openspec show <item>` when additional context is required.
18
+
19
+ **Reference**
20
+ - Use `openspec show <id> --json --deltas-only` if you need additional context from the proposal while implementing.
21
+ <!-- OPENSPEC:END -->