@mushi-mushi/cli 0.27.0 → 0.28.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 +6 -1
- package/dist/{chunk-TZL3F3GT.js → chunk-AV3RKAEE.js} +77 -47
- package/dist/{chunk-7JZUKNN5.js → chunk-FJETUM25.js} +156 -497
- package/dist/chunk-KOBEOGNF.js +475 -0
- package/dist/chunk-SXSI2W6Z.js +42 -0
- package/dist/chunk-U2VGB63C.js +8 -0
- package/dist/chunk-UVO4A2G6.js +10 -0
- package/dist/connect-63GYZLFM.js +13 -0
- package/dist/{connect-FAXWVFG2.js → connect-C673EKS3.js} +74 -42
- package/dist/detect-4PYRZXVK.js +22 -0
- package/dist/endpoint-NHECZL47.js +15 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1284 -814
- package/dist/init.d.ts +179 -1
- package/dist/init.js +468 -225
- package/dist/{version-F3ZOPM5F.js → version-VR37VEE4.js} +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/wizard-args.d.ts +2 -2
- package/dist/wizard-args.js +5 -3
- package/package.json +10 -15
- package/CODE_OF_CONDUCT.md +0 -51
- package/CONTRIBUTING.md +0 -226
- package/SECURITY.md +0 -359
- package/dist/chunk-LFZ5ZIBI.js +0 -8
- package/dist/chunk-MXD5UNMP.js +0 -10
- package/dist/connect-QHVFH77E.js +0 -10
|
@@ -2,7 +2,12 @@
|
|
|
2
2
|
import {
|
|
3
3
|
MUSHI_CLI_VERSION,
|
|
4
4
|
MUSHI_MCP_PIN_SPEC
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-UVO4A2G6.js";
|
|
6
|
+
import {
|
|
7
|
+
detectFramework,
|
|
8
|
+
envVarsToWrite,
|
|
9
|
+
readPackageJson
|
|
10
|
+
} from "./chunk-KOBEOGNF.js";
|
|
6
11
|
import {
|
|
7
12
|
CLOUD_API_ENDPOINT,
|
|
8
13
|
assertEndpoint,
|
|
@@ -14,7 +19,7 @@ import {
|
|
|
14
19
|
|
|
15
20
|
// src/connect.ts
|
|
16
21
|
import { appendFile, readFile as readFile2, writeFile as writeFile2 } from "fs/promises";
|
|
17
|
-
import { join as
|
|
22
|
+
import { join as join3, resolve } from "path";
|
|
18
23
|
|
|
19
24
|
// src/config.ts
|
|
20
25
|
import { randomUUID } from "crypto";
|
|
@@ -69,6 +74,11 @@ var DEFAULT_PROFILE = "default";
|
|
|
69
74
|
function isMultiProfileFile(value) {
|
|
70
75
|
return typeof value === "object" && value !== null && "profiles" in value && typeof value.profiles === "object" && value.profiles !== null;
|
|
71
76
|
}
|
|
77
|
+
function savedSdkKeyFor(config, projectId) {
|
|
78
|
+
const saved = config.sdkKey;
|
|
79
|
+
if (!projectId || !saved || typeof saved !== "object") return void 0;
|
|
80
|
+
return saved.projectId === projectId && typeof saved.key === "string" && saved.key ? saved.key : void 0;
|
|
81
|
+
}
|
|
72
82
|
function resolveProfileName(explicit, fileActive) {
|
|
73
83
|
const fromEnv = process.env["MUSHI_PROFILE"]?.trim();
|
|
74
84
|
return explicit?.trim() || fromEnv || fileActive || DEFAULT_PROFILE;
|
|
@@ -670,446 +680,6 @@ function pad(s, width) {
|
|
|
670
680
|
return s.length >= width ? s : s + " ".repeat(width - s.length);
|
|
671
681
|
}
|
|
672
682
|
|
|
673
|
-
// src/detect.ts
|
|
674
|
-
import { readFileSync as readFileSync3, existsSync as existsSync3 } from "fs";
|
|
675
|
-
import { join as join3 } from "path";
|
|
676
|
-
var FRAMEWORKS = {
|
|
677
|
-
next: {
|
|
678
|
-
id: "next",
|
|
679
|
-
label: "Next.js",
|
|
680
|
-
packageName: "@mushi-mushi/react",
|
|
681
|
-
needsWebPackage: false,
|
|
682
|
-
snippet: () => `// app/providers.tsx (or pages/_app.tsx for /pages router)
|
|
683
|
-
'use client'
|
|
684
|
-
import { MushiProvider } from '@mushi-mushi/react'
|
|
685
|
-
|
|
686
|
-
export function Providers({ children }: { children: React.ReactNode }) {
|
|
687
|
-
return (
|
|
688
|
-
<MushiProvider config={{
|
|
689
|
-
projectId: process.env.NEXT_PUBLIC_MUSHI_PROJECT_ID!,
|
|
690
|
-
apiKey: process.env.NEXT_PUBLIC_MUSHI_API_KEY!,
|
|
691
|
-
}}>
|
|
692
|
-
{children}
|
|
693
|
-
</MushiProvider>
|
|
694
|
-
)
|
|
695
|
-
}`
|
|
696
|
-
},
|
|
697
|
-
react: {
|
|
698
|
-
id: "react",
|
|
699
|
-
label: "React",
|
|
700
|
-
packageName: "@mushi-mushi/react",
|
|
701
|
-
needsWebPackage: false,
|
|
702
|
-
snippet: () => `// src/main.tsx
|
|
703
|
-
import { MushiProvider } from '@mushi-mushi/react'
|
|
704
|
-
|
|
705
|
-
createRoot(document.getElementById('root')!).render(
|
|
706
|
-
<MushiProvider config={{
|
|
707
|
-
projectId: import.meta.env.VITE_MUSHI_PROJECT_ID,
|
|
708
|
-
apiKey: import.meta.env.VITE_MUSHI_API_KEY,
|
|
709
|
-
}}>
|
|
710
|
-
<App />
|
|
711
|
-
</MushiProvider>
|
|
712
|
-
)`
|
|
713
|
-
},
|
|
714
|
-
cra: {
|
|
715
|
-
id: "cra",
|
|
716
|
-
label: "Create React App",
|
|
717
|
-
packageName: "@mushi-mushi/react",
|
|
718
|
-
needsWebPackage: false,
|
|
719
|
-
// CRA inlines only REACT_APP_*-prefixed vars into process.env at build time.
|
|
720
|
-
snippet: () => `// src/index.tsx
|
|
721
|
-
import { MushiProvider } from '@mushi-mushi/react'
|
|
722
|
-
|
|
723
|
-
root.render(
|
|
724
|
-
<MushiProvider config={{
|
|
725
|
-
projectId: process.env.REACT_APP_MUSHI_PROJECT_ID,
|
|
726
|
-
apiKey: process.env.REACT_APP_MUSHI_API_KEY,
|
|
727
|
-
}}>
|
|
728
|
-
<App />
|
|
729
|
-
</MushiProvider>
|
|
730
|
-
)`
|
|
731
|
-
},
|
|
732
|
-
remix: {
|
|
733
|
-
id: "remix",
|
|
734
|
-
label: "Remix",
|
|
735
|
-
packageName: "@mushi-mushi/react",
|
|
736
|
-
needsWebPackage: false,
|
|
737
|
-
// Remix doesn't inline client env. Expose public values at runtime via the
|
|
738
|
-
// root loader + window.ENV (works on both the classic compiler and Vite).
|
|
739
|
-
snippet: () => `// app/root.tsx
|
|
740
|
-
import { MushiProvider } from '@mushi-mushi/react'
|
|
741
|
-
import { useLoaderData } from '@remix-run/react'
|
|
742
|
-
|
|
743
|
-
export async function loader() {
|
|
744
|
-
return { ENV: {
|
|
745
|
-
MUSHI_PROJECT_ID: process.env.MUSHI_PROJECT_ID,
|
|
746
|
-
MUSHI_API_KEY: process.env.MUSHI_API_KEY,
|
|
747
|
-
} }
|
|
748
|
-
}
|
|
749
|
-
|
|
750
|
-
export default function App() {
|
|
751
|
-
const { ENV } = useLoaderData<typeof loader>()
|
|
752
|
-
return (
|
|
753
|
-
<html>
|
|
754
|
-
<body>
|
|
755
|
-
<MushiProvider config={{ projectId: ENV.MUSHI_PROJECT_ID, apiKey: ENV.MUSHI_API_KEY }}>
|
|
756
|
-
<Outlet />
|
|
757
|
-
</MushiProvider>
|
|
758
|
-
<Scripts />
|
|
759
|
-
</body>
|
|
760
|
-
</html>
|
|
761
|
-
)
|
|
762
|
-
}`
|
|
763
|
-
},
|
|
764
|
-
astro: {
|
|
765
|
-
id: "astro",
|
|
766
|
-
label: "Astro",
|
|
767
|
-
packageName: "@mushi-mushi/web",
|
|
768
|
-
needsWebPackage: false,
|
|
769
|
-
// Astro exposes only PUBLIC_*-prefixed vars to client code (Vite-based).
|
|
770
|
-
snippet: () => `---
|
|
771
|
-
// src/layouts/Layout.astro (add this <script> once, e.g. in your base layout)
|
|
772
|
-
---
|
|
773
|
-
<script>
|
|
774
|
-
import { Mushi } from '@mushi-mushi/web'
|
|
775
|
-
Mushi.init({
|
|
776
|
-
projectId: import.meta.env.PUBLIC_MUSHI_PROJECT_ID,
|
|
777
|
-
apiKey: import.meta.env.PUBLIC_MUSHI_API_KEY,
|
|
778
|
-
})
|
|
779
|
-
</script>`
|
|
780
|
-
},
|
|
781
|
-
solid: {
|
|
782
|
-
id: "solid",
|
|
783
|
-
label: "Solid",
|
|
784
|
-
packageName: "@mushi-mushi/web",
|
|
785
|
-
needsWebPackage: false,
|
|
786
|
-
// Solid / SolidStart are Vite-based → VITE_*-prefixed client env.
|
|
787
|
-
snippet: () => `// src/index.tsx (or src/app.tsx for SolidStart)
|
|
788
|
-
import { onMount } from 'solid-js'
|
|
789
|
-
import { Mushi } from '@mushi-mushi/web'
|
|
790
|
-
|
|
791
|
-
onMount(() => {
|
|
792
|
-
Mushi.init({
|
|
793
|
-
projectId: import.meta.env.VITE_MUSHI_PROJECT_ID,
|
|
794
|
-
apiKey: import.meta.env.VITE_MUSHI_API_KEY,
|
|
795
|
-
})
|
|
796
|
-
})`
|
|
797
|
-
},
|
|
798
|
-
vue: {
|
|
799
|
-
id: "vue",
|
|
800
|
-
label: "Vue 3",
|
|
801
|
-
packageName: "@mushi-mushi/vue",
|
|
802
|
-
needsWebPackage: false,
|
|
803
|
-
snippet: () => `// src/main.ts
|
|
804
|
-
import { MushiPlugin } from '@mushi-mushi/vue'
|
|
805
|
-
|
|
806
|
-
app.use(MushiPlugin, {
|
|
807
|
-
projectId: import.meta.env.VITE_MUSHI_PROJECT_ID,
|
|
808
|
-
apiKey: import.meta.env.VITE_MUSHI_API_KEY,
|
|
809
|
-
})`
|
|
810
|
-
},
|
|
811
|
-
nuxt: {
|
|
812
|
-
id: "nuxt",
|
|
813
|
-
label: "Nuxt",
|
|
814
|
-
packageName: "@mushi-mushi/vue",
|
|
815
|
-
needsWebPackage: false,
|
|
816
|
-
snippet: () => `// plugins/mushi.client.ts
|
|
817
|
-
import { MushiPlugin } from '@mushi-mushi/vue'
|
|
818
|
-
|
|
819
|
-
export default defineNuxtPlugin((nuxtApp) => {
|
|
820
|
-
nuxtApp.vueApp.use(MushiPlugin, {
|
|
821
|
-
projectId: import.meta.env.NUXT_PUBLIC_MUSHI_PROJECT_ID,
|
|
822
|
-
apiKey: import.meta.env.NUXT_PUBLIC_MUSHI_API_KEY,
|
|
823
|
-
})
|
|
824
|
-
})`
|
|
825
|
-
},
|
|
826
|
-
svelte: {
|
|
827
|
-
id: "svelte",
|
|
828
|
-
label: "Svelte",
|
|
829
|
-
packageName: "@mushi-mushi/svelte",
|
|
830
|
-
needsWebPackage: false,
|
|
831
|
-
snippet: () => `// src/main.ts
|
|
832
|
-
import { initMushi } from '@mushi-mushi/svelte'
|
|
833
|
-
|
|
834
|
-
initMushi({
|
|
835
|
-
projectId: import.meta.env.VITE_MUSHI_PROJECT_ID,
|
|
836
|
-
apiKey: import.meta.env.VITE_MUSHI_API_KEY,
|
|
837
|
-
})`
|
|
838
|
-
},
|
|
839
|
-
sveltekit: {
|
|
840
|
-
id: "sveltekit",
|
|
841
|
-
label: "SvelteKit",
|
|
842
|
-
packageName: "@mushi-mushi/svelte",
|
|
843
|
-
needsWebPackage: false,
|
|
844
|
-
snippet: () => `// src/routes/+layout.svelte
|
|
845
|
-
<script>
|
|
846
|
-
import { onMount } from 'svelte'
|
|
847
|
-
|
|
848
|
-
onMount(async () => {
|
|
849
|
-
const { initMushi } = await import('@mushi-mushi/svelte')
|
|
850
|
-
initMushi({
|
|
851
|
-
projectId: import.meta.env.VITE_MUSHI_PROJECT_ID,
|
|
852
|
-
apiKey: import.meta.env.VITE_MUSHI_API_KEY,
|
|
853
|
-
})
|
|
854
|
-
})
|
|
855
|
-
</script>`
|
|
856
|
-
},
|
|
857
|
-
angular: {
|
|
858
|
-
id: "angular",
|
|
859
|
-
label: "Angular",
|
|
860
|
-
packageName: "@mushi-mushi/angular",
|
|
861
|
-
needsWebPackage: false,
|
|
862
|
-
snippet: () => `// src/main.ts
|
|
863
|
-
import { provideMushi } from '@mushi-mushi/angular'
|
|
864
|
-
|
|
865
|
-
bootstrapApplication(AppComponent, {
|
|
866
|
-
providers: [
|
|
867
|
-
provideMushi({
|
|
868
|
-
projectId: import.meta.env.VITE_MUSHI_PROJECT_ID,
|
|
869
|
-
apiKey: import.meta.env.VITE_MUSHI_API_KEY,
|
|
870
|
-
}),
|
|
871
|
-
],
|
|
872
|
-
})`
|
|
873
|
-
},
|
|
874
|
-
expo: {
|
|
875
|
-
id: "expo",
|
|
876
|
-
label: "Expo",
|
|
877
|
-
packageName: "@mushi-mushi/react-native",
|
|
878
|
-
needsWebPackage: false,
|
|
879
|
-
snippet: () => `// App.tsx
|
|
880
|
-
import { MushiProvider } from '@mushi-mushi/react-native'
|
|
881
|
-
|
|
882
|
-
export default function App() {
|
|
883
|
-
return (
|
|
884
|
-
<MushiProvider
|
|
885
|
-
projectId={process.env.EXPO_PUBLIC_MUSHI_PROJECT_ID!}
|
|
886
|
-
apiKey={process.env.EXPO_PUBLIC_MUSHI_API_KEY!}
|
|
887
|
-
>
|
|
888
|
-
<YourApp />
|
|
889
|
-
</MushiProvider>
|
|
890
|
-
)
|
|
891
|
-
}`
|
|
892
|
-
},
|
|
893
|
-
"react-native": {
|
|
894
|
-
id: "react-native",
|
|
895
|
-
label: "React Native",
|
|
896
|
-
packageName: "@mushi-mushi/react-native",
|
|
897
|
-
needsWebPackage: false,
|
|
898
|
-
snippet: () => `// App.tsx
|
|
899
|
-
import { MushiProvider } from '@mushi-mushi/react-native'
|
|
900
|
-
|
|
901
|
-
export default function App() {
|
|
902
|
-
return (
|
|
903
|
-
<MushiProvider
|
|
904
|
-
projectId={process.env.MUSHI_PROJECT_ID!}
|
|
905
|
-
apiKey={process.env.MUSHI_API_KEY!}
|
|
906
|
-
>
|
|
907
|
-
<YourApp />
|
|
908
|
-
</MushiProvider>
|
|
909
|
-
)
|
|
910
|
-
}`
|
|
911
|
-
},
|
|
912
|
-
capacitor: {
|
|
913
|
-
id: "capacitor",
|
|
914
|
-
label: "Capacitor (Ionic)",
|
|
915
|
-
packageName: "@mushi-mushi/capacitor",
|
|
916
|
-
needsWebPackage: false,
|
|
917
|
-
/* The Capacitor plugin's public API is `Mushi.configure(...)`, not
|
|
918
|
-
* `Mushi.init(...)` — see packages/capacitor/src/definitions.ts. We
|
|
919
|
-
* shipped the wrong call here for two releases and users got a runtime
|
|
920
|
-
* `TypeError: Mushi.init is not a function`. The accompanying admin
|
|
921
|
-
* console snippet (apps/admin/src/lib/sdkSnippets.ts) emits the same
|
|
922
|
-
* `Mushi.configure(...)` shape; both are pinned by tests. */
|
|
923
|
-
snippet: () => `// src/main.ts \u2014 after install, run \`npx cap sync\`
|
|
924
|
-
import { Mushi } from '@mushi-mushi/capacitor'
|
|
925
|
-
|
|
926
|
-
await Mushi.configure({
|
|
927
|
-
projectId: import.meta.env.VITE_MUSHI_PROJECT_ID,
|
|
928
|
-
apiKey: import.meta.env.VITE_MUSHI_API_KEY,
|
|
929
|
-
})`
|
|
930
|
-
},
|
|
931
|
-
express: {
|
|
932
|
-
id: "express",
|
|
933
|
-
label: "Express",
|
|
934
|
-
packageName: "@mushi-mushi/node",
|
|
935
|
-
needsWebPackage: false,
|
|
936
|
-
snippet: () => `// src/instrument.ts \u2014 load with: node --import ./dist/instrument.js
|
|
937
|
-
import { MushiNodeClient, attachUnhandledHook } from '@mushi-mushi/node'
|
|
938
|
-
import { mushiExpressErrorHandler } from '@mushi-mushi/node/express'
|
|
939
|
-
import type { Express } from 'express'
|
|
940
|
-
|
|
941
|
-
export const mushi = new MushiNodeClient({
|
|
942
|
-
projectId: process.env.MUSHI_PROJECT_ID!,
|
|
943
|
-
apiKey: process.env.MUSHI_API_KEY!,
|
|
944
|
-
environment: process.env.NODE_ENV ?? 'production',
|
|
945
|
-
})
|
|
946
|
-
attachUnhandledHook({ client: mushi })
|
|
947
|
-
|
|
948
|
-
export function attachMushi(app: Express) {
|
|
949
|
-
app.use(mushiExpressErrorHandler({ client: mushi }))
|
|
950
|
-
}`
|
|
951
|
-
},
|
|
952
|
-
fastify: {
|
|
953
|
-
id: "fastify",
|
|
954
|
-
label: "Fastify",
|
|
955
|
-
packageName: "@mushi-mushi/node",
|
|
956
|
-
needsWebPackage: false,
|
|
957
|
-
snippet: () => `// src/instrument.ts \u2014 load with: node --import ./dist/instrument.js
|
|
958
|
-
import { MushiNodeClient, attachUnhandledHook } from '@mushi-mushi/node'
|
|
959
|
-
import { mushiFastifyPlugin } from '@mushi-mushi/node/fastify'
|
|
960
|
-
import Fastify from 'fastify'
|
|
961
|
-
|
|
962
|
-
export const mushi = new MushiNodeClient({
|
|
963
|
-
projectId: process.env.MUSHI_PROJECT_ID!,
|
|
964
|
-
apiKey: process.env.MUSHI_API_KEY!,
|
|
965
|
-
environment: process.env.NODE_ENV ?? 'production',
|
|
966
|
-
})
|
|
967
|
-
attachUnhandledHook({ client: mushi })
|
|
968
|
-
|
|
969
|
-
const app = Fastify()
|
|
970
|
-
mushiFastifyPlugin(app, { client: mushi })`
|
|
971
|
-
},
|
|
972
|
-
hono: {
|
|
973
|
-
id: "hono",
|
|
974
|
-
label: "Hono",
|
|
975
|
-
packageName: "@mushi-mushi/node",
|
|
976
|
-
needsWebPackage: false,
|
|
977
|
-
snippet: () => `// src/instrument.ts \u2014 load with: node --import ./dist/instrument.js
|
|
978
|
-
import { MushiNodeClient, attachUnhandledHook } from '@mushi-mushi/node'
|
|
979
|
-
import { mushiHonoErrorHandler } from '@mushi-mushi/node/hono'
|
|
980
|
-
import { Hono } from 'hono'
|
|
981
|
-
|
|
982
|
-
export const mushi = new MushiNodeClient({
|
|
983
|
-
projectId: process.env.MUSHI_PROJECT_ID!,
|
|
984
|
-
apiKey: process.env.MUSHI_API_KEY!,
|
|
985
|
-
environment: process.env.NODE_ENV ?? 'production',
|
|
986
|
-
})
|
|
987
|
-
attachUnhandledHook({ client: mushi })
|
|
988
|
-
|
|
989
|
-
const app = new Hono()
|
|
990
|
-
app.onError(
|
|
991
|
-
mushiHonoErrorHandler({ client: mushi }, (err, c) =>
|
|
992
|
-
c.text('Internal Server Error', 500),
|
|
993
|
-
),
|
|
994
|
-
)`
|
|
995
|
-
},
|
|
996
|
-
vanilla: {
|
|
997
|
-
id: "vanilla",
|
|
998
|
-
label: "Vanilla JS / unknown",
|
|
999
|
-
packageName: "@mushi-mushi/web",
|
|
1000
|
-
needsWebPackage: false,
|
|
1001
|
-
snippet: () => `// Anywhere in your client bundle
|
|
1002
|
-
import { Mushi } from '@mushi-mushi/web'
|
|
1003
|
-
|
|
1004
|
-
Mushi.init({
|
|
1005
|
-
projectId: import.meta.env.VITE_MUSHI_PROJECT_ID,
|
|
1006
|
-
apiKey: import.meta.env.VITE_MUSHI_API_KEY,
|
|
1007
|
-
})`
|
|
1008
|
-
}
|
|
1009
|
-
};
|
|
1010
|
-
function readPackageJson(cwd) {
|
|
1011
|
-
const path = join3(cwd, "package.json");
|
|
1012
|
-
if (!existsSync3(path)) return null;
|
|
1013
|
-
try {
|
|
1014
|
-
return JSON.parse(readFileSync3(path, "utf-8"));
|
|
1015
|
-
} catch {
|
|
1016
|
-
return null;
|
|
1017
|
-
}
|
|
1018
|
-
}
|
|
1019
|
-
function detectFramework(cwd, pkg) {
|
|
1020
|
-
const deps = collectDeps(pkg);
|
|
1021
|
-
if (deps.has("next")) return FRAMEWORKS.next;
|
|
1022
|
-
if (deps.has("nuxt")) return FRAMEWORKS.nuxt;
|
|
1023
|
-
if (deps.has("@sveltejs/kit")) return FRAMEWORKS.sveltekit;
|
|
1024
|
-
if (deps.has("@angular/core")) return FRAMEWORKS.angular;
|
|
1025
|
-
if (deps.has("expo")) return FRAMEWORKS.expo;
|
|
1026
|
-
if (deps.has("react-native")) return FRAMEWORKS["react-native"];
|
|
1027
|
-
if (deps.has("@remix-run/react") || deps.has("@remix-run/node") || deps.has("@remix-run/serve")) {
|
|
1028
|
-
return FRAMEWORKS.remix;
|
|
1029
|
-
}
|
|
1030
|
-
if (deps.has("astro")) return FRAMEWORKS.astro;
|
|
1031
|
-
if (deps.has("@solidjs/start") || deps.has("solid-js")) return FRAMEWORKS.solid;
|
|
1032
|
-
if (deps.has("@capacitor/core") && deps.has("react")) return FRAMEWORKS.react;
|
|
1033
|
-
if (deps.has("@capacitor/core")) return FRAMEWORKS.capacitor;
|
|
1034
|
-
if (deps.has("svelte")) return FRAMEWORKS.svelte;
|
|
1035
|
-
if (deps.has("vue")) return FRAMEWORKS.vue;
|
|
1036
|
-
if (deps.has("react-scripts")) return FRAMEWORKS.cra;
|
|
1037
|
-
if (deps.has("react")) return FRAMEWORKS.react;
|
|
1038
|
-
if (deps.has("express")) return FRAMEWORKS.express;
|
|
1039
|
-
if (deps.has("fastify")) return FRAMEWORKS.fastify;
|
|
1040
|
-
if (deps.has("hono") || deps.has("@hono/hono")) return FRAMEWORKS.hono;
|
|
1041
|
-
if (existsSync3(join3(cwd, "next.config.js")) || existsSync3(join3(cwd, "next.config.ts"))) {
|
|
1042
|
-
return FRAMEWORKS.next;
|
|
1043
|
-
}
|
|
1044
|
-
if (existsSync3(join3(cwd, "nuxt.config.ts")) || existsSync3(join3(cwd, "nuxt.config.js"))) {
|
|
1045
|
-
return FRAMEWORKS.nuxt;
|
|
1046
|
-
}
|
|
1047
|
-
if (existsSync3(join3(cwd, "svelte.config.js"))) return FRAMEWORKS.svelte;
|
|
1048
|
-
if (existsSync3(join3(cwd, "angular.json"))) return FRAMEWORKS.angular;
|
|
1049
|
-
if (existsSync3(join3(cwd, "remix.config.js")) || existsSync3(join3(cwd, "remix.config.ts"))) {
|
|
1050
|
-
return FRAMEWORKS.remix;
|
|
1051
|
-
}
|
|
1052
|
-
if (existsSync3(join3(cwd, "astro.config.mjs")) || existsSync3(join3(cwd, "astro.config.ts")) || existsSync3(join3(cwd, "astro.config.js"))) {
|
|
1053
|
-
return FRAMEWORKS.astro;
|
|
1054
|
-
}
|
|
1055
|
-
return FRAMEWORKS.vanilla;
|
|
1056
|
-
}
|
|
1057
|
-
function detectPackageManager(cwd) {
|
|
1058
|
-
if (existsSync3(join3(cwd, "bun.lockb")) || existsSync3(join3(cwd, "bun.lock"))) return "bun";
|
|
1059
|
-
if (existsSync3(join3(cwd, "pnpm-lock.yaml"))) return "pnpm";
|
|
1060
|
-
if (existsSync3(join3(cwd, "yarn.lock"))) return "yarn";
|
|
1061
|
-
if (existsSync3(join3(cwd, "package-lock.json"))) return "npm";
|
|
1062
|
-
const userAgent = process.env.npm_config_user_agent ?? "";
|
|
1063
|
-
if (userAgent.startsWith("bun")) return "bun";
|
|
1064
|
-
if (userAgent.startsWith("pnpm")) return "pnpm";
|
|
1065
|
-
if (userAgent.startsWith("yarn")) return "yarn";
|
|
1066
|
-
return "npm";
|
|
1067
|
-
}
|
|
1068
|
-
function installCommand(pm, packages) {
|
|
1069
|
-
const verb = pm === "npm" ? "install" : "add";
|
|
1070
|
-
return `${pm} ${verb} ${packages.join(" ")}`;
|
|
1071
|
-
}
|
|
1072
|
-
var SERVER_FRAMEWORK_IDS = /* @__PURE__ */ new Set(["express", "fastify", "hono"]);
|
|
1073
|
-
function envVarsToWrite(apiKey, projectId, framework, endpoint) {
|
|
1074
|
-
const CLOUD_ENDPOINT = "https://dxptnwrhwsqckaftyymj.supabase.co/functions/v1/api";
|
|
1075
|
-
const endpointLine = endpoint && endpoint !== CLOUD_ENDPOINT ? `MUSHI_API_ENDPOINT=${endpoint}` : null;
|
|
1076
|
-
if (SERVER_FRAMEWORK_IDS.has(framework.id)) {
|
|
1077
|
-
return [
|
|
1078
|
-
`MUSHI_PROJECT_ID=${projectId}`,
|
|
1079
|
-
`MUSHI_API_KEY=${apiKey}`,
|
|
1080
|
-
endpointLine
|
|
1081
|
-
].filter(Boolean).join("\n");
|
|
1082
|
-
}
|
|
1083
|
-
if (framework.id === "react-native" || framework.id === "remix") {
|
|
1084
|
-
return [
|
|
1085
|
-
`MUSHI_PROJECT_ID=${projectId}`,
|
|
1086
|
-
`MUSHI_API_KEY=${apiKey}`,
|
|
1087
|
-
endpointLine
|
|
1088
|
-
].filter(Boolean).join("\n");
|
|
1089
|
-
}
|
|
1090
|
-
if (framework.id === "expo") {
|
|
1091
|
-
return [
|
|
1092
|
-
`EXPO_PUBLIC_MUSHI_PROJECT_ID=${projectId}`,
|
|
1093
|
-
`EXPO_PUBLIC_MUSHI_API_KEY=${apiKey}`,
|
|
1094
|
-
endpointLine ? `EXPO_PUBLIC_${endpointLine}` : null
|
|
1095
|
-
].filter(Boolean).join("\n");
|
|
1096
|
-
}
|
|
1097
|
-
const prefix = framework.id === "next" ? "NEXT_PUBLIC_" : framework.id === "nuxt" ? "NUXT_PUBLIC_" : framework.id === "cra" ? "REACT_APP_" : framework.id === "astro" ? "PUBLIC_" : "VITE_";
|
|
1098
|
-
return [
|
|
1099
|
-
`${prefix}MUSHI_PROJECT_ID=${projectId}`,
|
|
1100
|
-
`${prefix}MUSHI_API_KEY=${apiKey}`,
|
|
1101
|
-
endpointLine ? `${prefix}${endpointLine}` : null
|
|
1102
|
-
].filter(Boolean).join("\n");
|
|
1103
|
-
}
|
|
1104
|
-
function collectDeps(pkg) {
|
|
1105
|
-
if (!pkg) return /* @__PURE__ */ new Set();
|
|
1106
|
-
return /* @__PURE__ */ new Set([
|
|
1107
|
-
...Object.keys(pkg.dependencies ?? {}),
|
|
1108
|
-
...Object.keys(pkg.devDependencies ?? {}),
|
|
1109
|
-
...Object.keys(pkg.peerDependencies ?? {})
|
|
1110
|
-
]);
|
|
1111
|
-
}
|
|
1112
|
-
|
|
1113
683
|
// src/sanitize-config.ts
|
|
1114
684
|
var PROJECT_ID_RE = /^(?:proj_[A-Za-z0-9_-]{10,}|[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})$/i;
|
|
1115
685
|
var API_KEY_RE = /^(mushi_|mush_pk_)[A-Za-z0-9_-]{10,}$/;
|
|
@@ -1221,55 +791,133 @@ async function waitForIngestReady(options) {
|
|
|
1221
791
|
return { ok: false, payload: lastPayload, attempts: maxAttempts, reason: "timeout" };
|
|
1222
792
|
}
|
|
1223
793
|
|
|
794
|
+
// src/key-scopes.ts
|
|
795
|
+
var SDK_KEY_SCOPES = ["report:write"];
|
|
796
|
+
var CLI_KEY_SCOPES = ["report:write", "mcp:read"];
|
|
797
|
+
var FULL_CLI_KEY_SCOPES = ["report:write", "mcp:read", "mcp:write"];
|
|
798
|
+
var SDK_KEY_LABEL = "sdk-ingest";
|
|
799
|
+
var CLI_KEY_LABEL = "cli-login";
|
|
800
|
+
async function probeKeyScope(endpoint, apiKey, projectId, doFetch = globalThis.fetch) {
|
|
801
|
+
let base = endpoint;
|
|
802
|
+
while (base.endsWith("/")) base = base.slice(0, -1);
|
|
803
|
+
let res;
|
|
804
|
+
try {
|
|
805
|
+
res = await doFetch(`${base}/v1/admin/mcp/account-overview`, {
|
|
806
|
+
headers: { "X-Mushi-Api-Key": apiKey, "X-Mushi-Project": projectId },
|
|
807
|
+
signal: AbortSignal.timeout(8e3)
|
|
808
|
+
});
|
|
809
|
+
} catch (err) {
|
|
810
|
+
return { result: "unreachable", message: err instanceof Error ? err.message : String(err) };
|
|
811
|
+
}
|
|
812
|
+
if (res.ok) return { result: "mcp", status: res.status };
|
|
813
|
+
if (res.status === 401) return { result: "invalid", status: res.status };
|
|
814
|
+
if (res.status === 403) {
|
|
815
|
+
const body = await res.json().catch(() => null);
|
|
816
|
+
const code = body?.error?.code ?? body?.code;
|
|
817
|
+
if (code === "INSUFFICIENT_SCOPE") return { result: "ingest-only", status: res.status };
|
|
818
|
+
}
|
|
819
|
+
return { result: "unknown", status: res.status };
|
|
820
|
+
}
|
|
821
|
+
function describeUnsafeSdkKey(probe, endpoint) {
|
|
822
|
+
switch (probe.result) {
|
|
823
|
+
case "mcp":
|
|
824
|
+
return "this key can read your bug reports (mcp scope), and SDK env vars ship inside the app bundle";
|
|
825
|
+
case "invalid":
|
|
826
|
+
return "the backend rejected this key";
|
|
827
|
+
case "unreachable":
|
|
828
|
+
return `could not reach ${endpoint} to confirm the key is ingest-only (${probe.message ?? "network error"})`;
|
|
829
|
+
case "unknown":
|
|
830
|
+
return `could not confirm the key is ingest-only (HTTP ${probe.status ?? "?"})`;
|
|
831
|
+
case "ingest-only":
|
|
832
|
+
return "the key is ingest-only";
|
|
833
|
+
}
|
|
834
|
+
}
|
|
835
|
+
|
|
1224
836
|
// src/mcp-config.ts
|
|
1225
837
|
import { mkdir, readFile, writeFile } from "fs/promises";
|
|
1226
838
|
import { dirname as dirname3 } from "path";
|
|
1227
839
|
var DEFAULT_MUSHI_FEATURES = "triage,fixes,inventory,setup,docs";
|
|
840
|
+
var MCP_CLIENTS = ["cursor", "claude", "continue", "zed"];
|
|
841
|
+
function isMcpClient(value) {
|
|
842
|
+
return typeof value === "string" && MCP_CLIENTS.includes(value);
|
|
843
|
+
}
|
|
844
|
+
var MCP_CLIENT_LABEL = {
|
|
845
|
+
cursor: "Cursor",
|
|
846
|
+
claude: "Claude Code",
|
|
847
|
+
continue: "Continue",
|
|
848
|
+
zed: "Zed"
|
|
849
|
+
};
|
|
850
|
+
function buildHostedMcpServerBlock(url) {
|
|
851
|
+
return { type: "http", url };
|
|
852
|
+
}
|
|
853
|
+
function isPlainObject(value) {
|
|
854
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
855
|
+
}
|
|
1228
856
|
async function writeMcpServerEntry(opts) {
|
|
1229
857
|
const { configPath, serverName, serverBlock, dryRun = false } = opts;
|
|
1230
|
-
let
|
|
1231
|
-
let created = false;
|
|
858
|
+
let existing = null;
|
|
1232
859
|
try {
|
|
1233
|
-
|
|
860
|
+
existing = await readFile(configPath, "utf8");
|
|
861
|
+
} catch {
|
|
862
|
+
existing = null;
|
|
863
|
+
}
|
|
864
|
+
let merged = {};
|
|
865
|
+
if (existing !== null && existing.trim() !== "") {
|
|
866
|
+
let parsed;
|
|
1234
867
|
try {
|
|
1235
|
-
|
|
868
|
+
parsed = JSON.parse(existing);
|
|
1236
869
|
} catch {
|
|
1237
|
-
|
|
870
|
+
throw new Error(`${configPath} is not valid JSON \u2014 fix or remove it, then re-run (nothing was written).`);
|
|
1238
871
|
}
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
872
|
+
if (!isPlainObject(parsed)) {
|
|
873
|
+
throw new Error(`${configPath} is not a JSON object \u2014 fix or remove it, then re-run (nothing was written).`);
|
|
874
|
+
}
|
|
875
|
+
merged = parsed;
|
|
1242
876
|
}
|
|
1243
|
-
const
|
|
1244
|
-
|
|
1245
|
-
|
|
877
|
+
const currentServers = merged.mcpServers;
|
|
878
|
+
if (currentServers !== void 0 && !isPlainObject(currentServers)) {
|
|
879
|
+
throw new Error(`${configPath} has an "mcpServers" field that is not an object \u2014 fix it, then re-run (nothing was written).`);
|
|
880
|
+
}
|
|
881
|
+
merged.mcpServers = { ...currentServers ?? {}, [serverName]: serverBlock };
|
|
1246
882
|
const output = JSON.stringify(merged, null, 2) + "\n";
|
|
1247
883
|
if (!dryRun) {
|
|
1248
884
|
await mkdir(dirname3(configPath), { recursive: true });
|
|
1249
885
|
await writeFile(configPath, output, "utf8");
|
|
1250
886
|
}
|
|
1251
|
-
return { created, path: configPath };
|
|
887
|
+
return { created: existing === null, path: configPath };
|
|
888
|
+
}
|
|
889
|
+
function apiKeyPlaceholderFor(client) {
|
|
890
|
+
switch (client) {
|
|
891
|
+
case "cursor":
|
|
892
|
+
return "${env:MUSHI_API_KEY}";
|
|
893
|
+
case "claude":
|
|
894
|
+
return "${MUSHI_API_KEY:-}";
|
|
895
|
+
case "continue":
|
|
896
|
+
case "zed":
|
|
897
|
+
return null;
|
|
898
|
+
}
|
|
1252
899
|
}
|
|
1253
900
|
function buildMcpServerBlock(opts) {
|
|
901
|
+
const keyValue = opts.inlineKey ? opts.apiKey : apiKeyPlaceholderFor(opts.client);
|
|
1254
902
|
return {
|
|
1255
903
|
command: "npx",
|
|
1256
904
|
args: ["-y", MUSHI_MCP_PIN_SPEC],
|
|
1257
905
|
env: {
|
|
1258
906
|
MUSHI_API_ENDPOINT: opts.endpoint,
|
|
1259
907
|
MUSHI_PROJECT_ID: opts.projectId,
|
|
1260
|
-
|
|
908
|
+
...keyValue !== null ? { MUSHI_API_KEY: keyValue } : {},
|
|
1261
909
|
MUSHI_FEATURES: DEFAULT_MUSHI_FEATURES
|
|
1262
910
|
}
|
|
1263
911
|
};
|
|
1264
912
|
}
|
|
1265
|
-
function printKeyExportHint(
|
|
1266
|
-
console.log("");
|
|
1267
|
-
console.log(" Your API key was NOT written into the config file (prevents git leaks).");
|
|
1268
|
-
console.log(" Add it to your shell profile or .env.local:");
|
|
1269
|
-
console.log("");
|
|
1270
|
-
console.log(` export MUSHI_API_KEY="${apiKey}"`);
|
|
913
|
+
function printKeyExportHint(client, configPath = CONFIG_PATH) {
|
|
1271
914
|
console.log("");
|
|
1272
|
-
console.log("
|
|
915
|
+
console.log(" No API key was written into the MCP config (safe to commit).");
|
|
916
|
+
console.log(` The MCP server uses the key \`mushi login\` saved in ${configPath}.`);
|
|
917
|
+
if (apiKeyPlaceholderFor(client) !== null) {
|
|
918
|
+
console.log(` To use a different key, export MUSHI_API_KEY in the environment ${MCP_CLIENT_LABEL[client]} is launched from.`);
|
|
919
|
+
}
|
|
920
|
+
console.log(" To write the key into the file instead (keep it out of git), re-run with --inline-key.");
|
|
1273
921
|
}
|
|
1274
922
|
function buildMcpServerName(opts) {
|
|
1275
923
|
if (opts.legacy) return "mushi";
|
|
@@ -1281,6 +929,12 @@ function buildMcpServerName(opts) {
|
|
|
1281
929
|
}
|
|
1282
930
|
|
|
1283
931
|
// src/connect.ts
|
|
932
|
+
async function resolveSdkEnvKey(opts) {
|
|
933
|
+
const candidate = opts.sdkKey ?? savedSdkKeyFor(opts.baseConfig, opts.projectId) ?? opts.apiKey;
|
|
934
|
+
const probe = await opts.probe(opts.endpoint, candidate, opts.projectId);
|
|
935
|
+
if (probe.result === "ingest-only") return { ok: true, key: candidate };
|
|
936
|
+
return { ok: false, reason: describeUnsafeSdkKey(probe, opts.endpoint) };
|
|
937
|
+
}
|
|
1284
938
|
function envKeyPresent(content, key) {
|
|
1285
939
|
const escaped = key.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
1286
940
|
return new RegExp(`^${escaped}=`, "m").test(content);
|
|
@@ -1310,44 +964,41 @@ ${needs.join("\n")}
|
|
|
1310
964
|
await writeFile2(path, block, "utf8");
|
|
1311
965
|
return true;
|
|
1312
966
|
}
|
|
1313
|
-
async function ensureMcpJsonGitignored(cwd, messages) {
|
|
1314
|
-
const gitignorePath = join4(cwd, ".gitignore");
|
|
1315
|
-
const patterns = [".cursor/mcp.json", ".cursor/"];
|
|
1316
|
-
let content = null;
|
|
1317
|
-
try {
|
|
1318
|
-
content = await readFile2(gitignorePath, "utf8");
|
|
1319
|
-
} catch {
|
|
1320
|
-
}
|
|
1321
|
-
if (content === null) {
|
|
1322
|
-
messages.push(
|
|
1323
|
-
"\u26A0 No .gitignore found \u2014 .cursor/mcp.json contains your API key. Add `.cursor/mcp.json` before committing."
|
|
1324
|
-
);
|
|
1325
|
-
return;
|
|
1326
|
-
}
|
|
1327
|
-
const covered = patterns.some((p) => content.split("\n").some((line) => line.trim() === p || line.trim() === `${p}/`));
|
|
1328
|
-
if (covered) return;
|
|
1329
|
-
await appendFile(gitignorePath, "\n# Mushi \u2014 keep MCP credentials out of git\n.cursor/mcp.json\n", "utf8");
|
|
1330
|
-
messages.push("\u2713 Added .cursor/mcp.json to .gitignore (contains API key)");
|
|
1331
|
-
}
|
|
1332
967
|
async function runConnect(opts, baseConfig = {}) {
|
|
1333
968
|
const cwd = resolve(opts.cwd ?? process.cwd());
|
|
1334
969
|
const endpoint = assertEndpoint(opts.endpoint);
|
|
1335
970
|
const projectId = requireUuid(opts.projectId, "projectId");
|
|
1336
971
|
const messages = [];
|
|
972
|
+
const writeEnv = opts.writeEnv !== false;
|
|
973
|
+
const sdkEnvKey = writeEnv ? await resolveSdkEnvKey({
|
|
974
|
+
sdkKey: opts.sdkKey,
|
|
975
|
+
apiKey: opts.apiKey,
|
|
976
|
+
projectId,
|
|
977
|
+
endpoint,
|
|
978
|
+
baseConfig,
|
|
979
|
+
probe: opts.probeKeyScope ?? probeKeyScope
|
|
980
|
+
}) : null;
|
|
1337
981
|
const config = {
|
|
1338
982
|
...baseConfig,
|
|
1339
983
|
apiKey: opts.apiKey,
|
|
1340
984
|
projectId,
|
|
1341
|
-
endpoint
|
|
985
|
+
endpoint,
|
|
986
|
+
...sdkEnvKey?.ok ? { sdkKey: { projectId, key: sdkEnvKey.key } } : {}
|
|
1342
987
|
};
|
|
1343
988
|
saveConfig(config);
|
|
1344
989
|
messages.push(`\u2713 Credentials saved to ${CONFIG_PATH}`);
|
|
1345
990
|
let envPath = null;
|
|
1346
|
-
|
|
991
|
+
let envRefused = false;
|
|
992
|
+
if (sdkEnvKey && !sdkEnvKey.ok) {
|
|
993
|
+
envRefused = true;
|
|
994
|
+
messages.push(
|
|
995
|
+
`\u2717 Did not write SDK env vars: ${sdkEnvKey.reason}. Pass an ingest-only key with --sdk-key <key> (console \u2192 Projects \u2192 API keys, scope report:write), or run \`npx mushi-mushi\`, which mints one.`
|
|
996
|
+
);
|
|
997
|
+
} else if (sdkEnvKey?.ok) {
|
|
1347
998
|
const pkg = readPackageJson(cwd);
|
|
1348
999
|
const framework = detectFramework(cwd, pkg);
|
|
1349
|
-
const lines = envVarsToWrite(
|
|
1350
|
-
envPath =
|
|
1000
|
+
const lines = envVarsToWrite(sdkEnvKey.key, projectId, framework).split("\n");
|
|
1001
|
+
envPath = join3(cwd, ".env.local");
|
|
1351
1002
|
const wrote = await mergeEnvFile(envPath, lines);
|
|
1352
1003
|
messages.push(
|
|
1353
1004
|
wrote ? `\u2713 Env vars merged into ${envPath}` : `\u2713 Env vars already present in ${envPath} (existing values left untouched)`
|
|
@@ -1361,20 +1012,20 @@ async function runConnect(opts, baseConfig = {}) {
|
|
|
1361
1012
|
}
|
|
1362
1013
|
let mcpPath = null;
|
|
1363
1014
|
if (opts.wireIde !== false) {
|
|
1364
|
-
const mcpDir =
|
|
1365
|
-
mcpPath =
|
|
1015
|
+
const mcpDir = join3(cwd, ".cursor");
|
|
1016
|
+
mcpPath = join3(mcpDir, "mcp.json");
|
|
1366
1017
|
const serverName = buildMcpServerName({ projectId });
|
|
1367
1018
|
const serverBlock = buildMcpServerBlock({
|
|
1368
1019
|
endpoint,
|
|
1369
1020
|
projectId,
|
|
1370
1021
|
apiKey: opts.apiKey,
|
|
1022
|
+
client: "cursor",
|
|
1371
1023
|
inlineKey: false
|
|
1372
|
-
//
|
|
1024
|
+
// no secret in the file; the MCP server reads the saved CLI key
|
|
1373
1025
|
});
|
|
1374
1026
|
await writeMcpServerEntry({ configPath: mcpPath, serverName, serverBlock });
|
|
1375
|
-
await ensureMcpJsonGitignored(cwd, messages);
|
|
1376
1027
|
messages.push(`\u2713 Wired ${mcpPath} \u2014 restart Cursor and run "list mushi tools"`);
|
|
1377
|
-
messages.push(`
|
|
1028
|
+
messages.push(` The MCP server reads the key saved in ${CONFIG_PATH} (export MUSHI_API_KEY before launching Cursor to override it).`);
|
|
1378
1029
|
}
|
|
1379
1030
|
let heartbeat = null;
|
|
1380
1031
|
if (opts.wait) {
|
|
@@ -1408,7 +1059,7 @@ async function runConnect(opts, baseConfig = {}) {
|
|
|
1408
1059
|
);
|
|
1409
1060
|
}
|
|
1410
1061
|
}
|
|
1411
|
-
const ok = !opts.wait || Boolean(heartbeat?.ok);
|
|
1062
|
+
const ok = !envRefused && (!opts.wait || Boolean(heartbeat?.ok));
|
|
1412
1063
|
return { ok, envPath, mcpPath, heartbeat, messages };
|
|
1413
1064
|
}
|
|
1414
1065
|
|
|
@@ -1416,19 +1067,22 @@ export {
|
|
|
1416
1067
|
printAndExit,
|
|
1417
1068
|
installSignalHandlers,
|
|
1418
1069
|
trySaveKeyToKeychain,
|
|
1070
|
+
savedSdkKeyFor,
|
|
1419
1071
|
resolveProfileName,
|
|
1072
|
+
CONFIG_PATH,
|
|
1420
1073
|
loadConfig,
|
|
1421
1074
|
ensureClientId,
|
|
1422
1075
|
maybeShowTelemetryNotice,
|
|
1423
1076
|
saveConfig,
|
|
1424
1077
|
listProfiles,
|
|
1425
1078
|
setActiveProfile,
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1079
|
+
SDK_KEY_SCOPES,
|
|
1080
|
+
CLI_KEY_SCOPES,
|
|
1081
|
+
FULL_CLI_KEY_SCOPES,
|
|
1082
|
+
SDK_KEY_LABEL,
|
|
1083
|
+
CLI_KEY_LABEL,
|
|
1084
|
+
probeKeyScope,
|
|
1085
|
+
describeUnsafeSdkKey,
|
|
1432
1086
|
consoleUrl,
|
|
1433
1087
|
resolveConsoleUrlSync,
|
|
1434
1088
|
resolveConsoleUrl,
|
|
@@ -1453,9 +1107,14 @@ export {
|
|
|
1453
1107
|
sanitizeCliCredentials,
|
|
1454
1108
|
apiKeyHeaders,
|
|
1455
1109
|
fetchIngestSetup,
|
|
1110
|
+
MCP_CLIENTS,
|
|
1111
|
+
isMcpClient,
|
|
1112
|
+
MCP_CLIENT_LABEL,
|
|
1113
|
+
buildHostedMcpServerBlock,
|
|
1456
1114
|
writeMcpServerEntry,
|
|
1457
1115
|
buildMcpServerBlock,
|
|
1458
1116
|
printKeyExportHint,
|
|
1459
1117
|
buildMcpServerName,
|
|
1118
|
+
resolveSdkEnvKey,
|
|
1460
1119
|
runConnect
|
|
1461
1120
|
};
|