@chengxianglibra/dsh-data-analysis 0.1.2 → 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.
Files changed (212) hide show
  1. package/README.md +136 -99
  2. package/cordis.patch.yml +1 -1
  3. package/lib/bin/environment.js +8 -6
  4. package/lib/client/credentials/changes.js +74 -0
  5. package/lib/client/credentials/create-datasource.js +126 -22
  6. package/lib/client/credentials/credential-draft.js +42 -0
  7. package/lib/client/credentials/defaults.js +11 -0
  8. package/lib/client/credentials/descriptions.js +46 -0
  9. package/lib/client/credentials/install.js +209 -81
  10. package/lib/client/credentials/model.js +323 -51
  11. package/lib/client/credentials/report-publishing.js +96 -0
  12. package/lib/client/credentials/styles.js +13 -9
  13. package/lib/client/i18n/context.js +22 -0
  14. package/lib/client/i18n/copy.js +57 -0
  15. package/lib/client/i18n/credentials.js +475 -0
  16. package/lib/client/i18n/host.js +27 -0
  17. package/lib/client/i18n/navigation.js +41 -0
  18. package/lib/client/i18n/presentation.js +577 -0
  19. package/lib/client/i18n/python.js +36 -0
  20. package/lib/client/i18n/semantic.js +441 -0
  21. package/lib/client/input-context.js +21 -0
  22. package/lib/client/python-tool/card.js +35 -0
  23. package/lib/client/python-tool/execution-error.js +35 -0
  24. package/lib/client/python-tool/install.js +9 -0
  25. package/lib/client/python-tool/model.js +101 -0
  26. package/lib/client/right-tabs/install.js +535 -0
  27. package/lib/client/right-tabs/live-delivery.js +58 -0
  28. package/lib/client/right-tabs/navigation.js +47 -0
  29. package/lib/client/right-tabs/page.js +178 -0
  30. package/lib/client/right-tabs/styles.js +11 -0
  31. package/lib/client/rpc.js +5 -0
  32. package/lib/client/semantic-reference.js +10 -0
  33. package/lib/client/workspace-header-action.js +14 -1
  34. package/lib/client/workspace-shortcuts.js +26 -0
  35. package/lib/client.js +365 -242
  36. package/lib/compatibility.js +1 -1
  37. package/lib/datasource/authoring.js +43 -4
  38. package/lib/datasource/bridge-programs.js +23 -20
  39. package/lib/datasource/bridge.js +46 -3
  40. package/lib/datasource/changes-contract.js +41 -0
  41. package/lib/datasource/changes.js +49 -0
  42. package/lib/datasource/configure.js +39 -0
  43. package/lib/datasource/defaults.js +25 -0
  44. package/lib/datasource/index.js +2 -1
  45. package/lib/datasource/python-options.js +21 -0
  46. package/lib/datasource/python.js +116 -25
  47. package/lib/datasource/rpc.js +75 -13
  48. package/lib/datasource/service.js +286 -11
  49. package/lib/datasource/test.js +2 -1
  50. package/lib/disclosure/activation.js +19 -7
  51. package/lib/disclosure/execution-guidance.js +52 -0
  52. package/lib/disclosure/help.js +4 -1
  53. package/lib/environment/runtime.js +35 -34
  54. package/lib/environment/workspace.js +18 -1
  55. package/lib/lifecycle.js +33 -0
  56. package/lib/plugin-agents.js +154 -0
  57. package/lib/plugin.js +94 -172
  58. package/lib/presentation/asset.js +34 -0
  59. package/lib/presentation/assets/portable.js +14 -14
  60. package/lib/presentation/assets/static.js +344 -73
  61. package/lib/presentation/build/index.js +3 -2
  62. package/lib/presentation/commit.js +19 -12
  63. package/lib/presentation/contracts/asset-path.js +9 -0
  64. package/lib/presentation/contracts/catalog.js +62 -0
  65. package/lib/presentation/contracts/charts.js +0 -23
  66. package/lib/presentation/contracts/index.js +17 -5
  67. package/lib/presentation/contracts/types.js +1 -1
  68. package/lib/presentation/delivery.js +45 -30
  69. package/lib/presentation/export-html.js +214 -0
  70. package/lib/presentation/files.js +4 -5
  71. package/lib/presentation/projection/index.js +2 -1
  72. package/lib/presentation/projection/program.js +2 -9
  73. package/lib/presentation/projection/sql-code.js +13 -13
  74. package/lib/presentation/reports.js +114 -17
  75. package/lib/presentation/rpc.js +96 -58
  76. package/lib/presentation/tool.js +6 -10
  77. package/lib/report-publishing/adapters.js +111 -0
  78. package/lib/report-publishing/config.js +69 -0
  79. package/lib/report-publishing/service.js +180 -0
  80. package/lib/rpc.js +49 -0
  81. package/lib/semantic-browser/contracts.js +17 -0
  82. package/lib/semantic-browser/program.js +10 -0
  83. package/lib/semantic-browser/service.js +40 -6
  84. package/lib/semantic-reference/bridge.js +10 -1
  85. package/lib/semantic-reference/contracts.js +20 -6
  86. package/lib/semantic-reference/environment.js +56 -0
  87. package/lib/semantic-reference/labels.js +16 -0
  88. package/lib/semantic-reference/rpc.js +39 -18
  89. package/lib/semantic-reference/search.js +5 -4
  90. package/lib/semantic-reference/usage.js +12 -3
  91. package/lib/tool-lifecycle.js +22 -0
  92. package/lib/types/client/credentials/changes.d.ts +9 -0
  93. package/lib/types/client/credentials/create-datasource.d.ts +3 -1
  94. package/lib/types/client/credentials/credential-draft.d.ts +14 -0
  95. package/lib/types/client/credentials/defaults.d.ts +2 -0
  96. package/lib/types/client/credentials/descriptions.d.ts +1 -0
  97. package/lib/types/client/credentials/install.d.ts +19 -1
  98. package/lib/types/client/credentials/model.d.ts +31 -11
  99. package/lib/types/client/credentials/report-publishing.d.ts +5 -0
  100. package/lib/types/client/credentials/styles.d.ts +1 -1
  101. package/lib/types/client/i18n/context.d.ts +17 -0
  102. package/lib/types/client/i18n/copy.d.ts +806 -0
  103. package/lib/types/client/i18n/credentials.d.ts +475 -0
  104. package/lib/types/client/i18n/host.d.ts +16 -0
  105. package/lib/types/client/i18n/navigation.d.ts +41 -0
  106. package/lib/types/client/i18n/presentation.d.ts +577 -0
  107. package/lib/types/client/i18n/python.d.ts +19 -0
  108. package/lib/types/client/i18n/semantic.d.ts +441 -0
  109. package/lib/types/client/input-context.d.ts +19 -0
  110. package/lib/types/client/presentation/ask-dsh.d.ts +4 -8
  111. package/lib/types/client/presentation/catalog-model.d.ts +24 -0
  112. package/lib/types/client/presentation/catalog.d.ts +20 -0
  113. package/lib/types/client/presentation/chart-tooltip.d.ts +2 -2
  114. package/lib/types/client/presentation/context-reference.d.ts +12 -0
  115. package/lib/types/client/presentation/copy-context.d.ts +2 -2
  116. package/lib/types/client/presentation/delivery-model.d.ts +27 -6
  117. package/lib/types/client/presentation/delivery.d.ts +8 -7
  118. package/lib/types/client/presentation/download.d.ts +2 -0
  119. package/lib/types/client/presentation/export-menu.d.ts +26 -0
  120. package/lib/types/client/presentation/export-view.d.ts +63 -0
  121. package/lib/types/client/presentation/host-entry.d.ts +8 -2
  122. package/lib/types/client/presentation/icons.d.ts +1 -1
  123. package/lib/types/client/presentation/model.d.ts +14 -15
  124. package/lib/types/client/presentation/reader.d.ts +15 -2
  125. package/lib/types/client/presentation/reference-source.d.ts +9 -0
  126. package/lib/types/client/presentation/source-code-model.d.ts +2 -1
  127. package/lib/types/client/presentation/source-code.d.ts +0 -5
  128. package/lib/types/client/presentation/source-dialog.d.ts +1 -2
  129. package/lib/types/client/presentation/sources.d.ts +5 -5
  130. package/lib/types/client/presentation/styles.d.ts +1 -1
  131. package/lib/types/client/presentation/table.d.ts +5 -1
  132. package/lib/types/client/python-tool/card.d.ts +2 -0
  133. package/lib/types/client/python-tool/execution-error.d.ts +3 -0
  134. package/lib/types/client/python-tool/install.d.ts +2 -0
  135. package/lib/types/client/python-tool/model.d.ts +20 -0
  136. package/lib/types/client/right-tabs/install.d.ts +18 -0
  137. package/lib/types/client/right-tabs/live-delivery.d.ts +8 -0
  138. package/lib/types/client/right-tabs/navigation.d.ts +17 -0
  139. package/lib/types/client/right-tabs/page.d.ts +36 -0
  140. package/lib/types/client/right-tabs/styles.d.ts +2 -0
  141. package/lib/types/client/rpc.d.ts +3 -0
  142. package/lib/types/client/semantic-reference.d.ts +4 -0
  143. package/lib/types/client/workspace-header-action.d.ts +1 -1
  144. package/lib/types/client/workspace-shortcuts.d.ts +15 -0
  145. package/lib/types/client.d.ts +6 -3
  146. package/lib/types/compatibility.d.ts +1 -1
  147. package/lib/types/datasource/authoring.d.ts +10 -0
  148. package/lib/types/datasource/bridge.d.ts +23 -2
  149. package/lib/types/datasource/changes-contract.d.ts +18 -0
  150. package/lib/types/datasource/changes.d.ts +15 -0
  151. package/lib/types/datasource/configure.d.ts +7 -0
  152. package/lib/types/datasource/defaults.d.ts +7 -0
  153. package/lib/types/datasource/index.d.ts +6 -1
  154. package/lib/types/datasource/python-options.d.ts +9 -0
  155. package/lib/types/datasource/python.d.ts +17 -2
  156. package/lib/types/datasource/rpc.d.ts +2 -1
  157. package/lib/types/datasource/service.d.ts +48 -5
  158. package/lib/types/datasource/test.d.ts +1 -1
  159. package/lib/types/disclosure/activation.d.ts +2 -1
  160. package/lib/types/disclosure/execution-guidance.d.ts +6 -0
  161. package/lib/types/disclosure/help.d.ts +1 -1
  162. package/lib/types/environment/types.d.ts +2 -1
  163. package/lib/types/environment/workspace.d.ts +1 -0
  164. package/lib/types/lifecycle.d.ts +8 -0
  165. package/lib/types/plugin-agents.d.ts +27 -0
  166. package/lib/types/plugin.d.ts +12 -28
  167. package/lib/types/presentation/asset.d.ts +6 -0
  168. package/lib/types/presentation/build/index.d.ts +7 -2
  169. package/lib/types/presentation/commit.d.ts +1 -1
  170. package/lib/types/presentation/contracts/asset-path.d.ts +2 -0
  171. package/lib/types/presentation/contracts/catalog.d.ts +27 -0
  172. package/lib/types/presentation/contracts/charts.d.ts +0 -2
  173. package/lib/types/presentation/contracts/types.d.ts +7 -4
  174. package/lib/types/presentation/delivery.d.ts +1 -1
  175. package/lib/types/presentation/export-html.d.ts +13 -0
  176. package/lib/types/presentation/reports.d.ts +6 -1
  177. package/lib/types/presentation/rpc.d.ts +3 -2
  178. package/lib/types/presentation/tool.d.ts +2 -2
  179. package/lib/types/report-publishing/adapters.d.ts +6 -0
  180. package/lib/types/report-publishing/config.d.ts +22 -0
  181. package/lib/types/report-publishing/service.d.ts +68 -0
  182. package/lib/types/rpc.d.ts +3 -0
  183. package/lib/types/semantic-browser/contracts.d.ts +7 -0
  184. package/lib/types/semantic-browser/service.d.ts +7 -1
  185. package/lib/types/semantic-reference/bridge.d.ts +1 -0
  186. package/lib/types/semantic-reference/contracts.d.ts +5 -2
  187. package/lib/types/semantic-reference/environment.d.ts +22 -0
  188. package/lib/types/semantic-reference/labels.d.ts +16 -0
  189. package/lib/types/semantic-reference/rpc.d.ts +1 -1
  190. package/lib/types/semantic-reference/search.d.ts +1 -1
  191. package/lib/types/tool-lifecycle.d.ts +4 -0
  192. package/lib/types/workspace-identity.d.ts +6 -0
  193. package/lib/workspace-identity.js +9 -0
  194. package/package.json +83 -61
  195. package/python/presentation-kit/dist/dsh_data_analysis_presentation_kit-1.1.0-py3-none-any.whl +0 -0
  196. package/skills/dsh-data-analysis-files/SKILL.md +32 -0
  197. package/skills/dsh-data-analysis-files/references/examples.md +93 -0
  198. package/skills/dsh-data-analysis-presentation/SKILL.md +10 -6
  199. package/skills/dsh-data-analysis-presentation/references/examples/artifact.draft.json +13 -4
  200. package/skills/dsh-data-analysis-presentation/references/examples/charts.draft.json +3 -2
  201. package/skills/dsh-data-analysis-presentation/references/examples/comparison.draft.json +3 -2
  202. package/skills/dsh-data-analysis-presentation/references/examples/computed-sources.draft.json +12 -5
  203. package/skills/dsh-data-analysis-presentation/references/examples/computed.draft.json +3 -2
  204. package/skills/dsh-data-analysis-presentation/references/examples/interaction.draft.json +3 -2
  205. package/skills/dsh-data-analysis-presentation/references/examples/source-only.draft.json +12 -4
  206. package/skills/dsh-data-analysis-presentation/references/examples.md +3 -1
  207. package/skills/dsh-data-analysis-presentation/references/export-html.md +7 -0
  208. package/skills/dsh-data-analysis-presentation/references/interaction.md +1 -1
  209. package/skills/dsh-data-analysis-presentation/references/narrative.md +1 -1
  210. package/skills/dsh-data-analysis-presentation/references/publishing.md +3 -0
  211. package/skills/dsh-data-analysis-presentation/references/schema.md +25 -1
  212. package/lib/types/client/presentation/install.d.ts +0 -15
