@bastani/atomic 0.9.13 → 0.9.14-alpha.1

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.
Files changed (96) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/builtin/i-have-adhd/package.json +1 -1
  3. package/dist/builtin/intercom/package.json +1 -1
  4. package/dist/builtin/mcp/package.json +1 -1
  5. package/dist/builtin/subagents/package.json +1 -1
  6. package/dist/builtin/web-access/package.json +1 -1
  7. package/dist/builtin/workflows/CHANGELOG.md +12 -0
  8. package/dist/builtin/workflows/README.md +9 -0
  9. package/dist/builtin/workflows/builtin/adversarial-verification.ts +4 -0
  10. package/dist/builtin/workflows/builtin/classify-and-act.ts +4 -0
  11. package/dist/builtin/workflows/builtin/fan-out-and-synthesize.ts +4 -0
  12. package/dist/builtin/workflows/builtin/generate-and-filter.ts +4 -0
  13. package/dist/builtin/workflows/builtin/goal.ts +4 -0
  14. package/dist/builtin/workflows/builtin/loop-until-done.ts +4 -0
  15. package/dist/builtin/workflows/builtin/open-claude-design.ts +4 -0
  16. package/dist/builtin/workflows/builtin/ralph.ts +4 -0
  17. package/dist/builtin/workflows/builtin/tournament.ts +4 -0
  18. package/dist/builtin/workflows/package.json +1 -1
  19. package/dist/builtin/workflows/src/authoring/workflow.ts +9 -0
  20. package/dist/builtin/workflows/src/authoring.d.ts +3 -0
  21. package/dist/builtin/workflows/src/durable/completed-catalog.ts +13 -2
  22. package/dist/builtin/workflows/src/durable/workflow-heartbeat-anchor.ts +153 -0
  23. package/dist/builtin/workflows/src/engine/run-durable-stage-session.ts +28 -0
  24. package/dist/builtin/workflows/src/engine/run.ts +1 -0
  25. package/dist/builtin/workflows/src/extension/extension-runtime-state.ts +138 -0
  26. package/dist/builtin/workflows/src/extension/index.bundle.mjs +766 -4
  27. package/dist/builtin/workflows/src/extension/workflow-heartbeat-delivery.ts +197 -0
  28. package/dist/builtin/workflows/src/extension/workflow-heartbeat-notice.ts +115 -0
  29. package/dist/builtin/workflows/src/extension/workflow-heartbeat-scheduler.ts +962 -0
  30. package/dist/builtin/workflows/src/sdk-surface.ts +9 -0
  31. package/dist/builtin/workflows/src/shared/authoring-contract-ui.d.ts +1 -0
  32. package/dist/builtin/workflows/src/shared/authoring-contract-ui.ts +1 -0
  33. package/dist/builtin/workflows/src/shared/persistence-restore.ts +12 -0
  34. package/dist/builtin/workflows/src/shared/workflow-authoring-types.d.ts +1 -0
  35. package/dist/builtin/workflows/src/shared/workflow-authoring-types.ts +1 -0
  36. package/dist/builtin/workflows/src/shared/workflow-heartbeat-contract.d.ts +21 -0
  37. package/dist/builtin/workflows/src/shared/workflow-heartbeat-contract.ts +25 -0
  38. package/dist/core/extensions/index.d.ts +1 -0
  39. package/dist/core/extensions/index.d.ts.map +1 -1
  40. package/dist/core/extensions/index.js +1 -0
  41. package/dist/core/extensions/index.js.map +1 -1
  42. package/dist/core/extensions/ui-types.d.ts +26 -0
  43. package/dist/core/extensions/ui-types.d.ts.map +1 -1
  44. package/dist/core/extensions/ui-types.js +17 -1
  45. package/dist/core/extensions/ui-types.js.map +1 -1
  46. package/dist/core/tools/ask-user-question/ask-user-question.d.ts +21 -0
  47. package/dist/core/tools/ask-user-question/ask-user-question.d.ts.map +1 -1
  48. package/dist/core/tools/ask-user-question/ask-user-question.js +34 -9
  49. package/dist/core/tools/ask-user-question/ask-user-question.js.map +1 -1
  50. package/dist/core/tools/ask-user-question/view/components/multi-select-view.d.ts.map +1 -1
  51. package/dist/core/tools/ask-user-question/view/components/multi-select-view.js +5 -2
  52. package/dist/core/tools/ask-user-question/view/components/multi-select-view.js.map +1 -1
  53. package/dist/core/tools/ask-user-question/view/components/submit-picker.d.ts.map +1 -1
  54. package/dist/core/tools/ask-user-question/view/components/submit-picker.js +3 -1
  55. package/dist/core/tools/ask-user-question/view/components/submit-picker.js.map +1 -1
  56. package/dist/core/tools/ask-user-question/view/components/wrapping-select.d.ts.map +1 -1
  57. package/dist/core/tools/ask-user-question/view/components/wrapping-select.js +8 -1
  58. package/dist/core/tools/ask-user-question/view/components/wrapping-select.js.map +1 -1
  59. package/dist/index-extensions.d.ts +1 -1
  60. package/dist/index-extensions.d.ts.map +1 -1
  61. package/dist/index-extensions.js +1 -1
  62. package/dist/index-extensions.js.map +1 -1
  63. package/dist/modes/interactive/components/reserved-bottom-overlay.d.ts +95 -0
  64. package/dist/modes/interactive/components/reserved-bottom-overlay.d.ts.map +1 -0
  65. package/dist/modes/interactive/components/reserved-bottom-overlay.js +234 -0
  66. package/dist/modes/interactive/components/reserved-bottom-overlay.js.map +1 -0
  67. package/dist/modes/interactive/interactive-extension-custom-ui.js +94 -6
  68. package/dist/modes/interactive/interactive-extension-custom-ui.js.map +1 -1
  69. package/dist/modes/interactive/interactive-mode-base.d.ts +3 -0
  70. package/dist/modes/interactive/interactive-mode-base.d.ts.map +1 -1
  71. package/dist/modes/interactive/interactive-mode-base.js +5 -1
  72. package/dist/modes/interactive/interactive-mode-base.js.map +1 -1
  73. package/dist/modes/interactive/interactive-mode-surface.d.ts +2 -0
  74. package/dist/modes/interactive/interactive-mode-surface.d.ts.map +1 -1
  75. package/dist/modes/interactive/interactive-mode-surface.js.map +1 -1
  76. package/dist/modes/interactive/interactive-tui.d.ts +3 -0
  77. package/dist/modes/interactive/interactive-tui.d.ts.map +1 -1
  78. package/dist/modes/interactive/interactive-tui.js +14 -0
  79. package/dist/modes/interactive/interactive-tui.js.map +1 -1
  80. package/dist/modes/interactive-engine/engine-custom-ui.d.ts +2 -0
  81. package/dist/modes/interactive-engine/engine-custom-ui.d.ts.map +1 -1
  82. package/dist/modes/interactive-engine/engine-custom-ui.js +1 -0
  83. package/dist/modes/interactive-engine/engine-custom-ui.js.map +1 -1
  84. package/dist/modes/interactive-engine/protocol.d.ts +1 -0
  85. package/dist/modes/interactive-engine/protocol.d.ts.map +1 -1
  86. package/dist/modes/interactive-engine/protocol.js +1 -0
  87. package/dist/modes/interactive-engine/protocol.js.map +1 -1
  88. package/dist/modes/interactive-engine/remote-component.d.ts +3 -1
  89. package/dist/modes/interactive-engine/remote-component.d.ts.map +1 -1
  90. package/dist/modes/interactive-engine/remote-component.js +3 -2
  91. package/dist/modes/interactive-engine/remote-component.js.map +1 -1
  92. package/docs/extensions.md +27 -0
  93. package/docs/keybindings.md +1 -0
  94. package/docs/workflows.md +34 -0
  95. package/npm-shrinkwrap.json +29 -29
  96. package/package.json +2 -2
@@ -8,6 +8,15 @@
8
8
  export type { Static, TSchema } from "typebox";
9
9
  export { KEEP_CONTEXT_CLOSE_TAG, KEEP_CONTEXT_OPEN_TAG, keepContext } from "./authoring/keep-context.js";
10
10
  export { workflow } from "./authoring/workflow.js";
11
+ export type {
12
+ WorkflowHeartbeatEvent,
13
+ WorkflowHeartbeatEventDetails,
14
+ WorkflowHeartbeatIdentity,
15
+ } from "./shared/workflow-heartbeat-contract.js";
16
+ export {
17
+ DEFAULT_WORKFLOW_HEARTBEAT_INTERVAL_MINUTES,
18
+ WORKFLOW_HEARTBEAT_CUSTOM_TYPE,
19
+ } from "./shared/workflow-heartbeat-contract.js";
11
20
 
12
21
  const REMOVED_RUN_WORKFLOW_MESSAGE =
13
22
  "@bastani/workflows no longer exports runWorkflow; author workflows with workflow({...})";
@@ -149,6 +149,7 @@ export interface WorkflowDefinition<TInputs extends WorkflowInputValues = Workfl
149
149
  readonly normalizedName: string;
150
150
  readonly description: string;
151
151
  readonly autoAttach?: true;
152
+ readonly heartbeatIntervalMinutes: number;
152
153
  readonly inputs: WorkflowInputSchemaMap;
153
154
  readonly outputs?: WorkflowOutputSchemaMap;
154
155
  readonly inputBindings?: WorkflowInputBindings;
@@ -235,6 +235,7 @@ export interface WorkflowDefinition<
235
235
  readonly normalizedName: string;
236
236
  readonly description: string;
237
237
  readonly autoAttach?: true;
238
+ readonly heartbeatIntervalMinutes: number;
238
239
  readonly inputs: WorkflowInputSchemaMap;
239
240
  readonly outputs?: WorkflowOutputSchemaMap;
240
241
  readonly inputBindings?: WorkflowInputBindings;
@@ -35,6 +35,18 @@ export interface SessionEntry {
35
35
  readonly payload?: Record<string, WorkflowSerializableValue>;
36
36
  readonly customType?: string;
37
37
  readonly data?: Record<string, WorkflowSerializableValue>;
38
+ /**
39
+ * The payload a custom-message entry was published with. Distinct from
40
+ * `data`: this is what an extension passed as `details`, so a heartbeat entry
41
+ * carries its `WorkflowHeartbeatEventDetails` here. Read only to recover a
42
+ * heartbeat's identity structurally rather than by parsing its rendered text.
43
+ *
44
+ * `unknown` deliberately: the host declares this generic and any extension
45
+ * may write any shape into it, so every reader narrows. Typing it as a known
46
+ * record here would be a claim about other extensions' data that nothing
47
+ * enforces.
48
+ */
49
+ readonly details?: unknown;
38
50
  }
39
51
 
