Package Exports
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (@tailor-app/cli) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
Tailor CLI
Command-line tool for uploading, sharing, and managing documents on Tailor.
Quickstart
npm install -g @tailor-app/cli
tailor login --email you@company.com
tailor upload ./my-document.docx --shareInstallation
From npm (recommended)
npm install -g @tailor-app/cli
tailor --helpRequires Node.js 20+.
From the repo (development)
cd tools/tailor-cli
npm install
npm run buildRun commands via node bin/tailor.js <command> or set up a shell alias.
Authentication
The CLI uses API keys for authentication. Keys are prefixed with tailor_sk_ and sent as X-Api-Key headers.
For AI agents and CI/CD (recommended)
Set an environment variable — no tailor login needed:
export TAILOR_API_KEY=tailor_sk_your_key
tailor list # works immediatelyOptionally set the base URL (defaults to https://tailor.au):
export TAILOR_BASE_URL=https://tailor.auEnvironment variables take precedence over stored configuration.
Store a key to disk
tailor login --key tailor_sk_your_key --url https://tailor.auVerify current auth
tailor login --checkInteractive login (humans only)
tailor login --email you@company.comNote:
tailor loginwithout flags is interactive and requires a terminal. In non-TTY environments (CI, AI agents), it prints guidance and exits.
Command Reference
tailor login
Configure API key and base URL for the CLI.
tailor login --key tailor_sk_abc123 # Store API key
tailor login --key tailor_sk_abc123 --url https://tailor.au
tailor login --check # Verify current auth
tailor login --email you@company.com # Interactive magic link
tailor login # Fully interactive (TTY only)Options:
| Flag | Description | Default |
|---|---|---|
--key <apiKey> |
API key (must start with tailor_sk_) |
— |
--url <baseUrl> |
Base URL for the Tailor API | https://tailor.au |
--check |
Validate current auth and exit (no prompts) | — |
--email <email> |
Account email for magic link auth | — |
--code-only |
Skip browser auth, use code entry only | — |
tailor upload <files...>
Upload one or more documents. Supports files, folders, and glob patterns.
tailor upload ./report.docx
tailor upload ./report.md
tailor upload ./docs/ # upload all supported files in folder (recursive)
tailor upload ./docs/*.docx
tailor upload ./deliverables/*.docx --share --public
tailor upload ./budget.xlsx --share --permission CommentOnly
tailor upload ./docs/*.docx --jsonWhen a folder is passed, it is scanned recursively for supported file types (.docx, .pdf, .html, .htm, .md).
Arguments:
| Argument | Description |
|---|---|
<files...> |
One or more file paths, folder paths, or glob patterns |
Options:
| Flag | Description | Default |
|---|---|---|
--share |
Create shareable links after upload | false |
--permission <perm> |
Share permission: ReadOnly, CommentOnly, FullReview |
ReadOnly |
--public |
Public links (no email verification) | false |
--json |
Output results as JSON | false |
tailor share <documentId>
Create a shareable link for an existing document.
tailor share a1b2c3d4-e5f6-7890-abcd-ef1234567890
tailor share a1b2c3d4 --permission FullReview
tailor share a1b2c3d4 --publicArguments:
| Argument | Description |
|---|---|
<documentId> |
Document ID (GUID) |
Options:
| Flag | Description | Default |
|---|---|---|
--permission <perm> |
ReadOnly, CommentOnly, FullReview |
ReadOnly |
--public |
No email verification required | false |
tailor list
List all your documents.
tailor list
tailor list --jsonOptions:
| Flag | Description | Default |
|---|---|---|
--json |
Output as JSON | false |
tailor keys create
Create a new API key.
tailor keys create --name "CI Pipeline"
tailor keys create --name "LCC Upload" --scopes "documents:read,documents:write"
tailor keys create --name "Temp Key" --expires 30Options:
| Flag | Description | Default |
|---|---|---|
--name <name> |
Key name (required) | — |
--scopes <scopes> |
Comma-separated scopes | documents:read,documents:write |
--expires <days> |
Days until expiry | 365 |
tailor keys list
List all active API keys.
tailor keys listtailor keys revoke
Revoke an API key.
tailor keys revoke key_abc123tailor tap — PACT Protocol
Collaborate on documents at machine speed. The tap command group lets AI agents join documents, propose edits, review proposals, and coordinate via the PACT protocol.
Command Reference
| Command | Description |
|---|---|
tailor tap join <docId> --as <name> |
Register as an agent on a document |
tailor tap leave <docId> |
Unregister from a document |
tailor tap get <docId> |
Get document content (Markdown, HTML, or DOCX text) |
tailor tap sections <docId> |
Show section tree with stable IDs (.md, .html, .docx) |
tailor tap propose <docId> --section <id> |
Propose an edit to a section |
tailor tap proposals <docId> |
List active proposals |
tailor tap approve <docId> <proposalId> |
Approve a proposal |
tailor tap reject <docId> <proposalId> --reason <text> |
Reject a proposal |
tailor tap agents <docId> |
List active agents |
tailor tap escalate <docId> --message <text> |
Escalate to human reviewer |
tailor tap events <docId> |
View event history |
tailor tap lock <docId> --section <id> |
Lock a section for editing |
tailor tap unlock <docId> --section <id> |
Unlock a section |
tailor tap intent <docId> --section <id> --goal <text> |
Declare an intent on a section |
tailor tap intents <docId> |
List intents on a document |
tailor tap constrain <docId> --section <id> --boundary <text> |
Publish a constraint |
tailor tap constraints <docId> |
List constraints on a document |
tailor tap salience <docId> --section <id> --score <0-10> |
Set salience score for a section |
tailor tap salience-map <docId> |
View salience heat map |
tailor tap object <docId> --proposal <id> --reason <text> |
Object to a proposal |
Supported Document Formats
PACT works with any document format Tailor supports:
| Format | Section Parsing | Proposals | Content Retrieval |
|---|---|---|---|
Markdown (.md) |
✅ ATX headings | ✅ Full | ✅ Raw Markdown |
HTML (.html) |
✅ <h1>–<h6> tags |
✅ Full | ✅ Raw HTML |
DOCX (.docx) |
✅ Word heading styles | ✅ Full | ✅ Text projection |
PDF (.pdf) |
✅ Via DOCX conversion | ✅ Full | ✅ Text projection |
All formats produce the same sec:slug/child-slug section IDs, so agents interact identically regardless of source format.
tailor tap join
tailor tap join abc123 --as "legal-reviewer" --role reviewer| Flag | Description | Required |
|---|---|---|
--as <agentName> |
Agent name | Yes |
--role <role> |
Agent role | No |
tailor tap get
Outputs document content to stdout so it can be piped. For Markdown and HTML, raw source is returned; for DOCX and PDF, a text projection is returned:
tailor tap get abc123 > document.md
tailor tap get abc123 --section sec_01 | head -20| Flag | Description | Required |
|---|---|---|
--section <sectionId> |
Get single section | No |
tailor tap propose
Propose a change using a file or inline content:
# From a file
tailor tap propose abc123 --section sec_01 --file ./revised-intro.md --summary "Tightened intro"
# Inline content
tailor tap propose abc123 --section sec_01 --content "New paragraph text" --summary "Fixed typo"| Flag | Description | Required |
|---|---|---|
--section <sectionId> |
Target section | Yes |
--file <path> |
Read content from file | One of --file / --content |
--content <text> |
Inline content | One of --file / --content |
--summary <text> |
Change summary | No |
--reasoning <text> |
Reasoning for change | No |
tailor tap proposals
tailor tap proposals abc123
tailor tap proposals abc123 --section sec_01 --status pending --json| Flag | Description | Required |
|---|---|---|
--section <sectionId> |
Filter by section | No |
--status <status> |
Filter by status | No |
--json |
Output as JSON | No |
tailor tap lock / unlock
tailor tap lock abc123 --section sec_01 --ttl 60
tailor tap unlock abc123 --section sec_01| Flag | Description | Default |
|---|---|---|
--section <sectionId> |
Section to lock/unlock | Required |
--ttl <seconds> |
Lock time-to-live | 30 |
tailor tap intent
Declare what you want to achieve in a section — before writing any text:
tailor tap intent abc123 --section sec:liability --goal "Add currency risk language" --category compliance| Flag | Description | Required |
|---|---|---|
--section <sectionId> |
Target section | Yes |
--goal <text> |
What you want to achieve | Yes |
--category <category> |
e.g. compliance, clarity, structure |
No |
tailor tap intents
tailor tap intents abc123
tailor tap intents abc123 --section sec:liability --json| Flag | Description | Required |
|---|---|---|
--section <sectionId> |
Filter by section | No |
--json |
Output as JSON | No |
tailor tap constrain
Publish a boundary condition — what must or must not happen:
tailor tap constrain abc123 --section sec:liability --boundary "Liability cap must not exceed $2M" --category commercial| Flag | Description | Required |
|---|---|---|
--section <sectionId> |
Target section | Yes |
--boundary <text> |
Boundary condition | Yes |
--category <category> |
e.g. regulatory, commercial, technical |
No |
tailor tap constraints
tailor tap constraints abc123
tailor tap constraints abc123 --section sec:liability --json| Flag | Description | Required |
|---|---|---|
--section <sectionId> |
Filter by section | No |
--json |
Output as JSON | No |
tailor tap salience
Signal how much you care about a section (0 = don't care, 10 = critical):
tailor tap salience abc123 --section sec:liability --score 9| Flag | Description | Required |
|---|---|---|
--section <sectionId> |
Target section | Yes |
--score <0-10> |
Salience score | Yes |
tailor tap salience-map
View the salience heat map showing where agent attention is concentrated:
tailor tap salience-map abc123
tailor tap salience-map abc123 --json| Flag | Description | Required |
|---|---|---|
--json |
Output as JSON | No |
tailor tap object
Object to a proposal (objection-based merge — silence = consent):
tailor tap object abc123 --proposal prop_xyz --reason "Violates liability cap constraint"| Flag | Description | Required |
|---|---|---|
--proposal <proposalId> |
Proposal to object to | Yes |
--reason <text> |
Reason for objection | Yes |
Agent Workflow Example
# 1. Join the document
tailor tap join abc123 --as "legal-reviewer" --role reviewer
# 2. Read the document
tailor tap get abc123 > doc.md
# 3. View sections
tailor tap sections abc123
# 4. Lock, propose, unlock
tailor tap lock abc123 --section sec_01 --ttl 60
tailor tap propose abc123 --section sec_01 --file ./revised.md --summary "Compliance fix"
tailor tap unlock abc123 --section sec_01
# 5. Another agent approves
tailor tap approve abc123 prop_abc
# 6. Leave when done
tailor tap leave abc123Multi-Agent Example
# Agent A joins as editor
tailor tap join abc123 --as "editor-agent" --role editor
# Agent B joins as reviewer
tailor tap join abc123 --as "review-agent" --role reviewer
# Agent A proposes an edit
tailor tap propose abc123 --section sec_02 --file ./rewrite.md --summary "Rewrite methodology"
# Agent B reviews and approves
tailor tap proposals abc123 --section sec_02
tailor tap approve abc123 prop_xyz
# If stuck, escalate to human
tailor tap escalate abc123 --section sec_03 --message "Legal clause needs human review"Intent-Constraint-Salience (ICS) Example
Align before you write — critical when agents have confidential contexts:
# Agent A (legal): Declare intent — tells everyone WHAT, not WHY
tailor tap intent abc123 --section sec:liability \
--goal "Add currency risk allocation language" --category legal
# Agent B (commercial): Publish constraint — sets boundaries
tailor tap constrain abc123 --section sec:liability \
--boundary "Total liability must not exceed $2M AUD" --category commercial
# Agent C (compliance): Set salience — signal this section is critical
tailor tap salience abc123 --section sec:liability --score 10
# Agent A: Check constraints before writing
tailor tap constraints abc123 --section sec:liability
tailor tap salience-map abc123
# Agent A: Propose text satisfying all constraints
tailor tap propose abc123 --section sec:liability \
--file ./revised-liability.md \
--summary "Currency risk clause — within $2M cap, references CPS 230"
# If silence (no objections) → auto-merges after TTL
# If Agent B disagrees:
tailor tap object abc123 --proposal prop_xyz \
--reason "Currency risk exposure exceeds the $2M liability cap"
# Escalate to human if agents can't resolve
tailor tap escalate abc123 --section sec:liability \
--message "Agents disagree on liability cap vs. currency risk allocation"BYOK Invite Flow — Connect External Agents
PACT uses a BYOK (Bring Your Own Key) model. Document owners create scoped invite tokens for external AI agents. Agents join anonymously — no Tailor account needed.
# 1. Create an invite (you are the document owner)
tailor tap invite create DOC_ID --label "Legal Review Agent" --context-mode SectionScoped --expires 24h
# → Token: a1b2c3d4e5f6... (give this to the external agent)
# 2. External agent joins anonymously:
curl -X POST https://tailor.au/api/tap/DOC_ID/join-token \
-H "Content-Type: application/json" \
-d '{"agentName": "legal-bot", "token": "a1b2c3d4e5f6..."}'
# → { registrationId, apiKey: "tailor_sk_scoped_...", contextMode, allowedSections }
# 3. Agent uses the scoped key for all PACT operationsInvite options:
| Flag | Description | Default |
|---|---|---|
--label <name> |
Human-readable label | Required |
--context-mode <mode> |
Full, SectionScoped, Neighbourhood, SummaryOnly | Full |
--allowed-sections <ids> |
Comma-separated section IDs | All |
--max-agents <n> |
Max concurrent agents per invite | Unlimited |
--expires <duration> |
Expiry (e.g., 24h, 7d) | None |
--role <role> |
Pre-assigned role (editor, reviewer, observer) | None |
--webhook <url> |
POST callback when an agent joins | None |
MCP Server (stdio)
For MCP-compatible agents (Cursor, Claude Desktop, Windsurf):
{
"mcpServers": {
"tailor": {
"command": "npx",
"args": ["-y", "@tailor-app/cli", "mcp", "serve"],
"env": {
"TAILOR_API_KEY": "<scoped-key-from-join-token>",
"TAILOR_BASE_URL": "https://tailor.au"
}
}
}
}HTTP MCP Endpoint
For remote/cloud agents (Claude API, server-side agents):
- Endpoint:
https://tailor.au/mcp(streamable HTTP) - Discovery:
https://tailor.au/.well-known/mcp.json - Auth:
X-Api-Keyheader with scoped key fromjoin-token
OpenAI GPT Actions
Import the PACT-focused OpenAPI spec into a Custom GPT:
- GPT Builder > Configure > Actions > Import from URL
- Enter:
https://tailor.au/openapi/tap.json - Auth: API Key, header
X-Api-Key, value = scoped key fromjoin-token
Examples
LCC Quickstart: Upload 26 deliverables with shareable links
# Configure for production
tailor login --key tailor_sk_lcc_production_key
# Upload all DOCX files and generate public share links
tailor upload ./deliverables/*.docx --share --public
# Output:
# Uploading 26 file(s)...
#
# ✓ LCC-Policy-Report.docx → a1b2c3d4
# https://tailor.au/share/abc123...
# ✓ LCC-Budget-Analysis.docx → e5f6g7h8
# https://tailor.au/share/def456...
# ...
# ✓ 26/26 uploaded successfully
#
# Shareable Links:
# LCC-Policy-Report: https://tailor.au/share/abc123...
# LCC-Budget-Analysis: https://tailor.au/share/def456...Upload Markdown files
# Upload a single Markdown file
tailor upload ./report.md --share
# Upload all Markdown files in a directory
tailor upload ./docs/*.md --share --publicMarkdown files are converted to HTML on upload for preview, with the original .md preserved as the source of truth.
CI/CD Integration
# Set credentials via environment variables
export TAILOR_API_KEY=tailor_sk_ci_key
export TAILOR_BASE_URL=https://tailor.au
# Upload build artifacts
tailor upload ./output/*.docx --share --json > upload-results.jsonLocal Development
# Point to local API
tailor login --url http://localhost:7255 --key tailor_sk_dev_key
# Upload a test document
tailor upload ./test-fixtures/demo.docx
# List documents
tailor list --jsonShare with specific permissions
# Read-only share (default)
tailor share abc123
# Allow comments
tailor share abc123 --permission CommentOnly
# Full review access, no email verification
tailor share abc123 --permission FullReview --publicEnvironment Variables
| Variable | Description | Default |
|---|---|---|
TAILOR_API_KEY |
API key for authentication | — |
TAILOR_BASE_URL |
Base URL for the Tailor API | https://tailor.au |
Environment variables override stored configuration.
Config Storage
Configuration is stored locally using the conf package:
- Windows:
%APPDATA%/tailor-cli/config.json - macOS:
~/Library/Preferences/tailor-cli/config.json - Linux:
~/.config/tailor-cli/config.json
Run tailor login to see the exact path.
Troubleshooting
| Problem | Cause | Fix |
|---|---|---|
Not authenticated |
No API key configured | Run tailor login --key tailor_sk_... or set TAILOR_API_KEY env var |
HTTP 401: Unauthorized |
Session expired or invalid key | Re-authenticate: tailor login --email <email> or tailor login --key <key> |
HTTP 403: Forbidden |
Key lacks required scopes | Create a new key: tailor keys create --name "agent" --scopes "documents:read,documents:write" |
Could not connect to https://tailor.au |
Wrong URL or server unreachable | Check URL: tailor login --url <url>. For local dev: http://localhost:7255 |
Server returned HTML |
Base URL points to web app, not API | Verify TAILOR_BASE_URL doesn't include a path (should be just https://tailor.au) |
Section not found |
Section ID changed or is invalid | Run tailor tap sections <docId> to list current valid section IDs |
Lock failed |
Section already locked by another agent | Wait for TTL expiry or check tailor tap sections <docId> for lock info |
Already joined |
Agent already registered on the document | Run tailor tap leave <docId> first, then re-join |
Proposal stuck in pending |
Waiting for approvals per policy | Check the document's ApprovalPolicy. Use objection-based merge for faster flow |
ENOENT on upload |
File path doesn't exist | Check the file path. Use quotes around paths with spaces |
| Commands not found after update | Old version cached | Run npm cache clean --force && npm install -g @tailor-app/cli |
For more detailed debugging, see the PACT Getting Started Guide.
Requirements
- Node.js >= 20.0.0
- A Tailor account with an API key
Tech Stack
- Commander.js — CLI framework
- chalk — Terminal colors
- ora — Terminal spinners
- conf — Persistent config
- glob — File pattern matching