diff --git a/.coderabbit.yaml b/.coderabbit.yaml index 64a62adc4..617d70016 100644 --- a/.coderabbit.yaml +++ b/.coderabbit.yaml @@ -131,7 +131,7 @@ reviews: - Do not treat upstream Karakeep behavior as authoritative when this fork intentionally diverges. - Flag contradictory setup, contributor, deployment, or operator instructions. - - path: "docs/fork-setup.md" + - path: "docs/operator-setup.md" instructions: | - Keep fork, development, and deployment facts aligned with the other canonical repository guidance when those facts change. - Do not treat upstream Karakeep behavior as authoritative when this fork intentionally diverges. diff --git a/.env.sample b/.env.sample index 0338ed8d0..a2ca5e83b 100644 --- a/.env.sample +++ b/.env.sample @@ -1,4 +1,4 @@ -# See https://docs.karakeep.app/configuration for more information +# See the repository documentation for configuration details. DATA_DIR= NEXTAUTH_SECRET= @@ -6,7 +6,7 @@ NEXTAUTH_SECRET= # Real values belong only in .env. KARAKEEP_PROD_SSH_HOST=vps KARAKEEP_PROD_SSH_USER= -KARAKEEP_PROD_COMPOSE_DIR=/home/praya/karakeep +KARAKEEP_PROD_COMPOSE_DIR=/home/praya/marka KARAKEEP_PROD_COMPOSE_SERVICE=web KARAKEEP_PROD_EXPORT_IMAGE=alpine:3.20 EMBEDDING_ENABLE_AUTO_INDEXING=false diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 88f8f1741..358760481 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -2,7 +2,7 @@ name: Build and Push image # Pull-based deploy: this workflow builds + pushes version-compatible web and # workers images to GHCR. The VPS runs Watchtower, which polls those tags and -# redeploys both Karakeep services without an inbound SSH deploy step. +# redeploys both Marka services without an inbound SSH deploy step. on: workflow_run: diff --git a/.wt/config.toml b/.wt/config.toml index e1c921b71..32300fdb8 100644 --- a/.wt/config.toml +++ b/.wt/config.toml @@ -1,15 +1,12 @@ worktree_path = ".worktrees" port_offset_interval = 100 max_slots = 9 +name_strategy = "cities" +branch_template = "{user}/{name}" +default_base = "origin/main" -# Each worktree receives a separate environment, persisted-state copy, ports, -# and Docker container names. setup-worktree.sh snapshots the main workspace's -# local data, which can be refreshed from production with `pnpm prod:pull-state` -# before creating a worktree. -# -# The generated .env is intentionally worktree-local and gitignored. Its -# DATA_DIR and service endpoints use WT_PORT_BASE, preventing concurrent -# worktrees from sharing state or ports. +# Setup prepares isolated dependencies and local state only. It does not start +# a development server or any long-running service. setup = [ "pnpm install --frozen-lockfile", "bash \"$WT_ROOT_PATH/scripts/setup-worktree.sh\"", @@ -17,3 +14,4 @@ setup = [ "ln -sfn ../../.env apps/workers/.env", "ln -sfn ../../.env packages/db/.env", ] +teardown = [] diff --git a/AGENTS.md b/AGENTS.md index 9ffa60899..f1d36a6c5 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,12 +1,12 @@ # Marka assistant context -`absolutepraya/marka` is the Marka fork. The upstream Karakeep project is . +`absolutepraya/marka` is the Marka repository. ## Authoritative documentation map -- `README.md`: public fork framing +- `README.md`: public product framing - `CONTRIBUTING.md`: contribution rules -- `docs/fork-setup.md`: fork operation, local development, and deployment +- `docs/operator-setup.md`: operator setup, local development, and deployment - `docs/README.md`: docs-site development - This file, `CLAUDE.md`, and `GEMINI.md`: concise assistant operations context @@ -18,7 +18,7 @@ - Start local development with `pnpm dev:start`. Use `pnpm dev:start -d` for detached mode and `pnpm dev:stop` to stop only that workspace. - Shared local infrastructure is machine-level: one Meilisearch at `http://localhost:7700` and one Chrome/CDP at `http://localhost:9222`. Manage it explicitly with `pnpm dev:infra:up`, `pnpm dev:infra:status`, and `pnpm dev:infra:down`. - Parallel worktrees keep separate SQLite/assets data and unique web ports. `scripts/setup-worktree.sh` assigns each worktree a unique `MEILI_INDEX_PREFIX`; both `bookmarks` and `bookmarks_vectors` use that namespace on the shared Meilisearch server. -- `pnpm dev:start` defaults the main workspace namespace to `main_`. Outside the fork dev launcher, an unset `MEILI_INDEX_PREFIX` preserves the original `bookmarks` and `bookmarks_vectors` index names. +- `pnpm dev:start` defaults the main workspace namespace to `main_`. An unset `MEILI_INDEX_PREFIX` is a compatibility fallback for the original `bookmarks` and `bookmarks_vectors` names; manual `web` or `workers` starts outside `pnpm dev:start` must set an explicit unique prefix. - Run focused checks before broad checks when practical. Standard checks are `pnpm format:fix`, `pnpm lint`, `pnpm typecheck`, and `pnpm test`. - Validate shared-dev shell behavior with `bash scripts/dev-infra.test.sh`. - Root `.env` is canonical. Do not print or commit secrets. @@ -28,9 +28,9 @@ Preserve package scopes, database paths, export-format names, `KARAKEEP_` variables, Compose service names, GHCR image paths, and Docker-network names. These are operations and compatibility identifiers, not product presentation. -The fork deploys through CI-built GHCR images and VPS Watchtower polling. The canonical production compose is `deploy/docker-compose.prod.yml`; use `docs/fork-setup.md` for the complete operator workflow. +Marka deploys through CI-built GHCR images and VPS Watchtower polling. The canonical production Compose file is `deploy/docker-compose.prod.yml`; use `docs/operator-setup.md` for the complete operator workflow. -Karakeep is a monorepo bookmark-everything app for saving and retrieving links, notes, images, PDFs, highlights, and archived pages. +Marka is a monorepo bookmark library for saving and retrieving links, notes, images, PDFs, highlights, and archived pages. Main stack: - **Frontend:** Next.js, React, TypeScript, Tailwind CSS @@ -63,15 +63,15 @@ Main stack: The preferred portable setup for a new self-hosted instance is `scripts/install.sh`. The public one-line entry point is: ```bash -curl -fsSLo /tmp/karakeep-setup.sh https://raw.githubusercontent.com/absolutepraya/marka/main/scripts/install.sh && bash /tmp/karakeep-setup.sh +curl -fsSLo /tmp/marka-setup.sh https://raw.githubusercontent.com/absolutepraya/marka/main/scripts/install.sh && bash /tmp/marka-setup.sh ``` Important installer facts: - supported host scope is Linux `amd64` with Docker Engine, Docker Compose v2, and OpenSSL already installed - the script never installs Docker, changes firewall rules, configures DNS, or provisions TLS/reverse-proxy infrastructure -- default configuration directory is `~/karakeep`; default persistent data directory is `~/karakeep/data` -- generated Compose project name is `karakeep` +- default configuration directory is `~/marka`; default persistent data directory is `~/marka/data` +- generated Compose project name remains `karakeep` for compatibility - generated app images are the paired `ghcr.io/absolutepraya/marka:web-main` and `ghcr.io/absolutepraya/marka:workers-main` tags - the default web listener is `127.0.0.1:3000`, intended to sit behind an operator-managed reverse proxy for Internet-facing installs - search choices are managed Meilisearch, external Meilisearch, or disabled search @@ -91,7 +91,7 @@ Validate installer changes with: bash scripts/install.test.sh ``` -## Local development for this fork +## Local development ### Runtime - Node 24 (`.nvmrc`) @@ -137,7 +137,7 @@ Parallel-worktree isolation: - every worktree receives a safe unique `MEILI_INDEX_PREFIX` derived from its normalized workspace name plus `WT_PORT_BASE` - both `bookmarks` and `bookmarks_vectors` use that prefix, so separate SQLite states never share Meilisearch documents - `pnpm dev:start` defaults the main workspace prefix to `main_` -- outside this fork's dev launcher, unset `MEILI_INDEX_PREFIX` preserves the original `bookmarks` / `bookmarks_vectors` names +- an unset `MEILI_INDEX_PREFIX` is a compatibility fallback; manual starts outside `pnpm dev:start` must set an explicit unique prefix for the workspace ### Direct commands @@ -171,9 +171,9 @@ Optional root `.env` keys: Every pull restores the full `/data` volume because SQLite rows can reference stored assets. Do not use DB-only pulls or print `.env` secrets. Meilisearch remains derived local state in that workspace's own index namespace. -## Deploy model for this fork +## Deploy model -This fork uses a **pull-based** personal VPS deploy flow that is separate from the portable guided installer. +Marka uses a **pull-based** personal VPS deploy flow that is separate from the portable guided installer. High-level flow: - CI passes on `main` @@ -184,7 +184,7 @@ Important notes: - no inbound SSH push-deploy from CI - canonical personal VPS compose: `deploy/docker-compose.prod.yml` - the guided installer generates its own portable Compose file and does not add Watchtower automatically -- details for the existing personal VPS live in `docs/fork-setup.md` +- details for the existing personal VPS live in `docs/operator-setup.md` ## Quality / maintenance tooling @@ -194,7 +194,7 @@ Standard commands: - `pnpm typecheck` - `pnpm test` -Additional tooling used in this fork: +Additional tooling used in this repository: - `pnpm knip` - unused files / deps / exports - `pnpm doctor` - React health scan via react.doctor - `pnpm doctor:staged` - staged-file React scan @@ -221,18 +221,18 @@ CodeRabbit is currently the only accepted active AI pull-request reviewer. Read ## Documentation guidance This repo's docs are intentionally split into audiences: -- **public/repo-facing** docs explain Karakeep plus this fork's repo identity -- **assistant docs** summarize the same fork facts for tooling +- **public/repo-facing** docs explain Marka and its product identity +- **assistant docs** summarize the same repository facts for tooling - **guided self-host docs** define the portable Docker installer contract -- **operator docs** capture the existing personal VPS deploy/dev workflow of this fork +- **operator docs** capture the existing personal VPS deploy/dev workflow of this repository -If you edit fork/dev/deploy facts, keep these aligned: +If you edit development or deployment facts, keep these aligned: - `README.md` - `CONTRIBUTING.md` - `AGENTS.md` - `CLAUDE.md` - `GEMINI.md` -- `docs/fork-setup.md` +- `docs/operator-setup.md` - `docs/docs/02-installation/11-guided-docker-setup.md` - relevant pages under `docs/docs/**` @@ -258,8 +258,8 @@ pnpm workers ## Working style for assistants -- Prefer repo-specific facts over generic upstream assumptions. +- Prefer repository-specific facts over generic upstream assumptions. - Use the guided Docker setup doc for portable fresh-host installation answers. -- Use `docs/fork-setup.md` for this fork's local-dev and existing personal VPS deployment answers. -- Treat upstream docs as product context, not as authoritative for this fork's operational workflow. +- Use `docs/operator-setup.md` for local development and existing personal VPS deployment answers. +- Treat upstream docs as product context, not as authoritative for Marka's operational workflow. - When changing documentation, avoid leaving split or contradictory setup instructions; rewrite for coherence. diff --git a/CONTEXT.md b/CONTEXT.md index 61954517c..34348e31b 100644 --- a/CONTEXT.md +++ b/CONTEXT.md @@ -1,5 +1,11 @@ # Domain Context +## Product identity + +- **Marka**: The public product identity for this repository and its operator-facing surfaces. +- **Operator-facing name**: A human-visible repository, guide, installer, skill, path, or service label that can change without changing persisted data, protocols, package scopes, or environment-variable contracts. +- **Compatibility identifier**: A retained Karakeep-era name used by code, packages, environment variables, persisted data, export formats, mobile schemes, or external distribution contracts. + ## List collaboration - **List owner**: the user who owns a list. Ownership is not a collaborator membership and is never inherited. @@ -24,4 +30,4 @@ - Moving a descendant out of a recursively shared subtree removes access that existed only through that inheritance. - Explicit direct access on a descendant overrides an inherited role on that descendant. Descendants inherit from the nearest recursive direct grant available on their own ancestor chain. - Accessible parents remain navigable in the shared hierarchy. Inaccessible ancestors are not revealed. -- Public sharing and collaborator sharing can coexist on the same list. \ No newline at end of file +- Public sharing and collaborator sharing can coexist on the same list. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f10326caf..ef74d1b65 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -2,33 +2,24 @@ Thanks for taking the time to improve Marka. -This repository is the **Marka fork** of the upstream project, so contribution flow here is a little different from the main project. +This repository maintains Marka's product, operator workflow, and repository-specific development practices. ## Which repo should you contribute to? -### Contribute upstream if... -- your change is generally useful to the main project -- it is not specific to this fork’s UX/QoL direction -- it affects the broader community-facing product, install flow, or platform support - -Start here: -- Upstream repo: -- Upstream docs: - -### Contribute to this fork if... -- the change is specific to this fork’s UX, operator workflow, or repo-specific maintenance model -- it depends on this fork’s pull-based deploy flow or local-dev scripts -- it intentionally diverges from upstream behavior or presentation +### Contribute here if... +- the change improves Marka's UX, operator workflow, or repository-specific maintenance model +- it depends on Marka's pull-based deploy flow or local-dev scripts +- it improves a product behavior or presentation maintained in this repository ## Before you start - Open an issue or discussion first if the change is large, behavioral, or opinionated. -- If the change probably belongs upstream, prefer proposing it there instead of here. -- Read the fork-specific setup guide: [`docs/fork-setup.md`](docs/fork-setup.md) +- If the change belongs to a different project, propose it there instead of here. +- Read the operator setup guide: [`docs/operator-setup.md`](docs/operator-setup.md) ## Local setup -This fork uses: +Marka uses: - Node 24.18.1 (`.nvmrc`; temporarily pinned to avoid the Node 24.19 native-addon cleanup regression) - `pnpm@11.2.1` via corepack - root `.env` symlinked into `apps/web`, `apps/workers`, and `packages/db` @@ -50,7 +41,7 @@ pnpm db:migrate ``` For the full workflow, detached mode, and production deploy notes, use: -- [`docs/fork-setup.md`](docs/fork-setup.md) +- [`docs/operator-setup.md`](docs/operator-setup.md) ## What to run before opening a PR @@ -80,19 +71,19 @@ Notes: ### UI / UX changes - Include screenshots or a short screen recording. -- Explain why the change fits this fork specifically. +- Explain why the change fits Marka specifically. - Keep the design language consistent with the current app rather than introducing a second style system. ### Schema / backend changes - Add migrations when needed. - Call out any deploy or operator impact clearly. -- Mention if a change would make upstream sync harder. +- Mention any compatibility or migration implications. ### Documentation changes -If you touch fork, development, or deployment facts, follow the authoritative documentation map: -- `README.md` provides public fork framing. +If you touch development or deployment facts, follow the authoritative documentation map: +- `README.md` provides public product framing. - `CONTRIBUTING.md` provides contribution rules. -- `docs/fork-setup.md` provides fork operation. +- `docs/operator-setup.md` provides operator setup. - `docs/README.md` provides docs-site development. - `AGENTS.md`, `CLAUDE.md`, and `GEMINI.md` provide concise assistant operations context. - Relevant docs-site pages under `docs/docs/**` must stay aligned when their content changes. @@ -101,10 +92,10 @@ If you touch fork, development, or deployment facts, follow the authoritative do A good PR for this repo should include: - a clear summary of the change -- why it belongs in this fork +- why it belongs in Marka - screenshots for UI changes - commands run for validation -- any deploy, migration, or sync-with-upstream implications +- any deploy, migration, or compatibility implications ## Review expectations @@ -119,6 +110,4 @@ AI review is advisory: See [`docs/ai-code-review.md`](docs/ai-code-review.md) for the current reviewer policy, rejected-candidate history, permissions ceiling, and future evaluation criteria. -This is a personal fork, so human review cadence is best-effort rather than community-SLA driven. - -If you need a guaranteed path to merge for a generally useful change, the upstream Karakeep project is usually the better place to propose it. +Human review cadence is best-effort rather than community-SLA driven. diff --git a/PRODUCT.md b/PRODUCT.md index 19e9829fe..94358f467 100644 --- a/PRODUCT.md +++ b/PRODUCT.md @@ -6,7 +6,7 @@ product ## Users -A single owner of a self-hosted Karakeep instance (this is a personal fork, not an upstream contribution). The primary user is the operator-owner who lives in the app daily on desktop and mobile. Their context: they come across a link, image, or note and want it **saved in one or two actions, with zero ceremony**, then come back days or weeks later to **find that thing again fast** when they actually need it. +A single owner of a self-hosted Marka instance. The primary user is the operator-owner who lives in the app daily on desktop and mobile. Their context: they come across a link, image, or note and want it **saved in one or two actions, with zero ceremony**, then come back days or weeks later to **find that thing again fast** when they actually need it. The job to be done is two-sided and asymmetric: - **Capture** (high frequency, must be instant): save a bookmark and move on. AI tagging/summarization happens in the background; the user does not babysit it. @@ -16,7 +16,7 @@ In-app long-form reading is explicitly **not** the primary workflow. The app is ## Product Purpose -Karakeep is a self-hostable "bookmark-everything" app: links, notes, images, and PDFs, with background AI tagging and summarization, full-text search, lists, and rule-based organization. This fork serves one person's collection and runs on their own infrastructure. +Marka is a self-hostable bookmark library for links, notes, images, and PDFs, with background AI tagging and summarization, full-text search, lists, and rule-based organization. It serves one person's collection and runs on their own infrastructure. Success looks like: saving is so frictionless it becomes reflexive, and retrieval is so reliable the user trusts the app as the place their information lives. The interface should make a large collection feel navigable rather than overwhelming, and make the act of saving feel instant and certain. diff --git a/README.md b/README.md index 9d0fee161..c4fae9e51 100644 --- a/README.md +++ b/README.md @@ -2,44 +2,16 @@ CI status - - Upstream release - - - Discord - - - Translation status - # Marka -Marka logo +Marka logo Marka is a self-hostable library for saving links, notes, images, PDFs, and web pages, then finding them again with fast search, lists, highlights, and optional AI tagging and summarization. -> [`absolutepraya/marka`](https://github.com/absolutepraya/marka) is the Marka fork. The upstream Karakeep project is . - ![Homepage screenshot](./screenshots/homepage.png) -## What this repository is - -This fork keeps the upstream product intact in spirit, while presenting and operating it as Marka: - -- **Marka fork:** `absolutepraya/marka` -- **Upstream project:** -- **Focus:** UX polish, quality-of-life improvements, and personal deployment ergonomics -- **Local dev:** one-command workflow via `pnpm dev:start` -- **Deploy model:** pull-based Docker image delivery via GHCR + Watchtower - -If you want the main project, releases, or community-first contribution flow, start with the upstream repo: -- Upstream repo: -- Upstream docs: - -If you are here to work on **this fork**, the most important repo-specific guide is: -- [`docs/fork-setup.md`](docs/fork-setup.md) - ## What Marka does Marka can: @@ -54,47 +26,47 @@ Marka can: - save and revisit **highlights** - sync with browser workflows through extensions, RSS, CLI, API, and MCP tooling -### Key features +## Key features -- 🔗 Bookmark links, store notes, images, and PDFs -- 📋 Organize bookmarks into lists -- 👥 Collaborate with others on shared lists -- 🔎 Search across saved content -- ✨ Automatic AI tagging and summarization -- 🖍️ Save highlights from your reading -- 🗄️ Archive full pages to protect against link rot -- 📰 Auto-hoard from RSS feeds -- 🔌 REST API, SDKs, CLI, and MCP server -- 📱 Browser extension + mobile apps -- 💾 Self-hosting first +- Bookmark links, store notes, images, and PDFs +- Organize bookmarks into lists +- Collaborate with others on shared lists +- Search across saved content +- Automatic AI tagging and summarization +- Save highlights from your reading +- Archive full pages to protect against link rot +- Auto-hoard from RSS feeds +- REST API, SDKs, CLI, and MCP server +- Browser extension and mobile apps +- Self-hosting first -## Quick start for this fork +## Quick start ### Guided self-hosted install For a Linux `amd64` host that already has Docker Engine, Docker Compose v2, and OpenSSL, run: ```bash -curl -fsSLo /tmp/karakeep-setup.sh https://raw.githubusercontent.com/absolutepraya/marka/main/scripts/install.sh && bash /tmp/karakeep-setup.sh +curl -fsSLo /tmp/marka-setup.sh https://raw.githubusercontent.com/absolutepraya/marka/main/scripts/install.sh && bash /tmp/marka-setup.sh ``` -The command downloads the script to a file before executing it. The guided flow asks for the install/data directories, public URL, search mode, browser-rendering mode, AI setup, and whether an existing compatible data directory should be reused. It generates a Docker Compose stack using the fork's paired `web-main` and `workers-main` images, writes secrets to restricted env files, validates the Compose config, and then starts the deployment. +The guided flow asks for the install/data directories, public URL, search mode, browser-rendering mode, AI setup, and whether an existing compatible data directory should be reused. It generates a Docker Compose stack using the paired `web-main` and `workers-main` images, writes secrets to restricted env files, validates the Compose config, and starts the deployment. -The default listener is `127.0.0.1:3000`, so an Internet-facing deployment should normally put a reverse proxy with TLS in front of it. The script deliberately does not install Docker, alter firewall rules, configure DNS, or provision certificates. +The default listener is `127.0.0.1:3000`, so an Internet-facing deployment should normally put a reverse proxy with TLS in front of it. The script does not install Docker, alter firewall rules, configure DNS, or provision certificates. For a reproducible setup, replace `main` with an immutable release tag or commit SHA after reviewing that revision: ```bash -REF=; curl -fsSLo /tmp/karakeep-setup.sh "https://raw.githubusercontent.com/absolutepraya/marka/${REF}/scripts/install.sh" && bash /tmp/karakeep-setup.sh +REF=; curl -fsSLo /tmp/marka-setup.sh "https://raw.githubusercontent.com/absolutepraya/marka/${REF}/scripts/install.sh" && bash /tmp/marka-setup.sh ``` After setup, the copied helper supports safe operations without deleting persistent data: ```bash -~/karakeep/install.sh status -~/karakeep/install.sh backup -~/karakeep/install.sh update -~/karakeep/install.sh uninstall +~/marka/install.sh status +~/marka/install.sh backup +~/marka/install.sh update +~/marka/install.sh uninstall ``` For all installer choices, non-interactive usage, rollback guidance, and safety behavior, see [`docs/docs/02-installation/11-guided-docker-setup.md`](docs/docs/02-installation/11-guided-docker-setup.md). @@ -114,14 +86,7 @@ pnpm db:migrate pnpm dev:start ``` -That starts: -- the web app -- background workers -- Meilisearch in Docker -- headless Chrome in Docker - -Then open: -- +That starts the web app, background workers, Meilisearch, and headless Chrome. Then open . Useful variants: @@ -137,106 +102,66 @@ pnpm web pnpm workers ``` -Meilisearch and headless Chrome are optional for booting the app, but required for full search/crawling behavior. +Meilisearch and headless Chrome are optional for booting the app, but required for full search and crawling behavior. ### Pull production state into local dev -The helper below pulls the production `/data` state from the VPS into your local `DATA_DIR`. +The helper below pulls the production `/data` state from the VPS into your local `DATA_DIR`: ```bash pnpm prod:pull-state pnpm prod:pull-state --dry-run ``` -The command replaces local development state by default, first backing up the current `DATA_DIR`. It always pulls the full `/data` volume, including SQLite files and stored assets. Use `--dry-run` to inspect the plan without replacing local state. +The command replaces local development state by default, first backing up the current `DATA_DIR`. It always pulls the full `/data` volume, including SQLite files and stored assets. Required root `.env` keys: + - `DATA_DIR` - `KARAKEEP_PROD_SSH_HOST` - `KARAKEEP_PROD_COMPOSE_DIR` Optional root `.env` keys: + - `KARAKEEP_PROD_SSH_USER` - `KARAKEEP_PROD_COMPOSE_SERVICE` - `KARAKEEP_PROD_EXPORT_IMAGE` -### Full fork/operator setup +### Operator setup -For the complete local-dev and deploy workflow, read: -- [`docs/fork-setup.md`](docs/fork-setup.md) +For the complete local-development and deployment workflow, read [`docs/operator-setup.md`](docs/operator-setup.md). ## Documentation map -### For this fork - Guided Docker self-hosting: [`docs/docs/02-installation/11-guided-docker-setup.md`](docs/docs/02-installation/11-guided-docker-setup.md) -- Fork/local dev/deploy guide: [`docs/fork-setup.md`](docs/fork-setup.md) +- Operator and local-development guide: [`docs/operator-setup.md`](docs/operator-setup.md) - Docs-site development guide: [`docs/README.md`](docs/README.md) -- Contribution guidance for this repo: [`CONTRIBUTING.md`](CONTRIBUTING.md) - -### For upstream product usage -- Upstream main docs: -- Upstream installation docs: -- Upstream configuration docs: -- Upstream development docs: -- Upstream API docs: - -## Demo - -The upstream project maintains the public demo: -- Upstream demo: - -Demo credentials: - -```text -email: demo@karakeep.app (upstream demo) -password: demodemo -``` - -The demo is read-only. - -## Upstream name - -The upstream Karakeep name is inspired by the Arabic word **كراكيب** (*karakeeb*), a colloquial term for miscellaneous clutter, odds and ends, or things that look messy but still feel worth keeping. +- Contribution guidance: [`CONTRIBUTING.md`](CONTRIBUTING.md) ## Tech stack - **Web:** Next.js, React, TypeScript, Tailwind CSS -- **API:** Hono + tRPC +- **API:** Hono and tRPC - **Database:** Drizzle ORM over SQLite (`better-sqlite3`) - **Search:** Meilisearch -- **Crawling:** headless Chrome / browser worker flow +- **Crawling:** headless Chrome and background workers - **Tooling:** pnpm, Turborepo, oxfmt, oxlint, Vitest ## Repo-specific development notes -This fork intentionally differs from upstream in a few practical ways: - -- deploys are **pull-based** rather than SSH push-based -- the canonical production compose lives at `deploy/docker-compose.prod.yml` -- `knip` and `react.doctor` are present as additional quality tooling -- `react-grab` is loaded only in local development for component/source capture +- Deployments are pull-based through GHCR and Watchtower. +- The canonical production Compose file is `deploy/docker-compose.prod.yml`. +- `knip` and `react.doctor` provide additional quality checks. +- `react-grab` is loaded only in local development for component/source capture. ## Contributing -There are two contribution paths: - -1. **Upstream contributions** - - Use the upstream repository: - - Follow the upstream community process - -2. **Fork-specific contributions for this repo** - - Use this repository - - Read [`CONTRIBUTING.md`](CONTRIBUTING.md) - - Prefer changes that are explicitly valuable for this fork’s UX, operator flow, or maintenance model - -## Community and support - -- Upstream Discord: -- Upstream project site: -- Upstream cloud: +Open an issue or discussion first for large, behavioral, or opinionated changes. Read [`CONTRIBUTING.md`](CONTRIBUTING.md) for the repository workflow. ## License -This fork remains licensed under [AGPL-3.0](./LICENSE). +Marka remains licensed under [AGPL-3.0](./LICENSE). + +## Attribution -The upstream Karakeep project is developed by [Localhost Labs Ltd](https://localhostlabs.co.uk). Marka is a personal fork, not the canonical upstream source. +Marka builds on the open-source [Karakeep](https://github.com/karakeep-app/karakeep) project. diff --git a/apps/landing/README.md b/apps/landing/README.md index 2a6d3b7fd..e1f40ada5 100644 --- a/apps/landing/README.md +++ b/apps/landing/README.md @@ -24,4 +24,4 @@ pnpm --filter @karakeep/landing typecheck - This package is separate from the main web app in `apps/web`. - It is mostly relevant when changing marketing pages, homepage copy, or public brand assets. -- For product/docs/deploy workflow of this fork, start from the root `README.md` and `docs/fork-setup.md` instead. +- For product/docs/deploy workflow of this repository, start from the root `README.md` and `docs/operator-setup.md` instead. diff --git a/deploy/docker-compose.prod.yml b/deploy/docker-compose.prod.yml index b67c8af83..df53ecb1f 100644 --- a/deploy/docker-compose.prod.yml +++ b/deploy/docker-compose.prod.yml @@ -1,4 +1,4 @@ -# Karakeep fork production compose, pull-based deploy via Watchtower. +# Marka production Compose, pull-based deploy via Watchtower. # GitHub Actions first pushes immutable version-matched web and workers images, # then promotes their mutable release tags after both builds succeed. Watchtower # rolls each service independently, so adjacent releases must remain compatible. diff --git a/docs/README.md b/docs/README.md index 565d9b7cb..24cc3ffe5 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,6 +1,6 @@ # Docs site -This directory contains the Docusaurus docs site for Marka as maintained in this fork. +This directory contains the Docusaurus docs site for Marka. ## What lives here @@ -16,9 +16,9 @@ This directory contains the Docusaurus docs site for Marka as maintained in this This repository keeps two related but distinct documentation layers: 1. **Repository documentation map** - - `README.md` is the public fork framing. + - `README.md` is the public product framing. - `CONTRIBUTING.md` contains contribution rules. - - `docs/fork-setup.md` contains fork operation. + - `docs/operator-setup.md` contains Marka operator setup. - `docs/README.md` contains docs-site development. - `AGENTS.md`, `CLAUDE.md`, and `GEMINI.md` provide concise assistant operations context. @@ -26,7 +26,7 @@ This repository keeps two related but distinct documentation layers: - end-user and developer docs under `docs/docs/**` - generated API docs under `docs/api/**` -The docs-site configuration and hosted presentation remain owned by deferred docs work. Keep its current upstream product context intact while documenting fork-specific development and operator workflow where relevant. +The docs-site configuration and hosted presentation remain owned by deferred docs work. Keep historical and upstream product context intact while documenting Marka development and operator workflow where relevant. ## Install @@ -73,12 +73,12 @@ and writes to: ## When editing docs -If you change fork/dev/deploy facts, keep the repo docs and docs-site pages aligned. +If you change Marka development or deployment facts, keep the repo docs and docs-site pages aligned. At minimum, check: - `README.md` - `CONTRIBUTING.md` -- `docs/fork-setup.md` +- `docs/operator-setup.md` - `AGENTS.md` - `CLAUDE.md` - `GEMINI.md` diff --git a/docs/docs/01-getting-started/01-intro.md b/docs/docs/01-getting-started/01-intro.md index 3272cf234..a1ef3cb51 100644 --- a/docs/docs/01-getting-started/01-intro.md +++ b/docs/docs/01-getting-started/01-intro.md @@ -4,13 +4,13 @@ slug: / # Introduction -Karakeep is a self-hostable bookmark-everything app for saving links, notes, images, PDFs, highlights, and archived pages, then finding them again quickly with search, lists, and optional AI assistance. +Marka is a self-hostable bookmark library for saving links, notes, images, PDFs, highlights, and archived pages, then finding them again quickly with search, lists, and optional AI assistance. -> These docs primarily describe **Karakeep itself**. This repository is a personal fork of upstream Karakeep, so fork-specific development and deployment notes also live in the repo docs: `README.md`, `CONTRIBUTING.md`, and `docs/fork-setup.md`. +> These docs describe Marka. Repository-specific development and deployment notes also live in `README.md`, `CONTRIBUTING.md`, and `docs/operator-setup.md`. ![Screenshot](https://raw.githubusercontent.com/absolutepraya/marka/main/screenshots/homepage.png) -## What Karakeep can do +## What Marka can do - 🔗 Save links, notes, images, and PDFs - ⬇️ Fetch titles, descriptions, and preview images automatically @@ -29,7 +29,7 @@ Karakeep is a self-hostable bookmark-everything app for saving links, notes, ima ## Where to go next -- **Install Karakeep:** browse the installation guides in this docs site +- **Install Marka:** browse the installation guides in this docs site - **Configure your instance:** see the configuration section - **Use the API:** visit the API reference - **Develop locally:** start with the development setup guide @@ -47,4 +47,4 @@ The demo is read-only. ## About the name -Karakeep is inspired by the Arabic word **كراكيب** (*karakeeb*), a colloquial term for miscellaneous clutter, odds and ends, or things that look messy but still feel worth keeping. That makes it a fitting name for a personal library of saved links, notes, screenshots, and everything else you are not ready to lose. +Marka is designed for a personal library of saved links, notes, screenshots, and everything else you are not ready to lose. diff --git a/docs/docs/02-installation/06-debuntu.md b/docs/docs/02-installation/06-debuntu.md index 7e00946ee..a8ee4b157 100644 --- a/docs/docs/02-installation/06-debuntu.md +++ b/docs/docs/02-installation/06-debuntu.md @@ -13,10 +13,10 @@ The script will download and install all dependencies (except for Ollama), insta The script functions as an update script in addition to an installer. See **[Updating](#updating)**. -### 1. Download the script from the [Marka fork repository](https://github.com/absolutepraya/marka/blob/main/karakeep-linux.sh) +### 1. Download the script from the [Marka repository](https://github.com/absolutepraya/marka/blob/main/marka-linux.sh) ```bash -wget https://raw.githubusercontent.com/absolutepraya/marka/main/karakeep-linux.sh +wget https://raw.githubusercontent.com/absolutepraya/marka/main/marka-linux.sh ``` ### 2. Run the script @@ -26,7 +26,7 @@ wget https://raw.githubusercontent.com/absolutepraya/marka/main/karakeep-linux.s If this is a fresh install, then run the installer by using the following command: ```shell - bash karakeep-linux.sh install + bash marka-linux.sh install ``` ### 3. Create an account/sign in @@ -40,7 +40,7 @@ wget https://raw.githubusercontent.com/absolutepraya/marka/main/karakeep-linux.s If Karakeep has previously been installed using this script, then run the updater like so: ```shell - bash karakeep-linux.sh update + bash marka-linux.sh update ``` ## Services and Ports diff --git a/docs/docs/02-installation/11-guided-docker-setup.md b/docs/docs/02-installation/11-guided-docker-setup.md index cd33eb2fb..d26f742fd 100644 --- a/docs/docs/02-installation/11-guided-docker-setup.md +++ b/docs/docs/02-installation/11-guided-docker-setup.md @@ -1,7 +1,7 @@ # Guided Docker Setup for This Fork :::info Fork-specific setup -This page documents the guided setup shipped by `absolutepraya/marka`. It is not the upstream Karakeep setup flow. +This page documents the guided setup shipped by Marka. ::: The guided script creates a Docker Compose deployment without installing system packages, changing firewall rules, configuring DNS, or provisioning TLS. Docker Engine, Docker Compose v2, and OpenSSL must already be installed on a Linux `amd64` host. @@ -11,15 +11,15 @@ The guided script creates a Docker Compose deployment without installing system Run the latest guided script from this fork: ```bash -curl -fsSLo /tmp/karakeep-setup.sh https://raw.githubusercontent.com/absolutepraya/marka/main/scripts/install.sh && bash /tmp/karakeep-setup.sh +curl -fsSLo /tmp/marka-setup.sh https://raw.githubusercontent.com/absolutepraya/marka/main/scripts/install.sh && bash /tmp/marka-setup.sh ``` -The script is downloaded to a file before execution rather than piped directly into a shell. During setup it copies itself into the selected configuration directory, which defaults to `~/karakeep`. +The script is downloaded to a file before execution rather than piped directly into a shell. During setup it copies itself into the selected configuration directory, which defaults to `~/marka`. For a reproducible setup, pin the download to an immutable release tag or commit SHA after reviewing that revision: ```bash -REF=; curl -fsSLo /tmp/karakeep-setup.sh "https://raw.githubusercontent.com/absolutepraya/marka/${REF}/scripts/install.sh" && bash /tmp/karakeep-setup.sh +REF=; curl -fsSLo /tmp/marka-setup.sh "https://raw.githubusercontent.com/absolutepraya/marka/${REF}/scripts/install.sh" && bash /tmp/marka-setup.sh ``` ## Preflight checks @@ -35,7 +35,7 @@ Before asking configuration questions, the installer checks that the host can ac If a required prerequisite is missing or unusable, setup stops immediately with an actionable error and does not write installation files. The installer deliberately does not install Docker or other host packages for you. -Node.js is **not** a host prerequisite. The Karakeep web application and workers run Node.js inside their Docker images. +Node.js is **not** a host prerequisite. The Marka web application and workers run Node.js inside their Docker images. `curl` is only needed to use the one-line download command. `tar` is checked later when the `backup` command is actually used. @@ -46,7 +46,7 @@ The interactive installer tells you that values shown in square brackets are def It then starts with: ```text -Use the recommended Karakeep setup? [Y/n]: +Use the recommended Marka setup? [Y/n]: ``` Pressing Enter selects the simple, dedicated deployment path. The installer asks only for the configuration directory, persistent data directory, and public application URL, while using these defaults: @@ -59,7 +59,7 @@ Pressing Enter selects the simple, dedicated deployment path. The installer asks - AI configuration deferred - signups enabled for a fresh deployment so the first administrator can be created -If the chosen data directory is already non-empty, the installer does not silently treat it as fresh data. It asks whether it is an existing compatible Karakeep data directory. +If the chosen data directory is already non-empty, the installer does not silently treat it as fresh data. It asks whether it is an existing compatible Marka data directory. Choose **No** at the recommended-setup prompt to enter advanced configuration. Advanced mode exposes the host port and bind address plus managed, external, or disabled search and browser-rendering choices, AI configuration, and the signup policy for an existing deployment. @@ -67,7 +67,7 @@ Fresh deployments always start with signups enabled so the first administrator a ## Generated deployment -The script uses the stable Compose project name `karakeep` and the paired fork images: +The script uses the stable Compose project name `karakeep` for compatibility and the paired Marka images: - `ghcr.io/absolutepraya/marka:web-main` - `ghcr.io/absolutepraya/marka:workers-main` @@ -79,7 +79,7 @@ A default fully featured installation runs four containers: - `meilisearch` for full-text search - `chrome` for browser rendering and screenshots -SQLite is not a separate service. The database and local assets live in the persistent Karakeep data directory shared by `web` and `workers`. +SQLite is not a separate service. The database and local assets live in the persistent Marka data directory shared by `web` and `workers`. The generated files are stored in the selected configuration directory: @@ -95,17 +95,17 @@ The default bind address is `127.0.0.1`. For an Internet-facing deployment, keep ## Search choices -`managed` is the recommended mode. It starts a dedicated Meilisearch container inside this Karakeep Compose project. The service is not published to the host network. +`managed` is the recommended mode. It starts a dedicated Meilisearch container inside this Marka Compose deployment. The service is not published to the host network. `external` is an advanced option for connecting to an externally managed Meilisearch service dedicated to this Karakeep deployment. In non-interactive mode, provide its key through `KARAKEEP_MEILI_MASTER_KEY`. -Do not point multiple independent Karakeep deployments at the same Meilisearch index. Karakeep uses a fixed `bookmarks` index name, so the guided installer does not support a shared Meilisearch index between Karakeep instances. +Do not point multiple independent Marka deployments at the same Meilisearch index. The application uses a fixed `bookmarks` index name, so the guided installer does not support a shared Meilisearch index between Marka instances. `disabled` omits Meilisearch entirely. Full-text search will not be available. ## Browser-rendering choices -`managed` is the recommended mode. It starts Karakeep's maintained Chrome image as a private container and connects the workers through the internal Compose network. The Chrome debugging port is not published to the host. +`managed` is the recommended mode. It starts the maintained Chrome image as a private container and connects the workers through the internal Compose network. The Chrome debugging port is not published to the host. `external` is an advanced option that connects workers on demand to an existing Browserless endpoint. In non-interactive mode, provide the token through `KARAKEEP_BROWSERLESS_TOKEN`. Keep the endpoint private or protect it with TLS, authentication, and suitable capacity limits. @@ -124,7 +124,7 @@ Do not point multiple independent Karakeep deployments at the same Meilisearch i Explicit deployment choices are required in non-interactive mode. Secrets are supplied through environment variables, not flags: ```bash -KARAKEEP_OPENAI_API_KEY='...' bash /tmp/karakeep-setup.sh \ +KARAKEEP_OPENAI_API_KEY='...' bash /tmp/marka-setup.sh \ --non-interactive \ --public-url https://keep.example.com \ --data-mode fresh \ @@ -146,12 +146,12 @@ The persistent data directory is never overwritten or deleted by the script. A n The script copy in the configuration directory also acts as the management helper: ```bash -~/karakeep/install.sh status -~/karakeep/install.sh backup -~/karakeep/install.sh update -~/karakeep/install.sh stop -~/karakeep/install.sh start -~/karakeep/install.sh uninstall +~/marka/install.sh status +~/marka/install.sh backup +~/marka/install.sh update +~/marka/install.sh stop +~/marka/install.sh start +~/marka/install.sh uninstall ``` `backup` briefly stops the web and worker services, archives the authoritative SQLite/assets data directory, then restores them if they were running. Meilisearch is not included because it is a derived search index. The backup command checks for `tar` when it is invoked. diff --git a/docs/docs/06-administration/05-troubleshooting.md b/docs/docs/06-administration/05-troubleshooting.md index 109e24ee6..cd0c88d12 100644 --- a/docs/docs/06-administration/05-troubleshooting.md +++ b/docs/docs/06-administration/05-troubleshooting.md @@ -116,7 +116,7 @@ Use this carefully: deleting `data.ms` wipes the search index, so only do it if For this fork’s current VPS workflow, a Cloudflare orange-cloud proxy can cause redirect-loop behavior depending on SSL mode and nginx redirects. If you hit that while following this repo’s operator workflow, check the notes in: -- `docs/fork-setup.md` +- `docs/operator-setup.md` ## Still stuck? @@ -126,4 +126,4 @@ If you are debugging the product generically, upstream docs and community channe If you are debugging this fork’s local/dev/deploy workflow specifically, prefer the repo docs first: - `README.md` -- `docs/fork-setup.md` +- `docs/operator-setup.md` diff --git a/docs/docs/06-administration/08-hoarder-to-karakeep-migration.md b/docs/docs/06-administration/08-hoarder-to-karakeep-migration.md index 689c730d8..674a6685c 100644 --- a/docs/docs/06-administration/08-hoarder-to-karakeep-migration.md +++ b/docs/docs/06-administration/08-hoarder-to-karakeep-migration.md @@ -22,7 +22,7 @@ You can also change the `HOARDER_VERSION` environment variable but if you do so If you previously used the [Debian/Ubuntu install script](../02-installation/06-debuntu.md) to install Hoarder, there is an option to migrate your installation to Karakeep. ```bash -bash karakeep-linux.sh migrate +bash marka-linux.sh migrate ``` This will migrate your installation with no user input required. After the migration, the script will also check for an update. diff --git a/docs/docs/08-development/01-setup.md b/docs/docs/08-development/01-setup.md index 515140ae4..be7ee3d7f 100644 --- a/docs/docs/08-development/01-setup.md +++ b/docs/docs/08-development/01-setup.md @@ -39,7 +39,7 @@ Useful variants: - `./stop-dev.sh` — stop detached services If you want the full operator-oriented notes for this fork’s local dev and deploy flow, see the repository guide at: -- `docs/fork-setup.md` +- `docs/operator-setup.md` ## Runtime requirements diff --git a/docs/docs/08-development/02-directories.md b/docs/docs/08-development/02-directories.md index a33f7ef4a..39a66f2d5 100644 --- a/docs/docs/08-development/02-directories.md +++ b/docs/docs/08-development/02-directories.md @@ -45,7 +45,7 @@ This repository is a pnpm workspace / Turborepo monorepo. | `README.md` | Public repo overview for this fork | | `CONTRIBUTING.md` | Contribution guidance for this repo | | `AGENTS.md` / `CLAUDE.md` / `GEMINI.md` | Internal assistant-facing repo context | -| `docs/fork-setup.md` | Canonical fork-specific local dev / deploy notes | +| `docs/operator-setup.md` | Canonical local dev / deploy notes | | `docs/docs/**` | Docs-site content | ## Tooling @@ -64,4 +64,4 @@ This repository is a pnpm workspace / Turborepo monorepo. - background job behavior usually lives across `apps/workers` + `packages/trpc` - schema changes start in `packages/db` - shared types/config/helpers usually live in `packages/shared` -- repo-specific dev/deploy behavior is documented in `docs/fork-setup.md` +- repo-specific dev/deploy behavior is documented in `docs/operator-setup.md` diff --git a/docs/fork-setup.md b/docs/operator-setup.md similarity index 92% rename from docs/fork-setup.md rename to docs/operator-setup.md index 7a00f4c28..2333cac4d 100644 --- a/docs/fork-setup.md +++ b/docs/operator-setup.md @@ -1,17 +1,16 @@ -# Fork setup and deploy notes +# Operator setup and deploy notes -This is the canonical operator and developer guide for the **Marka fork**. +This is the canonical operator and developer guide for Marka. Use it for: - local development in this repository - CI and image-build behavior -- production deployment notes specific to this fork +- production deployment notes specific to this repository ## Repo identity - **Origin:** `git@github.com:absolutepraya/marka.git` -- **Upstream project:** `git@github.com:karakeep-app/karakeep.git` -- **Branch model:** `main` is the active integration/deploy branch for this fork +- **Branch model:** `main` is the active integration/deploy branch for this repository ## Local development @@ -60,10 +59,10 @@ Variants: The machine-level infrastructure is shared across all local worktrees: -- `karakeep-dev-meilisearch` on `127.0.0.1:7700` -- `karakeep-dev-chrome` on `127.0.0.1:9222` +- `marka-dev-meilisearch` on `127.0.0.1:7700` +- `marka-dev-chrome` on `127.0.0.1:9222` -The Chrome helper uses `ghcr.io/karakeep-app/karakeep-chrome:release`, which is published for both `linux/amd64` and `linux/arm64`. The Meilisearch container uses the named volume `karakeep-dev-meilisearch-data`, which survives `pnpm dev:infra:down`. +The Chrome helper uses `ghcr.io/karakeep-app/karakeep-chrome:release`, which is published for both `linux/amd64` and `linux/arm64`. The Meilisearch container uses the named volume `marka-dev-meilisearch-data`, which survives `pnpm dev:infra:down`. `pnpm dev:stop` never stops the shared containers. This is intentional: another worktree may still be using them. @@ -114,7 +113,7 @@ Direct commands do not synthesize a namespace for you. Leaving the prefix unset Notes: - Meilisearch and headless Chrome are optional for booting the app, but required for full search/crawling behavior. - If `next dev` crashes with a stale Turbopack / `instrumentation.ts` parse issue, clear `apps/web/.next` and restart. -- If port `7700` is occupied by something other than `karakeep-dev-meilisearch`, or port `9222` by something other than `karakeep-dev-chrome`, `pnpm dev:infra:up` fails instead of silently reusing an unknown service. +- If port `7700` is occupied by something other than `marka-dev-meilisearch`, or port `9222` by something other than `marka-dev-chrome`, `pnpm dev:infra:up` fails instead of silently reusing an unknown service. ### Verify the offline iPhone PWA @@ -175,8 +174,8 @@ It runs: - tests - open-api-spec -Fork-specific notes: -- this fork does **not** use Turbo remote cache +Repository-specific notes: +- this repository does **not** use Turbo remote cache - some CI jobs reclaim disk space before heavy steps because typecheck/tests can otherwise exhaust hosted-runner storage - local development and production use Node 24.18.1 from `.nvmrc`; the combined CI `tests` job temporarily overrides setup to Node 22.21.1 because Vitest + `better-sqlite3` can abort during Node 24 worker teardown; remove that override once the Node fix tracked in [nodejs/node#65042](https://github.com/nodejs/node/pull/65042) ships in a usable Node 24 release - `knip` and `react-doctor` run as **non-blocking** report jobs @@ -191,7 +190,7 @@ Fork-specific notes: ## Build and deploy model -This fork deploys with a **pull-based split Docker flow**. +This repository deploys with a **pull-based split Docker flow**. ### Build path - `.github/workflows/docker.yml` builds the `web` and `workers` targets from the same successful `main` commit @@ -242,7 +241,7 @@ Do not publish a Browserless port. The external `karakeep-renderer` Docker netwo The stale-embedding migration is safe only as a controlled rollout. An empty-queue preflight by itself is not sufficient: pause automatic updates, capture a fresh successful read-only check immediately before the controlled `web` start that applies the migration, then resume automatic updates. -From the directory containing the production compose file: +From the repository root, where the canonical production Compose file is `deploy/docker-compose.prod.yml`: 1. Pause Watchtower so it cannot recreate `web` during the gate: @@ -253,7 +252,7 @@ From the directory containing the production compose file: 2. Immediately before the controlled application start, run this read-only check and record the command's `Embedding queue is empty` output with the deployment timestamp. A non-empty result blocks the cleanup. Do not reuse an earlier successful check or start `web` if this command fails: ```bash - docker exec -i karakeep-fork-web-1 node <<'NODE' + docker compose -f deploy/docker-compose.prod.yml exec -T web node <<'NODE' const Database = require("better-sqlite3"); const db = new Database("/data/queue.db", { readonly: true }); const rows = db.prepare( @@ -320,13 +319,13 @@ docker compose up -d Notes: - create the relevant DNS record before expecting nginx/HTTPS to work -- this fork’s current operator notes assume the service is fronted by nginx +- current operator notes assume the service is fronted by nginx - depending on SSL/proxy mode, a Cloudflare orange-cloud proxy can cause redirect loops; DNS-only/grey-cloud has been the safer path for this setup ## Related docs -- Public fork framing: `README.md` +- Public product framing: `README.md` - Contribution rules: `CONTRIBUTING.md` -- Fork operation: `docs/fork-setup.md` +- Operator operation: `docs/operator-setup.md` - Docs-site development: `docs/README.md` - Assistant operations context: `AGENTS.md`, `CLAUDE.md`, `GEMINI.md` diff --git a/docs/superpowers/plans/2026-06-19-prod-state-pull.md b/docs/superpowers/plans/2026-06-19-prod-state-pull.md index 863000078..cf3e2f453 100644 --- a/docs/superpowers/plans/2026-06-19-prod-state-pull.md +++ b/docs/superpowers/plans/2026-06-19-prod-state-pull.md @@ -23,7 +23,7 @@ - Adds user-facing operator command docs. - Modify: `AGENTS.md` - Adds assistant-facing operator guidance and safety constraints. -- Modify: `docs/fork-setup.md` +- Modify: `docs/operator-setup.md` - Keeps the canonical fork operator guide aligned with the new command. ## Task 1: Add Script @@ -125,7 +125,7 @@ KARAKEEP_PROD_EXPORT_IMAGE=alpine:3.20 **Files:** - Modify: `README.md` - Modify: `AGENTS.md` -- Modify: `docs/fork-setup.md` +- Modify: `docs/operator-setup.md` - [ ] **Step 1: Update README** @@ -148,9 +148,9 @@ Add assistant guidance: - Do not overwrite local state without `--yes`. - Default to full `/data`; use `--db-only` only when explicitly requested. -- [ ] **Step 3: Update docs/fork-setup.md** +- [ ] **Step 3: Update docs/operator-setup.md** -Add the same operator command, required `.env` keys, backup warning, full-state default, and DB-only caveat to the canonical fork setup guide. +Add the same operator command, required `.env` keys, backup warning, full-state default, and DB-only caveat to the canonical operator setup guide. ## Task 4: Verify And Commit @@ -176,7 +176,7 @@ Expected: Run: ```bash -pnpm exec oxfmt --check scripts/pull-prod-state.sh package.json README.md AGENTS.md docs/fork-setup.md .env.sample docs/superpowers/plans/2026-06-19-prod-state-pull.md +pnpm exec oxfmt --check scripts/pull-prod-state.sh package.json README.md AGENTS.md docs/operator-setup.md .env.sample docs/superpowers/plans/2026-06-19-prod-state-pull.md ``` Expected: all checked files use the correct format. @@ -197,6 +197,6 @@ Expected: no whitespace errors and only intended files changed. Run: ```bash -git add scripts/pull-prod-state.sh package.json .env.sample README.md AGENTS.md docs/fork-setup.md docs/superpowers/plans/2026-06-19-prod-state-pull.md +git add scripts/pull-prod-state.sh package.json .env.sample README.md AGENTS.md docs/operator-setup.md docs/superpowers/plans/2026-06-19-prod-state-pull.md git commit -m "Add prod state pull script" ``` diff --git a/docs/superpowers/plans/2026-07-12-lightweight-vps-deployment.md b/docs/superpowers/plans/2026-07-12-lightweight-vps-deployment.md index e275e34e0..da33ab4eb 100644 --- a/docs/superpowers/plans/2026-07-12-lightweight-vps-deployment.md +++ b/docs/superpowers/plans/2026-07-12-lightweight-vps-deployment.md @@ -45,7 +45,7 @@ | `.gitignore` | Prevent the worker-only production secret file from being committed. | | `deploy/docker-compose.prod.yml` | Define split web and worker services; remove dedicated Chrome; keep private Meilisearch and Watchtower updates. | | `.github/workflows/docker.yml` | Publish version-compatible web and worker image tags from the same commit. | -| `docs/fork-setup.md` | Record the new production topology, private renderer requirements, and safe migration procedure. | +| `docs/operator-setup.md` | Record the new production topology, private renderer requirements, and safe migration procedure. | ## Task 1: Make processing status reflect actual enabled work @@ -441,7 +441,7 @@ - Modify: `.env.sample:1-12` - Create: `.workers.env.sample` - Modify: `.gitignore:34-36` -- Modify: `docs/fork-setup.md:140-157` +- Modify: `docs/operator-setup.md:140-157` **Interfaces:** - Consumes: queue preflight proving no `embeddings` jobs exist. @@ -450,7 +450,7 @@ - [ ] **Step 1: Record the queue-safety preflight in the operator documentation** - Add this exact preflight under the production deployment procedure in `docs/fork-setup.md`: + Add this exact preflight under the production deployment procedure in `docs/operator-setup.md`: ```bash docker exec -i karakeep-fork-web-1 node <<'NODE' @@ -542,7 +542,7 @@ - [ ] **Step 6: Commit explicit policy and cleanup migration** ```bash - git add packages/db/drizzle .env.sample .workers.env.sample .gitignore docs/fork-setup.md + git add packages/db/drizzle .env.sample .workers.env.sample .gitignore docs/operator-setup.md git commit -m "fix: clear stale disabled embedding status" ``` ## Task 5: Publish split images and deploy split Karakeep services @@ -550,7 +550,7 @@ **Files:** - Modify: `.github/workflows/docker.yml:45-71` - Modify: `deploy/docker-compose.prod.yml:9-74` -- Modify: `docs/fork-setup.md:121-157` +- Modify: `docs/operator-setup.md:121-157` **Interfaces:** - Produces: `ghcr.io//karakeep:web-main` and `ghcr.io//karakeep:workers-main` from the same CI commit. @@ -656,7 +656,7 @@ - [ ] **Step 5: Update fork operator documentation** - In `docs/fork-setup.md`, replace the AIO-only image language with the split target names and document: + In `docs/operator-setup.md`, replace the AIO-only image language with the split target names and document: - web runs Next.js plus migrations - workers run `WORKER_PROFILE=screenshot-first` @@ -681,7 +681,7 @@ - [ ] **Step 7: Commit split deployment support** ```bash - git add .github/workflows/docker.yml deploy/docker-compose.prod.yml docs/fork-setup.md + git add .github/workflows/docker.yml deploy/docker-compose.prod.yml docs/operator-setup.md git commit -m "feat: deploy lightweight split karakeep services" ``` @@ -777,7 +777,7 @@ Do not commit VPS `.env` files, `.workers.env` files, Compose copies containing secrets, or deployment backups. If the guarded cutover uncovered a source-level documentation correction, commit only that repository change: ```bash - git add docs/fork-setup.md + git add docs/operator-setup.md git commit -m "docs: record shared renderer rollout" ``` diff --git a/docs/superpowers/plans/2026-07-12-offline-library-pwa.md b/docs/superpowers/plans/2026-07-12-offline-library-pwa.md index b5ef4f274..5ec9dbcae 100644 --- a/docs/superpowers/plans/2026-07-12-offline-library-pwa.md +++ b/docs/superpowers/plans/2026-07-12-offline-library-pwa.md @@ -789,7 +789,7 @@ git commit -m "feat: show offline library activity" ## Task 9: Run device acceptance and publish the operator procedure **Files:** -- Modify: `docs/fork-setup.md` +- Modify: `docs/operator-setup.md` **Interfaces:** - Consumes the completed app, service worker, and automated test suites from Tasks 1 through 8. @@ -797,7 +797,7 @@ git commit -m "feat: show offline library activity" - [ ] **Step 1: Add the iPhone PWA acceptance procedure** -Add this exact subsection to `docs/fork-setup.md`: +Add this exact subsection to `docs/operator-setup.md`: ```md ### Verify the offline iPhone PWA @@ -834,6 +834,6 @@ Use an iPhone Safari Home Screen installation and execute each numbered check ad - [ ] **Step 4: Commit verification instructions** ```bash -git add docs/fork-setup.md +git add docs/operator-setup.md git commit -m "docs: verify offline PWA workflow" ``` diff --git a/docs/superpowers/plans/2026-08-14-coderabbit-review.md b/docs/superpowers/plans/2026-08-14-coderabbit-review.md index 6bb8f8f50..732e42700 100644 --- a/docs/superpowers/plans/2026-08-14-coderabbit-review.md +++ b/docs/superpowers/plans/2026-08-14-coderabbit-review.md @@ -192,7 +192,7 @@ Add a reusable documentation instruction for the fork's canonical guidance files instructions: *fork-docs-review - path: "GEMINI.md" instructions: *fork-docs-review - - path: "docs/fork-setup.md" + - path: "docs/operator-setup.md" instructions: *fork-docs-review - path: "docs/docs/**" instructions: *fork-docs-review diff --git a/docs/superpowers/plans/2026-08-15-marka-public-identity-cutover.md b/docs/superpowers/plans/2026-08-15-marka-public-identity-cutover.md index 1f2f65b77..3e29493a7 100644 --- a/docs/superpowers/plans/2026-08-15-marka-public-identity-cutover.md +++ b/docs/superpowers/plans/2026-08-15-marka-public-identity-cutover.md @@ -44,7 +44,7 @@ - `README.md` - canonical public fork repository identity and install links. - `CONTRIBUTING.md` - active contribution/repository references. - `AGENTS.md`, `CLAUDE.md`, `GEMINI.md` - assistant/operator repo identity and guided install references. -- `docs/fork-setup.md` - canonical fork operator/deployment source of truth. +- `docs/operator-setup.md` - canonical operator/deployment source of truth. - `docs/README.md` - docs development references if they point at the fork repository. - `docs/docs/02-installation/11-guided-docker-setup.md` - guided installer contract and image/repository examples. - `docs/docusaurus.config.ts` - update only fork-owned GitHub/repository metadata; preserve upstream-owned URLs. @@ -62,7 +62,7 @@ **Files:** - Read: `AGENTS.md` -- Read: `docs/fork-setup.md` +- Read: `docs/operator-setup.md` - Read: `docs/superpowers/specs/2026-08-15-marka-public-identity-cutover-design.md` - Read: `docs/adr/0001-marka-public-identity-cutover-boundary.md` - Read: issue #27 and issue #35 through GitHub @@ -82,7 +82,7 @@ Use the existing isolated execution worktree for this cutover. If starting this git status --short --branch git remote -v sed -n '1,220p' AGENTS.md -sed -n '1,260p' docs/fork-setup.md +sed -n '1,260p' docs/operator-setup.md ``` Expected in the current execution worktree: `origin` resolves to `git@github.com:absolutepraya/marka.git`; the worktree is clean except for the intentional cutover documentation changes. @@ -146,7 +146,7 @@ Expected: no runtime/external mutation yet. - Modify: `scripts/install.sh` - Modify: `scripts/install.test.sh` - Modify: `docs/docs/02-installation/11-guided-docker-setup.md` -- Modify: `docs/fork-setup.md` +- Modify: `docs/operator-setup.md` - Modify: `AGENTS.md` - Modify: `CLAUDE.md` - Modify: `GEMINI.md` @@ -262,7 +262,7 @@ Expected: only historical records, if any. No current workflow/Compose/installer ```bash git add .github/workflows/docker.yml deploy/docker-compose.prod.yml \ scripts/install.sh scripts/install.test.sh \ - docs/docs/02-installation/11-guided-docker-setup.md docs/fork-setup.md \ + docs/docs/02-installation/11-guided-docker-setup.md docs/operator-setup.md \ AGENTS.md CLAUDE.md GEMINI.md git commit -m "chore: move fork images to Marka GHCR path" ``` @@ -278,7 +278,7 @@ git commit -m "chore: move fork images to Marka GHCR path" - Modify: `AGENTS.md` - Modify: `CLAUDE.md` - Modify: `GEMINI.md` -- Modify: `docs/fork-setup.md` +- Modify: `docs/operator-setup.md` - Modify: `docs/README.md` if it contains active fork repository links - Modify: `docs/docs/02-installation/11-guided-docker-setup.md` - Modify: active installation pages identified by Task 1 @@ -315,7 +315,7 @@ git@github.com:absolutepraya/marka.git https://raw.githubusercontent.com/absolutepraya/marka/main/scripts/install.sh ``` -Apply this to `README.md`, `CONTRIBUTING.md`, `AGENTS.md`, `CLAUDE.md`, `GEMINI.md`, `docs/fork-setup.md`, `docs/README.md` if applicable, and `docs/docs/02-installation/11-guided-docker-setup.md`. +Apply this to `README.md`, `CONTRIBUTING.md`, `AGENTS.md`, `CLAUDE.md`, `GEMINI.md`, `docs/operator-setup.md`, `docs/README.md` if applicable, and `docs/docs/02-installation/11-guided-docker-setup.md`. Do **not** alter `https://github.com/karakeep-app/karakeep` or any other upstream attribution. @@ -358,7 +358,7 @@ Expected: PASS, subject to an already-known repository baseline unrelated to thi ```bash git add apps/web/components/shared/sidebar/SidebarVersion.tsx \ README.md CONTRIBUTING.md AGENTS.md CLAUDE.md GEMINI.md \ - docs/fork-setup.md docs/README.md docs/docs docs/docusaurus.config.ts + docs/operator-setup.md docs/README.md docs/docs docs/docusaurus.config.ts git commit -m "chore: point public fork identity at absolutepraya/marka" ``` @@ -573,7 +573,7 @@ PY )" "$BACKUP_ROOT/data" ``` -If the repository helper's contract has changed, follow the current `docs/fork-setup.md` contract instead and update this plan before proceeding. +If the repository helper's contract has changed, follow the current `docs/operator-setup.md` contract instead and update this plan before proceeding. - [ ] **Step 4: Copy deployed configuration files locally without printing contents** @@ -778,7 +778,7 @@ Do not delete historical old-package images. - [ ] **Step 1: Inspect the current live hostname path before changing it** -On the VPS, capture the existing `keep.abhipraya.dev` nginx server block and listener/port mapping. Confirm which local port proxies to the `web` service. Compare with `docs/fork-setup.md` rather than assuming a container name. +On the VPS, capture the existing `keep.abhipraya.dev` nginx server block and listener/port mapping. Confirm which local port proxies to the `web` service. Compare with `docs/operator-setup.md` rather than assuming a container name. - [ ] **Step 2: Create the Marka DNS record using the same target/proxy mode proven by the current deployment** @@ -1044,7 +1044,7 @@ Expected: application response, not a redirect to the old host. ### Task 13: Finish GitHub-side presentation and active documentation cleanup **Files:** -- Modify as needed: `README.md`, `AGENTS.md`, `CLAUDE.md`, `GEMINI.md`, `docs/fork-setup.md`, guided installer docs, planning docs +- Modify as needed: `README.md`, `AGENTS.md`, `CLAUDE.md`, `GEMINI.md`, `docs/operator-setup.md`, guided installer docs, planning docs - External: GitHub repository description/homepage/topics/social preview/package linkage/settings **Interfaces:** diff --git a/docs/superpowers/plans/2026-08-15-shared-dev-infra.md b/docs/superpowers/plans/2026-08-15-shared-dev-infra.md index 0596a38ef..1b307f198 100644 --- a/docs/superpowers/plans/2026-08-15-shared-dev-infra.md +++ b/docs/superpowers/plans/2026-08-15-shared-dev-infra.md @@ -196,7 +196,7 @@ git commit -m "feat: reuse dev infrastructure across worktrees" ### Task 4: Documentation and assistant guidance **Files:** -- Modify: `docs/fork-setup.md` +- Modify: `docs/operator-setup.md` - Modify: `AGENTS.md` - Modify: PR description after implementation. @@ -209,7 +209,7 @@ Document shared infra architecture, `dev:infra:*` commands, automatic infra star - [ ] **Step 2: Update AGENTS.md** -Keep the assistant-facing local-dev summary aligned with `docs/fork-setup.md`; do not change production installer guidance. +Keep the assistant-facing local-dev summary aligned with `docs/operator-setup.md`; do not change production installer guidance. - [ ] **Step 3: Check CLAUDE/GEMINI representation** @@ -218,7 +218,7 @@ If they are references/symlinks to `AGENTS.md`, do not duplicate edits. If indep - [ ] **Step 4: Commit** ```bash -git add docs/fork-setup.md AGENTS.md +git add docs/operator-setup.md AGENTS.md git commit -m "docs: explain shared worktree dev infrastructure" ``` diff --git a/docs/superpowers/specs/2026-08-14-marka-phase-1-identity-design.md b/docs/superpowers/specs/2026-08-14-marka-phase-1-identity-design.md index 574b32ee0..77ef7a8b8 100644 --- a/docs/superpowers/specs/2026-08-14-marka-phase-1-identity-design.md +++ b/docs/superpowers/specs/2026-08-14-marka-phase-1-identity-design.md @@ -68,7 +68,7 @@ The documentation ownership model is: | --- | --- | | Public fork overview and repository presentation | `README.md` | | Contributions | `CONTRIBUTING.md` | -| Local development and fork operation | `docs/fork-setup.md` | +| Local development and operator operation | `docs/operator-setup.md` | | Docs-site development | `docs/README.md` | | Assistant operating context | `AGENTS.md`, `CLAUDE.md`, and `GEMINI.md` | diff --git a/docs/superpowers/specs/2026-08-14-shared-dev-infra-design.md b/docs/superpowers/specs/2026-08-14-shared-dev-infra-design.md index c56aca47a..36f1c12ef 100644 --- a/docs/superpowers/specs/2026-08-14-shared-dev-infra-design.md +++ b/docs/superpowers/specs/2026-08-14-shared-dev-infra-design.md @@ -231,7 +231,7 @@ Where existing test structure makes direct shell invocation awkward, extract sma Update the canonical fork-development documentation: -- `docs/fork-setup.md` +- `docs/operator-setup.md` - `AGENTS.md` Document: diff --git a/docs/superpowers/specs/2026-08-15-marka-public-identity-cutover-design.md b/docs/superpowers/specs/2026-08-15-marka-public-identity-cutover-design.md index df8214641..eb31bee46 100644 --- a/docs/superpowers/specs/2026-08-15-marka-public-identity-cutover-design.md +++ b/docs/superpowers/specs/2026-08-15-marka-public-identity-cutover-design.md @@ -67,7 +67,7 @@ The internal machine-facing migration is owned by #35. ## Current repository facts that drive the plan -The current repository explicitly treats `docs/fork-setup.md` as the production/operator source of truth and `deploy/docker-compose.prod.yml` as the canonical personal VPS Compose file. Production uses split `web` and `workers` images and Watchtower polls mutable release tags. +The current repository explicitly treats `docs/operator-setup.md` as the production/operator source of truth and `deploy/docker-compose.prod.yml` as the canonical personal VPS Compose file. Production uses split `web` and `workers` images and Watchtower polls mutable release tags. The current Docker workflow constructs `image_name="ghcr.io/${{ github.repository_owner }}/karakeep"`, so renaming the GitHub repository alone will **not** rename the GHCR package. `.github/workflows/docker.yml` must be changed deliberately. @@ -80,7 +80,7 @@ The new `ghcr.io/absolutepraya/marka` package must be proven pullable by the VPS The guided installer also hardcodes the fork's old repository/raw URL and old GHCR path. Its shell-level contract is covered by `bash scripts/install.test.sh`. -Current-tree searches also show the old GitHub identity in the README, assistant docs, installation docs, `docs/fork-setup.md`, `apps/web/components/shared/sidebar/SidebarVersion.tsx`, and other repository-facing documentation. Those hits must be classified, not blindly replaced: some old Karakeep references are intentional upstream attribution or historical specs. +Current-tree searches also show the old GitHub identity in the README, assistant docs, installation docs, `docs/operator-setup.md`, `apps/web/components/shared/sidebar/SidebarVersion.tsx`, and other repository-facing documentation. Those hits must be classified, not blindly replaced: some old Karakeep references are intentional upstream attribution or historical specs. ## Public identity rules @@ -192,7 +192,7 @@ The implementation must inspect and update, where the classification says they a - `AGENTS.md` - `CLAUDE.md` - `GEMINI.md` -- `docs/fork-setup.md` +- `docs/operator-setup.md` - `docs/README.md` - `docs/docs/02-installation/11-guided-docker-setup.md` - other current installation pages returned by repository search @@ -249,7 +249,7 @@ The migration uses checkpoints with a bounded service-recovery path. The reposit Before implementation: - update the implementation worktree/branch from current `main`; -- read `AGENTS.md` and `docs/fork-setup.md` again because they may have changed since this design was written; +- read `AGENTS.md` and `docs/operator-setup.md` again because they may have changed since this design was written; - inspect issue #27 and #35 for newer decisions; - inventory the exact current-tree references and current live configuration; - do not mutate external systems yet. diff --git a/kubernetes/README.md b/kubernetes/README.md index 730871626..0dd61505d 100644 --- a/kubernetes/README.md +++ b/kubernetes/README.md @@ -14,9 +14,9 @@ Before deploying, review and update the local configuration inputs such as `.env ## Note -This fork’s day-to-day operator flow is centered around Docker image builds plus pull-based deployment (`docs/fork-setup.md`), not Kubernetes-first operations. +Marka’s day-to-day operator flow is centered around Docker image builds plus pull-based deployment (`docs/operator-setup.md`), not Kubernetes-first operations. If you are looking for the main self-hosting path, start with: - `README.md` -- `docs/fork-setup.md` +- `docs/operator-setup.md` - upstream docs at diff --git a/karakeep-linux.sh b/marka-linux.sh similarity index 99% rename from karakeep-linux.sh rename to marka-linux.sh index 2875bf232..0f6575190 100644 --- a/karakeep-linux.sh +++ b/marka-linux.sh @@ -37,7 +37,8 @@ EOF } header() { - t_width=$(tput cols 2>/dev/null) + t_width="$(tput cols 2>/dev/null || printf '0')" + t_width="${t_width:-0}" if [[ "$t_width" -gt 115 ]]; then echo -e "$( cat </dev/null || true)" == "true" ]] } +adopt_legacy_container() { + local legacy="$1" current="$2" + if container_exists "$legacy" && ! container_exists "$current"; then + docker rename "$legacy" "$current" >/dev/null || die "Failed to rename legacy $legacy container to $current." + info "Renamed legacy $legacy container to $current" + fi +} + port_in_use() { local port="$1" if command -v lsof >/dev/null 2>&1; then @@ -41,11 +51,12 @@ port_in_use() { ensure_available_port() { local port="$1" owner="$2" if port_in_use "$port"; then - die "Port $port is already in use by something other than $owner. Stop the conflicting service before starting shared Karakeep dev infrastructure." + die "Port $port is already in use by something other than $owner. Stop the conflicting service before starting shared Marka dev infrastructure." fi } ensure_meilisearch() { + adopt_legacy_container "$LEGACY_MEILI_CONTAINER" "$MEILI_CONTAINER" if container_exists "$MEILI_CONTAINER"; then if container_running "$MEILI_CONTAINER"; then info "Reusing shared Meilisearch on http://localhost:$MEILI_PORT" @@ -69,6 +80,7 @@ ensure_meilisearch() { } ensure_chrome() { + adopt_legacy_container "$LEGACY_CHROME_CONTAINER" "$CHROME_CONTAINER" if container_exists "$CHROME_CONTAINER"; then if container_running "$CHROME_CONTAINER"; then info "Reusing shared Chrome on http://localhost:$CHROME_PORT" @@ -130,9 +142,9 @@ down() { removed=1 fi if ((removed)); then - info "Stopped shared Karakeep dev infrastructure. Meilisearch data volume $MEILI_VOLUME was preserved." + info "Stopped shared Marka dev infrastructure. Meilisearch data volume $MEILI_VOLUME was preserved." else - info "Shared Karakeep dev infrastructure is not running." + info "Shared Marka dev infrastructure is not running." fi } diff --git a/scripts/dev-infra.test.sh b/scripts/dev-infra.test.sh index 925ebf831..7d2c19efb 100644 --- a/scripts/dev-infra.test.sh +++ b/scripts/dev-infra.test.sh @@ -82,6 +82,11 @@ case "${1:-}" in name="${@: -1}" rm -f "$state_dir/$name" ;; + rename) + old="${2:?}" + new="${3:?}" + mv "$state_dir/$old" "$state_dir/$new" + ;; ps) for file in "$state_dir"/*; do [[ -e "$file" ]] || continue @@ -126,10 +131,10 @@ done # Shared infra starts exactly one stable Meilisearch and Chrome container. bash "$INFRA" up >/dev/null -assert_contains "$FAKE_DOCKER_LOG" "karakeep-dev-meilisearch" +assert_contains "$FAKE_DOCKER_LOG" "marka-dev-meilisearch" assert_contains "$FAKE_DOCKER_LOG" "127.0.0.1:7700:7700" assert_contains "$FAKE_DOCKER_LOG" "getmeili/meilisearch:v1.41.0" -assert_contains "$FAKE_DOCKER_LOG" "karakeep-dev-chrome" +assert_contains "$FAKE_DOCKER_LOG" "marka-dev-chrome" assert_contains "$FAKE_DOCKER_LOG" "127.0.0.1:9222:9222" assert_contains "$FAKE_DOCKER_LOG" "ghcr.io/karakeep-app/karakeep-chrome:release" @@ -139,13 +144,25 @@ second_run_count="$(grep -c '^run ' "$FAKE_DOCKER_LOG" || true)" [[ "$first_run_count" == "$second_run_count" ]] || fail "Repeated infra up created duplicate containers" # A foreign listener blocks creation instead of being silently reused. -rm -f "$state_dir/karakeep-dev-meilisearch" "$state_dir/karakeep-dev-chrome" +rm -f "$state_dir/marka-dev-meilisearch" "$state_dir/marka-dev-chrome" : >"$FAKE_DOCKER_LOG" if FAKE_BUSY_PORTS=7700 bash "$INFRA" up >"$root/foreign.out" 2>&1; then fail "Shared infra unexpectedly reused a foreign listener on port 7700" fi assert_contains "$root/foreign.out" "Port 7700 is already in use" +# Existing pre-Marka containers are adopted without treating their ports as foreign. +: >"$FAKE_DOCKER_LOG" +printf 'true\n' >"$state_dir/karakeep-dev-meilisearch" +printf 'true\n' >"$state_dir/karakeep-dev-chrome" +bash "$INFRA" up >/dev/null +assert_contains "$FAKE_DOCKER_LOG" "rename karakeep-dev-meilisearch marka-dev-meilisearch" +assert_contains "$FAKE_DOCKER_LOG" "rename karakeep-dev-chrome marka-dev-chrome" +[[ -e "$state_dir/marka-dev-meilisearch" ]] || fail "Meilisearch state was not renamed" +[[ -e "$state_dir/marka-dev-chrome" ]] || fail "Chrome state was not renamed" +[[ ! -e "$state_dir/karakeep-dev-meilisearch" ]] || fail "Legacy Meilisearch state remains" +[[ ! -e "$state_dir/karakeep-dev-chrome" ]] || fail "Legacy Chrome state remains" + # Worktrees share infra endpoints but retain unique web/data state and a Meilisearch-safe namespace. main_root="$root/main" workspace="$root/worktree" @@ -202,10 +219,10 @@ assert_contains "$PACKAGE_JSON" '"dev:infra:down": "bash scripts/dev-infra.sh do # Explicit down owns only the shared infra containers. : >"$FAKE_DOCKER_LOG" -printf 'true\n' >"$state_dir/karakeep-dev-meilisearch" -printf 'true\n' >"$state_dir/karakeep-dev-chrome" +printf 'true\n' >"$state_dir/marka-dev-meilisearch" +printf 'true\n' >"$state_dir/marka-dev-chrome" bash "$INFRA" down >/dev/null -assert_contains "$FAKE_DOCKER_LOG" "rm -f karakeep-dev-meilisearch" -assert_contains "$FAKE_DOCKER_LOG" "rm -f karakeep-dev-chrome" +assert_contains "$FAKE_DOCKER_LOG" "rm -f marka-dev-meilisearch" +assert_contains "$FAKE_DOCKER_LOG" "rm -f marka-dev-chrome" printf 'Shared dev infrastructure tests passed.\n' diff --git a/scripts/install.sh b/scripts/install.sh index a1fb5be38..29efce4e1 100644 --- a/scripts/install.sh +++ b/scripts/install.sh @@ -2,7 +2,7 @@ set -Eeuo pipefail SCRIPT_VERSION="1" -DEFAULT_INSTALL_DIR="${HOME}/karakeep" +DEFAULT_INSTALL_DIR="${HOME}/marka" DEFAULT_PUBLIC_URL="http://localhost:3000" DEFAULT_PORT="3000" DEFAULT_BIND_ADDRESS="127.0.0.1" @@ -49,7 +49,7 @@ die() { printf 'ERROR: %s\n' "$*" >&2; exit 1; } usage() { cat <<'EOF_USAGE' -Karakeep guided Docker Compose installer +Marka guided Docker Compose installer Usage: bash install.sh [install] [options] @@ -59,8 +59,8 @@ Usage: bash install.sh uninstall [--install-dir PATH] Install options: - --install-dir PATH Configuration directory (default: ~/karakeep) - --data-dir PATH Persistent Karakeep data directory (default: /data) + --install-dir PATH Configuration directory (default: ~/marka) + --data-dir PATH Persistent Marka data directory (default: /data) --public-url URL Public application URL, for example https://keep.example.com --port PORT Host port mapped to container port 3000 (default: 3000) --bind-address IP Host bind address (default: 127.0.0.1) @@ -99,8 +99,8 @@ Examples: --public-url https://keep.example.com \ --data-mode fresh --search managed --renderer managed --ai openai - bash install.sh update --install-dir /opt/karakeep - bash install.sh backup --install-dir /opt/karakeep + bash install.sh update --install-dir /opt/marka + bash install.sh backup --install-dir /opt/marka The installer never installs Docker, edits firewall rules, configures DNS, or provisions TLS/reverse proxies. EOF_USAGE @@ -162,7 +162,7 @@ check_platform() { [[ "$(uname -s)" == "Linux" ]] || die "This guided installer currently supports Linux hosts only." case "$(uname -m)" in x86_64|amd64) ;; - *) die "This fork currently publishes linux/amd64 images only; unsupported architecture: $(uname -m)" ;; + *) die "This repository currently publishes linux/amd64 images only; unsupported architecture: $(uname -m)" ;; esac } @@ -173,7 +173,7 @@ check_docker() { } preflight_install() { - say "Karakeep Guided Setup" + say "Marka Guided Setup" say "" say "Checking host prerequisites..." @@ -191,7 +191,7 @@ preflight_install() { case "$(uname -m)" in x86_64|amd64) say " [ok] amd64 architecture" ;; - *) die "This fork currently publishes linux/amd64 images only; unsupported architecture: $(uname -m)" ;; + *) die "This repository currently publishes linux/amd64 images only; unsupported architecture: $(uname -m)" ;; esac require_command openssl @@ -199,7 +199,7 @@ preflight_install() { say "" say "All required host prerequisites are available." - say "Node.js is not required on the host; it runs inside the Karakeep containers." + say "Node.js is not required on the host; it runs inside the Marka containers." say "" } @@ -325,15 +325,15 @@ interactive_configure() { local recommended=0 say "Press Enter to accept the recommended value shown in [brackets]." - say "Choose the recommended setup for a dedicated Karakeep deployment, or advanced setup for external/disabled services." + say "Choose the recommended setup for a dedicated Marka deployment, or advanced setup for external/disabled services." say "" - if prompt_yes_no "Use the recommended Karakeep setup?" "yes"; then + if prompt_yes_no "Use the recommended Marka setup?" "yes"; then recommended=1 else say "" say "Advanced configuration selected." - say "External Meilisearch should be dedicated to this Karakeep instance; sharing one Meilisearch index across multiple Karakeep deployments is not supported by this installer." + say "External Meilisearch should be dedicated to this Marka instance; sharing one Meilisearch index across multiple Marka deployments is not supported by this installer." say "" fi @@ -341,7 +341,7 @@ interactive_configure() { DATA_DIR="$(expand_path "$(prompt_text "Persistent data directory" "${DATA_DIR:-$INSTALL_DIR/data}")")" if [[ -d "$DATA_DIR" && -n "$(find "$DATA_DIR" -mindepth 1 -maxdepth 1 -print -quit 2>/dev/null || true)" ]]; then - DATA_MODE="$(prompt_choice "The data directory is not empty. Treat it as an existing compatible Karakeep data directory?" "existing fresh" "existing")" + DATA_MODE="$(prompt_choice "The data directory is not empty. Treat it as an existing compatible Marka data directory?" "existing fresh" "existing")" elif ((recommended)); then DATA_MODE="fresh" else @@ -376,7 +376,7 @@ interactive_configure() { SEARCH_MODE="$(prompt_choice "Full-text search" "managed external disabled" "${SEARCH_MODE:-$DEFAULT_SEARCH_MODE}")" SEARCH_MODE_SET=1 if [[ "$SEARCH_MODE" == "external" ]]; then - warn "Use a Meilisearch service dedicated to this Karakeep deployment; sharing the fixed bookmarks index with another Karakeep deployment is unsupported." + warn "Use a Meilisearch service dedicated to this Marka deployment; sharing the fixed bookmarks index with another Marka deployment is unsupported." MEILI_URL="$(prompt_text "External dedicated Meilisearch URL" "$MEILI_URL")" if [[ -z "${KARAKEEP_MEILI_MASTER_KEY:-}" ]]; then KARAKEEP_MEILI_MASTER_KEY="$(prompt_secret "External Meilisearch master key")" @@ -464,7 +464,7 @@ validate_install_config() { print_plan() { cat </dev/null || true)" ]]; then - die "Fresh data mode refuses to use non-empty directory $DATA_DIR. Use --data-mode existing only for a compatible Karakeep data directory." + die "Fresh data mode refuses to use non-empty directory $DATA_DIR. Use --data-mode existing only for a compatible Marka data directory." fi else [[ -d "$DATA_DIR" ]] || die "Existing data mode requires the data directory to already exist: $DATA_DIR" @@ -761,7 +761,7 @@ install_command() { docker compose pull docker compose up -d --remove-orphans ) - info "Karakeep is starting. Check status with: $INSTALL_DIR/install.sh status" + info "Marka is starting. Check status with: $INSTALL_DIR/install.sh status" fi say "" @@ -780,9 +780,17 @@ install_command() { } management_install_dir() { - INSTALL_DIR="$(expand_path "${INSTALL_DIR:-$DEFAULT_INSTALL_DIR}")" + if [[ -z "$INSTALL_DIR" && -f "$HOME/marka/docker-compose.yml" ]]; then + INSTALL_DIR="$HOME/marka" + elif [[ -z "$INSTALL_DIR" && -f "$HOME/karakeep/docker-compose.yml" ]]; then + # Keep existing guided installations manageable after the default moves to Marka. + INSTALL_DIR="$HOME/karakeep" + else + INSTALL_DIR="${INSTALL_DIR:-$DEFAULT_INSTALL_DIR}" + fi + INSTALL_DIR="$(expand_path "$INSTALL_DIR")" validate_path "Install directory" "$INSTALL_DIR" - [[ -f "$INSTALL_DIR/docker-compose.yml" ]] || die "No guided Karakeep installation found at $INSTALL_DIR" + [[ -f "$INSTALL_DIR/docker-compose.yml" ]] || die "No guided Marka installation found at $INSTALL_DIR" } compose_in_install_dir() { @@ -820,7 +828,7 @@ backup_command() { local stamp archive web_was_running workers_was_running stamp="$(date -u +%Y%m%dT%H%M%SZ)" - archive="$BACKUP_DIR/karakeep-data-$stamp.tar.gz" + archive="$BACKUP_DIR/marka-data-$stamp.tar.gz" web_was_running="$(compose_in_install_dir ps --status running -q web || true)" workers_was_running="$(compose_in_install_dir ps --status running -q workers || true)" diff --git a/scripts/install.test.sh b/scripts/install.test.sh index 3b9918ca4..f6b5f27fa 100644 --- a/scripts/install.test.sh +++ b/scripts/install.test.sh @@ -111,8 +111,8 @@ recommended_output="$(printf '\n%.0s' {1..12} | HOME="$recommended_home" bash "$ assert_contains "$recommended_output" "Press Enter to accept the recommended value shown in [brackets]." # Bash read -p only emits its prompt for terminal input, so verify the prompt itself in the script # and the resulting configuration behavior separately when stdin is piped for this automated test. -assert_contains "$INSTALLER" "Use the recommended Karakeep setup?" -assert_contains "$recommended_home/karakeep/docker-compose.yml" "ghcr.io/karakeep-app/karakeep-chrome:release" +assert_contains "$INSTALLER" "Use the recommended Marka setup?" +assert_contains "$recommended_home/marka/docker-compose.yml" "ghcr.io/karakeep-app/karakeep-chrome:release" # Dry run must not write configuration or disclose secrets. dry_dir="$root/dry" @@ -146,6 +146,14 @@ assert_contains "$managed/install/workers.env" 'BROWSER_WEB_URL="http://chrome:9 [[ "$(stat -c '%a' "$managed/install/workers.env")" == "600" ]] || fail "workers.env permissions are not 600" [[ "$(stat -c '%a' "$managed/install/install.sh")" == "700" ]] || fail "installed helper permissions are not 700" +# Existing guided installs remain manageable after the default moves to Marka. +legacy_home="$root/legacy-home" +mkdir -p "$legacy_home/karakeep" +touch "$legacy_home/karakeep/docker-compose.yml" +: >"$FAKE_DOCKER_LOG" +HOME="$legacy_home" bash "$INSTALLER" status >/dev/null +assert_contains "$FAKE_DOCKER_LOG" "compose ps" + # A rerun must refuse to overwrite generated configuration unless explicitly requested. before_hash="$(sha256sum "$managed/install/app.env" | awk '{print $1}')" if bash "$INSTALLER" --non-interactive --no-start --yes \ @@ -216,7 +224,7 @@ fi # Backup uses the persisted data directory and never removes it. backup_root="$root/backups" bash "$external/install/install.sh" backup --install-dir "$external/install" --backup-dir "$backup_root" >/dev/null -archive="$(find "$backup_root" -maxdepth 1 -name 'karakeep-data-*.tar.gz' -print -quit)" +archive="$(find "$backup_root" -maxdepth 1 -name 'marka-data-*.tar.gz' -print -quit)" [[ -n "$archive" && -f "$archive" ]] || fail "Backup archive was not created" [[ -f "$external/data/marker" ]] || fail "Backup removed persistent data" diff --git a/skills/SKILL.md b/skills/SKILL.md index c07fa7bb4..68b91c46d 100644 --- a/skills/SKILL.md +++ b/skills/SKILL.md @@ -1,6 +1,6 @@ --- -name: karakeep -description: Official skill for how to use karakeep (the bookmark manager) and interact with it programmatically. +name: marka +description: Official skill for how to use Marka (the bookmark manager) and interact with it programmatically. metadata: tags: bookmarks, bookmark manager, 2nd brain, productivity openclaw: @@ -29,20 +29,20 @@ metadata: bins: [karakeep] --- -# Karakeep +# Marka -Karakeep is an open source self-hosted bookmark manager for collecting, organizing, and searching content. This skill covers the core concepts and how to interact with Karakeep via the CLI. +Marka is an open source self-hosted bookmark manager for collecting, organizing, and searching content. This skill covers the core concepts and how to interact with Marka via the CLI. ## When to use -Use this skill when the user wants to interact with their Karakeep instance (adding bookmarks, managing lists/tags, searching, etc.). +Use this skill when the user wants to interact with their Marka instance (adding bookmarks, managing lists/tags, searching, etc.). ## Core Concepts ### Bookmarks -- **Bookmarks**: Core entity in Karakeep. Can be one of links, text or media. - - **Links**: Save URLs — Karakeep auto-fetches title, description, image, screenshot, and full-page archive. +- **Bookmarks**: A bookmark is the core entity in Marka. It can be a link, text, or media. + - **Links**: Save URLs — Marka auto-fetches title, description, image, screenshot, and full-page archive. - **Text**: Quick notes or text snippets stored as bookmarks. - **Media**: Images and PDFs uploaded directly. - **Favorites**: Star bookmarks for quick access. @@ -62,7 +62,7 @@ Lightweight labels for any bookmark (topics, sources, workflow states). Multiple ### Search Query Language -Karakeep has a powerful search query language for finding the right bookmarks. It supports full-text search, boolean logic, qualifiers, and more. +Marka has a powerful search query language for finding the right bookmarks. It supports full-text search, boolean logic, qualifiers, and more. #### Basic Syntax @@ -115,7 +115,7 @@ machine learning is:fav -is:archived ### RSS Feeds -Karakeep can also be used to consume RSS feeds, but also can itself act as an RSS feed publisher. +Marka can also be used to consume RSS feeds, but also can itself act as an RSS feed publisher. - **Publishing**: Export any list as an RSS feed with a unique token. - **Consuming**: Auto-monitor external RSS feeds and create bookmarks from new items (hourly, with duplicate detection). @@ -124,7 +124,7 @@ Karakeep can also be used to consume RSS feeds, but also can itself act as an RS - **Rule Engine**: If-this-then-that rules to auto-tag, favorite, or route bookmarks to lists. - **Webhooks**: Subscribe to bookmark events (add/update/archive). -## Interacting with Karakeep via the CLI +## Interacting with Marka via the CLI ### Installation @@ -140,7 +140,7 @@ docker run --rm ghcr.io/karakeep-app/karakeep-cli:release --help ### Authentication -The CLI requires an API key and server address. Get the API key from your Karakeep instance's settings page. +The CLI requires an API key and server address. Get the API key from your Marka instance's settings page. **Option 1 — Environment variables (recommended):** @@ -148,7 +148,7 @@ The CLI requires an API key and server address. Get the API key from your Karake export KARAKEEP_API_KEY="your-api-key" # If self-hosted, pass the server address as well. It defaults to the cloud instance if not set: -export KARAKEEP_SERVER_ADDR="https://cloud.karakeep.com" +export KARAKEEP_SERVER_ADDR="https://marka.abhipraya.dev" ``` **Option 2 — CLI flags:**