@a5c-ai/babysitter-codex 0.1.6-staging.4ebefe91 → 0.1.6-staging.77d6ebc1

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 (55) hide show
  1. package/.codex/skills/babysit/SKILL.md +110 -0
  2. package/README.md +44 -26
  3. package/SKILL.md +38 -16
  4. package/agents/openai.yaml +4 -4
  5. package/bin/postinstall.js +188 -39
  6. package/bin/uninstall.js +80 -37
  7. package/package.json +3 -3
  8. package/prompts/README.md +28 -0
  9. package/prompts/assimilate.md +9 -0
  10. package/prompts/call.md +12 -0
  11. package/prompts/doctor.md +9 -0
  12. package/prompts/forever.md +8 -0
  13. package/prompts/help.md +8 -0
  14. package/prompts/issue.md +9 -0
  15. package/prompts/model.md +8 -0
  16. package/prompts/observe.md +8 -0
  17. package/prompts/plan.md +11 -0
  18. package/prompts/project-install.md +8 -0
  19. package/prompts/resume.md +8 -0
  20. package/prompts/retrospect.md +8 -0
  21. package/prompts/team-install.md +8 -0
  22. package/prompts/user-install.md +8 -0
  23. package/prompts/yolo.md +8 -0
  24. package/scripts/team-install.js +147 -56
  25. package/.codex/skills/babysitter/assimilate/SKILL.md +0 -58
  26. package/.codex/skills/babysitter/call/SKILL.md +0 -588
  27. package/.codex/skills/babysitter/doctor/SKILL.md +0 -89
  28. package/.codex/skills/babysitter/forever/SKILL.md +0 -45
  29. package/.codex/skills/babysitter/help/SKILL.md +0 -48
  30. package/.codex/skills/babysitter/issue/SKILL.md +0 -36
  31. package/.codex/skills/babysitter/model/SKILL.md +0 -31
  32. package/.codex/skills/babysitter/observe/SKILL.md +0 -38
  33. package/.codex/skills/babysitter/plan/SKILL.md +0 -44
  34. package/.codex/skills/babysitter/project-install/SKILL.md +0 -62
  35. package/.codex/skills/babysitter/resume/SKILL.md +0 -30
  36. package/.codex/skills/babysitter/retrospect/SKILL.md +0 -43
  37. package/.codex/skills/babysitter/team-install/SKILL.md +0 -35
  38. package/.codex/skills/babysitter/user-install/SKILL.md +0 -53
  39. package/.codex/skills/babysitter/yolo/SKILL.md +0 -48
  40. package/commands/README.md +0 -23
  41. package/commands/assimilate.md +0 -26
  42. package/commands/call.md +0 -29
  43. package/commands/doctor.md +0 -27
  44. package/commands/forever.md +0 -26
  45. package/commands/help.md +0 -27
  46. package/commands/issue.md +0 -26
  47. package/commands/model.md +0 -26
  48. package/commands/observe.md +0 -26
  49. package/commands/plan.md +0 -26
  50. package/commands/project-install.md +0 -30
  51. package/commands/resume.md +0 -28
  52. package/commands/retrospect.md +0 -26
  53. package/commands/team-install.md +0 -28
  54. package/commands/user-install.md +0 -26
  55. package/commands/yolo.md +0 -27
