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
2 changes: 1 addition & 1 deletion .env.example
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Open Knowledge environment variables.
# OpenKnowledge environment variables.
#
# All variables are OPTIONAL. A fresh clone runs end-to-end with no .env file:
#
Expand Down
8 changes: 4 additions & 4 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Contributing to Open Knowledge
# Contributing to OpenKnowledge

Open Knowledge is developed in Inkeep's internal monorepo and mirrored to this public repository with Copybara. Public contributions should still start here: open a pull request against `inkeep/open-knowledge`.
OpenKnowledge is developed in Inkeep's internal monorepo and mirrored to this public repository with Copybara. Public contributions should still start here: open a pull request against `inkeep/open-knowledge`.

## How Public PRs Flow

Expand Down Expand Up @@ -42,7 +42,7 @@ bun run dev

### Environment Variables

Open Knowledge requires no environment variables for development — `bun install && bun run check` works in a fresh clone. To start the dev server, see the commands above. See `.env.example` for optional dev/observability env vars (OpenTelemetry, custom dev server port).
OpenKnowledge requires no environment variables for development — `bun install && bun run check` works in a fresh clone. To start the dev server, see the commands above. See `.env.example` for optional dev/observability env vars (OpenTelemetry, custom dev server port).

### Toolchain

Expand Down Expand Up @@ -91,4 +91,4 @@ Only source code, public docs, and build or development scripts are exported her

## License

Open Knowledge is licensed under the [GNU General Public License v3.0 or later](./LICENSE) (`GPL-3.0-or-later`). By submitting a contribution, you agree that it is licensed under the same terms.
OpenKnowledge is licensed under the [GNU General Public License v3.0 or later](./LICENSE) (`GPL-3.0-or-later`). By submitting a contribution, you agree that it is licensed under the same terms.
22 changes: 10 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
# Open Knowledge
# OpenKnowledge

Open Knowledge is a local-first knowledge base for teams that want docs, help-center content, SOPs, and agent-facing knowledge to live in one structured editing system.
OpenKnowledge is a beautiful, local-first markdown editor and LLM wiki with integrations for Claude, Codex, and Cursor.

The project includes a desktop app, web app, server, CLI, shared core packages, and docs site. It uses Bun workspaces and Turbo for builds.
The editor has full WYSWIG so that editing markdown feels like editing a Google Doc or Notion page.

Sharing and auto-sync are available for team-based collaboration are powered by git.

## Install

