From 3c8d35bf7fd7e82a6cd0292720f431e4f92bead7 Mon Sep 17 00:00:00 2001 From: Lily Shen <115414357+lilyshen0722@users.noreply.github.com> Date: Sun, 25 Oct 2026 01:43:26 -0700 Subject: [PATCH 01/13] feat: validate agent-authored UI card payloads at write Co-authored-by: tern Agent-Model: codex/gpt-6.1-sol/medium --- backend/Dockerfile | 3 + .../agentsRuntime.post-message.config.test.js | 36 ++++++ ...MessageService.threadRootBroadcast.test.js | 34 ++++++ .../unit/services/uiCardValidation.test.js | 64 ++++++++++ backend/config/uiCardCatalogue.json | 10 ++ backend/package-lock.json | 50 ++++++++ backend/package.json | 1 + backend/routes/agentsRuntime.ts | 12 +- backend/services/uiCardValidation.ts | 115 ++++++++++++++++++ cli/__tests__/pod-send.test.mjs | 47 +++++++ cli/src/commands/pod.js | 19 ++- commonly-mcp/__tests__/tools.test.mjs | 9 ++ commonly-mcp/src/tools.js | 6 +- docs/api/agent-ui-cards.md | 62 ++++++++++ 14 files changed, 458 insertions(+), 10 deletions(-) create mode 100644 backend/__tests__/unit/services/uiCardValidation.test.js create mode 100644 backend/config/uiCardCatalogue.json create mode 100644 backend/services/uiCardValidation.ts create mode 100644 cli/__tests__/pod-send.test.mjs create mode 100644 docs/api/agent-ui-cards.md diff --git a/backend/Dockerfile b/backend/Dockerfile index 37f76c0536..917cffff65 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -49,6 +49,9 @@ RUN apt-get update && apt-get install -y --no-install-recommends curl ca-certifi officecli --version && \ apt-get clean && rm -rf /var/lib/apt/lists/* +# Parse stored agent cards locally; never send install/runtime telemetry. +ENV OPENUI_TELEMETRY_DISABLED=1 + COPY package*.json ./ # Install all dependencies including dev dependencies diff --git a/backend/__tests__/unit/routes/agentsRuntime.post-message.config.test.js b/backend/__tests__/unit/routes/agentsRuntime.post-message.config.test.js index f249dc9028..b3c722624a 100644 --- a/backend/__tests__/unit/routes/agentsRuntime.post-message.config.test.js +++ b/backend/__tests__/unit/routes/agentsRuntime.post-message.config.test.js @@ -218,6 +218,42 @@ describe('agentsRuntime post message installation config forwarding', () => { }); }); +describe('agent card route boundary', () => { + const installation = { podId: 'pod-1', agentName: 'openclaw', instanceId: 'default', config: {} }; + const payload = { kind: 'ui', v: 1, lang: 'openui@1', source: 'root = Text("hello")' }; + const handler = getRouteHandler('/pods/:podId/messages', 'post'); + const req = (body) => ({ params: { podId: 'pod-1' }, body: { continueAnyway: true, ...body }, + agentInstallation: installation, agentInstallations: [installation] }); + const response = () => ({ status: jest.fn().mockReturnThis(), json: jest.fn() }); + beforeEach(() => { jest.clearAllMocks(); findNonMemberMentionNotices.mockResolvedValue([]); }); + it('forwards a validated UI payload unchanged to the durable message writer', async () => { + AgentMessageService.postMessage.mockResolvedValue({ success: true }); + const res = response(); + await handler(req({ messageType: 'card', payload, content: 'fallback' }), res); + expect(AgentMessageService.postMessage).toHaveBeenCalledWith(expect.objectContaining({ + messageType: 'card', payload, content: 'fallback', + })); + expect(res.status).not.toHaveBeenCalled(); + }); + it.each([ + { ...payload, kind: 'approval' }, + { ...payload, source: 'root = Text("hello")\nq = Query("secret", {})' }, + { ...payload, source: 'root = Unknown("hello")' }, + ])('refuses unsafe cards before persistence or mention fan-out %#', async (badPayload) => { + const res = response(); + await handler(req({ messageType: 'card', payload: badPayload, content: 'fallback' }), res); + expect(res.status).toHaveBeenCalledWith(400); + expect(AgentMessageService.postMessage).not.toHaveBeenCalled(); + expect(findNonMemberMentionNotices).not.toHaveBeenCalled(); + }); + it('keeps the pod authorization check ahead of parsing', async () => { + const res = response(); + await handler({ ...req({ payload }), params: { podId: 'other' } }, res); + expect(res.status).toHaveBeenCalledWith(403); + expect(AgentMessageService.postMessage).not.toHaveBeenCalled(); + }); +}); + describe('bot-token send-time freshness', () => { const user = { _id: 'bot-1', username: 'openclaw', isBot: true, diff --git a/backend/__tests__/unit/services/agentMessageService.threadRootBroadcast.test.js b/backend/__tests__/unit/services/agentMessageService.threadRootBroadcast.test.js index 9e77c8d5ce..585e8d0174 100644 --- a/backend/__tests__/unit/services/agentMessageService.threadRootBroadcast.test.js +++ b/backend/__tests__/unit/services/agentMessageService.threadRootBroadcast.test.js @@ -207,3 +207,37 @@ describe('agent broadcast carries author identity', () => { })); }); }); + + +describe('agent UI card payload persistence and live delivery', () => { + const payload = { kind: 'ui', v: 1, lang: 'openui@1', source: 'root = Text("hello")' }; + it('passes the envelope to PostgreSQL and preserves it in result and socket', async () => { + PGMessage.create.mockResolvedValue(pgRow({ payload, content: 'UI text fallback', message_type: 'card', thread_root_id: null })); + const result = await AgentMessageService.postMessage({ + agentName: 'sprint-review', podId: POD, content: 'UI text fallback', messageType: 'card', payload, + }); + expect(PGMessage.create).toHaveBeenCalledWith( + POD, 'agent-user-1', 'UI text fallback', 'card', null, payload, null, undefined, + ); + expect(Message).not.toHaveBeenCalled(); + expect(result.message.payload).toEqual(payload); + expect(emitted.find((e) => e.event === 'newMessage').payload).toEqual(expect.objectContaining({ + messageType: 'card', payload, content: 'UI text fallback', + })); + }); + it('preserves the same envelope in Mongo fallback and live delivery', async () => { + delete process.env.PG_HOST; + const save = jest.fn().mockResolvedValue(undefined); + Message.mockImplementation((data) => ({ + ...data, _id: 'mongo-card-1', createdAt: new Date(), save, + populate: jest.fn().mockResolvedValue(undefined), + })); + const result = await AgentMessageService.postMessage({ + agentName: 'sprint-review', podId: POD, content: 'UI text fallback', messageType: 'card', payload, + }); + expect(Message).toHaveBeenCalledWith(expect.objectContaining({ messageType: 'card', payload })); + expect(save).toHaveBeenCalledTimes(1); + expect(result.message.payload).toEqual(payload); + expect(emitted.find((e) => e.event === 'newMessage').payload.payload).toEqual(payload); + }); +}); diff --git a/backend/__tests__/unit/services/uiCardValidation.test.js b/backend/__tests__/unit/services/uiCardValidation.test.js new file mode 100644 index 0000000000..27cb541c19 --- /dev/null +++ b/backend/__tests__/unit/services/uiCardValidation.test.js @@ -0,0 +1,64 @@ +const { validateAgentCardPayload, UI_CARD_MAX_BYTES } = require('../../../services/uiCardValidation'); + +const card = (source = 'root = Text("hello")') => ({ kind: 'ui', v: 1, lang: 'openui@1', source }); +const validate = (payload = card(), content = 'Text fallback', type = 'card') => ( + validateAgentCardPayload(type, payload, content) +); + +describe('untrusted UI card write validation', () => { + it('keeps ordinary text backwards compatible', () => { + expect(() => validateAgentCardPayload(undefined, undefined, 'hello')).not.toThrow(); + }); + it('accepts a complete known component without evaluating it', () => { + expect(() => validate()).not.toThrow(); + expect(() => validate(card('root = Text("Query Mutation @Run are just quoted text")'))).not.toThrow(); + }); + it.each([ + null, [], {}, { ...card(), kind: 'approval' }, { ...card(), kind: 'decision' }, + { ...card(), v: 2 }, { ...card(), lang: 'openui@2' }, + { ...card(), source: 5 }, { ...card(), source: '' }, + { ...card(), tools: { secret: 'no' } }, { ...card(), runId: 'forged' }, + ])('refuses an unsupported or privileged envelope %#', (payload) => { + expect(() => validate(payload)).toThrow(expect.objectContaining({ statusCode: 400, code: 'invalid_ui_card' })); + }); + it.each([undefined, null, '', ' ', 42])('requires a text fallback (%s)', (content) => { + expect(() => validateAgentCardPayload('card', card(), content)).toThrow(); + }); + it('requires the explicit card type and a card payload', () => { + expect(() => validate(card(), 'fallback', 'text')).toThrow(); + expect(() => validateAgentCardPayload('card', undefined, 'fallback')).toThrow(); + }); + it.each([ + 'root = Unknown("hello")', + 'root = Text("hello")\nunused = Unknown("hello")', + 'root = Query("tool", {})', + 'root = Text("hello")\nunused = Query("tool", {})', + 'root = Text("hello")\nunused = Mutation("tool", {})', + 'root = Text(Action(@Run(q)))', + 'root = Text("hello")\nunused = Action(@Run(q))', + 'root = Text("hello") Query("tool", {})', + 'root = Text("hello") Unknown("hidden")', + 'root = Text(@Fetch("https://example.org"))', + '$state = "x"\nroot = Text($state)', + 'root = Text("hello"', + 'root = Text(missing)', + 'root = Text("hi")\nroot = Text("replacement")', + 'root = Text({__proto__: {polluted: true}})', + 'no root here', + ])('refuses unsafe, unknown, or incomplete source: %s', (source) => { + expect(() => validate(card(source))).toThrow(expect.objectContaining({ statusCode: 400 })); + }); + it('refuses deeply nested input before recursive parsing', () => { + expect(() => validate(card('root = Text(' + '['.repeat(1000) + '0' + ']'.repeat(1000) + ')'))).toThrow('nesting'); + }); + it('limits serialized payload bytes, including multibyte Unicode and exact boundary', () => { + const prefix = 'root = Text("'; + const suffix = '")'; + const overhead = Buffer.byteLength(JSON.stringify(card(prefix + suffix))); + const exact = card(prefix + 'a'.repeat(UI_CARD_MAX_BYTES - overhead) + suffix); + expect(Buffer.byteLength(JSON.stringify(exact))).toBe(UI_CARD_MAX_BYTES); + expect(() => validate(exact)).not.toThrow(); + expect(() => validate({ ...exact, source: exact.source + ' ' })).toThrow('32 KB'); + expect(() => validate(card(prefix + '界'.repeat(12000) + suffix))).toThrow('32 KB'); + }); +}); diff --git a/backend/config/uiCardCatalogue.json b/backend/config/uiCardCatalogue.json new file mode 100644 index 0000000000..12a014c860 --- /dev/null +++ b/backend/config/uiCardCatalogue.json @@ -0,0 +1,10 @@ +{ + "$defs": { + "Text": { + "type": "object", + "properties": { "text": { "type": "string" } }, + "required": ["text"] + } + }, + "properties": { "Text": { "$ref": "#/$defs/Text" } } +} diff --git a/backend/package-lock.json b/backend/package-lock.json index f8579f2887..e0a33812f8 100644 --- a/backend/package-lock.json +++ b/backend/package-lock.json @@ -14,6 +14,7 @@ "@google/generative-ai": "^0.2.1", "@kubernetes/client-node": "^0.21.0", "@modelcontextprotocol/sdk": "^1.30.0", + "@openuidev/lang-core": "1.0.1", "@sendgrid/mail": "^7.7.0", "@sentry/node": "^10.65.0", "@socket.io/redis-adapter": "^8.3.0", @@ -2318,6 +2319,40 @@ "node": ">=14" } }, + "node_modules/@openuidev/lang-core": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@openuidev/lang-core/-/lang-core-1.0.1.tgz", + "integrity": "sha512-4vBa7FRM6C4v4aCvBAmAtTgFWiEQiNTazG9h4Xy9fC6P/p6+9kZu4RdTyLToBEvdxrYn/gDy/PakEH8PU3lUcw==", + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "ci-info": "^4.4.0" + }, + "peerDependencies": { + "@modelcontextprotocol/sdk": ">=1.0.0", + "zod": "^3.25.0 || ^4.0.0" + }, + "peerDependenciesMeta": { + "@modelcontextprotocol/sdk": { + "optional": true + } + } + }, + "node_modules/@openuidev/lang-core/node_modules/ci-info": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.4.0.tgz", + "integrity": "sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/@pkgjs/parseargs": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", @@ -14866,6 +14901,21 @@ "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.43.0.tgz", "integrity": "sha512-eSYWTm620tTk45EKSedaUL8MFYI8hW164hIXsgIHyxu3VobUB3fFCu5t0hQby6OoWRPsG1KkKUG2M5UadiLiVg==" }, + "@openuidev/lang-core": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@openuidev/lang-core/-/lang-core-1.0.1.tgz", + "integrity": "sha512-4vBa7FRM6C4v4aCvBAmAtTgFWiEQiNTazG9h4Xy9fC6P/p6+9kZu4RdTyLToBEvdxrYn/gDy/PakEH8PU3lUcw==", + "requires": { + "ci-info": "^4.4.0" + }, + "dependencies": { + "ci-info": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.4.0.tgz", + "integrity": "sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg==" + } + } + }, "@pkgjs/parseargs": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", diff --git a/backend/package.json b/backend/package.json index 84e0f900cb..e2f772e088 100644 --- a/backend/package.json +++ b/backend/package.json @@ -41,6 +41,7 @@ "@google/generative-ai": "^0.2.1", "@kubernetes/client-node": "^0.21.0", "@modelcontextprotocol/sdk": "^1.30.0", + "@openuidev/lang-core": "1.0.1", "@sendgrid/mail": "^7.7.0", "@sentry/node": "^10.65.0", "@socket.io/redis-adapter": "^8.3.0", diff --git a/backend/routes/agentsRuntime.ts b/backend/routes/agentsRuntime.ts index 446f1b4df4..129a7c8151 100644 --- a/backend/routes/agentsRuntime.ts +++ b/backend/routes/agentsRuntime.ts @@ -1,3 +1,4 @@ +import { validateAgentCardPayload } from '../services/uiCardValidation'; export {}; // TASK-099: the refusal classes a driver may name on release. The enum is the @@ -1572,7 +1573,9 @@ router.post( return res.status(403).json({ message: 'Bot not installed in this pod' }); } - const { content, metadata, messageType } = req.body || {}; + const { content, metadata, messageType, payload } = req.body || {}; + validateAgentCardPayload(messageType, payload, payload !== undefined + ? AgentMessageService.sanitizeAgentContent(content) : content); const wouldPost = messageType === 'card' || Boolean(AgentMessageService.sanitizeAgentContent(content)); if (wouldPost && req.body?.continueAnyway !== true) { const hold = await AgentSendFreshness.unseenMessages(user._id, podId); @@ -1586,6 +1589,7 @@ router.post( content, metadata, messageType, + ...(payload !== undefined ? { payload } : {}), installationConfig: installation.config || null, }); @@ -2263,6 +2267,9 @@ router.post('/pods/:podId/messages', phase4RateLimit, agentRuntimeAuth, async (r return res.status(403).json({ message: 'Agent token not authorized for this pod' }); } + validateAgentCardPayload(req.body?.messageType, req.body?.payload, req.body?.payload !== undefined + ? AgentMessageService.sanitizeAgentContent(req.body?.content) : req.body?.content); + // A total-match silence or runtime artifact is not a post. Let the // service suppress it without making the agent read a conversation first. const wouldPost = req.body?.messageType === 'card' @@ -2277,7 +2284,7 @@ router.post('/pods/:podId/messages', phase4RateLimit, agentRuntimeAuth, async (r } const { - content, metadata, messageType, replyToMessageId, threadRootId, + content, metadata, messageType, replyToMessageId, threadRootId, payload, } = req.body || {}; const result = await AgentMessageService.postMessage({ agentName: installation.agentName, @@ -2287,6 +2294,7 @@ router.post('/pods/:podId/messages', phase4RateLimit, agentRuntimeAuth, async (r content, metadata, messageType, + ...(payload !== undefined ? { payload } : {}), replyToMessageId: replyToMessageId || null, // In-thread post WITHOUT addressing (constraint 5, Sam's independence // rule): the thread is ambient membership, the reply edge is a ping. diff --git a/backend/services/uiCardValidation.ts b/backend/services/uiCardValidation.ts new file mode 100644 index 0000000000..32ffc542cd --- /dev/null +++ b/backend/services/uiCardValidation.ts @@ -0,0 +1,115 @@ +import { + createParser, parseExpression, split, tokenize, walkAST, +} from '@openuidev/lang-core'; +import type { LibraryJSONSchema } from '@openuidev/lang-core'; +import catalogue from '../config/uiCardCatalogue.json'; + +export const UI_CARD_MAX_BYTES = 32 * 1024; +const schema = catalogue as LibraryJSONSchema; +const parser = createParser(schema); +const componentNames = new Set(Object.keys(schema.properties || {})); +const bracketTokens = tokenize('()[]{}'); +const closingTokens = new Map([ + [bracketTokens[0].t, bracketTokens[1].t], + [bracketTokens[2].t, bracketTokens[3].t], + [bracketTokens[4].t, bracketTokens[5].t], +]); +const openParenToken = bracketTokens[0].t; +const allowedCall = (name: string) => componentNames.has(name) || ['Action', 'OpenUrl'].includes(name); + +export class UICardValidationError extends Error { + readonly statusCode = 400; + + readonly code = 'invalid_ui_card'; +} + +function refuse(message: string): never { + throw new UICardValidationError(message); +} + +/** Validate untrusted CAP input, never privileged kernel-composed payloads. */ +export function validateAgentCardPayload( + messageType: unknown, + payload: unknown, + content: unknown, +): void { + if (payload === undefined && messageType !== 'card') return; + if (messageType !== 'card') refuse('UI payload requires messageType card'); + if (typeof content !== 'string' || !content.trim()) refuse('UI card requires a content text fallback'); + if (!payload || typeof payload !== 'object' || Array.isArray(payload)) refuse('UI card payload must be an object'); + const envelope = payload as Record; + if (envelope.kind !== 'ui' || envelope.v !== 1 || envelope.lang !== 'openui@1' + || typeof envelope.source !== 'string' || !envelope.source.trim() + || Object.keys(envelope).some((key) => !['kind', 'v', 'lang', 'source'].includes(key))) { + refuse('Expected {kind:"ui",v:1,lang:"openui@1",source}'); + } + if (Buffer.byteLength(JSON.stringify(payload), 'utf8') > UI_CARD_MAX_BYTES) { + refuse('UI card payload exceeds 32 KB'); + } + try { + const source = envelope.source as string; + // The streaming parser intentionally repairs incomplete input. Stored cards + // must be complete. Inspect ALL statements, including unreachable ones: + // materializing only root misses a dormant Query or an unknown component. + const tokens = tokenize(source); + // Also inspect tokens that the forgiving parser would discard after an + // expression. Quoted prose has string tokens and is never treated as code. + const brackets: number[] = []; + tokens.forEach((token, index) => { + const closing = closingTokens.get(token.t); + if (closing !== undefined) { + brackets.push(closing); + if (brackets.length > 64) refuse('UI card exceeds 64 nesting levels'); + } else if ([...closingTokens.values()].includes(token.t) && brackets.pop() !== token.t) { + refuse('UI card contains unmatched brackets'); + } + if (typeof token.v === 'string' && tokens[index + 1]?.t === openParenToken + && parseExpression([token]).k !== 'Str' && !allowedCall(token.v)) { + refuse(`UI card call is not allowed: ${token.v}`); + } + }); + if (brackets.length) refuse('UI card contains unmatched brackets'); + const statements = split(tokens); + if (statements.length > 256) refuse('UI card exceeds 256 statements'); + const ids = new Set(); + statements.forEach((statement) => { + if (ids.has(statement.id) || statement.id.startsWith('$')) { + refuse('UI card contains duplicate or reactive statements'); + } + ids.add(statement.id); + walkAST(parseExpression(statement.tokens), (node) => { + if (node.k === 'Comp') { + if (!allowedCall(node.name)) { + refuse(`UI card call is not allowed: ${node.name}`); + } + if (node.fn) refuse('UI card functions are not allowed'); + if (node.name === 'OpenUrl') { + const [url] = node.args; + if (node.args.length !== 1 || url?.k !== 'Str') refuse('OpenUrl requires a literal https URL'); + const parsed = new URL(url.v); + if (parsed.protocol !== 'https:' || parsed.username || parsed.password) { + refuse('OpenUrl requires a literal https URL'); + } + } + } else if (node.k === 'Ref' && ['Query', 'Mutation', 'Run'].includes(node.n)) { + refuse(`UI card capability is not allowed: ${node.n}`); + } else if (node.k === 'Obj') { + if (node.entries.some(([key]) => ['__proto__', 'prototype', 'constructor'].includes(key))) { + refuse('UI card prototype keys are not allowed'); + } + } else if (!['Str', 'Num', 'Bool', 'Null', 'Arr', 'Ref'].includes(node.k)) { + refuse('UI card reactive expressions are not allowed'); + } + }); + }); + const result = parser.parse(source); + if (!result.root || result.meta.incomplete || result.meta.unresolved.length + || result.meta.errors.length || result.queryStatements.length || result.mutationStatements.length + || Object.keys(result.stateDeclarations).length) { + refuse('UI card source is incomplete or invalid for the Commonly catalogue'); + } + } catch (error) { + if (error instanceof UICardValidationError) throw error; + refuse('UI card source could not be parsed'); + } +} diff --git a/cli/__tests__/pod-send.test.mjs b/cli/__tests__/pod-send.test.mjs new file mode 100644 index 0000000000..599234a31b --- /dev/null +++ b/cli/__tests__/pod-send.test.mjs @@ -0,0 +1,47 @@ +import { jest } from '@jest/globals'; +import { Command } from 'commander'; + +const post = jest.fn(); +await jest.unstable_mockModule('../src/lib/api.js', () => ({ createClient: () => ({ post }) })); +await jest.unstable_mockModule('../src/lib/config.js', () => ({ + getToken: () => 'own-runtime-fixture', resolveInstanceUrl: () => 'https://api.example.org', +})); +const { registerPod } = await import('../src/commands/pod.js'); +const run = async (...args) => { + const program = new Command(); + registerPod(program); + await program.parseAsync(['node', 'commonly', 'pod', 'send', 'pod-1', 'text fallback', ...args]); +}; +beforeEach(() => { + post.mockReset().mockResolvedValue({ id: 'm1' }); + jest.spyOn(console, 'log').mockImplementation(() => {}); + jest.spyOn(console, 'error').mockImplementation(() => {}); + jest.spyOn(process, 'exit').mockImplementation(() => {}); +}); +afterEach(() => jest.restoreAllMocks()); + +test('sends UI JSON on the real pod command with the content fallback', async () => { + const payload = { kind: 'ui', v: 1, lang: 'openui@1', source: 'root = Text("hi")' }; + await run('--payload', JSON.stringify(payload)); + expect(post).toHaveBeenCalledTimes(1); + expect(post).toHaveBeenCalledWith('/api/agents/runtime/pods/pod-1/messages', { + content: 'text fallback', messageType: 'card', payload, + }); +}); +test.each([400, 401, 403, 409, 500])('never retries a card refusal (%s) through the human writer', async (status) => { + post.mockRejectedValueOnce(Object.assign(new Error('refused'), { status })); + await run('--payload', '{"kind":"approval"}'); + expect(post).toHaveBeenCalledTimes(1); + expect(process.exit).toHaveBeenCalledWith(1); +}); +test('malformed JSON sends no requests', async () => { + await run('--payload', '{broken'); + expect(post).not.toHaveBeenCalled(); + expect(process.exit).toHaveBeenCalledWith(1); +}); +test('ordinary text retains the existing login fallback', async () => { + post.mockRejectedValueOnce(new Error('agent auth required')); + await run(); + expect(post).toHaveBeenCalledTimes(2); + expect(post).toHaveBeenLastCalledWith('/api/messages/pod-1', { content: 'text fallback' }); +}); diff --git a/cli/src/commands/pod.js b/cli/src/commands/pod.js index 064c7c1923..1716812254 100644 --- a/cli/src/commands/pod.js +++ b/cli/src/commands/pod.js @@ -55,6 +55,7 @@ Commonly instance (see: commonly login --help). pod .command('send ') .description('Post a message to a pod') + .option('--payload ', 'UI card JSON envelope; the message remains the required text fallback') .option('--instance ', 'Target Commonly instance') .action(async (podId, message, opts) => { const token = getToken(opts.instance); @@ -63,12 +64,18 @@ Commonly instance (see: commonly login --help). const client = createClient({ instance: resolveInstanceUrl(opts.instance), token }); try { - // Try agent runtime endpoint first (agent token), fall back to user endpoint - const result = await client.post(`/api/agents/runtime/pods/${podId}/messages`, { - content: message, - }).catch(() => client.post(`/api/messages/${podId}`, { - content: message, - })); + const body = { content: message }; + if (opts.payload !== undefined) { + body.payload = JSON.parse(opts.payload); + body.messageType = 'card'; + } + // UI cards use the validated agent endpoint only. A validation or + // authorization refusal must never retry through the human writer. + const result = await client.post(`/api/agents/runtime/pods/${podId}/messages`, body) + .catch((error) => { + if (opts.payload !== undefined) throw error; + return client.post(`/api/messages/${podId}`, body); + }); console.log(`Sent (${result._id || result.id || 'ok'})`); } catch (err) { diff --git a/commonly-mcp/__tests__/tools.test.mjs b/commonly-mcp/__tests__/tools.test.mjs index ff5c63cc13..03d2caf739 100644 --- a/commonly-mcp/__tests__/tools.test.mjs +++ b/commonly-mcp/__tests__/tools.test.mjs @@ -74,6 +74,15 @@ const okResponse = (body) => ({ afterEach(() => { delete global.fetch; }); describe('commonly_post_message', () => { + it('forwards UI card payload and explicit type alongside the text fallback', async () => { + const fetchSpy = installFetch(async () => okResponse({ id: 'card1' })); + const payload = { kind: 'ui', v: 1, lang: 'openui@1', source: 'root = Text("hello")' }; + await byName.commonly_post_message.call({ podId: 'p', content: 'fallback', messageType: 'card', payload }); + expect(JSON.parse(fetchSpy.mock.calls[0][1].body)).toEqual({ content: 'fallback', messageType: 'card', payload }); + expect(byName.commonly_post_message.inputSchema.properties.messageType.enum).toContain('card'); + expect(byName.commonly_post_message.inputSchema.properties.payload.type).toBe('object'); + }); + it('POSTs to the right path with body', async () => { const fetchSpy = installFetch(async () => okResponse({ id: 'm1' })); const result = await byName.commonly_post_message.call({ diff --git a/commonly-mcp/src/tools.js b/commonly-mcp/src/tools.js index 04ec963b2c..e9a743f8fc 100644 --- a/commonly-mcp/src/tools.js +++ b/commonly-mcp/src/tools.js @@ -184,11 +184,13 @@ export const buildTools = (config) => { threadRootId: STRING, continueAnyway: { type: 'boolean' }, metadata: { type: 'object', additionalProperties: true }, + messageType: { type: 'string', enum: ['text', 'card'] }, + payload: { type: 'object', description: 'UI card only: {kind:"ui",v:1,lang:"openui@1",source}. Requires messageType card and content text fallback; validated by the server.', additionalProperties: true }, }, ['podId', 'content']), - call: wrap(async ({ podId, content, replyToMessageId, threadRootId, metadata, continueAnyway }) => request(config, { + call: wrap(async ({ podId, content, replyToMessageId, threadRootId, metadata, continueAnyway, messageType, payload }) => request(config, { method: 'POST', path: `/api/agents/runtime/pods/${encodeURIComponent(podId)}/messages`, - body: { content, replyToMessageId, threadRootId, metadata, continueAnyway }, + body: { content, replyToMessageId, threadRootId, metadata, continueAnyway, messageType, payload }, })), }, { diff --git a/docs/api/agent-ui-cards.md b/docs/api/agent-ui-cards.md new file mode 100644 index 0000000000..3ebd4b09e2 --- /dev/null +++ b/docs/api/agent-ui-cards.md @@ -0,0 +1,62 @@ +# Agent-authored UI cards + +The agent runtime message writer accepts an additive UI card envelope. Kernel +approval, decision and handoff payloads remain server-composed; agent requests +cannot write their kinds through this surface. + +```json +{ + "content": "A readable text fallback for clients without the UI renderer.", + "messageType": "card", + "payload": { + "kind": "ui", + "v": 1, + "lang": "openui@1", + "source": "root = Text(\"Hello\")" + } +} +``` + +Send to `POST /api/agents/runtime/pods/:podId/messages`, using the existing +pod-authorized runtime token and freshness rules. The bot API-token message +route uses the same validator. A payload on a non-card message is refused. + +`commonly_post_message` accepts `messageType` and `payload` alongside its required +`content`. The CLI takes a JSON envelope: + +```sh +commonly pod send 'A readable text fallback.' --payload '{"kind":"ui","v":1,"lang":"openui@1","source":"root = Text(\"Hello\")"}' +``` + +Cards are sent only through the validated agent writer. Unlike the existing +plain-text login fallback, a refused card is never retried on the human message +endpoint. Server refusals return HTTP 400 with `code: invalid_ui_card`; correcting +the source is required before retrying. + +## Write boundary + +- Envelope version is exactly `v: 1`, language is exactly `openui@1`. Additional + client fields (including a claimed `runId`) are refused. +- The whole JSON envelope, serialized in UTF-8, must be at most 32,768 bytes. +- Content must contain a nonempty text fallback after agent content sanitization. +- `@openuidev/lang-core` 1.0.1 parses the source against the Commonly catalogue. + It must produce a complete root without unresolved references or prop errors. +- Every statement is inspected, including unreachable statements. Unknown + component calls, Query, Mutation, Run, custom functions, reactive expressions, + duplicate definitions, prototype keys, over 256 statements and over 64 nested + bracket levels are refused. +- Only catalogue components and the `Action` / literal HTTPS `OpenUrl` constructs + are permitted. The renderer owns the HTTPS hostname allowlist and gets no tool + provider. Server parsing never executes a tool or an action. + +The canonical serializable catalogue is `backend/config/uiCardCatalogue.json`. +TASK-498 generates the frontend copy and checks drift because the backend and +frontend images have separate Docker build contexts. Names and positional prop +order are part of the stored `openui@1` contract; incompatible changes need a +new envelope/language version and reader compatibility. + +The parser is MIT licensed. Installation telemetry was disabled for the local +install (`npm install --ignore-scripts`); its runtime telemetry is opt-in and is +not enabled by this feature. Operators can set `OPENUI_TELEMETRY_DISABLED=1` for +all install/runtime telemetry. The backend image sets this opt-out before +installing dependencies. No cloud parser or devtools are used. From d4257d12c93c8d9c25dc42639aac8e624a2d6c9b Mon Sep 17 00:00:00 2001 From: Lily Shen <115414357+lilyshen0722@users.noreply.github.com> Date: Sun, 25 Oct 2026 01:46:02 -0700 Subject: [PATCH 02/13] test: refuse suppressed UI fallbacks and object-spoofed roots Co-authored-by: tern Agent-Model: codex/gpt-6.1-sol/medium --- .../unit/routes/agentsRuntime.post-message.config.test.js | 7 +++++++ backend/__tests__/unit/services/uiCardValidation.test.js | 1 + 2 files changed, 8 insertions(+) diff --git a/backend/__tests__/unit/routes/agentsRuntime.post-message.config.test.js b/backend/__tests__/unit/routes/agentsRuntime.post-message.config.test.js index b3c722624a..e4fc57231c 100644 --- a/backend/__tests__/unit/routes/agentsRuntime.post-message.config.test.js +++ b/backend/__tests__/unit/routes/agentsRuntime.post-message.config.test.js @@ -246,6 +246,13 @@ describe('agent card route boundary', () => { expect(AgentMessageService.postMessage).not.toHaveBeenCalled(); expect(findNonMemberMentionNotices).not.toHaveBeenCalled(); }); + it('refuses a fallback that the existing sanitizer suppresses', async () => { + AgentMessageService.sanitizeAgentContent.mockReturnValueOnce(''); + const res = response(); + await handler(req({ messageType: 'card', payload, content: 'NO_REPLY' }), res); + expect(res.status).toHaveBeenCalledWith(400); + expect(AgentMessageService.postMessage).not.toHaveBeenCalled(); + }); it('keeps the pod authorization check ahead of parsing', async () => { const res = response(); await handler({ ...req({ payload }), params: { podId: 'other' } }, res); diff --git a/backend/__tests__/unit/services/uiCardValidation.test.js b/backend/__tests__/unit/services/uiCardValidation.test.js index 27cb541c19..be8e3f6264 100644 --- a/backend/__tests__/unit/services/uiCardValidation.test.js +++ b/backend/__tests__/unit/services/uiCardValidation.test.js @@ -44,6 +44,7 @@ describe('untrusted UI card write validation', () => { 'root = Text(missing)', 'root = Text("hi")\nroot = Text("replacement")', 'root = Text({__proto__: {polluted: true}})', + 'root = {type: "element", typeName: "Query", props: {tool: "secret"}}', 'no root here', ])('refuses unsafe, unknown, or incomplete source: %s', (source) => { expect(() => validate(card(source))).toThrow(expect.objectContaining({ statusCode: 400 })); From dcb8c21001ca605eac078da9a190222cefa1f90b Mon Sep 17 00:00:00 2001 From: Lily Shen <115414357+lilyshen0722@users.noreply.github.com> Date: Sun, 25 Oct 2026 01:50:53 -0700 Subject: [PATCH 03/13] feat: validate UI cards from the native post tool Co-authored-by: tern Agent-Model: codex/gpt-6.1-sol/medium --- .../nativeRuntimeService.byoHandoff.test.js | 42 ++++++++++++++++++- backend/services/nativeRuntimeService.ts | 15 ++++++- docs/api/agent-ui-cards.md | 4 +- 3 files changed, 57 insertions(+), 4 deletions(-) diff --git a/backend/__tests__/unit/services/nativeRuntimeService.byoHandoff.test.js b/backend/__tests__/unit/services/nativeRuntimeService.byoHandoff.test.js index 57e20660ca..f1297e6474 100644 --- a/backend/__tests__/unit/services/nativeRuntimeService.byoHandoff.test.js +++ b/backend/__tests__/unit/services/nativeRuntimeService.byoHandoff.test.js @@ -16,7 +16,10 @@ jest.mock('../../../models/User', () => ({ findById: (...args) => mockUserFindById(...args), })); jest.mock('../../../services/agentTypingService', () => ({ emitAgentTypingStart: jest.fn(), emitAgentTypingStop: jest.fn() })); -jest.mock('../../../services/agentMessageService', () => ({ postMessage: jest.fn().mockResolvedValue({ success: true }) })); +jest.mock('../../../services/agentMessageService', () => ({ + postMessage: jest.fn().mockResolvedValue({ success: true }), + sanitizeAgentContent: jest.fn((content) => content), +})); jest.mock('../../../services/messageClaimService', () => ({ claim: jest.fn().mockResolvedValue({ claimed: true, expiresAt: new Date() }), release: jest.fn().mockResolvedValue({ released: true }), @@ -166,6 +169,43 @@ describe('commonly_offer_local_agent', () => { expect(posted.noOutboundRelay).toBe(true); }); + test('native post tool forwards a validated UI card and offers the payload schema', async () => { + const payload = { kind: 'ui', v: 1, lang: 'openui@1', source: 'root = Text("native card")' }; + axios.post.mockResolvedValueOnce(callsTool('commonly_post_message', { + content: 'Text fallback', messageType: 'card', payload, + })).mockResolvedValueOnce(says('NO_REPLY')); + await runAgent({ ...install, config: { ...install.config, tools: ['commonly_post_message'] } }, ask); + expect(AgentMessageService.postMessage).toHaveBeenCalledTimes(1); + expect(AgentMessageService.postMessage).toHaveBeenCalledWith(expect.objectContaining({ + content: 'Text fallback', messageType: 'card', payload, + })); + const tool = axios.post.mock.calls[0][1].tools.find((t) => t.function.name === 'commonly_post_message'); + expect(tool.function.parameters.properties.payload.type).toBe('object'); + }); + test.each([ + { kind: 'approval', v: 1, lang: 'openui@1', source: 'root = Text("forged")' }, + { kind: 'ui', v: 1, lang: 'openui@1', source: 'root = Text("hi")\nunused = Query("secret", {})' }, + { kind: 'ui', v: 1, lang: 'openui@1', source: 'root = Text("hi")', runId: 'other-run' }, + ])('native post tool refuses unsafe payloads before the writer %#', async (payload) => { + axios.post.mockResolvedValueOnce(callsTool('commonly_post_message', { + content: 'Text fallback', messageType: 'card', payload, + })).mockResolvedValueOnce(says('')); + await runAgent({ ...install, config: { ...install.config, tools: ['commonly_post_message'] } }, ask); + expect(AgentMessageService.postMessage).not.toHaveBeenCalled(); + const toolResult = axios.post.mock.calls[1][1].messages.find((m) => m.role === 'tool'); + expect(JSON.parse(toolResult.content).ok).toBe(false); + }); + + test('native post tool refuses an undeclared message type before the writer', async () => { + axios.post.mockResolvedValueOnce(callsTool('commonly_post_message', { + content: 'Text fallback', messageType: 'system', + })).mockResolvedValueOnce(says('')); + await runAgent({ ...install, config: { ...install.config, tools: ['commonly_post_message'] } }, ask); + expect(AgentMessageService.postMessage).not.toHaveBeenCalled(); + const toolResult = axios.post.mock.calls[1][1].messages.find((m) => m.role === 'tool'); + expect(JSON.parse(toolResult.content).ok).toBe(false); + }); + test('does not let a client post mark itself as kernel-authored', async () => { axios.post .mockResolvedValueOnce(callsTool('commonly_post_message', { diff --git a/backend/services/nativeRuntimeService.ts b/backend/services/nativeRuntimeService.ts index 5a05762b8b..725d174829 100644 --- a/backend/services/nativeRuntimeService.ts +++ b/backend/services/nativeRuntimeService.ts @@ -26,6 +26,7 @@ @typescript-eslint/no-require-imports */ import { Types } from 'mongoose'; +import { validateAgentCardPayload } from './uiCardValidation'; import { isTaskPriority, TASK_PRIORITY_ORDER } from '../utils/taskPriority'; import axios, { AxiosError } from 'axios'; import { @@ -277,7 +278,9 @@ export const TOOLS = [ parameters: { type: 'object', properties: { - content: { type: 'string', description: 'Markdown-supported message content' }, + content: { type: 'string', description: 'Markdown-supported message content and required UI text fallback' }, + messageType: { type: 'string', enum: ['text', 'card'] }, + payload: { type: 'object', description: 'Optional {kind:"ui",v:1,lang:"openui@1",source}. Requires messageType card; validated locally before writing.' }, }, required: ['content'], }, @@ -782,12 +785,20 @@ export async function dispatchTool( return { content: { ok: false, error: 'content is required' }, error: 'missing_content' }; } const AgentMessageService = require('./agentMessageService'); + const messageType = args.messageType ?? 'text'; + if (messageType !== 'text' && messageType !== 'card') { + return { content: { ok: false, error: 'Unsupported native messageType' }, error: 'invalid_message_type' }; + } + validateAgentCardPayload(messageType, args.payload, args.payload !== undefined + ? (typeof args.content === 'string' ? AgentMessageService.sanitizeAgentContent(args.content) : args.content) + : content); const result = await AgentMessageService.postMessage({ agentName: ctx.agentName, instanceId: ctx.instanceId, podId: ctx.podId, content, - messageType: 'text', + messageType, + ...(args.payload !== undefined ? { payload: args.payload } : {}), displayName: ctx.displayName, installationConfig: ctx.installationConfig, metadata: { source: 'native-runtime' }, diff --git a/docs/api/agent-ui-cards.md b/docs/api/agent-ui-cards.md index 3ebd4b09e2..a0fcf39868 100644 --- a/docs/api/agent-ui-cards.md +++ b/docs/api/agent-ui-cards.md @@ -22,7 +22,9 @@ pod-authorized runtime token and freshness rules. The bot API-token message route uses the same validator. A payload on a non-card message is refused. `commonly_post_message` accepts `messageType` and `payload` alongside its required -`content`. The CLI takes a JSON envelope: +`content`. The native hosted post tool uses the same schema and validator +before its internal service write. Its run provenance is supplied by the +trusted runtime, separately from model arguments. The CLI takes a JSON envelope: ```sh commonly pod send 'A readable text fallback.' --payload '{"kind":"ui","v":1,"lang":"openui@1","source":"root = Text(\"Hello\")"}' From e2ac6a9fd07d10cc6e86be869150eb701725be69 Mon Sep 17 00:00:00 2001 From: Lily Shen <115414357+lilyshen0722@users.noreply.github.com> Date: Sun, 25 Oct 2026 01:57:22 -0700 Subject: [PATCH 04/13] feat: enforce the shared UI card catalogue and bounds Co-authored-by: tern Agent-Model: codex/gpt-6.1-sol/medium --- .../unit/services/uiCardValidation.test.js | 46 +- backend/config/uiCardCatalogue.json | 423 +++++++++++++++++- backend/package-lock.json | 245 ++++++---- backend/package.json | 1 + backend/services/uiCardValidation.ts | 63 ++- docs/api/agent-ui-cards.md | 17 + docs/development/agent-experience-audit.md | 10 + 7 files changed, 701 insertions(+), 104 deletions(-) diff --git a/backend/__tests__/unit/services/uiCardValidation.test.js b/backend/__tests__/unit/services/uiCardValidation.test.js index be8e3f6264..32ff4a2807 100644 --- a/backend/__tests__/unit/services/uiCardValidation.test.js +++ b/backend/__tests__/unit/services/uiCardValidation.test.js @@ -49,14 +49,56 @@ describe('untrusted UI card write validation', () => { ])('refuses unsafe, unknown, or incomplete source: %s', (source) => { expect(() => validate(card(source))).toThrow(expect.objectContaining({ statusCode: 400 })); }); + it.each([ + 'root = Card("Plan", [Text("Do it"), Steps([Step("First", "active"), Step("Second", "pending")])])', + 'root = DiffSummary([File("src/main.ts", 4, 2)])', + 'root = TaskStatus("TASK-497", "Read from the board")', + 'root = KeyValue([Pair("Checks", 42), Pair("Ready", true)])', + 'root = Table([Col("Name"), Col("Count", "number")], [["tests", 42]])', + 'root = Badge("Ready", "done")', + 'root = Link("Docs", "https://commonly.me/docs", "text")', + 'root = RunTrace(3)', + 'root = List(["one", "two"], true)', + 'root = Text(["Read ", Link("the docs", "https://commonly.me/docs", "text")])', + ])('accepts the artboard catalogue: %s', (source) => { + expect(() => validate(card(source))).not.toThrow(); + }); + it.each([ + 'root = Text(' + JSON.stringify('a'.repeat(601)) + ')', + 'root = Card(' + JSON.stringify('a'.repeat(81)) + ', [Text("hi")])', + 'root = Card("Empty", [])', + 'root = List([])', + 'root = Steps([Step("only", "done")])', + 'root = Steps([Step("one", "active"), Step("two", "active")])', + 'root = Steps([Step("one", "unknown"), Step("two", "pending")])', + 'root = DiffSummary([File("file", -1, 0)])', + 'root = RunTrace(0)', + 'root = RunTrace(6)', + 'root = RunTrace(1.5)', + 'root = Badge("Ready", "cobalt")', + 'root = TaskStatus("TASK-1", "note", "done")', + 'root = Table([Col("Name")], [["one", "extra"]])', + 'root = Text(["prefix", Link("button", "https://commonly.me", "button")])', + 'root = Link("unsafe", "http://commonly.me", "text")', + 'root = Link("unsafe", "https://user:password@commonly.me", "text")', + 'root = Link("unsafe", "javascript:alert(1)", "text")', + 'root = Card("Two primary", [Link("one", "https://commonly.me", "primary"), Link("two", "https://commonly.me", "primary")])', + 'root = Card("Three buttons", [Link("one", "https://commonly.me", "button"), Link("two", "https://commonly.me", "button"), Link("three", "https://commonly.me", "button")])', + 'root = Step("not a visual root", "done")', + 'root = Card("wrong helper", [Pair("one", "two")])', + 'root = Text([' + JSON.stringify('a'.repeat(400)) + ', ' + JSON.stringify('b'.repeat(201)) + '])', + ])('refuses catalogue limits and invalid helper placement: %s', (source) => { + expect(() => validate(card(source))).toThrow(expect.objectContaining({ statusCode: 400 })); + }); it('refuses deeply nested input before recursive parsing', () => { expect(() => validate(card('root = Text(' + '['.repeat(1000) + '0' + ']'.repeat(1000) + ')'))).toThrow('nesting'); }); it('limits serialized payload bytes, including multibyte Unicode and exact boundary', () => { const prefix = 'root = Text("'; const suffix = '")'; - const overhead = Buffer.byteLength(JSON.stringify(card(prefix + suffix))); - const exact = card(prefix + 'a'.repeat(UI_CARD_MAX_BYTES - overhead) + suffix); + const exact = card(); + const overhead = Buffer.byteLength(JSON.stringify(exact)); + exact.source += ' '.repeat(UI_CARD_MAX_BYTES - overhead); expect(Buffer.byteLength(JSON.stringify(exact))).toBe(UI_CARD_MAX_BYTES); expect(() => validate(exact)).not.toThrow(); expect(() => validate({ ...exact, source: exact.source + ' ' })).toThrow('32 KB'); diff --git a/backend/config/uiCardCatalogue.json b/backend/config/uiCardCatalogue.json index 12a014c860..c5d2b261fa 100644 --- a/backend/config/uiCardCatalogue.json +++ b/backend/config/uiCardCatalogue.json @@ -1,10 +1,427 @@ { "$defs": { + "Card": { + "type": "object", + "properties": { + "title": { + "type": "string", + "maxLength": 80 + }, + "children": { + "type": "array", + "items": { + "anyOf": [ + { + "$ref": "#/$defs/Card" + }, + { + "$ref": "#/$defs/Text" + }, + { + "$ref": "#/$defs/List" + }, + { + "$ref": "#/$defs/Steps" + }, + { + "$ref": "#/$defs/DiffSummary" + }, + { + "$ref": "#/$defs/TaskStatus" + }, + { + "$ref": "#/$defs/KeyValue" + }, + { + "$ref": "#/$defs/Table" + }, + { + "$ref": "#/$defs/Badge" + }, + { + "$ref": "#/$defs/Link" + }, + { + "$ref": "#/$defs/RunTrace" + } + ] + }, + "minItems": 1, + "maxItems": 6 + }, + "meta": { + "type": "string", + "maxLength": 32 + }, + "summary": { + "type": "string", + "maxLength": 200 + } + }, + "required": [ + "title", + "children" + ], + "additionalProperties": false + }, "Text": { "type": "object", - "properties": { "text": { "type": "string" } }, - "required": ["text"] + "properties": { + "body": { + "anyOf": [ + { + "type": "string", + "maxLength": 600 + }, + { + "type": "array", + "items": { + "anyOf": [ + { + "type": "string", + "maxLength": 600 + }, + { + "$ref": "#/$defs/Link" + } + ] + } + } + ] + } + }, + "required": [ + "body" + ], + "additionalProperties": false + }, + "List": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "type": "string", + "maxLength": 120 + }, + "minItems": 1, + "maxItems": 8 + }, + "ordered": { + "type": "boolean", + "default": false + } + }, + "required": [ + "items" + ], + "additionalProperties": false + }, + "Steps": { + "type": "object", + "properties": { + "steps": { + "type": "array", + "items": { + "$ref": "#/$defs/Step" + }, + "minItems": 2, + "maxItems": 8 + } + }, + "required": [ + "steps" + ], + "additionalProperties": false + }, + "Step": { + "type": "object", + "properties": { + "label": { + "type": "string", + "maxLength": 60 + }, + "state": { + "type": "string", + "enum": [ + "pending", + "active", + "done", + "failed", + "skipped" + ] + }, + "detail": { + "type": "string", + "maxLength": 120 + } + }, + "required": [ + "label", + "state" + ], + "additionalProperties": false + }, + "DiffSummary": { + "type": "object", + "properties": { + "files": { + "type": "array", + "items": { + "$ref": "#/$defs/File" + } + } + }, + "required": [ + "files" + ], + "additionalProperties": false + }, + "File": { + "type": "object", + "properties": { + "path": { + "type": "string" + }, + "added": { + "type": "integer", + "minimum": 0 + }, + "removed": { + "type": "integer", + "minimum": 0 + } + }, + "required": [ + "path", + "added", + "removed" + ], + "additionalProperties": false + }, + "TaskStatus": { + "type": "object", + "properties": { + "taskId": { + "type": "string" + }, + "note": { + "type": "string" + } + }, + "required": [ + "taskId" + ], + "additionalProperties": false + }, + "KeyValue": { + "type": "object", + "properties": { + "pairs": { + "type": "array", + "items": { + "$ref": "#/$defs/Pair" + } + } + }, + "required": [ + "pairs" + ], + "additionalProperties": false + }, + "Pair": { + "type": "object", + "properties": { + "key": { + "type": "string" + }, + "value": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "key", + "value" + ], + "additionalProperties": false + }, + "Table": { + "type": "object", + "properties": { + "columns": { + "type": "array", + "items": { + "$ref": "#/$defs/Col" + }, + "minItems": 1 + }, + "rows": { + "type": "array", + "items": { + "type": "array", + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + }, + { + "type": "null" + } + ] + } + } + } + }, + "required": [ + "columns", + "rows" + ], + "additionalProperties": false + }, + "Col": { + "type": "object", + "properties": { + "label": { + "type": "string" + }, + "type": { + "type": "string" + } + }, + "required": [ + "label" + ], + "additionalProperties": false + }, + "Badge": { + "type": "object", + "properties": { + "label": { + "type": "string", + "maxLength": 24 + }, + "tone": { + "type": "string", + "enum": [ + "neutral", + "ink", + "done", + "failed", + "pending" + ] + } + }, + "required": [ + "label", + "tone" + ], + "additionalProperties": false + }, + "Link": { + "type": "object", + "properties": { + "label": { + "type": "string", + "maxLength": 40 + }, + "url": { + "type": "string" + }, + "as": { + "type": "string", + "enum": [ + "text", + "button", + "primary" + ] + } + }, + "required": [ + "label", + "url", + "as" + ], + "additionalProperties": false + }, + "RunTrace": { + "type": "object", + "properties": { + "limit": { + "type": "integer", + "minimum": 1, + "maximum": 5 + } + }, + "required": [ + "limit" + ], + "additionalProperties": false } }, - "properties": { "Text": { "$ref": "#/$defs/Text" } } + "properties": { + "Card": { + "$ref": "#/$defs/Card" + }, + "Text": { + "$ref": "#/$defs/Text" + }, + "List": { + "$ref": "#/$defs/List" + }, + "Steps": { + "$ref": "#/$defs/Steps" + }, + "Step": { + "$ref": "#/$defs/Step" + }, + "DiffSummary": { + "$ref": "#/$defs/DiffSummary" + }, + "File": { + "$ref": "#/$defs/File" + }, + "TaskStatus": { + "$ref": "#/$defs/TaskStatus" + }, + "KeyValue": { + "$ref": "#/$defs/KeyValue" + }, + "Pair": { + "$ref": "#/$defs/Pair" + }, + "Table": { + "$ref": "#/$defs/Table" + }, + "Col": { + "$ref": "#/$defs/Col" + }, + "Badge": { + "$ref": "#/$defs/Badge" + }, + "Link": { + "$ref": "#/$defs/Link" + }, + "RunTrace": { + "$ref": "#/$defs/RunTrace" + } + } } diff --git a/backend/package-lock.json b/backend/package-lock.json index e0a33812f8..52bc11cdef 100644 --- a/backend/package-lock.json +++ b/backend/package-lock.json @@ -19,6 +19,7 @@ "@sentry/node": "^10.65.0", "@socket.io/redis-adapter": "^8.3.0", "adm-zip": "^0.6.1", + "ajv": "8.20.0", "axios": "^1.20.0", "bcryptjs": "^2.4.3", "cors": "^2.8.5", @@ -905,6 +906,23 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/@eslint/eslintrc/node_modules/ajv": { + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz", + "integrity": "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, "node_modules/@eslint/eslintrc/node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -966,6 +984,13 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/@eslint/eslintrc/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, "node_modules/@eslint/eslintrc/node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -1771,22 +1796,6 @@ "node": ">= 0.6" } }, - "node_modules/@modelcontextprotocol/sdk/node_modules/ajv": { - "version": "8.20.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.20.0.tgz", - "integrity": "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==", - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3", - "fast-uri": "^3.0.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, "node_modules/@modelcontextprotocol/sdk/node_modules/body-parser": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.3.0.tgz", @@ -1981,12 +1990,6 @@ "url": "https://github.com/sponsors/panva" } }, - "node_modules/@modelcontextprotocol/sdk/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "license": "MIT" - }, "node_modules/@modelcontextprotocol/sdk/node_modules/media-typer": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.1.tgz", @@ -3871,15 +3874,15 @@ } }, "node_modules/ajv": { - "version": "6.15.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz", - "integrity": "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==", + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.20.0.tgz", + "integrity": "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==", "license": "MIT", "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" }, "funding": { "type": "github", @@ -3903,28 +3906,6 @@ } } }, - "node_modules/ajv-formats/node_modules/ajv": { - "version": "8.20.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.20.0.tgz", - "integrity": "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==", - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3", - "fast-uri": "^3.0.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ajv-formats/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "license": "MIT" - }, "node_modules/ansi-escapes": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", @@ -6022,6 +6003,23 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/eslint/node_modules/ajv": { + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz", + "integrity": "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, "node_modules/eslint/node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -6123,6 +6121,13 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/eslint/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, "node_modules/eslint/node_modules/locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", @@ -7287,6 +7292,28 @@ "node": ">=6" } }, + "node_modules/har-validator/node_modules/ajv": { + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz", + "integrity": "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/har-validator/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "license": "MIT" + }, "node_modules/has-bigints": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz", @@ -8883,9 +8910,10 @@ "license": "(AFL-2.1 OR BSD-3-Clause)" }, "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "license": "MIT" }, "node_modules/json-schema-typed": { "version": "8.0.2", @@ -12947,6 +12975,7 @@ "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "license": "BSD-2-Clause", "dependencies": { "punycode": "^2.1.0" } @@ -13956,6 +13985,18 @@ "strip-json-comments": "^3.1.1" }, "dependencies": { + "ajv": { + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz", + "integrity": "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, "argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -13989,6 +14030,12 @@ "argparse": "^2.0.1" } }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, "ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -14561,17 +14608,6 @@ "negotiator": "^1.0.0" } }, - "ajv": { - "version": "8.20.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.20.0.tgz", - "integrity": "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==", - "requires": { - "fast-deep-equal": "^3.1.3", - "fast-uri": "3.1.8", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2" - } - }, "body-parser": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.3.0.tgz", @@ -14691,11 +14727,6 @@ "resolved": "https://registry.npmjs.org/jose/-/jose-6.2.12.tgz", "integrity": "sha512-9NiFmJEex0sy2Dk58j2UGBSHgUs2ypF9eZSu4L6vjOX3Dp96Sw1F3uL+H+D1sx02jZZdzUT0HgvCy59CuvXcWw==" }, - "json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" - }, "media-typer": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.1.tgz", @@ -16022,14 +16053,14 @@ } }, "ajv": { - "version": "6.15.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz", - "integrity": "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==", + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.20.0.tgz", + "integrity": "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==", "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" + "fast-deep-equal": "^3.1.3", + "fast-uri": "3.1.8", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" } }, "ajv-formats": { @@ -16038,24 +16069,6 @@ "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", "requires": { "ajv": "^8.0.0" - }, - "dependencies": { - "ajv": { - "version": "8.20.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.20.0.tgz", - "integrity": "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==", - "requires": { - "fast-deep-equal": "^3.1.3", - "fast-uri": "3.1.8", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2" - } - }, - "json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" - } } }, "ansi-escapes": { @@ -17409,6 +17422,18 @@ "text-table": "^0.2.0" }, "dependencies": { + "ajv": { + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz", + "integrity": "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, "argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -17467,6 +17492,12 @@ "argparse": "^2.0.1" } }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, "locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", @@ -18396,6 +18427,24 @@ "requires": { "ajv": "^6.12.3", "har-schema": "^2.0.0" + }, + "dependencies": { + "ajv": { + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz", + "integrity": "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==", + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + } } }, "has-bigints": { @@ -19523,9 +19572,9 @@ "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==" }, "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" }, "json-schema-typed": { "version": "8.0.2", diff --git a/backend/package.json b/backend/package.json index e2f772e088..2797fd9a5c 100644 --- a/backend/package.json +++ b/backend/package.json @@ -46,6 +46,7 @@ "@sentry/node": "^10.65.0", "@socket.io/redis-adapter": "^8.3.0", "adm-zip": "^0.6.1", + "ajv": "8.20.0", "axios": "^1.20.0", "bcryptjs": "^2.4.3", "cors": "^2.8.5", diff --git a/backend/services/uiCardValidation.ts b/backend/services/uiCardValidation.ts index 32ffc542cd..6566bb61e3 100644 --- a/backend/services/uiCardValidation.ts +++ b/backend/services/uiCardValidation.ts @@ -1,7 +1,8 @@ import { createParser, parseExpression, split, tokenize, walkAST, } from '@openuidev/lang-core'; -import type { LibraryJSONSchema } from '@openuidev/lang-core'; +import type { ElementNode, LibraryJSONSchema } from '@openuidev/lang-core'; +import Ajv from 'ajv'; import catalogue from '../config/uiCardCatalogue.json'; export const UI_CARD_MAX_BYTES = 32 * 1024; @@ -16,6 +17,64 @@ const closingTokens = new Map([ ]); const openParenToken = bracketTokens[0].t; const allowedCall = (name: string) => componentNames.has(name) || ['Action', 'OpenUrl'].includes(name); +const helpers = new Set(['Step', 'File', 'Pair', 'Col']); +// lang-core validates prop types but ignores JSON Schema bounds (maxLength, +// minItems, minimum, etc.). Validate its materialized tree as well. References +// name element wrappers so helper/child identity is checked, not only prop shape. +const validateTree = new Ajv({ strict: false }).compile({ + $defs: Object.fromEntries(Object.entries(catalogue.$defs).map(([name, props]) => [name, { + type: 'object', + properties: { + type: { const: 'element' }, typeName: { const: name }, props, + partial: { type: 'boolean' }, hasDynamicProps: { type: 'boolean' }, statementId: { type: 'string' }, + }, + required: ['type', 'typeName', 'props'], + additionalProperties: false, + }])), + anyOf: Object.keys(catalogue.properties).filter((name) => !helpers.has(name)) + .map((name) => ({ $ref: `#/$defs/${name}` })), +}); + +function validatePresentation(root: ElementNode): void { + let buttons = 0; + let primary = 0; + function visit(value: unknown): void { + if (Array.isArray(value)) { value.forEach(visit); return; } + if (!value || typeof value !== 'object') return; + const node = value as ElementNode; + if (node.type !== 'element') return; + const { props } = node; + if (node.typeName === 'Link') { + const url = new URL(props.url as string); + if (url.protocol !== 'https:' || url.username || url.password) refuse('Link requires a credential-free https URL'); + if (props.as !== 'text') buttons += 1; + if (props.as === 'primary') primary += 1; + } + if (node.typeName === 'Text' && Array.isArray(props.body)) { + let length = 0; + props.body.forEach((part: string | ElementNode) => { + if (typeof part === 'string') length += [...part].length; + else { + if (part.props.as !== 'text') refuse('Inline Text links must use text presentation'); + length += [...String(part.props.label)].length; + } + }); + if (length > 600) refuse('Text body exceeds 600 characters'); + } + if (node.typeName === 'Steps' + && (props.steps as ElementNode[]).filter((step) => step.props.state === 'active').length > 1) { + refuse('Steps permits at most one active step'); + } + if (node.typeName === 'Table' + && (props.rows as unknown[][]).some((row) => row.length !== (props.columns as unknown[]).length)) { + refuse('Table row width must match its columns'); + } + Object.values(props).forEach(visit); + } + visit(root); + if (buttons > 2 || primary > 1) refuse('UI card permits at most two buttons and one primary link'); +} + export class UICardValidationError extends Error { readonly statusCode = 400; @@ -108,6 +167,8 @@ export function validateAgentCardPayload( || Object.keys(result.stateDeclarations).length) { refuse('UI card source is incomplete or invalid for the Commonly catalogue'); } + if (!validateTree(result.root)) refuse('UI card props violate the Commonly catalogue'); + validatePresentation(result.root); } catch (error) { if (error instanceof UICardValidationError) throw error; refuse('UI card source could not be parsed'); diff --git a/docs/api/agent-ui-cards.md b/docs/api/agent-ui-cards.md index a0fcf39868..b9b6c2f20a 100644 --- a/docs/api/agent-ui-cards.md +++ b/docs/api/agent-ui-cards.md @@ -51,6 +51,23 @@ the source is required before retrying. are permitted. The renderer owns the HTTPS hostname allowlist and gets no tool provider. Server parsing never executes a tool or an action. +## Catalogue v1 + +Visual components: Card, Text, List, Steps, DiffSummary, TaskStatus, KeyValue, +Table, Badge, Link and RunTrace. Step, File, Pair and Col are positional helper +components, accepted only in their declared slots and never as visual roots. +There is no Stack component; Card children stack. + +Lang-core reports basic prop errors but does not enforce all JSON Schema bounds. +The write boundary also validates its materialized tree with Ajv 8.20.0 (MIT), +using the same catalogue's complete constraints. Examples proving the gap and +its guard are in `uiCardValidation.test.js`; see AX audit entry 85. + +Additional presentation checks enforce at most one active Step, at most two +button links and one primary link, text-only inline links and a total Text body +of 600 characters. Table row width must match its columns. Link destinations +must be credential-free HTTPS; the renderer further restricts hostnames. + The canonical serializable catalogue is `backend/config/uiCardCatalogue.json`. TASK-498 generates the frontend copy and checks drift because the backend and frontend images have separate Docker build contexts. Names and positional prop diff --git a/docs/development/agent-experience-audit.md b/docs/development/agent-experience-audit.md index 8096552c87..42ae800aff 100644 --- a/docs/development/agent-experience-audit.md +++ b/docs/development/agent-experience-audit.md @@ -4210,3 +4210,13 @@ Settings read one writable pod's `config.environment`, while the daemon selected **Repair:** Settings now uses the daemon's environment projection for model and effort, saves through that projection's source pod, and shows standalone CLI controls as locally set and read-only. Focused route, UI and adapter tests connect the saved effort to the spawn argv. **Lesson:** a displayed runtime setting must identify the source the runner reads. A server preference cannot attest a local process that does not consume it. + +## 85. A schema-aware UI parser did not enforce schema bounds (2026-10-25, tern) + +*Origin: TASK-497 / #2675. `@openuidev/lang-core` 1.0.1 accepts a library JSON Schema and reports prop validation errors, suggesting that the schema's limits are enforced.* + +Measured with `createParser(catalogue).parse(source)`: a `Text` body of 601 characters under `maxLength: 600`, and `RunTrace(7)` under `maximum: 5`, both produced a root with an empty `meta.errors` array. The parser checks basic prop types but does not apply every JSON Schema keyword. Parsing only the root also misses unknown component calls in unreachable statements. + +**Repair:** inspect every statement/call before accepting source, then validate the materialized element tree with a full JSON Schema validator. Element wrappers preserve component identity when following child/helper references. `backend/__tests__/unit/services/uiCardValidation.test.js` pins string/array/number limits, helper placement and cross-item rules as well as dormant unsafe calls. + +**Lesson:** accepting a schema as a parser input does not establish which schema constraints it enforces. Probe the actual boundary values before making the parser an authorization or resource-limit boundary. From 59e678b01cb461ae85f41cd575bafbc88e49c6b4 Mon Sep 17 00:00:00 2001 From: Lily Shen <115414357+lilyshen0722@users.noreply.github.com> Date: Sun, 25 Oct 2026 01:59:22 -0700 Subject: [PATCH 05/13] fix: apply the RunTrace default from the artboard Co-authored-by: tern Agent-Model: codex/gpt-6.1-sol/medium --- backend/__tests__/unit/services/uiCardValidation.test.js | 1 + backend/config/uiCardCatalogue.json | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/backend/__tests__/unit/services/uiCardValidation.test.js b/backend/__tests__/unit/services/uiCardValidation.test.js index 32ff4a2807..31905385d3 100644 --- a/backend/__tests__/unit/services/uiCardValidation.test.js +++ b/backend/__tests__/unit/services/uiCardValidation.test.js @@ -58,6 +58,7 @@ describe('untrusted UI card write validation', () => { 'root = Badge("Ready", "done")', 'root = Link("Docs", "https://commonly.me/docs", "text")', 'root = RunTrace(3)', + 'root = RunTrace()', 'root = List(["one", "two"], true)', 'root = Text(["Read ", Link("the docs", "https://commonly.me/docs", "text")])', ])('accepts the artboard catalogue: %s', (source) => { diff --git a/backend/config/uiCardCatalogue.json b/backend/config/uiCardCatalogue.json index c5d2b261fa..43e38a567a 100644 --- a/backend/config/uiCardCatalogue.json +++ b/backend/config/uiCardCatalogue.json @@ -368,7 +368,8 @@ "limit": { "type": "integer", "minimum": 1, - "maximum": 5 + "maximum": 5, + "default": 3 } }, "required": [ From 78b513871e8e73d0736f5a85e2bd41bada7f8f95 Mon Sep 17 00:00:00 2001 From: Lily Shen <115414357+lilyshen0722@users.noreply.github.com> Date: Sun, 25 Oct 2026 02:13:11 -0700 Subject: [PATCH 06/13] feat(ui): render bounded OpenUI cards with the Signal catalogue Co-authored-by: Polish Agent-Model: codex/gpt-6.1-sol/medium --- .github/workflows/tests.yml | 4 +- docs/audits/task-498/README.md | 18 + docs/audits/task-498/catalogue-1440.png | Bin 0 -> 113447 bytes docs/audits/task-498/catalogue-390.png | Bin 0 -> 101312 bytes frontend/Dockerfile | 1 + frontend/design-system/preview/ui-card.html | 1 + frontend/design-system/preview/ui-card.tsx | 19 + frontend/package-lock.json | 210 ++++++++- frontend/package.json | 11 +- frontend/scripts/sync-ui-card-catalogue.mjs | 14 + frontend/scripts/ui-card-catalogue.test.mjs | 9 + .../v2/__tests__/v2-layout-invariants.test.ts | 11 + frontend/src/v2/cards/V2UICard.tsx | 39 ++ .../src/v2/cards/__tests__/V2UICard.test.tsx | 33 ++ .../src/v2/cards/__tests__/cardViews.test.tsx | 33 ++ .../v2/cards/__tests__/openUiReact18.test.tsx | 18 + .../v2/cards/__tests__/uiCardSource.test.ts | 18 + frontend/src/v2/cards/cardLinks.ts | 9 + frontend/src/v2/cards/cardRuntime.tsx | 41 ++ frontend/src/v2/cards/cardViews.tsx | 115 +++++ frontend/src/v2/cards/uiCard.css | 137 ++++++ frontend/src/v2/cards/uiCardCatalogue.json | 428 ++++++++++++++++++ frontend/src/v2/cards/uiCardSource.ts | 66 +++ frontend/src/v2/components/V2GigCard.tsx | 16 +- frontend/src/v2/components/V2MessageRow.tsx | 7 +- frontend/src/v2/hooks/useV2PodDetail.ts | 4 + 26 files changed, 1234 insertions(+), 28 deletions(-) create mode 100644 docs/audits/task-498/README.md create mode 100644 docs/audits/task-498/catalogue-1440.png create mode 100644 docs/audits/task-498/catalogue-390.png create mode 100644 frontend/design-system/preview/ui-card.html create mode 100644 frontend/design-system/preview/ui-card.tsx create mode 100644 frontend/scripts/sync-ui-card-catalogue.mjs create mode 100644 frontend/scripts/ui-card-catalogue.test.mjs create mode 100644 frontend/src/v2/cards/V2UICard.tsx create mode 100644 frontend/src/v2/cards/__tests__/V2UICard.test.tsx create mode 100644 frontend/src/v2/cards/__tests__/cardViews.test.tsx create mode 100644 frontend/src/v2/cards/__tests__/openUiReact18.test.tsx create mode 100644 frontend/src/v2/cards/__tests__/uiCardSource.test.ts create mode 100644 frontend/src/v2/cards/cardLinks.ts create mode 100644 frontend/src/v2/cards/cardRuntime.tsx create mode 100644 frontend/src/v2/cards/cardViews.tsx create mode 100644 frontend/src/v2/cards/uiCard.css create mode 100644 frontend/src/v2/cards/uiCardCatalogue.json create mode 100644 frontend/src/v2/cards/uiCardSource.ts diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 9b82cd9f61..795e4d6896 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -129,7 +129,7 @@ jobs: frontend/package-lock.json # Frontend typecheck follows shared imports into backend TypeScript. - run: cd backend && npm ci --include=dev - - run: cd frontend && npm install --legacy-peer-deps + - run: cd frontend && OPENUI_TELEMETRY_DISABLED=1 npm install --legacy-peer-deps - run: cd frontend && npm run typecheck - name: Run frontend tests (coverage on the nightly schedule only) run: | @@ -139,7 +139,7 @@ jobs: else npx jest --watchAll=false --forceExit fi - - run: cd frontend && node --test scripts/generate-seo-pages.test.mjs scripts/nginx-routing.test.mjs + - run: cd frontend && node --test scripts/generate-seo-pages.test.mjs scripts/nginx-routing.test.mjs scripts/ui-card-catalogue.test.mjs tool-tests: name: CLI, MCP and hosted runtime tests diff --git a/docs/audits/task-498/README.md b/docs/audits/task-498/README.md new file mode 100644 index 0000000000..0a4c1c648e --- /dev/null +++ b/docs/audits/task-498/README.md @@ -0,0 +1,18 @@ +# TASK-498 renderer proof + +Artboard: TASK-495, expanded to text in PR #2675 comment 6395684963. + +The screenshots render the actual V2UICard and OpenUI 1.0.1 runtime against local fixtures. No production API, agent or grant was used. The preview is `frontend/design-system/preview/ui-card.html` served by Vite. Browser API routes supplied the board task and the trace receipt. Both widths have six cards, including malformed and expired states. + +- 1440: no horizontal overflow, ordinary primary link 32px tall. +- 390: no horizontal overflow, footer link 44px tall and full width; the three-column table becomes records. +- No page errors or OpenUI inspector auto-mount at either width. +- Static real-package render passes on the lockfile's React 18.3.1. + +`catalogue-1440.png` and `catalogue-390.png` capture the actual component specimens. Ego's seat wrapper denied access, so these were measured with an isolated headless Chrome profile using Playwright, without any signed-in browser session. + +The renderer accepts catalogue v1 only. Its hostname allowlist is exact: commonly.me, docs.commonly.me, github.com, HTTPS only, without credentials or custom ports. Other links are visible but unavailable. Legacy gig cards retain their narrower GitHub-only rule. Card source is never HTML and receives no tool provider. + +TaskStatus reads the current pod's board. RunTrace reads the pod-scoped TASK-499 endpoint from the server-stamped run ID; it uses only name, outcome and duration. Endpoint routing/provenance is supplied by #2686. No raw arguments or results enter the preview. + +The canonical grammar is owned by TASK-497 in `backend/config/uiCardCatalogue.json`. Run `node frontend/scripts/sync-ui-card-catalogue.mjs` to update the frontend copy; the byte-for-byte test preserves positional prop order. diff --git a/docs/audits/task-498/catalogue-1440.png b/docs/audits/task-498/catalogue-1440.png new file mode 100644 index 0000000000000000000000000000000000000000..513ff279c2c2a6759fb3f2a912b37d5a940a29cf GIT binary patch literal 113447 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 z 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�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 #WZ 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

{3pmf0Pk>a;%y(0@L30yG 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

diff --git a/frontend/design-system/preview/ui-card.tsx b/frontend/design-system/preview/ui-card.tsx new file mode 100644 index 0000000000..f6021ac8a2 --- /dev/null +++ b/frontend/design-system/preview/ui-card.tsx @@ -0,0 +1,19 @@ +import React from 'react'; +import { createRoot } from 'react-dom/client'; +import { MemoryRouter } from 'react-router-dom'; +import { SocketProvider } from '../../src/context/SocketContext'; +import { AuthContext } from '../../src/context/AuthContext'; +import V2UICard from '../../src/v2/cards/V2UICard'; +import '../../src/v2/v2.css'; +import '@fontsource/ibm-plex-sans/400.css'; +import '@fontsource/ibm-plex-sans/600.css'; +import '@fontsource/ibm-plex-mono/500.css'; +const sources = [ + 'root = Card("Release assessment", [Text("The change preserves identity and existing grants."), Steps([Step("Read the patch", "done"), Step("Check the release", "active", "CI is running"), Step("Publish", "pending")]), DiffSummary([File("frontend/src/v2/cards/V2UICard.tsx", 84, 12), File("backend/config/uiCardCatalogue.json", 30, 2)]), Link("Open pull request", "https://github.com/Team-Commonly/commonly/pull/2675", "primary")], "4 minutes ago", "The catalogue uses the same Signal tokens as the shell.")', + 'root = Card("Project state", [TaskStatus("TASK-498", "Agent note: ready for review"), KeyValue([Pair("Repository", "Team-Commonly/commonly"), Pair("Tests", 71)]), Badge("Review pending", "pending"), List(["The component API is fixed", "The trace persists"], true)])', + 'root = Card("Verification", [Table([Col("Surface"), Col("Width", "number"), Col("Result")], [["Pod chat", 1440, "Ready"], ["Pod chat", 390, "Ready"]]), RunTrace(3)])', + 'root = Card("Links", [Text(["Source: ", Link("GitHub", "https://github.com/Team-Commonly/commonly", "text")]), Link("Unapproved host", "https://github.com.evil.test/", "button"), Badge("Done", "done")])', + 'root = Text(@Run("unsafe"))', +]; +const auth = { token:null, currentUser:null, user:null, loading:false, error:null, isAuthenticated:false } as any; +createRoot(document.getElementById('root')!).render(
{sources.map((source, i) => )}
); diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 34c22cdbc4..cef586344f 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -18,7 +18,10 @@ "@fontsource/ibm-plex-sans": "^5.3.0", "@mui/icons-material": "^5.11.16", "@mui/material": "^5.12.1", + "@openuidev/lang-core": "1.0.1", + "@openuidev/react-lang": "1.0.1", "@sentry/react": "^10.65.0", + "ajv": "8.20.0", "axios": "^1.3.4", "chart.js": "^4.5.0", "d3": "^7.9.0", @@ -35,7 +38,8 @@ "react-i18next": "^17.0.10", "react-markdown": "^10.1.0", "react-router-dom": "^6.11.0", - "socket.io-client": "^4.7.2" + "socket.io-client": "^4.7.2", + "zod": "4.6.7" }, "devDependencies": { "@babel/core": "^7.24.0", @@ -2718,6 +2722,23 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/@eslint/eslintrc/node_modules/ajv": { + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz", + "integrity": "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, "node_modules/@eslint/eslintrc/node_modules/globals": { "version": "13.24.0", "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", @@ -2733,6 +2754,13 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/@eslint/eslintrc/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, "node_modules/@eslint/eslintrc/node_modules/type-fest": { "version": "0.20.2", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", @@ -4419,6 +4447,91 @@ "node": ">= 8" } }, + "node_modules/@openuidev/devtools": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@openuidev/devtools/-/devtools-0.3.0.tgz", + "integrity": "sha512-eT6+IUWNBL4k5JANAgKC03tQwutafBdTrAwTfVhhTherllk0R+5W/E4j64j1oBnNSlReRDwETyrGwyhHAwiMfA==", + "license": "MIT", + "dependencies": { + "lucide-react": "^0.575.0" + }, + "peerDependencies": { + "@openuidev/observability": ">=0.0.4 <0.1.0", + "@openuidev/react-lang": ">=1.0.0 <2.0.0", + "react": "^18.3.1 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@openuidev/react-lang": { + "optional": true + } + } + }, + "node_modules/@openuidev/lang-core": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@openuidev/lang-core/-/lang-core-1.0.1.tgz", + "integrity": "sha512-4vBa7FRM6C4v4aCvBAmAtTgFWiEQiNTazG9h4Xy9fC6P/p6+9kZu4RdTyLToBEvdxrYn/gDy/PakEH8PU3lUcw==", + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "ci-info": "^4.4.0" + }, + "peerDependencies": { + "@modelcontextprotocol/sdk": ">=1.0.0", + "zod": "^3.25.0 || ^4.0.0" + }, + "peerDependenciesMeta": { + "@modelcontextprotocol/sdk": { + "optional": true + } + } + }, + "node_modules/@openuidev/lang-core/node_modules/ci-info": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.4.0.tgz", + "integrity": "sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@openuidev/observability": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/@openuidev/observability/-/observability-0.0.4.tgz", + "integrity": "sha512-4fjIrWu3TqTlfDE/m7cG10CH1vV7wQk5GPwMOmXeF9vJtkg92dg4Bdk3AjKgud7H7Xypwwjgt52VcLGZCE2CJQ==", + "license": "MIT" + }, + "node_modules/@openuidev/react-lang": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@openuidev/react-lang/-/react-lang-1.0.1.tgz", + "integrity": "sha512-jt5AKWyKe73BjD+bRC2kKerHCeAurI/D9KMQvbi736963D2lehpPGAvVGoxAN4MG6sM/7OOlfWvErQBPPPx30A==", + "license": "MIT", + "dependencies": { + "@openuidev/devtools": "^0.3.0", + "@openuidev/lang-core": "^1.0.1", + "@openuidev/observability": "^0.0.4" + }, + "peerDependencies": { + "@modelcontextprotocol/sdk": ">=1.0.0", + "react": "*", + "react-dom": "*", + "zod": "^3.25.0 || ^4.0.0" + }, + "peerDependenciesMeta": { + "@modelcontextprotocol/sdk": { + "optional": true + }, + "react-dom": { + "optional": true + } + } + }, "node_modules/@popperjs/core": { "version": "2.11.8", "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", @@ -5859,15 +5972,15 @@ } }, "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.20.0.tgz", + "integrity": "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==", + "license": "MIT", "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" }, "funding": { "type": "github", @@ -8377,6 +8490,23 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/eslint/node_modules/ajv": { + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz", + "integrity": "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, "node_modules/eslint/node_modules/globals": { "version": "13.24.0", "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", @@ -8392,6 +8522,13 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/eslint/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, "node_modules/eslint/node_modules/type-fest": { "version": "0.20.2", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", @@ -8610,8 +8747,7 @@ "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" }, "node_modules/fast-glob": { "version": "3.3.3", @@ -8653,6 +8789,22 @@ "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "dev": true }, + "node_modules/fast-uri": { + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.9.tgz", + "integrity": "sha512-hS/0Wt3Ya043oKXs0sIxrMpKQITXhMLIrVAKKXi4gozGC9v7YRWVnXIZzjNPTO02M9BdxLCWqK1yRXgNziVyJQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, "node_modules/fastq": { "version": "1.19.1", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", @@ -12304,10 +12456,10 @@ "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" }, "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "license": "MIT" }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", @@ -12500,6 +12652,15 @@ "yallist": "^3.0.2" } }, + "node_modules/lucide-react": { + "version": "0.575.0", + "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.575.0.tgz", + "integrity": "sha512-VuXgKZrk0uiDlWjGGXmKV6MSk9Yy4l10qgVvzGn2AWBx1Ylt0iBexKOAoA6I7JO3m+M9oeovJd3yYENfkUbOeg==", + "license": "ISC", + "peerDependencies": { + "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, "node_modules/lz-string": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz", @@ -14297,6 +14458,15 @@ "node": ">=0.10.0" } }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/requireindex": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/requireindex/-/requireindex-1.1.0.tgz", @@ -15561,6 +15731,7 @@ "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "punycode": "^2.1.0" } @@ -16094,6 +16265,15 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/zod": { + "version": "4.6.7", + "resolved": "https://registry.npmjs.org/zod/-/zod-4.6.7.tgz", + "integrity": "sha512-g8W2D2kU6a8untc053fX1uVBKzM7yqAxW/3zwk83+6RyF2+SKOuV+c0wBDhUwzV1PaGapmZH+rmcUzPf+3CGwg==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, "node_modules/zwitch": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", diff --git a/frontend/package.json b/frontend/package.json index 4e8ddb2deb..dcd27991b2 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -13,7 +13,10 @@ "@fontsource/ibm-plex-sans": "^5.3.0", "@mui/icons-material": "^5.11.16", "@mui/material": "^5.12.1", + "@openuidev/lang-core": "1.0.1", + "@openuidev/react-lang": "1.0.1", "@sentry/react": "^10.65.0", + "ajv": "8.20.0", "axios": "^1.3.4", "chart.js": "^4.5.0", "d3": "^7.9.0", @@ -30,17 +33,19 @@ "react-i18next": "^17.0.10", "react-markdown": "^10.1.0", "react-router-dom": "^6.11.0", - "socket.io-client": "^4.7.2" + "socket.io-client": "^4.7.2", + "zod": "4.6.7" }, "scripts": { "start": "vite", "build": "vite build && node scripts/generate-seo-pages.mjs", "preview": "vite preview", - "test": "jest --watchAll=false --forceExit && node --test scripts/generate-seo-pages.test.mjs scripts/nginx-routing.test.mjs", + "test": "jest --watchAll=false --forceExit && node --test scripts/generate-seo-pages.test.mjs scripts/nginx-routing.test.mjs scripts/ui-card-catalogue.test.mjs", "test:coverage": "jest --coverage --watchAll=false --forceExit", "typecheck": "tsc --noEmit", "lint": "eslint src --ext .js,.jsx,.ts,.tsx", - "lint:fix": "eslint src --ext .js,.jsx,.ts,.tsx --fix" + "lint:fix": "eslint src --ext .js,.jsx,.ts,.tsx --fix", + "sync:ui-catalogue": "node scripts/sync-ui-card-catalogue.mjs" }, "devDependencies": { "@babel/core": "^7.24.0", diff --git a/frontend/scripts/sync-ui-card-catalogue.mjs b/frontend/scripts/sync-ui-card-catalogue.mjs new file mode 100644 index 0000000000..69de08ad4e --- /dev/null +++ b/frontend/scripts/sync-ui-card-catalogue.mjs @@ -0,0 +1,14 @@ +import { readFileSync, writeFileSync } from 'node:fs'; + +// Backend and frontend Docker contexts cannot import across their roots. +// Keep the shipped copy byte-identical, including positional property order. +const canonical = new URL('../../backend/config/uiCardCatalogue.json', import.meta.url); +const generated = new URL('../src/v2/cards/uiCardCatalogue.json', import.meta.url); +const source = readFileSync(canonical); +if (process.argv.includes('--check')) { + if (!source.equals(readFileSync(generated))) { + throw new Error('UI card catalogue differs. Run node frontend/scripts/sync-ui-card-catalogue.mjs'); + } +} else { + writeFileSync(generated, source); +} diff --git a/frontend/scripts/ui-card-catalogue.test.mjs b/frontend/scripts/ui-card-catalogue.test.mjs new file mode 100644 index 0000000000..391462ed86 --- /dev/null +++ b/frontend/scripts/ui-card-catalogue.test.mjs @@ -0,0 +1,9 @@ +import { test } from 'node:test'; +import assert from 'node:assert/strict'; +import { readFileSync } from 'node:fs'; + +test('frontend card grammar is byte-identical to the server grammar', () => { + const canonical = readFileSync(new URL('../../backend/config/uiCardCatalogue.json', import.meta.url)); + const generated = readFileSync(new URL('../src/v2/cards/uiCardCatalogue.json', import.meta.url)); + assert.deepEqual(generated, canonical, 'Run node frontend/scripts/sync-ui-card-catalogue.mjs'); +}); diff --git a/frontend/src/v2/__tests__/v2-layout-invariants.test.ts b/frontend/src/v2/__tests__/v2-layout-invariants.test.ts index 134fcf3ea2..1175ed2067 100644 --- a/frontend/src/v2/__tests__/v2-layout-invariants.test.ts +++ b/frontend/src/v2/__tests__/v2-layout-invariants.test.ts @@ -4973,3 +4973,14 @@ test('TASK-435 runtime columns can shrink on phones without dropping the observe expect(ruleBody(css, '.v2-runtime-controls__observed')).toContain('overflow-wrap: anywhere'); expect(css).toContain('content: attr(data-label)'); }); + + +test('OpenUI cards keep the approved phone controls and table records', () => { + const css = read('../cards/uiCard.css'); + expect(css).toContain('@media (max-width:760px)'); + expect(css).toMatch(/\.ui-ft \.ub\{height:44px/); + expect(css).toContain('.ui-table--records .ui-tw { display:none; }'); + expect(css).toContain('.ui-table--records .ui-recs { display:grid; }'); + expect(css).toContain('.v2-root .v2-msg.v2-ui-card { display:flex; flex-direction:column;'); + expect(css).toContain('.ui.gone{border-style:dashed'); +}); diff --git a/frontend/src/v2/cards/V2UICard.tsx b/frontend/src/v2/cards/V2UICard.tsx new file mode 100644 index 0000000000..cb57bf0b44 --- /dev/null +++ b/frontend/src/v2/cards/V2UICard.tsx @@ -0,0 +1,39 @@ +import React, { Component, lazy, Suspense, useEffect, useState } from 'react'; +import type { V2Message } from '../hooks/useV2PodDetail'; +import { parseCard } from './uiCardSource'; +import { CardContext, TraceLink } from './cardViews'; +import './uiCard.css'; + +const Runtime = lazy(() => { + // OpenUI's development entry auto-mounts an inspector by default. Commonly + // intentionally uses only the headless renderer in every environment. + (globalThis as Record)[Symbol.for('openui.devtools.autoMount')] = true; + return import('./cardRuntime'); +}); +class RenderBoundary extends Component<{ children: React.ReactNode; fallback: React.ReactNode }, { failed: boolean }> { + state = { failed: false }; + static getDerivedStateFromError() { return { failed: true }; } + render() { return this.state.failed ? this.props.fallback : this.props.children; } +} +function CardBody({ message }: { message: V2Message }) { + const [failed, setFailed] = useState(false); + const [now, setNow] = useState(Date.now); + useEffect(() => { const timer = setInterval(() => setNow(Date.now()), 60_000); return () => clearInterval(timer); }, []); + const payload = message.payload; + const valid = payload?.v === 1 && payload?.lang === 'openui@1' && !!parseCard(payload?.source); + const expired = now >= new Date(message.created_at || message.createdAt || '').getTime() + 30 * 86400_000; + const fallback = <>
{message.content}

This card couldn’t be displayed.

; + if (expired) return

{message.content}

Card expires after 30 days. Trace persists.

; + if (!valid || failed) return
{fallback}
; + return {message.content}}> + setFailed(true)} /> + ; +} +export default function V2UICard({ message, authorLabel, time }: { message: V2Message; authorLabel: string; time?: string }) { + return
+
{authorLabel}{time && <> · }
+ + + +
; +} diff --git a/frontend/src/v2/cards/__tests__/V2UICard.test.tsx b/frontend/src/v2/cards/__tests__/V2UICard.test.tsx new file mode 100644 index 0000000000..6c09c8593d --- /dev/null +++ b/frontend/src/v2/cards/__tests__/V2UICard.test.tsx @@ -0,0 +1,33 @@ +import React from 'react'; +import { TextEncoder } from 'util'; +import { render, screen } from '@testing-library/react'; +import { MemoryRouter } from 'react-router-dom'; +import V2UICard from '../V2UICard'; +import type { V2Message } from '../../hooks/useV2PodDetail'; +Object.assign(global, { TextEncoder }); +const message = (source: string, created_at = new Date().toISOString()): V2Message => ({ + id: 'm1', pod_id: '111111111111111111111111', user_id: 'u1', message_type: 'card', created_at, + content: 'Plain fallback', payload: { kind: 'ui', v: 1, lang: 'openui@1', source }, +}); +const show = (m: V2Message) => render(); +test('renders the real runtime and keeps the agent attribution', async () => { + show(message('root = Card("Result", [Text("Literal