trymeanwhile 1.2.0 → 1.2.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.
Files changed (2) hide show
  1. package/bin/meanwhile.js +22 -45
  2. package/package.json +1 -1
package/bin/meanwhile.js CHANGED
@@ -1,10 +1,9 @@
1
1
  #!/usr/bin/env node
2
- // Node reimplementation of install.sh/install.ps1/install_copilot.sh -- one
3
- // script instead of three, since Node itself is already cross-platform and
4
- // can detect which tool(s) are actually installed. Behavior is kept in
5
- // lockstep with those scripts (same install dir, same settings.json shape,
6
- // same non-fatal certifi step) so every installer produces an identical
7
- // result regardless of which one someone happens to run.
2
+ // The `npx trymeanwhile` entry point -- one cross-platform script that
3
+ // detects which tool(s) are actually installed and wires them up. The
4
+ // status line it wires in (statusline.js) runs on Node too, not Python:
5
+ // Node is already guaranteed present since npx can't invoke this script
6
+ // without it, so there's no second runtime to find, verify, or fail on.
8
7
 
9
8
  const fs = require("fs");
10
9
  const os = require("os");
@@ -24,13 +23,6 @@ function commandExists(cmd) {
24
23
  return spawnSync(cmd, ["--version"], { stdio: "ignore" }).status === 0;
25
24
  }
26
25
 
27
- function findPython() {
28
- for (const candidate of ["python3", "python", "py"]) {
29
- if (commandExists(candidate)) return candidate;
30
- }
31
- return null;
32
- }
33
-
34
26
  function openUrl(url) {
35
27
  const cmd =
36
28
  process.platform === "darwin" ? `open "${url}"`
@@ -39,32 +31,16 @@ function openUrl(url) {
39
31
  exec(cmd, () => {});
40
32
  }
41
33
 
42
- async function ensureCertifi(python) {
43
- const hasCertifi = spawnSync(python, ["-c", "import certifi"], { stdio: "ignore" }).status === 0;
44
- if (hasCertifi) return;
45
- // certifi is a nice-to-have, not a hard requirement -- both status line
46
- // scripts fall back to the system's own certificate store if it's
47
- // missing. Never let a failed pip install here take down the install.
48
- log("installing certifi (helps with HTTPS, not required)...");
49
- const pipAttempts = [
50
- ["-m", "pip", "install", "--quiet", "certifi"],
51
- ["-m", "pip", "install", "--quiet", "--user", "certifi"],
52
- ["-m", "pip", "install", "--quiet", "--break-system-packages", "certifi"],
53
- ];
54
- const installed = pipAttempts.some((args) => spawnSync(python, args, { stdio: "ignore" }).status === 0);
55
- if (!installed) log("couldn't install certifi, continuing without it (falls back automatically)");
56
- }
57
-
58
34
  async function downloadTo(remoteName, localPath) {
59
35
  const res = await fetch(`${SERVER}/${remoteName}`);
60
36
  if (!res.ok) throw new Error(`couldn't download ${remoteName} (${res.status})`);
61
37
  fs.writeFileSync(localPath, await res.text());
62
38
  }
63
39
 
64
- function wireSettings(settingsPath, python, scriptPath) {
40
+ function wireSettings(settingsPath, runtime, scriptPath) {
65
41
  fs.mkdirSync(path.dirname(settingsPath), { recursive: true });
66
42
  const settings = fs.existsSync(settingsPath) ? JSON.parse(fs.readFileSync(settingsPath, "utf8") || "{}") : {};
67
- settings.statusLine = { type: "command", command: `${python} "${scriptPath}"` };
43
+ settings.statusLine = { type: "command", command: `"${runtime}" "${scriptPath}"` };
68
44
  fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + "\n");
69
45
  log(`wired into ${settingsPath}`);
70
46
  }
@@ -135,13 +111,14 @@ async function main() {
135
111
  }
136
112
  const installId = fs.readFileSync(idPath, "utf8").trim();
137
113
 
138
- const python = findPython();
139
- if (!python) {
140
- log("couldn't find Python on your PATH.");
141
- log("install it from https://python.org, then run `npx trymeanwhile` again.");
142
- process.exit(1);
143
- }
144
- await ensureCertifi(python);
114
+ // Node, not Python: this script is already running under Node (it can't
115
+ // not be -- npx just invoked it), so there is no second runtime to find
116
+ // or verify. process.execPath is the absolute path to the exact node
117
+ // binary running right now, more robust than trusting a bare `node` on
118
+ // PATH (some distros only ship `nodejs`). This used to hard-require
119
+ // python3/python/py on top of Node and fail the whole install for
120
+ // anyone without it -- a real dead stop, not a cosmetic gap.
121
+ const node = process.execPath;
145
122
 
146
123
  // Wire whichever tool(s) are actually on this machine, so the same
147
124
  // command works everywhere instead of a different one per tool. Claude
@@ -149,20 +126,20 @@ async function main() {
149
126
  // built for -- and Copilot CLI is wired too if it's detected on PATH.
150
127
  const wireCopilot = commandExists("copilot");
151
128
 
152
- const claudeScript = path.join(INSTALL_DIR, "statusline.py");
153
- await downloadTo("statusline.py", claudeScript);
154
- wireSettings(path.join(os.homedir(), ".claude", "settings.json"), python, claudeScript);
129
+ const claudeScript = path.join(INSTALL_DIR, "statusline.js");
130
+ await downloadTo("statusline.js", claudeScript);
131
+ wireSettings(path.join(os.homedir(), ".claude", "settings.json"), node, claudeScript);
155
132
 
156
133
  if (wireCopilot) {
157
- const copilotScript = path.join(INSTALL_DIR, "copilot_statusline.py");
158
- await downloadTo("copilot_statusline.py", copilotScript);
159
- wireSettings(path.join(os.homedir(), ".copilot", "settings.json"), python, copilotScript);
134
+ const copilotScript = path.join(INSTALL_DIR, "copilot_statusline.js");
135
+ await downloadTo("copilot_statusline.js", copilotScript);
136
+ wireSettings(path.join(os.homedir(), ".copilot", "settings.json"), node, copilotScript);
160
137
  log("Copilot CLI detected -- wired that too, same install ID, earnings share one balance.");
161
138
  }
162
139
 
163
140
  log("installed. Restart Claude Code (and Copilot CLI, if wired) to see it live.");
164
141
  log("to check earnings or register a payout email later, run:");
165
- log(` ${python} "${claudeScript}" --claim`);
142
+ log(` "${node}" "${claudeScript}" --claim`);
166
143
 
167
144
  // Open the browser straight to the claim page -- same pattern as
168
145
  // `gh auth login` / `vercel login` / `wrangler login`. This is the only
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "trymeanwhile",
3
- "version": "1.2.0",
3
+ "version": "1.2.1",
4
4
  "description": "Get paid while your AI coding agent thinks. Wires a disclosed status line into Claude Code / Copilot CLI.",
5
5
  "bin": {
6
6
  "meanwhile": "bin/meanwhile.js"