@a5c-ai/babysitter-sdk 0.0.183-staging.d5ce2137 → 0.0.183-staging.dfcd1fad

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 +1 @@
1
- {"version":3,"file":"sessionCreate.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/sessionCreate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAWH,OAAO,KAAK,EACV,sBAAsB,EAIvB,MAAM,qBAAqB,CAAC;AA0B7B,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;AA+ID,wBAAgB,aAAa,CAC3B,UAAU,EAAE,sBAAsB,EAAE,EACpC,SAAS,CAAC,EAAE,MAAM,GACjB,sBAAsB,GAAG,SAAS,CAYpC;AA2hDD,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,iBAAiB,GACxB,OAAO,CAAC,MAAM,CAAC,CAiFjB"}
1
+ {"version":3,"file":"sessionCreate.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/sessionCreate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAWH,OAAO,KAAK,EACV,sBAAsB,EAIvB,MAAM,qBAAqB,CAAC;AA0B7B,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;AAsLD,wBAAgB,aAAa,CAC3B,UAAU,EAAE,sBAAsB,EAAE,EACpC,SAAS,CAAC,EAAE,MAAM,GACjB,sBAAsB,GAAG,SAAS,CAYpC;AAiwDD,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,iBAAiB,GACxB,OAAO,CAAC,MAAM,CAAC,CAiFjB"}
@@ -72,6 +72,34 @@ const GREEN = "\x1b[32m";
72
72
  const YELLOW = "\x1b[33m";
73
73
  const RED = "\x1b[31m";
74
74
  const MAGENTA = "\x1b[35m";
