@a5c-ai/babysitter-codex 0.1.6-staging.dd5dc0db → 0.1.6-staging.e7446f7c

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/README.md CHANGED
@@ -6,7 +6,8 @@ Babysitter in the Codex lifecycle loop.
6
6
 
7
7
  This is a Codex skill bundle plus workspace hook templates. It is not a
8
8
  Claude-style manifest plugin, but it does rely on Codex's real lifecycle hook
9
- engine through `.codex/hooks.json`.
9
+ engine through `.codex/hooks.json`, and the package postinstall now wires the
10
+ active workspace when the global install is launched from that workspace.
10
11
 
11
12
  ## What This Package Owns
12
13
 
@@ -61,6 +62,23 @@ Install from npm:
61
62
  npm install -g @a5c-ai/babysitter-codex
62
63
  ```
63
64
 
65
+ If you run that command from inside the target repository, postinstall will:
66
+
67
+ - install the skill payload into `CODEX_HOME`
68
+ - merge `~/.codex/config.toml` so `codex_hooks` is enabled
69
+ - materialize workspace `.codex/hooks.json` and `.codex/config.toml` for the
70
+ active workspace
71
+
72
+ If you installed from somewhere else, run:
73
+
74
+ ```bash
75
+ npm install -g @a5c-ai/babysitter-sdk
76
+ babysitter harness:install-plugin codex --workspace /path/to/repo
77
+ ```
78
+
79
+ `babysitter harness:install-plugin ...` is provided by the SDK CLI, so make
80
+ sure `@a5c-ai/babysitter-sdk` is installed first.
81
+
64
82
  Or from a local checkout:
65
83
 
66
84
  ```bash
@@ -6,9 +6,10 @@
6
6
  * so Codex CLI discovers the skill globally for all projects.
7
7
  */
8
8
 
9
- const fs = require('fs');
10
- const path = require('path');
9
+ const fs = require('fs');
10
+ const path = require('path');
11
11
  const os = require('os');
12
+ const { spawnSync } = require('child_process');
12
13
 
13
14
  const SKILL_NAME = 'babysitter-codex';
14
15
  const PACKAGE_ROOT = path.resolve(__dirname, '..');
@@ -32,6 +33,113 @@ function getCodexHome() {
32
33
  if (process.env.CODEX_HOME) return process.env.CODEX_HOME;
33
34
  return path.join(os.homedir(), '.codex');
34
35
  }
