diff --git a/rsc/lua/lib.lua b/rsc/lua/lib.lua
index fb3f7efe7338c8f7be4aa9da7976dccdb82a1aac..084d70b46074618c191081e8a300d3af42bec12a 100644
--- a/rsc/lua/lib.lua
+++ b/rsc/lua/lib.lua
@@ -83,6 +83,11 @@ function Vivy:newColor (colorString)
     return false
 end
 
+function Vivy:start  () return Vivy.___Fun:start()  end
+function Vivy:finish () return Vivy.___Fun:finish() end
+function Vivy:width  () return Vivy.___Fun:width()  end
+function Vivy:height () return Vivy.___Fun:height() end
+
 -- In case we are able to do the _ENV <- Vivy one day...
 Vivy["Vivy"] = Vivy
 
diff --git a/src/Lib/Script/CRTPLuaScriptObject.hh b/src/Lib/Script/CRTPLuaScriptObject.hh
index 480c569595e985fd42dc1137c2f9d678c34e3582..6772bb5a779fd79e8354e9c37499a71a47494b7f 100644
--- a/src/Lib/Script/CRTPLuaScriptObject.hh
+++ b/src/Lib/Script/CRTPLuaScriptObject.hh
@@ -17,24 +17,34 @@ namespace Vivy::Script
 #define LUA_RETURN_NOTHING(L)                       { lua_settop(L, 0); return 0; }
 // clang-format on
 
+#define method_list static constexpr inline auto
 #define script_class(theClassName) \
     class theClassName final : public CRTPLuaScriptObject<theClassName>
 
-#define method_list static constexpr inline auto
+#define LUA_DECL_GETTER(type, luaName, value)             \
+    static int luaName(lua_State *const L) noexcept       \
+    {                                                     \
+        return luaPushValue<type>(L, CHECK(L, 1)->value); \
+    }
 
-#define LUA_SCRIPTABLE_CLASS(theClassName)                                                  \
-    VIVY_UNMOVABLE_OBJECT(theClassName)                                                     \
-    static constexpr char className[] = #theClassName;                                      \
-    friend CRTPLuaScriptObject<theClassName>;                                               \
-    theClassName(lua_State *L) noexcept                                                     \
-    {                                                                                       \
-        out(LuaContext::getContext(L)) << "Create instance of " << theClassName::className; \
-    }                                                                                       \
+#define LUA_SCRIPTABLE_CLASS_MANUAL_CTOR(theClassName) \
+    VIVY_UNMOVABLE_OBJECT(theClassName)                \
+    static constexpr char className[] = #theClassName; \
+    friend CRTPLuaScriptObject<theClassName>;          \
     ~theClassName() noexcept {}
 
+#define LUA_SCRIPTABLE_CLASS(theClassName)                               \
+    LUA_SCRIPTABLE_CLASS_MANUAL_CTOR(theClassName)                       \
+    theClassName(lua_State *L) noexcept                                  \
+    {                                                                    \
+        err(LuaContext::getContext(L))                                   \
+            << "Create instance of " << theClassName::className << "\n"; \
+    }
+
 // The type of the thing that a job iterate over
 enum class JobIteratorType { Line = 1, Syllabe = 2 };
-static inline JobIteratorType
+
+[[maybe_unused]] static inline JobIteratorType
 getJobIteratorTypeFromString(const std::string_view it) noexcept
 {
     if (it == "LINE")
@@ -57,6 +67,30 @@ protected:
         exit(EXIT_FAILURE); // lua_error should not return anything
     }
 
