diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 7b581e615..88f8f1741 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -45,7 +45,7 @@ jobs: id: meta run: | set -euo pipefail - image_name="ghcr.io/${{ github.repository_owner }}/karakeep" + image_name="ghcr.io/${{ github.repository_owner }}/marka" short_sha="$(git rev-parse --short=12 HEAD)" { echo "image_name=${image_name}" diff --git a/AGENTS.md b/AGENTS.md index 9cd5d45e1..9ffa60899 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,6 +1,6 @@ # Marka assistant context -`absolutepraya/karakeep` is the Marka fork. The upstream Karakeep project is . +`absolutepraya/marka` is the Marka fork. The upstream Karakeep project is . ## Authoritative documentation map @@ -63,7 +63,7 @@ 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/karakeep/main/scripts/install.sh && bash /tmp/karakeep-setup.sh +curl -fsSLo /tmp/karakeep-setup.sh https://raw.githubusercontent.com/absolutepraya/marka/main/scripts/install.sh && bash /tmp/karakeep-setup.sh ``` Important installer facts: @@ -72,7 +72,7 @@ Important installer facts: - 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` -- generated app images are the paired `ghcr.io/absolutepraya/karakeep:web-main` and `ghcr.io/absolutepraya/karakeep:workers-main` tags +- 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 - renderer choices are managed private Chrome, external token-protected Browserless, or disabled browser rendering @@ -177,7 +177,7 @@ This fork uses a **pull-based** personal VPS deploy flow that is separate from t High-level flow: - CI passes on `main` -- `.github/workflows/docker.yml` builds and pushes matching `ghcr.io//karakeep:web-main` and `ghcr.io//karakeep:workers-main` images from the same successful commit +- `.github/workflows/docker.yml` builds and pushes matching `ghcr.io//marka:web-main` and `ghcr.io//marka:workers-main` images from the same successful commit - a Watchtower container on the VPS polls the paired GHCR tags and redeploys automatically Important notes: diff --git a/README.md b/README.md index 9a6d5848d..9d0fee161 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@
- - CI status + + CI status Upstream release @@ -19,7 +19,7 @@ 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/karakeep`](https://github.com/absolutepraya/karakeep) is the Marka fork. The upstream Karakeep project is . +> [`absolutepraya/marka`](https://github.com/absolutepraya/marka) is the Marka fork. The upstream Karakeep project is . ![Homepage screenshot](./screenshots/homepage.png) @@ -27,7 +27,7 @@ Marka is a self-hostable library for saving links, notes, images, PDFs, and web This fork keeps the upstream product intact in spirit, while presenting and operating it as Marka: -- **Marka fork:** `absolutepraya/karakeep` +- **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` @@ -75,7 +75,7 @@ Marka can: 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/karakeep/main/scripts/install.sh && bash /tmp/karakeep-setup.sh +curl -fsSLo /tmp/karakeep-setup.sh https://raw.githubusercontent.com/absolutepraya/marka/main/scripts/install.sh && bash /tmp/karakeep-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. @@ -85,7 +85,7 @@ The default listener is `127.0.0.1:3000`, so an Internet-facing deployment shoul 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/karakeep/${REF}/scripts/install.sh" && bash /tmp/karakeep-setup.sh +REF=; curl -fsSLo /tmp/karakeep-setup.sh "https://raw.githubusercontent.com/absolutepraya/marka/${REF}/scripts/install.sh" && bash /tmp/karakeep-setup.sh ``` After setup, the copied helper supports safe operations without deleting persistent data: diff --git a/apps/web/components/shared/sidebar/SidebarVersion.test.tsx b/apps/web/components/shared/sidebar/SidebarVersion.test.tsx index 00fe3aba5..9843efbac 100644 --- a/apps/web/components/shared/sidebar/SidebarVersion.test.tsx +++ b/apps/web/components/shared/sidebar/SidebarVersion.test.tsx @@ -57,12 +57,12 @@ describe("SidebarVersion", () => { it("shows the running app build and a ready deployed update", () => { const { container } = render(); - expect(container.textContent).toContain("absolutepraya/karakeep"); + expect(container.textContent).toContain("absolutepraya/marka"); expect(container.textContent).toContain("Build aaaaaaa"); expect(container.textContent).toContain("Update ready · bbbbbbb"); const buildLink = container.querySelector( - 'a[href="https://github.com/absolutepraya/karakeep/commit/aaaaaaa"]', + 'a[href="https://github.com/absolutepraya/marka/commit/aaaaaaa"]', ); expect(buildLink).not.toBeNull(); }); diff --git a/apps/web/components/shared/sidebar/SidebarVersion.tsx b/apps/web/components/shared/sidebar/SidebarVersion.tsx index b4d744b7b..36d19511b 100644 --- a/apps/web/components/shared/sidebar/SidebarVersion.tsx +++ b/apps/web/components/shared/sidebar/SidebarVersion.tsx @@ -6,7 +6,7 @@ import { usePwaLifecycle } from "@/components/pwa/ServiceWorkerRegistration"; import { useTranslation } from "@/lib/i18n/client"; import { GitBranch, Github } from "lucide-react"; -const FORK_REPO = "absolutepraya/karakeep"; +const FORK_REPO = "absolutepraya/marka"; const FORK_REPO_URL = `https://github.com/${FORK_REPO}`; function isCommitSha(value?: string): value is string { diff --git a/deploy/docker-compose.prod.yml b/deploy/docker-compose.prod.yml index 2621cb4a6..b67c8af83 100644 --- a/deploy/docker-compose.prod.yml +++ b/deploy/docker-compose.prod.yml @@ -8,7 +8,7 @@ # NEXTAUTH_SECRET, MEILI_MASTER_KEY, NEXTAUTH_URL, DISABLE_SIGNUPS, ... services: web: - image: ${KARAKEEP_WEB_IMAGE:-ghcr.io/absolutepraya/karakeep:web-main} + image: ${KARAKEEP_WEB_IMAGE:-ghcr.io/absolutepraya/marka:web-main} restart: unless-stopped mem_limit: 512m depends_on: @@ -28,7 +28,7 @@ services: DATA_DIR: /data workers: - image: ${KARAKEEP_WORKERS_IMAGE:-ghcr.io/absolutepraya/karakeep:workers-main} + image: ${KARAKEEP_WORKERS_IMAGE:-ghcr.io/absolutepraya/marka:workers-main} restart: unless-stopped mem_limit: 512m depends_on: diff --git a/docs/adr/0001-marka-public-identity-cutover-boundary.md b/docs/adr/0001-marka-public-identity-cutover-boundary.md new file mode 100644 index 000000000..ebbbee972 --- /dev/null +++ b/docs/adr/0001-marka-public-identity-cutover-boundary.md @@ -0,0 +1,86 @@ +# ADR 0001: Marka public identity cutover boundary + +- Status: Accepted for implementation planning +- Date: 2026-08-15 +- Issues: #10, #11, #27, #35 + +## Context + +The fork is publicly branded as **Marka**, but its external operational identity still uses Karakeep-era names in several places, including the GitHub repository, GHCR package path, production hostname, installer/repository URLs, and operator documentation. + +A single all-at-once rename of every `karakeep` identifier would mix public branding changes with compatibility-sensitive machine identifiers such as package scopes, environment variables, persisted paths, Compose services, Docker networks, export/protocol identifiers, and other internal names. That would substantially increase migration risk without being required to establish Marka as the public identity. + +The active production deployment is owned by this fork and is operated as a personal deployment, so the public GitHub/GHCR/domain cutover does not need to preserve a general third-party migration window. + +## Decision + +Issue #27 owns only the **public identity cutover**. + +The approved public targets are: + +- GitHub repository: `absolutepraya/marka` +- Canonical application origin: `https://marka.abhipraya.dev` +- GHCR web image: `ghcr.io/absolutepraya/marka:web-main` +- GHCR workers image: `ghcr.io/absolutepraya/marka:workers-main` + +The GHCR migration is a hard switch. CI stops publishing new fork images to `ghcr.io/absolutepraya/karakeep`; historical images may remain but are not a supported compatibility path. + +After the new Marka origin is verified, `keep.abhipraya.dev` becomes a permanent path- and query-preserving redirect to `marka.abhipraya.dev`. + +The GitHub repository is renamed rather than replaced. The old `absolutepraya/karakeep` repository name must not be recreated, so GitHub's rename redirects remain available for historical links. + +Repository-controlled current references, raw GitHub URLs, installer entry points, active badges/links, GHCR references, operator documentation, and Git remotes under our control move to the Marka identity. Git history and historical issue/PR/comment content are not rewritten solely to erase the old name. + +Before any production mutation, a fresh production backup is copied to the local MacBook used by the implementation agent and verified readable. A short controlled maintenance window is acceptable. + +The GitHub rename is intentionally forward-only, but production service recovery remains viable until the cutover stabilizes. Before any mutation, retain the verified local backup, old image references, deployed Compose/environment files, and nginx configuration. If Marka fails before the legacy redirect is enabled, restore the previous Compose image references, `NEXTAUTH_URL`, and old-host application server block from that evidence; do not proceed to the redirect checkpoint. Do not attempt to recreate the old GitHub repository name, because that would break GitHub's rename redirect. + +Database/schema changes and persisted-data rewriting solely for branding are forbidden in #27. + +## Deferred work + +Machine-facing/internal identifiers remain unchanged during #27, including, where applicable: + +- `KARAKEEP_*` environment variables +- `@karakeep/*` package scopes and package names +- persisted data/config/cache paths +- Compose service/project naming +- Docker network names such as `karakeep-renderer` +- export/protocol identifiers and compatibility keys +- other internal constants that do not form the active public identity +- the VPS deployment directory under the operator's home directory +- the MacBook checkout directory under `Documents/Projects` + +The VPS and MacBook directory renames are explicitly deferred to #35. They are machine-facing paths that can affect Compose project discovery, local backup tooling, worktree configuration, shell history, and operator automation. They require their own path-by-path migration and validation rather than an incidental `mv` during #27. + +Their audit and deliberate migration are tracked separately by #35. + +Browser-extension store identity, mobile-store identity, npm/SDK package publishing identity, and MCP distribution identity are also excluded from the #27 publishing cutover. They are audited only for accidental dependency on the GitHub/domain/GHCR values changed by #27; any actual distribution rename is separate follow-up work. + +## Consequences + +### Positive + +- Marka becomes coherent across the actively operated public web, repository, image, and documentation surfaces. +- The production image path and repository name match the public product name. +- The cutover remains small enough to reason about and validate as one controlled operation. +- Compatibility-sensitive internal identifiers are not churned merely for aesthetics. + +### Negative + +- The codebase will temporarily contain intentional internal `karakeep` names after the public cutover. +- Historical GHCR images remain under the old package path. +- A later #35 migration may still be substantial because it must treat internal identifiers as compatibility-sensitive rather than performing blind string replacement. + +## Verification requirement + +The implementation plan for #27 must prove, before completion, that: + +1. `absolutepraya/marka` is the canonical repository and fresh Git operations use it. +2. CI publishes paired Marka `web-main` and `workers-main` images and no longer publishes new fork images under the old package path. +3. Production actually runs the Marka images and Watchtower follows the new tags. +4. `https://marka.abhipraya.dev` works directly, including auth and core application/background-worker behavior. +5. New public/share/RSS URLs use the Marka origin. +6. `keep.abhipraya.dev` redirects to the equivalent Marka path/query once the new origin is proven healthy. +7. Current repository/docs/public metadata no longer use obsolete active identities except where intentionally historical/upstream/internal. +8. The pre-cutover production backup exists on the implementation MacBook and was verified before production mutation. diff --git a/docs/ai-code-review.md b/docs/ai-code-review.md index a51fd928b..3dfaad800 100644 --- a/docs/ai-code-review.md +++ b/docs/ai-code-review.md @@ -104,7 +104,7 @@ A future reviewer must satisfy all of the following before it is approved for on ### Repository scope -- install only for `absolutepraya/karakeep`, not all repositories on the account; +- install only for `absolutepraya/marka`, not all repositories on the account; - review non-draft pull requests targeting `main` where the service supports scope controls; - avoid wasting review quota on generated output and pure dependency-bot PRs where controls exist. @@ -184,7 +184,7 @@ Current accepted example: For any future candidate: 1. Confirm current official pricing/free-tier terms. -2. Confirm the App can be scoped only to `absolutepraya/karakeep`. +2. Confirm the App can be scoped only to `absolutepraya/marka`. 3. Inspect the exact GitHub App permissions before treating the integration as accepted. 4. Reject contents-write, Actions/workflows-write, administration, secrets/environment, or equivalent mutation capability. 5. Enable review-only behavior only. @@ -202,4 +202,4 @@ The complete decision history and evaluation are preserved in: - `docs/superpowers/plans/2026-08-15-ai-reviewer-army.md` - `docs/superpowers/plans/2026-08-15-ai-reviewer-army-live-rollout.md` -Vendor behavior changes over time. Re-check official vendor documentation before reconsidering a rejected integration. \ No newline at end of file +Vendor behavior changes over time. Re-check official vendor documentation before reconsidering a rejected integration. diff --git a/docs/docs/01-getting-started/01-intro.md b/docs/docs/01-getting-started/01-intro.md index e80e46d0a..3272cf234 100644 --- a/docs/docs/01-getting-started/01-intro.md +++ b/docs/docs/01-getting-started/01-intro.md @@ -8,7 +8,7 @@ Karakeep is a self-hostable bookmark-everything app for saving links, notes, ima > 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`. -![Screenshot](https://raw.githubusercontent.com/absolutepraya/karakeep/main/screenshots/homepage.png) +![Screenshot](https://raw.githubusercontent.com/absolutepraya/marka/main/screenshots/homepage.png) ## What Karakeep can do diff --git a/docs/docs/02-installation/01-docker.md b/docs/docs/02-installation/01-docker.md index a279275d7..57b083751 100644 --- a/docs/docs/02-installation/01-docker.md +++ b/docs/docs/02-installation/01-docker.md @@ -19,10 +19,10 @@ mkdir karakeep-app ### 2. Download the compose file -Download the docker compose file provided [here](https://github.com/absolutepraya/karakeep/blob/main/docker/docker-compose.yml) directly into your new directory. +Download the [Docker Compose file](https://github.com/absolutepraya/marka/blob/main/docker/docker-compose.yml) directly into your new directory. ``` -wget https://raw.githubusercontent.com/absolutepraya/karakeep/main/docker/docker-compose.yml +wget https://raw.githubusercontent.com/absolutepraya/marka/main/docker/docker-compose.yml ``` ### 3. Populate the environment variables diff --git a/docs/docs/02-installation/02-unraid.md b/docs/docs/02-installation/02-unraid.md index 7bea771b1..a18fa3f9c 100644 --- a/docs/docs/02-installation/02-unraid.md +++ b/docs/docs/02-installation/02-unraid.md @@ -2,7 +2,7 @@ ## Docker Compose Manager Plugin (Recommended) -You can use [Docker Compose Manager](https://forums.unraid.net/topic/114415-plugin-docker-compose-manager/) plugin to deploy Karakeep using the official docker compose file provided [here](https://github.com/absolutepraya/karakeep/blob/main/docker/docker-compose.yml). After creating the stack, you'll need to setup some env variables similar to that from the docker compose installation docs [here](/installation/docker#3-populate-the-environment-variables). +You can use [Docker Compose Manager](https://forums.unraid.net/topic/114415-plugin-docker-compose-manager/) plugin to deploy Karakeep using the official [Marka fork's Docker Compose file](https://github.com/absolutepraya/marka/blob/main/docker/docker-compose.yml). After creating the stack, you'll need to setup some env variables similar to that from the [Docker Compose installation docs](/installation/docker#3-populate-the-environment-variables). ## Community Apps diff --git a/docs/docs/02-installation/06-debuntu.md b/docs/docs/02-installation/06-debuntu.md index 13b345a6e..7e00946ee 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 [Karakeep repository](https://github.com/absolutepraya/karakeep/blob/main/karakeep-linux.sh) +### 1. Download the script from the [Marka fork repository](https://github.com/absolutepraya/marka/blob/main/karakeep-linux.sh) -``` -wget https://raw.githubusercontent.com/absolutepraya/karakeep/main/karakeep-linux.sh +```bash +wget https://raw.githubusercontent.com/absolutepraya/marka/main/karakeep-linux.sh ``` ### 2. Run the script diff --git a/docs/docs/02-installation/11-guided-docker-setup.md b/docs/docs/02-installation/11-guided-docker-setup.md index 15dddda7c..cd33eb2fb 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/karakeep`. It is not the upstream Karakeep setup flow. +This page documents the guided setup shipped by `absolutepraya/marka`. It is not the upstream Karakeep setup flow. ::: 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,7 +11,7 @@ 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/karakeep/main/scripts/install.sh && bash /tmp/karakeep-setup.sh +curl -fsSLo /tmp/karakeep-setup.sh https://raw.githubusercontent.com/absolutepraya/marka/main/scripts/install.sh && bash /tmp/karakeep-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`. @@ -19,7 +19,7 @@ The script is downloaded to a file before execution rather than piped directly i 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/karakeep/${REF}/scripts/install.sh" && bash /tmp/karakeep-setup.sh +REF=; curl -fsSLo /tmp/karakeep-setup.sh "https://raw.githubusercontent.com/absolutepraya/marka/${REF}/scripts/install.sh" && bash /tmp/karakeep-setup.sh ``` ## Preflight checks @@ -69,8 +69,8 @@ Fresh deployments always start with signups enabled so the first administrator a The script uses the stable Compose project name `karakeep` and the paired fork images: -- `ghcr.io/absolutepraya/karakeep:web-main` -- `ghcr.io/absolutepraya/karakeep:workers-main` +- `ghcr.io/absolutepraya/marka:web-main` +- `ghcr.io/absolutepraya/marka:workers-main` A default fully featured installation runs four containers: diff --git a/docs/docs/03-configuration/01-environment-variables.md b/docs/docs/03-configuration/01-environment-variables.md index 1eb91f22f..3cab645b6 100644 --- a/docs/docs/03-configuration/01-environment-variables.md +++ b/docs/docs/03-configuration/01-environment-variables.md @@ -1,13 +1,13 @@ # Configuration -The app is mainly configured by environment variables. All the used environment variables are listed in [packages/shared/config.ts](https://github.com/absolutepraya/karakeep/blob/main/packages/shared/config.ts). The most important ones are: +The app is mainly configured by environment variables. All the used environment variables are listed in [packages/shared/config.ts](https://github.com/absolutepraya/marka/blob/main/packages/shared/config.ts). The most important ones are: | Name | Required | Default | Description | | -------------------------------------- | ------------------------------------- | --------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | PORT | No | 3000 | The port on which the web server will listen. DON'T CHANGE THIS IF YOU'RE USING DOCKER, instead changed the docker bound external port. | | WORKERS_PORT | No | 0 (Random Port) | The port on which the worker will export its prometheus metrics on `/metrics`. By default it's a random unused port. If you want to utilize those metrics, fix the port to a value (and export it in docker if you're using docker). | | WORKERS_HOST | No | 127.0.0.1 | Host to listen to for requests to WORKERS_PORT. You will need to set this if running in a container, since localhost will not be reachable from outside | -| WORKERS_ENABLED_WORKERS | No | Not set | Comma separated list of worker names to enable. If set, only these workers will run. Valid values: crawler,inference,search,adminMaintenance,video,feed,assetPreprocessing,webhook,ruleEngine,backup. All available workers are listed in [apps/workers/index.ts](https://github.com/absolutepraya/karakeep/blob/main/apps/workers/index.ts#L39). | +| WORKERS_ENABLED_WORKERS | No | Not set | Comma separated list of worker names to enable. If set, only these workers will run. Valid values: crawler,inference,search,adminMaintenance,video,feed,assetPreprocessing,webhook,ruleEngine,backup. All available workers are listed in [apps/workers/index.ts](https://github.com/absolutepraya/marka/blob/main/apps/workers/index.ts#L39). | | WORKERS_DISABLED_WORKERS | No | Not set | Comma separated list of worker names to disable. Takes precedence over `WORKERS_ENABLED_WORKERS`. | | LOG_LEVEL | No | debug | The application log level as defined in the [winston documentation](https://github.com/winstonjs/winston?tab=readme-ov-file#logging-levels). You may want to set this to `notice` or `warning` when running Karakeep in a production environment. | | DATA_DIR | Yes | Not set | The path for the persistent data directory. This is where the db lives. Assets are stored here by default unless `ASSETS_DIR` is set. | diff --git a/docs/docusaurus.config.ts b/docs/docusaurus.config.ts index c4f8eaed1..9f6fc403a 100644 --- a/docs/docusaurus.config.ts +++ b/docs/docusaurus.config.ts @@ -45,7 +45,7 @@ const config: Config = { (item) => !(item.type == "category" && item.label === "API"), ); }, - editUrl: "https://github.com/absolutepraya/karakeep/tree/main/docs/", + editUrl: "https://github.com/absolutepraya/marka/tree/main/docs/", routeBasePath: "/", docItemComponent: "@theme/ApiItem", }, diff --git a/docs/fork-setup.md b/docs/fork-setup.md index 7c5c5d165..7a00f4c28 100644 --- a/docs/fork-setup.md +++ b/docs/fork-setup.md @@ -9,7 +9,7 @@ Use it for: ## Repo identity -- **Origin:** `git@github.com:absolutepraya/karakeep.git` +- **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 @@ -196,7 +196,7 @@ This fork 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 - the workflow first pushes matching immutable `:web-sha-` and `:workers-sha-` tags, then promotes both mutable release tags only after both builds succeed -- the mutable release tags are `ghcr.io//karakeep:web-main` and `ghcr.io//karakeep:workers-main` +- the mutable release tags are `ghcr.io//marka:web-main` and `ghcr.io//marka:workers-main` - `web` runs Next.js and owns database migrations - `workers` runs background work with `WORKER_PROFILE=screenshot-first` diff --git a/docs/superpowers/plans/2026-08-14-coderabbit-review.md b/docs/superpowers/plans/2026-08-14-coderabbit-review.md index 9e2c6b9fa..6bb8f8f50 100644 --- a/docs/superpowers/plans/2026-08-14-coderabbit-review.md +++ b/docs/superpowers/plans/2026-08-14-coderabbit-review.md @@ -2,7 +2,7 @@ > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. -**Goal:** Add a repository-controlled, advisory CodeRabbit review configuration for `absolutepraya/karakeep` and document the contributor workflow without changing existing CI or deployment behavior. +**Goal:** Add a repository-controlled, advisory CodeRabbit review configuration for `absolutepraya/marka` and document the contributor workflow without changing existing CI or deployment behavior. **Architecture:** CodeRabbit behavior is configured entirely through a root `.coderabbit.yaml`; no GitHub Actions workflow is added. Review policy is split into global review settings, path filters for generated artifacts, path-specific instructions for the major monorepo surfaces, and warning-only built-in pre-merge checks. `CONTRIBUTING.md` documents the human-facing workflow and makes clear that GitHub Actions remains authoritative for deterministic validation. @@ -381,12 +381,12 @@ Closes #29 ## Rollout -CodeRabbit remains advisory during the initial calibration period. Existing GitHub Actions checks remain authoritative for deterministic validation. After this PR is ready for review, the maintainer will install the CodeRabbit GitHub App only for `absolutepraya/karakeep` and use this PR as the first live review test. +CodeRabbit remains advisory during the initial calibration period. Existing GitHub Actions checks remain authoritative for deterministic validation. After this PR is ready for review, the maintainer will install the CodeRabbit GitHub App only for `absolutepraya/marka` and use this PR as the first live review test. ``` - [ ] **Step 4: Mark the PR ready for review** -Expected result: PR is no longer a draft. At this exact point, tell the maintainer to authorize/install CodeRabbit for `absolutepraya/karakeep`, scoped to this repository only. +Expected result: PR is no longer a draft. At this exact point, tell the maintainer to authorize/install CodeRabbit for `absolutepraya/marka`, scoped to this repository only. - [ ] **Step 5: After authorization, run the live CodeRabbit smoke test** 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 new file mode 100644 index 000000000..1f2f65b77 --- /dev/null +++ b/docs/superpowers/plans/2026-08-15-marka-public-identity-cutover.md @@ -0,0 +1,1210 @@ +# Marka Public Identity Cutover Implementation Plan + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** Cut the actively operated fork identity over to `absolutepraya/marka`, `ghcr.io/absolutepraya/marka`, and `https://marka.abhipraya.dev` without renaming compatibility-sensitive internal Karakeep identifiers. + +**Architecture:** Prepare all repository-controlled identity changes on one isolated branch, then execute a checkpointed external cutover: local MacBook backup, in-place GitHub repository rename, merge/publish Marka GHCR images, bring up the new hostname directly, move production to the Marka images, verify the complete application, and only then redirect the legacy hostname. `NEXTAUTH_URL` is the runtime source for `serverConfig.publicUrl` and `publicApiUrl`, so the production-origin migration is primarily a deployment/configuration operation rather than a new URL-generation subsystem. + +**Tech Stack:** Git/GitHub, GitHub Actions, GHCR, Docker Compose, Watchtower, nginx/reverse proxy, Cloudflare/DNS/TLS as currently deployed, Next.js/TypeScript, pnpm, shell installer tests. + +## Global Constraints + +- Public repository target is exactly `absolutepraya/marka`. +- Canonical application origin is exactly `https://marka.abhipraya.dev`; do not introduce `app.marka.abhipraya.dev`. +- Canonical fork images are exactly `ghcr.io/absolutepraya/marka:web-main` and `ghcr.io/absolutepraya/marka:workers-main`. +- Do not dual-publish new releases to `ghcr.io/absolutepraya/karakeep`; leave historical old-package images alone. +- `keep.abhipraya.dev` remains live until Marka passes direct validation, then becomes a permanent path- and query-preserving redirect. +- Keep `KARAKEEP_*`, `@karakeep/*`, persisted paths, Compose service/project names, Docker networks, protocol/export identifiers, and other compatibility-sensitive internal names unchanged under #27. #35 owns their later migration. +- Do not rewrite Git history or historical issues/PRs/comments merely to remove old names. +- Browser extension/mobile/npm/SDK/MCP distribution identities are audit-only in #27; do not rename/publish those identities here. +- Do not rename the VPS deployment directory or the MacBook checkout directory in #27. Both are machine-facing paths deferred to #35 after the public cutover stabilizes. +- Before the first production mutation, copy a fresh production backup to the local MacBook running this plan and verify it is readable. Never commit or print secrets. +- A short controlled maintenance window is acceptable. Do not add complexity solely for zero downtime. +- The GitHub rename is forward-only, but service recovery is mandatory until the legacy redirect is enabled. Retain the verified backup and captured Compose, environment, image, and nginx state. If direct Marka validation fails, restore the previous application origin, image references, and old-host application server block before continuing. Never recreate the old GitHub repository name. +- Do not close #27 automatically. + +--- + +## File Structure and Responsibilities + +### Durable design/planning files already created on the planning branch + +- `docs/adr/0001-marka-public-identity-cutover-boundary.md` - durable public-vs-internal identity decision. +- `docs/superpowers/specs/2026-08-15-marka-public-identity-cutover-design.md` - approved #27 design and validation contract. +- `docs/superpowers/plans/2026-08-15-marka-public-identity-cutover.md` - this execution plan. + +### Known implementation files + +- `.github/workflows/docker.yml` - publish fork images under `ghcr.io/absolutepraya/marka`. +- `deploy/docker-compose.prod.yml` - production defaults for paired Marka web/workers images. +- `scripts/install.sh` - guided installer fork repository/raw URL and generated Marka image defaults. +- `scripts/install.test.sh` - installer assertions for repository/GHCR defaults. +- `apps/web/components/shared/sidebar/SidebarVersion.tsx` - current fork GitHub repo/commit link. +- `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/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. +- Current installation pages found by the final repository search - update only active fork-specific links, not generic upstream instructions or versioned historical copies unless they are intentionally current. + +### Runtime configuration, not source renames + +- Production `NEXTAUTH_URL` becomes `https://marka.abhipraya.dev`. +- Production `packages/shared/config.ts` does **not** need a branding rename: it already derives `serverConfig.publicUrl` from `NEXTAUTH_URL` and `publicApiUrl` from that origin. +- Actual OAuth callback/provider settings, CORS/origin settings, webhook destinations, and reverse-proxy files are discovered from the live configuration at execution time because secrets/operator-specific values must not be committed or guessed. + +--- + +### Task 1: Refresh the execution workspace and produce the final cutover inventory + +**Files:** +- Read: `AGENTS.md` +- Read: `docs/fork-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 +- Modify: none + +**Interfaces:** +- Consumes: current `main`, planning branch `absolutepraya/marka-public-cutover-plan`, current production `.env` access available only at execution time. +- Produces: a current classified list of old fork-identity references and a confirmed implementation worktree based on the latest `main`. + +- [ ] **Step 1: Use the isolated execution worktree for this cutover** + +Use the existing isolated execution worktree for this cutover. If starting this plan from a new checkout, use the repository's `wt` workflow and base it on the latest `origin/main`; do not edit a stale root worktree. + +- [ ] **Step 2: Re-read current repository guidance** + +```bash +git status --short --branch +git remote -v +sed -n '1,220p' AGENTS.md +sed -n '1,260p' docs/fork-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. + +- [ ] **Step 3: Inventory old public identities in the current tree** + +```bash +rg -n --hidden \ + --glob '!node_modules' \ + --glob '!.git' \ + 'absolutepraya/karakeep|github\.com/absolutepraya/karakeep|raw\.githubusercontent\.com/absolutepraya/karakeep|ghcr\.io/absolutepraya/karakeep|keep\.abhipraya\.dev' . +``` + +For each hit, classify it in working notes as exactly one of: + +```text +ACTIVE_FORK_IDENTITY +UPSTREAM_ATTRIBUTION +INTERNAL_COMPATIBILITY_#35 +HISTORICAL_RECORD +DEFERRED_DISTRIBUTION +``` + +Do not commit the working notes if they contain operator-specific details. + +- [ ] **Step 4: Run the broad Karakeep-name audit without replacing anything** + +```bash +rg -ni --hidden --glob '!node_modules' --glob '!.git' 'karakeep' . > /tmp/marka-karakeep-audit.txt +wc -l /tmp/marka-karakeep-audit.txt +``` + +Use this only to identify missed active public surfaces. `KARAKEEP_*`, `@karakeep/*`, upstream references, data paths, Compose services, and Docker networks are expected to remain. + +- [ ] **Step 5: Confirm the known runtime origin behavior before changing source** + +```bash +rg -n 'NEXTAUTH_URL|publicUrl|publicApiUrl' packages/shared packages/api packages/trpc apps/web +``` + +Confirm `packages/shared/config.ts` still maps `NEXTAUTH_URL` to `serverConfig.publicUrl` and builds `publicApiUrl` from it. If that invariant still holds, do not add a second Marka-origin constant. + +- [ ] **Step 6: Commit only if the planning documents had to be carried onto a fresh implementation branch** + +```bash +git add docs/adr/0001-marka-public-identity-cutover-boundary.md \ + docs/superpowers/specs/2026-08-15-marka-public-identity-cutover-design.md \ + docs/superpowers/plans/2026-08-15-marka-public-identity-cutover.md +git commit -m "docs: plan Marka public identity cutover" +``` + +Expected: no runtime/external mutation yet. + +--- + +### Task 2: Change the fork's GHCR publishing contract to Marka + +**Files:** +- Modify: `.github/workflows/docker.yml` +- Modify: `deploy/docker-compose.prod.yml` +- 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: `AGENTS.md` +- Modify: `CLAUDE.md` +- Modify: `GEMINI.md` + +**Interfaces:** +- Consumes: existing paired web/workers build flow and mutable `web-main` / `workers-main` promotion semantics. +- Produces: one canonical fork image package `ghcr.io/absolutepraya/marka` with unchanged tag semantics. + +- [ ] **Step 1: Update installer tests first** + +In `scripts/install.test.sh`, change assertions that intentionally describe this fork's image package from: + +```text +ghcr.io/absolutepraya/karakeep:web-main +ghcr.io/absolutepraya/karakeep:workers-main +``` + +to: + +```text +ghcr.io/absolutepraya/marka:web-main +ghcr.io/absolutepraya/marka:workers-main +``` + +Also update assertions for the fork's raw installer URL from `absolutepraya/karakeep` to `absolutepraya/marka` when those assertions represent the canonical fork entry point. Leave generic internal `karakeep` Compose/data names untouched. + +- [ ] **Step 2: Run the installer tests and verify they fail against the old implementation** + +```bash +bash scripts/install.test.sh +``` + +Expected: at least the changed canonical-repository/GHCR assertions fail because `scripts/install.sh` still emits the old public identity. + +- [ ] **Step 3: Change the Docker workflow image package** + +In `.github/workflows/docker.yml`, change only the fork package basename in `Prepare image metadata`: + +```bash +image_name="ghcr.io/${{ github.repository_owner }}/marka" +``` + +Keep all of these unchanged: + +```text +web-sha- +workers-sha- +web-main +workers-main +paired immutable build first +paired mutable promotion only after both builds succeed +``` + +Do not add old-package alias tags. + +- [ ] **Step 4: Change production Compose image defaults** + +In `deploy/docker-compose.prod.yml`, set: + +```yaml +services: + web: + image: ${KARAKEEP_WEB_IMAGE:-ghcr.io/absolutepraya/marka:web-main} + workers: + image: ${KARAKEEP_WORKERS_IMAGE:-ghcr.io/absolutepraya/marka:workers-main} +``` + +Do not rename `KARAKEEP_WEB_IMAGE`, `KARAKEEP_WORKERS_IMAGE`, service names, volumes, or `karakeep-renderer` in #27. + +- [ ] **Step 5: Change guided installer public fork defaults** + +In `scripts/install.sh`, update every value classified `ACTIVE_FORK_IDENTITY` so that: + +```text +GitHub repository = absolutepraya/marka +raw installer repo = absolutepraya/marka +web image = ghcr.io/absolutepraya/marka:web-main +workers image = ghcr.io/absolutepraya/marka:workers-main +``` + +Do not rename generated config directories, Compose project name, environment-variable names, helper command names, or data paths merely because they contain lowercase `karakeep`; those belong to #35. + +- [ ] **Step 6: Update the canonical image-path documentation** + +Update the listed authoritative docs/assistant files so every statement about **this fork's current GHCR images** uses: + +```text +ghcr.io/absolutepraya/marka:web-main +ghcr.io/absolutepraya/marka:workers-main +``` + +Keep upstream images such as `ghcr.io/karakeep-app/karakeep-chrome:release` unchanged. + +- [ ] **Step 7: Re-run installer validation** + +```bash +bash scripts/install.test.sh +``` + +Expected: PASS. + +- [ ] **Step 8: Verify no active old fork package remains in implementation-controlled files** + +```bash +rg -n 'ghcr\.io/absolutepraya/karakeep' \ + .github deploy scripts README.md CONTRIBUTING.md AGENTS.md CLAUDE.md GEMINI.md docs apps +``` + +Expected: only historical records, if any. No current workflow/Compose/installer/operator instruction may retain the old fork package. + +- [ ] **Step 9: Commit the distribution-contract change** + +```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 \ + AGENTS.md CLAUDE.md GEMINI.md +git commit -m "chore: move fork images to Marka GHCR path" +``` + +--- + +### Task 3: Change active repository identity references to `absolutepraya/marka` + +**Files:** +- Modify: `apps/web/components/shared/sidebar/SidebarVersion.tsx` +- Modify: `README.md` +- Modify: `CONTRIBUTING.md` +- Modify: `AGENTS.md` +- Modify: `CLAUDE.md` +- Modify: `GEMINI.md` +- Modify: `docs/fork-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 +- Modify: `docs/docusaurus.config.ts` only for fork-owned repository metadata +- Modify: this design/plan only after the live rename when their current-repository links become active instructions + +**Interfaces:** +- Consumes: the Task 1 classification. +- Produces: all current active fork links point to `absolutepraya/marka`, while upstream/historical/internal references remain correct. + +- [ ] **Step 1: Update the visible sidebar repository link** + +In `apps/web/components/shared/sidebar/SidebarVersion.tsx`, change: + +```ts +const FORK_REPO = "absolutepraya/karakeep"; +``` + +to: + +```ts +const FORK_REPO = "absolutepraya/marka"; +``` + +Keep commit-SHA validation and URL construction unchanged. + +- [ ] **Step 2: Update canonical public and operator docs** + +Where the text refers to this fork, replace the active repository identities with: + +```text +https://github.com/absolutepraya/marka +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`. + +Do **not** alter `https://github.com/karakeep-app/karakeep` or any other upstream attribution. + +- [ ] **Step 3: Update other current installation pages surfaced by the exact search** + +Re-run: + +```bash +rg -n --hidden --glob '!node_modules' --glob '!.git' \ + 'absolutepraya/karakeep|github\.com/absolutepraya/karakeep|raw\.githubusercontent\.com/absolutepraya/karakeep' . +``` + +For every `ACTIVE_FORK_IDENTITY` hit, update to `absolutepraya/marka`. For `HISTORICAL_RECORD`, leave the text as historical unless that document is still an active runbook. Do not mechanically edit versioned upstream docs merely because the repository search found them. + +- [ ] **Step 4: Audit Docusaurus repository metadata** + +Open `docs/docusaurus.config.ts`. Change a GitHub/repository URL only if it points specifically at this fork's old repository. Preserve upstream `karakeep-app/karakeep`, `karakeep.app`, or upstream documentation links when they are intentionally upstream-owned. + +- [ ] **Step 5: Verify the active repository reference audit** + +```bash +rg -n --hidden --glob '!node_modules' --glob '!.git' \ + 'absolutepraya/karakeep|github\.com/absolutepraya/karakeep|raw\.githubusercontent\.com/absolutepraya/karakeep' . +``` + +Expected before final historical classification: no active current instructions, runtime links, installer entry points, or current fork presentation remain on the old repository path. + +- [ ] **Step 6: Run focused source checks** + +```bash +pnpm format:fix +pnpm lint +pnpm typecheck +``` + +Expected: PASS, subject to an already-known repository baseline unrelated to this branch. Any new failure caused by this task must be fixed before proceeding. + +- [ ] **Step 7: Commit the repository-identity source changes** + +```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 +git commit -m "chore: point public fork identity at absolutepraya/marka" +``` + +If `git status` shows unrelated versioned historical files changed by an accidental broad replacement, restore those files before committing. + +--- + +### Task 4: Audit origin-derived runtime behavior and prepare production-host settings + +**Files:** +- Read: `packages/shared/config.ts` +- Read: `packages/api/utils/rss.ts` +- Read: `packages/api/routes/rss.ts` +- Read: `packages/trpc/email.ts` +- Read: `packages/trpc/routers/subscriptions.ts` +- Search/read: public-list/share URL producers and metadata files returned by the commands below +- Modify: source files only if a hardcoded old production hostname is actually present +- Modify at deployment time: production `.env` / provider dashboards / reverse-proxy config, never commit secrets + +**Interfaces:** +- Consumes: `serverConfig.publicUrl` derived from `NEXTAUTH_URL`. +- Produces: proof that setting production `NEXTAUTH_URL=https://marka.abhipraya.dev` makes generated public URLs use Marka, plus an exact live-config checklist for any provider-specific callback/origin changes. + +- [ ] **Step 1: Inspect every server-side public URL consumer** + +```bash +rg -n 'serverConfig\.publicUrl|serverConfig\.publicApiUrl|NEXTAUTH_URL' \ + packages/shared packages/api packages/trpc apps/web +``` + +Confirm RSS/email/subscription/public URL construction derives from the server config rather than `keep.abhipraya.dev`. + +- [ ] **Step 2: Search for hardcoded production hosts in runtime source** + +```bash +rg -n 'keep\.abhipraya\.dev|marka\.abhipraya\.dev' \ + apps packages .env.sample docker kubernetes +``` + +Expected before source edits: no runtime hardcoded `keep.abhipraya.dev` that bypasses `NEXTAUTH_URL`. If a hardcoded old host exists and is genuinely fork-owned runtime behavior, replace it with config-derived behavior, not another hardcoded Marka host unless the file is explicitly operator documentation. + +- [ ] **Step 3: Identify actual production auth integrations without exposing secrets** + +On the MacBook, inspect only variable **names/presence** in the local operator `.env`, never values: + +```bash +python - <<'PY' +from pathlib import Path +for raw in Path('.env').read_text().splitlines(): + line = raw.strip() + if not line or line.startswith('#') or '=' not in line: + continue + key = line.split('=', 1)[0] + if key.startswith(('NEXTAUTH_', 'OAUTH_', 'TURNSTILE_', 'SMTP_', 'STRIPE_', 'KARAKEEP_PROD_')): + print(key) +PY +``` + +Use the resulting presence list to decide which external callback/origin dashboards actually need inspection. Never paste provider secret values into issue comments or commits. + +- [ ] **Step 4: Define the production environment change** + +The live application config must contain: + +```text +NEXTAUTH_URL=https://marka.abhipraya.dev +``` + +Do not rename `NEXTAUTH_URL` itself. Preserve all unrelated values. + +For each configured OAuth/provider/origin integration discovered in Step 3, add the exact Marka callback/origin required by the current application route **before** removing or disabling the old callback. Determine the callback path from current auth configuration/source, not from memory. + +- [ ] **Step 5: Run focused tests only if source code changed** + +If Step 2 required source edits, add or update the nearest unit test to assert URLs are built from `serverConfig.publicUrl`, then run that focused test plus: + +```bash +pnpm lint +pnpm typecheck +``` + +If no source code changed, record that the origin migration is deployment configuration only and continue. + +- [ ] **Step 6: Commit only actual source/test changes** + +If no runtime source was changed, do not create an empty commit. + +--- + +### Task 5: Run complete repository validation before any external mutation + +**Files:** +- Modify: implementation branch only to fix failures caused by Tasks 2-4 + +**Interfaces:** +- Consumes: prepared code/docs cutover branch. +- Produces: one reviewable branch that is safe to merge immediately after the GitHub rename. + +- [ ] **Step 1: Run formatting, linting, and type checking** + +```bash +pnpm format:fix +pnpm lint +pnpm typecheck +pnpm --filter @karakeep/docs typecheck +pnpm --filter @karakeep/docs build +bash scripts/install.test.sh +``` + +Expected: PASS for branch-caused behavior. + +- [ ] **Step 2: Run the repository's relevant tests** + +Run focused tests for any runtime files changed. If runtime changes extend beyond static repository URL strings, run: + +```bash +pnpm test +``` + +If the repository still has a known unrelated baseline failure, capture the exact failing job/test and prove it reproduces on the comparison baseline before treating it as non-blocking. + +- [ ] **Step 3: Inspect the diff for accidental internal renames** + +```bash +git diff origin/main...HEAD -- . ':!docs/superpowers/plans/2026-08-15-marka-public-identity-cutover.md' ':!docs/superpowers/specs/2026-08-15-marka-public-identity-cutover-design.md' +``` + +Reject changes that rename `KARAKEEP_*`, `@karakeep/*`, `karakeep-renderer`, persisted paths, or Compose services solely for branding. + +- [ ] **Step 4: Run the old-public-identity audit** + +```bash +rg -n --hidden --glob '!node_modules' --glob '!.git' \ + 'absolutepraya/karakeep|github\.com/absolutepraya/karakeep|raw\.githubusercontent\.com/absolutepraya/karakeep|ghcr\.io/absolutepraya/karakeep|keep\.abhipraya\.dev' . +``` + +At this stage, remaining hits must be explainable as historical design records or the documented legacy redirect source. Active fork code/docs must not depend on old GitHub/GHCR identities. + +- [ ] **Step 5: Push the prepared implementation branch without merging it yet** + +```bash +git push -u origin HEAD +``` + +Expected: branch is available on GitHub for review while production/GitHub identity are still unchanged. + +--- + +### Task 6: Capture and verify the MacBook-local production backup + +**Files:** +- Local-only output outside the repository: `~/Backups/marka-cutover//` +- Read locally: root `.env` for `KARAKEEP_PROD_*` connection metadata; do not print secrets +- Read remotely: deployed Compose directory and nginx/reverse-proxy configuration + +**Interfaces:** +- Consumes: current known-good production state immediately before live mutation. +- Produces: verified local data/config snapshot and a non-secret manifest. + +- [ ] **Step 1: Create a timestamped local backup directory outside the repository** + +```bash +BACKUP_ROOT="$HOME/Backups/marka-cutover/$(date -u +%Y%m%dT%H%M%SZ)" +mkdir -p "$BACKUP_ROOT" +printf '%s\n' "$BACKUP_ROOT" +``` + +Record the printed path in private working notes. Do not commit the backup. + +- [ ] **Step 2: Load only the production connection metadata needed by existing tooling** + +Use the repository's documented `.env`/production helper conventions. Do not `cat .env`. Confirm the required keys exist by name: + +```bash +python - <<'PY' +from pathlib import Path +keys = {line.split('=',1)[0].strip() for line in Path('.env').read_text().splitlines() if '=' in line and not line.lstrip().startswith('#')} +required = {'KARAKEEP_PROD_SSH_HOST', 'KARAKEEP_PROD_COMPOSE_DIR', 'DATA_DIR'} +missing = sorted(required - keys) +if missing: + raise SystemExit(f"missing required keys: {', '.join(missing)}") +print('required production connection keys are present') +PY +``` + +Expected: `required production connection keys are present`. + +- [ ] **Step 3: Pull a fresh copy of production persisted `/data` using the existing helper** + +First inspect without mutation: + +```bash +pnpm prod:pull-state --dry-run +``` + +Then perform the documented full-state pull into the local dev `DATA_DIR`: + +```bash +pnpm prod:pull-state +``` + +Copy the resulting local data snapshot into the backup root without following it back into Git: + +```bash +cp -a "$(python - <<'PY' +from pathlib import Path +for line in Path('.env').read_text().splitlines(): + if line.startswith('DATA_DIR='): + print(line.split('=',1)[1].strip()) + break +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. + +- [ ] **Step 4: Copy deployed configuration files locally without printing contents** + +Resolve `KARAKEEP_PROD_SSH_HOST`, optional `KARAKEEP_PROD_SSH_USER`, and `KARAKEEP_PROD_COMPOSE_DIR` from `.env` using the same safe parser approach as the repository helper. Copy the deployed Compose file and environment files using `scp` into `$BACKUP_ROOT/config/`. + +The files to capture when present are: + +```text +docker-compose.yml or the deployed canonical Compose filename +.env +.workers.env +``` + +Do not display file contents in terminal logs or issue comments. + +- [ ] **Step 5: Capture reverse-proxy configuration and current image identity** + +Over SSH, save `nginx -T` output to a file under `$BACKUP_ROOT/config/` rather than the repository, and save non-secret Docker inspection output containing current image names/IDs/digests for `web` and `workers`. + +The output may contain hostnames and paths but must not contain environment-variable values or container environment dumps. + +- [ ] **Step 6: Generate a non-secret local manifest and verify readability** + +```bash +MANIFEST_TMP="$(mktemp "${TMPDIR:-/tmp}/marka-cutover-checksums.XXXXXX")" +find "$BACKUP_ROOT" -type f ! -path "$BACKUP_ROOT/SHA256SUMS" \ + -exec shasum -a 256 {} + \ + | LC_ALL=C sort > "$MANIFEST_TMP" +mv "$MANIFEST_TMP" "$BACKUP_ROOT/SHA256SUMS" +du -sh "$BACKUP_ROOT" +find "$BACKUP_ROOT" -maxdepth 3 -type f -print +``` + +Then verify a representative SQLite/database file can be opened read-only or run the repository's safe local state validation against the copied data without modifying the backup. + +Expected: backup files exist, checksums are generated, and the persisted state is readable. + +- [ ] **Step 7: Stop if backup verification is incomplete** + +Do not rename the repository, touch DNS, or change production until Task 6 is fully successful. + +--- + +### Task 7: Verify the in-place GitHub rename and execution remote + +**Files:** +- External: GitHub repository metadata +- Local Git config: execution worktree `origin` +- Modify after rename: current planning/spec links if they are active current-repository references + +**Interfaces:** +- Consumes: prepared, pushed branch and verified local backup. +- Produces: live repository `absolutepraya/marka` with old-path redirect intact and a working new Git remote. + +The in-place repository rename is a completed prerequisite for this branch. This task is idempotent verification only and must never issue a second rename request or create the old repository name. + +- [ ] **Step 1: Confirm the repository is named `absolutepraya/marka` and the prepared branch is pushed** + +```bash +gh repo view absolutepraya/marka --json nameWithOwner,url,defaultBranchRef + +git status --short --branch +git log -1 --oneline +``` + +Expected: clean branch and repository name `absolutepraya/marka`. + +- [ ] **Step 2: Ensure the local execution remote uses the canonical repository** + +Update the remote only when it is not already canonical: + +```bash +if [[ "$(git remote get-url origin)" != "git@github.com:absolutepraya/marka.git" ]]; then + git remote set-url origin git@github.com:absolutepraya/marka.git +fi +git remote -v +git fetch origin +``` + +Expected: fetch succeeds through the new canonical path. + +- [ ] **Step 3: Verify old and new repository behavior** + +```bash +gh repo view absolutepraya/marka --json nameWithOwner,url +git ls-remote git@github.com:absolutepraya/marka.git HEAD +``` + +Also verify the old web repository URL redirects to the new repository. Do **not** create `absolutepraya/karakeep` as a placeholder. + +- [ ] **Step 4: Update active planning-document links that still describe the current repo with the old path** + +Change current links in the ADR/spec/plan from `https://github.com/absolutepraya/karakeep/...` to the renamed repository when they are intended as current navigation. Preserve explicit historical examples describing the pre-cutover state. + +- [ ] **Step 5: Commit and push any post-rename documentation fixups** + +```bash +git add docs/adr/0001-marka-public-identity-cutover-boundary.md \ + docs/superpowers/specs/2026-08-15-marka-public-identity-cutover-design.md \ + docs/superpowers/plans/2026-08-15-marka-public-identity-cutover.md +if ! git diff --cached --quiet; then + git commit -m "docs: point cutover records at renamed repository" +fi +git push origin HEAD +``` + +If there were no link changes, do not create an empty commit. + +--- + +### Task 8: Merge the prepared cutover branch and publish the Marka GHCR package + +**Files:** +- External: GitHub PR/main branch and Actions +- Consumes source changes from Tasks 2-5 + +**Interfaces:** +- Consumes: renamed GitHub repository and prepared branch. +- Produces: `main` capable of publishing only `ghcr.io/absolutepraya/marka` fork images. + +- [ ] **Step 1: Update the implementation branch from renamed `origin/main` if main moved** + +```bash +git fetch origin +git rebase origin/main +``` + +Resolve conflicts by preserving the #27 boundary. Re-run Task 5 validation after any conflict resolution. + +- [ ] **Step 2: Open or update the implementation PR against `main`** + +The PR description must state: + +```text +- repository has already been renamed to absolutepraya/marka +- this PR switches fork GHCR publishing to ghcr.io/absolutepraya/marka +- production has NOT yet been pointed at the new images +- internal Karakeep identifiers remain intentionally unchanged (#35) +- local pre-cutover backup has been verified +``` + +Do not claim production cutover is complete. + +- [ ] **Step 3: Wait for/review actual CI results and fix branch-caused failures** + +Inspect failing job logs rather than guessing. The PR is merge-ready only when branch-caused checks are green or a known baseline failure has been explicitly demonstrated as unrelated. + +- [ ] **Step 4: Merge only when explicitly authorized by the repository owner** + +The project guardrail forbids merging without explicit instruction. If authorization has not been given in the execution conversation, stop here and report that the next external prerequisite is the PR merge. + +- [ ] **Step 5: After authorized merge, inspect the Docker workflow run triggered from successful `main` CI** + +Verify the workflow pushes the paired immutable tags and promotes: + +```text +ghcr.io/absolutepraya/marka:web-main +ghcr.io/absolutepraya/marka:workers-main +``` + +- [ ] **Step 6: Verify both Marka mutable tags exist and record their digests** + +Use GHCR/Docker tooling available on the MacBook, for example: + +```bash +docker buildx imagetools inspect ghcr.io/absolutepraya/marka:web-main +docker buildx imagetools inspect ghcr.io/absolutepraya/marka:workers-main +``` + +Expected: both resolve successfully for `linux/amd64`. Record the resulting digest identifiers in private execution notes and later completion evidence. + +- [ ] **Step 7: Prove the VPS can pull the new public package before the maintenance window** + +From the VPS, without adding registry credentials, pull or inspect both canonical tags: + +```bash +docker pull ghcr.io/absolutepraya/marka:web-main +docker pull ghcr.io/absolutepraya/marka:workers-main +``` + +Expected: both pulls succeed and resolve to the digests recorded in the prior step. A MacBook-local image inspection is not sufficient evidence because it can use local credentials. Do not stop Watchtower or alter deployed Compose references until this succeeds. + +- [ ] **Step 8: Confirm the old package is no longer a workflow output** + +Inspect the successful workflow logs/metadata. There must be no new `ghcr.io/absolutepraya/karakeep:*` push created by the updated workflow. + +Do not delete historical old-package images. + +--- + +### Task 9: Provision `marka.abhipraya.dev` as a direct application origin + +**Files:** +- External: DNS/Cloudflare record for `marka.abhipraya.dev` +- External: nginx/reverse-proxy/TLS configuration on the VPS +- External/local secret config: production `.env` +- External provider dashboards: only actually configured auth/origin integrations + +**Interfaces:** +- Consumes: existing production web listener and existing `keep.abhipraya.dev` setup. +- Produces: both old and new hostnames can reach the app during validation, with Marka configured as the canonical app origin. + +- [ ] **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. + +- [ ] **Step 2: Create the Marka DNS record using the same target/proxy mode proven by the current deployment** + +Create `marka.abhipraya.dev` pointing at the same VPS/application endpoint as the existing app. Preserve the currently working Cloudflare proxy/DNS mode unless there is verified evidence it must differ. + +- [ ] **Step 3: Add a direct Marka reverse-proxy/TLS server configuration** + +Configure nginx so `marka.abhipraya.dev` proxies to the same application listener as the current live host. At this stage, **do not** redirect `keep.abhipraya.dev`. + +Obtain/verify TLS for the Marka hostname using the VPS's existing certificate workflow. + +- [ ] **Step 4: Update production canonical application URL** + +Edit the production environment file in place so it contains: + +```text +NEXTAUTH_URL=https://marka.abhipraya.dev +``` + +Preserve all unrelated keys and secret values. Do not print the file. + +- [ ] **Step 5: Update only actually configured external callbacks/origins** + +For each OAuth/auth/provider/origin integration proven present in Task 4, add/update the exact callback/origin for `marka.abhipraya.dev`. Keep the old callback temporarily if the provider supports both and the old hostname is still live during validation. + +- [ ] **Step 6: Reload/recreate only what is required for the new origin to take effect** + +Reload nginx after configuration validation: + +```bash +sudo nginx -t +sudo systemctl reload nginx +``` + +Recreate/restart the application services through Compose so the changed `NEXTAUTH_URL` is loaded. Use service names, not hardcoded generated container names. + +- [ ] **Step 7: Verify direct Marka reachability before touching the old hostname** + +From the MacBook: + +```bash +curl -fsSI https://marka.abhipraya.dev/ +``` + +Expected: valid HTTPS response from the application path with no redirect to `keep.abhipraya.dev`. + +Then use a browser to verify direct login, authenticated reload/session persistence, and logout on Marka. + +Stop here on any auth/cookie/redirect-loop problem. + +--- + +### Task 10: Switch production web/workers to the Marka GHCR package + +**Files:** +- External VPS deployed Compose/environment configuration +- Repository source already updated: `deploy/docker-compose.prod.yml` + +**Interfaces:** +- Consumes: verified Marka GHCR tags from Task 8 and functioning Marka hostname from Task 9. +- Produces: live production running `ghcr.io/absolutepraya/marka:web-main` and `:workers-main`, with Watchtower tracking them. + +- [ ] **Step 1: Enter the controlled maintenance window and prevent Watchtower from racing the manual switch** + +From the deployed Compose directory: + +```bash +docker compose stop watchtower +``` + +Confirm only Watchtower is stopped; do not destroy data volumes. + +- [ ] **Step 2: Update the deployed Compose image references** + +Ensure the deployed Compose file or its image overrides resolve to exactly: + +```text +ghcr.io/absolutepraya/marka:web-main +ghcr.io/absolutepraya/marka:workers-main +``` + +Keep the same Compose project, services, volumes, networks, env files, ports, and data paths. + +- [ ] **Step 3: Pull both images explicitly** + +```bash +docker compose pull web workers +``` + +Expected: both Marka images pull successfully before the running services are replaced. + +- [ ] **Step 4: Recreate web and workers from the new images** + +```bash +docker compose up -d --no-deps --force-recreate web +docker compose up -d --force-recreate workers +``` + +The web recreation is intentionally separate. The workers command omits `--no-deps` so Compose enforces `workers.depends_on.web` with `condition: service_healthy` before starting workers. + +- [ ] **Step 5: Verify service health and actual image identity** + +```bash +docker compose ps +docker compose images +``` + +Use `docker inspect` by Compose service/container discovery to confirm web/workers resolve to the intended Marka image references/digests. Do not depend on generated container names in documentation. + +- [ ] **Step 6: Restart Watchtower only after both application services are healthy** + +```bash +docker compose start watchtower +docker compose ps watchtower +``` + +Confirm Watchtower is running and the Compose services it monitors now reference the Marka package paths. + +--- + +### Task 11: Execute the Marka production smoke-test matrix + +**Files:** +- Modify: none unless a failing check exposes a branch/config defect that must be fixed forward +- External: live application and production services + +**Interfaces:** +- Consumes: live Marka origin and Marka GHCR production services. +- Produces: explicit evidence that the new identity is functional before legacy redirect. + +- [ ] **Step 1: Verify infrastructure** + +From the MacBook: + +```bash +dig +short marka.abhipraya.dev +curl -fsSI https://marka.abhipraya.dev/ +``` + +On the VPS: + +```bash +docker compose ps +``` + +Confirm web, workers, Meilisearch, and Watchtower are healthy/running as expected. + +- [ ] **Step 2: Verify authentication in a browser** + +Perform, in order: + +```text +1. login at https://marka.abhipraya.dev +2. authenticated page reload +3. close/reopen a normal tab and confirm session remains +4. logout +5. login again if needed for the remaining tests +``` + +No old-host redirect loop or cookie failure is acceptable. + +- [ ] **Step 3: Verify core bookmark behavior** + +Using a disposable test URL/bookmark: + +```text +1. create bookmark +2. confirm it appears in library +3. edit its title +4. search for the edited title/content +5. wait for crawler/archive processing +6. verify screenshot processing +7. verify configured AI behavior if production AI is enabled +8. delete the disposable bookmark +``` + +- [ ] **Step 4: Verify public behavior and origin-derived URLs** + +Publish/open a safe test public list or use a disposable existing list. Confirm: + +```text +public-list page loads on marka.abhipraya.dev +owner/avatar/current public-list UI renders +newly copied/generated public-list URL begins https://marka.abhipraya.dev +RSS/feed URL begins https://marka.abhipraya.dev +RSS/feed request succeeds where RSS is enabled +``` + +If an origin-derived URL still uses the old host, trace it to `serverConfig.publicUrl`/configuration before changing application code. + +- [ ] **Step 5: Verify deployment identity** + +Confirm again that production is running the Marka web/workers images and Watchtower is active. + +Do not enable the old-host redirect until every applicable check in Task 11 passes. + +--- + +### Task 12: Convert `keep.abhipraya.dev` into the permanent legacy redirect + +**Files:** +- External: nginx/reverse-proxy configuration for `keep.abhipraya.dev` +- DNS record remains present so legacy URLs continue resolving + +**Interfaces:** +- Consumes: fully verified Marka app origin. +- Produces: one canonical live application origin with legacy URL continuity. + +**Recovery boundary:** Until this task is complete, a failure on direct Marka validation must be recovered by restoring the pre-cutover application-origin setting, Compose image references, and old-host nginx application server block captured in Task 6. Do not attempt to reverse the GitHub rename or recreate `absolutepraya/karakeep`. + +- [ ] **Step 1: Replace the old live-app server block with a path/query-preserving permanent redirect** + +For nginx, use equivalent semantics to: + +```nginx +server { + server_name keep.abhipraya.dev; + return 308 https://marka.abhipraya.dev$request_uri; +} +``` + +Preserve the site's existing TLS/listen directives needed for HTTPS on the legacy hostname. Do not redirect to a fixed `/` path because `$request_uri` must retain path and query. + +- [ ] **Step 2: Validate and reload nginx** + +```bash +sudo nginx -t +sudo systemctl reload nginx +``` + +Expected: config test succeeds before reload. + +- [ ] **Step 3: Verify root redirect** + +```bash +curl -sSI https://keep.abhipraya.dev/ | sed -n '1p;/^[Ll]ocation:/p' +``` + +Expected status: `308` and location `https://marka.abhipraya.dev/`. + +- [ ] **Step 4: Verify path and query preservation** + +Using a real safe public-list path discovered during Task 11: + +```bash +curl -sSI 'https://keep.abhipraya.dev/?marka-cutover=1' | sed -n '1p;/^[Ll]ocation:/p' +``` + +Expected location exactly preserves `?marka-cutover=1` on `https://marka.abhipraya.dev`. + +Do not substitute a made-up public-list identifier. Use the actual safe path verified in Task 11. + +- [ ] **Step 5: Verify normal Marka access still does not redirect back** + +```bash +curl -fsSI https://marka.abhipraya.dev/ +``` + +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 +- External: GitHub repository description/homepage/topics/social preview/package linkage/settings + +**Interfaces:** +- Consumes: completed live repo/GHCR/domain cutover. +- Produces: coherent current public repository presentation with intentional old-name remnants documented rather than accidentally retained. + +- [ ] **Step 1: Audit GitHub repository metadata** + +Inspect the renamed repository's: + +```text +name +repository description +homepage/website +topics +social preview +default branch +Actions/environment references +webhooks, if any +GitHub Pages setting, if any +GHCR package linkage/presentation +``` + +Change only values that still encode the obsolete fork public identity. Do not alter unrelated permissions, secrets, rulesets, or branch protection. + +- [ ] **Step 2: Run the final exact old-public-identity search** + +```bash +rg -n --hidden --glob '!node_modules' --glob '!.git' \ + 'absolutepraya/karakeep|github\.com/absolutepraya/karakeep|raw\.githubusercontent\.com/absolutepraya/karakeep|ghcr\.io/absolutepraya/karakeep|keep\.abhipraya\.dev' . +``` + +Allowed remaining classes are: + +```text +HISTORICAL_RECORD +LEGACY_REDIRECT_DOCUMENTATION +``` + +There must be no current runtime/installer/deployment dependency on the old repo/GHCR identity. + +- [ ] **Step 3: Run the broad Karakeep classification audit** + +```bash +rg -ni --hidden --glob '!node_modules' --glob '!.git' 'karakeep' . > /tmp/marka-final-karakeep-audit.txt +``` + +Review remaining current-tree hits and make sure they fit one of: + +```text +UPSTREAM_ATTRIBUTION +INTERNAL_COMPATIBILITY_#35 +HISTORICAL_RECORD +DEFERRED_DISTRIBUTION +``` + +If an actual user-facing stale Marka/Karakeep branding miss is found, fix it now. Do not rename internal identifiers. + +- [ ] **Step 4: Audit deferred distribution apps for broken coupling only** + +```bash +rg -n 'absolutepraya/karakeep|raw\.githubusercontent\.com/absolutepraya/karakeep|ghcr\.io/absolutepraya/karakeep|keep\.abhipraya\.dev' \ + apps/browser-extension apps/mobile apps/mcp packages/sdk packages/open-api 2>/dev/null || true +``` + +If a hit breaks because the repository/domain/GHCR resource moved, update that dependency to the new public resource. Do not change the app/store/package distribution identity itself. Open a separate follow-up issue if a broader distribution rename is desired. + +- [ ] **Step 5: Run final repository checks** + +```bash +pnpm format:fix +pnpm lint +pnpm typecheck +pnpm --filter @karakeep/docs typecheck +pnpm --filter @karakeep/docs build +bash scripts/install.test.sh +``` + +Run focused runtime tests changed by any final fixes. + +- [ ] **Step 6: Commit final cleanup** + +```bash +git status --short +git add -A +git diff --cached --check +git commit -m "docs: finalize Marka public identity references" +``` + +Before committing, inspect `git diff --cached --name-only` and ensure no local backup, `.env`, secret file, or unrelated historical mass-edit is staged. + +- [ ] **Step 7: Push and use the normal PR/CI workflow for any post-cutover source changes** + +```bash +git push origin HEAD +``` + +Do not merge a post-cutover cleanup PR without explicit owner authorization. + +--- + +### Task 14: Record completion evidence without closing #27 + +**Files:** +- External: issue #27 comment, only after implementation/validation is actually complete +- Modify: none required + +**Interfaces:** +- Consumes: completed validation evidence from Tasks 6-13. +- Produces: concise owner-reviewable cutover report and leaves issue state open. + +- [ ] **Step 1: Assemble only non-secret evidence** + +The report must include: + +```text +Repository: https://github.com/absolutepraya/marka +Old repository redirect: verified/not verified +GHCR web-main digest: +GHCR workers-main digest: +Production image paths: exact Marka paths +Canonical origin: https://marka.abhipraya.dev +Auth smoke test: pass/fail +Core bookmark/crawler/screenshot smoke test: pass/fail +Public-list/RSS origin test: pass/fail +Legacy keep.abhipraya.dev redirect: pass/fail, including path/query preservation +Watchtower on new image paths: pass/fail +Local backup directory: local path only +Remaining Karakeep hits: summarized by upstream/internal/history/deferred categories +#35 internal-rename follow-up: still open +``` + +Never include `.env` values, tokens, provider secrets, SSH keys, or backup file contents. + +- [ ] **Step 2: Post the evidence to #27** + +Use a concise comment containing the actual values recorded during execution. Do not use placeholder text from this plan. + +- [ ] **Step 3: Leave #27 open** + +Report that the cutover implementation and validation are complete and wait for explicit owner instruction before closing #27. + +--- + +## Self-review checklist for the implementation agent + +Before claiming the plan is complete, verify all of the following: + +- [ ] The repository was renamed in place, not recreated. +- [ ] `origin` uses `git@github.com:absolutepraya/marka.git`. +- [ ] No new workflow tag is pushed to `ghcr.io/absolutepraya/karakeep`. +- [ ] Both Marka mutable GHCR tags existed before production image switch. +- [ ] Production data/config backup existed locally on the MacBook before live mutation. +- [ ] `NEXTAUTH_URL` is the Marka origin in production. +- [ ] Marka worked directly before the old-host redirect was enabled. +- [ ] Production runs both Marka images and Watchtower is active. +- [ ] `keep.abhipraya.dev` preserves path and query in its permanent redirect. +- [ ] The VPS deployment directory and MacBook checkout directory were not renamed during #27; #35 owns their later path migration. +- [ ] Current repository/docs/runtime links use the Marka repo/GHCR identity. +- [ ] Internal Karakeep identifiers were not swept into #27. +- [ ] Browser/mobile/npm/SDK/MCP publishing identities were not broadened into this cutover. +- [ ] No secret or local backup file entered Git. +- [ ] #27 remains open pending explicit owner closure. diff --git a/docs/superpowers/plans/2026-08-16-pwa-version-updates.md b/docs/superpowers/plans/2026-08-16-pwa-version-updates.md index 5d3ac81ff..12c7f3329 100644 --- a/docs/superpowers/plans/2026-08-16-pwa-version-updates.md +++ b/docs/superpowers/plans/2026-08-16-pwa-version-updates.md @@ -90,7 +90,7 @@ Desktop keeps the existing sidebar location. Mobile reuses the same presentation Normal state: ```text -absolutepraya/karakeep +absolutepraya/marka Build abc1234 ``` @@ -108,7 +108,7 @@ Build abc1234 Update ready · def5678 ``` -Valid running-build SHAs link to the matching commit in `absolutepraya/karakeep`. Non-SHA values such as `development` render as plain build text without a commit link. +Valid running-build SHAs link to the matching commit in `absolutepraya/marka`. Non-SHA values such as `development` render as plain build text without a commit link. ### Profile cleanup diff --git a/docs/superpowers/specs/2026-08-14-coderabbit-review-design.md b/docs/superpowers/specs/2026-08-14-coderabbit-review-design.md index 368dcfdab..e411f7e7a 100644 --- a/docs/superpowers/specs/2026-08-14-coderabbit-review-design.md +++ b/docs/superpowers/specs/2026-08-14-coderabbit-review-design.md @@ -2,7 +2,7 @@ ## Goal -Enable CodeRabbit as an advisory automated pull request reviewer for `absolutepraya/karakeep` without changing the role of the existing GitHub Actions CI or the fork's deployment chain. +Enable CodeRabbit as an advisory automated pull request reviewer for `absolutepraya/marka` without changing the role of the existing GitHub Actions CI or the fork's deployment chain. CodeRabbit will add semantic review, PR summaries, repository-specific guidance, and GitHub review/check context. Existing CI remains authoritative for deterministic validation such as linting, formatting, typechecking, tests, OpenAPI generation checks, Knip, and React Doctor. @@ -91,7 +91,7 @@ Before opening the PR: - confirm generated-file filters do not suppress source files that should remain reviewable - confirm `CONTRIBUTING.md` accurately describes advisory behavior -After the PR is opened and the GitHub App is installed for `absolutepraya/karakeep`: +After the PR is opened and the GitHub App is installed for `absolutepraya/marka`: - confirm CodeRabbit recognizes the branch configuration - trigger `@coderabbitai review` if an automatic review does not start for the already-open PR 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 new file mode 100644 index 000000000..df8214641 --- /dev/null +++ b/docs/superpowers/specs/2026-08-15-marka-public-identity-cutover-design.md @@ -0,0 +1,440 @@ +# Marka Public Identity Cutover Design + +**Status:** Approved design, implementation not started + +**Primary issue:** #27 + +**Related issues:** #10, #11, #25, #26, #35 + +## Purpose + +Complete the controlled external identity cutover from the current Karakeep-era public infrastructure names to **Marka**, while keeping the migration bounded to the actively operated public web/self-host surfaces. + +This document is the authoritative design for #27. The executable task sequence lives in `docs/superpowers/plans/2026-08-15-marka-public-identity-cutover.md`. ADR `docs/adr/0001-marka-public-identity-cutover-boundary.md` records the durable boundary between public identity and deferred internal identifiers. + +No external mutation is authorized merely by the existence of these documents. DNS, GitHub repository rename, GHCR publishing changes, production configuration, OAuth/auth settings, reverse proxy, and live redirects are implementation-stage actions and must follow the plan checkpoints. + +## Confirmed target state + +| Surface | Current identity | Target identity | +| --- | --- | --- | +| Product name | Marka already visible after Phase 1 | Marka | +| GitHub repository | `absolutepraya/karakeep` | `absolutepraya/marka` | +| Canonical app origin | `https://keep.abhipraya.dev` | `https://marka.abhipraya.dev` | +| Web image | `ghcr.io/absolutepraya/karakeep:web-main` | `ghcr.io/absolutepraya/marka:web-main` | +| Workers image | `ghcr.io/absolutepraya/karakeep:workers-main` | `ghcr.io/absolutepraya/marka:workers-main` | +| Legacy app hostname | Live application origin | Permanent redirect to Marka after verification | +| Legacy GitHub path | Active repository | GitHub-managed rename redirect only; never recreate the old repository name | +| Legacy GHCR package | Receives current releases | Frozen historical package; no new fork tags | + +## Explicit boundary + +### Included + +- GitHub repository rename to `absolutepraya/marka`. +- Current-tree repository links, raw GitHub URLs, clone URLs, badges, repo-facing metadata, and active references controlled by this fork. +- GHCR image publishing hard switch to `ghcr.io/absolutepraya/marka`. +- Production Compose and Watchtower migration to the Marka GHCR package. +- Guided installer defaults and documentation that currently point at the fork's old GitHub/GHCR identities. +- `marka.abhipraya.dev` DNS/TLS/reverse-proxy/application-origin cutover. +- Auth/origin/callback/CORS/cookie/webhook/RSS/API behavior that depends on the public origin. +- Active web canonical/discovery metadata and generated public/share/RSS URLs. +- Legacy `keep.abhipraya.dev` permanent redirect after Marka is verified. +- Current GitHub repository-side presentation/settings that expose obsolete public identity. +- A pre-cutover backup stored on the local MacBook running the migration. +- An audit of browser extension/mobile/npm/SDK/MCP surfaces for coupling to changed values. + +### Excluded + +- Renaming `KARAKEEP_*` variables. +- Renaming `@karakeep/*` packages or package scopes. +- Renaming persisted data/config/cache paths. +- Renaming Compose services/project naming solely for branding. +- Renaming `karakeep-renderer` or other internal Docker networks solely for branding. +- Rewriting database/application persisted data for branding. +- Renaming protocol/export/compatibility identifiers. +- Renaming the VPS deployment directory under the operator's home directory. +- Renaming the MacBook repository checkout directory under `Documents/Projects`. +- Publishing/renaming browser-extension store identity. +- Publishing/renaming mobile-store identity. +- Publishing/renaming npm/SDK package identity. +- Publishing/renaming MCP distribution identity. +- Rewriting Git history. +- Editing historical issues, pull requests, or comments merely to remove old URLs. +- Implementing #25 landing-site publication or #26 docs-site publication as a prerequisite. + +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 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. + +Current production Compose defaults are explicitly: + +- `ghcr.io/absolutepraya/karakeep:web-main` +- `ghcr.io/absolutepraya/karakeep:workers-main` + +The new `ghcr.io/absolutepraya/marka` package must be proven pullable by the VPS before the controlled maintenance window. A successful image inspection on the MacBook is insufficient because local credentials can hide a package-visibility or anonymous-pull failure. + +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. + +## Public identity rules + +### GitHub + +The canonical public repository after cutover is `absolutepraya/marka`. + +The existing GitHub repository is renamed in place. Do not create a new repository and migrate content manually. Do not later create another `absolutepraya/karakeep` repository, because the old path is reserved for GitHub's repository-rename redirect. + +After rename: + +- local `origin` remotes under our control must use `git@github.com:absolutepraya/marka.git`; +- current docs should use `https://github.com/absolutepraya/marka` where they mean this fork; +- raw installer URLs should use `https://raw.githubusercontent.com/absolutepraya/marka/...`; +- upstream Karakeep links such as `karakeep-app/karakeep` remain unchanged; +- historical design documents may retain old links if they describe an actual past state and are not active instructions. + +### GHCR + +The canonical fork package becomes `ghcr.io/absolutepraya/marka`. + +This is a hard switch, not a compatibility alias strategy: + +- new CI releases publish Marka tags only; +- production moves to Marka tags; +- new installer-generated configuration uses Marka tags; +- docs describe Marka tags; +- old `ghcr.io/absolutepraya/karakeep` tags stop advancing; +- historical old-package images may remain and must not be deleted as part of #27. + +Before any production Compose switch, both canonical mutable tags must exist and resolve successfully: + +- `ghcr.io/absolutepraya/marka:web-main` +- `ghcr.io/absolutepraya/marka:workers-main` + +The paired-image release invariant remains unchanged: web and workers are built from the same successful commit, immutable SHA tags are pushed first, and mutable release tags are promoted only after both builds succeed. + +### Application hostname + +The canonical application origin is exactly `https://marka.abhipraya.dev`. No `app.marka.abhipraya.dev` hostname is introduced. + +The new hostname must become fully functional while `keep.abhipraya.dev` is still available. Direct access to Marka is verified first. Only after that verification does the old hostname become a permanent redirect. + +The redirect must preserve path and query string. Example: + +```text +https://keep.abhipraya.dev/public/lists/abc?view=grid +→ +https://marka.abhipraya.dev/public/lists/abc?view=grid +``` + +A `308 Permanent Redirect` is preferred where the reverse-proxy/DNS setup supports it cleanly. + +Long-term there is one live application origin, not two parallel app origins. + +### Origin-dependent application behavior + +Any behavior derived from the application origin must be audited before the redirect is enabled, including: + +- `NEXTAUTH_URL` or equivalent canonical auth/application URL; +- OAuth provider callback URLs actually configured on production; +- allowed origins/CORS settings actually enabled by this fork; +- cookie/session behavior across the hostname switch; +- webhook URLs or webhook payload links that embed the public origin; +- RSS/feed URLs; +- public list/share URLs; +- API/OpenAPI examples or server URLs that embed a production host; +- canonical link tags; +- Open Graph/Twitter URLs; +- structured-data URLs; +- PWA/web metadata where an absolute origin is present. + +Do not invent integrations. During implementation, inspect the actual production configuration and repository before changing provider dashboards or webhook systems. + +## Repository reference classification + +Every current-tree hit for the old fork identity must be assigned to one of these classes: + +1. **Active fork identity:** change to Marka. +2. **Upstream attribution:** keep Karakeep/upstream URL unchanged. +3. **Internal compatibility identifier:** leave unchanged under #35. +4. **Historical record:** normally leave unchanged unless it is still presented as current instruction. +5. **External distribution surface deferred from #27:** audit for breakage, then leave publishing identity unchanged. + +This classification applies to searches for at least: + +```text +absolutepraya/karakeep +github.com/absolutepraya/karakeep +raw.githubusercontent.com/absolutepraya/karakeep +ghcr.io/absolutepraya/karakeep +keep.abhipraya.dev +Karakeep +karakeep +``` + +Lowercase `karakeep` will produce many intentional machine-facing/internal hits. It is an audit input, not a replacement list. + +## Known repository-controlled cutover surfaces + +The implementation must inspect and update, where the classification says they are active fork identity: + +- `.github/workflows/docker.yml` +- `deploy/docker-compose.prod.yml` +- `scripts/install.sh` +- `scripts/install.test.sh` +- `README.md` +- `CONTRIBUTING.md` +- `AGENTS.md` +- `CLAUDE.md` +- `GEMINI.md` +- `docs/fork-setup.md` +- `docs/README.md` +- `docs/docs/02-installation/11-guided-docker-setup.md` +- other current installation pages returned by repository search +- `docs/docusaurus.config.ts` where the value is fork-owned rather than upstream-owned +- `apps/web/components/shared/sidebar/SidebarVersion.tsx` +- active metadata/canonical/share/RSS files found during implementation inventory + +Historical specs/plans under `docs/superpowers/**` are not blanket rewrite targets. Update only documents that are still authoritative/current instructions, including this design and its implementation plan after the repository rename. + +## GitHub-side settings inventory + +Repository files do not cover all public identity. At implementation time, capture the current GitHub settings before the rename and inspect after the rename: + +- repository name; +- description; +- website/homepage; +- topics; +- social preview; +- default branch; +- branch/ruleset behavior; +- Actions settings and environment references; +- repository secrets/variables names only, never values; +- webhooks if any; +- GitHub Pages configuration if any; +- package/repository linkage where applicable. + +Only change settings whose values actually encode the old public identity. Do not disturb unrelated branch protection, secrets, permissions, or automation. + +## Production backup boundary + +Before the first production mutation, create a timestamped backup on the local MacBook running the plan. + +The backup must contain, at minimum: + +- a fresh copy of the production `/data` persisted state; +- the production Compose file as deployed; +- `.env` and workers-only environment/config files as deployed, copied locally without printing them; +- reverse-proxy configuration that controls the current app hostname; +- current running image names, tags, and immutable digests/IDs; +- a short manifest recording timestamp, source host, source Compose directory, and file checksums/sizes without secret contents. + +The backup directory must remain outside the Git repository and must never be staged or committed. + +The agent must verify the backup is readable before proceeding. Verification means listing the local files, checking the archive/test extraction or copied data structure, and recording checksums/size metadata without exposing secret values. + +No automated retention/deletion policy is part of #27. + +## Cutover staging model + +The migration uses checkpoints with a bounded service-recovery path. The repository rename is forward-only, but until the legacy redirect is enabled the captured pre-cutover Compose, origin, and nginx configuration can restore the previous running application if Marka validation fails. The implementation must stop and recover before advancing, rather than attempting a blind all-surface reversal. + +### Checkpoint 0: plan readiness + +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; +- inspect issue #27 and #35 for newer decisions; +- inventory the exact current-tree references and current live configuration; +- do not mutate external systems yet. + +### Checkpoint 1: repository changes prepared + +Prepare code/docs changes that can be reviewed before the external rename: + +- workflow image path moves to `.../marka`; +- Compose defaults move to `.../marka`; +- installer uses Marka repo/raw/GHCR identity; +- tests expect Marka identity; +- current docs/repository links move to `absolutepraya/marka`; +- active public-origin references use `marka.abhipraya.dev` where they are meant to represent the post-cutover target; +- internal compatibility names remain untouched. + +Do not merge/publish this state in a way that causes production consumers to switch before the external prerequisites exist. + +### Checkpoint 2: local production backup complete + +Create and verify the MacBook-local production backup. This must happen immediately before the live cutover phase, after the plan and repository changes are ready. + +### Checkpoint 3: GitHub repository rename + +Rename the existing repository to `absolutepraya/marka`. Then immediately: + +- verify the new URL resolves; +- verify the old URL redirects; +- update the local `origin` URL; +- verify fetch/push access using the new remote; +- confirm the implementation branch still exists under the renamed repository. + +### Checkpoint 4: publish Marka images + +Apply/push the prepared workflow change so CI publishes the canonical Marka image package. Wait for a successful image workflow associated with a successful CI commit. + +Verify both mutable Marka tags exist before production configuration points to them. Record their digests and confirm they correspond to the intended commit. + +Before the maintenance window, verify from the VPS that both Marka images can be pulled without relying on an interactive MacBook registry login. A package-visibility or pull failure blocks the production image switch. + +Do not dual-publish the old fork package. + +### Checkpoint 5: make Marka hostname directly reachable + +Create/update DNS and reverse-proxy/TLS configuration so `https://marka.abhipraya.dev` reaches the current application deployment without redirecting `keep.abhipraya.dev` yet. + +Update production origin/auth configuration needed for the new hostname. Restart/recreate only the services required for the configuration to take effect. + +Directly verify Marka auth and application behavior. + +### Checkpoint 6: switch production images + +Change production Compose/image overrides to the canonical Marka web/workers tags. Use the controlled maintenance window and pause automatic updates if necessary to avoid Watchtower racing manual changes. + +Verify production is actually running Marka image references/digests and both web/workers are healthy before resuming automatic updates. + +### Checkpoint 7: complete public-origin verification + +Exercise the required smoke-test matrix on `marka.abhipraya.dev`, including generated public URLs and background processing. + +Only after this checkpoint succeeds may the legacy hostname redirect be enabled. + +### Checkpoint 8: legacy hostname redirect + +Convert `keep.abhipraya.dev` to a permanent redirect that preserves path and query string. Verify representative root, authenticated-entry, public-list, and query-string URLs. + +The legacy redirect is the recovery boundary: do not enable it until all direct Marka tests pass. If a pre-redirect failure occurs, restore the previously captured application origin, image references, and old-host nginx application block before continuing. Do not recreate the old GitHub repository name. + +Do not keep the old hostname serving the application after the redirect is accepted. + +### Checkpoint 9: repository/GitHub presentation cleanup + +Finish GitHub-side description/homepage/topics/social-preview/package linkage and any active current-tree references that could not safely be finalized before the external rename. + +Run the final repository audit and record intentional remaining `karakeep` categories. + +### Deferred path migration + +The VPS deployment directory and MacBook checkout directory remain unchanged throughout #27. After the public cutover has stabilized, #35 must inventory every path-dependent Compose invocation, backup job, worktree setting, shell alias, editor workspace, and local automation reference before either directory is renamed. + +## Required production smoke tests + +The agent must record pass/fail evidence for every applicable item. + +### Infrastructure + +- `marka.abhipraya.dev` resolves correctly. +- HTTPS certificate is valid for `marka.abhipraya.dev`. +- web service healthy. +- workers service healthy. +- Meilisearch reachable/healthy. +- renderer/browser pipeline works. +- configured AI functionality works if production enables it. + +### Authentication + +- direct login through `marka.abhipraya.dev` succeeds. +- authenticated reload preserves session. +- logout succeeds. +- no redirect loop between old/new hosts. + +### Core application + +- bookmark library loads. +- create a disposable test bookmark. +- edit the disposable test bookmark. +- search finds expected content. +- crawler/archive processing for a test URL completes. +- screenshot processing completes. +- delete the disposable test bookmark. + +### Public behavior + +- publish/open a test public list or use an existing safe public list. +- public-list owner/avatar/current UI behavior renders as expected. +- generated public-list/share URL uses `https://marka.abhipraya.dev`. +- RSS/feed endpoint works where enabled. +- generated RSS URL uses the Marka origin. + +### Distribution/deployment + +- `ghcr.io/absolutepraya/marka:web-main` exists. +- `ghcr.io/absolutepraya/marka:workers-main` exists. +- both mutable tags correspond to the intended paired release commit. +- production web actually uses the Marka image. +- production workers actually use the Marka image. +- Watchtower is running again and follows the new paths. +- a later normal main-branch image publish can still be detected by the deployment path; do not manufacture an unnecessary production change solely to prove this if the current Watchtower/image inspection already demonstrates correct tracking. + +### Legacy paths + +- old GitHub repository URL redirects to the renamed repository. +- fresh clone using `git@github.com:absolutepraya/marka.git` works. +- old `keep.abhipraya.dev` root redirects to Marka. +- old public-list path redirects to the same path on Marka. +- old URL with query string preserves the query on Marka. + +## Verification for repository changes + +Run the repository's normal checks appropriate to changed code: + +```bash +pnpm format:fix +pnpm lint +pnpm typecheck +pnpm --filter @karakeep/docs typecheck +pnpm --filter @karakeep/docs build +bash scripts/install.test.sh +``` + +Run focused tests for any web URL/metadata logic changed by #27. Run the full test suite if the branch touches runtime code outside straightforward static URL/copy configuration and the current CI baseline permits it. + +Before claiming completion, run explicit searches for old fork identities and categorize every remaining hit: + +```bash +rg -n --hidden --glob '!node_modules' --glob '!.git' 'absolutepraya/karakeep|github\.com/absolutepraya/karakeep|raw\.githubusercontent\.com/absolutepraya/karakeep|ghcr\.io/absolutepraya/karakeep|keep\.abhipraya\.dev' . +``` + +Then run broader case-sensitive/case-insensitive searches for Karakeep naming and classify remaining hits as upstream attribution, internal compatibility identifier (#35), historical record, or deferred distribution identity. Do not turn this into a blind replacement exercise. + +## Documentation behavior after cutover + +After the external migration, current authoritative docs must consistently say: + +- this is the **Marka** fork; +- origin is `git@github.com:absolutepraya/marka.git`; +- public repository is `https://github.com/absolutepraya/marka`; +- guided install raw URL points at `absolutepraya/marka`; +- fork images are `ghcr.io/absolutepraya/marka:web-main` and `:workers-main`; +- canonical application origin is `https://marka.abhipraya.dev` where a real operator hostname is appropriate to document; +- internal `KARAKEEP_*`, package scopes, services, and network names remain intentionally unchanged pending #35. + +Public/general installation docs should continue to use placeholders instead of leaking personal operator details unless the document is explicitly the fork-owner/operator guide. + +## Deferred issue audit + +During final audit, inspect browser extension, mobile, npm/SDK, and MCP source/config for hard dependencies on: + +- `absolutepraya/karakeep`; +- `raw.githubusercontent.com/absolutepraya/karakeep`; +- `ghcr.io/absolutepraya/karakeep`; +- `keep.abhipraya.dev`. + +If a dependency would break because #27 changed one of those external resources, fix only that coupling as part of #27. Do not rename the distribution identity itself. If a broader rename is desirable, create a dedicated follow-up issue rather than expanding #27. + +## Completion rule + +The implementation agent must not automatically close #27. After all checks pass, post or prepare a concise evidence report covering the repository rename, GHCR digests, production image paths, hostname/auth smoke tests, redirect verification, local backup location (path only, never secret contents), and remaining intentional Karakeep identifier categories. Final issue closure remains an explicit owner action. diff --git a/docs/superpowers/specs/2026-08-16-pwa-version-updates-design.md b/docs/superpowers/specs/2026-08-16-pwa-version-updates-design.md index 153b2e1c7..4ca5ad59b 100644 --- a/docs/superpowers/specs/2026-08-16-pwa-version-updates-design.md +++ b/docs/superpowers/specs/2026-08-16-pwa-version-updates-design.md @@ -197,7 +197,7 @@ Both desktop and mobile consume the same PWA lifecycle state. Normal state: ```text -absolutepraya/karakeep +absolutepraya/marka Build b3f8690 ``` @@ -225,7 +225,7 @@ Keep the existing bottom-left sidebar version area. Refactor `SidebarVersion` so the displayed build comes from the shared PWA lifecycle state rather than treating the current live server build as the browser build. -The repository label and running build SHA remain linkable to `absolutepraya/karakeep` and the corresponding GitHub commit when the value is a valid SHA. +The repository label and running build SHA remain linkable to `absolutepraya/marka` and the corresponding GitHub commit when the value is a valid SHA. ### Mobile diff --git a/scripts/install.sh b/scripts/install.sh index eaad228e0..a1fb5be38 100644 --- a/scripts/install.sh +++ b/scripts/install.sh @@ -10,8 +10,8 @@ DEFAULT_SEARCH_MODE="managed" DEFAULT_RENDERER_MODE="managed" DEFAULT_AI_MODE="deferred" COMPOSE_PROJECT_NAME="karakeep" -WEB_IMAGE="ghcr.io/absolutepraya/karakeep:web-main" -WORKERS_IMAGE="ghcr.io/absolutepraya/karakeep:workers-main" +WEB_IMAGE="ghcr.io/absolutepraya/marka:web-main" +WORKERS_IMAGE="ghcr.io/absolutepraya/marka:workers-main" MEILI_IMAGE="getmeili/meilisearch:v1.41.0" CHROME_IMAGE="ghcr.io/karakeep-app/karakeep-chrome:release" diff --git a/scripts/install.test.sh b/scripts/install.test.sh index fb5816f17..3b9918ca4 100644 --- a/scripts/install.test.sh +++ b/scripts/install.test.sh @@ -131,8 +131,8 @@ bash "$INSTALLER" --non-interactive --no-start --yes \ --install-dir "$managed/install" --data-dir "$managed/data" \ --public-url https://keep.example.com --data-mode fresh \ --search managed --renderer managed --ai deferred >/dev/null -assert_contains "$managed/install/docker-compose.yml" "ghcr.io/absolutepraya/karakeep:web-main" -assert_contains "$managed/install/docker-compose.yml" "ghcr.io/absolutepraya/karakeep:workers-main" +assert_contains "$managed/install/docker-compose.yml" "ghcr.io/absolutepraya/marka:web-main" +assert_contains "$managed/install/docker-compose.yml" "ghcr.io/absolutepraya/marka:workers-main" assert_contains "$managed/install/docker-compose.yml" "getmeili/meilisearch:v1.41.0" assert_contains "$managed/install/docker-compose.yml" "ghcr.io/karakeep-app/karakeep-chrome:release" assert_contains "$managed/install/docker-compose.yml" "init: true"