@veltdev/types 6.0.8-beta.1 → 6.0.8-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Public data model for customer-defined action buttons on a comment.
3
+ *
4
+ * Customers attach a list of actions to a comment (or to the annotation, which
5
+ * acts as the per-agent-row default). Velt renders them as chips and emits
6
+ * `commentActionClicked` when one is clicked. **Velt never interprets an
7
+ * action** — clicking one performs no SDK write of any kind (spec AC-003).
8
+ *
9
+ * Part of the SDK public API (exported via `src/models.ts` → velt-types).
10
+ * Additive — see `specs/agent-comment-actions-and-progress/spec.md`
11
+ * `## Outbound contract changes`.
12
+ */
13
+ /**
14
+ * A single customer-defined action rendered as a chip on a comment.
15
+ *
16
+ * Identity is `id` and only `id` (spec AC-002). There is deliberately no
17
+ * `type` field — two opaque customer strings on one object is confusing, and
18
+ * `id` matches the already-shipped `AgentSuggestionAction`. There is also no
19
+ * `actor` (clicks are fire-and-forget, so the SDK has nothing to record), no
20
+ * `selected` / `singleSelect`, and no visual `variant`.
21
+ */
22
+ export interface CommentAction {
23
+ /**
24
+ * Stable, opaque, customer-owned identifier. REQUIRED — the only identity.
25
+ *
26
+ * The same `id` legitimately appears on many comments in one thread, which is
27
+ * why duplicate-click suppression is keyed on
28
+ * `(annotationId, commentId, actionId)` and never on `id` alone.
29
+ */
30
+ id: string;
31
+ /** Display label (chip text). Also the accessible name when an icon is set. */
32
+ label?: string;
33
+ /**
34
+ * Raw SVG string (a trimmed value starting with `<`) rendered through the
35
+ * `safeSvg` pipe, OR a URL / data-URI rendered as an `<img>`. Anything else
36
+ * is ignored — label only, no throw and no broken glyph.
37
+ *
38
+ * There is no named-icon registry and none is planned.
39
+ */
40
+ icon?: string;
41
+ /** Renders the chip non-interactive. A disabled chip emits nothing. */
42
+ disabled?: boolean;
43
+ /**
44
+ * Omits the chip entirely. An `actions` array in which every entry is hidden
45
+ * is a present-but-empty list: it renders NO row and does NOT fall back to
46
+ * the built-in accept/reject (spec INV-008 — that fallback would re-expose a
47
+ * state-changing control the customer deliberately suppressed).
48
+ */
49
+ hidden?: boolean;
50
+ /**
51
+ * Customer-owned bag, persisted as-is and echoed back verbatim on the click
52
+ * event. Velt never reads it.
53
+ */
54
+ metadata?: any;
55
+ }
@@ -1,6 +1,7 @@
1
1
  import { CommentAccessMode, CommentVisibilityOptionType } from "../../utils/enums";
2
2
  import { BaseMetadata } from "./base-metadata.data.model";
3
3
  import { CommentVisibilityType } from "./comment-actions.data.model";
4
+ import type { CommentAction } from "./comment-action.data.model";
4
5
  import { Comment } from "./comment.data.model";
5
6
  import { CursorPosition } from "./cursor-position.data.model";
6
7
  import { CustomAnnotationDropdownItem } from "./custom-chip-dropdown.data.model";
