@a5c-ai/babysitter-openclaw 0.1.1-staging.45beae68

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 (50) hide show
  1. package/README.md +312 -0
  2. package/bin/cli.cjs +80 -0
  3. package/bin/install.cjs +370 -0
  4. package/bin/uninstall.cjs +172 -0
  5. package/commands/assimilate.md +37 -0
  6. package/commands/babysit.md +7 -0
  7. package/commands/call.md +7 -0
  8. package/commands/cleanup.md +20 -0
  9. package/commands/contrib.md +33 -0
  10. package/commands/doctor.md +426 -0
  11. package/commands/forever.md +7 -0
  12. package/commands/help.md +244 -0
  13. package/commands/observe.md +12 -0
  14. package/commands/plan.md +7 -0
  15. package/commands/plugins.md +255 -0
  16. package/commands/project-install.md +17 -0
  17. package/commands/resume.md +8 -0
  18. package/commands/retrospect.md +55 -0
  19. package/commands/user-install.md +17 -0
  20. package/commands/yolo.md +7 -0
  21. package/extensions/hooks/agent-end.ts +127 -0
  22. package/extensions/hooks/before-prompt-build.ts +98 -0
  23. package/extensions/hooks/session-end.ts +80 -0
  24. package/extensions/hooks/session-start.ts +81 -0
  25. package/extensions/index.ts +67 -0
  26. package/hooks/babysitter-session-start.sh +61 -0
  27. package/hooks/babysitter-stop-hook.sh +44 -0
  28. package/hooks.json +26 -0
  29. package/openclaw.plugin.json +17 -0
  30. package/package.json +67 -0
  31. package/plugin.json +25 -0
  32. package/scripts/setup.sh +99 -0
  33. package/scripts/sync-command-docs.cjs +106 -0
  34. package/skills/assimilate/SKILL.md +38 -0
  35. package/skills/babysit/SKILL.md +36 -0
  36. package/skills/call/SKILL.md +8 -0
  37. package/skills/cleanup/SKILL.md +21 -0
  38. package/skills/contrib/SKILL.md +34 -0
  39. package/skills/doctor/SKILL.md +427 -0
  40. package/skills/forever/SKILL.md +8 -0
  41. package/skills/help/SKILL.md +245 -0
  42. package/skills/observe/SKILL.md +13 -0
  43. package/skills/plan/SKILL.md +8 -0
  44. package/skills/plugins/SKILL.md +257 -0
  45. package/skills/project-install/SKILL.md +18 -0
  46. package/skills/resume/SKILL.md +9 -0
  47. package/skills/retrospect/SKILL.md +56 -0
  48. package/skills/user-install/SKILL.md +18 -0
  49. package/skills/yolo/SKILL.md +8 -0
  50. package/versions.json +3 -0
