@xpert-ai/plugin-live-dashboard 0.3.0 → 0.4.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 (153) hide show
  1. package/.xpertai-plugin/plugin.json +10 -2
  2. package/README.md +70 -0
  3. package/assets/branding/cover-v1.prompt.txt +27 -0
  4. package/assets/branding/cover-v1.webp +0 -0
  5. package/assets/previews/customer-brief.png +0 -0
  6. package/assets/previews/profit-atlas.png +0 -0
  7. package/assets/previews/trend-workspace.png +0 -0
  8. package/dist/index.js +14 -1
  9. package/dist/lib/agent.schema.d.ts +43 -37
  10. package/dist/lib/agent.schema.js +2 -1
  11. package/dist/lib/app-config.d.ts +62 -0
  12. package/dist/lib/app-config.js +38 -0
  13. package/dist/lib/artifact-type.provider.d.ts +15 -0
  14. package/dist/lib/artifact-type.provider.js +78 -0
  15. package/dist/lib/assistant-template.d.ts +2 -0
  16. package/dist/lib/assistant-template.js +7 -0
  17. package/dist/lib/content.provider.js +13 -5
  18. package/dist/lib/dashboard-navigation.d.ts +58 -14
  19. package/dist/lib/dashboard-navigation.js +11 -10
  20. package/dist/lib/dashboard-view.schema.d.ts +197 -46
  21. package/dist/lib/dashboard-view.schema.js +8 -1
  22. package/dist/lib/dashboard.service.d.ts +39 -2
  23. package/dist/lib/dashboard.service.js +52 -28
  24. package/dist/lib/document-libraries.d.ts +1 -1
  25. package/dist/lib/document-libraries.js +3 -2
  26. package/dist/lib/document-network.d.ts +1 -1
  27. package/dist/lib/document-network.js +2 -6
  28. package/dist/lib/editing-feedback.d.ts +5 -0
  29. package/dist/lib/editing-feedback.js +19 -0
  30. package/dist/lib/editing-patch.d.ts +22 -0
  31. package/dist/lib/editing-patch.js +46 -0
  32. package/dist/lib/editing-session.d.ts +167 -0
  33. package/dist/lib/editing-session.js +53 -0
  34. package/dist/lib/editing.d.ts +92 -60
  35. package/dist/lib/editing.js +36 -24
  36. package/dist/lib/html-guidance.d.ts +1 -1
  37. package/dist/lib/html-guidance.js +1 -1
  38. package/dist/lib/middleware.js +48 -20
  39. package/dist/lib/monitor.d.ts +70 -0
  40. package/dist/lib/monitor.js +101 -0
  41. package/dist/lib/plugin.js +5 -1
  42. package/dist/lib/project.d.ts +106 -0
  43. package/dist/lib/project.js +17 -0
  44. package/dist/lib/projects.schema.d.ts +49 -0
  45. package/dist/lib/projects.schema.js +7 -0
  46. package/dist/lib/projects.service.d.ts +23 -0
  47. package/dist/lib/projects.service.js +65 -0
  48. package/dist/lib/prompt-workflows.d.ts +3 -2
  49. package/dist/lib/prompt-workflows.js +17 -3
  50. package/dist/lib/provider-options.controller.d.ts +10 -0
  51. package/dist/lib/provider-options.controller.js +49 -0
  52. package/dist/lib/resource-card.js +1 -1
  53. package/dist/lib/runtime-context.d.ts +3 -0
  54. package/dist/lib/runtime-context.js +13 -0
  55. package/dist/lib/save-evidence.d.ts +1 -1
  56. package/dist/lib/templates.d.ts +2 -0
  57. package/dist/lib/templates.js +55 -0
  58. package/dist/lib/view.provider.d.ts +97 -7
  59. package/dist/lib/view.provider.js +39 -10
  60. package/dist/libraries/TREND-WORKSPACE-ICONS-LICENSE.txt +43 -0
  61. package/dist/libraries/catalog.json +1 -1
  62. package/dist/remote/app.css +1 -1
  63. package/dist/remote/app.js +33 -33
  64. package/dist/remote/build-manifest.json +118 -32
  65. package/dist/sandbox-actions/action.json +1 -1
  66. package/dist/sandbox-actions/bundle/host.js +2 -2
  67. package/dist/sandbox-actions/bundle/resource-cache.mjs +2 -1
  68. package/dist/sandbox-actions/bundle/validate.mjs +1 -1
  69. package/docs/docs.json +7 -0
  70. package/docs/frontend-libraries.mdx +12 -4
  71. package/docs/html-mode.md +3 -3
  72. package/docs/quick-start-acceptance.mdx +50 -0
  73. package/docs/quick-start.mdx +64 -0
  74. package/docs/superstore.mdx +38 -0
  75. package/docs/team-sharing.mdx +6 -2
  76. package/docs/trend-workspace-acceptance.mdx +43 -0
  77. package/docs/trend-workspace.mdx +30 -0
  78. package/docs/verification.mdx +4 -2
  79. package/docs/visual-styles-acceptance.mdx +40 -0
  80. package/docs/visual-styles.mdx +46 -0
  81. package/package.json +25 -18
  82. package/scripts/import-prompts.mjs +108 -0
  83. package/skills/live-dashboard/SKILL.md +27 -3
  84. package/skills/live-dashboard/examples/README.md +25 -0
  85. package/skills/live-dashboard/examples/catalog.json +79 -0
  86. package/skills/live-dashboard/examples/production-quality/README.md +25 -0
  87. package/skills/live-dashboard/examples/production-quality/dashboard.html +129 -0
  88. package/skills/live-dashboard/examples/production-quality/definition.json +67 -0
  89. package/skills/live-dashboard/examples/production-quality/demo.csv +7 -0
  90. package/skills/live-dashboard/examples/production-quality/demo.json +44 -0
  91. package/skills/live-dashboard/examples/production-quality/expected.json +26 -0
  92. package/skills/live-dashboard/examples/production-quality/preview.png +0 -0
  93. package/skills/live-dashboard/examples/production-quality/query.json +53 -0
  94. package/skills/live-dashboard/examples/regional-sales/README.md +25 -0
  95. package/skills/live-dashboard/examples/regional-sales/dashboard-create.json +35 -0
  96. package/skills/live-dashboard/examples/regional-sales/definition.json +35 -0
  97. package/skills/live-dashboard/examples/regional-sales/demo.csv +5 -0
  98. package/skills/live-dashboard/examples/regional-sales/demo.json +18 -0
  99. package/skills/live-dashboard/examples/regional-sales/expected.json +19 -0
  100. package/skills/live-dashboard/examples/regional-sales/preview.png +0 -0
  101. package/skills/live-dashboard/examples/regional-sales/query.json +45 -0
  102. package/skills/live-dashboard/examples/sales-overview/README.md +25 -0
  103. package/skills/live-dashboard/examples/sales-overview/dashboard.html +129 -0
  104. package/skills/live-dashboard/examples/sales-overview/definition.json +57 -0
  105. package/skills/live-dashboard/examples/sales-overview/demo.csv +7 -0
  106. package/skills/live-dashboard/examples/sales-overview/demo.json +38 -0
  107. package/skills/live-dashboard/examples/sales-overview/expected.json +22 -0
  108. package/skills/live-dashboard/examples/sales-overview/preview.png +0 -0
  109. package/skills/live-dashboard/examples/sales-overview/query.json +52 -0
  110. package/skills/live-dashboard/examples/superstore/README.md +64 -0
  111. package/skills/live-dashboard/examples/superstore/THIRD_PARTY_LICENSE.txt +207 -0
  112. package/skills/live-dashboard/examples/superstore/build_data.py +155 -0
  113. package/skills/live-dashboard/examples/superstore/build_pages.py +129 -0
  114. package/skills/live-dashboard/examples/superstore/checks.json +104 -0
  115. package/skills/live-dashboard/examples/superstore/customers-mobile-dark.png +0 -0
  116. package/skills/live-dashboard/examples/superstore/customers-select.png +0 -0
  117. package/skills/live-dashboard/examples/superstore/customers.html +316 -0
  118. package/skills/live-dashboard/examples/superstore/customers.png +0 -0
  119. package/skills/live-dashboard/examples/superstore/customers.queries.json +512 -0
  120. package/skills/live-dashboard/examples/superstore/expected.json +4069 -0
  121. package/skills/live-dashboard/examples/superstore/import.json +200 -0
  122. package/skills/live-dashboard/examples/superstore/orders.csv +10195 -0
  123. package/skills/live-dashboard/examples/superstore/overview-mobile-dark.png +0 -0
  124. package/skills/live-dashboard/examples/superstore/overview-select.png +0 -0
  125. package/skills/live-dashboard/examples/superstore/overview.html +310 -0
  126. package/skills/live-dashboard/examples/superstore/overview.png +0 -0
  127. package/skills/live-dashboard/examples/superstore/overview.queries.json +636 -0
  128. package/skills/live-dashboard/examples/superstore/page.js +109 -0
  129. package/skills/live-dashboard/examples/superstore/profitability-mobile-dark.png +0 -0
  130. package/skills/live-dashboard/examples/superstore/profitability-select.png +0 -0
  131. package/skills/live-dashboard/examples/superstore/profitability.html +307 -0
  132. package/skills/live-dashboard/examples/superstore/profitability.png +0 -0
  133. package/skills/live-dashboard/examples/superstore/profitability.queries.json +334 -0
  134. package/skills/live-dashboard/examples/superstore/provenance.json +24 -0
  135. package/skills/live-dashboard/examples/superstore/semantic-model.json +220 -0
  136. package/skills/live-dashboard/examples/superstore/test_data.py +62 -0
  137. package/skills/live-dashboard/references/html-runtime.md +1 -1
  138. package/skills/live-dashboard/themes/README.md +50 -0
  139. package/skills/live-dashboard/themes/customer-brief/README.md +47 -0
  140. package/skills/live-dashboard/themes/customer-brief/charts.js +17 -0
  141. package/skills/live-dashboard/themes/customer-brief/layout.html +22 -0
  142. package/skills/live-dashboard/themes/customer-brief/theme.css +108 -0
  143. package/skills/live-dashboard/themes/profit-atlas/README.md +43 -0
  144. package/skills/live-dashboard/themes/profit-atlas/charts.js +30 -0
  145. package/skills/live-dashboard/themes/profit-atlas/layout.html +19 -0
  146. package/skills/live-dashboard/themes/profit-atlas/theme.css +75 -0
  147. package/skills/live-dashboard/themes/trend-workspace/ICON_LICENSE.txt +43 -0
  148. package/skills/live-dashboard/themes/trend-workspace/README.md +144 -0
  149. package/skills/live-dashboard/themes/trend-workspace/charts.js +60 -0
  150. package/skills/live-dashboard/themes/trend-workspace/icons.js +11 -0
  151. package/skills/live-dashboard/themes/trend-workspace/layout.html +45 -0
  152. package/skills/live-dashboard/themes/trend-workspace/select.js +127 -0
  153. package/skills/live-dashboard/themes/trend-workspace/theme.css +137 -0
