@sparkelf/dsh-dataops-managed 0.1.0 → 0.2.0
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/README.md +8 -8
- package/lib/client.js +28 -10
- package/lib/client.js.map +1 -1
- package/lib/index.js +83 -5
- package/lib/types/client/ManagedDataOpsSection.d.ts +1 -1
- package/lib/types/client/locales.d.ts +3 -3
- package/lib/types/index.d.ts +24 -4
- package/package.json +12 -2
package/README.md
CHANGED
|
@@ -2,32 +2,32 @@
|
|
|
2
2
|
|
|
3
3
|
## 中文
|
|
4
4
|
|
|
5
|
-
这是DataOps托管工作区使用的DeepSeek Harness
|
|
5
|
+
这是DataOps托管工作区使用的DeepSeek Harness集成插件。它接收当前DataOps会话JWT,并通过credential-backed HTTP MCP提供DataOps工具;DSH Settings显示只读的DataOps身份与权限说明。
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
本包不发起OAuth,也不提供连接、重新授权或断开按钮。DataOps父页面把现有JWT交给固定Host route;插件把它存入DSH credential,MCP transport在每次请求前读取当前值。DataOps API根据该JWT对应的当前角色和资源授权决定可执行范围。
|
|
8
8
|
|
|
9
9
|
本包只应安装到DataOps托管profile。独立DSH需要用户授权时使用@sparkelf/dsh-dataops-integration,两者不应同时安装。
|
|
10
10
|
|
|
11
11
|
### 模型体验
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
本包增加命名空间化DataOps MCP tool schema,但不把JWT写入system prompt、tool参数、结果或session log。认证本身不增加token或改变KV cache。
|
|
14
14
|
|
|
15
15
|
### 已知限制
|
|
16
16
|
|
|
17
|
-
-
|
|
17
|
+
- JWT尚未同步或DataOps拒绝当前权限时,MCP client直接呈现对应连接或工具错误。
|
|
18
18
|
|
|
19
19
|
## English
|
|
20
20
|
|
|
21
|
-
This is the DeepSeek Harness
|
|
21
|
+
This is the DeepSeek Harness integration plugin for DataOps-managed workspaces. It accepts the current DataOps session JWT and provides DataOps tools through credential-backed HTTP MCP; DSH Settings shows a read-only identity and permission summary.
|
|
22
22
|
|
|
23
|
-
The package
|
|
23
|
+
The package starts no OAuth flow and exposes no connect, reauthorize, or disconnect control. The DataOps parent supplies its existing JWT to one fixed Host route; the plugin stores it as a DSH credential, and the MCP transport resolves the current value before every request. DataOps APIs decide the allowed operations from the JWT principal's current roles and resource grants.
|
|
24
24
|
|
|
25
25
|
Install this package only in a DataOps-managed profile. Standalone DSH deployments that need user authorization use @sparkelf/dsh-dataops-integration; the two packages must not be installed together.
|
|
26
26
|
|
|
27
27
|
### Model Experience
|
|
28
28
|
|
|
29
|
-
The package
|
|
29
|
+
The package adds namespaced DataOps MCP tool schemas but never places the JWT in the system prompt, tool arguments, results, or Session log. Authentication adds no model tokens and does not affect the KV cache.
|
|
30
30
|
|
|
31
31
|
### Known Limitations
|
|
32
32
|
|
|
33
|
-
-
|
|
33
|
+
- Before JWT synchronization, or when DataOps rejects current permissions, the MCP client exposes the corresponding connection or tool error.
|
package/lib/client.js
CHANGED
|
@@ -17,17 +17,17 @@ window.__ModuleLoader__.load({
|
|
|
17
17
|
document.head.appendChild(tag);
|
|
18
18
|
}
|
|
19
19
|
var ManagedDataOpsSection_module_css_default = {
|
|
20
|
-
"statusRow": "aGKsna_statusRow",
|
|
21
20
|
"details": "aGKsna_details",
|
|
22
21
|
"detailRow": "aGKsna_detailRow",
|
|
23
|
-
"
|
|
22
|
+
"statusRow": "aGKsna_statusRow",
|
|
23
|
+
"title": "aGKsna_title",
|
|
24
24
|
"description": "aGKsna_description",
|
|
25
|
-
"
|
|
25
|
+
"section": "aGKsna_section"
|
|
26
26
|
};
|
|
27
27
|
//#endregion
|
|
28
28
|
//#region src/client/ManagedDataOpsSection.tsx
|
|
29
29
|
/**
|
|
30
|
-
* Explain DataOps-managed
|
|
30
|
+
* Explain the DataOps-managed JWT and permission owner without standalone controls.
|
|
31
31
|
* @param props - Settings slot injection values.
|
|
32
32
|
* @returns The localized managed DataOps section, or nothing before injection.
|
|
33
33
|
*/
|
|
@@ -69,26 +69,28 @@ window.__ModuleLoader__.load({
|
|
|
69
69
|
nav: "DataOps",
|
|
70
70
|
title: "DataOps",
|
|
71
71
|
managed: "Managed by this DataOps workspace",
|
|
72
|
-
description: "
|
|
72
|
+
description: "DSH uses your current DataOps session JWT. DataOps applies its role and resource permissions to every tool request.",
|
|
73
73
|
identityLabel: "Identity and permissions",
|
|
74
|
-
identityValue: "
|
|
74
|
+
identityValue: "Current DataOps JWT",
|
|
75
75
|
toolsLabel: "DataOps tools",
|
|
76
|
-
toolsValue: "
|
|
76
|
+
toolsValue: "Authorized by DataOps on every request"
|
|
77
77
|
};
|
|
78
78
|
/** Chinese managed DataOps Settings copy. */
|
|
79
79
|
const zh = {
|
|
80
80
|
nav: "DataOps",
|
|
81
81
|
title: "DataOps",
|
|
82
82
|
managed: "由当前 DataOps 工作区托管",
|
|
83
|
-
description: "DataOps
|
|
83
|
+
description: "DSH 使用当前 DataOps 会话 JWT;DataOps 对每次工具请求应用角色与资源权限。",
|
|
84
84
|
identityLabel: "身份与权限",
|
|
85
|
-
identityValue: "
|
|
85
|
+
identityValue: "当前 DataOps JWT",
|
|
86
86
|
toolsLabel: "DataOps 工具",
|
|
87
|
-
toolsValue: "
|
|
87
|
+
toolsValue: "每次请求均由 DataOps 授权"
|
|
88
88
|
};
|
|
89
89
|
//#endregion
|
|
90
90
|
//#region src/client/index.ts
|
|
91
91
|
const NS = "settings.dataops-managed";
|
|
92
|
+
const AUTH_UPDATED_MESSAGE = "dataops-auth-updated";
|
|
93
|
+
const MANAGED_AUTH_PATH = "/integrations/dataops/managed-auth";
|
|
92
94
|
/** Required client services for the managed DataOps Settings section. */
|
|
93
95
|
const inject = ["slots", "locale"];
|
|
94
96
|
/**
|
|
@@ -108,6 +110,22 @@ window.__ModuleLoader__.load({
|
|
|
108
110
|
label: () => t("nav"),
|
|
109
111
|
inject: () => ({ t })
|
|
110
112
|
}, ManagedDataOpsSection));
|
|
113
|
+
const synchronizeJwt = async () => {
|
|
114
|
+
const response = await fetch(new URL(MANAGED_AUTH_PATH, window.location.origin), {
|
|
115
|
+
method: "POST",
|
|
116
|
+
credentials: "same-origin"
|
|
117
|
+
});
|
|
118
|
+
if (!response.ok) throw new Error(`DataOps managed JWT synchronization failed with HTTP ${String(response.status)}`);
|
|
119
|
+
};
|
|
120
|
+
const onMessage = (event) => {
|
|
121
|
+
if (event.source !== window.parent || event.data?.type !== AUTH_UPDATED_MESSAGE) return;
|
|
122
|
+
synchronizeJwt().catch((error) => console.error("dataops-managed.jwt_sync_failed", error));
|
|
123
|
+
};
|
|
124
|
+
ctx.effect(() => {
|
|
125
|
+
window.addEventListener("message", onMessage);
|
|
126
|
+
synchronizeJwt().catch((error) => console.error("dataops-managed.jwt_sync_failed", error));
|
|
127
|
+
return () => window.removeEventListener("message", onMessage);
|
|
128
|
+
}, "dataops-managed: JWT synchronization");
|
|
111
129
|
}
|
|
112
130
|
//#endregion
|
|
113
131
|
exports.apply = apply;
|
package/lib/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","names":["styles","StateDot"],"sources":["../src/client/ManagedDataOpsSection.tsx","../src/client/locales.ts","../src/client/index.ts"],"sourcesContent":["import { StateDot } from '@deepseek-ai/dsh-client-ui-primitives'\nimport type { InjectFace } from '@deepseek-ai/dsh-client-ui-slots'\nimport type { en } from './locales.ts'\nimport styles from './ManagedDataOpsSection.module.css'\n\n/** Values injected by the DSH Settings slot. */\nexport interface ManagedDataOpsSectionInjected {\n /** Translate one managed DataOps Settings message key. */\n t: (key: keyof typeof en) => string\n}\n\n/** Props accepted by the managed DataOps Settings section. */\nexport type ManagedDataOpsSectionProps = Partial<InjectFace<ManagedDataOpsSectionInjected>>\n\n/**\n * Explain DataOps-managed
|
|
1
|
+
{"version":3,"file":"client.js","names":["styles","StateDot"],"sources":["../src/client/ManagedDataOpsSection.tsx","../src/client/locales.ts","../src/client/index.ts"],"sourcesContent":["import { StateDot } from '@deepseek-ai/dsh-client-ui-primitives'\nimport type { InjectFace } from '@deepseek-ai/dsh-client-ui-slots'\nimport type { en } from './locales.ts'\nimport styles from './ManagedDataOpsSection.module.css'\n\n/** Values injected by the DSH Settings slot. */\nexport interface ManagedDataOpsSectionInjected {\n /** Translate one managed DataOps Settings message key. */\n t: (key: keyof typeof en) => string\n}\n\n/** Props accepted by the managed DataOps Settings section. */\nexport type ManagedDataOpsSectionProps = Partial<InjectFace<ManagedDataOpsSectionInjected>>\n\n/**\n * Explain the DataOps-managed JWT and permission owner without standalone controls.\n * @param props - Settings slot injection values.\n * @returns The localized managed DataOps section, or nothing before injection.\n */\nexport function ManagedDataOpsSection(props: ManagedDataOpsSectionProps) {\n const { t } = props\n if (t === undefined) return null\n\n return (\n <section className={styles.section}>\n <h2 className={styles.title}>{t('title')}</h2>\n <div className={styles.statusRow}>\n <StateDot state=\"done\" />\n <strong>{t('managed')}</strong>\n </div>\n <p className={styles.description}>{t('description')}</p>\n <dl className={styles.details}>\n <div className={styles.detailRow}>\n <dt>{t('identityLabel')}</dt>\n <dd>{t('identityValue')}</dd>\n </div>\n <div className={styles.detailRow}>\n <dt>{t('toolsLabel')}</dt>\n <dd>{t('toolsValue')}</dd>\n </div>\n </dl>\n </section>\n )\n}\n","/** English managed DataOps Settings copy. */\nexport const en = {\n nav: 'DataOps',\n title: 'DataOps',\n managed: 'Managed by this DataOps workspace',\n description: 'DSH uses your current DataOps session JWT. DataOps applies its role and resource permissions to every tool request.',\n identityLabel: 'Identity and permissions',\n identityValue: 'Current DataOps JWT',\n toolsLabel: 'DataOps tools',\n toolsValue: 'Authorized by DataOps on every request',\n} as const\n\n/** Stable key set shared by every managed DataOps locale. */\nexport type ManagedDataOpsKey = keyof typeof en\n\n/** Chinese managed DataOps Settings copy. */\nexport const zh: Record<ManagedDataOpsKey, string> = {\n nav: 'DataOps',\n title: 'DataOps',\n managed: '由当前 DataOps 工作区托管',\n description: 'DSH 使用当前 DataOps 会话 JWT;DataOps 对每次工具请求应用角色与资源权限。',\n identityLabel: '身份与权限',\n identityValue: '当前 DataOps JWT',\n toolsLabel: 'DataOps 工具',\n toolsValue: '每次请求均由 DataOps 授权',\n}\n","import type { ClientContext } from '@deepseek-ai/dsh-client-runtime/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-settings/client'\nimport type {} from '@deepseek-ai/dsh-client-locale/client'\nimport { ManagedDataOpsSection } from './ManagedDataOpsSection.tsx'\nimport type { ManagedDataOpsSectionInjected } from './ManagedDataOpsSection.tsx'\nimport { en, zh, type ManagedDataOpsKey } from './locales.ts'\n\ndeclare module '@deepseek-ai/dsh-client-ui-slots' {\n interface LocaleNamespaceMap {\n 'settings.dataops-managed': ManagedDataOpsKey\n }\n}\n\nconst NS = 'settings.dataops-managed'\nconst AUTH_UPDATED_MESSAGE = 'dataops-auth-updated'\nconst MANAGED_AUTH_PATH = '/integrations/dataops/managed-auth'\n\n/** Required client services for the managed DataOps Settings section. */\nexport const inject = ['slots', 'locale']\n\n/**\n * Register localized managed DataOps Settings navigation and content.\n * @param ctx - DSH client context with locale and settings slots.\n */\nexport function apply(ctx: ClientContext): void {\n ctx.effect(() => ctx.locale.register(NS, { zh, en }), 'dataops-managed: settings copy')\n const t = ctx.locale.bind(NS) as ManagedDataOpsSectionInjected['t']\n ctx.slots.inject('settings.section', () => ctx.slots.register({\n name: 'settings.section',\n id: 'dataops',\n order: 25,\n label: () => t('nav'),\n inject: () => ({ t }),\n }, ManagedDataOpsSection))\n\n const synchronizeJwt = async (): Promise<void> => {\n const response = await fetch(new URL(MANAGED_AUTH_PATH, window.location.origin), {\n method: 'POST',\n credentials: 'same-origin',\n })\n if (!response.ok) throw new Error(`DataOps managed JWT synchronization failed with HTTP ${String(response.status)}`)\n }\n const onMessage = (event: MessageEvent<unknown>): void => {\n if (event.source !== window.parent\n || (event.data as { type?: unknown } | null)?.type !== AUTH_UPDATED_MESSAGE) return\n void synchronizeJwt().catch(error => console.error('dataops-managed.jwt_sync_failed', error))\n }\n ctx.effect(() => {\n window.addEventListener('message', onMessage)\n void synchronizeJwt().catch(error => console.error('dataops-managed.jwt_sync_failed', error))\n return () => window.removeEventListener('message', onMessage)\n }, 'dataops-managed: JWT synchronization')\n}\n"],"mappings":"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"}
|
package/lib/index.js
CHANGED
|
@@ -1,10 +1,88 @@
|
|
|
1
|
+
import { credentialRef } from "@deepseek-ai/dsh-credentials";
|
|
2
|
+
import * as McpClient from "@sparkelf/dsh-plugin-mcp-credentials";
|
|
3
|
+
import z from "@deepseek-ai/schemastery";
|
|
1
4
|
//#region src/index.ts
|
|
2
|
-
/** Cordis plugin name for the DataOps-managed
|
|
5
|
+
/** Cordis plugin name for the DataOps-managed integration. */
|
|
3
6
|
const name = "dataops-managed";
|
|
7
|
+
/** Host services required by managed JWT and MCP ownership. */
|
|
8
|
+
const inject = [
|
|
9
|
+
"credentials",
|
|
10
|
+
"webServer",
|
|
11
|
+
"tools"
|
|
12
|
+
];
|
|
13
|
+
const MANAGED_AUTH_PATH = "/integrations/dataops/managed-auth";
|
|
14
|
+
/** Schemastery parser for managed DataOps configuration. */
|
|
15
|
+
const Config = z.object({
|
|
16
|
+
baseUrl: z.string().default("http://host.docker.internal:3101"),
|
|
17
|
+
serverName: z.string().default("dataops"),
|
|
18
|
+
credentialRef: z.string().role("credential-ref").default("DATAOPS_ACCESS_TOKEN"),
|
|
19
|
+
toolCallTimeoutMs: z.number().min(1).default(12e4)
|
|
20
|
+
});
|
|
21
|
+
function bearerToken(request) {
|
|
22
|
+
const authorization = request.headers.authorization?.trim() ?? "";
|
|
23
|
+
if (!authorization.startsWith("Bearer ")) return null;
|
|
24
|
+
const token = authorization.slice(7).trim();
|
|
25
|
+
return token === "" ? null : token;
|
|
26
|
+
}
|
|
4
27
|
/**
|
|
5
|
-
*
|
|
6
|
-
* @param
|
|
28
|
+
* Accept the current DataOps JWT and expose DataOps MCP tools through its credential.
|
|
29
|
+
* @param ctx - DSH Host context with credentials, Web routes, and tools.
|
|
30
|
+
* @param config - Managed DataOps origin and MCP settings.
|
|
31
|
+
* @returns Startup readiness after an existing JWT is connected when present.
|
|
7
32
|
*/
|
|
8
|
-
function apply(
|
|
33
|
+
async function apply(ctx, config) {
|
|
34
|
+
const baseUrl = new URL(config.baseUrl).origin;
|
|
35
|
+
const accessRef = credentialRef(config.credentialRef);
|
|
36
|
+
let mcpFiber;
|
|
37
|
+
const ensureMcp = async () => {
|
|
38
|
+
if (mcpFiber !== void 0 && mcpFiber.uid !== null) return;
|
|
39
|
+
const fiber = ctx.plugin(McpClient, {
|
|
40
|
+
transport: "streamable-http",
|
|
41
|
+
serverName: config.serverName,
|
|
42
|
+
url: `${baseUrl}/api/ai/data-query/mcp`,
|
|
43
|
+
headers: {},
|
|
44
|
+
bearerTokenRef: config.credentialRef,
|
|
45
|
+
toolCallTimeoutMs: config.toolCallTimeoutMs
|
|
46
|
+
});
|
|
47
|
+
mcpFiber = fiber;
|
|
48
|
+
try {
|
|
49
|
+
await fiber.await();
|
|
50
|
+
} catch (error) {
|
|
51
|
+
if (mcpFiber === fiber) mcpFiber = void 0;
|
|
52
|
+
await fiber.dispose();
|
|
53
|
+
throw error;
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
ctx.effect(() => async () => {
|
|
57
|
+
const fiber = mcpFiber;
|
|
58
|
+
mcpFiber = void 0;
|
|
59
|
+
if (fiber !== void 0 && fiber.uid !== null) await fiber.dispose();
|
|
60
|
+
}, "dataops-managed: MCP lifecycle");
|
|
61
|
+
if (await ctx.credentials.resolve(accessRef) !== void 0) await ensureMcp();
|
|
62
|
+
ctx.effect(() => ctx.webServer.register({
|
|
63
|
+
kind: "exact",
|
|
64
|
+
path: MANAGED_AUTH_PATH,
|
|
65
|
+
handler: async (request, response) => {
|
|
66
|
+
if (request.method !== "POST") {
|
|
67
|
+
response.writeHead(405, {
|
|
68
|
+
allow: "POST",
|
|
69
|
+
"content-length": "0"
|
|
70
|
+
});
|
|
71
|
+
response.end();
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
const token = bearerToken(request);
|
|
75
|
+
if (token === null) {
|
|
76
|
+
response.writeHead(401, { "content-length": "0" });
|
|
77
|
+
response.end();
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
await ctx.credentials.set(accessRef, token);
|
|
81
|
+
await ensureMcp();
|
|
82
|
+
response.writeHead(204, { "cache-control": "no-store" });
|
|
83
|
+
response.end();
|
|
84
|
+
}
|
|
85
|
+
}), "dataops-managed: JWT intake route");
|
|
86
|
+
}
|
|
9
87
|
//#endregion
|
|
10
|
-
export { apply, name };
|
|
88
|
+
export { Config, MANAGED_AUTH_PATH, apply, inject, name };
|
|
@@ -8,7 +8,7 @@ export interface ManagedDataOpsSectionInjected {
|
|
|
8
8
|
/** Props accepted by the managed DataOps Settings section. */
|
|
9
9
|
export type ManagedDataOpsSectionProps = Partial<InjectFace<ManagedDataOpsSectionInjected>>;
|
|
10
10
|
/**
|
|
11
|
-
* Explain DataOps-managed
|
|
11
|
+
* Explain the DataOps-managed JWT and permission owner without standalone controls.
|
|
12
12
|
* @param props - Settings slot injection values.
|
|
13
13
|
* @returns The localized managed DataOps section, or nothing before injection.
|
|
14
14
|
*/
|
|
@@ -3,11 +3,11 @@ export declare const en: {
|
|
|
3
3
|
readonly nav: "DataOps";
|
|
4
4
|
readonly title: "DataOps";
|
|
5
5
|
readonly managed: "Managed by this DataOps workspace";
|
|
6
|
-
readonly description: "
|
|
6
|
+
readonly description: "DSH uses your current DataOps session JWT. DataOps applies its role and resource permissions to every tool request.";
|
|
7
7
|
readonly identityLabel: "Identity and permissions";
|
|
8
|
-
readonly identityValue: "
|
|
8
|
+
readonly identityValue: "Current DataOps JWT";
|
|
9
9
|
readonly toolsLabel: "DataOps tools";
|
|
10
|
-
readonly toolsValue: "
|
|
10
|
+
readonly toolsValue: "Authorized by DataOps on every request";
|
|
11
11
|
};
|
|
12
12
|
/** Stable key set shared by every managed DataOps locale. */
|
|
13
13
|
export type ManagedDataOpsKey = keyof typeof en;
|
package/lib/types/index.d.ts
CHANGED
|
@@ -1,8 +1,28 @@
|
|
|
1
|
+
/** DataOps-managed JWT intake and credential-backed MCP composition. */
|
|
1
2
|
import type { Context } from '@deepseek-ai/cordis';
|
|
2
|
-
|
|
3
|
+
import z from '@deepseek-ai/schemastery';
|
|
4
|
+
/** Cordis plugin name for the DataOps-managed integration. */
|
|
3
5
|
export declare const name = "dataops-managed";
|
|
6
|
+
/** Host services required by managed JWT and MCP ownership. */
|
|
7
|
+
export declare const inject: string[];
|
|
8
|
+
export declare const MANAGED_AUTH_PATH = "/integrations/dataops/managed-auth";
|
|
9
|
+
/** Configuration for the DataOps-managed MCP connection. */
|
|
10
|
+
export interface Config {
|
|
11
|
+
/** DataOps browser/API origin reachable from the DSH Host. */
|
|
12
|
+
baseUrl: string;
|
|
13
|
+
/** Local namespace for DataOps MCP tools. */
|
|
14
|
+
serverName: string;
|
|
15
|
+
/** DSH credential reference that stores the current DataOps access JWT. */
|
|
16
|
+
credentialRef: string;
|
|
17
|
+
/** Per-tool-call timeout forwarded to the MCP client. */
|
|
18
|
+
toolCallTimeoutMs: number;
|
|
19
|
+
}
|
|
20
|
+
/** Schemastery parser for managed DataOps configuration. */
|
|
21
|
+
export declare const Config: z<Config>;
|
|
4
22
|
/**
|
|
5
|
-
*
|
|
6
|
-
* @param
|
|
23
|
+
* Accept the current DataOps JWT and expose DataOps MCP tools through its credential.
|
|
24
|
+
* @param ctx - DSH Host context with credentials, Web routes, and tools.
|
|
25
|
+
* @param config - Managed DataOps origin and MCP settings.
|
|
26
|
+
* @returns Startup readiness after an existing JWT is connected when present.
|
|
7
27
|
*/
|
|
8
|
-
export declare function apply(
|
|
28
|
+
export declare function apply(ctx: Context, config: Config): Promise<void>;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sparkelf/dsh-dataops-managed",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "DataOps JWT intake and credential-backed MCP tools for managed DeepSeek Harness workspaces.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./lib/index.js",
|
|
7
7
|
"types": "./lib/types/index.d.ts",
|
|
@@ -54,20 +54,30 @@
|
|
|
54
54
|
},
|
|
55
55
|
"peerDependencies": {
|
|
56
56
|
"@deepseek-ai/cordis": "^4.0.1",
|
|
57
|
+
"@deepseek-ai/dsh-credentials": "^0.1.1-rc.2",
|
|
58
|
+
"@deepseek-ai/dsh-host-webserver": "^0.1.1-rc.2",
|
|
57
59
|
"@deepseek-ai/dsh-client-locale": "^0.1.1-rc.2",
|
|
58
60
|
"@deepseek-ai/dsh-client-runtime": "^0.1.1-rc.2",
|
|
59
61
|
"@deepseek-ai/dsh-client-ui-primitives": "^0.1.1-rc.2",
|
|
60
62
|
"@deepseek-ai/dsh-client-ui-settings": "^0.1.1-rc.2",
|
|
61
63
|
"@deepseek-ai/dsh-client-ui-slots": "^0.1.1-rc.2",
|
|
64
|
+
"@deepseek-ai/dsh-tools": "^0.1.1-rc.2",
|
|
65
|
+
"@deepseek-ai/schemastery": ">=3.18.1",
|
|
66
|
+
"@sparkelf/dsh-plugin-mcp-credentials": ">=0.1.0-rc.11",
|
|
62
67
|
"react": ">=18.2.0 <20"
|
|
63
68
|
},
|
|
64
69
|
"devDependencies": {
|
|
65
70
|
"@deepseek-ai/cordis": "4.0.1",
|
|
71
|
+
"@deepseek-ai/dsh-credentials": "0.1.1-rc.2",
|
|
72
|
+
"@deepseek-ai/dsh-host-webserver": "0.1.1-rc.2",
|
|
66
73
|
"@deepseek-ai/dsh-client-locale": "0.1.1-rc.2",
|
|
67
74
|
"@deepseek-ai/dsh-client-runtime": "0.1.1-rc.2",
|
|
68
75
|
"@deepseek-ai/dsh-client-ui-primitives": "0.1.1-rc.2",
|
|
69
76
|
"@deepseek-ai/dsh-client-ui-settings": "0.1.1-rc.2",
|
|
70
77
|
"@deepseek-ai/dsh-client-ui-slots": "0.1.1-rc.2",
|
|
78
|
+
"@deepseek-ai/dsh-tools": "0.1.1-rc.2",
|
|
79
|
+
"@deepseek-ai/schemastery": "^3.18.1",
|
|
80
|
+
"@sparkelf/dsh-plugin-mcp-credentials": "0.1.0-rc.11",
|
|
71
81
|
"@types/react": "~18.3.1",
|
|
72
82
|
"lightningcss": "^1.32.0",
|
|
73
83
|
"react": "^18.2.0",
|