@max-null/dsh-achievements 0.1.3 → 0.1.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/client.js CHANGED
@@ -102,50 +102,17 @@ var TROPHY_PATHS = [
102
102
  "M14 14.66V17c0 .55.47.98.97 1.21C16.15 18.75 17 20.24 17 22",
103
103
  "M18 2H6v7a6 6 0 0 0 12 0V2Z"
104
104
  ];
105
- var SETTINGS_NAV_MARKER = "data-dsh-achievements-settings-nav";
106
- var TROPHY_MASK_SVG = encodeURIComponent(
107
- `<svg 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'>${TROPHY_PATHS.map((d) => `<path d='${d}'/>`).join("")}</svg>`
108
- ).replace(/'/g, "%27").replace(/\//g, "%2F").replace(/\(/g, "%28").replace(/\)/g, "%29").replace(/#/g, "%23");
109
- var NAV_ICON_CSS = `
110
- [data-dsh-achievements-settings-nav] > svg:first-child { display: none; }
111
- [data-dsh-achievements-settings-nav]::before {
112
- content: '';
113
- flex: none;
114
- width: 16px;
115
- height: 16px;
116
- background: currentColor;
117
- -webkit-mask: url("data:image/svg+xml,${TROPHY_MASK_SVG}") center / contain no-repeat;
118
- mask: url("data:image/svg+xml,${TROPHY_MASK_SVG}") center / contain no-repeat;
119
- }
120
- `;
121
- var navCssInjected = false;
122
- function injectNavCss() {
123
- if (navCssInjected || typeof document === "undefined") return;
124
- navCssInjected = true;
125
- const style = document.createElement("style");
126
- style.setAttribute("data-plugin", "@max-null/dsh-achievements");
127
- style.textContent = NAV_ICON_CSS;
128
- document.head.append(style);
129
- }
130
- function registerSettingsNavIcon(label) {
131
- let disposed = false;
132
- const sync = () => {
133
- if (disposed) return;
134
- const currentLabel = label().trim();
135
- const buttons = document.querySelectorAll('[role="dialog"] nav button');
136
- for (const button of buttons) {
137
- const matches = currentLabel.length > 0 && button.textContent?.trim() === currentLabel;
138
- if (matches) button.setAttribute(SETTINGS_NAV_MARKER, "");
139
- else button.removeAttribute(SETTINGS_NAV_MARKER);
140
- }
141
- };
142
- sync();
143
- const observer = new MutationObserver(sync);
144
- observer.observe(document.body, { subtree: true, childList: true, characterData: true });
145
- return () => {
146
- disposed = true;
147
- observer.disconnect();
148
- };
105
+ function NavIcon({ size }) {
106
+ return (0, import_react.createElement)("svg", {
107
+ width: size,
108
+ height: size,
109
+ viewBox: "0 0 24 24",
110
+ fill: "none",
111
+ stroke: "currentColor",
112
+ strokeWidth: 2,
113
+ strokeLinecap: "round",
114
+ strokeLinejoin: "round"
115
+ }, TROPHY_PATHS.map((d, index) => (0, import_react.createElement)("path", { key: index, d })));
149
116
  }
150
117
  var GENUI_LS_KEY = "dsh.genui.achievements";
151
118
  function readGenUI() {
@@ -314,8 +281,12 @@ function apply(ctx) {
314
281
  label: () => STRINGS[lang()].title
315
282
  }, () => (0, import_react.createElement)(AchievementsView, { visible: true })));
316
283
  disposers.push(mountToastLayer());
317
- injectNavCss();
318
- disposers.push(registerSettingsNavIcon(() => STRINGS[lang()].title));
284
+ ctx.slots.inject("settings.section.icon", () => ctx.slots.register({
285
+ name: "settings.section.icon",
286
+ id: "ssid-achievements",
287
+ order: 90,
288
+ label: () => STRINGS[lang()].title
289
+ }, (props) => NavIcon({ size: props?.size ?? 16 })));
319
290
  return () => {
320
291
  for (const dispose of disposers) dispose();
321
292
  };
package/dist/engine.js CHANGED
@@ -297,13 +297,13 @@ function agentKeyOf(exec) {
297
297
  /** HTTP 路由(/achievements/api,POST)——仿 dsh-memory 的 /memory/api 信任围栏。 */
298
298
  export function registerRoutes(ctx, engine) {
299
299
  const webServer = ctx.webServer;
300
- const webRuntime = ctx.webRuntime;
300
+ const webStartup = ctx.webStartup;
301
301
  ctx.effect(() => webServer.register({
302
302
  kind: 'prefix',
303
303
  path: '/achievements/api',
304
304
  handler: async (req, res) => {
305
305
  const request = req;
306
- if (!isTrusted(request, webRuntime.trustedHosts)) {
306
+ if (!isTrusted(request, webStartup.trustedHosts)) {
307
307
  writeJson(res, 403, { ok: false, error: { code: 'forbidden', message: 'forbidden' } });
308
308
  return;
309
309
  }
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { AchievementsEngine, attachListeners, registerRoutes, registerTool } from "./engine.js";
2
2
  export const name = '@max-null/dsh-achievements';
3
- export const inject = ['tools', 'webServer', 'webRuntime'];
3
+ export const inject = ['tools', 'webServer', 'webStartup'];
4
4
  export function apply(ctx) {
5
5
  const engine = new AchievementsEngine();
6
6
  attachListeners(ctx, engine);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@max-null/dsh-achievements",
3
- "version": "0.1.3",
3
+ "version": "0.1.5",
4
4
  "description": "SSiD family progress achievements — listens to session/tool events, folds activity into durable counters, unlocks trophies with toasts and an achievements page; the GenUI category merges the genui plugin's own counter data.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -21,7 +21,9 @@
21
21
  "dist",
22
22
  "client.js",
23
23
  "cordis.patch.yml",
24
- "README.md", "docs/shots"],
24
+ "README.md",
25
+ "docs/shots"
26
+ ],
25
27
  "dsh": {
26
28
  "bundle": {
27
29
  "patch": "./cordis.patch.yml"
@@ -58,5 +60,9 @@
58
60
  "tsx": "^4.0.0",
59
61
  "typescript": "^5.5.0",
60
62
  "vitest": "^2.1.0"
63
+ },
64
+ "repository": {
65
+ "type": "git",
66
+ "url": "git+https://github.com/Max-Null/dsh-achievements.git"
61
67
  }
62
68
  }