Read Connect Codex or Claude Code to Studio for setup, the local engine and model data flow, account and billing ownership, and the applicable provider conditions. Official local integration support is distinct from certification or permission for a commercial/hosted deployment.
Start a new conversation from Create with AI. Studio creates a draft when you send its first message. Continue saved conversations in Projects → AI drafts, where you can also delete an idle draft after confirmation. The Back button at the far left of the title bar returns to Projects; editing an installed plugin returns to its detail page. Draft management stays outside the conversation header so the workspace focuses on creation, preview and saving.
Open PexarBolt Plugin Studio and choose Create with AI. Vibe uses your installed, authenticated Codex or Claude provider to create a private plugin draft. Inspect its real sandbox preview with sample data, refine checked revisions, then add it to the Studio workspace for testing. Export a .boltplugin to install in the consumer PexarBolt app.
.boltplugin
Tool discovery checks integration capabilities, not a minimum version number. Codex must expose app-server; Claude Code must expose streaming JSON and MCP permission interfaces. The selected engine completes the native protocol handshake and supplies its own model catalog. Desktop discovery includes Codex's bundled engine, ChatGPT's bundled Codex engine and Claude Desktop's downloaded host engine, as well as login-shell PATH, Homebrew and common version-manager paths. A broken or incompatible installation does not hide another usable installation. Version output is informational and may be omitted.
app-server
For Claude Desktop, open the Code tab once to finish downloading its local engine. A chat-only app installation or a VM-only engine is not a local coding interface. Sign in through the provider's normal flow; Studio uses the engine's existing configuration and authentication without extracting tokens. If an older Claude engine lacks auth status, Studio can read non-secret account metadata through the official SDK control protocol, without sending a model prompt. Missing or incompatible integration interfaces produce actionable setup messages instead of an arbitrary upgrade requirement.
auth status
Enter sends a message; Shift+Enter inserts a newline. IME composition and held Enter keys do not submit. With Codex, while the selected draft is running, the Steer button or Enter sends text and attachments into its active turn through turn/steer. Stop remains available separately. Input submitted during startup or local validation waits for an active turn, or starts a follow-up in the same conversation once validation finishes. Stopping cancels waiting submissions. Failed submissions restore the input and attachments; uncertain transport failures are never automatically replayed. Model and sandbox changes continue to apply at the next turn boundary.
turn/steer
Claude displays Queue message during generation: text and attachments wait until the current run (including local validation and repair) finishes, then start a follow-up. Stop cancels waiting submissions. Claude does not claim Codex-style mid-turn steering.
The maintained workflow is .agents/skills/pexarbolt-plugin/SKILL.md. It includes a contract reference and a helper for scaffolding, real sandbox validation and .boltplugin packaging. Codex can discover the repository skill; Claude Code can read the same skill or use an installed skill directory. Example invocation: Use $pexarbolt-plugin to build a focus timer for my Dock.
Use $pexarbolt-plugin to build a focus timer for my Dock.
The desktop build copies the skill and current SDK source into dist-electron/vibe-context. Vibe loads these packaged resources into every new or resumed conversation. Its starter and the standalone scaffold come from electron/vibe/context-kit.ts; validation and sample interaction checks share check-plugin.ts. No firmware checkout or compiler is required for Vibe's embedded Dock preview.
dist-electron/vibe-context
electron/vibe/context-kit.ts
check-plugin.ts
The header's AI tools menu displays the actual skill loading result and opens the directory of the loaded copy. These resources are unpacked in release builds so the folder is accessible in Finder or Explorer. If a required context file is missing or empty, Vibe displays the loading error and prevents generation with incomplete context.
The compact fixed header holds draft selection, creation and deletion. Conversation and preview scroll independently, with the composer always available. Narrow windows switch between Conversation and Preview tabs. Icon editing and revision history are collapsed beneath the preview; tool requests appear above the composer.
The row above the message input contains provider, permission mode, model and reasoning effort, in that order. Provider changes require an idle conversation. Models and permissions persist separately for each provider. Existing installations and drafts default to Codex. Model choices and supported efforts come from the paginated native model/list catalog. Defaults follow the effective Codex configuration; explicit Vibe choices persist alongside permission mode without changing config.toml. Choosing another model resets effort to that model's default. Changes made during generation apply at the next turn and display a pending indicator.
model/list
config.toml
The composer accepts pasted images and copied files, file selection and drag-and-drop. Pending attachments show thumbnails or filenames and can be removed before sending. Limits are 10 files, 20 MiB per file and 50 MiB per message. Images are decoded and normalized to PNG (up to 4096 pixels on the longest edge) and sent as native localImage inputs. Other files are copied into the draft's private workspace and referenced in the message for native tools to inspect. Sent files and thumbnail metadata remain with the conversation across restarts; draft deletion removes them. Attachments are reference material and do not automatically become installed plugin assets. Clipboard reads occur only on an explicit paste action; ordinary text paste remains supported.
localImage
Consecutive agent tool calls of all types share one collapsed transcript entry, including search, commands, file changes, MCP and draft tools. The summary shows the call count and any running or failed calls. Expanding reveals the individual activity, status and time, and stays open as progress arrives. Conversation messages separate groups; existing saved transcripts use the same presentation.
node .agents/skills/pexarbolt-plugin/scripts/plugin.mjs scaffold /tmp/my-plugin node .agents/skills/pexarbolt-plugin/scripts/plugin.mjs validate /tmp/my-plugin node .agents/skills/pexarbolt-plugin/scripts/plugin.mjs package /tmp/my-plugin /tmp/my-plugin.boltplugin
The repository helper needs the workspace dependencies and Electron installed. It refuses to overwrite scaffold directories or package files. Author files retain editable BUILD hash markers; the final package receives hashes in a private snapshot and has no enclosing folder in its ZIP.
Before each message, Desktop rereads the bundled SDK, skill and contract and versions them by content. plugin_read.context contains version, revision, sdk and skill, so rereading a draft refreshes API guidance. Resumed conversations receive changed context without losing drafts or history. Failed or interrupted turns are not marked as having received the new version.
plugin_read.context
Update the SDK, skill and contract together and rebuild Desktop. Bundled copies live in dist-electron/vibe-context; released clients need updating. Folder access is declared with host.imageFolders, not a schema path field, so authors need no speculative API probes.
host.imageFolders
A compatible Codex engine is detected on PATH, common native install paths, or in a supported desktop app; readiness depends on protocol support and the native handshake. Authentication stays with Codex; the client uses account/read and browser login and does not copy credential files. It starts its own stdio app-server and persists the thread id for resuming. This uses an experimental upstream protocol; incompatible versions surface an actionable connection error.
account/read
Resume requests use excludeTurns: true: Codex retains the conversation context, while the desktop uses its locally saved transcript. This avoids returning the full history of tool results and screenshots, which can exceed the 4 MiB transport limit after a single plugin generation. Invalid or oversized responses report the specific connection failure and retain the draft for retry.
excludeTurns: true
Vibe adds client-owned draft tools (read, write, check, preview event and screenshot) to the native Codex tools. Live web search is enabled. MCP servers, apps, plugins, skills and execution tools inherit the installed Codex configuration; availability depends on that app-server, its configuration and authentication. Tools exclusive to the Codex desktop UI are not automatically exported by app-server. The native sandbox and approval policy apply, including when resuming older Vibe threads. Research and supporting files use a private scratch directory per draft; plugin source still goes through plugin_write for validation and revision tracking. Native authoring tools do not become runtime APIs for installed plugins.
plugin_write
Native search and tool activity appear in the transcript. Command/file approvals, turn/session permission requests, questions, standard MCP forms and URL elicitations are presented in Vibe and returned through the Codex app-server protocol. File approval includes the reported changes. Answers remain in memory in the client and are not written to its draft transcript; Codex and the responding server manage their own conversation records. The generation watchdog pauses while waiting for a response. Stop, disconnection and server resolution clear outstanding requests; stale responses cannot approve another draft's operation.
The five-minute generation watchdog measures inactivity, not total turn duration. Messages, reasoning progress, native tool events and Vibe draft tool calls renew it only for the active thread and turn. Long turns can continue while making progress. Waiting for user responses suspends the timer until all pending requests are resolved. Five minutes without activity disconnects the stalled session and preserves the draft for the next message.
The composer uses the official permission-mode names: Ask for approval (workspace-write, on-request, reviewer user), Approve for me (workspace-write, on-request, reviewer auto_review), Full access (danger-full-access, never), and Custom (config.toml) (inherit native settings). Vibe stores the selection in its own settings.json; it does not modify the global Codex configuration. Existing Codex workspace roots and workspace network settings continue to apply. Installed-plugin runtime permissions remain separate.
workspace-write
on-request
user
auto_review
danger-full-access
never
settings.json
Approve for me delegates eligible requests to Codex automatic review; Vibe does not automatically click Allow once. Review results and rationales appear in the conversation. Supported app-servers can switch the reviewer between manual and automatic during a running turn. Already-issued requests retain their original reviewer. Sandbox changes, or reviewer changes unsupported by an older server, show Applies next turn and take effect on the next generation or repair turn. Native account and organization restrictions still apply, and some app prompts require a human response in any mode.
Sources are bounded JSON records under the application's userData/vibe directory, separate from the repository and installed plugins. Writes enforce package-relative paths, allowed file types, case uniqueness, 128 files and a 2 MiB source budget. PNG assets are base64; code and schemas are UTF-8. Validation uses the existing package validator, default configuration validation, real isolated runtime startup, touch events and dial events. All external effects in this check use sample brokers.
userData/vibe
Checked packages are immutable snapshots. Failed edits retain the previous preview and cannot be installed. The client retries a failed generated candidate at most twice, supports Stop, saves conversation history, and keeps up to 20 checked versions per draft and 20 drafts. Screenshot tools render the same trusted Dock component in a private window rather than capturing the user's desktop. Adding or updating a plugin never grants permissions, enables it, or installs it on a device.
Plugins requesting no host permissions can be enabled directly and do not display permission actions. Updates that introduce permissions require explicit consent before starting.
The icon picker beside the Vibe preview saves a selected PNG or JPG into the draft as a 128x128 PNG, with transparent padding to preserve the image's proportions. The manifest's optional icon references that file and the projection declares its hash. Each change passes the normal package checks and becomes a restorable revision; the same source is available to subsequent AI turns and installation. Cancelling or choosing an invalid image leaves the previous icon intact. Plugin details also offer icon selection through the header icon and Settings, plus removal in Settings. These changes preserve running instances and existing code authorization. The declared icon appears in the client and the next SDL session's plugin catalog. Docks advertising catalogIcons v1 automatically receive a thumbnail (72x72 on current firmware, 48x48 on earlier firmware); older firmware shows its default icon.
icon
catalogIcons
The embedded preview uses the firmware's font and navigation assets. SDL fits default images, state variants and dynamic artwork into the same transparent canvas, preserving the projection dimensions and aspect ratio. The LVGL renderer supports the SDK's full 8..48 px font range. Browser and FreeType antialiasing may differ slightly, but layout and image sizing use the same contract.
Requires a compatible local Claude Code engine exposing the integration interfaces. Vibe uses the pinned official TypeScript Agent SDK as a transport, with pathToClaudeCodeExecutable pointing at the detected, unmodified local CLI. It does not ship or patch a Claude binary. Sign in using the App's Sign in button (which runs the CLI's own claude auth login browser flow), or run claude auth login yourself and refresh AI tools. Login attempts stop after five minutes or when the provider closes. Authentication remains owned by Claude Code; Vibe never reads credential files or stores tokens. claude auth status --json is reduced to readiness and authentication category; account identifiers do not enter the renderer.
pathToClaudeCodeExecutable
claude auth login
claude auth status --json
Existing subscription authentication is supported. API keys, managed authentication and other configured Claude providers continue to follow the CLI's own configuration and billing. Vibe does not remove authentication options, inject API keys, change endpoints, or automatically fall back to separately billed API access. The tools menu identifies subscription versus other configured authentication. It is not a billing guarantee: native plan limits and extra-usage settings still apply. No --bare mode is used, because it skips subscription credentials. See Anthropic's current plan notice and running Claude Code in products.
--bare
The model catalog comes from the local CLI via supportedModels() without submitting a model prompt. Claude (default) leaves model and effort selection to the CLI. Explicit model selection exposes only the effort levels in that model's native catalog. Claude uses Default permissions (default, including configured native rules) or Bypass permissions (bypassPermissions, explicitly selected). Neither is a Codex filesystem sandbox. Codex automatic review and config.toml options are not offered for Claude. Permission changes apply next turn, and native organization restrictions still apply.
supportedModels()
default
bypassPermissions
The five private draft tools use the same JSON schemas as Codex, exposed through an in-process SDK MCP server. They are pre-approved as client-owned draft operations; installed-plugin permission grants remain separate. Other native tool requests, up to three single-choice/free-text questions and MCP form/URL elicitations use Vibe's request panel. Multi-select or larger question sets are declined with instructions to ask single-choice questions instead; unrecognized native dialogs are cancelled rather than left waiting indefinitely. Aborted or stopped requests cannot approve a later operation. Native stderr is not shown or saved in the Vibe transcript.
Text streams into the existing transcript; image attachments are sent as native PNG image blocks and other files remain inspectable in the draft workspace. Each turn closes its SDK process after completion and resumes the stored Claude session on the next turn. Codex and Claude keep separate session IDs for a shared draft; switching providers never sends one provider's session ID to the other. Current source and recent visible requirements are supplied when crossing providers. Both reuse the same validation, screenshot, preview, revision, restore and installation pipeline.
Codex and local Claude conversation workflows are implemented on macOS. Claude SDK transport and subscription authentication have a bounded live smoke test; the full generation smoke test also accepts Claude. Installing the development skill in an external Claude Code session remains independent of the in-app provider. The macOS Studio download includes precompiled SDL. Source checkouts can build SDL from the firmware tree. Windows/Linux tool discovery and native Windows SDL remain separate platform verification work; the embedded preview does not require SDL.
pnpm --filter @pexarbolt/plugin-studio type-check pnpm --filter @pexarbolt/plugin-studio test pnpm --filter @pexarbolt/plugin-studio test:vibe:ui pnpm --filter @pexarbolt/plugin-studio test:vibe:live pnpm --filter @pexarbolt/plugin-studio test:vibe:claude pnpm --filter @pexarbolt/plugin-studio test:vibe:claude:ui pnpm --filter @pexarbolt/plugin-studio test:vibe:claude:full pnpm --filter @pexarbolt/plugin-studio test:vibe:platform pnpm --filter @pexarbolt/plugin-studio test:vibe:permissions pnpm --filter @pexarbolt/plugin-studio exec node scripts/test-vibe-input.mjs pnpm --filter @pexarbolt/plugin-studio test:preview-rendering
The UI test includes deterministic Codex and Claude CLI protocol fixtures, with Claude provider/model selection, approval, real SDK MCP-to-sandbox checks and narrow layouts. The UI test needs the desktop Vite server at http://127.0.0.1:5174. It runs an isolated Electron profile and a deterministic Codex protocol fixture, exercising model/effort selection, attachments, native approvals/questions/forms, actual IPC, package store, sandbox, screenshot tool and preview controls across desktop and narrow windows. Screenshots are written under .cache/vibe-ui. The live tests use the installed authenticated Codex and consume model usage. test:vibe:platform combines native web search, a temporary read-only MCP server and a Vibe dynamic tool in one turn; it does not alter saved Codex configuration. test-vibe-input.mjs reads the actual model catalog and verifies explicit model/effort settings and local-image recognition in an ephemeral read-only thread. The generation smoke test creates a counter, resumes after reconnecting, changes behavior, restores a revision and imports the result into an isolated plugin manager. These tests do not touch a physical device or the user's installed plugins.
http://127.0.0.1:5174
.cache/vibe-ui
test:vibe:platform
test-vibe-input.mjs
The rendering test checks image size, transparent padding, variants and dynamic artwork. Set BOLT_HOST_BINARY to a built Host SDL executable to also compare 48 px text bounds in native/browser screenshots. An optional package directory argument captures an existing plugin with its fixture state; output is under .cache/plugin-rendering. Set BOLT_ASSETS_DIR when the firmware's assets are outside the sibling checkout.
BOLT_HOST_BINARY
.cache/plugin-rendering
BOLT_ASSETS_DIR
test:vibe:claude checks native authentication category, model discovery, private MCP read/write and reconnect/resume using a temporary scratch directory. test:vibe:claude:full exercises real Claude generation, the Electron sandbox and preview, interaction, reconnect with refreshed context, revision restore and import into an isolated profile. Both consume usage under the local CLI authentication. They do not change authentication, grant installed-plugin permissions or operate hardware.
test:vibe:claude
test:vibe:claude:full
test:vibe:claude:ui runs the focused Claude UI scenario with a deterministic CLI protocol fixture, without a model call. It verifies model/provider selection, native approval, the SDK MCP bridge to the real preview sandbox, persisted speaker labels and desktop/narrow layouts. It needs the same Vite server as the complete UI suite.
test:vibe:claude:ui