dsh-vault 1.10.66 → 1.10.68

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-zh.md CHANGED
@@ -228,10 +228,25 @@ echo "$DEMO_API_KEY"
228
228
  "no entries are tagged for environment export";先在 UI 里给条目的标签加上 `env`,或让助手执行 `vault_update { id, tags: ["env"] }`。
229
229
  - 名字默认由标题 + 字段推导(`DASHSCOPE` + `apiKey` → `DASHSCOPE_API_KEY`);想固定名字就在条目的 `envKeys` 里指定 —— 见[环境变量导出](#环境变量导出)。
230
230
 
231
+
232
+ **命名 —— 只有三个,其中两个故意都叫 `env`:**
233
+
234
+ | 名字 | 是什么 | 含义 |
235
+ |---|---|---|
236
+ | `env` | 条目的**标签** | 决定哪些条目会被 `dsh-vault env` 导出;不打标签就不导出 |
237
+ | `env` | **命令** | 打印带该标签的条目 |
238
+ | `envKeys` | 条目的**字段**(可选) | 固定确切名字,例如 `["DASHSCOPE_API_KEY"]`;旧的单数写法 `envKey` 仍作为"只写一个"的简写接受 |
239
+
240
+ 除此之外没有任何叫 `env*` 的东西:`list --json` / `show` 只报 `envKeys`(该条目会导出的名字,也就是 `get` 接受的名字)与 `envTagged`(是否被 `env` 包含)。
241
+
231
242
  ### 2. 有哪些命令
232
243
 
233
244
  ```sh
234
- dsh-vault list # id、类型、标题、导出的变量名,绝不含密钥
245
+ dsh-vault list # 分组显示:哪些会被 env 导出、哪些不会
246
+ # Exported by `env` (tag "env") — 1 entry:
247
+ # a1b2c3d4-… api-key DASHSCOPE → DASHSCOPE_API_KEY
248
+ # Not exported (no "env" tag) — 1 entry; `get <name>` still works for it:
249
+ # 9f8e7d6c-… api-key Example Billing → EXAMPLE_BILLING_API_KEY
235
250
  dsh-vault get my-entry # 取该条目的主密钥,仅 stdout
236
251
  dsh-vault get my-entry --field apiKey # 取指定字段
237
252
  dsh-vault get my-entry --mask # 只确认存在,不打印值
@@ -263,7 +278,7 @@ dsh-vault export-env .env && set -a && . ./.env && set +a
263
278
 
264
279
  ### 4. 主密码
265
280
 
266
- 依次取 `--password-stdin` → `$DSH_VAULT_MASTER_PASSWORD`(或 `$DSH_VAULT_PASSWORD`)→ 交互式提示;它**不会**去读插件配置文件里的密码,所以 CLI 既不依赖、也不会泄露 profile patch 里那份:
281
+ 依次取 `--password-stdin` → `$DSH_VAULT_MASTER_PASSWORD`(或 `$DSH_VAULT_PASSWORD`)→ 交互式提示(**输入不回显**,终端会切到 raw mode;`tests/e2e/cli-prompt.mjs` 会验证这一点);它**不会**去读插件配置文件里的密码,所以 CLI 既不依赖、也不会泄露 profile patch 里那份:
267
282
 
268
283
  ```sh
269
284
  DSH_VAULT_MASTER_PASSWORD=… pnpm vault list
package/README.md CHANGED
@@ -243,10 +243,26 @@ Two things worth knowing:
243
243
  `DASHSCOPE_API_KEY`) unless the entry sets `envKeys` — see
