Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 26 additions & 20 deletions .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,32 +6,38 @@ labels: bug
assignees: ""
---

**Describe the bug**
A clear, concise description of what went wrong.
Thanks for taking the time to report this. Good bug reports make OpenNotes better for everyone.

**To reproduce**
Steps to reproduce the behavior:
## What happened?

1. Go to "..."
2. Click on "..."
3. See error
<!-- Describe the broken behavior. What did you see? -->

**Expected behavior**
What you expected to happen.
## Steps to reproduce

**Screenshots**
If applicable, add screenshots to help explain the problem.
<!-- Make this as mechanical as possible. A maintainer should be able to follow it without guessing. -->

**Environment**
1.
2.
3.

- Surface: <!-- web app / Mac app -->
- OS and version: <!-- e.g. macOS 15.4, Windows 11 -->
- Browser (web app only): <!-- e.g. Chrome 126, Safari 17 -->
- OpenNotes version or commit: <!-- e.g. 0.1.0, or the commit SHA -->
## Expected behavior

**Data safety check**
<!-- What should have happened instead? -->

- [ ] This bug does not involve loss or corruption of my notes (if it does, say so explicitly at the top — those reports get priority).
## Environment

**Additional context**
Anything else relevant: console errors, whether it happens in a fresh browser profile, etc.
- Surface: <!-- Mac app / web build -->
- OpenNotes version: <!-- e.g. 0.1.2 -->
- OS and version: <!-- e.g. macOS 15.4 -->
- Browser, if using the web build: <!-- e.g. Chrome 126, Safari 17 -->

## Data safety

<!-- If notes were lost, corrupted, duplicated, or synced incorrectly, say that clearly here. These reports get priority. -->

- [ ] This involves possible note loss, corruption, duplication, or sync damage.
- [ ] This is a UI or behavior issue only; my notes are safe.

## Screenshots, logs, or notes

<!-- Screenshots, console errors, and short screen recordings help. Please remove private note content, tokens, or keys before uploading. -->
34 changes: 24 additions & 10 deletions .github/ISSUE_TEMPLATE/feature_request.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,31 @@ labels: enhancement
assignees: ""
---

**The problem or gap**
What are you trying to do that OpenNotes doesn't support today?
OpenNotes keeps the core small on purpose. The best feature requests explain the workflow, not just the button.

**Proposed solution**
What you'd like to see. Sketches or examples from other tools are welcome.
## Workflow

**Alternatives considered**
Other ways you've solved or worked around this.
<!-- What are you trying to do? Where does the current app get in the way? -->

**Core or extension?**
OpenNotes keeps the core small on purpose — capabilities that aren't universal ship as extensions. Do you see this as core behavior, or would it work as an extension? (If it's an extension idea, consider the "Extension idea" template instead.)
## Proposed behavior

**Local-first check**
Does this fit the project's constraints — no backend, no account, no telemetry, no custody of user secrets? If it needs a server or third-party service, explain how it stays opt-in and user-controlled.
<!-- What should OpenNotes do? Screenshots, sketches, or examples from other tools are welcome. -->

## Why this belongs in OpenNotes

<!-- Why is this important for a local-first markdown workspace? Who benefits? -->

## Core or extension?

<!-- Many ideas belong as extensions. If this can be an extension, say so. If it must be core behavior, explain why. -->

## Local-first fit

- [ ] This works without an OpenNotes account.
- [ ] This does not require OpenNotes to host, inspect, or sync user notes.
- [ ] Any third-party service is optional and user-controlled.
- [ ] No telemetry is required.

## Alternatives

<!-- How are you solving this today? What other tools handle it well? -->
50 changes: 35 additions & 15 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -1,27 +1,47 @@
<!-- Thanks for contributing. Keep the change minimal and focused — one concern per PR. -->
<!--
Write for maintainers and future contributors. Keep it public, specific, and calm.
This is not an internal status report. No Slack context, no private notes, no "Jeeves did X".
-->

