@opencraw/studio 0.0.36 → 0.0.38

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -12,5 +12,5 @@ export type { RecipePair, SampleRunCallbacks, SampleRunHandle, SampleRunRecord,
12
12
  export { fetchStartPage } from './page-snapshot';
13
13
  export type { WhyFacts, WhyStepFact } from './explain-why';
14
14
  export { sampleBudgetSchema, openWorkspaceCommandSchema, chooseFolderCommandSchema, openPathCommandSchema, importDocumentCommandSchema, runSampleCommandSchema, stopRunCommandSchema, saveRecipeCommandSchema, fetchStartPageCommandSchema, detectUrlCommandSchema, saveOutlineCommandSchema, takeSnapshotCommandSchema, verifySelectorCommandSchema, inferSelectorCommandSchema, missingWhyTargetSchema, rejectedWhyTargetSchema, whyTargetSchema, explainWhyCommandSchema, studioCommandSchema, chooseFolderViewSchema, openPathViewSchema, importDocumentViewSchema, stoppedBySchema, fieldTraceSchema, traceLineEventSchema, recordEventSchema, recordRejectedEventSchema, runFinishedEventSchema, workspaceChangedEventSchema, studioEventSchema, loadedHooksSchema, recipeIssueSchema, recipeListingSchema, workspaceViewSchema, sampleRunRecordSchema, sampleRunViewSchema, startPageViewSchema, detectUrlViewSchema, snapshotViewSchema, verifySelectorViewSchema, fieldPickSchema, inferSelectorViewSchema, selectorAlternativeSchema, sentencePartSchema, outlineCardSchema, outlineBracketSchema, outlineNodeSchema, outlineViewSchema, whyViewSchema, inspectPageCommandSchema, responsesSeenCommandSchema, documentTreeCommandSchema, pdfViewCommandSchema, tablePreviewOptionsSchema, tablePreviewCommandSchema, regionPreviewCommandSchema, regionPreviewMatchSchema, regionPreviewViewSchema, gridViewCommandSchema, gridRowsCommandSchema, gridPreviewOptionsSchema, gridPreviewCommandSchema, deckViewCommandSchema, deckPreviewOptionsSchema, deckPreviewCommandSchema, domTreeNodeViewSchema, pageDataFindingSchema, inspectViewSchema, observedResponseSchema, responsesSeenViewSchema, documentTreeNodeViewSchema, documentTreeViewSchema, pdfCellViewSchema, pdfRowViewSchema, pdfPageViewSchema, pdfDocumentViewSchema, tablePreviewTableSchema, tablePreviewBandSchema, tablePreviewMatchSchema, tablePreviewViewSchema, gridCellViewSchema, gridMergeViewSchema, gridRowsViewSchema, gridSheetViewSchema, workbookDocumentViewSchema, gridTablePreviewMatchSchema, gridTablePreviewViewSchema, deckShapeViewSchema, deckChartSeriesViewSchema, deckChartViewSchema, deckSlideViewSchema, deckDocumentViewSchema, deckTablePreviewMatchSchema, deckTablePreviewViewSchema, startRecordingCommandSchema, stopRecordingCommandSchema, recordingCardEventSchema, recordingNoteEventSchema, recordingStoppedEventSchema, } from './studio-api';
15
- export type { SampleBudget, OpenWorkspaceCommand, ChooseFolderCommand, OpenPathCommand, ImportDocumentCommand, RunSampleCommand, StopRunCommand, SaveRecipeCommand, FetchStartPageCommand, DetectUrlCommand, SaveOutlineCommand, TakeSnapshotCommand, VerifySelectorCommand, InferSelectorCommand, MissingWhyTarget, RejectedWhyTarget, WhyTarget, ExplainWhyCommand, InspectPageCommand, ResponsesSeenCommand, DocumentTreeCommand, PdfViewCommand, TablePreviewOptions, TablePreviewCommand, RegionPreviewCommand, GridViewCommand, GridRowsCommand, GridPreviewOptions, GridPreviewCommand, DeckViewCommand, DeckPreviewOptions, DeckPreviewCommand, StudioCommand, ChooseFolderView, OpenPathView, ImportDocumentView, RegionPreviewMatchView, RegionPreviewView, StoppedBy, FieldTraceView, TraceLineEvent, RecordEvent, RecordRejectedEvent, RunFinishedEvent, WorkspaceChangedEvent, StudioEvent, LoadedHooks, RecipeIssue, RecipeListing, WorkspaceView, SampleRunView, StartPageView, DetectUrlView, SnapshotView, VerifySelectorView, FieldPick, InferSelectorView, SelectorAlternative, SentencePart, OutlineCard, OutlineBracket, OutlineNode, OutlineView, WhyView, DomTreeNodeView, PageDataKind, PageDataFindingView, InspectView, ObservedResponseView, ResponsesSeenView, DocumentTreeNodeView, DocumentTreeView, PdfCellView, PdfRowView, PdfPageView, PdfDocumentView, TablePreviewTableView, TablePreviewBandView, TablePreviewMatchView, TablePreviewView, GridCellView, GridMergeView, GridRowsView, GridSheetView, WorkbookDocumentView, GridTablePreviewMatchView, GridTablePreviewView, DeckShapeView, DeckChartSeriesView, DeckChartView, DeckSlideView, DeckDocumentView, DeckTablePreviewMatchView, DeckTablePreviewView, StartRecordingCommand, StopRecordingCommand, RecordingCardEvent, RecordingNoteEvent, RecordingStoppedEvent, } from './studio-api';
15
+ export type { SampleBudget, OpenWorkspaceCommand, ChooseFolderCommand, OpenPathCommand, ImportDocumentCommand, RunSampleCommand, StopRunCommand, SaveRecipeCommand, FetchStartPageCommand, DetectUrlCommand, SaveOutlineCommand, TakeSnapshotCommand, VerifySelectorCommand, InferSelectorCommand, MissingWhyTarget, RejectedWhyTarget, WhyTarget, ExplainWhyCommand, InspectPageCommand, ResponsesSeenCommand, DocumentTreeCommand, PdfViewCommand, TablePreviewOptions, TablePreviewCommand, RegionPreviewCommand, GridViewCommand, GridRowsCommand, GridPreviewOptions, GridPreviewCommand, DeckViewCommand, DeckPreviewOptions, DeckPreviewCommand, StudioCommand, ChooseFolderView, OpenPathView, ImportDocumentView, RegionPreviewMatchView, RegionPreviewView, StoppedBy, FieldTraceView, TraceLineEvent, RecordEvent, RecordRejectedEvent, RunFinishedEvent, WorkspaceChangedEvent, StudioEvent, LoadedHooks, RecipeIssue, RecipeListing, WorkspaceView, SampleRunView, StartPageView, DetectUrlView, SnapshotView, VerifySelectorView, FieldPick, InferSelectorView, SelectorAlternative, SentencePart, OutlineCard, OutlineBracket, OutlineNode, OutlineView, WhyView, DomTreeNodeView, PageDataKind, PageDataFindingView, InspectView, ObservedResponseView, ResponsesSeenView, DocumentTreeNodeView, DocumentTreeView, PdfCellView, PdfRowView, PdfPageView, PdfDocumentView, TablePreviewTableView, TablePreviewBandView, TablePreviewMatchView, TablePreviewView, GridCellView, GridMergeView, GridRowsView, GridSheetView, WorkbookDocumentView, GridTablePreviewMatchView, GridTablePreviewView, DeckShapeView, DeckChartSeriesView, DeckChartView, DeckSlideView, DeckDocumentView, DeckTablePreviewMatchView, DeckTablePreviewView, StartRecordingCommand, StopRecordingCommand, UiReportCommand, RecordingCardEvent, RecordingNoteEvent, RecordingStoppedEvent, } from './studio-api';
16
16
  //# sourceMappingURL=index.d.ts.map
package/dist/index.esm.js CHANGED
@@ -4,7 +4,7 @@ import { promisify, stripVTControlCharacters } from 'node:util';
4
4
  import { fileURLToPath, pathToFileURL } from 'node:url';
5
5
  import { z } from 'zod';
6
6
  import { BODY_KINDS, formatOfResponse, HttpClient, BrowserClient, NODE_ID_ATTRIBUTE, sessionStateOf, readRecipeSource, parseInputRecipe, parseOutputRecipe, calloutLabel, bindRecipeSet, memorySink, createCrawler, traceLine, UnknownHookError, rowsOfCells, parseXml, marginRows, findDeckTables, findGridTables, analyzeTables, parseRegion, regionText, deckRegionText, isDeckDocument, resolveMissingPolicy, isWorkbookDocument, RecipeBindingError, RecipeValidationError, countMatches, matchesOf, tryParseJson, isPdfDocument, BrowserProfiles } from '@opencraw/core';
7
- import { randomBytes, createHash } from 'node:crypto';
7
+ import { randomBytes, randomUUID, createHash } from 'node:crypto';
8
8
  import { execFile } from 'node:child_process';
9
9
  import { mkdir, writeFile, chmod, rm, readFile, rename, stat } from 'node:fs/promises';
10
10
  import { homedir, tmpdir } from 'node:os';
@@ -47,6 +47,17 @@ z.object({
47
47
  kind: z.literal('open'),
48
48
  path: z.string().min(1),
49
49
  workspace: z.string().min(1).optional()
50
+ }),
51
+ /**
52
+ * Pick a value on the recipe's web page, as a click would: the page finds the element by `selector` (a CSS selector) or by its `text`,
53
+ * stages it the way a click does (the ways to reach it are shown to choose from) and, with `add`, adds it to the recipe.
54
+ */
55
+ z.object({
56
+ kind: z.literal('pick'),
57
+ recipeId: z.string().min(1),
58
+ selector: z.string().min(1).optional(),
59
+ text: z.string().min(1).optional(),
60
+ add: z.boolean().optional()
50
61
  })]);
