pinax

module
v0.1.11 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 23, 2026 License: MIT

README

Pinax

中文说明

Pinax is the agent-safe knowledge control plane for your Markdown vault — it lets AI safely read, diagnose, repair, and sync a real local knowledge base, while keeping every agent write auditable, previewable, and reversible. Your Markdown vault stays the source of truth; the agent never sees plaintext it should not, and the cloud never stores plaintext notes.

Three ideas to remember: Local Vault is the source of truth / the Proof Loop protects every agent write / Capsa Sync only coordinates ciphertext.

The aha moment

Run the whole agent-safe loop in one command — preview first, then plan, snapshot, apply, and restore if needed. Every step is bounded: the agent reads projections, never raw note bodies, and writes only happen through an explicit plan → snapshot → apply chain.

pinax proof loop run --vault ./my-notes --json            # preview: one projection with proof_loop_run_id
pinax repair plan --vault ./my-notes --save                # turn vault health issues into a reviewable plan
pinax version snapshot --vault ./my-notes --message "before repair"   # protective snapshot before any write
pinax repair apply --vault ./my-notes --plan repair-abc123 --yes      # apply approved low-risk fixes only
pinax version restore notes/example.md --revision HEAD --plan --vault ./my-notes          # something went wrong?
pinax version restore apply --vault ./my-notes --plan restore-<id> --yes                 # revert through a CLI-authored path

Why Pinax

Differentiator What it means
Proof loop safe writes Every agent-driven change is plan → snapshot → apply → receipt → restore. No direct file surgery, no silent writes, every apply is reversible.
Plaintext boundary Read commands default to --display card, not the full body. Agents, MCP, dashboard, and project boards share one bounded projection; only explicit --display body puts the body in a local JSON projection.
Self-hosted encrypted sync Capsa only coordinates encrypted revisions — AES-256-GCM client-side encryption, the server never sees plaintext notes and never executes local tools.

Pinax complements Obsidian and Logseq as the agent-safe maintenance layer for your vault, avoids Notion's cloud lock-in, and is more programmable and verifiable than Reflect. It is not another notes app — it is the control plane that makes your existing Markdown vault safe for AI.

Identity-first kernel

Every durable note, journal, asset, project, subproject, and managed task has a canonical UUIDv7 object_id. Paths are mutable locators, not identity. SQL/Dataview projections, backlinks, project boards, apply receipts, tombstones, and manifest v2 all join on object IDs.

pinax record identity audit --vault ./my-notes --json
pinax sync manifest audit --vault ./my-notes --json
pinax sync manifest plan --save --vault ./my-notes --json
pinax sync manifest promote --plan manifest-plan-<id> --remote-capability v2 --vault ./my-notes --yes --json

Agent plans bind the object ID plus the observed path and expected content/record revision. A pure move can safely rebase by UUID; path reuse or content drift returns plan_stale. Every apply writes a body-free receipt with before/after revisions, ledger sequence, snapshot evidence, changed paths, and sync readiness.

Status

Area Status
Local Markdown vault, notes, journals, inbox/drafts, templates, search, links/backlinks, assets, project workspaces/boards, database saved views, repair/organize plans Supported
CLI output modes: default summary, --agent, --json, --events, --explain Supported
Local dashboard, read-only MCP, localhost REST/RPC adapter, and workspace/task/database/graph read projections Supported
Obsidian-style vault compatibility: wikilinks/backlinks, properties, daily managed blocks, templates, attachments, dataview blocks, .obsidian/ ignore Preview
Capsa Sync over server, file/S3-compatible object store, and rclone transports Preview

Installation

Prerequisites:

  • Go 1.26.1 or newer, or download a prebuilt archive/package below.
  • Optional: Task for task check and local development shortcuts.

Install from source:

go install github.com/yeisme/pinax/cmd/pinax@latest

Download a prebuilt archive from GitHub Releases (current stable tag: v0.1.8):

# linux x86_64 (adjust os/arch for your platform: darwin, windows; x86_64, aarch64)
curl -L -o pinax.tar.gz https://github.com/yeisme/pinax/releases/download/v0.1.8/pinax_0.1.8_linux_x86_64.tar.gz
curl -L -o checksums.txt https://github.com/yeisme/pinax/releases/download/v0.1.8/checksums.txt
sha256sum -c checksums.txt --ignore-missing
tar xzf pinax.tar.gz
./pinax version

Windows uses a .zip archive instead of .tar.gz. See the release page for the full asset list (darwin, linux, windows × x86_64, aarch64), checksums.txt, source archives, and archive SBOMs.

