@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 +19 -1
- package/bin/postinstall.js +114 -3
- package/docs/INSTALL.md +24 -11
- package/package.json +2 -2
- package/test/packaged-install.test.js +6 -0
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
|
package/bin/postinstall.js
CHANGED
|
@@ -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
|
|
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.
|
|
7
|
-
`project-install`
|
|
6
|
+
2. Materialize Codex hook/config wiring for the active workspace
|
|
8
7
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
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.
|
|
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
|
-
|
|
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
|
-
|
|
93
|
-
|
|
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.
|
|
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.
|
|
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,
|