@@ -0,0 +1,110 @@
1
+ ---
2
+ name: babysit
3
+ description: >-
4
+ Run babysitter workflows from Codex using the installed babysit skill bundle,
5
+ workspace Codex hooks, workspace Codex config, and the Babysitter SDK runtime
6
+ loop.
7
+ Use when the user wants to babysit a task, resume a run, diagnose run health,
8
+ install the Codex skill, or assimilate a methodology for Codex.
9
+ ---
10
+
11
+ # Babysitter for Codex CLI
12
+
13
+ Babysitter on Codex is implemented as:
14
+
15
+ - the installed skill bundle under `~/.codex/skills/babysit` or `.codex/skills/babysit`
16
+ - optional prompt aliases under `~/.codex/prompts/*.md` or `.codex/prompts/*.md`
17
+ - workspace `.codex/hooks.json`
18
+ - workspace `.codex/config.toml`
19
+ - workspace `.a5c/`
20
+ - the Babysitter SDK CLI for `run:create`, `run:iterate`, `run:status`,
21
+ `task:list`, `task:post`, and process-library binding
22
+
23
+ This package supports only the hooks model for the Codex plugin path. Do not
24
+ introduce an app-server loop, an external orchestrator, or fake plugin-manifest
25
+ machinery for the Codex integration.
26
+
27
+ ## Choosing a Mode
28
+
29
+ Use this single skill for all Babysitter Codex flows.
30
+
31
+ Choose the mode from either:
32
+
33
+ 1. the direct user intent when the skill is invoked as `$babysit`
34
+ 2. the installed prompt alias name when the user invoked `/call`, `/plan`,
35
+ `/resume`, `/yolo`, and the rest
36
+
37
+ | User intent | Mode |
38
+ |-------------|------|
39
+ | Start an orchestration run | `call` |
40
+ | Run autonomously | `yolo` |
41
+ | Resume an existing run | `resume` |
42
+ | Plan without executing | `plan` |
43
+ | Diagnose run health | `doctor` |
44
+ | Help and documentation | `help` |
45
+ | Install into a project | `project-install` |
46
+ | Install user profile/setup | `user-install` |
47
+ | Install team-pinned setup | `team-install` |
48
+ | Assimilate external methodology | `assimilate` |
49
+
50
+ ## Runtime Contract
51
+
52
+ Use the Babysitter SDK CLI for orchestration:
53
+
54
+ ```bash
55
+ babysitter run:create --process-id <id> --entry <path>#<export> ...
56
+ babysitter run:iterate <runDir> --json --iteration <n>
57
+ babysitter run:status <runDir> --json
58
+ babysitter task:list <runDir> --pending --json
59
+ babysitter task:post <runDir> <effectId> --status ok --value <file> --json
60
+ ```
61
+
62
+ When a Codex session ID is available, bind it honestly:
63
+
64
+ ```bash
65
+ babysitter run:create ... --harness codex --session-id <id> --state-dir .a5c --json
66
+ ```
67
+
68
+ ## Result Posting Protocol
69
+
70
+ 1. Write the result value to `tasks/<effectId>/output.json`
71
+ 2. Post it with `babysitter task:post`
72
+ 3. Never write `result.json` directly
73
+
74
+ ## Hook Loop
75
+
76
+ Workspace onboarding must install `.codex/hooks.json` and `.codex/config.toml`
77
+ so:
78
+
79
+ 1. `SessionStart` seeds `.a5c` session state
80
+ 2. `UserPromptSubmit` performs prompt-time transformations when needed
81
+ 3. `Stop` decides whether the run is complete or Codex should receive the next
82
+ Babysitter iteration context
83
+
84
+ ## Process Library Model
85
+
86
+ The Codex package does not bundle the process library.
87
+
88
+ Workspace onboarding must:
89
+
90
+ 1. clone or update the upstream Babysitter repo into
91
+ `.a5c/process-library/babysitter-repo`
92
+ 2. bind `.a5c/process-library/babysitter-repo/library` with
93
+ `babysitter process-library:use`
94
+ 3. resolve the active binding later with
95
+ `babysitter process-library:active --state-dir .a5c --json`
96
+
97
+ Preferred discovery order:
98
+
99
+ 1. project-local `.a5c/processes`
100
+ 2. the active SDK-managed process-library binding
101
+
102
+ ## Codex-Specific Rules
103
+
104
+ - Prefer invoking the skill directly with `$babysit`
105
+ - Optional prompt aliases such as `/call`, `/plan`, `/resume`, and `/yolo` may
106
+ exist, but they should only forward into the `babysit` skill for the matching
107
+ mode; they are not the primary integration surface
108
+ - Never fabricate a session ID when none is available from Codex or the caller
109
+ - Use `notify` only for monitoring and telemetry, never as the orchestration
110
+ control loop
package/README.md CHANGED
@@ -6,7 +6,11 @@ This package is a Codex skill bundle plus installer assets. It is not a native
6
6
  Codex plugin manifest and it does not run an external orchestrator. The Codex
7
7
  plugin path is:
8
8
 
9
- - installed skill bundle under `~/.codex/skills/babysitter-codex`
9
+ - installed skill bundle under `~/.codex/skills/babysit`
10
+ - optional user-local prompt aliases under `~/.codex/prompts/call.md`,
11
+ `plan.md`, `resume.md`, `yolo.md`, and the rest of the Babysitter modes
12
+ - repo-local skill bundle under `.codex/skills/babysit`
13
+ - repo-local prompt aliases under `.codex/prompts/*.md`
10
14
  - workspace `.codex/hooks.json`
