papiers 0.1.7 → 0.1.8

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
@@ -5,7 +5,9 @@ Search and read your Papiers library from the terminal.
5
5
  The CLI can inspect your saved documents, highlights, notes, and
6
6
  conversations. It changes your library only to import a public PDF or webpage
7
7
  (`papiers import --help`) or highlight a passage in a saved PDF or webpage
8
- (`papiers highlight --help`), and only with a token that allows it.
8
+ (`papiers highlight --help`), and only with a token that allows it. With a
9
+ token that allows it, an agent can also add links to your own Discover feed
10
+ (`papiers feed --help`).
9
11
 
10
12
  ## Install
11
13
 
package/dist/index.js CHANGED
@@ -413,6 +413,120 @@ function isNodeError(error) {
413
413
  return Boolean(error && typeof error === "object" && "code" in error);
414
414
  }
415
415
 
416
+ // src/contracts.ts
417
+ var PAPIERS_SCHEMA_VERSIONS = {
418
+ searchRequest: "papiers.search.request.v1",
419
+ search: "papiers.search.v1",
420
+ searchResultsRequest: "papiers.search.results.request.v1",
421
+ listRequest: "papiers.list.request.v1",
422
+ list: "papiers.list.v1",
423
+ readRequest: "papiers.read.request.v1",
424
+ read: "papiers.read.v1",
425
+ capabilities: "papiers.capabilities.v1",
426
+ importRequest: "papiers.import.request.v1",
427
+ import: "papiers.import.v1",
428
+ highlightRequest: "papiers.highlight.request.v1",
429
+ highlight: "papiers.highlight.v1",
430
+ feedLinkRequest: "papiers.discover.feed.link.request.v1",
431
+ feedLink: "papiers.discover.feed.link.v1",
432
+ error: "papiers.error.v1"
433
+ };
434
+ var PAPIERS_PUBLIC_DATA_PLANE_SCOPES = [
435
+ "library:metadata:read",
436
+ "library:search",
437
+ "content:search",
438
+ "content:snippet:read",
439
+ "content:read",
440
+ "content:structure:read"
441
+ ];
442
+ var PAPIERS_PUBLIC_FEATURE_IDS = [
443
+ "document_content_read",
444
+ "non_document_kinds",
445
+ "content_search",
446
+ "list_cursors",
447
+ "read_cursors",
448
+ "read_section_scopes",
449
+ "read_context",
450
+ "read_locations",
451
+ "ranked_search_cursors",
452
+ "search_results_browse",
453
+ "public_id_projection_not_ready",
454
+ "queryIn:content",
455
+ "queryIn:all",
456
+ "queryIn:latex"
457
+ ];
458
+ var PAPIERS_SEARCH_QUALITY_SIGNALS = [
459
+ "high",
460
+ "medium",
461
+ "low",
462
+ "empty"
463
+ ];
464
+ var PAPIERS_SEARCH_RESULT_KINDS = [
465
+ "document",
466
+ "conversation",
467
+ "note"
468
+ ];
469
+ var PAPIERS_SEARCH_EVIDENCE_KINDS = [
470
+ "passage",
471
+ "highlight",
472
+ "equation"
473
+ ];
474
+ var PAPIERS_SEARCH_MATCH_REASONS = [
475
+ "title",
476
+ "doi",
477
+ "arxivId",
478
+ "pmid",
479
+ "passage",
480
+ "highlight",
481
+ "equation",
482
+ "conversation",
483
+ "note"
484
+ ];
485
+ var PAPIERS_PUBLIC_NOT_READY_REASONS_BY_FEATURE = {
486
+ document_content_read: ["explicit_enablement_required"],
487
+ non_document_kinds: ["public_id_projection_not_ready"],
488
+ content_search: ["content_search_not_ready"],
489
+ list_cursors: ["cursor_signing_not_configured"],
490
+ read_cursors: [
491
+ "cursor_signing_not_configured",
492
+ "document_content_read_required"
493
+ ],
494
+ read_section_scopes: ["section_scoped_read_not_ready"],
495
+ read_context: ["read_context_not_ready"],
496
+ ranked_search_cursors: ["search_sessions_not_ready"],
497
+ search_results_browse: [
498
+ "content_search_not_ready",
499
+ "search_sessions_not_ready"
500
+ ]
501
+ };
502
+ var PAPIERS_PUBLIC_ERROR_CODES = [
503
+ "api_disabled",
504
+ "auth_missing",
505
+ "auth_invalid_format",
506
+ "auth_invalid",
507
+ "auth_wrong_surface",
508
+ "auth_scope_missing",
509
+ "feature_not_available",
510
+ "filter_not_supported",
511
+ "invalid_filter_field",
512
+ "invalid_filter_operator",
513
+ "invalid_filter_value",
514
+ "invalid_filter_combination",
515
+ "order_not_supported",
516
+ "unsupported_format",
517
+ "invalid_cursor",
518
+ "invalid_cursor_context",
519
+ "forbidden",
520
+ "invalid_request",
521
+ "not_found",
522
+ "source_superseded",
523
+ "stale_reference",
524
+ "content_limit_exceeded",
525
+ "request_limit_exceeded",
526
+ "rate_limited",
527
+ "internal_error"
528
+ ];
529
+
416
530
  // ../../src/shared/papiers-public-ids.ts
