sybl 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.
- sybl-0.1.0/.cursor/rules/maintain-agents-md.mdc +34 -0
- sybl-0.1.0/.cursor/rules/no-coauthor-commits.mdc +9 -0
- sybl-0.1.0/.githooks/commit-msg +6 -0
- sybl-0.1.0/.github/ISSUE_TEMPLATE/bug_report.yml +96 -0
- sybl-0.1.0/.github/ISSUE_TEMPLATE/feature_request.yml +54 -0
- sybl-0.1.0/.github/PULL_REQUEST_TEMPLATE.md +17 -0
- sybl-0.1.0/.github/workflows/ci.yml +49 -0
- sybl-0.1.0/.github/workflows/release.yml +25 -0
- sybl-0.1.0/.gitignore +17 -0
- sybl-0.1.0/.python-version +1 -0
- sybl-0.1.0/AGENTS.md +256 -0
- sybl-0.1.0/CHANGELOG.md +41 -0
- sybl-0.1.0/CODE_OF_CONDUCT.md +59 -0
- sybl-0.1.0/CONTRIBUTING.md +92 -0
- sybl-0.1.0/LICENSE +21 -0
- sybl-0.1.0/PKG-INFO +123 -0
- sybl-0.1.0/README.md +79 -0
- sybl-0.1.0/SECURITY.md +26 -0
- sybl-0.1.0/docs/DAEMON.md +45 -0
- sybl-0.1.0/docs/DEVELOPMENT.md +72 -0
- sybl-0.1.0/docs/POPUP-SPIKE.md +42 -0
- sybl-0.1.0/docs/RESEARCH-NOTES.md +184 -0
- sybl-0.1.0/docs/ROADMAP.md +261 -0
- sybl-0.1.0/docs/configuration.md +147 -0
- sybl-0.1.0/docs/getting-started.md +117 -0
- sybl-0.1.0/docs/permissions.md +61 -0
- sybl-0.1.0/docs/providers.md +110 -0
- sybl-0.1.0/main.py +6 -0
- sybl-0.1.0/pyproject.toml +83 -0
- sybl-0.1.0/sybl/__init__.py +3 -0
- sybl-0.1.0/sybl/__main__.py +5 -0
- sybl-0.1.0/sybl/audio/__init__.py +38 -0
- sybl-0.1.0/sybl/audio/debug.py +41 -0
- sybl-0.1.0/sybl/audio/devices.py +224 -0
- sybl-0.1.0/sybl/audio/errors.py +17 -0
- sybl-0.1.0/sybl/audio/metering.py +77 -0
- sybl-0.1.0/sybl/audio/resample.py +25 -0
- sybl-0.1.0/sybl/audio/session.py +289 -0
- sybl-0.1.0/sybl/audio/types.py +34 -0
- sybl-0.1.0/sybl/cli/__init__.py +56 -0
- sybl-0.1.0/sybl/cli/audio_cmd.py +147 -0
- sybl-0.1.0/sybl/cli/config_cmd.py +164 -0
- sybl-0.1.0/sybl/cli/doctor.py +534 -0
- sybl-0.1.0/sybl/cli/hotkey_cmd.py +72 -0
- sybl-0.1.0/sybl/cli/io.py +13 -0
- sybl-0.1.0/sybl/cli/meter.py +32 -0
- sybl-0.1.0/sybl/cli/start.py +70 -0
- sybl-0.1.0/sybl/cli/status.py +39 -0
- sybl-0.1.0/sybl/cli/stop.py +32 -0
- sybl-0.1.0/sybl/cli/transcribe_cmd.py +169 -0
- sybl-0.1.0/sybl/cli/tui.py +30 -0
- sybl-0.1.0/sybl/config/__init__.py +29 -0
- sybl-0.1.0/sybl/config/manager.py +101 -0
- sybl-0.1.0/sybl/config/models.py +107 -0
- sybl-0.1.0/sybl/config/paths.py +34 -0
- sybl-0.1.0/sybl/config/vocabulary.py +94 -0
- sybl-0.1.0/sybl/core/__init__.py +17 -0
- sybl-0.1.0/sybl/core/daemon.py +305 -0
- sybl-0.1.0/sybl/core/dictation.py +340 -0
- sybl-0.1.0/sybl/core/events.py +95 -0
- sybl-0.1.0/sybl/core/history.py +63 -0
- sybl-0.1.0/sybl/core/postprocess.py +124 -0
- sybl-0.1.0/sybl/core/state.py +70 -0
- sybl-0.1.0/sybl/core/transcribe.py +189 -0
- sybl-0.1.0/sybl/core/voice_commands.py +43 -0
- sybl-0.1.0/sybl/hotkeys/__init__.py +16 -0
- sybl-0.1.0/sybl/hotkeys/base.py +40 -0
- sybl-0.1.0/sybl/hotkeys/bindings.py +95 -0
- sybl-0.1.0/sybl/hotkeys/focus.py +45 -0
- sybl-0.1.0/sybl/hotkeys/pynput_backend.py +197 -0
- sybl-0.1.0/sybl/indicator/__init__.py +22 -0
- sybl-0.1.0/sybl/indicator/base.py +15 -0
- sybl-0.1.0/sybl/indicator/cursor_win.py +31 -0
- sybl-0.1.0/sybl/indicator/noop.py +17 -0
- sybl-0.1.0/sybl/indicator/tk_win.py +187 -0
- sybl-0.1.0/sybl/inject/__init__.py +9 -0
- sybl-0.1.0/sybl/inject/base.py +32 -0
- sybl-0.1.0/sybl/inject/clipboard_win.py +253 -0
- sybl-0.1.0/sybl/inject/focus_win.py +56 -0
- sybl-0.1.0/sybl/ipc/__init__.py +12 -0
- sybl-0.1.0/sybl/ipc/client.py +175 -0
- sybl-0.1.0/sybl/ipc/process.py +28 -0
- sybl-0.1.0/sybl/ipc/protocol.py +76 -0
- sybl-0.1.0/sybl/ipc/server.py +192 -0
- sybl-0.1.0/sybl/ipc/single_instance.py +66 -0
- sybl-0.1.0/sybl/logging/__init__.py +6 -0
- sybl-0.1.0/sybl/logging/ring_buffer.py +36 -0
- sybl-0.1.0/sybl/logging/setup.py +49 -0
- sybl-0.1.0/sybl/providers/__init__.py +41 -0
- sybl-0.1.0/sybl/providers/base.py +17 -0
- sybl-0.1.0/sybl/providers/capabilities.py +51 -0
- sybl-0.1.0/sybl/providers/deepgram.py +213 -0
- sybl-0.1.0/sybl/providers/errors.py +21 -0
- sybl-0.1.0/sybl/providers/groq.py +141 -0
- sybl-0.1.0/sybl/providers/manager.py +90 -0
- sybl-0.1.0/sybl/providers/pcm.py +21 -0
- sybl-0.1.0/sybl/providers/registry.py +49 -0
- sybl-0.1.0/sybl/providers/types.py +12 -0
- sybl-0.1.0/sybl/secrets/__init__.py +19 -0
- sybl-0.1.0/sybl/secrets/store.py +52 -0
- sybl-0.1.0/sybl/tui/__init__.py +5 -0
- sybl-0.1.0/sybl/tui/app.py +178 -0
- sybl-0.1.0/sybl/tui/client.py +69 -0
- sybl-0.1.0/sybl/tui/screens/__init__.py +0 -0
- sybl-0.1.0/sybl/tui/screens/dashboard.py +51 -0
- sybl-0.1.0/sybl/tui/screens/onboarding.py +55 -0
- sybl-0.1.0/sybl/tui/screens/settings.py +147 -0
- sybl-0.1.0/sybl/tui/widgets/__init__.py +0 -0
- sybl-0.1.0/sybl/tui/widgets/history_panel.py +44 -0
- sybl-0.1.0/sybl/tui/widgets/log_view.py +17 -0
- sybl-0.1.0/sybl/tui/widgets/status_bar.py +29 -0
- sybl-0.1.0/tests/conftest.py +17 -0
- sybl-0.1.0/tests/test_audio.py +329 -0
- sybl-0.1.0/tests/test_bindings.py +40 -0
- sybl-0.1.0/tests/test_cli.py +83 -0
- sybl-0.1.0/tests/test_cli_io.py +16 -0
- sybl-0.1.0/tests/test_config.py +96 -0
- sybl-0.1.0/tests/test_daemon_indicator.py +65 -0
- sybl-0.1.0/tests/test_deepgram.py +119 -0
- sybl-0.1.0/tests/test_dictation.py +310 -0
- sybl-0.1.0/tests/test_doctor.py +46 -0
- sybl-0.1.0/tests/test_history.py +37 -0
- sybl-0.1.0/tests/test_hotkeys.py +79 -0
- sybl-0.1.0/tests/test_indicator.py +49 -0
- sybl-0.1.0/tests/test_inject.py +98 -0
- sybl-0.1.0/tests/test_ipc_protocol.py +39 -0
- sybl-0.1.0/tests/test_ipc_server.py +42 -0
- sybl-0.1.0/tests/test_logging.py +38 -0
- sybl-0.1.0/tests/test_manager.py +76 -0
- sybl-0.1.0/tests/test_postprocess.py +75 -0
- sybl-0.1.0/tests/test_provider_vocabulary.py +27 -0
- sybl-0.1.0/tests/test_providers.py +135 -0
- sybl-0.1.0/tests/test_secrets.py +75 -0
- sybl-0.1.0/tests/test_single_instance.py +34 -0
- sybl-0.1.0/tests/test_transcribe.py +128 -0
- sybl-0.1.0/tests/test_tui_client.py +31 -0
- sybl-0.1.0/tests/test_vocabulary.py +39 -0
- sybl-0.1.0/tests/test_voice_commands.py +35 -0
- sybl-0.1.0/uv.lock +1069 -0
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Keep AGENTS.md as the living source of truth; read it first and update it whenever project reality changes.
|
|
3
|
+
alwaysApply: true
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Maintain AGENTS.md
|
|
7
|
+
|
|
8
|
+
`AGENTS.md` at the repo root is the living source of truth for the sybl project
|
|
9
|
+
(mission, product spec, current state, architecture decisions, structure,
|
|
10
|
+
conventions).
|
|
11
|
+
|
|
12
|
+
## At the start of a task
|
|
13
|
+
- Read `AGENTS.md` before planning or making changes so your work aligns with
|
|
14
|
+
the current mission, decisions, and conventions.
|
|
15
|
+
|
|
16
|
+
## During / after a task — update `AGENTS.md` when you:
|
|
17
|
+
- Change the mission, scope, or product behavior → update the Mission / Product
|
|
18
|
+
Spec sections.
|
|
19
|
+
- Advance the project phase or status → update the Current State section and
|
|
20
|
+
`docs/ROADMAP.md`.
|
|
21
|
+
- Make or reverse a technical/architecture decision → append a row/note to the
|
|
22
|
+
Architecture & Tech Decisions log (append, don't erase history).
|
|
23
|
+
- Add, move, or remove top-level files/directories → update the Project
|
|
24
|
+
Structure section.
|
|
25
|
+
- Establish or change a convention → update the Conventions section.
|
|
26
|
+
|
|
27
|
+
## Rules
|
|
28
|
+
1. Bump the `Last updated` date at the top of `AGENTS.md` whenever you edit it.
|
|
29
|
+
2. Append to the decision log rather than deleting prior decisions; if a
|
|
30
|
+
decision changes, add a new entry explaining the change.
|
|
31
|
+
3. Keep `AGENTS.md` concise — it is a map. Put depth in `docs/`.
|
|
32
|
+
4. If reality and `AGENTS.md` disagree, fix `AGENTS.md`.
|
|
33
|
+
5. Before ending a turn that changed the project, verify `AGENTS.md` is still
|
|
34
|
+
accurate and update it if anything went stale.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# No agent co-author commit trailers
|
|
2
|
+
|
|
3
|
+
When creating git commits in this repository:
|
|
4
|
+
|
|
5
|
+
- **Never** add `Co-authored-by:` trailers (including `Co-authored-by: Cursor <cursoragent@cursor.com>`).
|
|
6
|
+
- **Never** add any Cursor, Copilot, or AI agent attribution to commit messages.
|
|
7
|
+
- Keep commit messages concise and focused on the change; author attribution is handled by git config only.
|
|
8
|
+
|
|
9
|
+
If staging changes for the user to commit, leave the message body free of co-author lines.
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
name: Bug report
|
|
2
|
+
description: Something isn't working as expected
|
|
3
|
+
title: "[Bug]: "
|
|
4
|
+
labels: ["bug"]
|
|
5
|
+
body:
|
|
6
|
+
- type: markdown
|
|
7
|
+
attributes:
|
|
8
|
+
value: |
|
|
9
|
+
Thanks for the report. Include `sybl doctor` output if you can.
|
|
10
|
+
|
|
11
|
+
- type: dropdown
|
|
12
|
+
id: os
|
|
13
|
+
attributes:
|
|
14
|
+
label: Operating system
|
|
15
|
+
options:
|
|
16
|
+
- Windows
|
|
17
|
+
- macOS
|
|
18
|
+
- Linux
|
|
19
|
+
- Other
|
|
20
|
+
validations:
|
|
21
|
+
required: true
|
|
22
|
+
|
|
23
|
+
- type: input
|
|
24
|
+
id: python
|
|
25
|
+
attributes:
|
|
26
|
+
label: Python version
|
|
27
|
+
placeholder: "3.12.x"
|
|
28
|
+
validations:
|
|
29
|
+
required: true
|
|
30
|
+
|
|
31
|
+
- type: input
|
|
32
|
+
id: sybl_version
|
|
33
|
+
attributes:
|
|
34
|
+
label: sybl version
|
|
35
|
+
placeholder: "0.1.0 or git commit"
|
|
36
|
+
validations:
|
|
37
|
+
required: true
|
|
38
|
+
|
|
39
|
+
- type: dropdown
|
|
40
|
+
id: provider
|
|
41
|
+
attributes:
|
|
42
|
+
label: STT provider
|
|
43
|
+
options:
|
|
44
|
+
- Groq
|
|
45
|
+
- Deepgram
|
|
46
|
+
- Other / none
|
|
47
|
+
- Not sure
|
|
48
|
+
validations:
|
|
49
|
+
required: true
|
|
50
|
+
|
|
51
|
+
- type: textarea
|
|
52
|
+
id: steps
|
|
53
|
+
attributes:
|
|
54
|
+
label: Steps to reproduce
|
|
55
|
+
placeholder: |
|
|
56
|
+
1. sybl start
|
|
57
|
+
2. Hold hotkey and speak
|
|
58
|
+
3. ...
|
|
59
|
+
validations:
|
|
60
|
+
required: true
|
|
61
|
+
|
|
62
|
+
- type: textarea
|
|
63
|
+
id: expected
|
|
64
|
+
attributes:
|
|
65
|
+
label: Expected behavior
|
|
66
|
+
validations:
|
|
67
|
+
required: true
|
|
68
|
+
|
|
69
|
+
- type: textarea
|
|
70
|
+
id: actual
|
|
71
|
+
attributes:
|
|
72
|
+
label: Actual behavior
|
|
73
|
+
validations:
|
|
74
|
+
required: true
|
|
75
|
+
|
|
76
|
+
- type: textarea
|
|
77
|
+
id: doctor
|
|
78
|
+
attributes:
|
|
79
|
+
label: sybl doctor output
|
|
80
|
+
render: shell
|
|
81
|
+
placeholder: Paste output of `sybl doctor`
|
|
82
|
+
|
|
83
|
+
- type: textarea
|
|
84
|
+
id: logs
|
|
85
|
+
attributes:
|
|
86
|
+
label: Relevant logs
|
|
87
|
+
description: Redact API keys. Log file is under your sybl state directory.
|
|
88
|
+
render: shell
|
|
89
|
+
|
|
90
|
+
- type: checkboxes
|
|
91
|
+
id: terms
|
|
92
|
+
attributes:
|
|
93
|
+
label: Checklist
|
|
94
|
+
options:
|
|
95
|
+
- label: I searched existing issues before opening this
|
|
96
|
+
required: true
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
name: Feature request
|
|
2
|
+
description: Suggest an idea for sybl
|
|
3
|
+
title: "[Feature]: "
|
|
4
|
+
labels: ["enhancement"]
|
|
5
|
+
body:
|
|
6
|
+
- type: markdown
|
|
7
|
+
attributes:
|
|
8
|
+
value: |
|
|
9
|
+
Check [docs/ROADMAP.md](https://github.com/Rikhil-Nell/sybl/blob/main/docs/ROADMAP.md)
|
|
10
|
+
before filing — some items may already be planned.
|
|
11
|
+
|
|
12
|
+
- type: textarea
|
|
13
|
+
id: problem
|
|
14
|
+
attributes:
|
|
15
|
+
label: Problem or use case
|
|
16
|
+
description: What problem does this solve? Who benefits?
|
|
17
|
+
validations:
|
|
18
|
+
required: true
|
|
19
|
+
|
|
20
|
+
- type: textarea
|
|
21
|
+
id: solution
|
|
22
|
+
attributes:
|
|
23
|
+
label: Proposed solution
|
|
24
|
+
description: How would you like this to work?
|
|
25
|
+
validations:
|
|
26
|
+
required: true
|
|
27
|
+
|
|
28
|
+
- type: textarea
|
|
29
|
+
id: alternatives
|
|
30
|
+
attributes:
|
|
31
|
+
label: Alternatives considered
|
|
32
|
+
description: Other approaches you've thought about
|
|
33
|
+
|
|
34
|
+
- type: dropdown
|
|
35
|
+
id: platform
|
|
36
|
+
attributes:
|
|
37
|
+
label: Primary platform
|
|
38
|
+
options:
|
|
39
|
+
- Windows
|
|
40
|
+
- macOS
|
|
41
|
+
- Linux
|
|
42
|
+
- Cross-platform
|
|
43
|
+
validations:
|
|
44
|
+
required: true
|
|
45
|
+
|
|
46
|
+
- type: checkboxes
|
|
47
|
+
id: terms
|
|
48
|
+
attributes:
|
|
49
|
+
label: Checklist
|
|
50
|
+
options:
|
|
51
|
+
- label: This aligns with sybl's BYOK, local-first mission (no hosted backend)
|
|
52
|
+
required: true
|
|
53
|
+
- label: I searched existing issues before opening this
|
|
54
|
+
required: true
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
## Summary
|
|
2
|
+
|
|
3
|
+
<!-- What changed and why? -->
|
|
4
|
+
|
|
5
|
+
## Test plan
|
|
6
|
+
|
|
7
|
+
- [ ] `uv run ruff check sybl tests`
|
|
8
|
+
- [ ] `uv run pytest -m "not integration" -q`
|
|
9
|
+
- [ ] Updated [AGENTS.md](AGENTS.md) if behavior or architecture changed
|
|
10
|
+
- [ ] No secrets or API keys in the diff
|
|
11
|
+
|
|
12
|
+
## Platform notes
|
|
13
|
+
|
|
14
|
+
<!-- If hotkeys, injection, or indicator code changed, describe manual Windows testing. -->
|
|
15
|
+
|
|
16
|
+
- [ ] Not applicable
|
|
17
|
+
- [ ] Tested manually on Windows
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
lint-and-test:
|
|
11
|
+
runs-on: ${{ matrix.os }}
|
|
12
|
+
strategy:
|
|
13
|
+
fail-fast: false
|
|
14
|
+
matrix:
|
|
15
|
+
os: [windows-latest, ubuntu-latest]
|
|
16
|
+
python-version: ["3.12"]
|
|
17
|
+
env:
|
|
18
|
+
NO_COLOR: "1"
|
|
19
|
+
TERM: dumb
|
|
20
|
+
steps:
|
|
21
|
+
- uses: actions/checkout@v4
|
|
22
|
+
|
|
23
|
+
- uses: astral-sh/setup-uv@v5
|
|
24
|
+
with:
|
|
25
|
+
python-version: ${{ matrix.python-version }}
|
|
26
|
+
|
|
27
|
+
- name: Install system dependencies (Linux)
|
|
28
|
+
if: runner.os == 'Linux'
|
|
29
|
+
run: sudo apt-get update && sudo apt-get install -y portaudio19-dev xvfb
|
|
30
|
+
|
|
31
|
+
- name: Install dependencies
|
|
32
|
+
run: uv sync
|
|
33
|
+
|
|
34
|
+
- name: Install Linux keyring backend
|
|
35
|
+
if: runner.os == 'Linux'
|
|
36
|
+
run: uv pip install keyrings.alt
|
|
37
|
+
|
|
38
|
+
- name: Lint
|
|
39
|
+
run: uv run ruff check sybl tests
|
|
40
|
+
|
|
41
|
+
- name: Unit tests (Linux)
|
|
42
|
+
if: runner.os == 'Linux'
|
|
43
|
+
env:
|
|
44
|
+
PYTHON_KEYRING_BACKEND: keyrings.alt.file.PlaintextKeyring
|
|
45
|
+
run: xvfb-run uv run pytest -m "not integration" -q --ignore=tests/test_inject.py
|
|
46
|
+
|
|
47
|
+
- name: Unit tests (Windows)
|
|
48
|
+
if: runner.os == 'Windows'
|
|
49
|
+
run: uv run pytest -m "not integration" -q
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
release:
|
|
5
|
+
types: [published]
|
|
6
|
+
|
|
7
|
+
permissions:
|
|
8
|
+
id-token: write
|
|
9
|
+
contents: read
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
pypi:
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
steps:
|
|
15
|
+
- uses: actions/checkout@v4
|
|
16
|
+
|
|
17
|
+
- uses: astral-sh/setup-uv@v5
|
|
18
|
+
with:
|
|
19
|
+
python-version: "3.12"
|
|
20
|
+
|
|
21
|
+
- name: Build package
|
|
22
|
+
run: uv build
|
|
23
|
+
|
|
24
|
+
- name: Publish to PyPI
|
|
25
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
sybl-0.1.0/.gitignore
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.12
|
sybl-0.1.0/AGENTS.md
ADDED
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
# AGENTS.md
|
|
2
|
+
|
|
3
|
+
> Living source of truth for the sybl project. Read this first. Keep it current.
|
|
4
|
+
> Last updated: 2026-06-28 (rebrand to sybl — package, CLI, PyPI, and paths)
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## 1. Mission
|
|
9
|
+
|
|
10
|
+
**sybl is an open-source, bring-your-own-key (BYOK) voice dictation tool.**
|
|
11
|
+
|
|
12
|
+
Put your cursor anywhere, hit a global shortcut, speak/ramble into a lightweight
|
|
13
|
+
popup, and sybl transcribes it fast and types it in for you — wherever you were
|
|
14
|
+
about to type. It is the open-source answer to closed tools like Wispr Flow.
|
|
15
|
+
|
|
16
|
+
The guiding principles:
|
|
17
|
+
|
|
18
|
+
- **BYOK, provider-agnostic.** Users plug in whatever speech-to-text (STT)
|
|
19
|
+
credits they already have — Deepgram, AssemblyAI, Gladia, Groq (Whisper
|
|
20
|
+
large-v3), etc. No vendor lock-in, no sybl-hosted backend, no subscription.
|
|
21
|
+
- **Local-first & private.** Audio goes straight from the user's machine to the
|
|
22
|
+
STT provider of their choice. sybl keeps no telemetry and stores nothing it
|
|
23
|
+
doesn't have to.
|
|
24
|
+
- **Fast & invisible.** Dictation should feel instant and stay out of the way.
|
|
25
|
+
- **TUI, daemon-based.** sybl runs as a background daemon. All of its UI is a
|
|
26
|
+
terminal UI (TUI): live logs, status, history, and config — nothing more.
|
|
27
|
+
|
|
28
|
+
## 2. What sybl Does (Product Spec)
|
|
29
|
+
|
|
30
|
+
- **Global activation.** A system-wide shortcut works regardless of focused app.
|
|
31
|
+
- **Two interaction modes:**
|
|
32
|
+
- **Push-to-talk (PTT):** hold the shortcut, speak, release to finish.
|
|
33
|
+
- **Toggle / constant recording:** a double-press of the shortcut starts
|
|
34
|
+
continuous recording; press again to stop.
|
|
35
|
+
- **Popup capture surface.** When activated, a small on-screen pill appears near the
|
|
36
|
+
cursor so the user knows sybl is listening (Windows tkinter overlay MVP; see
|
|
37
|
+
`docs/POPUP-SPIKE.md`).
|
|
38
|
+
- **BYOK transcription.** Audio is streamed/sent to the user's selected provider
|
|
39
|
+
and transcribed quickly.
|
|
40
|
+
- **Text injection.** The transcript is inserted at the current cursor location
|
|
41
|
+
in whatever app had focus when activation happened.
|
|
42
|
+
- **TUI surface.** A Textual-based TUI shows live logs, current state, and a
|
|
43
|
+
scrollback history of recent transcriptions for reference.
|
|
44
|
+
|
|
45
|
+
## 3. Current State
|
|
46
|
+
|
|
47
|
+
> Update this section every time the project's reality changes.
|
|
48
|
+
|
|
49
|
+
- **Phase:** Phase 10 complete — v0.1.0 public release on GitHub and PyPI; contributor
|
|
50
|
+
docs, CI (Windows + Ubuntu), issue/PR templates, and user docs hub shipped.
|
|
51
|
+
- **Code:** `sybl/audio/` implements `AudioCaptureSession` (sounddevice callback →
|
|
52
|
+
asyncio queue, 16 kHz mono int16, resampling, dBFS peak metering, debug WAV save).
|
|
53
|
+
`sybl/providers/` implements streaming-first STT interface, `ProviderCapabilities`,
|
|
54
|
+
`resolve_provider` session-start selection, `GroqProvider` (batch), and
|
|
55
|
+
`DeepgramProvider` (WebSocket streaming + REST batch via official SDK).
|
|
56
|
+
`sybl/hotkeys/` implements `HotkeyManager`, binding parser, Windows `pynput` PTT
|
|
57
|
+
backend, and focus capture at activation. `sybl/inject/` implements `TextInjector`,
|
|
58
|
+
Windows clipboard-paste injection with focus restore and clipboard restoration.
|
|
59
|
+
`sybl/core/` has `StateMachine`, `DictationController`, `SyblDaemon`, post-processing,
|
|
60
|
+
voice commands, `TranscriptHistory`, `EventBus`, and transcribe pipeline.
|
|
61
|
+
`sybl/config/vocabulary.py` stores STT hint terms. `sybl/ipc/` implements
|
|
62
|
+
NDJSON command/event TCP servers and client. `sybl/tui/` is a Textual app (logs,
|
|
63
|
+
status, history, settings, BYOK onboarding). `sybl/indicator/` implements
|
|
64
|
+
`CaptureIndicator` (NoOp + Windows tkinter overlay near cursor with RMS level bar).
|
|
65
|
+
CLI: `sybl start`, `sybl stop`, `sybl status`, `sybl tui`, `sybl config`,
|
|
66
|
+
`sybl config vocab`, `sybl doctor`, `sybl audio`, `sybl transcribe`, `sybl hotkey test`.
|
|
67
|
+
- **Stack pinned:** `typer`, `pydantic`, `platformdirs`, `keyring`, `tomli-w`,
|
|
68
|
+
`sounddevice`, `numpy`, `soundfile`, `soxr`, `groq`, `tenacity`, `deepgram-sdk`,
|
|
69
|
+
`pynput`, `textual`; dev: `ruff`, `pytest`, `pytest-asyncio`.
|
|
70
|
+
- **Primary platform:** Windows first (dev machine). Code stays cross-platform
|
|
71
|
+
behind interfaces, but the core loop is proven on Windows before expanding.
|
|
72
|
+
- **Open questions:** per-platform overlay beyond Windows; text-injection
|
|
73
|
+
edge cases (Wayland especially); how aggressive default post-processing should
|
|
74
|
+
be.
|
|
75
|
+
|
|
76
|
+
## 4. Architecture & Tech Decisions
|
|
77
|
+
|
|
78
|
+
> A decision log. Append new decisions; don't silently rewrite history.
|
|
79
|
+
|
|
80
|
+
| Area | Decision | Rationale |
|
|
81
|
+
|------|----------|-----------|
|
|
82
|
+
| Language | Python 3.12 | Already scaffolded; first-class STT SDKs; great TUI ecosystem. |
|
|
83
|
+
| Packaging / env | `uv` + `pyproject.toml` | Already in place; fast, reproducible. |
|
|
84
|
+
| TUI framework | Textual (pinned) | Modern, async, rich rendering for logs/history; `sybl tui` attaches over IPC. |
|
|
85
|
+
| Audio capture | `sounddevice` + **callback → queue** pattern | PortAudio bindings, NumPy-friendly; callback pushes int16 PCM to an `asyncio.Queue`; never block or process in the callback. |
|
|
86
|
+
| Audio format | **16 kHz, mono, int16 PCM** | What most STT providers expect; resample in-pipeline if the device opens at 48 kHz. |
|
|
87
|
+
| Daemon concurrency | **`asyncio` event loop** + dedicated audio thread | Daemon/TUI/async providers run on asyncio; sounddevice callback thread only enqueues chunks. |
|
|
88
|
+
| Global hotkeys | `pynput` for **MVP**, behind `HotkeyManager` interface | Fast to ship on Windows; plan migration to a small **native helper** (e.g. Rust `global-hotkey`) if reliability stalls. Avoid the `keyboard` library (security/root issues). |
|
|
89
|
+
| STT providers | Pluggable, **streaming-first** interface | Core BYOK requirement; designing for streaming up front avoids rework when batch is the easy case. |
|
|
90
|
+
| Reference provider | **Deepgram** (streaming) as reference; **Groq Whisper** (batch) as early sanity check | Deepgram's streaming is fast/feature-rich and makes the cleanest reference; Groq gives the fastest first end-to-end signal as a degenerate batch case behind the same interface. |
|
|
91
|
+
| Groq integration | Official **`groq` SDK** + in-memory WAV upload via `asyncio.to_thread()` | OpenAI-compatible transcriptions endpoint; default model `whisper-large-v3-turbo`; PCM→WAV matches Groq's 16 kHz mono expectation. |
|
|
92
|
+
| Deepgram integration | Official **`deepgram-sdk`** — WebSocket `wss://api.deepgram.com/v1/listen` for streaming, REST `/v1/listen` for batch | Raw linear16 PCM at 16 kHz mono on websocket; `interim_results=true` for partials; `CloseStream` on end; default model `nova-3`. |
|
|
93
|
+
| Process model | Background daemon + TUI client over local IPC | Daemon listens for hotkeys always; TUI attaches on demand. |
|
|
94
|
+
| Daemon authority | Daemon is the **single source of truth** | Owns mic, providers, state machine, injection, config; TUI is a thin observe/command client. Config changes flow through the daemon so they persist and take effect immediately (no TUI/daemon drift). |
|
|
95
|
+
| IPC shape | Simple command/response + a separate log/event stream; ring buffer for logs & history | More maintainable than sharing complex objects across processes; predictable memory; clean TUI reconnects. |
|
|
96
|
+
| STT interface shape | **Async generators** yielding `TranscriptionResult` | `async def transcribe(audio: bytes \| AsyncIterable[bytes]) -> AsyncGenerator[TranscriptionResult, None]` with `text`, `is_final`, optional `confidence`. |
|
|
97
|
+
| STT errors/retries | Custom exception hierarchy + **`tenacity`** | Normalize `STTError`, `STTTimeoutError`, `STTRateLimitError`; retry only transient failures. |
|
|
98
|
+
| Provider selection | **`ProviderManager`** above providers | Registry + capability flags + config-driven fallback at **session start** (not mid-stream). |
|
|
99
|
+
| Config validation | **Pydantic** models | Schema validation and sane defaults for provider/device settings. |
|
|
100
|
+
| Text injection | **Clipboard set + simulated paste = primary**; synthetic keystrokes = labeled secondary/experimental | Paste is the most forgiving path in pure Python; restore prior clipboard after. Wispr-level reliability eventually needs **native injection** (Win `SendInput`, macOS `CGEvent`) — document limitations until then. |
|
|
101
|
+
| Hotkey escape hatch | If `pynput` reliability becomes a recurring problem, introduce a small **native component** (Rust `global-hotkey` or similar) rather than fighting Python libs | Commercial tools use native code per OS; pure Python won't match Wispr Flow on hotkeys/injection long-term. |
|
|
102
|
+
| Signal metering | **RMS level** for UI now; proper **VAD later** | RMS feeds the popup/TUI meter; `webrtcvad` or `silero-vad` when we need to avoid cutting off speech or trailing silence. |
|
|
103
|
+
| Core concerns | State machine + post-processing pipeline are **first-class from early on** | They sit at the center of UX and the core text path; easier to refine while surrounding plumbing is still simple. |
|
|
104
|
+
| Secrets | OS keyring via `sybl.secrets` | Keep API keys out of plaintext config; `sybl config set-key`. |
|
|
105
|
+
| CLI | Typer subcommands | `start`, `stop`, `status`, `tui`, `config`, `doctor`, `audio`, `transcribe`, `hotkey`. |
|
|
106
|
+
| Logging | File + console + ring buffer | `sybl.logging.setup_logging`; ring buffer for future TUI tail. |
|
|
107
|
+
| Phase 4 hotkeys | **PTT-first** via `pynput` behind `HotkeyManager`; focus captured at **activation press** | Reliability anchor before toggle mode; HWND stored for Phase 5 injection; Windows-only MVP. |
|
|
108
|
+
| Phase 5 injection | **Clipboard set + simulated Ctrl+V** via `SendInput` (ctypes); restore prior clipboard; focus restore with thread attach | Primary strategy on Windows; avoids pynput paste deadlock with hotkey listener; no new deps. |
|
|
109
|
+
| Phase 5.5 post-processing | **Rule-based pipeline** (`PostProcessConfig` + ordered passes) between STT and inject | Whitespace, filler trim, capitalize on by default; auto-punctuation off; Phase 9 expands without restructuring. |
|
|
110
|
+
| Phase 6 IPC | **TCP localhost NDJSON** — separate command + event ports; `daemon.json` + PID lock | Cross-platform; asyncio-native; TUI/CLI attach without shared memory. |
|
|
111
|
+
| Phase 7 TUI | **Textual dashboard** — logs, status, history, settings, BYOK onboarding | All config/key writes routed through daemon IPC; keyboard-driven MVP. |
|
|
112
|
+
| Phase 8 indicator | **Windows tkinter overlay** on dedicated thread; `CaptureIndicator` protocol + `NoOpIndicator` elsewhere | Stdlib, no new deps; cursor position via ctypes; show on LISTENING, RMS level bar; degrade to no-op if tk fails (`docs/POPUP-SPIKE.md`). |
|
|
113
|
+
| Phase 9 vocabulary | **STT hints only** — `vocabulary.toml` + Deepgram keyterms + Groq prompt at session start | Names/jargon at transcription source; no post-STT replacement map; term list reused by future LLM pass. |
|
|
114
|
+
| Phase 9 voice commands | **Final-transcript parsing** — `new line`, `period`, `comma` | No streaming/wake-word; Esc cancels before STT/inject; no scratch-that erase. |
|
|
115
|
+
| Phase 10 OSS | **MIT license**, PyPI + `pipx`/`uv tool` primary install, GitHub issue/PR templates, CI on Windows+Ubuntu | Hermes-style contributor surface without a separate docs site; `docs/` hub + README landing page. |
|
|
116
|
+
| Phase 10 PyPI | **`release.yml`** on GitHub Release → `uv build` → PyPI trusted publishing (OIDC) | No long-lived PyPI token in repo; maintainers configure pending publisher on PyPI. |
|
|
117
|
+
| Rebrand | **sybl** everywhere — Python package `sybl/`, CLI **`sybl`**, PyPI **`sybl`**, app id `sybl` | Prior names `navi` and `sybil`/`sybil-dictation` were taken or conflicted on PyPI; `sybl` is the canonical name. |
|
|
118
|
+
|
|
119
|
+
High-level component map:
|
|
120
|
+
|
|
121
|
+
```
|
|
122
|
+
+-------------------+
|
|
123
|
+
global hotkey | Hotkey Listener |
|
|
124
|
+
───────────────▶ (PTT / toggle) │
|
|
125
|
+
+---------+---------+
|
|
126
|
+
│ activate
|
|
127
|
+
▼
|
|
128
|
+
+-----------+ +-------+-------+ +------------------+
|
|
129
|
+
| Audio |─────▶| Daemon Core |─────▶| STT Provider |
|
|
130
|
+
| Capture | PCM | (state machine)| audio| (BYOK, pluggable)|
|
|
131
|
+
+-----------+ +-------+-------+ +--------+---------+
|
|
132
|
+
│ transcript │ text
|
|
133
|
+
▼ │
|
|
134
|
+
+--------+--------+◀─────────────+
|
|
135
|
+
| Text Injection |
|
|
136
|
+
| (cursor target) |
|
|
137
|
+
+-----------------+
|
|
138
|
+
▲
|
|
139
|
+
+-----------------+------------------+
|
|
140
|
+
│ IPC (logs/state/history) │
|
|
141
|
+
+--------+--------+ +-----------+-----------+
|
|
142
|
+
| TUI Client | | Capture Indicator |
|
|
143
|
+
| (Textual app) | | (listening pill, Win) |
|
|
144
|
+
+-----------------+ +-----------------------+
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
## 5. Project Structure
|
|
148
|
+
|
|
149
|
+
> Keep this in sync with the real tree as it grows.
|
|
150
|
+
|
|
151
|
+
```
|
|
152
|
+
sybl/
|
|
153
|
+
├── AGENTS.md
|
|
154
|
+
├── README.md
|
|
155
|
+
├── LICENSE
|
|
156
|
+
├── CONTRIBUTING.md
|
|
157
|
+
├── CODE_OF_CONDUCT.md
|
|
158
|
+
├── SECURITY.md
|
|
159
|
+
├── CHANGELOG.md
|
|
160
|
+
├── .github/
|
|
161
|
+
│ ├── ISSUE_TEMPLATE/
|
|
162
|
+
│ ├── PULL_REQUEST_TEMPLATE.md
|
|
163
|
+
│ └── workflows/ # ci.yml, release.yml
|
|
164
|
+
├── .githooks/ # optional commit-msg hook (no Cursor co-author)
|
|
165
|
+
├── docs/
|
|
166
|
+
│ ├── getting-started.md
|
|
167
|
+
│ ├── providers.md
|
|
168
|
+
│ ├── configuration.md
|
|
169
|
+
│ ├── permissions.md
|
|
170
|
+
│ ├── DEVELOPMENT.md
|
|
171
|
+
│ ├── DAEMON.md
|
|
172
|
+
│ ├── POPUP-SPIKE.md
|
|
173
|
+
│ ├── ROADMAP.md
|
|
174
|
+
│ └── RESEARCH-NOTES.md
|
|
175
|
+
├── main.py # legacy redirect to CLI
|
|
176
|
+
├── pyproject.toml
|
|
177
|
+
├── tests/
|
|
178
|
+
│ ├── conftest.py
|
|
179
|
+
│ ├── test_audio.py
|
|
180
|
+
│ ├── test_bindings.py
|
|
181
|
+
│ ├── test_cli.py
|
|
182
|
+
│ ├── test_config.py
|
|
183
|
+
│ ├── test_deepgram.py
|
|
184
|
+
│ ├── test_dictation.py
|
|
185
|
+
│ ├── test_doctor.py
|
|
186
|
+
│ ├── test_daemon_indicator.py
|
|
187
|
+
│ ├── test_history.py
|
|
188
|
+
│ ├── test_hotkeys.py
|
|
189
|
+
│ ├── test_indicator.py
|
|
190
|
+
│ ├── test_inject.py
|
|
191
|
+
│ ├── test_ipc_protocol.py
|
|
192
|
+
│ ├── test_ipc_server.py
|
|
193
|
+
│ ├── test_logging.py
|
|
194
|
+
│ ├── test_manager.py
|
|
195
|
+
│ ├── test_postprocess.py
|
|
196
|
+
│ ├── test_providers.py
|
|
197
|
+
│ ├── test_secrets.py
|
|
198
|
+
│ ├── test_single_instance.py
|
|
199
|
+
│ ├── test_transcribe.py
|
|
200
|
+
│ ├── test_tui_client.py
|
|
201
|
+
│ ├── test_vocabulary.py
|
|
202
|
+
│ ├── test_voice_commands.py
|
|
203
|
+
│ └── test_provider_vocabulary.py
|
|
204
|
+
└── sybl/
|
|
205
|
+
├── __init__.py
|
|
206
|
+
├── __main__.py
|
|
207
|
+
├── cli/ # start, stop, status, tui, config, doctor, audio, transcribe, hotkey
|
|
208
|
+
├── config/ # Pydantic models, paths, ConfigManager, vocabulary store
|
|
209
|
+
├── secrets/ # keyring wrapper
|
|
210
|
+
├── logging/ # setup + RingBufferHandler
|
|
211
|
+
├── ipc/ # NDJSON command/event servers + client
|
|
212
|
+
├── audio/ # capture session, devices, resample, metering
|
|
213
|
+
├── core/ # daemon, dictation, postprocess, voice commands, transcribe
|
|
214
|
+
├── providers/ # STT interface, capabilities, manager, Groq, Deepgram
|
|
215
|
+
├── hotkeys/ # HotkeyManager, bindings, pynput backend, focus capture
|
|
216
|
+
├── inject/ # TextInjector, Windows clipboard-paste injection
|
|
217
|
+
├── indicator/ # CaptureIndicator, NoOp, Windows tkinter overlay
|
|
218
|
+
└── tui/ # Textual client (dashboard, settings, onboarding)
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
## 6. Conventions
|
|
222
|
+
|
|
223
|
+
- **Python:** target 3.12, type hints everywhere, **`ruff`** for lint/format.
|
|
224
|
+
- **Async:** the daemon and TUI are async-first (Textual is async); keep the
|
|
225
|
+
audio/STT pipeline non-blocking.
|
|
226
|
+
- **Comments:** explain *why*, not *what*. No narration comments.
|
|
227
|
+
- **Secrets:** never commit API keys; never log them. Use the keyring.
|
|
228
|
+
- **Cross-platform:** Windows, macOS, and Linux are all in scope long-term, but
|
|
229
|
+
**Windows is the primary target** for the core loop first. Always isolate
|
|
230
|
+
platform-specific code (hotkeys, injection, popup) behind interfaces so other
|
|
231
|
+
platforms slot in later without touching the core.
|
|
232
|
+
|
|
233
|
+
## 7. Self-Maintenance Protocol (READ THIS, AGENT)
|
|
234
|
+
|
|
235
|
+
`AGENTS.md` is the project's living memory. **You are responsible for keeping it
|
|
236
|
+
accurate.** After any meaningful change, update the relevant sections in the
|
|
237
|
+
same task — do not defer it.
|
|
238
|
+
|
|
239
|
+
Update `AGENTS.md` whenever you:
|
|
240
|
+
|
|
241
|
+
- Change the mission, scope, or product behavior → update §1/§2.
|
|
242
|
+
- Advance the project's phase or status → update §3 (and `docs/ROADMAP.md`).
|
|
243
|
+
- Make or reverse a technical/architecture decision → append to §4.
|
|
244
|
+
- Add, move, or remove top-level files/directories → update §5.
|
|
245
|
+
- Establish or change a convention → update §6.
|
|
246
|
+
|
|
247
|
+
Rules:
|
|
248
|
+
|
|
249
|
+
1. **Bump `Last updated`** at the top whenever you edit this file.
|
|
250
|
+
2. **Append, don't erase** decisions in §4 — if a decision changes, add a new
|
|
251
|
+
row/note explaining the change rather than deleting the old one.
|
|
252
|
+
3. **Keep it concise.** This is a map, not a manual. Link out to `docs/` for
|
|
253
|
+
depth.
|
|
254
|
+
4. **If reality and this file disagree, this file is wrong — fix it.**
|
|
255
|
+
5. When you finish a unit of work, ask yourself: *"Did anything here go stale?"*
|
|
256
|
+
If yes, update it before ending your turn.
|
sybl-0.1.0/CHANGELOG.md
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [0.1.0] - 2026-06-26
|
|
9
|
+
|
|
10
|
+
First public release. sybl is a BYOK voice dictation daemon with global
|
|
11
|
+
push-to-talk, STT provider plugins, clipboard-paste injection, and a Textual TUI.
|
|
12
|
+
|
|
13
|
+
### Added
|
|
14
|
+
|
|
15
|
+
- CLI: `sybl start`, `sybl stop`, `sybl status`, `sybl tui`, `sybl config`, `sybl doctor`, `sybl audio`, `sybl transcribe`, `sybl hotkey`
|
|
16
|
+
- Config system (TOML + Pydantic) and OS keyring secret storage
|
|
17
|
+
- Audio capture pipeline (16 kHz mono PCM, resampling, RMS metering, debug WAV)
|
|
18
|
+
- STT providers: Groq Whisper (batch) and Deepgram (streaming + batch)
|
|
19
|
+
- Global PTT hotkeys on Windows (`pynput`) with focus capture at activation
|
|
20
|
+
- Clipboard-paste text injection on Windows with clipboard restore
|
|
21
|
+
- Rule-based post-processing pipeline (fillers, capitalization, punctuation cleanup)
|
|
22
|
+
- Daemon + TCP NDJSON IPC; Textual TUI (logs, status, history, settings, onboarding)
|
|
23
|
+
- Windows listening indicator (tkinter overlay pill near cursor)
|
|
24
|
+
- Custom vocabulary STT hints (`sybl config vocab`) for Deepgram keyterms and Groq prompt
|
|
25
|
+
- Voice commands in final transcripts: `new line`, `period`, `comma`
|
|
26
|
+
- Duplicate punctuation collapse in post-processing
|
|
27
|
+
|
|
28
|
+
### Changed
|
|
29
|
+
|
|
30
|
+
- **Rebrand:** project renamed from Navi to **sybl** (`sybl` CLI, PyPI package `sybl`)
|
|
31
|
+
- Removed `scratch that` voice command; use **Esc** while holding the hotkey to cancel
|
|
32
|
+
before injection instead
|
|
33
|
+
|
|
34
|
+
### Notes
|
|
35
|
+
|
|
36
|
+
- **Windows-first:** hotkeys, injection, and the listening indicator are proven on
|
|
37
|
+
Windows. macOS/Linux backends are stubs behind interfaces.
|
|
38
|
+
- Integration tests requiring a microphone or live API keys are marked `@integration`
|
|
39
|
+
and excluded from CI.
|
|
40
|
+
|
|
41
|
+
[0.1.0]: https://github.com/Rikhil-Nell/sybl/releases/tag/v0.1.0
|
|
@@ -0,0 +1,59 @@
|
|
|
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, religion, or sexual identity and
|
|
10
|
+
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:
|
|
18
|
+
|
|
19
|
+
* Demonstrating empathy and kindness toward other people
|
|
20
|
+
* Being respectful of differing opinions, viewpoints, and experiences
|
|
21
|
+
* Giving and gracefully accepting constructive feedback
|
|
22
|
+
* Accepting responsibility and apologizing to those affected by our mistakes,
|
|
23
|
+
and learning from the experience
|
|
24
|
+
* Focusing on what is best not just for us as individuals, but for the overall
|
|
25
|
+
community
|
|
26
|
+
|
|
27
|
+
Examples of unacceptable behavior:
|
|
28
|
+
|
|
29
|
+
* The use of sexualized language or imagery, and sexual attention or advances of
|
|
30
|
+
any kind
|
|
31
|
+
* Trolling, insulting or derogatory comments, and personal or political attacks
|
|
32
|
+
* Public or private harassment
|
|
33
|
+
* Publishing others' private information, such as a physical or email address,
|
|
34
|
+
without their explicit permission
|
|
35
|
+
* Other conduct which could reasonably be considered inappropriate in a
|
|
36
|
+
professional setting
|
|
37
|
+
|
|
38
|
+
## Enforcement Responsibilities
|
|
39
|
+
|
|
40
|
+
Community leaders are responsible for clarifying and enforcing our standards of
|
|
41
|
+
acceptable behavior and will take appropriate and fair corrective action in
|
|
42
|
+
response to any behavior that they deem inappropriate, threatening, offensive,
|
|
43
|
+
or harmful.
|
|
44
|
+
|
|
45
|
+
## Scope
|
|
46
|
+
|
|
47
|
+
This Code of Conduct applies within all community spaces, and also applies when
|
|
48
|
+
an individual is officially representing the community in public spaces.
|
|
49
|
+
|
|
50
|
+
## Enforcement
|
|
51
|
+
|
|
52
|
+
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
|
53
|
+
reported to the maintainers at **nrikhil@gmail.com**. All complaints will be
|
|
54
|
+
reviewed and investigated promptly and fairly.
|
|
55
|
+
|
|
56
|
+
## Attribution
|
|
57
|
+
|
|
58
|
+
This Code of Conduct is adapted from the [Contributor Covenant](https://www.contributor-covenant.org),
|
|
59
|
+
version 2.1.
|