@@ -0,0 +1,70 @@
1
+ import { z } from 'zod/v3';
2
+ import { type AgentMiddleware, type IAgentMiddlewareStrategy, type IAgentMiddlewareContext } from '@xpert-ai/plugin-sdk';
3
+ import type { TAgentMiddlewareMeta, XpertResolvedViewHostContext } from '@xpert-ai/contracts';
4
+ import { DashboardService } from './dashboard.service';
5
+ declare const freshnessRuleSchema: z.ZodObject<{
6
+ bindingId: z.ZodString;
7
+ fieldId: z.ZodString;
8
+ maxAgeSeconds: z.ZodNumber;
9
+ }, "strict", z.ZodTypeAny, {
10
+ bindingId: string;
11
+ fieldId: string;
12
+ maxAgeSeconds: number;
13
+ }, {
14
+ bindingId: string;
15
+ fieldId: string;
16
+ maxAgeSeconds: number;
17
+ }>;
18
+ type FreshnessRule = z.infer<typeof freshnessRuleSchema>;
19
+ export declare class DashboardMonitor {
20
+ private readonly dashboards;
21
+ constructor(dashboards: DashboardService);
22
+ inspect(context: XpertResolvedViewHostContext, artifactId: string, freshnessRule?: FreshnessRule): Promise<{
23
+ artifactId: string;
24
+ versionId: string;
25
+ title: string;
26
+ status: "attention" | "healthy";
27
+ checkedAt: string;
28
+ failures: {
29
+ bindingId: string;
30
+ datasetId: string;
31
+ reason: "unavailable";
32
+ }[];
33
+ datasets: {
34
+ datasetId: string;
35
+ queryFetchedAt: string;
36
+ truncated: boolean;
37
+ returnedRows: number;
38
+ }[];
39
+ businessFreshness: {
40
+ status: "unknown" | "stale" | "fresh";
41
+ latestTimestamp: string | null;
42
+ coverage: "latest_returned_timestamp";
43
+ bindingId: string;
44
+ fieldId: string;
45
+ maxAgeSeconds: number;
46
+ } | "not_asserted";
47
+ availableFreshnessFields: {
48
+ bindingId: string;
49
+ fieldId: string;
50
+ label: string;
51
+ }[];
52
+ }>;
53
+ }
54
+ export declare class DashboardMonitorMiddleware implements IAgentMiddlewareStrategy {
55
+ private readonly monitor;
56
+ private readonly dashboards;
57
+ readonly meta: TAgentMiddlewareMeta;
58
+ constructor(monitor: DashboardMonitor, dashboards: DashboardService);
59
+ createMiddleware(options: unknown, context: IAgentMiddlewareContext): AgentMiddleware;
60
+ }
61
+ /** Business freshness must be an explicit data contract, never the query fetch timestamp. */
62
+ export declare function assessFreshness(manifest: import('./dashboard.schema').DashboardManifest, datasets: import('@xpert-ai/contracts').AnalyticalDataset[], input: FreshnessRule, now: number): {
63
+ status: "unknown" | "stale" | "fresh";
64
+ latestTimestamp: string | null;
65
+ coverage: "latest_returned_timestamp";
66
+ bindingId: string;
67
+ fieldId: string;
68
+ maxAgeSeconds: number;
69
+ };
70
+ export {};
@@ -0,0 +1,101 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.DashboardMonitorMiddleware = exports.DashboardMonitor = void 0;
13
+ exports.assessFreshness = assessFreshness;
14
+ const common_1 = require("@nestjs/common");
15
+ const tools_1 = require("@langchain/core/tools");
16
+ const v3_1 = require("zod/v3");
17
+ const plugin_sdk_1 = require("@xpert-ai/plugin-sdk");
18
+ const dashboard_service_1 = require("./dashboard.service");
19
+ const runtime_context_1 = require("./runtime-context");
20
+ const dashboard_icon_1 = require("./dashboard-icon");
21
+ const freshnessRuleSchema = v3_1.z.object({ bindingId: v3_1.z.string().min(1), fieldId: v3_1.z.string().min(1), maxAgeSeconds: v3_1.z.number().int().min(1).max(31536000) }).strict();
22
+ let DashboardMonitor = class DashboardMonitor {
23
+ constructor(dashboards) {
24
+ this.dashboards = dashboards;
25
+ }
26
+ async inspect(context, artifactId, freshnessRule) {
27
+ const access = await this.dashboards.access(context);
28
+ if (!access.project || access.archived)
29
+ throw new common_1.ForbiddenException('DASHBOARD_ACTIVE_PROJECT_REQUIRED');
30
+ const saved = await this.dashboards.open(context, artifactId, undefined, undefined, 'published');
31
+ if (!saved.versionId)
32
+ throw new Error('DASHBOARD_NOT_PUBLISHED');
33
+ const result = await this.dashboards.query(context, artifactId, saved.versionId, {});
34
+ // Reauthorize the target after the queries; a receipt is bound to this formal version.
35
+ const current = await this.dashboards.open(context, artifactId, undefined, undefined, 'published');
36
+ if (current.versionId !== saved.versionId || (await this.dashboards.access(context)).archived)
37
+ throw new Error('DASHBOARD_INSPECTION_CHANGED');
38
+ const freshness = freshnessRule ? assessFreshness(saved.manifest, result.datasets, freshnessRule, Date.now()) : undefined;
39
+ return { artifactId, versionId: saved.versionId, title: saved.manifest.title,
40
+ status: result.failures.length || freshness && freshness.status !== 'fresh' ? 'attention' : 'healthy',
41
+ checkedAt: new Date().toISOString(), failures: result.failures,
42
+ datasets: result.datasets.map(dataset => ({ datasetId: dataset.datasetId, queryFetchedAt: dataset.freshness.sourceFetchedAt,
43
+ truncated: dataset.completeness.truncated, returnedRows: dataset.completeness.returnedRows })),
44
+ businessFreshness: freshness ?? 'not_asserted',
45
+ availableFreshnessFields: saved.manifest.bindings.flatMap(binding => binding.output.fields.filter(field => field.logicalType === 'timestamp')
46
+ .map(field => ({ bindingId: binding.id, fieldId: field.id, label: field.label }))) };
47
+ }
48
+ };
49
+ exports.DashboardMonitor = DashboardMonitor;
50
+ exports.DashboardMonitor = DashboardMonitor = __decorate([
51
+ (0, common_1.Injectable)(),
52
+ __metadata("design:paramtypes", [dashboard_service_1.DashboardService])
53
+ ], DashboardMonitor);
54
+ let DashboardMonitorMiddleware = class DashboardMonitorMiddleware {
55
+ constructor(monitor, dashboards) {
56
+ this.monitor = monitor;
57
+ this.dashboards = dashboards;
58
+ this.meta = { name: 'LiveDashboardMonitor', icon: dashboard_icon_1.dashboardIcon, features: ['live_dashboard.monitor'],
59
+ label: { en_US: 'Dashboard inspection', zh_Hans: '看板巡检' },
60
+ description: { en_US: 'Inspect published Project dashboards without editing or publishing.', zh_Hans: '检查项目正式看板,不修改或发布。' },
61
+ configSchema: { type: 'object', properties: {}, additionalProperties: false } };
62
+ }
63
+ createMiddleware(options, context) {
64
+ v3_1.z.object({}).strict().parse(options ?? {});
65
+ const scope = (0, runtime_context_1.dashboardRuntimeContext)(context);
66
+ return { name: 'LiveDashboardMonitor', tools: [
67
+ (0, tools_1.tool)(async ({ artifactId, freshness }) => JSON.stringify(await this.monitor.inspect(scope, artifactId, freshness)), {
68
+ name: 'dashboard_inspect', description: 'Check one explicitly selected published Project dashboard as the current run actor. Returns compact binding availability and query timestamps, never data rows. Does not modify or publish. Query time is not proof of business-data freshness. Only an explicitly configured freshness rule checks the latest returned declared timestamp, and incomplete results remain unknown. Scheduled runs retain this receipt in platform execution history.',
69
+ schema: v3_1.z.object({ artifactId: v3_1.z.string().uuid(), freshness: freshnessRuleSchema.optional() }).strict(), verboseParsingErrors: true,
70
+ metadata: { toolName: { en_US: 'Inspect published dashboard', zh_Hans: '巡检正式看板' } }
71
+ }),
72
+ (0, tools_1.tool)(async ({ page }) => {
73
+ const access = await this.dashboards.access(scope);
74
+ if (!access.project || access.archived)
75
+ throw new common_1.ForbiddenException('DASHBOARD_ACTIVE_PROJECT_REQUIRED');
76
+ const result = await this.dashboards.listPage(scope, page, 50);
77
+ return JSON.stringify({ ...result, items: result.items.filter(item => !!item.versionId).map(({ artifactId, versionId, versionNumber, title }) => ({ artifactId, versionId, versionNumber, title })) });
78
+ }, { name: 'dashboard_list_published', description: 'List published dashboards in the current Project. Follow hasMore/page; never infer the target from recency.',
79
+ schema: v3_1.z.object({ page: v3_1.z.number().int().positive().default(1) }).strict(), verboseParsingErrors: true,
80
+ metadata: { toolName: { en_US: 'List published dashboards', zh_Hans: '列出正式看板' } } })
81
+ ] };
82
+ }
83
+ };
84
+ exports.DashboardMonitorMiddleware = DashboardMonitorMiddleware;
85
+ exports.DashboardMonitorMiddleware = DashboardMonitorMiddleware = __decorate([
86
+ (0, plugin_sdk_1.AgentMiddlewareStrategy)('LiveDashboardMonitor'),
87
+ __metadata("design:paramtypes", [DashboardMonitor, dashboard_service_1.DashboardService])
88
+ ], DashboardMonitorMiddleware);
89
+ /** Business freshness must be an explicit data contract, never the query fetch timestamp. */
90
+ function assessFreshness(manifest, datasets, input, now) {
91
+ const rule = freshnessRuleSchema.parse(input);
92
+ const binding = manifest.bindings.find(binding => binding.id === rule.bindingId);
93
+ const field = binding?.output.fields.find(field => field.id === rule.fieldId && field.logicalType === 'timestamp');
94
+ const dataset = datasets.find(dataset => dataset.datasetId === binding?.output.datasetId);
95
+ const values = dataset?.rows.map(row => row[rule.fieldId]) ?? [];
96
+ const times = values.map(value => typeof value === 'string' && /(?:Z|[+-]\d{2}:\d{2})$/.test(value) ? Date.parse(value) : NaN);
97
+ const unknown = !field || !dataset || dataset.completeness.truncated || !times.length || times.some(time => !Number.isFinite(time) || time > now + 60000);
98
+ const latest = unknown ? null : times.reduce((latest, time) => Math.max(latest, time), -Infinity);
99
+ return { ...rule, status: unknown ? 'unknown' : now - latest > rule.maxAgeSeconds * 1000 ? 'stale' : 'fresh',
100
+ latestTimestamp: latest === null ? null : new Date(latest).toISOString(), coverage: 'latest_returned_timestamp' };
101
+ }
@@ -7,7 +7,9 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
7
7
  };
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
9
  exports.LiveDashboardPlugin = void 0;
