alink-cli 0.11.2 → 0.11.3
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/agentlink-account.js +16 -4
- package/bin/agentlink.js +36 -2
- package/dist/ui.js +10 -5
- package/package.json +1 -1
package/bin/agentlink-account.js
CHANGED
|
@@ -35,7 +35,7 @@ function normalizeMachineRow(row) {
|
|
|
35
35
|
};
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
-
function machineIdFromToken(authToken) {
|
|
38
|
+
export function machineIdFromToken(authToken) {
|
|
39
39
|
try {
|
|
40
40
|
const payload = JSON.parse(
|
|
41
41
|
Buffer.from(authToken.split(".")[1] || "", "base64url").toString("utf8"),
|
|
@@ -60,6 +60,7 @@ export async function registerAgentLinkAccountMachine({
|
|
|
60
60
|
identifier,
|
|
61
61
|
password,
|
|
62
62
|
machineName,
|
|
63
|
+
preferredMachineId,
|
|
63
64
|
fetchFn = fetch,
|
|
64
65
|
cloudbaseSdk,
|
|
65
66
|
randomBytesFn = randomBytes,
|
|
@@ -89,7 +90,7 @@ export async function registerAgentLinkAccountMachine({
|
|
|
89
90
|
"Content-Type": "application/json",
|
|
90
91
|
"X-Requested-With": "agentlink",
|
|
91
92
|
},
|
|
92
|
-
body: JSON.stringify({ name: machineName }),
|
|
93
|
+
body: JSON.stringify({ name: machineName, ...(preferredMachineId ? { machineId: preferredMachineId } : {}) }),
|
|
93
94
|
});
|
|
94
95
|
const minted = await json(mintResponse);
|
|
95
96
|
const authToken = typeof minted.authToken === "string" ? minted.authToken : "";
|
|
@@ -144,6 +145,7 @@ export async function registerAgentLinkSessionMachine({
|
|
|
144
145
|
hub,
|
|
145
146
|
jwt,
|
|
146
147
|
machineName,
|
|
148
|
+
preferredMachineId,
|
|
147
149
|
fetchFn = fetch,
|
|
148
150
|
randomBytesFn = randomBytes,
|
|
149
151
|
}) {
|
|
@@ -156,10 +158,20 @@ export async function registerAgentLinkSessionMachine({
|
|
|
156
158
|
"Content-Type": "application/json",
|
|
157
159
|
"X-Requested-With": "agentlink",
|
|
158
160
|
},
|
|
159
|
-
body: JSON.stringify({
|
|
161
|
+
body: JSON.stringify({
|
|
162
|
+
name: machineName,
|
|
163
|
+
enckey,
|
|
164
|
+
...(preferredMachineId ? { machineId: preferredMachineId } : {}),
|
|
165
|
+
}),
|
|
160
166
|
});
|
|
161
167
|
const minted = await json(response);
|
|
162
|
-
if (
|
|
168
|
+
if (
|
|
169
|
+
!response.ok ||
|
|
170
|
+
typeof minted.authToken !== "string" ||
|
|
171
|
+
!minted.authToken.startsWith("al1.") ||
|
|
172
|
+
typeof minted.machineId !== "string" ||
|
|
173
|
+
!minted.machineId
|
|
174
|
+
) {
|
|
163
175
|
throw new Error(minted.error || "机器注册失败。");
|
|
164
176
|
}
|
|
165
177
|
return { credential: `${minted.authToken}.${enckey}`, machineId: minted.machineId, jwt };
|
package/bin/agentlink.js
CHANGED
|
@@ -14,6 +14,7 @@ import {
|
|
|
14
14
|
listAgentLinkAccountMachines,
|
|
15
15
|
listAgentLinkAccountMachinesFromHub,
|
|
16
16
|
loadAgentLinkAccountConfig,
|
|
17
|
+
machineIdFromToken,
|
|
17
18
|
registerAgentLinkAccountMachine,
|
|
18
19
|
registerAgentLinkSessionMachine,
|
|
19
20
|
} from "./agentlink-account.js";
|
|
@@ -60,6 +61,7 @@ function clearSessionJwt(hub = OFFICIAL_HUB) {
|
|
|
60
61
|
const OFFICIAL_HUB = process.env.AGENTLINK_DEFAULT_HUB || "wss://link.harmopath.com";
|
|
61
62
|
const STATE_DIR = process.env.AGENTLINK_STATE_DIR || join(homedir(), ".agentlink");
|
|
62
63
|
const CREDENTIAL_FILE = join(STATE_DIR, "credential");
|
|
64
|
+
const MACHINE_ID_FILE = join(STATE_DIR, "machine-id");
|
|
63
65
|
const SESSION_FILE = join(STATE_DIR, "session");
|
|
64
66
|
const args = process.argv.slice(2);
|
|
65
67
|
const legacyCredentialCommands = process.env.AGENTLINK_ENABLE_LEGACY_CREDENTIALS === "1";
|
|
@@ -118,6 +120,26 @@ function saveCredential(credential, hub = OFFICIAL_HUB) {
|
|
|
118
120
|
chmodSync(CREDENTIAL_FILE, 0o600);
|
|
119
121
|
}
|
|
120
122
|
|
|
123
|
+
function savedMachineId(hub = OFFICIAL_HUB) {
|
|
124
|
+
try {
|
|
125
|
+
const saved = JSON.parse(readFileSync(MACHINE_ID_FILE, "utf8"));
|
|
126
|
+
return saved.hub === normalizeHub(hub) && typeof saved.machineId === "string"
|
|
127
|
+
? saved.machineId
|
|
128
|
+
: undefined;
|
|
129
|
+
} catch {
|
|
130
|
+
return undefined;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
function saveMachineId(machineId, hub = OFFICIAL_HUB) {
|
|
135
|
+
if (!machineId) return;
|
|
136
|
+
mkdirSync(STATE_DIR, { recursive: true });
|
|
137
|
+
writeFileSync(MACHINE_ID_FILE, JSON.stringify({ hub: normalizeHub(hub), machineId }), {
|
|
138
|
+
mode: 0o600,
|
|
139
|
+
});
|
|
140
|
+
chmodSync(MACHINE_ID_FILE, 0o600);
|
|
141
|
+
}
|
|
142
|
+
|
|
121
143
|
function parseCredential(credential) {
|
|
122
144
|
const parts = credential.split(".");
|
|
123
145
|
if (parts.length === 3 && parts[0] === "als1" && parts.slice(1).every(Boolean)) {
|
|
@@ -149,17 +171,25 @@ async function createSingleCredential(hub) {
|
|
|
149
171
|
|
|
150
172
|
async function loginAndCreateCredential(hub, config) {
|
|
151
173
|
const envLogin = process.env.AGENTLINK_ACCOUNT && process.env.AGENTLINK_PASSWORD;
|
|
174
|
+
const preferredMachineId = savedMachineId(hub);
|
|
152
175
|
const result = envLogin
|
|
153
176
|
? await registerAgentLinkAccountMachine({
|
|
154
177
|
hub,
|
|
155
178
|
config,
|
|
156
179
|
...(await accountCredentials()),
|
|
157
180
|
machineName: hostname(),
|
|
181
|
+
preferredMachineId,
|
|
158
182
|
})
|
|
159
183
|
: await browserLogin(hub).then((jwt) =>
|
|
160
|
-
registerAgentLinkSessionMachine({
|
|
184
|
+
registerAgentLinkSessionMachine({
|
|
185
|
+
hub,
|
|
186
|
+
jwt,
|
|
187
|
+
machineName: hostname(),
|
|
188
|
+
preferredMachineId,
|
|
189
|
+
}),
|
|
161
190
|
);
|
|
162
191
|
saveCredential(result.credential, hub);
|
|
192
|
+
saveMachineId(result.machineId, hub);
|
|
163
193
|
if (result.jwt) saveSessionJwt(result.jwt, hub);
|
|
164
194
|
console.log("[agentlink] 登录成功,这台电脑已加入账号。");
|
|
165
195
|
return result.credential;
|
|
@@ -296,7 +326,11 @@ async function showStatus() {
|
|
|
296
326
|
async function doLogout() {
|
|
297
327
|
const hub = value("hub") || OFFICIAL_HUB;
|
|
298
328
|
const loggedIn = savedCredential(hub);
|
|
299
|
-
if (loggedIn)
|
|
329
|
+
if (loggedIn) {
|
|
330
|
+
const { machineToken } = parseCredential(loggedIn);
|
|
331
|
+
saveMachineId(machineIdFromToken(machineToken), hub);
|
|
332
|
+
rmSync(CREDENTIAL_FILE, { force: true });
|
|
333
|
+
}
|
|
300
334
|
clearSessionJwt(hub);
|
|
301
335
|
console.log(
|
|
302
336
|
loggedIn ? "[agentlink] 已退出账号;下次启动时需要重新登录。" : "[agentlink] 当前未登录。",
|
package/dist/ui.js
CHANGED
|
@@ -48721,11 +48721,16 @@ function App2() {
|
|
|
48721
48721
|
setReconnecting(false);
|
|
48722
48722
|
}
|
|
48723
48723
|
} else if (confirmAction.type === "logout") {
|
|
48724
|
-
|
|
48725
|
-
|
|
48726
|
-
|
|
48727
|
-
|
|
48728
|
-
|
|
48724
|
+
try {
|
|
48725
|
+
await stopDaemon();
|
|
48726
|
+
const code = await runDetachedScript(["logout", "--hub", cfg.hub]);
|
|
48727
|
+
if (code !== 0) throw new Error(`\u9000\u51FA\u547D\u4EE4\u5F02\u5E38\u7ED3\u675F\uFF08\u9000\u51FA\u7801 ${code}\uFF09`);
|
|
48728
|
+
setRunning(false);
|
|
48729
|
+
setAuthTick((t) => t + 1);
|
|
48730
|
+
setNotice("\u5DF2\u9000\u51FA\u8D26\u53F7\u5E76\u505C\u6B62 daemon");
|
|
48731
|
+
} catch (err) {
|
|
48732
|
+
setNotice(`\u9000\u51FA\u5931\u8D25: ${err instanceof Error ? err.message : String(err)}`);
|
|
48733
|
+
}
|
|
48729
48734
|
}
|
|
48730
48735
|
setView("menu");
|
|
48731
48736
|
setConfirmAction(null);
|
package/package.json
CHANGED