Install with Homebrew after a tagged release publishes the formula:

brew install yeisme/tap/pinax
pinax version

Install with Scoop after a tagged release publishes the bucket manifest:

scoop bucket add yeisme https://github.com/yeisme/scoop-bucket
scoop install pinax
pinax version

Linux release assets also include direct .deb, .rpm, and .apk packages generated by nFPM. These are downloadable package files, not APT, YUM, DNF, or Alpine repositories.

For local development from a checkout:

go build -trimpath -ldflags="-s -w" -o dist/pinax ./cmd/pinax
./dist/pinax version

For release rehearsal from a checkout:

task release:check
task release:local
task release:package:validate

task release:local builds linux, macOS and Windows archives for amd64 and arm64, plus dist/checksums.txt, without publishing. task release:package:validate additionally verifies checksums, smokes an extracted archive, checks for SBOMs, and inspects Linux package metadata when host tools are available.

Quick start

pinax init ./my-notes --title "My Knowledge Base"
pinax vault validate --vault ./my-notes --json
pinax note add "Research Log" --body "First note" --tags research --vault ./my-notes
pinax index refresh --vault ./my-notes --json
pinax search "First note" --vault ./my-notes --json

See the command map for the recommended entry point for each workflow.

Five core workflows

Pinax is built around one agent-safe proof loop. A user or agent drives a real Markdown vault through five stages, and every stage stays bounded — projections never dump full note bodies, and writes only happen through plan, snapshot, receipt and explicit apply.

Path What it does Entry commands
Capture Add notes, inbox items and journal entries to the vault. pinax init, pinax note add, pinax inbox capture, pinax journal daily append
Retrieve Build the index projection and read bounded context. pinax index sync, pinax search, pinax note links, pinax note backlinks, pinax note orphans
Diagnose Check vault health and surface low-risk and review items. pinax vault doctor, pinax vault stats
Plan Turn issues into reviewable, savable repair and organize plans. pinax repair plan --save, pinax organize plan --save
Apply safely Snapshot first, then apply low-risk changes with explicit confirmation. pinax version snapshot, pinax repair apply --yes, pinax organize apply --yes

Agents can run the whole loop in one command. Preview is read-only; add --apply --yes to take a fresh snapshot and apply approved operations:

pinax proof loop run --vault ./my-notes --json            # preview: one projection with proof_loop_run_id
pinax proof loop run --vault ./my-notes --apply --yes     # fresh snapshot + approved repair/organize apply

If an apply goes wrong, revert a file from the last snapshot through a CLI-authored restore path (never direct file surgery):

pinax version restore notes/example.md --revision HEAD --plan --vault ./my-notes
pinax version restore apply --vault ./my-notes --plan restore-<id> --yes   # local_write=true, remote_write=false

Remove obsolete projects through the recoverable trash path, not by editing .pinax/projects.json:

pinax project delete history --vault ./my-notes --yes --json
pinax trash list --vault ./my-notes --json
pinax trash restore project/history --vault ./my-notes --json
pinax trash purge project/history --dry-run --vault ./my-notes --json
pinax init ./my-notes --title "My Knowledge Base"
pinax inbox capture "an idea" --vault ./my-notes
pinax note add "Research Log" --body "First note" --vault ./my-notes
pinax index sync --vault ./my-notes --json
pinax search "First note" --vault ./my-notes --json
pinax vault doctor --vault ./my-notes --json
pinax repair plan --vault ./my-notes --save --json
pinax version snapshot --vault ./my-notes --message "checkpoint"
pinax repair apply --vault ./my-notes --plan repair-abc123 --yes

Every command supports --json, --agent, --events and --explain output modes that share one projection boundary: bounded facts and next actions, never raw note bodies, tokens, or provider payloads. Capsa Sync remains a transport boundary and is not required for the local proof loop.

Workspace And Database Views

Project workspaces, task adoption, and database saved views are local-first projections over the Markdown vault:

pinax project create research --name "Research" --notes-prefix notes/research --vault ./my-notes --json
pinax project subproject create research stock-learning --title "Stock Learning" --template scenario --vault ./my-notes --json
pinax project item add research "Read annual report" --subproject stock-learning --column next --vault ./my-notes --json
pinax task adopt task_abc123 --plan --vault ./my-notes --json

pinax database view save active-table --display table --query 'SELECT title, status FROM notes WHERE status = "active" LIMIT 20' --vault ./my-notes --json
pinax database view render active-table --vault ./my-notes --json

