@bike4mind/cli 0.15.3 → 0.17.0
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 +49 -0
- package/bin/bike4mind-cli.mjs +74 -0
- package/dist/{tools-GgAy5rmD.mjs → BackgroundAgentManager-CcetLt8q.mjs} +8637 -8283
- package/dist/{ConfigStore-D4gALtkZ.mjs → ConfigStore-CNveAjEv.mjs} +451 -27
- package/dist/commands/apiCommand.mjs +1 -1
- package/dist/commands/doctorCommand.mjs +1 -1
- package/dist/commands/envCommand.mjs +1 -1
- package/dist/commands/headlessCommand.mjs +6 -2
- package/dist/commands/mcpCommand.mjs +1 -1
- package/dist/commands/updateCommand.mjs +1 -1
- package/dist/index.mjs +2273 -2061
- package/dist/{package-CfGv2cC5.mjs → package-BJU2qiwQ.mjs} +1 -1
- package/package.json +13 -9
package/README.md
CHANGED
|
@@ -578,6 +578,55 @@ Coming soon:
|
|
|
578
578
|
⏳ Session search and management
|
|
579
579
|
⏳ Tool execution monitoring
|
|
580
580
|
|
|
581
|
+
## Running as a `claude` engine inside a host app
|
|
582
|
+
|
|
583
|
+
The CLI can be driven by a host app (e.g. a kanban-style agent pipeline) as a
|
|
584
|
+
drop-in replacement for `claude` — running a pipeline **stage** or a **board AI /
|
|
585
|
+
YAML** pane with full parity (board tools over HTTP MCP, the 3-layer brief
|
|
586
|
+
injected, the spec auto-fired on turn 1, and the live-card `processing` /
|
|
587
|
+
`action_required` / `ready` signal).
|
|
588
|
+
|
|
589
|
+
A host that only launches an engine whose executable basename is exactly `claude`
|
|
590
|
+
can be pointed at a **symlink** named `claude`:
|
|
591
|
+
|
|
592
|
+
```bash
|
|
593
|
+
# Create a claude-named symlink to the CLI entry point somewhere on disk:
|
|
594
|
+
ln -s "$(pwd)/apps/cli/bin/bike4mind-cli.mjs" /usr/local/bin/claude-b4m/claude
|
|
595
|
+
|
|
596
|
+
# In the host, set the engine's `terminal_command` to that symlink path:
|
|
597
|
+
# /usr/local/bin/claude-b4m/claude
|
|
598
|
+
```
|
|
599
|
+
|
|
600
|
+
Use a **direct symlink** whose basename is `claude` — not a `package.json` bin
|
|
601
|
+
alias (it would shadow the real `claude`) and not a wrapper shell script (argv
|
|
602
|
+
gets mangled). No other setup is required; the CLI replicates claude's launch-flag
|
|
603
|
+
and lifecycle-hook contract.
|
|
604
|
+
|
|
605
|
+
### Supported claude-compatible flags
|
|
606
|
+
|
|
607
|
+
These are parsed in `bin/bike4mind-cli.mjs` into `B4M_*` env vars consumed by the
|
|
608
|
+
runtime. Unknown flags are tolerated (never hard-error) and the interactive TUI is
|
|
609
|
+
preserved (a positional prompt seeds **and** submits turn 1 without switching to
|
|
610
|
+
headless `-p`):
|
|
611
|
+
|
|
612
|
+
| Flag | Effect |
|
|
613
|
+
| --- | --- |
|
|
614
|
+
| `--mcp-config <file>` | Inject MCP servers from a claude-shape JSON (`{ "mcpServers": {...} }`). Supports HTTP transport (`type: "http"`, `url`, `headers`) with per-launch Bearer auth. |
|
|
615
|
+
| `--strict-mcp-config` | Use ONLY `--mcp-config` servers; ignore file-config and `.mcp.json` (board YAML pane). |
|
|
616
|
+
| `--append-system-prompt <text>` | Append text verbatim to the end of the system prompt (the 3-layer brief). |
|
|
617
|
+
| `--allowedTools <patterns>` | Auto-approve matching tools without a permission prompt (glob `mcp__manifold__*` or a space-separated explicit list). |
|
|
618
|
+
| `--settings <json>` | Inline JSON; the `hooks` subset drives lifecycle hooks (see below). Malformed JSON is ignored, never fatal. |
|
|
619
|
+
| `--session-id <uuid>` / `--resume <uuid>` | Pin / resume a session (board pane). `/clear` and `/compact` keep the pinned uuid; a bad `--resume` prints `No conversation found with session ID <uuid>` and exits non-zero so the host can self-heal the pane. |
|
|
620
|
+
| `<positional prompt>` | Seeds and auto-fires turn 1 while staying interactive. |
|
|
621
|
+
|
|
622
|
+
### Lifecycle hooks (`--settings.hooks`)
|
|
623
|
+
|
|
624
|
+
Mirrors claude's hook contract for the host's `action_required` signal: a
|
|
625
|
+
`Notification`/`permission_prompt` command writes a sentinel file while an
|
|
626
|
+
interactive permission prompt blocks; `PostToolUse` / `Stop` / `UserPromptSubmit`
|
|
627
|
+
commands remove it. Each hook command runs via a real shell with its stdin piped
|
|
628
|
+
then closed (EOF), so a blocking `cat > <file>` hook returns immediately.
|
|
629
|
+
|
|
581
630
|
## License
|
|
582
631
|
|
|
583
632
|
Private - Bike4Mind
|
package/bin/bike4mind-cli.mjs
CHANGED
|
@@ -111,10 +111,48 @@ const argv = await yargs(hideBin(process.argv))
|
|
|
111
111
|
type: 'string',
|
|
112
112
|
description: 'Add local Ollama models to the model picker (e.g. http://localhost:11434)',
|
|
113
113
|
})
|
|
114
|
+
// ─── claude-compatible flags (host drop-in masquerade) ──────────────────────
|
|
115
|
+
// Declared so a host's claude launch flags parse into named options instead of
|
|
116
|
+
// leaking into the positional `argv._` task. See apps/cli README "host app".
|
|
117
|
+
.option('mcp-config', {
|
|
118
|
+
type: 'string',
|
|
119
|
+
description: 'Path to a JSON file of MCP servers to inject ({ "mcpServers": {...} })',
|
|
120
|
+
})
|
|
121
|
+
.option('strict-mcp-config', {
|
|
122
|
+
type: 'boolean',
|
|
123
|
+
description: 'Use ONLY --mcp-config servers; ignore file-config and .mcp.json',
|
|
124
|
+
default: false,
|
|
125
|
+
})
|
|
126
|
+
.option('append-system-prompt', {
|
|
127
|
+
type: 'string',
|
|
128
|
+
description: 'Text appended verbatim to the end of the composed system prompt',
|
|
129
|
+
})
|
|
130
|
+
.option('allowedTools', {
|
|
131
|
+
type: 'array',
|
|
132
|
+
string: true,
|
|
133
|
+
description: 'Tool names/globs auto-approved without a permission prompt (e.g. mcp__manifold__*)',
|
|
134
|
+
})
|
|
135
|
+
.option('settings', {
|
|
136
|
+
type: 'string',
|
|
137
|
+
description: 'Inline JSON settings (currently: lifecycle hooks) merged over user config',
|
|
138
|
+
})
|
|
139
|
+
.option('session-id', {
|
|
140
|
+
type: 'string',
|
|
141
|
+
description: 'Pin this session to a fixed uuid (first launch of a resumable pane)',
|
|
142
|
+
})
|
|
143
|
+
.option('resume', {
|
|
144
|
+
type: 'string',
|
|
145
|
+
description: 'Resume an existing session by uuid',
|
|
146
|
+
})
|
|
114
147
|
.option('api-url', {
|
|
115
148
|
type: 'string',
|
|
116
149
|
description: 'Set a custom API URL (self-hosted instance) and clear auth tokens, then exit',
|
|
117
150
|
})
|
|
151
|
+
.option('no-remote-skills', {
|
|
152
|
+
type: 'boolean',
|
|
153
|
+
description: 'Skip fetching B4M-web skills for this run (local files only)',
|
|
154
|
+
default: false,
|
|
155
|
+
})
|
|
118
156
|
.option('reset-api', {
|
|
119
157
|
type: 'boolean',
|
|
120
158
|
description: 'Reset the API URL to the Bike4Mind default and clear auth tokens, then exit',
|
|
@@ -196,6 +234,42 @@ if (argv['add-dir'] && argv['add-dir'].length > 0) {
|
|
|
196
234
|
if (argv['ollama-host']) {
|
|
197
235
|
process.env.B4M_OLLAMA_HOST = argv['ollama-host'];
|
|
198
236
|
}
|
|
237
|
+
if (argv['no-remote-skills']) {
|
|
238
|
+
process.env.B4M_NO_REMOTE_SKILLS = '1';
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
// ─── claude-compatible flags → B4M_* env (read by src/index.tsx init) ─────────
|
|
242
|
+
// Mirrors the established bin→env→init channel (cf. --add-dir → B4M_ADDITIONAL_DIRS).
|
|
243
|
+
if (argv['mcp-config']) {
|
|
244
|
+
process.env.B4M_MCP_CONFIG_FILE = resolve(argv['mcp-config']);
|
|
245
|
+
}
|
|
246
|
+
if (argv['strict-mcp-config']) {
|
|
247
|
+
process.env.B4M_STRICT_MCP_CONFIG = '1';
|
|
248
|
+
}
|
|
249
|
+
if (argv['append-system-prompt']) {
|
|
250
|
+
process.env.B4M_APPEND_SYSTEM_PROMPT = argv['append-system-prompt'];
|
|
251
|
+
}
|
|
252
|
+
if (argv.allowedTools && argv.allowedTools.length > 0) {
|
|
253
|
+
// Each element may itself be a space-separated list (the host's board pane passes
|
|
254
|
+
// "a b c" as a single argv token); flatten on whitespace into discrete patterns.
|
|
255
|
+
const patterns = argv.allowedTools.flatMap((s) => String(s).split(/\s+/)).filter(Boolean);
|
|
256
|
+
process.env.B4M_ALLOWED_TOOLS = JSON.stringify(patterns);
|
|
257
|
+
}
|
|
258
|
+
if (argv.settings) {
|
|
259
|
+
process.env.B4M_SETTINGS_JSON = argv.settings;
|
|
260
|
+
}
|
|
261
|
+
if (argv['session-id']) {
|
|
262
|
+
process.env.B4M_SESSION_ID = argv['session-id'];
|
|
263
|
+
}
|
|
264
|
+
if (argv.resume) {
|
|
265
|
+
process.env.B4M_RESUME_ID = argv.resume;
|
|
266
|
+
}
|
|
267
|
+
// Positional task (claude `<prompt>` form): seeds AND submits turn 1, stays interactive.
|
|
268
|
+
// Only when it's not a known subcommand and headless -p wasn't used.
|
|
269
|
+
const KNOWN_SUBCOMMANDS = new Set(['mcp', 'update', 'doctor']);
|
|
270
|
+
if (argv.prompt === undefined && argv._.length > 0 && !KNOWN_SUBCOMMANDS.has(String(argv._[0]))) {
|
|
271
|
+
process.env.B4M_INITIAL_PROMPT = String(argv._[0]);
|
|
272
|
+
}
|
|
199
273
|
|
|
200
274
|
// Auto-detect environment: prefer production mode when dist exists
|
|
201
275
|
const distPath = join(__dirname, '../dist/index.mjs');
|