11
15
  - workspace `.codex/config.toml`
12
16
  - workspace `.a5c/` state
@@ -20,8 +24,7 @@ Global install copies the Codex-facing bundle into `CODEX_HOME`:
20
24
  - `SKILL.md`
21
25
  - `.codex/`
22
26
  - `agents/`
23
- - `commands/`
24
- - `bin/`
27
+ - `prompts/` as the source for user-local prompt aliases
25
28
  - `scripts/`
26
29
  - `babysitter.lock.json`
27
30
 
@@ -52,6 +55,10 @@ Install the Codex package:
52
55
  npm install -g @a5c-ai/babysitter-codex
53
56
  ```
54
57
 
58
+ This global install now also clones or updates the process library into
59
+ `~/.a5c/process-library/babysitter-repo` and binds it as the default active
60
+ process library in `~/.a5c/active/process-library.json` through the SDK CLI.
61
+
55
62
  Then install the Codex plugin payload into the target workspace:
56
63
 
57
64
  ```bash
@@ -71,16 +78,19 @@ It:
71
78
 
72
79
  1. Resolves the installed package root.
73
80
  2. Reads `babysitter.lock.json`.
74
- 3. Clones or updates the upstream Babysitter repo into
81
+ 3. Installs the single repo-local Codex skill into `.codex/skills/babysit`.
82
+ 4. Installs the prompt aliases into `.codex/prompts`.
83
+ 5. Copies hook scripts into `.codex/hooks`.
84
+ 6. Clones or updates the upstream Babysitter repo into
75
85
  `<workspace>/.a5c/process-library/babysitter-repo`.
76
- 4. Binds `<workspace>/.a5c/process-library/babysitter-repo/library` with
86
+ 7. Binds `<workspace>/.a5c/process-library/babysitter-repo/library` with
77
87
  `babysitter process-library:use`.
78
- 5. Writes `<workspace>/.a5c/active/process-library.json`.
79
- 6. Writes or refreshes `<workspace>/.codex/hooks.json`.
80
- 7. Creates or merges `<workspace>/.codex/config.toml` so the workspace has the
88
+ 8. Writes `<workspace>/.a5c/active/process-library.json`.
89
+ 9. Writes or refreshes `<workspace>/.codex/hooks.json`.
90
+ 10. Creates or merges `<workspace>/.codex/config.toml` so the workspace has the
81
91
  required Codex settings.
82
- 8. Writes `<workspace>/.a5c/team/install.json`.
83
- 9. Creates `<workspace>/.a5c/team/profile.json` if it does not already exist.
92
+ 11. Writes `<workspace>/.a5c/team/install.json`.
93
+ 12. Creates `<workspace>/.a5c/team/profile.json` if it does not already exist.
84
94
 
85
95
  It does not create an external orchestrator, bundle the process library, or
86
96
  turn the workspace into a fake Codex plugin manifest.
@@ -89,6 +99,11 @@ turn the workspace into a fake Codex plugin manifest.
89
99
 
90
100
  After a successful workspace install, the important files are:
91
101
 
102
+ - `.codex/skills/babysit/SKILL.md`
103
+ - `.codex/prompts/call.md`
104
+ - `.codex/prompts/plan.md`
105
+ - `.codex/prompts/resume.md`
106
+ - `.codex/hooks/`
92
107
  - `.codex/hooks.json`
93
108
  - `.codex/config.toml`
94
109
  - `.a5c/team/install.json`
@@ -98,18 +113,23 @@ After a successful workspace install, the important files are:
98
113
 
99
114
  ## Using It In Codex
100
115
 
101
- Use normal Codex chat phrases:
116
+ Use the skill directly:
102
117
 
103
118
  ```text
104
- babysitter call implement authentication with tests
105
- babysitter resume
106
- babysitter doctor
107
- babysitter team-install
108
- babysitter project-install
119
+ $babysit implement authentication with tests
109
120
  ```
110
121
 
