@ogment-ai/cli 0.9.1-next.2 → 0.10.0-beta.1
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/README.md +5 -5
- package/dist/cli.js +500 -483
- package/dist/cli.js.map +1 -1
- package/package.json +9 -4
package/dist/cli.js
CHANGED
|
@@ -7998,25 +7998,25 @@ const toJsonValue = (value) => {
|
|
|
7998
7998
|
//#region src/shared/recovery.ts
|
|
7999
7999
|
const defaultRecoveryByCode = {
|
|
8000
8000
|
[ERROR_CODE.authDeviceExpired]: {
|
|
8001
|
-
command: "ogment
|
|
8002
|
-
reason: "
|
|
8001
|
+
command: "ogment login",
|
|
8002
|
+
reason: "Login request expired; start login again to continue.",
|
|
8003
8003
|
title: "Restart login",
|
|
8004
8004
|
when: "immediate"
|
|
8005
8005
|
},
|
|
8006
8006
|
[ERROR_CODE.authDevicePending]: {
|
|
8007
|
-
command: "ogment
|
|
8008
|
-
reason: "Authorization is pending;
|
|
8009
|
-
title: "
|
|
8007
|
+
command: "ogment login",
|
|
8008
|
+
reason: "Authorization is pending; run login again after approving in the browser.",
|
|
8009
|
+
title: "Complete login",
|
|
8010
8010
|
when: "immediate"
|
|
8011
8011
|
},
|
|
8012
8012
|
[ERROR_CODE.authInvalidCredentials]: {
|
|
8013
|
-
command: "ogment
|
|
8014
|
-
reason: "Credentials are invalid;
|
|
8015
|
-
title: "
|
|
8013
|
+
command: "ogment login",
|
|
8014
|
+
reason: "Credentials are invalid; sign in again to restore the local CLI session.",
|
|
8015
|
+
title: "Sign in again",
|
|
8016
8016
|
when: "immediate"
|
|
8017
8017
|
},
|
|
8018
8018
|
[ERROR_CODE.authRequired]: {
|
|
8019
|
-
command: "ogment
|
|
8019
|
+
command: "ogment login",
|
|
8020
8020
|
reason: "Authentication is required before catalog, search, or execute commands can run.",
|
|
8021
8021
|
title: "Authenticate",
|
|
8022
8022
|
when: "immediate"
|
|
@@ -8367,36 +8367,55 @@ const isRecord$1 = (value) => {
|
|
|
8367
8367
|
return typeof value === "object" && value !== null;
|
|
8368
8368
|
};
|
|
8369
8369
|
|
|
8370
|
-
//#endregion
|
|
8371
|
-
//#region src/shared/schemas.ts
|
|
8372
|
-
const credentialsFileSchema = object({
|
|
8373
|
-
agentName: string().optional(),
|
|
8374
|
-
apiKey: string().min(1).optional()
|
|
8375
|
-
});
|
|
8376
|
-
|
|
8377
8370
|
//#endregion
|
|
8378
8371
|
//#region src/infra/credentials.ts
|
|
8379
8372
|
const authStateFileSchema = object({
|
|
8373
|
+
currentAuthRequest: object({
|
|
8374
|
+
authRequestId: string().min(1),
|
|
8375
|
+
expiresAt: string().min(1),
|
|
8376
|
+
verificationUrl: string().min(1)
|
|
8377
|
+
}).nullable().optional(),
|
|
8378
|
+
installationId: uuid(),
|
|
8379
|
+
session: object({
|
|
8380
|
+
agentId: uuid(),
|
|
8381
|
+
agentName: string().min(1),
|
|
8382
|
+
apiKey: string().min(1),
|
|
8383
|
+
credentialId: uuid(),
|
|
8384
|
+
signedInAt: string().min(1)
|
|
8385
|
+
}).nullable().optional(),
|
|
8386
|
+
version: literal(3)
|
|
8387
|
+
}).strict();
|
|
8388
|
+
const authStateFileV2Schema = object({
|
|
8389
|
+
installationId: uuid(),
|
|
8390
|
+
pendingAuthRequest: object({
|
|
8391
|
+
authRequestId: string().min(1),
|
|
8392
|
+
expiresAt: string().min(1),
|
|
8393
|
+
verificationUrl: string().min(1)
|
|
8394
|
+
}).nullable().optional(),
|
|
8395
|
+
session: object({
|
|
8396
|
+
agentId: uuid(),
|
|
8397
|
+
agentName: string().min(1),
|
|
8398
|
+
apiKey: string().min(1),
|
|
8399
|
+
credentialId: uuid(),
|
|
8400
|
+
signedInAt: string().min(1)
|
|
8401
|
+
}).nullable().optional(),
|
|
8402
|
+
version: literal(2)
|
|
8403
|
+
}).strict();
|
|
8404
|
+
const legacyAuthStateFileSchema = object({
|
|
8380
8405
|
activeAuth: object({
|
|
8381
8406
|
agentName: string().optional(),
|
|
8382
8407
|
apiKey: string().min(1),
|
|
8383
|
-
boundAt: string().optional()
|
|
8384
|
-
namespaceKey: string().min(1).optional(),
|
|
8385
|
-
scopeFingerprint: string().min(1).optional()
|
|
8408
|
+
boundAt: string().optional()
|
|
8386
8409
|
}).nullable().optional(),
|
|
8387
8410
|
installationId: uuid(),
|
|
8388
8411
|
pendingRequests: array(object({
|
|
8389
8412
|
authRequestId: string().min(1),
|
|
8390
|
-
code: string().min(1),
|
|
8391
8413
|
createdAt: string().min(1),
|
|
8392
8414
|
expiresAt: string().min(1),
|
|
8393
|
-
namespaceKey: string().min(1),
|
|
8394
|
-
scopeFingerprint: string().min(1).optional(),
|
|
8395
8415
|
verificationUrl: string().min(1)
|
|
8396
8416
|
})).optional(),
|
|
8397
8417
|
version: literal(1)
|
|
8398
8418
|
}).strict();
|
|
8399
|
-
const telemetryInstallationSchema = object({ installationId: uuid() }).strict();
|
|
8400
8419
|
const LOCK_RETRY_DELAY_MS = 10;
|
|
8401
8420
|
const LOCK_STALE_MS = 3e4;
|
|
8402
8421
|
const LOCK_TIMEOUT_MS = 2e3;
|
|
@@ -8405,40 +8424,42 @@ const sleepBlocking = (milliseconds) => {
|
|
|
8405
8424
|
const view = new Int32Array(buffer);
|
|
8406
8425
|
Atomics.wait(view, 0, 0, milliseconds);
|
|
8407
8426
|
};
|
|
8408
|
-
const normalizeCredentials = (value) => {
|
|
8409
|
-
const parsed = parseWithSchema(credentialsFileSchema, value, "legacy credentials file");
|
|
8410
|
-
if (Result.isError(parsed) || parsed.value.apiKey === void 0) return null;
|
|
8411
|
-
return {
|
|
8412
|
-
...parsed.value.agentName === void 0 ? {} : { agentName: parsed.value.agentName },
|
|
8413
|
-
apiKey: parsed.value.apiKey
|
|
8414
|
-
};
|
|
8415
|
-
};
|
|
8416
8427
|
const normalizeAuthState = (value) => {
|
|
8417
|
-
const
|
|
8418
|
-
if (Result.
|
|
8419
|
-
|
|
8420
|
-
|
|
8421
|
-
|
|
8422
|
-
|
|
8423
|
-
|
|
8424
|
-
|
|
8425
|
-
|
|
8426
|
-
|
|
8427
|
-
|
|
8428
|
-
|
|
8429
|
-
|
|
8430
|
-
|
|
8431
|
-
|
|
8432
|
-
|
|
8433
|
-
|
|
8434
|
-
|
|
8435
|
-
}
|
|
8436
|
-
}
|
|
8428
|
+
const parsedCurrentState = parseWithSchema(authStateFileSchema, value, "auth state file");
|
|
8429
|
+
if (Result.isOk(parsedCurrentState)) return {
|
|
8430
|
+
needsMigration: false,
|
|
8431
|
+
state: {
|
|
8432
|
+
currentAuthRequest: parsedCurrentState.value.currentAuthRequest ?? null,
|
|
8433
|
+
installationId: parsedCurrentState.value.installationId,
|
|
8434
|
+
session: parsedCurrentState.value.session ?? null,
|
|
8435
|
+
version: 3
|
|
8436
|
+
}
|
|
8437
|
+
};
|
|
8438
|
+
const parsedLegacyV2State = parseWithSchema(authStateFileV2Schema, value, "auth state v2 file");
|
|
8439
|
+
if (Result.isOk(parsedLegacyV2State)) return {
|
|
8440
|
+
needsMigration: true,
|
|
8441
|
+
state: {
|
|
8442
|
+
currentAuthRequest: parsedLegacyV2State.value.pendingAuthRequest ?? null,
|
|
8443
|
+
installationId: parsedLegacyV2State.value.installationId,
|
|
8444
|
+
session: parsedLegacyV2State.value.session ?? null,
|
|
8445
|
+
version: 3
|
|
8446
|
+
}
|
|
8447
|
+
};
|
|
8448
|
+
const parsedV1 = parseWithSchema(legacyAuthStateFileSchema, value, "legacy auth state file");
|
|
8449
|
+
if (Result.isError(parsedV1)) return null;
|
|
8450
|
+
const latestPendingRequest = (parsedV1.value.pendingRequests ?? []).at(-1);
|
|
8437
8451
|
return {
|
|
8438
|
-
|
|
8439
|
-
|
|
8440
|
-
|
|
8441
|
-
|
|
8452
|
+
needsMigration: true,
|
|
8453
|
+
state: {
|
|
8454
|
+
currentAuthRequest: latestPendingRequest === void 0 ? null : {
|
|
8455
|
+
authRequestId: latestPendingRequest.authRequestId,
|
|
8456
|
+
expiresAt: latestPendingRequest.expiresAt,
|
|
8457
|
+
verificationUrl: latestPendingRequest.verificationUrl
|
|
8458
|
+
},
|
|
8459
|
+
installationId: parsedV1.value.installationId,
|
|
8460
|
+
session: null,
|
|
8461
|
+
version: 3
|
|
8462
|
+
}
|
|
8442
8463
|
};
|
|
8443
8464
|
};
|
|
8444
8465
|
const toCorruptPath = (path, nowFn) => {
|
|
@@ -8473,29 +8494,12 @@ const createFileCredentialsStore = (deps) => {
|
|
|
8473
8494
|
const unlinkSyncFn = deps.unlinkSyncFn ?? unlinkSync;
|
|
8474
8495
|
const writeFileSyncFn = deps.writeFileSyncFn ?? writeFileSync;
|
|
8475
8496
|
const lockPath = `${deps.credentialsPath}.lock`;
|
|
8476
|
-
const readJsonFile = (path) => {
|
|
8477
|
-
if (!existsSyncFn(path)) return null;
|
|
8478
|
-
try {
|
|
8479
|
-
return JSON.parse(readFileSyncFn(path, "utf8"));
|
|
8480
|
-
} catch {
|
|
8481
|
-
return null;
|
|
8482
|
-
}
|
|
8483
|
-
};
|
|
8484
|
-
const readLegacyCredentials = () => {
|
|
8485
|
-
return normalizeCredentials(readJsonFile(deps.legacyCredentialsPath));
|
|
8486
|
-
};
|
|
8487
|
-
const readLegacyInstallationId = () => {
|
|
8488
|
-
const raw = readJsonFile(deps.telemetryPath);
|
|
8489
|
-
if (raw === null) return null;
|
|
8490
|
-
const parsed = telemetryInstallationSchema.safeParse(raw);
|
|
8491
|
-
return parsed.success ? parsed.data.installationId : null;
|
|
8492
|
-
};
|
|
8493
8497
|
const createEmptyState = (installationId = randomUuidFn()) => {
|
|
8494
8498
|
return {
|
|
8495
|
-
|
|
8499
|
+
currentAuthRequest: null,
|
|
8496
8500
|
installationId,
|
|
8497
|
-
|
|
8498
|
-
version:
|
|
8501
|
+
session: null,
|
|
8502
|
+
version: 3
|
|
8499
8503
|
};
|
|
8500
8504
|
};
|
|
8501
8505
|
const withLock = (operation) => {
|
|
@@ -8588,43 +8592,33 @@ const createFileCredentialsStore = (deps) => {
|
|
|
8588
8592
|
}
|
|
8589
8593
|
throw error;
|
|
8590
8594
|
}
|
|
8591
|
-
const
|
|
8592
|
-
if (
|
|
8595
|
+
const normalized = normalizeAuthState(parsedJson);
|
|
8596
|
+
if (normalized === null) {
|
|
8593
8597
|
quarantineCorruptState();
|
|
8594
8598
|
return null;
|
|
8595
8599
|
}
|
|
8596
|
-
return
|
|
8597
|
-
};
|
|
8598
|
-
const migrateStateFromLegacy = () => {
|
|
8599
|
-
const migratedInstallationId = readLegacyInstallationId();
|
|
8600
|
-
const migratedCredentials = readLegacyCredentials();
|
|
8601
|
-
if (!(migratedInstallationId !== null || migratedCredentials !== null)) return null;
|
|
8602
|
-
return {
|
|
8603
|
-
...createEmptyState(migratedInstallationId ?? randomUuidFn()),
|
|
8604
|
-
...migratedCredentials === null ? {} : { activeAuth: migratedCredentials }
|
|
8605
|
-
};
|
|
8600
|
+
return normalized;
|
|
8606
8601
|
};
|
|
8607
8602
|
const loadState = (options) => {
|
|
8608
8603
|
const currentState = loadStateFromDisk();
|
|
8609
|
-
if (currentState !== null)
|
|
8610
|
-
|
|
8611
|
-
|
|
8612
|
-
|
|
8613
|
-
if (!existsSyncFn(deps.credentialsPath)) writeState(migratedState);
|
|
8604
|
+
if (currentState !== null) {
|
|
8605
|
+
if (currentState.needsMigration) withLock(() => {
|
|
8606
|
+
const latest = loadStateFromDisk();
|
|
8607
|
+
if (latest?.needsMigration) writeState(latest.state);
|
|
8614
8608
|
});
|
|
8615
|
-
return
|
|
8609
|
+
return currentState.state;
|
|
8616
8610
|
}
|
|
8617
8611
|
if (options?.persistIfMissing === true) {
|
|
8618
8612
|
const emptyState = createEmptyState();
|
|
8619
8613
|
withLock(() => {
|
|
8620
8614
|
if (!existsSyncFn(deps.credentialsPath)) writeState(emptyState);
|
|
8621
8615
|
});
|
|
8622
|
-
return loadStateFromDisk() ?? emptyState;
|
|
8616
|
+
return loadStateFromDisk()?.state ?? emptyState;
|
|
8623
8617
|
}
|
|
8624
8618
|
return null;
|
|
8625
8619
|
};
|
|
8626
8620
|
return {
|
|
8627
|
-
|
|
8621
|
+
clearCurrentAuthRequest: () => {
|
|
8628
8622
|
return Result.try({
|
|
8629
8623
|
catch: (cause) => new UnexpectedError({
|
|
8630
8624
|
cause,
|
|
@@ -8632,10 +8626,9 @@ const createFileCredentialsStore = (deps) => {
|
|
|
8632
8626
|
}),
|
|
8633
8627
|
try: () => {
|
|
8634
8628
|
withLock(() => {
|
|
8635
|
-
const latest = loadStateFromDisk() ?? migrateStateFromLegacy() ?? createEmptyState();
|
|
8636
8629
|
writeState({
|
|
8637
|
-
...
|
|
8638
|
-
|
|
8630
|
+
...loadStateFromDisk()?.state ?? createEmptyState(),
|
|
8631
|
+
currentAuthRequest: null
|
|
8639
8632
|
});
|
|
8640
8633
|
});
|
|
8641
8634
|
}
|
|
@@ -8650,27 +8643,22 @@ const createFileCredentialsStore = (deps) => {
|
|
|
8650
8643
|
try: () => {
|
|
8651
8644
|
withLock(() => {
|
|
8652
8645
|
writeState({
|
|
8653
|
-
...loadStateFromDisk() ??
|
|
8654
|
-
|
|
8655
|
-
pendingRequests: []
|
|
8646
|
+
...loadStateFromDisk()?.state ?? createEmptyState(),
|
|
8647
|
+
session: null
|
|
8656
8648
|
});
|
|
8657
8649
|
});
|
|
8658
8650
|
}
|
|
8659
8651
|
});
|
|
8660
8652
|
},
|
|
8661
|
-
|
|
8653
|
+
reset: () => {
|
|
8662
8654
|
return Result.try({
|
|
8663
8655
|
catch: (cause) => new UnexpectedError({
|
|
8664
8656
|
cause,
|
|
8665
|
-
message: "Failed to
|
|
8657
|
+
message: "Failed to reset local auth state"
|
|
8666
8658
|
}),
|
|
8667
8659
|
try: () => {
|
|
8668
8660
|
withLock(() => {
|
|
8669
|
-
|
|
8670
|
-
writeState({
|
|
8671
|
-
...latest,
|
|
8672
|
-
pendingRequests: latest.pendingRequests.filter((request) => request.authRequestId !== authRequestId)
|
|
8673
|
-
});
|
|
8661
|
+
writeState(createEmptyState());
|
|
8674
8662
|
});
|
|
8675
8663
|
}
|
|
8676
8664
|
});
|
|
@@ -8688,14 +8676,14 @@ const createFileCredentialsStore = (deps) => {
|
|
|
8688
8676
|
}
|
|
8689
8677
|
});
|
|
8690
8678
|
},
|
|
8691
|
-
|
|
8679
|
+
getCurrentAuthRequest: () => {
|
|
8692
8680
|
return Result.try({
|
|
8693
8681
|
catch: (cause) => new UnexpectedError({
|
|
8694
8682
|
cause,
|
|
8695
8683
|
message: "Failed to load local auth state"
|
|
8696
8684
|
}),
|
|
8697
8685
|
try: () => {
|
|
8698
|
-
return loadState()?.
|
|
8686
|
+
return loadState()?.currentAuthRequest ?? null;
|
|
8699
8687
|
}
|
|
8700
8688
|
});
|
|
8701
8689
|
},
|
|
@@ -8706,12 +8694,7 @@ const createFileCredentialsStore = (deps) => {
|
|
|
8706
8694
|
message: "Failed to load local auth state"
|
|
8707
8695
|
}),
|
|
8708
8696
|
try: () => {
|
|
8709
|
-
|
|
8710
|
-
if (state?.activeAuth === null || state === null) return null;
|
|
8711
|
-
return {
|
|
8712
|
-
...state.activeAuth.agentName === void 0 ? {} : { agentName: state.activeAuth.agentName },
|
|
8713
|
-
apiKey: state.activeAuth.apiKey
|
|
8714
|
-
};
|
|
8697
|
+
return loadState()?.session ?? null;
|
|
8715
8698
|
}
|
|
8716
8699
|
});
|
|
8717
8700
|
},
|
|
@@ -8724,17 +8707,15 @@ const createFileCredentialsStore = (deps) => {
|
|
|
8724
8707
|
try: () => {
|
|
8725
8708
|
withLock(() => {
|
|
8726
8709
|
writeState({
|
|
8727
|
-
...loadStateFromDisk() ??
|
|
8728
|
-
|
|
8729
|
-
|
|
8730
|
-
apiKey: credentials.apiKey
|
|
8731
|
-
}
|
|
8710
|
+
...loadStateFromDisk()?.state ?? createEmptyState(),
|
|
8711
|
+
currentAuthRequest: null,
|
|
8712
|
+
session: credentials
|
|
8732
8713
|
});
|
|
8733
8714
|
});
|
|
8734
8715
|
}
|
|
8735
8716
|
});
|
|
8736
8717
|
},
|
|
8737
|
-
|
|
8718
|
+
saveCurrentAuthRequest: (request) => {
|
|
8738
8719
|
return Result.try({
|
|
8739
8720
|
catch: (cause) => new UnexpectedError({
|
|
8740
8721
|
cause,
|
|
@@ -8742,43 +8723,13 @@ const createFileCredentialsStore = (deps) => {
|
|
|
8742
8723
|
}),
|
|
8743
8724
|
try: () => {
|
|
8744
8725
|
withLock(() => {
|
|
8745
|
-
const currentState = loadStateFromDisk() ?? migrateStateFromLegacy() ?? createEmptyState();
|
|
8746
8726
|
writeState({
|
|
8747
|
-
...
|
|
8748
|
-
|
|
8749
|
-
|
|
8750
|
-
|
|
8751
|
-
|
|
8752
|
-
|
|
8753
|
-
},
|
|
8754
|
-
pendingRequests: namespaceKey === void 0 ? [] : currentState.pendingRequests.filter((request) => request.namespaceKey !== namespaceKey)
|
|
8755
|
-
});
|
|
8756
|
-
});
|
|
8757
|
-
}
|
|
8758
|
-
});
|
|
8759
|
-
},
|
|
8760
|
-
savePendingRequest: (request) => {
|
|
8761
|
-
return Result.try({
|
|
8762
|
-
catch: (cause) => new UnexpectedError({
|
|
8763
|
-
cause,
|
|
8764
|
-
message: "Failed to update local auth state"
|
|
8765
|
-
}),
|
|
8766
|
-
try: () => {
|
|
8767
|
-
withLock(() => {
|
|
8768
|
-
const currentState = loadStateFromDisk() ?? migrateStateFromLegacy() ?? createEmptyState();
|
|
8769
|
-
const pendingRequests = currentState.pendingRequests.filter((entry) => entry.authRequestId !== request.authRequestId);
|
|
8770
|
-
pendingRequests.push({
|
|
8771
|
-
authRequestId: request.authRequestId,
|
|
8772
|
-
code: request.code,
|
|
8773
|
-
createdAt: request.createdAt,
|
|
8774
|
-
expiresAt: request.expiresAt,
|
|
8775
|
-
namespaceKey: request.namespaceKey,
|
|
8776
|
-
...request.scopeFingerprint === void 0 ? {} : { scopeFingerprint: request.scopeFingerprint },
|
|
8777
|
-
verificationUrl: request.verificationUrl
|
|
8778
|
-
});
|
|
8779
|
-
writeState({
|
|
8780
|
-
...currentState,
|
|
8781
|
-
pendingRequests
|
|
8727
|
+
...loadStateFromDisk()?.state ?? createEmptyState(),
|
|
8728
|
+
currentAuthRequest: {
|
|
8729
|
+
authRequestId: request.authRequestId,
|
|
8730
|
+
expiresAt: request.expiresAt,
|
|
8731
|
+
verificationUrl: request.verificationUrl
|
|
8732
|
+
}
|
|
8782
8733
|
});
|
|
8783
8734
|
});
|
|
8784
8735
|
}
|
|
@@ -8859,14 +8810,17 @@ const telemetryRuntimeFields = (env, configDir) => {
|
|
|
8859
8810
|
credentialsPath: join(configDir, "auth-state.json"),
|
|
8860
8811
|
envApiKey: env["OGMENT_API_KEY"],
|
|
8861
8812
|
executionEnvironment: detectExecutionEnvironment(env),
|
|
8862
|
-
legacyCredentialsPath: join(configDir, "credentials.json"),
|
|
8863
8813
|
telemetryDisabled: telemetryDisabledFromEnv(env),
|
|
8864
|
-
telemetryPath: join(configDir, "telemetry.json"),
|
|
8865
8814
|
version: VERSION$2
|
|
8866
8815
|
};
|
|
8867
8816
|
};
|
|
8817
|
+
const resolveConfigDir = (env, homeDirectory) => {
|
|
8818
|
+
const configuredDir = env["OGMENT_CONFIG_DIR"]?.trim();
|
|
8819
|
+
if (configuredDir && configuredDir.length > 0) return configuredDir;
|
|
8820
|
+
return join(homeDirectory, ".config", "ogment");
|
|
8821
|
+
};
|
|
8868
8822
|
const createRuntimeConfig = (env = process.env, homeDirectory = homedir()) => {
|
|
8869
|
-
const configDir =
|
|
8823
|
+
const configDir = resolveConfigDir(env, homeDirectory);
|
|
8870
8824
|
const envBaseUrl = env["OGMENT_BASE_URL"];
|
|
8871
8825
|
const hasBaseUrlOverride = typeof envBaseUrl === "string";
|
|
8872
8826
|
return {
|
|
@@ -8884,7 +8838,7 @@ const createRuntimeConfig = (env = process.env, homeDirectory = homedir()) => {
|
|
|
8884
8838
|
};
|
|
8885
8839
|
};
|
|
8886
8840
|
const createTelemetryRuntimeConfig = (env = process.env, homeDirectory = homedir()) => {
|
|
8887
|
-
const configDir =
|
|
8841
|
+
const configDir = resolveConfigDir(env, homeDirectory);
|
|
8888
8842
|
const parsedBaseUrl = baseUrlSchema.safeParse(env["OGMENT_BASE_URL"]);
|
|
8889
8843
|
return {
|
|
8890
8844
|
baseUrl: parsedBaseUrl.success ? parsedBaseUrl.data : DEFAULT_OGMENT_BASE_URL,
|
|
@@ -14140,7 +14094,13 @@ const cliOrgSchema = object({
|
|
|
14140
14094
|
role: string(),
|
|
14141
14095
|
servers: array(cliServerSchema)
|
|
14142
14096
|
}).strict();
|
|
14097
|
+
const cliActingAgentSchema = object({
|
|
14098
|
+
agentId: string().uuid(),
|
|
14099
|
+
agentName: string().min(1),
|
|
14100
|
+
boundInstallationId: string().uuid().nullable()
|
|
14101
|
+
}).strict();
|
|
14143
14102
|
const cliMeDataSchema = object({
|
|
14103
|
+
actingAgent: cliActingAgentSchema.nullable(),
|
|
14144
14104
|
email: string().nullable(),
|
|
14145
14105
|
imageUrl: string().nullable(),
|
|
14146
14106
|
name: string().nullable(),
|
|
@@ -14151,72 +14111,60 @@ const accountMeSchema = cliSuccessEnvelopeSchema(cliMeDataSchema);
|
|
|
14151
14111
|
|
|
14152
14112
|
//#endregion
|
|
14153
14113
|
//#region ../../packages/shared/src/cli/auth.ts
|
|
14154
|
-
const deviceCodeStartDataSchema = object({
|
|
14155
|
-
deviceCode: string().min(1),
|
|
14156
|
-
expiresIn: number$1().int().positive(),
|
|
14157
|
-
interval: number$1().int().positive(),
|
|
14158
|
-
userCode: string().min(1),
|
|
14159
|
-
verificationUri: string().url()
|
|
14160
|
-
}).strict();
|
|
14161
|
-
const deviceCodeStartSchema = cliSuccessEnvelopeSchema(deviceCodeStartDataSchema);
|
|
14162
14114
|
const authStartDataSchema = object({
|
|
14163
14115
|
authRequestId: string().min(1),
|
|
14116
|
+
disposition: _enum([
|
|
14117
|
+
"created",
|
|
14118
|
+
"reused_approved",
|
|
14119
|
+
"reused_pending"
|
|
14120
|
+
]),
|
|
14164
14121
|
expiresAt: isoTimestampSchema,
|
|
14165
|
-
userCode: string().min(1),
|
|
14166
14122
|
verificationUrl: string().url()
|
|
14167
14123
|
}).strict();
|
|
14168
14124
|
const authStartSchema = cliSuccessEnvelopeSchema(authStartDataSchema);
|
|
14169
|
-
const deviceTokenPendingDataSchema = object({ status: literal("authorization_pending") }).strict();
|
|
14170
|
-
const deviceTokenApprovedDataSchema = object({
|
|
14171
|
-
agentName: string().min(1),
|
|
14172
|
-
apiKey: string().min(1),
|
|
14173
|
-
status: literal("approved")
|
|
14174
|
-
}).strict();
|
|
14175
|
-
const deviceTokenDataSchema = discriminatedUnion("status", [deviceTokenPendingDataSchema, deviceTokenApprovedDataSchema]);
|
|
14176
|
-
const deviceTokenSchema = cliSuccessEnvelopeSchema(deviceTokenDataSchema);
|
|
14177
|
-
const deviceTokenApprovedSchema = cliSuccessEnvelopeSchema(deviceTokenApprovedDataSchema);
|
|
14178
14125
|
const authExchangePendingDataSchema = object({ status: literal("authorization_pending") }).strict();
|
|
14179
14126
|
const authExchangeApprovedDataSchema = object({
|
|
14127
|
+
agentId: string().uuid(),
|
|
14180
14128
|
agentName: string().min(1),
|
|
14181
14129
|
apiKey: string().min(1),
|
|
14182
|
-
|
|
14130
|
+
credentialId: string().uuid(),
|
|
14183
14131
|
status: literal("approved")
|
|
14184
14132
|
}).strict();
|
|
14185
14133
|
const authExchangeExpiredDataSchema = object({ status: literal("expired") }).strict();
|
|
14186
|
-
const authExchangeDeniedDataSchema = object({ status: literal("denied") }).strict();
|
|
14187
|
-
const authExchangeConflictDataSchema = object({ status: literal("conflict") }).strict();
|
|
14188
14134
|
const authExchangeInvalidDataSchema = object({ status: literal("invalid") }).strict();
|
|
14135
|
+
const authExchangeSupersededDataSchema = object({ status: literal("superseded") }).strict();
|
|
14189
14136
|
const authExchangeDataSchema = discriminatedUnion("status", [
|
|
14190
14137
|
authExchangePendingDataSchema,
|
|
14191
14138
|
authExchangeApprovedDataSchema,
|
|
14192
14139
|
authExchangeExpiredDataSchema,
|
|
14193
|
-
|
|
14194
|
-
|
|
14195
|
-
authExchangeInvalidDataSchema
|
|
14140
|
+
authExchangeInvalidDataSchema,
|
|
14141
|
+
authExchangeSupersededDataSchema
|
|
14196
14142
|
]);
|
|
14197
14143
|
const authExchangeSchema = cliSuccessEnvelopeSchema(authExchangeDataSchema);
|
|
14198
14144
|
const authExchangeApprovedSchema = cliSuccessEnvelopeSchema(authExchangeApprovedDataSchema);
|
|
14199
|
-
const
|
|
14200
|
-
const
|
|
14145
|
+
const authMutationSuccessDataSchema = object({ success: literal(true) }).strict();
|
|
14146
|
+
const authLogoutDataSchema = authMutationSuccessDataSchema;
|
|
14147
|
+
const authLogoutSchema = cliSuccessEnvelopeSchema(authLogoutDataSchema);
|
|
14148
|
+
const authResetDataSchema = authMutationSuccessDataSchema;
|
|
14149
|
+
const authResetSchema = cliSuccessEnvelopeSchema(authResetDataSchema);
|
|
14201
14150
|
|
|
14202
14151
|
//#endregion
|
|
14203
14152
|
//#region ../../packages/shared/src/cli/endpoints.ts
|
|
14204
14153
|
const cliEndpoints = {
|
|
14205
14154
|
accountMe: "/api/v1/cli/me",
|
|
14206
|
-
authExchange: "/api/v1/cli/auth/exchange",
|
|
14207
14155
|
authStart: "/api/v1/cli/auth/start",
|
|
14208
|
-
|
|
14209
|
-
|
|
14210
|
-
|
|
14156
|
+
authExchange: "/api/v1/cli/auth/exchange",
|
|
14157
|
+
authLogout: "/api/v1/cli/auth/logout",
|
|
14158
|
+
authReset: "/api/v1/cli/auth/reset",
|
|
14211
14159
|
telemetry: "/api/v1/cli/telemetry"
|
|
14212
14160
|
};
|
|
14213
14161
|
|
|
14214
14162
|
//#endregion
|
|
14215
14163
|
//#region ../../packages/shared/src/cli/telemetry.ts
|
|
14216
14164
|
const cliCommandKindSchema = _enum([
|
|
14217
|
-
"
|
|
14218
|
-
"
|
|
14219
|
-
"
|
|
14165
|
+
"login",
|
|
14166
|
+
"logout",
|
|
14167
|
+
"reset",
|
|
14220
14168
|
"catalog_detail",
|
|
14221
14169
|
"catalog_summary",
|
|
14222
14170
|
"catalog_tool_detail",
|
|
@@ -14368,25 +14316,16 @@ const exitCodeForError = (error) => {
|
|
|
14368
14316
|
|
|
14369
14317
|
//#endregion
|
|
14370
14318
|
//#region src/commands/auth.ts
|
|
14371
|
-
const
|
|
14372
|
-
const loginOptions =
|
|
14373
|
-
if (options.mode === "apiKey") return {
|
|
14374
|
-
apiKey: options.apiKey,
|
|
14375
|
-
mode: "apiKey"
|
|
14376
|
-
};
|
|
14377
|
-
return {
|
|
14378
|
-
mode: "device",
|
|
14379
|
-
...options.onPending === void 0 ? {} : { onPending: options.onPending }
|
|
14380
|
-
};
|
|
14381
|
-
})();
|
|
14319
|
+
const runLoginCommand = async (context, options) => {
|
|
14320
|
+
const loginOptions = options.onPending === void 0 ? {} : { onPending: options.onPending };
|
|
14382
14321
|
return context.services.auth.login(loginOptions);
|
|
14383
14322
|
};
|
|
14384
|
-
const
|
|
14385
|
-
return context.services.auth.status(context.apiKeyOverride);
|
|
14386
|
-
};
|
|
14387
|
-
const runAuthLogoutCommand = async (context) => {
|
|
14323
|
+
const runLogoutCommand = async (context) => {
|
|
14388
14324
|
return context.services.auth.logout();
|
|
14389
14325
|
};
|
|
14326
|
+
const runResetCommand = async (context) => {
|
|
14327
|
+
return context.services.auth.reset();
|
|
14328
|
+
};
|
|
14390
14329
|
|
|
14391
14330
|
//#endregion
|
|
14392
14331
|
//#region src/commands/server-context.ts
|
|
@@ -14760,13 +14699,6 @@ const withOrg = (orgSlug) => {
|
|
|
14760
14699
|
return orgSlug === void 0 ? [] : [`--org ${orgSlug}`];
|
|
14761
14700
|
};
|
|
14762
14701
|
const cliCommands = {
|
|
14763
|
-
auth: {
|
|
14764
|
-
help: () => "ogment auth --help",
|
|
14765
|
-
login: () => "ogment auth login",
|
|
14766
|
-
loginWithApiKeyRedacted: () => "ogment auth login --api-key <redacted>",
|
|
14767
|
-
logout: () => "ogment auth logout",
|
|
14768
|
-
status: () => "ogment auth status"
|
|
14769
|
-
},
|
|
14770
14702
|
catalog: {
|
|
14771
14703
|
command: (serverId, toolName, orgSlug) => [
|
|
14772
14704
|
"ogment catalog",
|
|
@@ -14825,14 +14757,19 @@ const cliCommands = {
|
|
|
14825
14757
|
if (scope === null) return "ogment --help";
|
|
14826
14758
|
return `ogment ${scope} --help`;
|
|
14827
14759
|
},
|
|
14760
|
+
login: { command: () => "ogment login" },
|
|
14761
|
+
logout: { command: () => "ogment logout" },
|
|
14762
|
+
reset: { command: () => "ogment reset" },
|
|
14828
14763
|
root: {
|
|
14829
14764
|
command: () => "ogment",
|
|
14830
14765
|
commandsSurface: () => {
|
|
14831
14766
|
return [
|
|
14832
|
-
"
|
|
14833
|
-
"
|
|
14834
|
-
"
|
|
14767
|
+
"login",
|
|
14768
|
+
"logout",
|
|
14769
|
+
"reset",
|
|
14835
14770
|
"catalog",
|
|
14771
|
+
"catalog <server-id>",
|
|
14772
|
+
"catalog <server-id> <tool-name>",
|
|
14836
14773
|
"search <server-id>",
|
|
14837
14774
|
"execute <server-id>",
|
|
14838
14775
|
"status"
|
|
@@ -14904,15 +14841,11 @@ const ensureSuccess = (result, runtime, context) => {
|
|
|
14904
14841
|
}
|
|
14905
14842
|
return result.unwrap();
|
|
14906
14843
|
};
|
|
14907
|
-
const nextActionsForLogin = (payload
|
|
14908
|
-
return [nextAction("
|
|
14844
|
+
const nextActionsForLogin = (payload) => {
|
|
14845
|
+
return [nextAction("inspect_status", "Inspect status", cliCommands.status.command(), `Verify the connected CLI state for ${payload.agentName}.`, "immediate"), nextAction("discover_servers", "Discover servers", cliCommands.catalog.command(), `Logged in as ${payload.agentName}; discover available servers.`, "after_auth")];
|
|
14909
14846
|
};
|
|
14910
|
-
const nextActionsForPendingLogin = (
|
|
14911
|
-
return [nextAction("
|
|
14912
|
-
};
|
|
14913
|
-
const nextActionsForAuthStatus = (payload) => {
|
|
14914
|
-
if (!payload.loggedIn) return [nextAction("login", "Authenticate", cliCommands.auth.login(), "No API key is configured locally; login is required.", "immediate")];
|
|
14915
|
-
return [nextAction("discover_servers", "Discover servers", cliCommands.catalog.command(), `Authenticated via ${payload.apiKeySource}; discover servers next.`, "after_auth")];
|
|
14847
|
+
const nextActionsForPendingLogin = (authRequestId, verificationUrl) => {
|
|
14848
|
+
return [nextAction("complete_login", "Complete login", cliCommands.login.command(), `Approve request ${authRequestId} at ${verificationUrl}, then run login again to finish local sign-in.`, "immediate"), nextAction("inspect_status", "Inspect status", cliCommands.status.command(), "Inspect the current CLI state and diagnostics.", "if_expired")];
|
|
14916
14849
|
};
|
|
14917
14850
|
const nextActionsForCatalogSummary = (payload, context) => {
|
|
14918
14851
|
const actions = [];
|
|
@@ -14941,7 +14874,7 @@ const nextActionsForExecute = (payload) => {
|
|
|
14941
14874
|
return [nextAction("search_tools", "Search tools again", cliCommands.search.inspectAllTools(payload.serverId), `Reinspect tool definitions on ${payload.serverId} before the next execution.`, "after_execute")];
|
|
14942
14875
|
};
|
|
14943
14876
|
const nextActionsForStatus = (payload) => {
|
|
14944
|
-
if (!payload.auth.apiKeyPresent) return [nextAction("login", "Authenticate", cliCommands.
|
|
14877
|
+
if (!payload.auth.apiKeyPresent) return [nextAction("login", "Authenticate", cliCommands.login.command(), "Status detected no API key; authenticate first.", "immediate")];
|
|
14945
14878
|
return [nextAction("discover_servers", "Discover servers", cliCommands.catalog.command(), `Connectivity is ${payload.summary.status}; discover available servers.`, "after_status")];
|
|
14946
14879
|
};
|
|
14947
14880
|
const codeSourceFromValue = (value) => {
|
|
@@ -14956,87 +14889,78 @@ const inputSourceFromValue = (value) => {
|
|
|
14956
14889
|
return "inline_json";
|
|
14957
14890
|
};
|
|
14958
14891
|
const runLoginFlow = async (runtime, options) => {
|
|
14959
|
-
const
|
|
14960
|
-
|
|
14961
|
-
invokedCommand: cliCommands.auth.loginWithApiKeyRedacted(),
|
|
14962
|
-
mode: "apiKey"
|
|
14963
|
-
} : {
|
|
14964
|
-
commandOptions: { mode: "device" },
|
|
14965
|
-
invokedCommand: cliCommands.auth.login(),
|
|
14966
|
-
mode: "device"
|
|
14967
|
-
};
|
|
14968
|
-
const data = ensureSuccess(await runAuthLoginCommand(runtime.context, commandOptions), runtime, {
|
|
14969
|
-
command: invokedCommand,
|
|
14970
|
-
entity: { mode }
|
|
14971
|
-
});
|
|
14892
|
+
const invokedCommand = cliCommands.login.command();
|
|
14893
|
+
const data = ensureSuccess(await runLoginCommand(runtime.context, options), runtime, { command: invokedCommand });
|
|
14972
14894
|
if (!data.loggedIn) {
|
|
14973
14895
|
const pendingOutput = {
|
|
14974
|
-
event: "
|
|
14896
|
+
event: "login.pending",
|
|
14975
14897
|
loggedIn: false,
|
|
14976
14898
|
verification: data.verification
|
|
14977
14899
|
};
|
|
14978
14900
|
runtime.output.success(pendingOutput, {
|
|
14979
14901
|
command: invokedCommand,
|
|
14980
14902
|
entity: {
|
|
14981
|
-
event: "
|
|
14982
|
-
mode,
|
|
14903
|
+
event: "login.pending",
|
|
14983
14904
|
verification: {
|
|
14984
|
-
|
|
14985
|
-
|
|
14905
|
+
authRequestId: data.verification.authRequestId,
|
|
14906
|
+
verificationUrl: data.verification.verificationUrl
|
|
14986
14907
|
}
|
|
14987
14908
|
},
|
|
14988
|
-
nextActions: nextActionsForPendingLogin(data.verification.
|
|
14909
|
+
nextActions: nextActionsForPendingLogin(data.verification.authRequestId, data.verification.verificationUrl)
|
|
14989
14910
|
});
|
|
14990
14911
|
return;
|
|
14991
14912
|
}
|
|
14992
14913
|
const outputData = {
|
|
14993
14914
|
...data,
|
|
14994
|
-
event: "
|
|
14915
|
+
event: "login.completed"
|
|
14995
14916
|
};
|
|
14996
14917
|
runtime.output.success(outputData, {
|
|
14997
14918
|
command: invokedCommand,
|
|
14998
14919
|
entity: {
|
|
14999
14920
|
agentName: data.agentName,
|
|
15000
|
-
event: "
|
|
14921
|
+
event: "login.completed",
|
|
15001
14922
|
loggedIn: data.loggedIn,
|
|
15002
|
-
mode,
|
|
15003
14923
|
outcome: data.outcome
|
|
15004
14924
|
},
|
|
15005
|
-
nextActions: nextActionsForLogin(data
|
|
14925
|
+
nextActions: nextActionsForLogin(data)
|
|
15006
14926
|
});
|
|
15007
14927
|
};
|
|
15008
|
-
const
|
|
15009
|
-
|
|
15010
|
-
await runLoginFlow(runtime, {
|
|
15011
|
-
apiKey: invocation.apiKey,
|
|
15012
|
-
mode: "apiKey"
|
|
15013
|
-
});
|
|
15014
|
-
return;
|
|
15015
|
-
}
|
|
15016
|
-
await runLoginFlow(runtime, { mode: "device" });
|
|
14928
|
+
const executeLoginInvocation = async (runtime, _invocation) => {
|
|
14929
|
+
await runLoginFlow(runtime, {});
|
|
15017
14930
|
};
|
|
15018
|
-
const
|
|
15019
|
-
const command = cliCommands.
|
|
15020
|
-
const data = ensureSuccess(await
|
|
15021
|
-
|
|
14931
|
+
const executeLogoutInvocation = async (runtime) => {
|
|
14932
|
+
const command = cliCommands.logout.command();
|
|
14933
|
+
const data = ensureSuccess(await runLogoutCommand(runtime.context), runtime, { command });
|
|
14934
|
+
const outputData = {
|
|
14935
|
+
...data,
|
|
14936
|
+
event: "logout.completed"
|
|
14937
|
+
};
|
|
14938
|
+
runtime.output.success(outputData, {
|
|
15022
14939
|
command,
|
|
15023
14940
|
entity: {
|
|
15024
|
-
|
|
15025
|
-
|
|
14941
|
+
event: "logout.completed",
|
|
14942
|
+
localStateCleared: data.localStateCleared,
|
|
14943
|
+
remoteSignedOut: data.remoteSignedOut
|
|
15026
14944
|
},
|
|
15027
|
-
nextActions:
|
|
14945
|
+
nextActions: [nextAction("login", "Authenticate again", cliCommands.login.command(), "Sign-out completed; run login when you want to reconnect this installation.", "after_logout")]
|
|
15028
14946
|
});
|
|
15029
14947
|
};
|
|
15030
|
-
const
|
|
15031
|
-
const command = cliCommands.
|
|
15032
|
-
const data = ensureSuccess(await
|
|
15033
|
-
|
|
14948
|
+
const executeResetInvocation = async (runtime) => {
|
|
14949
|
+
const command = cliCommands.reset.command();
|
|
14950
|
+
const data = ensureSuccess(await runResetCommand(runtime.context), runtime, { command });
|
|
14951
|
+
const outputData = {
|
|
14952
|
+
...data,
|
|
14953
|
+
event: "reset.completed"
|
|
14954
|
+
};
|
|
14955
|
+
runtime.output.success(outputData, {
|
|
15034
14956
|
command,
|
|
15035
14957
|
entity: {
|
|
15036
|
-
|
|
15037
|
-
|
|
14958
|
+
event: "reset.completed",
|
|
14959
|
+
installationReset: data.installationReset,
|
|
14960
|
+
localStateCleared: data.localStateCleared,
|
|
14961
|
+
remoteReset: data.remoteReset
|
|
15038
14962
|
},
|
|
15039
|
-
nextActions: [nextAction("login", "Authenticate
|
|
14963
|
+
nextActions: [nextAction("login", "Authenticate this fresh install", cliCommands.login.command(), "Reset completed; run login to create or reconnect this installation.", "after_reset"), nextAction("inspect_status", "Inspect status", cliCommands.status.command(), "Inspect the fresh-install CLI state and diagnostics.", "after_reset")]
|
|
15040
14964
|
});
|
|
15041
14965
|
};
|
|
15042
14966
|
const executeCatalogInvocation = async (runtime, invocation) => {
|
|
@@ -15197,19 +15121,19 @@ const executeRootInvocation = (runtime) => {
|
|
|
15197
15121
|
runtime.output.success({ commands: cliCommands.root.commandsSurface() }, {
|
|
15198
15122
|
command: cliCommands.root.command(),
|
|
15199
15123
|
entity: null,
|
|
15200
|
-
nextActions: [nextAction("login", "Authenticate", cliCommands.
|
|
15124
|
+
nextActions: [nextAction("login", "Authenticate", cliCommands.login.command(), "Authenticate first so catalog, search, and execute commands can run.", "immediate"), nextAction("catalog", "Discover servers", cliCommands.catalog.command(), "List accessible servers before running Codemode search or execute.", "after_auth")]
|
|
15201
15125
|
});
|
|
15202
15126
|
};
|
|
15203
15127
|
const executeInvocation = async (runtime, invocation) => {
|
|
15204
15128
|
switch (invocation.kind) {
|
|
15205
|
-
case "
|
|
15206
|
-
await
|
|
15129
|
+
case "login":
|
|
15130
|
+
await executeLoginInvocation(runtime, invocation);
|
|
15207
15131
|
return;
|
|
15208
|
-
case "
|
|
15209
|
-
await
|
|
15132
|
+
case "logout":
|
|
15133
|
+
await executeLogoutInvocation(runtime);
|
|
15210
15134
|
return;
|
|
15211
|
-
case "
|
|
15212
|
-
await
|
|
15135
|
+
case "reset":
|
|
15136
|
+
await executeResetInvocation(runtime);
|
|
15213
15137
|
return;
|
|
15214
15138
|
case "catalog":
|
|
15215
15139
|
await executeCatalogInvocation(runtime, invocation);
|
|
@@ -15285,19 +15209,19 @@ const nextActionForParseError = (scope, helpCommand) => {
|
|
|
15285
15209
|
};
|
|
15286
15210
|
};
|
|
15287
15211
|
const parseActionsForScope = (scope, helpAction) => {
|
|
15288
|
-
if (scope === "
|
|
15212
|
+
if (scope === "login" || scope === "logout" || scope === "reset") return [
|
|
15289
15213
|
{
|
|
15290
|
-
command: cliCommands.
|
|
15291
|
-
id: "
|
|
15292
|
-
reason: "Authenticate
|
|
15293
|
-
title: "
|
|
15214
|
+
command: cliCommands.login.command(),
|
|
15215
|
+
id: "login",
|
|
15216
|
+
reason: "Authenticate this CLI installation.",
|
|
15217
|
+
title: "Login",
|
|
15294
15218
|
when: "immediate"
|
|
15295
15219
|
},
|
|
15296
15220
|
{
|
|
15297
|
-
command: cliCommands.
|
|
15298
|
-
id: "
|
|
15299
|
-
reason: "
|
|
15300
|
-
title: "
|
|
15221
|
+
command: cliCommands.status.command(),
|
|
15222
|
+
id: "status",
|
|
15223
|
+
reason: "Inspect the current CLI state and diagnostics.",
|
|
15224
|
+
title: "Status",
|
|
15301
15225
|
when: "immediate"
|
|
15302
15226
|
},
|
|
15303
15227
|
helpAction
|
|
@@ -60760,8 +60684,8 @@ const createAccountService = (deps) => {
|
|
|
60760
60684
|
mapStatusError: (response, body) => {
|
|
60761
60685
|
if (response.status === 401) return new AuthError({
|
|
60762
60686
|
code: ERROR_CODE.authInvalidCredentials,
|
|
60763
|
-
message: "Authentication failed. Run `ogment
|
|
60764
|
-
recovery: { command: "ogment
|
|
60687
|
+
message: "Authentication failed. Run `ogment login` again.",
|
|
60688
|
+
recovery: { command: "ogment login" }
|
|
60765
60689
|
});
|
|
60766
60690
|
return new RemoteRequestError({
|
|
60767
60691
|
body,
|
|
@@ -60782,7 +60706,6 @@ const createAccountService = (deps) => {
|
|
|
60782
60706
|
|
|
60783
60707
|
//#endregion
|
|
60784
60708
|
//#region src/services/auth.ts
|
|
60785
|
-
const DEFAULT_NAMESPACE_KEY = "default";
|
|
60786
60709
|
const toEndpointUrl = (baseUrl, endpoint) => {
|
|
60787
60710
|
return `${baseUrl}${endpoint}`;
|
|
60788
60711
|
};
|
|
@@ -60792,85 +60715,138 @@ const authStartUrl = (baseUrl) => {
|
|
|
60792
60715
|
const authExchangeUrl = (baseUrl) => {
|
|
60793
60716
|
return toEndpointUrl(baseUrl, cliEndpoints.authExchange);
|
|
60794
60717
|
};
|
|
60795
|
-
const
|
|
60718
|
+
const authLogoutUrl = (baseUrl) => {
|
|
60719
|
+
return toEndpointUrl(baseUrl, cliEndpoints.authLogout);
|
|
60720
|
+
};
|
|
60721
|
+
const authResetUrl = (baseUrl) => {
|
|
60722
|
+
return toEndpointUrl(baseUrl, cliEndpoints.authReset);
|
|
60723
|
+
};
|
|
60724
|
+
const accountMeUrl = (baseUrl) => {
|
|
60725
|
+
return toEndpointUrl(baseUrl, cliEndpoints.accountMe);
|
|
60726
|
+
};
|
|
60727
|
+
const toLoginPendingInfo = (request) => {
|
|
60728
|
+
if (request === null) return null;
|
|
60729
|
+
return {
|
|
60730
|
+
authRequestId: request.authRequestId,
|
|
60731
|
+
verificationUrl: request.verificationUrl
|
|
60732
|
+
};
|
|
60733
|
+
};
|
|
60734
|
+
const isExpiredCurrentAuthRequest = (request, nowMs) => {
|
|
60796
60735
|
const parsedExpiresAt = Date.parse(request.expiresAt);
|
|
60797
60736
|
return !Number.isNaN(parsedExpiresAt) && parsedExpiresAt <= nowMs;
|
|
60798
60737
|
};
|
|
60799
60738
|
const createAuthService = (deps) => {
|
|
60800
60739
|
const now = deps.now ?? Date.now;
|
|
60801
|
-
const storeApprovedAuth = (approvedAuth
|
|
60802
|
-
return deps.credentialsStore.storeApprovedAuth({
|
|
60803
|
-
agentName: approvedAuth.agentName,
|
|
60804
|
-
apiKey: approvedAuth.apiKey
|
|
60805
|
-
}, namespaceKey);
|
|
60806
|
-
};
|
|
60807
|
-
const saveApiKeyAuth = (approvedAuth) => {
|
|
60740
|
+
const storeApprovedAuth = (approvedAuth) => {
|
|
60808
60741
|
return deps.credentialsStore.save({
|
|
60742
|
+
agentId: approvedAuth.agentId,
|
|
60809
60743
|
agentName: approvedAuth.agentName,
|
|
60810
|
-
apiKey: approvedAuth.apiKey
|
|
60744
|
+
apiKey: approvedAuth.apiKey,
|
|
60745
|
+
credentialId: approvedAuth.credentialId,
|
|
60746
|
+
signedInAt: new Date(now()).toISOString()
|
|
60811
60747
|
});
|
|
60812
60748
|
};
|
|
60813
|
-
const
|
|
60814
|
-
const
|
|
60815
|
-
if (Result.isError(
|
|
60816
|
-
const
|
|
60817
|
-
if (Result.isError(
|
|
60818
|
-
const
|
|
60819
|
-
|
|
60749
|
+
const loadLocalAuthSnapshot = () => {
|
|
60750
|
+
const installationId = deps.credentialsStore.getInstallationId();
|
|
60751
|
+
if (Result.isError(installationId)) return installationId;
|
|
60752
|
+
const session = deps.credentialsStore.load();
|
|
60753
|
+
if (Result.isError(session)) return session;
|
|
60754
|
+
const currentAuthRequest = deps.credentialsStore.getCurrentAuthRequest();
|
|
60755
|
+
if (Result.isError(currentAuthRequest)) return currentAuthRequest;
|
|
60756
|
+
return Result.ok({
|
|
60757
|
+
currentAuthRequest: currentAuthRequest.value,
|
|
60758
|
+
installationId: installationId.value,
|
|
60759
|
+
session: session.value
|
|
60820
60760
|
});
|
|
60821
|
-
|
|
60822
|
-
|
|
60823
|
-
|
|
60824
|
-
|
|
60825
|
-
|
|
60826
|
-
|
|
60827
|
-
|
|
60828
|
-
|
|
60829
|
-
|
|
60830
|
-
|
|
60831
|
-
|
|
60832
|
-
|
|
60833
|
-
|
|
60834
|
-
|
|
60835
|
-
|
|
60836
|
-
|
|
60837
|
-
|
|
60761
|
+
};
|
|
60762
|
+
const clearCurrentAuthRequest = () => {
|
|
60763
|
+
return deps.credentialsStore.clearCurrentAuthRequest();
|
|
60764
|
+
};
|
|
60765
|
+
const toStoredAuthorizationHeader = (session) => {
|
|
60766
|
+
return session === null ? null : `Bearer ${session.apiKey}`;
|
|
60767
|
+
};
|
|
60768
|
+
const validateStoredCredentials = async (apiKey) => {
|
|
60769
|
+
const response = await requestJson(deps.httpClient, accountMeUrl(deps.baseUrl), accountMeSchema, { headers: { Authorization: `Bearer ${apiKey}` } }, {
|
|
60770
|
+
context: "account response",
|
|
60771
|
+
mapStatusError: (httpResponse, body) => {
|
|
60772
|
+
if (httpResponse.status === 401) return new AuthError({
|
|
60773
|
+
code: ERROR_CODE.authInvalidCredentials,
|
|
60774
|
+
message: "Stored CLI session is invalid. Run `ogment login` to sign in again.",
|
|
60775
|
+
recovery: { command: "ogment login" }
|
|
60776
|
+
});
|
|
60777
|
+
return new RemoteRequestError({
|
|
60838
60778
|
body,
|
|
60839
|
-
httpStatus:
|
|
60840
|
-
message: "Failed to
|
|
60841
|
-
operation: "
|
|
60779
|
+
httpStatus: httpResponse.status,
|
|
60780
|
+
message: "Failed to validate current CLI session",
|
|
60781
|
+
operation: "account/fetch",
|
|
60842
60782
|
raw: body,
|
|
60843
60783
|
source: "http"
|
|
60844
|
-
}),
|
|
60845
|
-
operation: "auth/exchange"
|
|
60846
|
-
});
|
|
60847
|
-
if (Result.isError(exchangePayload)) return exchangePayload;
|
|
60848
|
-
const exchangeData = exchangePayload.value.data;
|
|
60849
|
-
if (exchangeData.status === "authorization_pending") continue;
|
|
60850
|
-
if (exchangeData.status === "approved") {
|
|
60851
|
-
const storeResult = storeApprovedAuth({
|
|
60852
|
-
agentName: exchangeData.agentName,
|
|
60853
|
-
apiKey: exchangeData.apiKey
|
|
60854
|
-
}, pendingRequest.namespaceKey);
|
|
60855
|
-
if (Result.isError(storeResult)) return storeResult;
|
|
60856
|
-
return Result.ok({
|
|
60857
|
-
agentName: exchangeData.agentName,
|
|
60858
|
-
apiKey: exchangeData.apiKey
|
|
60859
60784
|
});
|
|
60860
|
-
}
|
|
60861
|
-
|
|
60862
|
-
|
|
60785
|
+
},
|
|
60786
|
+
operation: "account/fetch"
|
|
60787
|
+
});
|
|
60788
|
+
if (Result.isError(response)) {
|
|
60789
|
+
if (response.error instanceof AuthError && response.error.code === ERROR_CODE.authInvalidCredentials) return Result.ok(false);
|
|
60790
|
+
return response;
|
|
60863
60791
|
}
|
|
60864
|
-
return Result.ok(
|
|
60792
|
+
return Result.ok(true);
|
|
60865
60793
|
};
|
|
60866
|
-
const
|
|
60867
|
-
const
|
|
60868
|
-
if (Result.
|
|
60794
|
+
const exchangeCurrentAuthRequest = async (snapshot) => {
|
|
60795
|
+
const currentAuthRequest = snapshot.currentAuthRequest;
|
|
60796
|
+
if (currentAuthRequest === null) return Result.ok({ kind: "none" });
|
|
60797
|
+
if (isExpiredCurrentAuthRequest(currentAuthRequest, now())) {
|
|
60798
|
+
const clearResult = clearCurrentAuthRequest();
|
|
60799
|
+
if (Result.isError(clearResult)) return clearResult;
|
|
60800
|
+
return Result.ok({ kind: "none" });
|
|
60801
|
+
}
|
|
60802
|
+
const exchangePayload = await requestJson(deps.httpClient, authExchangeUrl(deps.baseUrl), authExchangeSchema, {
|
|
60803
|
+
body: JSON.stringify({
|
|
60804
|
+
authRequestId: currentAuthRequest.authRequestId,
|
|
60805
|
+
installationId: snapshot.installationId
|
|
60806
|
+
}),
|
|
60807
|
+
headers: { "Content-Type": "application/json" },
|
|
60808
|
+
method: "POST"
|
|
60809
|
+
}, {
|
|
60810
|
+
context: "auth exchange response",
|
|
60811
|
+
mapStatusError: (response, body) => new RemoteRequestError({
|
|
60812
|
+
body,
|
|
60813
|
+
httpStatus: response.status,
|
|
60814
|
+
message: "Failed to exchange current CLI auth request",
|
|
60815
|
+
operation: "auth/exchange",
|
|
60816
|
+
raw: body,
|
|
60817
|
+
source: "http"
|
|
60818
|
+
}),
|
|
60819
|
+
operation: "auth/exchange"
|
|
60820
|
+
});
|
|
60821
|
+
if (Result.isError(exchangePayload)) return exchangePayload;
|
|
60822
|
+
const exchangeData = exchangePayload.value.data;
|
|
60823
|
+
if (exchangeData.status === "authorization_pending") return Result.ok({
|
|
60824
|
+
kind: "pending",
|
|
60825
|
+
request: currentAuthRequest
|
|
60826
|
+
});
|
|
60827
|
+
if (exchangeData.status === "approved") {
|
|
60828
|
+
const approvedAuth = {
|
|
60829
|
+
agentId: exchangeData.agentId,
|
|
60830
|
+
agentName: exchangeData.agentName,
|
|
60831
|
+
apiKey: exchangeData.apiKey,
|
|
60832
|
+
credentialId: exchangeData.credentialId
|
|
60833
|
+
};
|
|
60834
|
+
const storeResult = storeApprovedAuth(approvedAuth);
|
|
60835
|
+
if (Result.isError(storeResult)) return storeResult;
|
|
60836
|
+
return Result.ok({
|
|
60837
|
+
auth: approvedAuth,
|
|
60838
|
+
kind: "approved"
|
|
60839
|
+
});
|
|
60840
|
+
}
|
|
60841
|
+
const clearResult = clearCurrentAuthRequest();
|
|
60842
|
+
if (Result.isError(clearResult)) return clearResult;
|
|
60843
|
+
return Result.ok({ kind: "none" });
|
|
60844
|
+
};
|
|
60845
|
+
const startOrRecoverLogin = async (installationId, options) => {
|
|
60869
60846
|
const startPayload = await requestJson(deps.httpClient, authStartUrl(deps.baseUrl), authStartSchema, {
|
|
60870
60847
|
body: JSON.stringify({
|
|
60871
60848
|
...deps.executionEnvironment === void 0 ? {} : { executionEnvironment: deps.executionEnvironment },
|
|
60872
|
-
installationId
|
|
60873
|
-
namespaceKey: DEFAULT_NAMESPACE_KEY
|
|
60849
|
+
installationId
|
|
60874
60850
|
}),
|
|
60875
60851
|
headers: { "Content-Type": "application/json" },
|
|
60876
60852
|
method: "POST"
|
|
@@ -60887,76 +60863,140 @@ const createAuthService = (deps) => {
|
|
|
60887
60863
|
operation: "auth/start"
|
|
60888
60864
|
});
|
|
60889
60865
|
if (Result.isError(startPayload)) return startPayload;
|
|
60890
|
-
const
|
|
60866
|
+
const currentAuthRequest = {
|
|
60891
60867
|
authRequestId: startPayload.value.data.authRequestId,
|
|
60892
|
-
code: startPayload.value.data.userCode,
|
|
60893
|
-
createdAt: new Date(now()).toISOString(),
|
|
60894
60868
|
expiresAt: startPayload.value.data.expiresAt,
|
|
60895
|
-
namespaceKey: DEFAULT_NAMESPACE_KEY,
|
|
60896
60869
|
verificationUrl: startPayload.value.data.verificationUrl
|
|
60897
|
-
});
|
|
60898
|
-
if (Result.isError(savePendingRequestResult)) return savePendingRequestResult;
|
|
60899
|
-
const verification = {
|
|
60900
|
-
userCode: startPayload.value.data.userCode,
|
|
60901
|
-
verificationUri: startPayload.value.data.verificationUrl
|
|
60902
60870
|
};
|
|
60903
|
-
|
|
60871
|
+
const saveCurrentAuthRequestResult = deps.credentialsStore.saveCurrentAuthRequest(currentAuthRequest);
|
|
60872
|
+
if (Result.isError(saveCurrentAuthRequestResult)) return saveCurrentAuthRequestResult;
|
|
60873
|
+
if (startPayload.value.data.disposition === "reused_approved") {
|
|
60874
|
+
const exchangedCurrentAuthRequest = await exchangeCurrentAuthRequest({
|
|
60875
|
+
currentAuthRequest,
|
|
60876
|
+
installationId,
|
|
60877
|
+
session: null
|
|
60878
|
+
});
|
|
60879
|
+
if (Result.isError(exchangedCurrentAuthRequest)) return exchangedCurrentAuthRequest;
|
|
60880
|
+
if (exchangedCurrentAuthRequest.value.kind === "approved") return Result.ok({
|
|
60881
|
+
agentName: exchangedCurrentAuthRequest.value.auth.agentName,
|
|
60882
|
+
loggedIn: true,
|
|
60883
|
+
outcome: "authenticated"
|
|
60884
|
+
});
|
|
60885
|
+
}
|
|
60886
|
+
const verification = toLoginPendingInfo(currentAuthRequest);
|
|
60887
|
+
if (verification !== null) options.onPending?.(verification);
|
|
60904
60888
|
return Result.ok({
|
|
60905
60889
|
agentName: null,
|
|
60906
60890
|
loggedIn: false,
|
|
60907
60891
|
outcome: "pending_approval",
|
|
60908
|
-
verification
|
|
60892
|
+
verification: verification ?? {
|
|
60893
|
+
authRequestId: currentAuthRequest.authRequestId,
|
|
60894
|
+
verificationUrl: currentAuthRequest.verificationUrl
|
|
60895
|
+
}
|
|
60909
60896
|
});
|
|
60910
60897
|
};
|
|
60911
60898
|
return {
|
|
60912
60899
|
login: async (options) => {
|
|
60913
|
-
|
|
60914
|
-
|
|
60915
|
-
|
|
60916
|
-
|
|
60917
|
-
|
|
60918
|
-
if (
|
|
60919
|
-
|
|
60920
|
-
agentName: "CLI Agent",
|
|
60900
|
+
const snapshot = loadLocalAuthSnapshot();
|
|
60901
|
+
if (Result.isError(snapshot)) return snapshot;
|
|
60902
|
+
if (snapshot.value.session !== null) {
|
|
60903
|
+
const validationResult = await validateStoredCredentials(snapshot.value.session.apiKey);
|
|
60904
|
+
if (Result.isError(validationResult)) return validationResult;
|
|
60905
|
+
if (validationResult.value) return Result.ok({
|
|
60906
|
+
agentName: snapshot.value.session.agentName ?? "CLI Agent",
|
|
60921
60907
|
loggedIn: true,
|
|
60922
|
-
outcome: "
|
|
60908
|
+
outcome: "already_authenticated"
|
|
60923
60909
|
});
|
|
60910
|
+
const deleteResult = deps.credentialsStore.delete();
|
|
60911
|
+
if (Result.isError(deleteResult)) return deleteResult;
|
|
60924
60912
|
}
|
|
60925
|
-
|
|
60926
|
-
|
|
60927
|
-
|
|
60928
|
-
|
|
60929
|
-
}));
|
|
60930
|
-
const stored = deps.credentialsStore.load();
|
|
60931
|
-
if (Result.isError(stored)) return stored;
|
|
60932
|
-
if (stored.value !== null) return Result.ok({
|
|
60933
|
-
agentName: stored.value.agentName ?? "CLI Agent",
|
|
60934
|
-
loggedIn: true,
|
|
60935
|
-
outcome: "already_authenticated"
|
|
60936
|
-
});
|
|
60937
|
-
const exchangedPendingAuth = await tryExchangePendingRequests();
|
|
60938
|
-
if (Result.isError(exchangedPendingAuth)) return exchangedPendingAuth;
|
|
60939
|
-
if (exchangedPendingAuth.value !== null) return Result.ok({
|
|
60940
|
-
agentName: exchangedPendingAuth.value.agentName,
|
|
60913
|
+
const exchangedCurrentAuthRequest = await exchangeCurrentAuthRequest(snapshot.value);
|
|
60914
|
+
if (Result.isError(exchangedCurrentAuthRequest)) return exchangedCurrentAuthRequest;
|
|
60915
|
+
if (exchangedCurrentAuthRequest.value.kind === "approved") return Result.ok({
|
|
60916
|
+
agentName: exchangedCurrentAuthRequest.value.auth.agentName,
|
|
60941
60917
|
loggedIn: true,
|
|
60942
60918
|
outcome: "authenticated"
|
|
60943
60919
|
});
|
|
60944
|
-
|
|
60920
|
+
if (exchangedCurrentAuthRequest.value.kind === "pending") {
|
|
60921
|
+
const verification = toLoginPendingInfo(exchangedCurrentAuthRequest.value.request);
|
|
60922
|
+
if (verification !== null) options.onPending?.(verification);
|
|
60923
|
+
return Result.ok({
|
|
60924
|
+
agentName: null,
|
|
60925
|
+
loggedIn: false,
|
|
60926
|
+
outcome: "pending_approval",
|
|
60927
|
+
verification: verification ?? {
|
|
60928
|
+
authRequestId: exchangedCurrentAuthRequest.value.request.authRequestId,
|
|
60929
|
+
verificationUrl: exchangedCurrentAuthRequest.value.request.verificationUrl
|
|
60930
|
+
}
|
|
60931
|
+
});
|
|
60932
|
+
}
|
|
60933
|
+
return startOrRecoverLogin(snapshot.value.installationId, options);
|
|
60945
60934
|
},
|
|
60946
60935
|
logout: async () => {
|
|
60947
|
-
const
|
|
60948
|
-
if (Result.isError(
|
|
60949
|
-
|
|
60950
|
-
|
|
60951
|
-
|
|
60952
|
-
localCredentialsDeleted: false,
|
|
60953
|
-
revoked: false
|
|
60936
|
+
const snapshot = loadLocalAuthSnapshot();
|
|
60937
|
+
if (Result.isError(snapshot)) return snapshot;
|
|
60938
|
+
if (snapshot.value.session === null) return Result.ok({
|
|
60939
|
+
localStateCleared: false,
|
|
60940
|
+
remoteSignedOut: false
|
|
60954
60941
|
});
|
|
60942
|
+
const storedAuthorizationHeader = toStoredAuthorizationHeader(snapshot.value.session);
|
|
60943
|
+
let remoteSignedOut = false;
|
|
60944
|
+
if (storedAuthorizationHeader !== null) {
|
|
60945
|
+
const logoutPayload = await requestJson(deps.httpClient, authLogoutUrl(deps.baseUrl), authLogoutSchema, {
|
|
60946
|
+
headers: { Authorization: storedAuthorizationHeader },
|
|
60947
|
+
method: "POST"
|
|
60948
|
+
}, {
|
|
60949
|
+
context: "auth logout response",
|
|
60950
|
+
mapStatusError: (response, body) => new RemoteRequestError({
|
|
60951
|
+
body,
|
|
60952
|
+
httpStatus: response.status,
|
|
60953
|
+
message: "Failed to sign out current CLI session",
|
|
60954
|
+
operation: "auth/logout",
|
|
60955
|
+
raw: body,
|
|
60956
|
+
source: "http"
|
|
60957
|
+
}),
|
|
60958
|
+
operation: "auth/logout"
|
|
60959
|
+
});
|
|
60960
|
+
if (Result.isOk(logoutPayload)) remoteSignedOut = true;
|
|
60961
|
+
}
|
|
60955
60962
|
const deleteResult = deps.credentialsStore.delete();
|
|
60956
60963
|
if (Result.isError(deleteResult)) return deleteResult;
|
|
60957
60964
|
return Result.ok({
|
|
60958
|
-
|
|
60959
|
-
|
|
60965
|
+
localStateCleared: true,
|
|
60966
|
+
remoteSignedOut
|
|
60967
|
+
});
|
|
60968
|
+
},
|
|
60969
|
+
reset: async () => {
|
|
60970
|
+
const snapshot = loadLocalAuthSnapshot();
|
|
60971
|
+
if (Result.isError(snapshot)) return snapshot;
|
|
60972
|
+
const storedAuthorizationHeader = toStoredAuthorizationHeader(snapshot.value.session);
|
|
60973
|
+
const remoteResetResult = await requestJson(deps.httpClient, authResetUrl(deps.baseUrl), authResetSchema, {
|
|
60974
|
+
body: JSON.stringify({ installationId: snapshot.value.installationId }),
|
|
60975
|
+
headers: {
|
|
60976
|
+
"Content-Type": "application/json",
|
|
60977
|
+
...storedAuthorizationHeader === null ? {} : { Authorization: storedAuthorizationHeader }
|
|
60978
|
+
},
|
|
60979
|
+
method: "POST"
|
|
60980
|
+
}, {
|
|
60981
|
+
context: "auth reset response",
|
|
60982
|
+
mapStatusError: (response, body) => new RemoteRequestError({
|
|
60983
|
+
body,
|
|
60984
|
+
httpStatus: response.status,
|
|
60985
|
+
message: "Failed to reset current CLI installation",
|
|
60986
|
+
operation: "auth/reset",
|
|
60987
|
+
raw: body,
|
|
60988
|
+
source: "http"
|
|
60989
|
+
}),
|
|
60990
|
+
operation: "auth/reset"
|
|
60991
|
+
});
|
|
60992
|
+
const remoteReset = Result.isOk(remoteResetResult);
|
|
60993
|
+
const localStateCleared = snapshot.value.session !== null || snapshot.value.currentAuthRequest !== null;
|
|
60994
|
+
const resetLocalStateResult = deps.credentialsStore.reset();
|
|
60995
|
+
if (Result.isError(resetLocalStateResult)) return resetLocalStateResult;
|
|
60996
|
+
return Result.ok({
|
|
60997
|
+
installationReset: true,
|
|
60998
|
+
localStateCleared,
|
|
60999
|
+
remoteReset
|
|
60960
61000
|
});
|
|
60961
61001
|
},
|
|
60962
61002
|
resolveApiKey: async (overrideApiKey) => {
|
|
@@ -60967,42 +61007,16 @@ const createAuthService = (deps) => {
|
|
|
60967
61007
|
});
|
|
60968
61008
|
if (resolution.apiKey !== null) return Result.ok(resolution.apiKey);
|
|
60969
61009
|
if (resolution.source === "credentialsError" && resolution.loadError) return Result.err(resolution.loadError);
|
|
60970
|
-
const
|
|
60971
|
-
if (Result.isError(
|
|
60972
|
-
|
|
61010
|
+
const snapshot = loadLocalAuthSnapshot();
|
|
61011
|
+
if (Result.isError(snapshot)) return snapshot;
|
|
61012
|
+
const exchangedCurrentAuthRequest = await exchangeCurrentAuthRequest(snapshot.value);
|
|
61013
|
+
if (Result.isError(exchangedCurrentAuthRequest)) return exchangedCurrentAuthRequest;
|
|
61014
|
+
if (exchangedCurrentAuthRequest.value.kind === "approved") return Result.ok(exchangedCurrentAuthRequest.value.auth.apiKey);
|
|
60973
61015
|
return Result.err(new AuthError({
|
|
60974
61016
|
code: ERROR_CODE.authRequired,
|
|
60975
|
-
message: "Not logged in. Run `ogment
|
|
60976
|
-
recovery: { command: "ogment
|
|
61017
|
+
message: "Not logged in. Run `ogment login` or set OGMENT_API_KEY.",
|
|
61018
|
+
recovery: { command: "ogment login" }
|
|
60977
61019
|
}));
|
|
60978
|
-
},
|
|
60979
|
-
status: async (overrideApiKey) => {
|
|
60980
|
-
const resolution = resolveApiKey({
|
|
60981
|
-
apiKeyOverride: overrideApiKey,
|
|
60982
|
-
credentialsStore: deps.credentialsStore,
|
|
60983
|
-
envApiKey: deps.envApiKey
|
|
60984
|
-
});
|
|
60985
|
-
if (resolution.source === "credentialsError" && resolution.loadError) return Result.err(resolution.loadError);
|
|
60986
|
-
if (resolution.apiKey !== null) {
|
|
60987
|
-
const apiKeySource = resolution.source === "credentialsFile" ? "credentialsFile" : resolution.source === "apiKeyOption" ? "apiKeyOption" : "env";
|
|
60988
|
-
return Result.ok({
|
|
60989
|
-
agentName: resolution.agentName,
|
|
60990
|
-
apiKeySource,
|
|
60991
|
-
loggedIn: true
|
|
60992
|
-
});
|
|
60993
|
-
}
|
|
60994
|
-
const exchangedPendingAuth = await tryExchangePendingRequests();
|
|
60995
|
-
if (Result.isError(exchangedPendingAuth)) return exchangedPendingAuth;
|
|
60996
|
-
if (exchangedPendingAuth.value !== null) return Result.ok({
|
|
60997
|
-
agentName: exchangedPendingAuth.value.agentName,
|
|
60998
|
-
apiKeySource: "credentialsFile",
|
|
60999
|
-
loggedIn: true
|
|
61000
|
-
});
|
|
61001
|
-
return Result.ok({
|
|
61002
|
-
agentName: null,
|
|
61003
|
-
apiKeySource: "none",
|
|
61004
|
-
loggedIn: false
|
|
61005
|
-
});
|
|
61006
61020
|
}
|
|
61007
61021
|
};
|
|
61008
61022
|
};
|
|
@@ -61015,9 +61029,9 @@ const maskApiKey = (apiKey) => {
|
|
|
61015
61029
|
};
|
|
61016
61030
|
const nextActionByIssueCode = (includeDebug) => {
|
|
61017
61031
|
return {
|
|
61018
|
-
auth_failed: "Run `ogment
|
|
61032
|
+
auth_failed: "Run `ogment login` to refresh credentials.",
|
|
61019
61033
|
credentials_load_failed: "Check file permissions and contents of `~/.config/ogment/auth-state.json`.",
|
|
61020
|
-
no_api_key: "Run `ogment
|
|
61034
|
+
no_api_key: "Run `ogment login` or set `OGMENT_API_KEY`.",
|
|
61021
61035
|
unreachable: includeDebug ? "Verify `OGMENT_BASE_URL` and network connectivity." : "Verify network connectivity."
|
|
61022
61036
|
};
|
|
61023
61037
|
};
|
|
@@ -61056,6 +61070,8 @@ const createInfoService = (deps) => {
|
|
|
61056
61070
|
credentialsStore: deps.credentialsStore,
|
|
61057
61071
|
envApiKey: deps.envApiKey
|
|
61058
61072
|
});
|
|
61073
|
+
const installationIdResult = deps.credentialsStore.getInstallationId();
|
|
61074
|
+
const installationId = Result.isOk(installationIdResult) ? installationIdResult.value : null;
|
|
61059
61075
|
const selectedApiKey = apiKeyResolution.apiKey;
|
|
61060
61076
|
const credentialsFileExists = existsSyncFn(deps.credentialsPath);
|
|
61061
61077
|
const endpoint = `${deps.baseUrl}${cliEndpoints.accountMe}`;
|
|
@@ -61080,6 +61096,7 @@ const createInfoService = (deps) => {
|
|
|
61080
61096
|
};
|
|
61081
61097
|
const collectAccount = async () => {
|
|
61082
61098
|
if (selectedApiKey === null) return {
|
|
61099
|
+
actingAgent: null,
|
|
61083
61100
|
...emptyAccountErrorDetails(),
|
|
61084
61101
|
errorType: null,
|
|
61085
61102
|
latencyMs: null,
|
|
@@ -61097,6 +61114,12 @@ const createInfoService = (deps) => {
|
|
|
61097
61114
|
return organization.servers.map((server) => server.path);
|
|
61098
61115
|
});
|
|
61099
61116
|
return {
|
|
61117
|
+
actingAgent: accountResult.value.actingAgent === null ? null : {
|
|
61118
|
+
agentId: accountResult.value.actingAgent.agentId,
|
|
61119
|
+
agentName: accountResult.value.actingAgent.agentName,
|
|
61120
|
+
boundInstallationId: accountResult.value.actingAgent.boundInstallationId,
|
|
61121
|
+
boundToCurrentInstallation: installationId === null || accountResult.value.actingAgent.boundInstallationId === null ? null : accountResult.value.actingAgent.boundInstallationId === installationId
|
|
61122
|
+
},
|
|
61100
61123
|
...emptyAccountErrorDetails(),
|
|
61101
61124
|
errorType: null,
|
|
61102
61125
|
latencyMs: accountElapsedMs,
|
|
@@ -61123,6 +61146,7 @@ const createInfoService = (deps) => {
|
|
|
61123
61146
|
break;
|
|
61124
61147
|
}
|
|
61125
61148
|
return {
|
|
61149
|
+
actingAgent: null,
|
|
61126
61150
|
..."code" in accountResult.error ? { errorCode: String(accountResult.error.code) } : { errorCode: null },
|
|
61127
61151
|
..."httpStatus" in accountResult.error ? { errorHttpStatus: typeof accountResult.error.httpStatus === "number" ? accountResult.error.httpStatus : null } : { errorHttpStatus: null },
|
|
61128
61152
|
..."mcpCode" in accountResult.error ? { errorMcpCode: typeof accountResult.error.mcpCode === "number" ? accountResult.error.mcpCode : null } : { errorMcpCode: null },
|
|
@@ -61168,13 +61192,18 @@ const createInfoService = (deps) => {
|
|
|
61168
61192
|
code: "unexpected_diagnostic_error",
|
|
61169
61193
|
message: `Unexpected diagnostic error: ${account.message ?? "unknown error"}`
|
|
61170
61194
|
});
|
|
61195
|
+
if (Result.isError(installationIdResult)) issues.push({
|
|
61196
|
+
code: "credentials_load_failed",
|
|
61197
|
+
message: `Failed to load installation identity: ${installationIdResult.error.message}`
|
|
61198
|
+
});
|
|
61171
61199
|
return {
|
|
61172
61200
|
auth: {
|
|
61173
61201
|
apiKeyPresent: selectedApiKey !== null,
|
|
61174
61202
|
apiKeyPreview: selectedApiKey === null ? null : maskApiKey(selectedApiKey),
|
|
61175
61203
|
apiKeySource: apiKeyResolution.source,
|
|
61176
61204
|
credentialsFileExists,
|
|
61177
|
-
credentialsFileLoadError: apiKeyResolution.loadError?.message ?? null
|
|
61205
|
+
credentialsFileLoadError: apiKeyResolution.loadError?.message ?? null,
|
|
61206
|
+
installationId
|
|
61178
61207
|
},
|
|
61179
61208
|
config: {
|
|
61180
61209
|
baseUrl: deps.baseUrl,
|
|
@@ -61191,7 +61220,9 @@ const createInfoService = (deps) => {
|
|
|
61191
61220
|
],
|
|
61192
61221
|
quickCommands: [
|
|
61193
61222
|
"ogment status",
|
|
61194
|
-
"ogment
|
|
61223
|
+
"ogment login",
|
|
61224
|
+
"ogment logout",
|
|
61225
|
+
"ogment reset",
|
|
61195
61226
|
"ogment catalog",
|
|
61196
61227
|
"ogment search <server-id> --code 'return input'",
|
|
61197
61228
|
"ogment execute <server-id> --code 'return input' --input '{}'"
|
|
@@ -72001,9 +72032,7 @@ const createRuntime = () => {
|
|
|
72001
72032
|
const output = new OutputManager();
|
|
72002
72033
|
const authStateStore = createFileCredentialsStore({
|
|
72003
72034
|
configDir: runtimeConfig.configDir,
|
|
72004
|
-
credentialsPath: runtimeConfig.credentialsPath
|
|
72005
|
-
legacyCredentialsPath: runtimeConfig.legacyCredentialsPath,
|
|
72006
|
-
telemetryPath: runtimeConfig.telemetryPath
|
|
72035
|
+
credentialsPath: runtimeConfig.credentialsPath
|
|
72007
72036
|
});
|
|
72008
72037
|
const httpClient = createHttpClient();
|
|
72009
72038
|
const services = {
|
|
@@ -72128,7 +72157,7 @@ const createProgram = (runtime, parseState) => {
|
|
|
72128
72157
|
return [
|
|
72129
72158
|
"",
|
|
72130
72159
|
"Examples:",
|
|
72131
|
-
" $ ogment
|
|
72160
|
+
" $ ogment login",
|
|
72132
72161
|
" $ ogment catalog",
|
|
72133
72162
|
" $ ogment catalog billing",
|
|
72134
72163
|
" $ ogment catalog billing execute",
|
|
@@ -72143,27 +72172,14 @@ const createProgram = (runtime, parseState) => {
|
|
|
72143
72172
|
runtime.output.configure(mapGlobalOutputOptions(options));
|
|
72144
72173
|
runtime.context.apiKeyOverride = options.apiKey;
|
|
72145
72174
|
});
|
|
72146
|
-
|
|
72147
|
-
|
|
72148
|
-
return [
|
|
72149
|
-
"",
|
|
72150
|
-
"Examples:",
|
|
72151
|
-
" $ ogment auth login",
|
|
72152
|
-
" $ ogment auth status"
|
|
72153
|
-
].join("\n");
|
|
72154
|
-
});
|
|
72155
|
-
authCommand.command("login").summary("Login with device flow (default)").description("Authenticate with Ogment using device flow (recommended)").action((_, command) => {
|
|
72156
|
-
const { apiKey } = asGlobalOptions(command);
|
|
72157
|
-
setInvocation({
|
|
72158
|
-
apiKey,
|
|
72159
|
-
kind: "auth_login"
|
|
72160
|
-
});
|
|
72175
|
+
program.command("login").summary("Authenticate this CLI installation").description("Start or complete browser-based login for this installation").helpGroup("Authentication Commands:").action(() => {
|
|
72176
|
+
setInvocation({ kind: "login" });
|
|
72161
72177
|
});
|
|
72162
|
-
|
|
72163
|
-
setInvocation({ kind: "
|
|
72178
|
+
program.command("logout").summary("Sign this CLI installation out").description("Sign out the current local CLI session").helpGroup("Authentication Commands:").action(() => {
|
|
72179
|
+
setInvocation({ kind: "logout" });
|
|
72164
72180
|
});
|
|
72165
|
-
|
|
72166
|
-
setInvocation({ kind: "
|
|
72181
|
+
program.command("reset").summary("Reset this CLI installation").description("Wipe local state and create a fresh CLI installation identity").helpGroup("Authentication Commands:").action(() => {
|
|
72182
|
+
setInvocation({ kind: "reset" });
|
|
72167
72183
|
});
|
|
72168
72184
|
program.command("catalog").summary("Discover servers or inspect Codemode tools").description("Discover servers or inspect Codemode tools on a server").helpGroup("Discovery Commands:").argument("[serverId]", "Server id").argument("[toolName]", "Codemode tool name").addOption(new Option("--org <orgSlug>", "Organization slug").hideHelp()).addOption(new Option("--cursor <cursor>", "Pagination cursor for server discovery")).addOption(new Option("--limit <limit>", "Maximum servers to return").argParser(parseCatalogLimitOption)).action((serverId, toolName, options) => {
|
|
72169
72185
|
if (serverId !== void 0 && (options.cursor !== void 0 || options.limit !== void 0)) throw new InvalidArgumentError("--cursor and --limit are only supported for `ogment catalog`.");
|
|
@@ -72193,7 +72209,7 @@ const createProgram = (runtime, parseState) => {
|
|
|
72193
72209
|
serverId
|
|
72194
72210
|
});
|
|
72195
72211
|
});
|
|
72196
|
-
program.command("status").summary("Show runtime diagnostics").description("Show runtime configuration and
|
|
72212
|
+
program.command("status").summary("Show runtime diagnostics and auth state").description("Show runtime configuration, connectivity, and auth diagnostics").helpGroup("Diagnostics Commands:").action(() => {
|
|
72197
72213
|
setInvocation({ kind: "status" });
|
|
72198
72214
|
});
|
|
72199
72215
|
program.action(() => {
|
|
@@ -72220,10 +72236,13 @@ const RUNTIME_ERROR_COMMAND_PATH = "ogment <runtime_error>";
|
|
|
72220
72236
|
const PARSE_ERROR_COMMAND_PATH = "ogment <parse_error>";
|
|
72221
72237
|
const CLI_PACKAGE_NAME = "@ogment-ai/cli";
|
|
72222
72238
|
const PARSE_ERROR_SCOPE_COMMAND_PATHS = {
|
|
72223
|
-
|
|
72239
|
+
login: "ogment login <parse_error>",
|
|
72240
|
+
logout: "ogment logout <parse_error>",
|
|
72241
|
+
reset: "ogment reset <parse_error>",
|
|
72224
72242
|
catalog: "ogment catalog <parse_error>",
|
|
72225
72243
|
execute: "ogment execute <parse_error>",
|
|
72226
|
-
search: "ogment search <parse_error>"
|
|
72244
|
+
search: "ogment search <parse_error>",
|
|
72245
|
+
status: "ogment status <parse_error>"
|
|
72227
72246
|
};
|
|
72228
72247
|
const isParseErrorTelemetryScope = (value) => {
|
|
72229
72248
|
return value in PARSE_ERROR_SCOPE_COMMAND_PATHS;
|
|
@@ -72241,24 +72260,24 @@ const telemetryInputModeFromExecute = (input) => {
|
|
|
72241
72260
|
return "inline_json";
|
|
72242
72261
|
};
|
|
72243
72262
|
const telemetryContextResolvers = {
|
|
72244
|
-
|
|
72263
|
+
login: (_) => {
|
|
72245
72264
|
return {
|
|
72246
|
-
commandKind: "
|
|
72247
|
-
commandPath: "ogment
|
|
72265
|
+
commandKind: "login",
|
|
72266
|
+
commandPath: "ogment login",
|
|
72248
72267
|
inputMode: null
|
|
72249
72268
|
};
|
|
72250
72269
|
},
|
|
72251
|
-
|
|
72270
|
+
logout: (_) => {
|
|
72252
72271
|
return {
|
|
72253
|
-
commandKind: "
|
|
72254
|
-
commandPath: "ogment
|
|
72272
|
+
commandKind: "logout",
|
|
72273
|
+
commandPath: "ogment logout",
|
|
72255
72274
|
inputMode: null
|
|
72256
72275
|
};
|
|
72257
72276
|
},
|
|
72258
|
-
|
|
72277
|
+
reset: (_) => {
|
|
72259
72278
|
return {
|
|
72260
|
-
commandKind: "
|
|
72261
|
-
commandPath: "ogment
|
|
72279
|
+
commandKind: "reset",
|
|
72280
|
+
commandPath: "ogment reset",
|
|
72262
72281
|
inputMode: null
|
|
72263
72282
|
};
|
|
72264
72283
|
},
|
|
@@ -72310,9 +72329,9 @@ const telemetryContextResolvers = {
|
|
|
72310
72329
|
};
|
|
72311
72330
|
const telemetryContextFromInvocation = (invocation) => {
|
|
72312
72331
|
switch (invocation.kind) {
|
|
72313
|
-
case "
|
|
72314
|
-
case "
|
|
72315
|
-
case "
|
|
72332
|
+
case "login": return telemetryContextResolvers.login(invocation);
|
|
72333
|
+
case "logout": return telemetryContextResolvers.logout(invocation);
|
|
72334
|
+
case "reset": return telemetryContextResolvers.reset(invocation);
|
|
72316
72335
|
case "catalog": return telemetryContextResolvers.catalog(invocation);
|
|
72317
72336
|
case "execute": return telemetryContextResolvers.execute(invocation);
|
|
72318
72337
|
case "root": return telemetryContextResolvers.root(invocation);
|
|
@@ -72350,9 +72369,7 @@ const emitRuntimeErrorTelemetry = async (output, input) => {
|
|
|
72350
72369
|
const telemetry = createTelemetryService({
|
|
72351
72370
|
authStateStore: createFileCredentialsStore({
|
|
72352
72371
|
configDir: telemetryConfig.configDir,
|
|
72353
|
-
credentialsPath: telemetryConfig.credentialsPath
|
|
72354
|
-
legacyCredentialsPath: telemetryConfig.legacyCredentialsPath,
|
|
72355
|
-
telemetryPath: telemetryConfig.telemetryPath
|
|
72372
|
+
credentialsPath: telemetryConfig.credentialsPath
|
|
72356
72373
|
}),
|
|
72357
72374
|
baseUrl: telemetryConfig.baseUrl,
|
|
72358
72375
|
cliVersion: telemetryConfig.version,
|
|
@@ -72391,15 +72408,15 @@ const commandContextFromInvocation = (invocation, apiKeyOverride) => {
|
|
|
72391
72408
|
const withBase = (commandName, invocationKind, subcommand = void 0) => {
|
|
72392
72409
|
return {
|
|
72393
72410
|
commandName,
|
|
72394
|
-
hasApiKeyOverride:
|
|
72411
|
+
hasApiKeyOverride: hasApiKeyOverride(apiKeyOverride),
|
|
72395
72412
|
invocationKind,
|
|
72396
72413
|
subcommand
|
|
72397
72414
|
};
|
|
72398
72415
|
};
|
|
72399
72416
|
switch (invocation.kind) {
|
|
72400
|
-
case "
|
|
72401
|
-
case "
|
|
72402
|
-
case "
|
|
72417
|
+
case "login": return withBase("login", "login");
|
|
72418
|
+
case "logout": return withBase("logout", "logout");
|
|
72419
|
+
case "reset": return withBase("reset", "reset");
|
|
72403
72420
|
case "catalog": return withBase("catalog", "catalog", "summary");
|
|
72404
72421
|
case "execute": return withBase("execute", "execute");
|
|
72405
72422
|
case "root": return withBase("ogment", "root");
|
|
@@ -72555,4 +72572,4 @@ if (shouldExecuteCli(import.meta.url, process.argv[1])) await executeCli();
|
|
|
72555
72572
|
|
|
72556
72573
|
//#endregion
|
|
72557
72574
|
export { executeCli, runCli, shouldExecuteCli };
|
|
72558
|
-
//# debugId=
|
|
72575
|
+
//# debugId=38b5ce38-06fe-4ef8-9580-b9d5110652a6
|