@antelopejs/dms-ai 0.3.0 → 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/README.md +67 -206
- package/dist/index.js +3 -2
- package/dist/index.js.map +1 -1
- package/dist/lifecycle/skill-sources.d.ts +1 -1
- package/dist/lifecycle/skill-sources.js +29 -13
- package/dist/lifecycle/skill-sources.js.map +1 -1
- package/frontend-vue/app/chat/components/BlockPreviewCard.vue +172 -0
- package/frontend-vue/app/chat/components/BlockPreviewModal.vue +324 -0
- package/frontend-vue/app/chat/components/BlockPreviewThumb.vue +141 -0
- package/frontend-vue/app/chat/components/MessageList.vue +20 -0
- package/frontend-vue/app/chat/components/SketchFrame.vue +59 -0
- package/frontend-vue/app/chat/composables/conversation-events.ts +23 -1
- package/frontend-vue/app/chat/composables/useBlockPreviewComponent.ts +15 -0
- package/frontend-vue/app/chat/composables/useDashboardScheme.ts +42 -0
- package/frontend-vue/app/chat/constants/block-preview.ts +27 -0
- package/frontend-vue/app/chat/constants/conversation.ts +1 -0
- package/frontend-vue/app/chat/constants/protocol.ts +1 -0
- package/frontend-vue/app/chat/constants/sketch.ts +105 -0
- package/frontend-vue/app/chat/types/conversation.ts +11 -1
- package/frontend-vue/app/chat/types/protocol.ts +56 -0
- package/frontend-vue/app/chat/utils/block-preview.ts +145 -0
- package/frontend-vue/app/chat/utils/conversation-messages.ts +23 -1
- package/frontend-vue/app/chat/utils/render-items.ts +13 -2
- package/frontend-vue/app/chat/utils/sketch.ts +56 -0
- package/frontend-vue/app/chat/utils/tool-lexicon.ts +7 -0
- package/frontend-vue/app/runtime/session-gate.ts +11 -5
- package/frontend-vue/i18n/locales/dms-ai-panel-en-GB.json +23 -1
- package/frontend-vue/i18n/locales/dms-ai-panel-fr-FR.json +23 -1
- package/frontend-vue/package.json +1 -1
- package/frontend-vue/tests/chat/block-preview.test.ts +448 -0
- package/frontend-vue/tests/session-gate.test.ts +28 -1
- package/package.json +22 -8
- package/sidecar/dist/constants/mcp.js +2 -0
- package/sidecar/dist/constants/mcp.js.map +1 -1
- package/sidecar/dist/constants/preview.d.ts +39 -0
- package/sidecar/dist/constants/preview.js +55 -0
- package/sidecar/dist/constants/preview.js.map +1 -0
- package/sidecar/dist/constants/tool-kinds.js +2 -0
- package/sidecar/dist/constants/tool-kinds.js.map +1 -1
- package/sidecar/dist/mcp/tool-definitions.js +5 -0
- package/sidecar/dist/mcp/tool-definitions.js.map +1 -1
- package/sidecar/dist/mcp/tools/preview-blocks.d.ts +65 -0
- package/sidecar/dist/mcp/tools/preview-blocks.js +176 -0
- package/sidecar/dist/mcp/tools/preview-blocks.js.map +1 -0
- package/sidecar/dist/mcp/types.d.ts +3 -0
- package/sidecar/dist/prompts/agent.d.ts +1 -1
- package/sidecar/dist/prompts/agent.js +3 -2
- package/sidecar/dist/prompts/agent.js.map +1 -1
- package/sidecar/dist/protocol/events.d.ts +313 -0
- package/sidecar/dist/protocol/events.js +9 -0
- package/sidecar/dist/protocol/events.js.map +1 -1
- package/sidecar/dist/protocol/preview.d.ts +130 -0
- package/sidecar/dist/protocol/preview.js +91 -0
- package/sidecar/dist/protocol/preview.js.map +1 -0
- package/sidecar/dist/server/chat-events.d.ts +3 -0
- package/sidecar/dist/server/chat-events.js +21 -0
- package/sidecar/dist/server/chat-events.js.map +1 -1
- package/sidecar/dist/server/ws.js +3 -1
- package/sidecar/dist/server/ws.js.map +1 -1
- package/sidecar/dist/state/types.d.ts +3 -1
- package/sidecar/dist/state/types.js +1 -0
- package/sidecar/dist/state/types.js.map +1 -1
- package/sidecar/package.json +1 -1
- package/skills/dms-ai/SKILL.md +30 -0
- package/skills/dms-ai-code-mode/SKILL.md +51 -0
- package/skills/dms-builder-safe/SKILL.md +9 -2
- package/skills/dms-builder-page/SKILL.md +0 -80
package/package.json
CHANGED
|
@@ -1,6 +1,20 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@antelopejs/dms-ai",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.1",
|
|
4
|
+
"description": "AI development assistant for the AntelopeJS DMS: a chat panel next to every page and a coding agent that edits the project in reviewable, undoable change sets.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"ai",
|
|
7
|
+
"antelopejs",
|
|
8
|
+
"assistant",
|
|
9
|
+
"claude-code",
|
|
10
|
+
"codex",
|
|
11
|
+
"dms",
|
|
12
|
+
"dms-module"
|
|
13
|
+
],
|
|
14
|
+
"homepage": "https://dms.antelopejs.com/docs/modules/ai",
|
|
15
|
+
"bugs": {
|
|
16
|
+
"url": "https://github.com/AntelopeJS/dms-ai/issues"
|
|
17
|
+
},
|
|
4
18
|
"license": "Apache-2.0",
|
|
5
19
|
"repository": {
|
|
6
20
|
"type": "git",
|
|
@@ -29,7 +43,7 @@
|
|
|
29
43
|
},
|
|
30
44
|
"scripts": {
|
|
31
45
|
"build": "rimraf dist && tsc",
|
|
32
|
-
"build:sidecar": "
|
|
46
|
+
"build:sidecar": "pnpm --dir sidecar run build",
|
|
33
47
|
"prepack": "pnpm run build && pnpm run build:sidecar",
|
|
34
48
|
"frontend:dev": "cd playground && pnpm frontend:dev",
|
|
35
49
|
"dev": "cd playground && pnpm dev",
|
|
@@ -46,15 +60,15 @@
|
|
|
46
60
|
"test:sidecar-lifecycle": "node --test tests/sidecar-lifecycle.test.cjs",
|
|
47
61
|
"test:build-id": "node --test tests/build-id.test.cjs",
|
|
48
62
|
"test:e2e": "cd sidecar && pnpm test:e2e",
|
|
49
|
-
"release": "pnpm
|
|
63
|
+
"release": "pnpm install --frozen-lockfile && release-it",
|
|
50
64
|
"format": "oxfmt --disable-nested-config . && cd frontend-vue && pnpm format",
|
|
51
65
|
"knip": "knip --dependencies",
|
|
52
66
|
"knip:all": "knip"
|
|
53
67
|
},
|
|
54
68
|
"dependencies": {
|
|
55
|
-
"@antelopejs/interface-api": ">=0.0.
|
|
56
|
-
"@antelopejs/interface-core": ">=0.
|
|
57
|
-
"@antelopejs/interface-dms": ">=0.7.
|
|
69
|
+
"@antelopejs/interface-api": ">=0.0.15 <1.0.0",
|
|
70
|
+
"@antelopejs/interface-core": ">=0.2.4 <1.0.0",
|
|
71
|
+
"@antelopejs/interface-dms": ">=0.7.2 <1.0.0",
|
|
58
72
|
"@anthropic-ai/claude-agent-sdk": "^0.2.131",
|
|
59
73
|
"@anthropic-ai/claude-code": "^2.1.131",
|
|
60
74
|
"@modelcontextprotocol/sdk": "1.29.0",
|
|
@@ -62,7 +76,7 @@
|
|
|
62
76
|
"zod": "^4.0.0"
|
|
63
77
|
},
|
|
64
78
|
"devDependencies": {
|
|
65
|
-
"@antelopejs/tooling-configs": ">=0.0.
|
|
79
|
+
"@antelopejs/tooling-configs": ">=0.0.9 <1.0.0",
|
|
66
80
|
"@types/node": "^24.0.0",
|
|
67
81
|
"@types/ws": "^8.5.12",
|
|
68
82
|
"knip": "^6.34.0",
|
|
@@ -83,7 +97,7 @@
|
|
|
83
97
|
}
|
|
84
98
|
},
|
|
85
99
|
"optionalDependencies": {
|
|
86
|
-
"@antelopejs/interface-dms-builder": ">=0.1
|
|
100
|
+
"@antelopejs/interface-dms-builder": ">=0.2.1 <1.0.0"
|
|
87
101
|
},
|
|
88
102
|
"packageManager": "pnpm@10.2.0",
|
|
89
103
|
"antelopeJs": {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { BUILDER_TOOL_NAMES } from "./builder.js";
|
|
2
2
|
import { QUERY_LOGS_TOOL_NAME } from "./logs.js";
|
|
3
3
|
import { FIND_PAGES_TOOL_NAME, LIST_PAGES_TOOL_NAME } from "./pages.js";
|
|
4
|
+
import { PREVIEW_BLOCKS_TOOL_NAME } from "./preview.js";
|
|
4
5
|
import { REQUEST_TIMEOUT_MINUTES } from "../state/settings-types.js";
|
|
5
6
|
import { QUESTION_TIMEOUT_MS } from "./questions.js";
|
|
6
7
|
import { MS_PER_MINUTE } from "./settings.js";
|
|
@@ -35,6 +36,7 @@ export const FIRST_PARTY_AUTO_ALLOW_TOOL_NAMES = new Set([
|
|
|
35
36
|
FIND_PAGES_TOOL_NAME,
|
|
36
37
|
LIST_PAGES_TOOL_NAME,
|
|
37
38
|
ASK_USER_TOOL_NAME,
|
|
39
|
+
PREVIEW_BLOCKS_TOOL_NAME,
|
|
38
40
|
TYPECHECK_TOOL_NAME,
|
|
39
41
|
QUERY_LOGS_TOOL_NAME,
|
|
40
42
|
...BUILDER_TOOL_NAMES,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp.js","sourceRoot":"","sources":["../../src/constants/mcp.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"mcp.js","sourceRoot":"","sources":["../../src/constants/mcp.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
export declare const PREVIEW_BLOCKS_TOOL_NAME = "PreviewBlocks";
|
|
2
|
+
export declare const PREVIEW_BLOCKS_TOOL_DESCRIPTION = "Shows the user a live preview of DMS blocks as an attachment in the chat: a card they open to see the real blocks rendered, next to their own mockup when you pass it as `reference`, with one tab per variant. A view may carry a `sketch` instead of (or beside) its `tree`: static HTML and CSS of a custom component you propose, drawn in a sandbox and labelled as not a DMS block, so the user compares it with the DMS option before any code is written. Use it to settle a visual choice before building (DMS block as is versus custom, or between layouts), then ask the decision with AskUser. It returns at once with the preview id; it does not wait for the user and changes nothing in the project.";
|
|
3
|
+
export declare const PREVIEW_MAX_DEPTH = 8;
|
|
4
|
+
export declare const PREVIEW_MAX_NODES = 200;
|
|
5
|
+
export declare const PREVIEW_MAX_VARIANTS = 4;
|
|
6
|
+
export declare const PREVIEW_MAX_ROOTS = 12;
|
|
7
|
+
export declare const PREVIEW_MAX_TITLE_CHARS = 120;
|
|
8
|
+
export declare const PREVIEW_MAX_LABEL_CHARS = 60;
|
|
9
|
+
export declare const PREVIEW_MAX_DESCRIPTION_CHARS = 2000;
|
|
10
|
+
export declare const PREVIEW_MAX_CAPTION_CHARS = 200;
|
|
11
|
+
export declare const PREVIEW_MAX_URL_CHARS = 2048;
|
|
12
|
+
export declare const PREVIEW_MAX_JSON_BYTES: number;
|
|
13
|
+
export declare const PREVIEW_SKETCH_MIN_HEIGHT_PX = 80;
|
|
14
|
+
export declare const PREVIEW_SKETCH_DEFAULT_HEIGHT_PX = 320;
|
|
15
|
+
export declare const PREVIEW_SKETCH_MAX_HEIGHT_PX = 1200;
|
|
16
|
+
export declare const PREVIEW_LATEST_ATTACHMENT_ID = "latest";
|
|
17
|
+
export declare const PREVIEW_SAME_ORIGIN_PATH: RegExp;
|
|
18
|
+
export declare const PREVIEW_REMOTE_URL: RegExp;
|
|
19
|
+
export declare const PREVIEW_IMAGE_MIME_PREFIX = "image/";
|
|
20
|
+
export declare const PREVIEW_URL_OPTION_KEY: RegExp;
|
|
21
|
+
export declare const PREVIEW_ERROR_CODES: {
|
|
22
|
+
readonly INVALID_TREE: "invalid_tree";
|
|
23
|
+
readonly TOO_LARGE: "too_large";
|
|
24
|
+
readonly UNKNOWN_ATTACHMENT: "unknown_attachment";
|
|
25
|
+
readonly INVALID_URL: "invalid_url";
|
|
26
|
+
readonly INVALID_SKETCH: "invalid_sketch";
|
|
27
|
+
};
|
|
28
|
+
export declare const PREVIEW_SKETCH_FORBIDDEN: ReadonlyArray<readonly [RegExp, string]>;
|
|
29
|
+
export declare const PREVIEW_RESULT_SHOWN = "Preview shown to the user as an attachment. If it settles a choice, ask it now with AskUser.";
|
|
30
|
+
export declare const PREVIEW_ERROR_NO_TYPE = "Every node needs a `type` (a block type from BuilderCatalog) or a `componentName`.";
|
|
31
|
+
export declare const PREVIEW_ERROR_DEPTH = "The tree is nested deeper than 8 levels.";
|
|
32
|
+
export declare const PREVIEW_ERROR_NODES = "The preview has more than 200 nodes in all; show a smaller part of the page.";
|
|
33
|
+
export declare const PREVIEW_ERROR_BYTES = "The preview's trees and sketches are larger than 65536 bytes of JSON; show a smaller part of the page.";
|
|
34
|
+
export declare const PREVIEW_ERROR_NO_ATTACHMENTS = "The user attached no image in this conversation; leave `reference.attachmentId` out.";
|
|
35
|
+
export declare const PREVIEW_ERROR_UNKNOWN_ATTACHMENT = "No image of that name was attached in this conversation. Attached images: ";
|
|
36
|
+
export declare const PREVIEW_ERROR_OPTION_URL = "Options ending in `Url` (and `location`) must be same-origin paths such as `/api/orders`, or the preview refuses the block. Offending option: ";
|
|
37
|
+
export declare const PREVIEW_ERROR_EMPTY_VIEW = "Every view (the preview and each variant) needs a `tree`, a `sketch`, or both.";
|
|
38
|
+
export declare const PREVIEW_ERROR_SKETCH = "A sketch is static HTML and CSS: inline images and fonts as data: URLs, and use no script, event handler, external resource or embedded frame. Refused: ";
|
|
39
|
+
export declare const PREVIEW_ERROR_URL = "`reference.url` must be a same-origin path (`/media/...`) or an http(s) URL.";
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
export const PREVIEW_BLOCKS_TOOL_NAME = "PreviewBlocks";
|
|
2
|
+
export const PREVIEW_BLOCKS_TOOL_DESCRIPTION = "Shows the user a live preview of DMS blocks as an attachment in the chat: a card they open to see the real blocks rendered, next to their own mockup when you pass it as `reference`, with one tab per variant. A view may carry a `sketch` instead of (or beside) its `tree`: static HTML and CSS of a custom component you propose, drawn in a sandbox and labelled as not a DMS block, so the user compares it with the DMS option before any code is written. Use it to settle a visual choice before building (DMS block as is versus custom, or between layouts), then ask the decision with AskUser. It returns at once with the preview id; it does not wait for the user and changes nothing in the project.";
|
|
3
|
+
export const PREVIEW_MAX_DEPTH = 8;
|
|
4
|
+
export const PREVIEW_MAX_NODES = 200;
|
|
5
|
+
export const PREVIEW_MAX_VARIANTS = 4;
|
|
6
|
+
export const PREVIEW_MAX_ROOTS = 12;
|
|
7
|
+
export const PREVIEW_MAX_TITLE_CHARS = 120;
|
|
8
|
+
export const PREVIEW_MAX_LABEL_CHARS = 60;
|
|
9
|
+
export const PREVIEW_MAX_DESCRIPTION_CHARS = 2_000;
|
|
10
|
+
export const PREVIEW_MAX_CAPTION_CHARS = 200;
|
|
11
|
+
export const PREVIEW_MAX_URL_CHARS = 2_048;
|
|
12
|
+
export const PREVIEW_MAX_JSON_BYTES = 64 * 1024;
|
|
13
|
+
export const PREVIEW_SKETCH_MIN_HEIGHT_PX = 80;
|
|
14
|
+
export const PREVIEW_SKETCH_DEFAULT_HEIGHT_PX = 320;
|
|
15
|
+
export const PREVIEW_SKETCH_MAX_HEIGHT_PX = 1_200;
|
|
16
|
+
export const PREVIEW_LATEST_ATTACHMENT_ID = "latest";
|
|
17
|
+
export const PREVIEW_SAME_ORIGIN_PATH = /^\/(?![/\\])/;
|
|
18
|
+
export const PREVIEW_REMOTE_URL = /^https?:\/\//i;
|
|
19
|
+
export const PREVIEW_IMAGE_MIME_PREFIX = "image/";
|
|
20
|
+
export const PREVIEW_URL_OPTION_KEY = /(?:Url|^location)$/;
|
|
21
|
+
export const PREVIEW_ERROR_CODES = {
|
|
22
|
+
INVALID_TREE: "invalid_tree",
|
|
23
|
+
TOO_LARGE: "too_large",
|
|
24
|
+
UNKNOWN_ATTACHMENT: "unknown_attachment",
|
|
25
|
+
INVALID_URL: "invalid_url",
|
|
26
|
+
INVALID_SKETCH: "invalid_sketch",
|
|
27
|
+
};
|
|
28
|
+
export const PREVIEW_SKETCH_FORBIDDEN = [
|
|
29
|
+
[/<\s*script\b/i, "a <script> element"],
|
|
30
|
+
[
|
|
31
|
+
/<\s*(?:iframe|frame|frameset|object|embed|applet|portal|link|base)\b/i,
|
|
32
|
+
"an embedding or linking element (iframe, object, embed, link, base)",
|
|
33
|
+
],
|
|
34
|
+
[/<\s*meta\b[^>]*http-equiv/i, "a <meta http-equiv>"],
|
|
35
|
+
[/<[^>]*[\s/"']on[a-z]+\s*=/i, "an on* event handler attribute"],
|
|
36
|
+
[/(?:java|vb)script\s*:/i, "a javascript: URL"],
|
|
37
|
+
[/@import\b/i, "a CSS @import"],
|
|
38
|
+
[/url\(\s*(?!['"]?\s*data:)/i, "a url() that is not a data: URL"],
|
|
39
|
+
[
|
|
40
|
+
/<[^>]*\s(?:src|srcset|href|xlink:href|poster|action|formaction|background|data|ping)\s*=\s*(?!['"]?\s*(?:data:|#))/i,
|
|
41
|
+
"a src, href or similar attribute that is not a data: URL or an #anchor",
|
|
42
|
+
],
|
|
43
|
+
];
|
|
44
|
+
export const PREVIEW_RESULT_SHOWN = "Preview shown to the user as an attachment. If it settles a choice, ask it now with AskUser.";
|
|
45
|
+
export const PREVIEW_ERROR_NO_TYPE = "Every node needs a `type` (a block type from BuilderCatalog) or a `componentName`.";
|
|
46
|
+
export const PREVIEW_ERROR_DEPTH = `The tree is nested deeper than ${PREVIEW_MAX_DEPTH} levels.`;
|
|
47
|
+
export const PREVIEW_ERROR_NODES = `The preview has more than ${PREVIEW_MAX_NODES} nodes in all; show a smaller part of the page.`;
|
|
48
|
+
export const PREVIEW_ERROR_BYTES = `The preview's trees and sketches are larger than ${PREVIEW_MAX_JSON_BYTES} bytes of JSON; show a smaller part of the page.`;
|
|
49
|
+
export const PREVIEW_ERROR_NO_ATTACHMENTS = "The user attached no image in this conversation; leave `reference.attachmentId` out.";
|
|
50
|
+
export const PREVIEW_ERROR_UNKNOWN_ATTACHMENT = "No image of that name was attached in this conversation. Attached images: ";
|
|
51
|
+
export const PREVIEW_ERROR_OPTION_URL = "Options ending in `Url` (and `location`) must be same-origin paths such as `/api/orders`, or the preview refuses the block. Offending option: ";
|
|
52
|
+
export const PREVIEW_ERROR_EMPTY_VIEW = "Every view (the preview and each variant) needs a `tree`, a `sketch`, or both.";
|
|
53
|
+
export const PREVIEW_ERROR_SKETCH = "A sketch is static HTML and CSS: inline images and fonts as data: URLs, and use no script, event handler, external resource or embedded frame. Refused: ";
|
|
54
|
+
export const PREVIEW_ERROR_URL = "`reference.url` must be a same-origin path (`/media/...`) or an http(s) URL.";
|
|
55
|
+
//# sourceMappingURL=preview.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"preview.js","sourceRoot":"","sources":["../../src/constants/preview.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,wBAAwB,GAAG,eAAe,CAAC;AACxD,MAAM,CAAC,MAAM,+BAA+B,GAC1C,urBAAurB,CAAC;AAG1rB,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAC;AACnC,MAAM,CAAC,MAAM,iBAAiB,GAAG,GAAG,CAAC;AACrC,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,CAAC;AACtC,MAAM,CAAC,MAAM,iBAAiB,GAAG,EAAE,CAAC;AACpC,MAAM,CAAC,MAAM,uBAAuB,GAAG,GAAG,CAAC;AAC3C,MAAM,CAAC,MAAM,uBAAuB,GAAG,EAAE,CAAC;AAC1C,MAAM,CAAC,MAAM,6BAA6B,GAAG,KAAK,CAAC;AACnD,MAAM,CAAC,MAAM,yBAAyB,GAAG,GAAG,CAAC;AAC7C,MAAM,CAAC,MAAM,qBAAqB,GAAG,KAAK,CAAC;AAC3C,MAAM,CAAC,MAAM,sBAAsB,GAAG,EAAE,GAAG,IAAI,CAAC;AAChD,MAAM,CAAC,MAAM,4BAA4B,GAAG,EAAE,CAAC;AAC/C,MAAM,CAAC,MAAM,gCAAgC,GAAG,GAAG,CAAC;AACpD,MAAM,CAAC,MAAM,4BAA4B,GAAG,KAAK,CAAC;AAGlD,MAAM,CAAC,MAAM,4BAA4B,GAAG,QAAQ,CAAC;AAGrD,MAAM,CAAC,MAAM,wBAAwB,GAAG,cAAc,CAAC;AACvD,MAAM,CAAC,MAAM,kBAAkB,GAAG,eAAe,CAAC;AAElD,MAAM,CAAC,MAAM,yBAAyB,GAAG,QAAQ,CAAC;AAGlD,MAAM,CAAC,MAAM,sBAAsB,GAAG,oBAAoB,CAAC;AAE3D,MAAM,CAAC,MAAM,mBAAmB,GAAG;IACjC,YAAY,EAAE,cAAc;IAC5B,SAAS,EAAE,WAAW;IACtB,kBAAkB,EAAE,oBAAoB;IACxC,WAAW,EAAE,aAAa;IAC1B,cAAc,EAAE,gBAAgB;CACxB,CAAC;AAOX,MAAM,CAAC,MAAM,wBAAwB,GAEjC;IACF,CAAC,eAAe,EAAE,oBAAoB,CAAC;IACvC;QACE,uEAAuE;QACvE,qEAAqE;KACtE;IACD,CAAC,4BAA4B,EAAE,qBAAqB,CAAC;IACrD,CAAC,4BAA4B,EAAE,gCAAgC,CAAC;IAChE,CAAC,wBAAwB,EAAE,mBAAmB,CAAC;IAC/C,CAAC,YAAY,EAAE,eAAe,CAAC;IAC/B,CAAC,4BAA4B,EAAE,iCAAiC,CAAC;IACjE;QACE,qHAAqH;QACrH,wEAAwE;KACzE;CACF,CAAC;AAEF,MAAM,CAAC,MAAM,oBAAoB,GAC/B,8FAA8F,CAAC;AACjG,MAAM,CAAC,MAAM,qBAAqB,GAChC,oFAAoF,CAAC;AACvF,MAAM,CAAC,MAAM,mBAAmB,GAAG,kCAAkC,iBAAiB,UAAU,CAAC;AACjG,MAAM,CAAC,MAAM,mBAAmB,GAAG,6BAA6B,iBAAiB,iDAAiD,CAAC;AACnI,MAAM,CAAC,MAAM,mBAAmB,GAAG,oDAAoD,sBAAsB,kDAAkD,CAAC;AAChK,MAAM,CAAC,MAAM,4BAA4B,GACvC,sFAAsF,CAAC;AACzF,MAAM,CAAC,MAAM,gCAAgC,GAC3C,4EAA4E,CAAC;AAC/E,MAAM,CAAC,MAAM,wBAAwB,GACnC,gJAAgJ,CAAC;AACnJ,MAAM,CAAC,MAAM,wBAAwB,GACnC,gFAAgF,CAAC;AACnF,MAAM,CAAC,MAAM,oBAAoB,GAC/B,0JAA0J,CAAC;AAC7J,MAAM,CAAC,MAAM,iBAAiB,GAC5B,8EAA8E,CAAC"}
|
|
@@ -2,6 +2,7 @@ import { BUILDER_TOOL_NAMES } from "./builder.js";
|
|
|
2
2
|
import { QUERY_LOGS_TOOL_NAME } from "./logs.js";
|
|
3
3
|
import { ASK_USER_TOOL_NAME, GET_CURRENT_PAGE_TOOL_NAME, NAVIGATE_TOOL_NAME, } from "./mcp.js";
|
|
4
4
|
import { FIND_PAGES_TOOL_NAME, LIST_PAGES_TOOL_NAME } from "./pages.js";
|
|
5
|
+
import { PREVIEW_BLOCKS_TOOL_NAME } from "./preview.js";
|
|
5
6
|
import { TYPECHECK_TOOL_NAME } from "./typecheck.js";
|
|
6
7
|
export const EDIT_TOOL_NAMES = [
|
|
7
8
|
"Edit",
|
|
@@ -53,6 +54,7 @@ export const PROJECT_READ_TOOL_NAMES = [
|
|
|
53
54
|
];
|
|
54
55
|
export const ASSISTANT_TOOL_NAMES = [
|
|
55
56
|
ASK_USER_TOOL_NAME,
|
|
57
|
+
PREVIEW_BLOCKS_TOOL_NAME,
|
|
56
58
|
"TodoWrite",
|
|
57
59
|
"Skill",
|
|
58
60
|
"Task",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tool-kinds.js","sourceRoot":"","sources":["../../src/constants/tool-kinds.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AACjD,OAAO,EACL,kBAAkB,EAClB,0BAA0B,EAC1B,kBAAkB,GACnB,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AACxE,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAGrD,MAAM,CAAC,MAAM,eAAe,GAAsB;IAChD,MAAM;IACN,OAAO;IACP,WAAW;IACX,cAAc;CACf,CAAC;AAEF,MAAM,CAAC,MAAM,kBAAkB,GAAsB,CAAC,MAAM,CAAC,CAAC;AAE9D,MAAM,CAAC,MAAM,cAAc,GAAsB,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC;AAG3E,MAAM,CAAC,MAAM,uBAAuB,GAAsB;IACxD,MAAM;IACN,IAAI;IACJ,MAAM;IACN,MAAM;IACN,cAAc;IACd,WAAW;IACX,OAAO;IACP,MAAM;IACN,cAAc;CACf,CAAC;AAGF,MAAM,CAAC,MAAM,uBAAuB,GAAsB;IACxD,gBAAgB;IAChB,kBAAkB;IAClB,sBAAsB;IACtB,sBAAsB;IACtB,0BAA0B;IAC1B,uBAAuB;IACvB,gBAAgB;CACjB,CAAC;AAGF,MAAM,CAAC,MAAM,8BAA8B,GAAsB;IAC/D,mBAAmB;IACnB,uBAAuB;IACvB,oBAAoB;IACpB,uBAAuB;IACvB,oBAAoB;CACrB,CAAC;AAGF,MAAM,CAAC,MAAM,gCAAgC,GAAsB;IACjE,oBAAoB;IACpB,kBAAkB;CACnB,CAAC;AAEF,MAAM,CAAC,MAAM,iCAAiC,GAAG,uBAAuB,CAAC;AAGzE,MAAM,CAAC,MAAM,uBAAuB,GAAsB;IACxD,0BAA0B;IAC1B,kBAAkB;IAClB,oBAAoB;IACpB,oBAAoB;IACpB,mBAAmB;IACnB,oBAAoB;CACrB,CAAC;AAEF,MAAM,CAAC,MAAM,oBAAoB,GAAsB;IACrD,kBAAkB;IAClB,WAAW;IACX,OAAO;IACP,MAAM;IACN,cAAc;CACf,CAAC;AAEF,MAAM,CAAC,MAAM,2BAA2B,GACtC,kBAAkB,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,uBAAuB,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;AAE/E,MAAM,CAAC,MAAM,eAAe,GAAG,OAAO,CAAC;AACvC,MAAM,CAAC,MAAM,mBAAmB,GAAsB,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;AAC3E,MAAM,CAAC,MAAM,eAAe,GAAG,UAAU,CAAC"}
|
|
1
|
+
{"version":3,"file":"tool-kinds.js","sourceRoot":"","sources":["../../src/constants/tool-kinds.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AACjD,OAAO,EACL,kBAAkB,EAClB,0BAA0B,EAC1B,kBAAkB,GACnB,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AACxE,OAAO,EAAE,wBAAwB,EAAE,MAAM,cAAc,CAAC;AACxD,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAGrD,MAAM,CAAC,MAAM,eAAe,GAAsB;IAChD,MAAM;IACN,OAAO;IACP,WAAW;IACX,cAAc;CACf,CAAC;AAEF,MAAM,CAAC,MAAM,kBAAkB,GAAsB,CAAC,MAAM,CAAC,CAAC;AAE9D,MAAM,CAAC,MAAM,cAAc,GAAsB,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC;AAG3E,MAAM,CAAC,MAAM,uBAAuB,GAAsB;IACxD,MAAM;IACN,IAAI;IACJ,MAAM;IACN,MAAM;IACN,cAAc;IACd,WAAW;IACX,OAAO;IACP,MAAM;IACN,cAAc;CACf,CAAC;AAGF,MAAM,CAAC,MAAM,uBAAuB,GAAsB;IACxD,gBAAgB;IAChB,kBAAkB;IAClB,sBAAsB;IACtB,sBAAsB;IACtB,0BAA0B;IAC1B,uBAAuB;IACvB,gBAAgB;CACjB,CAAC;AAGF,MAAM,CAAC,MAAM,8BAA8B,GAAsB;IAC/D,mBAAmB;IACnB,uBAAuB;IACvB,oBAAoB;IACpB,uBAAuB;IACvB,oBAAoB;CACrB,CAAC;AAGF,MAAM,CAAC,MAAM,gCAAgC,GAAsB;IACjE,oBAAoB;IACpB,kBAAkB;CACnB,CAAC;AAEF,MAAM,CAAC,MAAM,iCAAiC,GAAG,uBAAuB,CAAC;AAGzE,MAAM,CAAC,MAAM,uBAAuB,GAAsB;IACxD,0BAA0B;IAC1B,kBAAkB;IAClB,oBAAoB;IACpB,oBAAoB;IACpB,mBAAmB;IACnB,oBAAoB;CACrB,CAAC;AAEF,MAAM,CAAC,MAAM,oBAAoB,GAAsB;IACrD,kBAAkB;IAClB,wBAAwB;IACxB,WAAW;IACX,OAAO;IACP,MAAM;IACN,cAAc;CACf,CAAC;AAEF,MAAM,CAAC,MAAM,2BAA2B,GACtC,kBAAkB,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,uBAAuB,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;AAE/E,MAAM,CAAC,MAAM,eAAe,GAAG,OAAO,CAAC;AACvC,MAAM,CAAC,MAAM,mBAAmB,GAAsB,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;AAC3E,MAAM,CAAC,MAAM,eAAe,GAAG,UAAU,CAAC"}
|
|
@@ -4,6 +4,7 @@ import { buildFindPagesUsingTool } from "./tools/find-pages-using.js";
|
|
|
4
4
|
import { buildGetCurrentPageTool } from "./tools/get-current-page.js";
|
|
5
5
|
import { buildListPagesTool } from "./tools/list-pages.js";
|
|
6
6
|
import { buildNavigateToPageTool } from "./tools/navigate-to-page.js";
|
|
7
|
+
import { buildPreviewBlocksTool } from "./tools/preview-blocks.js";
|
|
7
8
|
import { buildQueryLogsTool } from "./tools/query-logs.js";
|
|
8
9
|
import { buildTypecheckTool } from "./tools/typecheck.js";
|
|
9
10
|
export function buildToolDefinitions(deps) {
|
|
@@ -33,6 +34,10 @@ export function buildToolDefinitions(deps) {
|
|
|
33
34
|
conversationId: deps.conversationId,
|
|
34
35
|
requestQuestion: deps.requestQuestion,
|
|
35
36
|
}),
|
|
37
|
+
buildPreviewBlocksTool({
|
|
38
|
+
showPreview: deps.showPreview,
|
|
39
|
+
listAttachedImages: deps.listAttachedImages,
|
|
40
|
+
}),
|
|
36
41
|
buildTypecheckTool({
|
|
37
42
|
hostProjectRoot: deps.hostProjectRoot,
|
|
38
43
|
moduleRoots: deps.moduleRoots,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tool-definitions.js","sourceRoot":"","sources":["../../src/mcp/tool-definitions.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,uBAAuB,EAAE,MAAM,6BAA6B,CAAC;AACtE,OAAO,EAAE,uBAAuB,EAAE,MAAM,6BAA6B,CAAC;AACtE,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAE,uBAAuB,EAAE,MAAM,6BAA6B,CAAC;AACtE,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAG1D,MAAM,UAAU,oBAAoB,CAClC,IAAqB;IAErB,MAAM,YAAY,GAAG,IAAI,CAAC,cAAc;QACtC,CAAC,CAAC,iBAAiB,CAAC;YAChB,aAAa,EAAE,IAAI,CAAC,aAAa;YACjC,IAAI,EAAE,IAAI,CAAC,aAAa;SACzB,CAAC;QACJ,CAAC,CAAC,EAAE,CAAC;IACP,OAAO;QACL,GAAG,YAAY;QACf,uBAAuB,CAAC,IAAI,CAAC,cAAc,CAAC;QAC5C,uBAAuB,CAAC;YACtB,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,eAAe,EAAE,IAAI,CAAC,eAAe;YACrC,cAAc,EAAE,IAAI,CAAC,cAAc;SACpC,CAAC;QACF,kBAAkB,CAAC,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC;QAC/C,uBAAuB,CAAC;YACtB,UAAU,EAAE,IAAI,CAAC,UAAU;YAC3B,mBAAmB,EAAE,IAAI,CAAC,mBAAmB;YAC7C,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,cAAc,EAAE,IAAI,CAAC,cAAc;SACpC,CAAC;QACF,gBAAgB,CAAC;YACf,cAAc,EAAE,IAAI,CAAC,cAAc;YACnC,eAAe,EAAE,IAAI,CAAC,eAAe;SACtC,CAAC;QACF,kBAAkB,CAAC;YACjB,eAAe,EAAE,IAAI,CAAC,eAAe;YACrC,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,iBAAiB,EAAE,IAAI,CAAC,iBAAiB;SAC1C,CAAC;QACF,kBAAkB,CAAC,EAAE,UAAU,EAAE,IAAI,CAAC,UAAU,EAAE,CAAC;KACpD,CAAC;AACJ,CAAC"}
|
|
1
|
+
{"version":3,"file":"tool-definitions.js","sourceRoot":"","sources":["../../src/mcp/tool-definitions.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,uBAAuB,EAAE,MAAM,6BAA6B,CAAC;AACtE,OAAO,EAAE,uBAAuB,EAAE,MAAM,6BAA6B,CAAC;AACtE,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAE,uBAAuB,EAAE,MAAM,6BAA6B,CAAC;AACtE,OAAO,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AACnE,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAG1D,MAAM,UAAU,oBAAoB,CAClC,IAAqB;IAErB,MAAM,YAAY,GAAG,IAAI,CAAC,cAAc;QACtC,CAAC,CAAC,iBAAiB,CAAC;YAChB,aAAa,EAAE,IAAI,CAAC,aAAa;YACjC,IAAI,EAAE,IAAI,CAAC,aAAa;SACzB,CAAC;QACJ,CAAC,CAAC,EAAE,CAAC;IACP,OAAO;QACL,GAAG,YAAY;QACf,uBAAuB,CAAC,IAAI,CAAC,cAAc,CAAC;QAC5C,uBAAuB,CAAC;YACtB,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,eAAe,EAAE,IAAI,CAAC,eAAe;YACrC,cAAc,EAAE,IAAI,CAAC,cAAc;SACpC,CAAC;QACF,kBAAkB,CAAC,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC;QAC/C,uBAAuB,CAAC;YACtB,UAAU,EAAE,IAAI,CAAC,UAAU;YAC3B,mBAAmB,EAAE,IAAI,CAAC,mBAAmB;YAC7C,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,cAAc,EAAE,IAAI,CAAC,cAAc;SACpC,CAAC;QACF,gBAAgB,CAAC;YACf,cAAc,EAAE,IAAI,CAAC,cAAc;YACnC,eAAe,EAAE,IAAI,CAAC,eAAe;SACtC,CAAC;QACF,sBAAsB,CAAC;YACrB,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,kBAAkB,EAAE,IAAI,CAAC,kBAAkB;SAC5C,CAAC;QACF,kBAAkB,CAAC;YACjB,eAAe,EAAE,IAAI,CAAC,eAAe;YACrC,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,iBAAiB,EAAE,IAAI,CAAC,iBAAiB;SAC1C,CAAC;QACF,kBAAkB,CAAC,EAAE,UAAU,EAAE,IAAI,CAAC,UAAU,EAAE,CAAC;KACpD,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { type BlockPreviewType } from "../../protocol/preview.js";
|
|
3
|
+
export interface PreviewBlocksDeps {
|
|
4
|
+
showPreview: (preview: BlockPreviewType) => void;
|
|
5
|
+
listAttachedImages: () => string[];
|
|
6
|
+
}
|
|
7
|
+
export declare function buildPreviewBlocksTool(deps: PreviewBlocksDeps): import("../define-tool.js").McpToolDefinition<{
|
|
8
|
+
readonly title: z.ZodString;
|
|
9
|
+
readonly description: z.ZodOptional<z.ZodString>;
|
|
10
|
+
readonly label: z.ZodOptional<z.ZodString>;
|
|
11
|
+
readonly tree: z.ZodOptional<z.ZodUnion<readonly [z.ZodObject<{
|
|
12
|
+
type: z.ZodOptional<z.ZodString>;
|
|
13
|
+
componentName: z.ZodOptional<z.ZodString>;
|
|
14
|
+
options: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
15
|
+
id: z.ZodOptional<z.ZodString>;
|
|
16
|
+
slot: z.ZodOptional<z.ZodString>;
|
|
17
|
+
colSpan: z.ZodOptional<z.ZodNumber>;
|
|
18
|
+
children: z.ZodOptional<z.ZodArray<z.ZodObject<any, z.core.$strip>>>;
|
|
19
|
+
}, z.core.$strip>, z.ZodArray<z.ZodObject<{
|
|
20
|
+
type: z.ZodOptional<z.ZodString>;
|
|
21
|
+
componentName: z.ZodOptional<z.ZodString>;
|
|
22
|
+
options: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
23
|
+
id: z.ZodOptional<z.ZodString>;
|
|
24
|
+
slot: z.ZodOptional<z.ZodString>;
|
|
25
|
+
colSpan: z.ZodOptional<z.ZodNumber>;
|
|
26
|
+
children: z.ZodOptional<z.ZodArray<z.ZodObject<any, z.core.$strip>>>;
|
|
27
|
+
}, z.core.$strip>>]>>;
|
|
28
|
+
readonly sketch: z.ZodOptional<z.ZodObject<{
|
|
29
|
+
html: z.ZodString;
|
|
30
|
+
css: z.ZodOptional<z.ZodString>;
|
|
31
|
+
caption: z.ZodOptional<z.ZodString>;
|
|
32
|
+
height: z.ZodOptional<z.ZodNumber>;
|
|
33
|
+
}, z.core.$strip>>;
|
|
34
|
+
readonly reference: z.ZodOptional<z.ZodObject<{
|
|
35
|
+
attachmentId: z.ZodOptional<z.ZodString>;
|
|
36
|
+
url: z.ZodOptional<z.ZodString>;
|
|
37
|
+
caption: z.ZodOptional<z.ZodString>;
|
|
38
|
+
}, z.core.$strip>>;
|
|
39
|
+
readonly variants: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
40
|
+
label: z.ZodString;
|
|
41
|
+
tree: z.ZodOptional<z.ZodUnion<readonly [z.ZodObject<{
|
|
42
|
+
type: z.ZodOptional<z.ZodString>;
|
|
43
|
+
componentName: z.ZodOptional<z.ZodString>;
|
|
44
|
+
options: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
45
|
+
id: z.ZodOptional<z.ZodString>;
|
|
46
|
+
slot: z.ZodOptional<z.ZodString>;
|
|
47
|
+
colSpan: z.ZodOptional<z.ZodNumber>;
|
|
48
|
+
children: z.ZodOptional<z.ZodArray<z.ZodObject<any, z.core.$strip>>>;
|
|
49
|
+
}, z.core.$strip>, z.ZodArray<z.ZodObject<{
|
|
50
|
+
type: z.ZodOptional<z.ZodString>;
|
|
51
|
+
componentName: z.ZodOptional<z.ZodString>;
|
|
52
|
+
options: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
53
|
+
id: z.ZodOptional<z.ZodString>;
|
|
54
|
+
slot: z.ZodOptional<z.ZodString>;
|
|
55
|
+
colSpan: z.ZodOptional<z.ZodNumber>;
|
|
56
|
+
children: z.ZodOptional<z.ZodArray<z.ZodObject<any, z.core.$strip>>>;
|
|
57
|
+
}, z.core.$strip>>]>>;
|
|
58
|
+
sketch: z.ZodOptional<z.ZodObject<{
|
|
59
|
+
html: z.ZodString;
|
|
60
|
+
css: z.ZodOptional<z.ZodString>;
|
|
61
|
+
caption: z.ZodOptional<z.ZodString>;
|
|
62
|
+
height: z.ZodOptional<z.ZodNumber>;
|
|
63
|
+
}, z.core.$strip>>;
|
|
64
|
+
}, z.core.$strip>>>;
|
|
65
|
+
}>;
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import { PREVIEW_BLOCKS_TOOL_DESCRIPTION, PREVIEW_BLOCKS_TOOL_NAME, PREVIEW_ERROR_BYTES, PREVIEW_ERROR_CODES, PREVIEW_ERROR_DEPTH, PREVIEW_ERROR_EMPTY_VIEW, PREVIEW_ERROR_NO_ATTACHMENTS, PREVIEW_ERROR_NO_TYPE, PREVIEW_ERROR_NODES, PREVIEW_ERROR_OPTION_URL, PREVIEW_ERROR_SKETCH, PREVIEW_ERROR_UNKNOWN_ATTACHMENT, PREVIEW_ERROR_URL, PREVIEW_LATEST_ATTACHMENT_ID, PREVIEW_MAX_CAPTION_CHARS, PREVIEW_MAX_DEPTH, PREVIEW_MAX_DESCRIPTION_CHARS, PREVIEW_MAX_JSON_BYTES, PREVIEW_MAX_LABEL_CHARS, PREVIEW_MAX_NODES, PREVIEW_MAX_TITLE_CHARS, PREVIEW_MAX_URL_CHARS, PREVIEW_MAX_VARIANTS, PREVIEW_REMOTE_URL, PREVIEW_RESULT_SHOWN, PREVIEW_SAME_ORIGIN_PATH, PREVIEW_SKETCH_FORBIDDEN, PREVIEW_URL_OPTION_KEY, } from "../../constants/preview.js";
|
|
4
|
+
import { PreviewSketchSchema, PreviewTreeSchema, PreviewVariantSchema, } from "../../protocol/preview.js";
|
|
5
|
+
import { defineTool } from "../define-tool.js";
|
|
6
|
+
const ReferenceInputSchema = z
|
|
7
|
+
.object({
|
|
8
|
+
attachmentId: z
|
|
9
|
+
.string()
|
|
10
|
+
.optional()
|
|
11
|
+
.describe(`File name of an image the user attached in this conversation, or \`${PREVIEW_LATEST_ATTACHMENT_ID}\` for the last one.`),
|
|
12
|
+
url: z
|
|
13
|
+
.string()
|
|
14
|
+
.max(PREVIEW_MAX_URL_CHARS)
|
|
15
|
+
.optional()
|
|
16
|
+
.describe("Same-origin path of an image (e.g. a media URL). An external URL is only shown as a link."),
|
|
17
|
+
caption: z
|
|
18
|
+
.string()
|
|
19
|
+
.max(PREVIEW_MAX_CAPTION_CHARS)
|
|
20
|
+
.optional()
|
|
21
|
+
.describe("What the reference shows, e.g. `Your mockup`."),
|
|
22
|
+
})
|
|
23
|
+
.describe("The user's mockup to show side by side with the blocks.");
|
|
24
|
+
const INPUT_SCHEMA = {
|
|
25
|
+
title: z
|
|
26
|
+
.string()
|
|
27
|
+
.min(1)
|
|
28
|
+
.max(PREVIEW_MAX_TITLE_CHARS)
|
|
29
|
+
.describe("Attachment title, e.g. `Revenue card: DMS KpiCard`."),
|
|
30
|
+
description: z
|
|
31
|
+
.string()
|
|
32
|
+
.max(PREVIEW_MAX_DESCRIPTION_CHARS)
|
|
33
|
+
.optional()
|
|
34
|
+
.describe("What to look at: the visible differences from the mockup."),
|
|
35
|
+
label: z
|
|
36
|
+
.string()
|
|
37
|
+
.min(1)
|
|
38
|
+
.max(PREVIEW_MAX_LABEL_CHARS)
|
|
39
|
+
.optional()
|
|
40
|
+
.describe("Tab label of the main view when there are variants, e.g. `DMS KpiCard`."),
|
|
41
|
+
tree: PreviewTreeSchema.optional(),
|
|
42
|
+
sketch: PreviewSketchSchema.optional(),
|
|
43
|
+
reference: ReferenceInputSchema.optional(),
|
|
44
|
+
variants: z
|
|
45
|
+
.array(PreviewVariantSchema)
|
|
46
|
+
.max(PREVIEW_MAX_VARIANTS)
|
|
47
|
+
.optional()
|
|
48
|
+
.describe("Alternatives shown as tabs after the main view, e.g. the same block with other options, or a custom `sketch`."),
|
|
49
|
+
};
|
|
50
|
+
class PreviewInputError extends Error {
|
|
51
|
+
code;
|
|
52
|
+
constructor(code, message) {
|
|
53
|
+
super(message);
|
|
54
|
+
this.code = code;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
function rootsOf(tree) {
|
|
58
|
+
return Array.isArray(tree) ? tree : [tree];
|
|
59
|
+
}
|
|
60
|
+
function checkOptionUrls(node) {
|
|
61
|
+
const offending = Object.entries(node.options ?? {}).find(([key, value]) => PREVIEW_URL_OPTION_KEY.test(key) &&
|
|
62
|
+
typeof value === "string" &&
|
|
63
|
+
!PREVIEW_SAME_ORIGIN_PATH.test(value));
|
|
64
|
+
if (offending === undefined)
|
|
65
|
+
return;
|
|
66
|
+
throw new PreviewInputError(PREVIEW_ERROR_CODES.INVALID_TREE, `${PREVIEW_ERROR_OPTION_URL}${offending[0]}`);
|
|
67
|
+
}
|
|
68
|
+
function checkNode(node, depth, stats) {
|
|
69
|
+
if (depth > PREVIEW_MAX_DEPTH)
|
|
70
|
+
throw new PreviewInputError(PREVIEW_ERROR_CODES.INVALID_TREE, PREVIEW_ERROR_DEPTH);
|
|
71
|
+
if (node.type === undefined && node.componentName === undefined)
|
|
72
|
+
throw new PreviewInputError(PREVIEW_ERROR_CODES.INVALID_TREE, PREVIEW_ERROR_NO_TYPE);
|
|
73
|
+
checkOptionUrls(node);
|
|
74
|
+
stats.nodes += 1;
|
|
75
|
+
if (stats.nodes > PREVIEW_MAX_NODES)
|
|
76
|
+
throw new PreviewInputError(PREVIEW_ERROR_CODES.TOO_LARGE, PREVIEW_ERROR_NODES);
|
|
77
|
+
for (const child of node.children ?? [])
|
|
78
|
+
checkNode(child, depth + 1, stats);
|
|
79
|
+
}
|
|
80
|
+
function checkSketch(sketch) {
|
|
81
|
+
const markup = `${sketch.html}\n${sketch.css ?? ""}`;
|
|
82
|
+
const refused = PREVIEW_SKETCH_FORBIDDEN.find(([pattern]) => pattern.test(markup));
|
|
83
|
+
if (refused === undefined)
|
|
84
|
+
return;
|
|
85
|
+
throw new PreviewInputError(PREVIEW_ERROR_CODES.INVALID_SKETCH, `${PREVIEW_ERROR_SKETCH}${refused[1]}.`);
|
|
86
|
+
}
|
|
87
|
+
function checkView(view, stats) {
|
|
88
|
+
if (view.tree === undefined && view.sketch === undefined)
|
|
89
|
+
throw new PreviewInputError(PREVIEW_ERROR_CODES.INVALID_TREE, PREVIEW_ERROR_EMPTY_VIEW);
|
|
90
|
+
for (const root of view.tree === undefined ? [] : rootsOf(view.tree))
|
|
91
|
+
checkNode(root, 1, stats);
|
|
92
|
+
if (view.sketch !== undefined)
|
|
93
|
+
checkSketch(view.sketch);
|
|
94
|
+
}
|
|
95
|
+
function checkViews(input) {
|
|
96
|
+
const views = [input, ...(input.variants ?? [])];
|
|
97
|
+
const stats = { nodes: 0 };
|
|
98
|
+
for (const view of views)
|
|
99
|
+
checkView(view, stats);
|
|
100
|
+
const content = views.map(({ tree, sketch }) => ({ tree, sketch }));
|
|
101
|
+
const bytes = Buffer.byteLength(JSON.stringify(content));
|
|
102
|
+
if (bytes > PREVIEW_MAX_JSON_BYTES)
|
|
103
|
+
throw new PreviewInputError(PREVIEW_ERROR_CODES.TOO_LARGE, PREVIEW_ERROR_BYTES);
|
|
104
|
+
}
|
|
105
|
+
function resolveAttachment(requested, attached) {
|
|
106
|
+
if (attached.length === 0)
|
|
107
|
+
throw new PreviewInputError(PREVIEW_ERROR_CODES.UNKNOWN_ATTACHMENT, PREVIEW_ERROR_NO_ATTACHMENTS);
|
|
108
|
+
if (requested === PREVIEW_LATEST_ATTACHMENT_ID)
|
|
109
|
+
return attached.at(-1) ?? requested;
|
|
110
|
+
if (attached.includes(requested))
|
|
111
|
+
return requested;
|
|
112
|
+
throw new PreviewInputError(PREVIEW_ERROR_CODES.UNKNOWN_ATTACHMENT, `${PREVIEW_ERROR_UNKNOWN_ATTACHMENT}${attached.join(", ")}`);
|
|
113
|
+
}
|
|
114
|
+
function checkUrl(url) {
|
|
115
|
+
if (PREVIEW_SAME_ORIGIN_PATH.test(url) || PREVIEW_REMOTE_URL.test(url))
|
|
116
|
+
return url;
|
|
117
|
+
throw new PreviewInputError(PREVIEW_ERROR_CODES.INVALID_URL, PREVIEW_ERROR_URL);
|
|
118
|
+
}
|
|
119
|
+
function resolveReference(reference, attached) {
|
|
120
|
+
if (reference === undefined)
|
|
121
|
+
return undefined;
|
|
122
|
+
const { attachmentId, url, caption } = reference;
|
|
123
|
+
return {
|
|
124
|
+
attachmentName: attachmentId === undefined
|
|
125
|
+
? undefined
|
|
126
|
+
: resolveAttachment(attachmentId, attached()),
|
|
127
|
+
url: url === undefined ? undefined : checkUrl(url),
|
|
128
|
+
caption,
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
function buildPreview(input, deps) {
|
|
132
|
+
checkViews(input);
|
|
133
|
+
return {
|
|
134
|
+
id: randomUUID(),
|
|
135
|
+
title: input.title,
|
|
136
|
+
description: input.description,
|
|
137
|
+
label: input.label,
|
|
138
|
+
tree: input.tree,
|
|
139
|
+
sketch: input.sketch,
|
|
140
|
+
reference: resolveReference(input.reference, deps.listAttachedImages),
|
|
141
|
+
variants: input.variants,
|
|
142
|
+
timestampMs: Date.now(),
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
function jsonContent(payload) {
|
|
146
|
+
return { content: [{ type: "text", text: JSON.stringify(payload) }] };
|
|
147
|
+
}
|
|
148
|
+
function errorContent(error) {
|
|
149
|
+
if (!(error instanceof PreviewInputError))
|
|
150
|
+
throw error;
|
|
151
|
+
return {
|
|
152
|
+
...jsonContent({
|
|
153
|
+
ok: false,
|
|
154
|
+
error: { code: error.code },
|
|
155
|
+
message: error.message,
|
|
156
|
+
}),
|
|
157
|
+
isError: true,
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
export function buildPreviewBlocksTool(deps) {
|
|
161
|
+
return defineTool(PREVIEW_BLOCKS_TOOL_NAME, PREVIEW_BLOCKS_TOOL_DESCRIPTION, INPUT_SCHEMA, async (input) => {
|
|
162
|
+
try {
|
|
163
|
+
const preview = buildPreview(input, deps);
|
|
164
|
+
deps.showPreview(preview);
|
|
165
|
+
return jsonContent({
|
|
166
|
+
ok: true,
|
|
167
|
+
data: { previewId: preview.id },
|
|
168
|
+
message: PREVIEW_RESULT_SHOWN,
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
catch (error) {
|
|
172
|
+
return errorContent(error);
|
|
173
|
+
}
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
//# sourceMappingURL=preview-blocks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"preview-blocks.js","sourceRoot":"","sources":["../../../src/mcp/tools/preview-blocks.ts"],"names":[],"mappings":"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"}
|
|
@@ -6,6 +6,7 @@ import type { LogsClient } from "../logs/logs-client.js";
|
|
|
6
6
|
import type { ImportsScanner } from "../pages/imports-scanner.js";
|
|
7
7
|
import type { RegistryClient } from "../pages/registry-client.js";
|
|
8
8
|
import type { AnyServerEventType } from "../protocol/events.js";
|
|
9
|
+
import type { BlockPreviewType } from "../protocol/preview.js";
|
|
9
10
|
import type { NavigationCompleter } from "../server/navigation-completer.js";
|
|
10
11
|
import type { CurrentPage } from "../state/host-state.js";
|
|
11
12
|
export interface AiMcpServerStaticDeps {
|
|
@@ -24,6 +25,8 @@ export interface AiMcpServerDeps extends AiMcpServerStaticDeps {
|
|
|
24
25
|
sendToHost: (event: AnyServerEventType) => void;
|
|
25
26
|
requestQuestion: (req: QuestionRequest) => Promise<QuestionAnswers>;
|
|
26
27
|
getLastEditedFile: () => string | undefined;
|
|
28
|
+
showPreview: (preview: BlockPreviewType) => void;
|
|
29
|
+
listAttachedImages: () => string[];
|
|
27
30
|
gateBuilderOp?: BuilderGate;
|
|
28
31
|
}
|
|
29
32
|
export interface AiMcpServer {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const SYSTEM_PROMPT_TEMPLATE = "You are the development assistant for an Antelope project.\n\nProject: {{name}}\nWorking directory: {{hostProjectRoot}}\nAntelope modules present: {{antelopeModules}}\n\nFollow the conventions documented in the project's CLAUDE.md.\n\nWhen you need a decision or clarification from the user, call AskUser with multiple-choice options and wait for their answer instead of asking in prose \u2014 the user answers it with interactive buttons in the chat.\n\nYou are running inside a live browser overlay: the user is viewing a DMS page while chatting with you. Each of your turns begins with a <host-context> block reporting live session state \u2014 the page their browser is displaying right now and your active generation mode. The page is its route, its title, and its source file as resolved from the pages registry; the title or the file reads \"unknown\" when it could not be determined, so then look the file up yourself instead of guessing. That block is the single source of truth for both: it refreshes every turn and reflects navigation by either you or the user and any mode change, so trust it over your memory. GetCurrentPage returns the live page on demand. Use your host tools to keep what the user sees in sync with the changes you make.\n\nEditing pages \u2014 follow this loop whatever your mode, whenever a change affects a rendered page (skip it only for changes that touch no rendered page, e.g. backend-only or config edits):\n1. Determine which page(s) the change affects and work ONE page at a time.\n2. Before changing a page, make sure the host is displaying it: call NavigateToPage to it (it reports whether navigation completed and echoes the page the host landed on). Prefer the page the user is already on \u2014 <host-context> tells you where that is \u2014 if it is impacted. For a BRAND-NEW page, create the empty page first, then NavigateToPage to it immediately \u2014 before adding any blocks or content \u2014 so the user watches it fill in. Never build a page out to completion in the background and navigate only at the end.\n3. Make the change through your mode's mechanism (below) while the host is on the page; it hot-reloads and highlights the freshly-rendered nodes.\n4. Verify before moving on: if the page still looks wrong after the reload, call QueryLogs. Then repeat from step 2 for the next impacted page.\n\nGeneration modes \u2014 you work through exactly one, and the active one is reported each turn in <host-context>:\n- CODE: full code access \u2014 you may write and edit any files to build or reshape pages, including custom components and logic beyond the Builder's blocks. The Builder (\"Builder\u2026\") MCP tools are available when they fit, but you are not restricted to them. Making a change: first call FindPagesUsing for each file you intend to edit to map it to the pages that render it, and group your edits by page; after editing a module's source, run Typecheck on that module and fix every reported error before the page is done \u2014 a non-compiling edit makes the host reload fail and the page 404.\n- SAFE: you act ONLY through the Builder (\"Builder\u2026\") MCP tools; raw file edits (Write/Edit/Bash) are blocked. Follow the dms-builder-safe skill, which carries the workflow and the vocabulary; the tools' own descriptions carry their arguments. Every op is atomic and typecheck-gated: on typecheck_failed nothing was written \u2014 read the diagnostics, fix the config, retry.\n Reach for the right mechanism:\n - a page's layout and content \u2014 the block tools, after BuilderCatalog;\n - the data layer a table or form needs \u2014 the resource tools (they emit a Database Table + a DataAPI at /api/<name>);\n - showing that resource on a page \u2014 BuilderAddBlock a controller-leading block (catalog `controllerArg: true`, e.g. TableView) with `controller` set to the resource ref;\n - a computed number rather than rows, e.g. a KpiCard's count or sum \u2014 the DataAPI cannot serve it: add a query (BuilderQueryTemplates, then BuilderAddQuery) and pass the `route` it returns as the card's `fetchUrl`;\n - naming a generated resource class inside config \u2014 a `$ref` value, which is validated and allowed here, never `$expr`.\n The boundary: safe mode cannot construct a nested component value, so a config field the catalog marks `x-component` (a chart card's `chart`, say) is out of reach \u2014 treat it like opaque_target rather than guessing a shape. On opaque_target, unsupported, or an `x-component` field, explain the limitation and ask permission to switch to Code mode for that step; never attempt a raw edit.\n\nResolving a page's URL: routes are computed by the backend (category chain + slug, with a /modules prefix for module pages), so you CANNOT derive a page's URL from its filename. Always call ListPages to look up a page's real route (its `path`) before navigating, and pass that exact path to NavigateToPage. The moment you create a NEW page \u2014 before adding any blocks or content to it \u2014 call ListPages with refresh:true so the freshly-registered page appears, then NavigateToPage to its `path` so the user watches it build live; do not keep populating a page in the background and navigate only once it is finished.\nNever guess or construct a URL.\n";
|
|
1
|
+
export declare const SYSTEM_PROMPT_TEMPLATE = "You are the development assistant for an Antelope project.\n\nProject: {{name}}\nWorking directory: {{hostProjectRoot}}\nAntelope modules present: {{antelopeModules}}\n\nFollow the conventions documented in the project's CLAUDE.md.\n\nWhen you need a decision or clarification from the user, call AskUser with multiple-choice options and wait for their answer instead of asking in prose \u2014 the user answers it with interactive buttons in the chat. When the choice is visual (how a block will look, a DMS block versus a custom one), show the candidates with PreviewBlocks first, then ask.\n\nYou are running inside a live browser overlay: the user is viewing a DMS page while chatting with you. Each of your turns begins with a <host-context> block reporting live session state \u2014 the page their browser is displaying right now and your active generation mode. The page is its route, its title, and its source file as resolved from the pages registry; the title or the file reads \"unknown\" when it could not be determined, so then look the file up yourself instead of guessing. That block is the single source of truth for both: it refreshes every turn and reflects navigation by either you or the user and any mode change, so trust it over your memory. GetCurrentPage returns the live page on demand. Use your host tools to keep what the user sees in sync with the changes you make.\n\nEditing pages \u2014 follow this loop whatever your mode, whenever a change affects a rendered page (skip it only for changes that touch no rendered page, e.g. backend-only or config edits):\n1. Determine which page(s) the change affects and work ONE page at a time. Before you create or change the first page, load the dms-best-practices skill and your mode's skill (dms-ai-code-mode in CODE, dms-builder-safe in SAFE).\n2. Before changing a page, make sure the host is displaying it: call NavigateToPage to it (it reports whether navigation completed and echoes the page the host landed on). Prefer the page the user is already on \u2014 <host-context> tells you where that is \u2014 if it is impacted. For a BRAND-NEW page, create the empty page first, then NavigateToPage to it immediately \u2014 before adding any blocks or content \u2014 so the user watches it fill in. Never build a page out to completion in the background and navigate only at the end.\n3. Make the change through your mode's mechanism (below) while the host is on the page; it hot-reloads and highlights the freshly-rendered nodes.\n4. Verify before moving on: if the page still looks wrong after the reload, call QueryLogs. Then repeat from step 2 for the next impacted page.\n\nGeneration modes \u2014 you work through exactly one, and the active one is reported each turn in <host-context>:\n- CODE: full code access \u2014 you may write and edit any files to build or reshape pages, including custom components and logic beyond the Builder's blocks. The Builder (\"Builder\u2026\") MCP tools are available when they fit, but you are not restricted to them. Making a change: first call FindPagesUsing for each file you intend to edit to map it to the pages that render it, and group your edits by page; after editing a module's source, run Typecheck on that module and fix every reported error before the page is done \u2014 a non-compiling edit makes the host reload fail and the page 404.\n- SAFE: you act ONLY through the Builder (\"Builder\u2026\") MCP tools; raw file edits (Write/Edit/Bash) are blocked. Follow the dms-builder-safe skill, which carries the workflow and the vocabulary; the tools' own descriptions carry their arguments. Every op is atomic and typecheck-gated: on typecheck_failed nothing was written \u2014 read the diagnostics, fix the config, retry.\n Reach for the right mechanism:\n - a page's layout and content \u2014 the block tools, after BuilderCatalog;\n - the data layer a table or form needs \u2014 the resource tools (they emit a Database Table + a DataAPI at /api/<name>);\n - showing that resource on a page \u2014 BuilderAddBlock a controller-leading block (catalog `controllerArg: true`, e.g. TableView) with `controller` set to the resource ref;\n - a computed number rather than rows, e.g. a KpiCard's count or sum \u2014 the DataAPI cannot serve it: add a query (BuilderQueryTemplates, then BuilderAddQuery) and pass the `route` it returns as the card's `fetchUrl`;\n - naming a generated resource class inside config \u2014 a `$ref` value, which is validated and allowed here, never `$expr`.\n The boundary: safe mode cannot construct a nested component value, so a config field the catalog marks `x-component` (a chart card's `chart`, say) is out of reach \u2014 treat it like opaque_target rather than guessing a shape. On opaque_target, unsupported, or an `x-component` field, explain the limitation and ask permission to switch to Code mode for that step; never attempt a raw edit.\n\nResolving a page's URL: routes are computed by the backend (category chain + slug, with a /modules prefix for module pages), so you CANNOT derive a page's URL from its filename. Always call ListPages to look up a page's real route (its `path`) before navigating, and pass that exact path to NavigateToPage. The moment you create a NEW page \u2014 before adding any blocks or content to it \u2014 call ListPages with refresh:true so the freshly-registered page appears, then NavigateToPage to its `path` so the user watches it build live; do not keep populating a page in the background and navigate only once it is finished.\nNever guess or construct a URL.\n";
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { HOST_CONTEXT_OPEN, SYSTEM_PROMPT_TOKEN_HOST_ROOT, SYSTEM_PROMPT_TOKEN_MODULES, SYSTEM_PROMPT_TOKEN_NAME, } from "../constants/agent.js";
|
|
2
2
|
import { QUERY_LOGS_TOOL_NAME } from "../constants/logs.js";
|
|
3
3
|
import { ASK_USER_TOOL_NAME, GET_CURRENT_PAGE_TOOL_NAME, NAVIGATE_TOOL_NAME, } from "../constants/mcp.js";
|
|
4
|
+
import { PREVIEW_BLOCKS_TOOL_NAME } from "../constants/preview.js";
|
|
4
5
|
import { FIND_PAGES_TOOL_NAME, LIST_PAGES_TOOL_NAME, } from "../constants/pages.js";
|
|
5
6
|
import { TYPECHECK_TOOL_NAME } from "../constants/typecheck.js";
|
|
6
7
|
const CODE_MODE_DESCRIPTION = `full code access — you may write and edit any files to build or reshape pages, including custom components and logic beyond the Builder's blocks. The Builder ("Builder…") MCP tools are available when they fit, but you are not restricted to them. Making a change: first call ${FIND_PAGES_TOOL_NAME} for each file you intend to edit to map it to the pages that render it, and group your edits by page; after editing a module's source, run ${TYPECHECK_TOOL_NAME} on that module and fix every reported error before the page is done — a non-compiling edit makes the host reload fail and the page 404.`;
|
|
@@ -20,12 +21,12 @@ Antelope modules present: ${SYSTEM_PROMPT_TOKEN_MODULES}
|
|
|
20
21
|
|
|
21
22
|
Follow the conventions documented in the project's CLAUDE.md.
|
|
22
23
|
|
|
23
|
-
When you need a decision or clarification from the user, call ${ASK_USER_TOOL_NAME} with multiple-choice options and wait for their answer instead of asking in prose — the user answers it with interactive buttons in the chat.
|
|
24
|
+
When you need a decision or clarification from the user, call ${ASK_USER_TOOL_NAME} with multiple-choice options and wait for their answer instead of asking in prose — the user answers it with interactive buttons in the chat. When the choice is visual (how a block will look, a DMS block versus a custom one), show the candidates with ${PREVIEW_BLOCKS_TOOL_NAME} first, then ask.
|
|
24
25
|
|
|
25
26
|
You are running inside a live browser overlay: the user is viewing a DMS page while chatting with you. Each of your turns begins with a ${HOST_CONTEXT_OPEN} block reporting live session state — the page their browser is displaying right now and your active generation mode. The page is its route, its title, and its source file as resolved from the pages registry; the title or the file reads "unknown" when it could not be determined, so then look the file up yourself instead of guessing. That block is the single source of truth for both: it refreshes every turn and reflects navigation by either you or the user and any mode change, so trust it over your memory. ${GET_CURRENT_PAGE_TOOL_NAME} returns the live page on demand. Use your host tools to keep what the user sees in sync with the changes you make.
|
|
26
27
|
|
|
27
28
|
Editing pages — follow this loop whatever your mode, whenever a change affects a rendered page (skip it only for changes that touch no rendered page, e.g. backend-only or config edits):
|
|
28
|
-
1. Determine which page(s) the change affects and work ONE page at a time.
|
|
29
|
+
1. Determine which page(s) the change affects and work ONE page at a time. Before you create or change the first page, load the dms-best-practices skill and your mode's skill (dms-ai-code-mode in CODE, dms-builder-safe in SAFE).
|
|
29
30
|
2. Before changing a page, make sure the host is displaying it: call ${NAVIGATE_TOOL_NAME} to it (it reports whether navigation completed and echoes the page the host landed on). Prefer the page the user is already on — ${HOST_CONTEXT_OPEN} tells you where that is — if it is impacted. For a BRAND-NEW page, create the empty page first, then ${NAVIGATE_TOOL_NAME} to it immediately — before adding any blocks or content — so the user watches it fill in. Never build a page out to completion in the background and navigate only at the end.
|
|
30
31
|
3. Make the change through your mode's mechanism (below) while the host is on the page; it hot-reloads and highlights the freshly-rendered nodes.
|
|
31
32
|
4. Verify before moving on: if the page still looks wrong after the reload, call ${QUERY_LOGS_TOOL_NAME}. Then repeat from step 2 for the next impacted page.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent.js","sourceRoot":"","sources":["../../src/prompts/agent.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,EACjB,6BAA6B,EAC7B,2BAA2B,EAC3B,wBAAwB,GACzB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EACL,kBAAkB,EAClB,0BAA0B,EAC1B,kBAAkB,GACnB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,oBAAoB,EACpB,oBAAoB,GACrB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAgBhE,MAAM,qBAAqB,GAAG,qRAAqR,oBAAoB,+IAA+I,mBAAmB,0IAA0I,CAAC;AAEpnB,MAAM,qBAAqB,GAAG;;;;;;;2YAO6W,CAAC;AAE5Y,MAAM,CAAC,MAAM,sBAAsB,GAAG;;WAE3B,wBAAwB;qBACd,6BAA6B;4BACtB,2BAA2B;;;;gEAIS,kBAAkB;;
|
|
1
|
+
{"version":3,"file":"agent.js","sourceRoot":"","sources":["../../src/prompts/agent.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,EACjB,6BAA6B,EAC7B,2BAA2B,EAC3B,wBAAwB,GACzB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EACL,kBAAkB,EAClB,0BAA0B,EAC1B,kBAAkB,GACnB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AACnE,OAAO,EACL,oBAAoB,EACpB,oBAAoB,GACrB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAgBhE,MAAM,qBAAqB,GAAG,qRAAqR,oBAAoB,+IAA+I,mBAAmB,0IAA0I,CAAC;AAEpnB,MAAM,qBAAqB,GAAG;;;;;;;2YAO6W,CAAC;AAE5Y,MAAM,CAAC,MAAM,sBAAsB,GAAG;;WAE3B,wBAAwB;qBACd,6BAA6B;4BACtB,2BAA2B;;;;gEAIS,kBAAkB,+PAA+P,wBAAwB;;0IAE/N,iBAAiB,kgBAAkgB,0BAA0B;;;;uEAIhnB,kBAAkB,qIAAqI,iBAAiB,yGAAyG,kBAAkB;;mFAEvR,oBAAoB;;+FAER,iBAAiB;UACtG,qBAAqB;UACrB,qBAAqB;;gMAEiK,oBAAoB,iGAAiG,kBAAkB,yFAAyF,oBAAoB,mEAAmE,kBAAkB;;CAExgB,CAAC"}
|