@scribed/cli 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -25,6 +25,22 @@ bun link # registers the Node `scribed` bin
25
25
 
26
26
  The npm bin is a thin Node wrapper over the bundled `dist/index.js`. See `PUBLISHING.md` for the release checklist.
27
27
 
28
+ ### Install Scribed desktop apps
29
+
30
+ ```bash
31
+ scribed apps list --json
32
+ scribed apps download talk # verified download only
33
+ scribed apps install chat --yes # install a new app into ~/Applications
34
+ scribed apps install tel --yes
35
+ scribed apps download chat --directory ./downloads
36
+ ```
37
+
38
+ These local commands need no Scribed login. They read the official Talk, Chat and Tel release feeds, check this computer's hardware and operating system, and offer only published installers. Talk requires Apple silicon and macOS 14 or later; Chat and Tel support Apple silicon or Intel Macs on macOS 14 or later, and Windows x64 when its installer is published. A release can raise its minimum OS version. Linux and Windows ARM are unsupported. Rosetta on an Apple silicon Mac selects the native ARM build. Optional local AI model requirements do not block installing Chat or Tel.
39
+
40
+ Downloads use a new private folder, verify the published SHA256 and exact HTTP download size, and never open an installer. Mac installs additionally verify Scribed's signing identity, Gatekeeper acceptance, bundle identity, version and architecture, then verify the staged copy before moving it into `~/Applications`. Existing apps, including registered renamed or moved apps, are preserved; use their update flow. Apps and their data are never removed or replaced. No administrator password, Gatekeeper bypass, or automatic app launch is used.
41
+
42
+ On Windows, the CLI verifies Authenticode trust and reports the signer before opening the published native installer. `installer-opened` means installation is still pending in that window. JSON reports `downloaded`, `installed`, `already-installed`, or `installer-opened`; list results distinguish `available`, `unsupported`, and `unavailable` release metadata. App sign-in, billing and microphone/Accessibility permissions remain separate and are completed in the app. These operating-system commands are not hosted API or MCP tools.
43
+
28
44
  ## Login
29
45
 
30
46
  Three credential modes; exactly one is stored at a time.
@@ -163,9 +179,9 @@ scribed logout # revoke the session + clear the stored c
163
179
  scribed config # config path + effective settings
164
180
 
165
181
  # The full catalog (docs + execution):
166
- scribed tools list [--category core|all|<slugs>] # discover tools (name, category, scope)
167
- scribed tools categories # category slugs + core/opt-in
168
- scribed tools show <name> # description + JSON schema
182
+ scribed tools list [--category core|all|<slugs>] [--search <text>] [--offline]
183
+ scribed tools categories [--offline] # available category slugs + core/opt-in
184
+ scribed tools show <name> [--offline] # description + JSON schema
169
185
  scribed call <name> [key=value ...] [--args '<json>' | --input arguments.json]
170
186
  scribed call studio_upload --file file=./photo.png
171
187
  scribed call document_content_save --input revision.json
@@ -205,6 +221,10 @@ scribed --upload-api-url https://scribed-api.fly.dev call transcription_upload -
205
221
  # This sends your credential AND file to that host; use only your trusted Scribed API.
206
222
  # Default uploads stay on your credential's origin. Streaming has a 15-minute deadline
207
223
  # and never retries automatically: check transcriptions_list after an uncertain failure.
224
+ # API-key and browser OAuth writes accept a stable gateway operation key:
225
+ scribed call transcription_upload --file file=./recording.mp4 --idempotency-key interview-2026-10-09
226
+ # Raw gateway uploads carry a SHA-256 digest measured from the selected file.
227
+ # The server verifies those bytes before execution; retain the same file and key.
208
228
 
209
229
  # Vault --file uses the browser's direct private-storage lifecycle for every size,
210
230
  # including empty files. Only a scoped one-object grant reaches the storage SDK;
@@ -269,7 +289,7 @@ scribed leads import leads.csv [--map …] [--set …] [--ai] [--dry-run] | lead
269
289
  # Industry packs:
270
290
  scribed packs list # pack_list (installed state + page refs)
271
291
  scribed packs install investors [--pages dashboard.metrics] --yes # pack_install (admin / owner; --pages = a scoped install)
272
- scribed packs uninstall sales --yes # pack_uninstall (archives the pack's pages + collections; records stay)
292
+ # (a pack is copy-on-create and owns nothing after install — there is no uninstall; delete its pages / collections directly)
273
293
 
274
294
  scribed vault list # vault_list
275
295
  scribed vault read "Proposals/acme.pdf" # vault_read (PDF/DOCX extracted)
@@ -372,7 +392,7 @@ scribed credentials versions <itemId> # credentials_it
372
392
  scribed credentials events <vaultId> [--limit 30] [--cursor …] # credentials_events_list — who created, changed, revealed, restored or deleted what, who read codes