417
531
  var PAPIERS_PUBLIC_ID_PREFIX_BY_KIND = {
418
532
  document: "doc",
@@ -621,118 +735,6 @@ function isPublicIdForKind(value, kind) {
621
735
  return publicReadKindForId(value) === kind;
622
736
  }
623
737
 
624
- // src/contracts.ts
625
- var PAPIERS_SCHEMA_VERSIONS = {
626
- searchRequest: "papiers.search.request.v1",
627
- search: "papiers.search.v1",
628
- searchResultsRequest: "papiers.search.results.request.v1",
629
- listRequest: "papiers.list.request.v1",
630
- list: "papiers.list.v1",
631
- readRequest: "papiers.read.request.v1",
632
- read: "papiers.read.v1",
633
- capabilities: "papiers.capabilities.v1",
634
- importRequest: "papiers.import.request.v1",
635
- import: "papiers.import.v1",
636
- highlightRequest: "papiers.highlight.request.v1",
637
- highlight: "papiers.highlight.v1",
638
- error: "papiers.error.v1"
639
- };
640
- var PAPIERS_PUBLIC_DATA_PLANE_SCOPES = [
641
- "library:metadata:read",
642
- "library:search",
643
- "content:search",
644
- "content:snippet:read",
645
- "content:read",
646
- "content:structure:read"
647
- ];
648
- var PAPIERS_PUBLIC_FEATURE_IDS = [
649
- "document_content_read",
650
- "non_document_kinds",
651
- "content_search",
652
- "list_cursors",
653
- "read_cursors",
654
- "read_section_scopes",
655
- "read_context",
656
- "read_locations",
657
- "ranked_search_cursors",
658
- "search_results_browse",
659
- "public_id_projection_not_ready",
660
- "queryIn:content",
661
- "queryIn:all",
662
- "queryIn:latex"
663
- ];
664
- var PAPIERS_SEARCH_QUALITY_SIGNALS = [
665
- "high",
666
- "medium",
667
- "low",
668
- "empty"
669
- ];
670
- var PAPIERS_SEARCH_RESULT_KINDS = [
671
- "document",
672
- "conversation",
673
- "note"
674
- ];
675
- var PAPIERS_SEARCH_EVIDENCE_KINDS = [
676
- "passage",
677
- "highlight",
678
- "equation"
679
- ];
680
- var PAPIERS_SEARCH_MATCH_REASONS = [
681
- "title",
682
- "doi",
683
- "arxivId",
684
- "pmid",
685
- "passage",
686
- "highlight",
687
- "equation",
688
- "conversation",
689
- "note"
690
- ];
691
- var PAPIERS_PUBLIC_NOT_READY_REASONS_BY_FEATURE = {
692
- document_content_read: ["explicit_enablement_required"],
693
- non_document_kinds: ["public_id_projection_not_ready"],
694
- content_search: ["content_search_not_ready"],
695
- list_cursors: ["cursor_signing_not_configured"],
696
- read_cursors: [
697
- "cursor_signing_not_configured",
698
- "document_content_read_required"
699
- ],
700
- read_section_scopes: ["section_scoped_read_not_ready"],
701
- read_context: ["read_context_not_ready"],
702
- ranked_search_cursors: ["search_sessions_not_ready"],
703
- search_results_browse: [
704
- "content_search_not_ready",
705
- "search_sessions_not_ready"
706
- ]
707
- };
708
- var PAPIERS_PUBLIC_ERROR_CODES = [
709
- "api_disabled",
710
- "auth_missing",
711
- "auth_invalid_format",
712
- "auth_invalid",
713
- "auth_wrong_surface",
714
- "auth_scope_missing",
715
- "feature_not_available",
716
- "filter_not_supported",
717
- "invalid_filter_field",
718
- "invalid_filter_operator",
719
- "invalid_filter_value",
720
- "invalid_filter_combination",
721
- "order_not_supported",
722
- "unsupported_format",
723
- "invalid_cursor",
724
- "invalid_cursor_context",
725
- "forbidden",
726
- "invalid_request",
727
- "not_found",
728
- "source_superseded",
729
- "stale_reference",
730
- "content_limit_exceeded",
731
- "request_limit_exceeded",
732
- "rate_limited",
733
- "internal_error"
734
- ];
735
-
736
738
  // ../../src/shared/papiers-public-source-domain.ts
737
739
  var papiers_public_source_domain_exports = {};
738
740
  __export(papiers_public_source_domain_exports, {
@@ -3170,6 +3172,16 @@ async function highlightDocument(config, fetchImpl, request) {
3170
3172
  assertPapiersHighlightResponse("highlight", body);
3171
3173
  return body;
3172
3174
  }
3175
+ var FEED_PATH = "/api/v1/papiers/discover/feed";
3176
+ function addFeedLink(config, fetchImpl, link) {
3177
+ return requestPapiersApi(config, fetchImpl, FEED_PATH, {
3178
+ method: "POST",
3179
+ body: {
3180
+ schemaVersion: PAPIERS_SCHEMA_VERSIONS.feedLinkRequest,
3181
+ ...link
3182
+ }
3183
+ });
3184
+ }
3173
3185
  async function requestPapiersApi(config, fetchImpl, path, init) {
3174
3186
  if (!config.token) {
3175
3187
  throw new CliUsageError(
@@ -3292,10 +3304,14 @@ var PAPIERS_PUBLIC_DATA_PLANE_SCOPES2 = [
3292
3304
  "content:read",
3293
3305
  "content:structure:read"
3294
3306
  ];
3307
+ var PAPIERS_WRITE_SCOPES = [
3308
+ "library:import",
3309
+ "library:highlight",
3310
+ "discover:feed"
3311
+ ];
3295
3312
  var PAPIERS_PUBLIC_SCOPES = [
3296
3313
  ...PAPIERS_PUBLIC_DATA_PLANE_SCOPES2,
3297
- "library:import",
3298
- "library:highlight"
3314
+ ...PAPIERS_WRITE_SCOPES
3299
3315
  ];
3300
3316
  var PAPIERS_HIGHLIGHT_MAX_SCOPE_PAGES = 20;
3301
3317
  var PAPIERS_HIGHLIGHT_MAX_PAGE = 1e4;
@@ -3778,6 +3794,7 @@ var HIGHLIGHT_VALUE_FLAGS = [
3778
3794
  ];
3779
3795
  var VALUE_FLAGS = /* @__PURE__ */ new Set([
3780
3796
  ...HIGHLIGHT_VALUE_FLAGS,
3797
+ "reason",
3781
3798
  "api-url",
3782
3799
  "cursor",
3783
3800
  "document-id",
@@ -3897,6 +3914,7 @@ COMMANDS
3897
3914
  browse Page through an earlier search's results
3898
3915
  import Add a public PDF or webpage to your library
3899
3916
  highlight Highlight a passage in a saved document
3917
+ feed Add links to your Discover feed
3900
3918
  auth Sign in, check status, or sign out
3901
3919
  doctor Check your setup, connection, and what's available
3902
3920
  version Print the CLI version
@@ -3960,7 +3978,7 @@ OPTIONS
3960
3978
  e.g. --filter lastEngagedAt.gte=30d --filter annotated=true. Fields/ops: help --all.
3961
3979
  --order-by KEY addedAt:desc (default) or lastEngagedAt:desc. document kind only.
3962
3980
  --document-id ID scope to documents: doc_\u2026 (comma-separated or repeated), or @-/@file.
3963
- document and highlight only.
3981
+ document and highlight only; highlight also takes papiers://item/\u2026 locators.
3964
3982
  --since WHEN only items at or after an ISO 8601 time, or an Nd shorthand (e.g. 30d).
3965
3983
  highlight and conversation only.
3966
3984
  --limit N max results, 1\u201350.
@@ -4040,6 +4058,20 @@ check import-status until it is ready or failed; any other status means it
4040
4058
  is still in progress. Ready means papiers read works on its documentId now.
4041
4059
  A status is as of that check: reprocessing or trashing the document can
4042
4060
  change it later.`,
4061
+ feed: `papiers feed \u2014 add links to your own Discover feed.
4062
+
4063
+ USAGE
4064
+ papiers feed add URL [--reason TEXT] [--json]
4065
+
4066
+ Needs a token created with "Allow adding to your Discover feed" (Settings ->
4067
+ API tokens). A link shows in the user's Discover feed, labeled with the
4068
+ token's name and your reason, once Papiers has prepared it (usually within
4069
+ minutes); it never adds to their library. Give a short reason in your own
4070
+ words: why this user would want it. Sending a link again updates its reason.
4071
+ Links must be public pages: not paywalled, with no sign-in or private token.
4072
+ The user's plan sets how many new links it takes; past that, the answer says
4073
+ when to try again. The answer says whether the link is preparing, ready or
4074
+ failed; send it again to see how it is now.`,
4043
4075
  highlight: `papiers highlight \u2014 highlight a passage in a saved PDF or webpage.
4044
4076
 
4045
4077
  USAGE
@@ -4244,6 +4276,8 @@ function parseCliArgs(argv) {
4244
4276
  }
4245
4277
  return command === "import" ? { type: "import", ...global, url: target } : { type: "import-status", ...global, operationId: target };
4246
4278
  }
4279
+ case "feed":
4280
+ return parseFeedCommand(rest, parsed, global);
4247
4281
  case "highlight": {
4248
4282
  assertAllowedFlags(
4249
4283
  parsed,
@@ -4290,7 +4324,11 @@ function parseCliArgs(argv) {
4290
4324
  assertAllowedFlags(parsed, LIST_VALUE_FLAGS, "list");
4291
4325
  assertAllowedBooleanFlags(parsed, IDS_PIPELINE_BOOLEAN_FLAGS, "list");
4292
4326
  assertNoExtraPositionals(command, rest);
4293
- const listDocumentIds = parseDocumentIdFlagValues(parsed, "list");
4327
+ const listDocumentIds = parseDocumentIdFlagValues(
4328
+ parsed,
4329
+ "list",
4330
+ parseListKind(parsed) === "highlight"
4331
+ );
4294
4332
  const listOutput = parseIdsOutput(parsed, "list");
4295
4333
  return {
4296
4334
  type: "list",
@@ -4384,6 +4422,33 @@ function parsePrettyOutput(parsed, idsOnly) {
4384
4422
  }
4385
4423
  return true;
4386
4424
  }
4425
+ function parseFeedCommand(rest, parsed, global) {
4426
+ const [subcommand, target, ...extra] = rest;
4427
+ const name = `feed ${subcommand ?? ""}`.trim();
4428
+ assertAllowedBooleanFlags(parsed, NO_COMMAND_BOOLEAN_FLAGS, name);
4429
+ switch (subcommand) {
4430
+ case "add": {
4431
+ assertAllowedFlags(
4432
+ parsed,
4433
+ /* @__PURE__ */ new Set([...GLOBAL_VALUE_FLAGS, "reason"]),
4434
+ name
4435
+ );
4436
+ assertNoExtraPositionals(name, extra);
4437
+ if (!target) throw new CliUsageError("papiers feed add requires a URL.");
4438
+ const reason = singleFlagValue(parsed, "reason");
4439
+ return {
4440
+ type: "feed-add",
4441
+ ...global,
4442
+ url: target,
4443
+ ...reason !== void 0 ? { reason } : {}
4444
+ };
4445
+ }
4446
+ default:
4447
+ throw new CliUsageError(
4448
+ "papiers feed takes add. Run papiers feed --help."
4449
+ );
4450
+ }
4451
+ }
4387
4452
  function parseAuthCommand(rest, parsed, global) {
4388
4453
  const [subcommand, ...extra] = rest;
4389
4454
  switch (subcommand) {
@@ -4624,7 +4689,7 @@ function parseSinceFlag(parsed, kind, command) {
4624
4689
  }
4625
4690
  return new Date(parsedMs).toISOString();
4626
4691
  }
4627
- function parseDocumentIdFlagValues(parsed, command) {
4692
+ function parseDocumentIdFlagValues(parsed, command, acceptsItemLocators = false) {
4628
4693
  const rawDocumentIds = parsed.flags.get("document-id");
4629
4694
  if (!rawDocumentIds?.length) {
4630
4695
  return void 0;
@@ -4642,9 +4707,10 @@ function parseDocumentIdFlagValues(parsed, command) {
4642
4707
  `papiers ${command} --document-id file references must include a file path after @.`
4643
4708
  );
4644
4709
  }
4645
- if (documentIds.some((id) => !isDocumentIdSource(id) && !isDocumentPublicId(id))) {
4710
+ const isDocumentId = acceptsItemLocators ? isDocumentReadIdentifier : isDocumentPublicId;
4711
+ if (documentIds.some((id) => !isDocumentIdSource(id) && !isDocumentId(id))) {
4646
4712
  throw new CliUsageError(
4647
- `papiers ${command} --document-id currently accepts only doc_* IDs.`
4713
+ acceptsItemLocators ? `papiers ${command} --document-id accepts only doc_* IDs or papiers://item locators.` : `papiers ${command} --document-id currently accepts only doc_* IDs.`
4648
4714
  );
4649
4715
  }
4650
4716
  const explicitDocumentIdCount = documentIds.filter(
@@ -5895,6 +5961,15 @@ async function runCli(argv, dependencies = {}) {
5895
5961
  );
5896
5962
  return 0;
5897
5963
  }
5964
+ case "feed-add":
5965
+ writeJson(
5966
+ stdout,
5967
+ await addFeedLink(config, resolveFetch(dependencies.fetch), {
5968
+ url: command.url,
5969
+ ...command.reason !== void 0 ? { reason: command.reason } : {}
5970
+ })
5971
+ );
5972
+ return 0;
5898
5973
  case "import":
5899
5974
  writeJson(
5900
5975
  stdout,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "papiers",
3
- "version": "0.1.7",
3
+ "version": "0.1.8",
4
4
  "description": "Read-only CLI for your Papiers library.",
5
5
  "license": "UNLICENSED",
6
6
  "homepage": "https://papiers.ai",
@@ -132,6 +132,14 @@ once for the full contract. `PAPIERS_TOKEN` must be configured.
132
132
  a formula, its last words as `--end`; both as you read them, on plain words:
133
133
  keep math, even a single symbol like V, out of both (formatting doesn't
134
134
  matter). If it repeats, add words until unique.
135
+ - **Add to the user's Discover feed what you think they'd want to read.**
136
+ `papiers feed add URL --reason "..."` needs a token with "Allow adding to
137
+ your Discover feed". It puts the link in their own Discover feed in Papiers,
138
+ labeled with your token's name and your reason; it never touches their
139
+ library. Give a reason in your own words: why this user, given what you
140
+ know of them. Public pages only (not paywalled, nothing private in the
141
+ link). It shows once Papiers has prepared it, usually within minutes;
142
+ sending it again answers how it is now.
135
143
  - **Budgets are policy, not protocol.** Default to ~10–20 queries and 3–8
136
144
  document reads per task. The user may override any policy in this skill
137
145
  (read more, weight recency differently, skip curation); the loop's shape