@@ -0,0 +1,370 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ const fs = require('fs');
5
+ const os = require('os');
6
+ const path = require('path');
7
+ const { spawnSync } = require('child_process');
8
+
9
+ const PLUGIN_NAME = 'babysitter';
10
+ const PACKAGE_ROOT = path.resolve(__dirname, '..');
11
+ const PACKAGE_JSON = JSON.parse(fs.readFileSync(path.join(PACKAGE_ROOT, 'package.json'), 'utf8'));
12
+
13
+ // ── Directories ──────────────────────────────────────────────────────────
14
+
15
+ function getUserHome() {
16
+ if (process.env.USERPROFILE) return path.resolve(process.env.USERPROFILE);
17
+ if (process.env.HOME) return path.resolve(process.env.HOME);
18
+ return os.homedir();
19
+ }
20
+
21
+ function getOpenClawHome() {
22
+ if (process.env.OPENCLAW_HOME) return path.resolve(process.env.OPENCLAW_HOME);
23
+ return path.join(getUserHome(), '.openclaw');
24
+ }
25
+
26
+ function getGlobalStateDir() {
27
+ if (process.env.BABYSITTER_GLOBAL_STATE_DIR) {
28
+ return path.resolve(process.env.BABYSITTER_GLOBAL_STATE_DIR);
29
+ }
30
+ return path.join(getUserHome(), '.a5c');
31
+ }
32
+
33
+ function getPluginRoot(workspace) {
34
+ if (workspace) {
35
+ return path.join(workspace, '.openclaw', 'plugins', PLUGIN_NAME);
36
+ }
37
+ return path.join(getOpenClawHome(), 'plugins', PLUGIN_NAME);
38
+ }
39
+
40
+ // ── Args ─────────────────────────────────────────────────────────────────
41
+
42
+ function parseArgs(argv) {
43
+ let workspace = null;
44
+ for (let i = 2; i < argv.length; i += 1) {
45
+ const arg = argv[i];
46
+ if (arg === '--workspace') {
47
+ const next = argv[i + 1];
48
+ workspace = next && !next.startsWith('-') ? path.resolve(argv[++i]) : process.cwd();
49
+ continue;
50
+ }
51
+ if (arg === '--global') {
52
+ workspace = null;
53
+ continue;
54
+ }
55
+ throw new Error(`unknown argument: ${arg}`);
56
+ }
57
+ return { workspace };
58
+ }
59
+
60
+ // ── File helpers ─────────────────────────────────────────────────────────
61
+
62
+ function writeFileIfChanged(filePath, contents) {
63
+ if (fs.existsSync(filePath)) {
64
+ const current = fs.readFileSync(filePath, 'utf8');
65
+ if (current === contents) return false;
66
+ }
67
+ fs.mkdirSync(path.dirname(filePath), { recursive: true });
68
+ fs.writeFileSync(filePath, contents, 'utf8');
69
+ return true;
70
+ }
71
+
72
+ function readJson(filePath) {
73
+ return JSON.parse(fs.readFileSync(filePath, 'utf8'));
74
+ }
75
+
76
+ function writeJson(filePath, value) {
77
+ writeFileIfChanged(filePath, `${JSON.stringify(value, null, 2)}\n`);
78
+ }
79
+
80
+ function copyRecursive(src, dest) {
81
+ if (!fs.existsSync(src)) return;
82
+ const stat = fs.statSync(src);
83
+ if (stat.isDirectory()) {
84
+ fs.mkdirSync(dest, { recursive: true });
85
+ for (const entry of fs.readdirSync(src)) {
86
+ if (['node_modules', '.git', 'test', '.a5c'].includes(entry)) continue;
87
+ copyRecursive(path.join(src, entry), path.join(dest, entry));
88
+ }
89
+ return;
90
+ }
91
+ fs.mkdirSync(path.dirname(dest), { recursive: true });
92
+ fs.copyFileSync(src, dest);
93
+ }
94
+
95
+ function ensureExecutable(filePath) {
96
+ try {
97
+ fs.chmodSync(filePath, 0o755);
98
+ } catch {
99
+ // Best-effort: Windows may ignore mode changes.
100
+ }
101
+ }
102
+
103
+ // ── Plugin bundle ────────────────────────────────────────────────────────
104
+
105
+ const PLUGIN_BUNDLE_ENTRIES = [
106
+ 'plugin.json',
107
+ 'openclaw.plugin.json',
108
+ 'versions.json',
109
+ 'hooks.json',
110
+ 'hooks',
111
+ 'extensions',
112
+ 'skills',
113
+ 'commands',
114
+ ];
115
+
116
+ function copyPluginBundle(packageRoot, pluginRoot) {
117
+ if (path.resolve(packageRoot) === path.resolve(pluginRoot)) {
118
+ console.log('[babysitter] Source and target are the same directory; skipping copy.');
119
+ return;
120
+ }
121
+ // Idempotent: remove previous install and replace.
122
+ fs.rmSync(pluginRoot, { recursive: true, force: true });
123
+ fs.mkdirSync(pluginRoot, { recursive: true });
124
+ for (const entry of PLUGIN_BUNDLE_ENTRIES) {
125
+ const src = path.join(packageRoot, entry);
126
+ if (fs.existsSync(src)) {
127
+ copyRecursive(src, path.join(pluginRoot, entry));
128
+ }
129
+ }
130
+ }
131
+
132
+ // ── Hook registration ────────────────────────────────────────────────────
133
+
134
+ function ensureHooksRegistered(pluginRoot) {
135
+ const hooksJsonSrc = path.join(PACKAGE_ROOT, 'hooks.json');
136
+ if (!fs.existsSync(hooksJsonSrc)) return;
137
+
138
+ const hooksJson = readJson(hooksJsonSrc);
139
+ const hooksDir = path.join(pluginRoot, 'hooks');
140
+
141
+ // Ensure hook scripts are executable
142
+ if (fs.existsSync(hooksDir)) {
143
+ for (const entry of fs.readdirSync(hooksDir)) {
144
+ if (entry.endsWith('.sh')) {
145
+ ensureExecutable(path.join(hooksDir, entry));
146
+ }
147
+ }
148
+ }
149
+
150
+ console.log(`[babysitter] Hook registration verified (${Object.keys(hooksJson.hooks || {}).length} event types).`);
151
+ }
152
+
153
+ // ── SDK dependency ───────────────────────────────────────────────────────
154
+
155
+ function ensureSdkInstalled() {
156
+ try {
157
+ require.resolve('@a5c-ai/babysitter-sdk', { paths: [PACKAGE_ROOT] });
158
+ console.log('[babysitter] @a5c-ai/babysitter-sdk — OK');
159
+ return true;
160
+ } catch {
161
+ console.log('[babysitter] Installing @a5c-ai/babysitter-sdk...');
162
+ const sdkVersion = PACKAGE_JSON.dependencies?.['@a5c-ai/babysitter-sdk'] || 'latest';
163
+ const result = spawnSync('npm', ['install', '--no-save', `@a5c-ai/babysitter-sdk@${sdkVersion}`], {
164
+ cwd: PACKAGE_ROOT,
165
+ stdio: 'inherit',
166
+ env: process.env,
167
+ shell: true,
168
+ });
169
+ if ((result.status ?? 1) !== 0) {
170
+ console.warn('[babysitter] Warning: SDK installation failed. Some features may be unavailable.');
171
+ return false;
172
+ }
173
+ console.log('[babysitter] @a5c-ai/babysitter-sdk installed.');
174
+ return true;
175
+ }
176
+ }
177
+
178
+ // ── Process library ──────────────────────────────────────────────────────
179
+
180
+ function resolveBabysitterCommand() {
181
+ if (process.env.BABYSITTER_SDK_CLI) {
182
+ return {
183
+ command: process.execPath,
184
+ argsPrefix: [path.resolve(process.env.BABYSITTER_SDK_CLI)],
185
+ };
186
+ }
187
+ try {
188
+ return {
189
+ command: process.execPath,
190
+ argsPrefix: [
191
+ require.resolve('@a5c-ai/babysitter-sdk/dist/cli/main.js', {
192
+ paths: [PACKAGE_ROOT],
193
+ }),
194
+ ],
195
+ };
196
+ } catch {
197
+ return { command: 'babysitter', argsPrefix: [] };
198
+ }
199
+ }
200
+
201
+ function ensureGlobalProcessLibrary() {
202
+ const resolved = resolveBabysitterCommand();
203
+ const result = spawnSync(
204
+ resolved.command,
205
+ [...resolved.argsPrefix, 'process-library:active', '--state-dir', getGlobalStateDir(), '--json'],
206
+ {
207
+ cwd: PACKAGE_ROOT,
208
+ stdio: ['ignore', 'pipe', 'pipe'],
209
+ encoding: 'utf8',
210
+ env: process.env,
211
+ },
212
+ );
213
+ if (result.status === 0) {
214
+ try {
215
+ return JSON.parse(result.stdout);
216
+ } catch {
217
+ // Non-critical
218
+ }
219
+ }
220
+ console.log('[babysitter] Process library not yet active (will be set up on first run).');
221
+ return null;
222
+ }
223
+
224
+ // ── Marketplace entry (for babysitter plugin:install path) ───────────────
225
+
226
+ function normalizeMarketplaceSourcePath(marketplacePath, pluginSourcePath) {
227
+ let next = pluginSourcePath;
228
+ if (path.isAbsolute(next)) {
229
+ next = path.relative(path.dirname(marketplacePath), next);
230
+ }
231
+ next = String(next || '').replace(/\\/g, '/');
232
+ if (!next.startsWith('./') && !next.startsWith('../')) {
233
+ next = `./${next}`;
234
+ }
235
+ return next;
236
+ }
237
+
238
+ function ensureMarketplaceEntry(pluginRoot) {
239
+ const marketplacePath = path.join(getUserHome(), '.a5c', 'marketplace', 'marketplace.json');
240
+ const defaultMarketplace = {
241
+ name: 'local-plugins',
242
+ interface: { displayName: 'Local Plugins' },
243
+ plugins: [],
244
+ };
245
+
246
+ const marketplace = fs.existsSync(marketplacePath)
247
+ ? readJson(marketplacePath)
248
+ : { ...defaultMarketplace };
249
+
250
+ marketplace.name = marketplace.name || defaultMarketplace.name;
251
+ marketplace.interface = marketplace.interface || defaultMarketplace.interface;
252
+ if (!Array.isArray(marketplace.plugins)) {
253
+ marketplace.plugins = [];
254
+ }
255
+
256
+ const nextEntry = {
257
+ name: PLUGIN_NAME,
258
+ source: {
259
+ source: 'local',
260
+ path: normalizeMarketplaceSourcePath(marketplacePath, pluginRoot),
261
+ },
262
+ policy: {
263
+ installation: 'AVAILABLE',
264
+ authentication: 'ON_INSTALL',
265
+ },
266
+ category: 'Coding',
267
+ };
268
+
269
+ const existingIndex = marketplace.plugins.findIndex((e) => e && e.name === PLUGIN_NAME);
270
+ if (existingIndex >= 0) {
271
+ marketplace.plugins[existingIndex] = nextEntry;
272
+ } else {
273
+ marketplace.plugins.push(nextEntry);
274
+ }
275
+
276
+ writeJson(marketplacePath, marketplace);
277
+ console.log(`[babysitter] Marketplace entry written: ${marketplacePath}`);
278
+ }
279
+
280
+ // ── OpenClaw config placement ────────────────────────────────────────────
281
+
282
+ function ensureOpenClawConfig(workspace) {
283
+ const configDir = workspace
284
+ ? path.join(workspace, '.openclaw')
285
+ : getOpenClawHome();
286
+
287
+ const pluginsConfigPath = path.join(configDir, 'plugins.json');
288
+
289
+ let config;
290
+ if (fs.existsSync(pluginsConfigPath)) {
291
+ config = readJson(pluginsConfigPath);
292
+ } else {
293
+ config = { plugins: {} };
294
+ }
295
+
296
+ if (!config.plugins) config.plugins = {};
297
+
298
+ // Add or update babysitter plugin entry (idempotent)
299
+ config.plugins[PLUGIN_NAME] = {
300
+ enabled: true,
301
+ version: PACKAGE_JSON.version,
302
+ package: PACKAGE_JSON.name,
303
+ };
304
+
305
+ writeJson(pluginsConfigPath, config);
306
+ console.log(`[babysitter] OpenClaw plugin config updated: ${pluginsConfigPath}`);
307
+ }
308
+
309
+ // ── State directory ──────────────────────────────────────────────────────
310
+
311
+ function ensureStateDirectory(workspace) {
312
+ const stateDir = workspace
313
+ ? path.join(workspace, '.a5c')
314
+ : getGlobalStateDir();
315
+ fs.mkdirSync(stateDir, { recursive: true });
316
+ return stateDir;
317
+ }
318
+
319
+ // ── Main ─────────────────────────────────────────────────────────────────
320
+
321
+ function main() {
322
+ const { workspace } = parseArgs(process.argv);
323
+ const pluginRoot = getPluginRoot(workspace);
324
+ const scope = workspace ? `project (${workspace})` : 'global';
325
+
326
+ console.log(`[babysitter] Installing babysitter plugin for OpenClaw (${scope})`);
327
+ console.log(`[babysitter] plugin name: ${PLUGIN_NAME}`);
328
+ console.log(`[babysitter] package: ${PACKAGE_JSON.name}@${PACKAGE_JSON.version}`);
329
+ console.log(`[babysitter] target: ${pluginRoot}`);
330
+
331
+ try {
332
+ // 1. Copy plugin bundle
333
+ copyPluginBundle(PACKAGE_ROOT, pluginRoot);
334
+ console.log('[babysitter] Plugin bundle copied.');
335
+
336
+ // 2. Ensure SDK dependency
337
+ ensureSdkInstalled();
338
+
339
+ // 3. Register hooks
340
+ ensureHooksRegistered(pluginRoot);
341
+
342
+ // 4. OpenClaw config placement
343
+ ensureOpenClawConfig(workspace);
344
+
345
+ // 5. Marketplace entry (global only)
346
+ if (!workspace) {
347
+ ensureMarketplaceEntry(pluginRoot);
348
+ }
349
+
350
+ // 6. State directory
351
+ const stateDir = ensureStateDirectory(workspace);
352
+ console.log(`[babysitter] State directory: ${stateDir}`);
353
+
354
+ // 7. Process library (global only, best-effort)
355
+ if (!workspace) {
356
+ const active = ensureGlobalProcessLibrary();
357
+ if (active?.binding?.dir) {
358
+ console.log(`[babysitter] Process library: ${active.binding.dir}`);
359
+ }
360
+ }
361
+
362
+ console.log('[babysitter] Installation complete!');
363
+ console.log('[babysitter] Restart OpenClaw to pick up the installed plugin.');
364
+ } catch (err) {
365
+ console.error(`[babysitter] Failed to install plugin: ${err.message}`);
366
+ process.exitCode = 1;
367
+ }
368
+ }
369
+
370
+ main();
@@ -0,0 +1,172 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ const fs = require('fs');
5
+ const os = require('os');
6
+ const path = require('path');
7
+
8
+ const PLUGIN_NAME = 'babysitter';
9
+
10
+ // ── Directories ──────────────────────────────────────────────────────────
11
+
12
+ function getUserHome() {
13
+ if (process.env.USERPROFILE) return path.resolve(process.env.USERPROFILE);
14
+ if (process.env.HOME) return path.resolve(process.env.HOME);
15
+ return os.homedir();
16
+ }
17
+
18
+ function getOpenClawHome() {
19
+ if (process.env.OPENCLAW_HOME) return path.resolve(process.env.OPENCLAW_HOME);
20
+ return path.join(getUserHome(), '.openclaw');
21
+ }
22
+
23
+ function getPluginRoot(workspace) {
24
+ if (workspace) {
25
+ return path.join(workspace, '.openclaw', 'plugins', PLUGIN_NAME);
26
+ }
27
+ return path.join(getOpenClawHome(), 'plugins', PLUGIN_NAME);
28
+ }
29
+
30
+ // ── Args ─────────────────────────────────────────────────────────────────
31
+
32
+ function parseArgs(argv) {
33
+ let workspace = null;
34
+ for (let i = 2; i < argv.length; i += 1) {
35
+ const arg = argv[i];
36
+ if (arg === '--workspace') {
37
+ const next = argv[i + 1];
38
+ workspace = next && !next.startsWith('-') ? path.resolve(argv[++i]) : process.cwd();
39
+ continue;
40
+ }
41
+ if (arg === '--global') {
42
+ workspace = null;
43
+ continue;
44
+ }
45
+ throw new Error(`unknown argument: ${arg}`);
46
+ }
47
+ return { workspace };
48
+ }
49
+
50
+ // ── File helpers ─────────────────────────────────────────────────────────
51
+
52
+ function readJson(filePath) {
53
+ return JSON.parse(fs.readFileSync(filePath, 'utf8'));
54
+ }
55
+
56
+ function writeJson(filePath, value) {
57
+ fs.mkdirSync(path.dirname(filePath), { recursive: true });
58
+ fs.writeFileSync(filePath, `${JSON.stringify(value, null, 2)}\n`, 'utf8');
59
+ }
60
+
61
+ // ── Remove plugin directory ──────────────────────────────────────────────
62
+
63
+ function removePluginDir(pluginRoot) {
64
+ if (!fs.existsSync(pluginRoot)) {
65
+ console.log(`[babysitter] Plugin directory not found: ${pluginRoot}`);
66
+ return false;
67
+ }
68
+ try {
69
+ fs.rmSync(pluginRoot, { recursive: true, force: true });
70
+ console.log(`[babysitter] Removed plugin directory: ${pluginRoot}`);
71
+ return true;
72
+ } catch (err) {
73
+ console.warn(`[babysitter] Warning: Could not remove ${pluginRoot}: ${err.message}`);
74
+ return false;
75
+ }
76
+ }
77
+
78
+ // ── Remove OpenClaw config entry ─────────────────────────────────────────
79
+
80
+ function removeOpenClawConfig(workspace) {
81
+ const configDir = workspace
82
+ ? path.join(workspace, '.openclaw')
83
+ : getOpenClawHome();
84
+
85
+ const pluginsConfigPath = path.join(configDir, 'plugins.json');
86
+ if (!fs.existsSync(pluginsConfigPath)) return;
87
+
88
+ try {
89
+ const config = readJson(pluginsConfigPath);
90
+ if (config.plugins && config.plugins[PLUGIN_NAME]) {
91
+ delete config.plugins[PLUGIN_NAME];
92
+ writeJson(pluginsConfigPath, config);
93
+ console.log(`[babysitter] Removed plugin entry from: ${pluginsConfigPath}`);
94
+ }
95
+ } catch (err) {
96
+ console.warn(`[babysitter] Warning: Could not update config: ${err.message}`);
97
+ }
98
+ }
99
+
100
+ // ── Remove marketplace entry ─────────────────────────────────────────────
101
+
102
+ function removeMarketplaceEntry() {
103
+ const marketplacePath = path.join(getUserHome(), '.a5c', 'marketplace', 'marketplace.json');
104
+ if (!fs.existsSync(marketplacePath)) return;
105
+
106
+ try {
107
+ const marketplace = readJson(marketplacePath);
108
+ if (!Array.isArray(marketplace.plugins)) return;
109
+
110
+ const before = marketplace.plugins.length;
111
+ marketplace.plugins = marketplace.plugins.filter((e) => e && e.name !== PLUGIN_NAME);
112
+ if (marketplace.plugins.length < before) {
113
+ writeJson(marketplacePath, marketplace);
114
+ console.log(`[babysitter] Removed marketplace entry: ${marketplacePath}`);
115
+ }
116
+ } catch (err) {
117
+ console.warn(`[babysitter] Warning: Could not update marketplace: ${err.message}`);
118
+ }
119
+ }
120
+
121
+ // ── Remove legacy hook scripts from OpenClaw hooks dir ───────────────────
122
+
123
+ function removeLegacyHookScripts(workspace) {
124
+ const hooksDir = workspace
125
+ ? path.join(workspace, '.openclaw', 'hooks')
126
+ : path.join(getOpenClawHome(), 'hooks');
127
+
128
+ const legacyScripts = [
129
+ 'babysitter-session-start.sh',
130
+ 'babysitter-stop-hook.sh',
131
+ ];
132
+
133
+ for (const script of legacyScripts) {
134
+ const scriptPath = path.join(hooksDir, script);
135
+ if (fs.existsSync(scriptPath)) {
136
+ fs.rmSync(scriptPath, { force: true });
137
+ console.log(`[babysitter] Removed hook script: ${scriptPath}`);
138
+ }
139
+ }
140
+ }
141
+
142
+ // ── Main ─────────────────────────────────────────────────────────────────
143
+
144
+ function main() {
145
+ const { workspace } = parseArgs(process.argv);
146
+ const pluginRoot = getPluginRoot(workspace);
147
+ const scope = workspace ? `project (${workspace})` : 'global';
148
+
149
+ console.log(`[babysitter] Uninstalling babysitter plugin for OpenClaw (${scope})`);
150
+
151
+ // 1. Remove plugin directory
152
+ const removed = removePluginDir(pluginRoot);
153
+
154
+ // 2. Remove config entry
155
+ removeOpenClawConfig(workspace);
156
+
157
+ // 3. Remove marketplace entry (global only)
158
+ if (!workspace) {
159
+ removeMarketplaceEntry();
160
+ }
161
+
162
+ // 4. Remove legacy hook scripts
163
+ removeLegacyHookScripts(workspace);
164
+
165
+ if (removed) {
166
+ console.log('[babysitter] Uninstallation complete. Restart OpenClaw to apply changes.');
167
+ } else {
168
+ console.log('[babysitter] Plugin was not installed; cleaned up config entries if present.');
169
+ }
170
+ }
171
+
172
+ main();
@@ -0,0 +1,37 @@
1
+ ---
2
+ description: Assimilate an external methodology, harness, or specification into babysitter process definitions with skills and agents.
3
+ argument-hint: Target to assimilate (e.g. repo URL, harness name, or spec path)
4
+ allowed-tools: Read, Grep, Write, Task, Bash, Edit, Grep, Glob, WebFetch, WebSearch, Search, AskUserQuestion, TodoWrite, TodoRead, Skill, BashOutput, KillShell, MultiEdit, LS
5
+ ---
6
+
7
+ Invoke the babysitter:babysit skill (using the Skill tool) and follow its instructions (SKILL.md).
8
+
9
+ Use the assimilation domain processes from the active process library to convert external sources into well-defined babysitter process definitions with accompanying skills/ and agents/ directories.
10
+
11
+ If the workspace does not already have an active process-library binding, initialize it first through the shared global SDK binding:
12
+
13
+ ```bash
14
+ babysitter process-library:active --json
15
+ ```
16
+
17
+ Run the process after formalizing it.
18
+
19
+ Available assimilation workflows:
20
+ - **methodology-assimilation** (`specializations/meta/assimilation/workflows/methodology-assimilation`) - Learns an external methodology from its repo and converts procedural instructions, commands, and manual flows into babysitter processes with refactored skills and agents. Supports output as methodology or specialization.
21
+ - **harness integration** (`specializations/meta/assimilation/harness/*`) - Integrates babysitter SDK with a specific AI coding harness (generic, codex, opencode, gemini-cli, openclaw, antigravity).
22
+
23
+ During the interview phase, determine which assimilation workflow to use based on the user's target:
24
+ - If the target is a **repo URL or methodology name** then use the methodology-assimilation workflow.
25
+ - If the target is a **harness name** (e.g. codex, opencode, antigravity) then use the matching harness process.
26
+ - If the target is a **specification or other source** then adapt the methodology-assimilation workflow for the spec format.
27
+ - If unclear, ask the user to clarify the assimilation target and type.
28
+
29
+ ## After Assimilation: Contribute Back
30
+
31
+ After successfully assimilating a methodology or harness integration, prompt the user to share it with the community. The assimilated process definitions, skills, and agents could benefit other babysitter users:
32
+
33
+ - **Completed a methodology assimilation**: `/babysitter:contrib library contribution: assimilated [methodology-name] into babysitter process definitions`
34
+ - **Completed a harness integration**: `/babysitter:contrib library contribution: [harness-name] harness integration`
35
+ - **Hit issues during assimilation** (e.g. unsupported patterns, missing SDK features): `/babysitter:contrib bug report: assimilation of [target] failed because [description]` or `/babysitter:contrib feature request: [what the SDK needs to support]`
36
+
37
+ Even just reporting that an assimilation didn't work well helps improve babysitter for everyone.
@@ -0,0 +1,7 @@
1
+ ---
2
+ description: Orchestrate via @babysitter. Use this skill when asked to babysit a run, orchestrate a process or whenever it is called explicitly. (babysit, babysitter, orchestrate, orchestrate a run, workflow, etc.)
3
+ argument-hint: Optional arguments.
4
+ allowed-tools: Read, Grep, Write, Task, Bash, Edit, Grep, Glob, WebFetch, WebSearch, Search, AskUserQuestion, TodoWrite, TodoRead, Skill, BashOutput, KillShell, MultiEdit, LS
5
+ ---
6
+
7
+ Invoke the babysitter:babysit skill (using the Skill tool) and follow its instructions (SKILL.md).
@@ -0,0 +1,7 @@
1
+ ---
2
+ description: Orchestrate a babysitter run. use this command to start babysitting a complex workflow.
3
+ argument-hint: Specific instructions for the run.
4
+ allowed-tools: Read, Grep, Write, Task, Bash, Edit, Grep, Glob, WebFetch, WebSearch, Search, AskUserQuestion, TodoWrite, TodoRead, Skill, BashOutput, KillShell, MultiEdit, LS
5
+ ---
6
+
7
+ Invoke the babysitter:babysit skill (using the Skill tool) and follow its instructions (SKILL.md).
@@ -0,0 +1,20 @@
1
+ ---
2
+ description: Clean up .a5c/runs and .a5c/processes directories. Aggregates insights from completed/failed runs into docs/run-history-insights.md, then removes old run data and orphaned process files.
3
+ argument-hint: "[--dry-run] [--keep-days N] Optional flags. --dry-run shows what would be removed without deleting. --keep-days N keeps runs newer than N days (default 7)."
4
+ allowed-tools: Read, Grep, Write, Task, Bash, Edit, Grep, Glob, WebFetch, WebSearch, Search, AskUserQuestion, TodoWrite, TodoRead, Skill, BashOutput, KillShell, MultiEdit, LS
5
+ ---
6
+
7
+ Invoke the babysitter:babysit skill (using the Skill tool) and follow its instructions (SKILL.md).
8
+
9
+ Create and run a cleanup process using the process at `skills\babysit\process\cradle\cleanup-runs.js/processes/cleanup-runs.js`.
10
+
11
+ Implementation notes (for the process):
12
+ - Parse arguments for `--dry-run` flag (if present, set dryRun: true in inputs) and `--keep-days N` (default: 7)
13
+ - The process scans .a5c/runs/ for completed/failed runs, aggregates insights, writes summaries, then removes old data
14
+ - Always show the user what will be removed before removing (in interactive mode via breakpoints)
15
+ - In non-interactive mode (yolo), proceed with cleanup using defaults
16
+ - The insights file goes to docs/run-history-insights.md
17
+ - Only remove terminal runs (completed/failed) older than the keep-days threshold
18
+ - Never remove active/in-progress runs
19
+ - Remove orphaned process files not referenced by remaining runs
20
+ - After cleanup, show remaining run count and disk usage
@@ -0,0 +1,33 @@
1
+ ---
2
+ description: Submit feedback or contribute to babysitter project
3
+ argument-hint: Specific instructions for the run.
4
+ allowed-tools: Read, Grep, Write, Task, Bash, Edit, Grep, Glob, WebFetch, WebSearch, Search, AskUserQuestion, TodoWrite, TodoRead, Skill, BashOutput, KillShell, MultiEdit, LS
5
+ ---
6
+
7
+ Invoke the babysitter:babysit skill (using the Skill tool) and follow its instructions (SKILL.md).
8
+
9
+ ## Process Routing
10
+
11
+ Contribution processes live under the active process library's `cradle/` directory. Resolve the active library root with `babysitter process-library:active --json` and route based on arguments:
12
+
13
+ ### Issue-based (opens a GitHub issue in a5c-ai/babysitter)
14
+ * **Bug report** → `cradle/bug-report.js#process` — Report a bug in the SDK, CLI, process library, etc.
15
+ * **Feature request** → `cradle/feature-request.js#process` — Request a new feature or enhancement
16
+ * **Documentation question** → `cradle/documentation-question.js#process` — Ask about undocumented behavior or missing docs
17
+
18
+ ### PR-based (forks repo, creates branch, submits PR to a5c-ai/babysitter)
19
+ * **Bugfix** → `cradle/bugfix.js#process` — User already has the fix for a bug
20
+ * **Feature implementation** → `cradle/feature-implementation-contribute.js#process` — User already has a feature implementation
21
+ * **Harness integration** → `cradle/feature-harness-integration-contribute.js#process` — User has a harness (CI/CD, IDE, editor) integration
22
+ * **Library contribution** → `cradle/library-contribution.js#process` — New or improved process/skill/subagent for the library
23
+ * **Documentation answer** → `cradle/documentation-contribute-answer.js#process` — User has an answer for an unanswered docs question
24
+
25
+ ### Router (when arguments are empty or general)
26
+ * **Contribute** → `cradle/contribute.js#process` — Explains contribution types and routes to the specific process
27
+
28
+ ## Contribution Rules
29
+
30
+ * PR-based contributions: fork the babysitter repo (a5c-ai/babysitter) for the user, ask to star if not already starred, perform changes, submit PR
31
+ * Issue-based contributions: gather details, search for duplicates, review, then open an issue in a5c-ai/babysitter
32
+ * Add breakpoints (permissions) before ALL gh actions (fork, star, submit PR/issue) to allow user review and cancellation
33
+ * If arguments are empty: use the `contribute.js` router process to show options and route accordingly