@devness/useai-cli 0.8.8 → 0.8.9
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/index.js +130 -32
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -30,7 +30,7 @@ var SYSTEMD_SERVICE_PATH = join(homedir(), ".config", "systemd", "user", "useai-
|
|
|
30
30
|
var WINDOWS_STARTUP_SCRIPT_PATH = join(process.env["APPDATA"] ?? join(homedir(), "AppData", "Roaming"), "Microsoft", "Windows", "Start Menu", "Programs", "Startup", "useai-daemon.vbs");
|
|
31
31
|
|
|
32
32
|
// ../shared/dist/constants/version.js
|
|
33
|
-
var VERSION = "0.8.
|
|
33
|
+
var VERSION = "0.8.9";
|
|
34
34
|
|
|
35
35
|
// ../shared/dist/constants/defaults.js
|
|
36
36
|
var DEFAULT_CAPTURE_CONFIG = {
|
|
@@ -41,7 +41,7 @@ var DEFAULT_CAPTURE_CONFIG = {
|
|
|
41
41
|
milestones: true
|
|
42
42
|
};
|
|
43
43
|
var DEFAULT_SYNC_CONFIG = {
|
|
44
|
-
enabled:
|
|
44
|
+
enabled: false,
|
|
45
45
|
interval_hours: 1
|
|
46
46
|
};
|
|
47
47
|
var DEFAULT_CONFIG = {
|
|
@@ -234,6 +234,9 @@ function migrateConfig(raw) {
|
|
|
234
234
|
};
|
|
235
235
|
}
|
|
236
236
|
delete config.sync.include;
|
|
237
|
+
if (config.sync.enabled && !config.auth?.token) {
|
|
238
|
+
config.sync.enabled = false;
|
|
239
|
+
}
|
|
237
240
|
if (!config.evaluation_framework) {
|
|
238
241
|
config.evaluation_framework = "space";
|
|
239
242
|
}
|
|
@@ -360,6 +363,11 @@ import { Command as Command2 } from "commander";
|
|
|
360
363
|
import { existsSync as existsSync2, statSync, readdirSync } from "fs";
|
|
361
364
|
import pc3 from "picocolors";
|
|
362
365
|
|
|
366
|
+
// ../shared/dist/types/config.js
|
|
367
|
+
function getUserMode(config) {
|
|
368
|
+
return config.auth?.token ? "cloud" : "local";
|
|
369
|
+
}
|
|
370
|
+
|
|
363
371
|
// src/services/config.service.ts
|
|
364
372
|
function getConfig() {
|
|
365
373
|
const raw = readJson(CONFIG_FILE, {});
|
|
@@ -418,15 +426,17 @@ var statusCommand = new Command2("status").description("Full transparency dashbo
|
|
|
418
426
|
])
|
|
419
427
|
);
|
|
420
428
|
console.log(header("Settings"));
|
|
429
|
+
const mode = getUserMode(config);
|
|
430
|
+
const modeDisplay = mode === "cloud" ? pc3.green("Cloud") + pc3.dim(` \xB7 @${config.auth.user.username ?? config.auth.user.email}`) : pc3.cyan("Local");
|
|
421
431
|
console.log(
|
|
422
432
|
table([
|
|
433
|
+
["Mode", modeDisplay],
|
|
423
434
|
["Milestone tracking", config.capture.milestones ? pc3.green("on") : pc3.red("off")],
|
|
424
435
|
["Prompt capture", config.capture.prompt ? pc3.green("on") : pc3.red("off")],
|
|
425
436
|
["Eval reasons", config.capture.evaluation_reasons],
|
|
426
437
|
["Cloud sync", config.sync.enabled ? pc3.green("on") : pc3.red("off")],
|
|
427
438
|
["Sync interval", `${config.sync.interval_hours}h`],
|
|
428
|
-
["Last sync", config.last_sync_at ?? pc3.dim("never")]
|
|
429
|
-
["Logged in", config.auth ? pc3.green(config.auth.user.email) : pc3.dim("no")]
|
|
439
|
+
["Last sync", config.last_sync_at ?? pc3.dim("never")]
|
|
430
440
|
])
|
|
431
441
|
);
|
|
432
442
|
console.log(header("Privacy"));
|
|
@@ -6245,17 +6255,19 @@ var configCommand = new Command4("config").description("View or update settings"
|
|
|
6245
6255
|
}
|
|
6246
6256
|
const config = getConfig();
|
|
6247
6257
|
if (!changed) {
|
|
6258
|
+
const mode = getUserMode(config);
|
|
6259
|
+
const modeDisplay = mode === "cloud" ? pc5.green("Cloud") + pc5.dim(` \xB7 @${config.auth.user.username ?? config.auth.user.email}`) : pc5.cyan("Local");
|
|
6248
6260
|
console.log(header("Current Settings"));
|
|
6249
6261
|
console.log(
|
|
6250
6262
|
table([
|
|
6263
|
+
["Mode", modeDisplay],
|
|
6251
6264
|
["Milestone tracking", config.capture.milestones ? pc5.green("on") : pc5.red("off")],
|
|
6252
6265
|
["Prompt capture", config.capture.prompt ? pc5.green("on") : pc5.red("off")],
|
|
6253
6266
|
["Eval reasons", config.capture.evaluation_reasons],
|
|
6254
6267
|
["Cloud sync", config.sync.enabled ? pc5.green("on") : pc5.red("off")],
|
|
6255
6268
|
["Eval framework", pc5.cyan(config.evaluation_framework ?? "space")],
|
|
6256
6269
|
["Sync interval", `${config.sync.interval_hours}h`],
|
|
6257
|
-
["Last sync", config.last_sync_at ?? pc5.dim("never")]
|
|
6258
|
-
["Logged in", config.auth ? pc5.green(config.auth.user.email) : pc5.dim("no")]
|
|
6270
|
+
["Last sync", config.last_sync_at ?? pc5.dim("never")]
|
|
6259
6271
|
])
|
|
6260
6272
|
);
|
|
6261
6273
|
console.log("");
|
|
@@ -6820,11 +6832,80 @@ async function apiCall(endpoint, body) {
|
|
|
6820
6832
|
}
|
|
6821
6833
|
return data;
|
|
6822
6834
|
}
|
|
6823
|
-
|
|
6835
|
+
async function apiGet(endpoint, token) {
|
|
6836
|
+
const res = await fetch(`${API_URL}${endpoint}`, {
|
|
6837
|
+
headers: { Authorization: `Bearer ${token}` }
|
|
6838
|
+
});
|
|
6839
|
+
const data = await res.json();
|
|
6840
|
+
if (!res.ok) {
|
|
6841
|
+
throw new Error(data.message ?? `Request failed (${res.status})`);
|
|
6842
|
+
}
|
|
6843
|
+
return data;
|
|
6844
|
+
}
|
|
6845
|
+
async function apiPatch(endpoint, token, body) {
|
|
6846
|
+
const res = await fetch(`${API_URL}${endpoint}`, {
|
|
6847
|
+
method: "PATCH",
|
|
6848
|
+
headers: {
|
|
6849
|
+
"Content-Type": "application/json",
|
|
6850
|
+
Authorization: `Bearer ${token}`
|
|
6851
|
+
},
|
|
6852
|
+
body: JSON.stringify(body)
|
|
6853
|
+
});
|
|
6854
|
+
const data = await res.json();
|
|
6855
|
+
if (!res.ok) {
|
|
6856
|
+
throw new Error(data.message ?? `Request failed (${res.status})`);
|
|
6857
|
+
}
|
|
6858
|
+
return data;
|
|
6859
|
+
}
|
|
6860
|
+
function validateUsernameFormat(username) {
|
|
6861
|
+
if (username.length < 3) return "Username must be at least 3 characters";
|
|
6862
|
+
if (username.length > 20) return "Username must be at most 20 characters";
|
|
6863
|
+
if (!/^[a-z0-9][a-z0-9-]*[a-z0-9]$/.test(username) && username.length >= 3) {
|
|
6864
|
+
return "Only lowercase letters, numbers, and hyphens (not at start/end)";
|
|
6865
|
+
}
|
|
6866
|
+
if (/--/.test(username)) return "No consecutive hyphens";
|
|
6867
|
+
return void 0;
|
|
6868
|
+
}
|
|
6869
|
+
async function claimUsername(token) {
|
|
6870
|
+
while (true) {
|
|
6871
|
+
const usernameResult = await p2.text({
|
|
6872
|
+
message: "Choose a username:",
|
|
6873
|
+
placeholder: "e.g. fastdev",
|
|
6874
|
+
validate: (v) => {
|
|
6875
|
+
if (!v) return "Username is required";
|
|
6876
|
+
return validateUsernameFormat(v);
|
|
6877
|
+
}
|
|
6878
|
+
});
|
|
6879
|
+
if (p2.isCancel(usernameResult)) {
|
|
6880
|
+
return void 0;
|
|
6881
|
+
}
|
|
6882
|
+
const username = usernameResult.toLowerCase();
|
|
6883
|
+
try {
|
|
6884
|
+
const check = await apiGet(`/api/users/check-username/${encodeURIComponent(username)}`, token);
|
|
6885
|
+
if (!check.available) {
|
|
6886
|
+
console.log(pc9.yellow(` "${username}" is not available${check.reason ? `: ${check.reason}` : ""}. Try another.`));
|
|
6887
|
+
continue;
|
|
6888
|
+
}
|
|
6889
|
+
} catch {
|
|
6890
|
+
console.log(pc9.yellow(" Could not verify availability. Try again."));
|
|
6891
|
+
continue;
|
|
6892
|
+
}
|
|
6893
|
+
try {
|
|
6894
|
+
await apiPatch("/api/users/me", token, { username });
|
|
6895
|
+
return username;
|
|
6896
|
+
} catch (err) {
|
|
6897
|
+
console.log(pc9.yellow(` Could not claim "${username}": ${err.message}. Try another.`));
|
|
6898
|
+
continue;
|
|
6899
|
+
}
|
|
6900
|
+
}
|
|
6901
|
+
}
|
|
6902
|
+
var loginCommand = new Command10("login").description("Login to useai.dev and enable Cloud Mode").action(async () => {
|
|
6824
6903
|
try {
|
|
6825
6904
|
const config = getConfig();
|
|
6826
6905
|
if (config.auth?.token) {
|
|
6827
|
-
|
|
6906
|
+
const mode = pc9.green("Cloud Mode");
|
|
6907
|
+
const user = config.auth.user.username ? `@${config.auth.user.username}` : config.auth.user.email;
|
|
6908
|
+
console.log(pc9.dim(` Already logged in as ${pc9.bold(user)} (${mode})`));
|
|
6828
6909
|
console.log(pc9.dim(" Run `useai logout` to switch accounts."));
|
|
6829
6910
|
return;
|
|
6830
6911
|
}
|
|
@@ -6851,8 +6932,8 @@ var loginCommand = new Command10("login").description("Login to useai.dev").acti
|
|
|
6851
6932
|
console.log("");
|
|
6852
6933
|
let attempts = 0;
|
|
6853
6934
|
const maxAttempts = 3;
|
|
6854
|
-
let
|
|
6855
|
-
while (attempts < maxAttempts && !
|
|
6935
|
+
let verifyResult = null;
|
|
6936
|
+
while (attempts < maxAttempts && !verifyResult) {
|
|
6856
6937
|
const codeResult = await p2.text({
|
|
6857
6938
|
message: 'Enter 6-digit code (or "resend"):',
|
|
6858
6939
|
validate: (v) => {
|
|
@@ -6884,24 +6965,7 @@ var loginCommand = new Command10("login").description("Login to useai.dev").acti
|
|
|
6884
6965
|
try {
|
|
6885
6966
|
const result = await apiCall("/api/auth/verify-otp", { email, code });
|
|
6886
6967
|
if (result?.token) {
|
|
6887
|
-
|
|
6888
|
-
auth: {
|
|
6889
|
-
token: result.token,
|
|
6890
|
-
user: {
|
|
6891
|
-
id: result.user.id,
|
|
6892
|
-
email: result.user.email,
|
|
6893
|
-
username: result.user.username
|
|
6894
|
-
}
|
|
6895
|
-
}
|
|
6896
|
-
});
|
|
6897
|
-
console.log("");
|
|
6898
|
-
console.log(pc9.green(` \u2713 Logged in as ${pc9.bold(result.user.email)}`));
|
|
6899
|
-
if (result.user.username) {
|
|
6900
|
-
console.log(pc9.dim(` username: ${result.user.username}`));
|
|
6901
|
-
}
|
|
6902
|
-
console.log("");
|
|
6903
|
-
console.log(pc9.dim(" Your sessions and milestones will sync to useai.dev"));
|
|
6904
|
-
success2 = true;
|
|
6968
|
+
verifyResult = result;
|
|
6905
6969
|
}
|
|
6906
6970
|
} catch (err) {
|
|
6907
6971
|
attempts++;
|
|
@@ -6928,9 +6992,39 @@ var loginCommand = new Command10("login").description("Login to useai.dev").acti
|
|
|
6928
6992
|
}
|
|
6929
6993
|
}
|
|
6930
6994
|
}
|
|
6931
|
-
if (!
|
|
6995
|
+
if (!verifyResult) {
|
|
6932
6996
|
console.log(pc9.red(" Login failed. Please try again."));
|
|
6997
|
+
return;
|
|
6933
6998
|
}
|
|
6999
|
+
let username = verifyResult.user.username;
|
|
7000
|
+
if (!username) {
|
|
7001
|
+
console.log("");
|
|
7002
|
+
console.log(pc9.green(` \u2713 Authenticated as ${pc9.bold(email)}`));
|
|
7003
|
+
console.log("");
|
|
7004
|
+
username = await claimUsername(verifyResult.token);
|
|
7005
|
+
if (!username) {
|
|
7006
|
+
console.log(pc9.dim("\n Login cancelled \u2014 username is required for Cloud Mode."));
|
|
7007
|
+
return;
|
|
7008
|
+
}
|
|
7009
|
+
console.log(pc9.green(` \u2713 Username claimed: @${username}`));
|
|
7010
|
+
}
|
|
7011
|
+
updateConfig({
|
|
7012
|
+
auth: {
|
|
7013
|
+
token: verifyResult.token,
|
|
7014
|
+
user: {
|
|
7015
|
+
id: verifyResult.user.id,
|
|
7016
|
+
email: verifyResult.user.email,
|
|
7017
|
+
username
|
|
7018
|
+
}
|
|
7019
|
+
},
|
|
7020
|
+
sync: { enabled: true, interval_hours: config.sync.interval_hours }
|
|
7021
|
+
});
|
|
7022
|
+
console.log("");
|
|
7023
|
+
console.log(pc9.green(` \u2713 Cloud Mode enabled`));
|
|
7024
|
+
console.log(pc9.dim(` Logged in as ${pc9.bold(`@${username}`)} (${email})`));
|
|
7025
|
+
console.log(pc9.dim(` Sessions sync hourly \u2014 prompts stay local`));
|
|
7026
|
+
console.log(pc9.dim(` Profile: useai.dev/@${username}`));
|
|
7027
|
+
console.log("");
|
|
6934
7028
|
} catch (err) {
|
|
6935
7029
|
if (err.name === "ExitPromptError" || err.message?.includes("force closed")) {
|
|
6936
7030
|
console.log("");
|
|
@@ -6940,15 +7034,19 @@ var loginCommand = new Command10("login").description("Login to useai.dev").acti
|
|
|
6940
7034
|
console.log(pc9.red(` Login failed: ${err.message}`));
|
|
6941
7035
|
}
|
|
6942
7036
|
});
|
|
6943
|
-
var logoutCommand = new Command10("logout").description("Logout
|
|
7037
|
+
var logoutCommand = new Command10("logout").description("Logout and return to Local Mode").action(() => {
|
|
6944
7038
|
const config = getConfig();
|
|
6945
7039
|
if (!config.auth) {
|
|
6946
|
-
console.log(pc9.dim(" Not logged in."));
|
|
7040
|
+
console.log(pc9.dim(" Not logged in \u2014 already in Local Mode."));
|
|
6947
7041
|
return;
|
|
6948
7042
|
}
|
|
6949
7043
|
const email = config.auth.user.email;
|
|
6950
|
-
updateConfig({
|
|
7044
|
+
updateConfig({
|
|
7045
|
+
auth: void 0,
|
|
7046
|
+
sync: { enabled: false, interval_hours: config.sync.interval_hours }
|
|
7047
|
+
});
|
|
6951
7048
|
console.log(pc9.green(` \u2713 Logged out from ${email}`));
|
|
7049
|
+
console.log(pc9.dim(" Local Mode \u2014 your data stays on this device."));
|
|
6952
7050
|
});
|
|
6953
7051
|
|
|
6954
7052
|
// src/commands/update.ts
|