@a5c-ai/babysitter-codex 5.0.1-staging.e4f17eff → 5.0.1-staging.ef4e872c
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-plugin/plugin.json +14 -12
- package/README.md +1 -1
- package/bin/cli.js +8 -16
- package/bin/install-shared.js +333 -50
- package/bin/install.js +12 -29
- package/bin/uninstall.js +11 -27
- package/hooks/babysitter-proxied-session-start.sh +7 -162
- package/hooks/babysitter-proxied-stop.sh +3 -0
- package/hooks/babysitter-proxied-user-prompt-submit.sh +2 -88
- package/hooks.json +5 -5
- package/package.json +10 -13
- package/scripts/sync-command-skills.js +1 -0
- package/scripts/team-install.js +14 -78
- package/skills/cleanup/SKILL.md +21 -0
- package/skills/contrib/SKILL.md +34 -0
- package/skills/doctor/SKILL.md +5 -5
- package/skills/help/SKILL.md +3 -2
- package/skills/observe/SKILL.md +1 -1
- package/skills/plugins/SKILL.md +257 -0
- package/skills/project-install/SKILL.md +3 -3
- package/skills/resume/SKILL.md +1 -1
- package/skills/retrospect/SKILL.md +48 -48
- package/skills/user-install/SKILL.md +3 -3
- package/hooks/babysitter-proxied-stop-hook.sh +0 -103
- package/hooks/babysitter-session-start.sh +0 -45
- package/hooks/babysitter-stop-hook.sh +0 -45
- package/hooks/proxied-hooks.json +0 -38
- package/hooks/user-prompt-submit.sh +0 -34
- package/skills/issue/SKILL.md +0 -16
- package/skills/model/SKILL.md +0 -15
- package/skills/team-install/SKILL.md +0 -15
|
@@ -1,21 +1,23 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "babysitter",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "5.0.0",
|
|
4
|
+
"description": "Orchestrate complex, multi-step workflows with event-sourced state management, hook-based extensibility, and human-in-the-loop approval",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "a5c.ai",
|
|
7
|
-
"email": "support@a5c.ai"
|
|
8
|
-
"url": "https://github.com/a5c-ai/babysitter"
|
|
7
|
+
"email": "support@a5c.ai"
|
|
9
8
|
},
|
|
10
|
-
"homepage": "https://github.com/a5c-ai/babysitter/tree/main/plugins/babysitter-codex#readme",
|
|
11
|
-
"repository": "https://github.com/a5c-ai/babysitter",
|
|
12
9
|
"license": "MIT",
|
|
10
|
+
"repository": "https://github.com/a5c-ai/babysitter",
|
|
13
11
|
"keywords": [
|
|
14
|
-
"babysitter",
|
|
15
|
-
"codex",
|
|
16
12
|
"orchestration",
|
|
13
|
+
"workflow",
|
|
14
|
+
"automation",
|
|
15
|
+
"event-sourced",
|
|
17
16
|
"hooks",
|
|
18
|
-
"
|
|
17
|
+
"TDD",
|
|
18
|
+
"quality-convergence",
|
|
19
|
+
"agent",
|
|
20
|
+
"LLM"
|
|
19
21
|
],
|
|
20
22
|
"skills": "./skills/",
|
|
21
23
|
"hooks": "./hooks.json",
|
|
@@ -41,7 +43,7 @@
|
|
|
41
43
|
],
|
|
42
44
|
"brandColor": "#0F766E",
|
|
43
45
|
"composerIcon": "./assets/icon.svg",
|
|
44
|
-
"logo": "./assets/logo.png"
|
|
45
|
-
|
|
46
|
-
|
|
46
|
+
"logo": "./assets/logo.png"
|
|
47
|
+
},
|
|
48
|
+
"homepage": "https://github.com/a5c-ai/babysitter/tree/main/plugins/babysitter-codex#readme"
|
|
47
49
|
}
|
package/README.md
CHANGED
|
@@ -74,7 +74,7 @@ Verify the installed plugin bundle:
|
|
|
74
74
|
npm ls -g @a5c-ai/babysitter-codex --depth=0
|
|
75
75
|
test -f ~/.agents/plugins/babysitter/.codex-plugin/plugin.json
|
|
76
76
|
test -f ~/.agents/plugins/babysitter/hooks.json
|
|
77
|
-
test -f ~/.agents/plugins/babysitter/hooks/babysitter-stop
|
|
77
|
+
test -f ~/.agents/plugins/babysitter/hooks/babysitter-proxied-stop.sh
|
|
78
78
|
test -f ~/.agents/plugins/babysitter/skills/babysit/SKILL.md
|
|
79
79
|
test -f ~/.agents/plugins/marketplace.json
|
|
80
80
|
```
|
package/bin/cli.js
CHANGED
|
@@ -5,6 +5,8 @@ const path = require('path');
|
|
|
5
5
|
const { spawnSync } = require('child_process');
|
|
6
6
|
|
|
7
7
|
const PACKAGE_ROOT = path.resolve(__dirname, '..');
|
|
8
|
+
let shared;
|
|
9
|
+
try { shared = require('./install-shared'); } catch {}
|
|
8
10
|
|
|
9
11
|
function printUsage() {
|
|
10
12
|
console.error([
|
|
@@ -23,16 +25,10 @@ function parseInstallArgs(argv) {
|
|
|
23
25
|
for (let i = 0; i < argv.length; i += 1) {
|
|
24
26
|
const arg = argv[i];
|
|
25
27
|
if (arg === '--global') {
|
|
26
|
-
if (scope === 'workspace') {
|
|
27
|
-
throw new Error('install accepts either --global or --workspace, not both');
|
|
28
|
-
}
|
|
29
28
|
scope = 'global';
|
|
30
29
|
continue;
|
|
31
30
|
}
|
|
32
31
|
if (arg === '--workspace') {
|
|
33
|
-
if (scope === 'global' && workspace !== null) {
|
|
34
|
-
throw new Error('install accepts either --global or --workspace, not both');
|
|
35
|
-
}
|
|
36
32
|
scope = 'workspace';
|
|
37
33
|
const next = argv[i + 1];
|
|
38
34
|
if (next && !next.startsWith('-')) {
|
|
@@ -46,21 +42,14 @@ function parseInstallArgs(argv) {
|
|
|
46
42
|
passthrough.push(arg);
|
|
47
43
|
}
|
|
48
44
|
|
|
49
|
-
return {
|
|
50
|
-
scope,
|
|
51
|
-
workspace,
|
|
52
|
-
passthrough,
|
|
53
|
-
};
|
|
45
|
+
return { scope, workspace, passthrough };
|
|
54
46
|
}
|
|
55
47
|
|
|
56
48
|
function runNodeScript(scriptPath, args, extraEnv = {}) {
|
|
57
49
|
const result = spawnSync(process.execPath, [scriptPath, ...args], {
|
|
58
50
|
cwd: process.cwd(),
|
|
59
51
|
stdio: 'inherit',
|
|
60
|
-
env: {
|
|
61
|
-
...process.env,
|
|
62
|
-
...extraEnv,
|
|
63
|
-
},
|
|
52
|
+
env: { ...process.env, ...extraEnv },
|
|
64
53
|
});
|
|
65
54
|
process.exitCode = result.status ?? 1;
|
|
66
55
|
}
|
|
@@ -74,6 +63,9 @@ function main() {
|
|
|
74
63
|
}
|
|
75
64
|
|
|
76
65
|
if (command === 'install') {
|
|
66
|
+
if (shared && typeof shared.harnessCliRoute === 'function' && shared.harnessCliRoute(rest, PACKAGE_ROOT, runNodeScript)) {
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
77
69
|
const parsed = parseInstallArgs(rest);
|
|
78
70
|
if (parsed.scope === 'workspace') {
|
|
79
71
|
const args = [];
|
|
@@ -84,7 +76,7 @@ function main() {
|
|
|
84
76
|
runNodeScript(
|
|
85
77
|
path.join(PACKAGE_ROOT, 'scripts', 'team-install.js'),
|
|
86
78
|
args,
|
|
87
|
-
{
|
|
79
|
+
{ PLUGIN_PACKAGE_ROOT: PACKAGE_ROOT },
|
|
88
80
|
);
|
|
89
81
|
return;
|
|
90
82
|
}
|
package/bin/install-shared.js
CHANGED
|
@@ -5,8 +5,195 @@ const os = require('os');
|
|
|
5
5
|
const path = require('path');
|
|
6
6
|
const { spawnSync } = require('child_process');
|
|
7
7
|
|
|
8
|
-
const PLUGIN_NAME =
|
|
8
|
+
const PLUGIN_NAME = "babysitter";
|
|
9
9
|
const PLUGIN_CATEGORY = 'Coding';
|
|
10
|
+
|
|
11
|
+
function getUserHome() {
|
|
12
|
+
return os.homedir();
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function getHarnessHome() {
|
|
16
|
+
return path.join(os.homedir(), ".codex");
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function getHomePluginRoot(scope) {
|
|
20
|
+
if (scope === 'workspace') return path.join(process.cwd(), '.a5c', 'plugins', PLUGIN_NAME);
|
|
21
|
+
return path.join(path.join(os.homedir(), ".agents/plugins"), PLUGIN_NAME);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function getHomeMarketplacePath() {
|
|
25
|
+
return path.join(os.homedir(), ".agents/plugins/marketplace.json");
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function writeFileIfChanged(filePath, contents) {
|
|
29
|
+
try {
|
|
30
|
+
const existing = fs.readFileSync(filePath, 'utf8');
|
|
31
|
+
if (existing === contents) return false;
|
|
32
|
+
} catch {}
|
|
33
|
+
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
34
|
+
fs.writeFileSync(filePath, contents);
|
|
35
|
+
return true;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function copyRecursive(src, dest) {
|
|
39
|
+
fs.mkdirSync(dest, { recursive: true });
|
|
40
|
+
for (const entry of fs.readdirSync(src, { withFileTypes: true })) {
|
|
41
|
+
if (entry.name === 'node_modules' || entry.name === '.git') continue;
|
|
42
|
+
const s = path.join(src, entry.name);
|
|
43
|
+
const d = path.join(dest, entry.name);
|
|
44
|
+
if (entry.isDirectory()) {
|
|
45
|
+
copyRecursive(s, d);
|
|
46
|
+
} else {
|
|
47
|
+
fs.copyFileSync(s, d);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function copyPluginBundle(packageRoot, pluginRoot) {
|
|
53
|
+
const bundleEntries = fs.readdirSync(packageRoot).filter(
|
|
54
|
+
e => !['node_modules', '.git', 'test', 'dist'].includes(e)
|
|
55
|
+
);
|
|
56
|
+
fs.mkdirSync(pluginRoot, { recursive: true });
|
|
57
|
+
for (const entry of bundleEntries) {
|
|
58
|
+
const src = path.join(packageRoot, entry);
|
|
59
|
+
const dest = path.join(pluginRoot, entry);
|
|
60
|
+
const stat = fs.statSync(src);
|
|
61
|
+
if (stat.isDirectory()) {
|
|
62
|
+
copyRecursive(src, dest);
|
|
63
|
+
} else {
|
|
64
|
+
fs.copyFileSync(src, dest);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function readJson(filePath) {
|
|
70
|
+
try {
|
|
71
|
+
return JSON.parse(fs.readFileSync(filePath, 'utf8'));
|
|
72
|
+
} catch {
|
|
73
|
+
return null;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function writeJson(filePath, value) {
|
|
78
|
+
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
79
|
+
fs.writeFileSync(filePath, JSON.stringify(value, null, 2) + '\n');
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function ensureExecutable(filePath) {
|
|
83
|
+
try {
|
|
84
|
+
fs.chmodSync(filePath, 0o755);
|
|
85
|
+
} catch {}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function normalizeMarketplaceSourcePath(source, marketplacePath) {
|
|
89
|
+
if (typeof source === 'string') {
|
|
90
|
+
return path.relative(path.dirname(marketplacePath), source).replace(/\\/g, '/');
|
|
91
|
+
}
|
|
92
|
+
return source;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function ensureMarketplaceEntry(marketplacePath, pluginRoot) {
|
|
96
|
+
let marketplace = readJson(marketplacePath) || {
|
|
97
|
+
name: "a5c.ai",
|
|
98
|
+
plugins: [],
|
|
99
|
+
};
|
|
100
|
+
if (!Array.isArray(marketplace.plugins)) marketplace.plugins = [];
|
|
101
|
+
const idx = marketplace.plugins.findIndex(p => p.name === PLUGIN_NAME);
|
|
102
|
+
const relSource = './' + normalizeMarketplaceSourcePath(pluginRoot, marketplacePath);
|
|
103
|
+
const entry = {
|
|
104
|
+
name: PLUGIN_NAME,
|
|
105
|
+
source: relSource,
|
|
106
|
+
description: "Orchestrate complex, multi-step workflows with event-sourced state management, hook-based extensibility, and human-in-the-loop approval",
|
|
107
|
+
version: "5.0.0",
|
|
108
|
+
author: { name: "a5c.ai" },
|
|
109
|
+
};
|
|
110
|
+
if (idx >= 0) marketplace.plugins[idx] = entry;
|
|
111
|
+
else marketplace.plugins.push(entry);
|
|
112
|
+
writeJson(marketplacePath, marketplace);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function removeMarketplaceEntry(marketplacePath) {
|
|
116
|
+
const marketplace = readJson(marketplacePath);
|
|
117
|
+
if (!marketplace || !Array.isArray(marketplace.plugins)) return;
|
|
118
|
+
marketplace.plugins = marketplace.plugins.filter(p => p.name !== PLUGIN_NAME);
|
|
119
|
+
writeJson(marketplacePath, marketplace);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function warnWindowsHooks() {
|
|
123
|
+
if (process.platform === 'win32') {
|
|
124
|
+
console.warn('[' + PLUGIN_NAME + '] Windows detected — shell hooks (.sh) require Git Bash or WSL.');
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
function runPostInstall(pluginRoot) {
|
|
129
|
+
const postInstall = path.join(pluginRoot, 'scripts', 'post-install.js');
|
|
130
|
+
if (fs.existsSync(postInstall)) {
|
|
131
|
+
spawnSync(process.execPath, [postInstall], {
|
|
132
|
+
cwd: pluginRoot, stdio: 'inherit',
|
|
133
|
+
env: { ...process.env, PLUGIN_ROOT: pluginRoot },
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
function getGlobalStateDir() {
|
|
139
|
+
return process.env.BABYSITTER_GLOBAL_STATE_DIR || path.join(getUserHome(), '.a5c');
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
function resolveCliCommand(packageRoot) {
|
|
143
|
+
try {
|
|
144
|
+
const result = spawnSync('babysitter', ['--version'], { stdio: 'pipe', timeout: 10000 });
|
|
145
|
+
if (result.status === 0) return 'babysitter';
|
|
146
|
+
} catch {}
|
|
147
|
+
const versionsPath = path.join(packageRoot, 'versions.json');
|
|
148
|
+
const versions = readJson(versionsPath) || {};
|
|
149
|
+
const ver = versions.sdkVersion || 'latest';
|
|
150
|
+
return `npx -y @a5c-ai/babysitter-sdk@${ver}`;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
function runCli(packageRoot, cliArgs, options = {}) {
|
|
154
|
+
const cmd = resolveCliCommand(packageRoot);
|
|
155
|
+
const parts = cmd.split(' ');
|
|
156
|
+
const result = spawnSync(parts[0], [...parts.slice(1), ...cliArgs], {
|
|
157
|
+
stdio: options.stdio || 'inherit',
|
|
158
|
+
timeout: options.timeout || 120000,
|
|
159
|
+
cwd: options.cwd || process.cwd(),
|
|
160
|
+
env: { ...process.env, ...options.env },
|
|
161
|
+
});
|
|
162
|
+
return result;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
function ensureGlobalProcessLibrary(packageRoot) {
|
|
166
|
+
const stateDir = getGlobalStateDir();
|
|
167
|
+
const activeFile = path.join(stateDir, 'active', 'process-library.json');
|
|
168
|
+
let active = readJson(activeFile);
|
|
169
|
+
if (active && active.binding && active.binding.dir) {
|
|
170
|
+
return active;
|
|
171
|
+
}
|
|
172
|
+
const defaultSpec = readJson(path.join(stateDir, 'process-library-defaults.json'));
|
|
173
|
+
const cloneDir = defaultSpec && defaultSpec.cloneDir
|
|
174
|
+
? defaultSpec.cloneDir
|
|
175
|
+
: path.join(stateDir, 'process-library', PLUGIN_NAME + '-repo');
|
|
176
|
+
runCli(packageRoot, [
|
|
177
|
+
'process-library:clone',
|
|
178
|
+
'--dir', cloneDir,
|
|
179
|
+
'--state-dir', stateDir,
|
|
180
|
+
'--json',
|
|
181
|
+
], { stdio: 'pipe' });
|
|
182
|
+
runCli(packageRoot, [
|
|
183
|
+
'process-library:use',
|
|
184
|
+
'--dir', cloneDir,
|
|
185
|
+
'--state-dir', stateDir,
|
|
186
|
+
'--json',
|
|
187
|
+
], { stdio: 'pipe' });
|
|
188
|
+
active = readJson(activeFile);
|
|
189
|
+
return {
|
|
190
|
+
binding: active && active.binding ? active.binding : { dir: cloneDir },
|
|
191
|
+
defaultSpec: defaultSpec || { cloneDir },
|
|
192
|
+
stateFile: activeFile,
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
|
|
10
197
|
const LEGACY_MARKETPLACE_PLUGIN_NAMES = ['babysitter-codex'];
|
|
11
198
|
const LEGACY_SKILL_NAMES = [
|
|
12
199
|
'babysit',
|
|
@@ -50,6 +237,11 @@ const LEGACY_HOOK_SCRIPT_NAMES = [
|
|
|
50
237
|
'babysitter-stop-hook.sh',
|
|
51
238
|
'user-prompt-submit.sh',
|
|
52
239
|
];
|
|
240
|
+
const MANAGED_HOOK_SCRIPT_NAMES = [
|
|
241
|
+
'babysitter-proxied-session-start.sh',
|
|
242
|
+
'babysitter-proxied-stop.sh',
|
|
243
|
+
'babysitter-proxied-user-prompt-submit.sh',
|
|
244
|
+
];
|
|
53
245
|
const DEFAULT_MARKETPLACE = {
|
|
54
246
|
name: 'local-plugins',
|
|
55
247
|
interface: {
|
|
@@ -73,19 +265,6 @@ function getCodexHome() {
|
|
|
73
265
|
return path.join(os.homedir(), '.codex');
|
|
74
266
|
}
|
|
75
267
|
|
|
76
|
-
function getUserHome() {
|
|
77
|
-
if (process.env.USERPROFILE) return path.resolve(process.env.USERPROFILE);
|
|
78
|
-
if (process.env.HOME) return path.resolve(process.env.HOME);
|
|
79
|
-
return os.homedir();
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
function getGlobalStateDir() {
|
|
83
|
-
if (process.env.BABYSITTER_GLOBAL_STATE_DIR) {
|
|
84
|
-
return path.resolve(process.env.BABYSITTER_GLOBAL_STATE_DIR);
|
|
85
|
-
}
|
|
86
|
-
return path.join(getUserHome(), '.a5c');
|
|
87
|
-
}
|
|
88
|
-
|
|
89
268
|
function getHomePluginRoot() {
|
|
90
269
|
if (process.env.BABYSITTER_CODEX_PLUGIN_DIR) {
|
|
91
270
|
return path.resolve(process.env.BABYSITTER_CODEX_PLUGIN_DIR, PLUGIN_NAME);
|
|
@@ -100,6 +279,14 @@ function getHomeMarketplacePath() {
|
|
|
100
279
|
return path.join(getUserHome(), '.agents', 'plugins', 'marketplace.json');
|
|
101
280
|
}
|
|
102
281
|
|
|
282
|
+
function getWorkspacePluginRoot(workspaceRoot) {
|
|
283
|
+
return path.join(path.resolve(workspaceRoot), '.agents', 'plugins', PLUGIN_NAME);
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
function getWorkspaceMarketplacePath(workspaceRoot) {
|
|
287
|
+
return path.join(path.resolve(workspaceRoot), '.agents', 'plugins', 'marketplace.json');
|
|
288
|
+
}
|
|
289
|
+
|
|
103
290
|
function renderCodexConfigToml() {
|
|
104
291
|
return [
|
|
105
292
|
'approval_policy = "on-request"',
|
|
@@ -120,18 +307,6 @@ function renderCodexConfigToml() {
|
|
|
120
307
|
].join('\n');
|
|
121
308
|
}
|
|
122
309
|
|
|
123
|
-
function writeFileIfChanged(filePath, contents) {
|
|
124
|
-
if (fs.existsSync(filePath)) {
|
|
125
|
-
const current = fs.readFileSync(filePath, 'utf8');
|
|
126
|
-
if (current === contents) {
|
|
127
|
-
return false;
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
131
|
-
fs.writeFileSync(filePath, contents, 'utf8');
|
|
132
|
-
return true;
|
|
133
|
-
}
|
|
134
|
-
|
|
135
310
|
function copyRecursive(src, dest) {
|
|
136
311
|
const stat = fs.statSync(src);
|
|
137
312
|
if (stat.isDirectory()) {
|
|
@@ -292,29 +467,60 @@ function runBabysitterCli(packageRoot, cliArgs, options = {}) {
|
|
|
292
467
|
}
|
|
293
468
|
|
|
294
469
|
function ensureGlobalProcessLibrary(packageRoot) {
|
|
295
|
-
|
|
470
|
+
const stateDir = getGlobalStateDir();
|
|
471
|
+
const activeFile = path.join(stateDir, 'active', 'process-library.json');
|
|
472
|
+
const current = readJson(activeFile);
|
|
473
|
+
if (current && current.defaultBinding && current.defaultBinding.dir) {
|
|
474
|
+
return {
|
|
475
|
+
stateFile: activeFile,
|
|
476
|
+
binding: current.defaultBinding,
|
|
477
|
+
defaultSpec: {
|
|
478
|
+
stateDir,
|
|
479
|
+
repo: current.defaultBinding.repoUrl,
|
|
480
|
+
cloneDir: current.defaultBinding.dir,
|
|
481
|
+
},
|
|
482
|
+
};
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
const cloneDir = path.join(stateDir, 'process-library', `${PLUGIN_NAME}-repo`);
|
|
486
|
+
runBabysitterCli(
|
|
487
|
+
packageRoot,
|
|
488
|
+
[
|
|
489
|
+
'process-library:clone',
|
|
490
|
+
'--dir', cloneDir,
|
|
491
|
+
'--state-dir', stateDir,
|
|
492
|
+
'--json',
|
|
493
|
+
],
|
|
494
|
+
{ cwd: packageRoot },
|
|
495
|
+
);
|
|
496
|
+
runBabysitterCli(
|
|
497
|
+
packageRoot,
|
|
498
|
+
[
|
|
499
|
+
'process-library:use',
|
|
500
|
+
'--dir', cloneDir,
|
|
501
|
+
'--state-dir', stateDir,
|
|
502
|
+
'--json',
|
|
503
|
+
],
|
|
504
|
+
{ cwd: packageRoot },
|
|
505
|
+
);
|
|
506
|
+
|
|
507
|
+
const active = JSON.parse(
|
|
296
508
|
runBabysitterCli(
|
|
297
509
|
packageRoot,
|
|
298
|
-
['process-library:active', '--state-dir',
|
|
510
|
+
['process-library:active', '--state-dir', stateDir, '--json'],
|
|
299
511
|
{ cwd: packageRoot },
|
|
300
512
|
),
|
|
301
513
|
);
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
function readJson(filePath) {
|
|
305
|
-
return JSON.parse(fs.readFileSync(filePath, 'utf8'));
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
function writeJson(filePath, value) {
|
|
309
|
-
writeFileIfChanged(filePath, `${JSON.stringify(value, null, 2)}\n`);
|
|
310
|
-
}
|
|
311
514
|
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
515
|
+
return {
|
|
516
|
+
stateFile: active.stateFile || activeFile,
|
|
517
|
+
binding: active.binding || active.defaultBinding || { dir: cloneDir },
|
|
518
|
+
defaultSpec: active.defaultSpec || {
|
|
519
|
+
stateDir,
|
|
520
|
+
repo: process.env.BABYSITTER_PROCESS_LIBRARY_REPO || null,
|
|
521
|
+
cloneDir,
|
|
522
|
+
},
|
|
523
|
+
};
|
|
318
524
|
}
|
|
319
525
|
|
|
320
526
|
function getMarketplaceRootDir(marketplacePath) {
|
|
@@ -483,7 +689,7 @@ function installManagedHooks(packageRoot, codexHome) {
|
|
|
483
689
|
const targetRoot = path.join(codexHome, 'hooks');
|
|
484
690
|
fs.mkdirSync(targetRoot, { recursive: true });
|
|
485
691
|
|
|
486
|
-
for (const scriptName of
|
|
692
|
+
for (const scriptName of MANAGED_HOOK_SCRIPT_NAMES) {
|
|
487
693
|
const sourcePath = path.join(sourceRoot, scriptName);
|
|
488
694
|
const targetPath = path.join(targetRoot, scriptName);
|
|
489
695
|
copyRecursive(sourcePath, targetPath);
|
|
@@ -499,6 +705,46 @@ function installCodexSurface(packageRoot, codexHome) {
|
|
|
499
705
|
installManagedHooks(packageRoot, codexHome);
|
|
500
706
|
}
|
|
501
707
|
|
|
708
|
+
function harnessTeamInstall(packageRoot, pluginRoot, workspace) {
|
|
709
|
+
var workspaceRoot = path.resolve(workspace);
|
|
710
|
+
var resolvedPluginRoot = pluginRoot ? path.resolve(pluginRoot) : getWorkspacePluginRoot(workspaceRoot);
|
|
711
|
+
var marketplacePath = getWorkspaceMarketplacePath(workspaceRoot);
|
|
712
|
+
var codexHome = path.join(workspaceRoot, '.codex');
|
|
713
|
+
var codexConfigPath = path.join(codexHome, 'config.toml');
|
|
714
|
+
var teamDir = path.join(workspaceRoot, '.a5c', 'team');
|
|
715
|
+
|
|
716
|
+
var processLibraryState = ensureGlobalProcessLibrary(packageRoot);
|
|
717
|
+
ensureMarketplaceEntry(marketplacePath, resolvedPluginRoot);
|
|
718
|
+
mergeCodexConfigFile(codexConfigPath);
|
|
719
|
+
installCodexSurface(packageRoot, codexHome);
|
|
720
|
+
warnWindowsHooks();
|
|
721
|
+
|
|
722
|
+
writeJson(path.join(teamDir, 'install.json'), {
|
|
723
|
+
packageRoot: packageRoot,
|
|
724
|
+
workspaceRoot: workspaceRoot,
|
|
725
|
+
pluginRoot: resolvedPluginRoot,
|
|
726
|
+
marketplacePath: marketplacePath,
|
|
727
|
+
codexConfigPath: codexConfigPath,
|
|
728
|
+
processLibraryCloneDir: (processLibraryState.defaultSpec && processLibraryState.defaultSpec.cloneDir)
|
|
729
|
+
|| (processLibraryState.binding && processLibraryState.binding.dir),
|
|
730
|
+
processLibraryStateFile: processLibraryState.stateFile
|
|
731
|
+
|| path.join(getGlobalStateDir(), 'active', 'process-library.json'),
|
|
732
|
+
});
|
|
733
|
+
writeJson(path.join(teamDir, 'profile.json'), {
|
|
734
|
+
pluginRoot: resolvedPluginRoot,
|
|
735
|
+
marketplacePath: marketplacePath,
|
|
736
|
+
codexConfigPath: codexConfigPath,
|
|
737
|
+
processLibraryLookupCommand: 'babysitter process-library:active --json',
|
|
738
|
+
});
|
|
739
|
+
}
|
|
740
|
+
|
|
741
|
+
function harnessInstall(packageRoot, _pluginRoot) {
|
|
742
|
+
const codexConfigPath = path.join(getCodexHome(), 'config.toml');
|
|
743
|
+
mergeCodexConfigFile(codexConfigPath);
|
|
744
|
+
ensureGlobalProcessLibrary(packageRoot);
|
|
745
|
+
warnWindowsHooks();
|
|
746
|
+
}
|
|
747
|
+
|
|
502
748
|
function warnWindowsHooks() {
|
|
503
749
|
if (process.platform !== 'win32') {
|
|
504
750
|
return;
|
|
@@ -510,17 +756,54 @@ function warnWindowsHooks() {
|
|
|
510
756
|
console.warn('[babysitter] If hooks do not fire, run `codex --version` and upgrade if you are below 0.119.0.');
|
|
511
757
|
}
|
|
512
758
|
|
|
759
|
+
|
|
513
760
|
module.exports = {
|
|
514
|
-
|
|
761
|
+
PLUGIN_NAME,
|
|
762
|
+
PLUGIN_CATEGORY,
|
|
763
|
+
getUserHome,
|
|
764
|
+
getHarnessHome,
|
|
765
|
+
writeFileIfChanged,
|
|
766
|
+
readJson,
|
|
767
|
+
writeJson,
|
|
768
|
+
ensureExecutable,
|
|
769
|
+
runPostInstall,
|
|
770
|
+
getGlobalStateDir,
|
|
771
|
+
resolveCliCommand,
|
|
772
|
+
runCli,
|
|
515
773
|
ensureGlobalProcessLibrary,
|
|
774
|
+
PLUGIN_BUNDLE_ENTRIES,
|
|
775
|
+
copyRecursive,
|
|
776
|
+
copyPluginBundle,
|
|
777
|
+
DEFAULT_MARKETPLACE,
|
|
778
|
+
normalizeMarketplaceSourcePath,
|
|
516
779
|
ensureMarketplaceEntry,
|
|
780
|
+
removeMarketplaceEntry,
|
|
781
|
+
installManagedSkills,
|
|
782
|
+
mergeManagedHooksConfig,
|
|
783
|
+
installManagedHooks,
|
|
784
|
+
warnWindowsHooks,
|
|
785
|
+
LEGACY_MARKETPLACE_PLUGIN_NAMES,
|
|
786
|
+
LEGACY_SKILL_NAMES,
|
|
787
|
+
LEGACY_PROMPT_NAMES,
|
|
788
|
+
LEGACY_HOOK_SCRIPT_NAMES,
|
|
789
|
+
MANAGED_HOOK_SCRIPT_NAMES,
|
|
517
790
|
getCodexHome,
|
|
518
|
-
getHomeMarketplacePath,
|
|
519
791
|
getHomePluginRoot,
|
|
520
|
-
|
|
792
|
+
getHomeMarketplacePath,
|
|
793
|
+
getWorkspacePluginRoot,
|
|
794
|
+
getWorkspaceMarketplacePath,
|
|
795
|
+
renderCodexConfigToml,
|
|
796
|
+
insertRootKey,
|
|
797
|
+
ensureSectionLine,
|
|
798
|
+
ensureWritableRoots,
|
|
799
|
+
mergeCodexConfig,
|
|
521
800
|
mergeCodexConfigFile,
|
|
801
|
+
resolveBabysitterCommand,
|
|
802
|
+
runBabysitterCli,
|
|
803
|
+
ensureGlobalProcessLibrary,
|
|
804
|
+
getMarketplaceRootDir,
|
|
522
805
|
removeLegacyCodexSurface,
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
806
|
+
installCodexSurface,
|
|
807
|
+
harnessInstall,
|
|
808
|
+
harnessTeamInstall,
|
|
526
809
|
};
|
package/bin/install.js
CHANGED
|
@@ -2,44 +2,27 @@
|
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
4
|
const path = require('path');
|
|
5
|
-
const
|
|
6
|
-
copyPluginBundle,
|
|
7
|
-
ensureGlobalProcessLibrary,
|
|
8
|
-
ensureMarketplaceEntry,
|
|
9
|
-
getCodexHome,
|
|
10
|
-
getHomeMarketplacePath,
|
|
11
|
-
getHomePluginRoot,
|
|
12
|
-
mergeCodexConfigFile,
|
|
13
|
-
warnWindowsHooks,
|
|
14
|
-
} = require('./install-shared');
|
|
5
|
+
const shared = require('./install-shared');
|
|
15
6
|
|
|
16
7
|
const PACKAGE_ROOT = path.resolve(__dirname, '..');
|
|
17
8
|
|
|
18
9
|
function main() {
|
|
19
|
-
const
|
|
20
|
-
const
|
|
21
|
-
const marketplacePath = getHomeMarketplacePath();
|
|
10
|
+
const pluginRoot = shared.getHomePluginRoot();
|
|
11
|
+
const marketplacePath = shared.getHomeMarketplacePath();
|
|
22
12
|
|
|
23
|
-
console.log(`[
|
|
13
|
+
console.log(`[${shared.PLUGIN_NAME}] Installing plugin to ${pluginRoot}`);
|
|
24
14
|
|
|
25
15
|
try {
|
|
26
|
-
copyPluginBundle(PACKAGE_ROOT, pluginRoot);
|
|
27
|
-
ensureMarketplaceEntry(marketplacePath, pluginRoot);
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
const active = ensureGlobalProcessLibrary(PACKAGE_ROOT);
|
|
31
|
-
console.log(`[babysitter] marketplace: ${marketplacePath}`);
|
|
32
|
-
console.log(`[babysitter] process library: ${active.binding?.dir}`);
|
|
33
|
-
if (active.defaultSpec?.cloneDir) {
|
|
34
|
-
console.log(`[babysitter] process library clone: ${active.defaultSpec.cloneDir}`);
|
|
16
|
+
shared.copyPluginBundle(PACKAGE_ROOT, pluginRoot);
|
|
17
|
+
shared.ensureMarketplaceEntry(marketplacePath, pluginRoot);
|
|
18
|
+
if (typeof shared.harnessInstall === 'function') {
|
|
19
|
+
shared.harnessInstall(PACKAGE_ROOT, pluginRoot);
|
|
35
20
|
}
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
console.log(
|
|
39
|
-
console.log('[babysitter] Restart Codex to pick up the installed plugin and config changes, then run Codex and install Babysitter from `/plugins`.');
|
|
40
|
-
console.log('[babysitter] If Codex was already open, start a new thread after install before expecting `babysitter:*` skills such as `$babysitter:babysit` or `$babysitter:call` to appear.');
|
|
21
|
+
shared.runPostInstall && shared.runPostInstall(pluginRoot);
|
|
22
|
+
console.log(`[${shared.PLUGIN_NAME}] Installation complete!`);
|
|
23
|
+
console.log(`[${shared.PLUGIN_NAME}] Restart your IDE/CLI to pick up the plugin.`);
|
|
41
24
|
} catch (err) {
|
|
42
|
-
console.error(`[
|
|
25
|
+
console.error(`[${shared.PLUGIN_NAME}] Failed to install: ${err.message}`);
|
|
43
26
|
process.exitCode = 1;
|
|
44
27
|
}
|
|
45
28
|
}
|
package/bin/uninstall.js
CHANGED
|
@@ -2,39 +2,23 @@
|
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
4
|
const fs = require('fs');
|
|
5
|
-
const
|
|
6
|
-
getCodexHome,
|
|
7
|
-
getHomeMarketplacePath,
|
|
8
|
-
getHomePluginRoot,
|
|
9
|
-
removeLegacyCodexSurface,
|
|
10
|
-
removeMarketplaceEntry,
|
|
11
|
-
} = require('./install-shared');
|
|
5
|
+
const shared = require('./install-shared');
|
|
12
6
|
|
|
13
7
|
function main() {
|
|
14
|
-
const
|
|
15
|
-
const pluginRoot = getHomePluginRoot();
|
|
16
|
-
const marketplacePath = getHomeMarketplacePath();
|
|
17
|
-
let removedPlugin = false;
|
|
8
|
+
const pluginRoot = shared.getHomePluginRoot();
|
|
18
9
|
|
|
19
|
-
if (fs.existsSync(pluginRoot)) {
|
|
20
|
-
|
|
21
|
-
fs.rmSync(pluginRoot, { recursive: true, force: true });
|
|
22
|
-
console.log(`[babysitter] Removed ${pluginRoot}`);
|
|
23
|
-
removedPlugin = true;
|
|
24
|
-
} catch (err) {
|
|
25
|
-
console.warn(`[babysitter] Warning: Could not remove plugin directory ${pluginRoot}: ${err.message}`);
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
removeMarketplaceEntry(marketplacePath);
|
|
30
|
-
removeLegacyCodexSurface(codexHome);
|
|
31
|
-
|
|
32
|
-
if (!removedPlugin) {
|
|
33
|
-
console.log('[babysitter] Plugin directory not found, legacy Codex surface cleaned if present.');
|
|
10
|
+
if (!fs.existsSync(pluginRoot)) {
|
|
11
|
+
console.log(`[${shared.PLUGIN_NAME}] Plugin not installed at ${pluginRoot}`);
|
|
34
12
|
return;
|
|
35
13
|
}
|
|
36
14
|
|
|
37
|
-
|
|
15
|
+
try {
|
|
16
|
+
fs.rmSync(pluginRoot, { recursive: true, force: true });
|
|
17
|
+
console.log(`[${shared.PLUGIN_NAME}] Uninstalled from ${pluginRoot}`);
|
|
18
|
+
} catch (err) {
|
|
19
|
+
console.error(`[${shared.PLUGIN_NAME}] Failed to uninstall: ${err.message}`);
|
|
20
|
+
process.exitCode = 1;
|
|
21
|
+
}
|
|
38
22
|
}
|
|
39
23
|
|
|
40
24
|
main();
|