diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 35456df..f0ec202 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -81,8 +81,11 @@ jobs: - name: Install MCP package for verification run: python -m pip install ./mcp_package - - name: Run portability tests - run: python -m unittest tests.test_mcp_verify_core tests.test_web_http_core tests.test_release_hygiene tests.test_cli_parser_core tests.test_cli_runtime_core + - name: Install test runner + run: python -m pip install "pytest>=8,<10" + + - name: Run broad Windows tests + run: python -m pytest tests -q --ignore=tests/test_installers.py --ignore=tests/test_serve.py --ignore=tests/test_large_wiki_smoke.py - name: Demo value-loop smoke test shell: pwsh @@ -112,6 +115,13 @@ jobs: - name: Check shell syntax run: bash -n integrations/*/install.sh integrations/*/uninstall.sh integrations/_shared/*.sh + - name: Check PowerShell syntax + shell: pwsh + run: | + Get-ChildItem integrations -Recurse -Include *.ps1 | ForEach-Object { + [scriptblock]::Create((Get-Content -Raw $_.FullName)) | Out-Null + } + release-hygiene: runs-on: ubuntu-latest steps: diff --git a/CHANGELOG.md b/CHANGELOG.md index 5e89346..873ef0c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,45 @@ Release sections use `MAJOR.MINOR.PATCH` versions that match `link-mcp` on PyPI ## [Unreleased] +## [1.4.0] - 2026-06-14 + +### Added + +- Added official CLI skills under `skills/` so agents can lazy-load Link workflows without MCP setup. +- Added `lnk try` as a one-command demo proof loop that creates the demo, checks readiness, runs query/brief examples, and prints first agent prompts. +- Added `lnk connect ` to preview or write MCP client config for Codex, Kiro, Claude Code, Cursor, Antigravity, VS Code, and Copilot. +- Added Windows PowerShell installers for Codex, Kiro, Claude Code, Cursor, Antigravity, VS Code, and Copilot. +- Added optional `review_after` dates for durable memories so time-sensitive context can automatically return to the memory inbox for re-checking. +- Added optional `expires_at` dates for durable memories so temporary context automatically leaves default recall after expiry. +- Added `lnk import-obsidian ` to copy Obsidian Markdown notes into `raw/obsidian/` with secret scanning before the normal ingest workflow. +- Added `lnk compliance-export` for redacted readiness, validation, memory-review, operation, and log exports for team or security review. +- Added `lnk restore-backup` to preview and confirm local backup restores with unsafe-tar checks, raw restore opt-in, and pre-restore safety backups. +- Added `lnk team-sync` to print a safe Git sharing plan for reviewed team memory without pushing private raw sources automatically. +- Added `lnk share ` to print a local viewer permalink and agent prompt for a specific Link page. +- Added `lnk snapshot` to export a static, read-only HTML snapshot for demos or reviews while excluding raw sources, captures, live state, and memory pages by default. +- Added memory `visibility` metadata (`private`, `project`, or `team`) so team sharing can rely on explicit user intent instead of inferring privacy from scope alone. +- Added `lnk set-memory-visibility` and MCP `set_memory_visibility` so existing memories can move between private, project, and team sharing intent after explicit user approval. +- Added `lnk memory-log`, MCP `memory_log`, `/memory-log`, and `/api/memory-log` for recent memory lifecycle changes without exposing raw source or memory bodies. +- Added privacy-safe memory-log change summaries so review, status, and visibility transitions are visible without exposing memory bodies. +- Added `lnk wins`, MCP `memory_wins`, `/wins`, and `/api/wins` for local, non-telemetry proof signals about what Link memory is carrying. +- Added a team security review docs page covering local deployment, data boundaries, memory approval gates, Git sharing, audit exports, and current limits. +- Added a memory contract docs page that explains the stable MCP agent loop, tool groups, write rules, budget behavior, and sharing semantics. +- Added an integration maintainer checklist covering installer invariants, new-agent steps, PowerShell parity, and validation commands. +- Added a scale model docs page covering bounded defaults, benchmark/health checks, large-wiki habits, and current local limits. +- Added `python -m link_mcp --version` so MCP package installs can be verified before a wiki exists. +- Added an Obsidian guide for opening Link's Markdown wiki as a vault and rebuilding indexes after manual edits. +- Added validation and doctor failures for secret-looking values already present in wiki pages so local UI and MCP context do not quietly serve manually introduced secrets. + +### Changed + +- Broadened local secret detection for common modern provider tokens and credentials before capture, ingest, Obsidian import, and doctor scans. +- Changed the installed CLI command from `link` to `lnk` to avoid the POSIX/macOS `link` utility collision while preserving source-checkout `python3 link.py ...` usage. +- Tightened `lnk team-sync` readiness so unreviewed memories or active `visibility: private` memories block "ready" status before Git sharing. +- Tightened `lnk snapshot --include-memories` so private memories stay excluded unless `--include-private-memories` is explicitly passed. +- Broadened Windows CI from a small portability subset to most non-installer/non-server tests. +- Clarified that the Homebrew formula lives in the separate `gowtham0992/homebrew-link` tap. +- Tightened security reporting guidance to prefer private maintainer contact before public GitHub issues. + ## [1.3.0] - 2026-05-22 ### Added diff --git a/LINK.md b/LINK.md index e2f6106..8cbeed5 100644 --- a/LINK.md +++ b/LINK.md @@ -170,6 +170,7 @@ type: memory title: "Short Memory Title" memory_type: preference | decision | project | fact | note scope: user | project | global +visibility: private | project | team project: "optional-project-slug" status: active | stale | archived date_captured: "2026-04-09T14:30:00Z" @@ -178,6 +179,7 @@ update_count: 0 source: "manual | conversation | mcp | raw/source.md" last_update_source: "" review_status: pending | reviewed | needs_update +review_after: "optional YYYY-MM-DD date for scheduled re-check" tags: [memory, relevant-tag] --- @@ -287,6 +289,7 @@ Rules: - Keep memories specific and actionable. "User likes quality" is too vague; "User prefers release/* branches over codex/* branches" is useful. - Use `memory_type: preference` for user preferences, `decision` for choices made, `project` for project context, `fact` for stable facts, and `note` for everything else. - Use `scope: user` for broad personal preferences, `project` for the current project, and `global` for agent-wide principles. +- Use `visibility: private` for personal memory, `project` for project-team sharing, and `team` only when the human explicitly wants the memory shared across a team workspace. If omitted, Link treats user/global memories as private and project memories as project-visible. - For `scope: project`, include a project key when you know it. `link.py` infers this from repo-local installs; otherwise pass `--project ` or MCP `project`. - At the start of a session or substantial task, run `python3 link.py brief "" .` or MCP `memory_brief` when available. Treat this as the default way to prime yourself with local memory, review warnings, and saved raw capture status. - For long chat/session notes, prefer `python3 link.py capture-session "" .` or MCP `capture_session`; it stores the raw note locally and returns proposal-only memory candidates. If you do not need to keep the raw note, run `python3 link.py propose-memories "" .` or MCP `propose_memories` instead. Do not write proposals until the human confirms. diff --git a/README.md b/README.md index aa450b0..ae5c931 100644 --- a/README.md +++ b/README.md @@ -1,36 +1,54 @@

- Link + Link

-# Link +

Link

-**Local, source-backed memory for LLM agents.** +

Local memory for AI agents.

-Link gives Codex, Claude, Cursor, Kiro, VS Code, Copilot, and other MCP clients -the same durable memory about you and your work. It stays on your machine as -plain Markdown, with sources, backlinks, graph context, review state, and an -audit trail you can inspect. +

+ Link gives Codex, Claude, Cursor, Kiro, VS Code, Copilot, Antigravity, and + other local agents the same source-backed memory, stored locally as Markdown. +

-It follows Andrej Karpathy's -[LLM Wiki pattern](https://gist.github.com/karpathy/442a6bf555914893e9891c11519de94f): -keep knowledge outside the chat window, make claims inspectable, and let context -compound over time. +

+ Website · + Quick start · + MCP setup · + Skills · + CLI · + MCP Registry · + PyPI · + Homebrew +

+ +

+ GitHub stars + CI + MCP Registry + PyPI +

+ +## What Is Link? + +Link is an open-source memory layer for local AI agents. Raw sources become an +inspectable Markdown wiki. Explicit "remember this" requests become reviewable +memories. Agents retrieve compact, source-backed context through the CLI, MCP, +official skills, or the local viewer without dumping the whole wiki into a chat +window. + +The wiki is the storage layer. The product is durable memory that stays on your +machine, remains readable in plain files, and can be shared across multiple +agents instead of locked inside one vendor profile. -[![GitHub](https://img.shields.io/github/stars/gowtham0992/link?style=flat)](https://github.com/gowtham0992/link) -[![CI](https://github.com/gowtham0992/link/actions/workflows/ci.yml/badge.svg)](https://github.com/gowtham0992/link/actions/workflows/ci.yml) -[![MCP Registry](https://img.shields.io/badge/MCP_Registry-io.github.gowtham0992%2Flink-blue)](https://registry.modelcontextprotocol.io/?q=io.github.gowtham0992%2Flink) -[![PyPI](https://img.shields.io/pypi/v/link-mcp)](https://pypi.org/project/link-mcp/) +## How It Works -[Product site](https://gowtham0992.github.io/link/) · -[First 10 minutes](https://gowtham0992.github.io/link/getting-started.html) · -[Why Link?](https://gowtham0992.github.io/link/why-link.html) · -[Web UI](https://gowtham0992.github.io/link/ui.html) · -[MCP setup](https://gowtham0992.github.io/link/mcp.html) · -[CLI](https://gowtham0992.github.io/link/cli.html) · -[Security](SECURITY.md) · -[Changelog](CHANGELOG.md) +Link gives agents four simple moves: -## Why It Exists +1. **Capture** notes, transcripts, docs, screenshots, and project context in `raw/`. +2. **Structure** source-backed pages under `wiki/`. +3. **Remember** explicit preferences, decisions, facts, and project context as reviewable memory. +4. **Retrieve** compact query packets through the CLI, MCP, official skills, or the local web viewer. Most agent sessions start from zero. You re-explain preferences, repo decisions, project constraints, and why something matters. Link turns that repeated context @@ -43,6 +61,11 @@ into local memory agents can query. | Context windows are expensive. | Return compact query packets with provenance and follow-up actions. | | Memory needs trust. | Every page and memory can be inspected, reviewed, archived, or forgotten. | +Link follows Andrej Karpathy's +[LLM Wiki pattern](https://gist.github.com/karpathy/442a6bf555914893e9891c11519de94f): +keep knowledge outside the chat window, make claims inspectable, and let context +compound over time. + ## Quick Start Run the demo first. It creates a complete local wiki with raw sources, wiki @@ -52,12 +75,14 @@ macOS with Homebrew: ```bash brew install gowtham0992/link/link -link demo -link next link-demo -link serve link-demo +lnk try +lnk serve link-demo ``` -Windows or source checkout: +The installed command is `lnk` because `link` is already a POSIX/macOS system +utility. From a source checkout, use `python3 link.py ...` instead. + +Windows PowerShell: ```powershell git clone https://github.com/gowtham0992/link.git @@ -67,7 +92,7 @@ py link.py next link-demo py link.py serve link-demo ``` -Or from source: +Source checkout on macOS/Linux: ```bash git clone https://github.com/gowtham0992/link.git @@ -77,6 +102,13 @@ python3 link.py next link-demo python3 link.py serve link-demo ``` +Use `lnk try` for the shortest Homebrew proof loop. It creates the demo, +checks readiness, runs a compact query/brief proof, and prints the agent prompts +and viewer command. From source, use `python3 link.py try`. + +The Homebrew formula is maintained in the public +[`gowtham0992/homebrew-link`](https://github.com/gowtham0992/homebrew-link) tap. + Open: ```text @@ -89,15 +121,15 @@ The web viewer is for local use only. It binds to `127.0.0.1`, has no user accounts or authentication, and should not be exposed to the internet unless you add your own auth layer. -For the shortest guided proof path, run `link welcome link-demo`. +For the shortest guided proof path, run `lnk welcome link-demo`. Try the value loop: ```bash -link query "why does Link help agents?" link-demo --budget small -link brief "working on agent memory" link-demo -link benchmark "agent memory" link-demo -link health link-demo +lnk query "why does Link help agents?" link-demo --budget small +lnk brief "working on agent memory" link-demo +lnk benchmark "agent memory" link-demo +lnk health link-demo ``` The `/health` page mirrors the readiness loop in the browser: validation state, @@ -131,12 +163,21 @@ python3 scripts/smoke_large_wiki.py --pages 10000 This generates a temporary synthetic wiki, verifies bounded graph/query payloads, and reports cache timing, persistent-cache reuse, search, query, graph, and health signals without touching your real Link wiki. +The public scale model is documented at +[Link Scale](https://gowtham0992.github.io/link/scale.html): what stays +bounded by default, how to measure your own wiki, and where the current local +limits are. -## Three Ways To Use Link +## Ways To Use Link Pick the surface that matches how you work. They all read and write the same local Markdown wiki. +These surfaces are independent. `lnk serve` / `serve.py` is only the local web +viewer. CLI commands, official skills, and MCP tools read the same `wiki/` files +directly, so Claude, Codex, Kiro, Cursor, or another agent can use Link even +when the web viewer is not running. +
@@ -157,6 +198,19 @@ local Markdown wiki.
+Prefer skills instead of MCP? Link ships small, lazy-loadable CLI skills under +`skills/`. They let an agent use `lnk health`, `lnk query`, `lnk ingest-status`, +and `lnk remember` directly, without MCP setup or a running web viewer. + +```text +skills/link-health/SKILL.md +skills/link-retrieve/SKILL.md +skills/link-ingest/SKILL.md +skills/link-memory/SKILL.md +``` + +Full guide: [Link Skills](https://gowtham0992.github.io/link/skills.html). + ## Install For Your Agent Run one installer from the cloned checkout: @@ -175,9 +229,17 @@ Installers create or update `~/link`, install or upgrade `link-mcp`, write lightweight agent instructions, and preserve existing wiki data on reinstall. Use `--project` when a repo needs separate project memory. -The shell installers are intended for macOS/Linux-style agent config paths. -On Windows, use the source commands above plus the MCP-only config below until -your agent has a Windows-specific installer. +On Windows, use the matching PowerShell installer: + +```powershell +.\integrations\codex\install.ps1 +.\integrations\kiro\install.ps1 +.\integrations\claude-code\install.ps1 +.\integrations\cursor\install.ps1 +.\integrations\copilot\install.ps1 +.\integrations\vscode\install.ps1 +.\integrations\antigravity\install.ps1 +``` Then ask your agent: @@ -190,11 +252,23 @@ query Link for the release process what does Link remember about local personal memory? ``` +If your agent already has instructions and you only need MCP wiring, use the +connection helper. It previews the exact config first; add `--write` when you +want Link to update the agent config file. + +```bash +lnk connect codex ~/link +lnk connect codex ~/link --write +lnk connect kiro ~/link --write +lnk verify-mcp ~/link +``` +
MCP-only install ```bash python3 -m pip install --upgrade link-mcp +python3 -m link_mcp --version ``` ```json @@ -219,17 +293,28 @@ python3 -m venv ~/.link-mcp-venv Full setup: [MCP guide](https://gowtham0992.github.io/link/mcp.html).
-## How Link Works +Obsidian users can import an existing vault into `raw/` for agent ingest, or +open `~/link/wiki` directly as a vault for editing Link pages: + +```bash +lnk init ~/link +lnk import-obsidian ~/Documents/ObsidianVault ~/link +``` + +See the [Obsidian guide](https://gowtham0992.github.io/link/obsidian.html) for +the import, edit, and validation loop. + +## Storage Model -Link separates source-backed knowledge from durable agent memory: +Under the hood, Link separates source-backed knowledge from durable agent memory: 1. Drop raw notes, transcripts, articles, and project context into `raw/`. 2. Agents compile those sources into inspectable pages under `wiki/`. 3. Explicit "remember" requests become reviewable memory pages. -4. Queries retrieve compact MCP context from both the wiki and memory layer. +4. Queries retrieve compact agent context from both the wiki and memory layer.

- Link architecture: raw sources become wiki knowledge, explicit remembers become reviewed memory, and agents retrieve compact MCP context + Link architecture: raw sources become wiki knowledge, explicit remembers become reviewed memory, and agents retrieve compact context

The storage model is plain and inspectable: @@ -238,14 +323,17 @@ The storage model is plain and inspectable: |-------|------------------| | `raw/` | Original notes, transcripts, articles, PDFs, screenshots, and project files. | | `wiki/` | Source-backed pages, concepts, entities, explorations, comparisons, and memories. | -| MCP tools | Compact packets agents can use without dumping the whole wiki into context. | +| Agent interfaces | CLI, skills, MCP, and local viewer paths that avoid dumping the whole wiki into context. | -If a raw file was already ingested and later edited, `link ingest-status` marks it +If a raw file was already ingested and later edited, `lnk ingest-status` marks it as stale and tells your agent to refresh the existing source page instead of creating a duplicate. ## What Agents Get +When an agent uses Link through MCP, these are the stable tools it receives. +CLI and skill workflows call the same core behavior through `lnk`. + - `query_link`: an answer-ready packet with relevant memories, pages, graph neighborhood, reasons for selection, budget limits, and follow-up actions. - `memory_brief`: a compact pre-work brief with user/project preferences, @@ -253,13 +341,83 @@ creating a duplicate. - `ingest_status`: exact next steps for raw files, including source safety, stale ingest detection, validation, and memory proposal guidance. - `remember_memory`: durable local memory with duplicate/conflict checks, - review state, provenance, and audit logging. + `visibility` sharing intent, review state, optional `review_after` re-check + dates, optional `expires_at` expiry dates, provenance, and audit logging. +- `set_memory_visibility`: explicit post-review sharing changes between + `private`, `project`, and `team` visibility without editing Markdown by hand. - `explain_memory`: why a memory exists, what it links to, whether it is ready for recall, and what needs review. +- `memory_log`: recent memory lifecycle changes from `wiki/log.md`, without + raw source or memory bodies. +- `memory_wins`: local proof signals for what Link memory is carrying, based + on wiki metadata rather than telemetry. + +The stable agent-facing loop is documented at +[Link Memory Contract](https://gowtham0992.github.io/link/memory-contract.html): +readiness first, bounded recall, explicit memory writes, audit tools, and +sharing semantics. + +Use `review_after` for time-sensitive preferences or decisions. When that date +arrives, the memory reappears in Link's review inbox so an agent can ask the +user to confirm, update, archive, or forget it instead of trusting stale context. +Use `expires_at` for temporary context that should automatically leave default +recall after a date; Link keeps the Markdown page inspectable and asks the user +to update, archive, or delete it. +Use `visibility` to separate where a memory applies from who should see it: +`private` stays personal, `project` is intended for a project workspace, and +`team` means the user explicitly approved sharing it with a team. + +For team handoff or security review, `lnk compliance-export --output audit.json` +writes a redacted JSON packet with readiness, validation, memory review status, +operation markers, and recent audit log entries. Raw source contents and memory +bodies are not included. + +For day-to-day auditability, `lnk memory-log ~/link` shows what Link recently +remembered, updated, reviewed, archived, restored, forgot, or accepted from raw +captures. + +For recovery, `lnk backup ~/link` creates a local archive and `lnk +restore-backup ~/link` previews what would be restored. Passing +`--confirm` replaces local files after creating a safety backup when possible; +`raw/` is still excluded unless `--include-raw` is explicit. + +For local proof of value, `lnk wins ~/link` shows reusable memories, reviewed +memory, provenance, project continuity, freshness guardrails, and copyable +prompts without tracking user behavior. + +For Git-backed team memory, `lnk team-sync ~/link` checks whether the workspace +is ready to share reviewed `wiki/` pages while keeping `raw/`, caches, backups, +and local MCP Python markers private by default. It also blocks "ready" status +when the memory inbox is not clear or active `visibility: private` memories +would be included by a broad `git add wiki`. + +```bash +lnk team-sync ~/link --remote git@example.com:team/link-memory.git +``` + +For a teammate, reviewer, or another agent, `lnk share` resolves a page, +memory, title, alias, or search phrase into a local viewer URL: + +```bash +lnk share "Prefer local memory" ~/link +``` + +For a static, read-only review packet, `lnk snapshot` exports rendered wiki +HTML without `raw/`, captures, operation markers, live MCP state, or memory pages +by default. `--include-memories` exports only non-private memories; use +`--include-private-memories` only for a personal archive or an explicitly +approved review. It blocks export if wiki pages contain secret-looking values +unless you explicitly override it. + +```bash +lnk snapshot ~/link --output link-snapshot +lnk snapshot ~/link --output link-snapshot --include-memories --force +lnk snapshot ~/link --output personal-snapshot --include-memories --include-private-memories --force +``` ## Agent Contract -Agents should use Link in this order: +For MCP clients, agents should use Link in this order: 1. `link_status` to check readiness and safe next actions. 2. `starter_prompts` when the user asks what to try first. @@ -280,9 +438,12 @@ Link itself is local-first: - No hosted backend. - No external API calls from `serve.py` or `link-mcp`. - Raw sources and generated wiki pages are ignored by git by default. -- `link backup` excludes `raw/` unless you explicitly pass `--include-raw`. -- Secret-looking values are detected in raw sources, captures, and release - hygiene checks. +- `lnk backup` excludes `raw/` unless you explicitly pass `--include-raw`. +- Secret-looking API keys, provider tokens, JWTs, registry credentials, and + private key blocks are detected in raw sources, captures, and release hygiene + checks. `lnk validate` and `lnk doctor` also fail if secret-looking values + are found inside wiki pages before they can be served through the local UI or + returned through agent context. - The local web server binds to `127.0.0.1` and is not meant to be exposed to the internet without additional auth. @@ -306,8 +467,10 @@ More detail: [Security guide](https://gowtham0992.github.io/link/security.html). | Understand raw/wiki/memory | [Concepts](https://gowtham0992.github.io/link/concepts.html) | | Configure MCP | [MCP setup](https://gowtham0992.github.io/link/mcp.html) | | Find a command | [CLI reference](https://gowtham0992.github.io/link/cli.html) | +| Use Link without MCP setup | [Official skills](https://gowtham0992.github.io/link/skills.html) | | Use local HTTP endpoints | [HTTP API](https://gowtham0992.github.io/link/api.html) | | Review security boundaries | [Security model](https://gowtham0992.github.io/link/security.html) | +| Evaluate Link for a small team | [Team security review](https://gowtham0992.github.io/link/team-security.html) | | Fix setup issues | [Troubleshooting](https://gowtham0992.github.io/link/troubleshooting.html) | ## Contributing diff --git a/SECURITY.md b/SECURITY.md index 1ed73fa..16afa86 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -49,6 +49,7 @@ working directory. ## Reporting vulnerabilities -Please report security issues through GitHub issues or private maintainer -contact channels. Avoid posting secrets, private wiki content, or raw source -files in public reports. +Please use a private maintainer contact channel for security issues first. Do +not post secrets, private wiki content, raw source files, or exploitable details +in public GitHub issues. If a public issue is the only available path, keep it +high level and ask for a private follow-up channel. diff --git a/docs/api.html b/docs/api.html index 9eb06ba..c00e689 100644 --- a/docs/api.html +++ b/docs/api.html @@ -21,10 +21,13 @@