bavitutor 0.1.2 → 0.1.4

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 CHANGED
@@ -20,9 +20,10 @@ opens your browser. Data stays on your machine in `~/.bavitutor`. If 4100 is
20
20
  taken it moves to the next free port, and if BaviTutor is already running it
21
21
  opens that one.
22
22
 
23
- npx and vpx reuse a version they downloaded before (pnpm for a day), so when a
24
- newer one is out BaviTutor says so on start, with the exact command:
25
- `npx bavitutor@<version>` always fetches that version.
23
+ It always runs the newest version: on start it asks npm, and if a newer one is
24
+ out it starts that one instead, through npx or vpx like you did. (vpx inside a
25
+ pnpm project would otherwise reuse its download for a day.) `--no-update` skips
26
+ this.
26
27
 
27
28
  Requirements: Node 24+, [Vite+](https://viteplus.dev) (`vp`), and a logged-in
28
29
  [Claude Code](https://claude.com/claude-code) install (the Claude Agent SDK
@@ -8,7 +8,7 @@ import { createServer } from "node:http";
8
8
  import { connect, createServer as createServer$1 } from "node:net";
9
9
  import * as NodeCrypto from "node:crypto";
10
10
  import * as NFS from "node:fs";
11
- import { existsSync, mkdirSync, readFileSync } from "node:fs";
11
+ import { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
12
12
  import * as OS from "node:os";
13
13
  import { homedir, tmpdir } from "node:os";
14
14
  import * as Path from "node:path";
@@ -46584,7 +46584,7 @@ const fromLiteral = (literal) => codeByLiteral[literal];
46584
46584
  //#endregion
46585
46585
  //#region package.json
46586
46586
  var name = "bavitutor";
46587
- var version$1 = "0.1.2";
46587
+ var version$1 = "0.1.4";
46588
46588
  /**
46589
46589
  * Default Server-Sent Events encoder.
46590
46590
  *
@@ -61759,6 +61759,7 @@ Options:
61759
61759
  --host <host> interface to listen on (default: ${DEFAULT_HOST}, this machine only)
61760
61760
  --data-dir <dir> database and settings (default: ~/.bavitutor)
61761
61761
  --no-open don't open the browser
61762
+ --no-update don't switch to a newer version from npm
61762
61763
  -v, --version print the version
61763
61764
  -h, --help print this help
61764
61765
 
@@ -61781,6 +61782,10 @@ const parseOptions = () => {
61781
61782
  type: "boolean",
61782
61783
  default: true
61783
61784
  },
61785
+ update: {
61786
+ type: "boolean",
61787
+ default: true
61788
+ },
61784
61789
  version: {
61785
61790
  type: "boolean",
61786
61791
  short: "v"
@@ -61931,7 +61936,7 @@ const choosePort = async (requested, isExplicit, host) => {
61931
61936
  const latestVersion = async () => {
61932
61937
  if (process.env["NO_UPDATE_NOTIFIER"]) return;
61933
61938
  try {
61934
- const response = await fetch(`https://registry.npmjs.org/${name}/latest`, { signal: AbortSignal.timeout(3e3) });
61939
+ const response = await fetch(`https://registry.npmjs.org/${name}/latest`, { signal: AbortSignal.timeout(2e3) });
61935
61940
  const body = await response.json();
61936
61941
  return response.ok && body !== null && typeof body === "object" && "version" in body && typeof body.version === "string" ? body.version : void 0;
61937
61942
  } catch {
@@ -61949,10 +61954,58 @@ const isNewer = (candidate, current) => {
61949
61954
  return difference !== void 0 && difference > 0;
61950
61955
  };
61951
61956
  /**
61952
- * npx and vpx (through pnpm dlx) reuse what they downloaded before, so a bare
61953
- * `npx bavitutor` can keep starting an old version. An exact version is
61954
- * always fetched, so the notice names one.
61955
- */
61957
+ * How to start another version the way this one was started: npx, and vpx
61958
+ * outside a pnpm project, run `npm exec`; vpx inside one runs `pnpm dlx`,
61959
+ * which reuses what it downloaded for a day. An exact version is always
61960
+ * fetched. Undefined for a global install or a checkout's own build.
61961
+ */
61962
+ const relaunchCommand = (version) => {
61963
+ const runner = process.env["npm_execpath"];
61964
+ const spec = `${name}@${version}`;
61965
+ const args = process.argv.slice(2);
61966
+ const runnerArgs = process.env["npm_command"] === "exec" ? [
61967
+ "exec",
61968
+ "--yes",
61969
+ `--package=${spec}`,
61970
+ "--",
61971
+ name,
61972
+ ...args
61973
+ ] : process.env["npm_command"] === "dlx" ? [
61974
+ "dlx",
61975
+ spec,
61976
+ ...args
61977
+ ] : void 0;
61978
+ if (!runner || runnerArgs === void 0) return;
61979
+ return /\.[cm]?js$/.test(runner) ? [process.execPath, [runner, ...runnerArgs]] : [runner, runnerArgs];
61980
+ };
61981
+ /** Set for the newer version, which deletes the file once its code runs. */
61982
+ const RELAUNCH_MARKER = "BAVI_RELAUNCH_MARKER";
61983
+ /**
61984
+ * Runs the newer version in this terminal and resolves with its exit code,
61985
+ * or undefined if it never started (say npm can't serve it yet).
61986
+ */
61987
+ const runNewer = (command, args) => new Promise((done) => {
61988
+ const marker = join(tmpdir(), `bavitutor-relaunch-${process.pid}`);
61989
+ writeFileSync(marker, "");
61990
+ const waitForChild = () => {};
61991
+ process.on("SIGINT", waitForChild);
61992
+ const finish = (code) => {
61993
+ process.off("SIGINT", waitForChild);
61994
+ const hasStarted = !existsSync(marker);
61995
+ rmSync(marker, { force: true });
61996
+ done(hasStarted ? code : void 0);
61997
+ };
61998
+ const child = spawn(command, args, {
61999
+ stdio: "inherit",
62000
+ env: {
62001
+ ...process.env,
62002
+ [RELAUNCH_MARKER]: marker
62003
+ }
62004
+ });
62005
+ child.once("error", () => finish(void 0));
62006
+ child.once("exit", (code) => finish(code ?? 0));
62007
+ });
62008
+ /** Where starting the newest version wasn't possible, says how to. */
61956
62009
  const sayIfOutdated = (latest) => {
61957
62010
  if (latest !== void 0 && isNewer(latest, version$1)) {
61958
62011
  say(`BaviTutor ${latest} is out (this is ${version$1}). To update,`);
@@ -61992,7 +62045,23 @@ const main = async () => {
61992
62045
  say(version$1);
61993
62046
  return;
61994
62047
  }
61995
- const latest = latestVersion();
62048
+ const marker = process.env[RELAUNCH_MARKER];
62049
+ if (marker !== void 0) {
62050
+ rmSync(marker, { force: true });
62051
+ delete process.env[RELAUNCH_MARKER];
62052
+ }
62053
+ const latest = options.update && marker === void 0 ? await latestVersion() : void 0;
62054
+ const relaunch = latest !== void 0 && isNewer(latest, version$1) ? relaunchCommand(latest) : void 0;
62055
+ if (latest !== void 0 && relaunch !== void 0) {
62056
+ say(`BaviTutor ${latest} is out, starting it instead of ${version$1}`);
62057
+ const code = await runNewer(...relaunch);
62058
+ if (code !== void 0) {
62059
+ process.exitCode = code;
62060
+ return;
62061
+ }
62062
+ say(` couldn't start ${latest}, so staying on ${version$1}`);
62063
+ say();
62064
+ }
61996
62065
  const dataDir = resolve(expandHome(options["data-dir"] ?? join(homedir(), ".bavitutor")));
61997
62066
  mkdirSync(dataDir, { recursive: true });
61998
62067
  const envFile = join(dataDir, ".env");
@@ -62035,7 +62104,7 @@ const main = async () => {
62035
62104
  say(`BaviTutor is already running at ${urlFor(choice.port)}`);
62036
62105
  say();
62037
62106
  if (options.open) openBrowser(urlFor(choice.port));
62038
- sayIfOutdated(await latest);
62107
+ sayIfOutdated(latest);
62039
62108
  return;
62040
62109
  }
62041
62110
  const port = choice.port;
@@ -62047,7 +62116,7 @@ const main = async () => {
62047
62116
  say(`BaviTutor is running at ${url} (Ctrl+C to stop)`);
62048
62117
  say();
62049
62118
  if (options.open) openBrowser(url);
62050
- latest.then(sayIfOutdated);
62119
+ sayIfOutdated(latest);
62051
62120
  })).pipe(provide(makeServer({
62052
62121
  port,
62053
62122
  host,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bavitutor",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
4
4
  "description": "Describe what you want to learn; BaviTutor researches it, maps it and teaches it.",
5
5
  "keywords": [
6
6
  "claude",
@@ -24,13 +24,6 @@
24
24
  "assets/icon.svg"
25
25
  ],
26
26
  "type": "module",
27
- "scripts": {
28
- "dev": "vp run --filter \"./apps/*\" --parallel dev",
29
- "e2e": "vp run --filter @bavitutor/e2e e2e",
30
- "ready": "vp check && vp run -r test && vp run -r build",
31
- "prepare": "node scripts/prepare.ts",
32
- "prepack": "vp run build"
33
- },
34
27
  "dependencies": {
35
28
  "@anthropic-ai/claude-agent-sdk": "0.3.295",
36
29
  "playwright": "^1.64.0"
@@ -47,5 +40,10 @@
47
40
  },
48
41
  "engines": {
49
42
  "node": ">=24.0.0"
43
+ },
44
+ "scripts": {
45
+ "dev": "vp run --filter \"./apps/*\" --parallel dev",
46
+ "e2e": "vp run --filter @bavitutor/e2e e2e",
47
+ "ready": "vp check && vp run -r test && vp run -r build"
50
48
  }
51
- }
49
+ }