@a5c-ai/babysitter-openclaw 0.1.1-staging.45beae68
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +312 -0
- package/bin/cli.cjs +80 -0
- package/bin/install.cjs +370 -0
- package/bin/uninstall.cjs +172 -0
- package/commands/assimilate.md +37 -0
- package/commands/babysit.md +7 -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/extensions/hooks/agent-end.ts +127 -0
- package/extensions/hooks/before-prompt-build.ts +98 -0
- package/extensions/hooks/session-end.ts +80 -0
- package/extensions/hooks/session-start.ts +81 -0
- package/extensions/index.ts +67 -0
- package/hooks/babysitter-session-start.sh +61 -0
- package/hooks/babysitter-stop-hook.sh +44 -0
- package/hooks.json +26 -0
- package/openclaw.plugin.json +17 -0
- package/package.json +67 -0
- package/plugin.json +25 -0
- package/scripts/setup.sh +99 -0
- package/scripts/sync-command-docs.cjs +106 -0
- package/skills/assimilate/SKILL.md +38 -0
- package/skills/babysit/SKILL.md +36 -0
- package/skills/call/SKILL.md +8 -0
- package/skills/cleanup/SKILL.md +21 -0
- package/skills/contrib/SKILL.md +34 -0
- package/skills/doctor/SKILL.md +427 -0
- package/skills/forever/SKILL.md +8 -0
- package/skills/help/SKILL.md +245 -0
- package/skills/observe/SKILL.md +13 -0
- package/skills/plan/SKILL.md +8 -0
- package/skills/plugins/SKILL.md +257 -0
- package/skills/project-install/SKILL.md +18 -0
- package/skills/resume/SKILL.md +9 -0
- package/skills/retrospect/SKILL.md +56 -0
- package/skills/user-install/SKILL.md +18 -0
- package/skills/yolo/SKILL.md +8 -0
- package/versions.json +3 -0
package/README.md
ADDED
|
@@ -0,0 +1,312 @@
|
|
|
1
|
+
# @a5c-ai/babysitter-openclaw
|
|
2
|
+
|
|
3
|
+
Babysitter orchestration plugin for [OpenClaw](https://openclaw.dev), the daemon-based AI coding agent.
|
|
4
|
+
|
|
5
|
+
This package provides full Babysitter integration through OpenClaw's programmatic plugin API:
|
|
6
|
+
|
|
7
|
+
- **Programmatic hooks** via `api.on()` for session lifecycle and orchestration control
|
|
8
|
+
- **Skills** for process orchestration, diagnostics, and project management
|
|
9
|
+
- **Slash commands** forwarding to skills through OpenClaw's extension system
|
|
10
|
+
- **SDK-managed** process-library bootstrapping and state management
|
|
11
|
+
|
|
12
|
+
The SDK (`@a5c-ai/babysitter-sdk`) remains the single source of truth for orchestration, runs, tasks, replay, and state. This plugin is a thin adapter layer.
|
|
13
|
+
|
|
14
|
+
## Installation
|
|
15
|
+
|
|
16
|
+
### Primary: Babysitter Marketplace
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
babysitter plugin:install babysitter-openclaw
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
### Secondary: npm
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
npm install -g @a5c-ai/babysitter-openclaw
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
The `postinstall` script registers the plugin globally. To install into a specific workspace:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
npx @a5c-ai/babysitter-openclaw install --workspace /path/to/repo
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### Verify Installation
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
babysitter harness:discover --json
|
|
38
|
+
babysitter plugin:list-installed --json
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### Removal
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
npm uninstall -g @a5c-ai/babysitter-openclaw
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Or via the marketplace:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
babysitter plugin:uninstall babysitter-openclaw
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Architecture
|
|
54
|
+
|
|
55
|
+
### Daemon Model vs CLI Model
|
|
56
|
+
|
|
57
|
+
Most Babysitter harness plugins (Claude Code, Codex, Cursor) integrate with CLI-based agents that follow a **stop-hook model**: the agent runs, stops, a hook fires synchronously, and the agent resumes. This creates a natural iteration boundary.
|
|
58
|
+
|
|
59
|
+
OpenClaw is a **daemon-based harness**. It runs as a persistent process and exposes a programmatic plugin API rather than a filesystem-based hook surface. This changes the orchestration model:
|
|
60
|
+
|
|
61
|
+
| Aspect | CLI Harnesses (Claude Code, Codex) | OpenClaw (Daemon) |
|
|
62
|
+
|--------|-------------------------------------|-------------------|
|
|
63
|
+
| Agent lifecycle | Start, run, stop | Persistent daemon |
|
|
64
|
+
| Hook mechanism | Shell scripts via `hooks.json` | Programmatic `api.on()` callbacks |
|
|
65
|
+
| Iteration boundary | `Stop` hook (synchronous) | `agent_end` event (fire-and-forget) |
|
|
66
|
+
| Prompt injection | `UserPromptSubmit` hook | `before_prompt_build` callback |
|
|
67
|
+
| Session management | Implicit via CLI invocations | Explicit `session_start` / `session_end` events |
|
|
68
|
+
|
|
69
|
+
### How Orchestration Works
|
|
70
|
+
|
|
71
|
+
1. **Session starts** -- `session_start` hook fires, initializing Babysitter state via `babysitter hook:run --hook-type session-start --harness openclaw`.
|
|
72
|
+
2. **Each agent turn begins** -- `before_prompt_build` hook injects orchestration context (active run state, pending tasks, iteration instructions) into the prompt.
|
|
73
|
+
3. **Each agent turn ends** -- `agent_end` hook fires asynchronously (fire-and-forget via `spawn` + `unref`), triggering `babysitter hook:run --hook-type stop --harness openclaw` to advance the orchestration iteration.
|
|
74
|
+
4. **Session ends** -- `session_end` hook finalizes any active Babysitter runs.
|
|
75
|
+
|
|
76
|
+
The `agent_end` handler intentionally uses `spawn` with `unref()` rather than `execFileSync` so it does not block the next agent turn. Errors are logged to `$BABYSITTER_LOG_DIR/babysitter-agent-end-hook.log` but never propagate to the agent.
|
|
77
|
+
|
|
78
|
+
### Dual Hook Surface
|
|
79
|
+
|
|
80
|
+
The plugin ships both:
|
|
81
|
+
|
|
82
|
+
- **Programmatic hooks** (`extensions/hooks/*.ts`) -- registered via `api.on()` in `extensions/index.ts`. These are the primary integration path for OpenClaw's native plugin API.
|
|
83
|
+
- **Shell hooks** (`hooks/babysitter-session-start.sh`, `hooks/babysitter-stop-hook.sh`) -- declared in `hooks.json` for compatibility with harnesses that use the filesystem-based hook surface.
|
|
84
|
+
|
|
85
|
+
Both surfaces delegate to the same `babysitter hook:run` CLI commands.
|
|
86
|
+
|
|
87
|
+
## Capabilities
|
|
88
|
+
|
|
89
|
+
The OpenClaw adapter declares the following harness capabilities:
|
|
90
|
+
|
|
91
|
+
| Capability | Supported | Notes |
|
|
92
|
+
|------------|-----------|-------|
|
|
93
|
+
| **SessionBinding** | Yes | Binds runs to OpenClaw sessions via `session_start` / `session_end` |
|
|
94
|
+
| **Mcp** | Yes | MCP server integration via `babysitter mcp:serve` |
|
|
95
|
+
| **HeadlessPrompt** | Yes | Programmatic prompt submission via `api.sendUserMessage()` |
|
|
96
|
+
| **StopHook** | No | OpenClaw uses `agent_end` + `before_prompt_build` instead of a synchronous stop-hook model |
|
|
97
|
+
|
|
98
|
+
## Available Commands
|
|
99
|
+
|
|
100
|
+
The extension registers 17 slash commands (15 named commands plus `/babysit` and `/babysitter`). Each command forwards to its corresponding skill via OpenClaw's `/skill:<name>` mechanism.
|
|
101
|
+
|
|
102
|
+
| Command | Alias | Description |
|
|
103
|
+
|---------|-------|-------------|
|
|
104
|
+
| `/babysit` | `/babysitter` | Load the Babysitter orchestration skill |
|
|
105
|
+
| `/call` | `/babysitter:call` | Start orchestrating a complex workflow |
|
|
106
|
+
| `/plan` | `/babysitter:plan` | Plan a workflow without executing it |
|
|
107
|
+
| `/resume` | `/babysitter:resume` | Resume an existing orchestration run |
|
|
108
|
+
| `/yolo` | `/babysitter:yolo` | Run in non-interactive mode (no breakpoints) |
|
|
109
|
+
| `/forever` | `/babysitter:forever` | Start a never-ending orchestration loop |
|
|
110
|
+
| `/doctor` | `/babysitter:doctor` | Diagnose run health (journal, state, locks) |
|
|
111
|
+
| `/observe` | `/babysitter:observe` | Launch the real-time observer dashboard |
|
|
112
|
+
| `/retrospect` | `/babysitter:retrospect` | Analyze past runs for improvements |
|
|
113
|
+
| `/cleanup` | `/babysitter:cleanup` | Clean up old runs and aggregate insights |
|
|
114
|
+
| `/assimilate` | `/babysitter:assimilate` | Convert external methodologies into processes |
|
|
115
|
+
| `/contrib` | `/babysitter:contrib` | Submit feedback or contributions |
|
|
116
|
+
| `/help` | `/babysitter:help` | Babysitter documentation and usage help |
|
|
117
|
+
| `/plugins` | `/babysitter:plugins` | Manage Babysitter plugins |
|
|
118
|
+
| `/user-install` | `/babysitter:user-install` | Set up Babysitter for your user profile |
|
|
119
|
+
| `/project-install` | `/babysitter:project-install` | Onboard a project for Babysitter orchestration |
|
|
120
|
+
|
|
121
|
+
Every named command also has a `babysitter:` prefixed alias (e.g., `/babysitter:call`).
|
|
122
|
+
|
|
123
|
+
## Available Skills
|
|
124
|
+
|
|
125
|
+
Skills are defined in `skills/` and exposed through OpenClaw's skill system:
|
|
126
|
+
|
|
127
|
+
| Skill | Description |
|
|
128
|
+
|-------|-------------|
|
|
129
|
+
| **babysit** | Core orchestration skill -- iterates `.a5c/runs/<runId>/` through the deterministic replay loop |
|
|
130
|
+
| **call** | Start a new orchestrated run for a complex workflow |
|
|
131
|
+
| **plan** | Create and refine a process definition without executing it |
|
|
132
|
+
| **resume** | Resume an incomplete run, auto-discovering candidates if none specified |
|
|
133
|
+
| **yolo** | Non-interactive orchestration with no breakpoints or user prompts |
|
|
134
|
+
| **forever** | Infinite-loop process (e.g., periodic task polling with `ctx.sleep`) |
|
|
135
|
+
| **doctor** | Diagnose run health -- journal integrity, state cache, effects, locks, disk usage |
|
|
136
|
+
| **observe** | Launch the browser-based observer dashboard for real-time run monitoring |
|
|
137
|
+
| **retrospect** | Post-run analysis with suggestions for process improvements |
|
|
138
|
+
| **cleanup** | Aggregate insights from completed/failed runs, then remove old data |
|
|
139
|
+
| **assimilate** | Convert external methodologies or specifications into Babysitter process definitions |
|
|
140
|
+
| **contrib** | Submit feedback or contribute to the Babysitter project |
|
|
141
|
+
| **help** | Documentation and usage guidance for commands, processes, and methodologies |
|
|
142
|
+
| **plugins** | List, install, configure, update, or uninstall Babysitter plugins |
|
|
143
|
+
| **user-install** | Guided user onboarding -- profile setup, dependency installation, preferences |
|
|
144
|
+
| **project-install** | Guided project onboarding -- codebase analysis, profile setup, CI/CD configuration |
|
|
145
|
+
|
|
146
|
+
## Hook System
|
|
147
|
+
|
|
148
|
+
OpenClaw hooks are registered programmatically in `extensions/index.ts` via `api.on()`. Each hook delegates to the Babysitter SDK CLI.
|
|
149
|
+
|
|
150
|
+
### session_start
|
|
151
|
+
|
|
152
|
+
**File:** `extensions/hooks/session-start.ts`
|
|
153
|
+
**Maps to:** `babysitter hook:run --hook-type session-start --harness openclaw`
|
|
154
|
+
|
|
155
|
+
Fires when an OpenClaw session begins. Initializes Babysitter state, ensures the CLI is available (falls back to `npx` if not installed globally), and sets up the state directory. Runs synchronously with a 30-second timeout (60 seconds for `npx` fallback). Errors are logged but do not block the session.
|
|
156
|
+
|
|
157
|
+
### session_end
|
|
158
|
+
|
|
159
|
+
**File:** `extensions/hooks/session-end.ts`
|
|
160
|
+
**Maps to:** `babysitter hook:run --hook-type stop --harness openclaw`
|
|
161
|
+
|
|
162
|
+
Fires on session teardown. Finalizes any active Babysitter runs. Same synchronous execution model as `session_start`.
|
|
163
|
+
|
|
164
|
+
### before_prompt_build
|
|
165
|
+
|
|
166
|
+
**File:** `extensions/hooks/before-prompt-build.ts`
|
|
167
|
+
**Maps to:** `babysitter hook:run --hook-type user-prompt-submit --harness openclaw`
|
|
168
|
+
|
|
169
|
+
Fires before OpenClaw assembles the system/user prompt for each agent turn. This is the primary orchestration injection point -- Babysitter returns JSON context containing iteration instructions, active run state, and pending task information. The return value is merged into the prompt context. Runs synchronously.
|
|
170
|
+
|
|
171
|
+
### agent_end
|
|
172
|
+
|
|
173
|
+
**File:** `extensions/hooks/agent-end.ts`
|
|
174
|
+
**Maps to:** `babysitter hook:run --hook-type stop --harness openclaw`
|
|
175
|
+
|
|
176
|
+
Fires after each agent turn completes. This is the iteration driver -- it triggers Babysitter to advance the orchestration loop. Unlike other hooks, this runs **asynchronously** (fire-and-forget via `spawn` + `child.unref()`) so it does not block the next agent turn. Stderr is collected for diagnostic logging.
|
|
177
|
+
|
|
178
|
+
## Configuration
|
|
179
|
+
|
|
180
|
+
### Environment Variables
|
|
181
|
+
|
|
182
|
+
| Variable | Default | Description |
|
|
183
|
+
|----------|---------|-------------|
|
|
184
|
+
| `BABYSITTER_STATE_DIR` | `.a5c` (cwd-relative) | State directory for run storage and session data |
|
|
185
|
+
| `BABYSITTER_LOG_DIR` | `~/.a5c/logs` | Directory for hook execution logs |
|
|
186
|
+
| `BABYSITTER_RUNS_DIR` | `.a5c/runs` | Root directory for run storage |
|
|
187
|
+
| `BABYSITTER_GLOBAL_STATE_DIR` | `~/.a5c` | Global state directory |
|
|
188
|
+
| `OPENCLAW_PLUGIN_ROOT` | Auto-detected | Override the plugin root directory |
|
|
189
|
+
|
|
190
|
+
### SDK Version Pinning
|
|
191
|
+
|
|
192
|
+
The SDK version is pinned in `versions.json`:
|
|
193
|
+
|
|
194
|
+
```json
|
|
195
|
+
{"sdkVersion": "0.0.184-staging.58c6c09c"}
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
When the `babysitter` CLI is not available globally, hooks fall back to `npx -y @a5c-ai/babysitter-sdk@<pinned-version>`.
|
|
199
|
+
|
|
200
|
+
### Config Files
|
|
201
|
+
|
|
202
|
+
| File | Purpose |
|
|
203
|
+
|------|---------|
|
|
204
|
+
| `plugin.json` | Babysitter plugin manifest (name, version, hooks, commands, skills) |
|
|
205
|
+
| `openclaw.plugin.json` | OpenClaw-native plugin manifest (entrypoint, programmatic hooks, capabilities) |
|
|
206
|
+
| `hooks.json` | Shell-based hook declarations for filesystem hook surface |
|
|
207
|
+
| `versions.json` | Pinned SDK version for reproducible installations |
|
|
208
|
+
|
|
209
|
+
## Plugin Layout
|
|
210
|
+
|
|
211
|
+
```text
|
|
212
|
+
plugins/babysitter-openclaw/
|
|
213
|
+
|-- package.json # npm package manifest
|
|
214
|
+
|-- plugin.json # Babysitter plugin manifest
|
|
215
|
+
|-- openclaw.plugin.json # OpenClaw-native plugin manifest
|
|
216
|
+
|-- versions.json # Pinned SDK version
|
|
217
|
+
|-- hooks.json # Shell hook declarations
|
|
218
|
+
|-- extensions/
|
|
219
|
+
| |-- index.ts # Plugin entrypoint (api.on, registerCommand)
|
|
220
|
+
| `-- hooks/
|
|
221
|
+
| |-- session-start.ts # session_start handler
|
|
222
|
+
| |-- session-end.ts # session_end handler
|
|
223
|
+
| |-- before-prompt-build.ts # before_prompt_build handler
|
|
224
|
+
| `-- agent-end.ts # agent_end handler (async/fire-and-forget)
|
|
225
|
+
|-- hooks/
|
|
226
|
+
| |-- babysitter-session-start.sh # Shell fallback for session start
|
|
227
|
+
| `-- babysitter-stop-hook.sh # Shell fallback for stop
|
|
228
|
+
|-- skills/
|
|
229
|
+
| |-- babysit/SKILL.md
|
|
230
|
+
| |-- call/SKILL.md
|
|
231
|
+
| |-- plan/SKILL.md
|
|
232
|
+
| |-- resume/SKILL.md
|
|
233
|
+
| |-- yolo/SKILL.md
|
|
234
|
+
| |-- forever/SKILL.md
|
|
235
|
+
| |-- doctor/SKILL.md
|
|
236
|
+
| |-- observe/SKILL.md
|
|
237
|
+
| |-- retrospect/SKILL.md
|
|
238
|
+
| |-- cleanup/SKILL.md
|
|
239
|
+
| |-- assimilate/SKILL.md
|
|
240
|
+
| |-- contrib/SKILL.md
|
|
241
|
+
| |-- help/SKILL.md
|
|
242
|
+
| |-- plugins/SKILL.md
|
|
243
|
+
| |-- user-install/SKILL.md
|
|
244
|
+
| `-- project-install/SKILL.md
|
|
245
|
+
|-- commands/ # Mirrored command documentation (markdown)
|
|
246
|
+
|-- bin/
|
|
247
|
+
| |-- cli.cjs # Standalone CLI entrypoint
|
|
248
|
+
| |-- install.cjs # Global postinstall script
|
|
249
|
+
| `-- uninstall.cjs # Global preuninstall script
|
|
250
|
+
`-- scripts/
|
|
251
|
+
|-- setup.sh # Setup helper
|
|
252
|
+
`-- sync-command-docs.cjs # Regenerate mirrored command docs
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
## Development
|
|
256
|
+
|
|
257
|
+
### Local Development
|
|
258
|
+
|
|
259
|
+
Clone the monorepo and work within the plugin directory:
|
|
260
|
+
|
|
261
|
+
```bash
|
|
262
|
+
git clone https://github.com/a5c-ai/babysitter.git
|
|
263
|
+
cd babysitter
|
|
264
|
+
npm install
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
### Running Tests
|
|
268
|
+
|
|
269
|
+
```bash
|
|
270
|
+
cd plugins/babysitter-openclaw
|
|
271
|
+
npm test
|
|
272
|
+
npm run test:integration
|
|
273
|
+
npm run test:packaged-install
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
### Syncing Command Docs
|
|
277
|
+
|
|
278
|
+
Regenerate mirrored command documentation from skill definitions:
|
|
279
|
+
|
|
280
|
+
```bash
|
|
281
|
+
npm run sync:commands
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
### Publishing
|
|
285
|
+
|
|
286
|
+
```bash
|
|
287
|
+
npm run deploy # Publish to npm (public)
|
|
288
|
+
npm run deploy:staging # Publish with staging tag
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
### SDK Setup for Development
|
|
292
|
+
|
|
293
|
+
Read the pinned SDK version from `versions.json`:
|
|
294
|
+
|
|
295
|
+
```bash
|
|
296
|
+
PLUGIN_ROOT="$(pwd)"
|
|
297
|
+
SDK_VERSION=$(node -e "try{console.log(JSON.parse(require('fs').readFileSync('${PLUGIN_ROOT}/versions.json','utf8')).sdkVersion||'latest')}catch{console.log('latest')}")
|
|
298
|
+
CLI="npx -y @a5c-ai/babysitter-sdk@$SDK_VERSION"
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
## Troubleshooting
|
|
302
|
+
|
|
303
|
+
- Verify the harness with `babysitter harness:discover --json`.
|
|
304
|
+
- If `openclaw` is not detected, check `which openclaw` (Unix) or `where openclaw` (Windows).
|
|
305
|
+
- If commands do not appear, restart OpenClaw after installation so it reloads plugin metadata.
|
|
306
|
+
- If hooks fail silently, check log files in `$BABYSITTER_LOG_DIR` (defaults to `~/.a5c/logs/`).
|
|
307
|
+
- If the wrong SDK version is used, inspect `versions.json` inside the installed package root.
|
|
308
|
+
- Regenerate mirrored commands with `npm run sync:commands`.
|
|
309
|
+
|
|
310
|
+
## License
|
|
311
|
+
|
|
312
|
+
MIT
|
package/bin/cli.cjs
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
const path = require('path');
|
|
5
|
+
const { spawnSync } = require('child_process');
|
|
6
|
+
|
|
7
|
+
const PACKAGE_ROOT = path.resolve(__dirname, '..');
|
|
8
|
+
|
|
9
|
+
function printUsage() {
|
|
10
|
+
console.error([
|
|
11
|
+
'Usage:',
|
|
12
|
+
' babysitter-openclaw install [--global]',
|
|
13
|
+
' babysitter-openclaw install --workspace [path]',
|
|
14
|
+
' babysitter-openclaw uninstall [--global]',
|
|
15
|
+
' babysitter-openclaw uninstall --workspace [path]',
|
|
16
|
+
' babysitter-openclaw version',
|
|
17
|
+
' babysitter-openclaw help',
|
|
18
|
+
].join('\n'));
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function parseArgs(argv) {
|
|
22
|
+
let workspace = null;
|
|
23
|
+
|
|
24
|
+
for (let i = 0; i < argv.length; i += 1) {
|
|
25
|
+
const arg = argv[i];
|
|
26
|
+
if (arg === '--workspace') {
|
|
27
|
+
const next = argv[i + 1];
|
|
28
|
+
workspace = next && !next.startsWith('-') ? path.resolve(next) : process.cwd();
|
|
29
|
+
if (next && !next.startsWith('-')) {
|
|
30
|
+
i += 1;
|
|
31
|
+
}
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
if (arg === '--global') {
|
|
35
|
+
workspace = null;
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
throw new Error(`unknown argument: ${arg}`);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return { workspace };
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function runNodeScript(scriptPath, args) {
|
|
45
|
+
const result = spawnSync(process.execPath, [scriptPath, ...args], {
|
|
46
|
+
cwd: process.cwd(),
|
|
47
|
+
stdio: 'inherit',
|
|
48
|
+
env: process.env,
|
|
49
|
+
});
|
|
50
|
+
process.exitCode = result.status ?? 1;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function main() {
|
|
54
|
+
const [command, ...rest] = process.argv.slice(2);
|
|
55
|
+
if (!command || command === '--help' || command === '-h' || command === 'help') {
|
|
56
|
+
printUsage();
|
|
57
|
+
process.exitCode = command ? 0 : 1;
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
if (command === 'version' || command === '--version' || command === '-v') {
|
|
62
|
+
const fs = require('fs');
|
|
63
|
+
const pkg = JSON.parse(fs.readFileSync(path.join(PACKAGE_ROOT, 'package.json'), 'utf8'));
|
|
64
|
+
console.log(`${pkg.name}@${pkg.version}`);
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
if (command !== 'install' && command !== 'uninstall') {
|
|
69
|
+
console.error(`[babysitter] Unknown command: ${command}`);
|
|
70
|
+
printUsage();
|
|
71
|
+
process.exitCode = 1;
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const parsed = parseArgs(rest);
|
|
76
|
+
const args = parsed.workspace ? ['--workspace', parsed.workspace] : ['--global'];
|
|
77
|
+
runNodeScript(path.join(PACKAGE_ROOT, 'bin', `${command}.cjs`), args);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
main();
|