111
- The Codex skill and hooks own the plugin flow. Low-level SDK commands are still
112
- the runtime mechanism, but they are not the user-facing interface.
122
+ The optional prompt aliases are the mode shortcuts:
123
+
124
+ ```text
125
+ /call implement authentication with tests
126
+ /plan migration from monolith to services
127
+ /resume latest
128
+ ```
129
+
130
+ Each prompt alias should only forward into the `babysit` skill for the
131
+ matching mode. Low-level SDK commands remain runtime mechanics, not the
132
+ user-facing interface.
113
133
 
114
134
  ## Verification
115
135
 
@@ -117,9 +137,12 @@ Verify the installed skill bundle:
117
137
 
118
138
  ```bash
119
139
  npm ls -g @a5c-ai/babysitter-codex --depth=0
120
- ls -1 ~/.codex/skills/babysitter-codex
121
- test -f ~/.codex/skills/babysitter-codex/scripts/team-install.js
122
- test -f ~/.codex/skills/babysitter-codex/.codex/hooks/babysitter-stop-hook.sh
140
+ ls -1 ~/.codex/skills/babysit
141
+ test -f ~/.codex/skills/babysit/scripts/team-install.js
142
+ test -f ~/.codex/skills/babysit/.codex/hooks/babysitter-stop-hook.sh
143
+ test -f ~/.codex/prompts/call.md
144
+ test -f ~/.codex/prompts/plan.md
145
+ test -f ~/.codex/prompts/resume.md
123
146
  ```
124
147
 
125
148
  Verify the active process-library binding for a workspace:
@@ -128,11 +151,6 @@ Verify the active process-library binding for a workspace:
128
151
  babysitter process-library:active --state-dir /path/to/repo/.a5c --json