+    // Push something onto the stack, must be specialized
+    template <typename T> static int luaPushValue(lua_State *const L, const T &thing) noexcept;
+    using std_str  = std::string;
+    using std_strv = std::string_view;
+
+    template <> static int luaPushValue<int>(lua_State *const L, const int &thing) noexcept
+    {
+        lua_pushinteger(L, thing);
+        return 1;
+    }
+
+    template <>
+    static int luaPushValue<std_strv>(lua_State *const L, const std_strv &thing) noexcept
+    {
+        lua_pushlstring(L, thing.data(), thing.size());
+        return 1;
+    }
+
+    template <> static int luaPushValue<std_str>(lua_State *const L, const std_str &thing) noexcept
+    {
+        lua_pushstring(L, thing.c_str());
+        return 1;
+    }
+
     static bool PushFunctionFromRegistry(lua_State *const L, const int key) noexcept
     {
         if (key >= 0) {
@@ -324,17 +358,28 @@ public:
 
 // Holds all the free functions (well, not really free functions here...)
 script_class (FreeFunctions) {
-    LUA_SCRIPTABLE_CLASS(FreeFunctions)
+    LUA_SCRIPTABLE_CLASS_MANUAL_CTOR(FreeFunctions)
+
+    FreeFunctions(lua_State *const) noexcept;
 
     static int print(lua_State *const) noexcept;
     static int getModule(lua_State *const) noexcept;
-    static int start(lua_State *const) noexcept;
-    static int finish(lua_State *const) noexcept;
+
+    LUA_DECL_GETTER(int, start, audioStart)
+    LUA_DECL_GETTER(int, finish, audioFinish)
+    LUA_DECL_GETTER(int, width, videoWidth)
+    LUA_DECL_GETTER(int, height, videoHeight)
 
     method_list metaMethods = { luaRegDefaultGC };
     method_list methods     = { LUA_DECL_METHOD(FreeFunctions, getModule),
                             LUA_DECL_METHOD(FreeFunctions, start),
                             LUA_DECL_METHOD(FreeFunctions, finish),
-                            LUA_DECL_METHOD(FreeFunctions, print), LUA_DECL_CREATE(FreeFunctions) };
+                            LUA_DECL_METHOD(FreeFunctions, width),
+                            LUA_DECL_METHOD(FreeFunctions, height),
+                            LUA_DECL_METHOD(FreeFunctions, print),
+                            LUA_DECL_CREATE(FreeFunctions) };
+
+    int videoWidth{ 0 }, videoHeight{ 0 };
+    int audioStart{ 0 }, audioFinish{ 0 };
 };
 }
diff --git a/src/Lib/Script/CRTPLuaScriptObject/FreeFunctions.cc b/src/Lib/Script/CRTPLuaScriptObject/FreeFunctions.cc
index 3b49778e26aa4accd499e8dd03deaf4054face67..36c9cee70d84ed5ad0de6ccae9d6c000d0358bfe 100644
--- a/src/Lib/Script/CRTPLuaScriptObject/FreeFunctions.cc
+++ b/src/Lib/Script/CRTPLuaScriptObject/FreeFunctions.cc
@@ -1,7 +1,43 @@
 #include "../CRTPLuaScriptObject.hh"
+#include "../LuaContext.hh"
+#include "../../Document/CRTPSubDocument.hh"
+#include "../../Document/VivyDocument.hh"
+#include "../../Audio.hh"
+#include "../../Video.hh"
+#include "../../../VivyApplication.hh"
 
 using namespace Vivy::Script;
 
+FreeFunctions::FreeFunctions(lua_State *const L) noexcept
+{
+    const auto *const context = LuaContext::getContext(L);
+    out(context) << "Creating the FreeFunctions lua object!";
+
+    std::shared_ptr<VivyDocument> vivyDoc = context->getAttachedVivyDocument();
+    if (vivyDoc) {
+        if (!(vivyDoc->checkDocumentCapabilities(VivyDocument::AudioAble) &&
+              vivyDoc->checkDocumentCapabilities(VivyDocument::AssAble) &&
+              vivyDoc->checkDocumentCapabilities(VivyDocument::AudioAble))) {
+            err(context) << "The VivyDocument is not a complete document, "
+                         << "can't load it for scripting";
+            luaGlobalError(L, "Attached VivyDocument is not complete");
+        }
+
+        out(context) << "Initializing the FreeFunctions lua object with the VivyDocument";
+        std::shared_ptr<VideoStream> video = vivyDoc->getVideoSubDocument()->getDefaultStream();
+        [[maybe_unused]] std::shared_ptr<AudioStream> audio =
+            vivyDoc->getAudioSubDocument()->getDefaultStream();
+
+        videoWidth  = video->getWidth();
+        videoHeight = video->getWidth();
+        TODO(Set getters values for audio)
+    }
+
+    else {
+        out(context) << "No attached Vivy document in the Lua context";
+    }
+}
+
 int
 FreeFunctions::print(lua_State *const L) noexcept
 {
@@ -18,19 +54,3 @@ FreeFunctions::getModule(lua_State *const L) noexcept
     [[maybe_unused]] const ModuleDeclaration *const mod = context->getModule(modName);
     return 1;
 }
