@pablopunk/tau 0.1.0 → 0.1.2
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/dist/bin.js +1 -1
- package/dist/latest-version-di9hD7cY.js +106 -0
- package/dist/machines-behind-BjGgmSs_.js +257 -0
- package/dist/{main-CI9q691u.js → main-R5EDx89w.js} +349 -229
- package/dist/{service-command-C7WDeeR2.js → manager-B_WHbb1U.js} +1 -33
- package/dist/real-deps-f96UmLBz.js +89 -0
- package/dist/serve-CuMzEud7.js +1 -0
- package/dist/{serve-92lMbcls.js → serve-Uc4Nin5f.js} +25 -51
- package/dist/service-command-C74K0saj.js +34 -0
- package/dist/service-command-DqcstJ8e.js +1 -0
- package/dist/{wait-for-lock-D2V3vuye.js → src-DO9LUlhi.js} +183 -46
- package/dist/wait-for-lock-B1Qx8GWg.js +1 -0
- package/dist/wait-for-lock-CrSl2mi1.js +25 -0
- package/dist/web/dist/assets/{index-7m0crRNF.css → index-D_Aa3Oou.css} +1 -1
- package/dist/web/dist/assets/index-vDvuOoR3.js +110 -0
- package/dist/web/dist/index.html +2 -2
- package/package.json +1 -1
- package/dist/serve-BcVZj5e2.js +0 -1
- package/dist/service-command-BVr33vlP.js +0 -1
- package/dist/wait-for-lock-BMk6v3J5.js +0 -1
- package/dist/web/dist/assets/index--f7AYPm0.js +0 -108
|
@@ -1,8 +1,6 @@
|
|
|
1
|
-
import { t as cliEntry } from "./cli-entry-DcDpQ30L.js";
|
|
2
1
|
import { existsSync, mkdirSync, readFileSync, readdirSync, rmSync, writeFileSync } from "node:fs";
|
|
3
2
|
import { delimiter, dirname, join, resolve } from "node:path";
|
|
4
3
|
import { homedir, release, userInfo } from "node:os";
|
|
5
|
-
import { parseArgs } from "node:util";
|
|
6
4
|
import { createHash } from "node:crypto";
|
|
7
5
|
import { spawn, spawnSync } from "node:child_process";
|
|
8
6
|
//#region src/service/entry-guard.ts
|
|
@@ -588,34 +586,4 @@ async function uninstallHome(context, home) {
|
|
|
588
586
|
}, home).uninstall();
|
|
589
587
|
}
|
|
590
588
|
//#endregion
|
|
591
|
-
|
|
592
|
-
const USAGE = "Usage: tau service install | uninstall [--home <path>] | list";
|
|
593
|
-
/** `tau service install | uninstall [--home <path>] | list`. `argv` starts after the word `service`. */
|
|
594
|
-
async function runServiceCommandWith(deps, argv) {
|
|
595
|
-
const { positionals, values } = parseArgs({
|
|
596
|
-
args: [...argv],
|
|
597
|
-
allowPositionals: true,
|
|
598
|
-
options: { home: { type: "string" } }
|
|
599
|
-
});
|
|
600
|
-
const home = values.home ?? deps.context.env.TAU_HOME ?? deps.context.defaultHome;
|
|
601
|
-
const [action] = positionals;
|
|
602
|
-
if (action === "install") {
|
|
603
|
-
const warnings = await createServiceManager(deps.context, cliEntry(), home).install();
|
|
604
|
-
for (const warning of warnings) deps.out(`warning: ${warning}`);
|
|
605
|
-
deps.out("tau service installed.");
|
|
606
|
-
} else if (action === "uninstall") {
|
|
607
|
-
await uninstallHome(deps.context, home);
|
|
608
|
-
deps.out("tau service removed.");
|
|
609
|
-
} else if (action === "list") {
|
|
610
|
-
const names = await listServices(deps.context);
|
|
611
|
-
deps.out(names.length === 0 ? "No tau services." : names.join("\n"));
|
|
612
|
-
} else throw new Error(USAGE);
|
|
613
|
-
}
|
|
614
|
-
async function runServiceCommand(argv) {
|
|
615
|
-
await runServiceCommandWith({
|
|
616
|
-
context: realContext(),
|
|
617
|
-
out: (message) => console.log(message)
|
|
618
|
-
}, argv);
|
|
619
|
-
}
|
|
620
|
-
//#endregion
|
|
621
|
-
export { TemporaryEntryError as a, realContext as i, runServiceCommandWith as n, createServiceManager as r, runServiceCommand as t };
|
|
589
|
+
export { TemporaryEntryError as a, realContext as i, listServices as n, uninstallHome as r, createServiceManager as t };
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { n as readRunningInstance } from "./src-DO9LUlhi.js";
|
|
2
|
+
import { a as realLifecycleDeps, d as discoverServer, l as processEnv, t as fetchLinkedMachines, u as callRoute } from "./machines-behind-BjGgmSs_.js";
|
|
3
|
+
import { i as spawnCommand, n as fetchLatestVersion } from "./latest-version-di9hD7cY.js";
|
|
4
|
+
import { existsSync, readFileSync, realpathSync } from "node:fs";
|
|
5
|
+
import { join } from "node:path";
|
|
6
|
+
import { createInterface } from "node:readline/promises";
|
|
7
|
+
//#region src/update/ancestors.ts
|
|
8
|
+
const MAX_DEPTH = 64;
|
|
9
|
+
/** Best effort (POSIX): the pids above this process, from `ps -o ppid= -p`. */
|
|
10
|
+
async function ancestorPidsOf(run, start = process.pid) {
|
|
11
|
+
const pids = [];
|
|
12
|
+
let current = start;
|
|
13
|
+
for (let depth = 0; depth < MAX_DEPTH; depth++) {
|
|
14
|
+
const result = await run("ps", [
|
|
15
|
+
"-o",
|
|
16
|
+
"ppid=",
|
|
17
|
+
"-p",
|
|
18
|
+
String(current)
|
|
19
|
+
], {
|
|
20
|
+
stdio: "capture",
|
|
21
|
+
timeoutMs: 5e3
|
|
22
|
+
});
|
|
23
|
+
const parent = Number(result.stdout.trim());
|
|
24
|
+
if (result.code !== 0 || !Number.isInteger(parent) || parent <= 1 || pids.includes(parent)) break;
|
|
25
|
+
pids.push(parent);
|
|
26
|
+
current = parent;
|
|
27
|
+
}
|
|
28
|
+
return pids;
|
|
29
|
+
}
|
|
30
|
+
//#endregion
|
|
31
|
+
//#region src/update/real-deps.ts
|
|
32
|
+
const POLL_MS = 500;
|
|
33
|
+
const POLL_DEADLINE_MS = 6e4;
|
|
34
|
+
async function pollForVersion(home, version) {
|
|
35
|
+
const deadline = Date.now() + POLL_DEADLINE_MS;
|
|
36
|
+
for (;;) {
|
|
37
|
+
const instance = await readRunningInstance(home);
|
|
38
|
+
if (instance?.version === version || Date.now() >= deadline) return instance;
|
|
39
|
+
await new Promise((resolve) => setTimeout(resolve, POLL_MS));
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
async function ask(question) {
|
|
43
|
+
const rl = createInterface({
|
|
44
|
+
input: process.stdin,
|
|
45
|
+
output: process.stdout
|
|
46
|
+
});
|
|
47
|
+
try {
|
|
48
|
+
return /^y(es)?$/i.test((await rl.question(`${question} [y/N] `)).trim());
|
|
49
|
+
} finally {
|
|
50
|
+
rl.close();
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
async function realUpdateDeps() {
|
|
54
|
+
const base = await realLifecycleDeps();
|
|
55
|
+
const entry = process.argv[1] === void 0 ? "" : realpathSync(process.argv[1]);
|
|
56
|
+
return {
|
|
57
|
+
...base,
|
|
58
|
+
err: (message) => console.error(message),
|
|
59
|
+
runCommand: spawnCommand,
|
|
60
|
+
latestVersion: () => fetchLatestVersion(spawnCommand, process.execPath),
|
|
61
|
+
listConversations: async (home) => {
|
|
62
|
+
const env = {
|
|
63
|
+
...processEnv(),
|
|
64
|
+
home
|
|
65
|
+
};
|
|
66
|
+
const server = await discoverServer(env);
|
|
67
|
+
return await callRoute(server, "listAllConversations", {}, env);
|
|
68
|
+
},
|
|
69
|
+
confirm: ask,
|
|
70
|
+
isTty: Boolean(process.stdin.isTTY && process.stdout.isTTY),
|
|
71
|
+
env: process.env,
|
|
72
|
+
execPath: process.execPath,
|
|
73
|
+
entry,
|
|
74
|
+
realpath: realpathSync,
|
|
75
|
+
readPackageVersion: (dir) => {
|
|
76
|
+
try {
|
|
77
|
+
return JSON.parse(readFileSync(join(dir, "package.json"), "utf8")).version;
|
|
78
|
+
} catch {
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
},
|
|
82
|
+
ancestorPids: process.platform === "win32" ? void 0 : () => ancestorPidsOf(spawnCommand),
|
|
83
|
+
pollInstance: pollForVersion,
|
|
84
|
+
hasHubFile: (home) => existsSync(join(home, "hub.json")),
|
|
85
|
+
linkedMachines: fetchLinkedMachines
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
//#endregion
|
|
89
|
+
export { realUpdateDeps };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { t as serveInForeground } from "./serve-Uc4Nin5f.js";
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import { $ as routes, A as changedFrame, C as LIVE_MAX_FRAME_BYTES, D as TERMINAL_STREAM_PATH, E as TERMINAL_STREAM_MAX_INPUT_BYTES, F as ERROR_STATUS, I as isAppError, J as LIVE_PATH, N as encodeFrame, O as TerminalClientFrameSchema, P as AppError, Q as iconCandidateUrl, R as toErrorBody, S as encodeDataFrame, T as TERMINAL_STREAM_CLOSE_UNKNOWN, X as PAIR_PAGE_PATH, Y as MESSAGE_BODY_LIMIT,
|
|
1
|
+
import { $ as routes, A as changedFrame, C as LIVE_MAX_FRAME_BYTES, D as TERMINAL_STREAM_PATH, E as TERMINAL_STREAM_MAX_INPUT_BYTES, F as ERROR_STATUS, I as isAppError, J as LIVE_PATH, N as encodeFrame, O as TerminalClientFrameSchema, P as AppError, Q as iconCandidateUrl, R as toErrorBody, S as encodeDataFrame, T as TERMINAL_STREAM_CLOSE_UNKNOWN, X as PAIR_PAGE_PATH, Y as MESSAGE_BODY_LIMIT, b as chunkBody, d as CHUNK_BYTES, et as HUB_LINK_NONE, f as CREDIT_WINDOW_BYTES, i as createExitMarker, j as decodeClientFrame, k as WS_MAX_PAYLOAD_BYTES, m as LINK_CLOSE_UPDATE_REQUIRED, n as readRunningInstance, p as LINK_CLOSE_NO_CREDIT, r as createCore, rt as RETIRED_OPS, t as publishServerUrl, tt as MACHINE_PROXY_PREFIX, u as PROTOCOL_VERSION, v as LinkFrameSchema, w as TERMINAL_STREAM_CLOSE_SLOW, x as decodeDataFrame, y as MACHINE_LINK_PATH } from "./src-DO9LUlhi.js";
|
|
2
|
+
import { n as waitForFreeHome } from "./wait-for-lock-CrSl2mi1.js";
|
|
3
|
+
import { a as cliVersion, c as writePrivateFile, i as spawnCommand, n as fetchLatestVersion, o as readOrCreateToken, s as ensurePrivateDirectory } from "./latest-version-di9hD7cY.js";
|
|
2
4
|
import { t as cliEntry } from "./cli-entry-DcDpQ30L.js";
|
|
3
5
|
import { Worker } from "node:worker_threads";
|
|
4
6
|
import { appendFileSync, existsSync, mkdirSync, readFileSync, renameSync, statSync, writeFileSync } from "node:fs";
|
|
@@ -6,8 +8,8 @@ import { dirname, join } from "node:path";
|
|
|
6
8
|
import { arch, homedir, hostname, platform } from "node:os";
|
|
7
9
|
import { fileURLToPath } from "node:url";
|
|
8
10
|
import { format, parseArgs } from "node:util";
|
|
9
|
-
import { createHash,
|
|
10
|
-
import {
|
|
11
|
+
import { createHash, timingSafeEqual } from "node:crypto";
|
|
12
|
+
import { readFile, rm } from "node:fs/promises";
|
|
11
13
|
import { Value } from "typebox/value";
|
|
12
14
|
import { createServer } from "node:net";
|
|
13
15
|
import { request } from "node:http";
|
|
@@ -67,23 +69,6 @@ function startWatchdog(options) {
|
|
|
67
69
|
} };
|
|
68
70
|
}
|
|
69
71
|
//#endregion
|
|
70
|
-
//#region src/private-files.ts
|
|
71
|
-
const PRIVATE_DIRECTORY_MODE = 448;
|
|
72
|
-
const PRIVATE_FILE_MODE = 384;
|
|
73
|
-
async function ensurePrivateDirectory(path) {
|
|
74
|
-
await mkdir(path, {
|
|
75
|
-
recursive: true,
|
|
76
|
-
mode: PRIVATE_DIRECTORY_MODE
|
|
77
|
-
});
|
|
78
|
-
}
|
|
79
|
-
/** Temp file, then rename, so readers never see a half-written file. */
|
|
80
|
-
async function writePrivateFile(path, content) {
|
|
81
|
-
await ensurePrivateDirectory(dirname(path));
|
|
82
|
-
const temporary = `${path}.${process.pid}.tmp`;
|
|
83
|
-
await writeFile(temporary, content, { mode: PRIVATE_FILE_MODE });
|
|
84
|
-
await rename(temporary, path);
|
|
85
|
-
}
|
|
86
|
-
//#endregion
|
|
87
72
|
//#region src/machines/hub-file.ts
|
|
88
73
|
const hubFilePath = (home) => join(home, "hub.json");
|
|
89
74
|
function isHubFile(value) {
|
|
@@ -106,33 +91,6 @@ function createHubFileStore(home) {
|
|
|
106
91
|
};
|
|
107
92
|
}
|
|
108
93
|
//#endregion
|
|
109
|
-
//#region src/token.ts
|
|
110
|
-
const TOKEN_BYTES = 32;
|
|
111
|
-
const MIN_TOKEN_LENGTH = 32;
|
|
112
|
-
const tokenPath = (home) => join(home, "token");
|
|
113
|
-
async function readExistingToken(home) {
|
|
114
|
-
try {
|
|
115
|
-
const token = (await readFile(tokenPath(home), "utf8")).trim();
|
|
116
|
-
return token.length >= MIN_TOKEN_LENGTH ? token : void 0;
|
|
117
|
-
} catch {
|
|
118
|
-
return;
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
/** The token outlives restarts so open browser tabs keep their cookie. */
|
|
122
|
-
async function readOrCreateToken(home) {
|
|
123
|
-
const existing = await readExistingToken(home);
|
|
124
|
-
if (existing) return existing;
|
|
125
|
-
const token = randomBytes(TOKEN_BYTES).toString("base64url");
|
|
126
|
-
await writePrivateFile(tokenPath(home), `${token}\n`);
|
|
127
|
-
return token;
|
|
128
|
-
}
|
|
129
|
-
//#endregion
|
|
130
|
-
//#region src/version.ts
|
|
131
|
-
/** From the `package.json` next to `src/` and next to `dist/`. */
|
|
132
|
-
function cliVersion() {
|
|
133
|
-
return JSON.parse(readFileSync(new URL("../package.json", import.meta.url), "utf8")).version;
|
|
134
|
-
}
|
|
135
|
-
//#endregion
|
|
136
94
|
//#region src/lifecycle/flags.ts
|
|
137
95
|
function portOf$1(raw) {
|
|
138
96
|
if (raw === void 0) return void 0;
|
|
@@ -1117,6 +1075,7 @@ const DENIED_FIRST_SEGMENTS = /* @__PURE__ */ new Set([
|
|
|
1117
1075
|
"access",
|
|
1118
1076
|
"remote",
|
|
1119
1077
|
"machines",
|
|
1078
|
+
"update",
|
|
1120
1079
|
"pair",
|
|
1121
1080
|
"health",
|
|
1122
1081
|
"m"
|
|
@@ -1666,6 +1625,8 @@ function startLoginFor(core, id) {
|
|
|
1666
1625
|
}
|
|
1667
1626
|
function registerRoutes(app, core, sockets) {
|
|
1668
1627
|
defineRoute(app, routes.suggestDirectories, ({ body }) => core.fs.suggestDirectories(body));
|
|
1628
|
+
defineRoute(app, routes.getUpdateStatus, () => core.updates.status());
|
|
1629
|
+
defineRoute(app, routes.refreshUpdateStatus, () => core.updates.refresh());
|
|
1669
1630
|
defineRoute(app, routes.getSettings, () => core.settings.get());
|
|
1670
1631
|
defineRoute(app, routes.setDefaultModel, ({ body }) => core.settings.setDefaultModel(body));
|
|
1671
1632
|
defineRoute(app, routes.setDefaultThinking, ({ body }) => core.settings.setDefaultThinkingLevel(body.thinkingLevel));
|
|
@@ -2816,6 +2777,17 @@ async function listenOnFreePort(preferred, start) {
|
|
|
2816
2777
|
throw new Error(`No free port between ${preferred} and ${last}`);
|
|
2817
2778
|
}
|
|
2818
2779
|
//#endregion
|
|
2780
|
+
//#region src/update/latest-source.ts
|
|
2781
|
+
/**
|
|
2782
|
+
* Where core learns the latest published version. `TAU_FAKE_LATEST` is a test hook (e2e): its value is the
|
|
2783
|
+
* answer, so no npm runs.
|
|
2784
|
+
*/
|
|
2785
|
+
function latestVersionSource(env = process.env) {
|
|
2786
|
+
const fake = env.TAU_FAKE_LATEST;
|
|
2787
|
+
if (fake) return async () => fake;
|
|
2788
|
+
return () => fetchLatestVersion(spawnCommand, process.execPath);
|
|
2789
|
+
}
|
|
2790
|
+
//#endregion
|
|
2819
2791
|
//#region src/run.ts
|
|
2820
2792
|
const withToken = (origin, token) => `${origin}/?token=${encodeURIComponent(token)}`;
|
|
2821
2793
|
async function reportExistingInstance(options, dependencies, token) {
|
|
@@ -2844,7 +2816,9 @@ async function run(options, dependencies) {
|
|
|
2844
2816
|
faux: options.faux,
|
|
2845
2817
|
cliEntry: dependencies.cliEntry,
|
|
2846
2818
|
tunnelTarget: tunnelTarget.get,
|
|
2847
|
-
forgetHub: () => hubFile.delete()
|
|
2819
|
+
forgetHub: () => hubFile.delete(),
|
|
2820
|
+
currentVersion: dependencies.version ?? "",
|
|
2821
|
+
latestVersion: dependencies.latestVersion ?? latestVersionSource()
|
|
2848
2822
|
});
|
|
2849
2823
|
try {
|
|
2850
2824
|
const server = await listenOnFreePort(options.port, (port) => dependencies.createServer({
|
|
@@ -2879,8 +2853,8 @@ async function run(options, dependencies) {
|
|
|
2879
2853
|
//#endregion
|
|
2880
2854
|
//#region src/static-dir.ts
|
|
2881
2855
|
const here = (relative) => fileURLToPath(new URL(relative, import.meta.url));
|
|
2882
|
-
/** Bundled (`dist/web` next to `dist/bin.js
|
|
2883
|
-
const CANDIDATES = [here("./web"), here("../../web/dist")];
|
|
2856
|
+
/** Bundled (`dist/web/dist` next to `dist/bin.js`, as tsdown copies the folder inside the target) or, when run from source, the sibling web package build. */
|
|
2857
|
+
const CANDIDATES = [here("./web/dist"), here("../../web/dist")];
|
|
2884
2858
|
function findStaticDir(candidates = CANDIDATES) {
|
|
2885
2859
|
return candidates.find((directory) => existsSync(join(directory, "index.html")));
|
|
2886
2860
|
}
|
|
@@ -2955,4 +2929,4 @@ async function serveInForeground(argv) {
|
|
|
2955
2929
|
}
|
|
2956
2930
|
}
|
|
2957
2931
|
//#endregion
|
|
2958
|
-
export { lifecycleFlagsOf as a,
|
|
2932
|
+
export { lifecycleFlagsOf as a, connectRefusal as c, commandWordOf as i, serverLogOf as n, createHubFileStore as o, writeStoredPort as r, alreadyLinkedRefusal as s, serveInForeground as t };
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { i as realContext, n as listServices, r as uninstallHome, t as createServiceManager } from "./manager-B_WHbb1U.js";
|
|
2
|
+
import { t as cliEntry } from "./cli-entry-DcDpQ30L.js";
|
|
3
|
+
import { parseArgs } from "node:util";
|
|
4
|
+
//#region src/service/service-command.ts
|
|
5
|
+
const USAGE = "Usage: tau service install | uninstall [--home <path>] | list";
|
|
6
|
+
/** `tau service install | uninstall [--home <path>] | list`. `argv` starts after the word `service`. */
|
|
7
|
+
async function runServiceCommandWith(deps, argv) {
|
|
8
|
+
const { positionals, values } = parseArgs({
|
|
9
|
+
args: [...argv],
|
|
10
|
+
allowPositionals: true,
|
|
11
|
+
options: { home: { type: "string" } }
|
|
12
|
+
});
|
|
13
|
+
const home = values.home ?? deps.context.env.TAU_HOME ?? deps.context.defaultHome;
|
|
14
|
+
const [action] = positionals;
|
|
15
|
+
if (action === "install") {
|
|
16
|
+
const warnings = await createServiceManager(deps.context, cliEntry(), home).install();
|
|
17
|
+
for (const warning of warnings) deps.out(`warning: ${warning}`);
|
|
18
|
+
deps.out("tau service installed.");
|
|
19
|
+
} else if (action === "uninstall") {
|
|
20
|
+
await uninstallHome(deps.context, home);
|
|
21
|
+
deps.out("tau service removed.");
|
|
22
|
+
} else if (action === "list") {
|
|
23
|
+
const names = await listServices(deps.context);
|
|
24
|
+
deps.out(names.length === 0 ? "No tau services." : names.join("\n"));
|
|
25
|
+
} else throw new Error(USAGE);
|
|
26
|
+
}
|
|
27
|
+
async function runServiceCommand(argv) {
|
|
28
|
+
await runServiceCommandWith({
|
|
29
|
+
context: realContext(),
|
|
30
|
+
out: (message) => console.log(message)
|
|
31
|
+
}, argv);
|
|
32
|
+
}
|
|
33
|
+
//#endregion
|
|
34
|
+
export { runServiceCommandWith as n, runServiceCommand as t };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { t as runServiceCommand } from "./service-command-C74K0saj.js";
|