@a5c-ai/babysitter-opencode 0.1.1-staging.0dc03363

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/README.md +169 -0
  2. package/bin/cli.cjs +194 -0
  3. package/bin/cli.js +55 -0
  4. package/bin/install-shared.cjs +406 -0
  5. package/bin/install.cjs +97 -0
  6. package/bin/install.js +110 -0
  7. package/bin/uninstall.cjs +90 -0
  8. package/bin/uninstall.js +46 -0
  9. package/commands/assimilate.md +37 -0
  10. package/commands/call.md +7 -0
  11. package/commands/cleanup.md +20 -0
  12. package/commands/contrib.md +33 -0
  13. package/commands/doctor.md +426 -0
  14. package/commands/forever.md +7 -0
  15. package/commands/help.md +244 -0
  16. package/commands/observe.md +12 -0
  17. package/commands/plan.md +7 -0
  18. package/commands/plugins.md +255 -0
  19. package/commands/project-install.md +17 -0
  20. package/commands/resume.md +8 -0
  21. package/commands/retrospect.md +55 -0
  22. package/commands/status.md +8 -0
  23. package/commands/user-install.md +17 -0
  24. package/commands/yolo.md +7 -0
  25. package/hooks/hooks.json +46 -0
  26. package/hooks/session-created.js +180 -0
  27. package/hooks/session-idle.js +122 -0
  28. package/hooks/shell-env.js +86 -0
  29. package/hooks/tool-execute-after.js +105 -0
  30. package/hooks/tool-execute-before.js +107 -0
  31. package/package.json +46 -0
  32. package/plugin.json +25 -0
  33. package/scripts/sync-command-docs.cjs +105 -0
  34. package/scripts/sync-command-surfaces.js +52 -0
  35. package/skills/assimilate/SKILL.md +38 -0
  36. package/skills/babysit/SKILL.md +35 -0
  37. package/skills/call/SKILL.md +8 -0
  38. package/skills/cleanup/SKILL.md +21 -0
  39. package/skills/contrib/SKILL.md +34 -0
  40. package/skills/doctor/SKILL.md +427 -0
  41. package/skills/forever/SKILL.md +8 -0
  42. package/skills/help/SKILL.md +245 -0
  43. package/skills/observe/SKILL.md +13 -0
  44. package/skills/plan/SKILL.md +8 -0
  45. package/skills/plugins/SKILL.md +257 -0
  46. package/skills/project-install/SKILL.md +18 -0
  47. package/skills/resume/SKILL.md +9 -0
  48. package/skills/retrospect/SKILL.md +56 -0
  49. package/skills/user-install/SKILL.md +18 -0
  50. package/skills/yolo/SKILL.md +8 -0
  51. package/versions.json +4 -0
