@a5c-ai/babysitter-github 0.1.1-staging.88b9b847 → 0.1.1-staging.8e8a0133
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 +94 -24
- 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 +3 -2
- 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,26 +22,25 @@ directly.
|
|
|
19
22
|
|
|
20
23
|
## Installation
|
|
21
24
|
|
|
22
|
-
### From
|
|
25
|
+
### From marketplace (recommended)
|
|
23
26
|
|
|
24
|
-
|
|
27
|
+
Register the a5c.ai marketplace and install the plugin:
|
|
25
28
|
|
|
26
29
|
```bash
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
### From marketplace
|
|
31
|
-
|
|
32
|
-
If the a5c.ai marketplace has been registered, install by plugin name:
|
|
30
|
+
# Register the marketplace
|
|
31
|
+
copilot plugin marketplace add a5c-ai/babysitter
|
|
33
32
|
|
|
34
|
-
|
|
35
|
-
copilot plugin install babysitter
|
|
33
|
+
# Install the plugin
|
|
34
|
+
copilot plugin install babysitter
|
|
36
35
|
```
|
|
37
36
|
|
|
38
|
-
|
|
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:
|
|
39
41
|
|
|
40
42
|
```bash
|
|
41
|
-
copilot plugin
|
|
43
|
+
copilot plugin install a5c-ai/babysitter
|
|
42
44
|
```
|
|
43
45
|
|
|
44
46
|
### Alternative Installation (npm / development)
|
|
@@ -72,6 +74,30 @@ Install into a specific workspace:
|
|
|
72
74
|
babysitter-github install --workspace /path/to/repo
|
|
73
75
|
```
|
|
74
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
|
+
|
|
75
101
|
If the workspace does not already have an active process-library binding, the
|
|
76
102
|
installer bootstraps the shared global SDK process library automatically:
|
|
77
103
|
|
|
@@ -99,8 +125,13 @@ The plugin provides:
|
|
|
99
125
|
|
|
100
126
|
- `skills/babysit/SKILL.md` as the core orchestration entrypoint
|
|
101
127
|
- Mode wrapper skills such as `$call`, `$plan`, and `$resume`
|
|
102
|
-
- Plugin-level lifecycle hooks for `
|
|
103
|
-
`
|
|
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`.
|
|
104
135
|
|
|
105
136
|
The process library is fetched and bound through the SDK CLI in
|
|
106
137
|
`~/.a5c/active/process-library.json`.
|
|
@@ -148,10 +179,10 @@ Fires when a new Copilot CLI session begins. The hook:
|
|
|
148
179
|
`versions.json`)
|
|
149
180
|
3. Creates baseline session state in the `.a5c` state directory
|
|
150
181
|
|
|
151
|
-
###
|
|
182
|
+
### SessionEnd
|
|
152
183
|
|
|
153
|
-
The orchestration loop driver.
|
|
154
|
-
this hook
|
|
184
|
+
The orchestration loop driver. Registered as `sessionEnd` in `hooks.json`,
|
|
185
|
+
this hook fires when the Copilot CLI session ends and:
|
|
155
186
|
|
|
156
187
|
1. Checks whether the active run has completed or emitted a completion proof
|
|
157
188
|
2. If the run is still in progress, re-injects the next orchestration step
|
|
@@ -163,7 +194,7 @@ This is what keeps Babysitter iterating autonomously within the Copilot CLI
|
|
|
163
194
|
session -- each turn performs one orchestration phase, and the Stop hook
|
|
164
195
|
decides whether to loop or yield.
|
|
165
196
|
|
|
166
|
-
###
|
|
197
|
+
### UserPromptSubmitted
|
|
167
198
|
|
|
168
199
|
Fires before a user prompt reaches the model. The hook applies
|
|
169
200
|
density-filter compression to long user prompts to reduce token usage while
|
|
@@ -174,8 +205,21 @@ preserving semantic content.
|
|
|
174
205
|
### AGENTS.md
|
|
175
206
|
|
|
176
207
|
The plugin uses `AGENTS.md` (the Copilot CLI equivalent of `CLAUDE.md`) for
|
|
177
|
-
custom agent instructions.
|
|
178
|
-
|
|
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.
|
|
179
223
|
|
|
180
224
|
### Environment Variables
|
|
181
225
|
|
|
@@ -208,6 +252,10 @@ Copilot CLI looks for the plugin manifest in these paths, checked in order:
|
|
|
208
252
|
|
|
209
253
|
The first match wins. This plugin uses `plugin.json` at the package root.
|
|
210
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
|
+
|
|
211
259
|
### plugin.json Schema
|
|
212
260
|
|
|
213
261
|
The manifest declares metadata, skills, hooks, and optional integrations:
|
|
@@ -337,8 +385,8 @@ repositories that contain a manifest listing available plugins.
|
|
|
337
385
|
|
|
338
386
|
### Creating a Marketplace
|
|
339
387
|
|
|
340
|
-
A marketplace is a Git repository with a `marketplace.json` file
|
|
341
|
-
`.github/plugin
|
|
388
|
+
A marketplace is a Git repository with a `marketplace.json` file at the
|
|
389
|
+
repository root in `.github/plugin/marketplace.json`:
|
|
342
390
|
|
|
343
391
|
```json
|
|
344
392
|
{
|
|
@@ -415,7 +463,7 @@ These registries are available without running `marketplace add`.
|
|
|
415
463
|
```
|
|
416
464
|
plugins/babysitter-github/
|
|
417
465
|
plugin.json # Plugin manifest (skills, hooks, metadata)
|
|
418
|
-
.github/plugin.json #
|
|
466
|
+
.github/plugin.json # Plugin manifest (alternate discovery path)
|
|
419
467
|
hooks.json # Hook configuration (sessionStart, sessionEnd, userPromptSubmitted)
|
|
420
468
|
hooks/
|
|
421
469
|
session-start.sh # SessionStart lifecycle hook
|
|
@@ -443,8 +491,30 @@ plugins/babysitter-github/
|
|
|
443
491
|
AGENTS.md # Custom instructions for Copilot CLI
|
|
444
492
|
```
|
|
445
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
|
+
|
|
446
510
|
## Verification
|
|
447
511
|
|
|
512
|
+
Verify marketplace registration:
|
|
513
|
+
|
|
514
|
+
```bash
|
|
515
|
+
copilot plugin marketplace list
|
|
516
|
+
```
|
|
517
|
+
|
|
448
518
|
Verify the installed plugin:
|
|
449
519
|
|
|
450
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,
|
package/bin/install.js
CHANGED
|
@@ -10,12 +10,39 @@ const {
|
|
|
10
10
|
getCopilotHome,
|
|
11
11
|
getHomeMarketplacePath,
|
|
12
12
|
getHomePluginRoot,
|
|
13
|
+
installCloudAgentSurface,
|
|
13
14
|
installCopilotSurface,
|
|
14
15
|
warnWindowsHooks,
|
|
15
16
|
} = require('./install-shared');
|
|
16
17
|
|
|
17
18
|
const PACKAGE_ROOT = path.resolve(__dirname, '..');
|
|
18
19
|
|
|
20
|
+
function parseArgs(argv) {
|
|
21
|
+
const args = {
|
|
22
|
+
cloudAgent: false,
|
|
23
|
+
workspace: process.cwd(),
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
for (let i = 0; i < argv.length; i += 1) {
|
|
27
|
+
const arg = argv[i];
|
|
28
|
+
if (arg === '--cloud-agent') {
|
|
29
|
+
args.cloudAgent = true;
|
|
30
|
+
continue;
|
|
31
|
+
}
|
|
32
|
+
if (arg === '--workspace') {
|
|
33
|
+
const next = argv[i + 1];
|
|
34
|
+
if (next && !next.startsWith('-')) {
|
|
35
|
+
args.workspace = path.resolve(next);
|
|
36
|
+
i += 1;
|
|
37
|
+
} else {
|
|
38
|
+
args.workspace = process.cwd();
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return args;
|
|
44
|
+
}
|
|
45
|
+
|
|
19
46
|
/**
|
|
20
47
|
* Attempt to register the plugin via `copilot plugin install ./path`.
|
|
21
48
|
* Falls back to manual config.json registration if the CLI is not available.
|
|
@@ -28,26 +55,47 @@ function registerViaCopilotCli(pluginRoot) {
|
|
|
28
55
|
});
|
|
29
56
|
|
|
30
57
|
if (result.status === 0) {
|
|
31
|
-
console.log(`[babysitter
|
|
58
|
+
console.log(`[babysitter] Registered plugin via 'copilot plugin install'`);
|
|
32
59
|
return true;
|
|
33
60
|
}
|
|
34
61
|
|
|
35
62
|
// CLI not available or failed -- fall back to manual registration
|
|
36
63
|
const stderr = (result.stderr || '').trim();
|
|
37
64
|
if (result.error || stderr.includes('not found') || stderr.includes('not recognized')) {
|
|
38
|
-
console.log(`[babysitter
|
|
65
|
+
console.log(`[babysitter] Copilot CLI not found, using manual registration`);
|
|
39
66
|
} else {
|
|
40
|
-
console.warn(`[babysitter
|
|
67
|
+
console.warn(`[babysitter] 'copilot plugin install' failed: ${stderr || 'unknown error'}, using manual registration`);
|
|
41
68
|
}
|
|
42
69
|
return false;
|
|
43
70
|
}
|
|
44
71
|
|
|
45
72
|
function main() {
|
|
73
|
+
const args = parseArgs(process.argv.slice(2));
|
|
46
74
|
const copilotHome = getCopilotHome();
|
|
47
75
|
const pluginRoot = getHomePluginRoot();
|
|
48
76
|
const marketplacePath = getHomeMarketplacePath();
|
|
49
77
|
|
|
50
|
-
|
|
78
|
+
if (args.cloudAgent) {
|
|
79
|
+
const active = ensureGlobalProcessLibrary(PACKAGE_ROOT);
|
|
80
|
+
const installed = installCloudAgentSurface(PACKAGE_ROOT, args.workspace);
|
|
81
|
+
console.log(`[babysitter] Installed Copilot cloud-agent support into ${args.workspace}`);
|
|
82
|
+
console.log(`[babysitter] plugin bundle: ${installed.bundleRoot}`);
|
|
83
|
+
console.log(`[babysitter] skills: ${path.join(args.workspace, '.github', 'skills')}`);
|
|
84
|
+
console.log(`[babysitter] instructions: ${installed.copilotInstructionsPath}`);
|
|
85
|
+
console.log(`[babysitter] agents: ${installed.agentsPath}`);
|
|
86
|
+
if (installed.setupWorkflow.needsManualMerge) {
|
|
87
|
+
console.warn(`[babysitter] Existing copilot-setup-steps workflow preserved: ${installed.setupWorkflow.workflowPath}`);
|
|
88
|
+
console.warn(`[babysitter] Merge Babysitter setup steps from: ${installed.setupWorkflow.examplePath}`);
|
|
89
|
+
} else {
|
|
90
|
+
console.log(`[babysitter] setup workflow: ${installed.setupWorkflow.workflowPath}`);
|
|
91
|
+
}
|
|
92
|
+
console.log(`[babysitter] process library: ${active.binding?.dir}`);
|
|
93
|
+
console.log(`[babysitter] process library state: ${active.stateFile}`);
|
|
94
|
+
console.log('[babysitter] Cloud-agent installation complete!');
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
console.log(`[babysitter] Installing plugin to ${pluginRoot}`);
|
|
51
99
|
|
|
52
100
|
try {
|
|
53
101
|
copyPluginBundle(PACKAGE_ROOT, pluginRoot);
|
|
@@ -62,18 +110,18 @@ function main() {
|
|
|
62
110
|
installCopilotSurface(PACKAGE_ROOT, copilotHome);
|
|
63
111
|
|
|
64
112
|
const active = ensureGlobalProcessLibrary(PACKAGE_ROOT);
|
|
65
|
-
console.log(`[babysitter
|
|
66
|
-
console.log(`[babysitter
|
|
67
|
-
console.log(`[babysitter
|
|
113
|
+
console.log(`[babysitter] marketplace: ${marketplacePath}`);
|
|
114
|
+
console.log(`[babysitter] copilot config: ${path.join(copilotHome, 'config.json')}`);
|
|
115
|
+
console.log(`[babysitter] process library: ${active.binding?.dir}`);
|
|
68
116
|
if (active.defaultSpec?.cloneDir) {
|
|
69
|
-
console.log(`[babysitter
|
|
117
|
+
console.log(`[babysitter] process library clone: ${active.defaultSpec.cloneDir}`);
|
|
70
118
|
}
|
|
71
|
-
console.log(`[babysitter
|
|
119
|
+
console.log(`[babysitter] process library state: ${active.stateFile}`);
|
|
72
120
|
warnWindowsHooks();
|
|
73
|
-
console.log('[babysitter
|
|
74
|
-
console.log('[babysitter
|
|
121
|
+
console.log('[babysitter] Installation complete!');
|
|
122
|
+
console.log('[babysitter] Restart GitHub Copilot CLI to pick up the installed plugin and config changes.');
|
|
75
123
|
} catch (err) {
|
|
76
|
-
console.error(`[babysitter
|
|
124
|
+
console.error(`[babysitter] Failed to install plugin: ${err.message}`);
|
|
77
125
|
process.exitCode = 1;
|
|
78
126
|
}
|
|
79
127
|
}
|
package/bin/uninstall.js
CHANGED