51
62
 
52
63
  /** A budget for a sample run; never authored into a recipe, only asked for by the caller. */
@@ -386,6 +397,20 @@ const askUiCommandSchema = z.object({
386
397
  type: z.literal('ask-ui'),
387
398
  request: uiRequestSchema
388
399
  });
400
+ /** The page tells the server how a controller's request went, so the controller can find out (`ui-outcome`). */
401
+ const uiReportCommandSchema = z.object({
402
+ type: z.literal('ui-report'),
403
+ requestId: z.string().min(1),
404
+ ok: z.boolean(),
405
+ message: z.string(),
406
+ /** What the page found or did, for the controller to read. */
407
+ detail: z.record(z.string(), z.unknown()).optional()
408
+ });
409
+ /** Asks how a controller's request went: still waiting for the page, or done. */
410
+ const uiOutcomeCommandSchema = z.object({
411
+ type: z.literal('ui-outcome'),
412
+ requestId: z.string().min(1)
413
+ });
389
414
  /** Asks what Studio is doing: its workspace, how many pages are open and the run in progress. */
390
415
  const studioStatusCommandSchema = z.object({
391
416
  type: z.literal('studio-status')
@@ -395,7 +420,7 @@ const runStatusCommandSchema = z.object({
395
420
  type: z.literal('run-status'),
396
421
  recipeId: z.string().min(1)
397
422
  });
398
- const studioCommandSchema = z.discriminatedUnion('type', [openWorkspaceCommandSchema, chooseFolderCommandSchema, openPathCommandSchema, importDocumentCommandSchema, runSampleCommandSchema, stopRunCommandSchema, saveRecipeCommandSchema, fetchStartPageCommandSchema, detectUrlCommandSchema, saveOutlineCommandSchema, takeSnapshotCommandSchema, verifySelectorCommandSchema, inferSelectorCommandSchema, explainWhyCommandSchema, inspectPageCommandSchema, responsesSeenCommandSchema, documentTreeCommandSchema, pdfViewCommandSchema, tablePreviewCommandSchema, regionPreviewCommandSchema, gridViewCommandSchema, gridRowsCommandSchema, gridPreviewCommandSchema, deckViewCommandSchema, deckPreviewCommandSchema, startRecordingCommandSchema, stopRecordingCommandSchema, askUiCommandSchema, studioStatusCommandSchema, runStatusCommandSchema]);
423
+ const studioCommandSchema = z.discriminatedUnion('type', [openWorkspaceCommandSchema, chooseFolderCommandSchema, openPathCommandSchema, importDocumentCommandSchema, runSampleCommandSchema, stopRunCommandSchema, saveRecipeCommandSchema, fetchStartPageCommandSchema, detectUrlCommandSchema, saveOutlineCommandSchema, takeSnapshotCommandSchema, verifySelectorCommandSchema, inferSelectorCommandSchema, explainWhyCommandSchema, inspectPageCommandSchema, responsesSeenCommandSchema, documentTreeCommandSchema, pdfViewCommandSchema, tablePreviewCommandSchema, regionPreviewCommandSchema, gridViewCommandSchema, gridRowsCommandSchema, gridPreviewCommandSchema, deckViewCommandSchema, deckPreviewCommandSchema, startRecordingCommandSchema, stopRecordingCommandSchema, askUiCommandSchema, uiReportCommandSchema, uiOutcomeCommandSchema, studioStatusCommandSchema, runStatusCommandSchema]);
399
424
 
400
425
  /**
401
426
  * What `take-snapshot` answers with: the rewritten document ready for the
@@ -556,6 +581,8 @@ const recordingStoppedEventSchema = z.object({
556
581
  /** A controller (an agent, through the MCP server) asked the open page to do something; every page does it. */
557
582
  const uiRequestEventSchema = z.object({
558
583
  type: z.literal('ui-request'),
584
+ /** Names the request, so the page can report how it went (`ui-report`) and the controller can ask (`ui-outcome`). */
585
+ requestId: z.string().min(1),
559
586
  request: uiRequestSchema
560
587
  });
561
588
  const studioEventSchema = z.discriminatedUnion('type', [traceLineEventSchema, recordEventSchema, recordRejectedEventSchema, runFinishedEventSchema, workspaceChangedEventSchema, recordingCardEventSchema, recordingNoteEventSchema, recordingStoppedEventSchema, uiRequestEventSchema]);
@@ -942,7 +969,15 @@ const deckTablePreviewViewSchema = z.object({
942
969
 
943
970
  /** How many pages were listening when a controller asked them to do something: none means nobody has Studio open. */
944
971
  z.object({
945
- pages: z.number()
972
+ pages: z.number(),
973
+ requestId: z.string()
974
+ });
975
+ /** How a controller's request went: `pending` until a page reported, then what it said. */
976
+ z.object({
977
+ state: z.enum(['pending', 'done']),
978
+ ok: z.boolean().optional(),
979
+ message: z.string().optional(),
980
+ detail: z.record(z.string(), z.unknown()).optional()
946
981
  });
947
982
  /** What Studio is doing: its workspace, how many pages are open, and the recipe whose sample run is in progress. */
948
983
  z.object({
@@ -2297,6 +2332,7 @@ function defaultRecorderProfileDir() {
2297
2332
  function createStudioState() {
2298
2333
  return {
2299
2334
  sockets: new Set(),
2335
+ uiOutcomes: new Map(),
2300
2336
  snapshots: createSnapshotCache(),
2301
2337
  lastRuns: createLastRunCache(),
2302
2338
  recorderProfileDir: defaultRecorderProfileDir()
@@ -2321,21 +2357,63 @@ function broadcast(state, event) {
2321
2357
  }
2322
2358
  }
2323
2359
 
2360
+ /** How many outcomes are kept: a controller asks soon after it sent the request, so a few dozen is plenty. */
2361
+ const KEPT_OUTCOMES = 50;
2324
2362
  /**
2325
2363
  * Handles `ask-ui`: tells every open page what a controller (an agent, through the MCP server) asked for, so
2326
- * the person watching sees it happen. Nothing is done server-side: the page does it the way a click would.
2364
+ * the person watching sees it happen. Nothing is done server-side: the page does it the way a click would, and
2365
+ * says how it went (`ui-report`).
2327
2366
  *
2328
2367
  * @param state - The server state holding the connected pages.
2329
2368
  * @param command - What to ask the pages.
2330
- * @returns How many pages were listening; 0 means nobody has Studio open.
2369
+ * @returns How many pages were listening (0 means nobody has Studio open) and the id to ask the outcome with.
2331
2370
  */
2332
2371
  function handleAskUi(state, command) {
2372
+ const requestId = randomUUID();
2333
2373
  broadcast(state, {
2334
2374
  type: 'ui-request',
2375
+ requestId,
2335
2376
  request: command.request
2336
2377
  });
2337
2378
  return {
2338
- pages: state.sockets.size
2379
+ pages: state.sockets.size,
2380
+ requestId
2381
+ };
2382
+ }
2383
+ /**
2384
+ * Handles `ui-report`: a page says how a controller's request went. The first answer stays: every open page gets the
2385
+ * request, and a page that has nothing to do with it (another recipe open) does not report.
2386
+ *
2387
+ * @param state - The server state.
2388
+ * @param command - The request's id and the outcome.
2389
+ * @returns Whether the report was kept.
2390
+ */
2391
+ function handleUiReport(state, command) {
2392
+ if (state.uiOutcomes.has(command.requestId)) return {
2393
+ kept: false
2394
+ };
2395
+ state.uiOutcomes.set(command.requestId, {
2396
+ state: 'done',
2397
+ ok: command.ok,
2398
+ message: command.message,
2399
+ detail: command.detail
2400
+ });
2401
+ const [oldest] = state.uiOutcomes.keys();
2402
+ if (oldest !== undefined && state.uiOutcomes.size > KEPT_OUTCOMES) state.uiOutcomes.delete(oldest);
2403
+ return {
2404
+ kept: true
2405
+ };
2406
+ }
2407
+ /**
2408
+ * Handles `ui-outcome`: how a controller's request went.
2409
+ *
2410
+ * @param state - The server state.
2411
+ * @param command - The request's id.
2412
+ * @returns `pending` until a page reported, then what it said.
2413
+ */
2414
+ function handleUiOutcome(state, command) {
2415
+ return state.uiOutcomes.get(command.requestId) ?? {
2416
+ state: 'pending'
2339
2417
  };
2340
2418
  }
2341
2419
 
@@ -6511,6 +6589,14 @@ function dispatch(command, state) {
6511
6589
  {
6512
6590
  return Promise.resolve(handleAskUi(state, command));
6513
6591
  }
6592
+ case 'ui-report':
6593
+ {
6594
+ return Promise.resolve(handleUiReport(state, command));
6595
+ }
6596
+ case 'ui-outcome':
6597
+ {
6598
+ return Promise.resolve(handleUiOutcome(state, command));
6599
+ }
6514
6600
  case 'studio-status':
6515
6601
  {
6516
6602
  return Promise.resolve(handleStudioStatus(state));
@@ -12,5 +12,5 @@ export type { RecipePair, SampleRunCallbacks, SampleRunHandle, SampleRunRecord,
12
12
  export { fetchStartPage } from './page-snapshot/index.js';
13
13
  export type { WhyFacts, WhyStepFact } from './explain-why/index.js';
14
14
  export { sampleBudgetSchema, openWorkspaceCommandSchema, chooseFolderCommandSchema, openPathCommandSchema, importDocumentCommandSchema, runSampleCommandSchema, stopRunCommandSchema, saveRecipeCommandSchema, fetchStartPageCommandSchema, detectUrlCommandSchema, saveOutlineCommandSchema, takeSnapshotCommandSchema, verifySelectorCommandSchema, inferSelectorCommandSchema, missingWhyTargetSchema, rejectedWhyTargetSchema, whyTargetSchema, explainWhyCommandSchema, studioCommandSchema, chooseFolderViewSchema, openPathViewSchema, importDocumentViewSchema, stoppedBySchema, fieldTraceSchema, traceLineEventSchema, recordEventSchema, recordRejectedEventSchema, runFinishedEventSchema, workspaceChangedEventSchema, studioEventSchema, loadedHooksSchema, recipeIssueSchema, recipeListingSchema, workspaceViewSchema, sampleRunRecordSchema, sampleRunViewSchema, startPageViewSchema, detectUrlViewSchema, snapshotViewSchema, verifySelectorViewSchema, fieldPickSchema, inferSelectorViewSchema, selectorAlternativeSchema, sentencePartSchema, outlineCardSchema, outlineBracketSchema, outlineNodeSchema, outlineViewSchema, whyViewSchema, inspectPageCommandSchema, responsesSeenCommandSchema, documentTreeCommandSchema, pdfViewCommandSchema, tablePreviewOptionsSchema, tablePreviewCommandSchema, regionPreviewCommandSchema, regionPreviewMatchSchema, regionPreviewViewSchema, gridViewCommandSchema, gridRowsCommandSchema, gridPreviewOptionsSchema, gridPreviewCommandSchema, deckViewCommandSchema, deckPreviewOptionsSchema, deckPreviewCommandSchema, domTreeNodeViewSchema, pageDataFindingSchema, inspectViewSchema, observedResponseSchema, responsesSeenViewSchema, documentTreeNodeViewSchema, documentTreeViewSchema, pdfCellViewSchema, pdfRowViewSchema, pdfPageViewSchema, pdfDocumentViewSchema, tablePreviewTableSchema, tablePreviewBandSchema, tablePreviewMatchSchema, tablePreviewViewSchema, gridCellViewSchema, gridMergeViewSchema, gridRowsViewSchema, gridSheetViewSchema, workbookDocumentViewSchema, gridTablePreviewMatchSchema, gridTablePreviewViewSchema, deckShapeViewSchema, deckChartSeriesViewSchema, deckChartViewSchema, deckSlideViewSchema, deckDocumentViewSchema, deckTablePreviewMatchSchema, deckTablePreviewViewSchema, startRecordingCommandSchema, stopRecordingCommandSchema, recordingCardEventSchema, recordingNoteEventSchema, recordingStoppedEventSchema, } from './studio-api/index.js';
15
- export type { SampleBudget, OpenWorkspaceCommand, ChooseFolderCommand, OpenPathCommand, ImportDocumentCommand, RunSampleCommand, StopRunCommand, SaveRecipeCommand, FetchStartPageCommand, DetectUrlCommand, SaveOutlineCommand, TakeSnapshotCommand, VerifySelectorCommand, InferSelectorCommand, MissingWhyTarget, RejectedWhyTarget, WhyTarget, ExplainWhyCommand, InspectPageCommand, ResponsesSeenCommand, DocumentTreeCommand, PdfViewCommand, TablePreviewOptions, TablePreviewCommand, RegionPreviewCommand, GridViewCommand, GridRowsCommand, GridPreviewOptions, GridPreviewCommand, DeckViewCommand, DeckPreviewOptions, DeckPreviewCommand, StudioCommand, ChooseFolderView, OpenPathView, ImportDocumentView, RegionPreviewMatchView, RegionPreviewView, StoppedBy, FieldTraceView, TraceLineEvent, RecordEvent, RecordRejectedEvent, RunFinishedEvent, WorkspaceChangedEvent, StudioEvent, LoadedHooks, RecipeIssue, RecipeListing, WorkspaceView, SampleRunView, StartPageView, DetectUrlView, SnapshotView, VerifySelectorView, FieldPick, InferSelectorView, SelectorAlternative, SentencePart, OutlineCard, OutlineBracket, OutlineNode, OutlineView, WhyView, DomTreeNodeView, PageDataKind, PageDataFindingView, InspectView, ObservedResponseView, ResponsesSeenView, DocumentTreeNodeView, DocumentTreeView, PdfCellView, PdfRowView, PdfPageView, PdfDocumentView, TablePreviewTableView, TablePreviewBandView, TablePreviewMatchView, TablePreviewView, GridCellView, GridMergeView, GridRowsView, GridSheetView, WorkbookDocumentView, GridTablePreviewMatchView, GridTablePreviewView, DeckShapeView, DeckChartSeriesView, DeckChartView, DeckSlideView, DeckDocumentView, DeckTablePreviewMatchView, DeckTablePreviewView, StartRecordingCommand, StopRecordingCommand, RecordingCardEvent, RecordingNoteEvent, RecordingStoppedEvent, } from './studio-api/index.js';
15
+ export type { SampleBudget, OpenWorkspaceCommand, ChooseFolderCommand, OpenPathCommand, ImportDocumentCommand, RunSampleCommand, StopRunCommand, SaveRecipeCommand, FetchStartPageCommand, DetectUrlCommand, SaveOutlineCommand, TakeSnapshotCommand, VerifySelectorCommand, InferSelectorCommand, MissingWhyTarget, RejectedWhyTarget, WhyTarget, ExplainWhyCommand, InspectPageCommand, ResponsesSeenCommand, DocumentTreeCommand, PdfViewCommand, TablePreviewOptions, TablePreviewCommand, RegionPreviewCommand, GridViewCommand, GridRowsCommand, GridPreviewOptions, GridPreviewCommand, DeckViewCommand, DeckPreviewOptions, DeckPreviewCommand, StudioCommand, ChooseFolderView, OpenPathView, ImportDocumentView, RegionPreviewMatchView, RegionPreviewView, StoppedBy, FieldTraceView, TraceLineEvent, RecordEvent, RecordRejectedEvent, RunFinishedEvent, WorkspaceChangedEvent, StudioEvent, LoadedHooks, RecipeIssue, RecipeListing, WorkspaceView, SampleRunView, StartPageView, DetectUrlView, SnapshotView, VerifySelectorView, FieldPick, InferSelectorView, SelectorAlternative, SentencePart, OutlineCard, OutlineBracket, OutlineNode, OutlineView, WhyView, DomTreeNodeView, PageDataKind, PageDataFindingView, InspectView, ObservedResponseView, ResponsesSeenView, DocumentTreeNodeView, DocumentTreeView, PdfCellView, PdfRowView, PdfPageView, PdfDocumentView, TablePreviewTableView, TablePreviewBandView, TablePreviewMatchView, TablePreviewView, GridCellView, GridMergeView, GridRowsView, GridSheetView, WorkbookDocumentView, GridTablePreviewMatchView, GridTablePreviewView, DeckShapeView, DeckChartSeriesView, DeckChartView, DeckSlideView, DeckDocumentView, DeckTablePreviewMatchView, DeckTablePreviewView, StartRecordingCommand, StopRecordingCommand, UiReportCommand, RecordingCardEvent, RecordingNoteEvent, RecordingStoppedEvent, } from './studio-api/index.js';
16
16
  //# sourceMappingURL=index.d.ts.map
@@ -392,8 +392,27 @@ export declare const askUiCommandSchema: z.ZodObject<{
392
392
  kind: z.ZodLiteral<"open">;
393
393
  path: z.ZodString;
394
394
  workspace: z.ZodOptional<z.ZodString>;
395
+ }, z.core.$strip>, z.ZodObject<{
396
+ kind: z.ZodLiteral<"pick">;
397
+ recipeId: z.ZodString;
398
+ selector: z.ZodOptional<z.ZodString>;
399
+ text: z.ZodOptional<z.ZodString>;
400
+ add: z.ZodOptional<z.ZodBoolean>;
395
401
  }, z.core.$strip>], "kind">;
396
402
  }, z.core.$strip>;
403
+ /** The page tells the server how a controller's request went, so the controller can find out (`ui-outcome`). */
404
+ export declare const uiReportCommandSchema: z.ZodObject<{
405
+ type: z.ZodLiteral<"ui-report">;
406
+ requestId: z.ZodString;
407
+ ok: z.ZodBoolean;
408
+ message: z.ZodString;
409
+ detail: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
410
+ }, z.core.$strip>;
411
+ /** Asks how a controller's request went: still waiting for the page, or done. */
412
+ export declare const uiOutcomeCommandSchema: z.ZodObject<{
413
+ type: z.ZodLiteral<"ui-outcome">;
414
+ requestId: z.ZodString;
415
+ }, z.core.$strip>;
397
416
  /** Asks what Studio is doing: its workspace, how many pages are open and the run in progress. */
398
417
  export declare const studioStatusCommandSchema: z.ZodObject<{
399
418
  type: z.ZodLiteral<"studio-status">;
@@ -566,7 +585,22 @@ export declare const studioCommandSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
566
585
  kind: z.ZodLiteral<"open">;
567
586
  path: z.ZodString;
568
587
  workspace: z.ZodOptional<z.ZodString>;
588
+ }, z.core.$strip>, z.ZodObject<{
589
+ kind: z.ZodLiteral<"pick">;
590
+ recipeId: z.ZodString;
591
+ selector: z.ZodOptional<z.ZodString>;
592
+ text: z.ZodOptional<z.ZodString>;
593
+ add: z.ZodOptional<z.ZodBoolean>;
569
594
  }, z.core.$strip>], "kind">;
595
+ }, z.core.$strip>, z.ZodObject<{
596
+ type: z.ZodLiteral<"ui-report">;
597
+ requestId: z.ZodString;
598
+ ok: z.ZodBoolean;
599
+ message: z.ZodString;
600
+ detail: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
601
+ }, z.core.$strip>, z.ZodObject<{
602
+ type: z.ZodLiteral<"ui-outcome">;
603
+ requestId: z.ZodString;
570
604
  }, z.core.$strip>, z.ZodObject<{
571
605
  type: z.ZodLiteral<"studio-status">;
572
606
  }, z.core.$strip>, z.ZodObject<{
@@ -579,6 +613,8 @@ export type ChooseFolderCommand = z.infer<typeof chooseFolderCommandSchema>;
579
613
  export type OpenPathCommand = z.infer<typeof openPathCommandSchema>;
580
614
  export type ImportDocumentCommand = z.infer<typeof importDocumentCommandSchema>;
581
615
  export type RunSampleCommand = z.infer<typeof runSampleCommandSchema>;
616
+ export type UiReportCommand = z.infer<typeof uiReportCommandSchema>;
617
+ export type UiOutcomeCommand = z.infer<typeof uiOutcomeCommandSchema>;
582
618
  export type AskUiCommand = z.infer<typeof askUiCommandSchema>;
583
619
  export type StudioStatusCommand = z.infer<typeof studioStatusCommandSchema>;
584
620
  export type RunStatusCommand = z.infer<typeof runStatusCommandSchema>;
@@ -90,10 +90,17 @@ export declare const recordingStoppedEventSchema: z.ZodObject<{
90
90
  /** A controller (an agent, through the MCP server) asked the open page to do something; every page does it. */
91
91
  export declare const uiRequestEventSchema: z.ZodObject<{
92
92
  type: z.ZodLiteral<"ui-request">;
93
+ requestId: z.ZodString;
93
94
  request: z.ZodDiscriminatedUnion<[z.ZodObject<{
94
95
  kind: z.ZodLiteral<"open">;
95
96
  path: z.ZodString;
96
97
  workspace: z.ZodOptional<z.ZodString>;
98
+ }, z.core.$strip>, z.ZodObject<{
99
+ kind: z.ZodLiteral<"pick">;
100
+ recipeId: z.ZodString;
101
+ selector: z.ZodOptional<z.ZodString>;
102
+ text: z.ZodOptional<z.ZodString>;
103
+ add: z.ZodOptional<z.ZodBoolean>;
97
104
  }, z.core.$strip>], "kind">;
98
105
  }, z.core.$strip>;
99
106
  export declare const studioEventSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
@@ -150,10 +157,17 @@ export declare const studioEventSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
150
157
  steps: z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
151
158
  }, z.core.$strip>, z.ZodObject<{
152
159
  type: z.ZodLiteral<"ui-request">;
160
+ requestId: z.ZodString;
153
161
  request: z.ZodDiscriminatedUnion<[z.ZodObject<{
154
162
  kind: z.ZodLiteral<"open">;
155
163
  path: z.ZodString;
156
164
  workspace: z.ZodOptional<z.ZodString>;
165
+ }, z.core.$strip>, z.ZodObject<{
166
+ kind: z.ZodLiteral<"pick">;
167
+ recipeId: z.ZodString;
168
+ selector: z.ZodOptional<z.ZodString>;
169
+ text: z.ZodOptional<z.ZodString>;
170
+ add: z.ZodOptional<z.ZodBoolean>;
157
171
  }, z.core.$strip>], "kind">;
158
172
  }, z.core.$strip>], "type">;
159
173
  export type UiRequestEvent = z.infer<typeof uiRequestEventSchema>;
@@ -1,5 +1,5 @@
1
- export { sampleBudgetSchema, openWorkspaceCommandSchema, chooseFolderCommandSchema, openPathCommandSchema, importDocumentCommandSchema, runSampleCommandSchema, stopRunCommandSchema, saveRecipeCommandSchema, fetchStartPageCommandSchema, detectUrlCommandSchema, saveOutlineCommandSchema, takeSnapshotCommandSchema, verifySelectorCommandSchema, inferSelectorCommandSchema, missingWhyTargetSchema, rejectedWhyTargetSchema, whyTargetSchema, explainWhyCommandSchema, inspectPageCommandSchema, responsesSeenCommandSchema, documentTreeCommandSchema, pdfViewCommandSchema, tablePreviewOptionsSchema, tablePreviewCommandSchema, regionPreviewCommandSchema, gridViewCommandSchema, gridRowsCommandSchema, gridPreviewOptionsSchema, gridPreviewCommandSchema, deckViewCommandSchema, deckPreviewOptionsSchema, deckPreviewCommandSchema, startRecordingCommandSchema, stopRecordingCommandSchema, askUiCommandSchema, studioStatusCommandSchema, runStatusCommandSchema, studioCommandSchema } from './command.contract.js';
2
- export type { SampleBudget, OpenWorkspaceCommand, ChooseFolderCommand, OpenPathCommand, ImportDocumentCommand, RunSampleCommand, StopRunCommand, SaveRecipeCommand, FetchStartPageCommand, DetectUrlCommand, SaveOutlineCommand, TakeSnapshotCommand, VerifySelectorCommand, InferSelectorCommand, MissingWhyTarget, RejectedWhyTarget, WhyTarget, ExplainWhyCommand, InspectPageCommand, ResponsesSeenCommand, DocumentTreeCommand, PdfViewCommand, TablePreviewOptions, TablePreviewCommand, RegionPreviewCommand, GridViewCommand, GridRowsCommand, GridPreviewOptions, GridPreviewCommand, DeckViewCommand, DeckPreviewOptions, DeckPreviewCommand, StartRecordingCommand, StopRecordingCommand, AskUiCommand, StudioStatusCommand, RunStatusCommand, StudioCommand } from './command.contract.js';
1
+ export { sampleBudgetSchema, openWorkspaceCommandSchema, chooseFolderCommandSchema, openPathCommandSchema, importDocumentCommandSchema, runSampleCommandSchema, stopRunCommandSchema, saveRecipeCommandSchema, fetchStartPageCommandSchema, detectUrlCommandSchema, saveOutlineCommandSchema, takeSnapshotCommandSchema, verifySelectorCommandSchema, inferSelectorCommandSchema, missingWhyTargetSchema, rejectedWhyTargetSchema, whyTargetSchema, explainWhyCommandSchema, inspectPageCommandSchema, responsesSeenCommandSchema, documentTreeCommandSchema, pdfViewCommandSchema, tablePreviewOptionsSchema, tablePreviewCommandSchema, regionPreviewCommandSchema, gridViewCommandSchema, gridRowsCommandSchema, gridPreviewOptionsSchema, gridPreviewCommandSchema, deckViewCommandSchema, deckPreviewOptionsSchema, deckPreviewCommandSchema, startRecordingCommandSchema, stopRecordingCommandSchema, askUiCommandSchema, uiReportCommandSchema, uiOutcomeCommandSchema, studioStatusCommandSchema, runStatusCommandSchema, studioCommandSchema } from './command.contract.js';
2
+ export type { SampleBudget, OpenWorkspaceCommand, ChooseFolderCommand, OpenPathCommand, ImportDocumentCommand, RunSampleCommand, StopRunCommand, SaveRecipeCommand, FetchStartPageCommand, DetectUrlCommand, SaveOutlineCommand, TakeSnapshotCommand, VerifySelectorCommand, InferSelectorCommand, MissingWhyTarget, RejectedWhyTarget, WhyTarget, ExplainWhyCommand, InspectPageCommand, ResponsesSeenCommand, DocumentTreeCommand, PdfViewCommand, TablePreviewOptions, TablePreviewCommand, RegionPreviewCommand, GridViewCommand, GridRowsCommand, GridPreviewOptions, GridPreviewCommand, DeckViewCommand, DeckPreviewOptions, DeckPreviewCommand, StartRecordingCommand, StopRecordingCommand, AskUiCommand, UiReportCommand, UiOutcomeCommand, StudioStatusCommand, RunStatusCommand, StudioCommand } from './command.contract.js';
3
3
  export { snapshotViewSchema } from './snapshot-view.contract.js';
4
4
  export type { SnapshotView } from './snapshot-view.contract.js';
5
5
  export { verifySelectorViewSchema } from './verify-selector-view.contract.js';
@@ -48,6 +48,6 @@ export { deckTablePreviewMatchSchema, deckTablePreviewViewSchema } from './deck-
48
48
  export type { DeckTablePreviewMatchView, DeckTablePreviewView } from './deck-preview-view.contract.js';
49
49
  export { uiRequestSchema } from './ui-request.contract.js';
50
50
  export type { UiRequest } from './ui-request.contract.js';
51
- export { askUiViewSchema, studioStatusViewSchema, runStatusViewSchema } from './studio-control-view.contract.js';
52
- export type { AskUiView, StudioStatusView, RunStatusView } from './studio-control-view.contract.js';
51
+ export { askUiViewSchema, uiOutcomeViewSchema, studioStatusViewSchema, runStatusViewSchema } from './studio-control-view.contract.js';
52
+ export type { AskUiView, UiOutcomeView, StudioStatusView, RunStatusView } from './studio-control-view.contract.js';
53
53
  //# sourceMappingURL=index.d.ts.map
@@ -2,6 +2,17 @@ import { z } from 'zod';
2
2
  /** How many pages were listening when a controller asked them to do something: none means nobody has Studio open. */
3
3
  export declare const askUiViewSchema: z.ZodObject<{
4
4
  pages: z.ZodNumber;
5
+ requestId: z.ZodString;
6
+ }, z.core.$strip>;
7
+ /** How a controller's request went: `pending` until a page reported, then what it said. */
8
+ export declare const uiOutcomeViewSchema: z.ZodObject<{
9
+ state: z.ZodEnum<{
10
+ pending: "pending";
11
+ done: "done";
12
+ }>;
13
+ ok: z.ZodOptional<z.ZodBoolean>;
14
+ message: z.ZodOptional<z.ZodString>;
15
+ detail: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
5
16
  }, z.core.$strip>;
6
17
  /** What Studio is doing: its workspace, how many pages are open, and the recipe whose sample run is in progress. */
7
18
  export declare const studioStatusViewSchema: z.ZodObject<{
@@ -35,6 +46,7 @@ export declare const runStatusViewSchema: z.ZodObject<{
35
46
  }, z.core.$strip>>;
36
47
  }, z.core.$strip>>;
37
48
  }, z.core.$strip>;
49
+ export type UiOutcomeView = z.infer<typeof uiOutcomeViewSchema>;
38
50
  export type AskUiView = z.infer<typeof askUiViewSchema>;
39
51
  export type StudioStatusView = z.infer<typeof studioStatusViewSchema>;
40
52
  export type RunStatusView = z.infer<typeof runStatusViewSchema>;
@@ -4,6 +4,12 @@ export declare const uiRequestSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
4
4
  kind: z.ZodLiteral<"open">;
5
5
  path: z.ZodString;
6
6
  workspace: z.ZodOptional<z.ZodString>;
7
+ }, z.core.$strip>, z.ZodObject<{
8
+ kind: z.ZodLiteral<"pick">;
9
+ recipeId: z.ZodString;
10
+ selector: z.ZodOptional<z.ZodString>;
11
+ text: z.ZodOptional<z.ZodString>;
12
+ add: z.ZodOptional<z.ZodBoolean>;
7
13
  }, z.core.$strip>], "kind">;
8
14
  export type UiRequest = z.infer<typeof uiRequestSchema>;
9
15
  //# sourceMappingURL=ui-request.contract.d.ts.map
@@ -1,12 +1,32 @@
1
- import type { AskUiCommand, AskUiView } from '../studio-api/index.js';
1
+ import type { AskUiCommand, AskUiView, UiOutcomeCommand, UiOutcomeView, UiReportCommand } from '../studio-api/index.js';
2
2
  import type { StudioState } from './workspace.store.js';
3
3
  /**
4
4
  * Handles `ask-ui`: tells every open page what a controller (an agent, through the MCP server) asked for, so
5
- * the person watching sees it happen. Nothing is done server-side: the page does it the way a click would.
5
+ * the person watching sees it happen. Nothing is done server-side: the page does it the way a click would, and
6
+ * says how it went (`ui-report`).
6
7
  *
7
8
  * @param state - The server state holding the connected pages.
8
9
  * @param command - What to ask the pages.
9
- * @returns How many pages were listening; 0 means nobody has Studio open.
10
+ * @returns How many pages were listening (0 means nobody has Studio open) and the id to ask the outcome with.
10
11
  */
11
12
  export declare function handleAskUi(state: StudioState, command: AskUiCommand): AskUiView;
13
+ /**
14
+ * Handles `ui-report`: a page says how a controller's request went. The first answer stays: every open page gets the
15
+ * request, and a page that has nothing to do with it (another recipe open) does not report.
16
+ *
17
+ * @param state - The server state.
18
+ * @param command - The request's id and the outcome.
19
+ * @returns Whether the report was kept.
20
+ */
21
+ export declare function handleUiReport(state: StudioState, command: UiReportCommand): {
22
+ kept: boolean;
23
+ };
24
+ /**
25
+ * Handles `ui-outcome`: how a controller's request went.
26
+ *
27
+ * @param state - The server state.
28
+ * @param command - The request's id.
29
+ * @returns `pending` until a page reported, then what it said.
30
+ */
31
+ export declare function handleUiOutcome(state: StudioState, command: UiOutcomeCommand): UiOutcomeView;
12
32
  //# sourceMappingURL=ask-ui.handler.d.ts.map
@@ -2,7 +2,7 @@ import type { BrowserSessionConfig } from '@opencraw/core';
2
2
  import type { RecorderSessionHandle } from '../flow-recording/index.js';
3
3
  import type { SnapshotCache } from '../page-snapshot/index.js';
4
4
  import type { LastRunCache, SampleRunHandle } from '../sample-run/index.js';
5
- import type { StudioEvent } from '../studio-api/index.js';
5
+ import type { StudioEvent, UiOutcomeView } from '../studio-api/index.js';
6
6
  import type { TrustedPlugins } from '../trusted-plugins/index.js';
7
7
  import type { WsConnection } from './websocket.client.js';
8
8
  /** The server's mutable state: the opened folder, the run in progress (if any), the recording in progress (if any, issue #95), the connected event sockets, the per-recipe snapshot cache `take-snapshot`/`verify-selector`/`infer-selector` share, each recipe's last finished sample run (`explain-why`, issue #92), the browser launch settings every web-mode command (`take-snapshot`, `verify-selector`, `run-sample`, `start-recording`) shares, and where the studio's own recorder profile lives. */
@@ -15,6 +15,8 @@ export interface StudioState {
15
15
  /** A `start-recording` still opening its window: `stop-recording` and the server's own close wait for it, so a window is never left open behind them (issue #174). */
16
16
  openingRecording?: Promise<unknown>;
17
17
  sockets: Set<WsConnection>;
18
+ /** How the pages said a controller's requests went (`ui-report`), by request id; the oldest are dropped past a few dozen. */
19
+ uiOutcomes: Map<string, UiOutcomeView>;
18
20
  snapshots: SnapshotCache;
19
21
  lastRuns: LastRunCache;
20
22
  /** Set once at server start (`StudioServerOptions.browser`); every web-mode command reads it from here rather than each accepting its own. */
@@ -392,8 +392,27 @@ export declare const askUiCommandSchema: z.ZodObject<{
392
392
  kind: z.ZodLiteral<"open">;
393
393
  path: z.ZodString;
394
394
  workspace: z.ZodOptional<z.ZodString>;
395
+ }, z.core.$strip>, z.ZodObject<{
396
+ kind: z.ZodLiteral<"pick">;
397
+ recipeId: z.ZodString;
398
+ selector: z.ZodOptional<z.ZodString>;
399
+ text: z.ZodOptional<z.ZodString>;
400
+ add: z.ZodOptional<z.ZodBoolean>;
395
401
  }, z.core.$strip>], "kind">;
396
402
  }, z.core.$strip>;
403
+ /** The page tells the server how a controller's request went, so the controller can find out (`ui-outcome`). */
404
+ export declare const uiReportCommandSchema: z.ZodObject<{
405
+ type: z.ZodLiteral<"ui-report">;
406
+ requestId: z.ZodString;
407
+ ok: z.ZodBoolean;
408
+ message: z.ZodString;
409
+ detail: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
410
+ }, z.core.$strip>;
411
+ /** Asks how a controller's request went: still waiting for the page, or done. */
412
+ export declare const uiOutcomeCommandSchema: z.ZodObject<{
413
+ type: z.ZodLiteral<"ui-outcome">;
414
+ requestId: z.ZodString;
415
+ }, z.core.$strip>;
397
416
  /** Asks what Studio is doing: its workspace, how many pages are open and the run in progress. */
398
417
  export declare const studioStatusCommandSchema: z.ZodObject<{
399
418
  type: z.ZodLiteral<"studio-status">;
@@ -566,7 +585,22 @@ export declare const studioCommandSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
566
585
  kind: z.ZodLiteral<"open">;
567
586
  path: z.ZodString;
568
587
  workspace: z.ZodOptional<z.ZodString>;
588
+ }, z.core.$strip>, z.ZodObject<{
589
+ kind: z.ZodLiteral<"pick">;
590
+ recipeId: z.ZodString;
591
+ selector: z.ZodOptional<z.ZodString>;
592
+ text: z.ZodOptional<z.ZodString>;
593
+ add: z.ZodOptional<z.ZodBoolean>;
569
594
  }, z.core.$strip>], "kind">;
595
+ }, z.core.$strip>, z.ZodObject<{
596
+ type: z.ZodLiteral<"ui-report">;
597
+ requestId: z.ZodString;
598
+ ok: z.ZodBoolean;
599
+ message: z.ZodString;
600
+ detail: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
601
+ }, z.core.$strip>, z.ZodObject<{
602
+ type: z.ZodLiteral<"ui-outcome">;
603
+ requestId: z.ZodString;
570
604
  }, z.core.$strip>, z.ZodObject<{
571
605
  type: z.ZodLiteral<"studio-status">;
572
606
  }, z.core.$strip>, z.ZodObject<{
@@ -579,6 +613,8 @@ export type ChooseFolderCommand = z.infer<typeof chooseFolderCommandSchema>;
579
613
  export type OpenPathCommand = z.infer<typeof openPathCommandSchema>;
580
614
  export type ImportDocumentCommand = z.infer<typeof importDocumentCommandSchema>;
581
615
  export type RunSampleCommand = z.infer<typeof runSampleCommandSchema>;
616
+ export type UiReportCommand = z.infer<typeof uiReportCommandSchema>;
617
+ export type UiOutcomeCommand = z.infer<typeof uiOutcomeCommandSchema>;
582
618
  export type AskUiCommand = z.infer<typeof askUiCommandSchema>;
583
619
  export type StudioStatusCommand = z.infer<typeof studioStatusCommandSchema>;
584
620
  export type RunStatusCommand = z.infer<typeof runStatusCommandSchema>;
@@ -90,10 +90,17 @@ export declare const recordingStoppedEventSchema: z.ZodObject<{
90
90
  /** A controller (an agent, through the MCP server) asked the open page to do something; every page does it. */
91
91
  export declare const uiRequestEventSchema: z.ZodObject<{
92
92
  type: z.ZodLiteral<"ui-request">;
93
+ requestId: z.ZodString;
93
94
  request: z.ZodDiscriminatedUnion<[z.ZodObject<{
94
95
  kind: z.ZodLiteral<"open">;
95
96
  path: z.ZodString;
96
97
  workspace: z.ZodOptional<z.ZodString>;
98
+ }, z.core.$strip>, z.ZodObject<{
99
+ kind: z.ZodLiteral<"pick">;
100
+ recipeId: z.ZodString;
101
+ selector: z.ZodOptional<z.ZodString>;
102
+ text: z.ZodOptional<z.ZodString>;
103
+ add: z.ZodOptional<z.ZodBoolean>;
97
104
  }, z.core.$strip>], "kind">;
98
105
  }, z.core.$strip>;
99
106
  export declare const studioEventSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
@@ -150,10 +157,17 @@ export declare const studioEventSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
150
157
  steps: z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
151
158
  }, z.core.$strip>, z.ZodObject<{
152
159
  type: z.ZodLiteral<"ui-request">;
160
+ requestId: z.ZodString;
153
161
  request: z.ZodDiscriminatedUnion<[z.ZodObject<{
154
162
  kind: z.ZodLiteral<"open">;
155
163
  path: z.ZodString;
156
164
  workspace: z.ZodOptional<z.ZodString>;
165
+ }, z.core.$strip>, z.ZodObject<{
166
+ kind: z.ZodLiteral<"pick">;
167
+ recipeId: z.ZodString;
168
+ selector: z.ZodOptional<z.ZodString>;
169
+ text: z.ZodOptional<z.ZodString>;
170
+ add: z.ZodOptional<z.ZodBoolean>;
157
171
  }, z.core.$strip>], "kind">;
158
172
  }, z.core.$strip>], "type">;
159
173
  export type UiRequestEvent = z.infer<typeof uiRequestEventSchema>;
@@ -1,5 +1,5 @@
1
- export { sampleBudgetSchema, openWorkspaceCommandSchema, chooseFolderCommandSchema, openPathCommandSchema, importDocumentCommandSchema, runSampleCommandSchema, stopRunCommandSchema, saveRecipeCommandSchema, fetchStartPageCommandSchema, detectUrlCommandSchema, saveOutlineCommandSchema, takeSnapshotCommandSchema, verifySelectorCommandSchema, inferSelectorCommandSchema, missingWhyTargetSchema, rejectedWhyTargetSchema, whyTargetSchema, explainWhyCommandSchema, inspectPageCommandSchema, responsesSeenCommandSchema, documentTreeCommandSchema, pdfViewCommandSchema, tablePreviewOptionsSchema, tablePreviewCommandSchema, regionPreviewCommandSchema, gridViewCommandSchema, gridRowsCommandSchema, gridPreviewOptionsSchema, gridPreviewCommandSchema, deckViewCommandSchema, deckPreviewOptionsSchema, deckPreviewCommandSchema, startRecordingCommandSchema, stopRecordingCommandSchema, askUiCommandSchema, studioStatusCommandSchema, runStatusCommandSchema, studioCommandSchema } from './command.contract';
2
- export type { SampleBudget, OpenWorkspaceCommand, ChooseFolderCommand, OpenPathCommand, ImportDocumentCommand, RunSampleCommand, StopRunCommand, SaveRecipeCommand, FetchStartPageCommand, DetectUrlCommand, SaveOutlineCommand, TakeSnapshotCommand, VerifySelectorCommand, InferSelectorCommand, MissingWhyTarget, RejectedWhyTarget, WhyTarget, ExplainWhyCommand, InspectPageCommand, ResponsesSeenCommand, DocumentTreeCommand, PdfViewCommand, TablePreviewOptions, TablePreviewCommand, RegionPreviewCommand, GridViewCommand, GridRowsCommand, GridPreviewOptions, GridPreviewCommand, DeckViewCommand, DeckPreviewOptions, DeckPreviewCommand, StartRecordingCommand, StopRecordingCommand, AskUiCommand, StudioStatusCommand, RunStatusCommand, StudioCommand } from './command.contract';
1
+ export { sampleBudgetSchema, openWorkspaceCommandSchema, chooseFolderCommandSchema, openPathCommandSchema, importDocumentCommandSchema, runSampleCommandSchema, stopRunCommandSchema, saveRecipeCommandSchema, fetchStartPageCommandSchema, detectUrlCommandSchema, saveOutlineCommandSchema, takeSnapshotCommandSchema, verifySelectorCommandSchema, inferSelectorCommandSchema, missingWhyTargetSchema, rejectedWhyTargetSchema, whyTargetSchema, explainWhyCommandSchema, inspectPageCommandSchema, responsesSeenCommandSchema, documentTreeCommandSchema, pdfViewCommandSchema, tablePreviewOptionsSchema, tablePreviewCommandSchema, regionPreviewCommandSchema, gridViewCommandSchema, gridRowsCommandSchema, gridPreviewOptionsSchema, gridPreviewCommandSchema, deckViewCommandSchema, deckPreviewOptionsSchema, deckPreviewCommandSchema, startRecordingCommandSchema, stopRecordingCommandSchema, askUiCommandSchema, uiReportCommandSchema, uiOutcomeCommandSchema, studioStatusCommandSchema, runStatusCommandSchema, studioCommandSchema } from './command.contract';
2
+ export type { SampleBudget, OpenWorkspaceCommand, ChooseFolderCommand, OpenPathCommand, ImportDocumentCommand, RunSampleCommand, StopRunCommand, SaveRecipeCommand, FetchStartPageCommand, DetectUrlCommand, SaveOutlineCommand, TakeSnapshotCommand, VerifySelectorCommand, InferSelectorCommand, MissingWhyTarget, RejectedWhyTarget, WhyTarget, ExplainWhyCommand, InspectPageCommand, ResponsesSeenCommand, DocumentTreeCommand, PdfViewCommand, TablePreviewOptions, TablePreviewCommand, RegionPreviewCommand, GridViewCommand, GridRowsCommand, GridPreviewOptions, GridPreviewCommand, DeckViewCommand, DeckPreviewOptions, DeckPreviewCommand, StartRecordingCommand, StopRecordingCommand, AskUiCommand, UiReportCommand, UiOutcomeCommand, StudioStatusCommand, RunStatusCommand, StudioCommand } from './command.contract';
3
3
  export { snapshotViewSchema } from './snapshot-view.contract';
4
4
  export type { SnapshotView } from './snapshot-view.contract';
5
5
  export { verifySelectorViewSchema } from './verify-selector-view.contract';
@@ -48,6 +48,6 @@ export { deckTablePreviewMatchSchema, deckTablePreviewViewSchema } from './deck-
48
48
  export type { DeckTablePreviewMatchView, DeckTablePreviewView } from './deck-preview-view.contract';
49
49
  export { uiRequestSchema } from './ui-request.contract';
50
50
  export type { UiRequest } from './ui-request.contract';
51
- export { askUiViewSchema, studioStatusViewSchema, runStatusViewSchema } from './studio-control-view.contract';
52
- export type { AskUiView, StudioStatusView, RunStatusView } from './studio-control-view.contract';
51
+ export { askUiViewSchema, uiOutcomeViewSchema, studioStatusViewSchema, runStatusViewSchema } from './studio-control-view.contract';
52
+ export type { AskUiView, UiOutcomeView, StudioStatusView, RunStatusView } from './studio-control-view.contract';
53
53
  //# sourceMappingURL=index.d.ts.map
@@ -2,6 +2,17 @@ import { z } from 'zod';
2
2
  /** How many pages were listening when a controller asked them to do something: none means nobody has Studio open. */
3
3
  export declare const askUiViewSchema: z.ZodObject<{
4
4
  pages: z.ZodNumber;
5
+ requestId: z.ZodString;
6
+ }, z.core.$strip>;
7
+ /** How a controller's request went: `pending` until a page reported, then what it said. */
8
+ export declare const uiOutcomeViewSchema: z.ZodObject<{
9
+ state: z.ZodEnum<{
10
+ done: "done";
11
+ pending: "pending";
12
+ }>;
13
+ ok: z.ZodOptional<z.ZodBoolean>;
14
+ message: z.ZodOptional<z.ZodString>;
15
+ detail: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
5
16
  }, z.core.$strip>;
6
17
  /** What Studio is doing: its workspace, how many pages are open, and the recipe whose sample run is in progress. */
7
18
  export declare const studioStatusViewSchema: z.ZodObject<{
@@ -35,6 +46,7 @@ export declare const runStatusViewSchema: z.ZodObject<{
35
46
  }, z.core.$strip>>;
36
47
  }, z.core.$strip>>;
37
48
  }, z.core.$strip>;