10
+ const projects_service_1 = require("./projects.service");
10
11
  const content_capability_1 = require("./content-capability");
12
+ const monitor_1 = require("./monitor");
11
13
  const content_provider_1 = require("./content.provider");
12
14
  const plugin_sdk_1 = require("@xpert-ai/plugin-sdk");
13
15
  const dashboard_service_1 = require("./dashboard.service");
@@ -16,9 +18,11 @@ const middleware_1 = require("./middleware");
16
18
  const html_validation_1 = require("./html-validation");
17
19
  const presentation_provider_1 = require("./presentation.provider");
18
20
  const sharing_service_1 = require("./sharing.service");
21
+ const artifact_type_provider_1 = require("./artifact-type.provider");
22
+ const provider_options_controller_1 = require("./provider-options.controller");
19
23
  let LiveDashboardPlugin = class LiveDashboardPlugin {
20
24
  };
21
25
  exports.LiveDashboardPlugin = LiveDashboardPlugin;
22
26
  exports.LiveDashboardPlugin = LiveDashboardPlugin = __decorate([
23
- (0, plugin_sdk_1.XpertServerPlugin)({ providers: [content_capability_1.DashboardCapability, content_provider_1.DashboardContentProvider, content_provider_1.DashboardContentEditor, dashboard_service_1.DashboardService, view_provider_1.DashboardViewProvider, middleware_1.DashboardMiddleware, html_validation_1.HtmlDashboardValidation, presentation_provider_1.DashboardPresentationProvider, sharing_service_1.DashboardSharingService] })
27
+ (0, plugin_sdk_1.XpertServerPlugin)({ controllers: [provider_options_controller_1.DashboardProviderOptionsController], providers: [projects_service_1.DashboardProjectsService, monitor_1.DashboardMonitor, monitor_1.DashboardMonitorMiddleware, artifact_type_provider_1.DashboardArtifactType, content_capability_1.DashboardCapability, content_provider_1.DashboardContentProvider, content_provider_1.DashboardContentEditor, dashboard_service_1.DashboardService, view_provider_1.DashboardViewProvider, middleware_1.DashboardMiddleware, html_validation_1.HtmlDashboardValidation, presentation_provider_1.DashboardPresentationProvider, sharing_service_1.DashboardSharingService] })
24
28
  ], LiveDashboardPlugin);
