threadnote 0.4.0 → 0.4.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.
@@ -9163,6 +9163,8 @@ var import_node_fs5 = require("node:fs");
9163
9163
  var import_promises9 = require("node:fs/promises");
9164
9164
  var import_node_os6 = require("node:os");
9165
9165
  var import_node_path8 = require("node:path");
9166
+ var import_node_process2 = require("node:process");
9167
+ var import_promises10 = require("node:readline/promises");
9166
9168
 
9167
9169
  // src/update.ts
9168
9170
  var import_node_fs4 = require("node:fs");
@@ -10110,11 +10112,83 @@ async function waitForOpenVikingHealth(config, timeoutMs) {
10110
10112
  return void 0;
10111
10113
  }
10112
10114
  async function runInstallCommands(config, preferred, force, dryRun) {
10113
- const installCommands = await getInstallCommands(config, preferred, force);
10115
+ let manager = preferred;
10116
+ if (manager === void 0 && !dryRun) {
10117
+ const detected = await detectPackageManager();
10118
+ if (detected === "pip" && await offerToInstallUv()) {
10119
+ const rediscovered = await detectPackageManager();
10120
+ if (rediscovered === "uv") {
10121
+ manager = "uv";
10122
+ }
10123
+ }
10124
+ }
10125
+ const installCommands = await getInstallCommands(config, manager, force);
10114
10126
  for (const installCommand of installCommands) {
10115
10127
  await maybeRun(dryRun, installCommand.executable, installCommand.args);
10116
10128
  }
10117
10129
  }
10130
+ async function offerToInstallUv() {
10131
+ if (import_node_process2.stdin.isTTY !== true || import_node_process2.stdout.isTTY !== true) {
10132
+ console.warn(
10133
+ "Neither uv nor pipx was found on PATH. Falling back to `python3 -m pip install --user`, which fails on PEP 668 (Homebrew/system) Python.\nRe-run with --package-manager uv after installing uv (brew install uv), or pass --package-manager pipx."
10134
+ );
10135
+ return false;
10136
+ }
10137
+ const readline = (0, import_promises10.createInterface)({ input: import_node_process2.stdin, output: import_node_process2.stdout });
10138
+ let answer;
10139
+ try {
10140
+ answer = (await readline.question(
10141
+ "OpenViking installs into Python; neither uv nor pipx is on PATH so threadnote would fall back to `pip install --user`, which fails on PEP 668 setups.\nInstall uv now? [Y/n] "
10142
+ )).trim().toLowerCase();
10143
+ } finally {
10144
+ readline.close();
10145
+ }
10146
+ if (answer === "n" || answer === "no") {
10147
+ console.log("Continuing with `python3 -m pip install --user`. You may hit PEP 668 errors on managed Pythons.");
10148
+ return false;
10149
+ }
10150
+ return await installUv();
10151
+ }
10152
+ async function installUv() {
10153
+ const brew = await findExecutable(["brew"]);
10154
+ if (brew) {
10155
+ console.log("Installing uv via Homebrew...");
10156
+ const result = await runCommand(brew, ["install", "uv"], { allowFailure: true });
10157
+ if (result.exitCode === 0) {
10158
+ if (result.stdout.trim()) {
10159
+ console.log(result.stdout.trim());
10160
+ }
10161
+ if (await findExecutable(["uv"])) {
10162
+ return true;
10163
+ }
10164
+ } else {
10165
+ console.warn(`brew install uv failed: ${(result.stderr || result.stdout).trim()}`);
10166
+ }
10167
+ }
10168
+ if (await findExecutable(["curl"]) && await findExecutable(["sh"])) {
10169
+ console.log("Installing uv via the official install script (curl -LsSf https://astral.sh/uv/install.sh | sh)...");
10170
+ const result = await runCommand("sh", ["-c", "curl -LsSf https://astral.sh/uv/install.sh | sh"], {
10171
+ allowFailure: true
10172
+ });
10173
+ if (result.exitCode === 0) {
10174
+ if (result.stdout.trim()) {
10175
+ console.log(result.stdout.trim());
10176
+ }
10177
+ if (await findExecutable(["uv"])) {
10178
+ return true;
10179
+ }
10180
+ console.warn(
10181
+ "uv installed, but the new binary is not yet on this shell PATH. Open a new shell (or `source ~/.zshrc` / `source ~/.bashrc`) and re-run `threadnote install`."
10182
+ );
10183
+ return false;
10184
+ }
10185
+ console.warn(`uv install script failed: ${(result.stderr || result.stdout).trim()}`);
10186
+ }
10187
+ console.warn(
10188
+ "Could not install uv automatically. Install it manually (brew install uv) and re-run threadnote install."
10189
+ );
10190
+ return false;
10191
+ }
10118
10192
  async function getPythonSystemCertificatesInstallCommand(serverPath) {
10119
10193
  const pythonPath = await siblingPythonForExecutable(serverPath);
10120
10194
  if (!pythonPath) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "threadnote",
3
- "version": "0.4.0",
3
+ "version": "0.4.1",
4
4
  "type": "commonjs",
5
5
  "main": "dist/threadnote.cjs",
6
6
  "description": "Shared local context and handoffs for development agents",