49
+ export type UiOutcomeView = z.infer<typeof uiOutcomeViewSchema>;
38
50
  export type AskUiView = z.infer<typeof askUiViewSchema>;
39
51
  export type StudioStatusView = z.infer<typeof studioStatusViewSchema>;
40
52
  export type RunStatusView = z.infer<typeof runStatusViewSchema>;
@@ -4,6 +4,12 @@ export declare const uiRequestSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
4
4
  kind: z.ZodLiteral<"open">;
5
5
  path: z.ZodString;
6
6
  workspace: z.ZodOptional<z.ZodString>;
7
+ }, z.core.$strip>, z.ZodObject<{
8
+ kind: z.ZodLiteral<"pick">;
9
+ recipeId: z.ZodString;
10
+ selector: z.ZodOptional<z.ZodString>;
11
+ text: z.ZodOptional<z.ZodString>;
12
+ add: z.ZodOptional<z.ZodBoolean>;
7
13
  }, z.core.$strip>], "kind">;
8
14
  export type UiRequest = z.infer<typeof uiRequestSchema>;
9
15
  //# sourceMappingURL=ui-request.contract.d.ts.map
@@ -1,12 +1,32 @@
1
- import type { AskUiCommand, AskUiView } from '../studio-api';
1
+ import type { AskUiCommand, AskUiView, UiOutcomeCommand, UiOutcomeView, UiReportCommand } from '../studio-api';
2
2
  import type { StudioState } from './workspace.store';
