@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.
- package/dist/cli/commands/sessionCreate.d.ts.map +1 -1
- package/dist/cli/commands/sessionCreate.js +278 -82
- package/dist/cli/commands/skill.d.ts +3 -3
- package/dist/cli/commands/skill.d.ts.map +1 -1
- package/dist/cli/commands/skill.js +63 -12
- package/dist/harness/codex.d.ts.map +1 -1
- package/dist/harness/codex.js +1 -22
- package/dist/harness/pi.js +1 -1
- package/package.json +1 -1
|
@@ -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;
|
|
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
|
|
170
|
-
const
|
|
171
|
-
|
|
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
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
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
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
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: [
|
|
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(
|
|
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
|
|
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")
|
|
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
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
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
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
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
|
-
|
|
796
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
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":"AAAA;;;GAGG;
|
|
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
|
|
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
|
|
475
|
-
*
|
|
476
|
-
*
|
|
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,
|
|
480
|
-
const processRoot =
|
|
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,
|
|
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
|
|
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(
|
|
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;
|
|
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"}
|
package/dist/harness/codex.js
CHANGED
|
@@ -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
|
-
|
|
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) {
|
package/dist/harness/pi.js
CHANGED
|
@@ -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