episoda 0.2.10 → 0.2.12
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/daemon/daemon-process.d.ts +2 -0
- package/dist/daemon/daemon-process.js +3638 -0
- package/dist/daemon/daemon-process.js.map +1 -0
- package/dist/index.js +43 -19
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -2068,11 +2068,11 @@ var require_auth = __commonJS({
|
|
|
2068
2068
|
exports2.validateToken = validateToken;
|
|
2069
2069
|
var fs5 = __importStar(require("fs"));
|
|
2070
2070
|
var path7 = __importStar(require("path"));
|
|
2071
|
-
var
|
|
2071
|
+
var os2 = __importStar(require("os"));
|
|
2072
2072
|
var child_process_1 = require("child_process");
|
|
2073
2073
|
var DEFAULT_CONFIG_FILE = "config.json";
|
|
2074
2074
|
function getConfigDir4() {
|
|
2075
|
-
return process.env.EPISODA_CONFIG_DIR || path7.join(
|
|
2075
|
+
return process.env.EPISODA_CONFIG_DIR || path7.join(os2.homedir(), ".episoda");
|
|
2076
2076
|
}
|
|
2077
2077
|
function getConfigPath3(configPath) {
|
|
2078
2078
|
if (configPath) {
|
|
@@ -2541,7 +2541,7 @@ async function startDaemon() {
|
|
|
2541
2541
|
if (!fs2.existsSync(configDir)) {
|
|
2542
2542
|
fs2.mkdirSync(configDir, { recursive: true });
|
|
2543
2543
|
}
|
|
2544
|
-
const daemonScript = path2.join(__dirname, "daemon-process.js");
|
|
2544
|
+
const daemonScript = path2.join(__dirname, "daemon", "daemon-process.js");
|
|
2545
2545
|
if (!fs2.existsSync(daemonScript)) {
|
|
2546
2546
|
throw new Error(`Daemon script not found: ${daemonScript}. Make sure CLI is built.`);
|
|
2547
2547
|
}
|
|
@@ -2923,26 +2923,36 @@ Received ${signal}, shutting down...`);
|
|
|
2923
2923
|
}
|
|
2924
2924
|
|
|
2925
2925
|
// src/commands/auth.ts
|
|
2926
|
-
var
|
|
2926
|
+
var os = __toESM(require("os"));
|
|
2927
2927
|
var fs4 = __toESM(require("fs"));
|
|
2928
2928
|
var path6 = __toESM(require("path"));
|
|
2929
2929
|
var import_child_process4 = require("child_process");
|
|
2930
2930
|
var import_core5 = __toESM(require_dist());
|
|
2931
2931
|
|
|
2932
2932
|
// src/daemon/machine-id.ts
|
|
2933
|
-
var os = __toESM(require("os"));
|
|
2934
2933
|
var fs3 = __toESM(require("fs"));
|
|
2935
2934
|
var path5 = __toESM(require("path"));
|
|
2936
2935
|
var crypto2 = __toESM(require("crypto"));
|
|
2937
2936
|
var import_child_process3 = require("child_process");
|
|
2938
2937
|
var import_core4 = __toESM(require_dist());
|
|
2938
|
+
function isValidUUID(str) {
|
|
2939
|
+
const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
2940
|
+
return uuidRegex.test(str);
|
|
2941
|
+
}
|
|
2939
2942
|
async function getMachineId() {
|
|
2940
2943
|
const machineIdPath = path5.join((0, import_core4.getConfigDir)(), "machine-id");
|
|
2941
2944
|
try {
|
|
2942
2945
|
if (fs3.existsSync(machineIdPath)) {
|
|
2943
|
-
const
|
|
2944
|
-
if (
|
|
2945
|
-
|
|
2946
|
+
const existingId = fs3.readFileSync(machineIdPath, "utf-8").trim();
|
|
2947
|
+
if (existingId) {
|
|
2948
|
+
if (isValidUUID(existingId)) {
|
|
2949
|
+
return existingId;
|
|
2950
|
+
}
|
|
2951
|
+
console.log("[MachineId] Migrating legacy machine ID to UUID format...");
|
|
2952
|
+
const newUUID = generateMachineId();
|
|
2953
|
+
fs3.writeFileSync(machineIdPath, newUUID, "utf-8");
|
|
2954
|
+
console.log(`[MachineId] Migrated: ${existingId} \u2192 ${newUUID}`);
|
|
2955
|
+
return newUUID;
|
|
2946
2956
|
}
|
|
2947
2957
|
}
|
|
2948
2958
|
} catch (error) {
|
|
@@ -3001,10 +3011,21 @@ function getHardwareUUID() {
|
|
|
3001
3011
|
return crypto2.randomUUID();
|
|
3002
3012
|
}
|
|
3003
3013
|
function generateMachineId() {
|
|
3004
|
-
const hostname2 = os.hostname();
|
|
3005
3014
|
const hwUUID = getHardwareUUID();
|
|
3006
|
-
|
|
3007
|
-
|
|
3015
|
+
if (isValidUUID(hwUUID)) {
|
|
3016
|
+
return hwUUID.toLowerCase();
|
|
3017
|
+
}
|
|
3018
|
+
const hash = crypto2.createHash("sha256").update(hwUUID).digest("hex");
|
|
3019
|
+
const uuid = [
|
|
3020
|
+
hash.slice(0, 8),
|
|
3021
|
+
hash.slice(8, 12),
|
|
3022
|
+
"4" + hash.slice(13, 16),
|
|
3023
|
+
// Version 4
|
|
3024
|
+
(parseInt(hash.slice(16, 17), 16) & 3 | 8).toString(16) + hash.slice(17, 20),
|
|
3025
|
+
// Variant
|
|
3026
|
+
hash.slice(20, 32)
|
|
3027
|
+
].join("-");
|
|
3028
|
+
return uuid.toLowerCase();
|
|
3008
3029
|
}
|
|
3009
3030
|
|
|
3010
3031
|
// src/git-helpers/git-credential-helper.ts
|
|
@@ -3330,8 +3351,9 @@ async function authCommand(options = {}) {
|
|
|
3330
3351
|
const apiUrl = options.apiUrl || process.env.EPISODA_API_URL || "https://episoda.dev";
|
|
3331
3352
|
status.info("Initializing Episoda CLI...");
|
|
3332
3353
|
status.info("");
|
|
3354
|
+
const machineId = await getMachineId();
|
|
3333
3355
|
status.info("Step 1/3: Requesting authorization code...");
|
|
3334
|
-
const deviceAuth = await initiateDeviceFlow(apiUrl);
|
|
3356
|
+
const deviceAuth = await initiateDeviceFlow(apiUrl, machineId);
|
|
3335
3357
|
status.success(`\u2713 Authorization code received: ${deviceAuth.user_code}`);
|
|
3336
3358
|
status.info("");
|
|
3337
3359
|
status.info("Step 2/3: Opening browser for authorization...");
|
|
@@ -3347,7 +3369,6 @@ async function authCommand(options = {}) {
|
|
|
3347
3369
|
status.success("\u2713 Authorization successful!");
|
|
3348
3370
|
status.info("");
|
|
3349
3371
|
status.info("Step 3/3: Exchanging authorization for access token...");
|
|
3350
|
-
const machineId = await getMachineId();
|
|
3351
3372
|
const tokenResponse = await exchangeDeviceCode(apiUrl, deviceAuth.device_code, machineId);
|
|
3352
3373
|
status.success("\u2713 Access token received");
|
|
3353
3374
|
status.info(` Project: ${tokenResponse.project_uid}`);
|
|
@@ -3381,13 +3402,16 @@ async function authCommand(options = {}) {
|
|
|
3381
3402
|
status.info(" \u2022 Git operations will use Episoda auth automatically");
|
|
3382
3403
|
status.info("");
|
|
3383
3404
|
}
|
|
3384
|
-
async function initiateDeviceFlow(apiUrl) {
|
|
3405
|
+
async function initiateDeviceFlow(apiUrl, machineId) {
|
|
3385
3406
|
const response = await fetch(`${apiUrl}/api/oauth/code`, {
|
|
3386
3407
|
method: "POST",
|
|
3387
3408
|
headers: {
|
|
3388
3409
|
"Content-Type": "application/json"
|
|
3389
3410
|
},
|
|
3390
|
-
body: JSON.stringify({
|
|
3411
|
+
body: JSON.stringify({
|
|
3412
|
+
machine_id: machineId
|
|
3413
|
+
// EP812: For cookie-based device pairing
|
|
3414
|
+
})
|
|
3391
3415
|
});
|
|
3392
3416
|
if (!response.ok) {
|
|
3393
3417
|
const error = await response.json();
|
|
@@ -3488,7 +3512,7 @@ async function exchangeDeviceCode(apiUrl, deviceCode, machineId) {
|
|
|
3488
3512
|
return tokenResponse;
|
|
3489
3513
|
}
|
|
3490
3514
|
function openBrowser(url) {
|
|
3491
|
-
const platform2 =
|
|
3515
|
+
const platform2 = os.platform();
|
|
3492
3516
|
let command;
|
|
3493
3517
|
let args;
|
|
3494
3518
|
switch (platform2) {
|
|
@@ -3516,7 +3540,7 @@ function openBrowser(url) {
|
|
|
3516
3540
|
}
|
|
3517
3541
|
async function installGitCredentialHelper(apiUrl) {
|
|
3518
3542
|
try {
|
|
3519
|
-
const homeDir =
|
|
3543
|
+
const homeDir = os.homedir();
|
|
3520
3544
|
const episodaBinDir = path6.join(homeDir, ".episoda", "bin");
|
|
3521
3545
|
const helperPath = path6.join(episodaBinDir, "git-credential-episoda");
|
|
3522
3546
|
fs4.mkdirSync(episodaBinDir, { recursive: true });
|
|
@@ -3548,11 +3572,11 @@ async function installGitCredentialHelper(apiUrl) {
|
|
|
3548
3572
|
}
|
|
3549
3573
|
}
|
|
3550
3574
|
function updateShellProfile(binDir) {
|
|
3551
|
-
const platform2 =
|
|
3575
|
+
const platform2 = os.platform();
|
|
3552
3576
|
if (platform2 === "win32") {
|
|
3553
3577
|
return;
|
|
3554
3578
|
}
|
|
3555
|
-
const homeDir =
|
|
3579
|
+
const homeDir = os.homedir();
|
|
3556
3580
|
const profiles = [
|
|
3557
3581
|
path6.join(homeDir, ".bashrc"),
|
|
3558
3582
|
path6.join(homeDir, ".zshrc"),
|