@@ -0,0 +1,13 @@
1
+ import type { Context } from '@deepseek-ai/cordis';
2
+ import type { Session } from '@deepseek-ai/dsh-session';
3
+ export declare const MARIVO_EXPORT_HTML_TOOL_NAME = "marivo_export_html";
4
+ export type ExportWorkspaceSource = () => {
5
+ id: string;
6
+ path: string;
7
+ } | Promise<{
8
+ id: string;
9
+ path: string;
10
+ }>;
11
+ export declare function parseHtmlOutputPath(value: unknown): string;
12
+ export declare function createMarivoExportHtmlTool(source: ExportWorkspaceSource, session: Session): import("@deepseek-ai/dsh-tools").ToolDefinition;
13
+ export declare function registerMarivoExportHtmlTool(ctx: Context, source: ExportWorkspaceSource, session: Session): () => Promise<void>;
@@ -1,5 +1,10 @@
1
+ import { type PublicationSource, type ReportCatalog, type ReportHistory } from './contracts/catalog.ts';
1
2
  import { type PresentationDocument, type PresentationReceipt } from './contracts/index.ts';
2
3
  export declare function readReceiptDocument(root: string, receipt: PresentationReceipt, signal?: AbortSignal): Promise<PresentationDocument>;
4
+ /** Current and its publication history become visible through one atomic rename. */
5
+ export declare function readReportHistory(root: string, workspaceId: string, reportId: string, signal?: AbortSignal): Promise<ReportHistory>;
3
6
  export declare function resolvePresentation(root: string, workspaceId: string, reportId: string, signal?: AbortSignal): Promise<PresentationReceipt>;