@@ -0,0 +1,106 @@
1
+ export declare const DASHBOARD_PROJECT_TYPE: {
2
+ readonly applicationKey: "@xpert-ai/plugin-live-dashboard:live-dashboard";
3
+ readonly projectTypeKey: "dashboard";
4
+ };
5
+ export declare const dashboardApp: {
6
+ type: "app";
7
+ name: string;
8
+ icon: {
9
+ type: "svg";
10
+ alt: string;
11
+ value: string;
12
+ };
13
+ appConfig: {
14
+ scope: "organization";
15
+ assistantTemplateKey: string;
16
+ workspace: {
17
+ mode: "dedicated";
18
+ sharing: "private";
19
+ name: {
20
+ en_US: string;
21
+ zh_Hans: string;
22
+ };
23
+ description: {
24
+ en_US: string;
25
+ zh_Hans: string;
26
+ };
27
+ };
28
+ knowledgebases: never[];
29
+ modelRequirements: {
30
+ primary: true;
31
+ };
32
+ presentation: {
33
+ developer: string;
34
+ tagline: {
35
+ en_US: string;
36
+ zh_Hans: string;
37
+ };
38
+ longDescription: {
39
+ en_US: string;
40
+ zh_Hans: string;
41
+ };
42
+ screenshots: string[];
43
+ features: {
44
+ key: string;
45
+ title: {
46
+ en_US: string;
47
+ zh_Hans: string;
48
+ };
49
+ description: {
50
+ en_US: string;
51
+ zh_Hans: string;
52
+ };
53
+ }[];
54
+ useCases: {
55
+ en_US: string;
56
+ zh_Hans: string;
57
+ }[];
58
+ dataScope: {
59
+ en_US: string;
60
+ zh_Hans: string;
61
+ };
62
+ initializationSummary: {
63
+ en_US: string;
64
+ zh_Hans: string;
65
+ };
66
+ initializationSteps: {
67
+ en_US: string;
68
+ zh_Hans: string;
69
+ }[];
70
+ };
71
+ entry: {
72
+ type: "assistant-chat";
73
+ };
74
+ };
75
+ displayName: {
76
+ en_US: string;
77
+ zh_Hans: string;
78
+ };
79
+ description: {
80
+ en_US: string;
81
+ zh_Hans: string;
82
+ };
83
+ projectTypes: {
84
+ key: "dashboard";
85
+ title: {
86
+ en_US: string;
87
+ zh_Hans: string;
88
+ };
89
+ icon: {
90
+ type: "svg";
91
+ alt: string;
92
+ value: string;
93
+ };
94
+ binding: {
95
+ kind: "project";
96
+ };
97
+ }[];
98
+ };
99
+ export type DashboardAccess = {
100
+ project: boolean;
101
+ archived: boolean;
102
+ canReadDraft: boolean;
103
+ canEdit: boolean;
104
+ canManage: boolean;
105
+ };
106
+ export type DashboardMode = 'published' | 'draft';
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.dashboardApp = exports.DASHBOARD_PROJECT_TYPE = void 0;
4
+ const dashboard_icon_1 = require("./dashboard-icon");
5
+ const app_config_1 = require("./app-config");
6
+ exports.DASHBOARD_PROJECT_TYPE = {
7
+ applicationKey: '@xpert-ai/plugin-live-dashboard:live-dashboard', projectTypeKey: 'dashboard'
8
+ };
9
+ exports.dashboardApp = {
10
+ type: 'app', name: 'live-dashboard', icon: dashboard_icon_1.dashboardIcon,
11
+ appConfig: app_config_1.dashboardAppConfig,
12
+ displayName: { en_US: 'Live Dashboard', zh_Hans: '实时看板' },
13
+ description: { en_US: 'Create and use live dashboards in Assistant ChatKit with a synchronized Project selection.', zh_Hans: '在助理 ChatKit 中按项目制作和使用实时看板,项目选择双向同步。' },
14
+ projectTypes: [{ key: exports.DASHBOARD_PROJECT_TYPE.projectTypeKey,
15
+ title: { en_US: 'Live Dashboard project', zh_Hans: '实时看板项目' }, icon: dashboard_icon_1.dashboardIcon,
16
+ binding: { kind: 'project' } }]
17
+ };
@@ -0,0 +1,49 @@
1
+ import { z } from 'zod/v3';
2
+ export declare const projectSearchSchema: z.ZodObject<{
3
+ search: z.ZodDefault<z.ZodString>;
4
+ page: z.ZodDefault<z.ZodNumber>;
5
+ }, "strict", z.ZodTypeAny, {
6
+ search: string;
7
+ page: number;
8
+ }, {
9
+ search?: string | undefined;
10
+ page?: number | undefined;
11
+ }>;
12
+ export declare const dashboardProjectSchema: z.ZodObject<{
13
+ id: z.ZodString;
14
+ name: z.ZodString;
15
+ }, "strip", z.ZodTypeAny, {
16
+ id: string;
17
+ name: string;
18
+ }, {
19
+ id: string;
20
+ name: string;
21
+ }>;
22
+ export declare const dashboardProjectsSchema: z.ZodObject<{
23
+ items: z.ZodArray<z.ZodObject<{
24
+ id: z.ZodString;
25
+ name: z.ZodString;
26
+ }, "strip", z.ZodTypeAny, {
27
+ id: string;
28
+ name: string;
29
+ }, {
30
+ id: string;
31
+ name: string;
32
+ }>, "many">;
33
+ page: z.ZodNumber;
34
+ hasMore: z.ZodBoolean;
35
+ }, "strip", z.ZodTypeAny, {
36
+ page: number;
37
+ items: {
38
+ id: string;
39
+ name: string;
40
+ }[];
41
+ hasMore: boolean;
42
+ }, {
43
+ page: number;
44
+ items: {
45
+ id: string;
46
+ name: string;
47
+ }[];
48
+ hasMore: boolean;
49
+ }>;
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.dashboardProjectsSchema = exports.dashboardProjectSchema = exports.projectSearchSchema = void 0;
4
+ const v3_1 = require("zod/v3");
5
+ exports.projectSearchSchema = v3_1.z.object({ search: v3_1.z.string().trim().max(200).default(''), page: v3_1.z.number().int().positive().default(1) }).strict();
6
+ exports.dashboardProjectSchema = v3_1.z.object({ id: v3_1.z.string().uuid(), name: v3_1.z.string() });
7
+ exports.dashboardProjectsSchema = v3_1.z.object({ items: v3_1.z.array(exports.dashboardProjectSchema), page: v3_1.z.number().int().positive(), hasMore: v3_1.z.boolean() });
@@ -0,0 +1,23 @@
1
+ import { z } from 'zod/v3';
2
+ import type { XpertResolvedViewHostContext } from '@xpert-ai/contracts';
3
+ import { type RuntimeCapabilityRegistry } from '@xpert-ai/plugin-sdk';
4
+ import { projectSearchSchema } from './projects.schema';
5
+ export { projectSearchSchema } from './projects.schema';
6
+ /** Selection uses the host's membership and Assistant binding policy, never a client-supplied data scope. */
7
+ export declare class DashboardProjectsService {
8
+ private readonly runtime;
9
+ constructor(runtime: RuntimeCapabilityRegistry);
10
+ private actor;
11
+ current(context: XpertResolvedViewHostContext): Promise<{
12
+ id: string;
13
+ name: string;
14
+ } | null>;
15
+ list(context: XpertResolvedViewHostContext, input: z.infer<typeof projectSearchSchema>): Promise<{
16
+ items: {
17
+ id: string;
18
+ name: string;
19
+ }[];
20
+ page: number;
21
+ hasMore: boolean;
22
+ }>;
23
+ }
@@ -0,0 +1,65 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
12
+ return function (target, key) { decorator(target, key, paramIndex); }
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.DashboardProjectsService = exports.projectSearchSchema = void 0;
16
+ const common_1 = require("@nestjs/common");
17
+ const plugin_sdk_1 = require("@xpert-ai/plugin-sdk");
18
+ const dashboard_service_1 = require("./dashboard.service");
19
+ var projects_schema_1 = require("./projects.schema");
20
+ Object.defineProperty(exports, "projectSearchSchema", { enumerable: true, get: function () { return projects_schema_1.projectSearchSchema; } });
21
+ /** Selection uses the host's membership and Assistant binding policy, never a client-supplied data scope. */
22
+ let DashboardProjectsService = class DashboardProjectsService {
23
+ constructor(runtime) {
24
+ this.runtime = runtime;
25
+ }
26
+ actor(context) {
27
+ if (context.hostType !== 'agent' || !context.tenantId || !context.organizationId || !context.userId)
28
+ throw new common_1.ForbiddenException('DASHBOARD_ACCESS_DENIED');
29
+ return { tenantId: context.tenantId, organizationId: context.organizationId, userId: context.userId };
30
+ }
31
+ async current(context) {
32
+ const id = (0, dashboard_service_1.projectId)(context);
33
+ if (!id)
34
+ return null;
35
+ const access = await this.runtime.require(plugin_sdk_1.ProjectAccessRuntimeCapability).assertAssistant({ actor: this.actor(context), projectId: id, assistantId: context.hostId });
36
+ return { id, name: access.name ?? id };
37
+ }
38
+ async list(context, input) {
39
+ const actor = this.actor(context), access = this.runtime.require(plugin_sdk_1.ProjectAccessRuntimeCapability);
40
+ const projects = await access.listReadable({ actor });
41
+ const items = [];
42
+ for (const project of projects) {
43
+ if (project.archived || !(project.name ?? project.projectId).toLocaleLowerCase().includes(input.search.toLocaleLowerCase()))
44
+ continue;
45
+ try {
46
+ await access.assertAssistant({ actor, projectId: project.projectId, assistantId: context.hostId });
47
+ }
48
+ catch (error) {
49
+ if (error instanceof common_1.ForbiddenException)
50
+ continue;
51
+ throw error;
52
+ }
53
+ items.push({ id: project.projectId, name: project.name ?? project.projectId });
54
+ }
55
+ items.sort((a, b) => a.name.localeCompare(b.name) || a.id.localeCompare(b.id));
56
+ const start = (input.page - 1) * 20;
57
+ return { items: items.slice(start, start + 20), page: input.page, hasMore: start + 20 < items.length };
58
+ }
59
+ };
60
+ exports.DashboardProjectsService = DashboardProjectsService;
61
+ exports.DashboardProjectsService = DashboardProjectsService = __decorate([
62
+ (0, common_1.Injectable)(),
63
+ __param(0, (0, common_1.Inject)(plugin_sdk_1.XPERT_RUNTIME_CAPABILITIES_TOKEN)),
64
+ __metadata("design:paramtypes", [Object])
65
+ ], DashboardProjectsService);
@@ -1,3 +1,4 @@
1
- import type { SkillSlashCommand } from '@xpert-ai/contracts';
2
- /** Commands are resolved from the installed middleware, including on existing Assistants. */
1
+ import type { SkillSlashCommand, TPromptWorkflow } from '@xpert-ai/contracts';
3
2
  export declare const dashboardPromptWorkflows: SkillSlashCommand[];
