Skip to content

feat: wire kortex-cli init and add CLI logging#1231

Open
bmahabirbu wants to merge 2 commits intokortex-hub:mainfrom
bmahabirbu:workspace-create-flow
Open

feat: wire kortex-cli init and add CLI logging#1231
bmahabirbu wants to merge 2 commits intokortex-hub:mainfrom
bmahabirbu:workspace-create-flow

Conversation

@bmahabirbu
Copy link
Copy Markdown
Contributor

Summary

  • Wire up kortex-cli init from the workspace create UI form (name, agent, source path, runtime)
  • Add console.log for all kortex-cli commands (init, list, remove, start, stop) with error logging
  • Add AgentWorkspaceCreateOptions type, IPC handler, and preload bridge for create
  • Resolve CLI path from CliToolRegistry with fallback to kortex-cli from PATH
  • UI fields not yet supported by kortex-cli (skills, MCP servers, file access) are kept in the form but not sent to the backend

Test plan

  • 28 unit tests pass for AgentWorkspaceManager
  • Manual: create workspace via UI, verify Executing: log appears in terminal
  • Manual: trigger an error (e.g. invalid path), verify kortex-cli failed: log and red error banner in UI

🤖 Generated with Claude Code

bmahabirbu and others added 2 commits April 3, 2026 01:34
Wire up create IPC handler, resolve CLI path from CliToolRegistry,
and connect the renderer form to the backend.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Brian <bmahabir@bu.edu>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Brian <bmahabir@bu.edu>
@bmahabirbu bmahabirbu requested a review from a team as a code owner April 3, 2026 05:58
@bmahabirbu bmahabirbu requested review from benoitf and fbricon and removed request for a team April 3, 2026 05:58
@codecov
Copy link
Copy Markdown

codecov bot commented Apr 3, 2026

Codecov Report

❌ Patch coverage is 74.54545% with 14 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
...c/lib/agent-workspaces/AgentWorkspaceCreate.svelte 33.33% 10 Missing ⚠️
.../plugin/agent-workspace/agent-workspace-manager.ts 94.44% 2 Missing ⚠️
packages/preload/src/index.ts 33.33% 2 Missing ⚠️

📢 Thoughts on this report? Let us know!

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 3, 2026

📝 Walkthrough

Walkthrough

A new workspace creation feature is added through the agent workspace subsystem. The changes introduce a AgentWorkspaceCreateOptions type for creation inputs, extend AgentWorkspaceManager with CLI execution and dynamic path resolution via dependency injection, register an IPC handler for workspace creation, expose a createAgentWorkspace preload API, and update the UI component to handle async creation with loading and error states.

Changes

Cohort / File(s) Summary
Type Definitions
packages/api/src/agent-workspace-info.ts
Added new exported interface AgentWorkspaceCreateOptions with required fields sourcePath and agent, and optional fields runtime, name, and project.
Manager Implementation
packages/main/src/plugin/agent-workspace/agent-workspace-manager.ts
Added create() method to execute kortex-cli workspace init command with resolved CLI path from injected CliToolRegistry. Extended execKortex() helper to support execution options and dynamic CLI path resolution. Added agent-workspace:create IPC handler registration with event emission for workspace creation.
Manager Tests
packages/main/src/plugin/agent-workspace/agent-workspace-manager.spec.ts
Introduced CliToolRegistry mock and KORTEX_CLI_PATH constant to test setup. Added test coverage for IPC handler registration, CLI path fallback behavior, and full create() workflow including command construction, JSON parsing, event emission, and error handling. Updated existing tests to use resolved CLI path and include third exec.exec argument.
Dependency Injection
packages/main/src/plugin/index.ts
Moved CliToolRegistry singleton binding earlier in initialization phase to avoid duplicate binding after AuthenticationImpl setup.
Preload API
packages/preload/src/index.ts
Added AgentWorkspaceCreateOptions to type imports. Exposed new createAgentWorkspace() async function via contextBridge that invokes the agent-workspace:create IPC channel.
UI Component
packages/renderer/src/lib/agent-workspaces/AgentWorkspaceCreate.svelte
Converted startWorkspace() to async function with expanded validation for sessionName, workingDir, and selectedAgent. Added creating and error state management, error banner display, and button state/label updates reflecting the async creation workflow.

Sequence Diagram

