Migrate cua-cli to CuaAgentHarness runtime - #14
Conversation
Route print, interactive, and action flows through @onkernel/cua-agent/@onkernel/cua-ai with harness-native session repos so transcript persistence and resume behavior use the shared AgentHarness primitives. Co-authored-by: Cursor <cursoragent@cursor.com>
Execute fixture-main via tsx with source conditions so ptywright-driven TUI e2e tests no longer fail on ESM extensionless imports in dist output. Co-authored-by: Cursor <cursoragent@cursor.com>
Prepend the resolved Zig binary directory to PATH for build-ghostty subprocesses so combine_archives can invoke `zig ar` even when Zig is only installed under .dev/tools. Co-authored-by: Cursor <cursoragent@cursor.com>
Introduce an env-gated ptywright live test for OpenAI+Kernel flows and wire it into CI (non-draft PRs and main) with Zig installation and native ptywright build. Co-authored-by: Cursor <cursoragent@cursor.com>
Use explicit .js import specifiers in ptywright's ESM entrypoints so cli-e2e can resolve dist modules in Node. Add a Yutori harness test termination guard to avoid non-deterministic multi-round tool loops timing out in agent-e2e. Co-authored-by: Cursor <cursoragent@cursor.com>
|
Firetiger deploy monitoring skipped This PR didn't match the auto-monitor filter configured on your GitHub connection:
Reason: PR modifies cua-cli package and agent runtime, but does not change API endpoints (packages/api/cmd/api/) or Temporal workflows (packages/api/lib/temporal) that the filter specifies. To monitor this PR anyway, reply with |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
Autofix Details
Bugbot Autofix prepared a fix for the issue found in the latest run.
- ✅ Fixed: Dead
unsubscribePersistvariable left from migration- Removed the unused
unsubscribePersistdeclaration, redundant reassignment, and no-op cleanup call fromrunInteractivebecause persistence is already handled by the harness.
- Removed the unused
Or push these changes by commenting:
@cursor push 0bee1c46f1
Preview (0bee1c46f1)
diff --git a/packages/cua-cli/src/tui/main.ts b/packages/cua-cli/src/tui/main.ts
--- a/packages/cua-cli/src/tui/main.ts
+++ b/packages/cua-cli/src/tui/main.ts
@@ -146,7 +146,6 @@
});
};
- let unsubscribePersist = () => {};
const sm = opts.sessionState;
if (liveHandle && sm) await appendBrowserMetadata(sm, opts.browser);
if (liveHandle && sm && opts.resumed) {
@@ -154,7 +153,6 @@
`resumed from ${sm.getSessionFile() ?? "memory"} · ${sm.priorMessageCount} prior messages · fresh browser`,
);
}
- unsubscribePersist = () => {};
let driver: InteractiveDriver =
opts.driver ?? new LiveInteractiveDriver(liveHandle!, { skipInitialScreenshot: opts.resumed === true });
@@ -339,7 +337,6 @@
} finally {
removeListener();
unsubscribe();
- unsubscribePersist();
tui.stop();
try {
await driver.dispose();You can send follow-ups to the cloud agent here.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
Autofix Details
Bugbot Autofix prepared a fix for the issue found in the latest run.
- ✅ Fixed: Redundant
resumedprop duplicatessessionState.resumed- I removed the separate
InteractiveOptions.resumedfield and now derive resume behavior directly fromsessionState.resumedat use sites to eliminate duplicate state.
- I removed the separate
Or push these changes by commenting:
@cursor push afca7c44df
Preview (afca7c44df)
diff --git a/packages/cua-cli/src/cli.ts b/packages/cua-cli/src/cli.ts
--- a/packages/cua-cli/src/cli.ts
+++ b/packages/cua-cli/src/cli.ts
@@ -884,7 +884,6 @@
debugTui: flags.debugTui,
imageProtocol: flags.imageProtocol,
sessionState: sm,
- resumed: sm.resumed,
skills: startupResources.skills,
startupResources,
});
diff --git a/packages/cua-cli/src/tui/main.ts b/packages/cua-cli/src/tui/main.ts
--- a/packages/cua-cli/src/tui/main.ts
+++ b/packages/cua-cli/src/tui/main.ts
@@ -41,8 +41,6 @@
imageProtocol?: string;
/** Optional harness-native session state for transcript persistence. */
sessionState?: CuaSessionState;
- /** True when seeding the agent from a previously persisted session. */
- resumed?: boolean;
/** Skills available for /skill:name expansion and system-prompt injection. */
skills?: Skill[];
/** Optional startup sections mirroring pi's Context/Skills inventory. */
@@ -148,15 +146,16 @@
let unsubscribePersist = () => {};
const sm = opts.sessionState;
+ const resumed = sm?.resumed === true;
if (liveHandle && sm) await appendBrowserMetadata(sm, opts.browser);
- if (liveHandle && sm && opts.resumed) {
+ if (liveHandle && sm && resumed) {
messages.addNotice(
`resumed from ${sm.getSessionFile() ?? "memory"} · ${sm.priorMessageCount} prior messages · fresh browser`,
);
}
unsubscribePersist = () => {};
let driver: InteractiveDriver =
- opts.driver ?? new LiveInteractiveDriver(liveHandle!, { skipInitialScreenshot: opts.resumed === true });
+ opts.driver ?? new LiveInteractiveDriver(liveHandle!, { skipInitialScreenshot: resumed });
let assistantBuffer: AssistantBuffer | undefined;
let inflight = 0;You can send follow-ups to the cloud agent here.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
Bugbot Autofix prepared a fix for the issue found in the latest run.
- ✅ Fixed: New exported interfaces lack required TSDoc comments
- Added TSDoc comments to both exported interfaces
SessionInfoandCuaSessionStateinpackages/cua-cli/src/sessions.tsto document their purpose and usage semantics.
- Added TSDoc comments to both exported interfaces
Or push these changes by commenting:
@cursor push 75a8d44ff4
Preview (75a8d44ff4)
diff --git a/packages/cua-cli/src/sessions.ts b/packages/cua-cli/src/sessions.ts
--- a/packages/cua-cli/src/sessions.ts
+++ b/packages/cua-cli/src/sessions.ts
@@ -29,6 +29,7 @@
parentSession?: string;
}
+/** Display-oriented metadata for a persisted session in session list and resume selection flows. */
export interface SessionInfo {
path: string;
id: string;
@@ -41,6 +42,12 @@
firstMessage: string;
}
+/**
+ * Runtime session bundle shared by CLI flows after opening or resuming a session.
+ *
+ * `resumed` and `priorMessageCount` describe whether existing transcript history was loaded,
+ * and `getSessionFile()` returns the persisted JSONL path (or `undefined` for ephemeral sessions).
+ */
export interface CuaSessionState {
env: NodeExecutionEnv;
session: Session;You can send follow-ups to the cloud agent here.
Reviewed by Cursor Bugbot for commit e17af3e. Configure here.
| resumed: boolean; | ||
| priorMessageCount: number; | ||
| getSessionFile(): string | undefined; | ||
| } |
There was a problem hiding this comment.
New exported interfaces lack required TSDoc comments
Low Severity
The newly introduced exported interfaces CuaSessionState and SessionInfo lack TSDoc-style comments explaining their purpose. These are key types used across the CLI for session management and are exported for use by other modules, so newcomers would benefit from documentation explaining what they represent.
Additional Locations (1)
Triggered by learned rule: Exported types, interfaces, and classes require TSDoc
Reviewed by Cursor Bugbot for commit e17af3e. Configure here.