## What
## Summary

<!-- A short description of the change and the problem it solves. Link the issue if one exists. -->
<!-- What changed, in one or two sentences. Lead with the user-visible outcome when there is one. -->

## How
## Why

<!-- The approach in a sentence or two. Note anything you deliberately did NOT do. -->
<!-- What problem does this solve? What was awkward, broken, risky, or missing before? -->

## What changed

<!-- Prefer concrete bullets over a narrative dump. -->

-

## Screenshots or demo

<!-- Add screenshots, short clips, or before/after notes for UI changes. Write "N/A" for non-UI changes. -->

## Validation

Ran and passing:
<!-- Check every command you actually ran. Add or remove lines as needed. -->

- [ ] `pnpm exec eslint .`
- [ ] `pnpm exec tsc --noEmit`
- [ ] `pnpm run typecheck`
- [ ] `pnpm run lint`
- [ ] `pnpm exec vitest run`
- [ ] `pnpm exec next build`
- [ ] `pnpm run build`
- [ ] `cargo check --manifest-path src-tauri/Cargo.toml`
- [ ] manual app check, if this touches the desktop shell

## Release note

<!-- If this ships to users, write the public-facing line here. If not, write "N/A". -->

<!-- Add tests for new logic where practical (pure, framework-free functions are easiest). -->
>

## Checklist
## Contributor checklist

- [ ] Local-first preserved: nothing here uploads notes, requires an account, or adds telemetry.
- [ ] No secrets, tokens, or generated artifacts (`src-tauri/target`, `.next`, `dist`) committed.
- [ ] No emojis in UI or code; terminology is "notes folder" / "workspace".
- [ ] Docs updated if behavior or the extension API changed.
- [ ] The change preserves OpenNotes' local-first promise: no account, backend, telemetry, or hidden custody of user data.
- [ ] No secrets, tokens, private files, or generated build artifacts are committed.
- [ ] Behavior that can regress has test coverage.
- [ ] Public copy is written for users and contributors, not as an internal handoff note.
- [ ] Docs were updated if behavior, setup, release flow, or the extension API changed.
72 changes: 44 additions & 28 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,51 +1,67 @@
# Contributing to OpenNotes

Thanks for your interest. OpenNotes is a calm, open-source, local-first markdown workspace — **your files, your AI, your aesthetic, no account, no server.** We keep the core small and excellent, and we grow capability through extensions.
Thanks for wanting to help. OpenNotes is small on purpose: local-first notes, real files, user-owned sync, opt-in AI, no telemetry.

## The philosophy
Good contributions make that promise sharper.

- **Local-first, always.** Every keystroke lands locally before anything syncs. Never break this.
- **No custody of secrets.** We never hold a user's token, key, or password. Git sync uses the user's own local git (Mac app); AI uses the user's own key, encrypted on device.
- **Small core, deep extensions.** If a feature isn't universal, it's an extension. See `docs/extensions.md`.
- **Cut the feature, keep the polish.** A smaller thing done beautifully beats a larger thing done roughly.
## Before opening a PR

## Ways to contribute
- Keep one concern per PR.
- Prefer small, reviewable changes over sweeping rewrites.
- Add tests for behavior that can regress.
- Do not commit generated build output, private files, tokens, API keys, or screenshots containing note content.
- If a feature needs a server, account, analytics, hosted sync, or token custody, open an issue first.

1. **Build an extension** — the highest-leverage contribution. Read `docs/extensions.md`, copy `extensions/_starter/`, and open a PR. Templates, backlinks, export, Git Sync, and the AI Co-Writer are the reference patterns.
2. **Fix bugs** — reproduce first, add a failing test, fix, keep it minimal.
3. **Improve the core** — editor, storage, sync. These changes face the highest bar; open an issue to discuss before a large PR.
4. **Documentation & design** — clarity and calm are features here.
## Useful contribution lanes

