@ogment-ai/cli 0.9.1 → 0.10.0
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 +499 -484
- 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 or invoke commands can run.",
|
|
8021
8021
|
title: "Authenticate",
|
|
8022
8022
|
when: "immediate"
|
|
@@ -8367,36 +8367,55 @@ const isRecord$2 = (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
|
}
|
|
@@ -8800,7 +8751,7 @@ const DEFAULT_OGMENT_BASE_URL = "https://dashboard.ogment.ai";
|
|
|
8800
8751
|
*/
|
|
8801
8752
|
const SENTRY_DSN_BUILD = "https://4219ab98670b61086758b4d0e31ae318@o4507724844957696.ingest.us.sentry.io/4510992932405248";
|
|
8802
8753
|
const SENTRY_ENVIRONMENT_BUILD = "production";
|
|
8803
|
-
const SENTRY_RELEASE_BUILD = "cli-v0.
|
|
8754
|
+
const SENTRY_RELEASE_BUILD = "cli-v0.10.0+git:4ebe33ce3";
|
|
8804
8755
|
const packageJsonSchema = object({ version: string().min(1) });
|
|
8805
8756
|
const hasCode = (value, code) => {
|
|
8806
8757
|
if (typeof value !== "object" || value === null) return false;
|
|
@@ -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,
|
|
@@ -14151,7 +14105,13 @@ const cliOrgSchema = object({
|
|
|
14151
14105
|
role: string(),
|
|
14152
14106
|
servers: array(cliServerSchema)
|
|
14153
14107
|
}).strict();
|
|
14108
|
+
const cliActingAgentSchema = object({
|
|
14109
|
+
agentId: string().uuid(),
|
|
14110
|
+
agentName: string().min(1),
|
|
14111
|
+
boundInstallationId: string().uuid().nullable()
|
|
14112
|
+
}).strict();
|
|
14154
14113
|
const cliMeDataSchema = object({
|
|
14114
|
+
actingAgent: cliActingAgentSchema.nullable(),
|
|
14155
14115
|
email: string().nullable(),
|
|
14156
14116
|
imageUrl: string().nullable(),
|
|
14157
14117
|
name: string().nullable(),
|
|
@@ -14162,72 +14122,60 @@ const accountMeSchema = cliSuccessEnvelopeSchema(cliMeDataSchema);
|
|
|
14162
14122
|
|
|
14163
14123
|
//#endregion
|
|
14164
14124
|
//#region ../../packages/shared/src/cli/auth.ts
|
|
14165
|
-
const deviceCodeStartDataSchema = object({
|
|
14166
|
-
deviceCode: string().min(1),
|
|
14167
|
-
expiresIn: number$1().int().positive(),
|
|
14168
|
-
interval: number$1().int().positive(),
|
|
14169
|
-
userCode: string().min(1),
|
|
14170
|
-
verificationUri: string().url()
|
|
14171
|
-
}).strict();
|
|
14172
|
-
const deviceCodeStartSchema = cliSuccessEnvelopeSchema(deviceCodeStartDataSchema);
|
|
14173
14125
|
const authStartDataSchema = object({
|
|
14174
14126
|
authRequestId: string().min(1),
|
|
14127
|
+
disposition: _enum([
|
|
14128
|
+
"created",
|
|
14129
|
+
"reused_approved",
|
|
14130
|
+
"reused_pending"
|
|
14131
|
+
]),
|
|
14175
14132
|
expiresAt: isoTimestampSchema,
|
|
14176
|
-
userCode: string().min(1),
|
|
14177
14133
|
verificationUrl: string().url()
|
|
14178
14134
|
}).strict();
|
|
14179
14135
|
const authStartSchema = cliSuccessEnvelopeSchema(authStartDataSchema);
|
|
14180
|
-
const deviceTokenPendingDataSchema = object({ status: literal("authorization_pending") }).strict();
|
|
14181
|
-
const deviceTokenApprovedDataSchema = object({
|
|
14182
|
-
agentName: string().min(1),
|
|
14183
|
-
apiKey: string().min(1),
|
|
14184
|
-
status: literal("approved")
|
|
14185
|
-
}).strict();
|
|
14186
|
-
const deviceTokenDataSchema = discriminatedUnion("status", [deviceTokenPendingDataSchema, deviceTokenApprovedDataSchema]);
|
|
14187
|
-
const deviceTokenSchema = cliSuccessEnvelopeSchema(deviceTokenDataSchema);
|
|
14188
|
-
const deviceTokenApprovedSchema = cliSuccessEnvelopeSchema(deviceTokenApprovedDataSchema);
|
|
14189
14136
|
const authExchangePendingDataSchema = object({ status: literal("authorization_pending") }).strict();
|
|
14190
14137
|
const authExchangeApprovedDataSchema = object({
|
|
14138
|
+
agentId: string().uuid(),
|
|
14191
14139
|
agentName: string().min(1),
|
|
14192
14140
|
apiKey: string().min(1),
|
|
14193
|
-
|
|
14141
|
+
credentialId: string().uuid(),
|
|
14194
14142
|
status: literal("approved")
|
|
14195
14143
|
}).strict();
|
|
14196
14144
|
const authExchangeExpiredDataSchema = object({ status: literal("expired") }).strict();
|
|
14197
|
-
const authExchangeDeniedDataSchema = object({ status: literal("denied") }).strict();
|
|
14198
|
-
const authExchangeConflictDataSchema = object({ status: literal("conflict") }).strict();
|
|
14199
14145
|
const authExchangeInvalidDataSchema = object({ status: literal("invalid") }).strict();
|
|
14146
|
+
const authExchangeSupersededDataSchema = object({ status: literal("superseded") }).strict();
|
|
14200
14147
|
const authExchangeDataSchema = discriminatedUnion("status", [
|
|
14201
14148
|
authExchangePendingDataSchema,
|
|
14202
14149
|
authExchangeApprovedDataSchema,
|
|
14203
14150
|
authExchangeExpiredDataSchema,
|
|
14204
|
-
|
|
14205
|
-
|
|
14206
|
-
authExchangeInvalidDataSchema
|
|
14151
|
+
authExchangeInvalidDataSchema,
|
|
14152
|
+
authExchangeSupersededDataSchema
|
|
14207
14153
|
]);
|
|
14208
14154
|
const authExchangeSchema = cliSuccessEnvelopeSchema(authExchangeDataSchema);
|
|
14209
14155
|
const authExchangeApprovedSchema = cliSuccessEnvelopeSchema(authExchangeApprovedDataSchema);
|
|
14210
|
-
const
|
|
14211
|
-
const
|
|
14156
|
+
const authMutationSuccessDataSchema = object({ success: literal(true) }).strict();
|
|
14157
|
+
const authLogoutDataSchema = authMutationSuccessDataSchema;
|
|
14158
|
+
const authLogoutSchema = cliSuccessEnvelopeSchema(authLogoutDataSchema);
|
|
14159
|
+
const authResetDataSchema = authMutationSuccessDataSchema;
|
|
14160
|
+
const authResetSchema = cliSuccessEnvelopeSchema(authResetDataSchema);
|
|
14212
14161
|
|
|
14213
14162
|
//#endregion
|
|
14214
14163
|
//#region ../../packages/shared/src/cli/endpoints.ts
|
|
14215
14164
|
const cliEndpoints = {
|
|
14216
14165
|
accountMe: "/api/v1/cli/me",
|
|
14217
|
-
authExchange: "/api/v1/cli/auth/exchange",
|
|
14218
14166
|
authStart: "/api/v1/cli/auth/start",
|
|
14219
|
-
|
|
14220
|
-
|
|
14221
|
-
|
|
14167
|
+
authExchange: "/api/v1/cli/auth/exchange",
|
|
14168
|
+
authLogout: "/api/v1/cli/auth/logout",
|
|
14169
|
+
authReset: "/api/v1/cli/auth/reset",
|
|
14222
14170
|
telemetry: "/api/v1/cli/telemetry"
|
|
14223
14171
|
};
|
|
14224
14172
|
|
|
14225
14173
|
//#endregion
|
|
14226
14174
|
//#region ../../packages/shared/src/cli/telemetry.ts
|
|
14227
14175
|
const cliCommandKindSchema = _enum([
|
|
14228
|
-
"
|
|
14229
|
-
"
|
|
14230
|
-
"
|
|
14176
|
+
"login",
|
|
14177
|
+
"logout",
|
|
14178
|
+
"reset",
|
|
14231
14179
|
"catalog_summary",
|
|
14232
14180
|
"catalog_tool",
|
|
14233
14181
|
"catalog_tools",
|
|
@@ -14378,25 +14326,16 @@ const exitCodeForError = (error) => {
|
|
|
14378
14326
|
|
|
14379
14327
|
//#endregion
|
|
14380
14328
|
//#region src/commands/auth.ts
|
|
14381
|
-
const
|
|
14382
|
-
const loginOptions =
|
|
14383
|
-
if (options.mode === "apiKey") return {
|
|
14384
|
-
apiKey: options.apiKey,
|
|
14385
|
-
mode: "apiKey"
|
|
14386
|
-
};
|
|
14387
|
-
return {
|
|
14388
|
-
mode: "device",
|
|
14389
|
-
...options.onPending === void 0 ? {} : { onPending: options.onPending }
|
|
14390
|
-
};
|
|
14391
|
-
})();
|
|
14329
|
+
const runLoginCommand = async (context, options) => {
|
|
14330
|
+
const loginOptions = options.onPending === void 0 ? {} : { onPending: options.onPending };
|
|
14392
14331
|
return context.services.auth.login(loginOptions);
|
|
14393
14332
|
};
|
|
14394
|
-
const
|
|
14395
|
-
return context.services.auth.status(context.apiKeyOverride);
|
|
14396
|
-
};
|
|
14397
|
-
const runAuthLogoutCommand = async (context) => {
|
|
14333
|
+
const runLogoutCommand = async (context) => {
|
|
14398
14334
|
return context.services.auth.logout();
|
|
14399
14335
|
};
|
|
14336
|
+
const runResetCommand = async (context) => {
|
|
14337
|
+
return context.services.auth.reset();
|
|
14338
|
+
};
|
|
14400
14339
|
|
|
14401
14340
|
//#endregion
|
|
14402
14341
|
//#region src/commands/server-context.ts
|
|
@@ -14831,13 +14770,6 @@ const buildJsonSchemaExample = (schema) => {
|
|
|
14831
14770
|
//#endregion
|
|
14832
14771
|
//#region src/cli/commands.ts
|
|
14833
14772
|
const cliCommands = {
|
|
14834
|
-
auth: {
|
|
14835
|
-
help: () => "ogment auth --help",
|
|
14836
|
-
login: () => "ogment auth login",
|
|
14837
|
-
loginWithApiKeyRedacted: () => "ogment auth login --api-key <redacted>",
|
|
14838
|
-
logout: () => "ogment auth logout",
|
|
14839
|
-
status: () => "ogment auth status"
|
|
14840
|
-
},
|
|
14841
14773
|
catalog: {
|
|
14842
14774
|
command: () => "ogment catalog",
|
|
14843
14775
|
server: (serverId) => `ogment catalog ${serverId}`,
|
|
@@ -14861,6 +14793,8 @@ const cliCommands = {
|
|
|
14861
14793
|
if (scope === null) return "ogment --help";
|
|
14862
14794
|
return `ogment ${scope} --help`;
|
|
14863
14795
|
},
|
|
14796
|
+
login: { command: () => "ogment login" },
|
|
14797
|
+
logout: { command: () => "ogment logout" },
|
|
14864
14798
|
invoke: {
|
|
14865
14799
|
command: (serverId, toolName, orgSlug) => [
|
|
14866
14800
|
"ogment invoke",
|
|
@@ -14896,9 +14830,9 @@ const cliCommands = {
|
|
|
14896
14830
|
command: () => "ogment",
|
|
14897
14831
|
commandsSurface: () => {
|
|
14898
14832
|
return [
|
|
14899
|
-
"
|
|
14900
|
-
"
|
|
14901
|
-
"
|
|
14833
|
+
"login",
|
|
14834
|
+
"logout",
|
|
14835
|
+
"reset",
|
|
14902
14836
|
"catalog",
|
|
14903
14837
|
"catalog <server-id>",
|
|
14904
14838
|
"catalog <server-id> <tool-name>",
|
|
@@ -14908,6 +14842,7 @@ const cliCommands = {
|
|
|
14908
14842
|
},
|
|
14909
14843
|
help: () => "ogment --help"
|
|
14910
14844
|
},
|
|
14845
|
+
reset: { command: () => "ogment reset" },
|
|
14911
14846
|
status: { command: () => "ogment status" }
|
|
14912
14847
|
};
|
|
14913
14848
|
|
|
@@ -14946,15 +14881,11 @@ const ensureSuccess = (result, runtime, context) => {
|
|
|
14946
14881
|
}
|
|
14947
14882
|
return result.unwrap();
|
|
14948
14883
|
};
|
|
14949
|
-
const nextActionsForLogin = (payload
|
|
14950
|
-
return [nextAction("
|
|
14884
|
+
const nextActionsForLogin = (payload) => {
|
|
14885
|
+
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")];
|
|
14951
14886
|
};
|
|
14952
|
-
const nextActionsForPendingLogin = (
|
|
14953
|
-
return [nextAction("
|
|
14954
|
-
};
|
|
14955
|
-
const nextActionsForAuthStatus = (payload) => {
|
|
14956
|
-
if (!payload.loggedIn) return [nextAction("login", "Authenticate", cliCommands.auth.login(), "No API key is configured locally; login is required.", "immediate")];
|
|
14957
|
-
return [nextAction("discover_servers", "Discover servers", cliCommands.catalog.command(), `Authenticated via ${payload.apiKeySource}; discover servers next.`, "after_auth")];
|
|
14887
|
+
const nextActionsForPendingLogin = (authRequestId, verificationUrl) => {
|
|
14888
|
+
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")];
|
|
14958
14889
|
};
|
|
14959
14890
|
const nextActionsForCatalogSummary = (payload, context) => {
|
|
14960
14891
|
const actions = [];
|
|
@@ -14983,91 +14914,82 @@ const nextActionsForInvoke = (payload) => {
|
|
|
14983
14914
|
return [nextAction("inspect_tool", "Inspect tool schema", cliCommands.catalog.tool(payload.serverId, payload.toolName, { example: false }), `Review ${payload.serverId}/${payload.toolName} schema for the next invocation.`, "after_invoke")];
|
|
14984
14915
|
};
|
|
14985
14916
|
const nextActionsForStatus = (payload) => {
|
|
14986
|
-
if (!payload.auth.apiKeyPresent) return [nextAction("login", "Authenticate", cliCommands.
|
|
14917
|
+
if (!payload.auth.apiKeyPresent) return [nextAction("login", "Authenticate", cliCommands.login.command(), "Status detected no API key; authenticate first.", "immediate")];
|
|
14987
14918
|
return [nextAction("discover_servers", "Discover servers", cliCommands.catalog.command(), `Connectivity is ${payload.summary.status}; discover available servers.`, "after_status")];
|
|
14988
14919
|
};
|
|
14989
14920
|
const runLoginFlow = async (runtime, options) => {
|
|
14990
|
-
const
|
|
14991
|
-
|
|
14992
|
-
invokedCommand: cliCommands.auth.loginWithApiKeyRedacted(),
|
|
14993
|
-
mode: "apiKey"
|
|
14994
|
-
} : {
|
|
14995
|
-
commandOptions: { mode: "device" },
|
|
14996
|
-
invokedCommand: cliCommands.auth.login(),
|
|
14997
|
-
mode: "device"
|
|
14998
|
-
};
|
|
14999
|
-
const data = ensureSuccess(await runAuthLoginCommand(runtime.context, commandOptions), runtime, {
|
|
15000
|
-
command: invokedCommand,
|
|
15001
|
-
entity: { mode }
|
|
15002
|
-
});
|
|
14921
|
+
const invokedCommand = cliCommands.login.command();
|
|
14922
|
+
const data = ensureSuccess(await runLoginCommand(runtime.context, options), runtime, { command: invokedCommand });
|
|
15003
14923
|
if (!data.loggedIn) {
|
|
15004
14924
|
const pendingOutput = {
|
|
15005
|
-
event: "
|
|
14925
|
+
event: "login.pending",
|
|
15006
14926
|
loggedIn: false,
|
|
15007
14927
|
verification: data.verification
|
|
15008
14928
|
};
|
|
15009
14929
|
runtime.output.success(pendingOutput, {
|
|
15010
14930
|
command: invokedCommand,
|
|
15011
14931
|
entity: {
|
|
15012
|
-
event: "
|
|
15013
|
-
mode,
|
|
14932
|
+
event: "login.pending",
|
|
15014
14933
|
verification: {
|
|
15015
|
-
|
|
15016
|
-
|
|
14934
|
+
authRequestId: data.verification.authRequestId,
|
|
14935
|
+
verificationUrl: data.verification.verificationUrl
|
|
15017
14936
|
}
|
|
15018
14937
|
},
|
|
15019
|
-
nextActions: nextActionsForPendingLogin(data.verification.
|
|
14938
|
+
nextActions: nextActionsForPendingLogin(data.verification.authRequestId, data.verification.verificationUrl)
|
|
15020
14939
|
});
|
|
15021
14940
|
return;
|
|
15022
14941
|
}
|
|
15023
14942
|
const outputData = {
|
|
15024
14943
|
...data,
|
|
15025
|
-
event: "
|
|
14944
|
+
event: "login.completed"
|
|
15026
14945
|
};
|
|
15027
14946
|
runtime.output.success(outputData, {
|
|
15028
14947
|
command: invokedCommand,
|
|
15029
14948
|
entity: {
|
|
15030
14949
|
agentName: data.agentName,
|
|
15031
|
-
event: "
|
|
14950
|
+
event: "login.completed",
|
|
15032
14951
|
loggedIn: data.loggedIn,
|
|
15033
|
-
mode,
|
|
15034
14952
|
outcome: data.outcome
|
|
15035
14953
|
},
|
|
15036
|
-
nextActions: nextActionsForLogin(data
|
|
14954
|
+
nextActions: nextActionsForLogin(data)
|
|
15037
14955
|
});
|
|
15038
14956
|
};
|
|
15039
|
-
const
|
|
15040
|
-
|
|
15041
|
-
await runLoginFlow(runtime, {
|
|
15042
|
-
apiKey: invocation.apiKey,
|
|
15043
|
-
mode: "apiKey"
|
|
15044
|
-
});
|
|
15045
|
-
return;
|
|
15046
|
-
}
|
|
15047
|
-
await runLoginFlow(runtime, { mode: "device" });
|
|
14957
|
+
const executeLoginInvocation = async (runtime, _invocation) => {
|
|
14958
|
+
await runLoginFlow(runtime, {});
|
|
15048
14959
|
};
|
|
15049
|
-
const
|
|
15050
|
-
const command = cliCommands.
|
|
15051
|
-
const data = ensureSuccess(await
|
|
15052
|
-
|
|
14960
|
+
const executeLogoutInvocation = async (runtime) => {
|
|
14961
|
+
const command = cliCommands.logout.command();
|
|
14962
|
+
const data = ensureSuccess(await runLogoutCommand(runtime.context), runtime, { command });
|
|
14963
|
+
const outputData = {
|
|
14964
|
+
...data,
|
|
14965
|
+
event: "logout.completed"
|
|
14966
|
+
};
|
|
14967
|
+
runtime.output.success(outputData, {
|
|
15053
14968
|
command,
|
|
15054
14969
|
entity: {
|
|
15055
|
-
|
|
15056
|
-
|
|
14970
|
+
event: "logout.completed",
|
|
14971
|
+
localStateCleared: data.localStateCleared,
|
|
14972
|
+
remoteSignedOut: data.remoteSignedOut
|
|
15057
14973
|
},
|
|
15058
|
-
nextActions:
|
|
14974
|
+
nextActions: [nextAction("login", "Authenticate again", cliCommands.login.command(), "Sign-out completed; run login when you want to reconnect this installation.", "after_logout")]
|
|
15059
14975
|
});
|
|
15060
14976
|
};
|
|
15061
|
-
const
|
|
15062
|
-
const command = cliCommands.
|
|
15063
|
-
const data = ensureSuccess(await
|
|
15064
|
-
|
|
14977
|
+
const executeResetInvocation = async (runtime) => {
|
|
14978
|
+
const command = cliCommands.reset.command();
|
|
14979
|
+
const data = ensureSuccess(await runResetCommand(runtime.context), runtime, { command });
|
|
14980
|
+
const outputData = {
|
|
14981
|
+
...data,
|
|
14982
|
+
event: "reset.completed"
|
|
14983
|
+
};
|
|
14984
|
+
runtime.output.success(outputData, {
|
|
15065
14985
|
command,
|
|
15066
14986
|
entity: {
|
|
15067
|
-
|
|
15068
|
-
|
|
14987
|
+
event: "reset.completed",
|
|
14988
|
+
installationReset: data.installationReset,
|
|
14989
|
+
localStateCleared: data.localStateCleared,
|
|
14990
|
+
remoteReset: data.remoteReset
|
|
15069
14991
|
},
|
|
15070
|
-
nextActions: [nextAction("login", "Authenticate
|
|
14992
|
+
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")]
|
|
15071
14993
|
});
|
|
15072
14994
|
};
|
|
15073
14995
|
const executeCatalogInvocation = async (runtime, invocation) => {
|
|
@@ -15254,19 +15176,19 @@ const executeRootInvocation = (runtime) => {
|
|
|
15254
15176
|
runtime.output.success({ commands: cliCommands.root.commandsSurface() }, {
|
|
15255
15177
|
command: cliCommands.root.command(),
|
|
15256
15178
|
entity: null,
|
|
15257
|
-
nextActions: [nextAction("login", "Authenticate", cliCommands.
|
|
15179
|
+
nextActions: [nextAction("login", "Authenticate", cliCommands.login.command(), "Authenticate first so catalog and invoke commands can run.", "immediate"), nextAction("catalog", "Discover servers", cliCommands.catalog.command(), "List accessible servers and tool counts.", "after_auth")]
|
|
15258
15180
|
});
|
|
15259
15181
|
};
|
|
15260
15182
|
const executeInvocation = async (runtime, invocation) => {
|
|
15261
15183
|
switch (invocation.kind) {
|
|
15262
|
-
case "
|
|
15263
|
-
await
|
|
15184
|
+
case "login":
|
|
15185
|
+
await executeLoginInvocation(runtime, invocation);
|
|
15264
15186
|
return;
|
|
15265
|
-
case "
|
|
15266
|
-
await
|
|
15187
|
+
case "logout":
|
|
15188
|
+
await executeLogoutInvocation(runtime);
|
|
15267
15189
|
return;
|
|
15268
|
-
case "
|
|
15269
|
-
await
|
|
15190
|
+
case "reset":
|
|
15191
|
+
await executeResetInvocation(runtime);
|
|
15270
15192
|
return;
|
|
15271
15193
|
case "catalog":
|
|
15272
15194
|
await executeCatalogInvocation(runtime, invocation);
|
|
@@ -15339,19 +15261,19 @@ const nextActionForParseError = (scope, helpCommand) => {
|
|
|
15339
15261
|
};
|
|
15340
15262
|
};
|
|
15341
15263
|
const parseActionsForScope = (scope, helpAction) => {
|
|
15342
|
-
if (scope === "
|
|
15264
|
+
if (scope === "login" || scope === "logout" || scope === "reset") return [
|
|
15343
15265
|
{
|
|
15344
|
-
command: cliCommands.
|
|
15345
|
-
id: "
|
|
15346
|
-
reason: "Authenticate
|
|
15347
|
-
title: "
|
|
15266
|
+
command: cliCommands.login.command(),
|
|
15267
|
+
id: "login",
|
|
15268
|
+
reason: "Authenticate this CLI installation.",
|
|
15269
|
+
title: "Login",
|
|
15348
15270
|
when: "immediate"
|
|
15349
15271
|
},
|
|
15350
15272
|
{
|
|
15351
|
-
command: cliCommands.
|
|
15352
|
-
id: "
|
|
15353
|
-
reason: "
|
|
15354
|
-
title: "
|
|
15273
|
+
command: cliCommands.status.command(),
|
|
15274
|
+
id: "status",
|
|
15275
|
+
reason: "Inspect the current CLI state and diagnostics.",
|
|
15276
|
+
title: "Status",
|
|
15355
15277
|
when: "immediate"
|
|
15356
15278
|
},
|
|
15357
15279
|
helpAction
|
|
@@ -60807,8 +60729,8 @@ const createAccountService = (deps) => {
|
|
|
60807
60729
|
mapStatusError: (response, body) => {
|
|
60808
60730
|
if (response.status === 401) return new AuthError({
|
|
60809
60731
|
code: ERROR_CODE.authInvalidCredentials,
|
|
60810
|
-
message: "Authentication failed. Run `ogment
|
|
60811
|
-
recovery: { command: "ogment
|
|
60732
|
+
message: "Authentication failed. Run `ogment login` again.",
|
|
60733
|
+
recovery: { command: "ogment login" }
|
|
60812
60734
|
});
|
|
60813
60735
|
return new RemoteRequestError({
|
|
60814
60736
|
body,
|
|
@@ -60829,7 +60751,6 @@ const createAccountService = (deps) => {
|
|
|
60829
60751
|
|
|
60830
60752
|
//#endregion
|
|
60831
60753
|
//#region src/services/auth.ts
|
|
60832
|
-
const DEFAULT_NAMESPACE_KEY = "default";
|
|
60833
60754
|
const toEndpointUrl = (baseUrl, endpoint) => {
|
|
60834
60755
|
return `${baseUrl}${endpoint}`;
|
|
60835
60756
|
};
|
|
@@ -60839,85 +60760,138 @@ const authStartUrl = (baseUrl) => {
|
|
|
60839
60760
|
const authExchangeUrl = (baseUrl) => {
|
|
60840
60761
|
return toEndpointUrl(baseUrl, cliEndpoints.authExchange);
|
|
60841
60762
|
};
|
|
60842
|
-
const
|
|
60763
|
+
const authLogoutUrl = (baseUrl) => {
|
|
60764
|
+
return toEndpointUrl(baseUrl, cliEndpoints.authLogout);
|
|
60765
|
+
};
|
|
60766
|
+
const authResetUrl = (baseUrl) => {
|
|
60767
|
+
return toEndpointUrl(baseUrl, cliEndpoints.authReset);
|
|
60768
|
+
};
|
|
60769
|
+
const accountMeUrl = (baseUrl) => {
|
|
60770
|
+
return toEndpointUrl(baseUrl, cliEndpoints.accountMe);
|
|
60771
|
+
};
|
|
60772
|
+
const toLoginPendingInfo = (request) => {
|
|
60773
|
+
if (request === null) return null;
|
|
60774
|
+
return {
|
|
60775
|
+
authRequestId: request.authRequestId,
|
|
60776
|
+
verificationUrl: request.verificationUrl
|
|
60777
|
+
};
|
|
60778
|
+
};
|
|
60779
|
+
const isExpiredCurrentAuthRequest = (request, nowMs) => {
|
|
60843
60780
|
const parsedExpiresAt = Date.parse(request.expiresAt);
|
|
60844
60781
|
return !Number.isNaN(parsedExpiresAt) && parsedExpiresAt <= nowMs;
|
|
60845
60782
|
};
|
|
60846
60783
|
const createAuthService = (deps) => {
|
|
60847
60784
|
const now = deps.now ?? Date.now;
|
|
60848
|
-
const storeApprovedAuth = (approvedAuth
|
|
60849
|
-
return deps.credentialsStore.storeApprovedAuth({
|
|
60850
|
-
agentName: approvedAuth.agentName,
|
|
60851
|
-
apiKey: approvedAuth.apiKey
|
|
60852
|
-
}, namespaceKey);
|
|
60853
|
-
};
|
|
60854
|
-
const saveApiKeyAuth = (approvedAuth) => {
|
|
60785
|
+
const storeApprovedAuth = (approvedAuth) => {
|
|
60855
60786
|
return deps.credentialsStore.save({
|
|
60787
|
+
agentId: approvedAuth.agentId,
|
|
60856
60788
|
agentName: approvedAuth.agentName,
|
|
60857
|
-
apiKey: approvedAuth.apiKey
|
|
60789
|
+
apiKey: approvedAuth.apiKey,
|
|
60790
|
+
credentialId: approvedAuth.credentialId,
|
|
60791
|
+
signedInAt: new Date(now()).toISOString()
|
|
60858
60792
|
});
|
|
60859
60793
|
};
|
|
60860
|
-
const
|
|
60861
|
-
const
|
|
60862
|
-
if (Result.isError(
|
|
60863
|
-
const
|
|
60864
|
-
if (Result.isError(
|
|
60865
|
-
const
|
|
60866
|
-
|
|
60794
|
+
const loadLocalAuthSnapshot = () => {
|
|
60795
|
+
const installationId = deps.credentialsStore.getInstallationId();
|
|
60796
|
+
if (Result.isError(installationId)) return installationId;
|
|
60797
|
+
const session = deps.credentialsStore.load();
|
|
60798
|
+
if (Result.isError(session)) return session;
|
|
60799
|
+
const currentAuthRequest = deps.credentialsStore.getCurrentAuthRequest();
|
|
60800
|
+
if (Result.isError(currentAuthRequest)) return currentAuthRequest;
|
|
60801
|
+
return Result.ok({
|
|
60802
|
+
currentAuthRequest: currentAuthRequest.value,
|
|
60803
|
+
installationId: installationId.value,
|
|
60804
|
+
session: session.value
|
|
60867
60805
|
});
|
|
60868
|
-
|
|
60869
|
-
|
|
60870
|
-
|
|
60871
|
-
|
|
60872
|
-
|
|
60873
|
-
|
|
60874
|
-
|
|
60875
|
-
|
|
60876
|
-
|
|
60877
|
-
|
|
60878
|
-
|
|
60879
|
-
|
|
60880
|
-
|
|
60881
|
-
|
|
60882
|
-
|
|
60883
|
-
|
|
60884
|
-
|
|
60806
|
+
};
|
|
60807
|
+
const clearCurrentAuthRequest = () => {
|
|
60808
|
+
return deps.credentialsStore.clearCurrentAuthRequest();
|
|
60809
|
+
};
|
|
60810
|
+
const toStoredAuthorizationHeader = (session) => {
|
|
60811
|
+
return session === null ? null : `Bearer ${session.apiKey}`;
|
|
60812
|
+
};
|
|
60813
|
+
const validateStoredCredentials = async (apiKey) => {
|
|
60814
|
+
const response = await requestJson(deps.httpClient, accountMeUrl(deps.baseUrl), accountMeSchema, { headers: { Authorization: `Bearer ${apiKey}` } }, {
|
|
60815
|
+
context: "account response",
|
|
60816
|
+
mapStatusError: (httpResponse, body) => {
|
|
60817
|
+
if (httpResponse.status === 401) return new AuthError({
|
|
60818
|
+
code: ERROR_CODE.authInvalidCredentials,
|
|
60819
|
+
message: "Stored CLI session is invalid. Run `ogment login` to sign in again.",
|
|
60820
|
+
recovery: { command: "ogment login" }
|
|
60821
|
+
});
|
|
60822
|
+
return new RemoteRequestError({
|
|
60885
60823
|
body,
|
|
60886
|
-
httpStatus:
|
|
60887
|
-
message: "Failed to
|
|
60888
|
-
operation: "
|
|
60824
|
+
httpStatus: httpResponse.status,
|
|
60825
|
+
message: "Failed to validate current CLI session",
|
|
60826
|
+
operation: "account/fetch",
|
|
60889
60827
|
raw: body,
|
|
60890
60828
|
source: "http"
|
|
60891
|
-
}),
|
|
60892
|
-
operation: "auth/exchange"
|
|
60893
|
-
});
|
|
60894
|
-
if (Result.isError(exchangePayload)) return exchangePayload;
|
|
60895
|
-
const exchangeData = exchangePayload.value.data;
|
|
60896
|
-
if (exchangeData.status === "authorization_pending") continue;
|
|
60897
|
-
if (exchangeData.status === "approved") {
|
|
60898
|
-
const storeResult = storeApprovedAuth({
|
|
60899
|
-
agentName: exchangeData.agentName,
|
|
60900
|
-
apiKey: exchangeData.apiKey
|
|
60901
|
-
}, pendingRequest.namespaceKey);
|
|
60902
|
-
if (Result.isError(storeResult)) return storeResult;
|
|
60903
|
-
return Result.ok({
|
|
60904
|
-
agentName: exchangeData.agentName,
|
|
60905
|
-
apiKey: exchangeData.apiKey
|
|
60906
60829
|
});
|
|
60907
|
-
}
|
|
60908
|
-
|
|
60909
|
-
|
|
60830
|
+
},
|
|
60831
|
+
operation: "account/fetch"
|
|
60832
|
+
});
|
|
60833
|
+
if (Result.isError(response)) {
|
|
60834
|
+
if (response.error instanceof AuthError && response.error.code === ERROR_CODE.authInvalidCredentials) return Result.ok(false);
|
|
60835
|
+
return response;
|
|
60910
60836
|
}
|
|
60911
|
-
return Result.ok(
|
|
60837
|
+
return Result.ok(true);
|
|
60912
60838
|
};
|
|
60913
|
-
const
|
|
60914
|
-
const
|
|
60915
|
-
if (Result.
|
|
60839
|
+
const exchangeCurrentAuthRequest = async (snapshot) => {
|
|
60840
|
+
const currentAuthRequest = snapshot.currentAuthRequest;
|
|
60841
|
+
if (currentAuthRequest === null) return Result.ok({ kind: "none" });
|
|
60842
|
+
if (isExpiredCurrentAuthRequest(currentAuthRequest, now())) {
|
|
60843
|
+
const clearResult = clearCurrentAuthRequest();
|
|
60844
|
+
if (Result.isError(clearResult)) return clearResult;
|
|
60845
|
+
return Result.ok({ kind: "none" });
|
|
60846
|
+
}
|
|
60847
|
+
const exchangePayload = await requestJson(deps.httpClient, authExchangeUrl(deps.baseUrl), authExchangeSchema, {
|
|
60848
|
+
body: JSON.stringify({
|
|
60849
|
+
authRequestId: currentAuthRequest.authRequestId,
|
|
60850
|
+
installationId: snapshot.installationId
|
|
60851
|
+
}),
|
|
60852
|
+
headers: { "Content-Type": "application/json" },
|
|
60853
|
+
method: "POST"
|
|
60854
|
+
}, {
|
|
60855
|
+
context: "auth exchange response",
|
|
60856
|
+
mapStatusError: (response, body) => new RemoteRequestError({
|
|
60857
|
+
body,
|
|
60858
|
+
httpStatus: response.status,
|
|
60859
|
+
message: "Failed to exchange current CLI auth request",
|
|
60860
|
+
operation: "auth/exchange",
|
|
60861
|
+
raw: body,
|
|
60862
|
+
source: "http"
|
|
60863
|
+
}),
|
|
60864
|
+
operation: "auth/exchange"
|
|
60865
|
+
});
|
|
60866
|
+
if (Result.isError(exchangePayload)) return exchangePayload;
|
|
60867
|
+
const exchangeData = exchangePayload.value.data;
|
|
60868
|
+
if (exchangeData.status === "authorization_pending") return Result.ok({
|
|
60869
|
+
kind: "pending",
|
|
60870
|
+
request: currentAuthRequest
|
|
60871
|
+
});
|
|
60872
|
+
if (exchangeData.status === "approved") {
|
|
60873
|
+
const approvedAuth = {
|
|
60874
|
+
agentId: exchangeData.agentId,
|
|
60875
|
+
agentName: exchangeData.agentName,
|
|
60876
|
+
apiKey: exchangeData.apiKey,
|
|
60877
|
+
credentialId: exchangeData.credentialId
|
|
60878
|
+
};
|
|
60879
|
+
const storeResult = storeApprovedAuth(approvedAuth);
|
|
60880
|
+
if (Result.isError(storeResult)) return storeResult;
|
|
60881
|
+
return Result.ok({
|
|
60882
|
+
auth: approvedAuth,
|
|
60883
|
+
kind: "approved"
|
|
60884
|
+
});
|
|
60885
|
+
}
|
|
60886
|
+
const clearResult = clearCurrentAuthRequest();
|
|
60887
|
+
if (Result.isError(clearResult)) return clearResult;
|
|
60888
|
+
return Result.ok({ kind: "none" });
|
|
60889
|
+
};
|
|
60890
|
+
const startOrRecoverLogin = async (installationId, options) => {
|
|
60916
60891
|
const startPayload = await requestJson(deps.httpClient, authStartUrl(deps.baseUrl), authStartSchema, {
|
|
60917
60892
|
body: JSON.stringify({
|
|
60918
60893
|
...deps.executionEnvironment === void 0 ? {} : { executionEnvironment: deps.executionEnvironment },
|
|
60919
|
-
installationId
|
|
60920
|
-
namespaceKey: DEFAULT_NAMESPACE_KEY
|
|
60894
|
+
installationId
|
|
60921
60895
|
}),
|
|
60922
60896
|
headers: { "Content-Type": "application/json" },
|
|
60923
60897
|
method: "POST"
|
|
@@ -60934,76 +60908,140 @@ const createAuthService = (deps) => {
|
|
|
60934
60908
|
operation: "auth/start"
|
|
60935
60909
|
});
|
|
60936
60910
|
if (Result.isError(startPayload)) return startPayload;
|
|
60937
|
-
const
|
|
60911
|
+
const currentAuthRequest = {
|
|
60938
60912
|
authRequestId: startPayload.value.data.authRequestId,
|
|
60939
|
-
code: startPayload.value.data.userCode,
|
|
60940
|
-
createdAt: new Date(now()).toISOString(),
|
|
60941
60913
|
expiresAt: startPayload.value.data.expiresAt,
|
|
60942
|
-
namespaceKey: DEFAULT_NAMESPACE_KEY,
|
|
60943
60914
|
verificationUrl: startPayload.value.data.verificationUrl
|
|
60944
|
-
});
|
|
60945
|
-
if (Result.isError(savePendingRequestResult)) return savePendingRequestResult;
|
|
60946
|
-
const verification = {
|
|
60947
|
-
userCode: startPayload.value.data.userCode,
|
|
60948
|
-
verificationUri: startPayload.value.data.verificationUrl
|
|
60949
60915
|
};
|
|
60950
|
-
|
|
60916
|
+
const saveCurrentAuthRequestResult = deps.credentialsStore.saveCurrentAuthRequest(currentAuthRequest);
|
|
60917
|
+
if (Result.isError(saveCurrentAuthRequestResult)) return saveCurrentAuthRequestResult;
|
|
60918
|
+
if (startPayload.value.data.disposition === "reused_approved") {
|
|
60919
|
+
const exchangedCurrentAuthRequest = await exchangeCurrentAuthRequest({
|
|
60920
|
+
currentAuthRequest,
|
|
60921
|
+
installationId,
|
|
60922
|
+
session: null
|
|
60923
|
+
});
|
|
60924
|
+
if (Result.isError(exchangedCurrentAuthRequest)) return exchangedCurrentAuthRequest;
|
|
60925
|
+
if (exchangedCurrentAuthRequest.value.kind === "approved") return Result.ok({
|
|
60926
|
+
agentName: exchangedCurrentAuthRequest.value.auth.agentName,
|
|
60927
|
+
loggedIn: true,
|
|
60928
|
+
outcome: "authenticated"
|
|
60929
|
+
});
|
|
60930
|
+
}
|
|
60931
|
+
const verification = toLoginPendingInfo(currentAuthRequest);
|
|
60932
|
+
if (verification !== null) options.onPending?.(verification);
|
|
60951
60933
|
return Result.ok({
|
|
60952
60934
|
agentName: null,
|
|
60953
60935
|
loggedIn: false,
|
|
60954
60936
|
outcome: "pending_approval",
|
|
60955
|
-
verification
|
|
60937
|
+
verification: verification ?? {
|
|
60938
|
+
authRequestId: currentAuthRequest.authRequestId,
|
|
60939
|
+
verificationUrl: currentAuthRequest.verificationUrl
|
|
60940
|
+
}
|
|
60956
60941
|
});
|
|
60957
60942
|
};
|
|
60958
60943
|
return {
|
|
60959
60944
|
login: async (options) => {
|
|
60960
|
-
|
|
60961
|
-
|
|
60962
|
-
|
|
60963
|
-
|
|
60964
|
-
|
|
60965
|
-
if (
|
|
60966
|
-
|
|
60967
|
-
agentName: "CLI Agent",
|
|
60945
|
+
const snapshot = loadLocalAuthSnapshot();
|
|
60946
|
+
if (Result.isError(snapshot)) return snapshot;
|
|
60947
|
+
if (snapshot.value.session !== null) {
|
|
60948
|
+
const validationResult = await validateStoredCredentials(snapshot.value.session.apiKey);
|
|
60949
|
+
if (Result.isError(validationResult)) return validationResult;
|
|
60950
|
+
if (validationResult.value) return Result.ok({
|
|
60951
|
+
agentName: snapshot.value.session.agentName ?? "CLI Agent",
|
|
60968
60952
|
loggedIn: true,
|
|
60969
|
-
outcome: "
|
|
60953
|
+
outcome: "already_authenticated"
|
|
60970
60954
|
});
|
|
60955
|
+
const deleteResult = deps.credentialsStore.delete();
|
|
60956
|
+
if (Result.isError(deleteResult)) return deleteResult;
|
|
60971
60957
|
}
|
|
60972
|
-
|
|
60973
|
-
|
|
60974
|
-
|
|
60975
|
-
|
|
60976
|
-
}));
|
|
60977
|
-
const stored = deps.credentialsStore.load();
|
|
60978
|
-
if (Result.isError(stored)) return stored;
|
|
60979
|
-
if (stored.value !== null) return Result.ok({
|
|
60980
|
-
agentName: stored.value.agentName ?? "CLI Agent",
|
|
60981
|
-
loggedIn: true,
|
|
60982
|
-
outcome: "already_authenticated"
|
|
60983
|
-
});
|
|
60984
|
-
const exchangedPendingAuth = await tryExchangePendingRequests();
|
|
60985
|
-
if (Result.isError(exchangedPendingAuth)) return exchangedPendingAuth;
|
|
60986
|
-
if (exchangedPendingAuth.value !== null) return Result.ok({
|
|
60987
|
-
agentName: exchangedPendingAuth.value.agentName,
|
|
60958
|
+
const exchangedCurrentAuthRequest = await exchangeCurrentAuthRequest(snapshot.value);
|
|
60959
|
+
if (Result.isError(exchangedCurrentAuthRequest)) return exchangedCurrentAuthRequest;
|
|
60960
|
+
if (exchangedCurrentAuthRequest.value.kind === "approved") return Result.ok({
|
|
60961
|
+
agentName: exchangedCurrentAuthRequest.value.auth.agentName,
|
|
60988
60962
|
loggedIn: true,
|
|
60989
60963
|
outcome: "authenticated"
|
|
60990
60964
|
});
|
|
60991
|
-
|
|
60965
|
+
if (exchangedCurrentAuthRequest.value.kind === "pending") {
|
|
60966
|
+
const verification = toLoginPendingInfo(exchangedCurrentAuthRequest.value.request);
|
|
60967
|
+
if (verification !== null) options.onPending?.(verification);
|
|
60968
|
+
return Result.ok({
|
|
60969
|
+
agentName: null,
|
|
60970
|
+
loggedIn: false,
|
|
60971
|
+
outcome: "pending_approval",
|
|
60972
|
+
verification: verification ?? {
|
|
60973
|
+
authRequestId: exchangedCurrentAuthRequest.value.request.authRequestId,
|
|
60974
|
+
verificationUrl: exchangedCurrentAuthRequest.value.request.verificationUrl
|
|
60975
|
+
}
|
|
60976
|
+
});
|
|
60977
|
+
}
|
|
60978
|
+
return startOrRecoverLogin(snapshot.value.installationId, options);
|
|
60992
60979
|
},
|
|
60993
60980
|
logout: async () => {
|
|
60994
|
-
const
|
|
60995
|
-
if (Result.isError(
|
|
60996
|
-
|
|
60997
|
-
|
|
60998
|
-
|
|
60999
|
-
localCredentialsDeleted: false,
|
|
61000
|
-
revoked: false
|
|
60981
|
+
const snapshot = loadLocalAuthSnapshot();
|
|
60982
|
+
if (Result.isError(snapshot)) return snapshot;
|
|
60983
|
+
if (snapshot.value.session === null) return Result.ok({
|
|
60984
|
+
localStateCleared: false,
|
|
60985
|
+
remoteSignedOut: false
|
|
61001
60986
|
});
|
|
60987
|
+
const storedAuthorizationHeader = toStoredAuthorizationHeader(snapshot.value.session);
|
|
60988
|
+
let remoteSignedOut = false;
|
|
60989
|
+
if (storedAuthorizationHeader !== null) {
|
|
60990
|
+
const logoutPayload = await requestJson(deps.httpClient, authLogoutUrl(deps.baseUrl), authLogoutSchema, {
|
|
60991
|
+
headers: { Authorization: storedAuthorizationHeader },
|
|
60992
|
+
method: "POST"
|
|
60993
|
+
}, {
|
|
60994
|
+
context: "auth logout response",
|
|
60995
|
+
mapStatusError: (response, body) => new RemoteRequestError({
|
|
60996
|
+
body,
|
|
60997
|
+
httpStatus: response.status,
|
|
60998
|
+
message: "Failed to sign out current CLI session",
|
|
60999
|
+
operation: "auth/logout",
|
|
61000
|
+
raw: body,
|
|
61001
|
+
source: "http"
|
|
61002
|
+
}),
|
|
61003
|
+
operation: "auth/logout"
|
|
61004
|
+
});
|
|
61005
|
+
if (Result.isOk(logoutPayload)) remoteSignedOut = true;
|
|
61006
|
+
}
|
|
61002
61007
|
const deleteResult = deps.credentialsStore.delete();
|
|
61003
61008
|
if (Result.isError(deleteResult)) return deleteResult;
|
|
61004
61009
|
return Result.ok({
|
|
61005
|
-
|
|
61006
|
-
|
|
61010
|
+
localStateCleared: true,
|
|
61011
|
+
remoteSignedOut
|
|
61012
|
+
});
|
|
61013
|
+
},
|
|
61014
|
+
reset: async () => {
|
|
61015
|
+
const snapshot = loadLocalAuthSnapshot();
|
|
61016
|
+
if (Result.isError(snapshot)) return snapshot;
|
|
61017
|
+
const storedAuthorizationHeader = toStoredAuthorizationHeader(snapshot.value.session);
|
|
61018
|
+
const remoteResetResult = await requestJson(deps.httpClient, authResetUrl(deps.baseUrl), authResetSchema, {
|
|
61019
|
+
body: JSON.stringify({ installationId: snapshot.value.installationId }),
|
|
61020
|
+
headers: {
|
|
61021
|
+
"Content-Type": "application/json",
|
|
61022
|
+
...storedAuthorizationHeader === null ? {} : { Authorization: storedAuthorizationHeader }
|
|
61023
|
+
},
|
|
61024
|
+
method: "POST"
|
|
61025
|
+
}, {
|
|
61026
|
+
context: "auth reset response",
|
|
61027
|
+
mapStatusError: (response, body) => new RemoteRequestError({
|
|
61028
|
+
body,
|
|
61029
|
+
httpStatus: response.status,
|
|
61030
|
+
message: "Failed to reset current CLI installation",
|
|
61031
|
+
operation: "auth/reset",
|
|
61032
|
+
raw: body,
|
|
61033
|
+
source: "http"
|
|
61034
|
+
}),
|
|
61035
|
+
operation: "auth/reset"
|
|
61036
|
+
});
|
|
61037
|
+
const remoteReset = Result.isOk(remoteResetResult);
|
|
61038
|
+
const localStateCleared = snapshot.value.session !== null || snapshot.value.currentAuthRequest !== null;
|
|
61039
|
+
const resetLocalStateResult = deps.credentialsStore.reset();
|
|
61040
|
+
if (Result.isError(resetLocalStateResult)) return resetLocalStateResult;
|
|
61041
|
+
return Result.ok({
|
|
61042
|
+
installationReset: true,
|
|
61043
|
+
localStateCleared,
|
|
61044
|
+
remoteReset
|
|
61007
61045
|
});
|
|
61008
61046
|
},
|
|
61009
61047
|
resolveApiKey: async (overrideApiKey) => {
|
|
@@ -61014,42 +61052,16 @@ const createAuthService = (deps) => {
|
|
|
61014
61052
|
});
|
|
61015
61053
|
if (resolution.apiKey !== null) return Result.ok(resolution.apiKey);
|
|
61016
61054
|
if (resolution.source === "credentialsError" && resolution.loadError) return Result.err(resolution.loadError);
|
|
61017
|
-
const
|
|
61018
|
-
if (Result.isError(
|
|
61019
|
-
|
|
61055
|
+
const snapshot = loadLocalAuthSnapshot();
|
|
61056
|
+
if (Result.isError(snapshot)) return snapshot;
|
|
61057
|
+
const exchangedCurrentAuthRequest = await exchangeCurrentAuthRequest(snapshot.value);
|
|
61058
|
+
if (Result.isError(exchangedCurrentAuthRequest)) return exchangedCurrentAuthRequest;
|
|
61059
|
+
if (exchangedCurrentAuthRequest.value.kind === "approved") return Result.ok(exchangedCurrentAuthRequest.value.auth.apiKey);
|
|
61020
61060
|
return Result.err(new AuthError({
|
|
61021
61061
|
code: ERROR_CODE.authRequired,
|
|
61022
|
-
message: "Not logged in. Run `ogment
|
|
61023
|
-
recovery: { command: "ogment
|
|
61062
|
+
message: "Not logged in. Run `ogment login` or set OGMENT_API_KEY.",
|
|
61063
|
+
recovery: { command: "ogment login" }
|
|
61024
61064
|
}));
|
|
61025
|
-
},
|
|
61026
|
-
status: async (overrideApiKey) => {
|
|
61027
|
-
const resolution = resolveApiKey({
|
|
61028
|
-
apiKeyOverride: overrideApiKey,
|
|
61029
|
-
credentialsStore: deps.credentialsStore,
|
|
61030
|
-
envApiKey: deps.envApiKey
|
|
61031
|
-
});
|
|
61032
|
-
if (resolution.source === "credentialsError" && resolution.loadError) return Result.err(resolution.loadError);
|
|
61033
|
-
if (resolution.apiKey !== null) {
|
|
61034
|
-
const apiKeySource = resolution.source === "credentialsFile" ? "credentialsFile" : resolution.source === "apiKeyOption" ? "apiKeyOption" : "env";
|
|
61035
|
-
return Result.ok({
|
|
61036
|
-
agentName: resolution.agentName,
|
|
61037
|
-
apiKeySource,
|
|
61038
|
-
loggedIn: true
|
|
61039
|
-
});
|
|
61040
|
-
}
|
|
61041
|
-
const exchangedPendingAuth = await tryExchangePendingRequests();
|
|
61042
|
-
if (Result.isError(exchangedPendingAuth)) return exchangedPendingAuth;
|
|
61043
|
-
if (exchangedPendingAuth.value !== null) return Result.ok({
|
|
61044
|
-
agentName: exchangedPendingAuth.value.agentName,
|
|
61045
|
-
apiKeySource: "credentialsFile",
|
|
61046
|
-
loggedIn: true
|
|
61047
|
-
});
|
|
61048
|
-
return Result.ok({
|
|
61049
|
-
agentName: null,
|
|
61050
|
-
apiKeySource: "none",
|
|
61051
|
-
loggedIn: false
|
|
61052
|
-
});
|
|
61053
61065
|
}
|
|
61054
61066
|
};
|
|
61055
61067
|
};
|
|
@@ -61062,9 +61074,9 @@ const maskApiKey = (apiKey) => {
|
|
|
61062
61074
|
};
|
|
61063
61075
|
const nextActionByIssueCode = (includeDebug) => {
|
|
61064
61076
|
return {
|
|
61065
|
-
auth_failed: "Run `ogment
|
|
61077
|
+
auth_failed: "Run `ogment login` to refresh credentials.",
|
|
61066
61078
|
credentials_load_failed: "Check file permissions and contents of `~/.config/ogment/auth-state.json`.",
|
|
61067
|
-
no_api_key: "Run `ogment
|
|
61079
|
+
no_api_key: "Run `ogment login` or set `OGMENT_API_KEY`.",
|
|
61068
61080
|
unreachable: includeDebug ? "Verify `OGMENT_BASE_URL` and network connectivity." : "Verify network connectivity."
|
|
61069
61081
|
};
|
|
61070
61082
|
};
|
|
@@ -61103,6 +61115,8 @@ const createInfoService = (deps) => {
|
|
|
61103
61115
|
credentialsStore: deps.credentialsStore,
|
|
61104
61116
|
envApiKey: deps.envApiKey
|
|
61105
61117
|
});
|
|
61118
|
+
const installationIdResult = deps.credentialsStore.getInstallationId();
|
|
61119
|
+
const installationId = Result.isOk(installationIdResult) ? installationIdResult.value : null;
|
|
61106
61120
|
const selectedApiKey = apiKeyResolution.apiKey;
|
|
61107
61121
|
const credentialsFileExists = existsSyncFn(deps.credentialsPath);
|
|
61108
61122
|
const endpoint = `${deps.baseUrl}${cliEndpoints.accountMe}`;
|
|
@@ -61127,6 +61141,7 @@ const createInfoService = (deps) => {
|
|
|
61127
61141
|
};
|
|
61128
61142
|
const collectAccount = async () => {
|
|
61129
61143
|
if (selectedApiKey === null) return {
|
|
61144
|
+
actingAgent: null,
|
|
61130
61145
|
...emptyAccountErrorDetails(),
|
|
61131
61146
|
errorType: null,
|
|
61132
61147
|
latencyMs: null,
|
|
@@ -61144,6 +61159,12 @@ const createInfoService = (deps) => {
|
|
|
61144
61159
|
return organization.servers.map((server) => server.path);
|
|
61145
61160
|
});
|
|
61146
61161
|
return {
|
|
61162
|
+
actingAgent: accountResult.value.actingAgent === null ? null : {
|
|
61163
|
+
agentId: accountResult.value.actingAgent.agentId,
|
|
61164
|
+
agentName: accountResult.value.actingAgent.agentName,
|
|
61165
|
+
boundInstallationId: accountResult.value.actingAgent.boundInstallationId,
|
|
61166
|
+
boundToCurrentInstallation: installationId === null || accountResult.value.actingAgent.boundInstallationId === null ? null : accountResult.value.actingAgent.boundInstallationId === installationId
|
|
61167
|
+
},
|
|
61147
61168
|
...emptyAccountErrorDetails(),
|
|
61148
61169
|
errorType: null,
|
|
61149
61170
|
latencyMs: accountElapsedMs,
|
|
@@ -61170,6 +61191,7 @@ const createInfoService = (deps) => {
|
|
|
61170
61191
|
break;
|
|
61171
61192
|
}
|
|
61172
61193
|
return {
|
|
61194
|
+
actingAgent: null,
|
|
61173
61195
|
..."code" in accountResult.error ? { errorCode: String(accountResult.error.code) } : { errorCode: null },
|
|
61174
61196
|
..."httpStatus" in accountResult.error ? { errorHttpStatus: typeof accountResult.error.httpStatus === "number" ? accountResult.error.httpStatus : null } : { errorHttpStatus: null },
|
|
61175
61197
|
..."mcpCode" in accountResult.error ? { errorMcpCode: typeof accountResult.error.mcpCode === "number" ? accountResult.error.mcpCode : null } : { errorMcpCode: null },
|
|
@@ -61215,13 +61237,18 @@ const createInfoService = (deps) => {
|
|
|
61215
61237
|
code: "unexpected_diagnostic_error",
|
|
61216
61238
|
message: `Unexpected diagnostic error: ${account.message ?? "unknown error"}`
|
|
61217
61239
|
});
|
|
61240
|
+
if (Result.isError(installationIdResult)) issues.push({
|
|
61241
|
+
code: "credentials_load_failed",
|
|
61242
|
+
message: `Failed to load installation identity: ${installationIdResult.error.message}`
|
|
61243
|
+
});
|
|
61218
61244
|
return {
|
|
61219
61245
|
auth: {
|
|
61220
61246
|
apiKeyPresent: selectedApiKey !== null,
|
|
61221
61247
|
apiKeyPreview: selectedApiKey === null ? null : maskApiKey(selectedApiKey),
|
|
61222
61248
|
apiKeySource: apiKeyResolution.source,
|
|
61223
61249
|
credentialsFileExists,
|
|
61224
|
-
credentialsFileLoadError: apiKeyResolution.loadError?.message ?? null
|
|
61250
|
+
credentialsFileLoadError: apiKeyResolution.loadError?.message ?? null,
|
|
61251
|
+
installationId
|
|
61225
61252
|
},
|
|
61226
61253
|
config: {
|
|
61227
61254
|
baseUrl: deps.baseUrl,
|
|
@@ -61238,7 +61265,9 @@ const createInfoService = (deps) => {
|
|
|
61238
61265
|
],
|
|
61239
61266
|
quickCommands: [
|
|
61240
61267
|
"ogment status",
|
|
61241
|
-
"ogment
|
|
61268
|
+
"ogment login",
|
|
61269
|
+
"ogment logout",
|
|
61270
|
+
"ogment reset",
|
|
61242
61271
|
"ogment catalog",
|
|
61243
61272
|
"ogment catalog <server-id>",
|
|
61244
61273
|
"ogment catalog <server-id> <tool-name>",
|
|
@@ -72030,9 +72059,7 @@ const createRuntime = () => {
|
|
|
72030
72059
|
const output = new OutputManager();
|
|
72031
72060
|
const authStateStore = createFileCredentialsStore({
|
|
72032
72061
|
configDir: runtimeConfig.configDir,
|
|
72033
|
-
credentialsPath: runtimeConfig.credentialsPath
|
|
72034
|
-
legacyCredentialsPath: runtimeConfig.legacyCredentialsPath,
|
|
72035
|
-
telemetryPath: runtimeConfig.telemetryPath
|
|
72062
|
+
credentialsPath: runtimeConfig.credentialsPath
|
|
72036
72063
|
});
|
|
72037
72064
|
const httpClient = createHttpClient();
|
|
72038
72065
|
const services = {
|
|
@@ -72152,7 +72179,7 @@ const createProgram = (runtime, parseState) => {
|
|
|
72152
72179
|
return [
|
|
72153
72180
|
"",
|
|
72154
72181
|
"Examples:",
|
|
72155
|
-
" $ ogment
|
|
72182
|
+
" $ ogment login",
|
|
72156
72183
|
" $ ogment catalog billing create_invoice --example",
|
|
72157
72184
|
" $ ogment invoke billing create_invoice --input '{\"amount\":100}'",
|
|
72158
72185
|
"",
|
|
@@ -72164,27 +72191,14 @@ const createProgram = (runtime, parseState) => {
|
|
|
72164
72191
|
runtime.output.configure(mapGlobalOutputOptions(options));
|
|
72165
72192
|
runtime.context.apiKeyOverride = options.apiKey;
|
|
72166
72193
|
});
|
|
72167
|
-
|
|
72168
|
-
|
|
72169
|
-
return [
|
|
72170
|
-
"",
|
|
72171
|
-
"Examples:",
|
|
72172
|
-
" $ ogment auth login",
|
|
72173
|
-
" $ ogment auth status"
|
|
72174
|
-
].join("\n");
|
|
72175
|
-
});
|
|
72176
|
-
authCommand.command("login").summary("Login with device flow (default)").description("Authenticate with Ogment using device flow (recommended)").action((_, command) => {
|
|
72177
|
-
const { apiKey } = asGlobalOptions(command);
|
|
72178
|
-
setInvocation({
|
|
72179
|
-
apiKey,
|
|
72180
|
-
kind: "auth_login"
|
|
72181
|
-
});
|
|
72194
|
+
program.command("login").summary("Authenticate this CLI installation").description("Start or complete browser-based login for this installation").helpGroup("Authentication Commands:").action(() => {
|
|
72195
|
+
setInvocation({ kind: "login" });
|
|
72182
72196
|
});
|
|
72183
|
-
|
|
72184
|
-
setInvocation({ kind: "
|
|
72197
|
+
program.command("logout").summary("Sign this CLI installation out").description("Sign out the current local CLI session").helpGroup("Authentication Commands:").action(() => {
|
|
72198
|
+
setInvocation({ kind: "logout" });
|
|
72185
72199
|
});
|
|
72186
|
-
|
|
72187
|
-
setInvocation({ kind: "
|
|
72200
|
+
program.command("reset").summary("Reset this CLI installation").description("Wipe local state and create a fresh CLI installation identity").helpGroup("Authentication Commands:").action(() => {
|
|
72201
|
+
setInvocation({ kind: "reset" });
|
|
72188
72202
|
});
|
|
72189
72203
|
program.command("catalog [serverId] [toolName]").summary("Discover servers and inspect tools").description("Discover servers and tools with progressive disclosure").helpGroup("Discovery Commands:").addOption(new Option("--cursor <cursor>", "Pagination cursor (catalog summary only)").conflicts("example")).addOption(new Option("--limit <limit>", "Maximum servers to return (catalog summary only)").argParser(parseCatalogLimitOption).conflicts("example")).addOption(new Option("--example", "Include a generated example input payload (tool details only)").conflicts(["cursor", "limit"])).action((serverId, toolName, options) => {
|
|
72190
72204
|
setInvocation({
|
|
@@ -72205,7 +72219,7 @@ const createProgram = (runtime, parseState) => {
|
|
|
72205
72219
|
toolName
|
|
72206
72220
|
});
|
|
72207
72221
|
});
|
|
72208
|
-
program.command("status").summary("Show runtime diagnostics").description("Show runtime configuration and
|
|
72222
|
+
program.command("status").summary("Show runtime diagnostics and auth state").description("Show runtime configuration, connectivity, and auth diagnostics").helpGroup("Diagnostics Commands:").action(() => {
|
|
72209
72223
|
setInvocation({ kind: "status" });
|
|
72210
72224
|
});
|
|
72211
72225
|
program.action(() => {
|
|
@@ -72232,9 +72246,12 @@ const RUNTIME_ERROR_COMMAND_PATH = "ogment <runtime_error>";
|
|
|
72232
72246
|
const PARSE_ERROR_COMMAND_PATH = "ogment <parse_error>";
|
|
72233
72247
|
const CLI_PACKAGE_NAME = "@ogment-ai/cli";
|
|
72234
72248
|
const PARSE_ERROR_SCOPE_COMMAND_PATHS = {
|
|
72235
|
-
|
|
72249
|
+
login: "ogment login <parse_error>",
|
|
72250
|
+
logout: "ogment logout <parse_error>",
|
|
72251
|
+
reset: "ogment reset <parse_error>",
|
|
72236
72252
|
catalog: "ogment catalog <parse_error>",
|
|
72237
|
-
invoke: "ogment invoke <parse_error>"
|
|
72253
|
+
invoke: "ogment invoke <parse_error>",
|
|
72254
|
+
status: "ogment status <parse_error>"
|
|
72238
72255
|
};
|
|
72239
72256
|
const isParseErrorTelemetryScope = (value) => {
|
|
72240
72257
|
return value in PARSE_ERROR_SCOPE_COMMAND_PATHS;
|
|
@@ -72252,24 +72269,24 @@ const telemetryInputModeFromInvoke = (input) => {
|
|
|
72252
72269
|
return "inline_json";
|
|
72253
72270
|
};
|
|
72254
72271
|
const telemetryContextResolvers = {
|
|
72255
|
-
|
|
72272
|
+
login: (_) => {
|
|
72256
72273
|
return {
|
|
72257
|
-
commandKind: "
|
|
72258
|
-
commandPath: "ogment
|
|
72274
|
+
commandKind: "login",
|
|
72275
|
+
commandPath: "ogment login",
|
|
72259
72276
|
inputMode: null
|
|
72260
72277
|
};
|
|
72261
72278
|
},
|
|
72262
|
-
|
|
72279
|
+
logout: (_) => {
|
|
72263
72280
|
return {
|
|
72264
|
-
commandKind: "
|
|
72265
|
-
commandPath: "ogment
|
|
72281
|
+
commandKind: "logout",
|
|
72282
|
+
commandPath: "ogment logout",
|
|
72266
72283
|
inputMode: null
|
|
72267
72284
|
};
|
|
72268
72285
|
},
|
|
72269
|
-
|
|
72286
|
+
reset: (_) => {
|
|
72270
72287
|
return {
|
|
72271
|
-
commandKind: "
|
|
72272
|
-
commandPath: "ogment
|
|
72288
|
+
commandKind: "reset",
|
|
72289
|
+
commandPath: "ogment reset",
|
|
72273
72290
|
inputMode: null
|
|
72274
72291
|
};
|
|
72275
72292
|
},
|
|
@@ -72314,9 +72331,9 @@ const telemetryContextResolvers = {
|
|
|
72314
72331
|
};
|
|
72315
72332
|
const telemetryContextFromInvocation = (invocation) => {
|
|
72316
72333
|
switch (invocation.kind) {
|
|
72317
|
-
case "
|
|
72318
|
-
case "
|
|
72319
|
-
case "
|
|
72334
|
+
case "login": return telemetryContextResolvers.login(invocation);
|
|
72335
|
+
case "logout": return telemetryContextResolvers.logout(invocation);
|
|
72336
|
+
case "reset": return telemetryContextResolvers.reset(invocation);
|
|
72320
72337
|
case "catalog": return telemetryContextResolvers.catalog(invocation);
|
|
72321
72338
|
case "invoke": return telemetryContextResolvers.invoke(invocation);
|
|
72322
72339
|
case "root": return telemetryContextResolvers.root(invocation);
|
|
@@ -72353,9 +72370,7 @@ const emitRuntimeErrorTelemetry = async (output, input) => {
|
|
|
72353
72370
|
const telemetry = createTelemetryService({
|
|
72354
72371
|
authStateStore: createFileCredentialsStore({
|
|
72355
72372
|
configDir: telemetryConfig.configDir,
|
|
72356
|
-
credentialsPath: telemetryConfig.credentialsPath
|
|
72357
|
-
legacyCredentialsPath: telemetryConfig.legacyCredentialsPath,
|
|
72358
|
-
telemetryPath: telemetryConfig.telemetryPath
|
|
72373
|
+
credentialsPath: telemetryConfig.credentialsPath
|
|
72359
72374
|
}),
|
|
72360
72375
|
baseUrl: telemetryConfig.baseUrl,
|
|
72361
72376
|
cliVersion: telemetryConfig.version,
|
|
@@ -72394,15 +72409,15 @@ const commandContextFromInvocation = (invocation, apiKeyOverride) => {
|
|
|
72394
72409
|
const withBase = (commandName, invocationKind, subcommand = void 0) => {
|
|
72395
72410
|
return {
|
|
72396
72411
|
commandName,
|
|
72397
|
-
hasApiKeyOverride:
|
|
72412
|
+
hasApiKeyOverride: hasApiKeyOverride(apiKeyOverride),
|
|
72398
72413
|
invocationKind,
|
|
72399
72414
|
subcommand
|
|
72400
72415
|
};
|
|
72401
72416
|
};
|
|
72402
72417
|
switch (invocation.kind) {
|
|
72403
|
-
case "
|
|
72404
|
-
case "
|
|
72405
|
-
case "
|
|
72418
|
+
case "login": return withBase("login", "login");
|
|
72419
|
+
case "logout": return withBase("logout", "logout");
|
|
72420
|
+
case "reset": return withBase("reset", "reset");
|
|
72406
72421
|
case "catalog":
|
|
72407
72422
|
if (invocation.toolName !== void 0) return withBase("catalog", "catalog", "tool");
|
|
72408
72423
|
if (invocation.serverId !== void 0) return withBase("catalog", "catalog", "server");
|
|
@@ -72560,4 +72575,4 @@ if (shouldExecuteCli(import.meta.url, process.argv[1])) await executeCli();
|
|
|
72560
72575
|
|
|
72561
72576
|
//#endregion
|
|
72562
72577
|
export { executeCli, runCli, shouldExecuteCli };
|
|
72563
|
-
//# debugId=
|
|
72578
|
+
//# debugId=af3eaa67-a183-47bc-ab25-5c28a25c0929
|