@pantheon-systems/css-client 0.16.0-canary-20260911222513 → 0.16.0

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.
Files changed (53) hide show
  1. package/dist/auth.d.ts +18 -1
  2. package/dist/client.d.ts +8 -2
  3. package/dist/client.js +5 -1
  4. package/dist/endpoints/agent-edit.d.ts +12 -8
  5. package/dist/endpoints/agent-edit.js +3 -2
  6. package/dist/endpoints/agent-registry.d.ts +1 -1
  7. package/dist/endpoints/auth.d.ts +7 -0
  8. package/dist/endpoints/auth.js +11 -0
  9. package/dist/endpoints/base.d.ts +1 -1
  10. package/dist/endpoints/branches.d.ts +1 -1
  11. package/dist/endpoints/checkpoints.d.ts +1 -1
  12. package/dist/endpoints/documents.d.ts +1 -1
  13. package/dist/endpoints/index.d.ts +2 -0
  14. package/dist/endpoints/index.js +2 -0
  15. package/dist/endpoints/merge.d.ts +1 -1
  16. package/dist/endpoints/merge.js +1 -1
  17. package/dist/endpoints/migration-conflicts.d.ts +1 -1
  18. package/dist/endpoints/presence.d.ts +1 -1
  19. package/dist/endpoints/queries.d.ts +1 -1
  20. package/dist/endpoints/relations.d.ts +28 -5
  21. package/dist/endpoints/relations.js +15 -2
  22. package/dist/endpoints/sites.d.ts +6 -1
  23. package/dist/endpoints/sites.js +6 -0
  24. package/dist/endpoints/templates.d.ts +1 -1
  25. package/dist/endpoints/threads.d.ts +64 -0
  26. package/dist/endpoints/threads.js +70 -0
  27. package/dist/endpoints/translations.d.ts +1 -1
  28. package/dist/endpoints/versions.d.ts +1 -1
  29. package/dist/index.d.ts +4 -2
  30. package/dist/index.js +1 -0
  31. package/dist/realtime.d.ts +5 -1
  32. package/dist/realtime.js +3 -0
  33. package/dist/sdk-version.d.ts +1 -1
  34. package/dist/sdk-version.js +1 -1
  35. package/dist/{types.d.ts → types/index.d.ts} +66 -2
  36. package/dist/{types.js → types/index.js} +1 -0
  37. package/dist/types/site-members.d.ts +26 -0
  38. package/dist/types/site-members.js +1 -0
  39. package/dist/types/threads/agent.d.ts +36 -0
  40. package/dist/types/threads/agent.js +7 -0
  41. package/dist/types/threads/api.d.ts +29 -0
  42. package/dist/types/threads/api.js +1 -0
  43. package/dist/types/threads/comment.d.ts +57 -0
  44. package/dist/types/threads/comment.js +1 -0
  45. package/dist/types/threads/context.d.ts +9 -0
  46. package/dist/types/threads/context.js +1 -0
  47. package/dist/types/threads/event.d.ts +23 -0
  48. package/dist/types/threads/event.js +1 -0
  49. package/dist/types/threads/index.d.ts +11 -0
  50. package/dist/types/threads/index.js +1 -0
  51. package/dist/types/threads/thread.d.ts +22 -0
  52. package/dist/types/threads/thread.js +1 -0
  53. package/package.json +1 -1
package/dist/auth.d.ts CHANGED
@@ -1,8 +1,25 @@
1
1
  /**
2
2
  * P1 Client Authentication Utilities
3
3
  *
4
- * Functions for creating authentication providers.
4
+ * Functions for creating authentication providers, and role/permission types.
5
5
  */
6
+ export type RoleName = 'ADMIN' | 'EDITOR' | 'VIEWER' | 'NO_ACCESS';
7
+ export interface RolePermissions {
8
+ canView: boolean;
9
+ canEdit: boolean;
10
+ canCreateBranch: boolean;
11
+ canEditDocuments: boolean;
12
+ canCreateCheckpoint: boolean;
13
+ canProposeMerge: boolean;
14
+ canMerge: boolean;
15
+ canMergeToMain: boolean;
16
+ canManageGrants: boolean;
17
+ canManageTemplates: boolean;
18
+ }
19
+ export interface ViewerRole {
20
+ roleName: RoleName;
21
+ permissions: RolePermissions;
22
+ }
6
23
  /**
7
24
  * Authentication provider function type.
8
25
  * Returns the authorization header value.
package/dist/client.d.ts CHANGED
@@ -4,9 +4,9 @@
4
4
  * Main client class for interacting with Pantheon's P1 content platform API.
5
5
  */
6
6
  import type { AuthProvider } from './auth.js';
7
- import type { Principal } from './types.js';
7
+ import type { Principal } from './types/index.js';
8
8
  import type { SdkIdentity } from './telemetry-headers.js';
9
- import { BaseEndpoint, SitesEndpoint, BranchesEndpoint, DocumentsEndpoint, VersionsEndpoint, CheckpointsEndpoint, PresenceEndpoint, AgentRegistryEndpoint, AgentEditEndpoint, MergeEndpoint, TemplatesEndpoint, MigrationConflictsEndpoint, QueriesEndpoint, TranslationsEndpoint, RelationsEndpoint } from './endpoints/index.js';
9
+ import { BaseEndpoint, AuthEndpoint, SitesEndpoint, BranchesEndpoint, DocumentsEndpoint, VersionsEndpoint, CheckpointsEndpoint, PresenceEndpoint, AgentRegistryEndpoint, AgentEditEndpoint, MergeEndpoint, TemplatesEndpoint, MigrationConflictsEndpoint, QueriesEndpoint, TranslationsEndpoint, RelationsEndpoint, ThreadsEndpoint } from './endpoints/index.js';
10
10
  /**
11
11
  * Configuration options for P1Client.
12
12
  */
