dsh-vault 0.6.4 → 0.6.5

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/lib/client.js CHANGED
@@ -7,7 +7,7 @@ window.__ModuleLoader__.load({
7
7
  let react = require("react");
8
8
  let react_jsx_runtime = require("react/jsx-runtime");
9
9
  //#region \0dsh-css:/Users/zhipeng/Desktop/work/dsh test/dsh-vault/src/client/VaultSection.module.css.mjs
10
- const css = ".t_j5va_section{flex-direction:column;gap:12px;padding:16px 0;display:flex}.t_j5va_intro{opacity:.75;margin:0;font-size:13px}.t_j5va_toolbar{align-items:center;gap:8px;display:flex}.t_j5va_searchBox{flex:1;display:flex}.t_j5va_searchBox input{border:1px solid var(--color-border,#444);color:inherit;background:0 0;border-radius:6px;flex:1;padding:6px 10px;font-size:13px}.t_j5va_addButton,.t_j5va_saveButton{background:var(--color-accent,#4f8cff);color:#fff;cursor:pointer;border:1px solid #0000;border-radius:6px;padding:6px 12px;font-size:13px}.t_j5va_addButton:disabled,.t_j5va_saveButton:disabled,.t_j5va_rowActions button:disabled{opacity:.5;cursor:not-allowed}.t_j5va_list{flex-direction:column;gap:6px;margin:0;padding:0;list-style:none;display:flex}.t_j5va_row{border:1px solid var(--color-border,#333);border-radius:8px;justify-content:space-between;align-items:center;gap:12px;padding:8px 10px;display:flex}.t_j5va_rowMain{flex-direction:column;gap:2px;min-width:0;display:flex}.t_j5va_title{font-size:14px;font-weight:600}.t_j5va_identity{opacity:.7;text-overflow:ellipsis;white-space:nowrap;font-size:12px;overflow:hidden}.t_j5va_totp{font-family:var(--font-mono,monospace);color:var(--color-accent,#4f8cff);font-size:13px}.t_j5va_rowActions{flex-shrink:0;align-items:center;gap:6px;display:flex}.t_j5va_rowActions button{border:1px solid var(--color-border,#444);color:inherit;cursor:pointer;background:0 0;border-radius:6px;padding:4px 8px;font-size:12px}.t_j5va_deleteButton{color:#e5484d}.t_j5va_copied{color:#30a46c;font-size:12px}.t_j5va_empty,.t_j5va_status,.t_j5va_error{opacity:.8;font-size:13px}.t_j5va_modeReadonly,.t_j5va_modeAsk,.t_j5va_modeAuto{border-radius:999px;width:fit-content;margin:0;padding:4px 10px;font-size:12px;display:inline-block}.t_j5va_modeReadonly{color:#e5484d;border:1px solid #e5484d80}.t_j5va_modeAsk{color:#f5a524;border:1px solid #f5a52480}.t_j5va_modeAuto{color:#30a46c;border:1px solid #30a46c80}.t_j5va_policyBar{flex-direction:column;align-items:flex-start;gap:6px;display:flex}.t_j5va_policyField{align-items:center;gap:8px;font-size:13px;display:flex}.t_j5va_policyField select{border:1px solid var(--color-border,#444);color:inherit;background:0 0;border-radius:6px;padding:4px 8px;font-size:13px}.t_j5va_emptyBox{flex-direction:column;gap:4px;display:flex}.t_j5va_emptyHint{opacity:.65;margin:0;font-size:12px}.t_j5va_error{color:#e5484d}.t_j5va_editor{border:1px solid var(--color-border,#444);border-radius:8px;padding:12px}.t_j5va_editorBody{grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:8px 12px;display:grid}.t_j5va_field{flex-direction:column;gap:4px;font-size:12px;display:flex}.t_j5va_field input,.t_j5va_field select{border:1px solid var(--color-border,#444);color:inherit;background:0 0;border-radius:6px;padding:5px 8px;font-size:13px}.t_j5va_editorActions{justify-content:flex-end;gap:8px;margin-top:12px;display:flex}.t_j5va_editorActions button{border:1px solid var(--color-border,#444);color:inherit;cursor:pointer;background:0 0;border-radius:6px;padding:6px 12px;font-size:13px}.t_j5va_reportBox{border:1px solid #f5a52466;border-radius:8px;flex-direction:column;gap:2px;padding:8px 10px;font-size:12px;display:flex}.t_j5va_reportTitle{margin:0;font-weight:600}.t_j5va_reportLine{opacity:.8;margin:0}.t_j5va_trashButton{border:1px solid var(--color-border,#444);color:inherit;cursor:pointer;background:0 0;border-radius:6px;align-self:flex-start;padding:4px 8px;font-size:12px}.t_j5va_secretField{gap:4px;display:flex}.t_j5va_secretField input{flex:1;min-width:0}.t_j5va_revealButton{border:1px solid var(--color-border,#444);color:inherit;cursor:pointer;background:0 0;border-radius:6px;padding:0 8px;font-size:12px}.t_j5va_kindFilter{border:1px solid var(--color-border,#444);color:inherit;background:0 0;border-radius:6px;padding:6px 8px;font-size:13px}.t_j5va_highBadge{color:#e5484d;vertical-align:middle;background:#e5484d26;border-radius:4px;margin-left:6px;padding:1px 6px;font-size:10px;font-weight:600}.t_j5va_pinStar{color:#f5a524;margin-right:4px}.t_j5va_clearButton{color:inherit;cursor:pointer;opacity:.6;background:0 0;border:none;padding:0 8px;font-size:16px}.t_j5va_field textarea{border:1px solid var(--color-border,#444);color:inherit;resize:vertical;background:0 0;border-radius:6px;padding:5px 8px;font-family:inherit;font-size:13px}";
10
+ const css = ".t_j5va_section{flex-direction:column;gap:12px;padding:16px 0;display:flex}.t_j5va_intro{opacity:.75;margin:0;font-size:13px}.t_j5va_toolbar{align-items:center;gap:8px;display:flex}.t_j5va_searchBox{flex:1;display:flex}.t_j5va_searchBox input{border:1px solid var(--color-border,#444);color:inherit;background:0 0;border-radius:6px;flex:1;padding:6px 10px;font-size:13px}.t_j5va_addButton,.t_j5va_saveButton{background:var(--color-accent,#4f8cff);color:#fff;cursor:pointer;border:1px solid #0000;border-radius:6px;padding:6px 12px;font-size:13px}.t_j5va_addButton:disabled,.t_j5va_saveButton:disabled,.t_j5va_rowActions button:disabled{opacity:.5;cursor:not-allowed}.t_j5va_list{flex-direction:column;gap:6px;margin:0;padding:0;list-style:none;display:flex}.t_j5va_row{border:1px solid var(--color-border,#333);border-radius:8px;justify-content:space-between;align-items:center;gap:12px;padding:8px 10px;display:flex}.t_j5va_rowMain{flex-direction:column;gap:2px;min-width:0;display:flex}.t_j5va_title{font-size:14px;font-weight:600}.t_j5va_identity{opacity:.7;text-overflow:ellipsis;white-space:nowrap;font-size:12px;overflow:hidden}.t_j5va_totp{font-family:var(--font-mono,monospace);color:var(--color-accent,#4f8cff);font-size:13px}.t_j5va_rowActions{flex-shrink:0;align-items:center;gap:6px;display:flex}.t_j5va_rowActions button{border:1px solid var(--color-border,#444);color:inherit;cursor:pointer;background:0 0;border-radius:6px;padding:4px 8px;font-size:12px}.t_j5va_deleteButton{color:#e5484d}.t_j5va_copied{color:#30a46c;font-size:12px}.t_j5va_empty,.t_j5va_status,.t_j5va_error{opacity:.8;font-size:13px}.t_j5va_modeReadonly,.t_j5va_modeAsk,.t_j5va_modeAuto{border-radius:999px;width:fit-content;margin:0;padding:4px 10px;font-size:12px;display:inline-block}.t_j5va_modeReadonly{color:#e5484d;border:1px solid #e5484d80}.t_j5va_modeAsk{color:#f5a524;border:1px solid #f5a52480}.t_j5va_modeAuto{color:#30a46c;border:1px solid #30a46c80}.t_j5va_policyBar{flex-direction:column;align-items:flex-start;gap:6px;display:flex}.t_j5va_policyField{align-items:center;gap:8px;font-size:13px;display:flex}.t_j5va_policyField select{border:1px solid var(--color-border,#444);color:inherit;background:0 0;border-radius:6px;padding:4px 8px;font-size:13px}.t_j5va_emptyBox{flex-direction:column;gap:4px;display:flex}.t_j5va_emptyHint{opacity:.65;margin:0;font-size:12px}.t_j5va_error{color:#e5484d}.t_j5va_editor{border:1px solid var(--color-border,#444);border-radius:8px;padding:12px}.t_j5va_editorBody{grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:8px 12px;display:grid}.t_j5va_field{flex-direction:column;gap:4px;font-size:12px;display:flex}.t_j5va_field input,.t_j5va_field select{border:1px solid var(--color-border,#444);color:inherit;background:0 0;border-radius:6px;padding:5px 8px;font-size:13px}.t_j5va_editorActions{justify-content:flex-end;gap:8px;margin-top:12px;display:flex}.t_j5va_editorActions button{border:1px solid var(--color-border,#444);color:inherit;cursor:pointer;background:0 0;border-radius:6px;padding:6px 12px;font-size:13px}.t_j5va_reportBox{border:1px solid #f5a52466;border-radius:8px;flex-direction:column;gap:2px;padding:8px 10px;font-size:12px;display:flex}.t_j5va_reportTitle{margin:0;font-weight:600}.t_j5va_reportLine{opacity:.8;margin:0}.t_j5va_trashButton{border:1px solid var(--color-border,#444);color:inherit;cursor:pointer;background:0 0;border-radius:6px;align-self:flex-start;padding:4px 8px;font-size:12px}.t_j5va_secretField{gap:4px;display:flex}.t_j5va_secretField input{flex:1;min-width:0}.t_j5va_revealButton{border:1px solid var(--color-border,#444);color:inherit;cursor:pointer;background:0 0;border-radius:6px;padding:0 8px;font-size:12px}.t_j5va_kindFilter{border:1px solid var(--color-border,#444);color:inherit;background:0 0;border-radius:6px;padding:6px 8px;font-size:13px}.t_j5va_highBadge{color:#e5484d;vertical-align:middle;background:#e5484d26;border-radius:4px;margin-left:6px;padding:1px 6px;font-size:10px;font-weight:600}.t_j5va_pinStar{color:#f5a524;margin-right:4px}.t_j5va_clearButton{color:inherit;cursor:pointer;opacity:.6;background:0 0;border:none;padding:0 8px;font-size:16px}.t_j5va_field textarea{border:1px solid var(--color-border,#444);color:inherit;resize:vertical;background:0 0;border-radius:6px;padding:5px 8px;font-family:inherit;font-size:13px}.t_j5va_row{transition:background .12s}.t_j5va_row:hover{background:var(--color-hover,#80808014)}";
11
11
  const tagId = "dsh-vault/VaultSection.module.css";
12
12
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
13
13
  const tag = document.createElement("style");
@@ -17,45 +17,45 @@ window.__ModuleLoader__.load({
17
17
  document.head.appendChild(tag);
18
18
  }
19
19
  var VaultSection_module_css_default = {
20
- "rowMain": "t_j5va_rowMain",
21
- "list": "t_j5va_list",
22
- "kindFilter": "t_j5va_kindFilter",
23
- "totp": "t_j5va_totp",
24
- "clearButton": "t_j5va_clearButton",
25
- "intro": "t_j5va_intro",
26
- "toolbar": "t_j5va_toolbar",
27
- "policyBar": "t_j5va_policyBar",
20
+ "secretField": "t_j5va_secretField",
28
21
  "error": "t_j5va_error",
29
- "copied": "t_j5va_copied",
30
22
  "reportTitle": "t_j5va_reportTitle",
31
- "highBadge": "t_j5va_highBadge",
23
+ "title": "t_j5va_title",
32
24
  "empty": "t_j5va_empty",
33
- "saveButton": "t_j5va_saveButton",
34
- "emptyBox": "t_j5va_emptyBox",
35
- "modeAsk": "t_j5va_modeAsk",
36
- "status": "t_j5va_status",
37
- "field": "t_j5va_field",
38
- "secretField": "t_j5va_secretField",
39
- "revealButton": "t_j5va_revealButton",
40
- "editorBody": "t_j5va_editorBody",
41
25
  "deleteButton": "t_j5va_deleteButton",
26
+ "editorBody": "t_j5va_editorBody",
27
+ "highBadge": "t_j5va_highBadge",
28
+ "reportBox": "t_j5va_reportBox",
29
+ "trashButton": "t_j5va_trashButton",
30
+ "section": "t_j5va_section",
31
+ "clearButton": "t_j5va_clearButton",
32
+ "policyField": "t_j5va_policyField",
33
+ "saveButton": "t_j5va_saveButton",
34
+ "row": "t_j5va_row",
35
+ "list": "t_j5va_list",
36
+ "policyBar": "t_j5va_policyBar",
37
+ "kindFilter": "t_j5va_kindFilter",
42
38
  "modeReadonly": "t_j5va_modeReadonly",
43
- "reportLine": "t_j5va_reportLine",
39
+ "totp": "t_j5va_totp",
40
+ "rowMain": "t_j5va_rowMain",
41
+ "emptyBox": "t_j5va_emptyBox",
42
+ "intro": "t_j5va_intro",
44
43
  "modeAuto": "t_j5va_modeAuto",
45
44
  "emptyHint": "t_j5va_emptyHint",
46
- "addButton": "t_j5va_addButton",
47
- "editor": "t_j5va_editor",
48
- "rowActions": "t_j5va_rowActions",
49
45
  "editorActions": "t_j5va_editorActions",
50
- "trashButton": "t_j5va_trashButton",
51
- "pinStar": "t_j5va_pinStar",
52
- "title": "t_j5va_title",
53
- "searchBox": "t_j5va_searchBox",
54
- "row": "t_j5va_row",
55
- "section": "t_j5va_section",
56
- "policyField": "t_j5va_policyField",
46
+ "revealButton": "t_j5va_revealButton",
47
+ "reportLine": "t_j5va_reportLine",
57
48
  "identity": "t_j5va_identity",
58
- "reportBox": "t_j5va_reportBox"
49
+ "searchBox": "t_j5va_searchBox",
50
+ "rowActions": "t_j5va_rowActions",
51
+ "copied": "t_j5va_copied",
52
+ "editor": "t_j5va_editor",
53
+ "modeAsk": "t_j5va_modeAsk",
54
+ "status": "t_j5va_status",
55
+ "pinStar": "t_j5va_pinStar",
56
+ "field": "t_j5va_field",
57
+ "toolbar": "t_j5va_toolbar",
58
+ "addButton": "t_j5va_addButton"
59
59
  };
60
60
  //#endregion
61
61
  //#region src/client/VaultSection.tsx
package/lib/index.js CHANGED
@@ -110,9 +110,10 @@ export async function apply(ctx, config) {
110
110
  if (policy.mode === 'ask' && WRITE_TOOLS.has(exec.name)) {
111
111
  return { kind: 'ask', reason: `dsh-vault: ${exec.name} requires your confirmation in "ask" (prompt-before-write) mode` };
112
112
  }
113
- // High-sensitivity reads: in ask mode, reading a `high` entry's secrets
114
- // (vault_get by id) also requires confirmation.
115
- if (policy.mode === 'ask' && exec.name === 'vault_get') {
113
+ // High-sensitivity reads: reading a `high` entry's secrets (vault_get by
114
+ // id) requires confirmation in BOTH ask and auto modes — sensitive reads
115
+ // are always gated, unlike ordinary writes.
116
+ if (policy.mode !== 'readonly' && exec.name === 'vault_get') {
116
117
  const id = exec.arguments?.id;
117
118
  if (id !== undefined) {
118
119
  try {
@@ -616,6 +617,31 @@ export async function apply(ctx, config) {
616
617
  return { value, caution: 'value returned for copy; do not repeat it in the conversation' };
617
618
  },
618
619
  }));
620
+ // ── vault_notes: append/replace an entry's notes ────────────────────────────
621
+ ctx.tools.register(defineTool({
622
+ name: 'vault_notes',
623
+ description: 'Append to or replace the free-form notes of an entry (a convenient shortcut for '
624
+ + 'vault_update). Returns the updated entry summary.',
625
+ parameters: {
626
+ id: { type: 'string', required: true, description: 'Entry id.' },
627
+ text: { type: 'string', required: true, description: 'Notes text. Pass an empty string to clear notes.' },
628
+ append: { type: 'boolean', description: 'Append to existing notes instead of replacing (default false).' },
629
+ },
630
+ output: { schema: { type: 'object', additionalProperties: false, properties: { updated: { type: 'boolean', required: true } } }, render: (_a, v) => [{ type: 'text', text: v.updated ? 'notes updated' : 'entry not found' }] },
631
+ async execute(args) {
632
+ assertWritable('vault_notes');
633
+ const s = await guardStore();
634
+ const current = s.get(args.id);
635
+ if (!current)
636
+ return { updated: false };
637
+ const text = args.text;
638
+ const notes = args.append && current.notes !== undefined && text.length > 0
639
+ ? current.notes + '\n' + text
640
+ : text;
641
+ const updated = await s.update(args.id, { notes });
642
+ return { updated: updated !== undefined };
643
+ },
644
+ }));
619
645
  // ── vault_expiry: set/update an entry's expiry ──────────────────────────────
620
646
  ctx.tools.register(defineTool({
621
647
  name: 'vault_expiry',
@@ -730,6 +756,23 @@ export async function apply(ctx, config) {
730
756
  return { report: lines.length > 0 ? header + '\n' + lines.join('\n') : header };
731
757
  },
732
758
  }));
759
+ // ── vault_tags: tag inventory with counts ────────────────────────────────────
760
+ ctx.tools.register(defineTool({
761
+ name: 'vault_tags',
762
+ description: 'List every tag used across entries with the number of entries per tag. No secrets.',
763
+ parameters: {},
764
+ output: { schema: { type: 'object', additionalProperties: false, properties: { tags: { type: 'array', required: true, items: { type: 'json' } } } }, render: (_a, v) => [{ type: 'text', text: JSON.stringify(v.tags) }] },
765
+ async execute() {
766
+ const s = await guardStore();
767
+ const counts = new Map();
768
+ for (const e of s.list()) {
769
+ for (const tag of e.tags ?? [])
770
+ counts.set(tag, (counts.get(tag) ?? 0) + 1);
771
+ }
772
+ const tags = [...counts.entries()].map(([name, count]) => ({ name, count })).sort((a, b) => b.count - a.count || a.name.localeCompare(b.name));
773
+ return { tags };
774
+ },
775
+ }));
733
776
  // ── vault_rotation: expiry / rotation report ───────────────────────────────
734
777
  ctx.tools.register(defineTool({
735
778
  name: 'vault_rotation',
@@ -1013,6 +1056,14 @@ export async function apply(ctx, config) {
1013
1056
  skipped++;
1014
1057
  continue;
1015
1058
  }
1059
+ const VALID_KINDS = new Set(['login', 'ssh', 'api-key', 'secret', 'oauth', 'custom']);
1060
+ if (record.kind !== undefined && (typeof record.kind !== 'string' || !VALID_KINDS.has(record.kind))) {
1061
+ skipped++;
1062
+ continue; // invalid kind: skip the row
1063
+ }
1064
+ if (record.sensitivity !== undefined && record.sensitivity !== 'normal' && record.sensitivity !== 'high') {
1065
+ delete record.sensitivity;
1066
+ }
1016
1067
  if (Object.keys(fields).length > 0)
1017
1068
  record.fields = fields;
1018
1069
  const title = record.title;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-vault",
3
- "version": "0.6.4",
3
+ "version": "0.6.5",
4
4
  "description": "Encrypted credential vault for DeepSeek Harness: store and retrieve usernames, emails, phone numbers, passwords, TOTP secrets, SSH/API-key/OAuth developer credentials through model tools and a Settings UI page.",
5
5
  "type": "module",
6
6
  "license": "MIT",