@a5c-ai/babysitter-sdk 0.0.184 → 0.0.185

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/dist/cli/commands/instructions.d.ts.map +1 -1
  2. package/dist/cli/commands/instructions.js +41 -0
  3. package/dist/cli/main.js +2 -2
  4. package/dist/config/defaults.d.ts +11 -0
  5. package/dist/config/defaults.d.ts.map +1 -1
  6. package/dist/config/defaults.js +55 -0
  7. package/dist/config/index.d.ts +1 -1
  8. package/dist/config/index.d.ts.map +1 -1
  9. package/dist/config/index.js +2 -1
  10. package/dist/harness/claudeCode.d.ts +2 -2
  11. package/dist/harness/claudeCode.d.ts.map +1 -1
  12. package/dist/harness/claudeCode.js +47 -72
  13. package/dist/harness/codex.d.ts.map +1 -1
  14. package/dist/harness/codex.js +10 -49
  15. package/dist/harness/cursor.d.ts.map +1 -1
  16. package/dist/harness/cursor.js +23 -34
  17. package/dist/harness/customAdapter.d.ts.map +1 -1
  18. package/dist/harness/customAdapter.js +8 -3
  19. package/dist/harness/discovery.js +7 -7
  20. package/dist/harness/geminiCli.d.ts.map +1 -1
  21. package/dist/harness/geminiCli.js +20 -27
  22. package/dist/harness/githubCopilot.d.ts.map +1 -1
  23. package/dist/harness/githubCopilot.js +17 -40
  24. package/dist/harness/index.d.ts +1 -0
  25. package/dist/harness/index.d.ts.map +1 -1
  26. package/dist/harness/index.js +3 -1
  27. package/dist/harness/installSupport.d.ts +1 -0
  28. package/dist/harness/installSupport.d.ts.map +1 -1
  29. package/dist/harness/installSupport.js +7 -3
  30. package/dist/harness/invoker.js +1 -1
  31. package/dist/harness/ohMyPi.d.ts +0 -14
  32. package/dist/harness/ohMyPi.d.ts.map +1 -1
  33. package/dist/harness/ohMyPi.js +163 -24
  34. package/dist/harness/opencode.d.ts +28 -0
  35. package/dist/harness/opencode.d.ts.map +1 -0
  36. package/dist/harness/opencode.js +578 -0
  37. package/dist/harness/pi.d.ts +1 -11
  38. package/dist/harness/pi.d.ts.map +1 -1
  39. package/dist/harness/pi.js +81 -105
  40. package/dist/harness/registry.d.ts.map +1 -1
  41. package/dist/harness/registry.js +2 -0
  42. package/dist/prompts/context.d.ts +9 -0
  43. package/dist/prompts/context.d.ts.map +1 -1
  44. package/dist/prompts/context.js +128 -20
  45. package/dist/prompts/index.d.ts +1 -1
  46. package/dist/prompts/index.d.ts.map +1 -1
  47. package/dist/prompts/index.js +2 -1
  48. package/dist/prompts/templates/completion-proof.md +8 -0
  49. package/dist/prompts/templates/critical-rules.md +5 -5
  50. package/dist/prompts/types.d.ts +4 -5
  51. package/dist/prompts/types.d.ts.map +1 -1
  52. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"instructions.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/instructions.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAkBH,MAAM,WAAW,uBAAuB;IACtC,UAAU,EAAE,eAAe,GAAG,gBAAgB,GAAG,aAAa,GAAG,qBAAqB,CAAC;IACvF,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,OAAO,GAAG,SAAS,CAAC;IACjC,IAAI,EAAE,OAAO,CAAC;CACf;AA4GD;;GAEG;AACH,wBAAsB,yBAAyB,CAC7C,IAAI,EAAE,uBAAuB,GAC5B,OAAO,CAAC,MAAM,CAAC,CAiEjB"}
1
+ {"version":3,"file":"instructions.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/instructions.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAoBH,MAAM,WAAW,uBAAuB;IACtC,UAAU,EAAE,eAAe,GAAG,gBAAgB,GAAG,aAAa,GAAG,qBAAqB,CAAC;IACvF,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,OAAO,GAAG,SAAS,CAAC;IACjC,IAAI,EAAE,OAAO,CAAC;CACf;AAmID;;GAEG;AACH,wBAAsB,yBAAyB,CAC7C,IAAI,EAAE,uBAAuB,GAC5B,OAAO,CAAC,MAAM,CAAC,CAmFjB"}
@@ -9,9 +9,11 @@
9
9
  */
10
10
  Object.defineProperty(exports, "__esModule", { value: true });
11
11
  exports.handleInstructionsCommand = handleInstructionsCommand;
12
+ const node_fs_1 = require("node:fs");
12
13
  const prompts_1 = require("../../prompts");
13
14
  const active_1 = require("../../processLibrary/active");
14
15
  const registry_1 = require("../../harness/registry");
