voice-mode 4.0.1__py3-none-any.whl → 4.2.0__py3-none-any.whl

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 (78) hide show
  1. voice_mode/__version__.py +1 -1
  2. voice_mode/cli.py +73 -0
  3. voice_mode/cli_commands/claude.py +208 -0
  4. voice_mode/cli_commands/hook.py +197 -0
  5. voice_mode/cli_commands/pronounce_commands.py +223 -0
  6. voice_mode/config.py +25 -0
  7. voice_mode/data/default_pronunciation.yaml +268 -0
  8. voice_mode/frontend/.next/BUILD_ID +1 -1
  9. voice_mode/frontend/.next/app-build-manifest.json +5 -5
  10. voice_mode/frontend/.next/build-manifest.json +3 -3
  11. voice_mode/frontend/.next/next-minimal-server.js.nft.json +1 -1
  12. voice_mode/frontend/.next/next-server.js.nft.json +1 -1
  13. voice_mode/frontend/.next/prerender-manifest.json +1 -1
  14. voice_mode/frontend/.next/required-server-files.json +1 -1
  15. voice_mode/frontend/.next/server/app/_not-found/page.js +1 -1
  16. voice_mode/frontend/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  17. voice_mode/frontend/.next/server/app/_not-found.html +1 -1
  18. voice_mode/frontend/.next/server/app/_not-found.rsc +1 -1
  19. voice_mode/frontend/.next/server/app/api/connection-details/route.js +2 -2
  20. voice_mode/frontend/.next/server/app/favicon.ico/route.js +2 -2
  21. voice_mode/frontend/.next/server/app/index.html +1 -1
  22. voice_mode/frontend/.next/server/app/index.rsc +2 -2
  23. voice_mode/frontend/.next/server/app/page.js +2 -2
  24. voice_mode/frontend/.next/server/app/page_client-reference-manifest.js +1 -1
  25. voice_mode/frontend/.next/server/chunks/994.js +1 -1
  26. voice_mode/frontend/.next/server/middleware-build-manifest.js +1 -1
  27. voice_mode/frontend/.next/server/next-font-manifest.js +1 -1
  28. voice_mode/frontend/.next/server/next-font-manifest.json +1 -1
  29. voice_mode/frontend/.next/server/pages/404.html +1 -1
  30. voice_mode/frontend/.next/server/pages/500.html +1 -1
  31. voice_mode/frontend/.next/server/server-reference-manifest.json +1 -1
  32. voice_mode/frontend/.next/standalone/.next/BUILD_ID +1 -1
  33. voice_mode/frontend/.next/standalone/.next/app-build-manifest.json +5 -5
  34. voice_mode/frontend/.next/standalone/.next/build-manifest.json +3 -3
  35. voice_mode/frontend/.next/standalone/.next/prerender-manifest.json +1 -1
  36. voice_mode/frontend/.next/standalone/.next/required-server-files.json +1 -1
  37. voice_mode/frontend/.next/standalone/.next/server/app/_not-found/page.js +1 -1
  38. voice_mode/frontend/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  39. voice_mode/frontend/.next/standalone/.next/server/app/_not-found.html +1 -1
  40. voice_mode/frontend/.next/standalone/.next/server/app/_not-found.rsc +1 -1
  41. voice_mode/frontend/.next/standalone/.next/server/app/api/connection-details/route.js +2 -2
  42. voice_mode/frontend/.next/standalone/.next/server/app/favicon.ico/route.js +2 -2
  43. voice_mode/frontend/.next/standalone/.next/server/app/index.html +1 -1
  44. voice_mode/frontend/.next/standalone/.next/server/app/index.rsc +2 -2
  45. voice_mode/frontend/.next/standalone/.next/server/app/page.js +2 -2
  46. voice_mode/frontend/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  47. voice_mode/frontend/.next/standalone/.next/server/chunks/994.js +1 -1
  48. voice_mode/frontend/.next/standalone/.next/server/middleware-build-manifest.js +1 -1
  49. voice_mode/frontend/.next/standalone/.next/server/next-font-manifest.js +1 -1
  50. voice_mode/frontend/.next/standalone/.next/server/next-font-manifest.json +1 -1
  51. voice_mode/frontend/.next/standalone/.next/server/pages/404.html +1 -1
  52. voice_mode/frontend/.next/standalone/.next/server/pages/500.html +1 -1
  53. voice_mode/frontend/.next/standalone/.next/server/server-reference-manifest.json +1 -1
  54. voice_mode/frontend/.next/standalone/server.js +1 -1
  55. voice_mode/frontend/.next/static/chunks/app/layout-df4aba5e7309efec.js +1 -0
  56. voice_mode/frontend/.next/static/chunks/app/page-a87d04099ce6aeb2.js +1 -0
  57. voice_mode/frontend/.next/static/chunks/{main-app-233f6c633f73ae84.js → main-app-ca62791c49278d6d.js} +1 -1
  58. voice_mode/frontend/.next/trace +43 -43
  59. voice_mode/frontend/.next/types/app/api/connection-details/route.ts +1 -1
  60. voice_mode/frontend/.next/types/app/layout.ts +1 -1
  61. voice_mode/frontend/.next/types/app/page.ts +1 -1
  62. voice_mode/frontend/package-lock.json +3 -3
  63. voice_mode/pronounce.py +397 -0
  64. voice_mode/tools/claude_thinking.py +285 -0
  65. voice_mode/tools/converse.py +11 -0
  66. voice_mode/tools/pronounce.py +245 -0
  67. voice_mode/tools/sound_fonts/__init__.py +1 -0
  68. voice_mode/tools/sound_fonts/audio_player.py +87 -0
  69. voice_mode/tools/sound_fonts/hook_handler.py +127 -0
  70. voice_mode/tools/sound_fonts/player.py +180 -0
  71. {voice_mode-4.0.1.dist-info → voice_mode-4.2.0.dist-info}/METADATA +1 -1
  72. {voice_mode-4.0.1.dist-info → voice_mode-4.2.0.dist-info}/RECORD +76 -65
  73. voice_mode/frontend/.next/static/chunks/app/layout-0074dd8ab91cdbe0.js +0 -1
  74. voice_mode/frontend/.next/static/chunks/app/page-ae5f3aa9d9ba5993.js +0 -1
  75. /voice_mode/frontend/.next/static/{c5TIe90lGzrESrqJkkXQa → FTYM9NyY_2zq92GYxPDhS}/_buildManifest.js +0 -0
  76. /voice_mode/frontend/.next/static/{c5TIe90lGzrESrqJkkXQa → FTYM9NyY_2zq92GYxPDhS}/_ssgManifest.js +0 -0
  77. {voice_mode-4.0.1.dist-info → voice_mode-4.2.0.dist-info}/WHEEL +0 -0
  78. {voice_mode-4.0.1.dist-info → voice_mode-4.2.0.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,223 @@
1
+ """CLI commands for managing pronunciation rules."""
2
+
3
+ import click
4
+ import yaml
5
+ import json
6
+ from pathlib import Path
7
+ from typing import Optional
8
+
9
+ from voice_mode.pronounce import get_manager
10
+
11
+
12
+ @click.group(name='pronounce')
13
+ def pronounce_group():
14
+ """Manage pronunciation rules for TTS and STT."""
15
+ pass
16
+
17
+
18
+ @pronounce_group.command(name='list')
19
+ @click.option('--direction', '-d', type=click.Choice(['tts', 'stt', 'all']), default='all',
20
+ help='Filter by direction (tts/stt/all)')
21
+ @click.option('--enabled-only', '-e', is_flag=True, help='Show only enabled rules')
22
+ @click.option('--show-private', '-p', is_flag=True, help='Include private rules')
23
+ @click.option('--format', '-f', type=click.Choice(['table', 'yaml', 'json']), default='table',
24
+ help='Output format')
25
+ def list_rules(direction: str, enabled_only: bool, show_private: bool, format: str):
26
+ """List pronunciation rules."""
27
+ manager = get_manager()
28
+
29
+ # Get rules
30
+ if direction == 'all':
31
+ rules = manager.list_rules(include_private=show_private)
32
+ else:
33
+ rules = manager.list_rules(direction=direction, include_private=show_private)
34
+
35
+ # Filter if needed
36
+ if enabled_only:
37
+ rules = [r for r in rules if r['enabled']]
38
+
39
+ # Format output
40
+ if format == 'table':
41
+ if not rules:
42
+ click.echo("No rules found.")
43
+ return
44
+
45
+ # Count private rules that were hidden
46
+ all_rules = manager.list_rules(include_private=True)
47
+ private_count = len(all_rules) - len(rules)
48
+
49
+ # Simple table format without tabulate
50
+ click.echo("\nPronunciation Rules:")
51
+ click.echo("=" * 80)
52
+
53
+ for rule in rules:
54
+ status = '✓' if rule['enabled'] else '✗'
55
+ click.echo(f"\n{status} [{rule['direction'].upper()}] {rule['name']} (order: {rule['order']})")
56
+ click.echo(f" Pattern: {rule['pattern']}")
57
+ click.echo(f" Replace: {rule['replacement']}")
58
+ if rule['description']:
59
+ click.echo(f" Desc: {rule['description']}")
60
+
61
+ if private_count > 0 and not show_private:
62
+ click.echo(f"\n({private_count} private rules hidden. Use --show-private to display)")
63
+
64
+ elif format == 'yaml':
65
+ import yaml
66
+ click.echo(yaml.dump(rules, default_flow_style=False))
67
+
68
+ elif format == 'json':
69
+ import json
70
+ click.echo(json.dumps(rules, indent=2))
71
+
72
+
73
+ @pronounce_group.command(name='test')
74
+ @click.argument('text')
75
+ @click.option('--direction', '-d', type=click.Choice(['tts', 'stt']), default='tts',
76
+ help='Test direction (tts/stt)')
77
+ def test_rule(text: str, direction: str):
78
+ """Test pronunciation rules on text."""
79
+ manager = get_manager()
80
+ result = manager.test_rule(text, direction)
81
+
82
+ if text != result:
83
+ click.echo(f"Original: {text}")
84
+ click.echo(f"Modified: {result}")
85
+
86
+ # Show which rules were applied if logging is enabled
87
+ import os
88
+ if os.environ.get('VOICEMODE_PRONUNCIATION_LOG_SUBSTITUTIONS', '').lower() == 'true':
89
+ click.echo("\n(Check logs for applied rules)")
90
+ else:
91
+ click.echo(f"No changes: {text}")
92
+
93
+
94
+ @pronounce_group.command(name='add')
95
+ @click.option('--direction', '-d', type=click.Choice(['tts', 'stt']), required=True,
96
+ help='Rule direction (tts/stt)')
97
+ @click.option('--pattern', '-p', required=True, help='Regex pattern to match')
98
+ @click.option('--replacement', '-r', required=True, help='Replacement text')
99
+ @click.option('--name', '-n', help='Rule name (auto-generated if not provided)')
100
+ @click.option('--description', help='Rule description')
101
+ @click.option('--order', type=int, default=100, help='Processing order (lower = earlier)')
102
+ @click.option('--disabled', is_flag=True, help='Create rule as disabled')
103
+ def add_rule(direction: str, pattern: str, replacement: str, name: Optional[str],
104
+ description: str, order: int, disabled: bool):
105
+ """Add a new pronunciation rule."""
106
+ manager = get_manager()
107
+
108
+ success = manager.add_rule(
109
+ direction=direction,
110
+ pattern=pattern,
111
+ replacement=replacement,
112
+ name=name,
113
+ description=description or "",
114
+ enabled=not disabled,
115
+ order=order,
116
+ private=False # CLI-created rules are not private
117
+ )
118
+
119
+ if success:
120
+ click.echo(f"✓ Rule added successfully")
121
+ else:
122
+ click.echo("✗ Failed to add rule (check pattern validity)", err=True)
123
+
124
+
125
+ @pronounce_group.command(name='remove')
126
+ @click.option('--direction', '-d', type=click.Choice(['tts', 'stt']), required=True,
127
+ help='Rule direction (tts/stt)')
128
+ @click.argument('name')
129
+ def remove_rule(direction: str, name: str):
130
+ """Remove a pronunciation rule by name."""
131
+ manager = get_manager()
132
+
133
+ success = manager.remove_rule(direction, name)
134
+
135
+ if success:
136
+ click.echo(f"✓ Rule '{name}' removed")
137
+ else:
138
+ click.echo(f"✗ Rule '{name}' not found", err=True)
139
+
140
+
141
+ @pronounce_group.command(name='enable')
142
+ @click.option('--direction', '-d', type=click.Choice(['tts', 'stt']), required=True,
143
+ help='Rule direction (tts/stt)')
144
+ @click.argument('name')
145
+ def enable_rule(direction: str, name: str):
146
+ """Enable a pronunciation rule."""
147
+ manager = get_manager()
148
+
149
+ success = manager.enable_rule(direction, name)
150
+
151
+ if success:
152
+ click.echo(f"✓ Rule '{name}' enabled")
153
+ else:
154
+ click.echo(f"✗ Failed to enable rule '{name}' (not found or private)", err=True)
155
+
156
+
157
+ @pronounce_group.command(name='disable')
158
+ @click.option('--direction', '-d', type=click.Choice(['tts', 'stt']), required=True,
159
+ help='Rule direction (tts/stt)')
160
+ @click.argument('name')
161
+ def disable_rule(direction: str, name: str):
162
+ """Disable a pronunciation rule."""
163
+ manager = get_manager()
164
+
165
+ success = manager.disable_rule(direction, name)
166
+
167
+ if success:
168
+ click.echo(f"✓ Rule '{name}' disabled")
169
+ else:
170
+ click.echo(f"✗ Failed to disable rule '{name}' (not found or private)", err=True)
171
+
172
+
173
+ @pronounce_group.command(name='reload')
174
+ def reload_rules():
175
+ """Reload pronunciation rules from configuration files."""
176
+ manager = get_manager()
177
+ manager.reload_rules()
178
+ click.echo("✓ Pronunciation rules reloaded")
179
+
180
+
181
+ @pronounce_group.command(name='edit')
182
+ @click.option('--system', is_flag=True, help='Edit system default rules (requires sudo)')
183
+ def edit_config(system: bool):
184
+ """Open pronunciation config in editor."""
185
+ import os
186
+ import subprocess
187
+
188
+ if system:
189
+ # Edit system defaults
190
+ config_path = Path(__file__).parent.parent / 'data' / 'default_pronunciation.yaml'
191
+ if not config_path.exists():
192
+ click.echo(f"System config not found: {config_path}", err=True)
193
+ return
194
+ # Might need sudo
195
+ editor = os.environ.get('EDITOR', 'nano')
196
+ subprocess.run(['sudo', editor, str(config_path)])
197
+ else:
198
+ # Edit user config
199
+ config_path = Path.home() / '.voicemode' / 'config' / 'pronunciation.yaml'
200
+ if not config_path.exists():
201
+ # Create default config
202
+ config_path.parent.mkdir(parents=True, exist_ok=True)
203
+ default_config = {
204
+ 'version': 1,
205
+ 'tts_rules': [],
206
+ 'stt_rules': []
207
+ }
208
+ with open(config_path, 'w') as f:
209
+ yaml.dump(default_config, f, default_flow_style=False)
210
+
211
+ editor = os.environ.get('EDITOR', 'nano')
212
+ subprocess.run([editor, str(config_path)])
213
+
214
+ # Reload after editing
215
+ manager = get_manager()
216
+ manager.reload_rules()
217
+ click.echo("✓ Configuration edited and reloaded")
218
+
219
+
220
+ # Register the command group
221
+ def register_commands(cli):
222
+ """Register pronunciation commands with the main CLI."""
223
+ cli.add_command(pronounce_group)
voice_mode/config.py CHANGED
@@ -841,3 +841,28 @@ def get_format_export_params(format: str) -> dict:
841
841
  pass
842
842
 
843
843
  return params
844
+
845
+ # ==================== THINK OUT LOUD CONFIGURATION ====================
846
+
847
+ # Enable Think Out Loud mode
848
+ THINK_OUT_LOUD_ENABLED = env_bool("VOICEMODE_THINK_OUT_LOUD", False)
849
+
850
+ # Voice persona mappings for thinking roles (role:voice pairs)
851
+ # Default: analytical:am_adam,creative:af_sarah,critical:af_bella,synthesis:af_nova
852
+ THINKING_VOICES_STR = os.getenv(
853
+ "VOICEMODE_THINKING_VOICES",
854
+ "analytical:am_adam,creative:af_sarah,critical:af_bella,synthesis:af_nova"
855
+ )
856
+
857
+ # Parse thinking voices into a dictionary
858
+ THINKING_VOICES = {}
859
+ for pair in THINKING_VOICES_STR.split(","):
860
+ if ":" in pair:
861
+ role, voice = pair.strip().split(":", 1)
862
+ THINKING_VOICES[role.strip()] = voice.strip()
863
+
864
+ # Thinking presentation style: sequential, debate, or chorus
865
+ THINKING_STYLE = os.getenv("VOICEMODE_THINKING_STYLE", "sequential")
866
+
867
+ # Whether to announce which voice is speaking
868
+ THINKING_ANNOUNCE_VOICE = env_bool("VOICEMODE_THINKING_ANNOUNCE_VOICE", True)
@@ -0,0 +1,268 @@
1
+ version: 1
2
+ tts_rules:
3
+ # Company names
4
+ - name: "3m_company"
5
+ order: 10
6
+ pattern: '\b3M\b'
7
+ replacement: 'three em'
8
+ enabled: true
9
+ description: "Pronounce 3M company name correctly"
10
+ private: false
11
+
12
+ # Networking terms
13
+ - name: "poe_acronym"
14
+ order: 20
15
+ pattern: '\bPoE\+?\b'
16
+ replacement: 'P O E'
17
+ enabled: true
18
+ description: "Power over Ethernet acronym"
19
+ private: false
20
+
21
+ - name: "gigabit_ethernet"
22
+ order: 30
23
+ pattern: '\b(\d+(?:\.\d+)?)\s*GbE\b'
24
+ replacement: '$1 gigabit ethernet'
25
+ enabled: true
26
+ description: "Expand GbE to gigabit ethernet with number"
27
+ private: false
28
+
29
+ - name: "tcp_ip"
30
+ order: 40
31
+ pattern: '\bTCP/IP\b'
32
+ replacement: 'T C P I P'
33
+ enabled: true
34
+ description: "Pronounce TCP/IP as individual letters"
35
+ private: false
36
+
37
+ - name: "ssh"
38
+ order: 50
39
+ pattern: '\bSSH\b'
40
+ replacement: 'S S H'
41
+ enabled: true
42
+ description: "Pronounce SSH as individual letters"
43
+ private: false
44
+
45
+ - name: "https"
46
+ order: 60
47
+ pattern: '\bHTTPS\b'
48
+ replacement: 'H T T P S'
49
+ enabled: true
50
+ description: "Pronounce HTTPS as individual letters"
51
+ private: false
52
+
53
+ # Model numbers and versions
54
+ - name: "unifi_u7"
55
+ order: 70
56
+ pattern: '\bU7\b'
57
+ replacement: 'U seven'
58
+ enabled: true
59
+ description: "UniFi U7 model number"
60
+ private: false
61
+
62
+ - name: "wifi_6e"
63
+ order: 80
64
+ pattern: '\bWiFi 6E\b'
65
+ replacement: 'wifi six E'
66
+ enabled: true
67
+ description: "WiFi 6E standard"
68
+ private: false
69
+
70
+ - name: "wifi_7"
71
+ order: 90
72
+ pattern: '\bWiFi 7\b'
73
+ replacement: 'wifi seven'
74
+ enabled: true
75
+ description: "WiFi 7 standard"
76
+ private: false
77
+
78
+ # Units and measurements
79
+ - name: "gigahertz"
80
+ order: 100
81
+ pattern: '\b(\d+(?:\.\d+)?)\s*GHz\b'
82
+ replacement: '$1 gigahertz'
83
+ enabled: true
84
+ description: "Expand GHz to gigahertz"
85
+ private: false
86
+
87
+ - name: "megahertz"
88
+ order: 110
89
+ pattern: '\b(\d+(?:\.\d+)?)\s*MHz\b'
90
+ replacement: '$1 megahertz'
91
+ enabled: true
92
+ description: "Expand MHz to megahertz"
93
+ private: false
94
+
95
+ - name: "gigabytes"
96
+ order: 120
97
+ pattern: '\b(\d+(?:\.\d+)?)\s*GB\b'
98
+ replacement: '$1 gigabytes'
99
+ enabled: true
100
+ description: "Expand GB to gigabytes"
101
+ private: false
102
+
103
+ - name: "terabytes"
104
+ order: 130
105
+ pattern: '\b(\d+(?:\.\d+)?)\s*TB\b'
106
+ replacement: '$1 terabytes'
107
+ enabled: true
108
+ description: "Expand TB to terabytes"
109
+ private: false
110
+
111
+ - name: "milliseconds"
112
+ order: 140
113
+ pattern: '\b(\d+(?:\.\d+)?)\s*ms\b'
114
+ replacement: '$1 milliseconds'
115
+ enabled: true
116
+ description: "Expand ms to milliseconds"
117
+ private: false
118
+
119
+ # Cloud providers
120
+ - name: "aws"
121
+ order: 150
122
+ pattern: '\bAWS\b'
123
+ replacement: 'A W S'
124
+ enabled: true
125
+ description: "Amazon Web Services"
126
+ private: false
127
+
128
+ - name: "gcp"
129
+ order: 160
130
+ pattern: '\bGCP\b'
131
+ replacement: 'G C P'
132
+ enabled: true
133
+ description: "Google Cloud Platform"
134
+ private: false
135
+
136
+ # Programming terms
137
+ - name: "json"
138
+ order: 170
139
+ pattern: '\bJSON\b'
140
+ replacement: 'jason'
141
+ enabled: true
142
+ description: "Pronounce JSON as Jason"
143
+ private: false
144
+
145
+ - name: "yaml"
146
+ order: 180
147
+ pattern: '\bYAML\b'
148
+ replacement: 'yammel'
149
+ enabled: true
150
+ description: "Pronounce YAML as yammel"
151
+ private: false
152
+
153
+ - name: "api"
154
+ order: 190
155
+ pattern: '\bAPI\b'
156
+ replacement: 'A P I'
157
+ enabled: true
158
+ description: "Pronounce API as individual letters"
159
+ private: false
160
+
161
+ - name: "cli"
162
+ order: 200
163
+ pattern: '\bCLI\b'
164
+ replacement: 'C L I'
165
+ enabled: true
166
+ description: "Command Line Interface"
167
+ private: false
168
+
169
+ # Project specific
170
+ - name: "mcp"
171
+ order: 210
172
+ pattern: '\bMCP\b'
173
+ replacement: 'M C P'
174
+ enabled: true
175
+ description: "Model Context Protocol"
176
+ private: false
177
+
178
+ - name: "tts"
179
+ order: 220
180
+ pattern: '\bTTS\b'
181
+ replacement: 'T T S'
182
+ enabled: true
183
+ description: "Text to Speech"
184
+ private: false
185
+
186
+ - name: "stt"
187
+ order: 230
188
+ pattern: '\bSTT\b'
189
+ replacement: 'S T T'
190
+ enabled: true
191
+ description: "Speech to Text"
192
+ private: false
193
+
194
+ stt_rules:
195
+ # Common Whisper mishearings
196
+ - name: "metool_correction"
197
+ order: 10
198
+ pattern: '\bme tool\b'
199
+ replacement: 'metool'
200
+ enabled: true
201
+ description: "Correct Whisper hearing 'me tool' as two words"
202
+ private: false
203
+
204
+ - name: "cora_seven"
205
+ order: 20
206
+ pattern: '\bcora 7\b'
207
+ replacement: 'Cora 7'
208
+ enabled: true
209
+ description: "Ensure proper capitalization of Cora 7"
210
+ private: false
211
+
212
+ - name: "ai_cora"
213
+ order: 30
214
+ pattern: '\bAI cora\b'
215
+ replacement: 'ai-cora'
216
+ enabled: true
217
+ description: "GitHub username format"
218
+ private: false
219
+
220
+ # Programming terms often misheard
221
+ - name: "python_capital"
222
+ order: 40
223
+ pattern: '\bpython\b'
224
+ replacement: 'Python'
225
+ enabled: true
226
+ description: "Capitalize Python language name"
227
+ private: false
228
+
229
+ - name: "github_capital"
230
+ order: 50
231
+ pattern: '\bgithub\b'
232
+ replacement: 'GitHub'
233
+ enabled: true
234
+ description: "Correct GitHub capitalization"
235
+ private: false
236
+
237
+ - name: "tmux_spelling"
238
+ order: 60
239
+ pattern: '\b(tee mux|t mux|teamux)\b'
240
+ replacement: 'tmux'
241
+ enabled: true
242
+ description: "Correct various tmux mishearings"
243
+ private: false
244
+
245
+ - name: "neovim_spelling"
246
+ order: 70
247
+ pattern: '\b(neo vim|neovem|neovam)\b'
248
+ replacement: 'Neovim'
249
+ enabled: true
250
+ description: "Correct Neovim mishearings"
251
+ private: false
252
+
253
+ # Common phrases
254
+ - name: "lets_contraction"
255
+ order: 80
256
+ pattern: '\blet us\b'
257
+ replacement: "let's"
258
+ enabled: true
259
+ description: "Contract 'let us' to let's"
260
+ private: false
261
+
262
+ - name: "its_contraction"
263
+ order: 90
264
+ pattern: '\bit is\b'
265
+ replacement: "it's"
266
+ enabled: false # Disabled by default as it can be wrong
267
+ description: "Contract 'it is' to it's (use carefully)"
268
+ private: false
@@ -1 +1 @@
1
- c5TIe90lGzrESrqJkkXQa
1
+ FTYM9NyY_2zq92GYxPDhS
@@ -4,25 +4,25 @@
4
4
  "static/chunks/webpack-0ea9b80f19935b70.js",
5
5
  "static/chunks/fd9d1056-af324d327b243cf1.js",
6
6
  "static/chunks/117-40bc79a2b97edb21.js",
7
- "static/chunks/main-app-233f6c633f73ae84.js",
7
+ "static/chunks/main-app-ca62791c49278d6d.js",
8
8
  "static/chunks/app/_not-found/page-5011050e402ab9c8.js"
9
9
  ],
