burnwatch 0.5.1 → 0.5.2

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/CHANGELOG.md CHANGED
@@ -5,11 +5,18 @@ All notable changes to burnwatch will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [0.5.2] - 2026-03-24
9
+
10
+ ### Changed
11
+
12
+ - **Zero manual commands after init**: Every detected service is now fully configured during init - plan, tier, and budget. No wall of `burnwatch add` commands. Registry now includes `suggestedBudget` for all usage-based plans (Anthropic $100, OpenAI $100, Stripe $50, Google Gemini $50, Voyage AI $20, AWS $50). Flat-rate services get budget = plan cost. Free tiers get $0.
13
+ - **Interactive interview uses suggested budgets as defaults**: Usage plans show `Monthly budget [$100]: $` instead of a blank prompt. Press Enter to accept.
14
+
8
15
  ## [0.5.1] - 2026-03-24
9
16
 
10
17
  ### Fixed
11
18
 
12
- - **Init actually works now**: `process.stdin.isTTY` was `undefined` in Claude Code and many terminal environments, so the interactive interview never ran. Init now has three modes: (1) TTY detected = full interactive interview, (2) no TTY = smart auto-configure with defaults, (3) `--non-interactive` = minimal CI mode. The auto-configure path picks each service's default plan, detects API keys from env vars and global config, sets budget = plan cost for flat plans and $0 for usage-based, and only shows `burnwatch add` commands for the handful of usage-based services that genuinely need a human-set budget.
19
+ - **Init actually works now**: `process.stdin.isTTY` was `undefined` in Claude Code and many terminal environments, so the interactive interview never ran. Init now has three modes: (1) TTY detected = full interactive interview, (2) no TTY = smart auto-configure with defaults, (3) `--non-interactive` = minimal CI mode.
13
20
 
14
21
  ## [0.5.0] - 2026-03-24
15
22
 
@@ -72,6 +79,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
72
79
  - Snapshot system for delta computation across sessions
73
80
  - Claude Code skills: `/spend` (on-demand brief), `/setup-burnwatch` (guided onboarding)
74
81
 
82
+ [0.5.2]: https://github.com/RaleighSF/burnwatch/compare/v0.5.1...v0.5.2
75
83
  [0.5.1]: https://github.com/RaleighSF/burnwatch/compare/v0.5.0...v0.5.1
76
84
  [0.5.0]: https://github.com/RaleighSF/burnwatch/compare/v0.4.3...v0.5.0
77
85
  [0.4.3]: https://github.com/RaleighSF/burnwatch/compare/v0.4.2...v0.4.3
package/dist/cli.js CHANGED
@@ -874,6 +874,8 @@ function autoConfigureServices(detected) {
874
874
  if (defaultPlan.type === "flat" && defaultPlan.monthlyBase !== void 0) {
875
875
  tracked.planCost = defaultPlan.monthlyBase;
876
876
  tracked.budget = defaultPlan.monthlyBase;
877
+ } else if (defaultPlan.suggestedBudget !== void 0) {
878
+ tracked.budget = defaultPlan.suggestedBudget;
877
879
  }
878
880
  }
879
881
  const existingKey = globalConfig.services[service.id]?.apiKey;
@@ -905,16 +907,6 @@ function autoConfigureServices(detected) {
905
907
  console.log(" " + "-".repeat(48));
906
908
  console.log(` ${trackedList.length} services configured | Total budget: $${totalBudget}/mo`);
907
909
  if (liveCount > 0) console.log(` ${liveCount} with real-time billing (LIVE)`);
908
- const needBudget = trackedList.filter(
909
- (s) => s.budget === 0 && s.planCost === void 0
910
- );
911
- if (needBudget.length > 0) {
912
- console.log(`
913
- ${needBudget.length} usage-based service${needBudget.length > 1 ? "s" : ""} need budgets:`);
914
- for (const svc of needBudget) {
915
- console.log(` burnwatch add ${svc.serviceId} --budget <AMOUNT>`);
916
- }
917
- }
918
910
  console.log("");
919
911
  writeGlobalConfig(globalConfig);
920
912
  return { services };
@@ -1032,25 +1024,16 @@ async function runInteractiveInit(detected) {
1032
1024
  }
1033
1025
  }
1034
1026
  }
1035
- const planCost = chosen.monthlyBase ?? 0;
1036
- if (chosen.type === "usage" && planCost === 0) {
1037
- const budgetAnswer = await ask(
1038
- rl,
1039
- ` Monthly budget: $`
1040
- );
1027
+ const defaultBudget = chosen.monthlyBase ?? chosen.suggestedBudget ?? 0;
1028
+ const budgetAnswer = await ask(
1029
+ rl,
1030
+ ` Monthly budget [$${defaultBudget}]: $`
1031
+ );
1032
+ if (budgetAnswer) {
1041
1033
  const parsed = parseFloat(budgetAnswer);
1042
- tracked2.budget = !isNaN(parsed) ? parsed : 0;
1034
+ tracked2.budget = !isNaN(parsed) ? parsed : defaultBudget;
1043
1035
  } else {
1044
- const budgetAnswer = await ask(
1045
- rl,
1046
- ` Monthly budget [$${planCost}]: $`
1047
- );
1048
- if (budgetAnswer) {
1049
- const parsed = parseFloat(budgetAnswer);
1050
- tracked2.budget = !isNaN(parsed) ? parsed : planCost;
1051
- } else {
1052
- tracked2.budget = planCost;
1053
- }
1036
+ tracked2.budget = defaultBudget;
1054
1037
  }
1055
1038
  services[service.id] = tracked2;
1056
1039
  const tierLabel = tracked2.hasApiKey ? "LIVE" : tracked2.planCost !== void 0 ? "CALC" : "BLIND";