sequenceDiagram
    actor User
    participant Renderer as Renderer (UI)
    participant Preload as Preload Bridge
    participant Main as Main Process (IPC)
    participant CLI as kortex-cli

    User->>Renderer: Fill form & click "Start Workspace"
    Renderer->>Renderer: Validate inputs (sessionName, workingDir, agent)
    Renderer->>Renderer: Set creating=true, clear error
    Renderer->>Preload: createAgentWorkspace(options)
    Preload->>Main: IPC send 'agent-workspace:create'
    Main->>Main: Resolve kortex-cli path via CliToolRegistry
    Main->>CLI: Execute: kortex-cli workspace init<br/> --sourcePath --agent<br/> --runtime [--name] [--project]<br/> --output json
    CLI-->>Main: Return JSON with workspace ID
    Main->>Main: Parse JSON & emit<br/>'agent-workspace-update'
    Main-->>Preload: Return AgentWorkspaceId
    Preload-->>Renderer: Resolve Promise
    Renderer->>Renderer: Set creating=false
    Renderer->>Renderer: Navigate to AGENT_WORKSPACES
    Renderer-->>User: Show workspace list
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main changes: wiring up kortex-cli init functionality and adding CLI command logging.
Description check ✅ Passed The description is detailed and directly related to the changeset, covering the main objectives, implementation details, and test plan.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/renderer/src/lib/agent-workspaces/AgentWorkspaceCreate.svelte (1)

121-131: ⚠️ Potential issue | 🟠 Major

Remove the full renderer-side config dump.

This logs a superset of the actual IPC payload — free-form description, local/custom paths, skill IDs, and MCP IDs — even though most of those fields are intentionally not sent to the backend. In this codebase renderer console output is retained for troubleshooting export, so this becomes a privacy leak and a misleading trace.