10
10
  "/layout": [
11
11
  "static/chunks/webpack-0ea9b80f19935b70.js",
12
12
  "static/chunks/fd9d1056-af324d327b243cf1.js",
13
13
  "static/chunks/117-40bc79a2b97edb21.js",
14
- "static/chunks/main-app-233f6c633f73ae84.js",
14
+ "static/chunks/main-app-ca62791c49278d6d.js",
15
15
  "static/css/a2f49a47752b5010.css",
16
- "static/chunks/app/layout-0074dd8ab91cdbe0.js"
16
+ "static/chunks/app/layout-df4aba5e7309efec.js"
17
17
  ],
18
18
  "/page": [
19
19
  "static/chunks/webpack-0ea9b80f19935b70.js",
20
20
  "static/chunks/fd9d1056-af324d327b243cf1.js",
21
21
  "static/chunks/117-40bc79a2b97edb21.js",
22
- "static/chunks/main-app-233f6c633f73ae84.js",
22
+ "static/chunks/main-app-ca62791c49278d6d.js",
23
23
  "static/chunks/144d3bae-2d5f122b82426d88.js",
24
24
  "static/chunks/471-bd4b96a33883dfa2.js",
25
- "static/chunks/app/page-ae5f3aa9d9ba5993.js"
25
+ "static/chunks/app/page-a87d04099ce6aeb2.js"
26
26
  ]