package/README.md ADDED
@@ -0,0 +1,169 @@
1
+ # @a5c-ai/babysitter-opencode
2
+
3
+ Babysitter integration package for [OpenCode](https://opencode.ai).
4
+
5
+ This package ships an OpenCode plugin bundle that provides event-sourced
6
+ orchestration, hook-based extensibility, and human-in-the-loop approval for
7
+ complex multi-step workflows -- powered by the Babysitter SDK.
8
+
9
+ ## Plugin Structure
10
+
11
+ ```
12
+ plugins/babysitter-opencode/
13
+ bin/
14
+ cli.cjs CLI entry point (babysitter-opencode command)
15
+ install.cjs Installation script
16
+ install-shared.cjs Shared installation utilities
17
+ uninstall.cjs Uninstallation script
18
+ commands/ Slash command definitions (.md files)
19
+ hooks/
20
+ hooks.json Hook registration manifest
21
+ session-created.js Initialize babysitter session state
22
+ session-idle.js Check for pending effects when idle
23
+ shell-env.js Inject env vars into shell
24
+ tool-execute-before.js Pre-tool-use hook
25
+ tool-execute-after.js Post-tool-use hook
26
+ skills/
27
+ babysit/SKILL.md Core orchestration skill
28
+ plugin.json Plugin manifest
29
+ versions.json SDK version tracking
30
+ ```
31
+
32
+ ## Installation
33
+
34
+ ### Prerequisites
35
+
36
+ Install the Babysitter SDK CLI:
37
+
38
+ ```bash
39
+ npm install -g @a5c-ai/babysitter
40
+ ```
41
+
42
+ ### Method 1: npm global install (recommended)
43
+
44
+ ```bash
45
+ npm install -g @a5c-ai/babysitter-opencode
46
+ ```
47
+
48
+ The `postinstall` script automatically copies the plugin into your current
49
+ workspace's `.opencode/plugins/babysitter/` directory.
50
+
51
+ To install into a specific workspace:
52
+
53
+ ```bash
54
+ babysitter-opencode install --workspace /path/to/project
55
+ ```
56
+
57
+ ### Method 2: Babysitter plugin manager
58
+
59
+ ```bash
60
+ babysitter plugin:install babysitter-opencode
61
+ ```
62
+
63
+ ### Method 3: Manual copy
64
+
65
+ ```bash
66
+ mkdir -p .opencode/plugins/babysitter
67
+ cp -r node_modules/@a5c-ai/babysitter-opencode/hooks .opencode/plugins/babysitter/
68
+ cp -r node_modules/@a5c-ai/babysitter-opencode/skills .opencode/plugins/babysitter/
69
+ cp -r node_modules/@a5c-ai/babysitter-opencode/commands .opencode/plugins/babysitter/
70
+ cp node_modules/@a5c-ai/babysitter-opencode/plugin.json .opencode/plugins/babysitter/
71
+ cp node_modules/@a5c-ai/babysitter-opencode/versions.json .opencode/plugins/babysitter/
72
+ ```
73
+
74
+ ## Uninstallation
75
+
76
+ ```bash
77
+ babysitter-opencode uninstall
78
+ ```
79
+
80
+ Or from a specific workspace:
81
+
82
+ ```bash
83
+ babysitter-opencode uninstall --workspace /path/to/project
84
+ ```
85
+
86
+ ## CLI Reference
87
+
88
+ ```
89
+ babysitter-opencode install [--global] Install plugin globally
90
+ babysitter-opencode install --workspace [path] Install into workspace
91
+ babysitter-opencode uninstall [--global] Uninstall plugin globally
92
+ babysitter-opencode uninstall --workspace [path] Uninstall from workspace
93
+ babysitter-opencode sync Sync command surfaces
94
+ babysitter-opencode doctor Check installation health
95
+ babysitter-opencode version Show version
96
+ babysitter-opencode help Show help
97
+ ```
98
+
99
+ ## Integration Model
100
+
101
+ OpenCode plugins are JS/TS modules placed in `.opencode/plugins/`. The babysitter
102
+ plugin registers hooks for the following OpenCode events:
103
+
104
+ | OpenCode Event | Babysitter Hook | Purpose |
105
+ |----------------|-----------------|---------|
106
+ | `session.created` | `session-start` | Initialize session state |
107
+ | `session.idle` | `stop` | Check for pending effects |
108
+ | `shell.env` | -- | Inject env vars (BABYSITTER_SESSION_ID) |
109
+ | `tool.execute.before` | `pre-tool-use` | Pre-tool-use awareness |
110
+ | `tool.execute.after` | `post-tool-use` | Post-tool-use awareness |
111
+
112
+ ### Loop Model
113
+
114
+ OpenCode does NOT have a blocking stop hook. The `session.idle` event is
115
+ fire-and-forget. Therefore, babysitter uses an **in-turn iteration** model:
116
+ the agent runs the full orchestration loop within a single turn by calling
117
+ `babysitter run:iterate` repeatedly until completion.
118
+
119
+ ### Environment Variables
120
+
121
+ The `shell.env` hook self-injects these variables since OpenCode does not
122
+ natively provide them:
123
+
124
+ - `BABYSITTER_SESSION_ID` -- Unique session identifier
125
+ - `OPENCODE_SESSION_ID` -- Alias for session ID
126
+ - `BABYSITTER_STATE_DIR` -- State directory path
127
+ - `BABYSITTER_RUNS_DIR` -- Runs directory path
128
+ - `OPENCODE_PLUGIN_ROOT` -- Plugin root directory
129
+
130
+ ### Configuration Environment Variables
131
+
132
+ | Variable | Default | Description |
133
+ |----------|---------|-------------|
134
+ | `OPENCODE_HOME` | `.opencode/` in workspace | OpenCode config root |
135
+ | `OPENCODE_WORKSPACE` | `cwd` | Workspace directory |
136
+ | `BABYSITTER_OPENCODE_PLUGIN_DIR` | `.opencode/plugins/` | Plugin install target |
137
+ | `BABYSITTER_OPENCODE_MARKETPLACE_PATH` | `~/.agents/plugins/marketplace.json` | Marketplace file |
138
+ | `BABYSITTER_SDK_CLI` | (auto-detected) | Path to SDK CLI entry |
139
+ | `BABYSITTER_GLOBAL_STATE_DIR` | `~/.a5c` | Global state directory |
140
+
141
+ ## Verification
142
+
143
+ ```bash
144
+ # Check installation health
145
+ babysitter-opencode doctor
146
+
147
+ # Or verify manually:
148
+ test -f .opencode/plugins/babysitter/index.js
149
+ test -f .opencode/plugins/babysitter/hooks/session-created.js
150
+ test -f .opencode/plugins/babysitter/hooks/shell-env.js
151
+ test -f .opencode/plugins/babysitter/skills/babysit/SKILL.md
152
+
153
+ # Verify SDK CLI
154
+ babysitter --version
155
+
156
+ # Verify process library binding
157
+ babysitter process-library:active --json
158
+ ```
159
+
160
+ ## Running Tests
161
+
162
+ ```bash
163
+ cd plugins/babysitter-opencode
164
+ npm test
165
+ ```
166
+
167
+ ## License
168
+
169
+ MIT
package/bin/cli.cjs ADDED
@@ -0,0 +1,194 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ /**
5
+ * Babysitter OpenCode CLI shim.
6
+ *
7
+ * Provides `babysitter-opencode` command for plugin management tasks
8
+ * (install, uninstall, sync, doctor). Delegates heavy lifting to the
9
+ * SDK CLI with opencode-specific flags.
10
+ */
11
+
12
+ const path = require('path');
13
+ const { spawnSync } = require('child_process');
14
+
15
+ const PACKAGE_ROOT = path.resolve(__dirname, '..');
16
+
17
+ function printUsage() {
18
+ console.log([
19
+ 'babysitter-opencode - Babysitter plugin for OpenCode',
20
+ '',
21
+ 'Usage:',
22
+ ' babysitter-opencode install [--global] Install plugin globally',
23
+ ' babysitter-opencode install --workspace [path] Install into workspace',
24
+ ' babysitter-opencode uninstall [--global] Uninstall plugin globally',
25
+ ' babysitter-opencode uninstall --workspace [path] Uninstall from workspace',
26
+ ' babysitter-opencode sync Sync command surfaces',
27
+ ' babysitter-opencode doctor Check installation health',
28
+ ' babysitter-opencode version Show version',
29
+ ' babysitter-opencode help Show this help',
30
+ ].join('\n'));
31
+ }
32
+
33
+ function parseArgs(argv) {
34
+ let workspace = null;
35
+
36
+ for (let i = 0; i < argv.length; i += 1) {
37
+ const arg = argv[i];
38
+ if (arg === '--workspace') {
39
+ const next = argv[i + 1];
40
+ workspace = next && !next.startsWith('-') ? path.resolve(next) : process.cwd();
41
+ if (next && !next.startsWith('-')) {
42
+ i += 1;
43
+ }
44
+ continue;
45
+ }
46
+ if (arg === '--global') {
47
+ workspace = null;
48
+ continue;
49
+ }
50
+ throw new Error(`unknown argument: ${arg}`);
51
+ }
52
+
53
+ return { workspace };
54
+ }
55
+
56
+ function runNodeScript(scriptPath, args) {
57
+ const result = spawnSync(process.execPath, [scriptPath, ...args], {
58
+ cwd: process.cwd(),
59
+ stdio: 'inherit',
60
+ env: process.env,
61
+ });
62
+ process.exitCode = result.status ?? 1;
63
+ }
64
+
65
+ function runDoctor(workspace) {
66
+ const fs = require('fs');
67
+ const { getOpenCodeHome, getHomePluginRoot } = require('./install-shared.cjs');
68
+
69
+ const ws = workspace || process.cwd();
70
+ const openCodeHome = getOpenCodeHome(ws);
71
+ const pluginRoot = getHomePluginRoot(ws);
72
+ let ok = true;
73
+
74
+ console.log('[babysitter] OpenCode plugin health check');
75
+ console.log(` Workspace: ${ws}`);
76
+ console.log(` OpenCode: ${openCodeHome}`);
77
+ console.log(` Plugin root: ${pluginRoot}`);
78
+ console.log('');
79
+
80
+ // Check plugin directory
81
+ if (fs.existsSync(pluginRoot)) {
82
+ console.log(' [ok] Plugin directory exists');
83
+ } else {
84
+ console.log(' [FAIL] Plugin directory missing');
85
+ ok = false;
86
+ }
87
+
88
+ // Check index.js
89
+ const indexPath = path.join(pluginRoot, 'index.js');
90
+ if (fs.existsSync(indexPath)) {
91
+ console.log(' [ok] index.js entry point exists');
92
+ } else {
93
+ console.log(' [FAIL] index.js entry point missing');
94
+ ok = false;
95
+ }
96
+
97
+ // Check plugin.json
98
+ const pluginJsonPath = path.join(pluginRoot, 'plugin.json');
99
+ if (fs.existsSync(pluginJsonPath)) {
100
+ console.log(' [ok] plugin.json exists');
101
+ } else {
102
+ console.log(' [FAIL] plugin.json missing');
103
+ ok = false;
104
+ }
105
+
106
+ // Check hooks
107
+ const hooksDir = path.join(pluginRoot, 'hooks');
108
+ if (fs.existsSync(hooksDir)) {
109
+ const hooks = fs.readdirSync(hooksDir).filter((f) => f.endsWith('.js'));
110
+ console.log(` [ok] hooks/ directory (${hooks.length} scripts)`);
111
+ } else {
112
+ console.log(' [FAIL] hooks/ directory missing');
113
+ ok = false;
114
+ }
115
+
116
+ // Check skills
117
+ const skillPath = path.join(pluginRoot, 'skills', 'babysit', 'SKILL.md');
118
+ if (fs.existsSync(skillPath)) {
119
+ console.log(' [ok] skills/babysit/SKILL.md exists');
120
+ } else {
121
+ console.log(' [WARN] skills/babysit/SKILL.md missing');
122
+ }
123
+
124
+ // Check babysitter CLI availability
125
+ const { spawnSync: spawn } = require('child_process');
126
+ const cliCheck = spawn('babysitter', ['--version'], {
127
+ stdio: ['ignore', 'pipe', 'pipe'],
128
+ encoding: 'utf8',
129
+ });
130
+ if (cliCheck.status === 0) {
131
+ console.log(` [ok] babysitter CLI: ${(cliCheck.stdout || '').trim()}`);
132
+ } else {
133
+ console.log(' [WARN] babysitter CLI not found in PATH');
134
+ }
135
+
136
+ console.log('');
137
+ if (ok) {
138
+ console.log(' All checks passed.');
139
+ } else {
140
+ console.log(' Some checks failed. Run "babysitter-opencode install" to fix.');
141
+ process.exitCode = 1;
142
+ }
143
+ }
144
+
145
+ function main() {
146
+ const [command, ...rest] = process.argv.slice(2);
147
+ if (!command || command === '--help' || command === '-h' || command === 'help') {
148
+ printUsage();
149
+ process.exitCode = command ? 0 : 1;
150
+ return;
151
+ }
152
+
153
+ switch (command) {
154
+ case 'install':
155
+ case 'uninstall': {
156
+ const parsed = parseArgs(rest);
157
+ const args = parsed.workspace ? ['--workspace', parsed.workspace] : ['--global'];
158
+ runNodeScript(path.join(PACKAGE_ROOT, 'bin', `${command}.cjs`), args);
159
+ break;
160
+ }
161
+ case 'sync': {
162
+ const syncScript = path.join(PACKAGE_ROOT, 'scripts', 'sync-command-surfaces.js');
163
+ const fs = require('fs');
164
+ if (fs.existsSync(syncScript)) {
165
+ runNodeScript(syncScript, rest);
166
+ } else {
167
+ console.error('[babysitter] sync-command-surfaces.js not found');
168
+ process.exitCode = 1;
169
+ }
170
+ break;
171
+ }
172
+ case 'doctor': {
173
+ const parsed = parseArgs(rest);
174
+ runDoctor(parsed.workspace);
175
+ break;
176
+ }
177
+ case 'version': {
178
+ try {
179
+ const pkg = require(path.join(PACKAGE_ROOT, 'package.json'));
180
+ console.log(pkg.version);
181
+ } catch {
182
+ console.log('unknown');
183
+ }
184
+ break;
185
+ }
186
+ default:
187
+ console.error(`Unknown command: ${command}`);
188
+ printUsage();
189
+ process.exitCode = 1;
190
+ break;
191
+ }
192
+ }
193
+
194
+ main();
package/bin/cli.js ADDED
@@ -0,0 +1,55 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Babysitter OpenCode CLI shim.
4
+ *
5
+ * Provides `babysitter-opencode` command for plugin management tasks
6
+ * (install, uninstall, sync). Delegates heavy lifting to the SDK CLI.
7
+ */
8
+
9
+ "use strict";
10
+
11
+ const { execSync } = require("child_process");
12
+ const path = require("path");
13
+
14
+ const PLUGIN_ROOT = path.resolve(__dirname, "..");
15
+ const args = process.argv.slice(2);
16
+ const command = args[0] || "help";
17
+
18
+ function run(cmd) {
19
+ try {
20
+ execSync(cmd, { stdio: "inherit", cwd: PLUGIN_ROOT });
21
+ } catch (err) {
22
+ process.exit(err.status || 1);
23
+ }
24
+ }
25
+
26
+ switch (command) {
27
+ case "install":
28
+ run(`node ${path.join(PLUGIN_ROOT, "bin", "install.js")}`);
29
+ break;
30
+ case "uninstall":
31
+ run(`node ${path.join(PLUGIN_ROOT, "bin", "uninstall.js")}`);
32
+ break;
33
+ case "sync":
34
+ run(`node ${path.join(PLUGIN_ROOT, "scripts", "sync-command-surfaces.js")}`);
35
+ break;
36
+ case "version":
37
+ try {
38
+ const pkg = require(path.join(PLUGIN_ROOT, "package.json"));
39
+ console.log(pkg.version);
40
+ } catch {
41
+ console.log("unknown");
42
+ }
43
+ break;
44
+ case "help":
45
+ default:
46
+ console.log(`babysitter-opencode - Babysitter plugin for OpenCode
47
+
48
+ Usage:
49
+ babysitter-opencode install Install plugin into OpenCode
50
+ babysitter-opencode uninstall Remove plugin from OpenCode
51
+ babysitter-opencode sync Sync command surfaces
52
+ babysitter-opencode version Show version
53
+ babysitter-opencode help Show this help`);
54
+ break;
55
+ }