Summary
cua-cliprint, interactive, and action flows through@onkernel/cua-agent'sCuaAgentHarnessinstead of wiringpi-agent-coreAgentdirectlySessionManagerpersistence plumbing with harness-native session primitives (JsonlSessionRepo/InMemorySessionRepo+NodeExecutionEnv) while preserving resume/session selection behavior@onkernel/cua-aiand remove direct provider package wiring fromcua-cliTest plan
npm run --workspace @onkernel/cua-cli buildnpm run --workspace @onkernel/cua-cli test(fails in this environment: missing ptywright native dependency toolchain;zignot installed)Made with Cursor
Note
Medium Risk
Refactors core
cua-cliexecution and session persistence paths onto@onkernel/cua-agent/@onkernel/cua-ai, which can change agent behavior and resume semantics across providers. Adds new live CI coverage, but failures would primarily affect CLI runtime and session files rather than data security.Overview
Migrates
cua-clifrom directpi-agent-corewiring to@onkernel/cua-agent’sCuaAgentHarness, including switching model discovery/loading to@onkernel/cua-airuntime specs and consolidating computer tool wiring viacreateCuaComputerTools.Replaces
SessionManagerpersistence with harness-native sessions (JsonlSessionRepo/InMemorySessionRepo+NodeExecutionEnv), updating print/action/interactive flows to passCuaSessionStateand compute resume/initial-screenshot behavior from stored context.Adds a new live CLI TUI e2e smoke test (and CI job that installs Zig + builds
ptywrightnative) and tweaks agent live tests to terminate Yutori after the first completed tool batch for determinism; also adjustsptywrightESM exports/imports for.jspaths.Reviewed by Cursor Bugbot for commit e17af3e. Bugbot is set up for automated code reviews on this repo. Configure here.