bajaclaw 0.14.3 → 0.14.5

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 (72) hide show
  1. package/README.md +44 -44
  2. package/bin/bajaclaw.js +1 -1
  3. package/bin/create-bajaclaw.js +1 -1
  4. package/dist/agent.js +2 -2
  5. package/dist/api/server.js +7 -7
  6. package/dist/channels/gateway.d.ts +2 -2
  7. package/dist/channels/gateway.js +4 -4
  8. package/dist/claude.js +8 -8
  9. package/dist/cli.js +15 -15
  10. package/dist/commands/channel.js +2 -2
  11. package/dist/commands/chat.js +10 -10
  12. package/dist/commands/compact.js +2 -2
  13. package/dist/commands/daemon.js +5 -5
  14. package/dist/commands/dashboard.d.ts +1 -1
  15. package/dist/commands/dashboard.js +12 -12
  16. package/dist/commands/effort.js +4 -4
  17. package/dist/commands/guide.js +3 -3
  18. package/dist/commands/health.js +1 -1
  19. package/dist/commands/init.js +3 -3
  20. package/dist/commands/persona.js +1 -1
  21. package/dist/commands/port.js +1 -1
  22. package/dist/commands/setup.js +6 -6
  23. package/dist/commands/skill.js +8 -8
  24. package/dist/commands/subagent.js +1 -1
  25. package/dist/commands/uninstall.js +1 -1
  26. package/dist/concurrency.js +2 -2
  27. package/dist/delegation.js +2 -2
  28. package/dist/logger.js +1 -1
  29. package/dist/mcp/consumer.js +1 -1
  30. package/dist/memory/compact.js +1 -1
  31. package/dist/memory/recall.js +1 -1
  32. package/dist/model-picker.js +4 -4
  33. package/dist/persona.js +2 -2
  34. package/dist/prompt.js +1 -1
  35. package/dist/skills/auto-skiller.js +2 -2
  36. package/dist/skills/loader.d.ts +1 -1
  37. package/dist/skills/loader.js +1 -1
  38. package/dist/skills/matcher.js +1 -1
  39. package/dist/skills/porter.js +1 -1
  40. package/package.json +3 -3
  41. package/scripts/postinstall.js +4 -4
  42. package/scripts/run-tests.js +28 -0
  43. package/skills/configure-effort/SKILL.md +2 -2
  44. package/skills/configure-model/SKILL.md +3 -3
  45. package/skills/configure-tools/SKILL.md +6 -6
  46. package/skills/daily-briefing/SKILL.md +4 -4
  47. package/skills/delegate-to-subagent/SKILL.md +4 -4
  48. package/skills/setup-api/SKILL.md +10 -10
  49. package/skills/setup-compaction/SKILL.md +6 -6
  50. package/skills/setup-daemon/SKILL.md +1 -1
  51. package/skills/setup-dashboard/SKILL.md +2 -2
  52. package/skills/setup-discord/SKILL.md +9 -9
  53. package/skills/setup-heartbeat/SKILL.md +4 -4
  54. package/skills/setup-mcp-port/SKILL.md +2 -2
  55. package/skills/setup-memory-sync/SKILL.md +2 -2
  56. package/skills/setup-profile/SKILL.md +2 -2
  57. package/skills/setup-subagent/SKILL.md +1 -1
  58. package/skills/setup-telegram/SKILL.md +10 -10
  59. package/skills/setup-uninstall/SKILL.md +6 -6
  60. package/skills/web-research/SKILL.md +2 -2
  61. package/templates/code/AGENT.md +2 -2
  62. package/templates/code/SOUL.md +5 -2
  63. package/templates/custom/AGENT.md +1 -1
  64. package/templates/custom/SOUL.md +5 -2
  65. package/templates/outreach/AGENT.md +2 -2
  66. package/templates/outreach/SOUL.md +5 -2
  67. package/templates/research/AGENT.md +2 -2
  68. package/templates/research/SOUL.md +5 -2
  69. package/templates/social/AGENT.md +2 -2
  70. package/templates/social/SOUL.md +5 -2
  71. package/templates/support/AGENT.md +1 -1
  72. package/templates/support/SOUL.md +5 -2
package/README.md CHANGED
@@ -7,17 +7,17 @@
7
7
  ██╔══██╗██╔══██║██ ██║██╔══██║ ██║ ██║ ██╔══██║██║███╗██║
8
8
  ██████╔╝██║ ██║╚█████╔╝██║ ██║ ╚██████╗███████╗██║ ██║╚███╔███╔╝
9
9
  ╚═════╝ ╚═╝ ╚═╝ ╚════╝ ╚═╝ ╚═╝ ╚═════╝╚══════╝╚═╝ ╚═╝ ╚══╝╚══╝
