Skip to content
Merged
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
178 changes: 123 additions & 55 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,83 +1,168 @@
# DailyNote

> A private notes app where a note you wrote once comes back to you at the right time and asks
> whether anything came of it — and the ones worth sharing become a public record of what you
> actually followed through on.
**A notes app that remembers what you meant to do.**

Capture is table stakes; every notes app has it. **The follow-through loop is the product.**
Private by default. Works offline. Open source.

Private by default, offline-first, open source.
---

**Note-taking is the main component.** Publishing, likes, views and followers are real parts of
the product, but they are a second, deliberate act performed on notes that were written privately
first — the composer never asks who will see this. The app is complete and worth using with the
network off and no account at all. See [docs/product.md](docs/product.md) for the full statement.
## What it's for

There is **no integration with Apple Notes or Google Keep**: there is no API to build against, so
it is dropped rather than deferred ([ADR 0003](docs/adr/0003-no-notes-app-integrations.md)).
Capture is the composer, the share sheet, and a `dailynote://` link.
You write things down and then you forget them. Not because you're careless — because a note just
sits there. Nothing about it ever asks for your attention again.

DailyNote is a normal notes app: open it, write, close it. Nothing to set up, no account, no
internet needed. But when a note is about something you actually meant to do, it comes back to you
later and asks one question:

> **Anything come of this?**

You get four answers. *Not yet.* *Add update.* *Done.* *Let go.*

That's the whole idea. Not reminders, not deadlines, not a streak you'll feel bad about breaking.
Just a note that shows up again at a sensible moment and gives you an easy way to say what
happened — including "nothing, and I'm letting it go."
Comment on lines +20 to +24

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Align the current-state description of the four-answer flow.

Lines 20-24 say users get four answers now. Line 73 says the four-answer card is next. These statements describe different product states. If Line 73 is current, describe the four-answer card as upcoming in the product section.

Also applies to: 73-73

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@README.md` around lines 20 - 24, Update the four-answer flow description in
the README’s current product-state section to describe the card as upcoming
rather than already available, aligning it with the “next” state referenced
later. Preserve the existing explanation of the four response options.


There are no due dates and no overdue badges anywhere in this app. Feeling guilty is the thing we
are trying to avoid, not the thing we're trying to cause.

## And if you want, you can share

Some of what you write turns out to be worth showing people. A thing you said you'd learn, and
then did. A project that went somewhere.

So there's a **Feed**. You can publish a note you already wrote, or write a post straight to the
feed if that's what you feel like. You can read what other people have shared and follow the ones
worth following.

Two promises about it:

- **Your notes are private and stay that way.** Publishing is something you choose, note by note,
afterwards. Nothing you write is public unless you say so.
- **You never have to.** No account is needed to write notes. If you never publish anything, you
haven't missed out on anything — you just have a notes app, which is the point.

The writing screen never asks who's going to see it. Posting lives on its own tab, behind its own
composer, and tells you it's public before you type a word.

## What makes it different

Most feeds are full of people saying what they're *about* to do. "I'm going to learn Rust" is easy
to post and worth nothing.

Here, the thing that shows up in the feed is a **thread**: the original note, plus what actually
happened to it over time. When one resurfaces six weeks later carrying *"Done — here's what I
built"*, that's something no other feed has. Follow-through is the whole product, pointed inward
first and outward second.

---

## Status

**Rollout 1, Phase 0 complete.** Monorepo, CI, schema, domain logic and a working composer that
persists to SQLite. See [docs/plan.md](docs/plan.md) for the phase plan.
Being built in the open, by one person, part-time. It runs, and it's already usable for notes.

**Two things are honest to say up front:** there's no server yet, so the social side runs against
local storage with a few sample authors standing in for other people. And syncing between devices
isn't built, so your notes live on the device that wrote them.

| | Rollout 1 — the notes app | |
|---|---|---|
| 0 | Foundations | ✅ done |
| 1 | A good local notes app | 🚧 in progress |
| 1 | A good local notes app | ✅ mostly there |
| 2 | Capture surfaces — share sheet, URL scheme | — |
| 3 | Follow-through — the differentiator | — |
| 4 | Accounts and sync | — |
| 3 | Follow-through — the differentiator | 🚧 notes come back; the four-answer card is next |
| 4 | Accounts and sync | 🚧 sign-in done, sync not |
| 5 | Import and expansion | — |
| 6 | Ship | — |

| | Rollout 2 — the social layer ([plan](docs/plan-rollout-2.md)) | |
|---|---|---|
| 2.0 | Identity — profiles and handles | — |
| 2.1 | **Publishing + public web pages** — the one to build first | — |
| 2.2 | Follows and a chronological feed | — |
| 2.3 | Comments, reactions, and full moderation | — |
| 2.0 | Identity — profiles and handles | ✅ done |
| 2.1 | Publishing | 🚧 works in the app; public web pages not built |
| 2.2 | Follows and a chronological feed | ✅ done |
| 2.3 | Conversation and safety | 🚧 likes, block and report done; comments not |
| 2.4 | Themes as data, wallpapers | — |
| 2.5 | Discovery | — |

Rollout 2 starts after Rollout 1 Phase 4. R2.1 is independently shippable and works with zero
other users — if everything after it slips a year, there is still a notes app with shareable links.
Full plans: [docs/plan.md](docs/plan.md) · [docs/plan-rollout-2.md](docs/plan-rollout-2.md).
What the product *is*, as opposed to how it gets built: [docs/product.md](docs/product.md).

## Accounts

You don't need one to write notes. You never will — that isn't a trial, it's the design.

An account is asked for at exactly one moment: when you want to put something where other people
can read it. There are three ways in, and they all end up at the same account:

- **Google**
- **A six-digit code by email** — no password, so there's nothing to forget and nothing to leak
- **Sign in with Apple** — on iOS

Signing out leaves every note exactly where it is. They were never the account's.

Setting this up for your own build takes a few console steps: [docs/auth.md](docs/auth.md).

## Privacy

**This app does not use end-to-end encryption, and the server can read your notes.** Notes are
encrypted in transit and at rest. Any note can be marked **local-only**, and those never leave
your device.
encrypted in transit and at rest. Any note can be marked **local-only**, and those never leave your
device: publishing one is refused in code, and the server schema carries a constraint that makes a
published local-only note impossible to store at all.

That's a deliberate trade: end-to-end encryption would permanently rule out server-side search. The
whole server is open source and self-hostable, which is our substitute for "trust us." See
[ADR 0002](docs/adr/0002-no-end-to-end-encryption.md).

That is a deliberate trade — E2EE would permanently rule out search and AI features on the
server. The whole server is open source and self-hostable, which is our substitute for "trust
us". See [ADR 0002](docs/adr/0002-no-end-to-end-encryption.md).
There's also **no integration with Apple Notes or Google Keep**. Neither has an API to build
against, so it's dropped rather than promised
([ADR 0003](docs/adr/0003-no-notes-app-integrations.md)).

## Layout
---

## For developers

### Layout

```

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Add a language to the layout fence.

