@a5c-ai/babysitter-sdk 0.0.183-staging.f48a64a2 → 0.0.183-staging.f4d4d1df

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.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * session:create command handler.
2
+ * harness:create-run command handler.
3
3
  *
4
4
  * Drives a full babysitter session lifecycle through two agentic phases:
5
5
  * Phase 1 - Unbound interview / intent / process-definition
@@ -1 +1 @@
1
- {"version":3,"file":"sessionCreate.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/sessionCreate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAWH,OAAO,KAAK,EACV,sBAAsB,EAKvB,MAAM,qBAAqB,CAAC;AA6B7B,MAAM,WAAW,iBAAiB;IAChC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AA8LD,wBAAgB,aAAa,CAC3B,UAAU,EAAE,sBAAsB,EAAE,EACpC,SAAS,CAAC,EAAE,MAAM,GACjB,sBAAsB,GAAG,SAAS,CAkBpC;AA81HD,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,iBAAiB,GACxB,OAAO,CAAC,MAAM,CAAC,CAgFjB"}
1
+ {"version":3,"file":"sessionCreate.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/sessionCreate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAWH,OAAO,KAAK,EACV,sBAAsB,EAKvB,MAAM,qBAAqB,CAAC;AAgC7B,MAAM,WAAW,iBAAiB;IAChC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAmMD,wBAAgB,aAAa,CAC3B,UAAU,EAAE,sBAAsB,EAAE,EACpC,SAAS,CAAC,EAAE,MAAM,GACjB,sBAAsB,GAAG,SAAS,CAkBpC;AAk4HD,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,iBAAiB,GACxB,OAAO,CAAC,MAAM,CAAC,CAgFjB"}
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  /**
3
- * session:create command handler.
3
+ * harness:create-run command handler.
4
4
  *
5
5
  * Drives a full babysitter session lifecycle through two agentic phases:
6
6
  * Phase 1 - Unbound interview / intent / process-definition
@@ -1592,10 +1592,15 @@ function isApprovalAskRequest(request) {
1592
1592
  labels[1] === "Reject" &&
1593
1593
  question.allowOther === false;
1594
1594
  }
1595
- async function askUserQuestionViaTool(request, interactive, rl) {
1595
+ async function askUserQuestionViaTool(request, interactive, rl, toolContext) {
1596
1596
  (0, interaction_1.validateAskUserQuestionRequest)(request);
1597
- if (interactive && rl) {
1598
- return (0, interaction_1.promptAskUserQuestionWithReadline)(rl, request);
1597
+ if (interactive) {
1598
+ if (toolContext?.hasUI && toolContext.ui) {
1599
+ return (0, interaction_1.promptAskUserQuestionWithUiContext)(toolContext.ui, request);
1600
+ }
1601
+ if (rl) {
1602
+ return (0, interaction_1.promptAskUserQuestionWithReadline)(rl, request);
1603
+ }
1599
1604
  }
1600
1605
  const answers = {};
1601
1606
  for (const [index, question] of request.questions.entries()) {
@@ -1716,7 +1721,7 @@ function buildExternalProcessDefinitionPrompt(args) {
1716
1721
  "- Keep the process practical for a brand-new directory: it should create the project, build the game, and verify that it runs or tests cleanly.",
1717
1722
  ].join("\n");
1718
1723
  return [
1719
- "You are running babysitter session:create phase 1 on an external CLI harness in non-interactive mode.",
1724
+ "You are running babysitter harness:create-run phase 1 on an external CLI harness in non-interactive mode.",
1720
1725
  "Do the real process-authoring work in the workspace and write the actual process file to disk.",
1721
1726
  "",
1722
1727
  "Task:",
@@ -1947,6 +1952,9 @@ async function runProcessDefinitionPhase(args) {
1947
1952
  const state = {};
1948
1953
  const phaseOutputs = [];
1949
1954
  let session = null;
1955
+ const interactiveUiContext = args.interactive && args.rl
1956
+ ? (0, interaction_1.createReadlineAskUserQuestionUiContext)(args.rl)
1957
+ : undefined;
1950
1958
  const writeVerbose = (message) => {
1951
1959
  writeVerboseLine(args.verbose, args.json, message);
1952
1960
  };
@@ -2039,9 +2047,9 @@ async function runProcessDefinitionPhase(args) {
2039
2047
  description: "Ask the user one to four structured clarification questions and receive structured answers.",
2040
2048
  promptSnippet: "Ask the user focused clarification questions when you need missing requirements.",
2041
2049
  parameters: ASK_USER_QUESTION_SCHEMA,
2042
- execute: async (_toolCallId, params) => {
2050
+ execute: async (_toolCallId, params, _signal, _onUpdate, toolContext) => {
2043
2051
  writeVerboseData("phase1 tool AskUserQuestion request", params);
2044
- const response = await askUserQuestionViaTool(params, args.interactive, args.rl);
2052
+ const response = await askUserQuestionViaTool(params, args.interactive, args.rl, toolContext);
2045
2053
  writeVerboseData("phase1 tool AskUserQuestion response", response);
2046
2054
  emitProgress({
2047
2055
  phase: "1",
@@ -2102,6 +2110,7 @@ async function runProcessDefinitionPhase(args) {
2102
2110
  thinkingLevel: "low",
2103
2111
  toolsMode: phase1ToolsMode,
2104
2112
  customTools,
2113
+ uiContext: interactiveUiContext,
2105
2114
  systemPrompt: processDefinitionSystemPrompt,
2106
2115
  isolated: true,
2107
2116
  ephemeral: true,
@@ -2551,9 +2560,9 @@ async function runOrchestrationPhase(args) {
2551
2560
  description: "Ask the user one to four structured questions and receive structured answers.",
2552
2561
  promptSnippet: "Use this for breakpoint approvals and required user clarification.",
2553
2562
  parameters: ASK_USER_QUESTION_SCHEMA,
2554
- execute: async (_toolCallId, params) => {
2563
+ execute: async (_toolCallId, params, _signal, _onUpdate, toolContext) => {
2555
2564
  writeVerboseData("phase2 tool AskUserQuestion request", params);
2556
- const response = await askUserQuestionViaTool(params, args.interactive, args.rl);
2565
+ const response = await askUserQuestionViaTool(params, args.interactive, args.rl, toolContext);
2557
2566
  state.lastAskUserQuestionResponse = response;
2558
2567
  writeVerboseData("phase2 tool AskUserQuestion response", response);
2559
2568
  return formatToolResult(response, "AskUserQuestion completed.");
@@ -2910,6 +2919,9 @@ async function runOrchestrationPhase(args) {
2910
2919
  };
2911
2920
  }
2912
2921
  if (!effectResult && action.kind === "breakpoint") {
2922
+ if (args.interactive && !state.lastAskUserQuestionResponse) {
2923
+ throw new exceptions_1.BabysitterRuntimeError("InteractiveBreakpointDecisionMissing", "Interactive breakpoint results require AskUserQuestion before babysitter_task_post_result.", { category: exceptions_1.ErrorCategory.Runtime });
2924
+ }
2913
2925
  const question = action.taskDef?.question ??
2914
2926
  action.taskDef?.title ??
2915
2927
  "Breakpoint reached. Continue?";
@@ -3082,6 +3094,9 @@ async function runOrchestrationPhase(args) {
3082
3094
  model: args.model,
3083
3095
  toolsMode: "coding",
3084
3096
  customTools,
3097
+ uiContext: args.interactive && args.rl
3098
+ ? (0, interaction_1.createReadlineAskUserQuestionUiContext)(args.rl)
3099
+ : undefined,
3085
3100
  appendSystemPrompt: [(0, sessionCreatePrompts_1.buildOrchestrationSystemPrompt)(args.selectedHarnessName, args.promptContext)],
3086
3101
  ephemeral: true,
3087
3102
  });
@@ -1 +1 @@
1
- {"version":3,"file":"sessionCreatePrompts.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/sessionCreatePrompts.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAElE,MAAM,WAAW,0BAA0B;IACzC,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,mBAAmB,EAAE,sBAAsB,EAAE,CAAC;IAC9C,kBAAkB,EAAE,OAAO,CAAC;IAC5B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,oBAAoB,EAAE,OAAO,GAAG,MAAM,GAAG,QAAQ,CAAC;IAClD,kBAAkB,EAAE,OAAO,CAAC;IAC5B,QAAQ,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAClD;AAED,MAAM,WAAW,kCAAkC;IACjD,WAAW,EAAE,OAAO,CAAC;IACrB,mBAAmB,CAAC,EAAE,OAAO,GAAG,WAAW,CAAC;IAC5C,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;CAC7B;AAgFD,wBAAgB,kCAAkC,CAChD,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,0BAA0B,GAClC,MAAM,CAyCR;AAED,wBAAgB,gCAAgC,CAC9C,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE,kCAAkC,GAC3C,MAAM,CA6CR;AAED,wBAAgB,8BAA8B,CAC5C,mBAAmB,EAAE,MAAM,EAC3B,OAAO,EAAE,0BAA0B,GAClC,MAAM,CA2BR;AAED,wBAAgB,iCAAiC,CAC/C,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,MAAM,GAAG,SAAS,EAC9B,aAAa,EAAE,MAAM,GACpB,MAAM,CAWR;AAED,wBAAgB,4BAA4B,CAAC,IAAI,EAAE;IACjD,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,KAAK,CAAC;QACrB,QAAQ,EAAE,MAAM,CAAC;QACjB,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,CAAC,CAAC;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,GAAG,MAAM,CA+CT"}
1
+ {"version":3,"file":"sessionCreatePrompts.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/sessionCreatePrompts.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAElE,MAAM,WAAW,0BAA0B;IACzC,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,mBAAmB,EAAE,sBAAsB,EAAE,CAAC;IAC9C,kBAAkB,EAAE,OAAO,CAAC;IAC5B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,oBAAoB,EAAE,OAAO,GAAG,MAAM,GAAG,QAAQ,CAAC;IAClD,kBAAkB,EAAE,OAAO,CAAC;IAC5B,QAAQ,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAClD;AAED,MAAM,WAAW,kCAAkC;IACjD,WAAW,EAAE,OAAO,CAAC;IACrB,mBAAmB,CAAC,EAAE,OAAO,GAAG,WAAW,CAAC;IAC5C,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;CAC7B;AAgFD,wBAAgB,kCAAkC,CAChD,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,0BAA0B,GAClC,MAAM,CA0CR;AAED,wBAAgB,gCAAgC,CAC9C,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE,kCAAkC,GAC3C,MAAM,CAwDR;AAED,wBAAgB,8BAA8B,CAC5C,mBAAmB,EAAE,MAAM,EAC3B,OAAO,EAAE,0BAA0B,GAClC,MAAM,CA4BR;AAED,wBAAgB,iCAAiC,CAC/C,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,MAAM,GAAG,SAAS,EAC9B,aAAa,EAAE,MAAM,GACpB,MAAM,CAWR;AAED,wBAAgB,4BAA4B,CAAC,IAAI,EAAE;IACjD,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,KAAK,CAAC;QACrB,QAAQ,EAAE,MAAM,CAAC;QACjB,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,CAAC,CAAC;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,GAAG,MAAM,CA+CT"}
@@ -79,15 +79,16 @@ function formatSharedContext(context) {
79
79
  }
80
80
  function buildProcessDefinitionSystemPrompt(outputPath, context) {
81
81
  return [
82
- "You are the babysitter session:create phase 1 agent.",
82
+ "You are the babysitter harness:create-run phase 1 agent.",
83
83
  "Your job is to turn the user's intent into a concrete babysitter process definition before any run is created or bound.",
84
84
  "",
85
85
  "Rules:",
86
86
  "- This phase is unbound. Do not create a run, bind a session, iterate a run, or post task results.",
87
+ "- In interactive mode, AskUserQuestion is the only in-loop way to ask the user for clarification. If you need missing requirements, call AskUserQuestion instead of asking in plain text.",
87
88
  "- Use the AskUserQuestion tool when clarification is useful. Ask focused, high-signal questions in batches when possible.",
88
- "- Before authoring the process in any mode, resolve the active shared process-library and conduct a real search against it. In this built-in PI path, use `babysitter_resolve_process_library`, `babysitter_search_process_library`, and `babysitter_read_process_library_file`; those tools are the internal `session:create` harness surface for process-library work. Outside this built-in path, use `babysitter process-library:active --json`, then search the returned `binding.dir`. Do not skip this process-library search step.",
89
+ "- Before authoring the process in any mode, resolve the active shared process-library and conduct a real search against it. In this built-in PI path, use `babysitter_resolve_process_library`, `babysitter_search_process_library`, and `babysitter_read_process_library_file`; those tools are the internal `harness:create-run` harness surface for process-library work. Outside this built-in path, use `babysitter process-library:active --json`, then search the returned `binding.dir`. Do not skip this process-library search step.",
89
90
  "- Treat `binding.dir` as the active process-library root that must be searched first. If you need the cloned repo root itself for adjacent material, use `defaultSpec.cloneDir`. Treat `reference/` under the active root or `defaultSpec.referenceRoot` as the canonical reference area.",
90
- "- In interactive mode, follow a real interview phase: inspect the repo/workspace state first, inspect the most relevant process-library references through the active binding, then ask only the next highest-signal question. Do not plan more than one interview step ahead.",
91
+ "- In interactive mode, follow a real interview phase: inspect the repo/workspace state first, inspect the most relevant process-library references through the active binding, then ask only the next highest-signal AskUserQuestion when material ambiguity remains. Do not plan more than one interview step ahead.",
91
92
  "- In non-interactive mode, skip user questions but still parse the request, inspect the repo/workspace structure, resolve the active process-library root, and search that active library for the most relevant specialization or methodology before authoring the process.",
92
93
  "- Research the workspace before finalizing the process. Use your available read/search/bash/write tools as needed.",
93
94
  "- Treat the provided workspace as the only relevant filesystem root unless the user explicitly points you somewhere else.",
@@ -128,14 +129,21 @@ function buildProcessDefinitionUserPrompt(userPrompt, outputPath, options) {
128
129
  : "(no files)";
129
130
  const lines = [
130
131
  interactive
131
- ? "Interactive mode. Ask focused clarification questions only when they materially improve the process."
132
+ ? "Interactive mode. Run the interview step first. If material requirements are missing, use AskUserQuestion rather than plain-text questions."
132
133
  : "Non-interactive mode. Do not call AskUserQuestion; infer missing details from the request and workspace state.",
133
134
  "",
134
135
  `User request: ${userPrompt}`,
135
136
  `Output path: ${outputPath}`,
136
137
  ];
137
138
  if (workspaceAssessment === "empty") {
138
- lines.push("Workspace assessment: empty.", `Workspace entries: ${workspaceSummary}`, "Treat this as a greenfield request and move straight to authoring the process.", "You still must resolve the active shared process-library and search it before writing the process.", "Start with the repo/workspace state, then inspect only the most relevant local babysitter process references or discover output before you author the process.", "Do not inspect unrelated directories, home-directory configs, or irrelevant global skill/plugin folders.", "Keep the process practical for a brand-new workspace: plan, scaffold, implement, verify.", "Write a real babysitter process, not a direct one-shot script. The top-level `process()` should orchestrate work through `defineTask(...)` and `ctx.task(...)`.", "Put the main implementation in one or more `agent` tasks. Use `shell` tasks only for concrete runnable verification or tooling commands.", "Do not add internal worker guardrail metadata such as `task.metadata.bashSandbox`, `task.metadata.isolated`, or `task.metadata.enableCompaction` unless the task truly requires them.", "Keep generated asset strings syntax-safe. If the process writes JS/HTML/CSS files, avoid raw nested template literals inside the process module; prefer arrays joined with \"\\n\", String.raw, or escaped inner backticks and \\${...} sequences.");
139
+ lines.push("Workspace assessment: empty.", `Workspace entries: ${workspaceSummary}`);
140
+ if (interactive) {
141
+ lines.push("Treat this as a greenfield request, but do not skip the interview just because the workspace is empty.", "If material product or delivery constraints remain ambiguous after workspace and process-library inspection, ask the next highest-signal AskUserQuestion before you finalize the process.");
142
+ }
143
+ else {
144
+ lines.push("Treat this as a greenfield request and move straight to authoring the process.");
145
+ }
146
+ lines.push("You still must resolve the active shared process-library and search it before writing the process.", "Start with the repo/workspace state, then inspect only the most relevant local babysitter process references or discover output before you author the process.", "Do not inspect unrelated directories, home-directory configs, or irrelevant global skill/plugin folders.", "Keep the process practical for a brand-new workspace: plan, scaffold, implement, verify.", "Write a real babysitter process, not a direct one-shot script. The top-level `process()` should orchestrate work through `defineTask(...)` and `ctx.task(...)`.", "Put the main implementation in one or more `agent` tasks. Use `shell` tasks only for concrete runnable verification or tooling commands.", "Do not add internal worker guardrail metadata such as `task.metadata.bashSandbox`, `task.metadata.isolated`, or `task.metadata.enableCompaction` unless the task truly requires them.", "Keep generated asset strings syntax-safe. If the process writes JS/HTML/CSS files, avoid raw nested template literals inside the process module; prefer arrays joined with \"\\n\", String.raw, or escaped inner backticks and \\${...} sequences.");
139
147
  }
140
148
  else if (workspaceAssessment === "non-empty") {
141
149
  lines.push(`Workspace assessment: non-empty (${workspaceSummary}).`, "Inspect only the workspace files that are relevant to the request before finalizing the process.", "Do not wander through unrelated global directories or repositories.");
@@ -145,20 +153,21 @@ function buildProcessDefinitionUserPrompt(userPrompt, outputPath, options) {
145
153
  }
146
154
  function buildOrchestrationSystemPrompt(selectedHarnessName, context) {
147
155
  return [
148
- "You are the babysitter session:create phase 2 orchestration agent.",
156
+ "You are the babysitter harness:create-run phase 2 orchestration agent.",
149
157
  "Your job is to run the babysitter orchestration loop through tools, not by narrating what should happen.",
150
158
  "Follow the babysit workflow directly: run one iteration, inspect the returned effects, perform the requested effects through the babysitter effect tools and available coding tools, post the results, and repeat until the run reaches a terminal state.",
151
159
  "",
152
160
  "Rules:",
153
161
  `- Treat ${selectedHarnessName} as the target harness binding for this orchestration session.`,
154
162
  "- You have your built-in coding tools (bash/read/write/edit/search) plus the custom babysitter tools below. Use them to do the orchestration work itself.",
163
+ "- AskUserQuestion is the in-loop user interaction tool for this phase. In interactive mode, use it instead of asking the user in plain text.",
155
164
  "- Call babysitter_run_create to create the run if it does not already exist.",
156
165
  "- Immediately call babysitter_bind_session after run creation and before the first orchestration iteration.",
157
166
  "- Work in bounded turns. In each turn, call babysitter_run_iterate at most once unless the prompt explicitly tells you otherwise.",
158
167
  "- When babysitter_run_iterate reports pending effects, resolve each effect through tools.",
159
- "- For breakpoint effects, use AskUserQuestion in interactive mode. In non-interactive mode, select the best option according to the user intent and current context. Then call babysitter_task_post_result.",
168
+ "- For breakpoint effects, use AskUserQuestion in interactive mode with explicit approval options, then call babysitter_task_post_result. Never auto-approve or fabricate an approval response. In non-interactive mode, select the best option according to the user intent and current context, then call babysitter_task_post_result.",
160
169
  "- For `shell` effects, prefer `babysitter_run_shell_effect` so the command executes on an internal PI worker that respects task metadata. Use raw bash/coding tools only when the effect payload clearly requires manual inspection or direct intervention before posting the explicit outcome with babysitter_task_post_result.",
161
- "- For `agent`, `node`, and `orchestrator_task` effects, prefer babysitter_dispatch_effect_harness so the pending effect is fulfilled through the intended harness wrapper. These babysitter effect tools are the built-in internal `session:create` harness surface for phase 2. If you fulfill an effect directly with your own coding tools, you must still call babysitter_task_post_result with the explicit outcome.",
170
+ "- For `agent`, `node`, and `orchestrator_task` effects, prefer babysitter_dispatch_effect_harness so the pending effect is fulfilled through the intended harness wrapper. These babysitter effect tools are the built-in internal `harness:create-run` harness surface for phase 2. If you fulfill an effect directly with your own coding tools, you must still call babysitter_task_post_result with the explicit outcome.",
162
171
  "- Do not rely on a hidden host-side effect executor. Perform or dispatch each effect intentionally based on the effect payload you received from babysitter_run_iterate.",
163
172
  "- Shell effects are first-class pending effects. Do not skip them, narrate them, or assume the host will run them for you.",
164
173
  "- When choosing how to execute pending work, respect task-level harness metadata and the installed harness catalog provided below.",
@@ -217,7 +226,7 @@ function buildOrchestrationTurnPrompt(args) {
217
226
  lines.push("Handling rules:");
218
227
  lines.push("- For `shell` effects, prefer babysitter_run_shell_effect, then call babysitter_task_post_result with explicit status/stdout/stderr/value fields.");
219
228
  lines.push("- For `agent`, `node`, or `orchestrator_task` effects, prefer babysitter_dispatch_effect_harness unless direct coding-tool execution is clearly better for the requested effect.");
220
- lines.push("- For `breakpoint` effects, use AskUserQuestion in interactive mode or choose the best option non-interactively, then post the result.");
229
+ lines.push("- For `breakpoint` effects, use AskUserQuestion in interactive mode with explicit approval options or choose the best option non-interactively, then post the result.");
221
230
  }
222
231
  else {
223
232
  lines.push("");
package/dist/cli/main.js CHANGED
@@ -120,7 +120,7 @@ const USAGE = `Usage:
120
120
  babysitter compression:toggle <layer> <on|off> [--json]
121
121
  babysitter compression:set <layer.key> <value> [--json]
122
122
  babysitter compression:reset [--json]
123
- babysitter session:create --prompt <text> [--harness <name>] [--process <path>] [--workspace <dir>] [--model <model>] [--max-iterations <n>] [--runs-dir <dir>] [--interactive|--no-interactive|--non-interactive] [--json] [--verbose]
123
+ babysitter harness:create-run --prompt <text> [--harness <name>] [--process <path>] [--workspace <dir>] [--model <model>] [--max-iterations <n>] [--runs-dir <dir>] [--interactive|--no-interactive|--non-interactive] [--json] [--verbose]
124
124
  babysitter harness:discover [--json]
125
125
  babysitter harness:list [--json]
126
126
  babysitter harness:install <name> [--workspace <dir>] [--json] [--dry-run] [--verbose]
@@ -1905,7 +1905,7 @@ const VALID_COMMANDS = [
1905
1905
  "session:check-iteration",
1906
1906
  "session:last-message",
1907
1907
  "session:iteration-message",
1908
- "session:create",
1908
+ "harness:create-run",
1909
1909
  "hook:log",
1910
1910
  "hook:run",
1911
1911
  "skill:discover",
@@ -2407,7 +2407,7 @@ function createBabysitterCli() {
2407
2407
  if (parsed.command === "harness:invoke") {
2408
2408
  return await handleHarnessInvoke(parsed);
2409
2409
  }
2410
- if (parsed.command === "session:create") {
2410
+ if (parsed.command === "harness:create-run") {
2411
2411
  const { handleSessionCreate } = await Promise.resolve().then(() => __importStar(require("./commands/sessionCreate")));
2412
2412
  return await handleSessionCreate({
2413
2413
  prompt: parsed.prompt,
@@ -1 +1 @@
1
- {"version":3,"file":"claudeCode.d.ts","sourceRoot":"","sources":["../../src/harness/claudeCode.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AA+BH,OAAO,KAAK,EACV,cAAc,EAMf,MAAM,SAAS,CAAC;AAghCjB,wBAAgB,uBAAuB,IAAI,cAAc,CAwExD"}
1
+ {"version":3,"file":"claudeCode.d.ts","sourceRoot":"","sources":["../../src/harness/claudeCode.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AA+BH,OAAO,KAAK,EACV,cAAc,EAMf,MAAM,SAAS,CAAC;AAsjCjB,wBAAgB,uBAAuB,IAAI,cAAc,CAwExD"}
@@ -155,6 +155,15 @@ function countPendingByKind(records) {
155
155
  }
156
156
  return Object.fromEntries(Array.from(counts.entries()).sort(([a], [b]) => a.localeCompare(b)));
157
157
  }
158
+ /**
159
+ * Returns true when every pending effect is a breakpoint (human-approval gate).
160
+ * Breakpoints require external human action, so the stop hook should allow exit
161
+ * rather than spinning the orchestration loop uselessly.
162
+ */
163
+ function isOnlyBreakpoints(pendingByKind) {
164
+ const keys = Object.keys(pendingByKind);
165
+ return keys.length === 1 && keys[0] === "breakpoint";
166
+ }
158
167
  // ---------------------------------------------------------------------------