@@ -150,6 +150,12 @@ export declare class P1Client {
150
150
  * Relation edges: upstream drift for localization and template derivation.
151
151
  */
152
152
  readonly relations: RelationsEndpoint;
153
+ /** Advisory endpoint: resolves the calling user's role on a branch. */
154
+ readonly auth: AuthEndpoint;
155
+ /**
156
+ * Comment threads anchored to blocks, pages, sites and workstreams.
157
+ */
158
+ readonly threads: ThreadsEndpoint;
153
159
  constructor(config: P1ClientConfig | InternalConfig);
154
160
  /**
155
161
  * Create a new client instance with a different principal.
package/dist/client.js CHANGED
@@ -1,4 +1,4 @@
1
- import { BaseEndpoint, SitesEndpoint, BranchesEndpoint, DocumentsEndpoint, VersionsEndpoint, CheckpointsEndpoint, PresenceEndpoint, AgentRegistryEndpoint, AgentEditEndpoint, MergeEndpoint, TemplatesEndpoint, MigrationConflictsEndpoint, QueriesEndpoint, TranslationsEndpoint, RelationsEndpoint, } from './endpoints/index.js';
1
+ import { BaseEndpoint, AuthEndpoint, SitesEndpoint, BranchesEndpoint, DocumentsEndpoint, VersionsEndpoint, CheckpointsEndpoint, PresenceEndpoint, AgentRegistryEndpoint, AgentEditEndpoint, MergeEndpoint, TemplatesEndpoint, MigrationConflictsEndpoint, QueriesEndpoint, TranslationsEndpoint, RelationsEndpoint, ThreadsEndpoint, } from './endpoints/index.js';
2
2
  export class P1Client {
3
3
  baseEndpoint;
4
4
  sites;
@@ -15,6 +15,8 @@ export class P1Client {
15
15
  queries;
16
16
  translations;
17
17
  relations;
18
+ auth;
19
+ threads;
18
20
  constructor(config) {
19
21
  if ('baseEndpoint' in config) {
20
22
  this.baseEndpoint = config.baseEndpoint;
@@ -45,6 +47,8 @@ export class P1Client {
45
47
  this.queries = new QueriesEndpoint(this.baseEndpoint);
46
48
  this.translations = new TranslationsEndpoint(this.baseEndpoint);
47
49
  this.relations = new RelationsEndpoint(this.baseEndpoint);
50
+ this.auth = new AuthEndpoint(this.baseEndpoint);
51
+ this.threads = new ThreadsEndpoint(this.baseEndpoint);
48
52
  }
49
53
  withPrincipal(principal) {
50
54
  const newBaseEndpoint = this.baseEndpoint.withPrincipal(principal);
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * API endpoints for the agent edit workflow (politeness protocol).
5
5
  */
6
- import type { AgentEditContext, AgentEditPermission, AgentEditSession, AgentEditCompleteResult, AgentEditAbortResult, AgentStopResult } from '../types.js';
6
+ import type { AgentEditContext, AgentEditPermission, AgentEditSession, AgentEditCompleteResult, AgentEditAbortResult, AgentStopResult } from '../types/index.js';
7
7
  import type { BaseEndpoint } from './base.js';
8
8
  /**
9
9
  * Agent edit endpoint for managing agent edit sessions.
@@ -63,16 +63,20 @@ export declare class AgentEditEndpoint {
63
63
  */
64
64
  abortEdit(siteId: string, branchId: string, documentPath: string, agentId: string, checkpointId: string): Promise<AgentEditAbortResult>;
65
65
  /**
66
- * Stop an agent's edit session (human-initiated).
67
- *
68
- * Server looks up the agent's active session and rolls back
69
- * to the checkpoint created at edit-start. This allows humans
70
- * to stop an agent without knowing the session/checkpoint IDs.
66
+ * Stop an agent that is editing a document.
71
67
  *
72
68
  * @param siteId - Site ID
73
69
  * @param branchId - Branch ID
74
70
  * @param documentPath - Document path
75
- * @param agentId - Agent ID to stop
71
+ * @param target - The agent to stop, or the specific turn to stop; at least one of
72
+ * the two is required. Pass a turn when you know it: a turn between edits holds no
73
+ * session to find it by.
76
74
  */
77
- stopAgent(siteId: string, branchId: string, documentPath: string, agentId: string): Promise<AgentStopResult>;
75
+ stopAgent(siteId: string, branchId: string, documentPath: string, target: string | {
76
+ agentId: string;
77
+ turnId?: string;
78
+ } | {
79
+ agentId?: string;
80
+ turnId: string;
81
+ }): Promise<AgentStopResult>;
78
82
  }
@@ -48,11 +48,12 @@ export class AgentEditEndpoint {
48
48
  body: JSON.stringify({ agentId, checkpointId }),
49
49
  });
50
50
  }
51
- async stopAgent(siteId, branchId, documentPath, agentId) {
51
+ async stopAgent(siteId, branchId, documentPath, target) {
52
52
  const encodedPath = this.encodeDocumentPath(documentPath);
53
+ const body = typeof target === 'string' ? { agentId: target } : target;
53
54
  return this.base.request(`/api/sites/${siteId}/branches/${branchId}/documents/${encodedPath}/agent-stop`, {
54
55
  method: 'POST',
55
- body: JSON.stringify({ agentId }),
56
+ body: JSON.stringify(body),
56
57
  });
57
58
  }
58
59
  }
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * API endpoints for managing registered agents in an organization.
5
5
  */
6
- import type { RegisteredAgent, CreateAgentParams, UpdateAgentParams, ListAgentsOptions, AgentStatus } from '../types.js';
6
+ import type { RegisteredAgent, CreateAgentParams, UpdateAgentParams, ListAgentsOptions, AgentStatus } from '../types/index.js';
7
7
  import type { BaseEndpoint } from './base.js';
8
8
  /**
9
9
  * Agent registry endpoint for managing organization agents.
@@ -0,0 +1,7 @@
1
+ import type { ViewerRole } from '../auth.js';
2
+ import type { BaseEndpoint } from './base.js';
3
+ export declare class AuthEndpoint {
4
+ private readonly base;
5
+ constructor(base: BaseEndpoint);
6
+ getRole(siteId: string, branchId: string): Promise<ViewerRole>;
7
+ }
@@ -0,0 +1,11 @@
1
+ import { requirePathParams } from '../utils.js';
2
+ export class AuthEndpoint {
3
+ base;
4
+ constructor(base) {
5
+ this.base = base;
6
+ }
7
+ async getRole(siteId, branchId) {
8
+ requirePathParams({ siteId, branchId }, 'auth.getRole');
9
+ return this.base.request(`/api/sites/${encodeURIComponent(siteId)}/branches/${encodeURIComponent(branchId)}/auth/role`, { method: 'GET' });
10
+ }
11
+ }
@@ -4,7 +4,7 @@
4
4
  * Shared HTTP request logic for all endpoints.
5
5
  */
6
6
  import type { AuthProvider } from '../auth.js';
7
- import type { Principal } from '../types.js';
7
+ import type { Principal } from '../types/index.js';
8
8
  import { type SdkIdentity } from '../telemetry-headers.js';
