aitoearn-dsh-plugin-test 0.0.3 → 0.0.4

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 (37) hide show
  1. package/lib/client.js +34 -36
  2. package/lib/client.js.map +2 -2
  3. package/package.json +57 -40
  4. package/presets/aitoearn/lib/mcp.js +5 -1
  5. package/presets/aitoearn/lib/mcp.js.map +2 -2
  6. package/presets/aitoearn/package.json +14 -13
  7. package/skills/cloudedit/SKILL.md +113 -0
  8. package/skills/cloudedit/references/amk-scenarios/edit-asr.md +160 -0
  9. package/skills/cloudedit/references/edit-position.md +64 -0
  10. package/skills/cloudedit/references/edit-project.md +192 -0
  11. package/skills/cloudedit/references/edit-quality-gate.md +136 -0
  12. package/skills/cloudedit/references/edit-shader.md +114 -0
  13. package/skills/cloudedit/references/edit-text.md +227 -0
  14. package/skills/cloudedit/references/edit-timeline.md +29 -0
  15. package/skills/cloudedit-planner/SKILL.md +102 -0
  16. package/skills/cloudedit-planner/evals/evals.json +80 -0
  17. package/skills/cloudedit-planner/references/editing-plan.md +63 -0
  18. package/skills/cloudedit-planner/references/executable-handoff.md +25 -0
  19. package/skills/cloudedit-planner/references/media-evidence-models.md +32 -0
  20. package/skills/cloudedit-planner/references/media-understanding.md +25 -0
  21. package/skills/cloudedit-planner/references/processing-and-lineage.md +22 -0
  22. package/skills/cloudedit-planner/references/subtitle-timing.md +50 -0
  23. package/src/dsh/client/AitoearnCard.js +2 -2
  24. package/src/dsh/client/AitoearnCard.js.map +1 -1
  25. package/src/dsh/client/card-store.d.ts +2 -2
  26. package/src/dsh/client/card-store.js +18 -9
  27. package/src/dsh/client/card-store.js.map +1 -1
  28. package/src/dsh/client/index.js +15 -13
  29. package/src/dsh/client/index.js.map +1 -1
  30. package/src/dsh/index.d.ts +2 -1
  31. package/src/dsh/index.js +4 -6
  32. package/src/dsh/index.js.map +1 -1
  33. package/src/dsh/mcp.js +7 -1
  34. package/src/dsh/mcp.js.map +1 -1
  35. package/src/dsh/settings-schema.d.ts +16 -12
  36. package/src/dsh/settings-schema.js +8 -10
  37. package/src/dsh/settings-schema.js.map +1 -1
package/lib/client.js CHANGED
@@ -37,17 +37,6 @@ var ENVIRONMENT_ORIGINS = {
37
37
  cn: "https://aitoearn.cn"
38
38
  };
39
39
  var DEFAULT_MCP_URL = `${ENVIRONMENT_ORIGINS.global}${MCP_PATH}`;
40
- function pluginConfigFromSettings(section, fallback = {}) {
41
- if (section === null || typeof section !== "object" || Array.isArray(section))
42
- return fallback;
43
- const record = section;
44
- return {
45
- ...fallback,
46
- ...typeof record["environment"] === "string" ? { environment: record["environment"] } : {},
47
- ...typeof record["baseUrl"] === "string" ? { baseUrl: record["baseUrl"] } : {},
48
- ...typeof record["apiKey"] === "string" ? { apiKey: record["apiKey"] } : {}
49
- };
50
- }
51
40
  function resolveEnvironment(value) {
52
41
  if (value === "cn" || value === "custom" || value === "global")
53
42
  return value;
@@ -177,7 +166,7 @@ function AitoearnCard(props) {
177
166
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: description, children: t("description") })
178
167
  ] }),
179
168
  state.dirty ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.Tag, { tone: "neutral", className: pending, children: t("unsaved") }) : null,
180
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.IconChevronDownOutline14, { className: cx([chevron, open && chevronOpen]) })
169
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.IconChevronDownOutlineRegular, { className: cx([chevron, open && chevronOpen]) })
181
170
  ]
182
171
  }
183
172
  ),
@@ -269,13 +258,13 @@ function AitoearnCard(props) {
269
258
 
270
259
  // src/dsh/client/card-store.ts
271
260
  var import_dsh_client_store = require("@deepseek-ai/dsh-client-store");
272
- function createAitoearnCardFace(scope, describe) {
261
+ function createAitoearnCardFace(form, describe) {
273
262
  let draft = {};
274
263
  let saving = false;
275
264
  let failed2 = false;
276
265
  const store = (0, import_dsh_client_store.createSnapshotStore)(project());
277
266
  function stored() {
278
- return scope.getSnapshot().value ?? {};
267
+ return form.getSnapshot().value ?? {};
279
268
  }
280
269
  function apiKeyConfigured() {
281
270
  const view = describe.getSnapshot().view;
@@ -297,7 +286,7 @@ function createAitoearnCardFace(scope, describe) {
297
286
  return writes;
298
287
  }
299
288
  function project() {
300
- const snapshot = scope.getSnapshot();
289
+ const snapshot = form.getSnapshot();
301
290
  const value = stored();
302
291
  return {
303
292
  available: snapshot.status === "ready",
@@ -315,7 +304,7 @@ function createAitoearnCardFace(scope, describe) {
315
304
  store.set(project());
316
305
  };
317
306
  async function commit() {
318
- const snapshot = scope.getSnapshot();
307
+ const snapshot = form.getSnapshot();
319
308
  const writes = pendingWrites();
320
309
  if (saving || snapshot.status !== "ready" || !snapshot.writable || writes.length === 0)
321
310
  return;
@@ -326,16 +315,17 @@ function createAitoearnCardFace(scope, describe) {
326
315
  saving = true;
327
316
  failed2 = false;
328
317
  publish();
318
+ let accepted = true;
329
319
  try {
330
320
  if (writes.includes("environment"))
331
- await scope.set("environment", environment);
321
+ accepted = await form.set("environment", environment) && accepted;
332
322
  if (writes.includes("apiKey"))
333
- await scope.set("apiKey", apiKey);
323
+ accepted = await form.set("apiKey", apiKey) && accepted;
334
324
  if (writes.includes("baseUrl")) {
335
325
  if (environment === "custom")
336
- await scope.set("baseUrl", baseUrl);
326
+ accepted = await form.set("baseUrl", baseUrl) && accepted;
337
327
  else
338
- await scope.unset("baseUrl");
328
+ accepted = await form.unset("baseUrl") && accepted;
339
329
  }
340
330
  } catch {
341
331
  saving = false;
@@ -343,6 +333,12 @@ function createAitoearnCardFace(scope, describe) {
343
333
  publish();
344
334
  return;
345
335
  }
336
+ if (!accepted) {
337
+ saving = false;
338
+ failed2 = true;
339
+ publish();
340
+ return;
341
+ }
346
342
  const landed = (writes.includes("environment") ? resolveEnvironment(stored().environment) === environment : true) && (writes.includes("apiKey") ? apiKeyConfigured() : true) && (writes.includes("baseUrl") ? environment === "custom" ? (stored().baseUrl ?? "") === baseUrl : stored().baseUrl === void 0 : true);
347
343
  saving = false;
348
344
  if (landed)
@@ -351,7 +347,7 @@ function createAitoearnCardFace(scope, describe) {
351
347
  failed2 = true;
352
348
  publish();
353
349
  }
354
- scope.subscribe(publish);
350
+ form.subscribe(publish);
355
351
  describe.subscribe(publish);
356
352
  void describe.ensure();
357
353
  return {
@@ -428,26 +424,28 @@ var aitoearnCardLocales = {
428
424
 
429
425
  // src/dsh/client/index.ts
430
426
  var name2 = "aitoearn-settings-card";
431
- var inject = ["slots", "locale", "settingsScope"];
427
+ var inject = ["slots", "locale", "configForms"];
432
428
  function apply(ctx) {
433
429
  ctx.effect(
434
430
  () => ctx.locale.register(aitoearnCardNS, aitoearnCardLocales),
435
431
  "aitoearn-settings-card: dictionaries"
436
432
  );
437
- const scope = ctx.settingsScope.bind({
438
- namespace: "aitoearn",
439
- decode: (section) => pluginConfigFromSettings(section)
440
- });
441
- const face = createAitoearnCardFace(scope, ctx.settingsScope.describe());
442
- ctx.slots.inject("settings.plugin.item", () => ctx.slots.register(
443
- {
444
- name: "settings.plugin.item",
445
- key: "aitoearn",
446
- locale: aitoearnCardNS,
447
- inject: () => face
448
- },
449
- AitoearnCard
450
- ));
433
+ const t = ctx.locale.bind(aitoearnCardNS);
434
+ ctx.effect(() => ctx.configForms.whileServed([SETTINGS_NAMESPACE], () => {
435
+ const form = ctx.configForms.get(SETTINGS_NAMESPACE);
436
+ const face = createAitoearnCardFace(form, ctx.configForms.describe());
437
+ return ctx.slots.inject("settings.plugins.tab", () => ctx.slots.register(
438
+ {
439
+ name: "settings.plugins.tab",
440
+ id: "aitoearn",
441
+ order: 10,
442
+ label: () => t("title"),
443
+ locale: aitoearnCardNS,
444
+ inject: () => face
445
+ },
446
+ AitoearnCard
447
+ ));
448
+ }), "aitoearn-settings-card: tab");
451
449
  }
452
450
  return module.exports; } });
453
451
  //# sourceMappingURL=client.js.map
package/lib/client.js.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../tools/agent-plugin/src/dsh/client/index.ts", "../../../../../tools/agent-plugin/src/dsh/auth.ts", "../../../../../tools/agent-plugin/src/dsh/client/AitoearnCard.tsx", "../../../../../tools/agent-plugin/src/dsh/client/card.css.ts", "../../../../../tools/agent-plugin/src/dsh/client/card-store.ts", "../../../../../tools/agent-plugin/src/dsh/client/i18n.ts"],
4
- "sourcesContent": ["import { Context } from '@deepseek-ai/cordis'\nimport { AitoearnPluginConfig, pluginConfigFromSettings } from '../auth.js'\nimport { AitoearnCard } from './AitoearnCard.js'\nimport { createAitoearnCardFace } from './card-store.js'\nimport { aitoearnCardLocales, aitoearnCardNS } from './i18n.js'\n\nexport const name = 'aitoearn-settings-card'\nexport const inject = ['slots', 'locale', 'settingsScope']\n\nexport function apply(ctx: Context): void {\n ctx.effect(\n () => ctx.locale.register(aitoearnCardNS, aitoearnCardLocales),\n 'aitoearn-settings-card: dictionaries',\n )\n const scope = ctx.settingsScope.bind<AitoearnPluginConfig>({\n namespace: 'aitoearn',\n decode: section => pluginConfigFromSettings(section),\n })\n const face = createAitoearnCardFace(scope, ctx.settingsScope.describe())\n ctx.slots.inject('settings.plugin.item', () =>\n ctx.slots.register(\n {\n name: 'settings.plugin.item',\n key: 'aitoearn',\n locale: aitoearnCardNS,\n inject: () => face,\n },\n AitoearnCard,\n ))\n}\n", "export const MCP_PATH = '/api/ai/agent/mcp'\nexport const API_KEY_ENV = 'AITOEARN_API_KEY'\nexport const DEFAULT_ENVIRONMENT = 'global'\nexport const SETTINGS_NAMESPACE = 'aitoearn'\n\nexport const ENVIRONMENT_ORIGINS = {\n global: 'https://aitoearn.ai',\n cn: 'https://aitoearn.cn',\n} as const\n\nexport const DEFAULT_MCP_URL = `${ENVIRONMENT_ORIGINS.global}${MCP_PATH}`\n\nexport type AitoearnEnvironment = 'global' | 'cn' | 'custom'\n\nexport interface AitoearnAuth {\n mcpUrl: string\n apiKey: string\n}\n\nexport interface AitoearnPluginConfig {\n environment?: string\n baseUrl?: string\n apiKey?: string\n}\n\nexport function pluginConfigFromSettings(\n section: unknown,\n fallback: AitoearnPluginConfig = {},\n): AitoearnPluginConfig {\n if (section === null || typeof section !== 'object' || Array.isArray(section))\n return fallback\n const record = section as Record<string, unknown>\n return {\n ...fallback,\n ...(typeof record['environment'] === 'string' ? { environment: record['environment'] } : {}),\n ...(typeof record['baseUrl'] === 'string' ? { baseUrl: record['baseUrl'] } : {}),\n ...(typeof record['apiKey'] === 'string' ? { apiKey: record['apiKey'] } : {}),\n }\n}\n\nexport function resolveEnvironment(value: string | undefined): AitoearnEnvironment {\n if (value === 'cn' || value === 'custom' || value === 'global')\n return value\n return DEFAULT_ENVIRONMENT\n}\n\nexport function resolveOrigin(environment: AitoearnEnvironment, baseUrl?: string): string {\n if (environment !== 'custom')\n return ENVIRONMENT_ORIGINS[environment]\n const trimmed = baseUrl?.trim() ?? ''\n if (trimmed.length === 0)\n return ''\n try {\n const url = new URL(trimmed)\n if (url.protocol !== 'http:' && url.protocol !== 'https:')\n return ''\n return url.origin\n }\n catch {\n return ''\n }\n}\n\nexport function resolveMcpUrl(config: AitoearnPluginConfig): string {\n const environment = resolveEnvironment(config.environment)\n const origin = resolveOrigin(environment, config.baseUrl)\n if (origin.length === 0)\n return ''\n return `${origin}${MCP_PATH}`\n}\n\nexport function resolveAuth(\n config: AitoearnPluginConfig,\n env: NodeJS.ProcessEnv = process.env,\n): AitoearnAuth {\n return {\n mcpUrl: resolveMcpUrl(config),\n apiKey: config.apiKey?.trim() || env[API_KEY_ENV]?.trim() || '',\n }\n}\n\nexport function authorizationHeader(apiKey: string): Record<string, string> {\n if (apiKey.length === 0)\n return {}\n return { Authorization: `Bearer ${apiKey}` }\n}\n", "import { IconChevronDownOutline14, Tag } from '@deepseek-ai/dsh-client-ui-primitives'\nimport { SnapshotSelectorHook, TranslateNS } from '@deepseek-ai/dsh-client-ui-slots'\nimport { useEffect, useRef, useState } from 'react'\nimport { AitoearnEnvironment } from '../auth.js'\nimport { AitoearnCardState } from './card-store.js'\nimport * as css from './card.css.js'\nimport { AitoearnCardLocaleKey } from './i18n.js'\n\nexport interface AitoearnCardProps {\n t: TranslateNS<'aitoearn-card'>\n useAitoearnCard: SnapshotSelectorHook<AitoearnCardState>\n edit: (field: 'environment' | 'baseUrl' | 'apiKey', value: string) => void\n save: () => void\n discard: () => void\n}\n\nconst cx = (names: Array<string | false | undefined>): string => names.filter(Boolean).join(' ')\n\nconst ENVIRONMENT_OPTIONS: Array<{ value: AitoearnEnvironment, labelKey: AitoearnCardLocaleKey }> = [\n { value: 'global', labelKey: 'envGlobal' },\n { value: 'cn', labelKey: 'envCn' },\n { value: 'custom', labelKey: 'envCustom' },\n]\n\n/**\n * The Aitoearn plugin settings card, laid out after the official plugin cards:\n * a header naming the plugin, its fields in place, and the footer that writes\n * the staged edits.\n */\nexport function AitoearnCard(props: AitoearnCardProps) {\n const { t } = props\n const state = props.useAitoearnCard(snapshot => snapshot)\n const [open, setOpen] = useState(false)\n const saveStarted = useRef(false)\n useEffect(() => {\n if (state.saving) {\n saveStarted.current = true\n return\n }\n if (!saveStarted.current)\n return\n saveStarted.current = false\n if (!state.dirty && !state.failed)\n setOpen(false)\n }, [state.dirty, state.failed, state.saving])\n if (!state.available)\n return null\n const disabled = !state.writable\n const blocked = !state.dirty || state.saving\n return (\n <li className={cx([css.card, open && css.cardOpen])}>\n <button\n type=\"button\"\n className={css.header}\n aria-expanded={open}\n aria-label={`${t(open ? 'collapse' : 'expand')}: ${t('title')}`}\n onClick={() => {\n setOpen(!open)\n }}\n >\n <span className={css.headText}>\n <span className={css.name}>{t('title')}</span>\n <span className={css.description}>{t('description')}</span>\n </span>\n {state.dirty ? <Tag tone=\"neutral\" className={css.pending}>{t('unsaved')}</Tag> : null}\n <IconChevronDownOutline14 className={cx([css.chevron, open && css.chevronOpen])} />\n </button>\n {open\n ? (\n <div className={css.body}>\n {!state.writable ? <p className={css.readOnly} role=\"status\">{t('readOnly')}</p> : null}\n <div className={css.field}>\n <div className={css.head}>\n <span className={css.label} id=\"aitoearn-environment-label\">{t('environment')}</span>\n </div>\n <div className={css.envGroup} role=\"radiogroup\" aria-labelledby=\"aitoearn-environment-label\">\n {ENVIRONMENT_OPTIONS.map(option => (\n <button\n key={option.value}\n type=\"button\"\n role=\"radio\"\n aria-checked={state.environment === option.value}\n className={cx([css.envPill, state.environment === option.value && css.envPillActive])}\n disabled={disabled}\n onClick={() => {\n props.edit('environment', option.value)\n }}\n >\n {t(option.labelKey)}\n </button>\n ))}\n </div>\n </div>\n {state.environment === 'custom'\n ? (\n <div className={css.field}>\n <div className={css.head}>\n <label className={css.label} htmlFor=\"aitoearn-base-url\">{t('baseUrl')}</label>\n </div>\n <input\n id=\"aitoearn-base-url\"\n className={css.input}\n type=\"text\"\n value={state.baseUrl}\n placeholder=\"https://example.com\"\n disabled={disabled}\n onChange={(event) => {\n props.edit('baseUrl', event.currentTarget.value)\n }}\n />\n <p className={css.hint}>{t('baseUrlHint')}</p>\n </div>\n )\n : null}\n <div className={css.field}>\n <div className={css.head}>\n <label className={css.label} htmlFor=\"aitoearn-api-key\">{t('apiKey')}</label>\n <span className={css.badges}>\n <Tag tone={state.apiKeyConfigured ? 'neutral' : 'quiet'}>\n {state.apiKeyConfigured ? t('apiKeySet') : t('apiKeyUnset')}\n </Tag>\n </span>\n </div>\n <input\n id=\"aitoearn-api-key\"\n className={css.input}\n type=\"password\"\n autoComplete=\"off\"\n value={state.apiKey}\n disabled={disabled}\n onChange={(event) => {\n props.edit('apiKey', event.currentTarget.value)\n }}\n />\n <p className={css.hint}>{t('apiKeyHint')}</p>\n </div>\n <div className={css.footer}>\n {state.failed ? <p className={css.failed} role=\"status\">{t('saveFailed')}</p> : null}\n <button\n type=\"button\"\n className={css.discard}\n disabled={!state.dirty || state.saving}\n onClick={props.discard}\n >\n {t('discard')}\n </button>\n <button\n type=\"button\"\n className={css.save}\n disabled={blocked}\n onClick={props.save}\n >\n {t(state.saving ? 'saving' : 'save')}\n </button>\n </div>\n </div>\n )\n : null}\n </li>\n )\n}\n", "/**\n * Card styles for the Aitoearn plugin settings card. Values mirror the\n * official `PluginCard` / field styling in `@deepseek-ai/dsh-client-ui-settings-plugins`\n * so the card reads like the Bash / Agent loop / Web search cards. Everything is\n * token-styled through `--dsw-alias-*`; the sheet self-injects once, the same\n * `style[data-plugin-css]` way the official client packages do.\n */\n\nconst CARD_CSS = `\n.Ata_card{border:.5px solid var(--dsw-alias-border-l4);background:var(--dsw-alias-bg-layer-3);border-radius:16px;list-style:none;transition:border-color .16s,background .16s}\n.Ata_card:hover{border-color:var(--dsw-alias-label-dimmed)}\n.Ata_cardOpen{background:var(--dsw-alias-bg-layer-2);border-color:var(--dsw-alias-label-dimmed)}\n.Ata_header{appearance:none;width:100%;font:inherit;color:inherit;text-align:left;cursor:pointer;background:0 0;border:0;border-radius:12px;align-items:center;gap:12px;padding:14px 16px;display:flex}\n.Ata_header:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:-2px}\n.Ata_headText{flex-direction:column;flex:1;gap:4px;min-width:0;display:flex}\n.Ata_name{color:var(--dsw-alias-label-primary);font-size:15px;font-weight:600;line-height:1.4}\n.Ata_description{color:var(--dsw-alias-label-tertiary);font-size:13px;line-height:1.5}\n.Ata_pending{flex:none}\n.Ata_chevron{color:var(--dsw-alias-label-tertiary);flex:none;transition:transform .16s}\n.Ata_chevronOpen{transform:rotate(180deg)}\n.Ata_body{border-top:.5px solid var(--dsw-alias-border-l2);margin:0 16px;padding-bottom:8px}\n.Ata_readOnly{color:var(--dsw-alias-label-tertiary);margin:12px 0 0;font-size:12px;line-height:1.5}\n.Ata_footer{border-top:.5px solid var(--dsw-alias-border-l2);justify-content:flex-end;align-items:center;gap:8px;padding:12px 0 4px;display:flex}\n.Ata_failed{min-width:0;color:var(--dsw-alias-label-error);flex:1;margin:0;font-size:12px;line-height:1.5}\n.Ata_discard,.Ata_save{appearance:none;font:inherit;cursor:pointer;border:1px solid #0000;border-radius:8px;padding:5px 14px;font-size:13px;line-height:1.5;transition:background .16s,border-color .16s,color .16s}\n.Ata_discard{border-color:var(--dsw-alias-border-l2);color:var(--dsw-alias-label-secondary);background:0 0}\n.Ata_discard:hover:not(:disabled){color:var(--dsw-alias-label-primary);border-color:var(--dsw-alias-label-dimmed)}\n.Ata_discard:active:not(:disabled){background:var(--dsw-alias-interactive-bg-active)}\n.Ata_save{background:var(--dsw-alias-label-primary);color:var(--dsw-alias-bg-layer-3)}\n.Ata_discard:disabled,.Ata_save:disabled{opacity:.4;cursor:default}\n.Ata_discard:focus-visible,.Ata_save:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:1px}\n.Ata_field{flex-direction:column;gap:6px;padding:12px 0;display:flex}\n.Ata_field+.Ata_field{border-top:.5px solid var(--dsw-alias-border-l2)}\n.Ata_head{align-items:center;gap:8px;display:flex}\n.Ata_label{min-width:0;color:var(--dsw-alias-label-primary);flex:1;font-size:13px;font-weight:500;line-height:1.5}\n.Ata_badges{align-items:center;gap:8px;display:inline-flex}\n.Ata_input{border:.5px solid var(--dsw-alias-border-l4);background:var(--dsw-alias-bg-layer-3);height:34px;font:inherit;color:var(--dsw-alias-label-primary);border-radius:8px;padding:0 12px;font-size:13px;line-height:1.5}\n.Ata_input:focus-visible{border-color:var(--dsw-alias-brand-primary);outline:none}\n.Ata_input:disabled{color:var(--dsw-alias-label-tertiary);cursor:default}\n.Ata_hint{color:var(--dsw-alias-label-tertiary);margin:0;font-size:12px;line-height:1.5}\n.Ata_envGroup{flex-wrap:wrap;gap:8px;display:flex}\n.Ata_envPill{appearance:none;font:inherit;cursor:pointer;border:.5px solid var(--dsw-alias-border-l4);background:var(--dsw-alias-bg-layer-3);color:var(--dsw-alias-label-secondary);border-radius:999px;padding:5px 14px;font-size:13px;line-height:1.5;transition:background .16s,border-color .16s,color .16s}\n.Ata_envPill:hover:not(:disabled):not(.Ata_envPillActive){color:var(--dsw-alias-label-primary);border-color:var(--dsw-alias-label-dimmed)}\n.Ata_envPill:active:not(:disabled){background:var(--dsw-alias-bg-layer-4)}\n.Ata_envPill:disabled{opacity:.4;cursor:not-allowed}\n.Ata_envPill:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:1px}\n.Ata_envPillActive{border-color:var(--dsw-alias-brand-primary);color:var(--dsw-alias-brand-primary)}\n`\n\nconst STYLE_TAG_ID = '@aitoearn/dsh-plugin/card.css'\n\nif (typeof document !== 'undefined' && document.querySelector(`style[data-plugin-css=\"${STYLE_TAG_ID}\"]`) === null) {\n const tag = document.createElement('style')\n tag.dataset['plugin'] = '@aitoearn/dsh-plugin'\n tag.dataset['pluginCss'] = STYLE_TAG_ID\n tag.textContent = CARD_CSS\n document.head.appendChild(tag)\n}\n\nexport const card = 'Ata_card'\nexport const cardOpen = 'Ata_cardOpen'\nexport const header = 'Ata_header'\nexport const headText = 'Ata_headText'\nexport const name = 'Ata_name'\nexport const description = 'Ata_description'\nexport const pending = 'Ata_pending'\nexport const chevron = 'Ata_chevron'\nexport const chevronOpen = 'Ata_chevronOpen'\nexport const body = 'Ata_body'\nexport const readOnly = 'Ata_readOnly'\nexport const footer = 'Ata_footer'\nexport const failed = 'Ata_failed'\nexport const discard = 'Ata_discard'\nexport const save = 'Ata_save'\nexport const field = 'Ata_field'\nexport const head = 'Ata_head'\nexport const label = 'Ata_label'\nexport const badges = 'Ata_badges'\nexport const input = 'Ata_input'\nexport const hint = 'Ata_hint'\nexport const envGroup = 'Ata_envGroup'\nexport const envPill = 'Ata_envPill'\nexport const envPillActive = 'Ata_envPillActive'\n", "import { createSnapshotStore, SnapshotStore } from '@deepseek-ai/dsh-client-store'\nimport { SettingsDescribeFace, SettingsScope } from '@deepseek-ai/dsh-client-ui-settings/client'\nimport { AitoearnEnvironment, AitoearnPluginConfig, resolveEnvironment, SETTINGS_NAMESPACE } from '../auth.js'\n\nexport type AitoearnCardField = 'environment' | 'baseUrl' | 'apiKey'\n\nexport interface AitoearnCardState {\n available: boolean\n writable: boolean\n dirty: boolean\n saving: boolean\n failed: boolean\n environment: AitoearnEnvironment\n baseUrl: string\n apiKey: string\n apiKeyConfigured: boolean\n}\n\nexport interface AitoearnCardFace {\n hooks: { aitoearnCard: SnapshotStore<AitoearnCardState> }\n edit: (field: AitoearnCardField, value: string) => void\n save: () => void\n discard: () => void\n}\n\n/** Staged edits over the card's fields; an absent field inherits the section. */\ninterface CardDraft {\n environment?: AitoearnEnvironment\n baseUrl?: string\n apiKey?: string\n}\n\ntype PendingWrite = 'environment' | 'apiKey' | 'baseUrl'\n\n/** One schema-declared secret slot in the namespace view (`SettingsSecretView`). */\ninterface SecretSlot {\n path: string[]\n set: boolean\n}\n\n/**\n * Bridges the `aitoearn` settings scope onto the card's staged form. Edits stay\n * local drafts until `save` writes them in one gesture; a save that did not land\n * keeps its drafts so the user can correct them instead of retyping.\n *\n * The API key is a schema-declared secret: the Host redacts it from every view\n * it serves, so the key can never be read back and the input starts blank. A\n * blank draft keeps the stored key, and whether one is configured comes from\n * the namespace view's secret record.\n */\nexport function createAitoearnCardFace(scope: SettingsScope<AitoearnPluginConfig>, describe: SettingsDescribeFace): AitoearnCardFace {\n let draft: CardDraft = {}\n let saving = false\n let failed = false\n const store = createSnapshotStore<AitoearnCardState>(project())\n\n function stored(): AitoearnPluginConfig {\n return scope.getSnapshot().value ?? {}\n }\n\n function apiKeyConfigured(): boolean {\n const view = describe.getSnapshot().view\n const section = view?.namespaces.find(candidate => candidate.ns === SETTINGS_NAMESPACE)\n return section?.secrets.some((secret: SecretSlot) => secret.path.length === 1 && secret.path[0] === 'apiKey' && secret.set) ?? false\n }\n\n function pendingWrites(): PendingWrite[] {\n const value = stored()\n const writes: PendingWrite[] = []\n const environment = draft.environment ?? resolveEnvironment(value.environment)\n if (draft.environment !== undefined && environment !== resolveEnvironment(value.environment))\n writes.push('environment')\n if (draft.apiKey !== undefined && draft.apiKey.trim() !== '')\n writes.push('apiKey')\n if (draft.baseUrl !== undefined && environment === 'custom' && draft.baseUrl !== (value.baseUrl ?? ''))\n writes.push('baseUrl')\n if (environment !== 'custom' && value.baseUrl !== undefined)\n writes.push('baseUrl')\n return writes\n }\n\n function project(): AitoearnCardState {\n const snapshot = scope.getSnapshot()\n const value = stored()\n return {\n available: snapshot.status === 'ready',\n writable: snapshot.writable,\n dirty: pendingWrites().length > 0,\n saving,\n failed,\n environment: draft.environment ?? resolveEnvironment(value.environment),\n baseUrl: draft.baseUrl ?? value.baseUrl ?? '',\n apiKey: draft.apiKey ?? '',\n apiKeyConfigured: apiKeyConfigured(),\n }\n }\n\n const publish = () => {\n store.set(project())\n }\n\n async function commit(): Promise<void> {\n const snapshot = scope.getSnapshot()\n const writes = pendingWrites()\n if (saving || snapshot.status !== 'ready' || !snapshot.writable || writes.length === 0)\n return\n const value = stored()\n const environment = draft.environment ?? resolveEnvironment(value.environment)\n const baseUrl = draft.baseUrl ?? value.baseUrl ?? ''\n const apiKey = draft.apiKey?.trim() ?? ''\n saving = true\n failed = false\n publish()\n try {\n if (writes.includes('environment'))\n await scope.set('environment', environment)\n if (writes.includes('apiKey'))\n await scope.set('apiKey', apiKey)\n if (writes.includes('baseUrl')) {\n if (environment === 'custom')\n await scope.set('baseUrl', baseUrl)\n else\n await scope.unset('baseUrl')\n }\n }\n catch {\n // A rejected write keeps the drafts on screen (with the failure flag) so\n // the user can correct them instead of retyping.\n saving = false\n failed = true\n publish()\n return\n }\n const landed = (writes.includes('environment') ? resolveEnvironment(stored().environment) === environment : true)\n && (writes.includes('apiKey') ? apiKeyConfigured() : true)\n && (writes.includes('baseUrl')\n ? (environment === 'custom' ? (stored().baseUrl ?? '') === baseUrl : stored().baseUrl === undefined)\n : true)\n saving = false\n if (landed)\n draft = {}\n else\n failed = true\n publish()\n }\n\n scope.subscribe(publish)\n describe.subscribe(publish)\n void describe.ensure()\n\n return {\n hooks: { aitoearnCard: store },\n edit: (field, value) => {\n if (saving)\n return\n failed = false\n if (field === 'environment') {\n const environment = resolveEnvironment(value)\n draft = environment === 'custom'\n ? { ...draft, environment }\n : { ...draft, environment, baseUrl: undefined }\n }\n else {\n draft = { ...draft, [field]: value }\n }\n publish()\n },\n save: () => commit(),\n discard: () => {\n draft = {}\n failed = false\n publish()\n },\n }\n}\n", "/** Locale dictionary for the Aitoearn plugin settings card. */\n\nexport const aitoearnCardNS = 'aitoearn-card'\n\ndeclare module '@deepseek-ai/dsh-client-ui-slots' {\n interface LocaleNamespaceMap {\n /** The Aitoearn plugin card's copy. */\n 'aitoearn-card': keyof typeof aitoearnCardLocales.zh\n }\n}\n\nexport type AitoearnCardLocaleKey = keyof typeof aitoearnCardLocales.zh\n\nexport const aitoearnCardLocales = {\n zh: {\n title: 'Aitoearn',\n description: 'Aitoearn \u5DE5\u5177\u7684\u8FD0\u884C\u73AF\u5883\u4E0E API Key\u3002',\n environment: '\u8FD0\u884C\u73AF\u5883',\n envGlobal: '\u56FD\u9645\u7AD9 aitoearn.ai',\n envCn: '\u4E2D\u56FD\u7AD9 aitoearn.cn',\n envCustom: '\u81EA\u5B9A\u4E49',\n baseUrl: '\u63A5\u53E3\u5730\u5740',\n baseUrlHint: '\u7559\u7A7A\u5219\u4F7F\u7528\u6240\u9009\u73AF\u5883\u9ED8\u8BA4\u5730\u5740\u3002',\n apiKey: 'API Key',\n apiKeySet: '\u5DF2\u914D\u7F6E\u5BC6\u94A5\u3002',\n apiKeyUnset: '\u672A\u914D\u7F6E\u5BC6\u94A5\uFF1B\u914D\u7F6E\u4E4B\u524D Aitoearn \u5DE5\u5177\u4E0D\u53EF\u7528\u3002',\n apiKeyHint: '\u51FA\u4E8E\u5B89\u5168\u8003\u8651\u5BC6\u94A5\u4E0D\u4F1A\u56DE\u663E\uFF1B\u7559\u7A7A\u8868\u793A\u4FDD\u6301\u5F53\u524D\u5BC6\u94A5\uFF0C\u8F93\u5165\u65B0\u503C\u5C06\u8986\u76D6\u3002',\n expand: '\u5C55\u5F00\u8BBE\u7F6E',\n collapse: '\u6536\u8D77\u8BBE\u7F6E',\n save: '\u4FDD\u5B58',\n saving: '\u4FDD\u5B58\u4E2D\u2026',\n discard: '\u653E\u5F03\u4FEE\u6539',\n unsaved: '\u672A\u4FDD\u5B58',\n saveFailed: '\u672C\u90E8\u7F72\u6CA1\u6709\u63A5\u53D7\u8FD9\u4E9B\u503C\uFF0C\u5DF2\u4FDD\u7559\u4F9B\u4F60\u4FEE\u6539\u3002',\n readOnly: '\u672C\u90E8\u7F72\u7684\u8BBE\u7F6E\u4E3A\u53EA\u8BFB\u3002',\n },\n en: {\n title: 'Aitoearn',\n description: 'Environment and API key for Aitoearn tools.',\n environment: 'Environment',\n envGlobal: 'Global (aitoearn.ai)',\n envCn: 'China (aitoearn.cn)',\n envCustom: 'Custom',\n baseUrl: 'Base URL',\n baseUrlHint: 'Leave blank to use the selected environment default.',\n apiKey: 'API key',\n apiKeySet: 'A key is configured.',\n apiKeyUnset: 'No key is configured; Aitoearn tools are unavailable until one is.',\n apiKeyHint: 'The key is never displayed back; leave blank to keep the current key, or type a new one to overwrite it.',\n expand: 'Show settings',\n collapse: 'Hide settings',\n save: 'Save',\n saving: 'Saving\u2026',\n discard: 'Discard',\n unsaved: 'Unsaved',\n saveFailed: 'The deployment did not accept these values; they were left for you to correct.',\n readOnly: 'This deployment stores settings read-only.',\n },\n}\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA,cAAAA;AAAA;AAAA;;;ACAO,IAAM,WAAW;AAEjB,IAAM,sBAAsB;AAC5B,IAAM,qBAAqB;AAE3B,IAAM,sBAAsB;AAAA,EACjC,QAAQ;AAAA,EACR,IAAI;AACN;AAEO,IAAM,kBAAkB,GAAG,oBAAoB,MAAM,GAAG,QAAQ;AAehE,SAAS,yBACd,SACA,WAAiC,CAAC,GACZ;AACtB,MAAI,YAAY,QAAQ,OAAO,YAAY,YAAY,MAAM,QAAQ,OAAO;AAC1E,WAAO;AACT,QAAM,SAAS;AACf,SAAO;AAAA,IACL,GAAG;AAAA,IACH,GAAI,OAAO,OAAO,aAAa,MAAM,WAAW,EAAE,aAAa,OAAO,aAAa,EAAE,IAAI,CAAC;AAAA,IAC1F,GAAI,OAAO,OAAO,SAAS,MAAM,WAAW,EAAE,SAAS,OAAO,SAAS,EAAE,IAAI,CAAC;AAAA,IAC9E,GAAI,OAAO,OAAO,QAAQ,MAAM,WAAW,EAAE,QAAQ,OAAO,QAAQ,EAAE,IAAI,CAAC;AAAA,EAC7E;AACF;AAEO,SAAS,mBAAmB,OAAgD;AACjF,MAAI,UAAU,QAAQ,UAAU,YAAY,UAAU;AACpD,WAAO;AACT,SAAO;AACT;;;AC5CA,sCAA8C;AAE9C,mBAA4C;;;ACM5C,IAAM,WAAW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAyCjB,IAAM,eAAe;AAErB,IAAI,OAAO,aAAa,eAAe,SAAS,cAAc,0BAA0B,YAAY,IAAI,MAAM,MAAM;AAClH,QAAM,MAAM,SAAS,cAAc,OAAO;AAC1C,MAAI,QAAQ,QAAQ,IAAI;AACxB,MAAI,QAAQ,WAAW,IAAI;AAC3B,MAAI,cAAc;AAClB,WAAS,KAAK,YAAY,GAAG;AAC/B;AAEO,IAAM,OAAO;AACb,IAAM,WAAW;AACjB,IAAM,SAAS;AACf,IAAM,WAAW;AACjB,IAAM,OAAO;AACb,IAAM,cAAc;AACpB,IAAM,UAAU;AAChB,IAAM,UAAU;AAChB,IAAM,cAAc;AACpB,IAAM,OAAO;AACb,IAAM,WAAW;AACjB,IAAM,SAAS;AACf,IAAM,SAAS;AACf,IAAM,UAAU;AAChB,IAAM,OAAO;AACb,IAAM,QAAQ;AACd,IAAM,OAAO;AACb,IAAM,QAAQ;AACd,IAAM,SAAS;AACf,IAAM,QAAQ;AACd,IAAM,OAAO;AACb,IAAM,WAAW;AACjB,IAAM,UAAU;AAChB,IAAM,gBAAgB;;;ADtBrB;AA5CR,IAAM,KAAK,CAAC,UAAqD,MAAM,OAAO,OAAO,EAAE,KAAK,GAAG;AAE/F,IAAM,sBAA8F;AAAA,EAClG,EAAE,OAAO,UAAU,UAAU,YAAY;AAAA,EACzC,EAAE,OAAO,MAAM,UAAU,QAAQ;AAAA,EACjC,EAAE,OAAO,UAAU,UAAU,YAAY;AAC3C;AAOO,SAAS,aAAa,OAA0B;AACrD,QAAM,EAAE,EAAE,IAAI;AACd,QAAM,QAAQ,MAAM,gBAAgB,cAAY,QAAQ;AACxD,QAAM,CAAC,MAAM,OAAO,QAAI,uBAAS,KAAK;AACtC,QAAM,kBAAc,qBAAO,KAAK;AAChC,8BAAU,MAAM;AACd,QAAI,MAAM,QAAQ;AAChB,kBAAY,UAAU;AACtB;AAAA,IACF;AACA,QAAI,CAAC,YAAY;AACf;AACF,gBAAY,UAAU;AACtB,QAAI,CAAC,MAAM,SAAS,CAAC,MAAM;AACzB,cAAQ,KAAK;AAAA,EACjB,GAAG,CAAC,MAAM,OAAO,MAAM,QAAQ,MAAM,MAAM,CAAC;AAC5C,MAAI,CAAC,MAAM;AACT,WAAO;AACT,QAAM,WAAW,CAAC,MAAM;AACxB,QAAM,UAAU,CAAC,MAAM,SAAS,MAAM;AACtC,SACE,6CAAC,QAAG,WAAW,GAAG,CAAK,MAAM,QAAY,QAAQ,CAAC,GAChD;AAAA;AAAA,MAAC;AAAA;AAAA,QACC,MAAK;AAAA,QACL,WAAe;AAAA,QACf,iBAAe;AAAA,QACf,cAAY,GAAG,EAAE,OAAO,aAAa,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;AAAA,QAC7D,SAAS,MAAM;AACb,kBAAQ,CAAC,IAAI;AAAA,QACf;AAAA,QAEA;AAAA,uDAAC,UAAK,WAAe,UACnB;AAAA,wDAAC,UAAK,WAAe,MAAO,YAAE,OAAO,GAAE;AAAA,YACvC,4CAAC,UAAK,WAAe,aAAc,YAAE,aAAa,GAAE;AAAA,aACtD;AAAA,UACC,MAAM,QAAQ,4CAAC,uCAAI,MAAK,WAAU,WAAe,SAAU,YAAE,SAAS,GAAE,IAAS;AAAA,UAClF,4CAAC,4DAAyB,WAAW,GAAG,CAAK,SAAS,QAAY,WAAW,CAAC,GAAG;AAAA;AAAA;AAAA,IACnF;AAAA,IACC,OAEK,6CAAC,SAAI,WAAe,MACjB;AAAA,OAAC,MAAM,WAAW,4CAAC,OAAE,WAAe,UAAU,MAAK,UAAU,YAAE,UAAU,GAAE,IAAO;AAAA,MACnF,6CAAC,SAAI,WAAe,OAClB;AAAA,oDAAC,SAAI,WAAe,MAClB,sDAAC,UAAK,WAAe,OAAO,IAAG,8BAA8B,YAAE,aAAa,GAAE,GAChF;AAAA,QACA,4CAAC,SAAI,WAAe,UAAU,MAAK,cAAa,mBAAgB,8BAC7D,8BAAoB,IAAI,YACvB;AAAA,UAAC;AAAA;AAAA,YAEC,MAAK;AAAA,YACL,MAAK;AAAA,YACL,gBAAc,MAAM,gBAAgB,OAAO;AAAA,YAC3C,WAAW,GAAG,CAAK,SAAS,MAAM,gBAAgB,OAAO,SAAa,aAAa,CAAC;AAAA,YACpF;AAAA,YACA,SAAS,MAAM;AACb,oBAAM,KAAK,eAAe,OAAO,KAAK;AAAA,YACxC;AAAA,YAEC,YAAE,OAAO,QAAQ;AAAA;AAAA,UAVb,OAAO;AAAA,QAWd,CACD,GACH;AAAA,SACF;AAAA,MACC,MAAM,gBAAgB,WAEjB,6CAAC,SAAI,WAAe,OAClB;AAAA,oDAAC,SAAI,WAAe,MAClB,sDAAC,WAAM,WAAe,OAAO,SAAQ,qBAAqB,YAAE,SAAS,GAAE,GACzE;AAAA,QACA;AAAA,UAAC;AAAA;AAAA,YACC,IAAG;AAAA,YACH,WAAe;AAAA,YACf,MAAK;AAAA,YACL,OAAO,MAAM;AAAA,YACb,aAAY;AAAA,YACZ;AAAA,YACA,UAAU,CAAC,UAAU;AACnB,oBAAM,KAAK,WAAW,MAAM,cAAc,KAAK;AAAA,YACjD;AAAA;AAAA,QACF;AAAA,QACA,4CAAC,OAAE,WAAe,MAAO,YAAE,aAAa,GAAE;AAAA,SAC5C,IAEF;AAAA,MACJ,6CAAC,SAAI,WAAe,OAClB;AAAA,qDAAC,SAAI,WAAe,MAClB;AAAA,sDAAC,WAAM,WAAe,OAAO,SAAQ,oBAAoB,YAAE,QAAQ,GAAE;AAAA,UACrE,4CAAC,UAAK,WAAe,QACnB,sDAAC,uCAAI,MAAM,MAAM,mBAAmB,YAAY,SAC7C,gBAAM,mBAAmB,EAAE,WAAW,IAAI,EAAE,aAAa,GAC5D,GACF;AAAA,WACF;AAAA,QACA;AAAA,UAAC;AAAA;AAAA,YACC,IAAG;AAAA,YACH,WAAe;AAAA,YACf,MAAK;AAAA,YACL,cAAa;AAAA,YACb,OAAO,MAAM;AAAA,YACb;AAAA,YACA,UAAU,CAAC,UAAU;AACnB,oBAAM,KAAK,UAAU,MAAM,cAAc,KAAK;AAAA,YAChD;AAAA;AAAA,QACF;AAAA,QACA,4CAAC,OAAE,WAAe,MAAO,YAAE,YAAY,GAAE;AAAA,SAC3C;AAAA,MACA,6CAAC,SAAI,WAAe,QACjB;AAAA,cAAM,SAAS,4CAAC,OAAE,WAAe,QAAQ,MAAK,UAAU,YAAE,YAAY,GAAE,IAAO;AAAA,QAChF;AAAA,UAAC;AAAA;AAAA,YACC,MAAK;AAAA,YACL,WAAe;AAAA,YACf,UAAU,CAAC,MAAM,SAAS,MAAM;AAAA,YAChC,SAAS,MAAM;AAAA,YAEd,YAAE,SAAS;AAAA;AAAA,QACd;AAAA,QACA;AAAA,UAAC;AAAA;AAAA,YACC,MAAK;AAAA,YACL,WAAe;AAAA,YACf,UAAU;AAAA,YACV,SAAS,MAAM;AAAA,YAEd,YAAE,MAAM,SAAS,WAAW,MAAM;AAAA;AAAA,QACrC;AAAA,SACF;AAAA,OACF,IAEF;AAAA,KACN;AAEJ;;;AEhKA,8BAAmD;AAkD5C,SAAS,uBAAuB,OAA4C,UAAkD;AACnI,MAAI,QAAmB,CAAC;AACxB,MAAI,SAAS;AACb,MAAIC,UAAS;AACb,QAAM,YAAQ,6CAAuC,QAAQ,CAAC;AAE9D,WAAS,SAA+B;AACtC,WAAO,MAAM,YAAY,EAAE,SAAS,CAAC;AAAA,EACvC;AAEA,WAAS,mBAA4B;AACnC,UAAM,OAAO,SAAS,YAAY,EAAE;AACpC,UAAM,UAAU,MAAM,WAAW,KAAK,eAAa,UAAU,OAAO,kBAAkB;AACtF,WAAO,SAAS,QAAQ,KAAK,CAAC,WAAuB,OAAO,KAAK,WAAW,KAAK,OAAO,KAAK,CAAC,MAAM,YAAY,OAAO,GAAG,KAAK;AAAA,EACjI;AAEA,WAAS,gBAAgC;AACvC,UAAM,QAAQ,OAAO;AACrB,UAAM,SAAyB,CAAC;AAChC,UAAM,cAAc,MAAM,eAAe,mBAAmB,MAAM,WAAW;AAC7E,QAAI,MAAM,gBAAgB,UAAa,gBAAgB,mBAAmB,MAAM,WAAW;AACzF,aAAO,KAAK,aAAa;AAC3B,QAAI,MAAM,WAAW,UAAa,MAAM,OAAO,KAAK,MAAM;AACxD,aAAO,KAAK,QAAQ;AACtB,QAAI,MAAM,YAAY,UAAa,gBAAgB,YAAY,MAAM,aAAa,MAAM,WAAW;AACjG,aAAO,KAAK,SAAS;AACvB,QAAI,gBAAgB,YAAY,MAAM,YAAY;AAChD,aAAO,KAAK,SAAS;AACvB,WAAO;AAAA,EACT;AAEA,WAAS,UAA6B;AACpC,UAAM,WAAW,MAAM,YAAY;AACnC,UAAM,QAAQ,OAAO;AACrB,WAAO;AAAA,MACL,WAAW,SAAS,WAAW;AAAA,MAC/B,UAAU,SAAS;AAAA,MACnB,OAAO,cAAc,EAAE,SAAS;AAAA,MAChC;AAAA,MACA,QAAAA;AAAA,MACA,aAAa,MAAM,eAAe,mBAAmB,MAAM,WAAW;AAAA,MACtE,SAAS,MAAM,WAAW,MAAM,WAAW;AAAA,MAC3C,QAAQ,MAAM,UAAU;AAAA,MACxB,kBAAkB,iBAAiB;AAAA,IACrC;AAAA,EACF;AAEA,QAAM,UAAU,MAAM;AACpB,UAAM,IAAI,QAAQ,CAAC;AAAA,EACrB;AAEA,iBAAe,SAAwB;AACrC,UAAM,WAAW,MAAM,YAAY;AACnC,UAAM,SAAS,cAAc;AAC7B,QAAI,UAAU,SAAS,WAAW,WAAW,CAAC,SAAS,YAAY,OAAO,WAAW;AACnF;AACF,UAAM,QAAQ,OAAO;AACrB,UAAM,cAAc,MAAM,eAAe,mBAAmB,MAAM,WAAW;AAC7E,UAAM,UAAU,MAAM,WAAW,MAAM,WAAW;AAClD,UAAM,SAAS,MAAM,QAAQ,KAAK,KAAK;AACvC,aAAS;AACT,IAAAA,UAAS;AACT,YAAQ;AACR,QAAI;AACF,UAAI,OAAO,SAAS,aAAa;AAC/B,cAAM,MAAM,IAAI,eAAe,WAAW;AAC5C,UAAI,OAAO,SAAS,QAAQ;AAC1B,cAAM,MAAM,IAAI,UAAU,MAAM;AAClC,UAAI,OAAO,SAAS,SAAS,GAAG;AAC9B,YAAI,gBAAgB;AAClB,gBAAM,MAAM,IAAI,WAAW,OAAO;AAAA;AAElC,gBAAM,MAAM,MAAM,SAAS;AAAA,MAC/B;AAAA,IACF,QACM;AAGJ,eAAS;AACT,MAAAA,UAAS;AACT,cAAQ;AACR;AAAA,IACF;AACA,UAAM,UAAU,OAAO,SAAS,aAAa,IAAI,mBAAmB,OAAO,EAAE,WAAW,MAAM,cAAc,UACtG,OAAO,SAAS,QAAQ,IAAI,iBAAiB,IAAI,UACjD,OAAO,SAAS,SAAS,IACxB,gBAAgB,YAAY,OAAO,EAAE,WAAW,QAAQ,UAAU,OAAO,EAAE,YAAY,SACxF;AACN,aAAS;AACT,QAAI;AACF,cAAQ,CAAC;AAAA;AAET,MAAAA,UAAS;AACX,YAAQ;AAAA,EACV;AAEA,QAAM,UAAU,OAAO;AACvB,WAAS,UAAU,OAAO;AAC1B,OAAK,SAAS,OAAO;AAErB,SAAO;AAAA,IACL,OAAO,EAAE,cAAc,MAAM;AAAA,IAC7B,MAAM,CAACC,QAAO,UAAU;AACtB,UAAI;AACF;AACF,MAAAD,UAAS;AACT,UAAIC,WAAU,eAAe;AAC3B,cAAM,cAAc,mBAAmB,KAAK;AAC5C,gBAAQ,gBAAgB,WACpB,EAAE,GAAG,OAAO,YAAY,IACxB,EAAE,GAAG,OAAO,aAAa,SAAS,OAAU;AAAA,MAClD,OACK;AACH,gBAAQ,EAAE,GAAG,OAAO,CAACA,MAAK,GAAG,MAAM;AAAA,MACrC;AACA,cAAQ;AAAA,IACV;AAAA,IACA,MAAM,MAAM,OAAO;AAAA,IACnB,SAAS,MAAM;AACb,cAAQ,CAAC;AACT,MAAAD,UAAS;AACT,cAAQ;AAAA,IACV;AAAA,EACF;AACF;;;AC5KO,IAAM,iBAAiB;AAWvB,IAAM,sBAAsB;AAAA,EACjC,IAAI;AAAA,IACF,OAAO;AAAA,IACP,aAAa;AAAA,IACb,aAAa;AAAA,IACb,WAAW;AAAA,IACX,OAAO;AAAA,IACP,WAAW;AAAA,IACX,SAAS;AAAA,IACT,aAAa;AAAA,IACb,QAAQ;AAAA,IACR,WAAW;AAAA,IACX,aAAa;AAAA,IACb,YAAY;AAAA,IACZ,QAAQ;AAAA,IACR,UAAU;AAAA,IACV,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,SAAS;AAAA,IACT,YAAY;AAAA,IACZ,UAAU;AAAA,EACZ;AAAA,EACA,IAAI;AAAA,IACF,OAAO;AAAA,IACP,aAAa;AAAA,IACb,aAAa;AAAA,IACb,WAAW;AAAA,IACX,OAAO;AAAA,IACP,WAAW;AAAA,IACX,SAAS;AAAA,IACT,aAAa;AAAA,IACb,QAAQ;AAAA,IACR,WAAW;AAAA,IACX,aAAa;AAAA,IACb,YAAY;AAAA,IACZ,QAAQ;AAAA,IACR,UAAU;AAAA,IACV,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,SAAS;AAAA,IACT,YAAY;AAAA,IACZ,UAAU;AAAA,EACZ;AACF;;;ALpDO,IAAME,QAAO;AACb,IAAM,SAAS,CAAC,SAAS,UAAU,eAAe;AAElD,SAAS,MAAM,KAAoB;AACxC,MAAI;AAAA,IACF,MAAM,IAAI,OAAO,SAAS,gBAAgB,mBAAmB;AAAA,IAC7D;AAAA,EACF;AACA,QAAM,QAAQ,IAAI,cAAc,KAA2B;AAAA,IACzD,WAAW;AAAA,IACX,QAAQ,aAAW,yBAAyB,OAAO;AAAA,EACrD,CAAC;AACD,QAAM,OAAO,uBAAuB,OAAO,IAAI,cAAc,SAAS,CAAC;AACvE,MAAI,MAAM,OAAO,wBAAwB,MACvC,IAAI,MAAM;AAAA,IACR;AAAA,MACE,MAAM;AAAA,MACN,KAAK;AAAA,MACL,QAAQ;AAAA,MACR,QAAQ,MAAM;AAAA,IAChB;AAAA,IACA;AAAA,EACF,CAAC;AACL;",
4
+ "sourcesContent": ["import { Context } from '@deepseek-ai/cordis'\nimport { AitoearnPluginConfig, SETTINGS_NAMESPACE } from '../auth.js'\nimport { AitoearnCard } from './AitoearnCard.js'\nimport { createAitoearnCardFace } from './card-store.js'\nimport { aitoearnCardLocales, aitoearnCardNS } from './i18n.js'\n\nexport const name = 'aitoearn-settings-card'\nexport const inject = ['slots', 'locale', 'configForms']\n\nexport function apply(ctx: Context): void {\n ctx.effect(\n () => ctx.locale.register(aitoearnCardNS, aitoearnCardLocales),\n 'aitoearn-settings-card: dictionaries',\n )\n const t = ctx.locale.bind(aitoearnCardNS)\n ctx.effect(() => ctx.configForms.whileServed([SETTINGS_NAMESPACE], () => {\n const form = ctx.configForms.get<AitoearnPluginConfig>(SETTINGS_NAMESPACE)\n const face = createAitoearnCardFace(form, ctx.configForms.describe())\n return ctx.slots.inject('settings.plugins.tab', () =>\n ctx.slots.register(\n {\n name: 'settings.plugins.tab',\n id: 'aitoearn',\n order: 10,\n label: () => t('title'),\n locale: aitoearnCardNS,\n inject: () => face,\n },\n AitoearnCard,\n ))\n }), 'aitoearn-settings-card: tab')\n}\n", "export const MCP_PATH = '/api/ai/agent/mcp'\nexport const API_KEY_ENV = 'AITOEARN_API_KEY'\nexport const DEFAULT_ENVIRONMENT = 'global'\nexport const SETTINGS_NAMESPACE = 'aitoearn'\n\nexport const ENVIRONMENT_ORIGINS = {\n global: 'https://aitoearn.ai',\n cn: 'https://aitoearn.cn',\n} as const\n\nexport const DEFAULT_MCP_URL = `${ENVIRONMENT_ORIGINS.global}${MCP_PATH}`\n\nexport type AitoearnEnvironment = 'global' | 'cn' | 'custom'\n\nexport interface AitoearnAuth {\n mcpUrl: string\n apiKey: string\n}\n\nexport interface AitoearnPluginConfig {\n environment?: string\n baseUrl?: string\n apiKey?: string\n}\n\nexport function pluginConfigFromSettings(\n section: unknown,\n fallback: AitoearnPluginConfig = {},\n): AitoearnPluginConfig {\n if (section === null || typeof section !== 'object' || Array.isArray(section))\n return fallback\n const record = section as Record<string, unknown>\n return {\n ...fallback,\n ...(typeof record['environment'] === 'string' ? { environment: record['environment'] } : {}),\n ...(typeof record['baseUrl'] === 'string' ? { baseUrl: record['baseUrl'] } : {}),\n ...(typeof record['apiKey'] === 'string' ? { apiKey: record['apiKey'] } : {}),\n }\n}\n\nexport function resolveEnvironment(value: string | undefined): AitoearnEnvironment {\n if (value === 'cn' || value === 'custom' || value === 'global')\n return value\n return DEFAULT_ENVIRONMENT\n}\n\nexport function resolveOrigin(environment: AitoearnEnvironment, baseUrl?: string): string {\n if (environment !== 'custom')\n return ENVIRONMENT_ORIGINS[environment]\n const trimmed = baseUrl?.trim() ?? ''\n if (trimmed.length === 0)\n return ''\n try {\n const url = new URL(trimmed)\n if (url.protocol !== 'http:' && url.protocol !== 'https:')\n return ''\n return url.origin\n }\n catch {\n return ''\n }\n}\n\nexport function resolveMcpUrl(config: AitoearnPluginConfig): string {\n const environment = resolveEnvironment(config.environment)\n const origin = resolveOrigin(environment, config.baseUrl)\n if (origin.length === 0)\n return ''\n return `${origin}${MCP_PATH}`\n}\n\nexport function resolveAuth(\n config: AitoearnPluginConfig,\n env: NodeJS.ProcessEnv = process.env,\n): AitoearnAuth {\n return {\n mcpUrl: resolveMcpUrl(config),\n apiKey: config.apiKey?.trim() || env[API_KEY_ENV]?.trim() || '',\n }\n}\n\nexport function authorizationHeader(apiKey: string): Record<string, string> {\n if (apiKey.length === 0)\n return {}\n return { Authorization: `Bearer ${apiKey}` }\n}\n", "import { IconChevronDownOutlineRegular, Tag } from '@deepseek-ai/dsh-client-ui-primitives'\nimport { SnapshotSelectorHook, TranslateNS } from '@deepseek-ai/dsh-client-ui-slots'\nimport { useEffect, useRef, useState } from 'react'\nimport { AitoearnEnvironment } from '../auth.js'\nimport { AitoearnCardState } from './card-store.js'\nimport * as css from './card.css.js'\nimport { AitoearnCardLocaleKey } from './i18n.js'\n\nexport interface AitoearnCardProps {\n t: TranslateNS<'aitoearn-card'>\n useAitoearnCard: SnapshotSelectorHook<AitoearnCardState>\n edit: (field: 'environment' | 'baseUrl' | 'apiKey', value: string) => void\n save: () => void\n discard: () => void\n}\n\nconst cx = (names: Array<string | false | undefined>): string => names.filter(Boolean).join(' ')\n\nconst ENVIRONMENT_OPTIONS: Array<{ value: AitoearnEnvironment, labelKey: AitoearnCardLocaleKey }> = [\n { value: 'global', labelKey: 'envGlobal' },\n { value: 'cn', labelKey: 'envCn' },\n { value: 'custom', labelKey: 'envCustom' },\n]\n\n/**\n * The Aitoearn plugin settings card, laid out after the official plugin cards:\n * a header naming the plugin, its fields in place, and the footer that writes\n * the staged edits.\n */\nexport function AitoearnCard(props: AitoearnCardProps) {\n const { t } = props\n const state = props.useAitoearnCard(snapshot => snapshot)\n const [open, setOpen] = useState(false)\n const saveStarted = useRef(false)\n useEffect(() => {\n if (state.saving) {\n saveStarted.current = true\n return\n }\n if (!saveStarted.current)\n return\n saveStarted.current = false\n if (!state.dirty && !state.failed)\n setOpen(false)\n }, [state.dirty, state.failed, state.saving])\n if (!state.available)\n return null\n const disabled = !state.writable\n const blocked = !state.dirty || state.saving\n return (\n <li className={cx([css.card, open && css.cardOpen])}>\n <button\n type=\"button\"\n className={css.header}\n aria-expanded={open}\n aria-label={`${t(open ? 'collapse' : 'expand')}: ${t('title')}`}\n onClick={() => {\n setOpen(!open)\n }}\n >\n <span className={css.headText}>\n <span className={css.name}>{t('title')}</span>\n <span className={css.description}>{t('description')}</span>\n </span>\n {state.dirty ? <Tag tone=\"neutral\" className={css.pending}>{t('unsaved')}</Tag> : null}\n <IconChevronDownOutlineRegular className={cx([css.chevron, open && css.chevronOpen])} />\n </button>\n {open\n ? (\n <div className={css.body}>\n {!state.writable ? <p className={css.readOnly} role=\"status\">{t('readOnly')}</p> : null}\n <div className={css.field}>\n <div className={css.head}>\n <span className={css.label} id=\"aitoearn-environment-label\">{t('environment')}</span>\n </div>\n <div className={css.envGroup} role=\"radiogroup\" aria-labelledby=\"aitoearn-environment-label\">\n {ENVIRONMENT_OPTIONS.map(option => (\n <button\n key={option.value}\n type=\"button\"\n role=\"radio\"\n aria-checked={state.environment === option.value}\n className={cx([css.envPill, state.environment === option.value && css.envPillActive])}\n disabled={disabled}\n onClick={() => {\n props.edit('environment', option.value)\n }}\n >\n {t(option.labelKey)}\n </button>\n ))}\n </div>\n </div>\n {state.environment === 'custom'\n ? (\n <div className={css.field}>\n <div className={css.head}>\n <label className={css.label} htmlFor=\"aitoearn-base-url\">{t('baseUrl')}</label>\n </div>\n <input\n id=\"aitoearn-base-url\"\n className={css.input}\n type=\"text\"\n value={state.baseUrl}\n placeholder=\"https://example.com\"\n disabled={disabled}\n onChange={(event) => {\n props.edit('baseUrl', event.currentTarget.value)\n }}\n />\n <p className={css.hint}>{t('baseUrlHint')}</p>\n </div>\n )\n : null}\n <div className={css.field}>\n <div className={css.head}>\n <label className={css.label} htmlFor=\"aitoearn-api-key\">{t('apiKey')}</label>\n <span className={css.badges}>\n <Tag tone={state.apiKeyConfigured ? 'neutral' : 'quiet'}>\n {state.apiKeyConfigured ? t('apiKeySet') : t('apiKeyUnset')}\n </Tag>\n </span>\n </div>\n <input\n id=\"aitoearn-api-key\"\n className={css.input}\n type=\"password\"\n autoComplete=\"off\"\n value={state.apiKey}\n disabled={disabled}\n onChange={(event) => {\n props.edit('apiKey', event.currentTarget.value)\n }}\n />\n <p className={css.hint}>{t('apiKeyHint')}</p>\n </div>\n <div className={css.footer}>\n {state.failed ? <p className={css.failed} role=\"status\">{t('saveFailed')}</p> : null}\n <button\n type=\"button\"\n className={css.discard}\n disabled={!state.dirty || state.saving}\n onClick={props.discard}\n >\n {t('discard')}\n </button>\n <button\n type=\"button\"\n className={css.save}\n disabled={blocked}\n onClick={props.save}\n >\n {t(state.saving ? 'saving' : 'save')}\n </button>\n </div>\n </div>\n )\n : null}\n </li>\n )\n}\n", "/**\n * Card styles for the Aitoearn plugin settings card. Values mirror the\n * official `PluginCard` / field styling in `@deepseek-ai/dsh-client-ui-settings-plugins`\n * so the card reads like the Bash / Agent loop / Web search cards. Everything is\n * token-styled through `--dsw-alias-*`; the sheet self-injects once, the same\n * `style[data-plugin-css]` way the official client packages do.\n */\n\nconst CARD_CSS = `\n.Ata_card{border:.5px solid var(--dsw-alias-border-l4);background:var(--dsw-alias-bg-layer-3);border-radius:16px;list-style:none;transition:border-color .16s,background .16s}\n.Ata_card:hover{border-color:var(--dsw-alias-label-dimmed)}\n.Ata_cardOpen{background:var(--dsw-alias-bg-layer-2);border-color:var(--dsw-alias-label-dimmed)}\n.Ata_header{appearance:none;width:100%;font:inherit;color:inherit;text-align:left;cursor:pointer;background:0 0;border:0;border-radius:12px;align-items:center;gap:12px;padding:14px 16px;display:flex}\n.Ata_header:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:-2px}\n.Ata_headText{flex-direction:column;flex:1;gap:4px;min-width:0;display:flex}\n.Ata_name{color:var(--dsw-alias-label-primary);font-size:15px;font-weight:600;line-height:1.4}\n.Ata_description{color:var(--dsw-alias-label-tertiary);font-size:13px;line-height:1.5}\n.Ata_pending{flex:none}\n.Ata_chevron{color:var(--dsw-alias-label-tertiary);flex:none;transition:transform .16s}\n.Ata_chevronOpen{transform:rotate(180deg)}\n.Ata_body{border-top:.5px solid var(--dsw-alias-border-l2);margin:0 16px;padding-bottom:8px}\n.Ata_readOnly{color:var(--dsw-alias-label-tertiary);margin:12px 0 0;font-size:12px;line-height:1.5}\n.Ata_footer{border-top:.5px solid var(--dsw-alias-border-l2);justify-content:flex-end;align-items:center;gap:8px;padding:12px 0 4px;display:flex}\n.Ata_failed{min-width:0;color:var(--dsw-alias-label-error);flex:1;margin:0;font-size:12px;line-height:1.5}\n.Ata_discard,.Ata_save{appearance:none;font:inherit;cursor:pointer;border:1px solid #0000;border-radius:8px;padding:5px 14px;font-size:13px;line-height:1.5;transition:background .16s,border-color .16s,color .16s}\n.Ata_discard{border-color:var(--dsw-alias-border-l2);color:var(--dsw-alias-label-secondary);background:0 0}\n.Ata_discard:hover:not(:disabled){color:var(--dsw-alias-label-primary);border-color:var(--dsw-alias-label-dimmed)}\n.Ata_discard:active:not(:disabled){background:var(--dsw-alias-interactive-bg-active)}\n.Ata_save{background:var(--dsw-alias-label-primary);color:var(--dsw-alias-bg-layer-3)}\n.Ata_discard:disabled,.Ata_save:disabled{opacity:.4;cursor:default}\n.Ata_discard:focus-visible,.Ata_save:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:1px}\n.Ata_field{flex-direction:column;gap:6px;padding:12px 0;display:flex}\n.Ata_field+.Ata_field{border-top:.5px solid var(--dsw-alias-border-l2)}\n.Ata_head{align-items:center;gap:8px;display:flex}\n.Ata_label{min-width:0;color:var(--dsw-alias-label-primary);flex:1;font-size:13px;font-weight:500;line-height:1.5}\n.Ata_badges{align-items:center;gap:8px;display:inline-flex}\n.Ata_input{border:.5px solid var(--dsw-alias-border-l4);background:var(--dsw-alias-bg-layer-3);height:34px;font:inherit;color:var(--dsw-alias-label-primary);border-radius:8px;padding:0 12px;font-size:13px;line-height:1.5}\n.Ata_input:focus-visible{border-color:var(--dsw-alias-brand-primary);outline:none}\n.Ata_input:disabled{color:var(--dsw-alias-label-tertiary);cursor:default}\n.Ata_hint{color:var(--dsw-alias-label-tertiary);margin:0;font-size:12px;line-height:1.5}\n.Ata_envGroup{flex-wrap:wrap;gap:8px;display:flex}\n.Ata_envPill{appearance:none;font:inherit;cursor:pointer;border:.5px solid var(--dsw-alias-border-l4);background:var(--dsw-alias-bg-layer-3);color:var(--dsw-alias-label-secondary);border-radius:999px;padding:5px 14px;font-size:13px;line-height:1.5;transition:background .16s,border-color .16s,color .16s}\n.Ata_envPill:hover:not(:disabled):not(.Ata_envPillActive){color:var(--dsw-alias-label-primary);border-color:var(--dsw-alias-label-dimmed)}\n.Ata_envPill:active:not(:disabled){background:var(--dsw-alias-bg-layer-4)}\n.Ata_envPill:disabled{opacity:.4;cursor:not-allowed}\n.Ata_envPill:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:1px}\n.Ata_envPillActive{border-color:var(--dsw-alias-brand-primary);color:var(--dsw-alias-brand-primary)}\n`\n\nconst STYLE_TAG_ID = '@aitoearn/dsh-plugin/card.css'\n\nif (typeof document !== 'undefined' && document.querySelector(`style[data-plugin-css=\"${STYLE_TAG_ID}\"]`) === null) {\n const tag = document.createElement('style')\n tag.dataset['plugin'] = '@aitoearn/dsh-plugin'\n tag.dataset['pluginCss'] = STYLE_TAG_ID\n tag.textContent = CARD_CSS\n document.head.appendChild(tag)\n}\n\nexport const card = 'Ata_card'\nexport const cardOpen = 'Ata_cardOpen'\nexport const header = 'Ata_header'\nexport const headText = 'Ata_headText'\nexport const name = 'Ata_name'\nexport const description = 'Ata_description'\nexport const pending = 'Ata_pending'\nexport const chevron = 'Ata_chevron'\nexport const chevronOpen = 'Ata_chevronOpen'\nexport const body = 'Ata_body'\nexport const readOnly = 'Ata_readOnly'\nexport const footer = 'Ata_footer'\nexport const failed = 'Ata_failed'\nexport const discard = 'Ata_discard'\nexport const save = 'Ata_save'\nexport const field = 'Ata_field'\nexport const head = 'Ata_head'\nexport const label = 'Ata_label'\nexport const badges = 'Ata_badges'\nexport const input = 'Ata_input'\nexport const hint = 'Ata_hint'\nexport const envGroup = 'Ata_envGroup'\nexport const envPill = 'Ata_envPill'\nexport const envPillActive = 'Ata_envPillActive'\n", "import { createSnapshotStore, SnapshotStore } from '@deepseek-ai/dsh-client-store'\nimport { ConfigForm, SettingsDescribeFace } from '@deepseek-ai/dsh-client-ui-settings/client'\nimport { AitoearnEnvironment, AitoearnPluginConfig, resolveEnvironment, SETTINGS_NAMESPACE } from '../auth.js'\n\nexport type AitoearnCardField = 'environment' | 'baseUrl' | 'apiKey'\n\nexport interface AitoearnCardState {\n available: boolean\n writable: boolean\n dirty: boolean\n saving: boolean\n failed: boolean\n environment: AitoearnEnvironment\n baseUrl: string\n apiKey: string\n apiKeyConfigured: boolean\n}\n\nexport interface AitoearnCardFace {\n hooks: { aitoearnCard: SnapshotStore<AitoearnCardState> }\n edit: (field: AitoearnCardField, value: string) => void\n save: () => void\n discard: () => void\n}\n\n/** Staged edits over the card's fields; an absent field inherits the section. */\ninterface CardDraft {\n environment?: AitoearnEnvironment\n baseUrl?: string\n apiKey?: string\n}\n\ntype PendingWrite = 'environment' | 'apiKey' | 'baseUrl'\n\n/** One schema-declared secret slot in the namespace view (`SettingsSecretView`). */\ninterface SecretSlot {\n path: string[]\n set: boolean\n}\n\n/**\n * Bridges the `aitoearn` settings scope onto the card's staged form. Edits stay\n * local drafts until `save` writes them in one gesture; a save that did not land\n * keeps its drafts so the user can correct them instead of retyping.\n *\n * The API key is a schema-declared secret: the Host redacts it from every view\n * it serves, so the key can never be read back and the input starts blank. A\n * blank draft keeps the stored key, and whether one is configured comes from\n * the namespace view's secret record.\n */\nexport function createAitoearnCardFace(form: ConfigForm<AitoearnPluginConfig>, describe: SettingsDescribeFace): AitoearnCardFace {\n let draft: CardDraft = {}\n let saving = false\n let failed = false\n const store = createSnapshotStore<AitoearnCardState>(project())\n\n function stored(): AitoearnPluginConfig {\n return form.getSnapshot().value ?? {}\n }\n\n function apiKeyConfigured(): boolean {\n const view = describe.getSnapshot().view\n const section = view?.namespaces.find(candidate => candidate.ns === SETTINGS_NAMESPACE)\n return section?.secrets.some((secret: SecretSlot) => secret.path.length === 1 && secret.path[0] === 'apiKey' && secret.set) ?? false\n }\n\n function pendingWrites(): PendingWrite[] {\n const value = stored()\n const writes: PendingWrite[] = []\n const environment = draft.environment ?? resolveEnvironment(value.environment)\n if (draft.environment !== undefined && environment !== resolveEnvironment(value.environment))\n writes.push('environment')\n if (draft.apiKey !== undefined && draft.apiKey.trim() !== '')\n writes.push('apiKey')\n if (draft.baseUrl !== undefined && environment === 'custom' && draft.baseUrl !== (value.baseUrl ?? ''))\n writes.push('baseUrl')\n if (environment !== 'custom' && value.baseUrl !== undefined)\n writes.push('baseUrl')\n return writes\n }\n\n function project(): AitoearnCardState {\n const snapshot = form.getSnapshot()\n const value = stored()\n return {\n available: snapshot.status === 'ready',\n writable: snapshot.writable,\n dirty: pendingWrites().length > 0,\n saving,\n failed,\n environment: draft.environment ?? resolveEnvironment(value.environment),\n baseUrl: draft.baseUrl ?? value.baseUrl ?? '',\n apiKey: draft.apiKey ?? '',\n apiKeyConfigured: apiKeyConfigured(),\n }\n }\n\n const publish = () => {\n store.set(project())\n }\n\n async function commit(): Promise<void> {\n const snapshot = form.getSnapshot()\n const writes = pendingWrites()\n if (saving || snapshot.status !== 'ready' || !snapshot.writable || writes.length === 0)\n return\n const value = stored()\n const environment = draft.environment ?? resolveEnvironment(value.environment)\n const baseUrl = draft.baseUrl ?? value.baseUrl ?? ''\n const apiKey = draft.apiKey?.trim() ?? ''\n saving = true\n failed = false\n publish()\n // A `false` answer means the Host refused or skipped the write (transport\n // failures reject instead): keep the drafts so the user can correct them.\n let accepted = true\n try {\n if (writes.includes('environment'))\n accepted = await form.set('environment', environment) && accepted\n if (writes.includes('apiKey'))\n accepted = await form.set('apiKey', apiKey) && accepted\n if (writes.includes('baseUrl')) {\n if (environment === 'custom')\n accepted = await form.set('baseUrl', baseUrl) && accepted\n else\n accepted = await form.unset('baseUrl') && accepted\n }\n }\n catch {\n // A rejected write keeps the drafts on screen (with the failure flag) so\n // the user can correct them instead of retyping.\n saving = false\n failed = true\n publish()\n return\n }\n if (!accepted) {\n saving = false\n failed = true\n publish()\n return\n }\n const landed = (writes.includes('environment') ? resolveEnvironment(stored().environment) === environment : true)\n && (writes.includes('apiKey') ? apiKeyConfigured() : true)\n && (writes.includes('baseUrl')\n ? (environment === 'custom' ? (stored().baseUrl ?? '') === baseUrl : stored().baseUrl === undefined)\n : true)\n saving = false\n if (landed)\n draft = {}\n else\n failed = true\n publish()\n }\n\n form.subscribe(publish)\n describe.subscribe(publish)\n void describe.ensure()\n\n return {\n hooks: { aitoearnCard: store },\n edit: (field, value) => {\n if (saving)\n return\n failed = false\n if (field === 'environment') {\n const environment = resolveEnvironment(value)\n draft = environment === 'custom'\n ? { ...draft, environment }\n : { ...draft, environment, baseUrl: undefined }\n }\n else {\n draft = { ...draft, [field]: value }\n }\n publish()\n },\n save: () => commit(),\n discard: () => {\n draft = {}\n failed = false\n publish()\n },\n }\n}\n", "/** Locale dictionary for the Aitoearn plugin settings card. */\n\nexport const aitoearnCardNS = 'aitoearn-card'\n\ndeclare module '@deepseek-ai/dsh-client-ui-slots' {\n interface LocaleNamespaceMap {\n /** The Aitoearn plugin card's copy. */\n 'aitoearn-card': keyof typeof aitoearnCardLocales.zh\n }\n}\n\nexport type AitoearnCardLocaleKey = keyof typeof aitoearnCardLocales.zh\n\nexport const aitoearnCardLocales = {\n zh: {\n title: 'Aitoearn',\n description: 'Aitoearn \u5DE5\u5177\u7684\u8FD0\u884C\u73AF\u5883\u4E0E API Key\u3002',\n environment: '\u8FD0\u884C\u73AF\u5883',\n envGlobal: '\u56FD\u9645\u7AD9 aitoearn.ai',\n envCn: '\u4E2D\u56FD\u7AD9 aitoearn.cn',\n envCustom: '\u81EA\u5B9A\u4E49',\n baseUrl: '\u63A5\u53E3\u5730\u5740',\n baseUrlHint: '\u7559\u7A7A\u5219\u4F7F\u7528\u6240\u9009\u73AF\u5883\u9ED8\u8BA4\u5730\u5740\u3002',\n apiKey: 'API Key',\n apiKeySet: '\u5DF2\u914D\u7F6E\u5BC6\u94A5\u3002',\n apiKeyUnset: '\u672A\u914D\u7F6E\u5BC6\u94A5\uFF1B\u914D\u7F6E\u4E4B\u524D Aitoearn \u5DE5\u5177\u4E0D\u53EF\u7528\u3002',\n apiKeyHint: '\u51FA\u4E8E\u5B89\u5168\u8003\u8651\u5BC6\u94A5\u4E0D\u4F1A\u56DE\u663E\uFF1B\u7559\u7A7A\u8868\u793A\u4FDD\u6301\u5F53\u524D\u5BC6\u94A5\uFF0C\u8F93\u5165\u65B0\u503C\u5C06\u8986\u76D6\u3002',\n expand: '\u5C55\u5F00\u8BBE\u7F6E',\n collapse: '\u6536\u8D77\u8BBE\u7F6E',\n save: '\u4FDD\u5B58',\n saving: '\u4FDD\u5B58\u4E2D\u2026',\n discard: '\u653E\u5F03\u4FEE\u6539',\n unsaved: '\u672A\u4FDD\u5B58',\n saveFailed: '\u672C\u90E8\u7F72\u6CA1\u6709\u63A5\u53D7\u8FD9\u4E9B\u503C\uFF0C\u5DF2\u4FDD\u7559\u4F9B\u4F60\u4FEE\u6539\u3002',\n readOnly: '\u672C\u90E8\u7F72\u7684\u8BBE\u7F6E\u4E3A\u53EA\u8BFB\u3002',\n },\n en: {\n title: 'Aitoearn',\n description: 'Environment and API key for Aitoearn tools.',\n environment: 'Environment',\n envGlobal: 'Global (aitoearn.ai)',\n envCn: 'China (aitoearn.cn)',\n envCustom: 'Custom',\n baseUrl: 'Base URL',\n baseUrlHint: 'Leave blank to use the selected environment default.',\n apiKey: 'API key',\n apiKeySet: 'A key is configured.',\n apiKeyUnset: 'No key is configured; Aitoearn tools are unavailable until one is.',\n apiKeyHint: 'The key is never displayed back; leave blank to keep the current key, or type a new one to overwrite it.',\n expand: 'Show settings',\n collapse: 'Hide settings',\n save: 'Save',\n saving: 'Saving\u2026',\n discard: 'Discard',\n unsaved: 'Unsaved',\n saveFailed: 'The deployment did not accept these values; they were left for you to correct.',\n readOnly: 'This deployment stores settings read-only.',\n },\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["name", "failed", "field", "name"]
7
7
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "aitoearn-dsh-plugin-test",
3
3
  "type": "module",
4
- "version": "0.0.3",
4
+ "version": "0.0.4",
5
5
  "description": "Aitoearn agent preset, skills, and MCP tools for DeepSeek Harness",
6
6
  "exports": {
7
7
  ".": {
@@ -36,21 +36,22 @@
36
36
  }
37
37
  },
38
38
  "peerDependencies": {
39
- "@deepseek-ai/cordis": "^4.0.2",
40
- "@deepseek-ai/dsh-attachment": "0.1.5-rc.2",
41
- "@deepseek-ai/dsh-client-locale": "0.1.5-rc.2",
42
- "@deepseek-ai/dsh-client-store": "0.1.5-rc.2",
43
- "@deepseek-ai/dsh-client-ui-primitives": "0.1.5-rc.2",
44
- "@deepseek-ai/dsh-client-ui-renderer": "0.1.5-rc.2",
45
- "@deepseek-ai/dsh-client-ui-settings": "0.1.5-rc.2",
46
- "@deepseek-ai/dsh-client-ui-settings-plugins": "0.1.5-rc.2",
47
- "@deepseek-ai/dsh-client-ui-slots": "0.1.5-rc.2",
48
- "@deepseek-ai/dsh-mcp-client": "0.1.5-rc.2",
49
- "@deepseek-ai/dsh-settings": "0.1.5-rc.2",
50
- "@deepseek-ai/dsh-subprocess": "0.1.5-rc.2",
51
- "@deepseek-ai/dsh-system-prompt": "0.1.5-rc.2",
52
- "@deepseek-ai/dsh-timeout": "0.1.5-rc.2",
53
- "@deepseek-ai/dsh-tools": "0.1.5-rc.2",
39
+ "@deepseek-ai/cordis": "^4.0.4",
40
+ "@deepseek-ai/cosmokit": "1.8.5",
41
+ "@deepseek-ai/dsh-attachment": ">=0.2.0-rc.2",
42
+ "@deepseek-ai/dsh-client-locale": ">=0.2.0-rc.2",
43
+ "@deepseek-ai/dsh-client-store": ">=0.2.0-rc.2",
44
+ "@deepseek-ai/dsh-client-ui-primitives": ">=0.2.0-rc.2",
45
+ "@deepseek-ai/dsh-client-ui-renderer": ">=0.2.0-rc.2",
46
+ "@deepseek-ai/dsh-client-ui-settings": ">=0.2.0-rc.2",
47
+ "@deepseek-ai/dsh-client-ui-settings-plugins": ">=0.2.0-rc.2",
48
+ "@deepseek-ai/dsh-client-ui-slots": ">=0.2.0-rc.2",
49
+ "@deepseek-ai/dsh-mcp-client": ">=0.2.0-rc.2",
50
+ "@deepseek-ai/dsh-settings": ">=0.2.0-rc.2",
51
+ "@deepseek-ai/dsh-subprocess": ">=0.2.0-rc.2",
52
+ "@deepseek-ai/dsh-system-prompt": ">=0.2.0-rc.2",
53
+ "@deepseek-ai/dsh-timeout": ">=0.2.0-rc.2",
54
+ "@deepseek-ai/dsh-tools": ">=0.2.0-rc.2",
54
55
  "@deepseek-ai/schemastery": "^3.18.2",
55
56
  "react": "^19.0.0"
56
57
  },
@@ -58,6 +59,9 @@
58
59
  "@deepseek-ai/cordis": {
59
60
  "optional": true
60
61
  },
62
+ "@deepseek-ai/cosmokit": {
63
+ "optional": true
64
+ },
61
65
  "@deepseek-ai/dsh-attachment": {
62
66
  "optional": true
63
67
  },
@@ -102,31 +106,44 @@
102
106
  }
103
107
  },
104
108
  "dependencies": {
105
- "@deepseek-ai/schemastery": "3.18.2",
109
+ "@deepseek-ai/schemastery": "3.18.4",
106
110
  "tslib": "^2.8.1"
107
111
  },
108
112
  "devDependencies": {
109
- "@deepseek-ai/cordis": "4.0.2",
110
- "@deepseek-ai/dsh-agent": "0.1.5-rc.2",
111
- "@deepseek-ai/dsh-attachment": "0.1.5-rc.2",
112
- "@deepseek-ai/dsh-client-locale": "0.1.5-rc.2",
113
- "@deepseek-ai/dsh-client-store": "0.1.5-rc.2",
114
- "@deepseek-ai/dsh-client-ui-primitives": "0.1.5-rc.2",
115
- "@deepseek-ai/dsh-client-ui-renderer": "0.1.5-rc.2",
116
- "@deepseek-ai/dsh-client-ui-settings": "0.1.5-rc.2",
117
- "@deepseek-ai/dsh-client-ui-settings-plugins": "0.1.5-rc.2",
118
- "@deepseek-ai/dsh-client-ui-slots": "0.1.5-rc.2",
119
- "@deepseek-ai/dsh-http-proxy": "0.1.5-rc.2",
120
- "@deepseek-ai/dsh-llm": "0.1.5-rc.2",
121
- "@deepseek-ai/dsh-mcp-client": "0.1.5-rc.2",
122
- "@deepseek-ai/dsh-scope": "0.1.5-rc.2",
123
- "@deepseek-ai/dsh-session": "0.1.5-rc.2",
124
- "@deepseek-ai/dsh-settings": "0.1.5-rc.2",
125
- "@deepseek-ai/dsh-subprocess": "0.1.5-rc.2",
126
- "@deepseek-ai/dsh-system-prompt": "0.1.5-rc.2",
127
- "@deepseek-ai/dsh-timeout": "0.1.5-rc.2",
128
- "@deepseek-ai/dsh-tools": "0.1.5-rc.2",
129
- "@deepseek-ai/schemastery": "3.18.2",
113
+ "@deepseek-ai/cordis": "4.0.4",
114
+ "@deepseek-ai/cordis-plugin-loader": "1.0.5",
115
+ "@deepseek-ai/cosmokit": "1.8.5",
116
+ "@deepseek-ai/dsh-agent": "0.2.0-rc.2",
117
+ "@deepseek-ai/dsh-attachment": "0.2.0-rc.2",
118
+ "@deepseek-ai/dsh-client-locale": "0.2.0-rc.2",
119
+ "@deepseek-ai/dsh-client-store": "0.2.0-rc.2",
120
+ "@deepseek-ai/dsh-client-ui-primitives": "0.2.0-rc.2",
121
+ "@deepseek-ai/dsh-client-ui-renderer": "0.2.0-rc.2",
122
+ "@deepseek-ai/dsh-client-ui-settings": "0.2.0-rc.2",
123
+ "@deepseek-ai/dsh-client-ui-settings-plugins": "0.2.0-rc.2",
124
+ "@deepseek-ai/dsh-client-ui-slots": "0.2.0-rc.2",
125
+ "@deepseek-ai/dsh-config-editor": "0.2.0-rc.2",
126
+ "@deepseek-ai/dsh-http-proxy": "0.2.0-rc.2",
127
+ "@deepseek-ai/dsh-invariants": "0.2.0-rc.2",
128
+ "@deepseek-ai/dsh-llm": "0.2.0-rc.2",
129
+ "@deepseek-ai/dsh-mcp-client": "0.2.0-rc.2",
130
+ "@deepseek-ai/dsh-mcp-resources": "0.2.0-rc.2",
131
+ "@deepseek-ai/dsh-ptc-runtime": "0.2.0-rc.2",
132
+ "@deepseek-ai/dsh-sandbox": "0.2.0-rc.2",
133
+ "@deepseek-ai/dsh-sandbox-policy": "0.2.0-rc.2",
134
+ "@deepseek-ai/dsh-scope": "0.2.0-rc.2",
135
+ "@deepseek-ai/dsh-session": "0.2.0-rc.2",
136
+ "@deepseek-ai/dsh-session-projection": "0.2.0-rc.2",
137
+ "@deepseek-ai/dsh-settings": "0.2.0-rc.2",
138
+ "@deepseek-ai/dsh-subprocess": "0.2.0-rc.2",
139
+ "@deepseek-ai/dsh-system-prompt": "0.2.0-rc.2",
140
+ "@deepseek-ai/dsh-timeout": "0.2.0-rc.2",
141
+ "@deepseek-ai/dsh-tools": "0.2.0-rc.2",
142
+ "@deepseek-ai/dsh-typert-protocol": "0.2.0-rc.2",
143
+ "@deepseek-ai/dsh-user-approval": "0.2.0-rc.2",
144
+ "@deepseek-ai/dsh-util-crypto": "0.2.0-rc.2",
145
+ "@deepseek-ai/dsh-workspace": "0.2.0-rc.2",
146
+ "@deepseek-ai/schemastery": "3.18.4",
130
147
  "@types/react": "^19.1.13",
131
148
  "clsx": "^2.1.1",
132
149
  "esbuild": "^0.25.12",
@@ -134,5 +151,5 @@
134
151
  "react": "^19.1.1",
135
152
  "zustand": "~4.4.7"
136
153
  },
137
- "module": "./src/dsh/index.js"
138
- }
154
+ "module": "./tools/agent-plugin/src/dsh/index.js"
155
+ }
@@ -185,7 +185,11 @@ ${auth.apiKey}`;
185
185
  }, 50);
186
186
  };
187
187
  ctx.inject(["settings"], (scoped) => {
188
- current = () => pluginConfigFromSettings(scoped.settings.get(SETTINGS_NAMESPACE), config);
188
+ const readSection = () => {
189
+ const descriptor = scoped.settings.describe().find((candidate) => String(candidate.ns) === SETTINGS_NAMESPACE);
190
+ return pluginConfigFromSettings(descriptor?.value, config);
191
+ };
192
+ current = readSection;
189
193
  ctx.on("settings/document-updated", (namespace) => {
190
194
  if (String(namespace) === SETTINGS_NAMESPACE) {
191
195
  scheduleRemountSoon();
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../../tools/agent-plugin/src/dsh/mcp.ts", "../../../../../../../tools/agent-plugin/src/dsh/auth.ts", "../../../../../../../tools/agent-plugin/src/dsh/tool-name.ts"],
4
- "sourcesContent": ["import { createRequire } from 'node:module'\nimport { Context, Fiber } from '@deepseek-ai/cordis'\nimport { StreamableHttpConfig } from '@deepseek-ai/dsh-mcp-client'\nimport {} from '@deepseek-ai/dsh-settings'\nimport {} from '@deepseek-ai/dsh-settings/types'\nimport {} from '@deepseek-ai/dsh-tools'\nimport { AitoearnPluginConfig, authorizationHeader, pluginConfigFromSettings, resolveAuth, SETTINGS_NAMESPACE } from './auth.js'\nimport { MCP_SERVER_NAME, patchRawToolNames } from './tool-name.js'\n\nconst runtimeRequire = createRequire(import.meta.url)\n\nexport const name = 'aitoearn-mcp'\nexport const inject = ['tools']\n\nexport async function apply(ctx: Context, config: AitoearnPluginConfig = {}): Promise<void> {\n let current = () => config\n let restoreNames: (() => void) | undefined\n let fiber: Fiber | undefined\n let generation = 0\n let mountChain: Promise<void> = Promise.resolve()\n let remountTimer: ReturnType<typeof setTimeout> | undefined\n let mountedFingerprint: string | undefined\n\n const unmountAsync = async () => {\n restoreNames?.()\n restoreNames = undefined\n const previous = fiber\n fiber = undefined\n if (previous) {\n try {\n await previous.dispose()\n }\n catch (error) {\n ctx.logger.warn(error, 'aitoearn-mcp: failed to dispose previous MCP client')\n }\n }\n }\n\n const doMount = async (gen: number) => {\n const auth = resolveAuth(current())\n if (auth.apiKey.length === 0 || auth.mcpUrl.length === 0) {\n await unmountAsync()\n mountedFingerprint = undefined\n ctx.logger.warn('aitoearn-mcp: skip mounting; API key or MCP URL is not configured yet')\n return\n }\n const fingerprint = `${auth.mcpUrl}\\n${auth.apiKey}`\n if (fingerprint === mountedFingerprint && fiber) {\n return\n }\n await unmountAsync()\n if (gen !== generation) {\n return\n }\n restoreNames = patchRawToolNames(ctx.tools, MCP_SERVER_NAME, (publicName) => {\n ctx.logger.info(`kept qualified MCP tool name ${publicName}`)\n })\n try {\n const mcpClient: typeof import('@deepseek-ai/dsh-mcp-client') = runtimeRequire('@deepseek-ai/dsh-mcp-client')\n const mcpConfig: StreamableHttpConfig = {\n serverName: MCP_SERVER_NAME,\n transport: 'streamable-http',\n url: auth.mcpUrl,\n headers: authorizationHeader(auth.apiKey),\n failOnStartupError: false,\n toolCallTimeoutMs: 120000,\n }\n const next = ctx.plugin(mcpClient, mcpConfig)\n fiber = next\n await next\n }\n catch (error) {\n restoreNames?.()\n restoreNames = undefined\n fiber = undefined\n ctx.logger.warn(error, 'aitoearn-mcp: mount failed; will retry on next settings change')\n return\n }\n if (gen !== generation) {\n await unmountAsync()\n mountedFingerprint = undefined\n return\n }\n mountedFingerprint = fingerprint\n ctx.logger.info(`aitoearn-mcp: mounted MCP tools from ${auth.mcpUrl}`)\n }\n\n const scheduleMount = () => {\n generation += 1\n const gen = generation\n mountChain = mountChain\n .then(() => doMount(gen))\n .catch((error: Error) => {\n ctx.logger.warn(error, 'aitoearn-mcp: mount failed')\n })\n return mountChain\n }\n\n const scheduleRemountSoon = () => {\n if (remountTimer) {\n clearTimeout(remountTimer)\n }\n remountTimer = setTimeout(() => {\n remountTimer = undefined\n void scheduleMount()\n }, 50)\n }\n\n ctx.inject(['settings'], (scoped) => {\n current = () => pluginConfigFromSettings(scoped.settings.get(SETTINGS_NAMESPACE), config)\n ctx.on('settings/document-updated', (namespace) => {\n if (String(namespace) === SETTINGS_NAMESPACE) {\n scheduleRemountSoon()\n }\n })\n // The initial apply-time mount may run before the settings section is\n // readable; mount again once it is, so a stored key takes effect without\n // requiring a manual settings save.\n void scheduleMount()\n })\n\n ctx.effect(() => () => {\n if (remountTimer) {\n clearTimeout(remountTimer)\n remountTimer = undefined\n }\n void unmountAsync()\n }, 'aitoearn-mcp.client')\n await scheduleMount()\n}\n", "export const MCP_PATH = '/api/ai/agent/mcp'\nexport const API_KEY_ENV = 'AITOEARN_API_KEY'\nexport const DEFAULT_ENVIRONMENT = 'global'\nexport const SETTINGS_NAMESPACE = 'aitoearn'\n\nexport const ENVIRONMENT_ORIGINS = {\n global: 'https://aitoearn.ai',\n cn: 'https://aitoearn.cn',\n} as const\n\nexport const DEFAULT_MCP_URL = `${ENVIRONMENT_ORIGINS.global}${MCP_PATH}`\n\nexport type AitoearnEnvironment = 'global' | 'cn' | 'custom'\n\nexport interface AitoearnAuth {\n mcpUrl: string\n apiKey: string\n}\n\nexport interface AitoearnPluginConfig {\n environment?: string\n baseUrl?: string\n apiKey?: string\n}\n\nexport function pluginConfigFromSettings(\n section: unknown,\n fallback: AitoearnPluginConfig = {},\n): AitoearnPluginConfig {\n if (section === null || typeof section !== 'object' || Array.isArray(section))\n return fallback\n const record = section as Record<string, unknown>\n return {\n ...fallback,\n ...(typeof record['environment'] === 'string' ? { environment: record['environment'] } : {}),\n ...(typeof record['baseUrl'] === 'string' ? { baseUrl: record['baseUrl'] } : {}),\n ...(typeof record['apiKey'] === 'string' ? { apiKey: record['apiKey'] } : {}),\n }\n}\n\nexport function resolveEnvironment(value: string | undefined): AitoearnEnvironment {\n if (value === 'cn' || value === 'custom' || value === 'global')\n return value\n return DEFAULT_ENVIRONMENT\n}\n\nexport function resolveOrigin(environment: AitoearnEnvironment, baseUrl?: string): string {\n if (environment !== 'custom')\n return ENVIRONMENT_ORIGINS[environment]\n const trimmed = baseUrl?.trim() ?? ''\n if (trimmed.length === 0)\n return ''\n try {\n const url = new URL(trimmed)\n if (url.protocol !== 'http:' && url.protocol !== 'https:')\n return ''\n return url.origin\n }\n catch {\n return ''\n }\n}\n\nexport function resolveMcpUrl(config: AitoearnPluginConfig): string {\n const environment = resolveEnvironment(config.environment)\n const origin = resolveOrigin(environment, config.baseUrl)\n if (origin.length === 0)\n return ''\n return `${origin}${MCP_PATH}`\n}\n\nexport function resolveAuth(\n config: AitoearnPluginConfig,\n env: NodeJS.ProcessEnv = process.env,\n): AitoearnAuth {\n return {\n mcpUrl: resolveMcpUrl(config),\n apiKey: config.apiKey?.trim() || env[API_KEY_ENV]?.trim() || '',\n }\n}\n\nexport function authorizationHeader(apiKey: string): Record<string, string> {\n if (apiKey.length === 0)\n return {}\n return { Authorization: `Bearer ${apiKey}` }\n}\n", "import { ToolRuntime } from '@deepseek-ai/dsh-tools'\n\nexport const MCP_SERVER_NAME = 'aitoearn'\n\nconst HASHED_PUBLIC_NAME = /_[0-9a-f]{12}$/\n\nexport interface RawPublicName {\n modelName: string\n stripped: boolean\n}\n\nexport function qualifiedPrefix(serverName = MCP_SERVER_NAME): string {\n return `mcp__${serverName}__`\n}\n\nexport function toRawPublicName(publicName: string, serverName = MCP_SERVER_NAME): RawPublicName {\n const prefix = qualifiedPrefix(serverName)\n if (!publicName.startsWith(prefix))\n return { modelName: publicName, stripped: false }\n if (publicName.length === 64 && HASHED_PUBLIC_NAME.test(publicName))\n return { modelName: publicName, stripped: false }\n const raw = publicName.slice(prefix.length)\n if (raw.length === 0)\n return { modelName: publicName, stripped: false }\n return { modelName: raw, stripped: true }\n}\n\nexport function patchRawToolNames(\n tools: Pick<ToolRuntime, 'register'>,\n serverName = MCP_SERVER_NAME,\n onKeepQualified?: (publicName: string) => void,\n): () => void {\n const original = tools.register.bind(tools)\n tools.register = (definition) => {\n const next = toRawPublicName(definition.name, serverName)\n if (!next.stripped) {\n if (definition.name.startsWith(qualifiedPrefix(serverName)))\n onKeepQualified?.(definition.name)\n return original(definition)\n }\n return original({ ...definition, name: next.modelName })\n }\n return () => {\n tools.register = original\n }\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { createRequire } from 'node:module'\nimport { Context, Fiber } from '@deepseek-ai/cordis'\nimport { StreamableHttpConfig } from '@deepseek-ai/dsh-mcp-client'\nimport {} from '@deepseek-ai/dsh-settings'\nimport {} from '@deepseek-ai/dsh-settings/types'\nimport {} from '@deepseek-ai/dsh-tools'\nimport { AitoearnPluginConfig, authorizationHeader, pluginConfigFromSettings, resolveAuth, SETTINGS_NAMESPACE } from './auth.js'\nimport { MCP_SERVER_NAME, patchRawToolNames } from './tool-name.js'\n\nconst runtimeRequire = createRequire(import.meta.url)\n\nexport const name = 'aitoearn-mcp'\nexport const inject = ['tools']\n\nexport async function apply(ctx: Context, config: AitoearnPluginConfig = {}): Promise<void> {\n let current = () => config\n let restoreNames: (() => void) | undefined\n let fiber: Fiber | undefined\n let generation = 0\n let mountChain: Promise<void> = Promise.resolve()\n let remountTimer: ReturnType<typeof setTimeout> | undefined\n let mountedFingerprint: string | undefined\n\n const unmountAsync = async () => {\n restoreNames?.()\n restoreNames = undefined\n const previous = fiber\n fiber = undefined\n if (previous) {\n try {\n await previous.dispose()\n }\n catch (error) {\n ctx.logger.warn(error, 'aitoearn-mcp: failed to dispose previous MCP client')\n }\n }\n }\n\n const doMount = async (gen: number) => {\n const auth = resolveAuth(current())\n if (auth.apiKey.length === 0 || auth.mcpUrl.length === 0) {\n await unmountAsync()\n mountedFingerprint = undefined\n ctx.logger.warn('aitoearn-mcp: skip mounting; API key or MCP URL is not configured yet')\n return\n }\n const fingerprint = `${auth.mcpUrl}\\n${auth.apiKey}`\n if (fingerprint === mountedFingerprint && fiber) {\n return\n }\n await unmountAsync()\n if (gen !== generation) {\n return\n }\n restoreNames = patchRawToolNames(ctx.tools, MCP_SERVER_NAME, (publicName) => {\n ctx.logger.info(`kept qualified MCP tool name ${publicName}`)\n })\n try {\n const mcpClient: typeof import('@deepseek-ai/dsh-mcp-client') = runtimeRequire('@deepseek-ai/dsh-mcp-client')\n const mcpConfig: StreamableHttpConfig = {\n serverName: MCP_SERVER_NAME,\n transport: 'streamable-http',\n url: auth.mcpUrl,\n headers: authorizationHeader(auth.apiKey),\n failOnStartupError: false,\n toolCallTimeoutMs: 120000,\n }\n const next = ctx.plugin(mcpClient, mcpConfig)\n fiber = next\n await next\n }\n catch (error) {\n restoreNames?.()\n restoreNames = undefined\n fiber = undefined\n ctx.logger.warn(error, 'aitoearn-mcp: mount failed; will retry on next settings change')\n return\n }\n if (gen !== generation) {\n await unmountAsync()\n mountedFingerprint = undefined\n return\n }\n mountedFingerprint = fingerprint\n ctx.logger.info(`aitoearn-mcp: mounted MCP tools from ${auth.mcpUrl}`)\n }\n\n const scheduleMount = () => {\n generation += 1\n const gen = generation\n mountChain = mountChain\n .then(() => doMount(gen))\n .catch((error: Error) => {\n ctx.logger.warn(error, 'aitoearn-mcp: mount failed')\n })\n return mountChain\n }\n\n const scheduleRemountSoon = () => {\n if (remountTimer) {\n clearTimeout(remountTimer)\n }\n remountTimer = setTimeout(() => {\n remountTimer = undefined\n void scheduleMount()\n }, 50)\n }\n\n ctx.inject(['settings'], (scoped) => {\n // Host `describe()` serves the live value unredacted by default, so the\n // preset can read the stored key; remote callers get the redacted view.\n const readSection = (): AitoearnPluginConfig => {\n const descriptor = scoped.settings.describe().find(candidate => String(candidate.ns) === SETTINGS_NAMESPACE)\n return pluginConfigFromSettings(descriptor?.value, config)\n }\n current = readSection\n ctx.on('settings/document-updated', (namespace) => {\n if (String(namespace) === SETTINGS_NAMESPACE) {\n scheduleRemountSoon()\n }\n })\n // The initial apply-time mount may run before the settings section is\n // readable; mount again once it is, so a stored key takes effect without\n // requiring a manual settings save.\n void scheduleMount()\n })\n\n ctx.effect(() => () => {\n if (remountTimer) {\n clearTimeout(remountTimer)\n remountTimer = undefined\n }\n void unmountAsync()\n }, 'aitoearn-mcp.client')\n await scheduleMount()\n}\n", "export const MCP_PATH = '/api/ai/agent/mcp'\nexport const API_KEY_ENV = 'AITOEARN_API_KEY'\nexport const DEFAULT_ENVIRONMENT = 'global'\nexport const SETTINGS_NAMESPACE = 'aitoearn'\n\nexport const ENVIRONMENT_ORIGINS = {\n global: 'https://aitoearn.ai',\n cn: 'https://aitoearn.cn',\n} as const\n\nexport const DEFAULT_MCP_URL = `${ENVIRONMENT_ORIGINS.global}${MCP_PATH}`\n\nexport type AitoearnEnvironment = 'global' | 'cn' | 'custom'\n\nexport interface AitoearnAuth {\n mcpUrl: string\n apiKey: string\n}\n\nexport interface AitoearnPluginConfig {\n environment?: string\n baseUrl?: string\n apiKey?: string\n}\n\nexport function pluginConfigFromSettings(\n section: unknown,\n fallback: AitoearnPluginConfig = {},\n): AitoearnPluginConfig {\n if (section === null || typeof section !== 'object' || Array.isArray(section))\n return fallback\n const record = section as Record<string, unknown>\n return {\n ...fallback,\n ...(typeof record['environment'] === 'string' ? { environment: record['environment'] } : {}),\n ...(typeof record['baseUrl'] === 'string' ? { baseUrl: record['baseUrl'] } : {}),\n ...(typeof record['apiKey'] === 'string' ? { apiKey: record['apiKey'] } : {}),\n }\n}\n\nexport function resolveEnvironment(value: string | undefined): AitoearnEnvironment {\n if (value === 'cn' || value === 'custom' || value === 'global')\n return value\n return DEFAULT_ENVIRONMENT\n}\n\nexport function resolveOrigin(environment: AitoearnEnvironment, baseUrl?: string): string {\n if (environment !== 'custom')\n return ENVIRONMENT_ORIGINS[environment]\n const trimmed = baseUrl?.trim() ?? ''\n if (trimmed.length === 0)\n return ''\n try {\n const url = new URL(trimmed)\n if (url.protocol !== 'http:' && url.protocol !== 'https:')\n return ''\n return url.origin\n }\n catch {\n return ''\n }\n}\n\nexport function resolveMcpUrl(config: AitoearnPluginConfig): string {\n const environment = resolveEnvironment(config.environment)\n const origin = resolveOrigin(environment, config.baseUrl)\n if (origin.length === 0)\n return ''\n return `${origin}${MCP_PATH}`\n}\n\nexport function resolveAuth(\n config: AitoearnPluginConfig,\n env: NodeJS.ProcessEnv = process.env,\n): AitoearnAuth {\n return {\n mcpUrl: resolveMcpUrl(config),\n apiKey: config.apiKey?.trim() || env[API_KEY_ENV]?.trim() || '',\n }\n}\n\nexport function authorizationHeader(apiKey: string): Record<string, string> {\n if (apiKey.length === 0)\n return {}\n return { Authorization: `Bearer ${apiKey}` }\n}\n", "import { ToolRuntime } from '@deepseek-ai/dsh-tools'\n\nexport const MCP_SERVER_NAME = 'aitoearn'\n\nconst HASHED_PUBLIC_NAME = /_[0-9a-f]{12}$/\n\nexport interface RawPublicName {\n modelName: string\n stripped: boolean\n}\n\nexport function qualifiedPrefix(serverName = MCP_SERVER_NAME): string {\n return `mcp__${serverName}__`\n}\n\nexport function toRawPublicName(publicName: string, serverName = MCP_SERVER_NAME): RawPublicName {\n const prefix = qualifiedPrefix(serverName)\n if (!publicName.startsWith(prefix))\n return { modelName: publicName, stripped: false }\n if (publicName.length === 64 && HASHED_PUBLIC_NAME.test(publicName))\n return { modelName: publicName, stripped: false }\n const raw = publicName.slice(prefix.length)\n if (raw.length === 0)\n return { modelName: publicName, stripped: false }\n return { modelName: raw, stripped: true }\n}\n\nexport function patchRawToolNames(\n tools: Pick<ToolRuntime, 'register'>,\n serverName = MCP_SERVER_NAME,\n onKeepQualified?: (publicName: string) => void,\n): () => void {\n const original = tools.register.bind(tools)\n tools.register = (definition) => {\n const next = toRawPublicName(definition.name, serverName)\n if (!next.stripped) {\n if (definition.name.startsWith(qualifiedPrefix(serverName)))\n onKeepQualified?.(definition.name)\n return original(definition)\n }\n return original({ ...definition, name: next.modelName })\n }\n return () => {\n tools.register = original\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -4,19 +4,20 @@
4
4
  "version": "0.0.1",
5
5
  "private": true,
6
6
  "dependencies": {
7
- "@deepseek-ai/cordis": "4.0.2",
8
- "@deepseek-ai/dsh-client-locale": "0.1.5-rc.2",
9
- "@deepseek-ai/dsh-client-store": "0.1.5-rc.2",
10
- "@deepseek-ai/dsh-client-ui-primitives": "0.1.5-rc.2",
11
- "@deepseek-ai/dsh-client-ui-renderer": "0.1.5-rc.2",
12
- "@deepseek-ai/dsh-client-ui-settings": "0.1.5-rc.2",
13
- "@deepseek-ai/dsh-client-ui-settings-plugins": "0.1.5-rc.2",
14
- "@deepseek-ai/dsh-client-ui-slots": "0.1.5-rc.2",
15
- "@deepseek-ai/dsh-mcp-client": "0.1.5-rc.2",
16
- "@deepseek-ai/dsh-settings": "0.1.5-rc.2",
17
- "@deepseek-ai/dsh-system-prompt": "0.1.5-rc.2",
18
- "@deepseek-ai/dsh-tools": "0.1.5-rc.2",
19
- "@deepseek-ai/schemastery": "3.18.2",
7
+ "@deepseek-ai/cordis": "4.0.4",
8
+ "@deepseek-ai/cosmokit": "1.8.5",
9
+ "@deepseek-ai/dsh-client-locale": "0.2.0-rc.2",
10
+ "@deepseek-ai/dsh-client-store": "0.2.0-rc.2",
11
+ "@deepseek-ai/dsh-client-ui-primitives": "0.2.0-rc.2",
12
+ "@deepseek-ai/dsh-client-ui-renderer": "0.2.0-rc.2",
13
+ "@deepseek-ai/dsh-client-ui-settings": "0.2.0-rc.2",
14
+ "@deepseek-ai/dsh-client-ui-settings-plugins": "0.2.0-rc.2",
15
+ "@deepseek-ai/dsh-client-ui-slots": "0.2.0-rc.2",
16
+ "@deepseek-ai/dsh-mcp-client": "0.2.0-rc.2",
17
+ "@deepseek-ai/dsh-settings": "0.2.0-rc.2",
18
+ "@deepseek-ai/dsh-system-prompt": "0.2.0-rc.2",
19
+ "@deepseek-ai/dsh-tools": "0.2.0-rc.2",
20
+ "@deepseek-ai/schemastery": "3.18.4",
20
21
  "react": "19.3.0"
21
22
  }
22
23
  }