@basestream/cli 0.2.11 → 0.3.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 -349
- package/dist/cli.mjs +49 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,380 +1,80 @@
|
|
|
1
|
-
# Basestream
|
|
1
|
+
# Basestream
|
|
2
2
|
|
|
3
3
|
**Your team uses AI every day. Now you can see what it's building.**
|
|
4
4
|
|
|
5
|
-
Basestream
|
|
5
|
+
Basestream automatically tracks what your developers build with AI tools and gives engineering leaders visibility into AI-powered output — no manual logging, no workflow changes.
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
[basestream.ai](https://basestream.ai) | [Documentation](https://docs.basestream.ai)
|
|
8
8
|
|
|
9
9
|
---
|
|
10
10
|
|
|
11
|
-
##
|
|
11
|
+
## Install
|
|
12
12
|
|
|
13
13
|
```bash
|
|
14
|
-
|
|
15
|
-
cd packages/api && docker compose up -d && cd ../basestream
|
|
16
|
-
|
|
17
|
-
# 2. Install dependencies
|
|
18
|
-
npm install --legacy-peer-deps
|
|
19
|
-
|
|
20
|
-
# 3. Set up environment
|
|
21
|
-
cp .env.example .env
|
|
22
|
-
# .env is pre-configured for local dev with SKIP_PAYMENT=true
|
|
23
|
-
|
|
24
|
-
# 4. Push schema to database
|
|
25
|
-
npx drizzle-kit generate
|
|
26
|
-
# Then apply the migration:
|
|
27
|
-
cat src/db/migrations/0000_*.sql | docker exec -i basement-pg psql -U postgres -d basement_starter
|
|
28
|
-
|
|
29
|
-
# 5. Seed demo data (3 users, 44 entries, 1 org)
|
|
30
|
-
npx tsx src/db/seed.ts
|
|
31
|
-
|
|
32
|
-
# 6. Run dev server
|
|
33
|
-
npm run dev
|
|
14
|
+
npx @basestream/cli init
|
|
34
15
|
```
|
|
35
16
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
### End-to-End Local Testing
|
|
39
|
-
|
|
40
|
-
With `SKIP_PAYMENT=true` in `.env`, you can:
|
|
41
|
-
|
|
42
|
-
- Sign up via email magic link (check console for the link)
|
|
43
|
-
- Skip Stripe checkout — clicking "Get early access" instantly upgrades to Team
|
|
44
|
-
- Create orgs, invite members, manage integrations
|
|
45
|
-
- Ingest work entries via API key (`POST /api/entries`)
|
|
46
|
-
- Bulk sync entries (`POST /api/sync` — idempotent via sessionId)
|
|
47
|
-
|
|
48
|
-
---
|
|
49
|
-
|
|
50
|
-
## Architecture
|
|
51
|
-
|
|
52
|
-
```
|
|
53
|
-
packages/basestream/
|
|
54
|
-
├── src/
|
|
55
|
-
│ ├── db/
|
|
56
|
-
│ │ ├── schema.ts # Drizzle schema: 10 tables, 7 enums (bs_ prefixed)
|
|
57
|
-
│ │ ├── index.ts # Drizzle client (pg Pool → port 5434)
|
|
58
|
-
│ │ ├── seed.ts # Demo: 3 users, 44 entries, 1 org
|
|
59
|
-
│ │ └── migrations/ # Generated SQL migrations
|
|
60
|
-
│ ├── app/
|
|
61
|
-
│ │ ├── page.tsx # Landing page (marketing)
|
|
62
|
-
│ │ ├── layout.tsx # Root layout (fonts, metadata)
|
|
63
|
-
│ │ ├── login/page.tsx # Auth: email + GitHub + Google
|
|
64
|
-
│ │ ├── signup/page.tsx # Auth + Stripe checkout flow
|
|
65
|
-
│ │ ├── api/ # 16 API routes
|
|
66
|
-
│ │ │ ├── auth/ # NextAuth handler
|
|
67
|
-
│ │ │ ├── stripe/ # Checkout + webhook
|
|
68
|
-
│ │ │ ├── entries/ # CRUD + pagination + filters
|
|
69
|
-
│ │ │ ├── sync/ # Bulk upsert (CLI sync)
|
|
70
|
-
│ │ │ ├── summary/ # Aggregated stats + ROI
|
|
71
|
-
│ │ │ ├── search/ # Full-text search
|
|
72
|
-
│ │ │ ├── orgs/ # Org + members + invites
|
|
73
|
-
│ │ │ └── integrations/ # 5 integration stubs
|
|
74
|
-
│ │ └── dashboard/ # 9 authenticated pages
|
|
75
|
-
│ │ ├── page.tsx # Overview (feed + heatmap)
|
|
76
|
-
│ │ ├── team/ # Manager view (charts)
|
|
77
|
-
│ │ ├── projects/ # Project grid
|
|
78
|
-
│ │ ├── roi/ # ROI metrics + Recharts
|
|
79
|
-
│ │ ├── integrations/ # Connect/disconnect tools
|
|
80
|
-
│ │ └── settings/ # Profile, billing, team mgmt
|
|
81
|
-
│ ├── components/
|
|
82
|
-
│ │ ├── landing/ # 12 marketing components
|
|
83
|
-
│ │ ├── dashboard/ # 8 dashboard components
|
|
84
|
-
│ │ └── ui/ # 5 shared UI primitives
|
|
85
|
-
│ ├── lib/ # Core libraries
|
|
86
|
-
│ │ ├── auth.ts # NextAuth config (DrizzleAdapter)
|
|
87
|
-
│ │ ├── stripe.ts # Stripe helpers
|
|
88
|
-
│ │ ├── api-auth.ts # API key + session auth
|
|
89
|
-
│ │ ├── utils.ts # Utility functions
|
|
90
|
-
│ │ └── integrations/ # 6 integration modules
|
|
91
|
-
│ ├── hooks/ # 3 data hooks
|
|
92
|
-
│ ├── types/ # TypeScript types
|
|
93
|
-
│ └── middleware.ts # Route protection
|
|
94
|
-
├── drizzle.config.ts # Drizzle Kit config
|
|
95
|
-
├── tailwind.config.ts # Design system
|
|
96
|
-
└── package.json
|
|
97
|
-
```
|
|
98
|
-
|
|
99
|
-
**86 files total.** TypeScript strict mode, zero type errors.
|
|
100
|
-
|
|
101
|
-
---
|
|
102
|
-
|
|
103
|
-
## Tech Stack
|
|
104
|
-
|
|
105
|
-
| Layer | Technology |
|
|
106
|
-
| --------- | ----------------------------------------------------------------------------------- |
|
|
107
|
-
| Framework | Next.js 14 (App Router) |
|
|
108
|
-
| Language | TypeScript (strict) |
|
|
109
|
-
| Styling | Tailwind CSS + CSS variables |
|
|
110
|
-
| Database | PostgreSQL 16 via Drizzle ORM (shared `basement_starter` DB, `bs_` prefixed tables) |
|
|
111
|
-
| Auth | NextAuth.js (GitHub, Google, email magic link) |
|
|
112
|
-
| Payments | Stripe (Checkout, Webhooks, Customer Portal) |
|
|
113
|
-
| Charts | Recharts |
|
|
114
|
-
| Local dev | Docker Compose |
|
|
115
|
-
|
|
116
|
-
---
|
|
117
|
-
|
|
118
|
-
## Design System
|
|
119
|
-
|
|
120
|
-
The visual identity is **warm, editorial, premium** -- not the typical dark dev-tool aesthetic.
|
|
121
|
-
|
|
122
|
-
### Colors
|
|
17
|
+
This will:
|
|
123
18
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
| `warm-white` | `#FFFDF9` | Card backgrounds |
|
|
128
|
-
| `ink` | `#1A1714` | Primary text |
|
|
129
|
-
| `ink-soft` | `#4A453D` | Secondary text |
|
|
130
|
-
| `ink-muted` | `#8A8379` | Tertiary text, labels |
|
|
131
|
-
| `accent` | `#C4653A` | Terracotta orange, CTAs |
|
|
132
|
-
| `accent-soft` | `#E8956A` | Hover states |
|
|
133
|
-
| `accent-bg` | `#FFF3ED` | Accent backgrounds |
|
|
134
|
-
| `border` | `#E8E4DE` | Card borders |
|
|
135
|
-
| `sage` | `#6B7E6B` | Success, dev indicators |
|
|
136
|
-
| `blue` | `#4A6FA5` | Info, links |
|
|
19
|
+
1. Authenticate with your Basestream account
|
|
20
|
+
2. Configure automatic session tracking
|
|
21
|
+
3. Start capturing work in the background
|
|
137
22
|
|
|
138
|
-
|
|
23
|
+
## How it works
|
|
139
24
|
|
|
140
|
-
|
|
141
|
-
- **Body:** DM Sans (sans-serif), weight 300 body / 500 labels
|
|
142
|
-
- **Code:** SF Mono / Fira Code (monospace)
|
|
25
|
+
Basestream runs silently alongside your AI tools. At the end of each session, it captures what was built — files changed, commits made, tools used, token usage — and syncs it to your dashboard.
|
|
143
26
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
- Word-by-word blur reveal (hero headline)
|
|
147
|
-
- Terminal typing sequence with cursor blink
|
|
148
|
-
- Scroll-triggered reveal (opacity + translateY)
|
|
149
|
-
- Animated counters (eased count-up)
|
|
150
|
-
- Tool chip stagger reveal
|
|
151
|
-
- Divider accent wipe
|
|
152
|
-
- Ambient glow orb drift
|
|
153
|
-
- Card hover transitions
|
|
154
|
-
- Nav scroll blur transition
|
|
155
|
-
|
|
156
|
-
---
|
|
157
|
-
|
|
158
|
-
## Landing Page
|
|
159
|
-
|
|
160
|
-
The landing page at `/` is a single-page marketing site with 12 sections:
|
|
161
|
-
|
|
162
|
-
1. **Navbar** -- Fixed, blur-on-scroll, logo + links + CTA
|
|
163
|
-
2. **Hero** -- Glow orbs, word-by-word blur reveal headline, badge, dual CTAs
|
|
164
|
-
3. **Terminal Demo** -- Typing animation showing `npx basestream init` flow
|
|
165
|
-
4. **Problem Section** -- "Sessions vanish", "Tokens != outcomes", "Status is manual"
|
|
166
|
-
5. **Divider** -- Accent wipe on scroll
|
|
167
|
-
6. **How It Works** -- 3 numbered steps with hover accent lines
|
|
168
|
-
7. **Divider**
|
|
169
|
-
8. **Two Views** -- Developer journal + Manager dashboard mockups with animated counters
|
|
170
|
-
9. **Integrations** -- Tool chips with stagger animation (6 active, 3 coming soon)
|
|
171
|
-
10. **Pricing** -- 3-tier (Free / $12 Team / Custom Enterprise)
|
|
172
|
-
11. **CTA** -- Final conversion with accent glow
|
|
173
|
-
12. **Footer** -- Copyright + links
|
|
174
|
-
|
|
175
|
-
---
|
|
27
|
+
**No prompts. No interruptions. No behavior changes required.**
|
|
176
28
|
|
|
177
|
-
|
|
29
|
+
### Supported tools
|
|
178
30
|
|
|
179
|
-
|
|
31
|
+
- Claude Code
|
|
32
|
+
- Cursor
|
|
33
|
+
- GitHub Copilot
|
|
34
|
+
- More coming soon
|
|
180
35
|
|
|
181
|
-
|
|
182
|
-
- **Google OAuth** -- `GOOGLE_CLIENT_ID` + `GOOGLE_CLIENT_SECRET`
|
|
183
|
-
- **Email magic link** -- Sends sign-in link to email
|
|
184
|
-
|
|
185
|
-
Session includes `user.id` and `user.plan` via callback augmentation.
|
|
186
|
-
|
|
187
|
-
Middleware at `src/middleware.ts` protects all `/dashboard/*` routes.
|
|
188
|
-
|
|
189
|
-
---
|
|
190
|
-
|
|
191
|
-
## Stripe Integration
|
|
192
|
-
|
|
193
|
-
### Flow
|
|
194
|
-
|
|
195
|
-
1. User clicks "Get early access" on Team pricing -> `/signup?plan=team`
|
|
196
|
-
2. After auth, redirects to `GET /api/stripe/checkout` -> Stripe Checkout
|
|
197
|
-
3. Stripe webhook (`POST /api/stripe/webhook`) handles:
|
|
198
|
-
- `checkout.session.completed` -- Upgrade user to TEAM plan
|
|
199
|
-
- `customer.subscription.updated` -- Update billing period
|
|
200
|
-
- `customer.subscription.deleted` -- Downgrade to FREE
|
|
201
|
-
|
|
202
|
-
### Plans
|
|
203
|
-
|
|
204
|
-
| Plan | Price | Features |
|
|
205
|
-
| ---------- | ----------- | ----------------------------------------------------- |
|
|
206
|
-
| Personal | Free | Auto-logging, personal dashboard, CLI, weekly digest |
|
|
207
|
-
| Team | $12/user/mo | Team dashboard, privacy controls, GitHub, ROI metrics |
|
|
208
|
-
| Enterprise | Custom | SSO/SAML, SOC 2, self-hosted, RBAC, audit logs |
|
|
209
|
-
|
|
210
|
-
---
|
|
211
|
-
|
|
212
|
-
## API Routes
|
|
213
|
-
|
|
214
|
-
### Data Ingestion
|
|
215
|
-
|
|
216
|
-
| Method | Route | Auth | Description |
|
|
217
|
-
| ------ | -------------- | ------- | -------------------------------------- |
|
|
218
|
-
| `POST` | `/api/entries` | API key | Create single work entry |
|
|
219
|
-
| `POST` | `/api/sync` | API key | Bulk upsert (idempotent via sessionId) |
|
|
220
|
-
|
|
221
|
-
### Data Retrieval
|
|
222
|
-
|
|
223
|
-
| Method | Route | Auth | Description |
|
|
224
|
-
| -------- | ------------------- | --------------- | -------------------------------------- |
|
|
225
|
-
| `GET` | `/api/entries` | Session/API key | List entries (paginated, filtered) |
|
|
226
|
-
| `GET` | `/api/entries/[id]` | Session | Get single entry |
|
|
227
|
-
| `PATCH` | `/api/entries/[id]` | Session | Update entry |
|
|
228
|
-
| `DELETE` | `/api/entries/[id]` | Session | Delete entry |
|
|
229
|
-
| `GET` | `/api/summary` | Session | Aggregated stats (optional `type=roi`) |
|
|
230
|
-
| `GET` | `/api/search?q=` | Session | Full-text search on summary/why |
|
|
231
|
-
|
|
232
|
-
### Organization
|
|
233
|
-
|
|
234
|
-
| Method | Route | Auth | Description |
|
|
235
|
-
| ----------------- | --------------------------- | ------------------ | ------------------------- |
|
|
236
|
-
| `GET/POST` | `/api/orgs` | Session | List/create organizations |
|
|
237
|
-
| `GET/POST` | `/api/orgs/[orgId]/members` | Session (Manager+) | List/add members |
|
|
238
|
-
| `GET/POST/DELETE` | `/api/orgs/[orgId]/invites` | Session (Admin) | Manage invites |
|
|
239
|
-
|
|
240
|
-
### Integrations
|
|
241
|
-
|
|
242
|
-
| Method | Route | Auth | Description |
|
|
243
|
-
| ----------------- | ----------------------------------- | -------------------- | --------------------- |
|
|
244
|
-
| `GET/POST/DELETE` | `/api/integrations/github` | Session + org member | GitHub integration |
|
|
245
|
-
| `GET/POST/DELETE` | `/api/integrations/hubspot` | Session + org member | HubSpot integration |
|
|
246
|
-
| `GET/POST/DELETE` | `/api/integrations/jira` | Session + org member | Jira integration |
|
|
247
|
-
| `GET/POST/DELETE` | `/api/integrations/google-calendar` | Session + org member | Google Calendar |
|
|
248
|
-
| `GET/POST/DELETE` | `/api/integrations/fireflies` | Session + org member | Fireflies integration |
|
|
249
|
-
|
|
250
|
-
All integration routes verify org membership. DELETE requires ADMIN role.
|
|
251
|
-
|
|
252
|
-
---
|
|
253
|
-
|
|
254
|
-
## Dashboard Pages
|
|
255
|
-
|
|
256
|
-
All pages use the warm cream aesthetic with shared components.
|
|
257
|
-
|
|
258
|
-
| Page | Path | Description |
|
|
259
|
-
| ------------ | ----------------------------- | ------------------------------------------------------------ |
|
|
260
|
-
| Overview | `/dashboard` | Personal feed + activity heatmap + quick stats |
|
|
261
|
-
| Team | `/dashboard/team` | Manager view: stacked bar chart, per-person activity, digest |
|
|
262
|
-
| Projects | `/dashboard/projects` | Project grid with category breakdown bars |
|
|
263
|
-
| ROI | `/dashboard/roi` | Snapshot metrics + bar/pie/line Recharts |
|
|
264
|
-
| Integrations | `/dashboard/integrations` | Connect/disconnect tool integrations |
|
|
265
|
-
| Settings | `/dashboard/settings` | Profile, API keys, notification prefs |
|
|
266
|
-
| Billing | `/dashboard/settings/billing` | Plan management, Stripe portal |
|
|
267
|
-
| Team Mgmt | `/dashboard/settings/team` | Members, roles, invites |
|
|
268
|
-
|
|
269
|
-
---
|
|
270
|
-
|
|
271
|
-
## Database Schema
|
|
272
|
-
|
|
273
|
-
10 models across auth, work tracking, organizations, and integrations:
|
|
274
|
-
|
|
275
|
-
- **User** -- Auth + Stripe billing fields + plan
|
|
276
|
-
- **Account/Session/VerificationToken** -- NextAuth adapter tables
|
|
277
|
-
- **Org** -- Organization with slug
|
|
278
|
-
- **OrgMember** -- User-org junction with role (ADMIN/MANAGER/DEVELOPER)
|
|
279
|
-
- **OrgInvite** -- Email invitations with expiry
|
|
280
|
-
- **WorkEntry** -- Core data: summary, category, why, outcome, git context, AI metadata
|
|
281
|
-
- **ApiKey** -- `bs_`-prefixed keys for CLI auth
|
|
282
|
-
- **Integration** -- Per-org tool connections
|
|
283
|
-
|
|
284
|
-
### Seed Data
|
|
285
|
-
|
|
286
|
-
Run `npx prisma db seed` to populate:
|
|
287
|
-
|
|
288
|
-
- **Acme Engineering** org with 3 team members
|
|
289
|
-
- **Sarah Chen** (Manager), **James Rodriguez** (Developer), **Priya Patel** (Developer)
|
|
290
|
-
- **~50 work entries** across 5 projects over 2 weeks
|
|
291
|
-
- Realistic summaries, PR URLs, branch names, session durations
|
|
292
|
-
|
|
293
|
-
---
|
|
294
|
-
|
|
295
|
-
## Claude Code Integration
|
|
296
|
-
|
|
297
|
-
The core product mechanic: `src/lib/integrations/claude-code-rules.ts` exports a CLAUDE.md template that instructs Claude Code to silently log structured work entries to `~/.basestream/buffer/` after every meaningful task.
|
|
298
|
-
|
|
299
|
-
Each entry captures:
|
|
300
|
-
|
|
301
|
-
- Summary, category, business context (why)
|
|
302
|
-
- Git context (repo, branch, files changed)
|
|
303
|
-
- Outcome and complexity
|
|
304
|
-
- AI metadata (model, tool version, session duration, turns)
|
|
305
|
-
|
|
306
|
-
The CLI syncs buffered entries to the API via `POST /api/sync`.
|
|
307
|
-
|
|
308
|
-
---
|
|
309
|
-
|
|
310
|
-
## Environment Variables
|
|
36
|
+
## Commands
|
|
311
37
|
|
|
312
38
|
```bash
|
|
313
|
-
#
|
|
314
|
-
|
|
39
|
+
basestream init # Set up Basestream in your environment
|
|
40
|
+
basestream login # Authenticate with your account
|
|
41
|
+
basestream sync # Manually sync buffered entries
|
|
42
|
+
basestream status # View this week's sessions
|
|
43
|
+
basestream uninstall # Remove Basestream from your environment
|
|
44
|
+
```
|
|
315
45
|
|
|
316
|
-
|
|
317
|
-
SKIP_PAYMENT=true
|
|
46
|
+
## Dashboard
|
|
318
47
|
|
|
319
|
-
|
|
320
|
-
NEXTAUTH_URL=http://localhost:3000
|
|
321
|
-
NEXTAUTH_SECRET= # openssl rand -base64 32
|
|
48
|
+
Your team's AI work shows up at [app.basestream.ai](https://app.basestream.ai):
|
|
322
49
|
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
50
|
+
- **Overview** — Activity feed, heatmap, quick stats
|
|
51
|
+
- **Team** — Who's building what, output by person
|
|
52
|
+
- **Projects** — Work grouped by repository
|
|
53
|
+
- **Scores** — Performance metrics weighted by role
|
|
54
|
+
- **Cost Intelligence** — Token spend, tool adoption, before/after efficiency
|
|
55
|
+
- **ROI** — Cost per outcome, hours saved, completion rates
|
|
56
|
+
- **Integrations** — Connect GitHub, Jira, Notion, Google Calendar, and more
|
|
328
57
|
|
|
329
|
-
|
|
330
|
-
STRIPE_SECRET_KEY=
|
|
331
|
-
STRIPE_PUBLISHABLE_KEY=
|
|
332
|
-
STRIPE_WEBHOOK_SECRET=
|
|
333
|
-
STRIPE_TEAM_PRICE_ID=
|
|
58
|
+
## Plans
|
|
334
59
|
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
GOOGLE_CALENDAR_CLIENT_ID=
|
|
341
|
-
GOOGLE_CALENDAR_CLIENT_SECRET=
|
|
342
|
-
FIREFLIES_API_KEY=
|
|
343
|
-
```
|
|
60
|
+
| Plan | Price | For |
|
|
61
|
+
| ---------- | ----------- | ----------------------------------- |
|
|
62
|
+
| Personal | Free | Individual developers |
|
|
63
|
+
| Team | $12/user/mo | Engineering teams |
|
|
64
|
+
| Enterprise | Custom | Organizations with compliance needs |
|
|
344
65
|
|
|
345
|
-
|
|
66
|
+
## Privacy
|
|
346
67
|
|
|
347
|
-
|
|
68
|
+
- Work entries are scoped to your organization
|
|
69
|
+
- Visibility controls: private, team, or public per entry
|
|
70
|
+
- No source code is ever captured — only metadata
|
|
71
|
+
- API keys are scoped per user, revocable anytime
|
|
348
72
|
|
|
349
|
-
|
|
350
|
-
npm run dev # Start dev server (port 3000)
|
|
351
|
-
npm run build # Production build
|
|
352
|
-
npm run start # Start production server
|
|
353
|
-
npm run db:generate # Generate SQL migration from schema
|
|
354
|
-
npm run db:push # Push schema to database
|
|
355
|
-
npm run db:seed # Seed demo data (npx tsx src/db/seed.ts)
|
|
356
|
-
npx drizzle-kit studio # Visual database browser
|
|
357
|
-
npx tsc --noEmit # Type check
|
|
358
|
-
```
|
|
73
|
+
## Support
|
|
359
74
|
|
|
360
|
-
|
|
75
|
+
- [Documentation](https://docs.basestream.ai)
|
|
76
|
+
- [Contact us](mailto:support@basestream.ai)
|
|
361
77
|
|
|
362
|
-
|
|
78
|
+
---
|
|
363
79
|
|
|
364
|
-
|
|
365
|
-
| ---------------------------------- | ------------------------------------------------------ |
|
|
366
|
-
| TypeScript strict (`tsc --noEmit`) | 0 errors |
|
|
367
|
-
| Next.js build (`next build`) | All 26 pages generated |
|
|
368
|
-
| Landing page sections | All 12 implemented |
|
|
369
|
-
| Dashboard pages | All 9 implemented |
|
|
370
|
-
| API routes | All 16 implemented |
|
|
371
|
-
| Shared components used | All 8 dashboard + 5 UI components wired in |
|
|
372
|
-
| Auth flow | NextAuth + DrizzleAdapter + middleware + 3 providers |
|
|
373
|
-
| Stripe flow | Checkout + webhook + portal + SKIP_PAYMENT bypass |
|
|
374
|
-
| Drizzle schema | 10 tables (bs\_ prefixed), 7 enums, all indexes |
|
|
375
|
-
| Seed data | 3 users, 44 entries, 1 org |
|
|
376
|
-
| Monorepo integration | `packages/basestream/`, shared Postgres on port 5434 |
|
|
377
|
-
| E2E API tested | POST/GET entries, bulk sync (idempotent), API key auth |
|
|
378
|
-
| Design system | Colors, fonts, animations all matching spec |
|
|
379
|
-
| Mobile responsive | Sidebar collapse, grid stack, nav hide |
|
|
380
|
-
| Branding | "Basestream" + "A Sublevel product" throughout |
|
|
80
|
+
Built by [Sublevel Inc.](https://sublevel.com)
|
package/dist/cli.mjs
CHANGED
|
@@ -455,6 +455,18 @@ var OrgRole = makeEnum(["ADMIN", "MANAGER", "USER"]);
|
|
|
455
455
|
var ArtifactStatus = makeEnum(["GENERATING", "READY", "FAILED"]);
|
|
456
456
|
var ArtifactPeriod = makeEnum(["QUARTER", "HALF", "YEAR", "CUSTOM"]);
|
|
457
457
|
var IntegrationType = makeEnum(["GITHUB", "HUBSPOT", "JIRA", "GOOGLE_CALENDAR", "FIREFLIES", "CLAUDE_CODE", "NOTION"]);
|
|
458
|
+
var MemberRole = makeEnum([
|
|
459
|
+
"ENGINEER",
|
|
460
|
+
"MANAGER",
|
|
461
|
+
"DESIGNER",
|
|
462
|
+
"EXEC",
|
|
463
|
+
"SALES",
|
|
464
|
+
"SUPPORT",
|
|
465
|
+
"DATA_SCIENTIST",
|
|
466
|
+
"PRODUCT",
|
|
467
|
+
"QA",
|
|
468
|
+
"DEVOPS"
|
|
469
|
+
]);
|
|
458
470
|
|
|
459
471
|
// src/cli/commands/status.ts
|
|
460
472
|
init_util();
|
|
@@ -605,6 +617,10 @@ function readSessionAccumulator(sessionId) {
|
|
|
605
617
|
raw.filesWritten = new Set(raw.filesWritten || []);
|
|
606
618
|
raw.commitShas = new Set(raw.commitShas || []);
|
|
607
619
|
raw.userMessages = raw.userMessages || [];
|
|
620
|
+
raw.inputTokens = raw.inputTokens || 0;
|
|
621
|
+
raw.outputTokens = raw.outputTokens || 0;
|
|
622
|
+
raw.cacheReadTokens = raw.cacheReadTokens || 0;
|
|
623
|
+
raw.cacheWriteTokens = raw.cacheWriteTokens || 0;
|
|
608
624
|
return raw;
|
|
609
625
|
} catch {
|
|
610
626
|
return null;
|
|
@@ -616,8 +632,12 @@ function writeSessionAccumulator(acc) {
|
|
|
616
632
|
...acc,
|
|
617
633
|
filesWritten: Array.from(acc.filesWritten),
|
|
618
634
|
commitShas: Array.from(acc.commitShas),
|
|
619
|
-
userMessages: acc.userMessages.slice(0, 5)
|
|
620
|
-
|
|
635
|
+
userMessages: acc.userMessages.slice(0, 5),
|
|
636
|
+
inputTokens: acc.inputTokens,
|
|
637
|
+
outputTokens: acc.outputTokens,
|
|
638
|
+
cacheReadTokens: acc.cacheReadTokens,
|
|
639
|
+
cacheWriteTokens: acc.cacheWriteTokens,
|
|
640
|
+
model: acc.model
|
|
621
641
|
};
|
|
622
642
|
fs5.writeFileSync(sessionFile, JSON.stringify(serializable, null, 2));
|
|
623
643
|
}
|
|
@@ -650,6 +670,18 @@ function analyzeTranscript(transcriptPath, acc) {
|
|
|
650
670
|
);
|
|
651
671
|
if (hasText) acc.turns++;
|
|
652
672
|
}
|
|
673
|
+
if (entry.type === "assistant") {
|
|
674
|
+
const msg = entry.message;
|
|
675
|
+
const usage = msg?.usage || entry.usage;
|
|
676
|
+
const model = msg?.model || entry.model;
|
|
677
|
+
if (model) acc.model = model;
|
|
678
|
+
if (usage) {
|
|
679
|
+
acc.inputTokens += usage.input_tokens || 0;
|
|
680
|
+
acc.outputTokens += usage.output_tokens || 0;
|
|
681
|
+
acc.cacheReadTokens += usage.cache_read_input_tokens || 0;
|
|
682
|
+
acc.cacheWriteTokens += usage.cache_creation_input_tokens || 0;
|
|
683
|
+
}
|
|
684
|
+
}
|
|
653
685
|
if (entry.type === "assistant") {
|
|
654
686
|
for (const block of contentBlocks) {
|
|
655
687
|
if (block.type === "tool_use") {
|
|
@@ -751,7 +783,11 @@ function flushToBuffer(acc) {
|
|
|
751
783
|
filesTouched: acc.filesWritten.size,
|
|
752
784
|
complexity,
|
|
753
785
|
toolVersion: null,
|
|
754
|
-
model: null,
|
|
786
|
+
model: acc.model || null,
|
|
787
|
+
inputTokens: acc.inputTokens > 0 ? acc.inputTokens : null,
|
|
788
|
+
outputTokens: acc.outputTokens > 0 ? acc.outputTokens : null,
|
|
789
|
+
cacheReadTokens: acc.cacheReadTokens > 0 ? acc.cacheReadTokens : null,
|
|
790
|
+
cacheWriteTokens: acc.cacheWriteTokens > 0 ? acc.cacheWriteTokens : null,
|
|
755
791
|
sessionDurationMin: durationMin > 0 ? durationMin : 1,
|
|
756
792
|
turns: acc.turns,
|
|
757
793
|
prUrl: null,
|
|
@@ -865,6 +901,10 @@ async function hookStop() {
|
|
|
865
901
|
filesWritten: /* @__PURE__ */ new Set(),
|
|
866
902
|
commitShas: /* @__PURE__ */ new Set(),
|
|
867
903
|
userMessages: [],
|
|
904
|
+
inputTokens: 0,
|
|
905
|
+
outputTokens: 0,
|
|
906
|
+
cacheReadTokens: 0,
|
|
907
|
+
cacheWriteTokens: 0,
|
|
868
908
|
gitBranch: gitInfo.branch,
|
|
869
909
|
gitRepo: gitInfo.repo,
|
|
870
910
|
projectName: gitInfo.projectName
|
|
@@ -874,6 +914,11 @@ async function hookStop() {
|
|
|
874
914
|
acc.turns = 0;
|
|
875
915
|
acc.toolCalls = [];
|
|
876
916
|
acc.userMessages = [];
|
|
917
|
+
acc.inputTokens = 0;
|
|
918
|
+
acc.outputTokens = 0;
|
|
919
|
+
acc.cacheReadTokens = 0;
|
|
920
|
+
acc.cacheWriteTokens = 0;
|
|
921
|
+
acc.model = void 0;
|
|
877
922
|
if (transcript_path) {
|
|
878
923
|
acc = analyzeTranscript(transcript_path, acc);
|
|
879
924
|
}
|
|
@@ -1014,7 +1059,7 @@ async function main() {
|
|
|
1014
1059
|
process.exit(0);
|
|
1015
1060
|
}
|
|
1016
1061
|
if (command === "--version" || command === "-v") {
|
|
1017
|
-
console.log(true ? "0.
|
|
1062
|
+
console.log(true ? "0.3.0" : "dev");
|
|
1018
1063
|
process.exit(0);
|
|
1019
1064
|
}
|
|
1020
1065
|
switch (command || "init") {
|
package/package.json
CHANGED