27
27
  }
28
28
  }
@@ -5,14 +5,14 @@
5
5
  "devFiles": [],
6
6
  "ampDevFiles": [],
7
7
  "lowPriorityFiles": [
8
- "static/c5TIe90lGzrESrqJkkXQa/_buildManifest.js",
9
- "static/c5TIe90lGzrESrqJkkXQa/_ssgManifest.js"
8
+ "static/FTYM9NyY_2zq92GYxPDhS/_buildManifest.js",
9
+ "static/FTYM9NyY_2zq92GYxPDhS/_ssgManifest.js"
10
10
  ],
11
11
  "rootMainFiles": [
12
12
  "static/chunks/webpack-0ea9b80f19935b70.js",
13
13
  "static/chunks/fd9d1056-af324d327b243cf1.js",
14
14
  "static/chunks/117-40bc79a2b97edb21.js",
15
- "static/chunks/main-app-233f6c633f73ae84.js"
15
+ "static/chunks/main-app-ca62791c49278d6d.js"
16
16
  ],
17
17
  "pages": {
18
18
  "/_app": [
@@ -1 +1 @@
1
- {"version":1,"files":["../node_modules/styled-jsx/index.js","../node_modules/styled-jsx/package.json","../node_modules/styled-jsx/dist/index/index.js","../node_modules/react/package.json","../node_modules/react/index.js","../node_modules/client-only/package.json","../node_modules/react/cjs/react.production.min.js","../node_modules/client-only/index.js","../node_modules/styled-jsx/style.js","../node_modules/next/dist/compiled/next-server/server.runtime.prod.js","../node_modules/next/package.json","../node_modules/next/dist/lib/constants.js","../node_modules/next/dist/server/body-streams.js","../node_modules/next/dist/lib/picocolors.js","../node_modules/next/dist/shared/lib/constants.js","../node_modules/next/dist/server/web/utils.js","../node_modules/next/dist/client/components/app-router-headers.js","../node_modules/next/dist/server/lib/trace/tracer.js","../node_modules/next/dist/server/lib/trace/constants.js","../node_modules/next/dist/client/components/static-generation-async-storage.external.js","../node_modules/next/dist/shared/lib/error-source.js","../node_modules/next/dist/shared/lib/modern-browserslist-target.js","../node_modules/next/dist/compiled/debug/package.json","../node_modules/next/dist/client/components/static-generation-async-storage-instance.js","../node_modules/next/dist/shared/lib/runtime-config.external.js","../node_modules/next/dist/compiled/debug/index.js","../node_modules/next/dist/compiled/ws/package.json","../node_modules/next/dist/compiled/node-html-parser/package.json","../node_modules/next/dist/compiled/lru-cache/package.json","../node_modules/@swc/helpers/_/_interop_require_default/package.json","../node_modules/next/dist/compiled/ws/index.js","../node_modules/next/dist/compiled/node-html-parser/index.js","../node_modules/next/dist/compiled/lru-cache/index.js","../node_modules/next/dist/client/components/async-local-storage.js","../node_modules/next/dist/compiled/@opentelemetry/api/package.json","../node_modules/@swc/helpers/package.json","../node_modules/next/dist/client/components/react-dev-overlay/internal/helpers/parseStack.js","../node_modules/next/dist/client/components/react-dev-overlay/internal/helpers/nodeStackFrames.js","../node_modules/next/dist/compiled/jsonwebtoken/package.json","../node_modules/next/dist/client/components/react-dev-overlay/server/middleware.js","../node_modules/@swc/helpers/cjs/_interop_require_default.cjs","../node_modules/next/dist/compiled/@opentelemetry/api/index.js","../node_modules/next/dist/compiled/jsonwebtoken/index.js","../node_modules/next/dist/compiled/browserslist/package.json","../node_modules/next/dist/compiled/browserslist/index.js","../node_modules/next/dist/client/components/react-dev-overlay/server/shared.js","../node_modules/next/dist/client/components/react-dev-overlay/internal/helpers/getRawSourceMap.js","../node_modules/next/dist/client/components/react-dev-overlay/internal/helpers/launchEditor.js","../node_modules/next/dist/compiled/babel/code-frame.js","../node_modules/next/dist/compiled/json5/package.json","../node_modules/next/dist/compiled/semver/package.json","../node_modules/next/dist/compiled/babel/package.json","../node_modules/next/dist/lib/semver-noop.js","../node_modules/next/dist/compiled/json5/index.js","../node_modules/next/dist/compiled/semver/index.js","../node_modules/next/dist/compiled/stacktrace-parser/package.json","../node_modules/next/dist/compiled/source-map08/package.json","../node_modules/caniuse-lite/dist/unpacker/agents.js","../node_modules/caniuse-lite/dist/unpacker/feature.js","../node_modules/caniuse-lite/dist/unpacker/region.js","../node_modules/next/dist/compiled/babel/bundle.js","../node_modules/next/dist/client/components/react-dev-overlay/internal/helpers/getSourceMapUrl.js","../node_modules/next/dist/compiled/stacktrace-parser/stack-trace-parser.cjs.js","../node_modules/next/dist/compiled/source-map08/source-map.js","../node_modules/caniuse-lite/package.json","../node_modules/next/dist/compiled/babel/core.js","../node_modules/caniuse-lite/data/agents.js","../node_modules/caniuse-lite/dist/unpacker/browsers.js","../node_modules/caniuse-lite/dist/unpacker/browserVersions.js","../node_modules/caniuse-lite/dist/lib/statuses.js","../node_modules/caniuse-lite/dist/lib/supported.js","../node_modules/next/dist/compiled/data-uri-to-buffer/package.json","../node_modules/next/dist/compiled/shell-quote/package.json","../node_modules/next/dist/compiled/data-uri-to-buffer/index.js","../node_modules/next/dist/compiled/shell-quote/index.js","../node_modules/caniuse-lite/data/browsers.js","../node_modules/caniuse-lite/data/browserVersions.js","../node_modules/next/dist/compiled/babel-packages/package.json","../node_modules/next/dist/compiled/babel-packages/packages-bundle.js","../node_modules/next/dist/compiled/babel/parser.js","../node_modules/next/dist/compiled/babel/traverse.js","../node_modules/next/dist/compiled/babel/types.js","../node_modules/next/dist/server/future/route-modules/app-page/vendored/contexts/amp-context.js","../node_modules/next/dist/server/future/route-modules/app-page/vendored/contexts/app-router-context.js","../node_modules/next/dist/server/future/route-modules/app-page/vendored/contexts/entrypoints.js","../node_modules/next/dist/server/future/route-modules/app-page/vendored/contexts/head-manager-context.js","../node_modules/next/dist/server/future/route-modules/app-page/vendored/contexts/hooks-client-context.js","../node_modules/next/dist/server/future/route-modules/app-page/vendored/contexts/html-context.js","../node_modules/next/dist/server/future/route-modules/app-page/vendored/contexts/image-config-context.js","../node_modules/next/dist/server/future/route-modules/app-page/vendored/contexts/loadable-context.js","../node_modules/next/dist/server/future/route-modules/app-page/vendored/contexts/loadable.js","../node_modules/next/dist/server/future/route-modules/app-page/vendored/contexts/router-context.js","../node_modules/next/dist/server/future/route-modules/app-page/vendored/contexts/server-inserted-html.js","../node_modules/next/dist/server/future/route-modules/app-page/module.compiled.js","../node_modules/next/dist/server/future/route-modules/pages/vendored/contexts/amp-context.js","../node_modules/next/dist/server/future/route-modules/pages/vendored/contexts/app-router-context.js","../node_modules/next/dist/server/future/route-modules/pages/vendored/contexts/entrypoints.js","../node_modules/next/dist/server/future/route-modules/pages/vendored/contexts/head-manager-context.js","../node_modules/next/dist/server/future/route-modules/pages/vendored/contexts/hooks-client-context.js","../node_modules/next/dist/server/future/route-modules/pages/vendored/contexts/html-context.js","../node_modules/next/dist/server/future/route-modules/pages/vendored/contexts/image-config-context.js","../node_modules/next/dist/server/future/route-modules/pages/vendored/contexts/loadable-context.js","../node_modules/next/dist/server/future/route-modules/pages/vendored/contexts/loadable.js","../node_modules/next/dist/server/future/route-modules/pages/vendored/contexts/router-context.js","../node_modules/next/dist/server/future/route-modules/pages/vendored/contexts/server-inserted-html.js","../node_modules/next/dist/server/future/route-modules/pages/module.compiled.js"]}
1
+ {"version":1,"files":["../node_modules/styled-jsx/index.js","../node_modules/styled-jsx/package.json","../node_modules/styled-jsx/dist/index/index.js","../node_modules/react/package.json","../node_modules/react/index.js","../node_modules/client-only/package.json","../node_modules/react/cjs/react.production.min.js","../node_modules/client-only/index.js","../node_modules/styled-jsx/style.js","../node_modules/next/dist/compiled/next-server/server.runtime.prod.js","../node_modules/next/package.json","../node_modules/next/dist/lib/constants.js","../node_modules/next/dist/server/body-streams.js","../node_modules/next/dist/lib/picocolors.js","../node_modules/next/dist/shared/lib/constants.js","../node_modules/next/dist/server/web/utils.js","../node_modules/next/dist/client/components/app-router-headers.js","../node_modules/next/dist/server/lib/trace/tracer.js","../node_modules/next/dist/server/lib/trace/constants.js","../node_modules/next/dist/client/components/static-generation-async-storage.external.js","../node_modules/next/dist/shared/lib/error-source.js","../node_modules/next/dist/shared/lib/modern-browserslist-target.js","../node_modules/next/dist/compiled/debug/package.json","../node_modules/next/dist/client/components/static-generation-async-storage-instance.js","../node_modules/next/dist/shared/lib/runtime-config.external.js","../node_modules/next/dist/compiled/debug/index.js","../node_modules/next/dist/compiled/ws/package.json","../node_modules/next/dist/compiled/node-html-parser/package.json","../node_modules/next/dist/compiled/lru-cache/package.json","../node_modules/@swc/helpers/_/_interop_require_default/package.json","../node_modules/next/dist/compiled/ws/index.js","../node_modules/next/dist/compiled/node-html-parser/index.js","../node_modules/next/dist/compiled/lru-cache/index.js","../node_modules/next/dist/client/components/async-local-storage.js","../node_modules/next/dist/compiled/@opentelemetry/api/package.json","../node_modules/@swc/helpers/package.json","../node_modules/next/dist/client/components/react-dev-overlay/internal/helpers/parseStack.js","../node_modules/next/dist/client/components/react-dev-overlay/internal/helpers/nodeStackFrames.js","../node_modules/next/dist/compiled/jsonwebtoken/package.json","../node_modules/next/dist/client/components/react-dev-overlay/server/middleware.js","../node_modules/@swc/helpers/cjs/_interop_require_default.cjs","../node_modules/next/dist/compiled/@opentelemetry/api/index.js","../node_modules/next/dist/compiled/jsonwebtoken/index.js","../node_modules/next/dist/compiled/browserslist/package.json","../node_modules/next/dist/compiled/browserslist/index.js","../node_modules/next/dist/client/components/react-dev-overlay/server/shared.js","../node_modules/next/dist/client/components/react-dev-overlay/internal/helpers/getRawSourceMap.js","../node_modules/next/dist/client/components/react-dev-overlay/internal/helpers/launchEditor.js","../node_modules/next/dist/compiled/babel/code-frame.js","../node_modules/next/dist/compiled/json5/package.json","../node_modules/next/dist/compiled/semver/package.json","../node_modules/next/dist/compiled/babel/package.json","../node_modules/next/dist/lib/semver-noop.js","../node_modules/next/dist/compiled/json5/index.js","../node_modules/next/dist/compiled/semver/index.js","../node_modules/next/dist/compiled/stacktrace-parser/package.json","../node_modules/next/dist/compiled/source-map08/package.json","../node_modules/caniuse-lite/dist/unpacker/agents.js","../node_modules/caniuse-lite/dist/unpacker/feature.js","../node_modules/caniuse-lite/dist/unpacker/region.js","../node_modules/next/dist/compiled/babel/bundle.js","../node_modules/next/dist/client/components/react-dev-overlay/internal/helpers/getSourceMapUrl.js","../node_modules/next/dist/compiled/stacktrace-parser/stack-trace-parser.cjs.js","../node_modules/next/dist/compiled/source-map08/source-map.js","../node_modules/caniuse-lite/package.json","../node_modules/next/dist/compiled/babel/core.js","../node_modules/caniuse-lite/data/agents.js","../node_modules/caniuse-lite/dist/unpacker/browsers.js","../node_modules/caniuse-lite/dist/unpacker/browserVersions.js","../node_modules/caniuse-lite/dist/lib/statuses.js","../node_modules/caniuse-lite/dist/lib/supported.js","../node_modules/next/dist/compiled/data-uri-to-buffer/package.json","../node_modules/next/dist/compiled/shell-quote/package.json","../node_modules/next/dist/compiled/data-uri-to-buffer/index.js","../node_modules/next/dist/compiled/shell-quote/index.js","../node_modules/caniuse-lite/data/browserVersions.js","../node_modules/caniuse-lite/data/browsers.js","../node_modules/next/dist/compiled/babel-packages/package.json","../node_modules/next/dist/compiled/babel-packages/packages-bundle.js","../node_modules/next/dist/compiled/babel/traverse.js","../node_modules/next/dist/compiled/babel/parser.js","../node_modules/next/dist/compiled/babel/types.js","../node_modules/next/dist/server/future/route-modules/app-page/vendored/contexts/amp-context.js","../node_modules/next/dist/server/future/route-modules/app-page/vendored/contexts/app-router-context.js","../node_modules/next/dist/server/future/route-modules/app-page/vendored/contexts/entrypoints.js","../node_modules/next/dist/server/future/route-modules/app-page/vendored/contexts/head-manager-context.js","../node_modules/next/dist/server/future/route-modules/app-page/vendored/contexts/hooks-client-context.js","../node_modules/next/dist/server/future/route-modules/app-page/vendored/contexts/html-context.js","../node_modules/next/dist/server/future/route-modules/app-page/vendored/contexts/image-config-context.js","../node_modules/next/dist/server/future/route-modules/app-page/vendored/contexts/loadable-context.js","../node_modules/next/dist/server/future/route-modules/app-page/vendored/contexts/loadable.js","../node_modules/next/dist/server/future/route-modules/app-page/vendored/contexts/router-context.js","../node_modules/next/dist/server/future/route-modules/app-page/vendored/contexts/server-inserted-html.js","../node_modules/next/dist/server/future/route-modules/app-page/module.compiled.js","../node_modules/next/dist/server/future/route-modules/pages/vendored/contexts/amp-context.js","../node_modules/next/dist/server/future/route-modules/pages/vendored/contexts/app-router-context.js","../node_modules/next/dist/server/future/route-modules/pages/vendored/contexts/entrypoints.js","../node_modules/next/dist/server/future/route-modules/pages/vendored/contexts/head-manager-context.js","../node_modules/next/dist/server/future/route-modules/pages/vendored/contexts/hooks-client-context.js","../node_modules/next/dist/server/future/route-modules/pages/vendored/contexts/html-context.js","../node_modules/next/dist/server/future/route-modules/pages/vendored/contexts/image-config-context.js","../node_modules/next/dist/server/future/route-modules/pages/vendored/contexts/loadable-context.js","../node_modules/next/dist/server/future/route-modules/pages/vendored/contexts/loadable.js","../node_modules/next/dist/server/future/route-modules/pages/vendored/contexts/router-context.js","../node_modules/next/dist/server/future/route-modules/pages/vendored/contexts/server-inserted-html.js","../node_modules/next/dist/server/future/route-modules/pages/module.compiled.js"]}