fix: resolve ESM module not found error for kiro-sdk (GH-11)#668
fix: resolve ESM module not found error for kiro-sdk (GH-11)#668GeorgeZhiXu wants to merge 61 commits into
Conversation
…l fixes - Vite base: /claudeui/ for correct asset paths behind nginx subpath - Router basename injected via window.__ROUTER_BASENAME__ - Platform mode (VITE_IS_PLATFORM=true) bypasses internal auth - Home button in sidebar header (desktop + mobile) - API calls prefixed with base path via prefixUrl() - WebSocket URLs (/ws, /shell) prefixed with base path - Icon paths use dynamic base path - Shell spawns with CLAUDE* env vars stripped (prevents nesting detection) - Shell uses user's default shell (zsh on macOS) instead of hardcoded bash - Express serves static files at BASE_PATH mount point - PWA manifest updated for /claudeui/ scope - Default project path set to ~/dev instead of /workspace
SSH-based deployment using appleboy/ssh-action, triggered on push to main. Pulls latest code, installs deps, builds frontend, and restarts the pm2 process.
Move legacy non-git prod directory to a backup before cloning fresh.
The vite base path must be set during `npm run build` so asset URLs in the built HTML are prefixed with /claudeui/. Without it, nginx rewrites cause 404s for /assets/* requests.
SetupForm had a hardcoded /logo.svg path and index.html had a hardcoded /manifest.json path, both ignoring the VITE_BASE_PATH. This caused 404s when served behind a gateway with a sub-path like /claudeui/.
Like VITE_BASE_PATH, this is a Vite build-time variable that must be set during npm run build. Without it, the frontend shows the login/ setup page instead of bypassing auth in platform mode.
Browsers fetch <link rel="manifest"> without cookies by default, causing the auth gateway to return a 302 redirect instead of the JSON file. Adding crossorigin="use-credentials" sends the auth cookie with the manifest request.
Files in public/ are served as-is without Vite processing, so icon paths need the /claudeui/ prefix hardcoded.
- Add opus[1m] (Opus with 1M context) to Claude model dropdown - Add /api/cli/claude/config endpoint that reads the model from ~/.claude/settings.json and maps Bedrock model IDs to SDK shortnames - Frontend fetches Claude config on load and uses CLI-configured model as default (localStorage selection takes precedence on subsequent loads)
- Remove localStorage saving for Claude model to let CLI config be the default - Model from ~/.claude/settings.json now always takes priority on page load - User selections during session are still preserved but don't persist across page loads
…mini auth, add opus[1m], delete legacy .jsx files
Adds Kiro — AWS's agentic IDE built on Claude — as a supported provider in CloudUI, following the same patterns as Codex, Gemini, and Cursor CLI. ## What's added **Backend (server)** - `server/kiro-cli.js` — spawns `kiro` binary, streams NDJSON output via WebSocket with a proper line-buffer to handle partial TCP chunks - `server/providers/kiro/adapter.js` — normalises Kiro CLI events and session history into NormalizedMessage format - `server/routes/kiro.js` — DELETE /api/kiro/sessions/:sessionId endpoint - `server/providers/registry.js` — registers kiroAdapter - `server/providers/types.js` — adds 'kiro' to SessionProvider typedef - `server/routes/agent.js` — kiro provider validation + dispatch branch - `server/routes/messages.js` — JSDoc updated to include 'kiro' - `server/projects.js` — getKiroSessions() + getKiroCliSessionMessages(), wired into both project discovery loops; kiroSessions: [] in all shapes - `server/index.js` — mounts kiro router, adds kiro to VALID_PROVIDERS, watch paths, WS dispatch, abort/status/active-sessions handlers - `shared/modelConstants.js` — KIRO_MODELS constant (Claude models) **Frontend** - `src/components/chat/hooks/useChatComposerState.ts` — kiro-command WS dispatch branch; kiroModel threaded through - `src/components/chat/hooks/useChatProviderState.ts` — kiroModel state with localStorage persistence - `src/components/chat/view/ChatInterface.tsx` — passes kiroModel down - `src/components/chat/view/subcomponents/ChatMessagesPane.tsx` — kiroModel prop chain - `src/components/chat/view/subcomponents/ProviderSelectionEmptyState.tsx` — Kiro card with KIRO_MODELS in the provider selection grid - `src/components/llm-logo-provider/KiroLogo.tsx` — placeholder "K" badge (TODO: replace with official Kiro SVG) - `src/components/llm-logo-provider/SessionProviderLogo.tsx` — kiro branch - `src/components/provider-auth/types.ts` — 'kiro' in CliProvider - `src/components/settings/types/types.ts` — 'kiro' in AgentProvider - `src/components/settings/view/.../AgentSelectorSection.tsx` — 'kiro' in AGENT_PROVIDERS and AGENT_NAMES - `src/components/onboarding/view/utils.ts` — 'kiro' in cliProviders and createInitialProviderStatuses - `src/components/sidebar/types/types.ts` — isKiroSession flag - `src/components/sidebar/utils/utils.ts` — kiro session handling - `src/hooks/useProjectsState.ts` — kiroSessions change detection - `src/types/app.ts` — 'kiro' in SessionProvider union, kiroSessions field ## Known TODOs (needs Kiro CLI investigation) Several parts are stubs pending confirmation of actual Kiro CLI behaviour: - CLI argument flags (--prompt, --resume, --model, --output-format) - NDJSON event schema (field names for message/tool_use/tool_result events) - Session storage path (assumed ~/.kiro/sessions/) See siteboon#574 for investigation plan. Resolves siteboon#574 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… parsing Fixes all issues raised in the PR review: - Use correct Kiro CLI flags: kiro chat --no-interactive [--resume <id>] [--agent <name>] <message> per official docs. Removes non-existent --prompt, --model, --output-format, --yolo flags. - Optional watcher path: don't mkdir ~/.kiro/sessions on startup for users who don't have Kiro installed (optional: true in PROVIDER_WATCH_PATHS) - Fix JSONL parsing: parse line-by-line in getKiroSessions() and getKiroCliSessionMessages() instead of whole-file JSON.parse - Filter unscoped sessions: skip Kiro sessions with no projectPath to prevent them appearing under every project - Honor pagination contract in fetchHistory (limit/offset/hasMore/total) - Enable resume for disk-discovered sessions (fall back to sessionId directly) - Move processKey declaration before notifyTerminalState closure - Flush lineBuffer on process close to prevent truncated responses - Add Kiro label to provider text chains in ChatInterface.tsx - Type KiroLogo props for TypeScript strict mode - Add ownership-check TODO in routes/kiro.js (consistent with gemini pattern) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds all missing provider keys for Kiro in every locale file:
- messageTypes.kiro in chat.json (en, de, ko, ru, zh-CN, ja)
- providerSelection.providerInfo.kiro in chat.json (all 6)
- providerSelection.readyPrompt.kiro in chat.json (all 6, locale-appropriate)
- agents.account.kiro.description in settings.json (all 6)
- Defensive { defaultValue: 'Kiro' } on both t('messageTypes.kiro') calls
in ChatInterface.tsx
Also fills pre-existing ja locale gaps (missing gemini in messageTypes,
readyPrompt, and providerInfo.google) for consistency.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adding 'kiro' to AgentProvider required updating all Record<AgentProvider, ...> objects that TypeScript now enforces exhaustively: - settings/constants/constants.ts — add kiro to AUTH_STATUS_ENDPOINTS - AgentListItem.tsx — add kiro to agentConfig (name/color) - AgentsSettingsTab.tsx — add kiro stub to agentContextById (no auth flow yet) - AccountContent.tsx — add kiro to agentConfig (name/colors/description) All 4 TypeScript errors are resolved. Build and typecheck now pass cleanly. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replaces the no-op Kiro stub with real props-driven auth state, following
the exact gemini pattern at every layer:
- useSettingsController.ts: add kiroAuthStatus state, fix
setAuthStatusByProvider (kiro was falling through to setCodexAuthStatus —
a real bug), add mount-time checkAuthStatus('kiro'), expose in return
- AgentsSettingsTabProps types.ts: add kiroAuthStatus + onKiroLogin props
- AgentsSettingsTab.tsx: wire props into agentContextById.kiro + useMemo deps
- Settings.tsx: pass kiroAuthStatus + onKiroLogin={openLoginForProvider('kiro')},
add kiro branch to isAuthenticated ternary (also fixes missing gemini branch)
typecheck passes cleanly.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Extra `}` at end of checkGeminiCredentials() was crashing the server on startup.
- Add Home to lucide-react imports in SidebarHeader (was causing "Home is not defined" runtime error) - Use BASE_URL for service worker registration so it works under /claudeui/ subpath - Remove duplicate SW registration from index.html (main.jsx handles it)
Derive BASE from self.location so all paths (manifest, icons, navigation) resolve correctly when served under /claudeui/.
- fix kiro-cli binary name (kiro -> kiro-cli) - fix kiro session discovery path (~/.kiro/sessions/cli/) - fix kiro session format: session_id, cwd, updated_at, title fields - fix kiro message history parsing (NDJSON with kind/data structure) - update kiro model list to match kiro-cli available models - fix --resume flag (no argument), --model instead of --agent - add kiro provider label in MessageComponent, ClaudeStatus, ThinkingIndicator - support comma-separated WORKSPACES_ROOT for multiple allowed roots - add ALLOW_SYMLINKS=true env var to permit symlinked workspace paths
- scaffold kiro-sdk package wrapping kiro-cli acp via JSON-RPC 2.0 - query() returns AsyncGenerator<KiroMessage> matching claude-agent-sdk pattern - typed events: assistant, tool_use, tool_progress, result - control methods: interrupt(), setModel() - singleton ACP transport with session multiplexing - rewrite server/kiro-cli.js to use ACP instead of chat --no-interactive - fix kiro session history: structured tool_use/tool_result blocks - fix kiro adapter: prefer disk sessions over stale sessionManager data - fix message ordering with synthetic incrementing timestamps
- SessionRouter: register, push, iterate, finish, fullText aggregation, error handling - AcpTransport: connect, sendRpc, error responses, notifications, partial lines, disconnect - Public API: session lifecycle, resume, interrupt, sessionId property
- initialize: verifies agent capabilities and protocol version - session/new: validates session creation with ID, modes, models - MCP notifications: confirms server_initialized and commands_available - session/prompt: skipped — kiro-cli 1.29.3 exits on prompt (tracked)
- field name: content → prompt in session/prompt params - notification method: session/notification → session/update - event types: AgentMessageChunk → agent_message_chunk, TurnEnd → turn_end - content structure: update.text → update.content.text - handle stopReason in prompt response for turn completion - unskip integration test: session/prompt now works - all 19 unit tests + 4 integration tests pass
# Conflicts: # src/components/chat/view/subcomponents/AssistantThinkingIndicator.tsx # src/components/settings/types/types.ts
Adds a test that exercises the actual code path claudecodeui uses: query() → async generator → stream assistant chunks → result. Verifies: - assistant chunks and result message are yielded - streamed text content is correct - result.text aggregates the full response - sessionId is populated - CRITICAL: first assistant chunk arrives BEFORE the result message, proving streaming works (not buffered until turn end) This would have caught both the await-blocking bug and the broken notification handler brace bug.
Two bugs:
1. Every message created a new ACP session because the SDK always called
session/new, ignoring the resume option. Tested that kiro-cli 1.29.8
supports sending multiple session/prompt calls on the same sessionId
without session/load. SDK now skips session/new when resume is set.
2. First characters of responses were truncated ('!' instead of 'Hey!',
"'s Monday" instead of "It's Monday"). The session_created message
and first stream_delta were emitted in the same for-await iteration,
so the frontend received content before it had navigated to the new
session. Restructured kiro-cli.js to emit session_created before any
stream_delta messages.
Applied resume fix to both TS and Python SDKs.
The dist/ was stale (April 10) while source was modified multiple times. The server imports from dist/ via the file: symlink, so none of the SDK fixes (session resume, streaming order, notification handler) were active. - Rebuilt dist/ with tsc - Added 'prepare' script so npm install auto-builds - Track dist/ in git (override root .gitignore) since the server depends on it - Server restart required to pick up the new code
dist/ should not be tracked — it's a build artifact. Instead: - Root package.json: added 'build:sdk' script (npm run build --prefix kiro-sdk) - 'postinstall' runs build:sdk so fresh clones/installs get a built SDK - 'dev' and 'build' run build:sdk before starting - kiro-sdk/package.json already has 'prepare: tsc' as a safety net This ensures the SDK is always rebuilt from source before the server starts, without committing generated files.
Vite doesn't replace %VAR% syntax in HTML — only import.meta.env.* in JS. The server was sending the literal string %VITE_BASE_PATH% to the browser, causing URIError when the router tried to decode it as a URL path. Replace at serve-time using the already-resolved BASE_PATH variable.
Browsers with cached old HTML have the literal %VITE_BASE_PATH% in URLs, causing Express to throw URIError on decodeURIComponent. The error handler returns 400 instead of crashing the server. The root cause (unsubstituted variable) was already fixed in the previous commit — this just prevents the server from crashing on stale client requests.
# Conflicts: # package.json
# Conflicts: # shared/modelConstants.js
Auto-sync upstream (conflicts resolved by Claude Code)
# Conflicts: # package.json # src/components/onboarding/view/utils.ts # src/components/provider-auth/types.ts # src/components/settings/constants/constants.ts # src/components/settings/hooks/useSettingsController.ts # src/components/settings/types/types.ts # src/components/settings/view/Settings.tsx # src/components/settings/view/tabs/agents-settings/AgentsSettingsTab.tsx # src/components/settings/view/tabs/agents-settings/types.ts # src/types/app.ts
Auto-sync upstream (conflicts resolved by Claude Code)
- Replace Kiro text span with proper SVG icon (AWS orange with "K") - Add window.__ROUTER_BASENAME__ to Gemini icon path for /claudeui/ deployment
- Downloaded official Kiro icon SVG from https://kiro.dev/icon.svg - Added icon to public/icons/kiro-icon.svg - Updated KiroLogo component to use the actual icon file
# Conflicts: # package-lock.json # server/routes/cli-auth.js # src/utils/api.js
Auto-sync upstream (conflicts resolved by Claude Code)
…H-11, chunk 1) The kiro-sdk local package was missing its package.json, causing ERR_MODULE_NOT_FOUND when the server tried to import from 'kiro-sdk'. - Create kiro-sdk/package.json with ESM exports pointing to dist/index.js - Update .gitignore to track kiro-sdk/package.json while ignoring dist/ - Update package-lock.json to reflect the configured local package
…ecords [SDEGen] GH-11: Resolve merge conflict in src/types/app.ts by keeping LLMProvider type name while adding 'kiro' from HEAD branch. Update Record<LLMProvider, ...> usages in provider-auth types and AgentsSettingsTab to include kiro entries, fixing TypeScript build errors.
|
Caution Review failedPull request was closed or merged during review 📝 WalkthroughWalkthroughIntegrates a new AI provider called "Kiro" (AWS Agentic IDE) across frontend and backend, adding provider selection UI, model configuration, CLI session management, deployment workflows, and internationalization support. Also implements base-path deployment support and kiro-sdk as a local dependency. Changes
Sequence DiagramsequenceDiagram
participant Client as Client UI
participant Server as Server
participant SDK as Kiro SDK
participant FS as Filesystem
Client->>Server: Send kiro-command message<br/>(command, model, sessionId?)
Server->>SDK: spawnKiro(command, options)<br/>Create AbortController
SDK->>SDK: query() async generator
SDK-->>Server: assistant message delta
Server->>Server: normalizeMessage() →<br/>stream_delta event
Server-->>Client: stream_delta
SDK-->>Server: tool_use event
Server->>Server: normalizeMessage() →<br/>tool_use event
Server-->>Client: tool_use
SDK-->>Server: tool_result event
Server->>Server: normalizeMessage() →<br/>tool_result event
Server-->>Client: tool_result
SDK-->>Server: result/complete
Server->>Server: Generate/emit<br/>session_created
Server-->>Client: session_created<br/>(with sessionId)
Server->>FS: Save session to<br/>~/.kiro/sessions/cli/
SDK-->>Server: Complete/error
Server->>Server: normalizeMessage() →<br/>stream_end/complete
Server-->>Client: complete event
Client->>Client: Update chat UI<br/>with messages
Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Summary
Related Issue
Fixes GH-11
Changes
package.jsontokiro-sdkwith propertype: "module"andexportsconfigurationapp.tsError Fixed
Testing
Summary by CodeRabbit
New Features
Improvements
Documentation