3
3
  /**
4
4
  * Handles `ask-ui`: tells every open page what a controller (an agent, through the MCP server) asked for, so
5
- * the person watching sees it happen. Nothing is done server-side: the page does it the way a click would.
5
+ * the person watching sees it happen. Nothing is done server-side: the page does it the way a click would, and
6
+ * says how it went (`ui-report`).
6
7
  *
7
8
  * @param state - The server state holding the connected pages.
8
9
  * @param command - What to ask the pages.
9
- * @returns How many pages were listening; 0 means nobody has Studio open.
10
+ * @returns How many pages were listening (0 means nobody has Studio open) and the id to ask the outcome with.
10
11
  */
11
12
  export declare function handleAskUi(state: StudioState, command: AskUiCommand): AskUiView;
13
+ /**
14
+ * Handles `ui-report`: a page says how a controller's request went. The first answer stays: every open page gets the
15
+ * request, and a page that has nothing to do with it (another recipe open) does not report.
16
+ *
17
+ * @param state - The server state.
18
+ * @param command - The request's id and the outcome.
19
+ * @returns Whether the report was kept.
20
+ */
21
+ export declare function handleUiReport(state: StudioState, command: UiReportCommand): {
22
+ kept: boolean;
23
+ };
24
+ /**
25
+ * Handles `ui-outcome`: how a controller's request went.
26
+ *
27
+ * @param state - The server state.
28
+ * @param command - The request's id.
29
+ * @returns `pending` until a page reported, then what it said.
30
+ */
31
+ export declare function handleUiOutcome(state: StudioState, command: UiOutcomeCommand): UiOutcomeView;
12
32
  //# sourceMappingURL=ask-ui.handler.d.ts.map