feedbackbasket-cli 0.6.0 → 0.7.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.
package/README.md CHANGED
@@ -83,7 +83,7 @@ feedbackbasket feedback list --category BUG # Filter by category
83
83
  feedbackbasket feedback list --status OPEN # Filter by status
84
84
  feedbackbasket feedback list --sentiment NEGATIVE # Filter by sentiment
85
85
  feedbackbasket feedback list --search "login issue" # Text search
86
- feedbackbasket feedback show <id> # View single item detail
86
+ feedbackbasket feedback show <id> # View detail, including attachment links
87
87
  feedbackbasket feedback search "crash on mobile" # Search shortcut
88
88
 
89
89
  # Write
@@ -123,6 +123,7 @@ feedbackbasket widget settings myapp --position bottom-left --display modal
123
123
  feedbackbasket widget settings myapp --email-required --intro "How can we improve?"
124
124
  feedbackbasket widget settings myapp --button-radius 10 --button-size regular
125
125
  feedbackbasket widget settings myapp --show-email --allow-attachments --guided
126
+ feedbackbasket widget settings myapp --email-read-only --hide-email-when-prefilled
126
127
 
127
128
  # Configure guided feedback types and follow-up questions
128
129
  feedbackbasket widget flow myapp
@@ -134,6 +135,8 @@ feedbackbasket widget flow myapp --config ./feedback-flow.json
134
135
  feedbackbasket widget script myapp
135
136
  ```
136
137
 
138
+ Use `--email-read-only` and `--hide-email-when-prefilled` with runtime `userEmail` values from your app. These settings do not store visitor emails in FeedbackBasket widget settings.
139
+
137
140
  `widget flow --config` accepts either a `feedbackFlow` object or a JSON object with a `feedbackFlow` key. V1 supports guided mode with `text`, `textarea`, and `single_choice` follow-up questions.
138
141
 
139
142
  ```json
@@ -123,6 +123,9 @@ function renderBugList(bugs) {
123
123
  if (bug.aiSummary) {
124
124
  console.log(` ${brand.hint(bug.aiSummary)}`);
125
125
  }
126
+ if (bug.attachments && bug.attachments.length > 0) {
127
+ console.log(` ${brand.muted(`${bug.attachments.length} attachment${bug.attachments.length === 1 ? '' : 's'}`)}`);
128
+ }
126
129
  console.log();
127
130
  }
128
131
  }
@@ -161,6 +161,9 @@ function renderFeedbackList(items) {
161
161
  if (item.aiSummary) {
162
162
  console.log(` ${brand.hint(item.aiSummary)}`);
163
163
  }
164
+ if (item.attachments && item.attachments.length > 0) {
165
+ console.log(` ${brand.muted(`${item.attachments.length} attachment${item.attachments.length === 1 ? '' : 's'}`)}`);
166
+ }
164
167
  console.log();
165
168
  }
166
169
  }
@@ -200,6 +203,21 @@ function renderFeedbackDetail(item) {
200
203
  console.log(` ${value}`);
201
204
  }
202
205
  }