10
- autonomous agents on your terms · MIT · v0.14.3
10
+ autonomous agents on your terms · MIT · v0.14.5
11
11
  ```
12
12
 
13
13
  **BajaClaw is a long-running agent runtime for the `claude` CLI.** It turns
14
14
  the one-shot `claude -p` command into an always-on, scheduled, memory-backed,
15
- skill-matching autonomous agent with a local dashboard, multiple profiles,
15
+ skill-matching autonomous agent - with a local dashboard, multiple profiles,
16
16
  OS-native scheduling, and first-class MCP integration.
17
17
 
18
18
  You install it once. It sets itself up. You run `bajaclaw start`. It goes.
19
19
 
20
- > The name is a tribute to Baja Blast the author's favorite soda. The
20
+ > The name is a tribute to Baja Blast - the author's favorite soda. The
21
21
  > dashboard ships in that same tropical-lime teal on purpose.
22
22
 
23
23
  ---
@@ -36,7 +36,7 @@ That's it. The post-install runs `bajaclaw setup` automatically, which:
36
36
  - Runs the health check and tells you if anything's off
37
37
 
38
38
  **Requirements**: Node 20+ and the `claude` CLI backend on your `PATH`.
39
- BajaClaw drives the backend as a subprocess whatever login/subscription
39
+ BajaClaw drives the backend as a subprocess - whatever login/subscription
40
40
  that CLI uses is what BajaClaw uses. BajaClaw itself never sees credentials.
41
41
 
42
42
  First run, end-to-end:
@@ -82,7 +82,7 @@ A BajaClaw **cycle** is one pass of the 13-step loop in
82
82
 
83
83
  You can run a cycle manually (`bajaclaw start`), schedule it (`bajaclaw
84
84
  daemon install`), or trigger it externally (`bajaclaw trigger <event>`).
85
- Cycles are idempotent safe to re-run.
85
+ Cycles are idempotent - safe to re-run.
86
86
 
87
87
  ---
88
88
 
@@ -101,9 +101,9 @@ You can invoke it from a Claude Code session the same way you invoke any
101
101
  other agent. The BajaClaw profile is the durable side; the Claude Code
102
102
  descriptor is the handle.
103
103
 
104
- ### Claude Code skills compatible format, **isolated scope**
104
+ ### Claude Code skills - compatible format, **isolated scope**
105
105
 
106
- A BajaClaw skill is a `SKILL.md` file with YAML frontmatter byte-for-byte
106
+ A BajaClaw skill is a `SKILL.md` file with YAML frontmatter - byte-for-byte
107
107
  the same shape Claude Code uses. But BajaClaw reads only BajaClaw-owned
108
108
  directories:
109
109
 
@@ -114,7 +114,7 @@ directories:
114
114
  | 3 | `~/.bajaclaw/skills/` |
115
115
  | 4 | `<repo>/skills/` (built-ins) |
116
116
 
117
- `~/.claude/skills/` is **not** read automatically that keeps the two
117
+ `~/.claude/skills/` is **not** read automatically - that keeps the two
118
118
  agents from stepping on each other's skill libraries.
119
119
 
120
120
  **Porting skills from Claude Code is a one-liner:**
@@ -137,7 +137,7 @@ Skills`. See [`docs/skills.md`](docs/skills.md).
137
137
  ### Self-knowledge (built-in guides)
138
138
 
139
139
  BajaClaw knows how to configure itself. Ship 13 built-in skills describe
140
- the procedure for every integration ask your agent in plain language:
140
+ the procedure for every integration - ask your agent in plain language:
141
141
 
142
142
  > "Help me set up Telegram."
143
143
  > "Walk me through connecting Discord."
@@ -171,7 +171,7 @@ Procedure / Pitfalls / Verification sections into
171
171
  `~/.bajaclaw/skills/auto/<name>/` for review.
172
172
 
173
173
  This is BajaClaw's take on the "create a skill after a complex task"
174
- behavior from agents like Hermes capture procedures the first time you
174
+ behavior from agents like Hermes - capture procedures the first time you
175
175
  solve them so repeats are faster.
176
176
 
177
177
  Candidates live in `auto/` until you promote them:
@@ -187,7 +187,7 @@ Tune the trigger in the profile's `config.json`:
187
187
  { "autoSkill": { "enabled": true, "minToolUses": 5, "maxPerDay": 10 } }
188
188
  ```
189
189
 
190
- ### MCP isolated by default
190
+ ### MCP - isolated by default
191
191
 
192
192
  BajaClaw uses its own MCP config. The desktop CLI's `mcpServers` is **not**
193
193
  inherited by default. Merge order per cycle (highest wins):
@@ -195,7 +195,7 @@ inherited by default. Merge order per cycle (highest wins):
195
195
  1. `<profile>/agent-mcp-config.json`
196
196
  2. `<profile>/mcp-config.json`
197
197
  3. `~/.bajaclaw/mcp-config.json` (user-global BajaClaw)
198
- 4. Desktop CLI config **only if `mergeDesktopMcp: true`** in the profile
198
+ 4. Desktop CLI config - **only if `mergeDesktopMcp: true`** in the profile
199
199
 
200
200
  Port servers from Claude Code on demand:
201
201
 
@@ -212,7 +212,7 @@ desktop MCP list on every cycle (pre-0.4 behavior).
212
212
  BajaClaw's own MCP entry (`bajaclaw`) is skipped automatically during port
213
213
  to avoid self-references.
214
214
 
215
- ### MCP expose
215
+ ### MCP - expose
216
216
 
217
217
  BajaClaw is itself an MCP server. `bajaclaw setup` auto-registers it so your
218
218
  desktop MCP client (Claude Desktop and anything else that reads that config)
@@ -220,10 +220,10 @@ can query BajaClaw's state directly.
220
220
 
221
221
  **Resources:**
222
222
 
223
- - `bajaclaw://profiles` list of profiles
223
+ - `bajaclaw://profiles` - list of profiles
224
224
  - `bajaclaw://profile/<n>/agents`
