atune 0.1.0 → 0.1.1

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 (2) hide show
  1. package/README.md +114 -0
  2. package/package.json +1 -1
package/README.md ADDED
@@ -0,0 +1,114 @@
1
+ # atune
2
+
3
+ Customer-understanding infrastructure for B2B SaaS. Install it like any dependency; understanding comes back through a queryable API — no dashboard to babysit.
4
+
5
+ `atune` auto-captures how your customers use your product, takes the identity you choose to send, and lets you ask grounded, cited questions about any account, user, or feature.
6
+
7
+ ```ts
8
+ const answer = await understand("account:acme", "why did they go quiet?");
9
+ // { knows: true, answer: "Acme's weekly active seats fell from 8 to 2…",
10
+ // confidence: 0.72, citations: [...], recommendedNext: "…", signals: {…} }
11
+ ```
12
+
13
+ ## Install
14
+
15
+ One command wires a live app — detects your framework and auth, installs the package, patches your middleware, and writes your env keys:
16
+
17
+ ```bash
18
+ npx atune init
19
+ ```
20
+
21
+ You paste your workspace API key (from your Atune onboarding) when prompted. That's it — behavior capture starts immediately.
22
+
23
+ ## Requirements
24
+
25
+ - Node 18+
26
+ - Next.js 14+ for the zero-config `init` (optional peer dependency). Other frameworks: use the manual setup below.
27
+
28
+ ## Environment
29
+
30
+ `init` writes these to `.env.local`:
31
+
32
+ | Variable | What |
33
+ |----------|------|
34
+ | `ATUNE_API_KEY` | Your workspace key. The only secret. Server-side only — never ship it to the browser. |
35
+ | `ATUNE_URL` | Your Atune host. Defaults to `https://useatune.com`. |
36
+
37
+ ## What gets captured
38
+
39
+ - **Behavior** is captured automatically: the middleware records every server request as `http.<method>.<normalized-route>` with the resolved account/user. Fire-and-forget — it can never block or break a request. Request bodies are **never** read (no passwords, tokens, or card numbers).
40
+ - **Identity** is only what you send explicitly, via `identify()` / `group()`. Personal data (name, email, company) requires an accepted data-processing agreement.
41
+
42
+ ## Manual setup
43
+
44
+ If you don't want auto-wiring (or aren't on Next.js), add the middleware yourself:
45
+
46
+ ```ts
47
+ // middleware.ts
48
+ import { createAtuneMiddleware } from "atune";
49
+
50
+ const atune = createAtuneMiddleware();
51
+
52
+ export function middleware(request: Request) {
53
+ return atune(request);
54
+ }
55
+ ```
56
+
57
+ Chain it with an existing middleware (e.g. Clerk) by calling `atune(request)` inside your handler — `init` does this for you automatically.
58
+
59
+ ## Identify who is who
60
+
61
+ ```ts
62
+ import { identify, group } from "atune";
63
+
64
+ await identify(userId, { name: "Kari Nordmann", email: "kari@acme.no" });
65
+ await group(accountId, { company: "Acme AS" });
66
+ ```
67
+
68
+ So answers read "Kari at Acme", not "user u_123". Gated behind your accepted DPA.
69
+
70
+ ## Ask: `understand()`
71
+
72
+ ```ts
73
+ import { understand } from "atune";
74
+
75
+ const result = await understand(entity, question);
76
+ ```
77
+
78
+ `entity` is one of:
79
+
80
+ | Entity | Example |
81
+ |--------|---------|
82
+ | `account:<externalId>` | `account:acme` |
83
+ | `user:<accountExternalId>/<userExternalId>` | `user:acme/u_123` |
84
+ | `feature:<key>` | `feature:feature.report` |
85
+ | `portfolio` | your whole book of business |
86
+
87
+ Every answer is grounded in that workspace's real signals and **cited** — and says `knows: false` when there isn't enough understanding yet, instead of guessing.
88
+
89
+ ```ts
90
+ type UnderstandResult = {
91
+ knows: boolean; // false ⇒ "not enough understanding yet"
92
+ answer: string; // plain-language, grounded in your signals
93
+ confidence: number; // 0..1
94
+ citations: { signal: string; value: string; when: string }[];
95
+ recommendedNext: string | null; // one action, only when confident
96
+ signals: Record<string, unknown>; // the structured grounding bundle (LLM-free)
97
+ };
98
+ ```
99
+
100
+ Options: `understand(entity, question, { apiKey, url, fetch })` — all optional; `apiKey`/`url` fall back to the env vars.
101
+
102
+ ## Ask from an AI agent (MCP)
103
+
104
+ Expose `understand()` to an AI coding agent or assistant over the Model Context Protocol:
105
+
106
+ ```bash
107
+ npx atune mcp
108
+ ```
109
+
110
+ A stdio MCP server with a single `understand` tool. Point your agent at it and it can ask about any account, user, feature, or your portfolio on your behalf.
111
+
112
+ ## Privacy
113
+
114
+ Atune is a data processor; you are the controller. Behavior is captured broadly; personal data flows only through `identify()`/`group()` under an accepted DPA. Data stays in the EU.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "atune",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Atune server-side SDK and installer — capture, identify, and understand() your customers.",
5
5
  "license": "UNLICENSED",
6
6
  "repository": {