244
244
  [Environment export](#environment-export).
245
245
 
246
+
247
+ **Names — there are only three, and two of them are the word `env` on purpose:**
248
+
249
+ | name | what it is | meaning |
250
+ |---|---|---|
251
+ | `env` | an entry **tag** | which entries `dsh-vault env` exports; nothing is exported without it |
252
+ | `env` | the **command** | prints exactly the entries carrying that tag |
253
+ | `envKeys` | an entry **field** (optional) | pin exact names, e.g. `["DASHSCOPE_API_KEY"]`; the old singular `envKey` is accepted as a one-element shorthand |
254
+
255
+ Nothing else is called `env*`: `list --json` / `show` report `envKeys` (the names
256
+ an entry exports — what `get` accepts) and `envTagged` (whether `env` includes it).
257
+
246
258
  ### 2. The commands
247
259
 
248
260
  ```sh
249
- dsh-vault list # id, kind, title, exported env name — never secrets
261
+ dsh-vault list # grouped: what `env` exports vs the rest
262
+ # Exported by `env` (tag "env") — 1 entry:
263
+ # a1b2c3d4-… api-key DASHSCOPE → DASHSCOPE_API_KEY
264
+ # Not exported (no "env" tag) — 1 entry; `get <name>` still works for it:
265
+ # 9f8e7d6c-… api-key Example Billing → EXAMPLE_BILLING_API_KEY
250
266
  dsh-vault get my-entry # the entry's primary secret, stdout only
251
267
  dsh-vault get my-entry --field apiKey # one named field
252
268
  dsh-vault get my-entry --mask # confirm it exists without printing it
@@ -284,7 +300,8 @@ dsh-vault export-env .env && set -a && . ./.env && set +a
284
300
  ### 4. The master password
285
301
 
286
302
  `--password-stdin`, then `$DSH_VAULT_MASTER_PASSWORD` (or `$DSH_VAULT_PASSWORD`),
287
- then an interactive prompt. It is **not** read from the plugin's config file, so
303
+ then an interactive prompt that **hides what you type** (the terminal is switched
304
+ to raw mode; verify with `tests/e2e/cli-prompt.mjs`). It is **not** read from the plugin's config file, so
288
305
  the CLI never depends on (or leaks) whatever the profile patch holds:
289
306
 
290
307
  ```sh
package/lib/cli.js CHANGED
@@ -17,11 +17,12 @@
17
17
  * The core is `runCli(argv, io)`, which tests drive directly without spawning.
18
18
  */
19
19
  import { chmod, mkdir, writeFile } from 'node:fs/promises';
20
- import { existsSync, realpathSync } from 'node:fs';
20
+ import { existsSync, openSync, realpathSync, writeSync } from 'node:fs';
21
21
  import { createRequire } from 'node:module';
22
22
  import { dirname, resolve } from 'node:path';
23
23
  import { fileURLToPath, pathToFileURL } from 'node:url';
24
24
  import { createInterface } from 'node:readline';
25
+ import { ReadStream } from 'node:tty';
25
26
  import { openVault, defaultVaultPath } from "./store.js";
26
27
  import { envLinesFor, envPairsForEntry, maskSecret, primarySecret } from "./env-export.js";
27
28
  function packageVersion() {
@@ -64,6 +65,10 @@ list options:
64
65
  the count of further keys in parentheses, and [env]
65
66
  when the entry is included in "dsh-vault env")
66
67
 
68
+ JSON output ("list --json", "show") reports per entry:
69
+ envKeys the env names it exports (what "get" accepts)
70
+ envTagged whether "dsh-vault env" includes it
71
+
67
72
  get options:
68
73
  --field <name> apiKey | secret | accessToken | refreshToken | privateKey
69
74
  | password | cardNumber | username | url | fields.<custom>
@@ -152,50 +157,63 @@ export function resolveCliVaultPath(parsed, env) {
152
157
  }
153
158
  /** Interactive prompt with echo off, read from the terminal rather than stdin. */
154
159
  async function promptHidden(prompt) {
155
- const { open } = await import('node:fs/promises');
156
- let handle;
160
+ // The terminal echoes what you type unless it is switched to raw mode: the
161
+ // first version of this opened /dev/tty but left echo on, so the master
162
+ // password appeared in clear text. Raw mode also means we handle Enter,
163
+ // backspace and Ctrl-C ourselves (below).
164
+ let fd;
157
165
  try {
158
- handle = await open('/dev/tty', 'r+');
166
+ fd = openSync('/dev/tty', 'r+');
159
167
  }
160
168
  catch {
169
+ // No controlling terminal (piped input): read a plain line from stdin.
161
170
  const rl = createInterface({ input: process.stdin, output: process.stderr });
162
171
  const answer = await new Promise(res => rl.question(prompt, res));
163
172
  rl.close();
164
173
  return answer;
165
174
  }
166
- const reader = handle.createReadStream();
167
- const writer = handle.createWriteStream();
168
- writer.write(prompt);
169
- reader.setEncoding('utf8');
170
- return await new Promise((res, rej) => {
171
- let value = '';
172
- const finish = (result) => {
173
- reader.destroy();
174
- void handle?.close();
175
- res(result);
176
- };
177
- reader.on('data', (chunk) => {
178
- for (const ch of String(chunk)) {
179
- if (ch === '\n' || ch === '\r') {
180
- writer.write('\n');
181
- finish(value);
182
- return;
183
- }
184
- if (ch === '\u0003') {
185
- reader.destroy();
186
- void handle?.close();
187
- rej(new Error('aborted'));
188
- return;
189
- }
190
- if (ch === '\u007f' || ch === '\b') {
191
- value = value.slice(0, -1);
192
- continue;
175
+ const input = new ReadStream(fd);
176
+ input.setRawMode(true);
177
+ input.setEncoding('utf8');
178
+ writeSync(fd, prompt);
179
+ try {
180
+ return await new Promise((resolve, reject) => {
181
+ let value = '';
182
+ const finish = (result) => {
183
+ writeSync(fd, '\n');
184
+ resolve(result);
185
+ };
186
+ input.on('data', (chunk) => {
187
+ for (const ch of String(chunk)) {
188
+ if (ch === '\n' || ch === '\r') {
189
+ finish(value);
190
+ return;
191
+ }
192
+ if (ch === '\u0003') { // Ctrl-C
193
+ writeSync(fd, '\n');
194
+ reject(new Error('aborted'));
195
+ return;
196
+ }
197
+ if (ch === '\u007f' || ch === '\b') {
198
+ value = value.slice(0, -1);
199
+ continue;
200
+ }
201
+ if (ch === '\u0015') {
202
+ value = '';
203
+ continue;
204
+ } // Ctrl-U clears the line
205
+ if (ch < ' ')
206
+ continue; // ignore other control characters
207
+ value += ch;
193
208
  }
194
- value += ch;
195
- }
209
+ });
210
+ input.on('error', err => reject(err instanceof Error ? err : new Error(String(err))));
196
211
  });
197
- reader.on('error', rej);
198
- });
212
+ }
213
+ finally {
214
+ input.setRawMode(false);
215
+ input.destroy(); // owns the fd
216
+ }
199
217
  }
200
218
  async function readStdinLine() {
201
219
  const rl = createInterface({ input: process.stdin });
@@ -304,13 +322,12 @@ function publicFields(entry) {
304
322
  out[key] = value;
305
323
  }
306
324
  out.hasSecret = primarySecret(entry) !== undefined;
307
- // Every env name this entry would export, and whether it is actually
308
- // included in `dsh-vault env` (the tag decides that).
309
- // `envKeys` is what the user configured; `exportedKeys` is what the entry
310
- // will actually emit (and what `get` accepts). Keeping them apart is the
311
- // whole point — they used to be one confusingly-similar pair of names.
312
- out.envKeys = Array.isArray(entry.envKeys) ? entry.envKeys : (entry.envKey !== undefined ? [entry.envKey] : []);
313
- out.exportedKeys = envPairsForEntry(entry).map(pair => pair.key);
325
+ // ONE name for "the env names this entry exports": `envKeys`. It used to be a
326
+ // configured `envKeys` plus a computed `exportedKeys`, which read as two
327
+ // similar things — the computed list is the useful one (it already starts with
328
+ // whatever was pinned), so only that is reported.
329
+ out.envKeys = envPairsForEntry(entry).map(pair => pair.key);
330
+ // Whether `dsh-vault env` includes this entry (the tag decides).
314
331
  out.envTagged = (entry.tags ?? []).includes('env');
315
332
  return out;
316
333
  }
@@ -384,18 +401,33 @@ export async function runCli(argv, io) {
384
401
  io.out(`${JSON.stringify(entries.map(publicFields), null, 2)}\n`);
385
402
  return 0;
386
403
  }
387
- for (const entry of entries) {
404
+ // Group by what `env` actually does, because a bare `→ NAME` column used
405
+ // to read as "this is exported" for every entry: the name is only
406
+ // POTENTIAL until the entry carries the tag.
407
+ const line = (entry) => {
388
408
  const identity = [entry.username, entry.host, entry.url]
389
409
  .filter((v) => typeof v === 'string' && v.length > 0).join(' · ');
390
- // Show the env name `get`/`env` would use, so a script author can copy
391
- // it straight out of the listing (plus how many more keys follow).
392
410
  const keys = envPairsForEntry(entry).map(pair => pair.key);
393
- const envSuffix = keys.length > 0
394
- ? ` → ${keys[0]}${keys.length > 1 ? ` (+${keys.length - 1})` : ''}`
395
- : '';
396
- const tagged = (entry.tags ?? []).includes('env') ? ' [env]' : '';
397
- io.out(`${entry.id} ${(entry.kind ?? 'login').padEnd(8)} ${entry.title}`
398
- + `${identity.length > 0 ? ` (${identity})` : ''}${envSuffix}${tagged}\n`);
411
+ const suffix = keys.length > 0 ? ` → ${keys[0]}${keys.length > 1 ? ` (+${keys.length - 1})` : ''}` : '';
412
+ return `${entry.id} ${(entry.kind ?? 'login').padEnd(8)} ${entry.title}`
413
+ + `${identity.length > 0 ? ` (${identity})` : ''}${suffix}`;
414
+ };
415
+ const tagged = entries.filter(entry => (entry.tags ?? []).includes('env'));
416
+ const untagged = entries.filter(entry => !(entry.tags ?? []).includes('env'));
417
+ if (tagged.length > 0) {
418
+ io.out(`Exported by \`env\` (tag "env") — ${tagged.length} ${tagged.length === 1 ? 'entry' : 'entries'}:\n`);
419
+ for (const entry of tagged)
420
+ io.out(` ${line(entry)}\n`);
421
+ }
422
+ else {
423
+ io.out('Exported by `env` (tag "env"): none.\n');
424
+ io.out(' `env` prints only tagged entries; add the tag to one (UI: the entry\'s tags field)\n');
425
+ io.out(' or ask the assistant: vault_update { id, tags: ["env"] }.\n');
426
+ }
427
+ if (untagged.length > 0) {
428
+ io.out(`\nNot exported (no "env" tag) — ${untagged.length} ${untagged.length === 1 ? 'entry' : 'entries'}; \`get <name>\` still works for them:\n`);
429
+ for (const entry of untagged)
430
+ io.out(` ${line(entry)}\n`);
399
431
  }
400
432
  return 0;
401
433
  }
package/lib/client.js CHANGED
@@ -495,191 +495,191 @@ window.__ModuleLoader__.load({
495
495
  document.head.appendChild(tag);
496
496
  }
497
497
  var VaultSection_module_css_default = {
498
- "actionGroupLabel": "t_j5va_actionGroupLabel",
499
- "moreWrap": "t_j5va_moreWrap",
500
- "tagManager": "t_j5va_tagManager",
501
- "editorActions": "t_j5va_editorActions",
502
- "customEq": "t_j5va_customEq",
503
- "reportLineLink": "t_j5va_reportLineLink",
504
- "dupMerge": "t_j5va_dupMerge",
505
- "bulkItem": "t_j5va_bulkItem",
506
- "auditChip": "t_j5va_auditChip",
507
- "trashButton": "t_j5va_trashButton",
508
- "pwLabel": "t_j5va_pwLabel",
509
- "rowSelected": "t_j5va_rowSelected",
510
- "tagManagerHead": "t_j5va_tagManagerHead",
511
- "pinOff": "t_j5va_pinOff",
512
- "auditChipActive": "t_j5va_auditChipActive",
513
- "detailTotp": "t_j5va_detailTotp",
514
- "detailItem": "t_j5va_detailItem",
515
- "customFieldRows": "t_j5va_customFieldRows",
516
- "toolbarMain": "t_j5va_toolbarMain",
517
- "searchBox": "t_j5va_searchBox",
518
- "resultCount": "t_j5va_resultCount",
519
- "pinOn": "t_j5va_pinOn",
520
- "copied": "t_j5va_copied",
521
- "addButton": "t_j5va_addButton",
522
- "kindIcon": "t_j5va_kindIcon",
523
- "badge": "t_j5va_badge",
524
- "genHist": "t_j5va_genHist",
525
- "emojiPicker": "t_j5va_emojiPicker",
526
- "tagCount": "t_j5va_tagCount",
527
- "badgeOk": "t_j5va_badgeOk",
528
- "dueBadge": "t_j5va_dueBadge",
529
- "exportChip": "t_j5va_exportChip",
530
- "status": "t_j5va_status",
531
- "favToggle": "t_j5va_favToggle",
532
- "importRow": "t_j5va_importRow",
533
- "importActions": "t_j5va_importActions",
534
- "detailDeleteBtn": "t_j5va_detailDeleteBtn",
535
- "policyBar": "t_j5va_policyBar",
536
- "importList": "t_j5va_importList",
537
- "rowExpired": "t_j5va_rowExpired",
538
- "toolbar": "t_j5va_toolbar",
539
- "rowDue": "t_j5va_rowDue",
498
+ "reportLine": "t_j5va_reportLine",
540
499
  "genOptRow": "t_j5va_genOptRow",
541
- "revealButton": "t_j5va_revealButton",
542
- "attachBox": "t_j5va_attachBox",
543
- "toolbarFilters": "t_j5va_toolbarFilters",
544
- "recentChip": "t_j5va_recentChip",
545
- "actionBtn": "t_j5va_actionBtn",
546
- "importDesc": "t_j5va_importDesc",
547
- "field": "t_j5va_field",
500
+ "genHistItem": "t_j5va_genHistItem",
501
+ "healthBar": "t_j5va_healthBar",
548
502
  "title": "t_j5va_title",
549
- "identity": "t_j5va_identity",
503
+ "histDanger": "t_j5va_histDanger",
550
504
  "policyField": "t_j5va_policyField",
551
- "pwWeak": "t_j5va_pwWeak",
552
- "brandGlyph": "t_j5va_brandGlyph",
553
- "emojiBtn": "t_j5va_emojiBtn",
554
- "pwHistTime": "t_j5va_pwHistTime",
555
- "tagActions": "t_j5va_tagActions",
556
- "clearButton": "t_j5va_clearButton",
557
- "riskDanger": "t_j5va_riskDanger",
558
- "customFieldRow": "t_j5va_customFieldRow",
559
- "row": "t_j5va_row",
560
- "scoreRing": "t_j5va_scoreRing",
561
- "dupGroup": "t_j5va_dupGroup",
562
- "customKeyInput": "t_j5va_customKeyInput",
563
- "bulkCount": "t_j5va_bulkCount",
564
505
  "pinStar": "t_j5va_pinStar",
565
- "reportLine": "t_j5va_reportLine",
566
- "pwBar": "t_j5va_pwBar",
567
- "attachAdd": "t_j5va_attachAdd",
568
- "actionGroup": "t_j5va_actionGroup",
569
- "gridDetail": "t_j5va_gridDetail",
570
- "genHistItem": "t_j5va_genHistItem",
571
- "reportBox": "t_j5va_reportBox",
572
- "actionPrimary": "t_j5va_actionPrimary",
573
- "emptyHint": "t_j5va_emptyHint",
574
- "pwHistRow": "t_j5va_pwHistRow",
506
+ "moreMenu": "t_j5va_moreMenu",
575
507
  "retryButton": "t_j5va_retryButton",
508
+ "iconFieldWrap": "t_j5va_iconFieldWrap",
509
+ "dupNames": "t_j5va_dupNames",
510
+ "badgeLink": "t_j5va_badgeLink",
511
+ "totpCopy": "t_j5va_totpCopy",
512
+ "customFieldRows": "t_j5va_customFieldRows",
513
+ "detailActions": "t_j5va_detailActions",
514
+ "pwHistBox": "t_j5va_pwHistBox",
515
+ "importRow": "t_j5va_importRow",
516
+ "riskBanner": "t_j5va_riskBanner",
517
+ "recentClear": "t_j5va_recentClear",
518
+ "toolbarFilters": "t_j5va_toolbarFilters",
519
+ "detailDeleteBtn": "t_j5va_detailDeleteBtn",
520
+ "lenChipActive": "t_j5va_lenChipActive",
521
+ "editorBody": "t_j5va_editorBody",
522
+ "kindChip": "t_j5va_kindChip",
576
523
  "section": "t_j5va_section",
577
- "highBadge": "t_j5va_highBadge",
524
+ "checkField": "t_j5va_checkField",
578
525
  "secretField": "t_j5va_secretField",
579
- "pwStrong": "t_j5va_pwStrong",
580
- "kindFilter": "t_j5va_kindFilter",
581
- "histNeutral": "t_j5va_histNeutral",
582
- "gridRow": "t_j5va_gridRow",
583
- "inlineField": "t_j5va_inlineField",
526
+ "brandGlyph": "t_j5va_brandGlyph",
527
+ "urlGlyph": "t_j5va_urlGlyph",
528
+ "bulkBar": "t_j5va_bulkBar",
529
+ "reportJump": "t_j5va_reportJump",
530
+ "auditIssues": "t_j5va_auditIssues",
584
531
  "genOpts": "t_j5va_genOpts",
585
- "histUpdate": "t_j5va_histUpdate",
532
+ "pwWeak": "t_j5va_pwWeak",
533
+ "colorFieldWrap": "t_j5va_colorFieldWrap",
586
534
  "actionGroups": "t_j5va_actionGroups",
587
- "listCompact": "t_j5va_listCompact",
588
- "editorBody": "t_j5va_editorBody",
589
- "healthBar": "t_j5va_healthBar",
590
- "hit": "t_j5va_hit",
591
- "vaultManageRow": "t_j5va_vaultManageRow",
592
- "healthSummary": "t_j5va_healthSummary",
593
- "badgeDanger": "t_j5va_badgeDanger",
594
- "tabPane": "t_j5va_tabPane",
595
- "favActive": "t_j5va_favActive",
596
- "moreMenu": "t_j5va_moreMenu",
597
- "tabActive": "t_j5va_tabActive",
598
- "uriCode": "t_j5va_uriCode",
599
- "lenChipActive": "t_j5va_lenChipActive",
600
- "kindChipActive": "t_j5va_kindChipActive",
601
- "vaultSwitch": "t_j5va_vaultSwitch",
535
+ "inlineField": "t_j5va_inlineField",
536
+ "totpRing": "t_j5va_totpRing",
537
+ "inlineInput": "t_j5va_inlineInput",
538
+ "vaultTarget": "t_j5va_vaultTarget",
539
+ "searchKbd": "t_j5va_searchKbd",
602
540
  "gridName": "t_j5va_gridName",
603
- "gridInput": "t_j5va_gridInput",
604
- "recentLabel": "t_j5va_recentLabel",
605
- "recentClear": "t_j5va_recentClear",
606
- "kindChip": "t_j5va_kindChip",
607
- "headerMessage": "t_j5va_headerMessage",
608
- "badgeWarn": "t_j5va_badgeWarn",
609
- "detailActions": "t_j5va_detailActions",
541
+ "kindIcon": "t_j5va_kindIcon",
542
+ "lenChip": "t_j5va_lenChip",
543
+ "tagManager": "t_j5va_tagManager",
544
+ "editorActions": "t_j5va_editorActions",
545
+ "error": "t_j5va_error",
546
+ "tabPane": "t_j5va_tabPane",
610
547
  "modeReadonly": "t_j5va_modeReadonly",
611
- "colorSwatch": "t_j5va_colorSwatch",
612
- "auditWhen": "t_j5va_auditWhen",
613
- "histAdd": "t_j5va_histAdd",
614
- "rowActions": "t_j5va_rowActions",
615
- "selectActive": "t_j5va_selectActive",
616
- "reportSub": "t_j5va_reportSub",
617
- "dupNames": "t_j5va_dupNames",
618
- "checkField": "t_j5va_checkField",
548
+ "exportChips": "t_j5va_exportChips",
549
+ "actionBtn": "t_j5va_actionBtn",
550
+ "toolbarDivider": "t_j5va_toolbarDivider",
551
+ "pwHistPwd": "t_j5va_pwHistPwd",
619
552
  "intro": "t_j5va_intro",
620
- "rowMain": "t_j5va_rowMain",
621
- "list": "t_j5va_list",
622
- "totpRing": "t_j5va_totpRing",
623
- "sortButton": "t_j5va_sortButton",
624
- "lenChips": "t_j5va_lenChips",
553
+ "badgeDanger": "t_j5va_badgeDanger",
554
+ "importList": "t_j5va_importList",
555
+ "importName": "t_j5va_importName",
556
+ "actionGroup": "t_j5va_actionGroup",
557
+ "healthSummary": "t_j5va_healthSummary",
558
+ "importActions": "t_j5va_importActions",
625
559
  "histLink": "t_j5va_histLink",
626
- "modeAsk": "t_j5va_modeAsk",
627
- "detailRemain": "t_j5va_detailRemain",
628
- "pwHistPwd": "t_j5va_pwHistPwd",
629
- "srOnly": "t_j5va_srOnly",
630
- "auditIssues": "t_j5va_auditIssues",
560
+ "headerMessage": "t_j5va_headerMessage",
561
+ "attachBox": "t_j5va_attachBox",
562
+ "addButton": "t_j5va_addButton",
563
+ "rowActions": "t_j5va_rowActions",
564
+ "importDesc": "t_j5va_importDesc",
565
+ "pwHistRow": "t_j5va_pwHistRow",
566
+ "backupButton": "t_j5va_backupButton",
567
+ "pinOn": "t_j5va_pinOn",
568
+ "lenChips": "t_j5va_lenChips",
569
+ "tabs": "t_j5va_tabs",
570
+ "tagName": "t_j5va_tagName",
571
+ "recentChip": "t_j5va_recentChip",
572
+ "empty": "t_j5va_empty",
573
+ "tagCount": "t_j5va_tagCount",
574
+ "detailTotp": "t_j5va_detailTotp",
575
+ "identity": "t_j5va_identity",
576
+ "toolbar": "t_j5va_toolbar",
631
577
  "badgeBtn": "t_j5va_badgeBtn",
632
- "gridActions": "t_j5va_gridActions",
578
+ "dueBadge": "t_j5va_dueBadge",
579
+ "auditChip": "t_j5va_auditChip",
580
+ "customEq": "t_j5va_customEq",
581
+ "detailItem": "t_j5va_detailItem",
582
+ "scoreRing": "t_j5va_scoreRing",
583
+ "lockedTag": "t_j5va_lockedTag",
584
+ "list": "t_j5va_list",
585
+ "field": "t_j5va_field",
586
+ "clearButton": "t_j5va_clearButton",
587
+ "detailRemain": "t_j5va_detailRemain",
588
+ "tagManagerHead": "t_j5va_tagManagerHead",
589
+ "policyBar": "t_j5va_policyBar",
590
+ "favActive": "t_j5va_favActive",
591
+ "badgeWarn": "t_j5va_badgeWarn",
592
+ "editor": "t_j5va_editor",
593
+ "riskWarn": "t_j5va_riskWarn",
594
+ "badge": "t_j5va_badge",
595
+ "highBadge": "t_j5va_highBadge",
596
+ "exportChip": "t_j5va_exportChip",
597
+ "recentSearch": "t_j5va_recentSearch",
598
+ "gridDetail": "t_j5va_gridDetail",
599
+ "modeAuto": "t_j5va_modeAuto",
600
+ "tagActions": "t_j5va_tagActions",
601
+ "customValueInput": "t_j5va_customValueInput",
602
+ "reportSub": "t_j5va_reportSub",
633
603
  "copyAllBtn": "t_j5va_copyAllBtn",
604
+ "customFieldRow": "t_j5va_customFieldRow",
634
605
  "detailBox": "t_j5va_detailBox",
635
- "saveButton": "t_j5va_saveButton",
636
- "pwHistBox": "t_j5va_pwHistBox",
606
+ "modeAsk": "t_j5va_modeAsk",
607
+ "tagRow": "t_j5va_tagRow",
608
+ "customKeyInput": "t_j5va_customKeyInput",
609
+ "revealButton": "t_j5va_revealButton",
610
+ "reportLineLink": "t_j5va_reportLineLink",
611
+ "listCompact": "t_j5va_listCompact",
612
+ "moreWrap": "t_j5va_moreWrap",
613
+ "kindFilter": "t_j5va_kindFilter",
614
+ "colorPalette": "t_j5va_colorPalette",
615
+ "rowSelected": "t_j5va_rowSelected",
616
+ "rowDue": "t_j5va_rowDue",
617
+ "bulkItem": "t_j5va_bulkItem",
618
+ "selectActive": "t_j5va_selectActive",
637
619
  "rowCheck": "t_j5va_rowCheck",
638
- "tabs": "t_j5va_tabs",
620
+ "gridInput": "t_j5va_gridInput",
639
621
  "emptyBox": "t_j5va_emptyBox",
640
- "tab": "t_j5va_tab",
641
- "inlineInput": "t_j5va_inlineInput",
642
- "customValueInput": "t_j5va_customValueInput",
643
- "bulkBar": "t_j5va_bulkBar",
644
- "moreButton": "t_j5va_moreButton",
645
- "modeAuto": "t_j5va_modeAuto",
646
- "auditChips": "t_j5va_auditChips",
647
- "totpCopy": "t_j5va_totpCopy",
648
- "auditRow": "t_j5va_auditRow",
622
+ "dangerButton": "t_j5va_dangerButton",
623
+ "resultCount": "t_j5va_resultCount",
624
+ "uriCode": "t_j5va_uriCode",
625
+ "row": "t_j5va_row",
626
+ "sortButton": "t_j5va_sortButton",
627
+ "actionGroupLabel": "t_j5va_actionGroupLabel",
628
+ "gridActions": "t_j5va_gridActions",
629
+ "reportBox": "t_j5va_reportBox",
630
+ "hit": "t_j5va_hit",
649
631
  "detailCode": "t_j5va_detailCode",
650
- "riskWarn": "t_j5va_riskWarn",
651
- "recentSearch": "t_j5va_recentSearch",
652
- "colorPalette": "t_j5va_colorPalette",
653
- "badgeLink": "t_j5va_badgeLink",
654
- "exportChips": "t_j5va_exportChips",
632
+ "emojiPicker": "t_j5va_emojiPicker",
655
633
  "pwFair": "t_j5va_pwFair",
656
- "vaultHeader": "t_j5va_vaultHeader",
657
- "pwMeter": "t_j5va_pwMeter",
658
- "riskBanner": "t_j5va_riskBanner",
634
+ "tabActive": "t_j5va_tabActive",
635
+ "genHist": "t_j5va_genHist",
636
+ "actionPrimary": "t_j5va_actionPrimary",
637
+ "favToggle": "t_j5va_favToggle",
638
+ "badgeOk": "t_j5va_badgeOk",
659
639
  "deleteButton": "t_j5va_deleteButton",
660
- "brandGlyphSm": "t_j5va_brandGlyphSm",
661
- "lenChip": "t_j5va_lenChip",
662
- "totp": "t_j5va_totp",
640
+ "dupGroup": "t_j5va_dupGroup",
641
+ "attachAdd": "t_j5va_attachAdd",
642
+ "kindChipActive": "t_j5va_kindChipActive",
643
+ "tab": "t_j5va_tab",
644
+ "vaultSwitch": "t_j5va_vaultSwitch",
645
+ "pwStrong": "t_j5va_pwStrong",
663
646
  "reportTitle": "t_j5va_reportTitle",
647
+ "saveButton": "t_j5va_saveButton",
664
648
  "lockedBanner": "t_j5va_lockedBanner",
665
- "empty": "t_j5va_empty",
666
- "urlGlyph": "t_j5va_urlGlyph",
667
- "iconFieldWrap": "t_j5va_iconFieldWrap",
668
- "tagRow": "t_j5va_tagRow",
669
- "searchKbd": "t_j5va_searchKbd",
670
- "error": "t_j5va_error",
671
- "tagName": "t_j5va_tagName",
672
- "backupButton": "t_j5va_backupButton",
673
- "badgeActive": "t_j5va_badgeActive",
674
- "histDanger": "t_j5va_histDanger",
675
- "importName": "t_j5va_importName",
676
- "dangerButton": "t_j5va_dangerButton",
677
- "lockedTag": "t_j5va_lockedTag",
678
- "editor": "t_j5va_editor",
679
- "colorFieldWrap": "t_j5va_colorFieldWrap",
680
- "vaultTarget": "t_j5va_vaultTarget",
681
- "reportJump": "t_j5va_reportJump",
682
- "toolbarDivider": "t_j5va_toolbarDivider"
649
+ "auditChips": "t_j5va_auditChips",
650
+ "pwMeter": "t_j5va_pwMeter",
651
+ "emptyHint": "t_j5va_emptyHint",
652
+ "brandGlyphSm": "t_j5va_brandGlyphSm",
653
+ "recentLabel": "t_j5va_recentLabel",
654
+ "trashButton": "t_j5va_trashButton",
655
+ "vaultManageRow": "t_j5va_vaultManageRow",
656
+ "rowExpired": "t_j5va_rowExpired",
657
+ "histUpdate": "t_j5va_histUpdate",
658
+ "auditChipActive": "t_j5va_auditChipActive",
659
+ "pwBar": "t_j5va_pwBar",
660
+ "vaultHeader": "t_j5va_vaultHeader",
661
+ "rowMain": "t_j5va_rowMain",
662
+ "copied": "t_j5va_copied",
663
+ "riskDanger": "t_j5va_riskDanger",
664
+ "histNeutral": "t_j5va_histNeutral",
665
+ "status": "t_j5va_status",
666
+ "searchBox": "t_j5va_searchBox",
667
+ "auditRow": "t_j5va_auditRow",
668
+ "totp": "t_j5va_totp",
669
+ "colorSwatch": "t_j5va_colorSwatch",
670
+ "gridRow": "t_j5va_gridRow",
671
+ "moreButton": "t_j5va_moreButton",
672
+ "bulkCount": "t_j5va_bulkCount",
673
+ "pinOff": "t_j5va_pinOff",
674
+ "pwLabel": "t_j5va_pwLabel",
675
+ "pwHistTime": "t_j5va_pwHistTime",
676
+ "srOnly": "t_j5va_srOnly",
677
+ "dupMerge": "t_j5va_dupMerge",
678
+ "emojiBtn": "t_j5va_emojiBtn",
679
+ "toolbarMain": "t_j5va_toolbarMain",
680
+ "histAdd": "t_j5va_histAdd",
681
+ "auditWhen": "t_j5va_auditWhen",
682
+ "badgeActive": "t_j5va_badgeActive"
683
683
  };
684
684
  //#endregion
685
685
  //#region src/client/VaultSection.tsx
package/lib/index.js CHANGED
@@ -4549,7 +4549,7 @@ export async function apply(ctx, config) {
4549
4549
  const m = /^(.*)\.json$/.exec(entry);
4550
4550
  if (!m)
4551
4551
  continue;
4552
- if (['access', 'meta'].includes(m[1]) || m[1].startsWith('vault-export-') || isBackupFile(entry))
4552
+ if (isNonVaultFile(m[1]) || isBackupFile(entry))
4553
4553
  continue;
4554
4554
  names.push(m[1]);
4555
4555
  }
@@ -4594,7 +4594,7 @@ export async function apply(ctx, config) {
4594
4594
  const m = /^(.*)\.json$/.exec(entry);
4595
4595
  if (!m)
4596
4596
  continue;
4597
- if (['access', 'meta'].includes(m[1]) || m[1].startsWith('vault-export-') || isBackupFile(entry))
4597
+ if (isNonVaultFile(m[1]) || isBackupFile(entry))
4598
4598
  continue;
4599
4599
  names.push(m[1]);
4600
4600
  }
@@ -6611,9 +6611,12 @@ function resolveVaultPath(config) {
6611
6611
  * `access-<name>.json`, so two vaults in the same directory never share (or
6612
6612
  * overwrite) each other's mode / auto-capture / auto-lock settings. */
6613
6613
  /** Files that live beside vaults but are NOT vaults: sidecars and metadata. */
6614
+ /** Files that live beside vaults but are NOT vaults: sidecars and metadata.
6615
+ * Accepts the name with or without its `.json` suffix. */
6614
6616
  function isNonVaultFile(name) {
6615
- return name === 'access' || name.startsWith('access-') || name === 'tools' || name === 'meta'
6616
- || name.endsWith('-audit') || name.startsWith('vault-export-');
6617
+ const base = name.replace(/\.json$/i, '');
6618
+ return base === 'access' || base.startsWith('access-') || base === 'tools' || base === 'meta'
6619
+ || base.endsWith('-audit') || base.startsWith('vault-export-');
6617
6620
  }
6618
6621
  function accessPolicyFile(config) {
6619
6622
  const path = resolveVaultPath(config);
@@ -6981,7 +6984,7 @@ async function listVaultRoster(config, activeName) {
6981
6984
  const m = /^(.*)\.json$/.exec(entry);
6982
6985
  if (!m)
6983
6986
  continue;
6984
- if (['access', 'meta'].includes(m[1]) || m[1].startsWith('vault-export-') || isBackupFile(entry))
6987
+ if (isNonVaultFile(m[1]) || isBackupFile(entry))
6985
6988
  continue;
6986
6989
  names.push(m[1]);
6987
6990
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-vault",
3
- "version": "1.10.66",
3
+ "version": "1.10.68",
4
4
  "bin": {
5
5
  "dsh-vault": "./lib/cli.js"
6
6
  },
@@ -87,6 +87,7 @@
87
87
  "scan:public": "node scripts/secret-scan.mjs --public",
88
88
  "e2e:theme": "node tests/e2e/theme-check.mjs",
89
89
  "e2e:polish": "node tests/e2e/polish-check.mjs",
90
- "e2e:contrast": "node tests/e2e/contrast-audit.mjs"
90
+ "e2e:contrast": "node tests/e2e/contrast-audit.mjs",
91
+ "e2e:prompt": "node tests/e2e/cli-prompt.mjs"
91
92
  }
92
93
  }