@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.
- package/.codex/skills/babysit/SKILL.md +110 -0
- package/README.md +44 -26
- package/SKILL.md +38 -16
- package/agents/openai.yaml +4 -4
- package/bin/postinstall.js +188 -39
- package/bin/uninstall.js +80 -37
- package/package.json +3 -3
- package/prompts/README.md +28 -0
- package/prompts/assimilate.md +9 -0
- package/prompts/call.md +12 -0
- package/prompts/doctor.md +9 -0
- package/prompts/forever.md +8 -0
- package/prompts/help.md +8 -0
- package/prompts/issue.md +9 -0
- package/prompts/model.md +8 -0
- package/prompts/observe.md +8 -0
- package/prompts/plan.md +11 -0
- package/prompts/project-install.md +8 -0
- package/prompts/resume.md +8 -0
- package/prompts/retrospect.md +8 -0
- package/prompts/team-install.md +8 -0
- package/prompts/user-install.md +8 -0
- package/prompts/yolo.md +8 -0
- package/scripts/team-install.js +147 -56
- package/.codex/skills/babysitter/assimilate/SKILL.md +0 -58
- package/.codex/skills/babysitter/call/SKILL.md +0 -588
- package/.codex/skills/babysitter/doctor/SKILL.md +0 -89
- package/.codex/skills/babysitter/forever/SKILL.md +0 -45
- package/.codex/skills/babysitter/help/SKILL.md +0 -48
- package/.codex/skills/babysitter/issue/SKILL.md +0 -36
- package/.codex/skills/babysitter/model/SKILL.md +0 -31
- package/.codex/skills/babysitter/observe/SKILL.md +0 -38
- package/.codex/skills/babysitter/plan/SKILL.md +0 -44
- package/.codex/skills/babysitter/project-install/SKILL.md +0 -62
- package/.codex/skills/babysitter/resume/SKILL.md +0 -30
- package/.codex/skills/babysitter/retrospect/SKILL.md +0 -43
- package/.codex/skills/babysitter/team-install/SKILL.md +0 -35
- package/.codex/skills/babysitter/user-install/SKILL.md +0 -53
- package/.codex/skills/babysitter/yolo/SKILL.md +0 -48
- package/commands/README.md +0 -23
- package/commands/assimilate.md +0 -26
- package/commands/call.md +0 -29
- package/commands/doctor.md +0 -27
- package/commands/forever.md +0 -26
- package/commands/help.md +0 -27
- package/commands/issue.md +0 -26
- package/commands/model.md +0 -26
- package/commands/observe.md +0 -26
- package/commands/plan.md +0 -26
- package/commands/project-install.md +0 -30
- package/commands/resume.md +0 -28
- package/commands/retrospect.md +0 -26
- package/commands/team-install.md +0 -28
- package/commands/user-install.md +0 -26
- 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/
|
|
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
|
-
- `
|
|
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.
|
|
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
|
-
|
|
86
|
+
7. Binds `<workspace>/.a5c/process-library/babysitter-repo/library` with
|
|
77
87
|
`babysitter process-library:use`.
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
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
|
-
|
|
83
|
-
|
|
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
|
|
116
|
+
Use the skill directly:
|
|
102
117
|
|
|
103
118
|
```text
|
|
104
|
-
|
|
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
|
|
112
|
-
|
|
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/
|
|
121
|
-
test -f ~/.codex/skills/
|
|
122
|
-
test -f ~/.codex/skills/
|
|
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:
|
|
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/
|
|
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
|
-
|
|
29
|
-
|
|
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
|
-
|
|
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.
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
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
|
|
99
|
-
-
|
|
100
|
-
|
|
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
|
package/agents/openai.yaml
CHANGED
|
@@ -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 $
|
|
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"
|
package/bin/postinstall.js
CHANGED
|
@@ -1,35 +1,48 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
'use strict';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* postinstall.js
|
|
6
|
-
*
|
|
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 = '
|
|
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: '
|
|
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
|
|
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!');
|