@perrylink/dsh-github 0.7.10 → 0.7.13
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-es.md +63 -50
- package/README-hi.md +58 -45
- package/README-pt.md +63 -50
- package/README-zh.md +58 -45
- package/README.md +30 -17
- package/action.yml +1 -1
- package/lib/approval-gate.d.ts.map +1 -1
- package/lib/approval-gate.js +6 -0
- package/lib/approval-gate.js.map +1 -1
- package/lib/ci/bot.d.ts.map +1 -1
- package/lib/ci/bot.js +48 -9
- package/lib/ci/bot.js.map +1 -1
- package/lib/client.d.ts +272 -0
- package/lib/client.d.ts.map +1 -0
- package/lib/client.js +291 -305
- package/lib/client.js.map +1 -0
- package/lib/commands.d.ts.map +1 -1
- package/lib/commands.js +5 -2
- package/lib/commands.js.map +1 -1
- package/lib/index.d.ts +13 -21
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +16 -29
- package/lib/index.js.map +1 -1
- package/lib/jobs.d.ts.map +1 -1
- package/lib/jobs.js +9 -22
- package/lib/jobs.js.map +1 -1
- package/lib/message-source.d.ts +10 -0
- package/lib/message-source.d.ts.map +1 -0
- package/lib/message-source.js +2 -0
- package/lib/message-source.js.map +1 -0
- package/lib/types.d.ts +38 -86
- package/lib/types.d.ts.map +1 -1
- package/package.json +41 -23
- package/scripts/action-patch.mjs +1 -1
- package/scripts/check-readmes.mjs +3 -1
- package/scripts/local-test.mjs +2 -2
package/lib/client.js
CHANGED
|
@@ -1,305 +1,291 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
//#endregion
|
|
293
|
-
exports.DEFAULT_TOKEN_REF = DEFAULT_TOKEN_REF;
|
|
294
|
-
exports.GITHUB_NS = GITHUB_NS;
|
|
295
|
-
exports.GithubCard = GithubCard;
|
|
296
|
-
exports.GithubCardController = GithubCardController;
|
|
297
|
-
exports.NS = NS;
|
|
298
|
-
exports.apply = apply;
|
|
299
|
-
exports.createSnapshotStore = createSnapshotStore;
|
|
300
|
-
exports.en = en;
|
|
301
|
-
exports.inject = inject;
|
|
302
|
-
exports.zh = zh;
|
|
303
|
-
return module.exports;
|
|
304
|
-
}
|
|
305
|
-
});
|
|
1
|
+
/**
|
|
2
|
+
* dsh-github browser half — one card in the Plugins page's Official group.
|
|
3
|
+
*
|
|
4
|
+
* The card reports and edits the GitHub token. The token literal never rides
|
|
5
|
+
* the settings document: it is written through the credentials domain,
|
|
6
|
+
* addressed by the reference the plugin's cordis.yml `Config.tokenRef` names
|
|
7
|
+
* (default `GITHUB_TOKEN`), which is exactly where the host half resolves it —
|
|
8
|
+
* per operation, no restart needed.
|
|
9
|
+
*
|
|
10
|
+
* Since host 0.1.7-alpha.1 the page owns configuration: the card renders the
|
|
11
|
+
* `summary` one-liner and the `page` body from the `plugins.item` owner props
|
|
12
|
+
* (`view`, and the `form` the Plugins page supplies), instead of binding a
|
|
13
|
+
* `settingsScope` itself — that service, `settings.plugin.item`'s old shape,
|
|
14
|
+
* and the `dsh-settings-file` package behind them were all removed. The card
|
|
15
|
+
* therefore reads `tokenRef` from `form.state.value` and never writes the
|
|
16
|
+
* settings document; the credential is written through the credentials
|
|
17
|
+
* domain, which is a different seam and stayed.
|
|
18
|
+
*
|
|
19
|
+
* The shipped `lib/client.js` is the built bundle of this module. The browser
|
|
20
|
+
* module loader executes that bundle, not this file.
|
|
21
|
+
* @module @perrylink/dsh-github/client
|
|
22
|
+
*/
|
|
23
|
+
import { createElement, useState } from 'react';
|
|
24
|
+
import { Button, IconLoadingOutline16, } from '@deepseek-ai/dsh-client-ui-primitives';
|
|
25
|
+
/**
|
|
26
|
+
* Create the minimal card store.
|
|
27
|
+
* @param init - initial state.
|
|
28
|
+
* @returns the store.
|
|
29
|
+
*/
|
|
30
|
+
export function createSnapshotStore(init) {
|
|
31
|
+
let state = init;
|
|
32
|
+
const listeners = new Set();
|
|
33
|
+
return {
|
|
34
|
+
getSnapshot: () => state,
|
|
35
|
+
subscribe: (listener) => {
|
|
36
|
+
listeners.add(listener);
|
|
37
|
+
return () => { listeners.delete(listener); };
|
|
38
|
+
},
|
|
39
|
+
set: (next) => {
|
|
40
|
+
state = next;
|
|
41
|
+
for (const listener of [...listeners])
|
|
42
|
+
listener();
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
/** Namespace of the GitHub capability. Spelled here rather than imported: a client package must not depend on a Host package. */
|
|
47
|
+
export const GITHUB_NS = 'dsh-github';
|
|
48
|
+
/** Credential reference the provider resolves when the configuration names none. */
|
|
49
|
+
export const DEFAULT_TOKEN_REF = 'GITHUB_TOKEN';
|
|
50
|
+
/** English copy. */
|
|
51
|
+
export const en = {
|
|
52
|
+
githubTitle: 'GitHub',
|
|
53
|
+
githubDescription: 'GitHub pull requests, issues, and CI through the agent.',
|
|
54
|
+
tokenLabel: 'GitHub token',
|
|
55
|
+
tokenHint: 'Stored in the credentials file, not here. Applied immediately; leave blank to keep the current token.',
|
|
56
|
+
tokenSet: 'A token is configured.',
|
|
57
|
+
tokenUnset: 'No token is configured; GitHub tools are unavailable until one is.',
|
|
58
|
+
unsaved: 'Unsaved',
|
|
59
|
+
readOnly: 'This deployment stores settings read-only.',
|
|
60
|
+
save: 'Save',
|
|
61
|
+
saving: 'Saving…',
|
|
62
|
+
discard: 'Discard',
|
|
63
|
+
saveFailed: 'The deployment did not accept this value; it was left for you to correct.',
|
|
64
|
+
};
|
|
65
|
+
/** Simplified Chinese copy. */
|
|
66
|
+
export const zh = {
|
|
67
|
+
githubTitle: 'GitHub',
|
|
68
|
+
githubDescription: '通过 agent 操作 GitHub 的 PR、issue 与 CI。',
|
|
69
|
+
tokenLabel: 'GitHub Token',
|
|
70
|
+
tokenHint: '写入凭证文件而非设置文件;保存后立即生效。留空表示保持现有令牌。',
|
|
71
|
+
tokenSet: '已配置令牌。',
|
|
72
|
+
tokenUnset: '未配置令牌;配置之前 GitHub 工具不可用。',
|
|
73
|
+
unsaved: '未保存',
|
|
74
|
+
readOnly: '本部署的设置为只读。',
|
|
75
|
+
save: '保存',
|
|
76
|
+
saving: '保存中…',
|
|
77
|
+
discard: '放弃修改',
|
|
78
|
+
saveFailed: '本部署没有接受该值,已保留供你修改。',
|
|
79
|
+
};
|
|
80
|
+
/**
|
|
81
|
+
* Bridges the page-supplied configuration form and the credentials domain onto
|
|
82
|
+
* the card. The token is the one control that does not live in the
|
|
83
|
+
* configuration: its literal never rides a response, so the card learns only
|
|
84
|
+
* whether one is configured and writes it through the credentials domain,
|
|
85
|
+
* addressed by the reference `Config.tokenRef` names.
|
|
86
|
+
*/
|
|
87
|
+
export class GithubCardController {
|
|
88
|
+
form;
|
|
89
|
+
api;
|
|
90
|
+
store;
|
|
91
|
+
saving = false;
|
|
92
|
+
failed = false;
|
|
93
|
+
credential = { ref: '', configured: false, writable: true };
|
|
94
|
+
/**
|
|
95
|
+
* @param form - the configuration form the Plugins page hands this entry, or
|
|
96
|
+
* `undefined` when the page supplied none (the card then reads the default
|
|
97
|
+
* reference and offers the credential control alone).
|
|
98
|
+
* @param api - the credentials Remote namespace.
|
|
99
|
+
*/
|
|
100
|
+
constructor(form, api) {
|
|
101
|
+
this.form = form;
|
|
102
|
+
this.api = api;
|
|
103
|
+
this.store = createSnapshotStore(this.projection());
|
|
104
|
+
form?.subscribe(() => {
|
|
105
|
+
void this.readCredential();
|
|
106
|
+
this.publish();
|
|
107
|
+
});
|
|
108
|
+
void this.readCredential();
|
|
109
|
+
}
|
|
110
|
+
/** Whether the Host configuration document accepts writes. */
|
|
111
|
+
writable() {
|
|
112
|
+
return this.form?.getSnapshot().writable ?? true;
|
|
113
|
+
}
|
|
114
|
+
/** The configuration form this controller reads (identity-compared by the caller). */
|
|
115
|
+
formOf() {
|
|
116
|
+
return this.form;
|
|
117
|
+
}
|
|
118
|
+
/** Project the card's full state for its snapshot store. */
|
|
119
|
+
projection() {
|
|
120
|
+
return {
|
|
121
|
+
writable: this.writable(),
|
|
122
|
+
configured: this.credential.configured,
|
|
123
|
+
credentialWritable: this.credential.writable,
|
|
124
|
+
saving: this.saving,
|
|
125
|
+
failed: this.failed,
|
|
126
|
+
ref: this.credential.ref,
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
/** The credential reference the configuration names, or the provider default. */
|
|
130
|
+
refOf() {
|
|
131
|
+
const declared = this.form?.getSnapshot().value?.tokenRef;
|
|
132
|
+
return declared !== undefined && declared.length > 0 ? declared : DEFAULT_TOKEN_REF;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Ask the credentials domain about the reference the section names. A
|
|
136
|
+
* response is published only while it still answers for the reference in
|
|
137
|
+
* force, so two reads settling out of order cannot clobber each other.
|
|
138
|
+
*/
|
|
139
|
+
async readCredential() {
|
|
140
|
+
const ref = this.refOf();
|
|
141
|
+
if (ref !== this.credential.ref) {
|
|
142
|
+
this.credential = { ref, configured: false, writable: true };
|
|
143
|
+
this.publish();
|
|
144
|
+
}
|
|
145
|
+
let response;
|
|
146
|
+
try {
|
|
147
|
+
response = await this.api.describe([ref]);
|
|
148
|
+
}
|
|
149
|
+
catch {
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
if (!response.ok || ref !== this.refOf())
|
|
153
|
+
return;
|
|
154
|
+
const view = response.value[ref];
|
|
155
|
+
const next = { ref, configured: view?.configured ?? false, writable: view?.writable ?? true };
|
|
156
|
+
if (next.configured === this.credential.configured && next.writable === this.credential.writable)
|
|
157
|
+
return;
|
|
158
|
+
this.credential = next;
|
|
159
|
+
this.publish();
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Re-read after the Host reports a change to the reference this card
|
|
163
|
+
* watches — a token can be written from elsewhere, and the section does not
|
|
164
|
+
* change when it is.
|
|
165
|
+
* @param ref - the reference the Host reports as changed.
|
|
166
|
+
*/
|
|
167
|
+
refreshCredential(ref) {
|
|
168
|
+
if (ref !== this.credential.ref)
|
|
169
|
+
return;
|
|
170
|
+
void this.readCredential();
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Write the staged token, then re-read whether the Host now holds one. A
|
|
174
|
+
* blank value writes nothing, which keeps the stored key.
|
|
175
|
+
* @param value - the staged credential literal.
|
|
176
|
+
* @returns whether the Host reports a configured credential afterwards.
|
|
177
|
+
*/
|
|
178
|
+
async save(value) {
|
|
179
|
+
const text = (value ?? '').trim();
|
|
180
|
+
if (text === '' || this.saving)
|
|
181
|
+
return false;
|
|
182
|
+
this.saving = true;
|
|
183
|
+
this.failed = false;
|
|
184
|
+
this.publish();
|
|
185
|
+
try {
|
|
186
|
+
await this.api.set(this.refOf(), text);
|
|
187
|
+
}
|
|
188
|
+
catch {
|
|
189
|
+
// handled below by re-reading the configured state
|
|
190
|
+
}
|
|
191
|
+
await this.readCredential();
|
|
192
|
+
const landed = this.credential.configured;
|
|
193
|
+
this.saving = false;
|
|
194
|
+
this.failed = !landed;
|
|
195
|
+
this.publish();
|
|
196
|
+
return landed;
|
|
197
|
+
}
|
|
198
|
+
/** Build the face the card's slot registration injects. */
|
|
199
|
+
inject() {
|
|
200
|
+
return {
|
|
201
|
+
hooks: { githubCard: this.store },
|
|
202
|
+
submit: (value) => this.save(value),
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
publish() {
|
|
206
|
+
this.store.set(this.projection());
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Render the GitHub card. `summary` renders the one-liner the Plugins page
|
|
211
|
+
* places under the card's title (the description plus the token state badge);
|
|
212
|
+
* `page` renders the token control and the save/discard row on the plugin's
|
|
213
|
+
* own page. The page supplies the configuration form, so the card never
|
|
214
|
+
* depends on a served namespace to render.
|
|
215
|
+
*/
|
|
216
|
+
export function GithubCard(props) {
|
|
217
|
+
const { t } = props;
|
|
218
|
+
const state = props.useGithubCard((snapshot) => snapshot);
|
|
219
|
+
const [draft, setDraft] = useState('');
|
|
220
|
+
if (props.view === 'summary') {
|
|
221
|
+
return createElement('span', { className: 'ghc-summary' }, createElement('span', null, t('githubDescription')), createElement('span', { className: state.configured ? 'ghc-badge' : 'ghc-badgeMuted' }, state.configured ? t('tokenSet') : t('tokenUnset')));
|
|
222
|
+
}
|
|
223
|
+
const dirty = draft.trim() !== '';
|
|
224
|
+
const saveLabel = state.saving ? t('saving') : t('save');
|
|
225
|
+
return createElement('div', { className: 'ghc-card ghc-cardPage' }, !state.writable
|
|
226
|
+
? createElement('p', { className: 'ghc-readOnly', role: 'status' }, t('readOnly'))
|
|
227
|
+
: null, createElement('div', { className: 'ghc-field' }, createElement('div', { className: 'ghc-head' }, createElement('label', { className: 'ghc-label', htmlFor: 'plugin-config-github-token' }, t('tokenLabel')), createElement('span', { className: 'ghc-badges' }, createElement('span', { className: state.configured ? 'ghc-badge' : 'ghc-badgeMuted' }, state.configured ? t('tokenSet') : t('tokenUnset')))), createElement('input', {
|
|
228
|
+
id: 'plugin-config-github-token',
|
|
229
|
+
className: 'ghc-input',
|
|
230
|
+
type: 'password',
|
|
231
|
+
autoComplete: 'off',
|
|
232
|
+
value: draft,
|
|
233
|
+
disabled: !state.credentialWritable,
|
|
234
|
+
onChange: (event) => setDraft(event.target.value),
|
|
235
|
+
}), createElement('p', { className: 'ghc-hint' }, t('tokenHint'))), createElement('div', { className: 'ghc-actions' }, state.failed ? createElement('p', { className: 'ghc-failed', role: 'status' }, t('saveFailed')) : null, createElement(Button, {
|
|
236
|
+
variant: 'ghost',
|
|
237
|
+
size: 'sm',
|
|
238
|
+
disabled: !dirty || state.saving,
|
|
239
|
+
onClick: () => setDraft(''),
|
|
240
|
+
}, t('discard')), createElement(Button, {
|
|
241
|
+
variant: 'primary',
|
|
242
|
+
size: 'sm',
|
|
243
|
+
disabled: !state.writable || !dirty || state.saving,
|
|
244
|
+
icon: state.saving
|
|
245
|
+
? createElement('span', { className: 'ghc-spin' }, createElement(IconLoadingOutline16, { size: 16 }))
|
|
246
|
+
: undefined,
|
|
247
|
+
onClick: async () => {
|
|
248
|
+
const landed = await props.submit(draft);
|
|
249
|
+
if (landed)
|
|
250
|
+
setDraft('');
|
|
251
|
+
},
|
|
252
|
+
}, saveLabel)));
|
|
253
|
+
}
|
|
254
|
+
/** Dictionary namespace owned by this plugin. */
|
|
255
|
+
export const NS = 'dsh-github';
|
|
256
|
+
/**
|
|
257
|
+
* Required services (cordis fiber inject). `settingsScope` is gone: host
|
|
258
|
+
* 0.1.7-alpha.1 removed it, and the Plugins page now hands the configuration
|
|
259
|
+
* form to the `plugins.item` entry instead. `@deepseek-ai/dsh-client-ui-plugin-manager`
|
|
260
|
+
* owns that slot, so it must be composed for the card to mount at all.
|
|
261
|
+
*/
|
|
262
|
+
export const inject = ['slots', 'locale', 'connection', 'remote', 'remote.credentials'];
|
|
263
|
+
/**
|
|
264
|
+
* Mount the GitHub configuration card into the Plugins page's Official group.
|
|
265
|
+
*
|
|
266
|
+
* The form arrives per render, so the controller is rebuilt whenever the page
|
|
267
|
+
* supplies a different one — the page's own form owner stays authoritative and
|
|
268
|
+
* the card keeps no second copy of the accepted values.
|
|
269
|
+
* @param ctx - the browser plugin context.
|
|
270
|
+
*/
|
|
271
|
+
export function apply(ctx) {
|
|
272
|
+
const t = ctx.locale.bind(NS);
|
|
273
|
+
ctx.effect(() => ctx.locale.register(NS, { zh, en }), 'dsh-github: card dictionaries');
|
|
274
|
+
let github;
|
|
275
|
+
const controllerFor = (form) => {
|
|
276
|
+
if (github === undefined || github.formOf() !== form) {
|
|
277
|
+
github = new GithubCardController(form, ctx.remote.credentials);
|
|
278
|
+
}
|
|
279
|
+
return github;
|
|
280
|
+
};
|
|
281
|
+
ctx.effect(() => ctx.remote.$on('credentials/reference-updated', (ref) => github?.refreshCredential(ref)), 'dsh-github: credential invalidations');
|
|
282
|
+
ctx.slots.inject('plugins.item', () => ctx.slots.register({
|
|
283
|
+
name: 'plugins.item',
|
|
284
|
+
id: NS,
|
|
285
|
+
order: 100,
|
|
286
|
+
label: () => t('githubTitle'),
|
|
287
|
+
locale: NS,
|
|
288
|
+
inject: () => controllerFor(github?.formOf()).inject(),
|
|
289
|
+
}, GithubCard));
|
|
290
|
+
}
|
|
291
|
+
//# sourceMappingURL=client.js.map
|