hocai-connect 0.18.0 → 0.18.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/cli.js +241 -68
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -42302,6 +42302,27 @@ var ReorderPlatformSchema = external_exports.object({
|
|
|
42302
42302
|
});
|
|
42303
42303
|
var SetPlatformActiveSchema = external_exports.object({ active: external_exports.boolean() });
|
|
42304
42304
|
|
|
42305
|
+
// packages/types/project.ts
|
|
42306
|
+
var ProjectAgentSchema = external_exports.enum(["auto", "claude", "codex"]);
|
|
42307
|
+
var ProjectFolderRoleSchema = external_exports.enum(["SOURCE", "ASSIGNMENTS", "WORK"]);
|
|
42308
|
+
var ProjectBaseSchema = external_exports.object({
|
|
42309
|
+
name: external_exports.string().trim().min(1, "\u0110\u1EB7t t\xEAn cho d\u1EF1 \xE1n").max(120, "T\xEAn d\u1EF1 \xE1n qu\xE1 d\xE0i"),
|
|
42310
|
+
description: external_exports.string().trim().max(1e3, "M\xF4 t\u1EA3 t\u1ED1i \u0111a 1000 k\xFD t\u1EF1").optional(),
|
|
42311
|
+
defaultAgent: ProjectAgentSchema.default("auto")
|
|
42312
|
+
});
|
|
42313
|
+
var UpdateProjectSchema = ProjectBaseSchema.partial();
|
|
42314
|
+
var ProjectFilterSchema = external_exports.object({
|
|
42315
|
+
page: external_exports.coerce.number().int().min(1).default(1),
|
|
42316
|
+
perPage: external_exports.coerce.number().int().min(1).max(100).default(24),
|
|
42317
|
+
q: external_exports.string().trim().max(80).optional(),
|
|
42318
|
+
sort: external_exports.string().max(30).optional(),
|
|
42319
|
+
dir: external_exports.enum(["asc", "desc"]).optional()
|
|
42320
|
+
});
|
|
42321
|
+
var AttachProjectFolderSchema = external_exports.object({
|
|
42322
|
+
folderId: external_exports.string().min(1, "Ch\u1ECDn m\u1ED9t th\u01B0 m\u1EE5c"),
|
|
42323
|
+
role: ProjectFolderRoleSchema
|
|
42324
|
+
});
|
|
42325
|
+
|
|
42305
42326
|
// packages/types/machine.ts
|
|
42306
42327
|
var TerminalJobStatusSchema = external_exports.enum(["DONE", "FAILED", "CANCELLED"]);
|
|
42307
42328
|
var JobLineSchema = external_exports.object({ seq: external_exports.number().int().positive().max(Number.MAX_SAFE_INTEGER), line: external_exports.string().max(1024 * 1024) });
|
|
@@ -42319,6 +42340,8 @@ function terminalJobStatus(line) {
|
|
|
42319
42340
|
var CreateRemoteJobSchema = external_exports.object({
|
|
42320
42341
|
/** MÃ thư mục đã đăng ký, KHÔNG phải đường dẫn — xem apps/mcp/src/folder.ts. */
|
|
42321
42342
|
folderId: external_exports.string().min(1, "Ch\u1ECDn m\u1ED9t th\u01B0 m\u1EE5c"),
|
|
42343
|
+
projectId: external_exports.string().min(1).optional(),
|
|
42344
|
+
agent: ProjectAgentSchema.optional(),
|
|
42322
42345
|
prompt: external_exports.string().min(1, "G\xF5 vi\u1EC7c b\u1EA1n mu\u1ED1n m\xE1y l\xE0m").max(4e3, "Y\xEAu c\u1EA7u qu\xE1 d\xE0i \u2014 r\xFAt g\u1ECDn c\xF2n d\u01B0\u1EDBi 4000 k\xFD t\u1EF1")
|
|
42323
42346
|
});
|
|
42324
42347
|
var AddFolderSchema = external_exports.object({
|
|
@@ -45788,7 +45811,7 @@ var TOOLS = {
|
|
|
45788
45811
|
// không phải là lời mời đọc ổ đĩa của học viên.
|
|
45789
45812
|
CHAT: []
|
|
45790
45813
|
};
|
|
45791
|
-
var VERSION = "0.18.
|
|
45814
|
+
var VERSION = "0.18.2";
|
|
45792
45815
|
function claudeArgs(job, o, port) {
|
|
45793
45816
|
const mcp = {
|
|
45794
45817
|
mcpServers: {
|
|
@@ -45881,12 +45904,12 @@ function buildHttpServer(o) {
|
|
|
45881
45904
|
dir: o.jobsDir ?? (0, import_node_path9.join)((0, import_node_os5.homedir)(), ".hocai", "jobs"),
|
|
45882
45905
|
maxRunning: o.maxRunning,
|
|
45883
45906
|
run: (job, onLine) => {
|
|
45884
|
-
if (job.kind === "CHAT") {
|
|
45907
|
+
if (job.kind === "CHAT" || job.kind === "WORK" && job.agent) {
|
|
45885
45908
|
const controller = new AbortController();
|
|
45886
45909
|
let streamed = "";
|
|
45887
45910
|
const done = Promise.resolve().then(() => runAi({
|
|
45888
45911
|
agent: job.agent ?? "claude",
|
|
45889
|
-
mode: "chat",
|
|
45912
|
+
mode: job.kind === "CHAT" ? "chat" : "work",
|
|
45890
45913
|
prompt: job.prompt,
|
|
45891
45914
|
cwd: job.dir,
|
|
45892
45915
|
signal: controller.signal,
|
|
@@ -46253,6 +46276,7 @@ function handleServerMessage(msg, deps) {
|
|
|
46253
46276
|
if (jobs.has(jobId)) return;
|
|
46254
46277
|
const folderId = typeof msg.folderId === "string" ? msg.folderId : "";
|
|
46255
46278
|
const prompt = typeof msg.prompt === "string" ? msg.prompt : "";
|
|
46279
|
+
const agent = msg.agent === "codex" ? "codex" : "claude";
|
|
46256
46280
|
const dir = deps.folders.pathOf(folderId);
|
|
46257
46281
|
if (!dir) {
|
|
46258
46282
|
deps.send({
|
|
@@ -46263,7 +46287,7 @@ function handleServerMessage(msg, deps) {
|
|
|
46263
46287
|
});
|
|
46264
46288
|
return;
|
|
46265
46289
|
}
|
|
46266
|
-
const job = deps.store.create({ kind: "WORK", dir, prompt });
|
|
46290
|
+
const job = deps.store.create({ kind: "WORK", dir, prompt, agent });
|
|
46267
46291
|
const record3 = { localId: job.id, finished: false };
|
|
46268
46292
|
jobs.set(jobId, record3);
|
|
46269
46293
|
let off = () => {
|
|
@@ -47823,6 +47847,83 @@ async function setupMcp(options) {
|
|
|
47823
47847
|
return { script, protocolVerified: true, tools, clients };
|
|
47824
47848
|
}
|
|
47825
47849
|
|
|
47850
|
+
// apps/mcp/src/terminal-progress.ts
|
|
47851
|
+
var FRAMES = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
|
|
47852
|
+
var CLEAR_LINE = "\r\x1B[2K";
|
|
47853
|
+
function createTerminalProgress(options = {}) {
|
|
47854
|
+
const stream = options.stream ?? process.stderr;
|
|
47855
|
+
const intervalMs = options.intervalMs ?? 80;
|
|
47856
|
+
const interactive = options.interactive ?? (stream.isTTY === true && process.env.TERM !== "dumb");
|
|
47857
|
+
let timer = null;
|
|
47858
|
+
let frame = 0;
|
|
47859
|
+
let label = "";
|
|
47860
|
+
let active = false;
|
|
47861
|
+
let lastPlain = "";
|
|
47862
|
+
const clearTimer = () => {
|
|
47863
|
+
if (!timer) return;
|
|
47864
|
+
clearInterval(timer);
|
|
47865
|
+
timer = null;
|
|
47866
|
+
};
|
|
47867
|
+
const draw = () => {
|
|
47868
|
+
if (!active || !interactive) return;
|
|
47869
|
+
stream.write(`${CLEAR_LINE}${FRAMES[frame % FRAMES.length]} ${label}`);
|
|
47870
|
+
frame++;
|
|
47871
|
+
};
|
|
47872
|
+
const plain = (icon, text) => {
|
|
47873
|
+
stream.write(`${icon} ${text}
|
|
47874
|
+
`);
|
|
47875
|
+
lastPlain = text;
|
|
47876
|
+
};
|
|
47877
|
+
const stop = () => {
|
|
47878
|
+
if (!active) return;
|
|
47879
|
+
clearTimer();
|
|
47880
|
+
if (interactive) stream.write(CLEAR_LINE);
|
|
47881
|
+
active = false;
|
|
47882
|
+
};
|
|
47883
|
+
const settle = (icon, text) => {
|
|
47884
|
+
const finalLabel = text ?? label;
|
|
47885
|
+
clearTimer();
|
|
47886
|
+
if (interactive) stream.write(`${CLEAR_LINE}${icon} ${finalLabel}
|
|
47887
|
+
`);
|
|
47888
|
+
else plain(icon, finalLabel);
|
|
47889
|
+
active = false;
|
|
47890
|
+
};
|
|
47891
|
+
return {
|
|
47892
|
+
get interactive() {
|
|
47893
|
+
return interactive;
|
|
47894
|
+
},
|
|
47895
|
+
start(text) {
|
|
47896
|
+
stop();
|
|
47897
|
+
label = text;
|
|
47898
|
+
frame = 0;
|
|
47899
|
+
active = true;
|
|
47900
|
+
lastPlain = "";
|
|
47901
|
+
if (interactive) {
|
|
47902
|
+
draw();
|
|
47903
|
+
timer = setInterval(draw, intervalMs);
|
|
47904
|
+
timer.unref?.();
|
|
47905
|
+
} else {
|
|
47906
|
+
plain("\xB7", text);
|
|
47907
|
+
}
|
|
47908
|
+
},
|
|
47909
|
+
update(text) {
|
|
47910
|
+
if (!active) return;
|
|
47911
|
+
label = text;
|
|
47912
|
+
if (interactive) draw();
|
|
47913
|
+
else if (text !== lastPlain) plain("\xB7", text);
|
|
47914
|
+
},
|
|
47915
|
+
succeed(text) {
|
|
47916
|
+
if (!active && !text) return;
|
|
47917
|
+
settle("\u2713", text);
|
|
47918
|
+
},
|
|
47919
|
+
fail(text) {
|
|
47920
|
+
if (!active && !text) return;
|
|
47921
|
+
settle("\u2715", text);
|
|
47922
|
+
},
|
|
47923
|
+
stop
|
|
47924
|
+
};
|
|
47925
|
+
}
|
|
47926
|
+
|
|
47826
47927
|
// apps/mcp/src/cli.ts
|
|
47827
47928
|
var HOCAI_DIR = (0, import_node_path17.join)((0, import_node_os11.homedir)(), ".hocai");
|
|
47828
47929
|
var CREDS = (0, import_node_path17.join)(HOCAI_DIR, "config.json");
|
|
@@ -47867,18 +47968,35 @@ async function login() {
|
|
|
47867
47968
|
say2(`N\u1EBFu kh\xF4ng th\u1EA5y g\xEC m\u1EDF ra, d\xE1n \u0111\u1ECBa ch\u1EC9 n\xE0y v\xE0o tr\xECnh duy\u1EC7t:
|
|
47868
47969
|
${url2}`);
|
|
47869
47970
|
openBrowser(url2);
|
|
47870
|
-
const
|
|
47871
|
-
|
|
47872
|
-
|
|
47873
|
-
|
|
47874
|
-
|
|
47971
|
+
const progress = createTerminalProgress();
|
|
47972
|
+
progress.start("\u0110ang ch\u1EDD b\u1EA1n cho ph\xE9p trong tr\xECnh duy\u1EC7t\u2026");
|
|
47973
|
+
try {
|
|
47974
|
+
const creds = await l.token;
|
|
47975
|
+
await l.close();
|
|
47976
|
+
saveCreds({ token: creds.token, api: absoluteApiUrl(creds.api, WEB(), API_DEFAULT()) });
|
|
47977
|
+
progress.succeed("\u0110\xE3 \u0111\u0103ng nh\u1EADp v\xE0 l\u01B0u k\u1EBFt n\u1ED1i hocAI.");
|
|
47978
|
+
return loadCreds();
|
|
47979
|
+
} catch (error51) {
|
|
47980
|
+
progress.fail("Ch\u01B0a nh\u1EADn \u0111\u01B0\u1EE3c \u0111\u0103ng nh\u1EADp t\u1EEB tr\xECnh duy\u1EC7t.");
|
|
47981
|
+
await l.close().catch(() => {
|
|
47982
|
+
});
|
|
47983
|
+
throw error51;
|
|
47984
|
+
}
|
|
47875
47985
|
}
|
|
47876
47986
|
async function configureMcp(json3 = false) {
|
|
47877
47987
|
const creds = workCredentials(loadCreds());
|
|
47878
|
-
const
|
|
47988
|
+
const progress = json3 ? null : createTerminalProgress();
|
|
47989
|
+
progress?.start("\u0110ang c\u1EA5u h\xECnh MCP cho c\xE1c tr\u1EE3 l\xFD AI tr\xEAn m\xE1y\u2026");
|
|
47990
|
+
let result;
|
|
47991
|
+
try {
|
|
47992
|
+
result = await setupMcp({ root: HOCAI_DIR, source: __filename, authenticated: !!creds });
|
|
47993
|
+
} catch (error51) {
|
|
47994
|
+
progress?.fail("C\u1EA5u h\xECnh MCP ch\u01B0a ho\xE0n t\u1EA5t.");
|
|
47995
|
+
throw error51;
|
|
47996
|
+
}
|
|
47879
47997
|
if (json3) process.stdout.write(JSON.stringify(result) + "\n");
|
|
47880
47998
|
else {
|
|
47881
|
-
|
|
47999
|
+
progress?.succeed("MCP \u0111\xE3 b\u1EAFt tay v\xE0 kh\xE1m ph\xE1 c\xF4ng c\u1EE5 th\xE0nh c\xF4ng.");
|
|
47882
48000
|
for (const client of result.clients) {
|
|
47883
48001
|
const status = { configured: "\u0111\xE3 c\u1EA5u h\xECnh", unchanged: "\u0111\xE3 c\xF3 c\u1EA5u h\xECnh \u0111\xFAng", skipped: "ch\u01B0a th\u1EA5y \u1EE9ng d\u1EE5ng", failed: "ch\u01B0a c\u1EA5u h\xECnh \u0111\u01B0\u1EE3c" }[client.status];
|
|
47884
48002
|
say2(` ${client.client}: ${status}${client.message ? ` \u2014 ${client.message}` : ""}`);
|
|
@@ -47989,31 +48107,41 @@ function caiDichVu() {
|
|
|
47989
48107
|
say2("\xB7 H\u1EC7 \u0111i\u1EC1u h\xE0nh n\xE0y ch\u01B0a h\u1ED7 tr\u1EE3 ch\u1EA1y \u1EA9n. D\xF9ng `npx hocai-connect run` v\xE0 \u0111\u1EC3 c\u1EEDa s\u1ED5 m\u1EDF.");
|
|
47990
48108
|
return false;
|
|
47991
48109
|
}
|
|
47992
|
-
|
|
47993
|
-
|
|
47994
|
-
|
|
47995
|
-
|
|
47996
|
-
(0, import_node_fs10.mkdirSync)(
|
|
47997
|
-
(0, import_node_fs10.
|
|
47998
|
-
|
|
47999
|
-
|
|
48000
|
-
|
|
48001
|
-
|
|
48002
|
-
|
|
48003
|
-
|
|
48004
|
-
|
|
48005
|
-
|
|
48006
|
-
|
|
48110
|
+
const progress = createTerminalProgress();
|
|
48111
|
+
progress.start("\u0110ang chu\u1EA9n b\u1ECB d\u1ECBch v\u1EE5 n\u1EC1n\u2026");
|
|
48112
|
+
try {
|
|
48113
|
+
(0, import_node_fs10.mkdirSync)(APP_DIR, { recursive: true });
|
|
48114
|
+
(0, import_node_fs10.mkdirSync)(LOG_DIR, { recursive: true });
|
|
48115
|
+
(0, import_node_fs10.copyFileSync)(__filename, APP_CLI);
|
|
48116
|
+
progress.update("\u0110ang ghi c\u1EA5u h\xECnh d\u1ECBch v\u1EE5 n\u1EC1n\u2026");
|
|
48117
|
+
if (p.file && p.content) {
|
|
48118
|
+
(0, import_node_fs10.mkdirSync)((0, import_node_path17.dirname)(p.file), { recursive: true });
|
|
48119
|
+
(0, import_node_fs10.writeFileSync)(p.file, p.content);
|
|
48120
|
+
}
|
|
48121
|
+
progress.update("\u0110ang \u0111\u0103ng k\xFD d\u1ECBch v\u1EE5 v\u1EDBi h\u1EC7 \u0111i\u1EC1u h\xE0nh\u2026");
|
|
48122
|
+
p.install.forEach((c, i) => {
|
|
48123
|
+
if (i === 0) {
|
|
48124
|
+
chay(c, true);
|
|
48125
|
+
if ((0, import_node_os11.platform)() === "darwin") {
|
|
48126
|
+
const nhan = `gui/${process.getuid?.() ?? 501}/${p.label}`;
|
|
48127
|
+
for (let lan = 0; lan < 20; lan++) {
|
|
48128
|
+
if (!chay(["launchctl", "print", nhan], true)) break;
|
|
48129
|
+
nghi(250);
|
|
48130
|
+
}
|
|
48007
48131
|
}
|
|
48132
|
+
return;
|
|
48008
48133
|
}
|
|
48009
|
-
|
|
48010
|
-
|
|
48011
|
-
|
|
48012
|
-
|
|
48013
|
-
|
|
48014
|
-
|
|
48015
|
-
|
|
48016
|
-
|
|
48134
|
+
for (let lan = 0; lan < 5; lan++) {
|
|
48135
|
+
if (chay(c, true)) return;
|
|
48136
|
+
nghi(700);
|
|
48137
|
+
}
|
|
48138
|
+
});
|
|
48139
|
+
progress.succeed("D\u1ECBch v\u1EE5 n\u1EC1n \u0111\xE3 \u0111\u01B0\u1EE3c c\xE0i v\xE0 b\u1EADt.");
|
|
48140
|
+
return true;
|
|
48141
|
+
} catch (error51) {
|
|
48142
|
+
progress.fail("Kh\xF4ng c\xE0i \u0111\u01B0\u1EE3c d\u1ECBch v\u1EE5 n\u1EC1n.");
|
|
48143
|
+
throw error51;
|
|
48144
|
+
}
|
|
48017
48145
|
}
|
|
48018
48146
|
function goDichVu() {
|
|
48019
48147
|
const p = plan();
|
|
@@ -48058,19 +48186,41 @@ async function main() {
|
|
|
48058
48186
|
if (cmd === "sync-reports") {
|
|
48059
48187
|
const flags = process.argv.slice(3);
|
|
48060
48188
|
if (flags.some((flag) => flag !== "--json")) throw new Error("sync-reports ch\u1EC9 nh\u1EADn --json.");
|
|
48189
|
+
const json3 = flags.includes("--json");
|
|
48061
48190
|
const creds2 = workCredentials(loadCreds());
|
|
48062
48191
|
if (!creds2) throw new Error("Ch\u01B0a n\u1ED1i hocAI. Ch\u1EA1y hocai-connect tr\u01B0\u1EDBc.");
|
|
48063
|
-
const
|
|
48064
|
-
|
|
48065
|
-
|
|
48192
|
+
const progress = json3 ? null : createTerminalProgress();
|
|
48193
|
+
progress?.start("\u0110ang \u0111\u1ED3ng b\u1ED9 c\xE1c b\xE1o c\xE1o c\xF2n ch\u1EDD\u2026");
|
|
48194
|
+
let result;
|
|
48195
|
+
try {
|
|
48196
|
+
result = await createWorkOutbox({ ...creds2, root: (0, import_node_path17.join)(HOCAI_DIR, "work-outbox") }).flush();
|
|
48197
|
+
} catch (error51) {
|
|
48198
|
+
progress?.fail("\u0110\u1ED3ng b\u1ED9 b\xE1o c\xE1o ch\u01B0a ho\xE0n t\u1EA5t.");
|
|
48199
|
+
throw error51;
|
|
48200
|
+
}
|
|
48201
|
+
if (json3) process.stdout.write(JSON.stringify(result) + "\n");
|
|
48202
|
+
else {
|
|
48203
|
+
progress?.succeed(`\u0110\xE3 \u0111\u1ED3ng b\u1ED9 b\xE1o c\xE1o \xB7 g\u1EEDi ${result.sent} \xB7 c\xF2n ${result.pending}`);
|
|
48204
|
+
if (result.lastError) say2(` ${result.lastError}`);
|
|
48205
|
+
}
|
|
48066
48206
|
process.exitCode = result.pending ? 2 : 0;
|
|
48067
48207
|
return;
|
|
48068
48208
|
}
|
|
48069
48209
|
if (cmd === "report" || cmd === "doctor") {
|
|
48070
48210
|
const flags = process.argv.slice(3);
|
|
48071
48211
|
if (flags.some((flag) => flag !== "--json")) throw new Error("L\u1EC7nh report ch\u1EC9 nh\u1EADn tu\u1EF3 ch\u1ECDn --json.");
|
|
48072
|
-
const
|
|
48073
|
-
|
|
48212
|
+
const json3 = flags.includes("--json");
|
|
48213
|
+
const progress = json3 ? null : createTerminalProgress();
|
|
48214
|
+
progress?.start("\u0110ang d\xF2 Claude, Codex v\xE0 tr\u1EA1ng th\xE1i m\xE1y\u2026");
|
|
48215
|
+
let report;
|
|
48216
|
+
try {
|
|
48217
|
+
report = await collectMachineReport({ helperVersion: VERSION });
|
|
48218
|
+
progress?.succeed("\u0110\xE3 d\xF2 xong tr\u1EA1ng th\xE1i m\xE1y v\xE0 c\xE1c tr\u1EE3 l\xFD AI.");
|
|
48219
|
+
} catch (error51) {
|
|
48220
|
+
progress?.fail("Kh\xF4ng d\xF2 xong tr\u1EA1ng th\xE1i m\xE1y.");
|
|
48221
|
+
throw error51;
|
|
48222
|
+
}
|
|
48223
|
+
process.stdout.write((json3 ? JSON.stringify(report, null, 2) : formatMachineReport(report)) + "\n");
|
|
48074
48224
|
return;
|
|
48075
48225
|
}
|
|
48076
48226
|
if (cmd === "enable-usage") {
|
|
@@ -48111,25 +48261,37 @@ async function main() {
|
|
|
48111
48261
|
return;
|
|
48112
48262
|
}
|
|
48113
48263
|
if (cmd === "quen") {
|
|
48264
|
+
const progress = createTerminalProgress();
|
|
48265
|
+
progress.start("\u0110ang ng\u1EAFt m\xE1y n\xE0y kh\u1ECFi hocAI\u2026");
|
|
48114
48266
|
goDichVu();
|
|
48115
48267
|
(0, import_node_fs10.rmSync)(CREDS, { force: true });
|
|
48116
|
-
|
|
48268
|
+
progress.succeed("\u0110\xE3 ng\u1EAFt k\u1EBFt n\u1ED1i v\xE0 g\u1EE1 d\u1ECBch v\u1EE5 n\u1EC1n tr\xEAn m\xE1y n\xE0y.");
|
|
48117
48269
|
say2("Ch\u1EA1y l\u1EA1i `npx hocai-connect` \u0111\u1EC3 k\u1EBFt n\u1ED1i l\u1EA1i.");
|
|
48118
48270
|
return;
|
|
48119
48271
|
}
|
|
48120
48272
|
if (cmd === "update") {
|
|
48121
48273
|
const stored = loadCreds();
|
|
48122
|
-
const
|
|
48123
|
-
|
|
48124
|
-
|
|
48125
|
-
|
|
48274
|
+
const progress = createTerminalProgress();
|
|
48275
|
+
progress.start("\u0110ang ki\u1EC3m tra phi\xEAn b\u1EA3n m\u1EDBi v\xE0 d\u1ECBch v\u1EE5 \u0111ang ch\u1EA1y\u2026");
|
|
48276
|
+
let moi;
|
|
48277
|
+
let running;
|
|
48278
|
+
try {
|
|
48279
|
+
;
|
|
48280
|
+
[moi, running] = await Promise.all([
|
|
48281
|
+
latestVersion(),
|
|
48282
|
+
stored ? askPortOwner(PORT, stored.api.replace(/\/api$/, "")) : Promise.resolve(null)
|
|
48283
|
+
]);
|
|
48284
|
+
} catch (error51) {
|
|
48285
|
+
progress.fail("Kh\xF4ng ki\u1EC3m tra \u0111\u01B0\u1EE3c phi\xEAn b\u1EA3n hi\u1EC7n t\u1EA1i.");
|
|
48286
|
+
throw error51;
|
|
48287
|
+
}
|
|
48126
48288
|
const action = planHelperUpdate(VERSION, moi, running?.phienBan ?? null);
|
|
48127
48289
|
if (action === "current") {
|
|
48128
|
-
|
|
48290
|
+
progress.succeed(`D\u1ECBch v\u1EE5 \u0111ang ch\u1EA1y b\u1EA3n ${running?.phienBan}; kh\xF4ng c\u1EA7n c\xE0i l\u1EA1i.`);
|
|
48129
48291
|
return;
|
|
48130
48292
|
}
|
|
48131
48293
|
if (action === "download" && moi) {
|
|
48132
|
-
|
|
48294
|
+
progress.succeed(`C\xF3 b\u1EA3n m\u1EDBi ${VERSION} \u2192 ${moi}. B\u1EAFt \u0111\u1EA7u c\u1EADp nh\u1EADt.`);
|
|
48133
48295
|
say2("");
|
|
48134
48296
|
(0, import_node_fs10.mkdirSync)(NPM_CACHE, { recursive: true });
|
|
48135
48297
|
const r = (0, import_node_child_process9.spawnSync)("npx", updateNpxArgs(moi, NPM_CACHE), {
|
|
@@ -48138,12 +48300,15 @@ async function main() {
|
|
|
48138
48300
|
});
|
|
48139
48301
|
process.exit(r.status ?? 1);
|
|
48140
48302
|
}
|
|
48141
|
-
|
|
48303
|
+
progress.succeed(`\u0110\xE3 ch\u1ECDn bundle ${VERSION}; \u0111ang c\xE0i v\xE0o d\u1ECBch v\u1EE5 n\u1EC1n.`);
|
|
48142
48304
|
cmd = void 0;
|
|
48143
48305
|
}
|
|
48144
48306
|
if (cmd === "stop") {
|
|
48307
|
+
const progress = createTerminalProgress();
|
|
48308
|
+
progress.start("\u0110ang t\u1EAFt v\xE0 g\u1EE1 d\u1ECBch v\u1EE5 n\u1EC1n\u2026");
|
|
48145
48309
|
goDichVu();
|
|
48146
|
-
|
|
48310
|
+
progress.succeed("\u0110\xE3 t\u1EAFt v\xE0 g\u1EE1 d\u1ECBch v\u1EE5 n\u1EC1n.");
|
|
48311
|
+
say2("Ch\xECa kho\xE1 v\u1EABn gi\u1EEF \u2014 ch\u1EA1y `npx hocai-connect` l\xE0 n\u1ED1i l\u1EA1i ngay.");
|
|
48147
48312
|
return;
|
|
48148
48313
|
}
|
|
48149
48314
|
if (cmd === "status") {
|
|
@@ -48152,15 +48317,19 @@ async function main() {
|
|
|
48152
48317
|
say2("M\xE1y n\xE0y ch\u01B0a n\u1ED1i. Ch\u1EA1y `npx hocai-connect`.");
|
|
48153
48318
|
process.exit(1);
|
|
48154
48319
|
}
|
|
48155
|
-
const
|
|
48320
|
+
const progress = createTerminalProgress();
|
|
48321
|
+
progress.start("\u0110ang ki\u1EC3m tra d\u1ECBch v\u1EE5 v\xE0 phi\xEAn b\u1EA3n hocai-connect\u2026");
|
|
48322
|
+
const [info, moi] = await Promise.all([
|
|
48323
|
+
askPortOwner(PORT, c.api.replace(/\/api$/, "")),
|
|
48324
|
+
latestVersion()
|
|
48325
|
+
]);
|
|
48156
48326
|
if (!info) {
|
|
48157
|
-
|
|
48327
|
+
progress.fail(`Kh\xF4ng c\xF3 g\xEC tr\u1EA3 l\u1EDDi \u1EDF c\u1ED5ng ${PORT} \u2014 d\u1ECBch v\u1EE5 n\u1EC1n ch\u01B0a ch\u1EA1y.`);
|
|
48158
48328
|
process.exit(1);
|
|
48159
48329
|
}
|
|
48160
|
-
|
|
48330
|
+
progress.succeed(`\u0110ang ch\u1EA1y \xB7 ${info.user?.ten ?? "(ch\xECa \u0111\xE3 b\u1ECB thu h\u1ED3i)"} \xB7 b\u1EA3n ${info.phienBan}`);
|
|
48161
48331
|
say2(` Nh\u1EADt k\xFD: ${plan().log}`);
|
|
48162
48332
|
warnLines(doPerms());
|
|
48163
|
-
const moi = await latestVersion();
|
|
48164
48333
|
if (moi && info.phienBan && newerVersion(moi, info.phienBan)) {
|
|
48165
48334
|
say2("");
|
|
48166
48335
|
say2(` C\xF3 b\u1EA3n m\u1EDBi ${moi}. C\u1EADp nh\u1EADt: npx hocai-connect@latest update`);
|
|
@@ -48189,18 +48358,20 @@ async function main() {
|
|
|
48189
48358
|
}
|
|
48190
48359
|
const creds = loadCreds() ?? await login();
|
|
48191
48360
|
process.env.HOCAI_API_URL = creds.api;
|
|
48361
|
+
const identityProgress = cmd === "run" ? null : createTerminalProgress();
|
|
48362
|
+
identityProgress?.start("\u0110ang x\xE1c minh t\xE0i kho\u1EA3n hocAI\u2026");
|
|
48192
48363
|
const me = await fetchIdentity(creds.api, creds.token).catch(() => {
|
|
48193
|
-
|
|
48194
|
-
say2("
|
|
48195
|
-
say2("kh\xF4ng c\xF3 m\u1EA1ng th\xEC trang hocAI c\u0169ng kh\xF4ng m\u1EDF \u0111\u01B0\u1EE3c, n\xEAn ch\u1EA1y ti\u1EBFp c\u0169ng kh\xF4ng l\xE0m g\xEC \u0111\u01B0\u1EE3c.");
|
|
48364
|
+
identityProgress?.fail("Kh\xF4ng k\u1EBFt n\u1ED1i \u0111\u01B0\u1EE3c t\u1EDBi hocAI \u0111\u1EC3 ki\u1EC3m tra t\xE0i kho\u1EA3n.");
|
|
48365
|
+
say2("Ki\u1EC3m tra m\u1EA1ng r\u1ED3i ch\u1EA1y l\u1EA1i \u2014 kh\xF4ng c\xF3 m\u1EA1ng th\xEC trang hocAI c\u0169ng kh\xF4ng m\u1EDF \u0111\u01B0\u1EE3c.");
|
|
48196
48366
|
process.exit(1);
|
|
48197
48367
|
});
|
|
48198
48368
|
if (!me) {
|
|
48199
|
-
|
|
48200
|
-
say2("Token
|
|
48369
|
+
identityProgress?.fail("Token tr\xEAn m\xE1y n\xE0y kh\xF4ng d\xF9ng \u0111\u01B0\u1EE3c n\u1EEFa.");
|
|
48370
|
+
say2("Token c\xF3 th\u1EC3 \u0111\xE3 b\u1ECB thu h\u1ED3i, ho\u1EB7c t\xE0i kho\u1EA3n \u0111\xE3 b\u1ECB kho\xE1.");
|
|
48201
48371
|
say2("Ch\u1EA1y `npx hocai-connect quen` r\u1ED3i ch\u1EA1y l\u1EA1i `npx hocai-connect` \u0111\u1EC3 k\u1EBFt n\u1ED1i l\u1EA1i.");
|
|
48202
48372
|
process.exit(1);
|
|
48203
48373
|
}
|
|
48374
|
+
identityProgress?.succeed(`\u0110\xE3 x\xE1c minh t\xE0i kho\u1EA3n \xB7 ${me.ten}`);
|
|
48204
48375
|
const identity = createIdentityCache({
|
|
48205
48376
|
fetchIdentity: () => fetchIdentity(creds.api, creds.token),
|
|
48206
48377
|
seed: me,
|
|
@@ -48210,6 +48381,19 @@ async function main() {
|
|
|
48210
48381
|
if (cmd !== "run") {
|
|
48211
48382
|
const xong = caiDichVu();
|
|
48212
48383
|
const sanSang = doTroLy();
|
|
48384
|
+
if (xong) {
|
|
48385
|
+
const startupProgress = createTerminalProgress();
|
|
48386
|
+
startupProgress.start("\u0110ang ch\u1EDD d\u1ECBch v\u1EE5 n\u1EC1n kh\u1EDFi \u0111\u1ED9ng v\xE0 ph\u1EA3n h\u1ED3i\u2026");
|
|
48387
|
+
await new Promise((r) => setTimeout(r, 2500));
|
|
48388
|
+
const info = await askPortOwner(PORT, WEB());
|
|
48389
|
+
if (!info) {
|
|
48390
|
+
startupProgress.fail("D\u1ECBch v\u1EE5 \u0111\xE3 c\xE0i nh\u01B0ng ch\u01B0a ph\u1EA3n h\u1ED3i \u1EDF c\u1ED5ng " + PORT + ".");
|
|
48391
|
+
say2(` Xem nh\u1EADt k\xFD: npx hocai-connect logs`);
|
|
48392
|
+
process.exit(1);
|
|
48393
|
+
}
|
|
48394
|
+
startupProgress.succeed(`D\u1ECBch v\u1EE5 n\u1EC1n \u0111\xE3 s\u1EB5n s\xE0ng \xB7 b\u1EA3n ${info.phienBan}`);
|
|
48395
|
+
warnLines(doPerms());
|
|
48396
|
+
}
|
|
48213
48397
|
say2("");
|
|
48214
48398
|
say2("\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550");
|
|
48215
48399
|
say2(sanSang ? ` \u2713 \u0110\xE3 n\u1ED1i m\xE1y \xB7 ${me.ten}` : ` \u2713 \u0110\xE3 n\u1ED1i m\xE1y \xB7 ${me.ten} \u2014 nh\u01B0ng xem c\u1EA3nh b\xE1o \u1EDF tr\xEAn`);
|
|
@@ -48221,17 +48405,6 @@ async function main() {
|
|
|
48221
48405
|
say2(" Ng\u1EAFt k\u1EBFt n\u1ED1i: npx hocai-connect stop");
|
|
48222
48406
|
}
|
|
48223
48407
|
say2("\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550");
|
|
48224
|
-
if (xong) {
|
|
48225
|
-
await new Promise((r) => setTimeout(r, 2500));
|
|
48226
|
-
const info = await askPortOwner(PORT, WEB());
|
|
48227
|
-
if (!info) {
|
|
48228
|
-
say2("");
|
|
48229
|
-
say2("\u26A0 D\u1ECBch v\u1EE5 \u0111\xE3 c\xE0i nh\u01B0ng ch\u01B0a th\u1EA5y tr\u1EA3 l\u1EDDi \u1EDF c\u1ED5ng " + PORT + ".");
|
|
48230
|
-
say2(` Xem nh\u1EADt k\xFD: npx hocai-connect logs`);
|
|
48231
|
-
process.exit(1);
|
|
48232
|
-
}
|
|
48233
|
-
warnLines(doPerms());
|
|
48234
|
-
}
|
|
48235
48408
|
if (quyen && quyen.fixCache.length) {
|
|
48236
48409
|
say2("");
|
|
48237
48410
|
say2("C\xF2n m\u1ED9t vi\u1EC7c: cache npm tr\xEAn m\xE1y n\xE0y c\xF3 t\u1EC7p thu\u1ED9c ng\u01B0\u1EDDi d\xF9ng kh\xE1c,");
|