225
- - `bajaclaw://profile/<n>/memories` FTS5-searchable
226
- - `bajaclaw://profile/<n>/cycles` recent cycle history
225
+ - `bajaclaw://profile/<n>/memories` - FTS5-searchable
226
+ - `bajaclaw://profile/<n>/cycles` - recent cycle history
227
227
  - `bajaclaw://profile/<n>/schedules`
228
228
 
229
229
  **Tools:**
@@ -234,7 +234,7 @@ can query BajaClaw's state directly.
234
234
  - `bajaclaw_skill_list({ profile })`
235
235
 
236
236
  Which means: from any MCP client, you can ask "what does BajaClaw remember
237
- about X?" or "queue a task for the default agent" without leaving your
237
+ about X?" or "queue a task for the default agent" - without leaving your
238
238
  current session.
239
239
 
240
240
  Run it manually with `bajaclaw mcp serve --stdio` or as HTTP SSE with
@@ -249,7 +249,7 @@ Set `memorySync: true` in the profile config and BajaClaw will:
249
249
  - Write a digest to `~/.claude/memory/bajaclaw-<profile>.md` after each
250
250
  cycle, so Claude Code sessions can see what BajaClaw has been learning
251
251
 
252
- Disabled by default memory sharing is deliberate, not automatic. See
252
+ Disabled by default - memory sharing is deliberate, not automatic. See
253
253
  [`docs/memory.md`](docs/memory.md).
254
254
 
255
255
  ### Sub-agent delegation
@@ -257,7 +257,7 @@ Disabled by default — memory sharing is deliberate, not automatic. See
257
257
  For heavy coding work, an agent using the `code` template plans and then
258
258
  delegates to a dedicated Claude Code sub-session via `delegateCoding` in
259
259
  [`src/delegation.ts`](src/delegation.ts). The orchestrator never writes code
260
- itself that keeps its transcript reviewable before any code exists. See
260
+ itself - that keeps its transcript reviewable before any code exists. See
261
261
  [`docs/integration.md`](docs/integration.md).
262
262
 
263
263
  ---
@@ -267,12 +267,12 @@ itself — that keeps its transcript reviewable before any code exists. See
267
267
  ```
268
268
  bajaclaw start # runs a cycle against the default profile
269
269
  bajaclaw start --dry-run # shows the assembled prompt + exact argv
270
- bajaclaw dashboard # http://localhost:7337 live cycle feed, memories
270
+ bajaclaw dashboard # http://localhost:7337 - live cycle feed, memories
271
271
  bajaclaw daemon install # schedule a 15-minute heartbeat via your OS
272
272
  bajaclaw daemon start # supervisor loop with exponential backoff
273
273
  ```
274
274
 
275
- The default profile has **full tool access** Read, Write, Edit, Bash,
275
+ The default profile has **full tool access** - Read, Write, Edit, Bash,
276
276
  Grep, Glob, WebSearch, WebFetch, plus every MCP tool you've configured. It's
277
277
  a real autonomous agent, not a sandboxed assistant.
278
278
 
@@ -313,7 +313,7 @@ BAJACLAW_PROFILE=triage bajaclaw daemon start
313
313
 
314
314
  | template | shape |
315
315
  |---|---|
316
- | `custom` | blank slate, full tools the default |
316
+ | `custom` | blank slate, full tools - the default |
317
317
  | `research` | research + synthesis + artifacts; full tools |
318
318
  | `outreach` | email prospecting + drafting |
319
319
  | `support` | inbox triage + reply drafts |
@@ -333,7 +333,7 @@ classifies the task and routes it to the cheapest capable model:
333
333
  | **Sonnet** | normal work, answers, summaries | 5 memories, 2 skills, 8 turns |
334
334
  | **Opus** | planning, coding, refactoring, deep research, reflection | 7 memories, 3 skills, 14 turns |
335
335
 
336
- The classifier is a heuristic zero extra backend calls for routing.
336
+ The classifier is a heuristic - zero extra backend calls for routing.
337
337
  Post-cycle memory extract + auto-skill synthesis are **skipped**
338
338
  entirely for Haiku cycles. This keeps cheap tasks cheap.
339
339
 
@@ -353,8 +353,8 @@ bajaclaw serve --api-key $(openssl rand -hex 32) # with auth
353
353
  bajaclaw serve --host 0.0.0.0 --api-key <key> # bind all (auth required)
354
354
  ```
355
355
 
356
- Anything that speaks the OpenAI chat API Cursor, Open WebUI, LibreChat,
357
- `openai` SDKs, curl, LangChain, LlamaIndex can drive BajaClaw as an LLM.
356
+ Anything that speaks the OpenAI chat API - Cursor, Open WebUI, LibreChat,
357
+ `openai` SDKs, curl, LangChain, LlamaIndex - can drive BajaClaw as an LLM.
358
358
  The request's `model` field is a profile name; each request is one full
359
359
  cycle (memory recall, skill matching, MCP inheritance, backend call,
360
360
  post-cycle extract).
@@ -415,14 +415,14 @@ the notice with `BAJACLAW_NO_UPDATE_NOTICE=1`.
415
415
  ```
416
416
  bajaclaw setup # idempotent bootstrap; safe to re-run
