@myapihq/cli 2.11.1 → 2.12.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.
@@ -6,5 +6,6 @@ export declare const SCHEMA: FlagSchema;
6
6
  export declare function list(flags: Flags): Promise<void>;
7
7
  export declare function create(bodyArg: string | undefined, flags: Flags): Promise<void>;
8
8
  export declare function resolve(id: string, flags: Flags): Promise<void>;
9
+ export declare function del(id: string | undefined, flags: Flags): Promise<void>;
9
10
  export declare function widget(sub: string | undefined, arg: string | undefined, flags: Flags): Promise<void>;
10
11
  export declare function run(subcommand: string | undefined, args: string[], flags: Flags): Promise<void>;
@@ -13,6 +13,7 @@ export const EXPOSES = [
13
13
  'GET /feedback/orgs/{org_id}/items',
14
14
  'POST /feedback/orgs/{org_id}/items',
15
15
  'POST /feedback/orgs/{org_id}/items/{id}/resolve',
16
+ 'DELETE /feedback/orgs/{org_id}/items/{id}',
16
17
  'POST /feedback/orgs/{org_id}/widgets',
17
18
  'DELETE /feedback/orgs/{org_id}/widgets/{id}',
18
19
  ];
@@ -92,6 +93,18 @@ export async function resolve(id, flags) {
92
93
  success(`Resolved ${id}`);
93
94
  info('(An unknown id answers the same way, so this is not confirmation the item existed.)');
94
95
  }