16
+ const parse_1 = require("../../session/parse");
15
17
  /**
16
18
  * Legacy fallback map — used only when an adapter does not implement
17
19
  * `getPromptContext()`. New harnesses should add the method to their
@@ -103,6 +105,28 @@ async function tryResolveProcessLibraryRoot() {
103
105
  }
104
106
  return {};
105
107
  }
108
+ /**
109
+ * Detect whether the session-start hook has actually run by checking for the
110
+ * session state file it creates (`<stateDir>/<sessionId>.md`).
111
+ *
112
+ * Some adapters can resolve a session ID from env vars alone (e.g.
113
+ * GEMINI_SESSION_ID, CODEX_SESSION_ID) without the hook ever firing.
114
+ * The definitive signal is the state file — the hook writes it as a
115
+ * side effect of `babysitter hook:run --hook-type session-start`.
116
+ */
117
+ function detectHooksActive(harness) {
118
+ const adapter = (0, registry_1.getAdapterByName)(harness);
119
+ if (!adapter)
120
+ return false;
121
+ const sessionId = adapter.resolveSessionId({});
122
+ if (!sessionId)
123
+ return false;
124
+ const stateDir = adapter.resolveStateDir({});
125
+ if (!stateDir)
126
+ return false;
127
+ const stateFile = (0, parse_1.getSessionFilePath)(stateDir, sessionId);
128
+ return (0, node_fs_1.existsSync)(stateFile);
129
+ }
106
130
  /**
107
131
  * Route and handle an `instructions:*` subcommand.
108
132
  */
@@ -137,9 +161,18 @@ async function handleInstructionsCommand(args) {
137
161
  }
138
162
  // Resolve the active process-library root before composing the prompt
139
163
  const libraryInfo = await tryResolveProcessLibraryRoot();
164
+ // Detect whether hooks are actually active in this session.
165
+ // If the session-start hook never ran (no breadcrumb file), override
166
+ // hookDriven to false so the agent drives the loop in-turn.
167
+ const hooksActive = detectHooksActive(args.harness);
168
+ const hookOverride = {};
169
+ if (!hooksActive) {
170
+ hookOverride.hookDriven = false;
171
+ }
140
172
  const ctx = factory({
141
173
  interactive: args.interactive,
142
174
  ...libraryInfo,
175
+ ...hookOverride,
143
176
  });
144
177
  const content = composer.fn(ctx);
145
178
  if (args.json) {
@@ -147,11 +180,19 @@ async function handleInstructionsCommand(args) {
147
180
  harness: args.harness,
148
181
  interactive: args.interactive,
149
182
  promptType: composer.promptType,
183
+ hookDriven: ctx.hookDriven,
184
+ hooksDetected: hooksActive,
150
185
  content,
151
186
  partsIncluded: composer.partsIncluded,
152
187
  }, null, 2));
153
188
  }
154
189
  else {
190
+ if (!hooksActive && ctx.hookDriven !== false) {
191
+ // Context factory defaulted hookDriven to true, but we overrode it.
192
+ // This is a no-op because the override already happened, but it
193
+ // clarifies the JSON output. The text output is self-explanatory
194
+ // from the generated instructions.
195
+ }
155
196
  console.log(content);
156
197
  }
157
198
  return 0;
package/dist/cli/main.js CHANGED
@@ -334,7 +334,7 @@ function parseArgs(argv) {
334
334
  // Session command flags
335
335
  if (arg === "--session-id") {
336
336
  // Tolerate empty/missing value — the harness adapter can auto-detect
337
- // session ID from CLAUDE_ENV_FILE or CLAUDE_SESSION_ID env var.
337
+ // session ID from BABYSITTER_SESSION_ID env var or CLAUDE_ENV_FILE.
338
338
  const next = rest[i + 1];
339
339
  if (next && !next.startsWith("-")) {
340
340
  parsed.sessionId = next;
@@ -1071,7 +1071,7 @@ async function handleRunCreate(parsed) {
1071
1071
  harness: parsed.harness ?? adapter.name,
1072
1072
  sessionId: "",
1073
1073
  error: (adapter.getMissingSessionIdHint?.() ??
1074
- "No session ID provided. Use --session-id or set CLAUDE_SESSION_ID."),
1074
+ "No session ID provided. Use --session-id or set BABYSITTER_SESSION_ID."),
1075
1075
  };
1076
1076
  }
1077
1077
  }
@@ -111,6 +111,17 @@ export declare const CONFIG_ENV_VARS: {
111
111
  * They can be overridden via environment variables or explicit config.
112
112
  */
113
113
  export declare const DEFAULTS: Readonly<BabysitterConfig>;
114
+ /**
115
+ * Returns the global babysitter state directory (~/.a5c/state/).
116
+ *
117
+ * All harness adapters use this as the canonical default location for session
118
+ * state files. The directory is user-global (not workspace-relative or
119
+ * plugin-root-relative) so session state is discoverable regardless of the
120
+ * execution context (hook subprocess, Bash tool, CLI invocation, etc.).
121
+ *
122
+ * Override: set BABYSITTER_STATE_DIR to use a different path.
123
+ */
124
+ export declare function getGlobalStateDir(): string;
114
125
  /**
115
126
  * Retrieves configuration with environment variable overrides merged in.
116
127
  *
@@ -1 +1 @@
1
- {"version":3,"file":"defaults.d.ts","sourceRoot":"","sources":["../../src/config/defaults.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;GAEG;AACH,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAC;AAEtE;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;;OAGG;IACH,OAAO,EAAE,MAAM,CAAC;IAEhB;;;OAGG;IACH,aAAa,EAAE,MAAM,CAAC;IAEtB;;;OAGG;IACH,gBAAgB,EAAE,MAAM,CAAC;IAEzB;;;OAGG;IACH,OAAO,EAAE,MAAM,CAAC;IAEhB;;;OAGG;IACH,QAAQ,EAAE,QAAQ,CAAC;IAEnB;;;OAGG;IACH,eAAe,EAAE,OAAO,CAAC;IAEzB;;;OAGG;IACH,WAAW,EAAE,MAAM,CAAC;IAEpB;;;OAGG;IACH,eAAe,EAAE,MAAM,CAAC;IAExB;;;OAGG;IACH,WAAW,EAAE,MAAM,CAAC;IAEpB;;;OAGG;IACH,YAAY,EAAE,MAAM,CAAC;IAErB;;;OAGG;IACH,aAAa,EAAE,MAAM,CAAC;IAEtB;;;OAGG;IACH,uBAAuB,EAAE,MAAM,CAAC;CACjC;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC;;OAEG;IACH,KAAK,EAAE,OAAO,CAAC;IAEf;;OAEG;IACH,MAAM,EAAE,MAAM,EAAE,CAAC;IAEjB;;OAEG;IACH,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED;;GAEG;AACH,eAAO,MAAM,eAAe;;;;;;;;;CASlB,CAAC;AAEX;;;;;GAKG;AACH,eAAO,MAAM,QAAQ,EAAE,QAAQ,CAAC,gBAAgB,CAwEtC,CAAC;AAiDX;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,SAAS,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC,gBAAgB,CAAC,GAAG,gBAAgB,CAqCjF;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,gBAAgB,GAAG,sBAAsB,CA2E/E;AAED;;;;GAIG;AACH,wBAAgB,WAAW,IAAI,QAAQ,CAAC,gBAAgB,CAAC,CAExD;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,QAAQ,CAEjE"}
1
+ {"version":3,"file":"defaults.d.ts","sourceRoot":"","sources":["../../src/config/defaults.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH;;GAEG;AACH,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAC;AAEtE;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;;OAGG;IACH,OAAO,EAAE,MAAM,CAAC;IAEhB;;;OAGG;IACH,aAAa,EAAE,MAAM,CAAC;IAEtB;;;OAGG;IACH,gBAAgB,EAAE,MAAM,CAAC;IAEzB;;;OAGG;IACH,OAAO,EAAE,MAAM,CAAC;IAEhB;;;OAGG;IACH,QAAQ,EAAE,QAAQ,CAAC;IAEnB;;;OAGG;IACH,eAAe,EAAE,OAAO,CAAC;IAEzB;;;OAGG;IACH,WAAW,EAAE,MAAM,CAAC;IAEpB;;;OAGG;IACH,eAAe,EAAE,MAAM,CAAC;IAExB;;;OAGG;IACH,WAAW,EAAE,MAAM,CAAC;IAEpB;;;OAGG;IACH,YAAY,EAAE,MAAM,CAAC;IAErB;;;OAGG;IACH,aAAa,EAAE,MAAM,CAAC;IAEtB;;;OAGG;IACH,uBAAuB,EAAE,MAAM,CAAC;CACjC;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC;;OAEG;IACH,KAAK,EAAE,OAAO,CAAC;IAEf;;OAEG;IACH,MAAM,EAAE,MAAM,EAAE,CAAC;IAEjB;;OAEG;IACH,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED;;GAEG;AACH,eAAO,MAAM,eAAe;;;;;;;;;CASlB,CAAC;AAEX;;;;;GAKG;AACH,eAAO,MAAM,QAAQ,EAAE,QAAQ,CAAC,gBAAgB,CAwEtC,CAAC;AAEX;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,CAQ1C;AAiDD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,SAAS,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC,gBAAgB,CAAC,GAAG,gBAAgB,CAqCjF;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,gBAAgB,GAAG,sBAAsB,CA2E/E;AAED;;;;GAIG;AACH,wBAAgB,WAAW,IAAI,QAAQ,CAAC,gBAAgB,CAAC,CAExD;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,QAAQ,CAEjE"}
@@ -6,12 +6,48 @@
6
6
  * values used throughout the babysitter SDK. Import from here instead of using
7
7
  * scattered magic numbers and strings.
8
8
  */
9
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ var desc = Object.getOwnPropertyDescriptor(m, k);
12
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
13
+ desc = { enumerable: true, get: function() { return m[k]; } };
14
+ }
15
+ Object.defineProperty(o, k2, desc);
16
+ }) : (function(o, m, k, k2) {
17
+ if (k2 === undefined) k2 = k;
18
+ o[k2] = m[k];
19
+ }));
20
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
21
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
22
+ }) : function(o, v) {
23
+ o["default"] = v;
24
+ });
25
+ var __importStar = (this && this.__importStar) || (function () {
26
+ var ownKeys = function(o) {
27
+ ownKeys = Object.getOwnPropertyNames || function (o) {
28
+ var ar = [];
29
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
30
+ return ar;
31
+ };
32
+ return ownKeys(o);
33
+ };
34
+ return function (mod) {
35
+ if (mod && mod.__esModule) return mod;
36
+ var result = {};
37
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
38
+ __setModuleDefault(result, mod);
39
+ return result;
40
+ };
41
+ })();
9
42
  Object.defineProperty(exports, "__esModule", { value: true });
10
43
  exports.DEFAULTS = exports.CONFIG_ENV_VARS = void 0;
44
+ exports.getGlobalStateDir = getGlobalStateDir;
11
45
  exports.getConfig = getConfig;
12
46
  exports.validateConfig = validateConfig;
13
47
  exports.getDefaults = getDefaults;
14
48
  exports.isValidLogLevel = isValidLogLevel;
49
+ const path = __importStar(require("node:path"));
50
+ const os = __importStar(require("node:os"));
15
51
  /**
16
52
  * Environment variable names for configuration overrides
17
53
  */
@@ -93,6 +129,25 @@ exports.DEFAULTS = {
93
129
  */
94
130
  largeResultPreviewLimit: 1024 * 1024,
95
131
  };
132
+ /**
133
+ * Returns the global babysitter state directory (~/.a5c/state/).
134
+ *
135
+ * All harness adapters use this as the canonical default location for session
136
+ * state files. The directory is user-global (not workspace-relative or
137
+ * plugin-root-relative) so session state is discoverable regardless of the
138
+ * execution context (hook subprocess, Bash tool, CLI invocation, etc.).
139
+ *
140
+ * Override: set BABYSITTER_STATE_DIR to use a different path.
141
+ */
142
+ function getGlobalStateDir() {
143
+ if (process.env.BABYSITTER_STATE_DIR) {
144
+ return path.resolve(process.env.BABYSITTER_STATE_DIR);
145
+ }
146
+ const globalRoot = process.env.BABYSITTER_GLOBAL_STATE_DIR?.trim()
147
+ ? path.resolve(process.env.BABYSITTER_GLOBAL_STATE_DIR)
148
+ : path.join(os.homedir(), ".a5c");
149
+ return path.join(globalRoot, "state");
150
+ }
96
151
  /**
97
152
  * Valid log levels for validation
98
153
  */
@@ -21,5 +21,5 @@
21
21
  * }
22
22
  * ```
23
23
  */
24
- export { type LogLevel, type BabysitterConfig, type ConfigValidationResult, DEFAULTS, CONFIG_ENV_VARS, getConfig, validateConfig, getDefaults, isValidLogLevel, } from "./defaults";
24
+ export { type LogLevel, type BabysitterConfig, type ConfigValidationResult, DEFAULTS, CONFIG_ENV_VARS, getConfig, getGlobalStateDir, validateConfig, getDefaults, isValidLogLevel, } from "./defaults";
25
25
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,EAEL,KAAK,QAAQ,EACb,KAAK,gBAAgB,EACrB,KAAK,sBAAsB,EAG3B,QAAQ,EACR,eAAe,EAGf,SAAS,EACT,cAAc,EACd,WAAW,EACX,eAAe,GAChB,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,EAEL,KAAK,QAAQ,EACb,KAAK,gBAAgB,EACrB,KAAK,sBAAsB,EAG3B,QAAQ,EACR,eAAe,EAGf,SAAS,EACT,iBAAiB,EACjB,cAAc,EACd,WAAW,EACX,eAAe,GAChB,MAAM,YAAY,CAAC"}
@@ -23,13 +23,14 @@
23
23
  * ```
24
24
  */
25
25
  Object.defineProperty(exports, "__esModule", { value: true });
26
- exports.isValidLogLevel = exports.getDefaults = exports.validateConfig = exports.getConfig = exports.CONFIG_ENV_VARS = exports.DEFAULTS = void 0;
26
+ exports.isValidLogLevel = exports.getDefaults = exports.validateConfig = exports.getGlobalStateDir = exports.getConfig = exports.CONFIG_ENV_VARS = exports.DEFAULTS = void 0;
27
27
  var defaults_1 = require("./defaults");
28
28
  // Constants
29
29
  Object.defineProperty(exports, "DEFAULTS", { enumerable: true, get: function () { return defaults_1.DEFAULTS; } });
30
30
  Object.defineProperty(exports, "CONFIG_ENV_VARS", { enumerable: true, get: function () { return defaults_1.CONFIG_ENV_VARS; } });
31
31
  // Functions
32
32
  Object.defineProperty(exports, "getConfig", { enumerable: true, get: function () { return defaults_1.getConfig; } });
33
+ Object.defineProperty(exports, "getGlobalStateDir", { enumerable: true, get: function () { return defaults_1.getGlobalStateDir; } });
33
34
  Object.defineProperty(exports, "validateConfig", { enumerable: true, get: function () { return defaults_1.validateConfig; } });
34
35
  Object.defineProperty(exports, "getDefaults", { enumerable: true, get: function () { return defaults_1.getDefaults; } });
35
36
  Object.defineProperty(exports, "isValidLogLevel", { enumerable: true, get: function () { return defaults_1.isValidLogLevel; } });
@@ -2,9 +2,9 @@
2
2
  * Claude Code harness adapter.
3
3
  *
4
4
  * Centralizes all Claude Code-specific behaviors:
5
- * - Session ID resolution (CLAUDE_SESSION_ID, CLAUDE_ENV_FILE)
5
+ * - Session ID resolution (BABYSITTER_SESSION_ID via CLAUDE_ENV_FILE)
6
6
  * - Plugin root resolution (CLAUDE_PLUGIN_ROOT)
7
- * - State directory conventions (pluginRoot/skills/babysit/state)
7
+ * - State directory conventions (~/.a5c/state/)
8
8
  * - Session binding (run:create → state file with run association)
9
9
  * - Stop hook handler (approve/block decision)
10
10
  * - Session-start hook handler (env file + baseline state file)
@@ -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;AAmlCjB,wBAAgB,uBAAuB,IAAI,cAAc,CA4ExD"}
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;AA+jCjB,wBAAgB,uBAAuB,IAAI,cAAc,CA4ExD"}
@@ -3,9 +3,9 @@
3
3
  * Claude Code harness adapter.
4
4
  *
5
5
  * Centralizes all Claude Code-specific behaviors:
6
- * - Session ID resolution (CLAUDE_SESSION_ID, CLAUDE_ENV_FILE)
6
+ * - Session ID resolution (BABYSITTER_SESSION_ID via CLAUDE_ENV_FILE)
7
7
  * - Plugin root resolution (CLAUDE_PLUGIN_ROOT)
8
- * - State directory conventions (pluginRoot/skills/babysit/state)
8
+ * - State directory conventions (~/.a5c/state/)
9
9
  * - Session binding (run:create → state file with run association)
10
10
  * - Stop hook handler (approve/block decision)
11
11
  * - Session-start hook handler (env file + baseline state file)
@@ -58,6 +58,7 @@ const skill_1 = require("../cli/commands/skill");
58
58
  const session_1 = require("../session");
59
59
  const session_2 = require("../cli/commands/session");
60
60
  const context_1 = require("../prompts/context");
61
+ const config_1 = require("../config");
61
62
  const config_loader_1 = require("../compression/config-loader");
62
63
  const density_filter_1 = require("../compression/density-filter");
63
64
  const library_cache_1 = require("../compression/library-cache");
@@ -179,16 +180,19 @@ async function cleanupSession(filePath) {
179
180
  /**
180
181
  * Resolve the current session ID from environment, independent of the hook
181
182
  * payload. After `/clear`, the hook payload may carry a stale session ID while
182
- * CLAUDE_SESSION_ID or CLAUDE_ENV_FILE reflects the actual active session.
183
+ * BABYSITTER_SESSION_ID (persisted via CLAUDE_ENV_FILE) reflects the actual
184
+ * active session.
183
185
  */
184
186
  function resolveCurrentSessionIdFromEnv() {
185
- if (process.env.CLAUDE_SESSION_ID)
186
- return process.env.CLAUDE_SESSION_ID;
187
+ // Cross-harness standard env var (written by session-start hook to CLAUDE_ENV_FILE)
188
+ if (process.env.BABYSITTER_SESSION_ID)
189
+ return process.env.BABYSITTER_SESSION_ID;
190
+ // Fallback: read BABYSITTER_SESSION_ID from CLAUDE_ENV_FILE directly
187
191
  const envFile = process.env.CLAUDE_ENV_FILE;
188
192
  if (envFile) {
189
193
  try {
190
194
  const content = (0, node_fs_1.readFileSync)(envFile, "utf-8");
191
- const match = content.match(/export CLAUDE_SESSION_ID="([^"]+)"/);
195
+ const match = content.match(/export BABYSITTER_SESSION_ID="([^"]+)"/);
192
196
  if (match?.[1])
193
197
  return match[1];
194
198
  }
@@ -237,7 +241,7 @@ async function handleStopHookImpl(args) {
237
241
  const resolvedPluginRoot = pluginRoot ? path.resolve(pluginRoot) : "";
238
242
  const stateDir = args.stateDir
239
243
  ? path.resolve(args.stateDir)
240
- : (resolvedPluginRoot ? path.resolve(resolvedPluginRoot, "skills", "babysit", "state") : "");
244
+ : (0, config_1.getGlobalStateDir)();
241
245
  if (!stateDir) {
242
246
  log.warn("Cannot determine state directory — allowing exit");
243
247
  if (verbose) {
@@ -249,59 +253,42 @@ async function handleStopHookImpl(args) {
249
253
  log.info(`Resolved pluginRoot: ${resolvedPluginRoot || "(empty)"}`);
250
254
  log.info(`Resolved stateDir: ${stateDir}`);
251
255
  const runsDir = (0, resolveInputPath_1.collapseDoubledA5cRuns)(path.resolve(args.runsDir || ".a5c/runs"));
252
- // 3. Check iteration — try primary stateDir, then fallback to .a5c/state/
256
+ // 3. Check iteration — look up session state file in the resolved stateDir
253
257
  let filePath = (0, session_1.getSessionFilePath)(stateDir, sessionId);
254
258
  log.info(`Checking session file at: ${filePath}`);
255
259
  let sessionFile;
256
260
  try {
257
261
  if (!(await (0, session_1.sessionFileExists)(filePath))) {
258
- // Fallback: check .a5c/state/ directory
259
- const fallbackStateDir = path.resolve(".a5c", "state");
260
- const fallbackPath = (0, session_1.getSessionFilePath)(fallbackStateDir, sessionId);
261
- log.info(`Primary state file not found, trying fallback: ${fallbackPath}`);
262
- if (await (0, session_1.sessionFileExists)(fallbackPath)) {
263
- filePath = fallbackPath;
264
- log.info(`Found session file at fallback path: ${filePath}`);
265
- }
266
- else {
267
- // Fallback: the hook payload may carry a stale session ID (e.g. after
268
- // /clear). Try resolving the *current* session ID from CLAUDE_SESSION_ID
269
- // or CLAUDE_ENV_FILE and retry the lookup if it differs.
270
- const envSessionId = resolveCurrentSessionIdFromEnv();
271
- if (envSessionId && envSessionId !== sessionId) {
272
- log.info(`Payload session ${sessionId} is stale; current env session is ${envSessionId} — retrying lookup`);
273
- const primaryRetry = (0, session_1.getSessionFilePath)(stateDir, envSessionId);
274
- const fallbackRetry = (0, session_1.getSessionFilePath)(fallbackStateDir, envSessionId);
275
- if (await (0, session_1.sessionFileExists)(primaryRetry)) {
276
- filePath = primaryRetry;
277
- sessionId = envSessionId;
278
- log.setContext("session", sessionId);
279
- log.info(`Found session file for env session at primary: ${filePath}`);
280
- }
281
- else if (await (0, session_1.sessionFileExists)(fallbackRetry)) {
282
- filePath = fallbackRetry;
283
- sessionId = envSessionId;
284
- log.setContext("session", sessionId);
285
- log.info(`Found session file for env session at fallback: ${filePath}`);
286
- }
287
- else {
288
- log.info(`No active loop found for payload session ${sessionId} or env session ${envSessionId} — allowing exit`);
289
- if (verbose) {
290
- process.stderr.write(`[hook:run stop] No active loop found for session ${sessionId} or ${envSessionId}\n`);
291
- }
292
- process.stdout.write("{}\n");
293
- return 0;
294
- }
262
+ // Fallback: the hook payload may carry a stale session ID (e.g. after
263
+ // /clear). Try resolving the *current* session ID from BABYSITTER_SESSION_ID
264
+ // (persisted via CLAUDE_ENV_FILE) and retry the lookup if it differs.
265
+ const envSessionId = resolveCurrentSessionIdFromEnv();
266
+ if (envSessionId && envSessionId !== sessionId) {
267
+ log.info(`Payload session ${sessionId} is stale; current env session is ${envSessionId} — retrying lookup`);
268
+ const retryPath = (0, session_1.getSessionFilePath)(stateDir, envSessionId);
269
+ if (await (0, session_1.sessionFileExists)(retryPath)) {
270
+ filePath = retryPath;
271
+ sessionId = envSessionId;
272
+ log.setContext("session", sessionId);
273
+ log.info(`Found session file for env session: ${filePath}`);
295
274
  }
296
275
  else {
297
- log.info(`No active loop found at primary (${filePath}) or fallback (${fallbackPath}) — allowing exit`);
276
+ log.info(`No active loop found for payload session ${sessionId} or env session ${envSessionId} — allowing exit`);
298
277
  if (verbose) {
299
- process.stderr.write(`[hook:run stop] No active loop found for session ${sessionId}\n`);
278
+ process.stderr.write(`[hook:run stop] No active loop found for session ${sessionId} or ${envSessionId}\n`);
300
279
  }
301
280
  process.stdout.write("{}\n");
302
281
  return 0;
303
282
  }
304
283
  }
284
+ else {
285
+ log.info(`No active loop found for session ${sessionId} — allowing exit`);
286
+ if (verbose) {
287
+ process.stderr.write(`[hook:run stop] No active loop found for session ${sessionId}\n`);
288
+ }
289
+ process.stdout.write("{}\n");
290
+ return 0;
291
+ }
305
292
  }
306
293
  sessionFile = await (0, session_1.readSessionFile)(filePath);
307
294
  }
@@ -728,12 +715,13 @@ async function handleSessionStartHookImpl(args) {
728
715
  process.stdout.write("{}\n");
729
716
  return 0;
730
717
  }
731
- // 2. If CLAUDE_ENV_FILE is set, append session ID export
718
+ // 2. If CLAUDE_ENV_FILE is set, persist BABYSITTER_SESSION_ID so subsequent
719
+ // hooks (stop hook, Bash tool calls) can resolve it from the environment.
732
720
  let envFilePersisted = false;
733
721
  const envFile = process.env.CLAUDE_ENV_FILE;
734
722
  if (envFile) {
735
723
  try {
736
- (0, node_fs_1.appendFileSync)(envFile, `export CLAUDE_SESSION_ID="${sessionId}"\n`);
724
+ (0, node_fs_1.appendFileSync)(envFile, `export BABYSITTER_SESSION_ID="${sessionId}"\n`);
737
725
  envFilePersisted = true;
738
726
  }
739
727
  catch {
@@ -748,7 +736,7 @@ async function handleSessionStartHookImpl(args) {
748
736
  const resolvedPluginRoot = pluginRoot ? path.resolve(pluginRoot) : "";
749
737
  const stateDir = args.stateDir
750
738
  ? path.resolve(args.stateDir)
751
- : (resolvedPluginRoot ? path.resolve(resolvedPluginRoot, "skills", "babysit", "state") : "");
739
+ : (0, config_1.getGlobalStateDir)();
752
740
  let stateFilePersisted = false;
753
741
  if (stateDir) {
754
742
  const filePath = (0, session_1.getSessionFilePath)(stateDir, sessionId);
@@ -820,20 +808,9 @@ async function handleSessionStartHookImpl(args) {
820
808
  // Session binding (run:create flow)
821
809
  // ---------------------------------------------------------------------------
822
810
  async function bindSessionImpl(opts) {
823
- const { sessionId, runId, pluginRoot, runsDir, maxIterations = 256, prompt, verbose } = opts;
811
+ const { sessionId, runId, pluginRoot: _pluginRoot, runsDir, maxIterations = 256, prompt, verbose } = opts;
824
812
  // Resolve state directory (always resolve to absolute paths)
825
- const resolvedPluginRoot = pluginRoot ? path.resolve(pluginRoot) : "";
826
- let stateDir = opts.stateDir ? path.resolve(opts.stateDir) : "";
827
- if (!stateDir && resolvedPluginRoot) {
828
- stateDir = path.resolve(resolvedPluginRoot, "skills", "babysit", "state");
829
- }
830
- if (!stateDir) {
831
- return {
832
- harness: "claude-code",
833
- sessionId,
834
- error: "Cannot bind session: --state-dir or --plugin-root required for claude-code harness",
835
- };
836
- }
813
+ const stateDir = opts.stateDir ? path.resolve(opts.stateDir) : (0, config_1.getGlobalStateDir)();
837
814
  const filePath = (0, session_1.getSessionFilePath)(stateDir, sessionId);
838
815
  // Check for existing session (prevent re-entrant runs)
839
816
  if (await (0, session_1.sessionFileExists)(filePath)) {
@@ -993,7 +970,7 @@ function createClaudeCodeAdapter() {
993
970
  return {
994
971
  name: "claude-code",
995
972
  isActive() {
996
- return !!(process.env.CLAUDE_SESSION_ID || process.env.CLAUDE_ENV_FILE);
973
+ return !!(process.env.BABYSITTER_SESSION_ID || process.env.CLAUDE_ENV_FILE);
997
974
  },
998
975
  autoResolvesSessionId() {
999
976
  return true;
@@ -1001,14 +978,15 @@ function createClaudeCodeAdapter() {
1001
978
  resolveSessionId(parsed) {
1002
979
  if (parsed.sessionId)
1003
980
  return parsed.sessionId;
1004
- if (process.env.CLAUDE_SESSION_ID)
1005
- return process.env.CLAUDE_SESSION_ID;
1006
- // Fallback: read from CLAUDE_ENV_FILE (written by session-start hook)
981
+ // Cross-harness standard (written by session-start hook to CLAUDE_ENV_FILE)
982
+ if (process.env.BABYSITTER_SESSION_ID)
983
+ return process.env.BABYSITTER_SESSION_ID;
984
+ // Fallback: read BABYSITTER_SESSION_ID from CLAUDE_ENV_FILE directly
1007
985
  const envFile = process.env.CLAUDE_ENV_FILE;
1008
986
  if (envFile) {
1009
987
  try {
1010
988
  const content = (0, node_fs_1.readFileSync)(envFile, "utf-8");
1011
- const match = content.match(/export CLAUDE_SESSION_ID="([^"]+)"/);
989
+ const match = content.match(/export BABYSITTER_SESSION_ID="([^"]+)"/);
1012
990
  if (match?.[1])
1013
991
  return match[1];
1014
992
  }
@@ -1021,10 +999,7 @@ function createClaudeCodeAdapter() {
1021
999
  resolveStateDir(args) {
1022
1000
  if (args.stateDir)
1023
1001
  return path.resolve(args.stateDir);
1024
- const root = args.pluginRoot || process.env.CLAUDE_PLUGIN_ROOT;
1025
- if (root)
1026
- return path.resolve(root, "skills", "babysit", "state");
1027
- return undefined;
1002
+ return (0, config_1.getGlobalStateDir)();
1028
1003
  },
1029
1004
  resolvePluginRoot(args) {
1030
1005
  const root = args.pluginRoot || process.env.CLAUDE_PLUGIN_ROOT;
@@ -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;AAkUjB,wBAAgB,kBAAkB,IAAI,cAAc,CAuGnD"}
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;AAkRjB,wBAAgB,kBAAkB,IAAI,cAAc,CAuGnD"}
@@ -43,8 +43,8 @@ var __importStar = (this && this.__importStar) || (function () {
43
43
  Object.defineProperty(exports, "__esModule", { value: true });
44
44
  exports.createCodexAdapter = createCodexAdapter;
45
45
  const path = __importStar(require("node:path"));
46
- const node_fs_1 = require("node:fs");
47
46
  const node_stream_1 = require("node:stream");
47
+ const config_1 = require("../config");
48
48
  const claudeCode_1 = require("./claudeCode");
49
49
  const session_1 = require("../session");
50
50
  const context_1 = require("../prompts/context");
@@ -56,49 +56,20 @@ function resolveCodexPluginRoot(args = {}) {
56
56
  function resolveCodexStateDir(args) {
57
57
  if (args.stateDir)
58
58
  return path.resolve(args.stateDir);
59
- if (process.env.BABYSITTER_STATE_DIR) {
60
- return path.resolve(process.env.BABYSITTER_STATE_DIR);
61
- }
62
- const pluginRoot = resolveCodexPluginRoot(args);
63
- if (pluginRoot) {
64
- const cwd = path.resolve(process.cwd());
65
- const normalizedPluginRoot = path.resolve(pluginRoot);
66
- // Workspace-local installs place ".codex" beside ".a5c", so derive from
67
- // the plugin root only when that root lives under the active workspace.
68
- if (normalizedPluginRoot === cwd ||
69
- normalizedPluginRoot.startsWith(`${cwd}${path.sep}`)) {
70
- return path.resolve(normalizedPluginRoot, "..", ".a5c");
71
- }
72
- }
73
- if (pluginRoot) {
74
- // Global Codex installs live under "~/.codex", but Babysitter run/session
75
- // state must still default to the active workspace ".a5c".
76
- // Falling through here keeps global skill installs honest.
77
- return path.resolve(".a5c");
78
- }
79
- // Without any explicit state binding, Codex state belongs to the current
80
- // workspace, not a user-global directory.
81
- return path.resolve(".a5c");
59
+ return (0, config_1.getGlobalStateDir)();
82
60
  }
83
61
  function resolveCodexSessionId(parsed) {
84
62
  if (parsed.sessionId)
85
63
  return parsed.sessionId;
86
- // Codex injects CODEX_THREAD_ID; keep CODEX_SESSION_ID as legacy fallback.
64
+ // Cross-harness standard
65
+ if (process.env.BABYSITTER_SESSION_ID)
66
+ return process.env.BABYSITTER_SESSION_ID;
67
+ // Codex-native env vars (auto-injected by Codex CLI into all hooks)
87
68
  if (process.env.CODEX_THREAD_ID)
88
69
  return process.env.CODEX_THREAD_ID;
89
70
  if (process.env.CODEX_SESSION_ID)
90
71
  return process.env.CODEX_SESSION_ID;
91
- const envFile = process.env.CODEX_ENV_FILE;
92
- if (!envFile)
93
- return undefined;
94
- try {
95
- const content = (0, node_fs_1.readFileSync)(envFile, "utf-8");
96
- const match = content.match(/(?:^|\n)\s*(?:export\s+)?(?:CODEX_THREAD_ID|CODEX_SESSION_ID)="([^"]+)"/);
97
- return match?.[1] || undefined;
98
- }
99
- catch {
100
- return undefined;
101
- }
72
+ return undefined;
102
73
  }
103
74
  function readStdin() {
104
75
  return new Promise((resolve, reject) => {
@@ -205,17 +176,7 @@ async function handleCodexSessionStartHookImpl(args) {
205
176
  process.stdout.write("{}\n");
206
177
  return 0;
207
178
  }
208
- const envFile = process.env.CODEX_ENV_FILE;
209
- if (envFile) {
210
- try {
211
- (0, node_fs_1.appendFileSync)(envFile, `export CODEX_THREAD_ID="${sessionId}"\nexport CODEX_SESSION_ID="${sessionId}"\n`);
212
- }
213
- catch {
214
- if (verbose) {
215
- process.stderr.write(`[hook:run session-start] Failed to write to CODEX_ENV_FILE: ${envFile}\n`);
216
- }
217
- }
218
- }
179
+ // Codex auto-injects CODEX_THREAD_ID into all hooks — no env file write needed.
219
180
  const stateDir = resolveCodexStateDir({
220
181
  stateDir: args.stateDir,
221
182
  pluginRoot: args.pluginRoot,
@@ -317,9 +278,9 @@ function createCodexAdapter() {
317
278
  return {
318
279
  name: "codex",
319
280
  isActive() {
320
- return !!(process.env.CODEX_THREAD_ID ||
281
+ return !!(process.env.BABYSITTER_SESSION_ID ||
282
+ process.env.CODEX_THREAD_ID ||
321
283
  process.env.CODEX_SESSION_ID ||
322
- process.env.CODEX_ENV_FILE ||
323
284
  process.env.CODEX_PLUGIN_ROOT);
324
285
  },
325
286
  autoResolvesSessionId() {
@@ -1 +1 @@
1
- {"version":3,"file":"cursor.d.ts","sourceRoot":"","sources":["../../src/harness/cursor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAsBH,OAAO,KAAK,EACV,cAAc,EAMf,MAAM,SAAS,CAAC;AA4wBjB,wBAAgB,mBAAmB,IAAI,cAAc,CAiIpD"}
1
+ {"version":3,"file":"cursor.d.ts","sourceRoot":"","sources":["../../src/harness/cursor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAsBH,OAAO,KAAK,EACV,cAAc,EAMf,MAAM,SAAS,CAAC;AAgwBjB,wBAAgB,mBAAmB,IAAI,cAAc,CAgIpD"}