417
417
  bajaclaw setup --profile foo # use a different default profile name
418
- bajaclaw uninstall # dry-run shows what would be removed
418
+ bajaclaw uninstall # dry-run - shows what would be removed
419
419
  bajaclaw uninstall --yes # actually tear everything down
420
420
  bajaclaw uninstall --yes --keep-data # remove integrations, keep ~/.bajaclaw/
421
421
  ```
422
422
 
423
423
  `setup` is the re-run button. If the MCP registration gets knocked out of
424
424
  the desktop config, or the agent descriptor is missing, or you moved your
425
- home directory `bajaclaw setup` fixes it all without touching existing
425
+ home directory - `bajaclaw setup` fixes it all without touching existing
426
426
  data.
427
427
 
428
428
  `uninstall` tears down everything BajaClaw has created:
@@ -435,7 +435,7 @@ data.
435
435
  - Removes `~/.claude/memory/bajaclaw-*.md` sync files
436
436
  - Removes `~/.bajaclaw/` entirely (unless `--keep-data`)
437
437
 
438
- It does **not** `npm uninstall` itself that's one command you still run by
438
+ It does **not** `npm uninstall` itself - that's one command you still run by
439
439
  hand, printed at the end of the teardown.
440
440
 
441
441
  ---
@@ -483,7 +483,7 @@ Memories`. After the cycle finishes, a 1-turn Haiku call reads the
483
483
  Those facts become FTS-indexed rows with `source=cycle` and
484
484
  `source_cycle_id=<id>`. Next cycle, they're eligible for recall again.
485
485
 
486
- Kinds are a soft taxonomy BajaClaw doesn't enforce them: `fact`,
486
+ Kinds are a soft taxonomy - BajaClaw doesn't enforce them: `fact`,
487
487
  `decision`, `preference`, `todo`, `reference`, `claude-code`, `imported`.
488
488
 
489
489
  Full detail: [`docs/memory.md`](docs/memory.md).
@@ -493,7 +493,7 @@ Full detail: [`docs/memory.md`](docs/memory.md).
493
493
  ## Channels (optional)
494
494
 
495
495
  BajaClaw ships optional adapters for **Telegram** and **Discord** bots.
496
- They're `optionalDependencies` not installed unless you use them.
496
+ They're `optionalDependencies` - not installed unless you use them.
497
497
 
498
498
  ```
499
499
  bajaclaw channel add default telegram --token <BOT_TOKEN>
@@ -519,7 +519,7 @@ bajaclaw dashboard
519
519
  Single HTML file served at `http://localhost:7337` (port in `config.json`).
520
520
  Dark theme, vanilla JS, Tailwind CDN. Live cycle feed, FTS-searchable
521
521
  memory browser, schedule editor, inbox/tasks list. Reads directly from the
522
- SQLite DB no extra service.
522
+ SQLite DB - no extra service.
523
523
 
524
524
  ---
525
525
 
@@ -627,20 +627,20 @@ Deeper in [`docs/architecture.md`](docs/architecture.md).
627
627
 
628
628
  ## Docs
629
629
 
630
- - [`architecture.md`](docs/architecture.md) module map, cycle, on-disk layout
631
- - [`integration.md`](docs/integration.md) Claude Code + MCP seams in detail
632
- - [`commands.md`](docs/commands.md) full command reference
633
- - [`agents.md`](docs/agents.md) profiles, templates, AGENT.md / SOUL.md / HEARTBEAT.md
634
- - [`skills.md`](docs/skills.md) scoping, matching, self-generated skills
635
- - [`memory.md`](docs/memory.md) FTS5 recall + extract, cross-tool sync
636
- - [`heartbeat.md`](docs/heartbeat.md) scheduling + supervisor
630
+ - [`architecture.md`](docs/architecture.md) - module map, cycle, on-disk layout
631
+ - [`integration.md`](docs/integration.md) - Claude Code + MCP seams in detail
632
+ - [`commands.md`](docs/commands.md) - full command reference
633
+ - [`agents.md`](docs/agents.md) - profiles, templates, AGENT.md / SOUL.md / HEARTBEAT.md
634
+ - [`skills.md`](docs/skills.md) - scoping, matching, self-generated skills
635
+ - [`memory.md`](docs/memory.md) - FTS5 recall + extract, cross-tool sync
636
+ - [`heartbeat.md`](docs/heartbeat.md) - scheduling + supervisor
637
637
  - [`channels.md`](docs/channels.md)
638
- - [`api.md`](docs/api.md) OpenAI-compatible HTTP endpoint Telegram + Discord
639
- - [`security.md`](docs/security.md) threat model + mitigations
640
- - [`fair-use.md`](docs/fair-use.md) how BajaClaw stays a thin wrapper
641
- - [`troubleshooting.md`](docs/troubleshooting.md) common fixes
642
- - [`faq.md`](docs/faq.md) frequently asked
643
- - [`contributing.md`](docs/contributing.md) dev setup, style, release
638
+ - [`api.md`](docs/api.md) - OpenAI-compatible HTTP endpoint - Telegram + Discord
639
+ - [`security.md`](docs/security.md) - threat model + mitigations
640
+ - [`fair-use.md`](docs/fair-use.md) - how BajaClaw stays a thin wrapper
641
+ - [`troubleshooting.md`](docs/troubleshooting.md) - common fixes
642
+ - [`faq.md`](docs/faq.md) - frequently asked
643
+ - [`contributing.md`](docs/contributing.md) - dev setup, style, release
644
644
 