75
+ const VERBOSE_LOG_LIMIT = 4_000;
76
+ function truncateForVerboseLog(text, maxChars = VERBOSE_LOG_LIMIT) {
77
+ const normalized = text.replace(/\r\n/g, "\n");
78
+ if (normalized.length <= maxChars) {
79
+ return normalized;
80
+ }
81
+ return `${normalized.slice(0, maxChars)}\n... [truncated ${normalized.length - maxChars} chars]`;
82
+ }
83
+ function stringifyForVerboseLog(value, maxChars = VERBOSE_LOG_LIMIT) {
84
+ try {
85
+ const raw = typeof value === "string" ? value : JSON.stringify(value, null, 2);
86
+ return truncateForVerboseLog(raw, maxChars);
87
+ }
88
+ catch {
89
+ return truncateForVerboseLog(String(value), maxChars);
90
+ }
91
+ }
92
+ function writeVerboseLine(enabled, json, message) {
93
+ if (!json && enabled) {
94
+ process.stderr.write(`${DIM}${message}${RESET}\n`);
95
+ }
96
+ }
97
+ function writeVerboseBlock(enabled, json, label, value, maxChars = VERBOSE_LOG_LIMIT) {
98
+ if (json || !enabled) {
99
+ return;
100
+ }
101
+ process.stderr.write(`${DIM}[${label}]${RESET}\n${DIM}${stringifyForVerboseLog(value, maxChars)}${RESET}\n`);
102
+ }
75
103
  function loadSessionCompressionConfig(workspace) {
76
104
  try {
77
105
  return (0, config_loader_1.loadCompressionConfig)(workspace ?? process.cwd());
@@ -166,65 +194,107 @@ function buildMetaPrompt(userPrompt, workDir) {
166
194
  template = template.replace("{{INTERVIEW_CONTEXT}}", "");
167
195
  return template;
168
196
  }
169
- function buildFallbackProcessDefinitionSource(userPrompt) {
170
- const serializedPrompt = JSON.stringify(userPrompt);
171
- return `import { defineTask } from "@a5c-ai/babysitter-sdk";
172
-
173
- const implementRequest = defineTask("implement-request", (args) => ({
174
- kind: "agent",
175
- title: "Implement the requested work",
176
- agent: {
177
- prompt: {
178
- role: "delivery engineer",
179
- task: "Implement the user's request in the current workspace.",
180
- context: {
181
- request: args.request,
182
- },
183
- instructions: [
184
- "Create or update the necessary project files in the current workspace.",
185
- "Keep the implementation as small and direct as possible while still satisfying the request.",
186
- "Run lightweight verification where practical and include what you verified in the result.",
187
- "Return JSON with summary, changedFiles, and verificationNotes."
188
- ],
189
- outputFormat: "JSON with summary, changedFiles, verificationNotes"
197
+ function looksLikeProcessDefinitionSource(source) {
198
+ const normalized = source.trim();
199
+ if (!normalized) {
200
+ return false;
190
201
  }
191
- }
192
- }));
193
-
194
- const verifyRequest = defineTask("verify-request", (args) => ({
195
- kind: "agent",
196
- title: "Verify the requested work",
197
- agent: {
198
- prompt: {
199
- role: "verification engineer",
200
- task: "Verify that the user's request was completed and identify any remaining gaps.",
201
- context: {
202
- request: args.request,
203
- implementation: args.implementation
204
- },
205
- instructions: [
206
- "Inspect the workspace state produced by the implementation step.",
207
- "Confirm whether the requested work exists and is usable.",
208
- "If there are remaining issues, describe them precisely.",
209
- "Return JSON with success, findings, and recommendedNextSteps."
210
- ],
211
- outputFormat: "JSON with success, findings, recommendedNextSteps"
202
+ return (normalized.includes("defineTask(") ||
203
+ /export\s+async\s+function\s+process\s*\(/.test(normalized) ||
204
+ /export\s+default\s+async\s+function/.test(normalized) ||
205
+ /export\s*\{\s*process\s*\}/.test(normalized));
206
+ }
207
+ function extractProcessDefinitionCodeBlock(text) {
208
+ const codeBlockPattern = /```(?:javascript|js|mjs|ts)?\s*([\s\S]*?)```/gi;
209
+ let match;
210
+ let fallback = null;
211
+ while ((match = codeBlockPattern.exec(text)) !== null) {
212
+ const candidate = match[1]?.trim();
213
+ if (!candidate) {
214
+ continue;
215
+ }
216
+ if (looksLikeProcessDefinitionSource(candidate)) {
217
+ return candidate;
218
+ }
219
+ fallback ??= candidate;
212
220
  }
213
- }
214
- }));
215
-
216
- export async function process(inputs, ctx) {
217
- const request = inputs?.prompt || ${serializedPrompt};
218
- const implementation = await ctx.task(implementRequest, { request });
219
- const verification = await ctx.task(verifyRequest, { request, implementation });
220
- return {
221
- request,
222
- implementation,
223
- verification,
224
- success: verification?.success !== false,
225
- };
221
+ return fallback;
222
+ }
223
+ function normalizeReportedPath(candidate, workspace) {
224
+ const trimmed = candidate.trim().replace(/^['"`]|['"`]$/g, "");
225
+ if (path.isAbsolute(trimmed)) {
226
+ return path.resolve(trimmed);
227
+ }
228
+ return path.resolve(workspace ?? process.cwd(), trimmed);
226
229
  }
227
- `;
230
+ function extractMentionedProcessPaths(text, workspace) {
231
+ const patterns = [
232
+ /([A-Za-z]:[\\/][^\r\n"'`]+?\.m?js)\b/g,
233
+ /((?:\.{0,2}[\\/]|\/)[^\r\n"'`]+?\.m?js)\b/g,
234
+ /\b([A-Za-z0-9_.\-\\/]+generated-process\.m?js)\b/g,
235
+ ];
236
+ const matches = new Set();
237
+ for (const pattern of patterns) {
238
+ let match;
239
+ while ((match = pattern.exec(text)) !== null) {
240
+ const raw = match[1];
241
+ if (raw) {
242
+ matches.add(normalizeReportedPath(raw, workspace));
243
+ }
244
+ }
245
+ }
246
+ return [...matches];
247
+ }
248
+ async function recoverProcessDefinitionFromOutputs(args) {
249
+ const expectedPath = path.resolve(args.outputPath);
250
+ try {
251
+ await waitForProcessFile(expectedPath, 1_000);
252
+ return {
253
+ processPath: expectedPath,
254
+ summary: "Recovered from missing process-definition tool report by using the expected output path.",
255
+ };
256
+ }
257
+ catch {
258
+ // continue to other recovery strategies
259
+ }
260
+ for (const output of args.outputs) {
261
+ for (const candidatePath of extractMentionedProcessPaths(output, args.workspace)) {
262
+ try {
263
+ await waitForProcessFile(candidatePath, 1_000);
264
+ return {
265
+ processPath: candidatePath,
266
+ summary: "Recovered process-definition output by using a path mentioned by the agent.",
267
+ };
268
+ }
269
+ catch {
270
+ // keep trying
271
+ }
272
+ }
273
+ }
274
+ for (const output of args.outputs) {
275
+ const extracted = extractProcessDefinitionCodeBlock(output);
276
+ if (!extracted || !looksLikeProcessDefinitionSource(extracted)) {
277
+ continue;
278
+ }
279
+ await node_fs_1.promises.mkdir(path.dirname(expectedPath), { recursive: true });
280
+ await node_fs_1.promises.writeFile(expectedPath, extracted, "utf8");
281
+ return {
282
+ processPath: expectedPath,
283
+ summary: "Recovered process-definition output by writing a JavaScript code block returned by the agent.",
284
+ };
285
+ }
286
+ for (const output of args.outputs) {
287
+ if (!looksLikeProcessDefinitionSource(output)) {
288
+ continue;
289
+ }
290
+ await node_fs_1.promises.mkdir(path.dirname(expectedPath), { recursive: true });
291
+ await node_fs_1.promises.writeFile(expectedPath, output.trim(), "utf8");
292
+ return {
293
+ processPath: expectedPath,
294
+ summary: "Recovered process-definition output by writing the agent's direct JavaScript response.",
295
+ };
296
+ }
297
+ return null;
228
298
  }
229
299
  const POLL_INTERVAL_MS = 1_000;
230
300
  const POLL_TIMEOUT_MS = 60_000;
@@ -662,6 +732,13 @@ function writeVerboseProcessDefinitionRecovery(json) {
662
732
  }