Expand All @@ -17,17 +19,13 @@ ok init # scaffold the project + wire up Claude Code, Cursor, and Codex
ok start --open # serve the editor and open it in your browser
```

Full documentation: <https://openknowledge.ai/docs>.

The sections below are for **contributing to** Open Knowledge.

## Repository Model
Docs for general usage: <https://openknowledge.ai/docs>.

This public repository is mirrored from Inkeep's internal monorepo with Copybara. The internal source path is `public/open-knowledge/` in `inkeep/agents-private`.
## Contributions

Public pull requests are welcome. When a public PR opens here, automation mirrors it into the internal monorepo for review and merge. After the internal PR lands, Copybara syncs the accepted change back to this repository.
Public pull requests are welcome. When a public PR opens here, automation mirrors it into the internal monorepo for review and merge.

See [CONTRIBUTING.md](./CONTRIBUTING.md) for the full contribution flow and [AGENTS.md](./AGENTS.md) for agent-facing development guidance.
See [CONTRIBUTING.md](./CONTRIBUTING.md) for details.

## Prerequisites

Expand Down Expand Up @@ -79,4 +77,4 @@ bun run build

## License

Open Knowledge is licensed under the [GNU General Public License v3.0 or later](./LICENSE) (`GPL-3.0-or-later`).
OpenKnowledge is licensed under the [GNU General Public License v3.0 or later](./LICENSE) (`GPL-3.0-or-later`).
14 changes: 7 additions & 7 deletions docs/content/advanced/folders-and-templates.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ title: Folders and templates
description: Describe a folder with its own properties, and offer reusable templates that give new documents their starting content and properties.
---

Folders organize a project the same way they do on your computer: a place to group related docs. Open Knowledge adds two things on top: a folder can **describe itself** (its own properties, exactly like a document's), and it can offer a set of **templates** for new documents.
Folders organize a project the same way they do on your computer: a place to group related docs. OpenKnowledge adds two things on top: a folder can **describe itself** (its own properties, exactly like a document's), and it can offer a set of **templates** for new documents.

Click any folder in the sidebar to open its **overview**: a page listing what's inside, plus two cards: **Folder properties** and **Templates available**.

## Properties, in one minute

Every doc can carry a bit of structured information at the top: a `status`, an `owner`, a `tags` list, a date. Open Knowledge calls these its **properties**. In the raw markdown file they live in a `---`-fenced block at the very top, which markdown tools call *frontmatter*; the **Properties** panel in the editor edits them as ordinary form fields, so you never touch that block by hand. See [Editor → Properties](/docs/features/editor#properties) for the basics.
Every doc can carry a bit of structured information at the top: a `status`, an `owner`, a `tags` list, a date. OpenKnowledge calls these its **properties**. In the raw markdown file they live in a `---`-fenced block at the very top, which markdown tools call *frontmatter*; the **Properties** panel in the editor edits them as ordinary form fields, so you never touch that block by hand. See [Editor → Properties](/docs/features/editor#properties) for the basics.

A doc's properties are its own: exactly what's written in that file, nothing injected from elsewhere. The tedious part is setting the same starting properties on every new doc in a folder, which is what **templates** solve (below).

Expand Down Expand Up @@ -71,7 +71,7 @@ Recorded by {{user}}
## Blockers
```

These two are the only placeholders Open Knowledge fills in. Any other `{{...}}` is rejected when the template is saved, so a template never quietly grows its own mini-language.
These two are the only placeholders OpenKnowledge fills in. Any other `{{...}}` is rejected when the template is saved, so a template never quietly grows its own mini-language.

### Give new documents their own properties

Expand All @@ -96,9 +96,9 @@ tags: [daily]
(...)
```

The `template:` block is the template's own info (the name and description shown in the picker); Open Knowledge strips it when a document is created. Every other key — `type`, `description`, `title`, `status`, `tags` above — becomes the new document's own properties, written as real bytes into the file. `description` gives each new document a starting one-line summary; edit it per document. Because these are the new doc's *own* properties, the doc owns them outright: editing one doc never touches another.
The `template:` block is the template's own info (the name and description shown in the picker); OpenKnowledge strips it when a document is created. Every other key — `type`, `description`, `title`, `status`, `tags` above — becomes the new document's own properties, written as real bytes into the file. `description` gives each new document a starting one-line summary; edit it per document. Because these are the new doc's *own* properties, the doc owns them outright: editing one doc never touches another.

(Older templates that used two stacked frontmatter blocks still work — Open Knowledge reads them and rewrites them to the single-block form the next time they're saved.)
(Older templates that used two stacked frontmatter blocks still work — OpenKnowledge reads them and rewrites them to the single-block form the next time they're saved.)

### Edit and delete

Expand All @@ -108,7 +108,7 @@ Deleting a template removes the `.ok/templates/<name>.md` file. Folders and agen

## How templates reach subfolders

Templates flow **downhill**: a template on `posts/` applies to `posts/`, `posts/2026/`, `posts/2026/drafts/`, and every folder beneath it. When you create a document, Open Knowledge starts at the document's own folder and walks up to the top of the project, gathering the templates each folder along the way offers:
Templates flow **downhill**: a template on `posts/` applies to `posts/`, `posts/2026/`, `posts/2026/drafts/`, and every folder beneath it. When you create a document, OpenKnowledge starts at the document's own folder and walks up to the top of the project, gathering the templates each folder along the way offers:

- Templates from the document's **own folder** are marked **local**.
- Templates from a **folder above it** are marked **inherited**.
Expand All @@ -125,7 +125,7 @@ Agents create documents from templates the same way you do. Through MCP, an agen
write({ document: { path: "posts/launch", template: "blog-post" } })
```

