@a5c-ai/babysitter-github 0.1.1-staging.0a3fc67d → 0.1.1-staging.1d2024f8
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/.github/plugin.json +25 -0
- package/README.md +121 -22
- package/bin/cli.js +12 -0
- package/bin/install-shared.js +252 -1
- package/bin/install.js +60 -12
- package/bin/uninstall.js +1 -1
- package/commands/assimilate.md +37 -0
- package/commands/call.md +7 -0
- package/commands/cleanup.md +20 -0
- package/commands/contrib.md +33 -0
- package/commands/doctor.md +426 -0
- package/commands/forever.md +7 -0
- package/commands/help.md +244 -0
- package/commands/observe.md +12 -0
- package/commands/plan.md +7 -0
- package/commands/plugins.md +255 -0
- package/commands/project-install.md +17 -0
- package/commands/resume.md +8 -0
- package/commands/retrospect.md +55 -0
- package/commands/user-install.md +17 -0
- package/commands/yolo.md +7 -0
- package/package.json +8 -4
- package/plugin.json +5 -50
- package/scripts/sync-command-surfaces.js +62 -0
- package/scripts/team-install.js +8 -1
- package/skills/assimilate/SKILL.md +30 -9
- package/skills/call/SKILL.md +2 -11
- package/skills/doctor/SKILL.md +419 -8
- package/skills/help/SKILL.md +237 -7
- package/skills/observe/SKILL.md +6 -8
- package/skills/plan/SKILL.md +2 -10
- package/skills/resume/SKILL.md +3 -9
- package/skills/retrospect/SKILL.md +38 -37
- package/skills/user-install/SKILL.md +10 -7
- package/versions.json +1 -1
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "babysitter",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Orchestrate complex, multi-step workflows with event-sourced state management, hook-based extensibility, and human-in-the-loop approval -- powered by the Babysitter SDK",
|
|
5
|
+
"author": { "name": "a5c.ai", "email": "support@a5c.ai" },
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"skills": "skills/",
|
|
8
|
+
"hooks": "hooks.json",
|
|
9
|
+
"commands": "commands/",
|
|
10
|
+
"agents": "AGENTS.md",
|
|
11
|
+
"repository": {
|
|
12
|
+
"type": "git",
|
|
13
|
+
"url": "https://github.com/a5c-ai/babysitter"
|
|
14
|
+
},
|
|
15
|
+
"keywords": [
|
|
16
|
+
"orchestration",
|
|
17
|
+
"workflow",
|
|
18
|
+
"automation",
|
|
19
|
+
"event-sourced",
|
|
20
|
+
"hooks",
|
|
21
|
+
"github-copilot",
|
|
22
|
+
"agent",
|
|
23
|
+
"LLM"
|
|
24
|
+
]
|
|
25
|
+
}
|
package/README.md
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
# @a5c-ai/babysitter-github
|
|
2
2
|
|
|
3
|
-
Babysitter orchestration plugin for
|
|
3
|
+
Babysitter orchestration plugin for GitHub Copilot. It supports both:
|
|
4
|
+
|
|
5
|
+
- **GitHub Copilot CLI** via the local plugin and hook model
|
|
6
|
+
- **GitHub Copilot coding agent / cloud agent** via repository-installed skills and instructions
|
|
4
7
|
|
|
5
8
|
This package ships a complete Copilot CLI plugin bundle -- skills, lifecycle
|
|
6
9
|
hooks, and SDK integration -- that lets you run Babysitter's event-sourced,
|
|
@@ -19,6 +22,32 @@ directly.
|
|
|
19
22
|
|
|
20
23
|
## Installation
|
|
21
24
|
|
|
25
|
+
### From marketplace (recommended)
|
|
26
|
+
|
|
27
|
+
Register the a5c.ai marketplace and install the plugin:
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
# Register the marketplace
|
|
31
|
+
copilot plugin marketplace add a5c-ai/babysitter
|
|
32
|
+
|
|
33
|
+
# Install the plugin
|
|
34
|
+
copilot plugin install babysitter
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### Direct GitHub install
|
|
38
|
+
|
|
39
|
+
Install directly from the Git repository using Copilot CLI. Copilot CLI
|
|
40
|
+
discovers the plugin via `.github/plugin/marketplace.json` at the repo root:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
copilot plugin install a5c-ai/babysitter
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### Alternative Installation (npm / development)
|
|
47
|
+
|
|
48
|
+
For development or environments where the Copilot CLI plugin system is not
|
|
49
|
+
available, install via npm:
|
|
50
|
+
|
|
22
51
|
Install the SDK CLI first:
|
|
23
52
|
|
|
24
53
|
```bash
|
|
@@ -45,6 +74,30 @@ Install into a specific workspace:
|
|
|
45
74
|
babysitter-github install --workspace /path/to/repo
|
|
46
75
|
```
|
|
47
76
|
|
|
77
|
+
### GitHub Copilot cloud agent installation
|
|
78
|
+
|
|
79
|
+
For GitHub Copilot's cloud-hosted coding agent, install repository-scoped
|
|
80
|
+
Babysitter support instead of the local `~/.copilot` CLI plugin surface:
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
babysitter-github install --cloud-agent --workspace /path/to/repo
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
This installs:
|
|
87
|
+
|
|
88
|
+
- a mirrored Babysitter GitHub plugin bundle under `.github/babysitter/github-plugin/`
|
|
89
|
+
- Babysitter skills under `.github/skills/`
|
|
90
|
+
- a managed Babysitter block in `AGENTS.md`
|
|
91
|
+
- a managed Babysitter block in `.github/copilot-instructions.md`
|
|
92
|
+
- a `copilot-setup-steps` workflow, or a generated merge candidate if the repo already has one
|
|
93
|
+
|
|
94
|
+
If the repository already has a custom `copilot-setup-steps.yml`, the
|
|
95
|
+
installer preserves it and writes a merge candidate to:
|
|
96
|
+
|
|
97
|
+
```text
|
|
98
|
+
.github/workflows/copilot-setup-steps.babysitter.generated.yml
|
|
99
|
+
```
|
|
100
|
+
|
|
48
101
|
If the workspace does not already have an active process-library binding, the
|
|
49
102
|
installer bootstraps the shared global SDK process library automatically:
|
|
50
103
|
|
|
@@ -54,6 +107,14 @@ babysitter process-library:active --json
|
|
|
54
107
|
|
|
55
108
|
## Uninstallation
|
|
56
109
|
|
|
110
|
+
Via Copilot CLI:
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
copilot plugin uninstall babysitter
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
Via npm:
|
|
117
|
+
|
|
57
118
|
```bash
|
|
58
119
|
babysitter-github uninstall
|
|
59
120
|
```
|
|
@@ -64,8 +125,13 @@ The plugin provides:
|
|
|
64
125
|
|
|
65
126
|
- `skills/babysit/SKILL.md` as the core orchestration entrypoint
|
|
66
127
|
- Mode wrapper skills such as `$call`, `$plan`, and `$resume`
|
|
67
|
-
- Plugin-level lifecycle hooks for `
|
|
68
|
-
`
|
|
128
|
+
- Plugin-level lifecycle hooks for `sessionStart`, `sessionEnd`, and
|
|
129
|
+
`userPromptSubmitted`
|
|
130
|
+
|
|
131
|
+
For Copilot cloud agent, the hook scripts are mirrored into the repository as
|
|
132
|
+
part of the installed plugin bundle for reference and parity, but the hosted
|
|
133
|
+
agent path is driven by repository instructions, skills, and setup workflow
|
|
134
|
+
instead of local `~/.copilot/hooks.json`.
|
|
69
135
|
|
|
70
136
|
The process library is fetched and bound through the SDK CLI in
|
|
71
137
|
`~/.a5c/active/process-library.json`.
|
|
@@ -113,10 +179,10 @@ Fires when a new Copilot CLI session begins. The hook:
|
|
|
113
179
|
`versions.json`)
|
|
114
180
|
3. Creates baseline session state in the `.a5c` state directory
|
|
115
181
|
|
|
116
|
-
###
|
|
182
|
+
### SessionEnd
|
|
117
183
|
|
|
118
|
-
The orchestration loop driver.
|
|
119
|
-
this hook
|
|
184
|
+
The orchestration loop driver. Registered as `sessionEnd` in `hooks.json`,
|
|
185
|
+
this hook fires when the Copilot CLI session ends and:
|
|
120
186
|
|
|
121
187
|
1. Checks whether the active run has completed or emitted a completion proof
|
|
122
188
|
2. If the run is still in progress, re-injects the next orchestration step
|
|
@@ -128,7 +194,7 @@ This is what keeps Babysitter iterating autonomously within the Copilot CLI
|
|
|
128
194
|
session -- each turn performs one orchestration phase, and the Stop hook
|
|
129
195
|
decides whether to loop or yield.
|
|
130
196
|
|
|
131
|
-
###
|
|
197
|
+
### UserPromptSubmitted
|
|
132
198
|
|
|
133
199
|
Fires before a user prompt reaches the model. The hook applies
|
|
134
200
|
density-filter compression to long user prompts to reduce token usage while
|
|
@@ -139,9 +205,21 @@ preserving semantic content.
|
|
|
139
205
|
### AGENTS.md
|
|
140
206
|
|
|
141
207
|
The plugin uses `AGENTS.md` (the Copilot CLI equivalent of `CLAUDE.md`) for
|
|
142
|
-
custom agent instructions.
|
|
143
|
-
|
|
144
|
-
|
|
208
|
+
custom agent instructions. The cloud-agent installer appends a managed
|
|
209
|
+
Babysitter section to the repository root `AGENTS.md` so the hosted agent can
|
|
210
|
+
see the same orchestration guidance.
|
|
211
|
+
|
|
212
|
+
### .github/copilot-instructions.md
|
|
213
|
+
|
|
214
|
+
The cloud-agent installer also appends a managed Babysitter block to
|
|
215
|
+
`.github/copilot-instructions.md`. This gives GitHub-hosted Copilot sessions a
|
|
216
|
+
repository-wide entrypoint for the Babysitter skills and setup workflow.
|
|
217
|
+
|
|
218
|
+
### copilot-setup-steps workflow
|
|
219
|
+
|
|
220
|
+
The cloud-agent path seeds `.github/workflows/copilot-setup-steps.yml` with a
|
|
221
|
+
`copilot-setup-steps` job that installs the Babysitter SDK and initializes the
|
|
222
|
+
active process library before the cloud agent starts working.
|
|
145
223
|
|
|
146
224
|
### Environment Variables
|
|
147
225
|
|
|
@@ -174,6 +252,10 @@ Copilot CLI looks for the plugin manifest in these paths, checked in order:
|
|
|
174
252
|
|
|
175
253
|
The first match wins. This plugin uses `plugin.json` at the package root.
|
|
176
254
|
|
|
255
|
+
For marketplace discovery, Copilot CLI looks for `.github/plugin/marketplace.json`
|
|
256
|
+
at the repository root. This file lists all available plugins in the repo and is
|
|
257
|
+
used when installing via `copilot plugin install OWNER/REPO`.
|
|
258
|
+
|
|
177
259
|
### plugin.json Schema
|
|
178
260
|
|
|
179
261
|
The manifest declares metadata, skills, hooks, and optional integrations:
|
|
@@ -187,7 +269,7 @@ The manifest declares metadata, skills, hooks, and optional integrations:
|
|
|
187
269
|
| `license` | No | `string` | SPDX license identifier |
|
|
188
270
|
| `keywords` | No | `string[]` | Searchable tags for marketplace discovery |
|
|
189
271
|
| `agents` | No | `string` | Path to agents directory |
|
|
190
|
-
| `skills` | No | `
|
|
272
|
+
| `skills` | No | `string` | Path to skills directory (auto-discovers SKILL.md files in subdirectories) |
|
|
191
273
|
| `hooks` | No | `string` | Path to `hooks.json` |
|
|
192
274
|
| `mcpServers` | No | `string` | Path to `.mcp.json` for MCP server configuration |
|
|
193
275
|
|
|
@@ -200,15 +282,9 @@ Example from this plugin:
|
|
|
200
282
|
"description": "Orchestrate complex, multi-step workflows ...",
|
|
201
283
|
"author": "a5c.ai",
|
|
202
284
|
"license": "MIT",
|
|
203
|
-
"
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
"userPromptSubmitted": "hooks/user-prompt-submitted.sh"
|
|
207
|
-
},
|
|
208
|
-
"skills": [
|
|
209
|
-
{ "name": "babysit", "file": "skills/babysit/SKILL.md" },
|
|
210
|
-
{ "name": "call", "file": "skills/call/SKILL.md" }
|
|
211
|
-
],
|
|
285
|
+
"skills": "skills/",
|
|
286
|
+
"hooks": "hooks.json",
|
|
287
|
+
"commands": [],
|
|
212
288
|
"keywords": ["orchestration", "workflow", "automation"]
|
|
213
289
|
}
|
|
214
290
|
```
|
|
@@ -309,8 +385,8 @@ repositories that contain a manifest listing available plugins.
|
|
|
309
385
|
|
|
310
386
|
### Creating a Marketplace
|
|
311
387
|
|
|
312
|
-
A marketplace is a Git repository with a `marketplace.json` file
|
|
313
|
-
`.github/plugin
|
|
388
|
+
A marketplace is a Git repository with a `marketplace.json` file at the
|
|
389
|
+
repository root in `.github/plugin/marketplace.json`:
|
|
314
390
|
|
|
315
391
|
```json
|
|
316
392
|
{
|
|
@@ -387,6 +463,7 @@ These registries are available without running `marketplace add`.
|
|
|
387
463
|
```
|
|
388
464
|
plugins/babysitter-github/
|
|
389
465
|
plugin.json # Plugin manifest (skills, hooks, metadata)
|
|
466
|
+
.github/plugin.json # Plugin manifest (alternate discovery path)
|
|
390
467
|
hooks.json # Hook configuration (sessionStart, sessionEnd, userPromptSubmitted)
|
|
391
468
|
hooks/
|
|
392
469
|
session-start.sh # SessionStart lifecycle hook
|
|
@@ -414,8 +491,30 @@ plugins/babysitter-github/
|
|
|
414
491
|
AGENTS.md # Custom instructions for Copilot CLI
|
|
415
492
|
```
|
|
416
493
|
|
|
494
|
+
Cloud-agent installation additionally writes into the target repository:
|
|
495
|
+
|
|
496
|
+
```
|
|
497
|
+
.github/
|
|
498
|
+
babysitter/github-plugin/ # Mirrored plugin bundle for repo-local visibility
|
|
499
|
+
skills/
|
|
500
|
+
babysitter-babysit/SKILL.md # Installed Babysitter cloud skills
|
|
501
|
+
babysitter-call/SKILL.md
|
|
502
|
+
...
|
|
503
|
+
copilot-instructions.md # Managed Babysitter block appended
|
|
504
|
+
workflows/
|
|
505
|
+
copilot-setup-steps.yml # Managed workflow when no custom file exists
|
|
506
|
+
copilot-setup-steps.babysitter.generated.yml # Merge candidate when a custom file already exists
|
|
507
|
+
AGENTS.md # Managed Babysitter block appended
|
|
508
|
+
```
|
|
509
|
+
|
|
417
510
|
## Verification
|
|
418
511
|
|
|
512
|
+
Verify marketplace registration:
|
|
513
|
+
|
|
514
|
+
```bash
|
|
515
|
+
copilot plugin marketplace list
|
|
516
|
+
```
|
|
517
|
+
|
|
419
518
|
Verify the installed plugin:
|
|
420
519
|
|
|
421
520
|
```bash
|
package/bin/cli.js
CHANGED
|
@@ -11,6 +11,7 @@ function printUsage() {
|
|
|
11
11
|
'Usage:',
|
|
12
12
|
' babysitter-github install [--global]',
|
|
13
13
|
' babysitter-github install --workspace [path]',
|
|
14
|
+
' babysitter-github install --cloud-agent [--workspace [path]]',
|
|
14
15
|
' babysitter-github uninstall',
|
|
15
16
|
].join('\n'));
|
|
16
17
|
}
|
|
@@ -18,6 +19,7 @@ function printUsage() {
|
|
|
18
19
|
function parseInstallArgs(argv) {
|
|
19
20
|
let scope = 'global';
|
|
20
21
|
let workspace = null;
|
|
22
|
+
let cloudAgent = false;
|
|
21
23
|
const passthrough = [];
|
|
22
24
|
|
|
23
25
|
for (let i = 0; i < argv.length; i += 1) {
|
|
@@ -43,10 +45,16 @@ function parseInstallArgs(argv) {
|
|
|
43
45
|
}
|
|
44
46
|
continue;
|
|
45
47
|
}
|
|
48
|
+
if (arg === '--cloud-agent') {
|
|
49
|
+
cloudAgent = true;
|
|
50
|
+
passthrough.push(arg);
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
46
53
|
passthrough.push(arg);
|
|
47
54
|
}
|
|
48
55
|
|
|
49
56
|
return {
|
|
57
|
+
cloudAgent,
|
|
50
58
|
scope,
|
|
51
59
|
workspace,
|
|
52
60
|
passthrough,
|
|
@@ -75,6 +83,10 @@ function main() {
|
|
|
75
83
|
|
|
76
84
|
if (command === 'install') {
|
|
77
85
|
const parsed = parseInstallArgs(rest);
|
|
86
|
+
if (parsed.cloudAgent) {
|
|
87
|
+
runNodeScript(path.join(PACKAGE_ROOT, 'bin', 'install.js'), parsed.passthrough);
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
78
90
|
if (parsed.scope === 'workspace') {
|
|
79
91
|
const args = [];
|
|
80
92
|
if (parsed.workspace) {
|
package/bin/install-shared.js
CHANGED
|
@@ -5,7 +5,7 @@ const os = require('os');
|
|
|
5
5
|
const path = require('path');
|
|
6
6
|
const { spawnSync } = require('child_process');
|
|
7
7
|
|
|
8
|
-
const PLUGIN_NAME = 'babysitter
|
|
8
|
+
const PLUGIN_NAME = 'babysitter';
|
|
9
9
|
const PLUGIN_CATEGORY = 'Coding';
|
|
10
10
|
const LEGACY_HOOK_SCRIPT_NAMES = [
|
|
11
11
|
'session-start.sh',
|
|
@@ -35,6 +35,22 @@ const PLUGIN_BUNDLE_ENTRIES = [
|
|
|
35
35
|
'versions.json',
|
|
36
36
|
'AGENTS.md',
|
|
37
37
|
];
|
|
38
|
+
const CLOUD_AGENT_BUNDLE_ENTRIES = [
|
|
39
|
+
'.github',
|
|
40
|
+
'AGENTS.md',
|
|
41
|
+
'README.md',
|
|
42
|
+
'bin',
|
|
43
|
+
'commands',
|
|
44
|
+
'hooks',
|
|
45
|
+
'hooks.json',
|
|
46
|
+
'package.json',
|
|
47
|
+
'plugin.json',
|
|
48
|
+
'scripts',
|
|
49
|
+
'skills',
|
|
50
|
+
'versions.json',
|
|
51
|
+
];
|
|
52
|
+
const MANAGED_BLOCK_START = '<!-- BEGIN BABYSITTER GITHUB CLOUD AGENT -->';
|
|
53
|
+
const MANAGED_BLOCK_END = '<!-- END BABYSITTER GITHUB CLOUD AGENT -->';
|
|
38
54
|
|
|
39
55
|
function getCopilotHome() {
|
|
40
56
|
if (process.env.COPILOT_HOME) return path.resolve(process.env.COPILOT_HOME);
|
|
@@ -145,6 +161,79 @@ function writeJson(filePath, value) {
|
|
|
145
161
|
writeFileIfChanged(filePath, `${JSON.stringify(value, null, 2)}\n`);
|
|
146
162
|
}
|
|
147
163
|
|
|
164
|
+
function replaceManagedMarkdownBlock(existing, block) {
|
|
165
|
+
const normalized = String(existing || '').replace(/\r\n/g, '\n');
|
|
166
|
+
const managedBlock = `${MANAGED_BLOCK_START}\n${block.trim()}\n${MANAGED_BLOCK_END}`;
|
|
167
|
+
const escapedStart = MANAGED_BLOCK_START.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
168
|
+
const escapedEnd = MANAGED_BLOCK_END.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
169
|
+
const managedPattern = new RegExp(`${escapedStart}[\\s\\S]*?${escapedEnd}`, 'm');
|
|
170
|
+
|
|
171
|
+
if (managedPattern.test(normalized)) {
|
|
172
|
+
return normalized.replace(managedPattern, managedBlock).replace(/\n{3,}/g, '\n\n').trimEnd() + '\n';
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
if (normalized.trim().length === 0) {
|
|
176
|
+
return `${managedBlock}\n`;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
return `${normalized.trimEnd()}\n\n${managedBlock}\n`;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
function writeManagedMarkdown(filePath, block) {
|
|
183
|
+
const existing = fs.existsSync(filePath) ? fs.readFileSync(filePath, 'utf8') : '';
|
|
184
|
+
return writeFileIfChanged(filePath, replaceManagedMarkdownBlock(existing, block));
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
function readSdkVersion(packageRoot) {
|
|
188
|
+
const versionsPath = path.join(packageRoot, 'versions.json');
|
|
189
|
+
if (!fs.existsSync(versionsPath)) {
|
|
190
|
+
return 'latest';
|
|
191
|
+
}
|
|
192
|
+
try {
|
|
193
|
+
const parsed = readJson(versionsPath);
|
|
194
|
+
return typeof parsed.sdkVersion === 'string' && parsed.sdkVersion.trim() !== ''
|
|
195
|
+
? parsed.sdkVersion.trim()
|
|
196
|
+
: 'latest';
|
|
197
|
+
} catch {
|
|
198
|
+
return 'latest';
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
function toLowerHyphenName(name) {
|
|
203
|
+
return String(name)
|
|
204
|
+
.trim()
|
|
205
|
+
.toLowerCase()
|
|
206
|
+
.replace(/[^a-z0-9]+/g, '-')
|
|
207
|
+
.replace(/^-+|-+$/g, '');
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
function rewriteCloudSkill(skillId, contents) {
|
|
211
|
+
const normalized = String(contents).replace(/\r\n/g, '\n');
|
|
212
|
+
const prefixedName = `babysitter-${skillId}`;
|
|
213
|
+
let next = normalized;
|
|
214
|
+
|
|
215
|
+
if (next.startsWith('---\n')) {
|
|
216
|
+
next = next.replace(/^---\n([\s\S]*?)\n---\n?/, (_match, frontmatter) => {
|
|
217
|
+
const lines = String(frontmatter).split('\n');
|
|
218
|
+
let sawName = false;
|
|
219
|
+
const updatedLines = lines.map((line) => {
|
|
220
|
+
if (/^name:\s*/.test(line)) {
|
|
221
|
+
sawName = true;
|
|
222
|
+
return `name: ${prefixedName}`;
|
|
223
|
+
}
|
|
224
|
+
return line;
|
|
225
|
+
});
|
|
226
|
+
if (!sawName) {
|
|
227
|
+
updatedLines.push(`name: ${prefixedName}`);
|
|
228
|
+
}
|
|
229
|
+
return `---\n${updatedLines.join('\n')}\n---\n`;
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
next = next.replace(/^#\s+.+$/m, `# ${prefixedName}`);
|
|
234
|
+
return next.replace(/\n{3,}/g, '\n\n').trimEnd() + '\n';
|
|
235
|
+
}
|
|
236
|
+
|
|
148
237
|
function ensureMarketplaceEntry(marketplacePath, pluginSourcePath) {
|
|
149
238
|
const marketplace = fs.existsSync(marketplacePath)
|
|
150
239
|
? readJson(marketplacePath)
|
|
@@ -369,6 +458,167 @@ function installCopilotSurface(packageRoot, copilotHome) {
|
|
|
369
458
|
installManagedHooks(packageRoot, copilotHome);
|
|
370
459
|
}
|
|
371
460
|
|
|
461
|
+
function renderCloudAgentAgentsBlock() {
|
|
462
|
+
return [
|
|
463
|
+
'## Babysitter Cloud Agent',
|
|
464
|
+
'',
|
|
465
|
+
'This repository is configured to let GitHub Copilot cloud agent use Babysitter orchestration assets.',
|
|
466
|
+
'',
|
|
467
|
+
'- For complex multi-step work, use the Babysitter skills installed under `.github/skills/` when relevant.',
|
|
468
|
+
'- The cloud-agent setup workflow installs the Babysitter SDK before work begins.',
|
|
469
|
+
'- If you need the full orchestration instructions, run `babysitter instructions:babysit-skill --harness github-copilot --json`.',
|
|
470
|
+
'- Execute requested shell and Node tasks directly and report the results instead of describing what should be done.',
|
|
471
|
+
'- Do not revert unrelated user changes.',
|
|
472
|
+
].join('\n');
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
function renderCloudAgentCopilotInstructionsBlock() {
|
|
476
|
+
return [
|
|
477
|
+
'# Babysitter Copilot Cloud Agent Support',
|
|
478
|
+
'',
|
|
479
|
+
'This repository includes Babysitter support for GitHub Copilot cloud agent.',
|
|
480
|
+
'',
|
|
481
|
+
'- Read the nearest `AGENTS.md` instructions before making changes.',
|
|
482
|
+
'- Consider the Babysitter skills under `.github/skills/` when the task is a multi-step workflow, orchestration run, diagnosis, planning, or retrospective.',
|
|
483
|
+
'- The `copilot-setup-steps` workflow installs the Babysitter SDK and initializes the active process library before the agent starts working.',
|
|
484
|
+
'- Add repository-specific build, test, and validation commands below this managed section if they are not already documented elsewhere in the repo.',
|
|
485
|
+
].join('\n');
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
function renderCloudAgentSetupWorkflow(packageRoot) {
|
|
489
|
+
const sdkVersion = readSdkVersion(packageRoot);
|
|
490
|
+
return [
|
|
491
|
+
'name: "Copilot Setup Steps"',
|
|
492
|
+
'',
|
|
493
|
+
'on:',
|
|
494
|
+
' workflow_dispatch:',
|
|
495
|
+
' push:',
|
|
496
|
+
' paths:',
|
|
497
|
+
' - .github/workflows/copilot-setup-steps.yml',
|
|
498
|
+
' - .github/copilot-instructions.md',
|
|
499
|
+
' - .github/skills/**',
|
|
500
|
+
' - AGENTS.md',
|
|
501
|
+
' pull_request:',
|
|
502
|
+
' paths:',
|
|
503
|
+
' - .github/workflows/copilot-setup-steps.yml',
|
|
504
|
+
' - .github/copilot-instructions.md',
|
|
505
|
+
' - .github/skills/**',
|
|
506
|
+
' - AGENTS.md',
|
|
507
|
+
'',
|
|
508
|
+
'jobs:',
|
|
509
|
+
' copilot-setup-steps:',
|
|
510
|
+
' runs-on: ubuntu-latest',
|
|
511
|
+
' permissions:',
|
|
512
|
+
' contents: read',
|
|
513
|
+
' steps:',
|
|
514
|
+
' - name: Check out repository',
|
|
515
|
+
' uses: actions/checkout@v4',
|
|
516
|
+
'',
|
|
517
|
+
' - name: Set up Node.js',
|
|
518
|
+
' uses: actions/setup-node@v4',
|
|
519
|
+
' with:',
|
|
520
|
+
' node-version: 22',
|
|
521
|
+
' cache: npm',
|
|
522
|
+
'',
|
|
523
|
+
' - name: Install Babysitter SDK',
|
|
524
|
+
` run: npm install -g @a5c-ai/babysitter-sdk@${sdkVersion}`,
|
|
525
|
+
'',
|
|
526
|
+
' - name: Initialize active process library',
|
|
527
|
+
' run: babysitter process-library:active --json',
|
|
528
|
+
].join('\n') + '\n';
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
function installCloudAgentBundle(packageRoot, workspaceRoot) {
|
|
532
|
+
const bundleRoot = path.join(workspaceRoot, '.github', 'babysitter', 'github-plugin');
|
|
533
|
+
fs.rmSync(bundleRoot, { recursive: true, force: true });
|
|
534
|
+
fs.mkdirSync(bundleRoot, { recursive: true });
|
|
535
|
+
for (const entry of CLOUD_AGENT_BUNDLE_ENTRIES) {
|
|
536
|
+
const sourcePath = path.join(packageRoot, entry);
|
|
537
|
+
if (!fs.existsSync(sourcePath)) {
|
|
538
|
+
continue;
|
|
539
|
+
}
|
|
540
|
+
copyRecursive(sourcePath, path.join(bundleRoot, entry));
|
|
541
|
+
}
|
|
542
|
+
return bundleRoot;
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
function installCloudAgentSkills(packageRoot, workspaceRoot) {
|
|
546
|
+
const sourceRoot = path.join(packageRoot, 'skills');
|
|
547
|
+
if (!fs.existsSync(sourceRoot)) return [];
|
|
548
|
+
|
|
549
|
+
const targetRoot = path.join(workspaceRoot, '.github', 'skills');
|
|
550
|
+
fs.mkdirSync(targetRoot, { recursive: true });
|
|
551
|
+
const installed = [];
|
|
552
|
+
|
|
553
|
+
for (const entry of fs.readdirSync(sourceRoot, { withFileTypes: true })) {
|
|
554
|
+
if (!entry.isDirectory()) continue;
|
|
555
|
+
const sourceDir = path.join(sourceRoot, entry.name);
|
|
556
|
+
const skillId = toLowerHyphenName(entry.name);
|
|
557
|
+
const targetDir = path.join(targetRoot, `babysitter-${skillId}`);
|
|
558
|
+
fs.rmSync(targetDir, { recursive: true, force: true });
|
|
559
|
+
copyRecursive(sourceDir, targetDir);
|
|
560
|
+
const skillPath = path.join(targetDir, 'SKILL.md');
|
|
561
|
+
if (fs.existsSync(skillPath)) {
|
|
562
|
+
const rewritten = rewriteCloudSkill(skillId, fs.readFileSync(skillPath, 'utf8'));
|
|
563
|
+
fs.writeFileSync(skillPath, rewritten, 'utf8');
|
|
564
|
+
}
|
|
565
|
+
installed.push(targetDir);
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
return installed;
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
function installCloudAgentInstructions(packageRoot, workspaceRoot) {
|
|
572
|
+
const agentsPath = path.join(workspaceRoot, 'AGENTS.md');
|
|
573
|
+
const copilotInstructionsPath = path.join(workspaceRoot, '.github', 'copilot-instructions.md');
|
|
574
|
+
|
|
575
|
+
writeManagedMarkdown(agentsPath, renderCloudAgentAgentsBlock(packageRoot));
|
|
576
|
+
writeManagedMarkdown(copilotInstructionsPath, renderCloudAgentCopilotInstructionsBlock(packageRoot));
|
|
577
|
+
|
|
578
|
+
return {
|
|
579
|
+
agentsPath,
|
|
580
|
+
copilotInstructionsPath,
|
|
581
|
+
};
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
function installCloudAgentSetupSteps(packageRoot, workspaceRoot) {
|
|
585
|
+
const workflowsDir = path.join(workspaceRoot, '.github', 'workflows');
|
|
586
|
+
const workflowPath = path.join(workflowsDir, 'copilot-setup-steps.yml');
|
|
587
|
+
const examplePath = path.join(workflowsDir, 'copilot-setup-steps.babysitter.generated.yml');
|
|
588
|
+
const contents = renderCloudAgentSetupWorkflow(packageRoot);
|
|
589
|
+
|
|
590
|
+
fs.mkdirSync(workflowsDir, { recursive: true });
|
|
591
|
+
|
|
592
|
+
if (!fs.existsSync(workflowPath)) {
|
|
593
|
+
writeFileIfChanged(workflowPath, contents);
|
|
594
|
+
fs.rmSync(examplePath, { force: true });
|
|
595
|
+
return { workflowPath, examplePath: null, managed: true, needsManualMerge: false };
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
const existing = fs.readFileSync(workflowPath, 'utf8');
|
|
599
|
+
if (existing.includes('copilot-setup-steps') && existing.includes('@a5c-ai/babysitter-sdk')) {
|
|
600
|
+
writeFileIfChanged(workflowPath, contents);
|
|
601
|
+
fs.rmSync(examplePath, { force: true });
|
|
602
|
+
return { workflowPath, examplePath: null, managed: true, needsManualMerge: false };
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
writeFileIfChanged(examplePath, contents);
|
|
606
|
+
return { workflowPath, examplePath, managed: false, needsManualMerge: true };
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
function installCloudAgentSurface(packageRoot, workspaceRoot) {
|
|
610
|
+
const bundleRoot = installCloudAgentBundle(packageRoot, workspaceRoot);
|
|
611
|
+
const skillDirs = installCloudAgentSkills(packageRoot, workspaceRoot);
|
|
612
|
+
const instructions = installCloudAgentInstructions(packageRoot, workspaceRoot);
|
|
613
|
+
const setupWorkflow = installCloudAgentSetupSteps(packageRoot, workspaceRoot);
|
|
614
|
+
return {
|
|
615
|
+
bundleRoot,
|
|
616
|
+
skillDirs,
|
|
617
|
+
...instructions,
|
|
618
|
+
setupWorkflow,
|
|
619
|
+
};
|
|
620
|
+
}
|
|
621
|
+
|
|
372
622
|
function resolveBabysitterCommand(packageRoot) {
|
|
373
623
|
if (process.env.BABYSITTER_SDK_CLI) {
|
|
374
624
|
return {
|
|
@@ -442,6 +692,7 @@ module.exports = {
|
|
|
442
692
|
getHomeMarketplacePath,
|
|
443
693
|
getHomePluginRoot,
|
|
444
694
|
installCopilotSurface,
|
|
695
|
+
installCloudAgentSurface,
|
|
445
696
|
registerCopilotPlugin,
|
|
446
697
|
removeLegacyHooks,
|
|
447
698
|
removeMarketplaceEntry,
|