40
52
  export interface NormalizedSessionEntry {
@@ -47,6 +47,7 @@ export type WorkflowRunOutputResult<TOutputs extends WorkflowOutputSchemaMap, TA
47
47
  export interface AuthoredWorkflowSpec<TInputs extends WorkflowInputSchemaMap = Record<never, never>, TOutputs extends WorkflowOutputSchemaMap = WorkflowOutputSchemaMap, TActualOutputs extends WorkflowOutputsFromSchemas<TOutputs> = WorkflowOutputsFromSchemas<TOutputs>, TRunContext = unknown> {
48
48
  readonly name?: string;
49
49
  readonly autoAttach?: boolean;
50
+ readonly heartbeatIntervalMinutes?: number;
50
51
  readonly description: string;
51
52
  readonly inputs?: TInputs;
52
53
  readonly outputs: TOutputs;
@@ -97,6 +97,7 @@ export interface AuthoredWorkflowSpec<
97
97
  > {
98
98
  readonly name?: string;
99
99
  readonly autoAttach?: boolean;
100
+ readonly heartbeatIntervalMinutes?: number;
100
101
  readonly description: string;
101
102
  readonly inputs?: TInputs;
102
103
  readonly outputs: TOutputs;
@@ -0,0 +1,21 @@
1
+ /** Cadence used when a workflow definition omits `heartbeatIntervalMinutes`. */
2
+ export declare const DEFAULT_WORKFLOW_HEARTBEAT_INTERVAL_MINUTES = 15;
3
+ export declare const WORKFLOW_HEARTBEAT_CUSTOM_TYPE = "workflows:workflow-heartbeat";
4
+ /** Stable identity for one scheduled boundary of a workflow run. */
5
+ export interface WorkflowHeartbeatIdentity {
6
+ readonly runId: string;
7
+ /** Unix timestamp in milliseconds for the cadence boundary. */
8
+ readonly scheduledAt: number;
9
+ }
10
+ /** Deterministic context carried by a workflow heartbeat event. */
11
+ export interface WorkflowHeartbeatEventDetails extends WorkflowHeartbeatIdentity {
12
+ readonly workflowName: string;
13
+ /** Persisted workflow start timestamp in Unix milliseconds. */
14
+ readonly startedAt: number;
15
+ readonly intervalMinutes: number;
16
+ }
17
+ /** Slice-1 event envelope; scheduling and delivery are wired separately. */
18
+ export interface WorkflowHeartbeatEvent {
19
+ readonly customType: typeof WORKFLOW_HEARTBEAT_CUSTOM_TYPE;
20
+ readonly details: WorkflowHeartbeatEventDetails;
21
+ }
@@ -0,0 +1,25 @@
1
+ /** Cadence used when a workflow definition omits `heartbeatIntervalMinutes`. */
2
+ export const DEFAULT_WORKFLOW_HEARTBEAT_INTERVAL_MINUTES = 15;
3
+
4
+ export const WORKFLOW_HEARTBEAT_CUSTOM_TYPE = "workflows:workflow-heartbeat";
5
+
6
+ /** Stable identity for one scheduled boundary of a workflow run. */
7
+ export interface WorkflowHeartbeatIdentity {
8
+ readonly runId: string;
9
+ /** Unix timestamp in milliseconds for the cadence boundary. */
10
+ readonly scheduledAt: number;
11
+ }
12
+
13
+ /** Deterministic context carried by a workflow heartbeat event. */
14
+ export interface WorkflowHeartbeatEventDetails extends WorkflowHeartbeatIdentity {
15
+ readonly workflowName: string;
16
+ /** Persisted workflow start timestamp in Unix milliseconds. */
17
+ readonly startedAt: number;
18
+ readonly intervalMinutes: number;
19
+ }
20
+
21
+ /** Slice-1 event envelope; scheduling and delivery are wired separately. */
22
+ export interface WorkflowHeartbeatEvent {
23
+ readonly customType: typeof WORKFLOW_HEARTBEAT_CUSTOM_TYPE;
24
+ readonly details: WorkflowHeartbeatEventDetails;
25
+ }
@@ -14,5 +14,6 @@ export { ExtensionRunner } from "./runner.ts";
14
14
  export { isStaleExtensionContextError, STALE_EXTENSION_CONTEXT_MARKER } from "./stale-context.ts";
15
15
  export type { AfterProviderResponseEvent, AgentEndEvent, AgentSettledEvent, AgentStartEvent, AgentToolResult, AgentToolUpdateCallback, AppendEntryHandler, AppKeybinding, AutocompleteProviderFactory, BashToolCallEvent, BashToolResultEvent, BeforeAgentStartEvent, BeforeAgentStartEventResult, BeforeProviderHeadersEvent, BeforeProviderRequestEvent, BeforeProviderRequestEventResult, BuildSystemPromptOptions, CompactOptions, ContextEvent, ContextEventResult, ContextUsage, CustomMessageDelivery, CustomToolCallEvent, CustomToolResultEvent, EditorFactory, EditToolCallEvent, EditToolResultEvent, EntryRenderer, EntryRenderOptions, ExecOptions, ExecResult, Extension, ExtensionActions, ExtensionAPI, ExtensionCommandContext, ExtensionCommandContextActions, ExtensionContext, ExtensionContextActions, ExtensionCustomComponent, ExtensionError, ExtensionEvent, ExtensionFactory, ExtensionFlag, ExtensionHandler, ExtensionMode, ExtensionRuntime, ExtensionScopedModels, ExtensionShortcut, ExtensionUIContext, ExtensionUIDialogOptions, ExtensionWidgetOptions, FindToolCallEvent, FindToolResultEvent, GetActiveToolsHandler, GetAllToolsHandler, GetCommandsHandler, GetThinkingLevelHandler, HostCustomUiState, HostCustomUiStateListener, HostInputFormField, HostInputFormFieldType, HostInputFormRequest, HostSessionPickerHandle, HostSessionPickerRequest, HostSessionPickerRow, InlineExtension, InputEvent, InputEventResult, InputSource, KeybindingsManager, LoadExtensionsResult, LsToolCallEvent, LsToolResultEvent, MarkdownTransformContext, MarkdownTransformer, MessageEndEvent, MessageRenderer, MessageRenderOptions, MessageStartEvent, MessageUpdateEvent, ModelSelectEvent, ModelSelectSource, OrchestrationContext, ProjectTrustContext, ProjectTrustEvent, ProjectTrustEventDecision, ProjectTrustEventResult, ProjectTrustHandler, ProviderConfig, ProviderModelConfig, ReadToolCallEvent, ReadToolResultEvent, RegisteredCommand, RegisteredTool, ReplacedSessionContext, ResolvedCommand, ResourcesDiscoverEvent, ResourcesDiscoverResult, ScopedModel, SendMessageHandler, SendMessageOptions, SendMessagesHandler, SendMessagesOptions, SendUserMessageHandler, SessionBeforeCompactEvent, SessionBeforeCompactResult, SessionBeforeForkEvent, SessionBeforeForkResult, SessionBeforeSwitchEvent, SessionBeforeSwitchResult, SessionBeforeTreeEvent, SessionBeforeTreeResult, SessionCompactEvent, SessionEvent, SessionInfoChangedEvent, SessionShutdownEvent, SessionStartEvent, SessionTreeEvent, SetActiveToolsHandler, SetLabelHandler, SetModelHandler, SetThinkingLevelHandler, SubagentChildPolicy, SubagentIntercomIdentity, TerminalInputHandler, ToolCallEvent, ToolCallEventResult, ToolDefinition, ToolExecutionEndEvent, ToolExecutionMode, ToolExecutionStartEvent, ToolExecutionUpdateEvent, ToolInfo, ToolRenderResultOptions, ToolResultEvent, ToolResultEventResult, TreePreparation, TurnEndEvent, TurnStartEvent, UserBashEvent, UserBashEventResult, WidgetPlacement, WorkflowStageOrchestrationContext, WorkingIndicatorOptions, WriteToolCallEvent, WriteToolResultEvent, } from "./types.ts";
16
16
  export { defineTool, isBashToolResult, isEditToolResult, isFindToolResult, isLsToolResult, isReadToolResult, isSearchToolResult, isToolCallEventType, isWriteToolResult, } from "./types.ts";
17
+ export { OVERLAY_ACTIVE_ROW_MARKER } from "./ui-types.ts";
17
18
  export { wrapRegisteredTool, wrapRegisteredTools } from "./wrapper.ts";
18
19
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/extensions/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/extensions/index.ts"],"names":[],"mappings":"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"}
@@ -7,5 +7,6 @@ export { ExtensionRunner } from "./runner.js";
7
7
  export { isStaleExtensionContextError, STALE_EXTENSION_CONTEXT_MARKER } from "./stale-context.js";
8
8
  // Type guards
9
9
  export { defineTool, isBashToolResult, isEditToolResult, isFindToolResult, isLsToolResult, isReadToolResult, isSearchToolResult, isToolCallEventType, isWriteToolResult, } from "./types.js";
10
+ export { OVERLAY_ACTIVE_ROW_MARKER } from "./ui-types.js";
10
11
  export { wrapRegisteredTool, wrapRegisteredTools } from "./wrapper.js";
11
12
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/core/extensions/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAOH,OAAO,EACN,sBAAsB,EACtB,yBAAyB,EACzB,wBAAwB,EACxB,cAAc,GACd,MAAM,aAAa,CAAC;AAerB,OAAO,EACN,0BAA0B,EAC1B,qBAAqB,GACrB,MAAM,sBAAsB,CAAC;AAS9B,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,4BAA4B,EAAE,8BAA8B,EAAE,MAAM,oBAAoB,CAAC;AA0KlG,cAAc;AACd,OAAO,EACN,UAAU,EACV,gBAAgB,EAChB,gBAAgB,EAChB,gBAAgB,EAChB,cAAc,EACd,gBAAgB,EAChB,kBAAkB,EAClB,mBAAmB,EACnB,iBAAiB,GACjB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC","sourcesContent":["/**\n * Extension system for lifecycle events and custom tools.\n */\n\nexport type { ConstrainedSamplingConfig } from \"@earendil-works/pi-ai/compat\";\nexport type { AtomicProviderCompat } from \"../model-capabilities.ts\";\nexport type { SlashCommandInfo, SlashCommandSource } from \"../slash-commands.ts\";\nexport type { SourceInfo } from \"../source-info.ts\";\nexport type { WorkflowResourceProvider, WorkflowResourceProviderInput } from \"./loader.ts\";\nexport {\n\tcreateExtensionRuntime,\n\tdiscoverAndLoadExtensions,\n\tloadExtensionFromFactory,\n\tloadExtensions,\n} from \"./loader.ts\";\nexport type {\n\tInstallReactiveWidgetOptions,\n\tReactiveWidgetAction,\n\tReactiveWidgetComponent,\n\tReactiveWidgetController,\n\tReactiveWidgetFactory,\n\tReactiveWidgetRefreshReason,\n\tReactiveWidgetRenderContext,\n\tReactiveWidgetRenderState,\n\tReactiveWidgetScheduler,\n\tReactiveWidgetTimerApi,\n\tReactiveWidgetTimerHandle,\n\tReactiveWidgetUi,\n} from \"./reactive-widget.ts\";\nexport {\n\tdecideReactiveWidgetAction,\n\tinstallReactiveWidget,\n} from \"./reactive-widget.ts\";\nexport type {\n\tExtensionErrorListener,\n\tForkHandler,\n\tNavigateTreeHandler,\n\tNewSessionHandler,\n\tShutdownHandler,\n\tSwitchSessionHandler,\n} from \"./runner.ts\";\nexport { ExtensionRunner } from \"./runner.ts\";\nexport { isStaleExtensionContextError, STALE_EXTENSION_CONTEXT_MARKER } from \"./stale-context.ts\";\nexport type {\n\tAfterProviderResponseEvent,\n\tAgentEndEvent,\n\tAgentSettledEvent,\n\tAgentStartEvent,\n\t// Re-exports\n\tAgentToolResult,\n\tAgentToolUpdateCallback,\n\tAppendEntryHandler,\n\t// App keybindings (for custom editors)\n\tAppKeybinding,\n\tAutocompleteProviderFactory,\n\t// Events - Tool (ToolCallEvent types)\n\tBashToolCallEvent,\n\tBashToolResultEvent,\n\tBeforeAgentStartEvent,\n\tBeforeAgentStartEventResult,\n\tBeforeProviderHeadersEvent,\n\tBeforeProviderRequestEvent,\n\tBeforeProviderRequestEventResult,\n\tBuildSystemPromptOptions,\n\t// Context\n\tCompactOptions,\n\t// Events - Agent\n\tContextEvent,\n\t// Event Results\n\tContextEventResult,\n\tContextUsage,\n\tCustomMessageDelivery,\n\tCustomToolCallEvent,\n\tCustomToolResultEvent,\n\tEditorFactory,\n\tEditToolCallEvent,\n\tEditToolResultEvent,\n\t// Message Rendering\n\tEntryRenderer,\n\tEntryRenderOptions,\n\tExecOptions,\n\tExecResult,\n\tExtension,\n\tExtensionActions,\n\t// API\n\tExtensionAPI,\n\tExtensionCommandContext,\n\tExtensionCommandContextActions,\n\tExtensionContext,\n\tExtensionContextActions,\n\tExtensionCustomComponent,\n\t// Errors\n\tExtensionError,\n\tExtensionEvent,\n\tExtensionFactory,\n\tExtensionFlag,\n\tExtensionHandler,\n\tExtensionMode,\n\t// Runtime\n\tExtensionRuntime,\n\tExtensionScopedModels,\n\tExtensionShortcut,\n\tExtensionUIContext,\n\tExtensionUIDialogOptions,\n\tExtensionWidgetOptions,\n\tFindToolCallEvent,\n\tFindToolResultEvent,\n\tGetActiveToolsHandler,\n\tGetAllToolsHandler,\n\tGetCommandsHandler,\n\tGetThinkingLevelHandler,\n\tHostCustomUiState,\n\tHostCustomUiStateListener,\n\tHostInputFormField,\n\tHostInputFormFieldType,\n\tHostInputFormRequest,\n\tHostSessionPickerHandle,\n\tHostSessionPickerRequest,\n\tHostSessionPickerRow,\n\tInlineExtension,\n\t// Events - Input\n\tInputEvent,\n\tInputEventResult,\n\tInputSource,\n\tKeybindingsManager,\n\tLoadExtensionsResult,\n\tLsToolCallEvent,\n\tLsToolResultEvent,\n\tMarkdownTransformContext,\n\tMarkdownTransformer,\n\t// Events - Message\n\tMessageEndEvent,\n\tMessageRenderer,\n\tMessageRenderOptions,\n\tMessageStartEvent,\n\tMessageUpdateEvent,\n\tModelSelectEvent,\n\tModelSelectSource,\n\tOrchestrationContext,\n\tProjectTrustContext,\n\tProjectTrustEvent,\n\tProjectTrustEventDecision,\n\tProjectTrustEventResult,\n\tProjectTrustHandler,\n\t// Provider Registration\n\tProviderConfig,\n\tProviderModelConfig,\n\tReadToolCallEvent,\n\tReadToolResultEvent,\n\t// Commands\n\tRegisteredCommand,\n\tRegisteredTool,\n\tReplacedSessionContext,\n\tResolvedCommand,\n\t// Events - Resources\n\tResourcesDiscoverEvent,\n\tResourcesDiscoverResult,\n\tScopedModel,\n\tSendMessageHandler,\n\tSendMessageOptions,\n\tSendMessagesHandler,\n\tSendMessagesOptions,\n\tSendUserMessageHandler,\n\tSessionBeforeCompactEvent,\n\tSessionBeforeCompactResult,\n\tSessionBeforeForkEvent,\n\tSessionBeforeForkResult,\n\tSessionBeforeSwitchEvent,\n\tSessionBeforeSwitchResult,\n\tSessionBeforeTreeEvent,\n\tSessionBeforeTreeResult,\n\tSessionCompactEvent,\n\tSessionEvent,\n\tSessionInfoChangedEvent,\n\tSessionShutdownEvent,\n\t// Events - Session\n\tSessionStartEvent,\n\tSessionTreeEvent,\n\tSetActiveToolsHandler,\n\tSetLabelHandler,\n\tSetModelHandler,\n\tSetThinkingLevelHandler,\n\tSubagentChildPolicy,\n\tSubagentIntercomIdentity,\n\tTerminalInputHandler,\n\t// Events - Tool\n\tToolCallEvent,\n\tToolCallEventResult,\n\t// Tools\n\tToolDefinition,\n\t// Events - Tool Execution\n\tToolExecutionEndEvent,\n\t// Tool execution mode\n\tToolExecutionMode,\n\tToolExecutionStartEvent,\n\tToolExecutionUpdateEvent,\n\tToolInfo,\n\tToolRenderResultOptions,\n\tToolResultEvent,\n\tToolResultEventResult,\n\tTreePreparation,\n\tTurnEndEvent,\n\tTurnStartEvent,\n\t// Events - User Bash\n\tUserBashEvent,\n\tUserBashEventResult,\n\tWidgetPlacement,\n\tWorkflowStageOrchestrationContext,\n\tWorkingIndicatorOptions,\n\tWriteToolCallEvent,\n\tWriteToolResultEvent,\n} from \"./types.ts\";\n// Type guards\nexport {\n\tdefineTool,\n\tisBashToolResult,\n\tisEditToolResult,\n\tisFindToolResult,\n\tisLsToolResult,\n\tisReadToolResult,\n\tisSearchToolResult,\n\tisToolCallEventType,\n\tisWriteToolResult,\n} from \"./types.ts\";\nexport { wrapRegisteredTool, wrapRegisteredTools } from \"./wrapper.ts\";\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/core/extensions/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAOH,OAAO,EACN,sBAAsB,EACtB,yBAAyB,EACzB,wBAAwB,EACxB,cAAc,GACd,MAAM,aAAa,CAAC;AAerB,OAAO,EACN,0BAA0B,EAC1B,qBAAqB,GACrB,MAAM,sBAAsB,CAAC;AAS9B,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,4BAA4B,EAAE,8BAA8B,EAAE,MAAM,oBAAoB,CAAC;AA0KlG,cAAc;AACd,OAAO,EACN,UAAU,EACV,gBAAgB,EAChB,gBAAgB,EAChB,gBAAgB,EAChB,cAAc,EACd,gBAAgB,EAChB,kBAAkB,EAClB,mBAAmB,EACnB,iBAAiB,GACjB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,yBAAyB,EAAE,MAAM,eAAe,CAAC;AAC1D,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC","sourcesContent":["/**\n * Extension system for lifecycle events and custom tools.\n */\n\nexport type { ConstrainedSamplingConfig } from \"@earendil-works/pi-ai/compat\";\nexport type { AtomicProviderCompat } from \"../model-capabilities.ts\";\nexport type { SlashCommandInfo, SlashCommandSource } from \"../slash-commands.ts\";\nexport type { SourceInfo } from \"../source-info.ts\";\nexport type { WorkflowResourceProvider, WorkflowResourceProviderInput } from \"./loader.ts\";\nexport {\n\tcreateExtensionRuntime,\n\tdiscoverAndLoadExtensions,\n\tloadExtensionFromFactory,\n\tloadExtensions,\n} from \"./loader.ts\";\nexport type {\n\tInstallReactiveWidgetOptions,\n\tReactiveWidgetAction,\n\tReactiveWidgetComponent,\n\tReactiveWidgetController,\n\tReactiveWidgetFactory,\n\tReactiveWidgetRefreshReason,\n\tReactiveWidgetRenderContext,\n\tReactiveWidgetRenderState,\n\tReactiveWidgetScheduler,\n\tReactiveWidgetTimerApi,\n\tReactiveWidgetTimerHandle,\n\tReactiveWidgetUi,\n} from \"./reactive-widget.ts\";\nexport {\n\tdecideReactiveWidgetAction,\n\tinstallReactiveWidget,\n} from \"./reactive-widget.ts\";\nexport type {\n\tExtensionErrorListener,\n\tForkHandler,\n\tNavigateTreeHandler,\n\tNewSessionHandler,\n\tShutdownHandler,\n\tSwitchSessionHandler,\n} from \"./runner.ts\";\nexport { ExtensionRunner } from \"./runner.ts\";\nexport { isStaleExtensionContextError, STALE_EXTENSION_CONTEXT_MARKER } from \"./stale-context.ts\";\nexport type {\n\tAfterProviderResponseEvent,\n\tAgentEndEvent,\n\tAgentSettledEvent,\n\tAgentStartEvent,\n\t// Re-exports\n\tAgentToolResult,\n\tAgentToolUpdateCallback,\n\tAppendEntryHandler,\n\t// App keybindings (for custom editors)\n\tAppKeybinding,\n\tAutocompleteProviderFactory,\n\t// Events - Tool (ToolCallEvent types)\n\tBashToolCallEvent,\n\tBashToolResultEvent,\n\tBeforeAgentStartEvent,\n\tBeforeAgentStartEventResult,\n\tBeforeProviderHeadersEvent,\n\tBeforeProviderRequestEvent,\n\tBeforeProviderRequestEventResult,\n\tBuildSystemPromptOptions,\n\t// Context\n\tCompactOptions,\n\t// Events - Agent\n\tContextEvent,\n\t// Event Results\n\tContextEventResult,\n\tContextUsage,\n\tCustomMessageDelivery,\n\tCustomToolCallEvent,\n\tCustomToolResultEvent,\n\tEditorFactory,\n\tEditToolCallEvent,\n\tEditToolResultEvent,\n\t// Message Rendering\n\tEntryRenderer,\n\tEntryRenderOptions,\n\tExecOptions,\n\tExecResult,\n\tExtension,\n\tExtensionActions,\n\t// API\n\tExtensionAPI,\n\tExtensionCommandContext,\n\tExtensionCommandContextActions,\n\tExtensionContext,\n\tExtensionContextActions,\n\tExtensionCustomComponent,\n\t// Errors\n\tExtensionError,\n\tExtensionEvent,\n\tExtensionFactory,\n\tExtensionFlag,\n\tExtensionHandler,\n\tExtensionMode,\n\t// Runtime\n\tExtensionRuntime,\n\tExtensionScopedModels,\n\tExtensionShortcut,\n\tExtensionUIContext,\n\tExtensionUIDialogOptions,\n\tExtensionWidgetOptions,\n\tFindToolCallEvent,\n\tFindToolResultEvent,\n\tGetActiveToolsHandler,\n\tGetAllToolsHandler,\n\tGetCommandsHandler,\n\tGetThinkingLevelHandler,\n\tHostCustomUiState,\n\tHostCustomUiStateListener,\n\tHostInputFormField,\n\tHostInputFormFieldType,\n\tHostInputFormRequest,\n\tHostSessionPickerHandle,\n\tHostSessionPickerRequest,\n\tHostSessionPickerRow,\n\tInlineExtension,\n\t// Events - Input\n\tInputEvent,\n\tInputEventResult,\n\tInputSource,\n\tKeybindingsManager,\n\tLoadExtensionsResult,\n\tLsToolCallEvent,\n\tLsToolResultEvent,\n\tMarkdownTransformContext,\n\tMarkdownTransformer,\n\t// Events - Message\n\tMessageEndEvent,\n\tMessageRenderer,\n\tMessageRenderOptions,\n\tMessageStartEvent,\n\tMessageUpdateEvent,\n\tModelSelectEvent,\n\tModelSelectSource,\n\tOrchestrationContext,\n\tProjectTrustContext,\n\tProjectTrustEvent,\n\tProjectTrustEventDecision,\n\tProjectTrustEventResult,\n\tProjectTrustHandler,\n\t// Provider Registration\n\tProviderConfig,\n\tProviderModelConfig,\n\tReadToolCallEvent,\n\tReadToolResultEvent,\n\t// Commands\n\tRegisteredCommand,\n\tRegisteredTool,\n\tReplacedSessionContext,\n\tResolvedCommand,\n\t// Events - Resources\n\tResourcesDiscoverEvent,\n\tResourcesDiscoverResult,\n\tScopedModel,\n\tSendMessageHandler,\n\tSendMessageOptions,\n\tSendMessagesHandler,\n\tSendMessagesOptions,\n\tSendUserMessageHandler,\n\tSessionBeforeCompactEvent,\n\tSessionBeforeCompactResult,\n\tSessionBeforeForkEvent,\n\tSessionBeforeForkResult,\n\tSessionBeforeSwitchEvent,\n\tSessionBeforeSwitchResult,\n\tSessionBeforeTreeEvent,\n\tSessionBeforeTreeResult,\n\tSessionCompactEvent,\n\tSessionEvent,\n\tSessionInfoChangedEvent,\n\tSessionShutdownEvent,\n\t// Events - Session\n\tSessionStartEvent,\n\tSessionTreeEvent,\n\tSetActiveToolsHandler,\n\tSetLabelHandler,\n\tSetModelHandler,\n\tSetThinkingLevelHandler,\n\tSubagentChildPolicy,\n\tSubagentIntercomIdentity,\n\tTerminalInputHandler,\n\t// Events - Tool\n\tToolCallEvent,\n\tToolCallEventResult,\n\t// Tools\n\tToolDefinition,\n\t// Events - Tool Execution\n\tToolExecutionEndEvent,\n\t// Tool execution mode\n\tToolExecutionMode,\n\tToolExecutionStartEvent,\n\tToolExecutionUpdateEvent,\n\tToolInfo,\n\tToolRenderResultOptions,\n\tToolResultEvent,\n\tToolResultEventResult,\n\tTreePreparation,\n\tTurnEndEvent,\n\tTurnStartEvent,\n\t// Events - User Bash\n\tUserBashEvent,\n\tUserBashEventResult,\n\tWidgetPlacement,\n\tWorkflowStageOrchestrationContext,\n\tWorkingIndicatorOptions,\n\tWriteToolCallEvent,\n\tWriteToolResultEvent,\n} from \"./types.ts\";\n// Type guards\nexport {\n\tdefineTool,\n\tisBashToolResult,\n\tisEditToolResult,\n\tisFindToolResult,\n\tisLsToolResult,\n\tisReadToolResult,\n\tisSearchToolResult,\n\tisToolCallEventType,\n\tisWriteToolResult,\n} from \"./types.ts\";\nexport { OVERLAY_ACTIVE_ROW_MARKER } from \"./ui-types.ts\";\nexport { wrapRegisteredTool, wrapRegisteredTools } from \"./wrapper.ts\";\n"]}
@@ -38,6 +38,23 @@ export type ExtensionCustomComponent = Omit<Component, "handleInput"> & {
38
38
  handleInput?: (data: string) => boolean | undefined | Promise<boolean | undefined>;
39
39
  dispose?(): void;
40
40
  };
41
+ /**
42
+ * Zero-width mark a custom component may embed in the line it most needs kept
43
+ * on screen — the selected row of a list, say.
44
+ *
45
+ * A `reserveTranscriptRows` overlay is bounded against the terminal height, and
46
+ * on a short terminal that bound has to drop rows. Without a mark the host can
47
+ * only guess, and it guessed wrong: it kept a fixed number of rows from the top,
48
+ * so on a 16-to-22-row terminal the selected option was cropped away and the
49
+ * dialog looked frozen under the arrow keys. With the mark the host windows what
50
+ * it keeps around that row instead.
51
+ *
52
+ * It is an APC sequence, so pi-tui's `visibleWidth` measures it as zero and
53
+ * terminals ignore it — the same mechanism as pi-tui's own `CURSOR_MARKER`, but
54
+ * private to Atomic and stripped by the host before the line is painted. Embed
55
+ * it once per frame; the host uses the first line that carries it.
56
+ */
57
+ export declare const OVERLAY_ACTIVE_ROW_MARKER = "\u001B_atomic:active\u0007";
41
58
  export interface ChatRenderSettings {
42
59
  hideThinkingBlock: boolean;
43
60
  hiddenThinkingLabel: string;
@@ -212,6 +229,15 @@ export interface ExtensionUIContext {
212
229
  handlesCtrlC?: boolean;
213
230
  /** Declare that this component claims internal UI actions such as the jump-to-bottom URL. */
214
231
  handlesInternalUiAction?: boolean;
232
+ /**
233
+ * Overlay-only. Bound this overlay's height so a transcript strip stays
234
+ * visible, and extend the transcript's scroll extent by the rows it
235
+ * still covers, so every line of the scrollback can be brought above it.
236
+ *
237
+ * Set it for a blocking bottom-anchored dialog. Leave it unset for an
238
+ * overlay that is meant to take the screen, such as a full-screen graph.
239
+ */
240
+ reserveTranscriptRows?: boolean;
215
241
  /** AbortSignal to programmatically dismiss the custom UI. */
216
242
  signal?: AbortSignal;
217
243
  /** Overlay positioning/sizing options. Can be static or a function for dynamic updates. */
@@ -1 +1 @@
1
- {"version":3,"file":"ui-types.d.ts","sourceRoot":"","sources":["../../../src/core/extensions/ui-types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ui-types.d.ts","sourceRoot":"","sources":["../../../src/core/extensions/ui-types.ts"],"names":[],"mappings":"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"}
@@ -1,2 +1,18 @@
1
- export {};
1
+ /**
2
+ * Zero-width mark a custom component may embed in the line it most needs kept
3
+ * on screen — the selected row of a list, say.
4
+ *
5
+ * A `reserveTranscriptRows` overlay is bounded against the terminal height, and
6
+ * on a short terminal that bound has to drop rows. Without a mark the host can
7
+ * only guess, and it guessed wrong: it kept a fixed number of rows from the top,
8
+ * so on a 16-to-22-row terminal the selected option was cropped away and the
9
+ * dialog looked frozen under the arrow keys. With the mark the host windows what
10
+ * it keeps around that row instead.
11
+ *
12
+ * It is an APC sequence, so pi-tui's `visibleWidth` measures it as zero and
13
+ * terminals ignore it — the same mechanism as pi-tui's own `CURSOR_MARKER`, but
14
+ * private to Atomic and stripped by the host before the line is painted. Embed
15
+ * it once per frame; the host uses the first line that carries it.
16
+ */
17
+ export const OVERLAY_ACTIVE_ROW_MARKER = "\u001B_atomic:active\u0007";
2
18
  //# sourceMappingURL=ui-types.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ui-types.js","sourceRoot":"","sources":["../../../src/core/extensions/ui-types.ts"],"names":[],"mappings":"","sourcesContent":["import type {\n\tAutocompleteProvider,\n\tComponent,\n\tEditorComponent,\n\tEditorTheme,\n\tOverlayHandle,\n\tOverlayOptions,\n\tTUI,\n} from \"@earendil-works/pi-tui\";\nimport type { Theme } from \"../../modes/interactive/theme/theme.ts\";\nimport type { ReadonlyFooterDataProvider } from \"../footer-data-provider.ts\";\nimport type { KeybindingsManager } from \"../keybindings.ts\";\nimport type { MarkdownTransformer, MessageRenderer } from \"./message-types.ts\";\nimport type { ToolDefinition } from \"./tool-types.ts\";\n\n/** Options for extension UI dialogs. */\nexport interface ExtensionUIDialogOptions {\n\t/** AbortSignal to programmatically dismiss the dialog. */\n\tsignal?: AbortSignal;\n\t/** Timeout in milliseconds. Dialog auto-dismisses with live countdown display. */\n\ttimeout?: number;\n}\n\n/** Placement for extension widgets. */\nexport type WidgetPlacement = \"aboveEditor\" | \"belowEditor\";\n\n/** Options for extension widgets. */\nexport interface ExtensionWidgetOptions {\n\t/** Where the widget is rendered. Defaults to \"aboveEditor\". */\n\tplacement?: WidgetPlacement;\n}\n\n/** Raw terminal input listener for extensions. */\nexport type TerminalInputHandler = (data: string) => { consume?: boolean; data?: string } | undefined;\n\n/** Working indicator configuration for the interactive Working lifecycle. */\nexport interface WorkingIndicatorOptions {\n\t/** Animation frames. Use an empty array to hide the indicator entirely. Custom frames are rendered verbatim. */\n\tframes?: string[];\n\t/** Frame interval in milliseconds for animated indicators. */\n\tintervalMs?: number;\n}\n\n/** Wrap the current autocomplete provider with additional behavior. */\nexport type AutocompleteProviderFactory = (current: AutocompleteProvider) => AutocompleteProvider;\nexport type EditorFactory = (tui: TUI, theme: EditorTheme, keybindings: KeybindingsManager) => EditorComponent;\n/** Component returned by `ctx.ui.custom()`. Input handlers must report whether they consumed the key. */\nexport type ExtensionCustomComponent = Omit<Component, \"handleInput\"> & {\n\thandleInput?: (data: string) => boolean | undefined | Promise<boolean | undefined>;\n\tdispose?(): void;\n};\n\nexport interface ChatRenderSettings {\n\thideThinkingBlock: boolean;\n\thiddenThinkingLabel: string;\n\ttoolOutputExpanded: boolean;\n\tshowImages: boolean;\n\timageWidthCells: number;\n\tmarkdownTransformers: readonly MarkdownTransformer[];\n\trenderLatex?: boolean;\n\tgetToolDefinition(toolName: string): ToolDefinition | undefined;\n\tgetCustomMessageRenderer(customType: string): MessageRenderer | undefined;\n}\n\n/** Host-owned inline custom UI focus state exposed to overlays without prompt content. */\nexport interface HostCustomUiState {\n\t/** Number of active non-overlay host custom UI mounts. */\n\tblockingInlineCustomUiDepth: number;\n\t/** True when at least one non-overlay host custom UI is mounted and blocking. */\n\tblockingInlineCustomUiActive: boolean;\n\t/** True when the active inline custom UI is waiting behind an overlay that kept focus. */\n\tblockingInlineCustomUiFocusDeferred?: boolean;\n}\n\nexport type HostCustomUiStateListener = (state: HostCustomUiState) => void;\n\n/** Supported field kinds for the host-native input form. */\nexport type HostInputFormFieldType = \"string\" | \"text\" | \"number\" | \"integer\" | \"boolean\" | \"select\";\n\n/** JSON-safe field descriptor for {@link ExtensionUIContext.hostInputForm}. */\nexport interface HostInputFormField {\n\tname: string;\n\ttype: HostInputFormFieldType;\n\tdescription?: string;\n\trequired?: boolean;\n\tchoices?: string[];\n\tplaceholder?: string;\n\t/** Raw, display-ready initial value. */\n\tinitialValue: string;\n}\n\n/** Request for a host-owned inline input form. */\nexport interface HostInputFormRequest {\n\ttitle: string;\n\tfields: HostInputFormField[];\n\t/** Panel heading label. Defaults to \"WORKFLOW INPUTS\". */\n\theading?: string;\n\t/** Submit button label. Defaults to \"[ Run workflow ]\". */\n\tsubmitLabel?: string;\n}\n\n/**\n * JSON-safe session-selector row for the host-native session picker.\n * Mirrors `SessionInfo` with `created`/`modified` flattened to epoch millis so\n * rows can cross the interactive-engine protocol without `Date` objects.\n */\nexport interface HostSessionPickerRow {\n\tpath: string;\n\tid: string;\n\tcwd: string;\n\t/** Creation time in epoch milliseconds. */\n\tcreatedAt: number;\n\t/** Last-modified time in epoch milliseconds. */\n\tmodifiedAt: number;\n\tmessageCount: number;\n\tfirstMessage: string;\n\t/** Generated resume summary. Absent when never generated, or stale against the latest message. */\n\tsummary?: string;\n\tallMessagesText?: string;\n\tname?: string;\n\t/** Optional semantic color for synthetic selector rows. */\n\tmessageColor?: \"success\" | \"warning\" | \"accent\" | \"error\";\n}\n\n/** Request for {@link ExtensionUIContext.hostSessionPicker}. */\nexport interface HostSessionPickerRequest {\n\t/** Rows shown in the first frame. Push later rows via the handle's `update()`. */\n\tsessions: HostSessionPickerRow[];\n\t/** Show the rename keybinding hint in the picker header. Defaults to false. */\n\tshowRenameHint?: boolean;\n\t/**\n\t * Invoked after the user confirms a Ctrl+D delete on a row. The host does\n\t * NOT remove the row; reply with `update()` (row removed) or `error()`.\n\t */\n\tonDelete?: (path: string) => void | Promise<void>;\n}\n\n/** Live control surface for an open host-native session picker. */\nexport interface HostSessionPickerHandle {\n\t/** Resolves with the selected row's `path`, or `undefined` on cancel/close. */\n\tresult: Promise<string | undefined>;\n\t/** Replace the picker rows (navigation/search state is preserved host-side). */\n\tupdate(sessions: HostSessionPickerRow[]): void;\n\t/** Surface a transient error message in the picker header. */\n\terror(message: string): void;\n\t/** Close the picker; `result` resolves `undefined`. Idempotent. */\n\tclose(): void;\n}\n\n/**\n * UI context for extensions to request interactive UI.\n * Each mode (interactive, RPC, print) provides its own implementation.\n */\nexport interface ExtensionUIContext {\n\t/** Show a selector and return the user's choice. */\n\tselect(title: string, options: string[], opts?: ExtensionUIDialogOptions): Promise<string | undefined>;\n\n\t/** Show a confirmation dialog. */\n\tconfirm(title: string, message: string, opts?: ExtensionUIDialogOptions): Promise<boolean>;\n\n\t/** Show a text input dialog. */\n\tinput(title: string, placeholder?: string, opts?: ExtensionUIDialogOptions): Promise<string | undefined>;\n\n\t/** Show a notification to the user. */\n\tnotify(message: string, type?: \"info\" | \"warning\" | \"error\"): void;\n\n\t/** Request an interactive repaint after extension-owned state changes. */\n\trequestRender(): void;\n\n\t/** Get host-owned inline custom UI focus state, if the mode exposes it. */\n\tgetHostCustomUiState?(): HostCustomUiState;\n\n\t/** Observe host-owned inline custom UI focus state changes. Returns an unsubscribe function. */\n\tonHostCustomUiStateChange?(listener: HostCustomUiStateListener): () => void;\n\n\t/** Move focus to a mounted host-owned inline custom UI, if one is pending. */\n\tfocusHostInlineCustomUi?(): boolean;\n\n\t/** Listen to raw terminal input (interactive mode only). Returns an unsubscribe function. */\n\tonTerminalInput(handler: TerminalInputHandler): () => void;\n\n\t/** Set status text in the footer/status bar. Pass undefined to clear. */\n\tsetStatus(key: string, text: string | undefined): void;\n\n\t/**\n\t * Set the working/loading message presented during the active Working lifecycle,\n\t * from accepted prompt startup through the agent turn. This customizes\n\t * presentation only; it does not start work or emit pre-start events. Call with\n\t * no argument to restore the default.\n\t */\n\tsetWorkingMessage(message?: string): void;\n\n\t/**\n\t * Show or hide the built-in row during the active Working lifecycle.\n\t * This customizes presentation only; it does not start or stop work.\n\t */\n\tsetWorkingVisible(visible: boolean): void;\n\n\t/**\n\t * Configure the interactive indicator presented during the active Working\n\t * lifecycle, from accepted prompt startup through the agent turn. This\n\t * customizes presentation only; it does not start work or emit pre-start events.\n\t *\n\t * - Omit the argument to restore the default animated spinner.\n\t * - Use `frames: [\"●\"]` for a static indicator.\n\t * - Use `frames: []` to hide the indicator entirely.\n\t * - Custom frames are rendered as provided, so extensions must add their own colors.\n\t */\n\tsetWorkingIndicator(options?: WorkingIndicatorOptions): void;\n\n\t/** Set the label shown for hidden thinking blocks. Call with no argument to restore default. */\n\tsetHiddenThinkingLabel(label?: string): void;\n\n\t/** Set a widget to display above or below the editor. Accepts string array or component factory. */\n\tsetWidget(key: string, content: string[] | undefined, options?: ExtensionWidgetOptions): void;\n\tsetWidget(\n\t\tkey: string,\n\t\tcontent: ((tui: TUI, theme: Theme) => Component & { dispose?(): void }) | undefined,\n\t\toptions?: ExtensionWidgetOptions,\n\t): void;\n\n\t/** Set a custom footer component, or undefined to restore the built-in footer.\n\t *\n\t * The factory receives a FooterDataProvider for data not otherwise accessible:\n\t * git branch and extension statuses from setStatus(). Token stats, model info,\n\t * etc. are available via ctx.sessionManager and ctx.model.\n\t */\n\tsetFooter(\n\t\tfactory:\n\t\t\t| ((tui: TUI, theme: Theme, footerData: ReadonlyFooterDataProvider) => Component & { dispose?(): void })\n\t\t\t| undefined,\n\t): void;\n\n\t/** Set a custom header component (shown at startup, above chat), or undefined to restore the built-in header. */\n\tsetHeader(factory: ((tui: TUI, theme: Theme) => Component & { dispose?(): void }) | undefined): void;\n\n\t/** Set the terminal window/tab title. */\n\tsetTitle(title: string): void;\n\n\t/** Show a custom component with keyboard focus. */\n\tcustom<T>(\n\t\tfactory: (\n\t\t\ttui: TUI,\n\t\t\ttheme: Theme,\n\t\t\tkeybindings: KeybindingsManager,\n\t\t\tdone: (result: T) => void,\n\t\t) => ExtensionCustomComponent | Promise<ExtensionCustomComponent>,\n\t\toptions?: {\n\t\t\toverlay?: boolean;\n\t\t\t/** Keep host inline custom UI pending in the background while this overlay is visible. */\n\t\t\tdeferInlineCustomUiFocus?: boolean;\n\t\t\t/**\n\t\t\t * Declare that this component binds Ctrl+C itself (cancel, skip, close).\n\t\t\t * The host then forwards the first Ctrl+C to it instead of closing it.\n\t\t\t *\n\t\t\t * Leave it unset unless the component really handles the key: the host\n\t\t\t * closes an undeclared component on the first Ctrl+C so a component that\n\t\t\t * never resolves can never trap the keyboard.\n\t\t\t */\n\t\t\thandlesCtrlC?: boolean;\n\t\t\t/** Declare that this component claims internal UI actions such as the jump-to-bottom URL. */\n\t\t\thandlesInternalUiAction?: boolean;\n\t\t\t/** AbortSignal to programmatically dismiss the custom UI. */\n\t\t\tsignal?: AbortSignal;\n\t\t\t/** Overlay positioning/sizing options. Can be static or a function for dynamic updates. */\n\t\t\toverlayOptions?: OverlayOptions | (() => OverlayOptions);\n\t\t\t/** Called with the overlay handle after the overlay is shown. Use to control visibility. */\n\t\t\tonHandle?: (handle: OverlayHandle) => void;\n\t\t},\n\t): Promise<T>;\n\n\t/**\n\t * Open a session-list picker that runs natively in the host terminal\n\t * process. Every interactive host implements it — non-isolated mode\n\t * mounts the selector directly (no IPC), isolated mode routes it over\n\t * the engine session-picker protocol channel — so callers use one\n\t * identical API. In both cases navigation and search never cross a\n\t * process boundary; only open/update/select/delete/cancel do. The\n\t * member is absent only on non-interactive surfaces (headless RPC,\n\t * print); callers should fail with an actionable error there rather\n\t * than degrade.\n\t */\n\thostSessionPicker?(request: HostSessionPickerRequest): HostSessionPickerHandle;\n\n\t/**\n\t * Open an inline form whose component, focus, and editing state live in the\n\t * terminal host. Resolves raw field values, or undefined on cancellation.\n\t */\n\thostInputForm?(request: HostInputFormRequest): Promise<Record<string, string> | undefined>;\n\n\t/** Paste text into the editor, triggering paste handling (collapse for large content). */\n\tpasteToEditor(text: string): void;\n\n\t/** Set the text in the core input editor. */\n\tsetEditorText(text: string): void;\n\n\t/** Get the current text from the core input editor. */\n\tgetEditorText(): string;\n\n\t/**\n\t * Show a multi-line editor for text editing.\n\t *\n\t * `opts.signal` lets a host cancel the mount it owns — the isolated engine\n\t * bridge uses it to close dialogs belonging to a dead engine generation.\n\t */\n\teditor(title: string, prefill?: string, opts?: ExtensionUIDialogOptions): Promise<string | undefined>;\n\n\t/** Stack additional autocomplete behavior on top of the built-in provider. */\n\taddAutocompleteProvider(factory: AutocompleteProviderFactory): void;\n\n\t/**\n\t * Set a custom editor component via factory function.\n\t * Pass undefined to restore the default editor.\n\t *\n\t * The factory receives:\n\t * - `theme`: EditorTheme for styling borders and autocomplete\n\t * - `keybindings`: KeybindingsManager for app-level keybindings\n\t *\n\t * For full app keybinding support (escape, ctrl+d, model switching, etc.),\n\t * extend `CustomEditor` from `@bastani/atomic` and return `super.handleInput(data)`\n\t * for keys you don't handle.\n\t *\n\t * @example\n\t * ```ts\n\t * import { CustomEditor } from \"@bastani/atomic\";\n\t *\n\t * class VimEditor extends CustomEditor {\n\t * private mode: \"normal\" | \"insert\" = \"insert\";\n\t *\n\t * handleInput(data: string): boolean {\n\t * if (this.mode === \"normal\") {\n\t * // Handle vim normal mode keys...\n\t * if (data === \"i\") { this.mode = \"insert\"; return true; }\n\t * }\n\t * return super.handleInput(data); // App keybindings + text editing\n\t * }\n\t * }\n\t *\n\t * ctx.ui.setEditorComponent((tui, theme, keybindings) =>\n\t * new VimEditor(tui, theme, keybindings)\n\t * );\n\t * ```\n\t */\n\tsetEditorComponent(factory: EditorFactory | undefined): void;\n\n\t/** Get the currently configured custom editor factory, or undefined when using the default editor. */\n\tgetEditorComponent(): EditorFactory | undefined;\n\n\t/** Get the built-in footer data provider so embedded extension UIs can reuse the core footer. */\n\tgetFooterDataProvider(): ReadonlyFooterDataProvider;\n\n\t/** Get the current theme for styling. */\n\treadonly theme: Theme;\n\n\t/** Get all available themes with their names and file paths. */\n\tgetAllThemes(): { name: string; path: string | undefined }[];\n\n\t/** Load a theme by name without switching to it. Returns undefined if not found. */\n\tgetTheme(name: string): Theme | undefined;\n\n\t/** Set the current theme by name or Theme object. */\n\tsetTheme(theme: string | Theme): { success: boolean; error?: string };\n\n\t/** Get current tool output expansion state. */\n\tgetToolsExpanded(): boolean;\n\n\t/** Set tool output expansion state. */\n\tsetToolsExpanded(expanded: boolean): void;\n\n\t/** Get current chat rendering preferences and extension renderers. */\n\tgetChatRenderSettings(): ChatRenderSettings;\n}\n"]}
1
+ {"version":3,"file":"ui-types.js","sourceRoot":"","sources":["../../../src/core/extensions/ui-types.ts"],"names":[],"mappings":"AAoDA;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,4BAA4B,CAAC","sourcesContent":["import type {\n\tAutocompleteProvider,\n\tComponent,\n\tEditorComponent,\n\tEditorTheme,\n\tOverlayHandle,\n\tOverlayOptions,\n\tTUI,\n} from \"@earendil-works/pi-tui\";\nimport type { Theme } from \"../../modes/interactive/theme/theme.ts\";\nimport type { ReadonlyFooterDataProvider } from \"../footer-data-provider.ts\";\nimport type { KeybindingsManager } from \"../keybindings.ts\";\nimport type { MarkdownTransformer, MessageRenderer } from \"./message-types.ts\";\nimport type { ToolDefinition } from \"./tool-types.ts\";\n\n/** Options for extension UI dialogs. */\nexport interface ExtensionUIDialogOptions {\n\t/** AbortSignal to programmatically dismiss the dialog. */\n\tsignal?: AbortSignal;\n\t/** Timeout in milliseconds. Dialog auto-dismisses with live countdown display. */\n\ttimeout?: number;\n}\n\n/** Placement for extension widgets. */\nexport type WidgetPlacement = \"aboveEditor\" | \"belowEditor\";\n\n/** Options for extension widgets. */\nexport interface ExtensionWidgetOptions {\n\t/** Where the widget is rendered. Defaults to \"aboveEditor\". */\n\tplacement?: WidgetPlacement;\n}\n\n/** Raw terminal input listener for extensions. */\nexport type TerminalInputHandler = (data: string) => { consume?: boolean; data?: string } | undefined;\n\n/** Working indicator configuration for the interactive Working lifecycle. */\nexport interface WorkingIndicatorOptions {\n\t/** Animation frames. Use an empty array to hide the indicator entirely. Custom frames are rendered verbatim. */\n\tframes?: string[];\n\t/** Frame interval in milliseconds for animated indicators. */\n\tintervalMs?: number;\n}\n\n/** Wrap the current autocomplete provider with additional behavior. */\nexport type AutocompleteProviderFactory = (current: AutocompleteProvider) => AutocompleteProvider;\nexport type EditorFactory = (tui: TUI, theme: EditorTheme, keybindings: KeybindingsManager) => EditorComponent;\n/** Component returned by `ctx.ui.custom()`. Input handlers must report whether they consumed the key. */\nexport type ExtensionCustomComponent = Omit<Component, \"handleInput\"> & {\n\thandleInput?: (data: string) => boolean | undefined | Promise<boolean | undefined>;\n\tdispose?(): void;\n};\n\n/**\n * Zero-width mark a custom component may embed in the line it most needs kept\n * on screen — the selected row of a list, say.\n *\n * A `reserveTranscriptRows` overlay is bounded against the terminal height, and\n * on a short terminal that bound has to drop rows. Without a mark the host can\n * only guess, and it guessed wrong: it kept a fixed number of rows from the top,\n * so on a 16-to-22-row terminal the selected option was cropped away and the\n * dialog looked frozen under the arrow keys. With the mark the host windows what\n * it keeps around that row instead.\n *\n * It is an APC sequence, so pi-tui's `visibleWidth` measures it as zero and\n * terminals ignore it — the same mechanism as pi-tui's own `CURSOR_MARKER`, but\n * private to Atomic and stripped by the host before the line is painted. Embed\n * it once per frame; the host uses the first line that carries it.\n */\nexport const OVERLAY_ACTIVE_ROW_MARKER = \"\\u001B_atomic:active\\u0007\";\n\nexport interface ChatRenderSettings {\n\thideThinkingBlock: boolean;\n\thiddenThinkingLabel: string;\n\ttoolOutputExpanded: boolean;\n\tshowImages: boolean;\n\timageWidthCells: number;\n\tmarkdownTransformers: readonly MarkdownTransformer[];\n\trenderLatex?: boolean;\n\tgetToolDefinition(toolName: string): ToolDefinition | undefined;\n\tgetCustomMessageRenderer(customType: string): MessageRenderer | undefined;\n}\n\n/** Host-owned inline custom UI focus state exposed to overlays without prompt content. */\nexport interface HostCustomUiState {\n\t/** Number of active non-overlay host custom UI mounts. */\n\tblockingInlineCustomUiDepth: number;\n\t/** True when at least one non-overlay host custom UI is mounted and blocking. */\n\tblockingInlineCustomUiActive: boolean;\n\t/** True when the active inline custom UI is waiting behind an overlay that kept focus. */\n\tblockingInlineCustomUiFocusDeferred?: boolean;\n}\n\nexport type HostCustomUiStateListener = (state: HostCustomUiState) => void;\n\n/** Supported field kinds for the host-native input form. */\nexport type HostInputFormFieldType = \"string\" | \"text\" | \"number\" | \"integer\" | \"boolean\" | \"select\";\n\n/** JSON-safe field descriptor for {@link ExtensionUIContext.hostInputForm}. */\nexport interface HostInputFormField {\n\tname: string;\n\ttype: HostInputFormFieldType;\n\tdescription?: string;\n\trequired?: boolean;\n\tchoices?: string[];\n\tplaceholder?: string;\n\t/** Raw, display-ready initial value. */\n\tinitialValue: string;\n}\n\n/** Request for a host-owned inline input form. */\nexport interface HostInputFormRequest {\n\ttitle: string;\n\tfields: HostInputFormField[];\n\t/** Panel heading label. Defaults to \"WORKFLOW INPUTS\". */\n\theading?: string;\n\t/** Submit button label. Defaults to \"[ Run workflow ]\". */\n\tsubmitLabel?: string;\n}\n\n/**\n * JSON-safe session-selector row for the host-native session picker.\n * Mirrors `SessionInfo` with `created`/`modified` flattened to epoch millis so\n * rows can cross the interactive-engine protocol without `Date` objects.\n */\nexport interface HostSessionPickerRow {\n\tpath: string;\n\tid: string;\n\tcwd: string;\n\t/** Creation time in epoch milliseconds. */\n\tcreatedAt: number;\n\t/** Last-modified time in epoch milliseconds. */\n\tmodifiedAt: number;\n\tmessageCount: number;\n\tfirstMessage: string;\n\t/** Generated resume summary. Absent when never generated, or stale against the latest message. */\n\tsummary?: string;\n\tallMessagesText?: string;\n\tname?: string;\n\t/** Optional semantic color for synthetic selector rows. */\n\tmessageColor?: \"success\" | \"warning\" | \"accent\" | \"error\";\n}\n\n/** Request for {@link ExtensionUIContext.hostSessionPicker}. */\nexport interface HostSessionPickerRequest {\n\t/** Rows shown in the first frame. Push later rows via the handle's `update()`. */\n\tsessions: HostSessionPickerRow[];\n\t/** Show the rename keybinding hint in the picker header. Defaults to false. */\n\tshowRenameHint?: boolean;\n\t/**\n\t * Invoked after the user confirms a Ctrl+D delete on a row. The host does\n\t * NOT remove the row; reply with `update()` (row removed) or `error()`.\n\t */\n\tonDelete?: (path: string) => void | Promise<void>;\n}\n\n/** Live control surface for an open host-native session picker. */\nexport interface HostSessionPickerHandle {\n\t/** Resolves with the selected row's `path`, or `undefined` on cancel/close. */\n\tresult: Promise<string | undefined>;\n\t/** Replace the picker rows (navigation/search state is preserved host-side). */\n\tupdate(sessions: HostSessionPickerRow[]): void;\n\t/** Surface a transient error message in the picker header. */\n\terror(message: string): void;\n\t/** Close the picker; `result` resolves `undefined`. Idempotent. */\n\tclose(): void;\n}\n\n/**\n * UI context for extensions to request interactive UI.\n * Each mode (interactive, RPC, print) provides its own implementation.\n */\nexport interface ExtensionUIContext {\n\t/** Show a selector and return the user's choice. */\n\tselect(title: string, options: string[], opts?: ExtensionUIDialogOptions): Promise<string | undefined>;\n\n\t/** Show a confirmation dialog. */\n\tconfirm(title: string, message: string, opts?: ExtensionUIDialogOptions): Promise<boolean>;\n\n\t/** Show a text input dialog. */\n\tinput(title: string, placeholder?: string, opts?: ExtensionUIDialogOptions): Promise<string | undefined>;\n\n\t/** Show a notification to the user. */\n\tnotify(message: string, type?: \"info\" | \"warning\" | \"error\"): void;\n\n\t/** Request an interactive repaint after extension-owned state changes. */\n\trequestRender(): void;\n\n\t/** Get host-owned inline custom UI focus state, if the mode exposes it. */\n\tgetHostCustomUiState?(): HostCustomUiState;\n\n\t/** Observe host-owned inline custom UI focus state changes. Returns an unsubscribe function. */\n\tonHostCustomUiStateChange?(listener: HostCustomUiStateListener): () => void;\n\n\t/** Move focus to a mounted host-owned inline custom UI, if one is pending. */\n\tfocusHostInlineCustomUi?(): boolean;\n\n\t/** Listen to raw terminal input (interactive mode only). Returns an unsubscribe function. */\n\tonTerminalInput(handler: TerminalInputHandler): () => void;\n\n\t/** Set status text in the footer/status bar. Pass undefined to clear. */\n\tsetStatus(key: string, text: string | undefined): void;\n\n\t/**\n\t * Set the working/loading message presented during the active Working lifecycle,\n\t * from accepted prompt startup through the agent turn. This customizes\n\t * presentation only; it does not start work or emit pre-start events. Call with\n\t * no argument to restore the default.\n\t */\n\tsetWorkingMessage(message?: string): void;\n\n\t/**\n\t * Show or hide the built-in row during the active Working lifecycle.\n\t * This customizes presentation only; it does not start or stop work.\n\t */\n\tsetWorkingVisible(visible: boolean): void;\n\n\t/**\n\t * Configure the interactive indicator presented during the active Working\n\t * lifecycle, from accepted prompt startup through the agent turn. This\n\t * customizes presentation only; it does not start work or emit pre-start events.\n\t *\n\t * - Omit the argument to restore the default animated spinner.\n\t * - Use `frames: [\"●\"]` for a static indicator.\n\t * - Use `frames: []` to hide the indicator entirely.\n\t * - Custom frames are rendered as provided, so extensions must add their own colors.\n\t */\n\tsetWorkingIndicator(options?: WorkingIndicatorOptions): void;\n\n\t/** Set the label shown for hidden thinking blocks. Call with no argument to restore default. */\n\tsetHiddenThinkingLabel(label?: string): void;\n\n\t/** Set a widget to display above or below the editor. Accepts string array or component factory. */\n\tsetWidget(key: string, content: string[] | undefined, options?: ExtensionWidgetOptions): void;\n\tsetWidget(\n\t\tkey: string,\n\t\tcontent: ((tui: TUI, theme: Theme) => Component & { dispose?(): void }) | undefined,\n\t\toptions?: ExtensionWidgetOptions,\n\t): void;\n\n\t/** Set a custom footer component, or undefined to restore the built-in footer.\n\t *\n\t * The factory receives a FooterDataProvider for data not otherwise accessible:\n\t * git branch and extension statuses from setStatus(). Token stats, model info,\n\t * etc. are available via ctx.sessionManager and ctx.model.\n\t */\n\tsetFooter(\n\t\tfactory:\n\t\t\t| ((tui: TUI, theme: Theme, footerData: ReadonlyFooterDataProvider) => Component & { dispose?(): void })\n\t\t\t| undefined,\n\t): void;\n\n\t/** Set a custom header component (shown at startup, above chat), or undefined to restore the built-in header. */\n\tsetHeader(factory: ((tui: TUI, theme: Theme) => Component & { dispose?(): void }) | undefined): void;\n\n\t/** Set the terminal window/tab title. */\n\tsetTitle(title: string): void;\n\n\t/** Show a custom component with keyboard focus. */\n\tcustom<T>(\n\t\tfactory: (\n\t\t\ttui: TUI,\n\t\t\ttheme: Theme,\n\t\t\tkeybindings: KeybindingsManager,\n\t\t\tdone: (result: T) => void,\n\t\t) => ExtensionCustomComponent | Promise<ExtensionCustomComponent>,\n\t\toptions?: {\n\t\t\toverlay?: boolean;\n\t\t\t/** Keep host inline custom UI pending in the background while this overlay is visible. */\n\t\t\tdeferInlineCustomUiFocus?: boolean;\n\t\t\t/**\n\t\t\t * Declare that this component binds Ctrl+C itself (cancel, skip, close).\n\t\t\t * The host then forwards the first Ctrl+C to it instead of closing it.\n\t\t\t *\n\t\t\t * Leave it unset unless the component really handles the key: the host\n\t\t\t * closes an undeclared component on the first Ctrl+C so a component that\n\t\t\t * never resolves can never trap the keyboard.\n\t\t\t */\n\t\t\thandlesCtrlC?: boolean;\n\t\t\t/** Declare that this component claims internal UI actions such as the jump-to-bottom URL. */\n\t\t\thandlesInternalUiAction?: boolean;\n\t\t\t/**\n\t\t\t * Overlay-only. Bound this overlay's height so a transcript strip stays\n\t\t\t * visible, and extend the transcript's scroll extent by the rows it\n\t\t\t * still covers, so every line of the scrollback can be brought above it.\n\t\t\t *\n\t\t\t * Set it for a blocking bottom-anchored dialog. Leave it unset for an\n\t\t\t * overlay that is meant to take the screen, such as a full-screen graph.\n\t\t\t */\n\t\t\treserveTranscriptRows?: boolean;\n\t\t\t/** AbortSignal to programmatically dismiss the custom UI. */\n\t\t\tsignal?: AbortSignal;\n\t\t\t/** Overlay positioning/sizing options. Can be static or a function for dynamic updates. */\n\t\t\toverlayOptions?: OverlayOptions | (() => OverlayOptions);\n\t\t\t/** Called with the overlay handle after the overlay is shown. Use to control visibility. */\n\t\t\tonHandle?: (handle: OverlayHandle) => void;\n\t\t},\n\t): Promise<T>;\n\n\t/**\n\t * Open a session-list picker that runs natively in the host terminal\n\t * process. Every interactive host implements it — non-isolated mode\n\t * mounts the selector directly (no IPC), isolated mode routes it over\n\t * the engine session-picker protocol channel — so callers use one\n\t * identical API. In both cases navigation and search never cross a\n\t * process boundary; only open/update/select/delete/cancel do. The\n\t * member is absent only on non-interactive surfaces (headless RPC,\n\t * print); callers should fail with an actionable error there rather\n\t * than degrade.\n\t */\n\thostSessionPicker?(request: HostSessionPickerRequest): HostSessionPickerHandle;\n\n\t/**\n\t * Open an inline form whose component, focus, and editing state live in the\n\t * terminal host. Resolves raw field values, or undefined on cancellation.\n\t */\n\thostInputForm?(request: HostInputFormRequest): Promise<Record<string, string> | undefined>;\n\n\t/** Paste text into the editor, triggering paste handling (collapse for large content). */\n\tpasteToEditor(text: string): void;\n\n\t/** Set the text in the core input editor. */\n\tsetEditorText(text: string): void;\n\n\t/** Get the current text from the core input editor. */\n\tgetEditorText(): string;\n\n\t/**\n\t * Show a multi-line editor for text editing.\n\t *\n\t * `opts.signal` lets a host cancel the mount it owns — the isolated engine\n\t * bridge uses it to close dialogs belonging to a dead engine generation.\n\t */\n\teditor(title: string, prefill?: string, opts?: ExtensionUIDialogOptions): Promise<string | undefined>;\n\n\t/** Stack additional autocomplete behavior on top of the built-in provider. */\n\taddAutocompleteProvider(factory: AutocompleteProviderFactory): void;\n\n\t/**\n\t * Set a custom editor component via factory function.\n\t * Pass undefined to restore the default editor.\n\t *\n\t * The factory receives:\n\t * - `theme`: EditorTheme for styling borders and autocomplete\n\t * - `keybindings`: KeybindingsManager for app-level keybindings\n\t *\n\t * For full app keybinding support (escape, ctrl+d, model switching, etc.),\n\t * extend `CustomEditor` from `@bastani/atomic` and return `super.handleInput(data)`\n\t * for keys you don't handle.\n\t *\n\t * @example\n\t * ```ts\n\t * import { CustomEditor } from \"@bastani/atomic\";\n\t *\n\t * class VimEditor extends CustomEditor {\n\t * private mode: \"normal\" | \"insert\" = \"insert\";\n\t *\n\t * handleInput(data: string): boolean {\n\t * if (this.mode === \"normal\") {\n\t * // Handle vim normal mode keys...\n\t * if (data === \"i\") { this.mode = \"insert\"; return true; }\n\t * }\n\t * return super.handleInput(data); // App keybindings + text editing\n\t * }\n\t * }\n\t *\n\t * ctx.ui.setEditorComponent((tui, theme, keybindings) =>\n\t * new VimEditor(tui, theme, keybindings)\n\t * );\n\t * ```\n\t */\n\tsetEditorComponent(factory: EditorFactory | undefined): void;\n\n\t/** Get the currently configured custom editor factory, or undefined when using the default editor. */\n\tgetEditorComponent(): EditorFactory | undefined;\n\n\t/** Get the built-in footer data provider so embedded extension UIs can reuse the core footer. */\n\tgetFooterDataProvider(): ReadonlyFooterDataProvider;\n\n\t/** Get the current theme for styling. */\n\treadonly theme: Theme;\n\n\t/** Get all available themes with their names and file paths. */\n\tgetAllThemes(): { name: string; path: string | undefined }[];\n\n\t/** Load a theme by name without switching to it. Returns undefined if not found. */\n\tgetTheme(name: string): Theme | undefined;\n\n\t/** Set the current theme by name or Theme object. */\n\tsetTheme(theme: string | Theme): { success: boolean; error?: string };\n\n\t/** Get current tool output expansion state. */\n\tgetToolsExpanded(): boolean;\n\n\t/** Set tool output expansion state. */\n\tsetToolsExpanded(expanded: boolean): void;\n\n\t/** Get current chat rendering preferences and extension renderers. */\n\tgetChatRenderSettings(): ChatRenderSettings;\n}\n"]}
@@ -1,7 +1,28 @@
1
+ import type { OverlayOptions } from "@earendil-works/pi-tui";
1
2
  import type { ToolDefinition } from "../../extensions/types.ts";
2
3
  import { buildQuestionnaireResponse, buildToolResult } from "./tool/response-envelope.ts";
3
4
  import { type QuestionData, QuestionParamsSchema } from "./tool/types.ts";
4
5
  import type { WrappingSelectItem } from "./view/components/wrapping-select.ts";
6
+ /**
7
+ * Mount options for the blocking questionnaire (#2378).
8
+ *
9
+ * The dialog used to mount inline, inside the fullscreen dock, where it is a
10
+ * flex sibling of the transcript `ScrollView`. A tall side-by-side dialog then
11
+ * took the transcript's rows: on a 40-row terminal the transcript viewport
12
+ * collapsed from 34 rows to 6, and pi-tui derives its page step from that
13
+ * viewport (`viewportHeight - PAGE_SCROLL_OVERLAP`), so PageUp crawled two
14
+ * lines at a time through a six-line window.
15
+ *
16
+ * A bottom-anchored overlay is composited over the bottom rows instead of being
17
+ * measured into the layout, so the transcript keeps its full viewport height
18
+ * and its full page step. `reserveTranscriptRows` is what makes those rows
19
+ * observable rather than merely addressable: the host bounds this overlay so a
20
+ * transcript strip always survives, and extends the transcript's scroll extent
21
+ * by the rows the overlay still covers, so the newest output can be raised into
22
+ * that strip. No `maxHeight` — the host's bound is tighter, and letting pi-tui
23
+ * slice as well would make the measured overlay height wrong.
24
+ */
25
+ export declare const QUESTIONNAIRE_OVERLAY_OPTIONS: OverlayOptions;
5
26
  export declare function buildItemsForQuestion(question: QuestionData): WrappingSelectItem[];
6
27
  export declare const DEFAULT_PROMPT_SNIPPET = "Ask the user up to 4 structured questions (2-4 options each) when requirements are ambiguous";
7
28
  export declare const DEFAULT_PROMPT_GUIDELINES: string[];
@@ -1 +1 @@
1
- {"version":3,"file":"ask-user-question.d.ts","sourceRoot":"","sources":["../../../../src/core/tools/ask-user-question/ask-user-question.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAIhE,OAAO,EAAE,0BAA0B,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAC1F,OAAO,EAIN,KAAK,YAAY,EAGjB,oBAAoB,EACpB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,sCAAsC,CAAC;AAI/E,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,YAAY,GAAG,kBAAkB,EAAE,CAWlF;AAED,eAAO,MAAM,sBAAsB,iGAA0I,CAAC;AAC9K,eAAO,MAAM,yBAAyB,EAAE,MAAM,EAK7C,CAAC;AAEF,wBAAgB,mCAAmC,IAAI,cAAc,CAAC,OAAO,oBAAoB,EAAE,OAAO,CAAC,CA+E1G;AAED,OAAO,EAAE,0BAA0B,EAAE,eAAe,EAAE,CAAC"}
1
+ {"version":3,"file":"ask-user-question.d.ts","sourceRoot":"","sources":["../../../../src/core/tools/ask-user-question/ask-user-question.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAIhE,OAAO,EAAE,0BAA0B,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAC1F,OAAO,EAIN,KAAK,YAAY,EAGjB,oBAAoB,EACpB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,sCAAsC,CAAC;AAI/E;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,6BAA6B,EAAE,cAG3C,CAAC;AAEF,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,YAAY,GAAG,kBAAkB,EAAE,CAWlF;AAED,eAAO,MAAM,sBAAsB,iGAA0I,CAAC;AAC9K,eAAO,MAAM,yBAAyB,EAAE,MAAM,EAK7C,CAAC;AAEF,wBAAgB,mCAAmC,IAAI,cAAc,CAAC,OAAO,oBAAoB,EAAE,OAAO,CAAC,CAiF1G;AAED,OAAO,EAAE,0BAA0B,EAAE,eAAe,EAAE,CAAC"}
@@ -5,6 +5,29 @@ import { buildQuestionnaireResponse, buildToolResult } from "./tool/response-env
5
5
  import { MAX_OPTIONS, MAX_QUESTIONS, MIN_OPTIONS, QuestionParamsSchema, } from "./tool/types.js";
6
6
  import { validateQuestionnaire } from "./tool/validate-questionnaire.js";
7
7
  const ERROR_NO_UI = "Error: UI not available (running in non-interactive mode)";
8
+ /**
9
+ * Mount options for the blocking questionnaire (#2378).
10
+ *
11
+ * The dialog used to mount inline, inside the fullscreen dock, where it is a
12
+ * flex sibling of the transcript `ScrollView`. A tall side-by-side dialog then
13
+ * took the transcript's rows: on a 40-row terminal the transcript viewport
14
+ * collapsed from 34 rows to 6, and pi-tui derives its page step from that
15
+ * viewport (`viewportHeight - PAGE_SCROLL_OVERLAP`), so PageUp crawled two
16
+ * lines at a time through a six-line window.
17
+ *
18
+ * A bottom-anchored overlay is composited over the bottom rows instead of being
19
+ * measured into the layout, so the transcript keeps its full viewport height
20
+ * and its full page step. `reserveTranscriptRows` is what makes those rows
21
+ * observable rather than merely addressable: the host bounds this overlay so a
22
+ * transcript strip always survives, and extends the transcript's scroll extent
23
+ * by the rows the overlay still covers, so the newest output can be raised into
24
+ * that strip. No `maxHeight` — the host's bound is tighter, and letting pi-tui
25
+ * slice as well would make the measured overlay height wrong.
26
+ */
27
+ export const QUESTIONNAIRE_OVERLAY_OPTIONS = {
28
+ anchor: "bottom-center",
29
+ width: "100%",
30
+ };
8
31
  export function buildItemsForQuestion(question) {
9
32
  const items = question.options.map((o) => ({
10
33
  kind: "option",
@@ -66,14 +89,11 @@ Preview content is rendered as markdown in a monospace box. Multi-line text with
66
89
  const itemsByTab = typed.questions.map((q) => buildItemsForQuestion(q));
67
90
  // Suspend the animated working loader for the lifetime of the blocking dialog.
68
91
  //
69
- // The questionnaire mounts inline, directly below the status/working-loader row.
70
- // That loader ticks every ~88ms and calls `requestRender()` on each frame. On a
71
- // short terminal the (tall) side-by-side dialog pushes the loader line above the
72
- // viewport top, so pi-tui's differential renderer sees `firstChanged < viewportTop`
73
- // and falls back to a full clear+replay (`\x1b[2J\x1b[H\x1b[3J`) on every tick. The
74
- // transcript is replayed before the dialog each time, which is the flicker. The
75
- // loader conveys nothing while we're blocked on human input, so hide it for the
76
- // duration and restore it once the dialog closes (on every path).
92
+ // The loader ticks every ~88ms and calls `requestRender()` on each frame, and it
93
+ // conveys nothing while we are blocked on human input. Hiding it for the duration
94
+ // keeps the frame behind the dialog static and avoids the differential renderer
95
+ // falling back to a full clear+replay (`\x1b[2J\x1b[H\x1b[3J`) on every tick.
96
+ // Restored once the dialog closes (on every path).
77
97
  //
78
98
  // Guarded: some hosts (e.g. the workflow stage-UI broker) pass a minimal UI
79
99
  // context that only implements `custom`, so treat a missing loader control as a
@@ -89,7 +109,12 @@ Preview content is rendered as markdown in a monospace box. Multi-line text with
89
109
  done,
90
110
  });
91
111
  return session.component;
92
- }, { signal });
112
+ }, {
113
+ signal,
114
+ overlay: true,
115
+ reserveTranscriptRows: true,
116
+ overlayOptions: QUESTIONNAIRE_OVERLAY_OPTIONS,
117
+ });
93
118
  return buildQuestionnaireResponse(result, typed);
94
119
  }
95
120
  finally {
@@ -1 +1 @@
1
- {"version":3,"file":"ask-user-question.js","sourceRoot":"","sources":["../../../../src/core/tools/ask-user-question/ask-user-question.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ToolDefinition } from \"../../extensions/types.ts\";\nimport { loadConfig, validateGuidanceFields } from \"./config.ts\";\nimport { QuestionnaireSession } from \"./state/questionnaire-session.ts\";\nimport { ROW_INTENT_META, sentinelsToAppend } from \"./state/row-intent.ts\";\nimport { buildQuestionnaireResponse, buildToolResult } from \"./tool/response-envelope.ts\";\nimport {\n\tMAX_OPTIONS,\n\tMAX_QUESTIONS,\n\tMIN_OPTIONS,\n\ttype QuestionData,\n\ttype QuestionnaireResult,\n\ttype QuestionParams,\n\tQuestionParamsSchema,\n} from \"./tool/types.ts\";\nimport { validateQuestionnaire } from \"./tool/validate-questionnaire.ts\";\nimport type { WrappingSelectItem } from \"./view/components/wrapping-select.ts\";\n\nconst ERROR_NO_UI = \"Error: UI not available (running in non-interactive mode)\";\n\nexport function buildItemsForQuestion(question: QuestionData): WrappingSelectItem[] {\n\tconst items: WrappingSelectItem[] = question.options.map((o) => ({\n\t\tkind: \"option\",\n\t\tlabel: o.label,\n\t\tdescription: o.description,\n\t}));\n\tconst hasAnyPreview = question.options.some((o) => typeof o.preview === \"string\" && o.preview.length > 0);\n\tfor (const kind of sentinelsToAppend(question, hasAnyPreview)) {\n\t\titems.push({ kind, label: ROW_INTENT_META[kind].label });\n\t}\n\treturn items;\n}\n\nexport const DEFAULT_PROMPT_SNIPPET = `Ask the user up to ${MAX_QUESTIONS} structured questions (${MIN_OPTIONS}-${MAX_OPTIONS} options each) when requirements are ambiguous`;\nexport const DEFAULT_PROMPT_GUIDELINES: string[] = [\n\t`Use ask_user_question whenever the user's request is underspecified and you cannot proceed without concrete decisions — you can ask up to ${MAX_QUESTIONS} questions per invocation.`,\n\t`Each question MUST have ${MIN_OPTIONS}-${MAX_OPTIONS} options. Every option requires a concise label (1-5 words) and a description explaining what the choice means or its trade-offs. The user can additionally type a custom answer (\"Type something.\" row is appended automatically to single-select questions) or pick \"Chat about this\" to abandon the questionnaire.`,\n\t`Set multiSelect: true when multiple answers are valid; this suppresses the \"Type something.\" row. Provide an options[].preview markdown string when an option benefits from richer side-by-side context (mockups, code snippets, diagrams, configs) — single-select only. NOTE: any non-empty preview on a single-select question ALSO suppresses the \"Type something.\" row (no room in the side-by-side layout); \"Chat about this\" remains the escape hatch. If you recommend a specific option, make it the first option and append \"(Recommended)\" to its label.`,\n\t\"Do not stack multiple ask_user_question calls back-to-back — group all clarifying questions into one invocation.\",\n];\n\nexport function createAskUserQuestionToolDefinition(): ToolDefinition<typeof QuestionParamsSchema, unknown> {\n\tconst guidance = validateGuidanceFields(loadConfig().guidance);\n\treturn {\n\t\tname: \"ask_user_question\",\n\t\tlabel: \"Ask User Question\",\n\t\tdescription: `Ask the user one or more structured questions during execution. Use when you need to:\n1. Gather user preferences or requirements\n2. Clarify ambiguous instructions\n3. Get decisions on implementation choices as you work\n4. Offer choices to the user about what direction to take\n\nUsage notes:\n- Users will always be able to type a custom answer (\"Type something.\" row is appended automatically to every single-select question) or pick \"Chat about this\" to abandon the questionnaire and continue in free-form conversation. Do NOT author \"Other\" / \"Type something.\" / \"Chat about this\" labels yourself — duplicates are rejected at runtime.\n- Use multiSelect: true to allow multiple answers to be selected for a question. The \"Type something.\" row is suppressed on multi-select questions, and is ALSO suppressed on single-select questions where any option carries a \\`preview\\` (the side-by-side layout has no room for inline custom text — \"Chat about this\" remains as the free-form escape hatch).\n- If you recommend a specific option, make that the first option in the list and add \"(Recommended)\" at the end of the label.\n\nPreview feature:\nUse the optional \\`preview\\` field on options when presenting concrete artifacts that users need to visually compare:\n- ASCII mockups of UI layouts or components\n- Code snippets showing different implementations\n- Diagram variations\n- Configuration examples\n\nPreview content is rendered as markdown in a monospace box. Multi-line text with newlines is supported. When any option has a preview, the UI switches to a side-by-side layout with a vertical option list on the left and preview on the right. Do not use previews for simple preference questions where labels and descriptions suffice. Note: previews are only supported for single-select questions (not multiSelect).`,\n\t\tpromptSnippet: guidance.promptSnippet ?? DEFAULT_PROMPT_SNIPPET,\n\t\tpromptGuidelines: guidance.promptGuidelines ?? DEFAULT_PROMPT_GUIDELINES,\n\t\tparameters: QuestionParamsSchema,\n\n\t\tasync execute(_toolCallId, params, signal, _onUpdate, ctx) {\n\t\t\tconst typed = params as unknown as QuestionParams;\n\t\t\tif (!ctx.hasUI) return buildToolResult(ERROR_NO_UI, { answers: [], cancelled: true, error: \"no_ui\" });\n\n\t\t\tconst validation = validateQuestionnaire(typed);\n\t\t\tif (!validation.ok) {\n\t\t\t\treturn buildToolResult(validation.message, {\n\t\t\t\t\tanswers: [],\n\t\t\t\t\tcancelled: true,\n\t\t\t\t\terror: validation.error,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tconst itemsByTab: WrappingSelectItem[][] = typed.questions.map((q) => buildItemsForQuestion(q));\n\n\t\t\t// Suspend the animated working loader for the lifetime of the blocking dialog.\n\t\t\t//\n\t\t\t// The questionnaire mounts inline, directly below the status/working-loader row.\n\t\t\t// That loader ticks every ~88ms and calls `requestRender()` on each frame. On a\n\t\t\t// short terminal the (tall) side-by-side dialog pushes the loader line above the\n\t\t\t// viewport top, so pi-tui's differential renderer sees `firstChanged < viewportTop`\n\t\t\t// and falls back to a full clear+replay (`\\x1b[2J\\x1b[H\\x1b[3J`) on every tick. The\n\t\t\t// transcript is replayed before the dialog each time, which is the flicker. The\n\t\t\t// loader conveys nothing while we're blocked on human input, so hide it for the\n\t\t\t// duration and restore it once the dialog closes (on every path).\n\t\t\t//\n\t\t\t// Guarded: some hosts (e.g. the workflow stage-UI broker) pass a minimal UI\n\t\t\t// context that only implements `custom`, so treat a missing loader control as a\n\t\t\t// no-op rather than throwing.\n\t\t\tctx.ui.setWorkingVisible?.(false);\n\t\t\ttry {\n\t\t\t\tconst result = await ctx.ui.custom<QuestionnaireResult>(\n\t\t\t\t\t(tui, theme, _kb, done) => {\n\t\t\t\t\t\tconst session = new QuestionnaireSession({\n\t\t\t\t\t\t\ttui,\n\t\t\t\t\t\t\ttheme,\n\t\t\t\t\t\t\tparams: typed,\n\t\t\t\t\t\t\titemsByTab,\n\t\t\t\t\t\t\tdone,\n\t\t\t\t\t\t});\n\t\t\t\t\t\treturn session.component;\n\t\t\t\t\t},\n\t\t\t\t\t{ signal },\n\t\t\t\t);\n\n\t\t\t\treturn buildQuestionnaireResponse(result, typed);\n\t\t\t} finally {\n\t\t\t\tctx.ui.setWorkingVisible?.(true);\n\t\t\t}\n\t\t},\n\t};\n}\n\nexport { buildQuestionnaireResponse, buildToolResult };\n"]}
1
+ {"version":3,"file":"ask-user-question.js","sourceRoot":"","sources":["../../../../src/core/tools/ask-user-question/ask-user-question.ts"],"names":[],"mappings":"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","sourcesContent":["import type { OverlayOptions } from \"@earendil-works/pi-tui\";\nimport type { ToolDefinition } from \"../../extensions/types.ts\";\nimport { loadConfig, validateGuidanceFields } from \"./config.ts\";\nimport { QuestionnaireSession } from \"./state/questionnaire-session.ts\";\nimport { ROW_INTENT_META, sentinelsToAppend } from \"./state/row-intent.ts\";\nimport { buildQuestionnaireResponse, buildToolResult } from \"./tool/response-envelope.ts\";\nimport {\n\tMAX_OPTIONS,\n\tMAX_QUESTIONS,\n\tMIN_OPTIONS,\n\ttype QuestionData,\n\ttype QuestionnaireResult,\n\ttype QuestionParams,\n\tQuestionParamsSchema,\n} from \"./tool/types.ts\";\nimport { validateQuestionnaire } from \"./tool/validate-questionnaire.ts\";\nimport type { WrappingSelectItem } from \"./view/components/wrapping-select.ts\";\n\nconst ERROR_NO_UI = \"Error: UI not available (running in non-interactive mode)\";\n\n/**\n * Mount options for the blocking questionnaire (#2378).\n *\n * The dialog used to mount inline, inside the fullscreen dock, where it is a\n * flex sibling of the transcript `ScrollView`. A tall side-by-side dialog then\n * took the transcript's rows: on a 40-row terminal the transcript viewport\n * collapsed from 34 rows to 6, and pi-tui derives its page step from that\n * viewport (`viewportHeight - PAGE_SCROLL_OVERLAP`), so PageUp crawled two\n * lines at a time through a six-line window.\n *\n * A bottom-anchored overlay is composited over the bottom rows instead of being\n * measured into the layout, so the transcript keeps its full viewport height\n * and its full page step. `reserveTranscriptRows` is what makes those rows\n * observable rather than merely addressable: the host bounds this overlay so a\n * transcript strip always survives, and extends the transcript's scroll extent\n * by the rows the overlay still covers, so the newest output can be raised into\n * that strip. No `maxHeight` — the host's bound is tighter, and letting pi-tui\n * slice as well would make the measured overlay height wrong.\n */\nexport const QUESTIONNAIRE_OVERLAY_OPTIONS: OverlayOptions = {\n\tanchor: \"bottom-center\",\n\twidth: \"100%\",\n};\n\nexport function buildItemsForQuestion(question: QuestionData): WrappingSelectItem[] {\n\tconst items: WrappingSelectItem[] = question.options.map((o) => ({\n\t\tkind: \"option\",\n\t\tlabel: o.label,\n\t\tdescription: o.description,\n\t}));\n\tconst hasAnyPreview = question.options.some((o) => typeof o.preview === \"string\" && o.preview.length > 0);\n\tfor (const kind of sentinelsToAppend(question, hasAnyPreview)) {\n\t\titems.push({ kind, label: ROW_INTENT_META[kind].label });\n\t}\n\treturn items;\n}\n\nexport const DEFAULT_PROMPT_SNIPPET = `Ask the user up to ${MAX_QUESTIONS} structured questions (${MIN_OPTIONS}-${MAX_OPTIONS} options each) when requirements are ambiguous`;\nexport const DEFAULT_PROMPT_GUIDELINES: string[] = [\n\t`Use ask_user_question whenever the user's request is underspecified and you cannot proceed without concrete decisions — you can ask up to ${MAX_QUESTIONS} questions per invocation.`,\n\t`Each question MUST have ${MIN_OPTIONS}-${MAX_OPTIONS} options. Every option requires a concise label (1-5 words) and a description explaining what the choice means or its trade-offs. The user can additionally type a custom answer (\"Type something.\" row is appended automatically to single-select questions) or pick \"Chat about this\" to abandon the questionnaire.`,\n\t`Set multiSelect: true when multiple answers are valid; this suppresses the \"Type something.\" row. Provide an options[].preview markdown string when an option benefits from richer side-by-side context (mockups, code snippets, diagrams, configs) — single-select only. NOTE: any non-empty preview on a single-select question ALSO suppresses the \"Type something.\" row (no room in the side-by-side layout); \"Chat about this\" remains the escape hatch. If you recommend a specific option, make it the first option and append \"(Recommended)\" to its label.`,\n\t\"Do not stack multiple ask_user_question calls back-to-back — group all clarifying questions into one invocation.\",\n];\n\nexport function createAskUserQuestionToolDefinition(): ToolDefinition<typeof QuestionParamsSchema, unknown> {\n\tconst guidance = validateGuidanceFields(loadConfig().guidance);\n\treturn {\n\t\tname: \"ask_user_question\",\n\t\tlabel: \"Ask User Question\",\n\t\tdescription: `Ask the user one or more structured questions during execution. Use when you need to:\n1. Gather user preferences or requirements\n2. Clarify ambiguous instructions\n3. Get decisions on implementation choices as you work\n4. Offer choices to the user about what direction to take\n\nUsage notes:\n- Users will always be able to type a custom answer (\"Type something.\" row is appended automatically to every single-select question) or pick \"Chat about this\" to abandon the questionnaire and continue in free-form conversation. Do NOT author \"Other\" / \"Type something.\" / \"Chat about this\" labels yourself — duplicates are rejected at runtime.\n- Use multiSelect: true to allow multiple answers to be selected for a question. The \"Type something.\" row is suppressed on multi-select questions, and is ALSO suppressed on single-select questions where any option carries a \\`preview\\` (the side-by-side layout has no room for inline custom text — \"Chat about this\" remains as the free-form escape hatch).\n- If you recommend a specific option, make that the first option in the list and add \"(Recommended)\" at the end of the label.\n\nPreview feature:\nUse the optional \\`preview\\` field on options when presenting concrete artifacts that users need to visually compare:\n- ASCII mockups of UI layouts or components\n- Code snippets showing different implementations\n- Diagram variations\n- Configuration examples\n\nPreview content is rendered as markdown in a monospace box. Multi-line text with newlines is supported. When any option has a preview, the UI switches to a side-by-side layout with a vertical option list on the left and preview on the right. Do not use previews for simple preference questions where labels and descriptions suffice. Note: previews are only supported for single-select questions (not multiSelect).`,\n\t\tpromptSnippet: guidance.promptSnippet ?? DEFAULT_PROMPT_SNIPPET,\n\t\tpromptGuidelines: guidance.promptGuidelines ?? DEFAULT_PROMPT_GUIDELINES,\n\t\tparameters: QuestionParamsSchema,\n\n\t\tasync execute(_toolCallId, params, signal, _onUpdate, ctx) {\n\t\t\tconst typed = params as unknown as QuestionParams;\n\t\t\tif (!ctx.hasUI) return buildToolResult(ERROR_NO_UI, { answers: [], cancelled: true, error: \"no_ui\" });\n\n\t\t\tconst validation = validateQuestionnaire(typed);\n\t\t\tif (!validation.ok) {\n\t\t\t\treturn buildToolResult(validation.message, {\n\t\t\t\t\tanswers: [],\n\t\t\t\t\tcancelled: true,\n\t\t\t\t\terror: validation.error,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tconst itemsByTab: WrappingSelectItem[][] = typed.questions.map((q) => buildItemsForQuestion(q));\n\n\t\t\t// Suspend the animated working loader for the lifetime of the blocking dialog.\n\t\t\t//\n\t\t\t// The loader ticks every ~88ms and calls `requestRender()` on each frame, and it\n\t\t\t// conveys nothing while we are blocked on human input. Hiding it for the duration\n\t\t\t// keeps the frame behind the dialog static and avoids the differential renderer\n\t\t\t// falling back to a full clear+replay (`\\x1b[2J\\x1b[H\\x1b[3J`) on every tick.\n\t\t\t// Restored once the dialog closes (on every path).\n\t\t\t//\n\t\t\t// Guarded: some hosts (e.g. the workflow stage-UI broker) pass a minimal UI\n\t\t\t// context that only implements `custom`, so treat a missing loader control as a\n\t\t\t// no-op rather than throwing.\n\t\t\tctx.ui.setWorkingVisible?.(false);\n\t\t\ttry {\n\t\t\t\tconst result = await ctx.ui.custom<QuestionnaireResult>(\n\t\t\t\t\t(tui, theme, _kb, done) => {\n\t\t\t\t\t\tconst session = new QuestionnaireSession({\n\t\t\t\t\t\t\ttui,\n\t\t\t\t\t\t\ttheme,\n\t\t\t\t\t\t\tparams: typed,\n\t\t\t\t\t\t\titemsByTab,\n\t\t\t\t\t\t\tdone,\n\t\t\t\t\t\t});\n\t\t\t\t\t\treturn session.component;\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tsignal,\n\t\t\t\t\t\toverlay: true,\n\t\t\t\t\t\treserveTranscriptRows: true,\n\t\t\t\t\t\toverlayOptions: QUESTIONNAIRE_OVERLAY_OPTIONS,\n\t\t\t\t\t},\n\t\t\t\t);\n\n\t\t\t\treturn buildQuestionnaireResponse(result, typed);\n\t\t\t} finally {\n\t\t\t\tctx.ui.setWorkingVisible?.(true);\n\t\t\t}\n\t\t},\n\t};\n}\n\nexport { buildQuestionnaireResponse, buildToolResult };\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"multi-select-view.d.ts","sourceRoot":"","sources":["../../../../../../src/core/tools/ask-user-question/view/components/multi-select-view.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,iDAAiD,CAAC;AAE7E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAYxD,eAAO,MAAM,kBAAkB,WAAW,CAAC;AAE3C,MAAM,WAAW,oBAAoB;IACpC,IAAI,EAAE,aAAa,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,MAAM,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IAC3D,UAAU,EAAE,OAAO,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;;;GASG;AACH,qBAAa,eAAgB,YAAW,YAAY,CAAC,oBAAoB,CAAC;IACzE,OAAO,CAAC,KAAK,CAAuB;IAEpC,iBAAyB,KAAK,CAAQ;IACtC,iBAAyB,QAAQ,CAAe;IAEhD,YAAY,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,YAAY,EAI/C;IAED,QAAQ,CAAC,KAAK,EAAE,oBAAoB,GAAG,IAAI,CAE1C;IAED,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAG;IAEnC,UAAU,IAAI,IAAI,CAAG;IAErB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAgC9B;IAED,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAWnC;IAED,OAAO,CAAC,kBAAkB;CAW1B"}
1
+ {"version":3,"file":"multi-select-view.d.ts","sourceRoot":"","sources":["../../../../../../src/core/tools/ask-user-question/view/components/multi-select-view.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,iDAAiD,CAAC;AAG7E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAYxD,eAAO,MAAM,kBAAkB,WAAW,CAAC;AAE3C,MAAM,WAAW,oBAAoB;IACpC,IAAI,EAAE,aAAa,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,MAAM,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IAC3D,UAAU,EAAE,OAAO,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;;;GASG;AACH,qBAAa,eAAgB,YAAW,YAAY,CAAC,oBAAoB,CAAC;IACzE,OAAO,CAAC,KAAK,CAAuB;IAEpC,iBAAyB,KAAK,CAAQ;IACtC,iBAAyB,QAAQ,CAAe;IAEhD,YAAY,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,YAAY,EAI/C;IAED,QAAQ,CAAC,KAAK,EAAE,oBAAoB,GAAG,IAAI,CAE1C;IAED,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAG;IAEnC,UAAU,IAAI,IAAI,CAAG;IAErB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAkC9B;IAED,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAWnC;IAED,OAAO,CAAC,kBAAkB;CAW1B"}
@@ -1,4 +1,5 @@
1
1
  import { truncateToWidth, visibleWidth, wrapTextWithAnsi } from "@earendil-works/pi-tui";
2
+ import { OVERLAY_ACTIVE_ROW_MARKER } from "../../../../extensions/ui-types.js";
2
3
  import { ROW_INTENT_META } from "../../state/row-intent.js";
3
4
  const ACTIVE_POINTER = "❯ ";
4
5
  const INACTIVE_POINTER = " ";
@@ -50,7 +51,8 @@ export class MultiSelectView {
50
51
  const styledLabel = row.active ? this.theme.fg("accent", this.theme.bold(label)) : label;
51
52
  const num = String(i + 1).padStart(numberWidth, " ");
52
53
  const line = `${pointer}${num}${NUMBER_SEPARATOR}${box}${BOX_LABEL_GAP}${styledLabel}`;
53
- lines.push(truncateToWidth(line, width, ""));
54
+ const rendered = truncateToWidth(line, width, "");
55
+ lines.push(`${rendered}${row.active ? OVERLAY_ACTIVE_ROW_MARKER : ""}`);
54
56
  if (opt.description) {
55
57
  const wrapped = wrapTextWithAnsi(opt.description, contentWidth);
56
58
  for (const segment of wrapped) {
@@ -62,7 +64,8 @@ export class MultiSelectView {
62
64
  const nextLabel = this.props.nextActive
63
65
  ? this.theme.fg("accent", this.theme.bold(this.props.nextLabel))
64
66
  : this.props.nextLabel;
65
- lines.push(truncateToWidth(`${nextPointer}${nextLabel}`, width, ""));
67
+ const rendered = truncateToWidth(`${nextPointer}${nextLabel}`, width, "");
68
+ lines.push(`${rendered}${this.props.nextActive ? OVERLAY_ACTIVE_ROW_MARKER : ""}`);
66
69
  return lines;
67
70
  }
68
71
  naturalHeight(width) {