129
152
  ```
130
153
 
131
- ## Docs
132
-
133
- - [commands/README.md](./commands/README.md)
134
- - Internal orchestration details: [.codex/skills/babysitter/call/SKILL.md](./.codex/skills/babysitter/call/SKILL.md)
135
-
136
154
  ## License
137
155
 
138
156
  MIT
package/SKILL.md CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- name: babysitter-codex
2
+ name: babysit
3
3
  description: >-
4
- Run babysitter workflows from Codex using the installed skill bundle,
4
+ Run babysitter workflows from Codex using the installed babysit skill bundle,
5
5
  workspace Codex hooks, workspace Codex config, and the Babysitter SDK runtime
6
6
  loop.
7
7
  Use when the user wants to babysit a task, resume a run, diagnose run health,
@@ -12,7 +12,7 @@ description: >-
12
12
 
13
13
  Babysitter on Codex is implemented as:
14
14
 
15
- - the installed skill bundle under `~/.codex/skills/babysitter-codex`
15
+ - the installed skill bundle under `~/.codex/skills/babysit` or `.codex/skills/babysit`
16
16
  - workspace `.codex/hooks.json`
17
17
  - workspace `.codex/config.toml`
18
18
  - workspace `.a5c/`
@@ -25,8 +25,13 @@ machinery for the Codex integration.
25
25
 
26
26
  ## Choosing a Mode
27
27
 
28
- Read the matching sub-skill from `.codex/skills/babysitter/<mode>/SKILL.md`.
29
- If the user intent is unclear, default to `call/SKILL.md`.
28
+ Use this single skill for all Babysitter Codex flows.
29
+
30
+ Choose the mode from either:
31
+
32
+ 1. the direct user intent when the skill is invoked as `$babysit`
33
+ 2. the installed prompt alias name when the user invoked `/call`, `/plan`,
34
+ `/resume`, `/yolo`, and the rest
30
35
 
31
36
  | User intent | Mode |
32
37
  |-------------|------|
@@ -79,25 +84,42 @@ so:
79
84
 
80
85
  The Codex package does not bundle the process library.
81
86
 
82
- Workspace onboarding must:
87
+ The shared SDK-managed process library lives in the global Babysitter state dir
88
+ (`$BABYSITTER_GLOBAL_STATE_DIR` when set, otherwise `~/.a5c`), not per repo.
89
+ First use must rely on `babysitter process-library:active --json`, which
90
+ auto-clones and binds the default library if no active binding exists yet.
91
+
92
+ Read:
93
+
94
+ - `binding.dir` as the active process-library root that must be searched before
95
+ authoring a process
96
+ - `defaultSpec.cloneDir` as the cloned repo root when adjacent library material
97
+ is needed
98
+
99
+ Do not skip the active-library search step during process authoring.
100
+
101
+ Workspace onboarding and runtime flows must:
83
102
 
84
- 1. clone or update the upstream Babysitter repo into
85
- `.a5c/process-library/babysitter-repo`
86
- 2. bind `.a5c/process-library/babysitter-repo/library` with
87
- `babysitter process-library:use`
88
- 3. resolve the active binding later with
89
- `babysitter process-library:active --state-dir .a5c --json`
103
+ 1. resolve the active shared binding with `babysitter process-library:active --json`
104
+ 2. use the returned `binding.dir` as the active library root
105
+ 3. only consult `defaultSpec.cloneDir` when adjacent repo-level material is
106
+ needed beyond the active root itself
90
107
 
91
108
  Preferred discovery order:
92
109
 
93
110
  1. project-local `.a5c/processes`
94
- 2. the active SDK-managed process-library binding
111
+ 2. the active SDK-managed process-library binding from `binding.dir`
112
+ 3. the cloned process-library repo root from `defaultSpec.cloneDir` when
113
+ adjacent reference material is needed
95
114
 
96
115
  ## Codex-Specific Rules
97
116
 
98
- - Prefer natural-language activation such as `babysitter call ...`
99
- - Legacy `/babysitter:*` aliases may exist only as optional user-installed
100
- prompt sugar; they are not a native Codex plugin feature
117
+ - Prefer invoking the skill directly with `$babysit`
118
+ - Optional user-local prompt aliases such as `/call`, `/plan`, `/resume`, and
119
+ `/yolo` may exist, but they should only forward into the `babysit` skill for
120
+ the matching mode; they are not the primary integration surface
121
+ - Do not depend on nested mode skills under `.codex/skills/babysit/*`; the
122
+ installed Codex skill is the single `babysit` skill
101
123
  - Never fabricate a session ID when none is available from Codex or the caller
102
124
  - Use `notify` only for monitoring and telemetry, never as the orchestration
103
125
  control loop
@@ -1,4 +1,4 @@
1
- interface:
2
- display_name: "Babysitter"
3
- short_description: "Orchestrate multi-step AI workflows with quality convergence"
4
- default_prompt: "Use $babysitter-codex to orchestrate this task"
1
+ interface:
2
+ display_name: "Babysitter"
3
+ short_description: "Orchestrate multi-step AI workflows with quality convergence"
4
+ default_prompt: "Use $babysit to orchestrate this task"
@@ -1,35 +1,48 @@
1
- #!/usr/bin/env node
2
- 'use strict';
3
-
4
- /**
5
- * postinstall.js — Copies babysitter-codex skill files to ~/.codex/skills/
6
- * so Codex CLI discovers the skill globally for all projects.
7
- */
8
-
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ /**
5
+ * postinstall.js
6
+ *
7
+ * Installs the Codex-facing Babysitter skill bundle globally under CODEX_HOME,
8
+ * installs optional mode prompt aliases such as `/call` and `/plan`,
9
+ * clones/updates the process library into ~/.a5c via the SDK CLI, and
10
+ * optionally onboards the current workspace when npm was run from inside a
11
+ * repo.
12
+ */
13
+
9
14
  const fs = require('fs');
10
15
  const path = require('path');
11
16
  const os = require('os');
12
17
  const { spawnSync } = require('child_process');
13
18
 
14
- const SKILL_NAME = 'babysitter-codex';
19
+ const SKILL_NAME = 'babysit';
20
+ const LEGACY_SKILL_NAME = 'babysitter-codex';
15
21
  const PACKAGE_ROOT = path.resolve(__dirname, '..');
16
22
  const IS_WIN = process.platform === 'win32';
17
23
  const INSTALL_ENTRIES = [
18
24
  { source: 'SKILL.md', required: true },
19
25
  { source: 'README.md', required: true },
20
26
  { source: 'agents', required: true },
21
- { source: 'bin', required: true },
27
+ { source: 'prompts', required: true },
22
28
  { source: '.codex', required: true },
23
- { source: 'commands', required: true },
24
29
  { source: 'scripts', required: true },
25
30
  { source: 'babysitter.lock.json', required: true },
26
31
  ];
32
+ const LEGACY_PROMPT_NAMES = ['babysit.md'];
27
33
 
28
34
  function getCodexHome() {
29
35
  if (process.env.CODEX_HOME) return process.env.CODEX_HOME;
30
36
  return path.join(os.homedir(), '.codex');
31
37
  }
32
38
 