pinax-database-view <name> Markdown fences render as bounded tabs in pinax note show --view rendered; saved view registries store configuration only, not result rows. Dashboard, MCP, REST/RPC, and remote CLI mode consume the same application service projections.

Local vault workflow

Initialize a Markdown vault:

pinax init
pinax init ./my-notes --title "My Knowledge Base"
pinax vault validate --vault ./my-notes --json

When pinax init has no arguments, it initializes the current directory; you can also specify the vault path with --vault <path> or a positional argument.

Register a vault once to make --vault <TAB> and default vault selection useful across note commands:

pinax vault register ./my-notes --name work --default
pinax vault list --json
pinax note list
pinax note list --vault work
pinax vault remote refresh --profile cloud-work --json
pinax vault remote list --profile cloud-work --json

Shell completion reads only local registry/cache files: it completes registered local aliases and cached remote selectors without contacting remotes, resolving secrets, or writing state. Regular commands support default Chinese summaries, --agent, --json, --events, and --explain output modes; only one of these modes can be selected at a time. Machine protocol fields, facts, error codes, and schema keys remain stable English.

The new primary path should prefer pinax vault stats|validate|doctor|dashboard, pinax journal daily|weekly|monthly, and pinax storage set local|s3; old root aliases remain compatible with existing scripts.

View vault statistics, health issues, and the read-only local dashboard:

pinax vault stats --vault ./my-notes
pinax vault stats --vault ./my-notes --json
pinax vault doctor --vault ./my-notes --stale-after 90d --agent
pinax vault dashboard --vault ./my-notes --port 0

stats and doctor are read-only by default and do not modify Markdown, .pinax/, Git, or remote services; dashboard binds only to localhost and reuses the same set of application service projections.

Convert health issues into reviewable, savable, snapshot-protected maintenance actions:

pinax repair plan --vault ./my-notes --json
pinax repair plan --vault ./my-notes --save --json
pinax version snapshot --vault ./my-notes --message "snapshot before repair"
pinax repair apply --vault ./my-notes --plan repair-abc123 --yes
pinax repair apply --vault ./my-notes --plan repair-abc123 --yes --snapshot-message "snapshot before repair"

repair plan is read-only by default; only --save writes .pinax/repair-plans/<plan_id>.json through the service. repair apply only performs low-risk metadata, tags, index rebuild, and archive status fixes. Duplicate titles, broken links, ambiguous links, empty notes, and orphan notes only generate manual review; it does not automatically delete, merge, or rewrite body text. Dashboard /api/repair-plans and /api/graph-summary provide read-only display of saved plans, relationship health summaries, and CLI apply/rebuild commands.

Complete note metadata:

pinax metadata plan --vault ./my-notes --json
pinax metadata apply --vault ./my-notes --yes

Manage multiple projects inside one vault:

pinax project create research --name "Research" --notes-prefix notes/research --vault ./my-notes
pinax project list --vault ./my-notes --json
pinax project switch research --vault ./my-notes
pinax project subproject create research stock-learning --title "Stock Learning" --template scenario --vault ./my-notes --json
pinax project subproject show research stock-learning --vault ./my-notes --json

View and maintain the local project board workspace. The board comes from local Markdown, project metadata, SQLite/GORM projections, and saved planning snapshots; it is not a remote Todo provider, and it does not treat TaskBridge as the source of truth:

pinax project board show research --vault ./my-notes --json
pinax project board show research --subproject stock-learning --compact --vault ./my-notes
pinax project board show research --note-display card --vault ./my-notes
pinax project board configure research --columns inbox,next,doing,blocked,review,done --vault ./my-notes --json
pinax project board configure research --subproject stock-learning --columns inbox,next,doing,blocked,review,done --vault ./my-notes --json
pinax project board plan research --save --vault ./my-notes --json
pinax project board export research --format markdown --vault ./my-notes --json
pinax project item add research "Implement local board" --subproject stock-learning --column next --labels local,planning --milestone q3 --priority high --body "Controlled work item" --vault ./my-notes --json
pinax project item move research/Implement local board.md doing --vault ./my-notes --json
pinax version snapshot --vault ./my-notes --message "snapshot before project item archive"
pinax project item archive research/Implement local board.md --yes --vault ./my-notes --json

project board show and export are read-only by default and do not write .pinax/, Markdown, Git, TaskBridge, or remote providers. project board plan --save only writes .pinax/planning/project-boards/<snapshot_id>.json as review evidence; plan weekly --taskbridge --dry-run reads the next/doing/blocked counts from the latest board snapshot, but does not automatically write board items into TaskBridge. project item archive requires --yes and an explicit version snapshot.

Manage daily Markdown notes:

pinax note add "Research Log" --body "Today's observations" --tags research --status active --dir work --vault ./my-notes
pinax note add "Meeting Notes" --stdin --vault ./my-notes
pinax note list --tag research --status active --recent --limit 20 --vault ./my-notes
pinax note read "Research Log" --vault ./my-notes --json
pinax note read "Research Log" --display card --vault ./my-notes --json
pinax note read "Research Log" --display body --vault ./my-notes --json
pinax note preview "Research Log" --vault ./my-notes
pinax note edit "Research Log" --editor "$EDITOR" --vault ./my-notes
pinax note rename "Research Log" "Pinax Research Log" --vault ./my-notes
pinax note move "Pinax Research Log" archive --vault ./my-notes
pinax note archive "Pinax Research Log" --vault ./my-notes
pinax note tag add "Pinax Research Log" important --vault ./my-notes
pinax note delete "Pinax Research Log" --yes --vault ./my-notes

note add is the recommended entry point for adding notes, while note new and note create remain compatible aliases. By default, note list/search/show, the relationship graph, and the index only process Pinax notes with schema_version: pinax.note.v1; ordinary Markdown files in the vault do not automatically become notes just because their extension is .md. Use pinax import markdown ... --yes to batch adopt external Markdown.

User-visible note paths use vault-relative canonical paths: by default, ordinary notes are output as root-level foo.md; after using --dir work or move, they are output as work/foo.md. The resolver remains compatible with historical notes/foo.md, stems, note IDs, and unique title input, but the primary output of CLI/JSON/agent/search/record/MCP consistently uses canonical paths.

note show/read/edit/rename/move/archive/delete/tag all support note IDs, paths inside the vault, or unique titles; when a title has multiple candidates, note_ref_ambiguous is returned to avoid accidental edits. note edit/open/new --open supports editors with arguments, such as --editor "code --wait"; note list --recent means sorting by update time, not implicitly filtering old notes; note delete moves to .pinax/trash/YYYYMMDD/ by default and generates a unique target on same-name conflicts. Real deletion requires passing both --hard --yes.

note read/show --display card|detail|context|body uses the shared NoteDisplay projection. card/detail/context do not output the full body and are suitable for agents, dashboards, MCP, and project boards; only --display body puts the body into the local JSON projection.

note preview is for direct local reading: default human output renders only the preview body and does not print a standalone success table. Empty successful previews are silent; automation should use --json or --agent when it needs the success envelope and resolver facts.

Use notebook core workflows to capture, index, browse, and search:

pinax journal daily open --vault ./my-notes --editor "$EDITOR"
pinax journal daily append --body "Today's review" --vault ./my-notes
pinax inbox capture "Temporary idea" --body "Put it in inbox first" --tags idea --vault ./my-notes
pinax inbox triage "Temporary idea" --group work --folder ideas --kind reference --status active --vault ./my-notes

pinax index --vault ./my-notes
pinax index refresh --vault ./my-notes --json
pinax index doctor --vault ./my-notes --agent
pinax index rebuild --vault ./my-notes --json
pinax search "authentication" --tag auth --group work --folder architecture --kind reference --status active --vault ./my-notes --json

pinax note tags --vault ./my-notes --json
pinax note folders --vault ./my-notes --json
pinax note kinds --vault ./my-notes --json
pinax note groups --vault ./my-notes --json
pinax view save active-work --group work --status active --kind reference --sort updated --vault ./my-notes --json
pinax view show active-work --vault ./my-notes --json

Check local Markdown relationships and attachments:

pinax note links "Authentication Plan" --vault ./my-notes --json
pinax note links "Authentication Plan" --broken-only --vault ./my-notes --json
pinax note backlinks "Authentication Plan" --include-broken --vault ./my-notes --json
pinax note orphans --mode full --vault ./my-notes --json
pinax search "authentication" --link-target notes/design/auth.md --vault ./my-notes --json
pinax note attach "Authentication Plan" ./diagram.png --vault ./my-notes --json
pinax note attachments "Authentication Plan" --vault ./my-notes --json

pinax note links parses [[Title]], [[Title|Alias]], [[Title#Heading]], and Markdown relative links; external URLs, mailto:, plain headings, and non-Markdown attachments are not treated as note edges. Relationship statuses include resolved, broken, ambiguous, external, and ignored: broken links mean the target does not exist, and ambiguous means multiple title or alias candidates; Pinax does not guess for the user. pinax note orphans modes --mode full|no-incoming|no-outgoing respectively view completely isolated notes, notes with no incoming links, and notes with no outgoing links; search --link-target supports filtering by resolved note ID/path/title or unresolved raw target, and returns link_target_ambiguous when ambiguous.

The SQLite/GORM index is a rebuildable projection, not the note source of truth; the Markdown vault remains the source of truth. pinax index --vault ./my-notes summarizes index state and recommends next steps; when missing/stale, prefer running the low-cost pinax index refresh --vault ./my-notes; for structural exceptions or corrupt projections, first use pinax index doctor --vault ./my-notes to view issues, then follow prompts to run repair --dry-run or an explicit rebuild. pinax note links, pinax note backlinks, pinax note orphans, and search --link-target prefer a fresh index; when the index is unavailable, they fall back to scanning Markdown and provide executable actions.

note attach copies files into attachments/ inside the vault and appends a Markdown reference; if the source file is missing, it returns attachment_source_missing and does not modify the note body or attachment directory.

Import and export local Markdown bundles:

pinax import markdown ./source --group research --tags imported --dry-run --vault ./my-notes --json
pinax import markdown ./source --group research --kind reference --status active --conflict rename --yes --vault ./my-notes --json
pinax import markdown ./source/beta.md --group research --conflict overwrite --yes --vault ./my-notes --json
pinax export markdown ./out --tag imported --vault ./my-notes --json

import markdown --dry-run does not write notes, receipts, Git, or provider state; apply writes .pinax/receipts/import-*.json through the service. export markdown exports Markdown and referenced attachments according to note filters, and writes .pinax/receipts/export-*.json.

Manage Markdown templates and generate notes from templates:

pinax template init --vault ./my-notes
pinax template list --pack starter --vault ./my-notes --json
pinax template recommend --intent "meeting sync" --vault ./my-notes --json
pinax template recommend --intent "写小说" --vault ./my-notes --json
pinax template recommend --intent "便签" --vault ./my-notes --json
pinax journal daily show --date 2026-06-08 --template journal.daily --vault ./my-notes --json
pinax index page create home --template index.home --vault ./my-notes --json
pinax index page create ideas --template index.ideas --vault ./my-notes --json
pinax note add "Client Meeting" --template meeting.notes --tags meeting,client --vault ./my-notes --json
pinax note add "某篇小说是怎么写成的" --template idea.research_seed --vault ./my-notes --json
pinax note add "临时线索" --template sticky.capture --vault ./my-notes --json
pinax note add "子项目看板线索" --template sticky.project_signal --project research --folder inbox --vault ./my-notes --json
pinax note add "Transformer Paper" --template reading.paper --vault ./my-notes --json
pinax template create "Video Learning" --vault ./my-notes
pinax template create meeting --body "# {{title}} - {{client}}" --vault ./my-notes
pinax template create weekly --engine go-template --body "# {{ .Title }}
{{ .Vars.client }}" --vault ./my-notes
pinax template inspect weekly --vault ./my-notes --json
pinax template preview weekly --title "Client Meeting" --var client=Acme --vault ./my-notes --agent
pinax template render weekly --title "Client Meeting" --var client=Acme --save-run weekly-demo --vault ./my-notes --json
pinax template render weekly --run weekly-demo --vault ./my-notes --json
pinax template inspect weekly --runs --vault ./my-notes --json
pinax note new "Client Meeting" --template weekly --var client=Acme --tags meeting,client --vault ./my-notes
pinax template runs prune weekly --keep 20 --dry-run --vault ./my-notes --json
pinax template runs repair --vault ./my-notes --json
pinax template delete weekly --vault ./my-notes --yes

Templates are stored in .pinax/templates/*.md and are ordinary Markdown text. Legacy templates continue to support simple tokens such as {{title}} and {{client}}; after declaring schema_version: pinax.template.v2 and engine: go-template, they use Go text/template syntax. Use template inspect to view variable schemas, query facts, and render runs. Template functions are allowlisted: they do not execute scripts, read environment variables, or access the network.

Built-in templates are divided into journal, index, idea seed, sticky capture, and note starter packs: journal.daily|weekly|monthly create root-level journals, index.home and topic index pages only refresh pinax:managed managed blocks, idea.* templates park Chinese idea seeds with kind: idea and status: parked, sticky.* templates create short inbox notes with kind: sticky and status: inbox without writing managed board metadata, and detailed Chinese templates such as reading.paper, reading.novel, writing.novel, media.anime, media.drama, game.playlog, learning.video, and learning.book are suitable for deeper notes. template list --pack starter and template recommend --intent <intent> are the recommended entry points for choosing templates; JSON/agent output from template inspect <name> gives next-step actions, and template names, --template, --var, and render runs support shell Tab completion.

Query-backed templates use Pinax SQL, not raw SQLite. Templates can declare language: sql in queries in v2 frontmatter, or use pinax-sql fenced blocks in the body; template inspect only explains, while template preview/render executes bounded queries and puts results into .Queries, such as {{ table .Queries.active }} or {{ list .Queries.active "title" }}. Note rendered views also support safe pinax-dataview fenced blocks.

pinax query run 'SELECT title, status FROM notes WHERE status = "active" LIMIT 5' --lazy-index --vault ./my-notes --json
pinax dataview run 'TABLE title, status FROM #pinax LIMIT 5' --lazy-index --vault ./my-notes --json
pinax database view save active-dv --language dataview --query 'TABLE title, status FROM #pinax LIMIT 20' --vault ./my-notes --json
pinax template preview project-dashboard --vault ./my-notes --json

For formal rendering, use --save-run <name> to save a redacted receipt, rendered.md, and scope index.json in .pinax/renders/templates/<template>/<run-id>/; --run <name-or-id> reuses historical parameters and re-renders against the current vault. latest and aliases in the same scope can be used for shell completion.

Notes also support source/rendered views and controlled write-back:

pinax note show projects/dashboard.md --view source --vault ./my-notes --json
pinax note show projects/dashboard.md --view rendered --vault ./my-notes --json
pinax note refresh projects/dashboard.md --rendered --save-run dashboard-latest --yes --vault ./my-notes --json
pinax note show projects/dashboard.md --view rendered --snapshot latest --vault ./my-notes --json
pinax note show projects/dashboard.md --runs --vault ./my-notes --json

note show --view rendered read-only executes restricted pinax-sql and pinax-dataview blocks and does not write Markdown, .pinax/, Git, or providers. note refresh --rendered --yes only updates managed blocks from <!-- pinax:render <name> start --> to <!-- pinax:render <name> end --> or <!-- pinax:managed name=<name> --> to <!-- /pinax:managed -->, preserving source query blocks and user body text; note-scoped render runs are saved in .pinax/renders/<note-path-without-notes-prefix-and-ext>/<run-id>/.

Configure the storage backend for vault artifacts and diagnostics. S3-compatible configuration stores non-secret profile metadata; credentials stay in the provider profile or environment:

pinax storage set local --root ./my-notes --vault ./my-notes
pinax storage set s3 --bucket notes --region us-east-1 --prefix pinax/ --profile work --vault ./my-notes --json
pinax storage doctor --vault ./my-notes --json

Preview and create an explicit version snapshot before organizing structure:

pinax organize plan --vault ./my-notes --json
pinax version snapshot --vault ./my-notes --message "snapshot before organize"
pinax organize apply --vault ./my-notes --yes

You can also provide a snapshot message during apply, so Pinax creates a protective snapshot before applying changes:

pinax organize apply --vault ./my-notes --yes --snapshot-message "snapshot before organize"

Agents can generate reviewable organize plans instead of directly modifying notes:

pinax organize plan --vault ./my-notes --json
pinax organize plan --vault ./my-notes --save --agent
pinax organize list --vault ./my-notes --json
pinax organize apply --vault ./my-notes --plan organize-abc123 --yes --snapshot-message "snapshot before organize" --json

organize plan --save generates move, tag_patch, kind_patch, status_patch, link_resolution, link_rewrite, orphan_review, attachment_repair, and manual_review operations; organize apply --plan only executes low-risk moves protected by snapshots, leaving other operations for humans or future dedicated apply flows. The old organize suggest entry point remains compatible with existing scripts, but is no longer shown as the primary path.

Start the read-only MCP surface:

pinax mcp serve --vault ./my-notes

The local REST/RPC projection adapter binds only to localhost and only reuses application service projections; it is not a public hosted API. The root path returns a small discovery projection, while /v1/capabilities lists callable REST/RPC capabilities:

pinax api routes --vault ./my-notes --json
pinax api schema export --format openapi --vault ./my-notes --json
pinax api serve --readonly --no-auth --port 8787 --vault ./my-notes
curl -s http://127.0.0.1:8787/
curl -s http://127.0.0.1:8787/v1/capabilities

REST GET /v1/projects/{slug}/board, RPC Pinax.ProjectBoard.Show, and the MCP board tool return the same class of bounded board projection; write-like remote calls only return dry-run/plan, approval_required, or snapshot_required by default. Real Markdown changes still go through explicit CLI commands.

Capsa Sync preview

Pinax Capsa Sync is separate from pinax api serve. The Local API exposes one centralized vault through REST/RPC; Capsa Sync is a distributed protocol where each device keeps its own local vault and exchanges encrypted revisions, manifests, and blobs through a selected transport.

Configure a direct object-store transport and sync two local devices:

pinax init ./device-a --title "Device A"
pinax init ./device-b --title "Device B"
mkdir -p ./device-a/notes
printf '# Alpha\n\nfrom device A\n' > ./device-a/notes/alpha.md
pinax capsa login --endpoint "file://$PWD/.capsa-sync-store" --workspace personal --device laptop --secret-ref env://PINAX_SYNC_SECRET --vault ./device-a
pinax capsa login --endpoint "file://$PWD/.capsa-sync-store" --workspace personal --device desktop --secret-ref env://PINAX_SYNC_SECRET --vault ./device-b
pinax sync push --target capsa --vault ./device-a --yes --json
pinax sync pull --target capsa --vault ./device-b --yes --json

Run local automatic sync on a configured device:

pinax sync daemon run --target capsa --vault ./device-a --yes
pinax sync daemon status --vault ./device-a --json
pinax sync daemon logs --vault ./device-a --limit 20 --json
pinax sync daemon stop --vault ./device-a

The daemon is a local process. On startup it immediately runs one pull-before-push sync cycle, then watches local vault changes and polls the remote Capsa Sync head. Default human output shows live progress lines; --events emits an NDJSON stream; redacted daemon state and events are persisted under .pinax/sync-daemon/.

S3-compatible storage uses the same Capsa Sync protocol without a Capsa Server:

pinax capsa backend set s3 --bucket notes --region us-east-1 --prefix pinax-sync/ --profile work --workspace personal --device laptop --vault ./my-notes
pinax capsa doctor --vault ./my-notes --json

Server and rclone backends are explicit transports, not aliases for Local API. Server transport uses internal/cloudclient.Transport so Capsa can own auth/audit/policy, while rclone direct transport uses the shared object-store sync path for providers such as OneDrive. Native Microsoft Graph is a separate future transport.

remote_write=true is valid only after the selected transport durably commits a revision and Pinax writes local sync-state evidence. Dry-runs, plans, blob uploads, failed or unsupported transport operations, and pull operations keep remote_write=false.

See Capsa command docs, sync command docs, and Capsa Sync architecture.

MCP tools and resources are read-only, including pinax.note.links, pinax.note.backlinks, pinax.note.context, and pinax.vault.graph_summary. They reuse the CLI relationship projection and return bounded facts, candidate summaries, and next-step commands. They do not return full note bodies and do not write Markdown, .pinax/, Git, providers, or remote state.

Local validation

task build
task test
task check
task kb:sidecar:test

task check uses the offline LanceDB sidecar protocol test so local validation does not depend on PyPI availability. Run task kb:sidecar:test when you need the real Python lancedb package install and rebuild/search smoke.

When task is not installed, use the equivalent commands:

go test ./...
go build -trimpath -ldflags="-s -w" -o dist/pinax ./cmd/pinax
openspec validate --all

Documentation entry points

License

Pinax is licensed under the MIT License.

Directories

Path Synopsis
cmd
pinax command
internal
agentadapter
Package agentadapter 提供 reference adapter harness,验证 Codex 和 Cohors adapter 能力协商、context request 渲染、proposal/handoff 转换和 failure isolation。
Package agentadapter 提供 reference adapter harness,验证 Codex 和 Cohors adapter 能力协商、context request 渲染、proposal/handoff 转换和 failure isolation。
agentcontext
Package agentcontext 实现 permission-first bounded context compilation。
Package agentcontext 实现 permission-first bounded context compilation。
agentcontinuity
Package agentcontinuity 实现 Agent 连续工作的产品编排层。
Package agentcontinuity 实现 Agent 连续工作的产品编排层。
agentmemory
Package agentmemory 实现 Agent memory runtime 的持久化存储层。
Package agentmemory 实现 Agent memory runtime 的持久化存储层。
agentprotocol
Package agentprotocol defines the versioned, provider-neutral Agent memory runtime contract: principal, scope, memory record, context request/pack, proposal, handoff, feedback and adapter descriptor.
Package agentprotocol defines the versioned, provider-neutral Agent memory runtime contract: principal, scope, memory record, context request/pack, proposal, handoff, feedback and adapter descriptor.
api
app
Package app owns Pinax application-service orchestration.
Package app owns Pinax application-service orchestration.
app/briefingops
Package briefingops owns app-layer briefing workflows behind the app.Service facade.
Package briefingops owns app-layer briefing workflows behind the app.Service facade.
app/noteops
Package noteops owns app-layer note workflows behind the app.Service facade.
Package noteops owns app-layer note workflows behind the app.Service facade.
app/planningops
Package planningops owns app-layer planning workflows behind the app.Service facade.
Package planningops owns app-layer planning workflows behind the app.Service facade.
app/publishops
Package publishops owns pure rules for the publish command family.
Package publishops owns pure rules for the publish command family.
app/searchops
Package searchops owns app-layer search and query workflows behind the app.Service facade.
Package searchops owns app-layer search and query workflows behind the app.Service facade.
app/syncops
Package syncops owns app-layer cloud and backend sync workflows behind the app.Service facade.
Package syncops owns app-layer cloud and backend sync workflows behind the app.Service facade.
app/templateops
Package templateops owns app-layer template and journal workflows behind the app.Service facade.
Package templateops owns app-layer template and journal workflows behind the app.Service facade.
app/vaultops
Package vaultops owns app-layer vault maintenance workflows behind the app.Service facade.
Package vaultops owns app-layer vault maintenance workflows behind the app.Service facade.
app/versionops
Package versionops owns app-layer version-control workflows behind the app.Service facade.
Package versionops owns app-layer version-control workflows behind the app.Service facade.
cli
cloudclient
Package cloudclient 是 Pinax CLI 访问 Pinax Cloud Sync MLP 服务端 REST 合同的客户端。
Package cloudclient 是 Pinax CLI 访问 Pinax Cloud Sync MLP 服务端 REST 合同的客户端。
cloudclient/mlptest
Package mlptest 提供 Pinax Cloud Sync MLP REST 合同的内存 HTTP 测试服务端。
Package mlptest 提供 Pinax Cloud Sync MLP REST 合同的内存 HTTP 测试服务端。
domain
Package domain owns stable Pinax domain models and command projections.
Package domain owns stable Pinax domain models and command projections.
git
identity
Package identity 定义 Pinax durable vault object 的稳定身份合同。
Package identity 定义 Pinax durable vault object 的稳定身份合同。
index/gormgen command
gormgen 为 internal/index 本地索引投影生成 GORM Gen 类型化 DAO。
gormgen 为 internal/index 本地索引投影生成 GORM Gen 类型化 DAO。
index/model
Package model 定义 internal/index 本地索引投影的全部 GORM 模型。
Package model 定义 internal/index 本地索引投影的全部 GORM 模型。
memoryinbox
Package memoryinbox 实现 Memory Inbox 聚合投影。
Package memoryinbox 实现 Memory Inbox 聚合投影。
output
Package output renders Pinax command projections for human and machine modes.
Package output renders Pinax command projections for human and machine modes.
provider
Package provider 定义 provider adapter 的稳定内部接口和数据契约。
Package provider 定义 provider adapter 的稳定内部接口和数据契约。
publishdocast
Package publishdocast 把 Pinax note Markdown 解析为发布专用的抽象语法树, 供原生文档渲染器(飞书 native-docx)转换为 provider-neutral 文档块。
Package publishdocast 把 Pinax note Markdown 解析为发布专用的抽象语法树, 供原生文档渲染器(飞书 native-docx)转换为 provider-neutral 文档块。
redaction
Package redaction centralizes secret, token, raw payload, and trace redaction.
Package redaction centralizes secret, token, raw payload, and trace redaction.
testkit
Package testkit owns fixture vaults, fake provider CLIs, and test helpers.
Package testkit owns fixture vaults, fake provider CLIs, and test helpers.
testkit/evidence
Package evidence writes local integration/e2e evidence for Pinax test runs.
Package evidence writes local integration/e2e evidence for Pinax test runs.
testkit/integrationevidence command
Package main writes local integration/e2e evidence for Pinax test runs.
Package main writes local integration/e2e evidence for Pinax test runs.
pkg
agentmemory
Package agentmemory 提供面向 embedded Go consumer 的 Agent memory runtime facade。
Package agentmemory 提供面向 embedded Go consumer 的 Agent memory runtime facade。
tests

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL