aitoearn-dsh-plugin-test 0.0.2 → 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.
- package/lib/client.js +34 -36
- package/lib/client.js.map +2 -2
- package/package.json +57 -40
- package/presets/aitoearn/lib/mcp.js +85 -21
- package/presets/aitoearn/lib/mcp.js.map +2 -2
- package/presets/aitoearn/package.json +14 -13
- package/skills/cloudedit/SKILL.md +113 -0
- package/skills/cloudedit/references/amk-scenarios/edit-asr.md +160 -0
- package/skills/cloudedit/references/edit-position.md +64 -0
- package/skills/cloudedit/references/edit-project.md +192 -0
- package/skills/cloudedit/references/edit-quality-gate.md +136 -0
- package/skills/cloudedit/references/edit-shader.md +114 -0
- package/skills/cloudedit/references/edit-text.md +227 -0
- package/skills/cloudedit/references/edit-timeline.md +29 -0
- package/skills/cloudedit-planner/SKILL.md +102 -0
- package/skills/cloudedit-planner/evals/evals.json +80 -0
- package/skills/cloudedit-planner/references/editing-plan.md +63 -0
- package/skills/cloudedit-planner/references/executable-handoff.md +25 -0
- package/skills/cloudedit-planner/references/media-evidence-models.md +32 -0
- package/skills/cloudedit-planner/references/media-understanding.md +25 -0
- package/skills/cloudedit-planner/references/processing-and-lineage.md +22 -0
- package/skills/cloudedit-planner/references/subtitle-timing.md +50 -0
- package/src/dsh/client/AitoearnCard.js +2 -2
- package/src/dsh/client/AitoearnCard.js.map +1 -1
- package/src/dsh/client/card-store.d.ts +2 -2
- package/src/dsh/client/card-store.js +18 -9
- package/src/dsh/client/card-store.js.map +1 -1
- package/src/dsh/client/index.js +15 -13
- package/src/dsh/client/index.js.map +1 -1
- package/src/dsh/index.d.ts +2 -1
- package/src/dsh/index.js +4 -6
- package/src/dsh/index.js.map +1 -1
- package/src/dsh/mcp.js +90 -21
- package/src/dsh/mcp.js.map +1 -1
- package/src/dsh/settings-schema.d.ts +16 -12
- package/src/dsh/settings-schema.js +8 -10
- 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.
|
|
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(
|
|
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
|
|
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 =
|
|
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 =
|
|
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
|
|
321
|
+
accepted = await form.set("environment", environment) && accepted;
|
|
332
322
|
if (writes.includes("apiKey"))
|
|
333
|
-
await
|
|
323
|
+
accepted = await form.set("apiKey", apiKey) && accepted;
|
|
334
324
|
if (writes.includes("baseUrl")) {
|
|
335
325
|
if (environment === "custom")
|
|
336
|
-
await
|
|
326
|
+
accepted = await form.set("baseUrl", baseUrl) && accepted;
|
|
337
327
|
else
|
|
338
|
-
await
|
|
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
|
-
|
|
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", "
|
|
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
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
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;
|
|
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,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "aitoearn-dsh-plugin-test",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.0.
|
|
5
|
-
"description": "
|
|
4
|
+
"version": "0.0.4",
|
|
5
|
+
"description": "Aitoearn agent preset, skills, and MCP tools for DeepSeek Harness",
|
|
6
6
|
"exports": {
|
|
7
7
|
".": {
|
|
8
8
|
"types": "./src/dsh/index.d.ts",
|
|
@@ -36,21 +36,22 @@
|
|
|
36
36
|
}
|
|
37
37
|
},
|
|
38
38
|
"peerDependencies": {
|
|
39
|
-
"@deepseek-ai/cordis": "^4.0.
|
|
40
|
-
"@deepseek-ai/
|
|
41
|
-
"@deepseek-ai/dsh-
|
|
42
|
-
"@deepseek-ai/dsh-client-
|
|
43
|
-
"@deepseek-ai/dsh-client-
|
|
44
|
-
"@deepseek-ai/dsh-client-ui-
|
|
45
|
-
"@deepseek-ai/dsh-client-ui-
|
|
46
|
-
"@deepseek-ai/dsh-client-ui-settings
|
|
47
|
-
"@deepseek-ai/dsh-client-ui-
|
|
48
|
-
"@deepseek-ai/dsh-
|
|
49
|
-
"@deepseek-ai/dsh-
|
|
50
|
-
"@deepseek-ai/dsh-
|
|
51
|
-
"@deepseek-ai/dsh-
|
|
52
|
-
"@deepseek-ai/dsh-
|
|
53
|
-
"@deepseek-ai/dsh-
|
|
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.
|
|
109
|
+
"@deepseek-ai/schemastery": "3.18.4",
|
|
106
110
|
"tslib": "^2.8.1"
|
|
107
111
|
},
|
|
108
112
|
"devDependencies": {
|
|
109
|
-
"@deepseek-ai/cordis": "4.0.
|
|
110
|
-
"@deepseek-ai/
|
|
111
|
-
"@deepseek-ai/
|
|
112
|
-
"@deepseek-ai/dsh-
|
|
113
|
-
"@deepseek-ai/dsh-
|
|
114
|
-
"@deepseek-ai/dsh-client-
|
|
115
|
-
"@deepseek-ai/dsh-client-
|
|
116
|
-
"@deepseek-ai/dsh-client-ui-
|
|
117
|
-
"@deepseek-ai/dsh-client-ui-
|
|
118
|
-
"@deepseek-ai/dsh-client-ui-
|
|
119
|
-
"@deepseek-ai/dsh-
|
|
120
|
-
"@deepseek-ai/dsh-
|
|
121
|
-
"@deepseek-ai/dsh-
|
|
122
|
-
"@deepseek-ai/dsh-
|
|
123
|
-
"@deepseek-ai/dsh-
|
|
124
|
-
"@deepseek-ai/dsh-
|
|
125
|
-
"@deepseek-ai/dsh-
|
|
126
|
-
"@deepseek-ai/dsh-
|
|
127
|
-
"@deepseek-ai/dsh-
|
|
128
|
-
"@deepseek-ai/dsh-
|
|
129
|
-
"@deepseek-ai/
|
|
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"
|
|
154
|
+
"module": "./tools/agent-plugin/src/dsh/index.js"
|
|
138
155
|
}
|
|
@@ -102,45 +102,109 @@ async function apply(ctx, config = {}) {
|
|
|
102
102
|
let current = () => config;
|
|
103
103
|
let restoreNames;
|
|
104
104
|
let fiber;
|
|
105
|
-
|
|
105
|
+
let generation = 0;
|
|
106
|
+
let mountChain = Promise.resolve();
|
|
107
|
+
let remountTimer;
|
|
108
|
+
let mountedFingerprint;
|
|
109
|
+
const unmountAsync = async () => {
|
|
106
110
|
restoreNames?.();
|
|
107
111
|
restoreNames = void 0;
|
|
108
|
-
|
|
112
|
+
const previous = fiber;
|
|
109
113
|
fiber = void 0;
|
|
114
|
+
if (previous) {
|
|
115
|
+
try {
|
|
116
|
+
await previous.dispose();
|
|
117
|
+
} catch (error) {
|
|
118
|
+
ctx.logger.warn(error, "aitoearn-mcp: failed to dispose previous MCP client");
|
|
119
|
+
}
|
|
120
|
+
}
|
|
110
121
|
};
|
|
111
|
-
const
|
|
112
|
-
unmount();
|
|
122
|
+
const doMount = async (gen) => {
|
|
113
123
|
const auth = resolveAuth(current());
|
|
114
124
|
if (auth.apiKey.length === 0 || auth.mcpUrl.length === 0) {
|
|
125
|
+
await unmountAsync();
|
|
126
|
+
mountedFingerprint = void 0;
|
|
115
127
|
ctx.logger.warn("aitoearn-mcp: skip mounting; API key or MCP URL is not configured yet");
|
|
116
128
|
return;
|
|
117
129
|
}
|
|
130
|
+
const fingerprint = `${auth.mcpUrl}
|
|
131
|
+
${auth.apiKey}`;
|
|
132
|
+
if (fingerprint === mountedFingerprint && fiber) {
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
await unmountAsync();
|
|
136
|
+
if (gen !== generation) {
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
118
139
|
restoreNames = patchRawToolNames(ctx.tools, MCP_SERVER_NAME, (publicName) => {
|
|
119
140
|
ctx.logger.info(`kept qualified MCP tool name ${publicName}`);
|
|
120
141
|
});
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
142
|
+
try {
|
|
143
|
+
const mcpClient = runtimeRequire("@deepseek-ai/dsh-mcp-client");
|
|
144
|
+
const mcpConfig = {
|
|
145
|
+
serverName: MCP_SERVER_NAME,
|
|
146
|
+
transport: "streamable-http",
|
|
147
|
+
url: auth.mcpUrl,
|
|
148
|
+
headers: authorizationHeader(auth.apiKey),
|
|
149
|
+
failOnStartupError: false,
|
|
150
|
+
toolCallTimeoutMs: 12e4
|
|
151
|
+
};
|
|
152
|
+
const next = ctx.plugin(mcpClient, mcpConfig);
|
|
153
|
+
fiber = next;
|
|
154
|
+
await next;
|
|
155
|
+
} catch (error) {
|
|
156
|
+
restoreNames?.();
|
|
157
|
+
restoreNames = void 0;
|
|
158
|
+
fiber = void 0;
|
|
159
|
+
ctx.logger.warn(error, "aitoearn-mcp: mount failed; will retry on next settings change");
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
if (gen !== generation) {
|
|
163
|
+
await unmountAsync();
|
|
164
|
+
mountedFingerprint = void 0;
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
mountedFingerprint = fingerprint;
|
|
132
168
|
ctx.logger.info(`aitoearn-mcp: mounted MCP tools from ${auth.mcpUrl}`);
|
|
133
169
|
};
|
|
170
|
+
const scheduleMount = () => {
|
|
171
|
+
generation += 1;
|
|
172
|
+
const gen = generation;
|
|
173
|
+
mountChain = mountChain.then(() => doMount(gen)).catch((error) => {
|
|
174
|
+
ctx.logger.warn(error, "aitoearn-mcp: mount failed");
|
|
175
|
+
});
|
|
176
|
+
return mountChain;
|
|
177
|
+
};
|
|
178
|
+
const scheduleRemountSoon = () => {
|
|
179
|
+
if (remountTimer) {
|
|
180
|
+
clearTimeout(remountTimer);
|
|
181
|
+
}
|
|
182
|
+
remountTimer = setTimeout(() => {
|
|
183
|
+
remountTimer = void 0;
|
|
184
|
+
void scheduleMount();
|
|
185
|
+
}, 50);
|
|
186
|
+
};
|
|
134
187
|
ctx.inject(["settings"], (scoped) => {
|
|
135
|
-
|
|
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;
|
|
136
193
|
ctx.on("settings/document-updated", (namespace) => {
|
|
137
|
-
if (String(namespace) === SETTINGS_NAMESPACE)
|
|
138
|
-
|
|
194
|
+
if (String(namespace) === SETTINGS_NAMESPACE) {
|
|
195
|
+
scheduleRemountSoon();
|
|
196
|
+
}
|
|
139
197
|
});
|
|
140
|
-
void
|
|
198
|
+
void scheduleMount();
|
|
141
199
|
});
|
|
142
|
-
ctx.effect(() =>
|
|
143
|
-
|
|
200
|
+
ctx.effect(() => () => {
|
|
201
|
+
if (remountTimer) {
|
|
202
|
+
clearTimeout(remountTimer);
|
|
203
|
+
remountTimer = void 0;
|
|
204
|
+
}
|
|
205
|
+
void unmountAsync();
|
|
206
|
+
}, "aitoearn-mcp.client");
|
|
207
|
+
await scheduleMount();
|
|
144
208
|
}
|
|
145
209
|
export {
|
|
146
210
|
apply,
|