@chengxianglibra/dsh-data-analysis 0.2.1 → 0.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/README.en.md +6 -3
  2. package/README.md +6 -3
  3. package/lib/client/credentials/create-datasource.js +1 -1
  4. package/lib/client/credentials/install.js +1 -1
  5. package/lib/client/input-context.js +1 -1
  6. package/lib/client/python-tool/card.js +2 -2
  7. package/lib/client/python-tool/model.js +1 -1
  8. package/lib/client/right-tabs/install.js +10 -7
  9. package/lib/client/settings/install.js +7 -3
  10. package/lib/client-composition.js +701 -0
  11. package/lib/client.js +82 -71
  12. package/lib/compatibility.js +1 -0
  13. package/lib/datasource/changes-contract.js +6 -2
  14. package/lib/datasource/defaults.js +26 -4
  15. package/lib/datasource/python.js +3 -1
  16. package/lib/datasource/rpc.js +3 -3
  17. package/lib/environment/runtime.js +2 -0
  18. package/lib/environment/workspace.js +13 -1
  19. package/lib/integration.js +5 -0
  20. package/lib/plugin.js +18 -8
  21. package/lib/presentation/execution-policy.js +5 -0
  22. package/lib/presentation/projection/index.js +27 -10
  23. package/lib/presentation/tool.js +2 -1
  24. package/lib/settings.js +11 -15
  25. package/lib/types/client/settings/card.d.ts +2 -2
  26. package/lib/types/client.d.ts +1 -0
  27. package/lib/types/compatibility.d.ts +1 -0
  28. package/lib/types/datasource/defaults.d.ts +2 -1
  29. package/lib/types/datasource/rpc.d.ts +2 -2
  30. package/lib/types/disclosure/execution-guidance.d.ts +8 -0
  31. package/lib/types/environment/errors.d.ts +1 -1
  32. package/lib/types/environment/runtime.d.ts +2 -0
  33. package/lib/types/environment/workspace.d.ts +2 -1
  34. package/lib/types/integration.d.ts +16 -0
  35. package/lib/types/plugin.d.ts +26 -3
  36. package/lib/types/presentation/execution-policy.d.ts +5 -0
  37. package/lib/types/rpc.d.ts +2 -2
  38. package/lib/types/semantic-reference/rpc.d.ts +2 -2
  39. package/lib/types/settings.d.ts +8 -8
  40. package/package.json +89 -70
  41. package/python/presentation-kit/dist/dsh_data_analysis_presentation_kit-1.1.0-py3-none-any.whl +0 -0
  42. package/skills/dsh-data-analysis-files/SKILL.md +3 -3
  43. package/skills/dsh-data-analysis-files/references/delivery.md +2 -2
@@ -48,6 +48,7 @@ function parsePackageManifest(value) {
48
48
  contracts: Object.freeze({
49
49
  runtimeInstallation: requiredLiteral(contracts.runtimeInstallation, 'dsh-data-analysis-runtime/v3', 'package compatibility contracts.runtimeInstallation'),
50
50
  subprocessPolicy: requiredLiteral(contracts.subprocessPolicy, 'direct-argv-inherited-env-snapshot-overlay-v2', 'package compatibility contracts.subprocessPolicy'),
51
+ integration: requiredLiteral(contracts.integration, 'dsh-data-analysis-integration/v1', 'package compatibility contracts.integration'),
51
52
  }),
52
53
  }),
53
54
  });
@@ -18,14 +18,18 @@ const descriptor = {
18
18
  name: 'sessionId',
19
19
  wire: 'sessionId',
20
20
  source: 'json',
21
- codec: { mode: 'strict', typeSymbol: `${owner}#CredentialSessionId`, schema: sessionId },
21
+ codec: {
22
+ mode: 'strict',
23
+ typeSymbol: `${owner}#CredentialSessionId`,
24
+ create: () => sessionId,
25
+ },
22
26
  },
23
27
  ],
24
28
  cancellation: { parameter: 'signal' },
25
29
  result: {
26
30
  mode: 'strict',
27
31
  typeSymbol: `${owner}#CredentialRevision`,
28
- schema: credentialRevisionSchema,
32
+ create: () => credentialRevisionSchema,
29
33
  },
30
34
  };