9
9
  export interface BaseEndpointConfig {
10
10
  baseUrl: string;
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * API operations for branches.
5
5
  */
6
- import type { Branch, CreateBranchParams, PaginationOptions } from '../types.js';
6
+ import type { Branch, CreateBranchParams, PaginationOptions } from '../types/index.js';
7
7
  import type { BaseEndpoint } from './base.js';
8
8
  export declare class BranchesEndpoint {
9
9
  private readonly base;
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * API operations for checkpoints.
5
5
  */
6
- import type { Checkpoint, CheckpointDocument, CreateCheckpointParams, PaginationOptions } from '../types.js';
6
+ import type { Checkpoint, CheckpointDocument, CreateCheckpointParams, PaginationOptions } from '../types/index.js';
7
7
  import type { BaseEndpoint } from './base.js';
8
8
  export declare class CheckpointsEndpoint {
9
9
  private readonly base;
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * API operations for documents.
5
5
  */
6
- import type { Document, CreateDocumentParams, ListDocumentsOptions, PublishDocumentResult } from '../types.js';
6
+ import type { Document, CreateDocumentParams, ListDocumentsOptions, PublishDocumentResult } from '../types/index.js';
7
7
  import type { BaseEndpoint } from './base.js';
8
8
  export declare class DocumentsEndpoint {
9
9
  private readonly base;
@@ -2,6 +2,7 @@
2
2
  * Endpoints barrel export.
3
3
  */
4
4
  export { BaseEndpoint } from './base.js';
5
+ export { AuthEndpoint } from './auth.js';
5
6
  export type { BaseEndpointConfig, RequestOptions } from './base.js';
6
7
  export { SitesEndpoint } from './sites.js';
7
8
  export { BranchesEndpoint } from './branches.js';
@@ -17,3 +18,4 @@ export { MigrationConflictsEndpoint } from './migration-conflicts.js';
17
18
  export { QueriesEndpoint } from './queries.js';
18
19
  export { TranslationsEndpoint } from './translations.js';
19
20
  export { RelationsEndpoint } from './relations.js';
21
+ export { ThreadsEndpoint } from './threads.js';
@@ -1,4 +1,5 @@
1
1
  export { BaseEndpoint } from './base.js';
2
+ export { AuthEndpoint } from './auth.js';
2
3
  export { SitesEndpoint } from './sites.js';
3
4
  export { BranchesEndpoint } from './branches.js';
4
5
  export { DocumentsEndpoint } from './documents.js';
@@ -13,3 +14,4 @@ export { MigrationConflictsEndpoint } from './migration-conflicts.js';
13
14
  export { QueriesEndpoint } from './queries.js';
14
15
  export { TranslationsEndpoint } from './translations.js';
15
16
  export { RelationsEndpoint } from './relations.js';
17
+ export { ThreadsEndpoint } from './threads.js';
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * API operations for merge checks, previews, execution, and merge requests.
5
5
  */
6
- import type { MergeabilityResult, MergePreview, MergeExecuteParams, MergeExecuteResult, MergeJob, MergeRequest, CreateMergeRequestParams, UpdateMergeRequestParams, ListMergeRequestsOptions, ExecuteMergeRequestOptions } from '../types.js';
6
+ import type { MergeabilityResult, MergePreview, MergeExecuteParams, MergeExecuteResult, MergeJob, MergeRequest, CreateMergeRequestParams, UpdateMergeRequestParams, ListMergeRequestsOptions, ExecuteMergeRequestOptions } from '../types/index.js';
7
7
  import type { BaseEndpoint } from './base.js';
8
8
  export declare class MergeEndpoint {
9
9
  private readonly base;
@@ -1,4 +1,4 @@
1
- import { TERMINAL_MERGE_JOB_STATUSES } from '../types.js';
1
+ import { TERMINAL_MERGE_JOB_STATUSES } from '../types/index.js';
2
2
  import { requirePathParams } from '../utils.js';
3
3
  export class MergeEndpoint {
4
4
  base;
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * API operations for reviewing and resolving template migration conflicts.
5
5
  */
6
- import type { MigrationConflict } from '../types.js';
6
+ import type { MigrationConflict } from '../types/index.js';
7
7
  import type { BaseEndpoint } from './base.js';
8
8
  export declare class MigrationConflictsEndpoint {
9
9
  private readonly base;
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * API endpoints for querying presence data at site, branch, and agent levels.
5
5
  */
6
- import type { SitePresence, BranchPresence, AgentGlobalPresence, UpdateFocusRegionsResponse } from '../types.js';
6
+ import type { SitePresence, BranchPresence, AgentGlobalPresence, UpdateFocusRegionsResponse } from '../types/index.js';
7
7
  import type { BaseEndpoint } from './base.js';
8
8
  /**
9
9
  * Presence endpoint for querying actor presence data.
@@ -1,4 +1,4 @@
1
- import type { Query, QueryResults, QueryResultsParams } from '../types.js';
1
+ import type { Query, QueryResults, QueryResultsParams } from '../types/index.js';
2
2
  import type { BaseEndpoint } from './base.js';
3
3
  export declare class QueriesEndpoint {
4
4
  private readonly base;
@@ -1,11 +1,12 @@
1
1
  /**
2
2
  * Relations Endpoint
3
3
  *
4
- * Read operations over the derivation edges of a document (localization and
5
- * template). The upstream-diff endpoint classifies how the document has drifted
6
- * from its upstream source so an author can reconcile.
4
+ * Operations over the derivation edges of a document (localization and template).
5
+ * The upstream-diff endpoint classifies how the document has drifted from its
6
+ * upstream source so an author can reconcile, and the resolution endpoints record
7
+ * which props have been dealt with so a change is not reported forever.
7
8
  */
8
- import type { ChangeSummary } from '../types.js';
9
+ import type { ChangeSummary, UpstreamResolutions, UpstreamResolutionTarget } from '../types/index.js';
9
10
  import type { BaseEndpoint } from './base.js';
10
11
  export declare class RelationsEndpoint {
11
12
  private readonly base;
@@ -15,5 +16,27 @@ export declare class RelationsEndpoint {
15
16
  * `documentId` is the derived side of the relation edge (the current page). Rejects
16
17
  * with NotFoundError when no edge of that type exists.
17
18
  */
18
- getUpstreamDiff(siteId: string, branchId: string, documentId: string, relationType: 'localization' | 'template'): Promise<ChangeSummary>;
19
+ getUpstreamDiff(siteId: string, branchId: string, documentId: string, relationType: 'localization' | 'template', includeResolved?: boolean): Promise<ChangeSummary>;
20
+ /**
21
+ * Which of a translation's reported changes have been reconciled against their
22
+ * canonical, and at what canonical version. Rejects with NotFoundError when the
23
+ * document is not a translation.
24
+ */
25
+ getUpstreamResolutions(siteId: string, branchId: string, documentId: string): Promise<UpstreamResolutions>;
26
+ /**
27
+ * Records that reported changes have been reconciled, so they stop being
28
+ * reported. Taking the canonical value, writing your own translation of it, and
29
+ * deciding the translation keeps what it has all count as reconciling.
30
+ *
31
+ * `upstreamVersionId` is the `toVersionId` of the summary the changes were read
32
+ * from, so what gets settled is the state that was shown; a change the canonical
33
+ * made after that stays outstanding. Rejects a version that does not belong to
34
+ * the canonical, and a slot it no longer holds.
35
+ *
36
+ * Recorded per branch, so reconciling on one branch leaves the others as they
37
+ * were.
38
+ */
39
+ setUpstreamResolutions(siteId: string, branchId: string, documentId: string, targets: UpstreamResolutionTarget[], upstreamVersionId: string): Promise<UpstreamResolutions>;
40
+ /** Clears the changes' resolutions, returning them to the outstanding list. */
41
+ clearUpstreamResolutions(siteId: string, branchId: string, documentId: string, targets: UpstreamResolutionTarget[]): Promise<UpstreamResolutions>;
19
42
  }
@@ -3,7 +3,20 @@ export class RelationsEndpoint {
3
3
  constructor(base) {
4
4
  this.base = base;
5
5
  }
6
- async getUpstreamDiff(siteId, branchId, documentId, relationType) {
7
- return this.base.request(`/api/sites/${siteId}/branches/${branchId}/documents/${documentId}/upstream-diff?relationType=${relationType}`, { method: 'GET' });
6
+ async getUpstreamDiff(siteId, branchId, documentId, relationType, includeResolved = false) {
7
+ const query = new URLSearchParams({ relationType });
8
+ if (includeResolved) {
9
+ query.set('includeResolved', 'true');
10
+ }
11
+ return this.base.request(`/api/sites/${siteId}/branches/${branchId}/documents/${documentId}/upstream-diff?${query.toString()}`, { method: 'GET' });
12
+ }
13
+ async getUpstreamResolutions(siteId, branchId, documentId) {
14
+ return this.base.request(`/api/sites/${siteId}/branches/${branchId}/documents/${documentId}/upstream-resolutions`, { method: 'GET' });
15
+ }
16
+ async setUpstreamResolutions(siteId, branchId, documentId, targets, upstreamVersionId) {
17
+ return this.base.request(`/api/sites/${siteId}/branches/${branchId}/documents/${documentId}/upstream-resolutions`, { method: 'PUT', body: JSON.stringify({ targets, upstreamVersionId }) });
18
+ }
19
+ async clearUpstreamResolutions(siteId, branchId, documentId, targets) {
20
+ return this.base.request(`/api/sites/${siteId}/branches/${branchId}/documents/${documentId}/upstream-resolutions`, { method: 'DELETE', body: JSON.stringify({ targets }) });
8
21
  }
9
22
  }
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * API operations for sites.
5
5
  */
6
- import type { Site, PaginationOptions, SiteSettingsResult } from '../types.js';
6
+ import type { Site, PaginationOptions, SiteMembers, SiteSettingsResult } from '../types/index.js';
7
7
  import type { BaseEndpoint } from './base.js';
8
8
  export declare class SitesEndpoint {
9
9
  private readonly base;
@@ -16,6 +16,11 @@ export declare class SitesEndpoint {
16
16
  * Get a site's settings, including the locales it publishes in.
17
17
  */
18
18
  getSettings(siteId: string): Promise<SiteSettingsResult>;
19
+ /**
20
+ * The people and agents on a site, for pickers. Anyone who can view the site
21
+ * can read its roster.
22
+ */
23
+ members(siteId: string): Promise<SiteMembers>;
19
24
  /**
20
25
  * List all sites.
21
26
  */
@@ -16,6 +16,12 @@ export class SitesEndpoint {
16
16
  method: 'GET',
17
17
  });
18
18
  }
19
+ async members(siteId) {
20
+ requirePathParams({ siteId }, 'sites.members');
21
+ return this.base.request(`/api/sites/${siteId}/members`, {
22
+ method: 'GET',
23
+ });
24
+ }
19
25
  async list(options) {
20
26
  const params = new URLSearchParams();
21
27
  if (options?.limit !== undefined) {
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * API operations for content type templates.
5
5
  */
6
- import type { Template, TemplateSummary, CreateTemplateParams, UpdateTemplateParams, MigrationJob, MigrationPreview } from '../types.js';
6
+ import type { Template, TemplateSummary, CreateTemplateParams, UpdateTemplateParams, MigrationJob, MigrationPreview } from '../types/index.js';
7
7
  import type { BaseEndpoint } from './base.js';
8
8
  export declare class TemplatesEndpoint {
9
9
  private readonly base;
@@ -0,0 +1,64 @@
1
+ /**
2
+ * Threads Endpoint
3
+ *
4
+ * Comment threads anchored to a block, page, site or workstream. Threads are
5
+ * site-scoped: a block thread follows its block across branches.
6
+ */
7
+ import type { CommentContent, ThreadContextRef, ListThreadsOptions, PostCommentResult, PostThreadParams, ProposalDecision, ThreadListPage, ThreadOverview, ThreadStatus, ThreadWithComments } from '../types/threads/index.js';
8
+ import type { BaseEndpoint } from './base.js';
9
+ export declare class ThreadsEndpoint {
10
+ private readonly base;
11
+ constructor(base: BaseEndpoint);
12
+ /**
13
+ * List threads on a site, newest activity first. Pass `documentId` to get
14
+ * that page's threads: one overview per context, the open thread when there
15
+ * is one, otherwise the latest resolved one.
16
+ */
17
+ listThreads(siteId: string, options?: ListThreadsOptions): Promise<ThreadListPage>;
18
+ /**
19
+ * Every thread ever opened on one context, open and resolved alike.
20
+ */
21
+ listContextThreads(siteId: string, context: ThreadContextRef): Promise<ThreadOverview[]>;
22
+ /**
23
+ * One thread with its comments, oldest first.
24
+ */
25
+ getThread(siteId: string, threadId: string): Promise<ThreadWithComments>;
26
+ /**
27
+ * Open a thread on a context with its first comment. Posting to a context
28
+ * that already has an open thread appends to it instead.
29
+ */
30
+ postThread(siteId: string, params: PostThreadParams): Promise<PostCommentResult>;
31
+ /**
32
+ * Reply to an existing thread. Replying to a resolved thread reopens it. A
33
+ * plain string posts a message; an agent passes the full content to leave
34
+ * a working line or a proposal.
35
+ */
36
+ postComment(siteId: string, threadId: string, content: string | CommentContent): Promise<PostCommentResult>;
37
+ /**
38
+ * Replace one of the caller's own comments, kind and state included. This is
39
+ * how an agent turns its working line into its answer.
40
+ */
41
+ updateComment(siteId: string, threadId: string, commentId: string, content: CommentContent): Promise<PostCommentResult>;
42
+ /**
43
+ * Accept or dismiss an agent's proposal. Only a proposal still waiting can be
44
+ * decided. Accepting applies the proposed operations to the document as the
45
+ * deciding user before the decision is recorded, so the change reaches every
46
+ * open editor over realtime; a refusal leaves the proposal undecided.
47
+ */
48
+ decideProposal(siteId: string, threadId: string, commentId: string, decision: ProposalDecision): Promise<PostCommentResult>;
49
+ /**
50
+ * Resolve or reopen a thread. Setting the status it already has is a no-op.
51
+ */
52
+ setThreadStatus(siteId: string, threadId: string, status: ThreadStatus): Promise<ThreadOverview>;
53
+ /**
54
+ * Record that a mentioned agent never replied, so the share of mentions that go
55
+ * unanswered can be measured rather than guessed at. Takes the id of the comment
56
+ * that did the mentioning and how long the reader waited. Nothing is stored
57
+ * against the thread, and viewing the thread is enough permission to report.
58
+ */
59
+ reportUnansweredMention(siteId: string, threadId: string, report: {
60
+ commentId: string;
61
+ agentId: string;
62
+ elapsedMs: number;
63
+ }): Promise<void>;
64
+ }
@@ -0,0 +1,70 @@
1
+ import { requirePathParams } from '../utils.js';
2
+ export class ThreadsEndpoint {
3
+ base;
4
+ constructor(base) {
5
+ this.base = base;
6
+ }
7
+ async listThreads(siteId, options) {
8
+ requirePathParams({ siteId }, 'threads.listThreads');
9
+ const params = new URLSearchParams();
10
+ if (options?.documentId !== undefined)
11
+ params.set('documentId', options.documentId);
12
+ if (options?.status !== undefined)
13
+ params.set('status', options.status);
14
+ if (options?.limit !== undefined)
15
+ params.set('limit', String(options.limit));
16
+ if (options?.cursor !== undefined)
17
+ params.set('cursor', options.cursor);
18
+ const query = params.toString();
19
+ const path = query
20
+ ? `/api/sites/${siteId}/threads?${query}`
21
+ : `/api/sites/${siteId}/threads`;
22
+ return this.base.request(path, { method: 'GET' });
23
+ }
24
+ async listContextThreads(siteId, context) {
25
+ requirePathParams({ siteId, contextId: context.id }, 'threads.listContextThreads');
26
+ const response = await this.base.request(`/api/sites/${siteId}/contexts/${context.type}/${encodeURIComponent(context.id)}/threads`, { method: 'GET' });
27
+ return response.threads;
28
+ }
29
+ async getThread(siteId, threadId) {
30
+ requirePathParams({ siteId, threadId }, 'threads.getThread');
31
+ return this.base.request(`/api/sites/${siteId}/threads/${threadId}`, {
32
+ method: 'GET',
33
+ });
34
+ }
35
+ async postThread(siteId, params) {
36
+ requirePathParams({ siteId }, 'threads.postThread');
37
+ return this.base.request(`/api/sites/${siteId}/threads`, {
38
+ method: 'POST',
39
+ body: JSON.stringify(params),
40
+ });
41
+ }
42
+ async postComment(siteId, threadId, content) {
43
+ requirePathParams({ siteId, threadId }, 'threads.postComment');
44
+ return this.base.request(`/api/sites/${siteId}/threads/${threadId}/comments`, {
45
+ method: 'POST',
46
+ body: JSON.stringify(typeof content === 'string' ? { body: content } : content),
47
+ });
48
+ }
49
+ async updateComment(siteId, threadId, commentId, content) {
50
+ requirePathParams({ siteId, threadId, commentId }, 'threads.updateComment');
51
+ return this.base.request(`/api/sites/${siteId}/threads/${threadId}/comments/${commentId}`, { method: 'PUT', body: JSON.stringify(content) });
52
+ }
53
+ async decideProposal(siteId, threadId, commentId, decision) {
54
+ requirePathParams({ siteId, threadId, commentId }, 'threads.decideProposal');
55
+ return this.base.request(`/api/sites/${siteId}/threads/${threadId}/comments/${commentId}/decision`, { method: 'PUT', body: JSON.stringify({ decision }) });
56
+ }
57
+ async setThreadStatus(siteId, threadId, status) {
58
+ requirePathParams({ siteId, threadId }, 'threads.setThreadStatus');
59
+ const response = await this.base.request(`/api/sites/${siteId}/threads/${threadId}/status`, { method: 'PUT', body: JSON.stringify({ status }) });
60
+ return response.thread;
61
+ }
62
+ async reportUnansweredMention(siteId, threadId, report) {
63
+ requirePathParams({ siteId, threadId }, 'threads.reportUnansweredMention');
64
+ await this.base.request(`/api/sites/${siteId}/threads/${threadId}/unanswered-mentions`, {
65
+ method: 'POST',
66
+ body: JSON.stringify(report),
67
+ keepalive: true,
68
+ });
69
+ }
70
+ }
@@ -4,7 +4,7 @@
4
4
  * API operations for localization: creating and listing translation variants
5
5
  * of a canonical document.
6
6
  */
7
- import type { AuthorityOverridesResult, CreateTranslationParams, CreateTranslationResult, ListTranslationsResult, PropAuthority } from '../types.js';
7
+ import type { AuthorityOverridesResult, CreateTranslationParams, CreateTranslationResult, ListTranslationsResult, PropAuthority } from '../types/index.js';
8
8
  import type { BaseEndpoint } from './base.js';
9
9
  export declare class TranslationsEndpoint {
10
10
  private readonly base;
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * API operations for document versions.
5
5
  */
6
- import type { DocumentVersion, CreateDocumentVersionParams, PaginationOptions } from '../types.js';
6
+ import type { DocumentVersion, CreateDocumentVersionParams, PaginationOptions } from '../types/index.js';
7
7
  import type { BaseEndpoint } from './base.js';
8
8
  export declare class VersionsEndpoint {
9
9
  private readonly base;
package/dist/index.d.ts CHANGED
@@ -6,9 +6,11 @@
6
6
  export { P1Client } from './client.js';
7
7
  export type { P1ClientConfig } from './client.js';
8
8
  export { PRODUCTION_BASE_URL } from './constants.js';
9
- export type { Site, Branch, BranchStatus, Document, DocumentVersion, DocumentVersionSource, Checkpoint, CheckpointType, CheckpointStatus, CheckpointDocument, WorkflowSettings, PuckData, PuckComponentData, PuckRootData, Principal, PaginationOptions, CreateBranchParams, CreateDocumentParams, CreateDocumentVersionParams, CreateCheckpointParams, PublishDocumentResult, ListDocumentsOptions, ActorState, ActorRole, ActorPresence, DocumentPresenceSummary, BranchPresenceSummary, BranchPresence, SitePresence, AgentPresenceLocation, AgentGlobalPresence, AgentStatus, AgentSettings, RegisteredAgent, CreateAgentParams, UpdateAgentParams, ListAgentsOptions, AgentTrigger, AgentEditDenialReason, AgentEditContext, AgentEditPermission, AgentEditSession, AgentEditCompleteResult, AgentEditAbortResult, AgentStopResult, UpdateFocusRegionsResponse, PublishResult, ConflictResolutionStrategy, MergeRequestStatus, DocumentConflictType, DocumentConflict, ConflictDetails, MergeabilityResult, DocumentDiff, MergePreview, MergeExecuteParams, MergeExecuteResult, MergeRequest, CreateMergeRequestParams, UpdateMergeRequestParams, ListMergeRequestsOptions, ExecuteMergeRequestOptions, Template, TemplateSummary, TemplateMetadata, TemplateContentItem, TemplateRootProps, CreateTemplateParams, UpdateTemplateParams, MigrationJob, MigrationConflict, MigrationPreview, MigrationPreviewDocument, TriggerMigrationParams, Datasource, QuerySortField, Query, QueryResultItem, QueryResultsMeta, QueryResults, QueryResultsParams, LocalePolicy, SiteLocales, SiteSettings, SiteSettingsResult, TranslationMode, LocalizationRelation, CreateTranslationParams, CreateTranslationResult, TranslationVariant, ListTranslationsResult, PropAuthority, AuthorityOverridesMap, AuthorityOverridesResult, ChangeClassification, ChangeSummaryEntry, ChangeSummary, } from './types.js';
9
+ export type { Site, Branch, BranchStatus, Document, DocumentVersion, DocumentVersionSource, Checkpoint, CheckpointType, CheckpointStatus, CheckpointDocument, WorkflowSettings, PuckData, PuckComponentData, PuckRootData, Principal, PaginationOptions, CreateBranchParams, CreateDocumentParams, CreateDocumentVersionParams, CreateCheckpointParams, PublishDocumentResult, ListDocumentsOptions, ActorState, ActorRole, ActorPresence, DocumentPresenceSummary, BranchPresenceSummary, BranchPresence, SitePresence, AgentPresenceLocation, AgentGlobalPresence, AgentStatus, AgentSettings, RegisteredAgent, CreateAgentParams, UpdateAgentParams, ListAgentsOptions, AgentTrigger, AgentEditDenialReason, AgentEditContext, AgentEditPermission, AgentEditSession, AgentEditCompleteResult, AgentEditAbortResult, AgentStopResult, UpdateFocusRegionsResponse, PublishResult, ConflictResolutionStrategy, MergeRequestStatus, DocumentConflictType, DocumentConflict, ConflictDetails, MergeabilityResult, DocumentDiff, MergePreview, MergeExecuteParams, MergeExecuteResult, MergeRequest, CreateMergeRequestParams, UpdateMergeRequestParams, ListMergeRequestsOptions, ExecuteMergeRequestOptions, Template, TemplateSummary, TemplateMetadata, TemplateContentItem, TemplateRootProps, CreateTemplateParams, UpdateTemplateParams, MigrationJob, MigrationConflict, MigrationPreview, MigrationPreviewDocument, TriggerMigrationParams, Datasource, QuerySortField, Query, QueryResultItem, QueryResultsMeta, QueryResults, QueryResultsParams, LocalePolicy, SiteLocales, SiteSettings, SiteSettingsResult, TranslationMode, LocalizationRelation, CreateTranslationParams, CreateTranslationResult, TranslationVariant, ListTranslationsResult, PropAuthority, AuthorityOverridesMap, AuthorityOverridesResult, ChangeClassification, ChangeSummaryEntry, ChangeSummary, UpstreamResolutions, UpstreamResolutionTarget, SiteMemberRole, AgentSiteRole, SiteMemberUser, SiteMemberAgent, SiteMembers, } from './types/index.js';
10
+ export type * from './types/threads/index.js';
11
+ export { isAgentProposal, isAgentWorking } from './types/threads/index.js';
10
12
  export { createApiKeyAuth, createTokenAuth, InMemoryTokenStorage, LocalStorageTokenStorage, } from './auth.js';
11
- export type { AuthProvider, TokenStorage } from './auth.js';
13
+ export type { AuthProvider, TokenStorage, RoleName, RolePermissions, ViewerRole } from './auth.js';
12
14
  export { createOAuthAuthProvider, validateToken, loginMockUser, } from './oauth.js';
13
15
  export type { OAuthUserInfo, OAuthSession, AuthMeResponse, } from './oauth.js';
14
16
  export { createBrokerAuth, brokerLogout, hasPendingBrokerLogin, redeemPendingBrokerLogin } from './broker.js';
package/dist/index.js CHANGED
@@ -1,5 +1,6 @@
1
1
  export { P1Client } from './client.js';
2
2
  export { PRODUCTION_BASE_URL } from './constants.js';
3
+ export { isAgentProposal, isAgentWorking } from './types/threads/index.js';
3
4
  export { createApiKeyAuth, createTokenAuth, InMemoryTokenStorage, LocalStorageTokenStorage, } from './auth.js';
4
5
  export { createOAuthAuthProvider, validateToken, loginMockUser, } from './oauth.js';
5
6
  export { createBrokerAuth, brokerLogout, hasPendingBrokerLogin, redeemPendingBrokerLogin } from './broker.js';
@@ -6,7 +6,7 @@
6
6
  * Uses ReconnectingWebSocket from partysocket for automatic reconnection with exponential backoff.
7
7
  */
8
8
  import * as Y from 'yjs';
9
- import type { ActorPresence, ActorState, PublishResult } from './types';
9
+ import type { ActorPresence, ActorState, ThreadEvent, PublishResult } from './types/index.js';
10
10
  /**
11
11
  * Configuration for reconnection behavior
12
12
  */
@@ -101,6 +101,10 @@ export interface RealtimeClientConfig {
101
101
  * Use this to notify users that the document is being refreshed.
102
102
  */
103
103
  onServerReload?: () => void;
104
+ /**
105
+ * Called when a comment or thread on this document changes, from any editor.
106
+ */
107
+ onThreadEvent?: (event: ThreadEvent) => void;
104
108
  /**
105
109
  * Called when the server reports this client's Yjs history has diverged from
106
110
  * the document's current state (close code 4002). The caller must discard this
package/dist/realtime.js CHANGED
@@ -435,6 +435,9 @@ export class RealtimeClient {
435
435
  }
436
436
  break;
437
437
  }
438
+ case 'thread_event':
439
+ this.config.onThreadEvent?.(message.event);
440
+ break;
438
441
  case 'presence_error':
439
442
  if (message.code === 'RATE_LIMITED') {
440
443
  this.config.onRateLimited?.();
@@ -7,4 +7,4 @@
7
7
  /** Name half of `x-p1-sdk`. */
8
8
  export declare const SDK_NAME = "css-client";
9
9
  /** Version half of `x-p1-sdk`, matching the published release. */
10
- export declare const SDK_VERSION = "0.16.0-canary-20260911222513";
10
+ export declare const SDK_VERSION = "0.16.0";
@@ -1,2 +1,2 @@
1
1
  export const SDK_NAME = 'css-client';
2
- export const SDK_VERSION = '0.16.0-canary-20260911222513';
2
+ export const SDK_VERSION = '0.16.0';
@@ -3,6 +3,7 @@
3
3
  *
4
4
  * TypeScript types matching Pantheon's P1 content platform API.
5
5
  */
6
+ import type { ThreadEvent } from './threads/index.js';
6
7
  /**
7
8
  * Workflow settings for a site.
8
9
  */
@@ -119,6 +120,22 @@ export interface Document {
119
120
  * Document version source types.
120
121
  */
121
122
  export type DocumentVersionSource = 'edit' | 'merge' | 'revert' | 'initial';
123
+ /**
124
+ * Who a version's change really came from when an agent's accepted proposal was
125
+ * applied by a person: the agent that proposed it, the person it was applied for,
126
+ * and the agent's summary of the change.
127
+ */
128
+ export interface VersionAttribution {
129
+ agent: {
130
+ id: string;
131
+ name: string;
132
+ };
133
+ onBehalfOf: {
134
+ id: string;
135
+ name: string;
136
+ };
137
+ description: string;
138
+ }
122
139
  /**
123
140
  * A version of a document on a specific branch.
124
141
  */
@@ -140,6 +157,8 @@ export interface DocumentVersion {
140
157
  actionType?: string;
141
158
  /** Action metadata including puckActions array when structural */
142
159
  actionMetadata?: Record<string, unknown>;
160
+ /** Present when an agent's accepted proposal made this version. */
161
+ attribution?: VersionAttribution;
143
162
  }
144
163
  /**
145
164
  * Checkpoint types.
@@ -375,6 +394,12 @@ export interface ChangeSummaryEntry {
375
394
  authority?: PropAuthority;
376
395
  translatable?: boolean;
377
396
  structuralKind?: 'added' | 'removed' | 'moved';
397
+ /**
398
+ * The upstream version this change was reconciled at. Present only while that
399
+ * resolution still covers it: a change the upstream source makes again reads as
400
+ * outstanding once more.
401
+ */
402
+ resolvedAtVersion?: number;
378
403
  }
379
404
  /**
380
405
  * Classified summary of how a document has drifted from what it derives from,
@@ -399,8 +424,30 @@ export interface ChangeSummary {
399
424
  toVersionId: string;
400
425
  /** Id-keyed structural delta */
401
426
  slotDelta: unknown;
427
+ /** Outstanding changes, plus the reconciled ones when they were asked for. */
402
428
  changes: ChangeSummaryEntry[];
429
+ /** Per-classification tally over `changes`. */
403
430
  counts: Record<ChangeClassification, number>;
431
+ /**
432
+ * How many changes a resolution covers, whether or not they are listed. Absent
433
+ * from a backend that predates per-change resolutions.
434
+ */
435
+ resolvedCount?: number;
436
+ }
437
+ /**
438
+ * The upstream version each reported change was last reconciled at on this branch,
439
+ * keyed by slot id then the pointer the change was reported at. A change with no
440
+ * entry has never been reconciled there.
441
+ */
442
+ export interface UpstreamResolutions {
443
+ upstreamResolutions: Record<string, Record<string, number>>;
444
+ }
445
+ /** The reported change a resolution applies to. */
446
+ export interface UpstreamResolutionTarget {
447
+ /** Slot id of the component the change is on, or '__root__' for a page prop. */
448
+ slotId: string;
449
+ /** The change's `propPath`, so settling one change leaves its siblings listed. */
450
+ propPath: string;
404
451
  }
405
452
  /**
406
453
  * Parameters for creating a document version.
@@ -457,6 +504,8 @@ export interface ActorPresence {
457
504
  requestedById?: string;
458
505
  /** Display name of the human who triggered this agent session (human_requested sessions only) */
459
506
  requestedByName?: string;
507
+ /** The turn this agent is working on, when it named one. Names what a stop would end. */
508
+ turnId?: string;
460
509
  lastActivityAt: string;
461
510
  joinedAt: string;
462
511
  }
@@ -632,11 +681,15 @@ export interface AgentEditAbortResult {
632
681
  }
633
682
  /**
634
683
  * Result of stopping an agent (human-initiated).
635
- * Server looks up the agent's session and performs rollback if needed.
684
+ * The stop bars the turn from writing again, and rolls back its edit session if it had one.
636
685
  */
637
686
  export interface AgentStopResult {
638
687
  success: boolean;
688
+ /** The turn that was barred, when the stop named or found one. */
689
+ stoppedTurnId?: string;
639
690
  rolledBack: boolean;
691
+ /** Why nothing was stopped: 'no_active_turn' when no agent was running. */
692
+ reason?: string;
640
693
  message?: string;
641
694
  }
642
695
  /**
@@ -773,10 +826,19 @@ export interface WsSyncBaselineMessage {
773
826
  serverStateVector: string;
774
827
  timestamp: number;
775
828
  }
829
+ /**
830
+ * A comment or thread on this document changed. Carries the thread as it now
831
+ * stands and the comment involved, so caches can be updated without a refetch.
832
+ */
833
+ export interface WsThreadEventMessage {
834
+ type: 'thread_event';
835
+ event: ThreadEvent;
836
+ timestamp: number;
837
+ }
776
838
  /**
777
839
  * Union of all server-to-client WebSocket messages.
778
840
  */
779
- export type WsServerMessage = WsPresenceUpdateMessage | WsFocusRegionBroadcastMessage | WsFocusRegionAckMessage | WsPresenceErrorMessage | WsDeliveryAckMessage | WsPublishResultMessage | WsSyncBaselineMessage;
841
+ export type WsServerMessage = WsPresenceUpdateMessage | WsFocusRegionBroadcastMessage | WsFocusRegionAckMessage | WsPresenceErrorMessage | WsDeliveryAckMessage | WsPublishResultMessage | WsSyncBaselineMessage | WsThreadEventMessage;
780
842
  /**
781
843
  * Merge conflict resolution strategies (matches backend).
782
844
  */
@@ -1199,3 +1261,5 @@ export interface QueryResultsParams {
1199
1261
  includeMetadata?: boolean;
1200
1262
  includeSnapshot?: boolean;
1201
1263
  }
1264
+ export type * from './threads/index.js';
1265
+ export * from './site-members.js';
@@ -6,3 +6,4 @@ export const TERMINAL_MERGE_JOB_STATUSES = [
6
6
  'failed',
7
7
  'cancelled',
8
8
  ];
9
+ export * from './site-members.js';
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Site members: the people and agents who can be mentioned on a site.
3
+ */
4
+ export type SiteMemberRole = 'owner' | 'admin' | 'developer' | 'team_member' | 'author' | 'editor';
5
+ export type AgentSiteRole = 'viewer' | 'editor' | 'admin';
6
+ export interface SiteMemberUser {
7
+ id: string;
8
+ /** Null for someone granted access who has never signed in. */
9
+ name: string | null;
10
+ email: string | null;
11
+ role: SiteMemberRole;
12
+ avatar: string | null;
13
+ }
14
+ export interface SiteMemberAgent {
15
+ id: string;
16
+ name: string;
17
+ role: AgentSiteRole;
18
+ /** Agents carry no stored image; derive one from the id. */
19
+ avatar: null;
20
+ /** True when the agent reaches every site rather than being granted this one. */
21
+ isGlobal: boolean;
22
+ }
23
+ export interface SiteMembers {
24
+ members: SiteMemberUser[];
25
+ agents: SiteMemberAgent[];
26
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,36 @@
1
+ import type { Comment, CommentAuthor } from './comment.js';
2
+ export type ActivityStatus = 'working' | 'done' | 'failed';
3
+ /** `applying` is held while an accept puts the edits into the page; the card still offers the buttons, and the service refuses a second accept while the first is at work. */
4
+ export type ProposalStatus = 'proposed' | 'applying' | 'accepted' | 'dismissed';
5
+ /** What a reader can do to a proposal that is still waiting. */
6
+ export type ProposalDecision = Extract<ProposalStatus, 'accepted' | 'dismissed'>;
7
+ /**
8
+ * One change to the document, addressed by a dot path into its data
9
+ * (`content.2.props.title`). `from` is the source path of a `move`.
10
+ */
11
+ export interface ProposedOperation {
12
+ op: 'add' | 'remove' | 'replace' | 'move';
13
+ path: string;
14
+ value?: unknown;
15
+ from?: string;
16
+ }
17
+ export interface AgentActivityMetadata {
18
+ status: ActivityStatus;
19
+ }
20
+ export interface AgentProposalMetadata {
21
+ status: ProposalStatus;
22
+ /** One line saying what the operations do, for the card. */
23
+ summary: string;
24
+ operations: ProposedOperation[];
25
+ /** Who accepted or dismissed it, once someone has. */
26
+ decidedBy?: CommentAuthor;
27
+ decidedAt?: string;
28
+ /** When an accept began applying it; gone once it is decided. */
29
+ claimedAt?: string;
30
+ }
31
+ export type AgentProposalComment = Comment & {
32
+ kind: 'agent_proposal';
33
+ metadata: AgentProposalMetadata;
34
+ };
35
+ export declare function isAgentProposal(comment: Comment): comment is AgentProposalComment;
36
+ export declare function isAgentWorking(comment: Comment): boolean;
@@ -0,0 +1,7 @@
1
+ export function isAgentProposal(comment) {
2
+ return comment.kind === 'agent_proposal' && comment.metadata !== null && 'operations' in comment.metadata;
3
+ }
4
+ export function isAgentWorking(comment) {
5
+ return comment.kind === 'agent_activity' && comment.metadata !== null && 'status' in comment.metadata
6
+ && comment.metadata.status === 'working';
7
+ }
@@ -0,0 +1,29 @@
1
+ import type { Comment } from './comment.js';
2
+ import type { ThreadContextRef } from './context.js';
3
+ import type { ThreadOverview, ThreadStatus } from './thread.js';
4
+ export interface PostThreadParams {
5
+ context: ThreadContextRef;
6
+ /** Required for block and page threads, not allowed on site and workstream threads. */
7
+ documentId?: string;
8
+ branchId?: string;
9
+ body: string;
10
+ }
11
+ export interface PostCommentResult {
12
+ thread: ThreadOverview;
13
+ comment: Comment;
14
+ }
15
+ export interface ThreadWithComments {
16
+ thread: ThreadOverview;
17
+ comments: Comment[];
18
+ }
19
+ export interface ListThreadsOptions {
20
+ /** Narrow to one page's threads: one overview per context on that page. */
21
+ documentId?: string;
22
+ status?: ThreadStatus | 'all';
23
+ limit?: number;
24
+ cursor?: string;
25
+ }
26
+ export interface ThreadListPage {
27
+ threads: ThreadOverview[];
28
+ nextCursor: string | null;
29
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,57 @@
1
+ import type { Principal } from '../index.js';
2
+ import type { AgentActivityMetadata, AgentProposalMetadata } from './agent.js';
3
+ export type CommentAuthorType = Principal['type'];
4
+ /**
5
+ * Who wrote a comment. Fields match the site members roster so one component
6
+ * renders both.
7
+ */
8
+ export interface CommentAuthor {
9
+ type: CommentAuthorType;
10
+ id: string;
11
+ name: string | null;
12
+ avatar: string | null;
13
+ /** Present when an agent posted on a user's behalf. */
14
+ requestedBy?: {
15
+ id: string;
16
+ name: string | null;
17
+ };
18
+ }
19
+ export interface CommentMention {
20
+ type: CommentAuthorType;
21
+ id: string;
22
+ /** Null when the mentioned member has since left the site. */
23
+ name: string | null;
24
+ }
25
+ /**
26
+ * What a comment is. A `message` is what a person (or an agent) said; the
27
+ * agent kinds carry the state of a piece of work in `metadata`.
28
+ */
29
+ export type CommentKind = 'message' | 'agent_activity' | 'agent_proposal';
30
+ export type CommentMetadata = AgentActivityMetadata | AgentProposalMetadata;
31
+ export interface Comment {
32
+ id: string;
33
+ threadId: string;
34
+ kind: CommentKind;
35
+ /** Plain text with inline `${mention|user:uuid}` tokens. */
36
+ body: string;
37
+ /** Null on a `message`; the work's state on the agent kinds. */
38
+ metadata: CommentMetadata | null;
39
+ author: CommentAuthor;
40
+ mentions: CommentMention[];
41
+ createdAt: string;
42
+ editedAt: string | null;
43
+ }
44
+ /** A comment as written or rewritten: its kind decides which metadata it carries. */
45
+ export type CommentContent = {
46
+ kind: 'message';
47
+ body: string;
48
+ metadata?: null;
49
+ } | {
50
+ kind: 'agent_activity';
51
+ body: string;
52
+ metadata: AgentActivityMetadata;
53
+ } | {
54
+ kind: 'agent_proposal';
55
+ body: string;
56
+ metadata: AgentProposalMetadata;
57
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,9 @@
1
+ /**
2
+ * What a thread is anchored to. Block and page threads belong to a document;
3
+ * site and workstream threads do not.
4
+ */
5
+ export type ThreadContextType = 'block' | 'page' | 'site' | 'workstream';
6
+ export interface ThreadContextRef {
7
+ type: ThreadContextType;
8
+ id: string;
9
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,23 @@
1
+ import type { Comment, CommentAuthor } from './comment.js';
2
+ import type { ThreadOverview } from './thread.js';
3
+ /**
4
+ * Announced by the service after every thread write. The realtime
5
+ * channel delivers these to other editors; a client applies its own writes
6
+ * through the same shape.
7
+ */
8
+ export type ThreadEvent = {
9
+ type: 'comment_posted';
10
+ siteId: string;
11
+ thread: ThreadOverview;
12
+ comment: Comment;
13
+ } | {
14
+ type: 'comment_updated';
15
+ siteId: string;
16
+ thread: ThreadOverview;
17
+ comment: Comment;
18
+ } | {
19
+ type: 'thread_status_changed';
20
+ siteId: string;
21
+ thread: ThreadOverview;
22
+ actor: CommentAuthor;
23
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Threads: threads anchored to blocks, pages, sites and workstreams, and the
3
+ * comments in them.
4
+ */
5
+ export type * from './api.js';
6
+ export type * from './comment.js';
7
+ export type * from './agent.js';
8
+ export { isAgentProposal, isAgentWorking } from './agent.js';
9
+ export type * from './context.js';
10
+ export type * from './event.js';
11
+ export type * from './thread.js';
@@ -0,0 +1 @@
1
+ export { isAgentProposal, isAgentWorking } from './agent.js';
@@ -0,0 +1,22 @@
1
+ import type { CommentAuthor } from './comment.js';
2
+ import type { ThreadContextRef } from './context.js';
3
+ export type ThreadStatus = 'open' | 'resolved';
4
+ /**
5
+ * A thread without its comments: enough to draw a trigger's count and
6
+ * resolved state.
7
+ */
8
+ export interface ThreadOverview {
9
+ id: string;
10
+ siteId: string;
11
+ context: ThreadContextRef;
12
+ documentId: string | null;
13
+ /** The branch the thread was opened on, when it has a document. */
14
+ branchId: string | null;
15
+ status: ThreadStatus;
16
+ commentCount: number;
17
+ lastCommentAt: string;
18
+ createdAt: string;
19
+ updatedAt: string;
20
+ resolvedAt: string | null;
21
+ resolvedBy: CommentAuthor | null;
22
+ }
@@ -0,0 +1 @@
1
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pantheon-systems/css-client",
3
- "version": "0.16.0-canary-20260911222513",
3
+ "version": "0.16.0",
4
4
  "description": "TypeScript API client for Pantheon's P1 content platform",
5
5
  "publishConfig": {
6
6
  "access": "public",