beakr-cli 0.2.0__tar.gz → 0.2.1__tar.gz
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.
- {beakr_cli-0.2.0 → beakr_cli-0.2.1}/.claude/skills/beakr/SKILL.md +34 -1
- {beakr_cli-0.2.0 → beakr_cli-0.2.1}/PKG-INFO +6 -4
- {beakr_cli-0.2.0 → beakr_cli-0.2.1}/README.md +5 -3
- {beakr_cli-0.2.0 → beakr_cli-0.2.1}/install.sh +14 -3
- {beakr_cli-0.2.0 → beakr_cli-0.2.1}/pyproject.toml +1 -1
- {beakr_cli-0.2.0 → beakr_cli-0.2.1}/src/beakr_cli/__init__.py +1 -1
- {beakr_cli-0.2.0 → beakr_cli-0.2.1}/src/beakr_cli/commands/install.py +59 -11
- {beakr_cli-0.2.0 → beakr_cli-0.2.1}/src/beakr_cli/mcp_server.py +15 -1
- {beakr_cli-0.2.0 → beakr_cli-0.2.1}/uv.lock +1 -1
- {beakr_cli-0.2.0 → beakr_cli-0.2.1}/.claude/commands/kb-audit.md +0 -0
- {beakr_cli-0.2.0 → beakr_cli-0.2.1}/.claude/commands/kb-research.md +0 -0
- {beakr_cli-0.2.0 → beakr_cli-0.2.1}/.claude/commands/kb-search.md +0 -0
- {beakr_cli-0.2.0 → beakr_cli-0.2.1}/.claude/commands/kb-write.md +0 -0
- {beakr_cli-0.2.0 → beakr_cli-0.2.1}/.claude/skills/beakr/examples/answer-org-question.md +0 -0
- {beakr_cli-0.2.0 → beakr_cli-0.2.1}/.claude/skills/beakr/examples/research-topic.md +0 -0
- {beakr_cli-0.2.0 → beakr_cli-0.2.1}/.claude/skills/beakr/examples/write-decision-page.md +0 -0
- {beakr_cli-0.2.0 → beakr_cli-0.2.1}/.claude/skills/beakr/reference/auditing.md +0 -0
- {beakr_cli-0.2.0 → beakr_cli-0.2.1}/.claude/skills/beakr/reference/provenance.md +0 -0
- {beakr_cli-0.2.0 → beakr_cli-0.2.1}/.claude/skills/beakr/reference/research-workflow.md +0 -0
- {beakr_cli-0.2.0 → beakr_cli-0.2.1}/.claude/skills/beakr/reference/writing-pages.md +0 -0
- {beakr_cli-0.2.0 → beakr_cli-0.2.1}/.github/workflows/publish.yml +0 -0
- {beakr_cli-0.2.0 → beakr_cli-0.2.1}/.gitignore +0 -0
- {beakr_cli-0.2.0 → beakr_cli-0.2.1}/LICENSE +0 -0
- {beakr_cli-0.2.0 → beakr_cli-0.2.1}/src/beakr_cli/citations.py +0 -0
- {beakr_cli-0.2.0 → beakr_cli-0.2.1}/src/beakr_cli/client.py +0 -0
- {beakr_cli-0.2.0 → beakr_cli-0.2.1}/src/beakr_cli/commands/__init__.py +0 -0
- {beakr_cli-0.2.0 → beakr_cli-0.2.1}/src/beakr_cli/commands/auth.py +0 -0
- {beakr_cli-0.2.0 → beakr_cli-0.2.1}/src/beakr_cli/commands/kb.py +0 -0
- {beakr_cli-0.2.0 → beakr_cli-0.2.1}/src/beakr_cli/commands/workspace.py +0 -0
- {beakr_cli-0.2.0 → beakr_cli-0.2.1}/src/beakr_cli/config.py +0 -0
- {beakr_cli-0.2.0 → beakr_cli-0.2.1}/src/beakr_cli/main.py +0 -0
- {beakr_cli-0.2.0 → beakr_cli-0.2.1}/src/beakr_cli/output.py +0 -0
- {beakr_cli-0.2.0 → beakr_cli-0.2.1}/tests/__init__.py +0 -0
- {beakr_cli-0.2.0 → beakr_cli-0.2.1}/tests/test_citations.py +0 -0
- {beakr_cli-0.2.0 → beakr_cli-0.2.1}/tests/test_mcp_resolver.py +0 -0
|
@@ -5,7 +5,9 @@ description: "Access your organization's knowledge base, research questions with
|
|
|
5
5
|
|
|
6
6
|
# Beakr Knowledge Base
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
Beakr is the team's organizational memory. Teams write decisions, processes, ownership, and dated events here so that 6 months later the answer to "why did we do X" is one search away instead of lost in Slack archives or tribal knowledge.
|
|
9
|
+
|
|
10
|
+
Use the Beakr MCP tools to search and read existing knowledge — and to add to it when the conversation produces something durable.
|
|
9
11
|
|
|
10
12
|
## When to use
|
|
11
13
|
|
|
@@ -13,6 +15,37 @@ Use the Beakr MCP tools to search, read, research, and write to the organization
|
|
|
13
15
|
- User wants to look something up ("What do we know about X?", "Who owns Y?")
|
|
14
16
|
- User wants to research a topic across documents and connected services
|
|
15
17
|
- User wants to create, update, or audit knowledge base pages
|
|
18
|
+
- **The conversation itself surfaces durable information worth capturing** (see "Proactive capture" below)
|
|
19
|
+
|
|
20
|
+
## Proactive capture
|
|
21
|
+
|
|
22
|
+
You are not just a read interface. When the conversation produces something durable, **propose adding it — don't wait to be asked**.
|
|
23
|
+
|
|
24
|
+
**Capture when all of:**
|
|
25
|
+
- **Durable**: would still matter in 6 months
|
|
26
|
+
- **Shareable**: others would benefit, not just this user right now
|
|
27
|
+
- **Not already in Beakr**: check with `kb_search` first
|
|
28
|
+
- **In scope**: the user can write to it (their personal project, or a team project they belong to — confirm with `list_projects`)
|
|
29
|
+
|
|
30
|
+
**Good candidates:**
|
|
31
|
+
- Decisions with rationale ("we chose X over Y because…")
|
|
32
|
+
- Named processes ("here's how we onboard a customer")
|
|
33
|
+
- Role / ownership assignments ("Alex owns billing")
|
|
34
|
+
- Dated events: launches, hires, fundraising rounds, incidents
|
|
35
|
+
- External relationships: investors, partners, key vendors
|
|
36
|
+
- Recurring questions you just answered
|
|
37
|
+
|
|
38
|
+
**Skip:**
|
|
39
|
+
- Debugging traces, transient state
|
|
40
|
+
- Information already in source code, git history, Linear/Jira tickets
|
|
41
|
+
- Hot takes, speculation, "thinking out loud"
|
|
42
|
+
- Anything the user clearly considers ephemeral
|
|
43
|
+
|
|
44
|
+
**Etiquette:**
|
|
45
|
+
- **Surface the suggestion before writing**: "This decision about X seems worth capturing — want me to propose it for your wiki?"
|
|
46
|
+
- Never auto-write. Always propose, always wait for explicit OK.
|
|
47
|
+
- One capture offer per significant thread — don't pepper the user.
|
|
48
|
+
- Cite the current session as `conversation:<short-id>` with `meta.excerpt` so the source is traceable.
|
|
16
49
|
|
|
17
50
|
## Core tools
|
|
18
51
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: beakr-cli
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.1
|
|
4
4
|
Summary: CLI and MCP server for Beakr's knowledge base
|
|
5
5
|
Project-URL: Homepage, https://thebeakr.com
|
|
6
6
|
Project-URL: Repository, https://github.com/BeakrHub/beakr-cli
|
|
@@ -45,9 +45,11 @@ If you only want one, install both anyway — they don't conflict and the MCP se
|
|
|
45
45
|
## One-line install
|
|
46
46
|
|
|
47
47
|
```bash
|
|
48
|
-
curl -fsSL https://
|
|
48
|
+
curl -fsSL https://raw.githubusercontent.com/BeakrHub/beakr-cli/main/install.sh | sh
|
|
49
49
|
```
|
|
50
50
|
|
|
51
|
+
(Once `install.thebeakr.com` is wired up, `curl -fsSL https://install.thebeakr.com | sh` will work too — same script, prettier URL.)
|
|
52
|
+
|
|
51
53
|
That's it. The script:
|
|
52
54
|
|
|
53
55
|
1. Installs [`uv`](https://github.com/astral-sh/uv) if missing (no system Python required — `uv` ships its own).
|
|
@@ -62,10 +64,10 @@ Pass flags through the pipe if you want non-interactive behavior:
|
|
|
62
64
|
|
|
63
65
|
```bash
|
|
64
66
|
# Skip the API key prompt (auth later with `beakr auth login`)
|
|
65
|
-
curl -fsSL https://
|
|
67
|
+
curl -fsSL https://raw.githubusercontent.com/BeakrHub/beakr-cli/main/install.sh | sh -s -- --no-auth
|
|
66
68
|
|
|
67
69
|
# Only wire Claude Code, force-overwrite anything that exists
|
|
68
|
-
curl -fsSL https://
|
|
70
|
+
curl -fsSL https://raw.githubusercontent.com/BeakrHub/beakr-cli/main/install.sh | sh -s -- --client claude --force
|
|
69
71
|
```
|
|
70
72
|
|
|
71
73
|
## Manual install
|
|
@@ -14,9 +14,11 @@ If you only want one, install both anyway — they don't conflict and the MCP se
|
|
|
14
14
|
## One-line install
|
|
15
15
|
|
|
16
16
|
```bash
|
|
17
|
-
curl -fsSL https://
|
|
17
|
+
curl -fsSL https://raw.githubusercontent.com/BeakrHub/beakr-cli/main/install.sh | sh
|
|
18
18
|
```
|
|
19
19
|
|
|
20
|
+
(Once `install.thebeakr.com` is wired up, `curl -fsSL https://install.thebeakr.com | sh` will work too — same script, prettier URL.)
|
|
21
|
+
|
|
20
22
|
That's it. The script:
|
|
21
23
|
|
|
22
24
|
1. Installs [`uv`](https://github.com/astral-sh/uv) if missing (no system Python required — `uv` ships its own).
|
|
@@ -31,10 +33,10 @@ Pass flags through the pipe if you want non-interactive behavior:
|
|
|
31
33
|
|
|
32
34
|
```bash
|
|
33
35
|
# Skip the API key prompt (auth later with `beakr auth login`)
|
|
34
|
-
curl -fsSL https://
|
|
36
|
+
curl -fsSL https://raw.githubusercontent.com/BeakrHub/beakr-cli/main/install.sh | sh -s -- --no-auth
|
|
35
37
|
|
|
36
38
|
# Only wire Claude Code, force-overwrite anything that exists
|
|
37
|
-
curl -fsSL https://
|
|
39
|
+
curl -fsSL https://raw.githubusercontent.com/BeakrHub/beakr-cli/main/install.sh | sh -s -- --client claude --force
|
|
38
40
|
```
|
|
39
41
|
|
|
40
42
|
## Manual install
|
|
@@ -2,11 +2,13 @@
|
|
|
2
2
|
# install.sh - Bootstrap the Beakr CLI and wire it into Claude Code / Codex.
|
|
3
3
|
#
|
|
4
4
|
# Usage:
|
|
5
|
-
# curl -fsSL https://
|
|
5
|
+
# curl -fsSL https://raw.githubusercontent.com/BeakrHub/beakr-cli/main/install.sh | sh
|
|
6
|
+
#
|
|
7
|
+
# (Future: curl -fsSL https://install.thebeakr.com | sh — same script, prettier URL.)
|
|
6
8
|
#
|
|
7
9
|
# Pass flags through to `beakr setup`:
|
|
8
|
-
# curl -fsSL https://
|
|
9
|
-
# curl -fsSL https://
|
|
10
|
+
# curl -fsSL https://raw.githubusercontent.com/BeakrHub/beakr-cli/main/install.sh | sh -s -- --no-auth
|
|
11
|
+
# curl -fsSL https://raw.githubusercontent.com/BeakrHub/beakr-cli/main/install.sh | sh -s -- --client claude --force
|
|
10
12
|
|
|
11
13
|
set -eu
|
|
12
14
|
|
|
@@ -29,9 +31,18 @@ fi
|
|
|
29
31
|
|
|
30
32
|
# 2. Install (or upgrade) the beakr CLI as a uv tool. This puts a real `beakr`
|
|
31
33
|
# binary on PATH at ~/.local/bin/beakr — no `uvx` indirection at runtime.
|
|
34
|
+
#
|
|
35
|
+
# Three cases:
|
|
36
|
+
# a) uv-managed beakr-cli already installed -> upgrade
|
|
37
|
+
# b) a `beakr` binary exists from another install method (pipx, pip)
|
|
38
|
+
# -> install with --force so uv replaces it
|
|
39
|
+
# c) nothing installed yet -> plain install
|
|
32
40
|
if uv tool list 2>/dev/null | grep -q '^beakr-cli '; then
|
|
33
41
|
log "Upgrading beakr-cli ..."
|
|
34
42
|
uv tool upgrade beakr-cli
|
|
43
|
+
elif command -v beakr >/dev/null 2>&1; then
|
|
44
|
+
log "Existing 'beakr' binary detected from another install method; reinstalling via uv (--force) ..."
|
|
45
|
+
uv tool install --force beakr-cli
|
|
35
46
|
else
|
|
36
47
|
log "Installing beakr-cli ..."
|
|
37
48
|
uv tool install beakr-cli
|
|
@@ -7,6 +7,7 @@ import json
|
|
|
7
7
|
import os
|
|
8
8
|
import shutil
|
|
9
9
|
import subprocess
|
|
10
|
+
import sys
|
|
10
11
|
from enum import Enum
|
|
11
12
|
from pathlib import Path
|
|
12
13
|
|
|
@@ -404,14 +405,18 @@ def _unregister_codex_mcp() -> None:
|
|
|
404
405
|
# ---------------------------------------------------------------------------
|
|
405
406
|
|
|
406
407
|
|
|
407
|
-
def
|
|
408
|
-
|
|
408
|
+
def _identity_summary(data: dict) -> str:
|
|
409
|
+
user = data.get("user", data)
|
|
410
|
+
org = data.get("personal_org", data)
|
|
411
|
+
name = user.get("display_name") or user.get("primary_email") or "unknown"
|
|
412
|
+
org_name = org.get("name") or org.get("slug") or "unknown"
|
|
413
|
+
return f"{name} in {org_name}"
|
|
414
|
+
|
|
415
|
+
|
|
416
|
+
def _prompt_and_save_new_key() -> None:
|
|
409
417
|
from beakr_cli import config as beakr_config
|
|
410
418
|
from beakr_cli.client import api_get
|
|
411
419
|
|
|
412
|
-
if os.environ.get("BEAKR_API_KEY") or beakr_config.get("api_key"):
|
|
413
|
-
return
|
|
414
|
-
|
|
415
420
|
console.print("\n[bold]Beakr authentication[/bold]")
|
|
416
421
|
console.print("Get an API key at [cyan]https://thebeakr.com/settings/api-keys[/cyan]")
|
|
417
422
|
api_key = typer.prompt("API key", hide_input=True)
|
|
@@ -425,13 +430,56 @@ def _maybe_auth() -> None:
|
|
|
425
430
|
beakr_config.delete_key("api_key")
|
|
426
431
|
err_console.print(f"[red]Auth failed:[/red] {exc}")
|
|
427
432
|
raise typer.Exit(1) from exc
|
|
433
|
+
console.print(f"Authenticated as [bold]{_identity_summary(data)}[/bold]")
|
|
428
434
|
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
+
|
|
436
|
+
def _maybe_auth() -> None:
|
|
437
|
+
"""Confirm or replace an existing API key, or prompt for a new one."""
|
|
438
|
+
from beakr_cli import config as beakr_config
|
|
439
|
+
from beakr_cli.client import api_get
|
|
440
|
+
|
|
441
|
+
env_key = os.environ.get("BEAKR_API_KEY")
|
|
442
|
+
config_key = beakr_config.get("api_key")
|
|
443
|
+
|
|
444
|
+
# 1. Env var wins — verify and announce, don't prompt.
|
|
445
|
+
if env_key:
|
|
446
|
+
try:
|
|
447
|
+
data = api_get("/v1/me")
|
|
448
|
+
console.print(
|
|
449
|
+
f"Using [bold]$BEAKR_API_KEY[/bold] ([dim]{_identity_summary(data)}[/dim])"
|
|
450
|
+
)
|
|
451
|
+
except Exception as exc:
|
|
452
|
+
err_console.print(f"[red]$BEAKR_API_KEY didn't verify:[/red] {exc}")
|
|
453
|
+
raise typer.Exit(1) from exc
|
|
454
|
+
return
|
|
455
|
+
|
|
456
|
+
# 2. Stored key — verify, then ask whether to keep using it.
|
|
457
|
+
if config_key:
|
|
458
|
+
try:
|
|
459
|
+
data = api_get("/v1/me")
|
|
460
|
+
identity = _identity_summary(data)
|
|
461
|
+
except Exception:
|
|
462
|
+
err_console.print(
|
|
463
|
+
"[yellow]Existing API key didn't verify; let's get a new one.[/yellow]"
|
|
464
|
+
)
|
|
465
|
+
beakr_config.delete_key("api_key")
|
|
466
|
+
_prompt_and_save_new_key()
|
|
467
|
+
return
|
|
468
|
+
|
|
469
|
+
# Non-interactive (piped/CI): keep the existing verified key silently.
|
|
470
|
+
if not sys.stdin.isatty():
|
|
471
|
+
console.print(f"Using existing API key ([dim]{identity}[/dim])")
|
|
472
|
+
return
|
|
473
|
+
|
|
474
|
+
console.print(f"\nExisting API key found for [bold]{identity}[/bold].")
|
|
475
|
+
if typer.confirm("Use this key?", default=True):
|
|
476
|
+
return
|
|
477
|
+
beakr_config.delete_key("api_key")
|
|
478
|
+
_prompt_and_save_new_key()
|
|
479
|
+
return
|
|
480
|
+
|
|
481
|
+
# 3. Nothing configured — full prompt path.
|
|
482
|
+
_prompt_and_save_new_key()
|
|
435
483
|
|
|
436
484
|
|
|
437
485
|
# ---------------------------------------------------------------------------
|
|
@@ -12,7 +12,21 @@ from beakr_cli.client import get_async_client, scope_params
|
|
|
12
12
|
mcp = FastMCP(
|
|
13
13
|
"beakr",
|
|
14
14
|
instructions=(
|
|
15
|
-
"Beakr
|
|
15
|
+
"Beakr is the team's organizational memory and connected services. "
|
|
16
|
+
"Teams write decisions, processes, ownership, and dated events here so "
|
|
17
|
+
"that 6 months later the answer to 'why did we do X' is one search "
|
|
18
|
+
"away instead of lost in Slack archives or tribal knowledge.\n\n"
|
|
19
|
+
"RESPONSIBILITIES:\n"
|
|
20
|
+
"Use Beakr to answer questions about the user's org with citations. "
|
|
21
|
+
"When the conversation produces something durable (a decision with "
|
|
22
|
+
"rationale, a named process, an ownership assignment, a dated event, "
|
|
23
|
+
"a key relationship), propose adding it -- don't wait to be asked. "
|
|
24
|
+
"First check with kb_search that it isn't already captured, then "
|
|
25
|
+
"surface a brief suggestion before writing ('this seems worth "
|
|
26
|
+
"capturing -- want me to propose it?'). Never auto-write; always go "
|
|
27
|
+
"through proposals and wait for explicit acceptance. Cite the current "
|
|
28
|
+
"session as a 'conversation' inline source with meta.excerpt when the "
|
|
29
|
+
"information originates from this chat.\n\n"
|
|
16
30
|
"TOOLS:\n"
|
|
17
31
|
"- 'research': Primary tool. Ask any question and get a cited answer from the "
|
|
18
32
|
"wiki, documents, and connected services (Slack, Gmail, Calendar, Jira, etc.). "
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|