@arthur-ai/buzz 2.1.554-dev.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 +132 -0
- package/dist/chunk-DNHKKPJY.js +118 -0
- package/dist/index.js +2452 -0
- package/dist/prompts-NKUEI6PW.js +34 -0
- package/package.json +54 -0
package/README.md
ADDED
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
# Buzz — Arthur GenAI Engine Onboarding Agent
|
|
2
|
+
|
|
3
|
+
Buzz is an interactive CLI wizard that connects your agentic application to [Arthur GenAI Engine](https://arthur.ai) in minutes. It analyzes your codebase, installs the right instrumentation, and verifies that traces are flowing — all without leaving your terminal.
|
|
4
|
+
|
|
5
|
+
## Requirements
|
|
6
|
+
|
|
7
|
+
| Dependency | Version | Notes |
|
|
8
|
+
|---|---|---|
|
|
9
|
+
| Node.js | ≥ 20 | |
|
|
10
|
+
| Claude Code | latest | `npm install -g @anthropic-ai/claude-code` |
|
|
11
|
+
| Git | any | Your repo must have a clean working tree |
|
|
12
|
+
| macOS | any | Required for local Arthur Engine installation only |
|
|
13
|
+
|
|
14
|
+
You also need an Anthropic API key set in your environment (`ANTHROPIC_API_KEY`), or Claude Code authenticated via `claude auth login`.
|
|
15
|
+
|
|
16
|
+
## Quickstart
|
|
17
|
+
|
|
18
|
+
Run Buzz from the root of your agentic application:
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
npx @arthur-ai/buzz
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Or install globally:
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
npm install -g @arthur-ai/buzz
|
|
28
|
+
buzz
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
> **Your repository must have no uncommitted changes before running Buzz.** Commit or stash your work first.
|
|
32
|
+
|
|
33
|
+
## Local Development
|
|
34
|
+
|
|
35
|
+
After making changes to the Buzz source code, rebuild and reinstall globally to test them:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
npm run build && npm install -g .
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
This compiles the TypeScript source and replaces the globally installed `buzz` binary with your local build.
|
|
42
|
+
|
|
43
|
+
## What Buzz does
|
|
44
|
+
|
|
45
|
+
Buzz walks you through 7 steps automatically:
|
|
46
|
+
|
|
47
|
+
**Step 1 — Pre-flight check**
|
|
48
|
+
Verifies git is clean, Claude Code is installed and authenticated.
|
|
49
|
+
|
|
50
|
+
**Step 2 — Arthur GenAI Engine**
|
|
51
|
+
Connects to Arthur Engine. If you don't have one, Buzz can install it locally on Mac (requires Docker) or connect to an existing remote deployment. Credentials are saved so you don't have to re-enter them on subsequent runs.
|
|
52
|
+
|
|
53
|
+
**Step 3 — Task setup**
|
|
54
|
+
Creates or selects an Arthur Task — the logical grouping for your application's traces and evaluations.
|
|
55
|
+
|
|
56
|
+
**Step 4–6 — Instrumentation**
|
|
57
|
+
Buzz analyzes your codebase and applies the right instrumentation automatically using Claude:
|
|
58
|
+
|
|
59
|
+
| App type | What gets added |
|
|
60
|
+
|---|---|
|
|
61
|
+
| Python (LangChain, OpenAI, CrewAI, etc.) | `arthur-observability-sdk` + framework-specific instrumentation |
|
|
62
|
+
| Mastra (TypeScript) | `@mastra/arthur` package + `ArthurExporter` registered in your Mastra instance |
|
|
63
|
+
| Other (any framework) | OpenInference / OpenTelemetry instrumentation |
|
|
64
|
+
|
|
65
|
+
All API keys stay in environment variables — never hardcoded. A `.env.example` entry is added for `ARTHUR_API_KEY`, `ARTHUR_BASE_URL`, and `ARTHUR_TASK_ID`.
|
|
66
|
+
|
|
67
|
+
**Step 7 — Verification**
|
|
68
|
+
Prompts you to run your application, then polls Arthur Engine for incoming traces. Confirms live data is flowing.
|
|
69
|
+
|
|
70
|
+
## How instrumentation works
|
|
71
|
+
|
|
72
|
+
Buzz uses the [Claude Agent SDK](https://github.com/anthropic-ai/claude-agent-sdk) to drive Claude Code programmatically inside your repository. Claude reads your code, installs dependencies, edits the right files, runs your existing test suite, and fixes any failures it introduces — then reports a structured result back to Buzz.
|
|
73
|
+
|
|
74
|
+
Claude operates with `acceptEdits` permission mode, meaning it can read and write files but will not run arbitrary shell commands without them being explicitly listed (`npm install`, `tsc`, your test runner).
|
|
75
|
+
|
|
76
|
+
## Environment variables set by Buzz
|
|
77
|
+
|
|
78
|
+
After running Buzz your application needs these environment variables to send traces:
|
|
79
|
+
|
|
80
|
+
```
|
|
81
|
+
ARTHUR_API_KEY=<your-arthur-api-key>
|
|
82
|
+
ARTHUR_BASE_URL=<your-engine-url> # e.g. http://localhost:3030
|
|
83
|
+
ARTHUR_TASK_ID=<your-task-id>
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Buzz adds these to `.env.example` in your repo. Set them in your shell or `.env` before running your app.
|
|
87
|
+
|
|
88
|
+
## Re-running Buzz
|
|
89
|
+
|
|
90
|
+
Buzz is idempotent. It detects existing configuration (Arthur Engine URL, API key, task ID) and existing instrumentation, and skips steps that are already complete. Run it again at any time to reconfigure or re-verify.
|
|
91
|
+
|
|
92
|
+
## Local Arthur Engine (Mac)
|
|
93
|
+
|
|
94
|
+
If you choose to install Arthur Engine locally, Buzz runs the official install script:
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
bash <(curl -sSL https://get-genai-engine.arthur.ai/mac)
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
This installs Docker (if needed) and starts Arthur Engine at `http://localhost:3030`. Buzz waits up to 2 minutes for the engine to become ready before proceeding.
|
|
101
|
+
|
|
102
|
+
## Troubleshooting
|
|
103
|
+
|
|
104
|
+
**"Git repository has uncommitted changes"**
|
|
105
|
+
Commit or stash your changes: `git stash` then re-run Buzz.
|
|
106
|
+
|
|
107
|
+
**"Claude Code is not installed"**
|
|
108
|
+
```bash
|
|
109
|
+
npm install -g @anthropic-ai/claude-code
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
**"Claude Code is not authenticated"**
|
|
113
|
+
```bash
|
|
114
|
+
export ANTHROPIC_API_KEY=your-key-here
|
|
115
|
+
# or
|
|
116
|
+
claude auth login
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
**"Engine at … is not reachable"**
|
|
120
|
+
Check that Arthur Engine is running and the URL is correct. For local installs, ensure Docker is running.
|
|
121
|
+
|
|
122
|
+
**No traces detected after instrumentation**
|
|
123
|
+
1. Did your application run and make at least one LLM call?
|
|
124
|
+
2. Is `ARTHUR_API_KEY` set in your shell?
|
|
125
|
+
3. Is `ARTHUR_BASE_URL` pointing to the correct engine URL?
|
|
126
|
+
4. Is `ARTHUR_TASK_ID` set correctly?
|
|
127
|
+
5. Check your application logs for OpenTelemetry export errors.
|
|
128
|
+
|
|
129
|
+
For local installs, find your admin API key with:
|
|
130
|
+
```bash
|
|
131
|
+
grep GENAI_ENGINE_ADMIN_KEY ~/genai-engine/.env
|
|
132
|
+
```
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
// src/ui/prompts.ts
|
|
2
|
+
import * as p from "@clack/prompts";
|
|
3
|
+
import chalk from "chalk";
|
|
4
|
+
import { stripVTControlCharacters } from "util";
|
|
5
|
+
var { isCancel, cancel } = p;
|
|
6
|
+
var PHRASE_MAP = {
|
|
7
|
+
greeting: "10-4, do you copy? Buzz here. Ready for takeoff.",
|
|
8
|
+
checking: "Running diagnostics on {item}...",
|
|
9
|
+
success: "All systems nominal. {item} confirmed.",
|
|
10
|
+
error: "Houston, we have a problem. {detail}",
|
|
11
|
+
install: "Initiating {item} launch sequence...",
|
|
12
|
+
waiting: "Standing by for your input, astronaut.",
|
|
13
|
+
confirm: "Do you copy? {question}",
|
|
14
|
+
complete: "Mission accomplished. We are go for science!",
|
|
15
|
+
notMac: "This mission currently requires Mac OS hardware. Returning to base.",
|
|
16
|
+
dirty: "Cannot proceed \u2014 uncommitted work in progress detected in your repository.",
|
|
17
|
+
claudeInstall: "Claude Code is not installed.",
|
|
18
|
+
claudeAuth: "Claude Code is not authenticated."
|
|
19
|
+
};
|
|
20
|
+
function buzzSay(template, vars) {
|
|
21
|
+
let result = template;
|
|
22
|
+
if (vars) {
|
|
23
|
+
for (const [key, value] of Object.entries(vars)) {
|
|
24
|
+
result = result.replace(`{${key}}`, value);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
return chalk.cyan("[ BUZZ ] ") + result;
|
|
28
|
+
}
|
|
29
|
+
function buzzPhrase(key, vars) {
|
|
30
|
+
return buzzSay(PHRASE_MAP[key] ?? key, vars);
|
|
31
|
+
}
|
|
32
|
+
function handleCancel(value) {
|
|
33
|
+
if (isCancel(value)) {
|
|
34
|
+
cancel(buzzSay("Mission aborted by astronaut. Safe travels."));
|
|
35
|
+
process.exit(0);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
var CI_MODE = process.env.BUZZ_CI === "true";
|
|
39
|
+
async function confirm2(message) {
|
|
40
|
+
if (CI_MODE) {
|
|
41
|
+
p.log.info(buzzSay(`[CI] Auto-confirming: ${message}`));
|
|
42
|
+
return true;
|
|
43
|
+
}
|
|
44
|
+
const result = await p.confirm({ message: buzzSay(message) });
|
|
45
|
+
handleCancel(result);
|
|
46
|
+
return result;
|
|
47
|
+
}
|
|
48
|
+
async function select2(message, options) {
|
|
49
|
+
if (CI_MODE) {
|
|
50
|
+
p.log.info(buzzSay(`[CI] Auto-selecting: ${options[0].label}`));
|
|
51
|
+
return options[0].value;
|
|
52
|
+
}
|
|
53
|
+
const result = await p.select({ message: buzzSay(message), options });
|
|
54
|
+
handleCancel(result);
|
|
55
|
+
return result;
|
|
56
|
+
}
|
|
57
|
+
async function text2(message, placeholder) {
|
|
58
|
+
const result = await p.text({
|
|
59
|
+
message: buzzSay(message),
|
|
60
|
+
placeholder,
|
|
61
|
+
validate: (v) => v.trim() ? void 0 : "This field is required."
|
|
62
|
+
});
|
|
63
|
+
handleCancel(result);
|
|
64
|
+
return result.trim();
|
|
65
|
+
}
|
|
66
|
+
async function password2(message) {
|
|
67
|
+
const result = await p.password({ message: buzzSay(message) });
|
|
68
|
+
handleCancel(result);
|
|
69
|
+
return result.trim();
|
|
70
|
+
}
|
|
71
|
+
function logSuccess(msg) {
|
|
72
|
+
p.log.success(buzzSay(msg));
|
|
73
|
+
}
|
|
74
|
+
function logError(msg) {
|
|
75
|
+
p.log.error(buzzSay(msg));
|
|
76
|
+
}
|
|
77
|
+
function logWarn(msg) {
|
|
78
|
+
p.log.warn(buzzSay(msg));
|
|
79
|
+
}
|
|
80
|
+
function logInfo(msg) {
|
|
81
|
+
p.log.info(buzzSay(msg));
|
|
82
|
+
}
|
|
83
|
+
function note(message, title = "") {
|
|
84
|
+
const lines = message.split("\n");
|
|
85
|
+
const titleLen = stripVTControlCharacters(title).length;
|
|
86
|
+
const r = Math.max(
|
|
87
|
+
lines.reduce((n, l) => Math.max(n, stripVTControlCharacters(l).length), 0),
|
|
88
|
+
titleLen
|
|
89
|
+
) + 2;
|
|
90
|
+
const bar = chalk.gray("\u2502");
|
|
91
|
+
const contentLines = lines.map((l) => `${bar} ${chalk.dim(l)}${" ".repeat(r - stripVTControlCharacters(l).length)}${bar}`).join("\n");
|
|
92
|
+
const topDashes = chalk.gray("\u2500".repeat(Math.max(r - titleLen - 1, 1)) + "\u256E");
|
|
93
|
+
const top = `${chalk.green("\u25C7")} ${chalk.reset(title)} ${topDashes}`;
|
|
94
|
+
const bottom = chalk.gray("\u251C" + "\u2500".repeat(r + 2) + "\u256F");
|
|
95
|
+
process.stdout.write(`${chalk.gray("\u2502")}
|
|
96
|
+
${top}
|
|
97
|
+
${contentLines}
|
|
98
|
+
${bottom}
|
|
99
|
+
`);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export {
|
|
103
|
+
p,
|
|
104
|
+
isCancel,
|
|
105
|
+
cancel,
|
|
106
|
+
buzzSay,
|
|
107
|
+
buzzPhrase,
|
|
108
|
+
handleCancel,
|
|
109
|
+
confirm2 as confirm,
|
|
110
|
+
select2 as select,
|
|
111
|
+
text2 as text,
|
|
112
|
+
password2 as password,
|
|
113
|
+
logSuccess,
|
|
114
|
+
logError,
|
|
115
|
+
logWarn,
|
|
116
|
+
logInfo,
|
|
117
|
+
note
|
|
118
|
+
};
|