napier 0.1.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 (241) hide show
  1. napier-0.1.0/.github/ISSUE_TEMPLATE/bug_report.yml +43 -0
  2. napier-0.1.0/.github/ISSUE_TEMPLATE/config.yml +8 -0
  3. napier-0.1.0/.github/ISSUE_TEMPLATE/feature_request.yml +21 -0
  4. napier-0.1.0/.github/ISSUE_TEMPLATE/publisher_request.yml +41 -0
  5. napier-0.1.0/.github/ISSUE_TEMPLATE/source_request.yml +35 -0
  6. napier-0.1.0/.github/dependabot.yml +12 -0
  7. napier-0.1.0/.github/pull_request_template.md +14 -0
  8. napier-0.1.0/.github/workflows/ci.yml +139 -0
  9. napier-0.1.0/.github/workflows/release.yml +65 -0
  10. napier-0.1.0/.github/workflows/scorecard.yml +41 -0
  11. napier-0.1.0/.gitignore +15 -0
  12. napier-0.1.0/AGENTS.md +13 -0
  13. napier-0.1.0/CHANGELOG.md +44 -0
  14. napier-0.1.0/CITATION.cff +11 -0
  15. napier-0.1.0/CODE_OF_CONDUCT.md +134 -0
  16. napier-0.1.0/CONTRIBUTING.md +92 -0
  17. napier-0.1.0/LICENSE +202 -0
  18. napier-0.1.0/NOTICE +11 -0
  19. napier-0.1.0/PKG-INFO +348 -0
  20. napier-0.1.0/README.md +301 -0
  21. napier-0.1.0/SECURITY.md +74 -0
  22. napier-0.1.0/SUPPORT.md +13 -0
  23. napier-0.1.0/THIRD_PARTY_NOTICES.md +47 -0
  24. napier-0.1.0/catalog/modules.yaml +358 -0
  25. napier-0.1.0/docs/data-policy.md +53 -0
  26. napier-0.1.0/docs/how-it-works.md +98 -0
  27. napier-0.1.0/docs/images/example-rack.png +0 -0
  28. napier-0.1.0/docs/images/example-scenario.png +0 -0
  29. napier-0.1.0/docs/mcp.md +155 -0
  30. napier-0.1.0/docs/rack.md +156 -0
  31. napier-0.1.0/docs/sources.md +103 -0
  32. napier-0.1.0/examples/notes/rack-usage.md +60 -0
  33. napier-0.1.0/examples/notes/rack.md +59 -0
  34. napier-0.1.0/examples/racks/challenges.yaml +26 -0
  35. napier-0.1.0/examples/racks/devices.yaml +30 -0
  36. napier-0.1.0/examples/racks/example_rack.yaml +399 -0
  37. napier-0.1.0/examples/racks/layout.yaml +24 -0
  38. napier-0.1.0/examples/racks/scenarios/add-step-8.yaml +10 -0
  39. napier-0.1.0/examples/racks/usage.yaml +94 -0
  40. napier-0.1.0/facts/acid_rain_constellation.yaml +41 -0
  41. napier-0.1.0/facts/acid_rain_maestro.yaml +109 -0
  42. napier-0.1.0/facts/alm_akemies_castle.yaml +74 -0
  43. napier-0.1.0/facts/alm_mfd.yaml +52 -0
  44. napier-0.1.0/facts/alm_oax2.yaml +54 -0
  45. napier-0.1.0/facts/alm_pams_pro_workout.yaml +141 -0
  46. napier-0.1.0/facts/bastl_ikarie.yaml +108 -0
  47. napier-0.1.0/facts/boredbrain_optx_v2.yaml +73 -0
  48. napier-0.1.0/facts/digitakt_2.yaml +264 -0
  49. napier-0.1.0/facts/divkid_manic.yaml +95 -0
  50. napier-0.1.0/facts/divkid_ochd.yaml +44 -0
  51. napier-0.1.0/facts/divkid_ochd_expander.yaml +64 -0
  52. napier-0.1.0/facts/entineering_midi_mult_1u.yaml +19 -0
  53. napier-0.1.0/facts/erica_sample_drum.yaml +115 -0
  54. napier-0.1.0/facts/hexinverter_mutant_machine.yaml +33 -0
  55. napier-0.1.0/facts/instruo_aradh.yaml +95 -0
  56. napier-0.1.0/facts/instruo_carn.yaml +84 -0
  57. napier-0.1.0/facts/instruo_cnoc.yaml +82 -0
  58. napier-0.1.0/facts/instruo_csl.yaml +126 -0
  59. napier-0.1.0/facts/instruo_eas.yaml +64 -0
  60. napier-0.1.0/facts/instruo_larachd.yaml +81 -0
  61. napier-0.1.0/facts/instruo_neoni.yaml +75 -0
  62. napier-0.1.0/facts/intellijel_amps.yaml +95 -0
  63. napier-0.1.0/facts/intellijel_atlantix.yaml +107 -0
  64. napier-0.1.0/facts/intellijel_buff_mult_1u.yaml +44 -0
  65. napier-0.1.0/facts/intellijel_cascadia.yaml +165 -0
  66. napier-0.1.0/facts/intellijel_dual_vca_1u.yaml +51 -0
  67. napier-0.1.0/facts/intellijel_duatt_1u.yaml +74 -0
  68. napier-0.1.0/facts/intellijel_noise_tools.yaml +73 -0
  69. napier-0.1.0/facts/intellijel_octalink_1u.yaml +63 -0
  70. napier-0.1.0/facts/intellijel_passive_lpg_1u.yaml +43 -0
  71. napier-0.1.0/facts/intellijel_quadratt_1u.yaml +74 -0
  72. napier-0.1.0/facts/intellijel_quadrax.yaml +112 -0
  73. napier-0.1.0/facts/intellijel_steppy_1u.yaml +141 -0
  74. napier-0.1.0/facts/intellijel_stereo_line_out_1u.yaml +84 -0
  75. napier-0.1.0/facts/intellijel_tangrams.yaml +86 -0
  76. napier-0.1.0/facts/intellijel_zeroscope_1u.yaml +93 -0
  77. napier-0.1.0/facts/joranalogue_add_2.yaml +21 -0
  78. napier-0.1.0/facts/knobula_monumatic.yaml +93 -0
  79. napier-0.1.0/facts/koma_kmndr.yaml +23 -0
  80. napier-0.1.0/facts/m8_tracker.yaml +304 -0
  81. napier-0.1.0/facts/make_noise_maths.yaml +112 -0
  82. napier-0.1.0/facts/make_noise_multiwave.yaml +132 -0
  83. napier-0.1.0/facts/make_noise_polimaths.yaml +122 -0
  84. napier-0.1.0/facts/make_noise_qxg.yaml +73 -0
  85. napier-0.1.0/facts/metropolix_solo.yaml +228 -0
  86. napier-0.1.0/facts/msw_beehive.yaml +85 -0
  87. napier-0.1.0/facts/msw_nrings.yaml +96 -0
  88. napier-0.1.0/facts/mutable_beads.yaml +76 -0
  89. napier-0.1.0/facts/ne_lapsus_os.yaml +53 -0
  90. napier-0.1.0/facts/ne_xer_mixa.yaml +82 -0
  91. napier-0.1.0/facts/neutron_qvca.yaml +20 -0
  92. napier-0.1.0/facts/oxi_one_mk2.yaml +202 -0
  93. napier-0.1.0/facts/qubit_data_bender.yaml +151 -0
  94. napier-0.1.0/facts/ritual_guillotine.yaml +72 -0
  95. napier-0.1.0/facts/ritual_pointeuse.yaml +87 -0
  96. napier-0.1.0/facts/shakmat_bard_quartet.yaml +93 -0
  97. napier-0.1.0/facts/shakmat_bard_quartet_expander.yaml +55 -0
  98. napier-0.1.0/facts/shakmat_sumdif.yaml +23 -0
  99. napier-0.1.0/facts/soundforce_samples_ii.yaml +106 -0
  100. napier-0.1.0/facts/squarp_hermod_plus.yaml +145 -0
  101. napier-0.1.0/facts/ssf_metalloid.yaml +73 -0
  102. napier-0.1.0/facts/ssf_steady_state_gate.yaml +84 -0
  103. napier-0.1.0/facts/ssf_stereo_dipole.yaml +74 -0
  104. napier-0.1.0/facts/ssf_ultra_kick.yaml +78 -0
  105. napier-0.1.0/facts/ssf_ultra_perc.yaml +103 -0
  106. napier-0.1.0/facts/ssf_vortices.yaml +95 -0
  107. napier-0.1.0/facts/strymon_magneto.yaml +87 -0
  108. napier-0.1.0/facts/strymon_starlab.yaml +113 -0
  109. napier-0.1.0/facts/strymon_superkar_plus.yaml +69 -0
  110. napier-0.1.0/facts/venus_veno_orbit.yaml +124 -0
  111. napier-0.1.0/facts/vpme_t43.yaml +34 -0
  112. napier-0.1.0/facts/wmd_clutch.yaml +109 -0
  113. napier-0.1.0/facts/wmd_metron.yaml +104 -0
  114. napier-0.1.0/facts/wmd_voltera.yaml +53 -0
  115. napier-0.1.0/pyproject.toml +101 -0
  116. napier-0.1.0/sources.yaml +1639 -0
  117. napier-0.1.0/specs/acid_rain_constellation.yaml +39 -0
  118. napier-0.1.0/specs/acid_rain_maestro.yaml +35 -0
  119. napier-0.1.0/specs/alm_akemies_castle.yaml +36 -0
  120. napier-0.1.0/specs/alm_mfd.yaml +24 -0
  121. napier-0.1.0/specs/alm_oax2.yaml +17 -0
  122. napier-0.1.0/specs/alm_pams_pro_workout.yaml +31 -0
  123. napier-0.1.0/specs/alm_ppexp1.yaml +14 -0
  124. napier-0.1.0/specs/bastl_ikarie.yaml +29 -0
  125. napier-0.1.0/specs/befaco_random8.yaml +15 -0
  126. napier-0.1.0/specs/boredbrain_optx_v2.yaml +36 -0
  127. napier-0.1.0/specs/divkid_manic.yaml +21 -0
  128. napier-0.1.0/specs/divkid_ochd.yaml +22 -0
  129. napier-0.1.0/specs/divkid_ochd_expander.yaml +34 -0
  130. napier-0.1.0/specs/entineering_midi_mult_1u.yaml +23 -0
  131. napier-0.1.0/specs/erica_sample_drum.yaml +30 -0
  132. napier-0.1.0/specs/hexinverter_mutant_machine.yaml +34 -0
  133. napier-0.1.0/specs/instruo_aradh.yaml +23 -0
  134. napier-0.1.0/specs/instruo_carn.yaml +34 -0
  135. napier-0.1.0/specs/instruo_ceithir.yaml +87 -0
  136. napier-0.1.0/specs/instruo_cnoc.yaml +20 -0
  137. napier-0.1.0/specs/instruo_csl.yaml +46 -0
  138. napier-0.1.0/specs/instruo_eas.yaml +30 -0
  139. napier-0.1.0/specs/instruo_larachd.yaml +30 -0
  140. napier-0.1.0/specs/instruo_neoni.yaml +28 -0
  141. napier-0.1.0/specs/intellijel_amps.yaml +19 -0
  142. napier-0.1.0/specs/intellijel_atlantix.yaml +59 -0
  143. napier-0.1.0/specs/intellijel_atlx_1u.yaml +31 -0
  144. napier-0.1.0/specs/intellijel_buff_mult_1u.yaml +28 -0
  145. napier-0.1.0/specs/intellijel_dual_vca_1u.yaml +19 -0
  146. napier-0.1.0/specs/intellijel_duatt_1u.yaml +20 -0
  147. napier-0.1.0/specs/intellijel_fsr_1u.yaml +12 -0
  148. napier-0.1.0/specs/intellijel_multigrain.yaml +13 -0
  149. napier-0.1.0/specs/intellijel_noise_tools.yaml +25 -0
  150. napier-0.1.0/specs/intellijel_octalink_1u.yaml +28 -0
  151. napier-0.1.0/specs/intellijel_passive_lpg_1u.yaml +20 -0
  152. napier-0.1.0/specs/intellijel_planar_2.yaml +12 -0
  153. napier-0.1.0/specs/intellijel_quadratt_1u.yaml +23 -0
  154. napier-0.1.0/specs/intellijel_quadrax.yaml +29 -0
  155. napier-0.1.0/specs/intellijel_sealegs.yaml +12 -0
  156. napier-0.1.0/specs/intellijel_steppy_1u.yaml +22 -0
  157. napier-0.1.0/specs/intellijel_stereo_line_out_1u.yaml +19 -0
  158. napier-0.1.0/specs/intellijel_swells.yaml +13 -0
  159. napier-0.1.0/specs/intellijel_tangrams.yaml +31 -0
  160. napier-0.1.0/specs/intellijel_zeroscope_1u.yaml +20 -0
  161. napier-0.1.0/specs/joranalogue_add_2.yaml +27 -0
  162. napier-0.1.0/specs/joranalogue_step_8.yaml +40 -0
  163. napier-0.1.0/specs/knobula_drum_farm.yaml +8 -0
  164. napier-0.1.0/specs/knobula_monumatic.yaml +21 -0
  165. napier-0.1.0/specs/koma_kmndr.yaml +19 -0
  166. napier-0.1.0/specs/lpzw_tram8.yaml +33 -0
  167. napier-0.1.0/specs/make_noise_maths.yaml +43 -0
  168. napier-0.1.0/specs/make_noise_midi_inlet.yaml +19 -0
  169. napier-0.1.0/specs/make_noise_multiwave.yaml +36 -0
  170. napier-0.1.0/specs/make_noise_polimaths.yaml +41 -0
  171. napier-0.1.0/specs/make_noise_qxg.yaml +35 -0
  172. napier-0.1.0/specs/msw_beehive.yaml +26 -0
  173. napier-0.1.0/specs/msw_nrings.yaml +28 -0
  174. napier-0.1.0/specs/mutable_beads.yaml +29 -0
  175. napier-0.1.0/specs/ne_expando_expandi.yaml +21 -0
  176. napier-0.1.0/specs/ne_lapsus_os.yaml +33 -0
  177. napier-0.1.0/specs/ne_mimetic_digitwolis.yaml +13 -0
  178. napier-0.1.0/specs/ne_xer_mixa.yaml +46 -0
  179. napier-0.1.0/specs/neutron_qvca.yaml +21 -0
  180. napier-0.1.0/specs/qubit_data_bender.yaml +33 -0
  181. napier-0.1.0/specs/ritual_guillotine.yaml +18 -0
  182. napier-0.1.0/specs/ritual_pointeuse.yaml +23 -0
  183. napier-0.1.0/specs/shakmat_bard_quartet.yaml +30 -0
  184. napier-0.1.0/specs/shakmat_bard_quartet_expander.yaml +25 -0
  185. napier-0.1.0/specs/shakmat_sumdif.yaml +25 -0
  186. napier-0.1.0/specs/soundforce_samples_ii.yaml +29 -0
  187. napier-0.1.0/specs/squarp_core.yaml +20 -0
  188. napier-0.1.0/specs/squarp_hermod_plus.yaml +48 -0
  189. napier-0.1.0/specs/squarp_xp32.yaml +45 -0
  190. napier-0.1.0/specs/ssf_metalloid.yaml +23 -0
  191. napier-0.1.0/specs/ssf_steady_state_gate.yaml +26 -0
  192. napier-0.1.0/specs/ssf_stereo_dipole.yaml +29 -0
  193. napier-0.1.0/specs/ssf_ultra_kick.yaml +25 -0
  194. napier-0.1.0/specs/ssf_ultra_perc.yaml +35 -0
  195. napier-0.1.0/specs/ssf_vortices.yaml +42 -0
  196. napier-0.1.0/specs/strymon_magneto.yaml +42 -0
  197. napier-0.1.0/specs/strymon_starlab.yaml +41 -0
  198. napier-0.1.0/specs/strymon_superkar_plus.yaml +28 -0
  199. napier-0.1.0/specs/venus_veno_orbit.yaml +40 -0
  200. napier-0.1.0/specs/vpme_t43.yaml +21 -0
  201. napier-0.1.0/specs/wmd_bus_rider.yaml +20 -0
  202. napier-0.1.0/specs/wmd_clutch.yaml +28 -0
  203. napier-0.1.0/specs/wmd_metron.yaml +42 -0
  204. napier-0.1.0/specs/wmd_voltera.yaml +21 -0
  205. napier-0.1.0/src/napier/__init__.py +16 -0
  206. napier-0.1.0/src/napier/auto.py +443 -0
  207. napier-0.1.0/src/napier/cli.py +986 -0
  208. napier-0.1.0/src/napier/evaluate.py +64 -0
  209. napier-0.1.0/src/napier/facts.py +165 -0
  210. napier-0.1.0/src/napier/htmlmd.py +112 -0
  211. napier-0.1.0/src/napier/mcp_server.py +232 -0
  212. napier-0.1.0/src/napier/parse.py +156 -0
  213. napier-0.1.0/src/napier/paths.py +158 -0
  214. napier-0.1.0/src/napier/rack.py +707 -0
  215. napier-0.1.0/src/napier/rack_sources.py +124 -0
  216. napier-0.1.0/src/napier/refresh.py +267 -0
  217. napier-0.1.0/src/napier/scenarios.py +306 -0
  218. napier-0.1.0/src/napier/search.py +113 -0
  219. napier-0.1.0/src/napier/sources.py +564 -0
  220. napier-0.1.0/src/napier/specs.py +183 -0
  221. napier-0.1.0/src/napier/store.py +202 -0
  222. napier-0.1.0/src/napier/text.py +274 -0
  223. napier-0.1.0/src/napier/viewer.py +507 -0
  224. napier-0.1.0/tests/conftest.py +15 -0
  225. napier-0.1.0/tests/test_auto.py +65 -0
  226. napier-0.1.0/tests/test_core.py +107 -0
  227. napier-0.1.0/tests/test_data.py +94 -0
  228. napier-0.1.0/tests/test_e2e_pdf.py +113 -0
  229. napier-0.1.0/tests/test_examples.py +57 -0
  230. napier-0.1.0/tests/test_mcp_and_eval.py +155 -0
  231. napier-0.1.0/tests/test_offset.py +34 -0
  232. napier-0.1.0/tests/test_overlay.py +112 -0
  233. napier-0.1.0/tests/test_polite.py +163 -0
  234. napier-0.1.0/tests/test_rack.py +232 -0
  235. napier-0.1.0/tests/test_readme.py +76 -0
  236. napier-0.1.0/tests/test_refresh.py +80 -0
  237. napier-0.1.0/tests/test_scenarios.py +74 -0
  238. napier-0.1.0/tests/test_security.py +98 -0
  239. napier-0.1.0/tests/test_specs.py +109 -0
  240. napier-0.1.0/tests/test_viewer.py +67 -0
  241. napier-0.1.0/uv.lock +4382 -0