-
-int
-FreeFunctions::start(lua_State *const L) noexcept
-{
-    lua_settop(L, 0);
-    lua_pushinteger(L, 0);
-    return 1;
-}
-
-int
-FreeFunctions::finish(lua_State *const L) noexcept
-{
-    lua_settop(L, 0);
-    lua_pushinteger(L, 0);
-    return 1;
-}
diff --git a/src/Lib/Script/LuaContext.cc b/src/Lib/Script/LuaContext.cc
index 48ac5354729be15bbe4e597dc78e7d5a4924e7b9..52c00dd7d2ded0365192014bbc7feea9c9fd518c 100644
--- a/src/Lib/Script/LuaContext.cc
+++ b/src/Lib/Script/LuaContext.cc
@@ -1,6 +1,7 @@
 #include "CRTPLuaScriptObject.hh"
 #include "ScriptDocument.hh"
 #include "LuaContext.hh"
+#include "../Document/VivyDocument.hh"
 
 // LuaContext implementation
 using namespace Vivy::Script;
@@ -48,6 +49,15 @@ LuaContext::getContext(const lua_State *const state) noexcept
     return contextList.contains(state) ? contextList.at(state) : nullptr;
 }
 
+LuaContext::Code
+LuaContext::loadDocument(std::shared_ptr<Vivy::VivyDocument> doc) noexcept
+{
+    if (attachedVivyDocument != nullptr)
+        return Error;
+    attachedVivyDocument = doc;
+    return Success;
+}
+
 LuaContext::Code
 LuaContext::loadDocument(std::shared_ptr<ScriptDocument> doc) noexcept
 {
@@ -158,6 +168,12 @@ LuaContext::getState() noexcept
     return L;
 }
 