3
+ /** Separate names keep the host's middleware-first merge from hiding these editable shortcuts. */
4
+ export declare const dashboardWorkspacePrompts: TPromptWorkflow[];
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.dashboardPromptWorkflows = void 0;
3
+ exports.dashboardWorkspacePrompts = exports.dashboardPromptWorkflows = void 0;
4
4
  const dashboard_icon_1 = require("./dashboard-icon");
5
5
  const context = `Work in the current authorized Assistant/project scope. Use the user's language for the page and response. Read the installed live-dashboard skill through read_skill_file and follow the references relevant to this task. Respect provider policy, access controls and tool schemas. Never change deployment, credentials, Assistant configuration or business-source data.
6
6
  Resolve source/provider pairs, Artifact IDs, fields and file paths from current tools, not names or previous conversation claims. Use only real query results; no invented business data, targets, thresholds, comparison periods or activity feeds. Keep queries read-only and bounded. Report actual tool failures and diagnosticId when supplied. A missing capability or runtime binding is a blocker, not permission to bypass validation or switch presentation modes.`;
@@ -30,7 +30,7 @@ function command(prompt) {
30
30
  };
31
31
  }
32
32
  /** Commands are resolved from the installed middleware, including on existing Assistants. */
33
- exports.dashboardPromptWorkflows = [
33
+ const prompts = [
34
34
  {
35
35
  name: 'dashboard-standard-auto', group: 'standard',
36
36
  label: { en_US: 'Standard · Choose a business theme', zh_Hans: '标准看板 · 自动选题新建' },
@@ -115,4 +115,18 @@ exports.dashboardPromptWorkflows = [
115
115
  argsHint: '目标看板、筛选场景、预期业务结果(可选)',
116
116
  instructions: ['Acceptance only. Resolve the exact requested Artifact, open its current saved state with dashboard_open and record its identity/revision. Do not modify files, call save tools, publish or change source data. Preview its saved Bindings with actual defaults and observed alternative filter values; use dashboard_test_filter to validate affected queries and the null/all case. For HTML inspect its saved lifecycle and dependency contract as well. If actual viewer controls can be exercised through available authorized tools, check initial load, apply filters, refresh and reopening. Otherwise mark viewer behavior untested and give at most three manual actions with observable expected results. Do not equate a successful query or resource card with a verified browser interaction.']
117
117
  }
118
- ].map(command);
118
+ ];
119
+ exports.dashboardPromptWorkflows = prompts.map(command);
120
+ /** Separate names keep the host's middleware-first merge from hiding these editable shortcuts. */
121
+ exports.dashboardWorkspacePrompts = prompts.map((prompt) => ({
122
+ name: `live-${prompt.name}`,
123
+ label: prompt.label.zh_Hans,
124
+ description: prompt.description.zh_Hans,
125
+ icon: dashboard_icon_1.dashboardIcon,
126
+ category: 'live-dashboard',
127
+ argsHint: prompt.argsHint,
128
+ template: [context, ...prompt.instructions, 'User requirements / 用户需求:', '{{args}}'].join('\n\n'),
129
+ actionType: 'insert_text',
130
+ tags: ['live-dashboard', prompt.group],
131
+ visibility: 'team'
132
+ }));
@@ -0,0 +1,10 @@
1
+ import { type RuntimeCapabilityRegistry } from '@xpert-ai/plugin-sdk';
2
+ export declare class DashboardProviderOptionsController {
3
+ private readonly runtime;
4
+ constructor(runtime: RuntimeCapabilityRegistry);
5
+ list(): Promise<{
6
+ value: string;
7
+ label: string;
8
+ description: string;
9
+ }[]>;
10
+ }
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
12
+ return function (target, key) { decorator(target, key, paramIndex); }
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.DashboardProviderOptionsController = void 0;
16
+ const common_1 = require("@nestjs/common");
17
+ const plugin_sdk_1 = require("@xpert-ai/plugin-sdk");
18
+ let DashboardProviderOptionsController = class DashboardProviderOptionsController {
19
+ constructor(runtime) {
20
+ this.runtime = runtime;
21
+ }
22
+ async list() {
23
+ const tenantId = plugin_sdk_1.RequestContext.currentTenantId();
24
+ const organizationId = plugin_sdk_1.RequestContext.getOrganizationId();
25
+ const userId = plugin_sdk_1.RequestContext.currentUserId();
26
+ if (!tenantId || !organizationId || !userId)
27
+ throw new common_1.UnauthorizedException();
28
+ // The host revalidates the actor and filters source access; never accept scope from query parameters.
29
+ const sources = await this.runtime.require(plugin_sdk_1.AnalyticsRuntimeCapability).list({ tenantId, organizationId, userId });
30
+ const options = new Map();
31
+ for (const source of sources)
32
+ for (const provider of source.providers) {
33
+ options.set(provider.id, { value: provider.id, label: provider.name, description: provider.id });
34
+ }
35
+ return [...options.values()].sort((left, right) => left.value.localeCompare(right.value));
36
+ }
37
+ };
38
+ exports.DashboardProviderOptionsController = DashboardProviderOptionsController;
39
+ __decorate([
40
+ (0, common_1.Get)(),
41
+ __metadata("design:type", Function),
42
+ __metadata("design:paramtypes", []),
43
+ __metadata("design:returntype", Promise)
44
+ ], DashboardProviderOptionsController.prototype, "list", null);
45
+ exports.DashboardProviderOptionsController = DashboardProviderOptionsController = __decorate([
46
+ (0, common_1.Controller)('live-dashboard/provider-options'),
47
+ __param(0, (0, common_1.Inject)(plugin_sdk_1.XPERT_RUNTIME_CAPABILITIES_TOKEN)),
48
+ __metadata("design:paramtypes", [Object])
49
+ ], DashboardProviderOptionsController);
@@ -16,7 +16,7 @@ function dashboardResourceCard(scope, saved) {
16
16
  icon: { type: dashboard_icon_1.dashboardIcon.type, value: dashboard_icon_1.dashboardIcon.value },
17
17
  open: {
18
18
  ...(0, dashboard_navigation_1.dashboardNavigationTarget)(scope), selectionId: saved.artifactId,
19
- ...(saved.state === 'published' && saved.versionId ? { parameters: { versionId: saved.versionId } } : {})
19
+ parameters: saved.state === 'published' && saved.versionId ? { versionId: saved.versionId } : { mode: 'draft' }
20
20
  }
21
21
  };
22
22
  }