31
35
  export const credentialChangesHost = {
@@ -1,10 +1,13 @@
1
1
  import { z } from 'zod';
2
2
  import { CredentialServiceError } from "./service.js";
3
+ import { marivoCredentialStorageRef } from "./shell-env.js";
3
4
  /** Validate against this Workspace's live Runtime; never include config values in errors. */
4
- export function withDatasourceDefaults(schema, configured) {
5
- if (configured === undefined)
5
+ export function withDatasourceDefaults(schema, configured, managed) {
6
+ if (configured === undefined && managed === undefined)
6
7
  return schema;
7
- const parsed = z.record(z.string(), z.record(z.string(), z.json())).safeParse(configured);
8
+ const parsed = z
9
+ .record(z.string(), z.record(z.string(), z.json()))
10
+ .safeParse(configured === undefined ? {} : configured);
8
11
  if (!parsed.success)
9
12
  throw new CredentialServiceError('datasource-defaults-invalid');
10
13
  for (const [backend, values] of Object.entries(parsed.data)) {
@@ -21,5 +24,24 @@ export function withDatasourceDefaults(schema, configured) {
21
24
  throw new CredentialServiceError('datasource-defaults-type-invalid');
22
25
  }
23
26
  }
24
- return { ...schema, creationDefaults: parsed.data };
27
+ const combined = Object.fromEntries(Object.entries(parsed.data).map(([backend, values]) => [backend, { ...values }]));
28
+ if (managed !== undefined) {
29
+ const references = z.record(z.string(), z.record(z.string(), z.string())).safeParse(managed);
30
+ if (!references.success)
31
+ throw new CredentialServiceError('datasource-defaults-invalid');
32
+ for (const [backend, fields] of Object.entries(references.data)) {
33
+ const definition = schema.backends.find((item) => item.name === backend);
34
+ if (!definition)
35
+ throw new CredentialServiceError('datasource-defaults-backend-invalid');
36
+ for (const [name, reference] of Object.entries(fields)) {
37
+ if (!name.endsWith('_env') || !definition.fields.some((field) => field.name === name))
38
+ throw new CredentialServiceError('datasource-defaults-field-invalid');
39
+ marivoCredentialStorageRef(reference);
40
+ if (Object.hasOwn(combined[backend] ?? {}, name))
41
+ throw new CredentialServiceError('datasource-defaults-credential-forbidden');
42
+ }
43
+ combined[backend] = { ...combined[backend], ...fields };
44
+ }
45
+ }
46
+ return { ...schema, creationDefaults: combined };
25
47
  }
@@ -116,6 +116,7 @@ export function registerMarivoPythonTool(ctx, source, service, options = {}) {
116
116
  command: `${process.platform === 'win32' ? '& ' : ''}${quote(binding.pythonExecutable)} -c ${quote(PYTHON_LAUNCHER)}`,
117
117
  workdir: binding.projectRoot,
118
118
  timeoutMs: requestedTimeoutMs,
119
+ onExpiry: 'kill',
119
120
  signal: prepared.signal,
120
121
  stdin: JSON.stringify({
121
122
  identity: binding,
@@ -135,7 +136,8 @@ export function registerMarivoPythonTool(ctx, source, service, options = {}) {
135
136
  const startedAt = new Date().toISOString();
136
137
  phase = 'executing';
137
138
  shellStartedAt = performance.now();
138
- const result = await service.track(shell.run(spec));
139
+ const execution = await service.track(shell.execute(spec));
140
+ const result = await service.track(execution.result());
139
141
  executionElapsedMs = performance.now() - shellStartedAt;
140
142
  const finishedAt = new Date().toISOString();
141
143
  const credentialValues = prepared.values;
@@ -1,6 +1,6 @@
1
1
  import { z } from 'zod';
2
2
  import { registerPluginRpc } from "../rpc.js";
3
- import { withDatasourceDefaults } from "./defaults.js";
3
+ import { withDatasourceDefaults, } from "./defaults.js";
4
4
  import { CREDENTIAL_CHANNEL, credentialError } from "./service.js";
5
5
  const text = z.string().min(1).max(256);
6
6
  const handle = { generation: z.string().uuid(), id: z.string().uuid(), scope: z.string().uuid() };
@@ -15,7 +15,7 @@ const mutation = z
15
15
  changes: z.record(text, z.string().min(1).max(65536)).optional(),
16
16
  })
17
17
  .strict();
18
- export function registerCredentialRpc(connection, service, workspace, datasourceDefaults) {
18
+ export function registerCredentialRpc(connection, service, workspace, datasourceDefaults, managedCredentialDefaults) {
19
19
  const unregister = registerPluginRpc(connection, CREDENTIAL_CHANNEL, [
20
20
  'overview',
21
21
  'authoring',
@@ -53,7 +53,7 @@ export function registerCredentialRpc(connection, service, workspace, datasource
53
53
  generation: service.generation,
54
54
  ...(input.mode === 'edit'
55
55
  ? schema
56
- : withDatasourceDefaults(schema, datasourceDefaults)),
56
+ : withDatasourceDefaults(schema, datasourceDefaults, managedCredentialDefaults)),
57
57
  };
58
58
  }
59
59
  else if (endpoint === 'configuration') {
@@ -527,6 +527,8 @@ export async function ensureSharedMarivoRuntime(config = {}, options = {}) {
527
527
  const existing = await validatedExisting(runtimeRoot, configuredPython, options.environment, timeoutMs, presentationKitWheel);
528
528
  if (existing !== undefined)
529
529
  return existing;
530
+ if (options.existingOnly)
531
+ throw new MarivoEnvironmentError('shared-runtime-installation-required', 'A valid shared Marivo Runtime installation is required');
530
532
  await mkdir(path.dirname(runtimeRoot), { recursive: true });
531
533
  const lockPath = `${runtimeRoot}.install-lock`;
532
534
  const release = await acquireLock(lockPath, timeoutMs, options.waitIntervalMs ?? 100);
@@ -31,9 +31,11 @@ export class MarivoWorkspaceEnvironmentManager {
31
31
  #disposed = false;
32
32
  #closing;
33
33
  runtime;
34
+ onBound;
34
35
  #bindings = new Map();
35
- constructor(runtime) {
36
+ constructor(runtime, onBound) {
36
37
  this.runtime = runtime;
38
+ this.onBound = onBound;
37
39
  }
38
40
  resolve(projectRoot) {
39
41
  return this.#tasks.track(this.#resolve(projectRoot));
@@ -54,6 +56,16 @@ export class MarivoWorkspaceEnvironmentManager {
54
56
  version: this.runtime.presentationKitVersion,
55
57
  packagePath: this.runtime.presentationKitPackagePath,
56
58
  },
59
+ })
60
+ .then(async (environment) => {
61
+ if (this.#disposed)
62
+ throw new Error('Marivo Workspace manager disposed');
63
+ await this.onBound?.(environment);
64
+ return environment;
65
+ })
66
+ .catch((error) => {
67
+ this.#bindings.delete(canonicalRoot);
68
+ throw error;
57
69
  });
58
70
  this.#bindings.set(canonicalRoot, binding);
59
71
  }
@@ -0,0 +1,5 @@
1
+ /** Public extension seam. The version denotes this shape, not a specific consumer. */
2
+ export const INTEGRATION_CONTRACT_VERSION = 'dsh-data-analysis-integration/v1';
3
+ export { withDatasourceDefaults } from "./datasource/defaults.js";
4
+ export { applyWithIntegration } from "./plugin.js";
5
+ export { registerPluginRpc } from "./rpc.js";
package/lib/plugin.js CHANGED
@@ -5,7 +5,7 @@ import { createMarivoAgentInstallation } from "./plugin-agents.js";
5
5
  import { registerPublishingCredentials } from "./report-publishing/adapters.js";
6
6
  import { resolvePublishingConfig } from "./report-publishing/config.js";
7
7
  import { ReportPublishingService } from "./report-publishing/service.js";
8
- import { installPythonSettings } from "./settings.js";
8
+ import { currentPythonOptions, installPythonSettings, } from "./settings.js";
9
9
  import { resolvePresentationWorkspace } from "./workspace-identity.js";
10
10
  export { installMarivoPlugin } from "./plugin-agents.js";
11
11
  export { resolvePresentationWorkspace } from "./workspace-identity.js";
@@ -17,7 +17,7 @@ import { apply as installSkillFilesystem } from '@deepseek-ai/dsh-skill-filesyst
17
17
  import { WorkspaceId } from '@deepseek-ai/dsh-workspace';
18
18
  import z from '@deepseek-ai/schemastery';
19
19
  import { MarivoDatasourceBridge } from "./datasource/bridge.js";
20
- import { DEFAULT_PYTHON_TIMEOUT_MS, resolvePythonOptions, } from "./datasource/python-options.js";
20
+ import { DEFAULT_PYTHON_TIMEOUT_MS } from "./datasource/python-options.js";
21
21
  import { registerCredentialRpc } from "./datasource/rpc.js";
22
22
  import { MarivoCredentialService } from "./datasource/service.js";
23
23
  import { registerMarivoRuntimeShellEnvironment } from "./datasource/shell-env.js";
@@ -47,7 +47,13 @@ export const Config = z.object({
47
47
  // Defer validation to authoring so loader errors cannot echo configured values.
48
48
  datasourceDefaults: z.any(),
49
49
  reportPublishing: z.any(),
50
- pythonTimeoutMs: z.number().default(DEFAULT_PYTHON_TIMEOUT_MS),
50
+ pythonTimeoutMs: z
51
+ .number()
52
+ .min(1)
53
+ .max(2_147_483_647)
54
+ .step(1)
55
+ .default(DEFAULT_PYTHON_TIMEOUT_MS)
56
+ .volatile(),
51
57
  credentialInteraction: z.union(['web', 'none']).default('web'),
52
58
  projectRoot: z.string(),
53
59
  pythonExecutable: z.string(),
@@ -64,8 +70,12 @@ function configuredProjectRoot(config, agent) {
64
70
  }
65
71
  /** Ensure the shared Runtime once, mount its skills, then bind each Workspace lazily. */
66
72
  export async function apply(ctx, config = {}) {
73
+ return applyWithIntegration(ctx, config);
74
+ }
75
+ /** Compose an extension at the public seam while retaining the ordinary plugin behavior. */
76
+ export async function applyWithIntegration(ctx, config = {}, integration = {}) {
67
77
  const publishingConfig = resolvePublishingConfig(config.reportPublishing);
68
- const pythonOptions = resolvePythonOptions(config);
78
+ const pythonOptions = currentPythonOptions(config);
69
79
  const pythonExecutable = config.pythonExecutable ?? process.env.DSH_DATA_ANALYSIS_PYTHON;
70
80
  const runtimeRoot = config.runtimeRoot ?? process.env.DSH_DATA_ANALYSIS_RUNTIME_ROOT;
71
81
  const bootstrapPythonExecutable = config.bootstrapPythonExecutable ?? process.env.DSH_DATA_ANALYSIS_BOOTSTRAP_PYTHON;
@@ -76,7 +86,7 @@ export async function apply(ctx, config = {}) {
76
86
  ...(config.installTimeoutMs === undefined ? {} : { installTimeoutMs: config.installTimeoutMs }),
77
87
  });
78
88
  const disposeRuntimeShellEnvironment = registerMarivoRuntimeShellEnvironment(ctx, runtime.pythonExecutable);
79
- const manager = new MarivoWorkspaceEnvironmentManager(runtime);
89
+ const manager = new MarivoWorkspaceEnvironmentManager(runtime, integration.onWorkspaceBound);
80
90
  const bindings = new WeakMap();
81
91
  const resolveEnvironment = (agent) => {
82
92
  const root = configuredProjectRoot(config, agent);
@@ -87,7 +97,7 @@ export async function apply(ctx, config = {}) {
87
97
  bindings.set(agent, { root, environment });
88
98
  return environment;
89
99
  };
90
- const credentialService = new MarivoCredentialService(ctx.credentials, config.credentialInteraction);
100
+ const credentialService = new MarivoCredentialService(integration.datasourceCredentials ?? ctx.credentials, config.credentialInteraction);
91
101
  const credentialNotifications = new CredentialChangesService(ctx, credentialService);
92
102
  let unregisterChanges;
93
103
  const disposeChanges = async () => {
@@ -134,7 +144,7 @@ export async function apply(ctx, config = {}) {
134
144
  return closing;
135
145
  };
136
146
  try {
137
- pythonSettings = installPythonSettings(ctx, pythonOptions);
147
+ pythonSettings = installPythonSettings(ctx, config);
138
148
  unregisterChanges = ctx.typert.register(credentialChangesHost);
139
149
  installSkillFilesystem(ctx, {
140
150
  providerName: 'dsh-data-analysis-marivo',
@@ -182,7 +192,7 @@ export async function apply(ctx, config = {}) {
182
192
  root)
183
193
  throw new Error('Workspace changed');
184
194
  return new MarivoDatasourceBridge(environment);
185
- }, config.datasourceDefaults);
195
+ }, config.datasourceDefaults, integration.managedCredentialDefaults);
186
196
  let lastDiagnostic = -Infinity;
187
197
  const usage = new SemanticReferenceUsage(ctx.storageDomain, Date.now, () => {
188
198
  if (Date.now() - lastDiagnostic >= 30_000) {
@@ -0,0 +1,5 @@
1
+ /** Report-specific wall-clock budgets; leave time after source reads for publication. */
2
+ export const PRESENTATION_EXECUTION_BUDGETS = Object.freeze({
3
+ sourceReadTimeoutMs: 120_000,
4
+ toolTimeoutMs: 180_000,
5
+ });
@@ -1,6 +1,7 @@
1
1
  import { MarivoEnvironmentError } from "../../environment/errors.js";
2
2
  import { readPythonExecution } from "../../python-execution.js";
3
3
  import { PRESENTATION_BUDGETS, PresentationContractError, parsePresentationDocument, parsePresentationDraft, parseTypedDataset, } from "../contracts/index.js";
4
+ import { PRESENTATION_EXECUTION_BUDGETS } from "../execution-policy.js";
4
5
  import { readWorkspaceJson } from "./files.js";
5
6
  import { MARIVO_PRESENTATION_READ_PROGRAM } from "./program.js";
6
7
  export { readWorkspaceJson } from "./files.js";
@@ -60,16 +61,32 @@ export class MarivoPresentationProjection {
60
61
  let diagnostics = [];
61
62
  const artifactData = new Map();
62
63
  if (draft.sources.length > 0) {
63
- const result = await this.#runner.runChecked({
64
- program: MARIVO_PRESENTATION_READ_PROGRAM,
65
- args: [JSON.stringify({ sources: draft.sources, datasets: artifactSelections })],
66
- limits: {
67
- timeoutMs: 30_000,
68
- stdoutMaxBytes: PRESENTATION_BUDGETS.documentBytes,
69
- stderrMaxBytes: 65_536,
70
- },
71
- signal: options.signal,
72
- });
64
+ const startedAt = performance.now();
65
+ let result;
66
+ try {
67
+ result = await this.#runner.runChecked({
68
+ program: MARIVO_PRESENTATION_READ_PROGRAM,
69
+ args: [JSON.stringify({ sources: draft.sources, datasets: artifactSelections })],
70
+ limits: {
71
+ timeoutMs: PRESENTATION_EXECUTION_BUDGETS.sourceReadTimeoutMs,
72
+ stdoutMaxBytes: PRESENTATION_BUDGETS.documentBytes,
73
+ stderrMaxBytes: 65_536,
74
+ },
75
+ signal: options.signal,
76
+ });
77
+ }
78
+ catch (error) {
79
+ if (!(error instanceof MarivoEnvironmentError) || error.code !== 'subprocess-timeout')
80
+ throw error;
81
+ // Construct only safe operation metadata; upstream messages/details may contain secrets.
82
+ throw new MarivoEnvironmentError('subprocess-timeout', 'Presentation source reading timed out. Source projection did not complete; report submission has not started. Keep the draft and source declarations for retry; do not remove sources or rerun analysis to repair presentation.', {
83
+ phase: 'presentation-source-read',
84
+ timeoutMs: PRESENTATION_EXECUTION_BUDGETS.sourceReadTimeoutMs,
85
+ durationMs: Math.max(0, Math.round(performance.now() - startedAt)),
86
+ sourceCount: draft.sources.length,
87
+ sessionCount: new Set(draft.sources.map((source) => source.ref.sessionId)).size,
88
+ });
89
+ }
73
90
  this.#assertReady(options.signal);
74
91
  if (result.exitCode !== 0)
75
92
  throw new MarivoEnvironmentError('subprocess-failed', 'The bound Marivo presentation read failed.', { exitCode: result.exitCode });
@@ -2,6 +2,7 @@ import { randomUUID } from 'node:crypto';
2
2
  import { defineTool } from '@deepseek-ai/dsh-tools';
3
3
  import { registerMarivoTool } from "../tool-lifecycle.js";
4
4
  import { parsePresentationBuildId } from "./contracts/index.js";
5
+ import { PRESENTATION_EXECUTION_BUDGETS } from "./execution-policy.js";
5
6
  import { MARIVO_PRESENT_TOOL_NAME, MARIVO_PRESENTATION_DELIVERY_KIND, parsePresentationDelivery, presentationReceiptText, } from "./receipt.js";
6
7
  import { publishPresentation, resolvePresentation } from "./reports.js";
7
8
  /** One call projects a draft, builds the document, commits them, then emits the receipt. */
@@ -38,7 +39,7 @@ export function createMarivoPresentTool(source, session, lifecycleSignal) {
38
39
  ],
39
40
  presentationMeta: (_args, value) => JSON.parse(value.deliveryJson),
40
41
  },
41
- timeoutMs: 120_000,
42
+ timeoutMs: PRESENTATION_EXECUTION_BUDGETS.toolTimeoutMs,
42
43
  async execute(args, exec) {
43
44
  const signal = lifecycleSignal ? AbortSignal.any([exec.signal, lifecycleSignal]) : exec.signal;
44
45
  if (typeof args.draft_path !== 'string' ||
package/lib/settings.js CHANGED
@@ -1,21 +1,17 @@
1
- import z from '@deepseek-ai/schemastery';
2
1
  import { resolvePythonOptions } from "./datasource/python-options.js";
3
2
  export const PYTHON_SETTINGS_NAMESPACE = 'dsh-data-analysis';
4
- export const PythonSettings = z.object({
5
- pythonTimeoutMs: z.number().min(1).max(2_147_483_647).step(1).required(),
6
- });
7
- /** Follow the Host settings provider; headless compositions retain their entry configuration. */
3
+ export function currentPythonOptions(options) {
4
+ const value = options.pythonTimeoutMs;
5
+ return resolvePythonOptions({
6
+ pythonTimeoutMs: value !== null && typeof value === 'object' && typeof value.get === 'function'
7
+ ? value.get()
8
+ : value,
9
+ });
10
+ }
11
+ /** Config is projected by the Host settings service; a headless composition reads its live entry. */
8
12
  export function installPythonSettings(ctx, options) {
9
- const entry = resolvePythonOptions(options);
10
- let source = () => entry;
11
13
  const dispose = ctx.inject(['settings'], (settingsCtx) => {
12
- settingsCtx.settings.installSection(ctx, PYTHON_SETTINGS_NAMESPACE, PythonSettings, entry, {
13
- validate: resolvePythonOptions,
14
- setSource: (current) => {
15
- source = current;
16
- },
17
- onChange: () => { },
18
- });
14
+ settingsCtx.effect(() => settingsCtx.settings.configure({ auto: false }, ctx.fiber));
19
15
  });
20
- return { get: () => source(), dispose: () => dispose.dispose() };
16
+ return { get: () => currentPythonOptions(options), dispose: () => dispose.dispose() };
21
17
  }
@@ -1,9 +1,9 @@
1
- import type { SettingsScope } from '@deepseek-ai/dsh-client-ui-settings/client';
1
+ import type { ConfigForm } from '@deepseek-ai/dsh-client-ui-settings/client';
2
2
  export interface PythonSettingsValue {
3
3
  pythonTimeoutMs: number;
4
4
  }
5
5
  /** Seconds in the form, exact integer milliseconds at the Host boundary. */
6
6
  export declare function timeoutMilliseconds(text: string): number | undefined;
7
7
  export declare function PythonSettingsCard({ scope }: {
8
- scope: SettingsScope<PythonSettingsValue>;
8
+ scope: ConfigForm<PythonSettingsValue>;
9
9
  }): import("react").JSX.Element | null;
@@ -3,6 +3,7 @@ import { installRightTabs } from './client/right-tabs/install.tsx';
3
3
  export { marivoPresentationDeliveryDefinition, parsePresentationDurableContent, presentationDeliveryFromEvent, presentationsForNode, } from './client/presentation/delivery.ts';
4
4
  export { PresentationDeliveryModel } from './client/presentation/delivery-model.ts';
5
5
  export { HostPresentationReader } from './client/presentation/host-entry.tsx';
6
+ export { createPluginRpc } from './client/rpc.ts';
6
7
  export declare const inject: string[];
7
8
  export declare function apply(ctx: Context, options?: {
8
9
  diagnostics?: boolean;
@@ -12,6 +12,7 @@ export interface DshDataAnalysisCompatibility {
12
12
  readonly contracts: {
13
13
  readonly runtimeInstallation: 'dsh-data-analysis-runtime/v3';
14
14
  readonly subprocessPolicy: 'direct-argv-inherited-env-snapshot-overlay-v2';
15
+ readonly integration: 'dsh-data-analysis-integration/v1';
15
16
  };
16
17
  }
17
18
  /** The package semver and the compatibility contract shipped in this exact installation. */
@@ -1,7 +1,8 @@
1
1
  import type { DatasourceAuthoring } from './authoring.ts';
2
2
  export type DatasourceDefaults = Record<string, Record<string, unknown>>;
3
+ export type ManagedCredentialDefaults = Record<string, Record<string, string>>;
3
4
  export type DatasourceAuthoringView = DatasourceAuthoring & {
4
5
  creationDefaults?: DatasourceDefaults;
5
6
  };
6
7
  /** Validate against this Workspace's live Runtime; never include config values in errors. */
7
- export declare function withDatasourceDefaults(schema: DatasourceAuthoring, configured: unknown): DatasourceAuthoringView;
8
+ export declare function withDatasourceDefaults(schema: DatasourceAuthoring, configured: unknown, managed?: ManagedCredentialDefaults): DatasourceAuthoringView;
@@ -1,5 +1,5 @@
1
1
  import type { HostConnectionHandle } from '@deepseek-ai/dsh-client-connection';
2
2
  import type { MarivoDatasourceBridgePort } from './bridge.ts';
3
- import { type DatasourceDefaults } from './defaults.ts';
3
+ import { type DatasourceDefaults, type ManagedCredentialDefaults } from './defaults.ts';
4
4
  import { type MarivoCredentialService } from './service.ts';
5
- export declare function registerCredentialRpc(connection: HostConnectionHandle, service: MarivoCredentialService, workspace: (id: string) => Promise<MarivoDatasourceBridgePort>, datasourceDefaults?: DatasourceDefaults): () => Promise<void>;
5
+ export declare function registerCredentialRpc(connection: HostConnectionHandle, service: MarivoCredentialService, workspace: (id: string) => Promise<MarivoDatasourceBridgePort>, datasourceDefaults?: DatasourceDefaults, managedCredentialDefaults?: ManagedCredentialDefaults): () => Promise<void>;
@@ -1,5 +1,13 @@
1
1
  import type { Agent } from '@deepseek-ai/dsh-agent';
2
2
  import type { MarivoDisclosureController } from './activation.ts';
3
+ declare module '@deepseek-ai/dsh-llm' {
4
+ interface MessageSourceMap {
5
+ plugin: {
6
+ kind: 'plugin';
7
+ plugin: string;
8
+ };
9
+ }
10
+ }
3
11
  export declare const MARIVO_DATASOURCE_CREDENTIAL_PROMPT: string;
4
12
  export declare const MARIVO_ANALYSIS_CLOSEOUT_PROMPT: string;
5
13
  /** Full-plugin seam: requires its execution tools, credentials service and system sections. */
@@ -1,4 +1,4 @@
1
- export type EnvironmentFailureCode = 'project-root-invalid' | 'python-path-relative' | 'python-unavailable' | 'shared-runtime-config-invalid' | 'shared-runtime-lock-timeout' | 'shared-runtime-install-failed' | 'shared-runtime-identity-mismatch' | 'shared-runtime-version-unsupported' | 'shared-runtime-pandas-unsupported' | 'shared-runtime-presentation-kit-unsupported' | 'shared-runtime-presentation-kit-wheel-invalid' | 'shared-runtime-presentation-kit-wheel-unavailable' | 'shared-runtime-package-unavailable' | 'shared-runtime-skills-invalid' | 'subprocess-start-failed' | 'subprocess-timeout' | 'subprocess-cancelled' | 'subprocess-output-limit' | 'subprocess-output-invalid' | 'subprocess-failed' | 'datasource-credential-ref-invalid' | 'datasource-credential-resolve-failed' | 'shell-credential-lease-invalid' | 'shell-credential-lease-expired' | 'shell-credential-lease-exhausted' | 'shell-credential-lease-scope-mismatch' | 'shell-credential-lease-resolve-failed' | 'shell-credential-injection-unsupported' | 'doctor-json-invalid' | 'doctor-admission-failed' | 'binding-identity-mismatch' | 'binding-failed';
1
+ export type EnvironmentFailureCode = 'project-root-invalid' | 'python-path-relative' | 'python-unavailable' | 'shared-runtime-config-invalid' | 'shared-runtime-installation-required' | 'shared-runtime-lock-timeout' | 'shared-runtime-install-failed' | 'shared-runtime-identity-mismatch' | 'shared-runtime-version-unsupported' | 'shared-runtime-pandas-unsupported' | 'shared-runtime-presentation-kit-unsupported' | 'shared-runtime-presentation-kit-wheel-invalid' | 'shared-runtime-presentation-kit-wheel-unavailable' | 'shared-runtime-package-unavailable' | 'shared-runtime-skills-invalid' | 'subprocess-start-failed' | 'subprocess-timeout' | 'subprocess-cancelled' | 'subprocess-output-limit' | 'subprocess-output-invalid' | 'subprocess-failed' | 'datasource-credential-ref-invalid' | 'datasource-credential-resolve-failed' | 'shell-credential-lease-invalid' | 'shell-credential-lease-expired' | 'shell-credential-lease-exhausted' | 'shell-credential-lease-scope-mismatch' | 'shell-credential-lease-resolve-failed' | 'shell-credential-injection-unsupported' | 'doctor-json-invalid' | 'doctor-admission-failed' | 'binding-identity-mismatch' | 'binding-failed';
2
2
  /** Stable failure envelope for config, subprocess, doctor, and identity errors. */
3
3
  export declare class MarivoEnvironmentError extends Error {
4
4
  readonly code: EnvironmentFailureCode;
@@ -7,6 +7,8 @@ export declare const PRESENTATION_KIT_PANDAS_RANGE = ">=2.2.0,<3.0.0";
7
7
  export declare const PRESENTATION_KIT_WHEEL_FILENAME = "dsh_data_analysis_presentation_kit-1.1.0-py3-none-any.whl";
8
8
  export declare const DEFAULT_SHARED_RUNTIME_INSTALL_TIMEOUT_MS = 600000;
9
9
  interface RuntimeInstallOptions {
10
+ /** Validate an existing installation without creating directories or acquiring an install lock. */
11
+ existingOnly?: boolean;
10
12
  environment?: NodeJS.ProcessEnv;
11
13
  waitIntervalMs?: number;
12
14
  /** Test/build seam; production always resolves the wheel distributed beside the plugin. */
@@ -4,7 +4,8 @@ import type { SharedMarivoRuntime } from './types.ts';
4
4
  export declare class MarivoWorkspaceEnvironmentManager {
5
5
  #private;
6
6
  readonly runtime: SharedMarivoRuntime;
7
- constructor(runtime: SharedMarivoRuntime);
7
+ readonly onBound?: (environment: MarivoEnvironment) => Promise<void>;
8
+ constructor(runtime: SharedMarivoRuntime, onBound?: (environment: MarivoEnvironment) => Promise<void>);
8
9
  resolve(projectRoot: string): Promise<MarivoEnvironment>;
9
10
  close(): Promise<void>;
10
11
  dispose(): void;
@@ -0,0 +1,16 @@
1
+ import type { ManagedCredentialDefaults } from './datasource/defaults.ts';
2
+ import type { CredentialStore } from './datasource/service.ts';
3
+ import type { MarivoEnvironment } from './environment/index.ts';
4
+ /** Public extension seam. The version denotes this shape, not a specific consumer. */
5
+ export declare const INTEGRATION_CONTRACT_VERSION: "dsh-data-analysis-integration/v1";
6
+ export interface MarivoIntegrationV1 {
7
+ /** Runs once after a Workspace binds, before its environment is returned. */
8
+ readonly onWorkspaceBound?: (environment: MarivoEnvironment) => Promise<void>;
9
+ /** Harness-managed store used only by datasource operations. */
10
+ readonly datasourceCredentials?: CredentialStore;
11
+ /** Credential reference names, validated against the live Workspace Runtime schema. */
12
+ readonly managedCredentialDefaults?: ManagedCredentialDefaults;
13
+ }
14
+ export { withDatasourceDefaults } from './datasource/defaults.ts';
15
+ export { applyWithIntegration } from './plugin.ts';
16
+ export { registerPluginRpc } from './rpc.ts';
@@ -1,17 +1,18 @@
1
1
  import { type ReportPublishingConfig } from './report-publishing/config.ts';
2
+ import { type PythonTimeoutConfig } from './settings.ts';
2
3
  export { installMarivoPlugin, type MarivoPluginEnvironmentResolver } from './plugin-agents.ts';
3
4
  export { resolvePresentationWorkspace } from './workspace-identity.ts';
4
5
  import type { Context } from '@deepseek-ai/cordis';
5
6
  import z from '@deepseek-ai/schemastery';
6
7
  import type { DatasourceDefaults } from './datasource/defaults.ts';
7
- import { type MarivoPythonOptions } from './datasource/python-options.ts';
8
+ import type { MarivoIntegrationV1 } from './integration.ts';
8
9
  export { MARIVO_DATASOURCE_CREDENTIAL_PROMPT } from './disclosure/execution-guidance.ts';
9
10
  /** Cordis plugin name used by loader diagnostics and lifecycle logs. */
10
11
  export declare const name = "dsh-data-analysis";
11
12
  /** Services that must exist before the plugin binds and watches Agent scopes. */
12
13
  export declare const inject: string[];
13
14
  /** Loader-safe configuration for the shared Runtime and per-Workspace bindings. */
14
- export interface Config extends MarivoPythonOptions {
15
+ export interface Config extends PythonTimeoutConfig {
15
16
  readonly reportPublishing?: ReportPublishingConfig;
16
17
  /** Non-secret creation defaults by backend; checked against each live Runtime schema. */
17
18
  readonly datasourceDefaults?: DatasourceDefaults;
@@ -28,6 +29,28 @@ export interface Config extends MarivoPythonOptions {
28
29
  readonly installTimeoutMs?: number;
29
30
  }
30
31
  /** Cordis loader schema. Runtime defaults are resolved in {@link apply}. */
31
- export declare const Config: z<Config>;
32
+ export declare const Config: z<Schemastery.ObjectS<NoInfer<{
33
+ datasourceDefaults: z<any, any, "plain">;
34
+ reportPublishing: z<any, any, "plain">;
35
+ pythonTimeoutMs: z<number, number, "volatile-defined">;
36
+ credentialInteraction: z<"none" | "web", "none" | "web", "defined">;
37
+ projectRoot: z<string, string, "plain">;
38
+ pythonExecutable: z<string, string, "plain">;
39
+ runtimeRoot: z<string, string, "plain">;
40
+ bootstrapPythonExecutable: z<string, string, "plain">;
41
+ installTimeoutMs: z<number, number, "defined">;
42
+ }>>, Schemastery.ObjectT<NoInfer<{
43
+ datasourceDefaults: z<any, any, "plain">;
44
+ reportPublishing: z<any, any, "plain">;
45
+ pythonTimeoutMs: z<number, number, "volatile-defined">;
46
+ credentialInteraction: z<"none" | "web", "none" | "web", "defined">;
47
+ projectRoot: z<string, string, "plain">;
48
+ pythonExecutable: z<string, string, "plain">;
49
+ runtimeRoot: z<string, string, "plain">;
50
+ bootstrapPythonExecutable: z<string, string, "plain">;
51
+ installTimeoutMs: z<number, number, "defined">;
52
+ }>>, "plain">;
32
53
  /** Ensure the shared Runtime once, mount its skills, then bind each Workspace lazily. */
33
54
  export declare function apply(ctx: Context, config?: Config): Promise<() => Promise<void>>;
55
+ /** Compose an extension at the public seam while retaining the ordinary plugin behavior. */
56
+ export declare function applyWithIntegration(ctx: Context, config?: Config, integration?: MarivoIntegrationV1): Promise<() => Promise<void>>;
@@ -0,0 +1,5 @@
1
+ /** Report-specific wall-clock budgets; leave time after source reads for publication. */
2
+ export declare const PRESENTATION_EXECUTION_BUDGETS: Readonly<{
3
+ sourceReadTimeoutMs: 120000;
4
+ toolTimeoutMs: 180000;
5
+ }>;
@@ -1,3 +1,3 @@
1
1
  /** Dedicated plugin RPC envelopes over Harness-owned authenticated exact Fetch routes. */
2
- import { type ConnectionRpcHandler, type HostConnectionHandle } from '@deepseek-ai/dsh-client-connection';
3
- export declare function registerPluginRpc(connection: Pick<HostConnectionHandle, 'fetch'>, channel: string, endpoints: readonly string[], handler: ConnectionRpcHandler): () => Promise<void>;
2
+ import { type ConnectionRpcHandlerResult, type HostConnectionHandle } from '@deepseek-ai/dsh-client-connection';
3
+ export declare function registerPluginRpc(connection: Pick<HostConnectionHandle, 'fetch'>, channel: string, endpoints: readonly string[], handler: (endpoint: string, payload: unknown, signal: AbortSignal) => Promise<ConnectionRpcHandlerResult>): () => Promise<void>;
@@ -1,4 +1,4 @@
1
- import type { ConnectionRpcHandler, HostConnectionHandle } from '@deepseek-ai/dsh-client-connection';
1
+ import type { ConnectionRpcHandlerResult, HostConnectionHandle } from '@deepseek-ai/dsh-client-connection';
2
2
  import type { MarivoCheckedRunner } from '../environment/types.ts';
3
3
  import { SemanticReferenceBridge } from './bridge.ts';
4
4
  import { type SemanticReferenceUsage } from './usage.ts';
@@ -12,4 +12,4 @@ export declare class SemanticReferenceService {
12
12
  stop(): void;
13
13
  close(): Promise<void>;
14
14
  }
15
- export declare function registerSemanticReferenceRpc(connection: HostConnectionHandle, service: SemanticReferenceService, browser?: ConnectionRpcHandler): () => Promise<void>;
15
+ export declare function registerSemanticReferenceRpc(connection: HostConnectionHandle, service: SemanticReferenceService, browser?: (endpoint: string, payload: unknown, signal: AbortSignal) => Promise<ConnectionRpcHandlerResult>): () => Promise<void>;
@@ -1,14 +1,14 @@
1
1
  import type { Context } from '@deepseek-ai/cordis';
2
- import z from '@deepseek-ai/schemastery';
3
2
  import { type MarivoPythonOptions } from './datasource/python-options.ts';
4
3
  export declare const PYTHON_SETTINGS_NAMESPACE = "dsh-data-analysis";
5
- export declare const PythonSettings: z<Schemastery.ObjectS<{
6
- pythonTimeoutMs: z<number, number>;
7
- }>, Schemastery.ObjectT<{
8
- pythonTimeoutMs: z<number, number>;
9
- }>>;
10
- /** Follow the Host settings provider; headless compositions retain their entry configuration. */
11
- export declare function installPythonSettings(ctx: Context, options: MarivoPythonOptions): {
4
+ export interface PythonTimeoutConfig {
5
+ pythonTimeoutMs?: number | {
6
+ get(): number;
7
+ };
8
+ }
9
+ export declare function currentPythonOptions(options: PythonTimeoutConfig): Required<MarivoPythonOptions>;
10
+ /** Config is projected by the Host settings service; a headless composition reads its live entry. */
11
+ export declare function installPythonSettings(ctx: Context, options: PythonTimeoutConfig): {
12
12
  get: () => Required<MarivoPythonOptions>;
13
13
  dispose: () => Promise<void>;
14
14
  };