githits 0.4.2 → 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/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  version
3
- } from "./shared/chunk-jdygt0ra.js";
3
+ } from "./shared/chunk-96tjsv6y.js";
4
4
  export {
5
5
  version
6
6
  };
@@ -1,6 +1,6 @@
1
1
  import { createRequire } from "node:module";
2
2
  var __require = /* @__PURE__ */ createRequire(import.meta.url);
3
3
  // package.json
4
- var version = "0.4.2";
4
+ var version = "0.4.4";
5
5
 
6
6
  export { __require, version };
@@ -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-jdygt0ra.js";
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
- switch (process.platform) {
11
- case "win32":
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
- const configPath = getAuthConfigPath(fs);
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
- return { storage: "keychain", configPath };
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
 
@@ -1326,7 +1400,9 @@ class GitHitsServiceImpl {
1326
1400
  method: "POST",
1327
1401
  headers: this.headers(),
1328
1402
  body: JSON.stringify({
1329
- solution_id: params.solutionId,
1403
+ ...params.solutionId !== undefined && {
1404
+ solution_id: params.solutionId
1405
+ },
1330
1406
  accepted: params.accepted,
1331
1407
  feedback_text: params.feedbackText ?? null
1332
1408
  })
@@ -3531,15 +3607,19 @@ class MigratingAuthStorage {
3531
3607
  mode;
3532
3608
  configPath;
3533
3609
  onWarning;
3610
+ metadata;
3611
+ additionalLegacyStores;
3534
3612
  warnedFileModeKeychainExport = false;
3535
3613
  warnedAmbiguousPlaintext = false;
3536
- 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 = []) {
3537
3615
  this.primary = primary;
3538
3616
  this.file = file;
3539
3617
  this.legacy = legacy;
3540
3618
  this.mode = mode;
3541
3619
  this.configPath = configPath;
3542
3620
  this.onWarning = onWarning;
3621
+ this.metadata = metadata;
3622
+ this.additionalLegacyStores = additionalLegacyStores;
3543
3623
  }
3544
3624
  async loadTokens(baseUrl2) {
3545
3625
  if (this.mode === "file") {
@@ -3550,10 +3630,12 @@ class MigratingAuthStorage {
3550
3630
  async saveTokens(baseUrl2, data) {
3551
3631
  if (this.mode === "file") {
3552
3632
  await this.file.saveTokens(baseUrl2, data);
3633
+ await this.saveMetadataBestEffort(baseUrl2, data);
3553
3634
  return;
3554
3635
  }
3555
3636
  try {
3556
3637
  await this.primary.saveTokens(baseUrl2, data);
3638
+ await this.saveMetadataBestEffort(baseUrl2, data);
3557
3639
  } catch (error) {
3558
3640
  throw this.toPolicyError(error);
3559
3641
  }
@@ -3569,6 +3651,10 @@ class MigratingAuthStorage {
3569
3651
  const primaryError = await this.clearBestEffort(() => this.primary.clearTokens(baseUrl2));
3570
3652
  await this.clearBestEffort(() => this.file.clearTokens(baseUrl2));
3571
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());
3572
3658
  if (primaryError && !(primaryError instanceof KeychainUnavailableError)) {
3573
3659
  throw primaryError;
3574
3660
  }
@@ -3601,6 +3687,9 @@ class MigratingAuthStorage {
3601
3687
  const primaryError = await this.clearBestEffort(() => this.primary.clearClient(baseUrl2));
3602
3688
  await this.clearBestEffort(() => this.file.clearClient(baseUrl2));
3603
3689
  await this.clearBestEffort(() => this.legacy.clearClient(baseUrl2));
3690
+ for (const legacy of this.additionalLegacyStores) {
3691
+ await this.clearBestEffort(() => legacy.clearClient(baseUrl2));
3692
+ }
3604
3693
  if (primaryError && !(primaryError instanceof KeychainUnavailableError)) {
3605
3694
  throw primaryError;
3606
3695
  }
@@ -3608,10 +3697,12 @@ class MigratingAuthStorage {
3608
3697
  async saveAuthSession(baseUrl2, client, tokens) {
3609
3698
  if (this.mode === "file") {
3610
3699
  await this.file.saveAuthSession(baseUrl2, client, tokens);
3700
+ await this.saveMetadataBestEffort(baseUrl2, tokens);
3611
3701
  return;
3612
3702
  }
3613
3703
  try {
3614
3704
  await this.primary.saveAuthSession(baseUrl2, client, tokens);
3705
+ await this.saveMetadataBestEffort(baseUrl2, tokens);
3615
3706
  } catch (error) {
3616
3707
  throw this.toPolicyError(error);
3617
3708
  }
@@ -3620,6 +3711,10 @@ class MigratingAuthStorage {
3620
3711
  const primaryError = await this.clearBestEffort(() => this.primary.clearAuthSession(baseUrl2));
3621
3712
  await this.clearBestEffort(() => this.file.clearAuthSession(baseUrl2));
3622
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());
3623
3718
  if (primaryError && !(primaryError instanceof KeychainUnavailableError)) {
3624
3719
  throw primaryError;
3625
3720
  }
@@ -3630,8 +3725,10 @@ class MigratingAuthStorage {
3630
3725
  async loadTokensKeychainMode(baseUrl2) {
3631
3726
  try {
3632
3727
  const primaryTokens = await this.primary.loadTokens(baseUrl2);
3633
- if (primaryTokens)
3728
+ if (primaryTokens) {
3729
+ await this.saveMetadataBestEffort(baseUrl2, primaryTokens);
3634
3730
  return primaryTokens;
3731
+ }
3635
3732
  } catch (error) {
3636
3733
  if (!(error instanceof KeychainUnavailableError))
3637
3734
  throw error;
@@ -3646,7 +3743,8 @@ class MigratingAuthStorage {
3646
3743
  return candidate.data;
3647
3744
  throw error;
3648
3745
  }
3649
- 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);
3650
3748
  return candidate.data;
3651
3749
  }
3652
3750
  async loadTokensFileMode(baseUrl2) {
@@ -3654,8 +3752,9 @@ class MigratingAuthStorage {
3654
3752
  if (candidate) {
3655
3753
  if (candidate.source === "legacy") {
3656
3754
  await this.file.saveTokens(baseUrl2, candidate.data);
3657
- await this.clearBestEffort(() => this.legacy.clearTokens(baseUrl2));
3755
+ await this.clearBestEffort(() => candidate.storage.clearTokens(baseUrl2));
3658
3756
  }
3757
+ await this.saveMetadataBestEffort(baseUrl2, candidate.data);
3659
3758
  return candidate.data;
3660
3759
  }
3661
3760
  let primaryTokens = null;
@@ -3669,6 +3768,7 @@ class MigratingAuthStorage {
3669
3768
  return null;
3670
3769
  this.warnKeychainExport();
3671
3770
  await this.file.saveTokens(baseUrl2, primaryTokens);
3771
+ await this.saveMetadataBestEffort(baseUrl2, primaryTokens);
3672
3772
  return primaryTokens;
3673
3773
  }
3674
3774
  async loadClientKeychainMode(baseUrl2) {
@@ -3690,7 +3790,7 @@ class MigratingAuthStorage {
3690
3790
  return candidate.data;
3691
3791
  throw error;
3692
3792
  }
3693
- await this.clearMigratedPlaintext(baseUrl2, "client", candidate.source, candidate.ambiguous);
3793
+ await this.clearMigratedPlaintext(baseUrl2, "client", candidate.source, candidate.storage, candidate.ambiguous);
3694
3794
  return candidate.data;
3695
3795
  }
3696
3796
  async loadClientFileMode(baseUrl2) {
@@ -3698,7 +3798,7 @@ class MigratingAuthStorage {
3698
3798
  if (candidate) {
3699
3799
  if (candidate.source === "legacy") {
3700
3800
  await this.file.saveClient(baseUrl2, candidate.data);
3701
- await this.clearBestEffort(() => this.legacy.clearClient(baseUrl2));
3801
+ await this.clearBestEffort(() => candidate.storage.clearClient(baseUrl2));
3702
3802
  }
3703
3803
  return candidate.data;
3704
3804
  }
@@ -3722,18 +3822,22 @@ class MigratingAuthStorage {
3722
3822
  candidates.push({
3723
3823
  data: fileTokens,
3724
3824
  source: "file",
3825
+ storage: this.file,
3725
3826
  timestamp: fileTokens.createdAt,
3726
3827
  ambiguous: false
3727
3828
  });
3728
3829
  }
3729
- const legacyTokens = await this.legacy.loadTokens(baseUrl2);
3730
- if (legacyTokens) {
3731
- candidates.push({
3732
- data: legacyTokens,
3733
- source: "legacy",
3734
- timestamp: legacyTokens.createdAt,
3735
- ambiguous: false
3736
- });
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
+ }
3737
3841
  }
3738
3842
  return this.selectNewestCandidate(candidates);
3739
3843
  }
@@ -3744,18 +3848,22 @@ class MigratingAuthStorage {
3744
3848
  candidates.push({
3745
3849
  data: fileClient,
3746
3850
  source: "file",
3851
+ storage: this.file,
3747
3852
  timestamp: fileClient.registeredAt,
3748
3853
  ambiguous: false
3749
3854
  });
3750
3855
  }
3751
- const legacyClient = await this.legacy.loadClient(baseUrl2);
3752
- if (legacyClient) {
3753
- candidates.push({
3754
- data: legacyClient,
3755
- source: "legacy",
3756
- timestamp: legacyClient.registeredAt,
3757
- ambiguous: false
3758
- });
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
+ }
3759
3867
  }
3760
3868
  return this.selectNewestCandidate(candidates);
3761
3869
  }
@@ -3770,7 +3878,7 @@ class MigratingAuthStorage {
3770
3878
  }));
3771
3879
  if (parsed.some((entry) => Number.isNaN(entry.timestampMs))) {
3772
3880
  this.warnAmbiguousPlaintext();
3773
- const selected = candidates.find((candidate) => candidate.source === "file") ?? candidates[0] ?? null;
3881
+ const selected = candidates.find((candidate) => candidate.source === "file") ?? null;
3774
3882
  if (selected)
3775
3883
  selected.ambiguous = true;
3776
3884
  return selected;
@@ -3782,16 +3890,20 @@ class MigratingAuthStorage {
3782
3890
  return candidates[0] ?? null;
3783
3891
  if (second && first.timestampMs === second.timestampMs) {
3784
3892
  this.warnAmbiguousPlaintext();
3785
- const selected = candidates.find((candidate) => candidate.source === "file") ?? first.candidate;
3893
+ const selected = candidates.find((candidate) => candidate.source === "file") ?? null;
3894
+ if (!selected)
3895
+ return null;
3786
3896
  selected.ambiguous = true;
3787
3897
  return selected;
3788
3898
  }
3789
3899
  return first.candidate;
3790
3900
  }
3791
- async clearMigratedPlaintext(baseUrl2, kind, source, ambiguous = false) {
3901
+ async clearMigratedPlaintext(baseUrl2, kind, source, storage, ambiguous = false) {
3792
3902
  if (!ambiguous) {
3793
3903
  await this.clearPlaintextSource(this.file, baseUrl2, kind);
3794
- await this.clearPlaintextSource(this.legacy, baseUrl2, kind);
3904
+ for (const legacy of this.getLegacyStores()) {
3905
+ await this.clearPlaintextSource(legacy, baseUrl2, kind);
3906
+ }
3795
3907
  return;
3796
3908
  }
3797
3909
  if (source === "file") {
@@ -3799,9 +3911,12 @@ class MigratingAuthStorage {
3799
3911
  return;
3800
3912
  }
3801
3913
  if (source === "legacy") {
3802
- await this.clearPlaintextSource(this.legacy, baseUrl2, kind);
3914
+ await this.clearPlaintextSource(storage, baseUrl2, kind);
3803
3915
  }
3804
3916
  }
3917
+ getLegacyStores() {
3918
+ return [...this.additionalLegacyStores, this.legacy];
3919
+ }
3805
3920
  async clearPlaintextSource(storage, baseUrl2, kind) {
3806
3921
  await this.clearBestEffort(() => kind === "tokens" ? storage.clearTokens(baseUrl2) : storage.clearClient(baseUrl2));
3807
3922
  }
@@ -3813,6 +3928,9 @@ class MigratingAuthStorage {
3813
3928
  return error;
3814
3929
  }
3815
3930
  }
3931
+ async saveMetadataBestEffort(baseUrl2, tokens) {
3932
+ await this.clearBestEffort(() => this.metadata?.saveFromTokens(baseUrl2, tokens) ?? Promise.resolve());
3933
+ }
3816
3934
  toPolicyError(error) {
3817
3935
  if (!(error instanceof KeychainUnavailableError))
3818
3936
  return error;
@@ -3985,10 +4103,6 @@ var packageSecurityOverviewSchema = z3.object({
3985
4103
  hasCurrentVulnerabilities: z3.boolean().nullable().optional(),
3986
4104
  recentVulnerabilities: z3.array(vulnerabilityOverviewSchema).nullable().optional()
3987
4105
  }).nullable().optional();
3988
- var quickstartInfoSchema = z3.object({
3989
- installCommand: z3.string().nullable().optional(),
3990
- usageExample: z3.string().nullable().optional()
3991
- }).nullable().optional();
3992
4106
  var changelogEntrySchema = z3.object({
3993
4107
  version: z3.string().nullable().optional(),
3994
4108
  publishedAt: z3.string().nullable().optional(),
@@ -3997,7 +4111,6 @@ var changelogEntrySchema = z3.object({
3997
4111
  var packageSummaryResponseSchema = z3.object({
3998
4112
  package: packageIdentitySchema.nullable().optional(),
3999
4113
  security: packageSecurityOverviewSchema,
4000
- quickstart: quickstartInfoSchema,
4001
4114
  latestChangelogs: z3.array(changelogEntrySchema).nullable().optional()
4002
4115
  });
4003
4116
  var graphQLErrorSchema2 = z3.object({
@@ -4044,10 +4157,6 @@ query PackageSummary($registry: Registry!, $name: String!) {
4044
4157
  publishedAt
4045
4158
  }
4046
4159
  }
4047
- quickstart {
4048
- installCommand
4049
- usageExample
4050
- }
4051
4160
  latestChangelogs(limit: 3) {
4052
4161
  version
4053
4162
  publishedAt
@@ -4112,6 +4221,7 @@ query PackageVulnerabilities(
4112
4221
  $version: String
4113
4222
  $minSeverity: Float
4114
4223
  $includeWithdrawn: Boolean
4224
+ $scope: VulnerabilityScope = AFFECTED
4115
4225
  $after: String
4116
4226
  ) {
4117
4227
  packageVulnerabilities(
@@ -4132,7 +4242,7 @@ query PackageVulnerabilities(
4132
4242
  allVulnerabilityCount
4133
4243
  currentVersionAffected
4134
4244
  upgradePaths
4135
- advisories(scope: AFFECTED, first: 100, after: $after) {
4245
+ advisories(scope: $scope, first: 100, after: $after) {
4136
4246
  entries {
4137
4247
  osvId
4138
4248
  summary
@@ -4687,10 +4797,6 @@ class PackageIntelligenceServiceImpl {
4687
4797
  publishedAt: vuln.publishedAt ?? undefined
4688
4798
  })) ?? undefined
4689
4799
  } : undefined;
4690
- const quickstart = data.quickstart ? {
4691
- installCommand: data.quickstart.installCommand ?? undefined,
4692
- usageExample: data.quickstart.usageExample ?? undefined
4693
- } : undefined;
4694
4800
  const latestChangelogs = data.latestChangelogs?.map((entry) => ({
4695
4801
  version: entry.version ?? undefined,
4696
4802
  publishedAt: entry.publishedAt ?? undefined,
@@ -4699,7 +4805,6 @@ class PackageIntelligenceServiceImpl {
4699
4805
  return {
4700
4806
  package: identity,
4701
4807
  security,
4702
- quickstart,
4703
4808
  latestChangelogs
4704
4809
  };
4705
4810
  }
@@ -4774,6 +4879,7 @@ class PackageIntelligenceServiceImpl {
4774
4879
  version: params.version,
4775
4880
  minSeverity: params.minSeverity,
4776
4881
  includeWithdrawn: params.includeWithdrawn,
4882
+ scope: params.advisoryScope,
4777
4883
  after
4778
4884
  },
4779
4885
  fetchFn: this.fetchFn
@@ -5433,7 +5539,7 @@ var NPM_DIST_TAGS_URL = "https://registry.npmjs.org/-/package/githits/dist-tags"
5433
5539
  var NPM_PACKAGE_VERSION_URL = "https://registry.npmjs.org/githits";
5434
5540
  var CHECK_INTERVAL_MS = 24 * 60 * 60 * 1000;
5435
5541
  var FETCH_TIMEOUT_MS = 1000;
5436
- var DIR_MODE2 = 448;
5542
+ var DIR_MODE3 = 448;
5437
5543
  var UPDATE_COMMAND = "npm i -g githits@latest";
5438
5544
  var MAX_DEPRECATION_REASON_LENGTH = 200;
5439
5545
 
@@ -5623,7 +5729,7 @@ class NpmRegistryUpdateCheckService {
5623
5729
  }
5624
5730
  async saveCache(cache) {
5625
5731
  try {
5626
- await this.fs.ensureDir(this.configDir, DIR_MODE2);
5732
+ await this.fs.ensureDir(this.configDir, DIR_MODE3);
5627
5733
  if (typeof this.fs.atomicWriteFile === "function") {
5628
5734
  await this.fs.atomicWriteFile(this.cachePath, `${JSON.stringify(cache, null, 2)}
5629
5735
  `);
@@ -5760,10 +5866,29 @@ async function createAuthStorage(fileSystemService) {
5760
5866
  function createAuthStorageForMode(fileSystemService, mode, configPath = "your GitHits config.toml") {
5761
5867
  const fileStorage = new ModeAwareFileAuthStorage(new AuthStorageImpl(fileSystemService, getAuthFileStorageDir(fileSystemService)), mode, configPath);
5762
5868
  const legacyStorage = new AuthStorageImpl(fileSystemService, getLegacyAuthStorageDir(fileSystemService));
5869
+ const additionalLegacyStores = process.platform === "darwin" ? [
5870
+ new AuthStorageImpl(fileSystemService, getLegacyMacAuthFileStorageDir(fileSystemService))
5871
+ ] : [];
5763
5872
  const rawKeyring = new KeyringServiceImpl;
5764
5873
  const keyring = process.platform === "win32" ? new ChunkingKeyringService(rawKeyring, WINDOWS_MAX_ENTRY_SIZE) : rawKeyring;
5765
5874
  const keychainStorage = new KeychainAuthStorage(keyring);
5766
- return new LockedAuthStorage(new MigratingAuthStorage(keychainStorage, fileStorage, legacyStorage, mode, configPath, (message) => console.error(message)), fileSystemService);
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());
5767
5892
  }
5768
5893
  async function createAuthCommandDependencies() {
5769
5894
  return withTelemetrySpan("container.create-auth-command", async () => {
@@ -5802,8 +5927,9 @@ function createStaticTokenProvider(token) {
5802
5927
  }
5803
5928
  };
5804
5929
  }
5805
- async function createContainer() {
5930
+ async function createContainer(options = {}) {
5806
5931
  return withTelemetrySpan("container.create", async () => {
5932
+ const resolveStoredToken = options.resolveStoredToken ?? true;
5807
5933
  const mcpUrl = getMcpUrl();
5808
5934
  const apiUrl = getApiUrl();
5809
5935
  const codeNavigationUrl = getCodeNavigationUrl();
@@ -5834,7 +5960,10 @@ async function createContainer() {
5834
5960
  }
5835
5961
  const authStorage = await createAuthStorage(fileSystemService);
5836
5962
  const tokenManager = new TokenManager({ authService, authStorage, mcpUrl });
5837
- 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
+ }
5838
5967
  const codeNavigationService = new CodeNavigationServiceImpl(codeNavigationUrl, tokenManager);
5839
5968
  const packageIntelligenceService = new PackageIntelligenceServiceImpl(codeNavigationUrl, tokenManager);
5840
5969
  return {
@@ -5855,4 +5984,4 @@ async function createContainer() {
5855
5984
  });
5856
5985
  }
5857
5986
 
5858
- 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 };
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "githits",
3
- "version": "0.4.2",
3
+ "version": "0.4.4",
4
4
  "description": "Code examples from global open source for developers and AI assistants.",
5
5
  "mcpServers": {
6
6
  "githits": {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "githits",
3
3
  "description": "CLI companion for GitHits - code examples from global open source for developers and AI assistants",
4
- "version": "0.4.2",
4
+ "version": "0.4.4",
5
5
  "type": "module",
6
6
  "files": [
7
7
  "dist",
@@ -35,6 +35,9 @@
35
35
  "inspector": "npx @modelcontextprotocol/inspector bun run dev mcp",
36
36
  "smoke:cli": "bun run scripts/cli-smoke.ts",
37
37
  "smoke:mcp": "bun run scripts/mcp-smoke.ts",
38
+ "audit:pkg-ecosystems": "bun run scripts/pkg-ecosystem-audit.ts",
39
+ "agent:e2e": "bun run scripts/agent-eval.ts",
40
+ "agent:e2e:report": "bun run scripts/agent-eval-report.ts",
38
41
  "test": "bun test",
39
42
  "typecheck": "tsc",
40
43
  "format": "biome format --write .",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "githits",
3
- "version": "0.4.2",
3
+ "version": "0.4.4",
4
4
  "description": "Code examples from global open source for developers and AI assistants",
5
5
  "author": {
6
6
  "name": "GitHits"
@@ -1,11 +0,0 @@
1
- import {
2
- createAuthCommandDependencies,
3
- createAuthStatusDependencies,
4
- createContainer
5
- } from "./chunk-v8sths32.js";
6
- import"./chunk-jdygt0ra.js";
7
- export {
8
- createContainer,
9
- createAuthStatusDependencies,
10
- createAuthCommandDependencies
11
- };