@supersuit/suggest-a-change 0.2.0 → 0.2.1
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/CHANGELOG.md +5 -0
- package/README.md +1 -1
- package/dist/github/compose.d.ts +8 -1
- package/dist/github/compose.js +4 -1
- package/package.json +5 -2
- package/src/github/compose.ts +10 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.2.1 (2026-10-26)
|
|
4
|
+
|
|
5
|
+
- **The sheet says when a relay opens the issue.** `Destination` takes `via: 'direct' | 'relay'` and `relayApp` (the relay's app name as people see it). With `via: 'relay'`, `destinationWords` says "Opened by the Supersuit Suggestions app on GitHub, which says it came from <name>." instead of naming a GitHub account that does not open it ("Filed from <account>'s GitHub account."); without a name it says "came from you", without an app name "a suggestions app". The Helm is the first user: its own Mac's account usually cannot push to the repo, so Supersuit files through the relay.
|
|
6
|
+
- **The contract export is typed.** `"."` is now `{ types: "./dist/contract.d.mts", default: "./src/contract.mjs" }`, so a TypeScript host (the Helm's server, which checks a report's context with `validContext`) imports it with its types instead of an implicit any. Plain ESM imports are unchanged.
|
|
7
|
+
|
|
3
8
|
## 0.2.0 (2026-10-26)
|
|
4
9
|
|
|
5
10
|
A suggestion now becomes one ordinary GitHub issue, with everything it was sent with, in the repo that owns the app. A minor version because the statuses changed: apps on `^0.1` stay on 0.1 until they take this one.
|
package/README.md
CHANGED
|
@@ -97,7 +97,7 @@ The trail (pages, taps, errors) is kept from the moment any of the module's scre
|
|
|
97
97
|
|
|
98
98
|
The issue carries it all in a "Context (shared so this can be fixed)" table of what, value and why (in place of the About line), the trail in collapsible blocks, and a "Reach them" section with `mailto:` and `tel:` links "To thank them or ask a follow-up question". When the body would pass GitHub's limit, the trail is cut first (oldest taps, then pages, then errors), then the transcript.
|
|
99
99
|
|
|
100
|
-
**Where it files.** With the optional `destination()` adapter, answering `{ repo, public, account, attaches, name? }`, that line becomes the list of exactly what the issue will carry ("your words · your voice note and its transcript · 2 screenshots, saved to the suggestion-attachments branch of acme/notes · this screen (Photos, /photos) · notes 1.2.3 · iPhone, 390x844 · the time · your name, Alex Kim"), the repo it files on, who can read it there (a public repo says so in `--sac-danger`), and whose GitHub account files it. The list follows the draft as things are added or removed, and it is built by `whatGoes` from `./github`, the same pieces `composeIssue` writes the body from, so the sheet and the issue cannot drift. `attaches: false` says files wait until the repo can take them. Sending is the consent. Without the adapter (or when it answers null) the sheet keeps the one line. My suggestions and the detail view link the issue a report became ("Issue #7"); a member who cannot read the repo still sees the number and the state.
|
|
100
|
+
**Where it files.** With the optional `destination()` adapter, answering `{ repo, public, account, attaches, name? }`, that line becomes the list of exactly what the issue will carry ("your words · your voice note and its transcript · 2 screenshots, saved to the suggestion-attachments branch of acme/notes · this screen (Photos, /photos) · notes 1.2.3 · iPhone, 390x844 · the time · your name, Alex Kim"), the repo it files on, who can read it there (a public repo says so in `--sac-danger`), and whose GitHub account files it. The list follows the draft as things are added or removed, and it is built by `whatGoes` from `./github`, the same pieces `composeIssue` writes the body from, so the sheet and the issue cannot drift. `attaches: false` says files wait until the repo can take them. With `via: "relay"` (and `relayApp`, the relay's app name as people see it) the account line says the issue is opened by that app and whose it is ("Opened by the Supersuit Suggestions app on GitHub, which says it came from Alex Kim."), since the filer's own account is not what opens it. Sending is the consent. Without the adapter (or when it answers null) the sheet keeps the one line. My suggestions and the detail view link the issue a report became ("Issue #7"); a member who cannot read the repo still sees the number and the state.
|
|
101
101
|
|
|
102
102
|
**Identity.** Every screen asks `adapters.identity()` when it mounts, whenever it is handed a different `adapters` object, and whenever the host calls `refreshIdentity()` (exported from `"./client"`; call it after a sign-in, sign-out or account switch). When the account differs, the old account's rows leave the screen and its waiting reports stay on the phone, to be sent only while that account is signed in; every send re-confirms the account first. Keep `adapters` stable where you can; a parent that rebuilds it every render is safe, only slower (one `identity()` call per render).
|
|
103
103
|
|
package/dist/github/compose.d.ts
CHANGED
|
@@ -50,6 +50,11 @@ export interface Destination {
|
|
|
50
50
|
transcribes?: boolean;
|
|
51
51
|
/** The largest file this destination takes; a larger one is named in the list as staying on the phone. */
|
|
52
52
|
maxInlineBytes?: number;
|
|
53
|
+
/** How the issue is opened: `direct` from `account`, or `relay` by a relay's GitHub App (createSuggestionRelay), which names the
|
|
54
|
+
* sender in the issue. With `relay` the sheet's account line says the app opens it and whose it is, not `account`. */
|
|
55
|
+
via?: 'direct' | 'relay';
|
|
56
|
+
/** The relay's app name as people see it ("Acme Suggestions"), for that line. */
|
|
57
|
+
relayApp?: string;
|
|
53
58
|
}
|
|
54
59
|
/** What composeIssue and whatGoes read: a report in the contract's shape, plus two optional names for the list. */
|
|
55
60
|
export interface Draft {
|
|
@@ -137,7 +142,9 @@ export declare const PUBLIC_CONTACT_REASON = "this repo is public, so anyone cou
|
|
|
137
142
|
* of context. Anything but what the person added, the app's version and their name can be left out (`optional`). */
|
|
138
143
|
export declare function whatGoes(draft: Draft, destination: Destination): GoesItem[];
|
|
139
144
|
/** The lines around the list: where it files, who can read it there, and whose account files it. */
|
|
140
|
-
export declare function destinationWords(d: Destination
|
|
145
|
+
export declare function destinationWords(d: Destination & {
|
|
146
|
+
name?: string;
|
|
147
|
+
}): {
|
|
141
148
|
headline: string;
|
|
142
149
|
privacy: string;
|
|
143
150
|
danger: boolean;
|
package/dist/github/compose.js
CHANGED
|
@@ -115,11 +115,14 @@ function basicGoes(draft, destination) {
|
|
|
115
115
|
}
|
|
116
116
|
/** The lines around the list: where it files, who can read it there, and whose account files it. */
|
|
117
117
|
export function destinationWords(d) {
|
|
118
|
+
// Through a relay the issue is opened by the relay's GitHub App, not by the sender's account: say so, and say whose it is.
|
|
119
|
+
const sender = typeof d.name === 'string' && d.name.trim() ? d.name.trim() : 'you';
|
|
120
|
+
const app = typeof d.relayApp === 'string' && d.relayApp.trim() ? `the ${d.relayApp.trim()} app` : 'a suggestions app';
|
|
118
121
|
return {
|
|
119
122
|
headline: `Sending this files an issue on ${d.repo}`,
|
|
120
123
|
privacy: d.public ? 'public: anyone on the internet can read this' : `private: people with access to ${d.repo}'s code can read it`,
|
|
121
124
|
danger: Boolean(d.public),
|
|
122
|
-
account: `Filed from ${d.account}'s GitHub account.`,
|
|
125
|
+
account: d.via === 'relay' ? `Opened by ${app} on GitHub, which says it came from ${sender}.` : `Filed from ${d.account}'s GitHub account.`,
|
|
123
126
|
};
|
|
124
127
|
}
|
|
125
128
|
/** "2026-10-26T17:04:12Z" -> "2026-10-26 17:04 UTC"; anything unreadable as it is. */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@supersuit/suggest-a-change",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "The report format and flow behind a Suggest a change button: what a report is, who acts at each step, the screens, and the check every app runs. The contract has zero dependencies.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -8,7 +8,10 @@
|
|
|
8
8
|
"suggest-a-change-check": "bin/check.mjs"
|
|
9
9
|
},
|
|
10
10
|
"exports": {
|
|
11
|
-
".":
|
|
11
|
+
".": {
|
|
12
|
+
"types": "./dist/contract.d.mts",
|
|
13
|
+
"default": "./src/contract.mjs"
|
|
14
|
+
},
|
|
12
15
|
"./client": {
|
|
13
16
|
"types": "./dist/client/index.d.ts",
|
|
14
17
|
"import": "./dist/client/index.js"
|
package/src/github/compose.ts
CHANGED
|
@@ -28,6 +28,11 @@ export interface Destination {
|
|
|
28
28
|
transcribes?: boolean
|
|
29
29
|
/** The largest file this destination takes; a larger one is named in the list as staying on the phone. */
|
|
30
30
|
maxInlineBytes?: number
|
|
31
|
+
/** How the issue is opened: `direct` from `account`, or `relay` by a relay's GitHub App (createSuggestionRelay), which names the
|
|
32
|
+
* sender in the issue. With `relay` the sheet's account line says the app opens it and whose it is, not `account`. */
|
|
33
|
+
via?: 'direct' | 'relay'
|
|
34
|
+
/** The relay's app name as people see it ("Acme Suggestions"), for that line. */
|
|
35
|
+
relayApp?: string
|
|
31
36
|
}
|
|
32
37
|
/** What composeIssue and whatGoes read: a report in the contract's shape, plus two optional names for the list. */
|
|
33
38
|
export interface Draft {
|
|
@@ -167,12 +172,15 @@ function basicGoes(draft: Draft, destination: Destination): GoesItem[] {
|
|
|
167
172
|
}
|
|
168
173
|
|
|
169
174
|
/** The lines around the list: where it files, who can read it there, and whose account files it. */
|
|
170
|
-
export function destinationWords(d: Destination): { headline: string; privacy: string; danger: boolean; account: string } {
|
|
175
|
+
export function destinationWords(d: Destination & { name?: string }): { headline: string; privacy: string; danger: boolean; account: string } {
|
|
176
|
+
// Through a relay the issue is opened by the relay's GitHub App, not by the sender's account: say so, and say whose it is.
|
|
177
|
+
const sender = typeof d.name === 'string' && d.name.trim() ? d.name.trim() : 'you'
|
|
178
|
+
const app = typeof d.relayApp === 'string' && d.relayApp.trim() ? `the ${d.relayApp.trim()} app` : 'a suggestions app'
|
|
171
179
|
return {
|
|
172
180
|
headline: `Sending this files an issue on ${d.repo}`,
|
|
173
181
|
privacy: d.public ? 'public: anyone on the internet can read this' : `private: people with access to ${d.repo}'s code can read it`,
|
|
174
182
|
danger: Boolean(d.public),
|
|
175
|
-
account: `Filed from ${d.account}'s GitHub account.`,
|
|
183
|
+
account: d.via === 'relay' ? `Opened by ${app} on GitHub, which says it came from ${sender}.` : `Filed from ${d.account}'s GitHub account.`,
|
|
176
184
|
}
|
|
177
185
|
}
|
|
178
186
|
|