@@ -0,0 +1,3 @@
1
+ import type { XpertResolvedViewHostContext } from '@xpert-ai/contracts';
2
+ import { type IAgentMiddlewareContext } from '@xpert-ai/plugin-sdk';
3
+ export declare function dashboardRuntimeContext(context: IAgentMiddlewareContext): XpertResolvedViewHostContext;
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.dashboardRuntimeContext = dashboardRuntimeContext;
4
+ const plugin_sdk_1 = require("@xpert-ai/plugin-sdk");
5
+ function dashboardRuntimeContext(context) {
6
+ if (!context.xpertId)
7
+ throw new Error('DASHBOARD_ASSISTANT_REQUIRED');
8
+ return { tenantId: context.tenantId ?? plugin_sdk_1.RequestContext.currentTenantId(),
9
+ organizationId: context.organizationId ?? plugin_sdk_1.RequestContext.getOrganizationId(), userId: context.userId ?? plugin_sdk_1.RequestContext.currentUserId(),
10
+ hostType: 'agent', hostId: context.xpertId, slots: [],
11
+ ...(context.projectId ? { runtimeScope: { projectId: context.projectId, conversationId: context.conversationId ?? null,
12
+ dataScopeKey: `project:${context.projectId}`, workspaceFiles: { catalog: 'projects', scopeId: context.projectId, projectId: context.projectId } } } : {}) };
13
+ }
@@ -15,7 +15,7 @@ export declare function dashboardSaveEvidence(files: () => WorkspaceFilesApi): {
15
15
  token: number;
16
16
  generations: Map<string, number>;
17
17
  supersedesPaths: string[];
18
- confirmation: "draft" | "source";
18
+ confirmation: "source" | "draft";
19
19
  };
20
20
  accept(save: SaveAttempt, output: unknown): Promise<void>;
21
21
  readonly pending: boolean;
@@ -0,0 +1,2 @@
1
+ import type { XpertTemplateContribution } from '@xpert-ai/plugin-sdk';
2
+ export declare const dashboardTemplates: XpertTemplateContribution[];