373
393
  scribed call credentials_vault_create name="Production keys" visibility=restricted # the writes are plain `scribed call`s: credentials_vault_create / _update / _share / _unshare, credentials_item_create / _update / _delete / _version_restore
374
394
  scribed call credentials_item_version_reveal itemId=… versionId=… confirmed=true # an earlier version's value (logged with the version number)
375
- # `scribed mcp` and the hosted MCP's default `core` set carry every credentials_* tool EXCEPT the three that decrypt (reveal, version reveal, totp) — opt in with `--categories credentials-reveal` / `?categories=credentials-reveal`; `scribed call credentials_item_reveal itemId=… confirmed=true` and a write-scoped API key always reach them (and /v1 never replays their answers from its idempotency cache).
395
+ # `scribed mcp` and the hosted MCP's default `core` set carry every credentials_* tool EXCEPT the three that decrypt (reveal, version reveal, totp) — opt in with `--categories credentials-reveal` / `?categories=credentials-reveal`; `scribed call credentials_item_reveal itemId=… confirmed=true` and an API key with write scope and explicit tool access can reach them (and /v1 never replays their answers from stored execution receipts).
376
396
 
377
397
  # SAFEs (YC post-money SAFEs for e-signature; safe_* tools):
378
398
  scribed safes forms | safes settings [--input settings.json --yes] # safe_forms_list / safe_settings_get (wire instructions redacted) / safe_settings_update
@@ -443,7 +463,7 @@ scribed mcp --categories hr,automations,objects-crm-records
443
463
  scribed --workspace <id> mcp # pin every call to one workspace
444
464
  ```
445
465
 
446
- Auth comes from the config file or `SCRIBED_TOKEN` / `SCRIBED_API_KEY`. Browser-OAuth sessions proxy catalog execution through the hosted MCP; session tokens call the API directly; API keys go through `/v1/tools`. The default `core` selection is the daily-operations set — records, the workspace roster, the leaderboard, phone + texting, inbox, calendar + booking, transcriptions, HR, Payroll, Agent chats, Vault + pages + drive, forms, bulletins, SAFEs, credentials (the vault metadata and writes — never a value), jobs, notifications, automations, and profile & account; the rest is opt-in via `--categories`: the bulk-outreach suites (power dial, power-text campaigns, sequences, scheduled emails, email templates), phone metrics, workspace admin, billing, social accounts, Creative Studio, Documents, and `credentials-reveal` (audited secret reads) (`scribed tools categories` prints every slug and whether it is core). The policy lives in `scribed-agent/src/tool-catalog.ts` (`defaultMcp`). Tool annotations (read-only / destructive) are derived from the registry's HTTP method and read-only flag.
466
+ Auth comes from the config file or `SCRIBED_TOKEN` / `SCRIBED_API_KEY`. When using an API key, the local MCP server advertises only the intersection of its selected categories and the key’s permitted tools; restart it after changing those permissions. Every call is authorized again by the API. Browser-OAuth sessions proxy catalog execution through the hosted MCP; session tokens call the API directly; API keys go through `/v1/tools`. The default `core` selection is the daily-operations set — records, the workspace roster, the leaderboard, phone + texting, inbox, calendar + booking, transcriptions, HR, Payroll, Agent chats, Vault + pages + drive, forms, bulletins, SAFEs, credentials (the vault metadata and writes — never a value), jobs, notifications, automations, and profile & account; the rest is opt-in via `--categories`: the bulk-outreach suites (power dial, power-text campaigns, sequences, scheduled emails, email templates), phone metrics, workspace admin, billing, social accounts, Creative Studio, Documents, and `credentials-reveal` (audited secret reads) (`scribed tools categories` prints every slug and whether it is core). The policy lives in `scribed-agent/src/tool-catalog.ts` (`defaultMcp`). Tool annotations (read-only / destructive) are derived from the registry's HTTP method and read-only flag.
447
467
 
448
468
  Setup helpers print configuration by default and never silently edit another application:
449
469
 
@@ -481,23 +501,65 @@ The hosted adapter signs each catalog-derived loopback request with a short-live
481
501
 
482
502
  ## Personal-key HTTP API
483
503
 
484
- Backend scripts that do not need the CLI or MCP can create a read-only or read/write key in **Settings → API keys** and call the same catalog at `https://app.scribed.ai/v1/tools`. Discovery, JSON schemas, validation, execution, and HMAC provenance reuse this package's catalog adapter; there is no parallel REST contract, and personal keys cannot authenticate private `/api/*` routes.
504
+ An API key belongs to **your Scribed account** and lets a script or unattended integration act as you through the shared tool API. Browser sign-in with `scribed login` and the hosted MCP connection do not need one. An API key is optional for the CLI and local `scribed mcp`; hosted `/mcp` uses OAuth. Create and manage keys in **Settings → Account → API keys**.
505
+
506
+ Choose a name, expiry, read-only or read/write access, and the exact tools the integration needs. Selected tools stay fixed when new tools are released. “All tools” includes future tools within the key's read/write scope; existing keys keep that behavior until edited. Read/write permission alone never overrides a tool restriction, your current account access, workspace membership, role, seat or billing rules. A workspace restriction limits workspace operations to one workspace you belong to; the key is still account-owned and permitted account tools still act on your personal account. To exclude those tools, leave them out of the tool selection.
507
+
508
+ Store the secret in your deployment's secret manager as `SCRIBED_API_KEY`. Start with the **Account basics** preset or explicitly allow `workspaces_list` for this read-only connection check:
485
509
 
