name: t3-vx-apps-integration-workflow
description: Use when adding, changing, or debugging T3 Code integration with Vortex app wrappers, especially vx apps list --json, vx apps <target> artifacts ..., app catalog data, app target IDs, app-scoped server RPCs, NativeApi methods, or UI features driven by configured Vortex apps. Triggers on vx apps, Vortex apps, app catalog, target_id, app wrappers, app-scoped artifacts, server.listVortexApps, server.listVortexAppArtifacts, or adding app data to navigation/artifacts pages.
T3 Vortex Apps Integration Workflow
Use this skill whenever T3 Code needs to call or model vx apps ... output.
The integration boundary must stay server-side. Browser code must not shell out or assume local filesystem paths are readable directly.
Current Integration Shape
Primary files:
packages/contracts/src/server.ts- Owns app catalog, artifact list, and cache result schemas.
packages/contracts/src/ipc.ts- Owns
NativeApi.server.*method types.
- Owns
packages/contracts/src/ws.ts- Owns WebSocket method tags and request body schemas.
apps/server/src/vortexApps/Services/VortexApps.ts- Owns service interface and typed errors.
apps/server/src/vortexApps/Layers/VortexApps.ts- Runs
vx apps ..., decodes JSON, handles pagination, and returns typed results.
- Runs
apps/server/src/wsServer.ts- Routes WebSocket RPC methods to the service.
apps/server/src/serverLayers.ts- Provides the service layer.
apps/web/src/wsNativeApi.ts- Maps browser NativeApi methods to WebSocket RPCs.
apps/web/src/lib/vortexAppsReactQuery.ts- Owns browser query options and query keys.
App Catalog Pattern
Configured apps come from:
vx apps list --json
Do not hard-code the app list in UI code.
Expected key fields:
projects[].target_id: stable selector for follow-up wrapper commands.projects[].display_name: user-facing label.projects[].name: repo directory name.projects[].path: workspace path.projects[].installed: whether the repo is present.
When the browser needs configured apps:
- Add or reuse a server RPC.
- Decode command output with Effect Schema in contracts/server-side code.
- Cache server-side if repeated shelling is expensive.
- Fetch in the browser through NativeApi + React Query.
App-Scoped Artifact Pattern
Use app wrappers for artifact lists:
vx apps <target> artifacts list --json --limit 100 --page <n>
Include archived artifacts only when the UI explicitly requests them:
vx apps <target> artifacts list --json --limit 100 --page <n> --include-archived
The wrapper caps large limits, so page until backend pagination is complete.
Preferred result shape in T3:
target_idfetched_attotal_resultsartifacts
Artifact records are pass-through metadata objects. Known useful fields include:
titlepathpreviewrepocreatedAtkindstatuspinnedarchivedarchivedAtthreadIdplanKeyworkerupdatedAtmay be absent; usecreatedAtas the fallback for recently-updated ordering.
Do not over-normalize artifact records unless a consumer needs a stable field. Keep the raw record available so future UI can use new metadata without another server change.
For UI metadata helpers, normalize only the fields needed for stable display/routing and keep the original record alongside them. If title is absent, derive the display/routing fallback from the artifact path basename without a trailing .md.
Adding a New Vx Apps RPC
Follow this order:
- Add schemas/types in
packages/contracts/src/server.ts. - Add NativeApi method type in
packages/contracts/src/ipc.ts. - Add WS method tag and request schema in
packages/contracts/src/ws.ts. - Add service method in
apps/server/src/vortexApps/Services/VortexApps.ts. - Implement command execution and decoding in
apps/server/src/vortexApps/Layers/VortexApps.ts. - Route the WS method in
apps/server/src/wsServer.ts. - Add the browser transport mapping in
apps/web/src/wsNativeApi.ts. - Add React Query options in
apps/web/src/lib/*ReactQuery.tsif UI code will call it.
If a contracts type changes and the localized dev server is running, restart it through the repo-local surface so contracts are rebuilt:
bash scripts/dev/dev.sh stop --json
bash scripts/dev/dev.sh start --json --mode dev
See .claude/skills/t3-local-dev-server-workflow/SKILL.md for the full
lifecycle and JSON contract.
For optional request flags such as includeArchived, keep the field optional in contracts and only send it from the browser when true unless the server requires an explicit false. This keeps the browser compatible during local restart windows.
Command Execution Rules
Use runProcess from apps/server/src/processRunner.ts.
Set explicit safety bounds:
cwd: useServerConfig.cwdtimeoutMs: command-specific, not infinitemaxBufferBytes: large enough for expected JSONallowNonZeroExit: default false unless the wrapper documents non-zero as data
Never parse CLI JSON with ad hoc string slicing. Use Schema.decodeEffect(Schema.fromJsonString(...)).
Map errors into a tagged service error that includes:
- operation
- human-readable detail
- original cause
UI Consumption Rules
- Use
ensureNativeApi()in query functions. - Use stable query keys.
- Include meaningful request options in query keys. For example,
listVortexAppArtifacts(targetId, includeArchived)needs distinct keys for active-only and archived-inclusive lists. - Do not call NativeApi directly from render.
- Do not duplicate app catalog state into component-local state unless it is transient UI state.
- Use display names for labels and target IDs for route/cache keys.
Artifact metadata can include absolute paths outside the target app workspace, commonly under a shared knowledge/artifact store. If a UI needs file content, first try the existing workspace read helper path. If it cannot safely read the absolute artifact path, add the smallest read-only server RPC rather than broadening unrelated write APIs.
Artifact detail routes may use preloaded artifact metadata for instant display, but should refetch server.listVortexAppArtifacts on mount and write the fresh response back through the artifact preload cache helper. This keeps localStorage current without waiting for the background 5 minute preloader.
Footguns
- Do not call
vx apps ...from the browser. - Do not hard-code app targets in
SidebarBrandHeader.tsxor artifacts UI. - Do not forget to rebuild/restart after contracts changes.
- Do not add WS tags without updating
NativeApiandwsNativeApi. - Do not fetch only page 1 when pagination reports more pages.
- Do not use the active-only artifact preload cache as the source of truth for archived-inclusive views.
- Do not assume
titleis always present; path-derived fallback slugs must strip.md. - Do not assume all repos expose every wrapper; check wrapper support if adding a new workflow.
- Do not use deprecated
vx projects ...aliases.
Validation
At minimum for RPC changes:
bash scripts/dev/dev.sh status --json
Then exercise the WebSocket RPC directly or through the UI.
For final repo completion, run:
bun fmt
bun lint
bun typecheck
Never run bun test; use bun run test if tests are needed.