Skip to content

Commit 0e01461

Browse files
authored
CLI agent: align pi-tui with other pi-* deps and restore annotation tools (#3336)
1 parent 872fcba commit 0e01461

7 files changed

Lines changed: 87 additions & 63 deletions

File tree

apps/cli/ai/tools/index.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { installTaxonomyScriptsTool } from './install-taxonomy-scripts';
1010
import { listPreviewsTool } from './list-previews';
1111
import { listSitesTool } from './list-sites';
1212
import { auditPerformanceTool } from './need-for-speed';
13+
import { openAnnotationBrowserTool } from './open-annotation-browser';
1314
import { previewNavigateTool } from './preview-navigate';
1415
import { previewReloadTool } from './preview-reload';
1516
import { pullSiteTool } from './pull-site';
@@ -22,6 +23,7 @@ import { stopSiteTool } from './stop-site';
2223
import { takeScreenshotTool } from './take-screenshot';
2324
import { updatePreviewTool } from './update-preview';
2425
import { validateBlocksTool } from './validate-blocks';
26+
import { waitForAnnotationsTool } from './wait-for-annotations';
2527
import { runWpCliTool } from './wp-cli';
2628
import { createWpcomRequestTool } from './wpcom-request';
2729

@@ -54,6 +56,8 @@ export const studioToolDefinitions = [
5456
pullSiteTool,
5557
importSiteTool,
5658
exportSiteTool,
59+
openAnnotationBrowserTool,
60+
waitForAnnotationsTool,
5761
...previewSteeringToolDefinitions,
5862
];
5963

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import { tool } from '@anthropic-ai/claude-agent-sdk';
2+
import { z } from 'zod/v4';
3+
import { openAnnotationBrowser } from 'cli/ai/inspector/inspector-inject';
4+
import { emitProgress } from 'cli/logger';
5+
import { errorResult, textResult } from './utils';
6+
7+
export const openAnnotationBrowserTool = tool(
8+
'open_annotation_browser',
9+
'Opens a headed browser on a site with the Studio annotation inspector. ' +
10+
'The user clicks "Annotate", picks an element, types feedback, then clicks "Done". ' +
11+
'After calling this tool, call `wait_for_annotations` to block until the user submits.',
12+
{
13+
url: z.string().describe( 'The site URL to open (e.g., "http://localhost:8881")' ),
14+
},
15+
async ( args ) => {
16+
try {
17+
emitProgress( `Opening annotation browser at ${ args.url }…` );
18+
const message = await openAnnotationBrowser( args.url );
19+
emitProgress( 'Annotation browser ready' );
20+
return textResult( message );
21+
} catch ( error ) {
22+
return errorResult(
23+
`Failed to open annotation browser: ${
24+
error instanceof Error ? error.message : String( error )
25+
}`
26+
);
27+
}
28+
}
29+
);
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import { tool } from '@anthropic-ai/claude-agent-sdk';
2+
import { z } from 'zod/v4';
3+
import { waitForAnnotationsDone } from 'cli/ai/inspector/inspector-inject';
4+
import { emitProgress } from 'cli/logger';
5+
import { errorResult, textResult } from './utils';
6+
7+
export const waitForAnnotationsTool = tool(
8+
'wait_for_annotations',
9+
'Blocks until the user clicks "Done" in the annotation inspector toolbar. ' +
10+
'Returns the annotations the user wrote, captured straight from the page. ' +
11+
'Call this AFTER `open_annotation_browser`.',
12+
{
13+
// Bound the wait — `0` would resolve to `timeout: 0` in Playwright,
14+
// which means "no timeout" and would block the agent forever. The
15+
// upper bound of 120 minutes is generous enough for any realistic
16+
// annotation session.
17+
timeoutMinutes: z
18+
.number()
19+
.int()
20+
.min( 1 )
21+
.max( 120 )
22+
.optional()
23+
.describe( 'How long to wait for the user to click "Done", in minutes. Defaults to 30.' ),
24+
},
25+
async ( args ) => {
26+
try {
27+
emitProgress( 'Waiting for the user to click "Done"…' );
28+
const result = await waitForAnnotationsDone( {
29+
timeoutMs: ( args.timeoutMinutes ?? 30 ) * 60 * 1000,
30+
} );
31+
emitProgress( `Received ${ result.annotations.length } annotation(s)` );
32+
return textResult( JSON.stringify( result, null, 2 ) );
33+
} catch ( error ) {
34+
return errorResult(
35+
`Failed to read annotations: ${ error instanceof Error ? error.message : String( error ) }`
36+
);
37+
}
38+
}
39+
);

apps/cli/ai/ui.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,10 @@ class PromptEditor implements Component, Focusable {
131131
this.editor.setAutocompleteProvider( provider );
132132
}
133133

134+
addToHistory( text: string ): void {
135+
this.editor.addToHistory( text );
136+
}
137+
134138
getText(): string {
135139
return this.editor.getText();
136140
}
@@ -563,14 +567,15 @@ export class AiChatUI implements AiOutputAdapter {
563567
this.editor = new PromptEditor( this.tui, editorTheme );
564568

565569
this.editor.setAutocompleteProvider(
566-
new CombinedAutocompleteProvider( AI_CHAT_SLASH_COMMANDS )
570+
new CombinedAutocompleteProvider( AI_CHAT_SLASH_COMMANDS, process.cwd() )
567571
);
568572

569573
this.editor.onSubmit = ( text ) => {
570574
const trimmed = text.trim();
571575
if ( ! trimmed ) {
572576
return;
573577
}
578+
this.editor.addToHistory( trimmed );
574579
if ( this.submitResolve ) {
575580
const resolve = this.submitResolve;
576581
this.submitResolve = null;

apps/cli/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
"@mariozechner/pi-agent-core": "0.70.2",
3030
"@mariozechner/pi-ai": "0.70.2",
3131
"@mariozechner/pi-coding-agent": "0.70.2",
32-
"@mariozechner/pi-tui": "0.54.0",
32+
"@mariozechner/pi-tui": "0.70.2",
3333
"@modelcontextprotocol/sdk": "^1.27.1",
3434
"@php-wasm/node": "3.1.22",
3535
"@php-wasm/universal": "3.1.22",

apps/cli/patches/@mariozechner+pi-tui+0.54.0.patch

Lines changed: 0 additions & 12 deletions
This file was deleted.

package-lock.json

Lines changed: 8 additions & 49 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)