159
168
  // Cleanup helper
160
169
  // ---------------------------------------------------------------------------
@@ -407,6 +416,7 @@ async function handleStopHookImpl(args) {
407
416
  let runState = "";
408
417
  let completionProof = "";
409
418
  let pendingKinds = "";
419
+ let onlyBreakpointsPending = false;
410
420
  let entrypointImportPath;
411
421
  if (runId) {
412
422
  try {
@@ -442,6 +452,7 @@ async function handleStopHookImpl(args) {
442
452
  if (kindKeys.length > 0) {
443
453
  pendingKinds = kindKeys.join(", ");
444
454
  }
455
+ onlyBreakpointsPending = pendingRecords.length > 0 && isOnlyBreakpoints(pendingByKind);
445
456
  if (hasCompleted) {
446
457
  runState = "completed";
447
458
  completionProof = (0, completionProof_1.resolveCompletionProof)(metadata);
@@ -486,6 +497,29 @@ async function handleStopHookImpl(args) {
486
497
  return 0;
487
498
  }
488
499
  }
500
+ // 5b. If the run is waiting but ONLY on breakpoints, allow exit.
501
+ // Breakpoints require human interaction — spinning the orchestration loop
502
+ // accomplishes nothing and wastes iterations. The user (or an external
503
+ // system) must resolve breakpoints before the run can proceed.
504
+ if (runState === "waiting" && onlyBreakpointsPending) {
505
+ log.info(`Run waiting on breakpoints only (${pendingKinds}) — allowing exit`);
506
+ if (verbose) {
507
+ process.stderr.write(`[hook:run stop] Run waiting on breakpoint(s) — allowing exit for human resolution\n`);
508
+ }
509
+ if (runId) {
510
+ await appendStopHookEvent(path.join(runsDir, runId), {
511
+ sessionId,
512
+ iteration: state.iteration,
513
+ decision: "approve",
514
+ reason: "breakpoint_waiting",
515
+ runState,
516
+ pendingKinds,
517
+ hasPromise,
518
+ });
519
+ }
520
+ process.stdout.write("{}\n");
521
+ return 0;
522
+ }
489
523
  // 6. If completionProof matches promiseValue → complete
490
524
  if (hasPromise) {
491
525
  log.info("Detected valid promise tag");
@@ -1 +1 @@
1
- {"version":3,"file":"geminiCli.d.ts","sourceRoot":"","sources":["../../src/harness/geminiCli.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAsBH,OAAO,KAAK,EACV,cAAc,EAMf,MAAM,SAAS,CAAC;AAsxBjB,wBAAgB,sBAAsB,IAAI,cAAc,CA8EvD"}
1
+ {"version":3,"file":"geminiCli.d.ts","sourceRoot":"","sources":["../../src/harness/geminiCli.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAsBH,OAAO,KAAK,EACV,cAAc,EAMf,MAAM,SAAS,CAAC;AA2zBjB,wBAAgB,sBAAsB,IAAI,cAAc,CA8EvD"}
@@ -175,6 +175,15 @@ function countPendingByKind(records) {
175
175
  }
176
176
  return Object.fromEntries(Array.from(counts.entries()).sort(([a], [b]) => a.localeCompare(b)));
177
177
  }
178
+ /**
179
+ * Returns true when every pending effect is a breakpoint (human-approval gate).
180
+ * Breakpoints require external human action, so the stop hook should allow exit
181
+ * rather than spinning the orchestration loop uselessly.
182
+ */
183
+ function isOnlyBreakpoints(pendingByKind) {
184
+ const keys = Object.keys(pendingByKind);
185
+ return keys.length === 1 && keys[0] === "breakpoint";
186
+ }
178
187
  // ---------------------------------------------------------------------------
179
188
  // Cleanup helper
180
189
  // ---------------------------------------------------------------------------
@@ -362,6 +371,7 @@ async function handleAfterAgentHookImpl(args) {
362
371
  let runState = "";
363
372
  let completionProof = "";
364
373
  let pendingKinds = "";
374
+ let onlyBreakpointsPending = false;
365
375
  try {
366
376
  let runDir = path.isAbsolute(runId)
367
377
  ? runId
@@ -394,6 +404,7 @@ async function handleAfterAgentHookImpl(args) {
394
404
  if (kindKeys.length > 0) {
395
405
  pendingKinds = kindKeys.join(", ");
396
406
  }
407
+ onlyBreakpointsPending = pendingRecords.length > 0 && isOnlyBreakpoints(pendingByKind);
397
408
  if (hasCompleted) {
398
409
  runState = "completed";
399
410
  completionProof = (0, completionProof_1.resolveCompletionProof)(metadata);
@@ -430,6 +441,28 @@ async function handleAfterAgentHookImpl(args) {
430
441
  process.stdout.write("{}\n");
431
442
  return 0;
432
443
  }
444
+ // 9b. If the run is waiting but ONLY on breakpoints, allow exit.
445
+ // Breakpoints require human interaction — spinning the orchestration loop
446
+ // accomplishes nothing and wastes iterations.
447
+ if (runState === "waiting" && onlyBreakpointsPending) {
448
+ log.info(`Run waiting on breakpoints only (${pendingKinds}) — allowing exit`);
449
+ if (verbose) {
450
+ process.stderr.write(`[hook:run after-agent] Run waiting on breakpoint(s) — allowing exit for human resolution\n`);
451
+ }
452
+ if (runId) {
453
+ await appendStopHookEvent(path.join(runsDir, runId), {
454
+ sessionId,
455
+ iteration: state.iteration,
456
+ decision: "approve",
457
+ reason: "breakpoint_waiting",
458
+ runState,
459
+ pendingKinds,
460
+ hasPromise,
461
+ });
462
+ }
463
+ process.stdout.write("{}\n");
464
+ return 0;
465
+ }
433
466
  // 10. Check completion proof match
434
467
  if (hasPromise && completionProof && promiseValue === completionProof) {
435
468
  log.info("Promise matches completion proof — allowing exit");
@@ -1 +1 @@
1
- {"version":3,"file":"piWrapper.d.ts","sourceRoot":"","sources":["../../src/harness/piWrapper.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAYhF,sCAAsC;AACtC,MAAM,MAAM,eAAe,GAAG,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,CAAC;AAmP9D;;;;;GAKG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAmB;IAC3C,OAAO,CAAC,OAAO,CAA+B;IAC9C,OAAO,CAAC,WAAW,CAA8B;IACjD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAyC;gBAE1D,OAAO,GAAE,gBAAqB;IAI1C;;;;;OAKG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAcjC;;;;;OAKG;IACG,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAyGrE;;;;;OAKG;IACG,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAKxC;;OAEG;IACG,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAK3C;;;;OAIG;IACH,SAAS,CAAC,QAAQ,EAAE,eAAe,GAAG,MAAM,IAAI;IAKhD;;OAEG;IACG,WAAW,CACf,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,GAChC,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;QAAC,SAAS,EAAE,OAAO,CAAA;KAAE,CAAC;IAWhF;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAM5B;;OAEG;IACH,OAAO,IAAI,IAAI;IAcf,oDAAoD;IACpD,IAAI,SAAS,IAAI,MAAM,GAAG,SAAS,CAElC;IAED,6DAA6D;IAC7D,IAAI,WAAW,IAAI,OAAO,CAEzB;IAED,gDAAgD;IAChD,IAAI,aAAa,IAAI,OAAO,CAE3B;YAMa,YAAY;IAmJ1B,OAAO,CAAC,cAAc;CAUvB;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,OAAO,CAAC,EAAE,gBAAgB,GAAG,eAAe,CAE3E"}
1
+ {"version":3,"file":"piWrapper.d.ts","sourceRoot":"","sources":["../../src/harness/piWrapper.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAYhF,sCAAsC;AACtC,MAAM,MAAM,eAAe,GAAG,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,CAAC;AAoP9D;;;;;GAKG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAmB;IAC3C,OAAO,CAAC,OAAO,CAA+B;IAC9C,OAAO,CAAC,WAAW,CAA8B;IACjD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAyC;gBAE1D,OAAO,GAAE,gBAAqB;IAI1C;;;;;OAKG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAcjC;;;;;OAKG;IACG,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAyGrE;;;;;OAKG;IACG,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAKxC;;OAEG;IACG,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAK3C;;;;OAIG;IACH,SAAS,CAAC,QAAQ,EAAE,eAAe,GAAG,MAAM,IAAI;IAKhD;;OAEG;IACG,WAAW,CACf,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,GAChC,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;QAAC,SAAS,EAAE,OAAO,CAAA;KAAE,CAAC;IAWhF;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAM5B;;OAEG;IACH,OAAO,IAAI,IAAI;IAcf,oDAAoD;IACpD,IAAI,SAAS,IAAI,MAAM,GAAG,SAAS,CAElC;IAED,6DAA6D;IAC7D,IAAI,WAAW,IAAI,OAAO,CAEzB;IAED,gDAAgD;IAChD,IAAI,aAAa,IAAI,OAAO,CAE3B;YAMa,YAAY;IAsJ1B,OAAO,CAAC,cAAc;CAUvB;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,OAAO,CAAC,EAAE,gBAAgB,GAAG,eAAe,CAE3E"}
@@ -527,6 +527,9 @@ class PiSessionHandle {
527
527
  }
528
528
  try {
529
529
  const { session } = await mod.createAgentSession(createOpts);
530
+ if (this.options.uiContext && typeof session.bindExtensions === "function") {
531
+ await session.bindExtensions({ uiContext: this.options.uiContext });
532
+ }
530
533
  this.session = session;
531
534
  }
532
535
  catch (error) {
@@ -6,6 +6,7 @@
6
6
  * hook input/output formats. The adapter interface abstracts these differences
7
7
  * so the SDK core remains harness-agnostic.
8
8
  */
9
+ import type { AskUserQuestionUiContext } from "../interaction";
9
10
  /** Capabilities that a harness adapter may support. */
10
11
  export declare enum HarnessCapability {
11
12
  /** Harness supports programmatic (non-interactive) invocation. */
@@ -96,6 +97,8 @@ export interface PiSessionOptions {
96
97
  toolsMode?: "default" | "coding" | "readonly";
97
98
  /** Custom tool definitions to register with the session. */
98
99
  customTools?: unknown[];
100
+ /** Optional extension-style UI context exposed to custom tools inside the PI loop. */
101
+ uiContext?: AskUserQuestionUiContext;
99
102
  /** Replace the discovered system prompt with a custom one. */
100
103
  systemPrompt?: string;
101
104
  /** Append custom system prompt instructions. */
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/harness/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/harness/types.ts"],"names":[],"mappings":"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"}
@@ -18,8 +18,15 @@ export interface AskUserQuestionRequest {
18
18
  export interface AskUserQuestionResponse {
19
19
  answers: Record<string, string>;
20
20
  }
21
+ export interface AskUserQuestionUiContext {
22
+ select(title: string, options: string[]): Promise<string | undefined>;
23
+ input(title: string, placeholder?: string): Promise<string | undefined>;
24
+ confirm(title: string, message: string): Promise<boolean>;
25
+ }
21
26
  export declare function validateAskUserQuestionRequest(request: AskUserQuestionRequest): void;
22
27
  export declare function createAskUserQuestionResponse(request: AskUserQuestionRequest, answers: Record<string, string>): AskUserQuestionResponse;
23
28
  export declare function createApprovalAskUserQuestion(question: string, header?: string): AskUserQuestionRequest;
29
+ export declare function createReadlineAskUserQuestionUiContext(rl: readline.Interface): AskUserQuestionUiContext;
30
+ export declare function promptAskUserQuestionWithUiContext(ui: AskUserQuestionUiContext, request: AskUserQuestionRequest): Promise<AskUserQuestionResponse>;
24
31
  export declare function promptAskUserQuestionWithReadline(rl: readline.Interface, request: AskUserQuestionRequest): Promise<AskUserQuestionResponse>;
25
32
  //# sourceMappingURL=askUserQuestion.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"askUserQuestion.d.ts","sourceRoot":"","sources":["../../src/interaction/askUserQuestion.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAC;AAa1C,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,uBAAuB;IACtC,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,qBAAqB,EAAE,CAAC;IAClC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,sBAAsB;IACrC,SAAS,EAAE,uBAAuB,EAAE,CAAC;CACtC;AAED,MAAM,WAAW,uBAAuB;IACtC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACjC;AA2DD,wBAAgB,8BAA8B,CAC5C,OAAO,EAAE,sBAAsB,GAC9B,IAAI,CAuCN;AAED,wBAAgB,6BAA6B,CAC3C,OAAO,EAAE,sBAAsB,EAC/B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC9B,uBAAuB,CAUzB;AAED,wBAAgB,6BAA6B,CAC3C,QAAQ,EAAE,MAAM,EAChB,MAAM,GAAE,MAAmB,GAC1B,sBAAsB,CAqBxB;AAED,wBAAsB,iCAAiC,CACrD,EAAE,EAAE,QAAQ,CAAC,SAAS,EACtB,OAAO,EAAE,sBAAsB,GAC9B,OAAO,CAAC,uBAAuB,CAAC,CAsDlC"}
1
+ {"version":3,"file":"askUserQuestion.d.ts","sourceRoot":"","sources":["../../src/interaction/askUserQuestion.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAC;AAa1C,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,uBAAuB;IACtC,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,qBAAqB,EAAE,CAAC;IAClC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,sBAAsB;IACrC,SAAS,EAAE,uBAAuB,EAAE,CAAC;CACtC;AAED,MAAM,WAAW,uBAAuB;IACtC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACjC;AAED,MAAM,WAAW,wBAAwB;IACvC,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IACtE,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IACxE,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CAC3D;AA2DD,wBAAgB,8BAA8B,CAC5C,OAAO,EAAE,sBAAsB,GAC9B,IAAI,CAuCN;AAED,wBAAgB,6BAA6B,CAC3C,OAAO,EAAE,sBAAsB,EAC/B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC9B,uBAAuB,CAUzB;AAED,wBAAgB,6BAA6B,CAC3C,QAAQ,EAAE,MAAM,EAChB,MAAM,GAAE,MAAmB,GAC1B,sBAAsB,CAqBxB;AAqBD,wBAAgB,sCAAsC,CACpD,EAAE,EAAE,QAAQ,CAAC,SAAS,GACrB,wBAAwB,CA+B1B;AAED,wBAAsB,kCAAkC,CACtD,EAAE,EAAE,wBAAwB,EAC5B,OAAO,EAAE,sBAAsB,GAC9B,OAAO,CAAC,uBAAuB,CAAC,CAiGlC;AAED,wBAAsB,iCAAiC,CACrD,EAAE,EAAE,QAAQ,CAAC,SAAS,EACtB,OAAO,EAAE,sBAAsB,GAC9B,OAAO,CAAC,uBAAuB,CAAC,CAsDlC"}
@@ -3,6 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.validateAskUserQuestionRequest = validateAskUserQuestionRequest;
4
4
  exports.createAskUserQuestionResponse = createAskUserQuestionResponse;
5
5
  exports.createApprovalAskUserQuestion = createApprovalAskUserQuestion;
6
+ exports.createReadlineAskUserQuestionUiContext = createReadlineAskUserQuestionUiContext;
7
+ exports.promptAskUserQuestionWithUiContext = promptAskUserQuestionWithUiContext;
6
8
  exports.promptAskUserQuestionWithReadline = promptAskUserQuestionWithReadline;
7
9
  const RESET = "\x1b[0m";
8
10
  const BOLD = "\x1b[1m";
@@ -116,6 +118,135 @@ function createApprovalAskUserQuestion(question, header = "Decision") {
116
118
  ],
117
119
  };
118
120
  }
121
+ function formatUiPromptTitle(question) {
122
+ const lines = [question.question.trim()];
123
+ if (question.options?.length) {
124
+ lines.push("");
125
+ for (const [index, option] of question.options.entries()) {
126
+ const detailParts = [option.description?.trim(), option.preview?.trim()].filter(Boolean);
127
+ const detail = detailParts.length > 0 ? ` - ${detailParts.join(" | ")}` : "";
128
+ lines.push(`${index + 1}. ${option.label}${detail}`);
129
+ }
130
+ }
131
+ return lines.join("\n");
132
+ }
133
+ function buildUiTitle(question) {
134
+ const header = question.header?.trim();
135
+ const body = formatUiPromptTitle(question);
136
+ return header ? `${header}\n\n${body}` : body;
137
+ }
138
+ function createReadlineAskUserQuestionUiContext(rl) {
139
+ return {
140
+ async select(title, options) {
141
+ process.stderr.write(`${title}\n`);
142
+ for (const [index, option] of options.entries()) {
143
+ process.stderr.write(` ${index + 1}. ${option}\n`);
144
+ }
145
+ let matched;
146
+ while (!matched) {
147
+ const answer = await askLine(rl, "Choose an option (number or label)");
148
+ if (!answer) {
149
+ return undefined;
150
+ }
151
+ matched = resolveOption(answer, options.map((label) => ({ label })));
152
+ if (matched) {
153
+ return matched.label;
154
+ }
155
+ process.stderr.write(`${YELLOW}Please choose a valid option.${RESET}\n`);
156
+ }
157
+ },
158
+ async input(title, placeholder) {
159
+ process.stderr.write(`${title}\n`);
160
+ const answer = await askLine(rl, placeholder?.trim() || "Answer");
161
+ return answer || undefined;
162
+ },
163
+ async confirm(title, message) {
164
+ process.stderr.write(`${title}\n${message}\n`);
165
+ const answer = await askLine(rl, "Confirm (y/N)");
166
+ return ["y", "yes"].includes(answer.trim().toLowerCase());
167
+ },
168
+ };
169
+ }
170
+ async function promptAskUserQuestionWithUiContext(ui, request) {
171
+ validateAskUserQuestionRequest(request);
172
+ const answers = {};
173
+ for (const [index, question] of request.questions.entries()) {
174
+ const key = getQuestionKey(question, index);
175
+ const options = question.options ?? [];
176
+ if (options.length === 0) {
177
+ let resolved = false;
178
+ while (!resolved) {
179
+ const answer = (await ui.input(buildUiTitle(question), question.required ? "Answer (required)" : "Answer"))?.trim();
180
+ if (answer) {
181
+ answers[key] = answer;
182
+ resolved = true;
183
+ continue;
184
+ }
185
+ if (!question.required) {
186
+ answers[key] = "";
187
+ resolved = true;
188
+ }
189
+ }
190
+ continue;
191
+ }
192
+ if (question.multiSelect) {
193
+ let resolved = false;
194
+ while (!resolved) {
195
+ const rawAnswer = (await ui.input(buildUiTitle(question), "Enter one or more options (numbers or labels, comma-separated)"))?.trim() ?? "";
196
+ if (!rawAnswer && !question.required) {
197
+ answers[key] = "";
198
+ resolved = true;
199
+ continue;
200
+ }
201
+ const parsed = parseOptionAnswer(rawAnswer, question);
202
+ if (parsed !== undefined) {
203
+ answers[key] = parsed;
204
+ resolved = true;
205
+ }
206
+ }
207
+ continue;
208
+ }
209
+ const allowOther = question.allowOther !== false;
210
+ const optionLabels = options.map((option) => option.label);
211
+ const selectOptions = allowOther
212
+ ? [...optionLabels, "Other (type a custom answer)"]
213
+ : optionLabels;
214
+ let resolved = false;
215
+ while (!resolved) {
216
+ const selection = await ui.select(buildUiTitle(question), selectOptions);
217
+ if (!selection) {
218
+ if (question.required) {
219
+ continue;
220
+ }
221
+ answers[key] = "";
222
+ resolved = true;
223
+ continue;
224
+ }
225
+ if (allowOther && selection === "Other (type a custom answer)") {
226
+ const other = (await ui.input(buildUiTitle(question), "Type your answer"))?.trim();
227
+ if (other) {
228
+ answers[key] = other;
229
+ resolved = true;
230
+ continue;
231
+ }
232
+ if (!question.required) {
233
+ answers[key] = "";
234
+ resolved = true;
235
+ }
236
+ continue;
237
+ }
238
+ const parsed = parseOptionAnswer(selection, {
239
+ ...question,
240
+ allowOther: false,
241
+ });
242
+ if (parsed !== undefined) {
243
+ answers[key] = parsed;
244
+ resolved = true;
245
+ }
246
+ }
247
+ }
248
+ return createAskUserQuestionResponse(request, answers);
249
+ }
119
250
  async function promptAskUserQuestionWithReadline(rl, request) {
120
251
  validateAskUserQuestionRequest(request);
121
252
  const answers = {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@a5c-ai/babysitter-sdk",
3
- "version": "0.0.183-staging.f48a64a2",
3
+ "version": "0.0.183-staging.f4d4d1df",
4
4
  "description": "Storage and run-registry primitives for event-sourced babysitter workflows.",
5
5
  "license": "UNLICENSED",
6
6
  "type": "commonjs",