Open Knowledge finds the `blog-post` template the same way the New File dialog does: the agent gets the one that applies to `posts/`. The template's **starter content** becomes the new document; the template's own name and description stay behind as template info and are not copied into the document.
OpenKnowledge finds the `blog-post` template the same way the New File dialog does: the agent gets the one that applies to `posts/`. The template's **starter content** becomes the new document; the template's own name and description stay behind as template info and are not copied into the document.

This is why a template's **Name** matters: it is the label an agent reads when choosing which template fits the document it is about to create.

Expand Down
6 changes: 3 additions & 3 deletions docs/content/features/assets-and-embeds.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ title: Assets and embeds
description: Drop files into the editor and reference them with wiki-style embeds.
---

Open Knowledge treats assets (images, PDFs, video, audio) as first-class content alongside markdown. This page covers how asset references behave when shared outside the editor.
OpenKnowledge treats assets (images, PDFs, video, audio) as first-class content alongside markdown. This page covers how asset references behave when shared outside the editor.

## Sharing across apps

Local-path images (`![chart](./Q3-sales.png)`), wiki-embeds (`![[diagram.png]]`), and any other reference whose URL only resolves on your machine cannot render in apps that don't have access to your filesystem. When you copy a section containing one of these and paste into Gmail, Outlook, Notion, Slack, Discord, or Google Docs, Open Knowledge degrades visibly instead of silently:
Local-path images (`![chart](./Q3-sales.png)`), wiki-embeds (`![[diagram.png]]`), and any other reference whose URL only resolves on your machine cannot render in apps that don't have access to your filesystem. When you copy a section containing one of these and paste into Gmail, Outlook, Notion, Slack, Discord, or Google Docs, OpenKnowledge degrades visibly instead of silently:

- **Non-portable URLs surface as a styled code block.** Recipients see the literal markdown source (e.g. `![chart](./Q3-sales.png)`) in monospace, not a broken-image icon. They can read what the section was meant to include and ask for the file or accept the textual reference.
- **Inline images in paragraphs surface as inline source.** A paragraph with a local-path image keeps its prose flow; only the `<img>` collapses to inline source markup, and the surrounding sentence is unaffected.
Expand All @@ -16,7 +16,7 @@ Local-path images (`![chart](./Q3-sales.png)`), wiki-embeds (`![[diagram.png]]`)
Two affordances are preserved across the cross-app boundary, not degradations themselves:

- **Markdown-aware destinations get the source.** Linear, Outline, Obsidian, and similar apps that read `text/plain` first receive clean canonical markdown; the cross-app degradation only affects the `text/html` payload that destinations like Gmail render.
- **Open Knowledge → Open Knowledge paste round-trips faithfully.** Copying out of one Open Knowledge doc and pasting into another preserves the original markdown image / wiki-link / wiki-embed shape, because the cross-app degradation only fires when the receiving app reads `text/html` instead of `text/plain`.
- **OpenKnowledge → OpenKnowledge paste round-trips faithfully.** Copying out of one OpenKnowledge doc and pasting into another preserves the original markdown image / wiki-link / wiki-embed shape, because the cross-app degradation only fires when the receiving app reads `text/html` instead of `text/plain`.

Source-mode copy (the CodeMirror toggle) works the same way: the clipboard's `text/html` payload is always a styled code block of the raw markdown bytes, never the rendered output. Pasting a `# Heading` from source-mode into Gmail produces a code block, not a rendered heading. This is consistent with VS Code, Obsidian source mode, GitHub textareas, and CodeMirror itself.

Expand Down
Loading