junis 0.3.5 → 0.3.6
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/index.js +133 -0
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -126,6 +126,39 @@ async function authenticate(deviceName, platform3, onBrowserOpen, onWaiting, exi
|
|
|
126
126
|
}
|
|
127
127
|
throw new Error("Authentication timed out (5 min). Please try again.");
|
|
128
128
|
}
|
|
129
|
+
async function ensureTeam(deviceKey, token) {
|
|
130
|
+
let res;
|
|
131
|
+
try {
|
|
132
|
+
res = await fetch(`${JUNIS_API}/api/auth/device/ensure-team`, {
|
|
133
|
+
method: "POST",
|
|
134
|
+
headers: {
|
|
135
|
+
"Content-Type": "application/json",
|
|
136
|
+
Authorization: `Bearer ${token}`
|
|
137
|
+
},
|
|
138
|
+
body: JSON.stringify({ device_key: deviceKey })
|
|
139
|
+
});
|
|
140
|
+
} catch {
|
|
141
|
+
throw new Error("Network error: cannot reach server");
|
|
142
|
+
}
|
|
143
|
+
if (res.status === 401) {
|
|
144
|
+
return { status: "auth_expired" };
|
|
145
|
+
}
|
|
146
|
+
if (res.status === 404) {
|
|
147
|
+
return { status: "device_not_found" };
|
|
148
|
+
}
|
|
149
|
+
if (!res.ok) {
|
|
150
|
+
throw new Error(`ensure-team failed: ${res.status}`);
|
|
151
|
+
}
|
|
152
|
+
const data = await res.json();
|
|
153
|
+
return {
|
|
154
|
+
status: data.status,
|
|
155
|
+
// "ready" or "created"
|
|
156
|
+
organization_id: data.organization_id,
|
|
157
|
+
agent_id: data.agent_id,
|
|
158
|
+
agent_name: data.agent_name,
|
|
159
|
+
token: data.token
|
|
160
|
+
};
|
|
161
|
+
}
|
|
129
162
|
function sleep(ms) {
|
|
130
163
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
131
164
|
}
|
|
@@ -207,6 +240,13 @@ var RelayClient = class {
|
|
|
207
240
|
}
|
|
208
241
|
return;
|
|
209
242
|
}
|
|
243
|
+
if (code === 4004 || code === 4005) {
|
|
244
|
+
this.destroyed = true;
|
|
245
|
+
console.error(
|
|
246
|
+
"\n\u274C Device or team configuration is invalid. Run `npx junis --reset` to re-authenticate."
|
|
247
|
+
);
|
|
248
|
+
process.exit(1);
|
|
249
|
+
}
|
|
210
250
|
console.log(`\u26A0\uFE0F Disconnected. Reconnecting in ${this.reconnectDelay / 1e3}s...`);
|
|
211
251
|
setTimeout(() => this.connect(), this.reconnectDelay);
|
|
212
252
|
this.reconnectDelay = Math.min(this.reconnectDelay * 2, 3e4);
|
|
@@ -2398,6 +2438,27 @@ function printStep1(port) {
|
|
|
2398
2438
|
console.log(` \u25C9 Local MCP endpoint ........... http://localhost:${port}/mcp`);
|
|
2399
2439
|
console.log("");
|
|
2400
2440
|
}
|
|
2441
|
+
async function checkEnsureTeam(config, label) {
|
|
2442
|
+
try {
|
|
2443
|
+
const result = await ensureTeam(config.device_key, config.token);
|
|
2444
|
+
if (result.status === "ready") {
|
|
2445
|
+
return config;
|
|
2446
|
+
}
|
|
2447
|
+
if (result.status === "created") {
|
|
2448
|
+
console.log(`[${label}] Team restored automatically`);
|
|
2449
|
+
if (result.token) {
|
|
2450
|
+
config.token = result.token;
|
|
2451
|
+
saveConfig(config);
|
|
2452
|
+
}
|
|
2453
|
+
return config;
|
|
2454
|
+
}
|
|
2455
|
+
console.log(`[${label}] ${result.status} \u2014 re-authentication required`);
|
|
2456
|
+
clearConfig();
|
|
2457
|
+
return null;
|
|
2458
|
+
} catch {
|
|
2459
|
+
return config;
|
|
2460
|
+
}
|
|
2461
|
+
}
|
|
2401
2462
|
async function runForeground(config, port) {
|
|
2402
2463
|
const deviceName = config.device_name;
|
|
2403
2464
|
const platformName = process.platform === "darwin" ? "macos" : process.platform === "win32" ? "windows" : "linux";
|
|
@@ -2552,6 +2613,39 @@ program.command("start", { isDefault: true }).description("Start Junis agent con
|
|
|
2552
2613
|
console.log("");
|
|
2553
2614
|
}
|
|
2554
2615
|
} else {
|
|
2616
|
+
const checked = await checkEnsureTeam(config2, "junis");
|
|
2617
|
+
if (!checked) {
|
|
2618
|
+
let waitingPrinted = false;
|
|
2619
|
+
const authResult = await authenticate(
|
|
2620
|
+
deviceName2,
|
|
2621
|
+
platformName2,
|
|
2622
|
+
(uri) => {
|
|
2623
|
+
console.log("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");
|
|
2624
|
+
console.log(" STEP 2 \xB7 Connect to Junis Cloud");
|
|
2625
|
+
console.log("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");
|
|
2626
|
+
console.log(" Opening browser...");
|
|
2627
|
+
console.log(` \u2192 ${uri}`);
|
|
2628
|
+
process.stdout.write(" Waiting for login \xB7");
|
|
2629
|
+
},
|
|
2630
|
+
() => {
|
|
2631
|
+
if (!waitingPrinted) {
|
|
2632
|
+
waitingPrinted = true;
|
|
2633
|
+
} else {
|
|
2634
|
+
process.stdout.write("\xB7");
|
|
2635
|
+
}
|
|
2636
|
+
}
|
|
2637
|
+
);
|
|
2638
|
+
console.log("");
|
|
2639
|
+
console.log(` \u2705 Authenticated as ${authResult.email ?? "your account"}`);
|
|
2640
|
+
console.log("");
|
|
2641
|
+
config2 = {
|
|
2642
|
+
device_key: authResult.device_key,
|
|
2643
|
+
token: authResult.token,
|
|
2644
|
+
device_name: deviceName2,
|
|
2645
|
+
created_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
2646
|
+
};
|
|
2647
|
+
saveConfig(config2);
|
|
2648
|
+
}
|
|
2555
2649
|
console.log("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");
|
|
2556
2650
|
console.log(" STEP 3 \xB7 Register Device");
|
|
2557
2651
|
console.log("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");
|
|
@@ -2576,6 +2670,12 @@ program.command("start", { isDefault: true }).description("Start Junis agent con
|
|
|
2576
2670
|
console.error("\u274C No credentials found. Run npx junis first.");
|
|
2577
2671
|
process.exit(1);
|
|
2578
2672
|
}
|
|
2673
|
+
const checked = await checkEnsureTeam(config2, "junis daemon");
|
|
2674
|
+
if (!checked) {
|
|
2675
|
+
console.error("\u274C Device or team invalid. Run npx junis --reset to re-authenticate.");
|
|
2676
|
+
process.exit(1);
|
|
2677
|
+
}
|
|
2678
|
+
config2 = checked;
|
|
2579
2679
|
const deviceName2 = config2.device_name;
|
|
2580
2680
|
const platformName2 = process.platform === "darwin" ? "macos" : process.platform === "win32" ? "windows" : "linux";
|
|
2581
2681
|
const actualPort = await startMCPServer(port);
|
|
@@ -2699,6 +2799,39 @@ program.command("start", { isDefault: true }).description("Start Junis agent con
|
|
|
2699
2799
|
console.log("");
|
|
2700
2800
|
}
|
|
2701
2801
|
} else {
|
|
2802
|
+
const checked = await checkEnsureTeam(config, "junis");
|
|
2803
|
+
if (!checked) {
|
|
2804
|
+
let waitingPrinted = false;
|
|
2805
|
+
const authResult = await authenticate(
|
|
2806
|
+
deviceName,
|
|
2807
|
+
platformName,
|
|
2808
|
+
(uri) => {
|
|
2809
|
+
console.log("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");
|
|
2810
|
+
console.log(" STEP 2 \xB7 Connect to Junis Cloud");
|
|
2811
|
+
console.log("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");
|
|
2812
|
+
console.log(" Opening browser...");
|
|
2813
|
+
console.log(` \u2192 ${uri}`);
|
|
2814
|
+
process.stdout.write(" Waiting for login \xB7");
|
|
2815
|
+
},
|
|
2816
|
+
() => {
|
|
2817
|
+
if (!waitingPrinted) {
|
|
2818
|
+
waitingPrinted = true;
|
|
2819
|
+
} else {
|
|
2820
|
+
process.stdout.write("\xB7");
|
|
2821
|
+
}
|
|
2822
|
+
}
|
|
2823
|
+
);
|
|
2824
|
+
console.log("");
|
|
2825
|
+
console.log(` \u2705 Authenticated as ${authResult.email ?? "your account"}`);
|
|
2826
|
+
console.log("");
|
|
2827
|
+
config = {
|
|
2828
|
+
device_key: authResult.device_key,
|
|
2829
|
+
token: authResult.token,
|
|
2830
|
+
device_name: deviceName,
|
|
2831
|
+
created_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
2832
|
+
};
|
|
2833
|
+
saveConfig(config);
|
|
2834
|
+
}
|
|
2702
2835
|
console.log("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");
|
|
2703
2836
|
console.log(" STEP 3 \xB7 Register Device");
|
|
2704
2837
|
console.log("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");
|