markdownlint MD040 flags the fence at Line 126. Use text for this non-code layout block.

Proposed fix
-```
+```text
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
```
🧰 Tools
🪛 markdownlint-cli2 (0.23.2)

[warning] 126-126: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@README.md` at line 126, Update the fenced layout block in README.md around
line 126 to specify the text language, changing the opening fence to use text
while preserving the block’s contents and structure.

Source: Linters/SAST tools

apps/mobile Expo app (expo-router, NativeWind) MIT
packages/core pure TS domain logic, no RN, no Supabase MIT
packages/db Drizzle schema + Postgres migrations AGPL-3.0
supabase migrations, RLS policies AGPL-3.0
docs product.md, the two rollout plans, ADRs
docs product.md, the rollout plans, auth.md, ADRs
Comment on lines 127 to +131

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Use one exact license expression in the layout table.

Lines 129-130 say AGPL-3.0, while Line 184 says AGPL-3.0-or-later. Use the exact SPDX expression from the repository license metadata in both places.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@README.md` around lines 127 - 131, Update the license entries in the README
layout table, specifically the packages/db and supabase rows, to use the
repository’s exact SPDX license expression consistently with the later
AGPL-3.0-or-later reference.

```

`packages/core` holds hashtag parsing, title derivation, the review scheduler and search
ranking — the review scheduler is the piece most likely to have subtle bugs and the most annoying
to debug through a UI, so it is pure and unit tested without a simulator.
`packages/core` holds hashtag parsing, title derivation, the review scheduler, search ranking and
feed composition. These are the pieces most likely to have subtle bugs and the most annoying to
debug through a UI, so they're pure functions with unit tests and no simulator involved.

Two seams worth knowing about:

- **`apps/mobile/src/db/social-repo.ts`** is the entire social storage layer. When there's a real
server, that one file gets reimplemented over HTTP and nothing else changes.
- **Feed rules are code, not database policy.** Row-level security answers one question — "is this
row public" — and following, blocking and ordering are decided in `packages/core/src/social.ts`,
where they can be tested.

## Getting started
### Getting started

```bash
npm install
npm start # Expo dev server
npm run android # or: npm run ios
```

Requires Node ≥ 20.19. The app runs in Expo Go for Phase 1; a development build is needed once
native modules land in Phase 2.
Requires Node ≥ 20.19.

You'll need a **development build** rather than Expo Go — Google Sign-In is native code:

```bash
npx expo prebuild --clean
npx expo run:android
```