@@ -0,0 +1,43 @@
1
+ name: Bug report
2
+ description: Something napier did wrong, or a crash
3
+ labels: [bug]
4
+ body:
5
+ - type: markdown
6
+ attributes:
7
+ value: |
8
+ Thanks for the report. Please leave out personal details (names, paths with your user name,
9
+ your own notes) and don't attach manuals. A security problem goes to the private form
10
+ instead: Security tab, "Report a vulnerability".
11
+ - type: textarea
12
+ id: what-happened
13
+ attributes:
14
+ label: What happened
15
+ description: The command you ran and what it did. Paste the error or traceback if there was one.
16
+ render: text
17
+ validations:
18
+ required: true
19
+ - type: textarea
20
+ id: expected
21
+ attributes:
22
+ label: What you expected
23
+ validations:
24
+ required: true
25
+ - type: input
26
+ id: version
27
+ attributes:
28
+ label: napier --version
29
+ placeholder: napier 0.1.0 (from /path/to/napier)
30
+ validations:
31
+ required: true
32
+ - type: input
33
+ id: os
34
+ attributes:
35
+ label: OS and Python version
36
+ placeholder: macOS 15.3 (Apple silicon), Python 3.12.8
37
+ validations:
38
+ required: true
39
+ - type: input
40
+ id: extras
41
+ attributes:
42
+ label: Extras installed
43
+ placeholder: none, index, mcp
@@ -0,0 +1,8 @@
1
+ blank_issues_enabled: false
2
+ contact_links:
3
+ - name: Questions and ideas
4
+ url: https://github.com/bvk7787/napier/discussions
5
+ about: How do I..., is my gear covered, show what you built. Issues are for bugs and requests.
6
+ - name: Report a security problem
7
+ url: https://github.com/bvk7787/napier/security/advisories/new
8
+ about: Privately, as SECURITY.md describes. Please don't open a public issue for it.
@@ -0,0 +1,21 @@
1
+ name: Feature request
2
+ description: An idea for napier
3
+ labels: [enhancement]
4
+ body:
5
+ - type: textarea
6
+ id: problem
7
+ attributes:
8
+ label: What you're trying to do
9
+ description: The problem or the workflow behind it.
10
+ validations:
11
+ required: true
12
+ - type: textarea
13
+ id: proposal
14
+ attributes:
15
+ label: What you'd like
16
+ validations:
17
+ required: true
18
+ - type: textarea
19
+ id: alternatives
20
+ attributes:
21
+ label: What you've tried or considered
@@ -0,0 +1,41 @@
1
+ name: Publisher request
2
+ description: For makers and publishers. Ask to remove, shorten or correct what napier lists from your documents
3
+ labels: [publisher-request]
4
+ body:
5
+ - type: markdown
6
+ attributes:
7
+ value: |
8
+ Thanks for getting in touch. docs/data-policy.md says what napier holds (links, checksums and
9
+ short quoted anchors; each user downloads the documents) and what you can ask for. A
10
+ maintainer answers within a week; removals are made first and discussed after.
11
+ - type: input
12
+ id: who
13
+ attributes:
14
+ label: Who you are
15
+ description: The company or publisher, and your role (or that you speak for them).
16
+ validations:
17
+ required: true
18
+ - type: textarea
19
+ id: what
20
+ attributes:
21
+ label: What it concerns
22
+ description: Source ids from sources.yaml, URLs, or the devices.
23
+ validations:
24
+ required: true
25
+ - type: dropdown
26
+ id: ask
27
+ attributes:
28
+ label: What you'd like
29
+ multiple: true
30
+ options:
31
+ - Remove the source entry, with its facts and anchors
32
+ - Shorten or remove particular anchors
33
+ - Point the entry at a different URL
34
+ - Correct a claim, a version or a page
35
+ - Something else (below)
36
+ validations:
37
+ required: true
38
+ - type: textarea
39
+ id: details
40
+ attributes:
41
+ label: Details
@@ -0,0 +1,35 @@
1
+ name: Source request
2
+ description: Ask for a manual, changelog or community document napier doesn't have yet
3
+ labels: [source]
4
+ body:
5
+ - type: markdown
6
+ attributes:
7
+ value: |
8
+ If you own the device, a pull request adding the source is the fastest route (CONTRIBUTING.md
9
+ shows the three commands). Otherwise, the details below are what a source needs.
10
+ - type: input
11
+ id: device
12
+ attributes:
13
+ label: Device
14
+ placeholder: Maker and model
15
+ validations:
16
+ required: true
17
+ - type: input
18
+ id: url
19
+ attributes:
20
+ label: Where the document lives
21
+ description: The maker's own link (PDF, changelog page, GitHub releases), and its version.
22
+ validations:
23
+ required: true
24
+ - type: dropdown
25
+ id: kind
26
+ attributes:
27
+ label: Kind
28
+ options: [manual, changelog, community, code]
29
+ validations:
30
+ required: true
31
+ - type: textarea
32
+ id: notes
33
+ attributes:
34
+ label: Anything else
35
+ description: Firmware version you run, questions you'd want answered from it, facts you've checked on the hardware.
@@ -0,0 +1,12 @@
1
+ # GitHub Actions only. The Python dependencies are lower bounds in pyproject.toml and locked in
2
+ # uv.lock for CI, updated by hand (`uv lock --upgrade`); the repository's Dependabot security
3
+ # updates open a PR for any locked version with a published advisory.
4
+ version: 2
5
+ updates:
6
+ - package-ecosystem: github-actions
7
+ directory: /
8
+ schedule:
9
+ interval: monthly
10
+ groups:
11
+ actions:
12
+ patterns: ["*"]
@@ -0,0 +1,14 @@
1
+ ## What this changes
2
+
3
+ <!-- What and why. Link the issue if there is one (sources and facts for gear you own don't need one). -->
4
+
5
+ ## Checks
6
+
7
+ - [ ] `pytest -q` and `ruff check src tests` pass, and a behavior change comes with a test
8
+ - [ ] For a new source: `source add` passed robots.txt (no `--ignore-robots` unless the publisher said yes, explained above), the manual is pinned, and the page offset was checked
9
+ - [ ] For new facts: status and printed pages are right; facts with `q` and `anchors` pass `napier eval --device <id>` (score above)
10
+ - [ ] For `hardware` facts: what I checked on the device, and on which firmware, is described above
11
+ - [ ] For specs: `napier specs check <name>` passes with the manual fetched
12
+ - [ ] No personal data: no real person, private rig or rack; fixtures use invented names and `example.test` URLs
13
+ - [ ] `rack export` and MCP JSON only gained fields; nothing renamed or removed
14
+ - [ ] Docs and CHANGELOG.md updated where behavior changed
@@ -0,0 +1,139 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ workflow_dispatch:
8
+
9
+ permissions:
10
+ contents: read
11
+
12
+ concurrency:
13
+ group: ci-${{ github.ref }}
14
+ cancel-in-progress: true
15
+
16
+ # Actions minutes are free on a public repository and metered on a private one, where the
17
+ # maintainer runs the same checks locally: every job skips while the repository is private.
18
+ jobs:
19
+ test:
20
+ name: test (${{ matrix.os }}, ${{ matrix.python-version }})
21
+ if: ${{ !github.event.repository.private }}
22
+ runs-on: ${{ matrix.os }}
23
+ timeout-minutes: 15
24
+ env:
25
+ PYTHONNOUSERSITE: "1"
26
+ strategy:
27
+ fail-fast: false
28
+ matrix:
29
+ include:
30
+ - {os: ubuntu-latest, python-version: "3.11"}
31
+ - {os: ubuntu-latest, python-version: "3.12", coverage: true}
32
+ - {os: ubuntu-latest, python-version: "3.13"}
33
+ - {os: ubuntu-latest, python-version: "3.14"}
34
+ - {os: macos-latest, python-version: "3.12"}
35
+ - {os: macos-latest, python-version: "3.14"}
36
+ steps:
37
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
38
+ with:
39
+ persist-credentials: false
40
+ - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
41
+ with:
42
+ python-version: ${{ matrix.python-version }}
43
+ cache: pip
44
+ # the versions in uv.lock, base + dev (which includes mcp): the tests need no network, models
45
+ # or manuals, so the [index] extra stays out
46
+ - name: Install (locked versions)
47
+ shell: bash
48
+ run: |
49
+ python -m pip install --upgrade pip uv
50
+ uv export --frozen --no-hashes --extra dev --no-emit-project > "$RUNNER_TEMP/requirements.lock.txt"
51
+ python -m pip install -r "$RUNNER_TEMP/requirements.lock.txt"
52
+ python -m pip install -e . --no-deps
53
+ - name: Lint
54
+ run: ruff check src tests
55
+ - name: Tests
56
+ if: ${{ !matrix.coverage }}
57
+ run: pytest -q
58
+ - name: Tests, with coverage
59
+ if: ${{ matrix.coverage }}
60
+ shell: bash
61
+ run: |
62
+ # 71% when this began (2026-10-13): the floor stops a drop, raise it as it climbs
63
+ pytest -q --cov --cov-report=term --cov-fail-under=70
64
+ coverage report --format=markdown >> "$GITHUB_STEP_SUMMARY"
65
+ - name: The CLI starts and finds its data
66
+ run: |
67
+ napier --version
68
+ napier status > /dev/null
69
+ napier source list --json > /dev/null
70
+ napier rack scenarios --brief
71
+
72
+ typecheck:
73
+ name: typecheck (mypy)
74
+ if: ${{ !github.event.repository.private }}
75
+ runs-on: ubuntu-latest
76
+ timeout-minutes: 10
77
+ steps:
78
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
79
+ with:
80
+ persist-credentials: false
81
+ - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
82
+ with:
83
+ python-version: "3.12"
84
+ cache: pip
85
+ - name: Install (locked versions)
86
+ shell: bash
87
+ run: |
88
+ python -m pip install --upgrade pip uv
89
+ uv export --frozen --no-hashes --extra dev --no-emit-project > "$RUNNER_TEMP/requirements.lock.txt"
90
+ python -m pip install -r "$RUNNER_TEMP/requirements.lock.txt"
91
+ python -m pip install -e . --no-deps
92
+ - name: mypy (settings in pyproject.toml)
93
+ run: mypy
94
+
95
+ package:
96
+ # what `pip install napier` gives someone who hasn't cloned: the sdist and wheel build, their
97
+ # metadata passes twine, and the installed command runs and points at the clone it needs
98
+ name: package (build, install, run)
99
+ if: ${{ !github.event.repository.private }}
100
+ runs-on: ubuntu-latest
101
+ timeout-minutes: 10
102
+ steps:
103
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
104
+ with:
105
+ persist-credentials: false
106
+ - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
107
+ with:
108
+ python-version: "3.12"
109
+ cache: pip
110
+ - name: Build the sdist and wheel
111
+ run: |
112
+ python -m pip install --upgrade pip uv
113
+ uv build
114
+ ls -l dist
115
+ - name: Check the metadata
116
+ run: uvx twine check --strict dist/*
117
+ - name: Check what the sdist holds
118
+ shell: bash
119
+ run: |
120
+ tar tzf dist/*.tar.gz > "$RUNNER_TEMP/sdist.txt"
121
+ for f in sources.yaml facts/ specs/ catalog/modules.yaml examples/racks/layout.yaml LICENSE NOTICE uv.lock; do
122
+ grep -q "$f" "$RUNNER_TEMP/sdist.txt" || { echo "missing from the sdist: $f"; exit 1; }
123
+ done
124
+ if grep -q "/local/" "$RUNNER_TEMP/sdist.txt"; then echo "the sdist holds a local/ overlay"; exit 1; fi
125
+ - name: Install the wheel into a clean venv
126
+ run: |
127
+ python -m venv "$RUNNER_TEMP/venv"
128
+ "$RUNNER_TEMP/venv/bin/pip" install dist/*.whl
129
+ - name: The installed command says where to get the data
130
+ working-directory: ${{ runner.temp }} # away from the checkout
131
+ shell: bash
132
+ run: |
133
+ export PATH="$RUNNER_TEMP/venv/bin:$PATH" NAPIER_HOME="$RUNNER_TEMP/home"
134
+ napier --version
135
+ napier --help > /dev/null
136
+ if napier status > out.txt 2>&1; then echo "status should fail outside a clone"; exit 1; fi
137
+ cat out.txt
138
+ grep -q "git clone https://github.com/bvk7787/napier" out.txt
139
+ if grep -q Traceback out.txt; then exit 1; fi
@@ -0,0 +1,65 @@
1
+ name: Release
2
+
3
+ # A version tag (v0.1.0) builds the package and publishes it to PyPI with Trusted Publishing:
4
+ # no token is stored anywhere. PyPI trusts this workflow once the project's trusted publisher
5
+ # names it (github.com/bvk7787/napier, workflow release.yml, environment pypi).
6
+ # The tag must match the version in pyproject.toml. Nothing runs while the repository is private.
7
+
8
+ on:
9
+ push:
10
+ tags: ["v*"]
11
+ workflow_dispatch:
12
+
13
+ permissions:
14
+ contents: read
15
+
16
+ jobs:
17
+ build:
18
+ if: ${{ !github.event.repository.private }}
19
+ runs-on: ubuntu-latest
20
+ timeout-minutes: 15
21
+ steps:
22
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
23
+ with:
24
+ persist-credentials: false
25
+ - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
26
+ with:
27
+ python-version: "3.12"
28
+ - name: The tag matches the version
29
+ if: startsWith(github.ref, 'refs/tags/')
30
+ shell: bash
31
+ run: |
32
+ want="v$(python -c 'import tomllib; print(tomllib.load(open("pyproject.toml","rb"))["project"]["version"])')"
33
+ [ "$GITHUB_REF_NAME" = "$want" ] || { echo "tag $GITHUB_REF_NAME, pyproject says $want"; exit 1; }
34
+ - name: Build the sdist and wheel
35
+ run: |
36
+ python -m pip install --upgrade pip build twine
37
+ python -m build
38
+ twine check --strict dist/*
39
+ - name: The wheel installs and runs
40
+ shell: bash
41
+ run: |
42
+ python -m venv "$RUNNER_TEMP/v"
43
+ "$RUNNER_TEMP/v/bin/pip" install dist/*.whl
44
+ "$RUNNER_TEMP/v/bin/napier" --version
45
+ - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
46
+ with:
47
+ name: dist
48
+ path: dist/
49
+
50
+ publish:
51
+ needs: build
52
+ if: ${{ !github.event.repository.private && startsWith(github.ref, 'refs/tags/') }}
53
+ runs-on: ubuntu-latest
54
+ timeout-minutes: 10
55
+ environment:
56
+ name: pypi
57
+ url: https://pypi.org/project/napier/
58
+ permissions:
59
+ id-token: write # Trusted Publishing: PyPI checks this workflow's identity
60
+ steps:
61
+ - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
62
+ with:
63
+ name: dist
64
+ path: dist/
65
+ - uses: pypa/gh-action-pypi-publish@dc37677b2e1c63e2034f94d8a5b11f265b73ba33 # v1.14.2
@@ -0,0 +1,41 @@
1
+ name: Scorecard
2
+
3
+ # OpenSSF Scorecard: checks the repository's security practices (branch protection, pinned
4
+ # actions, token permissions, signed releases, and more) and publishes the score for the
5
+ # README badge. Results land in the Security tab under Code scanning.
6
+
7
+ on:
8
+ push:
9
+ branches: [main]
10
+ schedule:
11
+ - cron: "17 6 * * 1" # Mondays
12
+ branch_protection_rule:
13
+ workflow_dispatch:
14
+
15
+ permissions: read-all
16
+
17
+ jobs:
18
+ analysis:
19
+ name: Scorecard analysis
20
+ runs-on: ubuntu-latest
21
+ timeout-minutes: 15
22
+ permissions:
23
+ security-events: write # upload the results to code scanning
24
+ id-token: write # publish the results (and the badge)
25
+ steps:
26
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
27
+ with:
28
+ persist-credentials: false
29
+ - uses: ossf/scorecard-action@2d1146689b8cda280b9bc96326124645441f03bc # v2.4.4
30
+ with:
31
+ results_file: results.sarif
32
+ results_format: sarif
33
+ publish_results: true
34
+ - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
35
+ with:
36
+ name: scorecard-results
37
+ path: results.sarif
38
+ retention-days: 5
39
+ - uses: github/codeql-action/upload-sarif@2892aa5e19bbd11bc0cff5427e3b750a04d9e3c2 # v4.38.2
40
+ with:
41
+ sarif_file: results.sarif
@@ -0,0 +1,15 @@
1
+ __pycache__/
2
+ *.pyc
3
+ .venv/
4
+ .pytest_cache/
5
+ *.egg-info/
6
+ dist/
7
+ build/
8
+ .DS_Store
9
+ # the private overlay (its own repo) and private agent notes
10
+ /local/
11
+ /CLAUDE.local.md
12
+ .coverage
13
+ coverage.xml
14
+ .mypy_cache/
15
+ .ruff_cache/
napier-0.1.0/AGENTS.md ADDED
@@ -0,0 +1,13 @@
1
+ # Instructions for coding agents
2
+
3
+ Helping someone *use* napier (look something up, add a source, check a fact, plan a rack)? Use the
4
+ CLI or the MCP tools and cite what they print: title, version, printed page. Changing its code or
5
+ data? Read on.
6
+
7
+ - Read [CLAUDE.md](CLAUDE.md) first: the ground rules (polite fetching, printed pages, facts are
8
+ refuted rather than deleted, nothing personal in the public tree), the layout, and the checks to
9
+ run.
10
+ - Contributing (tests, what a pull request needs): [CONTRIBUTING.md](CONTRIBUTING.md).
11
+ - The rack planner and rack-source plug-ins: [docs/rack.md](docs/rack.md).
12
+ - Never move data from a user's overlay (`local/`) into the public tree, and never write names,
13
+ rack URLs or rig notes into public files or commit messages.
@@ -0,0 +1,44 @@
1
+ # Changelog
2
+
3
+ All notable changes to napier are recorded here. The format follows
4
+ [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and versions follow
5
+ [Semantic Versioning](https://semver.org/spec/v2.0.0.html) (before 1.0, a minor version may change
6
+ the CLI or the data formats).
7
+
8
+ ## [Unreleased]
9
+
10
+ ## [0.1.0] - 2026-10-13
11
+
12
+ First public release.
13
+
14
+ ### Added
15
+
16
+ - Sources: manuals, firmware changelogs, forum snapshots, pinned firmware source and your own notes,
17
+ with printed-page offsets detected from the page footers. 149 sources for 101 devices ship with it.
18
+ - `grep` and `read` over a text layer (one unit per printed page or section), and hybrid `search`
19
+ (vectors and BM25, fused, reranked) with pinned model revisions. Every result cites title,
20
+ version and printed page, and says which kind of source it came from.
21
+ - The facts ledger (`manual`, `changelog`, `community`, `code`, `hardware`, `unverified`,
22
+ `refuted`) and `napier eval`, which fails below 90% hit@3.
23
+ - `source check`, `source apply` and `facts recheck` for keeping sources current, and
24
+ `napier refresh`, an unattended pass for maintainers that opens a pull request.
25
+ - An MCP server (`napier mcp`) with `status`, `search`, `grep`, `read`, `facts`, `add_fact`,
26
+ `verify_fact` and `rack`. Errors reach the assistant with their reason; `grep` and `search` list
27
+ the sources they couldn't search yet; facts it writes are stamped `via: mcp`.
28
+ - A Eurorack rack planner: rack sources (built-in `file`, plug-ins under `napier.rack_sources`),
29
+ configurable case geometry, usage notes, what-if scenarios with power, distance and free-space
30
+ checks, manual-cited specs, and `rack view`.
31
+ - A private overlay (`local/`) for your own sources, facts, rack and notes, merged at run time and
32
+ never committed to the public repository.
33
+ - Polite fetching on every request: robots.txt per RFC 9309 (including `Crawl-delay` and
34
+ redirects), at least 2 seconds between requests to a site, backoff on 429 and 503, an honest user
35
+ agent. `fetch --from FILE` for documents a site doesn't allow napier to download.
36
+ - Limits on what a source list or document can do: plain-name ids, http(s) only, no private or local
37
+ addresses, a 300 MB and 10-minute cap per download, and a guard against runaway regexes.
38
+ - `napier status` summarizes per device (`--wide` for every source); unknown device or source ids
39
+ suggest the closest names.
40
+ - docs: MCP setup for Claude Desktop, Claude Code, Cursor, VS Code, Codex and Windsurf; sources;
41
+ how it works; the rack planner; the data policy and a publisher request form.
42
+
43
+ [Unreleased]: https://github.com/bvk7787/napier/compare/v0.1.0...HEAD
44
+ [0.1.0]: https://github.com/bvk7787/napier/releases/tag/v0.1.0
@@ -0,0 +1,11 @@
1
+ cff-version: 1.2.0
2
+ message: "If you refer to napier in writing, please cite it as below."
3
+ title: "napier"
4
+ abstract: "Page-cited lookups in music hardware manuals, changelogs and community documents, with a ledger of checked facts, a search eval and a Eurorack rack planner, as a CLI and an MCP server."
5
+ type: software
6
+ authors:
7
+ - name: "The napier authors"
8
+ repository-code: "https://github.com/bvk7787/napier"
9
+ license: Apache-2.0
10
+ version: 0.1.0
11
+ keywords: [music hardware, manuals, synthesizer, eurorack, mcp, search, citations]
@@ -0,0 +1,134 @@
1
+ # Contributor Covenant Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ We as members, contributors, and leaders pledge to make participation in our
6
+ community a harassment-free experience for everyone, regardless of age, body
7
+ size, visible or invisible disability, ethnicity, sex characteristics, gender
8
+ identity and expression, level of experience, education, socio-economic status,
9
+ nationality, personal appearance, race, caste, color, religion, or sexual
10
+ identity and orientation.
11
+
12
+ We pledge to act and interact in ways that contribute to an open, welcoming,
13
+ diverse, inclusive, and healthy community.
14
+
15
+ ## Our Standards
16
+
17
+ Examples of behavior that contributes to a positive environment for our
18
+ community include:
19
+
20
+ * Demonstrating empathy and kindness toward other people
21
+ * Being respectful of differing opinions, viewpoints, and experiences
22
+ * Giving and gracefully accepting constructive feedback
23
+ * Accepting responsibility and apologizing to those affected by our mistakes,
24
+ and learning from the experience
25
+ * Focusing on what is best not just for us as individuals, but for the overall
26
+ community
27
+
28
+ Examples of unacceptable behavior include:
29
+
30
+ * The use of sexualized language or imagery, and sexual attention or advances of
31
+ any kind
32
+ * Trolling, insulting or derogatory comments, and personal or political attacks
33
+ * Public or private harassment
34
+ * Publishing others' private information, such as a physical or email address,
35
+ without their explicit permission
36
+ * Other conduct which could reasonably be considered inappropriate in a
37
+ professional setting
38
+
39
+ ## Enforcement Responsibilities
40
+
41
+ Community leaders are responsible for clarifying and enforcing our standards of
42
+ acceptable behavior and will take appropriate and fair corrective action in
43
+ response to any behavior that they deem inappropriate, threatening, offensive,
44
+ or harmful.
45
+
46
+ Community leaders have the right and responsibility to remove, edit, or reject
47
+ comments, commits, code, wiki edits, issues, and other contributions that are
48
+ not aligned to this Code of Conduct, and will communicate reasons for moderation
49
+ decisions when appropriate.
50
+
51
+ ## Scope
52
+
53
+ This Code of Conduct applies within all community spaces, and also applies when
54
+ an individual is officially representing the community in public spaces.
55
+ Examples of representing our community include using an official e-mail address,
56
+ posting via an official social media account, or acting as an appointed
57
+ representative at an online or offline event.
58
+
59
+ ## Enforcement
60
+
61
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
62
+ reported to the community leaders responsible for enforcement, the project's
63
+ maintainers, privately through GitHub: use the repository's private reporting form
64
+ (the **Security** tab, **Report a vulnerability**) and say that it is a conduct
65
+ report, or report the content to GitHub with its **Report content** option.
66
+ All complaints will be reviewed and investigated promptly and fairly.
67
+
68
+ All community leaders are obligated to respect the privacy and security of the
69
+ reporter of any incident.
70
+
71
+ ## Enforcement Guidelines
72
+
73
+ Community leaders will follow these Community Impact Guidelines in determining
74
+ the consequences for any action they deem in violation of this Code of Conduct:
75
+
76
+ ### 1. Correction
77
+
78
+ **Community Impact**: Use of inappropriate language or other behavior deemed
79
+ unprofessional or unwelcome in the community.
80
+
81
+ **Consequence**: A private, written warning from community leaders, providing
82
+ clarity around the nature of the violation and an explanation of why the
83
+ behavior was inappropriate. A public apology may be requested.
84
+
85
+ ### 2. Warning
86
+
87
+ **Community Impact**: A violation through a single incident or series of
88
+ actions.
89
+
90
+ **Consequence**: A warning with consequences for continued behavior. No
91
+ interaction with the people involved, including unsolicited interaction with
92
+ those enforcing the Code of Conduct, for a specified period of time. This
93
+ includes avoiding interactions in community spaces as well as external channels
94
+ like social media. Violating these terms may lead to a temporary or permanent
95
+ ban.
96
+
97
+ ### 3. Temporary Ban
98
+
99
+ **Community Impact**: A serious violation of community standards, including
100
+ sustained inappropriate behavior.
101
+
102
+ **Consequence**: A temporary ban from any sort of interaction or public
103
+ communication with the community for a specified period of time. No public or
104
+ private interaction with the people involved, including unsolicited interaction
105
+ with those enforcing the Code of Conduct, is allowed during this period.
106
+ Violating these terms may lead to a permanent ban.
107
+
108
+ ### 4. Permanent Ban
109
+
110
+ **Community Impact**: Demonstrating a pattern of violation of community
111
+ standards, including sustained inappropriate behavior, harassment of an
112
+ individual, or aggression toward or disparagement of classes of individuals.
113
+
114
+ **Consequence**: A permanent ban from any sort of public interaction within the
115
+ community.
116
+
117
+ ## Attribution
118
+
119
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage],
120
+ version 2.1, available at
121
+ [https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1].
122
+
123
+ Community Impact Guidelines were inspired by
124
+ [Mozilla's code of conduct enforcement ladder][Mozilla CoC].
125
+
126
+ For answers to common questions about this code of conduct, see the FAQ at
127
+ [https://www.contributor-covenant.org/faq][FAQ]. Translations are available at
128
+ [https://www.contributor-covenant.org/translations][translations].
129
+
130
+ [homepage]: https://www.contributor-covenant.org
131
+ [v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html
132
+ [Mozilla CoC]: https://github.com/mozilla/diversity
133
+ [FAQ]: https://www.contributor-covenant.org/faq
134
+ [translations]: https://www.contributor-covenant.org/translations