@mushi-mushi/core 1.28.0 → 1.30.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.
@@ -0,0 +1,131 @@
1
+ /**
2
+ * FILE: reporter-ui.ts
3
+ * PURPOSE: The one reporter-facing vocabulary shared by every SDK widget
4
+ * (web, React Native, Capacitor): report categories, the end-user
5
+ * status table, the timeline kinds and their copy in en/ja/es/th.
6
+ *
7
+ * OVERVIEW:
8
+ * - `reporterStatus(report, locale)` maps all 14 internal `reports.status`
9
+ * values (plus the `awaiting_reporter` and duplicate-group overlays and the
10
+ * feature-request variants) onto eight end-user states. There is no branch
11
+ * that echoes the raw status: an unknown value reads as "Received".
12
+ * - `reporterTimelineText(kind, params, locale)` renders pipeline events from
13
+ * a fixed template per kind. Stored notification payload text is never
14
+ * shown, so internal category / severity can not leak to a reporter.
15
+ *
16
+ * USAGE:
17
+ * - `import { reporterStatus } from '@mushi-mushi/core/reporter-ui'`
18
+ * - Shipped as a subpath so the main `@mushi-mushi/core` entry stays within
19
+ * its size budget; nothing here is re-exported from `index.ts`.
20
+ *
21
+ * Plan 018 (docs/execplans/reporter-loop-v2.md) §2.1 and §2.3.
22
+ */
23
+ /** Every value `reports_status_check` allows. Pinned to the server list by a test. */
24
+ declare const REPORTER_CANONICAL_STATUSES: readonly ["new", "pending", "submitted", "queued", "classified", "grouped", "fixing", "fixed", "dismissed", "triaged", "in_progress", "resolved", "verified", "reopened"];
25
+ type ReporterCanonicalStatus = (typeof REPORTER_CANONICAL_STATUSES)[number];
26
+ declare const REPORTER_LOCALES: readonly ["en", "ja", "es", "th"];
27
+ type ReporterLocale = (typeof REPORTER_LOCALES)[number];
28
+ /** Optional type chips on the one-screen report form, in display order. */
29
+ declare const REPORTER_CATEGORIES: readonly ["bug", "slow", "visual", "confusing", "idea"];
30
+ type ReporterCategory = (typeof REPORTER_CATEGORIES)[number];
31
+ /** `closed_reason` values the `reports_closed_reason_check` constraint allows. */
32
+ declare const REPORTER_CLOSED_REASONS: readonly ["duplicate", "not_reproducible", "wont_fix", "working_as_intended", "spam"];
33
+ type ReporterClosedReason = (typeof REPORTER_CLOSED_REASONS)[number];
34
+ type ReporterTone = 'neutral' | 'info' | 'attention' | 'progress' | 'success' | 'success-muted' | 'muted';
35
+ /** The end-user state a report is shown in. */
36
+ type ReporterStatusKey = 'received' | 'reviewing' | 'reviewing_again' | 'fixing' | 'verified' | 'fixed_next' | 'fixed_version' | 'fixed' | 'closed' | 'waiting';
37
+ /** Timeline entry kinds the reporter detail view renders (§2.3). */
38
+ declare const REPORTER_TIMELINE_KINDS: readonly ["received", "reviewing", "duplicate_linked", "info_requested", "comment", "reporter_comment", "fix_started", "fixed", "released", "verified", "reopened", "closed"];
39
+ type ReporterTimelineKind = (typeof REPORTER_TIMELINE_KINDS)[number];
40
+ interface ReporterCopy {
41
+ status: Record<ReporterStatusKey, string>;
42
+ detail: Record<ReporterStatusKey, string>;
43
+ idea: {
44
+ received: string;
45
+ reviewing: string;
46
+ fixing: string;
47
+ shipped: string;
48
+ shippedVersion: string;
49
+ };
50
+ closedReason: Record<Exclude<ReporterClosedReason, 'spam'>, string> & {
51
+ none: string;
52
+ };
53
+ others: {
54
+ few: string;
55
+ many: string;
56
+ };
57
+ timeline: Record<Exclude<ReporterTimelineKind, 'comment' | 'closed'>, string>;
58
+ categories: Record<ReporterCategory, string>;
59
+ ui: {
60
+ yes: string;
61
+ notYet: string;
62
+ empty: string;
63
+ loadError: string;
64
+ retry: string;
65
+ sending: string;
66
+ sent: string;
67
+ sendFailed: string;
68
+ noReplies: string;
69
+ you: string;
70
+ developer: string;
71
+ addWords: string;
72
+ developerReplied: string;
73
+ updates: string;
74
+ };
75
+ }
76
+ /** Resolve a BCP-47 tag (`ja-JP`, `es-419`) to a supported locale; English otherwise. */
77
+ declare function resolveReporterLocale(tag: string | null | undefined): ReporterLocale;
78
+ /** The full copy table for a locale (unknown tags fall back to English). */
79
+ declare function reporterCopy(locale?: string): ReporterCopy;
80
+ /** Replace `{name}` placeholders; a missing value leaves an empty string. */
81
+ declare function fillReporterTemplate(template: string, params?: Record<string, string | number | null | undefined>): string;
82
+ /** Fields of a reporter-list row `reporterStatus` reads. All but `status` are optional. */
83
+ interface ReporterStatusInput {
84
+ status: string;
85
+ /** True (or a timestamp) while the developer waits for the reporter. */
86
+ awaiting_reporter?: boolean | null;
87
+ awaiting_reporter_at?: string | null;
88
+ fixed_in_version?: string | null;
89
+ closed_reason?: string | null;
90
+ /** Bucketed duplicate count; never a raw number. */
91
+ group_bucket?: 'none' | 'few' | 'many' | null;
92
+ /** `user_category`; "Feature request" / "idea" selects the idea labels. */
93
+ user_category?: string | null;
94
+ }
95
+ interface ReporterStatusView {
96
+ key: ReporterStatusKey;
97
+ label: string;
98
+ tone: ReporterTone;
99
+ detail: string;
100
+ /** Show the Yes / Not yet verification buttons. */
101
+ canVerify: boolean;
102
+ /** "You and a few others reported this", or null. */
103
+ othersNote: string | null;
104
+ /** `closed_reason = 'spam'`: hide the report from the reporter entirely. */
105
+ hidden: boolean;
106
+ }
107
+ /** True when the row is a feature request rather than a bug. */
108
+ declare function isReporterIdea(input: Pick<ReporterStatusInput, 'user_category'>): boolean;
109
+ /**
110
+ * The end-user view of a report. Overlays are checked before the base
111
+ * status: "Waiting on you" wins for any open report, and the duplicate-group
112
+ * note is added on top of whatever the base state is.
113
+ */
114
+ declare function reporterStatus(input: ReporterStatusInput, locale?: string): ReporterStatusView;
115
+ /** Parameters a timeline template may interpolate. */
116
+ interface ReporterTimelineParams {
117
+ /** Verbatim developer text for `comment` and `info_requested`; the reporter's own for `reporter_comment`. */
118
+ text?: string | null;
119
+ version?: string | null;
120
+ closed_reason?: string | null;
121
+ }
122
+ /**
123
+ * Render one timeline entry. Pipeline kinds always come from the template for
124
+ * their kind; only the developer's own words (`comment`, `info_requested`) are
125
+ * passed through, verbatim.
126
+ */
127
+ declare function reporterTimelineText(kind: ReporterTimelineKind, params?: ReporterTimelineParams, locale?: string): string;
128
+ /** Reporter-facing label for a category chip. */
129
+ declare function reporterCategoryLabel(category: ReporterCategory, locale?: string): string;
130
+
131
+ export { REPORTER_CANONICAL_STATUSES, REPORTER_CATEGORIES, REPORTER_CLOSED_REASONS, REPORTER_LOCALES, REPORTER_TIMELINE_KINDS, type ReporterCanonicalStatus, type ReporterCategory, type ReporterClosedReason, type ReporterCopy, type ReporterLocale, type ReporterStatusInput, type ReporterStatusKey, type ReporterStatusView, type ReporterTimelineKind, type ReporterTimelineParams, type ReporterTone, fillReporterTemplate, isReporterIdea, reporterCategoryLabel, reporterCopy, reporterStatus, reporterTimelineText, resolveReporterLocale };
@@ -0,0 +1,131 @@
1
+ /**
2
+ * FILE: reporter-ui.ts
3
+ * PURPOSE: The one reporter-facing vocabulary shared by every SDK widget
4
+ * (web, React Native, Capacitor): report categories, the end-user
5
+ * status table, the timeline kinds and their copy in en/ja/es/th.
6
+ *
7
+ * OVERVIEW:
8
+ * - `reporterStatus(report, locale)` maps all 14 internal `reports.status`
9
+ * values (plus the `awaiting_reporter` and duplicate-group overlays and the
10
+ * feature-request variants) onto eight end-user states. There is no branch
11
+ * that echoes the raw status: an unknown value reads as "Received".
12
+ * - `reporterTimelineText(kind, params, locale)` renders pipeline events from
13
+ * a fixed template per kind. Stored notification payload text is never
14
+ * shown, so internal category / severity can not leak to a reporter.
15
+ *
16
+ * USAGE:
17
+ * - `import { reporterStatus } from '@mushi-mushi/core/reporter-ui'`
18
+ * - Shipped as a subpath so the main `@mushi-mushi/core` entry stays within
19
+ * its size budget; nothing here is re-exported from `index.ts`.
20
+ *
21
+ * Plan 018 (docs/execplans/reporter-loop-v2.md) §2.1 and §2.3.
22
+ */
23
+ /** Every value `reports_status_check` allows. Pinned to the server list by a test. */
24
+ declare const REPORTER_CANONICAL_STATUSES: readonly ["new", "pending", "submitted", "queued", "classified", "grouped", "fixing", "fixed", "dismissed", "triaged", "in_progress", "resolved", "verified", "reopened"];
25
+ type ReporterCanonicalStatus = (typeof REPORTER_CANONICAL_STATUSES)[number];
26
+ declare const REPORTER_LOCALES: readonly ["en", "ja", "es", "th"];
27
+ type ReporterLocale = (typeof REPORTER_LOCALES)[number];
28
+ /** Optional type chips on the one-screen report form, in display order. */
29
+ declare const REPORTER_CATEGORIES: readonly ["bug", "slow", "visual", "confusing", "idea"];
30
+ type ReporterCategory = (typeof REPORTER_CATEGORIES)[number];
31
+ /** `closed_reason` values the `reports_closed_reason_check` constraint allows. */
32
+ declare const REPORTER_CLOSED_REASONS: readonly ["duplicate", "not_reproducible", "wont_fix", "working_as_intended", "spam"];
33
+ type ReporterClosedReason = (typeof REPORTER_CLOSED_REASONS)[number];
34
+ type ReporterTone = 'neutral' | 'info' | 'attention' | 'progress' | 'success' | 'success-muted' | 'muted';
35
+ /** The end-user state a report is shown in. */
36
+ type ReporterStatusKey = 'received' | 'reviewing' | 'reviewing_again' | 'fixing' | 'verified' | 'fixed_next' | 'fixed_version' | 'fixed' | 'closed' | 'waiting';
37
+ /** Timeline entry kinds the reporter detail view renders (§2.3). */
38
+ declare const REPORTER_TIMELINE_KINDS: readonly ["received", "reviewing", "duplicate_linked", "info_requested", "comment", "reporter_comment", "fix_started", "fixed", "released", "verified", "reopened", "closed"];
39
+ type ReporterTimelineKind = (typeof REPORTER_TIMELINE_KINDS)[number];
40
+ interface ReporterCopy {
41
+ status: Record<ReporterStatusKey, string>;
42
+ detail: Record<ReporterStatusKey, string>;
43
+ idea: {
44
+ received: string;
45
+ reviewing: string;
46
+ fixing: string;
47
+ shipped: string;
48
+ shippedVersion: string;
49
+ };
50
+ closedReason: Record<Exclude<ReporterClosedReason, 'spam'>, string> & {
51
+ none: string;
52
+ };
53
+ others: {
54
+ few: string;
55
+ many: string;
56
+ };
57
+ timeline: Record<Exclude<ReporterTimelineKind, 'comment' | 'closed'>, string>;
58
+ categories: Record<ReporterCategory, string>;
59
+ ui: {
60
+ yes: string;
61
+ notYet: string;
62
+ empty: string;
63
+ loadError: string;
64
+ retry: string;
65
+ sending: string;
66
+ sent: string;
67
+ sendFailed: string;
68
+ noReplies: string;
69
+ you: string;
70
+ developer: string;
71
+ addWords: string;
72
+ developerReplied: string;
73
+ updates: string;
74
+ };
75
+ }
76
+ /** Resolve a BCP-47 tag (`ja-JP`, `es-419`) to a supported locale; English otherwise. */
77
+ declare function resolveReporterLocale(tag: string | null | undefined): ReporterLocale;
78
+ /** The full copy table for a locale (unknown tags fall back to English). */
79
+ declare function reporterCopy(locale?: string): ReporterCopy;
80
+ /** Replace `{name}` placeholders; a missing value leaves an empty string. */
81
+ declare function fillReporterTemplate(template: string, params?: Record<string, string | number | null | undefined>): string;
82
+ /** Fields of a reporter-list row `reporterStatus` reads. All but `status` are optional. */
83
+ interface ReporterStatusInput {
84
+ status: string;
85
+ /** True (or a timestamp) while the developer waits for the reporter. */
86
+ awaiting_reporter?: boolean | null;
87
+ awaiting_reporter_at?: string | null;
88
+ fixed_in_version?: string | null;
89
+ closed_reason?: string | null;
90
+ /** Bucketed duplicate count; never a raw number. */
91
+ group_bucket?: 'none' | 'few' | 'many' | null;
92
+ /** `user_category`; "Feature request" / "idea" selects the idea labels. */
93
+ user_category?: string | null;
94
+ }
95
+ interface ReporterStatusView {
96
+ key: ReporterStatusKey;
97
+ label: string;
98
+ tone: ReporterTone;
99
+ detail: string;
100
+ /** Show the Yes / Not yet verification buttons. */
101
+ canVerify: boolean;
102
+ /** "You and a few others reported this", or null. */
103
+ othersNote: string | null;
104
+ /** `closed_reason = 'spam'`: hide the report from the reporter entirely. */
105
+ hidden: boolean;
106
+ }
107
+ /** True when the row is a feature request rather than a bug. */
108
+ declare function isReporterIdea(input: Pick<ReporterStatusInput, 'user_category'>): boolean;
109
+ /**
110
+ * The end-user view of a report. Overlays are checked before the base
111
+ * status: "Waiting on you" wins for any open report, and the duplicate-group
112
+ * note is added on top of whatever the base state is.
113
+ */
114
+ declare function reporterStatus(input: ReporterStatusInput, locale?: string): ReporterStatusView;
115
+ /** Parameters a timeline template may interpolate. */
116
+ interface ReporterTimelineParams {
117
+ /** Verbatim developer text for `comment` and `info_requested`; the reporter's own for `reporter_comment`. */
118
+ text?: string | null;
119
+ version?: string | null;
120
+ closed_reason?: string | null;
121
+ }
122
+ /**
123
+ * Render one timeline entry. Pipeline kinds always come from the template for
124
+ * their kind; only the developer's own words (`comment`, `info_requested`) are
125
+ * passed through, verbatim.
126
+ */
127
+ declare function reporterTimelineText(kind: ReporterTimelineKind, params?: ReporterTimelineParams, locale?: string): string;
128
+ /** Reporter-facing label for a category chip. */
129
+ declare function reporterCategoryLabel(category: ReporterCategory, locale?: string): string;
130
+
131
+ export { REPORTER_CANONICAL_STATUSES, REPORTER_CATEGORIES, REPORTER_CLOSED_REASONS, REPORTER_LOCALES, REPORTER_TIMELINE_KINDS, type ReporterCanonicalStatus, type ReporterCategory, type ReporterClosedReason, type ReporterCopy, type ReporterLocale, type ReporterStatusInput, type ReporterStatusKey, type ReporterStatusView, type ReporterTimelineKind, type ReporterTimelineParams, type ReporterTone, fillReporterTemplate, isReporterIdea, reporterCategoryLabel, reporterCopy, reporterStatus, reporterTimelineText, resolveReporterLocale };