39
+ function getGlobalStateDir() {
40
+ if (process.env.BABYSITTER_GLOBAL_STATE_DIR) {
41
+ return path.resolve(process.env.BABYSITTER_GLOBAL_STATE_DIR);
42
+ }
43
+ return path.join(os.homedir(), '.a5c');
44
+ }
45
+
33
46
  function writeFileIfChanged(filePath, contents) {
34
47
  if (fs.existsSync(filePath)) {
35
48
  const current = fs.readFileSync(filePath, 'utf8');
@@ -42,6 +55,118 @@ function writeFileIfChanged(filePath, contents) {
42
55
  return true;
43
56
  }
44
57
 
58
+ function copyRecursive(src, dest) {
59
+ const stat = fs.statSync(src);
60
+ if (stat.isDirectory()) {
61
+ fs.mkdirSync(dest, { recursive: true });
62
+ for (const entry of fs.readdirSync(src)) {
63
+ if (['node_modules', '.a5c', '.git', 'test', '.gitignore'].includes(entry)) continue;
64
+ copyRecursive(path.join(src, entry), path.join(dest, entry));
65
+ }
66
+ return;
67
+ }
68
+
69
+ if (path.basename(src) === 'SKILL.md') {
70
+ const file = fs.readFileSync(src);
71
+ const hasBom = file.length >= 3 && file[0] === 0xef && file[1] === 0xbb && file[2] === 0xbf;
72
+ fs.mkdirSync(path.dirname(dest), { recursive: true });
73
+ fs.writeFileSync(dest, hasBom ? file.subarray(3) : file);
74
+ return;
75
+ }
76
+
77
+ fs.mkdirSync(path.dirname(dest), { recursive: true });
78
+ fs.copyFileSync(src, dest);
79
+ }
80
+
81
+ function listPromptEntries() {
82
+ const promptsDir = path.join(PACKAGE_ROOT, 'prompts');
83
+ if (!fs.existsSync(promptsDir)) {
84
+ throw new Error(`required prompt alias directory is missing: ${promptsDir}`);
85
+ }
86
+ return fs
87
+ .readdirSync(promptsDir)
88
+ .filter((name) => name.endsWith('.md') && name.toLowerCase() !== 'readme.md')
89
+ .sort()
90
+ .map((name) => ({
91
+ source: path.join('prompts', name),
92
+ targetName: name,
93
+ }));
94
+ }
95
+
96
+ function resolveBabysitterCommand(packageRoot) {
97
+ if (process.env.BABYSITTER_SDK_CLI) {
98
+ return {
99
+ command: process.execPath,
100
+ argsPrefix: [path.resolve(process.env.BABYSITTER_SDK_CLI)],
101
+ };
102
+ }
103
+ try {
104
+ return {
105
+ command: process.execPath,
106
+ argsPrefix: [
107
+ require.resolve('@a5c-ai/babysitter-sdk/dist/cli/main.js', {
108
+ paths: [packageRoot],
109
+ }),
110
+ ],
111
+ };
112
+ } catch {
113
+ return {
114
+ command: 'babysitter',
115
+ argsPrefix: [],
116
+ };
117
+ }
118
+ }
119
+
120
+ function resolveLocalSdkCli(packageRoot) {
121
+ if (process.env.BABYSITTER_SDK_CLI) {
122
+ return path.resolve(process.env.BABYSITTER_SDK_CLI);
123
+ }
124
+ try {
125
+ return require.resolve('@a5c-ai/babysitter-sdk/dist/cli/main.js', {
126
+ paths: [packageRoot],
127
+ });
128
+ } catch {
129
+ return undefined;
130
+ }
131
+ }
132
+
133
+ function runBabysitterCli(packageRoot, cliArgs, options = {}) {
134
+ const resolved = resolveBabysitterCommand(packageRoot);
135
+ const result = spawnSync(resolved.command, [...resolved.argsPrefix, ...cliArgs], {
136
+ cwd: options.cwd || process.cwd(),
137
+ stdio: ['ignore', 'pipe', 'pipe'],
138
+ encoding: 'utf8',
139
+ env: {
140
+ ...process.env,
141
+ ...(options.env || {}),
142
+ },
143
+ });
144
+ if (result.status !== 0) {
145
+ const stderr = (result.stderr || '').trim();
146
+ const stdout = (result.stdout || '').trim();
147
+ throw new Error(
148
+ `babysitter ${cliArgs.join(' ')} failed` +
149
+ (stderr ? `: ${stderr}` : stdout ? `: ${stdout}` : ''),
150
+ );
151
+ }
152
+ return result.stdout;
153
+ }
154
+
155
+ function ensureGlobalProcessLibrary(packageRoot) {
156
+ const active = JSON.parse(
157
+ runBabysitterCli(
158
+ packageRoot,
159
+ ['process-library:active', '--state-dir', getGlobalStateDir(), '--json'],
160
+ { cwd: packageRoot },
161
+ ),
162
+ );
163
+ console.log(`[babysitter-codex] process library: ${active.binding?.dir}`);
164
+ if (active.defaultSpec?.cloneDir) {
165
+ console.log(`[babysitter-codex] process library clone: ${active.defaultSpec.cloneDir}`);
166
+ }
167
+ console.log(`[babysitter-codex] process library state: ${active.stateFile}`);
168
+ }
169
+
45
170
  function mergeCodexHomeConfig(codexHome) {
46
171
  const configPath = path.join(codexHome, 'config.toml');
47
172
  const featureLines = [
@@ -59,7 +184,7 @@ function mergeCodexHomeConfig(codexHome) {
59
184
  '',
60
185
  ...featureLines,
61
186
  '',
62
- ].join('\n')
187
+ ].join('\n'),
63
188
  );
64
189
  console.log(`[babysitter-codex] wrote ${configPath}`);
65
190
  return;
@@ -70,7 +195,7 @@ function mergeCodexHomeConfig(codexHome) {
70
195
  if (/^\[features\]\s*$/m.test(content)) {
71
196
  content = content.replace(
72
197
  /^\[features\]\s*$/m,
73
- ['[features]', 'codex_hooks = true', 'multi_agent = true'].join('\n')
198
+ ['[features]', 'codex_hooks = true', 'multi_agent = true'].join('\n'),
74
199
  );
75
200
  } else {
76
201
  content = [content.trimEnd(), '', ...featureLines, ''].join('\n');
@@ -78,7 +203,7 @@ function mergeCodexHomeConfig(codexHome) {
78
203
  } else if (!/^\s*multi_agent\s*=.*$/m.test(content) && /^\[features\]\s*$/m.test(content)) {
79
204
  content = content.replace(
80
205
  /^\[features\]\s*$/m,
81
- ['[features]', 'multi_agent = true'].join('\n')
206
+ ['[features]', 'multi_agent = true'].join('\n'),
82
207
  );
83
208
  }
84
209
 
@@ -87,6 +212,26 @@ function mergeCodexHomeConfig(codexHome) {
87
212
  }
88
213
  }
89
214
 
215
+ function removeLegacySkillDir(codexHome) {
216
+ const legacyDir = path.join(codexHome, 'skills', LEGACY_SKILL_NAME);
217
+ if (!fs.existsSync(legacyDir)) {
218
+ return;
219
+ }
220
+ fs.rmSync(legacyDir, { recursive: true, force: true });
221
+ console.log(`[babysitter-codex] removed legacy skill ${legacyDir}`);
222
+ }
223
+
224
+ function removeLegacyPrompts(codexHome) {
225
+ for (const promptName of LEGACY_PROMPT_NAMES) {
226
+ const promptPath = path.join(codexHome, 'prompts', promptName);
227
+ if (!fs.existsSync(promptPath)) {
228
+ continue;
229
+ }
230
+ fs.rmSync(promptPath, { force: true });
231
+ console.log(`[babysitter-codex] removed legacy prompt ${promptPath}`);
232
+ }
233
+ }
234
+
90
235
  function shouldAutoOnboardWorkspace(skillDir) {
91
236
  const initCwd = process.env.INIT_CWD;
92
237
  if (!initCwd) return null;
@@ -124,6 +269,9 @@ function autoOnboardWorkspace(skillDir) {
124
269
  env: {
125
270
  ...process.env,
126
271
  BABYSITTER_PACKAGE_ROOT: skillDir,
272
+ ...(resolveLocalSdkCli(PACKAGE_ROOT)
273
+ ? { BABYSITTER_SDK_CLI: resolveLocalSdkCli(PACKAGE_ROOT) }
274
+ : {}),
127
275
  },
128
276
  });
129
277
 
@@ -136,28 +284,6 @@ function autoOnboardWorkspace(skillDir) {
136
284
 
137
285
  console.log(`[babysitter-codex] onboarded workspace hooks/config at ${workspace}`);
138
286
  }
139
-
140
- function copyRecursive(src, dest) {
141
- const stat = fs.statSync(src);
142
- if (stat.isDirectory()) {
143
- fs.mkdirSync(dest, { recursive: true });
144
- for (const entry of fs.readdirSync(src)) {
145
- // Skip node_modules, .a5c, .git, and test directories
146
- if (['node_modules', '.a5c', '.git', 'test', '.gitignore'].includes(entry)) continue;
147
- copyRecursive(path.join(src, entry), path.join(dest, entry));
148
- }
149
- } else {
150
- // Codex requires SKILL.md frontmatter to begin exactly with "---".
151
- // Strip UTF-8 BOM if present to avoid loader parse failures.
152
- if (path.basename(src) === 'SKILL.md') {
153
- const file = fs.readFileSync(src);
154
- const hasBom = file.length >= 3 && file[0] === 0xef && file[1] === 0xbb && file[2] === 0xbf;
155
- fs.writeFileSync(dest, hasBom ? file.subarray(3) : file);
156
- return;
157
- }
158
- fs.copyFileSync(src, dest);
159
- }
160
- }
161
287
 
162
288
  function installEntry(skillDir, entry) {
163
289
  const src = path.join(PACKAGE_ROOT, entry.source);
@@ -173,20 +299,37 @@ function installEntry(skillDir, entry) {
173
299
  return true;
174
300
  }
175
301
 
176
- function verifyInstalledPayload(skillDir) {
302
+ function installPromptEntry(codexHome, entry) {
303
+ const src = path.join(PACKAGE_ROOT, entry.source);
304
+ if (!fs.existsSync(src)) {
305
+ throw new Error(`required prompt payload is missing: ${src}`);
306
+ }
307
+ const dest = path.join(codexHome, 'prompts', entry.targetName);
308
+ copyRecursive(src, dest);
309
+ console.log(`[babysitter-codex] prompts/${entry.targetName}`);
310
+ }
311
+
312
+ function verifyInstalledPayload(skillDir, codexHome) {
313
+ const promptEntries = listPromptEntries();
177
314
  const missing = INSTALL_ENTRIES
178
315
  .map((entry) => entry.source)
179
316
  .filter((source) => !fs.existsSync(path.join(skillDir, source)));
180
317
  if (missing.length > 0) {
181
318
  throw new Error(`installed skill is incomplete; missing: ${missing.join(', ')}`);
182
319
  }
320
+ for (const entry of promptEntries) {
321
+ if (!fs.existsSync(path.join(codexHome, 'prompts', entry.targetName))) {
322
+ throw new Error(`installed prompt is missing: ${entry.targetName}`);
323
+ }
324
+ }
183
325
  }
184
326
 
185
327
  function main() {
186
328
  const codexHome = getCodexHome();
187
329
  const skillDir = path.join(codexHome, 'skills', SKILL_NAME);
330
+ const promptEntries = listPromptEntries();
188
331
 
189
- console.log(`[babysitter-codex] Installing skill to ${skillDir}`);
332
+ console.log(`[babysitter-codex] Installing skill to ${skillDir}`);
190
333
 
191
334
  try {
192
335
  fs.mkdirSync(skillDir, { recursive: true });
@@ -194,8 +337,13 @@ function main() {
194
337
  for (const entry of INSTALL_ENTRIES) {
195
338
  installEntry(skillDir, entry);
196
339
  }
340
+ for (const entry of promptEntries) {
341
+ installPromptEntry(codexHome, entry);
342
+ }
197
343
 
198
- verifyInstalledPayload(skillDir);
344
+ verifyInstalledPayload(skillDir, codexHome);
345
+ removeLegacySkillDir(codexHome);
346
+ removeLegacyPrompts(codexHome);
199
347
  mergeCodexHomeConfig(codexHome);
200
348
 
201
349
  if (!IS_WIN) {
@@ -211,6 +359,7 @@ function main() {
211
359
  }
212
360
  }
213
361
 
362
+ ensureGlobalProcessLibrary(PACKAGE_ROOT);
214
363
  autoOnboardWorkspace(skillDir);
215
364
 
216
365
  console.log('[babysitter-codex] Installation complete!');