36
+
37
+ function writeFileIfChanged(filePath, contents) {
38
+ if (fs.existsSync(filePath)) {
39
+ const current = fs.readFileSync(filePath, 'utf8');
40
+ if (current === contents) {
41
+ return false;
42
+ }
43
+ }
44
+ fs.mkdirSync(path.dirname(filePath), { recursive: true });
45
+ fs.writeFileSync(filePath, contents, 'utf8');
46
+ return true;
47
+ }
48
+
49
+ function mergeCodexHomeConfig(codexHome) {
50
+ const configPath = path.join(codexHome, 'config.toml');
51
+ const featureLines = [
52
+ '[features]',
53
+ 'codex_hooks = true',
54
+ 'multi_agent = true',
55
+ ];
56
+
57
+ if (!fs.existsSync(configPath)) {
58
+ writeFileIfChanged(
59
+ configPath,
60
+ [
61
+ 'approval_policy = "on-request"',
62
+ 'sandbox_mode = "workspace-write"',
63
+ '',
64
+ ...featureLines,
65
+ '',
66
+ ].join('\n')
67
+ );
68
+ console.log(`[babysitter-codex] wrote ${configPath}`);
69
+ return;
70
+ }
71
+
72
+ let content = fs.readFileSync(configPath, 'utf8');
73
+ if (!/^\s*codex_hooks\s*=.*$/m.test(content)) {
74
+ if (/^\[features\]\s*$/m.test(content)) {
75
+ content = content.replace(
76
+ /^\[features\]\s*$/m,
77
+ ['[features]', 'codex_hooks = true', 'multi_agent = true'].join('\n')
78
+ );
79
+ } else {
80
+ content = [content.trimEnd(), '', ...featureLines, ''].join('\n');
81
+ }
82
+ } else if (!/^\s*multi_agent\s*=.*$/m.test(content) && /^\[features\]\s*$/m.test(content)) {
83
+ content = content.replace(
84
+ /^\[features\]\s*$/m,
85
+ ['[features]', 'multi_agent = true'].join('\n')
86
+ );
87
+ }
88
+
89
+ if (writeFileIfChanged(configPath, content)) {
90
+ console.log(`[babysitter-codex] merged ${configPath}`);
91
+ }
92
+ }
93
+
94
+ function shouldAutoOnboardWorkspace(skillDir) {
95
+ const initCwd = process.env.INIT_CWD;
96
+ if (!initCwd) return null;
97
+
98
+ const resolved = path.resolve(initCwd);
99
+ if (!fs.existsSync(resolved)) return null;
100
+ if (!fs.statSync(resolved).isDirectory()) return null;
101
+
102
+ const normalizedWorkspace = resolved.toLowerCase();
103
+ const normalizedPackageRoot = PACKAGE_ROOT.toLowerCase();
104
+ const normalizedSkillDir = skillDir.toLowerCase();
105
+ if (normalizedWorkspace === normalizedPackageRoot || normalizedWorkspace === normalizedSkillDir) {
106
+ return null;
107
+ }
108
+
109
+ return resolved;
110
+ }
111
+
112
+ function autoOnboardWorkspace(skillDir) {
113
+ const workspace = shouldAutoOnboardWorkspace(skillDir);
114
+ if (!workspace) {
115
+ return;
116
+ }
117
+
118
+ const scriptPath = path.join(skillDir, 'scripts', 'team-install.js');
119
+ if (!fs.existsSync(scriptPath)) {
120
+ console.warn('[babysitter-codex] WARNING: team-install.js is missing; skipping workspace hook onboarding');
121
+ return;
122
+ }
123
+
124
+ const result = spawnSync(process.execPath, [scriptPath, '--workspace', workspace], {
125
+ cwd: workspace,
126
+ stdio: 'pipe',
127
+ encoding: 'utf8',
128
+ env: {
129
+ ...process.env,
130
+ BABYSITTER_PACKAGE_ROOT: skillDir,
131
+ },
132
+ });
133
+
134
+ if (result.status !== 0) {
135
+ console.warn(`[babysitter-codex] WARNING: workspace onboarding failed for ${workspace}`);
136
+ if (result.stdout) console.warn(result.stdout.trim());
137
+ if (result.stderr) console.warn(result.stderr.trim());
138
+ return;
139
+ }
140
+
141
+ console.log(`[babysitter-codex] onboarded workspace hooks/config at ${workspace}`);
142
+ }
35
143
 
