@fml-inc/fml 0.8.0-rc.1 → 0.8.0-rc.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/.claude-plugin/plugin.json +1 -1
- package/README.md +27 -16
- package/dist/{chunk-CK5MEL5J.js → chunk-3KISRT57.js} +1 -1
- package/dist/{chunk-DEMVOVVY.js → chunk-56TPYMNK.js} +244 -29
- package/dist/{chunk-T5YVLSUC.js → chunk-7V7G7NVF.js} +4 -0
- package/dist/{chunk-7DR5X7XI.js → chunk-A6HAEVJX.js} +136 -52
- package/dist/{chunk-F66IBM3Z.js → chunk-DZKYW327.js} +2 -2
- package/dist/{chunk-I4GZPTBM.js → chunk-ENW2GJNO.js} +1 -1
- package/dist/{chunk-P3QLARXE.js → chunk-R45CWWZO.js} +3 -3
- package/dist/{chunk-HUR2HCUG.js → chunk-WZLLO563.js} +2 -2
- package/dist/{chunk-JXSSPQ5B.js → chunk-YSU5CS2V.js} +1 -1
- package/dist/cli.js +1310 -1158
- package/dist/hook-handler.js +290 -40
- package/dist/mcp/server.js +7 -7
- package/dist/observer-server.js +8 -8
- package/dist/sync-cycle.js +3 -3
- package/dist/{token-store-R7WXEPLI.js → token-store-BT5THIAJ.js} +1 -1
- package/package.json +3 -3
|
@@ -162,6 +162,10 @@ var FML_LEGACY_OBSERVER_DB_FILE = path.join(
|
|
|
162
162
|
"observer.db"
|
|
163
163
|
);
|
|
164
164
|
var FML_HOOK_INBOX_DIR = path.join(FML_OBSERVER_DIR, "hook-inbox");
|
|
165
|
+
var FML_HOOK_CONTEXT_STATE_DIR = path.join(
|
|
166
|
+
FML_OBSERVER_DIR,
|
|
167
|
+
"hook-context-state"
|
|
168
|
+
);
|
|
165
169
|
var FML_HOOK_CAPTURE_DISABLED_FILE = path.join(
|
|
166
170
|
FML_OBSERVER_DIR,
|
|
167
171
|
"hook-capture.disabled"
|
|
@@ -180,6 +184,10 @@ function ensureDirs() {
|
|
|
180
184
|
fs.mkdirSync(FML_LOG_DIR, { recursive: true, mode: 448 });
|
|
181
185
|
fs.mkdirSync(FML_OBSERVER_DIR, { recursive: true, mode: 448 });
|
|
182
186
|
fs.mkdirSync(FML_HOOK_INBOX_DIR, { recursive: true, mode: 448 });
|
|
187
|
+
fs.mkdirSync(FML_HOOK_CONTEXT_STATE_DIR, {
|
|
188
|
+
recursive: true,
|
|
189
|
+
mode: 448
|
|
190
|
+
});
|
|
183
191
|
}
|
|
184
192
|
|
|
185
193
|
// src/config.ts
|
|
@@ -540,10 +548,32 @@ var serviceTokenCaches = /* @__PURE__ */ new Map();
|
|
|
540
548
|
var serviceRefreshPromises = /* @__PURE__ */ new Map();
|
|
541
549
|
var oauthRefreshPromises = /* @__PURE__ */ new Map();
|
|
542
550
|
var cacheKey = (envName) => envName;
|
|
543
|
-
function
|
|
551
|
+
function waitForTokenRefresh(promise, signal) {
|
|
552
|
+
if (!signal) return promise;
|
|
553
|
+
if (signal.aborted) return Promise.resolve(null);
|
|
554
|
+
return new Promise((resolve, reject) => {
|
|
555
|
+
const onAbort = () => {
|
|
556
|
+
cleanup();
|
|
557
|
+
resolve(null);
|
|
558
|
+
};
|
|
559
|
+
const cleanup = () => signal.removeEventListener("abort", onAbort);
|
|
560
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
561
|
+
void promise.then(
|
|
562
|
+
(value) => {
|
|
563
|
+
cleanup();
|
|
564
|
+
resolve(value);
|
|
565
|
+
},
|
|
566
|
+
(error) => {
|
|
567
|
+
cleanup();
|
|
568
|
+
reject(error);
|
|
569
|
+
}
|
|
570
|
+
);
|
|
571
|
+
});
|
|
572
|
+
}
|
|
573
|
+
function getOrStartTokenRefresh(flights, key, forceRefresh, refresh, signal) {
|
|
544
574
|
const existing = flights.get(key);
|
|
545
575
|
if (existing && (!forceRefresh || existing.forceRefresh)) {
|
|
546
|
-
return existing.promise;
|
|
576
|
+
return waitForTokenRefresh(existing.promise, signal);
|
|
547
577
|
}
|
|
548
578
|
const operation = existing ? existing.promise.then(refresh, refresh) : refresh();
|
|
549
579
|
let flight;
|
|
@@ -552,7 +582,7 @@ function getOrStartTokenRefresh(flights, key, forceRefresh, refresh) {
|
|
|
552
582
|
});
|
|
553
583
|
flight = { forceRefresh, promise };
|
|
554
584
|
flights.set(key, flight);
|
|
555
|
-
return promise;
|
|
585
|
+
return waitForTokenRefresh(promise, signal);
|
|
556
586
|
}
|
|
557
587
|
function refreshLockPath(envName) {
|
|
558
588
|
return `${storePathFor(envName)}.refresh.lock`;
|
|
@@ -848,8 +878,30 @@ function releaseOwnedLease(filePath, claimedStat, owner, parseOwner, description
|
|
|
848
878
|
);
|
|
849
879
|
}
|
|
850
880
|
}
|
|
851
|
-
function sleep(milliseconds) {
|
|
852
|
-
|
|
881
|
+
function sleep(milliseconds, signal) {
|
|
882
|
+
if (!signal) {
|
|
883
|
+
return new Promise((resolve) => setTimeout(resolve, milliseconds));
|
|
884
|
+
}
|
|
885
|
+
if (signal.aborted) {
|
|
886
|
+
return Promise.reject(
|
|
887
|
+
signal.reason ?? new DOMException("The operation was aborted", "AbortError")
|
|
888
|
+
);
|
|
889
|
+
}
|
|
890
|
+
return new Promise((resolve, reject) => {
|
|
891
|
+
const timeout = setTimeout(() => {
|
|
892
|
+
cleanup();
|
|
893
|
+
resolve();
|
|
894
|
+
}, milliseconds);
|
|
895
|
+
const onAbort = () => {
|
|
896
|
+
clearTimeout(timeout);
|
|
897
|
+
cleanup();
|
|
898
|
+
reject(
|
|
899
|
+
signal.reason ?? new DOMException("The operation was aborted", "AbortError")
|
|
900
|
+
);
|
|
901
|
+
};
|
|
902
|
+
const cleanup = () => signal.removeEventListener("abort", onAbort);
|
|
903
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
904
|
+
});
|
|
853
905
|
}
|
|
854
906
|
function isProcessAlive(pid) {
|
|
855
907
|
try {
|
|
@@ -998,7 +1050,7 @@ function recoverStaleRefreshLock(lockPath) {
|
|
|
998
1050
|
recovery.release();
|
|
999
1051
|
}
|
|
1000
1052
|
}
|
|
1001
|
-
async function acquireRefreshLock(envName) {
|
|
1053
|
+
async function acquireRefreshLock(envName, signal) {
|
|
1002
1054
|
try {
|
|
1003
1055
|
ensureDir(envName);
|
|
1004
1056
|
} catch (error) {
|
|
@@ -1011,6 +1063,9 @@ async function acquireRefreshLock(envName) {
|
|
|
1011
1063
|
const recoveryPath = `${lockPath}.recovery`;
|
|
1012
1064
|
const deadline = Date.now() + OAUTH_REFRESH_LOCK_WAIT_MS;
|
|
1013
1065
|
while (Date.now() < deadline) {
|
|
1066
|
+
if (signal?.aborted) {
|
|
1067
|
+
throw signal.reason ?? new DOMException("The operation was aborted", "AbortError");
|
|
1068
|
+
}
|
|
1014
1069
|
if (fs3.existsSync(recoveryPath)) {
|
|
1015
1070
|
try {
|
|
1016
1071
|
recoverAbandonedRecoveryMarker(recoveryPath);
|
|
@@ -1020,7 +1075,7 @@ async function acquireRefreshLock(envName) {
|
|
|
1020
1075
|
);
|
|
1021
1076
|
return null;
|
|
1022
1077
|
}
|
|
1023
|
-
await sleep(OAUTH_REFRESH_LOCK_POLL_MS);
|
|
1078
|
+
await sleep(OAUTH_REFRESH_LOCK_POLL_MS, signal);
|
|
1024
1079
|
continue;
|
|
1025
1080
|
}
|
|
1026
1081
|
let descriptor;
|
|
@@ -1041,7 +1096,7 @@ async function acquireRefreshLock(envName) {
|
|
|
1041
1096
|
);
|
|
1042
1097
|
return null;
|
|
1043
1098
|
}
|
|
1044
|
-
await sleep(OAUTH_REFRESH_LOCK_POLL_MS);
|
|
1099
|
+
await sleep(OAUTH_REFRESH_LOCK_POLL_MS, signal);
|
|
1045
1100
|
continue;
|
|
1046
1101
|
}
|
|
1047
1102
|
const ownerId = randomUUID();
|
|
@@ -1076,6 +1131,10 @@ async function acquireRefreshLock(envName) {
|
|
|
1076
1131
|
parseRefreshLockOwner,
|
|
1077
1132
|
"credential lock"
|
|
1078
1133
|
);
|
|
1134
|
+
if (signal?.aborted) {
|
|
1135
|
+
releaseClaim();
|
|
1136
|
+
throw signal.reason ?? new DOMException("The operation was aborted", "AbortError");
|
|
1137
|
+
}
|
|
1079
1138
|
let entryBlocked;
|
|
1080
1139
|
try {
|
|
1081
1140
|
entryBlocked = fs3.existsSync(recoveryPath) || !isOwned();
|
|
@@ -1090,13 +1149,16 @@ async function acquireRefreshLock(envName) {
|
|
|
1090
1149
|
return null;
|
|
1091
1150
|
}
|
|
1092
1151
|
if (entryBlocked) {
|
|
1093
|
-
await sleep(OAUTH_REFRESH_LOCK_POLL_MS);
|
|
1094
1152
|
try {
|
|
1095
|
-
|
|
1096
|
-
}
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
)
|
|
1153
|
+
await sleep(OAUTH_REFRESH_LOCK_POLL_MS, signal);
|
|
1154
|
+
} finally {
|
|
1155
|
+
try {
|
|
1156
|
+
if (isOwned()) releaseClaim();
|
|
1157
|
+
} catch (error) {
|
|
1158
|
+
console.error(
|
|
1159
|
+
`[fml] Auth: unable to release a blocked refresh lock claim: ${describeError(error)}`
|
|
1160
|
+
);
|
|
1161
|
+
}
|
|
1100
1162
|
}
|
|
1101
1163
|
continue;
|
|
1102
1164
|
}
|
|
@@ -1142,7 +1204,7 @@ function isLockOwnedSafely(lock) {
|
|
|
1142
1204
|
}
|
|
1143
1205
|
}
|
|
1144
1206
|
async function withRefreshLock(envName, mutation, options) {
|
|
1145
|
-
const lock = await acquireRefreshLock(envName);
|
|
1207
|
+
const lock = await acquireRefreshLock(envName, options?.signal);
|
|
1146
1208
|
if (!lock) {
|
|
1147
1209
|
throw new Error("Unable to acquire the credential mutation lock");
|
|
1148
1210
|
}
|
|
@@ -1181,9 +1243,13 @@ async function clearStoredCredentials(envName) {
|
|
|
1181
1243
|
serviceRefreshPromises.delete(key);
|
|
1182
1244
|
oauthRefreshPromises.delete(key);
|
|
1183
1245
|
}
|
|
1184
|
-
async function refreshServiceToken(refreshToken2, envName, siteUrl) {
|
|
1246
|
+
async function refreshServiceToken(refreshToken2, envName, siteUrl, signal) {
|
|
1185
1247
|
try {
|
|
1248
|
+
if (signal?.aborted) return null;
|
|
1186
1249
|
const convexUrl = (envName ? resolveEnvConvexUrl(envName) : null) ?? CONVEX_URL;
|
|
1250
|
+
const requestTimeout = AbortSignal.timeout(
|
|
1251
|
+
OAUTH_REFRESH_REQUEST_TIMEOUT_MS
|
|
1252
|
+
);
|
|
1187
1253
|
const response = await fetch(
|
|
1188
1254
|
`${siteUrl ?? getSiteUrlForConvexUrl(convexUrl)}/api/tokens/refresh`,
|
|
1189
1255
|
{
|
|
@@ -1192,7 +1258,7 @@ async function refreshServiceToken(refreshToken2, envName, siteUrl) {
|
|
|
1192
1258
|
"Content-Type": "application/json",
|
|
1193
1259
|
Authorization: `Bearer ${refreshToken2}`
|
|
1194
1260
|
},
|
|
1195
|
-
signal: AbortSignal.
|
|
1261
|
+
signal: signal ? AbortSignal.any([signal, requestTimeout]) : requestTimeout
|
|
1196
1262
|
}
|
|
1197
1263
|
);
|
|
1198
1264
|
if (!response.ok) {
|
|
@@ -1212,6 +1278,7 @@ async function refreshServiceToken(refreshToken2, envName, siteUrl) {
|
|
|
1212
1278
|
});
|
|
1213
1279
|
return data.accessToken;
|
|
1214
1280
|
} catch (err) {
|
|
1281
|
+
if (signal?.aborted) return null;
|
|
1215
1282
|
Sentry.captureException(err);
|
|
1216
1283
|
console.error(`[fml] Service token refresh error: ${err}`);
|
|
1217
1284
|
return null;
|
|
@@ -1248,6 +1315,7 @@ async function storeServiceRefreshToken(refreshToken2, opts) {
|
|
|
1248
1315
|
return true;
|
|
1249
1316
|
}
|
|
1250
1317
|
async function getValidToken(opts) {
|
|
1318
|
+
if (opts?.signal?.aborted) return null;
|
|
1251
1319
|
const envName = resolveEnvName(opts?.env);
|
|
1252
1320
|
const forceRefresh = opts?.forceRefresh === true;
|
|
1253
1321
|
const key = cacheKey(envName);
|
|
@@ -1261,7 +1329,8 @@ async function getValidToken(opts) {
|
|
|
1261
1329
|
serviceRefreshPromises,
|
|
1262
1330
|
key,
|
|
1263
1331
|
forceRefresh,
|
|
1264
|
-
() => refreshServiceToken(envToken, envName)
|
|
1332
|
+
() => refreshServiceToken(envToken, envName, void 0, opts?.signal),
|
|
1333
|
+
opts?.signal
|
|
1265
1334
|
);
|
|
1266
1335
|
}
|
|
1267
1336
|
if (envToken?.startsWith("fml_st_")) return envToken;
|
|
@@ -1286,39 +1355,47 @@ async function getValidToken(opts) {
|
|
|
1286
1355
|
serviceRefreshPromises,
|
|
1287
1356
|
key,
|
|
1288
1357
|
forceRefresh,
|
|
1289
|
-
() => withRefreshLock(
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
return
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
writeTokensUnlocked(
|
|
1307
|
-
{
|
|
1308
|
-
...current,
|
|
1309
|
-
accessToken: newAccessToken,
|
|
1310
|
-
expiresAt: cached.expiresAt
|
|
1311
|
-
},
|
|
1312
|
-
envName
|
|
1358
|
+
() => withRefreshLock(
|
|
1359
|
+
envName,
|
|
1360
|
+
async (lock) => {
|
|
1361
|
+
const current = readTokens(envName);
|
|
1362
|
+
if (!current) return null;
|
|
1363
|
+
if (!forceRefresh && current.expiresAt > Date.now() + TOKEN_REFRESH_WINDOW_MS) {
|
|
1364
|
+
return current.accessToken;
|
|
1365
|
+
}
|
|
1366
|
+
if (current.tokenType !== "service") {
|
|
1367
|
+
return current.accessToken;
|
|
1368
|
+
}
|
|
1369
|
+
if (!lock.isOwned()) return null;
|
|
1370
|
+
const newAccessToken = await refreshServiceToken(
|
|
1371
|
+
current.refreshToken,
|
|
1372
|
+
envName,
|
|
1373
|
+
void 0,
|
|
1374
|
+
opts?.signal
|
|
1313
1375
|
);
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1376
|
+
if (!lock.isOwned()) return null;
|
|
1377
|
+
const cached = serviceTokenCaches.get(key);
|
|
1378
|
+
if (newAccessToken && cached) {
|
|
1379
|
+
writeTokensUnlocked(
|
|
1380
|
+
{
|
|
1381
|
+
...current,
|
|
1382
|
+
accessToken: newAccessToken,
|
|
1383
|
+
expiresAt: cached.expiresAt
|
|
1384
|
+
},
|
|
1385
|
+
envName
|
|
1386
|
+
);
|
|
1387
|
+
}
|
|
1388
|
+
return newAccessToken;
|
|
1389
|
+
},
|
|
1390
|
+
{ signal: opts?.signal }
|
|
1391
|
+
).catch((error) => {
|
|
1392
|
+
if (opts?.signal?.aborted) return null;
|
|
1317
1393
|
console.error(
|
|
1318
1394
|
`[fml] Auth: unable to refresh stored service credentials: ${error instanceof Error ? error.message : String(error)}`
|
|
1319
1395
|
);
|
|
1320
1396
|
return null;
|
|
1321
|
-
})
|
|
1397
|
+
}),
|
|
1398
|
+
opts?.signal
|
|
1322
1399
|
);
|
|
1323
1400
|
}
|
|
1324
1401
|
if (stored.refreshInvalidAt) {
|
|
@@ -1331,11 +1408,12 @@ async function getValidToken(opts) {
|
|
|
1331
1408
|
oauthRefreshPromises,
|
|
1332
1409
|
key,
|
|
1333
1410
|
forceRefresh,
|
|
1334
|
-
() => refreshTokenWithLock(envName, forceRefresh)
|
|
1411
|
+
() => refreshTokenWithLock(envName, forceRefresh, opts?.signal),
|
|
1412
|
+
opts?.signal
|
|
1335
1413
|
);
|
|
1336
1414
|
}
|
|
1337
|
-
async function refreshTokenWithLock(envName, forceRefresh = false) {
|
|
1338
|
-
const lock = await acquireRefreshLock(envName);
|
|
1415
|
+
async function refreshTokenWithLock(envName, forceRefresh = false, signal) {
|
|
1416
|
+
const lock = await acquireRefreshLock(envName, signal);
|
|
1339
1417
|
if (!lock) return null;
|
|
1340
1418
|
try {
|
|
1341
1419
|
if (!isLockOwnedSafely(lock)) return null;
|
|
@@ -1366,12 +1444,12 @@ async function refreshTokenWithLock(envName, forceRefresh = false) {
|
|
|
1366
1444
|
return null;
|
|
1367
1445
|
}
|
|
1368
1446
|
if (!isLockOwnedSafely(lock)) return null;
|
|
1369
|
-
return await refreshToken(current, lock, envName);
|
|
1447
|
+
return await refreshToken(current, lock, envName, signal);
|
|
1370
1448
|
} finally {
|
|
1371
1449
|
lock.release();
|
|
1372
1450
|
}
|
|
1373
1451
|
}
|
|
1374
|
-
async function refreshToken(stored, lock, envName) {
|
|
1452
|
+
async function refreshToken(stored, lock, envName, signal) {
|
|
1375
1453
|
if (!stored.workosClientId) {
|
|
1376
1454
|
console.error(
|
|
1377
1455
|
"[fml] Auth: token expired, missing workosClientId \u2014 run `fml login`"
|
|
@@ -1379,7 +1457,11 @@ async function refreshToken(stored, lock, envName) {
|
|
|
1379
1457
|
return null;
|
|
1380
1458
|
}
|
|
1381
1459
|
try {
|
|
1460
|
+
if (signal?.aborted) return null;
|
|
1382
1461
|
if (!lock.isOwned()) return null;
|
|
1462
|
+
const requestTimeout = AbortSignal.timeout(
|
|
1463
|
+
OAUTH_REFRESH_REQUEST_TIMEOUT_MS
|
|
1464
|
+
);
|
|
1383
1465
|
const response = await fetch(
|
|
1384
1466
|
`${WORKOS_API_URL}/user_management/authenticate`,
|
|
1385
1467
|
{
|
|
@@ -1390,7 +1472,7 @@ async function refreshToken(stored, lock, envName) {
|
|
|
1390
1472
|
client_id: stored.workosClientId,
|
|
1391
1473
|
refresh_token: stored.refreshToken
|
|
1392
1474
|
}),
|
|
1393
|
-
signal: AbortSignal.
|
|
1475
|
+
signal: signal ? AbortSignal.any([signal, requestTimeout]) : requestTimeout
|
|
1394
1476
|
}
|
|
1395
1477
|
);
|
|
1396
1478
|
if (!response.ok) {
|
|
@@ -1460,6 +1542,7 @@ async function refreshToken(stored, lock, envName) {
|
|
|
1460
1542
|
}
|
|
1461
1543
|
return refreshed.accessToken;
|
|
1462
1544
|
} catch (err) {
|
|
1545
|
+
if (signal?.aborted) return null;
|
|
1463
1546
|
const msg = err instanceof Error ? err.message : String(err);
|
|
1464
1547
|
console.error(
|
|
1465
1548
|
`[fml] Auth: refresh failed (network error: ${msg}) \u2014 token preserved`
|
|
@@ -1490,6 +1573,7 @@ export {
|
|
|
1490
1573
|
FML_PANOPTICON_DB_OBSERVER_LOCK_FILE,
|
|
1491
1574
|
FML_LEGACY_OBSERVER_DB_FILE,
|
|
1492
1575
|
FML_HOOK_INBOX_DIR,
|
|
1576
|
+
FML_HOOK_CONTEXT_STATE_DIR,
|
|
1493
1577
|
FML_HOOK_CAPTURE_DISABLED_FILE,
|
|
1494
1578
|
observerOnlyOverrideWarning,
|
|
1495
1579
|
ensureDirs,
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
resolveRepoFromCwdAsync
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-7V7G7NVF.js";
|
|
4
4
|
import {
|
|
5
5
|
getActiveEnv,
|
|
6
6
|
getSiteUrlForConvexUrl,
|
|
7
7
|
getSyncDestinationIdentity,
|
|
8
8
|
getValidToken
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-A6HAEVJX.js";
|
|
10
10
|
|
|
11
11
|
// src/hooks/sync-loop.ts
|
|
12
12
|
import { createHash } from "crypto";
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import {
|
|
2
2
|
resolveRepoFromCwd
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-7V7G7NVF.js";
|
|
4
4
|
import {
|
|
5
5
|
CONVEX_URL,
|
|
6
6
|
getActiveEnv,
|
|
7
7
|
getSelectedOrg,
|
|
8
8
|
getSiteUrlForConvexUrl,
|
|
9
9
|
getValidToken
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-A6HAEVJX.js";
|
|
11
11
|
|
|
12
12
|
// src/fml-client.ts
|
|
13
13
|
var LOGIN_EXPIRED_MESSAGE = "Authentication expired. Run `fml login` to sign in again, then restart Claude Code.";
|
|
@@ -79,7 +79,7 @@ function createFmlClient(token, options = {}) {
|
|
|
79
79
|
const repo = resolveRepoFromCwd(process.cwd());
|
|
80
80
|
if (repo) body.repo = repo.repo;
|
|
81
81
|
if (isServiceToken) {
|
|
82
|
-
const { readTokens, SERVICE_TOKEN_LOGIN_USER_ID } = await import("./token-store-
|
|
82
|
+
const { readTokens, SERVICE_TOKEN_LOGIN_USER_ID } = await import("./token-store-BT5THIAJ.js");
|
|
83
83
|
const stored = readTokens(options.envName);
|
|
84
84
|
const storedUserExternalId = stored?.tokenType === "service" && stored.user.id !== SERVICE_TOKEN_LOGIN_USER_ID ? stored.user.id : void 0;
|
|
85
85
|
const userExternalId = process.env.FML_USER_EXTERNAL_ID ?? storedUserExternalId;
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
2
|
OBSERVER_SERVICE_NAME
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-56TPYMNK.js";
|
|
4
4
|
import {
|
|
5
5
|
FML_OBSERVER_LOCK_FILE,
|
|
6
6
|
FML_OBSERVER_PORT,
|
|
7
7
|
FML_OBSERVER_STATE_FILE
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-A6HAEVJX.js";
|
|
9
9
|
|
|
10
10
|
// src/observer/state.ts
|
|
11
11
|
import { randomUUID } from "crypto";
|