@chengxianglibra/dsh-data-analysis 0.3.0 → 0.3.1

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 (53) hide show
  1. package/README.en.md +7 -2
  2. package/README.md +7 -2
  3. package/assets/logo-horizontal.svg +42 -0
  4. package/assets/logo-mark.svg +20 -0
  5. package/lib/bin/environment.js +99 -76
  6. package/lib/client/analysis-ui/offline-runtime.generated.js +1 -1
  7. package/lib/client/credentials/install.js +42 -38
  8. package/lib/client/credentials/model.js +9 -0
  9. package/lib/client/credentials/report-publishing.js +84 -0
  10. package/lib/client/credentials/styles.js +2 -0
  11. package/lib/client/i18n/credentials.js +18 -0
  12. package/lib/client/i18n/presentation.js +24 -0
  13. package/lib/client/right-tabs/install.js +9 -1
  14. package/lib/client/right-tabs/report-actions.js +30 -4
  15. package/lib/client/right-tabs/report-publishing.js +107 -0
  16. package/lib/client/right-tabs/styles.js +3 -0
  17. package/lib/client/ui/styles.generated.js +3 -0
  18. package/lib/client-composition.js +202 -191
  19. package/lib/client.js +205 -194
  20. package/lib/datasource/resolver-program.js +4 -4
  21. package/lib/environment/binding.js +16 -23
  22. package/lib/environment/doctor.js +8 -1
  23. package/lib/environment/identity.js +32 -0
  24. package/lib/environment/project-preparation.js +5 -5
  25. package/lib/environment/runtime.js +15 -16
  26. package/lib/plugin-agents.js +6 -1
  27. package/lib/plugin.js +18 -0
  28. package/lib/presentation/rpc.js +19 -0
  29. package/lib/report-publishing/adapters.js +136 -0
  30. package/lib/report-publishing/config.js +58 -0
  31. package/lib/report-publishing/credential-contract.js +25 -0
  32. package/lib/report-publishing/service.js +133 -0
  33. package/lib/skill-build.generated.js +2 -2
  34. package/lib/types/client/credentials/install.d.ts +2 -1
  35. package/lib/types/client/credentials/model.d.ts +30 -0
  36. package/lib/types/client/credentials/report-publishing.d.ts +5 -0
  37. package/lib/types/client/credentials/styles.d.ts +1 -1
  38. package/lib/types/client/i18n/copy.d.ts +21 -0
  39. package/lib/types/client/i18n/credentials.d.ts +18 -0
  40. package/lib/types/client/i18n/presentation.d.ts +24 -0
  41. package/lib/types/client/right-tabs/report-actions.d.ts +5 -1
  42. package/lib/types/client/right-tabs/report-publishing.d.ts +21 -0
  43. package/lib/types/client/right-tabs/styles.d.ts +1 -1
  44. package/lib/types/environment/identity.d.ts +6 -0
  45. package/lib/types/plugin-agents.d.ts +2 -0
  46. package/lib/types/plugin.d.ts +4 -0
  47. package/lib/types/presentation/rpc.d.ts +1358 -0
  48. package/lib/types/report-publishing/adapters.d.ts +6 -0
  49. package/lib/types/report-publishing/config.d.ts +23 -0
  50. package/lib/types/report-publishing/credential-contract.d.ts +61 -0
  51. package/lib/types/report-publishing/service.d.ts +31 -0
  52. package/package.json +4 -1
  53. package/skills/dsh-data-analysis-files/references/delivery.md +3 -1