96
+ export async function del(id, flags) {
97
+ const usage = 'myapi feedback delete <id> [--yes] [--org <id>]';
98
+ const config = requireConfig();
99
+ const orgId = requireOrg(flags, config, usage);
100
+ requireArg(id, 'id', usage);
101
+ // Erases rather than closes. `resolve` is the reversible one; this is not,
102
+ // so it takes the same confirmation every destructive verb here takes.
103
+ await confirmDestructive(flags, `permanently delete feedback ${id} (resolve keeps it; this erases it)`, usage);
104
+ await sdkFeedback.deleteFeedback(config.api_key, orgId, id);
105
+ success(`Deleted ${id}`);
106
+ info('(Idempotent — an unknown id answers the same way, so this is not confirmation the item existed.)');
107
+ }
95
108
  export async function widget(sub, arg, flags) {
96
109
  const config = requireConfig();
97
110
  const orgId = requireOrg(flags, config, 'myapi feedback widget create <name> | revoke <id>');
@@ -128,6 +141,11 @@ export async function widget(sub, arg, flags) {
128
141
  error('Usage: myapi feedback widget create <name> [--origins <list>]\n myapi feedback widget revoke <id>');
129
142
  }
130
143
  const SUBCOMMAND_USAGE = {
144
+ 'delete': `myapi feedback delete <id> [--yes] [--org <id>]
145
+
146
+ Erases an item. \`resolve\` closes one and keeps it; this removes it — for spam,
147
+ or a report where somebody typed personal details into the box. Idempotent, and
148
+ an unknown id answers the same way.`,
131
149
  'list': `myapi feedback list [--kind bug|issue|suggestion] [--status open|resolved]
132
150
  [--limit N] [--offset N] [--org <id>] [--json]
133
151
 
@@ -151,6 +169,7 @@ page submit without a credential; you list, filter and resolve the results.
151
169
 
152
170
  Subcommands:
153
171
  create "<text>" Record one piece of feedback (--kind bug|issue|suggestion)
172
+ delete <id> Erase an item (resolve keeps it; this does not)
154
173
  list List feedback, newest first (--kind, --status, --limit, --offset)
155
174
  resolve <id> Close a piece of feedback
156
175
  widget create <name> Mint a PUBLIC widget key for a site (--origins to restrict)
@@ -167,6 +186,7 @@ All commands accept --org <id> (or set default: myapi config set-org <id>).`);
167
186
  switch (subcommand) {
168
187
  case 'create': return create(args[0], flags);
169
188
  case 'list': return list(flags);
189
+ case 'delete': return del(args[0], flags);
170
190
  case 'resolve': return resolve(args[0], flags);
171
191
  case 'widget': return widget(args[0], args[1], flags);
172
192
  default: error(`Unknown subcommand: ${subcommand}. Run "myapi feedback --help" for a list of valid subcommands.`);
@@ -1,10 +1,10 @@
1
1
  ---
2
2
  name: my-feedback-api
3
- version: 1.0.0
3
+ version: 1.2.0
4
4
  description: >
5
5
  Collect feedback from the people using what you built. A public widget key lets a page submit without a credential; you list, filter and resolve the results. Kind is chosen by the person reporting, not inferred from their wording.
6
6
  triggers: [feedback, bug report, user feedback, feature request, widget, support, complaints, praise]
7
- checksum: sha256-41627c4bdf19a5af131adc0e7bab76816e7be47acdc15601bdcef7cdb47b2e26
7
+ checksum: sha256-199fba185e85ccc91a6858bce4a60e20167a6591dee28cbc475606c72cb8d787
8
8
  ---
9
9
 
10
10
  # MyFeedbackAPI
@@ -33,12 +33,44 @@ myapi feedback widget create site --origins app.example.com,example.com
33
33
  Revoke with `myapi feedback widget revoke <id>`. Submissions stop immediately;
34
34
  feedback already collected is kept.
35
35
 
36
- **The browser-side submit contract is not documented yet.** The CLI and SDK
37
- cover minting, revoking, listing and resolving; how a page posts with only the
38
- widget key is not published anywhere you can read it, so don't guess the
39
- endpoint. Until it lands, collect through a route you control a funnel form
40
- (`my-funnel-api`) or a webhook (`my-webhook-api`) — and file items with
41
- `myapi feedback create`.
36
+ ### Embedding it: one script tag
37
+
38
+ The platform hosts the widget, compiled per key with that widget's routes and
39
+ theme baked in. This is the intended way in you do not build a UI:
40
+
41
+ ```html
42
+ <script src="https://api.myapihq.com/feedback/in/<widget_key>/widget.js" async></script>
43
+ ```
44
+
45
+ It renders a button, shows itself only on the routes the widget is configured
46
+ for, and lets the person point at an element or drag a region. It sends `kind`,
47
+ `body`, `page_url`, `route`, `viewport`, plus **either** `target_selector` (they
48
+ clicked something) **or** `target_region` `{x,y,w,h}` (they dragged a box).
49
+
50
+ A wrong key does not break the page: the response is `application/javascript`
51
+ carrying a JS comment that names the fix, so a typo cannot throw a syntax error
52
+ in your app.
53
+
54
+ **No screenshots.** The submit body takes no image and there is no multipart
55
+ form — `target_selector` / `target_region` are the platform's answer to "where
56
+ were they pointing". Do not build a capture step expecting somewhere to put it.
57
+
58
+ ### Submitting by hand (only if you cannot use the script)
59
+
60
+ `POST https://api.myapihq.com/feedback/in/<widget_key>` — no auth, no SDK.
61
+ Same fields the widget sends:
62
+
63
+ ```js
64
+ await fetch(`https://api.myapihq.com/feedback/in/${WIDGET_KEY}`, {
65
+ method: 'POST',
66
+ headers: { 'Content-Type': 'application/json' },
67
+ body: JSON.stringify({ kind: 'bug', body: text, page_url: location.href }),
68
+ });
69
+ ```
70
+
71
+ Errors: `WIDGET_NOT_FOUND` (a revoked key reads like an invented one, so keys
72
+ cannot be probed), `ORIGIN_NOT_ALLOWED`, `RATE_LIMITED`, `INVALID_KIND`,
73
+ `BODY_REQUIRED`, `BODY_TOO_LONG`. The key only ever writes.
42
74
 
43
75
  ### Kind is a claim, not a guess
44
76
 
@@ -69,7 +101,8 @@ that is deliberate, so ids cannot be probed across orgs.
69
101
  |---|---|
70
102
  | `myapi feedback create "<text>" --kind <k>` | Record one item (`--page-url`, `--route` for context) |
71
103
  | `myapi feedback list [--kind bug\|issue\|suggestion] [--status open\|resolved] [--limit N] [--offset N]` | List feedback, newest first |
72
- | `myapi feedback resolve <id>` | Close an item |
104
+ | `myapi feedback resolve <id>` | Close an item, keeping it |
105
+ | `myapi feedback delete <id>` | Erase an item — for spam, or personal details typed into the box |
73
106
  | `myapi feedback widget create <name> [--origins a.com,b.com]` | Mint a PUBLIC widget key for a site |
74
107
  | `myapi feedback widget revoke <id>` | Revoke a key; collected feedback is kept |
75
108
  <!-- generated:end -->
@@ -99,6 +132,9 @@ myapi feedback resolve <id>
99
132
  - The widget key is public by design — restrict it with `--origins` rather than hiding it.
100
133
  - `resolve` is idempotent and deliberately indistinguishable from an unknown id.
101
134
  - Feedback survives widget revocation.
135
+ - **`resolve` keeps, `delete` erases.** A public inbox collects spam and the
136
+ occasional report with personal details in it; `delete` is how those leave.
137
+ Both are idempotent and answer the same for an unknown id.
102
138
 
103
139
  ## HTTP (from deployed code)
104
140
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@myapihq/cli",
3
3
  "license": "Apache-2.0",
4
- "version": "2.11.1",
4
+ "version": "2.12.0",
5
5
  "description": "MyAPI command-line interface",
6
6
  "repository": {
7
7
  "type": "git",
@@ -46,7 +46,7 @@
46
46
  "lint:skills:strict": "node scripts/copy-skills.js && node scripts/lint-skills.js --strict"
47
47
  },
48
48
  "dependencies": {
49
- "@myapihq/sdk": "^2.11.1"
49
+ "@myapihq/sdk": "^2.12.0"
50
50
  },
51
51
  "devDependencies": {
52
52
  "@types/node": "^25.6.0",