Sign-in needs credentials. Without them the app still launches, still takes notes and still reads
the feed; it just can't sign anyone in. Copy `apps/mobile/.env.example` to `.env.local` and see
[docs/auth.md](docs/auth.md).
Comment on lines +146 to +165

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🔵 Trivial | 💤 Low value

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail
while IFS= read -r file; do
  printf '\n--- %s ---\n' "$file"
  rg -n -C 4 '"(start|android|ios|engines|packageManager)"' "$file" || true
done < <(fd -a -g 'package.json')

rg -n -C 4 '20\.19|node-version|setup-node|NODE_VERSION' \
  --glob '*.json' --glob '*.yml' --glob '*.yaml' --glob 'Dockerfile*' .

Repository: zacktiger/DailyNote

Length of output: 209


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '--- package.json files ---'
fd -a 'package.json$' . | while IFS= read -r file; do
  printf '\n--- %s ---\n' "$file"
  rg -n -C 4 '"(start|android|ios|engines|packageManager)"' "$file" || true
done

echo
echo '--- toolchain references ---'
rg -n -C 4 '20\.19|node-version|setup-node|NODE_VERSION' \
  --glob '*.json' --glob '*.yml' --glob '*.yaml' --glob 'Dockerfile*' . || true

echo
echo '--- README start section ---'
sed -n '136,170p' README.md

Repository: zacktiger/DailyNote

Length of output: 19366


🌐 Web query:

Expo managed workflow native modules Google Sign-In need native code prebuild run android documentation

💡 Result:

To implement Google Sign-In in an Expo managed workflow, you must use a development build because these libraries require custom native code and cannot run in Expo Go [1][2][3]. The recommended approach is to use the Expo Prebuild workflow [2][4]. Follow these steps: 1. Choose a Library The official Expo documentation recommends either @react-native-google-signin/google-signin or react-native-nitro-google-signin [1][3]. Note that the legacy Google Sign-In SDK for Android is deprecated, and Google now recommends using Android Credential Manager [3]. The react-native-nitro-google-signin library supports Android Credential Manager, whereas the free/public version of @react-native-google-signin/google-signin uses the legacy SDK (though the latter offers Credential Manager support in a paid/premium version) [3][5]. 2. Install and Configure Install your chosen package using your preferred package manager (e.g., npx expo install @react-native-google-signin/google-signin). 3. Add the Config Plugin You must add the library's config plugin to the plugins array in your app.json or app.config.js file [1][2]. This plugin automatically handles the required native configuration (like Info.plist changes or google-services.json integration) during the prebuild process [2][6]. - If you are using Firebase, provide the path to your google-services.json (Android) and GoogleService-Info.plist (iOS) in your app config [2]. - If you are not using Firebase, you will need to provide the iosUrlScheme as an option to the config plugin [2]. 4. Run Prebuild and Build the App After configuring the plugin, run the following command to generate the native project directories: npx expo prebuild --clean [2] Once prebuild completes, you must create a development build to test the native modules: npx expo run:android npx expo run:ios [2][6] Any subsequent changes to native code or configuration require a full rebuild of the app using these commands [6].

Citations:


Clarify the two setup modes in the Getting started block.

npm run android / npm run ios starts Expo Go development mode, but Google Sign-In requires the prebuild development build. Move the prebuild/run commands before those scripts, or explicitly label the first group as Expo Go mode and the second group as the native development-build mode.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@README.md` around lines 146 - 165, Clarify the “Getting started” section by
distinguishing Expo Go commands from the native development-build flow required
for Google Sign-In. Label the npm start/android/ios commands as Expo Go mode,
and place or label the prebuild plus platform run commands as native
development-build mode before the credential instructions.


### Checks

Expand All @@ -91,25 +176,8 @@ All three run in CI on every PR.

### Database

Nothing in Phase 1–3 touches Postgres — the app is local-only until Phase 4. To work on the
schema anyway, see [supabase/README.md](supabase/README.md).

## How it works

- Write a note. The composer is the launch screen — the app opens with the cursor in an empty
note.
- Tags are inline `#hashtags` parsed out of the body. There is no tag picker.
- Write `#do`, or tap **Follow up**, and the note becomes a **commitment**: it comes back on a
loose ladder — **+2d → +7d → +21d → +60d**.
- When it comes back it asks one question, *"Anything come of this?"*, with four answers:
**Not yet** · **Add update** · **Done** · **Let go**.
- "Add update" appends to the note's **thread** — a commitment plus the record of acting on it.

No due dates, no overdue badges, no streaks. Guilt is the failure mode.

Later, a thread — a commitment plus the record of acting on it — is the thing you can publish.
Not a status post. That is why threads are built in Phase 3 and Rollout 2 is a publish button
over a structure that already exists.
The app is local-only until sync lands, so nothing here touches Postgres day to day. To work on the
schema, see [supabase/README.md](supabase/README.md).

## Licence

Expand Down
Loading