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
5 changes: 5 additions & 0 deletions .changeset/bundle-parcel-watcher-into-cli.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@inkeep/open-knowledge": patch
---

Restored the native `@parcel/watcher` file watcher in the packaged desktop app (inkeep/open-knowledge#760). The app runs `ok start` from a bundled CLI whose module resolver never reaches the app's own `@parcel/watcher` copy, so at server boot `import('@parcel/watcher')` failed with "Cannot find package" and the watcher silently fell back to chokidar. The macOS build now stages `@parcel/watcher` — its wrapper, the runtime dependencies it loads (`picomatch`, `is-glob`, `is-extglob`, `detect-libc`), and the per-architecture native binary — onto the CLI's own module path, so the fast native watcher loads as intended. Combined with the chokidar-fallback fix in the same release, external edits to files in subfolders are reflected in the graph, backlinks, and dead-link views without a restart. The staging resolves each dependency exactly as the wrapper loads it (the workspace carries two `picomatch` majors, so a naive copy could have shipped the wrong one), and a packaging test verifies the staged tree is CLI-resolvable without needing a full app build.
7 changes: 7 additions & 0 deletions .changeset/link-suggest-by-name.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"@inkeep/open-knowledge": patch
---

Link-target suggestions now match by name as you type, like the command palette.

When editing a link target (the "Edit markdown link" dialog, the wiki-link panel, and the bubble-menu link popover all share the same field), typing a bare page name such as `install` now opens the suggestion dropdown and surfaces the matching page — a leading `/` is no longer required. Typing or pasting an external URL, or a bare `#anchor`, still does not pop a page list. The empty/browse list also keeps real content pages ahead of dot-directory files (`.github/`, `.changeset/`) so they no longer fill the list on projects rooted at a repository.
22 changes: 22 additions & 0 deletions .changeset/pull-only-sync-mode.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
---
"@inkeep/open-knowledge": minor
---

Add Follow — a one-directional sync mode for people who follow a knowledge base they can read but not push to (share-link recipients and read-only followers).

Previously, opening a repository you lacked push access to left your copy silently frozen: the sync onboarding prompt was suppressed, no sync config was written, and the engine parked itself the moment a push was denied. Follow fixes that dead end.

What it does:

- Keeps your local copy current automatically by fast-forwarding to the latest on GitHub, without ever pushing or committing on your behalf.
- Lets your own uncommitted edits ride safely on top of incoming updates. Non-overlapping changes combine automatically; edits to the same lines the upstream changed surface in the familiar conflict view, where you choose keep-mine or take-theirs. Your branch always tracks the upstream tip and never forks.
- Is always opt-in. Push-denied users are now offered Follow at first open with plain-language copy ("updates flow in from GitHub; your edits stay on this computer"), and anyone can choose Off / Follow / Full in Settings. A project owner can commit `autoSync.default: follow` so a fresh clone starts following.

Also included:

- Full-sync users who lose push access now get a "Switch to Follow" action on the sync-paused notice instead of a silent stall; switching keeps any unshared local commits as a local overlay.
- The sync status badge stays visible for a followed project and shows a distinct following state (updating / up to date / conflict / offline).
- Anonymous followers of public repositories poll more gently than signed-in followers.
- A one-shot "Sync" pull that reports its outcome, for surfaces that need an on-demand refresh.

Configuration note: the sync preference is now stored as a single `autoSync.mode` (`off` / `follow` / `full`). Existing `autoSync.enabled` settings keep working, and choosing a mode clears the legacy flag so the two can't disagree across versions. An app that predates `autoSync.mode` then reads the config as unanswered and re-prompts rather than acting on a stale toggle, so it never pushes for a mode you didn't consent to there.
22 changes: 22 additions & 0 deletions .github/workflows/desktop-build-win-linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,17 @@ jobs:
working-directory: packages/desktop
run: node scripts/prepare-platform-natives.mjs

# Stage @parcel/watcher onto the bundled CLI's module path. This workflow
# invokes electron-builder directly (not the build:win/build:linux npm
# scripts, which DO run this), so the step must be explicit here or the
# packaged app ships without @parcel/watcher on the CLI path and the
# server degrades to chokidar (#760). Stages only the host-arch binary
# today; the other-arch artifact uses the (subfolder-correct) chokidar
# fallback — see scripts/stage-parcel-watcher.mjs.
- name: Stage @parcel/watcher for the bundled CLI
working-directory: packages/desktop
run: node scripts/stage-parcel-watcher.mjs

- name: Build desktop main/preload/renderer
working-directory: packages/desktop
run: pnpm run build:desktop
Expand Down Expand Up @@ -277,6 +288,17 @@ jobs:
working-directory: packages/desktop
run: node scripts/prepare-platform-natives.mjs

# Stage @parcel/watcher onto the bundled CLI's module path. This workflow
# invokes electron-builder directly (not the build:win/build:linux npm
# scripts, which DO run this), so the step must be explicit here or the
# packaged app ships without @parcel/watcher on the CLI path and the
# server degrades to chokidar (#760). Stages only the host-arch binary
# today; the other-arch artifact uses the (subfolder-correct) chokidar
# fallback — see scripts/stage-parcel-watcher.mjs.
- name: Stage @parcel/watcher for the bundled CLI
working-directory: packages/desktop
run: node scripts/stage-parcel-watcher.mjs

- name: Build desktop main/preload/renderer
working-directory: packages/desktop
run: pnpm run build:desktop
Expand Down
9 changes: 9 additions & 0 deletions .github/workflows/desktop-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,15 @@ jobs:
working-directory: packages/desktop
run: node scripts/prepare-universal.mjs

# Stage @parcel/watcher onto the bundled CLI's module path. This workflow
# invokes electron-builder directly (not the build:mac npm script, which
# DOES run this), so the step must be explicit here or the smoke/QA DMG
# ships without @parcel/watcher on the CLI path and the server degrades to
# chokidar (#760).
- name: Stage @parcel/watcher for the bundled CLI
working-directory: packages/desktop
run: node scripts/stage-parcel-watcher.mjs

# Step B: package via electron-builder. Kept as a separate runner step
# from step A (rather than chained via && in a single shell). The split
# was originally forced by a packaging bug in the previous script runner:
Expand Down
9 changes: 9 additions & 0 deletions .github/workflows/desktop-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,15 @@ jobs:
working-directory: packages/desktop
run: node scripts/prepare-universal.mjs

# Stage @parcel/watcher onto the bundled CLI's module path. This workflow
# invokes electron-builder directly (not the build:mac npm script, which
# DOES run this), so the step must be explicit here or the published DMG
# ships without @parcel/watcher on the CLI path and the server degrades to
# chokidar (#760).
- name: Stage @parcel/watcher for the bundled CLI
working-directory: packages/desktop
run: node scripts/stage-parcel-watcher.mjs

- name: Build + sign + notarize + publish DMG/ZIP
# electron-builder picks up CSC_LINK / CSC_KEY_PASSWORD from env +
# signs. afterSign.mjs picks up APPLE_* + notarizes + staples +
Expand Down
37 changes: 28 additions & 9 deletions docs/content/features/github-sync.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,18 @@ title: GitHub sync
icon: custom/GitHub
description: Clone repos from GitHub, auto-sync changes with your team, and resolve conflicts.
---
OpenKnowledge can connect a project to a GitHub remote repository and keep it synced over time. When GitHub sync is enabled, OpenKnowledge actively pulls commits from the remote and pushes commits back.

import { Cloud } from 'lucide-react';

OpenKnowledge can connect a project to a GitHub remote repository and keep it synced over time. When GitHub sync is enabled, OpenKnowledge keeps your copy current with the remote.

There are two modes for GitHub sync:

- **Full** pulls commits from the remote and pushes your commits back.
- **Follow** fetches updates from the remote and never pushes or commits on your behalf.

<Callout type="warn">
Only enable GitHub sync for repositories where you are comfortable with OpenKnowledge writing commits to the remote history. If you are worried about automated commits cluttering your Git history, do not enable sync for that repository.
Only enable full GitHub sync for repositories where you are comfortable with OpenKnowledge writing commits to the remote history. If you are worried about automated commits cluttering your Git history, do not enable full sync for that repository.
</Callout>

## What GitHub sync is for
Expand All @@ -27,7 +35,7 @@ These steps use the desktop app; from a terminal, [`ok clone`](/docs/reference/c
<Step>
### Open the clone dialog

From the Navigator window, click **Clone from GitHub**. You can open the navigator window from the editor by clicking on your project name in the bottom left and then clicking **Switch project**.
From the Navigator window, click **Clone from GitHub**. You can open the Navigator window from the editor by clicking on your project name in the bottom left and then clicking **Switch project**.
</Step>

<Step>
Expand Down Expand Up @@ -57,19 +65,30 @@ This will open a dialog where you can choose an owner and repository name. You c

## Enable GitHub sync

When you open a freshly cloned project, you will be prompted to enable sync. You can also toggle it from the project settings page at any time.
When you open a freshly cloned project, you will be prompted to enable sync. If you have full access to the repository, you will be prompted to enable **Full** sync. If you have read only access, you will be prompted to enable **Follow** sync. You can change the sync mode from the sync popover (the <Cloud role="img" aria-label="Sync" className="inline size-4 align-text-bottom" /> icon) or from **Settings → Sync** at any time.

If you want to set a default sync setting for future collaborators, go to the project settings page and navigate to the **Sync** → **Shared default** section. This writes [`autoSync.default`](/docs/reference/configuration) — one of `off`, `follow`, or `full` — to the project's committed `.ok/config.yml`, pre-answering the enable-sync prompt for everyone who clones the repo; each machine's own auto-sync choice overrides it.

While sync is active, OpenKnowledge:
### Full

With full sync active, OpenKnowledge:

- Fetches commits from the remote
- Commits your edits locally using the configured Git identity
- Pushes those commits back to the remote so collaborators see your changes

If your Git identity isn't set, sync still commits under a default "OpenKnowledge" author; the sync status indicator reminds you to set one so teammates see your name.
If your Git identity isn't set, OpenKnowledge commits under a default "OpenKnowledge" author; the sync status indicator reminds you to set one so teammates see your name.

Pulls can overwrite uncommitted local file changes, so commit or discard work-in-progress before you enable sync.

If you want to set a default auto-sync setting for future collaborators, go to the project settings page and navigate to the **Sync** -> **Shared default** section. This writes [`autoSync.default`](/docs/reference/configuration) to the project's committed `.ok/config.yml`, pre-answering the enable-sync prompt for everyone who clones the repo; each machine's own auto-sync choice overrides it.
### Follow

With follow sync active, OpenKnowledge:

- Fetches commits from the remote
- Never commits or pushes your edits to the remote

Your own edits stay on this computer. You can keep editing a followed project: when an update arrives, non-overlapping changes combine automatically, and an edit to the same lines the remote changed surfaces in the [conflict view](#resolving-a-conflict) where you choose which side to keep. Your branch always tracks the remote tip and never forks.

## Authentication

Expand Down Expand Up @@ -104,7 +123,7 @@ A few situations stop sync from completing successfully. In each case the sync s
### Conflicts and pending changes

- **Unresolved conflicts.** If even one file has a conflict between your edits and your team's, sync waits. You can keep working on every other doc; only the conflicted files are frozen until you choose a side from the diff view. See [Resolving a conflict](#resolving-a-conflict) above.
- **Local changes would be overwritten by an incoming update.** A teammate's update is ready to pull, but a file it touches has uncommitted local changes. Doc edits are committed automatically before merging, so this usually means other tracked files, like configs. Sync pauses rather than clobber your work; commit, stash, or discard those changes from a terminal and sync resumes.
- **Local changes would be overwritten by an incoming update.** A teammate's update is ready to pull, but a file it touches has uncommitted local changes. Doc edits are committed automatically before merging, so this usually means other tracked files, like configs. Sync pauses rather than clobbering your work; commit, stash, or discard those changes from a terminal and sync resumes.
- **Edits made outside the app aren't ready yet.** If you (or another tool) edited a file directly on disk while sync wanted to merge, OpenKnowledge waits until those external edits settle before merging. Usually this clears in a second or two on its own.

### Project isn't on a normal branch
Expand All @@ -115,7 +134,7 @@ A few situations stop sync from completing successfully. In each case the sync s
### GitHub-side blockers

- **Authentication errors.** Your stored credentials expired, were revoked, or don't have access to this repository anymore. Reconnect from the sync indicator (or from **Settings → Account**) to clear the error.
- **You don't have permission to push to this repo.** Someone shared a project backed by a GitHub repo where your account isn't a collaborator (or has read-only access on a private repo). OpenKnowledge checks this up front: instead of prompting you to enable sync that would just fail, the toggle is disabled with an inline "You don't have permission to push to this repo" message in both the sync indicator popover and **Settings → Sync**. If you had sync enabled on a different repo and switch to one you can't push to, OpenKnowledge pauses sync in-memory rather than mutating your preference; your `Auto-sync: on` setting is preserved for the next repo you have full access to. Ask the project owner for write access, then click sync to re-check.
- **You don't have permission to push to this repo.** Someone shared a project backed by a GitHub repo where your account isn't a collaborator (or has read-only access on a private repo). OpenKnowledge checks this up front and offers **Follow** instead of full sync.
- **Protected branches and rejected pushes.** If the target branch requires reviews, signed commits, or status checks, GitHub rejects the push. OpenKnowledge turns sync off automatically so it stops retrying, and it stays off until you turn it back on from the sync indicator or **Settings → Sync**. Switch to a branch you can push to, or use a pull request for the protected branch instead.

### Temporary problems
Expand Down
2 changes: 1 addition & 1 deletion docs/content/features/share.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,6 @@ Even on the right branch, a doc or folder can be renamed or deleted after a link

### Receiving without push permission

If the shared repo is one your GitHub account can't push to (you're not a collaborator on a public repo, or you have read-only access on a private one), OpenKnowledge skips the usual "Enable auto-sync?" prompt. Sync is also disabled for the same reason in **Settings → Sync**. If the project owner grants you write access later, push permission is re-checked the next time the project's server starts. See [GitHub sync: GitHub-side blockers](/docs/features/github-sync#github-side-blockers) for the full set of permission shapes the sync UI handles.
If the shared repo is one your GitHub account can't push to (you're not a collaborator on a public repo, or you have read-only access on a private one), OpenKnowledge offers **[Follow](/docs/features/github-sync#follow)** at first open instead of the full "Enable auto-sync?" prompt: your copy keeps up to date by pulling the latest from GitHub automatically, while your own edits stay on your computer. You can keep editing — an incoming update combines with your non-overlapping changes automatically, and an edit to the same lines surfaces as a conflict to resolve.

See [GitHub sync](/docs/features/github-sync) for how to automatically sync changes to GitHub, and [Timeline and recovery](/docs/features/timeline-and-recovery) for per-doc history once the doc is open.
Loading