@paneui/core 0.0.11 → 0.0.13

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/dist/client.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { TemplateRecord, TemplateSummary, TemplateType, TemplateVersion, CreateArtifactResponse, CreatePaneRequest, CreatePaneResponse, EventsPage, FeedbackPage, FeedbackSubmission, FeedbackType, KeyInfo, MintParticipantResponse, PaneEvent, ParticipantsList, SerializedRecord, PaneState, PanesPage, TasteInfo, TrashListResponse } from "./types.js";
1
+ import type { TemplateRecord, TemplateSummary, TemplateType, TemplateVersion, CreateArtifactResponse, CreatePaneRequest, CreatePaneResponse, EventsPage, FeedbackPage, FeedbackSubmission, FeedbackType, KeyInfo, MintParticipantResponse, PaneEvent, ParticipantsList, SerializedRecord, PaneState, PanesPage, TasteInfo, TrashListResponse, UpgradePaneResponse } from "./types.js";
2
2
  import type { ListPanesQuery } from "./schemas.js";
3
3
  export interface ClientOptions {
4
4
  /** Relay base URL, e.g. https://pane.example.com. Trailing slash is trimmed. */
@@ -81,6 +81,37 @@ export interface PatchArtifactMetadataRequest {
81
81
  * `null` to clear it. */
82
82
  icon_attachment_id?: string | null;
83
83
  }
84
+ /** One identity-share grant as returned by the grants endpoints. */
85
+ export interface PaneGrant {
86
+ id: string;
87
+ /** Set once the invitee logs in and the grant binds; null while pending. */
88
+ human_id: string | null;
89
+ /** The invited email, or null for a grant created directly against a human. */
90
+ invite_email: string | null;
91
+ /** "participant" (read + emit) | "viewer" (read-only). */
92
+ role: string;
93
+ /** ISO timestamp the grant was bound to a human, or null while pending. */
94
+ accepted_at: string | null;
95
+ }
96
+ /**
97
+ * The pane-id (`/p/:paneId`) access mode. Governs ONLY the pane-id path; token
98
+ * (`/s/<token>`) links are unaffected and keep working in every mode.
99
+ * - "invite_only" — only invited emails (after login) may open /p.
100
+ * - "link" — anyone with the /p URL opens it read-only, no login.
101
+ * - "public" — anyone opens it read-only, no login (discovery TBD).
102
+ */
103
+ export type AccessMode = "invite_only" | "link" | "public";
104
+ /** Response from GET /v1/panes/:id/grants. */
105
+ export interface PaneGrantsList {
106
+ pane_id: string;
107
+ access_mode: AccessMode;
108
+ items: PaneGrant[];
109
+ }
110
+ /** Response from PATCH /v1/panes/:id/visibility. */
111
+ export interface PaneVisibility {
112
+ pane_id: string;
113
+ access_mode: AccessMode;
114
+ }
84
115
  /**
85
116
  * An error thrown by the typed operations when the relay returns a non-2xx
86
117
  * response (or the request fails outright). Carries the HTTP status and the
@@ -382,6 +413,28 @@ export declare class PaneClient {
382
413
  mintParticipant(paneId: string, opts?: {
383
414
  kind?: "human";
384
415
  }): Promise<MintParticipantResponse>;
416
+ /**
417
+ * POST /v1/panes/:id/upgrade — re-pin a live pane to another version of the
418
+ * SAME template (#267), swapping its HTML and schemas in place without
419
+ * minting a new pane (the human keeps the same URL). Events already on disk
420
+ * are never rewritten — each carries the template version it was authored
421
+ * under (#268).
422
+ *
423
+ * `opts.template_version` defaults to the template head's latest version.
424
+ * `opts.compat` defaults to `"strict"`: the relay refuses with a 422
425
+ * `schema_incompatible_upgrade` (its `details.breaks` lists the offending
426
+ * paths) when the target schema narrows the current one — i.e. when events
427
+ * written under the old schema would no longer validate. Pass `"force"` to
428
+ * apply the upgrade anyway, accepting that old events may no longer match
429
+ * the new schema.
430
+ *
431
+ * Returns `{ upgraded: false }` (idempotent no-op) when the pane is already
432
+ * on the target version.
433
+ */
434
+ upgradePane(paneId: string, opts?: {
435
+ template_version?: number;
436
+ compat?: "strict" | "force";
437
+ }): Promise<UpgradePaneResponse>;
385
438
  /**
386
439
  * DELETE /v1/panes/:id/participants/:participant_id — revoke a single
387
440
  * participant URL. The pane's other participants (and the agent's own
@@ -393,6 +446,33 @@ export declare class PaneClient {
393
446
  * actively kicked in v1; new HTTP and WS connections are refused.
394
447
  */
395
448
  revokeParticipant(paneId: string, participantId: string): Promise<void>;
449
+ /**
450
+ * GET /v1/panes/:id/grants — list the pane's identity-share grants plus
451
+ * its current `access_mode`. Owner/agent-scope only.
452
+ */
453
+ listGrants(paneId: string): Promise<PaneGrantsList>;
454
+ /**
455
+ * POST /v1/panes/:id/grants — invite a human by email. Upserts by email,
456
+ * so re-inviting the same address adjusts the role in place. Role defaults
457
+ * to "participant" (read + emit); pass "viewer" for read-only.
458
+ */
459
+ createGrant(paneId: string, opts: {
460
+ email: string;
461
+ role?: "participant" | "viewer";
462
+ }): Promise<PaneGrant>;
463
+ /**
464
+ * DELETE /v1/panes/:id/grants/:grantId — revoke one grant. Idempotent: a
465
+ * missing/already-removed grant returns 204.
466
+ */
467
+ revokeGrant(paneId: string, grantId: string): Promise<void>;
468
+ /**
469
+ * PATCH /v1/panes/:id/visibility — set the pane's /p access mode.
470
+ * - "invite_only" — only invited emails (after login) may open /p.
471
+ * - "link" — anyone with the /p URL opens it READ-ONLY, no login.
472
+ * - "public" — anyone opens it READ-ONLY, no login (discovery TBD).
473
+ * Token (`/s/<token>`) links are independent of this and keep working.
474
+ */
475
+ setPaneVisibility(paneId: string, accessMode: AccessMode): Promise<PaneVisibility>;
396
476
  /**
397
477
  * DELETE /v1/panes/:id — close/delete a pane. Idempotent on the relay
398
478
  * side (an already-closed pane still returns 204 with no body).
package/dist/client.js CHANGED
@@ -578,6 +578,35 @@ export class PaneClient {
578
578
  this.fail(r);
579
579
  return this.asObject(r);
580
580
  }
581
+ /**
582
+ * POST /v1/panes/:id/upgrade — re-pin a live pane to another version of the
583
+ * SAME template (#267), swapping its HTML and schemas in place without
584
+ * minting a new pane (the human keeps the same URL). Events already on disk
585
+ * are never rewritten — each carries the template version it was authored
586
+ * under (#268).
587
+ *
588
+ * `opts.template_version` defaults to the template head's latest version.
589
+ * `opts.compat` defaults to `"strict"`: the relay refuses with a 422
590
+ * `schema_incompatible_upgrade` (its `details.breaks` lists the offending
591
+ * paths) when the target schema narrows the current one — i.e. when events
592
+ * written under the old schema would no longer validate. Pass `"force"` to
593
+ * apply the upgrade anyway, accepting that old events may no longer match
594
+ * the new schema.
595
+ *
596
+ * Returns `{ upgraded: false }` (idempotent no-op) when the pane is already
597
+ * on the target version.
598
+ */
599
+ async upgradePane(paneId, opts = {}) {
600
+ const body = {};
601
+ if (opts.template_version !== undefined)
602
+ body["template_version"] = opts.template_version;
603
+ if (opts.compat !== undefined)
604
+ body["compat"] = opts.compat;
605
+ const r = await this.call("POST", `/v1/panes/${encodeURIComponent(paneId)}/upgrade`, body);
606
+ if (!r.ok)
607
+ this.fail(r);
608
+ return this.asObject(r);
609
+ }
581
610
  /**
582
611
  * DELETE /v1/panes/:id/participants/:participant_id — revoke a single
583
612
  * participant URL. The pane's other participants (and the agent's own
@@ -593,6 +622,51 @@ export class PaneClient {
593
622
  if (!r.ok)
594
623
  this.fail(r);
595
624
  }
625
+ /**
626
+ * GET /v1/panes/:id/grants — list the pane's identity-share grants plus
627
+ * its current `access_mode`. Owner/agent-scope only.
628
+ */
629
+ async listGrants(paneId) {
630
+ const r = await this.call("GET", `/v1/panes/${encodeURIComponent(paneId)}/grants`);
631
+ if (!r.ok)
632
+ this.fail(r);
633
+ return this.asObject(r);
634
+ }
635
+ /**
636
+ * POST /v1/panes/:id/grants — invite a human by email. Upserts by email,
637
+ * so re-inviting the same address adjusts the role in place. Role defaults
638
+ * to "participant" (read + emit); pass "viewer" for read-only.
639
+ */
640
+ async createGrant(paneId, opts) {
641
+ const r = await this.call("POST", `/v1/panes/${encodeURIComponent(paneId)}/grants`, opts.role
642
+ ? { email: opts.email, role: opts.role }
643
+ : { email: opts.email });
644
+ if (!r.ok)
645
+ this.fail(r);
646
+ return this.asObject(r);
647
+ }
648
+ /**
649
+ * DELETE /v1/panes/:id/grants/:grantId — revoke one grant. Idempotent: a
650
+ * missing/already-removed grant returns 204.
651
+ */
652
+ async revokeGrant(paneId, grantId) {
653
+ const r = await this.call("DELETE", `/v1/panes/${encodeURIComponent(paneId)}/grants/${encodeURIComponent(grantId)}`);
654
+ if (!r.ok)
655
+ this.fail(r);
656
+ }
657
+ /**
658
+ * PATCH /v1/panes/:id/visibility — set the pane's /p access mode.
659
+ * - "invite_only" — only invited emails (after login) may open /p.
660
+ * - "link" — anyone with the /p URL opens it READ-ONLY, no login.
661
+ * - "public" — anyone opens it READ-ONLY, no login (discovery TBD).
662
+ * Token (`/s/<token>`) links are independent of this and keep working.
663
+ */
664
+ async setPaneVisibility(paneId, accessMode) {
665
+ const r = await this.call("PATCH", `/v1/panes/${encodeURIComponent(paneId)}/visibility`, { access_mode: accessMode });
666
+ if (!r.ok)
667
+ this.fail(r);
668
+ return this.asObject(r);
669
+ }
596
670
  /**
597
671
  * DELETE /v1/panes/:id — close/delete a pane. Idempotent on the relay
598
672
  * side (an already-closed pane still returns 204 with no body).
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  export { PaneClient, PaneApiError } from "./client.js";
2
- export type { ClientOptions, RelayResponse, CreateArtifactRequest, CreateArtifactVersionRequest, PatchArtifactMetadataRequest, AttachmentRef, UploadBlobOptions, PresignBlobOptions, AttachmentTokenMintResponse, ListBlobsOptions, AttachmentTokenAuditEntry, AttachmentTokenListResponse, QueryResponse, } from "./client.js";
2
+ export type { ClientOptions, RelayResponse, CreateArtifactRequest, CreateArtifactVersionRequest, PatchArtifactMetadataRequest, AttachmentRef, UploadBlobOptions, PresignBlobOptions, AttachmentTokenMintResponse, ListBlobsOptions, AttachmentTokenAuditEntry, AttachmentTokenListResponse, QueryResponse, PaneGrant, PaneGrantsList, PaneVisibility, AccessMode, } from "./client.js";
3
3
  export { openStream } from "./stream.js";
4
4
  export type { OpenStreamOptions, StreamHandlers, StreamHandle, } from "./stream.js";
5
5
  export { registerAgent } from "./register.js";
@@ -9,4 +9,4 @@ export type { CreatePaneInput, ListPanesStatus, ListPanesQuery, MintParticipantI
9
9
  export { validateIconEmoji, isValidIconEmoji, isRasterImageMime, RASTER_ICON_MIME_ALLOWLIST, MAX_ICON_EMOJI_BYTES, } from "./icons.js";
10
10
  export type { RasterIconMime } from "./icons.js";
11
11
  export { MAX_EVENT_TYPE_LENGTH, MAX_IDEMPOTENCY_KEY_LENGTH, MAX_RESPONSE_SNIPPET_LENGTH, MAX_FRAME_SNIPPET_LENGTH, } from "./limits.js";
12
- export type { AuthorKind, PaneEvent, SerializedRecord, DeletedRecordRef, RecordDeltaMessage, Template, TemplateType, TemplateVersion, TemplateRecord, TemplateSummary, CreateArtifactResponse, KeyInfo, TasteInfo, FeedbackType, FeedbackSubmission, FeedbackRecord, FeedbackPage, Callback, CreatePaneRequest, CreatePaneResponse, PaneState, EventsPage, ParticipantSummary, ParticipantsList, PaneSummary, PanesPage, MintParticipantResponse, TrashedPaneEntry, TrashedTemplateEntry, TrashListResponse, RelayError, } from "./types.js";
12
+ export type { AuthorKind, PaneEvent, SerializedRecord, DeletedRecordRef, RecordDeltaMessage, Template, TemplateType, TemplateVersion, TemplateRecord, TemplateSummary, CreateArtifactResponse, KeyInfo, TasteInfo, FeedbackType, FeedbackSubmission, FeedbackRecord, FeedbackPage, Callback, CreatePaneRequest, CreatePaneResponse, PaneState, EventsPage, ParticipantSummary, ParticipantsList, PaneSummary, PanesPage, MintParticipantResponse, UpgradeBreak, UpgradePaneResponse, TrashedPaneEntry, TrashedTemplateEntry, TrashListResponse, RelayError, } from "./types.js";
package/dist/types.d.ts CHANGED
@@ -209,6 +209,31 @@ export interface MintParticipantResponse {
209
209
  url: string;
210
210
  created_at: string;
211
211
  }
212
+ /** One break flagged by the schema-compat gate when upgrading a pane to a
213
+ * template version whose schema narrows the current one. */
214
+ export interface UpgradeBreak {
215
+ /** JSON-pointer-ish path to the offending schema location. */
216
+ path: string;
217
+ /** Human-readable description of why the change is incompatible. */
218
+ message: string;
219
+ }
220
+ /** Response from POST /v1/panes/:id/upgrade — the result of re-pinning a live
221
+ * pane to another version of the same template (#267). */
222
+ export interface UpgradePaneResponse {
223
+ pane_id: string;
224
+ /** The version id the pane now points at. */
225
+ template_version_id: string;
226
+ /** Denormalised integer version number the pane now points at. */
227
+ template_version: number;
228
+ /** `false` when the pane was already on the target version (idempotent
229
+ * no-op); `true` when the re-pin was applied. */
230
+ upgraded: boolean;
231
+ /** Schema-compat breaks detected against the target version. Empty on a
232
+ * clean upgrade; populated (and applied anyway) on `compat: "force"`. */
233
+ breaks: UpgradeBreak[];
234
+ /** The compat mode the upgrade ran under. */
235
+ compat: "strict" | "force";
236
+ }
212
237
  /** One immutable version of an template's content. */
213
238
  export interface TemplateVersion {
214
239
  id: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@paneui/core",
3
- "version": "0.0.11",
3
+ "version": "0.0.13",
4
4
  "description": "Pane relay client: typed HTTP + WebSocket operations against a Pane relay. Framework-free.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -53,6 +53,6 @@
53
53
  "@types/node": "^25.9.1",
54
54
  "@types/ws": "^8.18.1",
55
55
  "typescript": "^6.0.3",
56
- "vitest": "^4.1.6"
56
+ "vitest": "^4.1.8"
57
57
  }
58
58
  }