githits 0.4.3 → 0.4.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/.plugin/plugin.json +1 -1
- package/README.md +40 -14
- package/dist/cli.js +882 -274
- package/dist/index.js +1 -1
- package/dist/shared/{chunk-q6d3ttgn.js → chunk-96tjsv6y.js} +1 -1
- package/dist/shared/chunk-k35egwwf.js +15 -0
- package/dist/shared/{chunk-15argn2z.js → chunk-tfqxat16.js} +182 -43
- package/gemini-extension.json +1 -1
- package/package.json +1 -1
- package/plugins/claude/.claude-plugin/plugin.json +1 -1
- package/dist/shared/chunk-kmka6wpx.js +0 -11
package/dist/index.js
CHANGED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import {
|
|
2
|
+
clearAutoLoginAuthSessionMetadata,
|
|
3
|
+
createAuthCommandDependencies,
|
|
4
|
+
createAuthStatusDependencies,
|
|
5
|
+
createContainer,
|
|
6
|
+
loadAutoLoginAuthSessionMetadata
|
|
7
|
+
} from "./chunk-tfqxat16.js";
|
|
8
|
+
import"./chunk-96tjsv6y.js";
|
|
9
|
+
export {
|
|
10
|
+
loadAutoLoginAuthSessionMetadata,
|
|
11
|
+
createContainer,
|
|
12
|
+
createAuthStatusDependencies,
|
|
13
|
+
createAuthCommandDependencies,
|
|
14
|
+
clearAutoLoginAuthSessionMetadata
|
|
15
|
+
};
|
|
@@ -1,20 +1,16 @@
|
|
|
1
1
|
import {
|
|
2
2
|
__require,
|
|
3
3
|
version
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-96tjsv6y.js";
|
|
5
5
|
|
|
6
6
|
// src/services/app-config-paths.ts
|
|
7
7
|
var APP_DIR = "githits";
|
|
8
8
|
function getAppConfigDir(fs) {
|
|
9
9
|
const home = fs.getHomeDir();
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
return fs.joinPath(process.env.APPDATA ?? fs.joinPath(home, "AppData", "Roaming"), APP_DIR);
|
|
13
|
-
case "darwin":
|
|
14
|
-
return fs.joinPath(home, "Library", "Application Support", APP_DIR);
|
|
15
|
-
default:
|
|
16
|
-
return fs.joinPath(process.env.XDG_CONFIG_HOME ?? fs.joinPath(home, ".config"), APP_DIR);
|
|
10
|
+
if (process.platform === "win32") {
|
|
11
|
+
return fs.joinPath(process.env.APPDATA ?? fs.joinPath(home, "AppData", "Roaming"), APP_DIR);
|
|
17
12
|
}
|
|
13
|
+
return fs.joinPath(process.env.XDG_CONFIG_HOME ?? fs.joinPath(home, ".config"), APP_DIR);
|
|
18
14
|
}
|
|
19
15
|
function getAuthConfigPath(fs) {
|
|
20
16
|
return fs.joinPath(getAppConfigDir(fs), "config.toml");
|
|
@@ -25,6 +21,15 @@ function getAuthFileStorageDir(fs) {
|
|
|
25
21
|
function getLegacyAuthStorageDir(fs) {
|
|
26
22
|
return fs.joinPath(fs.getHomeDir(), ".githits");
|
|
27
23
|
}
|
|
24
|
+
function getLegacyMacAppConfigDir(fs) {
|
|
25
|
+
return fs.joinPath(fs.getHomeDir(), "Library", "Application Support", APP_DIR);
|
|
26
|
+
}
|
|
27
|
+
function getLegacyMacAuthConfigPath(fs) {
|
|
28
|
+
return fs.joinPath(getLegacyMacAppConfigDir(fs), "config.toml");
|
|
29
|
+
}
|
|
30
|
+
function getLegacyMacAuthFileStorageDir(fs) {
|
|
31
|
+
return fs.joinPath(getLegacyMacAppConfigDir(fs), "auth");
|
|
32
|
+
}
|
|
28
33
|
// src/services/auth-config.ts
|
|
29
34
|
import { parse as parseToml } from "smol-toml";
|
|
30
35
|
import { z } from "zod";
|
|
@@ -50,7 +55,7 @@ function parseAuthStorageMode(value) {
|
|
|
50
55
|
throw new AuthConfigError(`Invalid auth storage mode "${value}". Use "keychain" or "file". File mode stores OAuth credentials unencrypted on disk.`);
|
|
51
56
|
}
|
|
52
57
|
async function loadAuthConfig(fs) {
|
|
53
|
-
|
|
58
|
+
let configPath = getAuthConfigPath(fs);
|
|
54
59
|
const envMode = process.env.GITHITS_AUTH_STORAGE;
|
|
55
60
|
if (envMode !== undefined && envMode.trim() !== "") {
|
|
56
61
|
try {
|
|
@@ -63,7 +68,12 @@ async function loadAuthConfig(fs) {
|
|
|
63
68
|
}
|
|
64
69
|
}
|
|
65
70
|
if (!await fs.exists(configPath)) {
|
|
66
|
-
|
|
71
|
+
const legacyMacConfigPath = getLegacyMacAuthConfigPath(fs);
|
|
72
|
+
if (process.platform === "darwin" && await fs.exists(legacyMacConfigPath)) {
|
|
73
|
+
configPath = legacyMacConfigPath;
|
|
74
|
+
} else {
|
|
75
|
+
return { storage: "keychain", configPath };
|
|
76
|
+
}
|
|
67
77
|
}
|
|
68
78
|
let rawConfig;
|
|
69
79
|
try {
|
|
@@ -732,6 +742,70 @@ async function clearAuthSessionBestEffort(clearTokens, clearClient) {
|
|
|
732
742
|
if (firstError)
|
|
733
743
|
throw firstError;
|
|
734
744
|
}
|
|
745
|
+
|
|
746
|
+
// src/services/auth-session-metadata-storage.ts
|
|
747
|
+
var METADATA_FILE = "metadata.json";
|
|
748
|
+
var DIR_MODE2 = 448;
|
|
749
|
+
|
|
750
|
+
class AuthSessionMetadataStorage {
|
|
751
|
+
fs;
|
|
752
|
+
configDir;
|
|
753
|
+
metadataPath;
|
|
754
|
+
constructor(fs, configDir) {
|
|
755
|
+
this.fs = fs;
|
|
756
|
+
this.configDir = configDir ?? getAuthFileStorageDir(fs);
|
|
757
|
+
this.metadataPath = fs.joinPath(this.configDir, METADATA_FILE);
|
|
758
|
+
}
|
|
759
|
+
async load(baseUrl) {
|
|
760
|
+
const stored = await this.loadFile();
|
|
761
|
+
if (!stored)
|
|
762
|
+
return null;
|
|
763
|
+
const metadata = stored.sessions[normalizeBaseUrl(baseUrl)] ?? null;
|
|
764
|
+
return isAuthSessionMetadata(metadata) ? metadata : null;
|
|
765
|
+
}
|
|
766
|
+
async saveFromTokens(baseUrl, tokens) {
|
|
767
|
+
const stored = await this.loadFile() ?? {
|
|
768
|
+
version: 1,
|
|
769
|
+
sessions: {}
|
|
770
|
+
};
|
|
771
|
+
stored.sessions[normalizeBaseUrl(baseUrl)] = {
|
|
772
|
+
createdAt: tokens.createdAt,
|
|
773
|
+
expiresAt: tokens.expiresAt,
|
|
774
|
+
updatedAt: new Date().toISOString()
|
|
775
|
+
};
|
|
776
|
+
await this.fs.ensureDir(this.configDir, DIR_MODE2);
|
|
777
|
+
await this.fs.atomicWriteFile(this.metadataPath, JSON.stringify(stored, null, 2));
|
|
778
|
+
}
|
|
779
|
+
async clear(baseUrl) {
|
|
780
|
+
const stored = await this.loadFile();
|
|
781
|
+
if (!stored)
|
|
782
|
+
return;
|
|
783
|
+
delete stored.sessions[normalizeBaseUrl(baseUrl)];
|
|
784
|
+
if (Object.keys(stored.sessions).length === 0) {
|
|
785
|
+
await this.fs.deleteFile(this.metadataPath);
|
|
786
|
+
return;
|
|
787
|
+
}
|
|
788
|
+
await this.fs.atomicWriteFile(this.metadataPath, JSON.stringify(stored, null, 2));
|
|
789
|
+
}
|
|
790
|
+
async loadFile() {
|
|
791
|
+
if (!await this.fs.exists(this.metadataPath))
|
|
792
|
+
return null;
|
|
793
|
+
try {
|
|
794
|
+
const content = await this.fs.readFile(this.metadataPath);
|
|
795
|
+
const data = JSON.parse(content);
|
|
796
|
+
if (data.version !== 1 || !data.sessions)
|
|
797
|
+
return null;
|
|
798
|
+
return data;
|
|
799
|
+
} catch {
|
|
800
|
+
return null;
|
|
801
|
+
}
|
|
802
|
+
}
|
|
803
|
+
}
|
|
804
|
+
function isAuthSessionMetadata(value) {
|
|
805
|
+
if (value === null || typeof value !== "object")
|
|
806
|
+
return false;
|
|
807
|
+
return typeof value.createdAt === "string" && value.createdAt.length > 0 && typeof value.updatedAt === "string" && value.updatedAt.length > 0 && (value.expiresAt === null || typeof value.expiresAt === "string" && value.expiresAt.length > 0);
|
|
808
|
+
}
|
|
735
809
|
// src/services/browser-service.ts
|
|
736
810
|
import open from "open";
|
|
737
811
|
|
|
@@ -3533,15 +3607,19 @@ class MigratingAuthStorage {
|
|
|
3533
3607
|
mode;
|
|
3534
3608
|
configPath;
|
|
3535
3609
|
onWarning;
|
|
3610
|
+
metadata;
|
|
3611
|
+
additionalLegacyStores;
|
|
3536
3612
|
warnedFileModeKeychainExport = false;
|
|
3537
3613
|
warnedAmbiguousPlaintext = false;
|
|
3538
|
-
constructor(primary, file, legacy, mode, configPath = "your GitHits config.toml", onWarning = () => {}) {
|
|
3614
|
+
constructor(primary, file, legacy, mode, configPath = "your GitHits config.toml", onWarning = () => {}, metadata, additionalLegacyStores = []) {
|
|
3539
3615
|
this.primary = primary;
|
|
3540
3616
|
this.file = file;
|
|
3541
3617
|
this.legacy = legacy;
|
|
3542
3618
|
this.mode = mode;
|
|
3543
3619
|
this.configPath = configPath;
|
|
3544
3620
|
this.onWarning = onWarning;
|
|
3621
|
+
this.metadata = metadata;
|
|
3622
|
+
this.additionalLegacyStores = additionalLegacyStores;
|
|
3545
3623
|
}
|
|
3546
3624
|
async loadTokens(baseUrl2) {
|
|
3547
3625
|
if (this.mode === "file") {
|
|
@@ -3552,10 +3630,12 @@ class MigratingAuthStorage {
|
|
|
3552
3630
|
async saveTokens(baseUrl2, data) {
|
|
3553
3631
|
if (this.mode === "file") {
|
|
3554
3632
|
await this.file.saveTokens(baseUrl2, data);
|
|
3633
|
+
await this.saveMetadataBestEffort(baseUrl2, data);
|
|
3555
3634
|
return;
|
|
3556
3635
|
}
|
|
3557
3636
|
try {
|
|
3558
3637
|
await this.primary.saveTokens(baseUrl2, data);
|
|
3638
|
+
await this.saveMetadataBestEffort(baseUrl2, data);
|
|
3559
3639
|
} catch (error) {
|
|
3560
3640
|
throw this.toPolicyError(error);
|
|
3561
3641
|
}
|
|
@@ -3571,6 +3651,10 @@ class MigratingAuthStorage {
|
|
|
3571
3651
|
const primaryError = await this.clearBestEffort(() => this.primary.clearTokens(baseUrl2));
|
|
3572
3652
|
await this.clearBestEffort(() => this.file.clearTokens(baseUrl2));
|
|
3573
3653
|
await this.clearBestEffort(() => this.legacy.clearTokens(baseUrl2));
|
|
3654
|
+
for (const legacy of this.additionalLegacyStores) {
|
|
3655
|
+
await this.clearBestEffort(() => legacy.clearTokens(baseUrl2));
|
|
3656
|
+
}
|
|
3657
|
+
await this.clearBestEffort(() => this.metadata?.clear(baseUrl2) ?? Promise.resolve());
|
|
3574
3658
|
if (primaryError && !(primaryError instanceof KeychainUnavailableError)) {
|
|
3575
3659
|
throw primaryError;
|
|
3576
3660
|
}
|
|
@@ -3603,6 +3687,9 @@ class MigratingAuthStorage {
|
|
|
3603
3687
|
const primaryError = await this.clearBestEffort(() => this.primary.clearClient(baseUrl2));
|
|
3604
3688
|
await this.clearBestEffort(() => this.file.clearClient(baseUrl2));
|
|
3605
3689
|
await this.clearBestEffort(() => this.legacy.clearClient(baseUrl2));
|
|
3690
|
+
for (const legacy of this.additionalLegacyStores) {
|
|
3691
|
+
await this.clearBestEffort(() => legacy.clearClient(baseUrl2));
|
|
3692
|
+
}
|
|
3606
3693
|
if (primaryError && !(primaryError instanceof KeychainUnavailableError)) {
|
|
3607
3694
|
throw primaryError;
|
|
3608
3695
|
}
|
|
@@ -3610,10 +3697,12 @@ class MigratingAuthStorage {
|
|
|
3610
3697
|
async saveAuthSession(baseUrl2, client, tokens) {
|
|
3611
3698
|
if (this.mode === "file") {
|
|
3612
3699
|
await this.file.saveAuthSession(baseUrl2, client, tokens);
|
|
3700
|
+
await this.saveMetadataBestEffort(baseUrl2, tokens);
|
|
3613
3701
|
return;
|
|
3614
3702
|
}
|
|
3615
3703
|
try {
|
|
3616
3704
|
await this.primary.saveAuthSession(baseUrl2, client, tokens);
|
|
3705
|
+
await this.saveMetadataBestEffort(baseUrl2, tokens);
|
|
3617
3706
|
} catch (error) {
|
|
3618
3707
|
throw this.toPolicyError(error);
|
|
3619
3708
|
}
|
|
@@ -3622,6 +3711,10 @@ class MigratingAuthStorage {
|
|
|
3622
3711
|
const primaryError = await this.clearBestEffort(() => this.primary.clearAuthSession(baseUrl2));
|
|
3623
3712
|
await this.clearBestEffort(() => this.file.clearAuthSession(baseUrl2));
|
|
3624
3713
|
await this.clearBestEffort(() => this.legacy.clearAuthSession(baseUrl2));
|
|
3714
|
+
for (const legacy of this.additionalLegacyStores) {
|
|
3715
|
+
await this.clearBestEffort(() => legacy.clearAuthSession(baseUrl2));
|
|
3716
|
+
}
|
|
3717
|
+
await this.clearBestEffort(() => this.metadata?.clear(baseUrl2) ?? Promise.resolve());
|
|
3625
3718
|
if (primaryError && !(primaryError instanceof KeychainUnavailableError)) {
|
|
3626
3719
|
throw primaryError;
|
|
3627
3720
|
}
|
|
@@ -3632,8 +3725,10 @@ class MigratingAuthStorage {
|
|
|
3632
3725
|
async loadTokensKeychainMode(baseUrl2) {
|
|
3633
3726
|
try {
|
|
3634
3727
|
const primaryTokens = await this.primary.loadTokens(baseUrl2);
|
|
3635
|
-
if (primaryTokens)
|
|
3728
|
+
if (primaryTokens) {
|
|
3729
|
+
await this.saveMetadataBestEffort(baseUrl2, primaryTokens);
|
|
3636
3730
|
return primaryTokens;
|
|
3731
|
+
}
|
|
3637
3732
|
} catch (error) {
|
|
3638
3733
|
if (!(error instanceof KeychainUnavailableError))
|
|
3639
3734
|
throw error;
|
|
@@ -3648,7 +3743,8 @@ class MigratingAuthStorage {
|
|
|
3648
3743
|
return candidate.data;
|
|
3649
3744
|
throw error;
|
|
3650
3745
|
}
|
|
3651
|
-
await this.clearMigratedPlaintext(baseUrl2, "tokens", candidate.source, candidate.ambiguous);
|
|
3746
|
+
await this.clearMigratedPlaintext(baseUrl2, "tokens", candidate.source, candidate.storage, candidate.ambiguous);
|
|
3747
|
+
await this.saveMetadataBestEffort(baseUrl2, candidate.data);
|
|
3652
3748
|
return candidate.data;
|
|
3653
3749
|
}
|
|
3654
3750
|
async loadTokensFileMode(baseUrl2) {
|
|
@@ -3656,8 +3752,9 @@ class MigratingAuthStorage {
|
|
|
3656
3752
|
if (candidate) {
|
|
3657
3753
|
if (candidate.source === "legacy") {
|
|
3658
3754
|
await this.file.saveTokens(baseUrl2, candidate.data);
|
|
3659
|
-
await this.clearBestEffort(() =>
|
|
3755
|
+
await this.clearBestEffort(() => candidate.storage.clearTokens(baseUrl2));
|
|
3660
3756
|
}
|
|
3757
|
+
await this.saveMetadataBestEffort(baseUrl2, candidate.data);
|
|
3661
3758
|
return candidate.data;
|
|
3662
3759
|
}
|
|
3663
3760
|
let primaryTokens = null;
|
|
@@ -3671,6 +3768,7 @@ class MigratingAuthStorage {
|
|
|
3671
3768
|
return null;
|
|
3672
3769
|
this.warnKeychainExport();
|
|
3673
3770
|
await this.file.saveTokens(baseUrl2, primaryTokens);
|
|
3771
|
+
await this.saveMetadataBestEffort(baseUrl2, primaryTokens);
|
|
3674
3772
|
return primaryTokens;
|
|
3675
3773
|
}
|
|
3676
3774
|
async loadClientKeychainMode(baseUrl2) {
|
|
@@ -3692,7 +3790,7 @@ class MigratingAuthStorage {
|
|
|
3692
3790
|
return candidate.data;
|
|
3693
3791
|
throw error;
|
|
3694
3792
|
}
|
|
3695
|
-
await this.clearMigratedPlaintext(baseUrl2, "client", candidate.source, candidate.ambiguous);
|
|
3793
|
+
await this.clearMigratedPlaintext(baseUrl2, "client", candidate.source, candidate.storage, candidate.ambiguous);
|
|
3696
3794
|
return candidate.data;
|
|
3697
3795
|
}
|
|
3698
3796
|
async loadClientFileMode(baseUrl2) {
|
|
@@ -3700,7 +3798,7 @@ class MigratingAuthStorage {
|
|
|
3700
3798
|
if (candidate) {
|
|
3701
3799
|
if (candidate.source === "legacy") {
|
|
3702
3800
|
await this.file.saveClient(baseUrl2, candidate.data);
|
|
3703
|
-
await this.clearBestEffort(() =>
|
|
3801
|
+
await this.clearBestEffort(() => candidate.storage.clearClient(baseUrl2));
|
|
3704
3802
|
}
|
|
3705
3803
|
return candidate.data;
|
|
3706
3804
|
}
|
|
@@ -3724,18 +3822,22 @@ class MigratingAuthStorage {
|
|
|
3724
3822
|
candidates.push({
|
|
3725
3823
|
data: fileTokens,
|
|
3726
3824
|
source: "file",
|
|
3825
|
+
storage: this.file,
|
|
3727
3826
|
timestamp: fileTokens.createdAt,
|
|
3728
3827
|
ambiguous: false
|
|
3729
3828
|
});
|
|
3730
3829
|
}
|
|
3731
|
-
const
|
|
3732
|
-
|
|
3733
|
-
|
|
3734
|
-
|
|
3735
|
-
|
|
3736
|
-
|
|
3737
|
-
|
|
3738
|
-
|
|
3830
|
+
for (const legacy of this.getLegacyStores()) {
|
|
3831
|
+
const legacyTokens = await legacy.loadTokens(baseUrl2);
|
|
3832
|
+
if (legacyTokens) {
|
|
3833
|
+
candidates.push({
|
|
3834
|
+
data: legacyTokens,
|
|
3835
|
+
source: "legacy",
|
|
3836
|
+
storage: legacy,
|
|
3837
|
+
timestamp: legacyTokens.createdAt,
|
|
3838
|
+
ambiguous: false
|
|
3839
|
+
});
|
|
3840
|
+
}
|
|
3739
3841
|
}
|
|
3740
3842
|
return this.selectNewestCandidate(candidates);
|
|
3741
3843
|
}
|
|
@@ -3746,18 +3848,22 @@ class MigratingAuthStorage {
|
|
|
3746
3848
|
candidates.push({
|
|
3747
3849
|
data: fileClient,
|
|
3748
3850
|
source: "file",
|
|
3851
|
+
storage: this.file,
|
|
3749
3852
|
timestamp: fileClient.registeredAt,
|
|
3750
3853
|
ambiguous: false
|
|
3751
3854
|
});
|
|
3752
3855
|
}
|
|
3753
|
-
const
|
|
3754
|
-
|
|
3755
|
-
|
|
3756
|
-
|
|
3757
|
-
|
|
3758
|
-
|
|
3759
|
-
|
|
3760
|
-
|
|
3856
|
+
for (const legacy of this.getLegacyStores()) {
|
|
3857
|
+
const legacyClient = await legacy.loadClient(baseUrl2);
|
|
3858
|
+
if (legacyClient) {
|
|
3859
|
+
candidates.push({
|
|
3860
|
+
data: legacyClient,
|
|
3861
|
+
source: "legacy",
|
|
3862
|
+
storage: legacy,
|
|
3863
|
+
timestamp: legacyClient.registeredAt,
|
|
3864
|
+
ambiguous: false
|
|
3865
|
+
});
|
|
3866
|
+
}
|
|
3761
3867
|
}
|
|
3762
3868
|
return this.selectNewestCandidate(candidates);
|
|
3763
3869
|
}
|
|
@@ -3772,7 +3878,7 @@ class MigratingAuthStorage {
|
|
|
3772
3878
|
}));
|
|
3773
3879
|
if (parsed.some((entry) => Number.isNaN(entry.timestampMs))) {
|
|
3774
3880
|
this.warnAmbiguousPlaintext();
|
|
3775
|
-
const selected = candidates.find((candidate) => candidate.source === "file") ??
|
|
3881
|
+
const selected = candidates.find((candidate) => candidate.source === "file") ?? null;
|
|
3776
3882
|
if (selected)
|
|
3777
3883
|
selected.ambiguous = true;
|
|
3778
3884
|
return selected;
|
|
@@ -3784,16 +3890,20 @@ class MigratingAuthStorage {
|
|
|
3784
3890
|
return candidates[0] ?? null;
|
|
3785
3891
|
if (second && first.timestampMs === second.timestampMs) {
|
|
3786
3892
|
this.warnAmbiguousPlaintext();
|
|
3787
|
-
const selected = candidates.find((candidate) => candidate.source === "file") ??
|
|
3893
|
+
const selected = candidates.find((candidate) => candidate.source === "file") ?? null;
|
|
3894
|
+
if (!selected)
|
|
3895
|
+
return null;
|
|
3788
3896
|
selected.ambiguous = true;
|
|
3789
3897
|
return selected;
|
|
3790
3898
|
}
|
|
3791
3899
|
return first.candidate;
|
|
3792
3900
|
}
|
|
3793
|
-
async clearMigratedPlaintext(baseUrl2, kind, source, ambiguous = false) {
|
|
3901
|
+
async clearMigratedPlaintext(baseUrl2, kind, source, storage, ambiguous = false) {
|
|
3794
3902
|
if (!ambiguous) {
|
|
3795
3903
|
await this.clearPlaintextSource(this.file, baseUrl2, kind);
|
|
3796
|
-
|
|
3904
|
+
for (const legacy of this.getLegacyStores()) {
|
|
3905
|
+
await this.clearPlaintextSource(legacy, baseUrl2, kind);
|
|
3906
|
+
}
|
|
3797
3907
|
return;
|
|
3798
3908
|
}
|
|
3799
3909
|
if (source === "file") {
|
|
@@ -3801,9 +3911,12 @@ class MigratingAuthStorage {
|
|
|
3801
3911
|
return;
|
|
3802
3912
|
}
|
|
3803
3913
|
if (source === "legacy") {
|
|
3804
|
-
await this.clearPlaintextSource(
|
|
3914
|
+
await this.clearPlaintextSource(storage, baseUrl2, kind);
|
|
3805
3915
|
}
|
|
3806
3916
|
}
|
|
3917
|
+
getLegacyStores() {
|
|
3918
|
+
return [...this.additionalLegacyStores, this.legacy];
|
|
3919
|
+
}
|
|
3807
3920
|
async clearPlaintextSource(storage, baseUrl2, kind) {
|
|
3808
3921
|
await this.clearBestEffort(() => kind === "tokens" ? storage.clearTokens(baseUrl2) : storage.clearClient(baseUrl2));
|
|
3809
3922
|
}
|
|
@@ -3815,6 +3928,9 @@ class MigratingAuthStorage {
|
|
|
3815
3928
|
return error;
|
|
3816
3929
|
}
|
|
3817
3930
|
}
|
|
3931
|
+
async saveMetadataBestEffort(baseUrl2, tokens) {
|
|
3932
|
+
await this.clearBestEffort(() => this.metadata?.saveFromTokens(baseUrl2, tokens) ?? Promise.resolve());
|
|
3933
|
+
}
|
|
3818
3934
|
toPolicyError(error) {
|
|
3819
3935
|
if (!(error instanceof KeychainUnavailableError))
|
|
3820
3936
|
return error;
|
|
@@ -5423,7 +5539,7 @@ var NPM_DIST_TAGS_URL = "https://registry.npmjs.org/-/package/githits/dist-tags"
|
|
|
5423
5539
|
var NPM_PACKAGE_VERSION_URL = "https://registry.npmjs.org/githits";
|
|
5424
5540
|
var CHECK_INTERVAL_MS = 24 * 60 * 60 * 1000;
|
|
5425
5541
|
var FETCH_TIMEOUT_MS = 1000;
|
|
5426
|
-
var
|
|
5542
|
+
var DIR_MODE3 = 448;
|
|
5427
5543
|
var UPDATE_COMMAND = "npm i -g githits@latest";
|
|
5428
5544
|
var MAX_DEPRECATION_REASON_LENGTH = 200;
|
|
5429
5545
|
|
|
@@ -5613,7 +5729,7 @@ class NpmRegistryUpdateCheckService {
|
|
|
5613
5729
|
}
|
|
5614
5730
|
async saveCache(cache) {
|
|
5615
5731
|
try {
|
|
5616
|
-
await this.fs.ensureDir(this.configDir,
|
|
5732
|
+
await this.fs.ensureDir(this.configDir, DIR_MODE3);
|
|
5617
5733
|
if (typeof this.fs.atomicWriteFile === "function") {
|
|
5618
5734
|
await this.fs.atomicWriteFile(this.cachePath, `${JSON.stringify(cache, null, 2)}
|
|
5619
5735
|
`);
|
|
@@ -5750,10 +5866,29 @@ async function createAuthStorage(fileSystemService) {
|
|
|
5750
5866
|
function createAuthStorageForMode(fileSystemService, mode, configPath = "your GitHits config.toml") {
|
|
5751
5867
|
const fileStorage = new ModeAwareFileAuthStorage(new AuthStorageImpl(fileSystemService, getAuthFileStorageDir(fileSystemService)), mode, configPath);
|
|
5752
5868
|
const legacyStorage = new AuthStorageImpl(fileSystemService, getLegacyAuthStorageDir(fileSystemService));
|
|
5869
|
+
const additionalLegacyStores = process.platform === "darwin" ? [
|
|
5870
|
+
new AuthStorageImpl(fileSystemService, getLegacyMacAuthFileStorageDir(fileSystemService))
|
|
5871
|
+
] : [];
|
|
5753
5872
|
const rawKeyring = new KeyringServiceImpl;
|
|
5754
5873
|
const keyring = process.platform === "win32" ? new ChunkingKeyringService(rawKeyring, WINDOWS_MAX_ENTRY_SIZE) : rawKeyring;
|
|
5755
5874
|
const keychainStorage = new KeychainAuthStorage(keyring);
|
|
5756
|
-
|
|
5875
|
+
const metadataStorage = new AuthSessionMetadataStorage(fileSystemService);
|
|
5876
|
+
return new LockedAuthStorage(new MigratingAuthStorage(keychainStorage, fileStorage, legacyStorage, mode, configPath, (message) => console.error(message), metadataStorage, additionalLegacyStores), fileSystemService);
|
|
5877
|
+
}
|
|
5878
|
+
async function loadAutoLoginAuthSessionMetadata() {
|
|
5879
|
+
const envToken = getEnvApiToken();
|
|
5880
|
+
if (envToken) {
|
|
5881
|
+
const now = new Date().toISOString();
|
|
5882
|
+
return { createdAt: now, expiresAt: null, updatedAt: now };
|
|
5883
|
+
}
|
|
5884
|
+
const fileSystemService = new FileSystemServiceImpl;
|
|
5885
|
+
const metadataStorage = new AuthSessionMetadataStorage(fileSystemService);
|
|
5886
|
+
return metadataStorage.load(getMcpUrl());
|
|
5887
|
+
}
|
|
5888
|
+
async function clearAutoLoginAuthSessionMetadata() {
|
|
5889
|
+
const fileSystemService = new FileSystemServiceImpl;
|
|
5890
|
+
const metadataStorage = new AuthSessionMetadataStorage(fileSystemService);
|
|
5891
|
+
await metadataStorage.clear(getMcpUrl());
|
|
5757
5892
|
}
|
|
5758
5893
|
async function createAuthCommandDependencies() {
|
|
5759
5894
|
return withTelemetrySpan("container.create-auth-command", async () => {
|
|
@@ -5792,8 +5927,9 @@ function createStaticTokenProvider(token) {
|
|
|
5792
5927
|
}
|
|
5793
5928
|
};
|
|
5794
5929
|
}
|
|
5795
|
-
async function createContainer() {
|
|
5930
|
+
async function createContainer(options = {}) {
|
|
5796
5931
|
return withTelemetrySpan("container.create", async () => {
|
|
5932
|
+
const resolveStoredToken = options.resolveStoredToken ?? true;
|
|
5797
5933
|
const mcpUrl = getMcpUrl();
|
|
5798
5934
|
const apiUrl = getApiUrl();
|
|
5799
5935
|
const codeNavigationUrl = getCodeNavigationUrl();
|
|
@@ -5824,7 +5960,10 @@ async function createContainer() {
|
|
|
5824
5960
|
}
|
|
5825
5961
|
const authStorage = await createAuthStorage(fileSystemService);
|
|
5826
5962
|
const tokenManager = new TokenManager({ authService, authStorage, mcpUrl });
|
|
5827
|
-
const apiToken = await withTelemetrySpan("container.token.get", () => tokenManager.getToken());
|
|
5963
|
+
const apiToken = resolveStoredToken ? await withTelemetrySpan("container.token.get", () => tokenManager.getToken()) : undefined;
|
|
5964
|
+
if (resolveStoredToken && apiToken === undefined) {
|
|
5965
|
+
await new AuthSessionMetadataStorage(fileSystemService).clear(mcpUrl);
|
|
5966
|
+
}
|
|
5828
5967
|
const codeNavigationService = new CodeNavigationServiceImpl(codeNavigationUrl, tokenManager);
|
|
5829
5968
|
const packageIntelligenceService = new PackageIntelligenceServiceImpl(codeNavigationUrl, tokenManager);
|
|
5830
5969
|
return {
|
|
@@ -5845,4 +5984,4 @@ async function createContainer() {
|
|
|
5845
5984
|
});
|
|
5846
5985
|
}
|
|
5847
5986
|
|
|
5848
|
-
export { AuthConfigError, CLIENT_UPDATE_REQUIRED_REASON, ClientUpdateRequiredError, debugLog, setMcpClientVersionProvider, setClientMode, isTelemetryEnabled, withTelemetrySpan, startTelemetrySpan, endTelemetrySpan, flushTelemetry, AuthenticationError, CodeNavigationAccessError, CodeNavigationGraphQLError, CodeNavigationIndexingError, CodeNavigationUnresolvableError, MalformedCodeNavigationResponseError, CodeNavigationTargetNotFoundError, CodeNavigationFileNotFoundError, CodeNavigationVersionNotFoundError, CodeNavigationValidationError, CodeNavigationFeatureFlagRequiredError, CodeNavigationNetworkError, CodeNavigationBackendError, getCodeNavigationUrl, ExecServiceImpl, FileSystemServiceImpl, AuthStorageLockTimeoutError, AuthStoragePolicyError, PackageIntelligenceAccessError, PackageIntelligenceFeatureFlagRequiredError, PackageIntelligenceNetworkError, PackageIntelligenceBackendError, PackageIntelligenceGraphQLError, PackageIntelligenceTargetNotFoundError, PackageIntelligenceValidationError, PackageIntelligenceVersionNotFoundError, MalformedPackageIntelligenceResponseError, PackageIntelligenceChangelogSourceNotFoundError, PromptServiceImpl, refreshExpiredToken, NpmRegistryUpdateCheckService, shouldRunUpdateCheck, shouldRunRequiredUpdateEnforcement, formatUpdateNotice, formatRequiredUpdateNotice, createAuthCommandDependencies, createAuthStatusDependencies, createContainer };
|
|
5987
|
+
export { AuthConfigError, CLIENT_UPDATE_REQUIRED_REASON, ClientUpdateRequiredError, debugLog, setMcpClientVersionProvider, setClientMode, isTelemetryEnabled, withTelemetrySpan, startTelemetrySpan, endTelemetrySpan, flushTelemetry, AuthenticationError, CodeNavigationAccessError, CodeNavigationGraphQLError, CodeNavigationIndexingError, CodeNavigationUnresolvableError, MalformedCodeNavigationResponseError, CodeNavigationTargetNotFoundError, CodeNavigationFileNotFoundError, CodeNavigationVersionNotFoundError, CodeNavigationValidationError, CodeNavigationFeatureFlagRequiredError, CodeNavigationNetworkError, CodeNavigationBackendError, getCodeNavigationUrl, ExecServiceImpl, FileSystemServiceImpl, AuthStorageLockTimeoutError, AuthStoragePolicyError, PackageIntelligenceAccessError, PackageIntelligenceFeatureFlagRequiredError, PackageIntelligenceNetworkError, PackageIntelligenceBackendError, PackageIntelligenceGraphQLError, PackageIntelligenceTargetNotFoundError, PackageIntelligenceValidationError, PackageIntelligenceVersionNotFoundError, MalformedPackageIntelligenceResponseError, PackageIntelligenceChangelogSourceNotFoundError, PromptServiceImpl, refreshExpiredToken, NpmRegistryUpdateCheckService, shouldRunUpdateCheck, shouldRunRequiredUpdateEnforcement, formatUpdateNotice, formatRequiredUpdateNotice, loadAutoLoginAuthSessionMetadata, clearAutoLoginAuthSessionMetadata, createAuthCommandDependencies, createAuthStatusDependencies, createContainer };
|
package/gemini-extension.json
CHANGED
package/package.json
CHANGED