@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,58 @@
1
+ import { presentationDeliveryFromEvent, presentationDeliveryIdentity, } from "../presentation/delivery.js";
2
+ /** Read-only Session window consumer. Initial history and replacement never navigate. */
3
+ export class LiveDeliveryObserver {
4
+ #revision = -1;
5
+ #calls = new Map();
6
+ #seen = new Set();
7
+ #onDelivery;
8
+ #sessionId;
9
+ constructor(sessionId, onDelivery) {
10
+ this.#sessionId = sessionId;
11
+ this.#onDelivery = onDelivery;
12
+ }
13
+ consume(window, baseline = false) {
14
+ if (window.revision === this.#revision && !baseline)
15
+ return;
16
+ const initial = this.#revision < 0 || baseline;
17
+ this.#revision = window.revision;
18
+ const live = !initial && window.change.kind === 'append';
19
+ const entries = initial || window.change.kind === 'replace' || window.change.kind === 'prepend'
20
+ ? window.entries
21
+ : window.change.kind === 'append'
22
+ ? window.change.entries
23
+ : [];
24
+ if (initial || window.change.kind === 'replace' || window.change.kind === 'prepend')
25
+ this.#calls.clear();
26
+ for (const entry of entries) {
27
+ if (entry.type !== 'event')
28
+ continue;
29
+ const event = entry.event;
30
+ const turn = event.data?.turn;
31
+ if (event.type === 'tool/call' &&
32
+ Number.isSafeInteger(turn) &&
33
+ typeof event.data.callId === 'string' &&
34
+ typeof event.data.name === 'string') {
35
+ let calls = this.#calls.get(turn);
36
+ if (!calls) {
37
+ calls = new Map();
38
+ this.#calls.set(turn, calls);
39
+ }
40
+ calls.set(event.data.callId, event.data.name);
41
+ }
42
+ // Code dispatch has the canonical Turn in its durable envelope, not necessarily data.turn.
43
+ for (const [ownerTurn, calls] of this.#calls) {
44
+ const item = presentationDeliveryFromEvent(event, calls, ownerTurn);
45
+ if (!item || item.delivery.dshSessionId !== this.#sessionId)
46
+ continue;
47
+ const key = presentationDeliveryIdentity(item.delivery);
48
+ if (this.#seen.has(key))
49
+ continue;
50
+ this.#seen.add(key);
51
+ if (live)
52
+ this.#onDelivery(item.delivery);
53
+ }
54
+ if (event.type === 'turn/end' && Number.isSafeInteger(turn))
55
+ this.#calls.delete(turn);
56
+ }
57
+ }
58
+ }
@@ -0,0 +1,47 @@
1
+ import { boundedText, parseRef } from "../../semantic-reference/contracts.js";
2
+ export const directoryKind = (page) => `marivo-${page}`;
3
+ export const definitionId = (kind) => `dsh-data-analysis/right-tabs/${kind}`;
4
+ const segment = (value) => encodeURIComponent(boundedText(value, 2048));
5
+ export function resourceAddress(target) {
6
+ const root = `dsh-resource://marivo-${target.kind}/${segment(target.workspaceId)}/`;
7
+ return target.kind === 'report'
8
+ ? `${root}${segment(target.reportId)}/${target.buildId ? `build/${segment(target.buildId)}` : 'current'}`
9
+ : `${root}${segment(parseRef(target.ref).kind)}/${segment(target.ref.path)}`;
10
+ }
11
+ export function parseResource(address) {
12
+ const match = /^dsh-resource:\/\/marivo-(report|semantic)\/([^?#]+)$/.exec(address);
13
+ if (!match)
14
+ throw new Error('marivo.navigation.unknown-marivo-resource-address');
15
+ const parts = match[2].split('/').map(decodeURIComponent);
16
+ const workspaceId = boundedText(parts[0], 256);
17
+ let result;
18
+ if (match[1] === 'semantic' && parts.length === 3) {
19
+ result = {
20
+ kind: 'semantic',
21
+ workspaceId,
22
+ ref: parseRef({ schema: 'marivo.semantic_ref/v1', kind: parts[1], path: parts[2] }),
23
+ };
24
+ }
25
+ else if (match[1] === 'report' &&
26
+ ((parts.length === 3 && parts[2] === 'current') || (parts.length === 4 && parts[2] === 'build'))) {
27
+ result = {
28
+ kind: 'report',
29
+ workspaceId,
30
+ reportId: boundedText(parts[1], 256),
31
+ ...(parts.length === 4 ? { buildId: boundedText(parts[3], 256) } : {}),
32
+ };
33
+ }
34
+ else
35
+ throw new Error('marivo.navigation.unknown-marivo-resource-address');
36
+ if (resourceAddress(result) !== address)
37
+ throw new Error('marivo.navigation.resource-address-is-not-canonically-encoded');
38
+ return result;
39
+ }
40
+ export function canOpenResource(address, kind) {
41
+ try {
42
+ return parseResource(address).kind === kind;
43
+ }
44
+ catch {
45
+ return false;
46
+ }
47
+ }
@@ -0,0 +1,178 @@
1
+ import { parsePresentationReceipt } from "../../presentation/contracts/index.js";
2
+ import { MARIVO_PRESENTATION_RPC_CHANNEL } from "../../presentation/receipt.js";
3
+ import { CredentialClientModel } from "../credentials/model.js";
4
+ import { ReportCatalogModel } from "../presentation/catalog-model.js";
5
+ import { PresentationDeliveryModel } from "../presentation/delivery-model.js";
6
+ import { SemanticBrowserModel } from "../semantic-browser/model.js";
7
+ /** Lifetime belongs to a Host tab occurrence, never to a React body mount. */
8
+ export class TabPage {
9
+ sessionId;
10
+ target;
11
+ reader;
12
+ catalog;
13
+ semantic;
14
+ datasources;
15
+ viewMemory = new Map();
16
+ #rpc;
17
+ #lifetime = new AbortController();
18
+ #navigation = new AbortController();
19
+ #revision = -1;
20
+ #updateRevision = 0;
21
+ #state = {};
22
+ #listeners = new Set();
23
+ #closed = false;
24
+ constructor(sessionId, target, rpc, occurrenceId) {
25
+ this.sessionId = sessionId;
26
+ this.target = target;
27
+ this.#rpc = {
28
+ call: async (channel, endpoint, payload, signal) => {
29
+ const combined = AbortSignal.any([signal, this.#navigation.signal, this.#lifetime.signal]);
30
+ combined.throwIfAborted();
31
+ const result = await rpc.call(channel, endpoint, payload, combined);
32
+ combined.throwIfAborted();
33
+ return result;
34
+ },
35
+ };
36
+ this.reader = new PresentationDeliveryModel(this.#rpc);
37
+ this.catalog = new ReportCatalogModel(this.#rpc);
38
+ this.semantic = new SemanticBrowserModel(this.#rpc);
39
+ let storage;
40
+ try {
41
+ if (occurrenceId) {
42
+ const saved = window.sessionStorage;
43
+ const key = `marivo-credential-operation:${JSON.stringify([sessionId, occurrenceId])}`;
44
+ storage = {
45
+ getItem: () => saved.getItem(key),
46
+ setItem: (_key, value) => saved.setItem(key, value),
47
+ removeItem: () => saved.removeItem(key),
48
+ };
49
+ }
50
+ }
51
+ catch {
52
+ // Host query handles remain recoverable in memory when storage is unavailable.
53
+ }
54
+ this.datasources = new CredentialClientModel(this.#rpc, storage);
55
+ if (target.kind === 'datasources')
56
+ this.datasources.recover();
57
+ }
58
+ getSnapshot = () => this.#state;
59
+ subscribe = (listener) => {
60
+ this.#listeners.add(listener);
61
+ return () => {
62
+ this.#listeners.delete(listener);
63
+ };
64
+ };
65
+ patch(change) {
66
+ if (this.#closed)
67
+ return;
68
+ this.#state = { ...this.#state, ...change };
69
+ for (const listener of this.#listeners)
70
+ listener();
71
+ }
72
+ async navigate(revision, force = false, history = false) {
73
+ if (this.#closed || (this.#revision === revision && !force))
74
+ return;
75
+ this.#revision = revision;
76
+ if (this.reader.getSnapshot().editing || this.reader.getSnapshot().saving) {
77
+ this.patch({ notice: 'marivo.navigation.your-edits-are-retained-save-or-cancel-them-first' });
78
+ return;
79
+ }
80
+ if (this.target.kind !== 'datasources' || this.#navigation.signal.aborted) {
81
+ this.#navigation.abort();
82
+ this.#navigation = new AbortController();
83
+ }
84
+ this.#updateRevision++;
85
+ this.patch({ error: undefined, newer: undefined, notice: undefined });
86
+ const target = this.target;
87
+ if (target.kind === 'report') {
88
+ if (target.buildId)
89
+ await this.reader.showBuild(target.workspaceId, target.reportId, target.buildId);
90
+ else
91
+ await this.reader.showReport(target.workspaceId, target.reportId);
92
+ if (history &&
93
+ revision === this.#revision &&
94
+ !this.#closed &&
95
+ !this.#navigation.signal.aborted)
96
+ await this.reader.toggleHistory();
97
+ const displayed = this.reader.getSnapshot().document;
98
+ if (displayed)
99
+ for (const key of this.viewMemory.keys())
100
+ if (!key.startsWith(`${displayed.workspaceId}/${displayed.reportId}/${displayed.buildId}/`))
101
+ this.viewMemory.delete(key);
102
+ }
103
+ else if (target.kind === 'reports')
104
+ this.catalog.show(target.workspaceId);
105
+ else if (target.kind === 'datasources')
106
+ await this.datasources.show(target.workspaceId);
107
+ else if ('ref' in target)
108
+ this.semantic.showObject(target.workspaceId, target.ref);
109
+ else
110
+ this.semantic.show(target.workspaceId);
111
+ }
112
+ async refresh(confirmDiscard = () => window.confirm('marivo.navigation.there-are-unsaved-edits-discard-them-and-refresh-the')) {
113
+ // Incidental refreshes must not undo revocation. Only a checked navigation
114
+ // can reopen an unavailable occurrence.
115
+ if (this.#state.error || this.reader.getSnapshot().saving)
116
+ return;
117
+ if (this.reader.dirty && !confirmDiscard())
118
+ return;
119
+ this.reader.cancelEdit();
120
+ await this.navigate(this.#revision, true);
121
+ }
122
+ async publicationChanged(workspaceId, reportId) {
123
+ if (this.#closed || this.#state.error || workspaceId !== this.target.workspaceId)
124
+ return;
125
+ if (this.target.kind === 'reports') {
126
+ await this.catalog.refresh();
127
+ return;
128
+ }
129
+ if (this.target.kind !== 'report' ||
130
+ this.target.buildId ||
131
+ (reportId && reportId !== this.target.reportId))
132
+ return;
133
+ const generation = ++this.#updateRevision;
134
+ try {
135
+ const response = (await this.#rpc.call(MARIVO_PRESENTATION_RPC_CHANNEL, 'reports/resolve', { workspaceId, reportId: this.target.reportId }, this.#navigation.signal));
136
+ if (!response?.ok)
137
+ throw new Error(response?.error?.message ?? 'marivo.navigation.cannot-verify-the-new-version');
138
+ const receipt = parsePresentationReceipt(response.value);
139
+ if (receipt.workspaceId !== workspaceId || receipt.reportId !== this.target.reportId)
140
+ throw new Error('marivo.navigation.report-identity-changed');
141
+ if (generation !== this.#updateRevision || this.#closed)
142
+ return;
143
+ this.patch({
144
+ newer: receipt.buildId !== this.reader.getSnapshot().document?.buildId ? receipt : undefined,
145
+ });
146
+ }
147
+ catch (error) {
148
+ if (generation === this.#updateRevision && !this.#closed && !this.#state.error)
149
+ this.patch({
150
+ notice: error instanceof Error
151
+ ? error.message
152
+ : 'marivo.navigation.cannot-verify-the-new-version',
153
+ });
154
+ }
155
+ }
156
+ unavailable(message) {
157
+ this.#navigation.abort();
158
+ this.#updateRevision++;
159
+ this.reader.unavailable(message);
160
+ this.catalog.reset();
161
+ this.semantic.unavailable();
162
+ this.datasources.suspend();
163
+ this.viewMemory.clear();
164
+ this.patch({ error: message, newer: undefined });
165
+ }
166
+ dispose() {
167
+ if (this.#closed)
168
+ return;
169
+ this.#closed = true;
170
+ this.#lifetime.abort();
171
+ this.reader.dispose();
172
+ this.catalog.dispose();
173
+ this.semantic.dispose();
174
+ this.datasources.dispose();
175
+ this.viewMemory.clear();
176
+ this.#listeners.clear();
177
+ }
178
+ }
@@ -0,0 +1,11 @@
1
+ /** Host-only chrome. Portable reports keep their own independent stylesheet. */
2
+ export const rightTabStyles = `
3
+ .rt-page{height:100%;width:100%;min-width:0;overflow:auto;padding:16px;box-sizing:border-box;color:var(--dsw-alias-label-primary,#182a33);background:var(--dsw-alias-bg-base,#fff);container-type:inline-size;font:14px/1.6 system-ui,sans-serif}
4
+ .rt-page *{box-sizing:border-box}.rt-page h2{font-size:18px;overflow-wrap:anywhere}.rt-page .rt-heading{margin:0 0 4px}.rt-heading-row{display:flex;align-items:center;justify-content:space-between;gap:16px;margin-bottom:4px}.rt-page .rt-heading-row .rt-heading{margin:0}.rt-heading-row>button{flex:none}.rt-caption{color:var(--dsw-alias-label-secondary,#627580);font-size:12px;margin:0 0 16px;overflow-wrap:anywhere}
5
+ .rt-toolbar{display:flex;flex-wrap:wrap;align-items:center;gap:8px;padding-bottom:12px;border-bottom:1px solid var(--dsw-alias-border-l2,#dce4e8);margin-bottom:16px}
6
+ .rt-page button,.rt-page select,.rt-page input{font:inherit;color:inherit;max-width:100%}.rt-page button{cursor:pointer;border:1px solid var(--dsw-alias-border-l2,#dce4e8);background:var(--dsw-alias-bg-base,#fff);border-radius:7px;padding:6px 10px}.rt-page button:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover,#edf4f3)}.rt-page button:disabled{opacity:.5;cursor:default}.rt-page :focus-visible{outline:2px solid var(--dsw-alias-state-business-primary,#087b70);outline-offset:3px}
7
+ .rt-page select{padding:8px;border:1px solid var(--dsw-alias-border-l2,#dce4e8);border-radius:7px;background:var(--dsw-alias-bg-base,#fff)}.rt-page [role=alert]{color:var(--dsw-alias-state-warn-label,#b14927);overflow-wrap:anywhere}.rt-notice{padding:12px;border:1px solid var(--dsw-alias-border-l2,#dce4e8);border-radius:8px;background:var(--dsw-alias-bg-module-platform,#f5f7f9)}
8
+ .rt-page .pd-catalog{padding:0;overflow:auto}.rt-page .pd-history{position:static;max-height:300px;border:1px solid var(--dsw-alias-border-l2,#dce4e8);border-radius:8px;margin-bottom:16px;width:100%}
9
+ .rt-page .rt-refresh{display:grid;place-items:center;padding:7px;border-color:transparent;background:transparent}
10
+ @container(max-width:650px){.rt-page .pr-reader{padding:24px 4px}.rt-page .pr-reader h1{font-size:25px}.rt-page .pr-block-metric{padding:14px}.rt-page .pr-metric-value{font-size:clamp(18px,7cqi,30px)}}
11
+ `;
@@ -0,0 +1,5 @@
1
+ export function createPluginRpc(rpc) {
2
+ return {
3
+ call: (channel, endpoint, payload, signal) => rpc.call('/api', `${channel.slice(1)}/${endpoint}`, payload, signal),
4
+ };
5
+ }
@@ -0,0 +1,10 @@
1
+ import { envelopeJson, refKey, SOURCE } from "../semantic-reference/contracts.js";
2
+ /** Both the @ picker and semantic details insert exactly this Host reference. */
3
+ export function semanticReference(envelope) {
4
+ return {
5
+ source: SOURCE,
6
+ ref: envelopeJson(envelope),
7
+ label: refKey(envelope.ref),
8
+ clipboardText: `@${refKey(envelope.ref)}`,
9
+ };
10
+ }
@@ -1,11 +1,24 @@
1
1
  import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useCopy } from "./i18n/context.js";
2
3
  const styles = `
3
4
  .marivo-workspace-header-action{display:inline-flex;flex:none;align-items:center;justify-content:center;gap:5px;height:32px;padding:6px 8px;border:0;border-radius:8px;background:transparent;color:inherit;font:inherit;font-size:12px;line-height:20px;white-space:nowrap;cursor:pointer}
4
5
  .marivo-workspace-header-action:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover,#7b899414)}
5
6
  .marivo-workspace-header-action:focus-visible{outline:2px solid var(--dsw-alias-label-primary,#087b70);outline-offset:2px}
6
7
  .marivo-workspace-header-action:disabled{opacity:.45;cursor:default}
8
+ /* Public slot anchors keep this layout local to the blank homepage. */
9
+ :has(> [data-slot="conversation.input.dock"] > .marivo-workspace-shortcuts){display:grid;grid-template-columns:auto minmax(0,1fr);align-items:center}
10
+ :has(> [data-slot="conversation.input.dock"] > .marivo-workspace-shortcuts)>*,
11
+ :has(> [data-slot="conversation.input.dock"] > .marivo-workspace-shortcuts)>[data-slot]>*{grid-column:1 / -1;min-width:0}
12
+ :has(> [data-slot="conversation.input.dock"] > .marivo-workspace-shortcuts)>:has(+ [data-slot="conversation.input.dock"]){grid-column:1;padding-inline-end:0}
13
+ :has(> [data-slot="conversation.input.dock"] > .marivo-workspace-shortcuts)>[data-slot]>.marivo-workspace-shortcuts{grid-column:2}
14
+ .marivo-workspace-shortcuts{display:flex;flex-wrap:wrap;align-items:center;justify-content:flex-start;gap:2px;margin:4px 0 0;padding-inline:0 16px}
15
+ .marivo-workspace-shortcuts .marivo-workspace-header-action{width:auto;height:auto;min-height:32px;padding:6px 8px;white-space:normal;text-align:start}
16
+ .marivo-workspace-shortcuts .marivo-workspace-header-action span{display:inline}
17
+ .marivo-workspace-shortcuts-error{flex-basis:100%;margin:0;text-align:start;overflow-wrap:anywhere}
7
18
  @media(max-width:640px){.marivo-workspace-header-action{width:32px;padding:8px}.marivo-workspace-header-action span{display:none}}
19
+ @media(max-width:640px){:has(> [data-slot="conversation.input.dock"] > .marivo-workspace-shortcuts){grid-template-columns:minmax(0,1fr)}:has(> [data-slot="conversation.input.dock"] > .marivo-workspace-shortcuts)>[data-slot]>.marivo-workspace-shortcuts{grid-column:1 / -1;padding-inline:16px}}
8
20
  `;
9
21
  export function WorkspaceHeaderAction({ label, icon, disabled, title, onClick, }) {
10
- return (_jsxs(_Fragment, { children: [_jsx("style", { children: styles }), _jsxs("button", { className: "marivo-workspace-header-action", type: "button", title: title ?? label, "aria-label": `打开${label}`, disabled: disabled, onClick: onClick, children: [_jsx("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.6", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: icon === 'semantic' ? (_jsx("path", { d: "m12 3 9 5-9 5-9-5 9-5Zm-9 9 9 5 9-5M3 16l9 5 9-5" })) : (_jsxs(_Fragment, { children: [_jsx("rect", { x: "4", y: "10", width: "16", height: "11", rx: "2" }), _jsx("path", { d: "M8 10V7a4 4 0 0 1 8 0v3m-4 5v2" })] })) }), _jsx("span", { children: label })] })] }));
22
+ const t = useCopy();
23
+ return (_jsxs(_Fragment, { children: [_jsx("style", { children: styles }), _jsxs("button", { className: "marivo-workspace-header-action", type: "button", title: t(title ?? label), "aria-label": t('marivo.navigation.open-value', { p0: label }), disabled: disabled, onClick: onClick, children: [_jsx("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.6", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: icon === 'reports' ? (_jsx("path", { d: "M6 3h9l4 4v14H6zM14 3v5h5M9 12h7M9 16h7" })) : icon === 'semantic' ? (_jsx("path", { d: "m12 3 9 5-9 5-9-5 9-5Zm-9 9 9 5 9-5M3 16l9 5 9-5" })) : (_jsxs(_Fragment, { children: [_jsx("rect", { x: "4", y: "10", width: "16", height: "11", rx: "2" }), _jsx("path", { d: "M8 10V7a4 4 0 0 1 8 0v3m-4 5v2" })] })) }), _jsx("span", { children: t(label) })] })] }));
11
24
  }
@@ -0,0 +1,26 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { conversationPhase, } from '@deepseek-ai/dsh-client-ui-conversation/client';
3
+ import { useState } from 'react';
4
+ import { useCopy } from "./i18n/context.js";
5
+ import { WorkspaceHeaderAction } from "./workspace-header-action.js";
6
+ export const workspaceDirectories = {
7
+ datasources: 'marivo.credentials.datasources-and-credentials',
8
+ semantic: 'marivo.navigation.semantic-layer',
9
+ reports: 'marivo.presentation.reports',
10
+ };
11
+ /** Only the Host's blank phase exposes preparation actions; drafts are untouched. */
12
+ export function WorkspaceShortcuts({ session, conversation, disabled, open, }) {
13
+ const t = useCopy();
14
+ const [error, setError] = useState('');
15
+ if (!session || !conversation || conversationPhase(session, conversation) !== 'blank')
16
+ return null;
17
+ return (_jsxs("div", { className: "marivo-workspace-shortcuts", children: [Object.entries(workspaceDirectories).map(([page, label]) => (_jsx(WorkspaceHeaderAction, { label: t(label), icon: page === 'datasources' ? 'credentials' : page, disabled: disabled, onClick: () => {
18
+ setError('');
19
+ try {
20
+ open(page);
21
+ }
22
+ catch (cause) {
23
+ setError(cause instanceof Error ? cause.message : String(cause));
24
+ }
25
+ } }, page))), error && (_jsx("p", { className: "marivo-workspace-shortcuts-error", role: "alert", children: t(error) }))] }));
26
+ }