Skip to content

@uriva/agentdocs

1.0.12
Skill

Description

End-to-end encrypted JSON documents for AI agents — store, retrieve, and share via safescript..

Download
Review Recommended
tank install @uriva/agentdocs

agentdocs — Encrypted JSON Documents for AI Agents

agentdocs is an end-to-end encrypted document platform. It uses a hybrid model:

  • latest full encrypted snapshot stored on the document row for fast reads
  • append-only encrypted incremental patches as the edit history

The server stores only ciphertext and cannot read titles, bodies, ticket state, or any other domain metadata.

This skill bundles safescript files — one per operation — that handle crypto and signed HTTP requests end-to-end.

API base URL: https://agentdocs-api.uriva.deno.net safescript language: https://safescript.dev

Step 1 — Get an identity from the user

Agents do not generate identities. Ask the user to create one in the web UI and export it:

  1. Open https://agentdocs-nine.vercel.app and sign in.
  2. Create or choose an identity and click Export.
  3. Copy the base64url exported bundle.
  4. Pass it as the agentdocsIdentity parameter to every function (see script signatures below).

Bundle shape (decoded JSON):

{
  "id": "<identity UUID>",
  "name": "<display name>",
  "signing": { "privateKey": "<base64url PKCS8 Ed25519 private key>" },
  "encryption": { "privateKey": "<base64url PKCS8 X25519 private key>" },
  "algorithm": {
    "signing": "Ed25519",
    "keyExchange": "X25519",
    "symmetric": "AES-GCM-256"
  }
}

Step 2 — Use the scripts

ScriptPurpose
create-document.ssCreate a document with initial snapshot + first patch
add-edit.ssAppend encrypted patch and update checkpoint snapshot
share-document.ssGrant another identity access
list-documents.ssReturn decrypted latest snapshot per doc
get-document.ssReturn one decrypted latest snapshot
search-documents.ssReturn all decrypted latest snapshots
delete-document.ssDelete a single document by ID

Script signatures

createDocument(title: string, content: string, agentdocsIdentity: string)
  -> { documentId, documentKey, status, body }

addEdit(documentId: string, documentKey: string, newSnapshotJson: string, agentdocsIdentity: string)
  -> { status, body, sequenceNumber }

shareDocument(documentId: string, documentKey: string, granteeIdentityId: string, agentdocsIdentity: string)
  -> { status, body }

listDocuments(agentdocsIdentity: string)
  -> { documents: [{ documentId, kind, title, content, documentKey }] }

getDocument(documentId: string, agentdocsIdentity: string)
  -> { documentId, kind, title, content, documentKey, sequenceNumber }

searchDocuments(agentdocsIdentity: string)
  -> { documents: [{ documentId, kind, title, content, documentKey }] }

deleteDocument(documentId: string, agentdocsIdentity: string)
  -> { success: boolean, deleted: number }

How agents should modify documents

Edits are incremental patches. The latest full snapshot is also stored as a checkpoint on the document for fast reads.

Recommended update flow:

  1. Read current state with getDocument(documentId).
  2. Parse content as JSON if kind is not enough, or use known convention.
  3. Apply changes in memory.
  4. Build the new full snapshot JSON.
  5. Call addEdit(...) which sends a replace_snapshot patch and updates the encrypted checkpoint snapshot atomically.

Example: rename a doc

Read the latest snapshot, change title, keep everything else, then append:

{
  "kind": "doc",
  "title": "New Title",
  "content": "...existing content..."
}

Example: update ticket status

{
  "kind": "ticket",
  "title": "Fix auth timeout",
  "content": "Description and acceptance criteria",
  "status": "in_progress",
  "priority": "high",
  "assigneeIdentityId": "<identity-id>",
  "labels": ["bug", "auth"],
  "comments": [
    {
      "authorIdentityId": "<identity-id>",
      "timestamp": "2026-04-17T12:34:56.000Z",
      "content": "Investigating token refresh path"
    }
  ]
}

Important: preserve fields you are not changing. Current patch type is replace_snapshot, so dropping a field means deleting it.

Wiki links between documents

Use one canonical linking convention. Do not invent alternate fields or custom markdown syntaxes.

When one document references another document:

  1. Add a normal markdown link in content using the agentdocs: protocol: [Architecture Details](agentdocs:0b639d84-5998-4e86-8ef9-d1bd4b7c6cce)
  2. Also add or update a top-level linkedDocuments array in the JSON snapshot.

Canonical snapshot shape:

{
  "kind": "doc",
  "title": "Project Context & Wiki Initialization",
  "content": "See [Architecture Details](agentdocs:0b639d84-5998-4e86-8ef9-d1bd4b7c6cce).",
  "linkedDocuments": [
    {
      "documentId": "0b639d84-5998-4e86-8ef9-d1bd4b7c6cce",
      "title": "Architecture Details",
      "relationship": "related"
    }
  ]
}

Rules:

  • linkedDocuments is top-level, not inside content.
  • Use documentId, not id, docId, target, or href.
  • Keep title as the target document's current human-readable title.
  • Use relationship only for a short label like related, parent, child, source, or reference.
  • Preserve existing linkedDocuments entries when adding a new link.
  • If you create the target document, use the documentId returned by createDocument in both the markdown agentdocs: URL and linkedDocuments.
  • Do not use hardcoded web domains for internal document links. Use agentdocs:<documentId> so links work across localhost, previews, and custom domains.

JSON-first model (everything is a document)

The platform has one primitive: encrypted document snapshots, with patch-based history.

  • A note/spec doc is a JSON snapshot.
  • A ticket is a JSON snapshot with ticket fields.
  • A spreadsheet is a JSON snapshot with kind: "spreadsheet" and data.

Recommended conventions are documented in:

  • conventions/doc.md
  • conventions/ticket.md
  • conventions/spreadsheet.md
  • conventions/contact.md

Searching

searchDocuments decrypts every accessible latest snapshot and returns them. Your agent filters locally (substring, embeddings, LLM ranking, etc.).

Permission surface

All scripts:

  • hosts: agentdocs-api.uriva.deno.net
  • env: timestamp (all), randomBytes (create/share grant flows)

What scripts do not cover

  • Webhook lifecycle (/api/webhooks) is not wrapped here.
  • Key rotation / hard revocation is not implemented by API.

Command Palette

Search packages, docs, and navigate Tank