@duke-dsh-plugins/dsh-agent-approval 1.3.1 → 1.3.3

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/client.js CHANGED
@@ -56,6 +56,17 @@ window.__ModuleLoader__.load({
56
56
  hover/active colors without changing the shell's 16px icon rhythm. */
57
57
  [data-dsh-agent-approval-settings-nav]>svg:first-child{display:none}
58
58
  [data-dsh-agent-approval-settings-nav]::before{content:'';flex:none;width:16px;height:16px;background:currentColor;-webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z'/%3E%3Cpath d='m9 12 2 2 4-4'/%3E%3C/svg%3E") center/contain no-repeat;mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z'/%3E%3Cpath d='m9 12 2 2 4-4'/%3E%3C/svg%3E") center/contain no-repeat}
59
+
60
+ /* /permission menu + composer permission trigger: both pick icons from the
61
+ permissionGlyphs map compiled into the official dsh-client-ui-conversation
62
+ bundle ("host-configured names outside the design set get none") — there is
63
+ no public registration seam, so an external preset row renders with no icon
64
+ element at all. registerPermissionGlyphIcon marks the Agent 审批 menu row
65
+ ([role=menu] button[role=menuitem]) and the composer trigger button; CSS
66
+ draws the same shield + AI-star glyph patch-glyph.mjs used, as a
67
+ currentColor mask so hover/selected/disabled colors all follow the shell. */
68
+ [data-dsh-agent-approval-perm-item]::before,
69
+ [data-dsh-agent-approval-perm-trigger]::before{content:'';flex:none;width:16px;height:16px;background:currentColor;-webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16' fill='none'%3E%3Cpath d='M8.20554 0.899994L14.7901 3.36857V7.01026C14.7901 12 11.0466 14.2103 8.20554 15.3C5.36446 14.2103 1.62012 12 1.62012 7.01026V3.36857L8.20554 0.899994Z' stroke='black' stroke-width='1.31831' stroke-linejoin='round'/%3E%3Cpath d='M8 3.2L9.1 5.9L11.8 7L9.1 8.1L8 10.8L6.9 8.1L4.2 7L6.9 5.9Z' fill='black'/%3E%3C/svg%3E") center/contain no-repeat;mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16' fill='none'%3E%3Cpath d='M8.20554 0.899994L14.7901 3.36857V7.01026C14.7901 12 11.0466 14.2103 8.20554 15.3C5.36446 14.2103 1.62012 12 1.62012 7.01026V3.36857L8.20554 0.899994Z' stroke='black' stroke-width='1.31831' stroke-linejoin='round'/%3E%3Cpath d='M8 3.2L9.1 5.9L11.8 7L9.1 8.1L8 10.8L6.9 8.1L4.2 7L6.9 5.9Z' fill='black'/%3E%3C/svg%3E") center/contain no-repeat}
59
70
  `;
60
71
 
61
72
  // ---- Settings nav icon --------------------------------------------------
@@ -94,6 +105,66 @@ window.__ModuleLoader__.load({
94
105
  };
95
106
  }
96
107
 
108
+ // ---- /permission menu + composer trigger icon ----------------------------
109
+ // The permission surfaces (menu rows and the composer trigger button) pick
110
+ // icons from the permissionGlyphs map compiled into the official
111
+ // dsh-client-ui-conversation bundle — external presets get no icon element
112
+ // at all (see PermissionSelect: `icon === void 0 ? {} : { icon }`). Mark
113
+ // the two surfaces whose label is this preset's display name so the CSS
114
+ // above can paint the glyph; the disposer clears both markers.
115
+ const PERM_ITEM_MARKER = "data-dsh-agent-approval-perm-item";
116
+ const PERM_TRIGGER_MARKER = "data-dsh-agent-approval-perm-trigger";
117
+
118
+ function registerPermissionGlyphIcon(label) {
119
+ let disposed = false;
120
+ const sync = function () {
121
+ if (disposed) return;
122
+ const currentLabel = String(label).trim();
123
+ if (currentLabel.length === 0) return;
124
+ // 1) /permission menu rows: Menu renders [itemIcon?][itemLabel][check?]
125
+ // inside button[role=menuitem]; an icon-less row starts at the label.
126
+ const items = document.querySelectorAll('[role="menu"] button[role="menuitem"]');
127
+ for (let i = 0; i < items.length; i++) {
128
+ const button = items[i];
129
+ const text = button.textContent ? button.textContent.trim() : "";
130
+ if (text === currentLabel) button.setAttribute(PERM_ITEM_MARKER, "");
131
+ else button.removeAttribute(PERM_ITEM_MARKER);
132
+ }
133
+ // 2) Composer trigger button: [triggerIcon?][triggerLabel][chevron svg];
134
+ // with no glyph the icon span is absent, leaving label + chevron.
135
+ // Skip menu rows (handled above) and the settings dialog (its nav
136
+ // row carries the same label but is owned by the settings-nav icon).
137
+ const buttons = document.querySelectorAll("button");
138
+ for (let i = 0; i < buttons.length; i++) {
139
+ const button = buttons[i];
140
+ if (button.getAttribute("role") === "menuitem") continue;
141
+ if (button.closest('[role="dialog"]') !== null) continue;
142
+ if (button.hasAttribute(SETTINGS_NAV_MARKER)) continue;
143
+ const spans = button.querySelectorAll(":scope > span");
144
+ let labelText = "";
145
+ for (let j = 0; j < spans.length; j++) {
146
+ const s = spans[j].textContent ? spans[j].textContent.trim() : "";
147
+ if (s.length > 0) { labelText = s; break; }
148
+ }
149
+ const matches = labelText === currentLabel && button.querySelector("svg") !== null;
150
+ if (matches) button.setAttribute(PERM_TRIGGER_MARKER, "");
151
+ else button.removeAttribute(PERM_TRIGGER_MARKER);
152
+ }
153
+ };
154
+ sync();
155
+ const observer = new MutationObserver(sync);
156
+ observer.observe(document.body, { childList: true, subtree: true, characterData: true });
157
+ return function () {
158
+ disposed = true;
159
+ observer.disconnect();
160
+ const names = [PERM_ITEM_MARKER, PERM_TRIGGER_MARKER];
161
+ for (let n = 0; n < names.length; n++) {
162
+ const marked = document.querySelectorAll("[" + names[n] + "]");
163
+ for (let i = 0; i < marked.length; i++) marked[i].removeAttribute(names[n]);
164
+ }
165
+ };
166
+ }
167
+
97
168
  // ---- Client Remote contribution -------------------------------------------
98
169
  // The browser-side `remote.agentApproval` service only exists after this
99
170
  // module mounts its namespace via ctx.remote.$mount(): dsh-api-remotes'
@@ -190,6 +261,11 @@ window.__ModuleLoader__.load({
190
261
  // fallback gear (no icon field exists in settings.section yet).
191
262
  ctx.effect(() => registerSettingsNavIcon(SETTINGS_LABEL));
192
263
 
264
+ // Mark the /permission menu row and the composer trigger button so the
265
+ // CSS above paints the preset glyph (external presets get no icon from
266
+ // the official permissionGlyphs map; no public registration seam).
267
+ ctx.effect(() => registerPermissionGlyphIcon(SETTINGS_LABEL));
268
+
193
269
  // ctx.get() reads the service without the property-accessor inject guard.
194
270
  const remote = ctx.get("remote.agentApproval");
195
271
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@duke-dsh-plugins/dsh-agent-approval",
3
- "version": "1.3.1",
3
+ "version": "1.3.3",
4
4
  "description": "Agent-decided approvals for DeepSeek Harness: a workspace-write base permission mode where an independent approval subagent judges every sandbox escalation (risky operations are rejected), with a configurable approval model and an audit log in Settings.",
5
5
  "repository": {
6
6
  "type": "git",
package/typert.host.js CHANGED
@@ -148,7 +148,7 @@ const _agentApproval_toggle_parameter_0$schema = z.object({
148
148
  });
149
149
 
150
150
  export const TYPERT = {
151
- package: "dsh-agent-approval",
151
+ package: "@duke-dsh-plugins/dsh-agent-approval",
152
152
  face: "host",
153
153
  schemas: [],
154
154
  invocations: [