burnboard-cli 0.1.0 → 0.2.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/cli.mjs CHANGED
@@ -8,6 +8,9 @@ import { fileURLToPath } from "node:url";
8
8
  const packageRoot = path.dirname(fileURLToPath(import.meta.url));
9
9
  const installRoot = path.join(packageRoot, "install");
10
10
  const burnboardRoot = path.join(os.homedir(), ".burnboard");
11
+ const cliVersion = JSON.parse(fs.readFileSync(path.join(packageRoot, "package.json"), "utf8")).version;
12
+ const installedVersionPath = path.join(burnboardRoot, "cli-version");
13
+ const lastUpdateCheckPath = path.join(burnboardRoot, "last-update-check");
11
14
  const command = process.argv[2] || "help";
12
15
  const args = process.argv.slice(3);
13
16
 
@@ -20,17 +23,44 @@ function run(executable, runArgs) {
20
23
  const result = spawnSync(executable, runArgs, { stdio: "inherit" });
21
24
  if (result.error) throw result.error;
22
25
  process.exitCode = result.status ?? 1;
26
+ return result.status ?? 1;
23
27
  }
24
28
 
25
- function setup() {
26
- const name = option("--name", args.find((value) => !value.startsWith("-")));
29
+ function setup(nameOverride) {
30
+ const name = nameOverride || option("--name", args.find((value) => !value.startsWith("-")));
27
31
  const server = option("--server", "https://burnboard-public.vercel.app");
28
32
  if (!name || name.startsWith("--")) throw new Error('A name is required. Example: npx burnboard-cli setup --name "Harsh Sawant"');
33
+ let status;
29
34
  if (process.platform === "win32") {
30
- run("powershell.exe", ["-NoLogo", "-NoProfile", "-ExecutionPolicy", "Bypass", "-File", path.join(installRoot, "burnboard-setup.ps1"), "-Name", name, "-ServerUrl", server]);
35
+ status = run("powershell.exe", ["-NoLogo", "-NoProfile", "-ExecutionPolicy", "Bypass", "-File", path.join(installRoot, "burnboard-setup.ps1"), "-Name", name, "-ServerUrl", server]);
31
36
  } else {
32
- run("bash", [path.join(installRoot, "burnboard-setup.sh"), name, server]);
37
+ status = run("bash", [path.join(installRoot, "burnboard-setup.sh"), name, server]);
33
38
  }
39
+ if (status === 0) {
40
+ fs.writeFileSync(installedVersionPath, `${cliVersion}\n`);
41
+ fs.writeFileSync(lastUpdateCheckPath, `${new Date().toISOString()}\n`);
42
+ }
43
+ return status;
44
+ }
45
+
46
+ function update() {
47
+ const configPath = path.join(burnboardRoot, "config.json");
48
+ if (!fs.existsSync(configPath)) throw new Error("BurnBoard is not installed. Run the setup command first.");
49
+ const config = JSON.parse(fs.readFileSync(configPath, "utf8").replace(/^\uFEFF/, ""));
50
+ if (!config.token) throw new Error("The existing BurnBoard configuration is incomplete. Run setup again with your name.");
51
+ const force = args.includes("--force"), lastCheck = fs.existsSync(lastUpdateCheckPath) ? Date.parse(fs.readFileSync(lastUpdateCheckPath, "utf8").trim()) : 0;
52
+ if (!force && Number.isFinite(lastCheck) && Date.now() - lastCheck < 20 * 60 * 60 * 1000) {
53
+ console.log("BurnBoard update check skipped; it already ran recently.");
54
+ return;
55
+ }
56
+ const installedVersion = fs.existsSync(installedVersionPath) ? fs.readFileSync(installedVersionPath, "utf8").trim() : "";
57
+ if (!force && installedVersion === cliVersion) {
58
+ fs.writeFileSync(lastUpdateCheckPath, `${new Date().toISOString()}\n`);
59
+ console.log(`BurnBoard is already up to date (${cliVersion}).`);
60
+ return;
61
+ }
62
+ console.log(`Updating BurnBoard from ${installedVersion || "a legacy installation"} to ${cliVersion}...`);
63
+ if (setup("Existing BurnBoard User") !== 0) throw new Error("The update did not complete successfully; the existing tracker is unchanged.");
34
64
  }
35
65
 
36
66
  function sync() {
@@ -48,7 +78,8 @@ function status() {
48
78
  const config = JSON.parse(fs.readFileSync(configPath, "utf8").replace(/^\uFEFF/, ""));
49
79
  console.log(`BurnBoard is installed for ${config.serverUrl}${config.profileUrl || ""}`);
50
80
  console.log(`Tracker: ${fs.existsSync(path.join(burnboardRoot, "agent.mjs")) ? "ready" : "missing"}`);
51
- if (process.platform === "win32") run("powershell.exe", ["-NoLogo", "-NoProfile", "-Command", "$t=Get-ScheduledTask -TaskName 'Burnboard Token Sync' -ErrorAction SilentlyContinue;if($t){$i=$t|Get-ScheduledTaskInfo;Write-Output ('Schedule: '+$t.State+'; next run: '+$i.NextRunTime)}else{Write-Output 'Schedule: missing'}"]);
81
+ console.log(`Installer version: ${fs.existsSync(installedVersionPath) ? fs.readFileSync(installedVersionPath, "utf8").trim() : "legacy"} (running CLI ${cliVersion})`);
82
+ if (process.platform === "win32") run("powershell.exe", ["-NoLogo", "-NoProfile", "-Command", "foreach($name in @('Burnboard Token Sync','Burnboard Auto Update')){$t=Get-ScheduledTask -TaskName $name -ErrorAction SilentlyContinue;if($t){$i=$t|Get-ScheduledTaskInfo;Write-Output ($name+': '+$t.State+'; next run: '+$i.NextRunTime)}else{Write-Output ($name+': missing')}}"]);
52
83
  }
53
84
 
54
85
  function help() {
@@ -56,12 +87,14 @@ function help() {
56
87
 
57
88
  burnboard setup --name "Your Name" Install or repair automatic sync
58
89
  burnboard sync Sync usage now
90
+ burnboard update Update tracker and scheduling now
59
91
  burnboard status Check the local installation`);
60
92
  }
61
93
 
62
94
  try {
63
95
  if (command === "setup") setup();
64
96
  else if (command === "sync") sync();
97
+ else if (command === "update") update();
65
98
  else if (command === "status") status();
66
99
  else if (["help", "--help", "-h"].includes(command)) help();
67
100
  else throw new Error(`Unknown command: ${command}`);
@@ -38,6 +38,15 @@ $trigger=New-ScheduledTaskTrigger -Once -At (Get-Date).AddMinutes(1) -Repetition
38
38
  $settings=New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -StartWhenAvailable -RestartCount 3 -RestartInterval (New-TimeSpan -Minutes 1)
39
39
  $userId=[System.Security.Principal.WindowsIdentity]::GetCurrent().Name;$principal=New-ScheduledTaskPrincipal -UserId $userId -LogonType Interactive -RunLevel Limited
40
40
  Register-ScheduledTask -TaskName "Burnboard Token Sync" -Action $action -Trigger $trigger -Settings $settings -Principal $principal -Force|Out-Null
41
+ $npx=(Get-Command npx.cmd -ErrorAction Stop).Source
42
+ $updateLauncher=Join-Path $installDir "update-hidden.vbs"
43
+ $npxVbs=$npx.Replace('"','""')
44
+ $updateLauncherText="Set shell = CreateObject(`"WScript.Shell`")`r`ncommand = Chr(34) & `"$npxVbs`" & Chr(34) & `" --yes burnboard-cli@latest update`"`r`nexitCode = shell.Run(command, 0, True)`r`nWScript.Quit exitCode`r`n"
45
+ [System.IO.File]::WriteAllText($updateLauncher,$updateLauncherText,$utf8NoBom)
46
+ $updateAction=New-ScheduledTaskAction -Execute $wscript -Argument "//B //NoLogo `"$updateLauncher`""
47
+ $dailyUpdateTrigger=New-ScheduledTaskTrigger -Daily -At "4:00 AM"
48
+ $loginUpdateTrigger=New-ScheduledTaskTrigger -AtLogOn -User $userId;$loginUpdateTrigger.Delay="PT3M"
49
+ Register-ScheduledTask -TaskName "Burnboard Auto Update" -Action $updateAction -Trigger @($dailyUpdateTrigger,$loginUpdateTrigger) -Settings $settings -Principal $principal -Force|Out-Null
41
50
  $antigravityProcess=Get-Process -Name "Antigravity" -ErrorAction SilentlyContinue
42
51
  if(-not $antigravityProcess){
43
52
  $antigravityCandidates=@(
@@ -93,4 +102,4 @@ Show-SetupProgress 100 "Complete"
93
102
  Write-Progress -Activity "Connecting to BurnBoard" -Completed
94
103
  if($agentOutput){Write-Host $agentOutput.Trim()}
95
104
  Write-Host "Burnboard is connected: $ServerUrl$($enrollment.profileUrl)"
96
- Write-Host "Codex, Claude Code, Cursor, and both supported Antigravity installations sync every 5 minutes."
105
+ Write-Host "Codex, Claude Code, Cursor, and both supported Antigravity installations sync every 5 minutes. Burnboard checks for updates daily."
@@ -16,10 +16,10 @@ node -e 'require("fs").writeFileSync(process.argv[1],JSON.stringify({serverUrl:p
16
16
  node - "$HOME/.claude/settings.json" <<'NODE'
17
17
  const fs=require('fs'),file=process.argv[2],current=fs.existsSync(file)?JSON.parse(fs.readFileSync(file,'utf8')):{};current.env=current.env||{};for(const key of ['CLAUDE_CODE_ENABLE_TELEMETRY','OTEL_METRICS_EXPORTER','OTEL_LOGS_EXPORTER','OTEL_EXPORTER_OTLP_METRICS_PROTOCOL','OTEL_EXPORTER_OTLP_METRICS_ENDPOINT','OTEL_EXPORTER_OTLP_METRICS_HEADERS','OTEL_METRIC_EXPORT_INTERVAL','OTEL_METRICS_INCLUDE_SESSION_ID'])delete current.env[key];fs.writeFileSync(file,JSON.stringify(current,null,2)+"\n");
18
18
  NODE
19
- printf '[3/5] Scheduling automatic sync...\n'; (crontab -l 2>/dev/null|grep -v 'burnboard/agent.mjs'||true;echo "*/5 * * * * $(command -v node) $INSTALL_DIR/agent.mjs >/dev/null 2>&1")|crontab -
19
+ printf '[3/5] Scheduling automatic sync...\n'; (crontab -l 2>/dev/null|grep -Ev 'burnboard/agent.mjs|burnboard-cli@latest update'||true;echo "*/5 * * * * $(command -v node) $INSTALL_DIR/agent.mjs >/dev/null 2>&1";echo "0 4 * * * $(command -v npx) --yes burnboard-cli@latest update >/dev/null 2>&1";echo "@reboot sleep 180 && $(command -v npx) --yes burnboard-cli@latest update >/dev/null 2>&1")|crontab -
20
20
  if [[ "$(uname -s)" == "Darwin" ]] && ! pgrep -x Antigravity >/dev/null 2>&1 && [[ -d "/Applications/Antigravity.app" ]]; then open -a Antigravity; sleep 8; fi
21
21
  printf '[4/5] Counting and uploading local history'; OUT="$INSTALL_DIR/setup-sync.out"; ERR="$INSTALL_DIR/setup-sync.err"; node "$INSTALL_DIR/agent.mjs" >"$OUT" 2>"$ERR" & PID=$!
22
22
  while kill -0 "$PID" 2>/dev/null; do printf '.'; sleep 1; done
23
23
  if ! wait "$PID"; then printf '\n'; cat "$ERR" >&2; rm -f "$OUT" "$ERR"; exit 1; fi
24
24
  printf '\n[5/5] Complete\n'; cat "$OUT"; rm -f "$OUT" "$ERR"
25
- echo "Burnboard is connected: $SERVER_URL$PROFILE"; echo "Codex, Claude Code, Cursor, and both supported Antigravity installations sync every 5 minutes."
25
+ echo "Burnboard is connected: $SERVER_URL$PROFILE"; echo "Codex, Claude Code, Cursor, and both supported Antigravity installations sync every 5 minutes. Burnboard checks for updates daily."
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "burnboard-cli",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "Connect local AI coding token usage to BurnBoard",
5
5
  "type": "module",
6
6
  "bin": {