trymeanwhile 1.1.0 → 1.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/bin/meanwhile.js +50 -0
- package/package.json +1 -1
package/bin/meanwhile.js
CHANGED
|
@@ -69,7 +69,57 @@ function wireSettings(settingsPath, python, scriptPath) {
|
|
|
69
69
|
log(`wired into ${settingsPath}`);
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
+
// Wraps any long-running shell command (npm install, docker build, terraform
|
|
73
|
+
// apply, ...) and shows the same disclosed line the Claude Code/Copilot
|
|
74
|
+
// status lines show -- reusing the exact same /line endpoint and billing
|
|
75
|
+
// mechanism, just from a different trigger than an editor hook. The server
|
|
76
|
+
// only bills a line if it stayed on screen >= BILLABLE_THRESHOLD (10s), so
|
|
77
|
+
// this polls every 15s -- fast enough to feel alive, slow enough that real
|
|
78
|
+
// polls actually bill instead of always resetting the timer on each other.
|
|
79
|
+
async function wrapCommand(args) {
|
|
80
|
+
const cmdArgs = args[0] === "--" ? args.slice(1) : args;
|
|
81
|
+
if (cmdArgs.length === 0) {
|
|
82
|
+
log("usage: npx trymeanwhile wrap -- <command> [args...]");
|
|
83
|
+
log("example: npx trymeanwhile wrap -- npm install");
|
|
84
|
+
process.exit(1);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
fs.mkdirSync(STATE_DIR, { recursive: true });
|
|
88
|
+
const idPath = path.join(STATE_DIR, "install_id");
|
|
89
|
+
if (!fs.existsSync(idPath)) {
|
|
90
|
+
fs.writeFileSync(idPath, crypto.randomUUID(), { mode: 0o600 });
|
|
91
|
+
}
|
|
92
|
+
const installId = fs.readFileSync(idPath, "utf8").trim();
|
|
93
|
+
|
|
94
|
+
const { spawn } = require("child_process");
|
|
95
|
+
const child = spawn(cmdArgs[0], cmdArgs.slice(1), { stdio: "inherit", shell: process.platform === "win32" });
|
|
96
|
+
|
|
97
|
+
let stopped = false;
|
|
98
|
+
(async function pollLoop() {
|
|
99
|
+
while (!stopped) {
|
|
100
|
+
try {
|
|
101
|
+
const res = await fetch(`${SERVER}/line?id=${installId}&event=cli_wrap`);
|
|
102
|
+
if (res.ok) {
|
|
103
|
+
const data = await res.json();
|
|
104
|
+
process.stderr.write(`\nmeanwhile: ${data.line}\n`);
|
|
105
|
+
}
|
|
106
|
+
} catch (e) {}
|
|
107
|
+
await new Promise((r) => setTimeout(r, 15000));
|
|
108
|
+
}
|
|
109
|
+
})();
|
|
110
|
+
|
|
111
|
+
child.on("exit", (code) => {
|
|
112
|
+
stopped = true;
|
|
113
|
+
process.exit(code === null ? 1 : code);
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
|
|
72
117
|
async function main() {
|
|
118
|
+
if (process.argv[2] === "wrap") {
|
|
119
|
+
await wrapCommand(process.argv.slice(3));
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
|
|
73
123
|
log(`installing to ${INSTALL_DIR}`);
|
|
74
124
|
fs.mkdirSync(INSTALL_DIR, { recursive: true });
|
|
75
125
|
fs.mkdirSync(STATE_DIR, { recursive: true });
|
package/package.json
CHANGED