206
+ if (item.attachments && item.attachments.length > 0) {
207
+ console.log();
208
+ console.log(brand.bold(`Attachments (${item.attachments.length}):`));
209
+ for (const attachment of item.attachments) {
210
+ const size = typeof attachment.size === 'number' ? ` ${brand.muted(formatBytes(attachment.size))}` : '';
211
+ const type = attachment.mimeType ? ` ${brand.muted(attachment.mimeType)}` : '';
212
+ console.log(` ${brand.bold(attachment.filename)}${size}${type}`);
213
+ console.log(` ${attachment.url}`);
214
+ }
215
+ }
216
+ if (item.metadata && Object.keys(item.metadata).length > 0) {
217
+ console.log();
218
+ console.log(brand.bold('Metadata:'));
219
+ console.log(indentBlock(JSON.stringify(item.metadata, null, 2), ' '));
220
+ }
203
221
  if (item.aiSummary) {
204
222
  console.log();
205
223
  console.log(brand.bold('AI Summary:'));
@@ -227,3 +245,20 @@ function formatFeedbackType(item) {
227
245
  return undefined;
228
246
  return item.feedbackType.emoji ? `${item.feedbackType.emoji} ${label}` : label;
229
247
  }
248
+ function indentBlock(value, indent) {
249
+ return value
250
+ .split('\n')
251
+ .map((line) => `${indent}${line}`)
252
+ .join('\n');
253
+ }
254
+ function formatBytes(bytes) {
255
+ if (!Number.isFinite(bytes) || bytes < 0)
256
+ return '';
257
+ if (bytes < 1024)
258
+ return `${bytes} B`;
259
+ const kb = bytes / 1024;
260
+ if (kb < 1024)
261
+ return `${kb.toFixed(kb >= 10 ? 0 : 1)} KB`;
262
+ const mb = kb / 1024;
263
+ return `${mb.toFixed(mb >= 10 ? 0 : 1)} MB`;
264
+ }
@@ -65,6 +65,10 @@ export function createWidgetCommand(getWriter) {
65
65
  .option('--no-email-required', 'Make email optional')
66
66
  .option('--show-email', 'Show the email field')
67
67
  .option('--no-show-email', 'Hide the email field')
68
+ .option('--email-read-only', 'Lock the email field when userEmail is prefilled')
69
+ .option('--no-email-read-only', 'Allow editing prefilled email')
70
+ .option('--hide-email-when-prefilled', 'Hide the email field when userEmail is prefilled')
71
+ .option('--no-hide-email-when-prefilled', 'Show the email field even when userEmail is prefilled')
68
72
  .option('--allow-attachments', 'Allow image attachments')
69
73
  .option('--no-allow-attachments', 'Disable image attachments')
70
74
  .option('--icon-only', 'Show only the icon, no label')
@@ -84,6 +88,7 @@ export function createWidgetCommand(getWriter) {
84
88
  opts.success || opts.trigger || opts.display ||
85
89
  opts.buttonRadius || opts.buttonSize || opts.icon ||
86
90
  opts.emailRequired !== undefined || opts.showEmail !== undefined ||
91
+ opts.emailReadOnly !== undefined || opts.hideEmailWhenPrefilled !== undefined ||
87
92
  opts.allowAttachments !== undefined || opts.iconOnly !== undefined ||
88
93
  opts.showIcon !== undefined || opts.showBranding !== undefined ||
89
94
  opts.zIndex || opts.guided || opts.disableGuided;
@@ -117,6 +122,10 @@ export function createWidgetCommand(getWriter) {
117
122
  settings.emailRequired = opts.emailRequired;
118
123
  if (opts.showEmail !== undefined)
119
124
  settings.showEmailField = opts.showEmail;
125
+ if (opts.emailReadOnly !== undefined)
126
+ settings.emailReadOnly = opts.emailReadOnly;
127
+ if (opts.hideEmailWhenPrefilled !== undefined)
128
+ settings.hideEmailFieldWhenPrefilled = opts.hideEmailWhenPrefilled;
120
129
  if (opts.allowAttachments !== undefined)
121
130
  settings.allowAttachments = opts.allowAttachments;
122
131
  if (opts.iconOnly !== undefined)
@@ -349,6 +358,8 @@ function renderWidgetSettings(projectName, settings) {
349
358
  ['Display Mode', String(settings.displayMode ?? '')],
350
359
  ['Show Email', String(settings.showEmailField ?? true)],
351
360
  ['Email Required', String(settings.emailRequired ?? false)],
361
+ ['Email Read Only', String(settings.emailReadOnly ?? false)],
362
+ ['Hide Prefilled Email', String(settings.hideEmailFieldWhenPrefilled ?? false)],
352
363
  ['Attachments', String(settings.allowAttachments ?? true)],
353
364
  ['Guided Flow', String(settings.feedbackFlow?.enabled ?? false)],
354
365
  ['Intro Message', String(settings.introMessage ?? '')],
@@ -37,6 +37,8 @@ export interface WidgetSettings {
37
37
  position?: string;
38
38
  showEmailField?: boolean;
39
39
  emailRequired?: boolean;
40
+ emailReadOnly?: boolean;
41
+ hideEmailFieldWhenPrefilled?: boolean;
40
42
  allowAttachments?: boolean;
41
43
  displayMode?: 'modal' | 'popup';
42
44
  zIndex?: number;
@@ -76,11 +78,13 @@ export interface Feedback {
76
78
  type: FeedbackFlowQuestionType;
77
79
  value: string;
78
80
  }> | null;
81
+ metadata?: Record<string, unknown> | null;
79
82
  pageUrl?: string | null;
80
83
  browser?: string | null;
81
84
  os?: string | null;
82
85
  device?: string | null;
83
86
  language?: string | null;
87
+ attachments?: FeedbackAttachment[];
84
88
  project: {
85
89
  id: string;
86
90
  name: string;
@@ -89,6 +93,14 @@ export interface Feedback {
89
93
  notes?: FeedbackNote[];
90
94
  createdAt: string;
91
95
  }
96
+ export interface FeedbackAttachment {
97
+ id: string;
98
+ url: string;
99
+ filename: string;
100
+ size?: number;
101
+ mimeType?: string;
102
+ createdAt?: string;
103
+ }
92
104
  export interface FeedbackNote {
93
105
  id: string;
94
106
  content: string;
@@ -1,2 +1,2 @@
1
- export declare const VERSION = "0.6.0";
2
- export declare const USER_AGENT = "FeedbackBasket-CLI/0.6.0";
1
+ export declare const VERSION = "0.7.0";
2
+ export declare const USER_AGENT = "FeedbackBasket-CLI/0.7.0";
@@ -1,2 +1,2 @@
1
- export const VERSION = '0.6.0';
1
+ export const VERSION = '0.7.0';
2
2
  export const USER_AGENT = `FeedbackBasket-CLI/${VERSION}`;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "feedbackbasket-cli",
3
- "version": "0.6.0",
3
+ "version": "0.7.0",
4
4
  "description": "Command-line interface for FeedbackBasket — manage feedback from your terminal",
5
5
  "type": "module",
6
6
  "main": "dist/src/cli.js",
@@ -97,6 +97,7 @@ feedbackbasket widget settings <project> --color "#22c55e" --label "Send Feedbac
97
97
  feedbackbasket widget settings <project> --position bottom-left --display modal
98
98
  feedbackbasket widget settings <project> --email-required --intro "How can we improve?"
99
99
  feedbackbasket widget settings <project> --show-email --allow-attachments --guided
100
+ feedbackbasket widget settings <project> --email-read-only --hide-email-when-prefilled
100
101
 
101
102
  # Guided feedback types and follow-up questions
102
103
  feedbackbasket widget flow <project>
@@ -105,6 +106,8 @@ feedbackbasket widget flow <project> --reset-default --enable
105
106
  feedbackbasket widget flow <project> --config ./feedback-flow.json
106
107
  ```
107
108
 
109
+ `email-read-only` and `hide-email-when-prefilled` control behavior only when the host app passes a runtime `userEmail` value. Do not store visitor emails in widget settings.
110
+
108
111
  `widget flow --config` accepts either a `feedbackFlow` object or a JSON object with a `feedbackFlow` key. Use it when an agent needs to customize visitor choices such as Bug report, Feature request, and General feedback. Supported v1 question types are `text`, `textarea`, and `single_choice`.
109
112
 
110
113
  ### Team
@@ -144,7 +147,7 @@ feedbackbasket feedback note <id> "Reviewing — appears related to auth flow" -
144
147
  ```bash
145
148
  feedbackbasket bugs list --severity high --agent
146
149
  feedbackbasket feedback show <id> --agent
147
- # Response includes browser, OS, page URL, submitted feedback type, follow-up answers, AI analysis, priority score
150
+ # Response includes browser, OS, page URL, submitted feedback type, follow-up answers, attachment URLs, metadata, AI analysis, priority score
148
151
  ```
149
152
 
150
153
  ### Close the loop — reply to the submitter