+std::shared_ptr<Vivy::VivyDocument>
+LuaContext::getAttachedVivyDocument() const noexcept
+{
+    return attachedVivyDocument;
+}
+
 bool
 LuaContext::moduleExists(const std::string_view mod) const noexcept
 {
diff --git a/src/Lib/Script/LuaContext.hh b/src/Lib/Script/LuaContext.hh
index 06da7b4318d42a683802bfbdc7f4fa577160649d..318751abaeb7ad0e7cbf53616a20b7aad56a8a0b 100644
--- a/src/Lib/Script/LuaContext.hh
+++ b/src/Lib/Script/LuaContext.hh
@@ -9,6 +9,7 @@ struct lua_State;
 namespace Vivy
 {
 class ScriptDocument;
+class VivyDocument;
 }
 
 namespace Vivy::Script
@@ -27,6 +28,7 @@ class LuaContext final {
     VIVY_APP_LOGGABLE_OBJECT(LuaContext, logger)
 
     lua_State *L{ nullptr };
+    std::shared_ptr<Vivy::VivyDocument> attachedVivyDocument{ nullptr };
 
     std::string failureString{};
     std::string currentFile{};
@@ -47,6 +49,7 @@ public:
     ~LuaContext() noexcept;
 
     Code loadDocument(std::shared_ptr<ScriptDocument>) noexcept;
+    Code loadDocument(std::shared_ptr<Vivy::VivyDocument>) noexcept;
 
     QString getLastLuaError() noexcept;
 
@@ -59,9 +62,10 @@ public:
     void setFailedWith(const std::string &) noexcept;
 
     lua_State *getState() noexcept;
+    std::shared_ptr<Vivy::VivyDocument> getAttachedVivyDocument() const noexcept;
 
-    decltype(auto) getOutputStream() noexcept { return logInfo(); }
-    decltype(auto) getErrorStream() noexcept { return logError(); }
+    decltype(auto) getOutputStream() const noexcept { return logInfo(); }
+    decltype(auto) getErrorStream() const noexcept { return logError(); }
 
     operator lua_State *() noexcept { return L; }
     static LuaContext *getContext(const lua_State *const) noexcept;
@@ -99,14 +103,14 @@ private:
     void swapEnv() noexcept;
 };
 
-static inline decltype(auto)
-out(LuaContext *const context) noexcept
+[[maybe_unused]] static inline decltype(auto)
+out(const LuaContext *const context) noexcept
 {
     return context->getOutputStream();
 }
 
-static inline decltype(auto)
-err(LuaContext *const context) noexcept
+[[maybe_unused]] static inline decltype(auto)
+err(const LuaContext *const context) noexcept
 {
     return context->getErrorStream();
 }
diff --git a/src/Lib/Script/ScriptStore.cc b/src/Lib/Script/ScriptStore.cc
index 14ee4bc27d8a7e94c854e99c1df62be71c8fa929..44b8e5d16652b9ac658debbdd7ec40c7ea1bfeba 100644
--- a/src/Lib/Script/ScriptStore.cc
+++ b/src/Lib/Script/ScriptStore.cc
@@ -47,10 +47,22 @@ ScriptStore::resetLoadedScripts() noexcept
 bool
 ScriptStore::executeScript(Uuid id) noexcept
 {
-    const auto script = documents.at(id);
+    const auto &script = documents.at(id);
     return luaContext->loadDocument(script) == Code::Success;
 }
 
+bool
+ScriptStore::executeScript(Uuid id, std::shared_ptr<Vivy::VivyDocument> doc) noexcept
+{
+    if (doc == nullptr)
+        return false;
+    if (luaContext->loadDocument(doc) != Script::LuaContext::Success) {
+        luaContext->setFailedWith("A VivyDocument is already loaded, can't attach a new one");
+        return false;
+    }
+    return executeScript(id);
+}
+
 const std::vector<std::string_view>
 ScriptStore::getLoadedModules() const noexcept
 {
diff --git a/src/Lib/Script/ScriptStore.hh b/src/Lib/Script/ScriptStore.hh
index 636da75c11c3eec908e695e5d3529f062999b101..0a1968a6d3b2579843e248605191eca7e534690c 100644
--- a/src/Lib/Script/ScriptStore.hh
+++ b/src/Lib/Script/ScriptStore.hh
@@ -1,6 +1,7 @@
 #pragma once
 
 #include "../CRTPStore.hh"
+#include "../Document/VivyDocument.hh"
 #include "ScriptDocument.hh"
 #include "LuaContext.hh"
 
@@ -27,6 +28,7 @@ public:
     void loadScriptFolder(const QString &folderPath);
     std::vector<Item> getLoadedScripts() const noexcept;
     bool executeScript(Uuid) noexcept;
+    bool executeScript(Uuid, std::shared_ptr<Vivy::VivyDocument>) noexcept;
 
     QString getLastLuaError() noexcept;
 
diff --git a/src/VivyApplication.cc b/src/VivyApplication.cc
index f511fe9d3f34a840508a268651b7a4658639c04f..d474fca4c21e01152380f3f4b5ff196d013d1cfa 100644
--- a/src/VivyApplication.cc
+++ b/src/VivyApplication.cc
@@ -2,7 +2,9 @@
 #include "UI/MainWindow.hh"
 #include "UI/DockWidgetTitleBar.hh"
 #include "Lib/Document/VivyDocumentStore.hh"
+#include "Lib/Document/VivyDocument.hh"
 #include "Lib/Script/ScriptStore.hh"
+#include "Lib/Script/ScriptDocument.hh"
 
 using namespace Vivy;
 
@@ -14,7 +16,25 @@ VivyApplication::VivyApplication(int &argc, char **argv)
     VIVY_LOG_CTOR() << "Construction is OK";
 
     if (argc >= 2) {
-        selectedDoc  = scriptStore->loadDocument(QString::fromUtf8(argv[1]));
+        for (int i = 1; i < argc; ++i) {
+            const QString passedFileName(QString::fromUtf8(argv[1]));
+            const QFileInfo passedArgumentFile(passedFileName);
+            Utils::DocumentType passedFileType;
+            if (Utils::detectDocumentType(passedArgumentFile, &passedFileType)) {
+                if (passedFileType == Utils::DocumentType::Vivy) {
+                    selectedVivyDoc = documentStore->loadDocument(passedFileName);
+                    logInfo() << "Select vivy document " << passedFileName;
+                } else if (passedFileType == Utils::DocumentType::VivyScript) {
+                    selectedScriptDoc = scriptStore->loadDocument(passedFileName);
+                    logInfo() << "Select script document " << passedFileName;
+                } else {
+                    logError() << "Not handled file type for file " << passedFileName;
+                }
+            } else {
+                logError() << "Unrecognized file type for file " << passedFileName;
+            }
+        }
+
         selectedType = ApplicationType::CLI;
         VIVY_LOG_CTOR() << "Select the ApplicationType::CLI";
     }
@@ -70,9 +90,12 @@ VivyApplication::exec() noexcept
 
     switch (selectedType) {
     case ApplicationType::CLI: {
-        if ((selectedDoc == nullptr) || (!scriptStore->executeScript(selectedDoc->getUuid())))
+        if ((selectedVivyDoc == nullptr) || (selectedScriptDoc == nullptr))
             return 1;
 
+        if (!scriptStore->executeScript(selectedScriptDoc->getUuid(), selectedVivyDoc))
+            return 2;
+
         for (const auto &str : scriptStore->getLoadedModules()) {
             std::cout << "Module " << str << " was loaded!\n";
             [[maybe_unused]] const auto *mod = scriptStore->getModule(str);
diff --git a/src/VivyApplication.hh b/src/VivyApplication.hh
index 7317c7ea752bfea182e02d36a48bcf82281dd74a..654989b1805c41220045f297bfeca642a51f3632 100644
--- a/src/VivyApplication.hh
+++ b/src/VivyApplication.hh
@@ -16,8 +16,8 @@
 #define VIVY_APP_LOGGABLE_OBJECT_BY_STORED_NAME(name, logger) \
     VIVY_LOGGABLE_OBJECT_BY_STORED_NAME(vivyApp->getLogSink(), name, logger)
 
-#define currentVivyDocument() dynamic_cast<::Vivy::VivyDocument *>(vivyApp->getCurrentDocument())
-#define currentScriptDocument dynamic_cast<::Vivy::ScriptDocument *>(vivyApp->getCurrentDocument())
+#define currentVivyDocument   dynamic_cast<VivyDocument *>(vivyApp->getCurrentDocument())
+#define currentScriptDocument dynamic_cast<ScriptDocument *>(vivyApp->getCurrentDocument())
 
 // Only support dark theme for now
 #define VIVY_ICON_APP     ":icons/vivy.png"
@@ -49,6 +49,7 @@ class ScriptStore;
 class VivyDocumentStore;
 class AbstractDocument;
 class ScriptDocument;
+class VivyDocument;
 
 // Vivy application class
 class VivyApplication : public QApplication {
@@ -87,7 +88,8 @@ private:
     ApplicationType selectedType{ ApplicationType::GUI };
 
     // ApplicationType::CLI Only!
-    std::shared_ptr<ScriptDocument> selectedDoc{ nullptr };
+    std::shared_ptr<ScriptDocument> selectedScriptDoc{ nullptr };
+    std::shared_ptr<VivyDocument> selectedVivyDoc{ nullptr };
 
 public:
     VivyApplication(int &argc, char **argv);