@a5c-ai/babysitter-openclaw 5.0.1-staging.ff2c19f9 → 5.1.1-staging.00ceebd28cf2
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 +29 -16
- package/bin/install-shared.cjs +6 -6
- package/bin/uninstall.cjs +0 -1
- package/commands/blueprints.md +64 -0
- package/commands/call.md +11 -7
- package/commands/check-forbidden-markers.md +68 -0
- package/commands/cleanup.md +37 -9
- package/commands/contrib.md +31 -31
- package/commands/doctor.md +2 -3
- package/commands/forever.md +6 -6
- package/commands/help.md +11 -10
- package/commands/observe.md +6 -1
- package/commands/plan.md +17 -7
- package/commands/plugins.md +22 -255
- package/commands/project-install.md +10 -10
- package/commands/resume.md +8 -8
- package/commands/retrospect.md +55 -55
- package/commands/user-install.md +10 -10
- package/commands/yolo.md +11 -7
- package/extensions/hooks/gateway-request-completed.ts +20 -0
- package/extensions/hooks/gateway-request-received.ts +20 -0
- package/extensions/hooks/{session-start.ts → gateway-request-routed.ts} +4 -4
- package/extensions/hooks/{before-prompt-build.ts → plugin-tool-after.ts} +4 -4
- package/extensions/hooks/{session-end.ts → plugin-tool-before.ts} +4 -4
- package/extensions/hooks/{agent-end.ts → plugin-turn-stop.ts} +4 -4
- package/hooks/{babysitter-proxied-session-end.js → babysitter-proxied-gateway-request-completed.js} +6 -3
- package/hooks/{babysitter-proxied-session-end.sh → babysitter-proxied-gateway-request-completed.sh} +0 -0
- package/hooks/{babysitter-proxied-session-start.js → babysitter-proxied-gateway-request-received.js} +6 -3
- package/hooks/{babysitter-proxied-session-start.sh → babysitter-proxied-gateway-request-received.sh} +1 -1
- package/hooks/babysitter-proxied-gateway-request-routed.js +27 -0
- package/hooks/babysitter-proxied-gateway-request-routed.sh +3 -0
- package/hooks/babysitter-proxied-plugin-tool-after.js +27 -0
- package/hooks/babysitter-proxied-plugin-tool-after.sh +3 -0
- package/hooks/{babysitter-proxied-before-prompt-build.js → babysitter-proxied-plugin-tool-before.js} +7 -4
- package/hooks/babysitter-proxied-plugin-tool-before.sh +3 -0
- package/hooks/{babysitter-proxied-agent-end.js → babysitter-proxied-plugin-turn-stop.js} +7 -4
- package/hooks.json +1 -24
- package/openclaw.plugin.json +7 -5
- package/package.json +10 -9
- package/plugin.json +1 -1
- package/scripts/create-release-tag.mjs +18 -0
- package/scripts/publish-from-tag.mjs +41 -0
- package/scripts/team-install.cjs +1 -1
- package/skills/babysit/SKILL.md +35 -10
- package/skills/blueprints/SKILL.md +66 -0
- package/skills/call/SKILL.md +5 -1
- package/skills/check-forbidden-markers/SKILL.md +69 -0
- package/skills/cleanup/SKILL.md +37 -9
- package/skills/contrib/SKILL.md +25 -25
- package/skills/doctor/SKILL.md +2 -3
- package/skills/help/SKILL.md +11 -10
- package/skills/observe/SKILL.md +6 -1
- package/skills/plan/SKILL.md +11 -1
- package/skills/plugins/SKILL.md +18 -251
- 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/skills/yolo/SKILL.md +5 -1
- package/versions.json +2 -1
- package/hooks/babysitter-proxied-agent-end.sh +0 -3
- package/hooks/babysitter-proxied-before-prompt-build.sh +0 -3
- package/scripts/sync-command-docs.cjs +0 -107
- /package/hooks/{babysitter-proxied-stop-hook.sh → babysitter-proxied-plugin-turn-stop.sh} +0 -0
package/hooks/{babysitter-proxied-session-end.js → babysitter-proxied-gateway-request-completed.js}
RENAMED
|
@@ -6,7 +6,7 @@ var readFileSync = require("fs").readFileSync;
|
|
|
6
6
|
|
|
7
7
|
var PLUGIN_ROOT = process.env.PLUGIN_ROOT || process.env.PLUGIN_ROOT || path.resolve(__dirname, "..");
|
|
8
8
|
var stdin = "";
|
|
9
|
-
try { stdin = readFileSync(0, "utf8"); } catch {}
|
|
9
|
+
try { stdin = readFileSync(0, "utf8"); } catch (e) { process.stderr.write("[extensions-adapter] stdin read failed: " + (e instanceof Error ? e.message : String(e)) + "\n"); }
|
|
10
10
|
try {
|
|
11
11
|
var result = execSync("bash " + JSON.stringify(path.join(PLUGIN_ROOT, "hooks/session-end.sh")), {
|
|
12
12
|
input: stdin,
|
|
@@ -15,10 +15,13 @@ try {
|
|
|
15
15
|
env: Object.assign({}, process.env, {
|
|
16
16
|
HOOK_TYPE: process.env.HOOK_TYPE || "",
|
|
17
17
|
ADAPTER_NAME: process.env.ADAPTER_NAME || "openclaw",
|
|
18
|
-
PLUGIN_ROOT: PLUGIN_ROOT
|
|
18
|
+
PLUGIN_ROOT: PLUGIN_ROOT,
|
|
19
|
+
CLAUDE_PLUGIN_ROOT: PLUGIN_ROOT
|
|
19
20
|
})
|
|
20
21
|
});
|
|
21
22
|
process.stdout.write(result);
|
|
22
23
|
} catch (e) {
|
|
23
|
-
process.
|
|
24
|
+
process.stderr.write("[extensions-adapter] hook execution failed: " + (e instanceof Error ? e.message : String(e)) + "\n");
|
|
25
|
+
process.stdout.write(JSON.stringify({ error: e instanceof Error ? e.message : String(e) }) + "\n");
|
|
26
|
+
process.exit(1);
|
|
24
27
|
}
|
package/hooks/{babysitter-proxied-session-end.sh → babysitter-proxied-gateway-request-completed.sh}
RENAMED
|
File without changes
|
package/hooks/{babysitter-proxied-session-start.js → babysitter-proxied-gateway-request-received.js}
RENAMED
|
@@ -6,7 +6,7 @@ var readFileSync = require("fs").readFileSync;
|
|
|
6
6
|
|
|
7
7
|
var PLUGIN_ROOT = process.env.PLUGIN_ROOT || process.env.PLUGIN_ROOT || path.resolve(__dirname, "..");
|
|
8
8
|
var stdin = "";
|
|
9
|
-
try { stdin = readFileSync(0, "utf8"); } catch {}
|
|
9
|
+
try { stdin = readFileSync(0, "utf8"); } catch (e) { process.stderr.write("[extensions-adapter] stdin read failed: " + (e instanceof Error ? e.message : String(e)) + "\n"); }
|
|
10
10
|
try {
|
|
11
11
|
var result = execSync("bash " + JSON.stringify(path.join(PLUGIN_ROOT, "hooks/session-start.sh")), {
|
|
12
12
|
input: stdin,
|
|
@@ -15,10 +15,13 @@ try {
|
|
|
15
15
|
env: Object.assign({}, process.env, {
|
|
16
16
|
HOOK_TYPE: process.env.HOOK_TYPE || "",
|
|
17
17
|
ADAPTER_NAME: process.env.ADAPTER_NAME || "openclaw",
|
|
18
|
-
PLUGIN_ROOT: PLUGIN_ROOT
|
|
18
|
+
PLUGIN_ROOT: PLUGIN_ROOT,
|
|
19
|
+
CLAUDE_PLUGIN_ROOT: PLUGIN_ROOT
|
|
19
20
|
})
|
|
20
21
|
});
|
|
21
22
|
process.stdout.write(result);
|
|
22
23
|
} catch (e) {
|
|
23
|
-
process.
|
|
24
|
+
process.stderr.write("[extensions-adapter] hook execution failed: " + (e instanceof Error ? e.message : String(e)) + "\n");
|
|
25
|
+
process.stdout.write(JSON.stringify({ error: e instanceof Error ? e.message : String(e) }) + "\n");
|
|
26
|
+
process.exit(1);
|
|
24
27
|
}
|
package/hooks/{babysitter-proxied-session-start.sh → babysitter-proxied-gateway-request-received.sh}
RENAMED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/bin/bash
|
|
2
2
|
# Session Start — installs SDK if needed, then runs hook handler.
|
|
3
3
|
set -euo pipefail
|
|
4
|
-
PLUGIN_ROOT="${PLUGIN_ROOT:-$(cd "$(dirname "$0")/.." && pwd)}"
|
|
4
|
+
PLUGIN_ROOT="${PLUGIN_ROOT:-${CLAUDE_PLUGIN_ROOT:-$(cd "$(dirname "$0")/.." && pwd)}}"
|
|
5
5
|
SDK_VERSION=$(node -e "try{console.log(JSON.parse(require('fs').readFileSync('${PLUGIN_ROOT}/versions.json','utf8')).sdkVersion||'latest')}catch{console.log('latest')}" 2>/dev/null || echo "latest")
|
|
6
6
|
if ! command -v babysitter &>/dev/null; then
|
|
7
7
|
npm i -g "@a5c-ai/babysitter-sdk@${SDK_VERSION}" --loglevel=error 2>/dev/null || \
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
var execSync = require("child_process").execSync;
|
|
4
|
+
var path = require("path");
|
|
5
|
+
var readFileSync = require("fs").readFileSync;
|
|
6
|
+
|
|
7
|
+
var PLUGIN_ROOT = process.env.PLUGIN_ROOT || process.env.PLUGIN_ROOT || path.resolve(__dirname, "..");
|
|
8
|
+
var stdin = "";
|
|
9
|
+
try { stdin = readFileSync(0, "utf8"); } catch (e) { process.stderr.write("[extensions-adapter] stdin read failed: " + (e instanceof Error ? e.message : String(e)) + "\n"); }
|
|
10
|
+
try {
|
|
11
|
+
var result = execSync("bash " + JSON.stringify(path.join(PLUGIN_ROOT, "hooks/user-prompt-submit.sh")), {
|
|
12
|
+
input: stdin,
|
|
13
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
14
|
+
timeout: 30000,
|
|
15
|
+
env: Object.assign({}, process.env, {
|
|
16
|
+
HOOK_TYPE: process.env.HOOK_TYPE || "",
|
|
17
|
+
ADAPTER_NAME: process.env.ADAPTER_NAME || "openclaw",
|
|
18
|
+
PLUGIN_ROOT: PLUGIN_ROOT,
|
|
19
|
+
CLAUDE_PLUGIN_ROOT: PLUGIN_ROOT
|
|
20
|
+
})
|
|
21
|
+
});
|
|
22
|
+
process.stdout.write(result);
|
|
23
|
+
} catch (e) {
|
|
24
|
+
process.stderr.write("[extensions-adapter] hook execution failed: " + (e instanceof Error ? e.message : String(e)) + "\n");
|
|
25
|
+
process.stdout.write(JSON.stringify({ error: e instanceof Error ? e.message : String(e) }) + "\n");
|
|
26
|
+
process.exit(1);
|
|
27
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
var execSync = require("child_process").execSync;
|
|
4
|
+
var path = require("path");
|
|
5
|
+
var readFileSync = require("fs").readFileSync;
|
|
6
|
+
|
|
7
|
+
var PLUGIN_ROOT = process.env.PLUGIN_ROOT || process.env.PLUGIN_ROOT || path.resolve(__dirname, "..");
|
|
8
|
+
var stdin = "";
|
|
9
|
+
try { stdin = readFileSync(0, "utf8"); } catch (e) { process.stderr.write("[extensions-adapter] stdin read failed: " + (e instanceof Error ? e.message : String(e)) + "\n"); }
|
|
10
|
+
try {
|
|
11
|
+
var result = execSync("bash " + JSON.stringify(path.join(PLUGIN_ROOT, "hooks/post-tool-use.sh")), {
|
|
12
|
+
input: stdin,
|
|
13
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
14
|
+
timeout: 30000,
|
|
15
|
+
env: Object.assign({}, process.env, {
|
|
16
|
+
HOOK_TYPE: process.env.HOOK_TYPE || "",
|
|
17
|
+
ADAPTER_NAME: process.env.ADAPTER_NAME || "openclaw",
|
|
18
|
+
PLUGIN_ROOT: PLUGIN_ROOT,
|
|
19
|
+
CLAUDE_PLUGIN_ROOT: PLUGIN_ROOT
|
|
20
|
+
})
|
|
21
|
+
});
|
|
22
|
+
process.stdout.write(result);
|
|
23
|
+
} catch (e) {
|
|
24
|
+
process.stderr.write("[extensions-adapter] hook execution failed: " + (e instanceof Error ? e.message : String(e)) + "\n");
|
|
25
|
+
process.stdout.write(JSON.stringify({ error: e instanceof Error ? e.message : String(e) }) + "\n");
|
|
26
|
+
process.exit(1);
|
|
27
|
+
}
|
package/hooks/{babysitter-proxied-before-prompt-build.js → babysitter-proxied-plugin-tool-before.js}
RENAMED
|
@@ -6,19 +6,22 @@ var readFileSync = require("fs").readFileSync;
|
|
|
6
6
|
|
|
7
7
|
var PLUGIN_ROOT = process.env.PLUGIN_ROOT || process.env.PLUGIN_ROOT || path.resolve(__dirname, "..");
|
|
8
8
|
var stdin = "";
|
|
9
|
-
try { stdin = readFileSync(0, "utf8"); } catch {}
|
|
9
|
+
try { stdin = readFileSync(0, "utf8"); } catch (e) { process.stderr.write("[extensions-adapter] stdin read failed: " + (e instanceof Error ? e.message : String(e)) + "\n"); }
|
|
10
10
|
try {
|
|
11
|
-
var result = execSync("bash " + JSON.stringify(path.join(PLUGIN_ROOT, "hooks/
|
|
11
|
+
var result = execSync("bash " + JSON.stringify(path.join(PLUGIN_ROOT, "hooks/pre-tool-use.sh")), {
|
|
12
12
|
input: stdin,
|
|
13
13
|
stdio: ["pipe", "pipe", "pipe"],
|
|
14
14
|
timeout: 30000,
|
|
15
15
|
env: Object.assign({}, process.env, {
|
|
16
16
|
HOOK_TYPE: process.env.HOOK_TYPE || "",
|
|
17
17
|
ADAPTER_NAME: process.env.ADAPTER_NAME || "openclaw",
|
|
18
|
-
PLUGIN_ROOT: PLUGIN_ROOT
|
|
18
|
+
PLUGIN_ROOT: PLUGIN_ROOT,
|
|
19
|
+
CLAUDE_PLUGIN_ROOT: PLUGIN_ROOT
|
|
19
20
|
})
|
|
20
21
|
});
|
|
21
22
|
process.stdout.write(result);
|
|
22
23
|
} catch (e) {
|
|
23
|
-
process.
|
|
24
|
+
process.stderr.write("[extensions-adapter] hook execution failed: " + (e instanceof Error ? e.message : String(e)) + "\n");
|
|
25
|
+
process.stdout.write(JSON.stringify({ error: e instanceof Error ? e.message : String(e) }) + "\n");
|
|
26
|
+
process.exit(1);
|
|
24
27
|
}
|
|
@@ -6,19 +6,22 @@ var readFileSync = require("fs").readFileSync;
|
|
|
6
6
|
|
|
7
7
|
var PLUGIN_ROOT = process.env.PLUGIN_ROOT || process.env.PLUGIN_ROOT || path.resolve(__dirname, "..");
|
|
8
8
|
var stdin = "";
|
|
9
|
-
try { stdin = readFileSync(0, "utf8"); } catch {}
|
|
9
|
+
try { stdin = readFileSync(0, "utf8"); } catch (e) { process.stderr.write("[extensions-adapter] stdin read failed: " + (e instanceof Error ? e.message : String(e)) + "\n"); }
|
|
10
10
|
try {
|
|
11
|
-
var result = execSync("bash " + JSON.stringify(path.join(PLUGIN_ROOT, "hooks/
|
|
11
|
+
var result = execSync("bash " + JSON.stringify(path.join(PLUGIN_ROOT, "hooks/stop.sh")), {
|
|
12
12
|
input: stdin,
|
|
13
13
|
stdio: ["pipe", "pipe", "pipe"],
|
|
14
14
|
timeout: 30000,
|
|
15
15
|
env: Object.assign({}, process.env, {
|
|
16
16
|
HOOK_TYPE: process.env.HOOK_TYPE || "",
|
|
17
17
|
ADAPTER_NAME: process.env.ADAPTER_NAME || "openclaw",
|
|
18
|
-
PLUGIN_ROOT: PLUGIN_ROOT
|
|
18
|
+
PLUGIN_ROOT: PLUGIN_ROOT,
|
|
19
|
+
CLAUDE_PLUGIN_ROOT: PLUGIN_ROOT
|
|
19
20
|
})
|
|
20
21
|
});
|
|
21
22
|
process.stdout.write(result);
|
|
22
23
|
} catch (e) {
|
|
23
|
-
process.
|
|
24
|
+
process.stderr.write("[extensions-adapter] hook execution failed: " + (e instanceof Error ? e.message : String(e)) + "\n");
|
|
25
|
+
process.stdout.write(JSON.stringify({ error: e instanceof Error ? e.message : String(e) }) + "\n");
|
|
26
|
+
process.exit(1);
|
|
24
27
|
}
|
package/hooks.json
CHANGED
|
@@ -1,27 +1,4 @@
|
|
|
1
1
|
{
|
|
2
2
|
"description": "babysitter plugin hooks for OpenClaw",
|
|
3
|
-
"hooks": {
|
|
4
|
-
"SessionStart": [
|
|
5
|
-
{
|
|
6
|
-
"matcher": "*",
|
|
7
|
-
"hooks": [
|
|
8
|
-
{
|
|
9
|
-
"type": "command",
|
|
10
|
-
"command": "./hooks/babysitter-proxied-session-start.sh"
|
|
11
|
-
}
|
|
12
|
-
]
|
|
13
|
-
}
|
|
14
|
-
],
|
|
15
|
-
"Stop": [
|
|
16
|
-
{
|
|
17
|
-
"matcher": "*",
|
|
18
|
-
"hooks": [
|
|
19
|
-
{
|
|
20
|
-
"type": "command",
|
|
21
|
-
"command": "./hooks/babysitter-proxied-stop-hook.sh"
|
|
22
|
-
}
|
|
23
|
-
]
|
|
24
|
-
}
|
|
25
|
-
]
|
|
26
|
-
}
|
|
3
|
+
"hooks": {}
|
|
27
4
|
}
|
package/openclaw.plugin.json
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "babysitter",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.1.1-staging.00ceebd28cf2",
|
|
4
4
|
"description": "Orchestrate complex, multi-step workflows with event-sourced state management, hook-based extensibility, and human-in-the-loop approval",
|
|
5
5
|
"entrypoint": "extensions/index.ts",
|
|
6
6
|
"hooks": {
|
|
7
|
-
"
|
|
8
|
-
"
|
|
9
|
-
"
|
|
10
|
-
"
|
|
7
|
+
"gateway.request.received": "extensions/hooks/gateway-request-received.ts",
|
|
8
|
+
"plugin.turn.stop": "extensions/hooks/plugin-turn-stop.ts",
|
|
9
|
+
"gateway.request.routed": "extensions/hooks/gateway-request-routed.ts",
|
|
10
|
+
"plugin.tool.before": "extensions/hooks/plugin-tool-before.ts",
|
|
11
|
+
"plugin.tool.after": "extensions/hooks/plugin-tool-after.ts",
|
|
12
|
+
"gateway.request.completed": "extensions/hooks/gateway-request-completed.ts"
|
|
11
13
|
},
|
|
12
14
|
"capabilities": [
|
|
13
15
|
"orchestration",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@a5c-ai/babysitter-openclaw",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.1.1-staging.00ceebd28cf2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Orchestrate complex, multi-step workflows with event-sourced state management, hook-based extensibility, and human-in-the-loop approval",
|
|
6
6
|
"openclaw": {
|
|
@@ -22,21 +22,19 @@
|
|
|
22
22
|
"sdk-integration"
|
|
23
23
|
],
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@a5c-ai/babysitter-sdk": "5.
|
|
25
|
+
"@a5c-ai/babysitter-sdk": "5.1.1-staging.00ceebd28cf2"
|
|
26
26
|
},
|
|
27
27
|
"peerDependencies": {
|
|
28
28
|
"openclaw": "*"
|
|
29
29
|
},
|
|
30
30
|
"scripts": {
|
|
31
|
-
"
|
|
32
|
-
"
|
|
31
|
+
"plugin:install": "node bin/install.cjs --global",
|
|
32
|
+
"plugin:uninstall": "node bin/uninstall.cjs --global",
|
|
33
33
|
"test": "node --test test/integration.test.js",
|
|
34
34
|
"test:integration": "node --test test/integration.test.js",
|
|
35
35
|
"test:packaged-install": "node test/packaged-install.test.cjs",
|
|
36
|
-
"sync:commands": "node scripts/sync-command-docs.cjs",
|
|
37
36
|
"deploy": "npm publish --access public",
|
|
38
|
-
"deploy:staging": "npm publish --access public --tag staging"
|
|
39
|
-
"team:install": "node scripts/team-install.cjs"
|
|
37
|
+
"deploy:staging": "npm publish --access public --tag staging"
|
|
40
38
|
},
|
|
41
39
|
"bin": {
|
|
42
40
|
"babysitter-openclaw": "bin/cli.cjs"
|
|
@@ -62,7 +60,10 @@
|
|
|
62
60
|
},
|
|
63
61
|
"repository": {
|
|
64
62
|
"type": "git",
|
|
65
|
-
"url": "https://github.com/a5c-ai/babysitter"
|
|
63
|
+
"url": "git+https://github.com/a5c-ai/babysitter-openclaw.git"
|
|
66
64
|
},
|
|
67
|
-
"homepage": "https://github.com/a5c-ai/babysitter
|
|
65
|
+
"homepage": "https://github.com/a5c-ai/babysitter-openclaw#readme",
|
|
66
|
+
"bugs": {
|
|
67
|
+
"url": "https://github.com/a5c-ai/babysitter-openclaw/issues"
|
|
68
|
+
}
|
|
68
69
|
}
|
package/plugin.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "babysitter",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.1.1-staging.00ceebd28cf2",
|
|
4
4
|
"description": "Orchestrate complex, multi-step workflows with event-sourced state management, hook-based extensibility, and human-in-the-loop approval",
|
|
5
5
|
"author": "a5c.ai",
|
|
6
6
|
"license": "MIT",
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { spawnSync } from 'node:child_process';
|
|
3
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
4
|
+
|
|
5
|
+
function run(command, args) {
|
|
6
|
+
const result = spawnSync(command, args, { encoding: 'utf8', stdio: 'inherit' });
|
|
7
|
+
if (result.status !== 0) process.exit(result.status || 1);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const branch = process.env.GITHUB_REF_NAME || 'develop';
|
|
11
|
+
const sha = (process.env.GITHUB_SHA || '').slice(0, 12);
|
|
12
|
+
const version = existsSync('package.json') ? JSON.parse(readFileSync('package.json', 'utf8')).version : JSON.parse(readFileSync('versions.json', 'utf8')).sdkVersion;
|
|
13
|
+
const normalized = String(version).replace(/[^0-9A-Za-z._-]/g, '-');
|
|
14
|
+
const tag = 'release/' + branch + '/v' + normalized + '-' + sha;
|
|
15
|
+
run('git', ['config', 'user.name', 'github-actions[bot]']);
|
|
16
|
+
run('git', ['config', 'user.email', 'github-actions[bot]@users.noreply.github.com']);
|
|
17
|
+
run('git', ['tag', tag]);
|
|
18
|
+
run('git', ['push', 'origin', tag]);
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { spawnSync } from 'node:child_process';
|
|
3
|
+
import { readFileSync } from 'node:fs';
|
|
4
|
+
|
|
5
|
+
function run(command, args, options = {}) {
|
|
6
|
+
const result = spawnSync(command, args, { stdio: options.stdio || 'inherit', encoding: options.encoding });
|
|
7
|
+
if (result.status !== 0 && !options.allowFailure) process.exit(result.status || 1);
|
|
8
|
+
return result;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
function npmView(packageSpec) {
|
|
12
|
+
return run('npm', ['view', packageSpec, 'version'], { allowFailure: true, stdio: 'pipe', encoding: 'utf8' }).status === 0;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const pkg = JSON.parse(readFileSync('package.json', 'utf8'));
|
|
16
|
+
const ref = process.env.GITHUB_REF_NAME || '';
|
|
17
|
+
const branch = ref.split('/')[1] || 'develop';
|
|
18
|
+
const tag = branch === 'main' ? 'latest' : branch;
|
|
19
|
+
|
|
20
|
+
if (!process.env.NODE_AUTH_TOKEN) {
|
|
21
|
+
console.log('NODE_AUTH_TOKEN is not configured; skipping npm publish.');
|
|
22
|
+
process.exit(0);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
if (npmView(pkg.name + '@' + pkg.version)) {
|
|
26
|
+
console.log(pkg.name + '@' + pkg.version + ' already exists; ensuring dist-tag ' + tag + '.');
|
|
27
|
+
run('npm', ['dist-tag', 'add', pkg.name + '@' + pkg.version, tag], { allowFailure: true });
|
|
28
|
+
process.exit(0);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
for (const field of ['dependencies', 'peerDependencies', 'optionalDependencies']) {
|
|
32
|
+
for (const [name, version] of Object.entries(pkg[field] || {})) {
|
|
33
|
+
if (!name.startsWith('@a5c-ai/') || version.startsWith('^') || version.startsWith('~') || version === '*' || version.startsWith('workspace:')) continue;
|
|
34
|
+
if (!npmView(name + '@' + version)) {
|
|
35
|
+
console.log('Required internal dependency ' + name + '@' + version + ' is not published yet; skipping npm publish.');
|
|
36
|
+
process.exit(0);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
run('npm', ['publish', '--access', 'public', '--tag', tag]);
|
package/scripts/team-install.cjs
CHANGED
package/skills/babysit/SKILL.md
CHANGED
|
@@ -1,11 +1,24 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: babysit
|
|
3
|
-
description:
|
|
3
|
+
description: Execute via @babysitter. Use this skill when asked to babysit a task, do anything that is structured process-driven (even a loop) or whenever it is called explicitly. (babysit, babysitter, with a process, orchestrate, orchestrate a run, workflow, loop until, etc.)
|
|
4
|
+
allowed-tools: Read, Grep, Write, Task, Bash, Edit, Grep, Glob, WebFetch, WebSearch, Search, AskUserQuestion, TodoWrite, TodoRead, Skill, BashOutput, KillShell, MultiEdit, LS
|
|
5
|
+
version: 0.1.3
|
|
4
6
|
---
|
|
5
7
|
|
|
6
8
|
# babysit
|
|
7
9
|
|
|
8
|
-
|
|
10
|
+
Follow the commands below exactly. but apply judgement and creativity to get the job done. no matter how small or simple the task may seem, you must use the babysitter SDK and run lifecycle to execute it. This is non-negotiable. If you are asked to do something that seems like it could be done with a simple tool call, you must still use the babysitter SDK to create a run, define tasks, execute them, and complete the run. This is how you will learn and demonstrate mastery of the babysitter system. Always follow the full process, even for trivial tasks.
|
|
11
|
+
|
|
12
|
+
Subagents that need a scratch checkout or working directory must create it under
|
|
13
|
+
`/tmp/<descriptive-name>/`, not under `.a5c/runs/<runId>/work`. Before returning
|
|
14
|
+
deliverables, validate that no run-dir worktree was left behind, for example:
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
find .a5c/runs -maxdepth 3 -name work -type d -print
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
That command should print nothing. If it prints a non-empty work directory, move
|
|
21
|
+
or remove only the scratch data you created before returning.
|
|
9
22
|
|
|
10
23
|
## Dependencies
|
|
11
24
|
|
|
@@ -14,24 +27,36 @@ Orchestrate `.a5c/runs/<runId>/` through iterative execution.
|
|
|
14
27
|
Read the SDK version from `versions.json` to ensure version compatibility:
|
|
15
28
|
|
|
16
29
|
```bash
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
30
|
+
SDK_VERSION=$(node -e "try{console.log(JSON.parse(require('fs').readFileSync('${PLUGIN_ROOT}/versions.json','utf8')).sdkVersion||'latest')}catch{console.log('latest')}")
|
|
31
|
+
npm i -g @a5c-ai/babysitter-sdk@$SDK_VERSION || npm i -g @a5c-ai/babysitter-sdk@latest
|
|
32
|
+
|
|
33
|
+
if command -v babysitter >/dev/null 2>&1 && babysitter --version >/dev/null 2>&1; then
|
|
34
|
+
CLI="babysitter"
|
|
35
|
+
else
|
|
36
|
+
CLI="npm exec --yes --package @a5c-ai/babysitter-sdk@$SDK_VERSION -- babysitter"
|
|
37
|
+
fi
|
|
21
38
|
```
|
|
22
39
|
|
|
40
|
+
If the pinned version fails to install (e.g. not yet published), the fallback installs `latest`.
|
|
41
|
+
|
|
42
|
+
If a stale or broken global shim fails with `MODULE_NOT_FOUND`, repair it with `npm rm -g @a5c-ai/babysitter @a5c-ai/babysitter-sdk && npm i -g @a5c-ai/babysitter-sdk@$SDK_VERSION`, then re-run `babysitter --version`.
|
|
43
|
+
|
|
44
|
+
### jq
|
|
45
|
+
|
|
46
|
+
Make sure `jq` is installed and available in the path. If not, install it.
|
|
47
|
+
|
|
23
48
|
## Instructions
|
|
24
49
|
|
|
25
|
-
Run the following command to get full
|
|
50
|
+
Run the following command to get full instructions:
|
|
26
51
|
|
|
27
52
|
```bash
|
|
28
|
-
|
|
53
|
+
$CLI instructions:babysit-skill --harness openclaw --interactive
|
|
29
54
|
```
|
|
30
55
|
|
|
31
|
-
For non-interactive mode:
|
|
56
|
+
For non-interactive mode (running with `-p` flag or no AskUserQuestion tool):
|
|
32
57
|
|
|
33
58
|
```bash
|
|
34
|
-
|
|
59
|
+
$CLI instructions:babysit-skill --harness openclaw --no-interactive
|
|
35
60
|
```
|
|
36
61
|
|
|
37
62
|
Follow the instructions returned by the command above to orchestrate the run.
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: blueprints
|
|
3
|
+
description: manage Babysitter blueprints. Use this command to list installed blueprints, browse marketplaces, install, update, uninstall, configure, or create a new blueprint.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# blueprints
|
|
7
|
+
|
|
8
|
+
This command installs and manages Babysitter blueprints. A blueprint is a version-managed package of contextual instructions or deterministic Babysitter processes, not a conventional software plugin.
|
|
9
|
+
|
|
10
|
+
If the command is run without arguments, list installed blueprints with their name, version, marketplace, installation date, and last update date. Also list configured marketplaces and show how to add the default marketplace when none exist.
|
|
11
|
+
|
|
12
|
+
Blueprints can be installed at two scopes:
|
|
13
|
+
|
|
14
|
+
- **global** (`--global`): stored under `~/.a5c/`, available for all projects
|
|
15
|
+
- **project** (`--project`): stored under `<projectDir>/.a5c/`, project-specific
|
|
16
|
+
|
|
17
|
+
## Marketplace Management
|
|
18
|
+
|
|
19
|
+
Marketplaces are git repositories containing a `marketplace.json` manifest and blueprint package directories. The SDK clones new marketplaces to `.a5c/blueprints/marketplaces/` for the selected scope and reads legacy `.a5c/marketplaces/` clones for compatibility.
|
|
20
|
+
|
|
21
|
+
### Add a marketplace
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
babysitter blueprints:add-marketplace --marketplace-url <url> [--marketplace-path <relative-path>] [--marketplace-branch <ref>] [--force] --global|--project [--json]
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
### Update a marketplace
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
babysitter blueprints:update-marketplace --marketplace-name <name> [--marketplace-branch <ref>] --global|--project [--json]
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### List blueprints in a marketplace
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
babysitter blueprints:list-blueprints --marketplace-name <name> --global|--project [--json]
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Blueprint Lifecycle
|
|
40
|
+
|
|
41
|
+
For `blueprint:install`, `blueprint:update`, `blueprint:configure`, and `blueprint:list-blueprints`, the `--marketplace-name` flag is auto-detected when only one marketplace is cloned for the selected scope.
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
babysitter blueprints:install --plugin-name <name> [--marketplace-name <mp>] --global|--project [--json]
|
|
45
|
+
babysitter blueprints:update --plugin-name <name> --marketplace-name <mp> --global|--project [--json]
|
|
46
|
+
babysitter blueprints:configure --plugin-name <name> --marketplace-name <mp> --global|--project [--json]
|
|
47
|
+
babysitter blueprints:uninstall --plugin-name <name> --marketplace-name <mp> --global|--project [--json]
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
The `--plugin-name` flag is preserved for CLI compatibility with existing marketplace manifests. User-facing docs should call the installable a blueprint.
|
|
51
|
+
|
|
52
|
+
## Registry Management
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
babysitter blueprints:list-installed --global|--project [--json]
|
|
56
|
+
babysitter blueprints:update-registry --plugin-name <name> --plugin-version <ver> --marketplace-name <mp> --global|--project [--json]
|
|
57
|
+
babysitter blueprints:remove-from-registry --plugin-name <name> --global|--project [--json]
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Deprecated Aliases
|
|
61
|
+
|
|
62
|
+
The old `plugin:*` commands remain available as deprecated aliases for one release. Prefer `blueprint:*` in new docs, skills, and process instructions.
|
|
63
|
+
|
|
64
|
+
## Agent Plugins Are Separate
|
|
65
|
+
|
|
66
|
+
Do not rename or reinterpret agent harness plugins while handling blueprints. `CLAUDE_PLUGIN_ROOT`, `PI_PLUGIN_ROOT`, `.claude/plugins/`, hooks-adapter, extensions-adapter, and agent plugin manifests stay plugin-specific.
|
package/skills/call/SKILL.md
CHANGED
|
@@ -5,4 +5,8 @@ description: Orchestrate a babysitter run. use this command to start babysitting
|
|
|
5
5
|
|
|
6
6
|
# call
|
|
7
7
|
|
|
8
|
-
Invoke the babysitter:babysit skill (using the Skill tool) and follow its instructions (SKILL.md).
|
|
8
|
+
Invoke the babysitter:babysit skill (using the Skill tool) and follow its instructions (SKILL.md). Then continue executing the returned instructions in this same turn. Do not stop after the Skill tool returns; carry the requested run through to completion proof.
|
|
9
|
+
|
|
10
|
+
User arguments for this command:
|
|
11
|
+
|
|
12
|
+
$ARGUMENTS
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: check-forbidden-markers
|
|
3
|
+
description: Pre-deploy gate that scans built JS chunks for forbidden substring markers (saga-era / obsolete code paths) listed in a project-local forbidden-markers.txt
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# check-forbidden-markers
|
|
7
|
+
|
|
8
|
+
Invoke the babysitter:babysit skill (using the Skill tool) and follow its instructions (SKILL.md). Compose the gate from the shared helper at `library/processes/shared/forbidden-markers-scanner.js` (issue #477).
|
|
9
|
+
|
|
10
|
+
## What this gate does
|
|
11
|
+
|
|
12
|
+
Reads a list of literal substring markers from `scripts/forbidden-markers.txt` (blank lines and `#`-prefixed comments stripped) and greps every `.js` chunk under `.vercel/output/static/_next/static/chunks/` (Next.js / Vercel default; configurable) for any occurrence. Reports structured hits per `(marker, chunk)` pair with occurrence counts. Designed to chain between `vercel build --prod` and `vercel deploy --prod`.
|
|
13
|
+
|
|
14
|
+
Use this gate when a refactor or restart-from-baseline replaced load-bearing code paths and you need a structural guarantee the obsolete symbols never re-ship. Burned-in evidence: cookbook VI-9 / VI-12 near-miss revivals during the 2026-05 iOS-Safari saga; the prototype lives at `cookbook/scripts/check-no-forbidden.mjs` and shipped two upstream contributions before being generalized as this gate.
|
|
15
|
+
|
|
16
|
+
## When to use
|
|
17
|
+
|
|
18
|
+
- **Pre-deploy.** Insert after build, before deploy. Block the deploy when `ok: false`.
|
|
19
|
+
- **Post-restart.** After a baseline rollback + step-by-step re-add, snapshot the saga-era markers in `forbidden-markers.txt` and let CI hold the line.
|
|
20
|
+
- **Post-refactor.** When old helper / handler / module names must not coexist with the new ones in the same bundle.
|
|
21
|
+
|
|
22
|
+
## Expected config locations
|
|
23
|
+
|
|
24
|
+
- `scripts/forbidden-markers.txt` — one marker per line, `#` for comments. The list is the contract; the gate is mechanical. Commit this file to source control.
|
|
25
|
+
- `.vercel/output/static/_next/static/chunks/` — default scan target. Override for non-Vercel frameworks via the `--chunks-dir` flag or the `chunksDir` task input.
|
|
26
|
+
|
|
27
|
+
A missing markers file is a no-op (`ok: true`, `reason: 'missing-markers-file'`) — misconfiguration is never a deploy block. A missing chunks directory is likewise a no-op (`reason: 'missing-chunks-dir'`) so the gate is safe to chain into `check:all` before the build runs.
|
|
28
|
+
|
|
29
|
+
## Exit semantics
|
|
30
|
+
|
|
31
|
+
| Reason | `ok` | Deploy decision |
|
|
32
|
+
|-------------------------|--------|--------------------------------|
|
|
33
|
+
| `missing-markers-file` | true | Pass (no gate active) |
|
|
34
|
+
| `missing-chunks-dir` | true | Pass (run before build) |
|
|
35
|
+
| `empty-markers` | true | Pass (list is empty) |
|
|
36
|
+
| `no-chunks` | true | Pass (nothing to scan) |
|
|
37
|
+
| `clean` | true | Pass — proceed to deploy |
|
|
38
|
+
| `hits` | false | **BLOCK** — surface hits, ask for triage |
|
|
39
|
+
|
|
40
|
+
For each hit, the gate emits `{ marker, chunk, count }` so the operator sees the exact marker string, the absolute chunk path, and the number of occurrences in that chunk. Multiple hits across chunks for the same marker are reported separately.
|
|
41
|
+
|
|
42
|
+
## Programmatic surface
|
|
43
|
+
|
|
44
|
+
```js
|
|
45
|
+
import { scanForbiddenMarkers, checkForbiddenMarkersTask } from '@a5c-ai/babysitter-library/processes/shared';
|
|
46
|
+
|
|
47
|
+
// Direct call:
|
|
48
|
+
const result = await scanForbiddenMarkers({
|
|
49
|
+
markersFile: 'scripts/forbidden-markers.txt',
|
|
50
|
+
chunksDir: '.vercel/output/static/_next/static/chunks',
|
|
51
|
+
});
|
|
52
|
+
if (!result.ok) {
|
|
53
|
+
// result.hits: Array<{ marker, chunk, count }>
|
|
54
|
+
// result.reason === 'hits'
|
|
55
|
+
process.exit(1);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// Or dispatched as a babysitter task:
|
|
59
|
+
const gate = await ctx.task(checkForbiddenMarkersTask, {
|
|
60
|
+
projectDir: '.',
|
|
61
|
+
// markersFile / chunksDir are inferred from projectDir if omitted
|
|
62
|
+
});
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Reference
|
|
66
|
+
|
|
67
|
+
- Issue: https://github.com/a5c-ai/babysitter/issues/477
|
|
68
|
+
- Helper module: `library/processes/shared/forbidden-markers-scanner.js`
|
|
69
|
+
- Origin (cookbook prototype): `cookbook/scripts/check-no-forbidden.mjs` (81 lines)
|