Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
121 changes: 19 additions & 102 deletions apps/daemon/src/mcp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1796,111 +1796,28 @@ export async function runMcpStdio(options: RunMcpOptions): Promise<void> {
instructions: [
MCP_SERVER_INSTRUCTIONS,
'',
'OpenDesign (OD) is a local-first design workspace. The user typically',
'has OD running on their machine; each project contains a rendered',
'artifact (HTML/JSX/CSS) plus its source files.',
'OpenDesign (OD) is a local-first design workspace.',
'',
'Active context: get_artifact, get_project, get_file, search_files,',
'and list_files all accept project as OPTIONAL. When omitted, they',
'default to the project the user has open in OD right now; get_file',
'and get_artifact additionally default to the active file. So when',
'the user says "this file" / "the design I have open" / "find X",',
'just call the tool without project - no need to ask first. The',
'response carries usedActiveContext so you can confirm which',
'project/file you hit. Pass project explicitly to override.',
'GENERATING / REFINING DESIGNS (OD spawns its own inner agent):',
'- collect_brief first for new artifacts unless user asks to skip. Confirm brief card; never show draft IDs/nonces.',
'- list_skills / list_plugins to discover capabilities. list_agents before start_run.agent (do not guess IDs).',
'- Cloud mode: check login status first; if signed out, call sign-in tool and show activation URL/code.',

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Restore polling until Cloud sign-in is complete. This line now stops after initiating the browser/device flow and showing its activation data, but the changed instructions previously required polling the login-status tool until loggedIn:true. The sign-in tool can return while loginInFlight is still true (as covered by apps/daemon/tests/mcp-vela-login.test.ts), so a host following this shortened sequence can call start_run before authentication completes. Keep the compact wording, for example: ‘If signed out, call sign-in, show activation URL/code, then poll login status until loggedIn:true.’

🔁 Powered by Looper · runner=reviewer · agent=codex · An autonomous AI dev team for your GitHub repos.

'- create_project(name) first if needed; start_run requires an existing project.',
'- start_run(prompt, requestId, [skill], [plugin], [inputs]) starts generation. Generate UUID requestId once per action; reuse verbatim on retries.',
'- Poll get_run(runId) every 30–60s until terminal. Runs take 5–30m; unchanged files = inner agent thinking, NOT a hang. Do NOT cancel or use write_file unless user explicitly asks to abort.',

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Separate the cancellation exception from the write_file prohibition. Grammatically, ‘Do NOT cancel or use write_file unless user explicitly asks to abort’ permits both actions after an abort request, even though write_file is never an abort mechanism and the replaced guidance forbade substituting it for the generation pipeline. That can make a host mutate project files while attempting to stop a run. Use unambiguous compact wording such as: ‘Never substitute write_file. Cancel only if the user explicitly asks to abort.’

🔁 Powered by Looper · runner=reviewer · agent=codex · An autonomous AI dev team for your GitHub repos.

'- On failureAction:"recharge", show rechargeUrl. After top-up, call original start_run with same requestId and resume:true.',
'- On success, get_run returns previewUrl (open in browser) and agentMessage. Use get_artifact for source files.',
'',
'Pulling design context:',
' - get_artifact() - entry file PLUS every referenced sibling',
' (tokens CSS, JSX modules, imported assets) in one call.',
' PREFER THIS over multiple get_file calls when the user',
' wants to understand or extend a design.',
' - get_file(path) for a single known file. Returns up to 2000',
' lines starting at offset (default 0) and stamps a',
' [od:file-window ...] marker when the file is longer; page',
' by re-calling with the next offset.',
' - search_files(query) to find a class/component/copy string',
' without fetching every file.',
' - list_files for metadata only.',
' - create_artifact(name, content) to create one normal artifact',
' entry file in the active or specified project. It rejects',
' existing targets and can accept an artifactManifest sidecar.',
' - write_file(path, content) to overwrite or freshly create any',
' project file when an ArtifactManifest is not required.',
' Use this to iterate on a file create_artifact already wrote.',
' - delete_file(path) to remove one project file (nested paths ok).',
' - delete_project(project, confirm:true) for irreversible project',
' removal — requires explicit project + confirm:true.',
' - list_projects to discover what is available on this daemon.',
' - get_active_context() if you want the active project/file',
' explicitly without making any other tool call.',
'READING & EDITING FILES:',
'- project arg is OPTIONAL for file/project tools. Defaults to user\'s active project/file in OD (expires ~5m).',
'- Prefer get_artifact() over multiple get_file calls to pull entry + referenced siblings in one call.',
'- write_file(path, content) to edit/create files; create_artifact for initial entry files.',
'- delete_project requires explicit project arg and confirm:true.',
'- Resources: od://design-systems/<id>/DESIGN.md for brand spec; od://skills/<id>/SKILL.md for skills.',
'',
'To make OpenDesign GENERATE or refine a design (rather than just',
'read/edit files), commission a run - you do not run skills yourself:',
' - collect_brief first for a new artifact unless the user explicitly',
' asks to skip questions. Let the user complete the rendered card;',
' confirm_brief returns the readable brief to reuse with OpenDesign',
' Cloud or Local Codex. Never print or ask the user to copy',
' briefDraftId, nonce, or any other internal correlation value.',
' - list_skills / list_plugins to see what you can ask OD to make.',
' - for OpenDesign Cloud, call the Cloud login-status tool first.',
' If signed out, call the Cloud sign-in tool once, show its activation',
' URL/code when present, and poll login status until loggedIn:true.',
' The tool and runtime ids are internal protocol; never show them.',
' - list_agents when you need to pass start_run.agent — do not',
' guess "claude" / "codex" / "opencode"; only agents in the',
' returned list will actually spawn on this machine.',
' - create_project(name) first if you need a fresh project to',
' generate into; start_run requires an existing project.',
' - start_run(prompt, requestId, [skill], [plugin], [inputs]) kicks off',
' generation in the active or named project and returns a runId.',
' Generate a canonical UUID or ULID requestId once per confirmed',
' user action and reuse the exact same value after a timeout/lost',
' response. Do not call',
' start_run again while get_run reports the original run in flight.',
' If get_run returns failureAction:"recharge", show rechargeUrl;',
' after the user confirms top-up, call the exact original start_run',
' once with the same requestId and resume:true.',
' OpenDesign spawns its own agent to do the work.',
' - get_run(runId) polls until status is succeeded/failed/canceled;',
' on success it returns a previewUrl you can open in a browser',
' and a hint to pull the files with get_artifact.',
' - cancel_run(runId) aborts an in-flight run.',
'',
'Generation patience: OpenDesign runs typically take 5–30',
'minutes. Polls returning status:running with unchanged file',
'mtimes is the inner agent thinking, not a hang. Do NOT cancel',
'and substitute write_file as a "faster" workaround — that',
'throws away the pipeline\'s design quality and is exactly the',
'failure mode this surface is meant to avoid. Poll every 30–60',
'seconds, tell the user "still working" between polls, and let',
'the run finish. Only call cancel_run if the user explicitly',
'asks you to abort.',
'',
'Ambiguous-format requests: words like "PPT" / "deck" / "slides" /',
'"presentation" / "document" / "PDF" / "doc" map to two different',
'deliverables — OpenDesign natively produces browser-viewable',
'HTML/SVG (including HTML-rendered decks), but the user may want a',
'real binary file (.pptx / .docx / .pdf) which OpenDesign does NOT',
'produce and which you would have to export yourself from OD\'s',
'output. When the user\'s request is ambiguous, ASK them which one',
'they want before kicking off work; do not silently pick one and do',
'not run both paths in parallel.',
'',
'Project arguments accept either a UUID or a name substring',
'(e.g. "recaptr"); the server resolves the latter. When a project',
'is matched by slug or substring the response carries',
'resolvedProject:{id,name} so you can confirm which project was',
'resolved. Verify with the user if the match was unexpected.',
'',
'Reference material is exposed as MCP resources, not tools - read',
'od://design-systems/<id>/DESIGN.md when you need the brand spec',
'for a design (palette, typography, voice). Skills are similarly',
'available at od://skills/<id>/SKILL.md but are mostly relevant',
'when the user asks about how a particular artifact was generated.',
'',
'When extending an OpenDesign design in another codebase, pull',
'the full bundle once with get_artifact and work from those files',
'locally - do not fetch files one-by-one if you can avoid it.',
'AMBIGUOUS REQUESTS & RESOLUTION:',
'- "PPT"/"deck"/"doc"/"PDF" can mean native HTML or binary export (.pptx/.pdf). Ask user which before starting.',
'- Project args accept UUID or name substring (check resolvedProject in response).',
].join('\n'),
},

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a regression test for the fully assembled server instructions, including MCP_SERVER_INSTRUCTIONS. The PR’s stated bug is exceeding a 2,048-character host cap, but these changed lines have no executable guard; on this head the complete payload is already 2,026 UTF-8 bytes, leaving only 22 bytes of margin, and the follow-up cancellation edit increased it after the author’s documented 1,974-character check. A small future wording fix can therefore silently recreate the truncation. Extract/export the assembled instruction string (or a focused builder), then assert in apps/daemon/tests/ that Buffer.byteLength(instructions, 'utf8') <= 2048 and that the critical run/login/cancellation phrases remain present.

🔁 Powered by Looper · runner=reviewer · agent=codex · An autonomous AI dev team for your GitHub repos.

);
Expand Down
Loading