@anvil-works/anvil-cli 0.4.0 → 0.4.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 +280 -233
- package/dist/index.js +213 -81
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -42545,30 +42545,6 @@ var __webpack_exports__ = {};
|
|
|
42545
42545
|
if (/^https?:\/\//.test(url)) return url;
|
|
42546
42546
|
return `https://${url}`;
|
|
42547
42547
|
}
|
|
42548
|
-
async function detectAnvilUrlFromRemotes(repoPath) {
|
|
42549
|
-
try {
|
|
42550
|
-
const git = esm_default(repoPath);
|
|
42551
|
-
const remotes = await git.getRemotes(true);
|
|
42552
|
-
for (const remote of remotes){
|
|
42553
|
-
const fetchUrl = remote.refs.fetch;
|
|
42554
|
-
if (!fetchUrl) continue;
|
|
42555
|
-
const httpMatch = fetchUrl.match(/(https?:\/\/[^\/]+)\/git\/[A-Z0-9]+\.git/);
|
|
42556
|
-
if (httpMatch) return {
|
|
42557
|
-
url: normalizeAnvilUrl(httpMatch[1])
|
|
42558
|
-
};
|
|
42559
|
-
const sshMatch = fetchUrl.match(/ssh:\/\/([^@]+)@([^:]+):(\d+)\/(?:git\/)?([A-Z0-9]+)\.git/);
|
|
42560
|
-
if (sshMatch) {
|
|
42561
|
-
const username = decodeURIComponent(sshMatch[1]);
|
|
42562
|
-
const hostname = sshMatch[2];
|
|
42563
|
-
return {
|
|
42564
|
-
url: normalizeAnvilUrl(hostname),
|
|
42565
|
-
username
|
|
42566
|
-
};
|
|
42567
|
-
}
|
|
42568
|
-
}
|
|
42569
|
-
} catch (_e) {}
|
|
42570
|
-
return null;
|
|
42571
|
-
}
|
|
42572
42548
|
function resolveAnvilUrl() {
|
|
42573
42549
|
const fromConfig = getConfig("anvilUrl");
|
|
42574
42550
|
if ("string" == typeof fromConfig && fromConfig.trim()) return fromConfig.trim();
|
|
@@ -47410,38 +47386,36 @@ var __webpack_exports__ = {};
|
|
|
47410
47386
|
return null;
|
|
47411
47387
|
}
|
|
47412
47388
|
}
|
|
47413
|
-
|
|
47414
|
-
|
|
47415
|
-
|
|
47416
|
-
|
|
47417
|
-
|
|
47418
|
-
|
|
47419
|
-
|
|
47420
|
-
|
|
47421
|
-
|
|
47422
|
-
|
|
47423
|
-
|
|
47424
|
-
|
|
47425
|
-
|
|
47426
|
-
|
|
47427
|
-
|
|
47428
|
-
|
|
47429
|
-
|
|
47430
|
-
|
|
47431
|
-
|
|
47432
|
-
|
|
47433
|
-
|
|
47434
|
-
|
|
47435
|
-
|
|
47436
|
-
|
|
47437
|
-
|
|
47438
|
-
|
|
47439
|
-
|
|
47440
|
-
|
|
47441
|
-
|
|
47442
|
-
|
|
47443
|
-
} catch (_e) {}
|
|
47444
|
-
return out;
|
|
47389
|
+
function filterCandidates(candidates, explicitUrl, explicitUsername) {
|
|
47390
|
+
let filtered = candidates;
|
|
47391
|
+
if (explicitUrl) {
|
|
47392
|
+
const normalizedExplicit = normalizeAnvilUrl(explicitUrl);
|
|
47393
|
+
filtered = filtered.filter((c)=>c.detectedUrl && normalizeAnvilUrl(c.detectedUrl) === normalizedExplicit);
|
|
47394
|
+
}
|
|
47395
|
+
if (explicitUsername) filtered = filtered.filter((c)=>!c.detectedUsername || c.detectedUsername === explicitUsername);
|
|
47396
|
+
return filtered;
|
|
47397
|
+
}
|
|
47398
|
+
function formatCandidateLabel(candidate) {
|
|
47399
|
+
const parts = [
|
|
47400
|
+
candidate.appId
|
|
47401
|
+
];
|
|
47402
|
+
if (candidate.detectedUrl) if (candidate.detectedUsername) parts.push(`(${candidate.detectedUsername} on ${candidate.detectedUrl})`);
|
|
47403
|
+
else parts.push(`(${candidate.detectedUrl})`);
|
|
47404
|
+
parts.push(`- ${candidate.description}`);
|
|
47405
|
+
return parts.join(" ");
|
|
47406
|
+
}
|
|
47407
|
+
function lookupRemoteInfoForAppId(appId, detectedRemotes) {
|
|
47408
|
+
const matches = detectedRemotes.filter((c)=>c.appId === appId);
|
|
47409
|
+
if (0 === matches.length) return {};
|
|
47410
|
+
const withUsername = matches.find((c)=>c.detectedUsername);
|
|
47411
|
+
if (withUsername) return {
|
|
47412
|
+
detectedUrl: withUsername.detectedUrl,
|
|
47413
|
+
detectedUsername: withUsername.detectedUsername
|
|
47414
|
+
};
|
|
47415
|
+
return {
|
|
47416
|
+
detectedUrl: matches[0].detectedUrl,
|
|
47417
|
+
detectedUsername: matches[0].detectedUsername
|
|
47418
|
+
};
|
|
47445
47419
|
}
|
|
47446
47420
|
async function detectAppIdsFromAllRemotes(repoPath) {
|
|
47447
47421
|
const git = esm_default(repoPath);
|
|
@@ -47477,11 +47451,13 @@ var __webpack_exports__ = {};
|
|
|
47477
47451
|
} catch (_e) {}
|
|
47478
47452
|
return out;
|
|
47479
47453
|
}
|
|
47480
|
-
async function detectAppIdsByCommitLookup(repoPath,
|
|
47454
|
+
async function detectAppIdsByCommitLookup(repoPath, options) {
|
|
47455
|
+
const anvilUrl = options.anvilUrl || resolveAnvilUrl();
|
|
47456
|
+
const username = options.username;
|
|
47481
47457
|
const git = esm_default(repoPath);
|
|
47482
47458
|
const out = [];
|
|
47483
47459
|
try {
|
|
47484
|
-
const authToken = await auth_getValidAuthToken(anvilUrl);
|
|
47460
|
+
const authToken = await auth_getValidAuthToken(anvilUrl, username);
|
|
47485
47461
|
const branchRef = await git.revparse([
|
|
47486
47462
|
"--abbrev-ref",
|
|
47487
47463
|
"HEAD"
|
|
@@ -47520,16 +47496,6 @@ var __webpack_exports__ = {};
|
|
|
47520
47496
|
} catch (_e) {}
|
|
47521
47497
|
return out;
|
|
47522
47498
|
}
|
|
47523
|
-
async function detectAppIds(repoPath, options = {}) {
|
|
47524
|
-
const anvilUrl = options.anvilUrl || resolveAnvilUrl();
|
|
47525
|
-
const results = [];
|
|
47526
|
-
const includeReverseLookup = options.includeReverseLookup ?? true;
|
|
47527
|
-
results.push(...await detectAppIdsFromRemotes(repoPath, anvilUrl));
|
|
47528
|
-
if (0 === results.length && includeReverseLookup) results.push(...await detectAppIdsByCommitLookup(repoPath, anvilUrl));
|
|
47529
|
-
const seen = new Set();
|
|
47530
|
-
const unique = results.filter((c)=>seen.has(c.appId) ? false : (seen.add(c.appId), true));
|
|
47531
|
-
return unique;
|
|
47532
|
-
}
|
|
47533
47499
|
class WebSocketClient extends Emitter_Emitter {
|
|
47534
47500
|
ws = null;
|
|
47535
47501
|
appId;
|
|
@@ -47540,9 +47506,15 @@ var __webpack_exports__ = {};
|
|
|
47540
47506
|
username;
|
|
47541
47507
|
reconnectAttempts = 0;
|
|
47542
47508
|
reconnectTimer = null;
|
|
47509
|
+
heartbeatTimer = null;
|
|
47510
|
+
pongTimeoutTimer = null;
|
|
47511
|
+
reconnectDelayMs;
|
|
47512
|
+
isClosing = false;
|
|
47543
47513
|
sessionId;
|
|
47544
|
-
|
|
47545
|
-
|
|
47514
|
+
RECONNECT_DELAY_BASE_MS = 5000;
|
|
47515
|
+
RECONNECT_DELAY_MAX_MS = 60000;
|
|
47516
|
+
HEARTBEAT_INTERVAL_MS = 30000;
|
|
47517
|
+
HEARTBEAT_TIMEOUT_MS = 10000;
|
|
47546
47518
|
constructor(options){
|
|
47547
47519
|
super();
|
|
47548
47520
|
this.appId = options.appId;
|
|
@@ -47552,12 +47524,14 @@ var __webpack_exports__ = {};
|
|
|
47552
47524
|
this.editSession = options.editSession;
|
|
47553
47525
|
this.username = options.username;
|
|
47554
47526
|
this.sessionId = Math.random().toString(36).substring(2, 10);
|
|
47527
|
+
this.reconnectDelayMs = this.RECONNECT_DELAY_BASE_MS;
|
|
47555
47528
|
}
|
|
47556
47529
|
async connect() {
|
|
47530
|
+
this.isClosing = false;
|
|
47557
47531
|
if (this.ws?.readyState === ws_wrapper.OPEN) return void logger_logger.debug(`[WebSocket ${this.sessionId}]`, "WebSocket already open, skipping connection");
|
|
47558
47532
|
if (this.ws) {
|
|
47559
47533
|
logger_logger.debug(`[WebSocket ${this.sessionId}]`, "Closing existing WebSocket before reconnecting");
|
|
47560
|
-
this.
|
|
47534
|
+
this.teardownSocket();
|
|
47561
47535
|
}
|
|
47562
47536
|
this.authToken = await auth_getValidAuthToken(this.anvilUrl, this.username);
|
|
47563
47537
|
const wsUrl = getWebSocketUrl(this.appId, this.authToken, this.anvilUrl);
|
|
@@ -47567,6 +47541,8 @@ var __webpack_exports__ = {};
|
|
|
47567
47541
|
logger_logger.verbose(chalk_source.green("🔌 Connected to Anvil WebSocket"));
|
|
47568
47542
|
logger_logger.debug(`[WebSocket ${this.sessionId}]`, "WebSocket opened");
|
|
47569
47543
|
this.reconnectAttempts = 0;
|
|
47544
|
+
this.reconnectDelayMs = this.RECONNECT_DELAY_BASE_MS;
|
|
47545
|
+
this.startHeartbeat();
|
|
47570
47546
|
const subscribeMsg = {
|
|
47571
47547
|
cmd: "WATCH_APP",
|
|
47572
47548
|
app: this.appId,
|
|
@@ -47577,6 +47553,7 @@ var __webpack_exports__ = {};
|
|
|
47577
47553
|
this.emit("connected", void 0);
|
|
47578
47554
|
});
|
|
47579
47555
|
this.ws.on("message", (data)=>{
|
|
47556
|
+
this.markSocketResponsive();
|
|
47580
47557
|
try {
|
|
47581
47558
|
const msg = JSON.parse(data.toString());
|
|
47582
47559
|
logger_logger.debug(`[WebSocket ${this.sessionId}]`, `Message: ${JSON.stringify(msg)}`);
|
|
@@ -47585,8 +47562,12 @@ var __webpack_exports__ = {};
|
|
|
47585
47562
|
logger_logger.error(chalk_source.red(`Failed to parse WebSocket message: ${error.message}`));
|
|
47586
47563
|
}
|
|
47587
47564
|
});
|
|
47565
|
+
this.ws.on("pong", ()=>{
|
|
47566
|
+
this.markSocketResponsive();
|
|
47567
|
+
});
|
|
47588
47568
|
this.ws.on("close", (code, reason)=>{
|
|
47589
47569
|
logger_logger.debug(`[WebSocket ${this.sessionId}]`, `Closed: code=${code}, reason=${reason.toString()}`);
|
|
47570
|
+
this.stopHeartbeat();
|
|
47590
47571
|
this.ws = null;
|
|
47591
47572
|
if (1008 === code || reason.toString().includes("unauthenticated")) {
|
|
47592
47573
|
logger_logger.warn(chalk_source.yellow(" WebSocket authentication failed - changes from the Anvil Editor won't be detected"));
|
|
@@ -47594,21 +47575,12 @@ var __webpack_exports__ = {};
|
|
|
47594
47575
|
this.emit("auth-failed", void 0);
|
|
47595
47576
|
return;
|
|
47596
47577
|
}
|
|
47578
|
+
if (this.isClosing) return;
|
|
47597
47579
|
this.emit("disconnected", {
|
|
47598
47580
|
code,
|
|
47599
47581
|
reason: reason.toString()
|
|
47600
47582
|
});
|
|
47601
|
-
|
|
47602
|
-
this.reconnectAttempts++;
|
|
47603
|
-
logger_logger.verbose(chalk_source.gray(`WebSocket disconnected, reconnecting in ${this.RECONNECT_DELAY / 1000}s (attempt ${this.reconnectAttempts}/${this.MAX_RECONNECT_ATTEMPTS})...`));
|
|
47604
|
-
this.reconnectTimer = setTimeout(()=>{
|
|
47605
|
-
this.connect().catch((error)=>{
|
|
47606
|
-
this.emit("error", {
|
|
47607
|
-
error: error instanceof Error ? error : new Error(String(error))
|
|
47608
|
-
});
|
|
47609
|
-
});
|
|
47610
|
-
}, this.RECONNECT_DELAY);
|
|
47611
|
-
} else logger_logger.warn(chalk_source.yellow(` WebSocket reconnection failed after ${this.MAX_RECONNECT_ATTEMPTS} attempts - changes from the Anvil Editor won't be detected`));
|
|
47583
|
+
this.scheduleReconnect();
|
|
47612
47584
|
});
|
|
47613
47585
|
this.ws.on("error", (error)=>{
|
|
47614
47586
|
logger_logger.debug(`[WebSocket ${this.sessionId}]`, `Error: ${error.message}`);
|
|
@@ -47653,24 +47625,74 @@ var __webpack_exports__ = {};
|
|
|
47653
47625
|
return this.editSession;
|
|
47654
47626
|
}
|
|
47655
47627
|
close() {
|
|
47628
|
+
this.isClosing = true;
|
|
47656
47629
|
if (this.reconnectTimer) {
|
|
47657
47630
|
logger_logger.debug(`[WebSocket ${this.sessionId}]`, "Clearing reconnect timer");
|
|
47658
47631
|
clearTimeout(this.reconnectTimer);
|
|
47659
47632
|
this.reconnectTimer = null;
|
|
47660
47633
|
}
|
|
47661
|
-
|
|
47634
|
+
this.teardownSocket();
|
|
47635
|
+
}
|
|
47636
|
+
isConnected() {
|
|
47637
|
+
return this.ws?.readyState === ws_wrapper.OPEN;
|
|
47638
|
+
}
|
|
47639
|
+
scheduleReconnect() {
|
|
47640
|
+
if (this.reconnectTimer || this.isClosing) return;
|
|
47641
|
+
this.reconnectAttempts++;
|
|
47642
|
+
const delayMs = this.reconnectDelayMs;
|
|
47643
|
+
logger_logger.verbose(chalk_source.gray(`WebSocket disconnected, reconnecting in ${Math.round(delayMs / 1000)}s (attempt ${this.reconnectAttempts})...`));
|
|
47644
|
+
this.reconnectTimer = setTimeout(()=>{
|
|
47645
|
+
this.reconnectTimer = null;
|
|
47646
|
+
this.connect().catch((error)=>{
|
|
47647
|
+
this.emit("error", {
|
|
47648
|
+
error: error instanceof Error ? error : new Error(String(error))
|
|
47649
|
+
});
|
|
47650
|
+
});
|
|
47651
|
+
}, delayMs);
|
|
47652
|
+
this.reconnectDelayMs = Math.min(Math.round(1.5 * this.reconnectDelayMs), this.RECONNECT_DELAY_MAX_MS);
|
|
47653
|
+
}
|
|
47654
|
+
startHeartbeat() {
|
|
47655
|
+
this.stopHeartbeat();
|
|
47656
|
+
this.heartbeatTimer = setInterval(()=>{
|
|
47657
|
+
const ws = this.ws;
|
|
47658
|
+
if (!ws || ws.readyState !== ws_wrapper.OPEN) return;
|
|
47662
47659
|
try {
|
|
47663
|
-
|
|
47664
|
-
|
|
47665
|
-
|
|
47666
|
-
|
|
47667
|
-
|
|
47660
|
+
ws.ping();
|
|
47661
|
+
} catch (error) {
|
|
47662
|
+
logger_logger.debug(`[WebSocket ${this.sessionId}]`, `Failed to send ping: ${error.message}`);
|
|
47663
|
+
ws.terminate();
|
|
47664
|
+
return;
|
|
47668
47665
|
}
|
|
47669
|
-
this.
|
|
47666
|
+
this.pongTimeoutTimer = setTimeout(()=>{
|
|
47667
|
+
logger_logger.warn(chalk_source.yellow(" WebSocket heartbeat timed out - reconnecting"));
|
|
47668
|
+
ws.terminate();
|
|
47669
|
+
}, this.HEARTBEAT_TIMEOUT_MS);
|
|
47670
|
+
}, this.HEARTBEAT_INTERVAL_MS);
|
|
47671
|
+
}
|
|
47672
|
+
markSocketResponsive() {
|
|
47673
|
+
if (this.pongTimeoutTimer) {
|
|
47674
|
+
clearTimeout(this.pongTimeoutTimer);
|
|
47675
|
+
this.pongTimeoutTimer = null;
|
|
47670
47676
|
}
|
|
47671
47677
|
}
|
|
47672
|
-
|
|
47673
|
-
|
|
47678
|
+
stopHeartbeat() {
|
|
47679
|
+
if (this.heartbeatTimer) {
|
|
47680
|
+
clearInterval(this.heartbeatTimer);
|
|
47681
|
+
this.heartbeatTimer = null;
|
|
47682
|
+
}
|
|
47683
|
+
this.markSocketResponsive();
|
|
47684
|
+
}
|
|
47685
|
+
teardownSocket() {
|
|
47686
|
+
this.stopHeartbeat();
|
|
47687
|
+
if (!this.ws) return;
|
|
47688
|
+
try {
|
|
47689
|
+
logger_logger.debug(`[WebSocket ${this.sessionId}]`, "Closing WebSocket");
|
|
47690
|
+
this.ws.removeAllListeners();
|
|
47691
|
+
if (this.ws.readyState === ws_wrapper.OPEN || this.ws.readyState === ws_wrapper.CONNECTING) this.ws.terminate();
|
|
47692
|
+
} catch (e) {
|
|
47693
|
+
logger_logger.debug(`[WebSocket ${this.sessionId}]`, "Error closing WebSocket (ignoring):", e);
|
|
47694
|
+
}
|
|
47695
|
+
this.ws = null;
|
|
47674
47696
|
}
|
|
47675
47697
|
}
|
|
47676
47698
|
async function detectRemoteChanges(gitService, oldCommitId, newCommitId) {
|
|
@@ -49398,7 +49420,11 @@ var __webpack_exports__ = {};
|
|
|
49398
49420
|
wsClient = null;
|
|
49399
49421
|
saveProcessor = null;
|
|
49400
49422
|
syncManager = null;
|
|
49423
|
+
localChangePollTimer = null;
|
|
49424
|
+
isPollingLocalChanges = false;
|
|
49425
|
+
lastLocalStatusFingerprint = null;
|
|
49401
49426
|
BRANCH_CHANGE_SETTLE_MS = 2000;
|
|
49427
|
+
LOCAL_CHANGE_POLL_MS = 2000;
|
|
49402
49428
|
stagedOnly;
|
|
49403
49429
|
constructor(repoPath, appId, options){
|
|
49404
49430
|
super();
|
|
@@ -49536,6 +49562,10 @@ var __webpack_exports__ = {};
|
|
|
49536
49562
|
this.fileWatcher.cleanup();
|
|
49537
49563
|
this.fileWatcher = null;
|
|
49538
49564
|
}
|
|
49565
|
+
if (this.localChangePollTimer) {
|
|
49566
|
+
clearInterval(this.localChangePollTimer);
|
|
49567
|
+
this.localChangePollTimer = null;
|
|
49568
|
+
}
|
|
49539
49569
|
logger_logger.debug(`[Session ${this.sessionId}]`, "Cleanup complete");
|
|
49540
49570
|
}
|
|
49541
49571
|
async startWatching() {
|
|
@@ -49569,8 +49599,70 @@ var __webpack_exports__ = {};
|
|
|
49569
49599
|
}
|
|
49570
49600
|
});
|
|
49571
49601
|
await this.fileWatcher.start(this.currentBranch);
|
|
49602
|
+
await this.initializeLocalChangeFingerprint();
|
|
49603
|
+
this.startLocalChangeFallbackPolling();
|
|
49572
49604
|
await new Promise(()=>{});
|
|
49573
49605
|
}
|
|
49606
|
+
async initializeLocalChangeFingerprint() {
|
|
49607
|
+
if (this.stagedOnly) return;
|
|
49608
|
+
try {
|
|
49609
|
+
const status = await this.gitService.getStatus();
|
|
49610
|
+
this.lastLocalStatusFingerprint = this.getLocalStatusFingerprint(status);
|
|
49611
|
+
} catch (error) {
|
|
49612
|
+
logger_logger.debug(`[Session ${this.sessionId}]`, `Failed to initialize local change fingerprint: ${error.message}`);
|
|
49613
|
+
}
|
|
49614
|
+
}
|
|
49615
|
+
startLocalChangeFallbackPolling() {
|
|
49616
|
+
if (this.stagedOnly || this.localChangePollTimer) return;
|
|
49617
|
+
this.localChangePollTimer = setInterval(()=>{
|
|
49618
|
+
this.pollForMissedLocalChanges();
|
|
49619
|
+
}, this.LOCAL_CHANGE_POLL_MS);
|
|
49620
|
+
}
|
|
49621
|
+
async pollForMissedLocalChanges() {
|
|
49622
|
+
if (this.isCleanedUp || this.isPausedForUserInput || this.isPollingLocalChanges) return;
|
|
49623
|
+
this.isPollingLocalChanges = true;
|
|
49624
|
+
try {
|
|
49625
|
+
const status = await this.gitService.getStatus();
|
|
49626
|
+
const fingerprint = this.getLocalStatusFingerprint(status);
|
|
49627
|
+
if (null === this.lastLocalStatusFingerprint) {
|
|
49628
|
+
this.lastLocalStatusFingerprint = fingerprint;
|
|
49629
|
+
return;
|
|
49630
|
+
}
|
|
49631
|
+
if (fingerprint !== this.lastLocalStatusFingerprint) {
|
|
49632
|
+
this.lastLocalStatusFingerprint = fingerprint;
|
|
49633
|
+
if (fingerprint) {
|
|
49634
|
+
logger_logger.debug(`[Session ${this.sessionId}]`, "Detected local change via fallback status poll");
|
|
49635
|
+
this.saveProcessor?.queueSave();
|
|
49636
|
+
}
|
|
49637
|
+
}
|
|
49638
|
+
} catch (error) {
|
|
49639
|
+
logger_logger.debug(`[Session ${this.sessionId}]`, `Fallback status poll failed: ${error.message}`);
|
|
49640
|
+
} finally{
|
|
49641
|
+
this.isPollingLocalChanges = false;
|
|
49642
|
+
}
|
|
49643
|
+
}
|
|
49644
|
+
getLocalStatusFingerprint(status) {
|
|
49645
|
+
const renamed = status.renamed.map((r)=>`${r.from}->${r.to}`).sort();
|
|
49646
|
+
const modified = [
|
|
49647
|
+
...status.modified
|
|
49648
|
+
].sort();
|
|
49649
|
+
const notAdded = [
|
|
49650
|
+
...status.notAdded
|
|
49651
|
+
].sort();
|
|
49652
|
+
const created = [
|
|
49653
|
+
...status.created
|
|
49654
|
+
].sort();
|
|
49655
|
+
const deleted = [
|
|
49656
|
+
...status.deleted
|
|
49657
|
+
].sort();
|
|
49658
|
+
return [
|
|
49659
|
+
...renamed.map((r)=>`R:${r}`),
|
|
49660
|
+
...modified.map((m)=>`M:${m}`),
|
|
49661
|
+
...notAdded.map((n)=>`N:${n}`),
|
|
49662
|
+
...created.map((c)=>`C:${c}`),
|
|
49663
|
+
...deleted.map((d)=>`D:${d}`)
|
|
49664
|
+
].join("|");
|
|
49665
|
+
}
|
|
49574
49666
|
async handleFileChange(event, filePath, relativePath) {
|
|
49575
49667
|
if (this.isCleanedUp || this.isPausedForUserInput) return;
|
|
49576
49668
|
logger_logger.verbose(chalk_source.blue("File changed: ") + chalk_source.bold(relativePath));
|
|
@@ -49834,7 +49926,8 @@ var __webpack_exports__ = {};
|
|
|
49834
49926
|
authToken,
|
|
49835
49927
|
currentBranch,
|
|
49836
49928
|
commitId,
|
|
49837
|
-
stagedOnly
|
|
49929
|
+
stagedOnly,
|
|
49930
|
+
username
|
|
49838
49931
|
});
|
|
49839
49932
|
session.on("branch-changed", (data)=>{
|
|
49840
49933
|
logger_logger.debug("Event: branch-changed", data);
|
|
@@ -49863,27 +49956,8 @@ var __webpack_exports__ = {};
|
|
|
49863
49956
|
session.hasUncommittedChanges = hasUncommittedChanges;
|
|
49864
49957
|
return session;
|
|
49865
49958
|
}
|
|
49866
|
-
|
|
49867
|
-
|
|
49868
|
-
let username = explicitUsername;
|
|
49869
|
-
if (explicitUrl) url = normalizeAnvilUrl(explicitUrl);
|
|
49870
|
-
else if (repoPath) {
|
|
49871
|
-
const detected = await detectAnvilUrlFromRemotes(repoPath);
|
|
49872
|
-
if (detected) {
|
|
49873
|
-
url = detected.url;
|
|
49874
|
-
if (!username && detected.username) username = detected.username;
|
|
49875
|
-
} else url = resolveUrlFromAvailableOrConfig();
|
|
49876
|
-
} else url = resolveUrlFromAvailableOrConfig();
|
|
49877
|
-
if (!username) {
|
|
49878
|
-
const accounts = auth_getAccountsForUrl(url);
|
|
49879
|
-
if (1 === accounts.length) username = accounts[0];
|
|
49880
|
-
}
|
|
49881
|
-
return {
|
|
49882
|
-
url,
|
|
49883
|
-
username
|
|
49884
|
-
};
|
|
49885
|
-
}
|
|
49886
|
-
function resolveUrlFromAvailableOrConfig() {
|
|
49959
|
+
function resolveUrlForFallback(explicitUrl) {
|
|
49960
|
+
if (explicitUrl) return normalizeAnvilUrl(explicitUrl);
|
|
49887
49961
|
const availableUrls = getAvailableAnvilUrls();
|
|
49888
49962
|
if (availableUrls.length > 0) return availableUrls[0];
|
|
49889
49963
|
const fromConfig = getConfig("anvilUrl");
|
|
@@ -49911,11 +49985,16 @@ var __webpack_exports__ = {};
|
|
|
49911
49985
|
trimmed ? resolve(trimmed) : resolve(null);
|
|
49912
49986
|
});
|
|
49913
49987
|
});
|
|
49914
|
-
return
|
|
49988
|
+
if (manualAppId) return {
|
|
49989
|
+
appId: manualAppId,
|
|
49990
|
+
source: "config",
|
|
49991
|
+
description: "Manual entry"
|
|
49992
|
+
};
|
|
49993
|
+
return null;
|
|
49915
49994
|
}
|
|
49916
|
-
const choices = candidates.map((candidate)=>({
|
|
49917
|
-
name:
|
|
49918
|
-
value:
|
|
49995
|
+
const choices = candidates.map((candidate, index)=>({
|
|
49996
|
+
name: formatCandidateLabel(candidate),
|
|
49997
|
+
value: index
|
|
49919
49998
|
}));
|
|
49920
49999
|
choices.push({
|
|
49921
50000
|
name: "Cancel",
|
|
@@ -49944,9 +50023,14 @@ var __webpack_exports__ = {};
|
|
|
49944
50023
|
trimmed ? resolve(trimmed) : resolve(null);
|
|
49945
50024
|
});
|
|
49946
50025
|
});
|
|
49947
|
-
return
|
|
50026
|
+
if (manualAppId) return {
|
|
50027
|
+
appId: manualAppId,
|
|
50028
|
+
source: "config",
|
|
50029
|
+
description: "Manual entry"
|
|
50030
|
+
};
|
|
50031
|
+
return null;
|
|
49948
50032
|
}
|
|
49949
|
-
return answer.appId;
|
|
50033
|
+
return candidates[answer.appId];
|
|
49950
50034
|
} catch (error) {
|
|
49951
50035
|
const errorObj = error;
|
|
49952
50036
|
if ("ExitPromptError" === errorObj.name || errorObj.message.includes("User force closed")) logger_logger.warn("Operation cancelled by user.");
|
|
@@ -50384,137 +50468,100 @@ var __webpack_exports__ = {};
|
|
|
50384
50468
|
const validationResult = await validateAnvilApp(repoPath);
|
|
50385
50469
|
if (validationResult.appName) logger_logger.info(chalk_source.green("Anvil app: ") + chalk_source.bold(validationResult.appName));
|
|
50386
50470
|
const detectedFromAllRemotes = await detectAppIdsFromAllRemotes(repoPath);
|
|
50387
|
-
|
|
50388
|
-
|
|
50389
|
-
|
|
50390
|
-
let
|
|
50391
|
-
|
|
50392
|
-
|
|
50393
|
-
if (
|
|
50394
|
-
|
|
50395
|
-
|
|
50396
|
-
|
|
50397
|
-
|
|
50398
|
-
|
|
50399
|
-
|
|
50400
|
-
|
|
50401
|
-
|
|
50402
|
-
|
|
50403
|
-
|
|
50404
|
-
|
|
50405
|
-
|
|
50406
|
-
|
|
50407
|
-
|
|
50408
|
-
|
|
50409
|
-
const
|
|
50410
|
-
|
|
50411
|
-
|
|
50412
|
-
|
|
50413
|
-
|
|
50414
|
-
|
|
50415
|
-
|
|
50416
|
-
|
|
50417
|
-
|
|
50418
|
-
|
|
50419
|
-
|
|
50420
|
-
|
|
50421
|
-
|
|
50471
|
+
let filteredCandidates = filterCandidates(detectedFromAllRemotes, explicitUrl, explicitUsername);
|
|
50472
|
+
logger_logger.verbose(chalk_source.cyan(`Detected ${detectedFromAllRemotes.length} app ID(s) from git remotes`));
|
|
50473
|
+
if (filteredCandidates.length !== detectedFromAllRemotes.length) logger_logger.verbose(chalk_source.cyan(`After filtering: ${filteredCandidates.length} candidate(s)`));
|
|
50474
|
+
let finalAppId;
|
|
50475
|
+
let anvilUrl;
|
|
50476
|
+
let username = explicitUsername;
|
|
50477
|
+
if (explicitAppId) {
|
|
50478
|
+
finalAppId = explicitAppId;
|
|
50479
|
+
const remoteInfo = lookupRemoteInfoForAppId(explicitAppId, detectedFromAllRemotes);
|
|
50480
|
+
if (remoteInfo.detectedUrl && !explicitUrl) {
|
|
50481
|
+
anvilUrl = normalizeAnvilUrl(remoteInfo.detectedUrl);
|
|
50482
|
+
logger_logger.verbose(chalk_source.cyan("Resolved URL from remote for app ID: ") + chalk_source.bold(anvilUrl));
|
|
50483
|
+
}
|
|
50484
|
+
if (remoteInfo.detectedUsername && !explicitUsername) {
|
|
50485
|
+
username = remoteInfo.detectedUsername;
|
|
50486
|
+
logger_logger.verbose(chalk_source.cyan("Resolved username from remote for app ID: ") + chalk_source.bold(username));
|
|
50487
|
+
}
|
|
50488
|
+
} else {
|
|
50489
|
+
logger_logger.verbose(chalk_source.cyan("No app ID provided, attempting auto-detection..."));
|
|
50490
|
+
if (0 === filteredCandidates.length) {
|
|
50491
|
+
logger_logger.verbose(chalk_source.gray("No app IDs found in git remotes."));
|
|
50492
|
+
const fallbackUrl = resolveUrlForFallback(explicitUrl);
|
|
50493
|
+
const shouldContinue = await logger_logger.confirm(`Search ${fallbackUrl} for matching app IDs? (slower)`, true);
|
|
50494
|
+
if (shouldContinue) {
|
|
50495
|
+
logger_logger.progress("detect", `Searching ${fallbackUrl} ${explicitUsername ? `for ${explicitUsername}` : ''} for matching app IDs...`);
|
|
50496
|
+
const reverseLookupCandidates = await detectAppIdsByCommitLookup(repoPath, {
|
|
50497
|
+
anvilUrl: fallbackUrl,
|
|
50498
|
+
username: explicitUsername,
|
|
50499
|
+
includeRemotes: false
|
|
50500
|
+
});
|
|
50501
|
+
logger_logger.progressEnd("detect");
|
|
50502
|
+
for (const c of reverseLookupCandidates)filteredCandidates.push({
|
|
50503
|
+
...c,
|
|
50504
|
+
detectedUrl: fallbackUrl
|
|
50505
|
+
});
|
|
50506
|
+
}
|
|
50507
|
+
}
|
|
50508
|
+
if (filteredCandidates.length > 0) {
|
|
50509
|
+
for (const c of filteredCandidates)logger_logger.verbose(chalk_source.gray(` Found: ${formatCandidateLabel(c)}`));
|
|
50510
|
+
if (filteredCandidates.length > 1) logger_logger.verbose(chalk_source.yellow(`Found ${filteredCandidates.length} potential app IDs`));
|
|
50511
|
+
}
|
|
50512
|
+
if (useFirst && filteredCandidates.length > 0) {
|
|
50513
|
+
const selected = filteredCandidates[0];
|
|
50514
|
+
finalAppId = selected.appId;
|
|
50515
|
+
if (selected.detectedUrl) anvilUrl = normalizeAnvilUrl(selected.detectedUrl);
|
|
50516
|
+
if (selected.detectedUsername && !username) username = selected.detectedUsername;
|
|
50517
|
+
logger_logger.success("Auto-selected first app ID: " + chalk_source.bold(finalAppId));
|
|
50518
|
+
} else {
|
|
50519
|
+
const selected = await selectAppId(filteredCandidates);
|
|
50520
|
+
if (!selected) {
|
|
50521
|
+
logger_logger.error("No app ID provided. Cannot continue without an app ID.");
|
|
50522
|
+
process.exit(1);
|
|
50422
50523
|
}
|
|
50423
|
-
|
|
50524
|
+
finalAppId = selected.appId;
|
|
50525
|
+
if (selected.detectedUrl) anvilUrl = normalizeAnvilUrl(selected.detectedUrl);
|
|
50526
|
+
if (selected.detectedUsername && !username) username = selected.detectedUsername;
|
|
50424
50527
|
}
|
|
50425
50528
|
}
|
|
50529
|
+
if (explicitUrl) anvilUrl = normalizeAnvilUrl(explicitUrl);
|
|
50530
|
+
else if (!anvilUrl) anvilUrl = resolveUrlForFallback();
|
|
50531
|
+
anvilUrl = normalizeAnvilUrl(anvilUrl);
|
|
50532
|
+
logger_logger.verbose(chalk_source.green("Using app ID: ") + chalk_source.bold(finalAppId));
|
|
50533
|
+
logger_logger.verbose(chalk_source.cyan("Using Anvil URL: ") + chalk_source.bold(anvilUrl));
|
|
50426
50534
|
if (!username) {
|
|
50427
50535
|
const accounts = auth_getAccountsForUrl(anvilUrl);
|
|
50428
50536
|
if (1 === accounts.length) {
|
|
50429
50537
|
username = accounts[0];
|
|
50430
|
-
logger_logger.verbose(chalk_source.cyan("Auto-selected
|
|
50538
|
+
logger_logger.verbose(chalk_source.cyan("Auto-selected account: ") + chalk_source.bold(username));
|
|
50431
50539
|
} else if (accounts.length > 1) {
|
|
50432
|
-
|
|
50433
|
-
|
|
50434
|
-
|
|
50435
|
-
|
|
50436
|
-
|
|
50437
|
-
|
|
50438
|
-
|
|
50439
|
-
|
|
50440
|
-
|
|
50441
|
-
|
|
50442
|
-
|
|
50443
|
-
|
|
50444
|
-
logger_logger.warn(chalk_source.yellow("Git remotes point to ") + chalk_source.bold(detectedUrl) + chalk_source.yellow(", but you specified: ") + chalk_source.bold(normalizedSelected));
|
|
50445
|
-
if (detectedAppIds.length > 0) logger_logger.info(chalk_source.gray(" Detected app IDs on remote URL: ") + chalk_source.bold(detectedAppIds.join(", ")));
|
|
50446
|
-
logger_logger.info(chalk_source.gray(" To use the remote URL instead, run: ") + chalk_source.cyan(`anvil watch --url ${detectedUrl}`));
|
|
50447
|
-
}
|
|
50448
|
-
const candidatesForSelectedUrl = detectedFromAllRemotes.filter((c)=>c.detectedUrl && normalizeAnvilUrl(c.detectedUrl) === normalizedSelected);
|
|
50449
|
-
if (candidatesForSelectedUrl.length > 0) for (const candidate of candidatesForSelectedUrl){
|
|
50450
|
-
const isLoggedInAny = hasTokensForUrl(normalizedSelected);
|
|
50451
|
-
const isLoggedInWithUsername = candidate.detectedUsername ? hasTokensForUrl(normalizedSelected, candidate.detectedUsername) : false;
|
|
50452
|
-
const loggedInAccounts = auth_getAccountsForUrl(normalizedSelected);
|
|
50453
|
-
if (isLoggedInAny) {
|
|
50454
|
-
if (candidate.detectedUsername && !isLoggedInWithUsername) {
|
|
50455
|
-
logger_logger.warn(chalk_source.yellow("Detected from git remote: ") + chalk_source.bold(`app ID ${candidate.appId}`) + chalk_source.yellow(" on ") + chalk_source.bold(normalizedSelected) + chalk_source.yellow(" with username ") + chalk_source.bold(candidate.detectedUsername) + chalk_source.yellow(", but you're logged in as ") + chalk_source.bold(loggedInAccounts.join(", ")) + chalk_source.yellow("."));
|
|
50456
|
-
logger_logger.info(chalk_source.gray(" To log in, run: ") + chalk_source.cyan(`anvil login ${normalizedSelected}`));
|
|
50457
|
-
logger_logger.info(chalk_source.gray(" Make sure you're logged in as ") + chalk_source.bold(candidate.detectedUsername) + chalk_source.gray(" in your browser."));
|
|
50540
|
+
const choices = accounts.map((acct)=>({
|
|
50541
|
+
name: acct,
|
|
50542
|
+
value: acct
|
|
50543
|
+
}));
|
|
50544
|
+
choices.push({
|
|
50545
|
+
name: "Cancel",
|
|
50546
|
+
value: null
|
|
50547
|
+
});
|
|
50548
|
+
const selected = await logger_logger.select("Multiple accounts found. Which account owns this app?", choices, accounts[0]);
|
|
50549
|
+
if (null === selected) {
|
|
50550
|
+
logger_logger.warn("Operation cancelled.");
|
|
50551
|
+
process.exit(0);
|
|
50458
50552
|
}
|
|
50459
|
-
|
|
50460
|
-
logger_logger.warn(chalk_source.yellow("Detected from git remote: ") + chalk_source.bold(`app ID ${candidate.appId}`) + chalk_source.yellow(" on ") + chalk_source.bold(normalizedSelected) + chalk_source.yellow(", but you're not logged in to this URL."));
|
|
50461
|
-
logger_logger.info(chalk_source.gray(" To log in, run: ") + chalk_source.cyan(`anvil login ${normalizedSelected}`));
|
|
50462
|
-
if (candidate.detectedUsername) logger_logger.info(chalk_source.gray(" Make sure you're logged in as ") + chalk_source.bold(candidate.detectedUsername) + chalk_source.gray(" in your browser."));
|
|
50553
|
+
username = selected;
|
|
50463
50554
|
}
|
|
50464
50555
|
}
|
|
50556
|
+
if (username) logger_logger.verbose(chalk_source.cyan("Using account: ") + chalk_source.bold(username));
|
|
50465
50557
|
if (!hasTokensForUrl(anvilUrl, username)) {
|
|
50466
50558
|
if (username) logger_logger.error(`Not logged in to ${anvilUrl} as ${username}`);
|
|
50467
50559
|
else logger_logger.error(`Not logged in to ${anvilUrl}`);
|
|
50468
50560
|
logger_logger.verbose(chalk_source.yellow("Please log in first:"));
|
|
50469
|
-
console.log(chalk_source.cyan(` anvil login ${anvilUrl}`));
|
|
50561
|
+
console.log(chalk_source.cyan(` anvil login ${anvilUrl.replace(/^https?:\/\//, "")}`));
|
|
50470
50562
|
process.exit(1);
|
|
50471
50563
|
}
|
|
50472
|
-
logger_logger.verbose(chalk_source.green("✓ Authentication tokens found
|
|
50473
|
-
let finalAppId = explicitAppId;
|
|
50474
|
-
if (!finalAppId) {
|
|
50475
|
-
logger_logger.verbose(chalk_source.cyan("No app ID provided, attempting auto-detection..."));
|
|
50476
|
-
logger_logger.progress("detect", "Auto-detecting app ID...");
|
|
50477
|
-
let candidates = await detectAppIds(repoPath, {
|
|
50478
|
-
includeReverseLookup: false,
|
|
50479
|
-
anvilUrl
|
|
50480
|
-
});
|
|
50481
|
-
logger_logger.progressEnd("detect");
|
|
50482
|
-
if (0 === candidates.length) {
|
|
50483
|
-
logger_logger.verbose(chalk_source.gray("Fast lookup found no matching app IDs."));
|
|
50484
|
-
const shouldContinue = await logger_logger.confirm(`Search ${anvilUrl} for matching app IDs? (slower)`, true);
|
|
50485
|
-
if (shouldContinue) {
|
|
50486
|
-
logger_logger.progress("detect", `Searching ${anvilUrl} for matching app IDs...`);
|
|
50487
|
-
candidates = await detectAppIds(repoPath, {
|
|
50488
|
-
anvilUrl
|
|
50489
|
-
});
|
|
50490
|
-
logger_logger.progressEnd("detect");
|
|
50491
|
-
}
|
|
50492
|
-
}
|
|
50493
|
-
if (candidates.length > 0) {
|
|
50494
|
-
logger_logger.verbose(chalk_source.gray("Checking git remotes:"));
|
|
50495
|
-
candidates.filter((c)=>"remote" === c.source).forEach((c)=>{
|
|
50496
|
-
logger_logger.verbose(chalk_source.gray(` Found: ${c.description}`));
|
|
50497
|
-
logger_logger.verbose(chalk_source.green("Found app ID in remote: ") + chalk_source.bold(c.appId));
|
|
50498
|
-
});
|
|
50499
|
-
if (candidates.some((c)=>"config" === c.source)) candidates.filter((c)=>"config" === c.source).forEach((c)=>{
|
|
50500
|
-
logger_logger.verbose(chalk_source.gray(`Checking ${c.description.split("'")[1]} config...`));
|
|
50501
|
-
logger_logger.verbose(chalk_source.green("Found app ID in config: ") + chalk_source.bold(c.appId));
|
|
50502
|
-
});
|
|
50503
|
-
if (candidates.length > 1) logger_logger.verbose(chalk_source.yellow(`Found ${candidates.length} potential app IDs:`));
|
|
50504
|
-
}
|
|
50505
|
-
if (useFirst && candidates.length > 0) {
|
|
50506
|
-
finalAppId = candidates[0].appId;
|
|
50507
|
-
logger_logger.success("Auto-selected first app ID: " + chalk_source.bold(finalAppId));
|
|
50508
|
-
} else {
|
|
50509
|
-
const selectedAppId = await selectAppId(candidates);
|
|
50510
|
-
if (!selectedAppId) {
|
|
50511
|
-
logger_logger.error("No app ID provided. Cannot continue without an app ID.");
|
|
50512
|
-
process.exit(1);
|
|
50513
|
-
}
|
|
50514
|
-
finalAppId = selectedAppId;
|
|
50515
|
-
}
|
|
50516
|
-
}
|
|
50517
|
-
logger_logger.verbose(chalk_source.green("Using app ID: ") + chalk_source.bold(finalAppId));
|
|
50564
|
+
logger_logger.verbose(chalk_source.green("✓ Authentication tokens found"));
|
|
50518
50565
|
logger_logger.progress("validate", `Validating app ID: ${finalAppId}`);
|
|
50519
50566
|
const appIdValidation = await validateAppId(finalAppId, anvilUrl, username);
|
|
50520
50567
|
logger_logger.progressEnd("validate");
|
package/dist/index.js
CHANGED
|
@@ -11980,28 +11980,35 @@ var __webpack_exports__ = {};
|
|
|
11980
11980
|
"use strict";
|
|
11981
11981
|
__webpack_require__.r(__webpack_exports__);
|
|
11982
11982
|
__webpack_require__.d(__webpack_exports__, {
|
|
11983
|
-
syncToLatest: ()=>syncToLatest,
|
|
11984
|
-
validateAnvilApp: ()=>validateAnvilApp,
|
|
11985
|
-
validateBranchSyncStatus: ()=>validateBranchSyncStatus,
|
|
11986
11983
|
verifyAuth: ()=>verifyAuth,
|
|
11987
|
-
|
|
11988
|
-
|
|
11989
|
-
|
|
11984
|
+
lookupRemoteInfoForAppId: ()=>lookupRemoteInfoForAppId,
|
|
11985
|
+
validateBranchSyncStatus: ()=>validateBranchSyncStatus,
|
|
11986
|
+
AppIdWithContext: ()=>anvil_api_namespaceObject.AppIdWithContext,
|
|
11990
11987
|
checkUncommittedChanges: ()=>checkUncommittedChanges,
|
|
11991
|
-
|
|
11992
|
-
|
|
11988
|
+
hasTokensForUrl: ()=>hasTokensForUrl,
|
|
11989
|
+
validateAnvilApp: ()=>validateAnvilApp,
|
|
11993
11990
|
logout: ()=>logout,
|
|
11994
11991
|
detectAppIdsFromAllRemotes: ()=>detectAppIdsFromAllRemotes,
|
|
11992
|
+
BranchSyncStatus: ()=>validation_namespaceObject.BranchSyncStatus,
|
|
11993
|
+
formatCandidateLabel: ()=>formatCandidateLabel,
|
|
11994
|
+
syncToLatest: ()=>syncToLatest,
|
|
11995
|
+
filterCandidates: ()=>filterCandidates,
|
|
11996
|
+
getValidAuthToken: ()=>auth_getValidAuthToken,
|
|
11997
|
+
login: ()=>login,
|
|
11998
|
+
watch: ()=>api_watch,
|
|
11995
11999
|
AppIdCandidate: ()=>anvil_api_namespaceObject.AppIdCandidate,
|
|
11996
|
-
|
|
12000
|
+
detectAppIdsByCommitLookup: ()=>detectAppIdsByCommitLookup
|
|
11997
12001
|
});
|
|
11998
12002
|
var anvil_api_namespaceObject = {};
|
|
11999
12003
|
__webpack_require__.r(anvil_api_namespaceObject);
|
|
12000
12004
|
__webpack_require__.d(anvil_api_namespaceObject, {
|
|
12001
|
-
|
|
12005
|
+
lx: ()=>detectAppIdsByCommitLookup,
|
|
12002
12006
|
NZ: ()=>detectAppIdsFromAllRemotes,
|
|
12007
|
+
rZ: ()=>filterCandidates,
|
|
12008
|
+
T_: ()=>formatCandidateLabel,
|
|
12003
12009
|
OI: ()=>getGitFetchUrl,
|
|
12004
|
-
$0: ()=>getWebSocketUrl
|
|
12010
|
+
$0: ()=>getWebSocketUrl,
|
|
12011
|
+
Wj: ()=>lookupRemoteInfoForAppId
|
|
12005
12012
|
});
|
|
12006
12013
|
var validation_namespaceObject = {};
|
|
12007
12014
|
__webpack_require__.r(validation_namespaceObject);
|
|
@@ -22516,38 +22523,36 @@ var __webpack_exports__ = {};
|
|
|
22516
22523
|
function getWebSocketUrl(appId, authToken, anvilUrl = anvil_api_getDefaultAnvilUrl()) {
|
|
22517
22524
|
return anvilUrl.replace(/^http/, "ws") + `/ide/api/_/apps/${appId}/ws?access_token=${authToken}`;
|
|
22518
22525
|
}
|
|
22519
|
-
|
|
22520
|
-
|
|
22521
|
-
|
|
22522
|
-
|
|
22523
|
-
|
|
22524
|
-
|
|
22525
|
-
|
|
22526
|
-
|
|
22527
|
-
|
|
22528
|
-
|
|
22529
|
-
|
|
22530
|
-
|
|
22531
|
-
|
|
22532
|
-
|
|
22533
|
-
|
|
22534
|
-
|
|
22535
|
-
|
|
22536
|
-
|
|
22537
|
-
|
|
22538
|
-
|
|
22539
|
-
|
|
22540
|
-
|
|
22541
|
-
|
|
22542
|
-
|
|
22543
|
-
|
|
22544
|
-
|
|
22545
|
-
|
|
22546
|
-
|
|
22547
|
-
|
|
22548
|
-
|
|
22549
|
-
} catch (_e) {}
|
|
22550
|
-
return out;
|
|
22526
|
+
function filterCandidates(candidates, explicitUrl, explicitUsername) {
|
|
22527
|
+
let filtered = candidates;
|
|
22528
|
+
if (explicitUrl) {
|
|
22529
|
+
const normalizedExplicit = config_normalizeAnvilUrl(explicitUrl);
|
|
22530
|
+
filtered = filtered.filter((c)=>c.detectedUrl && config_normalizeAnvilUrl(c.detectedUrl) === normalizedExplicit);
|
|
22531
|
+
}
|
|
22532
|
+
if (explicitUsername) filtered = filtered.filter((c)=>!c.detectedUsername || c.detectedUsername === explicitUsername);
|
|
22533
|
+
return filtered;
|
|
22534
|
+
}
|
|
22535
|
+
function formatCandidateLabel(candidate) {
|
|
22536
|
+
const parts = [
|
|
22537
|
+
candidate.appId
|
|
22538
|
+
];
|
|
22539
|
+
if (candidate.detectedUrl) if (candidate.detectedUsername) parts.push(`(${candidate.detectedUsername} on ${candidate.detectedUrl})`);
|
|
22540
|
+
else parts.push(`(${candidate.detectedUrl})`);
|
|
22541
|
+
parts.push(`- ${candidate.description}`);
|
|
22542
|
+
return parts.join(" ");
|
|
22543
|
+
}
|
|
22544
|
+
function lookupRemoteInfoForAppId(appId, detectedRemotes) {
|
|
22545
|
+
const matches = detectedRemotes.filter((c)=>c.appId === appId);
|
|
22546
|
+
if (0 === matches.length) return {};
|
|
22547
|
+
const withUsername = matches.find((c)=>c.detectedUsername);
|
|
22548
|
+
if (withUsername) return {
|
|
22549
|
+
detectedUrl: withUsername.detectedUrl,
|
|
22550
|
+
detectedUsername: withUsername.detectedUsername
|
|
22551
|
+
};
|
|
22552
|
+
return {
|
|
22553
|
+
detectedUrl: matches[0].detectedUrl,
|
|
22554
|
+
detectedUsername: matches[0].detectedUsername
|
|
22555
|
+
};
|
|
22551
22556
|
}
|
|
22552
22557
|
async function detectAppIdsFromAllRemotes(repoPath) {
|
|
22553
22558
|
const git = esm_default(repoPath);
|
|
@@ -22583,11 +22588,13 @@ var __webpack_exports__ = {};
|
|
|
22583
22588
|
} catch (_e) {}
|
|
22584
22589
|
return out;
|
|
22585
22590
|
}
|
|
22586
|
-
async function detectAppIdsByCommitLookup(repoPath,
|
|
22591
|
+
async function detectAppIdsByCommitLookup(repoPath, options) {
|
|
22592
|
+
const anvilUrl = options.anvilUrl || resolveAnvilUrl();
|
|
22593
|
+
const username = options.username;
|
|
22587
22594
|
const git = esm_default(repoPath);
|
|
22588
22595
|
const out = [];
|
|
22589
22596
|
try {
|
|
22590
|
-
const authToken = await auth_getValidAuthToken(anvilUrl);
|
|
22597
|
+
const authToken = await auth_getValidAuthToken(anvilUrl, username);
|
|
22591
22598
|
const branchRef = await git.revparse([
|
|
22592
22599
|
"--abbrev-ref",
|
|
22593
22600
|
"HEAD"
|
|
@@ -22626,16 +22633,6 @@ var __webpack_exports__ = {};
|
|
|
22626
22633
|
} catch (_e) {}
|
|
22627
22634
|
return out;
|
|
22628
22635
|
}
|
|
22629
|
-
async function detectAppIds(repoPath, options = {}) {
|
|
22630
|
-
const anvilUrl = options.anvilUrl || resolveAnvilUrl();
|
|
22631
|
-
const results = [];
|
|
22632
|
-
const includeReverseLookup = options.includeReverseLookup ?? true;
|
|
22633
|
-
results.push(...await detectAppIdsFromRemotes(repoPath, anvilUrl));
|
|
22634
|
-
if (0 === results.length && includeReverseLookup) results.push(...await detectAppIdsByCommitLookup(repoPath, anvilUrl));
|
|
22635
|
-
const seen = new Set();
|
|
22636
|
-
const unique = results.filter((c)=>seen.has(c.appId) ? false : (seen.add(c.appId), true));
|
|
22637
|
-
return unique;
|
|
22638
|
-
}
|
|
22639
22636
|
class WebSocketClient extends Emitter {
|
|
22640
22637
|
ws = null;
|
|
22641
22638
|
appId;
|
|
@@ -22646,9 +22643,15 @@ var __webpack_exports__ = {};
|
|
|
22646
22643
|
username;
|
|
22647
22644
|
reconnectAttempts = 0;
|
|
22648
22645
|
reconnectTimer = null;
|
|
22646
|
+
heartbeatTimer = null;
|
|
22647
|
+
pongTimeoutTimer = null;
|
|
22648
|
+
reconnectDelayMs;
|
|
22649
|
+
isClosing = false;
|
|
22649
22650
|
sessionId;
|
|
22650
|
-
|
|
22651
|
-
|
|
22651
|
+
RECONNECT_DELAY_BASE_MS = 5000;
|
|
22652
|
+
RECONNECT_DELAY_MAX_MS = 60000;
|
|
22653
|
+
HEARTBEAT_INTERVAL_MS = 30000;
|
|
22654
|
+
HEARTBEAT_TIMEOUT_MS = 10000;
|
|
22652
22655
|
constructor(options){
|
|
22653
22656
|
super();
|
|
22654
22657
|
this.appId = options.appId;
|
|
@@ -22658,12 +22661,14 @@ var __webpack_exports__ = {};
|
|
|
22658
22661
|
this.editSession = options.editSession;
|
|
22659
22662
|
this.username = options.username;
|
|
22660
22663
|
this.sessionId = Math.random().toString(36).substring(2, 10);
|
|
22664
|
+
this.reconnectDelayMs = this.RECONNECT_DELAY_BASE_MS;
|
|
22661
22665
|
}
|
|
22662
22666
|
async connect() {
|
|
22667
|
+
this.isClosing = false;
|
|
22663
22668
|
if (this.ws?.readyState === ws_wrapper.OPEN) return void logger_logger.debug(`[WebSocket ${this.sessionId}]`, "WebSocket already open, skipping connection");
|
|
22664
22669
|
if (this.ws) {
|
|
22665
22670
|
logger_logger.debug(`[WebSocket ${this.sessionId}]`, "Closing existing WebSocket before reconnecting");
|
|
22666
|
-
this.
|
|
22671
|
+
this.teardownSocket();
|
|
22667
22672
|
}
|
|
22668
22673
|
this.authToken = await auth_getValidAuthToken(this.anvilUrl, this.username);
|
|
22669
22674
|
const wsUrl = getWebSocketUrl(this.appId, this.authToken, this.anvilUrl);
|
|
@@ -22673,6 +22678,8 @@ var __webpack_exports__ = {};
|
|
|
22673
22678
|
logger_logger.verbose(chalk_source.green("🔌 Connected to Anvil WebSocket"));
|
|
22674
22679
|
logger_logger.debug(`[WebSocket ${this.sessionId}]`, "WebSocket opened");
|
|
22675
22680
|
this.reconnectAttempts = 0;
|
|
22681
|
+
this.reconnectDelayMs = this.RECONNECT_DELAY_BASE_MS;
|
|
22682
|
+
this.startHeartbeat();
|
|
22676
22683
|
const subscribeMsg = {
|
|
22677
22684
|
cmd: "WATCH_APP",
|
|
22678
22685
|
app: this.appId,
|
|
@@ -22683,6 +22690,7 @@ var __webpack_exports__ = {};
|
|
|
22683
22690
|
this.emit("connected", void 0);
|
|
22684
22691
|
});
|
|
22685
22692
|
this.ws.on("message", (data)=>{
|
|
22693
|
+
this.markSocketResponsive();
|
|
22686
22694
|
try {
|
|
22687
22695
|
const msg = JSON.parse(data.toString());
|
|
22688
22696
|
logger_logger.debug(`[WebSocket ${this.sessionId}]`, `Message: ${JSON.stringify(msg)}`);
|
|
@@ -22691,8 +22699,12 @@ var __webpack_exports__ = {};
|
|
|
22691
22699
|
logger_logger.error(chalk_source.red(`Failed to parse WebSocket message: ${error.message}`));
|
|
22692
22700
|
}
|
|
22693
22701
|
});
|
|
22702
|
+
this.ws.on("pong", ()=>{
|
|
22703
|
+
this.markSocketResponsive();
|
|
22704
|
+
});
|
|
22694
22705
|
this.ws.on("close", (code, reason)=>{
|
|
22695
22706
|
logger_logger.debug(`[WebSocket ${this.sessionId}]`, `Closed: code=${code}, reason=${reason.toString()}`);
|
|
22707
|
+
this.stopHeartbeat();
|
|
22696
22708
|
this.ws = null;
|
|
22697
22709
|
if (1008 === code || reason.toString().includes("unauthenticated")) {
|
|
22698
22710
|
logger_logger.warn(chalk_source.yellow(" WebSocket authentication failed - changes from the Anvil Editor won't be detected"));
|
|
@@ -22700,21 +22712,12 @@ var __webpack_exports__ = {};
|
|
|
22700
22712
|
this.emit("auth-failed", void 0);
|
|
22701
22713
|
return;
|
|
22702
22714
|
}
|
|
22715
|
+
if (this.isClosing) return;
|
|
22703
22716
|
this.emit("disconnected", {
|
|
22704
22717
|
code,
|
|
22705
22718
|
reason: reason.toString()
|
|
22706
22719
|
});
|
|
22707
|
-
|
|
22708
|
-
this.reconnectAttempts++;
|
|
22709
|
-
logger_logger.verbose(chalk_source.gray(`WebSocket disconnected, reconnecting in ${this.RECONNECT_DELAY / 1000}s (attempt ${this.reconnectAttempts}/${this.MAX_RECONNECT_ATTEMPTS})...`));
|
|
22710
|
-
this.reconnectTimer = setTimeout(()=>{
|
|
22711
|
-
this.connect().catch((error)=>{
|
|
22712
|
-
this.emit("error", {
|
|
22713
|
-
error: error instanceof Error ? error : new Error(String(error))
|
|
22714
|
-
});
|
|
22715
|
-
});
|
|
22716
|
-
}, this.RECONNECT_DELAY);
|
|
22717
|
-
} else logger_logger.warn(chalk_source.yellow(` WebSocket reconnection failed after ${this.MAX_RECONNECT_ATTEMPTS} attempts - changes from the Anvil Editor won't be detected`));
|
|
22720
|
+
this.scheduleReconnect();
|
|
22718
22721
|
});
|
|
22719
22722
|
this.ws.on("error", (error)=>{
|
|
22720
22723
|
logger_logger.debug(`[WebSocket ${this.sessionId}]`, `Error: ${error.message}`);
|
|
@@ -22759,24 +22762,74 @@ var __webpack_exports__ = {};
|
|
|
22759
22762
|
return this.editSession;
|
|
22760
22763
|
}
|
|
22761
22764
|
close() {
|
|
22765
|
+
this.isClosing = true;
|
|
22762
22766
|
if (this.reconnectTimer) {
|
|
22763
22767
|
logger_logger.debug(`[WebSocket ${this.sessionId}]`, "Clearing reconnect timer");
|
|
22764
22768
|
clearTimeout(this.reconnectTimer);
|
|
22765
22769
|
this.reconnectTimer = null;
|
|
22766
22770
|
}
|
|
22767
|
-
|
|
22771
|
+
this.teardownSocket();
|
|
22772
|
+
}
|
|
22773
|
+
isConnected() {
|
|
22774
|
+
return this.ws?.readyState === ws_wrapper.OPEN;
|
|
22775
|
+
}
|
|
22776
|
+
scheduleReconnect() {
|
|
22777
|
+
if (this.reconnectTimer || this.isClosing) return;
|
|
22778
|
+
this.reconnectAttempts++;
|
|
22779
|
+
const delayMs = this.reconnectDelayMs;
|
|
22780
|
+
logger_logger.verbose(chalk_source.gray(`WebSocket disconnected, reconnecting in ${Math.round(delayMs / 1000)}s (attempt ${this.reconnectAttempts})...`));
|
|
22781
|
+
this.reconnectTimer = setTimeout(()=>{
|
|
22782
|
+
this.reconnectTimer = null;
|
|
22783
|
+
this.connect().catch((error)=>{
|
|
22784
|
+
this.emit("error", {
|
|
22785
|
+
error: error instanceof Error ? error : new Error(String(error))
|
|
22786
|
+
});
|
|
22787
|
+
});
|
|
22788
|
+
}, delayMs);
|
|
22789
|
+
this.reconnectDelayMs = Math.min(Math.round(1.5 * this.reconnectDelayMs), this.RECONNECT_DELAY_MAX_MS);
|
|
22790
|
+
}
|
|
22791
|
+
startHeartbeat() {
|
|
22792
|
+
this.stopHeartbeat();
|
|
22793
|
+
this.heartbeatTimer = setInterval(()=>{
|
|
22794
|
+
const ws = this.ws;
|
|
22795
|
+
if (!ws || ws.readyState !== ws_wrapper.OPEN) return;
|
|
22768
22796
|
try {
|
|
22769
|
-
|
|
22770
|
-
|
|
22771
|
-
|
|
22772
|
-
|
|
22773
|
-
|
|
22797
|
+
ws.ping();
|
|
22798
|
+
} catch (error) {
|
|
22799
|
+
logger_logger.debug(`[WebSocket ${this.sessionId}]`, `Failed to send ping: ${error.message}`);
|
|
22800
|
+
ws.terminate();
|
|
22801
|
+
return;
|
|
22774
22802
|
}
|
|
22775
|
-
this.
|
|
22803
|
+
this.pongTimeoutTimer = setTimeout(()=>{
|
|
22804
|
+
logger_logger.warn(chalk_source.yellow(" WebSocket heartbeat timed out - reconnecting"));
|
|
22805
|
+
ws.terminate();
|
|
22806
|
+
}, this.HEARTBEAT_TIMEOUT_MS);
|
|
22807
|
+
}, this.HEARTBEAT_INTERVAL_MS);
|
|
22808
|
+
}
|
|
22809
|
+
markSocketResponsive() {
|
|
22810
|
+
if (this.pongTimeoutTimer) {
|
|
22811
|
+
clearTimeout(this.pongTimeoutTimer);
|
|
22812
|
+
this.pongTimeoutTimer = null;
|
|
22776
22813
|
}
|
|
22777
22814
|
}
|
|
22778
|
-
|
|
22779
|
-
|
|
22815
|
+
stopHeartbeat() {
|
|
22816
|
+
if (this.heartbeatTimer) {
|
|
22817
|
+
clearInterval(this.heartbeatTimer);
|
|
22818
|
+
this.heartbeatTimer = null;
|
|
22819
|
+
}
|
|
22820
|
+
this.markSocketResponsive();
|
|
22821
|
+
}
|
|
22822
|
+
teardownSocket() {
|
|
22823
|
+
this.stopHeartbeat();
|
|
22824
|
+
if (!this.ws) return;
|
|
22825
|
+
try {
|
|
22826
|
+
logger_logger.debug(`[WebSocket ${this.sessionId}]`, "Closing WebSocket");
|
|
22827
|
+
this.ws.removeAllListeners();
|
|
22828
|
+
if (this.ws.readyState === ws_wrapper.OPEN || this.ws.readyState === ws_wrapper.CONNECTING) this.ws.terminate();
|
|
22829
|
+
} catch (e) {
|
|
22830
|
+
logger_logger.debug(`[WebSocket ${this.sessionId}]`, "Error closing WebSocket (ignoring):", e);
|
|
22831
|
+
}
|
|
22832
|
+
this.ws = null;
|
|
22780
22833
|
}
|
|
22781
22834
|
}
|
|
22782
22835
|
async function detectRemoteChanges(gitService, oldCommitId, newCommitId) {
|
|
@@ -25003,7 +25056,11 @@ var __webpack_exports__ = {};
|
|
|
25003
25056
|
wsClient = null;
|
|
25004
25057
|
saveProcessor = null;
|
|
25005
25058
|
syncManager = null;
|
|
25059
|
+
localChangePollTimer = null;
|
|
25060
|
+
isPollingLocalChanges = false;
|
|
25061
|
+
lastLocalStatusFingerprint = null;
|
|
25006
25062
|
BRANCH_CHANGE_SETTLE_MS = 2000;
|
|
25063
|
+
LOCAL_CHANGE_POLL_MS = 2000;
|
|
25007
25064
|
stagedOnly;
|
|
25008
25065
|
constructor(repoPath, appId, options){
|
|
25009
25066
|
super();
|
|
@@ -25141,6 +25198,10 @@ var __webpack_exports__ = {};
|
|
|
25141
25198
|
this.fileWatcher.cleanup();
|
|
25142
25199
|
this.fileWatcher = null;
|
|
25143
25200
|
}
|
|
25201
|
+
if (this.localChangePollTimer) {
|
|
25202
|
+
clearInterval(this.localChangePollTimer);
|
|
25203
|
+
this.localChangePollTimer = null;
|
|
25204
|
+
}
|
|
25144
25205
|
logger_logger.debug(`[Session ${this.sessionId}]`, "Cleanup complete");
|
|
25145
25206
|
}
|
|
25146
25207
|
async startWatching() {
|
|
@@ -25174,8 +25235,70 @@ var __webpack_exports__ = {};
|
|
|
25174
25235
|
}
|
|
25175
25236
|
});
|
|
25176
25237
|
await this.fileWatcher.start(this.currentBranch);
|
|
25238
|
+
await this.initializeLocalChangeFingerprint();
|
|
25239
|
+
this.startLocalChangeFallbackPolling();
|
|
25177
25240
|
await new Promise(()=>{});
|
|
25178
25241
|
}
|
|
25242
|
+
async initializeLocalChangeFingerprint() {
|
|
25243
|
+
if (this.stagedOnly) return;
|
|
25244
|
+
try {
|
|
25245
|
+
const status = await this.gitService.getStatus();
|
|
25246
|
+
this.lastLocalStatusFingerprint = this.getLocalStatusFingerprint(status);
|
|
25247
|
+
} catch (error) {
|
|
25248
|
+
logger_logger.debug(`[Session ${this.sessionId}]`, `Failed to initialize local change fingerprint: ${error.message}`);
|
|
25249
|
+
}
|
|
25250
|
+
}
|
|
25251
|
+
startLocalChangeFallbackPolling() {
|
|
25252
|
+
if (this.stagedOnly || this.localChangePollTimer) return;
|
|
25253
|
+
this.localChangePollTimer = setInterval(()=>{
|
|
25254
|
+
this.pollForMissedLocalChanges();
|
|
25255
|
+
}, this.LOCAL_CHANGE_POLL_MS);
|
|
25256
|
+
}
|
|
25257
|
+
async pollForMissedLocalChanges() {
|
|
25258
|
+
if (this.isCleanedUp || this.isPausedForUserInput || this.isPollingLocalChanges) return;
|
|
25259
|
+
this.isPollingLocalChanges = true;
|
|
25260
|
+
try {
|
|
25261
|
+
const status = await this.gitService.getStatus();
|
|
25262
|
+
const fingerprint = this.getLocalStatusFingerprint(status);
|
|
25263
|
+
if (null === this.lastLocalStatusFingerprint) {
|
|
25264
|
+
this.lastLocalStatusFingerprint = fingerprint;
|
|
25265
|
+
return;
|
|
25266
|
+
}
|
|
25267
|
+
if (fingerprint !== this.lastLocalStatusFingerprint) {
|
|
25268
|
+
this.lastLocalStatusFingerprint = fingerprint;
|
|
25269
|
+
if (fingerprint) {
|
|
25270
|
+
logger_logger.debug(`[Session ${this.sessionId}]`, "Detected local change via fallback status poll");
|
|
25271
|
+
this.saveProcessor?.queueSave();
|
|
25272
|
+
}
|
|
25273
|
+
}
|
|
25274
|
+
} catch (error) {
|
|
25275
|
+
logger_logger.debug(`[Session ${this.sessionId}]`, `Fallback status poll failed: ${error.message}`);
|
|
25276
|
+
} finally{
|
|
25277
|
+
this.isPollingLocalChanges = false;
|
|
25278
|
+
}
|
|
25279
|
+
}
|
|
25280
|
+
getLocalStatusFingerprint(status) {
|
|
25281
|
+
const renamed = status.renamed.map((r)=>`${r.from}->${r.to}`).sort();
|
|
25282
|
+
const modified = [
|
|
25283
|
+
...status.modified
|
|
25284
|
+
].sort();
|
|
25285
|
+
const notAdded = [
|
|
25286
|
+
...status.notAdded
|
|
25287
|
+
].sort();
|
|
25288
|
+
const created = [
|
|
25289
|
+
...status.created
|
|
25290
|
+
].sort();
|
|
25291
|
+
const deleted = [
|
|
25292
|
+
...status.deleted
|
|
25293
|
+
].sort();
|
|
25294
|
+
return [
|
|
25295
|
+
...renamed.map((r)=>`R:${r}`),
|
|
25296
|
+
...modified.map((m)=>`M:${m}`),
|
|
25297
|
+
...notAdded.map((n)=>`N:${n}`),
|
|
25298
|
+
...created.map((c)=>`C:${c}`),
|
|
25299
|
+
...deleted.map((d)=>`D:${d}`)
|
|
25300
|
+
].join("|");
|
|
25301
|
+
}
|
|
25179
25302
|
async handleFileChange(event, filePath, relativePath) {
|
|
25180
25303
|
if (this.isCleanedUp || this.isPausedForUserInput) return;
|
|
25181
25304
|
logger_logger.verbose(chalk_source.blue("File changed: ") + chalk_source.bold(relativePath));
|
|
@@ -25459,7 +25582,8 @@ var __webpack_exports__ = {};
|
|
|
25459
25582
|
authToken,
|
|
25460
25583
|
currentBranch,
|
|
25461
25584
|
commitId,
|
|
25462
|
-
stagedOnly
|
|
25585
|
+
stagedOnly,
|
|
25586
|
+
username
|
|
25463
25587
|
});
|
|
25464
25588
|
session.on("branch-changed", (data)=>{
|
|
25465
25589
|
logger_logger.debug("Event: branch-changed", data);
|
|
@@ -25490,14 +25614,18 @@ var __webpack_exports__ = {};
|
|
|
25490
25614
|
}
|
|
25491
25615
|
})();
|
|
25492
25616
|
exports.AppIdCandidate = __webpack_exports__.AppIdCandidate;
|
|
25617
|
+
exports.AppIdWithContext = __webpack_exports__.AppIdWithContext;
|
|
25493
25618
|
exports.BranchSyncStatus = __webpack_exports__.BranchSyncStatus;
|
|
25494
25619
|
exports.checkUncommittedChanges = __webpack_exports__.checkUncommittedChanges;
|
|
25495
|
-
exports.
|
|
25620
|
+
exports.detectAppIdsByCommitLookup = __webpack_exports__.detectAppIdsByCommitLookup;
|
|
25496
25621
|
exports.detectAppIdsFromAllRemotes = __webpack_exports__.detectAppIdsFromAllRemotes;
|
|
25622
|
+
exports.filterCandidates = __webpack_exports__.filterCandidates;
|
|
25623
|
+
exports.formatCandidateLabel = __webpack_exports__.formatCandidateLabel;
|
|
25497
25624
|
exports.getValidAuthToken = __webpack_exports__.getValidAuthToken;
|
|
25498
25625
|
exports.hasTokensForUrl = __webpack_exports__.hasTokensForUrl;
|
|
25499
25626
|
exports.login = __webpack_exports__.login;
|
|
25500
25627
|
exports.logout = __webpack_exports__.logout;
|
|
25628
|
+
exports.lookupRemoteInfoForAppId = __webpack_exports__.lookupRemoteInfoForAppId;
|
|
25501
25629
|
exports.syncToLatest = __webpack_exports__.syncToLatest;
|
|
25502
25630
|
exports.validateAnvilApp = __webpack_exports__.validateAnvilApp;
|
|
25503
25631
|
exports.validateBranchSyncStatus = __webpack_exports__.validateBranchSyncStatus;
|
|
@@ -25505,14 +25633,18 @@ exports.verifyAuth = __webpack_exports__.verifyAuth;
|
|
|
25505
25633
|
exports.watch = __webpack_exports__.watch;
|
|
25506
25634
|
for(var __rspack_i in __webpack_exports__)if (-1 === [
|
|
25507
25635
|
"AppIdCandidate",
|
|
25636
|
+
"AppIdWithContext",
|
|
25508
25637
|
"BranchSyncStatus",
|
|
25509
25638
|
"checkUncommittedChanges",
|
|
25510
|
-
"
|
|
25639
|
+
"detectAppIdsByCommitLookup",
|
|
25511
25640
|
"detectAppIdsFromAllRemotes",
|
|
25641
|
+
"filterCandidates",
|
|
25642
|
+
"formatCandidateLabel",
|
|
25512
25643
|
"getValidAuthToken",
|
|
25513
25644
|
"hasTokensForUrl",
|
|
25514
25645
|
"login",
|
|
25515
25646
|
"logout",
|
|
25647
|
+
"lookupRemoteInfoForAppId",
|
|
25516
25648
|
"syncToLatest",
|
|
25517
25649
|
"validateAnvilApp",
|
|
25518
25650
|
"validateBranchSyncStatus",
|