namzy 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.
namzy-0.1.0/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ __pycache__/
2
+ *.egg-info/
3
+ dist/
4
+ build/
5
+ .venv/
@@ -0,0 +1,8 @@
1
+ {
2
+ "session_id": "53d9fa2f-6fc7-4ab8-ac23-dbc85451de77",
3
+ "ended_at": "2026-05-15T13:20:39.777Z",
4
+ "reason": "prompt_input_exit",
5
+ "agents_spawned": 4,
6
+ "agents_completed": 4,
7
+ "modes_used": []
8
+ }
namzy-0.1.0/CLAUDE.md ADDED
@@ -0,0 +1,11 @@
1
+ <claude-mem-context>
2
+ # Recent Activity
3
+
4
+ <!-- This section is auto-generated by claude-mem. Edit content outside the tags. -->
5
+
6
+ ### May 15, 2026
7
+
8
+ | ID | Time | T | Title | Read |
9
+ |----|------|---|-------|------|
10
+ | #7072 | 3:19 PM | 🟣 | Multi-language namzy implementation across TypeScript, Python, C++, and Rust | ~746 |
11
+ </claude-mem-context>
namzy-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,80 @@
1
+ Metadata-Version: 2.4
2
+ Name: namzy
3
+ Version: 0.1.0
4
+ Summary: Generate fun human-friendly project names
5
+ License: MIT
6
+ Keywords: fun,generator,name,project
7
+ Classifier: License :: OSI Approved :: MIT License
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: Programming Language :: Python :: 3.10
10
+ Classifier: Programming Language :: Python :: 3.11
11
+ Classifier: Programming Language :: Python :: 3.12
12
+ Requires-Python: >=3.10
13
+ Description-Content-Type: text/markdown
14
+
15
+ # namzy
16
+
17
+ Generate fun, human-friendly project names — seeded by time, mangled for personality.
18
+
19
+ ## Install
20
+
21
+ ```bash
22
+ pip install namzy
23
+ # or run without installing:
24
+ uvx namzy
25
+ ```
26
+
27
+ ## CLI usage
28
+
29
+ ```bash
30
+ # One name, single word (default)
31
+ namzy
32
+
33
+ # Multiple names
34
+ namzy --count 5
35
+
36
+ # Output shapes
37
+ namzy --shape single # e.g. Tokyuriver
38
+ namzy --shape joined # e.g. TokyuRiver
39
+ namzy --shape spaced # e.g. Tokyu River
40
+
41
+ # Reproducible output
42
+ namzy --seed 42 --count 3
43
+
44
+ # Fetch words from a public API (falls back to offline on error)
45
+ namzy --online --count 3
46
+ ```
47
+
48
+ ## Library usage
49
+
50
+ ```python
51
+ from namzy import generate
52
+
53
+ # Single word (default)
54
+ name = generate()
55
+
56
+ # Joined PascalCase
57
+ name = generate(shape="joined")
58
+
59
+ # Spaced words
60
+ name = generate(shape="spaced")
61
+
62
+ # Reproducible
63
+ name = generate(seed=42)
64
+
65
+ # Online mode
66
+ name = generate(online=True)
67
+ ```
68
+
69
+ ## Modes
70
+
71
+ - **Offline** (default): Uses a bundled wordlist of ~40 geographic names and ~40 evocative English nouns. No network required.
72
+ - **Online**: Fetches two words from `random-word-api.herokuapp.com`. Falls back silently to offline on any error.
73
+
74
+ ## Mangling
75
+
76
+ Names pass through a phonetic mangling pass: `tion→shun`, `ight→ite`, `oo→u`, `ck→kk`, `ph→f`, `ks→x`, trailing `s→z`. One or two substitutions apply randomly per word.
77
+
78
+ ## License
79
+
80
+ MIT
namzy-0.1.0/README.md ADDED
@@ -0,0 +1,66 @@
1
+ # namzy
2
+
3
+ Generate fun, human-friendly project names — seeded by time, mangled for personality.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ pip install namzy
9
+ # or run without installing:
10
+ uvx namzy
11
+ ```
12
+
13
+ ## CLI usage
14
+
15
+ ```bash
16
+ # One name, single word (default)
17
+ namzy
18
+
19
+ # Multiple names
20
+ namzy --count 5
21
+
22
+ # Output shapes
23
+ namzy --shape single # e.g. Tokyuriver
24
+ namzy --shape joined # e.g. TokyuRiver
25
+ namzy --shape spaced # e.g. Tokyu River
26
+
27
+ # Reproducible output
28
+ namzy --seed 42 --count 3
29
+
30
+ # Fetch words from a public API (falls back to offline on error)
31
+ namzy --online --count 3
32
+ ```
33
+
34
+ ## Library usage
35
+
36
+ ```python
37
+ from namzy import generate
38
+
39
+ # Single word (default)
40
+ name = generate()
41
+
42
+ # Joined PascalCase
43
+ name = generate(shape="joined")
44
+
45
+ # Spaced words
46
+ name = generate(shape="spaced")
47
+
48
+ # Reproducible
49
+ name = generate(seed=42)
50
+
51
+ # Online mode
52
+ name = generate(online=True)
53
+ ```
54
+
55
+ ## Modes
56
+
57
+ - **Offline** (default): Uses a bundled wordlist of ~40 geographic names and ~40 evocative English nouns. No network required.
58
+ - **Online**: Fetches two words from `random-word-api.herokuapp.com`. Falls back silently to offline on any error.
59
+
60
+ ## Mangling
61
+
62
+ Names pass through a phonetic mangling pass: `tion→shun`, `ight→ite`, `oo→u`, `ck→kk`, `ph→f`, `ks→x`, trailing `s→z`. One or two substitutions apply randomly per word.
63
+
64
+ ## License
65
+
66
+ MIT
@@ -0,0 +1,28 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "namzy"
7
+ version = "0.1.0"
8
+ description = "Generate fun human-friendly project names"
9
+ readme = "README.md"
10
+ license = { text = "MIT" }
11
+ requires-python = ">=3.10"
12
+ keywords = ["name", "generator", "project", "fun"]
13
+ classifiers = [
14
+ "License :: OSI Approved :: MIT License",
15
+ "Programming Language :: Python :: 3",
16
+ "Programming Language :: Python :: 3.10",
17
+ "Programming Language :: Python :: 3.11",
18
+ "Programming Language :: Python :: 3.12",
19
+ ]
20
+
21
+ [project.scripts]
22
+ namzy = "namzy.cli:main"
23
+
24
+ [tool.hatch.version]
25
+ path = "src/namzy/__init__.py"
26
+
27
+ [tool.hatch.build.targets.wheel]
28
+ packages = ["src/namzy"]
Binary file
@@ -0,0 +1,7 @@
1
+ <claude-mem-context>
2
+ # Recent Activity
3
+
4
+ <!-- This section is auto-generated by claude-mem. Edit content outside the tags. -->
5
+
6
+ *No recent activity*
7
+ </claude-mem-context>
@@ -0,0 +1,58 @@
1
+ # this_file: src/namzy/__init__.py
2
+ """namzy — fun human-friendly project name generator."""
3
+
4
+ from __future__ import annotations
5
+
6
+ import random
7
+ import time
8
+
9
+ from ._mangle import join_clean, mangle
10
+ from ._wordlist import COMMON, GEO
11
+
12
+ __version__ = "0.2.0"
13
+
14
+ __all__ = ["generate"]
15
+
16
+ _ONLINE_URL_TWO = "https://random-word-api.herokuapp.com/word?number=2&length=6"
17
+
18
+
19
+ def _fetch_online() -> list[str] | None:
20
+ """Fetch two words from a public API. Returns None on any error."""
21
+ try:
22
+ import json
23
+ import urllib.request
24
+
25
+ with urllib.request.urlopen(_ONLINE_URL_TWO, timeout=3) as resp:
26
+ data = json.loads(resp.read().decode())
27
+ if isinstance(data, list):
28
+ words = [w for w in data if w.isalpha()]
29
+ if len(words) >= 2:
30
+ return words[:2]
31
+ except Exception:
32
+ pass
33
+ return None
34
+
35
+
36
+ def _pick_words(rng: random.Random, online: bool) -> tuple[str, str]:
37
+ """Return two raw lowercase words."""
38
+ if online:
39
+ fetched = _fetch_online()
40
+ if fetched:
41
+ return fetched[0].lower(), fetched[1].lower()
42
+ return rng.choice(GEO).lower(), rng.choice(COMMON).lower()
43
+
44
+
45
+ def generate(online: bool = False, seed: int | None = None) -> str:
46
+ """Generate a fun project name.
47
+
48
+ Picks two words, fuses them with junction cleanup, applies consonant
49
+ rotation, and capitalizes the first letter.
50
+ """
51
+ if seed is None:
52
+ seed = time.time_ns()
53
+ rng = random.Random(seed)
54
+
55
+ a, b = _pick_words(rng, online)
56
+ fused = join_clean(a, b)
57
+ rotated = mangle(fused)
58
+ return rotated[:1].upper() + rotated[1:]
@@ -0,0 +1,7 @@
1
+ # this_file: src/namzy/__main__.py
2
+ """Allow running as: python -m namzy"""
3
+
4
+ from .cli import main
5
+
6
+ if __name__ == "__main__":
7
+ main()
@@ -0,0 +1,52 @@
1
+ # this_file: src/namzy/_mangle.py
2
+ """Consonant-rotation mangling and word-junction cleanup."""
3
+
4
+ from __future__ import annotations
5
+
6
+ _ROT = {
7
+ "c": "q",
8
+ "f": "v",
9
+ "k": "c",
10
+ "q": "k",
11
+ "s": "z",
12
+ "z": "s",
13
+ "v": "f",
14
+ "w": "u",
15
+ }
16
+
17
+ _VOWELS = frozenset("aeiouy")
18
+
19
+
20
+ def _rot_char(ch: str) -> str:
21
+ low = ch.lower()
22
+ if low in _ROT:
23
+ sub = _ROT[low]
24
+ return sub.upper() if ch.isupper() else sub
25
+ return ch
26
+
27
+
28
+ def mangle(s: str) -> str:
29
+ """Apply per-letter consonant rotation, case-preserving."""
30
+ return "".join(_rot_char(c) for c in s)
31
+
32
+
33
+ def join_clean(a: str, b: str) -> str:
34
+ """Fuse two raw lowercase words, smoothing the junction.
35
+
36
+ Up to two passes: drop first char of tail if it duplicates the last char
37
+ of head (case-insensitive), or if both are vowels.
38
+ """
39
+ head = a
40
+ tail = b
41
+ for _ in range(2):
42
+ if not head or not tail:
43
+ break
44
+ h = head[-1].lower()
45
+ t = tail[0].lower()
46
+ if h == t:
47
+ tail = tail[1:]
48
+ elif h in _VOWELS and t in _VOWELS:
49
+ tail = tail[1:]
50
+ else:
51
+ break
52
+ return head + tail
@@ -0,0 +1,18 @@
1
+ # this_file: src/namzy/_wordlist.py
2
+ """Bundled word lists for offline name generation."""
3
+
4
+ GEO = (
5
+ "tokyo", "paris", "oslo", "berlin", "lagos", "lima", "boston", "vienna",
6
+ "cairo", "kyoto", "delhi", "milan", "rome", "seoul", "dubai", "athens",
7
+ "nairobi", "bali", "oslo", "havana", "lisbon", "tunis", "bogota", "dakar",
8
+ "quito", "darwin", "perth", "bruges", "riga", "minsk", "sofia", "vilna",
9
+ "vaduz", "bern", "accra", "kigali", "abuja", "bamako", "niamey", "lome",
10
+ )
11
+
12
+ COMMON = (
13
+ "river", "stone", "ember", "frost", "harbor", "willow", "copper", "marble",
14
+ "anchor", "lantern", "cedar", "falcon", "drift", "mesa", "grove", "canyon",
15
+ "basin", "fern", "gale", "haven", "peak", "ridge", "shore", "tide",
16
+ "vale", "bluff", "brook", "crest", "delta", "flint", "glen", "helm",
17
+ "inlet", "jetty", "knoll", "loft", "moor", "notch", "orbit", "prism",
18
+ )
@@ -0,0 +1,43 @@
1
+ # this_file: src/namzy/cli.py
2
+ """CLI entrypoint for namzy."""
3
+
4
+ from __future__ import annotations
5
+
6
+ import argparse
7
+ import time
8
+
9
+ from . import generate
10
+
11
+
12
+ def main() -> None:
13
+ parser = argparse.ArgumentParser(
14
+ prog="namzy",
15
+ description="Generate fun human-friendly project names.",
16
+ )
17
+ parser.add_argument(
18
+ "--online",
19
+ action="store_true",
20
+ default=False,
21
+ help="Fetch words from a public API (falls back to offline on error)",
22
+ )
23
+ parser.add_argument(
24
+ "--count",
25
+ type=int,
26
+ default=1,
27
+ metavar="N",
28
+ help="Number of names to generate (default: 1)",
29
+ )
30
+ parser.add_argument(
31
+ "--seed",
32
+ type=int,
33
+ default=None,
34
+ metavar="INT",
35
+ help="Random seed for reproducible output",
36
+ )
37
+
38
+ args = parser.parse_args()
39
+
40
+ base_seed = args.seed if args.seed is not None else time.time_ns()
41
+
42
+ for i in range(args.count):
43
+ print(generate(online=args.online, seed=base_seed + i))