645
645
  ---
646
646
 
package/bin/bajaclaw.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- // Thin launcher resolves tsx and invokes src/cli.ts, or dist/cli.js if built.
2
+ // Thin launcher - resolves tsx and invokes src/cli.ts, or dist/cli.js if built.
3
3
  import { spawnSync } from "node:child_process";
4
4
  import { existsSync } from "node:fs";
5
5
  import { dirname, join } from "node:path";
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- // npx create-bajaclaw [name] bootstrap BajaClaw.
2
+ // npx create-bajaclaw [name] - bootstrap BajaClaw.
3
3
  // With no args: runs `bajaclaw setup` to create the default profile.
4
4
  // With a name: runs `bajaclaw init <name>` to scaffold that specific profile.
5
5
  import { spawnSync } from "node:child_process";
package/dist/agent.js CHANGED
@@ -163,7 +163,7 @@ async function runCycleInner(input) {
163
163
  }
164
164
  recordSuccess(db);
165
165
  // Store up to 8k chars of the response. Needed for conversational
166
- // history on channel-sourced cycles the old 300-char cap made
166
+ // history on channel-sourced cycles - the old 300-char cap made
167
167
  // every prior turn look like a stub. 8k ≈ 2k tokens; beyond that
168
168
  // we rely on memory extraction to preserve context.
169
169
  db.prepare("UPDATE cycles SET finished_at=?, status=?, response_preview=?, cost_usd=?, input_tokens=?, output_tokens=?, turns=? WHERE id=?").run(finished, "ok", result.text.slice(0, 8000), result.costUsd ?? null, result.inputTokens ?? null, result.outputTokens ?? null, result.turns ?? null, cycleId);
@@ -171,7 +171,7 @@ async function runCycleInner(input) {
171
171
  db.prepare("UPDATE tasks SET status='done', cycle_id=? WHERE id=?").run(cycleId, popped.id);
172
172
  }
173
173
  // Post-cycle memory extraction + auto-skill synthesis. Both are extra
174
- // backend calls skip them on cheap (Haiku) cycles and on trivially
174
+ // backend calls - skip them on cheap (Haiku) cycles and on trivially
175
175
  // short responses to keep token usage tight.
176
176
  const shouldDoPostWork = !result.dryRun && result.text.length >= 120 && picked.tier !== "haiku";