663
733
  async function runProcessDefinitionPhase(args) {
664
734
  const state = {};
735
+ const phaseOutputs = [];
736
+ const writeVerbose = (message) => {
737
+ writeVerboseLine(args.verbose, args.json, message);
738
+ };
739
+ const writeVerboseData = (label, value, maxChars) => {
740
+ writeVerboseBlock(args.verbose, args.json, label, value, maxChars);
741
+ };
665
742
  const customTools = [
666
743
  {
667
744
  name: "AskUserQuestion",
@@ -670,7 +747,9 @@ async function runProcessDefinitionPhase(args) {
670
747
  promptSnippet: "Ask the user focused clarification questions when you need missing requirements.",
671
748
  parameters: ASK_USER_QUESTION_SCHEMA,
672
749
  execute: async (_toolCallId, params) => {
750
+ writeVerboseData("phase1 tool AskUserQuestion request", params);
673
751
  const response = await askUserQuestionViaTool(params, args.interactive, args.rl);
752
+ writeVerboseData("phase1 tool AskUserQuestion response", response);
674
753
  emitProgress({
675
754
  phase: "1",
676
755
  status: "interview",
@@ -688,6 +767,7 @@ async function runProcessDefinitionPhase(args) {
688
767
  summary: typebox_1.Type.Optional(typebox_1.Type.String()),
689
768
  }),
690
769
  execute: (_toolCallId, params) => {
770
+ writeVerboseData("phase1 tool babysitter_report_process_definition", params);
691
771
  state.report = {
692
772
  processPath: params.processPath,
693
773
  summary: params.summary,
@@ -697,12 +777,21 @@ async function runProcessDefinitionPhase(args) {
697
777
  },
698
778
  ];
699
779
  emitProgress({ phase: "1", status: "started", harness: "pi (agentic)" }, args.json, args.verbose);
780
+ writeVerbose(`[phase1 setup] workspace=${path.resolve(args.workspace ?? process.cwd())} model=${args.model ?? "(default)"} outputPath=${path.resolve(args.outputPath)}`);
781
+ writeVerboseData("phase1 tools", customTools.map((tool) => ({
782
+ name: tool.name,
783
+ label: tool.label,
784
+ })));
785
+ const processDefinitionSystemPrompt = (0, sessionCreatePrompts_1.buildProcessDefinitionSystemPrompt)(args.outputPath, args.promptContext);
786
+ const initialMetaPrompt = compressInternalHarnessPrompt(buildMetaPrompt(args.prompt, args.workspace ?? process.cwd()), args.compressionConfig, "agent");
787
+ writeVerboseData("phase1 system prompt", processDefinitionSystemPrompt);
788
+ writeVerboseData("phase1 initial prompt", initialMetaPrompt);
700
789
  const session = (0, piWrapper_1.createPiSession)({
701
790
  workspace: args.workspace,
702
791
  model: args.model,
703
792
  toolsMode: "coding",
704
793
  customTools,
705
- appendSystemPrompt: [(0, sessionCreatePrompts_1.buildProcessDefinitionSystemPrompt)(args.outputPath, args.promptContext)],
794
+ appendSystemPrompt: [processDefinitionSystemPrompt],
706
795
  ephemeral: true,
707
796
  });
708
797
  try {
@@ -718,49 +807,82 @@ async function runProcessDefinitionPhase(args) {
718
807
  }
719
808
  });
720
809
  }
721
- const result = await session.prompt(compressInternalHarnessPrompt(buildMetaPrompt(args.prompt, args.workspace ?? process.cwd()), args.compressionConfig, "agent"), 300_000);
810
+ const result = await session.prompt(initialMetaPrompt, 300_000);
722
811
  if (unsubscribe)
723
812
  unsubscribe();
724
813
  if (!args.json)
725
814
  process.stderr.write("\n");
726
815
  if (!result.success) {
816
+ writeVerboseData("phase1 agent failure output", result.output);
727
817
  throw new exceptions_1.BabysitterRuntimeError("ProcessDefinitionFailed", result.output, { category: exceptions_1.ErrorCategory.External });
728
818
  }
819
+ phaseOutputs.push(result.output);
820
+ writeVerboseData("phase1 agent output", result.output);
729
821
  if (!state.report?.processPath) {
730
822
  writeVerboseProcessDefinitionRecovery(args.json);
731
- const recovery = await session.prompt(compressInternalHarnessPrompt([
823
+ const recoveryPrompt = compressInternalHarnessPrompt([
732
824
  "Recovery step:",
733
825
  `- Write the full process file now to ${args.outputPath}`,
734
826
  "- Then call babysitter_report_process_definition exactly once.",
735
827
  "- Do not just describe the process in plain text.",
736
- ].join("\n"), args.compressionConfig, "agent"), 180_000);
828
+ ].join("\n"), args.compressionConfig, "agent");
829
+ writeVerboseData("phase1 recovery prompt", recoveryPrompt);
830
+ const recovery = await session.prompt(recoveryPrompt, 180_000);
737
831
  if (!recovery.success) {
832
+ writeVerboseData("phase1 recovery failure output", recovery.output);
738
833
  throw new exceptions_1.BabysitterRuntimeError("ProcessDefinitionFailed", recovery.output, { category: exceptions_1.ErrorCategory.External });
739
834
  }
835
+ phaseOutputs.push(recovery.output);
836
+ writeVerboseData("phase1 recovery output", recovery.output);
740
837
  }
741
838
  if (!state.report?.processPath) {
742
- try {
743
- await waitForProcessFile(args.outputPath, 5_000);
744
- state.report = {
745
- processPath: args.outputPath,
746
- summary: "Recovered from missing process-definition tool report by using the expected output path.",
747
- };
839
+ writeVerbose("[phase1 recovery] attempting host-side recovery from agent outputs");
840
+ state.report = (await recoverProcessDefinitionFromOutputs({
841
+ outputPath: args.outputPath,
842
+ workspace: args.workspace,
843
+ outputs: phaseOutputs,
844
+ })) ?? undefined;
845
+ if (state.report) {
846
+ writeVerboseData("phase1 recovered report", state.report);
748
847
  }
749
- catch {
750
- if (!args.interactive) {
751
- const fallbackSource = buildFallbackProcessDefinitionSource(args.prompt);
752
- await node_fs_1.promises.writeFile(args.outputPath, fallbackSource, "utf8");
753
- state.report = {
754
- processPath: args.outputPath,
755
- summary: "Recovered from phase-1 tool failure by writing a generic multi-step fallback process definition.",
756
- };
757
- }
758
- else {
759
- throw new exceptions_1.BabysitterRuntimeError("ProcessDefinitionReportMissing", "The process-definition agent finished without calling babysitter_report_process_definition.", { category: exceptions_1.ErrorCategory.Runtime });
760
- }
848
+ }
849
+ if (!state.report?.processPath) {
850
+ const finalRecoveryPrompt = compressInternalHarnessPrompt([
851
+ "Final recovery step:",
852
+ `- Write the complete JavaScript process file to ${args.outputPath}.`,
853
+ "- If you already wrote it, do not rewrite unnecessarily.",
854
+ "- Call babysitter_report_process_definition exactly once after the file exists.",
855
+ "- Do not answer with plain text only.",
856
+ "- If helpful, return the full JavaScript in a ```javascript fenced block, but the file must still be written and reported.",
857
+ ].join("\n"), args.compressionConfig, "agent");
858
+ writeVerboseData("phase1 final recovery prompt", finalRecoveryPrompt);
859
+ const finalRecovery = await session.prompt(finalRecoveryPrompt, 180_000);
860
+ if (!finalRecovery.success) {
861
+ writeVerboseData("phase1 final recovery failure output", finalRecovery.output);
862
+ throw new exceptions_1.BabysitterRuntimeError("ProcessDefinitionFailed", finalRecovery.output, { category: exceptions_1.ErrorCategory.External });
863
+ }
864
+ phaseOutputs.push(finalRecovery.output);
865
+ writeVerboseData("phase1 final recovery output", finalRecovery.output);
866
+ state.report = (await recoverProcessDefinitionFromOutputs({
867
+ outputPath: args.outputPath,
868
+ workspace: args.workspace,
869
+ outputs: phaseOutputs,
870
+ })) ?? undefined;
871
+ if (state.report) {
872
+ writeVerboseData("phase1 recovered report", state.report);
873
+ }
874
+ }
875
+ if (!state.report?.processPath) {
876
+ writeVerboseData("phase1 unrecoverable outputs", phaseOutputs);
877
+ if (!args.interactive) {
878
+ throw new exceptions_1.BabysitterRuntimeError("ProcessDefinitionReportMissing", "The process-definition agent finished without calling babysitter_report_process_definition, and no recoverable process file or code output was produced.", { category: exceptions_1.ErrorCategory.Runtime });
879
+ }
880
+ else {
881
+ throw new exceptions_1.BabysitterRuntimeError("ProcessDefinitionReportMissing", "The process-definition agent finished without calling babysitter_report_process_definition, and no recoverable process file or code output was produced.", { category: exceptions_1.ErrorCategory.Runtime });
761
882
  }
762
883
  }
763
884
  await waitForProcessFile(state.report.processPath);
885
+ writeVerbose(`[phase1 validate] validating process export from ${path.resolve(state.report.processPath)}`);
764
886
  await validateProcessExport(state.report.processPath);
765
887
  emitProgress({
766
888
  phase: "1",
@@ -771,6 +893,13 @@ async function runProcessDefinitionPhase(args) {
771
893
  return state.report.processPath;
772
894
  }
773
895
  catch (error) {
896
+ writeVerboseData("phase1 error", error instanceof Error
897
+ ? {
898
+ name: error.name,
899
+ message: error.message,
900
+ stack: error.stack,
901
+ }
902
+ : error);
774
903
  emitProgress({
775
904
  phase: "1",
776
905
  status: "failed",
@@ -792,9 +921,10 @@ async function runOrchestrationPhase(args) {
792
921
  };
793
922
  let orchestrationSession = null;
794
923
  const writeVerbose = (message) => {
795
- if (!args.json && args.verbose) {
796
- process.stderr.write(`${DIM}${message}${RESET}\n`);
797
- }
924
+ writeVerboseLine(args.verbose, args.json, message);
925
+ };
926
+ const writeVerboseData = (label, value, maxChars) => {
927
+ writeVerboseBlock(args.verbose, args.json, label, value, maxChars);
798
928
  };
799
929
  const summarizeAgentText = (text) => {
800
930
  const normalized = text.replace(/\s+/g, " ").trim();
@@ -826,8 +956,10 @@ async function runOrchestrationPhase(args) {
826
956
  promptSnippet: "Use this for breakpoint approvals and required user clarification.",
827
957
  parameters: ASK_USER_QUESTION_SCHEMA,
828
958
  execute: async (_toolCallId, params) => {
959
+ writeVerboseData("phase2 tool AskUserQuestion request", params);
829
960
  const response = await askUserQuestionViaTool(params, args.interactive, args.rl);
830
961
  state.lastAskUserQuestionResponse = response;
962
+ writeVerboseData("phase2 tool AskUserQuestion response", response);
831
963
  return formatToolResult(response, "AskUserQuestion completed.");
832
964
  },
833
965
  },
@@ -839,7 +971,9 @@ async function runOrchestrationPhase(args) {
839
971
  prompt: typebox_1.Type.Optional(typebox_1.Type.String()),
840
972
  }),
841
973
  execute: async (_toolCallId, params) => {
974
+ writeVerboseData("phase2 tool babysitter_run_create request", params);
842
975
  if (state.runId && state.runDir) {
976
+ writeVerboseData("phase2 tool babysitter_run_create result", { runId: state.runId, runDir: state.runDir });
843
977
  return formatToolResult({ runId: state.runId, runDir: state.runDir }, "Run already exists.");
844
978
  }
845
979
  const result = await (0, createRun_1.createRun)({
@@ -861,6 +995,7 @@ async function runOrchestrationPhase(args) {
861
995
  runId: result.runId,
862
996
  runDir: result.runDir,
863
997
  }, args.json, args.verbose);
998
+ writeVerboseData("phase2 tool babysitter_run_create result", result);
864
999
  return formatToolResult(result, "Run created.");
865
1000
  },
866
1001
  },
@@ -870,6 +1005,7 @@ async function runOrchestrationPhase(args) {
870
1005
  description: "Bind the orchestration run to the current harness session.",
871
1006
  parameters: typebox_1.Type.Object({}),
872
1007
  execute: async () => {
1008
+ writeVerbose("[phase2 tool babysitter_bind_session request]");
873
1009
  if (!state.runId || !state.runDir) {
874
1010
  throw new exceptions_1.BabysitterRuntimeError("RunNotCreated", "Create the run before binding the orchestration session.", { category: exceptions_1.ErrorCategory.Validation });
875
1011
  }
@@ -913,6 +1049,7 @@ async function runOrchestrationPhase(args) {
913
1049
  sessionId: state.sessionBound.sessionId,
914
1050
  error: state.sessionBound.error,
915
1051
  }, args.json, args.verbose);
1052
+ writeVerboseData("phase2 tool babysitter_bind_session result", state.sessionBound);
916
1053
  return formatToolResult(state.sessionBound, "Session bound.");
917
1054
  },
918
1055
  },
@@ -922,6 +1059,7 @@ async function runOrchestrationPhase(args) {
922
1059
  description: "Run the next orchestration iteration and return pending effects or a terminal result.",
923
1060
  parameters: typebox_1.Type.Object({}),
924
1061
  execute: async () => {
1062
+ writeVerbose(`[phase2 tool babysitter_run_iterate request] runDir=${state.runDir ?? "(missing)"} nextIteration=${state.iteration + 1}`);
925
1063
  if (!state.runDir) {
926
1064
  throw new exceptions_1.BabysitterRuntimeError("RunNotCreated", "Create the run before iterating it.", { category: exceptions_1.ErrorCategory.Validation });
927
1065
  }
@@ -944,6 +1082,13 @@ async function runOrchestrationPhase(args) {
944
1082
  state.pendingEffectResults.clear();
945
1083
  const result = await (0, orchestrateIteration_1.orchestrateIteration)({ runDir: state.runDir });
946
1084
  state.lastIterationResult = result;
1085
+ writeVerboseData("phase2 tool babysitter_run_iterate result", {
1086
+ iteration: state.iteration,
1087
+ status: result.status,
1088
+ nextActions: result.status === "waiting" ? result.nextActions : undefined,
1089
+ output: result.status === "completed" ? result.output : undefined,
1090
+ error: result.status === "failed" ? result.error : undefined,
1091
+ });
947
1092
  if (result.status === "waiting") {
948
1093
  for (const action of result.nextActions) {
949
1094
  state.pendingActions.set(action.effectId, action);
@@ -994,6 +1139,7 @@ async function runOrchestrationPhase(args) {
994
1139
  effectId: typebox_1.Type.String(),
995
1140
  }),
996
1141
  execute: async (_toolCallId, params) => {
1142
+ writeVerboseData("phase2 tool babysitter_execute_effect request", params);
997
1143
  const action = state.pendingActions.get(params.effectId);
998
1144
  if (!action) {
999
1145
  throw new exceptions_1.BabysitterRuntimeError("PendingEffectNotFound", `No pending effect found for ${params.effectId}.`, { category: exceptions_1.ErrorCategory.Validation });
@@ -1006,6 +1152,14 @@ async function runOrchestrationPhase(args) {
1006
1152
  }, "Breakpoint effects require explicit AskUserQuestion handling.");
1007
1153
  }
1008
1154
  const taskHarness = resolveTaskHarness(action, args.selectedHarnessName, args.discovered);
1155
+ writeVerboseData("phase2 effect execution plan", {
1156
+ effectId: params.effectId,
1157
+ kind: action.kind,
1158
+ title: action.taskDef?.title,
1159
+ resolvedHarness: taskHarness,
1160
+ selectedHarness: args.selectedHarnessName,
1161
+ metadata: action.taskDef?.metadata ?? undefined,
1162
+ });
1009
1163
  let workerSession = null;
1010
1164
  if (action.kind === "shell" || isPiHarness(taskHarness)) {
1011
1165
  workerSession = (0, piWrapper_1.createPiSession)(buildPiWorkerSessionOptions({
@@ -1013,6 +1167,11 @@ async function runOrchestrationPhase(args) {
1013
1167
  workspace: args.workspace,
1014
1168
  model: args.model,
1015
1169
  }));
1170
+ writeVerboseData("phase2 worker session options", buildPiWorkerSessionOptions({
1171
+ action,
1172
+ workspace: args.workspace,
1173
+ model: args.model,
1174
+ }));
1016
1175
  }
1017
1176
  try {
1018
1177
  const effectResult = await resolveEffect(action, args.selectedHarnessName, {
@@ -1022,6 +1181,10 @@ async function runOrchestrationPhase(args) {
1022
1181
  compressionConfig: args.compressionConfig,
1023
1182
  }, workerSession, args.discovered, null, args.json);
1024
1183
  state.pendingEffectResults.set(params.effectId, effectResult);
1184
+ writeVerboseData("phase2 tool babysitter_execute_effect result", {
1185
+ effectId: params.effectId,
1186
+ effectResult,
1187
+ });
1025
1188
  return formatToolResult({ effectId: params.effectId, effectResult }, "Effect executed and staged for task posting.");
1026
1189
  }
1027
1190
  finally {
@@ -1037,6 +1200,7 @@ async function runOrchestrationPhase(args) {
1037
1200
  effectId: typebox_1.Type.String(),
1038
1201
  }),
1039
1202
  execute: async (_toolCallId, params) => {
1203
+ writeVerboseData("phase2 tool babysitter_task_post_result request", params);
1040
1204
  if (!state.runDir) {
1041
1205
  throw new exceptions_1.BabysitterRuntimeError("RunNotCreated", "Create the run before posting task results.", { category: exceptions_1.ErrorCategory.Validation });
1042
1206
  }
@@ -1080,6 +1244,14 @@ async function runOrchestrationPhase(args) {
1080
1244
  finishedAt,
1081
1245
  },
1082
1246
  });
1247
+ writeVerboseData("phase2 tool babysitter_task_post_result result", {
1248
+ effectId: params.effectId,
1249
+ status: effectResult.status,
1250
+ startedAt,
1251
+ finishedAt,
1252
+ valuePreview: effectResult.value,
1253
+ error: effectResult.error,
1254
+ });
1083
1255
  emitProgress({
1084
1256
  phase: "2",
1085
1257
  status: "effect",
@@ -1115,6 +1287,7 @@ async function runOrchestrationPhase(args) {
1115
1287
  summary: typebox_1.Type.Optional(typebox_1.Type.String()),
1116
1288
  }),
1117
1289
  execute: (_toolCallId, params) => {
1290
+ writeVerboseData("phase2 tool babysitter_finish_orchestration", params);
1118
1291
  state.finished = { summary: params.summary };
1119
1292
  return formatToolResult(state.finished, "Orchestration finish recorded.");
1120
1293
  },
@@ -1132,8 +1305,11 @@ async function runOrchestrationPhase(args) {
1132
1305
  if (!tool?.execute) {
1133
1306
  throw new exceptions_1.BabysitterRuntimeError("MissingSessionCreateTool", `Required orchestration tool is unavailable: ${name}`, { category: exceptions_1.ErrorCategory.Internal });
1134
1307
  }
1308
+ writeVerboseData(`phase2 host invoke ${name} request`, params);
1135
1309
  const result = tool.execute(`host-${name}`, params);
1136
- return await Promise.resolve(result);
1310
+ const resolved = await Promise.resolve(result);
1311
+ writeVerboseData(`phase2 host invoke ${name} result`, resolved);
1312
+ return resolved;
1137
1313
  };
1138
1314
  const runDeterministicPendingEffects = async (reason) => {
1139
1315
  const pending = describePendingActions();
@@ -1161,8 +1337,10 @@ async function runOrchestrationPhase(args) {
1161
1337
  const label = options?.label ?? "phase2";
1162
1338
  process.stderr.write(`\n${DIM}[${label}] agent turn${RESET}\n`);
1163
1339
  }
1340
+ writeVerboseData(`${options?.label ?? "phase2"} prompt`, message);
1164
1341
  const result = await orchestrationSession.prompt(compressInternalHarnessPrompt(message, args.compressionConfig, "agent"), 900_000);
1165
1342
  if (!result.success) {
1343
+ writeVerboseData(`${options?.label ?? "phase2"} agent failure output`, result.output);
1166
1344
  throw new exceptions_1.BabysitterRuntimeError("OrchestrationAgentFailed", result.output, { category: exceptions_1.ErrorCategory.External });
1167
1345
  }
1168
1346
  writeVerbose(`[phase2 agent] ${summarizeAgentText(result.output)}`);
@@ -1178,6 +1356,12 @@ async function runOrchestrationPhase(args) {
1178
1356
  appendSystemPrompt: [(0, sessionCreatePrompts_1.buildOrchestrationSystemPrompt)(args.selectedHarnessName, args.promptContext)],
1179
1357
  ephemeral: true,
1180
1358
  });
1359
+ writeVerbose(`[phase2 setup] harness=${args.selectedHarnessName} workspace=${path.resolve(args.workspace ?? process.cwd())} model=${args.model ?? "(default)"} processPath=${path.resolve(args.processPath)}`);
1360
+ writeVerboseData("phase2 tools", customTools.map((tool) => ({
1361
+ name: tool.name,
1362
+ label: tool.label,
1363
+ })));
1364
+ writeVerboseData("phase2 system prompt", (0, sessionCreatePrompts_1.buildOrchestrationSystemPrompt)(args.selectedHarnessName, args.promptContext));
1181
1365
  emitProgress({ phase: "2", status: "started", harness: args.selectedHarnessName }, args.json, args.verbose);
1182
1366
  let unsubscribe = null;
1183
1367
  try {
@@ -1266,6 +1450,18 @@ async function runOrchestrationPhase(args) {
1266
1450
  throw new exceptions_1.BabysitterRuntimeError("OrchestrationIncomplete", "The orchestration phase ended without a terminal run state.", { category: exceptions_1.ErrorCategory.Runtime });
1267
1451
  }
1268
1452
  catch (error) {
1453
+ writeVerboseData("phase2 error", error instanceof Error
1454
+ ? {
1455
+ name: error.name,
1456
+ message: error.message,
1457
+ stack: error.stack,
1458
+ runId: state.runId,
1459
+ runDir: state.runDir,
1460
+ iteration: state.iteration,
1461
+ pendingEffects: describePendingActions(),
1462
+ lastIterationResult: state.lastIterationResult,
1463
+ }
1464
+ : error);
1269
1465
  emitProgress({
1270
1466
  phase: "2",
1271
1467
  status: "failed",
@@ -84,8 +84,7 @@ export interface ProcessDiscoveryResult {
84
84
  * @skill <name> <relative-path-to-SKILL.md>
85
85
  * @agent <name> <relative-path-to-AGENT.md>
86
86
  *
87
- * Paths are relative to the plugin's process root:
88
- * pluginRoot/skills/babysit/process/
87
+ * Paths are relative to the active process-library root.
89
88
  */
90
89
  export declare function parseProcessFileMarkers(filePath: string): ProcessMarkersResult;
91
90
  /**
@@ -95,7 +94,8 @@ export declare function parseProcessFileMarkers(filePath: string): ProcessMarker
95
94
  */
96
95
  export declare function discoverFromProcessFile(options: {
97
96
  processFilePath: string;
98
- pluginRoot: string;
97
+ pluginRoot?: string;
98
+ processRoot?: string;
99
99
  }): ProcessDiscoveryResult | null;
100
100
  /**
101
101
  * Result from internal discovery.
@@ -1 +1 @@
1
- {"version":3,"file":"skill.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/skill.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"skill.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/skill.ts"],"names":[],"mappings":"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"}
@@ -45,6 +45,7 @@ exports.handleSkillFetchRemote = handleSkillFetchRemote;
45
45
  const node_fs_1 = require("node:fs");
46
46
  const path = __importStar(require("node:path"));
47
47
  const os = __importStar(require("node:os"));
48
+ const active_1 = require("../../processLibrary/active");
48
49
  const DEFAULT_CACHE_TTL = 300; // 5 minutes
49
50
  const CACHE_DIR = path.join(os.tmpdir(), 'babysitter-skill-cache');
50
51
  // ---------------------------------------------------------------------------
@@ -424,8 +425,7 @@ function capPerSpecialization(items, cap) {
424
425
  * @skill <name> <relative-path-to-SKILL.md>
425
426
  * @agent <name> <relative-path-to-AGENT.md>
426
427
  *
427
- * Paths are relative to the plugin's process root:
428
- * pluginRoot/skills/babysit/process/
428
+ * Paths are relative to the active process-library root.
429
429
  */
430
430
  function parseProcessFileMarkers(filePath) {
431
431
  let content;
@@ -471,13 +471,12 @@ function parseProcessFileMarkers(filePath) {
471
471
  };
472
472
  }
473
473
  /**
474
- * Resolve parsed markers to full file paths using the plugin process root.
475
- *
476
- * processRoot = pluginRoot/skills/babysit/process/
477
- * Each marker's relativePath is resolved against processRoot.
474
+ * Resolve parsed markers to full file paths using the active process-library
475
+ * root when known, or the legacy plugin-local process root as a compatibility
476
+ * fallback.
478
477
  */
479
- function resolveMarkersToMetadata(markers, pluginRoot) {
480
- const processRoot = path.join(pluginRoot, 'skills', 'babysit', 'process');
478
+ function resolveMarkersToMetadata(markers, options) {
479
+ const processRoot = resolveStaticProcessRoot(options);
481
480
  const resolveMarker = (marker) => {
482
481
  if (!marker.relativePath) {
483
482
  return { name: marker.name };
@@ -500,7 +499,55 @@ function discoverFromProcessFile(options) {
500
499
  if (!markers.hasMarkers) {
501
500
  return null;
502
501
  }
503
- return resolveMarkersToMetadata(markers, options.pluginRoot);
502
+ return resolveMarkersToMetadata(markers, {
503
+ pluginRoot: options.pluginRoot,
504
+ processRoot: options.processRoot,
505
+ });
506
+ }
507
+ function resolveLegacyPluginProcessRoot(pluginRoot) {
508
+ return path.join(pluginRoot, 'skills', 'babysit', 'process');
509
+ }
510
+ function findRepoLibraryRoot(start) {
511
+ for (let current = path.resolve(start); current;) {
512
+ const candidate = path.join(current, 'library');
513
+ if ((0, node_fs_1.existsSync)(candidate)) {
514
+ return candidate;
515
+ }
516
+ const parent = path.dirname(current);
517
+ if (parent === current) {
518
+ break;
519
+ }
520
+ current = parent;
521
+ }
522
+ return null;
523
+ }
524
+ function resolveStaticProcessRoot(options) {
525
+ if (options.processRoot) {
526
+ return path.resolve(options.processRoot);
527
+ }
528
+ if (options.pluginRoot) {
529
+ const repoLibraryRoot = findRepoLibraryRoot(options.pluginRoot);
530
+ if (repoLibraryRoot) {
531
+ return repoLibraryRoot;
532
+ }
533
+ return resolveLegacyPluginProcessRoot(options.pluginRoot);
534
+ }
535
+ return path.resolve(process.cwd(), 'library');
536
+ }
537
+ async function resolveDiscoveryProcessRoot(options) {
538
+ try {
539
+ const active = await (0, active_1.resolveActiveProcessLibrary)({
540
+ stateDir: path.resolve(process.cwd(), '.a5c'),
541
+ runId: options.runId,
542
+ });
543
+ if (active.binding?.dir) {
544
+ return path.resolve(active.binding.dir);
545
+ }
546
+ }
547
+ catch {
548
+ // Fall back to repo-local/library or legacy plugin-local roots.
549
+ }
550
+ return resolveStaticProcessRoot({ pluginRoot: options.pluginRoot });
504
551
  }
505
552
  /**
506
553
  * Internal discovery logic, extracted for reuse by other CLI commands
@@ -525,7 +572,11 @@ async function discoverSkillsInternal(options) {
525
572
  if (!domain) {
526
573
  domain = await detectRunDomain(runId, runsDir);
527
574
  }
528
- const specializationsDir = path.join(pluginRoot, 'skills', 'babysit', 'process', 'specializations');
575
+ const processRoot = await resolveDiscoveryProcessRoot({
576
+ pluginRoot,
577
+ runId,
578
+ });
579
+ const specializationsDir = path.join(processRoot, 'specializations');
529
580
  // ------------------------------------------------------------------
530
581
  // Skills
531
582
  // ------------------------------------------------------------------
@@ -536,7 +587,7 @@ async function discoverSkillsInternal(options) {
536
587
  // 2. Scan plugin-level skills
537
588
  const pluginSkillsDir = path.join(pluginRoot, 'skills');
538
589
  const pluginSkills = await scanSkillsDirectory(pluginSkillsDir, 'local-plugin');
539
- const filteredPluginSkills = pluginSkills.filter(s => !s.file?.includes('/specializations/'));
590
+ const filteredPluginSkills = pluginSkills.filter(s => !(s.file?.replace(/\\/g, '/').includes('/specializations/')));
540
591
  allSkills.push(...filteredPluginSkills);
541
592
  // 3. Scan repo-level skills (.a5c/skills)
542
593
  const repoSkillsDir = '.a5c/skills';
@@ -591,7 +642,7 @@ async function discoverSkillsInternal(options) {
591
642
  // Specializations dir may not exist
592
643
  }
593
644
  // 2. Methodology processes
594
- const methodologiesDir = path.join(pluginRoot, 'skills', 'babysit', 'process', 'methodologies');
645
+ const methodologiesDir = path.join(processRoot, 'methodologies');
595
646
  try {
596
647
  // Top-level methodology files
597
648
  const topProcs = await scanProcessesDirectory(methodologiesDir, 'methodologies', 'library');
@@ -1 +1 @@
1
- {"version":3,"file":"codex.d.ts","sourceRoot":"","sources":["../../src/harness/codex.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAaH,OAAO,KAAK,EACV,cAAc,EAMf,MAAM,SAAS,CAAC;AAoYjB,wBAAgB,kBAAkB,IAAI,cAAc,CAyHnD"}
1
+ {"version":3,"file":"codex.d.ts","sourceRoot":"","sources":["../../src/harness/codex.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAaH,OAAO,KAAK,EACV,cAAc,EAMf,MAAM,SAAS,CAAC;AA+XjB,wBAAgB,kBAAkB,IAAI,cAAc,CAmGnD"}
@@ -86,11 +86,6 @@ function resolveCodexSessionId(parsed) {
86
86
  return undefined;
87
87
  }
88
88
  }
89
- function supportsCodexLifecycleHooks() {
90
- if (process.env.BABYSITTER_CODEX_FORCE_HOOKS === "1")
91
- return true;
92
- return process.platform !== "win32";
93
- }
94
89
  function readStdin() {
95
90
  return new Promise((resolve, reject) => {
96
91
  let data = "";
@@ -354,9 +349,6 @@ async function installCodexPlugin(options) {
354
349
  }
355
350
  function createCodexAdapter() {
356
351
  const claude = (0, claudeCode_1.createClaudeCodeAdapter)();
357
- const unsupportedHookMessage = (hookType) => (`Codex lifecycle hook "${hookType}" is unavailable on this platform. ` +
358
- `Use a hook-capable Codex install on Linux, macOS, or WSL for the ` +
359
- `babysitter-codex plugin hook model.`);
360
352
  return {
361
353
  name: "codex",
362
354
  isActive() {
@@ -382,14 +374,9 @@ function createCodexAdapter() {
382
374
  "that provides a stable session/thread ID.");
383
375
  },
384
376
  supportsHookType(hookType) {
385
- if (hookType === "stop" || hookType === "session-start") {
386
- return supportsCodexLifecycleHooks();
387
- }
377
+ void hookType;
388
378
  return true;
389
379
  },
390
- getUnsupportedHookMessage(hookType) {
391
- return unsupportedHookMessage(hookType);
392
- },
393
380
  async bindSession(opts) {
394
381
  const stateDir = resolveCodexStateDir({
395
382
  stateDir: opts.stateDir,
@@ -405,10 +392,6 @@ function createCodexAdapter() {
405
392
  };
406
393
  },
407
394
  async handleStopHook(args) {
408
- if (!supportsCodexLifecycleHooks()) {
409
- process.stderr.write(`${unsupportedHookMessage("stop")}\n`);
410
- return 1;
411
- }
412
395
  let rawInput = "";
413
396
  try {
414
397
  rawInput = await readStdin();
@@ -427,10 +410,6 @@ function createCodexAdapter() {
427
410
  }));
428
411
  },
429
412
  handleSessionStartHook(args) {
430
- if (!supportsCodexLifecycleHooks()) {
431
- process.stderr.write(`${unsupportedHookMessage("session-start")}\n`);
432
- return Promise.resolve(1);
433
- }
434
413
  return handleCodexSessionStartHookImpl(args);
435
414
  },
436
415
  findHookDispatcherPath(_startCwd) {
@@ -87,7 +87,7 @@ async function installPiFamilyPlugin(args) {
87
87
  if (!repoRoot) {
88
88
  throw new exceptions_1.BabysitterRuntimeError("RepoRootNotFound", "Could not resolve the babysitter repo root for the repo-local pi plugin install.", { category: exceptions_1.ErrorCategory.Configuration });
89
89
  }
90
- const pluginDir = path.join(repoRoot, "plugins", "pi");
90
+ const pluginDir = path.join(repoRoot, "plugins", "babysitter-pi");
91
91
  const command = "omp";
92
92
  const commandArgs = ["plugin", "link", pluginDir];
93
93
  if (args.options.dryRun) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@a5c-ai/babysitter-sdk",
3
- "version": "0.0.183-staging.d5ce2137",
3
+ "version": "0.0.183-staging.dfcd1fad",
4
4
  "description": "Storage and run-registry primitives for event-sourced babysitter workflows.",
5
5
  "license": "UNLICENSED",
6
6
  "type": "commonjs",