@xpert-ai/plugin-live-dashboard 0.3.1 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.xpertai-plugin/plugin.json +10 -2
- package/README.md +6 -0
- package/assets/branding/cover-v1.prompt.txt +27 -0
- package/assets/branding/cover-v1.webp +0 -0
- package/assets/previews/customer-brief.png +0 -0
- package/assets/previews/profit-atlas.png +0 -0
- package/assets/previews/trend-workspace.png +0 -0
- package/dist/index.js +6 -3
- package/dist/lib/agent.schema.d.ts +43 -37
- package/dist/lib/agent.schema.js +2 -1
- package/dist/lib/app-config.d.ts +62 -0
- package/dist/lib/app-config.js +38 -0
- package/dist/lib/artifact-type.provider.d.ts +15 -0
- package/dist/lib/artifact-type.provider.js +78 -0
- package/dist/lib/assistant-template.d.ts +1 -2
- package/dist/lib/assistant-template.js +3 -52
- package/dist/lib/content.provider.js +13 -5
- package/dist/lib/dashboard-navigation.d.ts +58 -14
- package/dist/lib/dashboard-navigation.js +11 -10
- package/dist/lib/dashboard-view.schema.d.ts +278 -46
- package/dist/lib/dashboard-view.schema.js +9 -1
- package/dist/lib/dashboard.service.d.ts +49 -3
- package/dist/lib/dashboard.service.js +64 -28
- package/dist/lib/document-libraries.d.ts +1 -1
- package/dist/lib/document-libraries.js +3 -2
- package/dist/lib/document-network.d.ts +1 -1
- package/dist/lib/document-network.js +2 -6
- package/dist/lib/editing-feedback.d.ts +5 -0
- package/dist/lib/editing-feedback.js +19 -0
- package/dist/lib/editing-patch.d.ts +22 -0
- package/dist/lib/editing-patch.js +46 -0
- package/dist/lib/editing-session.d.ts +167 -0
- package/dist/lib/editing-session.js +53 -0
- package/dist/lib/editing.d.ts +92 -60
- package/dist/lib/editing.js +36 -24
- package/dist/lib/html-guidance.d.ts +1 -1
- package/dist/lib/html-guidance.js +1 -1
- package/dist/lib/middleware.js +42 -18
- package/dist/lib/monitor.d.ts +70 -0
- package/dist/lib/monitor.js +101 -0
- package/dist/lib/plugin.js +4 -1
- package/dist/lib/project.d.ts +106 -0
- package/dist/lib/project.js +17 -0
- package/dist/lib/projects.schema.d.ts +63 -0
- package/dist/lib/projects.schema.js +8 -0
- package/dist/lib/projects.service.d.ts +25 -0
- package/dist/lib/projects.service.js +75 -0
- package/dist/lib/resource-card.js +1 -1
- package/dist/lib/runtime-context.d.ts +3 -0
- package/dist/lib/runtime-context.js +13 -0
- package/dist/lib/save-evidence.d.ts +1 -1
- package/dist/lib/templates.d.ts +2 -0
- package/dist/lib/templates.js +55 -0
- package/dist/lib/view.provider.d.ts +127 -8
- package/dist/lib/view.provider.js +49 -12
- package/dist/libraries/TREND-WORKSPACE-ICONS-LICENSE.txt +43 -0
- package/dist/libraries/catalog.json +1 -1
- package/dist/remote/app.css +1 -1
- package/dist/remote/app.js +34 -34
- package/dist/remote/build-manifest.json +116 -32
- package/dist/sandbox-actions/action.json +1 -1
- package/dist/sandbox-actions/bundle/host.js +2 -2
- package/dist/sandbox-actions/bundle/resource-cache.mjs +2 -1
- package/dist/sandbox-actions/bundle/validate.mjs +1 -1
- package/docs/docs.json +7 -0
- package/docs/frontend-libraries.mdx +12 -4
- package/docs/html-mode.md +3 -3
- package/docs/quick-start-acceptance.mdx +50 -0
- package/docs/quick-start.mdx +64 -0
- package/docs/superstore.mdx +38 -0
- package/docs/team-sharing.mdx +6 -2
- package/docs/trend-workspace-acceptance.mdx +43 -0
- package/docs/trend-workspace.mdx +30 -0
- package/docs/verification.mdx +4 -2
- package/docs/visual-styles-acceptance.mdx +40 -0
- package/docs/visual-styles.mdx +46 -0
- package/package.json +23 -17
- package/skills/live-dashboard/SKILL.md +27 -3
- package/skills/live-dashboard/examples/README.md +25 -0
- package/skills/live-dashboard/examples/catalog.json +79 -0
- package/skills/live-dashboard/examples/production-quality/README.md +25 -0
- package/skills/live-dashboard/examples/production-quality/dashboard.html +129 -0
- package/skills/live-dashboard/examples/production-quality/definition.json +67 -0
- package/skills/live-dashboard/examples/production-quality/demo.csv +7 -0
- package/skills/live-dashboard/examples/production-quality/demo.json +44 -0
- package/skills/live-dashboard/examples/production-quality/expected.json +26 -0
- package/skills/live-dashboard/examples/production-quality/preview.png +0 -0
- package/skills/live-dashboard/examples/production-quality/query.json +53 -0
- package/skills/live-dashboard/examples/regional-sales/README.md +25 -0
- package/skills/live-dashboard/examples/regional-sales/dashboard-create.json +35 -0
- package/skills/live-dashboard/examples/regional-sales/definition.json +35 -0
- package/skills/live-dashboard/examples/regional-sales/demo.csv +5 -0
- package/skills/live-dashboard/examples/regional-sales/demo.json +18 -0
- package/skills/live-dashboard/examples/regional-sales/expected.json +19 -0
- package/skills/live-dashboard/examples/regional-sales/preview.png +0 -0
- package/skills/live-dashboard/examples/regional-sales/query.json +45 -0
- package/skills/live-dashboard/examples/sales-overview/README.md +25 -0
- package/skills/live-dashboard/examples/sales-overview/dashboard.html +129 -0
- package/skills/live-dashboard/examples/sales-overview/definition.json +57 -0
- package/skills/live-dashboard/examples/sales-overview/demo.csv +7 -0
- package/skills/live-dashboard/examples/sales-overview/demo.json +38 -0
- package/skills/live-dashboard/examples/sales-overview/expected.json +22 -0
- package/skills/live-dashboard/examples/sales-overview/preview.png +0 -0
- package/skills/live-dashboard/examples/sales-overview/query.json +52 -0
- package/skills/live-dashboard/examples/superstore/README.md +64 -0
- package/skills/live-dashboard/examples/superstore/THIRD_PARTY_LICENSE.txt +207 -0
- package/skills/live-dashboard/examples/superstore/build_data.py +155 -0
- package/skills/live-dashboard/examples/superstore/build_pages.py +129 -0
- package/skills/live-dashboard/examples/superstore/checks.json +104 -0
- package/skills/live-dashboard/examples/superstore/customers-mobile-dark.png +0 -0
- package/skills/live-dashboard/examples/superstore/customers-select.png +0 -0
- package/skills/live-dashboard/examples/superstore/customers.html +316 -0
- package/skills/live-dashboard/examples/superstore/customers.png +0 -0
- package/skills/live-dashboard/examples/superstore/customers.queries.json +512 -0
- package/skills/live-dashboard/examples/superstore/expected.json +4069 -0
- package/skills/live-dashboard/examples/superstore/import.json +200 -0
- package/skills/live-dashboard/examples/superstore/orders.csv +10195 -0
- package/skills/live-dashboard/examples/superstore/overview-mobile-dark.png +0 -0
- package/skills/live-dashboard/examples/superstore/overview-select.png +0 -0
- package/skills/live-dashboard/examples/superstore/overview.html +310 -0
- package/skills/live-dashboard/examples/superstore/overview.png +0 -0
- package/skills/live-dashboard/examples/superstore/overview.queries.json +636 -0
- package/skills/live-dashboard/examples/superstore/page.js +109 -0
- package/skills/live-dashboard/examples/superstore/profitability-mobile-dark.png +0 -0
- package/skills/live-dashboard/examples/superstore/profitability-select.png +0 -0
- package/skills/live-dashboard/examples/superstore/profitability.html +307 -0
- package/skills/live-dashboard/examples/superstore/profitability.png +0 -0
- package/skills/live-dashboard/examples/superstore/profitability.queries.json +334 -0
- package/skills/live-dashboard/examples/superstore/provenance.json +24 -0
- package/skills/live-dashboard/examples/superstore/semantic-model.json +220 -0
- package/skills/live-dashboard/examples/superstore/test_data.py +62 -0
- package/skills/live-dashboard/references/html-runtime.md +1 -1
- package/skills/live-dashboard/themes/README.md +50 -0
- package/skills/live-dashboard/themes/customer-brief/README.md +47 -0
- package/skills/live-dashboard/themes/customer-brief/charts.js +17 -0
- package/skills/live-dashboard/themes/customer-brief/layout.html +22 -0
- package/skills/live-dashboard/themes/customer-brief/theme.css +108 -0
- package/skills/live-dashboard/themes/profit-atlas/README.md +43 -0
- package/skills/live-dashboard/themes/profit-atlas/charts.js +30 -0
- package/skills/live-dashboard/themes/profit-atlas/layout.html +19 -0
- package/skills/live-dashboard/themes/profit-atlas/theme.css +75 -0
- package/skills/live-dashboard/themes/trend-workspace/ICON_LICENSE.txt +43 -0
- package/skills/live-dashboard/themes/trend-workspace/README.md +144 -0
- package/skills/live-dashboard/themes/trend-workspace/charts.js +60 -0
- package/skills/live-dashboard/themes/trend-workspace/icons.js +11 -0
- package/skills/live-dashboard/themes/trend-workspace/layout.html +45 -0
- package/skills/live-dashboard/themes/trend-workspace/select.js +127 -0
- package/skills/live-dashboard/themes/trend-workspace/theme.css +137 -0
|
@@ -1,18 +1,26 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.dashboardViewDataSchema = exports.dashboardSavedSchema = exports.dashboardSummarySchema = void 0;
|
|
3
|
+
exports.dashboardViewDataSchema = exports.dashboardSavedSchema = exports.dashboardPickerPageSchema = exports.dashboardSummarySchema = void 0;
|
|
4
4
|
const v3_1 = require("zod/v3");
|
|
5
5
|
const analytics_1 = require("@xpert-ai/plugin-sdk/analytics");
|
|
6
6
|
const artifact_document_1 = require("@xpert-ai/plugin-sdk/artifact-document");
|
|
7
|
+
const projects_schema_1 = require("./projects.schema");
|
|
7
8
|
const dashboard_schema_1 = require("./dashboard.schema");
|
|
8
9
|
const dashboard_navigation_1 = require("./dashboard-navigation");
|
|
9
10
|
exports.dashboardSummarySchema = v3_1.z.object({ artifactId: v3_1.z.string(), versionId: v3_1.z.string().nullish(), versionNumber: v3_1.z.number().optional(), title: v3_1.z.string().nullish(), updatedAt: v3_1.z.string().optional(), draftRevision: v3_1.z.number().optional(), canDelete: v3_1.z.boolean().optional(), isDraft: v3_1.z.boolean().optional(), baseVersionId: v3_1.z.string().nullish() });
|
|
11
|
+
exports.dashboardPickerPageSchema = v3_1.z.object({ items: v3_1.z.array(exports.dashboardSummarySchema), page: v3_1.z.number().int().positive(), hasMore: v3_1.z.boolean(), canEdit: v3_1.z.boolean().default(false), mode: v3_1.z.enum(['draft', 'published']).optional() });
|
|
10
12
|
exports.dashboardSavedSchema = exports.dashboardSummarySchema.extend({ manifest: dashboard_schema_1.dashboardSchema, dependencies: artifact_document_1.artifactDocumentDependencyAssets.optional() });
|
|
11
13
|
// Source identities belong to Analytics, including immutable Definitions and Artifacts.
|
|
12
14
|
// The viewer consumes only the reference and label; DataSource fields are not universal.
|
|
13
15
|
exports.dashboardViewDataSchema = v3_1.z.object({ meta: v3_1.z.object({
|
|
16
|
+
currentProject: projects_schema_1.dashboardProjectSchema.nullable().optional(),
|
|
17
|
+
access: v3_1.z.object({ project: v3_1.z.boolean(), archived: v3_1.z.boolean(), canReadDraft: v3_1.z.boolean(), canEdit: v3_1.z.boolean(), canManage: v3_1.z.boolean() }).optional(),
|
|
18
|
+
mode: v3_1.z.enum(['published', 'draft']).optional(),
|
|
19
|
+
notice: v3_1.z.literal('not_published').optional(),
|
|
20
|
+
pagination: v3_1.z.object({ page: v3_1.z.number(), pageSize: v3_1.z.number(), hasMore: v3_1.z.boolean() }).optional(),
|
|
14
21
|
navigationTarget: dashboard_navigation_1.dashboardNavigationTargetSchema.optional(),
|
|
15
22
|
dashboards: v3_1.z.array(exports.dashboardSummarySchema),
|
|
23
|
+
selectedDashboard: exports.dashboardSummarySchema.optional(),
|
|
16
24
|
sources: v3_1.z.array(v3_1.z.object({ source: analytics_1.analyticsSourceRefSchema, name: v3_1.z.string() })),
|
|
17
25
|
saved: exports.dashboardSavedSchema.optional(),
|
|
18
26
|
versions: v3_1.z.array(exports.dashboardSummarySchema).optional()
|
|
@@ -2,6 +2,7 @@ import type { AnalyticsValue, AnalyticsDiscoveryRequest, AnalyticsQueryRequest,
|
|
|
2
2
|
import { type RuntimeCapabilityRegistry } from '@xpert-ai/plugin-sdk';
|
|
3
3
|
import { type DashboardManifest, type DashboardChanges } from './dashboard.schema';
|
|
4
4
|
import { HtmlDashboardValidation } from './html-validation';
|
|
5
|
+
import type { DashboardAccess, DashboardMode } from './project';
|
|
5
6
|
export declare const PLUGIN_NAME = "@xpert-ai/plugin-live-dashboard";
|
|
6
7
|
export declare class DashboardService {
|
|
7
8
|
private readonly runtime;
|
|
@@ -13,12 +14,52 @@ export declare class DashboardService {
|
|
|
13
14
|
list(context: XpertResolvedViewHostContext): Promise<{
|
|
14
15
|
title: string | null | undefined;
|
|
15
16
|
draftRevision?: number | undefined;
|
|
17
|
+
updatedAt: string | Date | undefined;
|
|
16
18
|
canDelete: boolean;
|
|
17
19
|
artifactId: string;
|
|
18
20
|
versionId: string | null | undefined;
|
|
19
21
|
versionNumber: number | undefined;
|
|
20
|
-
updatedAt: string | Date | undefined;
|
|
21
22
|
}[]>;
|
|
23
|
+
access(context: XpertResolvedViewHostContext): Promise<DashboardAccess>;
|
|
24
|
+
listPage(context: XpertResolvedViewHostContext, page?: number, pageSize?: number): Promise<{
|
|
25
|
+
page: number;
|
|
26
|
+
pageSize: number;
|
|
27
|
+
hasMore: boolean;
|
|
28
|
+
items: {
|
|
29
|
+
title: string | null | undefined;
|
|
30
|
+
draftRevision?: number | undefined;
|
|
31
|
+
updatedAt: string | Date | undefined;
|
|
32
|
+
canDelete: boolean;
|
|
33
|
+
artifactId: string;
|
|
34
|
+
versionId: string | null | undefined;
|
|
35
|
+
versionNumber: number | undefined;
|
|
36
|
+
}[];
|
|
37
|
+
}>;
|
|
38
|
+
searchPage(context: XpertResolvedViewHostContext, input: {
|
|
39
|
+
search: string;
|
|
40
|
+
page: number;
|
|
41
|
+
}): Promise<{
|
|
42
|
+
items: {
|
|
43
|
+
title: string | null | undefined;
|
|
44
|
+
draftRevision?: number | undefined;
|
|
45
|
+
updatedAt: string | Date | undefined;
|
|
46
|
+
canDelete: boolean;
|
|
47
|
+
artifactId: string;
|
|
48
|
+
versionId: string | null | undefined;
|
|
49
|
+
versionNumber: number | undefined;
|
|
50
|
+
}[];
|
|
51
|
+
page: number;
|
|
52
|
+
hasMore: boolean;
|
|
53
|
+
}>;
|
|
54
|
+
selectedSummary(context: XpertResolvedViewHostContext, artifactId: string): Promise<{
|
|
55
|
+
title: string | null | undefined;
|
|
56
|
+
draftRevision?: number | undefined;
|
|
57
|
+
canDelete: boolean;
|
|
58
|
+
artifactId: string;
|
|
59
|
+
versionId: string | null | undefined;
|
|
60
|
+
versionNumber: number | undefined;
|
|
61
|
+
updatedAt: string | Date | undefined;
|
|
62
|
+
} | undefined>;
|
|
22
63
|
trash(context: XpertResolvedViewHostContext, artifactId: string, expectedRevision: number): Promise<{
|
|
23
64
|
artifactId: string;
|
|
24
65
|
}>;
|
|
@@ -30,7 +71,7 @@ export declare class DashboardService {
|
|
|
30
71
|
status: "draft";
|
|
31
72
|
title: string;
|
|
32
73
|
}>;
|
|
33
|
-
open(context: XpertResolvedViewHostContext, artifactId: string, versionId?: string, draftRevision?: number): Promise<{
|
|
74
|
+
open(context: XpertResolvedViewHostContext, artifactId: string, versionId?: string, draftRevision?: number, mode?: DashboardMode): Promise<{
|
|
34
75
|
manifest: {
|
|
35
76
|
schema: "xpert.live-dashboard";
|
|
36
77
|
id: string;
|
|
@@ -64,6 +105,7 @@ export declare class DashboardService {
|
|
|
64
105
|
dependencies?: import("@xpert-ai/plugin-sdk/artifact-document").ArtifactDocumentDependencyLock[] | undefined;
|
|
65
106
|
} | undefined;
|
|
66
107
|
};
|
|
108
|
+
contentHash: string;
|
|
67
109
|
draftId?: string | undefined;
|
|
68
110
|
draftRevision?: number | undefined;
|
|
69
111
|
baseVersionId?: string | null | undefined;
|
|
@@ -75,7 +117,7 @@ export declare class DashboardService {
|
|
|
75
117
|
versionNumber: number | undefined;
|
|
76
118
|
}>;
|
|
77
119
|
/** Trusted View transport only. Agent read tools receive locks, never megabytes of library code. */
|
|
78
|
-
openDocument(context: XpertResolvedViewHostContext, artifactId: string, versionId?: string, draftRevision?: number): Promise<{
|
|
120
|
+
openDocument(context: XpertResolvedViewHostContext, artifactId: string, versionId?: string, draftRevision?: number, mode?: DashboardMode): Promise<{
|
|
79
121
|
manifest: {
|
|
80
122
|
schema: "xpert.live-dashboard";
|
|
81
123
|
id: string;
|
|
@@ -110,6 +152,7 @@ export declare class DashboardService {
|
|
|
110
152
|
} | undefined;
|
|
111
153
|
};
|
|
112
154
|
dependencies: import("@xpert-ai/plugin-sdk/artifact-document").ArtifactDocumentDependencyAsset[];
|
|
155
|
+
contentHash: string;
|
|
113
156
|
draftId?: string | undefined;
|
|
114
157
|
draftRevision?: number | undefined;
|
|
115
158
|
baseVersionId?: string | null | undefined;
|
|
@@ -142,6 +185,8 @@ export declare class DashboardService {
|
|
|
142
185
|
versionNumber: number;
|
|
143
186
|
title: string | null | undefined;
|
|
144
187
|
}>;
|
|
188
|
+
validatePublication(context: XpertResolvedViewHostContext, artifactId: string, expectedRevision: number, expectedCurrentVersionId: string | null): Promise<void>;
|
|
189
|
+
private publishDraft;
|
|
145
190
|
query(context: XpertResolvedViewHostContext, artifactId: string, versionId: string | undefined, controls: Record<string, AnalyticsValue>, draftRevision?: number): Promise<{
|
|
146
191
|
payload?: {
|
|
147
192
|
ok: boolean;
|
|
@@ -237,6 +282,7 @@ export declare class DashboardService {
|
|
|
237
282
|
dependencies?: import("@xpert-ai/plugin-sdk/artifact-document").ArtifactDocumentDependencyLock[] | undefined;
|
|
238
283
|
} | undefined;
|
|
239
284
|
};
|
|
285
|
+
contentHash: string;
|
|
240
286
|
draftId?: string | undefined;
|
|
241
287
|
draftRevision?: number | undefined;
|
|
242
288
|
baseVersionId?: string | null | undefined;
|
|
@@ -32,23 +32,61 @@ let DashboardService = class DashboardService {
|
|
|
32
32
|
this.runtime = runtime;
|
|
33
33
|
this.htmlValidation = htmlValidation;
|
|
34
34
|
}
|
|
35
|
-
sources(context) { return this.runtime.require(plugin_sdk_1.AnalyticsRuntimeCapability).list(actor(context)); }
|
|
36
|
-
discover(context, input) { return this.runtime.require(plugin_sdk_1.AnalyticsRuntimeCapability).discover(actor(context), input); }
|
|
35
|
+
async sources(context) { await this.authorizeProject(context); return this.runtime.require(plugin_sdk_1.AnalyticsRuntimeCapability).list(actor(context)); }
|
|
36
|
+
async discover(context, input) { await this.authorizeProject(context); return this.runtime.require(plugin_sdk_1.AnalyticsRuntimeCapability).discover(actor(context), input); }
|
|
37
37
|
async preview(context, input) {
|
|
38
|
+
await this.authorizeProject(context);
|
|
38
39
|
const dataset = await this.runtime.require(plugin_sdk_1.AnalyticsRuntimeCapability).query(actor(context), input);
|
|
39
40
|
await this.probeControls(context, input.binding, input.controls ?? {});
|
|
40
41
|
return dataset;
|
|
41
42
|
}
|
|
42
43
|
async list(context) {
|
|
44
|
+
return (await this.listPage(context)).items;
|
|
45
|
+
}
|
|
46
|
+
async access(context) {
|
|
43
47
|
const access = await this.authorizeProject(context);
|
|
44
|
-
|
|
48
|
+
return { project: !!projectId(context), archived: access?.archived ?? false,
|
|
49
|
+
canReadDraft: !access || access.role !== 'member', canEdit: !access || !access.archived && access.role !== 'member',
|
|
50
|
+
canManage: !access || !access.archived && access.canManage };
|
|
51
|
+
}
|
|
52
|
+
async listPage(context, page = 1, pageSize = 50) {
|
|
53
|
+
const access = await this.access(context);
|
|
54
|
+
if (!Number.isSafeInteger(page) || page < 1 || !Number.isSafeInteger(pageSize) || pageSize < 1 || pageSize > 100)
|
|
55
|
+
throw new common_1.BadRequestException('DASHBOARD_INVALID_CURSOR');
|
|
56
|
+
const result = await this.runtime.require(plugin_sdk_1.ArtifactsRuntimeCapability).listArtifacts({ pluginName: exports.PLUGIN_NAME, resourceType: RESOURCE_TYPE, resourceIdPrefix: hostPrefix(context), status: 'active', page, pageSize, includeCurrentVersion: true });
|
|
45
57
|
const items = result.items.filter((item) => item.resourceId.startsWith(hostPrefix(context)) && (item.userId === context.userId || !item.userId && item.projectId === projectId(context)));
|
|
46
|
-
const drafts = new Map((await this.runtime.require(plugin_sdk_1.ArtifactDraftsRuntimeCapability).list(items.map(item => item.id))).map(draft => [draft.artifactId, draft]));
|
|
47
|
-
return items.map(item => {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
58
|
+
const drafts = new Map((access.canReadDraft ? await this.runtime.require(plugin_sdk_1.ArtifactDraftsRuntimeCapability).list(items.map(item => item.id)) : []).map(draft => [draft.artifactId, draft]));
|
|
59
|
+
return { page, pageSize, hasMore: page * pageSize < result.total, items: items.filter(item => access.canReadDraft || !!item.currentVersionId).map(item => {
|
|
60
|
+
const draft = drafts.get(item.id);
|
|
61
|
+
return { ...summary(item), canDelete: !!draft && access.canManage,
|
|
62
|
+
...(draft ? { title: draft.title ?? item.title, draftRevision: draft.revision, updatedAt: draft.updatedAt ?? item.updatedAt } : {}) };
|
|
63
|
+
}) };
|
|
64
|
+
}
|
|
65
|
+
async searchPage(context, input) {
|
|
66
|
+
// Search the authorized display titles, including editor drafts. Filtering a stored
|
|
67
|
+
// Artifact title in the host would miss renamed drafts or expose them to members.
|
|
68
|
+
const pageSize = 20, offset = (input.page - 1) * pageSize;
|
|
69
|
+
const search = input.search.trim().toLocaleLowerCase();
|
|
70
|
+
const matches = [];
|
|
71
|
+
for (let page = 1;; page++) {
|
|
72
|
+
const batch = await this.listPage(context, page, 100);
|
|
73
|
+
matches.push(...batch.items.filter(item => `${item.title ?? ''} ${item.artifactId}`.toLocaleLowerCase().includes(search)));
|
|
74
|
+
if (!batch.hasMore || matches.length > offset + pageSize)
|
|
75
|
+
break;
|
|
76
|
+
}
|
|
77
|
+
return { items: matches.slice(offset, offset + pageSize), page: input.page, hasMore: matches.length > offset + pageSize };
|
|
78
|
+
}
|
|
79
|
+
async selectedSummary(context, artifactId) {
|
|
80
|
+
const access = await this.access(context);
|
|
81
|
+
const artifact = await this.runtime.require(plugin_sdk_1.ArtifactsRuntimeCapability).getArtifact(artifactId);
|
|
82
|
+
assertOwned(context, artifact);
|
|
83
|
+
if (artifact.status !== 'active')
|
|
84
|
+
throw new common_1.ForbiddenException('DASHBOARD_ARCHIVED');
|
|
85
|
+
if (!access.canReadDraft && !artifact.currentVersionId)
|
|
86
|
+
return undefined;
|
|
87
|
+
const draft = access.canReadDraft ? (await this.runtime.require(plugin_sdk_1.ArtifactDraftsRuntimeCapability).list([artifactId]))[0] : undefined;
|
|
88
|
+
return { ...summary(artifact), canDelete: !!draft && access.canManage,
|
|
89
|
+
...(draft ? { title: draft.title ?? artifact.title, draftRevision: draft.revision } : {}) };
|
|
52
90
|
}
|
|
53
91
|
async trash(context, artifactId, expectedRevision) {
|
|
54
92
|
await this.authorizeProject(context, 'manage');
|
|
@@ -88,38 +126,30 @@ let DashboardService = class DashboardService {
|
|
|
88
126
|
for (const binding of parsed.bindings)
|
|
89
127
|
await this.probeControls(context, binding, Object.fromEntries(parsed.controls.filter((control) => control.defaultValue !== undefined).map((control) => [control.controlId, control.defaultValue ?? null])));
|
|
90
128
|
const htmlValidation = await this.htmlValidation.validate(context, parsed, preview, dependencies);
|
|
91
|
-
const artifact = existing ?? await artifacts.createArtifact({ source, kind: 'file', title: parsed.title,
|
|
129
|
+
const artifact = existing ?? await artifacts.createArtifact({ source, type: { pluginName: exports.PLUGIN_NAME, resourceType: RESOURCE_TYPE }, kind: 'file', title: parsed.title,
|
|
92
130
|
scope: { ...scopedActor, ...(projectId(context) ? { projectId: projectId(context), userId: null } : { xpertId: context.hostId }) } });
|
|
93
|
-
const
|
|
94
|
-
const project = projectId(context);
|
|
95
|
-
// Shared definitions live in the Project volume; private legacy dashboards retain their user volume.
|
|
96
|
-
const privateScope = { tenantId: scopedActor.tenantId, userId: scopedActor.userId, catalog: 'users' };
|
|
97
|
-
const reference = project
|
|
98
|
-
? (await files.writeRuntimeBuffer({ tenantId: scopedActor.tenantId, userId: scopedActor.userId,
|
|
99
|
-
catalog: 'projects', scopeId: project, projectId: project, buffer, originalName: 'dashboard.json',
|
|
100
|
-
fileName: `${digest}.json`, folder: `.xpert/live-dashboards/${parsed.id}`, mimeType: MIME_TYPE })).reference
|
|
101
|
-
: await files.uploadBuffer({ ...privateScope, buffer, originalName: 'dashboard.json', fileName: `${digest}.json`,
|
|
102
|
-
folder: `live-dashboards/${parsed.id}`, mimeType: MIME_TYPE }).then(file => ({
|
|
103
|
-
source: 'platform.workspace.files', ...privateScope, filePath: file.filePath, workspacePath: file.workspacePath
|
|
104
|
-
}));
|
|
131
|
+
const reference = await this.runtime.require(plugin_sdk_1.ArtifactContentRuntimeCapability).write({ artifactId: artifact.id, buffer });
|
|
105
132
|
const result = await this.runtime.require(plugin_sdk_1.ArtifactDraftsRuntimeCapability).save({ artifactId: artifact.id, expectedRevision,
|
|
106
133
|
expectedCurrentVersionId: expectedVersionId, mimeType: MIME_TYPE, title: parsed.title, fileName: 'dashboard.json', sha256: digest,
|
|
107
134
|
...(htmlValidation ? { metadata: { htmlValidation } } : {}), workspaceFileRef: reference });
|
|
108
135
|
return { artifactId: artifact.id, draftId: result.id, draftRevision: result.revision, baseVersionId: result.baseVersionId, status: 'draft', title: parsed.title };
|
|
109
136
|
}
|
|
110
|
-
async open(context, artifactId, versionId, draftRevision) {
|
|
111
|
-
const { dependencies, ...saved } = await this.openDocument(context, artifactId, versionId, draftRevision);
|
|
137
|
+
async open(context, artifactId, versionId, draftRevision, mode = 'draft') {
|
|
138
|
+
const { dependencies, ...saved } = await this.openDocument(context, artifactId, versionId, draftRevision, mode);
|
|
112
139
|
return saved;
|
|
113
140
|
}
|
|
114
141
|
/** Trusted View transport only. Agent read tools receive locks, never megabytes of library code. */
|
|
115
|
-
async openDocument(context, artifactId, versionId, draftRevision) {
|
|
116
|
-
await this.
|
|
142
|
+
async openDocument(context, artifactId, versionId, draftRevision, mode = 'draft') {
|
|
143
|
+
const access = await this.access(context);
|
|
144
|
+
const readDraft = draftRevision !== undefined || !versionId && mode === 'draft';
|
|
145
|
+
if (readDraft && !access.canReadDraft)
|
|
146
|
+
throw new common_1.ForbiddenException('DASHBOARD_DRAFT_ACCESS_DENIED');
|
|
117
147
|
const artifacts = this.runtime.require(plugin_sdk_1.ArtifactsRuntimeCapability);
|
|
118
148
|
const artifact = await artifacts.getArtifact(artifactId);
|
|
119
149
|
assertOwned(context, artifact);
|
|
120
150
|
if (artifact.status !== 'active')
|
|
121
151
|
throw new common_1.ForbiddenException('DASHBOARD_ARCHIVED');
|
|
122
|
-
const draft =
|
|
152
|
+
const draft = readDraft ? await this.runtime.require(plugin_sdk_1.ArtifactDraftsRuntimeCapability).get(artifactId) : null;
|
|
123
153
|
if (draftRevision !== undefined && draft?.revision !== draftRevision)
|
|
124
154
|
throw new common_1.ConflictException('DASHBOARD_DRAFT_CONFLICT');
|
|
125
155
|
const version = draft ?? (versionId ? (await artifacts.listArtifactVersions({ artifactId, status: 'active' })).find((item) => item.id === versionId) : artifact.currentVersion);
|
|
@@ -135,7 +165,7 @@ let DashboardService = class DashboardService {
|
|
|
135
165
|
throw new common_1.BadRequestException('DASHBOARD_IDENTITY_MISMATCH');
|
|
136
166
|
return { ...summary(artifact, 'versionNumber' in version ? version : undefined),
|
|
137
167
|
...(draft ? { draftId: draft.id, draftRevision: draft.revision, baseVersionId: draft.baseVersionId,
|
|
138
|
-
isDraft: draft.revision !== draft.publishedRevision, title: draft.title, updatedAt: draft.updatedAt } : {}), manifest, dependencies };
|
|
168
|
+
isDraft: draft.revision !== draft.publishedRevision, title: draft.title, updatedAt: draft.updatedAt } : {}), manifest, dependencies, contentHash: version.sha256 };
|
|
139
169
|
}
|
|
140
170
|
async history(context, artifactId) {
|
|
141
171
|
await this.authorizeProject(context);
|
|
@@ -156,6 +186,9 @@ let DashboardService = class DashboardService {
|
|
|
156
186
|
}
|
|
157
187
|
async publish(context, artifactId, expectedRevision, expectedCurrentVersionId) {
|
|
158
188
|
await this.authorizeProject(context, 'manage');
|
|
189
|
+
return this.publishDraft(context, artifactId, expectedRevision, expectedCurrentVersionId);
|
|
190
|
+
}
|
|
191
|
+
async validatePublication(context, artifactId, expectedRevision, expectedCurrentVersionId) {
|
|
159
192
|
const saved = await this.open(context, artifactId, undefined, expectedRevision);
|
|
160
193
|
if (!saved.manifest.bindings.length)
|
|
161
194
|
throw new common_1.BadRequestException('DASHBOARD_CONFIGURE_BEFORE_PUBLISHING');
|
|
@@ -167,6 +200,9 @@ let DashboardService = class DashboardService {
|
|
|
167
200
|
}
|
|
168
201
|
// Revalidate current source access and bindings before publishing the exact reviewed bytes.
|
|
169
202
|
await this.execute(context, saved.manifest, {});
|
|
203
|
+
}
|
|
204
|
+
async publishDraft(context, artifactId, expectedRevision, expectedCurrentVersionId) {
|
|
205
|
+
await this.validatePublication(context, artifactId, expectedRevision, expectedCurrentVersionId);
|
|
170
206
|
const version = await this.runtime.require(plugin_sdk_1.ArtifactDraftsRuntimeCapability).publish({ artifactId, expectedRevision, expectedCurrentVersionId });
|
|
171
207
|
return { artifactId, versionId: version.id, versionNumber: version.versionNumber, title: version.title };
|
|
172
208
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { z } from 'zod/v3';
|
|
2
2
|
import { type ArtifactDocumentDependencyAsset, type ArtifactDocumentDependencyLock } from '@xpert-ai/plugin-sdk/artifact-document';
|
|
3
3
|
/** The plugin owns its catalog. The platform owns verification and isolated execution. */
|
|
4
|
-
export declare const libraryRequestsSchema: z.ZodEffects<z.ZodArray<z.ZodEnum<["echarts", "three"]>, "many">, ("echarts" | "three")[], ("echarts" | "three")[]>;
|
|
4
|
+
export declare const libraryRequestsSchema: z.ZodEffects<z.ZodEffects<z.ZodArray<z.ZodEnum<["echarts", "three", "trend-workspace", "profit-atlas", "customer-brief"]>, "many">, ("echarts" | "three" | "trend-workspace" | "profit-atlas" | "customer-brief")[], ("echarts" | "three" | "trend-workspace" | "profit-atlas" | "customer-brief")[]>, ("echarts" | "three" | "trend-workspace" | "profit-atlas" | "customer-brief")[], ("echarts" | "three" | "trend-workspace" | "profit-atlas" | "customer-brief")[]>;
|
|
5
5
|
export type LibraryRequests = z.output<typeof libraryRequestsSchema>;
|
|
6
6
|
export declare function bundledLibraries(): Promise<ArtifactDocumentDependencyAsset[]>;
|
|
7
7
|
export declare function libraryLocks(ids: LibraryRequests): Promise<ArtifactDocumentDependencyLock[]>;
|
|
@@ -9,8 +9,9 @@ const node_path_1 = require("node:path");
|
|
|
9
9
|
const v3_1 = require("zod/v3");
|
|
10
10
|
const artifact_document_1 = require("@xpert-ai/plugin-sdk/artifact-document");
|
|
11
11
|
/** The plugin owns its catalog. The platform owns verification and isolated execution. */
|
|
12
|
-
exports.libraryRequestsSchema = v3_1.z.array(v3_1.z.enum(['echarts', 'three'])).max(
|
|
13
|
-
.refine(ids => new Set(ids).size === ids.length, 'Duplicate library')
|
|
12
|
+
exports.libraryRequestsSchema = v3_1.z.array(v3_1.z.enum(['echarts', 'three', 'trend-workspace', 'profit-atlas', 'customer-brief'])).max(3)
|
|
13
|
+
.refine(ids => new Set(ids).size === ids.length, 'Duplicate library')
|
|
14
|
+
.refine(ids => ids.filter(id => ['trend-workspace', 'profit-atlas', 'customer-brief'].includes(id)).length <= 1, 'Choose one dashboard visual theme');
|
|
14
15
|
async function bundledLibraries() {
|
|
15
16
|
return (0, artifact_document_1.verifyArtifactDocumentDependencies)(JSON.parse(await (0, promises_1.readFile)((0, node_path_1.join)(__dirname, '../libraries/catalog.json'), 'utf8')));
|
|
16
17
|
}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import type { ArtifactDocumentNetworkPolicy } from '@xpert-ai/plugin-sdk/artifact-document';
|
|
2
|
-
/**
|
|
2
|
+
/** Temporary functional acceptance policy, shared by preview and viewing. */
|
|
3
3
|
export declare const DASHBOARD_NETWORK_POLICY: ArtifactDocumentNetworkPolicy;
|
|
@@ -1,9 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.DASHBOARD_NETWORK_POLICY = void 0;
|
|
4
|
-
/**
|
|
5
|
-
exports.DASHBOARD_NETWORK_POLICY = {
|
|
6
|
-
scripts: ['https://cdn.tailwindcss.com', 'https://cdn.jsdelivr.net', 'https://cdnjs.cloudflare.com', 'https://unpkg.com'],
|
|
7
|
-
styles: ['https://cdn.jsdelivr.net', 'https://cdnjs.cloudflare.com', 'https://unpkg.com', 'https://fonts.googleapis.com'],
|
|
8
|
-
fonts: ['https://cdn.jsdelivr.net', 'https://cdnjs.cloudflare.com', 'https://unpkg.com', 'https://fonts.gstatic.com']
|
|
9
|
-
};
|
|
4
|
+
/** Temporary functional acceptance policy, shared by preview and viewing. */
|
|
5
|
+
exports.DASHBOARD_NETWORK_POLICY = { mode: 'unrestricted' };
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/** Missing selection is a normal interaction outcome; no Artifact operation is attempted. */
|
|
2
|
+
export declare function dashboardSelectionRequired(config: unknown): {
|
|
3
|
+
status: "selection_required";
|
|
4
|
+
message: "Please select a dashboard to edit first." | "请先选择要编辑的看板" | "請先選擇要編輯的看板";
|
|
5
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.dashboardSelectionRequired = dashboardSelectionRequired;
|
|
4
|
+
const plugin_sdk_1 = require("@xpert-ai/plugin-sdk");
|
|
5
|
+
const v3_1 = require("zod/v3");
|
|
6
|
+
const messages = {
|
|
7
|
+
en: 'Please select a dashboard to edit first.',
|
|
8
|
+
'zh-Hans': '请先选择要编辑的看板',
|
|
9
|
+
'zh-Hant': '請先選擇要編輯的看板'
|
|
10
|
+
};
|
|
11
|
+
const languageConfig = v3_1.z.object({ configurable: v3_1.z.object({ language: v3_1.z.string().optional() }).optional() });
|
|
12
|
+
/** Missing selection is a normal interaction outcome; no Artifact operation is attempted. */
|
|
13
|
+
function dashboardSelectionRequired(config) {
|
|
14
|
+
const parsed = languageConfig.safeParse(config);
|
|
15
|
+
const language = (parsed.success ? parsed.data.configurable?.language : undefined) ?? plugin_sdk_1.RequestContext.getLanguageCode();
|
|
16
|
+
const locale = language.toLowerCase().replaceAll('_', '-');
|
|
17
|
+
const key = ['zh-hant', 'zh-tw', 'zh-hk', 'zh-mo'].includes(locale) ? 'zh-Hant' : locale === 'zh' || locale.startsWith('zh-') ? 'zh-Hans' : 'en';
|
|
18
|
+
return { status: 'selection_required', message: messages[key] };
|
|
19
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { z } from 'zod/v3';
|
|
2
|
+
import type { DashboardManifest } from './dashboard.schema';
|
|
3
|
+
export declare const removalsSchema: z.ZodOptional<z.ZodObject<{
|
|
4
|
+
bindingIds: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
|
|
5
|
+
controlIds: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
|
|
6
|
+
viewIds: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
|
|
7
|
+
htmlElementIds: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
|
|
8
|
+
}, "strict", z.ZodTypeAny, {
|
|
9
|
+
bindingIds: string[];
|
|
10
|
+
controlIds: string[];
|
|
11
|
+
viewIds: string[];
|
|
12
|
+
htmlElementIds: string[];
|
|
13
|
+
}, {
|
|
14
|
+
bindingIds?: string[] | undefined;
|
|
15
|
+
controlIds?: string[] | undefined;
|
|
16
|
+
viewIds?: string[] | undefined;
|
|
17
|
+
htmlElementIds?: string[] | undefined;
|
|
18
|
+
}>>;
|
|
19
|
+
export declare function upsertComponents<T>(existing: T[], changes: T[] | undefined, id: (item: T) => string, removed?: string[]): T[];
|
|
20
|
+
export declare function htmlElementIds(html: string): Set<string>;
|
|
21
|
+
/** IDs are an explicit preservation contract, not a semantic comparison of arbitrary HTML. */
|
|
22
|
+
export declare function assertHtmlPreserved(previous: DashboardManifest['presentation'], next: DashboardManifest['presentation'], removed?: string[]): void;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.removalsSchema = void 0;
|
|
4
|
+
exports.upsertComponents = upsertComponents;
|
|
5
|
+
exports.htmlElementIds = htmlElementIds;
|
|
6
|
+
exports.assertHtmlPreserved = assertHtmlPreserved;
|
|
7
|
+
const parse5_1 = require("parse5");
|
|
8
|
+
const v3_1 = require("zod/v3");
|
|
9
|
+
exports.removalsSchema = v3_1.z.object({
|
|
10
|
+
bindingIds: v3_1.z.array(v3_1.z.string()).max(8).default([]), controlIds: v3_1.z.array(v3_1.z.string()).max(24).default([]),
|
|
11
|
+
viewIds: v3_1.z.array(v3_1.z.string()).max(40).default([]), htmlElementIds: v3_1.z.array(v3_1.z.string()).max(500).default([])
|
|
12
|
+
}).strict().optional().describe('Only explicitly requested removals. Arrays of changed components otherwise upsert by stable ID and preserve omitted components.');
|
|
13
|
+
function upsertComponents(existing, changes, id, removed = []) {
|
|
14
|
+
if (new Set(changes?.map(id)).size !== (changes?.length ?? 0))
|
|
15
|
+
throw new Error('DASHBOARD_DUPLICATE_COMPONENT');
|
|
16
|
+
if (removed.some(key => !existing.some(item => id(item) === key) || changes?.some(item => id(item) === key)))
|
|
17
|
+
throw new Error('DASHBOARD_REMOVAL_INVALID: copy existing IDs and do not also update a removed component');
|
|
18
|
+
const next = new Map(existing.filter(item => !removed.includes(id(item))).map(item => [id(item), item]));
|
|
19
|
+
for (const item of changes ?? [])
|
|
20
|
+
next.set(id(item), item);
|
|
21
|
+
return [...next.values()];
|
|
22
|
+
}
|
|
23
|
+
function htmlElementIds(html) {
|
|
24
|
+
const ids = new Set();
|
|
25
|
+
const visit = (node) => {
|
|
26
|
+
if ('attrs' in node)
|
|
27
|
+
for (const attr of node.attrs)
|
|
28
|
+
if (attr.name === 'id' && attr.value)
|
|
29
|
+
ids.add(attr.value);
|
|
30
|
+
if ('childNodes' in node)
|
|
31
|
+
node.childNodes.forEach(visit);
|
|
32
|
+
if ('content' in node)
|
|
33
|
+
visit(node.content);
|
|
34
|
+
};
|
|
35
|
+
visit((0, parse5_1.parse)(html));
|
|
36
|
+
return ids;
|
|
37
|
+
}
|
|
38
|
+
/** IDs are an explicit preservation contract, not a semantic comparison of arbitrary HTML. */
|
|
39
|
+
function assertHtmlPreserved(previous, next, removed = []) {
|
|
40
|
+
if (!previous || !next || previous.html === next.html)
|
|
41
|
+
return;
|
|
42
|
+
const before = htmlElementIds(previous.html), after = htmlElementIds(next.html);
|
|
43
|
+
const missing = [...before].filter(id => !after.has(id) && !removed.includes(id));
|
|
44
|
+
if (missing.length)
|
|
45
|
+
throw new Error(`DASHBOARD_COMPONENT_REMOVAL_REQUIRED: preserve existing HTML IDs or explicitly declare user-requested removals: ${JSON.stringify(missing)}. Your editing file is retained.`);
|
|
46
|
+
}
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import { z } from 'zod/v3';
|
|
2
|
+
import type { IAgentMiddlewareContext } from '@xpert-ai/plugin-sdk';
|
|
3
|
+
export declare const dashboardSelectionSchema: z.ZodObject<{
|
|
4
|
+
schemaVersion: z.ZodLiteral<1>;
|
|
5
|
+
artifactId: z.ZodString;
|
|
6
|
+
versionId: z.ZodOptional<z.ZodString>;
|
|
7
|
+
draftRevision: z.ZodOptional<z.ZodNumber>;
|
|
8
|
+
}, "strict", z.ZodTypeAny, {
|
|
9
|
+
artifactId: string;
|
|
10
|
+
schemaVersion: 1;
|
|
11
|
+
versionId?: string | undefined;
|
|
12
|
+
draftRevision?: number | undefined;
|
|
13
|
+
}, {
|
|
14
|
+
artifactId: string;
|
|
15
|
+
schemaVersion: 1;
|
|
16
|
+
versionId?: string | undefined;
|
|
17
|
+
draftRevision?: number | undefined;
|
|
18
|
+
}>;
|
|
19
|
+
export declare const dashboardContextSchema: z.ZodObject<{
|
|
20
|
+
live_dashboard: z.ZodOptional<z.ZodNullable<z.ZodUnion<[z.ZodObject<{
|
|
21
|
+
schemaVersion: z.ZodLiteral<1>;
|
|
22
|
+
artifactId: z.ZodString;
|
|
23
|
+
versionId: z.ZodOptional<z.ZodString>;
|
|
24
|
+
draftRevision: z.ZodOptional<z.ZodNumber>;
|
|
25
|
+
}, "strict", z.ZodTypeAny, {
|
|
26
|
+
artifactId: string;
|
|
27
|
+
schemaVersion: 1;
|
|
28
|
+
versionId?: string | undefined;
|
|
29
|
+
draftRevision?: number | undefined;
|
|
30
|
+
}, {
|
|
31
|
+
artifactId: string;
|
|
32
|
+
schemaVersion: 1;
|
|
33
|
+
versionId?: string | undefined;
|
|
34
|
+
draftRevision?: number | undefined;
|
|
35
|
+
}>, z.ZodObject<{
|
|
36
|
+
schemaVersion: z.ZodLiteral<1>;
|
|
37
|
+
mode: z.ZodLiteral<"new">;
|
|
38
|
+
}, "strict", z.ZodTypeAny, {
|
|
39
|
+
mode: "new";
|
|
40
|
+
schemaVersion: 1;
|
|
41
|
+
}, {
|
|
42
|
+
mode: "new";
|
|
43
|
+
schemaVersion: 1;
|
|
44
|
+
}>]>>>;
|
|
45
|
+
}, "strip", z.ZodTypeAny, {
|
|
46
|
+
live_dashboard?: {
|
|
47
|
+
artifactId: string;
|
|
48
|
+
schemaVersion: 1;
|
|
49
|
+
versionId?: string | undefined;
|
|
50
|
+
draftRevision?: number | undefined;
|
|
51
|
+
} | {
|
|
52
|
+
mode: "new";
|
|
53
|
+
schemaVersion: 1;
|
|
54
|
+
} | null | undefined;
|
|
55
|
+
}, {
|
|
56
|
+
live_dashboard?: {
|
|
57
|
+
artifactId: string;
|
|
58
|
+
schemaVersion: 1;
|
|
59
|
+
versionId?: string | undefined;
|
|
60
|
+
draftRevision?: number | undefined;
|
|
61
|
+
} | {
|
|
62
|
+
mode: "new";
|
|
63
|
+
schemaVersion: 1;
|
|
64
|
+
} | null | undefined;
|
|
65
|
+
}>;
|
|
66
|
+
export type DashboardSelection = z.infer<typeof dashboardSelectionSchema>;
|
|
67
|
+
export declare const dashboardStateSchema: z.ZodObject<{
|
|
68
|
+
dashboardEditing: z.ZodOptional<z.ZodNullable<z.ZodObject<{
|
|
69
|
+
scope: z.ZodString;
|
|
70
|
+
target: z.ZodNullable<z.ZodObject<{
|
|
71
|
+
schemaVersion: z.ZodLiteral<1>;
|
|
72
|
+
artifactId: z.ZodString;
|
|
73
|
+
versionId: z.ZodOptional<z.ZodString>;
|
|
74
|
+
draftRevision: z.ZodOptional<z.ZodNumber>;
|
|
75
|
+
}, "strict", z.ZodTypeAny, {
|
|
76
|
+
artifactId: string;
|
|
77
|
+
schemaVersion: 1;
|
|
78
|
+
versionId?: string | undefined;
|
|
79
|
+
draftRevision?: number | undefined;
|
|
80
|
+
}, {
|
|
81
|
+
artifactId: string;
|
|
82
|
+
schemaVersion: 1;
|
|
83
|
+
versionId?: string | undefined;
|
|
84
|
+
draftRevision?: number | undefined;
|
|
85
|
+
}>>;
|
|
86
|
+
}, "strip", z.ZodTypeAny, {
|
|
87
|
+
target: {
|
|
88
|
+
artifactId: string;
|
|
89
|
+
schemaVersion: 1;
|
|
90
|
+
versionId?: string | undefined;
|
|
91
|
+
draftRevision?: number | undefined;
|
|
92
|
+
} | null;
|
|
93
|
+
scope: string;
|
|
94
|
+
}, {
|
|
95
|
+
target: {
|
|
96
|
+
artifactId: string;
|
|
97
|
+
schemaVersion: 1;
|
|
98
|
+
versionId?: string | undefined;
|
|
99
|
+
draftRevision?: number | undefined;
|
|
100
|
+
} | null;
|
|
101
|
+
scope: string;
|
|
102
|
+
}>>>;
|
|
103
|
+
}, "strip", z.ZodTypeAny, {
|
|
104
|
+
dashboardEditing?: {
|
|
105
|
+
target: {
|
|
106
|
+
artifactId: string;
|
|
107
|
+
schemaVersion: 1;
|
|
108
|
+
versionId?: string | undefined;
|
|
109
|
+
draftRevision?: number | undefined;
|
|
110
|
+
} | null;
|
|
111
|
+
scope: string;
|
|
112
|
+
} | null | undefined;
|
|
113
|
+
}, {
|
|
114
|
+
dashboardEditing?: {
|
|
115
|
+
target: {
|
|
116
|
+
artifactId: string;
|
|
117
|
+
schemaVersion: 1;
|
|
118
|
+
versionId?: string | undefined;
|
|
119
|
+
draftRevision?: number | undefined;
|
|
120
|
+
} | null;
|
|
121
|
+
scope: string;
|
|
122
|
+
} | null | undefined;
|
|
123
|
+
}>;
|
|
124
|
+
/** Checkpoints belong to an actor and conversation. Copied state must never choose another user's target. */
|
|
125
|
+
export declare function editingSession(context: IAgentMiddlewareContext): {
|
|
126
|
+
current: () => {
|
|
127
|
+
artifactId: string;
|
|
128
|
+
schemaVersion: 1;
|
|
129
|
+
versionId?: string | undefined;
|
|
130
|
+
draftRevision?: number | undefined;
|
|
131
|
+
} | null;
|
|
132
|
+
resolve(config: unknown): {
|
|
133
|
+
artifactId: string;
|
|
134
|
+
schemaVersion: 1;
|
|
135
|
+
versionId?: string | undefined;
|
|
136
|
+
draftRevision?: number | undefined;
|
|
137
|
+
} | null;
|
|
138
|
+
restore(state: unknown, requestContext: unknown): {
|
|
139
|
+
dashboardEditing: {
|
|
140
|
+
scope: string;
|
|
141
|
+
target: {
|
|
142
|
+
artifactId: string;
|
|
143
|
+
schemaVersion: 1;
|
|
144
|
+
versionId?: string | undefined;
|
|
145
|
+
draftRevision?: number | undefined;
|
|
146
|
+
} | null;
|
|
147
|
+
};
|
|
148
|
+
};
|
|
149
|
+
select(target: DashboardSelection | null): {
|
|
150
|
+
dashboardEditing: {
|
|
151
|
+
scope: string;
|
|
152
|
+
target: {
|
|
153
|
+
artifactId: string;
|
|
154
|
+
schemaVersion: 1;
|
|
155
|
+
versionId?: string | undefined;
|
|
156
|
+
draftRevision?: number | undefined;
|
|
157
|
+
} | null;
|
|
158
|
+
};
|
|
159
|
+
};
|
|
160
|
+
};
|
|
161
|
+
export declare function selectionFromContext(value: unknown): DashboardSelection | null | undefined;
|
|
162
|
+
export declare function selectionFromConfig(value: unknown): {
|
|
163
|
+
artifactId: string;
|
|
164
|
+
schemaVersion: 1;
|
|
165
|
+
versionId?: string | undefined;
|
|
166
|
+
draftRevision?: number | undefined;
|
|
167
|
+
} | null | undefined;
|