36
144
  function copyRecursive(src, dest) {
37
145
  const stat = fs.statSync(src);
@@ -92,6 +200,7 @@ function main() {
92
200
  }
93
201
 
94
202
  verifyInstalledPayload(skillDir);
203
+ mergeCodexHomeConfig(codexHome);
95
204
 
96
205
  if (!IS_WIN) {
97
206
  const hookDir = path.join(skillDir, '.codex', 'hooks');
@@ -106,8 +215,10 @@ function main() {
106
215
  }
107
216
  }
108
217
 
218
+ autoOnboardWorkspace(skillDir);
219
+
109
220
  console.log('[babysitter-codex] Installation complete!');
110
- console.log('[babysitter-codex] Restart Codex to pick up the new skill.');
221
+ console.log('[babysitter-codex] Restart Codex to pick up the updated skill and hook config.');
111
222
  } catch (err) {
112
223
  console.error(`[babysitter-codex] Failed to install skill files: ${err.message}`);
113
224
  process.exitCode = 1;
package/docs/INSTALL.md CHANGED
@@ -3,12 +3,13 @@
3
3
  `babysitter-codex` installation has two layers:
4
4
 
5
5
  1. Install the global Codex skill payload into `~/.codex/skills/babysitter-codex`
6
- 2. Optionally apply workspace onboarding with `team-install` and
7
- `project-install`
6
+ 2. Materialize Codex hook/config wiring for the active workspace
8
7
 
9
- The second layer does not create a separate process-library universe. It adds
10
- config, profile, and pinned-content setup around the active process roots the
11
- runtime already uses.
8
+ When you run `npm install -g @a5c-ai/babysitter-codex` from inside the target
9
+ workspace, the postinstall now uses `INIT_CWD` to auto-apply the workspace
10
+ hook/config wiring. If you install from somewhere else, use
11
+ `babysitter harness:install-plugin codex --workspace <dir>` or the packaged
12
+ `team-install` helper afterwards.
12
13
 
13
14
  ## 1. Global Skill Install
14
15
 
@@ -59,6 +60,9 @@ Test-Path "$HOME/.codex/skills/babysitter-codex/.codex/hooks.json"
59
60
  Test-Path "$HOME/.codex/skills/babysitter-codex/.codex/hooks/babysitter-stop-hook.sh"
60
61
  ```
61
62
 
63
+ The installer also merges `~/.codex/config.toml` so `features.codex_hooks = true`
64
+ is present for the local Codex install.
65
+
62
66
  ## 3. Active Process Roots After Install
63
67
 
64
68
  After install, Codex-facing docs and processes should prefer:
@@ -70,10 +74,20 @@ After install, Codex-facing docs and processes should prefer:
70
74
 
71
75
  Do not document the bundled upstream snapshot as the primary library root.
72
76
 
73
- ## 4. Team And Project Onboarding
77
+ ## 4. Workspace Hook Onboarding
78
+
79
+ If the global install was not launched from the target workspace, materialize
80
+ the workspace-local `.codex/hooks.json` and `.codex/config.toml` after install:
81
+
82
+ ```bash
83
+ npm install -g @a5c-ai/babysitter-sdk
84
+ babysitter harness:install-plugin codex --workspace /path/to/repo
85
+ ```
86
+
87
+ `babysitter harness:install-plugin ...` is provided by the Babysitter SDK CLI,
88
+ so `@a5c-ai/babysitter-sdk` must already be installed.
74
89
 
75
- After the package is installed, use the Codex command surface from the target
76
- workspace:
90
+ Equivalent packaged helper:
77
91
 
78
92
  ```text
79
93
  babysitter team-install
@@ -89,9 +103,8 @@ This setup:
89
103
  Codex hook model
90
104
  - prepares the repo for Codex-facing Babysitter usage
91
105
 
92
- It should be described as layering pinned configuration and install metadata.
93
- It should not be described as moving process discovery into a team-only or
94
- project-only library root.
106
+ This onboarding layers pinned configuration and install metadata. It does not
107
+ move process discovery into a team-only or project-only library root.
95
108
 
96
109
  ## 5. First Run Expectations
97
110
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@a5c-ai/babysitter-codex",
3
- "version": "0.1.6-staging.dd5dc0db",
3
+ "version": "0.1.6-staging.e7446f7c",
4
4
  "description": "Babysitter Codex skill bundle and integration package for OpenAI Codex CLI - multi-step AI workflows with the upstream process library, 15 orchestration modes, and BOM-safe SKILL installation",
5
5
  "scripts": {
6
6
  "test": "node test/integration.test.js && node test/harness.test.js && node test/plugin.test.js && node test/packaged-install.test.js && node test/features-1-10.test.js && node test/process-mining.test.js",
@@ -60,6 +60,6 @@
60
60
  },
61
61
  "homepage": "https://github.com/a5c-ai/babysitter/tree/main/plugins/babysitter-codex#readme",
62
62
  "dependencies": {
63
- "@a5c-ai/babysitter-sdk": "0.0.183-staging.dd5dc0db"
63
+ "@a5c-ai/babysitter-sdk": "0.0.183-staging.e7446f7c"
64
64
  }
65
65
  }
@@ -69,6 +69,7 @@ try {
69
69
  env: {
70
70
  ...process.env,
71
71
  CODEX_HOME: codexHome,
72
+ INIT_CWD: workspaceRoot,
72
73
  },
73
74
  });
74
75
  assert.ok(installOutput.includes('Installation complete!'));
@@ -95,6 +96,11 @@ try {
95
96
  const installedSkill = fs.readFileSync(path.join(installedSkillRoot, 'SKILL.md'), 'utf8');
96
97
  assert.ok(installedSkill.includes('SessionStart'));
97
98
  assert.ok(installedSkill.includes('Stop'));
99
+ const homeConfig = fs.readFileSync(path.join(codexHome, 'config.toml'), 'utf8');
100
+ assert.ok(homeConfig.includes('codex_hooks = true'));
101
+ assert.ok(homeConfig.includes('multi_agent = true'));
102
+ assert.ok(fs.existsSync(path.join(workspaceRoot, '.codex', 'hooks.json')));
103
+ assert.ok(fs.existsSync(path.join(workspaceRoot, '.codex', 'config.toml')));
98
104
 
99
105
  const verifyOutput = run(process.execPath, [path.join(installedSkillRoot, 'scripts', 'verify-content-manifest.js')], {
100
106
  cwd: workspaceRoot,