7
+ /** Enumerate only publication pointers, never completed-but-unpublished build directories. */
8
+ export declare function listReports(root: string, workspaceId: string, signal?: AbortSignal): Promise<ReportCatalog>;
4
9
  /** The mutable pointer is the publication boundary; completed builds are never overwritten. */
5
- export declare function publishPresentation(root: string, document: PresentationDocument, expectedBuildId: string | null, assertOwner: () => Promise<void>, signal?: AbortSignal): Promise<PresentationReceipt>;
10
+ export declare function publishPresentation(root: string, document: PresentationDocument, expectedBuildId: string | null, assertOwner: () => Promise<void>, signal?: AbortSignal, source?: PublicationSource | null): Promise<PresentationReceipt>;
@@ -7,8 +7,9 @@ export interface PresentationWorkspace {
7
7
  export type PresentationWorkspaceResolver = (sessionId: string) => PresentationWorkspace | undefined | Promise<PresentationWorkspace | undefined>;
8
8
  export declare class MarivoPresentationFileService {
9
9
  #private;
10
- constructor(resolve: PresentationWorkspaceResolver);
11
- close(): void;
10
+ constructor(resolve: PresentationWorkspaceResolver, resolveId?: PresentationWorkspaceResolver);
11
+ catalog(endpoint: 'reports/list' | 'reports/history', payload: unknown, caller?: AbortSignal): Promise<import("./contracts/catalog.ts").ReportHistory | import("./contracts/catalog.ts").ReportCatalog>;
12
+ close(): Promise<void>;
12
13
  report(endpoint: 'reports/resolve' | 'reports/save', payload: unknown, caller?: AbortSignal): Promise<import("./contracts/types.ts").PresentationReceipt>;
13
14
  read(payload: unknown, caller?: AbortSignal): Promise<{
14
15
  workspaceId: string;
@@ -7,6 +7,6 @@ export interface PresentationBinding {
7
7
  projection: MarivoPresentationProjection;
8
8
  }
9
9
  export type PresentationBindingSource = () => PresentationBinding | Promise<PresentationBinding>;
10
- /** One call projects a draft, builds both assets, commits them, then emits the receipt. */
10
+ /** One call projects a draft, builds the document, commits them, then emits the receipt. */
11
11
  export declare function createMarivoPresentTool(source: PresentationBindingSource, session: Session, lifecycleSignal?: AbortSignal): ToolDefinition;
12
- export declare function registerMarivoPresentTool(ctx: Context, source: PresentationBindingSource, session: Session): () => void;
12
+ export declare function registerMarivoPresentTool(ctx: Context, source: PresentationBindingSource, session: Session): () => Promise<void>;
@@ -0,0 +1,6 @@
1
+ import type { Context } from '@deepseek-ai/cordis';
2
+ import type { HostConnectionHandle } from '@deepseek-ai/dsh-client-connection';
3
+ import type { ReportPublishingService } from './service.ts';
4
+ export declare const PUBLISHING_CHANNEL = "/dsh-report-publishing";
5
+ export declare function registerPublishingCredentials(connection: HostConnectionHandle, service: ReportPublishingService, workspaceExists: (id: string) => boolean): () => Promise<void>;
6
+ export declare function registerReportPublishTool(ctx: Context, service: ReportPublishingService, sessionId: string): () => Promise<void>;
@@ -0,0 +1,22 @@
1
+ import { z } from 'zod';
2
+ export declare const publishingConfigSchema: z.ZodObject<{
3
+ enabled: z.ZodDefault<z.ZodBoolean>;
4
+ storage: z.ZodObject<{
5
+ name: z.ZodString;
6
+ protocol: z.ZodDefault<z.ZodLiteral<"s3">>;
7
+ endpoint: z.ZodString;
8
+ region: z.ZodString;
9
+ bucket: z.ZodString;
10
+ forcePathStyle: z.ZodDefault<z.ZodBoolean>;
11
+ accessKeyIdRef: z.ZodString;
12
+ secretAccessKeyRef: z.ZodString;
13
+ sessionTokenRef: z.ZodOptional<z.ZodString>;
14
+ }, z.core.$strict>;
15
+ pathPrefix: z.ZodDefault<z.ZodString>;
16
+ publicBaseUrl: z.ZodString;
17
+ }, z.core.$strict>;
18
+ export type ReportPublishingConfig = z.input<typeof publishingConfigSchema> | {
19
+ enabled?: false;
20
+ };
21
+ export type EnabledPublishingConfig = z.output<typeof publishingConfigSchema>;
22
+ export declare function resolvePublishingConfig(value?: ReportPublishingConfig): EnabledPublishingConfig | undefined;
@@ -0,0 +1,68 @@
1
+ import { type CredentialProvider } from '@deepseek-ai/dsh-credentials';
2
+ import type { MarivoPresentationFileService } from '../presentation/rpc.ts';
3
+ import type { EnabledPublishingConfig } from './config.ts';
4
+ export declare function publishingPathName(value: string, fallback: string): string;
5
+ export type PublishingField = 'accessKeyId' | 'secretAccessKey' | 'sessionToken';
6
+ export interface PublishingCredentialField {
7
+ field: PublishingField;
8
+ reference: string;
9
+ required: boolean;
10
+ configured: boolean;
11
+ writable: boolean;
12
+ source?: string;
13
+ }
14
+ export interface PublishingCredentialView {
15
+ enabled: boolean;
16
+ configId?: string;
17
+ name?: string;
18
+ bucket?: string;
19
+ fields: PublishingCredentialField[];
20
+ }
21
+ type Store = Pick<CredentialProvider, 'describe' | 'set' | 'unset' | 'resolve'>;
22
+ export interface UploadInput {
23
+ config: EnabledPublishingConfig;
24
+ credentials: {
25
+ accessKeyId: string;
26
+ secretAccessKey: string;
27
+ sessionToken?: string;
28
+ };
29
+ key: string;
30
+ bytes: Buffer;
31
+ signal: AbortSignal;
32
+ }
33
+ export declare function uploadReport(input: UploadInput): Promise<void>;
34
+ export declare class ReportPublishingService {
35
+ readonly configId: `${string}-${string}-${string}-${string}-${string}`;
36
+ readonly config: EnabledPublishingConfig | undefined;
37
+ readonly store: Store;
38
+ readonly files: Pick<MarivoPresentationFileService, 'catalog' | 'read'>;
39
+ readonly upload: (input: UploadInput) => Promise<void>;
40
+ readonly workspaceName: (id: string) => string;
41
+ constructor(config: EnabledPublishingConfig | undefined, store: Store, files: Pick<MarivoPresentationFileService, 'catalog' | 'read'>, upload?: (input: UploadInput) => Promise<void>, workspaceName?: (id: string) => string);
42
+ assertConfig(configId: string): void;
43
+ references(): Array<{
44
+ field: PublishingField;
45
+ reference: string;
46
+ required: boolean;
47
+ }>;
48
+ describe(): Promise<PublishingCredentialView>;
49
+ change(field: PublishingField, value: string | undefined, signal: AbortSignal): Promise<void>;
50
+ publish(scope: {
51
+ sessionId: string;
52
+ } | {
53
+ workspaceId: string;
54
+ }, reportId: string, buildId: string, signal: AbortSignal, viewHtml?: string): Promise<{
55
+ storage: string;
56
+ bucket: string;
57
+ key: string;
58
+ url: string;
59
+ workspaceId: string;
60
+ reportId: string;
61
+ buildId: string;
62
+ sha256: string;
63
+ bytes: number;
64
+ kind: string;
65
+ publishedAt: string;
66
+ }>;
67
+ }
68
+ export {};
@@ -0,0 +1,3 @@
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,6 +2,7 @@ import { type SemanticRef } from '../semantic-reference/contracts.ts';
2
2
  import { type ComputationDefinition } from './definition.ts';
3
3
  export declare const BROWSER_ENDPOINT = "semantic-browser/catalog";
4
4
  export declare const CATALOG_MAX_BYTES: number;
5
+ export declare const CATALOG_ERROR_SCHEMA = "marivo.semantic_catalog_error/v1";
5
6
  export interface DisplayField {
6
7
  readonly name: string;
7
8
  readonly value: string;
@@ -30,6 +31,11 @@ export interface CatalogProjection {
30
31
  readonly kinds: readonly string[];
31
32
  readonly objects: readonly SemanticObjectView[];
32
33
  }
34
+ export interface CatalogFailure {
35
+ readonly schema: typeof CATALOG_ERROR_SCHEMA;
36
+ readonly kind: 'semantic';
37
+ readonly message: string;
38
+ }
33
39
  export interface CatalogSnapshot extends CatalogProjection {
34
40
  readonly workspaceId: string;
35
41
  readonly projectRoot: string;
@@ -37,4 +43,5 @@ export interface CatalogSnapshot extends CatalogProjection {
37
43
  readonly loadedAt: string;
38
44
  }
39
45
  export declare function parseCatalogProjection(value: unknown): CatalogProjection;
46
+ export declare function parseCatalogFailure(value: unknown): CatalogFailure | undefined;
40
47
  export declare function parseCatalogSnapshot(value: unknown): CatalogSnapshot;
@@ -9,12 +9,18 @@ export interface BrowserHost {
9
9
  projectRoot(workspace: BrowserWorkspace): string;
10
10
  resolve(root: string): Promise<MarivoCheckedRunner>;
11
11
  }
12
+ export declare class SemanticCatalogLoadError extends Error {
13
+ readonly code = "catalog-load-failed";
14
+ readonly diagnostic: string;
15
+ constructor(diagnostic: string);
16
+ }
12
17
  /** Workspace-addressed read service; intentionally has no Agent or credential dependency. */
13
18
  export declare class SemanticBrowserService {
14
19
  #private;
15
20
  constructor(host: BrowserHost);
16
21
  read(payload: unknown, caller: AbortSignal): Promise<CatalogSnapshot>;
22
+ close(): Promise<void>;
17
23
  dispose(): void;
18
24
  }
19
- /** Fixed diagnostics only: Python errors may contain model code or datasource secrets. */
25
+ /** Preserve Marivo semantic diagnostics; keep unknown Python failures behind a fixed fallback. */
20
26
  export declare function browserFailure(error: unknown): string;
@@ -6,6 +6,7 @@ export declare class SemanticReferenceBridge {
6
6
  #private;
7
7
  constructor(clock?: () => number);
8
8
  candidates(runner: MarivoCheckedRunner, signal: AbortSignal): Promise<Projection>;
9
+ close(): Promise<void>;
9
10
  invalidate(key: string): void;
10
11
  dispose(): void;
11
12
  }
@@ -1,7 +1,6 @@
1
1
  /** Browser-safe wire contracts. These bounds do not reimplement Marivo's domain grammar. */
2
2
  export declare const CHANNEL = "/dsh-data-analysis";
3
3
  export declare const SOURCE = "marivo-semantic";
4
- export declare const LIMIT = 40;
5
4
  export declare const MAX_WIRE_BYTES: number;
6
5
  export interface SemanticRef {
7
6
  readonly schema: 'marivo.semantic_ref/v1';
@@ -46,6 +45,10 @@ export declare function parseCandidatesRequest(value: unknown): {
46
45
  sessionId: string;
47
46
  query: string;
48
47
  quoted: boolean;
49
- limit: number;
50
48
  };
51
49
  export declare function parseCandidatesResponse(value: unknown): CandidatesResponse;
50
+ /** Browser selection identity only; preparation never reloads semantic content. */
51
+ export declare function parsePrepareRequest(value: unknown): {
52
+ workspaceId: string;
53
+ envelope: Envelope;
54
+ };
@@ -0,0 +1,22 @@
1
+ import type { MarivoCheckedRunner } from '../environment/types.ts';
2
+ import type { EnvironmentResolver } from './rpc.ts';
3
+ interface Workspace {
4
+ id: string;
5
+ path: string;
6
+ }
7
+ interface Binding {
8
+ root: string;
9
+ environment: Promise<MarivoCheckedRunner>;
10
+ }
11
+ export interface ReferenceEnvironmentHost<A extends object> {
12
+ agent(sessionId: string): A | undefined;
13
+ binding(agent: A): Binding | undefined;
14
+ projectRoot(agent: A): string;
15
+ resolve(agent: A): Promise<MarivoCheckedRunner>;
16
+ workspace(sessionId: string): Workspace;
17
+ }
18
+ /** Reference identity includes Harness ownership; the underlying Runtime stays unchanged. */
19
+ export declare function semanticEnvironmentFingerprint(workspaceId: string, runtimeFingerprint: string): string;
20
+ /** Explicit selection establishes ownership; serialization never repairs it. */
21
+ export declare function referenceEnvironmentResolver<A extends object>(host: ReferenceEnvironmentHost<A>): EnvironmentResolver;
22
+ export {};
@@ -0,0 +1,16 @@
1
+ /** Shared display labels and search aliases; object kinds still come from the live Catalog. */
2
+ export declare const semanticKindLabels: {
3
+ readonly domain: "业务域";
4
+ readonly datasource: "数据源";
5
+ readonly entity: "实体";
6
+ readonly dimension: "维度";
7
+ readonly measure: "度量";
8
+ readonly time_dimension: "时间维度";
9
+ readonly metric: "指标";
10
+ readonly relationship: "关系";
11
+ readonly event: "事件";
12
+ readonly state_model: "状态模型";
13
+ readonly period_calendar: "周期日历";
14
+ readonly temporal_set: "时间集合";
15
+ readonly work_schedule: "工作日程";
16
+ };
@@ -2,7 +2,7 @@ import type { ConnectionRpcHandler, HostConnectionHandle } from '@deepseek-ai/ds
2
2
  import type { MarivoCheckedRunner } from '../environment/types.ts';
3
3
  import { SemanticReferenceBridge } from './bridge.ts';
4
4
  import { type SemanticReferenceUsage } from './usage.ts';
5
- export type EnvironmentResolver = (sessionId: string, purpose: 'candidates' | 'reference') => Promise<MarivoCheckedRunner>;
5
+ export type EnvironmentResolver = (sessionId: string, purpose: 'candidates' | 'reference' | 'prepare', workspaceId?: string) => Promise<MarivoCheckedRunner>;
6
6
  /** Abort the caller's wait, without pretending to cancel the shared Environment resolver. */
7
7
  export declare function abortable<T>(promise: Promise<T>, signal: AbortSignal): Promise<T>;
8
8
  export declare class SemanticReferenceService {
@@ -1,4 +1,4 @@
1
- import { type Projection, type RankedCandidate } from './contracts.ts';
1
+ import type { Projection, RankedCandidate } from './contracts.ts';
2
2
  export interface UsageScore {
3
3
  readonly count: number;
4
4
  readonly last: number;
@@ -0,0 +1,4 @@
1
+ import type { Context } from '@deepseek-ai/cordis';
2
+ import type { ToolDefinition } from '@deepseek-ai/dsh-tools';
3
+ /** A plugin tool owns its execution promises; withdrawing its schema is not a drain. */
4
+ export declare function registerMarivoTool(ctx: Context, tool: ToolDefinition): () => Promise<void>;
@@ -0,0 +1,6 @@
1
+ import type { Context } from '@deepseek-ai/cordis';
2
+ /** Resolve only Harness-owned, header-validated Workspace membership; never infer it from a path. */
3
+ export declare function resolvePresentationWorkspace(ctx: Context, sessionId: string): {
4
+ id: string;
5
+ path: string;
6
+ };
@@ -0,0 +1,9 @@
1
+ /** Resolve only Harness-owned, header-validated Workspace membership; never infer it from a path. */
2
+ export function resolvePresentationWorkspace(ctx, sessionId) {
3
+ const matches = ctx.workspaceRegistry
4
+ .list()
5
+ .filter((workspace) => workspace.sessionIds.some((id) => String(id) === sessionId));
6
+ if (matches.length !== 1)
7
+ throw new Error('Presentation requires one current Session Workspace');
8
+ return { id: String(matches[0].id), path: matches[0].path };
9
+ }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@chengxianglibra/dsh-data-analysis",
3
3
  "description": "Marivo runtime, live Help, secure datasource execution and presentation delivery for DeepSeek Harness",
4
- "version": "0.1.2",
4
+ "version": "0.2.0",
5
5
  "repository": {
6
6
  "type": "git",
7
7
  "url": "git+https://github.com/chengxianglibra/dsh-data-analysis.git",
@@ -14,7 +14,7 @@
14
14
  "license": "MIT",
15
15
  "type": "module",
16
16
  "engines": {
17
- "node": ">=24"
17
+ "node": "^22.19.0 || >=24.0.0"
18
18
  },
19
19
  "main": "lib/index.js",
20
20
  "types": "lib/types/index.d.ts",
@@ -54,6 +54,7 @@
54
54
  "lib/**/*.js",
55
55
  "lib/types/**/*.d.ts",
56
56
  "skills/dsh-data-analysis-presentation/**",
57
+ "skills/dsh-data-analysis-files/**",
57
58
  "python/presentation-kit/dist/dsh_data_analysis_presentation_kit-1.1.0-py3-none-any.whl",
58
59
  "cordis.patch.yml",
59
60
  "README.md"
@@ -72,11 +73,11 @@
72
73
  "schema": "dsh-data-analysis-compatibility/v2",
73
74
  "dsh": {
74
75
  "distribution": "@deepseek-ai/dsh",
75
- "peerRange": "0.1.1-rc.2"
76
+ "peerRange": ">=0.1.5-rc.1"
76
77
  },
77
78
  "marivo": {
78
- "version": "0.5.4",
79
- "packageSpec": "marivo[duckdb,trino,clickhouse]==0.5.4"
79
+ "version": "0.5.5",
80
+ "packageSpec": "marivo[duckdb,trino,clickhouse]==0.5.5"
80
81
  },
81
82
  "contracts": {
82
83
  "runtimeInstallation": "dsh-data-analysis-runtime/v3",
@@ -87,13 +88,17 @@
87
88
  "client": {
88
89
  "inject": [
89
90
  "@deepseek-ai/dsh-client-connection",
91
+ "@deepseek-ai/dsh-api-gateway",
90
92
  "@deepseek-ai/dsh-client-locale",
91
- "@deepseek-ai/dsh-client-runtime",
93
+ "@deepseek-ai/dsh-api-session-controller",
94
+ "@deepseek-ai/dsh-api-workspace-controller",
95
+ "@deepseek-ai/dsh-client-ui-chat",
92
96
  "@deepseek-ai/dsh-client-ui-conversation",
93
97
  "@deepseek-ai/dsh-client-ui-tool",
94
98
  "@deepseek-ai/dsh-client-ui-input-trigger",
95
99
  "@deepseek-ai/dsh-client-ui-sidebar",
96
- "@deepseek-ai/dsh-client-ui-layout"
100
+ "@deepseek-ai/dsh-client-ui-layout",
101
+ "@deepseek-ai/dsh-client-ui-sidebar-right"
97
102
  ],
98
103
  "platform": "web"
99
104
  },
@@ -102,72 +107,89 @@
102
107
  }
103
108
  },
104
109
  "dependencies": {
110
+ "@aws-sdk/client-s3": "^3.1129.0",
105
111
  "@deepseek-ai/schemastery": "^3.18.1",
106
112
  "zod": "^4.4.3"
107
113
  },
108
114
  "devDependencies": {
109
- "@deepseek-ai/dsh-agent-loop": "^0.1.1-rc.2",
110
- "@deepseek-ai/dsh-anonymous-user-id": "^0.1.1-rc.2",
111
- "@deepseek-ai/dsh-bash-local": "^0.1.1-rc.2",
112
- "@deepseek-ai/dsh-client-ui-primitives": "^0.1.1-rc.2",
113
- "@deepseek-ai/dsh-client-ui-slots": "^0.1.1-rc.2",
114
- "@deepseek-ai/dsh-code-runtime": "^0.1.1-rc.2",
115
- "@deepseek-ai/dsh-code-runtime-worker-thread": "^0.1.1-rc.2",
116
- "@deepseek-ai/dsh-credentials-local": "^0.1.1-rc.2",
117
- "@deepseek-ai/dsh-fs-local": "^0.1.1-rc.2",
118
- "@deepseek-ai/dsh-fs-observation-policy": "^0.1.1-rc.2",
119
- "@deepseek-ai/dsh-llm-deepseek": "^0.1.1-rc.2",
120
- "@deepseek-ai/dsh-scope": "^0.1.1-rc.2",
121
- "@deepseek-ai/dsh-skill": "^0.1.1-rc.2",
122
- "@deepseek-ai/dsh-subprocess-local": "^0.1.1-rc.2",
123
- "@deepseek-ai/dsh-tool-bash": "^0.1.1-rc.2",
124
- "@deepseek-ai/dsh-tool-fs": "^0.1.1-rc.2",
115
+ "@deepseek-ai/dsh-agent-loop": "0.1.5-rc.1",
116
+ "@deepseek-ai/dsh-anonymous-user-id": "0.1.5-rc.1",
117
+ "@deepseek-ai/dsh-bash-local": "0.1.5-rc.1",
118
+ "@deepseek-ai/dsh-client-store": "0.1.5-rc.1",
119
+ "@deepseek-ai/dsh-client-ui-primitives": "0.1.5-rc.1",
120
+ "@deepseek-ai/dsh-client-ui-renderer": "0.1.5-rc.1",
121
+ "@deepseek-ai/dsh-client-ui-sidebar-right": "0.1.5-rc.1",
122
+ "@deepseek-ai/dsh-client-ui-slots": "0.1.5-rc.1",
123
+ "@deepseek-ai/dsh-code-runtime": "0.1.5-rc.1",
124
+ "@deepseek-ai/dsh-code-runtime-worker-thread": "0.1.5-rc.1",
125
+ "@deepseek-ai/dsh-credentials-local": "0.1.5-rc.1",
126
+ "@deepseek-ai/dsh-fs-local": "0.1.5-rc.1",
127
+ "@deepseek-ai/dsh-fs-observation-policy": "0.1.5-rc.1",
128
+ "@deepseek-ai/dsh-launch-environment": "0.1.5-rc.1",
129
+ "@deepseek-ai/dsh-llm-deepseek": "0.1.5-rc.1",
130
+ "@deepseek-ai/dsh-scope": "0.1.5-rc.1",
131
+ "@deepseek-ai/dsh-session-persistence": "0.1.5-rc.1",
132
+ "@deepseek-ai/dsh-session-persistence-jsonl": "0.1.5-rc.1",
133
+ "@deepseek-ai/dsh-session-projection": "0.1.5-rc.1",
134
+ "@deepseek-ai/dsh-skill": "0.1.5-rc.1",
135
+ "@deepseek-ai/dsh-storage": "0.1.5-rc.1",
136
+ "@deepseek-ai/dsh-storage-json": "0.1.5-rc.1",
137
+ "@deepseek-ai/dsh-subprocess-local": "0.1.5-rc.1",
138
+ "@deepseek-ai/dsh-tool-bash": "0.1.5-rc.1",
139
+ "@deepseek-ai/dsh-tool-fs": "0.1.5-rc.1",
140
+ "@deepseek-ai/dsh-tool-present": "0.1.5-rc.1",
141
+ "@deepseek-ai/dsh-tool-skill": "0.1.5-rc.1",
142
+ "@deepseek-ai/dsh-util-workspace-path": "0.1.5-rc.1",
143
+ "@shikijs/core": "4.4.3",
144
+ "@shikijs/engine-javascript": "4.4.3",
145
+ "@shikijs/langs": "4.4.3",
125
146
  "@types/react": "^18.3.31",
126
- "react": "^18.3.1",
127
- "typescript": "^6.0.3",
128
- "esbuild": "^0.28.2",
129
- "@deepseek-ai/dsh-storage": "^0.1.1-rc.2",
130
- "@deepseek-ai/dsh-storage-json": "^0.1.1-rc.2",
131
- "@deepseek-ai/dsh-session-persistence-jsonl": "0.1.1-rc.2",
132
147
  "@types/react-dom": "18.3.7",
148
+ "@wasm-fmt/ruff_fmt": "0.15.20",
149
+ "esbuild": "^0.28.2",
150
+ "immer": "10.1.1",
133
151
  "playwright": "1.63.0",
152
+ "react": "^18.3.1",
134
153
  "react-dom": "18.3.1",
135
154
  "react-is": "18.3.1",
136
155
  "recharts": "3.8.1",
137
- "@deepseek-ai/dsh-launch-environment": "^0.1.1-rc.2",
138
- "@deepseek-ai/dsh-tool-skill": "^0.1.1-rc.2",
139
- "@shikijs/core": "4.4.3",
140
- "@shikijs/engine-javascript": "4.4.3",
141
- "@shikijs/langs": "4.4.3",
142
- "@wasm-fmt/ruff_fmt": "0.15.20",
143
- "sql-formatter": "15.8.2"
156
+ "sql-formatter": "15.8.2",
157
+ "typescript": "^6.0.3",
158
+ "zustand": "4.4.7"
144
159
  },
145
160
  "peerDependencies": {
146
- "@deepseek-ai/dsh-agent": "0.1.1-rc.2",
147
- "@deepseek-ai/dsh-client-connection": "0.1.1-rc.2",
148
- "@deepseek-ai/dsh-client-locale": "0.1.1-rc.2",
149
- "@deepseek-ai/dsh-client-runtime": "0.1.1-rc.2",
150
- "@deepseek-ai/dsh-client-ui-conversation": "0.1.1-rc.2",
151
- "@deepseek-ai/dsh-client-ui-primitives": "0.1.1-rc.2",
152
- "@deepseek-ai/dsh-client-ui-tool": "0.1.1-rc.2",
153
- "@deepseek-ai/dsh-credentials": "0.1.1-rc.2",
154
- "@deepseek-ai/dsh-home-paths": "0.1.1-rc.2",
155
- "@deepseek-ai/dsh-llm": "0.1.1-rc.2",
156
- "@deepseek-ai/dsh-session": "0.1.1-rc.2",
157
- "@deepseek-ai/dsh-shell-env": "0.1.1-rc.2",
158
- "@deepseek-ai/dsh-skill-filesystem": "0.1.1-rc.2",
159
- "@deepseek-ai/dsh-scope": "0.1.1-rc.2",
160
- "@deepseek-ai/dsh-system-prompt": "0.1.1-rc.2",
161
161
  "@deepseek-ai/cordis": "^4.0.1",
162
- "@deepseek-ai/dsh-tools": "0.1.1-rc.2",
163
- "react": "^18.3.1",
164
- "@deepseek-ai/dsh-storage-domain": "0.1.1-rc.2",
165
- "@deepseek-ai/dsh-client-ui-input-trigger": "0.1.1-rc.2",
166
- "@deepseek-ai/dsh-workspace": "0.1.1-rc.2",
167
- "@deepseek-ai/dsh-client-ui-sidebar": "0.1.1-rc.2",
168
- "@deepseek-ai/dsh-client-ui-layout": "0.1.1-rc.2",
169
- "@deepseek-ai/dsh-shell": "0.1.1-rc.2",
170
- "@deepseek-ai/dsh-sandbox": "0.1.1-rc.2",
171
- "@deepseek-ai/dsh-atomic-write": "0.1.1-rc.2"
162
+ "@deepseek-ai/dsh-agent": ">=0.1.5-rc.1",
163
+ "@deepseek-ai/dsh-api-gateway": ">=0.1.5-rc.1",
164
+ "@deepseek-ai/dsh-api-session-controller": ">=0.1.5-rc.1",
165
+ "@deepseek-ai/dsh-api-workspace-controller": ">=0.1.5-rc.1",
166
+ "@deepseek-ai/dsh-atomic-write": ">=0.1.5-rc.1",
167
+ "@deepseek-ai/dsh-client-connection": ">=0.1.5-rc.1",
168
+ "@deepseek-ai/dsh-client-locale": ">=0.1.5-rc.1",
169
+ "@deepseek-ai/dsh-client-ui-chat": ">=0.1.5-rc.1",
170
+ "@deepseek-ai/dsh-client-ui-conversation": ">=0.1.5-rc.1",
171
+ "@deepseek-ai/dsh-client-ui-input-trigger": ">=0.1.5-rc.1",
172
+ "@deepseek-ai/dsh-client-ui-layout": ">=0.1.5-rc.1",
173
+ "@deepseek-ai/dsh-client-ui-primitives": ">=0.1.5-rc.1",
174
+ "@deepseek-ai/dsh-client-ui-sidebar": ">=0.1.5-rc.1",
175
+ "@deepseek-ai/dsh-client-ui-sidebar-right": ">=0.1.5-rc.1",
176
+ "@deepseek-ai/dsh-client-ui-tool": ">=0.1.5-rc.1",
177
+ "@deepseek-ai/dsh-credentials": ">=0.1.5-rc.1",
178
+ "@deepseek-ai/dsh-home-paths": ">=0.1.5-rc.1",
179
+ "@deepseek-ai/dsh-llm": ">=0.1.5-rc.1",
180
+ "@deepseek-ai/dsh-sandbox": ">=0.1.5-rc.1",
181
+ "@deepseek-ai/dsh-scope": ">=0.1.5-rc.1",
182
+ "@deepseek-ai/dsh-session": ">=0.1.5-rc.1",
183
+ "@deepseek-ai/dsh-shell": ">=0.1.5-rc.1",
184
+ "@deepseek-ai/dsh-shell-env": ">=0.1.5-rc.1",
185
+ "@deepseek-ai/dsh-skill-filesystem": ">=0.1.5-rc.1",
186
+ "@deepseek-ai/dsh-storage-domain": ">=0.1.5-rc.1",
187
+ "@deepseek-ai/dsh-system-prompt": ">=0.1.5-rc.1",
188
+ "@deepseek-ai/dsh-tools": ">=0.1.5-rc.1",
189
+ "@deepseek-ai/dsh-typert-protocol": ">=0.1.5-rc.1",
190
+ "@deepseek-ai/dsh-typert-registry": ">=0.1.5-rc.1",
191
+ "@deepseek-ai/dsh-util-values": ">=0.1.5-rc.1",
192
+ "@deepseek-ai/dsh-workspace": ">=0.1.5-rc.1",
193
+ "react": "^18.3.1"
172
194
  }
173
195
  }
@@ -0,0 +1,32 @@
1
+ ---
2
+ name: dsh-data-analysis-files
3
+ description: 分析已上传或 Workspace 中的 CSV、JSON、Parquet、Excel 文件,使用 pandas 或 DuckDB 计算,按需导出 CSV、JSON、PNG 等普通文件或接入报告。无需先建立 Marivo datasource 或语义模型。
4
+ ---
5
+
6
+ # 文件分析
7
+
8
+ 使用 Harness 提供的当前附件可读路径,或用户指定的 Workspace 文件;同名附件按消息和完整路径区分。路径不可读时报告实际问题,不猜测 Host 缓存位置。
9
+
10
+ 文件读取、计算和最终文件生成(包括 CSV、JSON、PNG)均通过 `marivo_python` 在绑定 Runtime 中执行,不改走 Bash 的 `python`/`python3` 或其他解释器。纯本地文件分析可直接使用 pandas 或原生 `duckdb`,传 `datasources: []`;按任务选择或组合使用,无需 `md.raw_sql`、Marivo 分析 Skill、live Help 或语义建模。只有实际访问 Marivo datasource 时才声明其精确名称并查询相关契约。
11
+
12
+ 使用现有 reader,保留回答所需的 sheet、字段和解析范围;区分样本与全量。Excel `.xlsx` 可用 DuckDB `read_xlsx`,首次使用可能联网获取官方扩展;不承诺旧 `.xls` 或冷缓存离线读取,不临时安装 Python 依赖。
13
+
14
+ 每次 `marivo_python` 都是独立进程。原生 DuckDB 连接可在本次调用内复用、创建临时表,并及时关闭;后续追问重新读取原文件或已有结果,不依赖上次内存状态。按问题控制读取和输出规模,SQL `LIMIT` 不代表仅扫描这些行。
15
+
16
+ ## 按用户目标交付
17
+
18
+ 普通答案直接用文字,不为结论额外创建文件。用户要求 CSV、JSON、PNG 等实际文件时,先通过 `marivo_python` 生成最终文件,优先写入当前绑定 Workspace;确认执行成功、文件存在后,调用当前实际可用的 Harness 原生 `present`,再回复用户。回复前分别核对文件生成与原生声明状态:生成文件、回复路径或展示代码块均不能替代原生交付。缺少 `present` 时,最终回复必须说明“文件已生成,原生交付能力不可用”,并提供准确路径;不能只说文件已生成。不猜测附件缓存或 Shell 私有临时目录。
19
+
20
+ 需要交互图表、表格、报告或看板时加载 `dsh-data-analysis-presentation`,将 DataFrame 交给现有 writer,并关联实际返回的 `codeRef`,使用 `marivo_present` 保存固定 Build。在正文说明文件名与分析范围,不将文件结果冒充 Marivo Artifact 或 Evidence。普通 `present` 不赋予文件 Report/Build 或 Evidence 身份。
21
+
22
+ 报告内部的 `presentation.json`、computed 数据和 receipt 不作为默认附件;只有用户另行要求实际文件且文件已经存在于 Session 文件系统可访问位置时,才调用 `present`。阅读器下载/发布 HTML 沿用现有流程,浏览器内生成的下载不伪装成 Session 文件。
23
+
24
+ ## 能力与失败
25
+
26
+ 遵循 Harness [present 契约](https://github.com/deepseek-ai/deepseek-harness/blob/dsh-v0.1.5-rc.1/packages/fs/tool-present/README.md),由工具验证路径和文件类型。当前工具集中缺少 `present` 时,明确说明“文件已生成,原生交付能力不可用”,提供实际准确路径供手动使用,不虚构卡片,不安装工具或改写 profile。
27
+
28
+ 生成失败不声明成功;声明失败区分“文件已生成”和“交付未完成”,修复路径或可见性后只重试交付,不为补卡片重跑分析。响应不确定时先核对已有调用结果和事件,不盲目重复声明。原生打开失败时使用 Host 的预览或错误反馈,不绕过权限。
29
+
30
+ 卡片打开当前源文件,不保存内容版本;修改、移动或删除会影响后续读取。成功声明的持久事件属于 Harness,即使 PTC 外层程序随后失败,也不撤销已成功的声明。子代理产物属于其调用 Session;父 Agent 如需交付,先确认自己能访问文件,再在父 Session 显式调用 `present`,不自动跨 Session 转投递。
31
+
32
+ 需要起步代码时读[简短示例](references/examples.md);其中提供无需额外依赖的 PNG 写入代码,也通过 `marivo_python` 执行。