dsh-image-gen-plugin 1.0.0 → 1.0.2

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.
Files changed (3) hide show
  1. package/client.js +41 -18
  2. package/index.js +1 -1
  3. package/package.json +9 -1
package/client.js CHANGED
@@ -44,6 +44,7 @@ window.__ModuleLoader__.load({
44
44
  ];
45
45
  const FIELDS = [
46
46
  'apiUrl',
47
+ 'secret',
47
48
  'model',
48
49
  'count',
49
50
  'outputFormat',
@@ -70,8 +71,9 @@ window.__ModuleLoader__.load({
70
71
  labelApiUrl: 'API URL',
71
72
  hintApiUrl: 'Base URL of an OpenAI-compatible API. /images/generations is appended to it.',
72
73
  labelApiKey: 'API key',
73
- hintApiKeySet: 'A key is stored under a neutral field name in the profile config, and the settings API never sends it back. Leave this empty to keep it; type a new one to replace it.',
74
- hintApiKeyEmpty: 'Sent as the Bearer token. It is stored in the profile configuration under a neutral field name and never leaves this machine.',
74
+ hintApiKey: 'Sent as the Bearer token. Stored in this profile\'s configuration and never leaves this machine.',
75
+ showKey: 'Show',
76
+ hideKey: 'Hide',
75
77
  sectionConnection: 'Connection',
76
78
  sectionMaintenance: 'Records',
77
79
  clearButton: 'Clear image records',
@@ -157,8 +159,9 @@ window.__ModuleLoader__.load({
157
159
  labelApiUrl: 'API 地址',
158
160
  hintApiUrl: '兼容 OpenAI 的接口基地址,会在后面拼接 /images/generations。',
159
161
  labelApiKey: 'API 密钥',
160
- hintApiKeySet: '密钥已保存,配置里用的是中性字段名,设置接口不会把它回传。留空表示不改动;输入新值即可替换。',
161
- hintApiKeyEmpty: '作为 Bearer 令牌发送。保存在本机配置里,字段名是中性的,不会外传。',
162
+ hintApiKey: '作为 Bearer 令牌发送。保存在本机这份 profile 配置里,不会外传。',
163
+ showKey: '显示',
164
+ hideKey: '隐藏',
162
165
  sectionConnection: '连接',
163
166
  sectionMaintenance: '记录',
164
167
  clearButton: '清除图片记录',
@@ -436,6 +439,7 @@ window.__ModuleLoader__.load({
436
439
  function normalize(raw) {
437
440
  return {
438
441
  apiUrl: typeof raw?.apiUrl === 'string' ? raw.apiUrl : '',
442
+ secret: typeof raw?.secret === 'string' ? raw.secret : '',
439
443
  model: typeof raw?.model === 'string' ? raw.model : '',
440
444
  count: asNumber(raw?.count, 1),
441
445
  outputFormat: typeof raw?.outputFormat === 'string' ? raw.outputFormat : 'png',
@@ -467,7 +471,7 @@ window.__ModuleLoader__.load({
467
471
  const t = useLanguage();
468
472
  const [state, setState] = useState({ status: 'loading' });
469
473
  const [form, setForm] = useState(null);
470
- const [keyDraft, setKeyDraft] = useState(null);
474
+ const [keyVisible, setKeyVisible] = useState(false);
471
475
  const [busy, setBusy] = useState(false);
472
476
  const [message, setMessage] = useState(null);
473
477
 
@@ -523,12 +527,11 @@ window.__ModuleLoader__.load({
523
527
  setBusy(true);
524
528
  setMessage(null);
525
529
  try {
526
- const ops = FIELDS.filter((field) => field !== 'secret').map((field) => ({
530
+ const ops = FIELDS.map((field) => ({
527
531
  op: 'set',
528
532
  path: [field],
529
533
  value: form[field],
530
534
  }));
531
- if (keyDraft) ops.push({ op: 'set', path: ['secret'], value: keyDraft });
532
535
  const written = unwrap(await api.mutate(state.ns, ops, state.revision));
533
536
  if (!written.ok) {
534
537
  setMessage({ kind: 'error', text: written.message.includes('conflict') ? t('conflict') : written.message });
@@ -542,7 +545,6 @@ window.__ModuleLoader__.load({
542
545
  revision: view?.revision ?? current.revision,
543
546
  secrets: Array.isArray(view?.secrets) ? view.secrets : current.secrets,
544
547
  }));
545
- setKeyDraft(null);
546
548
  setMessage({ kind: 'ok', text: t('saved') });
547
549
  } catch (error) {
548
550
  const text = String(error?.message ?? error);
@@ -588,9 +590,6 @@ window.__ModuleLoader__.load({
588
590
  return h('div', { style: { fontSize: 13, color: TOKENS.danger } }, state.message);
589
591
  }
590
592
 
591
- const keyIsSet = state.secrets.some(
592
- (secret) => Array.isArray(secret.path) && secret.path[0] === 'secret' && secret.set,
593
- );
594
593
  const compressionLocked = form.outputFormat === 'png';
595
594
 
596
595
  return h(
@@ -625,13 +624,37 @@ window.__ModuleLoader__.load({
625
624
  ),
626
625
  h(
627
626
  Row,
628
- { label: t('labelApiKey'), hint: keyIsSet ? t('hintApiKeySet') : t('hintApiKeyEmpty') },
629
- h(TextField, {
630
- type: 'password',
631
- value: keyDraft ?? '',
632
- placeholder: keyIsSet ? '••••••••' : 'sk-...',
633
- onChange: setKeyDraft,
634
- }),
627
+ { label: t('labelApiKey'), hint: t('hintApiKey') },
628
+ h(
629
+ 'div',
630
+ { style: { display: 'flex', gap: 8, alignItems: 'center' } },
631
+ h(TextField, {
632
+ // The value itself is shown, so the key can be read back and copied. It starts
633
+ // masked only against a shoulder, and the toggle reveals it.
634
+ type: keyVisible ? 'text' : 'password',
635
+ value: form.secret ?? '',
636
+ placeholder: 'sk-...',
637
+ onChange: patch('secret'),
638
+ }),
639
+ h(
640
+ 'button',
641
+ {
642
+ type: 'button',
643
+ onClick: () => setKeyVisible((current) => !current),
644
+ style: {
645
+ flex: '0 0 auto',
646
+ padding: '6px 10px',
647
+ fontSize: 12,
648
+ cursor: 'pointer',
649
+ borderRadius: 6,
650
+ border: `1px solid ${TOKENS.border}`,
651
+ background: 'transparent',
652
+ color: TOKENS.muted,
653
+ },
654
+ },
655
+ keyVisible ? t('hideKey') : t('showKey'),
656
+ ),
657
+ ),
635
658
  ),
636
659
 
637
660
  h('div', { style: { fontSize: 13, fontWeight: 600, color: TOKENS.text, margin: '20px 0 10px' } }, t('sectionDefaults')),
package/index.js CHANGED
@@ -12,7 +12,7 @@ export const inject = ['tools'];
12
12
  export const Config = z.object({
13
13
  apiUrl: z.string().default('https://api.openai.com/v1').volatile(),
14
14
 
15
- secret: z.string().role('secret').default('').volatile(),
15
+ secret: z.string().default('').volatile(),
16
16
  model: z.string().default('gpt-image-2.5-flare').volatile(),
17
17
  count: z.number().default(1).volatile(),
18
18
  outputFormat: z.string().default('png').volatile(),
package/package.json CHANGED
@@ -1,9 +1,17 @@
1
1
  {
2
2
  "name": "dsh-image-gen-plugin",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "type": "module",
5
5
  "description": "Image generation tool and settings page for DeepSeek Harness, talking to any OpenAI-compatible /images/generations endpoint.",
6
6
  "license": "MIT",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/miller-owo/dsh-image-gen-plugin.git"
10
+ },
11
+ "homepage": "https://github.com/miller-owo/dsh-image-gen-plugin#readme",
12
+ "bugs": {
13
+ "url": "https://github.com/miller-owo/dsh-image-gen-plugin/issues"
14
+ },
7
15
  "icon": "./icon.svg",
8
16
  "main": "./index.js",
9
17
  "meta": {