@@ -66,6 +67,16 @@ export declare class CommentAnnotation {
66
67
  */
67
68
  annotationNumber?: number;
68
69
  visibilityConfig?: CommentAnnotationVisibilityConfig;
70
+ /**
71
+ * Customer-defined action buttons for this annotation.
72
+ *
73
+ * These are the PER-ROW DEFAULT, not a thread-level row: every comment row
74
+ * without its own `comment.actions` renders these, regardless of who authored
75
+ * it. A progress row deliberately does NOT inherit them (spec AC-043) — only
76
+ * explicitly-set comment-level actions render there, because a row whose
77
+ * content has not been written yet has nothing for a "Copy"/"Retry" to act on.
78
+ */
79
+ actions?: CommentAction[];
69
80
  /**
70
81
  * This is the list of all comments part of this annotation.
71
82
  *
@@ -2,6 +2,7 @@ import { AssignToType, CommentAccessMode, CommentEventTypes, CommentStatus, Comm
2
2
  import { Attachment } from "./attachment.model";
3
3
  import { VeltButtonClickEvent } from "./button.data.model";
4
4
  import { AddAttachmentResponse } from "./comment-actions.data.model";
5
+ import { CommentAction } from "./comment-action.data.model";
5
6
  import { CommentAnnotation, UpdateContextConfig } from "./comment-annotation.data.model";
6
7
  import { Comment } from "./comment.data.model";
7
8
  import { CustomPriority, CustomStatus } from "./custom-filter.data.model";
@@ -100,7 +101,58 @@ export type CommentEventTypesMap = {
100
101
  [CommentEventTypes.VISIBILITY_OPTION_CLICKED]: VisibilityOptionClickedEvent;
101
102
  [CommentEventTypes.SUGGESTION_ACCEPTED]: SuggestionAcceptEvent;
102
103
  [CommentEventTypes.SUGGESTION_REJECTED]: SuggestionRejectEvent;
104
+ [CommentEventTypes.COMMENT_ACTION_CLICKED]: CommentActionClickedEvent;
103
105
  };
106
+ /**
107
+ * Emitted when a customer-defined action chip is clicked.
108
+ *
109
+ * Consumed as `Velt.getCommentElement().on('commentActionClicked')` — the same
110
+ * surface as `suggestionAccepted`.
111
+ *
112
+ * The SDK writes NOTHING in response. If the customer wants a one-time action,
113
+ * or wants to record who clicked, they rewrite the action list themselves via
114
+ * `updateComment`.
115
+ */
116
+ export interface CommentActionClickedEvent {
117
+ /** The full action object, including the customer's `metadata`. */
118
+ action: CommentAction;
119
+ actionId: string;
120
+ /**
121
+ * Where the action was DEFINED. Independent of `commentId`.
122
+ *
123
+ * `scope` and `commentId` answer different questions: `scope` says where the
124
+ * action came from, `commentId` says which row it was clicked on. An
125
+ * annotation-scoped action clicked on the second of three replies emits
126
+ * `scope: 'annotation'` WITH that reply's `commentId` — without which an
127
+ * annotation-level action on a multi-reply thread would be unactionable.
128
+ */
129
+ scope: 'comment' | 'annotation';
130
+ annotationId: string;
131
+ /**
132
+ * Which ROW was clicked. Present for any thread-row click regardless of
133
+ * `scope`; absent ONLY on the standalone suggestion card, which has no rows.
134
+ */
135
+ commentId?: number;
136
+ commentAnnotation: CommentAnnotation;
137
+ /** Same presence rule as `commentId`. */
138
+ comment?: Comment;
139
+ /**
140
+ * The user who clicked.
141
+ *
142
+ * Named `actionUser`, not `user`, for two reasons. Convention: all six
143
+ * events meaning "a user performed an action" use it (approve / accept /
144
+ * reject / delete comment-annotation, suggestion accept / reject). And
145
+ * semantics: on an AGENT comment a bare `user` is genuinely ambiguous —
146
+ * the comment's author is an agent, the clicker is a human. `actionUser`
147
+ * disambiguates what `user` would leave open.
148
+ */
149
+ actionUser: User;
150
+ /**
151
+ * Velt event metadata. Distinct from `action.metadata`, which is the
152
+ * customer's opaque bag — they never occupy the same level.
153
+ */
154
+ metadata: VeltEventMetadata;
155
+ }
104
156
  export interface AddAttachmentEvent {
105
157
  annotationId: string;
106
158
  commentAnnotation: CommentAnnotation;
@@ -0,0 +1,127 @@
1
+ /**
2
+ * Public data model for the comment progress indicator.
3
+ *
4
+ * A customer creates a comment in a progress state via `addComment`, pushes
5
+ * updates via repeated `updateComment` calls, and finally writes the real
6
+ * content with `state: 'completed'` on the SAME comment.
7
+ *
8
+ * DELIBERATELY NOT AGENT-SPECIFIC, and this is the whole point of the shape.
9
+ * An earlier revision nested this under the agent block as `AgentData.progress`.
10
+ * That forced a caller to supply a valid agent identity — `agentSource`,
11
+ * `agentId`, `agentName`, and backend-side a full `reason` with
12
+ * title/description/severity — merely to render three animated dots. Progress
13
+ * is a property of the COMMENT, not of who authored it: translation pipelines,
14
+ * moderation checks and multi-step workflows all want it without pretending to
15
+ * be an agent. It therefore sits on `Comment.progress`, beside
16
+ * `Comment.actions`, and nothing about progress touches the agent block.
17
+ *
18
+ * Part of the SDK public API (exported via `src/models.ts` → velt-types).
19
+ *
20
+ * NAMING: this feature uses `state`, never `status`. `status` already means
21
+ * four different things on adjacent objects (`CommentAnnotation.status` is a
22
+ * `CustomStatus`, `Comment.status` is `'added' | 'updated'`,
23
+ * `SuggestionData.status` is the suggestion lifecycle, plus per-step).
24
+ */
25
+ /**
26
+ * Lifecycle of one progress run.
27
+ *
28
+ * REQUIRED on `CommentProgress`, and deliberately so: presence-based state
29
+ * would force the final update to DELETE the field, and a Firestore merge write
30
+ * cannot remove a field without `FieldValue.delete()`. An explicit
31
+ * `state: 'completed'` makes the final update a plain merge.
32
+ *
33
+ * `'active'` deliberately matches the per-step `'active'`: both mean "the one
34
+ * currently running", at different levels.
35
+ */
36
+ export type CommentProgressState = 'active' | 'completed' | 'failed' | 'cancelled';
37
+ /** Lifecycle of one step within a progress run. */
38
+ export type CommentProgressStepState = 'pending' | 'active' | 'completed' | 'failed';
39
+ /**
40
+ * One step of the progress trace.
41
+ *
42
+ * Phase 1 renders only the current step's label. The array exists so this can
43
+ * grow into an expandable trace later without a model change.
44
+ */
45
+ export interface CommentProgressStep {
46
+ id?: string;
47
+ /**
48
+ * Customer-authored label shown on the progress row.
49
+ *
50
+ * This is CUSTOMER CONTENT and is never translated — see
51
+ * `resolveProgressLabel` in `src/app/utils/comment-progress.utils.ts`.
52
+ */
53
+ label: string;
54
+ state?: CommentProgressStepState;
55
+ startedAt?: number;
56
+ completedAt?: number;
57
+ metadata?: any;
58
+ }
59
+ /**
60
+ * Progress payload on a comment.
61
+ */
62
+ export interface CommentProgress {
63
+ /** REQUIRED. See `CommentProgressState` for why presence-based state was rejected. */
64
+ state: CommentProgressState;
65
+ /**
66
+ * Progress steps.
67
+ *
68
+ * **The customer owns this array outright.** `updateComment` replaces the
69
+ * comment wholesale, so whatever `steps` you send IS the new array. There is
70
+ * deliberately NO server-side appending: it would make the SDK stateful about
71
+ * array order, and it would break the checklist pattern below, where
72
+ * re-sending the same list with a different step marked active is exactly the
73
+ * right move.
74
+ *
75
+ * Three authoring patterns are supported, and label resolution handles all
76
+ * three without being told which is in play:
77
+ *
78
+ * - **Replace** — send a single-element array on each push.
79
+ * ```
80
+ * push 1: [ { label: 'Getting data', state: 'active' } ]
81
+ * push 2: [ { label: 'Processing data', state: 'active' } ]
82
+ * ```
83
+ * Simplest, and keeps no history.
84
+ *
85
+ * - **Append** — grow the array, marking the newest step active.
86
+ * ```
87
+ * push 1: [ { label: 'Getting data', state: 'active' } ]
88
+ * push 2: [ { label: 'Getting data', state: 'completed' },
89
+ * { label: 'Processing data', state: 'active' } ]
90
+ * ```
91
+ * Richer, and what a streaming agent naturally produces. It preserves the
92
+ * history a future expandable trace needs. Phase 1 renders only the tail.
93
+ *
94
+ * - **Checklist** — send the full list up front and move the `active` marker.
95
+ * ```
96
+ * push 1: [ { label: 'Getting data', state: 'active' },
97
+ * { label: 'Processing data', state: 'pending' } ]
98
+ * push 2: [ { label: 'Getting data', state: 'completed' },
99
+ * { label: 'Processing data', state: 'active' } ]
100
+ * ```
101
+ *
102
+ * **At most one step should be `state: 'active'` at a time.** The resolver
103
+ * tolerates violations gracefully — it takes the LAST active step, so an
104
+ * append-without-demoting still advances correctly — but a single active step
105
+ * is the contract, and relying on the tolerance makes the rendered label
106
+ * depend on array order rather than on what you marked.
107
+ */
108
+ steps?: CommentProgressStep[];
109
+ /**
110
+ * DISPLAY-ONLY. Phase 1 defaults to everyone and NEVER scopes.
111
+ *
112
+ * This is explicitly **not a security boundary**: Velt visibility is
113
+ * annotation-level, so a comment inside a readable annotation is readable by
114
+ * all. Do not add a filter keyed on this field without changing that
115
+ * architecture first.
116
+ */
117
+ visibleToUserIds?: string[];
118
+ /**
119
+ * Customer-supplied start time.
120
+ *
121
+ * NEVER used for staleness — the staleness fail-safe reads the comment's own
122
+ * SERVER-STAMPED `lastUpdated` (spec AC-046). Also never used for ordering
123
+ * multiple progress rows, which sort by server-stamped `createdAt`, because
124
+ * `startedAt` is optional and has no value when absent (spec AC-036).
125
+ */
126
+ startedAt?: number;
127
+ }
@@ -1,4 +1,6 @@
1
1
  import { Attachment } from "./attachment.model";
2
+ import type { CommentAction } from "./comment-action.data.model";
3
+ import type { CommentProgress } from "./comment-progress.data.model";
2
4
  import { AutocompleteGroupReplaceData, AutocompleteReplaceData, AutocompleteUserContactReplaceData } from "./autocomplete.data.model";
3
5
  import type { AgentData } from "./comment-annotation.data.model";
4
6
  import { ReactionAnnotation } from "./reaction-annotation.data.model";
@@ -106,4 +108,31 @@ export declare class Comment {
106
108
  * provides it; not server-generated.
107
109
  */
108
110
  metadata?: any;
111
+ /**
112
+ * Customer-defined action buttons rendered on this comment.
113
+ *
114
+ * Overrides `CommentAnnotation.actions` for this comment. `undefined` falls
115
+ * back to the annotation-level list; an explicit `[]` (or a list whose every
116
+ * entry is non-renderable) renders NO row and does NOT fall back to the
117
+ * built-in accept/reject.
118
+ *
119
+ * NOT inside `agent`: `agent` is provenance (who authored), `actions` is
120
+ * affordance (what you can do), and they have different lifecycles — the
121
+ * action list is rewritten many times over one immutable agent identity.
122
+ */
123
+ actions?: CommentAction[];
124
+ /**
125
+ * Progress payload for an in-flight or finished multi-step operation on this
126
+ * comment — an agent run, a translation pass, a moderation check, a workflow.
127
+ *
128
+ * NOT inside `agent`, and that is the point: requiring a valid agent identity
129
+ * to render a progress indicator was a bad constraint, and progress is a
130
+ * property of the comment rather than of its author. See
131
+ * `CommentProgress` for the full rationale.
132
+ *
133
+ * A content-less comment carrying this field is split out of
134
+ * `annotation.comments` at the data layer, so it never affects reply count,
135
+ * sidebar preview text, resolve, or any `comments.length`-driven dialog gate.
136
+ */
137
+ progress?: CommentProgress;
109
138
  }
@@ -1323,6 +1323,14 @@ export declare class CommentElement {
1323
1323
  * To set max reply avatars
1324
1324
  */
1325
1325
  public setMaxReplyAvatars: (maxReplyAvatars: number) => void;
1326
+ /**
1327
+ * Staleness window for the comment progress indicator, in milliseconds. Default 600000.
1328
+ *
1329
+ * Not a timeout: this is a staleness comparison evaluated only when a component
1330
+ * receives the annotation, and a stale row already on screen is allowed to remain.
1331
+ * Raise it for long-running agents.
1332
+ */
1333
+ public setCommentProgressStaleAfter: (commentProgressStaleAfter: number) => void;
1326
1334
 
1327
1335
  /**
1328
1336
  * To set sidebar button count type
@@ -2692,6 +2700,7 @@ export declare class CommentElement {
2692
2700
  /**
2693
2701
  * To set max reply avatars
2694
2702
  */
2703
+ private _setCommentProgressStaleAfter;
2695
2704
  private _setMaxReplyAvatars;
2696
2705
 
2697
2706
  /**
@@ -109,6 +109,7 @@ export declare const CommentEventTypes: {
109
109
  readonly VISIBILITY_OPTION_CLICKED: "visibilityOptionClicked";
110
110
  readonly SUGGESTION_ACCEPTED: "suggestionAccepted";
111
111
  readonly SUGGESTION_REJECTED: "suggestionRejected";
112
+ readonly COMMENT_ACTION_CLICKED: "commentActionClicked";
112
113
  };
113
114
  export declare const RecorderEventTypes: {
114
115
  readonly TRANSCRIPTION_DONE: "transcriptionDone";
package/models.d.ts CHANGED
@@ -5,6 +5,8 @@ export * from './app/models/data/activity.data.model';
5
5
  export * from './app/models/data/area-annotation.data.model';
6
6
  export * from './app/features/arrow/models/arrow-annotation.model';
7
7
  export * from './app/models/data/agent-suggestion.data.model';
8
+ export * from './app/models/data/comment-progress.data.model';
9
+ export * from './app/models/data/comment-action.data.model';
8
10
  export * from './app/models/data/base-metadata.data.model';
9
11
  export * from './app/models/data/button.data.model';
10
12
  export * from './app/models/data/chatgpt.data.model';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@veltdev/types",
3
- "version": "6.0.8-beta.1",
3
+ "version": "6.0.8-beta.2",
4
4
  "description": "Velt is an SDK to add collaborative features to your product within minutes. Example: Comments like Figma, Frame.io, Google docs or sheets, Recording like Loom, Huddles like Slack and much more.",
5
5
  "homepage": "https://velt.dev",
6
6
  "keywords": [