flightdesk 0.2.3 → 0.2.5
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/main.js +211 -67
- package/main.js.map +3 -3
- package/package.json +1 -1
package/main.js
CHANGED
|
@@ -3059,9 +3059,6 @@ function loadConfig() {
|
|
|
3059
3059
|
if (fs.existsSync(CONFIG_FILE)) {
|
|
3060
3060
|
const content = fs.readFileSync(CONFIG_FILE, "utf-8");
|
|
3061
3061
|
const parsed = JSON.parse(content);
|
|
3062
|
-
if (parsed.organizations?.[0]?.apiKey) {
|
|
3063
|
-
return migrateOldConfig(parsed);
|
|
3064
|
-
}
|
|
3065
3062
|
return {
|
|
3066
3063
|
organizations: [],
|
|
3067
3064
|
repoMapping: {},
|
|
@@ -3076,22 +3073,6 @@ function loadConfig() {
|
|
|
3076
3073
|
repoMapping: {}
|
|
3077
3074
|
};
|
|
3078
3075
|
}
|
|
3079
|
-
function migrateOldConfig(oldConfig) {
|
|
3080
|
-
console.log("\u{1F4E6} Migrating config to new format...");
|
|
3081
|
-
const defaultOrg = oldConfig.defaultOrganization ? oldConfig.organizations.find((o) => o.id === oldConfig.defaultOrganization) : oldConfig.organizations[0];
|
|
3082
|
-
const newConfig = {
|
|
3083
|
-
apiKey: defaultOrg?.apiKey,
|
|
3084
|
-
activeOrganization: defaultOrg?.id,
|
|
3085
|
-
organizations: oldConfig.organizations.map((o) => ({
|
|
3086
|
-
id: o.id,
|
|
3087
|
-
name: o.name
|
|
3088
|
-
})),
|
|
3089
|
-
repoMapping: oldConfig.repoMapping || {}
|
|
3090
|
-
};
|
|
3091
|
-
saveConfig(newConfig);
|
|
3092
|
-
console.log("\u2705 Config migrated successfully");
|
|
3093
|
-
return newConfig;
|
|
3094
|
-
}
|
|
3095
3076
|
function saveConfig(config) {
|
|
3096
3077
|
fs.writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2));
|
|
3097
3078
|
}
|
|
@@ -3162,6 +3143,9 @@ var readline = __toESM(require("readline"));
|
|
|
3162
3143
|
// apps/cli/src/lib/api.ts
|
|
3163
3144
|
var FlightDeskAPI = class _FlightDeskAPI {
|
|
3164
3145
|
constructor(config, org2) {
|
|
3146
|
+
if (!config.apiKey) {
|
|
3147
|
+
throw new Error("API key is required. Run: flightdesk login");
|
|
3148
|
+
}
|
|
3165
3149
|
this.apiUrl = getApiUrl();
|
|
3166
3150
|
this.apiKey = config.apiKey;
|
|
3167
3151
|
this.organizationId = org2.id;
|
|
@@ -3173,6 +3157,12 @@ var FlightDeskAPI = class _FlightDeskAPI {
|
|
|
3173
3157
|
return new _FlightDeskAPI(config, org2);
|
|
3174
3158
|
}
|
|
3175
3159
|
async graphql(query, variables) {
|
|
3160
|
+
const verbose = process.env.FLIGHTDESK_DEBUG === "1";
|
|
3161
|
+
if (verbose) {
|
|
3162
|
+
console.log("\n--- GraphQL Request ---");
|
|
3163
|
+
console.log("URL:", `${this.apiUrl}/graphql`);
|
|
3164
|
+
console.log("Variables:", JSON.stringify(variables, null, 2));
|
|
3165
|
+
}
|
|
3176
3166
|
const response = await fetch(`${this.apiUrl}/graphql`, {
|
|
3177
3167
|
method: "POST",
|
|
3178
3168
|
headers: {
|
|
@@ -3182,9 +3172,19 @@ var FlightDeskAPI = class _FlightDeskAPI {
|
|
|
3182
3172
|
body: JSON.stringify({ query, variables })
|
|
3183
3173
|
});
|
|
3184
3174
|
if (!response.ok) {
|
|
3185
|
-
|
|
3175
|
+
const body = await response.text();
|
|
3176
|
+
if (verbose) {
|
|
3177
|
+
console.log("--- Error Response ---");
|
|
3178
|
+
console.log("Status:", response.status, response.statusText);
|
|
3179
|
+
console.log("Body:", body);
|
|
3180
|
+
}
|
|
3181
|
+
throw new Error(`API request failed: ${response.status} ${response.statusText}${verbose ? "" : " (set FLIGHTDESK_DEBUG=1 for details)"}`);
|
|
3186
3182
|
}
|
|
3187
3183
|
const result = await response.json();
|
|
3184
|
+
if (verbose) {
|
|
3185
|
+
console.log("--- Response ---");
|
|
3186
|
+
console.log(JSON.stringify(result, null, 2));
|
|
3187
|
+
}
|
|
3188
3188
|
if (result.errors && result.errors.length > 0) {
|
|
3189
3189
|
throw new Error(`GraphQL error: ${result.errors.map((e) => e.message).join(", ")}`);
|
|
3190
3190
|
}
|
|
@@ -3577,7 +3577,51 @@ var path2 = __toESM(require("node:path"));
|
|
|
3577
3577
|
var os2 = __toESM(require("node:os"));
|
|
3578
3578
|
var fs2 = __toESM(require("node:fs"));
|
|
3579
3579
|
var readline2 = __toESM(require("node:readline"));
|
|
3580
|
+
var import_node_child_process = require("node:child_process");
|
|
3580
3581
|
var playwright = null;
|
|
3582
|
+
var PlaywrightBrowserNotInstalledError = class extends Error {
|
|
3583
|
+
constructor(autoInstallError) {
|
|
3584
|
+
const baseMessage = "Playwright browser not installed.";
|
|
3585
|
+
const autoInstallInfo = autoInstallError ? `
|
|
3586
|
+
|
|
3587
|
+
Auto-install failed: ${autoInstallError}
|
|
3588
|
+
` : "\n\n";
|
|
3589
|
+
super(
|
|
3590
|
+
baseMessage + autoInstallInfo + "Run one of the following commands:\n\n npx playwright install chromium # Just Chromium (recommended)\n npx playwright install # All browsers\n\nThen retry your command."
|
|
3591
|
+
);
|
|
3592
|
+
this.name = "PlaywrightBrowserNotInstalledError";
|
|
3593
|
+
}
|
|
3594
|
+
};
|
|
3595
|
+
function isBrowserNotInstalledError(error) {
|
|
3596
|
+
if (!(error instanceof Error)) return false;
|
|
3597
|
+
return error.message.includes("Executable doesn't exist") || error.message.includes("browserType.launch") || error.message.includes("npx playwright install");
|
|
3598
|
+
}
|
|
3599
|
+
var autoInstallAttempted = false;
|
|
3600
|
+
function tryAutoInstallBrowsers() {
|
|
3601
|
+
if (autoInstallAttempted) {
|
|
3602
|
+
return false;
|
|
3603
|
+
}
|
|
3604
|
+
autoInstallAttempted = true;
|
|
3605
|
+
console.log("");
|
|
3606
|
+
console.log("\u{1F4E6} Playwright browser not found. Installing automatically...");
|
|
3607
|
+
console.log("");
|
|
3608
|
+
try {
|
|
3609
|
+
(0, import_node_child_process.execSync)("npx playwright install chromium", {
|
|
3610
|
+
stdio: "inherit",
|
|
3611
|
+
timeout: 12e4
|
|
3612
|
+
// 2 minute timeout
|
|
3613
|
+
});
|
|
3614
|
+
console.log("");
|
|
3615
|
+
console.log("\u2705 Browser installed successfully!");
|
|
3616
|
+
console.log("");
|
|
3617
|
+
return true;
|
|
3618
|
+
} catch (error) {
|
|
3619
|
+
console.error("");
|
|
3620
|
+
console.error("\u274C Auto-install failed:", error instanceof Error ? error.message : String(error));
|
|
3621
|
+
console.error("");
|
|
3622
|
+
return false;
|
|
3623
|
+
}
|
|
3624
|
+
}
|
|
3581
3625
|
var USER_DATA_DIR = path2.join(os2.homedir(), ".flightdesk", "chromium-profile");
|
|
3582
3626
|
var STORAGE_STATE_FILE = path2.join(os2.homedir(), ".flightdesk", "auth-state.json");
|
|
3583
3627
|
var PersistentBrowser = class {
|
|
@@ -3587,18 +3631,47 @@ var PersistentBrowser = class {
|
|
|
3587
3631
|
this.page = null;
|
|
3588
3632
|
this.headless = headless;
|
|
3589
3633
|
}
|
|
3634
|
+
/**
|
|
3635
|
+
* Get page, throwing if not initialized
|
|
3636
|
+
*/
|
|
3637
|
+
get activePage() {
|
|
3638
|
+
if (!this.page) {
|
|
3639
|
+
throw new Error("Browser not initialized. Call init() first.");
|
|
3640
|
+
}
|
|
3641
|
+
return this.page;
|
|
3642
|
+
}
|
|
3590
3643
|
/**
|
|
3591
3644
|
* Initialize the browser context (if not already initialized)
|
|
3592
3645
|
*/
|
|
3593
3646
|
async init() {
|
|
3594
3647
|
if (this.context) return;
|
|
3595
|
-
if (!await isPlaywrightAvailable()) {
|
|
3648
|
+
if (!await isPlaywrightAvailable() || !playwright) {
|
|
3596
3649
|
throw new Error("Playwright not available");
|
|
3597
3650
|
}
|
|
3598
3651
|
ensureUserDataDir();
|
|
3599
|
-
|
|
3600
|
-
|
|
3601
|
-
|
|
3652
|
+
try {
|
|
3653
|
+
this.browser = await playwright.chromium.launch({
|
|
3654
|
+
headless: this.headless
|
|
3655
|
+
});
|
|
3656
|
+
} catch (error) {
|
|
3657
|
+
if (isBrowserNotInstalledError(error)) {
|
|
3658
|
+
if (tryAutoInstallBrowsers()) {
|
|
3659
|
+
try {
|
|
3660
|
+
this.browser = await playwright.chromium.launch({
|
|
3661
|
+
headless: this.headless
|
|
3662
|
+
});
|
|
3663
|
+
} catch (retryError) {
|
|
3664
|
+
throw new PlaywrightBrowserNotInstalledError(
|
|
3665
|
+
retryError instanceof Error ? retryError.message : String(retryError)
|
|
3666
|
+
);
|
|
3667
|
+
}
|
|
3668
|
+
} else {
|
|
3669
|
+
throw new PlaywrightBrowserNotInstalledError();
|
|
3670
|
+
}
|
|
3671
|
+
} else {
|
|
3672
|
+
throw error;
|
|
3673
|
+
}
|
|
3674
|
+
}
|
|
3602
3675
|
const hasAuthState = fs2.existsSync(STORAGE_STATE_FILE);
|
|
3603
3676
|
const contextOptions = {
|
|
3604
3677
|
viewport: { width: 1280, height: 720 },
|
|
@@ -3617,9 +3690,9 @@ var PersistentBrowser = class {
|
|
|
3617
3690
|
async checkAuth() {
|
|
3618
3691
|
await this.init();
|
|
3619
3692
|
try {
|
|
3620
|
-
await this.
|
|
3621
|
-
await this.
|
|
3622
|
-
const url = this.
|
|
3693
|
+
await this.activePage.goto("https://claude.ai/", { waitUntil: "domcontentloaded", timeout: 3e4 });
|
|
3694
|
+
await this.activePage.waitForTimeout(2e3);
|
|
3695
|
+
const url = this.activePage.url();
|
|
3623
3696
|
console.log(" Final URL:", url);
|
|
3624
3697
|
return !url.includes("/login") && !url.includes("/oauth") && !url.includes("accounts.google") && url.includes("claude.ai");
|
|
3625
3698
|
} catch (error) {
|
|
@@ -3693,7 +3766,26 @@ async function launchBrowser(headless) {
|
|
|
3693
3766
|
throw new Error("Playwright not available");
|
|
3694
3767
|
}
|
|
3695
3768
|
ensureUserDataDir();
|
|
3696
|
-
|
|
3769
|
+
let browser;
|
|
3770
|
+
try {
|
|
3771
|
+
browser = await playwright.chromium.launch({ headless });
|
|
3772
|
+
} catch (error) {
|
|
3773
|
+
if (isBrowserNotInstalledError(error)) {
|
|
3774
|
+
if (tryAutoInstallBrowsers()) {
|
|
3775
|
+
try {
|
|
3776
|
+
browser = await playwright.chromium.launch({ headless });
|
|
3777
|
+
} catch (retryError) {
|
|
3778
|
+
throw new PlaywrightBrowserNotInstalledError(
|
|
3779
|
+
retryError instanceof Error ? retryError.message : String(retryError)
|
|
3780
|
+
);
|
|
3781
|
+
}
|
|
3782
|
+
} else {
|
|
3783
|
+
throw new PlaywrightBrowserNotInstalledError();
|
|
3784
|
+
}
|
|
3785
|
+
} else {
|
|
3786
|
+
throw error;
|
|
3787
|
+
}
|
|
3788
|
+
}
|
|
3697
3789
|
const hasAuthState = fs2.existsSync(STORAGE_STATE_FILE);
|
|
3698
3790
|
const contextOptions = {
|
|
3699
3791
|
viewport: { width: 1280, height: 720 },
|
|
@@ -3713,7 +3805,7 @@ async function checkAuth() {
|
|
|
3713
3805
|
try {
|
|
3714
3806
|
const page = await context.newPage();
|
|
3715
3807
|
page.setDefaultTimeout(3e4);
|
|
3716
|
-
await page.goto("https://claude.ai/", { waitUntil: "
|
|
3808
|
+
await page.goto("https://claude.ai/", { waitUntil: "domcontentloaded", timeout: 3e4 });
|
|
3717
3809
|
await page.waitForTimeout(2e3);
|
|
3718
3810
|
const url = page.url();
|
|
3719
3811
|
console.log(" Final URL:", url);
|
|
@@ -3776,7 +3868,7 @@ async function scrapeSession(page, sessionUrl, options = {}) {
|
|
|
3776
3868
|
const { timeout = 3e4, autoPr = false } = options;
|
|
3777
3869
|
try {
|
|
3778
3870
|
page.setDefaultTimeout(timeout);
|
|
3779
|
-
await page.goto(sessionUrl, { waitUntil: "
|
|
3871
|
+
await page.goto(sessionUrl, { waitUntil: "domcontentloaded", timeout });
|
|
3780
3872
|
await page.waitForSelector('[data-testid="conversation-turn"], .code-spinner-animate, button:has-text("Create PR")', {
|
|
3781
3873
|
timeout: 1e4
|
|
3782
3874
|
}).catch(() => {
|
|
@@ -3906,7 +3998,23 @@ async function detectActiveSpinner(page) {
|
|
|
3906
3998
|
try {
|
|
3907
3999
|
const spinner = await page.$(".code-spinner-animate");
|
|
3908
4000
|
if (spinner) {
|
|
3909
|
-
|
|
4001
|
+
const isVisibleAndAnimating = await spinner.evaluate((el) => {
|
|
4002
|
+
const style = globalThis.getComputedStyle(el);
|
|
4003
|
+
if (style.display === "none" || style.visibility === "hidden" || style.opacity === "0") {
|
|
4004
|
+
return false;
|
|
4005
|
+
}
|
|
4006
|
+
if (style.animationName && style.animationName !== "none") {
|
|
4007
|
+
return true;
|
|
4008
|
+
}
|
|
4009
|
+
if (style.animationPlayState === "paused") {
|
|
4010
|
+
return false;
|
|
4011
|
+
}
|
|
4012
|
+
const rect = el.getBoundingClientRect();
|
|
4013
|
+
return rect.width > 0 && rect.height > 0;
|
|
4014
|
+
});
|
|
4015
|
+
if (isVisibleAndAnimating) {
|
|
4016
|
+
return true;
|
|
4017
|
+
}
|
|
3910
4018
|
}
|
|
3911
4019
|
const spinnerByContent = await page.$('span:has-text("\u273D")');
|
|
3912
4020
|
if (spinnerByContent) {
|
|
@@ -3915,10 +4023,19 @@ async function detectActiveSpinner(page) {
|
|
|
3915
4023
|
while (current) {
|
|
3916
4024
|
const classList = current.classList;
|
|
3917
4025
|
if (classList?.contains("code-spinner-animate")) {
|
|
3918
|
-
|
|
4026
|
+
const style2 = globalThis.getComputedStyle(current);
|
|
4027
|
+
if (style2.display === "none" || style2.visibility === "hidden" || style2.opacity === "0") {
|
|
4028
|
+
current = current.parentElement;
|
|
4029
|
+
continue;
|
|
4030
|
+
}
|
|
4031
|
+
if (style2.animationPlayState === "paused") {
|
|
4032
|
+
current = current.parentElement;
|
|
4033
|
+
continue;
|
|
4034
|
+
}
|
|
4035
|
+
return style2.animationName !== "none";
|
|
3919
4036
|
}
|
|
3920
4037
|
const style = globalThis.getComputedStyle(current);
|
|
3921
|
-
if (style.animationName && style.animationName !== "none") {
|
|
4038
|
+
if (style.animationName && style.animationName !== "none" && style.animationPlayState !== "paused") {
|
|
3922
4039
|
return true;
|
|
3923
4040
|
}
|
|
3924
4041
|
current = current.parentElement;
|
|
@@ -3945,30 +4062,48 @@ async function authCommand() {
|
|
|
3945
4062
|
console.log(`Profile directory: ${USER_DATA_DIR}
|
|
3946
4063
|
`);
|
|
3947
4064
|
console.log("Checking current authentication status...");
|
|
3948
|
-
|
|
3949
|
-
|
|
3950
|
-
|
|
3951
|
-
|
|
3952
|
-
|
|
4065
|
+
try {
|
|
4066
|
+
const isAuthenticated = await checkAuth();
|
|
4067
|
+
if (isAuthenticated) {
|
|
4068
|
+
console.log("\u2705 Already logged in to Claude!");
|
|
4069
|
+
console.log("\nThe watch daemon will be able to monitor your sessions.");
|
|
4070
|
+
return;
|
|
4071
|
+
}
|
|
4072
|
+
} catch (error) {
|
|
4073
|
+
if (error instanceof PlaywrightBrowserNotInstalledError) {
|
|
4074
|
+
console.error("");
|
|
4075
|
+
console.error("\u274C " + error.message);
|
|
4076
|
+
process.exit(1);
|
|
4077
|
+
}
|
|
4078
|
+
throw error;
|
|
3953
4079
|
}
|
|
3954
4080
|
console.log("\u274C Not logged in to Claude.\n");
|
|
3955
4081
|
console.log("Opening browser for login...");
|
|
3956
4082
|
console.log("Please log in to your Claude account.\n");
|
|
3957
|
-
|
|
3958
|
-
|
|
3959
|
-
|
|
3960
|
-
|
|
3961
|
-
|
|
3962
|
-
|
|
3963
|
-
|
|
4083
|
+
try {
|
|
4084
|
+
const loginSuccessful = await openForLogin();
|
|
4085
|
+
if (loginSuccessful) {
|
|
4086
|
+
console.log("\n\u2705 Successfully logged in!");
|
|
4087
|
+
console.log("The watch daemon can now monitor your Claude Code sessions.");
|
|
4088
|
+
} else {
|
|
4089
|
+
console.log("\n\u274C Login was not detected.");
|
|
4090
|
+
console.log("Please try again with: flightdesk auth");
|
|
4091
|
+
}
|
|
4092
|
+
} catch (error) {
|
|
4093
|
+
if (error instanceof PlaywrightBrowserNotInstalledError) {
|
|
4094
|
+
console.error("");
|
|
4095
|
+
console.error("\u274C " + error.message);
|
|
4096
|
+
process.exit(1);
|
|
4097
|
+
}
|
|
4098
|
+
throw error;
|
|
3964
4099
|
}
|
|
3965
4100
|
}
|
|
3966
4101
|
|
|
3967
4102
|
// apps/cli/src/lib/git.ts
|
|
3968
|
-
var
|
|
4103
|
+
var import_node_child_process2 = require("node:child_process");
|
|
3969
4104
|
function detectGitRepo() {
|
|
3970
4105
|
try {
|
|
3971
|
-
const remoteUrl = (0,
|
|
4106
|
+
const remoteUrl = (0, import_node_child_process2.execSync)("git remote get-url origin", {
|
|
3972
4107
|
encoding: "utf-8",
|
|
3973
4108
|
stdio: ["pipe", "pipe", "pipe"]
|
|
3974
4109
|
}).trim();
|
|
@@ -3976,7 +4111,7 @@ function detectGitRepo() {
|
|
|
3976
4111
|
if (!repoFullName) {
|
|
3977
4112
|
return null;
|
|
3978
4113
|
}
|
|
3979
|
-
const branch = (0,
|
|
4114
|
+
const branch = (0, import_node_child_process2.execSync)("git rev-parse --abbrev-ref HEAD", {
|
|
3980
4115
|
encoding: "utf-8",
|
|
3981
4116
|
stdio: ["pipe", "pipe", "pipe"]
|
|
3982
4117
|
}).trim();
|
|
@@ -4254,16 +4389,25 @@ async function watchCommand(options) {
|
|
|
4254
4389
|
} else {
|
|
4255
4390
|
browser = new PersistentBrowser(options.headless !== false);
|
|
4256
4391
|
console.log("Checking Claude authentication...");
|
|
4257
|
-
|
|
4258
|
-
|
|
4259
|
-
|
|
4260
|
-
|
|
4261
|
-
|
|
4262
|
-
|
|
4263
|
-
|
|
4264
|
-
|
|
4265
|
-
|
|
4266
|
-
|
|
4392
|
+
try {
|
|
4393
|
+
const isAuthenticated = await browser.checkAuth();
|
|
4394
|
+
if (!isAuthenticated) {
|
|
4395
|
+
console.log("\u26A0\uFE0F Not logged into Claude. Run: flightdesk auth");
|
|
4396
|
+
console.log("");
|
|
4397
|
+
await browser.close();
|
|
4398
|
+
browser = null;
|
|
4399
|
+
} else {
|
|
4400
|
+
console.log("\u2705 Playwright ready, Claude authenticated");
|
|
4401
|
+
console.log(" (Browser session kept alive for monitoring)");
|
|
4402
|
+
console.log("");
|
|
4403
|
+
}
|
|
4404
|
+
} catch (error) {
|
|
4405
|
+
if (error instanceof PlaywrightBrowserNotInstalledError) {
|
|
4406
|
+
console.error("");
|
|
4407
|
+
console.error("\u274C " + error.message);
|
|
4408
|
+
process.exit(1);
|
|
4409
|
+
}
|
|
4410
|
+
throw error;
|
|
4267
4411
|
}
|
|
4268
4412
|
}
|
|
4269
4413
|
const api = FlightDeskAPI.fromConfig(config, org2);
|
|
@@ -5214,7 +5358,7 @@ async function scanClaudeSessions(options) {
|
|
|
5214
5358
|
}
|
|
5215
5359
|
|
|
5216
5360
|
// apps/cli/src/commands/project.ts
|
|
5217
|
-
async function projectCommand(action,
|
|
5361
|
+
async function projectCommand(action, _options) {
|
|
5218
5362
|
const { config, org: org2 } = requireActiveOrg();
|
|
5219
5363
|
const api = FlightDeskAPI.fromConfig(config, org2);
|
|
5220
5364
|
switch (action) {
|
|
@@ -5245,7 +5389,7 @@ ${projects.length} project(s)`);
|
|
|
5245
5389
|
}
|
|
5246
5390
|
|
|
5247
5391
|
// apps/cli/src/commands/preview.ts
|
|
5248
|
-
var
|
|
5392
|
+
var import_node_child_process3 = require("node:child_process");
|
|
5249
5393
|
var path3 = __toESM(require("node:path"));
|
|
5250
5394
|
var os3 = __toESM(require("node:os"));
|
|
5251
5395
|
var fs4 = __toESM(require("node:fs"));
|
|
@@ -5351,7 +5495,7 @@ async function handleLogs(api, options) {
|
|
|
5351
5495
|
`);
|
|
5352
5496
|
validateSSHParams(instance);
|
|
5353
5497
|
const sshCommand = `docker logs -f ${instance.containerId}`;
|
|
5354
|
-
const ssh = (0,
|
|
5498
|
+
const ssh = (0, import_node_child_process3.spawn)("ssh", [
|
|
5355
5499
|
"-o",
|
|
5356
5500
|
"StrictHostKeyChecking=no",
|
|
5357
5501
|
"-o",
|
|
@@ -5391,7 +5535,7 @@ async function handleMount(api, options) {
|
|
|
5391
5535
|
await new Promise((resolve) => setTimeout(resolve, 3e3));
|
|
5392
5536
|
}
|
|
5393
5537
|
try {
|
|
5394
|
-
(0,
|
|
5538
|
+
(0, import_node_child_process3.execSync)("which sshfs", { stdio: "ignore" });
|
|
5395
5539
|
} catch {
|
|
5396
5540
|
console.error("\u274C sshfs is not installed.");
|
|
5397
5541
|
console.error("");
|
|
@@ -5412,7 +5556,7 @@ async function handleMount(api, options) {
|
|
|
5412
5556
|
fs4.mkdirSync(mountDir, { recursive: true });
|
|
5413
5557
|
}
|
|
5414
5558
|
try {
|
|
5415
|
-
const mounted = (0,
|
|
5559
|
+
const mounted = (0, import_node_child_process3.execSync)("mount", { encoding: "utf8" });
|
|
5416
5560
|
if (mounted.includes(mountDir)) {
|
|
5417
5561
|
console.log(`\u{1F4C1} Already mounted at ${mountDir}`);
|
|
5418
5562
|
return;
|
|
@@ -5438,7 +5582,7 @@ async function handleMount(api, options) {
|
|
|
5438
5582
|
mountDir
|
|
5439
5583
|
];
|
|
5440
5584
|
try {
|
|
5441
|
-
const result = (0,
|
|
5585
|
+
const result = (0, import_node_child_process3.spawnSync)("sshfs", sshfsArgs, { stdio: "inherit" });
|
|
5442
5586
|
if (result.status !== 0) {
|
|
5443
5587
|
throw new Error(`sshfs exited with code ${result.status}`);
|
|
5444
5588
|
}
|
|
@@ -5472,9 +5616,9 @@ async function handleUnmount(_api, options) {
|
|
|
5472
5616
|
try {
|
|
5473
5617
|
let result;
|
|
5474
5618
|
if (process.platform === "darwin") {
|
|
5475
|
-
result = (0,
|
|
5619
|
+
result = (0, import_node_child_process3.spawnSync)("umount", [mountDir], { stdio: "inherit" });
|
|
5476
5620
|
} else {
|
|
5477
|
-
result = (0,
|
|
5621
|
+
result = (0, import_node_child_process3.spawnSync)("fusermount", ["-u", mountDir], { stdio: "inherit" });
|
|
5478
5622
|
}
|
|
5479
5623
|
if (result.status !== 0) {
|
|
5480
5624
|
throw new Error(`Unmount exited with code ${result.status}`);
|
|
@@ -5514,7 +5658,7 @@ async function handleTeardown(api, options) {
|
|
|
5514
5658
|
|
|
5515
5659
|
// apps/cli/src/main.ts
|
|
5516
5660
|
var program2 = new Command();
|
|
5517
|
-
program2.name("flightdesk").description("FlightDesk CLI - AI task management for Claude Code sessions").version("0.2.
|
|
5661
|
+
program2.name("flightdesk").description("FlightDesk CLI - AI task management for Claude Code sessions").version("0.2.5").option("--dev", "Use local development API (localhost:3000)").option("--api <url>", "Use custom API URL");
|
|
5518
5662
|
program2.hook("preAction", () => {
|
|
5519
5663
|
const opts = program2.opts();
|
|
5520
5664
|
if (opts.api) {
|