486
510
  ```bash
487
511
  curl https://app.scribed.ai/v1/tools \
488
512
  -H "Authorization: Bearer $SCRIBED_API_KEY"
489
513
 
490
- curl https://app.scribed.ai/v1/tools/objects_records_list \
491
- -H "Authorization: Bearer $SCRIBED_API_KEY" # description + JSON input schema
492
-
493
- curl -X POST https://app.scribed.ai/v1/tools/objects_records_list \
514
+ curl -X POST https://app.scribed.ai/v1/tools/workspaces_list \
494
515
  -H "Authorization: Bearer $SCRIBED_API_KEY" \
495
516
  -H "Content-Type: application/json" \
496
- -H "X-Workspace-Id: <workspace uuid>" \
497
- --data '{"pack":"sales","key":"contacts"}'
517
+ --data '{}'
518
+
519
+ # Find permitted tools, then read the exact input schema before calling one.
520
+ curl 'https://app.scribed.ai/v1/tools?q=records' \
521
+ -H "Authorization: Bearer $SCRIBED_API_KEY"
522
+
523
+ curl https://app.scribed.ai/v1/tools/objects_records_list \
524
+ -H "Authorization: Bearer $SCRIBED_API_KEY"
498
525
  ```
499
526
 
500
- Contract: the body is the tool's arguments object (validated against the same schema `scribed tools show` prints); success is `200 { tool, result, requestId }`; failures are `{ error: { code, message }, requestId }` (plus `toolStatus` when the upstream tool failed) with codes such as `invalid_api_key` (401), `insufficient_scope` (403), `tool_not_found` (404), `invalid_arguments` (400), `invalid_json` (400), `idempotency_key_required` (400), `idempotency_conflict` (409), `request_too_large` (413 — bodies are capped at 64 MiB, with smaller per-tool decoded file limits), `rate_limit_exceeded` (429 — 120 requests per minute per key), `tool_request_failed` (the upstream tool's own 4xx / 503, sanitized), and `tool_execution_failed` (502). Every response carries `X-Request-Id`. Write tools additionally require an `Idempotency-Key` header (8–200 printable characters; the CLI sends a random UUID) — a replay with the same arguments returns the recorded response with `Idempotency-Replayed: true`. A read-only key sees and may call only read tools. `X-Workspace-Id` scopes workspace-bound tools (400 `invalid_workspace_id` unless a UUID); a key pinned to a workspace always acts there and refuses a different header with 403 `api_key_workspace_mismatch`.
527
+ The catalog lists only tools allowed by the key and accepts `q` and `category` filters (category display name or slug). A schema lookup for an excluded tool returns `404`; an attempted call returns `403 api_key_tool_not_allowed`. For workspace tools, pass `X-Workspace-Id: <workspace UUID>` or set `--workspace` in the CLI. A key's workspace restriction cannot be overridden by a header or tool argument. Account tools do not need a workspace. Keys cannot authenticate private `/api/*` routes.
528
+
529
+ With an API key selected, `scribed tools list`, `categories`, and `show` use authenticated discovery from the API. `--offline` explicitly shows the bundled reference catalog, which does not establish your permissions. Invalid keys and network failures do not silently fall back to a broader catalog. If a tool is newer than your installed CLI, update the CLI before calling it. Some shortcuts use several tools: direct Vault file uploads need `vault_upload_start`, `vault_upload_complete` and `vault_upload_cancel`, not just `vault_upload`.
530
+
531
+ You can edit a key's name, tool selection, read/write access and expiry without replacing its secret. Replacement offers immediate revocation, a one-hour overlap, or a 24-hour overlap; an existing expiry can shorten that window. Only create and replace reveal the secret, once. Revoke immediately if a key is compromised. Recent write activity shows tool names, request IDs, times and outcomes across replacements; it excludes request/response contents, read calls and secret-reveal calls. It is a troubleshooting view of durable write receipts, not a complete audit of every request.
532
+
533
+ The POST body is the tool's arguments object, validated against its schema.
534
+ First execution returns `200 { tool, result, requestId }`; failures return
535
+ `{ error: { code, message }, requestId }`, with `toolCode`, `toolStatus`,
536
+ `retryAfterSeconds` and a non-content execution receipt when available. Each
537
+ response carries `X-Request-Id`.
538
+
539
+ Writes require `Idempotency-Key` (8–200 non-space ASCII characters).
540
+ `scribed call --idempotency-key <key>` supplies it; when omitted, the adapter
541
+ generates one UUID for that invocation and exposes it if the outcome is
542
+ uncertain. Browser OAuth carries the same identity in MCP request metadata
543
+ `_meta['scribed/idempotencyKey']`. Local stdio MCP accepts that metadata too.
544
+ Third-party MCP hosts must retain that metadata key across transport retries.
545
+ Unkeyed calls receive a new identity each time; the gateway cannot recognize
546
+ two separately submitted unkeyed calls as the same operation.
547
+ Retain the same `Idempotency-Key`, arguments and selected file when checking an uncertain
548
+ operation; replacements made with the new rotation flow retain the same duplicate-write identity
549
+ (older, already-replaced keys are not retroactively combined); the CLI never automatically retries a write. Direct session calls
550
+ and direct-provider Vault transfers use their tool-specific idempotency
551
+ arguments and reject this transport flag.
552
+
553
+ Repeated writes return receipt state `running`, `completed`, `failed`, `unknown`
554
+ or `retryable`, plus the original request ID and timestamps. A completed replay
555
+ returns `{ receipt, message }` with `resultAvailable:false`; it does not replay
556
+ the original result or bypass current authorization. Inspect current state
557
+ with the appropriate read tool. An unknown or failed receipt does not authorize
558
+ a second operation with a fresh key. A server-confirmed retryable outcome may
559
+ be retried with the same key after its stated cooldown. Raw `/v1/uploads`
560
+ additionally requires `X-Scribed-Content-SHA256`; CLI `--file` measures the
561
+ selected file through the same handle it streams. The API checks bytes while
562
+ streaming and withholds the final chunk until the length and digest match.
501
563
 
502
564
  ## Development
503
565
 
@@ -511,8 +573,8 @@ Contract: the body is the tool's arguments object (validated against the same sc
511
573
  - From the monorepo root, `bun run verify:parity` builds the CLI adapter and runs both catalog checks. The Agent and CLI parity pull-request workflow runs this check, packaged Node MCP discovery, agent/CLI tests and companion API permission/transport tests without production credentials. These checks prove local contract conformance; provider configuration, delivery and device behavior still require an authenticated environment-specific smoke run.
512
574
  - CI separately runs the six embedded PostgreSQL suites for Drive/publication constraints, workspace/reminder visibility, document receipt transactions and notifications. It installs exactly `@electric-sql/pglite@0.5.8` in a temporary project with lifecycle scripts disabled and sets all three runtime-path variables so those checks cannot silently skip. Product dependencies and lockfiles are unchanged; no live database is used.
513
575
  - `bun run smoke` — LIVE tool matrix against a running scribed-api (`scripts/smoke-tools.ts`): env `SCRIBED_API_URL` (default `http://localhost:8081`), `SCRIBED_TOKEN` (a bearer session token), `SCRIBED_WORKSPACE_ID` (default: the first workspace); flags `--only <substring>`, `--json <file>`. Runs every read tool plus a create → read → update → delete lifecycle per domain on rows it created; exits 1 on any failed row. It never sends an SMS or email, enrolls, starts a campaign / sequence / dial session, or invites a real address — it does schedule-and-cancel one text to a fictional 555-01xx number and makes one small AI-draft call.
514
- - `npm pack --dry-run --ignore-scripts` — inspect the publish tarball
515
- - The catalog source of truth is `scribed-agent/src/tools.ts`, `tool-catalog.ts`, and `tool-metering.ts`; this package deliberately contains no route/schema definitions of its own. Use `scribed tools categories` for current counts; every new registry tool appears automatically on the CLI, MCP and API-key surfaces.
576
+ - From the monorepo root, `bun run ci:cli` runs the fleet's CLI release checks. The main-branch release workflow waits for matching production deployments, builds a versioned tarball, verifies it under Node 20, and publishes through npm's short-lived GitHub identity exchange. See [PUBLISHING.md](PUBLISHING.md) for setup, packed export normalization and retries.
577
+ - The catalog source of truth is `scribed-agent/src/tools.ts`, `tool-catalog.ts`, and `tool-metering.ts`; this package deliberately contains no route/schema definitions of its own. Use `scribed tools categories` for current counts; every new registry tool is available to the CLI, MCP and API-key surfaces, subject to each credential’s permissions and category selection.
516
578
 
517
579
  ### Read-only companion smoke
518
580