177
177
  if (shouldDoPostWork) {
@@ -2,10 +2,10 @@
2
2
  //
3
3
  // Endpoints:
4
4
  // GET /health
5
- // GET /v1/models lists exposed profiles as models
6
- // POST /v1/chat/completions OpenAI chat (stream + non-stream)
7
- // POST /v1/bajaclaw/cycle native: { profile, task } -> full CycleOutput
8
- // POST /v1/bajaclaw/tasks native: enqueue without waiting
5
+ // GET /v1/models - lists exposed profiles as models
6
+ // POST /v1/chat/completions - OpenAI chat (stream + non-stream)
7
+ // POST /v1/bajaclaw/cycle - native: { profile, task } -> full CycleOutput
8
+ // POST /v1/bajaclaw/tasks - native: enqueue without waiting
9
9
  //
10
10
  // Auth: if config.api.apiKey is set, require `Authorization: Bearer <key>`.
11
11
  // Bind: defaults to 127.0.0.1 unless config.api.host is explicit.
@@ -139,18 +139,18 @@ function listProfilesAsModels(exposed) {
139
139
  const names = filter ? all.filter((n) => filter.has(n)) : all;
140
140
  const now = Math.floor(Date.now() / 1000);
141
141
  const out = [];
142
- // Bare profile names use each profile's configured model.
142
+ // Bare profile names - use each profile's configured model.
143
143
  for (const id of names) {
144
144
  out.push({ id, object: "model", created: now, owned_by: "bajaclaw" });
145
145
  }
146
- // profile:model virtual entries pick any model per request without
146
+ // profile:model virtual entries - pick any model per request without
147
147
  // touching profile config.
148
148
  for (const id of names) {
149
149
  for (const m of KNOWN_MODELS) {
150
150
  out.push({ id: `${id}:${m.id}`, object: "model", created: now, owned_by: "bajaclaw" });
151
151
  }
152
152
  }
153
- // Bare model-id shortcuts apply to the default profile.
153
+ // Bare model-id shortcuts - apply to the default profile.
154
154
  if (names.includes("default")) {
155
155
  for (const m of KNOWN_MODELS) {
156
156
  out.push({ id: m.id, object: "model", created: now, owned_by: "bajaclaw" });
@@ -5,14 +5,14 @@ export declare function startAllGateways(profile: string): Promise<void>;
5
5
  /** Backwards-compatible entry point: starts adapters, then blocks. */
6
6
  export declare function runGateway(profile: string): Promise<void>;
7
7
  /** Send an agent reply back to whatever channel originated a task.
8
- * `source` is formatted as "telegram:<id>" or "discord:<id>" the
8
+ * `source` is formatted as "telegram:<id>" or "discord:<id>" - the
9
9
  * same string written into tasks.source by the inbound handlers.
10
10
  * Also ends any typing indicator associated with that source. */
11
11
  export declare function replyToSource(profile: string, source: string, text: string): Promise<void>;
12
12
  /** Show the platform's "typing…" indicator for the given source. The
13
13
  * adapter internally refreshes on the platform's cadence (Telegram
14
14
  * indicator lasts ~5s, Discord ~10s) until `endTyping(source)` is
15
- * called. Safe to call multiple times a second call replaces the
15
+ * called. Safe to call multiple times - a second call replaces the
16
16
  * first. No-ops if the adapter isn't loaded. */
17
17
  export declare function beginTyping(profile: string, source: string): void;
18
18
  export declare function endTyping(source: string): void;
@@ -54,7 +54,7 @@ export async function runGateway(profile) {
54
54
  await new Promise(() => { });
55
55
  }
56
56
  /** Send an agent reply back to whatever channel originated a task.
57
- * `source` is formatted as "telegram:<id>" or "discord:<id>" the
57
+ * `source` is formatted as "telegram:<id>" or "discord:<id>" - the
58
58
  * same string written into tasks.source by the inbound handlers.
59
59
  * Also ends any typing indicator associated with that source. */
60
60
  export async function replyToSource(profile, source, text) {
@@ -74,7 +74,7 @@ export async function replyToSource(profile, source, text) {
74
74
  /** Show the platform's "typing…" indicator for the given source. The
75
75
  * adapter internally refreshes on the platform's cadence (Telegram
76
76
  * indicator lasts ~5s, Discord ~10s) until `endTyping(source)` is
77
- * called. Safe to call multiple times a second call replaces the
77
+ * called. Safe to call multiple times - a second call replaces the
78
78
  * first. No-ops if the adapter isn't loaded. */
79
79
  export function beginTyping(profile, source) {
80
80
  const colon = source.indexOf(":");
@@ -94,7 +94,7 @@ export function beginTyping(profile, source) {
94
94
  const stop = a.startTyping(id);
95
95
  activeTyping.set(source, stop);
96
96
  }
97
- catch { /* ignore typing is best-effort */ }
97
+ catch { /* ignore - typing is best-effort */ }
98
98
  }
99
99
  export function endTyping(source) {
100
100
  const stop = activeTyping.get(source);
@@ -149,7 +149,7 @@ async function startTelegram(profile, c, log) {
149
149
  startTyping: (chatId) => {
150
150
  // Telegram's typing indicator auto-clears after 5s, so re-send
151
151
  // every 4s until stopped. `sendChatAction` errors are swallowed
152
- // they'd be noise (bot blocked, etc.) and the agent still has
152
+ // - they'd be noise (bot blocked, etc.) and the agent still has
153
153
  // a reply path via the eventual send.
154
154
  const send = () => {
155
155
  bot.sendChatAction(Number(chatId), "typing").catch(() => undefined);
package/dist/claude.js CHANGED
@@ -57,7 +57,7 @@ export function buildCommand(prompt, opts) {
57
57
  // --effort is the real knob for "how much runway does the agent get".
58
58
  // Levels: low < medium < high < xhigh < max. Higher = more turns
59
59
  // + more tokens + higher cost. claude's internal turn budget is
60
- // tied to this level there is no `--max-turns` flag.
60
+ // tied to this level - there is no `--max-turns` flag.
61
61
  if (opts.effort)
62
62
  args.push("--effort", opts.effort);
63
63
  if (opts.allowedTools?.length)
@@ -69,7 +69,7 @@ export function buildCommand(prompt, opts) {
69
69
  if (opts.systemPrompt)
70
70
  args.push("--system-prompt", opts.systemPrompt);
71
71
  // Beta flags. `context1M: true` is shorthand for adding the
72
- // `context-1m-2025-08-07` beta. API-key-only the CLI warns and
72
+ // `context-1m-2025-08-07` beta. API-key-only - the CLI warns and
73
73
  // falls back to 200k for subscription auth.
74
74
  const betas = [...(opts.betas ?? [])];
75
75
  if (opts.context1M && !betas.includes("context-1m-2025-08-07")) {
@@ -78,7 +78,7 @@ export function buildCommand(prompt, opts) {
78
78
  if (betas.length > 0)
79
79
  args.push("--betas", ...betas);
80
80
  // Per-cycle cost ceiling. Safer than a turn cap because agent
81
- // complexity varies wildly this caps the actual spend, not a
81
+ // complexity varies wildly - this caps the actual spend, not a
82
82
  // proxy for it.
83
83
  if (opts.maxBudgetUsd !== undefined) {
84
84
  args.push("--max-budget-usd", String(opts.maxBudgetUsd));
@@ -128,7 +128,7 @@ export async function runOnce(prompt, opts = {}) {
128
128
  // Explicitly close stdin. Without this, the claude CLI waits 3s
129
129
  // for piped input before proceeding (and treats the wait as a
130
130
  // warning that contaminates stdout). Closing stdin tells it
131
- // "the prompt on -p is complete don't wait for more".
131
+ // "the prompt on -p is complete - don't wait for more".
132
132
  stdin: "ignore",
133
133
  });
134
134
  return parseResult(r.stdout, r.stderr, r.exitCode ?? 0, start, jsonSupported, ["claude", ...cmd]);
@@ -163,12 +163,12 @@ function parseResult(stdout, stderr, exitCode, start, jsonMode, command) {
163
163
  command,
164
164
  };
165
165
  // True when the JSON result block explicitly reported success. When
166
- // it's set, trust the JSON over a non-zero exit code claude can
166
+ // it's set, trust the JSON over a non-zero exit code - claude can
167
167
  // exit non-zero if a child process it spawned (e.g. a long-running
168
168
  // dashboard server) leaves stdout/stderr pipes open past the
169
169
  // parent's timeout, even though the turn itself completed cleanly.
170
170
  let jsonReportedSuccess = false;
171
- // Try JSON parse regardless of exit code claude sometimes emits
171
+ // Try JSON parse regardless of exit code - claude sometimes emits
172
172
  // useful error detail in JSON even when exiting non-zero.
173
173
  if (jsonMode) {
174
174
  try {
@@ -251,7 +251,7 @@ function parseResult(stdout, stderr, exitCode, start, jsonMode, command) {
251
251
  }
252
252
  if (exitCode !== 0 && !base.error && !jsonReportedSuccess) {
253
253
  // Prefer stderr, then stdout first-line fallback. Never echo the
254
- // entire stdout into the error field it may be a multi-KB JSON.
254
+ // entire stdout into the error field - it may be a multi-KB JSON.
255
255
  const trimmedStderr = stderr.trim();
256
256
  if (trimmedStderr)
257
257
  base.error = trimmedStderr.slice(0, 400);
@@ -263,7 +263,7 @@ function parseResult(stdout, stderr, exitCode, start, jsonMode, command) {
263
263
  // If we determined an error from JSON but exit was 0, still mark not-ok.
264
264
  if (base.error && base.ok)
265
265
  base.ok = false;
266
- // Conversely: JSON explicitly said success. Honor that ignore a
266
+ // Conversely: JSON explicitly said success. Honor that - ignore a
267
267
  // non-zero exit caused by lingering child processes.
268
268
  if (jsonReportedSuccess) {
269
269
  base.ok = true;
package/dist/cli.js CHANGED
@@ -35,7 +35,7 @@ function defaultProfile(explicit) {
35
35
  return explicit ?? process.env.BAJACLAW_PROFILE ?? DEFAULT_PROFILE_NAME;
36
36
  }
37
37
  const program = new Command();
38
- program.name(pkg.name).description("BajaClaw autonomous agents on your terms").version(pkg.version);
38
+ program.name(pkg.name).description("BajaClaw - autonomous agents on your terms").version(pkg.version);
39
39
  program
40
40
  .command("init [name]")
41
41
  .description("Scaffold a new agent profile")
@@ -53,7 +53,7 @@ program
53
53
  });
54
54
  program
55
55
  .command("chat [profile]")
56
- .description("Interactive chat REPL converse with the agent turn-by-turn")
56
+ .description("Interactive chat REPL - converse with the agent turn-by-turn")
57
57
  .option("--model <id>", "model or alias (auto|haiku|sonnet|opus|<full-id>)")
58
58
  .action(async (p, opts) => {
59
59
  const target = defaultProfile(p);
@@ -188,7 +188,7 @@ program.command("update").description("Check for and install a newer version")
188
188
  .option("--check", "only check; don't install")
189
189
  .option("--yes", "apply without confirmation")
190
190
  .action(async (opts) => runUpdate({ check: !!opts.check, yes: !!opts.yes }));
191
- // Setup idempotent first-run bootstrap. Safe to rerun. Interactive
191
+ // Setup - idempotent first-run bootstrap. Safe to rerun. Interactive
192
192
  // persona wizard on a TTY the first time; non-interactive otherwise.
193
193
  program.command("setup").description("Idempotent first-run bootstrap (profile, MCP register, persona wizard, health check)")
194
194
  .option("--profile <name>", "profile name (default: 'default')")
@@ -207,7 +207,7 @@ program.command("setup").description("Idempotent first-run bootstrap (profile, M
207
207
  interactive: !!opts.interactive,
208
208
  nonInteractive: !!opts.nonInteractive,
209
209
  }));
210
- // Compact run memory compaction (or show what would run)
210
+ // Compact - run memory compaction (or show what would run)
211
211
  program.command("compact [profile]")
212
212
  .description("Compact memory (summarize old entries, prune stale cycle rows)")
213
213
  .option("--dry-run", "show trigger state and policy without running")
@@ -242,7 +242,7 @@ program.command("compact [profile]")
242
242
  set: Object.keys(set).length > 0 ? set : undefined,
243
243
  });
244
244
  });
245
- // Persona view or re-run the wizard
245
+ // Persona - view or re-run the wizard
246
246
  program.command("persona [profile]")
247
247
  .description("Show or edit the agent's persona (name, tone, user name, focus)")
248
248
  .option("--edit", "re-run the interactive wizard")
@@ -270,30 +270,30 @@ subCmd.command("create <name>")
270
270
  subCmd.command("list [parent]")
271
271
  .description("List sub-agents under a parent (or the whole tree if omitted)")
272
272
  .action(async (p) => subagent.cmdList(p));
273
- // Delegate orchestrators call this via Bash to hand off a task
273
+ // Delegate - orchestrators call this via Bash to hand off a task
274
274
  program.command("delegate <subagent> <task>")
275
275
  .description("Run one cycle on a sub-agent and stream its response text to stdout")
276
276
  .option("--json", "output full CycleOutput JSON instead of just text")
277
277
  .action(async (sub, task, opts) => subagent.cmdDelegate(sub, task, { json: !!opts.json }));
278
- // Uninstall full teardown.
278
+ // Uninstall - full teardown.
279
279
  program.command("uninstall").description("Remove all BajaClaw state (profiles, scheduler, MCP, memory sync)")
280
280
  .option("--yes", "actually perform the teardown")
281
281
  .option("--keep-data", "keep ~/.bajaclaw/ data; only remove integrations")
282
282
  .action(async (opts) => runUninstall({ yes: !!opts.yes, keepData: !!opts.keepData }));
283
- // Model show or set per profile
283
+ // Model - show or set per profile
284
284
  program.command("model [value] [profile]")
285
285
  .description("Show or set the model for a profile (no value: lists known models)")
286
286
  .action(async (value, p) => runModel(value, { profile: p }));
287
- // Effort show or set per profile
287
+ // Effort - show or set per profile
288
288
  program.command("effort [value] [profile]")
289
289
  .description("Show or set the effort level (low/medium/high) for a profile")
290
290
  .action(async (value, p) => runEffort(value, { profile: p }));
291
- // Guide print a self-setup walkthrough
291
+ // Guide - print a self-setup walkthrough
292
292
  program.command("guide [topic]")
293
293
  .description("Print a self-setup walkthrough, or list available guides")
294
294
  .option("--profile <name>", "profile to use for skill lookup")
295
295
  .action(async (topic, opts) => runGuide(topic, { profile: opts.profile }));
296
- // Serve OpenAI-compatible HTTP endpoint
296
+ // Serve - OpenAI-compatible HTTP endpoint
297
297
  program.command("serve")
298
298
  .description("Serve BajaClaw over an OpenAI-compatible HTTP API")
299
299
  .option("--host <host>", "bind host (default 127.0.0.1)")
@@ -312,7 +312,7 @@ program.command("serve")
312
312
  program.command("banner").description("Print the ASCII banner").action(() => {
313
313
  printBanner(pkg.version, { force: true });
314
314
  });
315
- // Welcome first-run greeting; also callable anytime
315
+ // Welcome - first-run greeting; also callable anytime
316
316
  program.command("welcome").description("Print the welcome banner + next steps")
317
317
  .action(async () => {
318
318
  await printWelcome({ force: true });
@@ -341,7 +341,7 @@ async function printWelcome(opts = {}) {
341
341
  }
342
342
  catch { /* health check optional */ }
343
343
  console.log(chalk.bold("Start chatting:"));
344
- console.log(` ${chalk.cyan("bajaclaw chat")} ${chalk.dim("# interactive REPL talk to your agent")}`);
344
+ console.log(` ${chalk.cyan("bajaclaw chat")} ${chalk.dim("# interactive REPL - talk to your agent")}`);
345
345
  console.log("");
346
346
  console.log(chalk.bold("First-time setup:"));
347
347
  console.log(` ${chalk.cyan("bajaclaw setup --interactive")} ${chalk.dim("# name your agent, set tone, topics, don'ts")}`);
@@ -368,7 +368,7 @@ async function maybeShowWelcome() {
368
368
  return;
369
369
  // Only show when stdout is a TTY. npm captures postinstall output,
370
370
  // so firing the welcome during `npm install` prints to the void and
371
- // then marks done defeating the point. Non-TTY: silent no-op, don't
371
+ // then marks done - defeating the point. Non-TTY: silent no-op, don't
372
372
  // even mark done, so the next interactive run still gets the welcome.
373
373
  if (!process.stdout.isTTY)
374
374
  return;
@@ -392,7 +392,7 @@ program.hook("postAction", async () => {
392
392
  return;
393
393
  await maybeNoticeAtExit();
394
394
  });
395
- // Run the first-run welcome before command dispatch. Non-blocking
395
+ // Run the first-run welcome before command dispatch. Non-blocking -
396
396
  // a failure here should never prevent the user's command from running.
397
397
  await maybeShowWelcome().catch(() => { });
398
398
  // Await the parse so long-running interactive commands (like `chat`)
@@ -4,7 +4,7 @@ export async function cmdAdd(profile, kind, token, channelId, userId) {
4
4
  const cfg = loadConfig(profile);
5
5
  // For telegram: `--channel-id` is the user's numeric Telegram id
6
6
  // (the same thing @userinfobot returns). It lives in the allowlist,
7
- // not channelId telegram adapters route replies by chat id from
7
+ // not channelId - telegram adapters route replies by chat id from
8
8
  // the inbound message, not a pre-set channel.
9
9
  // For discord: `--channel-id` is the discord channel id; `--user-id`
10
10
  // is the sender to allow. Without a user id, no allowlist is
@@ -25,7 +25,7 @@ export async function cmdAdd(profile, kind, token, channelId, userId) {
25
25
  saveConfig(cfg);
26
26
  console.log(chalk.green(`✓ added ${kind} channel to ${profile}`));
27
27
  if (kind === "telegram" && entry.allowlist?.length === 0) {
28
- console.log(chalk.yellow(" note: no user id provided allowlist is empty (any user can message)"));
28
+ console.log(chalk.yellow(" note: no user id provided - allowlist is empty (any user can message)"));
29
29
  }
30
30
  }
31
31
  export async function cmdRemove(profile, kind) {