## Setup
- Bug fixes with a clear reproduction.
- Extension ideas and extension API improvements.
- Reliability work around storage, sync, import/export, and desktop shell behavior.
- Documentation that helps users understand where their data lives.
- UI polish that makes the app calmer without making it louder.

## Local setup

```bash
corepack enable
pnpm install
pnpm dev # http://localhost:3000
pnpm dev
```

## Before you open a PR
For the Mac app:

```bash
pnpm exec tsc --noEmit # types clean
pnpm exec eslint . # lint clean
pnpm exec vitest run # all tests green
pnpm exec next build # builds
pnpm tauri:dev
```

- Add tests for new logic (pure functions are easiest — keep them framework-free).
- Match the existing code style (Prettier + Tailwind, no emojis in UI or code).
- Keep changes minimal and focused; one concern per PR.
- Do not commit secrets, tokens, or large generated artifacts (`src-tauri/target`, `.next`, `dist`).
## Validation

Run the checks that match your change. For most PRs:

```bash
pnpm run typecheck
pnpm run lint
pnpm exec vitest run
pnpm run build
```

For desktop/Tauri changes, also run:

```bash
cargo check --manifest-path src-tauri/Cargo.toml
```

## Commit style
## Writing the PR

Short, imperative, scoped where useful: `fix: stabilize panel toggle`, `feat: add backlinks panel`, `docs: extension guide`. No force-pushes to shared branches.
The PR should explain:

## Code of conduct
1. What changed.
2. Why it matters.
3. How you validated it.
4. Whether it affects local-first behavior, storage, sync, secrets, or the extension API.

This project follows the [Contributor Covenant](CODE_OF_CONDUCT.md). Be kind, be direct, assume good intent. We're building something people trust with their words — act like it.
Public PRs are not internal status notes. Write for the next contributor who lands here from search six months from now.

## License
## Release notes

Apache-2.0. By contributing, you agree your contributions are licensed under the same.
If your change ships to users, add a short public-facing release note in the PR. Use `docs/release-writing.md` for the project style.
83 changes: 83 additions & 0 deletions docs/release-writing.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
# Release writing guide

Release notes are the public face of OpenNotes. They should read like a careful maintainer explaining what changed and why it matters, not like an internal build receipt.

## Audience

Write for three people at once:

1. **Users** deciding whether to download the build.
2. **Contributors** trying to understand the product direction.
3. **Future maintainers** scanning history months later.

Internal notes can mention exact commands, Slack context, local paths, and operational detail. Public release notes should not.

## Shape

Use this structure unless the release is tiny:

```md
# OpenNotes vX.Y.Z

One short paragraph about the release in product language.

## Highlights

- User-visible outcome.
- Contributor-visible improvement.
- Integrity or compatibility note, if relevant.

## Why it matters

A few sentences explaining the product or trust reason behind the change.

## Download

- macOS Apple Silicon: `OpenNotes_X.Y.Z_aarch64.dmg`
- Checksum: `OpenNotes_X.Y.Z_aarch64.dmg.sha256`

## macOS signing note

Be honest about signing and notarization. Do not bury Gatekeeper caveats.

## Verification

Short list of the meaningful checks, not a raw terminal diary.
```

## Good release notes sound like

- specific
- calm
- user-facing
- honest about limitations
- proud without sounding inflated
- grounded in product behavior

## Avoid

- internal chat context
- local file paths
- full commit SHAs unless needed for traceability
- “I ran...” / “Jeeves did...”
- long command transcripts
- calling a release a preview unless GitHub marks it as pre-release
- burying macOS signing caveats

## Examples

Good:

> Report a bug now works in the Mac app. The command opens a prefilled GitHub issue in the system browser, so users can send useful reports without hunting through the repository.

Bad:

> Ran cargo check, built the DMG from commit abc123, mounted it locally, and uploaded it after fixing the branch.

Good:

> Open-source software earns trust in small places. A bug-report button that does nothing is exactly the kind of paper cut that makes a project feel unfinished.

Bad:

> Fixed bug report button. CI passed.
Loading