@@ -0,0 +1,133 @@
1
+ import { createHash, randomUUID } from 'node:crypto';
2
+ import { credentialRef } from '@deepseek-ai/dsh-credentials';
3
+ import { publishingFields, } from "./credential-contract.js";
4
+ function pathName(value, fallback) {
5
+ const name = Array.from(value.normalize('NFKC').replace(/[^\p{L}\p{N}_-]+/gu, '-'))
6
+ .slice(0, 48)
7
+ .join('')
8
+ .replace(/^-+|-+$/g, '');
9
+ return name || fallback;
10
+ }
11
+ export class ReportPublishingService {
12
+ configId = randomUUID();
13
+ #config;
14
+ #store;
15
+ #files;
16
+ #workspaceName;
17
+ constructor(config, store, files, workspaceName) {
18
+ this.#config = config;
19
+ this.#store = store;
20
+ this.#files = files;
21
+ this.#workspaceName = workspaceName;
22
+ }
23
+ assertConfig(configId) {
24
+ if (configId !== this.configId)
25
+ throw new Error('report-publishing-config-changed');
26
+ }
27
+ async describe() {
28
+ const fields = await Promise.all(publishingFields.flatMap((field) => {
29
+ const reference = this.#config.storage[`${field}Ref`];
30
+ if (reference === undefined)
31
+ return [];
32
+ return [
33
+ this.#store.describe(credentialRef(reference)).then((info) => ({
34
+ field,
35
+ reference,
36
+ required: true,
37
+ configured: info.configured,
38
+ writable: info.writable,
39
+ ...(info.source ? { source: info.source } : {}),
40
+ })),
41
+ ];
42
+ }));
43
+ return {
44
+ enabled: true,
45
+ configId: this.configId,
46
+ name: this.#config.storage.name,
47
+ bucket: this.#config.storage.bucket,
48
+ fields,
49
+ };
50
+ }
51
+ async change(field, value, signal) {
52
+ const reference = this.#config.storage[`${field}Ref`];
53
+ if (reference === undefined)
54
+ throw new Error('report-publishing-disabled-or-field-unavailable');
55
+ signal.throwIfAborted();
56
+ if (value === undefined)
57
+ await this.#store.unset(credentialRef(reference));
58
+ else
59
+ await this.#store.set(credentialRef(reference), value);
60
+ }
61
+ async publish(scope, ref, caller) {
62
+ const signal = AbortSignal.any([caller, AbortSignal.timeout(110_000)]);
63
+ const { workspaceId, reportId, buildId } = ref;
64
+ const document = await this.#files.readSavedReport(scope, ref, signal);
65
+ const { exportAnalysisHtml } = await import("../client/analysis-ui/offline-export.js");
66
+ const bytes = Buffer.from(exportAnalysisHtml(document), 'utf8');
67
+ const sha256 = createHash('sha256').update(bytes).digest('hex');
68
+ const publicationId = createHash('sha256')
69
+ .update(JSON.stringify([workspaceId, reportId, buildId, sha256]))
70
+ .digest('hex')
71
+ .slice(0, 32);
72
+ const { pathPrefix, publicBaseUrl, storage } = this.#config;
73
+ const key = [
74
+ pathPrefix,
75
+ pathName(this.#workspaceName(workspaceId), 'workspace'),
76
+ pathName(document.title, 'report'),
77
+ publicationId,
78
+ 'index.html',
79
+ ]
80
+ .filter(Boolean)
81
+ .join('/');
82
+ const { S3Client, PutObjectCommand } = await import('@aws-sdk/client-s3');
83
+ const accessKeyId = await this.#resolveCredential(storage.accessKeyIdRef, signal);
84
+ const secretAccessKey = await this.#resolveCredential(storage.secretAccessKeyRef, signal);
85
+ const sessionToken = storage.sessionTokenRef === undefined
86
+ ? undefined
87
+ : await this.#resolveCredential(storage.sessionTokenRef, signal);
88
+ signal.throwIfAborted();
89
+ const client = new S3Client({
90
+ endpoint: storage.endpoint,
91
+ region: storage.region,
92
+ forcePathStyle: storage.forcePathStyle,
93
+ credentials: { accessKeyId, secretAccessKey, sessionToken },
94
+ maxAttempts: 3,
95
+ requestChecksumCalculation: 'WHEN_REQUIRED',
96
+ });
97
+ try {
98
+ await client.send(new PutObjectCommand({
99
+ Bucket: storage.bucket,
100
+ Key: key,
101
+ Body: bytes,
102
+ ContentType: 'text/html; charset=utf-8',
103
+ ContentDisposition: 'inline',
104
+ CacheControl: 'public, max-age=31536000, immutable',
105
+ }), { abortSignal: signal });
106
+ }
107
+ catch {
108
+ throw new Error('report-publishing-upload-unconfirmed');
109
+ }
110
+ finally {
111
+ client.destroy();
112
+ }
113
+ return {
114
+ storage: storage.name,
115
+ bucket: storage.bucket,
116
+ key,
117
+ url: `${publicBaseUrl.replace(/\/+$/, '')}/${key.split('/').map(encodeURIComponent).join('/')}`,
118
+ workspaceId,
119
+ reportId,
120
+ buildId,
121
+ sha256,
122
+ bytes: bytes.length,
123
+ publishedAt: new Date().toISOString(),
124
+ };
125
+ }
126
+ async #resolveCredential(reference, signal) {
127
+ signal.throwIfAborted();
128
+ const result = await this.#store.resolve(credentialRef(reference));
129
+ if (!result?.value)
130
+ throw new Error('report-publishing-credentials-missing');
131
+ return result.value;
132
+ }
133
+ }
@@ -1,6 +1,6 @@
1
1
  export const packagedSkillBuild = {
2
2
  "schema": "dsh-data-analysis-skills/v1",
3
- "digest": "fff651d8aca73eaf4a855e13a1a42ac6a271b7a0aa73baee03d83a01d4bfbc27",
3
+ "digest": "8826de1c36384d33c07b611c8f7244abbef18ad1d1facde9a45b096c745bbbb7",
4
4
  "files": [
5
5
  {
6
6
  "path": "dsh-data-analysis-files/SKILL.md",
@@ -8,7 +8,7 @@ export const packagedSkillBuild = {
8
8
  },
9
9
  {
10
10
  "path": "dsh-data-analysis-files/references/delivery.md",
11
- "sha256": "bcc03e13a013fb081050a95d0da71ba12eba32569e37b3fcaee3c7c694f21637"
11
+ "sha256": "60b2eb892c17410b431477976ee504894ef9f60fe82938ddfcecf963be562728"
12
12
  },
13
13
  {
14
14
  "path": "dsh-data-analysis-files/references/examples.md",
@@ -7,9 +7,10 @@ export declare function CredentialIcon({ name, size }: {
7
7
  export declare function DatasourceProperties({ context }: {
8
8
  context: any;
9
9
  }): import("react").JSX.Element;
10
- export declare function CredentialPanel({ model, workspaces, onRefresh }: {
10
+ export declare function CredentialPanel({ model, workspaces, onRefresh, initialSection }: {
11
11
  model: any;
12
12
  workspaces: any;
13
13
  onRefresh: any;
14
+ initialSection?: string | undefined;
14
15
  }): import("react").JSX.Element | null;
15
16
  export declare function installCredentials(ctx: any, rpc: any, changes?: CredentialChanges): CredentialClientModel;
@@ -1,4 +1,5 @@
1
1
  import type { CredentialAction, CredentialContextView, CredentialOperationView, CredentialRequestView } from '../../datasource/service.ts';
2
+ import { type PublishingField } from '../../report-publishing/credential-contract.ts';
2
3
  import { type Notice } from './../i18n/copy.ts';
3
4
  import type { BrowserRpc } from '../semantic-browser/model.ts';
4
5
  import type { CredentialChanges } from './changes.ts';
@@ -7,6 +8,18 @@ interface QueryHandle {
7
8
  id: string;
8
9
  scope: string;
9
10
  }
11
+ export type PublishingCredentialRequest = {
12
+ endpoint: 'describe';
13
+ } | {
14
+ endpoint: 'set';
15
+ configId: string;
16
+ field: PublishingField;
17
+ value: string;
18
+ } | {
19
+ endpoint: 'unset';
20
+ configId: string;
21
+ field: PublishingField;
22
+ };
10
23
  export interface ClientOperation {
11
24
  handle: QueryHandle;
12
25
  name: string;
@@ -38,6 +51,23 @@ export declare class CredentialClientModel {
38
51
  constructor(rpc: BrowserRpc, storage?: Pick<Storage, 'getItem' | 'setItem' | 'removeItem'>, changes?: CredentialChanges);
39
52
  getSnapshot: () => CredentialClientState;
40
53
  subscribe: (listener: () => void) => (() => void);
54
+ publishingCredentials(workspaceId: string, { endpoint, ...input }: PublishingCredentialRequest, signal: AbortSignal): Promise<{
55
+ enabled: false;
56
+ fields: [];
57
+ } | {
58
+ enabled: true;
59
+ configId: string;
60
+ name: string;
61
+ bucket: string;
62
+ fields: {
63
+ field: "accessKeyId" | "secretAccessKey" | "sessionToken";
64
+ reference: string;
65
+ required: boolean;
66
+ configured: boolean;
67
+ writable: boolean;
68
+ source?: string | undefined;
69
+ }[];
70
+ }>;
41
71
  show(workspaceId: string, selectedToken?: string): Promise<void>;
42
72
  close(): void;
43
73
  suspend(): void;
@@ -0,0 +1,5 @@
1
+ import type { CredentialClientModel } from './model.ts';
2
+ export declare function ReportPublishingCredentials({ model, workspaceId, }: {
3
+ model: CredentialClientModel;
4
+ workspaceId: string;
5
+ }): import("react").JSX.Element;
@@ -1,2 +1,2 @@
1
1
  /** Datasource arrangement and saved-property reading; controls use shadcn primitives. */
2
- export declare const credentialStyles = "\n.mc-panel{min-width:0;width:100%;container-type:inline-size;--mc-accent:var(--dsw-alias-state-business-primary,#075bea)}\n.mc-shell,.mc-columns,.mc-main,.mc-form{display:flex;flex-direction:column;min-width:0}\n.mc-shell,.mc-columns,.mc-form-body{gap:1.5rem}\n.mc-form{gap:1rem;flex:1}\n.mc-form-body{display:flex;flex-direction:column;flex:1}\n.mc-detail-heading,.mc-name-row,.mc-heading-actions,.mc-field-header,.mc-field-actions,.mc-request-heading,.mc-progress{display:flex;align-items:center;flex-wrap:wrap;gap:.75rem;min-width:0}\n.mc-detail-heading,.mc-name-row,.mc-field-header{justify-content:space-between}\n.mc-name-row{width:100%}\n.mc-identity{display:flex;align-items:flex-start;gap:1rem;flex:1 1 180px;min-width:0}\n.mc-identity-icon{width:3.375rem;height:3.375rem;display:grid;place-items:center;flex:none;background:var(--muted);border-radius:.625rem}\n.mc-identity-copy{min-width:0}\n.mc-identity-title{display:flex;align-items:center;flex-wrap:wrap;gap:.5rem;min-width:0}\n.mc-identity-title [data-slot=card-title]{min-width:0;max-width:100%}\n.mc-heading-actions{flex:none}\n.mc-detail-heading{margin-bottom:.5rem}\n.mc-detail-heading h3{margin:0;font-size:1.25rem;line-height:1.4;font-weight:600;overflow-wrap:anywhere}\n.mc-datasource-heading [data-slot=card-title]{font-size:1.5rem;line-height:1.2;font-weight:700;letter-spacing:-.025em;overflow-wrap:anywhere}\n.mc-nav{min-width:0}\n.mc-nav-heading{margin-bottom:.75rem;color:var(--muted-foreground);font-size:.875rem}\n.mc-nav-heading h3{font:inherit;margin:0}\n.mc-datasources{width:100%;max-width:100%;height:auto;justify-content:flex-start;overflow-x:auto;border-bottom:1px solid var(--border);border-radius:0;padding:0;gap:.25rem}\n.mc-datasources .mc-datasource{min-width:0;max-width:min(16rem,100%);flex:0 0 auto;border-radius:0;padding:.75rem 1.25rem;font-size:.9375rem;background:transparent;color:var(--muted-foreground);box-shadow:none;transition:none}\n.mc-datasources .mc-datasource[aria-selected=true]{color:var(--mc-accent)}\n.mc-datasources .mc-datasource::after{background:var(--mc-accent);bottom:0;opacity:0;transition:none}\n.mc-datasources .mc-datasource[aria-selected=true]::after{opacity:1}\n.mc-datasources .mc-datasource:focus-visible{outline:2px solid var(--ring);outline-offset:-2px}\n.mc-datasource>svg{flex:none}\n.mc-datasource-copy{min-width:0;display:flex;align-items:center;gap:.375rem}\n.mc-datasource-name{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n.mc-visually-hidden{position:absolute;left:0;top:0;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}\n.mc-dot{width:6px;height:6px;background:var(--muted-foreground);border-radius:50%;flex:none}\n.mc-dot[data-ready=true]{background:var(--mv-success)}\n.mc-dot[data-ready=false]{background:var(--destructive)}\n.mc-properties,.mc-fields{min-width:0}\n.mc-datasource-detail .mc-properties,.mc-datasource-detail .mc-fields{gap:1rem;padding:0;background:transparent;box-shadow:none;border-radius:0;overflow:visible}\n.mc-datasource-detail .mc-properties>[data-slot=card-header],.mc-datasource-detail .mc-properties>[data-slot=card-content],.mc-datasource-detail .mc-fields>[data-slot=card-content]{padding:0}\n.mc-credential-section{display:flex;flex-direction:column;gap:1rem;min-width:0;padding-top:1.5rem;border-top:1px solid var(--border)}\n.mc-section-heading{display:flex;align-items:center;gap:.625rem;min-width:0;margin:0;font-size:1.125rem;line-height:1.4;font-weight:700}\n.mc-section-heading>svg{width:1.125rem;height:1.125rem;flex:none}\n.mc-fields>[data-slot=card-content]>.mc-field+.mc-field{border-top:1px solid var(--border);padding-top:1rem;margin-top:1rem}\n.mc-property-list{margin:0;min-width:0}\n.mc-property{display:grid;grid-template-columns:minmax(0,140px) minmax(0,1fr);gap:1rem;padding:.75rem 0}\n.mc-property+.mc-property{border-top:1px solid var(--border)}\n.mc-property dt{color:var(--muted-foreground);font-weight:500;overflow-wrap:anywhere}\n.mc-property dd{margin:0;min-width:0;white-space:pre-wrap;overflow-wrap:anywhere}\n.mc-property pre{font-family:var(--mv-font-mono,ui-monospace,monospace);tab-size:4;white-space:pre-wrap;overflow-wrap:anywhere;margin:0}\n.mc-property-json{max-height:240px;overflow:auto}\n.mc-field{min-width:0;margin:0;border:0;padding:0;display:flex;flex-direction:column;gap:1rem}\n\n.mc-field-title{min-width:0;overflow-wrap:anywhere}\n.mc-field-title h4,.mc-field-title p{margin:0}\n.mc-field-title p,.mc-field-note,.mc-note,.mc-eyebrow{color:var(--muted-foreground);font-size:.875rem;overflow-wrap:anywhere}\n.mc-eyebrow{margin:0}\n.mc-confirm{margin-top:.75rem}\n.mc-result-title{display:flex;align-items:center;gap:.5rem}\n.mc-result pre{white-space:pre-wrap;overflow-wrap:anywhere;max-height:180px;overflow:auto}\n.mc-form-footer{display:flex;align-items:center;flex-wrap:wrap;gap:.5rem}\n.mc-form-footer .mc-cancel{margin-left:auto}\n.mc-requests,.mc-activity-list{display:flex;align-items:center;gap:.5rem;flex-wrap:wrap}\n.mc-request-status,.mc-operation-note{overflow-wrap:anywhere}\n.mc-reference-options summary{cursor:pointer}\n.mc-credential-entry,.mc-credential-group,.mc-existing-source,.mc-inline-credentials{display:flex;flex-direction:column;gap:1rem;min-width:0}\n.mc-reference-options{min-width:0}\n.mc-timezone-control{display:flex;gap:.375rem;align-items:center}\n.mc-timezone-control input{flex:1;min-width:0}\n.mc-timezone-popover{display:grid;gap:.625rem;max-width:calc(100vw - 2rem)}\n.mc-timezone-select{width:100%;min-width:0;max-height:15rem;border:1px solid var(--border);border-radius:var(--radius);background:var(--background);color:var(--foreground);font:inherit}\n.mc-timezone-select:focus-visible{outline:2px solid var(--ring);outline-offset:2px}\n.mc-engine-confirm{margin-top:.5rem}\n.mc-scoped-actions{display:flex;flex-wrap:wrap;gap:.5rem}\n.mc-activity{display:flex;flex-direction:column;gap:.75rem}\n.mc-activity-heading{margin:0;color:var(--muted-foreground);font-size:.875rem}\n.mc-progress button{margin-left:auto}\n.mc-empty{margin:auto}\n@container(max-width:650px){.mc-name-row>.mc-heading-actions{width:100%}.mc-property{grid-template-columns:minmax(0,1fr);gap:.375rem}.mc-field-actions{margin-left:auto}}\n";
2
+ export declare const credentialStyles = "\n.mc-panel{min-width:0;width:100%;container-type:inline-size;--mc-accent:var(--dsw-alias-state-business-primary,#075bea)}\n.mc-shell,.mc-columns,.mc-main,.mc-form{display:flex;flex-direction:column;min-width:0}\n.mc-directory-content{min-width:0}\n.mc-directory-content>.mc-requests{margin-bottom:1rem}\n.mc-shell,.mc-columns,.mc-form-body{gap:1.5rem}\n.mc-form{gap:1rem;flex:1}\n.mc-form-body{display:flex;flex-direction:column;flex:1}\n.mc-detail-heading,.mc-name-row,.mc-heading-actions,.mc-field-header,.mc-field-actions,.mc-request-heading,.mc-progress{display:flex;align-items:center;flex-wrap:wrap;gap:.75rem;min-width:0}\n.mc-detail-heading,.mc-name-row,.mc-field-header{justify-content:space-between}\n.mc-name-row{width:100%}\n.mc-identity{display:flex;align-items:flex-start;gap:1rem;flex:1 1 180px;min-width:0}\n.mc-identity-icon{width:3.375rem;height:3.375rem;display:grid;place-items:center;flex:none;background:var(--muted);border-radius:.625rem}\n.mc-identity-copy{min-width:0}\n.mc-identity-title{display:flex;align-items:center;flex-wrap:wrap;gap:.5rem;min-width:0}\n.mc-identity-title [data-slot=card-title]{min-width:0;max-width:100%}\n.mc-heading-actions{flex:none}\n.mc-detail-heading{margin-bottom:.5rem}\n.mc-detail-heading h3{margin:0;font-size:1.25rem;line-height:1.4;font-weight:600;overflow-wrap:anywhere}\n.mc-datasource-heading [data-slot=card-title]{font-size:1.5rem;line-height:1.2;font-weight:700;letter-spacing:-.025em;overflow-wrap:anywhere}\n.mc-nav{min-width:0}\n.mc-nav-heading{margin-bottom:.75rem;color:var(--muted-foreground);font-size:.875rem}\n.mc-nav-heading h3{font:inherit;margin:0}\n.mc-datasources{width:100%;max-width:100%;height:auto;justify-content:flex-start;overflow-x:auto;border-bottom:1px solid var(--border);border-radius:0;padding:0;gap:.25rem}\n.mc-datasources .mc-datasource{min-width:0;max-width:min(16rem,100%);flex:0 0 auto;border-radius:0;padding:.75rem 1.25rem;font-size:.9375rem;background:transparent;color:var(--muted-foreground);box-shadow:none;transition:none}\n.mc-datasources .mc-datasource[aria-selected=true]{color:var(--mc-accent)}\n.mc-datasources .mc-datasource::after{background:var(--mc-accent);bottom:0;opacity:0;transition:none}\n.mc-datasources .mc-datasource[aria-selected=true]::after{opacity:1}\n.mc-datasources .mc-datasource:focus-visible{outline:2px solid var(--ring);outline-offset:-2px}\n.mc-datasource>svg{flex:none}\n.mc-datasource-copy{min-width:0;display:flex;align-items:center;gap:.375rem}\n.mc-datasource-name{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n.mc-visually-hidden{position:absolute;left:0;top:0;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}\n.mc-dot{width:6px;height:6px;background:var(--muted-foreground);border-radius:50%;flex:none}\n.mc-dot[data-ready=true]{background:var(--mv-success)}\n.mc-dot[data-ready=false]{background:var(--destructive)}\n.mc-properties,.mc-fields{min-width:0}\n.mc-datasource-detail .mc-properties,.mc-datasource-detail .mc-fields{gap:1rem;padding:0;background:transparent;box-shadow:none;border-radius:0;overflow:visible}\n.mc-datasource-detail .mc-properties>[data-slot=card-header],.mc-datasource-detail .mc-properties>[data-slot=card-content],.mc-datasource-detail .mc-fields>[data-slot=card-content]{padding:0}\n.mc-credential-section{display:flex;flex-direction:column;gap:1rem;min-width:0;padding-top:1.5rem;border-top:1px solid var(--border)}\n.mc-section-heading{display:flex;align-items:center;gap:.625rem;min-width:0;margin:0;font-size:1.125rem;line-height:1.4;font-weight:700}\n.mc-section-heading>svg{width:1.125rem;height:1.125rem;flex:none}\n.mc-fields>[data-slot=card-content]>.mc-field+.mc-field{border-top:1px solid var(--border);padding-top:1rem;margin-top:1rem}\n.mc-property-list{margin:0;min-width:0}\n.mc-property{display:grid;grid-template-columns:minmax(0,140px) minmax(0,1fr);gap:1rem;padding:.75rem 0}\n.mc-property+.mc-property{border-top:1px solid var(--border)}\n.mc-property dt{color:var(--muted-foreground);font-weight:500;overflow-wrap:anywhere}\n.mc-property dd{margin:0;min-width:0;white-space:pre-wrap;overflow-wrap:anywhere}\n.mc-property pre{font-family:var(--mv-font-mono,ui-monospace,monospace);tab-size:4;white-space:pre-wrap;overflow-wrap:anywhere;margin:0}\n.mc-property-json{max-height:240px;overflow:auto}\n.mc-field{min-width:0;margin:0;border:0;padding:0;display:flex;flex-direction:column;gap:1rem}\n\n.mc-field-title{min-width:0;overflow-wrap:anywhere}\n.mc-field-title h4,.mc-field-title p{margin:0}\n.mc-field-title p,.mc-field-note,.mc-note,.mc-eyebrow{color:var(--muted-foreground);font-size:.875rem;overflow-wrap:anywhere}\n.mc-eyebrow{margin:0}\n.mc-confirm{margin-top:.75rem}\n.mc-result-title{display:flex;align-items:center;gap:.5rem}\n.mc-result pre{white-space:pre-wrap;overflow-wrap:anywhere;max-height:180px;overflow:auto}\n.mc-form-footer{display:flex;align-items:center;flex-wrap:wrap;gap:.5rem}\n.mc-form-footer .mc-cancel{margin-left:auto}\n.mc-requests,.mc-activity-list{display:flex;align-items:center;gap:.5rem;flex-wrap:wrap}\n.mc-request-status,.mc-operation-note{overflow-wrap:anywhere}\n.mc-reference-options summary{cursor:pointer}\n.mc-credential-entry,.mc-credential-group,.mc-existing-source,.mc-inline-credentials{display:flex;flex-direction:column;gap:1rem;min-width:0}\n.mc-reference-options{min-width:0}\n.mc-timezone-control{display:flex;gap:.375rem;align-items:center}\n.mc-timezone-control input{flex:1;min-width:0}\n.mc-timezone-popover{display:grid;gap:.625rem;max-width:calc(100vw - 2rem)}\n.mc-timezone-select{width:100%;min-width:0;max-height:15rem;border:1px solid var(--border);border-radius:var(--radius);background:var(--background);color:var(--foreground);font:inherit}\n.mc-timezone-select:focus-visible{outline:2px solid var(--ring);outline-offset:2px}\n.mc-engine-confirm{margin-top:.5rem}\n.mc-scoped-actions{display:flex;flex-wrap:wrap;gap:.5rem}\n.mc-activity{display:flex;flex-direction:column;gap:.75rem}\n.mc-activity-heading{margin:0;color:var(--muted-foreground);font-size:.875rem}\n.mc-progress button{margin-left:auto}\n.mc-empty{margin:auto}\n@container(max-width:650px){.mc-name-row>.mc-heading-actions{width:100%}.mc-property{grid-template-columns:minmax(0,1fr);gap:.375rem}.mc-field-actions{margin-left:auto}}\n";
@@ -489,6 +489,18 @@ export declare const zh: {
489
489
  'marivo.presentation.export-html-started': "HTML 下载已开始。";
490
490
  'marivo.presentation.export-html-failed': "导出失败,请重试。";
491
491
  'marivo.presentation.export-html-dismiss': "关闭导出提示";
492
+ 'marivo.presentation.report-delivery-checking': "正在读取导出设置…";
493
+ 'marivo.presentation.report-delivery-unavailable': "导出设置不可用,重新打开菜单重试";
494
+ 'marivo.presentation.publish-report': "发布到对象存储";
495
+ 'marivo.presentation.publishing-report': "正在发布…";
496
+ 'marivo.presentation.publish-report-success': "报告已上传到对象存储。";
497
+ 'marivo.presentation.publish-report-credentials-missing': "缺少发布凭据。补齐后可重新发布。";
498
+ 'marivo.presentation.publish-report-config-changed': "发布配置已变更,请重新打开菜单。";
499
+ 'marivo.presentation.publish-report-unconfirmed': "上传结果未确认,请检查对象存储或重试。";
500
+ 'marivo.presentation.publish-report-failed': "无法发布报告,请重试。";
501
+ 'marivo.presentation.open-published-report': "查看已发布报告";
502
+ 'marivo.presentation.open-publishing-credentials': "前往凭证管理";
503
+ 'marivo.presentation.publish-report-dismiss': "关闭发布提示";
492
504
  'marivo.presentation.ui-open-tab': "在右侧打开分析视图";
493
505
  'marivo.presentation.ui-loading': "正在读取已保存快照…";
494
506
  'marivo.presentation.ui-preparing': "正在准备分析视图…";
@@ -575,6 +587,15 @@ export declare const zh: {
575
587
  'marivo.navigation.cannot-verify-the-new-version': "无法核验新版本";
576
588
  'marivo.navigation.report-identity-changed': "分析视图身份已变化";
577
589
  'marivo.navigation.open-value': "打开{p0}";
590
+ 'marivo.credentials.datasources-tab': "数据源";
591
+ 'marivo.credentials.credential-management-tab': "凭证管理";
592
+ 'marivo.credentials.report-publishing-credentials': "报告发布凭证";
593
+ 'marivo.credentials.refresh-credential-status': "刷新凭证状态";
594
+ 'marivo.credentials.loading-publishing-credentials': "正在读取发布凭证状态…";
595
+ 'marivo.credentials.publishing-disabled': "当前 Host 尚未启用对象存储发布。";
596
+ 'marivo.credentials.publishing-config-changed': "发布配置已更新,请刷新状态后重新填写。";
597
+ 'marivo.credentials.publishing-credential-unconfirmed': "凭证操作结果未确认,请刷新状态后重试。";
598
+ 'marivo.credentials.delete-shared-publishing-credential': "删除 {p0} 的已保存值?当前 Host 中使用此引用的 Workspace 都会受到影响。";
578
599
  'marivo.credentials.basic-settings': "基本配置";
579
600
  'marivo.credentials.advanced-settings': "高级设置";
580
601
  'marivo.credentials.autocommit-required': "MySQL 和 PostgreSQL 仅支持默认或启用自动提交;请选择默认或 true。";
@@ -1,5 +1,14 @@
1
1
  /** Plugin-owned copy; keys are stable identifiers, never business labels. */
2
2
  export declare const zh: {
3
+ readonly 'marivo.credentials.datasources-tab': "数据源";
4
+ readonly 'marivo.credentials.credential-management-tab': "凭证管理";
5
+ readonly 'marivo.credentials.report-publishing-credentials': "报告发布凭证";
6
+ readonly 'marivo.credentials.refresh-credential-status': "刷新凭证状态";
7
+ readonly 'marivo.credentials.loading-publishing-credentials': "正在读取发布凭证状态…";
8
+ readonly 'marivo.credentials.publishing-disabled': "当前 Host 尚未启用对象存储发布。";
9
+ readonly 'marivo.credentials.publishing-config-changed': "发布配置已更新,请刷新状态后重新填写。";
10
+ readonly 'marivo.credentials.publishing-credential-unconfirmed': "凭证操作结果未确认,请刷新状态后重试。";
11
+ readonly 'marivo.credentials.delete-shared-publishing-credential': "删除 {p0} 的已保存值?当前 Host 中使用此引用的 Workspace 都会受到影响。";
3
12
  readonly 'marivo.credentials.basic-settings': "基本配置";
4
13
  readonly 'marivo.credentials.advanced-settings': "高级设置";
5
14
  readonly 'marivo.credentials.autocommit-required': "MySQL 和 PostgreSQL 仅支持默认或启用自动提交;请选择默认或 true。";
@@ -271,6 +280,15 @@ export declare const zh: {
271
280
  readonly 'marivo.credentials.save-failed': "保存配置失败。";
272
281
  };
273
282
  export declare const en: {
283
+ 'marivo.credentials.datasources-tab': string;
284
+ 'marivo.credentials.credential-management-tab': string;
285
+ 'marivo.credentials.report-publishing-credentials': string;
286
+ 'marivo.credentials.refresh-credential-status': string;
287
+ 'marivo.credentials.loading-publishing-credentials': string;
288
+ 'marivo.credentials.publishing-disabled': string;
289
+ 'marivo.credentials.publishing-config-changed': string;
290
+ 'marivo.credentials.publishing-credential-unconfirmed': string;
291
+ 'marivo.credentials.delete-shared-publishing-credential': string;
274
292
  'marivo.credentials.basic-settings': string;
275
293
  'marivo.credentials.advanced-settings': string;
276
294
  'marivo.credentials.autocommit-required': string;
@@ -162,6 +162,18 @@ export declare const zh: {
162
162
  readonly 'marivo.presentation.export-html-started': "HTML 下载已开始。";
163
163
  readonly 'marivo.presentation.export-html-failed': "导出失败,请重试。";
164
164
  readonly 'marivo.presentation.export-html-dismiss': "关闭导出提示";
165
+ readonly 'marivo.presentation.report-delivery-checking': "正在读取导出设置…";
166
+ readonly 'marivo.presentation.report-delivery-unavailable': "导出设置不可用,重新打开菜单重试";
167
+ readonly 'marivo.presentation.publish-report': "发布到对象存储";
168
+ readonly 'marivo.presentation.publishing-report': "正在发布…";
169
+ readonly 'marivo.presentation.publish-report-success': "报告已上传到对象存储。";
170
+ readonly 'marivo.presentation.publish-report-credentials-missing': "缺少发布凭据。补齐后可重新发布。";
171
+ readonly 'marivo.presentation.publish-report-config-changed': "发布配置已变更,请重新打开菜单。";
172
+ readonly 'marivo.presentation.publish-report-unconfirmed': "上传结果未确认,请检查对象存储或重试。";
173
+ readonly 'marivo.presentation.publish-report-failed': "无法发布报告,请重试。";
174
+ readonly 'marivo.presentation.open-published-report': "查看已发布报告";
175
+ readonly 'marivo.presentation.open-publishing-credentials': "前往凭证管理";
176
+ readonly 'marivo.presentation.publish-report-dismiss': "关闭发布提示";
165
177
  readonly 'marivo.presentation.ui-open-tab': "在右侧打开分析视图";
166
178
  readonly 'marivo.presentation.ui-loading': "正在读取已保存快照…";
167
179
  readonly 'marivo.presentation.ui-preparing': "正在准备分析视图…";
@@ -398,6 +410,18 @@ export declare const en: {
398
410
  'marivo.presentation.export-html-started': string;
399
411
  'marivo.presentation.export-html-failed': string;
400
412
  'marivo.presentation.export-html-dismiss': string;
413
+ 'marivo.presentation.report-delivery-checking': string;
414
+ 'marivo.presentation.report-delivery-unavailable': string;
415
+ 'marivo.presentation.publish-report': string;
416
+ 'marivo.presentation.publishing-report': string;
417
+ 'marivo.presentation.publish-report-success': string;
418
+ 'marivo.presentation.publish-report-credentials-missing': string;
419
+ 'marivo.presentation.publish-report-config-changed': string;
420
+ 'marivo.presentation.publish-report-unconfirmed': string;
421
+ 'marivo.presentation.publish-report-failed': string;
422
+ 'marivo.presentation.open-published-report': string;
423
+ 'marivo.presentation.open-publishing-credentials': string;
424
+ 'marivo.presentation.publish-report-dismiss': string;
401
425
  'marivo.presentation.ui-open-tab': string;
402
426
  'marivo.presentation.ui-loading': string;
403
427
  'marivo.presentation.ui-preparing': string;
@@ -1,9 +1,13 @@
1
1
  import type { AnalysisDocument } from '../../presentation/contracts/analysis-document.ts';
2
- export declare function ReportActions({ document, isCurrent, onHistory, refreshLocked, onRefreshData, onDelete, }: {
2
+ import type { BrowserRpc } from '../semantic-browser/model.ts';
3
+ export declare function ReportActions({ document, isCurrent, onHistory, refreshLocked, onRefreshData, onDelete, rpc, signal, onOpenPublishingCredentials, }: {
3
4
  document: AnalysisDocument;
4
5
  isCurrent: () => boolean;
5
6
  onHistory: () => void;
6
7
  refreshLocked: boolean;
7
8
  onRefreshData: (isCurrent: () => boolean) => Promise<'accepted' | 'stale' | 'unavailable' | 'failed' | 'uncertain'>;
8
9
  onDelete: (isCurrent: () => boolean) => Promise<'deleted' | 'cleanup-pending' | 'stale' | 'unavailable' | 'failed' | 'uncertain'>;
10
+ rpc: BrowserRpc;
11
+ signal: AbortSignal;
12
+ onOpenPublishingCredentials: () => void;
9
13
  }): import("react").JSX.Element;
@@ -0,0 +1,21 @@
1
+ import type { AnalysisDocument } from '../../presentation/contracts/analysis-document.ts';
2
+ import type { BrowserRpc } from '../semantic-browser/model.ts';
3
+ type PublishStatus = {
4
+ kind: 'working' | 'credentials-missing' | 'config-changed' | 'unconfirmed' | 'failed';
5
+ } | {
6
+ kind: 'success';
7
+ url: string;
8
+ };
9
+ export declare function useReportPublishing({ rpc, document, signal, isCurrent, }: {
10
+ rpc: BrowserRpc;
11
+ document: AnalysisDocument;
12
+ signal: AbortSignal;
13
+ isCurrent: () => boolean;
14
+ }): {
15
+ mode: "unavailable" | "publish" | "download" | "checking";
16
+ status: PublishStatus | undefined;
17
+ check: () => Promise<void>;
18
+ publish: () => Promise<void>;
19
+ dismiss: () => void;
20
+ };
21
+ export {};
@@ -1,2 +1,2 @@
1
1
  /** Content layout inside the native Host right-side tab. */
2
- export declare const rightTabStyles = "\n.rt-page{height:100%;width:100%;min-width:0;overflow:auto;padding:1rem;box-sizing:border-box;container-type:inline-size}\n.rt-heading-row{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:1rem;margin-bottom:.25rem}\n.rt-heading{margin:0;font-size:1.25rem;line-height:1.4;font-weight:600;overflow-wrap:anywhere}\n.rt-heading-row>button{flex:none}\n.rt-caption{color:var(--muted-foreground);font-size:.875rem;margin:0 0 1.5rem;overflow-wrap:anywhere}\n.rt-report-surface{position:relative;min-width:0}\n.rt-toolbar{position:absolute;top:1rem;right:1rem;z-index:1}\n.rt-report-surface:has(.rt-toolbar) .au-surface-content>:first-child:not(.au-surface-body),\n.rt-report-surface:has(.rt-toolbar) .au-surface-body:first-child>[aria-busy]>div>:not(.au-stack[data-direction=column]),\n.rt-report-surface:has(.rt-toolbar) .au-surface-body:first-child>[aria-busy]>div>.au-stack[data-direction=column]>:first-child{box-sizing:border-box;padding-right:3rem}\n.rt-actions-menu{z-index:100;min-width:13rem;max-width:min(22rem,calc(100vw - 2rem));padding:.35rem;border:1px solid var(--border);border-radius:var(--radius-lg);background:var(--popover);color:var(--popover-foreground);box-shadow:0 8px 24px #0002;font-size:.875rem}\n.rt-actions-item{padding:.5rem .65rem;border-radius:var(--radius-md);cursor:pointer;outline:none}\n.rt-actions-item[data-highlighted]{background:var(--accent);color:var(--accent-foreground)}\n.rt-actions-item[data-disabled]{opacity:.5;cursor:default}\n.rt-dialog-overlay{position:fixed;inset:0;background:#0008;z-index:200}\n.rt-dialog{position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);z-index:201;width:min(28rem,calc(100vw - 2rem));box-sizing:border-box;padding:1.25rem;border:1px solid var(--border);border-radius:var(--radius-lg);background:var(--popover);color:var(--popover-foreground);box-shadow:0 8px 24px #0003}\n.rt-dialog h2{font-size:1.1rem;font-weight:600;margin:0 0 .75rem}.rt-dialog p{margin:0;overflow-wrap:anywhere;line-height:1.5}\n.rt-dialog-actions{display:flex;justify-content:flex-end;gap:.5rem;margin-top:1.25rem}\n.rt-export-notice{position:absolute;top:calc(100% + .5rem);right:0;z-index:101;display:flex;align-items:center;gap:.5rem;width:max-content;max-width:min(22rem,calc(100vw - 2rem));box-sizing:border-box;padding:.75rem;border:1px solid var(--border);border-radius:var(--radius-lg);background:var(--popover);color:var(--popover-foreground);box-shadow:0 8px 24px #0002;font-size:.875rem;line-height:1.4}\n.rt-export-notice>svg{width:1rem;height:1rem;flex:none;color:var(--primary)}\n.rt-export-notice-error>svg{color:var(--destructive)}\n.rt-export-notice button{width:1.75rem;height:1.75rem;flex:none;margin:-.375rem -.375rem -.375rem 0}\n.rt-notice{display:flex;align-items:center;flex-wrap:wrap;gap:.75rem;margin-bottom:1rem}\n.rt-page .pd-catalog{padding:0;overflow:auto}\n.rt-page .pd-history{position:static;max-height:300px;margin-bottom:1rem;width:100%}\n";
2
+ export declare const rightTabStyles = "\n.rt-page{height:100%;width:100%;min-width:0;overflow:auto;padding:1rem;box-sizing:border-box;container-type:inline-size}\n.rt-heading-row{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:1rem;margin-bottom:.25rem}\n.rt-heading{margin:0;font-size:1.25rem;line-height:1.4;font-weight:600;overflow-wrap:anywhere}\n.rt-heading-row>button{flex:none}\n.rt-caption{color:var(--muted-foreground);font-size:.875rem;margin:0 0 1.5rem;overflow-wrap:anywhere}\n.rt-report-surface{position:relative;min-width:0}\n.rt-toolbar{position:absolute;top:1rem;right:1rem;z-index:1}\n.rt-report-surface:has(.rt-toolbar) .au-surface-content>:first-child:not(.au-surface-body),\n.rt-report-surface:has(.rt-toolbar) .au-surface-body:first-child>[aria-busy]>div>:not(.au-stack[data-direction=column]),\n.rt-report-surface:has(.rt-toolbar) .au-surface-body:first-child>[aria-busy]>div>.au-stack[data-direction=column]>:first-child{box-sizing:border-box;padding-right:3rem}\n.rt-actions-menu{z-index:100;min-width:13rem;max-width:min(22rem,calc(100vw - 2rem));padding:.35rem;border:1px solid var(--border);border-radius:var(--radius-lg);background:var(--popover);color:var(--popover-foreground);box-shadow:0 8px 24px #0002;font-size:.875rem}\n.rt-actions-item{padding:.5rem .65rem;border-radius:var(--radius-md);cursor:pointer;outline:none}\n.rt-actions-item[data-highlighted]{background:var(--accent);color:var(--accent-foreground)}\n.rt-actions-item[data-disabled]{opacity:.5;cursor:default}\n.rt-dialog-overlay{position:fixed;inset:0;background:#0008;z-index:200}\n.rt-dialog{position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);z-index:201;width:min(28rem,calc(100vw - 2rem));box-sizing:border-box;padding:1.25rem;border:1px solid var(--border);border-radius:var(--radius-lg);background:var(--popover);color:var(--popover-foreground);box-shadow:0 8px 24px #0003}\n.rt-dialog h2{font-size:1.1rem;font-weight:600;margin:0 0 .75rem}.rt-dialog p{margin:0;overflow-wrap:anywhere;line-height:1.5}\n.rt-dialog-actions{display:flex;justify-content:flex-end;gap:.5rem;margin-top:1.25rem}\n.rt-export-notice{position:absolute;top:calc(100% + .5rem);right:0;z-index:101;display:flex;align-items:center;gap:.5rem;width:max-content;max-width:min(22rem,calc(100vw - 2rem));box-sizing:border-box;padding:.75rem;border:1px solid var(--border);border-radius:var(--radius-lg);background:var(--popover);color:var(--popover-foreground);box-shadow:0 8px 24px #0002;font-size:.875rem;line-height:1.4}\n.rt-export-notice>svg{width:1rem;height:1rem;flex:none;color:var(--primary)}\n.rt-export-notice-error>svg{color:var(--destructive)}\n.rt-export-notice button{width:1.75rem;height:1.75rem;flex:none;margin:-.375rem -.375rem -.375rem 0}\n.rt-publishing-details{display:flex;flex-direction:column;align-items:flex-start;gap:.25rem;min-width:0;overflow-wrap:anywhere}\n.rt-publishing-details a{color:var(--primary);text-decoration:underline}\n.rt-publishing-details button{width:auto;height:auto;margin:0;padding:0;white-space:normal;text-align:start}\n.rt-notice{display:flex;align-items:center;flex-wrap:wrap;gap:.75rem;margin-bottom:1rem}\n.rt-page .pd-catalog{padding:0;overflow:auto}\n.rt-page .pd-history{position:static;max-height:300px;margin-bottom:1rem;width:100%}\n";
@@ -0,0 +1,6 @@
1
+ import type { ImportIdentity } from './types.ts';
2
+ /** Resolve directory aliases without following a venv's Python link into its base installation. */
3
+ export declare function canonicalPythonExecutable(executable: string): string;
4
+ export declare function canonicalImportIdentity(identity: ImportIdentity): ImportIdentity;
5
+ /** The Python equivalent of canonicalImportIdentity, shared by every execution boundary. */
6
+ export declare const PYTHON_IMPORT_IDENTITY: string;
@@ -7,6 +7,7 @@ import { type MarivoDisclosureOptions } from './disclosure/index.ts';
7
7
  import { MarivoEnvironment } from './environment/index.ts';
8
8
  import type { NextStepsNotice } from './next-steps/contracts.ts';
9
9
  import { AnalysisDrafts } from './presentation/drafts.ts';
10
+ import type { ReportPublishingService } from './report-publishing/service.ts';
10
11
  export type MarivoPluginEnvironmentResolver = (agent: Agent) => MarivoEnvironment | Promise<MarivoEnvironment>;
11
12
  /**
12
13
  * Install one already-bound environment into every live or subsequently published Agent scope.
@@ -22,6 +23,7 @@ export declare function createMarivoAgentInstallation(ctx: Context, environmentO
22
23
  /** Runtime-scoped Help source; normal plugin installation never binds Help to a Workspace. */
23
24
  helpBridgeSource?: MarivoHelpBridgeSource;
24
25
  presentationDrafts?: AnalysisDrafts;
26
+ reportPublishing?: ReportPublishingService;
25
27
  nextStepsPublish?: (notice: NextStepsNotice) => void;
26
28
  }): {
27
29
  install(): void;
@@ -4,6 +4,7 @@ export { resolvePresentationWorkspace } from './workspace-identity.ts';
4
4
  import type { Context } from '@deepseek-ai/cordis';
5
5
  import z from '@deepseek-ai/schemastery';
6
6
  import type { MarivoIntegrationV1 } from './integration.ts';
7
+ import { type ReportPublishingConfig } from './report-publishing/config.ts';
7
8
  /** Cordis plugin name used by loader diagnostics and lifecycle logs. */
8
9
  export declare const name = "dsh-data-analysis";
9
10
  /** Services that must exist before the plugin binds and watches Agent scopes. */
@@ -11,6 +12,7 @@ export declare const inject: string[];
11
12
  /** Loader-safe configuration for the shared Runtime and per-Workspace bindings. */
12
13
  export interface Config extends PythonTimeoutConfig {
13
14
  readonly credentialInteraction?: 'web' | 'none';
15
+ readonly reportPublishing?: ReportPublishingConfig;
14
16
  /** Explicit project root override; otherwise each Agent uses session.header.cwd. */
15
17
  readonly projectRoot?: string;
16
18
  /** Administrator-provided shared interpreter; must already contain an importable Marivo. */
@@ -24,6 +26,7 @@ export interface Config extends PythonTimeoutConfig {
24
26
  }
25
27
  /** Cordis loader schema. Runtime defaults are resolved in {@link apply}. */
26
28
  export declare const Config: z<Schemastery.ObjectS<NoInfer<{
29
+ reportPublishing: z<any, any, "plain">;
27
30
  pythonTimeoutMs: z<number, number, "volatile-defined">;
28
31
  credentialInteraction: z<"web" | "none", "web" | "none", "defined">;
29
32
  projectRoot: z<string, string, "plain">;
@@ -32,6 +35,7 @@ export declare const Config: z<Schemastery.ObjectS<NoInfer<{
32
35
  bootstrapPythonExecutable: z<string, string, "plain">;
33
36
  installTimeoutMs: z<number, number, "defined">;
34
37
  }>>, Schemastery.ObjectT<NoInfer<{
38
+ reportPublishing: z<any, any, "plain">;
35
39
  pythonTimeoutMs: z<number, number, "volatile-defined">;
36
40
  credentialInteraction: z<"web" | "none", "web" | "none", "defined">;
37
41
  projectRoot: z<string, string, "plain">;