✂️ Proposed fix
-  const config = {
-    name: sessionName,
-    workingDir,
-    description,
-    agent: selectedAgent,
-    fileAccess: selectedFileAccess,
-    customPaths: selectedFileAccess === 'custom' ? customPaths.filter(p => p.trim()) : undefined,
-    skills: selectedSkillIds,
-    mcpServers: selectedMcpIds,
-  };
-  console.log('Starting workspace with config:', config);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/renderer/src/lib/agent-workspaces/AgentWorkspaceCreate.svelte`
around lines 121 - 131, The console.log emitting the full renderer-side config
(the const config object created from sessionName, workingDir, description,
selectedAgent, selectedFileAccess, customPaths, selectedSkillIds,
selectedMcpIds) must be removed or replaced with a minimal/sanitized log; do not
print free-form description, customPaths, skill IDs, or MCP IDs. Update the code
around the config variable in AgentWorkspaceCreate.svelte so that either the
console.log line is deleted or it only logs non-sensitive fields (e.g.,
sessionName and selectedAgent) and explicitly omits description, customPaths,
selectedSkillIds, and selectedMcpIds.
🧹 Nitpick comments (1)
packages/main/src/plugin/agent-workspace/agent-workspace-manager.spec.ts (1)

124-188: Add assertions for the new CLI logging behavior.

The PR adds command/error logging, but the spec currently validates only command execution/results. Add log/error expectations to prevent regressions.

Example test additions
 test('executes kortex-cli init with required flags and returns the workspace id', async () => {
+  const logSpy = vi.spyOn(console, 'log').mockImplementation(() => undefined);
   vi.spyOn(exec, 'exec').mockResolvedValue(mockExecResult(JSON.stringify({ id: 'ws-new' })));

   const result = await manager.create(defaultOptions);

+  expect(logSpy).toHaveBeenCalledWith(expect.stringContaining('Executing:'));
   expect(exec.exec).toHaveBeenCalledWith(KORTEX_CLI_PATH, [
     'init',
     '/tmp/my-project',
@@
   expect(result).toEqual({ id: 'ws-new' });
 });

 test('rejects when CLI fails', async () => {
+  const errorSpy = vi.spyOn(console, 'error').mockImplementation(() => undefined);
   vi.spyOn(exec, 'exec').mockRejectedValue(new Error('command not found'));

   await expect(manager.list()).rejects.toThrow('command not found');
+  expect(errorSpy).toHaveBeenCalledWith(expect.stringContaining('kortex-cli failed:'));
 });

Also applies to: 214-218

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/main/src/plugin/agent-workspace/agent-workspace-manager.spec.ts`
around lines 124 - 188, Tests currently assert exec.exec calls and results but
not the new CLI logging; update the tests that mock exec.exec and call
manager.create to also assert the logger methods are invoked: for successful
runs (the tests that mockResolvedValue) add an expectation that logger.info (or
the module's CLI logger used in the implementation) was called with the executed
command/args (matching KORTEX_CLI_PATH and the args array), and for the failure
test (the one that mockRejectedValue) add an expectation that logger.error was
called with the thrown error message. Reference the existing mocks around
exec.exec and manager.create when adding these assertions so you modify the same
test cases (including the test around lines 214-218).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/main/src/plugin/agent-workspace/agent-workspace-manager.spec.ts`:
- Line 27: The imported type named Proxy shadows the global Proxy and triggers
the lint rule; rename the import to a non-conflicting alias (e.g., ProxyType) in
the import statement in agent-workspace-manager.spec.ts and update all
references to that type within the file (search for usages of Proxy and replace
with the new alias) so the linter no longer flags noShadowRestrictedNames while
preserving the same type.

In `@packages/main/src/plugin/agent-workspace/agent-workspace-manager.ts`:
- Around line 74-95: The create method shells out via this.exec.exec in
agent-workspace-manager.ts but doesn't use TaskManager so long-running init
calls can outlive UI; update create(AgentWorkspaceCreateOptions) to create and
run a Task via TaskManager (e.g., createTask/runTask) around the call to
this.exec.exec, publish incremental status (starting, success, failure) and wire
cancellation to abort the exec if TaskManager supports it, then send the
existing this.apiSender.send('agent-workspace-update') on success and rethrow
errors after marking the task failed; ensure you reference the create method,
this.exec.exec call, TaskManager APIs you have in the codebase, and keep
existing JSON parsing of result.stdout and error logging behavior.

In `@packages/renderer/src/lib/agent-workspaces/AgentWorkspaceCreate.svelte`:
- Around line 136-140: The create call in AgentWorkspaceCreate.svelte currently
invokes window.createAgentWorkspace with only sourcePath, agent and name which
causes AgentWorkspaceManager.create() to default runtime to 'podman'; update the
call to include the runtime selected in the UI (e.g., pass runtime: runtime or
runtime: selectedRuntime alongside sourcePath: workingDir, agent: selectedAgent,
name: sessionName) so the UI's runtime selection is forwarded to
window.createAgentWorkspace and ultimately to AgentWorkspaceManager.create().

---

Outside diff comments:
In `@packages/renderer/src/lib/agent-workspaces/AgentWorkspaceCreate.svelte`:
- Around line 121-131: The console.log emitting the full renderer-side config
(the const config object created from sessionName, workingDir, description,
selectedAgent, selectedFileAccess, customPaths, selectedSkillIds,
selectedMcpIds) must be removed or replaced with a minimal/sanitized log; do not
print free-form description, customPaths, skill IDs, or MCP IDs. Update the code
around the config variable in AgentWorkspaceCreate.svelte so that either the
console.log line is deleted or it only logs non-sensitive fields (e.g.,
sessionName and selectedAgent) and explicitly omits description, customPaths,
selectedSkillIds, and selectedMcpIds.

---

Nitpick comments:
In `@packages/main/src/plugin/agent-workspace/agent-workspace-manager.spec.ts`:
- Around line 124-188: Tests currently assert exec.exec calls and results but
not the new CLI logging; update the tests that mock exec.exec and call
manager.create to also assert the logger methods are invoked: for successful
runs (the tests that mockResolvedValue) add an expectation that logger.info (or
the module's CLI logger used in the implementation) was called with the executed
command/args (matching KORTEX_CLI_PATH and the args array), and for the failure
test (the one that mockRejectedValue) add an expectation that logger.error was
called with the thrown error message. Reference the existing mocks around
exec.exec and manager.create when adding these assertions so you modify the same
test cases (including the test around lines 214-218).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: e0d0d8d6-0491-4f5f-aa3d-d76b0e0ccad4

📥 Commits

Reviewing files that changed from the base of the PR and between b8a233e and 24ce8b8.

📒 Files selected for processing (6)
  • packages/api/src/agent-workspace-info.ts
  • packages/main/src/plugin/agent-workspace/agent-workspace-manager.spec.ts
  • packages/main/src/plugin/agent-workspace/agent-workspace-manager.ts
  • packages/main/src/plugin/index.ts
  • packages/preload/src/index.ts
  • packages/renderer/src/lib/agent-workspaces/AgentWorkspaceCreate.svelte


import type { IPCHandle } from '/@/plugin/api.js';
import type { CliToolRegistry } from '/@/plugin/cli-tool-registry.js';
import type { Proxy } from '/@/plugin/proxy.js';
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
rg -n "import type \{ Proxy( as .+)? \}" packages/main/src/plugin/agent-workspace/agent-workspace-manager.spec.ts
rg -n "as unknown as Proxy\\b" packages/main/src/plugin/agent-workspace/agent-workspace-manager.spec.ts

Repository: kortex-hub/kortex

Length of output: 138


🏁 Script executed:

#!/bin/bash
# Get full context around the import and usage
sed -n '25,65p' packages/main/src/plugin/agent-workspace/agent-workspace-manager.spec.ts | cat -n

# Search for all uses of "Proxy" (not just imports) in the file to ensure fix is complete
rg -n "\bProxy\b" packages/main/src/plugin/agent-workspace/agent-workspace-manager.spec.ts

Repository: kortex-hub/kortex

Length of output: 1701


Rename imported Proxy type to avoid lint-blocking global shadowing.

The Proxy import at line 27 shadows the global Proxy object, triggering lint/suspicious/noShadowRestrictedNames and blocking CI.

Proposed fix
-import type { Proxy } from '/@/plugin/proxy.js';
+import type { Proxy as KortexProxy } from '/@/plugin/proxy.js';
...
-} as unknown as Proxy;
+} as unknown as KortexProxy;
🧰 Tools
🪛 Biome (2.4.9)

[error] 27-27: Do not shadow the global "Proxy" property.

(lint/suspicious/noShadowRestrictedNames)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/main/src/plugin/agent-workspace/agent-workspace-manager.spec.ts` at
line 27, The imported type named Proxy shadows the global Proxy and triggers the
lint rule; rename the import to a non-conflicting alias (e.g., ProxyType) in the
import statement in agent-workspace-manager.spec.ts and update all references to
that type within the file (search for usages of Proxy and replace with the new
alias) so the linter no longer flags noShadowRestrictedNames while preserving
the same type.

Comment on lines +74 to 95
async create(options: AgentWorkspaceCreateOptions): Promise<AgentWorkspaceId> {
const cliPath = this.getCliPath();
const runtime = options.runtime ?? 'podman';
const args = ['init', options.sourcePath, '--runtime', runtime, '--agent', options.agent, '--output', 'json'];
if (options.name) {
args.push('--name', options.name);
}
if (options.project) {
args.push('--project', options.project);
}
console.log(`Executing: ${cliPath} ${args.join(' ')}`);
try {
const result = await this.exec.exec(cliPath, args);
const workspaceId = JSON.parse(result.stdout) as AgentWorkspaceId;
this.apiSender.send('agent-workspace-update');
return workspaceId;
} catch (err: unknown) {
const message = err instanceof Error ? err.message : String(err);
console.log(`kortex-cli failed: ${cliPath} ${args.join(' ')} — ${message}`);
throw err;
}
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major

Track init through TaskManager.

This shells out to an external CLI and can easily outlive the form-local spinner, but it never creates a task or publishes status the rest of the app can observe. Mirroring the other main-process CLI flows here would give users durable progress and failure reporting even if they navigate away. As per coding guidelines, "Long-running operations should use TaskManager to create and manage tasks with appropriate status updates".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/main/src/plugin/agent-workspace/agent-workspace-manager.ts` around
lines 74 - 95, The create method shells out via this.exec.exec in
agent-workspace-manager.ts but doesn't use TaskManager so long-running init
calls can outlive UI; update create(AgentWorkspaceCreateOptions) to create and
run a Task via TaskManager (e.g., createTask/runTask) around the call to
this.exec.exec, publish incremental status (starting, success, failure) and wire
cancellation to abort the exec if TaskManager supports it, then send the
existing this.apiSender.send('agent-workspace-update') on success and rethrow
errors after marking the task failed; ensure you reference the create method,
this.exec.exec call, TaskManager APIs you have in the codebase, and keep
existing JSON parsing of result.stdout and error logging behavior.

Comment on lines +136 to +140
await window.createAgentWorkspace({
sourcePath: workingDir,
agent: selectedAgent,
name: sessionName,
});
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Forward runtime in the create request.

This call only sends sourcePath, agent, and name. Because AgentWorkspaceManager.create() defaults a missing runtime to 'podman', the new flow still hard-codes the default instead of propagating runtime from the UI.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/renderer/src/lib/agent-workspaces/AgentWorkspaceCreate.svelte`
around lines 136 - 140, The create call in AgentWorkspaceCreate.svelte currently
invokes window.createAgentWorkspace with only sourcePath, agent and name which
causes AgentWorkspaceManager.create() to default runtime to 'podman'; update the
call to include the runtime selected in the UI (e.g., pass runtime: runtime or
runtime: selectedRuntime alongside sourcePath: workingDir, agent: selectedAgent,
name: sessionName) so the UI's runtime selection is forwarded to
window.createAgentWorkspace and ultimately to AgentWorkspaceManager.create().

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant