papiers 0.1.5 → 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 +6 -2
- package/dist/index.js +580 -380
- package/package.json +1 -1
- package/skills/papiers-research/SKILL.md +29 -2
package/dist/index.js
CHANGED
|
@@ -9,6 +9,7 @@ import { realpathSync } from "fs";
|
|
|
9
9
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
10
10
|
|
|
11
11
|
// src/commands.ts
|
|
12
|
+
import { randomUUID as randomUUID2 } from "crypto";
|
|
12
13
|
import { readFile, stat } from "fs/promises";
|
|
13
14
|
import { isAbsolute, resolve as resolve2 } from "path";
|
|
14
15
|
|
|
@@ -412,6 +413,177 @@ function isNodeError(error) {
|
|
|
412
413
|
return Boolean(error && typeof error === "object" && "code" in error);
|
|
413
414
|
}
|
|
414
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
|
+
|
|
530
|
+
// ../../src/shared/papiers-public-ids.ts
|
|
531
|
+
var PAPIERS_PUBLIC_ID_PREFIX_BY_KIND = {
|
|
532
|
+
document: "doc",
|
|
533
|
+
highlight: "hl",
|
|
534
|
+
conversation: "cnv",
|
|
535
|
+
section: "sec",
|
|
536
|
+
figure: "fig",
|
|
537
|
+
table: "tbl",
|
|
538
|
+
note: "nte"
|
|
539
|
+
};
|
|
540
|
+
var PAPIERS_PUBLIC_ID_KIND_BY_PREFIX = Object.fromEntries(
|
|
541
|
+
Object.entries(PAPIERS_PUBLIC_ID_PREFIX_BY_KIND).map(([kind, prefix]) => [
|
|
542
|
+
prefix,
|
|
543
|
+
kind
|
|
544
|
+
])
|
|
545
|
+
);
|
|
546
|
+
var PAPIERS_PUBLIC_ID_PATTERN = /^(doc|hl|cnv|sec|fig|tbl|nte)_([a-f0-9]{32})$/;
|
|
547
|
+
var PAPIERS_PUBLIC_REF_PATTERN = /^(doc_[a-f0-9]{32})#(?:p(0|[1-9][0-9]{0,9})|e([a-z0-9_]{1,64}))\.([a-f0-9]{8})$/;
|
|
548
|
+
var MAX_CHUNK_INDEX = 2147483647;
|
|
549
|
+
function parsePapiersPublicId(value) {
|
|
550
|
+
const id = value.trim();
|
|
551
|
+
const ref = id.match(PAPIERS_PUBLIC_REF_PATTERN);
|
|
552
|
+
if (ref) {
|
|
553
|
+
const [, documentId, chunkIndex, astNodeId, fingerprint] = ref;
|
|
554
|
+
if (chunkIndex !== void 0) {
|
|
555
|
+
const index = Number(chunkIndex);
|
|
556
|
+
if (index > MAX_CHUNK_INDEX) return null;
|
|
557
|
+
return {
|
|
558
|
+
id,
|
|
559
|
+
kind: "passage",
|
|
560
|
+
documentId,
|
|
561
|
+
chunkIndex: index,
|
|
562
|
+
fingerprint
|
|
563
|
+
};
|
|
564
|
+
}
|
|
565
|
+
return { id, kind: "equation", documentId, astNodeId, fingerprint };
|
|
566
|
+
}
|
|
567
|
+
const match = id.match(PAPIERS_PUBLIC_ID_PATTERN);
|
|
568
|
+
if (!match) {
|
|
569
|
+
return null;
|
|
570
|
+
}
|
|
571
|
+
const prefix = match[1];
|
|
572
|
+
const kind = PAPIERS_PUBLIC_ID_KIND_BY_PREFIX[prefix];
|
|
573
|
+
if (!kind) {
|
|
574
|
+
return null;
|
|
575
|
+
}
|
|
576
|
+
return {
|
|
577
|
+
id,
|
|
578
|
+
kind,
|
|
579
|
+
prefix,
|
|
580
|
+
opaqueId: match[2]
|
|
581
|
+
};
|
|
582
|
+
}
|
|
583
|
+
function staleReferenceMessage(kind) {
|
|
584
|
+
return kind === "passage" ? "Passage text has changed. Search or read the document again." : "Equation text has changed. Search or read the document again.";
|
|
585
|
+
}
|
|
586
|
+
|
|
415
587
|
// ../../src/shared/papiers-resource-locators.ts
|
|
416
588
|
var UUID_PATTERN = "[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}";
|
|
417
589
|
var PAPIERS_RESOURCE_LOCATOR_PATTERN_SOURCE = `papiers://(?:note|highlight|item|conversation|artifact)/${UUID_PATTERN}`;
|
|
@@ -533,54 +705,20 @@ var DOCUMENT_MAX_FILTER_VALUES = DOCUMENT_MAX_IDS;
|
|
|
533
705
|
var DOCUMENT_DEFAULT_READ_CHARS_PER_ITEM = 5e4;
|
|
534
706
|
var DOCUMENT_MAX_READ_CHARS_PER_ITEM = 2e5;
|
|
535
707
|
var DOCUMENT_MAX_READ_CHARS_PER_REQUEST = 5e5;
|
|
536
|
-
var DOCUMENT_PUBLIC_ID_PATTERN = /^doc_[a-f0-9]{32}$/u;
|
|
537
|
-
var PASSAGE_PUBLIC_ID_PATTERN = /^pas_[a-f0-9]{32}$/u;
|
|
538
|
-
var HIGHLIGHT_PUBLIC_ID_PATTERN = /^hl_[a-f0-9]{32}$/u;
|
|
539
|
-
var CONVERSATION_PUBLIC_ID_PATTERN = /^cnv_[a-f0-9]{32}$/u;
|
|
540
|
-
var EQUATION_PUBLIC_ID_PATTERN = /^eq_[a-f0-9]{32}$/u;
|
|
541
|
-
var NOTE_PUBLIC_ID_PATTERN = /^nte_[a-f0-9]{32}$/u;
|
|
542
708
|
var SEARCH_RANKING_ID_PATTERN = /^srch_[a-f0-9]{32}$/u;
|
|
543
709
|
function isSearchRankingId(value) {
|
|
544
710
|
return SEARCH_RANKING_ID_PATTERN.test(value);
|
|
545
711
|
}
|
|
546
|
-
|
|
547
|
-
return DOCUMENT_PUBLIC_ID_PATTERN.test(value);
|
|
548
|
-
}
|
|
549
|
-
function isPassagePublicId(value) {
|
|
550
|
-
return PASSAGE_PUBLIC_ID_PATTERN.test(value);
|
|
551
|
-
}
|
|
552
|
-
function isHighlightPublicId(value) {
|
|
553
|
-
return HIGHLIGHT_PUBLIC_ID_PATTERN.test(value);
|
|
554
|
-
}
|
|
555
|
-
function isConversationPublicId(value) {
|
|
556
|
-
return CONVERSATION_PUBLIC_ID_PATTERN.test(value);
|
|
557
|
-
}
|
|
558
|
-
function isEquationPublicId(value) {
|
|
559
|
-
return EQUATION_PUBLIC_ID_PATTERN.test(value);
|
|
560
|
-
}
|
|
561
|
-
function isNotePublicId(value) {
|
|
562
|
-
return NOTE_PUBLIC_ID_PATTERN.test(value);
|
|
563
|
-
}
|
|
712
|
+
var CLI_READABLE_KINDS = new Set(PUBLIC_KINDS);
|
|
564
713
|
function publicReadKindForId(value) {
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
if (isPassagePublicId(value)) {
|
|
569
|
-
return "passage";
|
|
570
|
-
}
|
|
571
|
-
if (isHighlightPublicId(value)) {
|
|
572
|
-
return "highlight";
|
|
573
|
-
}
|
|
574
|
-
if (isConversationPublicId(value)) {
|
|
575
|
-
return "conversation";
|
|
576
|
-
}
|
|
577
|
-
if (isEquationPublicId(value)) {
|
|
578
|
-
return "equation";
|
|
579
|
-
}
|
|
580
|
-
if (isNotePublicId(value)) {
|
|
581
|
-
return "note";
|
|
714
|
+
const parsed = parsePapiersPublicId(value);
|
|
715
|
+
if (!parsed || parsed.id !== value || !CLI_READABLE_KINDS.has(parsed.kind)) {
|
|
716
|
+
return null;
|
|
582
717
|
}
|
|
583
|
-
return
|
|
718
|
+
return parsed.kind;
|
|
719
|
+
}
|
|
720
|
+
function isDocumentPublicId(value) {
|
|
721
|
+
return publicReadKindForId(value) === "document";
|
|
584
722
|
}
|
|
585
723
|
function readKindForIdentifier(value) {
|
|
586
724
|
const publicKind = publicReadKindForId(value);
|
|
@@ -597,118 +735,6 @@ function isPublicIdForKind(value, kind) {
|
|
|
597
735
|
return publicReadKindForId(value) === kind;
|
|
598
736
|
}
|
|
599
737
|
|
|
600
|
-
// src/contracts.ts
|
|
601
|
-
var PAPIERS_SCHEMA_VERSIONS = {
|
|
602
|
-
searchRequest: "papiers.search.request.v1",
|
|
603
|
-
search: "papiers.search.v1",
|
|
604
|
-
searchResultsRequest: "papiers.search.results.request.v1",
|
|
605
|
-
listRequest: "papiers.list.request.v1",
|
|
606
|
-
list: "papiers.list.v1",
|
|
607
|
-
readRequest: "papiers.read.request.v1",
|
|
608
|
-
read: "papiers.read.v1",
|
|
609
|
-
capabilities: "papiers.capabilities.v1",
|
|
610
|
-
tokenList: "papiers.tokens.list.response.v1",
|
|
611
|
-
tokenRevoke: "papiers.tokens.revoke.response.v1",
|
|
612
|
-
error: "papiers.error.v1"
|
|
613
|
-
};
|
|
614
|
-
var PAPIERS_PUBLIC_DATA_PLANE_SCOPES = [
|
|
615
|
-
"library:metadata:read",
|
|
616
|
-
"library:search",
|
|
617
|
-
"content:search",
|
|
618
|
-
"content:snippet:read",
|
|
619
|
-
"content:read",
|
|
620
|
-
"content:structure:read"
|
|
621
|
-
];
|
|
622
|
-
var PAPIERS_PUBLIC_FEATURE_IDS = [
|
|
623
|
-
"document_content_read",
|
|
624
|
-
"non_document_kinds",
|
|
625
|
-
"content_search",
|
|
626
|
-
"list_cursors",
|
|
627
|
-
"read_cursors",
|
|
628
|
-
"read_section_scopes",
|
|
629
|
-
"read_context",
|
|
630
|
-
"read_locations",
|
|
631
|
-
"ranked_search_cursors",
|
|
632
|
-
"search_results_browse",
|
|
633
|
-
"public_id_projection_not_ready",
|
|
634
|
-
"queryIn:content",
|
|
635
|
-
"queryIn:all",
|
|
636
|
-
"queryIn:latex"
|
|
637
|
-
];
|
|
638
|
-
var PAPIERS_SEARCH_QUALITY_SIGNALS = [
|
|
639
|
-
"high",
|
|
640
|
-
"medium",
|
|
641
|
-
"low",
|
|
642
|
-
"empty"
|
|
643
|
-
];
|
|
644
|
-
var PAPIERS_SEARCH_RESULT_KINDS = [
|
|
645
|
-
"document",
|
|
646
|
-
"conversation",
|
|
647
|
-
"note"
|
|
648
|
-
];
|
|
649
|
-
var PAPIERS_SEARCH_EVIDENCE_KINDS = [
|
|
650
|
-
"passage",
|
|
651
|
-
"highlight",
|
|
652
|
-
"equation"
|
|
653
|
-
];
|
|
654
|
-
var PAPIERS_SEARCH_MATCH_REASONS = [
|
|
655
|
-
"title",
|
|
656
|
-
"doi",
|
|
657
|
-
"arxivId",
|
|
658
|
-
"pmid",
|
|
659
|
-
"passage",
|
|
660
|
-
"highlight",
|
|
661
|
-
"equation",
|
|
662
|
-
"conversation",
|
|
663
|
-
"note"
|
|
664
|
-
];
|
|
665
|
-
var PAPIERS_PUBLIC_NOT_READY_REASONS_BY_FEATURE = {
|
|
666
|
-
document_content_read: ["explicit_enablement_required"],
|
|
667
|
-
non_document_kinds: ["public_id_projection_not_ready"],
|
|
668
|
-
content_search: [
|
|
669
|
-
"content_search_not_ready",
|
|
670
|
-
"public_passage_projection_not_ready"
|
|
671
|
-
],
|
|
672
|
-
list_cursors: ["cursor_signing_not_configured"],
|
|
673
|
-
read_cursors: [
|
|
674
|
-
"cursor_signing_not_configured",
|
|
675
|
-
"document_content_read_required"
|
|
676
|
-
],
|
|
677
|
-
read_section_scopes: ["section_scoped_read_not_ready"],
|
|
678
|
-
read_context: ["read_context_not_ready"],
|
|
679
|
-
ranked_search_cursors: ["search_sessions_not_ready"],
|
|
680
|
-
search_results_browse: [
|
|
681
|
-
"content_search_not_ready",
|
|
682
|
-
"search_sessions_not_ready"
|
|
683
|
-
]
|
|
684
|
-
};
|
|
685
|
-
var PAPIERS_PUBLIC_ERROR_CODES = [
|
|
686
|
-
"api_disabled",
|
|
687
|
-
"auth_missing",
|
|
688
|
-
"auth_invalid_format",
|
|
689
|
-
"auth_invalid",
|
|
690
|
-
"auth_wrong_surface",
|
|
691
|
-
"auth_scope_missing",
|
|
692
|
-
"feature_not_available",
|
|
693
|
-
"filter_not_supported",
|
|
694
|
-
"invalid_filter_field",
|
|
695
|
-
"invalid_filter_operator",
|
|
696
|
-
"invalid_filter_value",
|
|
697
|
-
"invalid_filter_combination",
|
|
698
|
-
"order_not_supported",
|
|
699
|
-
"unsupported_format",
|
|
700
|
-
"invalid_cursor",
|
|
701
|
-
"invalid_cursor_context",
|
|
702
|
-
"forbidden",
|
|
703
|
-
"invalid_request",
|
|
704
|
-
"not_found",
|
|
705
|
-
"source_superseded",
|
|
706
|
-
"content_limit_exceeded",
|
|
707
|
-
"request_limit_exceeded",
|
|
708
|
-
"rate_limited",
|
|
709
|
-
"internal_error"
|
|
710
|
-
];
|
|
711
|
-
|
|
712
738
|
// ../../src/shared/papiers-public-source-domain.ts
|
|
713
739
|
var papiers_public_source_domain_exports = {};
|
|
714
740
|
__export(papiers_public_source_domain_exports, {
|
|
@@ -799,9 +825,6 @@ function isTokenUuid(value) {
|
|
|
799
825
|
}
|
|
800
826
|
|
|
801
827
|
// src/response-validation.ts
|
|
802
|
-
var PUBLIC_DATA_PLANE_SCOPE_SET = new Set(
|
|
803
|
-
PAPIERS_PUBLIC_DATA_PLANE_SCOPES
|
|
804
|
-
);
|
|
805
828
|
var PUBLIC_ERROR_CODE_SET = new Set(PAPIERS_PUBLIC_ERROR_CODES);
|
|
806
829
|
var SAFE_REQUEST_ID_PATTERN = /^[A-Za-z0-9._:-]{1,128}$/u;
|
|
807
830
|
var LIST_RESPONSE_KEYS = /* @__PURE__ */ new Set([
|
|
@@ -850,26 +873,6 @@ var READ_RESPONSE_KEYS = /* @__PURE__ */ new Set([
|
|
|
850
873
|
"items",
|
|
851
874
|
"usage"
|
|
852
875
|
]);
|
|
853
|
-
var TOKEN_LIST_RESPONSE_KEYS = /* @__PURE__ */ new Set([
|
|
854
|
-
"schemaVersion",
|
|
855
|
-
"requestId",
|
|
856
|
-
"tokens"
|
|
857
|
-
]);
|
|
858
|
-
var TOKEN_REVOKE_RESPONSE_KEYS = /* @__PURE__ */ new Set([
|
|
859
|
-
"schemaVersion",
|
|
860
|
-
"requestId",
|
|
861
|
-
"tokenId",
|
|
862
|
-
"revoked"
|
|
863
|
-
]);
|
|
864
|
-
var TOKEN_SUMMARY_KEYS = /* @__PURE__ */ new Set([
|
|
865
|
-
"tokenId",
|
|
866
|
-
"name",
|
|
867
|
-
"scopes",
|
|
868
|
-
"createdAt",
|
|
869
|
-
"expiresAt",
|
|
870
|
-
"revokedAt",
|
|
871
|
-
"lastUsedAt"
|
|
872
|
-
]);
|
|
873
876
|
var PAGE_KEYS = /* @__PURE__ */ new Set(["nextCursor", "returnedCount"]);
|
|
874
877
|
var READ_USAGE_KEYS = /* @__PURE__ */ new Set(["returnedChars", "truncatedItemCount"]);
|
|
875
878
|
var LIST_DOCUMENT_ITEM_KEYS = /* @__PURE__ */ new Set([
|
|
@@ -949,6 +952,7 @@ var READ_SUCCESS_PASSAGE_ITEM_KEYS = /* @__PURE__ */ new Set([
|
|
|
949
952
|
"truncated",
|
|
950
953
|
"charCount",
|
|
951
954
|
"tokenEstimate",
|
|
955
|
+
"metadata",
|
|
952
956
|
"warnings"
|
|
953
957
|
]);
|
|
954
958
|
var READ_SUCCESS_HIGHLIGHT_ITEM_KEYS = /* @__PURE__ */ new Set([
|
|
@@ -1056,6 +1060,7 @@ var CONVERSATION_READ_NOT_FOUND_MESSAGE = "Conversation is not available.";
|
|
|
1056
1060
|
var EQUATION_READ_NOT_FOUND_MESSAGE = "Equation is not available.";
|
|
1057
1061
|
var NOTE_READ_NOT_FOUND_MESSAGE = "Note is not available.";
|
|
1058
1062
|
var DOCUMENT_READ_SOURCE_SUPERSEDED_CODE = "source_superseded";
|
|
1063
|
+
var READ_STALE_REFERENCE_CODE = "stale_reference";
|
|
1059
1064
|
var CONVERSATION_READ_CONTENT_LIMIT_CODE = "content_limit_exceeded";
|
|
1060
1065
|
var CONVERSATION_READ_REQUEST_LIMIT_CODE = "request_limit_exceeded";
|
|
1061
1066
|
var DOCUMENT_READ_SOURCE_SUPERSEDED_MESSAGE = "Document content is not available for the current source.";
|
|
@@ -1299,28 +1304,64 @@ function assertPapiersReadResponse(label, body, expectedIds, expected = "metadat
|
|
|
1299
1304
|
function assertPapiersReadPipelineEnvelope(label, body) {
|
|
1300
1305
|
validatePapiersReadResponse(label, body);
|
|
1301
1306
|
}
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1307
|
+
var IMPORT_RESPONSE_KEYS = /* @__PURE__ */ new Set([
|
|
1308
|
+
"schemaVersion",
|
|
1309
|
+
"requestId",
|
|
1310
|
+
"operationId",
|
|
1311
|
+
"status",
|
|
1312
|
+
"documentId",
|
|
1313
|
+
"error"
|
|
1314
|
+
]);
|
|
1315
|
+
var IMPORT_ERROR_KEYS = new Set(
|
|
1316
|
+
Object.keys({
|
|
1317
|
+
code: true,
|
|
1318
|
+
message: true,
|
|
1319
|
+
retryable: true,
|
|
1320
|
+
details: true
|
|
1321
|
+
})
|
|
1322
|
+
);
|
|
1323
|
+
var IMPORT_ERROR_DETAIL_KEYS = /* @__PURE__ */ new Set(["importCode"]);
|
|
1324
|
+
function assertPapiersImportResponse(label, body) {
|
|
1325
|
+
const value = assertSchema(label, body, PAPIERS_SCHEMA_VERSIONS.import);
|
|
1326
|
+
rejectUnexpectedKeys(label, value, IMPORT_RESPONSE_KEYS);
|
|
1306
1327
|
assertPublicRequestId(`${label} requestId`, value.requestId);
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1328
|
+
assertNonEmptyString(`${label} operationId`, value.operationId);
|
|
1329
|
+
assertNonEmptyString(`${label} status`, value.status);
|
|
1330
|
+
if (value.documentId !== null) {
|
|
1331
|
+
assertDocumentReadIdentifier(`${label} documentId`, value.documentId);
|
|
1332
|
+
}
|
|
1333
|
+
if (value.error !== null) {
|
|
1334
|
+
const error = assertRecord(`${label} error`, value.error);
|
|
1335
|
+
rejectUnexpectedKeys(`${label} error`, error, IMPORT_ERROR_KEYS);
|
|
1336
|
+
assertPublicErrorCode(`${label} error.code`, error.code);
|
|
1337
|
+
assertNonEmptyString(`${label} error.message`, error.message);
|
|
1338
|
+
assertBoolean(`${label} error.retryable`, error.retryable);
|
|
1339
|
+
const details = assertRecord(`${label} error.details`, error.details);
|
|
1340
|
+
rejectUnexpectedKeys(
|
|
1341
|
+
`${label} error.details`,
|
|
1342
|
+
details,
|
|
1343
|
+
IMPORT_ERROR_DETAIL_KEYS
|
|
1344
|
+
);
|
|
1345
|
+
assertNonEmptyString(
|
|
1346
|
+
`${label} error.details.importCode`,
|
|
1347
|
+
details.importCode
|
|
1348
|
+
);
|
|
1310
1349
|
}
|
|
1311
1350
|
}
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1351
|
+
var HIGHLIGHT_RESPONSE_KEYS = /* @__PURE__ */ new Set([
|
|
1352
|
+
"schemaVersion",
|
|
1353
|
+
"requestId",
|
|
1354
|
+
"highlightId"
|
|
1355
|
+
]);
|
|
1356
|
+
function assertPapiersHighlightResponse(label, body) {
|
|
1357
|
+
const value = assertSchema(label, body, PAPIERS_SCHEMA_VERSIONS.highlight);
|
|
1358
|
+
rejectUnexpectedKeys(label, value, HIGHLIGHT_RESPONSE_KEYS);
|
|
1316
1359
|
assertPublicRequestId(`${label} requestId`, value.requestId);
|
|
1317
|
-
|
|
1318
|
-
if (tokenId !== expectedTokenId) {
|
|
1360
|
+
if (typeof value.highlightId !== "string" || !value.highlightId.startsWith("papiers://highlight/")) {
|
|
1319
1361
|
throw new PapiersCliResponseValidationError(
|
|
1320
|
-
`${label}
|
|
1362
|
+
`${label} returned an invalid highlight identifier.`
|
|
1321
1363
|
);
|
|
1322
1364
|
}
|
|
1323
|
-
assertBoolean(`${label} revoked`, value.revoked);
|
|
1324
1365
|
}
|
|
1325
1366
|
function assertPapiersErrorResponse(label, body, expectedHttpStatus) {
|
|
1326
1367
|
assertNoInternalResponseKeys(label, body);
|
|
@@ -1438,28 +1479,6 @@ function validatePapiersReadResponse(label, body, options = {}) {
|
|
|
1438
1479
|
);
|
|
1439
1480
|
}
|
|
1440
1481
|
}
|
|
1441
|
-
function validateTokenSummary(label, rawToken) {
|
|
1442
|
-
const token = assertRecord(label, rawToken);
|
|
1443
|
-
rejectUnexpectedKeys(label, token, TOKEN_SUMMARY_KEYS);
|
|
1444
|
-
assertTokenId(`${label} tokenId`, token.tokenId);
|
|
1445
|
-
assertNonEmptyString(`${label} name`, token.name);
|
|
1446
|
-
const scopes = assertArray(`${label} scopes`, token.scopes);
|
|
1447
|
-
if (scopes.length === 0) {
|
|
1448
|
-
throw new PapiersCliResponseValidationError(`${label} scopes was empty.`);
|
|
1449
|
-
}
|
|
1450
|
-
for (const [index, rawScope] of scopes.entries()) {
|
|
1451
|
-
const scope = assertNonEmptyString(`${label} scope ${index}`, rawScope);
|
|
1452
|
-
if (!PUBLIC_DATA_PLANE_SCOPE_SET.has(scope)) {
|
|
1453
|
-
throw new PapiersCliResponseValidationError(
|
|
1454
|
-
`${label} scope ${index} was not a public data-plane scope.`
|
|
1455
|
-
);
|
|
1456
|
-
}
|
|
1457
|
-
}
|
|
1458
|
-
assertTimestampString(`${label} createdAt`, token.createdAt);
|
|
1459
|
-
validateOptionalTimestamp(`${label} expiresAt`, token.expiresAt);
|
|
1460
|
-
validateOptionalTimestamp(`${label} revokedAt`, token.revokedAt);
|
|
1461
|
-
validateOptionalTimestamp(`${label} lastUsedAt`, token.lastUsedAt);
|
|
1462
|
-
}
|
|
1463
1482
|
function validateSearchResults(label, results, options = {}) {
|
|
1464
1483
|
const values = assertArray(`${label} results`, results);
|
|
1465
1484
|
for (const [index, rawResult] of values.entries()) {
|
|
@@ -1807,7 +1826,7 @@ function validateOptionalListSearchMetadata(label, value, kind) {
|
|
|
1807
1826
|
);
|
|
1808
1827
|
}
|
|
1809
1828
|
if (kind === "passage") {
|
|
1810
|
-
return
|
|
1829
|
+
return validatePassageMetadata(label, value);
|
|
1811
1830
|
}
|
|
1812
1831
|
if (kind === "highlight") {
|
|
1813
1832
|
return validateHighlightMetadata(label, value, assertDocId);
|
|
@@ -1821,7 +1840,7 @@ function validateOptionalListSearchMetadata(label, value, kind) {
|
|
|
1821
1840
|
}
|
|
1822
1841
|
return validateEquationReadMetadata(label, value);
|
|
1823
1842
|
}
|
|
1824
|
-
function
|
|
1843
|
+
function validatePassageMetadata(label, value) {
|
|
1825
1844
|
const metadata = assertRecord(label, value);
|
|
1826
1845
|
rejectUnexpectedKeys(label, metadata, PASSAGE_METADATA_KEYS);
|
|
1827
1846
|
const documentId = assertDocId(`${label}.documentId`, metadata.documentId);
|
|
@@ -1951,6 +1970,19 @@ function validatePassageReadSuccessItem(label, item, options) {
|
|
|
1951
1970
|
const contentResult = validateReadContent(label, item, itemFormat, {
|
|
1952
1971
|
expectedMaxCharsPerItem: options.expectedMaxCharsPerItem
|
|
1953
1972
|
});
|
|
1973
|
+
const metadataRequested = options.expectedInclude?.has("metadata") ?? false;
|
|
1974
|
+
if (Object.prototype.hasOwnProperty.call(item, "metadata")) {
|
|
1975
|
+
if (!metadataRequested) {
|
|
1976
|
+
throw new PapiersCliResponseValidationError(
|
|
1977
|
+
`${label} returned metadata that was not requested.`
|
|
1978
|
+
);
|
|
1979
|
+
}
|
|
1980
|
+
validatePassageMetadata(`${label} metadata`, item.metadata);
|
|
1981
|
+
} else if (metadataRequested) {
|
|
1982
|
+
throw new PapiersCliResponseValidationError(
|
|
1983
|
+
`${label} did not return requested metadata.`
|
|
1984
|
+
);
|
|
1985
|
+
}
|
|
1954
1986
|
const hasReadTruncatedWarning = validateOptionalReadWarnings(
|
|
1955
1987
|
`${label} warnings`,
|
|
1956
1988
|
item.warnings,
|
|
@@ -2383,7 +2415,8 @@ function validateReadItemError(label, value, kind, expectedFormat) {
|
|
|
2383
2415
|
const sourceSupersededAllowed = error.code === DOCUMENT_READ_SOURCE_SUPERSEDED_CODE && (kind === "document" || kind === "passage" || kind === "note" || kind === "conversation");
|
|
2384
2416
|
const contentLimitAllowed = error.code === CONVERSATION_READ_CONTENT_LIMIT_CODE && kind === "conversation";
|
|
2385
2417
|
const requestLimitAllowed = error.code === CONVERSATION_READ_REQUEST_LIMIT_CODE && kind === "conversation";
|
|
2386
|
-
|
|
2418
|
+
const staleReferenceKind = error.code === READ_STALE_REFERENCE_CODE && (kind === "passage" || kind === "equation") ? kind : null;
|
|
2419
|
+
if (error.code !== DOCUMENT_READ_NOT_FOUND_CODE && !sourceSupersededAllowed && !contentLimitAllowed && !requestLimitAllowed && !staleReferenceKind) {
|
|
2387
2420
|
throw new PapiersCliResponseValidationError(
|
|
2388
2421
|
`${label}.code was not a supported read error code.`
|
|
2389
2422
|
);
|
|
@@ -2393,7 +2426,7 @@ function validateReadItemError(label, value, kind, expectedFormat) {
|
|
|
2393
2426
|
`${label}.code was not supported for metadata reads.`
|
|
2394
2427
|
);
|
|
2395
2428
|
}
|
|
2396
|
-
const expectedMessage = error.code === DOCUMENT_READ_NOT_FOUND_CODE ? readNotFoundMessageForKind(kind) : error.code === CONVERSATION_READ_CONTENT_LIMIT_CODE ? CONVERSATION_READ_CONTENT_LIMIT_MESSAGE : error.code === CONVERSATION_READ_REQUEST_LIMIT_CODE ? CONVERSATION_READ_REQUEST_LIMIT_MESSAGE : kind === "conversation" ? CONVERSATION_READ_SOURCE_SUPERSEDED_MESSAGE : kind === "passage" ? PASSAGE_READ_CONTENT_UNAVAILABLE_MESSAGE : kind === "note" ? NOTE_READ_SOURCE_SUPERSEDED_MESSAGE : DOCUMENT_READ_SOURCE_SUPERSEDED_MESSAGE;
|
|
2429
|
+
const expectedMessage = staleReferenceKind ? staleReferenceMessage(staleReferenceKind) : error.code === DOCUMENT_READ_NOT_FOUND_CODE ? readNotFoundMessageForKind(kind) : error.code === CONVERSATION_READ_CONTENT_LIMIT_CODE ? CONVERSATION_READ_CONTENT_LIMIT_MESSAGE : error.code === CONVERSATION_READ_REQUEST_LIMIT_CODE ? CONVERSATION_READ_REQUEST_LIMIT_MESSAGE : kind === "conversation" ? CONVERSATION_READ_SOURCE_SUPERSEDED_MESSAGE : kind === "passage" ? PASSAGE_READ_CONTENT_UNAVAILABLE_MESSAGE : kind === "note" ? NOTE_READ_SOURCE_SUPERSEDED_MESSAGE : DOCUMENT_READ_SOURCE_SUPERSEDED_MESSAGE;
|
|
2397
2430
|
if (error.message !== expectedMessage) {
|
|
2398
2431
|
throw new PapiersCliResponseValidationError(
|
|
2399
2432
|
`${label}.message was not a supported read error message.`
|
|
@@ -2920,14 +2953,6 @@ function assertReadIdentifier(label, value) {
|
|
|
2920
2953
|
}
|
|
2921
2954
|
return value;
|
|
2922
2955
|
}
|
|
2923
|
-
function assertTokenId(label, value) {
|
|
2924
|
-
if (typeof value !== "string" || !isTokenUuid(value)) {
|
|
2925
|
-
throw new PapiersCliResponseValidationError(
|
|
2926
|
-
`${label} was not a token UUID.`
|
|
2927
|
-
);
|
|
2928
|
-
}
|
|
2929
|
-
return value;
|
|
2930
|
-
}
|
|
2931
2956
|
function assertPublicRequestId(label, value) {
|
|
2932
2957
|
if (typeof value !== "string" || !SAFE_REQUEST_ID_PATTERN.test(value)) {
|
|
2933
2958
|
throw new PapiersCliResponseValidationError(
|
|
@@ -3015,7 +3040,7 @@ async function getCapabilities(config, fetchImpl) {
|
|
|
3015
3040
|
config,
|
|
3016
3041
|
fetchImpl,
|
|
3017
3042
|
"/api/v1/papiers/capabilities",
|
|
3018
|
-
{ method: "GET"
|
|
3043
|
+
{ method: "GET" }
|
|
3019
3044
|
);
|
|
3020
3045
|
assertPapiersCapabilitiesResponse("capabilities", body);
|
|
3021
3046
|
return body;
|
|
@@ -3026,7 +3051,7 @@ async function listDocuments(config, fetchImpl, request) {
|
|
|
3026
3051
|
config,
|
|
3027
3052
|
fetchImpl,
|
|
3028
3053
|
"/api/v1/papiers/list",
|
|
3029
|
-
{ method: "POST", body: request
|
|
3054
|
+
{ method: "POST", body: request }
|
|
3030
3055
|
);
|
|
3031
3056
|
assertPapiersListResponse("list", body, { expectedKind });
|
|
3032
3057
|
return body;
|
|
@@ -3037,7 +3062,7 @@ async function searchDocuments(config, fetchImpl, request) {
|
|
|
3037
3062
|
config,
|
|
3038
3063
|
fetchImpl,
|
|
3039
3064
|
"/api/v1/papiers/search",
|
|
3040
|
-
{ method: "POST", body: request
|
|
3065
|
+
{ method: "POST", body: request }
|
|
3041
3066
|
);
|
|
3042
3067
|
assertPapiersSearchResponse("search", body, request.query, expected);
|
|
3043
3068
|
return body;
|
|
@@ -3047,7 +3072,7 @@ async function browseSearchResults(config, fetchImpl, request) {
|
|
|
3047
3072
|
config,
|
|
3048
3073
|
fetchImpl,
|
|
3049
3074
|
"/api/v1/papiers/search/results",
|
|
3050
|
-
{ method: "POST", body: request
|
|
3075
|
+
{ method: "POST", body: request }
|
|
3051
3076
|
);
|
|
3052
3077
|
assertPapiersSearchResultsResponse("search results", body, request);
|
|
3053
3078
|
return body;
|
|
@@ -3057,7 +3082,7 @@ async function readDocuments(config, fetchImpl, request) {
|
|
|
3057
3082
|
config,
|
|
3058
3083
|
fetchImpl,
|
|
3059
3084
|
"/api/v1/papiers/read",
|
|
3060
|
-
{ method: "POST", body: request
|
|
3085
|
+
{ method: "POST", body: request }
|
|
3061
3086
|
);
|
|
3062
3087
|
const readKind = readKindForIdentifier(request.ids[0] ?? "");
|
|
3063
3088
|
assertPapiersReadResponse("read", body, request.ids, {
|
|
@@ -3070,26 +3095,6 @@ async function readDocuments(config, fetchImpl, request) {
|
|
|
3070
3095
|
});
|
|
3071
3096
|
return body;
|
|
3072
3097
|
}
|
|
3073
|
-
async function listPapiersTokens(config, fetchImpl) {
|
|
3074
|
-
const body = await requestPapiersApi(
|
|
3075
|
-
config,
|
|
3076
|
-
fetchImpl,
|
|
3077
|
-
"/api/v1/papiers/tokens",
|
|
3078
|
-
{ method: "GET", retryable: true }
|
|
3079
|
-
);
|
|
3080
|
-
assertPapiersTokenListResponse("tokens list", body);
|
|
3081
|
-
return body;
|
|
3082
|
-
}
|
|
3083
|
-
async function revokePapiersToken(config, fetchImpl, tokenId) {
|
|
3084
|
-
const body = await requestPapiersApi(
|
|
3085
|
-
config,
|
|
3086
|
-
fetchImpl,
|
|
3087
|
-
`/api/v1/papiers/tokens/${encodeURIComponent(tokenId)}/revoke`,
|
|
3088
|
-
{ method: "POST" }
|
|
3089
|
-
);
|
|
3090
|
-
assertPapiersTokenRevokeResponse("tokens revoke", body, tokenId);
|
|
3091
|
-
return body;
|
|
3092
|
-
}
|
|
3093
3098
|
function expectedKindForListSearchRequest(request) {
|
|
3094
3099
|
const kinds = request.kinds;
|
|
3095
3100
|
if (kinds === void 0) {
|
|
@@ -3135,6 +3140,48 @@ function expectedKindsForSearchRequest(request) {
|
|
|
3135
3140
|
const [onlyKind] = expectedKinds;
|
|
3136
3141
|
return expectedKinds.size === 1 ? { expectedKind: onlyKind } : { expectedKinds };
|
|
3137
3142
|
}
|
|
3143
|
+
async function importDocument(config, fetchImpl, request) {
|
|
3144
|
+
const body = await requestPapiersApi(
|
|
3145
|
+
config,
|
|
3146
|
+
fetchImpl,
|
|
3147
|
+
"/api/v1/papiers/imports",
|
|
3148
|
+
{ method: "POST", body: request }
|
|
3149
|
+
);
|
|
3150
|
+
assertPapiersImportResponse("import", body);
|
|
3151
|
+
return body;
|
|
3152
|
+
}
|
|
3153
|
+
async function getImportStatus(config, fetchImpl, operationId) {
|
|
3154
|
+
const body = await requestPapiersApi(
|
|
3155
|
+
config,
|
|
3156
|
+
fetchImpl,
|
|
3157
|
+
`/api/v1/papiers/imports/${encodeURIComponent(operationId)}`,
|
|
3158
|
+
{ method: "GET" }
|
|
3159
|
+
);
|
|
3160
|
+
assertPapiersImportResponse("import-status", body);
|
|
3161
|
+
return body;
|
|
3162
|
+
}
|
|
3163
|
+
async function highlightDocument(config, fetchImpl, request) {
|
|
3164
|
+
const body = await requestPapiersApi(
|
|
3165
|
+
config,
|
|
3166
|
+
fetchImpl,
|
|
3167
|
+
"/api/v1/papiers/highlights",
|
|
3168
|
+
// Outlasts the server's 10 s queue wait plus 20 s search, so its answer
|
|
3169
|
+
// arrives.
|
|
3170
|
+
{ method: "POST", body: request, timeoutMs: 4e4 }
|
|
3171
|
+
);
|
|
3172
|
+
assertPapiersHighlightResponse("highlight", body);
|
|
3173
|
+
return body;
|
|
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
|
+
}
|
|
3138
3185
|
async function requestPapiersApi(config, fetchImpl, path, init) {
|
|
3139
3186
|
if (!config.token) {
|
|
3140
3187
|
throw new CliUsageError(
|
|
@@ -3164,10 +3211,13 @@ async function requestPapiersApiWithBearer(config, fetchImpl, bearerToken, path,
|
|
|
3164
3211
|
headers["content-type"] = "application/json";
|
|
3165
3212
|
requestInit.body = JSON.stringify(init.body);
|
|
3166
3213
|
}
|
|
3167
|
-
const response = await fetchWithRetry(
|
|
3168
|
-
|
|
3169
|
-
|
|
3170
|
-
|
|
3214
|
+
const { response, text } = await fetchWithRetry(
|
|
3215
|
+
fetchImpl,
|
|
3216
|
+
requestUrl,
|
|
3217
|
+
requestInit,
|
|
3218
|
+
init.timeoutMs ?? REQUEST_TIMEOUT_MS
|
|
3219
|
+
);
|
|
3220
|
+
const body = parseResponseBody(text);
|
|
3171
3221
|
if (!response.ok) {
|
|
3172
3222
|
const errorEnvelope = extractErrorEnvelope(body, response.status);
|
|
3173
3223
|
throw new PapiersCliApiError({
|
|
@@ -3179,44 +3229,45 @@ async function requestPapiersApiWithBearer(config, fetchImpl, bearerToken, path,
|
|
|
3179
3229
|
}
|
|
3180
3230
|
return body;
|
|
3181
3231
|
}
|
|
3182
|
-
async function fetchWithRetry(fetchImpl, requestUrl, requestInit,
|
|
3183
|
-
const maxAttempts = options.retryable ? MAX_REQUEST_ATTEMPTS : 1;
|
|
3232
|
+
async function fetchWithRetry(fetchImpl, requestUrl, requestInit, timeoutMs) {
|
|
3184
3233
|
let attempt = 1;
|
|
3185
3234
|
while (true) {
|
|
3186
3235
|
let response;
|
|
3236
|
+
let text;
|
|
3187
3237
|
try {
|
|
3188
3238
|
response = await fetchImpl(requestUrl, {
|
|
3189
3239
|
...requestInit,
|
|
3190
|
-
signal: AbortSignal.timeout(
|
|
3240
|
+
signal: AbortSignal.timeout(timeoutMs)
|
|
3191
3241
|
});
|
|
3242
|
+
text = await response.text();
|
|
3192
3243
|
} catch (error) {
|
|
3193
|
-
if (attempt >=
|
|
3244
|
+
if (attempt >= MAX_REQUEST_ATTEMPTS) {
|
|
3194
3245
|
throw error;
|
|
3195
3246
|
}
|
|
3196
3247
|
await sleep(RETRY_BACKOFF_MS[attempt - 1] ?? 1e3);
|
|
3197
3248
|
attempt += 1;
|
|
3198
3249
|
continue;
|
|
3199
3250
|
}
|
|
3200
|
-
|
|
3201
|
-
|
|
3251
|
+
const delayMs = retryDelayMs(response, attempt);
|
|
3252
|
+
if (attempt < MAX_REQUEST_ATTEMPTS && RETRYABLE_STATUS_CODES.has(response.status) && delayMs <= MAX_RETRY_AFTER_MS) {
|
|
3253
|
+
await sleep(delayMs);
|
|
3202
3254
|
attempt += 1;
|
|
3203
3255
|
continue;
|
|
3204
3256
|
}
|
|
3205
|
-
return response;
|
|
3257
|
+
return { response, text };
|
|
3206
3258
|
}
|
|
3207
3259
|
}
|
|
3208
3260
|
function retryDelayMs(response, attempt) {
|
|
3209
3261
|
const retryAfterSeconds = Number(response.headers.get("retry-after") ?? "");
|
|
3210
3262
|
if (Number.isFinite(retryAfterSeconds) && retryAfterSeconds > 0) {
|
|
3211
|
-
return
|
|
3263
|
+
return retryAfterSeconds * 1e3;
|
|
3212
3264
|
}
|
|
3213
3265
|
return RETRY_BACKOFF_MS[attempt - 1] ?? 1e3;
|
|
3214
3266
|
}
|
|
3215
3267
|
function sleep(ms) {
|
|
3216
3268
|
return new Promise((resolveSleep) => setTimeout(resolveSleep, ms));
|
|
3217
3269
|
}
|
|
3218
|
-
|
|
3219
|
-
const text = await response.text();
|
|
3270
|
+
function parseResponseBody(text) {
|
|
3220
3271
|
if (!text) {
|
|
3221
3272
|
return null;
|
|
3222
3273
|
}
|
|
@@ -3241,6 +3292,30 @@ function formatApiErrorMessage(params) {
|
|
|
3241
3292
|
return `Papiers API error ${params.status}.`;
|
|
3242
3293
|
}
|
|
3243
3294
|
|
|
3295
|
+
// ../../src/shared/highlight-colors.ts
|
|
3296
|
+
var HIGHLIGHT_HEX_COLOR_REGEX = /^#[0-9a-f]{6}$/;
|
|
3297
|
+
|
|
3298
|
+
// ../../src/shared/papiers-public-api.ts
|
|
3299
|
+
var PAPIERS_PUBLIC_DATA_PLANE_SCOPES2 = [
|
|
3300
|
+
"library:metadata:read",
|
|
3301
|
+
"library:search",
|
|
3302
|
+
"content:search",
|
|
3303
|
+
"content:snippet:read",
|
|
3304
|
+
"content:read",
|
|
3305
|
+
"content:structure:read"
|
|
3306
|
+
];
|
|
3307
|
+
var PAPIERS_WRITE_SCOPES = [
|
|
3308
|
+
"library:import",
|
|
3309
|
+
"library:highlight",
|
|
3310
|
+
"discover:feed"
|
|
3311
|
+
];
|
|
3312
|
+
var PAPIERS_PUBLIC_SCOPES = [
|
|
3313
|
+
...PAPIERS_PUBLIC_DATA_PLANE_SCOPES2,
|
|
3314
|
+
...PAPIERS_WRITE_SCOPES
|
|
3315
|
+
];
|
|
3316
|
+
var PAPIERS_HIGHLIGHT_MAX_SCOPE_PAGES = 20;
|
|
3317
|
+
var PAPIERS_HIGHLIGHT_MAX_PAGE = 1e4;
|
|
3318
|
+
|
|
3244
3319
|
// src/filters.ts
|
|
3245
3320
|
var FILTER_OPERATORS = [
|
|
3246
3321
|
"eq",
|
|
@@ -3709,7 +3784,17 @@ var BOOLEAN_FLAGS = /* @__PURE__ */ new Set([
|
|
|
3709
3784
|
"fail-fast",
|
|
3710
3785
|
"version"
|
|
3711
3786
|
]);
|
|
3787
|
+
var HIGHLIGHT_VALUE_FLAGS = [
|
|
3788
|
+
"start",
|
|
3789
|
+
"end",
|
|
3790
|
+
"passage",
|
|
3791
|
+
"pages",
|
|
3792
|
+
"note",
|
|
3793
|
+
"color"
|
|
3794
|
+
];
|
|
3712
3795
|
var VALUE_FLAGS = /* @__PURE__ */ new Set([
|
|
3796
|
+
...HIGHLIGHT_VALUE_FLAGS,
|
|
3797
|
+
"reason",
|
|
3713
3798
|
"api-url",
|
|
3714
3799
|
"cursor",
|
|
3715
3800
|
"document-id",
|
|
@@ -3827,8 +3912,10 @@ COMMANDS
|
|
|
3827
3912
|
list List your documents, highlights, notes, and conversations
|
|
3828
3913
|
read Print a document, highlight, note, or conversation
|
|
3829
3914
|
browse Page through an earlier search's results
|
|
3915
|
+
import Add a public PDF or webpage to your library
|
|
3916
|
+
highlight Highlight a passage in a saved document
|
|
3917
|
+
feed Add links to your Discover feed
|
|
3830
3918
|
auth Sign in, check status, or sign out
|
|
3831
|
-
tokens List or revoke your API tokens
|
|
3832
3919
|
doctor Check your setup, connection, and what's available
|
|
3833
3920
|
version Print the CLI version
|
|
3834
3921
|
|
|
@@ -3886,12 +3973,12 @@ USAGE
|
|
|
3886
3973
|
papiers list --kind highlight|conversation [--since WHEN]
|
|
3887
3974
|
|
|
3888
3975
|
OPTIONS
|
|
3889
|
-
--kind KIND document (default) \xB7
|
|
3976
|
+
--kind KIND document (default) \xB7 highlight \xB7 conversation \xB7 note.
|
|
3890
3977
|
--filter FIELD.OP=VALUE narrow document results \u2014 repeatable, up to 25. document kind only.
|
|
3891
3978
|
e.g. --filter lastEngagedAt.gte=30d --filter annotated=true. Fields/ops: help --all.
|
|
3892
3979
|
--order-by KEY addedAt:desc (default) or lastEngagedAt:desc. document kind only.
|
|
3893
3980
|
--document-id ID scope to documents: doc_\u2026 (comma-separated or repeated), or @-/@file.
|
|
3894
|
-
document and highlight only.
|
|
3981
|
+
document and highlight only; highlight also takes papiers://item/\u2026 locators.
|
|
3895
3982
|
--since WHEN only items at or after an ISO 8601 time, or an Nd shorthand (e.g. 30d).
|
|
3896
3983
|
highlight and conversation only.
|
|
3897
3984
|
--limit N max results, 1\u201350.
|
|
@@ -3916,7 +4003,7 @@ OPTIONS
|
|
|
3916
4003
|
highlight, conversation: metadata|plain. note: markdown|plain.
|
|
3917
4004
|
equation: metadata.
|
|
3918
4005
|
--include SECTION extra sections, comma-separated: metadata, source, locations.
|
|
3919
|
-
document only (highlight/conversation/equation/note: metadata only
|
|
4006
|
+
document only (passage/highlight/conversation/equation/note: metadata only).
|
|
3920
4007
|
--pages RANGE restrict a document read to pages, e.g. 1,3-5. document only.
|
|
3921
4008
|
--max-chars-per-item N truncate each item's content to N chars, 1\u2013200000.
|
|
3922
4009
|
--cursor CURSOR continue one long document or note \u2014 use items[].nextCursor from the
|
|
@@ -3959,13 +4046,54 @@ OPTIONS
|
|
|
3959
4046
|
--force when signing in, replace an already-saved token.
|
|
3960
4047
|
|
|
3961
4048
|
Signing in saves your token on this machine. For scripts or an AI agent, set PAPIERS_TOKEN instead.`,
|
|
3962
|
-
|
|
4049
|
+
import: `papiers import \u2014 add a public PDF or webpage to your library.
|
|
4050
|
+
|
|
4051
|
+
USAGE
|
|
4052
|
+
papiers import URL [--json]
|
|
4053
|
+
papiers import-status OPERATION_ID [--json]
|
|
4054
|
+
|
|
4055
|
+
Needs a token created with "Allow document imports" (Settings -> API tokens).
|
|
4056
|
+
Import only sources the user approved. An import is queued, not finished:
|
|
4057
|
+
check import-status until it is ready or failed; any other status means it
|
|
4058
|
+
is still in progress. Ready means papiers read works on its documentId now.
|
|
4059
|
+
A status is as of that check: reprocessing or trashing the document can
|
|
4060
|
+
change it later.`,
|
|
4061
|
+
feed: `papiers feed \u2014 add links to your own Discover feed.
|
|
3963
4062
|
|
|
3964
4063
|
USAGE
|
|
3965
|
-
papiers
|
|
3966
|
-
papiers tokens revoke TOKEN_ID [--json]
|
|
4064
|
+
papiers feed add URL [--reason TEXT] [--json]
|
|
3967
4065
|
|
|
3968
|
-
|
|
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.`,
|
|
4075
|
+
highlight: `papiers highlight \u2014 highlight a passage in a saved PDF or webpage.
|
|
4076
|
+
|
|
4077
|
+
USAGE
|
|
4078
|
+
papiers highlight DOCUMENT_ID --start TEXT [--end TEXT]
|
|
4079
|
+
[--passage PASSAGE_REF | --pages N[-M]]
|
|
4080
|
+
[--note TEXT] [--color #rrggbb] [--json]
|
|
4081
|
+
|
|
4082
|
+
Needs a token created with "Allow highlights" (Settings -> API tokens).
|
|
4083
|
+
DOCUMENT_ID is a doc_ ID or papiers://item/... locator. In a PDF, name what you
|
|
4084
|
+
read: --passage is the reference of a search result in this document
|
|
4085
|
+
(doc_\u2026#p\u2026.\u2026), --pages the page or pages (3, 3-4 or 3,5) you read it on. The
|
|
4086
|
+
passage is only looked for there; a webpage is searched whole and takes neither.
|
|
4087
|
+
--start is the passage's first words (or all of a short passage); --end its
|
|
4088
|
+
last words, for a longer passage or one crossing a formula. The highlight runs
|
|
4089
|
+
from --start through --end, so formulas and footnote marks between need not be
|
|
4090
|
+
quoted; if either repeats within reach (that page and the next, a few
|
|
4091
|
+
paragraphs), add words to it. Quote both as you read them; punctuation, hyphens,
|
|
4092
|
+
spacing and formatting don't matter. Keep math out of --start and --end, even
|
|
4093
|
+
a single symbol like V or \u03B2t: what you read spells it differently from the
|
|
4094
|
+
page, so start and end on plain words. If the passage appears more than once,
|
|
4095
|
+
add words until it is unique. Highlight only passages the user asked for or
|
|
4096
|
+
approved.`,
|
|
3969
4097
|
doctor: `papiers doctor \u2014 check your setup, connection, and what's available.
|
|
3970
4098
|
|
|
3971
4099
|
USAGE
|
|
@@ -3981,10 +4109,18 @@ USAGE
|
|
|
3981
4109
|
var REFERENCE = `REFERENCE \u2014 IDs, piping, pagination, and limits.
|
|
3982
4110
|
|
|
3983
4111
|
ID PREFIXES
|
|
3984
|
-
doc_ document
|
|
3985
|
-
|
|
3986
|
-
|
|
3987
|
-
|
|
4112
|
+
doc_ document hl_ highlight cnv_ conversation
|
|
4113
|
+
nte_ note srch_ a saved search ranking (for browse)
|
|
4114
|
+
On read, the kind \u2014 and which --format/--include apply \u2014 is read from the ID.
|
|
4115
|
+
|
|
4116
|
+
PASSAGES AND EQUATIONS
|
|
4117
|
+
A passage or equation is a place in a document plus a fingerprint of its text:
|
|
4118
|
+
doc_<id>#p12.3f9c01aa passage 12 of that document
|
|
4119
|
+
doc_<id>#enode_812.77d0e2b1 an equation in that document
|
|
4120
|
+
It keeps working while that text is unchanged. If the document is processed
|
|
4121
|
+
again and the text changed, you get stale_reference: search or read the
|
|
4122
|
+
document again. Quote references in the shell ('doc_\u2026#p12.3f9c01aa'): some
|
|
4123
|
+
shells treat # specially.
|
|
3988
4124
|
|
|
3989
4125
|
RESOURCE LOCATORS
|
|
3990
4126
|
papiers://note/<uuid> papiers://highlight/<uuid>
|
|
@@ -4041,11 +4177,12 @@ var SUGGESTIBLE_COMMANDS = [
|
|
|
4041
4177
|
"auth",
|
|
4042
4178
|
"doctor",
|
|
4043
4179
|
"capabilities",
|
|
4044
|
-
"tokens",
|
|
4045
4180
|
"list",
|
|
4046
4181
|
"search",
|
|
4047
4182
|
"browse",
|
|
4048
4183
|
"read",
|
|
4184
|
+
"import",
|
|
4185
|
+
"highlight",
|
|
4049
4186
|
"version",
|
|
4050
4187
|
"help"
|
|
4051
4188
|
];
|
|
@@ -4098,7 +4235,8 @@ function parseCliArgs(argv) {
|
|
|
4098
4235
|
if (parsed.booleanFlags.has("all")) {
|
|
4099
4236
|
return { type: "help", all: true, ...global };
|
|
4100
4237
|
}
|
|
4101
|
-
const
|
|
4238
|
+
const named = command === "help" ? rest[0] : command;
|
|
4239
|
+
const topic = named === "import-status" ? "import" : named;
|
|
4102
4240
|
if (topic && HELP_TOPIC_NAMES.includes(topic)) {
|
|
4103
4241
|
return { type: "help", topic, ...global };
|
|
4104
4242
|
}
|
|
@@ -4125,14 +4263,72 @@ function parseCliArgs(argv) {
|
|
|
4125
4263
|
);
|
|
4126
4264
|
assertNoExtraPositionals(command, rest);
|
|
4127
4265
|
return { type: "capabilities", ...global };
|
|
4128
|
-
case "
|
|
4129
|
-
|
|
4130
|
-
|
|
4266
|
+
case "import":
|
|
4267
|
+
case "import-status": {
|
|
4268
|
+
assertAllowedFlags(parsed, NO_COMMAND_VALUE_FLAGS, command);
|
|
4269
|
+
assertAllowedBooleanFlags(parsed, NO_COMMAND_BOOLEAN_FLAGS, command);
|
|
4270
|
+
const [target, ...extra] = rest;
|
|
4271
|
+
assertNoExtraPositionals(command, extra);
|
|
4272
|
+
if (!target) {
|
|
4273
|
+
throw new CliUsageError(
|
|
4274
|
+
command === "import" ? "papiers import requires a URL." : "papiers import-status requires an operation ID."
|
|
4275
|
+
);
|
|
4276
|
+
}
|
|
4277
|
+
return command === "import" ? { type: "import", ...global, url: target } : { type: "import-status", ...global, operationId: target };
|
|
4278
|
+
}
|
|
4279
|
+
case "feed":
|
|
4280
|
+
return parseFeedCommand(rest, parsed, global);
|
|
4281
|
+
case "highlight": {
|
|
4282
|
+
assertAllowedFlags(
|
|
4283
|
+
parsed,
|
|
4284
|
+
/* @__PURE__ */ new Set([...GLOBAL_VALUE_FLAGS, ...HIGHLIGHT_VALUE_FLAGS]),
|
|
4285
|
+
command
|
|
4286
|
+
);
|
|
4287
|
+
assertAllowedBooleanFlags(parsed, NO_COMMAND_BOOLEAN_FLAGS, command);
|
|
4288
|
+
const [documentId, ...extra] = rest;
|
|
4289
|
+
assertNoExtraPositionals(command, extra);
|
|
4290
|
+
const start = singleFlagValue(parsed, "start");
|
|
4291
|
+
if (!documentId || !start) {
|
|
4292
|
+
throw new CliUsageError(
|
|
4293
|
+
"papiers highlight requires a document ID and --start."
|
|
4294
|
+
);
|
|
4295
|
+
}
|
|
4296
|
+
const passageId = singleFlagValue(parsed, "passage");
|
|
4297
|
+
const pagesFlag = singleFlagValue(parsed, "pages");
|
|
4298
|
+
if (passageId !== void 0 && pagesFlag !== void 0) {
|
|
4299
|
+
throw new CliUsageError("Give --passage or --pages, not both.");
|
|
4300
|
+
}
|
|
4301
|
+
const color = singleFlagValue(parsed, "color");
|
|
4302
|
+
if (color !== void 0 && !HIGHLIGHT_HEX_COLOR_REGEX.test(color)) {
|
|
4303
|
+
throw new CliUsageError(
|
|
4304
|
+
"--color must be a lowercase #rrggbb hex color, like #fde68a."
|
|
4305
|
+
);
|
|
4306
|
+
}
|
|
4307
|
+
const optional = (name) => {
|
|
4308
|
+
const value = singleFlagValue(parsed, name);
|
|
4309
|
+
return value === void 0 ? {} : { [name]: value };
|
|
4310
|
+
};
|
|
4311
|
+
return {
|
|
4312
|
+
type: "highlight",
|
|
4313
|
+
...global,
|
|
4314
|
+
documentId,
|
|
4315
|
+
start,
|
|
4316
|
+
...optional("end"),
|
|
4317
|
+
...passageId === void 0 ? {} : { passageId },
|
|
4318
|
+
...pagesFlag === void 0 ? {} : { pages: parsePages(pagesFlag) },
|
|
4319
|
+
...optional("note"),
|
|
4320
|
+
...optional("color")
|
|
4321
|
+
};
|
|
4322
|
+
}
|
|
4131
4323
|
case "list": {
|
|
4132
4324
|
assertAllowedFlags(parsed, LIST_VALUE_FLAGS, "list");
|
|
4133
4325
|
assertAllowedBooleanFlags(parsed, IDS_PIPELINE_BOOLEAN_FLAGS, "list");
|
|
4134
4326
|
assertNoExtraPositionals(command, rest);
|
|
4135
|
-
const listDocumentIds = parseDocumentIdFlagValues(
|
|
4327
|
+
const listDocumentIds = parseDocumentIdFlagValues(
|
|
4328
|
+
parsed,
|
|
4329
|
+
"list",
|
|
4330
|
+
parseListKind(parsed) === "highlight"
|
|
4331
|
+
);
|
|
4136
4332
|
const listOutput = parseIdsOutput(parsed, "list");
|
|
4137
4333
|
return {
|
|
4138
4334
|
type: "list",
|
|
@@ -4226,33 +4422,31 @@ function parsePrettyOutput(parsed, idsOnly) {
|
|
|
4226
4422
|
}
|
|
4227
4423
|
return true;
|
|
4228
4424
|
}
|
|
4229
|
-
function
|
|
4230
|
-
const [subcommand,
|
|
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);
|
|
4231
4429
|
switch (subcommand) {
|
|
4232
|
-
case "
|
|
4233
|
-
|
|
4430
|
+
case "add": {
|
|
4431
|
+
assertAllowedFlags(
|
|
4234
4432
|
parsed,
|
|
4235
|
-
|
|
4236
|
-
|
|
4433
|
+
/* @__PURE__ */ new Set([...GLOBAL_VALUE_FLAGS, "reason"]),
|
|
4434
|
+
name
|
|
4237
4435
|
);
|
|
4238
|
-
assertNoExtraPositionals(
|
|
4239
|
-
|
|
4240
|
-
|
|
4241
|
-
|
|
4242
|
-
|
|
4243
|
-
|
|
4244
|
-
|
|
4245
|
-
|
|
4246
|
-
|
|
4247
|
-
|
|
4248
|
-
}
|
|
4249
|
-
assertNoExtraPositionals("tokens revoke", extra);
|
|
4250
|
-
if (!isUuid(tokenId)) {
|
|
4251
|
-
throw new CliUsageError("papiers tokens revoke requires a token UUID.");
|
|
4252
|
-
}
|
|
4253
|
-
return { type: "tokens-revoke", ...global, tokenId };
|
|
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
|
+
}
|
|
4254
4446
|
default:
|
|
4255
|
-
throw new CliUsageError(
|
|
4447
|
+
throw new CliUsageError(
|
|
4448
|
+
"papiers feed takes add. Run papiers feed --help."
|
|
4449
|
+
);
|
|
4256
4450
|
}
|
|
4257
4451
|
}
|
|
4258
4452
|
function parseAuthCommand(rest, parsed, global) {
|
|
@@ -4357,7 +4551,7 @@ function buildReadRequest(parsed) {
|
|
|
4357
4551
|
};
|
|
4358
4552
|
}
|
|
4359
4553
|
function buildListRequest(parsed, documentIds) {
|
|
4360
|
-
const kind =
|
|
4554
|
+
const kind = parseListKind(parsed);
|
|
4361
4555
|
const since = parseSinceFlag(parsed, kind, "list");
|
|
4362
4556
|
if (kind !== "document") {
|
|
4363
4557
|
if (documentIds?.length && kind !== "highlight") {
|
|
@@ -4495,7 +4689,7 @@ function parseSinceFlag(parsed, kind, command) {
|
|
|
4495
4689
|
}
|
|
4496
4690
|
return new Date(parsedMs).toISOString();
|
|
4497
4691
|
}
|
|
4498
|
-
function parseDocumentIdFlagValues(parsed, command) {
|
|
4692
|
+
function parseDocumentIdFlagValues(parsed, command, acceptsItemLocators = false) {
|
|
4499
4693
|
const rawDocumentIds = parsed.flags.get("document-id");
|
|
4500
4694
|
if (!rawDocumentIds?.length) {
|
|
4501
4695
|
return void 0;
|
|
@@ -4513,9 +4707,10 @@ function parseDocumentIdFlagValues(parsed, command) {
|
|
|
4513
4707
|
`papiers ${command} --document-id file references must include a file path after @.`
|
|
4514
4708
|
);
|
|
4515
4709
|
}
|
|
4516
|
-
|
|
4710
|
+
const isDocumentId = acceptsItemLocators ? isDocumentReadIdentifier : isDocumentPublicId;
|
|
4711
|
+
if (documentIds.some((id) => !isDocumentIdSource(id) && !isDocumentId(id))) {
|
|
4517
4712
|
throw new CliUsageError(
|
|
4518
|
-
`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.`
|
|
4519
4714
|
);
|
|
4520
4715
|
}
|
|
4521
4716
|
const explicitDocumentIdCount = documentIds.filter(
|
|
@@ -4649,7 +4844,13 @@ function validateReadOptionsForKind(parsed, kind, format) {
|
|
|
4649
4844
|
"Public passage read supports --format markdown or --format plain."
|
|
4650
4845
|
);
|
|
4651
4846
|
}
|
|
4652
|
-
|
|
4847
|
+
const includes = parseReadInclude(parsed);
|
|
4848
|
+
if (includes?.some((include) => include !== "metadata")) {
|
|
4849
|
+
throw new CliUsageError(
|
|
4850
|
+
"Public passage read supports only --include metadata."
|
|
4851
|
+
);
|
|
4852
|
+
}
|
|
4853
|
+
rejectReadFlagsForKind(parsed, "passage", ["pages", "cursor"]);
|
|
4653
4854
|
return;
|
|
4654
4855
|
}
|
|
4655
4856
|
if (kind === "highlight") {
|
|
@@ -4834,19 +5035,24 @@ function parseGlobalOptions(parsed) {
|
|
|
4834
5035
|
apiBaseUrl: singleFlagValue(parsed, "api-url")
|
|
4835
5036
|
};
|
|
4836
5037
|
}
|
|
4837
|
-
function
|
|
5038
|
+
function parseListKind(parsed) {
|
|
4838
5039
|
const kind = singleFlagValue(parsed, "kind") ?? "document";
|
|
4839
5040
|
const normalized = normalizeCliPublicKind(kind);
|
|
5041
|
+
if (normalized === "passage" || normalized === "equation") {
|
|
5042
|
+
throw new CliUsageError(
|
|
5043
|
+
`papiers list does not list ${normalized}s. Read a document (papiers read doc_\u2026) to page through its ${normalized}s in order, or search for them.`
|
|
5044
|
+
);
|
|
5045
|
+
}
|
|
4840
5046
|
if (normalized) {
|
|
4841
5047
|
return normalized;
|
|
4842
5048
|
}
|
|
4843
5049
|
if (kind.trim().toLowerCase() === "all") {
|
|
4844
5050
|
throw new CliUsageError(
|
|
4845
|
-
|
|
5051
|
+
"papiers list does not support --kind all here; multi-kind requests are available via papiers search --kind all."
|
|
4846
5052
|
);
|
|
4847
5053
|
}
|
|
4848
5054
|
throw new CliUsageError(
|
|
4849
|
-
`papiers
|
|
5055
|
+
`papiers list supports --kind document, highlight, conversation, or note; received "${kind}".${didYouMeanKind(kind)}`
|
|
4850
5056
|
);
|
|
4851
5057
|
}
|
|
4852
5058
|
function normalizeCliPublicKind(value) {
|
|
@@ -5025,11 +5231,6 @@ function singleFlagValue(parsed, name) {
|
|
|
5025
5231
|
}
|
|
5026
5232
|
return values[0];
|
|
5027
5233
|
}
|
|
5028
|
-
function isUuid(value) {
|
|
5029
|
-
return /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/iu.test(
|
|
5030
|
-
value
|
|
5031
|
-
);
|
|
5032
|
-
}
|
|
5033
5234
|
function splitCommaSeparatedValues(rawValue) {
|
|
5034
5235
|
return rawValue.split(",").map((value) => value.trim()).filter(Boolean);
|
|
5035
5236
|
}
|
|
@@ -5045,6 +5246,26 @@ function pruneUndefined(value) {
|
|
|
5045
5246
|
Object.entries(value).filter(([, entry]) => entry !== void 0)
|
|
5046
5247
|
);
|
|
5047
5248
|
}
|
|
5249
|
+
function parsePages(value) {
|
|
5250
|
+
const pages = [];
|
|
5251
|
+
for (const part of value.split(",")) {
|
|
5252
|
+
const match = /^\s*(\d+)\s*(?:-\s*(\d+)\s*)?$/.exec(part);
|
|
5253
|
+
const first = match ? Number(match[1]) : Number.NaN;
|
|
5254
|
+
const last = match?.[2] ? Number(match[2]) : first;
|
|
5255
|
+
if (!(first >= 1 && first <= last && last <= PAPIERS_HIGHLIGHT_MAX_PAGE)) {
|
|
5256
|
+
throw new CliUsageError(
|
|
5257
|
+
`--pages must be a page, a range like 3-4, or a list like 3,5, of pages up to ${PAPIERS_HIGHLIGHT_MAX_PAGE}.`
|
|
5258
|
+
);
|
|
5259
|
+
}
|
|
5260
|
+
if (pages.length + (last - first + 1) > PAPIERS_HIGHLIGHT_MAX_SCOPE_PAGES) {
|
|
5261
|
+
throw new CliUsageError(
|
|
5262
|
+
`--pages can name at most ${PAPIERS_HIGHLIGHT_MAX_SCOPE_PAGES} pages.`
|
|
5263
|
+
);
|
|
5264
|
+
}
|
|
5265
|
+
for (let page = first; page <= last; page++) pages.push(page);
|
|
5266
|
+
}
|
|
5267
|
+
return pages;
|
|
5268
|
+
}
|
|
5048
5269
|
|
|
5049
5270
|
// src/capabilities.ts
|
|
5050
5271
|
var CAPABILITIES_ACCOUNT_KEYS = [
|
|
@@ -5074,11 +5295,11 @@ function assertSupportedDocumentCapabilities(value) {
|
|
|
5074
5295
|
assertNonEmptyString2("capabilities account.userId", account.userId);
|
|
5075
5296
|
assertExactString("capabilities account.profile", account.profile, "pat-v1");
|
|
5076
5297
|
const scopes = assertStringArray("capabilities scopes", capabilities.scopes);
|
|
5077
|
-
|
|
5078
|
-
|
|
5079
|
-
|
|
5080
|
-
|
|
5081
|
-
|
|
5298
|
+
if (!PAPIERS_PUBLIC_DATA_PLANE_SCOPES.every((s) => scopes.includes(s))) {
|
|
5299
|
+
throw new Error(
|
|
5300
|
+
`capabilities scopes was ${scopes.join(", ") || "empty"}; expected every public read scope.`
|
|
5301
|
+
);
|
|
5302
|
+
}
|
|
5082
5303
|
const searchKinds = assertStringArray(
|
|
5083
5304
|
"capabilities searchKinds",
|
|
5084
5305
|
capabilities.searchKinds
|
|
@@ -5740,22 +5961,45 @@ async function runCli(argv, dependencies = {}) {
|
|
|
5740
5961
|
);
|
|
5741
5962
|
return 0;
|
|
5742
5963
|
}
|
|
5743
|
-
case "
|
|
5744
|
-
|
|
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;
|
|
5973
|
+
case "import":
|
|
5974
|
+
writeJson(
|
|
5745
5975
|
stdout,
|
|
5746
|
-
await
|
|
5747
|
-
|
|
5976
|
+
await importDocument(config, resolveFetch(dependencies.fetch), {
|
|
5977
|
+
schemaVersion: PAPIERS_SCHEMA_VERSIONS.importRequest,
|
|
5978
|
+
url: command.url,
|
|
5979
|
+
submissionId: randomUUID2()
|
|
5980
|
+
})
|
|
5748
5981
|
);
|
|
5749
5982
|
return 0;
|
|
5750
|
-
case "
|
|
5751
|
-
|
|
5983
|
+
case "highlight": {
|
|
5984
|
+
const { type: _, json: __, apiBaseUrl: ___, ...highlight } = command;
|
|
5985
|
+
writeJson(
|
|
5752
5986
|
stdout,
|
|
5753
|
-
await
|
|
5987
|
+
await highlightDocument(config, resolveFetch(dependencies.fetch), {
|
|
5988
|
+
schemaVersion: PAPIERS_SCHEMA_VERSIONS.highlightRequest,
|
|
5989
|
+
...highlight,
|
|
5990
|
+
referenceId: randomUUID2()
|
|
5991
|
+
})
|
|
5992
|
+
);
|
|
5993
|
+
return 0;
|
|
5994
|
+
}
|
|
5995
|
+
case "import-status":
|
|
5996
|
+
writeJson(
|
|
5997
|
+
stdout,
|
|
5998
|
+
await getImportStatus(
|
|
5754
5999
|
config,
|
|
5755
6000
|
resolveFetch(dependencies.fetch),
|
|
5756
|
-
command.
|
|
5757
|
-
)
|
|
5758
|
-
command.json
|
|
6001
|
+
command.operationId
|
|
6002
|
+
)
|
|
5759
6003
|
);
|
|
5760
6004
|
return 0;
|
|
5761
6005
|
case "list":
|
|
@@ -6016,50 +6260,6 @@ function writeAuthInspectOutput(stdout, output, json) {
|
|
|
6016
6260
|
`
|
|
6017
6261
|
);
|
|
6018
6262
|
}
|
|
6019
|
-
function writeTokenListOutput(stdout, output, json) {
|
|
6020
|
-
if (json) {
|
|
6021
|
-
writeJson(stdout, output);
|
|
6022
|
-
return;
|
|
6023
|
-
}
|
|
6024
|
-
if (output.tokens.length === 0) {
|
|
6025
|
-
stdout.write(
|
|
6026
|
-
`No active Papiers tokens found. requestId=${output.requestId}
|
|
6027
|
-
`
|
|
6028
|
-
);
|
|
6029
|
-
return;
|
|
6030
|
-
}
|
|
6031
|
-
const lines = [
|
|
6032
|
-
`Papiers tokens requestId=${output.requestId}`,
|
|
6033
|
-
...output.tokens.map(
|
|
6034
|
-
(token) => [
|
|
6035
|
-
token.tokenId,
|
|
6036
|
-
token.name,
|
|
6037
|
-
`scopes=${token.scopes.join(",")}`,
|
|
6038
|
-
`created=${token.createdAt}`,
|
|
6039
|
-
`expires=${token.expiresAt ?? "never"}`,
|
|
6040
|
-
`lastUsed=${token.lastUsedAt ?? "never"}`
|
|
6041
|
-
].join(" | ")
|
|
6042
|
-
)
|
|
6043
|
-
];
|
|
6044
|
-
stdout.write(`${redactSensitiveText(lines.join("\n"))}
|
|
6045
|
-
`);
|
|
6046
|
-
}
|
|
6047
|
-
function writeTokenRevokeOutput(stdout, output, json) {
|
|
6048
|
-
if (json) {
|
|
6049
|
-
writeJson(stdout, output);
|
|
6050
|
-
return;
|
|
6051
|
-
}
|
|
6052
|
-
const state = output.revoked ? "revoked" : "already revoked";
|
|
6053
|
-
stdout.write(
|
|
6054
|
-
`${redactSensitiveText(
|
|
6055
|
-
[
|
|
6056
|
-
`Token ${output.tokenId} ${state}. requestId=${output.requestId}`,
|
|
6057
|
-
"Local auth files were not changed; run papiers auth logout if this was your configured token."
|
|
6058
|
-
].join("\n")
|
|
6059
|
-
)}
|
|
6060
|
-
`
|
|
6061
|
-
);
|
|
6062
|
-
}
|
|
6063
6263
|
async function runAuthInspect(params) {
|
|
6064
6264
|
const capabilities = await getCapabilities(params.config, params.fetchImpl);
|
|
6065
6265
|
assertCliSupportedCapabilities(capabilities);
|
|
@@ -6613,9 +6813,9 @@ function validateExpandedReadRequest(request, ids, requestedReadKind) {
|
|
|
6613
6813
|
"Public passage read supports --format markdown or --format plain."
|
|
6614
6814
|
);
|
|
6615
6815
|
}
|
|
6616
|
-
if (request.include?.
|
|
6816
|
+
if (request.include?.some((include) => include !== "metadata")) {
|
|
6617
6817
|
throw new CliUsageError(
|
|
6618
|
-
"Public passage read
|
|
6818
|
+
"Public passage read supports only --include metadata."
|
|
6619
6819
|
);
|
|
6620
6820
|
}
|
|
6621
6821
|
if (request.scope?.pages || request.scope?.sectionId) {
|